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
8 changes: 4 additions & 4 deletions packages/addons/drizzle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default defineAddon({

if (!kit) return unsupported('Requires SvelteKit');
},
run: ({ sv, typescript, options, kit, dependencyVersion, cwd, cancel }) => {
run: ({ sv, typescript, options, kit, dependencyVersion, cwd, cancel, files }) => {
if (!kit) throw new Error('SvelteKit is required');

const ext = typescript ? 'ts' : 'js';
Expand Down Expand Up @@ -177,7 +177,7 @@ export default defineAddon({
});
}

sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);
data.scripts ??= {};
const scripts: Record<string, string> = data.scripts;
Expand All @@ -191,7 +191,7 @@ export default defineAddon({

const hasPrettier = Boolean(dependencyVersion('prettier'));
if (hasPrettier) {
sv.file('.prettierignore', (content) => {
sv.file(files.prettierignore, (content) => {
if (!content.includes(`/drizzle/`)) {
return content.trimEnd() + '\n/drizzle/';
}
Expand All @@ -200,7 +200,7 @@ export default defineAddon({
}

if (options.database === 'sqlite') {
sv.file('.gitignore', (content) => {
sv.file(files.gitignore, (content) => {
// Adds the db file to the gitignore if an ignore is present
if (content.length === 0) return content;

Expand Down
10 changes: 5 additions & 5 deletions packages/addons/eslint/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default defineAddon({
shortDescription: 'linter',
homepage: 'https://eslint.org',
options: {},
run: ({ sv, typescript, dependencyVersion }) => {
run: ({ sv, typescript, dependencyVersion, files }) => {
const prettierInstalled = Boolean(dependencyVersion('prettier'));

sv.devDependency('eslint', '^9.39.1');
Expand All @@ -31,7 +31,7 @@ export default defineAddon({

if (prettierInstalled) sv.devDependency('eslint-config-prettier', '^10.1.8');

sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);
data.scripts ??= {};
const scripts: Record<string, string> = data.scripts;
Expand All @@ -41,7 +41,7 @@ export default defineAddon({
return generateCode();
});

sv.file('.vscode/settings.json', (content) => {
sv.file(files.vscodeSettings, (content) => {
if (!content) return content;

const { data, generateCode } = parseJson(content);
Expand All @@ -52,7 +52,7 @@ export default defineAddon({
return generateCode();
});

sv.file('eslint.config.js', (content) => {
sv.file(files.eslintConfig, (content) => {
const { ast, generateCode } = parseScript(content);

const eslintConfigs: Array<AstTypes.Expression | AstTypes.SpreadElement> = [];
Expand Down Expand Up @@ -170,7 +170,7 @@ export default defineAddon({
});

if (prettierInstalled) {
sv.file('eslint.config.js', addEslintConfigPrettier);
sv.file(files.eslintConfig, addEslintConfigPrettier);
}
}
});
2 changes: 1 addition & 1 deletion packages/addons/paraglide/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export default defineAddon({
return generateCode();
});

sv.file('.gitignore', (content) => {
sv.file(files.gitignore, (content) => {
if (!content) return content;

if (!content.includes(`\n${paraglideOutDir}`)) {
Expand Down
6 changes: 3 additions & 3 deletions packages/addons/playwright/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export default defineAddon({
shortDescription: 'browser testing',
homepage: 'https://playwright.dev',
options: {},
run: ({ sv, typescript }) => {
run: ({ sv, typescript, files }) => {
const ext = typescript ? 'ts' : 'js';

sv.devDependency('@playwright/test', '^1.56.1');

sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);
data.scripts ??= {};
const scripts: Record<string, string> = data.scripts;
Expand All @@ -24,7 +24,7 @@ export default defineAddon({
return generateCode();
});

sv.file('.gitignore', (content) => {
sv.file(files.gitignore, (content) => {
if (!content) return content;
if (content.includes('test-results')) return content;
return 'test-results\n' + content.trim();
Expand Down
10 changes: 5 additions & 5 deletions packages/addons/prettier/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export default defineAddon({
shortDescription: 'formatter',
homepage: 'https://prettier.io',
options: {},
run: ({ sv, dependencyVersion, kit }) => {
run: ({ sv, dependencyVersion, kit, files }) => {
const tailwindcssInstalled = Boolean(dependencyVersion('tailwindcss'));
if (tailwindcssInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.7.1');

sv.devDependency('prettier', '^3.6.2');
sv.devDependency('prettier-plugin-svelte', '^3.4.0');

sv.file('.prettierignore', (content) => {
sv.file(files.prettierignore, (content) => {
if (content) return content;
return dedent`
# Package Managers
Expand All @@ -29,7 +29,7 @@ export default defineAddon({
`;
});

sv.file('.prettierrc', (content) => {
sv.file(files.prettierrc, (content) => {
let data, generateCode;
try {
({ data, generateCode } = parseJson(content));
Expand Down Expand Up @@ -72,7 +72,7 @@ export default defineAddon({
const eslintVersion = dependencyVersion('eslint');
const eslintInstalled = hasEslint(eslintVersion);

sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);

data.scripts ??= {};
Expand All @@ -99,7 +99,7 @@ export default defineAddon({

if (eslintInstalled) {
sv.devDependency('eslint-config-prettier', '^10.1.8');
sv.file('eslint.config.js', addEslintConfigPrettier);
sv.file(files.eslintConfig, addEslintConfigPrettier);
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion packages/addons/sveltekit-adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default defineAddon({
const adapter = adapters.find((a) => a.id === options.adapter)!;

// removes previously installed adapters
sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);
const devDeps = data['devDependencies'];

Expand Down
30 changes: 12 additions & 18 deletions packages/addons/tailwindcss/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@ export default defineAddon({
run: ({ sv, options, files, typescript, kit, dependencyVersion }) => {
const prettierInstalled = Boolean(dependencyVersion('prettier'));

const stylesheet = kit
? ({
rootPath: `${kit.routesDirectory}/layout.css`,
relativePath: './layout.css'
} as const)
: ({
rootPath: 'src/app.css',
relativePath: './app.css'
} as const);

sv.devDependency('tailwindcss', '^4.1.17');
sv.devDependency('@tailwindcss/vite', '^4.1.17');
sv.pnpmBuildDependency('@tailwindcss/oxide');
Expand All @@ -68,7 +58,7 @@ export default defineAddon({
return generateCode();
});

sv.file(stylesheet.rootPath, (content) => {
sv.file(files.stylesheet, (content) => {
let atRules = parseCss(content).ast.nodes.filter((node) => node.type === 'atrule');

const findAtRule = (name: string, params: string) =>
Expand Down Expand Up @@ -104,15 +94,19 @@ export default defineAddon({
});

if (!kit) {
sv.file('src/App.svelte', (content) => {
const appSvelte = 'src/App.svelte';
const stylesheetRelative = files.getRelative({ from: appSvelte, to: files.stylesheet });
sv.file(appSvelte, (content) => {
const { script, generateCode } = parseSvelte(content, { typescript });
imports.addEmpty(script.ast, { from: stylesheet.relativePath });
imports.addEmpty(script.ast, { from: stylesheetRelative });
return generateCode({ script: script.generateCode() });
});
} else {
sv.file(`${kit?.routesDirectory}/+layout.svelte`, (content) => {
const layoutSvelte = `${kit?.routesDirectory}/+layout.svelte`;
const stylesheetRelative = files.getRelative({ from: layoutSvelte, to: files.stylesheet });
sv.file(layoutSvelte, (content) => {
const { script, template, generateCode } = parseSvelte(content, { typescript });
imports.addEmpty(script.ast, { from: stylesheet.relativePath });
imports.addEmpty(script.ast, { from: stylesheetRelative });

if (content.length === 0) {
const svelteVersion = dependencyVersion('svelte');
Expand All @@ -130,7 +124,7 @@ export default defineAddon({
});
}

sv.file('.vscode/settings.json', (content) => {
sv.file(files.vscodeSettings, (content) => {
const { data, generateCode } = parseJson(content);

data['files.associations'] ??= {};
Expand All @@ -140,7 +134,7 @@ export default defineAddon({
});

if (prettierInstalled) {
sv.file('.prettierrc', (content) => {
sv.file(files.prettierrc, (content) => {
const { data, generateCode } = parseJson(content);
const PLUGIN_NAME = 'prettier-plugin-tailwindcss';

Expand All @@ -149,7 +143,7 @@ export default defineAddon({

if (!plugins.includes(PLUGIN_NAME)) plugins.push(PLUGIN_NAME);

data.tailwindStylesheet ??= stylesheet.rootPath;
data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet });

return generateCode();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/addons/vitest-addon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default defineAddon({
sv.devDependency('playwright', '^1.56.1');
}

sv.file('package.json', (content) => {
sv.file(files.package, (content) => {
const { data, generateCode } = parseJson(content);
data.scripts ??= {};
const scripts: Record<string, string> = data.scripts;
Expand Down
28 changes: 26 additions & 2 deletions packages/cli/commands/add/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,37 @@ export async function createWorkspace({
dependencies[key] = value.replaceAll(/[^\d|.]/g, '');
}

const kit = dependencies['@sveltejs/kit'] ? parseKitOptions(resolvedCwd) : undefined;
const stylesheet: `${string}/layout.css` | 'src/app.css' = kit
? `${kit.routesDirectory}/layout.css`
: 'src/app.css';

return {
cwd: resolvedCwd,
options,
packageManager: packageManager ?? (await detect({ cwd }))?.name ?? getUserAgent() ?? 'npm',
typescript: usesTypescript,
files: { viteConfig, svelteConfig },
kit: dependencies['@sveltejs/kit'] ? parseKitOptions(resolvedCwd) : undefined,
files: {
viteConfig,
svelteConfig,
stylesheet,
package: 'package.json',
gitignore: '.gitignore',
prettierignore: '.prettierignore',
prettierrc: '.prettierrc',
eslintConfig: 'eslint.config.js',
vscodeSettings: '.vscode/settings.json',
getRelative({ from, to }) {
from = from ?? '';
let relativePath = path.posix.relative(path.posix.dirname(from), to);
// Ensure relative paths start with ./ for proper relative path syntax
if (!relativePath.startsWith('.') && !relativePath.startsWith('/')) {
relativePath = `./${relativePath}`;
}
return relativePath;
}
},
kit,
dependencyVersion: (pkg) => dependencies[pkg]
};
}
Expand Down
17 changes: 15 additions & 2 deletions packages/core/addon/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,21 @@ export type Workspace<Args extends OptionDefinition> = {
dependencyVersion: (pkg: string) => string | undefined;
typescript: boolean;
files: {
viteConfig: string;
svelteConfig: string;
viteConfig: 'vite.config.js' | 'vite.config.ts';
svelteConfig: 'svelte.config.js' | 'svelte.config.ts';
/** `${kit.routesDirectory}/layout.css` or `src/app.css` */
stylesheet: `${string}/layout.css` | 'src/app.css';
package: 'package.json';
gitignore: '.gitignore';

prettierignore: '.prettierignore';
prettierrc: '.prettierrc';
eslintConfig: 'eslint.config.js';

vscodeSettings: '.vscode/settings.json';

/** Get the relative path between two files */
getRelative: ({ from, to }: { from?: string; to: string }) => string;
};
kit: { libDirectory: string; routesDirectory: string } | undefined;
packageManager: PackageManager;
Expand Down
Loading