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.
Files changed (45) hide show
  1. package/changelog/log-2026-06-25.md +38 -0
  2. package/changelog/log-2026-06-26.md +54 -0
  3. package/dist/app/compile.d.ts +6 -0
  4. package/dist/app/compile.d.ts.map +1 -1
  5. package/dist/app/compile.js +51 -17
  6. package/dist/app/compile.js.map +1 -1
  7. package/dist/app/flattenRouter.d.ts +17 -1
  8. package/dist/app/flattenRouter.d.ts.map +1 -1
  9. package/dist/app/flattenRouter.js +41 -3
  10. package/dist/app/flattenRouter.js.map +1 -1
  11. package/dist/app/introspectExpress.d.ts +6 -0
  12. package/dist/app/introspectExpress.d.ts.map +1 -1
  13. package/dist/app/introspectExpress.js +13 -0
  14. package/dist/app/introspectExpress.js.map +1 -1
  15. package/dist/fastify/adapters/define.d.ts +24 -0
  16. package/dist/fastify/adapters/define.d.ts.map +1 -0
  17. package/dist/fastify/adapters/define.js +52 -0
  18. package/dist/fastify/adapters/define.js.map +1 -0
  19. package/dist/fastify/adapters/request.d.ts.map +1 -1
  20. package/dist/fastify/adapters/request.js +24 -44
  21. package/dist/fastify/adapters/request.js.map +1 -1
  22. package/dist/fastify/adapters/response.js +4 -4
  23. package/dist/fastify/adapters/response.js.map +1 -1
  24. package/dist/fastify/register.d.ts +13 -0
  25. package/dist/fastify/register.d.ts.map +1 -1
  26. package/dist/fastify/register.js +28 -0
  27. package/dist/fastify/register.js.map +1 -1
  28. package/dist/runtime/fast.d.ts.map +1 -1
  29. package/dist/runtime/fast.js +9 -3
  30. package/dist/runtime/fast.js.map +1 -1
  31. package/dist/runtime/lifecycle.d.ts.map +1 -1
  32. package/dist/runtime/lifecycle.js +3 -0
  33. package/dist/runtime/lifecycle.js.map +1 -1
  34. package/dist/runtime/routingOptions.d.ts +16 -0
  35. package/dist/runtime/routingOptions.d.ts.map +1 -0
  36. package/dist/runtime/routingOptions.js +31 -0
  37. package/dist/runtime/routingOptions.js.map +1 -0
  38. package/dist/utils/detect.d.ts.map +1 -1
  39. package/dist/utils/detect.js +5 -0
  40. package/dist/utils/detect.js.map +1 -1
  41. package/dist/utils/expressPath.d.ts +24 -0
  42. package/dist/utils/expressPath.d.ts.map +1 -0
  43. package/dist/utils/expressPath.js +47 -0
  44. package/dist/utils/expressPath.js.map +1 -0
  45. 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', …)`.
@@ -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;AAKzD,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;CACvB;AAED;;;;;;;;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,CA+EN"}
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"}
@@ -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
- fastify.route({
176
- method: m,
177
- url: path,
178
- handler: (request, reply) => {
179
- if (logLane)
180
- logLane(request);
181
- (0, maxListeners_1.applyMaxListeners)(request.raw, reply.raw);
182
- const req = adaptRequest(request);
183
- const res = adaptResponse(reply, request);
184
- res.req = req;
185
- req.baseUrl = baseUrl;
186
- if (fastSingle !== null) {
187
- return fastSingle(req, res, noopNext);
188
- }
189
- return run(chain, req, res);
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/app/compile.ts"],"names":[],"mappings":"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"}
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
- * - If any middleware layer has no path we can read, return null and the caller mounts the router on Express lane.
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;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CAoE/F"}
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
- * - If any middleware layer has no path we can read, return null and the caller mounts the router on Express lane.
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
- return null;
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":"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"}
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;AA3DD,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;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"}
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;AA4D1D,wBAAgB,YAAY,CAAC,UAAU,EAAE,cAAc,GAAG,cAAc,CAoDvE;AAmHD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,CAAC,UAAU,EAAE,cAAc,KAAK,cAAc,CAsBrF"}
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"}