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.
Files changed (135) hide show
  1. package/README.md +5 -0
  2. package/dist/commands.d.ts +4 -0
  3. package/dist/commands.d.ts.map +1 -0
  4. package/dist/commands.js +5 -0
  5. package/dist/commands.js.map +1 -0
  6. package/dist/lib/agent-config.d.ts +15 -0
  7. package/dist/lib/agent-config.d.ts.map +1 -0
  8. package/dist/lib/agent-config.js +22 -0
  9. package/dist/lib/agent-config.js.map +1 -0
  10. package/dist/lib/agent-config.spec.js +23 -0
  11. package/dist/lib/agent-config.spec.js.map +1 -0
  12. package/dist/lib/ast/adapter-config.d.ts.map +1 -1
  13. package/dist/lib/ast/adapter-config.js +0 -10
  14. package/dist/lib/ast/adapter-config.js.map +1 -1
  15. package/dist/lib/ast/package-json.d.ts +9 -0
  16. package/dist/lib/ast/package-json.d.ts.map +1 -1
  17. package/dist/lib/ast/package-json.js +34 -8
  18. package/dist/lib/ast/package-json.js.map +1 -1
  19. package/dist/lib/ast/package-json.spec.js +73 -1
  20. package/dist/lib/ast/package-json.spec.js.map +1 -1
  21. package/dist/lib/ast/types.d.ts +2 -2
  22. package/dist/lib/ast/types.d.ts.map +1 -1
  23. package/dist/lib/ast/types.js +0 -1
  24. package/dist/lib/ast/types.js.map +1 -1
  25. package/dist/lib/configure-payload-tsconfig.d.ts +5 -0
  26. package/dist/lib/configure-payload-tsconfig.d.ts.map +1 -0
  27. package/dist/lib/configure-payload-tsconfig.js +26 -0
  28. package/dist/lib/configure-payload-tsconfig.js.map +1 -0
  29. package/dist/lib/configure-payload-tsconfig.spec.js +135 -0
  30. package/dist/lib/configure-payload-tsconfig.spec.js.map +1 -0
  31. package/dist/lib/configure-plugin-project.d.ts.map +1 -1
  32. package/dist/lib/create-project.d.ts +1 -2
  33. package/dist/lib/create-project.d.ts.map +1 -1
  34. package/dist/lib/create-project.js +5 -21
  35. package/dist/lib/create-project.js.map +1 -1
  36. package/dist/lib/create-project.spec.js +9 -0
  37. package/dist/lib/create-project.spec.js.map +1 -1
  38. package/dist/lib/generate-secret.js +1 -1
  39. package/dist/lib/generate-secret.js.map +1 -1
  40. package/dist/lib/init-next.d.ts.map +1 -1
  41. package/dist/lib/init-next.js +5 -34
  42. package/dist/lib/init-next.js.map +1 -1
  43. package/dist/lib/init-tanstack-default-template.spec.js +121 -0
  44. package/dist/lib/init-tanstack-default-template.spec.js.map +1 -0
  45. package/dist/lib/init-tanstack.d.ts +18 -0
  46. package/dist/lib/init-tanstack.d.ts.map +1 -0
  47. package/dist/lib/init-tanstack.js +150 -0
  48. package/dist/lib/init-tanstack.js.map +1 -0
  49. package/dist/lib/init-tanstack.spec.js +394 -0
  50. package/dist/lib/init-tanstack.spec.js.map +1 -0
  51. package/dist/lib/tanstack/detect.d.ts +5 -0
  52. package/dist/lib/tanstack/detect.d.ts.map +1 -0
  53. package/dist/lib/tanstack/detect.js +131 -0
  54. package/dist/lib/tanstack/detect.js.map +1 -0
  55. package/dist/lib/tanstack/detect.spec.js +227 -0
  56. package/dist/lib/tanstack/detect.spec.js.map +1 -0
  57. package/dist/lib/tanstack/prepare.d.ts +23 -0
  58. package/dist/lib/tanstack/prepare.d.ts.map +1 -0
  59. package/dist/lib/tanstack/prepare.js +114 -0
  60. package/dist/lib/tanstack/prepare.js.map +1 -0
  61. package/dist/lib/tanstack/prepare.spec.js +288 -0
  62. package/dist/lib/tanstack/prepare.spec.js.map +1 -0
  63. package/dist/lib/tanstack/template-files.d.ts +50 -0
  64. package/dist/lib/tanstack/template-files.d.ts.map +1 -0
  65. package/dist/lib/tanstack/template-files.js +64 -0
  66. package/dist/lib/tanstack/template-files.js.map +1 -0
  67. package/dist/lib/tanstack/transform-root-route.d.ts +7 -0
  68. package/dist/lib/tanstack/transform-root-route.d.ts.map +1 -0
  69. package/dist/lib/tanstack/transform-root-route.js +747 -0
  70. package/dist/lib/tanstack/transform-root-route.js.map +1 -0
  71. package/dist/lib/tanstack/transform-root-route.spec.js +484 -0
  72. package/dist/lib/tanstack/transform-root-route.spec.js.map +1 -0
  73. package/dist/lib/tanstack/transform-router.d.ts +5 -0
  74. package/dist/lib/tanstack/transform-router.d.ts.map +1 -0
  75. package/dist/lib/tanstack/transform-router.js +301 -0
  76. package/dist/lib/tanstack/transform-router.js.map +1 -0
  77. package/dist/lib/tanstack/transform-router.spec.js +264 -0
  78. package/dist/lib/tanstack/transform-router.spec.js.map +1 -0
  79. package/dist/lib/tanstack/transform-vite-config.d.ts +14 -0
  80. package/dist/lib/tanstack/transform-vite-config.d.ts.map +1 -0
  81. package/dist/lib/tanstack/transform-vite-config.js +576 -0
  82. package/dist/lib/tanstack/transform-vite-config.js.map +1 -0
  83. package/dist/lib/tanstack/transform-vite-config.spec.js +456 -0
  84. package/dist/lib/tanstack/transform-vite-config.spec.js.map +1 -0
  85. package/dist/lib/templates.d.ts.map +1 -1
  86. package/dist/lib/templates.js +6 -0
  87. package/dist/lib/templates.js.map +1 -1
  88. package/dist/lib/update-payload-in-project.d.ts +18 -3
  89. package/dist/lib/update-payload-in-project.d.ts.map +1 -1
  90. package/dist/lib/update-payload-in-project.js +98 -18
  91. package/dist/lib/update-payload-in-project.js.map +1 -1
  92. package/dist/lib/update-payload-in-project.spec.js +262 -0
  93. package/dist/lib/update-payload-in-project.spec.js.map +1 -0
  94. package/dist/lib/wrap-next-config.d.ts.map +1 -1
  95. package/dist/main.d.ts +20 -1
  96. package/dist/main.d.ts.map +1 -1
  97. package/dist/main.js +120 -29
  98. package/dist/main.js.map +1 -1
  99. package/dist/main.spec.js +102 -0
  100. package/dist/main.spec.js.map +1 -0
  101. package/dist/scripts/pack-template-files.js +18 -0
  102. package/dist/scripts/pack-template-files.js.map +1 -1
  103. package/dist/template/src/app/(frontend)/styles.css +1 -1
  104. package/dist/template/src/app/(payload)/layout.tsx +8 -2
  105. package/dist/template-tanstack/routes/_payload/admin.$.tsx +8 -0
  106. package/dist/template-tanstack/routes/_payload/admin.index.tsx +8 -0
  107. package/dist/template-tanstack/routes/_payload/api.$.ts +10 -0
  108. package/dist/template-tanstack/routes/_payload/importMap.js +32 -0
  109. package/dist/template-tanstack/routes/_payload/server.functions.ts +49 -0
  110. package/dist/template-tanstack/routes/_payload.tsx +30 -0
  111. package/dist/template-tanstack/src/collections/Folders.ts +16 -0
  112. package/dist/template-tanstack/src/collections/Media.ts +20 -0
  113. package/dist/template-tanstack/src/collections/Tags.ts +16 -0
  114. package/dist/template-tanstack/src/collections/Users.ts +14 -0
  115. package/dist/template-tanstack/src/payload.config.ts +40 -0
  116. package/dist/template-tanstack/src/payload.css +1 -0
  117. package/dist/types.d.ts +22 -3
  118. package/dist/types.d.ts.map +1 -1
  119. package/dist/types.js.map +1 -1
  120. package/dist/utils/casing.d.ts.map +1 -1
  121. package/dist/utils/log.d.ts.map +1 -1
  122. package/dist/utils/messages.d.ts +1 -0
  123. package/dist/utils/messages.d.ts.map +1 -1
  124. package/dist/utils/messages.js +8 -6
  125. package/dist/utils/messages.js.map +1 -1
  126. package/package.json +4 -4
  127. package/dist/lib/download-skill.d.ts +0 -8
  128. package/dist/lib/download-skill.d.ts.map +0 -1
  129. package/dist/lib/download-skill.js +0 -35
  130. package/dist/lib/download-skill.js.map +0 -1
  131. package/dist/lib/select-agent.d.ts +0 -16
  132. package/dist/lib/select-agent.d.ts.map +0 -1
  133. package/dist/lib/select-agent.js +0 -67
  134. package/dist/lib/select-agent.js.map +0 -1
  135. /package/dist/template/src/app/(payload)/{custom.scss → custom.css} +0 -0
