Skip to content

Commit 0f2744e

Browse files
committed
fix(create): normalize generated src js/jsx extensions for TypeScript
1 parent 7562b58 commit 0f2744e

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

.changeset/tidy-seas-hug.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/create': patch
3+
---
4+
5+
Normalize add-on source filenames under `src/` to TypeScript extensions when TypeScript is enabled, converting `.js` to `.ts` and `.jsx` to `.tsx`.

packages/create/src/template-file.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,28 @@ function convertDotFilesAndPaths(path: string) {
2424
.join(sep)
2525
}
2626

27+
function normalizeSourceExtension(target: string, typescript: boolean) {
28+
if (!typescript) {
29+
return target
30+
}
31+
32+
const normalizedTarget = target.replace(/\\/g, '/')
33+
34+
if (!normalizedTarget.startsWith('src/')) {
35+
return target
36+
}
37+
38+
if (normalizedTarget.endsWith('.js')) {
39+
return `${target.slice(0, -3)}.ts`
40+
}
41+
42+
if (normalizedTarget.endsWith('.jsx')) {
43+
return `${target.slice(0, -4)}.tsx`
44+
}
45+
46+
return target
47+
}
48+
2749
export function createTemplateFile(environment: Environment, options: Options) {
2850
function getPackageManagerAddScript(
2951
packageName: string,
@@ -146,6 +168,7 @@ export function createTemplateFile(environment: Environment, options: Options) {
146168
}
147169

148170
let target = convertDotFilesAndPaths(file.replace('.ejs', ''))
171+
target = normalizeSourceExtension(target, options.typescript)
149172

150173
// Strip option prefixes from filename (e.g., __postgres__schema.prisma -> schema.prisma)
151174
const prefixMatch = target.match(/^(.+\/)?__([^_]+)__(.+)$/)

packages/create/tests/template-file.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,32 @@ describe('createTemplateFile', () => {
175175
expect(output.files['/test/foo-dev.txt']).toEqual('pnpm add foo --dev')
176176
expect(output.files['/test/run-dev.txt']).toEqual('pnpm dev')
177177
})
178+
179+
it('should normalize src js files to ts when typescript is enabled', async () => {
180+
const { environment, output } = createMemoryEnvironment()
181+
const templateFile = createTemplateFile(environment, simpleOptions)
182+
183+
environment.startRun()
184+
await templateFile('src/lib/auth.js', 'export const auth = true')
185+
await templateFile('src/lib/auth-client.js', 'export const authClient = true')
186+
await templateFile('src/db.js', 'export const db = true')
187+
await templateFile('vite.config.js', 'export default {}')
188+
environment.finishRun()
189+
190+
expect(output.files['/test/src/lib/auth.ts']).toBeDefined()
191+
expect(output.files['/test/src/lib/auth-client.ts']).toBeDefined()
192+
expect(output.files['/test/src/db.ts']).toBeDefined()
193+
expect(output.files['/test/vite.config.js']).toBeDefined()
194+
})
195+
196+
it('should normalize src jsx files to tsx when typescript is enabled', async () => {
197+
const { environment, output } = createMemoryEnvironment()
198+
const templateFile = createTemplateFile(environment, simpleOptions)
199+
200+
environment.startRun()
201+
await templateFile('src/components/auth-button.jsx', 'export default function AuthButton() { return <button>Auth</button> }')
202+
environment.finishRun()
203+
204+
expect(output.files['/test/src/components/auth-button.tsx']).toBeDefined()
205+
})
178206
})

0 commit comments

Comments
 (0)