@reddoorla/maintenance 0.69.0 → 0.72.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.
Files changed (133) hide show
  1. package/README.md +15 -14
  2. package/dist/airtable-U2GTDTK5.js +9 -0
  3. package/dist/{announce-72R3LRNT.js → announce-HJCGEVJA.js} +6 -6
  4. package/dist/blux-FKZYMKLF.js +2205 -0
  5. package/dist/blux-FKZYMKLF.js.map +1 -0
  6. package/dist/{bump-deps-QNM3H4GI.js → bump-deps-GZEJAUKI.js} +3 -2
  7. package/dist/bump-deps-GZEJAUKI.js.map +1 -0
  8. package/dist/chunk-7MJBTV2R.js +145 -0
  9. package/dist/chunk-7MJBTV2R.js.map +1 -0
  10. package/dist/{chunk-2DCA7FHZ.js → chunk-7P7YETHG.js} +34 -12
  11. package/dist/chunk-7P7YETHG.js.map +1 -0
  12. package/dist/{chunk-42KKVLYN.js → chunk-APTAITXZ.js} +10 -2
  13. package/dist/chunk-APTAITXZ.js.map +1 -0
  14. package/dist/{chunk-6G7BC5SN.js → chunk-BHE5CUWI.js} +392 -7
  15. package/dist/chunk-BHE5CUWI.js.map +1 -0
  16. package/dist/{chunk-XWPZ46IN.js → chunk-BJCA7O4A.js} +2 -2
  17. package/dist/{chunk-C3PDS623.js → chunk-BWKK2ZXS.js} +67 -8
  18. package/dist/chunk-BWKK2ZXS.js.map +1 -0
  19. package/dist/{chunk-45AUGDFR.js → chunk-D4FVAIEJ.js} +6 -20
  20. package/dist/chunk-D4FVAIEJ.js.map +1 -0
  21. package/dist/{chunk-YQMYQAJX.js → chunk-GI4M2AMO.js} +2 -2
  22. package/dist/{chunk-OTBA7DON.js → chunk-GYNRZCM6.js} +7 -2
  23. package/dist/chunk-GYNRZCM6.js.map +1 -0
  24. package/dist/{chunk-6MT5W6UF.js → chunk-HR5SONJC.js} +6 -3
  25. package/dist/chunk-HR5SONJC.js.map +1 -0
  26. package/dist/{chunk-6JFOAPW4.js → chunk-JCITWZQR.js} +51 -19
  27. package/dist/chunk-JCITWZQR.js.map +1 -0
  28. package/dist/{chunk-GKSXZIMX.js → chunk-JGLAWXUC.js} +77 -3
  29. package/dist/chunk-JGLAWXUC.js.map +1 -0
  30. package/dist/{chunk-E2GKKUEX.js → chunk-KLB2OLPW.js} +26 -6
  31. package/dist/chunk-KLB2OLPW.js.map +1 -0
  32. package/dist/{chunk-RINXPU3H.js → chunk-KLVMJYZZ.js} +2 -2
  33. package/dist/chunk-KRDLHAKK.js +17 -0
  34. package/dist/chunk-KRDLHAKK.js.map +1 -0
  35. package/dist/{chunk-AESJBEM7.js → chunk-KRHPS3R4.js} +3 -3
  36. package/dist/{chunk-LYCKN7ZR.js → chunk-LJPCMXR7.js} +8 -5
  37. package/dist/chunk-LJPCMXR7.js.map +1 -0
  38. package/dist/{chunk-O6G4HHMF.js → chunk-NRISG4XD.js} +308 -104
  39. package/dist/chunk-NRISG4XD.js.map +1 -0
  40. package/dist/chunk-PKVZMFEB.js +315 -0
  41. package/dist/chunk-PKVZMFEB.js.map +1 -0
  42. package/dist/chunk-SL24DCGC.js +41 -0
  43. package/dist/chunk-SL24DCGC.js.map +1 -0
  44. package/dist/{chunk-A5KYRGQA.js → chunk-SQJ53Z7R.js} +4 -4
  45. package/dist/cli/bin.js +63 -19
  46. package/dist/cli/bin.js.map +1 -1
  47. package/dist/cli/commands/audit.d.ts +1 -1
  48. package/dist/cli/commands/audit.js +11 -9
  49. package/dist/cli/commands/audit.js.map +1 -1
  50. package/dist/configs/playwright-a11y.d.ts +1 -1
  51. package/dist/configs/playwright-a11y.js +1 -3
  52. package/dist/{convert-to-pnpm-XH7NYRVK.js → convert-to-pnpm-SVFDLXZS.js} +3 -2
  53. package/dist/convert-to-pnpm-SVFDLXZS.js.map +1 -0
  54. package/dist/{digest-Q2TAQHXF.js → digest-VX7Q4MNF.js} +8 -8
  55. package/dist/{ensure-site-2PF522VL.js → ensure-site-O7G5ZJS7.js} +2 -2
  56. package/dist/forms/index.d.ts +5 -2
  57. package/dist/forms/index.js +22 -9
  58. package/dist/forms/index.js.map +1 -1
  59. package/dist/{github-signals-CLQC2IPY.js → github-signals-QVW2LB7N.js} +5 -5
  60. package/dist/health-endpoint-IYR5VBUT.js +54 -0
  61. package/dist/health-endpoint-IYR5VBUT.js.map +1 -0
  62. package/dist/index.d.ts +136 -20
  63. package/dist/index.js +207 -64
  64. package/dist/index.js.map +1 -1
  65. package/dist/{init-UA6D7GKW.js → init-CU6PVZRG.js} +9 -5
  66. package/dist/init-CU6PVZRG.js.map +1 -0
  67. package/dist/{launch-AENAS2O2.js → launch-JWXCTJRG.js} +9 -9
  68. package/dist/{lighthouse-airtable-UBSXKHAQ.js → lighthouse-airtable-J5TLASJC.js} +3 -3
  69. package/dist/{onboard-X6KJ5Z2V.js → onboard-6UQE5QIO.js} +2 -2
  70. package/dist/{orchestrate-GADNFGDH.js → orchestrate-ZDH24Z6Y.js} +5 -5
  71. package/dist/{preflight-D5RQGX4V.js → preflight-BNTMWTPG.js} +7 -7
  72. package/dist/probe-DJAMLVTT.js +46 -0
  73. package/dist/probe-DJAMLVTT.js.map +1 -0
  74. package/dist/recipes/sync-configs.d.ts +1 -1
  75. package/dist/{renovate-dispatch-LG4RJGDY.js → renovate-dispatch-C3ALLACX.js} +2 -2
  76. package/dist/{report-3FJ224H5.js → report-YLFSGNWR.js} +12 -12
  77. package/dist/run-migration-LJNNZWIV.js +205 -0
  78. package/dist/run-migration-LJNNZWIV.js.map +1 -0
  79. package/dist/{self-updating-JTTFOJ7Q.js → self-updating-64FNRQB5.js} +2 -2
  80. package/dist/{selftest-55OJIWEB.js → selftest-7DPNGL6R.js} +12 -9
  81. package/dist/selftest-7DPNGL6R.js.map +1 -0
  82. package/dist/smoke-suite-TWILWDSF.js +54 -0
  83. package/dist/smoke-suite-TWILWDSF.js.map +1 -0
  84. package/dist/{svelte-codemods-KJLNH6FQ.js → svelte-codemods-RVDTTXFD.js} +3 -2
  85. package/dist/svelte-codemods-RVDTTXFD.js.map +1 -0
  86. package/dist/{sync-configs-TIBO6DUJ.js → sync-configs-BUUD6L5Q.js} +3 -2
  87. package/dist/sync-configs-BUUD6L5Q.js.map +1 -0
  88. package/dist/{types-Dg4mHvyf.d.ts → types-0jreMCF5.d.ts} +2 -2
  89. package/dist/{upgrade-TPTE26FG.js → upgrade-HHKWYJRN.js} +3 -2
  90. package/dist/upgrade-HHKWYJRN.js.map +1 -0
  91. package/dist/{websites-6YTT5ZTO.js → websites-EH2ULELZ.js} +8 -2
  92. package/dist/{write-audits-to-airtable-IWOO4FFH.js → write-audits-to-airtable-LZDYTNX5.js} +4 -4
  93. package/package.json +4 -1
  94. package/dist/airtable-WGQQ3KAD.js +0 -9
  95. package/dist/bump-deps-QNM3H4GI.js.map +0 -1
  96. package/dist/chunk-2DCA7FHZ.js.map +0 -1
  97. package/dist/chunk-42KKVLYN.js.map +0 -1
  98. package/dist/chunk-45AUGDFR.js.map +0 -1
  99. package/dist/chunk-6G7BC5SN.js.map +0 -1
  100. package/dist/chunk-6JFOAPW4.js.map +0 -1
  101. package/dist/chunk-6MT5W6UF.js.map +0 -1
  102. package/dist/chunk-C3PDS623.js.map +0 -1
  103. package/dist/chunk-E2GKKUEX.js.map +0 -1
  104. package/dist/chunk-GKSXZIMX.js.map +0 -1
  105. package/dist/chunk-LYCKN7ZR.js.map +0 -1
  106. package/dist/chunk-O6G4HHMF.js.map +0 -1
  107. package/dist/chunk-OTBA7DON.js.map +0 -1
  108. package/dist/convert-to-pnpm-XH7NYRVK.js.map +0 -1
  109. package/dist/init-UA6D7GKW.js.map +0 -1
  110. package/dist/selftest-55OJIWEB.js.map +0 -1
  111. package/dist/svelte-codemods-KJLNH6FQ.js.map +0 -1
  112. package/dist/sync-configs-TIBO6DUJ.js.map +0 -1
  113. package/dist/upgrade-TPTE26FG.js.map +0 -1
  114. /package/dist/{airtable-WGQQ3KAD.js.map → airtable-U2GTDTK5.js.map} +0 -0
  115. /package/dist/{announce-72R3LRNT.js.map → announce-HJCGEVJA.js.map} +0 -0
  116. /package/dist/{chunk-XWPZ46IN.js.map → chunk-BJCA7O4A.js.map} +0 -0
  117. /package/dist/{chunk-YQMYQAJX.js.map → chunk-GI4M2AMO.js.map} +0 -0
  118. /package/dist/{chunk-RINXPU3H.js.map → chunk-KLVMJYZZ.js.map} +0 -0
  119. /package/dist/{chunk-AESJBEM7.js.map → chunk-KRHPS3R4.js.map} +0 -0
  120. /package/dist/{chunk-A5KYRGQA.js.map → chunk-SQJ53Z7R.js.map} +0 -0
  121. /package/dist/{digest-Q2TAQHXF.js.map → digest-VX7Q4MNF.js.map} +0 -0
  122. /package/dist/{ensure-site-2PF522VL.js.map → ensure-site-O7G5ZJS7.js.map} +0 -0
  123. /package/dist/{github-signals-CLQC2IPY.js.map → github-signals-QVW2LB7N.js.map} +0 -0
  124. /package/dist/{launch-AENAS2O2.js.map → launch-JWXCTJRG.js.map} +0 -0
  125. /package/dist/{lighthouse-airtable-UBSXKHAQ.js.map → lighthouse-airtable-J5TLASJC.js.map} +0 -0
  126. /package/dist/{onboard-X6KJ5Z2V.js.map → onboard-6UQE5QIO.js.map} +0 -0
  127. /package/dist/{orchestrate-GADNFGDH.js.map → orchestrate-ZDH24Z6Y.js.map} +0 -0
  128. /package/dist/{preflight-D5RQGX4V.js.map → preflight-BNTMWTPG.js.map} +0 -0
  129. /package/dist/{renovate-dispatch-LG4RJGDY.js.map → renovate-dispatch-C3ALLACX.js.map} +0 -0
  130. /package/dist/{report-3FJ224H5.js.map → report-YLFSGNWR.js.map} +0 -0
  131. /package/dist/{self-updating-JTTFOJ7Q.js.map → self-updating-64FNRQB5.js.map} +0 -0
  132. /package/dist/{websites-6YTT5ZTO.js.map → websites-EH2ULELZ.js.map} +0 -0
  133. /package/dist/{write-audits-to-airtable-IWOO4FFH.js.map → write-audits-to-airtable-LZDYTNX5.js.map} +0 -0
