sv 0.13.0 → 0.13.2

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.
@@ -81,9 +81,10 @@ type Workspace = {
81
81
  */
82
82
  dependencyVersion: (pkg: string) => string | undefined; /** to know if the workspace is using typescript or javascript */
83
83
  language: "ts" | "js";
84
- files: {
84
+ file: {
85
85
  viteConfig: "vite.config.js" | "vite.config.ts";
86
- svelteConfig: "svelte.config.js" | "svelte.config.ts"; /** `${kit.routesDirectory}/layout.css` or `src/app.css` */
86
+ svelteConfig: "svelte.config.js" | "svelte.config.ts";
87
+ typeConfig: "jsconfig.json" | "tsconfig.json" | undefined; /** `${directory.routes}/layout.css` or `src/app.css` */
87
88
  stylesheet: `${string}/layout.css` | "src/app.css";
88
89
  package: "package.json";
89
90
  gitignore: ".gitignore";
@@ -99,18 +100,21 @@ type Workspace = {
99
100
  from?: string;
100
101
  to: string;
101
102
  }) => string;
102
- }; /** If we are in a kit project, this object will contain the lib and routes directories */
103
- kit: {
104
- libDirectory: string;
105
- routesDirectory: string;
106
- } | undefined; /** The package manager used to install dependencies */
103
+ };
104
+ isKit: boolean;
105
+ directory: {
106
+ src: string; /** In SvelteKit taking `kit.files.lib` automatically. Falls back to `src/lib` in non-Kit projects */
107
+ lib: string; /** In SvelteKit taking `kit.files.routes` automatically. Falls back to `src/routes` in non-Kit projects */
108
+ kitRoutes: string;
109
+ }; /** The package manager used to install dependencies */
107
110
  packageManager: AgentName;
108
111
  };
109
112
  type CreateWorkspaceOptions = {
110
113
  cwd: string;
111
114
  packageManager?: AgentName;
112
115
  override?: {
113
- kit?: Workspace["kit"];
116
+ isKit?: boolean;
117
+ directory?: Workspace["directory"];
114
118
  dependencies: Record<string, string>;
115
119
  };
116
120
  };
@@ -138,8 +142,13 @@ type SvApi = {
138
142
  /** Add a package to the pnpm build dependencies. */pnpmBuildDependency: (pkg: string) => void; /** Add a package to the dependencies. */
139
143
  dependency: (pkg: string, version: string) => void; /** Add a package to the dev dependencies. */
140
144
  devDependency: (pkg: string, version: string) => void; /** Execute a command in the workspace. */
141
- execute: (args: string[], stdio: "inherit" | "pipe") => Promise<void>; /** Edit a file in the workspace. (will create it if it doesn't exist) */
142
- file: (path: string, edit: (content: string) => string) => void;
145
+ execute: (args: string[], stdio: "inherit" | "pipe") => Promise<void>;
146
+ /**
147
+ * Edit a file in the workspace. (will create it if it doesn't exist)
148
+ *
149
+ * Return `false` from the callback to abort - the original content is returned unchanged.
150
+ */
151
+ file: (path: string, edit: (content: string) => string | false) => void;
143
152
  };
