create-faas-app 8.0.0-beta.4 → 8.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/index.d.ts +16 -15
- package/dist/index.mjs +155 -304
- package/index.mjs +1 -1
- package/package.json +20 -23
- package/template/admin/.env.example +1 -0
- package/template/admin/gitignore +4 -0
- package/template/admin/index.html +12 -0
- package/template/admin/package.json +35 -0
- package/template/admin/server.ts +33 -0
- package/template/admin/src/.faasjs/types.d.ts +16 -0
- package/template/admin/src/db/migrations/20250101000000_create_users.ts +12 -0
- package/template/admin/src/db/tables/users.ts +8 -0
- package/template/admin/src/faas.yaml +11 -0
- package/template/admin/src/features/auth/api/__tests__/me.test.ts +39 -0
- package/template/admin/src/features/auth/api/me.api.ts +23 -0
- package/template/admin/src/features/users/api/__tests__/create.test.ts +47 -0
- package/template/admin/src/features/users/api/__tests__/detail.test.ts +39 -0
- package/template/admin/src/features/users/api/__tests__/list.test.ts +31 -0
- package/template/admin/src/features/users/api/__tests__/update.test.ts +51 -0
- package/template/admin/src/features/users/api/create.api.ts +26 -0
- package/template/admin/src/features/users/api/detail.api.ts +23 -0
- package/template/admin/src/features/users/api/list.api.ts +22 -0
- package/template/admin/src/features/users/api/update.api.ts +35 -0
- package/template/admin/src/features/users/index.tsx +138 -0
- package/template/admin/src/main.tsx +24 -0
- package/template/admin/src/plugins/auth.ts +25 -0
- package/template/admin/src/types/faasjs-auth.d.ts +8 -0
- package/template/admin/tsconfig.json +4 -0
- package/template/admin/vite.config.ts +12 -0
- package/template/minimal/gitignore +4 -0
- package/template/minimal/index.html +12 -0
- package/template/minimal/package.json +27 -0
- package/template/minimal/server.ts +33 -0
- package/template/minimal/src/.faasjs/types.d.ts +12 -0
- package/template/minimal/src/faas.yaml +11 -0
- package/template/minimal/src/features/home/api/__tests__/hello.test.ts +17 -0
- package/template/minimal/src/features/home/api/hello.api.ts +13 -0
- package/template/minimal/src/features/home/index.tsx +37 -0
- package/template/minimal/src/main.tsx +5 -0
- package/template/minimal/src/react-client.ts +8 -0
- package/template/minimal/tsconfig.json +4 -0
- package/template/minimal/vite.config.ts +6 -0
- package/dist/index.cjs +0 -318
package/README.md
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
# create-faas-app
|
|
2
2
|
|
|
3
|
+
# create-faas-app
|
|
4
|
+
|
|
3
5
|
[](https://github.com/faasjs/faasjs/blob/main/packages/create-faas-app/LICENSE)
|
|
4
6
|
[](https://www.npmjs.com/package/create-faas-app)
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
Curated scaffolder for FaasJS projects. The `admin` template is the default
|
|
9
|
+
React + Ant Design + PostgreSQL starter, and `minimal` provides a smaller
|
|
10
|
+
React starter. After scaffolding, the CLI runs `npm install`, `npm run types`,
|
|
11
|
+
and `npm run test` in the new project.
|
|
7
12
|
|
|
8
13
|
## Usage
|
|
9
14
|
|
|
10
15
|
```bash
|
|
11
|
-
# use npm
|
|
12
16
|
npx create-faas-app --name faasjs
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
bunx create-faas-app --name faasjs
|
|
17
|
+
npx create-faas-app --name faasjs-admin --template admin
|
|
18
|
+
npx create-faas-app --name faasjs-minimal --template minimal
|
|
16
19
|
```
|
|
17
20
|
|
|
18
21
|
## Functions
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { Command } from
|
|
1
|
+
import { Command } from "commander";
|
|
2
2
|
|
|
3
|
+
//#region src/index.d.ts
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
* [](https://www.npmjs.com/package/create-faas-app)
|
|
5
|
+
* Run the `create-faas-app` CLI with a provided argv array.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* The array should use the same shape as `process.argv`, including executable
|
|
8
|
+
* and script slots. Parsing may prompt for a project name, create files, install
|
|
9
|
+
* dependencies, generate FaasJS action types, and run template tests. Commander
|
|
10
|
+
* help exits are swallowed and return the shared program; unexpected errors are
|
|
11
|
+
* printed with `console.error` and also return the program.
|
|
8
12
|
*
|
|
9
|
-
*
|
|
13
|
+
* @param {string[]} argv - CLI arguments forwarded to Commander.
|
|
14
|
+
* @returns {Promise<Command>} Commander program instance after parsing.
|
|
10
15
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { main } from 'create-faas-app'
|
|
14
19
|
*
|
|
15
|
-
*
|
|
16
|
-
* bunx create-faas-app --name faasjs
|
|
20
|
+
* await main(['node', 'create-faas-app', '--help'])
|
|
17
21
|
* ```
|
|
18
|
-
*
|
|
19
|
-
* @packageDocumentation
|
|
20
22
|
*/
|
|
21
|
-
|
|
22
23
|
declare function main(argv: string[]): Promise<Command>;
|
|
23
|
-
|
|
24
|
-
export { main };
|
|
24
|
+
//#endregion
|
|
25
|
+
export { main };
|
package/dist/index.mjs
CHANGED
|
@@ -1,316 +1,167 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { execSync } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
writeFileSync(path, content);
|
|
26
|
-
}
|
|
27
|
-
function buildPackageJSON(name) {
|
|
28
|
-
return `${JSON.stringify(
|
|
29
|
-
{
|
|
30
|
-
name,
|
|
31
|
-
private: true,
|
|
32
|
-
type: "module",
|
|
33
|
-
version: "1.0.0",
|
|
34
|
-
scripts: {
|
|
35
|
-
dev: "faas dev",
|
|
36
|
-
build: "faas build",
|
|
37
|
-
start: "faas start",
|
|
38
|
-
check: "faas check",
|
|
39
|
-
test: "vitest run"
|
|
40
|
-
},
|
|
41
|
-
dependencies: {
|
|
42
|
-
"@faasjs/http": "*",
|
|
43
|
-
faasjs: "*",
|
|
44
|
-
react: "*",
|
|
45
|
-
"react-dom": "*",
|
|
46
|
-
zod: "*"
|
|
47
|
-
},
|
|
48
|
-
devDependencies: {
|
|
49
|
-
"@biomejs/biome": "*",
|
|
50
|
-
"@faasjs/lint": "*",
|
|
51
|
-
"@faasjs/test": "*",
|
|
52
|
-
"@faasjs/vite": "*",
|
|
53
|
-
"@types/node": "*",
|
|
54
|
-
"@types/react": "*",
|
|
55
|
-
"@types/react-dom": "*",
|
|
56
|
-
"@vitejs/plugin-react": "*",
|
|
57
|
-
jsdom: "*",
|
|
58
|
-
typescript: "*",
|
|
59
|
-
vite: "*",
|
|
60
|
-
vitest: "*"
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
null,
|
|
64
|
-
2
|
|
65
|
-
)}
|
|
66
|
-
`;
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import enquirer from "enquirer";
|
|
8
|
+
//#region package.json
|
|
9
|
+
var version = "8.0.0-beta.40";
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/action/index.ts
|
|
12
|
+
const prompt = enquirer.prompt;
|
|
13
|
+
const validateName = (input) => Validator.name(input);
|
|
14
|
+
const templateRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "template");
|
|
15
|
+
const ignoredTemplateEntries = new Set(["node_modules"]);
|
|
16
|
+
const Validator = { name(input) {
|
|
17
|
+
const match = /^[a-z0-9-_]+$/i.test(input) ? true : "Must be a-z, 0-9 or -_";
|
|
18
|
+
if (match !== true) return match;
|
|
19
|
+
if (existsSync(input)) return `${input} folder exists, please try another name`;
|
|
20
|
+
return true;
|
|
21
|
+
} };
|
|
22
|
+
function getTemplateNames() {
|
|
23
|
+
return readdirSync(templateRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
67
24
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
dist/
|
|
73
|
-
coverage/
|
|
74
|
-
`
|
|
75
|
-
);
|
|
76
|
-
writeFile(
|
|
77
|
-
join(rootPath, "biome.json"),
|
|
78
|
-
`{
|
|
79
|
-
"extends": ["@faasjs/lint/biome"]
|
|
25
|
+
function resolveTemplateName(template = "admin") {
|
|
26
|
+
const templates = getTemplateNames();
|
|
27
|
+
if (templates.includes(template)) return template;
|
|
28
|
+
throw new Error(`Unknown template "${template}". Available templates: ${templates.join(", ")}`);
|
|
80
29
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
writeFile(
|
|
84
|
-
join(rootPath, "tsconfig.json"),
|
|
85
|
-
`{
|
|
86
|
-
"compilerOptions": {
|
|
87
|
-
"target": "ES2022",
|
|
88
|
-
"module": "ESNext",
|
|
89
|
-
"moduleResolution": "Bundler",
|
|
90
|
-
"jsx": "react-jsx",
|
|
91
|
-
"strict": true,
|
|
92
|
-
"types": ["vitest/globals"]
|
|
93
|
-
},
|
|
94
|
-
"include": ["src", "vite.config.ts", "server.ts"]
|
|
30
|
+
function renderTemplate(content, replacements) {
|
|
31
|
+
return Object.entries(replacements).reduce((result, [key, value]) => result.replaceAll(`{{${key}}}`, value), content);
|
|
95
32
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
writeFile(
|
|
99
|
-
join(rootPath, "index.html"),
|
|
100
|
-
`<!doctype html>
|
|
101
|
-
<html lang="en">
|
|
102
|
-
<head>
|
|
103
|
-
<meta charset="UTF-8" />
|
|
104
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
105
|
-
<title>FaasJS App</title>
|
|
106
|
-
</head>
|
|
107
|
-
<body>
|
|
108
|
-
<div id="root"></div>
|
|
109
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
110
|
-
</body>
|
|
111
|
-
</html>
|
|
112
|
-
`
|
|
113
|
-
);
|
|
114
|
-
writeFile(
|
|
115
|
-
join(rootPath, "vite.config.ts"),
|
|
116
|
-
`import { viteFaasJsServer } from '@faasjs/vite'
|
|
117
|
-
import react from '@vitejs/plugin-react'
|
|
118
|
-
import { defineConfig } from 'vite'
|
|
119
|
-
|
|
120
|
-
export default defineConfig({
|
|
121
|
-
server: {
|
|
122
|
-
host: '0.0.0.0',
|
|
123
|
-
},
|
|
124
|
-
plugins: [react(), viteFaasJsServer()],
|
|
125
|
-
})
|
|
126
|
-
`
|
|
127
|
-
);
|
|
128
|
-
writeFile(
|
|
129
|
-
join(rootPath, "server.ts"),
|
|
130
|
-
`import { dirname, join } from 'node:path'
|
|
131
|
-
import { fileURLToPath } from 'node:url'
|
|
132
|
-
import { Server, staticHandler } from '@faasjs/server'
|
|
133
|
-
|
|
134
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
135
|
-
const __dirname = dirname(__filename)
|
|
136
|
-
|
|
137
|
-
const publicHandler = staticHandler({
|
|
138
|
-
root: join(__dirname, 'public'),
|
|
139
|
-
notFound: false,
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
const distHandler = staticHandler({
|
|
143
|
-
root: join(__dirname, 'dist'),
|
|
144
|
-
notFound: 'index.html',
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
new Server(join(__dirname, 'src'), {
|
|
148
|
-
beforeHandle: async (req, res, ctx) => {
|
|
149
|
-
if (!req.url || req.method !== 'GET') return
|
|
150
|
-
|
|
151
|
-
await publicHandler(req, res, ctx)
|
|
152
|
-
await distHandler(req, res, ctx)
|
|
153
|
-
},
|
|
154
|
-
}).listen()
|
|
155
|
-
`
|
|
156
|
-
);
|
|
157
|
-
writeFile(
|
|
158
|
-
join(rootPath, "src", "faas.yaml"),
|
|
159
|
-
`defaults:
|
|
160
|
-
plugins:
|
|
161
|
-
http:
|
|
162
|
-
config:
|
|
163
|
-
cookie:
|
|
164
|
-
secure: false
|
|
165
|
-
session:
|
|
166
|
-
secret: secret
|
|
167
|
-
development:
|
|
168
|
-
testing:
|
|
169
|
-
production:
|
|
170
|
-
`
|
|
171
|
-
);
|
|
172
|
-
writeFile(
|
|
173
|
-
join(rootPath, "src", "main.tsx"),
|
|
174
|
-
`import { createRoot } from 'react-dom/client'
|
|
175
|
-
import HomePage from './pages/home'
|
|
176
|
-
|
|
177
|
-
createRoot(document.getElementById('root') as HTMLElement).render(<HomePage />)
|
|
178
|
-
`
|
|
179
|
-
);
|
|
180
|
-
writeFile(
|
|
181
|
-
join(rootPath, "src", "pages", "home", "index.tsx"),
|
|
182
|
-
`import { useState } from 'react'
|
|
183
|
-
|
|
184
|
-
type ApiResponse = {
|
|
185
|
-
ok: boolean
|
|
186
|
-
data: string
|
|
187
|
-
error: null | {
|
|
188
|
-
code?: string
|
|
189
|
-
message: string
|
|
190
|
-
}
|
|
33
|
+
function generateSessionSecret() {
|
|
34
|
+
return randomBytes(32).toString("hex");
|
|
191
35
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
'Content-Type': 'application/json',
|
|
205
|
-
},
|
|
206
|
-
body: JSON.stringify({ name: 'world' }),
|
|
207
|
-
}).then(res => res.json() as Promise<ApiResponse>)
|
|
208
|
-
|
|
209
|
-
if (data.ok) setMessage(data.data)
|
|
210
|
-
else setMessage(data.error?.message || 'Unknown error')
|
|
211
|
-
} catch (error: any) {
|
|
212
|
-
setMessage(error?.message || 'Unknown error')
|
|
213
|
-
} finally {
|
|
214
|
-
setLoading(false)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return (
|
|
219
|
-
<main style={{ margin: '5rem auto', maxWidth: 420, padding: 24 }}>
|
|
220
|
-
<h1>FaasJS Starter</h1>
|
|
221
|
-
<p>{message}</p>
|
|
222
|
-
<button type="button" onClick={fetchMessage} disabled={loading}>
|
|
223
|
-
{loading ? 'Loading...' : 'Call /home/api/hello'}
|
|
224
|
-
</button>
|
|
225
|
-
</main>
|
|
226
|
-
)
|
|
36
|
+
function copyTemplateDirectory(sourcePath, targetPath, replacements) {
|
|
37
|
+
mkdirSync(targetPath, { recursive: true });
|
|
38
|
+
for (const entry of readdirSync(sourcePath, { withFileTypes: true })) {
|
|
39
|
+
if (ignoredTemplateEntries.has(entry.name)) continue;
|
|
40
|
+
const nextSourcePath = join(sourcePath, entry.name);
|
|
41
|
+
const nextTargetPath = join(targetPath, entry.name === "gitignore" ? ".gitignore" : entry.name);
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
copyTemplateDirectory(nextSourcePath, nextTargetPath, replacements);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
writeFileSync(nextTargetPath, renderTemplate(readFileSync(nextSourcePath, "utf8"), replacements));
|
|
47
|
+
}
|
|
227
48
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
join(rootPath, "src", "pages", "home", "api", "hello.func.ts"),
|
|
232
|
-
`import { useHttpFunc } from '@faasjs/http'
|
|
233
|
-
import { z } from 'zod'
|
|
234
|
-
|
|
235
|
-
const schema = z
|
|
236
|
-
.object({
|
|
237
|
-
name: z.string().optional(),
|
|
238
|
-
})
|
|
239
|
-
.required()
|
|
240
|
-
|
|
241
|
-
export const func = useHttpFunc<z.infer<typeof schema>>(() => {
|
|
242
|
-
return async ({ params }) => {
|
|
243
|
-
const parsed = schema.parse(params || {})
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
ok: true,
|
|
247
|
-
data: \`Hello, \${parsed.name || 'FaasJS'}\`,
|
|
248
|
-
error: null,
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
`
|
|
253
|
-
);
|
|
254
|
-
writeFile(
|
|
255
|
-
join(rootPath, "src", "pages", "home", "api", "__tests__", "hello.test.ts"),
|
|
256
|
-
`import { test } from '@faasjs/test'
|
|
257
|
-
import { func } from '../hello.func'
|
|
258
|
-
|
|
259
|
-
describe('home/api/hello', () => {
|
|
260
|
-
it('should work', async () => {
|
|
261
|
-
const testFunc = test(func)
|
|
262
|
-
|
|
263
|
-
const { statusCode, data } = await testFunc.JSONhandler({ name: 'world' })
|
|
264
|
-
|
|
265
|
-
expect(statusCode).toEqual(200)
|
|
266
|
-
expect(data).toEqual({
|
|
267
|
-
ok: true,
|
|
268
|
-
data: 'Hello, world',
|
|
269
|
-
error: null,
|
|
270
|
-
})
|
|
271
|
-
})
|
|
272
|
-
})
|
|
273
|
-
`
|
|
274
|
-
);
|
|
49
|
+
function scaffold(rootPath, replacements, templateName) {
|
|
50
|
+
mkdirSync(rootPath);
|
|
51
|
+
copyTemplateDirectory(join(templateRoot, templateName), rootPath, replacements);
|
|
275
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Scaffold a new FaasJS app from a bundled template and install its dependencies.
|
|
55
|
+
*
|
|
56
|
+
* @param {object} [options] - Optional CLI arguments used to choose the project name and template.
|
|
57
|
+
* @param {string} [options.name] - Target folder name for the generated app.
|
|
58
|
+
* @param {string} [options.template] - Template name such as `admin` or `minimal`.
|
|
59
|
+
* @returns {Promise<void>} Resolves after the project is scaffolded, dependencies are installed, action types are generated, and tests pass.
|
|
60
|
+
* @throws {Error} When the selected template is unknown.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* await action({
|
|
64
|
+
* name: 'faasjs-demo',
|
|
65
|
+
* template: 'admin',
|
|
66
|
+
* })
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
276
69
|
async function action(options = {}) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
execSync(`cd ${answers.name} && ${runtime} install`, { stdio: "inherit" });
|
|
295
|
-
if (runtime === "bun") {
|
|
296
|
-
execSync(`cd ${answers.name} && bun test`, { stdio: "inherit" });
|
|
297
|
-
} else execSync(`cd ${answers.name} && npm run test`, { stdio: "inherit" });
|
|
70
|
+
const templateName = resolveTemplateName(options.template);
|
|
71
|
+
const answers = Object.assign(options, {});
|
|
72
|
+
if (!options.name || Validator.name(options.name) !== true) answers.name = await prompt({
|
|
73
|
+
type: "input",
|
|
74
|
+
name: "value",
|
|
75
|
+
message: "Project name",
|
|
76
|
+
initial: "faasjs",
|
|
77
|
+
validate: validateName
|
|
78
|
+
}).then((res) => res.value);
|
|
79
|
+
if (!answers.name) return;
|
|
80
|
+
scaffold(answers.name, {
|
|
81
|
+
name: answers.name,
|
|
82
|
+
secret: generateSessionSecret()
|
|
83
|
+
}, templateName);
|
|
84
|
+
execSync(`cd ${answers.name} && npm install`, { stdio: "inherit" });
|
|
85
|
+
execSync(`cd ${answers.name} && npm run types`, { stdio: "inherit" });
|
|
86
|
+
execSync(`cd ${answers.name} && npm run test`, { stdio: "inherit" });
|
|
298
87
|
}
|
|
299
|
-
|
|
300
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Register the `create-faas-app` command on a Commander program.
|
|
90
|
+
*
|
|
91
|
+
* @param {Command} program - Commander program instance to register the command on.
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const program = new Command()
|
|
95
|
+
*
|
|
96
|
+
* registerCreateFaasApp(program)
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
function registerCreateFaasApp(program) {
|
|
100
|
+
program.description("Create a new FaasJS app").on("--help", () => console.log(`Examples:
|
|
101
|
+
npx create-faas-app --name faasjs
|
|
102
|
+
npx create-faas-app --name faasjs-admin --template admin
|
|
103
|
+
npx create-faas-app --name faasjs-minimal --template minimal
|
|
104
|
+
|
|
105
|
+
Templates:
|
|
106
|
+
admin: recommended React + Ant Design + PostgreSQL starter
|
|
107
|
+
minimal: lighter React starter
|
|
108
|
+
|
|
109
|
+
Available:
|
|
110
|
+
${getTemplateNames().join(", ")}`)).option("--name <name>", "Project name").option("--template <template>", "Template name", "admin").action(action);
|
|
301
111
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/index.ts
|
|
114
|
+
/**
|
|
115
|
+
* # create-faas-app
|
|
116
|
+
*
|
|
117
|
+
* [](https://github.com/faasjs/faasjs/blob/main/packages/create-faas-app/LICENSE)
|
|
118
|
+
* [](https://www.npmjs.com/package/create-faas-app)
|
|
119
|
+
*
|
|
120
|
+
* Curated scaffolder for FaasJS projects. The `admin` template is the default
|
|
121
|
+
* React + Ant Design + PostgreSQL starter, and `minimal` provides a smaller
|
|
122
|
+
* React starter. After scaffolding, the CLI runs `npm install`, `npm run types`,
|
|
123
|
+
* and `npm run test` in the new project.
|
|
124
|
+
*
|
|
125
|
+
* ## Usage
|
|
126
|
+
*
|
|
127
|
+
* ```bash
|
|
128
|
+
* npx create-faas-app --name faasjs
|
|
129
|
+
* npx create-faas-app --name faasjs-admin --template admin
|
|
130
|
+
* npx create-faas-app --name faasjs-minimal --template minimal
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @packageDocumentation
|
|
134
|
+
*/
|
|
135
|
+
const commander = new Command();
|
|
136
|
+
commander.storeOptionsAsProperties(false).allowUnknownOption(true).version(version).name("create-faas-app").exitOverride();
|
|
137
|
+
registerCreateFaasApp(commander);
|
|
138
|
+
/**
|
|
139
|
+
* Run the `create-faas-app` CLI with a provided argv array.
|
|
140
|
+
*
|
|
141
|
+
* The array should use the same shape as `process.argv`, including executable
|
|
142
|
+
* and script slots. Parsing may prompt for a project name, create files, install
|
|
143
|
+
* dependencies, generate FaasJS action types, and run template tests. Commander
|
|
144
|
+
* help exits are swallowed and return the shared program; unexpected errors are
|
|
145
|
+
* printed with `console.error` and also return the program.
|
|
146
|
+
*
|
|
147
|
+
* @param {string[]} argv - CLI arguments forwarded to Commander.
|
|
148
|
+
* @returns {Promise<Command>} Commander program instance after parsing.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* import { main } from 'create-faas-app'
|
|
153
|
+
*
|
|
154
|
+
* await main(['node', 'create-faas-app', '--help'])
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
307
157
|
async function main(argv) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
158
|
+
try {
|
|
159
|
+
await commander.parseAsync(argv);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "commander.helpDisplayed") return commander;
|
|
162
|
+
console.error(error);
|
|
163
|
+
}
|
|
164
|
+
return commander;
|
|
314
165
|
}
|
|
315
|
-
|
|
166
|
+
//#endregion
|
|
316
167
|
export { main };
|
package/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,44 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-faas-app",
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.cjs",
|
|
7
|
-
"module": "dist/index.mjs",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"bin": {
|
|
10
|
-
"create-faas-app": "index.mjs"
|
|
11
|
-
},
|
|
12
|
-
"exports": {
|
|
13
|
-
".": {
|
|
14
|
-
"types": "./dist/index.d.ts",
|
|
15
|
-
"import": "./dist/index.mjs",
|
|
16
|
-
"require": "./dist/index.cjs"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
3
|
+
"version": "8.0.0-beta.41",
|
|
19
4
|
"homepage": "https://faasjs.com/doc/create-faas-app",
|
|
5
|
+
"bugs": {
|
|
6
|
+
"url": "https://github.com/faasjs/faasjs/issues"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
20
9
|
"repository": {
|
|
21
10
|
"type": "git",
|
|
22
11
|
"url": "git+https://github.com/faasjs/faasjs.git",
|
|
23
12
|
"directory": "packages/create-faas-app"
|
|
24
13
|
},
|
|
25
|
-
"bugs": {
|
|
26
|
-
"url": "https://github.com/faasjs/faasjs/issues"
|
|
27
|
-
},
|
|
28
14
|
"funding": "https://github.com/sponsors/faasjs",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
15
|
+
"bin": {
|
|
16
|
+
"create-faas-app": "index.mjs"
|
|
31
17
|
},
|
|
32
18
|
"files": [
|
|
33
19
|
"dist",
|
|
34
|
-
"index.
|
|
20
|
+
"index.mjs",
|
|
21
|
+
"template"
|
|
35
22
|
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "dist/index.mjs",
|
|
25
|
+
"module": "dist/index.mjs",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.mjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
36
33
|
"dependencies": {
|
|
37
34
|
"commander": ">=14.0.0",
|
|
38
35
|
"enquirer": "*"
|
|
39
36
|
},
|
|
40
37
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
38
|
+
"node": ">=26.0.0",
|
|
42
39
|
"npm": ">=11.0.0"
|
|
43
40
|
}
|
|
44
41
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/{{name}}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>FaasJS Ant Design App</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vp dev",
|
|
8
|
+
"build": "vp build",
|
|
9
|
+
"start": "node --import @faasjs/node-utils/register-hooks server.ts",
|
|
10
|
+
"types": "faas types",
|
|
11
|
+
"test": "vp test",
|
|
12
|
+
"db:new": "faasjs-pg new",
|
|
13
|
+
"db:status": "faasjs-pg status",
|
|
14
|
+
"db:migrate": "faasjs-pg migrate",
|
|
15
|
+
"db:up": "faasjs-pg up",
|
|
16
|
+
"db:down": "faasjs-pg down"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@faasjs/dev": "*",
|
|
20
|
+
"@faasjs/pg-dev": "*"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@faasjs/ant-design": "*",
|
|
24
|
+
"@faasjs/core": "*",
|
|
25
|
+
"@faasjs/pg": "*"
|
|
26
|
+
},
|
|
27
|
+
"overrides": {
|
|
28
|
+
"vite": "npm:@voidzero-dev/vite-plus-core",
|
|
29
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=26.0.0",
|
|
33
|
+
"npm": ">=11.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|