express-fastify-runtime 0.1.1 → 0.1.3
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/changelog/log-2026-06-25.md +38 -0
- package/changelog/log-2026-06-26.md +54 -0
- package/dist/app/compile.d.ts +6 -0
- package/dist/app/compile.d.ts.map +1 -1
- package/dist/app/compile.js +51 -17
- package/dist/app/compile.js.map +1 -1
- package/dist/app/flattenRouter.d.ts +17 -1
- package/dist/app/flattenRouter.d.ts.map +1 -1
- package/dist/app/flattenRouter.js +41 -3
- package/dist/app/flattenRouter.js.map +1 -1
- package/dist/app/introspectExpress.d.ts +6 -0
- package/dist/app/introspectExpress.d.ts.map +1 -1
- package/dist/app/introspectExpress.js +13 -0
- package/dist/app/introspectExpress.js.map +1 -1
- package/dist/fastify/adapters/define.d.ts +24 -0
- package/dist/fastify/adapters/define.d.ts.map +1 -0
- package/dist/fastify/adapters/define.js +52 -0
- package/dist/fastify/adapters/define.js.map +1 -0
- package/dist/fastify/adapters/request.d.ts.map +1 -1
- package/dist/fastify/adapters/request.js +24 -44
- package/dist/fastify/adapters/request.js.map +1 -1
- package/dist/fastify/adapters/response.js +4 -4
- package/dist/fastify/adapters/response.js.map +1 -1
- package/dist/fastify/register.d.ts +13 -0
- package/dist/fastify/register.d.ts.map +1 -1
- package/dist/fastify/register.js +28 -0
- package/dist/fastify/register.js.map +1 -1
- package/dist/runtime/fast.d.ts.map +1 -1
- package/dist/runtime/fast.js +9 -3
- package/dist/runtime/fast.js.map +1 -1
- package/dist/runtime/lifecycle.d.ts.map +1 -1
- package/dist/runtime/lifecycle.js +3 -0
- package/dist/runtime/lifecycle.js.map +1 -1
- package/dist/runtime/routingOptions.d.ts +16 -0
- package/dist/runtime/routingOptions.d.ts.map +1 -0
- package/dist/runtime/routingOptions.js +31 -0
- package/dist/runtime/routingOptions.js.map +1 -0
- package/dist/utils/detect.d.ts.map +1 -1
- package/dist/utils/detect.js +5 -0
- package/dist/utils/detect.js.map +1 -1
- package/dist/utils/expressPath.d.ts +24 -0
- package/dist/utils/expressPath.d.ts.map +1 -0
- package/dist/utils/expressPath.js +47 -0
- package/dist/utils/expressPath.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# 2026-06-25
|
|
2
2
|
|
|
3
|
+
## Stability: the Fastify-lane adapter is now a fully-mutable Express object
|
|
4
|
+
|
|
5
|
+
Root cause behind a recurring class of "middleware breaks on the Fastify lane" bugs (read-only
|
|
6
|
+
`req.body` 500, etc.): the adapter reimplements Express's `req`/`res`, and several Express
|
|
7
|
+
properties were **read-only getters**. When middleware assigns them — trust-proxy rewriting
|
|
8
|
+
`req.ip`/`req.protocol`/`req.hostname`, cookie-parser setting `req.cookies`, host rewriting,
|
|
9
|
+
caching middleware — the assignment **threw in strict mode or was silently dropped**.
|
|
10
|
+
|
|
11
|
+
- **Fix** (`src/fastify/adapters/define.ts` + `request.ts`): `defineWritable()` installs accessors
|
|
12
|
+
whose `set` shadows the getter with a per-instance own property (concurrency-safe). Applied to
|
|
13
|
+
`protocol`, `ip`, `ips`, `hostname`, `host`, `cookies`, `signedCookies` (memoized — also a small
|
|
14
|
+
speedup vs recomputing every read) and `method`, `headers`, `path`, `secure`, `fresh`, `stale`
|
|
15
|
+
(kept live, since they derive from other mutable props — `path`←`url`, `secure`←`protocol`).
|
|
16
|
+
Custom props (`req.user`) already worked (objects are extensible). `response.ts` was already
|
|
17
|
+
fine (`locals`/`statusCode` have setters; `headersSent`/`finished` correctly read-only).
|
|
18
|
+
- **Design**: deliberately kept on the **Fastify lane** (no "run real Express on the fast lane"
|
|
19
|
+
rewrite — that would have been slower). Property-mutating middleware now stay fast; only
|
|
20
|
+
body-stream middleware (multer, urlencoded/raw/text) remain the intentional Express-lane fallback.
|
|
21
|
+
- **Verified**: new `test/integration/req-mutation.test.js` (mutations stick, derived getters stay
|
|
22
|
+
live, per-request isolation under concurrency); full suite green on Express 4 (71) and 5 (69 + 2
|
|
23
|
+
skip); benchmark unchanged (Plain JSON 1.34× Express, middleware 1.21× Fastify).
|
|
24
|
+
|
|
25
|
+
## Fix: empty JSON body 400'd ("Body cannot be empty…") — now matches express.json()
|
|
26
|
+
|
|
27
|
+
Reported by a consumer: bodyless requests sent with `Content-Type: application/json` (common from
|
|
28
|
+
axios on POST/PUT/DELETE with no payload) failed with
|
|
29
|
+
`FST_ERR_CTP_EMPTY_JSON_BODY` — "Body cannot be empty when content-type is set to 'application/json'".
|
|
30
|
+
|
|
31
|
+
- **Cause.** `express.json()` tolerates an empty body and sets `req.body = {}`; Fastify's default
|
|
32
|
+
`application/json` parser rejects it with 400. Because `fast()` maps Express's JSON parsing onto
|
|
33
|
+
Fastify's native parser, it inherited the stricter behavior — 400'ing requests that work on plain
|
|
34
|
+
Express.
|
|
35
|
+
- **Fix** (`src/fastify/register.ts` `installExpressJsonParser`, wired into `runtime/fast.ts` and
|
|
36
|
+
`runtime/lifecycle.ts`): override Fastify's JSON content-type parser to behave like Express —
|
|
37
|
+
empty/whitespace body → `{}`, otherwise `JSON.parse` (malformed JSON still → 400, as on Express).
|
|
38
|
+
- **Test**: `test/integration/middleware-parity.test.js` now asserts empty body → 200 `{}`, valid
|
|
39
|
+
body → parsed, malformed JSON → 400.
|
|
40
|
+
|
|
3
41
|
## Fix: writes (POST/PUT with a JSON body) 500'd on the Express-lane fallback (Express 4)
|
|
4
42
|
|
|
5
43
|
Reported by a consumer (Express 4): reads worked, but every request with a JSON body returned
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 2026-06-26
|
|
2
|
+
|
|
3
|
+
## Feature: full Express routing-paradigm coverage on fast()
|
|
4
|
+
|
|
5
|
+
Paths were previously passed to Fastify verbatim and several routing features were unhandled. A
|
|
6
|
+
survey (run on Express 4 and 5) found gaps; all are now addressed — high-value ones on the Fastify
|
|
7
|
+
lane, rarer/complex ones via a correct Express-lane fallback. None can crash startup anymore.
|
|
8
|
+
|
|
9
|
+
- **Wildcards (fast lane).** New `src/utils/expressPath.ts` translates Express wildcard paths to
|
|
10
|
+
Fastify's (`/files/*`, Express 5 `/files/*splat` → Fastify `/files/*`) and bridges the captured
|
|
11
|
+
value back to where Express handlers read it (`req.params[0]` on v4, `req.params.splat` on v5).
|
|
12
|
+
Fixes a **startup crash** on Express 5's named wildcards and a silent "wildcard value lost" bug.
|
|
13
|
+
- **Never crash (fast lane).** `fastify.route()` registration is wrapped in try/catch — any path
|
|
14
|
+
Fastify rejects is left on the Express lane instead of taking down boot.
|
|
15
|
+
- **`next('route')` / `next('router')` (Express lane).** Detected in handler source
|
|
16
|
+
(`utils/detect.ts`) → run on real Express, which implements the skip semantics (no more 500).
|
|
17
|
+
- **`app.param(name, fn)` (Express lane).** `introspectExpress.ts` reads registered param names;
|
|
18
|
+
routes using such a param run on real Express so the callbacks fire.
|
|
19
|
+
- **Mounted sub-apps (Express lane).** `app.use('/x', express())` is detected (`isExpressApp` in
|
|
20
|
+
`flattenRouter.ts`) and runs as a unit on real Express; siblings still compile.
|
|
21
|
+
- **`case sensitive routing` / `strict routing` (fast lane).** `runtime/routingOptions.ts` reads the
|
|
22
|
+
app's settings and sets Fastify's `routerOptions.caseSensitive` / `ignoreTrailingSlash`. Also fixes
|
|
23
|
+
a prior parity bug — fast() was case-SENSITIVE by default while Express is case-INSENSITIVE; now
|
|
24
|
+
`/Foo` matches `/foo` and trailing slashes are tolerated, matching Express defaults.
|
|
25
|
+
- **Test.** `test/integration/routing-paradigms.test.js` covers all of the above on Express 4 and 5;
|
|
26
|
+
verified end-to-end under bun. Full suite green: Express 4 (79) and 5 (77 + 2 skip).
|
|
27
|
+
|
|
28
|
+
## Fix: one un-flattenable router no longer sinks the whole app to the Express lane
|
|
29
|
+
|
|
30
|
+
Reported by a real consumer (Express 4, 49 routers, run under bun): `fast()` logged
|
|
31
|
+
`No routes compiled to Fastify lane (all requests will use Express lane)` and the entire app ran on
|
|
32
|
+
the embedded Express — no Fastify speedup, and every prior body bug was actually on the Express lane.
|
|
33
|
+
|
|
34
|
+
- **Cause.** `flattenRouter` (`src/app/flattenRouter.ts`) returned `null` for the whole app as soon
|
|
35
|
+
as **any** single layer couldn't be flattened, and that `null` propagated to the root, so
|
|
36
|
+
`introspectExpressApp` compiled **zero** routes. The trigger was a single sub-router using an
|
|
37
|
+
**array mount path** — `router.use(['/suppression','/watchlist'], …)` — which has no string
|
|
38
|
+
`_path`; that one router sank all 49.
|
|
39
|
+
- **Fix.** Localize the fallback: a sub-router that can't be flattened (array/RegExp mount, or one
|
|
40
|
+
containing such a middleware) is now left on the **Express lane as a unit** — its routes fall
|
|
41
|
+
through to the real Express app with their full middleware chain (auth/guards) intact — while every
|
|
42
|
+
sibling router still compiles onto the **Fastify lane**. We still bail (for the current router
|
|
43
|
+
only) on a middleware *function* whose path we can't read, since we can't know which routes it
|
|
44
|
+
guards — never risk silently dropping a guard.
|
|
45
|
+
- **Not a bun bug.** Verified the Layer patch lands correctly under bun (string mounts get `_path`);
|
|
46
|
+
the abort was purely the flatten logic. No patch change needed.
|
|
47
|
+
- **Test.** `test/integration/partial-flatten.test.js`: array- and RegExp-mount sub-routers fall back
|
|
48
|
+
while siblings serve on the Fastify lane, and the fallback router's guard middleware still runs
|
|
49
|
+
(401 without key / 200 with). Green on Express 4 and 5; verified end-to-end under bun.
|
|
50
|
+
- **Docs.** The `No routes compiled …` startup message and the `res.render` hints now link the full
|
|
51
|
+
`FAST_PRODUCTION_CHECKLIST.md` URL instead of a bare repo-relative path.
|
|
52
|
+
|
|
53
|
+
Immediate consumer workaround (no upgrade needed): split an array mount into separate string mounts —
|
|
54
|
+
`router.use('/suppression', …)` + `router.use('/watchlist', …)`.
|
package/dist/app/compile.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ import type { ResponseAdapter } from "../types/internal";
|
|
|
11
11
|
export type RunMiddleware = (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => void | Promise<void>;
|
|
12
12
|
export interface RegisterFastifyRoutesOptions {
|
|
13
13
|
diagnostics?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Param names that have `app.param(name, fn)` callbacks registered. Routes whose path uses one of
|
|
16
|
+
* these params are left on the Express lane so the param callbacks actually run (we don't
|
|
17
|
+
* reimplement app.param on the Fastify lane). See runtime/fast.ts / introspectExpress.ts.
|
|
18
|
+
*/
|
|
19
|
+
paramNames?: ReadonlySet<string>;
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
16
22
|
* Register compiled Fastify routes (safe route entries only).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/app/compile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,YAAY,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/app/compile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,YAAY,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,YAAY,KACf,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAyG1B,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAClC;AASD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,eAAe,EAAE,EAC7B,YAAY,EAAE,cAAc,EAC5B,aAAa,EAAE,eAAe,EAC9B,cAAc,EAAE,aAAa,EAC7B,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAwGN"}
|
package/dist/app/compile.js
CHANGED
|
@@ -9,6 +9,7 @@ exports.registerFastifyRoutes = registerFastifyRoutes;
|
|
|
9
9
|
const path_1 = require("../utils/path");
|
|
10
10
|
const maxListeners_1 = require("../utils/maxListeners");
|
|
11
11
|
const middleware_1 = require("../express/middleware");
|
|
12
|
+
const expressPath_1 = require("../utils/expressPath");
|
|
12
13
|
/** Path prefix match: middleware at /api applies to /api, /api/users, etc. */
|
|
13
14
|
function pathMatches(middlewarePath, routePath) {
|
|
14
15
|
const m = (0, path_1.normalizePath)(middlewarePath);
|
|
@@ -112,6 +113,13 @@ function collectApplicableMiddleware(routePath, classified, routeIndex) {
|
|
|
112
113
|
}
|
|
113
114
|
return applicable;
|
|
114
115
|
}
|
|
116
|
+
/** Path segments like ":id" → "id"; used to skip routes that depend on app.param() callbacks. */
|
|
117
|
+
function routeParamNames(path) {
|
|
118
|
+
const out = [];
|
|
119
|
+
for (const m of path.matchAll(/:([A-Za-z_$][\w$]*)/g))
|
|
120
|
+
out.push(m[1]);
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
115
123
|
/**
|
|
116
124
|
* Register compiled Fastify routes (safe route entries only).
|
|
117
125
|
*
|
|
@@ -148,10 +156,20 @@ function registerFastifyRoutes(fastify, classified, adaptRequest, adaptResponse,
|
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
const routeEntries = classified.filter((c) => c.type === "route" && c.lane === "fastify");
|
|
159
|
+
const paramNames = options?.paramNames;
|
|
151
160
|
for (const entry of routeEntries) {
|
|
152
161
|
if (entry.type !== "route")
|
|
153
162
|
continue;
|
|
154
163
|
const path = (0, path_1.normalizePath)(entry.path);
|
|
164
|
+
// app.param(): a route using a param that has a registered callback runs on the Express lane.
|
|
165
|
+
if (paramNames && paramNames.size > 0 && routeParamNames(path).some((n) => paramNames.has(n))) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
// Translate Express path syntax → Fastify (wildcards). null = untranslatable → Express lane.
|
|
169
|
+
const fastifyPath = (0, expressPath_1.toFastifyPath)(path);
|
|
170
|
+
if (fastifyPath === null)
|
|
171
|
+
continue;
|
|
172
|
+
const wildcardKey = fastifyPath.wildcard;
|
|
155
173
|
// baseUrl is constant per route — compute once at registration, not per request.
|
|
156
174
|
const baseUrlSegments = path.split("/").filter(Boolean);
|
|
157
175
|
const baseUrl = baseUrlSegments.length >= 1 ? "/" + baseUrlSegments[0] : "";
|
|
@@ -172,23 +190,39 @@ function registerFastifyRoutes(fastify, classified, adaptRequest, adaptResponse,
|
|
|
172
190
|
const logLane = diagnostics
|
|
173
191
|
? (request) => console.log(`[express-fastify-runtime] Fastify lane: ${m} ${request.url ?? path}`)
|
|
174
192
|
: null;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
logLane
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
193
|
+
try {
|
|
194
|
+
fastify.route({
|
|
195
|
+
method: m,
|
|
196
|
+
url: fastifyPath.url,
|
|
197
|
+
handler: (request, reply) => {
|
|
198
|
+
if (logLane)
|
|
199
|
+
logLane(request);
|
|
200
|
+
(0, maxListeners_1.applyMaxListeners)(request.raw, reply.raw);
|
|
201
|
+
// Bridge a wildcard: Fastify stores it as params['*']; Express handlers read params[0]
|
|
202
|
+
// (v4) or params.<name> (v5). Set the Express key so handlers find the value.
|
|
203
|
+
if (wildcardKey !== null) {
|
|
204
|
+
const rp = request.params;
|
|
205
|
+
if (rp && rp["*"] !== undefined)
|
|
206
|
+
rp[wildcardKey] = rp["*"];
|
|
207
|
+
}
|
|
208
|
+
const req = adaptRequest(request);
|
|
209
|
+
const res = adaptResponse(reply, request);
|
|
210
|
+
res.req = req;
|
|
211
|
+
req.baseUrl = baseUrl;
|
|
212
|
+
if (fastSingle !== null) {
|
|
213
|
+
return fastSingle(req, res, noopNext);
|
|
214
|
+
}
|
|
215
|
+
return run(chain, req, res);
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
// Fastify rejected this path (exotic syntax we didn't translate). Never crash boot — leave
|
|
221
|
+
// the route on the Express lane (it falls through to the real Express app), and surface why.
|
|
222
|
+
if (diagnostics) {
|
|
223
|
+
console.log(`[express-fastify-runtime] Route ${m} ${path} left on the Express lane (Fastify rejected the path): ${err.message}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
192
226
|
}
|
|
193
227
|
}
|
|
194
228
|
}
|
package/dist/app/compile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/app/compile.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/app/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,12 +40,28 @@ export interface ExpressRouteLike {
|
|
|
40
40
|
* Returns true if the value looks like an Express Router (has stack array).
|
|
41
41
|
*/
|
|
42
42
|
export declare function isExpressRouter(value: unknown): value is ExpressRouterLike;
|
|
43
|
+
/**
|
|
44
|
+
* Returns true if the value looks like a mounted Express sub-app (`app.use('/x', express())`).
|
|
45
|
+
* A sub-app is a function with its own settings/router but no top-level `.stack` (its stack lives on
|
|
46
|
+
* `app._router`). We don't flatten sub-apps (they have their own settings/init); they run on the
|
|
47
|
+
* Express lane as a unit.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isExpressApp(value: unknown): boolean;
|
|
43
50
|
/**
|
|
44
51
|
* Flatten a Router into RouteEntry[] when possible.
|
|
45
52
|
* - Route layers (router.get/post etc.) are always flattened when we have route.path.
|
|
46
53
|
* - Middleware layers (router.use) are flattened when we have the path (from Layer._path patch or slash).
|
|
47
54
|
* - Nested routers are flattened recursively.
|
|
48
|
-
*
|
|
55
|
+
*
|
|
56
|
+
* Resilient fallback (so ONE un-flattenable router never sinks the whole app):
|
|
57
|
+
* - A nested router we can't flatten (or one mounted with a RegExp/array path) is SKIPPED here and
|
|
58
|
+
* left on the Express lane as a unit — its routes fall through to the real Express app via the
|
|
59
|
+
* notFoundHandler, where the full middleware chain (auth, etc.) still runs. Sibling routers keep
|
|
60
|
+
* compiling onto the Fastify lane.
|
|
61
|
+
* - A *middleware function* whose path we can't read is the one case we still bail on (return null
|
|
62
|
+
* for the CURRENT router only): we can't tell which routes it guards, so we can't safely compile
|
|
63
|
+
* any of this router's routes without risking dropping that middleware. The caller (a parent
|
|
64
|
+
* router, or fast()) then keeps this whole router on the Express lane but continues with siblings.
|
|
49
65
|
*/
|
|
50
66
|
export declare function flattenRouter(router: ExpressRouterLike, mountPath: string): RouteEntry[] | null;
|
|
51
67
|
//# sourceMappingURL=flattenRouter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flattenRouter.d.ts","sourceRoot":"","sources":["../../src/app/flattenRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAoBvD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,0GAA0G;AAC1G,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;wDAEoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,CAAC;IAC3C,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CAC1E;AAID;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAI1E;AAYD
|
|
1
|
+
{"version":3,"file":"flattenRouter.d.ts","sourceRoot":"","sources":["../../src/app/flattenRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAoBvD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,0GAA0G;AAC1G,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;wDAEoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,CAAC;IAC3C,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CAC1E;AAID;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAI1E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpD;AAYD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CAkF/F"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.isExpressRouter = isExpressRouter;
|
|
12
|
+
exports.isExpressApp = isExpressApp;
|
|
12
13
|
exports.flattenRouter = flattenRouter;
|
|
13
14
|
const expressLane_1 = require("../runtime/expressLane");
|
|
14
15
|
const middleware_1 = require("../express/middleware");
|
|
@@ -37,6 +38,20 @@ function isExpressRouter(value) {
|
|
|
37
38
|
const obj = value;
|
|
38
39
|
return Array.isArray(obj.stack);
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the value looks like a mounted Express sub-app (`app.use('/x', express())`).
|
|
43
|
+
* A sub-app is a function with its own settings/router but no top-level `.stack` (its stack lives on
|
|
44
|
+
* `app._router`). We don't flatten sub-apps (they have their own settings/init); they run on the
|
|
45
|
+
* Express lane as a unit.
|
|
46
|
+
*/
|
|
47
|
+
function isExpressApp(value) {
|
|
48
|
+
if (value == null || typeof value !== 'function')
|
|
49
|
+
return false;
|
|
50
|
+
const obj = value;
|
|
51
|
+
if (Array.isArray(obj.stack))
|
|
52
|
+
return false; // that's a Router, handled separately
|
|
53
|
+
return typeof obj.handle === 'function' && (obj._router != null || typeof obj.set === 'function');
|
|
54
|
+
}
|
|
40
55
|
/**
|
|
41
56
|
* Get the path for a middleware layer. Uses _path (from our patch), or '/' when slash is true.
|
|
42
57
|
*/
|
|
@@ -53,7 +68,16 @@ function getMiddlewareLayerPath(layer) {
|
|
|
53
68
|
* - Route layers (router.get/post etc.) are always flattened when we have route.path.
|
|
54
69
|
* - Middleware layers (router.use) are flattened when we have the path (from Layer._path patch or slash).
|
|
55
70
|
* - Nested routers are flattened recursively.
|
|
56
|
-
*
|
|
71
|
+
*
|
|
72
|
+
* Resilient fallback (so ONE un-flattenable router never sinks the whole app):
|
|
73
|
+
* - A nested router we can't flatten (or one mounted with a RegExp/array path) is SKIPPED here and
|
|
74
|
+
* left on the Express lane as a unit — its routes fall through to the real Express app via the
|
|
75
|
+
* notFoundHandler, where the full middleware chain (auth, etc.) still runs. Sibling routers keep
|
|
76
|
+
* compiling onto the Fastify lane.
|
|
77
|
+
* - A *middleware function* whose path we can't read is the one case we still bail on (return null
|
|
78
|
+
* for the CURRENT router only): we can't tell which routes it guards, so we can't safely compile
|
|
79
|
+
* any of this router's routes without risking dropping that middleware. The caller (a parent
|
|
80
|
+
* router, or fast()) then keeps this whole router on the Express lane but continues with siblings.
|
|
57
81
|
*/
|
|
58
82
|
function flattenRouter(router, mountPath) {
|
|
59
83
|
const stack = router.stack;
|
|
@@ -101,16 +125,30 @@ function flattenRouter(router, mountPath) {
|
|
|
101
125
|
const builtinName = layer.name || (typeof handle === 'function' ? handle.name : '');
|
|
102
126
|
if (builtinName === 'query' || builtinName === 'expressInit')
|
|
103
127
|
continue;
|
|
128
|
+
// Mounted sub-app (app.use('/x', express())): it has its own settings/init — don't flatten it;
|
|
129
|
+
// leave it on the Express lane as a unit (its routes fall through to the real Express app).
|
|
130
|
+
if (isExpressApp(handle))
|
|
131
|
+
continue;
|
|
104
132
|
const middlewarePath = getMiddlewareLayerPath(layer);
|
|
105
|
-
if (middlewarePath === null)
|
|
133
|
+
if (middlewarePath === null) {
|
|
134
|
+
// Path unreadable: array/RegExp mount, or an unpatched Layer. If it's a router, leave just
|
|
135
|
+
// that router on the Express lane and keep compiling siblings. If it's a middleware function,
|
|
136
|
+
// we don't know which routes it guards — fall back the CURRENT router only (return null), so
|
|
137
|
+
// we never silently compile a route without a guard middleware that should apply to it.
|
|
138
|
+
if (isExpressRouter(handle))
|
|
139
|
+
continue;
|
|
106
140
|
return null;
|
|
141
|
+
}
|
|
107
142
|
if ((0, expressLane_1.isExpressLaneHandler)(handle))
|
|
108
143
|
continue;
|
|
109
144
|
const fullPath = (0, path_1.joinPath)(mountPath, middlewarePath);
|
|
110
145
|
if (isExpressRouter(handle)) {
|
|
111
146
|
const nested = flattenRouter(handle, fullPath);
|
|
147
|
+
// Can't flatten this sub-router (e.g. it contains an array/RegExp-mounted middleware): leave
|
|
148
|
+
// it on the Express lane as a unit and keep compiling the rest of THIS router. Its routes fall
|
|
149
|
+
// through to the real Express app (with their full middleware chain) via the notFoundHandler.
|
|
112
150
|
if (nested === null)
|
|
113
|
-
|
|
151
|
+
continue;
|
|
114
152
|
entries.push(...nested);
|
|
115
153
|
}
|
|
116
154
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flattenRouter.js","sourceRoot":"","sources":["../../src/app/flattenRouter.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAuDH,0CAIC;
|
|
1
|
+
{"version":3,"file":"flattenRouter.js","sourceRoot":"","sources":["../../src/app/flattenRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,12 @@ export interface ExpressAppLike {
|
|
|
18
18
|
* Returns null if the app has middleware layers we can't flatten (e.g. no _path).
|
|
19
19
|
*/
|
|
20
20
|
export declare function introspectExpressApp(app: ExpressAppLike): RouteEntry[] | null;
|
|
21
|
+
/**
|
|
22
|
+
* Names of params that have `app.param(name, fn)` callbacks registered. Both Express 4 (`router.params`
|
|
23
|
+
* on `app._router`) and the Express 5 `router` package store them as `{ [name]: fn[] }`. Routes using
|
|
24
|
+
* these params run on the Express lane so the callbacks actually fire (we don't reimplement app.param).
|
|
25
|
+
*/
|
|
26
|
+
export declare function getAppParamNames(app: ExpressAppLike): Set<string>;
|
|
21
27
|
/** Express 4-arg error middleware type. */
|
|
22
28
|
export type ExpressErrorMiddleware = (err: Error, req: import('../types/express').ExpressRequest, res: import('../types/express').ExpressResponse, next: import('../types/express').NextFunction) => void | Promise<void>;
|
|
23
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspectExpress.d.ts","sourceRoot":"","sources":["../../src/app/introspectExpress.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG3E,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAiBD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,UAAU,EAAE,GAAG,IAAI,CAM7E;AAED,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG,CACnC,GAAG,EAAE,KAAK,EACV,GAAG,EAAE,OAAO,kBAAkB,EAAE,cAAc,EAC9C,GAAG,EAAE,OAAO,kBAAkB,EAAE,eAAe,EAC/C,IAAI,EAAE,OAAO,kBAAkB,EAAE,YAAY,KAC1C,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,sBAAsB,GAAG,IAAI,CAW5F"}
|
|
1
|
+
{"version":3,"file":"introspectExpress.d.ts","sourceRoot":"","sources":["../../src/app/introspectExpress.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG3E,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAiBD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,UAAU,EAAE,GAAG,IAAI,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAKjE;AAED,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG,CACnC,GAAG,EAAE,KAAK,EACV,GAAG,EAAE,OAAO,kBAAkB,EAAE,cAAc,EAC9C,GAAG,EAAE,OAAO,kBAAkB,EAAE,eAAe,EAC/C,IAAI,EAAE,OAAO,kBAAkB,EAAE,YAAY,KAC1C,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,sBAAsB,GAAG,IAAI,CAW5F"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.introspectExpressApp = introspectExpressApp;
|
|
12
|
+
exports.getAppParamNames = getAppParamNames;
|
|
12
13
|
exports.getExpressErrorMiddleware = getExpressErrorMiddleware;
|
|
13
14
|
const flattenRouter_1 = require("./flattenRouter");
|
|
14
15
|
/**
|
|
@@ -38,6 +39,18 @@ function introspectExpressApp(app) {
|
|
|
38
39
|
}
|
|
39
40
|
return (0, flattenRouter_1.flattenRouter)(router, '/');
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Names of params that have `app.param(name, fn)` callbacks registered. Both Express 4 (`router.params`
|
|
44
|
+
* on `app._router`) and the Express 5 `router` package store them as `{ [name]: fn[] }`. Routes using
|
|
45
|
+
* these params run on the Express lane so the callbacks actually fire (we don't reimplement app.param).
|
|
46
|
+
*/
|
|
47
|
+
function getAppParamNames(app) {
|
|
48
|
+
const router = getAppRouter(app);
|
|
49
|
+
const params = router?.params;
|
|
50
|
+
if (!params || typeof params !== 'object')
|
|
51
|
+
return new Set();
|
|
52
|
+
return new Set(Object.keys(params));
|
|
53
|
+
}
|
|
41
54
|
/**
|
|
42
55
|
* Return the first Express error middleware (4-arg handler) from the app's router stack, if any.
|
|
43
56
|
* Only considers middleware layers (no route), so we don't pick a route's handler by mistake.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspectExpress.js","sourceRoot":"","sources":["../../src/app/introspectExpress.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA+BH,oDAMC;AAeD,8DAWC;
|
|
1
|
+
{"version":3,"file":"introspectExpress.js","sourceRoot":"","sources":["../../src/app/introspectExpress.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA+BH,oDAMC;AAOD,4CAKC;AAeD,8DAWC;AAvED,mDAAgD;AAQhD;;;;;GAKG;AACH,SAAS,YAAY,CAAC,GAAmB;IACvC,IAAI,GAAG,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,GAAmB;IACtD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAA,6BAAa,EAAC,MAA2B,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,GAAmB;IAClD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAA2E,CAAC;IAC3G,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC5D,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACtC,CAAC;AAUD;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,GAAmB;IAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAoD,EAAE,CAAC;QAChF,IAAI,KAAK,CAAC,KAAK;YAAE,SAAS,CAAC,mDAAmD;QAC9E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,OAAO,MAAM,KAAK,UAAU,IAAK,MAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,MAAgC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines an Express-like property on a shared adapter prototype that is READABLE, WRITABLE, and
|
|
3
|
+
* concurrency-safe.
|
|
4
|
+
*
|
|
5
|
+
* The Fastify-lane req/res adapters reimplement Express's surface. Several Express properties
|
|
6
|
+
* (req.ip, req.hostname, req.protocol, req.cookies, ...) are derived values, but real Express code
|
|
7
|
+
* also *assigns* them (trust-proxy rewrites req.ip/protocol, cookie-parser sets req.cookies, etc.).
|
|
8
|
+
* A plain read-only getter makes those assignments throw in strict mode or silently drop — which is
|
|
9
|
+
* the root of the recurring "middleware breaks on the Fastify lane" bugs.
|
|
10
|
+
*
|
|
11
|
+
* This helper installs an accessor on the prototype whose `set` defines an OWN writable data
|
|
12
|
+
* property on the instance, so:
|
|
13
|
+
* - reads compute the derived value (Express's "derived until overridden" semantics),
|
|
14
|
+
* - the first write shadows the accessor with a per-instance own property (so it sticks AND is
|
|
15
|
+
* concurrency-safe — it lives on the per-request instance, never the shared prototype).
|
|
16
|
+
*
|
|
17
|
+
* @param memoize When true, the computed value is cached as a writable own property on first read
|
|
18
|
+
* (use for values that are STABLE for the life of the request and non-trivial to compute — ip,
|
|
19
|
+
* hostname, cookies — a speedup vs recomputing every access). When false, the value is recomputed
|
|
20
|
+
* on every read (use for values DERIVED FROM OTHER MUTABLE props — path←url, secure←protocol —
|
|
21
|
+
* which must stay live until explicitly overridden).
|
|
22
|
+
*/
|
|
23
|
+
export declare function defineWritable<T>(proto: object, key: string, compute: (self: Record<string, unknown>) => T, memoize?: boolean): void;
|
|
24
|
+
//# sourceMappingURL=define.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../src/fastify/adapters/define.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAC7C,OAAO,UAAQ,GACd,IAAI,CAyBN"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineWritable = defineWritable;
|
|
4
|
+
/**
|
|
5
|
+
* Defines an Express-like property on a shared adapter prototype that is READABLE, WRITABLE, and
|
|
6
|
+
* concurrency-safe.
|
|
7
|
+
*
|
|
8
|
+
* The Fastify-lane req/res adapters reimplement Express's surface. Several Express properties
|
|
9
|
+
* (req.ip, req.hostname, req.protocol, req.cookies, ...) are derived values, but real Express code
|
|
10
|
+
* also *assigns* them (trust-proxy rewrites req.ip/protocol, cookie-parser sets req.cookies, etc.).
|
|
11
|
+
* A plain read-only getter makes those assignments throw in strict mode or silently drop — which is
|
|
12
|
+
* the root of the recurring "middleware breaks on the Fastify lane" bugs.
|
|
13
|
+
*
|
|
14
|
+
* This helper installs an accessor on the prototype whose `set` defines an OWN writable data
|
|
15
|
+
* property on the instance, so:
|
|
16
|
+
* - reads compute the derived value (Express's "derived until overridden" semantics),
|
|
17
|
+
* - the first write shadows the accessor with a per-instance own property (so it sticks AND is
|
|
18
|
+
* concurrency-safe — it lives on the per-request instance, never the shared prototype).
|
|
19
|
+
*
|
|
20
|
+
* @param memoize When true, the computed value is cached as a writable own property on first read
|
|
21
|
+
* (use for values that are STABLE for the life of the request and non-trivial to compute — ip,
|
|
22
|
+
* hostname, cookies — a speedup vs recomputing every access). When false, the value is recomputed
|
|
23
|
+
* on every read (use for values DERIVED FROM OTHER MUTABLE props — path←url, secure←protocol —
|
|
24
|
+
* which must stay live until explicitly overridden).
|
|
25
|
+
*/
|
|
26
|
+
function defineWritable(proto, key, compute, memoize = false) {
|
|
27
|
+
Object.defineProperty(proto, key, {
|
|
28
|
+
configurable: true,
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get() {
|
|
31
|
+
const value = compute(this);
|
|
32
|
+
if (memoize) {
|
|
33
|
+
Object.defineProperty(this, key, {
|
|
34
|
+
value,
|
|
35
|
+
writable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
enumerable: true,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
},
|
|
42
|
+
set(value) {
|
|
43
|
+
Object.defineProperty(this, key, {
|
|
44
|
+
value,
|
|
45
|
+
writable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
enumerable: true,
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../src/fastify/adapters/define.ts"],"names":[],"mappings":";;AAsBA,wCA8BC;AApDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,cAAc,CAC5B,KAAa,EACb,GAAW,EACX,OAA6C,EAC7C,OAAO,GAAG,KAAK;IAEf,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE;QAChC,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;QAChB,GAAG;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE;oBAC/B,KAAK;oBACL,QAAQ,EAAE,IAAI;oBACd,YAAY,EAAE,IAAI;oBAClB,UAAU,EAAE,IAAI;iBACjB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,GAAG,CAAgC,KAAQ;YACzC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE;gBAC/B,KAAK;gBACL,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/fastify/adapters/request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/fastify/adapters/request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA6D1D,wBAAgB,YAAY,CAAC,UAAU,EAAE,cAAc,GAAG,cAAc,CAoDvE;AAiGD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,CAAC,UAAU,EAAE,cAAc,KAAK,cAAc,CAsBrF"}
|