@web-ts-toolkit/express-runtime 0.40.1 → 0.42.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 +246 -66
- package/chunk-UPFG3S34.mjs +1494 -0
- package/chunk-VPFBKM2K.mjs +487 -0
- package/cli-api.d.mts +133 -29
- package/cli-api.d.ts +133 -29
- package/cli-api.js +1150 -196
- package/cli-api.mjs +51 -771
- package/cli-utils-4POUMJN7.mjs +69 -0
- package/cli.js +1143 -195
- package/index.d.mts +74 -33
- package/index.d.ts +74 -33
- package/index.js +314 -47
- package/index.mjs +7 -3
- package/package.json +12 -3
- package/chunk-SOW7OLVN.mjs +0 -221
package/cli-api.d.mts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { LocalServerOptions, LocalServer } from './index.mjs';
|
|
2
|
+
import { watch, existsSync } from 'node:fs';
|
|
3
|
+
import { ChildProcess, fork } from 'node:child_process';
|
|
4
|
+
import { Response, Request, Express } from 'express';
|
|
3
5
|
import 'node:http';
|
|
4
6
|
import 'serverless-http';
|
|
5
7
|
|
|
8
|
+
declare const CLI_VERSION: string;
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
declare const CLI_VERSION = "0.0.0-PLACEHOLDER";
|
|
10
|
-
/**
|
|
11
|
-
* Read the next argv value after a flag, throwing if it is missing or looks
|
|
12
|
-
* like another flag.
|
|
10
|
+
* Read the next argv value after a flag, throwing if it is missing, empty, or
|
|
11
|
+
* looks like another flag.
|
|
13
12
|
*/
|
|
14
13
|
declare function readValue(argv: string[], index: number, name: string): string;
|
|
15
14
|
type Subcommand = 'dev' | 'build' | 'start' | 'build-serverless' | 'start-serverless';
|
|
@@ -42,7 +41,6 @@ interface BuildArgs {
|
|
|
42
41
|
}
|
|
43
42
|
interface BuildEntryContentArgs {
|
|
44
43
|
entryContent: string;
|
|
45
|
-
tempEntryFilename: string;
|
|
46
44
|
tsconfigPath?: string;
|
|
47
45
|
outDir: string;
|
|
48
46
|
outName: string;
|
|
@@ -62,6 +60,8 @@ interface StartArgs {
|
|
|
62
60
|
interface StartServerlessArgs {
|
|
63
61
|
handlerPath: string;
|
|
64
62
|
options: Omit<LocalServerOptions, 'init' | 'onShutdown'>;
|
|
63
|
+
/** Maximum bytes to buffer for request bodies via the local adapter. Default: 1048576. */
|
|
64
|
+
maxBodyBytes?: number;
|
|
65
65
|
/** Modules to preload before loading the handler (repeatable `--require`). */
|
|
66
66
|
require: string[];
|
|
67
67
|
/** Env files to load before loading the handler (repeatable `--env`). */
|
|
@@ -107,7 +107,8 @@ declare function loadApp(appPath: string): Promise<Express>;
|
|
|
107
107
|
* Parse env file content as KEY=VALUE lines. Supports `export` prefix,
|
|
108
108
|
* single/double-quoted values, and `#` comments. Returns parsed entries.
|
|
109
109
|
*
|
|
110
|
-
*
|
|
110
|
+
* Public helper for packages that reuse the CLI's env-file parsing without
|
|
111
|
+
* shelling out to the binary.
|
|
111
112
|
*/
|
|
112
113
|
declare function parseEnvFile(content: string): Record<string, string>;
|
|
113
114
|
/**
|
|
@@ -115,7 +116,8 @@ declare function parseEnvFile(content: string): Record<string, string>;
|
|
|
115
116
|
* **not** overridden (consistent with dotenv's default behavior). Missing
|
|
116
117
|
* files throw with a friendly message.
|
|
117
118
|
*
|
|
118
|
-
*
|
|
119
|
+
* Public helper for programmatic CLI integrations. Mutates `process.env` by
|
|
120
|
+
* design and never overwrites existing environment variables.
|
|
119
121
|
*/
|
|
120
122
|
declare function loadEnvFiles(paths: string[]): void;
|
|
121
123
|
/**
|
|
@@ -123,38 +125,90 @@ declare function loadEnvFiles(paths: string[]): void;
|
|
|
123
125
|
* loading the app module. Each module is `require()`-ed, running its
|
|
124
126
|
* side effects (registering hooks, loading configs, etc.).
|
|
125
127
|
*
|
|
126
|
-
*
|
|
128
|
+
* Public helper for programmatic CLI integrations that need the same preload
|
|
129
|
+
* behavior as the binary before loading an app or handler module.
|
|
127
130
|
*/
|
|
128
131
|
declare function preloadModules(modules: string[]): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Dependencies for watch supervision, injectable for tests.
|
|
134
|
+
* Not part of the documented public API; exposed for deterministic testing
|
|
135
|
+
* without expanding the supported consumer contract.
|
|
136
|
+
*/
|
|
137
|
+
interface WatchSupervisorDeps {
|
|
138
|
+
fork?: typeof fork;
|
|
139
|
+
watch?: typeof watch;
|
|
140
|
+
existsSync?: typeof existsSync;
|
|
141
|
+
logger?: Pick<Console, 'error'>;
|
|
142
|
+
killTimeoutMs?: number;
|
|
143
|
+
setTimeout?: typeof setTimeout;
|
|
144
|
+
clearTimeout?: typeof clearTimeout;
|
|
145
|
+
exit?: (code: number) => void;
|
|
146
|
+
installSignalHandlers?: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Controller returned by the injectable supervisor factory.
|
|
150
|
+
* Allows tests to observe and deterministically shut down watchers/children.
|
|
151
|
+
*/
|
|
152
|
+
interface WatchSupervisorController {
|
|
153
|
+
/** Stop watching and terminate child, idempotent. */
|
|
154
|
+
shutdown: () => Promise<void>;
|
|
155
|
+
/** Currently tracked child, if any. */
|
|
156
|
+
getChild: () => ChildProcess | null;
|
|
157
|
+
/** Active watchers (FSWatcher handles). */
|
|
158
|
+
getWatchers: () => ReturnType<typeof watch>[];
|
|
159
|
+
/** Whether shutdown has been initiated. */
|
|
160
|
+
isShuttingDown: () => boolean;
|
|
161
|
+
}
|
|
129
162
|
/**
|
|
130
163
|
* Reconstruct the argv for the child process, stripping --watch/--ext/--delay
|
|
131
164
|
* flags (the child runs without watch mode).
|
|
132
165
|
*
|
|
133
|
-
*
|
|
166
|
+
* Public helper for CLI wrappers that supervise watch mode themselves and need
|
|
167
|
+
* the same child argv reconstruction as `runWithWatch`.
|
|
134
168
|
*/
|
|
135
169
|
declare function buildChildArgs(args: DevArgs): string[];
|
|
136
170
|
/**
|
|
137
171
|
* Run the CLI in watch mode. Forks a child process running the same CLI
|
|
138
172
|
* without --watch, watches the specified paths for file changes, and
|
|
139
|
-
* restarts the child (SIGTERM
|
|
140
|
-
* extensions. Uses Node 20+'s `fs.watch` with
|
|
173
|
+
* restarts the child (SIGTERM, then SIGKILL after 5 seconds) on changes
|
|
174
|
+
* matching the given extensions. Uses Node 20+'s `fs.watch` with
|
|
175
|
+
* `{ recursive: true }`.
|
|
176
|
+
*
|
|
177
|
+
* Production entry point that delegates to `createWatchSupervisor` with real
|
|
178
|
+
* dependencies and installs signal handlers that exit the process.
|
|
141
179
|
*/
|
|
142
|
-
declare function runWithWatch(args: DevArgs):
|
|
180
|
+
declare function runWithWatch(args: DevArgs, deps?: WatchSupervisorDeps): WatchSupervisorController;
|
|
181
|
+
/** Legacy fixed staging filenames — no longer written, but retained for regression tests that verify they are not overwritten. */
|
|
182
|
+
declare const TEMP_BUILD_ENTRY_FILENAME = ".express-runtime-build-entry.ts";
|
|
183
|
+
declare const TEMP_SERVERLESS_ENTRY_FILENAME = ".express-runtime-build-serverless-entry.ts";
|
|
143
184
|
type RuntimeModuleInit = () => Promise<void> | void;
|
|
185
|
+
type RuntimeModuleShutdown = () => Promise<void> | void;
|
|
144
186
|
/**
|
|
145
187
|
* Generate the temporary entry file content that wires the user's app and
|
|
146
188
|
* optional init hook into a serverless handler.
|
|
147
189
|
*
|
|
148
|
-
*
|
|
190
|
+
* Public build-entry generator used by programmatic CLI integrations.
|
|
149
191
|
*/
|
|
150
192
|
declare function generateServerlessEntry(appPath: string, initPath?: string): string;
|
|
151
193
|
/**
|
|
152
194
|
* Generate the temporary entry file content that wires the user's app and
|
|
153
195
|
* optional init hook into a local runtime bundle.
|
|
154
196
|
*
|
|
155
|
-
*
|
|
197
|
+
* Public build-entry generator used by programmatic CLI integrations.
|
|
156
198
|
*/
|
|
157
199
|
declare function generateRuntimeEntry(appPath: string, initPath?: string): string;
|
|
200
|
+
/**
|
|
201
|
+
* Validate that `outDir` is safe to clean before invoking tsup.
|
|
202
|
+
* Prevents destructive `clean: true` combinations:
|
|
203
|
+
* - filesystem root
|
|
204
|
+
* - project cwd itself (repository root)
|
|
205
|
+
* - symlinked output directories
|
|
206
|
+
* - output that contains input files (appPath/initPath)
|
|
207
|
+
*
|
|
208
|
+
* Public safety check for programmatic build integrations before invoking
|
|
209
|
+
* `buildBundleFromEntryContent()` with `clean: true`.
|
|
210
|
+
*/
|
|
211
|
+
declare function validateOutDirForClean(outDir: string, clean: boolean, appPath?: string, initPath?: string): void;
|
|
158
212
|
declare function buildBundleFromEntryContent(args: BuildEntryContentArgs): Promise<void>;
|
|
159
213
|
/**
|
|
160
214
|
* Bundle an Express app as a local runtime module. The output default-exports
|
|
@@ -175,25 +229,70 @@ declare function buildServerless(args: BuildArgs): Promise<void>;
|
|
|
175
229
|
* `build-serverless`).
|
|
176
230
|
*/
|
|
177
231
|
type GenericHandler = (event: unknown, context: unknown) => Promise<unknown>;
|
|
232
|
+
/** AWS API Gateway REST API v1 / Lambda proxy event shape emitted by the local adapter. */
|
|
233
|
+
interface ApiGatewayRestEvent {
|
|
234
|
+
httpMethod: string;
|
|
235
|
+
path: string;
|
|
236
|
+
headers: Record<string, string>;
|
|
237
|
+
multiValueHeaders: Record<string, string[]>;
|
|
238
|
+
queryStringParameters: Record<string, string> | null;
|
|
239
|
+
multiValueQueryStringParameters: Record<string, string[]> | null;
|
|
240
|
+
body: string;
|
|
241
|
+
isBase64Encoded: boolean;
|
|
242
|
+
requestContext: {
|
|
243
|
+
identity: {
|
|
244
|
+
sourceIp: string;
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
}
|
|
178
248
|
/**
|
|
179
|
-
*
|
|
249
|
+
* AWS API Gateway REST API v1 / Lambda proxy result shape returned by `serverless-http`.
|
|
180
250
|
*/
|
|
181
251
|
interface ServerlessResult {
|
|
182
252
|
statusCode?: number;
|
|
183
|
-
headers?: Record<string, string |
|
|
253
|
+
headers?: Record<string, string | undefined>;
|
|
254
|
+
multiValueHeaders?: Record<string, string[] | undefined>;
|
|
184
255
|
body?: string;
|
|
185
256
|
isBase64Encoded?: boolean;
|
|
186
257
|
}
|
|
258
|
+
declare const DEFAULT_ADAPTER_MAX_BODY_BYTES: number;
|
|
259
|
+
interface ServerlessAdapterOptions {
|
|
260
|
+
/**
|
|
261
|
+
* Maximum bytes to buffer for a single request body.
|
|
262
|
+
* Default: 1048576 (1 MiB). Must be a finite non-negative integer.
|
|
263
|
+
* When `0`, no body is allowed — any non-empty body receives `413`.
|
|
264
|
+
* The adapter never retains more than this limit plus at most one incoming chunk.
|
|
265
|
+
*/
|
|
266
|
+
maxBodyBytes?: number;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Validate `maxBodyBytes` — finite non-negative integer. Zero means no body allowed (empty bodies only).
|
|
270
|
+
* Public validator shared by CLI parsing and programmatic adapter callers.
|
|
271
|
+
*/
|
|
272
|
+
declare function validateMaxBodyBytes(value: unknown): number;
|
|
273
|
+
/**
|
|
274
|
+
* Read the raw request body into a Buffer with bounded memory.
|
|
275
|
+
* Since `createExpressApp` is called with `json: false, urlencoded: false` in the adapter,
|
|
276
|
+
* no body parser has consumed the stream yet. Rejects oversized declared or incremental
|
|
277
|
+
* bodies with a `LIMIT_EXCEEDED` error (413), stops retaining chunks after the limit,
|
|
278
|
+
* removes owned listeners, and drains the request.
|
|
279
|
+
* Distinguishes client aborts (`CLIENT_ABORT`) and stream errors from oversize.
|
|
280
|
+
*/
|
|
281
|
+
declare function collectBody(req: Request, maxBytes: number): Promise<Buffer>;
|
|
187
282
|
/**
|
|
188
|
-
* Build
|
|
283
|
+
* Build an AWS API Gateway REST API v1 / Lambda proxy event from HTTP request components.
|
|
189
284
|
*
|
|
190
|
-
*
|
|
285
|
+
* Public helper for adapters that need the same AWS REST API v1 event shape as
|
|
286
|
+
* the `start-serverless` command.
|
|
191
287
|
*/
|
|
192
|
-
declare function toServerlessEvent(method: string, url: string, headers: Record<string, string | string[] | undefined>, body: Buffer):
|
|
288
|
+
declare function toServerlessEvent(method: string, url: string, headers: Record<string, string | string[] | undefined>, body: Buffer): ApiGatewayRestEvent;
|
|
193
289
|
/**
|
|
194
290
|
* Write a serverless handler result to an Express response.
|
|
291
|
+
* Validates the complete AWS API Gateway REST API v1 / Lambda proxy result before writing anything.
|
|
292
|
+
* `multiValueHeaders` wins over `headers` when the same header appears in both maps.
|
|
195
293
|
*
|
|
196
|
-
*
|
|
294
|
+
* Public helper for adapters that need the same AWS REST API v1 result-to-HTTP
|
|
295
|
+
* translation as the `start-serverless` command.
|
|
197
296
|
*/
|
|
198
297
|
declare function applyServerlessResult(result: unknown, res: Response): void;
|
|
199
298
|
/**
|
|
@@ -204,14 +303,18 @@ declare function applyServerlessResult(result: unknown, res: Response): void;
|
|
|
204
303
|
* Express body parsers are disabled; the raw request body is read directly
|
|
205
304
|
* from the stream and passed as a Buffer (so the serverless handler's request
|
|
206
305
|
* hook — including the #305 workaround — works identically to production).
|
|
306
|
+
* Bodies exceeding `maxBodyBytes` (default 1 MiB, 0 = empty bodies only) receive
|
|
307
|
+
* `413 Payload Too Large` without invoking the handler; the request is drained
|
|
308
|
+
* and retained memory is bounded to the limit plus at most one chunk.
|
|
207
309
|
*/
|
|
208
|
-
declare function createServerlessAdapterApp(handler: GenericHandler): Express;
|
|
310
|
+
declare function createServerlessAdapterApp(handler: GenericHandler, options?: ServerlessAdapterOptions): Express;
|
|
209
311
|
/**
|
|
210
312
|
* Load a bundled app module from the `build` output.
|
|
211
313
|
*/
|
|
212
314
|
declare function loadBuiltApp(appPath: string): Promise<{
|
|
213
315
|
app: Express;
|
|
214
316
|
init?: RuntimeModuleInit;
|
|
317
|
+
shutdown?: RuntimeModuleShutdown;
|
|
215
318
|
}>;
|
|
216
319
|
/**
|
|
217
320
|
* Load a bundled serverless handler from a JS/CJS module. The module must
|
|
@@ -224,12 +327,13 @@ interface DevCommandRunner<TLoaded> {
|
|
|
224
327
|
load: (appPath: string) => Promise<TLoaded> | TLoaded;
|
|
225
328
|
start: (loaded: TLoaded, options: DevArgs['options'] & {
|
|
226
329
|
exitAfterShutdown: true;
|
|
227
|
-
}) => void;
|
|
228
|
-
watch?: (args: DevArgs) => void;
|
|
330
|
+
}) => LocalServer | void;
|
|
331
|
+
watch?: (args: DevArgs) => void | WatchSupervisorController;
|
|
229
332
|
}
|
|
230
333
|
interface BuildEntryCommandOptions {
|
|
231
334
|
generateEntry: (appPath: string, initPath?: string) => string;
|
|
232
|
-
|
|
335
|
+
/** @deprecated staging is now uniquely created; this is ignored if provided */
|
|
336
|
+
tempEntryFilename?: string;
|
|
233
337
|
allowInit?: boolean;
|
|
234
338
|
initErrorMessage?: string;
|
|
235
339
|
}
|
|
@@ -238,4 +342,4 @@ declare function runExpressDevCommand(args: DevArgs): Promise<void>;
|
|
|
238
342
|
declare function runBuildEntryCommand(args: BuildArgs, options: BuildEntryCommandOptions): Promise<void>;
|
|
239
343
|
declare function runCliCommand(parsedArgs: RuntimeCliCommand): Promise<void>;
|
|
240
344
|
|
|
241
|
-
export { type BuildArgs, type BuildEntryCommandOptions, type BuildEntryContentArgs, CLI_VERSION, type DevArgs, type DevCommandRunner, type GenericHandler, type ParsedArgs, type RuntimeCliCommand, type RuntimeModuleInit, type ServerlessResult, type StartArgs, type StartServerlessArgs, type Subcommand, applyServerlessResult, buildBundleFromEntryContent, buildChildArgs, buildRuntime, buildServerless, createServerlessAdapterApp, extractExport, generateRuntimeEntry, generateServerlessEntry, isExpressApp, loadApp, loadBuiltApp, loadEnvFiles, loadHandler, parseArgs, parseEnvFile, preloadModules, printHelp, readValue, resolveExport, runBuildEntryCommand, runCliCommand, runDevCommand, runExpressDevCommand, runWithWatch, toServerlessEvent };
|
|
345
|
+
export { type ApiGatewayRestEvent, type BuildArgs, type BuildEntryCommandOptions, type BuildEntryContentArgs, CLI_VERSION, DEFAULT_ADAPTER_MAX_BODY_BYTES, type DevArgs, type DevCommandRunner, type GenericHandler, type ParsedArgs, type RuntimeCliCommand, type RuntimeModuleInit, type RuntimeModuleShutdown, type ServerlessAdapterOptions, type ServerlessResult, type StartArgs, type StartServerlessArgs, type Subcommand, TEMP_BUILD_ENTRY_FILENAME, TEMP_SERVERLESS_ENTRY_FILENAME, applyServerlessResult, buildBundleFromEntryContent, buildChildArgs, buildRuntime, buildServerless, collectBody, createServerlessAdapterApp, extractExport, generateRuntimeEntry, generateServerlessEntry, isExpressApp, loadApp, loadBuiltApp, loadEnvFiles, loadHandler, parseArgs, parseEnvFile, preloadModules, printHelp, readValue, resolveExport, runBuildEntryCommand, runCliCommand, runDevCommand, runExpressDevCommand, runWithWatch, toServerlessEvent, validateMaxBodyBytes, validateOutDirForClean };
|
package/cli-api.d.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { LocalServerOptions, LocalServer } from './index.js';
|
|
2
|
+
import { watch, existsSync } from 'node:fs';
|
|
3
|
+
import { ChildProcess, fork } from 'node:child_process';
|
|
4
|
+
import { Response, Request, Express } from 'express';
|
|
3
5
|
import 'node:http';
|
|
4
6
|
import 'serverless-http';
|
|
5
7
|
|
|
8
|
+
declare const CLI_VERSION: string;
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
declare const CLI_VERSION = "0.0.0-PLACEHOLDER";
|
|
10
|
-
/**
|
|
11
|
-
* Read the next argv value after a flag, throwing if it is missing or looks
|
|
12
|
-
* like another flag.
|
|
10
|
+
* Read the next argv value after a flag, throwing if it is missing, empty, or
|
|
11
|
+
* looks like another flag.
|
|
13
12
|
*/
|
|
14
13
|
declare function readValue(argv: string[], index: number, name: string): string;
|
|
15
14
|
type Subcommand = 'dev' | 'build' | 'start' | 'build-serverless' | 'start-serverless';
|
|
@@ -42,7 +41,6 @@ interface BuildArgs {
|
|
|
42
41
|
}
|
|
43
42
|
interface BuildEntryContentArgs {
|
|
44
43
|
entryContent: string;
|
|
45
|
-
tempEntryFilename: string;
|
|
46
44
|
tsconfigPath?: string;
|
|
47
45
|
outDir: string;
|
|
48
46
|
outName: string;
|
|
@@ -62,6 +60,8 @@ interface StartArgs {
|
|
|
62
60
|
interface StartServerlessArgs {
|
|
63
61
|
handlerPath: string;
|
|
64
62
|
options: Omit<LocalServerOptions, 'init' | 'onShutdown'>;
|
|
63
|
+
/** Maximum bytes to buffer for request bodies via the local adapter. Default: 1048576. */
|
|
64
|
+
maxBodyBytes?: number;
|
|
65
65
|
/** Modules to preload before loading the handler (repeatable `--require`). */
|
|
66
66
|
require: string[];
|
|
67
67
|
/** Env files to load before loading the handler (repeatable `--env`). */
|
|
@@ -107,7 +107,8 @@ declare function loadApp(appPath: string): Promise<Express>;
|
|
|
107
107
|
* Parse env file content as KEY=VALUE lines. Supports `export` prefix,
|
|
108
108
|
* single/double-quoted values, and `#` comments. Returns parsed entries.
|
|
109
109
|
*
|
|
110
|
-
*
|
|
110
|
+
* Public helper for packages that reuse the CLI's env-file parsing without
|
|
111
|
+
* shelling out to the binary.
|
|
111
112
|
*/
|
|
112
113
|
declare function parseEnvFile(content: string): Record<string, string>;
|
|
113
114
|
/**
|
|
@@ -115,7 +116,8 @@ declare function parseEnvFile(content: string): Record<string, string>;
|
|
|
115
116
|
* **not** overridden (consistent with dotenv's default behavior). Missing
|
|
116
117
|
* files throw with a friendly message.
|
|
117
118
|
*
|
|
118
|
-
*
|
|
119
|
+
* Public helper for programmatic CLI integrations. Mutates `process.env` by
|
|
120
|
+
* design and never overwrites existing environment variables.
|
|
119
121
|
*/
|
|
120
122
|
declare function loadEnvFiles(paths: string[]): void;
|
|
121
123
|
/**
|
|
@@ -123,38 +125,90 @@ declare function loadEnvFiles(paths: string[]): void;
|
|
|
123
125
|
* loading the app module. Each module is `require()`-ed, running its
|
|
124
126
|
* side effects (registering hooks, loading configs, etc.).
|
|
125
127
|
*
|
|
126
|
-
*
|
|
128
|
+
* Public helper for programmatic CLI integrations that need the same preload
|
|
129
|
+
* behavior as the binary before loading an app or handler module.
|
|
127
130
|
*/
|
|
128
131
|
declare function preloadModules(modules: string[]): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Dependencies for watch supervision, injectable for tests.
|
|
134
|
+
* Not part of the documented public API; exposed for deterministic testing
|
|
135
|
+
* without expanding the supported consumer contract.
|
|
136
|
+
*/
|
|
137
|
+
interface WatchSupervisorDeps {
|
|
138
|
+
fork?: typeof fork;
|
|
139
|
+
watch?: typeof watch;
|
|
140
|
+
existsSync?: typeof existsSync;
|
|
141
|
+
logger?: Pick<Console, 'error'>;
|
|
142
|
+
killTimeoutMs?: number;
|
|
143
|
+
setTimeout?: typeof setTimeout;
|
|
144
|
+
clearTimeout?: typeof clearTimeout;
|
|
145
|
+
exit?: (code: number) => void;
|
|
146
|
+
installSignalHandlers?: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Controller returned by the injectable supervisor factory.
|
|
150
|
+
* Allows tests to observe and deterministically shut down watchers/children.
|
|
151
|
+
*/
|
|
152
|
+
interface WatchSupervisorController {
|
|
153
|
+
/** Stop watching and terminate child, idempotent. */
|
|
154
|
+
shutdown: () => Promise<void>;
|
|
155
|
+
/** Currently tracked child, if any. */
|
|
156
|
+
getChild: () => ChildProcess | null;
|
|
157
|
+
/** Active watchers (FSWatcher handles). */
|
|
158
|
+
getWatchers: () => ReturnType<typeof watch>[];
|
|
159
|
+
/** Whether shutdown has been initiated. */
|
|
160
|
+
isShuttingDown: () => boolean;
|
|
161
|
+
}
|
|
129
162
|
/**
|
|
130
163
|
* Reconstruct the argv for the child process, stripping --watch/--ext/--delay
|
|
131
164
|
* flags (the child runs without watch mode).
|
|
132
165
|
*
|
|
133
|
-
*
|
|
166
|
+
* Public helper for CLI wrappers that supervise watch mode themselves and need
|
|
167
|
+
* the same child argv reconstruction as `runWithWatch`.
|
|
134
168
|
*/
|
|
135
169
|
declare function buildChildArgs(args: DevArgs): string[];
|
|
136
170
|
/**
|
|
137
171
|
* Run the CLI in watch mode. Forks a child process running the same CLI
|
|
138
172
|
* without --watch, watches the specified paths for file changes, and
|
|
139
|
-
* restarts the child (SIGTERM
|
|
140
|
-
* extensions. Uses Node 20+'s `fs.watch` with
|
|
173
|
+
* restarts the child (SIGTERM, then SIGKILL after 5 seconds) on changes
|
|
174
|
+
* matching the given extensions. Uses Node 20+'s `fs.watch` with
|
|
175
|
+
* `{ recursive: true }`.
|
|
176
|
+
*
|
|
177
|
+
* Production entry point that delegates to `createWatchSupervisor` with real
|
|
178
|
+
* dependencies and installs signal handlers that exit the process.
|
|
141
179
|
*/
|
|
142
|
-
declare function runWithWatch(args: DevArgs):
|
|
180
|
+
declare function runWithWatch(args: DevArgs, deps?: WatchSupervisorDeps): WatchSupervisorController;
|
|
181
|
+
/** Legacy fixed staging filenames — no longer written, but retained for regression tests that verify they are not overwritten. */
|
|
182
|
+
declare const TEMP_BUILD_ENTRY_FILENAME = ".express-runtime-build-entry.ts";
|
|
183
|
+
declare const TEMP_SERVERLESS_ENTRY_FILENAME = ".express-runtime-build-serverless-entry.ts";
|
|
143
184
|
type RuntimeModuleInit = () => Promise<void> | void;
|
|
185
|
+
type RuntimeModuleShutdown = () => Promise<void> | void;
|
|
144
186
|
/**
|
|
145
187
|
* Generate the temporary entry file content that wires the user's app and
|
|
146
188
|
* optional init hook into a serverless handler.
|
|
147
189
|
*
|
|
148
|
-
*
|
|
190
|
+
* Public build-entry generator used by programmatic CLI integrations.
|
|
149
191
|
*/
|
|
150
192
|
declare function generateServerlessEntry(appPath: string, initPath?: string): string;
|
|
151
193
|
/**
|
|
152
194
|
* Generate the temporary entry file content that wires the user's app and
|
|
153
195
|
* optional init hook into a local runtime bundle.
|
|
154
196
|
*
|
|
155
|
-
*
|
|
197
|
+
* Public build-entry generator used by programmatic CLI integrations.
|
|
156
198
|
*/
|
|
157
199
|
declare function generateRuntimeEntry(appPath: string, initPath?: string): string;
|
|
200
|
+
/**
|
|
201
|
+
* Validate that `outDir` is safe to clean before invoking tsup.
|
|
202
|
+
* Prevents destructive `clean: true` combinations:
|
|
203
|
+
* - filesystem root
|
|
204
|
+
* - project cwd itself (repository root)
|
|
205
|
+
* - symlinked output directories
|
|
206
|
+
* - output that contains input files (appPath/initPath)
|
|
207
|
+
*
|
|
208
|
+
* Public safety check for programmatic build integrations before invoking
|
|
209
|
+
* `buildBundleFromEntryContent()` with `clean: true`.
|
|
210
|
+
*/
|
|
211
|
+
declare function validateOutDirForClean(outDir: string, clean: boolean, appPath?: string, initPath?: string): void;
|
|
158
212
|
declare function buildBundleFromEntryContent(args: BuildEntryContentArgs): Promise<void>;
|
|
159
213
|
/**
|
|
160
214
|
* Bundle an Express app as a local runtime module. The output default-exports
|
|
@@ -175,25 +229,70 @@ declare function buildServerless(args: BuildArgs): Promise<void>;
|
|
|
175
229
|
* `build-serverless`).
|
|
176
230
|
*/
|
|
177
231
|
type GenericHandler = (event: unknown, context: unknown) => Promise<unknown>;
|
|
232
|
+
/** AWS API Gateway REST API v1 / Lambda proxy event shape emitted by the local adapter. */
|
|
233
|
+
interface ApiGatewayRestEvent {
|
|
234
|
+
httpMethod: string;
|
|
235
|
+
path: string;
|
|
236
|
+
headers: Record<string, string>;
|
|
237
|
+
multiValueHeaders: Record<string, string[]>;
|
|
238
|
+
queryStringParameters: Record<string, string> | null;
|
|
239
|
+
multiValueQueryStringParameters: Record<string, string[]> | null;
|
|
240
|
+
body: string;
|
|
241
|
+
isBase64Encoded: boolean;
|
|
242
|
+
requestContext: {
|
|
243
|
+
identity: {
|
|
244
|
+
sourceIp: string;
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
}
|
|
178
248
|
/**
|
|
179
|
-
*
|
|
249
|
+
* AWS API Gateway REST API v1 / Lambda proxy result shape returned by `serverless-http`.
|
|
180
250
|
*/
|
|
181
251
|
interface ServerlessResult {
|
|
182
252
|
statusCode?: number;
|
|
183
|
-
headers?: Record<string, string |
|
|
253
|
+
headers?: Record<string, string | undefined>;
|
|
254
|
+
multiValueHeaders?: Record<string, string[] | undefined>;
|
|
184
255
|
body?: string;
|
|
185
256
|
isBase64Encoded?: boolean;
|
|
186
257
|
}
|
|
258
|
+
declare const DEFAULT_ADAPTER_MAX_BODY_BYTES: number;
|
|
259
|
+
interface ServerlessAdapterOptions {
|
|
260
|
+
/**
|
|
261
|
+
* Maximum bytes to buffer for a single request body.
|
|
262
|
+
* Default: 1048576 (1 MiB). Must be a finite non-negative integer.
|
|
263
|
+
* When `0`, no body is allowed — any non-empty body receives `413`.
|
|
264
|
+
* The adapter never retains more than this limit plus at most one incoming chunk.
|
|
265
|
+
*/
|
|
266
|
+
maxBodyBytes?: number;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Validate `maxBodyBytes` — finite non-negative integer. Zero means no body allowed (empty bodies only).
|
|
270
|
+
* Public validator shared by CLI parsing and programmatic adapter callers.
|
|
271
|
+
*/
|
|
272
|
+
declare function validateMaxBodyBytes(value: unknown): number;
|
|
273
|
+
/**
|
|
274
|
+
* Read the raw request body into a Buffer with bounded memory.
|
|
275
|
+
* Since `createExpressApp` is called with `json: false, urlencoded: false` in the adapter,
|
|
276
|
+
* no body parser has consumed the stream yet. Rejects oversized declared or incremental
|
|
277
|
+
* bodies with a `LIMIT_EXCEEDED` error (413), stops retaining chunks after the limit,
|
|
278
|
+
* removes owned listeners, and drains the request.
|
|
279
|
+
* Distinguishes client aborts (`CLIENT_ABORT`) and stream errors from oversize.
|
|
280
|
+
*/
|
|
281
|
+
declare function collectBody(req: Request, maxBytes: number): Promise<Buffer>;
|
|
187
282
|
/**
|
|
188
|
-
* Build
|
|
283
|
+
* Build an AWS API Gateway REST API v1 / Lambda proxy event from HTTP request components.
|
|
189
284
|
*
|
|
190
|
-
*
|
|
285
|
+
* Public helper for adapters that need the same AWS REST API v1 event shape as
|
|
286
|
+
* the `start-serverless` command.
|
|
191
287
|
*/
|
|
192
|
-
declare function toServerlessEvent(method: string, url: string, headers: Record<string, string | string[] | undefined>, body: Buffer):
|
|
288
|
+
declare function toServerlessEvent(method: string, url: string, headers: Record<string, string | string[] | undefined>, body: Buffer): ApiGatewayRestEvent;
|
|
193
289
|
/**
|
|
194
290
|
* Write a serverless handler result to an Express response.
|
|
291
|
+
* Validates the complete AWS API Gateway REST API v1 / Lambda proxy result before writing anything.
|
|
292
|
+
* `multiValueHeaders` wins over `headers` when the same header appears in both maps.
|
|
195
293
|
*
|
|
196
|
-
*
|
|
294
|
+
* Public helper for adapters that need the same AWS REST API v1 result-to-HTTP
|
|
295
|
+
* translation as the `start-serverless` command.
|
|
197
296
|
*/
|
|
198
297
|
declare function applyServerlessResult(result: unknown, res: Response): void;
|
|
199
298
|
/**
|
|
@@ -204,14 +303,18 @@ declare function applyServerlessResult(result: unknown, res: Response): void;
|
|
|
204
303
|
* Express body parsers are disabled; the raw request body is read directly
|
|
205
304
|
* from the stream and passed as a Buffer (so the serverless handler's request
|
|
206
305
|
* hook — including the #305 workaround — works identically to production).
|
|
306
|
+
* Bodies exceeding `maxBodyBytes` (default 1 MiB, 0 = empty bodies only) receive
|
|
307
|
+
* `413 Payload Too Large` without invoking the handler; the request is drained
|
|
308
|
+
* and retained memory is bounded to the limit plus at most one chunk.
|
|
207
309
|
*/
|
|
208
|
-
declare function createServerlessAdapterApp(handler: GenericHandler): Express;
|
|
310
|
+
declare function createServerlessAdapterApp(handler: GenericHandler, options?: ServerlessAdapterOptions): Express;
|
|
209
311
|
/**
|
|
210
312
|
* Load a bundled app module from the `build` output.
|
|
211
313
|
*/
|
|
212
314
|
declare function loadBuiltApp(appPath: string): Promise<{
|
|
213
315
|
app: Express;
|
|
214
316
|
init?: RuntimeModuleInit;
|
|
317
|
+
shutdown?: RuntimeModuleShutdown;
|
|
215
318
|
}>;
|
|
216
319
|
/**
|
|
217
320
|
* Load a bundled serverless handler from a JS/CJS module. The module must
|
|
@@ -224,12 +327,13 @@ interface DevCommandRunner<TLoaded> {
|
|
|
224
327
|
load: (appPath: string) => Promise<TLoaded> | TLoaded;
|
|
225
328
|
start: (loaded: TLoaded, options: DevArgs['options'] & {
|
|
226
329
|
exitAfterShutdown: true;
|
|
227
|
-
}) => void;
|
|
228
|
-
watch?: (args: DevArgs) => void;
|
|
330
|
+
}) => LocalServer | void;
|
|
331
|
+
watch?: (args: DevArgs) => void | WatchSupervisorController;
|
|
229
332
|
}
|
|
230
333
|
interface BuildEntryCommandOptions {
|
|
231
334
|
generateEntry: (appPath: string, initPath?: string) => string;
|
|
232
|
-
|
|
335
|
+
/** @deprecated staging is now uniquely created; this is ignored if provided */
|
|
336
|
+
tempEntryFilename?: string;
|
|
233
337
|
allowInit?: boolean;
|
|
234
338
|
initErrorMessage?: string;
|
|
235
339
|
}
|
|
@@ -238,4 +342,4 @@ declare function runExpressDevCommand(args: DevArgs): Promise<void>;
|
|
|
238
342
|
declare function runBuildEntryCommand(args: BuildArgs, options: BuildEntryCommandOptions): Promise<void>;
|
|
239
343
|
declare function runCliCommand(parsedArgs: RuntimeCliCommand): Promise<void>;
|
|
240
344
|
|
|
241
|
-
export { type BuildArgs, type BuildEntryCommandOptions, type BuildEntryContentArgs, CLI_VERSION, type DevArgs, type DevCommandRunner, type GenericHandler, type ParsedArgs, type RuntimeCliCommand, type RuntimeModuleInit, type ServerlessResult, type StartArgs, type StartServerlessArgs, type Subcommand, applyServerlessResult, buildBundleFromEntryContent, buildChildArgs, buildRuntime, buildServerless, createServerlessAdapterApp, extractExport, generateRuntimeEntry, generateServerlessEntry, isExpressApp, loadApp, loadBuiltApp, loadEnvFiles, loadHandler, parseArgs, parseEnvFile, preloadModules, printHelp, readValue, resolveExport, runBuildEntryCommand, runCliCommand, runDevCommand, runExpressDevCommand, runWithWatch, toServerlessEvent };
|
|
345
|
+
export { type ApiGatewayRestEvent, type BuildArgs, type BuildEntryCommandOptions, type BuildEntryContentArgs, CLI_VERSION, DEFAULT_ADAPTER_MAX_BODY_BYTES, type DevArgs, type DevCommandRunner, type GenericHandler, type ParsedArgs, type RuntimeCliCommand, type RuntimeModuleInit, type RuntimeModuleShutdown, type ServerlessAdapterOptions, type ServerlessResult, type StartArgs, type StartServerlessArgs, type Subcommand, TEMP_BUILD_ENTRY_FILENAME, TEMP_SERVERLESS_ENTRY_FILENAME, applyServerlessResult, buildBundleFromEntryContent, buildChildArgs, buildRuntime, buildServerless, collectBody, createServerlessAdapterApp, extractExport, generateRuntimeEntry, generateServerlessEntry, isExpressApp, loadApp, loadBuiltApp, loadEnvFiles, loadHandler, parseArgs, parseEnvFile, preloadModules, printHelp, readValue, resolveExport, runBuildEntryCommand, runCliCommand, runDevCommand, runExpressDevCommand, runWithWatch, toServerlessEvent, validateMaxBodyBytes, validateOutDirForClean };
|