sv 0.12.8 → 0.13.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 +13 -18
- package/dist/{engine-BZ0rj9tz.d.mts → engine-fG9K-byo.d.mts} +42 -52
- package/dist/engine-lCnxwqd0.mjs +12404 -0
- package/dist/shared.json +3 -3
- package/dist/src/index.d.mts +1 -1
- package/dist/src/index.mjs +2 -4
- package/dist/src/testing.d.mts +11 -7
- package/dist/src/testing.mjs +124 -47
- package/dist/templates/addon/assets/src/index.js +35 -35
- package/dist/templates/addon/assets/tests/setup/suite.js +3 -128
- package/dist/templates/addon/assets/tsdown.config.js +6 -0
- package/dist/templates/addon/package.json +16 -8
- package/dist/templates/demo/assets/src/app.html +1 -0
- package/dist/templates/demo/files.types=checkjs.json +1 -1
- package/dist/templates/demo/files.types=none.json +1 -1
- package/dist/templates/demo/files.types=typescript.json +1 -1
- package/dist/templates/demo/package.json +1 -1
- package/dist/templates/library/assets/src/app.html +1 -0
- package/dist/templates/library/package.json +1 -1
- package/dist/templates/minimal/assets/src/app.html +1 -0
- package/dist/templates/minimal/package.json +1 -1
- package/dist/templates/svelte/files.types=none.json +1 -1
- package/dist/templates/svelte/files.types=typescript.json +1 -1
- package/package.json +2 -2
- package/dist/engine-DUNH7ELq.mjs +0 -7042
- package/dist/package-manager-BYzDyeam.mjs +0 -5964
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##
|
|
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';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\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}
|
|
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';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\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}
|
|
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",
|
package/dist/src/index.d.mts
CHANGED
|
@@ -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-
|
|
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-fG9K-byo.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/create/index.d.ts
|
|
4
4
|
type TemplateType = (typeof templateTypes)[number];
|
package/dist/src/index.mjs
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export { add, create, defineAddon, defineAddonOptions, officialAddons };
|
|
1
|
+
import { d as defineAddon, f as defineAddonOptions, t as add, u as officialAddons, v as create } from "../engine-lCnxwqd0.mjs";
|
|
2
|
+
export { add, create, defineAddon, defineAddonOptions, officialAddons };
|
package/dist/src/testing.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { r as OptionMap, t as AddonMap } from "../engine-
|
|
1
|
+
import { r as OptionMap, t as AddonMap } from "../engine-fG9K-byo.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
|
|
7
|
-
|
|
8
8
|
declare function addPnpmBuildDependencies(cwd: string, packageManager: AgentName | null | undefined, allowedPackages: string[]): Promise<void>;
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/testing.d.ts
|
|
@@ -12,14 +12,12 @@ type ProjectVariant = "kit-js" | "kit-ts" | "vite-js" | "vite-ts";
|
|
|
12
12
|
declare const variants: ProjectVariant[];
|
|
13
13
|
type CreateProject = (options: {
|
|
14
14
|
testId: string;
|
|
15
|
-
variant: ProjectVariant;
|
|
16
|
-
/** @default true */
|
|
15
|
+
variant: ProjectVariant; /** @default true */
|
|
17
16
|
clean?: boolean;
|
|
18
17
|
}) => string;
|
|
19
18
|
type SetupOptions = {
|
|
20
19
|
cwd: string;
|
|
21
|
-
variants: readonly ProjectVariant[];
|
|
22
|
-
/** @default false */
|
|
20
|
+
variants: readonly ProjectVariant[]; /** @default false */
|
|
23
21
|
clean?: boolean;
|
|
24
22
|
};
|
|
25
23
|
declare function setup({
|
|
@@ -104,5 +102,11 @@ declare function prepareServer({
|
|
|
104
102
|
buildCommand,
|
|
105
103
|
previewCommand
|
|
106
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
|
+
};
|
|
107
111
|
//#endregion
|
|
108
|
-
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 };
|
package/dist/src/testing.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
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-lCnxwqd0.mjs";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process$1 from "node:process";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
6
|
-
|
|
7
6
|
//#region ../../node_modules/.pnpm/through@2.3.8/node_modules/through/index.js
|
|
8
7
|
var require_through = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
9
8
|
var Stream$4 = __require("stream");
|
|
@@ -83,15 +82,14 @@ var require_through = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
83
82
|
return stream;
|
|
84
83
|
}
|
|
85
84
|
}));
|
|
86
|
-
|
|
87
85
|
//#endregion
|
|
88
86
|
//#region ../../node_modules/.pnpm/from@0.1.7/node_modules/from/index.js
|
|
89
87
|
var require_from = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
90
88
|
var Stream$3 = __require("stream");
|
|
91
|
-
module.exports = function from
|
|
89
|
+
module.exports = function from(source) {
|
|
92
90
|
if (Array.isArray(source)) {
|
|
93
91
|
var source_index = 0, source_len = source.length;
|
|
94
|
-
return from
|
|
92
|
+
return from(function(i) {
|
|
95
93
|
if (source_index < source_len) this.emit("data", source[source_index++]);
|
|
96
94
|
else this.emit("end");
|
|
97
95
|
return true;
|
|
@@ -135,7 +133,6 @@ var require_from = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
135
133
|
return s;
|
|
136
134
|
};
|
|
137
135
|
}));
|
|
138
|
-
|
|
139
136
|
//#endregion
|
|
140
137
|
//#region ../../node_modules/.pnpm/duplexer@0.1.2/node_modules/duplexer/index.js
|
|
141
138
|
var require_duplexer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -184,8 +181,8 @@ var require_duplexer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
184
181
|
}
|
|
185
182
|
}
|
|
186
183
|
function proxyStream(methodName) {
|
|
187
|
-
reader.on(methodName, reemit
|
|
188
|
-
function reemit
|
|
184
|
+
reader.on(methodName, reemit);
|
|
185
|
+
function reemit() {
|
|
189
186
|
var args = slice.call(arguments);
|
|
190
187
|
args.unshift(methodName);
|
|
191
188
|
stream.emit.apply(stream, args);
|
|
@@ -203,7 +200,6 @@ var require_duplexer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
202
|
}));
|
|
206
|
-
|
|
207
203
|
//#endregion
|
|
208
204
|
//#region ../../node_modules/.pnpm/map-stream@0.1.0/node_modules/map-stream/index.js
|
|
209
205
|
var require_map_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -284,13 +280,11 @@ var require_map_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
284
280
|
return stream;
|
|
285
281
|
};
|
|
286
282
|
}));
|
|
287
|
-
|
|
288
283
|
//#endregion
|
|
289
284
|
//#region ../../node_modules/.pnpm/pause-stream@0.0.11/node_modules/pause-stream/index.js
|
|
290
285
|
var require_pause_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
291
286
|
module.exports = require_through();
|
|
292
287
|
}));
|
|
293
|
-
|
|
294
288
|
//#endregion
|
|
295
289
|
//#region ../../node_modules/.pnpm/split@0.3.3/node_modules/split/index.js
|
|
296
290
|
var require_split = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -331,7 +325,6 @@ var require_split = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
331
325
|
});
|
|
332
326
|
}
|
|
333
327
|
}));
|
|
334
|
-
|
|
335
328
|
//#endregion
|
|
336
329
|
//#region ../../node_modules/.pnpm/stream-combiner@0.0.4/node_modules/stream-combiner/index.js
|
|
337
330
|
var require_stream_combiner = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -340,10 +333,10 @@ var require_stream_combiner = /* @__PURE__ */ __commonJSMin(((exports, module) =
|
|
|
340
333
|
var streams = [].slice.call(arguments), first = streams[0], last = streams[streams.length - 1], thepipe = duplexer(first, last);
|
|
341
334
|
if (streams.length == 1) return streams[0];
|
|
342
335
|
else if (!streams.length) throw new Error("connect called with empty args");
|
|
343
|
-
function recurse(streams
|
|
344
|
-
if (streams
|
|
345
|
-
streams
|
|
346
|
-
recurse(streams
|
|
336
|
+
function recurse(streams) {
|
|
337
|
+
if (streams.length < 2) return;
|
|
338
|
+
streams[0].pipe(streams[1]);
|
|
339
|
+
recurse(streams.slice(1));
|
|
347
340
|
}
|
|
348
341
|
recurse(streams);
|
|
349
342
|
function onerror() {
|
|
@@ -355,7 +348,6 @@ var require_stream_combiner = /* @__PURE__ */ __commonJSMin(((exports, module) =
|
|
|
355
348
|
return thepipe;
|
|
356
349
|
};
|
|
357
350
|
}));
|
|
358
|
-
|
|
359
351
|
//#endregion
|
|
360
352
|
//#region ../../node_modules/.pnpm/event-stream@3.3.4/node_modules/event-stream/index.js
|
|
361
353
|
var require_event_stream = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
@@ -460,8 +452,8 @@ var require_event_stream = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
460
452
|
reading = false;
|
|
461
453
|
get.apply(null, arguments);
|
|
462
454
|
});
|
|
463
|
-
} catch (err
|
|
464
|
-
stream.emit("error", err
|
|
455
|
+
} catch (err) {
|
|
456
|
+
stream.emit("error", err);
|
|
465
457
|
}
|
|
466
458
|
});
|
|
467
459
|
}
|
|
@@ -516,13 +508,13 @@ var require_event_stream = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
516
508
|
});
|
|
517
509
|
};
|
|
518
510
|
es$1.stringify = function() {
|
|
519
|
-
var Buffer
|
|
511
|
+
var Buffer = __require("buffer").Buffer;
|
|
520
512
|
return es$1.mapSync(function(e) {
|
|
521
|
-
return JSON.stringify(Buffer
|
|
513
|
+
return JSON.stringify(Buffer.isBuffer(e) ? e.toString() : e) + "\n";
|
|
522
514
|
});
|
|
523
515
|
};
|
|
524
|
-
es$1.replace = function(from
|
|
525
|
-
return es$1.pipeline(es$1.split(from
|
|
516
|
+
es$1.replace = function(from, to) {
|
|
517
|
+
return es$1.pipeline(es$1.split(from), es$1.join(to));
|
|
526
518
|
};
|
|
527
519
|
es$1.join = function(str) {
|
|
528
520
|
if ("function" === typeof str) return es$1.wait(str);
|
|
@@ -549,10 +541,9 @@ var require_event_stream = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
549
541
|
throw new Error("[EVENT-STREAM] es.pipeable is deprecated");
|
|
550
542
|
};
|
|
551
543
|
}));
|
|
552
|
-
|
|
553
544
|
//#endregion
|
|
554
|
-
//#region
|
|
555
|
-
var
|
|
545
|
+
//#region src/testing.ts
|
|
546
|
+
var import_ps_tree = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
556
547
|
var spawn$1 = __require("child_process").spawn, es = require_event_stream();
|
|
557
548
|
module.exports = function childrenOfPid(pid, callback) {
|
|
558
549
|
var headers = null;
|
|
@@ -608,11 +599,7 @@ var require_ps_tree = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
608
599
|
default: throw new Error("Unknown process listing header: " + str);
|
|
609
600
|
}
|
|
610
601
|
}
|
|
611
|
-
}));
|
|
612
|
-
|
|
613
|
-
//#endregion
|
|
614
|
-
//#region src/testing.ts
|
|
615
|
-
var import_ps_tree = /* @__PURE__ */ __toESM(require_ps_tree(), 1);
|
|
602
|
+
})))(), 1);
|
|
616
603
|
const variants = [
|
|
617
604
|
"kit-js",
|
|
618
605
|
"kit-ts",
|
|
@@ -620,15 +607,15 @@ const variants = [
|
|
|
620
607
|
"vite-ts"
|
|
621
608
|
];
|
|
622
609
|
const TEMPLATES_DIR = ".templates";
|
|
623
|
-
function setup({ cwd
|
|
624
|
-
const workingDir = path.resolve(cwd
|
|
610
|
+
function setup({ cwd, clean = false, variants }) {
|
|
611
|
+
const workingDir = path.resolve(cwd);
|
|
625
612
|
if (clean && fs.existsSync(workingDir)) fs.rmSync(workingDir, {
|
|
626
613
|
force: true,
|
|
627
614
|
recursive: true
|
|
628
615
|
});
|
|
629
616
|
const templatesDir = path.resolve(workingDir, TEMPLATES_DIR);
|
|
630
617
|
fs.mkdirSync(templatesDir, { recursive: true });
|
|
631
|
-
for (const variant of variants
|
|
618
|
+
for (const variant of variants) {
|
|
632
619
|
const templatePath = path.resolve(templatesDir, variant);
|
|
633
620
|
if (fs.existsSync(templatePath)) continue;
|
|
634
621
|
if (variant === "kit-js") create(templatePath, {
|
|
@@ -655,8 +642,8 @@ function setup({ cwd: cwd$1, clean = false, variants: variants$1 }) {
|
|
|
655
642
|
}
|
|
656
643
|
return { templatesDir };
|
|
657
644
|
}
|
|
658
|
-
function createProject({ cwd
|
|
659
|
-
const testDir = path.resolve(cwd
|
|
645
|
+
function createProject({ cwd, testName, templatesDir }) {
|
|
646
|
+
const testDir = path.resolve(cwd, testName);
|
|
660
647
|
fs.mkdirSync(testDir, { recursive: true });
|
|
661
648
|
return ({ testId, variant, clean = true }) => {
|
|
662
649
|
const targetDir = path.resolve(testDir, testId);
|
|
@@ -672,11 +659,11 @@ function createProject({ cwd: cwd$1, testName, templatesDir }) {
|
|
|
672
659
|
return targetDir;
|
|
673
660
|
};
|
|
674
661
|
}
|
|
675
|
-
async function startPreview({ cwd
|
|
662
|
+
async function startPreview({ cwd, command = "npm run preview" }) {
|
|
676
663
|
const [cmd, ...args] = command.split(" ");
|
|
677
|
-
const proc =
|
|
664
|
+
const proc = z(cmd, args, {
|
|
678
665
|
nodeOptions: {
|
|
679
|
-
cwd
|
|
666
|
+
cwd,
|
|
680
667
|
stdio: "pipe"
|
|
681
668
|
},
|
|
682
669
|
throwOnError: true,
|
|
@@ -686,13 +673,13 @@ async function startPreview({ cwd: cwd$1, command = "npm run preview" }) {
|
|
|
686
673
|
if (!proc.pid) return;
|
|
687
674
|
await terminate(proc.pid);
|
|
688
675
|
};
|
|
689
|
-
return await new Promise((resolve
|
|
676
|
+
return await new Promise((resolve, reject) => {
|
|
690
677
|
if (!proc.process?.stdout) return reject("impossible state");
|
|
691
678
|
proc.process.stdout.on("data", (data) => {
|
|
692
679
|
const urls = data.toString().replace(/[^\x20-\xaf]+/g, "").replace(/\[[0-9]{1,2}m/g, "").match(/http:\/\/[^:\s]+:[0-9]+\//g);
|
|
693
680
|
if (urls && urls.length > 0) {
|
|
694
681
|
const url = urls[0];
|
|
695
|
-
resolve
|
|
682
|
+
resolve({
|
|
696
683
|
url,
|
|
697
684
|
close
|
|
698
685
|
});
|
|
@@ -710,7 +697,7 @@ async function getProcessTree(pid) {
|
|
|
710
697
|
}
|
|
711
698
|
async function terminate(pid) {
|
|
712
699
|
if (process$1.platform === "win32") {
|
|
713
|
-
await
|
|
700
|
+
await R("taskkill", [
|
|
714
701
|
"/PID",
|
|
715
702
|
`${pid}`,
|
|
716
703
|
"/T",
|
|
@@ -745,13 +732,13 @@ function setupGlobal({ TEST_DIR, pre, post }) {
|
|
|
745
732
|
};
|
|
746
733
|
};
|
|
747
734
|
}
|
|
748
|
-
async function prepareServer({ cwd
|
|
735
|
+
async function prepareServer({ cwd, page, buildCommand = "pnpm build", previewCommand = "pnpm preview" }) {
|
|
749
736
|
if (buildCommand) execSync(buildCommand, {
|
|
750
|
-
cwd
|
|
737
|
+
cwd,
|
|
751
738
|
stdio: "pipe"
|
|
752
739
|
});
|
|
753
740
|
const { url, close } = await startPreview({
|
|
754
|
-
cwd
|
|
741
|
+
cwd,
|
|
755
742
|
command: previewCommand
|
|
756
743
|
});
|
|
757
744
|
page.setDefaultNavigationTimeout(62e3);
|
|
@@ -766,6 +753,96 @@ async function prepareServer({ cwd: cwd$1, page, buildCommand = "pnpm build", pr
|
|
|
766
753
|
close
|
|
767
754
|
};
|
|
768
755
|
}
|
|
769
|
-
|
|
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
|
+
}
|
|
770
847
|
//#endregion
|
|
771
|
-
export { addPnpmBuildDependencies, createProject, prepareServer, setup, setupGlobal, startPreview, variants };
|
|
848
|
+
export { addPnpmBuildDependencies, createProject, createSetupTest, prepareServer, setup, setupGlobal, startPreview, variants };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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: ({
|
|
17
|
-
if (!
|
|
16
|
+
setup: ({ isKit, unsupported }) => {
|
|
17
|
+
if (!isKit) unsupported('Requires SvelteKit');
|
|
18
18
|
},
|
|
19
19
|
|
|
20
|
-
run: ({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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 {
|
|
2
|
-
import
|
|
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
|
|
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);
|