@web-ts-toolkit/express-runtime 0.8.0 → 0.9.0
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 +38 -8
- package/cli.js +243 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -103,6 +103,29 @@ For TypeScript app modules, run the CLI through `tsx`:
|
|
|
103
103
|
npx tsx ./node_modules/@web-ts-toolkit/express-runtime/dist/cli.js dev ./src/app.ts
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
#### CLI — dev with env, require, and watch
|
|
107
|
+
|
|
108
|
+
`--env` loads `.env` files into `process.env` (existing vars are not
|
|
109
|
+
overridden). `--require` preloads modules (e.g. `tsconfig-paths/register` for
|
|
110
|
+
TS path aliases) before the app module is loaded. `--watch` forks a child
|
|
111
|
+
process running the server and restarts it on file changes:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
npx tsx ./node_modules/@web-ts-toolkit/express-runtime/dist/cli.js dev ./src/app.ts \
|
|
115
|
+
--env .env \
|
|
116
|
+
--require tsconfig-paths/register \
|
|
117
|
+
--watch ./src,./shared \
|
|
118
|
+
--ext ts,json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> `--env` parses `KEY=VALUE` lines (supports `export` prefix, quoted values,
|
|
122
|
+
> `#` comments). For advanced dotenv features (multiline, variable expansion),
|
|
123
|
+
> use `--require dotenv/config` instead.
|
|
124
|
+
>
|
|
125
|
+
> `--watch` uses Node 20+'s `fs.watch` with `{ recursive: true }` and forks the
|
|
126
|
+
> same CLI as a child process. On file change, the child receives `SIGTERM`,
|
|
127
|
+
> waits for it to exit, and respawns after the debounce delay (`--delay`).
|
|
128
|
+
|
|
106
129
|
> The `dev` command evaluates arbitrary code from `<app-module>` in the current
|
|
107
130
|
> process and inherits its privileges. Init logic (e.g. DB connections) should
|
|
108
131
|
> be placed at the top level of your app module since `dev` does not expose an
|
|
@@ -147,7 +170,7 @@ serverless platform:
|
|
|
147
170
|
|
|
148
171
|
```sh
|
|
149
172
|
npx wtt-express-runtime build ./src/app.ts --out-dir dist
|
|
150
|
-
npx wtt-express-runtime start ./dist/handler.js --port 9000
|
|
173
|
+
npx wtt-express-runtime start ./dist/handler.js --port 9000 --env .env
|
|
151
174
|
```
|
|
152
175
|
|
|
153
176
|
The handler module must export a `handler` function (named or default) that
|
|
@@ -291,6 +314,11 @@ Omitting `<command>` defaults to `dev` for backward compatibility.
|
|
|
291
314
|
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`) |
|
|
292
315
|
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration |
|
|
293
316
|
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`) |
|
|
317
|
+
| `--require <module>` | Module(s) to preload before app load (repeatable; comma-separated values supported) |
|
|
318
|
+
| `--env <path>` | Env file(s) to load before app load (repeatable; existing env vars are not overridden) |
|
|
319
|
+
| `--watch <paths>` | Comma-separated paths to watch for restart (repeatable; forks a child process) |
|
|
320
|
+
| `--ext <extensions>` | Comma-separated extensions to watch (default: `ts,js,mjs,cjs,json`) |
|
|
321
|
+
| `--delay <ms>` | Debounce ms before restarting on change (default: `500`) |
|
|
294
322
|
|
|
295
323
|
#### build options
|
|
296
324
|
|
|
@@ -307,13 +335,15 @@ Omitting `<command>` defaults to `dev` for backward compatibility.
|
|
|
307
335
|
|
|
308
336
|
#### start options
|
|
309
337
|
|
|
310
|
-
| Option | Description
|
|
311
|
-
| ------------------------- |
|
|
312
|
-
| `<handler-module>` | JS/CJS module path exporting `handler` (named or default) — the output of `build`
|
|
313
|
-
| `--port <number>` | Port or named pipe (default: `process.env.PORT` or `8080`)
|
|
314
|
-
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`)
|
|
315
|
-
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration
|
|
316
|
-
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`)
|
|
338
|
+
| Option | Description |
|
|
339
|
+
| ------------------------- | ------------------------------------------------------------------------------------------ |
|
|
340
|
+
| `<handler-module>` | JS/CJS module path exporting `handler` (named or default) — the output of `build` |
|
|
341
|
+
| `--port <number>` | Port or named pipe (default: `process.env.PORT` or `8080`) |
|
|
342
|
+
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`) |
|
|
343
|
+
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration |
|
|
344
|
+
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`) |
|
|
345
|
+
| `--require <module>` | Module(s) to preload before handler load (repeatable; comma-separated values supported) |
|
|
346
|
+
| `--env <path>` | Env file(s) to load before handler load (repeatable; existing env vars are not overridden) |
|
|
317
347
|
|
|
318
348
|
#### global options
|
|
319
349
|
|
package/cli.js
CHANGED
|
@@ -27,6 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var import_node_url = require("url");
|
|
28
28
|
var import_node_path = require("path");
|
|
29
29
|
var import_node_fs = require("fs");
|
|
30
|
+
var import_node_module = require("module");
|
|
31
|
+
var import_node_child_process = require("child_process");
|
|
30
32
|
|
|
31
33
|
// src/index.ts
|
|
32
34
|
var import_node_http = __toESM(require("http"));
|
|
@@ -194,6 +196,7 @@ function startLocalServer(app, options = {}) {
|
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
// src/cli-utils.ts
|
|
199
|
+
var import_meta = {};
|
|
197
200
|
var CLI_VERSION = "0.0.0-PLACEHOLDER";
|
|
198
201
|
function readValue(argv, index, name) {
|
|
199
202
|
const value = argv[index + 1];
|
|
@@ -221,6 +224,11 @@ Dev options:
|
|
|
221
224
|
--host <hostname> Hostname to bind (default: process.env.HOST or 0.0.0.0)
|
|
222
225
|
--no-signals Disable SIGINT/SIGTERM handler registration
|
|
223
226
|
--shutdown-timeout <ms> Max ms to wait for in-flight requests (default: 5000)
|
|
227
|
+
--require <module> Module(s) to preload before app load (repeatable)
|
|
228
|
+
--env <path> Env file(s) to load (repeatable; existing env vars are not overridden)
|
|
229
|
+
--watch <paths> Comma-separated paths to watch for restart (repeatable; dev only)
|
|
230
|
+
--ext <extensions> Comma-separated extensions to watch (default: ts,js,mjs,cjs,json)
|
|
231
|
+
--delay <ms> Debounce ms before restarting on change (default: 500)
|
|
224
232
|
|
|
225
233
|
Build options:
|
|
226
234
|
--init <path> Init hook module (default export, async function)
|
|
@@ -236,6 +244,8 @@ Start options:
|
|
|
236
244
|
--host <hostname> Hostname to bind (default: process.env.HOST or 0.0.0.0)
|
|
237
245
|
--no-signals Disable SIGINT/SIGTERM handler registration
|
|
238
246
|
--shutdown-timeout <ms> Max ms to wait for in-flight requests (default: 5000)
|
|
247
|
+
--require <module> Module(s) to preload before handler load (repeatable)
|
|
248
|
+
--env <path> Env file(s) to load (repeatable; existing env vars are not overridden)
|
|
239
249
|
|
|
240
250
|
Global options:
|
|
241
251
|
-V, --version Show version
|
|
@@ -244,15 +254,21 @@ Global options:
|
|
|
244
254
|
Examples:
|
|
245
255
|
wtt-express-runtime dev ./dist/app.js
|
|
246
256
|
wtt-express-runtime dev ./dist/app.js --port 3000 --host localhost
|
|
257
|
+
wtt-express-runtime dev ./src/app.ts --env .env --require tsconfig-paths/register --watch ./src,./shared
|
|
247
258
|
wtt-express-runtime build ./src/app.ts --out-dir netlify/functions
|
|
248
259
|
wtt-express-runtime build ./src/app.ts --init ./src/init.ts --format esm
|
|
249
|
-
wtt-express-runtime start ./netlify/functions/handler.js --port 9000
|
|
260
|
+
wtt-express-runtime start ./netlify/functions/handler.js --port 9000 --env .env
|
|
250
261
|
wtt-express-runtime build ./src/app.ts && wtt-express-runtime start ./dist/handler.js
|
|
251
262
|
|
|
252
263
|
Notes:
|
|
253
264
|
- In dev mode, the CLI evaluates arbitrary code from <app-module> in the current process.
|
|
254
265
|
- TypeScript app modules in dev mode require a TS loader. Run via tsx:
|
|
255
266
|
npx tsx ./node_modules/@web-ts-toolkit/express-runtime/dist/cli.js dev ./src/app.ts
|
|
267
|
+
Or use --require with a TS-aware loader module.
|
|
268
|
+
- --env files are parsed as KEY=VALUE; existing process.env entries are never overridden.
|
|
269
|
+
For advanced dotenv features (multiline, expansion), --require dotenv/config instead.
|
|
270
|
+
- --watch forks a child process running the same CLI without --watch. On file change,
|
|
271
|
+
the child is killed (SIGTERM) and respawned after the debounce delay.
|
|
256
272
|
- In build mode, tsup is required: pnpm add -D tsup
|
|
257
273
|
- In start mode, the bundled handler file must be a JS/CJS module whose "handler"
|
|
258
274
|
export (or default export) is a function: (event, context) => Promise<result>.
|
|
@@ -268,8 +284,23 @@ function isHelp(arg) {
|
|
|
268
284
|
function isSubcommand(arg) {
|
|
269
285
|
return arg === "dev" || arg === "build" || arg === "start";
|
|
270
286
|
}
|
|
287
|
+
var DEFAULT_WATCH_EXTENSIONS = ["ts", "js", "mjs", "cjs", "json"];
|
|
288
|
+
var DEFAULT_WATCH_DELAY = 500;
|
|
289
|
+
function parseRepeatable(argv, index, arg, list) {
|
|
290
|
+
const value = readValue(argv, index, arg);
|
|
291
|
+
for (const part of value.split(",")) {
|
|
292
|
+
const trimmed = part.trim();
|
|
293
|
+
if (trimmed) list.push(trimmed);
|
|
294
|
+
}
|
|
295
|
+
return index + 1;
|
|
296
|
+
}
|
|
271
297
|
function parseDevArgs(argv) {
|
|
272
298
|
const options = {};
|
|
299
|
+
const requireModules = [];
|
|
300
|
+
const envFiles = [];
|
|
301
|
+
const watchPaths = [];
|
|
302
|
+
let watchExt;
|
|
303
|
+
let watchDelay;
|
|
273
304
|
let appPath;
|
|
274
305
|
for (let index = 0; index < argv.length; index += 1) {
|
|
275
306
|
const arg = argv[index];
|
|
@@ -314,6 +345,61 @@ function parseDevArgs(argv) {
|
|
|
314
345
|
options.shutdownTimeout = Number(arg.slice("--shutdown-timeout=".length));
|
|
315
346
|
continue;
|
|
316
347
|
}
|
|
348
|
+
if (arg === "--require") {
|
|
349
|
+
index = parseRepeatable(argv, index, arg, requireModules);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (arg.startsWith("--require=")) {
|
|
353
|
+
for (const part of arg.slice("--require=".length).split(",")) {
|
|
354
|
+
const trimmed = part.trim();
|
|
355
|
+
if (trimmed) requireModules.push(trimmed);
|
|
356
|
+
}
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (arg === "--env") {
|
|
360
|
+
index = parseRepeatable(argv, index, arg, envFiles);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (arg.startsWith("--env=")) {
|
|
364
|
+
for (const part of arg.slice("--env=".length).split(",")) {
|
|
365
|
+
const trimmed = part.trim();
|
|
366
|
+
if (trimmed) envFiles.push(trimmed);
|
|
367
|
+
}
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (arg === "--watch") {
|
|
371
|
+
index = parseRepeatable(argv, index, arg, watchPaths);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (arg.startsWith("--watch=")) {
|
|
375
|
+
for (const part of arg.slice("--watch=".length).split(",")) {
|
|
376
|
+
const trimmed = part.trim();
|
|
377
|
+
if (trimmed) watchPaths.push(trimmed);
|
|
378
|
+
}
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (arg === "--ext") {
|
|
382
|
+
watchExt = [];
|
|
383
|
+
index = parseRepeatable(argv, index, arg, watchExt);
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
if (arg.startsWith("--ext=")) {
|
|
387
|
+
watchExt = [];
|
|
388
|
+
for (const part of arg.slice("--ext=".length).split(",")) {
|
|
389
|
+
const trimmed = part.trim();
|
|
390
|
+
if (trimmed) watchExt.push(trimmed);
|
|
391
|
+
}
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
if (arg === "--delay") {
|
|
395
|
+
watchDelay = Number(readValue(argv, index, arg));
|
|
396
|
+
index += 1;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
if (arg.startsWith("--delay=")) {
|
|
400
|
+
watchDelay = Number(arg.slice("--delay=".length));
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
317
403
|
if (!arg.startsWith("--")) {
|
|
318
404
|
if (appPath) {
|
|
319
405
|
throw new Error(`Unexpected positional argument: ${arg}. App module already set to ${appPath}`);
|
|
@@ -327,11 +413,29 @@ function parseDevArgs(argv) {
|
|
|
327
413
|
printHelp();
|
|
328
414
|
throw new Error("Missing required argument: <app-module>");
|
|
329
415
|
}
|
|
330
|
-
return {
|
|
416
|
+
return {
|
|
417
|
+
appPath,
|
|
418
|
+
options,
|
|
419
|
+
require: requireModules,
|
|
420
|
+
env: envFiles,
|
|
421
|
+
watch: watchPaths,
|
|
422
|
+
watchExt: watchExt ?? DEFAULT_WATCH_EXTENSIONS,
|
|
423
|
+
watchDelay: watchDelay ?? DEFAULT_WATCH_DELAY
|
|
424
|
+
};
|
|
331
425
|
}
|
|
332
426
|
function parseStartArgs(argv) {
|
|
427
|
+
for (const arg of argv) {
|
|
428
|
+
if (arg === "--watch" || arg.startsWith("--watch=") || arg === "--ext" || arg.startsWith("--ext=") || arg === "--delay" || arg.startsWith("--delay=")) {
|
|
429
|
+
throw new Error(`--watch/--ext/--delay are not supported with the start subcommand`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
333
432
|
const result = parseDevArgs(argv);
|
|
334
|
-
return {
|
|
433
|
+
return {
|
|
434
|
+
handlerPath: result.appPath,
|
|
435
|
+
options: result.options,
|
|
436
|
+
require: result.require,
|
|
437
|
+
env: result.env
|
|
438
|
+
};
|
|
335
439
|
}
|
|
336
440
|
function parseBuildArgs(argv) {
|
|
337
441
|
let appPath;
|
|
@@ -494,6 +598,124 @@ async function loadApp(appPath) {
|
|
|
494
598
|
}
|
|
495
599
|
return resolveExport(exported, appPath);
|
|
496
600
|
}
|
|
601
|
+
function parseEnvFile(content) {
|
|
602
|
+
const result = {};
|
|
603
|
+
for (const line of content.split("\n")) {
|
|
604
|
+
let trimmed = line.trim();
|
|
605
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
606
|
+
if (trimmed.startsWith("export ")) trimmed = trimmed.slice("export ".length).trim();
|
|
607
|
+
const eqIndex = trimmed.indexOf("=");
|
|
608
|
+
if (eqIndex === -1) continue;
|
|
609
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
610
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
611
|
+
if (value.length >= 2) {
|
|
612
|
+
const first = value[0];
|
|
613
|
+
const last = value[value.length - 1];
|
|
614
|
+
if (first === '"' && last === '"' || first === "'" && last === "'") {
|
|
615
|
+
value = value.slice(1, -1);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
result[key] = value;
|
|
619
|
+
}
|
|
620
|
+
return result;
|
|
621
|
+
}
|
|
622
|
+
function loadEnvFiles(paths) {
|
|
623
|
+
for (const p of paths) {
|
|
624
|
+
const absPath = (0, import_node_path.resolve)(process.cwd(), p);
|
|
625
|
+
if (!(0, import_node_fs.existsSync)(absPath)) {
|
|
626
|
+
throw new Error(`Env file not found: ${p}`);
|
|
627
|
+
}
|
|
628
|
+
const content = (0, import_node_fs.readFileSync)(absPath, "utf8");
|
|
629
|
+
const parsed = parseEnvFile(content);
|
|
630
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
631
|
+
if (process.env[key] === void 0) {
|
|
632
|
+
process.env[key] = value;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
var moduleRequire = (0, import_node_module.createRequire)(
|
|
638
|
+
typeof import_meta !== "undefined" && import_meta.url || (0, import_node_path.resolve)(process.cwd(), "x").replace(/x$/, "")
|
|
639
|
+
);
|
|
640
|
+
async function preloadModules(modules) {
|
|
641
|
+
for (const mod of modules) {
|
|
642
|
+
moduleRequire(mod);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
function buildChildArgs(args) {
|
|
646
|
+
const result = ["dev", args.appPath];
|
|
647
|
+
if (args.options.port !== void 0) result.push("--port", String(args.options.port));
|
|
648
|
+
if (args.options.host !== void 0) result.push("--host", args.options.host);
|
|
649
|
+
if (args.options.signals === false) result.push("--no-signals");
|
|
650
|
+
if (args.options.shutdownTimeout !== void 0)
|
|
651
|
+
result.push("--shutdown-timeout", String(args.options.shutdownTimeout));
|
|
652
|
+
for (const r of args.require) result.push("--require", r);
|
|
653
|
+
for (const e of args.env) result.push("--env", e);
|
|
654
|
+
return result;
|
|
655
|
+
}
|
|
656
|
+
function runWithWatch(args) {
|
|
657
|
+
const cliPath = process.argv[1];
|
|
658
|
+
const childArgv = buildChildArgs(args);
|
|
659
|
+
let child = null;
|
|
660
|
+
let restartTimer = null;
|
|
661
|
+
let isShuttingDown = false;
|
|
662
|
+
const restartDelay = args.watchDelay;
|
|
663
|
+
const spawnChild = () => {
|
|
664
|
+
child = (0, import_node_child_process.fork)(cliPath, childArgv, { stdio: "inherit" });
|
|
665
|
+
child.on("exit", (code) => {
|
|
666
|
+
child = null;
|
|
667
|
+
if (!isShuttingDown && code !== null && code !== 0) {
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
};
|
|
671
|
+
const killChild = () => {
|
|
672
|
+
return new Promise((resolve) => {
|
|
673
|
+
if (!child || !child.pid) {
|
|
674
|
+
resolve();
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
child.once("exit", () => resolve());
|
|
678
|
+
child.kill("SIGTERM");
|
|
679
|
+
});
|
|
680
|
+
};
|
|
681
|
+
const restart = async () => {
|
|
682
|
+
await killChild();
|
|
683
|
+
spawnChild();
|
|
684
|
+
};
|
|
685
|
+
const debouncedRestart = () => {
|
|
686
|
+
if (restartTimer) clearTimeout(restartTimer);
|
|
687
|
+
restartTimer = setTimeout(() => {
|
|
688
|
+
restartTimer = null;
|
|
689
|
+
void restart();
|
|
690
|
+
}, restartDelay);
|
|
691
|
+
};
|
|
692
|
+
for (const watchPath of args.watch) {
|
|
693
|
+
const absPath = (0, import_node_path.resolve)(process.cwd(), watchPath);
|
|
694
|
+
if (!(0, import_node_fs.existsSync)(absPath)) {
|
|
695
|
+
throw new Error(`Watch path not found: ${watchPath}`);
|
|
696
|
+
}
|
|
697
|
+
(0, import_node_fs.watch)(absPath, { recursive: true }, (_eventType, filename) => {
|
|
698
|
+
if (!filename) return;
|
|
699
|
+
const ext = (0, import_node_path.extname)(filename).slice(1).toLowerCase();
|
|
700
|
+
if (args.watchExt.includes(ext)) {
|
|
701
|
+
debouncedRestart();
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
const shutdown = () => {
|
|
706
|
+
isShuttingDown = true;
|
|
707
|
+
if (restartTimer) clearTimeout(restartTimer);
|
|
708
|
+
if (child && child.pid) {
|
|
709
|
+
child.once("exit", () => process.exit(0));
|
|
710
|
+
child.kill("SIGTERM");
|
|
711
|
+
} else {
|
|
712
|
+
process.exit(0);
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
process.on("SIGINT", shutdown);
|
|
716
|
+
process.on("SIGTERM", shutdown);
|
|
717
|
+
spawnChild();
|
|
718
|
+
}
|
|
497
719
|
var TEMP_ENTRY_FILENAME = ".express-runtime-build-entry.ts";
|
|
498
720
|
function generateServerlessEntry(appPath, initPath) {
|
|
499
721
|
const absAppPath = (0, import_node_path.resolve)(process.cwd(), appPath);
|
|
@@ -619,12 +841,26 @@ async function main() {
|
|
|
619
841
|
return;
|
|
620
842
|
}
|
|
621
843
|
if (parsedArgs.subcommand === "dev") {
|
|
622
|
-
const
|
|
623
|
-
|
|
844
|
+
const { dev } = parsedArgs;
|
|
845
|
+
if (dev.watch.length > 0) {
|
|
846
|
+
runWithWatch(dev);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (dev.env.length > 0) {
|
|
850
|
+
loadEnvFiles(dev.env);
|
|
851
|
+
}
|
|
852
|
+
await preloadModules(dev.require);
|
|
853
|
+
const app = await loadApp(dev.appPath);
|
|
854
|
+
startLocalServer(app, { ...dev.options, exitAfterShutdown: true });
|
|
624
855
|
} else if (parsedArgs.subcommand === "start") {
|
|
625
|
-
const
|
|
856
|
+
const { start } = parsedArgs;
|
|
857
|
+
if (start.env.length > 0) {
|
|
858
|
+
loadEnvFiles(start.env);
|
|
859
|
+
}
|
|
860
|
+
await preloadModules(start.require);
|
|
861
|
+
const handler = await loadHandler(start.handlerPath);
|
|
626
862
|
const app = createServerlessAdapterApp(handler);
|
|
627
|
-
startLocalServer(app, { ...
|
|
863
|
+
startLocalServer(app, { ...start.options, exitAfterShutdown: true });
|
|
628
864
|
} else {
|
|
629
865
|
await buildServerless(parsedArgs.build);
|
|
630
866
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@web-ts-toolkit/express-runtime",
|
|
3
3
|
"description": "Express app factory plus serverless handler and local dev server helpers",
|
|
4
4
|
"homepage": "https://web-ts-toolkit.pages.dev/docs/packages/express-runtime",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.9.0",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"keywords": [
|
|
8
8
|
"express",
|