Skip to content

Commit 50bedc8

Browse files
committed
Merge branch 'main' of github.com:sveltejs/cli into feat/community-add-on-draft-0
2 parents 1ca9513 + e4a5ac2 commit 50bedc8

File tree

17 files changed

+196
-101
lines changed

17 files changed

+196
-101
lines changed

.changeset/major-moles-cut.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/mighty-papers-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sv': patch
3+
---
4+
5+
fix: improve add-on option types

packages/addons/drizzle/index.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import { parseJson, parseScript } from '@sveltejs/cli-core/parsers';
66
import { resolveCommand } from 'package-manager-detector/commands';
77
import { getNodeTypesVersion } from '../common.ts';
88

9-
const PORTS = {
9+
type Database = 'mysql' | 'postgresql' | 'sqlite';
10+
const PORTS: Record<Database, string> = {
1011
mysql: '3306',
1112
postgresql: '5432',
1213
sqlite: ''
13-
} as const;
14+
};
1415

15-
const options = defineAddonOptions({
16-
database: {
16+
const options = defineAddonOptions()
17+
.add('database', {
1718
question: 'Which database would you like to use?',
1819
type: 'select',
1920
default: 'sqlite',
@@ -22,8 +23,8 @@ const options = defineAddonOptions({
2223
{ value: 'mysql', label: 'MySQL' },
2324
{ value: 'sqlite', label: 'SQLite' }
2425
]
25-
},
26-
postgresql: {
26+
})
27+
.add('postgresql', {
2728
question: 'Which PostgreSQL client would you like to use?',
2829
type: 'select',
2930
group: 'client',
@@ -33,8 +34,8 @@ const options = defineAddonOptions({
3334
{ value: 'neon', label: 'Neon', hint: 'popular hosted platform' }
3435
],
3536
condition: ({ database }) => database === 'postgresql'
36-
},
37-
mysql: {
37+
})
38+
.add('mysql', {
3839
question: 'Which MySQL client would you like to use?',
3940
type: 'select',
4041
group: 'client',
@@ -44,8 +45,8 @@ const options = defineAddonOptions({
4445
{ value: 'planetscale', label: 'PlanetScale', hint: 'popular hosted platform' }
4546
],
4647
condition: ({ database }) => database === 'mysql'
47-
},
48-
sqlite: {
48+
})
49+
.add('sqlite', {
4950
question: 'Which SQLite client would you like to use?',
5051
type: 'select',
5152
group: 'client',
@@ -56,16 +57,16 @@ const options = defineAddonOptions({
5657
{ value: 'turso', label: 'Turso', hint: 'popular hosted platform' }
5758
],
5859
condition: ({ database }) => database === 'sqlite'
59-
},
60-
docker: {
60+
})
61+
.add('docker', {
6162
question: 'Do you want to run the database locally with docker-compose?',
6263
default: false,
6364
type: 'boolean',
6465
condition: ({ database, mysql, postgresql }) =>
6566
(database === 'mysql' && mysql === 'mysql2') ||
6667
(database === 'postgresql' && postgresql === 'postgres.js')
67-
}
68-
});
68+
})
69+
.build();
6970

7071
export default defineAddon({
7172
id: 'drizzle',
@@ -112,7 +113,7 @@ export default defineAddon({
112113
if (options.sqlite === 'better-sqlite3') {
113114
sv.dependency('better-sqlite3', '^11.8.0');
114115
sv.devDependency('@types/better-sqlite3', '^7.6.12');
115-
sv.pnpmBuildDependendency('better-sqlite3');
116+
sv.pnpmBuildDependency('better-sqlite3');
116117
}
117118

118119
if (options.sqlite === 'libsql' || options.sqlite === 'turso')

packages/addons/lucia/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ type Dialect = 'mysql' | 'postgresql' | 'sqlite' | 'turso';
2626
let drizzleDialect: Dialect;
2727
let schemaPath: string;
2828

29-
const options = defineAddonOptions({
30-
demo: {
29+
const options = defineAddonOptions()
30+
.add('demo', {
3131
type: 'boolean',
3232
default: true,
3333
question: `Do you want to include a demo? ${colors.dim('(includes a login/register page)')}`
34-
}
35-
});
34+
})
35+
.build();
3636

3737
export default defineAddon({
3838
id: 'lucia',

packages/addons/paraglide/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ const DEFAULT_INLANG_PROJECT = {
1616
}
1717
};
1818

19-
const options = defineAddonOptions({
20-
languageTags: {
19+
const options = defineAddonOptions()
20+
.add('languageTags', {
2121
question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`,
2222
type: 'string',
2323
default: 'en, es',
@@ -39,13 +39,13 @@ const options = defineAddonOptions({
3939

4040
return undefined;
4141
}
42-
},
43-
demo: {
42+
})
43+
.add('demo', {
4444
type: 'boolean',
4545
default: true,
4646
question: 'Do you want to include a demo?'
47-
}
48-
});
47+
})
48+
.build();
4949

5050
export default defineAddon({
5151
id: 'paraglide',

packages/addons/sveltekit-adapter/index.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,23 @@ import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core';
22
import { exports, functions, imports, object, type AstTypes } from '@sveltejs/cli-core/js';
33
import { parseJson, parseScript } from '@sveltejs/cli-core/parsers';
44

5-
type Adapter = {
6-
id: string;
7-
package: string;
8-
version: string;
9-
};
10-
11-
const adapters: Adapter[] = [
5+
const adapters = [
126
{ id: 'auto', package: '@sveltejs/adapter-auto', version: '^6.0.0' },
137
{ id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.12' },
148
{ id: 'static', package: '@sveltejs/adapter-static', version: '^3.0.8' },
159
{ id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.6.3' },
1610
{ id: 'cloudflare', package: '@sveltejs/adapter-cloudflare', version: '^7.0.0' },
1711
{ id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^5.0.0' }
18-
];
12+
] as const;
1913

20-
const options = defineAddonOptions({
21-
adapter: {
14+
const options = defineAddonOptions()
15+
.add('adapter', {
2216
type: 'select',
2317
question: 'Which SvelteKit adapter would you like to use?',
24-
options: adapters.map((p) => ({ value: p.id, label: p.id, hint: p.package })),
25-
default: 'auto'
26-
}
27-
});
18+
default: 'auto',
19+
options: adapters.map((p) => ({ value: p.id, label: p.id, hint: p.package }))
20+
})
21+
.build();
2822

2923
export default defineAddon({
3024
id: 'sveltekit-adapter',

packages/addons/tailwindcss/index.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,28 @@ import { imports, vite } from '@sveltejs/cli-core/js';
33
import { parseCss, parseJson, parseScript, parseSvelte } from '@sveltejs/cli-core/parsers';
44
import { addSlot } from '@sveltejs/cli-core/html';
55

6-
type Plugin = {
7-
id: string;
8-
package: string;
9-
version: string;
10-
identifier: string;
11-
};
12-
13-
const plugins: Plugin[] = [
6+
const plugins = [
147
{
158
id: 'typography',
169
package: '@tailwindcss/typography',
17-
version: '^0.5.15',
18-
identifier: 'typography'
10+
version: '^0.5.15'
1911
},
2012
{
2113
id: 'forms',
2214
package: '@tailwindcss/forms',
23-
version: '^0.5.9',
24-
identifier: 'forms'
15+
version: '^0.5.9'
2516
}
26-
];
17+
] as const;
2718

28-
const options = defineAddonOptions({
29-
plugins: {
19+
const options = defineAddonOptions()
20+
.add('plugins', {
3021
type: 'multiselect',
3122
question: 'Which plugins would you like to add?',
3223
options: plugins.map((p) => ({ value: p.id, label: p.id, hint: p.package })),
33-
default: [],
24+
default: [] as Array<(typeof plugins)[number]['id']>,
3425
required: false
35-
}
36-
});
26+
})
27+
.build();
3728

3829
export default defineAddon({
3930
id: 'tailwindcss',

packages/addons/vitest-addon/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { dedent, defineAddon, defineAddonOptions, log } from '@sveltejs/cli-core
22
import { array, exports, functions, object } from '@sveltejs/cli-core/js';
33
import { parseJson, parseScript } from '@sveltejs/cli-core/parsers';
44

5-
const options = defineAddonOptions({
6-
usages: {
5+
const options = defineAddonOptions()
6+
.add('usages', {
77
question: 'What do you want to use vitest for?',
88
type: 'multiselect',
99
default: ['unit', 'component'],
@@ -12,8 +12,8 @@ const options = defineAddonOptions({
1212
{ value: 'component', label: 'component testing' }
1313
],
1414
required: true
15-
}
16-
});
15+
})
16+
.build();
1717

1818
export default defineAddon({
1919
id: 'vitest',

packages/cli/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# sv
22

3+
## 0.9.3
4+
### Patch Changes
5+
6+
7+
- chore(core): change `defineAddonOptions({ /*config */ })` to `defineAddonOptions().add('key', { /*config */ }).build()` in order to provide better type safety. ([#686](https://github.com/sveltejs/cli/pull/686))
8+
9+
10+
- fix(migrate): allow `migrate` to run without specifying a migration arg ([#676](https://github.com/sveltejs/cli/pull/676))
11+
12+
13+
- fix(add): improve robustness of add-on args parsing ([#681](https://github.com/sveltejs/cli/pull/681))
14+
315
## 0.9.2
416
### Patch Changes
517

packages/cli/commands/add/index.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,16 @@ export const add = new Command('add')
5959
process.exit(1);
6060
}
6161

62-
// occurs when an `=` isn't present (e.g. `sv add foo`)
63-
if (optionFlags === undefined) {
64-
prev.push({ id: addonId, options: undefined });
65-
return prev;
66-
}
67-
68-
// validates that the options are relatively well-formed.
69-
// occurs when no <name> or <value> is specified (e.g. `sv add foo=demo`).
70-
if (optionFlags.length > 0 && !/.+:.*/.test(optionFlags)) {
71-
console.error(
72-
`Malformed arguments: An add-on's option in '${value}' is missing it's option name or value (e.g. 'addon=option:value').`
73-
);
62+
try {
63+
const options = common.parseAddonOptions(optionFlags);
64+
prev.push({ id: addonId, options });
65+
} catch (error) {
66+
if (error instanceof Error) {
67+
console.error(error.message);
68+
}
7469
process.exit(1);
7570
}
7671

77-
// parses the option flags into a array of `<name>:<value>` strings
78-
const options: string[] = optionFlags.match(/[^+]*:[^:]*(?=\+|$)/g) ?? [];
79-
80-
prev.push({ id: addonId, options });
8172
return prev;
8273
})
8374
.option('-C, --cwd <path>', 'path to working directory', defaultCwd)
@@ -644,7 +635,7 @@ function getOptionChoices(details: AddonWithoutExplicitArgs) {
644635
const choices: string[] = [];
645636
const defaults: string[] = [];
646637
const groups: Record<string, string[]> = {};
647-
const options: Record<string, unknown> = {};
638+
const options: OptionValues<any> = {};
648639
for (const [id, question] of Object.entries(details.options)) {
649640
let values: string[] = [];
650641
const applyDefault = question.condition?.(options) !== false;

0 commit comments

Comments
 (0)