Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wide-geese-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'sv': patch
---

fix(cli): generating closing </script> tags now works correctly
1 change: 0 additions & 1 deletion packages/addons/drizzle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/lib/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>', '</script>'));
files.add(path);
} catch (e) {
if (e instanceof Error) {
Expand Down
83 changes: 83 additions & 0 deletions packages/core/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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\`
<script lang="ts">
console.log('Hello Literal');
</script>
\`;
`
);

const testFileFunction = path.join(testDir, 'testFunction.ts');
fs.writeFileSync(
testFileFunction,
`import dedent from 'dedent';

export const result = dedent(\`
<script lang="ts">
console.log('Hello Function');
</script>
\`);
`
);

// 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 </script> 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
Loading