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.
Files changed (44) hide show
  1. package/README.md +8 -5
  2. package/dist/index.d.ts +16 -15
  3. package/dist/index.mjs +155 -304
  4. package/index.mjs +1 -1
  5. package/package.json +20 -23
  6. package/template/admin/.env.example +1 -0
  7. package/template/admin/gitignore +4 -0
  8. package/template/admin/index.html +12 -0
  9. package/template/admin/package.json +35 -0
  10. package/template/admin/server.ts +33 -0
  11. package/template/admin/src/.faasjs/types.d.ts +16 -0
  12. package/template/admin/src/db/migrations/20250101000000_create_users.ts +12 -0
  13. package/template/admin/src/db/tables/users.ts +8 -0
  14. package/template/admin/src/faas.yaml +11 -0
  15. package/template/admin/src/features/auth/api/__tests__/me.test.ts +39 -0
  16. package/template/admin/src/features/auth/api/me.api.ts +23 -0
  17. package/template/admin/src/features/users/api/__tests__/create.test.ts +47 -0
  18. package/template/admin/src/features/users/api/__tests__/detail.test.ts +39 -0
  19. package/template/admin/src/features/users/api/__tests__/list.test.ts +31 -0
  20. package/template/admin/src/features/users/api/__tests__/update.test.ts +51 -0
  21. package/template/admin/src/features/users/api/create.api.ts +26 -0
  22. package/template/admin/src/features/users/api/detail.api.ts +23 -0
  23. package/template/admin/src/features/users/api/list.api.ts +22 -0
  24. package/template/admin/src/features/users/api/update.api.ts +35 -0
  25. package/template/admin/src/features/users/index.tsx +138 -0
  26. package/template/admin/src/main.tsx +24 -0
  27. package/template/admin/src/plugins/auth.ts +25 -0
  28. package/template/admin/src/types/faasjs-auth.d.ts +8 -0
  29. package/template/admin/tsconfig.json +4 -0
  30. package/template/admin/vite.config.ts +12 -0
  31. package/template/minimal/gitignore +4 -0
  32. package/template/minimal/index.html +12 -0
  33. package/template/minimal/package.json +27 -0
  34. package/template/minimal/server.ts +33 -0
  35. package/template/minimal/src/.faasjs/types.d.ts +12 -0
  36. package/template/minimal/src/faas.yaml +11 -0
  37. package/template/minimal/src/features/home/api/__tests__/hello.test.ts +17 -0
  38. package/template/minimal/src/features/home/api/hello.api.ts +13 -0
  39. package/template/minimal/src/features/home/index.tsx +37 -0
  40. package/template/minimal/src/main.tsx +5 -0
  41. package/template/minimal/src/react-client.ts +8 -0
  42. package/template/minimal/tsconfig.json +4 -0
  43. package/template/minimal/vite.config.ts +6 -0
  44. package/dist/index.cjs +0 -318
