sv 0.13.2 → 0.14.0

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as detectPackageManager, c as name, h as program, l as version, m as Command, n as add, o as forwardExitCode, p as from, r as create, s as helpConfig } from "./engine-B8V7JiJ3.mjs";
2
+ import { a as detectPackageManager, c as name, h as program, l as version, m as Command, n as add, o as forwardExitCode, p as from, r as create, s as helpConfig } from "./engine-BaqBUQsx.mjs";
3
3
  import { color, resolveCommandArray } from "@sveltejs/sv-utils";
4
4
  import process from "node:process";
5
5
  import { execSync } from "node:child_process";
@@ -7908,7 +7908,7 @@ function getAddonDetails(id) {
7908
7908
  //#endregion
7909
7909
  //#region package.json
7910
7910
  var name = "sv";
7911
- var version = "0.13.2";
7911
+ var version = "0.14.0";
7912
7912
  //#endregion
7913
7913
  //#region src/core/errors.ts
7914
7914
  var UnsupportedError = class extends Error {
@@ -10818,7 +10818,7 @@ async function downloadPackage(options) {
10818
10818
  if (platform() === "win32" && (error.code === "EPERM" || error.code === "EACCES")) copyDirectorySync(options.path, dest);
10819
10819
  else throw error;
10820
10820
  }
10821
- return await importAddonCode(pkg.name);
10821
+ return await importAddonCode(pkg.name, pkg.version);
10822
10822
  }
10823
10823
  const tarballUrl = pkg.dist.tarball;
10824
10824
  const data = await fetch(tarballUrl);
@@ -10827,14 +10827,22 @@ async function downloadPackage(options) {
10827
10827
  header.name = header.name.replace("package", pkg.name);
10828
10828
  return header;
10829
10829
  } }));
10830
- return await importAddonCode(pkg.name);
10830
+ return await importAddonCode(pkg.name, pkg.version);
10831
10831
  }
10832
- async function importAddonCode(pkgName) {
10832
+ async function importAddonCode(pkgName, pkgVersion) {
10833
+ const issues = [];
10834
+ let details;
10833
10835
  try {
10834
- const { default: details } = await import(`${pkgName}/sv`);
10835
- return details;
10836
- } catch {}
10837
- const { default: details } = await import(pkgName);
10836
+ ({default: details} = await import(`${pkgName}/sv`));
10837
+ } catch {
10838
+ issues.push(`'/sv' export not found`);
10839
+ }
10840
+ if (!details) try {
10841
+ ({default: details} = await import(pkgName));
10842
+ } catch {
10843
+ issues.push(`default export not found`);
10844
+ }
10845
+ if (!details && issues.length > 0) throw new Error(`Failed to load add-on '${pkgName}@${pkgVersion}':\n- ${issues.join("\n- ")}\n\nPlease report this to the add-on author.`);
10838
10846
  return details;
10839
10847
  }
10840
10848
  async function getPackageJSON(ref) {
@@ -11486,8 +11494,23 @@ async function createProject(cwd, options) {
11486
11494
  const projectPath = path.resolve(directory);
11487
11495
  const basename = path.basename(projectPath);
11488
11496
  const parentDirName = path.basename(path.dirname(projectPath));
11489
- const projectName = parentDirName.startsWith("@") ? `${parentDirName}/${basename}` : basename;
11490
- if (template === "addon" && !projectName.startsWith("@")) errorAndExit(`Community add-ons must be published under an npm org (e.g. ${color.command("@my-org/sv")}). Unscoped package names are not supported at this stage.`);
11497
+ let projectName = parentDirName.startsWith("@") ? `${parentDirName}/${basename}` : basename;
11498
+ if (template === "addon" && !projectName.startsWith("@")) {
11499
+ const org = await Qt({
11500
+ message: `Community add-ons must be published under an npm org. Enter the name of your npm org:`,
11501
+ placeholder: " @my-org",
11502
+ validate: (value) => {
11503
+ if (!value) return "Organization name is required";
11504
+ if (!value.startsWith("@")) return "Must start with @";
11505
+ if (value.includes("/")) return "Just the org, not the full package name";
11506
+ }
11507
+ });
11508
+ if (Ct$1(org)) {
11509
+ Pt("Operation cancelled.");
11510
+ process$1.exit(0);
11511
+ }
11512
+ projectName = `${org}/${basename}`;
11513
+ }
11491
11514
  if (template === "addon" && options.add.length > 0) errorAndExit(`The ${color.command("--add")} flag cannot be used with the ${color.command("addon")} template.`);
11492
11515
  let loadedAddons = [];
11493
11516
  let answers = {};
@@ -11736,6 +11759,8 @@ const add$1 = new Command("add").description("applies specified add-ons into a p
11736
11759
  " sv add prettier eslint",
11737
11760
  " sv add vitest=\"usages:unit\" tailwindcss=\"plugins:none\"",
11738
11761
  " sv add drizzle=\"database:postgresql+client:postgres.js+docker:yes\"",
11762
+ " sv add prettier @supacool",
11763
+ " sv add @supacool/sv@0.1.2",
11739
11764
  ""
11740
11765
  ].join("\n");
11741
11766
  }
@@ -12141,7 +12166,8 @@ function formatAddonHelpSection(opts) {
12141
12166
  if (!option) return formatItem(id, "(no options)");
12142
12167
  return formatItem(id, option.choices);
12143
12168
  });
