sv 0.16.5 → 0.16.6
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 +1 -1
- package/dist/{engine-CtSoxta7.d.mts → engine-BhR6Vrxy.d.mts} +18 -5
- package/dist/{engine-CCAozEpo.mjs → engine-DbEL5s1q.mjs} +130 -53
- package/dist/src/index.d.mts +1 -1
- package/dist/src/index.mjs +1 -1
- package/dist/src/testing.d.mts +1 -1
- package/dist/src/testing.mjs +1 -1
- package/dist/templates/addon/package.json +3 -3
- package/package.json +2 -2
package/dist/bin.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as name, a as detectPackageManager, d as Command, g as helpConfig, h as forwardExitCode, l as from, n as add, r as create, u as program, v as version } from "./engine-
|
|
2
|
+
import { _ as name, a as detectPackageManager, d as Command, g as helpConfig, h as forwardExitCode, l as from, n as add, r as create, u as program, v as version } from "./engine-DbEL5s1q.mjs";
|
|
3
3
|
import { color, resolveCommandArray } from "@sveltejs/sv-utils";
|
|
4
4
|
import V from "node:process";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
@@ -65,7 +65,7 @@ type BaseQuestion<Args extends OptionDefinition> = {
|
|
|
65
65
|
};
|
|
66
66
|
type Question<Args extends OptionDefinition = OptionDefinition> = BaseQuestion<Args> & (BooleanQuestion | StringQuestion | NumberQuestion | SelectQuestion<any> | MultiSelectQuestion<any>);
|
|
67
67
|
type OptionDefinition = Record<string, Question<any>>;
|
|
68
|
-
type OptionValues<Args extends OptionDefinition> = { [K in keyof Args]: Args[K] extends StringQuestion ? string : Args[K] extends BooleanQuestion ? boolean : Args[K] extends NumberQuestion ? number : Args[K] extends SelectQuestion<infer Value> ? Value : Args[K] extends MultiSelectQuestion<infer Value> ? Value[] : "ERROR: The value for this type is invalid. Ensure that the `default` value exists in `options`." };
|
|
68
|
+
type OptionValues<Args extends OptionDefinition> = { [K in keyof Args]: Args[K] extends StringQuestion ? string : Args[K] extends BooleanQuestion ? boolean : Args[K] extends NumberQuestion ? number : Args[K] extends SelectQuestion<infer Value> ? Value : Args[K] extends MultiSelectQuestion<infer Value> ? Value[] : Args[K] extends Question<any> ? unknown : "ERROR: The value for this type is invalid. Ensure that the `default` value exists in `options`." };
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region src/core/workspace.d.ts
|
|
71
71
|
type WorkspaceOptions<Args extends OptionDefinition> = OptionValues<Args>;
|
|
@@ -134,7 +134,7 @@ type SvApi = {
|
|
|
134
134
|
*/
|
|
135
135
|
file: (path: string, edit: (content: string) => string | false) => void;
|
|
136
136
|
};
|
|
137
|
-
type Addon<Args extends OptionDefinition, Id extends string = string> = {
|
|
137
|
+
type Addon<Args extends OptionDefinition, Id extends string = string, Setup extends Record<string, unknown> = Record<string, unknown>> = {
|
|
138
138
|
id: Id;
|
|
139
139
|
alias?: string; /** one-liner shown in prompts */
|
|
140
140
|
shortDescription?: string; /** link to docs/repo */
|
|
@@ -149,10 +149,11 @@ type Addon<Args extends OptionDefinition, Id extends string = string> = {
|
|
|
149
149
|
* if (!isKit) unsupported('Requires SvelteKit');
|
|
150
150
|
*/
|
|
151
151
|
unsupported: (reason: string) => void; /** On what official addons does this addon run after? */
|
|
152
|
-
runsAfter: (name: keyof typeof officialAddons) => void;
|
|
152
|
+
runsAfter: (name: keyof typeof officialAddons) => void; /** Dynamically add an option to be prompted to the user */
|
|
153
|
+
addOption: <K extends Extract<keyof Setup, string>>(key: K, question: SetupOptions<Setup>[K]) => void;
|
|
153
154
|
}) => MaybePromise<void>; /** Run the addon. The actual execution of the addon... Add files, edit files, etc. */
|
|
154
155
|
run: (workspace: Workspace & {
|
|
155
|
-
/** Add-on options */options: WorkspaceOptions<Args>; /** Api to interact with the workspace. */
|
|
156
|
+
/** Add-on options (includes dynamically added options from setup) */options: WorkspaceOptions<Args> & Record<string, unknown>; /** Api to interact with the workspace. */
|
|
156
157
|
sv: SvApi;
|
|
157
158
|
/** Cancel the addon at any time!
|
|
158
159
|
* @example
|
|
@@ -161,13 +162,24 @@ type Addon<Args extends OptionDefinition, Id extends string = string> = {
|
|
|
161
162
|
cancel: (reason: string) => void;
|
|
162
163
|
}) => MaybePromise<void>; /** Next steps to display after the addon is run. */
|
|
163
164
|
nextSteps?: (workspace: Workspace & {
|
|
164
|
-
options: WorkspaceOptions<Args>;
|
|
165
|
+
options: WorkspaceOptions<Args> & Record<string, unknown>;
|
|
165
166
|
}) => string[];
|
|
166
167
|
};
|
|
168
|
+
/** Maps value types to question definitions for dynamic setup options */
|
|
169
|
+
type SetupOptions<T extends Record<string, unknown>> = { [K in keyof T]: BaseQuestion<any> & (T[K] extends boolean ? BooleanQuestion : T[K] extends string ? StringQuestion : T[K] extends number ? NumberQuestion : T[K] extends Array<infer V> ? MultiSelectQuestion<V> : Question<any>) };
|
|
167
170
|
/**
|
|
168
171
|
* The entry point for your addon, It will hold every thing! (options, setup, run, nextSteps, ...)
|
|
172
|
+
*
|
|
173
|
+
* For dynamic options added via `addOption` in setup, use the generic to get strong typing:
|
|
174
|
+
* ```ts
|
|
175
|
+
* const addon = defineAddon<{ extra: boolean }>()({ ... });
|
|
176
|
+
* addon.options.extra.default // boolean
|
|
177
|
+
* ```
|
|
169
178
|
*/
|
|
170
179
|
declare function defineAddon<const Id extends string, Args extends OptionDefinition>(config: Addon<Args, Id>): Addon<Args, Id>;
|
|
180
|
+
declare function defineAddon<SetupValues extends Record<string, unknown>>(): <const Id extends string, Args extends OptionDefinition>(config: Omit<Addon<Args & SetupOptions<SetupValues>, Id, SetupValues>, "options"> & {
|
|
181
|
+
options: Args;
|
|
182
|
+
}) => Addon<Args & SetupOptions<SetupValues>, Id, SetupValues>;
|
|
171
183
|
/**
|
|
172
184
|
* Stage 1: Raw CLI input - what the user typed
|
|
173
185
|
*/
|
|
@@ -229,6 +241,7 @@ type SetupResult = {
|
|
|
229
241
|
dependsOn: string[];
|
|
230
242
|
unsupported: string[];
|
|
231
243
|
runsAfter: string[];
|
|
244
|
+
additionalOptions: Record<string, Question>;
|
|
232
245
|
};
|
|
233
246
|
type AddonDefinition<Id extends string = string> = Addon<Record<string, Question<any>>, Id>;
|
|
234
247
|
type MaybePromise<T> = Promise<T> | T;
|
|
@@ -8,7 +8,7 @@ import * as b$1 from "node:readline";
|
|
|
8
8
|
import G from "node:readline";
|
|
9
9
|
import { ReadStream } from "node:tty";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
-
import childProcess, { exec, spawn } from "node:child_process";
|
|
11
|
+
import childProcess, { exec, spawn, spawnSync } from "node:child_process";
|
|
12
12
|
import { pipeline } from "node:stream/promises";
|
|
13
13
|
import { PassThrough } from "node:stream";
|
|
14
14
|
import { EventEmitter } from "node:events";
|
|
@@ -493,9 +493,9 @@ function W({ input: r = stdin, output: t = stdout, overwrite: s = !0, hideCursor
|
|
|
493
493
|
r.off("keypress", n), e && t.write(import_src.cursor.show), r instanceof ReadStream && r.isTTY && !q$1 && r.setRawMode(!1), i.terminal = !1, i.close();
|
|
494
494
|
};
|
|
495
495
|
}
|
|
496
|
-
const A = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80, L = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
|
|
497
|
-
function B(r, t, s, e = s, i = s, n) {
|
|
498
|
-
return wrapAnsi(t, A(r ?? stdout) - s.length, {
|
|
496
|
+
const A$1 = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80, L$1 = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
|
|
497
|
+
function B$1(r, t, s, e = s, i = s, n) {
|
|
498
|
+
return wrapAnsi(t, A$1(r ?? stdout) - s.length, {
|
|
499
499
|
hard: !0,
|
|
500
500
|
trim: !1
|
|
501
501
|
}).split(`
|
|
@@ -629,7 +629,7 @@ var m = class {
|
|
|
629
629
|
if (t !== this._prevFrame) {
|
|
630
630
|
if (this.state === "initial") this.output.write(import_src.cursor.hide);
|
|
631
631
|
else {
|
|
632
|
-
const s = Y$1(this._prevFrame, t), e = L(this.output);
|
|
632
|
+
const s = Y$1(this._prevFrame, t), e = L$1(this.output);
|
|
633
633
|
if (this.restoreCursor(), s) {
|
|
634
634
|
const i = Math.max(0, s.numLinesAfter - e), n = Math.max(0, s.numLinesBefore - e);
|
|
635
635
|
let o = s.lines.find((u) => u >= i);
|
|
@@ -805,7 +805,7 @@ const tt = se(), at = () => process.env.CI === "true", Tt = (t) => t.isTTY === !
|
|
|
805
805
|
removals: c
|
|
806
806
|
};
|
|
807
807
|
}, F$1 = ({ cursor: t, options: i, style: s, output: r = process.stdout, maxItems: u = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: a = 4 }) => {
|
|
808
|
-
const c = A(r) - n, o = L(r), l = styleText("dim", "..."), d = Math.max(o - a, 0), g = Math.max(Math.min(u, d), 5);
|
|
808
|
+
const c = A$1(r) - n, o = L$1(r), l = styleText("dim", "..."), d = Math.max(o - a, 0), g = Math.max(Math.min(u, d), 5);
|
|
809
809
|
let p = 0;
|
|
810
810
|
t >= g - 3 && (p = Math.max(Math.min(t - g + 3, i.length - g), 0));
|
|
811
811
|
let f = g < i.length && p > 0, h = g < i.length && p + g < i.length;
|
|
@@ -843,7 +843,7 @@ const le = (t) => {
|
|
|
843
843
|
output: t.output,
|
|
844
844
|
initialValue: t.initialValue ?? !0,
|
|
845
845
|
render() {
|
|
846
|
-
const r = t.withGuide ?? h$1.withGuide, u = `${P$1(this.state)} `, n = r ? `${styleText("gray", $)} ` : "", a = B(t.output, t.message, n, u), c = `${r ? `${styleText("gray", $)}
|
|
846
|
+
const r = t.withGuide ?? h$1.withGuide, u = `${P$1(this.state)} `, n = r ? `${styleText("gray", $)} ` : "", a = B$1(t.output, t.message, n, u), c = `${r ? `${styleText("gray", $)}
|
|
847
847
|
` : ""}${a}
|
|
848
848
|
`, o = this.value ? i : s;
|
|
849
849
|
switch (this.state) {
|
|
@@ -961,7 +961,7 @@ ${styleText("reset", styleText("dim", `Press ${styleText([
|
|
|
961
961
|
], " space ")} to select, ${styleText("gray", styleText("bgWhite", styleText("inverse", " enter ")))} to submit`))}`;
|
|
962
962
|
},
|
|
963
963
|
render() {
|
|
964
|
-
const r = t.withGuide ?? h$1.withGuide, u = B(t.output, t.message, r ? `${ft(this.state)} ` : "", `${P$1(this.state)} `), n = `${r ? `${styleText("gray", $)}
|
|
964
|
+
const r = t.withGuide ?? h$1.withGuide, u = B$1(t.output, t.message, r ? `${ft(this.state)} ` : "", `${P$1(this.state)} `), n = `${r ? `${styleText("gray", $)}
|
|
965
965
|
` : ""}${u}
|
|
966
966
|
`, a = this.value ?? [], c = (o, l) => {
|
|
967
967
|
if (o.disabled) return i(o, "disabled");
|
|
@@ -971,12 +971,12 @@ ${styleText("reset", styleText("dim", `Press ${styleText([
|
|
|
971
971
|
switch (this.state) {
|
|
972
972
|
case "submit": {
|
|
973
973
|
const o = this.options.filter(({ value: d }) => a.includes(d)).map((d) => i(d, "submitted")).join(styleText("dim", ", ")) || styleText("dim", "none");
|
|
974
|
-
return `${n}${B(t.output, o, r ? `${styleText("gray", $)} ` : "")}`;
|
|
974
|
+
return `${n}${B$1(t.output, o, r ? `${styleText("gray", $)} ` : "")}`;
|
|
975
975
|
}
|
|
976
976
|
case "cancel": {
|
|
977
977
|
const o = this.options.filter(({ value: d }) => a.includes(d)).map((d) => i(d, "cancelled")).join(styleText("dim", ", "));
|
|
978
978
|
if (o.trim() === "") return `${n}${styleText("gray", $)}`;
|
|
979
|
-
return `${n}${B(t.output, o, r ? `${styleText("gray", $)} ` : "")}${r ? `
|
|
979
|
+
return `${n}${B$1(t.output, o, r ? `${styleText("gray", $)} ` : "")}${r ? `
|
|
980
980
|
${styleText("gray", $)}` : ""}`;
|
|
981
981
|
}
|
|
982
982
|
case "error": {
|
|
@@ -1027,7 +1027,7 @@ ${r ? styleText("cyan", x$1) : ""}
|
|
|
1027
1027
|
}, Ce = (t = "", i = "", s) => {
|
|
1028
1028
|
const r = s?.output ?? V.stdout, u = s?.withGuide ?? h$1.withGuide, n = s?.format ?? be, a = [
|
|
1029
1029
|
"",
|
|
1030
|
-
...Se(t, A(r) - 6, n).split(`
|
|
1030
|
+
...Se(t, A$1(r) - 6, n).split(`
|
|
1031
1031
|
`).map(n),
|
|
1032
1032
|
""
|
|
1033
1033
|
], c = fastStringWidth(i), o = Math.max(a.reduce((p, f) => {
|
|
@@ -1053,7 +1053,7 @@ ${styleText("gray", g + st.repeat(o + 2) + dt)}
|
|
|
1053
1053
|
], delay: a = tt ? 80 : 120, signal: c, ...o } = {}) => {
|
|
1054
1054
|
const l = at();
|
|
1055
1055
|
let d, g, p = !1, f = !1, h = "", I, m = performance.now();
|
|
1056
|
-
const y = A(s), v = o?.styleFrame ?? _e, C = (_) => {
|
|
1056
|
+
const y = A$1(s), v = o?.styleFrame ?? _e, C = (_) => {
|
|
1057
1057
|
const A = _ > 1 ? u ?? h$1.messages.error : r ?? h$1.messages.cancel;
|
|
1058
1058
|
f = _ === 1, p && (W$1(A, _), f && typeof i == "function" && i());
|
|
1059
1059
|
}, S = () => C(2), b = () => C(1), G = () => {
|
|
@@ -1136,17 +1136,17 @@ ${styleText("gray", g + st.repeat(o + 2) + dt)}
|
|
|
1136
1136
|
output: t.output,
|
|
1137
1137
|
initialValue: t.initialValue,
|
|
1138
1138
|
render() {
|
|
1139
|
-
const s = t.withGuide ?? h$1.withGuide, r = `${P$1(this.state)} `, u = `${ft(this.state)} `, n = B(t.output, t.message, u, r), a = `${s ? `${styleText("gray", $)}
|
|
1139
|
+
const s = t.withGuide ?? h$1.withGuide, r = `${P$1(this.state)} `, u = `${ft(this.state)} `, n = B$1(t.output, t.message, u, r), a = `${s ? `${styleText("gray", $)}
|
|
1140
1140
|
` : ""}${n}
|
|
1141
1141
|
`;
|
|
1142
1142
|
switch (this.state) {
|
|
1143
1143
|
case "submit": {
|
|
1144
1144
|
const c = s ? `${styleText("gray", $)} ` : "";
|
|
1145
|
-
return `${a}${B(t.output, i(this.options[this.cursor], "selected"), c)}`;
|
|
1145
|
+
return `${a}${B$1(t.output, i(this.options[this.cursor], "selected"), c)}`;
|
|
1146
1146
|
}
|
|
1147
1147
|
case "cancel": {
|
|
1148
1148
|
const c = s ? `${styleText("gray", $)} ` : "";
|
|
1149
|
-
return `${a}${B(t.output, i(this.options[this.cursor], "cancelled"), c)}${s ? `
|
|
1149
|
+
return `${a}${B$1(t.output, i(this.options[this.cursor], "cancelled"), c)}${s ? `
|
|
1150
1150
|
${styleText("gray", $)}` : ""}`;
|
|
1151
1151
|
}
|
|
1152
1152
|
default: {
|
|
@@ -1192,7 +1192,7 @@ ${Bt}${r.trimStart()}`), s = 3 + stripVTControlCharacters(r.trimStart()).length)
|
|
|
1192
1192
|
warning: (t) => q.warn(t),
|
|
1193
1193
|
error: (t) => q.message(t, { symbol: styleText("red", yt) })
|
|
1194
1194
|
}, Oe = (t) => t.replace(/\x1b\[(?:\d+;)*\d*[ABCDEFGHfJKSTsu]|\x1b\[(s|u)/g, ""), Pe = (t) => {
|
|
1195
|
-
const i = t.output ?? process.stdout, s = A(i), r = styleText("gray", $), u = t.spacing ?? 1, n = 3, a = t.retainLog === !0, c = !at() && Tt(i);
|
|
1195
|
+
const i = t.output ?? process.stdout, s = A$1(i), r = styleText("gray", $), u = t.spacing ?? 1, n = 3, a = t.retainLog === !0, c = !at() && Tt(i);
|
|
1196
1196
|
i.write(`${r}
|
|
1197
1197
|
`), i.write(`${styleText("green", H)} ${t.title}
|
|
1198
1198
|
`);
|
|
@@ -1348,7 +1348,7 @@ ${i ? styleText("cyan", x$1) : ""}
|
|
|
1348
1348
|
//#endregion
|
|
1349
1349
|
//#region package.json
|
|
1350
1350
|
var name = "sv";
|
|
1351
|
-
var version = "0.16.
|
|
1351
|
+
var version = "0.16.6";
|
|
1352
1352
|
//#endregion
|
|
1353
1353
|
//#region src/core/errors.ts
|
|
1354
1354
|
var UnsupportedError = class extends Error {
|
|
@@ -1885,10 +1885,12 @@ var k = class extends Error {
|
|
|
1885
1885
|
this.output = t;
|
|
1886
1886
|
}
|
|
1887
1887
|
};
|
|
1888
|
+
const A = /\r?\n/;
|
|
1888
1889
|
const j = {
|
|
1889
1890
|
timeout: void 0,
|
|
1890
1891
|
persist: false
|
|
1891
1892
|
};
|
|
1893
|
+
const M = { timeout: void 0 };
|
|
1892
1894
|
const N = { windowsHide: true };
|
|
1893
1895
|
function P(e) {
|
|
1894
1896
|
const t = new AbortController();
|
|
@@ -2036,12 +2038,56 @@ var I = class {
|
|
|
2036
2038
|
if (this._resolveClose) this._resolveClose();
|
|
2037
2039
|
};
|
|
2038
2040
|
};
|
|
2041
|
+
function L(e, r, i) {
|
|
2042
|
+
const a = {
|
|
2043
|
+
...M,
|
|
2044
|
+
...i
|
|
2045
|
+
};
|
|
2046
|
+
const o = cwd();
|
|
2047
|
+
const s = {
|
|
2048
|
+
windowsHide: true,
|
|
2049
|
+
...a.nodeOptions
|
|
2050
|
+
};
|
|
2051
|
+
if (a.timeout !== void 0) s.timeout = a.timeout;
|
|
2052
|
+
s.env = y(o, s.env, a.nodePath);
|
|
2053
|
+
const c = D(e, r ?? [], s);
|
|
2054
|
+
const l = spawnSync(c.command, c.args, c.options);
|
|
2055
|
+
if (l.error) throw l.error;
|
|
2056
|
+
const u = l.stdout?.toString() ?? "";
|
|
2057
|
+
const d = l.stderr?.toString() ?? "";
|
|
2058
|
+
const f = l.status ?? void 0;
|
|
2059
|
+
const p = l.signal != null;
|
|
2060
|
+
const m = {
|
|
2061
|
+
stdout: u,
|
|
2062
|
+
stderr: d,
|
|
2063
|
+
get exitCode() {
|
|
2064
|
+
return f;
|
|
2065
|
+
},
|
|
2066
|
+
get pid() {
|
|
2067
|
+
return l.pid;
|
|
2068
|
+
},
|
|
2069
|
+
get killed() {
|
|
2070
|
+
return p;
|
|
2071
|
+
},
|
|
2072
|
+
*[Symbol.iterator]() {
|
|
2073
|
+
for (const e of [u, d]) {
|
|
2074
|
+
if (!e) continue;
|
|
2075
|
+
const t = e.split(A);
|
|
2076
|
+
if (t[t.length - 1] === "") t.pop();
|
|
2077
|
+
yield* t;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
};
|
|
2081
|
+
if (a.throwOnError && f !== 0 && f !== void 0) throw new k(m, m);
|
|
2082
|
+
return m;
|
|
2083
|
+
}
|
|
2039
2084
|
const R = (e, t, n) => {
|
|
2040
2085
|
const r = new I(e, t, n);
|
|
2041
2086
|
r.spawn();
|
|
2042
2087
|
return r;
|
|
2043
2088
|
};
|
|
2044
2089
|
const z = R;
|
|
2090
|
+
const B = L;
|
|
2045
2091
|
//#endregion
|
|
2046
2092
|
//#region ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
2047
2093
|
/**
|
|
@@ -5637,11 +5683,9 @@ function pipe(...pipe$1) {
|
|
|
5637
5683
|
}
|
|
5638
5684
|
//#endregion
|
|
5639
5685
|
//#region src/core/config.ts
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
function defineAddon(config) {
|
|
5644
|
-
return config;
|
|
5686
|
+
function defineAddon(...args) {
|
|
5687
|
+
if (args.length === 0) return (config) => config;
|
|
5688
|
+
return args[0];
|
|
5645
5689
|
}
|
|
5646
5690
|
/**
|
|
5647
5691
|
* Generates an inline error hint based on the addon source
|
|
@@ -10722,21 +10766,23 @@ async function formatFiles(options) {
|
|
|
10722
10766
|
//#endregion
|
|
10723
10767
|
//#region src/core/package-manager.ts
|
|
10724
10768
|
const AGENT_NAMES = AGENTS.filter((agent) => !agent.includes("@"));
|
|
10725
|
-
const agentOptions = AGENT_NAMES.map((pm) => ({
|
|
10726
|
-
value: pm,
|
|
10727
|
-
label: pm
|
|
10728
|
-
}));
|
|
10729
|
-
agentOptions.unshift({
|
|
10730
|
-
label: "None",
|
|
10731
|
-
value: void 0
|
|
10732
|
-
});
|
|
10733
10769
|
const installOption = new Option("--install <package-manager>", "installs dependencies with a specified package manager").choices(AGENT_NAMES);
|
|
10734
10770
|
async function packageManagerPrompt(cwd) {
|
|
10735
10771
|
const agent = (await detect({ cwd }))?.name ?? getUserAgent();
|
|
10736
10772
|
if (!V.stdout.isTTY) return agent;
|
|
10737
10773
|
const pm = await Ee({
|
|
10738
10774
|
message: "Which package manager do you want to install dependencies with?",
|
|
10739
|
-
options:
|
|
10775
|
+
options: [{
|
|
10776
|
+
label: "None",
|
|
10777
|
+
value: void 0
|
|
10778
|
+
}, ...AGENT_NAMES.map((agent) => {
|
|
10779
|
+
const installed = isInstalled(agent);
|
|
10780
|
+
return {
|
|
10781
|
+
value: agent,
|
|
10782
|
+
label: installed ? agent : color.dim(`${agent} (not installed)`),
|
|
10783
|
+
installed
|
|
10784
|
+
};
|
|
10785
|
+
}).sort((a, b) => Number(b.installed) - Number(a.installed))],
|
|
10740
10786
|
initialValue: agent
|
|
10741
10787
|
});
|
|
10742
10788
|
if (R$2(pm)) {
|
|
@@ -10745,7 +10791,12 @@ async function packageManagerPrompt(cwd) {
|
|
|
10745
10791
|
}
|
|
10746
10792
|
return pm;
|
|
10747
10793
|
}
|
|
10794
|
+
/** Returns `false` when the package manager isn't installed and the install was skipped. */
|
|
10748
10795
|
async function installDependencies(agent, cwd) {
|
|
10796
|
+
if (!isInstalled(agent)) {
|
|
10797
|
+
R$1.warn(`${color.command(agent)} is not installed, skipping dependency installation.`);
|
|
10798
|
+
return false;
|
|
10799
|
+
}
|
|
10749
10800
|
const task = Pe({
|
|
10750
10801
|
title: `Installing dependencies with ${color.command(agent)}...`,
|
|
10751
10802
|
limit: Math.ceil(V.stdout.rows / 2),
|
|
@@ -10769,12 +10820,12 @@ async function installDependencies(agent, cwd) {
|
|
|
10769
10820
|
} catch {}
|
|
10770
10821
|
if ((proc.exitCode ?? 0) === 0) {
|
|
10771
10822
|
task.success(`Successfully installed dependencies with ${color.command(agent)}`);
|
|
10772
|
-
return;
|
|
10823
|
+
return true;
|
|
10773
10824
|
}
|
|
10774
10825
|
if (agent === "pnpm" && output.join("\n").includes("ERR_PNPM_IGNORED_BUILDS")) {
|
|
10775
10826
|
task.success(`Installed dependencies with ${color.command(agent)}`);
|
|
10776
10827
|
R$1.warn(`Some build scripts were skipped. Run ${color.command(`${agent} approve-builds`)} to approve them.`);
|
|
10777
|
-
return;
|
|
10828
|
+
return true;
|
|
10778
10829
|
}
|
|
10779
10830
|
task.error("Failed to install dependencies");
|
|
10780
10831
|
ge("Operation failed.");
|
|
@@ -10791,6 +10842,20 @@ function getUserAgent() {
|
|
|
10791
10842
|
const name = pmSpec.substring(0, separatorPos);
|
|
10792
10843
|
return AGENTS.includes(name) ? name : void 0;
|
|
10793
10844
|
}
|
|
10845
|
+
const installedCache = /* @__PURE__ */ new Map();
|
|
10846
|
+
function isInstalled(agent) {
|
|
10847
|
+
let installed = installedCache.get(agent);
|
|
10848
|
+
if (installed === void 0) {
|
|
10849
|
+
try {
|
|
10850
|
+
B(agent, ["--version"], { nodeOptions: { stdio: "ignore" } });
|
|
10851
|
+
installed = true;
|
|
10852
|
+
} catch {
|
|
10853
|
+
installed = false;
|
|
10854
|
+
}
|
|
10855
|
+
installedCache.set(agent, installed);
|
|
10856
|
+
}
|
|
10857
|
+
return installed;
|
|
10858
|
+
}
|
|
10794
10859
|
function addPnpmAllowBuilds(cwd, packageManager, ...packages) {
|
|
10795
10860
|
if (packageManager !== "pnpm" || packages.length === 0) return;
|
|
10796
10861
|
const found = up$1("pnpm-workspace.yaml", { cwd });
|
|
@@ -11225,7 +11290,7 @@ const create = new Command("create").description("Scaffold a new project (--add
|
|
|
11225
11290
|
V.exit(1);
|
|
11226
11291
|
}
|
|
11227
11292
|
runCommand(async () => {
|
|
11228
|
-
const { directory, addOnNextSteps, packageManager } = await createProject(cwd, options);
|
|
11293
|
+
const { directory, addOnNextSteps, packageManager, depsInstalled } = await createProject(cwd, options);
|
|
11229
11294
|
let i = 1;
|
|
11230
11295
|
const initialSteps = ["📁 Project steps", ""];
|
|
11231
11296
|
const relative = path.relative(V.cwd(), directory);
|
|
@@ -11234,7 +11299,8 @@ const create = new Command("create").description("Scaffold a new project (--add
|
|
|
11234
11299
|
const pathHasSpaces = relative.includes(" ");
|
|
11235
11300
|
initialSteps.push(` ${i++}: ${color.command(`cd ${pathHasSpaces ? `"${relative}"` : relative}`)}`);
|
|
11236
11301
|
}
|
|
11237
|
-
if (!
|
|
11302
|
+
if (packageManager && !depsInstalled) initialSteps.push(` ${i++}: Install ${color.command(pm)}`);
|
|
11303
|
+
if (!packageManager || !depsInstalled) initialSteps.push(` ${i++}: ${color.command(resolveCommandArray(pm, "install", []))}`);
|
|
11238
11304
|
const steps = [
|
|
11239
11305
|
...initialSteps,
|
|
11240
11306
|
` ${i++}: ${color.command(resolveCommandArray(pm, "run", ["dev", "--open"]))}`,
|
|
@@ -11410,18 +11476,20 @@ async function createProject(cwd, options) {
|
|
|
11410
11476
|
updateAgent(directory, language, packageManager ?? "npm", loadedAddons);
|
|
11411
11477
|
const addOnNextSteps = getNextSteps(addOnSuccessfulAddons, workspace, answers, addonSetupResults);
|
|
11412
11478
|
addPnpmAllowBuilds(projectPath, packageManager, "esbuild");
|
|
11479
|
+
let depsInstalled = false;
|
|
11413
11480
|
if (packageManager) {
|
|
11414
|
-
await installDependencies(packageManager, projectPath);
|
|
11415
|
-
await formatFiles({
|
|
11481
|
+
depsInstalled = await installDependencies(packageManager, projectPath);
|
|
11482
|
+
if (depsInstalled) await formatFiles({
|
|
11416
11483
|
packageManager,
|
|
11417
11484
|
cwd: projectPath,
|
|
11418
|
-
filesToFormat: addOnFilesToFormat
|
|
11485
|
+
filesToFormat: addOnSuccessfulAddons.some((addon) => addon.addon.id === "prettier") ? ["."] : addOnFilesToFormat
|
|
11419
11486
|
});
|
|
11420
11487
|
}
|
|
11421
11488
|
return {
|
|
11422
11489
|
directory: projectPath,
|
|
11423
11490
|
addOnNextSteps,
|
|
11424
|
-
packageManager
|
|
11491
|
+
packageManager,
|
|
11492
|
+
depsInstalled
|
|
11425
11493
|
};
|
|
11426
11494
|
}
|
|
11427
11495
|
async function createProjectFromPlayground(url, cwd) {
|
|
@@ -11713,9 +11781,9 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
|
|
|
11713
11781
|
}
|
|
11714
11782
|
for (const loaded of addons) answers[loaded.addon.id] ??= {};
|
|
11715
11783
|
let setupResults = {};
|
|
11716
|
-
if (addons.length > 0) setupResults = setupAddons(addons, workspace);
|
|
11784
|
+
if (addons.length > 0) setupResults = await setupAddons(addons, workspace);
|
|
11717
11785
|
if (addons.length === 0) {
|
|
11718
|
-
const results = setupAddons(officialAddons.map((a) => createLoadedAddon(a)), workspace);
|
|
11786
|
+
const results = await setupAddons(officialAddons.map((a) => createLoadedAddon(a)), workspace);
|
|
11719
11787
|
const addonOptions = officialAddons.filter(({ id, hidden }) => results[id].unsupported.length === 0 && !hidden).map(({ id, homepage, shortDescription }) => ({
|
|
11720
11788
|
label: id,
|
|
11721
11789
|
value: id,
|
|
@@ -11735,11 +11803,11 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
|
|
|
11735
11803
|
addons.push(createLoadedAddon(addon));
|
|
11736
11804
|
answers[id] = {};
|
|
11737
11805
|
}
|
|
11738
|
-
setupResults = setupAddons(addons, workspace);
|
|
11806
|
+
setupResults = await setupAddons(addons, workspace);
|
|
11739
11807
|
}
|
|
11740
11808
|
const missingSetupResults = addons.filter((a) => !setupResults[a.addon.id]);
|
|
11741
11809
|
if (missingSetupResults.length > 0) {
|
|
11742
|
-
const additionalSetupResults = setupAddons(missingSetupResults, workspace);
|
|
11810
|
+
const additionalSetupResults = await setupAddons(missingSetupResults, workspace);
|
|
11743
11811
|
Object.assign(setupResults, additionalSetupResults);
|
|
11744
11812
|
}
|
|
11745
11813
|
const dependencyChains = /* @__PURE__ */ new Map();
|
|
@@ -11779,7 +11847,7 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
|
|
|
11779
11847
|
}
|
|
11780
11848
|
const newlyAddedAddons = addons.filter((a) => !setupResults[a.addon.id]);
|
|
11781
11849
|
if (newlyAddedAddons.length > 0) {
|
|
11782
|
-
const newSetupResults = setupAddons(newlyAddedAddons, workspace);
|
|
11850
|
+
const newSetupResults = await setupAddons(newlyAddedAddons, workspace);
|
|
11783
11851
|
Object.assign(setupResults, newSetupResults);
|
|
11784
11852
|
}
|
|
11785
11853
|
}
|
|
@@ -11851,7 +11919,7 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
|
|
|
11851
11919
|
};
|
|
11852
11920
|
}
|
|
11853
11921
|
async function runAddonsApply({ answers, options, loadedAddons, setupResults, workspace, fromCommand }) {
|
|
11854
|
-
if (!setupResults) setupResults = setupAddons(loadedAddons.length ? loadedAddons : officialAddons.map((a) => createLoadedAddon(a)), workspace);
|
|
11922
|
+
if (!setupResults) setupResults = await setupAddons(loadedAddons.length ? loadedAddons : officialAddons.map((a) => createLoadedAddon(a)), workspace);
|
|
11855
11923
|
if (loadedAddons.length === 0) return {
|
|
11856
11924
|
nextSteps: [],
|
|
11857
11925
|
argsFormattedAddons: [],
|
|
@@ -11910,17 +11978,20 @@ async function runAddonsApply({ answers, options, loadedAddons, setupResults, wo
|
|
|
11910
11978
|
if (!options.gitCheck) argsFormattedAddons.push("--no-git-check");
|
|
11911
11979
|
buildAndLogArgs(packageManager, "add", argsFormattedAddons);
|
|
11912
11980
|
}
|
|
11981
|
+
let depsInstalled = true;
|
|
11913
11982
|
if (packageManager) {
|
|
11914
11983
|
workspace.packageManager = packageManager;
|
|
11915
|
-
await installDependencies(packageManager, options.cwd);
|
|
11916
|
-
await formatFiles({
|
|
11984
|
+
depsInstalled = await installDependencies(packageManager, options.cwd);
|
|
11985
|
+
if (depsInstalled) await formatFiles({
|
|
11917
11986
|
packageManager,
|
|
11918
11987
|
cwd: options.cwd,
|
|
11919
11988
|
filesToFormat
|
|
11920
11989
|
});
|
|
11921
11990
|
}
|
|
11991
|
+
const nextSteps = getNextSteps(successfulAddons, workspace, answers, setupResults);
|
|
11992
|
+
if (packageManager && !depsInstalled) nextSteps.unshift(`Install ${color.command(packageManager)}, then run ${color.command(resolveCommandArray(packageManager, "install", []))}`);
|
|
11922
11993
|
return {
|
|
11923
|
-
nextSteps
|
|
11994
|
+
nextSteps,
|
|
11924
11995
|
argsFormattedAddons,
|
|
11925
11996
|
filesToFormat,
|
|
11926
11997
|
successfulAddons,
|
|
@@ -12133,7 +12204,7 @@ async function add({ addons, cwd, options, packageManager = "npm" }) {
|
|
|
12133
12204
|
loadedAddons,
|
|
12134
12205
|
workspace,
|
|
12135
12206
|
options,
|
|
12136
|
-
setupResults: setupAddons(loadedAddons, workspace)
|
|
12207
|
+
setupResults: await setupAddons(loadedAddons, workspace)
|
|
12137
12208
|
});
|
|
12138
12209
|
}
|
|
12139
12210
|
async function applyAddons({ loadedAddons, workspace, setupResults, options }) {
|
|
@@ -12176,29 +12247,35 @@ async function applyAddons({ loadedAddons, workspace, setupResults, options }) {
|
|
|
12176
12247
|
};
|
|
12177
12248
|
}
|
|
12178
12249
|
/** Setup addons - takes LoadedAddon[] and returns setup results */
|
|
12179
|
-
function setupAddons(loadedAddons, workspace) {
|
|
12250
|
+
async function setupAddons(loadedAddons, workspace) {
|
|
12180
12251
|
const setupResults = {};
|
|
12181
12252
|
for (const loaded of loadedAddons) {
|
|
12182
12253
|
const addon = loaded.addon;
|
|
12254
|
+
const additionalOptions = {};
|
|
12183
12255
|
const setupResult = {
|
|
12184
12256
|
unsupported: [],
|
|
12185
12257
|
dependsOn: [],
|
|
12186
|
-
runsAfter: []
|
|
12258
|
+
runsAfter: [],
|
|
12259
|
+
additionalOptions
|
|
12187
12260
|
};
|
|
12188
12261
|
try {
|
|
12189
|
-
addon.setup?.({
|
|
12262
|
+
await addon.setup?.({
|
|
12190
12263
|
...workspace,
|
|
12191
12264
|
dependsOn: (name) => {
|
|
12192
12265
|
setupResult.dependsOn.push(name);
|
|
12193
12266
|
setupResult.runsAfter.push(name);
|
|
12194
12267
|
},
|
|
12195
12268
|
unsupported: (reason) => setupResult.unsupported.push(reason),
|
|
12196
|
-
runsAfter: (name) => setupResult.runsAfter.push(name)
|
|
12269
|
+
runsAfter: (name) => setupResult.runsAfter.push(name),
|
|
12270
|
+
addOption: (key, question) => {
|
|
12271
|
+
additionalOptions[key] = question;
|
|
12272
|
+
}
|
|
12197
12273
|
});
|
|
12198
12274
|
} catch (err) {
|
|
12199
12275
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12200
12276
|
throw new Error(`Add-on '${addon.id}' failed during setup: ${msg}\n\n${getErrorHint(loaded.reference.source)}`, { cause: err });
|
|
12201
12277
|
}
|
|
12278
|
+
if (Object.keys(additionalOptions).length > 0) Object.assign(addon.options, additionalOptions);
|
|
12202
12279
|
setupResults[addon.id] = setupResult;
|
|
12203
12280
|
}
|
|
12204
12281
|
return setupResults;
|
package/dist/src/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as StringQuestion, C as BooleanQuestion, D as OptionValues, E as OptionDefinition, O as Question, S as BaseQuestion, T as NumberQuestion, _ as SvApi, a as Addon, b as Workspace, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as SetupResult, h as PreparedAddon, i as add, j as officialAddons, k as SelectQuestion, 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 defineAddon, w as MultiSelectQuestion, x as WorkspaceOptions, y as defineAddonOptions } from "../engine-
|
|
1
|
+
import { A as StringQuestion, C as BooleanQuestion, D as OptionValues, E as OptionDefinition, O as Question, S as BaseQuestion, T as NumberQuestion, _ as SvApi, a as Addon, b as Workspace, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as SetupResult, h as PreparedAddon, i as add, j as officialAddons, k as SelectQuestion, 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 defineAddon, w as MultiSelectQuestion, x as WorkspaceOptions, y as defineAddonOptions } from "../engine-BhR6Vrxy.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,4 @@
|
|
|
1
|
-
import { c as defineAddonOptions, m as create$1, o as officialAddons, s as defineAddon, t as add, y as svDeprecated } from "../engine-
|
|
1
|
+
import { c as defineAddonOptions, m as create$1, o as officialAddons, s as defineAddon, t as add, y as svDeprecated } from "../engine-DbEL5s1q.mjs";
|
|
2
2
|
//#region src/index.ts
|
|
3
3
|
function create(cwdOrOptions, legacyOptions) {
|
|
4
4
|
if (typeof cwdOrOptions === "string") {
|
package/dist/src/testing.d.mts
CHANGED
package/dist/src/testing.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as __toESM, b as __commonJSMin, f as R, i as addPnpmAllowBuilds, m as create, p as z, t as add, x as __require } from "../engine-
|
|
1
|
+
import { S as __toESM, b as __commonJSMin, f as R, i as addPnpmAllowBuilds, m as create, p as z, t as add, x as __require } from "../engine-DbEL5s1q.mjs";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import V from "node:process";
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"sv": "^0.16.
|
|
25
|
+
"sv": "^0.16.6"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"sv": "^0.16.
|
|
29
|
-
"@sveltejs/sv-utils": "^0.3.
|
|
28
|
+
"sv": "^0.16.6",
|
|
29
|
+
"@sveltejs/sv-utils": "^0.3.2",
|
|
30
30
|
"@playwright/test": "^1.60.0",
|
|
31
31
|
"@types/node": "^25.9.1",
|
|
32
32
|
"tsdown": "^0.22.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sv",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.6",
|
|
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.3.
|
|
28
|
+
"@sveltejs/sv-utils": "0.3.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@clack/prompts": "1.5.0",
|