sv 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { AGENT_NAMES, Command, Element, Option, Tag, __commonJS, __export, __require, __toESM as __toESM$1, __toESM$1 as __toESM, addPnpmBuildDependencies, box, cancel, confirm, create, detect, esm_exports, from, getUserAgent, group, installDependencies, installOption, intro, isCancel, log, multiselect, note, outro, packageManagerPrompt, parseCss$1, parseHtml, parseHtml$1, parseJson$1, parseScript$1, parseSvelte, program, require_picocolors, resolveCommand, select, spinner, templates, text, up, walk_exports } from "./package-manager-D3PRQ-L_.js";
3
- import { addFromString, applyAddons, array_exports, common_exports, createWorkspace, dedent_default, exports_exports, formatFiles, function_exports, getHighlighter, imports_exports, kit_exports, object_exports, require_picocolors$1, setupAddons, variables_exports } from "./install-DP0ugKT8.js";
2
+ import { AGENT_NAMES, Command, Element, Option, Tag, __commonJS, __export, __require, __toESM, __toESM$1, addPnpmBuildDependencies, box, cancel, confirm, create, detect, esm_exports, from, getUserAgent, group, installDependencies, installOption, intro, isCancel, log, multiselect, note, outro, packageManagerPrompt, parseCss$1, parseHtml, parseHtml$1, parseJson$1, parseScript$1, parseSvelte, program, require_picocolors, resolveCommand, select, spinner, templates, text, up, walk_exports } from "./package-manager-D3PRQ-L_.js";
3
+ import { addFromString, applyAddons, array_exports, common_exports, createWorkspace, dedent_default, exports_exports, formatFiles, function_exports, getHighlighter, imports_exports, kit_exports, object_exports, require_picocolors$1, setupAddons, variables_exports } from "./install-BTJ6iCTS.js";
4
4
  import fs, { existsSync } from "node:fs";
5
5
  import path, { dirname, join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
@@ -12,7 +12,7 @@ import { promisify } from "node:util";
12
12
 
13
13
  //#region packages/cli/package.json
14
14
  var name = "sv";
15
- var version = "0.8.3";
15
+ var version = "0.8.5";
16
16
  var type = "module";
17
17
  var description = "A CLI for creating and updating SvelteKit projects";
18
18
  var license = "MIT";
@@ -138,6 +138,9 @@ function _addIssue(context, label, dataset, config2, other) {
138
138
  if (dataset.issues) dataset.issues.push(issue);
139
139
  else dataset.issues = [issue];
140
140
  }
141
+ function _isValidObjectKey(object2, key) {
142
+ return Object.hasOwn(object2, key) && key !== "__proto__" && key !== "prototype" && key !== "constructor";
143
+ }
141
144
  function _joinExpects(values, separator) {
142
145
  const list = [...new Set(values)];
143
146
  if (list.length > 1) return `(${list.join(` ${separator} `)})`;
@@ -237,53 +240,6 @@ else _addIssue(this, "type", dataset, config2);
237
240
  }
238
241
  };
239
242
  }
240
- function object(entries, message) {
241
- return {
242
- kind: "schema",
243
- type: "object",
244
- reference: object,
245
- expects: "Object",
246
- async: false,
247
- entries,
248
- message,
249
- _run(dataset, config2) {
250
- const input = dataset.value;
251
- if (input && typeof input === "object") {
252
- dataset.typed = true;
253
- dataset.value = {};
254
- for (const key in this.entries) {
255
- const value2 = input[key];
256
- const valueDataset = this.entries[key]._run({
257
- typed: false,
258
- value: value2
259
- }, config2);
260
- if (valueDataset.issues) {
261
- const pathItem = {
262
- type: "object",
263
- origin: "value",
264
- input,
265
- key,
266
- value: value2
267
- };
268
- for (const issue of valueDataset.issues) {
269
- if (issue.path) issue.path.unshift(pathItem);
270
- else issue.path = [pathItem];
271
- dataset.issues?.push(issue);
272
- }
273
- if (!dataset.issues) dataset.issues = valueDataset.issues;
274
- if (config2.abortEarly) {
275
- dataset.typed = false;
276
- break;
277
- }
278
- }
279
- if (!valueDataset.typed) dataset.typed = false;
280
- if (valueDataset.value !== void 0 || key in input) dataset.value[key] = valueDataset.value;
281
- }
282
- } else _addIssue(this, "type", dataset, config2);
283
- return dataset;
284
- }
285
- };
286
- }
287
243
  function optional(wrapped, ...args) {
288
244
  const schema = {
289
245
  kind: "schema",
@@ -322,6 +278,76 @@ else _addIssue(this, "type", dataset, config2);
322
278
  }
323
279
  };
324
280
  }
