sv 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { $ as pipe, A as filePaths, B as updateAgent, C as templates, D as buildAndLogArgs, E as PackageJSONSchema, F as isNodeError, G as version, H as updateReadme, I as normalizePosix, J as literal, K as array, L as parseAddonOptions, M as getHelpSections, N as getPadding, O as cliOptions, P as helpConfig, Q as picklist, R as runAndValidateVerifications, S as create$1, T as getSharedFiles, U as UnsupportedError, V as updateLibraryBuild, W as name, X as optional, Y as nonEmpty, Z as parse$1, _t as we, a as setupAddons, at as union, b as exec, c as AGENT_NAMES, ct as Option, d as installDependencies, dt as R, et as record, f as installOption, ft as Re, g as createLoadedAddon, gt as vt, h as from, ht as pe, i as prepareSvApi, it as transform, j as forwardExitCode, k as errorAndExit, l as addAllowBuildsIfPnpm, lt as Ce, m as up$1, mt as le, n as applyAddons, nt as strictObject, o as createWorkspace, ot as program, p as packageManagerPrompt, pt as ge, q as boolean, r as orderAddons, rt as string, s as findWorkspaceRoot, st as Command, tt as safeParse, u as detectPackageManager, ut as Ee, vt as R$1, w as dist, x as execSync, y as getErrorHint, z as runCommand } from "./engine-LhRAh1ZA.mjs";
3
- import { n as officialAddons$1, t as getAddonDetails } from "./addons-BvT-iII-.mjs";
2
+ import { $ as parse$1, A as cliOptions, B as runAndValidateVerifications, C as execSync, D as getSharedFiles, E as dist, 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 exec, T as templates, U as updateLibraryBuild, V as runCommand, W as updateReadme, X as literal, Y as boolean, Z as nonEmpty, _ as createLoadedAddon, _t as pe, a as setupAddons, at as string, b as getErrorHint, bt as R$1, c as AGENT_NAMES, ct as program, d as installDependencies, dt as Ce, et as picklist, f as installOption, ft as Ee, g as from, gt as le, h as up$2, ht as ge, i as prepareSvApi, it as strictObject, j as errorAndExit, k as buildAndLogArgs, l as addAllowBuildsIfPnpm, lt as Command, m as up$1, mt as Re, n as applyAddons, nt as record, o as createWorkspace, ot as transform, p as packageManagerPrompt, pt as R, q as version, r as orderAddons, rt as safeParse, s as findWorkspaceRoot, st as union, tt as pipe, u as detectPackageManager, ut as Option, vt, w as create$1, x as NonZeroExitError, yt as we, z as parseAddonOptions } from "./engine-CpcTzL2R.mjs";
3
+ import { n as officialAddons$1, t as getAddonDetails } from "./addons-DaktRhvH.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";
@@ -1218,22 +1218,16 @@ function isPrettierInstalled(cwd) {
1218
1218
  /** Nearest dir from `cwd` up to the workspace root with a `format` or `fmt` package.json script. */
1219
1219
  function findFormatScript(cwd) {
1220
1220
  const workspaceRoot = findWorkspaceRoot(cwd);
1221
- let directory = path.resolve(cwd);
1222
- const { root } = path.parse(directory);
1223
- while (directory && directory.length >= workspaceRoot.length) {
1224
- if (fs.existsSync(path.join(directory, "package.json"))) {
1225
- const { data } = loadPackageJson(directory);
1226
- if (data.scripts?.format) return {
1227
- dir: directory,
1228
- name: "format"
1229
- };
1230
- if (data.scripts?.fmt) return {
1231
- dir: directory,
1232
- name: "fmt"
1233
- };
1234
- }
1235
- if (directory === root) break;
1236
- directory = path.dirname(directory);
1221
+ for (const directory of up$2(path.resolve(cwd), { last: workspaceRoot })) if (fs.existsSync(path.join(directory, "package.json"))) {
1222
+ const { data } = loadPackageJson(directory);
1223
+ if (data.scripts?.format) return {
1224
+ dir: directory,
1225
+ name: "format"
1226
+ };
1227
+ if (data.scripts?.fmt) return {
1228
+ dir: directory,
1229
+ name: "fmt"
1230
+ };
1237
1231
  }
1238
1232
  }
1239
1233
  async function withSpinner(startMsg, task) {
@@ -1258,12 +1252,16 @@ async function run(command, args, cwd) {
1258
1252
  });
1259
1253
  return {};
1260
1254
  } catch (e) {
1261
- if (e?.code === "ENOENT") return {
1255
+ if (e instanceof NonZeroExitError) {
1256
+ const { stdout, stderr } = e.output ?? {};
1257
+ return { error: [stderr, stdout].filter(Boolean).join("\n").trim() };
1258
+ }
1259
+ if (!isNodeError(e)) return { error: "unknown error" };
1260
+ if (e.code === "ENOENT") return {
1262
1261
  notFound: true,
1263
1262
  error: `${command} not found`
1264
1263
  };
1265
- const output = e?.output;
1266
- return { error: [output?.stderr, output?.stdout].filter(Boolean).join("\n").trim() || (e instanceof Error ? e.message : "unknown error") };
1264
+ return { error: e.message };
1267
1265
  }
1268
1266
  }
1269
1267
  //#endregion
@@ -1519,6 +1517,32 @@ async function resolveNonOfficialAddons(refs, downloadCheck) {
1519
1517
  }
1520
1518
  return selectedAddons;
1521
1519
  }
