sv 1.1.1 → 1.2.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.
@@ -1,4 +1,4 @@
1
- import { D as getSharedFiles, pt as R, v as defineAddon, y as defineAddonOptions } from "./engine-CpcTzL2R.mjs";
1
+ import { E as getSharedFiles, _ as defineAddon, mt as R, v as defineAddonOptions } from "./engine-0i6PA_0L.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";
@@ -713,11 +713,11 @@ const addon$7 = defineAddon({
713
713
  }
714
714
  });
715
715
  const generateEnv$1 = (demoGithub, isExample) => transforms.text(({ content, text }) => {
716
- content = text.upsert(content, "ORIGIN", {
716
+ content = text.add(content, "ORIGIN", {
717
717
  value: isExample ? `""` : `"http://localhost:5173"`,
718
718
  separator: true
719
719
  });
720
- content = text.upsert(content, "BETTER_AUTH_SECRET", {
720
+ content = text.add(content, "BETTER_AUTH_SECRET", {
721
721
  value: isExample ? `""` : `"${crypto.randomUUID()}"`,
722
722
  comment: [
723
723
  "Better Auth",
@@ -727,11 +727,11 @@ const generateEnv$1 = (demoGithub, isExample) => transforms.text(({ content, tex
727
727
  separator: true
728
728
  });
729
729
  if (demoGithub) {
730
- content = text.upsert(content, "GITHUB_CLIENT_ID", {
730
+ content = text.add(content, "GITHUB_CLIENT_ID", {
731
731
  value: `""`,
732
732
  comment: "GitHub OAuth\n# https://www.better-auth.com/docs/authentication/github"
733
733
  });
734
- content = text.upsert(content, "GITHUB_CLIENT_SECRET", { value: `""` });
734
+ content = text.add(content, "GITHUB_CLIENT_SECRET", { value: `""` });
735
735
  }
736
736
  return content;
737
737
  });
@@ -1052,10 +1052,10 @@ const addon$6 = defineAddon({
1052
1052
  json.packageScriptsUpsert(data, "db:migrate", "drizzle-kit migrate");
1053
1053
  json.packageScriptsUpsert(data, "db:studio", "drizzle-kit studio");
1054
1054
  }));
1055
- if (Boolean(dependencyVersion("prettier"))) sv.file(".prettierignore", transforms.text(({ content, text }) => text.upsert(content, "/drizzle/")));
1055
+ if (Boolean(dependencyVersion("prettier"))) sv.file(".prettierignore", transforms.text(({ content, text }) => text.add(content, "/drizzle/")));
1056
1056
  if (options.database === "sqlite") sv.file(file.gitignore, transforms.text(({ content, text }) => {
1057
1057
  if (content.length === 0) return false;
1058
- return text.upsert(content, "*.db", { comment: "SQLite" });
1058
+ return text.add(content, "*.db", { comment: "SQLite" });
1059
1059
  }));
1060
1060
  sv.file(paths["drizzle config"], transforms.script(({ ast, js }) => {
1061
1061
  const d1 = options.database === "d1";
@@ -1333,13 +1333,13 @@ const addon$6 = defineAddon({
1333
1333
  const generateEnv = (opts, isExample) => transforms.text(({ content, text }) => {
1334
1334
  const DB_URL_KEY = "DATABASE_URL";
1335
1335
  if (opts.database === "d1") {
1336
- content = text.upsert(content, "CLOUDFLARE_ACCOUNT_ID", {
1336
+ content = text.add(content, "CLOUDFLARE_ACCOUNT_ID", {
1337
1337
  value: "\"\"",
1338
1338
  comment: ["Cloudflare D1"],
1339
1339
  separator: true
1340
1340
  });
1341
- content = text.upsert(content, "CLOUDFLARE_DATABASE_ID", { value: "\"\"" });
1342
- content = text.upsert(content, "CLOUDFLARE_D1_TOKEN", { value: "\"\"" });
1341
+ content = text.add(content, "CLOUDFLARE_DATABASE_ID", { value: "\"\"" });
1342
+ content = text.add(content, "CLOUDFLARE_D1_TOKEN", { value: "\"\"" });
1343
1343
  return content;
1344
1344
  }
1345
1345
  let value;
@@ -1371,12 +1371,12 @@ const generateEnv = (opts, isExample) => transforms.text(({ content, text }) =>
1371
1371
  value = "\"postgres://user:password@host:port/db-name\"";
1372
1372
  comment.push("Replace with your DB credentials!");
1373
1373
  } else value = "";
1374
- content = text.upsert(content, DB_URL_KEY, {
1374
+ content = text.add(content, DB_URL_KEY, {
1375
1375
  value,
1376
1376
  comment,
1377
1377
  separator: true
1378
1378
  });
1379
- if (opts.sqlite === "turso") content = text.upsert(content, "DATABASE_AUTH_TOKEN", { value: isExample ? `""` : `"${crypto.randomUUID()}"` });
1379
+ if (opts.sqlite === "turso") content = text.add(content, "DATABASE_AUTH_TOKEN", { value: isExample ? `""` : `"${crypto.randomUUID()}"` });
1380
1380
  return content;
1381
1381
  });
1382
1382
  //#endregion
@@ -1448,6 +1448,13 @@ var eslint_default = defineAddon({
1448
1448
  language,
1449
1449
  entry: "node"
1450
1450
  });
1451
+ addToTypeConfigInclude({
1452
+ sv,
1453
+ cwd,
1454
+ language,
1455
+ kitVersion: dependencyVersion("@sveltejs/kit"),
1456
+ entry: "eslint.config.js"
1457
+ });
1451
1458
  if (typescript) sv.devDependency("typescript-eslint", "^8.60.1");
1452
1459
  if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^10.1.8");
1453
1460
  sv.file(file.package, transforms.json(({ data, json }) => {
@@ -1766,8 +1773,8 @@ const addon$4 = defineAddon({
1766
1773
  }));
1767
1774
  sv.file(file.gitignore, transforms.text(({ content, text }) => {
1768
1775
  if (!content) return false;
1769
- content = text.upsert(content, paraglideOutDir, { comment: "Paraglide" });
1770
- content = text.upsert(content, "project.inlang/cache/");
1776
+ content = text.add(content, paraglideOutDir, { comment: "Paraglide" });
1777
+ content = text.add(content, "project.inlang/cache/");
1771
1778
  return content;
1772
1779
  }));
1773
1780
  const { validLanguageTags } = parseLanguageTagInput(options.languageTags);
@@ -1864,7 +1871,7 @@ const addon$3 = defineAddon({
1864
1871
  }));
1865
1872
  sv.file(file.gitignore, transforms.text(({ content, text }) => {
1866
1873
  if (!content) return false;
1867
- return text.upsert(content, "test-results", { comment: "Playwright" });
1874
+ return text.add(content, "test-results", { comment: "Playwright" });
1868
1875
  }));
1869
1876
  const withDemo = isKit && options.demo;
1870
1877
  const demo = defineDemoPage("playwright", language, directory.kitRoutes);
@@ -1933,7 +1940,7 @@ var prettier_default = defineAddon({
1933
1940
  shortDescription: "formatter",
1934
1941
  homepage: "https://prettier.io",
1935
1942
  options: {},
1936
- run: ({ sv, dependencyVersion, file }) => {
1943
+ run: ({ sv, dependencyVersion, file, cwd, language }) => {
1937
1944
  const tailwindcssInstalled = Boolean(dependencyVersion("tailwindcss"));
1938
1945
  if (tailwindcssInstalled) sv.devDependency("prettier-plugin-tailwindcss", "^0.8.0");
1939
1946
  sv.devDependency("prettier", "^3.8.3");
@@ -1956,6 +1963,13 @@ var prettier_default = defineAddon({
1956
1963
  tailwind: tailwindcssInstalled,
1957
1964
  stylesheet: tailwindcssInstalled ? file.getRelative({ to: file.stylesheet }) : void 0
1958
1965
  }));
1966
+ addToTypeConfigInclude({
1967
+ sv,
1968
+ cwd,
1969
+ language,
1970
+ kitVersion: dependencyVersion("@sveltejs/kit"),
1971
+ entry: prettierConfigPath()
1972
+ });
1959
1973
  const eslintInfo = checkEslint(dependencyVersion("eslint"));
1960
1974
  sv.file(file.package, transforms.json(({ data, json }) => {
1961
1975
  json.packageScriptsUpsert(data, "lint", "prettier --check .", { mode: "prepend" });
@@ -1993,12 +2007,13 @@ var storybook_default = defineAddon({
1993
2007
  runsAfter(ADDON_IDS.vitest);
1994
2008
  runsAfter(ADDON_IDS.eslint);
1995
2009
  },
1996
- run: async ({ sv }) => {
2010
+ run: async ({ sv, packageManager }) => {
1997
2011
  const args = [
1998
2012
  `create-storybook@latest`,
1999
2013
  "--skip-install",
2000
2014
  "--no-dev"
2001
2015
  ];
2016
+ if (packageManager === "pnpm") args.unshift("--allow-build=esbuild");
2002
2017
  if (V.env.NODE_ENV?.toLowerCase() === "test") args.push(...["--no-features", "--yes"]);
2003
2018
  await sv.execute(args, "inherit");
2004
2019
  sv.devDependency(`@types/node`, getNodeTypesVersion());
@@ -2017,6 +2032,11 @@ const adapters = [
2017
2032
  package: "@sveltejs/adapter-node",
2018
2033
  version: "^6.0.0"
2019
2034
  },
2035
+ {
2036
+ id: "bun",
2037
+ package: "@sveltejs/adapter-bun",
2038
+ version: "^1.0.0"
2039
+ },
2020
2040
  {
2021
2041
  id: "static",
2022
2042
  package: "@sveltejs/adapter-static",
@@ -2074,14 +2094,6 @@ const addon$2 = defineAddon({
2074
2094
  },
2075
2095
  run: ({ sv, options, packageManager, file, cwd, language }) => {
2076
2096
  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
2097
  sv.devDependency(adapter.package, adapter.version);
2086
2098
  if (options.adapter === "node") {
2087
2099
  sv.devDependency("@types/node", getNodeTypesVersion());
@@ -2092,14 +2104,16 @@ const addon$2 = defineAddon({
2092
2104
  entry: "node"
2093
2105
  });
2094
2106
  }
2095
- if (adapter.package !== "@sveltejs/adapter-auto") sv.file("README.md", transforms.text(({ content }) => content.replace(ADAPTER_HINT_REGEX, "")));
2107
+ let previousAdapter;
2096
2108
  svelteConfig.edit({
2097
2109
  sv,
2098
2110
  cwd
2099
2111
  }, ({ ast, override, js }) => {
2100
- const adapterImports = ast.body.filter((n) => n.type === "ImportDeclaration").find((importDecl) => typeof importDecl.source.value === "string" && importDecl.source.value.startsWith("@sveltejs/adapter-") && importDecl.importKind === "value");
2112
+ 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
2113
  let adapterName = "adapter";
2102
2114
  if (adapterImports) {
2115
+ const foundPackage = adapterImports.source.value;
2116
+ if (typeof foundPackage === "string" && foundPackage !== adapter.package) previousAdapter = foundPackage;
2103
2117
  adapterImports.source.value = adapter.package;
2104
2118
  adapterImports.source.raw = void 0;
2105
2119
  adapterName = (adapterImports.specifiers?.find((s) => s.type === "ImportDefaultSpecifier")).local.name;
@@ -2113,6 +2127,13 @@ const addon$2 = defineAddon({
2113
2127
  useIdentifiers: true
2114
2128
  }) }, adapter.package === "@sveltejs/adapter-auto" ? void 0 : { dropLeadingComments: ["adapter"] });
2115
2129
  });
2130
+ sv.file(file.package, transforms.json(({ data }) => {
2131
+ if (previousAdapter) {
2132
+ delete data["devDependencies"]?.[previousAdapter];
2133
+ delete data["dependencies"]?.[previousAdapter];
2134
+ }
2135
+ }));
2136
+ if (adapter.package !== "@sveltejs/adapter-auto") sv.file("README.md", transforms.text(({ content }) => content.replace(ADAPTER_HINT_REGEX, "")));
2116
2137
  if (adapter.package === "@sveltejs/adapter-cloudflare") {
2117
2138
  sv.devDependency("wrangler", "^4.97.0");
2118
2139
  if (packageManager === "pnpm") sv.file(file.findUp("pnpm-workspace.yaml"), pnpm.allowBuilds({
@@ -2142,25 +2163,20 @@ const addon$2 = defineAddon({
2142
2163
  }
2143
2164
  };
2144
2165
  sv.file(`wrangler.${ext}`, ext === "toml" ? transforms.toml(({ data }) => applyWranglerConfig(data)) : transforms.json(({ data }) => applyWranglerConfig(data)));
2145
- if (file.typeConfig) {
2146
- sv.file(file.package, transforms.json(({ data, json }) => {
2166
+ sv.file(file.package, transforms.json(({ data, json }) => {
2167
+ if (file.typeConfig) {
2147
2168
  json.packageScriptsUpsert(data, "gen", "wrangler types");
2148
2169
  json.packageScriptsUpsert(data, "check", "wrangler types --check", { mode: "prepend" });
2149
2170
  json.packageScriptsUpsert(data, "build", "wrangler types --check", { mode: "prepend" });
2150
- }));
2151
- addToTypeConfigType({
2152
- sv,
2153
- cwd,
2154
- language,
2155
- entry: "./worker-configuration.d.ts"
2156
- });
2157
- sv.file("src/app.d.ts", transforms.script(({ ast, comments, js }) => {
2158
- const platform = js.kit.addGlobalAppInterface(ast, { name: "Platform" });
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
- }
2171
+ }
2172
+ data.scripts.preview = options.cfTarget === "workers" ? "wrangler dev .svelte-kit/cloudflare/_worker.js --port 4173" : "wrangler pages dev .svelte-kit/cloudflare --port 4173";
2173
+ }));
2174
+ if (file.typeConfig) addToTypeConfigType({
2175
+ sv,
2176
+ cwd,
2177
+ language,
2178
+ entry: "./worker-configuration.d.ts"
2179
+ });
2164
2180
  }
2165
2181
  },
2166
2182
  nextSteps({ options, packageManager }) {
@@ -2304,10 +2320,10 @@ const addon = defineAddon({
2304
2320
  json.packageScriptsUpsert(data, "test", "npm run test:unit -- --run", { mode: "prepend" });
2305
2321
  }));
2306
2322
  const examplesDir = `${directory.lib}/vitest-examples`;
2307
- const [ts] = createPrinter(language === "ts");
2323
+ const [ts, jsdocs] = createPrinter(language === "ts", !!file.typeConfig?.endsWith("jsconfig.json"));
2308
2324
  if (unitTesting || componentTesting) sv.file(`${examplesDir}/greet.${language}`, transforms.text(({ content }) => {
2309
2325
  if (content) return false;
2310
- return dedent`
2326
+ return dedent`${jsdocs("/** @param {string} name */\n")}
2311
2327
  export function greet(name${ts(": string")})${ts(": string")} {
2312
2328
  return 'Hello, ' + name + '!';
2313
2329
  }
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 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";
2
+ import { $ as optional, A as buildAndLogArgs, B as parseAddonOptions, C as create$1, D as up$2, E as getSharedFiles, F as getHelpSections, G as updateReadme, H as runCommand, I as getPadding, J as version, K as UnsupportedError, L as helpConfig, M as errorAndExit, N as filePaths, O as from, P as forwardExitCode, Q as nonEmpty, R as isNodeError, S as execSync, T as dist_dir, U as updateAgent, V as runAndValidateVerifications, W as updateLibraryBuild, X as boolean, Y as array, Z as literal, _t as le, a as setupAddons, at as strictObject, b as NonZeroExitError, bt as we, c as AGENT_NAMES, ct as union, d as detectPackageManager, dt as Option, et as parse$1, f as installDependencies, ft as Ce, g as createLoadedAddon, gt as ge, h as up$1, ht as Re, i as prepareSvApi, it as safeParse, j as cliOptions, k as PackageJSONSchema, l as addAllowBuildsIfPnpm, lt as program, m as packageManagerPrompt, mt as R, n as applyAddons, nt as pipe, o as createWorkspace, ot as string, p as installOption, pt as Ee, q as name, r as orderAddons, rt as record, s as findWorkspaceRoot, st as transform, tt as picklist, u as addEngineStrict, ut as Command, vt as pe, w as templates, x as exec, xt as R$1, y as getErrorHint, yt as vt, z as normalizePosix } from "./engine-0i6PA_0L.mjs";
3
+ import { n as officialAddons$1, t as getAddonDetails } from "./addons-Ih-Pmrow.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";
@@ -2380,6 +2380,10 @@ async function createProject(cwd, options) {
2380
2380
  updateReadme(directory, prompt);
2381
2381
  updateAgent(directory, language, packageManager ?? "npm", loadedAddons);
2382
2382
  const addOnNextSteps = getNextSteps(addOnSuccessfulAddons, workspace, answers, addonSetupResults);
2383
+ addEngineStrict({
2384
+ cwd: projectPath,
2385
+ packageManager
2386
+ });
2383
2387
  addAllowBuildsIfPnpm({
2384
2388
  cwd: projectPath,
2385
2389
  packageManager,
@@ -2431,7 +2435,7 @@ async function createVirtualWorkspace({ cwd, template, type }) {
2431
2435
  kitRoutes: "src/routes"
2432
2436
  };
2433
2437
  }
2434
- const templatePackageJsonPath = dist(`templates/${template}`);
2438
+ const templatePackageJsonPath = path.join(dist_dir, "templates", template);
2435
2439
  const { data: packageJson } = loadPackageJson(templatePackageJsonPath);
2436
2440
  override.dependencies = {
2437
2441
  ...packageJson.devDependencies,
@@ -3085,6 +3089,16 @@ const migrationTasks = [
3085
3089
  summary: "Cross-origin mutative requests without a `Content-Type` header are rejected as CSRF.",
3086
3090
  instructions: "Ensure the submission sends an appropriate `Content-Type` header or add the destination to the narrowest possible `csrf.trustedOrigins` allowlist.",
3087
3091
  links: guideLink("Security-Cross-origin-form-submissions-require-a-Content-Type-header")
3092
+ },
3093
+ {
3094
+ title: "Review `redirect(...)` destinations for external URLs",
3095
+ checks: [{
3096
+ include: CODE_FILES,
3097
+ patterns: [/^(?=[\s\S]*['"]@sveltejs\/kit['"])(?=[\s\S]*\bredirect\s*\()/]
3098
+ }],
3099
+ summary: "`redirect(...)` to an external URL now requires an `external` option.",
3100
+ 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.",
3101
+ links: guideLink("Miscellaneous-External-redirects-must-be-opted-into")
3088
3102
  }
3089
3103
  ];
3090
3104
  var collect_migration_instructions_default = defineMigrationTask({
@@ -3872,7 +3886,7 @@ var lib_alias_default = defineMigrationTask({
3872
3886
  const KIT3_MIN_VERSIONS = {
3873
3887
  vite: "^8.0.12",
3874
3888
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
3875
- svelte: "^5.57.1",
3889
+ svelte: "^5.57.2",
3876
3890
  "@sveltejs/package": "^3.0.0",
3877
3891
  "svelte-check": "^4.7.5",
3878
3892
  typescript: "^6.0.0"
@@ -9,9 +9,9 @@ import G from "node:readline";
9
9
  import { ReadStream } from "node:tty";
10
10
  import { EventEmitter } from "node:events";
11
11
  import childProcess, { spawn, spawnSync } from "node:child_process";
12
+ import { fileURLToPath } from "node:url";
12
13
  import { pipeline } from "node:stream/promises";
13
14
  import { PassThrough } from "node:stream";
14
- import { fileURLToPath } from "node:url";
15
15
  //#region \0rolldown/runtime.js
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -5020,7 +5020,7 @@ function safeParse(schema, input, config$1) {
5020
5020
  //#endregion
5021
5021
  //#region package.json
5022
5022
  var name = "sv";
5023
- var version = "1.1.1";
5023
+ var version = "1.2.0";
5024
5024
  //#endregion
5025
5025
  //#region src/core/errors.ts
5026
5026
  var UnsupportedError = class extends Error {
@@ -5293,7 +5293,60 @@ function isNodeError(err) {
5293
5293
  return err instanceof Error;
5294
5294
  }
5295
5295
  //#endregion
5296
+ //#region ../../node_modules/.pnpm/empathic@2.0.1/node_modules/empathic/resolve.mjs
5297
+ /**
5298
+ * Resolve an absolute path from {@link root}, but only
5299
+ * if {@link input} isn't already absolute.
5300
+ *
5301
+ * @param input The path to resolve.
5302
+ * @param root The base path; default = process.cwd()
5303
+ * @returns The resolved absolute path.
5304
+ */
5305
+ function absolute(input, root) {
5306
+ return isAbsolute(input) ? input : resolve(root || ".", input);
5307
+ }
5308
+ function from(root, ident, silent) {
5309
+ try {
5310
+ let r = root instanceof URL || root.startsWith("file://") ? join(fileURLToPath(root), "noop.js") : join(absolute(root), "noop.js");
5311
+ return createRequire(r).resolve(ident);
5312
+ } catch (err) {
5313
+ if (!silent) throw err;
5314
+ }
5315
+ }
5316
+ //#endregion
5317
+ //#region ../../node_modules/.pnpm/empathic@2.0.1/node_modules/empathic/walk.mjs
5318
+ /**
5319
+ * Get all parent directories of {@link base}.
5320
+ * Stops after {@link Options['last']} is processed.
5321
+ *
5322
+ * @returns An array of absolute paths of all parent directories.
5323
+ */
5324
+ function up$1(base, options) {
5325
+ let { last, cwd } = options || {};
5326
+ let tmp = absolute(base, cwd);
5327
+ let root = absolute(last || "/", cwd);
5328
+ let prev, arr = [];
5329
+ while (prev !== root) {
5330
+ arr.push(tmp);
5331
+ tmp = dirname(prev = tmp);
5332
+ if (tmp === prev) break;
5333
+ }
5334
+ return arr;
5335
+ }
5336
+ //#endregion
5296
5337
  //#region src/create/utils.ts
5338
+ /**
5339
+ * @returns an absolute path to the `dist` directory
5340
+ * containing templates, add-ons and shared files
5341
+ *
5342
+ * this function can be called during runtime or devtime
5343
+ */
5344
+ const resolve_dist_dir = () => {
5345
+ const root = up$1(import.meta.dirname).find((dir) => fs.existsSync(path.join(dir, "package.json")));
5346
+ if (!root) throw new Error("could not locate package.json");
5347
+ return path.join(root, "dist");
5348
+ };
5349
+ const dist_dir = resolve_dist_dir();
5297
5350
  function mkdirp(dir) {
5298
5351
  try {
5299
5352
  fs.mkdirSync(dir, { recursive: true });
@@ -5332,12 +5385,8 @@ function copy(from, to, rename = identity, kv = {}) {
5332
5385
  else fs.copyFileSync(from, to);
5333
5386
  }
5334
5387
  }
5335
- function dist(currentPath) {
5336
- const insideDistFolder = import.meta.url.includes("dist");
5337
- return path.resolve(import.meta.dirname, insideDistFolder ? "" : "dist", currentPath);
5338
- }
5339
5388
  function getSharedFiles() {
5340
- const shared = dist("shared.json");
5389
+ const shared = path.join(dist_dir, "shared.json");
5341
5390
  const { files } = JSON.parse(fs.readFileSync(shared, "utf-8"));
5342
5391
  return files;
5343
5392
  }
@@ -5373,7 +5422,7 @@ function create({ cwd, ...options }) {
5373
5422
  ]) fs.rmSync(path.join(cwd, name), { force: true });
5374
5423
  }
5375
5424
  const templates = publicTemplateTypes.map((dir) => {
5376
- const meta_file = dist(`templates/${dir}/meta.json`);
5425
+ const meta_file = path.join(dist_dir, "templates", dir, "meta.json");
5377
5426
  const { title, description } = JSON.parse(fs.readFileSync(meta_file, "utf8"));
5378
5427
  return {
5379
5428
  name: dir,
@@ -5382,7 +5431,7 @@ const templates = publicTemplateTypes.map((dir) => {
5382
5431
  };
5383
5432
  });
5384
5433
  function write_template_files(template, types, name, cwd) {
5385
- const dir = dist(`templates/${template}`);
5434
+ const dir = path.join(dist_dir, "templates", template);
5386
5435
  copy(`${dir}/assets`, cwd, (name) => name.replace("DOT-", "."), kv(name));
5387
5436
  copy(`${dir}/package.json`, `${cwd}/package.json`, void 0, kv(name));
5388
5437
  const manifest = `${dir}/files.types=${types}.json`;
@@ -5446,7 +5495,7 @@ function sort_files(files) {
5446
5495
  });
5447
5496
  }
5448
5497
  //#endregion
5449
- //#region ../../node_modules/.pnpm/tinyexec@1.3.0/node_modules/tinyexec/dist/main.mjs
5498
+ //#region ../../node_modules/.pnpm/tinyexec@1.3.1/node_modules/tinyexec/dist/main.mjs
5450
5499
  const isPathLikePattern = /^path$/i;
5451
5500
  const defaultEnvPathInfo = {
5452
5501
  key: "PATH",
@@ -5467,7 +5516,7 @@ function getPathFromEnv(env) {
5467
5516
  function addNodeBinToPath(cwd, path) {
5468
5517
  const parts = path.value.split(delimiter);
5469
5518
  const nodeBinPaths = [];
5470
- let currentPath = cwd;
5519
+ let currentPath = typeof cwd === "string" ? cwd : fileURLToPath(cwd, { windows: false });
5471
5520
  let lastPath;
5472
5521
  do {
5473
5522
  nodeBinPaths.push(resolve(currentPath, "node_modules", ".bin"));
@@ -5593,7 +5642,8 @@ function resolveCommand$1(command, options) {
5593
5642
  let pathExt = env.PATHEXT ? env.PATHEXT.split(delimiter) : defaultPathExt;
5594
5643
  if (command.includes(".") && pathExt[0] !== "") pathExt = ["", ...pathExt];
5595
5644
  for (const extensions of [pathExt, noPathExt]) for (const path of pathEnv) {
5596
- const dest = resolve(cwd$3, path.startsWith("\"") && path.endsWith("\"") && path.length > 1 ? path.slice(1, -1) : path, command);
5645
+ const unquoted = path.startsWith("\"") && path.endsWith("\"") && path.length > 1 ? path.slice(1, -1) : path;
5646
+ const dest = resolve(cwd$3, unquoted, command);
5597
5647
  for (const ext of extensions) {
5598
5648
  const destWithExt = dest + ext;
5599
5649
  try {
@@ -5737,12 +5787,12 @@ var ExecProcess = class {
5737
5787
  _streamOut;
5738
5788
  _streamErr;
5739
5789
  spawn() {
5740
- const cwd$1 = cwd();
5741
5790
  const options = this._options;
5742
5791
  const nodeOptions = {
5743
5792
  ...defaultNodeOptions,
5744
5793
  ...options.nodeOptions
5745
5794
  };
5795
+ const cwd$1 = nodeOptions?.cwd ?? cwd();
5746
5796
  const signals = [];
5747
5797
  this._resetState();
5748
5798
  if (options.timeout !== void 0) signals.push(AbortSignal.timeout(options.timeout));
@@ -5786,11 +5836,11 @@ function xSync(command, args, options) {
5786
5836
  ...defaultSyncOptions,
5787
5837
  ...options
5788
5838
  };
5789
- const cwd$2 = cwd();
5790
5839
  const nodeOptions = {
5791
- windowsHide: true,
5840
+ ...defaultNodeOptions,
5792
5841
  ...opts.nodeOptions
5793
5842
  };
5843
+ const cwd$2 = nodeOptions?.cwd ?? cwd();
5794
5844
  if (opts.timeout !== void 0) nodeOptions.timeout = opts.timeout;
5795
5845
  nodeOptions.env = computeEnv(cwd$2, nodeOptions.env, opts.nodePath);
5796
5846
  const crossResult = normalizeSpawnCommand(command, args ?? [], nodeOptions);
@@ -5918,47 +5968,6 @@ function createOptionBuilder(options) {
5918
5968
  //#region src/core/env.ts
5919
5969
  const TESTING = V.env.NODE_ENV?.toLowerCase() === "test";
5920
5970
  //#endregion
5921
- //#region ../../node_modules/.pnpm/empathic@2.0.1/node_modules/empathic/resolve.mjs
5922
- /**
5923
- * Resolve an absolute path from {@link root}, but only
5924
- * if {@link input} isn't already absolute.
5925
- *
5926
- * @param input The path to resolve.
5927
- * @param root The base path; default = process.cwd()
5928
- * @returns The resolved absolute path.
5929
- */
5930
- function absolute(input, root) {
5931
- return isAbsolute(input) ? input : resolve(root || ".", input);
5932
- }
5933
- function from(root, ident, silent) {
5934
- try {
5935
- let r = root instanceof URL || root.startsWith("file://") ? join(fileURLToPath(root), "noop.js") : join(absolute(root), "noop.js");
5936
- return createRequire(r).resolve(ident);
5937
- } catch (err) {
5938
- if (!silent) throw err;
5939
- }
5940
- }
5941
- //#endregion
5942
- //#region ../../node_modules/.pnpm/empathic@2.0.1/node_modules/empathic/walk.mjs
5943
- /**
5944
- * Get all parent directories of {@link base}.
5945
- * Stops after {@link Options['last']} is processed.
5946
- *
5947
- * @returns An array of absolute paths of all parent directories.
5948
- */
5949
- function up$1(base, options) {
5950
- let { last, cwd } = options || {};
5951
- let tmp = absolute(base, cwd);
5952
- let root = absolute(last || "/", cwd);
5953
- let prev, arr = [];
5954
- while (prev !== root) {
5955
- arr.push(tmp);
5956
- tmp = dirname(prev = tmp);
5957
- if (tmp === prev) break;
5958
- }
5959
- return arr;
5960
- }
5961
- //#endregion
5962
5971
  //#region ../../node_modules/.pnpm/empathic@2.0.1/node_modules/empathic/find.mjs
5963
5972
  /**
5964
5973
  * Find an item by name, walking parent directories until found.
@@ -6076,13 +6085,20 @@ function isInstalled(agent) {
6076
6085
  function addAllowBuildsIfPnpm(options) {
6077
6086
  const { cwd, packageManager, packages } = options;
6078
6087
  if (packageManager !== "pnpm") return;
6079
- const found = up("pnpm-workspace.yaml", { cwd });
6080
- const filePath = found ?? path.join(cwd, "pnpm-workspace.yaml");
6081
- const content = found ? fs.readFileSync(found, "utf-8") : "";
6082
- const newContent = pnpm.allowBuilds({
6088
+ transformFile(up("pnpm-workspace.yaml", { cwd }) ?? path.join(cwd, "pnpm-workspace.yaml"), pnpm.allowBuilds({
6083
6089
  cwd,
6084
6090
  packages
6085
- })(content);
6091
+ }));
6092
+ }
6093
+ /** pnpm >= 10.5 reads its settings from `pnpm-workspace.yaml`, others from `.npmrc`. */
6094
+ function addEngineStrict(options) {
6095
+ if (options.packageManager === "pnpm" && pnpm.supportsWorkspaceSettings(options.cwd)) transformFile(path.join(options.cwd, "pnpm-workspace.yaml"), transforms.yaml(({ data }) => data.set("engineStrict", true)));
6096
+ else transformFile(path.join(options.cwd, ".npmrc"), transforms.text(({ content, text }) => text.upsert(content, "engine-strict", { value: "true" })));
6097
+ }
6098
+ /** Missing file is treated as empty, so the transform can create it. */
6099
+ function transformFile(filePath, transform) {
6100
+ const content = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf-8") : "";
6101
+ const newContent = transform(content);
6086
6102
  if (newContent && newContent !== content) fs.writeFileSync(filePath, newContent, "utf-8");
6087
6103
  }
6088
6104
  //#endregion
@@ -6473,4 +6489,4 @@ function orderAddons(addons, setupResults) {
6473
6489
  return ordered;
6474
6490
  }
6475
6491
  //#endregion
6476
- export { parse$1 as $, cliOptions as A, runAndValidateVerifications as B, execSync as C, __toESM as Ct, getSharedFiles as D, dist as E, getPadding as F, UnsupportedError as G, updateAgent as H, helpConfig as I, array as J, name as K, isNodeError as L, filePaths as M, forwardExitCode as N, PackageJSONSchema as O, getHelpSections as P, optional as Q, normalizePosix as R, exec as S, __require as St, templates as T, updateLibraryBuild as U, runCommand as V, updateReadme as W, literal as X, boolean as Y, nonEmpty as Z, createLoadedAddon as _, pe as _t, setupAddons as a, string as at, getErrorHint as b, R$1 as bt, AGENT_NAMES as c, program as ct, installDependencies as d, Ce as dt, picklist as et, installOption as f, Ee as ft, from as g, le as gt, up$1 as h, ge as ht, prepareSvApi as i, strictObject as it, errorAndExit as j, buildAndLogArgs as k, addAllowBuildsIfPnpm as l, Command as lt, up as m, Re as mt, applyAddons as n, record as nt, createWorkspace as o, transform as ot, packageManagerPrompt as p, R as pt, version as q, orderAddons as r, safeParse as rt, findWorkspaceRoot as s, union as st, add as t, pipe as tt, detectPackageManager as u, Option as ut, defineAddon as v, vt, create as w, NonZeroExitError as x, __commonJSMin as xt, defineAddonOptions as y, we as yt, parseAddonOptions as z };
6492
+ export { optional as $, buildAndLogArgs as A, parseAddonOptions as B, create as C, __require as Ct, up$1 as D, getSharedFiles as E, getHelpSections as F, updateReadme as G, runCommand as H, getPadding as I, version as J, UnsupportedError as K, helpConfig as L, errorAndExit as M, filePaths as N, from as O, forwardExitCode as P, nonEmpty as Q, isNodeError as R, execSync as S, __commonJSMin as St, dist_dir as T, updateAgent as U, runAndValidateVerifications as V, updateLibraryBuild as W, boolean as X, array as Y, literal as Z, defineAddon as _, le as _t, setupAddons as a, strictObject as at, NonZeroExitError as b, we as bt, AGENT_NAMES as c, union as ct, detectPackageManager as d, Option as dt, parse$1 as et, installDependencies as f, Ce as ft, createLoadedAddon as g, ge as gt, up as h, Re as ht, prepareSvApi as i, safeParse as it, cliOptions as j, PackageJSONSchema as k, addAllowBuildsIfPnpm as l, program as lt, packageManagerPrompt as m, R as mt, applyAddons as n, pipe as nt, createWorkspace as o, string as ot, installOption as p, Ee as pt, name as q, orderAddons as r, record as rt, findWorkspaceRoot as s, transform as st, add as t, picklist as tt, addEngineStrict as u, Command as ut, defineAddonOptions as v, pe as vt, templates as w, __toESM as wt, exec as x, R$1 as xt, getErrorHint as y, vt as yt, normalizePosix as z };
@@ -94,8 +94,9 @@ type Workspace = {
94
94
  language: "ts" | "js";
95
95
  file: {
96
96
  viteConfig: "vite.config.js" | "vite.config.ts";
97
- typeConfig: "jsconfig.json" | "tsconfig.json" | undefined;
98
- /** `${directory.routes}/layout.css` or `src/app.css` */
97
+ /** @type {string} absolute path */
98
+ typeConfig: `${string}jsconfig.json` | `${string}tsconfig.json` | undefined;
99
+ /** `${directory.kitRoutes}/layout.css` or `src/app.css` */
99
100
  stylesheet: `${string}/layout.css` | "src/app.css";
100
101
  package: "package.json";
101
102
  gitignore: ".gitignore";
@@ -1,4 +1,4 @@
1
- import { A as SelectQuestion, C as BaseQuestion, D as OptionDefinition, E as NumberQuestion, M as ADDON_IDS, O as OptionValues, S as AddonOptions, T as MultiSelectQuestion, _ as SvApi, a as Addon, b as Workspace, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as SetupResult, h as PreparedAddon, i as add, j as StringQuestion, k as Question, l as AddonResult, m as OptionBuilder, n as InstallOptions, o as AddonDefinition, p as LoadedAddon, r as OptionMap, s as AddonInput, t as AddonMap, u as AddonSource, v as defineAddon, w as BooleanQuestion, x as WorkspaceOptions, y as defineAddonOptions } from "../engine-BLZdMrao.mjs";
1
+ import { A as SelectQuestion, C as BaseQuestion, D as OptionDefinition, E as NumberQuestion, M as ADDON_IDS, O as OptionValues, S as AddonOptions, T as MultiSelectQuestion, _ as SvApi, a as Addon, b as Workspace, c as AddonReference, d as ConditionDefinition, f as ConfiguredAddon, g as SetupResult, h as PreparedAddon, i as add, j as StringQuestion, k as Question, l as AddonResult, m as OptionBuilder, n as InstallOptions, o as AddonDefinition, p as LoadedAddon, r as OptionMap, s as AddonInput, t as AddonMap, u as AddonSource, v as defineAddon, w as BooleanQuestion, x as WorkspaceOptions, y as defineAddonOptions } from "../engine-fNvU_-IL.mjs";
2
2
  //#region src/create/index.d.ts
3
3
  type TemplateType = (typeof templateTypes)[number];
4
4
  type LanguageType = (typeof languageTypes)[number];
@@ -52,8 +52,38 @@ type PlaywrightOptions = {
52
52
  };
53
53
  //#endregion
54
54
  //#region src/addons/sveltekit-adapter.d.ts
55
+ declare const adapters: readonly [{
56
+ readonly id: "auto";
57
+ readonly package: "@sveltejs/adapter-auto";
58
+ readonly version: "^8.0.0";
59
+ }, {
60
+ readonly id: "node";
61
+ readonly package: "@sveltejs/adapter-node";
62
+ readonly version: "^6.0.0";
63
+ }, {
64
+ readonly id: "bun";
65
+ readonly package: "@sveltejs/adapter-bun";
66
+ readonly version: "^1.0.0";
67
+ }, {
68
+ readonly id: "static";
69
+ readonly package: "@sveltejs/adapter-static";
70
+ readonly version: "^4.0.0";
71
+ }, {
72
+ readonly id: "vercel";
73
+ readonly package: "@sveltejs/adapter-vercel";
74
+ readonly version: "^7.0.0";
75
+ }, {
76
+ readonly id: "cloudflare";
77
+ readonly package: "@sveltejs/adapter-cloudflare";
78
+ readonly version: "^8.0.0";
79
+ }, {
80
+ readonly id: "netlify";
81
+ readonly package: "@sveltejs/adapter-netlify";
82
+ readonly version: "^7.0.0";
83
+ }];
84
+ type AdapterId = (typeof adapters)[number]["id"];
55
85
  type SveltekitAdapterOptions = {
56
- adapter: "auto" | "node" | "static" | "vercel" | "cloudflare" | "netlify";
86
+ adapter: AdapterId;
57
87
  cfTarget: "workers" | "pages";
58
88
  };
59
89
  //#endregion
@@ -1,3 +1,3 @@
1
- import { t as add, v as defineAddon, w as create, y as defineAddonOptions } from "../engine-CpcTzL2R.mjs";
2
- import { n as officialAddons } from "../addons-DaktRhvH.mjs";
1
+ import { C as create, _ as defineAddon, t as add, v as defineAddonOptions } from "../engine-0i6PA_0L.mjs";
2
+ import { n as officialAddons } from "../addons-Ih-Pmrow.mjs";
3
3
  export { add, create, defineAddon, defineAddonOptions, officialAddons };
@@ -1,4 +1,4 @@
1
- import { r as OptionMap, t as AddonMap } from "../engine-BLZdMrao.mjs";
1
+ import { r as OptionMap, t as AddonMap } from "../engine-fNvU_-IL.mjs";
2
2
  import { Page } from "@playwright/test";
3
3
  import { TestProject } from "vitest/node";
4
4
  //#region src/testing.d.ts
@@ -1,4 +1,4 @@
1
- import { C as execSync, Ct as __toESM, S as exec, St as __require, l as addAllowBuildsIfPnpm, t as add, w as create, xt as __commonJSMin } from "../engine-CpcTzL2R.mjs";
1
+ import { C as create, Ct as __require, S as execSync, St as __commonJSMin, l as addAllowBuildsIfPnpm, t as add, wt as __toESM, x as exec } from "../engine-0i6PA_0L.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import V from "node:process";
@@ -22,11 +22,11 @@
22
22
  "access": "public"
23
23
  },
24
24
  "peerDependencies": {
25
- "sv": "^1.1.1"
25
+ "sv": "^1.2.0"
26
26
  },
27
27
  "devDependencies": {
28
- "sv": "^1.1.1",
29
- "@sveltejs/sv-utils": "^1.0.2",
28
+ "sv": "^1.2.0",
29
+ "@sveltejs/sv-utils": "^1.1.0",
30
30
  "@playwright/test": "^1.60.0",
31
31
  "@types/node": "^25.9.1",
32
32
  "tsdown": "^0.22.1",
@@ -15,7 +15,7 @@
15
15
  "@sveltejs/adapter-auto": "^8.0.0",
16
16
  "@sveltejs/kit": "^3.0.0",
17
17
  "@sveltejs/vite-plugin-svelte": "^7.2.0",
18
- "svelte": "^5.57.1",
18
+ "svelte": "^5.57.2",
19
19
  "vite": "^8.3.0"
20
20
  },
21
21
  "imports": {
@@ -28,7 +28,7 @@
28
28
  "@sveltejs/package": "^2.5.8",
29
29
  "@sveltejs/vite-plugin-svelte": "^7.2.0",
30
30
  "publint": "^0.3.21",
31
- "svelte": "^5.57.1",
31
+ "svelte": "^5.57.2",
32
32
  "typescript": "^6.0.3",
33
33
  "vite": "^8.3.0"
34
34
  },
@@ -13,7 +13,7 @@
13
13
  "@sveltejs/adapter-auto": "^8.0.0",
14
14
  "@sveltejs/kit": "^3.0.0",
15
15
  "@sveltejs/vite-plugin-svelte": "^7.2.0",
16
- "svelte": "^5.57.1",
16
+ "svelte": "^5.57.2",
17
17
  "vite": "^8.3.0"
18
18
  },
19
19
  "imports": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "A command line interface (CLI) for creating and maintaining Svelte applications",
5
5
  "keywords": [
6
6
  "create",
@@ -34,7 +34,7 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "@sveltejs/sv-utils": "1.0.2"
37
+ "@sveltejs/sv-utils": "1.1.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@clack/prompts": "1.5.0",
@@ -47,14 +47,12 @@
47
47
  "modern-tar": "^0.7.7",
48
48
  "ps-tree": "^1.2.0",
49
49
  "sucrase": "^3.35.1",
50
- "svelte": "^5.56.9",
50
+ "svelte": "^5.57.2",
51
51
  "tinyexec": "^1.2.4",
52
52
  "valibot": "^1.4.1"
53
53
  },
54
54
  "scripts": {
55
- "check": "tsgo",
56
- "update-kit-template-railway": "./src/create/scripts/update-kit-template-railway.sh",
57
- "update-template-repo": "./src/create/scripts/update-template-repo.sh"
55
+ "check": "tsgo"
58
56
  },
59
57
  "bin": {
60
58
  "sv": "./dist/bin.mjs"
@@ -1 +0,0 @@
1
- engine-strict=true
@@ -1 +0,0 @@
1
- engine-strict=true
@@ -1 +0,0 @@
1
- engine-strict=true