sv 1.0.1 → 1.1.0
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/{addons-BvT-iII-.mjs → addons-OcP_HeQ_.mjs} +407 -326
- package/dist/bin.mjs +88 -66
- package/dist/{engine-D2x5kvrf.d.mts → engine-BLZdMrao.d.mts} +44 -26
- package/dist/{engine-LhRAh1ZA.mjs → engine-DB9amJxd.mjs} +18 -20
- package/dist/src/index.d.mts +79 -2
- package/dist/src/index.mjs +2 -2
- package/dist/src/testing.d.mts +1 -1
- package/dist/src/testing.mjs +1 -1
- package/dist/templates/addon/package.json +3 -3
- package/dist/templates/demo/files.types=checkjs.json +2 -2
- package/dist/templates/demo/files.types=none.json +2 -2
- package/dist/templates/demo/files.types=typescript.json +3 -3
- package/dist/templates/demo/package.json +1 -1
- package/dist/templates/library/package.json +1 -1
- package/dist/templates/minimal/files.types=checkjs.json +1 -1
- package/dist/templates/minimal/files.types=typescript.json +1 -1
- package/dist/templates/minimal/package.json +1 -1
- package/dist/templates/svelte/assets/public/favicon.svg +1 -0
- package/dist/templates/svelte/assets/public/icons.svg +24 -0
- package/dist/templates/svelte/assets/src/assets/hero.png +0 -0
- package/dist/templates/svelte/assets/src/assets/vite.svg +1 -0
- package/dist/templates/svelte/files.types=none.json +7 -7
- package/dist/templates/svelte/files.types=typescript.json +9 -9
- package/package.json +3 -3
- package/dist/templates/svelte/assets/public/vite.svg +0 -1
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as getSharedFiles, pt as R, v as defineAddon, y as defineAddonOptions } from "./engine-DB9amJxd.mjs";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { Walker, coerceVersion, color, createPrinter, dedent, defineEnv, fileExists, isKit3, loadPackageJson, pnpm, resolveCommandArray, resolveLibPrefix, sanitizeName, svelteConfig, transforms } from "@sveltejs/sv-utils";
|
|
4
|
+
import { KIT3_TSCONFIG, Walker, coerceVersion, color, createPrinter, dedent, defineDemoPage, defineEnv, fileExists, isKit3, loadPackageJson, pnpm, resolveCommandArray, resolveLibPrefix, sanitizeName, svelteConfig, transforms } from "@sveltejs/sv-utils";
|
|
5
5
|
import V from "node:process";
|
|
6
6
|
import crypto from "node:crypto";
|
|
7
|
+
//#region src/addons/ids.ts
|
|
8
|
+
/**
|
|
9
|
+
* Official add-on ids, declared without importing the add-ons themselves so that
|
|
10
|
+
* add-ons can reference each other in `dependsOn`/`runsAfter` without import cycles.
|
|
11
|
+
*/
|
|
12
|
+
const ADDON_IDS = {
|
|
13
|
+
prettier: "prettier",
|
|
14
|
+
eslint: "eslint",
|
|
15
|
+
vitest: "vitest",
|
|
16
|
+
playwright: "playwright",
|
|
17
|
+
tailwindcss: "tailwindcss",
|
|
18
|
+
enhancedImg: "enhanced-img",
|
|
19
|
+
sveltekitAdapter: "sveltekit-adapter",
|
|
20
|
+
drizzle: "drizzle",
|
|
21
|
+
betterAuth: "better-auth",
|
|
22
|
+
mdsvex: "mdsvex",
|
|
23
|
+
paraglide: "paraglide",
|
|
24
|
+
storybook: "storybook",
|
|
25
|
+
aiTools: "ai-tools",
|
|
26
|
+
experimental: "experimental"
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
7
29
|
//#region src/addons/ai-tools.ts
|
|
8
30
|
const REGEX_MD = /\.md$/;
|
|
9
31
|
const CLIENTS = {
|
|
@@ -96,7 +118,7 @@ const TOOLS = {
|
|
|
96
118
|
hint: "sub-agent"
|
|
97
119
|
}
|
|
98
120
|
};
|
|
99
|
-
const options$
|
|
121
|
+
const options$8 = defineAddonOptions().add("ide", {
|
|
100
122
|
question: "Which client would you like to use?",
|
|
101
123
|
type: "multiselect",
|
|
102
124
|
default: [],
|
|
@@ -145,11 +167,11 @@ const options$7 = defineAddonOptions().add("ide", {
|
|
|
145
167
|
}],
|
|
146
168
|
condition: ({ ide, delivery, tools }) => (tools === void 0 || tools.includes("mcp")) && ide.some((i) => wantsMcpConfig(CLIENTS[i], delivery))
|
|
147
169
|
}).build();
|
|
148
|
-
|
|
149
|
-
id:
|
|
170
|
+
const addon$8 = defineAddon({
|
|
171
|
+
id: ADDON_IDS.aiTools,
|
|
150
172
|
shortDescription: "Svelte AI tools",
|
|
151
173
|
homepage: "https://svelte.dev/docs/ai",
|
|
152
|
-
options: options$
|
|
174
|
+
options: options$8,
|
|
153
175
|
run: ({ sv, options }) => {
|
|
154
176
|
const usePlugin = options.delivery === "plugin";
|
|
155
177
|
const selected = options.tools ?? Object.keys(TOOLS);
|
|
@@ -262,126 +284,6 @@ var ai_tools_default = defineAddon({
|
|
|
262
284
|
}
|
|
263
285
|
});
|
|
264
286
|
//#endregion
|
|
265
|
-
//#region src/addons/common.ts
|
|
266
|
-
const ESLINT_VERSION = "^10.4.1";
|
|
267
|
-
const addEslintConfigPrettier = transforms.script(({ ast, js }) => {
|
|
268
|
-
const sveltePluginImport = ast.body.filter((n) => n.type === "ImportDeclaration").find((n) => n.type === "ImportDeclaration" && n.source.value === "eslint-plugin-svelte" && n.specifiers?.some((n) => n.type === "ImportDefaultSpecifier"));
|
|
269
|
-
let svelteImportName;
|
|
270
|
-
for (const specifier of sveltePluginImport?.specifiers ?? []) if (specifier.type === "ImportDefaultSpecifier" && specifier.local?.name) svelteImportName = specifier.local.name;
|
|
271
|
-
svelteImportName ??= "svelte";
|
|
272
|
-
js.imports.addDefault(ast, {
|
|
273
|
-
from: "eslint-plugin-svelte",
|
|
274
|
-
as: svelteImportName
|
|
275
|
-
});
|
|
276
|
-
js.imports.addDefault(ast, {
|
|
277
|
-
from: "eslint-config-prettier",
|
|
278
|
-
as: "prettier"
|
|
279
|
-
});
|
|
280
|
-
const fallbackConfig = js.common.parseExpression("[]");
|
|
281
|
-
const eslintConfig = js.exports.createDefault(ast, { fallback: fallbackConfig }).value;
|
|
282
|
-
let elements = [];
|
|
283
|
-
if (eslintConfig.type === "ArrayExpression") elements = eslintConfig.elements;
|
|
284
|
-
else if (eslintConfig.type === "CallExpression") {
|
|
285
|
-
if (eslintConfig.arguments.length === 1 && eslintConfig.arguments[0].type === "ArrayExpression") elements = eslintConfig.arguments[0].elements;
|
|
286
|
-
else elements = eslintConfig.arguments;
|
|
287
|
-
} else return false;
|
|
288
|
-
const prettier = js.common.parseExpression("prettier");
|
|
289
|
-
const sveltePrettierConfig = js.common.parseExpression(`${svelteImportName}.configs.prettier`);
|
|
290
|
-
const nodesToInsert = [];
|
|
291
|
-
if (!js.common.contains(eslintConfig, prettier)) nodesToInsert.push(prettier);
|
|
292
|
-
if (!js.common.contains(eslintConfig, sveltePrettierConfig)) nodesToInsert.push(sveltePrettierConfig);
|
|
293
|
-
const isSvelteConfig = (maybeSpread) => {
|
|
294
|
-
const el = maybeSpread?.type === "SpreadElement" ? maybeSpread?.argument : maybeSpread;
|
|
295
|
-
return el?.type === "MemberExpression" && el.object.type === "MemberExpression" && el.object.object.type === "Identifier" && el.object.object.name === svelteImportName && el.object.property.type === "Identifier" && el.object.property.name === "configs";
|
|
296
|
-
};
|
|
297
|
-
const idx = elements.findIndex(isSvelteConfig);
|
|
298
|
-
if (idx !== -1) elements.splice(idx + 1, 0, ...nodesToInsert);
|
|
299
|
-
else elements.push(...nodesToInsert);
|
|
300
|
-
});
|
|
301
|
-
/**
|
|
302
|
-
* Path of the prettier config file we generate. We always emit a `.js` file (with a JSDoc `@type`)
|
|
303
|
-
* rather than `.ts`, since the VSCode prettier extension can't load a `.ts` config without a recent
|
|
304
|
-
* enough Node in its extension host (see prettier/prettier-vscode#3989).
|
|
305
|
-
*/
|
|
306
|
-
function prettierConfigPath() {
|
|
307
|
-
return "prettier.config.js";
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Creates a `prettier.config.js` file with our defaults. Bails (leaving the file untouched)
|
|
311
|
-
* if a config is already defined.
|
|
312
|
-
*/
|
|
313
|
-
const createPrettierConfig = (opts) => transforms.script(({ ast, comments, js }) => {
|
|
314
|
-
if (ast.body.some((node) => node.type === "ExportDefaultDeclaration")) {
|
|
315
|
-
R.warn(`A ${color.warning("prettier")} config already exists. Skipping initialization.`);
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
const plugins = ["prettier-plugin-svelte"];
|
|
319
|
-
if (opts.tailwind) plugins.push("prettier-plugin-tailwindcss");
|
|
320
|
-
const properties = [
|
|
321
|
-
"useTabs: true",
|
|
322
|
-
"singleQuote: true",
|
|
323
|
-
`trailingComma: 'none'`,
|
|
324
|
-
"printWidth: 100",
|
|
325
|
-
`plugins: [${plugins.map((p) => `'${p}'`).join(", ")}]`,
|
|
326
|
-
`overrides: [{ files: '*.svelte', options: { parser: 'svelte' } }]`
|
|
327
|
-
];
|
|
328
|
-
if (opts.tailwind && opts.stylesheet) properties.push(`tailwindStylesheet: '${opts.stylesheet}'`);
|
|
329
|
-
js.common.appendFromString(ast, {
|
|
330
|
-
comments,
|
|
331
|
-
code: `
|
|
332
|
-
/** @type {import("prettier").Config} */
|
|
333
|
-
const config = { ${properties.join(", ")} };
|
|
334
|
-
export default config;
|
|
335
|
-
`
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
/**
|
|
339
|
-
* Augments an existing `prettier.config.js` config object with the tailwindcss plugin and
|
|
340
|
-
* stylesheet. Used when prettier was added before tailwindcss.
|
|
341
|
-
*/
|
|
342
|
-
const addPrettierTailwind = (opts) => transforms.script(({ ast, js }) => {
|
|
343
|
-
if (!ast.body.some((node) => node.type === "ExportDefaultDeclaration")) return false;
|
|
344
|
-
const { value } = js.exports.createDefault(ast, { fallback: js.object.create({}) });
|
|
345
|
-
if (value.type !== "ObjectExpression") return false;
|
|
346
|
-
const plugins = js.object.property(value, {
|
|
347
|
-
name: "plugins",
|
|
348
|
-
fallback: js.array.create()
|
|
349
|
-
});
|
|
350
|
-
if (plugins.type === "ArrayExpression") js.array.append(plugins, "prettier-plugin-tailwindcss");
|
|
351
|
-
if (!value.properties.some((p) => p.type === "Property" && p.key.type === "Identifier" && p.key.name === "tailwindStylesheet")) js.object.property(value, {
|
|
352
|
-
name: "tailwindStylesheet",
|
|
353
|
-
fallback: js.common.createLiteral(opts.stylesheet)
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
const addToDemoPage = (path, language) => transforms.svelteScript({ language }, ({ ast, js, svelte }) => {
|
|
357
|
-
for (const node of ast.fragment.nodes) if (node.type === "RegularElement") {
|
|
358
|
-
const hrefAttribute = node.attributes.find((x) => x.type === "Attribute" && x.name === "href");
|
|
359
|
-
if (!hrefAttribute || !hrefAttribute.value) continue;
|
|
360
|
-
if (!Array.isArray(hrefAttribute.value)) continue;
|
|
361
|
-
if (hrefAttribute.value.some((x) => x.type === "Text" && x.data.includes(`/demo/${path}`))) return false;
|
|
362
|
-
}
|
|
363
|
-
js.imports.addNamed(ast.instance.content, {
|
|
364
|
-
imports: ["resolve"],
|
|
365
|
-
from: "$app/paths"
|
|
366
|
-
});
|
|
367
|
-
svelte.addFragment(ast, `<a href={resolve('/demo/${path}')}>${path}</a>`, { mode: "prepend" });
|
|
368
|
-
});
|
|
369
|
-
/**
|
|
370
|
-
* Returns the corresponding `@types/node` version for the version of Node.js running in the current process.
|
|
371
|
-
*
|
|
372
|
-
* If the installed version of Node.js is from a `Current` release, then the major is decremented to
|
|
373
|
-
* the nearest `LTS` release version.
|
|
374
|
-
*/
|
|
375
|
-
function getNodeTypesVersion() {
|
|
376
|
-
const nodeVersion = V.versions.node;
|
|
377
|
-
const isDenoOrBun = Boolean(V.versions.deno ?? V.versions.bun);
|
|
378
|
-
const [major] = nodeVersion.split(".");
|
|
379
|
-
const majorNum = Number(major);
|
|
380
|
-
const isEvenMajor = majorNum % 2 === 0;
|
|
381
|
-
if (!!V.release.lts || isDenoOrBun && isEvenMajor) return `^${major}`;
|
|
382
|
-
return `^${isEvenMajor ? majorNum - 2 : majorNum - 1}`;
|
|
383
|
-
}
|
|
384
|
-
//#endregion
|
|
385
287
|
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/taggedTemplateLiteral.js
|
|
386
288
|
function _taggedTemplateLiteral(e, t) {
|
|
387
289
|
return t || (t = e.slice(0)), Object.freeze(Object.defineProperties(e, { raw: { value: Object.freeze(t) } }));
|
|
@@ -390,7 +292,7 @@ function _taggedTemplateLiteral(e, t) {
|
|
|
390
292
|
//#region src/addons/better-auth.ts
|
|
391
293
|
var _templateObject$1;
|
|
392
294
|
var _templateObject2;
|
|
393
|
-
const options$
|
|
295
|
+
const options$7 = defineAddonOptions().add("demo", {
|
|
394
296
|
question: "Which demo would you like to include?",
|
|
395
297
|
type: "multiselect",
|
|
396
298
|
default: ["password"],
|
|
@@ -403,17 +305,17 @@ const options$6 = defineAddonOptions().add("demo", {
|
|
|
403
305
|
}],
|
|
404
306
|
required: false
|
|
405
307
|
}).build();
|
|
406
|
-
|
|
407
|
-
id:
|
|
308
|
+
const addon$7 = defineAddon({
|
|
309
|
+
id: ADDON_IDS.betterAuth,
|
|
408
310
|
shortDescription: "auth library",
|
|
409
311
|
homepage: "https://www.better-auth.com",
|
|
410
|
-
options: options$
|
|
312
|
+
options: options$7,
|
|
411
313
|
setup: ({ isKit, dependencyVersion, unsupported, dependsOn, runsAfter }) => {
|
|
412
314
|
if (!isKit) unsupported("Requires SvelteKit");
|
|
413
|
-
if (!dependencyVersion("drizzle-orm")) dependsOn(
|
|
414
|
-
runsAfter(
|
|
415
|
-
runsAfter(
|
|
416
|
-
runsAfter(
|
|
315
|
+
if (!dependencyVersion("drizzle-orm")) dependsOn(ADDON_IDS.drizzle);
|
|
316
|
+
runsAfter(ADDON_IDS.sveltekitAdapter);
|
|
317
|
+
runsAfter(ADDON_IDS.tailwindcss);
|
|
318
|
+
runsAfter(ADDON_IDS.experimental);
|
|
417
319
|
},
|
|
418
320
|
run: ({ sv, cwd, language, options, directory, dependencyVersion, file }) => {
|
|
419
321
|
const lib = resolveLibPrefix(dependencyVersion("@sveltejs/kit"));
|
|
@@ -614,10 +516,12 @@ var better_auth_default = defineAddon({
|
|
|
614
516
|
});
|
|
615
517
|
}));
|
|
616
518
|
if (hasDemo) {
|
|
617
|
-
|
|
618
|
-
sv.file(
|
|
519
|
+
const demo = defineDemoPage("better-auth", language, directory.kitRoutes);
|
|
520
|
+
sv.file(...demo.links);
|
|
521
|
+
sv.file(...demo.layout);
|
|
522
|
+
sv.file(`${demo.addonPath}/login/+page.server.${language}`, (content) => {
|
|
619
523
|
if (content) {
|
|
620
|
-
const filePath = `${
|
|
524
|
+
const filePath = `${demo.addonPath}/login/+page.server.${language}`;
|
|
621
525
|
R.warn(`Existing ${color.warning(filePath)} file. Could not update.`);
|
|
622
526
|
return false;
|
|
623
527
|
}
|
|
@@ -706,9 +610,9 @@ var better_auth_default = defineAddon({
|
|
|
706
610
|
};
|
|
707
611
|
`;
|
|
708
612
|
});
|
|
709
|
-
sv.file(`${
|
|
613
|
+
sv.file(`${demo.addonPath}/login/+page.svelte`, (content) => {
|
|
710
614
|
if (content) {
|
|
711
|
-
const filePath = `${
|
|
615
|
+
const filePath = `${demo.addonPath}/login/+page.svelte`;
|
|
712
616
|
R.warn(`Existing ${color.warning(filePath)} file. Could not update.`);
|
|
713
617
|
return false;
|
|
714
618
|
}
|
|
@@ -750,9 +654,9 @@ var better_auth_default = defineAddon({
|
|
|
750
654
|
"\n "
|
|
751
655
|
])), ts("lang='ts'"), ts("import type { ActionData } from './$types';\n"), s5(`let { form }${ts(": { form: ActionData }")} = $props();`, `export let form${ts(": ActionData")};`), passwordForm, separator, githubForm);
|
|
752
656
|
});
|
|
753
|
-
sv.file(`${
|
|
657
|
+
sv.file(`${demo.addonPath}/+page.server.${language}`, (content) => {
|
|
754
658
|
if (content) {
|
|
755
|
-
const filePath = `${
|
|
659
|
+
const filePath = `${demo.addonPath}/+page.server.${language}`;
|
|
756
660
|
R.warn(`Existing ${color.warning(filePath)} file. Could not update.`);
|
|
757
661
|
return false;
|
|
758
662
|
}
|
|
@@ -780,9 +684,9 @@ var better_auth_default = defineAddon({
|
|
|
780
684
|
};
|
|
781
685
|
`;
|
|
782
686
|
});
|
|
783
|
-
sv.file(`${
|
|
687
|
+
sv.file(`${demo.addonPath}/+page.svelte`, (content) => {
|
|
784
688
|
if (content) {
|
|
785
|
-
const filePath = `${
|
|
689
|
+
const filePath = `${demo.addonPath}/+page.svelte`;
|
|
786
690
|
R.warn(`Existing ${color.warning(filePath)} file. Could not update.`);
|
|
787
691
|
return false;
|
|
788
692
|
}
|
|
@@ -832,6 +736,137 @@ const generateEnv$1 = (demoGithub, isExample) => transforms.text(({ content, tex
|
|
|
832
736
|
return content;
|
|
833
737
|
});
|
|
834
738
|
//#endregion
|
|
739
|
+
//#region src/addons/common.ts
|
|
740
|
+
const ESLINT_VERSION = "^10.4.1";
|
|
741
|
+
const addEslintConfigPrettier = transforms.script(({ ast, js }) => {
|
|
742
|
+
const sveltePluginImport = ast.body.filter((n) => n.type === "ImportDeclaration").find((n) => n.type === "ImportDeclaration" && n.source.value === "eslint-plugin-svelte" && n.specifiers?.some((n) => n.type === "ImportDefaultSpecifier"));
|
|
743
|
+
let svelteImportName;
|
|
744
|
+
for (const specifier of sveltePluginImport?.specifiers ?? []) if (specifier.type === "ImportDefaultSpecifier" && specifier.local?.name) svelteImportName = specifier.local.name;
|
|
745
|
+
svelteImportName ??= "svelte";
|
|
746
|
+
js.imports.addDefault(ast, {
|
|
747
|
+
from: "eslint-plugin-svelte",
|
|
748
|
+
as: svelteImportName
|
|
749
|
+
});
|
|
750
|
+
js.imports.addDefault(ast, {
|
|
751
|
+
from: "eslint-config-prettier",
|
|
752
|
+
as: "prettier"
|
|
753
|
+
});
|
|
754
|
+
const fallbackConfig = js.common.parseExpression("[]");
|
|
755
|
+
const eslintConfig = js.exports.createDefault(ast, { fallback: fallbackConfig }).value;
|
|
756
|
+
let elements = [];
|
|
757
|
+
if (eslintConfig.type === "ArrayExpression") elements = eslintConfig.elements;
|
|
758
|
+
else if (eslintConfig.type === "CallExpression") {
|
|
759
|
+
if (eslintConfig.arguments.length === 1 && eslintConfig.arguments[0].type === "ArrayExpression") elements = eslintConfig.arguments[0].elements;
|
|
760
|
+
else elements = eslintConfig.arguments;
|
|
761
|
+
} else return false;
|
|
762
|
+
const prettier = js.common.parseExpression("prettier");
|
|
763
|
+
const sveltePrettierConfig = js.common.parseExpression(`${svelteImportName}.configs.prettier`);
|
|
764
|
+
const nodesToInsert = [];
|
|
765
|
+
if (!js.common.contains(eslintConfig, prettier)) nodesToInsert.push(prettier);
|
|
766
|
+
if (!js.common.contains(eslintConfig, sveltePrettierConfig)) nodesToInsert.push(sveltePrettierConfig);
|
|
767
|
+
const isSvelteConfig = (maybeSpread) => {
|
|
768
|
+
const el = maybeSpread?.type === "SpreadElement" ? maybeSpread?.argument : maybeSpread;
|
|
769
|
+
return el?.type === "MemberExpression" && el.object.type === "MemberExpression" && el.object.object.type === "Identifier" && el.object.object.name === svelteImportName && el.object.property.type === "Identifier" && el.object.property.name === "configs";
|
|
770
|
+
};
|
|
771
|
+
const idx = elements.findIndex(isSvelteConfig);
|
|
772
|
+
if (idx !== -1) elements.splice(idx + 1, 0, ...nodesToInsert);
|
|
773
|
+
else elements.push(...nodesToInsert);
|
|
774
|
+
});
|
|
775
|
+
/**
|
|
776
|
+
* Path of the prettier config file we generate. We always emit a `.js` file (with a JSDoc `@type`)
|
|
777
|
+
* rather than `.ts`, since the VSCode prettier extension can't load a `.ts` config without a recent
|
|
778
|
+
* enough Node in its extension host (see prettier/prettier-vscode#3989).
|
|
779
|
+
*/
|
|
780
|
+
function prettierConfigPath() {
|
|
781
|
+
return "prettier.config.js";
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Creates a `prettier.config.js` file with our defaults. Bails (leaving the file untouched)
|
|
785
|
+
* if a config is already defined.
|
|
786
|
+
*/
|
|
787
|
+
const createPrettierConfig = (opts) => transforms.script(({ ast, comments, js }) => {
|
|
788
|
+
if (ast.body.some((node) => node.type === "ExportDefaultDeclaration")) {
|
|
789
|
+
R.warn(`A ${color.warning("prettier")} config already exists. Skipping initialization.`);
|
|
790
|
+
return false;
|
|
791
|
+
}
|
|
792
|
+
const plugins = ["prettier-plugin-svelte"];
|
|
793
|
+
if (opts.tailwind) plugins.push("prettier-plugin-tailwindcss");
|
|
794
|
+
const properties = [
|
|
795
|
+
"useTabs: true",
|
|
796
|
+
"singleQuote: true",
|
|
797
|
+
`trailingComma: 'none'`,
|
|
798
|
+
"printWidth: 100",
|
|
799
|
+
`plugins: [${plugins.map((p) => `'${p}'`).join(", ")}]`,
|
|
800
|
+
`overrides: [{ files: '*.svelte', options: { parser: 'svelte' } }]`
|
|
801
|
+
];
|
|
802
|
+
if (opts.tailwind && opts.stylesheet) properties.push(`tailwindStylesheet: '${opts.stylesheet}'`);
|
|
803
|
+
js.common.appendFromString(ast, {
|
|
804
|
+
comments,
|
|
805
|
+
code: `
|
|
806
|
+
/** @type {import("prettier").Config} */
|
|
807
|
+
const config = { ${properties.join(", ")} };
|
|
808
|
+
export default config;
|
|
809
|
+
`
|
|
810
|
+
});
|
|
811
|
+
});
|
|
812
|
+
/**
|
|
813
|
+
* Augments an existing `prettier.config.js` config object with the tailwindcss plugin and
|
|
814
|
+
* stylesheet. Used when prettier was added before tailwindcss.
|
|
815
|
+
*/
|
|
816
|
+
const addPrettierTailwind = (opts) => transforms.script(({ ast, js }) => {
|
|
817
|
+
if (!ast.body.some((node) => node.type === "ExportDefaultDeclaration")) return false;
|
|
818
|
+
const { value } = js.exports.createDefault(ast, { fallback: js.object.create({}) });
|
|
819
|
+
if (value.type !== "ObjectExpression") return false;
|
|
820
|
+
const plugins = js.object.property(value, {
|
|
821
|
+
name: "plugins",
|
|
822
|
+
fallback: js.array.create()
|
|
823
|
+
});
|
|
824
|
+
if (plugins.type === "ArrayExpression") js.array.append(plugins, "prettier-plugin-tailwindcss");
|
|
825
|
+
if (!value.properties.some((p) => p.type === "Property" && p.key.type === "Identifier" && p.key.name === "tailwindStylesheet")) js.object.property(value, {
|
|
826
|
+
name: "tailwindStylesheet",
|
|
827
|
+
fallback: js.common.createLiteral(opts.stylesheet)
|
|
828
|
+
});
|
|
829
|
+
});
|
|
830
|
+
/**
|
|
831
|
+
* Returns the corresponding `@types/node` version for the version of Node.js running in the current process.
|
|
832
|
+
*
|
|
833
|
+
* If the installed version of Node.js is from a `Current` release, then the major is decremented to
|
|
834
|
+
* the nearest `LTS` release version.
|
|
835
|
+
*/
|
|
836
|
+
function getNodeTypesVersion() {
|
|
837
|
+
const nodeVersion = V.versions.node;
|
|
838
|
+
const isDenoOrBun = Boolean(V.versions.deno ?? V.versions.bun);
|
|
839
|
+
const [major] = nodeVersion.split(".");
|
|
840
|
+
const majorNum = Number(major);
|
|
841
|
+
const isEvenMajor = majorNum % 2 === 0;
|
|
842
|
+
if (!!V.release.lts || isDenoOrBun && isEvenMajor) return `^${major}`;
|
|
843
|
+
return `^${isEvenMajor ? majorNum - 2 : majorNum - 1}`;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Kit 3 no longer generates an `include`, so root files outside `src` (like tool configs) must be
|
|
847
|
+
* listed in the project's own ts/jsconfig to be type-checked. No-op before Kit 3.
|
|
848
|
+
*/
|
|
849
|
+
function addToTypeConfigInclude(opts) {
|
|
850
|
+
if (!isKit3(opts.kitVersion)) return;
|
|
851
|
+
const configFile = opts.language === "ts" ? "tsconfig.json" : "jsconfig.json";
|
|
852
|
+
if (!fileExists(opts.cwd, configFile)) return;
|
|
853
|
+
opts.sv.file(configFile, transforms.json(({ data }) => {
|
|
854
|
+
const include = data.include ??= ["src"];
|
|
855
|
+
if (!include.includes(opts.entry)) include.push(opts.entry);
|
|
856
|
+
}));
|
|
857
|
+
}
|
|
858
|
+
function addToTypeConfigType(opts) {
|
|
859
|
+
const configFile = opts.language === "ts" ? "tsconfig.json" : "jsconfig.json";
|
|
860
|
+
if (!fileExists(opts.cwd, configFile)) return;
|
|
861
|
+
opts.sv.file(configFile, transforms.json(({ data }) => {
|
|
862
|
+
data.compilerOptions ??= {};
|
|
863
|
+
data.compilerOptions.types ??= [];
|
|
864
|
+
const types = data.compilerOptions.types;
|
|
865
|
+
if (!types.includes(opts.entry)) types.push(opts.entry);
|
|
866
|
+
if ([data.extends].flat().includes(KIT3_TSCONFIG) && !types.includes("$app/types")) types.unshift("$app/types");
|
|
867
|
+
}));
|
|
868
|
+
}
|
|
869
|
+
//#endregion
|
|
835
870
|
//#region src/addons/drizzle.ts
|
|
836
871
|
const PORTS = {
|
|
837
872
|
mysql: "3306",
|
|
@@ -839,7 +874,7 @@ const PORTS = {
|
|
|
839
874
|
sqlite: "",
|
|
840
875
|
d1: ""
|
|
841
876
|
};
|
|
842
|
-
const options$
|
|
877
|
+
const options$6 = defineAddonOptions().add("database", {
|
|
843
878
|
question: "Which database would you like to use?",
|
|
844
879
|
type: "select",
|
|
845
880
|
default: "sqlite",
|
|
@@ -923,15 +958,15 @@ const options$5 = defineAddonOptions().add("database", {
|
|
|
923
958
|
type: "boolean",
|
|
924
959
|
condition: ({ database, mysql, postgresql }) => database === "mysql" && mysql === "mysql2" || database === "postgresql" && postgresql === "postgres.js"
|
|
925
960
|
}).build();
|
|
926
|
-
|
|
927
|
-
id:
|
|
961
|
+
const addon$6 = defineAddon({
|
|
962
|
+
id: ADDON_IDS.drizzle,
|
|
928
963
|
shortDescription: "database orm",
|
|
929
964
|
homepage: "https://orm.drizzle.team",
|
|
930
|
-
options: options$
|
|
965
|
+
options: options$6,
|
|
931
966
|
setup: ({ isKit, unsupported, runsAfter }) => {
|
|
932
|
-
runsAfter(
|
|
933
|
-
runsAfter(
|
|
934
|
-
runsAfter(
|
|
967
|
+
runsAfter(ADDON_IDS.prettier);
|
|
968
|
+
runsAfter(ADDON_IDS.sveltekitAdapter);
|
|
969
|
+
runsAfter(ADDON_IDS.experimental);
|
|
935
970
|
if (!isKit) return unsupported("Requires SvelteKit");
|
|
936
971
|
},
|
|
937
972
|
run: ({ sv, language, options, directory, dependencyVersion, cwd, cancel, file, packageManager }) => {
|
|
@@ -946,6 +981,12 @@ var drizzle_default = defineAddon({
|
|
|
946
981
|
sv.devDependency("drizzle-orm", "^0.45.2");
|
|
947
982
|
sv.devDependency("drizzle-kit", "^0.31.10");
|
|
948
983
|
sv.devDependency("@types/node", getNodeTypesVersion());
|
|
984
|
+
addToTypeConfigType({
|
|
985
|
+
sv,
|
|
986
|
+
cwd,
|
|
987
|
+
language,
|
|
988
|
+
entry: "node"
|
|
989
|
+
});
|
|
949
990
|
if (options.mysql === "mysql2") sv.devDependency("mysql2", "^3.22.4");
|
|
950
991
|
if (options.mysql === "planetscale") sv.devDependency("@planetscale/database", "^1.20.1");
|
|
951
992
|
if (options.postgresql === "neon") sv.devDependency("@neondatabase/serverless", "^1.1.0");
|
|
@@ -1054,13 +1095,15 @@ var drizzle_default = defineAddon({
|
|
|
1054
1095
|
})
|
|
1055
1096
|
`) });
|
|
1056
1097
|
}));
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1098
|
+
const kitVersion = dependencyVersion("@sveltejs/kit");
|
|
1099
|
+
if (isKit3(kitVersion)) addToTypeConfigInclude({
|
|
1100
|
+
sv,
|
|
1101
|
+
cwd,
|
|
1102
|
+
language,
|
|
1103
|
+
kitVersion,
|
|
1104
|
+
entry: `drizzle.config.${language}`
|
|
1105
|
+
});
|
|
1106
|
+
else svelteConfig.edit({
|
|
1064
1107
|
sv,
|
|
1065
1108
|
cwd
|
|
1066
1109
|
}, ({ override, js }) => {
|
|
@@ -1344,7 +1387,7 @@ function escapeRegex(value) {
|
|
|
1344
1387
|
return value.replace(REGEX_REGEX_CHARS, "\\$&");
|
|
1345
1388
|
}
|
|
1346
1389
|
var enhanced_img_default = defineAddon({
|
|
1347
|
-
id:
|
|
1390
|
+
id: ADDON_IDS.enhancedImg,
|
|
1348
1391
|
shortDescription: "image optimization",
|
|
1349
1392
|
homepage: "https://svelte.dev/docs/kit/images",
|
|
1350
1393
|
options: {},
|
|
@@ -1385,7 +1428,7 @@ var enhanced_img_default = defineAddon({
|
|
|
1385
1428
|
//#endregion
|
|
1386
1429
|
//#region src/addons/eslint.ts
|
|
1387
1430
|
var eslint_default = defineAddon({
|
|
1388
|
-
id:
|
|
1431
|
+
id: ADDON_IDS.eslint,
|
|
1389
1432
|
shortDescription: "linter",
|
|
1390
1433
|
homepage: "https://eslint.org",
|
|
1391
1434
|
options: {},
|
|
@@ -1399,6 +1442,12 @@ var eslint_default = defineAddon({
|
|
|
1399
1442
|
sv.devDependency("globals", "^17.6.0");
|
|
1400
1443
|
sv.devDependency("@eslint/js", "^10.0.1");
|
|
1401
1444
|
sv.devDependency("@types/node", getNodeTypesVersion());
|
|
1445
|
+
addToTypeConfigType({
|
|
1446
|
+
sv,
|
|
1447
|
+
cwd,
|
|
1448
|
+
language,
|
|
1449
|
+
entry: "node"
|
|
1450
|
+
});
|
|
1402
1451
|
if (typescript) sv.devDependency("typescript-eslint", "^8.60.1");
|
|
1403
1452
|
if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^10.1.8");
|
|
1404
1453
|
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
@@ -1539,7 +1588,7 @@ const FEATURES = {
|
|
|
1539
1588
|
off: true
|
|
1540
1589
|
}
|
|
1541
1590
|
};
|
|
1542
|
-
const options$
|
|
1591
|
+
const options$5 = defineAddonOptions().add("features", {
|
|
1543
1592
|
question: "Which experimental features do you want to enable?",
|
|
1544
1593
|
type: "multiselect",
|
|
1545
1594
|
default: Object.entries(FEATURES).filter(([, f]) => !f.off).map(([value]) => value),
|
|
@@ -1550,11 +1599,11 @@ const options$4 = defineAddonOptions().add("features", {
|
|
|
1550
1599
|
})),
|
|
1551
1600
|
required: false
|
|
1552
1601
|
}).build();
|
|
1553
|
-
|
|
1554
|
-
id:
|
|
1602
|
+
const addon$5 = defineAddon({
|
|
1603
|
+
id: ADDON_IDS.experimental,
|
|
1555
1604
|
shortDescription: "svelte & kit experimental features",
|
|
1556
1605
|
homepage: "https://svelte.dev/docs/kit/configuration#experimental",
|
|
1557
|
-
options: options$
|
|
1606
|
+
options: options$5,
|
|
1558
1607
|
run: ({ sv, cwd, options }) => {
|
|
1559
1608
|
const config = {};
|
|
1560
1609
|
for (const [name, f] of Object.entries(FEATURES)) {
|
|
@@ -1573,7 +1622,7 @@ var experimental_default = defineAddon({
|
|
|
1573
1622
|
//#endregion
|
|
1574
1623
|
//#region src/addons/mdsvex.ts
|
|
1575
1624
|
var mdsvex_default = defineAddon({
|
|
1576
|
-
id:
|
|
1625
|
+
id: ADDON_IDS.mdsvex,
|
|
1577
1626
|
shortDescription: "svelte + markdown",
|
|
1578
1627
|
homepage: "https://mdsvex.pngwn.io",
|
|
1579
1628
|
options: {},
|
|
@@ -1614,7 +1663,7 @@ const DEFAULT_INLANG_PROJECT = {
|
|
|
1614
1663
|
modules: ["https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js", "https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"],
|
|
1615
1664
|
"plugin.inlang.messageFormat": { pathPattern: "./messages/{locale}.json" }
|
|
1616
1665
|
};
|
|
1617
|
-
const options$
|
|
1666
|
+
const options$4 = defineAddonOptions().add("languageTags", {
|
|
1618
1667
|
question: `Which languages would you like to support? ${color.optional("(e.g. en,de-ch)")}`,
|
|
1619
1668
|
type: "string",
|
|
1620
1669
|
default: "en, es",
|
|
@@ -1635,14 +1684,14 @@ const options$3 = defineAddonOptions().add("languageTags", {
|
|
|
1635
1684
|
default: true,
|
|
1636
1685
|
question: "Do you want to include a demo?"
|
|
1637
1686
|
}).build();
|
|
1638
|
-
|
|
1639
|
-
id:
|
|
1687
|
+
const addon$4 = defineAddon({
|
|
1688
|
+
id: ADDON_IDS.paraglide,
|
|
1640
1689
|
shortDescription: "i18n",
|
|
1641
1690
|
homepage: "https://inlang.com/m/gerre34r/library-inlang-paraglideJs",
|
|
1642
|
-
options: options$
|
|
1691
|
+
options: options$4,
|
|
1643
1692
|
setup: ({ isKit, unsupported, runsAfter }) => {
|
|
1644
1693
|
if (!isKit) unsupported("Requires SvelteKit");
|
|
1645
|
-
runsAfter(
|
|
1694
|
+
runsAfter(ADDON_IDS.experimental);
|
|
1646
1695
|
},
|
|
1647
1696
|
run: ({ sv, options, file, language, directory, dependencyVersion }) => {
|
|
1648
1697
|
const [ts] = createPrinter(language === "ts");
|
|
@@ -1721,10 +1770,10 @@ var paraglide_default = defineAddon({
|
|
|
1721
1770
|
content = text.upsert(content, "project.inlang/cache/");
|
|
1722
1771
|
return content;
|
|
1723
1772
|
}));
|
|
1773
|
+
const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
|
|
1724
1774
|
sv.file("project.inlang/settings.json", transforms.json(({ data }) => {
|
|
1725
1775
|
if (Object.keys(data).length > 0) return false;
|
|
1726
1776
|
for (const key in DEFAULT_INLANG_PROJECT) data[key] = DEFAULT_INLANG_PROJECT[key];
|
|
1727
|
-
const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
|
|
1728
1777
|
data.baseLocale = validLanguageTags[0];
|
|
1729
1778
|
data.locales = validLanguageTags;
|
|
1730
1779
|
}));
|
|
@@ -1754,8 +1803,10 @@ var paraglide_default = defineAddon({
|
|
|
1754
1803
|
</div>`, { language });
|
|
1755
1804
|
}));
|
|
1756
1805
|
if (options.demo) {
|
|
1757
|
-
|
|
1758
|
-
sv.file(
|
|
1806
|
+
const demo = defineDemoPage("paraglide", language, directory.kitRoutes);
|
|
1807
|
+
sv.file(...demo.links);
|
|
1808
|
+
sv.file(...demo.layout);
|
|
1809
|
+
sv.file(`${demo.addonPath}/+page.svelte`, transforms.svelteScript({ language }, ({ ast, svelte, js }) => {
|
|
1759
1810
|
js.imports.addNamed(ast.instance.content, {
|
|
1760
1811
|
imports: { m: "m" },
|
|
1761
1812
|
from: `${lib}/paraglide/messages.js`
|
|
@@ -1765,24 +1816,24 @@ var paraglide_default = defineAddon({
|
|
|
1765
1816
|
from: `${lib}/paraglide/runtime.js`
|
|
1766
1817
|
});
|
|
1767
1818
|
let templateCode = "<h1>{m.hello_world({ name: 'SvelteKit User' })}</h1>";
|
|
1768
|
-
const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
|
|
1769
1819
|
const links = validLanguageTags.map((x) => `<button onclick={() => setLocale('${x}')}>${x}</button>`).join("");
|
|
1770
1820
|
templateCode += `<div>${links}</div>`;
|
|
1771
1821
|
templateCode += "<p>If you use VSCode, install the <a href=\"https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension\" target=\"_blank\">Sherlock i18n extension</a> for a better i18n experience.</p>";
|
|
1772
1822
|
svelte.addFragment(ast, templateCode);
|
|
1773
1823
|
}));
|
|
1774
1824
|
}
|
|
1775
|
-
const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
|
|
1776
1825
|
for (const languageTag of validLanguageTags) sv.file(`messages/${languageTag}.json`, transforms.json(({ data }) => {
|
|
1777
1826
|
data["$schema"] = "https://inlang.com/schema/inlang-message-format";
|
|
1778
1827
|
data.hello_world = `Hello, {name} from ${languageTag}!`;
|
|
1779
1828
|
}));
|
|
1780
1829
|
},
|
|
1781
|
-
nextSteps: (
|
|
1830
|
+
nextSteps: ({ options }) => {
|
|
1831
|
+
return [`Edit your messages in ${color.path(DEFAULT_INLANG_PROJECT["plugin.inlang.messageFormat"].pathPattern)}`, options.demo && `Visit ${color.route("/demo/paraglide")} route to view the demo`].filter((line) => Boolean(line));
|
|
1832
|
+
}
|
|
1782
1833
|
});
|
|
1783
1834
|
const isValidLanguageTag = (languageTag) => RegExp("^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?))(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*))$").test(languageTag);
|
|
1784
1835
|
function parseLanguageTagInput(input) {
|
|
1785
|
-
const probablyLanguageTags = input.replace(/[
|
|
1836
|
+
const probablyLanguageTags = new Set(input.replace(/[,\s:]/g, " ").split(" ").filter(Boolean).map((tag) => tag.toLowerCase()));
|
|
1786
1837
|
const validLanguageTags = [];
|
|
1787
1838
|
const invalidLanguageTags = [];
|
|
1788
1839
|
for (const tag of probablyLanguageTags) if (isValidLanguageTag(tag)) validLanguageTags.push(tag);
|
|
@@ -1794,12 +1845,17 @@ function parseLanguageTagInput(input) {
|
|
|
1794
1845
|
}
|
|
1795
1846
|
//#endregion
|
|
1796
1847
|
//#region src/addons/playwright.ts
|
|
1797
|
-
|
|
1798
|
-
|
|
1848
|
+
const options$3 = defineAddonOptions().add("demo", {
|
|
1849
|
+
type: "boolean",
|
|
1850
|
+
default: true,
|
|
1851
|
+
question: "Do you want to include a demo?"
|
|
1852
|
+
}).build();
|
|
1853
|
+
const addon$3 = defineAddon({
|
|
1854
|
+
id: ADDON_IDS.playwright,
|
|
1799
1855
|
shortDescription: "browser testing",
|
|
1800
1856
|
homepage: "https://playwright.dev",
|
|
1801
|
-
options:
|
|
1802
|
-
run: ({ sv, language, file, isKit, directory }) => {
|
|
1857
|
+
options: options$3,
|
|
1858
|
+
run: ({ sv, options, language, file, isKit, directory, cwd, dependencyVersion }) => {
|
|
1803
1859
|
sv.devDependency("@playwright/test", "^1.60.0");
|
|
1804
1860
|
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
1805
1861
|
json.packageScriptsUpsert(data, "test:e2e", "playwright test");
|
|
@@ -1810,10 +1866,13 @@ var playwright_default = defineAddon({
|
|
|
1810
1866
|
if (!content) return false;
|
|
1811
1867
|
return text.upsert(content, "test-results", { comment: "Playwright" });
|
|
1812
1868
|
}));
|
|
1813
|
-
const
|
|
1814
|
-
const
|
|
1815
|
-
|
|
1816
|
-
|
|
1869
|
+
const withDemo = isKit && options.demo;
|
|
1870
|
+
const demo = defineDemoPage("playwright", language, directory.kitRoutes);
|
|
1871
|
+
const testDir = withDemo ? demo.addonPath : isKit ? directory.kitRoutes : directory.src;
|
|
1872
|
+
const testRoute = withDemo ? "/demo/playwright" : "/";
|
|
1873
|
+
if (withDemo) {
|
|
1874
|
+
sv.file(...demo.links);
|
|
1875
|
+
sv.file(...demo.layout);
|
|
1817
1876
|
sv.file(`${testDir}/+page.svelte`, transforms.text(({ content }) => {
|
|
1818
1877
|
if (content) return false;
|
|
1819
1878
|
return dedent`
|
|
@@ -1851,11 +1910,18 @@ var playwright_default = defineAddon({
|
|
|
1851
1910
|
} else if (defaultExport.type === "ObjectExpression") js.object.overrideProperties(defaultExport, config);
|
|
1852
1911
|
else R.warn("Unexpected playwright config for playwright add-on. Could not update.");
|
|
1853
1912
|
}));
|
|
1913
|
+
addToTypeConfigInclude({
|
|
1914
|
+
sv,
|
|
1915
|
+
cwd,
|
|
1916
|
+
language,
|
|
1917
|
+
kitVersion: dependencyVersion("@sveltejs/kit"),
|
|
1918
|
+
entry: `playwright.config.${language}`
|
|
1919
|
+
});
|
|
1854
1920
|
},
|
|
1855
|
-
nextSteps: ({ isKit, packageManager }) => {
|
|
1921
|
+
nextSteps: ({ isKit, options, packageManager }) => {
|
|
1856
1922
|
const steps = [];
|
|
1857
1923
|
steps.push(`Run ${color.command(resolveCommandArray(packageManager, "execute-local", ["playwright", "install"]))} to download browsers`);
|
|
1858
|
-
if (isKit) steps.push(`Visit ${color.route("/demo/playwright")} to see the demo page`);
|
|
1924
|
+
if (isKit && options.demo) steps.push(`Visit ${color.route("/demo/playwright")} to see the demo page`);
|
|
1859
1925
|
steps.push(`Run ${color.command(resolveCommandArray(packageManager, "run", ["test:e2e"]))} to execute the example tests`);
|
|
1860
1926
|
return steps;
|
|
1861
1927
|
}
|
|
@@ -1863,7 +1929,7 @@ var playwright_default = defineAddon({
|
|
|
1863
1929
|
//#endregion
|
|
1864
1930
|
//#region src/addons/prettier.ts
|
|
1865
1931
|
var prettier_default = defineAddon({
|
|
1866
|
-
id:
|
|
1932
|
+
id: ADDON_IDS.prettier,
|
|
1867
1933
|
shortDescription: "formatter",
|
|
1868
1934
|
homepage: "https://prettier.io",
|
|
1869
1935
|
options: {},
|
|
@@ -1919,13 +1985,13 @@ function checkEslint(version) {
|
|
|
1919
1985
|
//#endregion
|
|
1920
1986
|
//#region src/addons/storybook.ts
|
|
1921
1987
|
var storybook_default = defineAddon({
|
|
1922
|
-
id:
|
|
1988
|
+
id: ADDON_IDS.storybook,
|
|
1923
1989
|
shortDescription: "frontend workshop",
|
|
1924
1990
|
homepage: "https://storybook.js.org",
|
|
1925
1991
|
options: {},
|
|
1926
1992
|
setup: ({ runsAfter }) => {
|
|
1927
|
-
runsAfter(
|
|
1928
|
-
runsAfter(
|
|
1993
|
+
runsAfter(ADDON_IDS.vitest);
|
|
1994
|
+
runsAfter(ADDON_IDS.eslint);
|
|
1929
1995
|
},
|
|
1930
1996
|
run: async ({ sv }) => {
|
|
1931
1997
|
const args = [
|
|
@@ -1997,8 +2063,8 @@ const options$2 = defineAddonOptions().add("adapter", {
|
|
|
1997
2063
|
label: "Pages"
|
|
1998
2064
|
}]
|
|
1999
2065
|
}).build();
|
|
2000
|
-
|
|
2001
|
-
id:
|
|
2066
|
+
const addon$2 = defineAddon({
|
|
2067
|
+
id: ADDON_IDS.sveltekitAdapter,
|
|
2002
2068
|
alias: "adapter",
|
|
2003
2069
|
shortDescription: "deployment",
|
|
2004
2070
|
homepage: "https://svelte.dev/docs/kit/adapters",
|
|
@@ -2006,7 +2072,7 @@ var sveltekit_adapter_default = defineAddon({
|
|
|
2006
2072
|
setup: ({ isKit, unsupported }) => {
|
|
2007
2073
|
if (!isKit) unsupported("Requires SvelteKit");
|
|
2008
2074
|
},
|
|
2009
|
-
run: ({ sv, options, packageManager, file, cwd }) => {
|
|
2075
|
+
run: ({ sv, options, packageManager, file, cwd, language }) => {
|
|
2010
2076
|
const adapter = adapters.find((a) => a.id === options.adapter);
|
|
2011
2077
|
sv.file(file.package, transforms.json(({ data }) => {
|
|
2012
2078
|
const devDeps = data["devDependencies"];
|
|
@@ -2017,6 +2083,15 @@ var sveltekit_adapter_default = defineAddon({
|
|
|
2017
2083
|
}
|
|
2018
2084
|
}));
|
|
2019
2085
|
sv.devDependency(adapter.package, adapter.version);
|
|
2086
|
+
if (options.adapter === "node") {
|
|
2087
|
+
sv.devDependency("@types/node", getNodeTypesVersion());
|
|
2088
|
+
addToTypeConfigType({
|
|
2089
|
+
sv,
|
|
2090
|
+
cwd,
|
|
2091
|
+
language,
|
|
2092
|
+
entry: "node"
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2020
2095
|
if (adapter.package !== "@sveltejs/adapter-auto") sv.file("README.md", transforms.text(({ content }) => content.replace(ADAPTER_HINT_REGEX, "")));
|
|
2021
2096
|
svelteConfig.edit({
|
|
2022
2097
|
sv,
|
|
@@ -2073,11 +2148,12 @@ var sveltekit_adapter_default = defineAddon({
|
|
|
2073
2148
|
json.packageScriptsUpsert(data, "check", "wrangler types --check", { mode: "prepend" });
|
|
2074
2149
|
json.packageScriptsUpsert(data, "build", "wrangler types --check", { mode: "prepend" });
|
|
2075
2150
|
}));
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2151
|
+
addToTypeConfigType({
|
|
2152
|
+
sv,
|
|
2153
|
+
cwd,
|
|
2154
|
+
language,
|
|
2155
|
+
entry: "./worker-configuration.d.ts"
|
|
2156
|
+
});
|
|
2081
2157
|
sv.file("src/app.d.ts", transforms.script(({ ast, comments, js }) => {
|
|
2082
2158
|
const platform = js.kit.addGlobalAppInterface(ast, { name: "Platform" });
|
|
2083
2159
|
if (!platform) throw new Error("Failed detecting `platform` interface in `src/app.d.ts`");
|
|
@@ -2115,8 +2191,8 @@ const options$1 = defineAddonOptions().add("plugins", {
|
|
|
2115
2191
|
default: [],
|
|
2116
2192
|
required: false
|
|
2117
2193
|
}).build();
|
|
2118
|
-
|
|
2119
|
-
id:
|
|
2194
|
+
const addon$1 = defineAddon({
|
|
2195
|
+
id: ADDON_IDS.tailwindcss,
|
|
2120
2196
|
alias: "tailwind",
|
|
2121
2197
|
shortDescription: "css framework",
|
|
2122
2198
|
homepage: "https://tailwindcss.com",
|
|
@@ -2207,44 +2283,39 @@ const options = defineAddonOptions().add("usages", {
|
|
|
2207
2283
|
required: true
|
|
2208
2284
|
}).build();
|
|
2209
2285
|
let vitestV3Installed = false;
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
const examplesDir = `${directory.lib}/vitest-examples`;
|
|
2236
|
-
const [ts] = createPrinter(language === "ts");
|
|
2237
|
-
if (unitTesting || componentTesting) sv.file(`${examplesDir}/greet.${language}`, transforms.text(({ content }) => {
|
|
2238
|
-
if (content) return false;
|
|
2239
|
-
return dedent`
|
|
2286
|
+
const addon = defineAddon({
|
|
2287
|
+
id: ADDON_IDS.vitest,
|
|
2288
|
+
shortDescription: "unit testing",
|
|
2289
|
+
homepage: "https://vitest.dev",
|
|
2290
|
+
options,
|
|
2291
|
+
run: ({ sv, file, language, directory, options, dependencyVersion }) => {
|
|
2292
|
+
const unitTesting = options.usages.includes("unit");
|
|
2293
|
+
const componentTesting = options.usages.includes("component");
|
|
2294
|
+
const vitestVersion = dependencyVersion("vitest");
|
|
2295
|
+
if (vitestVersion) vitestV3Installed = coerceVersion(vitestVersion).major === 3;
|
|
2296
|
+
sv.devDependency("vitest", "^4.1.8");
|
|
2297
|
+
if (componentTesting) {
|
|
2298
|
+
sv.devDependency("@vitest/browser-playwright", "^4.1.8");
|
|
2299
|
+
sv.devDependency("vitest-browser-svelte", "^2.1.1");
|
|
2300
|
+
sv.devDependency("playwright", "^1.60.0");
|
|
2301
|
+
}
|
|
2302
|
+
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
2303
|
+
json.packageScriptsUpsert(data, "test:unit", "vitest");
|
|
2304
|
+
json.packageScriptsUpsert(data, "test", "npm run test:unit -- --run", { mode: "prepend" });
|
|
2305
|
+
}));
|
|
2306
|
+
const examplesDir = `${directory.lib}/vitest-examples`;
|
|
2307
|
+
const [ts] = createPrinter(language === "ts");
|
|
2308
|
+
if (unitTesting || componentTesting) sv.file(`${examplesDir}/greet.${language}`, transforms.text(({ content }) => {
|
|
2309
|
+
if (content) return false;
|
|
2310
|
+
return dedent`
|
|
2240
2311
|
export function greet(name${ts(": string")})${ts(": string")} {
|
|
2241
2312
|
return 'Hello, ' + name + '!';
|
|
2242
2313
|
}
|
|
2243
2314
|
`;
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2315
|
+
}));
|
|
2316
|
+
if (unitTesting) sv.file(`${examplesDir}/greet.spec.${language}`, transforms.text(({ content }) => {
|
|
2317
|
+
if (content) return false;
|
|
2318
|
+
return dedent`
|
|
2248
2319
|
import { describe, it, expect } from 'vitest';
|
|
2249
2320
|
import { greet } from './greet';
|
|
2250
2321
|
|
|
@@ -2254,15 +2325,19 @@ const officialAddons = {
|
|
|
2254
2325
|
});
|
|
2255
2326
|
});
|
|
2256
2327
|
`;
|
|
2328
|
+
}));
|
|
2329
|
+
if (componentTesting) {
|
|
2330
|
+
sv.file(`${examplesDir}/Welcome.svelte`, transforms.text(({ content }) => {
|
|
2331
|
+
if (content) return false;
|
|
2332
|
+
return dedent(_templateObject || (_templateObject = _taggedTemplateLiteral([
|
|
2333
|
+
"\n <script",
|
|
2334
|
+
">\n import { greet } from './greet';\n\n let { host = 'SvelteKit', guest = 'Vitest' }",
|
|
2335
|
+
" = $props();\n <\/script>\n\n <h1>{greet(host)}</h1>\n <p>{greet(guest)}</p>\n "
|
|
2336
|
+
])), ts(" lang=\"ts\""), ts(": { host: string; guest: string }"));
|
|
2257
2337
|
}));
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
return dedent(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n <script>\n import { greet } from './greet';\n\n let { host = 'SvelteKit', guest = 'Vitest' } = $props();\n <\/script>\n\n <h1>{greet(host)}</h1>\n <p>{greet(guest)}</p>\n "])));
|
|
2262
|
-
}));
|
|
2263
|
-
sv.file(`${examplesDir}/Welcome.svelte.spec.${language}`, transforms.text(({ content }) => {
|
|
2264
|
-
if (content) return false;
|
|
2265
|
-
return dedent`
|
|
2338
|
+
sv.file(`${examplesDir}/Welcome.svelte.spec.${language}`, transforms.text(({ content }) => {
|
|
2339
|
+
if (content) return false;
|
|
2340
|
+
return dedent`
|
|
2266
2341
|
import { page } from 'vitest/browser';
|
|
2267
2342
|
import { describe, expect, it } from 'vitest';
|
|
2268
2343
|
import { render } from 'vitest-browser-svelte';
|
|
@@ -2277,97 +2352,103 @@ const officialAddons = {
|
|
|
2277
2352
|
});
|
|
2278
2353
|
});
|
|
2279
2354
|
`;
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2355
|
+
}));
|
|
2356
|
+
}
|
|
2357
|
+
sv.file(file.viteConfig, transforms.script(({ ast, js }) => {
|
|
2358
|
+
const clientObjectExpression = js.object.create({
|
|
2359
|
+
extends: `./${file.viteConfig}`,
|
|
2360
|
+
test: {
|
|
2361
|
+
name: "client",
|
|
2362
|
+
browser: {
|
|
2363
|
+
enabled: true,
|
|
2364
|
+
provider: js.functions.createCall({
|
|
2365
|
+
name: "playwright",
|
|
2366
|
+
args: []
|
|
2367
|
+
}),
|
|
2368
|
+
instances: [{
|
|
2369
|
+
browser: "chromium",
|
|
2370
|
+
headless: true
|
|
2371
|
+
}]
|
|
2372
|
+
},
|
|
2373
|
+
include: ["src/**/*.svelte.{test,spec}.{js,ts}"],
|
|
2374
|
+
exclude: ["src/lib/server/**"]
|
|
2375
|
+
}
|
|
2376
|
+
});
|
|
2377
|
+
const serverObjectExpression = js.object.create({
|
|
2378
|
+
extends: `./${file.viteConfig}`,
|
|
2379
|
+
test: {
|
|
2380
|
+
name: "server",
|
|
2381
|
+
environment: "node",
|
|
2382
|
+
include: ["src/**/*.{test,spec}.{js,ts}"],
|
|
2383
|
+
exclude: ["src/**/*.svelte.{test,spec}.{js,ts}"]
|
|
2384
|
+
}
|
|
2385
|
+
});
|
|
2386
|
+
const viteConfig = js.vite.getConfig(ast);
|
|
2387
|
+
const testObject = js.object.property(viteConfig, {
|
|
2388
|
+
name: "test",
|
|
2389
|
+
fallback: js.object.create({ expect: { requireAssertions: true } })
|
|
2390
|
+
});
|
|
2391
|
+
const workspaceArray = js.object.property(testObject, {
|
|
2392
|
+
name: "projects",
|
|
2393
|
+
fallback: js.array.create()
|
|
2394
|
+
});
|
|
2395
|
+
if (componentTesting) js.array.append(workspaceArray, clientObjectExpression);
|
|
2396
|
+
if (unitTesting) js.array.append(workspaceArray, serverObjectExpression);
|
|
2397
|
+
if (componentTesting) js.imports.addNamed(ast, {
|
|
2398
|
+
imports: ["playwright"],
|
|
2399
|
+
from: "@vitest/browser-playwright"
|
|
2400
|
+
});
|
|
2401
|
+
const importName = "defineConfig";
|
|
2402
|
+
const { statement, alias } = js.imports.find(ast, {
|
|
2403
|
+
name: importName,
|
|
2404
|
+
from: "vite"
|
|
2405
|
+
});
|
|
2406
|
+
if (statement) {
|
|
2407
|
+
js.imports.addNamed(ast, {
|
|
2408
|
+
imports: { defineConfig: alias },
|
|
2409
|
+
from: "vitest/config"
|
|
2325
2410
|
});
|
|
2326
|
-
|
|
2327
|
-
const { statement, alias } = js.imports.find(ast, {
|
|
2411
|
+
js.imports.remove(ast, {
|
|
2328
2412
|
name: importName,
|
|
2329
|
-
from: "vite"
|
|
2413
|
+
from: "vite",
|
|
2414
|
+
statement
|
|
2330
2415
|
});
|
|
2331
|
-
if (statement) {
|
|
2332
|
-
js.imports.addNamed(ast, {
|
|
2333
|
-
imports: { defineConfig: alias },
|
|
2334
|
-
from: "vitest/config"
|
|
2335
|
-
});
|
|
2336
|
-
js.imports.remove(ast, {
|
|
2337
|
-
name: importName,
|
|
2338
|
-
from: "vite",
|
|
2339
|
-
statement
|
|
2340
|
-
});
|
|
2341
|
-
}
|
|
2342
|
-
}));
|
|
2343
|
-
},
|
|
2344
|
-
nextSteps: ({ language, options }) => {
|
|
2345
|
-
const toReturn = [];
|
|
2346
|
-
if (vitestV3Installed) {
|
|
2347
|
-
if (options.usages.includes("component")) {
|
|
2348
|
-
toReturn.push(`Uninstall ${color.command("@vitest/browser")} package`);
|
|
2349
|
-
toReturn.push(`Update usage from ${color.command("'@vitest/browser...'")} to ${color.command("'vitest/browser'")}`);
|
|
2350
|
-
}
|
|
2351
|
-
toReturn.push(`${color.optional("Optional")} Check ${color.path("./vite.config.ts")} and remove duplicate project definitions`);
|
|
2352
|
-
toReturn.push(`${color.optional("Optional")} Remove ${color.path(`./vitest-setup-client.${language}`)} file`);
|
|
2353
2416
|
}
|
|
2354
|
-
|
|
2417
|
+
}));
|
|
2418
|
+
},
|
|
2419
|
+
nextSteps: ({ language, options }) => {
|
|
2420
|
+
const toReturn = [];
|
|
2421
|
+
if (vitestV3Installed) {
|
|
2422
|
+
if (options.usages.includes("component")) {
|
|
2423
|
+
toReturn.push(`Uninstall ${color.command("@vitest/browser")} package`);
|
|
2424
|
+
toReturn.push(`Update usage from ${color.command("'@vitest/browser...'")} to ${color.command("'vitest/browser'")}`);
|
|
2425
|
+
}
|
|
2426
|
+
toReturn.push(`${color.optional("Optional")} Check ${color.path("./vite.config.ts")} and remove duplicate project definitions`);
|
|
2427
|
+
toReturn.push(`${color.optional("Optional")} Remove ${color.path(`./vitest-setup-client.${language}`)} file`);
|
|
2355
2428
|
}
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2429
|
+
return toReturn;
|
|
2430
|
+
}
|
|
2431
|
+
});
|
|
2432
|
+
//#endregion
|
|
2433
|
+
//#region src/addons/index.ts
|
|
2434
|
+
const officialAddons = {
|
|
2435
|
+
[ADDON_IDS.prettier]: prettier_default,
|
|
2436
|
+
[ADDON_IDS.eslint]: eslint_default,
|
|
2437
|
+
[ADDON_IDS.vitest]: addon,
|
|
2438
|
+
[ADDON_IDS.playwright]: addon$3,
|
|
2439
|
+
[ADDON_IDS.tailwindcss]: addon$1,
|
|
2440
|
+
[ADDON_IDS.enhancedImg]: enhanced_img_default,
|
|
2441
|
+
[ADDON_IDS.sveltekitAdapter]: addon$2,
|
|
2442
|
+
[ADDON_IDS.drizzle]: addon$6,
|
|
2443
|
+
[ADDON_IDS.betterAuth]: addon$7,
|
|
2444
|
+
[ADDON_IDS.mdsvex]: mdsvex_default,
|
|
2445
|
+
[ADDON_IDS.paraglide]: addon$4,
|
|
2446
|
+
[ADDON_IDS.storybook]: storybook_default,
|
|
2447
|
+
[ADDON_IDS.aiTools]: addon$8,
|
|
2448
|
+
[ADDON_IDS.experimental]: addon$5
|
|
2368
2449
|
};
|
|
2369
2450
|
function getAddonDetails(id) {
|
|
2370
|
-
const details =
|
|
2451
|
+
const details = officialAddons[id];
|
|
2371
2452
|
if (!details) throw new Error(`Invalid add-on: ${id}`);
|
|
2372
2453
|
return details;
|
|
2373
2454
|
}
|