@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.9 → 3.5.0-ultramodern.91
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/cjs/cli/artifacts.js +157 -0
- package/dist/cjs/cli/index.js +8 -79
- package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +113 -0
- package/dist/cjs/cli/tanstackTypes/shared.js +123 -0
- package/dist/cjs/cli/tanstackTypes/source.js +255 -0
- package/dist/cjs/cli/tanstackTypes.js +4 -350
- package/dist/cjs/runtime/blockingSubscribe.js +57 -0
- package/dist/cjs/runtime/{pluginCore.js → clientBasepath.js} +12 -19
- package/dist/cjs/runtime/clientHydration.js +118 -0
- package/dist/cjs/runtime/dataMutation.js +11 -176
- package/dist/cjs/runtime/formData.js +116 -0
- package/dist/cjs/runtime/loaderBridge.js +7 -11
- package/dist/cjs/runtime/plugin.js +21 -125
- package/dist/cjs/runtime/plugin.node.js +45 -125
- package/dist/cjs/runtime/pluginShared.js +87 -0
- package/dist/cjs/runtime/prefetchLink.js +15 -2
- package/dist/cjs/runtime/register.js +3 -16
- package/dist/cjs/runtime/routeTree/components.js +102 -0
- package/dist/cjs/runtime/routeTree/construction.js +152 -0
- package/dist/cjs/runtime/routeTree/index.js +47 -0
- package/dist/cjs/runtime/routeTree/loaders.js +158 -0
- package/dist/cjs/runtime/routeTree/paths.js +57 -0
- package/dist/cjs/runtime/routeTree/staticData.js +63 -0
- package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
- package/dist/cjs/runtime/routeTree/types.js +18 -0
- package/dist/cjs/runtime/routeTree.js +7 -320
- package/dist/cjs/runtime/router.js +15 -2
- package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
- package/dist/cjs/runtime/rsc/ReplayableStream.js +0 -4
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
- package/dist/cjs/runtime/rsc/client.js +8 -25
- package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
- package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
- package/dist/cjs/runtime/rsc/payloadFetch.js +105 -0
- package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
- package/dist/cjs/runtime/rsc/payloadRoutes.js +94 -0
- package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
- package/dist/cjs/runtime/rsc/server.js +14 -18
- package/dist/cjs/runtime/rsc/shared.js +68 -0
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +1 -0
- package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
- package/dist/cjs/runtime/shared/isAbsoluteUrl.js +47 -0
- package/dist/cjs/runtime/ssrManagedTags.js +103 -0
- package/dist/cjs/runtime/ssrPreload.js +89 -0
- package/dist/cjs/runtime/ssrTypes.js +18 -0
- package/dist/cjs/runtime/state.js +1 -1
- package/dist/cjs/runtime/submitAction.js +161 -0
- package/dist/cjs/runtime/utils.js +49 -86
- package/dist/esm/cli/artifacts.mjs +103 -0
- package/dist/esm/cli/index.mjs +8 -82
- package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
- package/dist/esm/cli/tanstackTypes/shared.mjs +61 -0
- package/dist/esm/cli/tanstackTypes/source.mjs +207 -0
- package/dist/esm/cli/tanstackTypes.mjs +2 -339
- package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
- package/dist/esm/runtime/clientBasepath.mjs +10 -0
- package/dist/esm/runtime/clientHydration.mjs +71 -0
- package/dist/esm/runtime/dataMutation.mjs +2 -167
- package/dist/esm/runtime/formData.mjs +63 -0
- package/dist/esm/runtime/loaderBridge.mjs +5 -9
- package/dist/esm/runtime/plugin.mjs +14 -118
- package/dist/esm/runtime/plugin.node.mjs +41 -121
- package/dist/esm/runtime/pluginShared.mjs +40 -0
- package/dist/esm/runtime/prefetchLink.mjs +18 -5
- package/dist/esm/runtime/register.mjs +1 -14
- package/dist/esm/runtime/routeTree/components.mjs +55 -0
- package/dist/esm/runtime/routeTree/construction.mjs +111 -0
- package/dist/esm/runtime/routeTree/index.mjs +2 -0
- package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
- package/dist/esm/runtime/routeTree/paths.mjs +16 -0
- package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
- package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
- package/dist/esm/runtime/routeTree/types.mjs +0 -0
- package/dist/esm/runtime/routeTree.mjs +1 -318
- package/dist/esm/runtime/router.mjs +16 -2
- package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm/runtime/rsc/client.mjs +6 -26
- package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
- package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
- package/dist/esm/runtime/rsc/payloadFetch.mjs +55 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
- package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
- package/dist/esm/runtime/rsc/server.mjs +17 -21
- package/dist/esm/runtime/rsc/shared.mjs +21 -0
- package/dist/esm/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
- package/dist/esm/runtime/shared/isAbsoluteUrl.mjs +9 -0
- package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
- package/dist/esm/runtime/ssrPreload.mjs +51 -0
- package/dist/esm/runtime/ssrTypes.mjs +0 -0
- package/dist/esm/runtime/state.mjs +1 -1
- package/dist/esm/runtime/submitAction.mjs +120 -0
- package/dist/esm/runtime/utils.mjs +47 -75
- package/dist/esm-node/cli/artifacts.mjs +104 -0
- package/dist/esm-node/cli/index.mjs +8 -82
- package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
- package/dist/esm-node/cli/tanstackTypes/shared.mjs +62 -0
- package/dist/esm-node/cli/tanstackTypes/source.mjs +208 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
- package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
- package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
- package/dist/esm-node/runtime/clientHydration.mjs +72 -0
- package/dist/esm-node/runtime/dataMutation.mjs +2 -167
- package/dist/esm-node/runtime/formData.mjs +64 -0
- package/dist/esm-node/runtime/loaderBridge.mjs +5 -9
- package/dist/esm-node/runtime/plugin.mjs +14 -118
- package/dist/esm-node/runtime/plugin.node.mjs +41 -121
- package/dist/esm-node/runtime/pluginShared.mjs +41 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +18 -5
- package/dist/esm-node/runtime/register.mjs +1 -14
- package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
- package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
- package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
- package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
- package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
- package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
- package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
- package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
- package/dist/esm-node/runtime/routeTree.mjs +1 -318
- package/dist/esm-node/runtime/router.mjs +16 -2
- package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm-node/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm-node/runtime/rsc/client.mjs +6 -26
- package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
- package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
- package/dist/esm-node/runtime/rsc/payloadFetch.mjs +56 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
- package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
- package/dist/esm-node/runtime/rsc/server.mjs +17 -21
- package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
- package/dist/esm-node/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
- package/dist/esm-node/runtime/shared/isAbsoluteUrl.mjs +10 -0
- package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
- package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
- package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
- package/dist/esm-node/runtime/state.mjs +1 -1
- package/dist/esm-node/runtime/submitAction.mjs +121 -0
- package/dist/esm-node/runtime/utils.mjs +47 -75
- package/dist/types/cli/artifacts.d.ts +33 -0
- package/dist/types/cli/index.d.ts +2 -22
- package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
- package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
- package/dist/types/cli/tanstackTypes/source.d.ts +12 -0
- package/dist/types/cli/tanstackTypes.d.ts +3 -31
- package/dist/types/runtime/blockingSubscribe.d.ts +1 -0
- package/dist/types/runtime/clientBasepath.d.ts +1 -0
- package/dist/types/runtime/clientHydration.d.ts +10 -0
- package/dist/types/runtime/dataMutation.d.ts +3 -12
- package/dist/types/runtime/formData.d.ts +24 -0
- package/dist/types/runtime/loaderBridge.d.ts +2 -1
- package/dist/types/runtime/plugin.d.ts +1 -1
- package/dist/types/runtime/plugin.node.d.ts +1 -1
- package/dist/types/runtime/pluginShared.d.ts +38 -0
- package/dist/types/runtime/register.d.ts +10 -9
- package/dist/types/runtime/routeTree/components.d.ts +7 -0
- package/dist/types/runtime/routeTree/construction.d.ts +5 -0
- package/dist/types/runtime/routeTree/index.d.ts +2 -0
- package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
- package/dist/types/runtime/routeTree/paths.d.ts +3 -0
- package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
- package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
- package/dist/types/runtime/routeTree/types.d.ts +76 -0
- package/dist/types/runtime/routeTree.d.ts +1 -9
- package/dist/types/runtime/router.d.ts +6 -7
- package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
- package/dist/types/runtime/rsc/ReplayableStream.d.ts +3 -2
- package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
- package/dist/types/runtime/rsc/SlotContext.d.ts +2 -1
- package/dist/types/runtime/rsc/client.d.ts +2 -0
- package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
- package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
- package/dist/types/runtime/rsc/payloadFetch.d.ts +8 -0
- package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
- package/dist/types/runtime/rsc/payloadRoutes.d.ts +40 -0
- package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
- package/dist/types/runtime/rsc/shared.d.ts +18 -0
- package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
- package/dist/types/runtime/shared/isAbsoluteUrl.d.ts +1 -0
- package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
- package/dist/types/runtime/ssrPreload.d.ts +2 -0
- package/dist/types/runtime/ssrTypes.d.ts +44 -0
- package/dist/types/runtime/state.d.ts +1 -1
- package/dist/types/runtime/submitAction.d.ts +14 -0
- package/dist/types/runtime/types.d.ts +4 -10
- package/dist/types/runtime/utils.d.ts +4 -24
- package/package.json +37 -17
- package/rstest.config.mts +23 -0
- package/src/cli/artifacts.ts +255 -0
- package/src/cli/index.ts +7 -185
- package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
- package/src/cli/tanstackTypes/shared.ts +113 -0
- package/src/cli/tanstackTypes/source.ts +414 -0
- package/src/cli/tanstackTypes.ts +4 -647
- package/src/runtime/blockingSubscribe.ts +48 -0
- package/src/runtime/clientBasepath.ts +12 -0
- package/src/runtime/clientHydration.ts +149 -0
- package/src/runtime/dataMutation.tsx +9 -306
- package/src/runtime/formData.ts +153 -0
- package/src/runtime/loaderBridge.ts +11 -12
- package/src/runtime/plugin.node.tsx +76 -291
- package/src/runtime/plugin.tsx +21 -257
- package/src/runtime/pluginShared.ts +112 -0
- package/src/runtime/prefetchLink.tsx +78 -15
- package/src/runtime/register.ts +10 -42
- package/src/runtime/routeTree/components.ts +130 -0
- package/src/runtime/routeTree/construction.ts +238 -0
- package/src/runtime/routeTree/index.ts +7 -0
- package/src/runtime/routeTree/loaders.ts +232 -0
- package/src/runtime/routeTree/paths.ts +36 -0
- package/src/runtime/routeTree/staticData.ts +66 -0
- package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
- package/src/runtime/routeTree/types.ts +87 -0
- package/src/runtime/routeTree.ts +5 -750
- package/src/runtime/router.ts +35 -7
- package/src/runtime/rsc/CompositeComponent.tsx +29 -20
- package/src/runtime/rsc/ReplayableStream.ts +2 -2
- package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
- package/src/runtime/rsc/SlotContext.tsx +1 -1
- package/src/runtime/rsc/client.tsx +12 -40
- package/src/runtime/rsc/flightSerialization.ts +158 -0
- package/src/runtime/rsc/payloadErrors.ts +73 -0
- package/src/runtime/rsc/payloadFetch.ts +92 -0
- package/src/runtime/rsc/payloadRouter.ts +29 -234
- package/src/runtime/rsc/payloadRoutes.ts +122 -0
- package/src/runtime/rsc/payloadStorage.ts +35 -0
- package/src/runtime/rsc/server.tsx +20 -29
- package/src/runtime/rsc/shared.ts +70 -0
- package/src/runtime/rsc/slotUsageSanitizer.ts +4 -0
- package/src/runtime/rsc/treeGetter.tsx +52 -0
- package/src/runtime/shared/isAbsoluteUrl.ts +8 -0
- package/src/runtime/ssrManagedTags.ts +107 -0
- package/src/runtime/ssrPreload.ts +125 -0
- package/src/runtime/ssrTypes.ts +51 -0
- package/src/runtime/state.ts +9 -3
- package/src/runtime/submitAction.ts +201 -0
- package/src/runtime/types.ts +4 -18
- package/src/runtime/utils.tsx +76 -110
- package/src/types/react-server-dom-rspack.d.ts +56 -0
- package/tests/castRatchet.test.ts +85 -0
- package/tests/realm-isolation.test.ts +114 -0
- package/tests/router/cli.test.ts +7 -0
- package/tests/router/clientHydration.test.tsx +61 -0
- package/tests/router/dataMutation.test.tsx +59 -0
- package/tests/router/fixtures/legacyRuntimeRouter.ts +10 -0
- package/tests/router/fixtures/router-gen.golden.txt +71 -0
- package/tests/router/fixtures/router-gen.oxlint.json +5 -0
- package/tests/router/flightSerialization.roundtrip.test.tsx +137 -0
- package/tests/router/generateRouteArtifacts.test.ts +106 -0
- package/tests/router/hooks.test.ts +14 -0
- package/tests/router/loaderBridge.test.ts +21 -0
- package/tests/router/prefetchLink.test.tsx +106 -59
- package/tests/router/prefetchLinkPreload.test.tsx +85 -0
- package/tests/router/register.test.ts +1 -39
- package/tests/router/routeTree.test.ts +51 -11
- package/tests/router/routerCompatibility.test.ts +245 -0
- package/tests/router/rsc.test.tsx +189 -0
- package/tests/router/rscPayloadRouterMatrix.test.ts +197 -0
- package/tests/router/slotUsageSanitizer.test.ts +23 -0
- package/tests/router/ssrPreload.test.ts +30 -0
- package/tests/router/tanstackTypes.test.ts +298 -1
- package/dist/esm/runtime/pluginCore.mjs +0 -14
- package/dist/esm-node/runtime/pluginCore.mjs +0 -15
- package/dist/types/runtime/pluginCore.d.ts +0 -21
- package/src/runtime/pluginCore.ts +0 -48
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__setTanstackRscPayloadDecoderForTests,
|
|
3
|
+
createTanstackRscServerPayload,
|
|
4
|
+
handleTanstackRscRedirect,
|
|
5
|
+
loadTanstackRscRouteData,
|
|
6
|
+
} from '../../src/runtime/rsc/payloadRouter';
|
|
7
|
+
|
|
8
|
+
function createPayload(
|
|
9
|
+
routeId: string,
|
|
10
|
+
loaderData: unknown,
|
|
11
|
+
options: { errors?: Record<string, unknown> | null } = {},
|
|
12
|
+
) {
|
|
13
|
+
return {
|
|
14
|
+
type: 'render',
|
|
15
|
+
actionData: null,
|
|
16
|
+
errors: options.errors ?? null,
|
|
17
|
+
loaderData: loaderData === undefined ? {} : { [routeId]: loaderData },
|
|
18
|
+
location: { href: routeId },
|
|
19
|
+
routes: [{ id: routeId, hasLoader: true }],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function decodeJsonPayload(stream: ReadableStream<Uint8Array>) {
|
|
24
|
+
return JSON.parse(await new Response(stream).text());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('tanstack rsc payload router matrix', () => {
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
__setTanstackRscPayloadDecoderForTests();
|
|
30
|
+
rstest.restoreAllMocks();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('normalizes redirect basenames while preserving status and non-location headers', () => {
|
|
34
|
+
const scenarios = [
|
|
35
|
+
{
|
|
36
|
+
location: '/base',
|
|
37
|
+
name: 'exact basename',
|
|
38
|
+
redirect: '/',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
location: '/base/login?from=%2Fbase',
|
|
42
|
+
name: 'leading basename',
|
|
43
|
+
redirect: '/login?from=%2Fbase',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
location: '/shop/base/login',
|
|
47
|
+
name: 'mid-path basename',
|
|
48
|
+
redirect: '/shop/base/login',
|
|
49
|
+
},
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
for (const scenario of scenarios) {
|
|
53
|
+
const response = handleTanstackRscRedirect(
|
|
54
|
+
new Headers({
|
|
55
|
+
Location: scenario.location,
|
|
56
|
+
'X-Trace': scenario.name,
|
|
57
|
+
}),
|
|
58
|
+
'/base',
|
|
59
|
+
307,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
expect(response.status).toBe(307);
|
|
63
|
+
expect(response.headers.get('Location')).toBeNull();
|
|
64
|
+
expect(response.headers.get('X-Modernjs-BaseUrl')).toBe('/base');
|
|
65
|
+
expect(response.headers.get('X-Modernjs-Redirect')).toBe(
|
|
66
|
+
scenario.redirect,
|
|
67
|
+
);
|
|
68
|
+
expect(response.headers.get('X-Trace')).toBe(scenario.name);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('separates payload fetch cache entries by URL and request method', async () => {
|
|
73
|
+
const payloads = [
|
|
74
|
+
createPayload('/resource', { method: 'GET' }),
|
|
75
|
+
createPayload('/resource', { method: 'POST' }),
|
|
76
|
+
];
|
|
77
|
+
let payloadIndex = 0;
|
|
78
|
+
const fetchMock = rstest.fn(() =>
|
|
79
|
+
Promise.resolve(new Response(JSON.stringify(payloads[payloadIndex++]))),
|
|
80
|
+
);
|
|
81
|
+
rstest.stubGlobal('fetch', fetchMock);
|
|
82
|
+
__setTanstackRscPayloadDecoderForTests(decodeJsonPayload);
|
|
83
|
+
|
|
84
|
+
const [getData, postData] = await Promise.all([
|
|
85
|
+
loadTanstackRscRouteData({
|
|
86
|
+
loadClientData: async () => ({ fallback: 'get' }),
|
|
87
|
+
request: new Request('http://localhost/resource', { method: 'GET' }),
|
|
88
|
+
routeId: '/resource',
|
|
89
|
+
}),
|
|
90
|
+
loadTanstackRscRouteData({
|
|
91
|
+
loadClientData: async () => ({ fallback: 'post' }),
|
|
92
|
+
request: new Request('http://localhost/resource', { method: 'POST' }),
|
|
93
|
+
routeId: '/resource',
|
|
94
|
+
}),
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
expect(getData).toEqual({ method: 'GET' });
|
|
98
|
+
expect(postData).toEqual({ method: 'POST' });
|
|
99
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
100
|
+
expect(fetchMock.mock.calls.map(call => call[0])).toEqual([
|
|
101
|
+
'http://localhost/resource',
|
|
102
|
+
'http://localhost/resource',
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('rethrows matched route errors from the decoded payload', async () => {
|
|
107
|
+
const routeError = new Error('route loader failed');
|
|
108
|
+
const payload = createPayload('/broken', undefined, {
|
|
109
|
+
errors: { '/broken': routeError },
|
|
110
|
+
});
|
|
111
|
+
rstest.stubGlobal(
|
|
112
|
+
'fetch',
|
|
113
|
+
rstest.fn(() => Promise.resolve(new Response('payload'))),
|
|
114
|
+
);
|
|
115
|
+
__setTanstackRscPayloadDecoderForTests(async () => payload);
|
|
116
|
+
|
|
117
|
+
await expect(
|
|
118
|
+
loadTanstackRscRouteData({
|
|
119
|
+
loadClientData: async () => ({ fallback: true }),
|
|
120
|
+
request: new Request('http://localhost/broken'),
|
|
121
|
+
routeId: '/broken',
|
|
122
|
+
}),
|
|
123
|
+
).rejects.toBe(routeError);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('returns undefined for route ids missing from the decoded payload', async () => {
|
|
127
|
+
const loadClientData = rstest.fn(async () => ({ fallback: true }));
|
|
128
|
+
const payload = createPayload('/known', { known: true });
|
|
129
|
+
rstest.stubGlobal(
|
|
130
|
+
'fetch',
|
|
131
|
+
rstest.fn(() => Promise.resolve(new Response('payload'))),
|
|
132
|
+
);
|
|
133
|
+
__setTanstackRscPayloadDecoderForTests(async () => payload);
|
|
134
|
+
|
|
135
|
+
await expect(
|
|
136
|
+
loadTanstackRscRouteData({
|
|
137
|
+
loadClientData,
|
|
138
|
+
request: new Request('http://localhost/missing'),
|
|
139
|
+
routeId: '/missing',
|
|
140
|
+
}),
|
|
141
|
+
).resolves.toBeUndefined();
|
|
142
|
+
expect(loadClientData).not.toHaveBeenCalled();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('omits server payload matches with no route identity', () => {
|
|
146
|
+
const payload = createTanstackRscServerPayload({
|
|
147
|
+
state: {
|
|
148
|
+
location: { href: '/kept' },
|
|
149
|
+
matches: [
|
|
150
|
+
{
|
|
151
|
+
loaderData: { omitted: true },
|
|
152
|
+
params: {},
|
|
153
|
+
pathname: '/missing-id',
|
|
154
|
+
pathnameBase: '/missing-id',
|
|
155
|
+
route: {
|
|
156
|
+
options: {
|
|
157
|
+
path: 'missing-id',
|
|
158
|
+
staticData: { modernRouteHasLoader: true },
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
loaderData: { kept: true },
|
|
164
|
+
params: {},
|
|
165
|
+
pathname: '/kept',
|
|
166
|
+
pathnameBase: '/kept',
|
|
167
|
+
route: {
|
|
168
|
+
id: '/kept',
|
|
169
|
+
options: {
|
|
170
|
+
path: 'kept',
|
|
171
|
+
staticData: { modernRouteHasLoader: true },
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
expect(payload.loaderData).toEqual({ '/kept': { kept: true } });
|
|
180
|
+
expect(payload.routes).toEqual([
|
|
181
|
+
{
|
|
182
|
+
handle: undefined,
|
|
183
|
+
hasAction: false,
|
|
184
|
+
hasClientLoader: false,
|
|
185
|
+
hasErrorBoundary: false,
|
|
186
|
+
hasLoader: true,
|
|
187
|
+
id: '/kept',
|
|
188
|
+
index: undefined,
|
|
189
|
+
params: {},
|
|
190
|
+
parentId: undefined,
|
|
191
|
+
path: 'kept',
|
|
192
|
+
pathname: '/kept',
|
|
193
|
+
pathnameBase: '/kept',
|
|
194
|
+
},
|
|
195
|
+
]);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { sanitizeSlotArgs } from '../../src/runtime/rsc/slotUsageSanitizer';
|
|
2
|
+
|
|
3
|
+
describe('RSC slot usage sanitizer', () => {
|
|
4
|
+
test('redacts callable slot args without serializing function source', () => {
|
|
5
|
+
function tokenFactory() {
|
|
6
|
+
return 'token-secret';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const args = sanitizeSlotArgs([
|
|
10
|
+
tokenFactory,
|
|
11
|
+
{ nested: tokenFactory },
|
|
12
|
+
[tokenFactory],
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
expect(args).toEqual([
|
|
16
|
+
'[Function]',
|
|
17
|
+
{ nested: '[Function]' },
|
|
18
|
+
['[Function]'],
|
|
19
|
+
]);
|
|
20
|
+
expect(JSON.stringify(args)).not.toContain('token-secret');
|
|
21
|
+
expect(JSON.stringify(args)).not.toContain('tokenFactory');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { preloadMatchedRouteComponents } from '../../src/runtime/ssrPreload';
|
|
2
|
+
|
|
3
|
+
describe('preloadMatchedRouteComponents', () => {
|
|
4
|
+
test('preloads each component identity once per SSR pass', async () => {
|
|
5
|
+
const sharedComponent = Object.assign(() => null, {
|
|
6
|
+
preload: rstest.fn(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
await preloadMatchedRouteComponents({
|
|
10
|
+
routesById: {
|
|
11
|
+
child: {
|
|
12
|
+
options: {
|
|
13
|
+
component: sharedComponent,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
root: {
|
|
17
|
+
options: {
|
|
18
|
+
component: sharedComponent,
|
|
19
|
+
pendingComponent: sharedComponent,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
state: {
|
|
24
|
+
matches: [{ routeId: 'root' }, { routeId: 'child' }],
|
|
25
|
+
},
|
|
26
|
+
} as never);
|
|
27
|
+
|
|
28
|
+
expect(sharedComponent.preload).toHaveBeenCalledTimes(1);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -1,19 +1,172 @@
|
|
|
1
1
|
import { execFile } from 'node:child_process';
|
|
2
|
-
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
|
+
import { isRedirect } from '@tanstack/react-router';
|
|
7
|
+
|
|
8
|
+
const resolverDelays = new Map<string, number>();
|
|
9
|
+
|
|
10
|
+
rstest.mock('../../src/cli/tanstackTypes/shared', () => {
|
|
11
|
+
const actual = rstest.requireActual(
|
|
12
|
+
'../../src/cli/tanstackTypes/shared',
|
|
13
|
+
) as typeof import('../../src/cli/tanstackTypes/shared');
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...actual,
|
|
17
|
+
resolveFileNoExt: async (inputNoExtPath: string) => {
|
|
18
|
+
const normalized = inputNoExtPath.replaceAll('\\', '/');
|
|
19
|
+
const delay =
|
|
20
|
+
[...resolverDelays.entries()].find(([suffix]) =>
|
|
21
|
+
normalized.endsWith(suffix),
|
|
22
|
+
)?.[1] ?? 0;
|
|
23
|
+
|
|
24
|
+
if (delay > 0) {
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return actual.resolveFileNoExt(inputNoExtPath);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
6
33
|
import {
|
|
7
34
|
collectCanonicalRoutesForEntry,
|
|
8
35
|
generateTanstackRouterTypesSourceForEntry,
|
|
9
36
|
} from '../../src/cli/tanstackTypes';
|
|
37
|
+
import { throwTanstackRedirect } from '../../src/runtime/loaderBridge';
|
|
10
38
|
|
|
11
39
|
const execFileAsync = promisify(execFile);
|
|
40
|
+
const routerGenGoldenPath = path.join(
|
|
41
|
+
__dirname,
|
|
42
|
+
'fixtures',
|
|
43
|
+
'router-gen.golden.txt',
|
|
44
|
+
);
|
|
45
|
+
const routerGenOxlintConfigPath = path.join(
|
|
46
|
+
__dirname,
|
|
47
|
+
'fixtures',
|
|
48
|
+
'router-gen.oxlint.json',
|
|
49
|
+
);
|
|
50
|
+
const oxlintCliPath = path.resolve(
|
|
51
|
+
__dirname,
|
|
52
|
+
'../../../../toolkit/code-tools/node_modules/oxlint/bin/oxlint',
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
type RedirectLike = {
|
|
56
|
+
options?: {
|
|
57
|
+
href?: string;
|
|
58
|
+
to?: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function catchThrown(fn: () => unknown): unknown {
|
|
63
|
+
try {
|
|
64
|
+
fn();
|
|
65
|
+
} catch (err) {
|
|
66
|
+
return err;
|
|
67
|
+
}
|
|
68
|
+
throw new Error('expected function to throw');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function extractRouteGenerationOrder(source: string) {
|
|
72
|
+
return source.split('\n').filter(line => {
|
|
73
|
+
return (
|
|
74
|
+
line.startsWith('import component_') ||
|
|
75
|
+
line.startsWith('const route_') ||
|
|
76
|
+
line.includes('component: component_') ||
|
|
77
|
+
line.startsWith('export const routeTree')
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function writeGoldenRouterFixture(srcDirectory: string) {
|
|
83
|
+
const files = new Map([
|
|
84
|
+
[
|
|
85
|
+
'routes/(app)/layout.tsx',
|
|
86
|
+
'export default function AppLayout() { return null; }',
|
|
87
|
+
],
|
|
88
|
+
[
|
|
89
|
+
'routes/(app)/users/(userId)/page.tsx',
|
|
90
|
+
'export default function UserPage() { return null; }',
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
'routes/(app)/users/(userId)/page.data.ts',
|
|
94
|
+
[
|
|
95
|
+
'export const loader = () => ({ userId: "42" });',
|
|
96
|
+
'export const action = () => Response.json({ ok: true });',
|
|
97
|
+
].join('\n'),
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
'routes/(app)/docs/splat.tsx',
|
|
101
|
+
'export default function DocsSplatPage() { return null; }',
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
'routes/search.contract.ts',
|
|
105
|
+
[
|
|
106
|
+
'export const validateSearch = (search: { tab?: string }) => ({ tab: search.tab ?? "overview" });',
|
|
107
|
+
'export const loaderDeps = ({ search }: { search: { tab: string } }) => ({ tab: search.tab });',
|
|
108
|
+
].join('\n'),
|
|
109
|
+
],
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
for (const [relativePath, contents] of files) {
|
|
113
|
+
const filePath = path.join(srcDirectory, relativePath);
|
|
114
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
115
|
+
await writeFile(filePath, contents);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function generateGoldenRouterGen(srcDirectory: string) {
|
|
120
|
+
await writeGoldenRouterFixture(srcDirectory);
|
|
121
|
+
|
|
122
|
+
const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
|
|
123
|
+
appContext: {
|
|
124
|
+
srcDirectory,
|
|
125
|
+
internalSrcAlias: '@/_',
|
|
126
|
+
} as any,
|
|
127
|
+
entryName: 'golden',
|
|
128
|
+
routes: [
|
|
129
|
+
{
|
|
130
|
+
type: 'nested',
|
|
131
|
+
id: 'layout',
|
|
132
|
+
isRoot: true,
|
|
133
|
+
children: [
|
|
134
|
+
{
|
|
135
|
+
type: 'nested',
|
|
136
|
+
id: '(app)/layout',
|
|
137
|
+
_component: '@/_/routes/(app)/layout',
|
|
138
|
+
children: [
|
|
139
|
+
{
|
|
140
|
+
type: 'nested',
|
|
141
|
+
id: '(app)/users/(userId)/page',
|
|
142
|
+
path: 'users/:userId',
|
|
143
|
+
_component: '@/_/routes/(app)/users/(userId)/page',
|
|
144
|
+
data: '@/_/routes/(app)/users/(userId)/page.data',
|
|
145
|
+
action: '@/_/routes/(app)/users/(userId)/page.data',
|
|
146
|
+
validateSearch: '@/_/routes/search.contract',
|
|
147
|
+
loaderDeps: '@/_/routes/search.contract',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'nested',
|
|
151
|
+
id: '(app)/docs/splat/page',
|
|
152
|
+
path: 'docs/*',
|
|
153
|
+
_component: '@/_/routes/(app)/docs/splat',
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
] as any,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return routerGenTs;
|
|
163
|
+
}
|
|
12
164
|
|
|
13
165
|
describe('tanstack router type generation', () => {
|
|
14
166
|
let tempDir: string | undefined;
|
|
15
167
|
|
|
16
168
|
afterEach(async () => {
|
|
169
|
+
resolverDelays.clear();
|
|
17
170
|
if (tempDir) {
|
|
18
171
|
await rm(tempDir, { recursive: true, force: true });
|
|
19
172
|
tempDir = undefined;
|
|
@@ -77,6 +230,15 @@ describe('tanstack router type generation', () => {
|
|
|
77
230
|
expect(routerGenTs).not.toContain('function modernLoaderToTanstack');
|
|
78
231
|
expect(routerGenTs).not.toContain('function createRouteStaticData');
|
|
79
232
|
expect(routerGenTs).not.toContain('function throwTanstackRedirect');
|
|
233
|
+
expect(routerGenTs).not.toContain('new URL(target)');
|
|
234
|
+
expect(routerGenTs).not.toContain('redirect({ to: target })');
|
|
235
|
+
|
|
236
|
+
const redirectError = catchThrown(() =>
|
|
237
|
+
throwTanstackRedirect('https://example.com/absolute'),
|
|
238
|
+
) as RedirectLike;
|
|
239
|
+
expect(isRedirect(redirectError)).toBe(true);
|
|
240
|
+
expect(redirectError.options?.href).toBe('https://example.com/absolute');
|
|
241
|
+
expect(redirectError.options?.to).toBeUndefined();
|
|
80
242
|
});
|
|
81
243
|
|
|
82
244
|
test('emits resolvable relative component imports for routes carrying _component', async () => {
|
|
@@ -167,6 +329,141 @@ describe('tanstack router type generation', () => {
|
|
|
167
329
|
expect(dataOnlyRoute).not.toContain('component:');
|
|
168
330
|
});
|
|
169
331
|
|
|
332
|
+
test('keeps generated source stable when route module resolution races', async () => {
|
|
333
|
+
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
|
|
334
|
+
const srcDirectory = path.join(tempDir, 'src');
|
|
335
|
+
|
|
336
|
+
for (const componentFile of [
|
|
337
|
+
'routes/slow-page.tsx',
|
|
338
|
+
'routes/fast-page.tsx',
|
|
339
|
+
'routes/shared-page.tsx',
|
|
340
|
+
]) {
|
|
341
|
+
const componentPath = path.join(srcDirectory, componentFile);
|
|
342
|
+
await mkdir(path.dirname(componentPath), { recursive: true });
|
|
343
|
+
await writeFile(
|
|
344
|
+
componentPath,
|
|
345
|
+
'export default function Page() { return null; }',
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const routes = [
|
|
350
|
+
{
|
|
351
|
+
type: 'nested',
|
|
352
|
+
id: 'layout',
|
|
353
|
+
isRoot: true,
|
|
354
|
+
children: [
|
|
355
|
+
{
|
|
356
|
+
type: 'nested',
|
|
357
|
+
id: 'slow/page',
|
|
358
|
+
path: 'slow',
|
|
359
|
+
_component: '@/_/routes/slow-page',
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
type: 'nested',
|
|
363
|
+
id: 'fast/page',
|
|
364
|
+
path: 'fast',
|
|
365
|
+
_component: '@/_/routes/fast-page',
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
type: 'nested',
|
|
369
|
+
id: 'shared-a/page',
|
|
370
|
+
path: 'shared-a',
|
|
371
|
+
_component: '@/_/routes/shared-page',
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
type: 'nested',
|
|
375
|
+
id: 'shared-b/page',
|
|
376
|
+
path: 'shared-b',
|
|
377
|
+
_component: '@/_/routes/shared-page',
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
},
|
|
381
|
+
] as any;
|
|
382
|
+
|
|
383
|
+
const generateWithResolverDelays = async (
|
|
384
|
+
delays: Record<string, number>,
|
|
385
|
+
) => {
|
|
386
|
+
resolverDelays.clear();
|
|
387
|
+
for (const [suffix, delay] of Object.entries(delays)) {
|
|
388
|
+
resolverDelays.set(suffix, delay);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
|
|
392
|
+
appContext: {
|
|
393
|
+
srcDirectory,
|
|
394
|
+
internalSrcAlias: '@/_',
|
|
395
|
+
} as any,
|
|
396
|
+
entryName: 'index',
|
|
397
|
+
routes,
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
return routerGenTs;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const sequentialOutput = await generateWithResolverDelays({});
|
|
404
|
+
const racedOutput = await generateWithResolverDelays({
|
|
405
|
+
'/routes/slow-page': 25,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
expect(
|
|
409
|
+
racedOutput.match(/from "\.\.\/\.\.\/routes\/shared-page";/g),
|
|
410
|
+
).toHaveLength(1);
|
|
411
|
+
expect(extractRouteGenerationOrder(racedOutput)).toEqual(
|
|
412
|
+
extractRouteGenerationOrder(sequentialOutput),
|
|
413
|
+
);
|
|
414
|
+
expect(racedOutput).toBe(sequentialOutput);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
test('matches checked-in router.gen golden output', async () => {
|
|
418
|
+
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
|
|
419
|
+
const srcDirectory = path.join(tempDir, 'src');
|
|
420
|
+
const routerGenTs = await generateGoldenRouterGen(srcDirectory);
|
|
421
|
+
|
|
422
|
+
if (process.env.UPDATE_TANSTACK_ROUTER_GOLDEN === '1') {
|
|
423
|
+
await mkdir(path.dirname(routerGenGoldenPath), { recursive: true });
|
|
424
|
+
await writeFile(routerGenGoldenPath, routerGenTs);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
await expect(readFile(routerGenGoldenPath, 'utf8')).resolves.toBe(
|
|
428
|
+
routerGenTs,
|
|
429
|
+
);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
test('emits suppression-free router source that passes the generated-artifact lint fixture', async () => {
|
|
433
|
+
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
|
|
434
|
+
const srcDirectory = path.join(tempDir, 'src');
|
|
435
|
+
const routerGenTs = await generateGoldenRouterGen(srcDirectory);
|
|
436
|
+
const routerGenPath = path.join(
|
|
437
|
+
srcDirectory,
|
|
438
|
+
'modern-tanstack',
|
|
439
|
+
'golden',
|
|
440
|
+
'router.gen.ts',
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
await mkdir(path.dirname(routerGenPath), { recursive: true });
|
|
444
|
+
await writeFile(routerGenPath, routerGenTs);
|
|
445
|
+
|
|
446
|
+
expect(routerGenTs).not.toContain('eslint-disable');
|
|
447
|
+
|
|
448
|
+
const { stderr, stdout } = await execFileAsync(
|
|
449
|
+
process.execPath,
|
|
450
|
+
[
|
|
451
|
+
oxlintCliPath,
|
|
452
|
+
routerGenPath,
|
|
453
|
+
'--config',
|
|
454
|
+
routerGenOxlintConfigPath,
|
|
455
|
+
'--no-ignore',
|
|
456
|
+
'--report-unused-disable-directives-severity',
|
|
457
|
+
'error',
|
|
458
|
+
'--format',
|
|
459
|
+
'unix',
|
|
460
|
+
],
|
|
461
|
+
{ cwd: tempDir },
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
expect(`${stdout}${stderr}`).toBe('');
|
|
465
|
+
});
|
|
466
|
+
|
|
170
467
|
test('typechecks generated TanStack search contracts', async () => {
|
|
171
468
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
|
|
172
469
|
const srcDirectory = path.join(tempDir, 'src');
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
|
|
2
|
-
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
|
-
function getMergedRouterConfig(api, userConfig) {
|
|
4
|
-
const pluginConfig = api.getRuntimeConfig();
|
|
5
|
-
return merge(pluginConfig.router || {}, userConfig);
|
|
6
|
-
}
|
|
7
|
-
function getFinalRouteConfig(mergedConfig) {
|
|
8
|
-
return {
|
|
9
|
-
routes: getGlobalRoutes(),
|
|
10
|
-
globalApp: getGlobalLayoutApp(),
|
|
11
|
-
...mergedConfig.routesConfig
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export { getFinalRouteConfig, getMergedRouterConfig };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
import { getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
|
|
3
|
-
import { merge } from "@modern-js/runtime-utils/merge";
|
|
4
|
-
function getMergedRouterConfig(api, userConfig) {
|
|
5
|
-
const pluginConfig = api.getRuntimeConfig();
|
|
6
|
-
return merge(pluginConfig.router || {}, userConfig);
|
|
7
|
-
}
|
|
8
|
-
function getFinalRouteConfig(mergedConfig) {
|
|
9
|
-
return {
|
|
10
|
-
routes: getGlobalRoutes(),
|
|
11
|
-
globalApp: getGlobalLayoutApp(),
|
|
12
|
-
...mergedConfig.routesConfig
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export { getFinalRouteConfig, getMergedRouterConfig };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
|
|
2
|
-
import type { RuntimePluginAPI } from '@modern-js/plugin/runtime';
|
|
3
|
-
import { type TInternalRuntimeContext } from '@modern-js/runtime/context';
|
|
4
|
-
import type { RouterExtendsHooks } from './hooks';
|
|
5
|
-
import type { RouterConfig } from './types';
|
|
6
|
-
export type TanstackRouterRuntimeConfig = {
|
|
7
|
-
plugins?: TanstackRouterRuntimePlugin[];
|
|
8
|
-
router?: Partial<RouterConfig>;
|
|
9
|
-
[key: string]: unknown;
|
|
10
|
-
};
|
|
11
|
-
type TanstackRouterRuntimeExtends = Required<RuntimePluginExtends<TanstackRouterRuntimeConfig, TInternalRuntimeContext>> & {
|
|
12
|
-
extendHooks: RouterExtendsHooks;
|
|
13
|
-
};
|
|
14
|
-
export type TanstackRouterPluginAPI = RuntimePluginAPI<TanstackRouterRuntimeExtends>;
|
|
15
|
-
export type TanstackRouterRuntimePlugin = Plugin<TanstackRouterPluginAPI, TInternalRuntimeContext>;
|
|
16
|
-
export declare function getMergedRouterConfig(api: TanstackRouterPluginAPI, userConfig: Partial<RouterConfig>): RouterConfig;
|
|
17
|
-
export declare function getFinalRouteConfig(mergedConfig: RouterConfig): {
|
|
18
|
-
routes: (import("@modern-js/types").NestedRoute<string | (() => JSX.Element)> | import("@modern-js/types").PageRoute)[] | undefined;
|
|
19
|
-
globalApp: import("react").ComponentClass<{}, any> | import("react").FunctionComponent<{}> | undefined;
|
|
20
|
-
};
|
|
21
|
-
export {};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
|
|
2
|
-
import type { RuntimePluginAPI } from '@modern-js/plugin/runtime';
|
|
3
|
-
import {
|
|
4
|
-
getGlobalLayoutApp,
|
|
5
|
-
getGlobalRoutes,
|
|
6
|
-
type TInternalRuntimeContext,
|
|
7
|
-
} from '@modern-js/runtime/context';
|
|
8
|
-
import { merge } from '@modern-js/runtime-utils/merge';
|
|
9
|
-
import type { RouterExtendsHooks } from './hooks';
|
|
10
|
-
import type { RouterConfig } from './types';
|
|
11
|
-
|
|
12
|
-
export type TanstackRouterRuntimeConfig = {
|
|
13
|
-
plugins?: TanstackRouterRuntimePlugin[];
|
|
14
|
-
router?: Partial<RouterConfig>;
|
|
15
|
-
[key: string]: unknown;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
type TanstackRouterRuntimeExtends = Required<
|
|
19
|
-
RuntimePluginExtends<TanstackRouterRuntimeConfig, TInternalRuntimeContext>
|
|
20
|
-
> & {
|
|
21
|
-
extendHooks: RouterExtendsHooks;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type TanstackRouterPluginAPI =
|
|
25
|
-
RuntimePluginAPI<TanstackRouterRuntimeExtends>;
|
|
26
|
-
|
|
27
|
-
export type TanstackRouterRuntimePlugin = Plugin<
|
|
28
|
-
TanstackRouterPluginAPI,
|
|
29
|
-
TInternalRuntimeContext
|
|
30
|
-
>;
|
|
31
|
-
|
|
32
|
-
export function getMergedRouterConfig(
|
|
33
|
-
api: TanstackRouterPluginAPI,
|
|
34
|
-
userConfig: Partial<RouterConfig>,
|
|
35
|
-
): RouterConfig {
|
|
36
|
-
const pluginConfig = api.getRuntimeConfig() as {
|
|
37
|
-
router?: Partial<RouterConfig>;
|
|
38
|
-
};
|
|
39
|
-
return merge(pluginConfig.router || {}, userConfig) as RouterConfig;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function getFinalRouteConfig(mergedConfig: RouterConfig) {
|
|
43
|
-
return {
|
|
44
|
-
routes: getGlobalRoutes(),
|
|
45
|
-
globalApp: getGlobalLayoutApp(),
|
|
46
|
-
...mergedConfig.routesConfig,
|
|
47
|
-
};
|
|
48
|
-
}
|