@faasjs/dev 8.0.0-beta.5 → 8.0.0-beta.6

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 CHANGED
@@ -60,19 +60,19 @@ expect(response.data).toEqual({ message: 'Hello, FaasJS' })
60
60
 
61
61
  ## API
62
62
 
63
- - Vite: [viteFaasJsServer](functions/viteFaasJsServer.md), [ViteFaasJsServerOptions](type-aliases/ViteFaasJsServerOptions.md)
64
- - PGlite: [createPgliteKnex](functions/createPgliteKnex.md), [mountFaasKnex](functions/mountFaasKnex.md), [runPgliteSql](functions/runPgliteSql.md), [runPgliteSqlFile](functions/runPgliteSqlFile.md), [unmountFaasKnex](functions/unmountFaasKnex.md), [MountFaasKnexOptions](type-aliases/MountFaasKnexOptions.md)
63
+ - Vite: [viteFaasJsServer](functions/viteFaasJsServer.md)
64
+ - PGlite: [createPgliteKnex](functions/createPgliteKnex.md), [mountFaasKnex](functions/mountFaasKnex.md), [unmountFaasKnex](functions/unmountFaasKnex.md), [MountFaasKnexOptions](type-aliases/MountFaasKnexOptions.md)
65
65
  - Test: [test](functions/test.md), [FuncWarper](classes/FuncWarper.md), [streamToString](functions/streamToString.md)
66
66
 
67
67
  ## Functions
68
68
 
69
69
  - [createPgliteKnex](functions/createPgliteKnex.md)
70
70
  - [defineFunc](functions/defineFunc.md)
71
+ - [generateFaasTypes](functions/generateFaasTypes.md)
72
+ - [isTypegenSourceFile](functions/isTypegenSourceFile.md)
71
73
  - [mountFaasKnex](functions/mountFaasKnex.md)
72
74
  - [nameFunc](functions/nameFunc.md)
73
75
  - [parseFuncFilenameFromStack](functions/parseFuncFilenameFromStack.md)
74
- - [runPgliteSql](functions/runPgliteSql.md)
75
- - [runPgliteSqlFile](functions/runPgliteSqlFile.md)
76
76
  - [streamToString](functions/streamToString.md)
77
77
  - [test](functions/test.md)
78
78
  - [unmountFaasKnex](functions/unmountFaasKnex.md)
@@ -85,6 +85,10 @@ expect(response.data).toEqual({ message: 'Hello, FaasJS' })
85
85
  - [Func](classes/Func.md)
86
86
  - [FuncWarper](classes/FuncWarper.md)
87
87
 
88
+ ## Interfaces
89
+
90
+ - [FaasPluginEventMap](interfaces/FaasPluginEventMap.md)
91
+
88
92
  ## Type Aliases
89
93
 
90
94
  - [Config](type-aliases/Config.md)
@@ -92,12 +96,18 @@ expect(response.data).toEqual({ message: 'Hello, FaasJS' })
92
96
  - [FuncConfig](type-aliases/FuncConfig.md)
93
97
  - [FuncEventType](type-aliases/FuncEventType.md)
94
98
  - [FuncReturnType](type-aliases/FuncReturnType.md)
99
+ - [GenerateFaasTypesOptions](type-aliases/GenerateFaasTypesOptions.md)
100
+ - [GenerateFaasTypesResult](type-aliases/GenerateFaasTypesResult.md)
95
101
  - [Handler](type-aliases/Handler.md)
102
+ - [InferPluginEvent](type-aliases/InferPluginEvent.md)
96
103
  - [InvokeData](type-aliases/InvokeData.md)
97
104
  - [LifeCycleKey](type-aliases/LifeCycleKey.md)
98
105
  - [MountData](type-aliases/MountData.md)
99
106
  - [MountFaasKnexOptions](type-aliases/MountFaasKnexOptions.md)
100
107
  - [Next](type-aliases/Next.md)
108
+ - [NormalizePluginType](type-aliases/NormalizePluginType.md)
101
109
  - [Plugin](type-aliases/Plugin.md)
110
+ - [ResolvePluginEvent](type-aliases/ResolvePluginEvent.md)
111
+ - [Simplify](type-aliases/Simplify.md)
112
+ - [UnionToIntersection](type-aliases/UnionToIntersection.md)
102
113
  - [UseifyPlugin](type-aliases/UseifyPlugin.md)