@@ -5,19 +5,22 @@ import {
5
5
  } from "./chunk-4NAOR44V.js";
6
6
  import {
7
7
  resolveSites
8
- } from "./chunk-YQMYQAJX.js";
8
+ } from "./chunk-GI4M2AMO.js";
9
9
  import {
10
10
  init
11
- } from "./chunk-42KKVLYN.js";
11
+ } from "./chunk-APTAITXZ.js";
12
12
  import "./chunk-2X322ZES.js";
13
13
  import "./chunk-BTEBRTW4.js";
14
14
  import "./chunk-J7SZQUCW.js";
15
+ import "./chunk-7MJBTV2R.js";
16
+ import "./chunk-PKVZMFEB.js";
17
+ import "./chunk-KRDLHAKK.js";
15
18
  import "./chunk-ZYBOT5PM.js";
16
19
  import "./chunk-JNXCDUYB.js";
17
20
  import "./chunk-CASCWQQX.js";
18
21
  import "./chunk-XKOZUVK2.js";
19
22
  import "./chunk-OTGB6YQO.js";
20
- import "./chunk-6G7BC5SN.js";
23
+ import "./chunk-BHE5CUWI.js";
21
24
  import "./chunk-GASBX52O.js";
22
25
  import "./chunk-YEGHUODU.js";
23
26
  import "./chunk-LKGVSM2O.js";