144
153
  type Addon<Args extends OptionDefinition, Id extends string = string> = {
145
154
  id: Id;
@@ -153,7 +162,7 @@ type Addon<Args extends OptionDefinition, Id extends string = string> = {
153
162
  /** Why is this addon not supported?
154
163
  *
155
164
  * @example
156
- * if (!kit) unsupported('Requires SvelteKit');
165
+ * if (!isKit) unsupported('Requires SvelteKit');
157
166
  */
158
167
  unsupported: (reason: string) => void; /** On what official addons does this addon run after? */
159
168
  runsAfter: (name: keyof typeof officialAddons) => void;
@@ -167,7 +176,7 @@ type Addon<Args extends OptionDefinition, Id extends string = string> = {
167
176
  */
168
177
  cancel: (reason: string) => void;
169
178
  }) => MaybePromise<void>; /** Next steps to display after the addon is run. */
170
- nextSteps?: (data: Workspace & {
179
+ nextSteps?: (workspace: Workspace & {
171
180
  options: WorkspaceOptions<Args>;
172
181
  }) => string[];
173
182
  };
package/dist/shared.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "addon"
13
13
  ],
14
14
  "exclude": [],
15
- "contents": "# Contributing Guide\n\nCheatsheet: [All official add-ons source code](https://github.com/sveltejs/cli/tree/main/packages/sv/src/addons)\n\n---\n\nSome convenient scripts are provided to help develop the add-on.\n\n```sh\n## create a new minimal project in the `demo` directory\nnpm run demo-create\n\n## add your current add-on to the demo project\nnpm run demo-add\n\n## run the tests\nnpm run test\n```\n\n## Key things to note\n\nYour `add-on` should:\n\n- export a function that returns a `defineAddon` object.\n- have a `package.json` with an `exports` field that points to the main entry point of the add-on.\n\n## Sharing your add-on\n\nWhen you're ready to publish your add-on to npm, run:\n\n```shell\nnpm login\nnpm publish\n```\n\n## Things to be aware of\n\nCommunity add-ons are **not permitted** to have any external dependencies outside of `sv`. If the use of a dependency is absolutely necessary, then they can be bundled using a bundler of your choosing (e.g. Rollup, Rolldown, tsup, etc.).\n"
15
+ "contents": "# Contributing Guide\n\nCheatsheet: [All official add-ons source code](https://github.com/sveltejs/cli/tree/main/packages/sv/src/addons)\n\n---\n\nSome convenient scripts are provided to help develop the add-on.\n\n```sh\n## create a new minimal project in the `demo` directory\nnpm run demo-create\n\n## add your current add-on to the demo project\nnpm run demo-add\n\n## run the tests\nnpm run test\n```\n\n## Key things to note\n\nYour `add-on` should:\n\n- export a function that returns a `defineAddon` object.\n- have a `package.json` with an `exports` field that points to the main entry point of the add-on.\n\n## Building\n\nYour add-on is bundled with [tsdown](https://tsdown.dev/) into a single file in `dist/`. This bundles everything except `sv` (which is a peer dependency provided at runtime).\n\n```sh\nnpm run build\n```\n\n## Publishing\n\nWhen you're ready to publish your add-on to npm:\n\n```sh\nnpm login\nnpm publish\n```\n\n> `prepublishOnly` will automatically run the build before publishing.\n\n## Things to be aware of\n\nCommunity add-ons must have `sv` as a `peerDependency` and should **not** have any `dependencies`. Everything else (including `@sveltejs/sv-utils`) is bundled at build time by tsdown.\n"
16
16
  },
