@web-ts-toolkit/express-runtime 0.43.0 → 0.45.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 +86 -52
- package/{chunk-UPFG3S34.mjs → chunk-KBNC4WIR.mjs} +378 -101
- package/{chunk-VPFBKM2K.mjs → chunk-QNRHWPTO.mjs} +13 -10
- package/cli-api.d.mts +166 -18
- package/cli-api.d.ts +166 -18
- package/cli-api.js +385 -109
- package/cli-api.mjs +4 -4
- package/{cli-utils-4POUMJN7.mjs → cli-utils-IN67EHOM.mjs} +2 -2
- package/cli.js +385 -109
- package/index.d.mts +16 -6
- package/index.d.ts +16 -6
- package/index.js +11 -10
- package/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -171,8 +171,13 @@ This produces `dist/app.js` (configurable via `--out-name`) that default-exports
|
|
|
171
171
|
the Express app and, when `--init` is used, also exports `init` for the `start`
|
|
172
172
|
command to run before listening.
|
|
173
173
|
|
|
174
|
-
> `express`
|
|
175
|
-
> `--external`.
|
|
174
|
+
> `express` and `@web-ts-toolkit/express-runtime` are always external;
|
|
175
|
+
> additional externals can be added via `--external`. Deploy the bundle with
|
|
176
|
+
> both packages installed (`express` is a peer dependency).
|
|
177
|
+
|
|
178
|
+
> `build` and `build-serverless` require `tsup` to be installed: the CLI bundle
|
|
179
|
+
> keeps it external and loads it via dynamic import only when building. Users
|
|
180
|
+
> who only run `dev`, `start`, or `start-serverless` don't need it.
|
|
176
181
|
|
|
177
182
|
### CLI — start (run a bundled app locally)
|
|
178
183
|
|
|
@@ -202,8 +207,10 @@ npx wtt-express-runtime build-serverless ./src/app.ts --init ./src/init.ts --out
|
|
|
202
207
|
```
|
|
203
208
|
|
|
204
209
|
This produces `netlify/functions/handler.js` (configurable via `--out-name`)
|
|
205
|
-
that exports a `handler` function using `serverless-http`.
|
|
206
|
-
|
|
210
|
+
that exports a `handler` function using `serverless-http`. Configure the
|
|
211
|
+
supported `serverless-http` provider options via `serverlessOptions`
|
|
212
|
+
(`provider: 'aws' | 'azure'`); other platform shapes are not emulated locally
|
|
213
|
+
(see the `start-serverless` adapter contract below).
|
|
207
214
|
|
|
208
215
|
### CLI — start-serverless (run a bundled handler locally)
|
|
209
216
|
|
|
@@ -232,6 +239,13 @@ npx wtt-express-runtime start-serverless ./dist/handler.js --port 9000 --env .en
|
|
|
232
239
|
> IP.
|
|
233
240
|
>
|
|
234
241
|
> The incoming URL query is split from the path before the handler is invoked.
|
|
242
|
+
> Origin-form paths are preserved verbatim — never dot-segment-resolved,
|
|
243
|
+
> slash-collapsed, or percent-decoded — so `//admin/users`, `/a/../private`,
|
|
244
|
+
> and `/%2E%2E/private` reach wrapped routing exactly as sent. Absolute-form
|
|
245
|
+
> targets (`scheme://authority/path?query`, as sent to proxies) are supported
|
|
246
|
+
> by stripping the scheme and authority; asterisk-form (`*`) yields path `*`;
|
|
247
|
+
> the empty string maps to `/`. Any other target shape is rejected with a 500
|
|
248
|
+
> before the handler runs.
|
|
235
249
|
> Query keys and values are decoded once from percent-encoding, duplicate keys are
|
|
236
250
|
> preserved in `multiValueQueryStringParameters`, empty values are preserved as
|
|
237
251
|
> `''`, literal `+` signs remain `+`, and encoded delimiters such as `%26` and
|
|
@@ -253,8 +267,12 @@ npx wtt-express-runtime start-serverless ./dist/handler.js --port 9000 --env .en
|
|
|
253
267
|
> chunked bodies are checked incrementally and stop retaining chunks after the
|
|
254
268
|
> limit — the request is drained and a `413 Payload Too Large` is returned without
|
|
255
269
|
> invoking the handler. Client aborts and stream errors release listeners and do
|
|
256
|
-
> not produce an unhandled rejection.
|
|
257
|
-
> one
|
|
270
|
+
> not produce an unhandled rejection. Chunk retention is `O(limit)` — appending
|
|
271
|
+
> stops once the running total would exceed the limit, so at most one chunk over
|
|
272
|
+
> the limit is observed. `Buffer.concat` then holds the chunks plus one output
|
|
273
|
+
> Buffer, and event translation adds a transient base64 copy (~4/3 of the body),
|
|
274
|
+
> so peak transient memory is a small multiple of the limit rather than an exact
|
|
275
|
+
> limit-plus-chunk ceiling.
|
|
258
276
|
>
|
|
259
277
|
> Override the limit intentionally:
|
|
260
278
|
>
|
|
@@ -374,19 +392,27 @@ runtime calls, which pass `(request, event, context)` before Express and
|
|
|
374
392
|
`Record<string, unknown>` for both arguments; provide provider-specific event and
|
|
375
393
|
context types when you need typed access in hooks.
|
|
376
394
|
|
|
377
|
-
####
|
|
395
|
+
#### Serverless deployment example
|
|
378
396
|
|
|
379
397
|
```ts
|
|
380
398
|
import { createExpressApp, createServerlessHandler } from '@web-ts-toolkit/express-runtime';
|
|
381
|
-
import { Handler } from '@netlify/functions';
|
|
382
399
|
|
|
383
400
|
const app = createExpressApp({
|
|
384
401
|
routers: [{ path: () => '/.netlify/functions/main', handler: myRouter }],
|
|
385
402
|
});
|
|
386
403
|
|
|
387
|
-
export const handler
|
|
404
|
+
export const handler = createServerlessHandler(app, { init: startDB });
|
|
388
405
|
```
|
|
389
406
|
|
|
407
|
+
Export the `ServerlessHandler` as-is with its inferred type. Do not annotate
|
|
408
|
+
it with the platform's `Handler` type (e.g. from `@netlify/functions`): the
|
|
409
|
+
handler resolves `Promise<object>` for the event shapes `serverless-http`
|
|
410
|
+
supports (`aws`/`azure` providers), which is not assignable to Netlify's
|
|
411
|
+
`HandlerResponse` (`statusCode` is required there), so such an annotation fails
|
|
412
|
+
strict compilation. If the platform requires its own handler type, add an
|
|
413
|
+
explicit adapter in the app. No platform-specific adapter is shipped; the local
|
|
414
|
+
`start-serverless` command emulates AWS API Gateway REST API v1 only.
|
|
415
|
+
|
|
390
416
|
### `startLocalServer(app, options?): LocalServer`
|
|
391
417
|
|
|
392
418
|
Binds an Express app to a TCP port (or named pipe) via `http.createServer`,
|
|
@@ -398,18 +424,18 @@ Shutdown order and timeout policy: on `shutdown()`, the server first stops accep
|
|
|
398
424
|
|
|
399
425
|
Port `0` logs the actual bound port (e.g. `Server running at http://127.0.0.1:54321/ (port 54321)`).
|
|
400
426
|
|
|
401
|
-
| Option | Type | Default | Description
|
|
402
|
-
| ------------------- | ----------------------------- | ----------------------------- |
|
|
403
|
-
| `port` | `number \| string` | `process.env.PORT ?? 8080` | Port number or named-pipe path (use `0` for an ephemeral port; actual port is logged)
|
|
404
|
-
| `host` | `string` | `process.env.HOST ?? 0.0.0.0` | Hostname (ignored for named pipes)
|
|
405
|
-
| `init` | `() => Promise<void>` | — | Called once before listening; rejection rejects `ready` and skips listening
|
|
406
|
-
| `onShutdown` | `() => Promise<void> \| void` | — | Called **after** draining; rejection is logged and fails shutdown
|
|
407
|
-
| `onListening` | `() => void` | — | Called when listening (after actual-port log)
|
|
408
|
-
| `onError` | `(error) => void` | logs + exits | Called on listen errors and init failures (init failures are not `listen` syscall errors)
|
|
409
|
-
| `signals` | `boolean \| NodeJS.Signals[]` | `true` (`SIGINT`, `SIGTERM`) | Signal handlers to register (owned handlers removed on shutdown/terminal failure)
|
|
410
|
-
| `shutdownTimeout` | `number` | `5000` | Max ms to wait for in-flight requests before force-closing (covers draining only)
|
|
411
|
-
| `exitAfterShutdown` | `boolean` | `false` | Call `process.exit(0)` after successful shutdown or `process.exit(1)` after cleanup failure
|
|
412
|
-
| `logger` | `Logger` | `console` | Logger used internally
|
|
427
|
+
| Option | Type | Default | Description |
|
|
428
|
+
| ------------------- | ----------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
429
|
+
| `port` | `number \| string` | `process.env.PORT ?? 8080` | Port number or named-pipe path (use `0` for an ephemeral port; actual port is logged) |
|
|
430
|
+
| `host` | `string` | `process.env.HOST ?? 0.0.0.0` | Hostname (ignored for named pipes) |
|
|
431
|
+
| `init` | `() => Promise<void>` | — | Called once before listening; rejection rejects `ready` and skips listening |
|
|
432
|
+
| `onShutdown` | `() => Promise<void> \| void` | — | Called **after** draining; rejection is logged and fails shutdown |
|
|
433
|
+
| `onListening` | `() => void` | — | Called when listening (after actual-port log) |
|
|
434
|
+
| `onError` | `(error) => void` | logs + exits | Called on listen errors and init failures (init failures are not `listen` syscall errors) |
|
|
435
|
+
| `signals` | `boolean \| NodeJS.Signals[]` | `true` (`SIGINT`, `SIGTERM`) | Signal handlers to register (owned handlers removed on shutdown/terminal failure) |
|
|
436
|
+
| `shutdownTimeout` | `number` | `5000` | Max ms to wait for in-flight requests before force-closing (covers draining only; `0..2147483647`, `0` force-closes immediately) |
|
|
437
|
+
| `exitAfterShutdown` | `boolean` | `false` | Call `process.exit(0)` after successful shutdown or `process.exit(1)` after cleanup failure |
|
|
438
|
+
| `logger` | `Logger` | `console` | Logger used internally |
|
|
413
439
|
|
|
414
440
|
#### `LocalServer`
|
|
415
441
|
|
|
@@ -460,9 +486,9 @@ The `@web-ts-toolkit/express-runtime/cli` subpath is a supported programmatic CL
|
|
|
460
486
|
facade used by packages such as `@web-ts-toolkit/access-router-runtime`.
|
|
461
487
|
Supported consumer API exports are `parseArgs`, `runCliCommand`, `runDevCommand`,
|
|
462
488
|
`runExpressDevCommand`, `runBuildEntryCommand`, `RuntimeCliCommand`,
|
|
463
|
-
`DevCommandRunner`, `BuildEntryCommandOptions`, `DevArgs`, `BuildArgs`,
|
|
489
|
+
`DevCommandRunner`, `BuildEntryCommandOptions`, `BuildEntryContentArgs`, `DevArgs`, `BuildArgs`,
|
|
464
490
|
`StartArgs`, `StartServerlessArgs`, `ParsedArgs`, `Subcommand`,
|
|
465
|
-
`RuntimeModuleInit`, `GenericHandler`, `ApiGatewayRestEvent`,
|
|
491
|
+
`RuntimeModuleInit`, `RuntimeModuleShutdown`, `GenericHandler`, `ApiGatewayRestEvent`,
|
|
466
492
|
`ServerlessResult`, `ServerlessAdapterOptions`, `CLI_VERSION`,
|
|
467
493
|
`DEFAULT_ADAPTER_MAX_BODY_BYTES`, `TEMP_BUILD_ENTRY_FILENAME`, and
|
|
468
494
|
`TEMP_SERVERLESS_ENTRY_FILENAME`.
|
|
@@ -509,25 +535,25 @@ Omitting `<command>` defaults to `dev` for backward compatibility.
|
|
|
509
535
|
| `--port <number>` | Port or named pipe (default: `process.env.PORT` or `8080`) |
|
|
510
536
|
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`) |
|
|
511
537
|
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration |
|
|
512
|
-
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`)
|
|
538
|
+
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`; `0..2147483647`) |
|
|
513
539
|
| `--require <module>` | Module(s) to preload before app load (repeatable; comma-separated values supported) |
|
|
514
540
|
| `--env <path>` | Env file(s) to load before app load (repeatable; existing env vars are not overridden) |
|
|
515
541
|
| `--watch <paths>` | Comma-separated paths to watch for restart (repeatable; forks a child process) |
|
|
516
542
|
| `--ext <extensions>` | Comma-separated extensions to watch (default: `ts,js,mjs,cjs,json`) |
|
|
517
|
-
| `--delay <ms>` | Debounce ms before restarting on change (default: `500`)
|
|
543
|
+
| `--delay <ms>` | Debounce ms before restarting on change (default: `500`; `0..2147483647`) |
|
|
518
544
|
|
|
519
545
|
#### build options
|
|
520
546
|
|
|
521
|
-
| Option | Description
|
|
522
|
-
| --------------------- |
|
|
523
|
-
| `<app-module>` | Module path whose **default export** is an Express app (sync, not async factory)
|
|
524
|
-
| `--init <path>` | Init hook module (default export, async function) called once per cold start
|
|
525
|
-
| `--out-dir <path>` | Output directory (default: `dist`)
|
|
526
|
-
| `--out-name <name>` | Output filename without extension (default: `app`)
|
|
527
|
-
| `--format <cjs\|esm>` | Output format (default: `cjs`)
|
|
528
|
-
| `--target <target>` | Compilation target (default: `node22`)
|
|
529
|
-
| `--external <pkg>` | Mark package as external (repeatable; `express`
|
|
530
|
-
| `--no-clean` | Don't clean the output directory before building
|
|
547
|
+
| Option | Description |
|
|
548
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
549
|
+
| `<app-module>` | Module path whose **default export** is an Express app (sync, not async factory) |
|
|
550
|
+
| `--init <path>` | Init hook module (default export, async function) called once per cold start |
|
|
551
|
+
| `--out-dir <path>` | Output directory (default: `dist`) |
|
|
552
|
+
| `--out-name <name>` | Output filename without extension (default: `app`) |
|
|
553
|
+
| `--format <cjs\|esm>` | Output format (default: `cjs`) |
|
|
554
|
+
| `--target <target>` | Compilation target (default: `node22`) |
|
|
555
|
+
| `--external <pkg>` | Mark package as external (repeatable; `express` and `@web-ts-toolkit/express-runtime` are always external) |
|
|
556
|
+
| `--no-clean` | Don't clean the output directory before building |
|
|
531
557
|
|
|
532
558
|
#### start options
|
|
533
559
|
|
|
@@ -537,22 +563,22 @@ Omitting `<command>` defaults to `dev` for backward compatibility.
|
|
|
537
563
|
| `--port <number>` | Port or named pipe (default: `process.env.PORT` or `8080`) |
|
|
538
564
|
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`) |
|
|
539
565
|
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration |
|
|
540
|
-
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`)
|
|
566
|
+
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`; `0..2147483647`) |
|
|
541
567
|
| `--require <module>` | Module(s) to preload before app load (repeatable; comma-separated values supported) |
|
|
542
568
|
| `--env <path>` | Env file(s) to load before app load (repeatable; existing env vars are not overridden) |
|
|
543
569
|
|
|
544
570
|
#### build-serverless options
|
|
545
571
|
|
|
546
|
-
| Option | Description
|
|
547
|
-
| --------------------- |
|
|
548
|
-
| `<app-module>` | Module path whose **default export** is an Express app (sync, not async factory)
|
|
549
|
-
| `--init <path>` | Init hook module (default export, async function) called once per cold start
|
|
550
|
-
| `--out-dir <path>` | Output directory (default: `dist`)
|
|
551
|
-
| `--out-name <name>` | Output filename without extension (default: `handler`)
|
|
552
|
-
| `--format <cjs\|esm>` | Output format (default: `cjs`)
|
|
553
|
-
| `--target <target>` | Compilation target (default: `node22`)
|
|
554
|
-
| `--external <pkg>` | Mark package as external (repeatable; `express`
|
|
555
|
-
| `--no-clean` | Don't clean the output directory before building
|
|
572
|
+
| Option | Description |
|
|
573
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
574
|
+
| `<app-module>` | Module path whose **default export** is an Express app (sync, not async factory) |
|
|
575
|
+
| `--init <path>` | Init hook module (default export, async function) called once per cold start |
|
|
576
|
+
| `--out-dir <path>` | Output directory (default: `dist`) |
|
|
577
|
+
| `--out-name <name>` | Output filename without extension (default: `handler`) |
|
|
578
|
+
| `--format <cjs\|esm>` | Output format (default: `cjs`) |
|
|
579
|
+
| `--target <target>` | Compilation target (default: `node22`) |
|
|
580
|
+
| `--external <pkg>` | Mark package as external (repeatable; `express` and `@web-ts-toolkit/express-runtime` are always external) |
|
|
581
|
+
| `--no-clean` | Don't clean the output directory before building |
|
|
556
582
|
|
|
557
583
|
#### start-serverless options
|
|
558
584
|
|
|
@@ -562,7 +588,7 @@ Omitting `<command>` defaults to `dev` for backward compatibility.
|
|
|
562
588
|
| `--port <number>` | Port or named pipe (default: `process.env.PORT` or `8080`) |
|
|
563
589
|
| `--host <hostname>` | Hostname to bind (default: `process.env.HOST` or `0.0.0.0`) |
|
|
564
590
|
| `--no-signals` | Disable `SIGINT` / `SIGTERM` handler registration |
|
|
565
|
-
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`)
|
|
591
|
+
| `--shutdown-timeout <ms>` | Max ms to wait for in-flight requests (default: `5000`; `0..2147483647`) |
|
|
566
592
|
| `--max-body-bytes <bytes>` | Max request body bytes for adapter (default: `1048576`; `0` allows empty bodies only) |
|
|
567
593
|
| `--require <module>` | Module(s) to preload before handler load (repeatable; comma-separated values supported) |
|
|
568
594
|
| `--env <path>` | Env file(s) to load before handler load (repeatable; existing env vars are not overridden) |
|
|
@@ -578,8 +604,11 @@ Use `--` to stop option parsing when a positional module path starts with a
|
|
|
578
604
|
dash, for example `wtt-express-runtime dev -- --app.js`. Numeric CLI values are
|
|
579
605
|
validated before env files, preload modules, app modules, watchers, or servers
|
|
580
606
|
are opened. Ports must be canonical decimal integers in `0..65535` or explicit
|
|
581
|
-
nonnumeric named-pipe paths;
|
|
582
|
-
be finite integers in `0..
|
|
607
|
+
nonnumeric named-pipe paths; timer durations (`--shutdown-timeout`, `--delay`)
|
|
608
|
+
must be finite integers in `0..2147483647` (Node's `setTimeout` limit — larger
|
|
609
|
+
values are rejected instead of overflowing into near-immediate timers; `0`
|
|
610
|
+
means no wait and `2147483647` is the largest safe delay). Adapter body-limit
|
|
611
|
+
values (`--max-body-bytes`) keep the wider `0..9007199254740991` range.
|
|
583
612
|
|
|
584
613
|
The `dev` command sets `exitAfterShutdown: true` so `SIGINT` / `SIGTERM` cleanly
|
|
585
614
|
exit the process after the server drains. TypeScript app modules require a TS
|
|
@@ -594,9 +623,14 @@ starts.
|
|
|
594
623
|
The `build` command generates a temporary entry file that re-exports the app
|
|
595
624
|
module and optional `init` hook, then produces a local runtime bundle. The
|
|
596
625
|
`build-serverless` command instead wraps the app with `createServerlessHandler`
|
|
597
|
-
and bundles the serverless runtime. `express`
|
|
598
|
-
|
|
599
|
-
|
|
626
|
+
and bundles the serverless runtime. `express` and
|
|
627
|
+
`@web-ts-toolkit/express-runtime` (imported by the generated entry) are always
|
|
628
|
+
external; all other dependencies are bundled into the output unless marked
|
|
629
|
+
external via `--external`. Deploy the bundle with both mandatory externals
|
|
630
|
+
installed — `pnpm add express @web-ts-toolkit/express-runtime`
|
|
631
|
+
(`serverless-http` ships with the runtime package, so no extra install is
|
|
632
|
+
needed for it). A bundle executed without the runtime package installed fails
|
|
633
|
+
to load with a missing-module error for `@web-ts-toolkit/express-runtime`.
|
|
600
634
|
|
|
601
635
|
## License
|
|
602
636
|
|