@reddoorla/maintenance 0.6.1 → 0.6.2

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/cli/bin.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/bin.ts
4
- import { dirname } from "path";
5
- import { fileURLToPath } from "url";
4
+ import { dirname as dirname2 } from "path";
5
+ import { fileURLToPath as fileURLToPath2 } from "url";
6
6
  import { cac } from "cac";
7
7
 
8
8
  // src/cli/commands/audit.ts
@@ -761,6 +761,13 @@ function assertSafeName(name) {
761
761
  throw new Error(`unsafe site name (traversal segment not allowed): ${name}`);
762
762
  }
763
763
  }
764
+ function assertSafeRepoUrl(repoUrl) {
765
+ if (!/^(https?|ssh|git|file):\/\//.test(repoUrl) && !/^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+:/.test(repoUrl)) {
766
+ throw new Error(
767
+ `unsafe repoUrl: must start with a scheme (https://, ssh://, git://, file://) or use scp-style "user@host:path" (got: ${JSON.stringify(repoUrl)})`
768
+ );
769
+ }
770
+ }
764
771
  async function isNonEmptyDir(path) {
765
772
  try {
766
773
  const s = await stat(path);
@@ -778,13 +785,14 @@ async function cloneIfNeeded(site, opts) {
778
785
  }
779
786
  const name = site.name ?? deriveNameFromRepoUrl(site.repoUrl);
780
787
  assertSafeName(name);
788
+ assertSafeRepoUrl(site.repoUrl);
781
789
  const target = join5(opts.workdir, name);
782
790
  await mkdir(opts.workdir, { recursive: true });
783
791
  if (await isNonEmptyDir(target)) {
784
792
  return { ...site, name, path: target };
785
793
  }
786
794
  const spawn2 = opts.spawn ?? defaultSpawn;
787
- const result = await spawn2("git", ["clone", site.repoUrl, target], {
795
+ const result = await spawn2("git", ["clone", "--", site.repoUrl, target], {
788
796
  cwd: opts.workdir,
789
797
  timeoutMs: 5 * 6e4
790
798
  });
@@ -1572,6 +1580,80 @@ function dollarPropsClass(source) {
1572
1580
  return updated;
1573
1581
  }
1574
1582
 
1583
+ // src/recipes/svelte-5/codemods/legacy-reactive.ts
1584
+ var SCRIPT_BLOCK4 = /<script\b([^>]*)>([\s\S]*?)<\/script>/g;
1585
+ var SIMPLE_REACTIVE = /^([ \t]*)\$:\s*(\w+)\s*=\s*([^;\n]+);?[ \t]*$/gm;
1586
+ var BLOCK_REACTIVE_HEAD = /(^|\n)([ \t]*)\$:\s*\{/g;
1587
+ function findMatchingClose(source, openIdx) {
1588
+ let depth = 0;
1589
+ let i = openIdx;
1590
+ while (i < source.length) {
1591
+ const ch = source[i];
1592
+ if (ch === '"' || ch === "'" || ch === "`") {
1593
+ const closeStr = findStringClose(source, i);
1594
+ if (closeStr === -1) return -1;
1595
+ i = closeStr + 1;
1596
+ continue;
1597
+ }
1598
+ if (ch === "{") depth++;
1599
+ else if (ch === "}") {
1600
+ depth--;
1601
+ if (depth === 0) return i;
1602
+ }
1603
+ i++;
1604
+ }
1605
+ return -1;
1606
+ }
1607
+ function findStringClose(source, openIdx) {
1608
+ const quote = source[openIdx];
1609
+ let i = openIdx + 1;
1610
+ while (i < source.length) {
1611
+ const ch = source[i];
1612
+ if (ch === "\\") {
1613
+ i += 2;
1614
+ continue;
1615
+ }
1616
+ if (ch === quote) return i;
1617
+ i++;
1618
+ }
1619
+ return -1;
1620
+ }
1621
+ function transformBlocks(body) {
1622
+ const out = [];
1623
+ let last = 0;
1624
+ BLOCK_REACTIVE_HEAD.lastIndex = 0;
1625
+ let m;
1626
+ while ((m = BLOCK_REACTIVE_HEAD.exec(body)) !== null) {
1627
+ const leadingNewline = m[1] ?? "";
1628
+ const indent = m[2] ?? "";
1629
+ const headEnd = m.index + m[0].length;
1630
+ const openBraceIdx = headEnd - 1;
1631
+ const closeBraceIdx = findMatchingClose(body, openBraceIdx);
1632
+ if (closeBraceIdx === -1) continue;
1633
+ out.push(body.slice(last, m.index));
1634
+ out.push(leadingNewline);
1635
+ const blockBody = body.slice(openBraceIdx + 1, closeBraceIdx);
1636
+ out.push(`${indent}$effect(() => {${blockBody}});`);
1637
+ last = closeBraceIdx + 1;
1638
+ BLOCK_REACTIVE_HEAD.lastIndex = last;
1639
+ }
1640
+ out.push(body.slice(last));
1641
+ return out.join("");
1642
+ }
1643
+ function transformSimple(body) {
1644
+ return body.replace(SIMPLE_REACTIVE, (_full, indent, name, expr) => {
1645
+ return `${indent}let ${name} = $derived(${expr.trim()});`;
1646
+ });
1647
+ }
1648
+ function legacyReactiveToRunes(source) {
1649
+ return source.replace(SCRIPT_BLOCK4, (full, _attrs, body) => {
1650
+ let next = transformBlocks(body);
1651
+ next = transformSimple(next);
1652
+ if (next === body) return full;
1653
+ return full.replace(body, next);
1654
+ });
1655
+ }
1656
+
1575
1657
  // src/recipes/svelte-5/step-gotchas.ts
1576
1658
  var SVELTE_GLOBS = ["src/**/*.svelte"];
1577
1659
  var IGNORE2 = ["node_modules/**", ".svelte-kit/**", "build/**"];
@@ -1580,7 +1662,8 @@ var CODEMODS = [
1580
1662
  exportLetToProps,
1581
1663
  removeDollarRestProps,
1582
1664
  stateEffectSyncToDerived,
1583
- dollarPropsClass
1665
+ dollarPropsClass,
1666
+ legacyReactiveToRunes
1584
1667
  ];
1585
1668
  async function planGotchaCodemods(cwd) {
1586
1669
  const changes = [];
@@ -1905,9 +1988,28 @@ import { resolve as resolve7 } from "path";
1905
1988
 
1906
1989
  // src/recipes/onboard.ts
1907
1990
  import { stat as stat3 } from "fs/promises";
1908
- import { join as join15 } from "path";
1991
+ import { join as join16 } from "path";
1992
+
1993
+ // src/util/self-version.ts
1994
+ import { readFileSync } from "fs";
1995
+ import { fileURLToPath } from "url";
1996
+ import { dirname, join as join15 } from "path";
1997
+ function selfPackageVersion(callerImportMetaUrl) {
1998
+ try {
1999
+ const here2 = dirname(fileURLToPath(callerImportMetaUrl));
2000
+ const raw = readFileSync(join15(here2, "..", "..", "package.json"), "utf-8");
2001
+ const pkg = JSON.parse(raw);
2002
+ return pkg.version ?? "0.0.0";
2003
+ } catch {
2004
+ return "0.0.0";
2005
+ }
2006
+ }
2007
+ function selfCaretRange(callerImportMetaUrl) {
2008
+ return `^${selfPackageVersion(callerImportMetaUrl)}`;
2009
+ }
2010
+
2011
+ // src/recipes/onboard.ts
1909
2012
  var PACKAGE_NAME = "@reddoorla/maintenance";
1910
- var DEFAULT_PACKAGE_VERSION = "^0.2.0";
1911
2013
  var AUDIT_DEPS = {
1912
2014
  lighthouse: [{ name: "@lhci/cli", version: "^0.15.1" }],
1913
2015
  a11y: [
@@ -1933,8 +2035,8 @@ async function onboard(site, opts = {}) {
1933
2035
  const label = siteLabel10(site);
1934
2036
  const spawn2 = opts.spawn ?? defaultSpawn;
1935
2037
  const audits = opts.audits ?? ["lighthouse", "a11y"];
1936
- const packageVersion = opts.packageVersion ?? DEFAULT_PACKAGE_VERSION;
1937
- if (!await exists2(join15(site.path, "pnpm-lock.yaml"))) {
2038
+ const packageVersion = opts.packageVersion ?? selfCaretRange(import.meta.url);
2039
+ if (!await exists2(join16(site.path, "pnpm-lock.yaml"))) {
1938
2040
  return {
1939
2041
  recipe: "onboard",
1940
2042
  site: label,
@@ -1943,7 +2045,7 @@ async function onboard(site, opts = {}) {
1943
2045
  notes: "no pnpm-lock.yaml at site root \u2014 run convert-to-pnpm first"
1944
2046
  };
1945
2047
  }
1946
- const pkgPath = join15(site.path, "package.json");
2048
+ const pkgPath = join16(site.path, "package.json");
1947
2049
  const pkg = await readPackageJson(pkgPath);
1948
2050
  const toAdd = [];
1949
2051
  if (!isDeclared(pkg, PACKAGE_NAME)) {
@@ -2047,7 +2149,7 @@ import { resolve as resolve8 } from "path";
2047
2149
 
2048
2150
  // src/recipes/svelte-codemods.ts
2049
2151
  import { writeFile as writeFile8 } from "fs/promises";
2050
- import { join as join16 } from "path";
2152
+ import { join as join17 } from "path";
2051
2153
  function siteLabel11(site) {
2052
2154
  return site.name ?? site.path;
2053
2155
  }
@@ -2069,7 +2171,7 @@ async function svelteCodemods(site) {
2069
2171
  const branch = branchName("svelte-codemods");
2070
2172
  await createBranch(site.path, branch);
2071
2173
  for (const c of changes) {
2072
- await writeFile8(join16(site.path, c.rel), c.after, "utf-8");
2174
+ await writeFile8(join17(site.path, c.rel), c.after, "utf-8");
2073
2175
  }
2074
2176
  const sha = await commit(
2075
2177
  site.path,
@@ -2110,11 +2212,11 @@ async function runSvelteCodemodsCommand(site, opts) {
2110
2212
  }
2111
2213
 
2112
2214
  // src/cli/version.ts
2113
- import { readFileSync } from "fs";
2114
- import { join as join17 } from "path";
2215
+ import { readFileSync as readFileSync2 } from "fs";
2216
+ import { join as join18 } from "path";
2115
2217
  function resolvePackageVersion(fromDir) {
2116
2218
  try {
2117
- const raw = readFileSync(join17(fromDir, "..", "..", "package.json"), "utf-8");
2219
+ const raw = readFileSync2(join18(fromDir, "..", "..", "package.json"), "utf-8");
2118
2220
  const pkg = JSON.parse(raw);
2119
2221
  return pkg.version ?? "unknown";
2120
2222
  } catch {
@@ -2123,7 +2225,7 @@ function resolvePackageVersion(fromDir) {
2123
2225
  }
2124
2226
 
2125
2227
  // src/cli/bin.ts
2126
- var here = dirname(fileURLToPath(import.meta.url));
2228
+ var here = dirname2(fileURLToPath2(import.meta.url));
2127
2229
  var version = resolvePackageVersion(here);
2128
2230
  var AUDIT_DESCRIPTIONS = {
2129
2231
  deps: "Diff site package.json against the bundled baseline version map.",