@@ -29,7 +32,7 @@ import {
29
32
  import "./chunk-XTK5VIQB.js";
30
33
  import "./chunk-U5SZ4FOP.js";
31
34
  import "./chunk-EYODPUHV.js";
32
- import "./chunk-LYCKN7ZR.js";
35
+ import "./chunk-LJPCMXR7.js";
33
36
 
34
37
  // src/cli/commands/init.ts
35
38
  import { resolve } from "path";
@@ -68,6 +71,7 @@ async function runInitCommand(site, opts) {
68
71
  let sites = await resolveSites({
69
72
  ...site !== void 0 ? { site } : {},
70
73
  ...opts.fleet !== void 0 ? { fleet: opts.fleet } : {},
74
+ ...opts.workdir !== void 0 ? { workdir: opts.workdir } : {},
71
75
  cwd
72
76
  });
73
77
  let skipped = [];
@@ -101,4 +105,4 @@ async function runInitCommand(site, opts) {
101
105
  export {
102
106
  runInitCommand
103
107
  };
104
- //# sourceMappingURL=init-UA6D7GKW.js.map
108
+ //# sourceMappingURL=init-CU6PVZRG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/init.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { init, type InitResult, type InitStepResult } from \"../../recipes/init.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\nimport { siteLabel } from \"../../util/site.js\";\n\nexport type InitCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatStep(name: string, r: InitStepResult): string {\n if (r.kind === \"error\") return `${name.padEnd(20)} error: ${r.message}`;\n if (r.kind === \"audit\") {\n const lines = r.results.map(\n (a) => ` ${a.audit.padEnd(12)} ${a.status.padEnd(5)} ${a.summary}`,\n );\n return `${name.padEnd(20)} ${r.results.length} audit(s):\\n${lines.join(\"\\n\")}`;\n }\n const rec = r.result;\n if (rec.status === \"noop\") return `${name.padEnd(20)} noop${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n if (rec.status === \"failed\")\n return `${name.padEnd(20)} failed${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n return `${name.padEnd(20)} applied (${rec.commits.length} commit${rec.commits.length === 1 ? \"\" : \"s\"})${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n}\n\nfunction formatResult(r: InitResult): string {\n const header = `[${r.site}] init — ${r.complete ? \"complete\" : \"STOPPED\"}`;\n const body = r.steps.map((s) => formatStep(s.name, s.result)).join(\"\\n\");\n return `${header}\\n${body}`;\n}\n\nfunction exitCodeFor(r: InitResult): number {\n if (!r.complete) return 1;\n // A complete chain can still surface a failing audit at the end. Treat\n // any `fail`-status audit as exit 1 so CI signals a regression even when\n // every recipe applied cleanly.\n for (const step of r.steps) {\n if (step.result.kind === \"audit\" && step.result.results.some((a) => a.status === \"fail\")) {\n return 1;\n }\n }\n return 0;\n}\n\nexport async function runInitCommand(\n site: string | undefined,\n opts: InitCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n ...(opts.workdir !== undefined ? { workdir: opts.workdir } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results: InitResult[] = [];\n for (const s of sites) {\n try {\n results.push(await init(s));\n } catch (err) {\n // Isolate a per-site throw (e.g. a transient git error) so the rest of the\n // fleet still runs — the same guarantee `runRecipeOverSites` gives the other\n // fleet commands, but `init` returns an `InitResult`, so synthesize a stopped\n // one here rather than reuse the shared helper.\n results.push({\n site: siteLabel(s),\n steps: [\n {\n name: \"init\",\n result: { kind: \"error\", message: err instanceof Error ? err.message : String(err) },\n },\n ],\n complete: false,\n });\n }\n }\n\n const output = results.map(formatResult).join(\"\\n\\n\");\n const code = results.some((r) => exitCodeFor(r) !== 0) ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":"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","names":[]}
@@ -3,18 +3,18 @@ import {
3
3
  } from "./chunk-IRRZG66U.js";
4
4
  import {
5
5
  writeAuditsToAirtable
6
- } from "./chunk-GKSXZIMX.js";
6
+ } from "./chunk-JGLAWXUC.js";
7
7
  import {
8
8
  hasRealScores,
9
9
  lighthouseScoresFromResult
10
- } from "./chunk-XWPZ46IN.js";
10
+ } from "./chunk-BJCA7O4A.js";
11
11
  import "./chunk-5L3FPQIJ.js";
12
12
  import {
13
13
  resolveSites
14
- } from "./chunk-YQMYQAJX.js";
14
+ } from "./chunk-GI4M2AMO.js";
15
15
  import {
16
16
  queueDraft
17
- } from "./chunk-RINXPU3H.js";
17
+ } from "./chunk-KLVMJYZZ.js";
18
18
  import {
19
19
  createDraft,
20
20
  findReportByPeriod,
@@ -22,11 +22,11 @@ import {
22
22
  resolveCopy,
23
23
  updateReportScores,
24
24
  uploadAttachment
25
- } from "./chunk-6JFOAPW4.js";
25
+ } from "./chunk-JCITWZQR.js";
26
26
  import "./chunk-CASCWQQX.js";
27
27
  import {
28
28
  runAudits
29
- } from "./chunk-6G7BC5SN.js";
29
+ } from "./chunk-BHE5CUWI.js";
30
30
  import "./chunk-GASBX52O.js";
31
31
  import "./chunk-YEGHUODU.js";
32
32
  import "./chunk-LKGVSM2O.js";
@@ -40,14 +40,14 @@ import "./chunk-U5SZ4FOP.js";
40
40
  import {
41
41
  listWebsites,
42
42
  siteSlug
43
- } from "./chunk-C3PDS623.js";
43
+ } from "./chunk-BWKK2ZXS.js";
44
44
  import {
45
45
  openBase,
46
46
  readAirtableConfig
47
47
  } from "./chunk-HN6I2XWI.js";
48
48
  import "./chunk-6VAL7XJT.js";
49
49
  import "./chunk-EYODPUHV.js";
50
- import "./chunk-LYCKN7ZR.js";
50
+ import "./chunk-LJPCMXR7.js";
51
51
 
52
52
  // src/cli/commands/launch.ts
53
53
  import { resolve } from "path";
@@ -210,4 +210,4 @@ async function runLaunchCommand(site, opts) {
210
210
  export {
211
211
  runLaunchCommand
212
212
  };
213
- //# sourceMappingURL=launch-AENAS2O2.js.map
213
+ //# sourceMappingURL=launch-JWXCTJRG.js.map
@@ -2,11 +2,11 @@ import {
2
2
  hasRealScores,
3
3
  lighthouseScoresFromResult,
4
4
  resolveSlugFromCwd
5
- } from "./chunk-XWPZ46IN.js";
6
- import "./chunk-C3PDS623.js";
5
+ } from "./chunk-BJCA7O4A.js";
6
+ import "./chunk-BWKK2ZXS.js";
7
7
  export {
8
8
  hasRealScores,
9
9
  lighthouseScoresFromResult,
10
10
  resolveSlugFromCwd
11
11
  };
12
- //# sourceMappingURL=lighthouse-airtable-UBSXKHAQ.js.map
12
+ //# sourceMappingURL=lighthouse-airtable-J5TLASJC.js.map
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-4NAOR44V.js";
9
9
  import {
10
10
  resolveSites
11
- } from "./chunk-YQMYQAJX.js";
11
+ } from "./chunk-GI4M2AMO.js";
12
12
  import {
13
13
  onboard
14
14
  } from "./chunk-ZYBOT5PM.js";
@@ -70,4 +70,4 @@ async function runOnboardCommand(site, opts) {
70
70
  export {
71
71
  runOnboardCommand
72
72
  };
73
- //# sourceMappingURL=onboard-X6KJ5Z2V.js.map
73
+ //# sourceMappingURL=onboard-6UQE5QIO.js.map
@@ -4,15 +4,15 @@ import {
4
4
  parseAddresses,
5
5
  sendApprovedReports,
6
6
  withGlobalCc
7
- } from "./chunk-2DCA7FHZ.js";
7
+ } from "./chunk-7P7YETHG.js";
8
8
  import "./chunk-GECESMVS.js";
9
- import "./chunk-6JFOAPW4.js";
9
+ import "./chunk-JCITWZQR.js";
10
10
  import "./chunk-WEKL2HYJ.js";
11
- import "./chunk-OTBA7DON.js";
11
+ import "./chunk-GYNRZCM6.js";
12
12
  import "./chunk-PH3AGF4Z.js";