17
17
  {
18
18
  "name": "README.md",
@@ -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, execept 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';\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"
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, execept 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';\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"
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-M8NNzIgv.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-DmG_8K_H.mjs";
2
2
 
3
3
  //#region src/create/index.d.ts
4
4
  type TemplateType = (typeof templateTypes)[number];
@@ -1,3 +1,2 @@
1
- import { p as create } from "../package-manager-BU-MLhop.mjs";
2
- import { c as officialAddons, l as defineAddon, t as add, u as defineAddonOptions } from "../engine-DOKagHfI.mjs";
1
+ import { d as defineAddon, f as defineAddonOptions, t as add, u as officialAddons, v as create } from "../engine-B8V7JiJ3.mjs";
3
2
  export { add, create, defineAddon, defineAddonOptions, officialAddons };
@@ -1,6 +1,7 @@
1
- import { r as OptionMap, t as AddonMap } from "../engine-M8NNzIgv.mjs";
1
+ import { r as OptionMap, t as AddonMap } from "../engine-DmG_8K_H.mjs";
2
2
  import { AgentName } from "@sveltejs/sv-utils";
3
3
  import { Page } from "@playwright/test";
4
+ import * as vitest from "vitest";
4
5
  import { TestProject } from "vitest/node";
5
6
 
6
7
  //#region src/core/package-manager.d.ts
@@ -101,5 +102,11 @@ declare function prepareServer({
101
102
  buildCommand,
102
103
  previewCommand
103
104
  }: PrepareServerOptions): Promise<PrepareServerReturn>;
105
+ type VitestContext = Pick<typeof vitest, "inject" | "test" | "beforeAll" | "beforeEach">;
106
+ declare function createSetupTest(vitest: VitestContext): <Addons extends AddonMap>(addons: Addons, options?: SetupTestOptions<Addons>) => {
107
+ test: vitest.TestAPI<Fixtures>;
108
+ testCases: Array<AddonTestCase<AddonMap>>;
109
+ prepareServer: typeof prepareServer;
110
+ };
104
111
  //#endregion
105
- export { AddonTestCase, CreateProject, Fixtures, PrepareServerOptions, PrepareServerReturn, ProjectVariant, SetupTestOptions, addPnpmBuildDependencies, createProject, prepareServer, setup, setupGlobal, startPreview, variants };
112
+ export { AddonTestCase, CreateProject, Fixtures, PrepareServerOptions, PrepareServerReturn, ProjectVariant, SetupTestOptions, VitestContext, addPnpmBuildDependencies, createProject, createSetupTest, prepareServer, setup, setupGlobal, startPreview, variants };
@@ -1,4 +1,4 @@
1
- import { B as __toESM, R as __commonJSMin, T as z, n as addPnpmBuildDependencies, p as create, w as R, z as __require } from "../package-manager-BU-MLhop.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-B8V7JiJ3.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import process$1 from "node:process";
@@ -753,5 +753,96 @@ async function prepareServer({ cwd, page, buildCommand = "pnpm build", previewCo
753
753
  close
754
754
  };
755
755
  }
756
+ function createSetupTest(vitest) {
757
+ return function setupTest(addons, options) {
758
+ const { inject, test: vitestTest, beforeAll, beforeEach } = vitest;
759
+ const test = vitestTest.extend({});
760
+ const cwd = inject("testDir");
761
+ const templatesDir = inject("templatesDir");
762
+ const variants = inject("variants");
763
+ const withBrowser = options?.browser ?? true;
764
+ let create;
765
+ let browser;
766
+ if (withBrowser) beforeAll(async () => {
767
+ let chromium;
768
+ try {
769
+ ({chromium} = await import("@playwright/test"));
770
+ } catch {
771
+ throw new Error("Browser testing requires @playwright/test. Install it with: pnpm add -D @playwright/test");
772
+ }
773
+ browser = await chromium.launch();
774
+ return async () => {
775
+ await browser.close();
776
+ };
777
+ });
778
+ const testCases = [];
779
+ for (const kind of options?.kinds ?? []) for (const variant of variants) {
780
+ const addonTestCase = {
781
+ variant,
782
+ kind
783
+ };
784
+ if (options?.filter === void 0 || options.filter(addonTestCase)) testCases.push(addonTestCase);
785
+ }
786
+ let testName;
787
+ test.beforeAll(async (_ctx, suite) => {
788
+ testName = path.dirname(suite.file.filepath).split("/").at(-1);
789
+ create = createProject({
790
+ cwd,
791
+ templatesDir,
792
+ testName
793
+ });
794
+ fs.writeFileSync(path.resolve(cwd, testName, "pnpm-workspace.yaml"), "packages:\n - '**/*'", "utf8");
795
+ fs.writeFileSync(path.resolve(cwd, testName, "package.json"), JSON.stringify({
796
+ name: `${testName}-workspace-root`,
797
+ private: true
798
+ }));
799
+ for (const addonTestCase of testCases) {
800
+ const { variant, kind } = addonTestCase;
801
+ const cwd = create({
802
+ testId: `${kind.type}-${variant}`,
803
+ variant
804
+ });
805
+ const metaPath = path.resolve(cwd, "meta.json");
806
+ fs.writeFileSync(metaPath, JSON.stringify({
807
+ variant,
808
+ kind
809
+ }, null, " "), "utf8");
810
+ if (options?.preAdd) await options.preAdd({
811
+ addonTestCase,
812
+ cwd
813
+ });
814
+ const { pnpmBuildDependencies } = await add({
815
+ cwd,
816
+ addons,
817
+ options: kind.options,
818
+ packageManager: "pnpm"
819
+ });
820
+ await addPnpmBuildDependencies(cwd, "pnpm", ["esbuild", ...pnpmBuildDependencies]);
821
+ }
822
+ execSync("pnpm install", {
823
+ cwd: path.resolve(cwd, testName),
824
+ stdio: "pipe"
825
+ });
826
+ });
827
+ beforeEach(async (ctx) => {
828
+ let browserCtx;
829
+ if (withBrowser) {
830
+ browserCtx = await browser.newContext();
831
+ ctx.page = await browserCtx.newPage();
832
+ }
833
+ ctx.cwd = (addonTestCase) => {
834
+ return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`);
835
+ };
836
+ return async () => {
837
+ if (withBrowser) await browserCtx.close();
838
+ };
839
+ });
840
+ return {
841
+ test,
842
+ testCases,
843
+ prepareServer
844
+ };
845
+ };
846
+ }
756
847
  //#endregion
757
- export { addPnpmBuildDependencies, createProject, prepareServer, setup, setupGlobal, startPreview, variants };
848
+ export { addPnpmBuildDependencies, createProject, createSetupTest, prepareServer, setup, setupGlobal, startPreview, variants };
@@ -1,4 +1,4 @@
1
- import { js, parse, svelte } from '@sveltejs/sv-utils';
1
+ import { transforms } from '@sveltejs/sv-utils';
2
2
  import { defineAddon, defineAddonOptions } from 'sv';
3
3
 
4
4
  const options = defineAddonOptions()
@@ -13,41 +13,41 @@ export default defineAddon({
13
13
  id: '~SV-NAME-TODO~',
14
14
  options,
15
15
 
16
- setup: ({ kit, unsupported }) => {
17
- if (!kit) unsupported('Requires SvelteKit');
16
+ setup: ({ isKit, unsupported }) => {
17
+ if (!isKit) unsupported('Requires SvelteKit');
18
18
  },
19
19
 
20
- run: ({ kit, sv, options, language, cancel }) => {
21
- if (!kit) return cancel('SvelteKit is required');
22
-
23
- sv.file(`src/lib/~SV-NAME-TODO~/content.txt`, () => {
24
- return `This is a text file made by the Community Addon Template demo for the add-on: '~SV-NAME-TODO~'!`;
25
- });
26
-
27
- sv.file(`src/lib/~SV-NAME-TODO~/HelloComponent.svelte`, (content) => {
28
- const { ast, generateCode } = parse.svelte(content);
29
- svelte.ensureScript(ast, { language });
30
-
31
- js.imports.addDefault(ast.instance.content, { as: 'content', from: './content.txt?raw' });
32
-
33
- svelte.addFragment(ast, '<p>{content}</p>');
34
- svelte.addFragment(ast, `<h2>Hello ${options.who}!</h2>`);
35
-
36
- return generateCode();
37
- });
38
-
39
- sv.file(kit.routesDirectory + '/+page.svelte', (content) => {
40
- const { ast, generateCode } = parse.svelte(content);
41
- svelte.ensureScript(ast, { language });
42
-
43
- js.imports.addDefault(ast.instance.content, {
44
- as: 'HelloComponent',
45
- from: `$lib/~SV-NAME-TODO~/HelloComponent.svelte`
46
- });
47
-
48
- svelte.addFragment(ast, '<HelloComponent />');
49
-
50
- return generateCode();
51
- });
20
+ run: ({ directory, sv, options, language }) => {
21
+ sv.file(
22
+ `${directory.lib}/~SV-NAME-TODO~/content.txt`,
23
+ transforms.text(() => {
24
+ return `This is a text file made by the Community Addon Template demo for the add-on: '~SV-NAME-TODO~'!`;
25
+ })
26
+ );
27
+
28
+ sv.file(
29
+ `${directory.lib}/~SV-NAME-TODO~/HelloComponent.svelte`,
30
+ transforms.svelteScript({ language }, ({ ast, svelte, js }) => {
31
+ js.imports.addDefault(ast.instance.content, {
32
+ as: 'content',
33
+ from: './content.txt?raw'
34
+ });
35
+
36
+ svelte.addFragment(ast, '<p>{content}</p>');
37
+ svelte.addFragment(ast, `<h2>Hello ${options.who}!</h2>`);
38
+ })
39
+ );
40
+
41
+ sv.file(
42
+ directory.kitRoutes + '/+page.svelte',
43
+ transforms.svelteScript({ language }, ({ ast, svelte, js }) => {
44
+ js.imports.addDefault(ast.instance.content, {
45
+ as: 'HelloComponent',
46
+ from: `$lib/~SV-NAME-TODO~/HelloComponent.svelte`
47
+ });
48
+
49
+ svelte.addFragment(ast, '<HelloComponent />');
50
+ })
51
+ );
52
52
  }
53
53
  });
@@ -1,129 +1,4 @@
1
- import { chromium } from '@playwright/test';
2
- import { execSync } from 'node:child_process';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { add } from 'sv';
6
- import { createProject, addPnpmBuildDependencies, prepareServer } from 'sv/testing';
7
- import { inject, test as vitestTest, beforeAll, beforeEach } from 'vitest';
1
+ import { createSetupTest } from 'sv/testing';
2
+ import * as vitest from 'vitest';
8
3
 
9
- const cwd = inject('testDir');
10
- const templatesDir = inject('templatesDir');
11
- const variants = inject('variants');
12
-
13
- /**
14
- * @template {import('sv').AddonMap} AddonMap
15
- * @param {AddonMap} addons
16
- * @param {import('sv/testing').SetupTestOptions<AddonMap>} [options]
17
- * @returns {{ test: ReturnType<typeof vitestTest.extend<import('sv/testing').Fixtures>>, testCases: Array<import('sv/testing').AddonTestCase<AddonMap>>, prepareServer: typeof prepareServer }}
18
- */
19
- export function setupTest(addons, options) {
20
- /** @type {ReturnType<typeof vitestTest.extend<import('sv/testing').Fixtures>>} */
21
- // @ts-ignore - vitest.extend expects fixtures object but we provide it in beforeEach
22
- const test = vitestTest.extend({});
23
-
24
- const withBrowser = options?.browser ?? true;
25
-
26
- /** @type {ReturnType<typeof createProject>} */
27
- let create;
28
- /** @type {Awaited<ReturnType<typeof chromium.launch>>} */
29
- let browser;
30
-
31
- if (withBrowser) {
32
- beforeAll(async () => {
33
- browser = await chromium.launch();
34
- return async () => {
35
- await browser.close();
36
- };
37
- });
38
- }
39
-
40
- /** @type {Array<import('sv/testing').AddonTestCase<AddonMap>>} */
41
- const testCases = [];
42
- for (const kind of options?.kinds ?? []) {
43
- for (const variant of variants) {
44
- const addonTestCase = { variant, kind };
45
- if (options?.filter === undefined || options.filter(addonTestCase)) {
46
- testCases.push(addonTestCase);
47
- }
48
- }
49
- }
50
- /** @type {string} */
51
- let testName;
52
- test.beforeAll(async (_ctx, suite) => {
53
- testName = path.dirname(suite.name).split('/').at(-1) ?? '';
54
-
55
- // constructs a builder to create test projects
56
- create = createProject({ cwd, templatesDir, testName });
57
-
58
- // creates a pnpm workspace in each addon dir
59
- fs.writeFileSync(
60
- path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
61
- "packages:\n - '**/*'",
62
- 'utf8'
63
- );
64
-
65
- // creates a barebones package.json in each addon dir
66
- fs.writeFileSync(
67
- path.resolve(cwd, testName, 'package.json'),
68
- JSON.stringify({
69
- name: `${testName}-workspace-root`,
70
- private: true
71
- })
72
- );
73
-
74
- for (const addonTestCase of testCases) {
75
- const { variant, kind } = addonTestCase;
76
- const cwd = create({ testId: `${kind.type}-${variant}`, variant });
77
-
78
- // test metadata
79
- const metaPath = path.resolve(cwd, 'meta.json');
80
- fs.writeFileSync(metaPath, JSON.stringify({ variant, kind }, null, '\t'), 'utf8');
81
-
82
- if (options?.preAdd) {
83
- await options.preAdd({ addonTestCase, cwd });
84
- }
85
- const { pnpmBuildDependencies } = await add({
86
- cwd,
87
- addons,
88
- options: kind.options,
89
- packageManager: 'pnpm'
90
- });
91
- await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
92
- }
93
-
94
- execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' });
95
- });
96
-
97
- // runs before each test case
98
- /**
99
- * @param {import('sv/testing').Fixtures & import('vitest').TestContext} ctx
100
- */
101
- beforeEach(async (ctx) => {
102
- /** @type {Awaited<ReturnType<typeof browser.newContext>>} */
103
- let browserCtx;
104
- if (withBrowser) {
105
- browserCtx = await browser.newContext();
106
- /** @type {import('sv/testing').Fixtures} */ (/** @type {unknown} */ (ctx)).page =
107
- await browserCtx.newPage();
108
- }
109
-
110
- /**
111
- * @param {import('sv/testing').AddonTestCase<Addons>} addonTestCase
112
- * @returns {string}
113
- */
114
- /** @type {import('sv/testing').Fixtures} */ (/** @type {unknown} */ (ctx)).cwd = (
115
- addonTestCase
116
- ) => {
117
- return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`);
118
- };
119
-
120
- return async () => {
121
- if (withBrowser) {
122
- await browserCtx.close();
123
- }
124
- // ...other tear downs
125
- };
126
- });
127
-
128
- return { test, testCases, prepareServer };
129
- }
4
+ export const setupTest = createSetupTest(vitest);
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.js'],
5
+ format: 'esm'
6
+ });
@@ -8,26 +8,34 @@
8
8
  "demo-create": "sv create demo --types ts --template minimal --no-add-ons --no-install",
