@nextrush/core 3.0.6 → 4.0.0-beta.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 +322 -493
- package/dist/index.d.ts +193 -182
- package/dist/index.js +448 -296
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { Middleware, Context,
|
|
2
|
-
export { ContentType, Context, ContextState, HttpMethod, HttpStatus, HttpStatusCode, Middleware, Next,
|
|
3
|
-
export { BadRequestError, ForbiddenError, HttpError, InternalServerError, NextRushError, NotFoundError, UnauthorizedError
|
|
1
|
+
import { Logger, Router, Container, Middleware, RouteEntry, Context, Extension, Next } from '@nextrush/types';
|
|
2
|
+
export { ContentType, Context, ContextState, Extension, ExtensionContext, ExtensionHost, HttpMethod, HttpStatus, HttpStatusCode, Logger, Middleware, Next, QueryParams, RouteEntry, RouteHandler, RouteParams, Router } from '@nextrush/types';
|
|
3
|
+
export { BadRequestError, ForbiddenError, HttpError, InternalServerError, NextRushError, NotFoundError, UnauthorizedError } from '@nextrush/errors';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @nextrush/core - Application Class
|
|
7
7
|
*
|
|
8
8
|
* The Application class is the main entry point for NextRush.
|
|
9
|
-
* It manages middleware registration and
|
|
9
|
+
* It manages middleware registration and the extension lifecycle.
|
|
10
|
+
*
|
|
11
|
+
* See docs/RFC/class-runtime/005-plugin-system.md for the extension model.
|
|
10
12
|
*
|
|
11
13
|
* @packageDocumentation
|
|
12
14
|
*/
|
|
@@ -16,13 +18,21 @@ export { BadRequestError, ForbiddenError, HttpError, InternalServerError, NextRu
|
|
|
16
18
|
*/
|
|
17
19
|
type ErrorHandler = (error: Error, ctx: Context) => void | Promise<void>;
|
|
18
20
|
/**
|
|
19
|
-
*
|
|
21
|
+
* Options for {@link Application.close}.
|
|
22
|
+
*
|
|
23
|
+
* @see RFC-022 (`docs/RFC/class-runtime/022-bounded-teardown-lifecycle.md`) / ADR-0012.
|
|
20
24
|
*/
|
|
21
|
-
interface
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
interface CloseOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Bound, in milliseconds, on total teardown time. Every teardown unit
|
|
28
|
+
* (extension `destroy()`) races against this budget independently — a
|
|
29
|
+
* unit that does not finish in time is reported as a {@link TeardownTimeoutError}
|
|
30
|
+
* in the returned array, and never blocks `close()` past the budget.
|
|
31
|
+
*
|
|
32
|
+
* @remarks Omitted = unbounded, identical to calling `close()` with no
|
|
33
|
+
* arguments today (`Promise.allSettled`, no timeout).
|
|
34
|
+
*/
|
|
35
|
+
timeout?: number;
|
|
26
36
|
}
|
|
27
37
|
/**
|
|
28
38
|
* Application options
|
|
@@ -42,26 +52,31 @@ interface ApplicationOptions {
|
|
|
42
52
|
* Custom logger. Defaults to no-op (silent).
|
|
43
53
|
*
|
|
44
54
|
* @remarks
|
|
45
|
-
* Pass `console` for quick development logging
|
|
46
|
-
*
|
|
47
|
-
* const app = createApp({ logger: console });
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* For production, provide a structured logger (e.g. pino, winston)
|
|
51
|
-
* that implements the {@link Logger} interface.
|
|
52
|
-
*
|
|
53
|
-
* Adapters and internal hooks use `app.logger` — configuring it here
|
|
54
|
-
* ensures consistent logging across the framework.
|
|
55
|
+
* Pass `console` for quick development logging. For production, provide a
|
|
56
|
+
* structured logger (pino, winston, `@nextrush/logger`) implementing {@link Logger}.
|
|
55
57
|
*/
|
|
56
58
|
logger?: Logger;
|
|
59
|
+
/**
|
|
60
|
+
* A router the app owns. Route methods (`app.get`, `app.post`, …) delegate to
|
|
61
|
+
* it, and it is mounted last at `ready()`. The `nextrush` meta-package's
|
|
62
|
+
* `createApp` injects one automatically; pass it explicitly when using
|
|
63
|
+
* `@nextrush/core` directly.
|
|
64
|
+
*/
|
|
65
|
+
router?: Router;
|
|
66
|
+
/**
|
|
67
|
+
* A per-app DI container. Exposed to extensions via `ExtensionContext.container`
|
|
68
|
+
* and used by class-based registrars (e.g. `registerControllers`). Injected by
|
|
69
|
+
* `nextrush/class`; omitted for functional, DI-free apps.
|
|
70
|
+
*/
|
|
71
|
+
container?: Container;
|
|
57
72
|
}
|
|
58
73
|
/**
|
|
59
74
|
* Listener callback type
|
|
60
75
|
*/
|
|
61
76
|
type ListenCallback = () => void;
|
|
62
77
|
/**
|
|
63
|
-
* Routable interface - any object with routes() method
|
|
64
|
-
*
|
|
78
|
+
* Routable interface - any object with routes() method.
|
|
79
|
+
* Allows mounting Router instances without a circular dependency.
|
|
65
80
|
*/
|
|
66
81
|
interface Routable {
|
|
67
82
|
routes(): Middleware;
|
|
@@ -77,195 +92,173 @@ interface Routable {
|
|
|
77
92
|
* ctx.json({ message: 'Hello World' });
|
|
78
93
|
* });
|
|
79
94
|
*
|
|
80
|
-
* //
|
|
81
|
-
*
|
|
95
|
+
* // Extensions (rare — long-lived services) are booted at ready(), which
|
|
96
|
+
* // adapters call automatically before start().
|
|
97
|
+
* app.extend(events());
|
|
98
|
+
*
|
|
99
|
+
* listen(app, { port: 8080 });
|
|
82
100
|
* ```
|
|
83
101
|
*/
|
|
84
102
|
declare class Application {
|
|
85
|
-
/**
|
|
86
|
-
* Middleware stack
|
|
87
|
-
*/
|
|
103
|
+
/** Middleware stack */
|
|
88
104
|
private readonly middlewareStack;
|
|
105
|
+
/** Registered extensions, in registration order (setup runs at ready()) */
|
|
106
|
+
private readonly extensions;
|
|
107
|
+
/** Registered extension names — enforces uniqueness */
|
|
108
|
+
private readonly extensionNames;
|
|
89
109
|
/**
|
|
90
|
-
*
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
110
|
+
* Combined teardown-unit registration order: extension `destroy()`s and
|
|
111
|
+
* {@link onClose} hooks interleaved in the exact order they were registered,
|
|
112
|
+
* so `_shutdown()` can run the whole set in one reverse-of-registration pass
|
|
113
|
+
* (RFC-022 §7.3 — "teardown becomes a flat list of independently-isolated,
|
|
114
|
+
* budget-raced units"). Populated lazily by {@link extend} (for extensions
|
|
115
|
+
* declaring `destroy()`) and {@link onClose}.
|
|
95
116
|
*/
|
|
117
|
+
private readonly teardownUnits;
|
|
118
|
+
/** Whether {@link close} has started — {@link onClose} is a pre-shutdown-only registration point (RFC-022 §8.6). */
|
|
119
|
+
private _closeStarted;
|
|
120
|
+
/** Names decorated onto the app — enforces collision detection */
|
|
121
|
+
private readonly decorations;
|
|
122
|
+
/** Custom error handler */
|
|
96
123
|
private _errorHandler;
|
|
97
|
-
/**
|
|
98
|
-
* Pluggable logger
|
|
99
|
-
*/
|
|
124
|
+
/** Pluggable logger */
|
|
100
125
|
readonly logger: Logger;
|
|
101
|
-
/**
|
|
102
|
-
* Application options
|
|
103
|
-
*/
|
|
126
|
+
/** Application options */
|
|
104
127
|
readonly options: ApplicationOptions;
|
|
105
|
-
/**
|
|
106
|
-
* Whether the app is running
|
|
107
|
-
*/
|
|
128
|
+
/** Whether the app is running (server listening) */
|
|
108
129
|
private _isRunning;
|
|
130
|
+
/** Whether the app has been booted (extensions set up, config frozen) */
|
|
131
|
+
private _isReady;
|
|
132
|
+
/** Whether ready() mounted the app-owned router (so close() can undo it) */
|
|
133
|
+
private _routerMounted;
|
|
134
|
+
/** In-flight boot promise — memoized so concurrent ready() calls share one boot (H-1) */
|
|
135
|
+
private _readyPromise;
|
|
136
|
+
/** In-flight shutdown promise — memoized so concurrent close() calls share one (H-3) */
|
|
137
|
+
private _closePromise;
|
|
138
|
+
/** The app-owned router (optional). Route methods delegate to it. */
|
|
139
|
+
readonly router?: Router;
|
|
140
|
+
/** The app-owned DI container (optional). Exposed to extensions and registrars. */
|
|
141
|
+
readonly container?: Container;
|
|
109
142
|
constructor(options?: ApplicationOptions);
|
|
110
|
-
/**
|
|
111
|
-
* Check if running in production
|
|
112
|
-
*/
|
|
143
|
+
/** Check if running in production */
|
|
113
144
|
get isProduction(): boolean;
|
|
114
|
-
/**
|
|
115
|
-
* Check if app is running
|
|
116
|
-
*/
|
|
145
|
+
/** Check if app is running */
|
|
117
146
|
get isRunning(): boolean;
|
|
118
147
|
/**
|
|
119
|
-
*
|
|
148
|
+
* Whether a graceful shutdown is currently in progress — `true` from the
|
|
149
|
+
* moment {@link close} begins tearing down until it completes (F-12:
|
|
150
|
+
* shutdown observability, RFC-022). A readiness check or operator tooling
|
|
151
|
+
* can read this to reflect an in-progress drain.
|
|
120
152
|
*/
|
|
153
|
+
get isDraining(): boolean;
|
|
154
|
+
/** Check if app has been booted via ready() */
|
|
155
|
+
get isReady(): boolean;
|
|
156
|
+
/** Get middleware count */
|
|
121
157
|
get middlewareCount(): number;
|
|
158
|
+
/** Get registered extension count */
|
|
159
|
+
get extensionCount(): number;
|
|
122
160
|
/**
|
|
123
|
-
* Throws if the app is
|
|
124
|
-
* Prevents
|
|
161
|
+
* Throws if the app configuration is frozen (after ready() or start()).
|
|
162
|
+
* Prevents unsafe mutations once the app has booted or is serving traffic.
|
|
125
163
|
*/
|
|
126
|
-
private
|
|
164
|
+
private assertConfigurable;
|
|
127
165
|
/**
|
|
128
166
|
* Register middleware function(s)
|
|
129
167
|
*
|
|
130
|
-
* @param middleware - Middleware function
|
|
168
|
+
* @param middleware - Middleware function(s)
|
|
131
169
|
* @returns this for chaining
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```typescript
|
|
135
|
-
* // Single middleware
|
|
136
|
-
* app.use(async (ctx) => {
|
|
137
|
-
* console.log(ctx.method, ctx.path);
|
|
138
|
-
* await ctx.next();
|
|
139
|
-
* });
|
|
140
|
-
*
|
|
141
|
-
* // Multiple middleware
|
|
142
|
-
* app.use(cors(), helmet(), json());
|
|
143
|
-
* ```
|
|
144
170
|
*/
|
|
145
171
|
use(...middleware: Middleware[]): this;
|
|
146
172
|
/**
|
|
147
|
-
* Mount a router at a path prefix
|
|
148
|
-
*
|
|
149
|
-
* This is the Hono-style API for mounting routers directly on the app.
|
|
150
|
-
* The router's routes will only match requests that start with the given prefix.
|
|
173
|
+
* Mount a router at a path prefix.
|
|
151
174
|
*
|
|
152
|
-
* @param path - Path prefix
|
|
175
|
+
* @param path - Path prefix (e.g. '/api/users')
|
|
153
176
|
* @param router - Router instance to mount
|
|
154
177
|
* @returns this for chaining
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* // Create modular routers
|
|
159
|
-
* const users = createRouter();
|
|
160
|
-
* users.get('/', listUsers);
|
|
161
|
-
* users.get('/:id', getUser);
|
|
162
|
-
* users.post('/', createUser);
|
|
163
|
-
*
|
|
164
|
-
* const posts = createRouter();
|
|
165
|
-
* posts.get('/', listPosts);
|
|
166
|
-
* posts.get('/:id', getPost);
|
|
167
|
-
*
|
|
168
|
-
* // Mount directly on app - clean like Hono!
|
|
169
|
-
* const app = createApp();
|
|
170
|
-
* app.route('/api/users', users);
|
|
171
|
-
* app.route('/api/posts', posts);
|
|
172
|
-
*
|
|
173
|
-
* listen(app, 3000);
|
|
174
|
-
* ```
|
|
175
178
|
*/
|
|
176
179
|
route(path: string, router: Routable): this;
|
|
180
|
+
private requireRouter;
|
|
181
|
+
/** Register a GET route on the app-owned router. */
|
|
182
|
+
get(path: string, ...entries: RouteEntry[]): this;
|
|
183
|
+
/** Register a POST route on the app-owned router. */
|
|
184
|
+
post(path: string, ...entries: RouteEntry[]): this;
|
|
185
|
+
/** Register a PUT route on the app-owned router. */
|
|
186
|
+
put(path: string, ...entries: RouteEntry[]): this;
|
|
187
|
+
/** Register a PATCH route on the app-owned router. */
|
|
188
|
+
patch(path: string, ...entries: RouteEntry[]): this;
|
|
189
|
+
/** Register a DELETE route on the app-owned router. */
|
|
190
|
+
delete(path: string, ...entries: RouteEntry[]): this;
|
|
191
|
+
/** Register a HEAD route on the app-owned router. */
|
|
192
|
+
head(path: string, ...entries: RouteEntry[]): this;
|
|
177
193
|
/**
|
|
178
|
-
*
|
|
194
|
+
* Register a route for all HTTP methods on the app-owned router.
|
|
179
195
|
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
* @param handler - Error handler function
|
|
185
|
-
* @returns this for chaining
|
|
186
|
-
*
|
|
187
|
-
* @example
|
|
188
|
-
* ```typescript
|
|
189
|
-
* app.setErrorHandler((error, ctx) => {
|
|
190
|
-
* console.error('Request failed:', error);
|
|
191
|
-
*
|
|
192
|
-
* if (error instanceof ValidationError) {
|
|
193
|
-
* ctx.status = 400;
|
|
194
|
-
* ctx.json({ error: error.message, details: error.details });
|
|
195
|
-
* return;
|
|
196
|
-
* }
|
|
197
|
-
*
|
|
198
|
-
* ctx.status = 500;
|
|
199
|
-
* ctx.json({ error: 'Internal Server Error' });
|
|
200
|
-
* });
|
|
201
|
-
* ```
|
|
196
|
+
* @remarks
|
|
197
|
+
* There is intentionally no `app.options()` verb method — it would collide
|
|
198
|
+
* with the `app.options` configuration property. Register OPTIONS routes via
|
|
199
|
+
* `app.all()`, the router directly, or let CORS middleware handle preflight.
|
|
202
200
|
*/
|
|
203
|
-
|
|
201
|
+
all(path: string, ...entries: RouteEntry[]): this;
|
|
204
202
|
/**
|
|
205
|
-
* Set
|
|
203
|
+
* Set the application error handler. Replaces any previously set handler.
|
|
206
204
|
*
|
|
207
205
|
* @param handler - Error handler function
|
|
208
206
|
* @returns this for chaining
|
|
209
|
-
*
|
|
210
|
-
* @deprecated Use `setErrorHandler()` instead — `onError()` implies
|
|
211
|
-
* event subscription (additive), but this is a setter (replaces).
|
|
212
207
|
*/
|
|
213
|
-
|
|
208
|
+
setErrorHandler(handler: ErrorHandler): this;
|
|
214
209
|
/**
|
|
215
|
-
*
|
|
210
|
+
* Register an extension. Queues it — `setup()` runs later, at `ready()`,
|
|
211
|
+
* in registration order. Synchronous and chainable.
|
|
216
212
|
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* @returns this
|
|
213
|
+
* @param extension - Extension to register. If it declares a decorated
|
|
214
|
+
* shape via `Extension<TDecorated>`, the return type carries that shape —
|
|
215
|
+
* `app.extend(events<MyEvents>()).events` is statically known, no
|
|
216
|
+
* `declare module` augmentation required.
|
|
217
|
+
* @returns this, intersected with the extension's declared decorated shape
|
|
222
218
|
*
|
|
223
219
|
* @example
|
|
224
220
|
* ```typescript
|
|
225
|
-
*
|
|
226
|
-
* app.
|
|
227
|
-
*
|
|
228
|
-
* // Async plugin — just await it
|
|
229
|
-
* await app.plugin(databasePlugin({ uri: '...' }));
|
|
221
|
+
* const extended = app.extend(events<MyEvents>());
|
|
222
|
+
* await app.ready(); // adapters call this automatically — runs setup()/decorate()
|
|
223
|
+
* extended.events.emit('user:created', { id: '1' }); // available only AFTER ready()
|
|
230
224
|
* ```
|
|
231
225
|
*/
|
|
232
|
-
|
|
226
|
+
extend<TDecorated = Record<string, never>>(extension: Extension<TDecorated>): this & TDecorated;
|
|
233
227
|
/**
|
|
234
|
-
*
|
|
228
|
+
* Boot the application: run every registered extension's `setup()` once, in
|
|
229
|
+
* registration order, awaiting async setups. Idempotent — safe to call twice.
|
|
230
|
+
* Adapters call this automatically before `start()`.
|
|
235
231
|
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
232
|
+
* After `ready()` resolves, the configuration is frozen (`use`/`route`/`extend`
|
|
233
|
+
* throw).
|
|
238
234
|
*
|
|
239
|
-
* @
|
|
240
|
-
*
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
*
|
|
245
|
-
*
|
|
235
|
+
* @returns this
|
|
236
|
+
* @throws if an extension declares a `needs` dependency not yet registered
|
|
237
|
+
*/
|
|
238
|
+
ready(): Promise<this>;
|
|
239
|
+
/**
|
|
240
|
+
* Run the boot sequence once (extension setup + router mount). Guarded and
|
|
241
|
+
* memoized by {@link ready}.
|
|
246
242
|
*/
|
|
247
|
-
|
|
243
|
+
private _boot;
|
|
248
244
|
/**
|
|
249
|
-
*
|
|
245
|
+
* Attach a value to the app under `name`. Extension-author primitive, invoked
|
|
246
|
+
* through {@link ExtensionContext.decorate} — there is intentionally no public
|
|
247
|
+
* `app.decorate()` (RFC §6.1). Throws on collision.
|
|
250
248
|
*
|
|
251
|
-
* @
|
|
252
|
-
* @returns Plugin instance or undefined
|
|
249
|
+
* @internal
|
|
253
250
|
*/
|
|
254
|
-
|
|
251
|
+
private decorate;
|
|
255
252
|
/**
|
|
256
|
-
*
|
|
253
|
+
* Whether a decoration already occupies `name`.
|
|
257
254
|
*/
|
|
258
|
-
|
|
255
|
+
hasDecorator(name: string): boolean;
|
|
259
256
|
/**
|
|
260
|
-
* Create the request handler callback
|
|
261
|
-
*
|
|
262
|
-
* This is the function that adapters call to handle each request.
|
|
263
|
-
* It composes all middleware and returns a function that processes context.
|
|
257
|
+
* Create the request handler callback.
|
|
264
258
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* handler that includes subsequent registrations.
|
|
259
|
+
* The middleware stack is snapshot at call time — call `ready()` before
|
|
260
|
+
* `callback()` so extension-registered middleware is included. Adapters do
|
|
261
|
+
* this automatically.
|
|
269
262
|
*
|
|
270
263
|
* @returns Request handler function
|
|
271
264
|
*/
|
|
@@ -275,46 +268,58 @@ declare class Application {
|
|
|
275
268
|
*/
|
|
276
269
|
private handleError;
|
|
277
270
|
/**
|
|
278
|
-
* Default error handler
|
|
279
|
-
*
|
|
280
|
-
* Uses the `expose` flag on errors (set by HttpError/NextRushError)
|
|
281
|
-
* to decide whether to include the error message in the response.
|
|
282
|
-
* 4xx errors expose messages by default; 5xx errors never do.
|
|
283
|
-
* This prevents leaking internal details (paths, SQL, stack info)
|
|
284
|
-
* regardless of environment.
|
|
271
|
+
* Default error handler — delegates to the shared error serializer so the
|
|
272
|
+
* default response matches `@nextrush/errors`' `errorHandler()` (audit C-1).
|
|
285
273
|
*/
|
|
286
274
|
private defaultErrorHandler;
|
|
287
275
|
/**
|
|
288
276
|
* Mark app as running and freeze configuration.
|
|
289
277
|
*
|
|
290
|
-
* Called by adapters when the server starts listening
|
|
291
|
-
* `use()`, `route()`, `plugin()`, and `pluginAsync()` will throw.
|
|
292
|
-
* This prevents unsafe middleware mutations while requests are in flight.
|
|
293
|
-
*
|
|
294
|
-
* To re-enable registration (e.g. for testing), call `close()` first.
|
|
278
|
+
* Called by adapters when the server starts listening (after `ready()`).
|
|
295
279
|
*/
|
|
296
280
|
start(): void;
|
|
297
281
|
/**
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
282
|
+
* Register a teardown hook for a resource outside the extension system
|
|
283
|
+
* (stateful middleware, a manually-attached service, …). Run during
|
|
284
|
+
* {@link close} under the SAME bounded/isolated guarantee as extension
|
|
285
|
+
* `destroy()` — one throwing/hanging hook never strands the others — in one
|
|
286
|
+
* combined reverse-of-registration order together with every `extend()`ed
|
|
287
|
+
* extension's `destroy()` (RFC-022 §8.1/§8.2).
|
|
288
|
+
*
|
|
289
|
+
* @param hook - Teardown callback. May be sync or async; a thrown/rejected
|
|
290
|
+
* hook is isolated and its error collected in {@link close}'s returned array.
|
|
302
291
|
*
|
|
303
|
-
* @
|
|
292
|
+
* @remarks Registration is pre-shutdown only: a hook registered after
|
|
293
|
+
* `close()` has already started is not run in that shutdown (RFC-022 §8.6).
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* const store = new MemoryStore(options);
|
|
298
|
+
* app.onClose(() => store.shutdown());
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
onClose(hook: () => void | Promise<void>): void;
|
|
302
|
+
/**
|
|
303
|
+
* Graceful shutdown. Destroys extensions in reverse registration order,
|
|
304
|
+
* each isolated from the others' failures — one failing/hanging `destroy()`
|
|
305
|
+
* never strands the rest (RFC-022 / ADR-0012).
|
|
306
|
+
*
|
|
307
|
+
* @param options - Optional teardown budget. Omitted = unbounded, byte-identical
|
|
308
|
+
* to today's behavior (`Promise.allSettled`, no timeout). When `timeout` is
|
|
309
|
+
* given, every teardown unit races against it independently; a unit that
|
|
310
|
+
* does not finish in time is reported as a {@link TeardownTimeoutError} in
|
|
311
|
+
* the returned array instead of blocking `close()` past the budget.
|
|
312
|
+
* @returns Array of errors from units that failed or timed out (empty on success)
|
|
304
313
|
*/
|
|
305
|
-
close(): Promise<Error[]>;
|
|
314
|
+
close(options?: CloseOptions): Promise<Error[]>;
|
|
315
|
+
/** Run the shutdown sequence once. Guarded and memoized by {@link close}. */
|
|
316
|
+
private _shutdown;
|
|
306
317
|
}
|
|
307
318
|
/**
|
|
308
319
|
* Create a new Application instance
|
|
309
320
|
*
|
|
310
321
|
* @param options - Application options
|
|
311
322
|
* @returns New Application instance
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
* ```typescript
|
|
315
|
-
* const app = createApp();
|
|
316
|
-
* const app = createApp({ env: 'production' });
|
|
317
|
-
* ```
|
|
318
323
|
*/
|
|
319
324
|
declare function createApp(options?: ApplicationOptions): Application;
|
|
320
325
|
|
|
@@ -337,8 +342,14 @@ type ComposedMiddleware = (ctx: Context, next?: Next) => Promise<void>;
|
|
|
337
342
|
interface ComposeOptions {
|
|
338
343
|
/**
|
|
339
344
|
* Warn when a middleware sends a response AND calls next().
|
|
340
|
-
*
|
|
341
|
-
* @
|
|
345
|
+
*
|
|
346
|
+
* @remarks
|
|
347
|
+
* Opt-in and defaults to `false` — `@nextrush/core` is a runtime-agnostic
|
|
348
|
+
* package and must not read `process.env` (global-rules §2, audit C-4). The
|
|
349
|
+
* `Application` enables this in non-production by passing the flag from its
|
|
350
|
+
* own `env` option.
|
|
351
|
+
*
|
|
352
|
+
* @default false
|
|
342
353
|
*/
|
|
343
354
|
warnDoubleResponse?: boolean;
|
|
344
355
|
}
|
|
@@ -385,4 +396,4 @@ declare function isMiddleware(fn: unknown): fn is Middleware;
|
|
|
385
396
|
*/
|
|
386
397
|
declare function flattenMiddleware(arr: (Middleware | Middleware[])[]): Middleware[];
|
|
387
398
|
|
|
388
|
-
export { Application, type ApplicationOptions, type ComposeOptions, type ComposedMiddleware, type ErrorHandler, type ListenCallback, type
|
|
399
|
+
export { Application, type ApplicationOptions, type ComposeOptions, type ComposedMiddleware, type ErrorHandler, type ListenCallback, type Routable, compose, createApp, flattenMiddleware, isMiddleware };
|