@rebask/core 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__type_probe__.d.ts +2 -0
- package/dist/__type_probe__.d.ts.map +1 -0
- package/dist/__type_probe__.js +4 -0
- package/dist/components/head.d.ts +2 -11
- package/dist/components/head.d.ts.map +1 -1
- package/dist/components/head.js +12 -24
- package/dist/entry.browser.js +2 -2
- package/dist/entry.ssr.d.ts.map +1 -1
- package/dist/entry.ssr.js +12 -7
- package/dist/handlers/rsc/background-render.js +2 -2
- package/dist/handlers/rsc/render-request.js +2 -2
- package/dist/handlers/rsc/render-to-response.js +2 -2
- package/dist/handlers/rsc/state.d.ts.map +1 -1
- package/dist/handlers/rsc/state.js +11 -5
- package/dist/lib/client-route-prediction.d.ts +1 -1
- package/dist/lib/client-route-prediction.d.ts.map +1 -1
- package/dist/lib/client-route-prediction.js +2 -7
- package/dist/lib/head/head-manager.d.ts +9 -0
- package/dist/lib/head/head-manager.d.ts.map +1 -0
- package/dist/lib/head/head-manager.js +98 -0
- package/dist/lib/head/head-script.js +8 -13
- package/dist/lib/image-optimization/image-plugin.d.ts +2 -0
- package/dist/lib/image-optimization/image-plugin.d.ts.map +1 -1
- package/dist/lib/image-optimization/image-plugin.js +10 -3
- package/dist/lib/plugin-names.d.ts +3 -0
- package/dist/lib/plugin-names.d.ts.map +1 -0
- package/dist/lib/plugin-names.js +2 -0
- package/dist/lib/proxy/build-proxy.d.ts +1 -1
- package/dist/lib/proxy/build-proxy.d.ts.map +1 -1
- package/dist/lib/proxy/build-proxy.js +4 -11
- package/dist/lib/proxy/pattern.d.ts +7 -0
- package/dist/lib/proxy/pattern.d.ts.map +1 -0
- package/dist/lib/proxy/pattern.js +18 -0
- package/dist/lib/proxy/types.d.ts +3 -1
- package/dist/lib/proxy/types.d.ts.map +1 -1
- package/dist/lib/route-prediction.d.ts.map +1 -1
- package/dist/lib/rsc-request.d.ts.map +1 -1
- package/dist/lib/rsc-request.js +6 -4
- package/dist/lib/server-router/build-entries.d.ts +76 -0
- package/dist/lib/server-router/build-entries.d.ts.map +1 -0
- package/dist/lib/server-router/build-entries.js +74 -0
- package/dist/lib/server-router/get-router.d.ts.map +1 -1
- package/dist/lib/server-router/get-router.js +55 -105
- package/dist/lib/server-router/rou3.d.ts +20 -0
- package/dist/lib/server-router/rou3.d.ts.map +1 -0
- package/dist/lib/server-router/rou3.js +55 -0
- package/dist/lib/server-router/route-entries.d.ts +16 -0
- package/dist/lib/server-router/route-entries.d.ts.map +1 -0
- package/dist/lib/server-router/route-entries.js +67 -0
- package/dist/lib/server-router/types.d.ts +24 -33
- package/dist/lib/server-router/types.d.ts.map +1 -1
- package/dist/lib/server-router/types.js +1 -6
- package/dist/lib/types.d.ts +2 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/plugins/prerender.d.ts +3 -4
- package/dist/plugins/prerender.d.ts.map +1 -1
- package/dist/plugins/prerender.js +31 -0
- package/dist/plugins/proxy.d.ts.map +1 -1
- package/dist/plugins/proxy.js +7 -1
- package/dist/plugins/router/rou3-compiled.d.ts +9 -0
- package/dist/plugins/router/rou3-compiled.d.ts.map +1 -0
- package/dist/plugins/router/rou3-compiled.js +14 -0
- package/dist/plugins/router/rou3-router.d.ts +3 -0
- package/dist/plugins/router/rou3-router.d.ts.map +1 -0
- package/dist/plugins/router/rou3-router.js +16 -0
- package/dist/plugins/router/router-plugin.d.ts +6 -16
- package/dist/plugins/router/router-plugin.d.ts.map +1 -1
- package/dist/plugins/router/router-plugin.js +43 -22
- package/dist/proxy.d.ts +1 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +1 -0
- package/dist/request-context.d.ts +0 -2
- package/dist/request-context.d.ts.map +1 -1
- package/dist/request-context.js +0 -4
- package/dist/router.d.ts +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +4 -4
- package/dist/server-router.d.ts +3 -3
- package/dist/server-router.d.ts.map +1 -1
- package/dist/server-router.js +2 -2
- package/dist/vite.d.ts +8 -3
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +60 -29
- package/package.json +5 -4
|
@@ -10,7 +10,7 @@ import type { RouteParams } from "../route-matcher.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export type ProxyHandler = (request: Request, params: RouteParams) => Response | void | Promise<Response | void>;
|
|
12
12
|
/**
|
|
13
|
-
* An object mapping
|
|
13
|
+
* An object mapping rou3 route patterns to proxy handler functions.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```ts
|
|
@@ -43,6 +43,8 @@ export interface ProxyBundle {
|
|
|
43
43
|
proxyRouter: ProxyRouter | null;
|
|
44
44
|
/** The route patterns, or `null` if there are no proxy routes. */
|
|
45
45
|
proxyPatterns: string[] | null;
|
|
46
|
+
/** Match-only regex sources for the route patterns, or `null` if there are no proxy routes. */
|
|
47
|
+
proxyRegexps: string[] | null;
|
|
46
48
|
}
|
|
47
49
|
/** Standalone proxy bundle path, relative to the project root. */
|
|
48
50
|
export declare const REBASK_PROXY_BUNDLE_PATH = "dist/proxy/index.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,WAAW,KACf,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAE/C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,CAAA;AAE7D,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC3B;;;OAGG;IACH,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC,YAAY,CAAC,CAAC,GAAG,IAAI,CAAA;CACnF;AAED,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC3B,mEAAmE;IACnE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,kEAAkE;IAClE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,WAAW,KACf,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAE/C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,CAAA;AAE7D,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC3B;;;OAGG;IACH,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC,YAAY,CAAC,CAAC,GAAG,IAAI,CAAA;CACnF;AAED,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC3B,mEAAmE;IACnE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,kEAAkE;IAClE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC9B,+FAA+F;IAC/F,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAC7B;AAED,kEAAkE;AAClE,eAAO,MAAM,wBAAwB,wBAAwB,CAAA;AAE7D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-prediction.d.ts","sourceRoot":"","sources":["../../src/lib/route-prediction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,4FAA4F;AAC5F,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,CAAA;AAEhC,MAAM,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,MAAM;IACf;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAClF,kFAAkF;IAClF,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACpE,iGAAiG;IACjG,UAAU,CAAC,EAAE,OAAO;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,SAAS,CAAA;IACf,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAA;CACX,CAAA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,GAAG,CAEhE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,UAAQ,GACb,MAAM,
|
|
1
|
+
{"version":3,"file":"route-prediction.d.ts","sourceRoot":"","sources":["../../src/lib/route-prediction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,4FAA4F;AAC5F,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,CAAA;AAEhC,MAAM,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,MAAM;IACf;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAClF,kFAAkF;IAClF,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACpE,iGAAiG;IACjG,UAAU,CAAC,EAAE,OAAO;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,SAAS,CAAA;IACf,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAA;CACX,CAAA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,GAAG,CAEhE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,UAAQ,GACb,MAAM,CA+BR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsc-request.d.ts","sourceRoot":"","sources":["../../src/lib/rsc-request.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"rsc-request.d.ts","sourceRoot":"","sources":["../../src/lib/rsc-request.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/rsc-request.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createClientManifest, renderToReadableStream } from "@vitejs/plugin-rsc
|
|
|
3
3
|
import { prerender } from "@vitejs/plugin-rsc/vendor/react-server-dom/static.edge";
|
|
4
4
|
import { hooks, hooksOptions } from "virtual:rebask/hooks";
|
|
5
5
|
import { pprConfig } from "virtual:rebask/ppr-config";
|
|
6
|
-
import { getCacheLife,
|
|
6
|
+
import { getCacheLife, hasNotFoundMark, isUncacheable, mergeResponseHeaders, RequestStorage, withRequestStorage, OutgoingResponseHeaders, } from "../request-context.js";
|
|
7
7
|
import { CacheKeyTag } from "./cache-key-tags.js";
|
|
8
8
|
import { getCacheKey } from "./cache-keys.js";
|
|
9
9
|
import { streamFromCachePayload, streamToCachePayload } from "./cache-payload.js";
|
|
@@ -59,13 +59,15 @@ export function createRscResponse(rscStream, options = {}) {
|
|
|
59
59
|
const tagHeader = pprConfig?.cacheTagsHeader;
|
|
60
60
|
let trailerNonce;
|
|
61
61
|
if (trailer && rscStream) {
|
|
62
|
+
// `flush()` can run after the request scope exits, so keep the state instead of looking it
|
|
63
|
+
// up in AsyncLocalStorage. `trackSearchParam()` fills `usedSearch` lazily during the render.
|
|
64
|
+
const requestState = RequestStorage.getStore().state;
|
|
62
65
|
trailerNonce = randomBytes(16).toString("hex");
|
|
63
66
|
rscStream = rscStream.pipeThrough(new TransformStream({
|
|
64
67
|
flush(controller) {
|
|
65
68
|
const used = {};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
for (const [key, value] of usedSearch)
|
|
69
|
+
if (requestState.usedSearch) {
|
|
70
|
+
for (const [key, value] of requestState.usedSearch)
|
|
69
71
|
used[key] = value;
|
|
70
72
|
}
|
|
71
73
|
controller.enqueue(TEXT_ENCODER.encode(`\r\n--${trailerNonce}\r\n${JSON.stringify({ used })}`));
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type LayoutRoute, type PageRoute, type RouteHandlerRoute } from "../route-matcher.js";
|
|
2
|
+
import { RouteType, type ProxyEntry, type RouteEntry } from "./types.js";
|
|
3
|
+
type Handler = (request: Request, params: Record<string, string | string[] | undefined>) => Promise<Response>;
|
|
4
|
+
export interface EntryHandlers {
|
|
5
|
+
page: (route: PageRoute) => Handler;
|
|
6
|
+
markdown: (route: PageRoute) => Handler;
|
|
7
|
+
routeHandler: (route: RouteHandlerRoute) => Handler;
|
|
8
|
+
layout: (route: LayoutRoute) => Handler;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildEntries(pageRoutes: PageRoute[], routeHandlerRoutes: RouteHandlerRoute[], layoutRoutes: LayoutRoute[], imageEntry: Exclude<RouteEntry, ProxyEntry> | null, handlers: EntryHandlers): {
|
|
11
|
+
appEntries: ({
|
|
12
|
+
type: RouteType.IMAGE;
|
|
13
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
14
|
+
pattern: string;
|
|
15
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
16
|
+
} | {
|
|
17
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
18
|
+
type: RouteType.APP;
|
|
19
|
+
route: LayoutRoute;
|
|
20
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
21
|
+
} | {
|
|
22
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
23
|
+
type: RouteType.APP;
|
|
24
|
+
route: import("../route-matcher.js").Route;
|
|
25
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
26
|
+
} | {
|
|
27
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
28
|
+
type: RouteType.APP;
|
|
29
|
+
route: RouteHandlerRoute;
|
|
30
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
31
|
+
})[];
|
|
32
|
+
layoutEntries: ({
|
|
33
|
+
type: RouteType.IMAGE;
|
|
34
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
35
|
+
pattern: string;
|
|
36
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
37
|
+
} | {
|
|
38
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
39
|
+
type: RouteType.APP;
|
|
40
|
+
route: LayoutRoute;
|
|
41
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
42
|
+
} | {
|
|
43
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
44
|
+
type: RouteType.APP;
|
|
45
|
+
route: import("../route-matcher.js").Route;
|
|
46
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
47
|
+
} | {
|
|
48
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
49
|
+
type: RouteType.APP;
|
|
50
|
+
route: RouteHandlerRoute;
|
|
51
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
52
|
+
})[];
|
|
53
|
+
markdownEntries: ({
|
|
54
|
+
type: RouteType.IMAGE;
|
|
55
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
56
|
+
pattern: string;
|
|
57
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
58
|
+
} | {
|
|
59
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
60
|
+
type: RouteType.APP;
|
|
61
|
+
route: LayoutRoute;
|
|
62
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
63
|
+
} | {
|
|
64
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
65
|
+
type: RouteType.APP;
|
|
66
|
+
route: import("../route-matcher.js").Route;
|
|
67
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
68
|
+
} | {
|
|
69
|
+
methods: import("../route-matcher.js").HttpMethod[];
|
|
70
|
+
type: RouteType.APP;
|
|
71
|
+
route: RouteHandlerRoute;
|
|
72
|
+
handler: (request: Request, params: import("../route-matcher.js").RouteParams) => Promise<Response>;
|
|
73
|
+
})[];
|
|
74
|
+
};
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=build-entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entries.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/build-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,iBAAiB,EAEtB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAExE,KAAK,OAAO,GAAG,CACd,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,KACjD,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtB,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAA;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAA;IACvC,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAA;IACnD,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;CACvC;AAUD,wBAAgB,YAAY,CAC3B,UAAU,EAAE,SAAS,EAAE,EACvB,kBAAkB,EAAE,iBAAiB,EAAE,EACvC,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,IAAI,EAClD,QAAQ,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4EvB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { HTTP_METHODS, } from "../route-matcher.js";
|
|
2
|
+
import { appPattern, setEntryParams } from "./rou3.js";
|
|
3
|
+
import { RouteType } from "./types.js";
|
|
4
|
+
function setAppParams(entry) {
|
|
5
|
+
if (entry.type !== RouteType.APP)
|
|
6
|
+
return entry;
|
|
7
|
+
setEntryParams(entry, appPattern(entry.route.segments, entry.route.type === "layout"));
|
|
8
|
+
return entry;
|
|
9
|
+
}
|
|
10
|
+
export function buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes, imageEntry, handlers) {
|
|
11
|
+
const appEntries = [];
|
|
12
|
+
const layoutEntries = [];
|
|
13
|
+
const markdownEntries = [];
|
|
14
|
+
const hasMarkdownRoutes = pageRoutes.some((route) => route.markdownFilePath);
|
|
15
|
+
if (imageEntry) {
|
|
16
|
+
setAppParams(imageEntry);
|
|
17
|
+
appEntries.push(imageEntry);
|
|
18
|
+
if (hasMarkdownRoutes)
|
|
19
|
+
markdownEntries.push(imageEntry);
|
|
20
|
+
}
|
|
21
|
+
for (const route of pageRoutes) {
|
|
22
|
+
if (route.hasPage !== false) {
|
|
23
|
+
appEntries.push(setAppParams({
|
|
24
|
+
type: RouteType.APP,
|
|
25
|
+
methods: ["GET", "POST"],
|
|
26
|
+
route,
|
|
27
|
+
handler: handlers.page(route),
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
if (!hasMarkdownRoutes)
|
|
31
|
+
continue;
|
|
32
|
+
if (route.markdownFilePath) {
|
|
33
|
+
markdownEntries.push(setAppParams({
|
|
34
|
+
type: RouteType.APP,
|
|
35
|
+
methods: ["GET", "HEAD"],
|
|
36
|
+
route,
|
|
37
|
+
handler: handlers.markdown(route),
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
else if (route.hasPage !== false) {
|
|
41
|
+
markdownEntries.push(setAppParams({
|
|
42
|
+
type: RouteType.APP,
|
|
43
|
+
methods: ["GET"],
|
|
44
|
+
route,
|
|
45
|
+
handler: handlers.page(route),
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const route of routeHandlerRoutes) {
|
|
50
|
+
const entry = setAppParams({
|
|
51
|
+
type: RouteType.APP,
|
|
52
|
+
methods: [...HTTP_METHODS],
|
|
53
|
+
route,
|
|
54
|
+
handler: handlers.routeHandler(route),
|
|
55
|
+
});
|
|
56
|
+
appEntries.push(entry);
|
|
57
|
+
if (hasMarkdownRoutes)
|
|
58
|
+
markdownEntries.push(entry);
|
|
59
|
+
}
|
|
60
|
+
for (const route of layoutRoutes) {
|
|
61
|
+
const segments = [
|
|
62
|
+
{ type: "static", value: "_rebask" },
|
|
63
|
+
{ type: "static", value: "1" },
|
|
64
|
+
...route.segments,
|
|
65
|
+
];
|
|
66
|
+
layoutEntries.push(setAppParams({
|
|
67
|
+
type: RouteType.APP,
|
|
68
|
+
methods: ["GET"],
|
|
69
|
+
route: { ...route, segments },
|
|
70
|
+
handler: handlers.layout(route),
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
return { appEntries, layoutEntries, markdownEntries };
|
|
74
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-router.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/get-router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-router.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/get-router.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA4L9C,yDAAyD;AACzD,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CA4BvD"}
|
|
@@ -17,117 +17,67 @@ import { buildProxy } from "../proxy/build-proxy.js";
|
|
|
17
17
|
import { proxyExternal } from "../proxy/proxy-external.js";
|
|
18
18
|
import { REWRITE_HEADER, rewriteHeaders } from "../proxy/rewrite.js";
|
|
19
19
|
import { assertNoPageRouteHandlerConflicts, buildLayoutRoutes, buildRouteHandlerRoutes, buildRoutes, } from "../route-builder.js";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
function buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes) {
|
|
23
|
-
const appEntries = [];
|
|
24
|
-
const layoutEntries = [];
|
|
25
|
-
const markdownEntries = [];
|
|
26
|
-
const hasMarkdownRoutes = pageRoutes.some((route) => route.markdownFilePath);
|
|
27
|
-
// Image optimization route
|
|
28
|
-
if (imageConfig !== null && loadImageHandler !== undefined) {
|
|
29
|
-
const imageEntry = {
|
|
30
|
-
type: RouteType.IMAGE,
|
|
31
|
-
methods: ["GET"],
|
|
32
|
-
pattern: imageConfig.path,
|
|
33
|
-
handler: handleImageRequest,
|
|
34
|
-
};
|
|
35
|
-
appEntries.push(imageEntry);
|
|
36
|
-
if (hasMarkdownRoutes)
|
|
37
|
-
markdownEntries.push(imageEntry);
|
|
38
|
-
}
|
|
39
|
-
// Page routes — registered for GET and POST:
|
|
40
|
-
// - GET: page loads, RSC requests, segment requests
|
|
41
|
-
// - POST: server functions, form submissions, PPR resume
|
|
42
|
-
for (const route of pageRoutes) {
|
|
43
|
-
if (route.hasPage !== false) {
|
|
44
|
-
appEntries.push({
|
|
45
|
-
type: RouteType.APP,
|
|
46
|
-
methods: ["GET", "POST"],
|
|
47
|
-
route,
|
|
48
|
-
handler: (req, params) => handlePageRoute(req, route, params),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
if (!hasMarkdownRoutes)
|
|
52
|
-
continue;
|
|
53
|
-
if (route.markdownFilePath) {
|
|
54
|
-
markdownEntries.push({
|
|
55
|
-
type: RouteType.APP,
|
|
56
|
-
methods: ["GET", "HEAD"],
|
|
57
|
-
route,
|
|
58
|
-
handler: (req, params) => handleMarkdownRoute(req, route, params),
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
else if (route.hasPage !== false) {
|
|
62
|
-
// A specific page without Markdown still wins negotiation over a Markdown catch-all.
|
|
63
|
-
markdownEntries.push({
|
|
64
|
-
type: RouteType.APP,
|
|
65
|
-
methods: ["GET"],
|
|
66
|
-
route,
|
|
67
|
-
handler: (req, params) => handlePageRoute(req, route, params),
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Route handlers — registered for all methods so they can return 405 when the path exists but a
|
|
72
|
-
// specific method is not implemented.
|
|
73
|
-
for (const route of routeHandlerRoutes) {
|
|
74
|
-
const entry = {
|
|
75
|
-
type: RouteType.APP,
|
|
76
|
-
methods: [...HTTP_METHODS],
|
|
77
|
-
route,
|
|
78
|
-
handler: (req, params) => handleRouteHandler(req, route, params),
|
|
79
|
-
};
|
|
80
|
-
appEntries.push(entry);
|
|
81
|
-
if (hasMarkdownRoutes)
|
|
82
|
-
markdownEntries.push(entry);
|
|
83
|
-
}
|
|
84
|
-
// Layout routes — registered under /_rebask/1/{path}
|
|
85
|
-
for (const route of layoutRoutes) {
|
|
86
|
-
const segments = [
|
|
87
|
-
{ type: "static", value: "_rebask" },
|
|
88
|
-
{ type: "static", value: "1" },
|
|
89
|
-
...route.segments,
|
|
90
|
-
];
|
|
91
|
-
layoutEntries.push({
|
|
92
|
-
type: RouteType.APP,
|
|
93
|
-
methods: ["GET"],
|
|
94
|
-
route: { ...route, segments },
|
|
95
|
-
handler: (req, params) => handleLayoutRouteRequest(req, route, params),
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return { appEntries, layoutEntries, markdownEntries };
|
|
99
|
-
}
|
|
20
|
+
import { extractAppParams } from "./rou3.js";
|
|
21
|
+
import { buildRouteEntries } from "./route-entries.js";
|
|
100
22
|
function createRouter(pageRoutes, routeHandlerRoutes, layoutRoutes, resolvedProxyRouter = proxyRouter) {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
23
|
+
const imageEntry = imageConfig !== null && loadImageHandler !== undefined
|
|
24
|
+
? { pattern: imageConfig.path, handler: handleImageRequest }
|
|
25
|
+
: null;
|
|
26
|
+
const { entries, markdownEnabled } = buildRouteEntries(pageRoutes, routeHandlerRoutes, layoutRoutes, imageEntry, {
|
|
27
|
+
page: (route) => (request, params) => handlePageRoute(request, route, params),
|
|
28
|
+
markdown: (route) => (request, params) => handleMarkdownRoute(request, route, params),
|
|
29
|
+
routeHandler: (route) => (request, params) => handleRouteHandler(request, route, params),
|
|
30
|
+
layout: (route) => (request, params) => handleLayoutRouteRequest(request, route, params),
|
|
31
|
+
});
|
|
32
|
+
const appMatcher = createMatcher(entries);
|
|
105
33
|
const app = async (request) => {
|
|
106
34
|
const method = request.method;
|
|
107
35
|
const accept = request.headers.get("accept");
|
|
108
36
|
const isRscRequest = accept?.startsWith("text/x-component");
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
37
|
+
const isMarkdownRequest = markdownEnabled && !isRscRequest && (method === "GET" || method === "HEAD");
|
|
38
|
+
const url = new URL(request.url);
|
|
39
|
+
let markdownPathname = null;
|
|
40
|
+
if (isMarkdownRequest) {
|
|
41
|
+
markdownPathname = __REBASK_MARKDOWN_URLS ? getMarkdownPathname(url.pathname) : null;
|
|
42
|
+
if (markdownPathname !== null)
|
|
114
43
|
url.pathname = markdownPathname;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
44
|
+
}
|
|
45
|
+
const match = appMatcher.find(method, url.href);
|
|
46
|
+
const matched = match?.params ?? {};
|
|
47
|
+
if (markdownPathname !== null) {
|
|
48
|
+
if (match?.entry.type === "app") {
|
|
49
|
+
const variant = match.entry.markdown;
|
|
50
|
+
if (variant?.route.type === "page" && variant.route.markdownFilePath) {
|
|
51
|
+
return variant.handler(request, extractAppParams(variant.params, matched));
|
|
118
52
|
}
|
|
119
|
-
return markdownNotFound(request);
|
|
120
|
-
}
|
|
121
|
-
if (prefersMarkdown(accept)) {
|
|
122
|
-
const handler = markdownMatcher.find(method, request.url);
|
|
123
|
-
return handler ? handler(request) : markdownNotFound(request);
|
|
124
53
|
}
|
|
54
|
+
return markdownNotFound(request);
|
|
55
|
+
}
|
|
56
|
+
const wantsMarkdown = isMarkdownRequest && prefersMarkdown(accept);
|
|
57
|
+
if (!match) {
|
|
58
|
+
return wantsMarkdown
|
|
59
|
+
? markdownNotFound(request)
|
|
60
|
+
: handlePageRoute(request, buildDefaultNotFoundRoute(), {});
|
|
61
|
+
}
|
|
62
|
+
const entry = match.entry;
|
|
63
|
+
if (wantsMarkdown && entry.type === "app") {
|
|
64
|
+
const variant = entry.markdown;
|
|
65
|
+
return variant
|
|
66
|
+
? variant.handler(request, extractAppParams(variant.params, matched))
|
|
67
|
+
: markdownNotFound(request);
|
|
68
|
+
}
|
|
69
|
+
if (isRscRequest) {
|
|
70
|
+
const layout = entry.layout;
|
|
71
|
+
if (layout)
|
|
72
|
+
return layout.handler(request, extractAppParams(layout.params, matched));
|
|
73
|
+
}
|
|
74
|
+
if (entry.type === "app") {
|
|
75
|
+
const variant = entry.app;
|
|
76
|
+
return variant
|
|
77
|
+
? variant.handler(request, extractAppParams(variant.params, matched))
|
|
78
|
+
: handlePageRoute(request, buildDefaultNotFoundRoute(), {});
|
|
125
79
|
}
|
|
126
|
-
|
|
127
|
-
? layoutMatcher?.find(request.method, request.url)
|
|
128
|
-
: undefined;
|
|
129
|
-
const handler = layoutHandler ?? appMatcher.find(request.method, request.url);
|
|
130
|
-
return handler ? handler(request) : handlePageRoute(request, buildDefaultNotFoundRoute(), {});
|
|
80
|
+
return entry.app(request, matched);
|
|
131
81
|
};
|
|
132
82
|
const mainRouter = { handle: app, app, proxy: async () => null };
|
|
133
83
|
if (!resolvedProxyRouter)
|
|
@@ -140,10 +90,10 @@ function createRouter(pageRoutes, routeHandlerRoutes, layoutRoutes, resolvedProx
|
|
|
140
90
|
const rewriteUrl = result.headers.get(REWRITE_HEADER);
|
|
141
91
|
if (!rewriteUrl)
|
|
142
92
|
return applyCookies(result);
|
|
143
|
-
const
|
|
144
|
-
const
|
|
93
|
+
const reqUrl = new URL(req.url);
|
|
94
|
+
const rewrittenUrl = new URL(rewriteUrl, reqUrl);
|
|
145
95
|
let response;
|
|
146
|
-
if (rewrittenUrl.origin !==
|
|
96
|
+
if (rewrittenUrl.origin !== reqUrl.origin) {
|
|
147
97
|
response = await proxyExternal(rewrittenUrl, req, result, stashed);
|
|
148
98
|
}
|
|
149
99
|
else {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RouteParams, RouteSegment } from "../route-matcher.js";
|
|
2
|
+
export type EntryParams = {
|
|
3
|
+
pattern: string;
|
|
4
|
+
segments: RouteSegment[];
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Converts filesystem route segments into a rou3 pattern. Static text is escaped, and dynamic
|
|
8
|
+
* segments use generated `pN` keys because filesystem names are not always valid rou3 param names
|
|
9
|
+
* (e.g `[foo-bar]`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function appPattern(segments: RouteSegment[], includeGroups: boolean): {
|
|
12
|
+
pattern: string;
|
|
13
|
+
segments: RouteSegment[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Converts the raw params from an `appPattern` match into the route's original params, decoding
|
|
17
|
+
* dynamic values and splitting catch-all matches into decoded segment arrays.
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractAppParams(params: EntryParams, matched: Record<string, string>): RouteParams;
|
|
20
|
+
//# sourceMappingURL=rou3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rou3.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/rou3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAKpE,MAAM,MAAM,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAAA;AAEvE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,aAAa,EAAE,OAAO;;;EAmB1E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,WAAW,CAsBb"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const ROU3_SYNTAX = /[:*?+(){}]/g;
|
|
2
|
+
const escapeStatic = (value) => value.replace(ROU3_SYNTAX, "\\$&");
|
|
3
|
+
/**
|
|
4
|
+
* Converts filesystem route segments into a rou3 pattern. Static text is escaped, and dynamic
|
|
5
|
+
* segments use generated `pN` keys because filesystem names are not always valid rou3 param names
|
|
6
|
+
* (e.g `[foo-bar]`).
|
|
7
|
+
*/
|
|
8
|
+
export function appPattern(segments, includeGroups) {
|
|
9
|
+
const parts = [];
|
|
10
|
+
let index = 0;
|
|
11
|
+
for (const segment of segments) {
|
|
12
|
+
if (segment.type === "static") {
|
|
13
|
+
parts.push(escapeStatic(segment.value));
|
|
14
|
+
}
|
|
15
|
+
else if (segment.type === "group") {
|
|
16
|
+
if (includeGroups)
|
|
17
|
+
parts.push(escapeStatic(segment.value));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const name = `p${index++}`;
|
|
21
|
+
if (segment.type === "dynamic")
|
|
22
|
+
parts.push(`:${name}`);
|
|
23
|
+
else if (segment.type === "catch-all")
|
|
24
|
+
parts.push(`:${name}+`);
|
|
25
|
+
else
|
|
26
|
+
parts.push(`:${name}*`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { pattern: "/" + parts.join("/"), segments };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Converts the raw params from an `appPattern` match into the route's original params, decoding
|
|
33
|
+
* dynamic values and splitting catch-all matches into decoded segment arrays.
|
|
34
|
+
*/
|
|
35
|
+
export function extractAppParams(params, matched) {
|
|
36
|
+
const result = {};
|
|
37
|
+
let index = 0;
|
|
38
|
+
for (const segment of params.segments) {
|
|
39
|
+
if (segment.type === "dynamic") {
|
|
40
|
+
result[segment.name] = decodeURIComponent(matched[`p${index++}`]);
|
|
41
|
+
}
|
|
42
|
+
else if (segment.type === "catch-all" || segment.type === "optional-catch-all") {
|
|
43
|
+
const value = matched[`p${index++}`];
|
|
44
|
+
const parts = [];
|
|
45
|
+
if (value) {
|
|
46
|
+
for (const part of value.split("/")) {
|
|
47
|
+
if (part)
|
|
48
|
+
parts.push(decodeURIComponent(part));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
result[segment.name] = parts;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type LayoutRoute, type PageRoute, type RouteHandlerRoute } from "../route-matcher.js";
|
|
2
|
+
import type { AppEntry, AppHandler } from "./types.js";
|
|
3
|
+
export interface EntryHandlers {
|
|
4
|
+
page: (route: PageRoute) => AppHandler;
|
|
5
|
+
markdown: (route: PageRoute) => AppHandler;
|
|
6
|
+
routeHandler: (route: RouteHandlerRoute) => AppHandler;
|
|
7
|
+
layout: (route: LayoutRoute) => AppHandler;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildRouteEntries(pageRoutes: PageRoute[], routeHandlerRoutes: RouteHandlerRoute[], layoutRoutes: LayoutRoute[], imageEntry: {
|
|
10
|
+
pattern: string;
|
|
11
|
+
handler: AppHandler;
|
|
12
|
+
} | null, handlers: EntryHandlers): {
|
|
13
|
+
entries: AppEntry[];
|
|
14
|
+
markdownEnabled: boolean;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=route-entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-entries.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/route-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,KAAK,iBAAiB,EAEtB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEtD,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,UAAU,CAAA;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,UAAU,CAAA;IAC1C,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,UAAU,CAAA;IACtD,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,UAAU,CAAA;CAC1C;AAED,wBAAgB,iBAAiB,CAChC,UAAU,EAAE,SAAS,EAAE,EACvB,kBAAkB,EAAE,iBAAiB,EAAE,EACvC,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,EAC3D,QAAQ,EAAE,aAAa,GACrB;IAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CA2EnD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { HTTP_METHODS, } from "../route-matcher.js";
|
|
2
|
+
import { appPattern } from "./rou3.js";
|
|
3
|
+
export function buildRouteEntries(pageRoutes, routeHandlerRoutes, layoutRoutes, imageEntry, handlers) {
|
|
4
|
+
const entries = new Map();
|
|
5
|
+
const hasMarkdownRoutes = pageRoutes.some((route) => route.markdownFilePath);
|
|
6
|
+
const entryKey = (pattern, method) => `${pattern}\n${method}`;
|
|
7
|
+
function ensureEntry(pattern, method) {
|
|
8
|
+
const key = entryKey(pattern, method);
|
|
9
|
+
let entry = entries.get(key);
|
|
10
|
+
if (!entry) {
|
|
11
|
+
entry = { type: "app", methods: [method], pattern };
|
|
12
|
+
entries.set(key, entry);
|
|
13
|
+
}
|
|
14
|
+
return entry;
|
|
15
|
+
}
|
|
16
|
+
function addApp(route, methods, handler, variant) {
|
|
17
|
+
const params = appPattern(route.segments, route.type === "layout");
|
|
18
|
+
const handlerEntry = { handler, route, params };
|
|
19
|
+
for (const method of methods) {
|
|
20
|
+
const entry = ensureEntry(params.pattern, method);
|
|
21
|
+
if (entry.type === "image") {
|
|
22
|
+
// An image route can collide with a layout route. RSC still gives layout precedence.
|
|
23
|
+
if (variant === "layout" && !entry.layout)
|
|
24
|
+
entry.layout = handlerEntry;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!entry[variant])
|
|
28
|
+
entry[variant] = handlerEntry;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (imageEntry) {
|
|
32
|
+
entries.set(entryKey(imageEntry.pattern, "GET"), {
|
|
33
|
+
type: "image",
|
|
34
|
+
methods: ["GET"],
|
|
35
|
+
pattern: imageEntry.pattern,
|
|
36
|
+
app: imageEntry.handler,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
for (const route of pageRoutes) {
|
|
40
|
+
if (route.hasPage !== false) {
|
|
41
|
+
addApp(route, ["GET", "POST"], handlers.page(route), "app");
|
|
42
|
+
}
|
|
43
|
+
if (!hasMarkdownRoutes)
|
|
44
|
+
continue;
|
|
45
|
+
if (route.markdownFilePath) {
|
|
46
|
+
addApp(route, ["GET", "HEAD"], handlers.markdown(route), "markdown");
|
|
47
|
+
}
|
|
48
|
+
else if (route.hasPage !== false) {
|
|
49
|
+
addApp(route, ["GET"], handlers.page(route), "markdown");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
for (const route of routeHandlerRoutes) {
|
|
53
|
+
const handler = handlers.routeHandler(route);
|
|
54
|
+
addApp(route, HTTP_METHODS, handler, "app");
|
|
55
|
+
if (hasMarkdownRoutes)
|
|
56
|
+
addApp(route, HTTP_METHODS, handler, "markdown");
|
|
57
|
+
}
|
|
58
|
+
for (const route of layoutRoutes) {
|
|
59
|
+
const segments = [
|
|
60
|
+
{ type: "static", value: "_rebask" },
|
|
61
|
+
{ type: "static", value: "1" },
|
|
62
|
+
...route.segments,
|
|
63
|
+
];
|
|
64
|
+
addApp({ ...route, segments }, ["GET"], handlers.layout(route), "layout");
|
|
65
|
+
}
|
|
66
|
+
return { entries: [...entries.values()], markdownEnabled: hasMarkdownRoutes };
|
|
67
|
+
}
|