13
13
  import "./chunk-HIN3P4ZN.js";
14
14
  import "./chunk-U5SZ4FOP.js";
15
- import "./chunk-C3PDS623.js";
15
+ import "./chunk-BWKK2ZXS.js";
16
16
  import "./chunk-HN6I2XWI.js";
17
17
  import "./chunk-6VAL7XJT.js";
18
18
  export {
@@ -22,4 +22,4 @@ export {
22
22
  sendApprovedReports,
23
23
  withGlobalCc
24
24
  };
25
- //# sourceMappingURL=orchestrate-GADNFGDH.js.map
25
+ //# sourceMappingURL=orchestrate-ZDH24Z6Y.js.map
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  preflight
3
- } from "./chunk-E2GKKUEX.js";
4
- import "./chunk-45AUGDFR.js";
5
- import "./chunk-2DCA7FHZ.js";
3
+ } from "./chunk-KLB2OLPW.js";
4
+ import "./chunk-D4FVAIEJ.js";
5
+ import "./chunk-7P7YETHG.js";
6
6
  import "./chunk-GECESMVS.js";
7
- import "./chunk-6JFOAPW4.js";
7
+ import "./chunk-JCITWZQR.js";
8
8
  import "./chunk-WEKL2HYJ.js";
9
- import "./chunk-OTBA7DON.js";
9
+ import "./chunk-GYNRZCM6.js";
10
10
  import "./chunk-PH3AGF4Z.js";
11
11
  import "./chunk-HIN3P4ZN.js";
12
12
  import "./chunk-U5SZ4FOP.js";
13
- import "./chunk-C3PDS623.js";
13
+ import "./chunk-BWKK2ZXS.js";
14
14
  import "./chunk-HN6I2XWI.js";
15
15
  import "./chunk-6VAL7XJT.js";
16
16
 