103
- - [ViteFaasJsServerOptions](type-aliases/ViteFaasJsServerOptions.md)
@@ -0,0 +1,221 @@
1
+ import { existsSync } from 'fs';
2
+ import { readFile, mkdir, writeFile, readdir } from 'fs/promises';
3
+ import { resolve, join, dirname, relative } from 'path';
4
+ import { loadConfig } from '@faasjs/load';
5
+ import { Logger } from '@faasjs/logger';
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
24
+ function resolveFaasStaging() {
25
+ return process.env.FaasEnv || "development";
26
+ }
27
+ function resolveServerConfig(root, logger, defaultBase = "/") {
28
+ const projectRoot = resolve(root);
29
+ const staging = resolveFaasStaging();
30
+ const srcRoot = join(projectRoot, "src");
31
+ const config = loadConfig(
32
+ srcRoot,
33
+ join(srcRoot, "index.func.ts"),
34
+ staging,
35
+ logger
36
+ );
37
+ const server = config && typeof config === "object" ? config.server : void 0;
38
+ const resolvedRoot = server && typeof server.root === "string" && server.root.length ? resolve(projectRoot, server.root) : projectRoot;
39
+ const resolvedBase = server && typeof server.base === "string" && server.base.length ? server.base : defaultBase;
40
+ return {
41
+ root: resolvedRoot,
42
+ base: resolvedBase,
43
+ staging
44
+ };
45
+ }
46
+
47
+ // src/typegen.ts
48
+ function normalizeSlashes(path) {
49
+ return path.replace(/\\/g, "/");
50
+ }
51
+ function normalizeRoute(path) {
52
+ const normalized = path.replace(/\/+/g, "/");
53
+ if (!normalized.length || normalized === "/") return "/";
54
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
55
+ }
56
+ function toRoute(srcRoot, file) {
57
+ const relativePath = normalizeSlashes(relative(srcRoot, file));
58
+ const noTsPath = relativePath.replace(/\.ts$/, "");
59
+ if (noTsPath === "index.func") return { route: "/", priority: 2 };
60
+ if (noTsPath === "default.func") return { route: "/*", priority: 1 };
61
+ if (noTsPath.endsWith("/index.func"))
62
+ return {
63
+ route: normalizeRoute(`/${noTsPath.slice(0, -"/index.func".length)}`),
64
+ priority: 2
65
+ };
66
+ if (noTsPath.endsWith("/default.func"))
67
+ return {
68
+ route: normalizeRoute(`/${noTsPath.slice(0, -"/default.func".length)}/*`),
69
+ priority: 1
70
+ };
71
+ if (noTsPath.endsWith(".func"))
72
+ return {
73
+ route: normalizeRoute(`/${noTsPath.slice(0, -".func".length)}`),
74
+ priority: 3
75
+ };
76
+ throw Error(`[faas-types] Invalid func filename: ${file}`);
77
+ }
78
+ function toImportPath(fromFile, targetFile) {
79
+ const fromDir = dirname(fromFile);
80
+ const importPath = normalizeSlashes(relative(fromDir, targetFile)).replace(
81
+ /\.ts$/,
82
+ ""
83
+ );
84
+ if (importPath.startsWith(".")) return importPath;
85
+ return `./${importPath}`;
86
+ }
87
+ function parsePluginTypes(config) {
88
+ const pluginConfig = config.plugins;
89
+ if (!pluginConfig || typeof pluginConfig !== "object") return [];
90
+ const pluginTypes = /* @__PURE__ */ new Set();
91
+ for (const key in pluginConfig) {
92
+ const data = pluginConfig[key];
93
+ if (typeof data === "string" && data.length) {
94
+ pluginTypes.add(data);
95
+ continue;
96
+ }
97
+ if (data && typeof data === "object") {
98
+ if (typeof data.type === "string" && data.type.length)
99
+ pluginTypes.add(data.type);
100
+ else pluginTypes.add(key);
101
+ continue;
102
+ }
103
+ pluginTypes.add(key);
104
+ }
105
+ return Array.from(pluginTypes).sort((a, b) => a.localeCompare(b));
106
+ }
107
+ async function readFuncFiles(dir) {
108
+ const result = [];
109
+ async function walk(currentDir) {
110
+ const entries = await readdir(currentDir, {
111
+ withFileTypes: true
112
+ });
113
+ for (const entry of entries) {
114
+ if (entry.name === ".faasjs" || entry.name === "node_modules") continue;
115
+ const filePath = join(currentDir, entry.name);
116
+ if (entry.isDirectory()) {
117
+ await walk(filePath);
118
+ continue;
119
+ }
120
+ if (entry.isFile() && entry.name.endsWith(".func.ts"))
121
+ result.push(filePath);
122
+ }
123
+ }
124
+ await walk(dir);
125
+ return result.sort((a, b) => a.localeCompare(b));
126
+ }
127
+ function formatTypes(items) {
128
+ const actionLines = items.map((item) => {
129
+ return ` ${JSON.stringify(item.route)}: __FaasFuncAction<__FaasModuleFunc<typeof import(${JSON.stringify(item.importPath)})>>`;
130
+ });
131
+ const eventLines = items.map((item) => {
132
+ const plugins = item.pluginTypes.length ? `[${item.pluginTypes.map((type) => JSON.stringify(type)).join(", ")}]` : "[]";
133
+ return ` ${JSON.stringify(item.route)}: InferPluginEvent<${plugins}>`;
134
+ });
135
+ return `/**
136
+ * Generated by @faasjs/dev.
137
+ *
138
+ * Do not edit this file manually.
139
+ */
140
+ import type { Func, InferPluginEvent } from '@faasjs/func'
141
+
142
+ type __FaasModuleFunc<TModule> = TModule extends { func: infer TFunc }
143
+ ? TFunc extends Func
144
+ ? TFunc
145
+ : never
146
+ : TModule extends { default: infer TFunc }
147
+ ? TFunc extends Func
148
+ ? TFunc
149
+ : never
150
+ : never
151
+
152
+ type __FaasFuncAction<TFunc extends Func> = {
153
+ Params: Parameters<ReturnType<TFunc['export']>['handler']>[0]['params']
154
+ Data: Awaited<ReturnType<ReturnType<TFunc['export']>['handler']>>
155
+ }
156
+
157
+ declare module '@faasjs/types' {
158
+ interface FaasActions {
159
+ ${actionLines.length ? `${actionLines.join("\n")}
160
+ ` : ""} }
161
+
162
+ interface FaasEvents {
163
+ ${eventLines.length ? `${eventLines.join("\n")}
164
+ ` : ""} }
165
+ }
166
+ `;
167
+ }
168
+ function isTypegenSourceFile(filePath) {
169
+ return /\.func\.ts$/.test(filePath) || /(^|[\\/])faas\.ya?ml$/.test(filePath);
170
+ }
171
+ async function generateFaasTypes(options = {}) {
172
+ const logger = options.logger || new Logger("FaasJs:Typegen");
173
+ const { root: projectRoot, staging } = resolveServerConfig(
174
+ options.root || process.cwd(),
175
+ logger
176
+ );
177
+ const srcRoot = join(projectRoot, "src");
178
+ const output = join(srcRoot, ".faasjs", "types.d.ts");
179
+ if (!existsSync(srcRoot))
180
+ throw Error(`[faas-types] Source directory not found: ${srcRoot}`);
181
+ const files = await readFuncFiles(srcRoot);
182
+ const routeMap = /* @__PURE__ */ new Map();
183
+ for (const file of files) {
184
+ const { route, priority } = toRoute(srcRoot, file);
185
+ const config = loadConfig(srcRoot, file, staging, logger);
186
+ const pluginTypes = parsePluginTypes(config);
187
+ const importPath = toImportPath(output, file);
188
+ const prev = routeMap.get(route);
189
+ if (!prev || priority > prev.priority)
190
+ routeMap.set(route, {
191
+ route,
192
+ importPath,
193
+ pluginTypes,
194
+ priority
195
+ });
196
+ }
197
+ const items = Array.from(routeMap.values()).sort(
198
+ (a, b) => a.route.localeCompare(b.route)
199
+ );
200
+ const content = formatTypes(items);
201
+ let changed = true;
202
+ try {
203
+ const previous = await readFile(output, "utf8");
204
+ if (previous === content) changed = false;
205
+ } catch (_error) {
206
+ }
207
+ if (changed) {
208
+ await mkdir(dirname(output), {
209
+ recursive: true
210
+ });
211
+ await writeFile(output, content);
212
+ }
213
+ return {
214
+ output,
215
+ changed,
216
+ fileCount: files.length,
217
+ routeCount: items.length
218
+ };
219
+ }
220
+
221
+ export { __export, __reExport, generateFaasTypes, isTypegenSourceFile, resolveServerConfig };
package/dist/cli.cjs ADDED
@@ -0,0 +1,335 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var promises = require('fs/promises');
5
+ var path = require('path');
6
+ var load = require('@faasjs/load');
7
+ var logger = require('@faasjs/logger');
8
+
9
+ // package.json
10
+ var package_default = {
11
+ name: "@faasjs/dev",
12
+ version: "v8.0.0-beta.5",
13
+ license: "MIT",
14
+ type: "module",
15
+ main: "dist/index.cjs",
16
+ module: "dist/index.mjs",
17
+ types: "dist/index.d.ts",
18
+ bin: {
19
+ "faas-types": "faas-types.mjs"
20
+ },
21
+ exports: {
22
+ ".": {
23
+ types: "./dist/index.d.ts",
24
+ import: "./dist/index.mjs",
25
+ require: "./dist/index.cjs"
26
+ }
27
+ },
28
+ homepage: "https://faasjs.com/doc/dev",
29
+ repository: {
30
+ type: "git",
31
+ url: "git+https://github.com/faasjs/faasjs.git",
32
+ directory: "packages/dev"
33
+ },
34
+ bugs: {
35
+ url: "https://github.com/faasjs/faasjs/issues"
36
+ },
37
+ funding: "https://github.com/sponsors/faasjs",
38
+ scripts: {
39
+ build: "tsup-node --entry src/index.ts --entry src/cli.ts --config ../../tsup.config.ts"
40
+ },
41
+ files: [
42
+ "dist",
43
+ "faas-types.mjs"
44
+ ],
45
+ peerDependencies: {
46
+ "@electric-sql/pglite": "*",
47
+ "@faasjs/deep_merge": ">=v8.0.0-beta.5",
48
+ "@faasjs/func": ">=v8.0.0-beta.5",
49
+ "@faasjs/http": ">=v8.0.0-beta.5",
50
+ "@faasjs/server": ">=v8.0.0-beta.5",
51
+ "@faasjs/knex": ">=v8.0.0-beta.5",
52
+ "@faasjs/load": ">=v8.0.0-beta.5",
53
+ "@faasjs/logger": ">=v8.0.0-beta.5",
54
+ "@types/node": "*",
55
+ knex: "*",
56
+ vite: "*",
57
+ vitest: "*",
58
+ "knex-pglite": "*"
59
+ },
60
+ devDependencies: {
61
+ "@electric-sql/pglite": "*",
62
+ "@faasjs/deep_merge": ">=v8.0.0-beta.5",
63
+ "@faasjs/func": ">=v8.0.0-beta.5",
64
+ "@faasjs/http": ">=v8.0.0-beta.5",
65
+ "@faasjs/server": ">=v8.0.0-beta.5",
66
+ "@faasjs/knex": ">=v8.0.0-beta.5",
67
+ "@faasjs/load": ">=v8.0.0-beta.5",
68
+ "@faasjs/logger": ">=v8.0.0-beta.5",
69
+ "@types/node": "*",
70
+ knex: "*",
71
+ vite: "*",
72
+ vitest: "*",
73
+ "knex-pglite": "*"
74
+ },
75
+ engines: {
76
+ node: ">=24.0.0",
77
+ npm: ">=11.0.0"
78
+ }
79
+ };
80
+ function resolveFaasStaging() {
81
+ return process.env.FaasEnv || "development";
82
+ }
83
+ function resolveServerConfig(root, logger, defaultBase = "/") {
84
+ const projectRoot = path.resolve(root);
85
+ const staging = resolveFaasStaging();
86
+ const srcRoot = path.join(projectRoot, "src");
87
+ const config = load.loadConfig(
88
+ srcRoot,
89
+ path.join(srcRoot, "index.func.ts"),
90
+ staging,
91
+ logger
92
+ );
93
+ const server = config && typeof config === "object" ? config.server : void 0;
94
+ const resolvedRoot = server && typeof server.root === "string" && server.root.length ? path.resolve(projectRoot, server.root) : projectRoot;
95
+ const resolvedBase = server && typeof server.base === "string" && server.base.length ? server.base : defaultBase;
96
+ return {
97
+ root: resolvedRoot,
98
+ base: resolvedBase,
99
+ staging
100
+ };
101
+ }
102
+
103
+ // src/typegen.ts
104
+ function normalizeSlashes(path) {
105
+ return path.replace(/\\/g, "/");
106
+ }
107
+ function normalizeRoute(path) {
108
+ const normalized = path.replace(/\/+/g, "/");
109
+ if (!normalized.length || normalized === "/") return "/";
110
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
111
+ }
112
+ function toRoute(srcRoot, file) {
113
+ const relativePath = normalizeSlashes(path.relative(srcRoot, file));
114
+ const noTsPath = relativePath.replace(/\.ts$/, "");
115
+ if (noTsPath === "index.func") return { route: "/", priority: 2 };
116
+ if (noTsPath === "default.func") return { route: "/*", priority: 1 };
117
+ if (noTsPath.endsWith("/index.func"))
118
+ return {
119
+ route: normalizeRoute(`/${noTsPath.slice(0, -"/index.func".length)}`),
120
+ priority: 2
121
+ };
122
+ if (noTsPath.endsWith("/default.func"))
123
+ return {
124
+ route: normalizeRoute(`/${noTsPath.slice(0, -"/default.func".length)}/*`),
125
+ priority: 1
126
+ };
127
+ if (noTsPath.endsWith(".func"))
128
+ return {
129
+ route: normalizeRoute(`/${noTsPath.slice(0, -".func".length)}`),
130
+ priority: 3
131
+ };
132
+ throw Error(`[faas-types] Invalid func filename: ${file}`);
133
+ }
134
+ function toImportPath(fromFile, targetFile) {
135
+ const fromDir = path.dirname(fromFile);
136
+ const importPath = normalizeSlashes(path.relative(fromDir, targetFile)).replace(
137
+ /\.ts$/,
138
+ ""
139
+ );
140
+ if (importPath.startsWith(".")) return importPath;
141
+ return `./${importPath}`;
142
+ }
143
+ function parsePluginTypes(config) {
144
+ const pluginConfig = config.plugins;
145
+ if (!pluginConfig || typeof pluginConfig !== "object") return [];
146
+ const pluginTypes = /* @__PURE__ */ new Set();
147
+ for (const key in pluginConfig) {
148
+ const data = pluginConfig[key];
149
+ if (typeof data === "string" && data.length) {
150
+ pluginTypes.add(data);
151
+ continue;
152
+ }
153
+ if (data && typeof data === "object") {
154
+ if (typeof data.type === "string" && data.type.length)
155
+ pluginTypes.add(data.type);
156
+ else pluginTypes.add(key);
157
+ continue;
158
+ }
159
+ pluginTypes.add(key);
160
+ }
161
+ return Array.from(pluginTypes).sort((a, b) => a.localeCompare(b));
162
+ }
163
+ async function readFuncFiles(dir) {
164
+ const result = [];
165
+ async function walk(currentDir) {
166
+ const entries = await promises.readdir(currentDir, {
167
+ withFileTypes: true
168
+ });
169
+ for (const entry of entries) {
170
+ if (entry.name === ".faasjs" || entry.name === "node_modules") continue;
171
+ const filePath = path.join(currentDir, entry.name);
172
+ if (entry.isDirectory()) {
173
+ await walk(filePath);
174
+ continue;
175
+ }
176
+ if (entry.isFile() && entry.name.endsWith(".func.ts"))
177
+ result.push(filePath);
178
+ }
179
+ }
180
+ await walk(dir);
181
+ return result.sort((a, b) => a.localeCompare(b));
182
+ }
183
+ function formatTypes(items) {
184
+ const actionLines = items.map((item) => {
185
+ return ` ${JSON.stringify(item.route)}: __FaasFuncAction<__FaasModuleFunc<typeof import(${JSON.stringify(item.importPath)})>>`;
186
+ });
187
+ const eventLines = items.map((item) => {
188
+ const plugins = item.pluginTypes.length ? `[${item.pluginTypes.map((type) => JSON.stringify(type)).join(", ")}]` : "[]";
189
+ return ` ${JSON.stringify(item.route)}: InferPluginEvent<${plugins}>`;
190
+ });
191
+ return `/**
192
+ * Generated by @faasjs/dev.
193
+ *
194
+ * Do not edit this file manually.
195
+ */
196
+ import type { Func, InferPluginEvent } from '@faasjs/func'
197
+
198
+ type __FaasModuleFunc<TModule> = TModule extends { func: infer TFunc }
199
+ ? TFunc extends Func
200
+ ? TFunc
201
+ : never
202
+ : TModule extends { default: infer TFunc }
203
+ ? TFunc extends Func
204
+ ? TFunc
205
+ : never
206
+ : never
207
+
208
+ type __FaasFuncAction<TFunc extends Func> = {
209
+ Params: Parameters<ReturnType<TFunc['export']>['handler']>[0]['params']
210
+ Data: Awaited<ReturnType<ReturnType<TFunc['export']>['handler']>>
211
+ }
212
+
213
+ declare module '@faasjs/types' {
214
+ interface FaasActions {
215
+ ${actionLines.length ? `${actionLines.join("\n")}
216
+ ` : ""} }
217
+
218
+ interface FaasEvents {
219
+ ${eventLines.length ? `${eventLines.join("\n")}
220
+ ` : ""} }
221
+ }
222
+ `;
223
+ }
224
+ async function generateFaasTypes(options = {}) {
225
+ const logger$1 = options.logger || new logger.Logger("FaasJs:Typegen");
226
+ const { root: projectRoot, staging } = resolveServerConfig(
227
+ options.root || process.cwd(),
228
+ logger$1
229
+ );
230
+ const srcRoot = path.join(projectRoot, "src");
231
+ const output = path.join(srcRoot, ".faasjs", "types.d.ts");
232
+ if (!fs.existsSync(srcRoot))
233
+ throw Error(`[faas-types] Source directory not found: ${srcRoot}`);
234
+ const files = await readFuncFiles(srcRoot);
235
+ const routeMap = /* @__PURE__ */ new Map();
236
+ for (const file of files) {
237
+ const { route, priority } = toRoute(srcRoot, file);
238
+ const config = load.loadConfig(srcRoot, file, staging, logger$1);
239
+ const pluginTypes = parsePluginTypes(config);
240
+ const importPath = toImportPath(output, file);
241
+ const prev = routeMap.get(route);
242
+ if (!prev || priority > prev.priority)
243
+ routeMap.set(route, {
244
+ route,
245
+ importPath,
246
+ pluginTypes,
247
+ priority
248
+ });
249
+ }
250
+ const items = Array.from(routeMap.values()).sort(
251
+ (a, b) => a.route.localeCompare(b.route)
252
+ );
253
+ const content = formatTypes(items);
254
+ let changed = true;
255
+ try {
256
+ const previous = await promises.readFile(output, "utf8");
257
+ if (previous === content) changed = false;
258
+ } catch (_error) {
259
+ }
260
+ if (changed) {
261
+ await promises.mkdir(path.dirname(output), {
262
+ recursive: true
263
+ });
264
+ await promises.writeFile(output, content);
265
+ }
266
+ return {
267
+ output,
268
+ changed,
269
+ fileCount: files.length,
270
+ routeCount: items.length
271
+ };
272
+ }
273
+
274
+ // src/cli.ts
275
+ var HelpText = `Generate FaasJS API/event type declarations.
276
+
277
+ Usage:
278
+ faas-types [options]
279
+
280
+ Options:
281
+ --root <path> Project root path (default: process.cwd())
282
+ -h, --help Show help
283
+ -v, --version Show version
284
+ `;
285
+ function parseCliArgs(argv) {
286
+ const args = argv.slice(2);
287
+ const options = {};
288
+ const readValue = (index, name) => {
289
+ const value = args[index + 1];
290
+ if (!value || value.startsWith("-"))
291
+ throw Error(`[faas-types] Missing value for ${name}`);
292
+ return value;
293
+ };
294
+ for (let i = 0; i < args.length; i++) {
295
+ const arg = args[i];
296
+ if (arg === "-h" || arg === "--help") return { showHelp: true, options };
297
+ if (arg === "-v" || arg === "--version")
298
+ return {
299
+ showVersion: true,
300
+ options
301
+ };
302
+ if (arg === "--root") {
303
+ options.root = readValue(i, arg);
304
+ i++;
305
+ continue;
306
+ }
307
+ throw Error(`[faas-types] Unknown option: ${arg}`);
308
+ }
309
+ return {
310
+ options
311
+ };
312
+ }
313
+ async function main(argv = process.argv) {
314
+ try {
315
+ const parsed = parseCliArgs(argv);
316
+ if (parsed.showHelp) {
317
+ console.log(HelpText);
318
+ return 0;
319
+ }
320
+ if (parsed.showVersion) {
321
+ console.log(package_default.version);
322
+ return 0;
323
+ }
324
+ const result = await generateFaasTypes(parsed.options);
325
+ console.log(
326
+ `[faas-types] ${result.changed ? "Generated" : "Up to date"} ${result.output} (${result.routeCount} routes from ${result.fileCount} files)`
327
+ );
328
+ return 0;
329
+ } catch (error) {
330
+ console.error(error?.message || error);
331
+ return 1;
332
+ }
333
+ }
334
+
335
+ exports.main = main;
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ declare function main(argv?: string[]): Promise<number>;
2
+
3
+ export { main };