281
+ function record(key, value2, message) {
282
+ return {
283
+ kind: "schema",
284
+ type: "record",
285
+ reference: record,
286
+ expects: "Object",
287
+ async: false,
288
+ key,
289
+ value: value2,
290
+ message,
291
+ _run(dataset, config2) {
292
+ const input = dataset.value;
293
+ if (input && typeof input === "object") {
294
+ dataset.typed = true;
295
+ dataset.value = {};
296
+ for (const entryKey in input) if (_isValidObjectKey(input, entryKey)) {
297
+ const entryValue = input[entryKey];
298
+ const keyDataset = this.key._run({
299
+ typed: false,
300
+ value: entryKey
301
+ }, config2);
302
+ if (keyDataset.issues) {
303
+ const pathItem = {
304
+ type: "object",
305
+ origin: "key",
306
+ input,
307
+ key: entryKey,
308
+ value: entryValue
309
+ };
310
+ for (const issue of keyDataset.issues) {
311
+ issue.path = [pathItem];
312
+ dataset.issues?.push(issue);
313
+ }
314
+ if (!dataset.issues) dataset.issues = keyDataset.issues;
315
+ if (config2.abortEarly) {
316
+ dataset.typed = false;
317
+ break;
318
+ }
319
+ }
320
+ const valueDataset = this.value._run({
321
+ typed: false,
322
+ value: entryValue
323
+ }, config2);
324
+ if (valueDataset.issues) {
325
+ const pathItem = {
326
+ type: "object",
327
+ origin: "value",
328
+ input,
329
+ key: entryKey,
330
+ value: entryValue
331
+ };
332
+ for (const issue of valueDataset.issues) {
333
+ if (issue.path) issue.path.unshift(pathItem);
334
+ else issue.path = [pathItem];
335
+ dataset.issues?.push(issue);
336
+ }
337
+ if (!dataset.issues) dataset.issues = valueDataset.issues;
338
+ if (config2.abortEarly) {
339
+ dataset.typed = false;
340
+ break;
341
+ }
342
+ }
343
+ if (!keyDataset.typed || !valueDataset.typed) dataset.typed = false;
344
+ if (keyDataset.typed) dataset.value[keyDataset.value] = valueDataset.value;
345
+ }
346
+ } else _addIssue(this, "type", dataset, config2);
347
+ return dataset;
348
+ }
349
+ };
350
+ }
325
351
  function strictObject(entries, message) {
326
352
  return {
327
353
  kind: "schema",
@@ -1073,7 +1099,7 @@ function createPrinter(...conditions) {
1073
1099
  });
1074
1100
  return printers;
1075
1101
  }
1076
- var import_picocolors$4 = __toESM$1(require_picocolors(), 1);
1102
+ var import_picocolors$4 = __toESM(require_picocolors(), 1);
1077
1103
  var colors = import_picocolors$4.default;
1078
1104
 
1079
1105
  //#endregion
