@faasjs/dev 8.0.0-beta.7 → 8.0.0-beta.9

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.
@@ -0,0 +1,295 @@
1
+ import { r as resolveServerConfig, t as generateFaasTypes } from "../typegen-BNWmP5Qp.mjs";
2
+ import { createRequire } from "node:module";
3
+ import { KnexSchema, useKnex } from "@faasjs/core";
4
+ import { loadConfig } from "@faasjs/node-utils";
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { dirname, join, resolve } from "node:path";
7
+ import { execFileSync } from "node:child_process";
8
+
9
+ //#region package.json
10
+ var version = "8.0.0-beta.8";
11
+
12
+ //#endregion
13
+ //#region src/cli/shared.ts
14
+ function parseCommonCliArgs(args, scope) {
15
+ const options = {};
16
+ const rest = [];
17
+ for (let i = 0; i < args.length; i++) {
18
+ const arg = args[i];
19
+ if (arg === "-h" || arg === "--help") return {
20
+ mode: "help",
21
+ options,
22
+ rest
23
+ };
24
+ if (arg === "-v" || arg === "--version") return {
25
+ mode: "version",
26
+ options,
27
+ rest
28
+ };
29
+ if (arg === "--root") {
30
+ const value = args[i + 1];
31
+ if (!value || value.startsWith("-")) throw Error(`[${scope}] Missing value for ${arg}`);
32
+ options.root = value;
33
+ i += 1;
34
+ continue;
35
+ }
36
+ if (arg.startsWith("-")) throw Error(`[${scope}] Unknown option: ${arg}`);
37
+ rest.push(arg);
38
+ }
39
+ return {
40
+ mode: "run",
41
+ options,
42
+ rest
43
+ };
44
+ }
45
+ function printVersion() {
46
+ console.log(version);
47
+ return 0;
48
+ }
49
+ async function runCli(handler) {
50
+ try {
51
+ return await handler();
52
+ } catch (error) {
53
+ console.error(error?.message || error);
54
+ return 1;
55
+ }
56
+ }
57
+ function createMain(run) {
58
+ return async (argv = process.argv) => runCli(() => run(argv.slice(2)));
59
+ }
60
+
61
+ //#endregion
62
+ //#region src/cli/knex.ts
63
+ const MigrateActions = [
64
+ "latest",
65
+ "rollback",
66
+ "status",
67
+ "current",
68
+ "make"
69
+ ];
70
+ function isMigrateAction(value) {
71
+ return MigrateActions.includes(value);
72
+ }
73
+ const ActionHandlers = {
74
+ latest: (schema) => schema.migrateLatest(),
75
+ rollback: (schema) => schema.migrateRollback(),
76
+ status: async (schema) => {
77
+ console.log(await schema.migrateStatus());
78
+ },
79
+ current: async (schema) => {
80
+ console.log(await schema.migrateCurrentVersion());
81
+ }
82
+ };
83
+ const HelpText$3 = `Run FaasJS knex migrations.
84
+
85
+ Usage:
86
+ faas knex <action> [name] [options]
87
+
88
+ Actions:
89
+ latest Run all pending migrations
90
+ rollback Roll back the last migration batch
91
+ status Print pending migration count
92
+ current Print current migration version
93
+ make <name> Create a new migration file
94
+
95
+ Options:
96
+ --root <path> Project root path (default: process.cwd())
97
+ -h, --help Show help
98
+ -v, --version Show version
99
+ `;
100
+ function parseCliArgs(args) {
101
+ const { mode, options, rest } = parseCommonCliArgs(args, "faas knex");
102
+ if (mode !== "run") return {
103
+ mode,
104
+ options
105
+ };
106
+ const [action, name, extra] = rest;
107
+ if (!action) throw Error("[faas knex] Missing action. Usage: faas knex <latest|rollback|status|current|make>");
108
+ if (!isMigrateAction(action)) throw Error(`[faas knex] Unknown action: ${action}`);
109
+ if (action !== "make") {
110
+ if (name) throw Error(`[faas knex] Unexpected argument: ${name}`);
111
+ return {
112
+ mode: "run",
113
+ action,
114
+ options
115
+ };
116
+ }
117
+ if (!name) throw Error("[faas knex] Missing migration name. Usage: faas knex make create_users");
118
+ if (extra) throw Error(`[faas knex] Unexpected argument: ${extra}`);
119
+ return {
120
+ mode: "run",
121
+ action: "make",
122
+ name,
123
+ options
124
+ };
125
+ }
126
+ async function run$3(args) {
127
+ const parsed = parseCliArgs(args);
128
+ if (parsed.mode === "help") {
129
+ console.log(HelpText$3);
130
+ return 0;
131
+ }
132
+ if (parsed.mode === "version") return printVersion();
133
+ const { root: projectRoot, staging } = resolveServerConfig(parsed.options.root ?? process.cwd());
134
+ const srcRoot = join(projectRoot, "src");
135
+ const knex = useKnex({ config: loadConfig(srcRoot, join(srcRoot, "index.func.ts"), staging).plugins?.knex?.config });
136
+ await knex.mount();
137
+ const schema = new KnexSchema(knex);
138
+ try {
139
+ if (parsed.action === "make") console.log(await schema.migrateMake(parsed.name));
140
+ else await ActionHandlers[parsed.action](schema);
141
+ } finally {
142
+ await knex.quit();
143
+ }
144
+ return 0;
145
+ }
146
+ const main$3 = createMain(run$3);
147
+
148
+ //#endregion
149
+ //#region src/cli/lint.ts
150
+ const HelpText$2 = `Run formatter and lint checks with Oxc shared configs.
151
+
152
+ Usage:
153
+ faas lint [options]
154
+
155
+ Options:
156
+ --root <path> Project root path (default: process.cwd())
157
+ -h, --help Show help
158
+ -v, --version Show version
159
+ `;
160
+ function resolvePackageJsonPath(projectRoot, packageName) {
161
+ const requireFromProject = createRequire(resolve(projectRoot, "package.json"));
162
+ let packageEntryPath = "";
163
+ try {
164
+ packageEntryPath = requireFromProject.resolve(packageName);
165
+ } catch {
166
+ throw Error(`[faas lint] Missing dependency: ${packageName}. Please install ${packageName} in your project.`);
167
+ }
168
+ let currentPath = dirname(packageEntryPath);
169
+ let packageJsonPath = "";
170
+ while (true) {
171
+ const candidate = join(currentPath, "package.json");
172
+ if (existsSync(candidate)) {
173
+ packageJsonPath = candidate;
174
+ break;
175
+ }
176
+ const parentPath = dirname(currentPath);
177
+ if (parentPath === currentPath) break;
178
+ currentPath = parentPath;
179
+ }
180
+ if (!packageJsonPath) throw Error(`[faas lint] Invalid dependency: Cannot find package.json for ${packageName}.`);
181
+ return packageJsonPath;
182
+ }
183
+ function resolveBinPath(projectRoot, packageName, binName) {
184
+ const packageJsonPath = resolvePackageJsonPath(projectRoot, packageName);
185
+ const packageJSON = JSON.parse(readFileSync(packageJsonPath, "utf8"));
186
+ const bin = typeof packageJSON.bin === "string" ? packageJSON.bin : packageJSON.bin?.[binName];
187
+ if (!bin) throw Error(`[faas lint] Invalid dependency: ${packageName} does not expose "${binName}" bin.`);
188
+ return resolve(dirname(packageJsonPath), bin);
189
+ }
190
+ function resolveSharedConfigPath(projectRoot, configFileName) {
191
+ const configPath = resolve(dirname(resolvePackageJsonPath(projectRoot, "@faasjs/dev")), "configs", configFileName);
192
+ if (!existsSync(configPath)) throw Error(`[faas lint] Missing shared config: ${configPath}`);
193
+ return configPath;
194
+ }
195
+ function runNodeBin(projectRoot, command, binPath, args) {
196
+ try {
197
+ execFileSync(process.execPath, [binPath, ...args], {
198
+ cwd: projectRoot,
199
+ stdio: "inherit"
200
+ });
201
+ } catch {
202
+ throw Error(`[faas lint] ${command} failed`);
203
+ }
204
+ }
205
+ async function run$2(args) {
206
+ const { mode, options, rest } = parseCommonCliArgs(args, "faas lint");
207
+ if (mode === "help") {
208
+ console.log(HelpText$2);
209
+ return 0;
210
+ }
211
+ if (mode === "version") return printVersion();
212
+ if (rest.length) throw Error(`[faas lint] Unexpected argument: ${rest[0]}`);
213
+ const projectRoot = options.root ?? process.cwd();
214
+ const oxfmtBinPath = resolveBinPath(projectRoot, "oxfmt", "oxfmt");
215
+ const oxlintBinPath = resolveBinPath(projectRoot, "oxlint", "oxlint");
216
+ const oxfmtConfigPath = resolveSharedConfigPath(projectRoot, "oxfmt.base.json");
217
+ const oxlintConfigPath = resolveSharedConfigPath(projectRoot, "oxlint.base.json");
218
+ runNodeBin(projectRoot, "oxfmt", oxfmtBinPath, [
219
+ "-c",
220
+ oxfmtConfigPath,
221
+ "."
222
+ ]);
223
+ runNodeBin(projectRoot, "oxlint", oxlintBinPath, [
224
+ "-c",
225
+ oxlintConfigPath,
226
+ "--fix",
227
+ "."
228
+ ]);
229
+ console.log("[faas lint] Done");
230
+ return 0;
231
+ }
232
+ const main$2 = createMain(run$2);
233
+
234
+ //#endregion
235
+ //#region src/cli/types.ts
236
+ const HelpText$1 = `Generate FaasJS API/event type declarations.
237
+
238
+ Usage:
239
+ faas types [options]
240
+
241
+ Options:
242
+ --root <path> Project root path (default: process.cwd())
243
+ -h, --help Show help
244
+ -v, --version Show version
245
+ `;
246
+ async function run$1(args) {
247
+ const { mode, options, rest } = parseCommonCliArgs(args, "faas types");
248
+ if (mode === "help") {
249
+ console.log(HelpText$1);
250
+ return 0;
251
+ }
252
+ if (mode === "version") return printVersion();
253
+ if (rest.length) throw Error(`[faas types] Unknown option: ${rest[0]}`);
254
+ const result = await generateFaasTypes(options);
255
+ console.log(`[faas types] ${result.changed ? "Generated" : "Up to date"} ${result.output} (${result.routeCount} routes from ${result.fileCount} files)`);
256
+ return 0;
257
+ }
258
+ const main$1 = createMain(run$1);
259
+
260
+ //#endregion
261
+ //#region src/cli/index.ts
262
+ const HelpText = `FaasJS CLI.
263
+
264
+ Usage:
265
+ faas <command> [...args]
266
+
267
+ Commands:
268
+ types [options] Generate FaasJS API/event type declarations
269
+ knex <action> [name] [options] Run FaasJS knex migrations
270
+ lint [options] Run formatter and lint with Oxc
271
+
272
+ Options:
273
+ -h, --help Show help
274
+ -v, --version Show version
275
+ `;
276
+ const Commands = {
277
+ types: run$1,
278
+ knex: run$3,
279
+ lint: run$2
280
+ };
281
+ async function run(args) {
282
+ const command = args[0];
283
+ if (!command || command === "-h" || command === "--help") {
284
+ console.log(HelpText);
285
+ return 0;
286
+ }
287
+ if (command === "-v" || command === "--version") return printVersion();
288
+ const handler = Commands[command];
289
+ if (!handler) throw Error(`[faas] Unknown command: ${command}`);
290
+ return await handler(args.slice(1));
291
+ }
292
+ const main = createMain(run);
293
+
294
+ //#endregion
295
+ export { main, run };
package/dist/index.cjs CHANGED
@@ -34,13 +34,11 @@ var __copyProps = (to, from, except, desc) => {
34
34
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
35
35
 
36
36
  //#endregion
37
- const require_typegen = require('./typegen-C6t9LIyi.cjs');
37
+ const require_typegen = require('./typegen-HX5QyuhP.cjs');
38
38
  let node_zlib = require("node:zlib");
39
- let _faasjs_http = require("@faasjs/http");
40
- let _faasjs_logger = require("@faasjs/logger");
39
+ let _faasjs_core = require("@faasjs/core");
41
40
  let _faasjs_node_utils = require("@faasjs/node-utils");
42
41
  let node_path = require("node:path");
43
- let _faasjs_server = require("@faasjs/server");
44
42
 
45
43
  //#region src/test.ts
46
44
  /**
@@ -73,7 +71,7 @@ var FuncWarper = class {
73
71
  */
74
72
  constructor(initBy) {
75
73
  this.staging = process.env.FaasEnv ?? "default";
76
- this.logger = new _faasjs_logger.Logger("TestCase");
74
+ this.logger = new _faasjs_node_utils.Logger("TestCase");
77
75
  this.func = initBy.default ? initBy.default : initBy;
78
76
  if (this.func.filename) this.func.config = (0, _faasjs_node_utils.deepMerge)((0, _faasjs_node_utils.loadConfig)(process.cwd(), this.func.filename, this.staging, this.logger), this.func.config);
79
77
  this.file = this.func.filename || "";
@@ -104,7 +102,7 @@ var FuncWarper = class {
104
102
  async JSONhandler(body, options = Object.create(null)) {
105
103
  await this.mount();
106
104
  const headers = options.headers || Object.create(null);
107
- if (this.http && this.http instanceof _faasjs_http.Http) {
105
+ if (this.http && this.http instanceof _faasjs_core.Http) {
108
106
  if (options.cookie) for (const key in options.cookie) this.http.cookie.write(key, options.cookie[key]);
109
107
  if (options.session) {
110
108
  for (const key in options.session) this.http.session.write(key, options.session[key]);
@@ -223,20 +221,20 @@ function stripBase(url, base) {
223
221
  * Create a Vite plugin that proxies POST requests to an in-process FaasJS server.
224
222
  *
225
223
  * It resolves server root/base from `src/faas.yaml` and strips `base` from
226
- * request URL before forwarding to `@faasjs/server`.
224
+ * request URL before forwarding to `@faasjs/core`.
227
225
  */
228
226
  function viteFaasJsServer() {
229
227
  let config;
230
228
  let server = null;
231
- const logger = new _faasjs_logger.Logger("FaasJs:Vite");
229
+ const logger = new _faasjs_node_utils.Logger("FaasJs:Vite");
232
230
  return {
233
231
  name: "vite:faasjs",
234
232
  enforce: "pre",
235
233
  configResolved(resolvedConfig) {
236
- const serverConfig = require_typegen.resolveServerConfig(resolvedConfig.root, logger, resolvedConfig.base);
234
+ const { root, base } = require_typegen.resolveServerConfig(resolvedConfig.root, logger, resolvedConfig.base);
237
235
  config = {
238
- root: serverConfig.root,
239
- base: normalizeBase(serverConfig.base)
236
+ root,
237
+ base: normalizeBase(base)
240
238
  };
241
239
  },
242
240
  configureServer: async ({ middlewares, watcher }) => {
@@ -245,34 +243,21 @@ function viteFaasJsServer() {
245
243
  return;
246
244
  }
247
245
  if (!config) throw new Error("viteFaasJsServer: config is not resolved");
248
- server = new _faasjs_server.Server((0, node_path.join)(config.root, "src"));
246
+ server = new _faasjs_core.Server((0, node_path.join)(config.root, "src"));
249
247
  const runTypegen = async () => {
250
248
  try {
251
249
  const result = await require_typegen.generateFaasTypes({ root: config.root });
252
- logger.debug("[faas-types] %s %s (%i routes)", result.changed ? "generated" : "up-to-date", result.output, result.routeCount);
250
+ logger.debug("[faas types] %s %s (%i routes)", result.changed ? "generated" : "up-to-date", result.output, result.routeCount);
253
251
  } catch (error) {
254
- logger.error("[faas-types] %s", error.message);
255
- }
256
- };
257
- let timer = null;
258
- let runningTypegen = false;
259
- let pendingTypegen = false;
260
- const flushTypegen = async () => {
261
- if (runningTypegen || !pendingTypegen) return;
262
- pendingTypegen = false;
263
- runningTypegen = true;
264
- try {
265
- await runTypegen();
266
- } finally {
267
- runningTypegen = false;
268
- if (pendingTypegen) flushTypegen();
252
+ logger.error("[faas types] %s", error.message);
269
253
  }
270
254
  };
255
+ let timer;
256
+ let typegenChain = Promise.resolve();
271
257
  const scheduleTypegen = () => {
272
- pendingTypegen = true;
273
258
  if (timer) clearTimeout(timer);
274
259
  timer = setTimeout(() => {
275
- flushTypegen();
260
+ typegenChain = typegenChain.then(runTypegen);
276
261
  }, TYPEGEN_DEBOUNCE);
277
262
  };
278
263
  await runTypegen();
@@ -325,10 +310,9 @@ exports.streamToString = _faasjs_node_utils.streamToString;
325
310
  exports.streamToText = _faasjs_node_utils.streamToText;
326
311
  exports.test = test;
327
312
  exports.viteFaasJsServer = viteFaasJsServer;
328
- var _faasjs_func = require("@faasjs/func");
329
- Object.keys(_faasjs_func).forEach(function (k) {
313
+ Object.keys(_faasjs_core).forEach(function (k) {
330
314
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
331
315
  enumerable: true,
332
- get: function () { return _faasjs_func[k]; }
316
+ get: function () { return _faasjs_core[k]; }
333
317
  });
334
318
  });
package/dist/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { n as __reExport, t as __exportAll } from "./chunk-CtajNgzt.mjs";
2
- import { Logger } from "@faasjs/logger";
3
- import { streamToObject, streamToString, streamToText } from "@faasjs/node-utils";
4
- import { Config, Func, Plugin } from "@faasjs/func";
1
+ import { n as __reExport, t as __exportAll } from "./chunk-D8kEL_kv.mjs";
2
+ import { Config, Func, Plugin } from "@faasjs/core";
3
+ import { Logger, streamToObject, streamToString, streamToText } from "@faasjs/node-utils";
5
4
  import { Plugin as Plugin$1 } from "vite";
6
- export * from "@faasjs/func";
5
+ export * from "@faasjs/core";
7
6
 
8
7
  //#region src/test.d.ts
9
8
  /**
@@ -96,7 +95,7 @@ declare function generateFaasTypes(options?: GenerateFaasTypesOptions): Promise<
96
95
  * Create a Vite plugin that proxies POST requests to an in-process FaasJS server.
97
96
  *
98
97
  * It resolves server root/base from `src/faas.yaml` and strips `base` from
99
- * request URL before forwarding to `@faasjs/server`.
98
+ * request URL before forwarding to `@faasjs/core`.
100
99
  */
101
100
  declare function viteFaasJsServer(): Plugin$1;
102
101
  declare namespace index_d_exports {
package/dist/index.mjs CHANGED
@@ -1,13 +1,11 @@
1
- import { n as __reExport, t as __exportAll } from "./chunk-CtajNgzt.mjs";
2
- import { n as isTypegenSourceFile, r as resolveServerConfig, t as generateFaasTypes } from "./typegen-D5s91_xL.mjs";
1
+ import { n as __reExport, t as __exportAll } from "./chunk-D8kEL_kv.mjs";
2
+ import { n as isTypegenSourceFile, r as resolveServerConfig, t as generateFaasTypes } from "./typegen-BNWmP5Qp.mjs";
3
3
  import { brotliDecompressSync, gunzipSync, inflateSync } from "node:zlib";
4
- import { Http } from "@faasjs/http";
5
- import { Logger } from "@faasjs/logger";
6
- import { deepMerge, loadConfig, streamToObject, streamToString, streamToText } from "@faasjs/node-utils";
4
+ import { Http, Server } from "@faasjs/core";
5
+ import { Logger, deepMerge, loadConfig, streamToObject, streamToString, streamToText } from "@faasjs/node-utils";
7
6
  import { join } from "node:path";
8
- import { Server } from "@faasjs/server";
9
7
 
10
- export * from "@faasjs/func"
8
+ export * from "@faasjs/core"
11
9
 
12
10
  //#region src/test.ts
13
11
  /**
@@ -190,7 +188,7 @@ function stripBase(url, base) {
190
188
  * Create a Vite plugin that proxies POST requests to an in-process FaasJS server.
191
189
  *
192
190
  * It resolves server root/base from `src/faas.yaml` and strips `base` from
193
- * request URL before forwarding to `@faasjs/server`.
191
+ * request URL before forwarding to `@faasjs/core`.
194
192
  */
195
193
  function viteFaasJsServer() {
196
194
  let config;
@@ -200,10 +198,10 @@ function viteFaasJsServer() {
200
198
  name: "vite:faasjs",
201
199
  enforce: "pre",
202
200
  configResolved(resolvedConfig) {
203
- const serverConfig = resolveServerConfig(resolvedConfig.root, logger, resolvedConfig.base);
201
+ const { root, base } = resolveServerConfig(resolvedConfig.root, logger, resolvedConfig.base);
204
202
  config = {
205
- root: serverConfig.root,
206
- base: normalizeBase(serverConfig.base)
203
+ root,
204
+ base: normalizeBase(base)
207
205
  };
208
206
  },
209
207
  configureServer: async ({ middlewares, watcher }) => {
@@ -216,30 +214,17 @@ function viteFaasJsServer() {
216
214
  const runTypegen = async () => {
217
215
  try {
218
216
  const result = await generateFaasTypes({ root: config.root });
219
- logger.debug("[faas-types] %s %s (%i routes)", result.changed ? "generated" : "up-to-date", result.output, result.routeCount);
217
+ logger.debug("[faas types] %s %s (%i routes)", result.changed ? "generated" : "up-to-date", result.output, result.routeCount);
220
218
  } catch (error) {
221
- logger.error("[faas-types] %s", error.message);
222
- }
223
- };
224
- let timer = null;
225
- let runningTypegen = false;
226
- let pendingTypegen = false;
227
- const flushTypegen = async () => {
228
- if (runningTypegen || !pendingTypegen) return;
229
- pendingTypegen = false;
230
- runningTypegen = true;
231
- try {
232
- await runTypegen();
233
- } finally {
234
- runningTypegen = false;
235
- if (pendingTypegen) flushTypegen();
219
+ logger.error("[faas types] %s", error.message);
236
220
  }
237
221
  };
222
+ let timer;
223
+ let typegenChain = Promise.resolve();
238
224
  const scheduleTypegen = () => {
239
- pendingTypegen = true;
240
225
  if (timer) clearTimeout(timer);
241
226
  timer = setTimeout(() => {
242
- flushTypegen();
227
+ typegenChain = typegenChain.then(runTypegen);
243
228
  }, TYPEGEN_DEBOUNCE);
244
229
  };
245
230
  await runTypegen();
@@ -1,5 +1,4 @@
1
- import { Logger } from "@faasjs/logger";
2
- import { loadConfig } from "@faasjs/node-utils";
1
+ import { Logger, loadConfig } from "@faasjs/node-utils";
3
2
  import { existsSync } from "node:fs";
4
3
  import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
5
4
  import { dirname, join, relative, resolve } from "node:path";
@@ -15,24 +14,24 @@ function resolveServerConfig(root, logger, defaultBase = "/") {
15
14
  const config = loadConfig(srcRoot, join(srcRoot, "index.func.ts"), staging, logger);
16
15
  const server = config && typeof config === "object" ? config.server : void 0;
17
16
  return {
18
- root: server && typeof server.root === "string" && server.root.length ? resolve(projectRoot, server.root) : projectRoot,
19
- base: server && typeof server.base === "string" && server.base.length ? server.base : defaultBase,
17
+ root: typeof server?.root === "string" && server.root.length ? resolve(projectRoot, server.root) : projectRoot,
18
+ base: typeof server?.base === "string" && server.base.length ? server.base : defaultBase,
20
19
  staging
21
20
  };
22
21
  }
23
22
 
24
23
  //#endregion
25
24
  //#region src/typegen.ts
26
- function normalizeSlashes(path) {
27
- return path.replace(/\\/g, "/");
28
- }
29
25
  function normalizeRoute(path) {
30
- const normalized = path.replace(/\/+/g, "/");
26
+ const normalized = path.replace(/\\/g, "/").replace(/\/+/g, "/");
31
27
  if (!normalized.length || normalized === "/") return "/";
32
28
  return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
33
29
  }
30
+ function toTypegenRoute(route) {
31
+ return route === "/" ? "/" : route.replace(/^\/+/, "");
32
+ }
34
33
  function toRoute(srcRoot, file) {
35
- const noTsPath = normalizeSlashes(relative(srcRoot, file)).replace(/\.ts$/, "");
34
+ const noTsPath = relative(srcRoot, file).replace(/\\/g, "/").replace(/\.ts$/, "");
36
35
  if (noTsPath === "index.func") return {
37
36
  route: "/",
38
37
  priority: 2
@@ -53,10 +52,10 @@ function toRoute(srcRoot, file) {
53
52
  route: normalizeRoute(`/${noTsPath.slice(0, -5)}`),
54
53
  priority: 3
55
54
  };
56
- throw Error(`[faas-types] Invalid func filename: ${file}`);
55
+ throw Error(`[faas types] Invalid func filename: ${file}`);
57
56
  }
58
57
  function toImportPath(fromFile, targetFile) {
59
- const importPath = normalizeSlashes(relative(dirname(fromFile), targetFile)).replace(/\.ts$/, "");
58
+ const importPath = relative(dirname(fromFile), targetFile).replace(/\\/g, "/").replace(/\.ts$/, "");
60
59
  if (importPath.startsWith(".")) return importPath;
61
60
  return `./${importPath}`;
62
61
  }
@@ -81,35 +80,36 @@ function parsePluginTypes(config) {
81
80
  }
82
81
  async function readFuncFiles(dir) {
83
82
  const result = [];
84
- async function walk(currentDir) {
83
+ const pendingDirs = [dir];
84
+ while (pendingDirs.length) {
85
+ const currentDir = pendingDirs.pop();
85
86
  const entries = await readdir(currentDir, { withFileTypes: true });
86
87
  for (const entry of entries) {
87
88
  if (entry.name === ".faasjs" || entry.name === "node_modules") continue;
88
89
  const filePath = join(currentDir, entry.name);
89
90
  if (entry.isDirectory()) {
90
- await walk(filePath);
91
+ pendingDirs.push(filePath);
91
92
  continue;
92
93
  }
93
94
  if (entry.isFile() && entry.name.endsWith(".func.ts")) result.push(filePath);
94
95
  }
95
96
  }
96
- await walk(dir);
97
97
  return result.sort((a, b) => a.localeCompare(b));
98
98
  }
99
99
  function formatTypes(items) {
100
100
  const actionLines = items.map((item) => {
101
- return ` ${JSON.stringify(item.route)}: InferFaasAction<InferFaasFunc<typeof import(${JSON.stringify(item.importPath)})>>`;
101
+ return ` ${JSON.stringify(toTypegenRoute(item.route))}: InferFaasAction<InferFaasFunc<typeof import(${JSON.stringify(item.importPath)})>>`;
102
102
  });
103
103
  const eventLines = items.map((item) => {
104
104
  const plugins = item.pluginTypes.length ? `[${item.pluginTypes.map((type) => JSON.stringify(type)).join(", ")}]` : "[]";
105
- return ` ${JSON.stringify(item.route)}: InferPluginEvent<${plugins}>`;
105
+ return ` ${JSON.stringify(toTypegenRoute(item.route))}: InferPluginEvent<${plugins}>`;
106
106
  });
107
107
  return `/**
108
108
  * Generated by @faasjs/dev.
109
109
  *
110
110
  * Do not edit this file manually.
111
111
  */
112
- import type { Func, InferPluginEvent } from '@faasjs/func'
112
+ import type { Func, InferPluginEvent } from '@faasjs/core'
113
113
  import type { InferFaasAction, InferFaasFunc } from '@faasjs/types'
114
114
 
115
115
  declare module '@faasjs/types' {
@@ -122,25 +122,24 @@ ${eventLines.length ? `${eventLines.join("\n")}\n` : ""} }
122
122
  `;
123
123
  }
124
124
  function isTypegenSourceFile(filePath) {
125
- return /\.func\.ts$/.test(filePath) || /(^|[\\/])faas\.ya?ml$/.test(filePath);
125
+ return filePath.endsWith(".func.ts") || /(^|[\\/])faas\.ya?ml$/.test(filePath);
126
126
  }
127
127
  async function generateFaasTypes(options = {}) {
128
- const logger = options.logger || new Logger("FaasJs:Typegen");
129
- const { root: projectRoot, staging } = resolveServerConfig(options.root || process.cwd(), logger);
128
+ const logger = options.logger ?? new Logger("FaasJs:Typegen");
129
+ const { root: projectRoot, staging } = resolveServerConfig(options.root ?? process.cwd(), logger);
130
130
  const srcRoot = join(projectRoot, "src");
131
131
  const output = join(srcRoot, ".faasjs", "types.d.ts");
132
- if (!existsSync(srcRoot)) throw Error(`[faas-types] Source directory not found: ${srcRoot}`);
132
+ if (!existsSync(srcRoot)) throw Error(`[faas types] Source directory not found: ${srcRoot}`);
133
133
  const files = await readFuncFiles(srcRoot);
134
134
  const routeMap = /* @__PURE__ */ new Map();
135
135
  for (const file of files) {
136
136
  const { route, priority } = toRoute(srcRoot, file);
137
- const pluginTypes = parsePluginTypes(loadConfig(srcRoot, file, staging, logger));
138
- const importPath = toImportPath(output, file);
139
137
  const prev = routeMap.get(route);
140
- if (!prev || priority > prev.priority) routeMap.set(route, {
138
+ if (prev && priority <= prev.priority) continue;
139
+ routeMap.set(route, {
141
140
  route,
142
- importPath,
143
- pluginTypes,
141
+ importPath: toImportPath(output, file),
142
+ pluginTypes: parsePluginTypes(loadConfig(srcRoot, file, staging, logger)),
144
143
  priority
145
144
  });
146
145
  }
@@ -149,7 +148,7 @@ async function generateFaasTypes(options = {}) {
149
148
  let changed = true;
150
149
  try {
151
150
  if (await readFile(output, "utf8") === content) changed = false;
152
- } catch (_error) {}
151
+ } catch {}
153
152
  if (changed) {
154
153
  await mkdir(dirname(output), { recursive: true });
155
154
  await writeFile(output, content);