sv 0.13.2 → 0.14.1

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-CK31LRlH.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";
@@ -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
  */
@@ -7326,6 +7326,7 @@ var playwright_default = defineAddon({
7326
7326
  run: ({ sv, language, file, isKit, directory }) => {
7327
7327
  sv.devDependency("@playwright/test", "^1.58.2");
7328
7328
  sv.file(file.package, transforms.json(({ data, json }) => {
7329
+ json.packageScriptsUpsert(data, "prepare", "playwright install", { mode: "prepend" });
7329
7330
  json.packageScriptsUpsert(data, "test:e2e", "playwright test");
7330
7331
  json.packageScriptsUpsert(data, "test", "npm run test:e2e");
7331
7332
  }));
@@ -7908,7 +7909,7 @@ function getAddonDetails(id) {
7908
7909
  //#endregion
7909
7910
  //#region package.json
7910
7911
  var name = "sv";
7911
- var version = "0.13.2";
7912
+ var version = "0.14.1";
7912
7913
  //#endregion
7913
7914
  //#region src/core/errors.ts
7914
7915
  var UnsupportedError = class extends Error {
@@ -10818,7 +10819,7 @@ async function downloadPackage(options) {
10818
10819
  if (platform() === "win32" && (error.code === "EPERM" || error.code === "EACCES")) copyDirectorySync(options.path, dest);
10819
10820
  else throw error;
10820
10821
  }
10821
- return await importAddonCode(pkg.name);
10822
+ return await importAddonCode(pkg.name, pkg.version);
10822
10823
  }
10823
10824
  const tarballUrl = pkg.dist.tarball;
10824
10825
  const data = await fetch(tarballUrl);
@@ -10827,14 +10828,22 @@ async function downloadPackage(options) {
10827
10828
  header.name = header.name.replace("package", pkg.name);
10828
10829
  return header;
10829
10830
  } }));
10830
- return await importAddonCode(pkg.name);
10831
+ return await importAddonCode(pkg.name, pkg.version);
10831
10832
  }
10832
- async function importAddonCode(pkgName) {
10833
+ async function importAddonCode(pkgName, pkgVersion) {
10834
+ const issues = [];
10835
+ let details;
10833
10836
  try {
10834
- const { default: details } = await import(`${pkgName}/sv`);
10835
- return details;
10836
- } catch {}
10837
- const { default: details } = await import(pkgName);
10837
+ ({default: details} = await import(`${pkgName}/sv`));
10838
+ } catch {
10839
+ issues.push(`'/sv' export not found`);
10840
+ }
10841
+ if (!details) try {
10842
+ ({default: details} = await import(pkgName));
10843
+ } catch {
10844
+ issues.push(`default export not found`);
10845
+ }
10846
+ 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
10847
  return details;
10839
10848
  }