9
9
  "demo-add": "sv add file:../ --cwd demo --no-git-check --no-install",
10
10
  "demo-add:ci": "sv add file:../=who:you --cwd demo --no-git-check --no-download-check --no-install",
11
+ "build": "tsdown",
12
+ "prepublishOnly": "npm run build",
11
13
  "test": "vitest run"
12
14
  },
13
- "files": ["src", "!src/**/*.test.*"],
15
+ "files": ["dist"],
14
16
  "exports": {
15
17
  ".": {
16
18
  "default": "./src/index.js"
17
19
  }
18
20
  },
19
- "dependencies": {
20
- "@sveltejs/sv-utils": "latest",
21
+ "publishConfig": {
22
+ "access": "public",
23
+ "exports": {
24
+ ".": {
25
+ "default": "./dist/index.js"
26
+ }
27
+ }
28
+ },
29
+ "peerDependencies": {
21
30
  "sv": "latest"
22
31
  },
23
32
  "devDependencies": {
33
+ "sv": "latest",
34
+ "@sveltejs/sv-utils": "latest",
24
35
  "@playwright/test": "^1.58.2",
25
36
  "@types/node": "^25.2.1",
37
+ "tsdown": "^0.21.4",
26
38
  "vitest": "^4.1.0"
27
39
  },
28
- "keywords": ["sv-add"],
29
- "publishConfig": {
30
- "directory": "dist",
31
- "access": "public"
32
- }
40
+ "keywords": ["sv-add"]
33
41
  }
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <link rel="icon" href="%sveltekit.assets%/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="text-scale" content="scale" />
7
8
  %sveltekit.head%
8
9
  </head>
9
10
  <body data-sveltekit-preload-data="hover">
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <link rel="icon" href="%sveltekit.assets%/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="text-scale" content="scale" />
7
8
  %sveltekit.head%
8
9
  </head>
9
10
  <body data-sveltekit-preload-data="hover">
@@ -3,6 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="text-scale" content="scale" />
6
7
  %sveltekit.head%
7
8
  </head>
8
9
  <body data-sveltekit-preload-data="hover">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
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.3"
28
+ "@sveltejs/sv-utils": "0.0.5"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@clack/prompts": "1.0.0",