sv 1.1.1 → 1.3.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/{shared.json → addons/ai-tools.json} +18 -199
- package/dist/{addons-DaktRhvH.mjs → addons-BCioxI2r.mjs} +134 -53
- package/dist/bin.mjs +39 -27
- package/dist/{engine-CpcTzL2R.mjs → engine-S8UpCG24.mjs} +81 -119
- package/dist/{engine-BLZdMrao.d.mts → engine-fNvU_-IL.d.mts} +3 -2
- package/dist/playground/PlaygroundLayout.svelte +218 -0
- package/dist/src/index.d.mts +36 -6
- 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/assets/CONTRIBUTING.md +48 -0
- package/dist/templates/addon/assets/README.md +29 -0
- package/dist/templates/addon/files.types=checkjs.json +10 -1
- package/dist/templates/addon/files.types=none.json +10 -1
- package/dist/templates/addon/files.types=typescript.json +10 -1
- package/dist/templates/addon/package.json +22 -16
- package/dist/templates/demo/assets/README.md +49 -0
- package/dist/templates/demo/files.types=checkjs.json +12 -0
- package/dist/templates/demo/files.types=none.json +12 -0
- package/dist/templates/demo/files.types=typescript.json +12 -0
- package/dist/templates/demo/package.json +11 -7
- package/dist/templates/library/assets/README.md +72 -0
- package/dist/templates/library/files.types=checkjs.json +12 -0
- package/dist/templates/library/files.types=none.json +12 -0
- package/dist/templates/library/files.types=typescript.json +12 -0
- package/dist/templates/library/package.json +29 -18
- package/dist/templates/minimal/assets/README.md +49 -0
- package/dist/templates/minimal/files.types=checkjs.json +12 -0
- package/dist/templates/minimal/files.types=none.json +12 -0
- package/dist/templates/minimal/files.types=typescript.json +12 -0
- package/dist/templates/minimal/package.json +11 -7
- package/package.json +4 -8
- package/dist/templates/demo/assets/DOT-npmrc +0 -1
- package/dist/templates/library/assets/DOT-npmrc +0 -1
- package/dist/templates/minimal/assets/DOT-npmrc +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { T as dist_dir, _ as defineAddon, pt as R, v as defineAddonOptions } from "./engine-S8UpCG24.mjs";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { KIT3_TSCONFIG, Walker, coerceVersion, color, createPrinter, dedent, defineDemoPage, defineEnv, fileExists, isKit3, loadPackageJson, pnpm, resolveCommandArray, resolveLibPrefix, sanitizeName, svelteConfig, transforms } from "@sveltejs/sv-utils";
|
|
@@ -56,6 +56,11 @@ const CLIENTS = {
|
|
|
56
56
|
agentPath: "AGENTS.md",
|
|
57
57
|
configPath: ".cursor/mcp.json",
|
|
58
58
|
skillsPath: ".cursor/skills",
|
|
59
|
+
alsoReadsSkillsFrom: [
|
|
60
|
+
".agents/skills",
|
|
61
|
+
".claude/skills",
|
|
62
|
+
".codex/skills"
|
|
63
|
+
],
|
|
59
64
|
agentsPath: ".cursor/agents",
|
|
60
65
|
mcpOptions: {}
|
|
61
66
|
},
|
|
@@ -64,6 +69,7 @@ const CLIENTS = {
|
|
|
64
69
|
agentPath: "GEMINI.md",
|
|
65
70
|
configPath: ".gemini/settings.json",
|
|
66
71
|
skillsPath: ".gemini/skills",
|
|
72
|
+
alsoReadsSkillsFrom: [".agents/skills"],
|
|
67
73
|
agentsPath: ".gemini/agents",
|
|
68
74
|
schema: "https://raw.githubusercontent.com/google-gemini/gemini-cli/main/schemas/settings.schema.json",
|
|
69
75
|
mcpOptions: {}
|
|
@@ -73,6 +79,8 @@ const CLIENTS = {
|
|
|
73
79
|
pluginOnly: true,
|
|
74
80
|
agentPath: "AGENTS.md",
|
|
75
81
|
configPath: ".opencode/opencode.json",
|
|
82
|
+
skillsPath: ".opencode/skills",
|
|
83
|
+
alsoReadsSkillsFrom: [".agents/skills"],
|
|
76
84
|
schema: "https://opencode.ai/config.json",
|
|
77
85
|
customData: { plugin: ["@sveltejs/opencode"] },
|
|
78
86
|
extraFiles: [{
|
|
@@ -80,11 +88,26 @@ const CLIENTS = {
|
|
|
80
88
|
data: { $schema: "https://svelte.dev/opencode/schema.json" }
|
|
81
89
|
}]
|
|
82
90
|
},
|
|
91
|
+
pi: {
|
|
92
|
+
label: "Pi",
|
|
93
|
+
pluginOnly: true,
|
|
94
|
+
agentPath: "AGENTS.md",
|
|
95
|
+
configPath: ".pi/settings.json",
|
|
96
|
+
skillsPath: ".pi/skills",
|
|
97
|
+
alsoReadsSkillsFrom: [".agents/skills"],
|
|
98
|
+
schema: "https://pi.dev/schemas/settings.schema.json",
|
|
99
|
+
customData: { packages: ["npm:@sveltejs/pi"] },
|
|
100
|
+
extraFiles: [{
|
|
101
|
+
path: ".pi/svelte.json",
|
|
102
|
+
data: { $schema: "https://svelte.dev/pi/schema.json" }
|
|
103
|
+
}]
|
|
104
|
+
},
|
|
83
105
|
vscode: {
|
|
84
106
|
label: "VS Code",
|
|
85
107
|
agentPath: "AGENTS.md",
|
|
86
108
|
configPath: ".vscode/mcp.json",
|
|
87
109
|
skillsPath: ".github/skills",
|
|
110
|
+
alsoReadsSkillsFrom: [".claude/skills", ".agents/skills"],
|
|
88
111
|
agentsPath: ".github/agents",
|
|
89
112
|
agentExtension: ".agent.md",
|
|
90
113
|
mcpOptions: { serversKey: "servers" }
|
|
@@ -118,6 +141,29 @@ const TOOLS = {
|
|
|
118
141
|
hint: "sub-agent"
|
|
119
142
|
}
|
|
120
143
|
};
|
|
144
|
+
const OPT_IN_SKILLS = { "svelte-mcp-feedback": {
|
|
145
|
+
label: "svelte-mcp-feedback",
|
|
146
|
+
hint: "reports Svelte mistakes you correct to sveltejs/ai-tools"
|
|
147
|
+
} };
|
|
148
|
+
const skillDirsOf = (client) => client.skillsPath ? [client.skillsPath, ...client.alsoReadsSkillsFrom ?? []] : [];
|
|
149
|
+
const hasSkillIn = (cwd, dir, skill) => fs.existsSync(path.resolve(cwd, dir, skill, "SKILL.md"));
|
|
150
|
+
const isSkillInstalled = (cwd, client, skill) => skillDirsOf(client).some((dir) => hasSkillIn(cwd, dir, skill));
|
|
151
|
+
const readersOf = (dir) => Object.values(CLIENTS).filter((client) => skillDirsOf(client).includes(dir)).length;
|
|
152
|
+
const optInSkillsQuestion = (isInstalled = () => false) => {
|
|
153
|
+
const missingFor = (ides) => Object.keys(OPT_IN_SKILLS).filter((skill) => ides.some((i) => CLIENTS[i]?.skillsPath && !isInstalled(CLIENTS[i], skill)));
|
|
154
|
+
return {
|
|
155
|
+
question: "Would you like to add any opt-in skills?",
|
|
156
|
+
type: "multiselect",
|
|
157
|
+
default: [],
|
|
158
|
+
options: missingFor(Object.keys(CLIENTS)).map((value) => ({
|
|
159
|
+
value,
|
|
160
|
+
label: OPT_IN_SKILLS[value].label,
|
|
161
|
+
hint: OPT_IN_SKILLS[value].hint
|
|
162
|
+
})),
|
|
163
|
+
required: false,
|
|
164
|
+
condition: ({ ide }) => missingFor(ide).length > 0
|
|
165
|
+
};
|
|
166
|
+
};
|
|
121
167
|
const options$8 = defineAddonOptions().add("ide", {
|
|
122
168
|
question: "Which client would you like to use?",
|
|
123
169
|
type: "multiselect",
|
|
@@ -166,18 +212,22 @@ const options$8 = defineAddonOptions().add("ide", {
|
|
|
166
212
|
hint: "will use a remote endpoint"
|
|
167
213
|
}],
|
|
168
214
|
condition: ({ ide, delivery, tools }) => (tools === void 0 || tools.includes("mcp")) && ide.some((i) => wantsMcpConfig(CLIENTS[i], delivery))
|
|
169
|
-
}).build();
|
|
215
|
+
}).add("optInSkills", optInSkillsQuestion()).build();
|
|
170
216
|
const addon$8 = defineAddon({
|
|
171
217
|
id: ADDON_IDS.aiTools,
|
|
172
218
|
shortDescription: "Svelte AI tools",
|
|
173
219
|
homepage: "https://svelte.dev/docs/ai",
|
|
174
220
|
options: options$8,
|
|
175
|
-
|
|
221
|
+
setup: ({ cwd, addOption }) => {
|
|
222
|
+
addOption("optInSkills", optInSkillsQuestion((client, skill) => isSkillInstalled(cwd, client, skill)));
|
|
223
|
+
},
|
|
224
|
+
run: ({ sv, options, cwd }) => {
|
|
176
225
|
const usePlugin = options.delivery === "plugin";
|
|
177
226
|
const selected = options.tools ?? Object.keys(TOOLS);
|
|
178
227
|
const selectedSkills = selected.filter((t) => TOOLS[t]?.kind === "skill");
|
|
179
228
|
const selectedAgents = selected.filter((t) => TOOLS[t]?.kind === "agent");
|
|
180
229
|
const wantsMcp = selected.includes("mcp");
|
|
230
|
+
const selectedOptInSkills = (options.optInSkills ?? []).filter((s) => s in OPT_IN_SKILLS);
|
|
181
231
|
const getLocalConfig = (o) => {
|
|
182
232
|
return {
|
|
183
233
|
...o?.typeLocal ? { type: o.typeLocal } : {},
|
|
@@ -194,10 +244,14 @@ const addon$8 = defineAddon({
|
|
|
194
244
|
};
|
|
195
245
|
const filesAdded = [];
|
|
196
246
|
const filesExistingAlready = [];
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
247
|
+
const { files } = JSON.parse(fs.readFileSync(path.join(dist_dir, "addons", "ai-tools.json"), "utf-8"));
|
|
248
|
+
const at = (kind) => files.filter((file) => file.name.startsWith(`${kind}/`)).map((file) => ({
|
|
249
|
+
...file,
|
|
250
|
+
name: file.name.slice(kind.length + 1)
|
|
251
|
+
}));
|
|
252
|
+
const mcpFiles = at("mcp");
|
|
253
|
+
const skillFiles = at("skills");
|
|
254
|
+
const agentFiles = at("agents");
|
|
201
255
|
const agentFile = mcpFiles.find((file) => file.name === "AGENTS.md");
|
|
202
256
|
const addFile = (path, contents) => {
|
|
203
257
|
sv.file(path, (content) => {
|
|
@@ -209,6 +263,16 @@ const addon$8 = defineAddon({
|
|
|
209
263
|
return contents;
|
|
210
264
|
});
|
|
211
265
|
};
|
|
266
|
+
const optInClients = options.ide.map((ide) => CLIENTS[ide]).filter((client) => Boolean(client?.skillsPath)).sort((a, b) => readersOf(b.skillsPath) - readersOf(a.skillsPath));
|
|
267
|
+
for (const skill of selectedOptInSkills) {
|
|
268
|
+
const files = skillFiles.filter((file) => file.name.split("/")[0] === skill);
|
|
269
|
+
const writtenDirs = /* @__PURE__ */ new Set();
|
|
270
|
+
for (const client of optInClients) {
|
|
271
|
+
if (skillDirsOf(client).some((dir) => writtenDirs.has(dir) || hasSkillIn(cwd, dir, skill))) continue;
|
|
272
|
+
for (const file of files) addFile(`${client.skillsPath}/${file.name}`, file.contents);
|
|
273
|
+
writtenDirs.add(client.skillsPath);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
212
276
|
for (const ide of options.ide) {
|
|
213
277
|
const client = CLIENTS[ide];
|
|
214
278
|
if (!client) continue;
|
|
@@ -249,11 +313,12 @@ const addon$8 = defineAddon({
|
|
|
249
313
|
if (extraFiles) for (const extra of extraFiles) sv.file(extra.path, transforms.json(({ data }) => {
|
|
250
314
|
for (const [key, value] of Object.entries(extra.data)) data[key] = value;
|
|
251
315
|
}));
|
|
252
|
-
|
|
316
|
+
const looseTools = wantsLooseTools(client, options.delivery);
|
|
317
|
+
if (skillsPath && looseTools) for (const file of skillFiles) {
|
|
253
318
|
if (!selectedSkills.includes(file.name.split("/")[0])) continue;
|
|
254
319
|
addFile(`${skillsPath}/${file.name}`, file.contents);
|
|
255
320
|
}
|
|
256
|
-
if (agentsPath) for (const file of agentFiles) {
|
|
321
|
+
if (agentsPath && looseTools) for (const file of agentFiles) {
|
|
257
322
|
if (!selectedAgents.includes(file.name.replace(REGEX_MD, ""))) continue;
|
|
258
323
|
const ext = agentExtension ?? ".md";
|
|
259
324
|
addFile(`${agentsPath}/${file.name.replace(REGEX_MD, ext)}`, file.contents);
|
|
@@ -713,11 +778,11 @@ const addon$7 = defineAddon({
|
|
|
713
778
|
}
|
|
714
779
|
});
|
|
715
780
|
const generateEnv$1 = (demoGithub, isExample) => transforms.text(({ content, text }) => {
|
|
716
|
-
content = text.
|
|
781
|
+
content = text.add(content, "ORIGIN", {
|
|
717
782
|
value: isExample ? `""` : `"http://localhost:5173"`,
|
|
718
783
|
separator: true
|
|
719
784
|
});
|
|
720
|
-
content = text.
|
|
785
|
+
content = text.add(content, "BETTER_AUTH_SECRET", {
|
|
721
786
|
value: isExample ? `""` : `"${crypto.randomUUID()}"`,
|
|
722
787
|
comment: [
|
|
723
788
|
"Better Auth",
|
|
@@ -727,11 +792,11 @@ const generateEnv$1 = (demoGithub, isExample) => transforms.text(({ content, tex
|
|
|
727
792
|
separator: true
|
|
728
793
|
});
|
|
729
794
|
if (demoGithub) {
|
|
730
|
-
content = text.
|
|
795
|
+
content = text.add(content, "GITHUB_CLIENT_ID", {
|
|
731
796
|
value: `""`,
|
|
732
797
|
comment: "GitHub OAuth\n# https://www.better-auth.com/docs/authentication/github"
|
|
733
798
|
});
|
|
734
|
-
content = text.
|
|
799
|
+
content = text.add(content, "GITHUB_CLIENT_SECRET", { value: `""` });
|
|
735
800
|
}
|
|
736
801
|
return content;
|
|
737
802
|
});
|
|
@@ -1052,10 +1117,10 @@ const addon$6 = defineAddon({
|
|
|
1052
1117
|
json.packageScriptsUpsert(data, "db:migrate", "drizzle-kit migrate");
|
|
1053
1118
|
json.packageScriptsUpsert(data, "db:studio", "drizzle-kit studio");
|
|
1054
1119
|
}));
|
|
1055
|
-
if (Boolean(dependencyVersion("prettier"))) sv.file(".prettierignore", transforms.text(({ content, text }) => text.
|
|
1120
|
+
if (Boolean(dependencyVersion("prettier"))) sv.file(".prettierignore", transforms.text(({ content, text }) => text.add(content, "/drizzle/")));
|
|
1056
1121
|
if (options.database === "sqlite") sv.file(file.gitignore, transforms.text(({ content, text }) => {
|
|
1057
1122
|
if (content.length === 0) return false;
|
|
1058
|
-
return text.
|
|
1123
|
+
return text.add(content, "*.db", { comment: "SQLite" });
|
|
1059
1124
|
}));
|
|
1060
1125
|
sv.file(paths["drizzle config"], transforms.script(({ ast, js }) => {
|
|
1061
1126
|
const d1 = options.database === "d1";
|
|
@@ -1333,13 +1398,13 @@ const addon$6 = defineAddon({
|
|
|
1333
1398
|
const generateEnv = (opts, isExample) => transforms.text(({ content, text }) => {
|
|
1334
1399
|
const DB_URL_KEY = "DATABASE_URL";
|
|
1335
1400
|
if (opts.database === "d1") {
|
|
1336
|
-
content = text.
|
|
1401
|
+
content = text.add(content, "CLOUDFLARE_ACCOUNT_ID", {
|
|
1337
1402
|
value: "\"\"",
|
|
1338
1403
|
comment: ["Cloudflare D1"],
|
|
1339
1404
|
separator: true
|
|
1340
1405
|
});
|
|
1341
|
-
content = text.
|
|
1342
|
-
content = text.
|
|
1406
|
+
content = text.add(content, "CLOUDFLARE_DATABASE_ID", { value: "\"\"" });
|
|
1407
|
+
content = text.add(content, "CLOUDFLARE_D1_TOKEN", { value: "\"\"" });
|
|
1343
1408
|
return content;
|
|
1344
1409
|
}
|
|
1345
1410
|
let value;
|
|
@@ -1371,12 +1436,12 @@ const generateEnv = (opts, isExample) => transforms.text(({ content, text }) =>
|
|
|
1371
1436
|
value = "\"postgres://user:password@host:port/db-name\"";
|
|
1372
1437
|
comment.push("Replace with your DB credentials!");
|
|
1373
1438
|
} else value = "";
|
|
1374
|
-
content = text.
|
|
1439
|
+
content = text.add(content, DB_URL_KEY, {
|
|
1375
1440
|
value,
|
|
1376
1441
|
comment,
|
|
1377
1442
|
separator: true
|
|
1378
1443
|
});
|
|
1379
|
-
if (opts.sqlite === "turso") content = text.
|
|
1444
|
+
if (opts.sqlite === "turso") content = text.add(content, "DATABASE_AUTH_TOKEN", { value: isExample ? `""` : `"${crypto.randomUUID()}"` });
|
|
1380
1445
|
return content;
|
|
1381
1446
|
});
|
|
1382
1447
|
//#endregion
|
|
@@ -1448,6 +1513,13 @@ var eslint_default = defineAddon({
|
|
|
1448
1513
|
language,
|
|
1449
1514
|
entry: "node"
|
|
1450
1515
|
});
|
|
1516
|
+
addToTypeConfigInclude({
|
|
1517
|
+
sv,
|
|
1518
|
+
cwd,
|
|
1519
|
+
language,
|
|
1520
|
+
kitVersion: dependencyVersion("@sveltejs/kit"),
|
|
1521
|
+
entry: "eslint.config.js"
|
|
1522
|
+
});
|
|
1451
1523
|
if (typescript) sv.devDependency("typescript-eslint", "^8.60.1");
|
|
1452
1524
|
if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^10.1.8");
|
|
1453
1525
|
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
@@ -1766,8 +1838,8 @@ const addon$4 = defineAddon({
|
|
|
1766
1838
|
}));
|
|
1767
1839
|
sv.file(file.gitignore, transforms.text(({ content, text }) => {
|
|
1768
1840
|
if (!content) return false;
|
|
1769
|
-
content = text.
|
|
1770
|
-
content = text.
|
|
1841
|
+
content = text.add(content, paraglideOutDir, { comment: "Paraglide" });
|
|
1842
|
+
content = text.add(content, "project.inlang/cache/");
|
|
1771
1843
|
return content;
|
|
1772
1844
|
}));
|
|
1773
1845
|
const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
|
|
@@ -1864,7 +1936,7 @@ const addon$3 = defineAddon({
|
|
|
1864
1936
|
}));
|
|
1865
1937
|
sv.file(file.gitignore, transforms.text(({ content, text }) => {
|
|
1866
1938
|
if (!content) return false;
|
|
1867
|
-
return text.
|
|
1939
|
+
return text.add(content, "test-results", { comment: "Playwright" });
|
|
1868
1940
|
}));
|
|
1869
1941
|
const withDemo = isKit && options.demo;
|
|
1870
1942
|
const demo = defineDemoPage("playwright", language, directory.kitRoutes);
|
|
@@ -1933,7 +2005,7 @@ var prettier_default = defineAddon({
|
|
|
1933
2005
|
shortDescription: "formatter",
|
|
1934
2006
|
homepage: "https://prettier.io",
|
|
1935
2007
|
options: {},
|
|
1936
|
-
run: ({ sv, dependencyVersion, file }) => {
|
|
2008
|
+
run: ({ sv, dependencyVersion, file, cwd, language }) => {
|
|
1937
2009
|
const tailwindcssInstalled = Boolean(dependencyVersion("tailwindcss"));
|
|
1938
2010
|
if (tailwindcssInstalled) sv.devDependency("prettier-plugin-tailwindcss", "^0.8.0");
|
|
1939
2011
|
sv.devDependency("prettier", "^3.8.3");
|
|
@@ -1956,6 +2028,13 @@ var prettier_default = defineAddon({
|
|
|
1956
2028
|
tailwind: tailwindcssInstalled,
|
|
1957
2029
|
stylesheet: tailwindcssInstalled ? file.getRelative({ to: file.stylesheet }) : void 0
|
|
1958
2030
|
}));
|
|
2031
|
+
addToTypeConfigInclude({
|
|
2032
|
+
sv,
|
|
2033
|
+
cwd,
|
|
2034
|
+
language,
|
|
2035
|
+
kitVersion: dependencyVersion("@sveltejs/kit"),
|
|
2036
|
+
entry: prettierConfigPath()
|
|
2037
|
+
});
|
|
1959
2038
|
const eslintInfo = checkEslint(dependencyVersion("eslint"));
|
|
1960
2039
|
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
1961
2040
|
json.packageScriptsUpsert(data, "lint", "prettier --check .", { mode: "prepend" });
|
|
@@ -1993,12 +2072,13 @@ var storybook_default = defineAddon({
|
|
|
1993
2072
|
runsAfter(ADDON_IDS.vitest);
|
|
1994
2073
|
runsAfter(ADDON_IDS.eslint);
|
|
1995
2074
|
},
|
|
1996
|
-
run: async ({ sv }) => {
|
|
2075
|
+
run: async ({ sv, packageManager }) => {
|
|
1997
2076
|
const args = [
|
|
1998
2077
|
`create-storybook@latest`,
|
|
1999
2078
|
"--skip-install",
|
|
2000
2079
|
"--no-dev"
|
|
2001
2080
|
];
|
|
2081
|
+
if (packageManager === "pnpm") args.unshift("--allow-build=esbuild");
|
|
2002
2082
|
if (V.env.NODE_ENV?.toLowerCase() === "test") args.push(...["--no-features", "--yes"]);
|
|
2003
2083
|
await sv.execute(args, "inherit");
|
|
2004
2084
|
sv.devDependency(`@types/node`, getNodeTypesVersion());
|
|
@@ -2017,6 +2097,11 @@ const adapters = [
|
|
|
2017
2097
|
package: "@sveltejs/adapter-node",
|
|
2018
2098
|
version: "^6.0.0"
|
|
2019
2099
|
},
|
|
2100
|
+
{
|
|
2101
|
+
id: "bun",
|
|
2102
|
+
package: "@sveltejs/adapter-bun",
|
|
2103
|
+
version: "^1.0.0"
|
|
2104
|
+
},
|
|
2020
2105
|
{
|
|
2021
2106
|
id: "static",
|
|
2022
2107
|
package: "@sveltejs/adapter-static",
|
|
@@ -2074,14 +2159,6 @@ const addon$2 = defineAddon({
|
|
|
2074
2159
|
},
|
|
2075
2160
|
run: ({ sv, options, packageManager, file, cwd, language }) => {
|
|
2076
2161
|
const adapter = adapters.find((a) => a.id === options.adapter);
|
|
2077
|
-
sv.file(file.package, transforms.json(({ data }) => {
|
|
2078
|
-
const devDeps = data["devDependencies"];
|
|
2079
|
-
for (const pkg of Object.keys(devDeps)) if (pkg.startsWith("@sveltejs/adapter-")) delete devDeps[pkg];
|
|
2080
|
-
if (options.adapter === "cloudflare") {
|
|
2081
|
-
const preview = options.cfTarget === "workers" ? "wrangler dev .svelte-kit/cloudflare/_worker.js --port 4173" : "wrangler pages dev .svelte-kit/cloudflare --port 4173";
|
|
2082
|
-
data.scripts.preview = preview;
|
|
2083
|
-
}
|
|
2084
|
-
}));
|
|
2085
2162
|
sv.devDependency(adapter.package, adapter.version);
|
|
2086
2163
|
if (options.adapter === "node") {
|
|
2087
2164
|
sv.devDependency("@types/node", getNodeTypesVersion());
|
|
@@ -2092,14 +2169,16 @@ const addon$2 = defineAddon({
|
|
|
2092
2169
|
entry: "node"
|
|
2093
2170
|
});
|
|
2094
2171
|
}
|
|
2095
|
-
|
|
2172
|
+
let previousAdapter;
|
|
2096
2173
|
svelteConfig.edit({
|
|
2097
2174
|
sv,
|
|
2098
2175
|
cwd
|
|
2099
2176
|
}, ({ ast, override, js }) => {
|
|
2100
|
-
const adapterImports = ast.body.filter((
|
|
2177
|
+
const adapterImports = ast.body.filter((node) => node.type === "ImportDeclaration").find((importDecl) => typeof importDecl.source.value === "string" && importDecl.source.value.startsWith("@sveltejs/adapter-") && importDecl.importKind === "value");
|
|
2101
2178
|
let adapterName = "adapter";
|
|
2102
2179
|
if (adapterImports) {
|
|
2180
|
+
const foundPackage = adapterImports.source.value;
|
|
2181
|
+
if (typeof foundPackage === "string" && foundPackage !== adapter.package) previousAdapter = foundPackage;
|
|
2103
2182
|
adapterImports.source.value = adapter.package;
|
|
2104
2183
|
adapterImports.source.raw = void 0;
|
|
2105
2184
|
adapterName = (adapterImports.specifiers?.find((s) => s.type === "ImportDefaultSpecifier")).local.name;
|
|
@@ -2113,6 +2192,13 @@ const addon$2 = defineAddon({
|
|
|
2113
2192
|
useIdentifiers: true
|
|
2114
2193
|
}) }, adapter.package === "@sveltejs/adapter-auto" ? void 0 : { dropLeadingComments: ["adapter"] });
|
|
2115
2194
|
});
|
|
2195
|
+
sv.file(file.package, transforms.json(({ data }) => {
|
|
2196
|
+
if (previousAdapter) {
|
|
2197
|
+
delete data["devDependencies"]?.[previousAdapter];
|
|
2198
|
+
delete data["dependencies"]?.[previousAdapter];
|
|
2199
|
+
}
|
|
2200
|
+
}));
|
|
2201
|
+
if (adapter.package !== "@sveltejs/adapter-auto") sv.file("README.md", transforms.text(({ content }) => content.replace(ADAPTER_HINT_REGEX, "")));
|
|
2116
2202
|
if (adapter.package === "@sveltejs/adapter-cloudflare") {
|
|
2117
2203
|
sv.devDependency("wrangler", "^4.97.0");
|
|
2118
2204
|
if (packageManager === "pnpm") sv.file(file.findUp("pnpm-workspace.yaml"), pnpm.allowBuilds({
|
|
@@ -2142,25 +2228,20 @@ const addon$2 = defineAddon({
|
|
|
2142
2228
|
}
|
|
2143
2229
|
};
|
|
2144
2230
|
sv.file(`wrangler.${ext}`, ext === "toml" ? transforms.toml(({ data }) => applyWranglerConfig(data)) : transforms.json(({ data }) => applyWranglerConfig(data)));
|
|
2145
|
-
|
|
2146
|
-
|
|
2231
|
+
sv.file(file.package, transforms.json(({ data, json }) => {
|
|
2232
|
+
if (file.typeConfig) {
|
|
2147
2233
|
json.packageScriptsUpsert(data, "gen", "wrangler types");
|
|
2148
2234
|
json.packageScriptsUpsert(data, "check", "wrangler types --check", { mode: "prepend" });
|
|
2149
2235
|
json.packageScriptsUpsert(data, "build", "wrangler types --check", { mode: "prepend" });
|
|
2150
|
-
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
if (!platform) throw new Error("Failed detecting `platform` interface in `src/app.d.ts`");
|
|
2160
|
-
comments.remove((c) => c.type === "Line" && c.value.trim() === "interface Platform {}");
|
|
2161
|
-
platform.body.body.push(js.common.createTypeProperty("env", "Env"), js.common.createTypeProperty("ctx", "ExecutionContext"), js.common.createTypeProperty("caches", "CacheStorage"), js.common.createTypeProperty("cf", "IncomingRequestCfProperties", true));
|
|
2162
|
-
}));
|
|
2163
|
-
}
|
|
2236
|
+
}
|
|
2237
|
+
data.scripts.preview = options.cfTarget === "workers" ? "wrangler dev .svelte-kit/cloudflare/_worker.js --port 4173" : "wrangler pages dev .svelte-kit/cloudflare --port 4173";
|
|
2238
|
+
}));
|
|
2239
|
+
if (file.typeConfig) addToTypeConfigType({
|
|
2240
|
+
sv,
|
|
2241
|
+
cwd,
|
|
2242
|
+
language,
|
|
2243
|
+
entry: "./worker-configuration.d.ts"
|
|
2244
|
+
});
|
|
2164
2245
|
}
|
|
2165
2246
|
},
|
|
2166
2247
|
nextSteps({ options, packageManager }) {
|
|
@@ -2304,10 +2385,10 @@ const addon = defineAddon({
|
|
|
2304
2385
|
json.packageScriptsUpsert(data, "test", "npm run test:unit -- --run", { mode: "prepend" });
|
|
2305
2386
|
}));
|
|
2306
2387
|
const examplesDir = `${directory.lib}/vitest-examples`;
|
|
2307
|
-
const [ts] = createPrinter(language === "ts");
|
|
2388
|
+
const [ts, jsdocs] = createPrinter(language === "ts", !!file.typeConfig?.endsWith("jsconfig.json"));
|
|
2308
2389
|
if (unitTesting || componentTesting) sv.file(`${examplesDir}/greet.${language}`, transforms.text(({ content }) => {
|
|
2309
2390
|
if (content) return false;
|
|
2310
|
-
return dedent
|
|
2391
|
+
return dedent`${jsdocs("/** @param {string} name */\n")}
|
|
2311
2392
|
export function greet(name${ts(": string")})${ts(": string")} {
|
|
2312
2393
|
return 'Hello, ' + name + '!';
|
|
2313
2394
|
}
|
package/dist/bin.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as parse$1, A as cliOptions, B as runAndValidateVerifications, C as
|
|
3
|
-
import { n as officialAddons$1, t as getAddonDetails } from "./addons-
|
|
2
|
+
import { $ as parse$1, A as cliOptions, B as runAndValidateVerifications, C as create$1, D as from, E as up$2, F as getPadding, G as UnsupportedError, H as updateAgent, I as helpConfig, J as array, K as name, L as isNodeError, M as filePaths, N as forwardExitCode, O as PackageJSONSchema, P as getHelpSections, Q as optional, R as normalizePosix, S as execSync, T as dist_dir, U as updateLibraryBuild, V as runCommand, W as updateReadme, X as literal, Y as boolean, Z as nonEmpty, _t as pe, a as setupAddons, at as string, b as NonZeroExitError, bt as R$1, c as AGENT_NAMES, ct as program, d as detectPackageManager, dt as Ce, et as picklist, f as installDependencies, ft as Ee, g as createLoadedAddon, gt as le, h as up$1, ht as ge, i as prepareSvApi, it as strictObject, j as errorAndExit, k as buildAndLogArgs, l as addAllowBuildsIfPnpm, lt as Command, m as packageManagerPrompt, mt as Re, n as applyAddons, nt as record, o as createWorkspace, ot as transform, p as installOption, pt as R, q as version, r as orderAddons, rt as safeParse, s as findWorkspaceRoot, st as union, tt as pipe, u as addEngineStrict, ut as Option, vt, w as templates, x as exec, y as getErrorHint, yt as we, z as parseAddonOptions } from "./engine-S8UpCG24.mjs";
|
|
3
|
+
import { n as officialAddons$1, t as getAddonDetails } from "./addons-BCioxI2r.mjs";
|
|
4
4
|
import * as fs$1 from "node:fs";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import * as path$1 from "node:path";
|
|
@@ -2063,25 +2063,19 @@ function setupPlaygroundProject(url, playground, cwd, installDependencies) {
|
|
|
2063
2063
|
fs.writeFileSync(filePath, file.content, "utf8");
|
|
2064
2064
|
}
|
|
2065
2065
|
{
|
|
2066
|
-
const
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
} else if (node.value === "$sv-url-$sv") {
|
|
2077
|
-
node.value = url;
|
|
2078
|
-
node.raw = void 0;
|
|
2079
|
-
}
|
|
2080
|
-
} });
|
|
2081
|
-
contentToWrite = generateCode();
|
|
2066
|
+
const layout = fs.readFileSync(path.join(dist_dir, "playground", "PlaygroundLayout.svelte"), "utf-8");
|
|
2067
|
+
const { ast, generateCode } = parse.svelte(layout);
|
|
2068
|
+
svelte.ensureScript(ast);
|
|
2069
|
+
Walker.walk(ast.instance.content, null, { Literal(node) {
|
|
2070
|
+
if (node.value === "$sv-title-$sv") {
|
|
2071
|
+
node.value = playground.name;
|
|
2072
|
+
node.raw = void 0;
|
|
2073
|
+
} else if (node.value === "$sv-url-$sv") {
|
|
2074
|
+
node.value = url;
|
|
2075
|
+
node.raw = void 0;
|
|
2082
2076
|
}
|
|
2083
|
-
|
|
2084
|
-
|
|
2077
|
+
} });
|
|
2078
|
+
fs.writeFileSync(path.join(cwd, "src/lib/PlaygroundLayout.svelte"), generateCode(), "utf-8");
|
|
2085
2079
|
}
|
|
2086
2080
|
const filePath = path.join(cwd, "src/routes/+page.svelte");
|
|
2087
2081
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
@@ -2380,6 +2374,10 @@ async function createProject(cwd, options) {
|
|
|
2380
2374
|
updateReadme(directory, prompt);
|
|
2381
2375
|
updateAgent(directory, language, packageManager ?? "npm", loadedAddons);
|
|
2382
2376
|
const addOnNextSteps = getNextSteps(addOnSuccessfulAddons, workspace, answers, addonSetupResults);
|
|
2377
|
+
addEngineStrict({
|
|
2378
|
+
cwd: projectPath,
|
|
2379
|
+
packageManager
|
|
2380
|
+
});
|
|
2383
2381
|
addAllowBuildsIfPnpm({
|
|
2384
2382
|
cwd: projectPath,
|
|
2385
2383
|
packageManager,
|
|
@@ -2431,7 +2429,7 @@ async function createVirtualWorkspace({ cwd, template, type }) {
|
|
|
2431
2429
|
kitRoutes: "src/routes"
|
|
2432
2430
|
};
|
|
2433
2431
|
}
|
|
2434
|
-
const templatePackageJsonPath =
|
|
2432
|
+
const templatePackageJsonPath = path.join(dist_dir, "templates", template);
|
|
2435
2433
|
const { data: packageJson } = loadPackageJson(templatePackageJsonPath);
|
|
2436
2434
|
override.dependencies = {
|
|
2437
2435
|
...packageJson.devDependencies,
|
|
@@ -3085,6 +3083,16 @@ const migrationTasks = [
|
|
|
3085
3083
|
summary: "Cross-origin mutative requests without a `Content-Type` header are rejected as CSRF.",
|
|
3086
3084
|
instructions: "Ensure the submission sends an appropriate `Content-Type` header or add the destination to the narrowest possible `csrf.trustedOrigins` allowlist.",
|
|
3087
3085
|
links: guideLink("Security-Cross-origin-form-submissions-require-a-Content-Type-header")
|
|
3086
|
+
},
|
|
3087
|
+
{
|
|
3088
|
+
title: "Review `redirect(...)` destinations for external URLs",
|
|
3089
|
+
checks: [{
|
|
3090
|
+
include: CODE_FILES,
|
|
3091
|
+
patterns: [/^(?=[\s\S]*['"]@sveltejs\/kit['"])(?=[\s\S]*\bredirect\s*\()/]
|
|
3092
|
+
}],
|
|
3093
|
+
summary: "`redirect(...)` to an external URL now requires an `external` option.",
|
|
3094
|
+
instructions: "The automatic migration only analyzes static URLs. Inspect each `redirect` call: if the destination can be an external URL at runtime, pass `{ external: true }` for a blanket allow, or `{ external: [...] }` for a list of permitted origins, or keep it as is when determining that this should only handle app-internal redirects.",
|
|
3095
|
+
links: guideLink("Miscellaneous-External-redirects-must-be-opted-into")
|
|
3088
3096
|
}
|
|
3089
3097
|
];
|
|
3090
3098
|
var collect_migration_instructions_default = defineMigrationTask({
|
|
@@ -3838,7 +3846,8 @@ function libSubpathImports(libDir) {
|
|
|
3838
3846
|
var lib_alias_default = defineMigrationTask({
|
|
3839
3847
|
id: "lib-alias",
|
|
3840
3848
|
description: "Replace the $lib alias with #lib subpath imports",
|
|
3841
|
-
run: ({ sv, cwd, directory }) => {
|
|
3849
|
+
run: ({ sv, cwd, directory, dependencyVersion }) => {
|
|
3850
|
+
const isLibrary = Boolean(dependencyVersion("@sveltejs/package"));
|
|
3842
3851
|
sv.file("package.json", transforms.json(({ data }) => {
|
|
3843
3852
|
data.imports = {
|
|
3844
3853
|
...libSubpathImports(directory.lib),
|
|
@@ -3855,11 +3864,14 @@ var lib_alias_default = defineMigrationTask({
|
|
|
3855
3864
|
match = match.replace("$lib", "#lib");
|
|
3856
3865
|
if (import_path && !import_path.endsWith(".js") && !import_path.endsWith(".ts")) {
|
|
3857
3866
|
for (const ending of [
|
|
3858
|
-
".js",
|
|
3859
3867
|
".ts",
|
|
3860
|
-
"
|
|
3861
|
-
"/index.ts"
|
|
3862
|
-
|
|
3868
|
+
".js",
|
|
3869
|
+
"/index.ts",
|
|
3870
|
+
"/index.js"
|
|
3871
|
+
]) if (fs.existsSync(path.join(cwd, directory.lib, import_path + ending))) {
|
|
3872
|
+
const specifier = isLibrary ? ending.replace(".ts", ".js") : ending;
|
|
3873
|
+
return match.slice(0, -1) + specifier + match.slice(-1);
|
|
3874
|
+
}
|
|
3863
3875
|
}
|
|
3864
3876
|
return match;
|
|
3865
3877
|
});
|
|
@@ -3872,7 +3884,7 @@ var lib_alias_default = defineMigrationTask({
|
|
|
3872
3884
|
const KIT3_MIN_VERSIONS = {
|
|
3873
3885
|
vite: "^8.0.12",
|
|
3874
3886
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
3875
|
-
svelte: "^5.57.
|
|
3887
|
+
svelte: "^5.57.2",
|
|
3876
3888
|
"@sveltejs/package": "^3.0.0",
|
|
3877
3889
|
"svelte-check": "^4.7.5",
|
|
3878
3890
|
typescript: "^6.0.0"
|