@timber-js/app 0.2.0-alpha.115 → 0.2.0-alpha.117
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/dist/_chunks/{actions-ILhDUzES.js → actions-Cw-7NfJJ.js} +24 -17
- package/dist/_chunks/actions-Cw-7NfJJ.js.map +1 -0
- package/dist/_chunks/{define-a0CCE6Nx.js → define-zQX6e1tN.js} +2 -2
- package/dist/_chunks/{define-a0CCE6Nx.js.map → define-zQX6e1tN.js.map} +1 -1
- package/dist/_chunks/{navigation-root-CY3pRMxF.js → navigation-root-DKsJ5Di7.js} +2 -2
- package/dist/_chunks/{navigation-root-CY3pRMxF.js.map → navigation-root-DKsJ5Di7.js.map} +1 -1
- package/dist/_chunks/{resolve-schema-DO8B0mO9.js → resolve-schema-23Mc8aLi.js} +1 -1
- package/dist/_chunks/{resolve-schema-DO8B0mO9.js.map → resolve-schema-23Mc8aLi.js.map} +1 -1
- package/dist/_chunks/{segment-context-EsfQpS--.js → segment-context-Bg0pFbLT.js} +1 -1
- package/dist/_chunks/{segment-context-EsfQpS--.js.map → segment-context-Bg0pFbLT.js.map} +1 -1
- package/dist/_chunks/tracing-DvKLzCFa.js.map +1 -1
- package/dist/_chunks/{use-segment-params-BSt_O2cb.js → use-segment-params-CskiK-59.js} +2 -2
- package/dist/_chunks/{use-segment-params-BSt_O2cb.js.map → use-segment-params-CskiK-59.js.map} +1 -1
- package/dist/_chunks/{walkers-DGV9dQRq.js → walkers-DgOXkTts.js} +12 -10
- package/dist/_chunks/walkers-DgOXkTts.js.map +1 -0
- package/dist/client/index.js +4 -4
- package/dist/client/internal.js +3 -3
- package/dist/client/use-segment-params.d.ts +3 -3
- package/dist/client/use-segment-params.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/params/index.js +1 -1
- package/dist/routing/codegen-types.d.ts +3 -0
- package/dist/routing/codegen-types.d.ts.map +1 -1
- package/dist/routing/index.js +1 -1
- package/dist/segment-params/index.js +1 -1
- package/dist/server/als-registry.d.ts +17 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/internal.js +70 -69
- package/dist/server/internal.js.map +1 -1
- package/dist/server/param-coercion.d.ts +18 -0
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +7 -0
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +18 -9
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +41 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/client/use-segment-params.ts +4 -4
- package/src/routing/codegen-types.ts +3 -0
- package/src/routing/codegen.ts +18 -9
- package/src/server/als-registry.ts +17 -4
- package/src/server/param-coercion.ts +58 -0
- package/src/server/pipeline-phases.ts +14 -7
- package/src/server/pipeline.ts +7 -0
- package/src/server/request-context.ts +48 -17
- package/src/server/route-element-builder.ts +12 -2
- package/src/server/route-matcher.ts +8 -168
- package/src/server/slot-resolver.ts +79 -112
- package/src/server/tree-match.ts +198 -0
- package/dist/_chunks/actions-ILhDUzES.js.map +0 -1
- package/dist/_chunks/walkers-DGV9dQRq.js.map +0 -1
|
@@ -53,12 +53,25 @@ export interface RequestContextStore {
|
|
|
53
53
|
*/
|
|
54
54
|
segmentParams?: Record<string, string | string[]>;
|
|
55
55
|
/**
|
|
56
|
-
* The matched
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* The matched segment path (e.g. '/(browse)/[artistSlug]/[year]').
|
|
57
|
+
* Includes route groups and parallel slots — uniquely identifies the
|
|
58
|
+
* segment in the route tree. Set by the pipeline alongside segmentParams.
|
|
59
|
+
* Used by getSegmentParams() for dev-mode validation.
|
|
59
60
|
* See design/41-global-params.md §Runtime Validation
|
|
60
61
|
*/
|
|
61
|
-
|
|
62
|
+
matchedSegmentPath?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Per-slot coerced segment params, keyed by the slot's full tree path
|
|
65
|
+
* (e.g. '/(browse)/@shows/[artistSlug]/[...year]').
|
|
66
|
+
*
|
|
67
|
+
* Each slot walks its own segment tree and may interpret URL parts
|
|
68
|
+
* differently from the main route (e.g. catch-all vs dynamic). This
|
|
69
|
+
* map stores slot-specific params so getSegmentParams(segmentPath)
|
|
70
|
+
* returns the correct types for slot pages.
|
|
71
|
+
*
|
|
72
|
+
* See design/07-routing.md §"Parallel Slot Params"
|
|
73
|
+
*/
|
|
74
|
+
slotParamsMap?: Map<string, Record<string, string | string[]>>;
|
|
62
75
|
/** Outgoing Set-Cookie entries (name → serialized value + options). Last write wins. */
|
|
63
76
|
cookieJar: Map<string, CookieEntry>;
|
|
64
77
|
/** Whether the response has flushed (headers committed). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"als-registry.d.ts","sourceRoot":"","sources":["../../src/server/als-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAMlE,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,wCAA+C,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,uEAAuE;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,YAAY,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAClD
|
|
1
|
+
{"version":3,"file":"als-registry.d.ts","sourceRoot":"","sources":["../../src/server/als-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAMlE,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,wCAA+C,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,uEAAuE;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,YAAY,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/D,wFAAwF;IACxF,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,4DAA4D;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,cAAc,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,mBAAmB,EAAE,CAAC;CACrD;AAED,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;CACtD;AAMD,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,mDAAmD;AACnD,eAAO,MAAM,QAAQ,+BAAsC,CAAC;AAM5D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;CACrD;AAED,yDAAyD;AACzD,eAAO,MAAM,SAAS,gCAAuC,CAAC;AAM9D,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,mDAAmD;AACnD,eAAO,MAAM,eAAe,sCAA6C,CAAC;AAM1E,sDAAsD;AACtD,eAAO,MAAM,YAAY,4DAAmE,CAAC;AAM7F,4EAA4E;AAC5E,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE3D,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,uCAA8C,CAAC;AAM/E,6EAA6E;AAC7E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AAE9D,4DAA4D;AAC5D,eAAO,MAAM,YAAY,gCAAuC,CAAC"}
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-DvKLzCFa.js";
|
|
2
2
|
import { t as formatSize } from "../_chunks/format-CR6v1pWE.js";
|
|
3
|
-
import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-
|
|
3
|
+
import { D as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-Cw-7NfJJ.js";
|
|
4
4
|
//#region src/server/sensitive-fields.ts
|
|
5
5
|
/**
|
|
6
6
|
* Sensitive field stripping — removes password/token/CVV-style fields
|
package/dist/server/internal.js
CHANGED
|
@@ -3,10 +3,10 @@ import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as wa
|
|
|
3
3
|
import { n as classifyUrlSegment } from "../_chunks/segment-classify-CnfLLvir.js";
|
|
4
4
|
import { i as getMetadataRouteServePath, n as classifyMetadataRoute, r as getMetadataRouteAutoLink, t as METADATA_ROUTE_CONVENTIONS } from "../_chunks/metadata-routes-Cjmvi3rQ.js";
|
|
5
5
|
import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-DDmK5skc.js";
|
|
6
|
-
import { C as
|
|
6
|
+
import { C as setMatchedSegmentPath, E as getCookie, O as getSetCookieHeaders, S as runWithRequestContext, T as setSegmentParams, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setMutableCookieContext, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-Cw-7NfJJ.js";
|
|
7
7
|
import "../client/error-boundary.js";
|
|
8
|
-
import "../_chunks/
|
|
9
|
-
import
|
|
8
|
+
import { n as toBracketKey } from "../_chunks/resolve-schema-23Mc8aLi.js";
|
|
9
|
+
import "../_chunks/segment-context-Bg0pFbLT.js";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
11
|
import { createElement } from "react";
|
|
12
12
|
//#region src/server/server-timing.ts
|
|
@@ -1336,6 +1336,70 @@ function buildDeniedFallback(DeniedComponent, slotName, data, createElement) {
|
|
|
1336
1336
|
});
|
|
1337
1337
|
}
|
|
1338
1338
|
//#endregion
|
|
1339
|
+
//#region src/server/param-coercion.ts
|
|
1340
|
+
/** Global schema codecs, set once at startup from virtual:timber-schema. */
|
|
1341
|
+
var _globalCodecs = null;
|
|
1342
|
+
/**
|
|
1343
|
+
* Run segment param coercion on the matched route's segments.
|
|
1344
|
+
*
|
|
1345
|
+
* When `globalCodecs` is provided (from app/schema.ts), uses the global
|
|
1346
|
+
* codec map keyed by bare param name. Otherwise falls back to loading
|
|
1347
|
+
* per-segment params.ts modules.
|
|
1348
|
+
*
|
|
1349
|
+
* Throws ParamCoercionError if any codec fails (→ 404).
|
|
1350
|
+
*
|
|
1351
|
+
* This runs BEFORE middleware, so ctx.segmentParams is already typed.
|
|
1352
|
+
* See design/07-routing.md §"Where Coercion Runs"
|
|
1353
|
+
* See design/41-global-params.md §"Pipeline Integration"
|
|
1354
|
+
*/
|
|
1355
|
+
async function coerceSegmentParams(match) {
|
|
1356
|
+
const globalCodecs = _globalCodecs;
|
|
1357
|
+
const mergeTarget = Object.create(null);
|
|
1358
|
+
for (const key of Object.keys(match.segmentParams)) if (key !== "__proto__") mergeTarget[key] = match.segmentParams[key];
|
|
1359
|
+
match.segmentParams = mergeTarget;
|
|
1360
|
+
if (globalCodecs) {
|
|
1361
|
+
for (const segment of match.segments) {
|
|
1362
|
+
if (!segment.paramName) continue;
|
|
1363
|
+
const bracketKey = toBracketKey(segment.segmentType, segment.paramName);
|
|
1364
|
+
const codec = globalCodecs[bracketKey];
|
|
1365
|
+
if (!codec) continue;
|
|
1366
|
+
const key = segment.paramName;
|
|
1367
|
+
try {
|
|
1368
|
+
mergeTarget[key] = sanitizeParamValue(codec.parse(mergeTarget[key]));
|
|
1369
|
+
} catch (err) {
|
|
1370
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1371
|
+
if (isDebug()) console.warn(`[timber] Global schema codec rejected value for param "${key}"\n Error: ${message}\n Raw value: ${JSON.stringify(mergeTarget[key])}\n Hint: check the codec in app/schema.ts for key '${bracketKey}'.`);
|
|
1372
|
+
throw new ParamCoercionError(message);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
for (const segment of match.segments) {
|
|
1378
|
+
if (!segment.params) continue;
|
|
1379
|
+
let mod;
|
|
1380
|
+
try {
|
|
1381
|
+
mod = await loadModule(segment.params);
|
|
1382
|
+
} catch (err) {
|
|
1383
|
+
const message = `Failed to load params module for segment "${segment.segmentName}": ${err instanceof Error ? err.message : String(err)}`;
|
|
1384
|
+
if (isDebug()) console.warn(`[timber] Param coercion error: ${message}\n Segment: ${segment.segmentName}\n Params file: ${segment.params}`);
|
|
1385
|
+
throw new ParamCoercionError(message);
|
|
1386
|
+
}
|
|
1387
|
+
const segmentParamsDef = mod.segmentParams;
|
|
1388
|
+
if (!segmentParamsDef || typeof segmentParamsDef.parse !== "function") continue;
|
|
1389
|
+
try {
|
|
1390
|
+
const coerced = segmentParamsDef.parse(match.segmentParams);
|
|
1391
|
+
for (const key of Object.keys(coerced)) if (key !== "__proto__") mergeTarget[key] = sanitizeParamValue(coerced[key]);
|
|
1392
|
+
} catch (err) {
|
|
1393
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1394
|
+
if (isDebug()) {
|
|
1395
|
+
const rawKeys = Object.keys(match.segmentParams).join(", ");
|
|
1396
|
+
console.warn(`[timber] Param codec rejected values for segment "${segment.segmentName}"\n Error: ${message}\n Available raw params: { ${rawKeys} }\n Params file: ${segment.params}\n Hint: this usually means a codec threw for the raw URL value.\n Check that the regex/schema accepts the actual path segment string.`);
|
|
1397
|
+
}
|
|
1398
|
+
throw new ParamCoercionError(message);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
//#endregion
|
|
1339
1403
|
//#region src/server/route-element-builder.ts
|
|
1340
1404
|
/**
|
|
1341
1405
|
* Thrown when a defineSegmentParams codec's parse() fails.
|
|
@@ -1536,70 +1600,6 @@ function pathnameMatchesPattern(pathname, pattern) {
|
|
|
1536
1600
|
return pi === pathParts.length;
|
|
1537
1601
|
}
|
|
1538
1602
|
//#endregion
|
|
1539
|
-
//#region src/server/param-coercion.ts
|
|
1540
|
-
/** Global schema codecs, set once at startup from virtual:timber-schema. */
|
|
1541
|
-
var _globalCodecs = null;
|
|
1542
|
-
/**
|
|
1543
|
-
* Run segment param coercion on the matched route's segments.
|
|
1544
|
-
*
|
|
1545
|
-
* When `globalCodecs` is provided (from app/schema.ts), uses the global
|
|
1546
|
-
* codec map keyed by bare param name. Otherwise falls back to loading
|
|
1547
|
-
* per-segment params.ts modules.
|
|
1548
|
-
*
|
|
1549
|
-
* Throws ParamCoercionError if any codec fails (→ 404).
|
|
1550
|
-
*
|
|
1551
|
-
* This runs BEFORE middleware, so ctx.segmentParams is already typed.
|
|
1552
|
-
* See design/07-routing.md §"Where Coercion Runs"
|
|
1553
|
-
* See design/41-global-params.md §"Pipeline Integration"
|
|
1554
|
-
*/
|
|
1555
|
-
async function coerceSegmentParams(match) {
|
|
1556
|
-
const globalCodecs = _globalCodecs;
|
|
1557
|
-
const mergeTarget = Object.create(null);
|
|
1558
|
-
for (const key of Object.keys(match.segmentParams)) if (key !== "__proto__") mergeTarget[key] = match.segmentParams[key];
|
|
1559
|
-
match.segmentParams = mergeTarget;
|
|
1560
|
-
if (globalCodecs) {
|
|
1561
|
-
for (const segment of match.segments) {
|
|
1562
|
-
if (!segment.paramName) continue;
|
|
1563
|
-
const bracketKey = toBracketKey(segment.segmentType, segment.paramName);
|
|
1564
|
-
const codec = globalCodecs[bracketKey];
|
|
1565
|
-
if (!codec) continue;
|
|
1566
|
-
const key = segment.paramName;
|
|
1567
|
-
try {
|
|
1568
|
-
mergeTarget[key] = sanitizeParamValue(codec.parse(mergeTarget[key]));
|
|
1569
|
-
} catch (err) {
|
|
1570
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1571
|
-
if (isDebug()) console.warn(`[timber] Global schema codec rejected value for param "${key}"\n Error: ${message}\n Raw value: ${JSON.stringify(mergeTarget[key])}\n Hint: check the codec in app/schema.ts for key '${bracketKey}'.`);
|
|
1572
|
-
throw new ParamCoercionError(message);
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
for (const segment of match.segments) {
|
|
1578
|
-
if (!segment.params) continue;
|
|
1579
|
-
let mod;
|
|
1580
|
-
try {
|
|
1581
|
-
mod = await loadModule(segment.params);
|
|
1582
|
-
} catch (err) {
|
|
1583
|
-
const message = `Failed to load params module for segment "${segment.segmentName}": ${err instanceof Error ? err.message : String(err)}`;
|
|
1584
|
-
if (isDebug()) console.warn(`[timber] Param coercion error: ${message}\n Segment: ${segment.segmentName}\n Params file: ${segment.params}`);
|
|
1585
|
-
throw new ParamCoercionError(message);
|
|
1586
|
-
}
|
|
1587
|
-
const segmentParamsDef = mod.segmentParams;
|
|
1588
|
-
if (!segmentParamsDef || typeof segmentParamsDef.parse !== "function") continue;
|
|
1589
|
-
try {
|
|
1590
|
-
const coerced = segmentParamsDef.parse(match.segmentParams);
|
|
1591
|
-
for (const key of Object.keys(coerced)) if (key !== "__proto__") mergeTarget[key] = sanitizeParamValue(coerced[key]);
|
|
1592
|
-
} catch (err) {
|
|
1593
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1594
|
-
if (isDebug()) {
|
|
1595
|
-
const rawKeys = Object.keys(match.segmentParams).join(", ");
|
|
1596
|
-
console.warn(`[timber] Param codec rejected values for segment "${segment.segmentName}"\n Error: ${message}\n Available raw params: { ${rawKeys} }\n Params file: ${segment.params}\n Hint: this usually means a codec threw for the raw URL value.\n Check that the regex/schema accepts the actual path segment string.`);
|
|
1597
|
-
}
|
|
1598
|
-
throw new ParamCoercionError(message);
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
//#endregion
|
|
1603
1603
|
//#region src/server/pipeline-outcome.ts
|
|
1604
1604
|
/**
|
|
1605
1605
|
* Pipeline outcome translator — converts a `PhaseOutcome` (the value
|
|
@@ -1935,6 +1935,7 @@ async function handleRequest(config, req, method, path) {
|
|
|
1935
1935
|
} catch (err) {
|
|
1936
1936
|
swallow(err, "early hints hook threw");
|
|
1937
1937
|
}
|
|
1938
|
+
match.rawSegmentParams = { ...match.segmentParams };
|
|
1938
1939
|
try {
|
|
1939
1940
|
await coerceSegmentParams(match);
|
|
1940
1941
|
} catch (error) {
|
|
@@ -1951,8 +1952,8 @@ async function handleRequest(config, req, method, path) {
|
|
|
1951
1952
|
throw error;
|
|
1952
1953
|
}
|
|
1953
1954
|
setSegmentParams(match.segmentParams);
|
|
1954
|
-
const
|
|
1955
|
-
|
|
1955
|
+
const segmentPath = match.segments.map((s) => s.segmentName).filter(Boolean).join("/") || "/";
|
|
1956
|
+
setMatchedSegmentPath(segmentPath.startsWith("/") ? segmentPath : `/${segmentPath}`);
|
|
1956
1957
|
return outcomeToResponse(config, !shouldBypassMiddleware(req) && match.middlewareChain.length > 0 ? await runMiddlewarePhase(config, req, match, responseHeaders, requestHeaderOverlay, {
|
|
1957
1958
|
canonicalPathname,
|
|
1958
1959
|
interception
|