@@ -61,4 +61,4 @@ async function runPreflightCommand(site, opts) {
61
61
  export {
62
62
  runPreflightCommand
63
63
  };
64
- //# sourceMappingURL=preflight-D5RQGX4V.js.map
64
+ //# sourceMappingURL=preflight-BNTMWTPG.js.map
@@ -0,0 +1,46 @@
1
+ import {
2
+ CDN_HOSTS
3
+ } from "./chunk-SL24DCGC.js";
4
+
5
+ // src/blux/emit/probe.ts
6
+ var IMAGE_EXTS = ["jpg", "png", "jpeg", "webp", "gif", "svg"];
7
+ var FILE_EXTS = ["mp4", "pdf"];
8
+ function extCandidates(t) {
9
+ const c = [];
10
+ const nameExt = t.name.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
11
+ if (nameExt) c.push(nameExt);
12
+ const mimeExt = t.mime.split("/")[1]?.replace("jpeg", "jpg");
13
+ if (mimeExt && !c.includes(mimeExt)) c.push(mimeExt);
14
+ const commons = t.mime.startsWith("image/") ? IMAGE_EXTS : t.mime ? FILE_EXTS : [...IMAGE_EXTS, ...FILE_EXTS];
15
+ for (const e of commons) if (!c.includes(e)) c.push(e);
16
+ return c;
17
+ }
18
+ async function probeOne(t, siteId, fetchImpl) {
19
+ for (const ext of extCandidates(t)) {
20
+ for (const host of CDN_HOSTS) {
21
+ const url = `https://${host}/${siteId}/${t.id}.${ext}`;
22
+ try {
23
+ if ((await fetchImpl(url, { method: "HEAD" })).ok) return url;
24
+ } catch {
25
+ }
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ async function probeAssetUrls(targets, siteId, fetchImpl = fetch, concurrency = 8) {
31
+ const results = /* @__PURE__ */ new Map();
32
+ let i = 0;
33
+ await Promise.all(
34
+ Array.from({ length: Math.min(concurrency, targets.length) }, async () => {
35
+ while (i < targets.length) {
36
+ const t = targets[i++];
37
+ results.set(t.id, await probeOne(t, siteId, fetchImpl));
38
+ }
39
+ })
40
+ );
41
+ return results;
42
+ }
43
+ export {
44
+ probeAssetUrls
45
+ };
46
+ //# sourceMappingURL=probe-DJAMLVTT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/blux/emit/probe.ts"],"sourcesContent":["/** Reconstruct-and-probe fallback for assets the rendered HTML never showed:\n * the Blux CDN serves originals at <host>/<siteId>/<uuid>.<ext>. Proven on\n * thePointe 2026-07-06: the scrape found 4/320 library assets while the probe\n * resolved the remaining 52/52 used ones. Network-touching by design — wired\n * to `blux emit --probe`, never into the pure builders. */\n\nimport { CDN_HOSTS as HOSTS } from \"../assets.js\";\n\nconst IMAGE_EXTS = [\"jpg\", \"png\", \"jpeg\", \"webp\", \"gif\", \"svg\"];\nconst FILE_EXTS = [\"mp4\", \"pdf\"];\n\nexport type ProbeTarget = { id: string; name: string; mime: string };\n\nfunction extCandidates(t: ProbeTarget): string[] {\n const c: string[] = [];\n const nameExt = t.name.match(/\\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();\n if (nameExt) c.push(nameExt);\n const mimeExt = t.mime.split(\"/\")[1]?.replace(\"jpeg\", \"jpg\");\n if (mimeExt && !c.includes(mimeExt)) c.push(mimeExt);\n // a known image mime never needs the video/pdf probes (and vice versa)\n const commons = t.mime.startsWith(\"image/\")\n ? IMAGE_EXTS\n : t.mime\n ? FILE_EXTS\n : [...IMAGE_EXTS, ...FILE_EXTS];\n for (const e of commons) if (!c.includes(e)) c.push(e);\n return c;\n}\n\nasync function probeOne(\n t: ProbeTarget,\n siteId: string,\n fetchImpl: typeof fetch,\n): Promise<string | null> {\n for (const ext of extCandidates(t)) {\n for (const host of HOSTS) {\n const url = `https://${host}/${siteId}/${t.id}.${ext}`;\n try {\n if ((await fetchImpl(url, { method: \"HEAD\" })).ok) return url;\n } catch {\n // network hiccup on one candidate — try the next\n }\n }\n }\n return null;\n}\n\nexport async function probeAssetUrls(\n targets: ProbeTarget[],\n siteId: string,\n fetchImpl: typeof fetch = fetch,\n concurrency = 8,\n): Promise<Map<string, string | null>> {\n const results = new Map<string, string | null>();\n let i = 0;\n await Promise.all(\n Array.from({ length: Math.min(concurrency, targets.length) }, async () => {\n while (i < targets.length) {\n const t = targets[i++]!;\n results.set(t.id, await probeOne(t, siteId, fetchImpl));\n }\n }),\n );\n return results;\n}\n"],"mappings":";;;;;AAQA,IAAM,aAAa,CAAC,OAAO,OAAO,QAAQ,QAAQ,OAAO,KAAK;AAC9D,IAAM,YAAY,CAAC,OAAO,KAAK;AAI/B,SAAS,cAAc,GAA0B;AAC/C,QAAM,IAAc,CAAC;AACrB,QAAM,UAAU,EAAE,KAAK,MAAM,iBAAiB,IAAI,CAAC,GAAG,YAAY;AAClE,MAAI,QAAS,GAAE,KAAK,OAAO;AAC3B,QAAM,UAAU,EAAE,KAAK,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,QAAQ,KAAK;AAC3D,MAAI,WAAW,CAAC,EAAE,SAAS,OAAO,EAAG,GAAE,KAAK,OAAO;AAEnD,QAAM,UAAU,EAAE,KAAK,WAAW,QAAQ,IACtC,aACA,EAAE,OACA,YACA,CAAC,GAAG,YAAY,GAAG,SAAS;AAClC,aAAW,KAAK,QAAS,KAAI,CAAC,EAAE,SAAS,CAAC,EAAG,GAAE,KAAK,CAAC;AACrD,SAAO;AACT;AAEA,eAAe,SACb,GACA,QACA,WACwB;AACxB,aAAW,OAAO,cAAc,CAAC,GAAG;AAClC,eAAW,QAAQ,WAAO;AACxB,YAAM,MAAM,WAAW,IAAI,IAAI,MAAM,IAAI,EAAE,EAAE,IAAI,GAAG;AACpD,UAAI;AACF,aAAK,MAAM,UAAU,KAAK,EAAE,QAAQ,OAAO,CAAC,GAAG,GAAI,QAAO;AAAA,MAC5D,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,eACpB,SACA,QACA,YAA0B,OAC1B,cAAc,GACuB;AACrC,QAAM,UAAU,oBAAI,IAA2B;AAC/C,MAAI,IAAI;AACR,QAAM,QAAQ;AAAA,IACZ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,QAAQ,MAAM,EAAE,GAAG,YAAY;AACxE,aAAO,IAAI,QAAQ,QAAQ;AACzB,cAAM,IAAI,QAAQ,GAAG;AACrB,gBAAQ,IAAI,EAAE,IAAI,MAAM,SAAS,GAAG,QAAQ,SAAS,CAAC;AAAA,MACxD;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":[]}
@@ -1,4 +1,4 @@
1
- import { C as ConfigName, S as Site, b as RecipeResult } from '../types-Dg4mHvyf.js';
1
+ import { C as ConfigName, S as Site, b as RecipeResult } from '../types-0jreMCF5.js';
2
2
 
3
3
  type SyncConfigsOptions = {
4
4
  which?: ConfigName[];
@@ -9,7 +9,7 @@ import {
9
9
  isDashboardVisible,
10
10
  listWebsites,
11
11
  updateAutoFixAttempts
12
- } from "./chunk-C3PDS623.js";
12
+ } from "./chunk-BWKK2ZXS.js";
13
13
  import {
14
14
  openBase,
15
15
  readAirtableConfig
@@ -136,4 +136,4 @@ No active repo-backed sites with critical/high vulnerabilities \u2014 nothing to
136
136
  export {
137
137
  runRenovateDispatchCommand
138
138
  };
139
- //# sourceMappingURL=renovate-dispatch-LG4RJGDY.js.map
139
+ //# sourceMappingURL=renovate-dispatch-C3ALLACX.js.map
@@ -1,25 +1,25 @@
1
- import {
2
- findDueReports,
3
- nextDueDate,
4
- reportPeriodKey
5
- } from "./chunk-45AUGDFR.js";
6
1
  import {
7
2
  draftReportForSite,
8
3
  readGaConfig
9
- } from "./chunk-O6G4HHMF.js";
4
+ } from "./chunk-NRISG4XD.js";
10
5
  import {
11
6
  reportTier
12
- } from "./chunk-RINXPU3H.js";
7
+ } from "./chunk-KLVMJYZZ.js";
8
+ import {
9
+ findDueReports,
10
+ nextDueDate,
11
+ reportPeriodKey
12
+ } from "./chunk-D4FVAIEJ.js";
13
13
  import {
14
14
  escapeHtml,
15
15
  listAllReports
16
- } from "./chunk-6JFOAPW4.js";
16
+ } from "./chunk-JCITWZQR.js";
17
17
  import "./chunk-U5SZ4FOP.js";
18
18
  import {
19
19
  listWebsites,
20
20
  siteSlug,
21
21
  updateNextDueDates
22
- } from "./chunk-C3PDS623.js";
22
+ } from "./chunk-BWKK2ZXS.js";
23
23
  import {
24
24
  openBase,
25
25
  readAirtableConfig
@@ -69,11 +69,11 @@ function dashboardBaseUrl() {
69
69
  }
70
70
  async function runReportCommand(slug, opts) {
71
71
  if (opts.digest) {
72
- const { runDigest } = await import("./digest-Q2TAQHXF.js");
72
+ const { runDigest } = await import("./digest-VX7Q4MNF.js");
73
73
  return runDigest({ baseUrl: dashboardBaseUrl() });
74
74
  }
75
75
  if (opts.sendReady) {
76
- const { sendApprovedReports } = await import("./orchestrate-GADNFGDH.js");
76
+ const { sendApprovedReports } = await import("./orchestrate-ZDH24Z6Y.js");
77
77
  return sendApprovedReports();
78
78
  }
79
79
  if (opts.due) {
@@ -252,4 +252,4 @@ export {
252
252
  parseSingleSiteReportType,
253
253
  runReportCommand
254
254
  };
255
- //# sourceMappingURL=report-3FJ224H5.js.map
255
+ //# sourceMappingURL=report-YLFSGNWR.js.map
@@ -0,0 +1,205 @@
1
+ // src/blux/emit/resolve-doc.ts
2
+ import { htmlAsRichText } from "@prismicio/migrate";
3
+ function resolveDocData(data, assetIdByUuid) {
4
+ const missing = [];
5
+ const resolve = (v) => {
6
+ if (v && typeof v === "object") {
7
+ if ("__richtext_html" in v) {
8
+ return htmlAsRichText(v.__richtext_html).result;
9
+ }
10
+ if ("__asset_id" in v) {
11
+ const uuid = v.__asset_id;
12
+ const id = assetIdByUuid.get(uuid);
13
+ if (!id) {
14
+ missing.push(uuid);
15
+ return void 0;
16
+ }
17
+ return { id };
18
+ }
19
+ if (Array.isArray(v)) return v.map(resolve);
20
+ return Object.fromEntries(
21
+ Object.entries(v).map(([k, val]) => [k, resolve(val)]).filter(([, val]) => val !== void 0)
22
+ );
23
+ }
24
+ return v;
25
+ };
26
+ return { data: resolve(data), missingAssets: missing };
27
+ }
28
+
29
+ // src/blux/emit/run-migration.ts
30
+ var THROTTLE_MS = 1200;
31
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
32
+ async function fetchWithRetry(url, init, tries = 4) {
33
+ for (let i = 0; ; i++) {
34
+ const res = await fetch(url, init);
35
+ if (res.status !== 429 || i >= tries - 1) return res;
36
+ await sleep(1500 * (i + 1));
37
+ }
38
+ }
39
+ function readCreds() {
40
+ const repo = process.env.PRISMIC_REPOSITORY_NAME;
41
+ const token = process.env.PRISMIC_WRITE_TOKEN;
42
+ if (!repo || !token) throw new Error("Set PRISMIC_REPOSITORY_NAME and PRISMIC_WRITE_TOKEN");
43
+ return { repo, token };
44
+ }
45
+ var apiHeaders = (repo, token) => ({
46
+ repository: repo,
47
+ Authorization: `Bearer ${token}`
48
+ });
49
+ async function expectOk(res, what) {
50
+ if (res.ok) return res;
51
+ throw new Error(`${what}: ${res.status} ${await res.text()}`);
52
+ }
53
+ async function pushCustomTypes(types) {
54
+ const { repo, token } = readCreds();
55
+ const headers = { ...apiHeaders(repo, token), "Content-Type": "application/json" };
56
+ const post = (path, body) => fetchWithRetry(`https://customtypes.prismic.io/customtypes/${path}`, {
57
+ method: "POST",
58
+ headers,
59
+ body
60
+ });
61
+ const pushed = [];
62
+ for (const t of types) {
63
+ const body = JSON.stringify(t.json);
64
+ const ins = await post("insert", body);
65
+ if (!ins.ok) {
66
+ const insErr = `insert ${ins.status} ${await ins.text()}`;
67
+ if (ins.status !== 409 && ins.status !== 400)
68
+ throw new Error(`custom type ${t.id}: ${insErr}`);
69
+ const upd = await post("update", body);
70
+ if (!upd.ok) {
71
+ throw new Error(`custom type ${t.id}: ${insErr}; update ${upd.status} ${await upd.text()}`);
72
+ }
73
+ }
74
+ pushed.push(t.id);
75
+ }
76
+ return pushed;
77
+ }
78
+ async function listAssetsByFilename(repo, token) {
79
+ const map = /* @__PURE__ */ new Map();
80
+ let cursor = "";
81
+ for (; ; ) {
82
+ const res = await expectOk(
83
+ await fetchWithRetry(`https://asset-api.prismic.io/assets?limit=500${cursor}`, {
84
+ headers: apiHeaders(repo, token)
85
+ }),
86
+ "asset list"
87
+ );
88
+ const page = await res.json();
89
+ for (const a of page.items) map.set(a.filename, { id: a.id, url: a.url });
90
+ if (!page.cursor || !page.items.length) return map;
91
+ cursor = `&cursor=${encodeURIComponent(page.cursor)}`;
92
+ }
93
+ }
94
+ async function lookupDocIds(repo) {
95
+ const access = process.env.PRISMIC_ACCESS_TOKEN;
96
+ const qs = access ? `?access_token=${access}` : "";
97
+ const apiRes = await expectOk(
98
+ await fetchWithRetry(`https://${repo}.prismic.io/api/v2${qs}`),
99
+ "Document API /api/v2 (set PRISMIC_ACCESS_TOKEN for a private repo)"
100
+ );
101
+ const api = await apiRes.json();
102
+ const master = api.refs?.find((r) => r.id === "master")?.ref;
103
+ if (!master) throw new Error(`Document API for ${repo} returned no master ref`);
104
+ const map = /* @__PURE__ */ new Map();
105
+ const sep = qs ? "&" : "?";
106
+ let url = `https://${repo}.prismic.io/api/v2/documents/search${qs}${sep}ref=${master}&pageSize=100`;
107
+ while (url) {
108
+ const res = await expectOk(await fetchWithRetry(url), "Document API search");
109
+ const page = await res.json();
110
+ for (const d of page.results) if (d.uid) map.set(d.uid, d.id);
111
+ url = page.next_page;
112
+ }
113
+ return map;
114
+ }
115
+ async function runMigration(plan, log = console.log) {
116
+ const { repo, token } = readCreds();
117
+ const existing = await listAssetsByFilename(repo, token);
118
+ const assetIdByUuid = /* @__PURE__ */ new Map();
119
+ const assetUrlByCdn = /* @__PURE__ */ new Map();
120
+ let assetsUploaded = 0;
121
+ let assetsReused = 0;
122
+ for (const a of plan.assets) {
123
+ const filename = (a.url.split("/").pop() ?? a.id).split("?")[0];
124
+ const known = existing.get(filename);
125
+ if (known) {
126
+ assetIdByUuid.set(a.id, known.id);
127
+ assetUrlByCdn.set(a.url, known.url);
128
+ assetsReused++;
129
+ continue;
130
+ }
131
+ const blob = await (await expectOk(await fetch(a.url), `fetch asset ${filename}`)).blob();
132
+ const form = new FormData();
133
+ form.append("file", blob, filename);
134
+ if (a.alt) form.append("alt", a.alt);
135
+ const res = await expectOk(
136
+ await fetchWithRetry("https://asset-api.prismic.io/assets", {
137
+ method: "POST",
138
+ headers: apiHeaders(repo, token),
139
+ body: form
140
+ }),
141
+ `upload asset ${filename}`
142
+ );
143
+ const created = await res.json();
144
+ assetIdByUuid.set(a.id, created.id);
145
+ assetUrlByCdn.set(a.url, created.url);
146
+ assetsUploaded++;
147
+ log(`asset ${assetsUploaded + assetsReused}/${plan.assets.length} ${filename}`);
148
+ await sleep(THROTTLE_MS);
149
+ }
150
+ let docIds = null;
151
+ let docsCreated = 0;
152
+ let docsUpdated = 0;
153
+ const missingAssets = [];
154
+ for (const doc of plan.documents) {
155
+ const { data, missingAssets: miss } = resolveDocData(doc.data, assetIdByUuid);
156
+ missingAssets.push(...miss);
157
+ const body = JSON.stringify({
158
+ type: doc.type,
159
+ uid: doc.uid,
160
+ lang: "en-us",
161
+ title: doc.uid,
162
+ data
163
+ });
164
+ const headers = { ...apiHeaders(repo, token), "Content-Type": "application/json" };
165
+ const res = await fetchWithRetry("https://migration.prismic.io/documents", {
166
+ method: "POST",
167
+ headers,
168
+ body
169
+ });
170
+ if (res.ok) {
171
+ docsCreated++;
172
+ log(`created ${doc.uid}`);
173
+ } else {
174
+ const text = await res.text();
175
+ if (!/already exists/i.test(text)) {
176
+ throw new Error(`create ${doc.uid}: ${res.status} ${text}`);
177
+ }
178
+ docIds ??= await lookupDocIds(repo);
179
+ const id = docIds.get(doc.uid);
180
+ if (!id) {
181
+ throw new Error(
182
+ `update ${doc.uid}: the uid exists but is not visible on the master ref \u2014 most likely it sits in an UNPUBLISHED migration release; publish the release in the Prismic dashboard, then re-run to update` + (process.env.PRISMIC_ACCESS_TOKEN ? "" : " (if the repo's Document API is private, also set PRISMIC_ACCESS_TOKEN)")
183
+ );
184
+ }
185
+ await sleep(THROTTLE_MS);
186
+ await expectOk(
187
+ await fetchWithRetry(`https://migration.prismic.io/documents/${id}`, {
188
+ method: "PUT",
189
+ headers,
190
+ body
191
+ }),
192
+ `update ${doc.uid}`
193
+ );
194
+ docsUpdated++;
195
+ log(`updated ${doc.uid}`);
196
+ }
197
+ await sleep(THROTTLE_MS);
198
+ }
199
+ return { assetsUploaded, assetsReused, docsCreated, docsUpdated, missingAssets, assetUrlByCdn };
200
+ }
201
+ export {
202
+ pushCustomTypes,
203
+ runMigration
204
+ };
205
+ //# sourceMappingURL=run-migration-LJNNZWIV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/blux/emit/resolve-doc.ts","../src/blux/emit/run-migration.ts"],"sourcesContent":["import { htmlAsRichText } from \"@prismicio/migrate\";\n\n/** Resolve a PlanDocument's plain-JSON markers into Migration API values:\n * `__richtext_html` → rich text nodes, `__asset_id` → `{ id }` using the\n * uuid → Prismic-asset-id map (missing assets are dropped and reported).\n * Pure, so the network shell in run-migration.ts stays untested-thin. */\nexport function resolveDocData(\n data: Record<string, unknown>,\n assetIdByUuid: Map<string, string>,\n): { data: Record<string, unknown>; missingAssets: string[] } {\n const missing: string[] = [];\n const resolve = (v: unknown): unknown => {\n if (v && typeof v === \"object\") {\n if (\"__richtext_html\" in v) {\n return htmlAsRichText((v as { __richtext_html: string }).__richtext_html).result;\n }\n if (\"__asset_id\" in v) {\n const uuid = (v as { __asset_id: string }).__asset_id;\n const id = assetIdByUuid.get(uuid);\n if (!id) {\n missing.push(uuid);\n return undefined;\n }\n return { id };\n }\n if (Array.isArray(v)) return v.map(resolve);\n return Object.fromEntries(\n Object.entries(v)\n .map(([k, val]) => [k, resolve(val)] as const)\n .filter(([, val]) => val !== undefined),\n );\n }\n return v;\n };\n return { data: resolve(data) as Record<string, unknown>, missingAssets: missing };\n}\n","import type { MigrationPlan, PlanCustomType } from \"./plan.js\";\nimport { resolveDocData } from \"./resolve-doc.js\";\n\n/** LIVE runner on the raw Prismic APIs. Learned from the Pointe run\n * (2026-07-06): the js client's migrate() creates docs hollow, PATCHes data\n * in a later pass, swallows validation `details[]`, re-uploads every asset on\n * retry, and cannot update existing docs. This runner: skips assets already\n * in the library (by filename), POSTs documents and falls back to PUT when\n * the uid exists (id looked up via the Document API), and surfaces full error\n * bodies. Creds: PRISMIC_REPOSITORY_NAME + PRISMIC_WRITE_TOKEN (+ optional\n * PRISMIC_ACCESS_TOKEN when the repo's Document API is private).\n * Live I/O — excluded from unit coverage; resolveDocData carries the tested\n * pure logic and Plan 4 Task 10 is the live acceptance run. */\n\nconst THROTTLE_MS = 1200; // migration API limit ~1 req/s\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n/** fetch with backoff on 429 — the Asset/Migration APIs rate-limit hard and a\n * single 429 must not abort a minutes-long migration. */\nasync function fetchWithRetry(url: string, init?: RequestInit, tries = 4): Promise<Response> {\n for (let i = 0; ; i++) {\n const res = await fetch(url, init);\n if (res.status !== 429 || i >= tries - 1) return res;\n await sleep(1500 * (i + 1));\n }\n}\n\nfunction readCreds(): { repo: string; token: string } {\n const repo = process.env.PRISMIC_REPOSITORY_NAME;\n const token = process.env.PRISMIC_WRITE_TOKEN;\n if (!repo || !token) throw new Error(\"Set PRISMIC_REPOSITORY_NAME and PRISMIC_WRITE_TOKEN\");\n return { repo, token };\n}\n\nconst apiHeaders = (repo: string, token: string) => ({\n repository: repo,\n Authorization: `Bearer ${token}`,\n});\n\nasync function expectOk(res: Response, what: string): Promise<Response> {\n if (res.ok) return res;\n throw new Error(`${what}: ${res.status} ${await res.text()}`);\n}\n\n/** Push the plan's repeatable custom types via the Custom Types API\n * (insert, falling back to update when the type already exists). */\nexport async function pushCustomTypes(types: PlanCustomType[]): Promise<string[]> {\n const { repo, token } = readCreds();\n const headers = { ...apiHeaders(repo, token), \"Content-Type\": \"application/json\" };\n const post = (path: \"insert\" | \"update\", body: string) =>\n fetchWithRetry(`https://customtypes.prismic.io/customtypes/${path}`, {\n method: \"POST\",\n headers,\n body,\n });\n const pushed: string[] = [];\n for (const t of types) {\n const body = JSON.stringify(t.json);\n const ins = await post(\"insert\", body);\n if (!ins.ok) {\n const insErr = `insert ${ins.status} ${await ins.text()}`;\n // 409/400 usually means \"type exists\" — but keep the insert body: when\n // the update ALSO fails, the insert's validation detail is the real clue\n if (ins.status !== 409 && ins.status !== 400)\n throw new Error(`custom type ${t.id}: ${insErr}`);\n const upd = await post(\"update\", body);\n if (!upd.ok) {\n throw new Error(`custom type ${t.id}: ${insErr}; update ${upd.status} ${await upd.text()}`);\n }\n }\n pushed.push(t.id);\n }\n return pushed;\n}\n\n/** filename → { id, url } for every asset already in the media library. `url`\n * is the servable CDN url (the Asset API asset object's `url` field, e.g.\n * https://images.prismic.io/...) that the render side loads. */\nasync function listAssetsByFilename(\n repo: string,\n token: string,\n): Promise<Map<string, { id: string; url: string }>> {\n const map = new Map<string, { id: string; url: string }>();\n let cursor = \"\";\n for (;;) {\n const res = await expectOk(\n await fetchWithRetry(`https://asset-api.prismic.io/assets?limit=500${cursor}`, {\n headers: apiHeaders(repo, token),\n }),\n \"asset list\",\n );\n const page = (await res.json()) as {\n items: { id: string; filename: string; url: string }[];\n cursor?: string;\n };\n for (const a of page.items) map.set(a.filename, { id: a.id, url: a.url });\n if (!page.cursor || !page.items.length) return map;\n cursor = `&cursor=${encodeURIComponent(page.cursor)}`;\n }\n}\n\n/** uid → document id on the target repo, for the PUT-update path. Reads the\n * MASTER ref, so it only sees PUBLISHED documents — docs sitting in an\n * unpublished migration release are invisible here (the miss error explains\n * that). Follows next_page so >100-doc repos resolve fully. */\nasync function lookupDocIds(repo: string): Promise<Map<string, string>> {\n const access = process.env.PRISMIC_ACCESS_TOKEN;\n const qs = access ? `?access_token=${access}` : \"\";\n const apiRes = await expectOk(\n await fetchWithRetry(`https://${repo}.prismic.io/api/v2${qs}`),\n \"Document API /api/v2 (set PRISMIC_ACCESS_TOKEN for a private repo)\",\n );\n const api = (await apiRes.json()) as { refs?: { id: string; ref: string }[] };\n const master = api.refs?.find((r) => r.id === \"master\")?.ref;\n if (!master) throw new Error(`Document API for ${repo} returned no master ref`);\n\n const map = new Map<string, string>();\n const sep = qs ? \"&\" : \"?\";\n let url: string | null =\n `https://${repo}.prismic.io/api/v2/documents/search${qs}${sep}ref=${master}&pageSize=100`;\n while (url) {\n const res = await expectOk(await fetchWithRetry(url), \"Document API search\");\n const page = (await res.json()) as {\n results: { id: string; uid: string | null }[];\n next_page: string | null;\n };\n for (const d of page.results) if (d.uid) map.set(d.uid, d.id);\n url = page.next_page;\n }\n return map;\n}\n\nexport type MigrationResult = {\n assetsUploaded: number;\n assetsReused: number;\n docsCreated: number;\n docsUpdated: number;\n missingAssets: string[];\n /** cdn url (the manifest/plan-asset url) → resolved Prismic servable url, for\n * every asset uploaded or reused. Lets the caller rewrite the render manifest\n * onto durable Prismic-hosted media. */\n assetUrlByCdn: Map<string, string>;\n};\n\n/** Execute a MigrationPlan: upload missing assets (reusing existing ones by\n * filename), then create-or-update each document by uid. Documents land in a\n * migration release the operator publishes in the dashboard. */\nexport async function runMigration(\n plan: MigrationPlan,\n log: (line: string) => void = console.log,\n): Promise<MigrationResult> {\n const { repo, token } = readCreds();\n const existing = await listAssetsByFilename(repo, token);\n const assetIdByUuid = new Map<string, string>();\n const assetUrlByCdn = new Map<string, string>();\n let assetsUploaded = 0;\n let assetsReused = 0;\n\n for (const a of plan.assets) {\n // Blux filenames are `<uuid>.<ext>` — globally unique, so filename keying\n // is a sound dedup. Reused assets keep their existing alt (trade-off:\n // alt from the plan is only applied on first upload).\n const filename = (a.url.split(\"/\").pop() ?? a.id).split(\"?\")[0]!;\n const known = existing.get(filename);\n if (known) {\n assetIdByUuid.set(a.id, known.id);\n assetUrlByCdn.set(a.url, known.url);\n assetsReused++;\n continue;\n }\n const blob = await (await expectOk(await fetch(a.url), `fetch asset ${filename}`)).blob();\n const form = new FormData();\n form.append(\"file\", blob, filename);\n if (a.alt) form.append(\"alt\", a.alt);\n const res = await expectOk(\n await fetchWithRetry(\"https://asset-api.prismic.io/assets\", {\n method: \"POST\",\n headers: apiHeaders(repo, token),\n body: form,\n }),\n `upload asset ${filename}`,\n );\n const created = (await res.json()) as { id: string; url: string };\n assetIdByUuid.set(a.id, created.id);\n assetUrlByCdn.set(a.url, created.url);\n assetsUploaded++;\n log(`asset ${assetsUploaded + assetsReused}/${plan.assets.length} ${filename}`);\n await sleep(THROTTLE_MS);\n }\n\n let docIds: Map<string, string> | null = null;\n let docsCreated = 0;\n let docsUpdated = 0;\n const missingAssets: string[] = [];\n\n for (const doc of plan.documents) {\n const { data, missingAssets: miss } = resolveDocData(doc.data, assetIdByUuid);\n missingAssets.push(...miss);\n const body = JSON.stringify({\n type: doc.type,\n uid: doc.uid,\n lang: \"en-us\",\n title: doc.uid,\n data,\n });\n const headers = { ...apiHeaders(repo, token), \"Content-Type\": \"application/json\" };\n const res = await fetchWithRetry(\"https://migration.prismic.io/documents\", {\n method: \"POST\",\n headers,\n body,\n });\n if (res.ok) {\n docsCreated++;\n log(`created ${doc.uid}`);\n } else {\n const text = await res.text();\n if (!/already exists/i.test(text)) {\n throw new Error(`create ${doc.uid}: ${res.status} ${text}`);\n }\n docIds ??= await lookupDocIds(repo);\n const id = docIds.get(doc.uid);\n if (!id) {\n throw new Error(\n `update ${doc.uid}: the uid exists but is not visible on the master ref — ` +\n `most likely it sits in an UNPUBLISHED migration release; publish the release ` +\n `in the Prismic dashboard, then re-run to update` +\n (process.env.PRISMIC_ACCESS_TOKEN\n ? \"\"\n : \" (if the repo's Document API is private, also set PRISMIC_ACCESS_TOKEN)\"),\n );\n }\n await sleep(THROTTLE_MS); // the failed POST already hit the migration API\n await expectOk(\n await fetchWithRetry(`https://migration.prismic.io/documents/${id}`, {\n method: \"PUT\",\n headers,\n body,\n }),\n `update ${doc.uid}`,\n );\n docsUpdated++;\n log(`updated ${doc.uid}`);\n }\n await sleep(THROTTLE_MS);\n }\n return { assetsUploaded, assetsReused, docsCreated, docsUpdated, missingAssets, assetUrlByCdn };\n}\n"],"mappings":"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","names":[]}
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-4NAOR44V.js";
12
12
  import {
13
13
  resolveSites
14
- } from "./chunk-YQMYQAJX.js";
14
+ } from "./chunk-GI4M2AMO.js";
15
15
  import "./chunk-CASCWQQX.js";
16
16
  import "./chunk-GASBX52O.js";
17
17
  import "./chunk-YEGHUODU.js";
@@ -61,4 +61,4 @@ async function runSelfUpdatingCommand(site, opts) {
61
61
  export {
62
62
  runSelfUpdatingCommand
63
63
  };
64
- //# sourceMappingURL=self-updating-JTTFOJ7Q.js.map
64
+ //# sourceMappingURL=self-updating-64FNRQB5.js.map
@@ -1,30 +1,33 @@
1
1
  import {
2
2
  buildReportDataForSite,
3
3
  scoresFromRow
4
- } from "./chunk-A5KYRGQA.js";
5
- import "./chunk-O6G4HHMF.js";
6
- import "./chunk-RINXPU3H.js";
4
+ } from "./chunk-SQJ53Z7R.js";
5
+ import "./chunk-NRISG4XD.js";
6
+ import "./chunk-KLVMJYZZ.js";
7
+ import {
8
+ ELIGIBLE_STATUSES
9
+ } from "./chunk-D4FVAIEJ.js";
7
10
  import {
8
11
  isProbablyEmail,
9
12
  parseAddresses,
10
13
  prepareHeaderImage,
11
14
  renderReportEmail
12
- } from "./chunk-2DCA7FHZ.js";
15
+ } from "./chunk-7P7YETHG.js";
13
16
  import "./chunk-GECESMVS.js";
14
17
  import {
15
18
  fetchAttachmentBytes
16
- } from "./chunk-6JFOAPW4.js";
19
+ } from "./chunk-JCITWZQR.js";
17
20
  import {
18
21
  defaultResendClient
19
22
  } from "./chunk-WEKL2HYJ.js";
20
- import "./chunk-OTBA7DON.js";
23
+ import "./chunk-GYNRZCM6.js";
21
24
  import "./chunk-PH3AGF4Z.js";
22
25
  import "./chunk-HIN3P4ZN.js";
23
26
  import "./chunk-U5SZ4FOP.js";
24
27
  import {
25
28
  listWebsites,
26
29
  siteSlug
27
- } from "./chunk-C3PDS623.js";
30
+ } from "./chunk-BWKK2ZXS.js";
28
31
  import {
29
32
  openBase,
30
33
  readAirtableConfig
@@ -56,7 +59,7 @@ async function selftestEmail(deps) {
56
59
  const websites = await listWebsites(base);
57
60
  let targets;
58
61
  if (deps.all) {
59
- targets = websites.filter((w) => w.status === "maintenance");
62
+ targets = websites.filter((w) => w.status !== null && ELIGIBLE_STATUSES.has(w.status));
60
63
  } else if (deps.site) {
61
64
  const wanted = siteSlug(deps.site);
62
65
  targets = websites.filter((w) => siteSlug(w.name) === wanted);
@@ -156,4 +159,4 @@ async function runSelftestCommand(kind, site, opts) {
156
159
  export {
157
160
  runSelftestCommand
158
161
  };
159
- //# sourceMappingURL=selftest-55OJIWEB.js.map
162
+ //# sourceMappingURL=selftest-7DPNGL6R.js.map