diff --git a/.changeset/wide-geese-smoke.md b/.changeset/wide-geese-smoke.md new file mode 100644 index 000000000..5c58af8a2 --- /dev/null +++ b/.changeset/wide-geese-smoke.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix(cli): generating closing tags now works correctly diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 00495fc70..b455218ed 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -94,7 +94,6 @@ export default defineAddon({ return cancel(`Preexisting ${fileType} file at '${filePath}'`); } } - console.log(`no preexisting files`); sv.devDependency('drizzle-orm', '^0.44.6'); sv.devDependency('drizzle-kit', '^0.31.5'); sv.devDependency('@types/node', getNodeTypesVersion()); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index aafd6446a..e11c30574 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -142,7 +142,8 @@ async function runAddon({ addon, multiple, workspace }: RunAddon) { fileContent = content(fileContent); if (!fileContent) return fileContent; - writeFile(workspace, path, fileContent); + // TODO: fix https://github.com/rolldown/tsdown/issues/575 to remove the `replaceAll` + writeFile(workspace, path, fileContent.replaceAll('<\\/script>', '')); files.add(path); } catch (e) { if (e instanceof Error) { diff --git a/packages/core/tests/utils.ts b/packages/core/tests/utils.ts index 01139fbc4..10350d1a2 100644 --- a/packages/core/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -269,3 +269,86 @@ describe('yaml', () => { `); }); }); + +// TODO: fix https://github.com/rolldown/tsdown/issues/575 to remove the `skip` +test.skip('tsdown escapes script tags in bundled source code', async () => { + const { execSync } = await import('node:child_process'); + const fs = await import('node:fs'); + const path = await import('node:path'); + + const testDir = path.join('../..', '.test-output', `tsdown-test`); + fs.rmSync(testDir, { recursive: true, force: true }); + fs.mkdirSync(testDir, { recursive: true }); + + // Create a test file that uses dedent with script tags + const testFileLiteral = path.join(testDir, 'testLiteral.ts'); + fs.writeFileSync( + testFileLiteral, + `import dedent from 'dedent'; + +export const result = dedent\` + +\`; +` + ); + + const testFileFunction = path.join(testDir, 'testFunction.ts'); + fs.writeFileSync( + testFileFunction, + `import dedent from 'dedent'; + +export const result = dedent(\` + +\`); +` + ); + + // Create a tsdown config + const configFile = path.join(testDir, 'tsdown.config.ts'); + fs.writeFileSync( + configFile, + `import { defineConfig } from 'tsdown'; + +export default defineConfig({ + entry: ['testLiteral.ts', 'testFunction.ts'], + format: ['esm'], + outDir: 'dist', +}); +` + ); + + // Create package.json with tsdown + const pkgJson = { + name: 'test', + type: 'module', + devDependencies: { + tsdown: '^0.15.2', + dedent: '^1.6.0' + } + }; + fs.writeFileSync(path.join(testDir, 'package.json'), JSON.stringify(pkgJson, null, 2)); + + // Install dependencies and build + execSync('npm install', { cwd: testDir, stdio: 'pipe' }); + execSync('npx tsdown', { cwd: testDir, stdio: 'pipe' }); + + // Read the bundled output + const bundledFileLiteral = path.join(testDir, 'dist', 'testLiteral.js'); + const bundledFileFunction = path.join(testDir, 'dist', 'testFunction.js'); + const bundledCodeLiteral = fs.readFileSync(bundledFileLiteral, 'utf-8'); + const bundledCodeFunction = fs.readFileSync(bundledFileFunction, 'utf-8'); + + // Check if the bundled code contains escaped script tags + const hasEscapedScriptTagLiteral = bundledCodeLiteral.includes('<\\/script>'); + const hasEscapedScriptTagFunction = bundledCodeFunction.includes('<\\/script>'); + + // This test demonstrates the issue: tsdown escapes in the bundled source + // Expected: Bundled code should NOT contain escaped script tags + // Actual: Bundled code contains <\/script> when using dedent`...` syntax + expect(hasEscapedScriptTagLiteral).toBe(false); + expect(hasEscapedScriptTagFunction).toBe(false); +}, 30000); // 30s timeout for npm install and build