@@ -0,0 +1,394 @@
1
+ import fse from 'fs-extra';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
+ import { initTanStack } from './init-tanstack.js';
6
+ const mocks = vi.hoisted(()=>({
7
+ applyPreparedWrites: vi.fn(),
8
+ configurePayloadTsConfig: vi.fn(),
9
+ ensurePnpmBuildApprovals: vi.fn(),
10
+ getTanStackAppDetails: vi.fn(),
11
+ installPackages: vi.fn(),
12
+ prepareTanStackInit: vi.fn(),
13
+ resolvePackageVersion: vi.fn()
14
+ }));
15
+ vi.mock('../utils/resolvePackageVersion.js', async (importOriginal)=>({
16
+ ...await importOriginal(),
17
+ resolvePackageVersion: mocks.resolvePackageVersion
18
+ }));
19
+ vi.mock('./configure-payload-tsconfig.js', ()=>({
20
+ configurePayloadTsConfig: mocks.configurePayloadTsConfig
21
+ }));
22
+ vi.mock('./configure-pnpm-builds.js', ()=>({
23
+ ensurePnpmBuildApprovals: mocks.ensurePnpmBuildApprovals
24
+ }));
25
+ vi.mock('./install-packages.js', ()=>({
26
+ installPackages: mocks.installPackages
27
+ }));
28
+ vi.mock('./tanstack/detect.js', ()=>({
29
+ getTanStackAppDetails: mocks.getTanStackAppDetails
30
+ }));
31
+ vi.mock('./tanstack/prepare.js', ()=>({
32
+ applyPreparedWrites: mocks.applyPreparedWrites,
33
+ prepareTanStackInit: mocks.prepareTanStackInit
34
+ }));
35
+ describe('initTanStack', ()=>{
36
+ const templateRoot = '/tmp/tanstack-template';
37
+ let appDetails;
38
+ let preparedWrites;
39
+ let projectDir;
40
+ beforeEach(()=>{
41
+ vi.clearAllMocks();
42
+ projectDir = fse.mkdtempSync(path.join(os.tmpdir(), 'cpa-init-tanstack-'));
43
+ appDetails = createAppDetails({
44
+ kind: 'start',
45
+ projectDir
46
+ });
47
+ preparedWrites = [
48
+ {
49
+ content: 'export default {}\n',
50
+ filePath: path.join(projectDir, 'src/payload.config.ts')
51
+ }
52
+ ];
53
+ mocks.prepareTanStackInit.mockResolvedValue({
54
+ success: true,
55
+ writes: preparedWrites
56
+ });
57
+ mocks.applyPreparedWrites.mockResolvedValue(undefined);
58
+ mocks.ensurePnpmBuildApprovals.mockResolvedValue(undefined);
59
+ mocks.installPackages.mockResolvedValue({
60
+ success: true
61
+ });
62
+ mocks.configurePayloadTsConfig.mockResolvedValue(undefined);
63
+ mocks.resolvePackageVersion.mockResolvedValue('4.2.0');
64
+ mocks.getTanStackAppDetails.mockResolvedValue({
65
+ compatible: true,
66
+ details: appDetails,
67
+ detected: true
68
+ });
69
+ });
70
+ afterEach(()=>{
71
+ fse.removeSync(projectDir);
72
+ });
73
+ it('should prepare, apply, install, and configure in order', async ()=>{
74
+ const result = await initTanStack({
75
+ '--debug': true,
76
+ '--payload-version': 'beta',
77
+ appDetails,
78
+ dbType: 'mongodb',
79
+ packageManager: 'pnpm',
80
+ projectDir,
81
+ templateRoot
82
+ });
83
+ expect(result).toEqual({
84
+ payloadConfigPath: path.join(projectDir, 'src/payload.config.ts'),
85
+ success: true
86
+ });
87
+ expect(mocks.prepareTanStackInit).toHaveBeenCalledWith({
88
+ appDetails,
89
+ templateRoot
90
+ });
91
+ expect(mocks.applyPreparedWrites).toHaveBeenCalledWith({
92
+ writes: preparedWrites
93
+ });
94
+ expect(mocks.prepareTanStackInit).toHaveBeenCalledBefore(mocks.applyPreparedWrites);
95
+ expect(mocks.applyPreparedWrites).toHaveBeenCalledBefore(mocks.installPackages);
96
+ expect(mocks.resolvePackageVersion).toHaveBeenCalledWith({
97
+ debug: true,
98
+ packageName: 'payload',
99
+ versionOrTag: 'beta'
100
+ });
101
+ expect(mocks.ensurePnpmBuildApprovals).toHaveBeenCalledWith({
102
+ packageManager: 'pnpm',
103
+ projectDir
104
+ });
105
+ expect(mocks.configurePayloadTsConfig).toHaveBeenCalledWith({
106
+ configPath: path.join(projectDir, 'tsconfig.json'),
107
+ payloadConfigPath: path.join(projectDir, 'src/payload.config.ts')
108
+ });
109
+ });
110
+ it.each([
111
+ [
112
+ 'mongodb',
113
+ '@payloadcms/db-mongodb@4.2.0'
114
+ ],
115
+ [
116
+ 'postgres',
117
+ '@payloadcms/db-postgres@4.2.0'
118
+ ],
119
+ [
120
+ 'sqlite',
121
+ '@payloadcms/db-sqlite@4.2.0'
122
+ ]
123
+ ])('should install the exact Payload dependencies for %s', async (dbType, databasePackage)=>{
124
+ await initTanStack({
125
+ appDetails,
126
+ dbType,
127
+ packageManager: 'npm',
128
+ projectDir,
129
+ templateRoot
130
+ });
131
+ expect(mocks.installPackages).toHaveBeenCalledWith({
132
+ packageManager: 'npm',
133
+ packagesToInstall: [
134
+ '@payloadcms/plugin-mcp@4.2.0',
135
+ '@payloadcms/richtext-lexical@4.2.0',
136
+ '@payloadcms/tanstack-start@4.2.0',
137
+ '@payloadcms/ui@4.2.0',
138
+ '@vitejs/plugin-rsc@^0.5.21',
139
+ databasePackage,
140
+ 'graphql@^16.8.1',
141
+ 'payload@4.2.0',
142
+ 'sharp@0.34.2'
143
+ ],
144
+ projectDir
145
+ });
146
+ });
147
+ it('should replace Router-only plugin package metadata', async ()=>{
148
+ appDetails = createAppDetails({
149
+ kind: 'router-only',
150
+ projectDir
151
+ });
152
+ const packageJsonPath = path.join(projectDir, 'package.json');
153
+ const originalPackageContent = `{
154
+ "name": "router-app",
155
+ "scripts": {
156
+ "dev": "vite"
157
+ },
158
+ "dependencies": {
159
+ "@tanstack/router-plugin": "^1.0.0",
160
+ "payload": "^4.0.0"
161
+ },
162
+ "devDependencies": {
163
+ "@tanstack/router-plugin": "^1.0.0",
164
+ "typescript": "^6.0.0"
165
+ }
166
+ }`;
167
+ fse.writeFileSync(packageJsonPath, originalPackageContent);
168
+ await initTanStack({
169
+ appDetails,
170
+ dbType: 'mongodb',
171
+ packageManager: 'yarn',
172
+ projectDir,
173
+ templateRoot
174
+ });
175
+ expect(mocks.applyPreparedWrites).toHaveBeenCalledWith({
176
+ writes: [
177
+ ...preparedWrites,
178
+ {
179
+ content: `{
180
+ "name": "router-app",
181
+ "scripts": {
182
+ "dev": "vite"
183
+ },
184
+ "dependencies": {
185
+ "payload": "^4.0.0"
186
+ },
187
+ "devDependencies": {
188
+ "typescript": "^6.0.0"
189
+ }
190
+ }\n`,
191
+ filePath: packageJsonPath
192
+ }
193
+ ]
194
+ });
195
+ expect(fse.readFileSync(packageJsonPath, 'utf8')).toBe(originalPackageContent);
196
+ expect(mocks.installPackages).toHaveBeenCalledWith({
197
+ packageManager: 'yarn',
198
+ packagesToInstall: [
199
+ '@payloadcms/plugin-mcp@4.2.0',
200
+ '@payloadcms/richtext-lexical@4.2.0',
201
+ '@payloadcms/tanstack-start@4.2.0',
202
+ '@payloadcms/ui@4.2.0',
203
+ '@vitejs/plugin-rsc@^0.5.21',
204
+ '@payloadcms/db-mongodb@4.2.0',
205
+ 'graphql@^16.8.1',
206
+ 'payload@4.2.0',
207
+ 'sharp@0.34.2',
208
+ '@tanstack/react-start@^1.168.26'
209
+ ],
210
+ projectDir
211
+ });
212
+ });
213
+ it('should reject malformed Router package metadata before applying host writes', async ()=>{
214
+ appDetails = createAppDetails({
215
+ kind: 'router-only',
216
+ projectDir
217
+ });
218
+ const packageJsonPath = path.join(projectDir, 'package.json');
219
+ const malformedPackageContent = '{ "dependencies": {';
220
+ fse.writeFileSync(packageJsonPath, malformedPackageContent);
221
+ const result = await initTanStack({
222
+ appDetails,
223
+ dbType: 'mongodb',
224
+ packageManager: 'pnpm',
225
+ projectDir,
226
+ templateRoot
227
+ });
228
+ expect(result.success).toBe(false);
229
+ if (result.success) {
230
+ throw new Error('Expected malformed package metadata to fail preparation.');
231
+ }
232
+ expect(result.reason).toContain('Could not prepare package.json');
233
+ expect(fse.readFileSync(packageJsonPath, 'utf8')).toBe(malformedPackageContent);
234
+ expect(mocks.applyPreparedWrites).not.toHaveBeenCalled();
235
+ expect(mocks.installPackages).not.toHaveBeenCalled();
236
+ });
237
+ it.each([
238
+ {
239
+ existingDependencies: {
240
+ '@tanstack/react-router': '^1.200.0',
241
+ '@tanstack/react-start': '^1.200.0',
242
+ react: '^19.0.0'
243
+ },
244
+ existingDevDependencies: {
245
+ vite: '^7.0.0'
246
+ },
247
+ expectedDependencies: {
248
+ '@payloadcms/db-postgres': '4.2.0',
249
+ '@payloadcms/plugin-mcp': '4.2.0',
250
+ '@payloadcms/richtext-lexical': '4.2.0',
251
+ '@payloadcms/tanstack-start': '4.2.0',
252
+ '@payloadcms/ui': '4.2.0',
253
+ '@tanstack/react-router': '^1.200.0',
254
+ '@tanstack/react-start': '^1.200.0',
255
+ '@vitejs/plugin-rsc': '^0.5.21',
256
+ graphql: '^16.8.1',
257
+ payload: '4.2.0',
258
+ react: '^19.0.0',
259
+ sharp: '0.34.2'
260
+ },
261
+ expectedDevDependencies: {
262
+ vite: '^7.0.0'
263
+ },
264
+ kind: 'start'
265
+ },
266
+ {
267
+ existingDependencies: {
268
+ '@tanstack/react-router': '^1.200.0',
269
+ react: '^19.0.0'
270
+ },
271
+ existingDevDependencies: {
272
+ '@tanstack/router-plugin': '^1.200.0',
273
+ vite: '^7.0.0'
274
+ },
275
+ expectedDependencies: {
276
+ '@payloadcms/db-postgres': '4.2.0',
277
+ '@payloadcms/plugin-mcp': '4.2.0',
278
+ '@payloadcms/richtext-lexical': '4.2.0',
279
+ '@payloadcms/tanstack-start': '4.2.0',
280
+ '@payloadcms/ui': '4.2.0',
281
+ '@tanstack/react-router': '^1.200.0',
282
+ '@tanstack/react-start': '^1.168.26',
283
+ '@vitejs/plugin-rsc': '^0.5.21',
284
+ graphql: '^16.8.1',
285
+ payload: '4.2.0',
286
+ react: '^19.0.0',
287
+ sharp: '0.34.2'
288
+ },
289
+ expectedDevDependencies: {
290
+ vite: '^7.0.0'
291
+ },
292
+ kind: 'router-only'
293
+ }
294
+ ])('should record required dependencies without installing them for a $kind project with --no-deps', async ({ existingDependencies, existingDevDependencies, expectedDependencies, expectedDevDependencies, kind })=>{
295
+ appDetails = createAppDetails({
296
+ kind,
297
+ projectDir
298
+ });
299
+ const packageJsonPath = path.join(projectDir, 'package.json');
300
+ fse.writeJsonSync(packageJsonPath, {
301
+ dependencies: existingDependencies,
302
+ devDependencies: existingDevDependencies,
303
+ name: `${kind}-app`
304
+ });
305
+ const result = await initTanStack({
306
+ '--no-deps': true,
307
+ appDetails,
308
+ dbType: 'postgres',
309
+ packageManager: 'pnpm',
310
+ projectDir,
311
+ templateRoot
312
+ });
313
+ expect(result.success).toBe(true);
314
+ expect(mocks.resolvePackageVersion).toHaveBeenCalledWith({
315
+ debug: undefined,
316
+ packageName: 'payload',
317
+ versionOrTag: 'canary'
318
+ });
319
+ expect(mocks.ensurePnpmBuildApprovals).not.toHaveBeenCalled();
320
+ expect(mocks.installPackages).not.toHaveBeenCalled();
321
+ expect(mocks.configurePayloadTsConfig).toHaveBeenCalledOnce();
322
+ const appliedWrites = mocks.applyPreparedWrites.mock.calls[0]?.[0].writes;
323
+ const packageJsonWrite = appliedWrites.find(({ filePath })=>filePath === packageJsonPath);
324
+ expect(JSON.parse(packageJsonWrite?.content ?? '{}')).toEqual({
325
+ dependencies: expectedDependencies,
326
+ devDependencies: expectedDevDependencies,
327
+ name: `${kind}-app`
328
+ });
329
+ });
330
+ it('should return the preparation failure without applying writes', async ()=>{
331
+ mocks.prepareTanStackInit.mockResolvedValue({
332
+ reason: 'unsafe host transform',
333
+ success: false
334
+ });
335
+ const result = await initTanStack({
336
+ appDetails,
337
+ dbType: 'sqlite',
338
+ packageManager: 'bun',
339
+ projectDir,
340
+ templateRoot
341
+ });
342
+ expect(result).toEqual({
343
+ reason: 'unsafe host transform',
344
+ success: false
345
+ });
346
+ expect(mocks.applyPreparedWrites).not.toHaveBeenCalled();
347
+ expect(mocks.installPackages).not.toHaveBeenCalled();
348
+ });
349
+ it('should return a failure when dependency installation rejects', async ()=>{
350
+ mocks.installPackages.mockRejectedValue(new Error('Command failed with exit code 1'));
351
+ const result = await initTanStack({
352
+ appDetails,
353
+ dbType: 'mongodb',
354
+ packageManager: 'npm',
355
+ projectDir,
356
+ templateRoot
357
+ });
358
+ expect(result).toEqual({
359
+ reason: 'Failed to install dependencies',
360
+ success: false
361
+ });
362
+ expect(mocks.configurePayloadTsConfig).not.toHaveBeenCalled();
363
+ });
364
+ it('should detect app details when none are provided', async ()=>{
365
+ const result = await initTanStack({
366
+ dbType: 'mongodb',
367
+ packageManager: 'npm',
368
+ projectDir,
369
+ templateRoot
370
+ });
371
+ expect(result.success).toBe(true);
372
+ expect(mocks.getTanStackAppDetails).toHaveBeenCalledWith({
373
+ projectDir
374
+ });
375
+ expect(mocks.prepareTanStackInit).toHaveBeenCalledWith({
376
+ appDetails,
377
+ templateRoot
378
+ });
379
+ });
380
+ });
381
+ function createAppDetails({ kind, projectDir }) {
382
+ return {
383
+ isPayloadInstalled: false,
384
+ kind,
385
+ projectDir,
386
+ rootRoutePath: path.join(projectDir, 'src/routes/__root.tsx'),
387
+ routerPath: path.join(projectDir, 'src/router.tsx'),
388
+ routesDir: path.join(projectDir, 'src/routes'),
389
+ sourceDir: path.join(projectDir, 'src'),
390
+ viteConfigPath: path.join(projectDir, 'vite.config.ts')
391
+ };
392
+ }
393
+
394
+ //# sourceMappingURL=init-tanstack.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/init-tanstack.spec.ts"],"sourcesContent":["import fse from 'fs-extra'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport type { DbType, TanStackAppDetails } from '../types.js'\n\nimport { initTanStack } from './init-tanstack.js'\n\nconst mocks = vi.hoisted(() => ({\n applyPreparedWrites: vi.fn(),\n configurePayloadTsConfig: vi.fn(),\n ensurePnpmBuildApprovals: vi.fn(),\n getTanStackAppDetails: vi.fn(),\n installPackages: vi.fn(),\n prepareTanStackInit: vi.fn(),\n resolvePackageVersion: vi.fn(),\n}))\n\nvi.mock('../utils/resolvePackageVersion.js', async (importOriginal) => ({\n ...(await importOriginal()),\n resolvePackageVersion: mocks.resolvePackageVersion,\n}))\n\nvi.mock('./configure-payload-tsconfig.js', () => ({\n configurePayloadTsConfig: mocks.configurePayloadTsConfig,\n}))\n\nvi.mock('./configure-pnpm-builds.js', () => ({\n ensurePnpmBuildApprovals: mocks.ensurePnpmBuildApprovals,\n}))\n\nvi.mock('./install-packages.js', () => ({\n installPackages: mocks.installPackages,\n}))\n\nvi.mock('./tanstack/detect.js', () => ({\n getTanStackAppDetails: mocks.getTanStackAppDetails,\n}))\n\nvi.mock('./tanstack/prepare.js', () => ({\n applyPreparedWrites: mocks.applyPreparedWrites,\n prepareTanStackInit: mocks.prepareTanStackInit,\n}))\n\ndescribe('initTanStack', () => {\n const templateRoot = '/tmp/tanstack-template'\n let appDetails: TanStackAppDetails\n let preparedWrites: Array<{ content: string; filePath: string }>\n let projectDir: string\n\n beforeEach(() => {\n vi.clearAllMocks()\n projectDir = fse.mkdtempSync(path.join(os.tmpdir(), 'cpa-init-tanstack-'))\n appDetails = createAppDetails({ kind: 'start', projectDir })\n preparedWrites = [\n {\n content: 'export default {}\\n',\n filePath: path.join(projectDir, 'src/payload.config.ts'),\n },\n ]\n mocks.prepareTanStackInit.mockResolvedValue({ success: true, writes: preparedWrites })\n mocks.applyPreparedWrites.mockResolvedValue(undefined)\n mocks.ensurePnpmBuildApprovals.mockResolvedValue(undefined)\n mocks.installPackages.mockResolvedValue({ success: true })\n mocks.configurePayloadTsConfig.mockResolvedValue(undefined)\n mocks.resolvePackageVersion.mockResolvedValue('4.2.0')\n mocks.getTanStackAppDetails.mockResolvedValue({\n compatible: true,\n details: appDetails,\n detected: true,\n })\n })\n\n afterEach(() => {\n fse.removeSync(projectDir)\n })\n\n it('should prepare, apply, install, and configure in order', async () => {\n const result = await initTanStack({\n '--debug': true,\n '--payload-version': 'beta',\n appDetails,\n dbType: 'mongodb',\n packageManager: 'pnpm',\n projectDir,\n templateRoot,\n })\n\n expect(result).toEqual({\n payloadConfigPath: path.join(projectDir, 'src/payload.config.ts'),\n success: true,\n })\n expect(mocks.prepareTanStackInit).toHaveBeenCalledWith({ appDetails, templateRoot })\n expect(mocks.applyPreparedWrites).toHaveBeenCalledWith({ writes: preparedWrites })\n expect(mocks.prepareTanStackInit).toHaveBeenCalledBefore(mocks.applyPreparedWrites)\n expect(mocks.applyPreparedWrites).toHaveBeenCalledBefore(mocks.installPackages)\n expect(mocks.resolvePackageVersion).toHaveBeenCalledWith({\n debug: true,\n packageName: 'payload',\n versionOrTag: 'beta',\n })\n expect(mocks.ensurePnpmBuildApprovals).toHaveBeenCalledWith({\n packageManager: 'pnpm',\n projectDir,\n })\n expect(mocks.configurePayloadTsConfig).toHaveBeenCalledWith({\n configPath: path.join(projectDir, 'tsconfig.json'),\n payloadConfigPath: path.join(projectDir, 'src/payload.config.ts'),\n })\n })\n\n it.each<[DbType, string]>([\n ['mongodb', '@payloadcms/db-mongodb@4.2.0'],\n ['postgres', '@payloadcms/db-postgres@4.2.0'],\n ['sqlite', '@payloadcms/db-sqlite@4.2.0'],\n ])('should install the exact Payload dependencies for %s', async (dbType, databasePackage) => {\n await initTanStack({\n appDetails,\n dbType,\n packageManager: 'npm',\n projectDir,\n templateRoot,\n })\n\n expect(mocks.installPackages).toHaveBeenCalledWith({\n packageManager: 'npm',\n packagesToInstall: [\n '@payloadcms/plugin-mcp@4.2.0',\n '@payloadcms/richtext-lexical@4.2.0',\n '@payloadcms/tanstack-start@4.2.0',\n '@payloadcms/ui@4.2.0',\n '@vitejs/plugin-rsc@^0.5.21',\n databasePackage,\n 'graphql@^16.8.1',\n 'payload@4.2.0',\n 'sharp@0.34.2',\n ],\n projectDir,\n })\n })\n\n it('should replace Router-only plugin package metadata', async () => {\n appDetails = createAppDetails({ kind: 'router-only', projectDir })\n const packageJsonPath = path.join(projectDir, 'package.json')\n const originalPackageContent = `{\n \"name\": \"router-app\",\n \"scripts\": {\n \"dev\": \"vite\"\n },\n \"dependencies\": {\n \"@tanstack/router-plugin\": \"^1.0.0\",\n \"payload\": \"^4.0.0\"\n },\n \"devDependencies\": {\n \"@tanstack/router-plugin\": \"^1.0.0\",\n \"typescript\": \"^6.0.0\"\n }\n}`\n fse.writeFileSync(packageJsonPath, originalPackageContent)\n\n await initTanStack({\n appDetails,\n dbType: 'mongodb',\n packageManager: 'yarn',\n projectDir,\n templateRoot,\n })\n\n expect(mocks.applyPreparedWrites).toHaveBeenCalledWith({\n writes: [\n ...preparedWrites,\n {\n content: `{\n \"name\": \"router-app\",\n \"scripts\": {\n \"dev\": \"vite\"\n },\n \"dependencies\": {\n \"payload\": \"^4.0.0\"\n },\n \"devDependencies\": {\n \"typescript\": \"^6.0.0\"\n }\n}\\n`,\n filePath: packageJsonPath,\n },\n ],\n })\n expect(fse.readFileSync(packageJsonPath, 'utf8')).toBe(originalPackageContent)\n expect(mocks.installPackages).toHaveBeenCalledWith({\n packageManager: 'yarn',\n packagesToInstall: [\n '@payloadcms/plugin-mcp@4.2.0',\n '@payloadcms/richtext-lexical@4.2.0',\n '@payloadcms/tanstack-start@4.2.0',\n '@payloadcms/ui@4.2.0',\n '@vitejs/plugin-rsc@^0.5.21',\n '@payloadcms/db-mongodb@4.2.0',\n 'graphql@^16.8.1',\n 'payload@4.2.0',\n 'sharp@0.34.2',\n '@tanstack/react-start@^1.168.26',\n ],\n projectDir,\n })\n })\n\n it('should reject malformed Router package metadata before applying host writes', async () => {\n appDetails = createAppDetails({ kind: 'router-only', projectDir })\n const packageJsonPath = path.join(projectDir, 'package.json')\n const malformedPackageContent = '{ \"dependencies\": {'\n fse.writeFileSync(packageJsonPath, malformedPackageContent)\n\n const result = await initTanStack({\n appDetails,\n dbType: 'mongodb',\n packageManager: 'pnpm',\n projectDir,\n templateRoot,\n })\n\n expect(result.success).toBe(false)\n if (result.success) {\n throw new Error('Expected malformed package metadata to fail preparation.')\n }\n expect(result.reason).toContain('Could not prepare package.json')\n expect(fse.readFileSync(packageJsonPath, 'utf8')).toBe(malformedPackageContent)\n expect(mocks.applyPreparedWrites).not.toHaveBeenCalled()\n expect(mocks.installPackages).not.toHaveBeenCalled()\n })\n\n it.each([\n {\n existingDependencies: {\n '@tanstack/react-router': '^1.200.0',\n '@tanstack/react-start': '^1.200.0',\n react: '^19.0.0',\n },\n existingDevDependencies: { vite: '^7.0.0' },\n expectedDependencies: {\n '@payloadcms/db-postgres': '4.2.0',\n '@payloadcms/plugin-mcp': '4.2.0',\n '@payloadcms/richtext-lexical': '4.2.0',\n '@payloadcms/tanstack-start': '4.2.0',\n '@payloadcms/ui': '4.2.0',\n '@tanstack/react-router': '^1.200.0',\n '@tanstack/react-start': '^1.200.0',\n '@vitejs/plugin-rsc': '^0.5.21',\n graphql: '^16.8.1',\n payload: '4.2.0',\n react: '^19.0.0',\n sharp: '0.34.2',\n },\n expectedDevDependencies: { vite: '^7.0.0' },\n kind: 'start' as const,\n },\n {\n existingDependencies: {\n '@tanstack/react-router': '^1.200.0',\n react: '^19.0.0',\n },\n existingDevDependencies: {\n '@tanstack/router-plugin': '^1.200.0',\n vite: '^7.0.0',\n },\n expectedDependencies: {\n '@payloadcms/db-postgres': '4.2.0',\n '@payloadcms/plugin-mcp': '4.2.0',\n '@payloadcms/richtext-lexical': '4.2.0',\n '@payloadcms/tanstack-start': '4.2.0',\n '@payloadcms/ui': '4.2.0',\n '@tanstack/react-router': '^1.200.0',\n '@tanstack/react-start': '^1.168.26',\n '@vitejs/plugin-rsc': '^0.5.21',\n graphql: '^16.8.1',\n payload: '4.2.0',\n react: '^19.0.0',\n sharp: '0.34.2',\n },\n expectedDevDependencies: { vite: '^7.0.0' },\n kind: 'router-only' as const,\n },\n ])(\n 'should record required dependencies without installing them for a $kind project with --no-deps',\n async ({\n existingDependencies,\n existingDevDependencies,\n expectedDependencies,\n expectedDevDependencies,\n kind,\n }) => {\n appDetails = createAppDetails({ kind, projectDir })\n const packageJsonPath = path.join(projectDir, 'package.json')\n fse.writeJsonSync(packageJsonPath, {\n dependencies: existingDependencies,\n devDependencies: existingDevDependencies,\n name: `${kind}-app`,\n })\n\n const result = await initTanStack({\n '--no-deps': true,\n appDetails,\n dbType: 'postgres',\n packageManager: 'pnpm',\n projectDir,\n templateRoot,\n })\n\n expect(result.success).toBe(true)\n expect(mocks.resolvePackageVersion).toHaveBeenCalledWith({\n debug: undefined,\n packageName: 'payload',\n versionOrTag: 'canary',\n })\n expect(mocks.ensurePnpmBuildApprovals).not.toHaveBeenCalled()\n expect(mocks.installPackages).not.toHaveBeenCalled()\n expect(mocks.configurePayloadTsConfig).toHaveBeenCalledOnce()\n\n const appliedWrites = mocks.applyPreparedWrites.mock.calls[0]?.[0].writes as Array<{\n content: string\n filePath: string\n }>\n const packageJsonWrite = appliedWrites.find(({ filePath }) => filePath === packageJsonPath)\n\n expect(JSON.parse(packageJsonWrite?.content ?? '{}')).toEqual({\n dependencies: expectedDependencies,\n devDependencies: expectedDevDependencies,\n name: `${kind}-app`,\n })\n },\n )\n\n it('should return the preparation failure without applying writes', async () => {\n mocks.prepareTanStackInit.mockResolvedValue({ reason: 'unsafe host transform', success: false })\n\n const result = await initTanStack({\n appDetails,\n dbType: 'sqlite',\n packageManager: 'bun',\n projectDir,\n templateRoot,\n })\n\n expect(result).toEqual({ reason: 'unsafe host transform', success: false })\n expect(mocks.applyPreparedWrites).not.toHaveBeenCalled()\n expect(mocks.installPackages).not.toHaveBeenCalled()\n })\n\n it('should return a failure when dependency installation rejects', async () => {\n mocks.installPackages.mockRejectedValue(new Error('Command failed with exit code 1'))\n\n const result = await initTanStack({\n appDetails,\n dbType: 'mongodb',\n packageManager: 'npm',\n projectDir,\n templateRoot,\n })\n\n expect(result).toEqual({ reason: 'Failed to install dependencies', success: false })\n expect(mocks.configurePayloadTsConfig).not.toHaveBeenCalled()\n })\n\n it('should detect app details when none are provided', async () => {\n const result = await initTanStack({\n dbType: 'mongodb',\n packageManager: 'npm',\n projectDir,\n templateRoot,\n })\n\n expect(result.success).toBe(true)\n expect(mocks.getTanStackAppDetails).toHaveBeenCalledWith({ projectDir })\n expect(mocks.prepareTanStackInit).toHaveBeenCalledWith({ appDetails, templateRoot })\n })\n})\n\nfunction createAppDetails({\n kind,\n projectDir,\n}: {\n kind: TanStackAppDetails['kind']\n projectDir: string\n}): TanStackAppDetails {\n return {\n isPayloadInstalled: false,\n kind,\n projectDir,\n rootRoutePath: path.join(projectDir, 'src/routes/__root.tsx'),\n routerPath: path.join(projectDir, 'src/router.tsx'),\n routesDir: path.join(projectDir, 'src/routes'),\n sourceDir: path.join(projectDir, 'src'),\n viteConfigPath: path.join(projectDir, 'vite.config.ts'),\n }\n}\n"],"names":["fse","os","path","afterEach","beforeEach","describe","expect","it","vi","initTanStack","mocks","hoisted","applyPreparedWrites","fn","configurePayloadTsConfig","ensurePnpmBuildApprovals","getTanStackAppDetails","installPackages","prepareTanStackInit","resolvePackageVersion","mock","importOriginal","templateRoot","appDetails","preparedWrites","projectDir","clearAllMocks","mkdtempSync","join","tmpdir","createAppDetails","kind","content","filePath","mockResolvedValue","success","writes","undefined","compatible","details","detected","removeSync","result","dbType","packageManager","toEqual","payloadConfigPath","toHaveBeenCalledWith","toHaveBeenCalledBefore","debug","packageName","versionOrTag","configPath","each","databasePackage","packagesToInstall","packageJsonPath","originalPackageContent","writeFileSync","readFileSync","toBe","malformedPackageContent","Error","reason","toContain","not","toHaveBeenCalled","existingDependencies","react","existingDevDependencies","vite","expectedDependencies","graphql","payload","sharp","expectedDevDependencies","writeJsonSync","dependencies","devDependencies","name","toHaveBeenCalledOnce","appliedWrites","calls","packageJsonWrite","find","JSON","parse","mockRejectedValue","isPayloadInstalled","rootRoutePath","routerPath","routesDir","sourceDir","viteConfigPath"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { TanStackDetectionResult } from '../../types.js';
2
+ export declare function getTanStackAppDetails({ projectDir, }: {
3
+ projectDir: string;
4
+ }): Promise<TanStackDetectionResult>;
5
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/lib/tanstack/detect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAuC,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AASlG,wBAAsB,qBAAqB,CAAC,EAC1C,UAAU,GACX,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA8GnC"}
@@ -0,0 +1,131 @@
1
+ import fse from 'fs-extra';
2
+ import globby from 'globby';
3
+ import path from 'path';
4
+ const FILE_EXTENSIONS = 'js|jsx|ts|tsx|cjs|cts|mjs|mts';
5
+ export async function getTanStackAppDetails({ projectDir }) {
6
+ const absoluteProjectDir = path.resolve(projectDir);
7
+ const packageJson = await getPackageJson({
8
+ projectDir: absoluteProjectDir
9
+ });
10
+ const packages = {
11
+ ...packageJson.dependencies,
12
+ ...packageJson.devDependencies
13
+ };
14
+ const isSolidHost = Boolean(packages['@tanstack/solid-router'] || packages['@tanstack/solid-start']);
15
+ const hasReactRouter = Boolean(packages['@tanstack/react-router']);
16
+ const hasReactStart = Boolean(packages['@tanstack/react-start']);
17
+ const hasRouterPlugin = Boolean(packages['@tanstack/router-plugin']);
18
+ if (!isSolidHost && !hasReactRouter && !hasReactStart && !hasRouterPlugin) {
19
+ return {
20
+ detected: false
21
+ };
22
+ }
23
+ if (isSolidHost) {
24
+ return incompatible('TanStack Solid projects are not supported.');
25
+ }
26
+ if (hasReactStart && packages.next) {
27
+ return incompatible('TanStack Start and Next.js markers are both present.');
28
+ }
29
+ if (!hasReactRouter) {
30
+ return incompatible('Could not find @tanstack/react-router.');
31
+ }
32
+ const kind = hasReactStart ? 'start' : 'router-only';
33
+ const viteConfigPaths = await findFiles({
34
+ cwd: absoluteProjectDir,
35
+ pattern: `vite.config.@(${FILE_EXTENSIONS})`
36
+ });
37
+ if (viteConfigPaths.length > 1) {
38
+ return incompatible(getAmbiguousFilesReason({
39
+ filePaths: viteConfigPaths,
40
+ projectDir: absoluteProjectDir,
41
+ role: 'Vite config'
42
+ }));
43
+ }
44
+ const viteConfigPath = viteConfigPaths[0];
45
+ if (!viteConfigPath) {
46
+ return incompatible('Could not find a Vite config file.');
47
+ }
48
+ const viteConfig = await fse.readFile(viteConfigPath, 'utf8');
49
+ const pluginName = kind === 'start' ? 'tanstackStart' : 'tanstackRouter';
50
+ if (!new RegExp(`\\b${pluginName}\\s*\\(`).test(viteConfig)) {
51
+ return incompatible(`Could not find ${pluginName}() in ${viteConfigPath}.`);
52
+ }
53
+ const sourceDir = path.join(absoluteProjectDir, 'src');
54
+ const routesDir = path.join(sourceDir, 'routes');
55
+ const routerPaths = await findFiles({
56
+ cwd: sourceDir,
57
+ pattern: `router.@(${FILE_EXTENSIONS})`
58
+ });
59
+ if (routerPaths.length > 1) {
60
+ return incompatible(getAmbiguousFilesReason({
61
+ filePaths: routerPaths,
62
+ projectDir: absoluteProjectDir,
63
+ role: 'router'
64
+ }));
65
+ }
66
+ const routerPath = routerPaths[0];
67
+ if (!routerPath) {
68
+ return incompatible(`Could not find src/router.* in ${absoluteProjectDir}.`);
69
+ }
70
+ const router = await fse.readFile(routerPath, 'utf8');
71
+ if (!/\bgetRouter\b/.test(router)) {
72
+ return incompatible(`Could not find getRouter in ${routerPath}.`);
73
+ }
74
+ const rootRoutePaths = await findFiles({
75
+ cwd: routesDir,
76
+ pattern: `__root.@(${FILE_EXTENSIONS})`
77
+ });
78
+ if (rootRoutePaths.length > 1) {
79
+ return incompatible(getAmbiguousFilesReason({
80
+ filePaths: rootRoutePaths,
81
+ projectDir: absoluteProjectDir,
82
+ role: 'root route'
83
+ }));
84
+ }
85
+ const rootRoutePath = rootRoutePaths[0];
86
+ if (!rootRoutePath) {
87
+ return incompatible(`Could not find src/routes/__root.* in ${absoluteProjectDir}.`);
88
+ }
89
+ const details = {
90
+ isPayloadInstalled: Boolean(packages.payload),
91
+ kind,
92
+ projectDir: absoluteProjectDir,
93
+ rootRoutePath,
94
+ routerPath,
95
+ routesDir,
96
+ sourceDir,
97
+ viteConfigPath
98
+ };
99
+ return {
100
+ compatible: true,
101
+ details,
102
+ detected: true
103
+ };
104
+ }
105
+ function incompatible(reason) {
106
+ return {
107
+ compatible: false,
108
+ detected: true,
109
+ reason
110
+ };
111
+ }
112
+ function getAmbiguousFilesReason({ filePaths, projectDir, role }) {
113
+ const relativePaths = filePaths.map((filePath)=>path.relative(projectDir, filePath)).sort();
114
+ return `Found multiple supported ${role} files: ${relativePaths.join(', ')}.`;
115
+ }
116
+ async function findFiles({ cwd, pattern }) {
117
+ return globby(pattern, {
118
+ absolute: true,
119
+ cwd,
120
+ onlyFiles: true
121
+ });
122
+ }
123
+ async function getPackageJson({ projectDir }) {
124
+ const packageJsonPath = path.join(projectDir, 'package.json');
125
+ if (!await fse.pathExists(packageJsonPath)) {
126
+ return {};
127
+ }
128
+ return fse.readJson(packageJsonPath);
129
+ }
130
+
131
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/tanstack/detect.ts"],"sourcesContent":["import fse from 'fs-extra'\nimport globby from 'globby'\nimport path from 'path'\n\nimport type { TanStackAppDetails, TanStackAppKind, TanStackDetectionResult } from '../../types.js'\n\ntype PackageJson = {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\nconst FILE_EXTENSIONS = 'js|jsx|ts|tsx|cjs|cts|mjs|mts'\n\nexport async function getTanStackAppDetails({\n projectDir,\n}: {\n projectDir: string\n}): Promise<TanStackDetectionResult> {\n const absoluteProjectDir = path.resolve(projectDir)\n const packageJson = await getPackageJson({ projectDir: absoluteProjectDir })\n const packages = { ...packageJson.dependencies, ...packageJson.devDependencies }\n const isSolidHost = Boolean(\n packages['@tanstack/solid-router'] || packages['@tanstack/solid-start'],\n )\n const hasReactRouter = Boolean(packages['@tanstack/react-router'])\n const hasReactStart = Boolean(packages['@tanstack/react-start'])\n const hasRouterPlugin = Boolean(packages['@tanstack/router-plugin'])\n\n if (!isSolidHost && !hasReactRouter && !hasReactStart && !hasRouterPlugin) {\n return { detected: false }\n }\n\n if (isSolidHost) {\n return incompatible('TanStack Solid projects are not supported.')\n }\n\n if (hasReactStart && packages.next) {\n return incompatible('TanStack Start and Next.js markers are both present.')\n }\n\n if (!hasReactRouter) {\n return incompatible('Could not find @tanstack/react-router.')\n }\n\n const kind: TanStackAppKind = hasReactStart ? 'start' : 'router-only'\n const viteConfigPaths = await findFiles({\n cwd: absoluteProjectDir,\n pattern: `vite.config.@(${FILE_EXTENSIONS})`,\n })\n if (viteConfigPaths.length > 1) {\n return incompatible(\n getAmbiguousFilesReason({\n filePaths: viteConfigPaths,\n projectDir: absoluteProjectDir,\n role: 'Vite config',\n }),\n )\n }\n\n const viteConfigPath = viteConfigPaths[0]\n if (!viteConfigPath) {\n return incompatible('Could not find a Vite config file.')\n }\n\n const viteConfig = await fse.readFile(viteConfigPath, 'utf8')\n const pluginName = kind === 'start' ? 'tanstackStart' : 'tanstackRouter'\n if (!new RegExp(`\\\\b${pluginName}\\\\s*\\\\(`).test(viteConfig)) {\n return incompatible(`Could not find ${pluginName}() in ${viteConfigPath}.`)\n }\n\n const sourceDir = path.join(absoluteProjectDir, 'src')\n const routesDir = path.join(sourceDir, 'routes')\n const routerPaths = await findFiles({\n cwd: sourceDir,\n pattern: `router.@(${FILE_EXTENSIONS})`,\n })\n if (routerPaths.length > 1) {\n return incompatible(\n getAmbiguousFilesReason({\n filePaths: routerPaths,\n projectDir: absoluteProjectDir,\n role: 'router',\n }),\n )\n }\n\n const routerPath = routerPaths[0]\n if (!routerPath) {\n return incompatible(`Could not find src/router.* in ${absoluteProjectDir}.`)\n }\n\n const router = await fse.readFile(routerPath, 'utf8')\n if (!/\\bgetRouter\\b/.test(router)) {\n return incompatible(`Could not find getRouter in ${routerPath}.`)\n }\n\n const rootRoutePaths = await findFiles({\n cwd: routesDir,\n pattern: `__root.@(${FILE_EXTENSIONS})`,\n })\n if (rootRoutePaths.length > 1) {\n return incompatible(\n getAmbiguousFilesReason({\n filePaths: rootRoutePaths,\n projectDir: absoluteProjectDir,\n role: 'root route',\n }),\n )\n }\n\n const rootRoutePath = rootRoutePaths[0]\n if (!rootRoutePath) {\n return incompatible(`Could not find src/routes/__root.* in ${absoluteProjectDir}.`)\n }\n\n const details: TanStackAppDetails = {\n isPayloadInstalled: Boolean(packages.payload),\n kind,\n projectDir: absoluteProjectDir,\n rootRoutePath,\n routerPath,\n routesDir,\n sourceDir,\n viteConfigPath,\n }\n\n return { compatible: true, details, detected: true }\n}\n\nfunction incompatible(reason: string): TanStackDetectionResult {\n return { compatible: false, detected: true, reason }\n}\n\nfunction getAmbiguousFilesReason({\n filePaths,\n projectDir,\n role,\n}: {\n filePaths: string[]\n projectDir: string\n role: string\n}): string {\n const relativePaths = filePaths.map((filePath) => path.relative(projectDir, filePath)).sort()\n\n return `Found multiple supported ${role} files: ${relativePaths.join(', ')}.`\n}\n\nasync function findFiles({ cwd, pattern }: { cwd: string; pattern: string }): Promise<string[]> {\n return globby(pattern, {\n absolute: true,\n cwd,\n onlyFiles: true,\n })\n}\n\nasync function getPackageJson({ projectDir }: { projectDir: string }): Promise<PackageJson> {\n const packageJsonPath = path.join(projectDir, 'package.json')\n\n if (!(await fse.pathExists(packageJsonPath))) {\n return {}\n }\n\n return fse.readJson(packageJsonPath) as Promise<PackageJson>\n}\n"],"names":["fse","globby","path","FILE_EXTENSIONS","getTanStackAppDetails","projectDir","absoluteProjectDir","resolve","packageJson","getPackageJson","packages","dependencies","devDependencies","isSolidHost","Boolean","hasReactRouter","hasReactStart","hasRouterPlugin","detected","incompatible","next","kind","viteConfigPaths","findFiles","cwd","pattern","length","getAmbiguousFilesReason","filePaths","role","viteConfigPath","viteConfig","readFile","pluginName","RegExp","test","sourceDir","join","routesDir","routerPaths","routerPath","router","rootRoutePaths","rootRoutePath","details","isPayloadInstalled","payload","compatible","reason","relativePaths","map","filePath","relative","sort","absolute","onlyFiles","packageJsonPath","pathExists","readJson"],"mappings":"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"}