12144
- if (addonList.length > 0) output.push(styleTitle("Add-Ons:"), ...addonList, "");
12169
+ if (addonList.length > 0) output.push(styleTitle("Official Add-Ons:"), ...addonList, "");
12170
+ output.push(styleTitle("Community Add-Ons:"), " Find on: https://www.npmjs.com/search?q=keywords:sv-add", "");
12145
12171
  output.push(styleTitle("Add-On Syntax:"), " <addon> add with defaults (may still prompt)", " <addon>=<opt>:<val> set a single option", " <addon>=<opt1>:<val1>+<opt2>:<val2> set multiple options", " <addon>=<opt>:none explicitly set no value (for multiselect)", " To skip prompts, explicitly set ALL options (use defaults shown above).", "");
12146
12172
  return output;
12147
12173
  }
@@ -139,7 +139,7 @@ type Scripts = {
139
139
  condition?: ConditionDefinition;
140
140
  };
141
141
  type SvApi = {
142
- /** Add a package to the pnpm build dependencies. */pnpmBuildDependency: (pkg: string) => void; /** Add a package to the dependencies. */
142
+ /** Add a package to the pnpm onlyBuiltDependencies. */pnpmBuildDependency: (pkg: string) => void; /** Add a package to the dependencies. */
143
143
  dependency: (pkg: string, version: string) => void; /** Add a package to the dev dependencies. */
144
144
  devDependency: (pkg: string, version: string) => void; /** Execute a command in the workspace. */
145
145
  execute: (args: string[], stdio: "inherit" | "pipe") => Promise<void>;
@@ -152,15 +152,15 @@ type SvApi = {
152
152
  };
153
153
  type Addon<Args extends OptionDefinition, Id extends string = string> = {
154
154
  id: Id;
155
- alias?: string;
156
- shortDescription?: string;
155
+ alias?: string; /** one-liner shown in prompts */
156
+ shortDescription?: string; /** link to docs/repo */
157
157
  homepage?: string; /** If true, this addon won't appear in the interactive prompt but can still be used via CLI */
158
158
  hidden?: boolean;
159
159
  options: Args; /** Setup the addon. Will be called before the addon is run. */
160
160
  setup?: (workspace: Workspace & {
161
161
  /** On what official addons does this addon depend on? */dependsOn: (name: keyof typeof officialAddons) => void;
162
- /** Why is this addon not supported?
163
- *
162
+ /**
163
+ * Why is this addon not supported?
164
164
  * @example
165
165
  * if (!isKit) unsupported('Requires SvelteKit');
166
166
  */
@@ -1,4 +1,4 @@
1
- import { A as BooleanQuestion, C as defineAddon, D as WorkspaceOptions, E as Workspace, F as Question, I as SelectQuestion, L as StringQuestion, M as NumberQuestion, N as OptionDefinition, O as createWorkspace, P as OptionValues, R as officialAddons, S as Verification, T as getErrorHint, _ as Scripts, a as Addon, b as TestDefinition, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as PreparedAddon, h as PackageDefinition, i as add, j as MultiSelectQuestion, k as BaseQuestion, l as AddonResult, m as OptionBuilder, n as InstallOptions, o as AddonDefinition, p as LoadedAddon, r as OptionMap, s as AddonInput, t as AddonMap, u as AddonSource, v as SetupResult, w as defineAddonOptions, x as Tests, y as SvApi } from "../engine-DmG_8K_H.mjs";
1
+ import { A as BooleanQuestion, C as defineAddon, D as WorkspaceOptions, E as Workspace, F as Question, I as SelectQuestion, L as StringQuestion, M as NumberQuestion, N as OptionDefinition, O as createWorkspace, P as OptionValues, R as officialAddons, S as Verification, T as getErrorHint, _ as Scripts, a as Addon, b as TestDefinition, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as PreparedAddon, h as PackageDefinition, i as add, j as MultiSelectQuestion, k as BaseQuestion, l as AddonResult, m as OptionBuilder, n as InstallOptions, o as AddonDefinition, p as LoadedAddon, r as OptionMap, s as AddonInput, t as AddonMap, u as AddonSource, v as SetupResult, w as defineAddonOptions, x as Tests, y as SvApi } from "../engine-BdGJvT03.mjs";
2
2
 
3
3
  //#region src/create/index.d.ts
4
4
  type TemplateType = (typeof templateTypes)[number];
@@ -1,2 +1,2 @@
1
- import { d as defineAddon, f as defineAddonOptions, t as add, u as officialAddons, v as create } from "../engine-B8V7JiJ3.mjs";
1
+ import { d as defineAddon, f as defineAddonOptions, t as add, u as officialAddons, v as create } from "../engine-BaqBUQsx.mjs";
2
2
  export { add, create, defineAddon, defineAddonOptions, officialAddons };
@@ -1,5 +1,6 @@
1
- import { r as OptionMap, t as AddonMap } from "../engine-DmG_8K_H.mjs";
1
+ import { r as OptionMap, t as AddonMap } from "../engine-BdGJvT03.mjs";
2
2
  import { AgentName } from "@sveltejs/sv-utils";
3
+ import * as _playwright_test0 from "@playwright/test";
3
4
  import { Page } from "@playwright/test";
4
5
  import * as vitest from "vitest";
5
6
  import { TestProject } from "vitest/node";
@@ -102,11 +103,12 @@ declare function prepareServer({
102
103
  buildCommand,
103
104
  previewCommand
104
105
  }: PrepareServerOptions): Promise<PrepareServerReturn>;
106
+ type PlaywrightContext = Pick<typeof _playwright_test0, "chromium">;
105
107
  type VitestContext = Pick<typeof vitest, "inject" | "test" | "beforeAll" | "beforeEach">;
106
- declare function createSetupTest(vitest: VitestContext): <Addons extends AddonMap>(addons: Addons, options?: SetupTestOptions<Addons>) => {
108
+ declare function createSetupTest(vitest: VitestContext, playwright?: PlaywrightContext): <Addons extends AddonMap>(addons: Addons, options?: SetupTestOptions<Addons>) => {
107
109
  test: vitest.TestAPI<Fixtures>;
108
110
  testCases: Array<AddonTestCase<AddonMap>>;
109
111
  prepareServer: typeof prepareServer;
110
112
  };
111
113
  //#endregion
112
- export { AddonTestCase, CreateProject, Fixtures, PrepareServerOptions, PrepareServerReturn, ProjectVariant, SetupTestOptions, VitestContext, addPnpmBuildDependencies, createProject, createSetupTest, prepareServer, setup, setupGlobal, startPreview, variants };
114
+ export { AddonTestCase, CreateProject, Fixtures, PlaywrightContext, PrepareServerOptions, PrepareServerReturn, ProjectVariant, SetupTestOptions, VitestContext, addPnpmBuildDependencies, createProject, createSetupTest, prepareServer, setup, setupGlobal, startPreview, variants };
@@ -1,4 +1,4 @@
1
- import { _ as z, b as __require, g as R, i as addPnpmBuildDependencies, t as add, v as create, x as __toESM, y as __commonJSMin } from "../engine-B8V7JiJ3.mjs";
1
+ import { _ as z, b as __require, g as R, i as addPnpmBuildDependencies, t as add, v as create, x as __toESM, y as __commonJSMin } from "../engine-BaqBUQsx.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import process$1 from "node:process";
@@ -753,7 +753,7 @@ async function prepareServer({ cwd, page, buildCommand = "pnpm build", previewCo
753
753
  close
754
754
  };
755
755
  }
756
- function createSetupTest(vitest) {
756
+ function createSetupTest(vitest, playwright) {
757
757
  return function setupTest(addons, options) {
758
758
  const { inject, test: vitestTest, beforeAll, beforeEach } = vitest;
759
759
  const test = vitestTest.extend({});
@@ -765,7 +765,8 @@ function createSetupTest(vitest) {
765
765
  let browser;
766
766
  if (withBrowser) beforeAll(async () => {
767
767
  let chromium;
768
- try {
768
+ if (playwright) chromium = playwright.chromium;
769
+ else try {
769
770
  ({chromium} = await import("@playwright/test"));
770
771
  } catch {
771
772
  throw new Error("Browser testing requires @playwright/test. Install it with: pnpm add -D @playwright/test");
@@ -10,7 +10,7 @@ const browser = false;
10
10
  const { test, prepareServer, testCases } = setupTest(
11
11
  { addon },
12
12
  {
13
- kinds: [{ type: 'default', options: { addon: { who: 'you' } } }],
13
+ kinds: [{ type: 'default', options: { [addon.id]: { who: 'you' } } }],
14
14
  filter: (testCase) => testCase.variant.includes('kit'),
15
15
  browser
16
16
  }
@@ -21,15 +21,18 @@ test.concurrent.for(testCases)(
21
21
  async (testCase, { page, ...ctx }) => {
22
22
  const cwd = ctx.cwd(testCase);
23
23
 
24
- const msg =
25
- "This is a text file made by the Community Addon Template demo for the add-on: '~SV-NAME-TODO~'!";
24
+ const msg = "Community Addon Template demo for the add-on: '~SV-NAME-TODO~'!";
26
25
 
27
26
  const contentPath = path.resolve(cwd, `src/lib/~SV-NAME-TODO~/content.txt`);
28
27
  const contentContent = fs.readFileSync(contentPath, 'utf8');
29
-
30
28
  // Check if we have the imports
31
29
  expect(contentContent).toContain(msg);
32
30
 
31
+ const helloPath = path.resolve(cwd, `src/lib/~SV-NAME-TODO~/HelloComponent.svelte`);
32
+ const helloContent = fs.readFileSync(helloPath, 'utf8');
33
+ // Check if we have the imports
34
+ expect(helloContent).toContain('you');
35
+
33
36
  // For browser testing
34
37
  if (browser) {
35
38
  const { close } = await prepareServer({ cwd, page });
@@ -6,8 +6,8 @@
6
6
  "license": "MIT",
7
7
  "scripts": {
8
8
  "demo-create": "sv create demo --types ts --template minimal --no-add-ons --no-install",
9
- "demo-add": "sv add file:../ --cwd demo --no-git-check --no-install",
10
- "demo-add:ci": "sv add file:../=who:you --cwd demo --no-git-check --no-download-check --no-install",
9
+ "demo-add": "pnpm build && sv add file:../ --cwd demo --no-git-check --no-install",
10
+ "demo-add:ci": "pnpm build && sv add file:../=who:you --cwd demo --no-git-check --no-download-check --no-install",
11
11
  "build": "tsdown",
12
12
  "prepublishOnly": "npm run build",
13
13
  "test": "vitest run"
@@ -15,16 +15,11 @@
15
15
  "files": ["dist"],
16
16
  "exports": {
17
17
  ".": {
18
- "default": "./src/index.js"
18
+ "default": "./dist/index.mjs"
19
19
  }
20
20
  },
21
21
  "publishConfig": {
22
- "access": "public",
23
- "exports": {
24
- ".": {
25
- "default": "./dist/index.js"
26
- }
27
- }
22
+ "access": "public"
28
23
  },
29
24
  "peerDependencies": {
30
25
  "sv": "latest"
@@ -37,5 +32,5 @@
37
32
  "tsdown": "^0.21.4",
38
33
  "vitest": "^4.1.0"
39
34
  },
40
- "keywords": ["sv-add"]
35
+ "keywords": ["sv-add", "svelte", "sveltekit"]
41
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
4
4
  "type": "module",
5
5
  "description": "A command line interface (CLI) for creating and maintaining Svelte applications",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  }
26
26
  },
27
27
  "dependencies": {
28
- "@sveltejs/sv-utils": "0.0.5"
28
+ "@sveltejs/sv-utils": "0.1.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@clack/prompts": "1.0.0",