@@ -0,0 +1,27 @@
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
+ },
13
+ "devDependencies": {
14
+ "@faasjs/dev": "*"
15
+ },
16
+ "peerDependencies": {
17
+ "@faasjs/core": "*"
18
+ },
19
+ "overrides": {
20
+ "vite": "npm:@voidzero-dev/vite-plus-core",
21
+ "vitest": "npm:@voidzero-dev/vite-plus-test"
22
+ },
23
+ "engines": {
24
+ "node": ">=26.0.0",
25
+ "npm": ">=11.0.0"
26
+ }
27
+ }
@@ -0,0 +1,33 @@
1
+ import { dirname, join } from 'node:path'
2
+ import { loadEnvFile } from 'node:process'
3
+ import { fileURLToPath } from 'node:url'
4
+
5
+ import { Server, staticHandler } from '@faasjs/core'
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = dirname(__filename)
9
+
10
+ try {
11
+ loadEnvFile()
12
+ } catch (error) {
13
+ console.warn('[faasjs] Failed to load env file', error)
14
+ }
15
+
16
+ const publicHandler = staticHandler({
17
+ root: join(__dirname, 'public'),
18
+ notFound: false,
19
+ })
20
+
21
+ const distHandler = staticHandler({
22
+ root: join(__dirname, 'dist'),
23
+ notFound: 'index.html',
24
+ })
25
+
26
+ new Server(join(__dirname, 'src'), {
27
+ beforeHandle: async (req, res, ctx) => {
28
+ if (!req.url || req.method !== 'GET') return
29
+
30
+ await publicHandler(req, res, ctx)
31
+ await distHandler(req, res, ctx)
32
+ },
33
+ }).listen()
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generated by @faasjs/dev.
3
+ *
4
+ * Do not edit this file manually.
5
+ */
6
+ import type { InferFaasAction } from '@faasjs/types'
7
+
8
+ declare module '@faasjs/types' {
9
+ interface FaasActions {
10
+ "features/home/api/hello": InferFaasAction<typeof import("../features/home/api/hello.api")>
11
+ }
12
+ }
@@ -0,0 +1,11 @@
1
+ defaults:
2
+ server:
3
+ root: .
4
+ base: /
5
+ plugins:
6
+ http:
7
+ config:
8
+ cookie:
9
+ secure: false
10
+ session:
11
+ secret: '{{secret}}'
@@ -0,0 +1,17 @@
1
+ import { testApi } from '@faasjs/dev'
2
+ import { describe, it, expect } from 'vitest'
3
+
4
+ import api from '../hello.api'
5
+
6
+ describe('features/home/api/hello', () => {
7
+ it('should work', async () => {
8
+ const handler = testApi(api)
9
+
10
+ const { statusCode, data } = await handler({ name: 'world' })
11
+
12
+ expect(statusCode).toEqual(200)
13
+ expect(data).toEqual({
14
+ message: 'Hello, world!',
15
+ })
16
+ })
17
+ })
@@ -0,0 +1,13 @@
1
+ import { defineApi } from '@faasjs/core'
2
+ import { z } from '@faasjs/utils'
3
+
4
+ export default defineApi({
5
+ schema: z.object({
6
+ name: z.nonemptystring().optional(),
7
+ }),
8
+ async handler({ params }) {
9
+ return {
10
+ message: `Hello, ${params.name || 'FaasJS'}!`,
11
+ }
12
+ },
13
+ })
@@ -0,0 +1,37 @@
1
+ import { useState } from 'react'
2
+
3
+ import { useFaas } from '../../react-client'
4
+
5
+ export default function HomePage() {
6
+ const [name, setName] = useState('FaasJS')
7
+
8
+ const { data, loading, reload } = useFaas(
9
+ 'features/home/api/hello',
10
+ { name: name.trim() || undefined },
11
+ { skip: true },
12
+ )
13
+
14
+ return (
15
+ <main style={{ margin: '5rem auto', maxWidth: 420, padding: 24 }}>
16
+ <h1>FaasJS Minimal App</h1>
17
+ <p>{data?.message || 'Click button to call API'}</p>
18
+
19
+ <label style={{ display: 'block', marginBottom: 12 }}>
20
+ Name:
21
+ <input
22
+ style={{ marginLeft: 8 }}
23
+ value={name}
24
+ onChange={(event) => setName(event.target.value)}
25
+ />
26
+ </label>
27
+
28
+ <button
29
+ type="button"
30
+ onClick={() => reload({ name: name.trim() || undefined })}
31
+ disabled={loading}
32
+ >
33
+ {loading ? 'Loading...' : 'Call features/home/api/hello'}
34
+ </button>
35
+ </main>
36
+ )
37
+ }
@@ -0,0 +1,5 @@
1
+ import { createRoot } from 'react-dom/client'
2
+
3
+ import HomePage from './features/home'
4
+
5
+ createRoot(document.getElementById('root') as HTMLElement).render(<HomePage />)
@@ -0,0 +1,8 @@
1
+ import { FaasReactClient } from '@faasjs/react'
2
+
3
+ const client = FaasReactClient({
4
+ baseUrl: '/',
5
+ })
6
+
7
+ export const faas = client.faas
8
+ export const useFaas = client.useFaas
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "@faasjs/types/tsconfig/build.json",
3
+ "include": ["src", "src/.faasjs/types.d.ts", "vite.config.ts", "server.ts"]
4
+ }
@@ -0,0 +1,6 @@
1
+ import { ViteConfig } from '@faasjs/dev'
2
+ import { defineConfig } from 'vite-plus'
3
+
4
+ export default defineConfig({
5
+ ...ViteConfig,
6
+ })
package/dist/index.cjs DELETED
@@ -1,318 +0,0 @@
1
- 'use strict';
2
-
3
- var commander$1 = require('commander');
4
- var child_process = require('child_process');
5
- var fs = require('fs');
6
- var path = require('path');
7
- var enquirer = require('enquirer');
8
-
9
- // src/index.ts
10
-
11
- // package.json
12
- var package_default = {
13
- version: "v8.0.0-beta.3"};
14
- var Validator = {
15
- name(input) {
16
- const match = /^[a-z0-9-_]+$/i.test(input) ? true : "Must be a-z, 0-9 or -_";
17
- if (match !== true) return match;
18
- if (fs.existsSync(input))
19
- return `${input} folder exists, please try another name`;
20
- return true;
21
- }
22
- };
23
- function writeFile(path$1, content) {
24
- fs.mkdirSync(path.dirname(path$1), {
25
- recursive: true
26
- });
27
- fs.writeFileSync(path$1, content);
28
- }
29
- function buildPackageJSON(name) {
30
- return `${JSON.stringify(
31
- {
32
- name,
33
- private: true,
34
- type: "module",
35
- version: "1.0.0",
36
- scripts: {
37
- dev: "faas dev",
38
- build: "faas build",
39
- start: "faas start",
40
- check: "faas check",
41
- test: "vitest run"
42
- },
43
- dependencies: {
44
- "@faasjs/http": "*",
45
- faasjs: "*",
46
- react: "*",
47
- "react-dom": "*",
48
- zod: "*"
49
- },
50
- devDependencies: {
51
- "@biomejs/biome": "*",
52
- "@faasjs/lint": "*",
53
- "@faasjs/test": "*",
54
- "@faasjs/vite": "*",
55
- "@types/node": "*",
56
- "@types/react": "*",
57
- "@types/react-dom": "*",
58
- "@vitejs/plugin-react": "*",
59
- jsdom: "*",
60
- typescript: "*",
61
- vite: "*",
62
- vitest: "*"
63
- }
64
- },
65
- null,
66
- 2
67
- )}
68
- `;
69
- }
70
- function scaffold(rootPath) {
71
- writeFile(
72
- path.join(rootPath, ".gitignore"),
73
- `node_modules/
74
- dist/
75
- coverage/
76
- `
77
- );
78
- writeFile(
79
- path.join(rootPath, "biome.json"),
80
- `{
81
- "extends": ["@faasjs/lint/biome"]
82
- }
83
- `
84
- );
85
- writeFile(
86
- path.join(rootPath, "tsconfig.json"),
87
- `{
88
- "compilerOptions": {
89
- "target": "ES2022",
90
- "module": "ESNext",
91
- "moduleResolution": "Bundler",
92
- "jsx": "react-jsx",
93
- "strict": true,
94
- "types": ["vitest/globals"]
95
- },
96
- "include": ["src", "vite.config.ts", "server.ts"]
97
- }
98
- `
99
- );
100
- writeFile(
101
- path.join(rootPath, "index.html"),
102
- `<!doctype html>
103
- <html lang="en">
104
- <head>
105
- <meta charset="UTF-8" />
106
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
107
- <title>FaasJS App</title>
108
- </head>
109
- <body>
110
- <div id="root"></div>
111
- <script type="module" src="/src/main.tsx"></script>
112
- </body>
113
- </html>
114
- `
115
- );
116
- writeFile(
117
- path.join(rootPath, "vite.config.ts"),
118
- `import { viteFaasJsServer } from '@faasjs/vite'
119
- import react from '@vitejs/plugin-react'
120
- import { defineConfig } from 'vite'
121
-
122
- export default defineConfig({
123
- server: {
124
- host: '0.0.0.0',
125
- },
126
- plugins: [react(), viteFaasJsServer()],
127
- })
128
- `
129
- );
130
- writeFile(
131
- path.join(rootPath, "server.ts"),
132
- `import { dirname, join } from 'node:path'
133
- import { fileURLToPath } from 'node:url'
134
- import { Server, staticHandler } from '@faasjs/server'
135
-
136
- const __filename = fileURLToPath(import.meta.url)
137
- const __dirname = dirname(__filename)
138
-
139
- const publicHandler = staticHandler({
140
- root: join(__dirname, 'public'),
141
- notFound: false,
142
- })
143
-
144
- const distHandler = staticHandler({
145
- root: join(__dirname, 'dist'),
146
- notFound: 'index.html',
147
- })
148
-
149
- new Server(join(__dirname, 'src'), {
150
- beforeHandle: async (req, res, ctx) => {
151
- if (!req.url || req.method !== 'GET') return
152
-
153
- await publicHandler(req, res, ctx)
154
- await distHandler(req, res, ctx)
155
- },
156
- }).listen()
157
- `
158
- );
159
- writeFile(
160
- path.join(rootPath, "src", "faas.yaml"),
161
- `defaults:
162
- plugins:
163
- http:
164
- config:
165
- cookie:
166
- secure: false
167
- session:
168
- secret: secret
169
- development:
170
- testing:
171
- production:
172
- `
173
- );
174
- writeFile(
175
- path.join(rootPath, "src", "main.tsx"),
176
- `import { createRoot } from 'react-dom/client'
177
- import HomePage from './pages/home'
178
-
179
- createRoot(document.getElementById('root') as HTMLElement).render(<HomePage />)
180
- `
181
- );
182
- writeFile(
183
- path.join(rootPath, "src", "pages", "home", "index.tsx"),
184
- `import { useState } from 'react'
185
-
186
- type ApiResponse = {
187
- ok: boolean
188
- data: string
189
- error: null | {
190
- code?: string
191
- message: string
192
- }
193
- }
194
-
195
- export default function HomePage() {
196
- const [message, setMessage] = useState('Click button to call API')
197
- const [loading, setLoading] = useState(false)
198
-
199
- const fetchMessage = async () => {
200
- setLoading(true)
201
-
202
- try {
203
- const data = await fetch('/home/api/hello', {
204
- method: 'POST',
205
- headers: {
206
- 'Content-Type': 'application/json',
207
- },
208
- body: JSON.stringify({ name: 'world' }),
209
- }).then(res => res.json() as Promise<ApiResponse>)
210
-
211
- if (data.ok) setMessage(data.data)
212
- else setMessage(data.error?.message || 'Unknown error')
213
- } catch (error: any) {
214
- setMessage(error?.message || 'Unknown error')
215
- } finally {
216
- setLoading(false)
217
- }
218
- }
219
-
220
- return (
221
- <main style={{ margin: '5rem auto', maxWidth: 420, padding: 24 }}>
222
- <h1>FaasJS Starter</h1>
223
- <p>{message}</p>
224
- <button type="button" onClick={fetchMessage} disabled={loading}>
225
- {loading ? 'Loading...' : 'Call /home/api/hello'}
226
- </button>
227
- </main>
228
- )
229
- }
230
- `
231
- );
232
- writeFile(
233
- path.join(rootPath, "src", "pages", "home", "api", "hello.func.ts"),
234
- `import { useHttpFunc } from '@faasjs/http'
235
- import { z } from 'zod'
236
-
237
- const schema = z
238
- .object({
239
- name: z.string().optional(),
240
- })
241
- .required()
242
-
243
- export const func = useHttpFunc<z.infer<typeof schema>>(() => {
244
- return async ({ params }) => {
245
- const parsed = schema.parse(params || {})
246
-
247
- return {
248
- ok: true,
249
- data: \`Hello, \${parsed.name || 'FaasJS'}\`,
250
- error: null,
251
- }
252
- }
253
- })
254
- `
255
- );
256
- writeFile(
257
- path.join(rootPath, "src", "pages", "home", "api", "__tests__", "hello.test.ts"),
258
- `import { test } from '@faasjs/test'
259
- import { func } from '../hello.func'
260
-
261
- describe('home/api/hello', () => {
262
- it('should work', async () => {
263
- const testFunc = test(func)
264
-
265
- const { statusCode, data } = await testFunc.JSONhandler({ name: 'world' })
266
-
267
- expect(statusCode).toEqual(200)
268
- expect(data).toEqual({
269
- ok: true,
270
- data: 'Hello, world',
271
- error: null,
272
- })
273
- })
274
- })
275
- `
276
- );
277
- }
278
- async function action(options = {}) {
279
- const answers = Object.assign(options, {});
280
- if (!options.name || Validator.name(options.name) !== true)
281
- answers.name = await enquirer.prompt({
282
- type: "input",
283
- name: "value",
284
- message: "Project name",
285
- initial: "faasjs",
286
- validate: Validator.name
287
- }).then((res) => res.value);
288
- if (!answers.name) return;
289
- const runtime = process.versions.bun ? "bun" : "npm";
290
- fs.mkdirSync(answers.name);
291
- fs.writeFileSync(
292
- path.join(answers.name, "package.json"),
293
- buildPackageJSON(answers.name)
294
- );
295
- scaffold(answers.name);
296
- child_process.execSync(`cd ${answers.name} && ${runtime} install`, { stdio: "inherit" });
297
- if (runtime === "bun") {
298
- child_process.execSync(`cd ${answers.name} && bun test`, { stdio: "inherit" });
299
- } else child_process.execSync(`cd ${answers.name} && npm run test`, { stdio: "inherit" });
300
- }
301
- function action_default(program) {
302
- program.description("Create a new faas app").on("--help", () => console.log("Examples:\nnpx create-faas-app")).option("--name <name>", "Project name").action(action);
303
- }
304
-
305
- // src/index.ts
306
- var commander = new commander$1.Command();
307
- commander.storeOptionsAsProperties(false).allowUnknownOption(true).version(package_default.version).name("create-faas-app").exitOverride();
308
- action_default(commander);
309
- async function main(argv) {
310
- try {
311
- await commander.parseAsync(argv);
312
- } catch (error) {
313
- console.error(error);
314
- }
315
- return commander;
316
- }
317
-
318
- exports.main = main;