Skip to content
5 changes: 5 additions & 0 deletions .changeset/proud-baboons-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"sv": patch
---

fix(cli): `kit` projects were detected incorrectly
4 changes: 2 additions & 2 deletions packages/addons/prettier/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default defineAddon({
shortDescription: 'formatter',
homepage: 'https://prettier.io',
options: {},
run: ({ sv, dependencyVersion, kit, files }) => {
run: ({ sv, dependencyVersion, files }) => {
const tailwindcssInstalled = Boolean(dependencyVersion('tailwindcss'));
if (tailwindcssInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.7.1');

Expand Down Expand Up @@ -53,7 +53,7 @@ export default defineAddon({
if (!plugins.includes('prettier-plugin-tailwindcss')) {
data.plugins.unshift('prettier-plugin-tailwindcss');
}
data.tailwindStylesheet ??= kit ? `${kit?.routesDirectory}/layout.css` : './src/app.css';
data.tailwindStylesheet ??= files.getRelative({ to: files.stylesheet });
}
if (!plugins.includes('prettier-plugin-svelte')) {
data.plugins.unshift('prettier-plugin-svelte');
Expand Down
17 changes: 13 additions & 4 deletions packages/cli/commands/add/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import { getUserAgent } from '../../utils/package-manager.ts';
type CreateWorkspaceOptions = {
cwd: string;
packageManager?: PackageManager;
override?: {
kit?: Workspace['kit'];
};
};
export async function createWorkspace({
cwd,
packageManager
packageManager,
override
}: CreateWorkspaceOptions): Promise<Workspace> {
const resolvedCwd = path.resolve(cwd);

Expand All @@ -28,8 +32,8 @@ export async function createWorkspace({
const viteConfig = fs.existsSync(viteConfigPath)
? commonFilePaths.viteConfigTS
: commonFilePaths.viteConfig;
const sveteConfigPath = path.join(resolvedCwd, commonFilePaths.svelteConfigTS);
const svelteConfig = fs.existsSync(sveteConfigPath)
const svelteConfigPath = path.join(resolvedCwd, commonFilePaths.svelteConfigTS);
const svelteConfig = fs.existsSync(svelteConfigPath)
? commonFilePaths.svelteConfigTS
: commonFilePaths.svelteConfig;

Expand Down Expand Up @@ -59,7 +63,12 @@ export async function createWorkspace({
dependencies[key] = value.replaceAll(/[^\d|.]/g, '');
}

const kit = dependencies['@sveltejs/kit'] ? parseKitOptions(resolvedCwd) : undefined;
const kit = override?.kit
? override.kit
: dependencies['@sveltejs/kit']
? parseKitOptions(resolvedCwd)
: undefined;

const stylesheet: `${string}/layout.css` | 'src/app.css' = kit
? `${kit.routesDirectory}/layout.css`
: 'src/app.css';
Expand Down
24 changes: 13 additions & 11 deletions packages/cli/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,18 @@ export async function createVirtualWorkspace({
packageManager,
type
}: CreateVirtualWorkspaceOptions): Promise<Workspace> {
const tentativeWorkspace = await createWorkspace({ cwd, packageManager });
const override: { kit?: Workspace['kit'] } = {};

// 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'
};
}

const tentativeWorkspace = await createWorkspace({ cwd, packageManager, override });

const virtualWorkspace: Workspace = {
...tentativeWorkspace,
typescript: type === 'typescript',
Expand All @@ -372,17 +383,8 @@ export async function createVirtualWorkspace({
viteConfig: type === 'typescript' ? commonFilePaths.viteConfigTS : commonFilePaths.viteConfig,
svelteConfig:
type === 'typescript' ? commonFilePaths.svelteConfigTS : commonFilePaths.svelteConfig
},
kit: undefined,
dependencyVersion: () => undefined
}
};

if (template === 'minimal' || template === 'demo' || template === 'library') {
virtualWorkspace.kit = {
routesDirectory: 'src/routes',
libDirectory: 'src/lib'
};
}

return virtualWorkspace;
}
31 changes: 27 additions & 4 deletions packages/cli/tests/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,32 @@ beforeAll(() => {
});

describe('cli', () => {
it('should be able to create a new project with cli command', async () => {
const testCases = [
{ projectName: 'create-only', args: ['--no-add-ons'] },
{
projectName: 'create-with-all-addons',
args: [
'--add',
'prettier',
'eslint',
'vitest=usages:unit,component',
'playwright',
'tailwindcss=plugins:typography,forms',
'sveltekit-adapter=adapter:node',
'devtools-json',
'drizzle=database:sqlite+sqlite:libsql',
'lucia=demo:yes',
'mdsvex',
'paraglide=languageTags:en,es+demo:yes',
'mcp=ide:claude-code,cursor,gemini,opencode,vscode,other+setup:local'
]
}
];

it.for(testCases)('should create a new project with name $projectName', async (testCase) => {
const { projectName, args } = testCase;
const svBinPath = path.resolve(monoRepoPath, 'packages', 'cli', 'dist', 'bin.js');
const testOutputPath = path.resolve(monoRepoPath, '.test-output', 'cli', 'test-project');
const testOutputPath = path.resolve(monoRepoPath, '.test-output', 'cli', projectName);

const result = await exec(
'node',
Expand All @@ -31,7 +54,7 @@ describe('cli', () => {
'--types',
'ts',
'--no-install',
'--no-add-ons'
...args
],
{ nodeOptions: { stdio: 'ignore' } }
);
Expand All @@ -45,6 +68,6 @@ describe('cli', () => {
// package.json has a name
const packageJsonPath = path.resolve(testOutputPath, 'package.json');
const packageJson = parseJson(fs.readFileSync(packageJsonPath, 'utf-8'));
expect(packageJson.name).toBe('test-project');
expect(packageJson.name).toBe(projectName);
});
});
Loading