1520
+ /**
1521
+ * Walks the `dependsOn` graph and returns the first cycle found as a path
1522
+ * (e.g. `['a', 'b', 'a']`), or `undefined` when the graph is acyclic.
1523
+ */
1524
+ function findDependencyCycle(addonIds, setupResults) {
1525
+ const known = new Set(addonIds);
1526
+ const settled = /* @__PURE__ */ new Set();
1527
+ const path = [];
1528
+ const visit = (id) => {
1529
+ if (settled.has(id)) return;
1530
+ const cycleStart = path.indexOf(id);
1531
+ if (cycleStart !== -1) return [...path.slice(cycleStart), id];
1532
+ path.push(id);
1533
+ for (const depId of setupResults[id]?.dependsOn ?? []) {
1534
+ if (!known.has(depId)) continue;
1535
+ const cycle = visit(depId);
1536
+ if (cycle) return cycle;
1537
+ }
1538
+ path.pop();
1539
+ settled.add(id);
1540
+ };
1541
+ for (const id of addonIds) {
1542
+ const cycle = visit(id);
1543
+ if (cycle) return cycle;
1544
+ }
1545
+ }
1522
1546
  async function promptAddonQuestions({ options, loadedAddons, workspace }) {
1523
1547
  const addons = [...loadedAddons];
1524
1548
  const emptyAnswersReducer = (acc, id) => {
@@ -1612,7 +1636,6 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
1612
1636
  const additionalSetupResults = await setupAddons(missingSetupResults, workspace);
1613
1637
  Object.assign(setupResults, additionalSetupResults);
1614
1638
  }
1615
- const dependencyChains = /* @__PURE__ */ new Map();
1616
1639
  let hasNewDependencies = true;
1617
1640
  while (hasNewDependencies) {
1618
1641
  hasNewDependencies = false;
@@ -1623,30 +1646,9 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
1623
1646
  if (!setupResult) errorAndExit(`Setup result missing for addon: ${addonId}`);
1624
1647
  const missingDependencies = setupResult.dependsOn.filter((depId) => !addons.some((a) => a.addon.id === depId));
1625
1648
  for (const depId of missingDependencies) {
1626
- const addonChain = dependencyChains.get(addonId) ?? /* @__PURE__ */ new Set();
1627
- if (addonChain.has(depId)) {
1628
- const cyclePath = [
1629
- ...addonChain,
1630
- addonId,
1631
- depId
1632
- ].join(" → ");
1633
- errorAndExit(`Circular dependency detected: ${cyclePath}\nAdd-ons cannot have circular dependencies.`);
1634
- }
1635
- const depChain = new Set(addonChain);
1636
- depChain.add(addonId);
1637
- dependencyChains.set(depId, depChain);
1649
+ if (!officialAddons.some((a) => a.id === depId)) errorAndExit(`'${color.addon(addonId)}' depends on '${color.addon(depId)}', which is not an official add-on.\nAdd it to the command explicitly.`);
1638
1650
  hasNewDependencies = true;
1639
- if (!addons.find((a) => a.addon.id === depId)) {
1640
- if (!officialAddons.find((a) => a.id === depId)) throw new Error(`'${addonId}' depends on an invalid add-on: '${depId}'`);
1641
- const officialAddonDetails = getAddonDetails(depId);
1642
- addons.push(createLoadedAddon(officialAddonDetails));
1643
- answers[depId] = {};
1644
- continue;
1645
- }
1646
- if (await le({ message: `The ${color.addon(addonId)} add-on requires ${color.addon(depId)} to also be setup. ${color.success("Include it?")}` }) !== true) {
1647
- ge("Operation cancelled.");
1648
- V.exit(1);
1649
- }
1651
+ addons.push(createLoadedAddon(getAddonDetails(depId)));
1650
1652
  answers[depId] = {};
1651
1653
  }
1652
1654
  }
@@ -1656,6 +1658,8 @@ async function promptAddonQuestions({ options, loadedAddons, workspace }) {
1656
1658
  Object.assign(setupResults, newSetupResults);
1657
1659
  }
1658
1660
  }
