From 79bab7656d77f643717e5c00c3bee1be5be7ce6c Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 18:10:35 +0100 Subject: [PATCH 01/10] rename workspace `files` to `file` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Singular form is more consistent — `file.viteConfig` reads better than `files.viteConfig` since each property refers to a single file. Prep for community add-on improvements. --- packages/sv/src/addons/better-auth.ts | 4 ++-- packages/sv/src/addons/devtools-json.ts | 4 ++-- packages/sv/src/addons/drizzle.ts | 8 ++++---- packages/sv/src/addons/eslint.ts | 10 +++++----- packages/sv/src/addons/mdsvex.ts | 4 ++-- packages/sv/src/addons/paraglide.ts | 6 +++--- packages/sv/src/addons/playwright.ts | 6 +++--- packages/sv/src/addons/prettier.ts | 14 +++++++------- packages/sv/src/addons/sveltekit-adapter.ts | 12 ++++++------ packages/sv/src/addons/tailwindcss.ts | 18 +++++++++--------- packages/sv/src/addons/vitest-addon.ts | 10 +++++----- packages/sv/src/cli/create.ts | 4 ++-- packages/sv/src/core/workspace.ts | 4 ++-- 13 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/sv/src/addons/better-auth.ts b/packages/sv/src/addons/better-auth.ts index f38dc58f3..60ee914ac 100644 --- a/packages/sv/src/addons/better-auth.ts +++ b/packages/sv/src/addons/better-auth.ts @@ -42,7 +42,7 @@ export default defineAddon({ runsAfter('sveltekitAdapter'); runsAfter('tailwindcss'); }, - run: ({ sv, language, options, kit, dependencyVersion, files }) => { + run: ({ sv, language, options, kit, dependencyVersion, file }) => { if (!kit) throw new Error('SvelteKit is required'); const demoPassword = options.demo.includes('password'); @@ -168,7 +168,7 @@ export default defineAddon({ const authConfigPath = `${kit?.libDirectory}/server/auth.${language}`; const authSchemaPath = `${kit?.libDirectory}/server/db/auth.schema.${language}`; - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert( data, diff --git a/packages/sv/src/addons/devtools-json.ts b/packages/sv/src/addons/devtools-json.ts index e4d8dc46a..156edd16a 100644 --- a/packages/sv/src/addons/devtools-json.ts +++ b/packages/sv/src/addons/devtools-json.ts @@ -7,11 +7,11 @@ export default defineAddon({ homepage: 'https://github.com/ChromeDevTools/vite-plugin-devtools-json', options: {}, - run: ({ sv, files }) => { + run: ({ sv, file }) => { sv.devDependency('vite-plugin-devtools-json', '^1.0.0'); // add the vite plugin - sv.file(files.viteConfig, (content) => { + sv.file(file.viteConfig, (content) => { const { ast, generateCode } = parse.script(content); const vitePluginName = 'devtoolsJson'; diff --git a/packages/sv/src/addons/drizzle.ts b/packages/sv/src/addons/drizzle.ts index 9a242e1be..ae0137b10 100644 --- a/packages/sv/src/addons/drizzle.ts +++ b/packages/sv/src/addons/drizzle.ts @@ -82,7 +82,7 @@ export default defineAddon({ if (!kit) return unsupported('Requires SvelteKit'); }, - run: ({ sv, language, options, kit, dependencyVersion, cwd, cancel, files }) => { + run: ({ sv, language, options, kit, dependencyVersion, cwd, cancel, file }) => { if (!kit) throw new Error('SvelteKit is required'); if (options.database === 'd1' && !dependencyVersion('@sveltejs/adapter-cloudflare')) { @@ -186,7 +186,7 @@ export default defineAddon({ }); } - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); if (options.docker) json.packageScriptsUpsert(data, 'db:start', 'docker compose up'); @@ -200,13 +200,13 @@ export default defineAddon({ const hasPrettier = Boolean(dependencyVersion('prettier')); if (hasPrettier) { - sv.file(files.prettierignore, (content) => { + sv.file(file.prettierignore, (content) => { return text.upsert(content, '/drizzle/'); }); } if (options.database === 'sqlite') { - sv.file(files.gitignore, (content) => { + sv.file(file.gitignore, (content) => { if (content.length === 0) return content; return text.upsert(content, '*.db', { comment: 'SQLite' }); }); diff --git a/packages/sv/src/addons/eslint.ts b/packages/sv/src/addons/eslint.ts index f57eec50f..feea56524 100644 --- a/packages/sv/src/addons/eslint.ts +++ b/packages/sv/src/addons/eslint.ts @@ -8,7 +8,7 @@ export default defineAddon({ shortDescription: 'linter', homepage: 'https://eslint.org', options: {}, - run: ({ sv, language, dependencyVersion, files }) => { + run: ({ sv, language, dependencyVersion, file }) => { const typescript = language === 'ts'; const prettierInstalled = Boolean(dependencyVersion('prettier')); @@ -23,7 +23,7 @@ export default defineAddon({ if (prettierInstalled) sv.devDependency('eslint-config-prettier', '^10.1.8'); - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert(data, 'lint', 'eslint .'); @@ -31,7 +31,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.eslintConfig, (content) => { + sv.file(file.eslintConfig, (content) => { const { ast, comments, generateCode } = parse.script(content); const eslintConfigs: Array = []; @@ -140,14 +140,14 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.vscodeExtensions, (content) => { + sv.file(file.vscodeExtensions, (content) => { const { data, generateCode } = parse.json(content); json.arrayUpsert(data, 'recommendations', 'dbaeumer.vscode-eslint'); return generateCode(); }); if (prettierInstalled) { - sv.file(files.eslintConfig, addEslintConfigPrettier); + sv.file(file.eslintConfig, addEslintConfigPrettier); } } }); diff --git a/packages/sv/src/addons/mdsvex.ts b/packages/sv/src/addons/mdsvex.ts index 30583f07a..644b30c6e 100644 --- a/packages/sv/src/addons/mdsvex.ts +++ b/packages/sv/src/addons/mdsvex.ts @@ -6,10 +6,10 @@ export default defineAddon({ shortDescription: 'svelte + markdown', homepage: 'https://mdsvex.pngwn.io', options: {}, - run: ({ sv, files }) => { + run: ({ sv, file }) => { sv.devDependency('mdsvex', '^0.12.6'); - sv.file(files.svelteConfig, (content) => { + sv.file(file.svelteConfig, (content) => { const { ast, generateCode } = parse.script(content); js.imports.addNamed(ast, { from: 'mdsvex', imports: ['mdsvex'] }); diff --git a/packages/sv/src/addons/paraglide.ts b/packages/sv/src/addons/paraglide.ts index 6bcde3224..143216076 100644 --- a/packages/sv/src/addons/paraglide.ts +++ b/packages/sv/src/addons/paraglide.ts @@ -53,7 +53,7 @@ export default defineAddon({ setup: ({ kit, unsupported }) => { if (!kit) unsupported('Requires SvelteKit'); }, - run: ({ sv, options, files, language, kit }) => { + run: ({ sv, options, file, language, kit }) => { if (!kit) throw new Error('SvelteKit is required'); const paraglideOutDir = 'src/lib/paraglide'; @@ -61,7 +61,7 @@ export default defineAddon({ sv.devDependency('@inlang/paraglide-js', '^2.10.0'); // add the vite plugin - sv.file(files.viteConfig, (content) => { + sv.file(file.viteConfig, (content) => { const { ast, generateCode } = parse.script(content); const vitePluginName = 'paraglideVitePlugin'; @@ -152,7 +152,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.gitignore, (content) => { + sv.file(file.gitignore, (content) => { if (!content) return content; content = text.upsert(content, paraglideOutDir, { comment: 'Paraglide' }); diff --git a/packages/sv/src/addons/playwright.ts b/packages/sv/src/addons/playwright.ts index 75216fe83..83b86cf2f 100644 --- a/packages/sv/src/addons/playwright.ts +++ b/packages/sv/src/addons/playwright.ts @@ -8,10 +8,10 @@ export default defineAddon({ shortDescription: 'browser testing', homepage: 'https://playwright.dev', options: {}, - run: ({ sv, language, files, kit }) => { + run: ({ sv, language, file, kit }) => { sv.devDependency('@playwright/test', '^1.58.2'); - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert(data, 'test:e2e', 'playwright test'); @@ -20,7 +20,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.gitignore, (content) => { + sv.file(file.gitignore, (content) => { if (!content) return content; return text.upsert(content, 'test-results', { comment: 'Playwright' }); }); diff --git a/packages/sv/src/addons/prettier.ts b/packages/sv/src/addons/prettier.ts index c1c7d307a..6d1af4a2a 100644 --- a/packages/sv/src/addons/prettier.ts +++ b/packages/sv/src/addons/prettier.ts @@ -8,14 +8,14 @@ export default defineAddon({ shortDescription: 'formatter', homepage: 'https://prettier.io', options: {}, - run: ({ sv, dependencyVersion, files }) => { + run: ({ sv, dependencyVersion, file }) => { const tailwindcssInstalled = Boolean(dependencyVersion('tailwindcss')); if (tailwindcssInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.7.2'); sv.devDependency('prettier', '^3.8.1'); sv.devDependency('prettier-plugin-svelte', '^3.4.1'); - sv.file(files.prettierignore, (content) => { + sv.file(file.prettierignore, (content) => { if (content) return content; return dedent` # Package Managers @@ -30,7 +30,7 @@ export default defineAddon({ `; }); - sv.file(files.prettierrc, (content) => { + sv.file(file.prettierrc, (content) => { let data, generateCode; try { ({ data, generateCode } = parse.json(content)); @@ -52,7 +52,7 @@ export default defineAddon({ if (tailwindcssInstalled) { json.arrayUpsert(data, 'plugins', 'prettier-plugin-tailwindcss'); - data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet }); + data.tailwindStylesheet ??= file.getRelative({ to: file.stylesheet }); } data.overrides ??= []; @@ -68,7 +68,7 @@ export default defineAddon({ const eslintVersion = dependencyVersion('eslint'); const eslintInstalled = hasEslint(eslintVersion); - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert(data, 'lint', 'prettier --check .', { mode: 'prepend' }); @@ -77,7 +77,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.vscodeExtensions, (content) => { + sv.file(file.vscodeExtensions, (content) => { const { data, generateCode } = parse.json(content); json.arrayUpsert(data, 'recommendations', 'esbenp.prettier-vscode'); return generateCode(); @@ -93,7 +93,7 @@ export default defineAddon({ if (eslintInstalled) { sv.devDependency('eslint-config-prettier', '^10.1.8'); - sv.file(files.eslintConfig, addEslintConfigPrettier); + sv.file(file.eslintConfig, addEslintConfigPrettier); } } }); diff --git a/packages/sv/src/addons/sveltekit-adapter.ts b/packages/sv/src/addons/sveltekit-adapter.ts index a05057391..c2e5a7ae7 100644 --- a/packages/sv/src/addons/sveltekit-adapter.ts +++ b/packages/sv/src/addons/sveltekit-adapter.ts @@ -41,11 +41,11 @@ export default defineAddon({ setup: ({ kit, unsupported }) => { if (!kit) unsupported('Requires SvelteKit'); }, - run: ({ sv, options, files, cwd, language }) => { + run: ({ sv, options, file, cwd, language }) => { const adapter = adapters.find((a) => a.id === options.adapter)!; // removes previously installed adapters - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); const devDeps = data['devDependencies']; @@ -69,7 +69,7 @@ export default defineAddon({ sv.devDependency(adapter.package, adapter.version); - sv.file(files.svelteConfig, (content) => { + sv.file(file.svelteConfig, (content) => { const { ast, comments, generateCode } = parse.script(content); // finds any existing adapter's import declaration @@ -136,7 +136,7 @@ export default defineAddon({ } if (!data.name) { - const pkg = parse.json(readFileSync(join(cwd, files.package), 'utf-8')); + const pkg = parse.json(readFileSync(join(cwd, file.package), 'utf-8')); data.name = sanitizeName(pkg.data.name, 'wrangler'); } @@ -172,7 +172,7 @@ export default defineAddon({ const typeChecked = language === 'ts' || jsconfig; if (typeChecked) { - sv.file(files.gitignore, (content) => { + sv.file(file.gitignore, (content) => { if (content.length === 0) return content; return text.upsert(content, '/worker-configuration.d.ts', { comment: 'Cloudflare Types' @@ -180,7 +180,7 @@ export default defineAddon({ }); // Setup wrangler types command - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert(data, 'gen', 'wrangler types'); diff --git a/packages/sv/src/addons/tailwindcss.ts b/packages/sv/src/addons/tailwindcss.ts index 00941ab25..9cb63d0d5 100644 --- a/packages/sv/src/addons/tailwindcss.ts +++ b/packages/sv/src/addons/tailwindcss.ts @@ -30,7 +30,7 @@ export default defineAddon({ shortDescription: 'css framework', homepage: 'https://tailwindcss.com', options, - run: ({ sv, options, files, kit, dependencyVersion, language }) => { + run: ({ sv, options, file, kit, dependencyVersion, language }) => { const prettierInstalled = Boolean(dependencyVersion('prettier')); sv.devDependency('tailwindcss', '^4.1.18'); @@ -46,7 +46,7 @@ export default defineAddon({ } // add the vite plugin - sv.file(files.viteConfig, (content) => { + sv.file(file.viteConfig, (content) => { const { ast, generateCode } = parse.script(content); const vitePluginName = 'tailwindcss'; @@ -56,7 +56,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.stylesheet, (content) => { + sv.file(file.stylesheet, (content) => { const { ast, generateCode } = parse.css(content); // since we are prepending all the `AtRule` let's add them in reverse order, @@ -83,7 +83,7 @@ export default defineAddon({ if (!kit) { const appSvelte = 'src/App.svelte'; - const stylesheetRelative = files.getRelative({ from: appSvelte, to: files.stylesheet }); + const stylesheetRelative = file.getRelative({ from: appSvelte, to: file.stylesheet }); sv.file(appSvelte, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); @@ -92,7 +92,7 @@ export default defineAddon({ }); } else { const layoutSvelte = `${kit?.routesDirectory}/+layout.svelte`; - const stylesheetRelative = files.getRelative({ from: layoutSvelte, to: files.stylesheet }); + const stylesheetRelative = file.getRelative({ from: layoutSvelte, to: file.stylesheet }); sv.file(layoutSvelte, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); @@ -110,7 +110,7 @@ export default defineAddon({ }); } - sv.file(files.vscodeSettings, (content) => { + sv.file(file.vscodeSettings, (content) => { const { data, generateCode } = parse.json(content); data['files.associations'] ??= {}; @@ -119,18 +119,18 @@ export default defineAddon({ return generateCode(); }); - sv.file(files.vscodeExtensions, (content) => { + sv.file(file.vscodeExtensions, (content) => { const { data, generateCode } = parse.json(content); json.arrayUpsert(data, 'recommendations', 'bradlc.vscode-tailwindcss'); return generateCode(); }); if (prettierInstalled) { - sv.file(files.prettierrc, (content) => { + sv.file(file.prettierrc, (content) => { const { data, generateCode } = parse.json(content); json.arrayUpsert(data, 'plugins', 'prettier-plugin-tailwindcss'); - data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet }); + data.tailwindStylesheet ??= file.getRelative({ to: file.stylesheet }); return generateCode(); }); diff --git a/packages/sv/src/addons/vitest-addon.ts b/packages/sv/src/addons/vitest-addon.ts index 50f632980..68948abf7 100644 --- a/packages/sv/src/addons/vitest-addon.ts +++ b/packages/sv/src/addons/vitest-addon.ts @@ -23,7 +23,7 @@ export default defineAddon({ homepage: 'https://vitest.dev', options, - run: ({ sv, files, language, kit, options, dependencyVersion }) => { + run: ({ sv, file, language, kit, options, dependencyVersion }) => { const unitTesting = options.usages.includes('unit'); const componentTesting = options.usages.includes('component'); @@ -40,7 +40,7 @@ export default defineAddon({ sv.devDependency('playwright', '^1.58.2'); } - sv.file(files.package, (content) => { + sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); json.packageScriptsUpsert(data, 'test:unit', 'vitest'); @@ -119,11 +119,11 @@ export default defineAddon({ }); } - sv.file(files.viteConfig, (content) => { + sv.file(file.viteConfig, (content) => { const { ast, generateCode } = parse.script(content); const clientObjectExpression = js.object.create({ - extends: `./${files.viteConfig}`, + extends: `./${file.viteConfig}`, test: { name: 'client', browser: { @@ -137,7 +137,7 @@ export default defineAddon({ }); const serverObjectExpression = js.object.create({ - extends: `./${files.viteConfig}`, + extends: `./${file.viteConfig}`, test: { name: 'server', environment: 'node', diff --git a/packages/sv/src/cli/create.ts b/packages/sv/src/cli/create.ts index 1ea4e63db..40c272e65 100644 --- a/packages/sv/src/cli/create.ts +++ b/packages/sv/src/cli/create.ts @@ -454,8 +454,8 @@ export async function createVirtualWorkspace({ const virtualWorkspace: Workspace = { ...tentativeWorkspace, language: type === 'typescript' ? 'ts' : 'js', - files: { - ...tentativeWorkspace.files, + file: { + ...tentativeWorkspace.file, viteConfig: type === 'typescript' ? commonFilePaths.viteConfigTS : commonFilePaths.viteConfig, svelteConfig: commonFilePaths.svelteConfig // currently we always use js files, never typescript files } diff --git a/packages/sv/src/core/workspace.ts b/packages/sv/src/core/workspace.ts index 7c0e6717e..9ee6422c8 100644 --- a/packages/sv/src/core/workspace.ts +++ b/packages/sv/src/core/workspace.ts @@ -21,7 +21,7 @@ export type Workspace = { dependencyVersion: (pkg: string) => string | undefined; /** to know if the workspace is using typescript or javascript */ language: 'ts' | 'js'; - files: { + file: { viteConfig: 'vite.config.js' | 'vite.config.ts'; svelteConfig: 'svelte.config.js' | 'svelte.config.ts'; /** `${kit.routesDirectory}/layout.css` or `src/app.css` */ @@ -119,7 +119,7 @@ export async function createWorkspace({ cwd: resolvedCwd, packageManager: packageManager ?? (await detectPackageManager(cwd)), language: typescript ? 'ts' : 'js', - files: { + file: { viteConfig, svelteConfig, stylesheet, From 2151f201bb254908b587635599a8ec8b126cb73b Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 18:54:23 +0100 Subject: [PATCH 02/10] changeset --- .changeset/icy-mice-jump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/icy-mice-jump.md diff --git a/.changeset/icy-mice-jump.md b/.changeset/icy-mice-jump.md new file mode 100644 index 000000000..ca3f82889 --- /dev/null +++ b/.changeset/icy-mice-jump.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +api change: rename `files` to `file` in the `run` phase From 348b09e398d3eab515782df3bc9d2fa15a3a8dbe Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 21:43:19 +0100 Subject: [PATCH 03/10] kit & directory --- packages/sv/src/addons/better-auth.ts | 69 ++++++++++----------- packages/sv/src/addons/drizzle.ts | 12 ++-- packages/sv/src/addons/paraglide.ts | 16 +++-- packages/sv/src/addons/playwright.ts | 16 ++--- packages/sv/src/addons/sveltekit-adapter.ts | 4 +- packages/sv/src/addons/tailwindcss.ts | 6 +- packages/sv/src/addons/vitest-addon.ts | 4 +- packages/sv/src/cli/create.ts | 10 +-- packages/sv/src/core/config.ts | 2 +- packages/sv/src/core/workspace.ts | 33 +++++----- 10 files changed, 84 insertions(+), 88 deletions(-) diff --git a/packages/sv/src/addons/better-auth.ts b/packages/sv/src/addons/better-auth.ts index 60ee914ac..96e5b0ae4 100644 --- a/packages/sv/src/addons/better-auth.ts +++ b/packages/sv/src/addons/better-auth.ts @@ -35,16 +35,14 @@ export default defineAddon({ shortDescription: 'auth library', homepage: 'https://www.better-auth.com', options, - setup: ({ kit, dependencyVersion, unsupported, dependsOn, runsAfter }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ isKit, dependencyVersion, unsupported, dependsOn, runsAfter }) => { + if (!isKit) unsupported('Requires SvelteKit'); if (!dependencyVersion('drizzle-orm')) dependsOn('drizzle'); runsAfter('sveltekitAdapter'); runsAfter('tailwindcss'); }, - run: ({ sv, language, options, kit, dependencyVersion, file }) => { - if (!kit) throw new Error('SvelteKit is required'); - + run: ({ sv, language, options, directory, dependencyVersion, file }) => { const demoPassword = options.demo.includes('password'); const demoGithub = options.demo.includes('github'); const hasDemo = demoPassword || demoGithub; @@ -89,7 +87,7 @@ export default defineAddon({ sv.file('.env', (content) => generateEnvFileContent(content, demoGithub, false)); sv.file('.env.example', (content) => generateEnvFileContent(content, demoGithub, true)); - sv.file(`${kit?.libDirectory}/server/auth.${language}`, (content) => { + sv.file(`${directory.lib}/server/auth.${language}`, (content) => { const { ast, generateCode, comments } = parse.script(content); js.imports.addNamed(ast, { from: '$lib/server/db', imports: [d1 ? 'getDb' : 'db'] }); @@ -165,8 +163,8 @@ export default defineAddon({ return generateCode(); }); - const authConfigPath = `${kit?.libDirectory}/server/auth.${language}`; - const authSchemaPath = `${kit?.libDirectory}/server/db/auth.schema.${language}`; + const authConfigPath = `${directory.lib}/server/auth.${language}`; + const authSchemaPath = `${directory.lib}/server/db/auth.schema.${language}`; sv.file(file.package, (content) => { const { data, generateCode } = parse.json(content); @@ -178,14 +176,14 @@ export default defineAddon({ return generateCode(); }); - sv.file(`${kit?.libDirectory}/server/db/auth.schema.${language}`, (content) => { + sv.file(`${directory.lib}/server/db/auth.schema.${language}`, (content) => { if (content) return content; return dedent` // If you see this file, you have not run the auth:schema script yet, but you should! `; }); - sv.file(`${kit?.libDirectory}/server/db/schema.${language}`, (content) => { + sv.file(`${directory.lib}/server/db/schema.${language}`, (content) => { const { ast, generateCode } = parse.script(content); js.exports.addNamespace(ast, { from: './auth.schema' }); @@ -276,25 +274,23 @@ export default defineAddon({ }); if (hasDemo) { - sv.file(`${kit?.routesDirectory}/demo/+page.svelte`, (content) => { + sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'better-auth', language); }); - sv.file( - `${kit!.routesDirectory}/demo/better-auth/login/+page.server.${language}`, - (content) => { - if (content) { - const filePath = `${kit!.routesDirectory}/demo/better-auth/login/+page.server.${language}`; - log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); - return content; - } + sv.file(`${directory.routes}/demo/better-auth/login/+page.server.${language}`, (content) => { + if (content) { + const filePath = `${directory.routes}/demo/better-auth/login/+page.server.${language}`; + log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); + return content; + } - const [ts] = createPrinter(language === 'ts'); + const [ts] = createPrinter(language === 'ts'); - const d1AuthLine = d1 ? '\n\t\t\t\t\t\t\tconst { auth } = event.locals;\n' : ''; + const d1AuthLine = d1 ? '\n\t\t\t\t\t\t\tconst { auth } = event.locals;\n' : ''; - const signInEmailAction = demoPassword - ? ` + const signInEmailAction = demoPassword + ? ` signInEmail: async (event) => {${d1AuthLine} const formData = await event.request.formData(); const email = formData.get('email')?.toString() ?? ''; @@ -341,10 +337,10 @@ export default defineAddon({ return redirect(302, '/demo/better-auth'); },` - : ''; + : ''; - const signInSocialAction = demoGithub - ? ` + const signInSocialAction = demoGithub + ? ` signInSocial: async (event) => {${d1AuthLine} const formData = await event.request.formData(); const provider = formData.get('provider')?.toString() ?? 'github'; @@ -362,11 +358,11 @@ export default defineAddon({ } return fail(400, { message: 'Social sign-in failed' }); },` - : ''; + : ''; - const needsAPIError = demoPassword; + const needsAPIError = demoPassword; - return dedent` + return dedent` import { fail, redirect } from '@sveltejs/kit'; ${ts("import type { Actions } from './$types';")} ${ts("import type { PageServerLoad } from './$types';")} @@ -383,12 +379,11 @@ export default defineAddon({ export const actions${ts(': Actions')} = {${signInEmailAction}${signInSocialAction} }; `; - } - ); + }); - sv.file(`${kit!.routesDirectory}/demo/better-auth/login/+page.svelte`, (content) => { + sv.file(`${directory.routes}/demo/better-auth/login/+page.svelte`, (content) => { if (content) { - const filePath = `${kit!.routesDirectory}/demo/better-auth/login/+page.svelte`; + const filePath = `${directory.routes}/demo/better-auth/login/+page.svelte`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } @@ -450,9 +445,9 @@ export default defineAddon({ `; }); - sv.file(`${kit!.routesDirectory}/demo/better-auth/+page.server.${language}`, (content) => { + sv.file(`${directory.routes}/demo/better-auth/+page.server.${language}`, (content) => { if (content) { - const filePath = `${kit!.routesDirectory}/demo/better-auth/+page.server.${language}`; + const filePath = `${directory.routes}/demo/better-auth/+page.server.${language}`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } @@ -483,9 +478,9 @@ export default defineAddon({ `; }); - sv.file(`${kit!.routesDirectory}/demo/better-auth/+page.svelte`, (content) => { + sv.file(`${directory.routes}/demo/better-auth/+page.svelte`, (content) => { if (content) { - const filePath = `${kit!.routesDirectory}/demo/better-auth/+page.svelte`; + const filePath = `${directory.routes}/demo/better-auth/+page.svelte`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } diff --git a/packages/sv/src/addons/drizzle.ts b/packages/sv/src/addons/drizzle.ts index ae0137b10..3d55dbcf8 100644 --- a/packages/sv/src/addons/drizzle.ts +++ b/packages/sv/src/addons/drizzle.ts @@ -76,21 +76,19 @@ export default defineAddon({ shortDescription: 'database orm', homepage: 'https://orm.drizzle.team', options, - setup: ({ kit, unsupported, runsAfter }) => { + setup: ({ isKit, unsupported, runsAfter }) => { runsAfter('prettier'); runsAfter('sveltekitAdapter'); - if (!kit) return unsupported('Requires SvelteKit'); + if (!isKit) return unsupported('Requires SvelteKit'); }, - run: ({ sv, language, options, kit, dependencyVersion, cwd, cancel, file }) => { - if (!kit) throw new Error('SvelteKit is required'); - + run: ({ sv, language, options, directory, dependencyVersion, cwd, cancel, file }) => { if (options.database === 'd1' && !dependencyVersion('@sveltejs/adapter-cloudflare')) { return cancel('Cloudflare D1 requires @sveltejs/adapter-cloudflare — add the adapter first'); } const typescript = language === 'ts'; - const baseDBPath = path.resolve(cwd, kit.libDirectory, 'server', 'db'); + const baseDBPath = path.resolve(cwd, directory.lib, 'server', 'db'); const paths = { 'drizzle config': path.resolve(cwd, `drizzle.config.${language}`), 'database schema': path.resolve(baseDBPath, `schema.${language}`), @@ -262,7 +260,7 @@ export default defineAddon({ js.exports.createDefault(ast, { fallback: js.common.parseExpression(` defineConfig({ - schema: "./src/lib/server/db/schema.${language}", + schema: "./${directory.lib}/server/db/schema.${language}", dialect: "${getDialect()}", ${d1 ? "driver: 'd1-http'," : ''} dbCredentials: { diff --git a/packages/sv/src/addons/paraglide.ts b/packages/sv/src/addons/paraglide.ts index 143216076..44d7401da 100644 --- a/packages/sv/src/addons/paraglide.ts +++ b/packages/sv/src/addons/paraglide.ts @@ -50,13 +50,11 @@ export default defineAddon({ shortDescription: 'i18n', homepage: 'https://inlang.com/m/gerre34r/library-inlang-paraglideJs', options, - setup: ({ kit, unsupported }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ isKit, unsupported }) => { + if (!isKit) unsupported('Requires SvelteKit'); }, - run: ({ sv, options, file, language, kit }) => { - if (!kit) throw new Error('SvelteKit is required'); - - const paraglideOutDir = 'src/lib/paraglide'; + run: ({ sv, options, file, language, directory }) => { + const paraglideOutDir = `${directory.lib}/paraglide`; sv.devDependency('@inlang/paraglide-js', '^2.10.0'); @@ -178,7 +176,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(`${kit.routesDirectory}/+layout.svelte`, (content) => { + sv.file(`${directory.routes}/+layout.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); js.imports.addNamed(ast.instance.content, { @@ -198,12 +196,12 @@ export default defineAddon({ }); if (options.demo) { - sv.file(`${kit.routesDirectory}/demo/+page.svelte`, (content) => { + sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide', language); }); // add usage example - sv.file(`${kit.routesDirectory}/demo/paraglide/+page.svelte`, (content) => { + sv.file(`${directory.routes}/demo/paraglide/+page.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); diff --git a/packages/sv/src/addons/playwright.ts b/packages/sv/src/addons/playwright.ts index 83b86cf2f..95b189a33 100644 --- a/packages/sv/src/addons/playwright.ts +++ b/packages/sv/src/addons/playwright.ts @@ -8,7 +8,7 @@ export default defineAddon({ shortDescription: 'browser testing', homepage: 'https://playwright.dev', options: {}, - run: ({ sv, language, file, kit }) => { + run: ({ sv, language, file, isKit, directory }) => { sv.devDependency('@playwright/test', '^1.58.2'); sv.file(file.package, (content) => { @@ -25,11 +25,11 @@ export default defineAddon({ return text.upsert(content, 'test-results', { comment: 'Playwright' }); }); - const testDir = kit ? `${kit.routesDirectory}/demo/playwright` : 'src'; - const testRoute = kit ? '/demo/playwright' : '/'; + const testDir = isKit ? `${directory.routes}/demo/playwright` : 'src'; + const testRoute = isKit ? '/demo/playwright' : '/'; - if (kit) { - sv.file(`${kit.routesDirectory}/demo/+page.svelte`, (content) => { + if (isKit) { + sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'playwright', language); }); @@ -42,7 +42,7 @@ export default defineAddon({ }); } - sv.file(`${testDir}/${kit ? 'page' : 'app'}.svelte.e2e.${language}`, (content) => { + sv.file(`${testDir}/${isKit ? 'page' : 'app'}.svelte.e2e.${language}`, (content) => { if (content) return content; return dedent` @@ -83,12 +83,12 @@ export default defineAddon({ }); }, - nextSteps: ({ kit }) => { + nextSteps: ({ isKit }) => { const steps: string[] = []; steps.push(`Run ${color.command('npx playwright install')} to download browsers`); - if (kit) { + if (isKit) { steps.push(`Visit ${color.route('/demo/playwright')} to see the demo page`); } diff --git a/packages/sv/src/addons/sveltekit-adapter.ts b/packages/sv/src/addons/sveltekit-adapter.ts index c2e5a7ae7..9ef0b2de6 100644 --- a/packages/sv/src/addons/sveltekit-adapter.ts +++ b/packages/sv/src/addons/sveltekit-adapter.ts @@ -38,8 +38,8 @@ export default defineAddon({ shortDescription: 'deployment', homepage: 'https://svelte.dev/docs/kit/adapters', options, - setup: ({ kit, unsupported }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ isKit, unsupported }) => { + if (!isKit) unsupported('Requires SvelteKit'); }, run: ({ sv, options, file, cwd, language }) => { const adapter = adapters.find((a) => a.id === options.adapter)!; diff --git a/packages/sv/src/addons/tailwindcss.ts b/packages/sv/src/addons/tailwindcss.ts index 9cb63d0d5..7c503c9f1 100644 --- a/packages/sv/src/addons/tailwindcss.ts +++ b/packages/sv/src/addons/tailwindcss.ts @@ -30,7 +30,7 @@ export default defineAddon({ shortDescription: 'css framework', homepage: 'https://tailwindcss.com', options, - run: ({ sv, options, file, kit, dependencyVersion, language }) => { + run: ({ sv, options, file, isKit, directory, dependencyVersion, language }) => { const prettierInstalled = Boolean(dependencyVersion('prettier')); sv.devDependency('tailwindcss', '^4.1.18'); @@ -81,7 +81,7 @@ export default defineAddon({ return generateCode(); }); - if (!kit) { + if (!isKit) { const appSvelte = 'src/App.svelte'; const stylesheetRelative = file.getRelative({ from: appSvelte, to: file.stylesheet }); sv.file(appSvelte, (content) => { @@ -91,7 +91,7 @@ export default defineAddon({ return generateCode(); }); } else { - const layoutSvelte = `${kit?.routesDirectory}/+layout.svelte`; + const layoutSvelte = `${directory.routes}/+layout.svelte`; const stylesheetRelative = file.getRelative({ from: layoutSvelte, to: file.stylesheet }); sv.file(layoutSvelte, (content) => { const { ast, generateCode } = parse.svelte(content); diff --git a/packages/sv/src/addons/vitest-addon.ts b/packages/sv/src/addons/vitest-addon.ts index 68948abf7..43e840e4c 100644 --- a/packages/sv/src/addons/vitest-addon.ts +++ b/packages/sv/src/addons/vitest-addon.ts @@ -23,7 +23,7 @@ export default defineAddon({ homepage: 'https://vitest.dev', options, - run: ({ sv, file, language, kit, options, dependencyVersion }) => { + run: ({ sv, file, language, directory, options, dependencyVersion }) => { const unitTesting = options.usages.includes('unit'); const componentTesting = options.usages.includes('component'); @@ -50,7 +50,7 @@ export default defineAddon({ return generateCode(); }); - const examplesDir = (kit ? kit.libDirectory : 'src/lib') + '/vitest-examples'; + const examplesDir = `${directory.lib}/vitest-examples`; const typed = language === 'ts'; if (unitTesting || componentTesting) { diff --git a/packages/sv/src/cli/create.ts b/packages/sv/src/cli/create.ts index 40c272e65..e8659b8c6 100644 --- a/packages/sv/src/cli/create.ts +++ b/packages/sv/src/cli/create.ts @@ -428,15 +428,17 @@ export async function createVirtualWorkspace({ type }: CreateVirtualWorkspaceOptions): Promise { const override: { - kit?: Workspace['kit']; + isKit?: boolean; + directory?: Workspace['directory']; dependencies: Record; } = { dependencies: {} }; // These are our default project structure so we know that it's a kit project if (template === 'minimal' || template === 'demo' || template === 'library') { - override.kit = { - routesDirectory: 'src/routes', - libDirectory: 'src/lib' + override.isKit = true; + override.directory = { + lib: 'src/lib', + routes: 'src/routes' }; } diff --git a/packages/sv/src/core/config.ts b/packages/sv/src/core/config.ts index 5ebd7fd0c..a89e4a9a6 100644 --- a/packages/sv/src/core/config.ts +++ b/packages/sv/src/core/config.ts @@ -50,7 +50,7 @@ export type Addon = { /** Why is this addon not supported? * * @example - * if (!kit) unsupported('Requires SvelteKit'); + * if (!isKit) unsupported('Requires SvelteKit'); */ unsupported: (reason: string) => void; diff --git a/packages/sv/src/core/workspace.ts b/packages/sv/src/core/workspace.ts index 9ee6422c8..b7e47d5e9 100644 --- a/packages/sv/src/core/workspace.ts +++ b/packages/sv/src/core/workspace.ts @@ -24,7 +24,7 @@ export type Workspace = { file: { viteConfig: 'vite.config.js' | 'vite.config.ts'; svelteConfig: 'svelte.config.js' | 'svelte.config.ts'; - /** `${kit.routesDirectory}/layout.css` or `src/app.css` */ + /** `${directory.routes}/layout.css` or `src/app.css` */ stylesheet: `${string}/layout.css` | 'src/app.css'; package: 'package.json'; gitignore: '.gitignore'; @@ -39,8 +39,8 @@ export type Workspace = { /** Get the relative path between two files */ getRelative: ({ from, to }: { from?: string; to: string }) => string; }; - /** If we are in a kit project, this object will contain the lib and routes directories */ - kit: { libDirectory: string; routesDirectory: string } | undefined; + isKit: boolean; + directory: { lib: string; routes: string }; /** The package manager used to install dependencies */ packageManager: AgentName; }; @@ -49,7 +49,8 @@ type CreateWorkspaceOptions = { cwd: string; packageManager?: AgentName; override?: { - kit?: Workspace['kit']; + isKit?: boolean; + directory?: Workspace['directory']; dependencies: Record; }; }; @@ -105,14 +106,15 @@ export async function createWorkspace({ dependencies[key] = value.replaceAll(/[^\d|.]/g, ''); } - const kit = override?.kit - ? override.kit - : dependencies['@sveltejs/kit'] + const isKit = override?.isKit ?? !!dependencies['@sveltejs/kit']; + const directory = override?.directory + ? override.directory + : isKit ? parseKitOptions(resolvedCwd, svelteConfig) - : undefined; + : { lib: 'src/lib', routes: 'src' }; - const stylesheet: `${string}/layout.css` | 'src/app.css' = kit - ? `${kit.routesDirectory}/layout.css` + const stylesheet: `${string}/layout.css` | 'src/app.css' = isKit + ? `${directory.routes}/layout.css` : 'src/app.css'; return { @@ -140,7 +142,8 @@ export async function createWorkspace({ return relativePath; } }, - kit, + isKit, + directory, dependencyVersion: (pkg) => dependencies[pkg] }; } @@ -215,8 +218,8 @@ function parseKitOptions(cwd: string, svelteConfigPath: string) { }); const lib = js.object.property(files, { name: 'lib', fallback: js.common.createLiteral('') }); - const routesDirectory = (routes.value as string) || 'src/routes'; - const libDirectory = (lib.value as string) || 'src/lib'; - - return { routesDirectory, libDirectory }; + return { + lib: (lib.value as string) || 'src/lib', + routes: (routes.value as string) || 'src/routes' + }; } From 44f0eaf95ca80dd118da9dc5dc2cadd8ae9fb064 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 21:49:47 +0100 Subject: [PATCH 04/10] changeset update --- .changeset/icy-mice-jump.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/icy-mice-jump.md b/.changeset/icy-mice-jump.md index ca3f82889..23fa9c71b 100644 --- a/.changeset/icy-mice-jump.md +++ b/.changeset/icy-mice-jump.md @@ -2,4 +2,4 @@ 'sv': patch --- -api change: rename `files` to `file` in the `run` phase +api: rename `files` to `file`, `kit` to `isKit` & `directory` From 65ba789e661e3899c246eb705b38498c7f91045f Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 22:11:56 +0100 Subject: [PATCH 05/10] update addon template to use isKit & directory --- .../sv/src/create/templates/addon/src/index.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/sv/src/create/templates/addon/src/index.js b/packages/sv/src/create/templates/addon/src/index.js index 889aab0af..b8d49cd64 100644 --- a/packages/sv/src/create/templates/addon/src/index.js +++ b/packages/sv/src/create/templates/addon/src/index.js @@ -13,18 +13,16 @@ export default defineAddon({ id: '~SV-NAME-TODO~', options, - setup: ({ kit, unsupported }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ isKit, unsupported }) => { + if (!isKit) unsupported('Requires SvelteKit'); }, - run: ({ kit, sv, options, language, cancel }) => { - if (!kit) return cancel('SvelteKit is required'); - - sv.file(`src/lib/~SV-NAME-TODO~/content.txt`, () => { + run: ({ directory, sv, options, language }) => { + sv.file(`${directory.lib}/~SV-NAME-TODO~/content.txt`, () => { return `This is a text file made by the Community Addon Template demo for the add-on: '~SV-NAME-TODO~'!`; }); - sv.file(`src/lib/~SV-NAME-TODO~/HelloComponent.svelte`, (content) => { + sv.file(`${directory.lib}/~SV-NAME-TODO~/HelloComponent.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); @@ -36,7 +34,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(kit.routesDirectory + '/+page.svelte', (content) => { + sv.file(directory.routes + '/+page.svelte', (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); From 46fc65912748310a62238e6d90de854682288bf4 Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 21 Mar 2026 22:21:54 +0100 Subject: [PATCH 06/10] update addon template snapshot --- .../cli/tests/snapshots/@my-org/sv/src/index.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js b/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js index bf1d89251..2c37a86a0 100644 --- a/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js +++ b/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js @@ -13,18 +13,16 @@ export default defineAddon({ id: '@my-org/sv', options, - setup: ({ kit, unsupported }) => { - if (!kit) unsupported('Requires SvelteKit'); + setup: ({ isKit, unsupported }) => { + if (!isKit) unsupported('Requires SvelteKit'); }, - run: ({ kit, sv, options, language, cancel }) => { - if (!kit) return cancel('SvelteKit is required'); - - sv.file(`src/lib/@my-org/sv/content.txt`, () => { + run: ({ directory, sv, options, language }) => { + sv.file(`${directory.lib}/@my-org/sv/content.txt`, () => { return `This is a text file made by the Community Addon Template demo for the add-on: '@my-org/sv'!`; }); - sv.file(`src/lib/@my-org/sv/HelloComponent.svelte`, (content) => { + sv.file(`${directory.lib}/@my-org/sv/HelloComponent.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); @@ -36,7 +34,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(kit.routesDirectory + '/+page.svelte', (content) => { + sv.file(directory.routes + '/+page.svelte', (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); From 7adb15edd50dcdfe5715d7775547b3402a8e25c9 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 27 Mar 2026 22:09:35 +0100 Subject: [PATCH 07/10] going to routes? --- packages/sv/src/addons/playwright.ts | 2 +- packages/sv/src/addons/tailwindcss.ts | 2 +- packages/sv/src/cli/create.ts | 1 + packages/sv/src/core/workspace.ts | 11 ++++++++--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/sv/src/addons/playwright.ts b/packages/sv/src/addons/playwright.ts index 95b189a33..68876e605 100644 --- a/packages/sv/src/addons/playwright.ts +++ b/packages/sv/src/addons/playwright.ts @@ -25,7 +25,7 @@ export default defineAddon({ return text.upsert(content, 'test-results', { comment: 'Playwright' }); }); - const testDir = isKit ? `${directory.routes}/demo/playwright` : 'src'; + const testDir = isKit ? `${directory.routes}/demo/playwright` : directory.src; const testRoute = isKit ? '/demo/playwright' : '/'; if (isKit) { diff --git a/packages/sv/src/addons/tailwindcss.ts b/packages/sv/src/addons/tailwindcss.ts index 7c503c9f1..c6757987b 100644 --- a/packages/sv/src/addons/tailwindcss.ts +++ b/packages/sv/src/addons/tailwindcss.ts @@ -82,7 +82,7 @@ export default defineAddon({ }); if (!isKit) { - const appSvelte = 'src/App.svelte'; + const appSvelte = `${directory.src}/App.svelte`; const stylesheetRelative = file.getRelative({ from: appSvelte, to: file.stylesheet }); sv.file(appSvelte, (content) => { const { ast, generateCode } = parse.svelte(content); diff --git a/packages/sv/src/cli/create.ts b/packages/sv/src/cli/create.ts index e8659b8c6..959c6bc75 100644 --- a/packages/sv/src/cli/create.ts +++ b/packages/sv/src/cli/create.ts @@ -437,6 +437,7 @@ export async function createVirtualWorkspace({ if (template === 'minimal' || template === 'demo' || template === 'library') { override.isKit = true; override.directory = { + src: 'src', lib: 'src/lib', routes: 'src/routes' }; diff --git a/packages/sv/src/core/workspace.ts b/packages/sv/src/core/workspace.ts index b7e47d5e9..3ba864550 100644 --- a/packages/sv/src/core/workspace.ts +++ b/packages/sv/src/core/workspace.ts @@ -40,7 +40,12 @@ export type Workspace = { getRelative: ({ from, to }: { from?: string; to: string }) => string; }; isKit: boolean; - directory: { lib: string; routes: string }; + directory: { + src: string; + lib: string; + /** Only available in SvelteKit projects. Check `isKit` */ + routes?: string; + }; /** The package manager used to install dependencies */ packageManager: AgentName; }; @@ -110,8 +115,8 @@ export async function createWorkspace({ const directory = override?.directory ? override.directory : isKit - ? parseKitOptions(resolvedCwd, svelteConfig) - : { lib: 'src/lib', routes: 'src' }; + ? { src: 'src', ...parseKitOptions(resolvedCwd, svelteConfig) } + : { src: 'src', lib: 'src/lib' }; const stylesheet: `${string}/layout.css` | 'src/app.css' = isKit ? `${directory.routes}/layout.css` From a3757acf724e27004810a5061403bff9f0226268 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 27 Mar 2026 22:27:13 +0100 Subject: [PATCH 08/10] kitRoutes with fallback & add an src --- packages/sv/src/addons/better-auth.ts | 18 +++++++++--------- packages/sv/src/addons/paraglide.ts | 6 +++--- packages/sv/src/addons/playwright.ts | 4 ++-- packages/sv/src/addons/tailwindcss.ts | 2 +- packages/sv/src/cli/create.ts | 2 +- .../tests/snapshots/@my-org/sv/src/index.js | 2 +- packages/sv/src/core/workspace.ts | 10 +++++----- .../sv/src/create/templates/addon/src/index.js | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/sv/src/addons/better-auth.ts b/packages/sv/src/addons/better-auth.ts index 96e5b0ae4..9a9eec89a 100644 --- a/packages/sv/src/addons/better-auth.ts +++ b/packages/sv/src/addons/better-auth.ts @@ -274,13 +274,13 @@ export default defineAddon({ }); if (hasDemo) { - sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'better-auth', language); }); - sv.file(`${directory.routes}/demo/better-auth/login/+page.server.${language}`, (content) => { + sv.file(`${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`, (content) => { if (content) { - const filePath = `${directory.routes}/demo/better-auth/login/+page.server.${language}`; + const filePath = `${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } @@ -381,9 +381,9 @@ export default defineAddon({ `; }); - sv.file(`${directory.routes}/demo/better-auth/login/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/better-auth/login/+page.svelte`, (content) => { if (content) { - const filePath = `${directory.routes}/demo/better-auth/login/+page.svelte`; + const filePath = `${directory.kitRoutes}/demo/better-auth/login/+page.svelte`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } @@ -445,9 +445,9 @@ export default defineAddon({ `; }); - sv.file(`${directory.routes}/demo/better-auth/+page.server.${language}`, (content) => { + sv.file(`${directory.kitRoutes}/demo/better-auth/+page.server.${language}`, (content) => { if (content) { - const filePath = `${directory.routes}/demo/better-auth/+page.server.${language}`; + const filePath = `${directory.kitRoutes}/demo/better-auth/+page.server.${language}`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } @@ -478,9 +478,9 @@ export default defineAddon({ `; }); - sv.file(`${directory.routes}/demo/better-auth/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/better-auth/+page.svelte`, (content) => { if (content) { - const filePath = `${directory.routes}/demo/better-auth/+page.svelte`; + const filePath = `${directory.kitRoutes}/demo/better-auth/+page.svelte`; log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); return content; } diff --git a/packages/sv/src/addons/paraglide.ts b/packages/sv/src/addons/paraglide.ts index 44d7401da..a72d4fcd8 100644 --- a/packages/sv/src/addons/paraglide.ts +++ b/packages/sv/src/addons/paraglide.ts @@ -176,7 +176,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(`${directory.routes}/+layout.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/+layout.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); js.imports.addNamed(ast.instance.content, { @@ -196,12 +196,12 @@ export default defineAddon({ }); if (options.demo) { - sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'paraglide', language); }); // add usage example - sv.file(`${directory.routes}/demo/paraglide/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/paraglide/+page.svelte`, (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); diff --git a/packages/sv/src/addons/playwright.ts b/packages/sv/src/addons/playwright.ts index 68876e605..9cda97cfc 100644 --- a/packages/sv/src/addons/playwright.ts +++ b/packages/sv/src/addons/playwright.ts @@ -25,11 +25,11 @@ export default defineAddon({ return text.upsert(content, 'test-results', { comment: 'Playwright' }); }); - const testDir = isKit ? `${directory.routes}/demo/playwright` : directory.src; + const testDir = isKit ? `${directory.kitRoutes}/demo/playwright` : directory.src; const testRoute = isKit ? '/demo/playwright' : '/'; if (isKit) { - sv.file(`${directory.routes}/demo/+page.svelte`, (content) => { + sv.file(`${directory.kitRoutes}/demo/+page.svelte`, (content) => { return addToDemoPage(content, 'playwright', language); }); diff --git a/packages/sv/src/addons/tailwindcss.ts b/packages/sv/src/addons/tailwindcss.ts index c6757987b..c14820d76 100644 --- a/packages/sv/src/addons/tailwindcss.ts +++ b/packages/sv/src/addons/tailwindcss.ts @@ -91,7 +91,7 @@ export default defineAddon({ return generateCode(); }); } else { - const layoutSvelte = `${directory.routes}/+layout.svelte`; + const layoutSvelte = `${directory.kitRoutes}/+layout.svelte`; const stylesheetRelative = file.getRelative({ from: layoutSvelte, to: file.stylesheet }); sv.file(layoutSvelte, (content) => { const { ast, generateCode } = parse.svelte(content); diff --git a/packages/sv/src/cli/create.ts b/packages/sv/src/cli/create.ts index 959c6bc75..9e9e94ddb 100644 --- a/packages/sv/src/cli/create.ts +++ b/packages/sv/src/cli/create.ts @@ -439,7 +439,7 @@ export async function createVirtualWorkspace({ override.directory = { src: 'src', lib: 'src/lib', - routes: 'src/routes' + kitRoutes: 'src/routes' }; } diff --git a/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js b/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js index 2c37a86a0..d1755e9e6 100644 --- a/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js +++ b/packages/sv/src/cli/tests/snapshots/@my-org/sv/src/index.js @@ -34,7 +34,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(directory.routes + '/+page.svelte', (content) => { + sv.file(directory.kitRoutes + '/+page.svelte', (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); diff --git a/packages/sv/src/core/workspace.ts b/packages/sv/src/core/workspace.ts index 3ba864550..1144a86dc 100644 --- a/packages/sv/src/core/workspace.ts +++ b/packages/sv/src/core/workspace.ts @@ -43,8 +43,8 @@ export type Workspace = { directory: { src: string; lib: string; - /** Only available in SvelteKit projects. Check `isKit` */ - routes?: string; + /** SvelteKit routes directory, taking `kit.files.routes` automatically. Falls back to `src/routes` in non-Kit projects */ + kitRoutes: string; }; /** The package manager used to install dependencies */ packageManager: AgentName; @@ -116,10 +116,10 @@ export async function createWorkspace({ ? override.directory : isKit ? { src: 'src', ...parseKitOptions(resolvedCwd, svelteConfig) } - : { src: 'src', lib: 'src/lib' }; + : { src: 'src', lib: 'src/lib', kitRoutes: 'src/routes' }; const stylesheet: `${string}/layout.css` | 'src/app.css' = isKit - ? `${directory.routes}/layout.css` + ? `${directory.kitRoutes}/layout.css` : 'src/app.css'; return { @@ -225,6 +225,6 @@ function parseKitOptions(cwd: string, svelteConfigPath: string) { return { lib: (lib.value as string) || 'src/lib', - routes: (routes.value as string) || 'src/routes' + kitRoutes: (routes.value as string) || 'src/routes' }; } diff --git a/packages/sv/src/create/templates/addon/src/index.js b/packages/sv/src/create/templates/addon/src/index.js index b8d49cd64..463b2b900 100644 --- a/packages/sv/src/create/templates/addon/src/index.js +++ b/packages/sv/src/create/templates/addon/src/index.js @@ -34,7 +34,7 @@ export default defineAddon({ return generateCode(); }); - sv.file(directory.routes + '/+page.svelte', (content) => { + sv.file(directory.kitRoutes + '/+page.svelte', (content) => { const { ast, generateCode } = parse.svelte(content); svelte.ensureScript(ast, { language }); From 7d5a6a71ce383b85a94c36b40aab4c8ca64c6a32 Mon Sep 17 00:00:00 2001 From: jycouet Date: Fri, 27 Mar 2026 22:36:05 +0100 Subject: [PATCH 09/10] fmt --- packages/sv/src/addons/better-auth.ts | 37 +++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/sv/src/addons/better-auth.ts b/packages/sv/src/addons/better-auth.ts index 9a9eec89a..87a263333 100644 --- a/packages/sv/src/addons/better-auth.ts +++ b/packages/sv/src/addons/better-auth.ts @@ -278,19 +278,21 @@ export default defineAddon({ return addToDemoPage(content, 'better-auth', language); }); - sv.file(`${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`, (content) => { - if (content) { - const filePath = `${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`; - log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); - return content; - } + sv.file( + `${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`, + (content) => { + if (content) { + const filePath = `${directory.kitRoutes}/demo/better-auth/login/+page.server.${language}`; + log.warn(`Existing ${color.warning(filePath)} file. Could not update.`); + return content; + } - const [ts] = createPrinter(language === 'ts'); + const [ts] = createPrinter(language === 'ts'); - const d1AuthLine = d1 ? '\n\t\t\t\t\t\t\tconst { auth } = event.locals;\n' : ''; + const d1AuthLine = d1 ? '\n\t\t\t\t\t\t\tconst { auth } = event.locals;\n' : ''; - const signInEmailAction = demoPassword - ? ` + const signInEmailAction = demoPassword + ? ` signInEmail: async (event) => {${d1AuthLine} const formData = await event.request.formData(); const email = formData.get('email')?.toString() ?? ''; @@ -337,10 +339,10 @@ export default defineAddon({ return redirect(302, '/demo/better-auth'); },` - : ''; + : ''; - const signInSocialAction = demoGithub - ? ` + const signInSocialAction = demoGithub + ? ` signInSocial: async (event) => {${d1AuthLine} const formData = await event.request.formData(); const provider = formData.get('provider')?.toString() ?? 'github'; @@ -358,11 +360,11 @@ export default defineAddon({ } return fail(400, { message: 'Social sign-in failed' }); },` - : ''; + : ''; - const needsAPIError = demoPassword; + const needsAPIError = demoPassword; - return dedent` + return dedent` import { fail, redirect } from '@sveltejs/kit'; ${ts("import type { Actions } from './$types';")} ${ts("import type { PageServerLoad } from './$types';")} @@ -379,7 +381,8 @@ export default defineAddon({ export const actions${ts(': Actions')} = {${signInEmailAction}${signInSocialAction} }; `; - }); + } + ); sv.file(`${directory.kitRoutes}/demo/better-auth/login/+page.svelte`, (content) => { if (content) { From 5fdc1b4b6a57672c29b50d8d4b1ff62b707b1f9f Mon Sep 17 00:00:00 2001 From: jycouet Date: Sat, 28 Mar 2026 22:12:06 +0100 Subject: [PATCH 10/10] add com --- packages/sv/src/core/workspace.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sv/src/core/workspace.ts b/packages/sv/src/core/workspace.ts index 9e8236399..b660833e8 100644 --- a/packages/sv/src/core/workspace.ts +++ b/packages/sv/src/core/workspace.ts @@ -49,8 +49,9 @@ export type Workspace = { isKit: boolean; directory: { src: string; + /** In SvelteKit taking `kit.files.lib` automatically. Falls back to `src/lib` in non-Kit projects */ lib: string; - /** SvelteKit routes directory, taking `kit.files.routes` automatically. Falls back to `src/routes` in non-Kit projects */ + /** In SvelteKit taking `kit.files.routes` automatically. Falls back to `src/routes` in non-Kit projects */ kitRoutes: string; }; /** The package manager used to install dependencies */