@@ -1212,8 +1238,16 @@ var drizzle_default = defineAddon({
1212
1238
  shortDescription: "database orm",
1213
1239
  homepage: "https://orm.drizzle.team",
1214
1240
  options: options$5,
1215
- setup: ({ kit, unsupported }) => {
1241
+ setup: ({ kit, unsupported, cwd, typescript }) => {
1242
+ const ext = typescript ? "ts" : "js";
1216
1243
  if (!kit) unsupported("Requires SvelteKit");
1244
+ const baseDBPath = path.resolve(kit.libDirectory, "server", "db");
1245
+ const paths = {
1246
+ "drizzle config": path.relative(cwd, path.resolve(cwd, `drizzle.config.${ext}`)),
1247
+ "database schema": path.relative(cwd, path.resolve(baseDBPath, `schema.${ext}`)),
1248
+ database: path.relative(cwd, path.resolve(baseDBPath, `index.${ext}`))
1249
+ };
1250
+ for (const [fileType, filePath] of Object.entries(paths)) if (fs.existsSync(filePath)) unsupported(`Preexisting ${fileType} file at '${filePath}'`);
1217
1251
  },
1218
1252
  run: ({ sv, typescript, options: options$6, kit }) => {
1219
1253
  const ext = typescript ? "ts" : "js";
@@ -1286,32 +1320,18 @@ var drizzle_default = defineAddon({
1286
1320
  sv.file(`drizzle.config.${ext}`, (content) => {
1287
1321
  const { ast, generateCode } = parseScript$1(content);
1288
1322
  imports_exports.addNamed(ast, "drizzle-kit", { defineConfig: "defineConfig" });
1289
- const envCheckStatement = common_exports.statementFromString("if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');");
1290
- common_exports.addStatement(ast, envCheckStatement);
1291
- const fallback = common_exports.expressionFromString("defineConfig({})");
1292
- const { value: exportDefault } = exports_exports.defaultExport(ast, fallback);
1293
- if (exportDefault.type !== "CallExpression") return content;
1294
- const objExpression = exportDefault.arguments?.[0];
1295
- if (!objExpression || objExpression.type !== "ObjectExpression") return content;
1296
- const authToken = options$6.sqlite === "turso" ? common_exports.expressionFromString("process.env.DATABASE_AUTH_TOKEN") : undefined;
1297
- object_exports.properties(objExpression, {
1298
- schema: common_exports.createLiteral(`./src/lib/server/db/schema.${typescript ? "ts" : "js"}`),
1299
- dbCredentials: object_exports.create({
1300
- url: common_exports.expressionFromString("process.env.DATABASE_URL"),
1301
- authToken
1302
- }),
1303
- verbose: {
1304
- type: "Literal",
1305
- value: true
1306
- },
1307
- strict: {
1308
- type: "Literal",
1309
- value: true
1310
- }
1311
- });
1312
- const dialect = options$6.sqlite === "turso" ? "turso" : options$6.database;
1313
- object_exports.overrideProperties(objExpression, { dialect: common_exports.createLiteral(dialect) });
1314
- if (options$6.database !== "sqlite") object_exports.removeProperty(objExpression, "driver");
1323
+ common_exports.addStatement(ast, common_exports.statementFromString("if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"));
1324
+ exports_exports.defaultExport(ast, common_exports.expressionFromString(`
1325
+ defineConfig({
1326
+ schema: "./src/lib/server/db/schema.${typescript ? "ts" : "js"}",
1327
+ dialect: "${options$6.sqlite === "turso" ? "turso" : options$6.database}",
1328
+ dbCredentials: {
1329
+ ${options$6.sqlite === "turso" ? "authToken: process.env.DATABASE_AUTH_TOKEN," : ""}
1330
+ url: process.env.DATABASE_URL
1331
+ },
1332
+ verbose: true,
1333
+ strict: true
1334
+ })`));
1315
1335
  return generateCode();
1316
1336
  });
1317
1337
  sv.file(`${kit?.libDirectory}/server/db/schema.${ext}`, (content) => {
@@ -2685,9 +2705,10 @@ var lucia_default = defineAddon({
2685
2705
  shortDescription: "auth guide",
2686
2706
  homepage: "https://lucia-auth.com",
2687
2707
  options: options$3,
2688
- setup: ({ kit, dependencyVersion, unsupported, dependsOn }) => {
2708
+ setup: ({ kit, dependencyVersion, unsupported, dependsOn, runsAfter }) => {
2689
2709
  if (!kit) unsupported("Requires SvelteKit");
2690
2710
  if (!dependencyVersion("drizzle-orm")) dependsOn("drizzle");
2711
+ runsAfter("tailwindcss");
2691
2712
  },
2692
2713
  run: ({ sv, typescript, options: options$6, kit, dependencyVersion }) => {
2693
2714
  const ext = typescript ? "ts" : "js";
@@ -3045,6 +3066,9 @@ var lucia_default = defineAddon({
3045
3066
  log$1.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`);
3046
3067
  return content;
3047
3068
  }
3069
+ const tailwind = dependencyVersion("@tailwindcss/vite") !== undefined;
3070
+ const twInputClasses = "class=\"mt-1 px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"";
3071
+ const twBtnClasses = "class=\"bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition\"";
3048
3072
  const svelte5 = !!dependencyVersion("svelte")?.startsWith("5");
3049
3073
  const [ts, s5] = utils_exports.createPrinter(typescript, svelte5);
3050
3074
  return dedent_default`
@@ -3055,17 +3079,28 @@ var lucia_default = defineAddon({
3055
3079
  </script>
3056
3080
 
3057
3081
  <h1>Login/Register</h1>
3058
- <form method='post' action='?/login' use:enhance>
3082
+ <form method="post" action="?/login" use:enhance>
3059
3083
  <label>
3060
3084
  Username
3061
- <input name='username' />
3085
+ <input
3086
+ name="username"
3087
+ ${tailwind ? twInputClasses : ""}
3088
+ />
3062
3089
  </label>
3063
3090
  <label>
3064
3091
  Password
3065
- <input type='password' name='password' />
3092
+ <input
3093
+ type="password"
3094
+ name="password"
3095
+ ${tailwind ? twInputClasses : ""}
3096
+ />
3066
3097
  </label>
3067
- <button>Login</button>
3068
- <button formaction='?/register'>Register</button>
3098
+ <button ${tailwind ? twBtnClasses : ""}
3099
+ >Login</button>
3100
+ <button
3101
+ formaction="?/register"
3102
+ ${tailwind ? twBtnClasses : ""}
3103
+ >Register</button>
3069
3104
  </form>
3070
3105
  <p style='color: red'>{form?.message ?? ''}</p>
3071
3106
  `;
@@ -3080,12 +3115,11 @@ var lucia_default = defineAddon({
3080
3115
  return dedent_default`
3081
3116
  import * as auth from '$lib/server/auth';
3082
3117
  import { fail, redirect } from '@sveltejs/kit';
3118
+ import { getRequestEvent } from '$app/server';
3083
3119
  ${ts("import type { Actions, PageServerLoad } from './$types';\n")}
3084
- export const load${ts(": PageServerLoad")} = async (event) => {
3085
- if (!event.locals.user) {
3086
- return redirect(302, '/demo/lucia/login');
3087
- }
3088
- return { user: event.locals.user };
3120
+ export const load${ts(": PageServerLoad")} = async () => {
3121
+ const user = requireLogin()
3122
+ return { user };
3089
3123
  };
3090
3124
 
3091
3125
  export const actions${ts(": Actions")} = {
@@ -3099,6 +3133,16 @@ var lucia_default = defineAddon({
3099
3133
  return redirect(302, '/demo/lucia/login');
3100
3134
  },
3101
3135
  };
3136
+
3137
+ function requireLogin() {
3138
+ const { locals } = getRequestEvent();
3139
+
3140
+ if (!locals.user) {
3141
+ return redirect(302, "/demo/lucia/login");
3142
+ }
3143
+
3144
+ return locals.user;
3145
+ }
3102
3146
  `;
3103
3147
  });
3104
3148
  sv.file(`${kit.routesDirectory}/demo/lucia/+page.svelte`, (content) => {
@@ -3260,7 +3304,7 @@ const DEFAULT_INLANG_PROJECT = {
3260
3304
  "plugin.inlang.messageFormat": { pathPattern: "./messages/{locale}.json" }
3261
3305
  };
3262
3306
  const options$2 = defineAddonOptions({
3263
- availableLanguageTags: {
3307
+ languageTags: {
3264
3308
  question: `Which languages would you like to support? ${colors.gray("(e.g. en,de-ch)")}`,
3265
3309
  type: "string",
3266
3310
  default: "en, es",
@@ -3301,7 +3345,7 @@ var paraglide_default = defineAddon({
3301
3345
  if (content) return content;
3302
3346
  const { data, generateCode } = parseJson$1(content);
3303
3347
  for (const key in DEFAULT_INLANG_PROJECT) data[key] = DEFAULT_INLANG_PROJECT[key];
3304
- const { validLanguageTags: validLanguageTags$1 } = parseLanguageTagInput(options$6.availableLanguageTags);
3348
+ const { validLanguageTags: validLanguageTags$1 } = parseLanguageTagInput(options$6.languageTags);
3305
3349
  const baseLocale = validLanguageTags$1[0];
3306
3350
  data.baseLocale = baseLocale;
3307
3351
  data.locales = validLanguageTags$1;
@@ -3375,7 +3419,7 @@ var paraglide_default = defineAddon({
3375
3419
  const scriptCode = new MagicString(script.generateCode());
3376
3420
  const templateCode = new MagicString(template.source);
3377
3421
  templateCode.append("\n\n<h1>{m.hello_world({ name: 'SvelteKit User' })}</h1>\n");
3378
- const { validLanguageTags: validLanguageTags$1 } = parseLanguageTagInput(options$6.availableLanguageTags);
3422
+ const { validLanguageTags: validLanguageTags$1 } = parseLanguageTagInput(options$6.languageTags);
3379
3423
  const links = validLanguageTags$1.map((x) => `${templateCode.getIndentString()}<button onclick={() => setLocale('${x}')}>${x}</button>`).join("\n");
3380
3424
  templateCode.append(`<div>\n${links}\n</div>`);
3381
3425
  templateCode.append("<p>\nIf you use VSCode, install the <a href=\"https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension\" target=\"_blank\">Sherlock i18n extension</a> for a better i18n experience.\n</p>");
@@ -3385,7 +3429,7 @@ var paraglide_default = defineAddon({
3385
3429
  });
3386
3430
  });
3387
3431
  }
3388
- const { validLanguageTags } = parseLanguageTagInput(options$6.availableLanguageTags);
3432
+ const { validLanguageTags } = parseLanguageTagInput(options$6.languageTags);
3389
3433
  for (const languageTag of validLanguageTags) sv.file(`messages/${languageTag}.json`, (content) => {
3390
3434
  const { data, generateCode } = parseJson$1(content);
3391
3435
  data["$schema"] = "https://inlang.com/schema/inlang-message-format";
@@ -3550,6 +3594,10 @@ var storybook_default = defineAddon({
3550
3594
  shortDescription: "frontend workshop",
3551
3595
  homepage: "https://storybook.js.org",
3552
3596
  options: {},
3597
+ setup: ({ runsAfter }) => {
3598
+ runsAfter("vitest");
3599
+ runsAfter("eslint");
3600
+ },
3553
3601
  run: async ({ sv }) => {
3554
3602
  await sv.execute([
3555
3603
  "storybook@latest",
@@ -3831,7 +3879,7 @@ var UnsupportedError = class extends Error {
3831
3879
 
3832
3880
  //#endregion
3833
3881
  //#region packages/cli/utils/common.ts
3834
- var import_picocolors$3 = __toESM(require_picocolors$1(), 1);
3882
+ var import_picocolors$3 = __toESM$1(require_picocolors$1(), 1);
3835
3883
  const NO_PREFIX = "--no-";
3836
3884
  let options = [];
3837
3885
  function getLongFlag(flags) {
@@ -6580,7 +6628,7 @@ else if (err) return cb(err);
6580
6628
 
6581
6629
  //#endregion
6582
6630
  //#region packages/cli/commands/add/fetch-packages.ts
6583
- var import_tar_fs = __toESM(require_tar_fs(), 1);
6631
+ var import_tar_fs = __toESM$1(require_tar_fs(), 1);
6584
6632
  const NODE_MODULES = fileURLToPath(new URL("../node_modules", import.meta.url));
6585
6633
  const REGISTRY = "https://registry.npmjs.org";
6586
6634
  const Directive = {
@@ -6702,24 +6750,101 @@ function getGlobalPreconditions(cwd, addons, addonSetupResult) {
6702
6750
 
6703
6751
  //#endregion
6704
6752
  //#region packages/cli/commands/add/index.ts
6705
- var import_picocolors$2 = __toESM(require_picocolors$1(), 1);
6753
+ var import_picocolors$2 = __toESM$1(require_picocolors$1(), 1);
6706
6754
  const aliases = officialAddons.map((c) => c.alias).filter((v) => v !== undefined);
6707
- const addonsOptions = getAddonOptionFlags();
6755
+ const addonOptions = getAddonOptionFlags();
6708
6756
  const communityDetails = [];
6709
- const OptionFlagSchema = optional(array(string()));
6710
- const addonOptionFlags = addonsOptions.reduce((flags, opt) => Object.assign(flags, { [opt.attributeName()]: OptionFlagSchema }), {});
6711
6757
  const AddonsSchema = array(string());
6712
- const AddonOptionFlagsSchema = object(addonOptionFlags);
6713
6758
  const OptionsSchema$1 = strictObject({
6714
6759
  cwd: string(),
6715
6760
  install: union([boolean(), picklist(AGENT_NAMES)]),
6716
6761
  preconditions: boolean(),
6717
6762
  community: optional(union([AddonsSchema, boolean()])),
6718
- ...AddonOptionFlagsSchema.entries
6763
+ addons: record(string(), optional(array(string())))
6719
6764
  });
6720
6765
  const defaultPkgPath = up$1();
6721
6766
  const defaultCwd = defaultPkgPath ? path.dirname(defaultPkgPath) : undefined;
6722
- const add = new Command("add").description("applies specified add-ons into a project").argument("[add-on...]", "add-ons to install").option("-C, --cwd <path>", "path to working directory", defaultCwd).option("--no-preconditions", "skip validating preconditions").option("--no-install", "skip installing dependencies").addOption(installOption).configureHelp(helpConfig).action((addonArgs, opts) => {
6767
+ const add = new Command("add").description("applies specified add-ons into a project").argument("[add-on...]", `add-ons to install`, (value, prev = []) => {
6768
+ const [addonId, optionFlags] = value.split("=", 2);
6769
+ const repeatedAddons = prev.find(({ id }) => id === addonId);
6770
+ if (repeatedAddons) {
6771
+ console.error(`Malformed arguments: Add-on '${addonId}' is repeated multiple times.`);
6772
+ process$1.exit(1);
6773
+ }
6774
+ if (optionFlags === undefined) {
6775
+ prev.push({
6776
+ id: addonId,
6777
+ options: undefined
6778
+ });
6779
+ return prev;
6780
+ }
6781
+ if (optionFlags.length > 0 && !/.+:.*/.test(optionFlags)) {
6782
+ console.error(`Malformed arguments: An add-on's option in '${value}' is missing it's option name or value (e.g. 'addon=option:value').`);
6783
+ process$1.exit(1);
6784
+ }
6785
+ const options$6 = optionFlags.match(/[^+]*:[^:]*(?=\+|$)/g) ?? [];
6786
+ prev.push({
6787
+ id: addonId,
6788
+ options: options$6
6789
+ });
6790
+ return prev;
6791
+ }).option("-C, --cwd <path>", "path to working directory", defaultCwd).option("--no-preconditions", "skip validating preconditions").option("--no-install", "skip installing dependencies").addOption(installOption).configureHelp({
6792
+ ...helpConfig,
6793
+ formatHelp(cmd, helper) {
6794
+ const termWidth = helper.padWidth(cmd, helper);
6795
+ const helpWidth = helper.helpWidth ?? 80;
6796
+ function callFormatItem(term, description$1) {
6797
+ return helper.formatItem(term, termWidth, description$1, helper);
6798
+ }
6799
+ let output = [`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`, ""];
6800
+ const commandDescription = helper.commandDescription(cmd);
6801
+ if (commandDescription.length > 0) output = output.concat([helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth), ""]);
6802
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
6803
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
6804
+ });
6805
+ if (argumentList.length > 0) output = output.concat([
6806
+ helper.styleTitle("Arguments:"),
6807
+ ...argumentList,
6808
+ ""
6809
+ ]);
6810
+ const addonList = addonOptions.map((option) => {
6811
+ const description$1 = option.choices;
6812
+ return callFormatItem(helper.styleArgumentTerm(option.id), helper.styleArgumentDescription(description$1));
6813
+ });
6814
+ if (addonList.length > 0) output = output.concat([
6815
+ helper.styleTitle("Add-On Options:"),
6816
+ ...addonList,
6817
+ ""
6818
+ ]);
6819
+ const optionList = helper.visibleOptions(cmd).map((option) => {
6820
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
6821
+ });
6822
+ if (optionList.length > 0) output = output.concat([
6823
+ helper.styleTitle("Options:"),
6824
+ ...optionList,
6825
+ ""
6826
+ ]);
6827
+ if (helper.showGlobalOptions) {
6828
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
6829
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
6830
+ });
6831
+ if (globalOptionList.length > 0) output = output.concat([
6832
+ helper.styleTitle("Global Options:"),
6833
+ ...globalOptionList,
6834
+ ""
6835
+ ]);
6836
+ }
6837
+ const commandList = helper.visibleCommands(cmd).map((cmd$1) => {
6838
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(cmd$1)), helper.styleSubcommandDescription(helper.subcommandDescription(cmd$1)));
6839
+ });
6840
+ if (commandList.length > 0) output = output.concat([
6841
+ helper.styleTitle("Commands:"),
6842
+ ...commandList,
6843
+ ""
6844
+ ]);
6845
+ return output.join("\n");
6846
+ }
6847
+ }).action((addonArgs, opts) => {
6723
6848
  if (opts.cwd === undefined) {
6724
6849
  console.error("Invalid workspace: Please verify that you are inside of a Svelte project. You can also specify the working directory with `--cwd <path>`");
6725
6850
  process$1.exit(1);
@@ -6727,21 +6852,24 @@ const add = new Command("add").description("applies specified add-ons into a pro
6727
6852
  console.error(`Invalid workspace: Path '${path.resolve(opts.cwd)}' is not a valid workspace.`);
6728
6853
  process$1.exit(1);
6729
6854
  }
6730
- const specifiedAddons = parse(AddonsSchema, addonArgs);
6731
- const options$6 = parse(OptionsSchema$1, opts);
6732
6855
  const addonIds = officialAddons.map((addon) => addon.id);
6733
- const invalidAddons = specifiedAddons.filter((a) => !addonIds.includes(a) && !aliases.includes(a));
6856
+ const invalidAddons = addonArgs.filter(({ id }) => !addonIds.includes(id) && !aliases.includes(id)).map(({ id }) => id);
6734
6857
  if (invalidAddons.length > 0) {
6735
6858
  console.error(`Invalid add-ons specified: ${invalidAddons.join(", ")}`);
6736
6859
  process$1.exit(1);
6737
6860
  }
6738
- const selectedAddons = transformAliases(specifiedAddons);
6861
+ const options$6 = parse(OptionsSchema$1, {
6862
+ ...opts,
6863
+ addons: {}
6864
+ });
6865
+ const selectedAddons = transformAliases(addonArgs);
6866
+ selectedAddons.forEach((addon) => options$6.addons[addon.id] = addon.options);
6739
6867
  runCommand(async () => {
6740
- const { nextSteps } = await runAddCommand(options$6, selectedAddons);
6868
+ const selectedAddonIds = selectedAddons.map(({ id }) => id);
6869
+ const { nextSteps } = await runAddCommand(options$6, selectedAddonIds);
6741
6870
  if (nextSteps) box(nextSteps, "Next steps");
6742
6871
  });
6743
6872
  });
6744
- for (const option of addonsOptions) add.addOption(option);
6745
6873
  async function runAddCommand(options$6, selectedAddonIds) {
6746
6874
  const selectedAddons = selectedAddonIds.map((id) => ({
6747
6875
  type: "official",
@@ -6749,10 +6877,9 @@ async function runAddCommand(options$6, selectedAddonIds) {
6749
6877
  }));
6750
6878
  const official = {};
6751
6879
  const community = {};
6752
- for (const addonOption of addonsOptions) {
6753
- const addonId = addonOption.name();
6754
- const aliased = addonOption.attributeName();
6755
- const specifiedOptions = options$6[addonId] || options$6[aliased];
6880
+ for (const addonOption of addonOptions) {
6881
+ const addonId = addonOption.id;
6882
+ const specifiedOptions = options$6.addons[addonId];
6756
6883
  if (!specifiedOptions) continue;
6757
6884
  const details$1 = getAddonDetails(addonId);
6758
6885
  if (!selectedAddons.find((d) => d.addon === details$1)) selectedAddons.push({
@@ -6761,26 +6888,26 @@ async function runAddCommand(options$6, selectedAddonIds) {
6761
6888
  });
6762
6889
  official[addonId] ??= {};
6763
6890
  const optionEntries = Object.entries(details$1.options);
6764
- for (const specifiedOption of specifiedOptions) {
6765
- if (!specifiedOption || specifiedOption === "none") continue;
6766
- const optionEntry = optionEntries.find(([id, question$1]) => {
6767
- if (question$1.type === "boolean") return id === specifiedOption || `no-${id}` === specifiedOption;
6768
- if (question$1.type === "select" || question$1.type === "multiselect") return question$1.options.some((o) => o.value === specifiedOption);
6769
- });
6891
+ for (const option of specifiedOptions) {
6892
+ let [optionId, optionValue] = option.split(":", 2);
6893
+ const optionEntry = optionEntries.find(([id, question$1]) => id === optionId || question$1.group === optionId);
6770
6894
  if (!optionEntry) {
6771
6895
  const { choices } = getOptionChoices(details$1);
6772
- throw new Error(`Invalid '--${addonId}' option: '${specifiedOption}'\nAvailable options: ${choices.join(", ")}`);
6896
+ throw new Error(`Invalid '${addonId}' option: '${option}'\nAvailable options: ${choices.join(", ")}`);
6773
6897
  }
6774
6898
  const [questionId, question] = optionEntry;
6899
+ if (question.type === "multiselect" && optionValue === "none") optionValue = "";
6775
6900
  let existingOption = official[addonId][questionId];
6776
6901
  if (existingOption !== undefined) {
6777
- if (typeof existingOption === "boolean") existingOption = existingOption ? questionId : `no-${questionId}`;
6778
- throw new Error(`Conflicting '--${addonId}' option: '${specifiedOption}' conflicts with '${existingOption}'`);
6902
+ if (typeof existingOption === "boolean") existingOption = existingOption ? "yes" : "no";
6903
+ throw new Error(`Conflicting '${addonId}' option: '${option}' conflicts with '${questionId}:${existingOption}'`);
6779
6904
  }
6780
- official[addonId][questionId] = question.type === "boolean" ? !specifiedOption.startsWith("no-") : specifiedOption;
6905
+ if (question.type === "boolean") official[addonId][questionId] = optionValue === "yes";
6906
+ else if (question.type === "number") official[addonId][questionId] = Number(optionValue);
6907
+ else official[addonId][questionId] = optionValue;
6781
6908
  }
6782
6909
  for (const [id, question] of Object.entries(details$1.options)) if (question.condition?.(official[addonId]) !== false) official[addonId][id] ??= question.default;
6783
- else if (official[addonId][id] !== undefined) throw new Error(`Incompatible '--${addonId}' option specified: '${official[addonId][id]}'`);
6910
+ else if (official[addonId][id] !== undefined) throw new Error(`Incompatible '${addonId}' option specified: '${official[addonId][id]}'`);
6784
6911
  }
6785
6912
  if (options$6.community === true) {
6786
6913
  const communityAddons = await Promise.all(communityAddonIds.map(async (id) => await getCommunityAddon(id)));
@@ -6856,14 +6983,14 @@ else if (official[addonId][id] !== undefined) throw new Error(`Incompatible '--$
6856
6983
  let workspace = await createWorkspace({ cwd: options$6.cwd });
6857
6984
  const addonSetupResults = setupAddons(officialAddons, workspace);
6858
6985
  if (selectedAddons.length === 0) {
6859
- const addonOptions = officialAddons.filter(({ id }) => addonSetupResults[id].unsupported.length === 0).map(({ id, homepage: homepage$1, shortDescription }) => ({
6986
+ const addonOptions$1 = officialAddons.filter(({ id }) => addonSetupResults[id].unsupported.length === 0).map(({ id, homepage: homepage$1, shortDescription }) => ({
6860
6987
  label: id,
6861
6988
  value: id,
6862
6989
  hint: `${shortDescription} - ${homepage$1}`
6863
6990
  }));
6864
6991
  const selected = await multiselect({
6865
6992
  message: `What would you like to add to your project? ${import_picocolors$2.default.dim("(use arrow keys / space bar)")}`,
6866
- options: addonOptions,
6993
+ options: addonOptions$1,
6867
6994
  required: false
6868
6995
  });
6869
6996
  if (isCancel(selected)) {
@@ -7025,13 +7152,16 @@ else if (official[addonId][id] !== undefined) throw new Error(`Incompatible '--$
7025
7152
  /**
7026
7153
  * Dedupes and transforms aliases into their respective addon id
7027
7154
  */
7028
- function transformAliases(ids) {
7029
- const set = new Set();
7030
- for (const id of ids) if (aliases.includes(id)) {
7031
- const addon = officialAddons.find((a) => a.alias === id);
7032
- set.add(addon.id);
7033
- } else set.add(id);
7034
- return Array.from(set);
7155
+ function transformAliases(addons) {
7156
+ const set = new Map();
7157
+ for (const addon of addons) if (aliases.includes(addon.id)) {
7158
+ const officialAddon = officialAddons.find((a) => a.alias === addon.id);
7159
+ set.set(officialAddon.id, {
7160
+ id: officialAddon.id,
7161
+ options: addon.options
7162
+ });
7163
+ } else set.set(addon.id, addon);
7164
+ return Array.from(set.values());
7035
7165
  }
7036
7166
  function getAddonOptionFlags() {
7037
7167
  const options$6 = [];
@@ -7042,12 +7172,11 @@ function getAddonOptionFlags() {
7042
7172
  const { defaults, groups } = getOptionChoices(details);
7043
7173
  const choices = Object.entries(groups).map(([group$1, choices$1]) => `${import_picocolors$2.default.dim(`${group$1}:`)} ${choices$1.join(", ")}`).join("\n");
7044
7174
  const preset = defaults.join(", ") || "none";
7045
- const option = new Option(`--${id} [options...]`, `${id} add-on options ${import_picocolors$2.default.dim(`(preset: ${preset})`)}\n${choices}`).preset(preset).argParser((value, prev) => {
7046
- prev ??= [];
7047
- prev = prev.concat(value.split(/\s|,/));
7048
- return prev;
7175
+ options$6.push({
7176
+ id,
7177
+ choices,
7178
+ preset
7049
7179
  });
7050
- options$6.push(option);
7051
7180
  }
7052
7181
  return options$6;
7053
7182
  }
@@ -7060,7 +7189,7 @@ function getOptionChoices(details) {
7060
7189
  let values = [];
7061
7190
  const applyDefault = question.condition?.(options$6) !== false;
7062
7191
  if (question.type === "boolean") {
7063
- values = [id, `no-${id}`];
7192
+ values = ["yes", `no`];
7064
7193
  if (applyDefault) {
7065
7194
  options$6[id] = question.default;
7066
7195
  defaults.push(question.default ? values[0] : values[1]);
@@ -7080,6 +7209,13 @@ function getOptionChoices(details) {
7080
7209
  defaults.push(...question.default);
7081
7210
  }
7082
7211
  }
7212
+ if (question.type === "string" || question.type === "number") {
7213
+ values = ["<user-input>"];
7214
+ if (applyDefault) {
7215
+ options$6[id] = question.default;
7216
+ defaults.push(question.default.toString());
7217
+ }
7218
+ }
7083
7219
  choices.push(...values);
7084
7220
  const groupId = question.group ?? id;
7085
7221
  groups[groupId] ??= [];
@@ -7094,7 +7230,7 @@ function getOptionChoices(details) {
7094
7230
 
7095
7231
  //#endregion
7096
7232
  //#region packages/cli/commands/create.ts
7097
- var import_picocolors$1 = __toESM(require_picocolors$1(), 1);
7233
+ var import_picocolors$1 = __toESM$1(require_picocolors$1(), 1);
7098
7234
  const langs = ["ts", "jsdoc"];
7099
7235
  const langMap = {
7100
7236
  ts: "typescript",
@@ -7223,7 +7359,8 @@ async function createProject(cwd, options$6) {
7223
7359
  cwd: projectPath,
7224
7360
  install: options$6.install,
7225
7361
  preconditions: false,
7226
- community: []
7362
+ community: [],
7363
+ addons: {}
7227
7364
  }, []);
7228
7365
  packageManager = pm;
7229
7366
  addOnNextSteps = nextSteps;
@@ -7261,7 +7398,7 @@ function runMigrate(cwd, args) {
7261
7398
 
7262
7399
  //#endregion
7263
7400
  //#region packages/cli/commands/check.ts
7264
- var import_picocolors = __toESM(require_picocolors$1(), 1);
7401
+ var import_picocolors = __toESM$1(require_picocolors$1(), 1);
7265
7402
  const check = new Command("check").description("a CLI for checking your Svelte code").allowUnknownOption(true).allowExcessArguments(true).option("-C, --cwd <path>", "path to working directory", process$1.cwd()).configureHelp({ formatHelp() {
7266
7403
  runCheck(process$1.cwd(), ["--help"]);
7267
7404
  return "";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { create } from "./package-manager-D3PRQ-L_.js";
2
- import { installAddon } from "./install-DP0ugKT8.js";
2
+ import { installAddon } from "./install-BTJ6iCTS.js";
3
3
 
4
4
  export { create, installAddon };
@@ -159,7 +159,7 @@ else mindent = Math.min(mindent, indent);
159
159
  }
160
160
 
161
161
  //#endregion
162
- //#region packages/core/dist/common-B-wxp0Ti.js
162
+ //#region packages/core/dist/common-CeY_dUZD.js
163
163
  function decircular(object) {
164
164
  const seenObjects = new WeakMap();
165
165
  function internalDecircular(value, path$1 = []) {
@@ -280,6 +280,7 @@ function addFromString(ast, value) {
280
280
  }
281
281
  function expressionFromString(value) {
282
282
  const program = parseScript(dedent_default(value));
283
+ stripAst(program, ["raw"]);
283
284
  const statement = program.body[0];
284
285
  if (statement.type !== "ExpressionStatement") throw new Error("value passed was not an expression");
285
286
  return statement.expression;
@@ -1038,12 +1039,17 @@ function setupAddons(addons, workspace) {
1038
1039
  for (const addon of addons) {
1039
1040
  const setupResult = {
1040
1041
  unsupported: [],
1041
- dependsOn: []
1042
+ dependsOn: [],
1043
+ runsAfter: []
1042
1044
  };
1043
1045
  addon.setup?.({
1044
1046
  ...workspace,
1045
- dependsOn: (name) => setupResult.dependsOn.push(name),
1046
- unsupported: (reason) => setupResult.unsupported.push(reason)
1047
+ dependsOn: (name) => {
1048
+ setupResult.dependsOn.push(name);
1049
+ setupResult.runsAfter.push(name);
1050
+ },
1051
+ unsupported: (reason) => setupResult.unsupported.push(reason),
1052
+ runsAfter: (name) => setupResult.runsAfter.push(name)
1047
1053
  });
1048
1054
  addonSetupResults[addon.id] = setupResult;
1049
1055
  }
@@ -1118,9 +1124,7 @@ async function runAddon({ addon, multiple, workspace }) {
1118
1124
  }
1119
1125
  function orderAddons(addons, setupResults) {
1120
1126
  return addons.sort((a, b) => {
1121
- if (a.id === "storybook") return 1;
1122
- if (b.id === "storybook") return -1;
1123
- return setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length;
1127
+ return setupResults[a.id]?.runsAfter?.length - setupResults[b.id]?.runsAfter?.length;
1124
1128
  });
1125
1129
  }
1126
1130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "type": "module",
5
5
  "description": "A CLI for creating and updating SvelteKit projects",
6
6
  "license": "MIT",
@@ -38,9 +38,9 @@
38
38
  "tinyexec": "^0.3.2",
39
39
  "valibot": "^0.41.0",
40
40
  "@sveltejs/cli-core": "0.0.0",
41
- "@sveltejs/clack-prompts": "0.9.1",
41
+ "@sveltejs/addons": "0.0.0",
42
42
  "@sveltejs/create": "0.0.0",
43
- "@sveltejs/addons": "0.0.0"
43
+ "@sveltejs/clack-prompts": "0.9.1"
44
44
  },
45
45
  "keywords": [
46
46
  "create",