1661
+ const cycle = findDependencyCycle(addons.map((a) => a.addon.id), setupResults);
1662
+ if (cycle) errorAndExit(`Circular dependency detected: ${cycle.map((id) => color.addon(id)).join(" → ")}\nAdd-ons cannot have circular dependencies.`);
1659
1663
  const addonDefinitions = addons.map((a) => a.addon);
1660
1664
  const verifications = [...verifyCleanWorkingDirectory(options.cwd, options.gitCheck), ...verifyUnsupportedAddons(addonDefinitions, setupResults)];
1661
1665
  await runAndValidateVerifications(verifications);
@@ -3003,21 +3007,9 @@ const migrationTasks = [
3003
3007
  },
3004
3008
  {
3005
3009
  title: "Move adapter-node `ORIGIN` to `paths.origin`",
3006
- checks: [{
3007
- include: [
3008
- "Dockerfile*",
3009
- "**/Dockerfile*",
3010
- "**/*.{js,ts,mjs,mts,json,jsonc,yml,yaml,toml}"
3011
- ],
3012
- patterns: [
3013
- /\bprocess\.env\.ORIGIN\b/,
3014
- /\benv\s*\[\s*['"]ORIGIN['"]\s*\]/,
3015
- /^\s*(?:ENV|ARG)\s+ORIGIN\b/m,
3016
- /^\s*ORIGIN\s*[:=]/m
3017
- ]
3018
- }],
3010
+ dependency: "@sveltejs/adapter-node",
3019
3011
  summary: "The adapter-node `ORIGIN` environment variable is removed.",
3020
- instructions: "If this value configures adapter-node, move the public-facing origin to `paths.origin` in `sveltekit(...)`. Remove the environment variable only after confirming it has no unrelated use.",
3012
+ instructions: "Find where `ORIGIN` is set (`.env` files, scripts, hosting dashboard, ...) and move the public-facing origin to `paths.origin` in `sveltekit(...)`. Do not delete `ORIGIN`: it is ignored by adapter-node now and may have other uses.",
3021
3013
  links: guideLink("Adapters-adapter-node")
3022
3014
  },
3023
3015
  {
@@ -3098,9 +3090,10 @@ const migrationTasks = [
3098
3090
  var collect_migration_instructions_default = defineMigrationTask({
3099
3091
  id: "collect-migration-instructions",
3100
3092
  description: `Collect instructions for non-automated migration tasks; creates ${REPORT_PATH} whose instructions you should follow to complete the migration`,
3101
- run: ({ sv }) => {
3093
+ run: ({ sv, dependencyVersion }) => {
3102
3094
  const findings = [];
3103
3095
  for (const task of migrationTasks) {
3096
+ if (task.dependency && !dependencyVersion(task.dependency)) continue;
3104
3097
  const files = /* @__PURE__ */ new Set();
3105
3098
  if (!task.checks) findings.push({
3106
3099
  task,
@@ -3853,7 +3846,7 @@ var lib_alias_default = defineMigrationTask({
3853
3846
  };
3854
3847
  }));
3855
3848
  sv.files({
3856
- include: `${directory.src}/**/*.{svelte,svelte.ts,svelte.js,ts,js,svx,md}`,
3849
+ include: `**/*.{svelte,svelte.ts,svelte.js,ts,js,svx,md}`,
3857
3850
  where: (content) => content.includes("$lib")
3858
3851
  }, (content, file) => {
3859
3852
  let styleLibPath = path.posix.relative(path.posix.dirname(file.replaceAll("\\", "/")), directory.lib.replaceAll("\\", "/"));
@@ -3866,7 +3859,7 @@ var lib_alias_default = defineMigrationTask({
3866
3859
  ".ts",
3867
3860
  "/index.js",
3868
3861
  "/index.ts"
3869
- ]) if (fs.existsSync(`${cwd}/${directory.lib}/${import_path}${ending}`)) return match.slice(0, -1) + ending.replace(".ts", ".js") + match.slice(-1);
3862
+ ]) if (fs.existsSync(path.join(cwd, directory.lib, import_path + ending))) return match.slice(0, -1) + ending.replace(".ts", ".js") + match.slice(-1);
3870
3863
  }
3871
3864
  return match;
3872
3865
  });
@@ -3879,8 +3872,8 @@ var lib_alias_default = defineMigrationTask({
3879
3872
  const KIT3_MIN_VERSIONS = {
3880
3873
  vite: "^8.0.12",
3881
3874
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
3882
- svelte: "^5.56.4",
3883
- "@sveltejs/package": "^2.5.8",
3875
+ svelte: "^5.57.1",
3876
+ "@sveltejs/package": "^3.0.0",
3884
3877
  "svelte-check": "^4.7.5",
3885
3878
  typescript: "^6.0.0"
3886
3879
  };
@@ -3962,6 +3955,7 @@ function migrateMatcher(cwd, file, target, context) {
3962
3955
  const importDeclarations = [];
3963
3956
  const body = [];
3964
3957
  const paramMatcherTypes = /* @__PURE__ */ new Set(["ParamMatcher"]);
3958
+ const typescript = target.endsWith(".ts");
3965
3959
  let declaresMatch = false;
3966
3960
  let exportsMatch = false;
3967
3961
  for (const statement of parsed.ast.body) {
@@ -3984,7 +3978,7 @@ function migrateMatcher(cwd, file, target, context) {
3984
3978
  if (statement.type === "ExportAllDeclaration") throw new Error(`Cannot migrate '${file}' because it re-exports another module`);
3985
3979
  if (statement.type === "ExportNamedDeclaration") {
3986
3980
  if (statement.declaration) {
3987
- stripParamMatcherType(statement.declaration, paramMatcherTypes);
3981
+ stripParamMatcherType(statement.declaration, paramMatcherTypes, typescript);
3988
3982
  if (declares(statement.declaration, "match")) {
3989
3983
  declaresMatch = true;
3990
3984
  exportsMatch = true;
@@ -3993,7 +3987,7 @@ function migrateMatcher(cwd, file, target, context) {
3993
3987
  } else exportsMatch ||= statement.specifiers.some((specifier) => specifier.exported.type === "Identifier" && specifier.exported.name === "match");
3994
3988
  continue;
3995
3989
  }
3996
- stripParamMatcherType(statement, paramMatcherTypes);
3990
+ stripParamMatcherType(statement, paramMatcherTypes, typescript);
3997
3991
  declaresMatch ||= declares(statement, "match");
3998
3992
  body.push(statement);
3999
3993
  }
@@ -4092,13 +4086,27 @@ function generateImportCode(context) {
4092
4086
  for (const source of context.sideEffectImports) lines.push(`import ${quoteString(source)};`);
4093
4087
  return lines;
4094
4088
  }
4095
- function stripParamMatcherType(node, paramMatcherTypes) {
4089
+ function stripParamMatcherType(node, paramMatcherTypes, typescript) {
4090
+ if (node.type === "FunctionDeclaration") {
4091
+ if (typescript && node.id?.name === "match") annotateParam(node);
4092
+ return;
4093
+ }
4096
4094
  if (node.type !== "VariableDeclaration") return;
4097
4095
  const declaration = node.declarations.find((declaration) => declaration.id.type === "Identifier" && declaration.id.name === "match");
4098
4096
  if (!declaration || declaration.id.type !== "Identifier") return;
4099
4097
  const annotation = declaration.id.typeAnnotation?.typeAnnotation;
4100
4098
  if (annotation?.type === "TSTypeReference" && annotation.typeName.type === "Identifier" && paramMatcherTypes.has(annotation.typeName.name)) delete declaration.id.typeAnnotation;
4101
4099
  if ((declaration.init?.type === "TSSatisfiesExpression" || declaration.init?.type === "TSAsExpression") && declaration.init.typeAnnotation.type === "TSTypeReference" && declaration.init.typeAnnotation.typeName.type === "Identifier" && paramMatcherTypes.has(declaration.init.typeAnnotation.typeName.name)) declaration.init = declaration.init.expression;
4100
+ if (typescript) annotateParam(declaration.init);
4101
+ }
4102
+ function annotateParam(init) {
4103
+ if (init?.type !== "ArrowFunctionExpression" && init?.type !== "FunctionExpression" && init?.type !== "FunctionDeclaration") return;
4104
+ const [param] = init.params;
4105
+ if (param?.type !== "Identifier" || param.typeAnnotation) return;
4106
+ param.typeAnnotation = {
4107
+ type: "TSTypeAnnotation",
4108
+ typeAnnotation: { type: "TSStringKeyword" }
4109
+ };
4102
4110
  }
4103
4111
  function stripParamMatcherComments(content) {
4104
4112
  return content.replace(/\/\*\*[\s\S]*?\*\//g, (comment) => {
@@ -4479,18 +4487,29 @@ function gotoOptions(replace, state) {
4479
4487
  function migrateNavigationHook(call) {
4480
4488
  const callback = call.arguments[0];
4481
4489
  if (callback?.type !== "ArrowFunctionExpression" && callback?.type !== "FunctionExpression") return false;
4482
- const shallow = shallowTest(callback);
4483
- if (!shallow) return false;
4490
+ const properties = navigationHookProperties(callback);
4491
+ if (!properties) return false;
4492
+ const [shallow, type] = properties;
4484
4493
  const guard = {
4485
4494
  type: "IfStatement",
4486
- test: shallow,
4495
+ test: {
4496
+ type: "LogicalExpression",
4497
+ operator: "&&",
4498
+ left: shallow,
4499
+ right: {
4500
+ type: "BinaryExpression",
4501
+ operator: "===",
4502
+ left: type,
4503
+ right: js.common.createLiteral("goto")
4504
+ }
4505
+ },
4487
4506
  consequent: {
4488
4507
  type: "ReturnStatement",
4489
4508
  argument: null
4490
4509
  }
4491
4510
  };
4492
4511
  if (callback.body.type === "BlockStatement") {
4493
- if (startsWithShallowGuard(callback.body, shallow)) return false;
4512
+ if (startsWithNavigationGuard(callback.body, shallow, type)) return false;
4494
4513
  callback.body.body.unshift(guard);
4495
4514
  } else callback.body = {
4496
4515
  type: "BlockStatement",
@@ -4501,35 +4520,43 @@ function migrateNavigationHook(call) {
4501
4520
  };
4502
4521
  return true;
4503
4522
  }
4504
- function shallowTest(callback) {
4523
+ function navigationHookProperties(callback) {
4505
4524
  const parameter = callback.params[0];
4506
4525
  if (!parameter) {
4507
4526
  callback.params.push({
4508
4527
  type: "ObjectPattern",
4509
- properties: [patternProperty("shallow")]
4528
+ properties: [patternProperty("shallow"), patternProperty("type")]
4510
4529
  });
4511
- return js.variables.createIdentifier("shallow");
4530
+ return [js.variables.createIdentifier("shallow"), js.variables.createIdentifier("type")];
4512
4531
  }
4513
- if (parameter.type === "Identifier") return member(parameter.name, "shallow");
4514
- if (parameter.type === "AssignmentPattern" && parameter.left.type === "Identifier") return member(parameter.left.name, "shallow");
4532
+ if (parameter.type === "Identifier") return [member(parameter.name, "shallow"), member(parameter.name, "type")];
4533
+ if (parameter.type === "AssignmentPattern" && parameter.left.type === "Identifier") return [member(parameter.left.name, "shallow"), member(parameter.left.name, "type")];
4515
4534
  if (parameter.type !== "ObjectPattern") return void 0;
4535
+ const shallow = patternIdentifier(parameter, "shallow");
4536
+ const type = patternIdentifier(parameter, "type");
4537
+ if (shallow === null || type === null) return void 0;
4538
+ for (const name of [shallow ? void 0 : "shallow", type ? void 0 : "type"]) {
4539
+ if (!name) continue;
4540
+ const restIndex = parameter.properties.findIndex((entry) => entry.type === "RestElement");
4541
+ const property = patternProperty(name);
4542
+ if (restIndex === -1) parameter.properties.push(property);
4543
+ else parameter.properties.splice(restIndex, 0, property);
4544
+ }
4545
+ return [shallow ?? js.variables.createIdentifier("shallow"), type ?? js.variables.createIdentifier("type")];
4546
+ }
4547
+ function patternIdentifier(parameter, name) {
4516
4548
  for (const entry of parameter.properties) {
4517
4549
  if (entry.type !== "Property") continue;
4518
4550
  const key = entry.key;
4519
- if ((key.type !== "Identifier" || key.name !== "shallow") && (key.type !== "Literal" || key.value !== "shallow")) continue;
4551
+ if ((key.type !== "Identifier" || key.name !== name) && (key.type !== "Literal" || key.value !== name)) continue;
4520
4552
  if (entry.value.type === "Identifier") return js.variables.createIdentifier(entry.value.name);
4521
4553
  if (entry.value.type === "AssignmentPattern" && entry.value.left.type === "Identifier") return js.variables.createIdentifier(entry.value.left.name);
4522
- return;
4554
+ return null;
4523
4555
  }
4524
- const restIndex = parameter.properties.findIndex((entry) => entry.type === "RestElement");
4525
- const shallowProperty = patternProperty("shallow");
4526
- if (restIndex === -1) parameter.properties.push(shallowProperty);
4527
- else parameter.properties.splice(restIndex, 0, shallowProperty);
4528
- return js.variables.createIdentifier("shallow");
4529
4556
  }
4530
- function startsWithShallowGuard(body, shallow) {
4557
+ function startsWithNavigationGuard(body, shallow, type) {
4531
4558
  const first = body.body[0];
4532
- return first?.type === "IfStatement" && first.consequent.type === "ReturnStatement" && first.consequent.argument === null && sameExpression(first.test, shallow);
4559
+ return first?.type === "IfStatement" && first.consequent.type === "ReturnStatement" && first.consequent.argument === null && first.test.type === "LogicalExpression" && first.test.operator === "&&" && sameExpression(first.test.left, shallow) && first.test.right.type === "BinaryExpression" && first.test.right.operator === "===" && first.test.right.left.type !== "PrivateIdentifier" && sameExpression(first.test.right.left, type) && first.test.right.right.type === "Literal" && first.test.right.right.value === "goto";
4533
4560
  }
4534
4561
  function sameExpression(left, right) {
4535
4562
  if (left.type === "Identifier" && right.type === "Identifier") return left.name === right.name;
@@ -4565,7 +4592,15 @@ var svelte_config_default = defineMigrationTask({
4565
4592
  run: ({ sv, cwd }) => {
4566
4593
  const configSource = svelteConfig.find(cwd);
4567
4594
  if (!configSource) return;
4568
- if (configSource.kind === "vite") return;
4595
+ if (configSource.kind === "vite") {
4596
+ svelteConfig.edit({
4597
+ sv,
4598
+ cwd
4599
+ }, ({ config }) => {
4600
+ if (!removeFilesLib(config)) return false;
4601
+ });
4602
+ return;
4603
+ }
4569
4604
  const originalConfigObject = svelteConfig.read(cwd);
4570
4605
  if (!originalConfigObject) return;
4571
4606
  sv.removeFile(configSource.path);
@@ -4580,6 +4615,16 @@ var svelte_config_default = defineMigrationTask({
4580
4615
  const originalStatements = [];
4581
4616
  for (const node of originalConfigObject.ast.body) if (node.type === "ImportDeclaration") originalImports.push(node);
4582
4617
  else if (node.type !== "ExportDefaultDeclaration" && node !== configDeclaration) originalStatements.push(node);
4618
+ const existingBindings = js.scope.topLevelBindings([ast]);
4619
+ const movedProgram = {
4620
+ ...originalConfigObject.ast,
4621
+ body: [...originalImports, ...originalStatements]
4622
+ };
4623
+ const movedBindings = js.scope.topLevelBindings([movedProgram]);
4624
+ const usedBindings = /* @__PURE__ */ new Set([...existingBindings, ...movedBindings]);
4625
+ const renames = /* @__PURE__ */ new Map();
4626
+ for (const name of movedBindings) if (existingBindings.has(name)) renames.set(name, js.identifiers.uniqueName(name, usedBindings));
4627
+ js.identifiers.renameReferences([originalConfigObject.ast], renames);
4583
4628
  ast.body.unshift(...originalImports);
4584
4629
  const exportIndex = ast.body.findIndex((node) => node.type === "ExportDefaultDeclaration");
4585
4630
  ast.body.splice(exportIndex, 0, ...originalStatements);
@@ -4590,24 +4635,24 @@ var svelte_config_default = defineMigrationTask({
4590
4635
  let trustsAllOrigins = false;
4591
4636
  for (const prop of newConfigProperties) {
4592
4637
  if (prop.type !== "Property") continue;
4593
- if (prop.key.type !== "Identifier") continue;
4594
- if (prop.key.name === "kit") continue;
4638
+ const key = js.object.propertyName(prop);
4639
+ if (!key || key === "kit") continue;
4595
4640
  const propAttachment = attachments.get(prop);
4596
- keyedConfig[prop.key.name] = prop.value;
4597
- if (propAttachment) propComments.set(prop.key.name, propAttachment);
4641
+ keyedConfig[key] = prop.value;
4642
+ if (propAttachment) propComments.set(key, propAttachment);
4598
4643
  }
4599
4644
  for (const [key, value] of Object.entries(keyedConfig)) {
4600
4645
  if (key === "experimental" && value.type === "ObjectExpression") {
4601
- removeProperty(value, "handleRenderingErrors");
4602
- removeProperty(value, "instrumentation");
4603
- const index = value.properties.findIndex((prop) => prop.type === "Property" && prop.key.type === "Identifier" && prop.key.name === "tracing");
4604
- if (index !== -1) {
4605
- keyedConfig.tracing = value.properties[index].value;
4606
- value.properties.splice(index, 1);
4646
+ js.object.removeProperty(value, { name: "handleRenderingErrors" });
4647
+ js.object.removeProperty(value, { name: "instrumentation" });
4648
+ const tracing = js.object.findProperty(value, { name: "tracing" });
4649
+ if (tracing) {
4650
+ keyedConfig.tracing = tracing.value;
4651
+ js.object.removeProperty(value, { name: "tracing" });
4607
4652
  }
4608
4653
  }
4609
4654
  if (key === "prerender" && value.type === "ObjectExpression") {
4610
- const originProp = value.properties.find((prop) => prop.type === "Property" && prop.key.type === "Identifier" && prop.key.name === "origin");
4655
+ const originProp = js.object.findProperty(value, { name: "origin" });
4611
4656
  if (originProp) {
4612
4657
  keyedConfig.paths ??= {
4613
4658
  type: "ObjectExpression",
@@ -4625,14 +4670,22 @@ var svelte_config_default = defineMigrationTask({
4625
4670
  shorthand: false,
4626
4671
  computed: false
4627
4672
  });
4628
- removeProperty(value, "origin");
4673
+ js.object.removeProperty(value, { name: "origin" });
4629
4674
  if (value.properties.length === 0) delete keyedConfig.prerender;
4630
4675
  }
4631
4676
  }
4677
+ if (key === "files" && value.type === "ObjectExpression") {
4678
+ js.object.removeProperty(value, { name: "lib" });
4679
+ if (value.properties.length === 0) delete keyedConfig.files;
4680
+ }
4632
4681
  if (key === "csrf" && value.type === "ObjectExpression") {
4633
4682
  const checkOrigin = findDisabledCheckOrigin(value);
4634
4683
  if (checkOrigin) {
4635
- checkOrigin.key.name = "trustedOrigins";
4684
+ checkOrigin.key = {
4685
+ type: "Identifier",
4686
+ name: "trustedOrigins"
4687
+ };
4688
+ checkOrigin.computed = false;
4636
4689
  checkOrigin.value = {
4637
4690
  type: "ArrayExpression",
4638
4691
  elements: [{
@@ -4663,7 +4716,10 @@ var svelte_config_default = defineMigrationTask({
4663
4716
  apply(node, attachments.get(node));
4664
4717
  if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "sveltekit" && node.arguments[0]?.type === "ObjectExpression") rootConfig = node.arguments[0];
4665
4718
  });
4666
- for (const prop of rootConfig?.properties ?? []) if (prop.type === "Property" && prop.key.type === "Identifier") apply(prop, propComments.get(prop.key.name));
4719
+ for (const prop of rootConfig?.properties ?? []) if (prop.type === "Property") {
4720
+ const key = js.object.propertyName(prop);
4721
+ if (key) apply(prop, propComments.get(key));
4722
+ }
4667
4723
  });
4668
4724
  let addedConfigLoader = false;
4669
4725
  sv.files({
@@ -4713,10 +4769,19 @@ function forEachNode(root, visit) {
4713
4769
  forEachNode(node[key], visit);
4714
4770
  }
4715
4771
  }
4716
- /** Removes a statically named property from an object literal. */
4717
- function removeProperty(value, name) {
4718
- const index = value.properties.findIndex((prop) => prop.type === "Property" && prop.key.type === "Identifier" && prop.key.name === name);
4719
- if (index !== -1) value.properties.splice(index, 1);
4772
+ /**
4773
+ * Drops the `files.lib` option from a kit config object, deleting `files` itself when it only
4774
+ * contained `lib`.
4775
+ * Returns whether anything was removed.
4776
+ */
4777
+ function removeFilesLib(config) {
4778
+ const filesProp = js.object.findProperty(config, { name: "files" });
4779
+ if (!filesProp) return false;
4780
+ const files = filesProp.value;
4781
+ if (files.type !== "ObjectExpression") return false;
4782
+ if (!js.object.removeProperty(files, { name: "lib" })) return false;
4783
+ if (files.properties.length === 0) js.object.removeProperty(config, { name: "files" });
4784
+ return true;
4720
4785
  }
4721
4786
  /**
4722
4787
  * Maps each source comment to the node it documents, returned keyed by node identity. A comment is
@@ -4772,7 +4837,8 @@ function collectComments(ast, source) {
4772
4837
  }
4773
4838
  /** Returns the `checkOrigin: false` property of a `csrf` object, if present. */
4774
4839
  function findDisabledCheckOrigin(value) {
4775
- return value.properties.find((p) => p.type === "Property" && p.key.type === "Identifier" && p.key.name === "checkOrigin" && p.value.type === "Literal" && p.value.value === false);
4840
+ const property = js.object.findProperty(value, { name: "checkOrigin" });
4841
+ return property?.value.type === "Literal" && property.value.value === false ? property : void 0;
4776
4842
  }
4777
4843
  //#endregion
4778
4844
  //#region src/migrate/migrations/sveltekit-3/tasks/tsconfig.ts
@@ -4800,6 +4866,20 @@ const INHERITED_OPTIONS = {
4800
4866
  target: "esnext",
4801
4867
  verbatimModuleSyntax: true
4802
4868
  };
4869
+ /**
4870
+ * Root entries type-checked by the Kit 2 generated config (vite config, `test`, `tests`), plus the
4871
+ * configs `sv create` adds to `include`. Only the ones present in the project are kept.
4872
+ */
4873
+ const ROOT_INCLUDES = [
4874
+ "vite.config.ts",
4875
+ "vite.config.js",
4876
+ "drizzle.config.ts",
4877
+ "drizzle.config.js",
4878
+ "playwright.config.ts",
4879
+ "playwright.config.js",
4880
+ "test",
4881
+ "tests"
4882
+ ];
4803
4883
  var tsconfig_default = defineMigrationTask({
4804
4884
  id: "tsconfig",
4805
4885
  description: "Extend the generated $app/tsconfig instead of .svelte-kit/tsconfig.json",
@@ -4814,11 +4894,11 @@ var tsconfig_default = defineMigrationTask({
4814
4894
  extended[index] = PARENT_CONFIG;
4815
4895
  data.extends = Array.isArray(data.extends) ? extended : PARENT_CONFIG;
4816
4896
  }
4817
- const include = data.include ??= ["src"];
4897
+ const include = data.include ??= ["src", ...ROOT_INCLUDES.filter((entry) => fs.existsSync(path.join(cwd, entry)))];
4818
4898
  include.push(...moved.filter((entry) => !include.includes(entry)));
4819
4899
  if (data.compilerOptions?.types) {
4820
4900
  const types = data.compilerOptions.types;
4821
- if (!types.includes("$app/types")) types.push("$app/types");
4901
+ if (!types.includes("$app/types")) types.unshift("$app/types");
4822
4902
  }
4823
4903
  for (const [key, value] of Object.entries(data.compilerOptions ?? {})) if (INHERITED_OPTIONS[key] === value) delete data.compilerOptions[key];
4824
4904
  }));