sv 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { f as program, l as from, r as detectPackageManager, u as Command } from "./package-manager-DYfxv5nk.mjs";
3
- import { ht as resolveCommand, t as color } from "./utils-CnfD6Z1s.mjs";
4
- import { a as helpConfig, i as forwardExitCode, n as add, o as name, r as create, s as version } from "./add-D8995Wsf.mjs";
2
+ import { f as program, l as from, r as detectPackageManager, u as Command } from "./package-manager-BYzDyeam.mjs";
3
+ import { a as helpConfig, i as forwardExitCode, n as add, o as name, r as create, s as version } from "./engine-BmcQ5Tk6.mjs";
4
+ import { color, resolveCommand } from "@sveltejs/sv-utils";
5
5
  import process from "node:process";
6
6
  import { execSync } from "node:child_process";
7
7
 
8
- //#region lib/cli/check.ts
8
+ //#region src/cli/check.ts
9
9
  const check = new Command("check").description("a CLI for checking your Svelte code").allowUnknownOption(true).allowExcessArguments(true).option("-C, --cwd <path>", "path to working directory", process.cwd()).helpOption(false).action(async (options, check$1) => {
10
10
  const cwd$1 = options.cwd;
11
11
  const args = check$1.args;
@@ -36,7 +36,7 @@ async function runCheck(cwd$1, args) {
36
36
  }
37
37
 
38
38
  //#endregion
39
- //#region lib/cli/migrate.ts
39
+ //#region src/cli/migrate.ts
40
40
  const migrate = new Command("migrate").description("a CLI for migrating Svelte(Kit) codebases").argument("[migration]", "migration to run").option("-C, --cwd <path>", "path to working directory", process.cwd()).action(async (migration, options) => {
41
41
  await runMigrate(options.cwd, [migration]);
42
42
  });
@@ -0,0 +1,359 @@
1
+ import { AgentName } from "@sveltejs/sv-utils";
2
+
3
+ //#region src/addons/index.d.ts
4
+ type OfficialAddons = {
5
+ prettier: Addon<any>;
6
+ eslint: Addon<any>;
7
+ vitest: Addon<any>;
8
+ playwright: Addon<any>;
9
+ tailwindcss: Addon<any>;
10
+ sveltekitAdapter: Addon<any>;
11
+ devtoolsJson: Addon<any>;
12
+ drizzle: Addon<any>;
13
+ betterAuth: Addon<any>;
14
+ mdsvex: Addon<any>;
15
+ paraglide: Addon<any>;
16
+ storybook: Addon<any>;
17
+ mcp: Addon<any>;
18
+ };
19
+ declare const officialAddons: OfficialAddons;
20
+ //#endregion
21
+ //#region src/core/options.d.ts
22
+ type BooleanQuestion = {
23
+ type: "boolean";
24
+ default: boolean;
25
+ };
26
+ type StringQuestion = {
27
+ type: "string";
28
+ default: string;
29
+ validate?: (value: string | undefined) => string | Error | undefined;
30
+ placeholder?: string;
31
+ };
32
+ type NumberQuestion = {
33
+ type: "number";
34
+ default: number;
35
+ validate?: (value: string | undefined) => string | Error | undefined;
36
+ placeholder?: string;
37
+ };
38
+ type SelectQuestion<Value$1> = {
39
+ type: "select";
40
+ default: NoInfer<Value$1>;
41
+ options: Array<{
42
+ value: Value$1;
43
+ label?: string;
44
+ hint?: string;
45
+ }>;
46
+ };
47
+ type MultiSelectQuestion<Value$1> = {
48
+ type: "multiselect";
49
+ default: NoInfer<Value$1[]>;
50
+ options: Array<{
51
+ value: Value$1;
52
+ label?: string;
53
+ hint?: string;
54
+ }>;
55
+ required: boolean;
56
+ };
57
+ type BaseQuestion<Args extends OptionDefinition> = {
58
+ question: string;
59
+ group?: string;
60
+ /**
61
+ * When this condition explicitly returns `false`, the question's value will
62
+ * always be `undefined` and will not fallback to the specified `default` value.
63
+ */
64
+ condition?: (options: OptionValues<Args>) => boolean;
65
+ };
66
+ type Question<Args extends OptionDefinition = OptionDefinition> = BaseQuestion<Args> & (BooleanQuestion | StringQuestion | NumberQuestion | SelectQuestion<any> | MultiSelectQuestion<any>);
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`." };
69
+ //#endregion
70
+ //#region src/core/workspace.d.ts
71
+ type WorkspaceOptions<Args extends OptionDefinition> = OptionValues<Args>;
72
+ type Workspace = {
73
+ cwd: string;
74
+ /**
75
+ * Returns the dependency version declared in the package.json.
76
+ * This may differ from the installed version.
77
+ * Includes both dependencies and devDependencies.
78
+ * Also checks parent package.json files if called in a monorepo.
79
+ * @param pkg the package to check for
80
+ * @returns the dependency version with any leading characters such as ^ or ~ removed
81
+ */
82
+ dependencyVersion: (pkg: string) => string | undefined;
83
+ /** to know if the workspace is using typescript or javascript */
84
+ language: "ts" | "js";
85
+ files: {
86
+ viteConfig: "vite.config.js" | "vite.config.ts";
87
+ svelteConfig: "svelte.config.js" | "svelte.config.ts";
88
+ /** `${kit.routesDirectory}/layout.css` or `src/app.css` */
89
+ stylesheet: `${string}/layout.css` | "src/app.css";
90
+ package: "package.json";
91
+ gitignore: ".gitignore";
92
+ prettierignore: ".prettierignore";
93
+ prettierrc: ".prettierrc";
94
+ eslintConfig: "eslint.config.js";
95
+ vscodeSettings: ".vscode/settings.json";
96
+ vscodeExtensions: ".vscode/extensions.json";
97
+ /** Get the relative path between two files */
98
+ getRelative: ({
99
+ from,
100
+ to
101
+ }: {
102
+ from?: string;
103
+ to: string;
104
+ }) => string;
105
+ };
106
+ /** If we are in a kit project, this object will contain the lib and routes directories */
107
+ kit: {
108
+ libDirectory: string;
109
+ routesDirectory: string;
110
+ } | undefined;
111
+ /** The package manager used to install dependencies */
112
+ packageManager: AgentName;
113
+ };
114
+ type CreateWorkspaceOptions = {
115
+ cwd: string;
116
+ packageManager?: AgentName;
117
+ override?: {
118
+ kit?: Workspace["kit"];
119
+ dependencies: Record<string, string>;
120
+ };
121
+ };
122
+ declare function createWorkspace({
123
+ cwd,
124
+ packageManager,
125
+ override
126
+ }: CreateWorkspaceOptions): Promise<Workspace>;
127
+ //#endregion
128
+ //#region src/core/config.d.ts
129
+ type ConditionDefinition = (Workspace: Workspace) => boolean;
130
+ type PackageDefinition = {
131
+ name: string;
132
+ version: string;
133
+ dev: boolean;
134
+ condition?: ConditionDefinition;
135
+ };
136
+ type Scripts = {
137
+ description: string;
138
+ args: string[];
139
+ stdio: "inherit" | "pipe";
140
+ condition?: ConditionDefinition;
141
+ };
142
+ type SvApi = {
143
+ /** Add a package to the pnpm build dependencies. */
144
+ pnpmBuildDependency: (pkg: string) => void;
145
+ /** Add a package to the dependencies. */
146
+ dependency: (pkg: string, version: string) => void;
147
+ /** Add a package to the dev dependencies. */
148
+ devDependency: (pkg: string, version: string) => void;
149
+ /** Execute a command in the workspace. */
150
+ execute: (args: string[], stdio: "inherit" | "pipe") => Promise<void>;
151
+ /** Edit a file in the workspace. (will create it if it doesn't exist) */
152
+ file: (path: string, edit: (content: string) => string) => void;
153
+ };
154
+ type Addon<Args extends OptionDefinition, Id$1 extends string = string> = {
155
+ id: Id$1;
156
+ alias?: string;
157
+ shortDescription?: string;
158
+ homepage?: string;
159
+ /** If true, this addon won't appear in the interactive prompt but can still be used via CLI */
160
+ hidden?: boolean;
161
+ options: Args;
162
+ /** Setup the addon. Will be called before the addon is run. */
163
+ setup?: (workspace: Workspace & {
164
+ /** On what official addons does this addon depend on? */
165
+ dependsOn: (name: keyof typeof officialAddons) => void;
166
+ /** Why is this addon not supported?
167
+ *
168
+ * @example
169
+ * if (!kit) unsupported('Requires SvelteKit');
170
+ */
171
+ unsupported: (reason: string) => void;
172
+ /** On what official addons does this addon run after? */
173
+ runsAfter: (name: keyof typeof officialAddons) => void;
174
+ }) => MaybePromise<void>;
175
+ /** Run the addon. The actual execution of the addon... Add files, edit files, etc. */
176
+ run: (workspace: Workspace & {
177
+ /** Add-on options */
178
+ options: WorkspaceOptions<Args>;
179
+ /** Api to interact with the workspace. */
180
+ sv: SvApi;
181
+ /** Cancel the addon at any time!
182
+ * @example
183
+ * return cancel('There is a problem with...');
184
+ */
185
+ cancel: (reason: string) => void;
186
+ }) => MaybePromise<void>;
187
+ /** Next steps to display after the addon is run. */
188
+ nextSteps?: (data: Workspace & {
189
+ options: WorkspaceOptions<Args>;
190
+ }) => string[];
191
+ };
192
+ /**
193
+ * The entry point for your addon, It will hold every thing! (options, setup, run, nextSteps, ...)
194
+ */
195
+ declare function defineAddon<const Id$1 extends string, Args extends OptionDefinition>(config: Addon<Args, Id$1>): Addon<Args, Id$1>;
196
+ /**
197
+ * Stage 1: Raw CLI input - what the user typed
198
+ */
199
+ type AddonInput = {
200
+ readonly specifier: string;
201
+ readonly options: string[];
202
+ };
203
+ /**
204
+ * Stage 2: Classified source - knows where addon comes from
205
+ */
206
+ type AddonSource = {
207
+ readonly kind: "official";
208
+ readonly id: string;
209
+ } | {
210
+ readonly kind: "file";
211
+ readonly path: string;
212
+ } | {
213
+ readonly kind: "npm";
214
+ readonly packageName: string;
215
+ readonly npmUrl: string;
216
+ readonly registryUrl: string;
217
+ readonly tag: string;
218
+ };
219
+ type AddonReference = {
220
+ readonly specifier: string;
221
+ readonly options: string[];
222
+ readonly source: AddonSource;
223
+ };
224
+ /**
225
+ * Stage 3: Code loaded - addon definition is always present
226
+ */
227
+ type LoadedAddon = {
228
+ readonly reference: AddonReference;
229
+ readonly addon: AddonDefinition;
230
+ };
231
+ /**
232
+ * Stage 4: Setup done - has dependency info
233
+ */
234
+ type PreparedAddon = LoadedAddon & {
235
+ readonly setupResult: SetupResult;
236
+ };
237
+ /**
238
+ * Stage 5: User configured - has answers to questions
239
+ */
240
+ type ConfiguredAddon = PreparedAddon & {
241
+ readonly answers: OptionValues<any>;
242
+ };
243
+ /**
244
+ * Stage 6: Execution result
245
+ */
246
+ type AddonResult = {
247
+ readonly id: string;
248
+ readonly status: "success" | {
249
+ canceled: string[];
250
+ };
251
+ readonly files: string[];
252
+ };
253
+ /**
254
+ * Generates an inline error hint based on the addon source
255
+ */
256
+ declare function getErrorHint(source: AddonSource): string;
257
+ type SetupResult = {
258
+ dependsOn: string[];
259
+ unsupported: string[];
260
+ runsAfter: string[];
261
+ };
262
+ type AddonDefinition<Id$1 extends string = string> = Addon<Record<string, Question<any>>, Id$1>;
263
+ type Tests = {
264
+ expectProperty: (selector: string, property: string, expectedValue: string) => Promise<void>;
265
+ elementExists: (selector: string) => Promise<void>;
266
+ click: (selector: string, path?: string) => Promise<void>;
267
+ expectUrlPath: (path: string) => void;
268
+ };
269
+ type TestDefinition<Args extends OptionDefinition> = {
270
+ name: string;
271
+ run: (tests: Tests) => Promise<void>;
272
+ condition?: (options: OptionValues<Args>) => boolean;
273
+ };
274
+ type MaybePromise<T> = Promise<T> | T;
275
+ type Verification = {
276
+ name: string;
277
+ run: () => MaybePromise<{
278
+ success: boolean;
279
+ message: string | undefined;
280
+ }>;
281
+ };
282
+ type Prettify<T> = { [K in keyof T]: T[K] } & unknown;
283
+ type OptionBuilder<T extends OptionDefinition> = {
284
+ /**
285
+ * This type is a bit complex, but in usage, it's quite simple!
286
+ *
287
+ * The idea is to `add()` options one by one, with the key and the question.
288
+ *
289
+ * ```ts
290
+ * .add('demo', {
291
+ * question: 'Do you want to add a demo?',
292
+ * type: 'boolean', // string, number, select, multiselect
293
+ * default: true,
294
+ * // condition: (o) => o.previousOption === 'ok',
295
+ * })
296
+ * ```
297
+ */
298
+ add<K$1 extends string, const Q extends Question<T & Record<K$1, Q>>>(key: K$1, question: Q): OptionBuilder<T & Record<K$1, Q>>;
299
+ /** Finalize all options of your `add-on`. */
300
+ build(): Prettify<T>;
301
+ };
302
+ /**
303
+ * Options for an addon.
304
+ *
305
+ * Will be prompted to the user if there are not answered by args when calling the cli.
306
+ *
307
+ * ```ts
308
+ * const options = defineAddonOptions()
309
+ * .add('demo', {
310
+ * question: `demo? ${color.optional('(a cool one!)')}`
311
+ * type: string | boolean | number | select | multiselect,
312
+ * default: true,
313
+ * })
314
+ * .build();
315
+ * ```
316
+ *
317
+ * To define by args, you can do
318
+ * ```sh
319
+ * npx sv add <addon>=<option1>:<value1>+<option2>:<value2>
320
+ * ```
321
+ */
322
+ declare function defineAddonOptions(): OptionBuilder<{}>;
323
+ //#endregion
324
+ //#region src/core/engine.d.ts
325
+ type InstallOptions<Addons extends AddonMap> = {
326
+ cwd: string;
327
+ addons: Addons;
328
+ options: OptionMap<Addons>;
329
+ packageManager?: AgentName;
330
+ };
331
+ type AddonMap = Record<string, Addon<any, any>>;
332
+ type AddonById<Addons extends AddonMap, Id$1 extends string> = Extract<Addons[keyof Addons], {
333
+ id: Id$1;
334
+ }>;
335
+ type OptionMap<Addons extends AddonMap> = { [Id in Addons[keyof Addons]["id"]]: Partial<OptionValues<AddonById<Addons, Id>["options"]>> };
336
+ declare function add<Addons extends AddonMap>({
337
+ addons,
338
+ cwd,
339
+ options,
340
+ packageManager
341
+ }: InstallOptions<Addons>): Promise<ReturnType<typeof applyAddons>>;
342
+ type ApplyAddonOptions = {
343
+ loadedAddons: LoadedAddon[];
344
+ options: OptionMap<AddonMap>;
345
+ workspace: Workspace;
346
+ setupResults: Record<string, SetupResult>;
347
+ };
348
+ declare function applyAddons({
349
+ loadedAddons,
350
+ workspace,
351
+ setupResults,
352
+ options
353
+ }: ApplyAddonOptions): Promise<{
354
+ filesToFormat: string[];
355
+ pnpmBuildDependencies: string[];
356
+ status: Record<string, string[] | "success">;
357
+ }>;
358
+ //#endregion
359
+ export { BooleanQuestion as A, defineAddon as C, WorkspaceOptions as D, Workspace as E, Question as F, SelectQuestion as I, StringQuestion as L, NumberQuestion as M, OptionDefinition as N, createWorkspace as O, OptionValues as P, officialAddons as R, Verification as S, getErrorHint as T, Scripts as _, Addon as a, TestDefinition as b, AddonReference as c, ConditionDefinition as d, ConfiguredAddon as f, PreparedAddon as g, PackageDefinition as h, add as i, MultiSelectQuestion as j, BaseQuestion as k, AddonResult as l, OptionBuilder as m, InstallOptions as n, AddonDefinition as o, LoadedAddon as p, OptionMap as r, AddonInput as s, AddonMap as t, AddonSource as u, SetupResult as v, defineAddonOptions as w, Tests as x, SvApi as y };