diff --git a/community-addon-template/src/index.js b/community-addon-template/src/index.js
index 3c2f5ee50..6cb0802dc 100644
--- a/community-addon-template/src/index.js
+++ b/community-addon-template/src/index.js
@@ -14,7 +14,7 @@ export default defineAddon({
setup: ({ kit, unsupported }) => {
if (!kit) unsupported('Requires SvelteKit');
},
- run: ({ sv, options, typescript }) => {
+ run: ({ sv, options, ext }) => {
sv.file('addon-template-demo.txt', (content) => {
if (options.demo) {
return 'This is a text file made by the Community Addon Template demo!';
@@ -25,7 +25,7 @@ export default defineAddon({
sv.file('src/DemoComponent.svelte', (content) => {
if (!options.demo) return content;
const { ast, generateCode } = parseSvelte(content);
- const scriptAst = svelte.ensureScript(ast, { langTs: typescript });
+ const scriptAst = svelte.ensureScript(ast, { ext });
js.imports.addDefault(scriptAst, { from: '../addon-template-demo.txt?raw', as: 'demo' });
return generateCode();
});
diff --git a/packages/sv/lib/addons/_tests/mdsvex/test.ts b/packages/sv/lib/addons/_tests/mdsvex/test.ts
index 5144d5ac9..31b6d0868 100644
--- a/packages/sv/lib/addons/_tests/mdsvex/test.ts
+++ b/packages/sv/lib/addons/_tests/mdsvex/test.ts
@@ -41,9 +41,8 @@ function addFixture(cwd: string, variant: string) {
}
const src = fs.readFileSync(page, 'utf8');
- const { ast, generateCode } = parseSvelte(src);
- const scriptAst = svelte.ensureScript(ast);
- imports.addDefault(scriptAst, { from: './Demo.svx', as: 'Demo' });
+ const { script, generateCode } = parseSvelte(src, { ensureScript: { ext: 'ts' } });
+ imports.addDefault(script, { from: './Demo.svx', as: 'Demo' });
const div = html.createElement('div', { class: 'mdsvex' });
div.fragment.nodes = svelte.toFragment('');
diff --git a/packages/sv/lib/addons/common.ts b/packages/sv/lib/addons/common.ts
index 95108f8c8..d2f46d10f 100644
--- a/packages/sv/lib/addons/common.ts
+++ b/packages/sv/lib/addons/common.ts
@@ -1,5 +1,5 @@
import { imports, exports, common } from '../core/tooling/js/index.ts';
-import { toFragment, type SvelteAst, ensureScript } from '../core/tooling/svelte/index.ts';
+import { toFragment, type SvelteAst } from '../core/tooling/svelte/index.ts';
import { parseScript, parseSvelte } from '../core/tooling/parsers.ts';
import process from 'node:process';
@@ -64,8 +64,8 @@ export function addEslintConfigPrettier(content: string): string {
return generateCode();
}
-export function addToDemoPage(existingContent: string, path: string, langTs: boolean): string {
- const { ast, generateCode } = parseSvelte(existingContent);
+export function addToDemoPage(existingContent: string, path: string, ext: 'ts' | 'js'): string {
+ const { ast, script, generateCode } = parseSvelte(existingContent, { ensureScript: { ext } });
for (const node of ast.fragment.nodes) {
if (node.type === 'RegularElement') {
@@ -86,7 +86,7 @@ export function addToDemoPage(existingContent: string, path: string, langTs: boo
}
}
- imports.addNamed(ensureScript(ast, { langTs }), { imports: ['resolve'], from: '$app/paths' });
+ imports.addNamed(script, { imports: ['resolve'], from: '$app/paths' });
ast.fragment.nodes.unshift(...toFragment(`${path}`));
ast.fragment.nodes.unshift();
diff --git a/packages/sv/lib/addons/drizzle/index.ts b/packages/sv/lib/addons/drizzle/index.ts
index 3ee9784fd..e3cdb20b1 100644
--- a/packages/sv/lib/addons/drizzle/index.ts
+++ b/packages/sv/lib/addons/drizzle/index.ts
@@ -85,10 +85,10 @@ export default defineAddon({
if (!kit) return unsupported('Requires SvelteKit');
},
- run: ({ sv, typescript, options, kit, dependencyVersion, cwd, cancel, files }) => {
+ run: ({ sv, ext, options, kit, dependencyVersion, cwd, cancel, files }) => {
if (!kit) throw new Error('SvelteKit is required');
- const ext = typescript ? 'ts' : 'js';
+ const typescript = ext === 'ts';
const baseDBPath = path.resolve(cwd, kit.libDirectory, 'server', 'db');
const paths = {
'drizzle config': path.resolve(cwd, `drizzle.config.${ext}`),
diff --git a/packages/sv/lib/addons/eslint/index.ts b/packages/sv/lib/addons/eslint/index.ts
index 49d716107..f8b1cb255 100644
--- a/packages/sv/lib/addons/eslint/index.ts
+++ b/packages/sv/lib/addons/eslint/index.ts
@@ -17,7 +17,8 @@ export default defineAddon({
shortDescription: 'linter',
homepage: 'https://eslint.org',
options: {},
- run: ({ sv, typescript, dependencyVersion, files }) => {
+ run: ({ sv, ext, dependencyVersion, files }) => {
+ const typescript = ext === 'ts';
const prettierInstalled = Boolean(dependencyVersion('prettier'));
sv.devDependency('eslint', '^9.39.1');
diff --git a/packages/sv/lib/addons/lucia/index.ts b/packages/sv/lib/addons/lucia/index.ts
index 3964788ce..ef316e328 100644
--- a/packages/sv/lib/addons/lucia/index.ts
+++ b/packages/sv/lib/addons/lucia/index.ts
@@ -45,8 +45,8 @@ export default defineAddon({
runsAfter('tailwindcss');
},
- run: ({ sv, typescript, options, kit, dependencyVersion }) => {
- const ext = typescript ? 'ts' : 'js';
+ run: ({ sv, ext, options, kit, dependencyVersion }) => {
+ const typescript = ext === 'ts';
sv.devDependency('@oslojs/crypto', '^1.0.1');
sv.devDependency('@oslojs/encoding', '^1.1.0');
@@ -387,7 +387,7 @@ export default defineAddon({
const { ast, generateCode } = parseScript(content);
js.imports.addNamespace(ast, { from: '$lib/server/auth', as: 'auth' });
js.kit.addHooksHandle(ast, {
- typescript,
+ ext,
newHandleName: 'handleAuth',
handleContent: getAuthHandleContent()
});
@@ -396,7 +396,7 @@ export default defineAddon({
if (options.demo) {
sv.file(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => {
- return addToDemoPage(content, 'lucia', typescript);
+ return addToDemoPage(content, 'lucia', ext);
});
sv.file(`${kit!.routesDirectory}/demo/lucia/login/+page.server.${ext}`, (content) => {
diff --git a/packages/sv/lib/addons/paraglide/index.ts b/packages/sv/lib/addons/paraglide/index.ts
index 55b502372..d9ebdf65b 100644
--- a/packages/sv/lib/addons/paraglide/index.ts
+++ b/packages/sv/lib/addons/paraglide/index.ts
@@ -62,8 +62,7 @@ export default defineAddon({
setup: ({ kit, unsupported }) => {
if (!kit) unsupported('Requires SvelteKit');
},
- run: ({ sv, options, files, typescript, kit }) => {
- const ext = typescript ? 'ts' : 'js';
+ run: ({ sv, options, files, ext, kit }) => {
if (!kit) throw new Error('SvelteKit is required');
const paraglideOutDir = 'src/lib/paraglide';
@@ -127,7 +126,7 @@ export default defineAddon({
});
});`;
kitJs.addHooksHandle(ast, {
- typescript,
+ ext,
newHandleName: 'handleParaglide',
handleContent: hookHandleContent
});
@@ -181,13 +180,15 @@ export default defineAddon({
});
sv.file(`${kit.routesDirectory}/+layout.svelte`, (content) => {
- const { ast, generateCode } = parseSvelte(content);
- const scriptAst = svelte.ensureScript(ast);
- imports.addNamed(scriptAst, {
+ const { ast, script, generateCode } = parseSvelte(content, {
+ ensureScript: { ext }
+ });
+
+ imports.addNamed(script, {
imports: ['locales', 'localizeHref'],
from: '$lib/paraglide/runtime'
});
- imports.addNamed(scriptAst, { imports: ['page'], from: '$app/state' });
+ imports.addNamed(script, { imports: ['page'], from: '$app/state' });
ast.fragment.nodes.push(
...svelte.toFragment(`
{#each locales as locale}
@@ -200,16 +201,17 @@ export default defineAddon({
if (options.demo) {
sv.file(`${kit.routesDirectory}/demo/+page.svelte`, (content) => {
- return addToDemoPage(content, 'paraglide', typescript);
+ return addToDemoPage(content, 'paraglide', ext);
});
// add usage example
sv.file(`${kit.routesDirectory}/demo/paraglide/+page.svelte`, (content) => {
- const { ast, generateCode } = parseSvelte(content);
- const scriptAst = svelte.ensureScript(ast, { langTs: typescript });
+ const { ast, script, generateCode } = parseSvelte(content, {
+ ensureScript: { ext }
+ });
- imports.addNamed(scriptAst, { imports: { m: 'm' }, from: '$lib/paraglide/messages.js' });
- imports.addNamed(scriptAst, {
+ imports.addNamed(script, { imports: { m: 'm' }, from: '$lib/paraglide/messages.js' });
+ imports.addNamed(script, {
imports: {
setLocale: 'setLocale'
},
diff --git a/packages/sv/lib/addons/playwright/index.ts b/packages/sv/lib/addons/playwright/index.ts
index 6bf862ed5..f0d749937 100644
--- a/packages/sv/lib/addons/playwright/index.ts
+++ b/packages/sv/lib/addons/playwright/index.ts
@@ -7,9 +7,7 @@ export default defineAddon({
shortDescription: 'browser testing',
homepage: 'https://playwright.dev',
options: {},
- run: ({ sv, typescript, files }) => {
- const ext = typescript ? 'ts' : 'js';
-
+ run: ({ sv, ext, files }) => {
sv.devDependency('@playwright/test', '^1.57.0');
sv.file(files.package, (content) => {
diff --git a/packages/sv/lib/addons/sveltekit-adapter/index.ts b/packages/sv/lib/addons/sveltekit-adapter/index.ts
index b5630edcc..7b23f034e 100644
--- a/packages/sv/lib/addons/sveltekit-adapter/index.ts
+++ b/packages/sv/lib/addons/sveltekit-adapter/index.ts
@@ -42,7 +42,7 @@ export default defineAddon({
setup: ({ kit, unsupported }) => {
if (!kit) unsupported('Requires SvelteKit');
},
- run: ({ sv, options, files, cwd, packageManager, typescript }) => {
+ run: ({ sv, options, files, cwd, packageManager, ext }) => {
const adapter = adapters.find((a) => a.id === options.adapter)!;
// removes previously installed adapters
@@ -171,7 +171,7 @@ export default defineAddon({
});
const jsconfig = fileExists(cwd, 'jsconfig.json');
- const typeChecked = typescript || jsconfig;
+ const typeChecked = ext === 'ts' || jsconfig;
if (typeChecked) {
// Ignore generated Cloudflare Types
diff --git a/packages/sv/lib/addons/tailwindcss/index.ts b/packages/sv/lib/addons/tailwindcss/index.ts
index c43fcb129..01db0fc58 100644
--- a/packages/sv/lib/addons/tailwindcss/index.ts
+++ b/packages/sv/lib/addons/tailwindcss/index.ts
@@ -33,7 +33,7 @@ export default defineAddon({
shortDescription: 'css framework',
homepage: 'https://tailwindcss.com',
options,
- run: ({ sv, options, files, kit, dependencyVersion, typescript }) => {
+ run: ({ sv, options, files, kit, dependencyVersion, ext }) => {
const prettierInstalled = Boolean(dependencyVersion('prettier'));
sv.devDependency('tailwindcss', '^4.1.17');
@@ -88,18 +88,19 @@ export default defineAddon({
const appSvelte = 'src/App.svelte';
const stylesheetRelative = files.getRelative({ from: appSvelte, to: files.stylesheet });
sv.file(appSvelte, (content) => {
- const { ast, generateCode } = parseSvelte(content);
- const scriptAst = svelte.ensureScript(ast, { langTs: typescript });
- imports.addEmpty(scriptAst, { from: stylesheetRelative });
+ const { script, generateCode } = parseSvelte(content, {
+ ensureScript: { ext }
+ });
+ imports.addEmpty(script, { from: stylesheetRelative });
return generateCode();
});
} else {
const layoutSvelte = `${kit?.routesDirectory}/+layout.svelte`;
const stylesheetRelative = files.getRelative({ from: layoutSvelte, to: files.stylesheet });
sv.file(layoutSvelte, (content) => {
- const { ast, generateCode } = parseSvelte(content);
- const scriptAst = svelte.ensureScript(ast, { langTs: typescript });
- imports.addEmpty(scriptAst, { from: stylesheetRelative });
+ const { ast, script, generateCode } = parseSvelte(content, { ensureScript: { ext } });
+
+ imports.addEmpty(script, { from: stylesheetRelative });
if (content.length === 0) {
const svelteVersion = dependencyVersion('svelte');
diff --git a/packages/sv/lib/addons/vitest-addon/index.ts b/packages/sv/lib/addons/vitest-addon/index.ts
index f2c048ad6..99fde6a8c 100644
--- a/packages/sv/lib/addons/vitest-addon/index.ts
+++ b/packages/sv/lib/addons/vitest-addon/index.ts
@@ -24,8 +24,7 @@ export default defineAddon({
homepage: 'https://vitest.dev',
options,
- run: ({ sv, files, typescript, kit, options, dependencyVersion }) => {
- const ext = typescript ? 'ts' : 'js';
+ run: ({ sv, files, ext, kit, options, dependencyVersion }) => {
const unitTesting = options.usages.includes('unit');
const componentTesting = options.usages.includes('component');
@@ -160,7 +159,7 @@ export default defineAddon({
});
},
- nextSteps: ({ highlighter, typescript, options }) => {
+ nextSteps: ({ highlighter, ext, options }) => {
const toReturn: string[] = [];
if (vitestV3Installed) {
@@ -175,7 +174,7 @@ export default defineAddon({
`${highlighter.optional('Optional')} Check ${highlighter.path('./vite.config.ts')} and remove duplicate project definitions`
);
toReturn.push(
- `${highlighter.optional('Optional')} Remove ${highlighter.path('./vitest-setup-client' + (typescript ? '.ts' : '.js'))} file`
+ `${highlighter.optional('Optional')} Remove ${highlighter.path('./vitest-setup-client.' + ext)} file`
);
}
diff --git a/packages/sv/lib/cli/add/workspace.ts b/packages/sv/lib/cli/add/workspace.ts
index 886ca7468..036b2317c 100644
--- a/packages/sv/lib/cli/add/workspace.ts
+++ b/packages/sv/lib/cli/add/workspace.ts
@@ -82,7 +82,7 @@ export async function createWorkspace({
return {
cwd: resolvedCwd,
packageManager: packageManager ?? (await detect({ cwd }))?.name ?? getUserAgent() ?? 'npm',
- typescript: usesTypescript,
+ ext: usesTypescript ? 'ts' : 'js',
files: {
viteConfig,
svelteConfig,
diff --git a/packages/sv/lib/cli/create.ts b/packages/sv/lib/cli/create.ts
index e02d2eeb6..132b7a681 100644
--- a/packages/sv/lib/cli/create.ts
+++ b/packages/sv/lib/cli/create.ts
@@ -386,7 +386,7 @@ export async function createVirtualWorkspace({
const virtualWorkspace: Workspace = {
...tentativeWorkspace,
- typescript: type === 'typescript',
+ ext: type === 'typescript' ? 'ts' : 'js',
files: {
...tentativeWorkspace.files,
viteConfig: type === 'typescript' ? commonFilePaths.viteConfigTS : commonFilePaths.viteConfig,
diff --git a/packages/sv/lib/core/addon/workspace.ts b/packages/sv/lib/core/addon/workspace.ts
index 4c1fdc4d0..f8e0d6242 100644
--- a/packages/sv/lib/core/addon/workspace.ts
+++ b/packages/sv/lib/core/addon/workspace.ts
@@ -13,7 +13,8 @@ export type Workspace = {
* @returns the dependency version with any leading characters such as ^ or ~ removed
*/
dependencyVersion: (pkg: string) => string | undefined;
- typescript: boolean;
+ /** to know if the workspace is using typescript or javascript */
+ ext: 'ts' | 'js';
files: {
viteConfig: 'vite.config.js' | 'vite.config.ts';
svelteConfig: 'svelte.config.js' | 'svelte.config.ts';
diff --git a/packages/sv/lib/core/tests/svelte/common/ensure-script-ts/run.ts b/packages/sv/lib/core/tests/svelte/common/ensure-script-ts/run.ts
index 3ac0c7533..ccac1642a 100644
--- a/packages/sv/lib/core/tests/svelte/common/ensure-script-ts/run.ts
+++ b/packages/sv/lib/core/tests/svelte/common/ensure-script-ts/run.ts
@@ -1,5 +1,5 @@
import { type SvelteAst, ensureScript } from '../../../../tooling/svelte/index.ts';
export function run(ast: SvelteAst.Root): void {
- ensureScript(ast, { langTs: true });
+ ensureScript(ast, { ext: 'ts' });
}
diff --git a/packages/sv/lib/core/tooling/js/kit.ts b/packages/sv/lib/core/tooling/js/kit.ts
index fed1cf763..571d24227 100644
--- a/packages/sv/lib/core/tooling/js/kit.ts
+++ b/packages/sv/lib/core/tooling/js/kit.ts
@@ -61,12 +61,12 @@ export function addGlobalAppInterface(
export function addHooksHandle(
node: AstTypes.Program,
options: {
- typescript: boolean;
+ ext: 'ts' | 'js';
newHandleName: string;
handleContent: string;
}
): void {
- if (options.typescript) {
+ if (options.ext === 'ts') {
imports.addNamed(node, {
from: '@sveltejs/kit',
imports: { Handle: 'Handle' },
@@ -133,7 +133,7 @@ export function addHooksHandle(
value: newHandle
});
- if (options.typescript) {
+ if (options.ext === 'ts') {
const declarator = newHandleDecl.declarations[0] as AstTypes.VariableDeclarator;
variables.typeAnnotateDeclarator(declarator, { typeName: 'Handle' });
}
@@ -145,7 +145,7 @@ export function addHooksHandle(
value: variables.createIdentifier(options.newHandleName)
});
- if (options.typescript) {
+ if (options.ext === 'ts') {
const declarator = handleDecl.declarations[0] as AstTypes.VariableDeclarator;
variables.typeAnnotateDeclarator(declarator, { typeName: 'Handle' });
}
@@ -163,7 +163,7 @@ export function addHooksHandle(
name: options.newHandleName,
value: newHandle
});
- if (options.typescript) {
+ if (options.ext === 'ts') {
const declarator = newHandleDecl.declarations[0] as AstTypes.VariableDeclarator;
variables.typeAnnotateDeclarator(declarator, { typeName: 'Handle' });
}
@@ -269,7 +269,7 @@ export function addHooksHandle(
name: handleName,
value: sequenceCall
});
- if (options.typescript) {
+ if (options.ext === 'ts') {
const declarator = finalHandleDecl.declarations[0] as AstTypes.VariableDeclarator;
variables.typeAnnotateDeclarator(declarator, { typeName: 'Handle' });
}
diff --git a/packages/sv/lib/core/tooling/parsers.ts b/packages/sv/lib/core/tooling/parsers.ts
index 2dc8c5972..d7408b9eb 100644
--- a/packages/sv/lib/core/tooling/parsers.ts
+++ b/packages/sv/lib/core/tooling/parsers.ts
@@ -1,5 +1,6 @@
import type { TomlTable } from 'smol-toml';
import * as utils from './index.ts';
+import { ensureScript } from './svelte/index.ts';
type ParseBase = {
source: string;
@@ -48,12 +49,30 @@ export function parseYaml(
return { data, source, generateCode };
}
-export function parseSvelte(source: string): { ast: utils.SvelteAst.Root } & ParseBase {
+export function parseSvelte(
+ source: string,
+ options: { ensureScript: Parameters[1] }
+): { ast: utils.SvelteAst.Root; script: utils.AstTypes.Program } & ParseBase;
+export function parseSvelte(
+ source: string,
+ options?: { ensureScript?: Parameters[1] }
+): { ast: utils.SvelteAst.Root; script?: utils.AstTypes.Program } & ParseBase;
+export function parseSvelte(
+ source: string,
+ options?: { ensureScript?: Parameters[1] }
+): { ast: utils.SvelteAst.Root; script?: utils.AstTypes.Program } & ParseBase {
const ast = utils.parseSvelte(source);
+
+ let script = ast.instance?.content;
+ if (options?.ensureScript) {
+ script = ensureScript(ast, options.ensureScript);
+ }
+
const generateCode = () => utils.serializeSvelte(ast);
return {
ast,
+ script,
source,
generateCode
};
diff --git a/packages/sv/lib/core/tooling/svelte/index.ts b/packages/sv/lib/core/tooling/svelte/index.ts
index c73df0908..c56408917 100644
--- a/packages/sv/lib/core/tooling/svelte/index.ts
+++ b/packages/sv/lib/core/tooling/svelte/index.ts
@@ -6,7 +6,7 @@ export type { SvelteAst };
export function ensureScript(
ast: SvelteAst.Root,
- options?: { langTs?: boolean }
+ options?: { ext?: 'ts' | 'js' }
): AstTypes.Program {
let scriptAst = ast.instance?.content;
if (!scriptAst) {
@@ -17,17 +17,18 @@ export function ensureScript(
end: 0,
context: 'default',
// @ts-expect-error
- attributes: options?.langTs
- ? [
- {
- type: 'Attribute',
- start: 8,
- end: 17,
- name: 'lang',
- value: [{ start: 14, end: 16, type: 'Text', raw: 'ts', data: 'ts' }]
- }
- ]
- : [],
+ attributes:
+ options?.ext === 'ts'
+ ? [
+ {
+ type: 'Attribute',
+ start: 8,
+ end: 17,
+ name: 'lang',
+ value: [{ start: 14, end: 16, type: 'Text', raw: 'ts', data: 'ts' }]
+ }
+ ]
+ : [],
content: scriptAst
};
}
@@ -37,7 +38,7 @@ export function ensureScript(
export function addSlot(
ast: SvelteAst.Root,
- options: { svelteVersion: string; langTs?: boolean }
+ options: { svelteVersion: string; ext?: 'ts' | 'js' }
): void {
const slotSyntax =
options.svelteVersion &&
@@ -60,7 +61,7 @@ export function addSlot(
return;
}
- const scriptAst = ensureScript(ast, { langTs: options.langTs });
+ const scriptAst = ensureScript(ast, { ext: options.ext });
appendFromString(scriptAst, {
code: 'const { children } = $props();'
});
diff --git a/packages/sv/lib/create/playground.ts b/packages/sv/lib/create/playground.ts
index 6ec216415..08b62a34f 100644
--- a/packages/sv/lib/create/playground.ts
+++ b/packages/sv/lib/create/playground.ts
@@ -102,8 +102,8 @@ export function detectPlaygroundDependencies(files: PlaygroundData['files']): Ma
for (const file of files) {
let ast: js.AstTypes.Program | undefined;
if (file.name.endsWith('.svelte')) {
- const { ast: svelteAst } = parseSvelte(file.content);
- ast = svelte.ensureScript(svelteAst);
+ const { script } = parseSvelte(file.content, { ensureScript: {} });
+ ast = script;
} else if (file.name.endsWith('.js') || file.name.endsWith('.ts')) {
ast = parseScript(file.content).ast;
}