10840
10849
  async function getPackageJSON(ref) {
@@ -11486,8 +11495,23 @@ async function createProject(cwd, options) {
11486
11495
  const projectPath = path.resolve(directory);
11487
11496
  const basename = path.basename(projectPath);
11488
11497
  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.`);
11498
+ let projectName = parentDirName.startsWith("@") ? `${parentDirName}/${basename}` : basename;
11499
+ if (template === "addon" && !projectName.startsWith("@")) {
11500
+ const org = await Qt({
11501
+ message: `Community add-ons must be published under an npm org. Enter the name of your npm org:`,
11502
+ placeholder: " @my-org",
11503
+ validate: (value) => {
11504
+ if (!value) return "Organization name is required";
11505
+ if (!value.startsWith("@")) return "Must start with @";
11506
+ if (value.includes("/")) return "Just the org, not the full package name";
11507
+ }
11508
+ });
11509
+ if (Ct$1(org)) {
11510
+ Pt("Operation cancelled.");
11511
+ process$1.exit(0);
11512
+ }
11513
+ projectName = `${org}/${basename}`;
11514
+ }
11491
11515
  if (template === "addon" && options.add.length > 0) errorAndExit(`The ${color.command("--add")} flag cannot be used with the ${color.command("addon")} template.`);
11492
11516
  let loadedAddons = [];
11493
11517
  let answers = {};
@@ -11736,6 +11760,8 @@ const add$1 = new Command("add").description("applies specified add-ons into a p
11736
11760
  " sv add prettier eslint",
11737
11761
  " sv add vitest=\"usages:unit\" tailwindcss=\"plugins:none\"",
11738
11762
  " sv add drizzle=\"database:postgresql+client:postgres.js+docker:yes\"",
11763
+ " sv add prettier @supacool",
11764
+ " sv add @supacool/sv@0.1.2",
11739
11765
  ""
11740
11766
  ].join("\n");
11741
11767
  }
@@ -12141,7 +12167,8 @@ function formatAddonHelpSection(opts) {
12141
12167
  if (!option) return formatItem(id, "(no options)");
12142
12168
  return formatItem(id, option.choices);
12143
12169
  });
12144
- if (addonList.length > 0) output.push(styleTitle("Add-Ons:"), ...addonList, "");
12170
+ if (addonList.length > 0) output.push(styleTitle("Official Add-Ons:"), ...addonList, "");
12171
+ output.push(styleTitle("Community Add-Ons:"), " Find on: https://www.npmjs.com/search?q=keywords:sv-add", "");
12145
12172
  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
12173
  return output;
12147
12174
  }
package/dist/shared.json CHANGED
@@ -84,7 +84,7 @@
84
84
  "typescript"
85
85
  ],
86
86
  "exclude": [],
87
- "contents": "import adapter from '@sveltejs/adapter-auto';\nimport { relative, sep } from 'node:path';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tcompilerOptions: {\n\t\t// defaults to rune mode for the project, except for `node_modules`. Can be removed in svelte 6.\n\t\trunes: ({ filename }) => {\n\t\t\tconst relativePath = relative(import.meta.dirname, filename);\n\t\t\tconst pathSegments = relativePath.toLowerCase().split(sep);\n\t\t\tconst isExternalLibrary = pathSegments.includes('node_modules');\n\n\t\t\treturn isExternalLibrary ? undefined : true;\n\t\t}\n\t},\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n\t\t// If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n\t\t// See https://svelte.dev/docs/kit/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n"
87
+ "contents": "import adapter from '@sveltejs/adapter-auto';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tcompilerOptions: {\n\t\t// Force runes mode for the project, except for libraries. Can be removed in svelte 6.\n\t\trunes: ({ filename }) => (filename.split(/[/\\\\]/).includes('node_modules') ? undefined : true)\n\t},\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n\t\t// If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n\t\t// See https://svelte.dev/docs/kit/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n"
88
88
  },
89
89
  {
90
90
  "name": "tsconfig.json",
@@ -100,7 +100,7 @@
100
100
  "exclude": [
101
101
  "typescript"
102
102
  ],
103
- "contents": "import adapter from '@sveltejs/adapter-auto';\nimport { relative, sep } from 'node:path';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tcompilerOptions: {\n\t\t// defaults to rune mode for the project, except for `node_modules`. Can be removed in svelte 6.\n\t\trunes: ({ filename }) => {\n\t\t\tconst relativePath = relative(import.meta.dirname, filename);\n\t\t\tconst pathSegments = relativePath.toLowerCase().split(sep);\n\t\t\tconst isExternalLibrary = pathSegments.includes('node_modules');\n\n\t\t\treturn isExternalLibrary ? undefined : true;\n\t\t}\n\t},\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n\t\t// If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n\t\t// See https://svelte.dev/docs/kit/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n"
103
+ "contents": "import adapter from '@sveltejs/adapter-auto';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\tcompilerOptions: {\n\t\t// Force runes mode for the project, except for libraries. Can be removed in svelte 6.\n\t\trunes: ({ filename }) => (filename.split(/[/\\\\]/).includes('node_modules') ? undefined : true)\n\t},\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n\t\t// If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n\t\t// See https://svelte.dev/docs/kit/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n"
104
104
  },
105
105
  {
106
106
  "name": "vite.config.ts",
@@ -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-CK31LRlH.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-CK31LRlH.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.1",
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",