create-payload-app 4.0.0-internal.fa345ef → 4.0.0-internal.fec2230
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/README.md +5 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +5 -0
- package/dist/commands.js.map +1 -0
- package/dist/lib/agent-config.d.ts +15 -0
- package/dist/lib/agent-config.d.ts.map +1 -0
- package/dist/lib/agent-config.js +22 -0
- package/dist/lib/agent-config.js.map +1 -0
- package/dist/lib/agent-config.spec.js +23 -0
- package/dist/lib/agent-config.spec.js.map +1 -0
- package/dist/lib/ast/adapter-config.d.ts.map +1 -1
- package/dist/lib/ast/adapter-config.js +0 -10
- package/dist/lib/ast/adapter-config.js.map +1 -1
- package/dist/lib/ast/package-json.d.ts +9 -0
- package/dist/lib/ast/package-json.d.ts.map +1 -1
- package/dist/lib/ast/package-json.js +34 -8
- package/dist/lib/ast/package-json.js.map +1 -1
- package/dist/lib/ast/package-json.spec.js +73 -1
- package/dist/lib/ast/package-json.spec.js.map +1 -1
- package/dist/lib/ast/types.d.ts +2 -2
- package/dist/lib/ast/types.d.ts.map +1 -1
- package/dist/lib/ast/types.js +0 -1
- package/dist/lib/ast/types.js.map +1 -1
- package/dist/lib/configure-payload-tsconfig.d.ts +5 -0
- package/dist/lib/configure-payload-tsconfig.d.ts.map +1 -0
- package/dist/lib/configure-payload-tsconfig.js +26 -0
- package/dist/lib/configure-payload-tsconfig.js.map +1 -0
- package/dist/lib/configure-payload-tsconfig.spec.js +135 -0
- package/dist/lib/configure-payload-tsconfig.spec.js.map +1 -0
- package/dist/lib/configure-plugin-project.d.ts.map +1 -1
- package/dist/lib/create-project.d.ts +1 -2
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +5 -21
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/create-project.spec.js +9 -0
- package/dist/lib/create-project.spec.js.map +1 -1
- package/dist/lib/generate-secret.js +1 -1
- package/dist/lib/generate-secret.js.map +1 -1
- package/dist/lib/init-next.d.ts.map +1 -1
- package/dist/lib/init-next.js +5 -34
- package/dist/lib/init-next.js.map +1 -1
- package/dist/lib/init-tanstack-default-template.spec.js +121 -0
- package/dist/lib/init-tanstack-default-template.spec.js.map +1 -0
- package/dist/lib/init-tanstack.d.ts +18 -0
- package/dist/lib/init-tanstack.d.ts.map +1 -0
- package/dist/lib/init-tanstack.js +150 -0
- package/dist/lib/init-tanstack.js.map +1 -0
- package/dist/lib/init-tanstack.spec.js +394 -0
- package/dist/lib/init-tanstack.spec.js.map +1 -0
- package/dist/lib/tanstack/detect.d.ts +5 -0
- package/dist/lib/tanstack/detect.d.ts.map +1 -0
- package/dist/lib/tanstack/detect.js +131 -0
- package/dist/lib/tanstack/detect.js.map +1 -0
- package/dist/lib/tanstack/detect.spec.js +227 -0
- package/dist/lib/tanstack/detect.spec.js.map +1 -0
- package/dist/lib/tanstack/prepare.d.ts +23 -0
- package/dist/lib/tanstack/prepare.d.ts.map +1 -0
- package/dist/lib/tanstack/prepare.js +114 -0
- package/dist/lib/tanstack/prepare.js.map +1 -0
- package/dist/lib/tanstack/prepare.spec.js +288 -0
- package/dist/lib/tanstack/prepare.spec.js.map +1 -0
- package/dist/lib/tanstack/template-files.d.ts +50 -0
- package/dist/lib/tanstack/template-files.d.ts.map +1 -0
- package/dist/lib/tanstack/template-files.js +64 -0
- package/dist/lib/tanstack/template-files.js.map +1 -0
- package/dist/lib/tanstack/transform-root-route.d.ts +7 -0
- package/dist/lib/tanstack/transform-root-route.d.ts.map +1 -0
- package/dist/lib/tanstack/transform-root-route.js +747 -0
- package/dist/lib/tanstack/transform-root-route.js.map +1 -0
- package/dist/lib/tanstack/transform-root-route.spec.js +484 -0
- package/dist/lib/tanstack/transform-root-route.spec.js.map +1 -0
- package/dist/lib/tanstack/transform-router.d.ts +5 -0
- package/dist/lib/tanstack/transform-router.d.ts.map +1 -0
- package/dist/lib/tanstack/transform-router.js +301 -0
- package/dist/lib/tanstack/transform-router.js.map +1 -0
- package/dist/lib/tanstack/transform-router.spec.js +264 -0
- package/dist/lib/tanstack/transform-router.spec.js.map +1 -0
- package/dist/lib/tanstack/transform-vite-config.d.ts +14 -0
- package/dist/lib/tanstack/transform-vite-config.d.ts.map +1 -0
- package/dist/lib/tanstack/transform-vite-config.js +576 -0
- package/dist/lib/tanstack/transform-vite-config.js.map +1 -0
- package/dist/lib/tanstack/transform-vite-config.spec.js +456 -0
- package/dist/lib/tanstack/transform-vite-config.spec.js.map +1 -0
- package/dist/lib/templates.d.ts.map +1 -1
- package/dist/lib/templates.js +6 -0
- package/dist/lib/templates.js.map +1 -1
- package/dist/lib/update-payload-in-project.d.ts +18 -3
- package/dist/lib/update-payload-in-project.d.ts.map +1 -1
- package/dist/lib/update-payload-in-project.js +98 -18
- package/dist/lib/update-payload-in-project.js.map +1 -1
- package/dist/lib/update-payload-in-project.spec.js +262 -0
- package/dist/lib/update-payload-in-project.spec.js.map +1 -0
- package/dist/lib/wrap-next-config.d.ts.map +1 -1
- package/dist/main.d.ts +20 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +120 -29
- package/dist/main.js.map +1 -1
- package/dist/main.spec.js +102 -0
- package/dist/main.spec.js.map +1 -0
- package/dist/scripts/pack-template-files.js +18 -0
- package/dist/scripts/pack-template-files.js.map +1 -1
- package/dist/template/src/app/(frontend)/styles.css +1 -1
- package/dist/template/src/app/(payload)/layout.tsx +8 -2
- package/dist/template-tanstack/routes/_payload/admin.$.tsx +8 -0
- package/dist/template-tanstack/routes/_payload/admin.index.tsx +8 -0
- package/dist/template-tanstack/routes/_payload/api.$.ts +10 -0
- package/dist/template-tanstack/routes/_payload/importMap.js +32 -0
- package/dist/template-tanstack/routes/_payload/server.functions.ts +49 -0
- package/dist/template-tanstack/routes/_payload.tsx +30 -0
- package/dist/template-tanstack/src/collections/Folders.ts +16 -0
- package/dist/template-tanstack/src/collections/Media.ts +20 -0
- package/dist/template-tanstack/src/collections/Tags.ts +16 -0
- package/dist/template-tanstack/src/collections/Users.ts +14 -0
- package/dist/template-tanstack/src/payload.config.ts +40 -0
- package/dist/template-tanstack/src/payload.css +1 -0
- package/dist/types.d.ts +22 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/casing.d.ts.map +1 -1
- package/dist/utils/log.d.ts.map +1 -1
- package/dist/utils/messages.d.ts +1 -0
- package/dist/utils/messages.d.ts.map +1 -1
- package/dist/utils/messages.js +8 -6
- package/dist/utils/messages.js.map +1 -1
- package/package.json +4 -4
- package/dist/lib/download-skill.d.ts +0 -8
- package/dist/lib/download-skill.d.ts.map +0 -1
- package/dist/lib/download-skill.js +0 -35
- package/dist/lib/download-skill.js.map +0 -1
- package/dist/lib/select-agent.d.ts +0 -16
- package/dist/lib/select-agent.d.ts.map +0 -1
- package/dist/lib/select-agent.js +0 -67
- package/dist/lib/select-agent.js.map +0 -1
- /package/dist/template/src/app/(payload)/{custom.scss → custom.css} +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { Project } from 'ts-morph';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { transformTanStackRouter } from './transform-router.js';
|
|
4
|
+
function expectSuccessfulTransform(result) {
|
|
5
|
+
expect(result.success).toBe(true);
|
|
6
|
+
if (!result.success) {
|
|
7
|
+
throw new Error(result.reason);
|
|
8
|
+
}
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
11
|
+
function getRouterContent({ imports = `import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
|
12
|
+
|
|
13
|
+
import { routeTree } from './routeTree.gen'`, properties = `
|
|
14
|
+
routeTree,
|
|
15
|
+
defaultPreload: 'intent',
|
|
16
|
+
scrollRestoration: true,
|
|
17
|
+
context: { auth: undefined! },` } = {}) {
|
|
18
|
+
return `${imports}
|
|
19
|
+
|
|
20
|
+
export function getRouter() {
|
|
21
|
+
const router = createTanStackRouter({${properties}
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
return router
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare module '@tanstack/react-router' {
|
|
28
|
+
interface Register {
|
|
29
|
+
router: ReturnType<typeof getRouter>
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
function getPayloadSearchImports(content) {
|
|
35
|
+
const project = new Project({
|
|
36
|
+
useInMemoryFileSystem: true
|
|
37
|
+
});
|
|
38
|
+
const sourceFile = project.createSourceFile('router.tsx', content);
|
|
39
|
+
return sourceFile.getImportDeclarations().filter((declaration)=>declaration.getModuleSpecifierValue() === '@payloadcms/tanstack-start/shared').flatMap((declaration)=>declaration.getNamedImports().map((namedImport)=>({
|
|
40
|
+
importedName: namedImport.getName(),
|
|
41
|
+
localName: namedImport.getAliasNode()?.getText() ?? namedImport.getName()
|
|
42
|
+
})));
|
|
43
|
+
}
|
|
44
|
+
describe('transformTanStackRouter', ()=>{
|
|
45
|
+
it('should integrate Payload with an aliased official getRouter declaration', ()=>{
|
|
46
|
+
const content = getRouterContent();
|
|
47
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
48
|
+
content
|
|
49
|
+
}));
|
|
50
|
+
expect(result.modified).toBe(true);
|
|
51
|
+
expect(result.content).toContain("import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'");
|
|
52
|
+
expect(result.content).toContain('const router = createTanStackRouter({');
|
|
53
|
+
expect(result.content).toContain('parseSearch: payloadParseSearch');
|
|
54
|
+
expect(result.content).toContain('stringifySearch: payloadStringifySearch');
|
|
55
|
+
expect(result.content).toContain('routeTree');
|
|
56
|
+
expect(result.content).toContain("defaultPreload: 'intent'");
|
|
57
|
+
expect(result.content).toContain('scrollRestoration: true');
|
|
58
|
+
expect(result.content).toContain('context: { auth: undefined! }');
|
|
59
|
+
expect(result.content).toContain("declare module '@tanstack/react-router'");
|
|
60
|
+
expect(result.content).toContain('router: ReturnType<typeof getRouter>');
|
|
61
|
+
});
|
|
62
|
+
it('should preserve router components and unrelated options', ()=>{
|
|
63
|
+
const content = getRouterContent({
|
|
64
|
+
properties: `
|
|
65
|
+
routeTree,
|
|
66
|
+
defaultNotFoundComponent: NotFound,
|
|
67
|
+
defaultPendingComponent: Pending,
|
|
68
|
+
defaultPreload: 'viewport',
|
|
69
|
+
trailingSlash: 'always',`
|
|
70
|
+
});
|
|
71
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
72
|
+
content
|
|
73
|
+
}));
|
|
74
|
+
expect(result.content).toContain('defaultNotFoundComponent: NotFound');
|
|
75
|
+
expect(result.content).toContain('defaultPendingComponent: Pending');
|
|
76
|
+
expect(result.content).toContain("defaultPreload: 'viewport'");
|
|
77
|
+
expect(result.content).toContain("trailingSlash: 'always'");
|
|
78
|
+
});
|
|
79
|
+
it('should report an already transformed router as unmodified', ()=>{
|
|
80
|
+
const firstResult = expectSuccessfulTransform(transformTanStackRouter({
|
|
81
|
+
content: getRouterContent()
|
|
82
|
+
}));
|
|
83
|
+
const secondResult = expectSuccessfulTransform(transformTanStackRouter({
|
|
84
|
+
content: firstResult.content
|
|
85
|
+
}));
|
|
86
|
+
expect(secondResult).toEqual({
|
|
87
|
+
content: firstResult.content,
|
|
88
|
+
modified: false,
|
|
89
|
+
success: true
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
it('should not add value bindings to an unrelated type-only Payload import', ()=>{
|
|
93
|
+
const content = getRouterContent({
|
|
94
|
+
imports: `import type { SearchOptions } from '@payloadcms/tanstack-start/shared'
|
|
95
|
+
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
|
96
|
+
|
|
97
|
+
import { routeTree } from './routeTree.gen'`
|
|
98
|
+
});
|
|
99
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
100
|
+
content
|
|
101
|
+
}));
|
|
102
|
+
expect(result.content).toContain("import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'");
|
|
103
|
+
expect(result.content).toContain("import type { SearchOptions } from '@payloadcms/tanstack-start/shared'");
|
|
104
|
+
});
|
|
105
|
+
it('should restore missing Payload imports for otherwise configured search options', ()=>{
|
|
106
|
+
const content = getRouterContent({
|
|
107
|
+
properties: `
|
|
108
|
+
parseSearch: payloadParseSearch,
|
|
109
|
+
routeTree,
|
|
110
|
+
stringifySearch: payloadStringifySearch,`
|
|
111
|
+
});
|
|
112
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
113
|
+
content
|
|
114
|
+
}));
|
|
115
|
+
expect(result.modified).toBe(true);
|
|
116
|
+
expect(result.content).toContain("import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'");
|
|
117
|
+
});
|
|
118
|
+
it('should reuse aliased Payload search imports as the configured identifiers', ()=>{
|
|
119
|
+
const content = getRouterContent({
|
|
120
|
+
imports: `import { payloadParseSearch as parseWithPayload } from '@payloadcms/tanstack-start/shared'
|
|
121
|
+
import { payloadStringifySearch as stringifyWithPayload } from '@payloadcms/tanstack-start/shared'
|
|
122
|
+
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
|
123
|
+
|
|
124
|
+
import { routeTree } from './routeTree.gen'`
|
|
125
|
+
});
|
|
126
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
127
|
+
content
|
|
128
|
+
}));
|
|
129
|
+
expect(result.content).toContain('parseSearch: parseWithPayload');
|
|
130
|
+
expect(result.content).toContain('stringifySearch: stringifyWithPayload');
|
|
131
|
+
expect(getPayloadSearchImports(result.content)).toEqual([
|
|
132
|
+
{
|
|
133
|
+
importedName: 'payloadParseSearch',
|
|
134
|
+
localName: 'parseWithPayload'
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
importedName: 'payloadStringifySearch',
|
|
138
|
+
localName: 'stringifyWithPayload'
|
|
139
|
+
}
|
|
140
|
+
]);
|
|
141
|
+
});
|
|
142
|
+
it('should preserve split Payload search imports without duplicating bindings', ()=>{
|
|
143
|
+
const content = getRouterContent({
|
|
144
|
+
imports: `import { payloadParseSearch } from '@payloadcms/tanstack-start/shared'
|
|
145
|
+
import { payloadStringifySearch } from '@payloadcms/tanstack-start/shared'
|
|
146
|
+
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
|
147
|
+
|
|
148
|
+
import { routeTree } from './routeTree.gen'`
|
|
149
|
+
});
|
|
150
|
+
const result = expectSuccessfulTransform(transformTanStackRouter({
|
|
151
|
+
content
|
|
152
|
+
}));
|
|
153
|
+
expect(getPayloadSearchImports(result.content)).toEqual([
|
|
154
|
+
{
|
|
155
|
+
importedName: 'payloadParseSearch',
|
|
156
|
+
localName: 'payloadParseSearch'
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
importedName: 'payloadStringifySearch',
|
|
160
|
+
localName: 'payloadStringifySearch'
|
|
161
|
+
}
|
|
162
|
+
]);
|
|
163
|
+
expect(result.content).toContain('parseSearch: payloadParseSearch');
|
|
164
|
+
expect(result.content).toContain('stringifySearch: payloadStringifySearch');
|
|
165
|
+
});
|
|
166
|
+
it.each([
|
|
167
|
+
'parseSearch',
|
|
168
|
+
'stringifySearch'
|
|
169
|
+
])('should reject an existing non-Payload %s option', (name)=>{
|
|
170
|
+
const content = getRouterContent({
|
|
171
|
+
properties: `
|
|
172
|
+
routeTree,
|
|
173
|
+
${name}: customSearchSerializer,`
|
|
174
|
+
});
|
|
175
|
+
const result = transformTanStackRouter({
|
|
176
|
+
content
|
|
177
|
+
});
|
|
178
|
+
expect(result).toEqual({
|
|
179
|
+
reason: `The router already defines a non-Payload ${name} option.`,
|
|
180
|
+
success: false
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
it('should reject Payload-named search options imported from another module', ()=>{
|
|
184
|
+
const content = getRouterContent({
|
|
185
|
+
imports: `import { payloadParseSearch, payloadStringifySearch } from 'custom-search'
|
|
186
|
+
import { createRouter } from '@tanstack/react-router'
|
|
187
|
+
|
|
188
|
+
import { routeTree } from './routeTree.gen'`,
|
|
189
|
+
properties: `
|
|
190
|
+
routeTree,
|
|
191
|
+
parseSearch: payloadParseSearch,
|
|
192
|
+
stringifySearch: payloadStringifySearch,`
|
|
193
|
+
}).replaceAll('createTanStackRouter', 'createRouter');
|
|
194
|
+
const result = transformTanStackRouter({
|
|
195
|
+
content
|
|
196
|
+
});
|
|
197
|
+
expect(result).toEqual({
|
|
198
|
+
reason: 'Identifier "payloadParseSearch" is already bound incompatibly.',
|
|
199
|
+
success: false
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
it.each([
|
|
203
|
+
[
|
|
204
|
+
'payloadParseSearch',
|
|
205
|
+
`const payloadParseSearch = customSearchSerializer`
|
|
206
|
+
],
|
|
207
|
+
[
|
|
208
|
+
'payloadStringifySearch',
|
|
209
|
+
`function payloadStringifySearch() { return '' }`
|
|
210
|
+
]
|
|
211
|
+
])('should reject an incompatible %s destination binding', (name, binding)=>{
|
|
212
|
+
const content = getRouterContent().replace('export function getRouter()', `${binding}\n\nexport function getRouter()`);
|
|
213
|
+
const result = transformTanStackRouter({
|
|
214
|
+
content
|
|
215
|
+
});
|
|
216
|
+
expect(result).toEqual({
|
|
217
|
+
reason: `Identifier "${name}" is already bound incompatibly.`,
|
|
218
|
+
success: false
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
it('should reject object spreads that could override search serialization', ()=>{
|
|
222
|
+
const content = getRouterContent({
|
|
223
|
+
properties: `
|
|
224
|
+
routeTree,
|
|
225
|
+
...routerOptions,`
|
|
226
|
+
});
|
|
227
|
+
const result = transformTanStackRouter({
|
|
228
|
+
content
|
|
229
|
+
});
|
|
230
|
+
expect(result).toEqual({
|
|
231
|
+
reason: 'Router object spreads cannot be transformed safely.',
|
|
232
|
+
success: false
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
it('should reject a locally constructed route tree', ()=>{
|
|
236
|
+
const content = getRouterContent({
|
|
237
|
+
imports: `import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
|
238
|
+
|
|
239
|
+
const routeTree = createRouteTree()`
|
|
240
|
+
});
|
|
241
|
+
const result = transformTanStackRouter({
|
|
242
|
+
content
|
|
243
|
+
});
|
|
244
|
+
expect(result).toEqual({
|
|
245
|
+
reason: 'The routeTree option must reference the generated route tree import.',
|
|
246
|
+
success: false
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
it('should reject multiple createRouter calls', ()=>{
|
|
250
|
+
const content = `${getRouterContent()}
|
|
251
|
+
|
|
252
|
+
const otherRouter = createTanStackRouter({ routeTree })
|
|
253
|
+
`;
|
|
254
|
+
const result = transformTanStackRouter({
|
|
255
|
+
content
|
|
256
|
+
});
|
|
257
|
+
expect(result).toEqual({
|
|
258
|
+
reason: 'Expected exactly one createRouter() call.',
|
|
259
|
+
success: false
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
//# sourceMappingURL=transform-router.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/tanstack/transform-router.spec.ts"],"sourcesContent":["import { Project } from 'ts-morph'\nimport { describe, expect, it } from 'vitest'\n\nimport { transformTanStackRouter } from './transform-router.js'\n\nfunction expectSuccessfulTransform(result: ReturnType<typeof transformTanStackRouter>) {\n expect(result.success).toBe(true)\n\n if (!result.success) {\n throw new Error(result.reason)\n }\n\n return result\n}\n\nfunction getRouterContent({\n imports = `import { createRouter as createTanStackRouter } from '@tanstack/react-router'\n\nimport { routeTree } from './routeTree.gen'`,\n properties = `\n routeTree,\n defaultPreload: 'intent',\n scrollRestoration: true,\n context: { auth: undefined! },`,\n}: {\n imports?: string\n properties?: string\n} = {}) {\n return `${imports}\n\nexport function getRouter() {\n const router = createTanStackRouter({${properties}\n })\n\n return router\n}\n\ndeclare module '@tanstack/react-router' {\n interface Register {\n router: ReturnType<typeof getRouter>\n }\n}\n`\n}\n\nfunction getPayloadSearchImports(content: string) {\n const project = new Project({ useInMemoryFileSystem: true })\n const sourceFile = project.createSourceFile('router.tsx', content)\n\n return sourceFile\n .getImportDeclarations()\n .filter(\n (declaration) =>\n declaration.getModuleSpecifierValue() === '@payloadcms/tanstack-start/shared',\n )\n .flatMap((declaration) =>\n declaration.getNamedImports().map((namedImport) => ({\n importedName: namedImport.getName(),\n localName: namedImport.getAliasNode()?.getText() ?? namedImport.getName(),\n })),\n )\n}\n\ndescribe('transformTanStackRouter', () => {\n it('should integrate Payload with an aliased official getRouter declaration', () => {\n const content = getRouterContent()\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(result.modified).toBe(true)\n expect(result.content).toContain(\n \"import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'\",\n )\n expect(result.content).toContain('const router = createTanStackRouter({')\n expect(result.content).toContain('parseSearch: payloadParseSearch')\n expect(result.content).toContain('stringifySearch: payloadStringifySearch')\n expect(result.content).toContain('routeTree')\n expect(result.content).toContain(\"defaultPreload: 'intent'\")\n expect(result.content).toContain('scrollRestoration: true')\n expect(result.content).toContain('context: { auth: undefined! }')\n expect(result.content).toContain(\"declare module '@tanstack/react-router'\")\n expect(result.content).toContain('router: ReturnType<typeof getRouter>')\n })\n\n it('should preserve router components and unrelated options', () => {\n const content = getRouterContent({\n properties: `\n routeTree,\n defaultNotFoundComponent: NotFound,\n defaultPendingComponent: Pending,\n defaultPreload: 'viewport',\n trailingSlash: 'always',`,\n })\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(result.content).toContain('defaultNotFoundComponent: NotFound')\n expect(result.content).toContain('defaultPendingComponent: Pending')\n expect(result.content).toContain(\"defaultPreload: 'viewport'\")\n expect(result.content).toContain(\"trailingSlash: 'always'\")\n })\n\n it('should report an already transformed router as unmodified', () => {\n const firstResult = expectSuccessfulTransform(\n transformTanStackRouter({ content: getRouterContent() }),\n )\n const secondResult = expectSuccessfulTransform(\n transformTanStackRouter({ content: firstResult.content }),\n )\n\n expect(secondResult).toEqual({ content: firstResult.content, modified: false, success: true })\n })\n\n it('should not add value bindings to an unrelated type-only Payload import', () => {\n const content = getRouterContent({\n imports: `import type { SearchOptions } from '@payloadcms/tanstack-start/shared'\nimport { createRouter as createTanStackRouter } from '@tanstack/react-router'\n\nimport { routeTree } from './routeTree.gen'`,\n })\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(result.content).toContain(\n \"import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'\",\n )\n expect(result.content).toContain(\n \"import type { SearchOptions } from '@payloadcms/tanstack-start/shared'\",\n )\n })\n\n it('should restore missing Payload imports for otherwise configured search options', () => {\n const content = getRouterContent({\n properties: `\n parseSearch: payloadParseSearch,\n routeTree,\n stringifySearch: payloadStringifySearch,`,\n })\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(result.modified).toBe(true)\n expect(result.content).toContain(\n \"import { payloadParseSearch, payloadStringifySearch } from '@payloadcms/tanstack-start/shared'\",\n )\n })\n\n it('should reuse aliased Payload search imports as the configured identifiers', () => {\n const content = getRouterContent({\n imports: `import { payloadParseSearch as parseWithPayload } from '@payloadcms/tanstack-start/shared'\nimport { payloadStringifySearch as stringifyWithPayload } from '@payloadcms/tanstack-start/shared'\nimport { createRouter as createTanStackRouter } from '@tanstack/react-router'\n\nimport { routeTree } from './routeTree.gen'`,\n })\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(result.content).toContain('parseSearch: parseWithPayload')\n expect(result.content).toContain('stringifySearch: stringifyWithPayload')\n expect(getPayloadSearchImports(result.content)).toEqual([\n { importedName: 'payloadParseSearch', localName: 'parseWithPayload' },\n { importedName: 'payloadStringifySearch', localName: 'stringifyWithPayload' },\n ])\n })\n\n it('should preserve split Payload search imports without duplicating bindings', () => {\n const content = getRouterContent({\n imports: `import { payloadParseSearch } from '@payloadcms/tanstack-start/shared'\nimport { payloadStringifySearch } from '@payloadcms/tanstack-start/shared'\nimport { createRouter as createTanStackRouter } from '@tanstack/react-router'\n\nimport { routeTree } from './routeTree.gen'`,\n })\n\n const result = expectSuccessfulTransform(transformTanStackRouter({ content }))\n\n expect(getPayloadSearchImports(result.content)).toEqual([\n { importedName: 'payloadParseSearch', localName: 'payloadParseSearch' },\n { importedName: 'payloadStringifySearch', localName: 'payloadStringifySearch' },\n ])\n expect(result.content).toContain('parseSearch: payloadParseSearch')\n expect(result.content).toContain('stringifySearch: payloadStringifySearch')\n })\n\n it.each(['parseSearch', 'stringifySearch'])(\n 'should reject an existing non-Payload %s option',\n (name) => {\n const content = getRouterContent({\n properties: `\n routeTree,\n ${name}: customSearchSerializer,`,\n })\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: `The router already defines a non-Payload ${name} option.`,\n success: false,\n })\n },\n )\n\n it('should reject Payload-named search options imported from another module', () => {\n const content = getRouterContent({\n imports: `import { payloadParseSearch, payloadStringifySearch } from 'custom-search'\nimport { createRouter } from '@tanstack/react-router'\n\nimport { routeTree } from './routeTree.gen'`,\n properties: `\n routeTree,\n parseSearch: payloadParseSearch,\n stringifySearch: payloadStringifySearch,`,\n }).replaceAll('createTanStackRouter', 'createRouter')\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: 'Identifier \"payloadParseSearch\" is already bound incompatibly.',\n success: false,\n })\n })\n\n it.each([\n ['payloadParseSearch', `const payloadParseSearch = customSearchSerializer`],\n ['payloadStringifySearch', `function payloadStringifySearch() { return '' }`],\n ])('should reject an incompatible %s destination binding', (name, binding) => {\n const content = getRouterContent().replace(\n 'export function getRouter()',\n `${binding}\\n\\nexport function getRouter()`,\n )\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: `Identifier \"${name}\" is already bound incompatibly.`,\n success: false,\n })\n })\n\n it('should reject object spreads that could override search serialization', () => {\n const content = getRouterContent({\n properties: `\n routeTree,\n ...routerOptions,`,\n })\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: 'Router object spreads cannot be transformed safely.',\n success: false,\n })\n })\n\n it('should reject a locally constructed route tree', () => {\n const content = getRouterContent({\n imports: `import { createRouter as createTanStackRouter } from '@tanstack/react-router'\n\nconst routeTree = createRouteTree()`,\n })\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: 'The routeTree option must reference the generated route tree import.',\n success: false,\n })\n })\n\n it('should reject multiple createRouter calls', () => {\n const content = `${getRouterContent()}\n\nconst otherRouter = createTanStackRouter({ routeTree })\n`\n\n const result = transformTanStackRouter({ content })\n\n expect(result).toEqual({\n reason: 'Expected exactly one createRouter() call.',\n success: false,\n })\n })\n})\n"],"names":["Project","describe","expect","it","transformTanStackRouter","expectSuccessfulTransform","result","success","toBe","Error","reason","getRouterContent","imports","properties","getPayloadSearchImports","content","project","useInMemoryFileSystem","sourceFile","createSourceFile","getImportDeclarations","filter","declaration","getModuleSpecifierValue","flatMap","getNamedImports","map","namedImport","importedName","getName","localName","getAliasNode","getText","modified","toContain","firstResult","secondResult","toEqual","each","name","replaceAll","binding","replace"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TanStackAppDetails } from '../../types.js';
|
|
2
|
+
export type TextTransformResult = {
|
|
3
|
+
content: string;
|
|
4
|
+
modified: boolean;
|
|
5
|
+
success: true;
|
|
6
|
+
} | {
|
|
7
|
+
reason: string;
|
|
8
|
+
success: false;
|
|
9
|
+
};
|
|
10
|
+
export declare function transformTanStackViteConfig({ appDetails, content, }: {
|
|
11
|
+
appDetails: TanStackAppDetails;
|
|
12
|
+
content: string;
|
|
13
|
+
}): TextTransformResult;
|
|
14
|
+
//# sourceMappingURL=transform-vite-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-vite-config.d.ts","sourceRoot":"","sources":["../../../src/lib/tanstack/transform-vite-config.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,MAAM,mBAAmB,GAC3B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAA;AAetC,wBAAgB,2BAA2B,CAAC,EAC1C,UAAU,EACV,OAAO,GACR,EAAE;IACD,UAAU,EAAE,kBAAkB,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,mBAAmB,CA6KtB"}
|