@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.100 → 3.5.0-ultramodern.101
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/tanstackTypes/source.js +2 -3
- package/dist/esm/cli/tanstackTypes/source.mjs +2 -3
- package/dist/esm-node/cli/tanstackTypes/source.mjs +2 -3
- package/package.json +10 -9
- package/src/cli/tanstackTypes/source.ts +2 -3
- package/tests/router/cli.test.ts +200 -96
- package/tests/router/routerCompatibility.test.ts +0 -6
- package/tests/router/tanstackTypes.test.ts +333 -346
- package/tests/castRatchet.test.ts +0 -85
- package/tests/router/fixtures/router-gen.golden.txt +0 -71
|
@@ -214,8 +214,7 @@ import {
|
|
|
214
214
|
createRouter,
|
|
215
215
|
createRouteStaticData,
|
|
216
216
|
type ModernRouterContext,
|
|
217
|
-
modernLoaderToTanstack,
|
|
218
|
-
modernTanstackRouterFastDefaults,
|
|
217
|
+
${loaderImportMap.size > 0 ? ' modernLoaderToTanstack,\n' : ''} modernTanstackRouterFastDefaults,
|
|
219
218
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
220
219
|
|
|
221
220
|
${imports.join('\n')}
|
|
@@ -239,7 +238,7 @@ export const router = createRouter({
|
|
|
239
238
|
history: createMemoryHistory({
|
|
240
239
|
initialEntries: ['/'],
|
|
241
240
|
}),
|
|
242
|
-
context: {}
|
|
241
|
+
context: {},
|
|
243
242
|
});
|
|
244
243
|
`;
|
|
245
244
|
return {
|
|
@@ -172,8 +172,7 @@ import {
|
|
|
172
172
|
createRouter,
|
|
173
173
|
createRouteStaticData,
|
|
174
174
|
type ModernRouterContext,
|
|
175
|
-
modernLoaderToTanstack,
|
|
176
|
-
modernTanstackRouterFastDefaults,
|
|
175
|
+
${loaderImportMap.size > 0 ? ' modernLoaderToTanstack,\n' : ''} modernTanstackRouterFastDefaults,
|
|
177
176
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
178
177
|
|
|
179
178
|
${imports.join('\n')}
|
|
@@ -197,7 +196,7 @@ export const router = createRouter({
|
|
|
197
196
|
history: createMemoryHistory({
|
|
198
197
|
initialEntries: ['/'],
|
|
199
198
|
}),
|
|
200
|
-
context: {}
|
|
199
|
+
context: {},
|
|
201
200
|
});
|
|
202
201
|
`;
|
|
203
202
|
return {
|
|
@@ -173,8 +173,7 @@ import {
|
|
|
173
173
|
createRouter,
|
|
174
174
|
createRouteStaticData,
|
|
175
175
|
type ModernRouterContext,
|
|
176
|
-
modernLoaderToTanstack,
|
|
177
|
-
modernTanstackRouterFastDefaults,
|
|
176
|
+
${loaderImportMap.size > 0 ? ' modernLoaderToTanstack,\n' : ''} modernTanstackRouterFastDefaults,
|
|
178
177
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
179
178
|
|
|
180
179
|
${imports.join('\n')}
|
|
@@ -198,7 +197,7 @@ export const router = createRouter({
|
|
|
198
197
|
history: createMemoryHistory({
|
|
199
198
|
initialEntries: ['/'],
|
|
200
199
|
}),
|
|
201
|
-
context: {}
|
|
200
|
+
context: {},
|
|
202
201
|
});
|
|
203
202
|
`;
|
|
204
203
|
return {
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"modern.js",
|
|
19
19
|
"tanstack-router"
|
|
20
20
|
],
|
|
21
|
-
"version": "3.5.0-ultramodern.
|
|
21
|
+
"version": "3.5.0-ultramodern.101",
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=20"
|
|
24
24
|
},
|
|
@@ -94,28 +94,29 @@
|
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.
|
|
98
|
-
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.5.0-ultramodern.
|
|
99
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.
|
|
100
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.
|
|
97
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.101",
|
|
98
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.5.0-ultramodern.101",
|
|
99
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.101",
|
|
100
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.101",
|
|
101
101
|
"@swc/helpers": "^0.5.23",
|
|
102
102
|
"@tanstack/react-router": "1.170.17",
|
|
103
103
|
"@tanstack/router-core": "1.171.14",
|
|
104
104
|
"react-server-dom-rspack": "0.0.2"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
|
-
"@modern-js/app-tools": "3.5.0-ultramodern.
|
|
108
|
-
"@modern-js/runtime": "3.5.0-ultramodern.
|
|
107
|
+
"@modern-js/app-tools": "3.5.0-ultramodern.101",
|
|
108
|
+
"@modern-js/runtime": "3.5.0-ultramodern.101",
|
|
109
109
|
"react": "^19.2.7",
|
|
110
110
|
"react-dom": "^19.2.7"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
|
-
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.
|
|
114
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.
|
|
113
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.101",
|
|
114
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.101",
|
|
115
115
|
"@rslib/core": "0.23.2",
|
|
116
116
|
"@scripts/rstest-config": "2.66.0",
|
|
117
117
|
"@tanstack/history": "1.162.0",
|
|
118
118
|
"@testing-library/react": "^16.3.2",
|
|
119
|
+
"@tsconfig/strictest": "2.0.8",
|
|
119
120
|
"@types/node": "^26.1.1",
|
|
120
121
|
"@types/react": "^19.2.17",
|
|
121
122
|
"@types/react-dom": "^19.2.3",
|
|
@@ -379,8 +379,7 @@ import {
|
|
|
379
379
|
createRouter,
|
|
380
380
|
createRouteStaticData,
|
|
381
381
|
type ModernRouterContext,
|
|
382
|
-
modernLoaderToTanstack,
|
|
383
|
-
modernTanstackRouterFastDefaults,
|
|
382
|
+
${loaderImportMap.size > 0 ? ' modernLoaderToTanstack,\n' : ''} modernTanstackRouterFastDefaults,
|
|
384
383
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
385
384
|
|
|
386
385
|
${imports.join('\n')}
|
|
@@ -406,7 +405,7 @@ export const router = createRouter({
|
|
|
406
405
|
history: createMemoryHistory({
|
|
407
406
|
initialEntries: ['/'],
|
|
408
407
|
}),
|
|
409
|
-
context: {}
|
|
408
|
+
context: {},
|
|
410
409
|
});
|
|
411
410
|
`;
|
|
412
411
|
|
package/tests/router/cli.test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
|
|
2
3
|
import { tmpdir } from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
4
6
|
import { mergeConfig } from '@modern-js/plugin/cli';
|
|
5
7
|
import type { Entrypoint } from '@modern-js/types';
|
|
6
8
|
import { fs, NESTED_ROUTE_SPEC_FILE } from '@modern-js/utils';
|
|
@@ -12,6 +14,119 @@ import {
|
|
|
12
14
|
writeTanstackRouterTypesForEntries,
|
|
13
15
|
} from '../../src/cli';
|
|
14
16
|
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
18
|
+
const strictestTsconfigPath = path.resolve(
|
|
19
|
+
__dirname,
|
|
20
|
+
'../../node_modules/@tsconfig/strictest/tsconfig.json',
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
async function typecheckGeneratedRegistration(options: {
|
|
24
|
+
entries: string[];
|
|
25
|
+
generatedDirName: string;
|
|
26
|
+
srcDirectory: string;
|
|
27
|
+
runtimeModule?: string;
|
|
28
|
+
i18nRuntimeModule?: string;
|
|
29
|
+
canonicalTypeChecks?: string[];
|
|
30
|
+
}) {
|
|
31
|
+
const {
|
|
32
|
+
entries,
|
|
33
|
+
generatedDirName,
|
|
34
|
+
srcDirectory,
|
|
35
|
+
runtimeModule = '@modern-js/plugin-tanstack/runtime',
|
|
36
|
+
i18nRuntimeModule,
|
|
37
|
+
canonicalTypeChecks = [],
|
|
38
|
+
} = options;
|
|
39
|
+
const projectDirectory = path.dirname(srcDirectory);
|
|
40
|
+
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
const routerPath = path.join(
|
|
43
|
+
srcDirectory,
|
|
44
|
+
generatedDirName,
|
|
45
|
+
entry,
|
|
46
|
+
'router.gen.ts',
|
|
47
|
+
);
|
|
48
|
+
if (!(await fs.pathExists(routerPath))) {
|
|
49
|
+
await fs.outputFile(routerPath, 'export const router = { context: {} };');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const runtimeDeclaration = [
|
|
54
|
+
`declare module '${runtimeModule}' {`,
|
|
55
|
+
' export interface Register {}',
|
|
56
|
+
' export type ModernRouterContext = { request?: Request; requestContext?: unknown };',
|
|
57
|
+
' type RouteOptions = { getParentRoute?: (...args: never[]) => unknown; id?: string; loader?: (...args: never[]) => unknown; path?: string; staticData?: unknown };',
|
|
58
|
+
' type Route<TOptions extends RouteOptions = RouteOptions> = { options: TOptions; addChildren<const TChildren extends readonly unknown[]>(children: TChildren): Route<TOptions> & { children: TChildren } };',
|
|
59
|
+
' export function createMemoryHistory<TOptions>(options: TOptions): TOptions;',
|
|
60
|
+
' export function createRootRouteWithContext<TContext extends ModernRouterContext>(): <const TOptions extends RouteOptions>(options: TOptions) => Route<TOptions>;',
|
|
61
|
+
' export function createRoute<const TOptions extends RouteOptions>(options: TOptions): Route<TOptions>;',
|
|
62
|
+
' export function createRouter<const TOptions extends { context: ModernRouterContext; routeTree: unknown }>(options: TOptions): TOptions;',
|
|
63
|
+
' export function createRouteStaticData<const TData extends Record<string, unknown>>(data: TData): TData;',
|
|
64
|
+
' export function modernLoaderToTanstack<TLoader extends (...args: never[]) => unknown>(options: { hasSplat: boolean }, loader: TLoader): (context: unknown) => Promise<Awaited<ReturnType<TLoader>>>;',
|
|
65
|
+
' export const modernTanstackRouterFastDefaults: Record<string, unknown>;',
|
|
66
|
+
'}',
|
|
67
|
+
];
|
|
68
|
+
if (i18nRuntimeModule) {
|
|
69
|
+
runtimeDeclaration.push(
|
|
70
|
+
`declare module '${i18nRuntimeModule}' { export interface UltramodernCanonicalRoutes {} }`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
await fs.outputFile(
|
|
74
|
+
path.join(srcDirectory, 'generated-runtime-shim.d.ts'),
|
|
75
|
+
runtimeDeclaration.join('\n'),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const contractLines = [
|
|
79
|
+
`import type { Register } from '${runtimeModule}';`,
|
|
80
|
+
...entries.map(
|
|
81
|
+
(entry, index) =>
|
|
82
|
+
`import { router as router${index} } from './${generatedDirName}/${entry}/router.gen';`,
|
|
83
|
+
),
|
|
84
|
+
...entries.map(
|
|
85
|
+
(_, index) =>
|
|
86
|
+
`const registeredRouter${index}: Register['router'] = router${index};`,
|
|
87
|
+
),
|
|
88
|
+
...entries.map((_, index) => `void registeredRouter${index};`),
|
|
89
|
+
...canonicalTypeChecks,
|
|
90
|
+
];
|
|
91
|
+
await fs.outputFile(
|
|
92
|
+
path.join(srcDirectory, 'registration-contract.ts'),
|
|
93
|
+
contractLines.join('\n'),
|
|
94
|
+
);
|
|
95
|
+
await fs.outputJSON(path.join(projectDirectory, 'tsconfig.json'), {
|
|
96
|
+
extends: strictestTsconfigPath,
|
|
97
|
+
compilerOptions: {
|
|
98
|
+
lib: ['ESNext', 'DOM'],
|
|
99
|
+
module: 'Preserve',
|
|
100
|
+
moduleResolution: 'Bundler',
|
|
101
|
+
noEmit: true,
|
|
102
|
+
target: 'ESNext',
|
|
103
|
+
types: [],
|
|
104
|
+
},
|
|
105
|
+
include: ['src/**/*.ts', 'src/**/*.d.ts'],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
await execFileAsync(
|
|
110
|
+
process.platform === 'win32' ? 'tsgo.cmd' : 'tsgo',
|
|
111
|
+
['-p', 'tsconfig.json'],
|
|
112
|
+
{
|
|
113
|
+
cwd: projectDirectory,
|
|
114
|
+
shell: process.platform === 'win32',
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (
|
|
119
|
+
error &&
|
|
120
|
+
typeof error === 'object' &&
|
|
121
|
+
'stdout' in error &&
|
|
122
|
+
typeof error.stdout === 'string'
|
|
123
|
+
) {
|
|
124
|
+
throw new Error(error.stdout, { cause: error });
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
15
130
|
const runtimeCliMocks = {
|
|
16
131
|
handleFileChange: rstest.fn(),
|
|
17
132
|
handleGeneratorEntryCode: rstest.fn(),
|
|
@@ -86,7 +201,7 @@ describe('tanstack router cli plugin', () => {
|
|
|
86
201
|
}
|
|
87
202
|
});
|
|
88
203
|
|
|
89
|
-
test('
|
|
204
|
+
test('typechecks plugin-owned routers and register metadata under strictest', async () => {
|
|
90
205
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-cli-'));
|
|
91
206
|
const srcDirectory = path.join(tempDir, 'src');
|
|
92
207
|
await mkdir(srcDirectory, { recursive: true });
|
|
@@ -102,33 +217,33 @@ describe('tanstack router cli plugin', () => {
|
|
|
102
217
|
} as any,
|
|
103
218
|
generatedDirName: 'generated-router',
|
|
104
219
|
routesByEntry: {
|
|
105
|
-
dashboard: [
|
|
106
|
-
|
|
220
|
+
dashboard: [
|
|
221
|
+
{
|
|
222
|
+
type: 'nested',
|
|
223
|
+
id: 'layout',
|
|
224
|
+
isRoot: true,
|
|
225
|
+
children: [{ type: 'nested', id: 'page', index: true }],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
main: [
|
|
229
|
+
{
|
|
230
|
+
type: 'nested',
|
|
231
|
+
id: 'layout',
|
|
232
|
+
isRoot: true,
|
|
233
|
+
children: [{ type: 'nested', id: 'page', index: true }],
|
|
234
|
+
},
|
|
235
|
+
],
|
|
107
236
|
},
|
|
108
237
|
});
|
|
109
238
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"} from '@modern-js/plugin-tanstack/runtime';",
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const register = await readFile(
|
|
119
|
-
path.join(srcDirectory, 'generated-router', 'register.gen.d.ts'),
|
|
120
|
-
'utf-8',
|
|
121
|
-
);
|
|
122
|
-
expect(register).toContain("from './main/router.gen'");
|
|
123
|
-
expect(register.indexOf("from './main/router.gen'")).toBeLessThan(
|
|
124
|
-
register.indexOf("from './dashboard/router.gen'"),
|
|
125
|
-
);
|
|
126
|
-
expect(register).toContain(
|
|
127
|
-
"declare module '@modern-js/plugin-tanstack/runtime'",
|
|
128
|
-
);
|
|
239
|
+
await typecheckGeneratedRegistration({
|
|
240
|
+
entries: ['main', 'dashboard'],
|
|
241
|
+
generatedDirName: 'generated-router',
|
|
242
|
+
srcDirectory,
|
|
243
|
+
});
|
|
129
244
|
});
|
|
130
245
|
|
|
131
|
-
test('
|
|
246
|
+
test('typechecks register metadata for custom entry lists without routes', async () => {
|
|
132
247
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-cli-'));
|
|
133
248
|
const srcDirectory = path.join(tempDir, 'src');
|
|
134
249
|
|
|
@@ -138,17 +253,14 @@ describe('tanstack router cli plugin', () => {
|
|
|
138
253
|
srcDirectory,
|
|
139
254
|
});
|
|
140
255
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
'
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
expect(register).toContain(
|
|
147
|
-
"declare module '@modern-js/plugin-tanstack/runtime'",
|
|
148
|
-
);
|
|
256
|
+
await typecheckGeneratedRegistration({
|
|
257
|
+
entries: ['main'],
|
|
258
|
+
generatedDirName: 'tanstack',
|
|
259
|
+
srcDirectory,
|
|
260
|
+
});
|
|
149
261
|
});
|
|
150
262
|
|
|
151
|
-
test('
|
|
263
|
+
test('exposes canonical route params through plugin-i18n types', async () => {
|
|
152
264
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-cli-'));
|
|
153
265
|
const srcDirectory = path.join(tempDir, 'src');
|
|
154
266
|
|
|
@@ -162,20 +274,22 @@ describe('tanstack router cli plugin', () => {
|
|
|
162
274
|
},
|
|
163
275
|
});
|
|
164
276
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
'
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
277
|
+
await typecheckGeneratedRegistration({
|
|
278
|
+
entries: ['main'],
|
|
279
|
+
generatedDirName: 'tanstack',
|
|
280
|
+
srcDirectory,
|
|
281
|
+
i18nRuntimeModule: '@modern-js/plugin-i18n/runtime',
|
|
282
|
+
canonicalTypeChecks: [
|
|
283
|
+
"import type { UltramodernCanonicalRoutes } from '@modern-js/plugin-i18n/runtime';",
|
|
284
|
+
"const rootParams: UltramodernCanonicalRoutes['/'] = {};",
|
|
285
|
+
"const productParams: UltramodernCanonicalRoutes['/products/$slug'] = { slug: 'tractor' };",
|
|
286
|
+
'void rootParams;',
|
|
287
|
+
'void productParams;',
|
|
288
|
+
],
|
|
289
|
+
});
|
|
176
290
|
});
|
|
177
291
|
|
|
178
|
-
test('
|
|
292
|
+
test('typechecks a plain TanStack register without plugin-i18n installed', async () => {
|
|
179
293
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-cli-'));
|
|
180
294
|
const srcDirectory = path.join(tempDir, 'src');
|
|
181
295
|
|
|
@@ -183,23 +297,16 @@ describe('tanstack router cli plugin', () => {
|
|
|
183
297
|
entries: ['main'],
|
|
184
298
|
generatedDirName: 'tanstack',
|
|
185
299
|
srcDirectory,
|
|
186
|
-
// No canonicalRoutes provided at all — plain TanStack app
|
|
187
300
|
});
|
|
188
301
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
'
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
expect(register).not.toContain('plugin-i18n');
|
|
195
|
-
expect(register).not.toContain('UltramodernCanonicalRoutes');
|
|
196
|
-
// But the standard TanStack runtime augmentation must still be present.
|
|
197
|
-
expect(register).toContain(
|
|
198
|
-
"declare module '@modern-js/plugin-tanstack/runtime'",
|
|
199
|
-
);
|
|
302
|
+
await typecheckGeneratedRegistration({
|
|
303
|
+
entries: ['main'],
|
|
304
|
+
generatedDirName: 'tanstack',
|
|
305
|
+
srcDirectory,
|
|
306
|
+
});
|
|
200
307
|
});
|
|
201
308
|
|
|
202
|
-
test('
|
|
309
|
+
test('exposes canonical route params through a custom i18n runtime module', async () => {
|
|
203
310
|
tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-cli-'));
|
|
204
311
|
const srcDirectory = path.join(tempDir, 'src');
|
|
205
312
|
|
|
@@ -213,15 +320,17 @@ describe('tanstack router cli plugin', () => {
|
|
|
213
320
|
i18nRuntimeModule: '@my-org/i18n/runtime',
|
|
214
321
|
});
|
|
215
322
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
'
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
323
|
+
await typecheckGeneratedRegistration({
|
|
324
|
+
entries: ['main'],
|
|
325
|
+
generatedDirName: 'tanstack',
|
|
326
|
+
srcDirectory,
|
|
327
|
+
i18nRuntimeModule: '@my-org/i18n/runtime',
|
|
328
|
+
canonicalTypeChecks: [
|
|
329
|
+
"import type { UltramodernCanonicalRoutes } from '@my-org/i18n/runtime';",
|
|
330
|
+
"const talksParams: UltramodernCanonicalRoutes['/talks'] = {};",
|
|
331
|
+
'void talksParams;',
|
|
332
|
+
],
|
|
333
|
+
});
|
|
225
334
|
});
|
|
226
335
|
|
|
227
336
|
test('claims custom routes, injects runtime plugin, and merges route specs', async () => {
|
|
@@ -576,32 +685,36 @@ describe('tanstack router cli plugin', () => {
|
|
|
576
685
|
tanstackRouterPlugin().setup!(api as any);
|
|
577
686
|
await taps.generateEntryCode({ entrypoints: [entrypoint] });
|
|
578
687
|
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
'utf-8',
|
|
688
|
+
const hasI18n = registeredPlugins.some(
|
|
689
|
+
plugin => plugin.name === '@modern-js/plugin-i18n',
|
|
582
690
|
);
|
|
691
|
+
await typecheckGeneratedRegistration({
|
|
692
|
+
entries: ['main'],
|
|
693
|
+
generatedDirName: 'modern-tanstack',
|
|
694
|
+
srcDirectory,
|
|
695
|
+
...(hasI18n && {
|
|
696
|
+
i18nRuntimeModule: '@modern-js/plugin-i18n/runtime',
|
|
697
|
+
}),
|
|
698
|
+
canonicalTypeChecks: hasI18n
|
|
699
|
+
? [
|
|
700
|
+
"import type { UltramodernCanonicalRoutes } from '@modern-js/plugin-i18n/runtime';",
|
|
701
|
+
"const aboutParams: UltramodernCanonicalRoutes['/about'] = {};",
|
|
702
|
+
'void aboutParams;',
|
|
703
|
+
]
|
|
704
|
+
: [],
|
|
705
|
+
});
|
|
583
706
|
await rm(dir, { recursive: true, force: true });
|
|
584
|
-
return register;
|
|
585
707
|
};
|
|
586
708
|
|
|
587
709
|
// A hand-rolled `/:lang/` app WITHOUT plugin-i18n must not get the
|
|
588
710
|
// augmentation — it would reference an unresolvable module (TS2664).
|
|
589
|
-
|
|
590
|
-
expect(withoutI18n).not.toContain('plugin-i18n');
|
|
591
|
-
expect(withoutI18n).not.toContain('UltramodernCanonicalRoutes');
|
|
592
|
-
expect(withoutI18n).toContain(
|
|
593
|
-
"declare module '@modern-js/plugin-tanstack/runtime'",
|
|
594
|
-
);
|
|
711
|
+
await runGenerate([{ name: '@modern-js/app-tools' }]);
|
|
595
712
|
|
|
596
713
|
// With plugin-i18n registered the canonical route map is emitted.
|
|
597
|
-
|
|
714
|
+
await runGenerate([
|
|
598
715
|
{ name: '@modern-js/app-tools' },
|
|
599
716
|
{ name: '@modern-js/plugin-i18n' },
|
|
600
717
|
]);
|
|
601
|
-
expect(withI18n).toContain(
|
|
602
|
-
"declare module '@modern-js/plugin-i18n/runtime'",
|
|
603
|
-
);
|
|
604
|
-
expect(withI18n).toContain("'/about': Record<string, never>;");
|
|
605
718
|
});
|
|
606
719
|
|
|
607
720
|
test('generates plugin-owned TanStack route files through core route generation', async () => {
|
|
@@ -692,20 +805,11 @@ describe('tanstack router cli plugin', () => {
|
|
|
692
805
|
},
|
|
693
806
|
);
|
|
694
807
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
'
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
expect(routerGen).toContain('modernRouteAction: action_0');
|
|
701
|
-
|
|
702
|
-
const register = await readFile(
|
|
703
|
-
path.join(srcDirectory, 'tanstack-generated', 'register.gen.d.ts'),
|
|
704
|
-
'utf-8',
|
|
705
|
-
);
|
|
706
|
-
expect(register).toContain(
|
|
707
|
-
"declare module '@modern-js/plugin-tanstack/runtime'",
|
|
708
|
-
);
|
|
808
|
+
await typecheckGeneratedRegistration({
|
|
809
|
+
entries: ['main'],
|
|
810
|
+
generatedDirName: 'tanstack-generated',
|
|
811
|
+
srcDirectory,
|
|
812
|
+
});
|
|
709
813
|
});
|
|
710
814
|
|
|
711
815
|
test('regenerates plugin-owned TanStack files for scoped file changes', async () => {
|
|
@@ -199,12 +199,6 @@ describe('runtime router compatibility', () => {
|
|
|
199
199
|
runTsgo(tsgoBin, path.join(tempRoot, 'emit.json'));
|
|
200
200
|
|
|
201
201
|
const declarationPath = path.join(emittedRoot, 'router.d.ts');
|
|
202
|
-
const declaration = readFileSync(declarationPath, 'utf8');
|
|
203
|
-
expect(declaration).not.toMatch(
|
|
204
|
-
/\b(?:createRouterPlugin|RouterPluginFactory)\b/u,
|
|
205
|
-
);
|
|
206
|
-
expect(declaration).toContain("['routerPlugin']");
|
|
207
|
-
|
|
208
202
|
writeFileSync(
|
|
209
203
|
path.join(tempRoot, 'legacyRuntimeRouter.ts'),
|
|
210
204
|
readFileSync(legacyFixturePath, 'utf8'),
|