-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
172 lines (165 loc) · 17.3 KB
/
index.html
File metadata and controls
172 lines (165 loc) · 17.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="generator" content="FaasJS Custom SSG" />
<style>
:root {
--vp-c-bg: #fff;
}
[data-theme='dark'] {
--vp-c-bg: #1b1b1f;
}
html,
body {
background-color: var(--vp-c-bg);
}
</style>
<script>
try {
const useChoice = localStorage.getItem('vuepress-color-scheme');
const systemStatus =
'matchMedia' in window
? window.matchMedia('(prefers-color-scheme: dark)').matches
: false;
if (useChoice === 'light') {
document.documentElement.dataset.theme = 'light';
} else if (useChoice === 'dark' || systemStatus) {
document.documentElement.dataset.theme = 'dark';
}
} catch {}
</script>
<link rel="icon" href="/logo.jpg" />
<title>FaasJS</title>
<meta name="description" content="A Rails-inspired, curated full-stack TypeScript framework for database-driven React business applications." />
<link rel="stylesheet" href="/assets/style.css" />
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-0049636498302507" crossorigin="anonymous"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-143006612-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-143006612-1');
</script>
</head>
<body>
<div id="app">
<div class="vp-theme-container external-link-icon no-sidebar">
<header class="vp-navbar" vp-navbar>
<div class="vp-toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0">
<div class="icon" aria-hidden="true"><span></span><span></span><span></span></div>
</div>
<span>
<a class="route-link" href="/"><span class="vp-site-name" aria-hidden="true">FaasJS</span></a>
</span>
<div class="vp-navbar-items-wrapper"><nav class="vp-navbar-items vp-hide-mobile" aria-label="site navigation"><div class="vp-navbar-item"><a class="auto-link route-link route-link-active" href="/" aria-label="Home">Home</a></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper"><button class="vp-navbar-dropdown-title" type="button" aria-label="Learn"><span class="title">Learn</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="Learn"><span class="title">Learn</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/guide/" aria-label="Guide">Guide</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/doc/" aria-label="Documents">Documents</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/faasjs/faasjs/tree/main/templates" aria-label="Templates" rel="noopener noreferrer" target="_blank">Templates</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/CHANGELOG.html" aria-label="Changelog">Changelog</a></li><li class="vp-navbar-dropdown-item"><h4 class="vp-navbar-dropdown-subtitle"><span>Ecosystem</span></h4><ul class="vp-navbar-dropdown-subitem-wrapper"><li class="vp-navbar-dropdown-subitem"><a class="auto-link route-link" href="/doc/images/" aria-label="Docker Images">Docker Images</a></li></ul></li></ul></div></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper"><button class="vp-navbar-dropdown-title" type="button" aria-label="Community"><span class="title">Community</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="Community"><span class="title">Community</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/faasjs/faasjs/" aria-label="Github" rel="noopener noreferrer" target="_blank">Github</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/CONTRIBUTING.html" aria-label="Contributing">Contributing</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/sponsors/faasjs" aria-label="Sponsor" rel="noopener noreferrer" target="_blank">Sponsor</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/SECURITY.html" aria-label="Security">Security</a></li></ul></div></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper"><button class="vp-navbar-dropdown-title" type="button" aria-label="English"><span class="title">English</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="English"><span class="title">English</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link route-link route-link-active" href="/" aria-label="English">English</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/zh/" aria-label="简体中文">简体中文</a></li></ul></div></div></nav></div>
</header>
<div class="vp-sidebar-mask"></div>
<aside class="vp-sidebar" vp-sidebar><nav class="vp-navbar-items" aria-label="site navigation"><div class="vp-navbar-item"><a class="auto-link route-link route-link-active" href="/" aria-label="Home">Home</a></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper mobile"><button class="vp-navbar-dropdown-title" type="button" aria-label="Learn"><span class="title">Learn</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="Learn"><span class="title">Learn</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/guide/" aria-label="Guide">Guide</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/doc/" aria-label="Documents">Documents</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/faasjs/faasjs/tree/main/templates" aria-label="Templates" rel="noopener noreferrer" target="_blank">Templates</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/CHANGELOG.html" aria-label="Changelog">Changelog</a></li><li class="vp-navbar-dropdown-item"><h4 class="vp-navbar-dropdown-subtitle"><span>Ecosystem</span></h4><ul class="vp-navbar-dropdown-subitem-wrapper"><li class="vp-navbar-dropdown-subitem"><a class="auto-link route-link" href="/doc/images/" aria-label="Docker Images">Docker Images</a></li></ul></li></ul></div></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper mobile"><button class="vp-navbar-dropdown-title" type="button" aria-label="Community"><span class="title">Community</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="Community"><span class="title">Community</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/faasjs/faasjs/" aria-label="Github" rel="noopener noreferrer" target="_blank">Github</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/CONTRIBUTING.html" aria-label="Contributing">Contributing</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link external-link" href="https://github.com/sponsors/faasjs" aria-label="Sponsor" rel="noopener noreferrer" target="_blank">Sponsor</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/SECURITY.html" aria-label="Security">Security</a></li></ul></div></div><div class="vp-navbar-item"><div class="vp-navbar-dropdown-wrapper mobile"><button class="vp-navbar-dropdown-title" type="button" aria-label="English"><span class="title">English</span><span class="arrow down"></span></button><button class="vp-navbar-dropdown-title-mobile" type="button" aria-label="English"><span class="title">English</span><span class="right arrow"></span></button><ul class="vp-navbar-dropdown"><li class="vp-navbar-dropdown-item"><a class="auto-link route-link route-link-active" href="/" aria-label="English">English</a></li><li class="vp-navbar-dropdown-item"><a class="auto-link route-link" href="/zh/" aria-label="简体中文">简体中文</a></li></ul></div></div></nav></aside>
<main class="vp-page">
<div vp-content>
<div id="content"><div class="vp-home"><header class="vp-hero"><img class="vp-hero-image" src="/logo.jpg" alt="🚀 FaasJS" /><h1>🚀 FaasJS</h1></header><div class="theme-default-content"><div style="width:100%;line-height:1.7">
<div style="text-align:center;font-size:1.6rem;color:#6a8bad;margin-bottom:1em">A Rails-inspired, curated full-stack TypeScript framework for database-driven React business applications.</div>
<div style="display:flex;gap:4px;align-items:center;justify-content:center;flex-wrap:wrap">
<a href="https://github.com/faasjs/faasjs/blob/main/packages/faasjs/LICENSE"><img src="https://img.shields.io/npm/l/faasjs.svg"></a>
<br>
<a href="https://www.npmjs.com/package/faasjs"><img src="https://img.shields.io/npm/v/faasjs.svg"></a>
<br>
<a href="https://github.com/faasjs/faasjs/actions/workflows/unit.yml"><img src="https://github.com/faasjs/faasjs/actions/workflows/unit.yml/badge.svg"></a>
<a href="https://github.com/faasjs/faasjs/actions/workflows/lint.yml"><img src="https://github.com/faasjs/faasjs/actions/workflows/lint.yml/badge.svg"></a>
<br>
<a href="https://codecov.io/gh/faasjs/faasjs"><img src="https://img.shields.io/codecov/c/github/faasjs/faasjs.svg"></a>
<a href="https://github.com/faasjs/faasjs"><img src="https://badgen.net/github/commits/faasjs/faasjs"></a>
<br>
<a href="https://github.com/faasjs/faasjs"><img src="https://badgen.net/github/last-commit/faasjs/faasjs"></a>
</div>
</div>
<p style="max-width:760px;margin:0 auto 1em;text-align:center;line-height:1.8;color:#5c7080">FaasJS provides a chef-selected default path across React, Ant Design, typed APIs, PostgreSQL, validation, testing, plugins, and project conventions so teams can build predictable products without repeatedly assembling their own framework.</p>
<p style="max-width:760px;margin:0 auto 2em;text-align:center;line-height:1.8;color:#5c7080">The official frontend path is React. The curated business-app stack uses <code>@faasjs/ant-design</code> for UI, <code>@faasjs/pg</code> for PostgreSQL workflows, and agent-readable conventions for complete UI → API → DB → test slices.</p>
<h2 id="features" tabindex="-1">Features</h2>
<h3 id="curated-default-stack" tabindex="-1">Curated default stack</h3>
<p>✅ React, Ant Design, PostgreSQL, Vitest, and Vite Plus working together.</p>
<p>✅ Strong defaults for database-driven admin panels, internal tools, SaaS dashboards, and BFF/API layers.</p>
<p>✅ Replaceable choices without turning alternatives into parallel first-class tracks.</p>
<h3 id="typed-full-stack-workflow" tabindex="-1">Typed full-stack workflow</h3>
<p>✅ <code>defineApi</code> endpoints with explicit schemas and typed contracts.</p>
<p>✅ Shared API types across backend handlers and React clients.</p>
<p>✅ PostgreSQL query, migration, and testing workflows through <code>@faasjs/pg</code> and <code>@faasjs/pg-dev</code>.</p>
<h3 id="agent-readable-conventions" tabindex="-1">Agent-readable conventions</h3>
<p>✅ Stable file conventions and routing rules.</p>
<p>✅ Complete application slices that are easy for humans and AI coding agents to inspect, review, and refactor.</p>
<p>✅ Plugin patterns for business-specific concerns such as auth context and permissions.</p>
<h2 id="quick-start" tabindex="-1">Quick start</h2>
<h3 id="start-with-codespaces-and-templates" tabindex="-1">Start with Codespaces and Templates</h3>
<p><a href="https://github.com/faasjs/faasjs/tree/main/templates" target="_blank" rel="noopener noreferrer" class="external-link">🧪 FaasJS Templates</a></p>
<h3 id="start-with-command-line" tabindex="-1">Start with Command Line</h3>
<pre><code class="hljs language-bash">npx create-faas-app --name faasjs
npx create-faas-app --name faasjs-admin --template admin
npx create-faas-app --name faasjs-minimal --template minimal
</code></pre>
<p><code>admin</code> is the default starter. It follows the curated FaasJS path with React, Ant Design, PostgreSQL, and <code>@faasjs/pg-dev</code>-powered tests. Use <code>--template minimal</code> when you want a lighter React starter without the database stack.</p>
<h2 id="examples" tabindex="-1">Examples</h2>
<h3 id="api-file" tabindex="-1">API file</h3>
<pre><code class="hljs language-ts"><span class="hljs-comment">// index.api.ts</span>
<span class="hljs-comment">// all API entry files should end with .api.ts</span>
<span class="hljs-keyword">import</span> { defineApi } <span class="hljs-keyword">from</span> <span class="hljs-string">'@faasjs/core'</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title function_">defineApi</span>({
<span class="hljs-keyword">async</span> <span class="hljs-title function_">handler</span>(<span class="hljs-params"></span>) {
<span class="hljs-keyword">return</span> <span class="hljs-string">'Hello, world'</span> <span class="hljs-comment">// response content</span>
},
})
</code></pre>
<h3 id="unit-test's-file" tabindex="-1">Unit test's file</h3>
<pre><code class="hljs language-ts"><span class="hljs-comment">// __tests__/index.test.ts</span>
<span class="hljs-comment">// unit test files should end with .test.ts</span>
<span class="hljs-comment">// TSX-based UI tests should use .test.tsx</span>
<span class="hljs-comment">// UI tests without TSX should use .ui.test.ts</span>
<span class="hljs-keyword">import</span> { testApi } <span class="hljs-keyword">from</span> <span class="hljs-string">'@faasjs/dev'</span>
<span class="hljs-keyword">import</span> api <span class="hljs-keyword">from</span> <span class="hljs-string">'../index.api'</span>
<span class="hljs-title function_">describe</span>(<span class="hljs-string">'index'</span>, <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {
<span class="hljs-title function_">it</span>(<span class="hljs-string">'should work'</span>, <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {
<span class="hljs-comment">// create a test handler</span>
<span class="hljs-keyword">const</span> handler = <span class="hljs-title function_">testApi</span>(api)
<span class="hljs-comment">// mock the request</span>
<span class="hljs-keyword">const</span> { statusCode, data } = <span class="hljs-keyword">await</span> <span class="hljs-title function_">handler</span>()
<span class="hljs-comment">// expect the response with 200 status</span>
<span class="hljs-title function_">expect</span>(statusCode).<span class="hljs-title function_">toEqual</span>(<span class="hljs-number">200</span>)
<span class="hljs-comment">// expect the response content is 'Hello, world'</span>
<span class="hljs-title function_">expect</span>(data).<span class="hljs-title function_">toEqual</span>(<span class="hljs-string">'Hello, world'</span>)
})
})
</code></pre>
<h2 id="thanks" tabindex="-1">Thanks</h2>
<p>Code contributors (in alphabetical order):</p>
<div style="display:flex;flex-wrap:wrap;gap:4px;">
<a href="https://github.com/Germiniku" target="_blank">Germini</a>,
<a href="https://github.com/hiisea" target="_blank">hiisea</a>,
<a href="https://github.com/iHeyTang">iHeyTang</a>,
<a href="https://github.com/luckyporo" target="_blank">luckyporo</a>,
<a href="https://github.com/mingkang1993" target="_blank">mingkang1993</a>,
<a href="https://github.com/minzojian" target="_blank">minzojian</a>,
<a href="https://github.com/onichandame" target="_blank">onichandame</a>,
<a href="https://github.com/Vibutnum" target="_blank">Vibutnum</a>,
<a href="https://github.com/victoryifei" target="_blank">victoryifei</a>,
<a href="https://github.com/WittCsharp" target="_blank">WittCsharp</a>,
<a href="https://github.com/zfben" target="_blank">zfben</a>
</div>
<p>Open source projects (in alphabetical order):</p>
<div style="display:flex;flex-wrap:wrap;gap:4px;margin-bottom:2em">
<a href="https://oxc.rs/" target="_blank">Oxc</a>,
<a href="https://nodejs.org/" target="_blank">Node.js</a>,
<a href="https://react.dev/" target="_blank">React</a>,
<a href="https://rollupjs.org/" target="_blank">Rollup.js</a>,
<a href="https://vitest.dev/" target="_blank">Vitest</a>,
<a href="https://www.typescriptlang.org/" target="_blank">TypeScript</a>
</div>
</div></div></div>
</div>
<footer class="vp-footer">🚀 FaasJS is a Rails-inspired, curated full-stack TypeScript framework for database-driven React business applications. | MIT Licensed | Copyright © 2019-2026 Zhu Feng</footer>
</main>
</div>
</div>
<script src="/assets/app.js" defer></script>
</body>
</html>