create-faas-app 8.0.0-beta.3 → 8.0.0-beta.5

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 (3) hide show
  1. package/dist/index.cjs +243 -89
  2. package/dist/index.mjs +244 -90
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -10,7 +10,7 @@ var enquirer = require('enquirer');
10
10
 
11
11
  // package.json
12
12
  var package_default = {
13
- version: "v8.0.0-beta.2"};
13
+ version: "v8.0.0-beta.4"};
14
14
  var Validator = {
15
15
  name(input) {
16
16
  const match = /^[a-z0-9-_]+$/i.test(input) ? true : "Must be a-z, 0-9 or -_";
@@ -20,126 +20,280 @@ var Validator = {
20
20
  return true;
21
21
  }
22
22
  };
23
- async function action(options = {}) {
24
- const answers = Object.assign(options, {});
25
- if (!options.name || Validator.name(options.name) !== true)
26
- answers.name = await enquirer.prompt({
27
- type: "input",
28
- name: "value",
29
- message: "Project name",
30
- initial: "faasjs",
31
- validate: Validator.name
32
- }).then((res) => res.value);
33
- if (!answers.name) return;
34
- fs.mkdirSync(answers.name);
35
- const runtime = process.versions.bun ? "bun" : "npm";
36
- fs.writeFileSync(
37
- path.join(answers.name, "faas.yaml"),
38
- `defaults:
39
- plugins:
40
- development:
41
- testing:
42
- staging:
43
- production:
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: "vite",
38
+ build: "vite build",
39
+ start: "node server.ts",
40
+ check: "tsc --noEmit && biome check .",
41
+ test: "vitest run"
42
+ },
43
+ dependencies: {
44
+ "@faasjs/func": "*",
45
+ "@faasjs/http": "*",
46
+ faasjs: "*",
47
+ react: "*",
48
+ "react-dom": "*",
49
+ zod: "*"
50
+ },
51
+ devDependencies: {
52
+ "@biomejs/biome": "*",
53
+ "@faasjs/dev": "*",
54
+ "@faasjs/lint": "*",
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/
44
76
  `
45
77
  );
46
- fs.writeFileSync(
47
- path.join(answers.name, "package.json"),
78
+ writeFile(
79
+ path.join(rootPath, "biome.json"),
48
80
  `{
49
- "name": "${answers.name}",
50
- "version": "1.0.0",
51
- "private": true,
52
- "scripts": {
53
- "serve": "faas server",
54
- "test": "vitest run"
55
- },
56
- "dependencies": {
57
- "faasjs": "*"
58
- },
59
- "devDependencies": {
60
- "vitest": "*"
61
- }
62
- }`
81
+ "extends": ["@faasjs/lint/biome"]
82
+ }
83
+ `
63
84
  );
64
- fs.writeFileSync(
65
- path.join(answers.name, "tsconfig.json"),
85
+ writeFile(
86
+ path.join(rootPath, "tsconfig.json"),
66
87
  `{
67
88
  "compilerOptions": {
68
- "downlevelIteration": true,
69
- "esModuleInterop": true,
70
- "target": "ES2019",
89
+ "target": "ES2022",
71
90
  "module": "ESNext",
72
- "moduleResolution": "node",
73
- "baseUrl": "."
74
- }
91
+ "moduleResolution": "Bundler",
92
+ "jsx": "react-jsx",
93
+ "strict": true,
94
+ "types": ["vitest/globals"]
95
+ },
96
+ "include": ["src", "vite.config.ts", "server.ts"]
75
97
  }
76
98
  `
77
99
  );
78
- fs.writeFileSync(
79
- path.join(answers.name, ".gitignore"),
80
- `node_modules/
81
- tmp/
82
- coverage/
83
- *.tmp.js
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>
84
114
  `
85
115
  );
86
- fs.mkdirSync(path.join(answers.name, ".vscode"));
87
- fs.writeFileSync(
88
- path.join(answers.name, ".vscode", "settings.json"),
89
- `{
90
- "editor.detectIndentation": true,
91
- "editor.insertSpaces": true,
92
- "editor.tabSize": 2,
93
- "editor.codeActionsOnSave": {
94
- "source.fixAll": true
116
+ writeFile(
117
+ path.join(rootPath, "vite.config.ts"),
118
+ `import { viteFaasJsServer } from '@faasjs/dev'
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',
95
125
  },
96
- "editor.wordWrap": "on",
97
- "files.insertFinalNewline": true,
98
- "files.trimFinalNewlines": true,
99
- "files.trimTrailingWhitespace": true
100
- }
126
+ plugins: [react(), viteFaasJsServer()],
127
+ })
101
128
  `
102
129
  );
103
- fs.writeFileSync(
104
- path.join(answers.name, ".vscode", "extensions.json"),
105
- `{
106
- "recommendations": [
107
- "faasjs.faasjs-snippets"
108
- ]
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
+ )
109
229
  }
110
230
  `
111
231
  );
112
- child_process.execSync(`cd ${answers.name} && ${runtime} install`, { stdio: "inherit" });
113
- fs.writeFileSync(
114
- path.join(answers.name, "index.func.ts"),
115
- `import { useFunc } from '@faasjs/func'
116
- import { useHttp } from '@faasjs/http'
232
+ writeFile(
233
+ path.join(rootPath, "src", "pages", "home", "api", "hello.func.ts"),
234
+ `import { defineFunc } from '@faasjs/func'
235
+ import { z } from 'zod'
117
236
 
118
- export const func = useFunc(() => {
119
- const http = useHttp<{ name: string }>()
237
+ const schema = z
238
+ .object({
239
+ name: z.string().optional(),
240
+ })
241
+ .required()
120
242
 
121
- return async () => \`Hello, \${http.params.name}\`
122
- })
243
+ export const func = defineFunc<{ params?: z.infer<typeof schema> }>(
244
+ async ({ event }) => {
245
+ const parsed = schema.parse(event.params || {})
246
+
247
+ return {
248
+ ok: true,
249
+ data: \`Hello, \${parsed.name || 'FaasJS'}\`,
250
+ error: null,
251
+ }
252
+ }
253
+ )
123
254
  `
124
255
  );
125
- fs.mkdirSync(path.join(answers.name, "__tests__"));
126
- fs.writeFileSync(
127
- path.join(answers.name, "__tests__", "index.test.ts"),
128
- `import { test } from '@faasjs/test'
129
- import { func } from '../index.func'
256
+ writeFile(
257
+ path.join(rootPath, "src", "pages", "home", "api", "__tests__", "hello.test.ts"),
258
+ `import { test } from '@faasjs/dev'
259
+ import { func } from '../hello.func'
130
260
 
131
- describe('hello', () => {
261
+ describe('home/api/hello', () => {
132
262
  it('should work', async () => {
133
263
  const testFunc = test(func)
134
264
 
135
- const { statusCode, data } = await testFunc.JSONhandler<string>({ name: 'world' })
265
+ const { statusCode, data } = await testFunc.JSONhandler({ name: 'world' })
136
266
 
137
267
  expect(statusCode).toEqual(200)
138
- expect(data).toEqual('Hello, world')
268
+ expect(data).toEqual({
269
+ ok: true,
270
+ data: 'Hello, world',
271
+ error: null,
272
+ })
139
273
  })
140
274
  })
141
275
  `
142
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" });
143
297
  if (runtime === "bun") {
144
298
  child_process.execSync(`cd ${answers.name} && bun test`, { stdio: "inherit" });
145
299
  } else child_process.execSync(`cd ${answers.name} && npm run test`, { stdio: "inherit" });
package/dist/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  import { Command } from 'commander';
2
2
  import { execSync } from 'child_process';
3
3
  import { mkdirSync, writeFileSync, existsSync } from 'fs';
4
- import { join } from 'path';
4
+ import { join, dirname } from 'path';
5
5
  import { prompt } from 'enquirer';
6
6
 
7
7
  // src/index.ts
8
8
 
9
9
  // package.json
10
10
  var package_default = {
11
- version: "v8.0.0-beta.2"};
11
+ version: "v8.0.0-beta.4"};
12
12
  var Validator = {
13
13
  name(input) {
14
14
  const match = /^[a-z0-9-_]+$/i.test(input) ? true : "Must be a-z, 0-9 or -_";
@@ -18,126 +18,280 @@ var Validator = {
18
18
  return true;
19
19
  }
20
20
  };
21
- async function action(options = {}) {
22
- const answers = Object.assign(options, {});
23
- if (!options.name || Validator.name(options.name) !== true)
24
- answers.name = await prompt({
25
- type: "input",
26
- name: "value",
27
- message: "Project name",
28
- initial: "faasjs",
29
- validate: Validator.name
30
- }).then((res) => res.value);
31
- if (!answers.name) return;
32
- mkdirSync(answers.name);
33
- const runtime = process.versions.bun ? "bun" : "npm";
34
- writeFileSync(
35
- join(answers.name, "faas.yaml"),
36
- `defaults:
37
- plugins:
38
- development:
39
- testing:
40
- staging:
41
- production:
21
+ function writeFile(path, content) {
22
+ mkdirSync(dirname(path), {
23
+ recursive: true
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: "vite",
36
+ build: "vite build",
37
+ start: "node server.ts",
38
+ check: "tsc --noEmit && biome check .",
39
+ test: "vitest run"
40
+ },
41
+ dependencies: {
42
+ "@faasjs/func": "*",
43
+ "@faasjs/http": "*",
44
+ faasjs: "*",
45
+ react: "*",
46
+ "react-dom": "*",
47
+ zod: "*"
48
+ },
49
+ devDependencies: {
50
+ "@biomejs/biome": "*",
51
+ "@faasjs/dev": "*",
52
+ "@faasjs/lint": "*",
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
+ `;
67
+ }
68
+ function scaffold(rootPath) {
69
+ writeFile(
70
+ join(rootPath, ".gitignore"),
71
+ `node_modules/
72
+ dist/
73
+ coverage/
42
74
  `
43
75
  );
44
- writeFileSync(
45
- join(answers.name, "package.json"),
76
+ writeFile(
77
+ join(rootPath, "biome.json"),
46
78
  `{
47
- "name": "${answers.name}",
48
- "version": "1.0.0",
49
- "private": true,
50
- "scripts": {
51
- "serve": "faas server",
52
- "test": "vitest run"
53
- },
54
- "dependencies": {
55
- "faasjs": "*"
56
- },
57
- "devDependencies": {
58
- "vitest": "*"
59
- }
60
- }`
79
+ "extends": ["@faasjs/lint/biome"]
80
+ }
81
+ `
61
82
  );
62
- writeFileSync(
63
- join(answers.name, "tsconfig.json"),
83
+ writeFile(
84
+ join(rootPath, "tsconfig.json"),
64
85
  `{
65
86
  "compilerOptions": {
66
- "downlevelIteration": true,
67
- "esModuleInterop": true,
68
- "target": "ES2019",
87
+ "target": "ES2022",
69
88
  "module": "ESNext",
70
- "moduleResolution": "node",
71
- "baseUrl": "."
72
- }
89
+ "moduleResolution": "Bundler",
90
+ "jsx": "react-jsx",
91
+ "strict": true,
92
+ "types": ["vitest/globals"]
93
+ },
94
+ "include": ["src", "vite.config.ts", "server.ts"]
73
95
  }
74
96
  `
75
97
  );
76
- writeFileSync(
77
- join(answers.name, ".gitignore"),
78
- `node_modules/
79
- tmp/
80
- coverage/
81
- *.tmp.js
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>
82
112
  `
83
113
  );
84
- mkdirSync(join(answers.name, ".vscode"));
85
- writeFileSync(
86
- join(answers.name, ".vscode", "settings.json"),
87
- `{
88
- "editor.detectIndentation": true,
89
- "editor.insertSpaces": true,
90
- "editor.tabSize": 2,
91
- "editor.codeActionsOnSave": {
92
- "source.fixAll": true
114
+ writeFile(
115
+ join(rootPath, "vite.config.ts"),
116
+ `import { viteFaasJsServer } from '@faasjs/dev'
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',
93
123
  },
94
- "editor.wordWrap": "on",
95
- "files.insertFinalNewline": true,
96
- "files.trimFinalNewlines": true,
97
- "files.trimTrailingWhitespace": true
98
- }
124
+ plugins: [react(), viteFaasJsServer()],
125
+ })
99
126
  `
100
127
  );
101
- writeFileSync(
102
- join(answers.name, ".vscode", "extensions.json"),
103
- `{
104
- "recommendations": [
105
- "faasjs.faasjs-snippets"
106
- ]
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
+ }
191
+ }
192
+
193
+ export default function HomePage() {
194
+ const [message, setMessage] = useState('Click button to call API')
195
+ const [loading, setLoading] = useState(false)
196
+
197
+ const fetchMessage = async () => {
198
+ setLoading(true)
199
+
200
+ try {
201
+ const data = await fetch('/home/api/hello', {
202
+ method: 'POST',
203
+ headers: {
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
+ )
107
227
  }
108
228
  `
109
229
  );
110
- execSync(`cd ${answers.name} && ${runtime} install`, { stdio: "inherit" });
111
- writeFileSync(
112
- join(answers.name, "index.func.ts"),
113
- `import { useFunc } from '@faasjs/func'
114
- import { useHttp } from '@faasjs/http'
230
+ writeFile(
231
+ join(rootPath, "src", "pages", "home", "api", "hello.func.ts"),
232
+ `import { defineFunc } from '@faasjs/func'
233
+ import { z } from 'zod'
115
234
 
116
- export const func = useFunc(() => {
117
- const http = useHttp<{ name: string }>()
235
+ const schema = z
236
+ .object({
237
+ name: z.string().optional(),
238
+ })
239
+ .required()
118
240
 
119
- return async () => \`Hello, \${http.params.name}\`
120
- })
241
+ export const func = defineFunc<{ params?: z.infer<typeof schema> }>(
242
+ async ({ event }) => {
243
+ const parsed = schema.parse(event.params || {})
244
+
245
+ return {
246
+ ok: true,
247
+ data: \`Hello, \${parsed.name || 'FaasJS'}\`,
248
+ error: null,
249
+ }
250
+ }
251
+ )
121
252
  `
122
253
  );
123
- mkdirSync(join(answers.name, "__tests__"));
124
- writeFileSync(
125
- join(answers.name, "__tests__", "index.test.ts"),
126
- `import { test } from '@faasjs/test'
127
- import { func } from '../index.func'
254
+ writeFile(
255
+ join(rootPath, "src", "pages", "home", "api", "__tests__", "hello.test.ts"),
256
+ `import { test } from '@faasjs/dev'
257
+ import { func } from '../hello.func'
128
258
 
129
- describe('hello', () => {
259
+ describe('home/api/hello', () => {
130
260
  it('should work', async () => {
131
261
  const testFunc = test(func)
132
262
 
133
- const { statusCode, data } = await testFunc.JSONhandler<string>({ name: 'world' })
263
+ const { statusCode, data } = await testFunc.JSONhandler({ name: 'world' })
134
264
 
135
265
  expect(statusCode).toEqual(200)
136
- expect(data).toEqual('Hello, world')
266
+ expect(data).toEqual({
267
+ ok: true,
268
+ data: 'Hello, world',
269
+ error: null,
270
+ })
137
271
  })
138
272
  })
139
273
  `
140
274
  );
275
+ }
276
+ async function action(options = {}) {
277
+ const answers = Object.assign(options, {});
278
+ if (!options.name || Validator.name(options.name) !== true)
279
+ answers.name = await prompt({
280
+ type: "input",
281
+ name: "value",
282
+ message: "Project name",
283
+ initial: "faasjs",
284
+ validate: Validator.name
285
+ }).then((res) => res.value);
286
+ if (!answers.name) return;
287
+ const runtime = process.versions.bun ? "bun" : "npm";
288
+ mkdirSync(answers.name);
289
+ writeFileSync(
290
+ join(answers.name, "package.json"),
291
+ buildPackageJSON(answers.name)
292
+ );
293
+ scaffold(answers.name);
294
+ execSync(`cd ${answers.name} && ${runtime} install`, { stdio: "inherit" });
141
295
  if (runtime === "bun") {
142
296
  execSync(`cd ${answers.name} && bun test`, { stdio: "inherit" });
143
297
  } else execSync(`cd ${answers.name} && npm run test`, { stdio: "inherit" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-faas-app",
3
- "version": "v8.0.0-beta.3",
3
+ "version": "v8.0.0-beta.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",