@reddoorla/maintenance 0.85.2 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/airtable-ZBUPQJSC.js +9 -0
- package/dist/{announce-GIAYN67S.js → announce-I2Z4JN3I.js} +58 -30
- package/dist/announce-I2Z4JN3I.js.map +1 -0
- package/dist/attachments-NLZIJ5NU.js +9 -0
- package/dist/{bump-deps-SWJB6H5V.js → bump-deps-CGVELRLK.js} +9 -9
- package/dist/{chunk-SDUJIANJ.js → chunk-2NJQLSEU.js} +3 -3
- package/dist/chunk-2NQUCS7O.js +243 -0
- package/dist/chunk-2NQUCS7O.js.map +1 -0
- package/dist/{chunk-ZTPPCHDB.js → chunk-3G25KIWW.js} +4 -4
- package/dist/{chunk-DTTIFYAM.js → chunk-3JQ2FO3D.js} +44 -405
- package/dist/chunk-3JQ2FO3D.js.map +1 -0
- package/dist/chunk-3SF7D4DY.js +359 -0
- package/dist/chunk-3SF7D4DY.js.map +1 -0
- package/dist/{chunk-37S6L6G4.js → chunk-5UINJNAJ.js} +72 -2
- package/dist/chunk-5UINJNAJ.js.map +1 -0
- package/dist/{chunk-THEFTZ7F.js → chunk-62CMMGEO.js} +5 -5
- package/dist/{chunk-FDIFTIXC.js → chunk-6TWWY7ZU.js} +2 -2
- package/dist/{chunk-PBWDDDQH.js → chunk-7BZUOZPU.js} +2 -2
- package/dist/{chunk-577HCGZO.js → chunk-7NYN2P6I.js} +44 -26
- package/dist/chunk-7NYN2P6I.js.map +1 -0
- package/dist/{chunk-UYCAF77E.js → chunk-7RJ2HMMJ.js} +3 -3
- package/dist/{chunk-Q276MZ7E.js → chunk-7UAYMAKR.js} +2 -2
- package/dist/{chunk-MGR2H7F4.js → chunk-BBUSGEES.js} +58 -45
- package/dist/chunk-BBUSGEES.js.map +1 -0
- package/dist/chunk-BNM5POSJ.js +284 -0
- package/dist/chunk-BNM5POSJ.js.map +1 -0
- package/dist/{chunk-R6FPFMOS.js → chunk-BQRFQSGY.js} +3 -3
- package/dist/{chunk-NWB4O5EY.js → chunk-C6CLRKPV.js} +5 -5
- package/dist/chunk-C6CLRKPV.js.map +1 -0
- package/dist/{chunk-7J53SUT6.js → chunk-CROKUHJB.js} +4 -4
- package/dist/chunk-DEWJMMG3.js +274 -0
- package/dist/chunk-DEWJMMG3.js.map +1 -0
- package/dist/{chunk-SEEA6RXF.js → chunk-DJZWYIPP.js} +2 -2
- package/dist/chunk-DJZWYIPP.js.map +1 -0
- package/dist/chunk-EVBCK2KC.js +68 -0
- package/dist/chunk-EVBCK2KC.js.map +1 -0
- package/dist/chunk-F3JWOPTG.js +202 -0
- package/dist/chunk-F3JWOPTG.js.map +1 -0
- package/dist/{chunk-GZNBCHAZ.js → chunk-HEWSRXYV.js} +4 -4
- package/dist/chunk-HHMMUR4P.js +335 -0
- package/dist/chunk-HHMMUR4P.js.map +1 -0
- package/dist/chunk-HSI6Q7MI.js +1238 -0
- package/dist/chunk-HSI6Q7MI.js.map +1 -0
- package/dist/{chunk-MPBXOJ3N.js → chunk-IY6256GK.js} +33 -2
- package/dist/chunk-IY6256GK.js.map +1 -0
- package/dist/{chunk-LS6QPANO.js → chunk-IYSEC543.js} +2 -2
- package/dist/{chunk-DC5H7KEQ.js → chunk-JHGHLKFS.js} +2 -2
- package/dist/{chunk-4DHQCN5H.js → chunk-LBYOLBW7.js} +17 -2
- package/dist/chunk-LBYOLBW7.js.map +1 -0
- package/dist/{chunk-6QRLRT3P.js → chunk-MT2JINSS.js} +16 -265
- package/dist/chunk-MT2JINSS.js.map +1 -0
- package/dist/{chunk-TP5M2NQB.js → chunk-NCMZMLY7.js} +3 -3
- package/dist/{chunk-COZPL62X.js → chunk-NDWYJLRF.js} +24 -139
- package/dist/chunk-NDWYJLRF.js.map +1 -0
- package/dist/{chunk-3YXDSCM6.js → chunk-NXNPDCF3.js} +29 -11
- package/dist/chunk-NXNPDCF3.js.map +1 -0
- package/dist/chunk-NYUYNYQL.js +48 -0
- package/dist/chunk-NYUYNYQL.js.map +1 -0
- package/dist/chunk-P6AORG32.js +415 -0
- package/dist/chunk-P6AORG32.js.map +1 -0
- package/dist/chunk-PTDMVGKL.js +31 -0
- package/dist/chunk-PTDMVGKL.js.map +1 -0
- package/dist/{chunk-D4FVAIEJ.js → chunk-PZR4EBPY.js} +5 -2
- package/dist/chunk-PZR4EBPY.js.map +1 -0
- package/dist/{chunk-LTB6KVJW.js → chunk-SDDPUAWH.js} +13 -11
- package/dist/{chunk-LTB6KVJW.js.map → chunk-SDDPUAWH.js.map} +1 -1
- package/dist/{chunk-WYYQK4D3.js → chunk-TD2NNXLZ.js} +13 -13
- package/dist/{chunk-ZMIPG6TR.js → chunk-TVL5MVUF.js} +4 -4
- package/dist/chunk-UDRHAQT7.js +172 -0
- package/dist/chunk-UDRHAQT7.js.map +1 -0
- package/dist/chunk-VAD43MOR.js +72 -0
- package/dist/chunk-VAD43MOR.js.map +1 -0
- package/dist/chunk-VSBFM7DS.js +229 -0
- package/dist/chunk-VSBFM7DS.js.map +1 -0
- package/dist/{chunk-VRWUL4TR.js → chunk-XHHMM5HX.js} +2 -2
- package/dist/{chunk-RJB3QUSP.js → chunk-XIDUYLSR.js} +3 -3
- package/dist/{chunk-QG6OSL4M.js → chunk-XUGSZP7Z.js} +2 -2
- package/dist/{chunk-S56JQJ4F.js → chunk-Y53WOQIJ.js} +3 -3
- package/dist/{chunk-62VF32IC.js → chunk-YFAXOD7Z.js} +10 -6
- package/dist/chunk-YFAXOD7Z.js.map +1 -0
- package/dist/{chunk-ICXV25N7.js → chunk-Z3KYFUN6.js} +3 -3
- package/dist/chunk-ZBDZTJUO.js +129 -0
- package/dist/chunk-ZBDZTJUO.js.map +1 -0
- package/dist/chunk-ZGBEIWSC.js +146 -0
- package/dist/chunk-ZGBEIWSC.js.map +1 -0
- package/dist/cli/bin.js +51 -28
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +30 -1
- package/dist/cli/commands/audit.js +69 -33
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/client-AUE3XUPO.js +11 -0
- package/dist/{convert-to-pnpm-AT52NWZB.js → convert-to-pnpm-QFJOEP5V.js} +9 -9
- package/dist/db-UXNIZ2RG.js +217 -0
- package/dist/db-UXNIZ2RG.js.map +1 -0
- package/dist/{digest-UVHYZUYE.js → digest-FW6QMZZJ.js} +26 -22
- package/dist/{digest-UVHYZUYE.js.map → digest-FW6QMZZJ.js.map} +1 -1
- package/dist/dump-P6EBSIOH.js +68 -0
- package/dist/dump-P6EBSIOH.js.map +1 -0
- package/dist/email-KJXASVH5.js +195 -0
- package/dist/email-KJXASVH5.js.map +1 -0
- package/dist/{ensure-site-S25MDDHW.js → ensure-site-4DCEBAPM.js} +25 -16
- package/dist/ensure-site-4DCEBAPM.js.map +1 -0
- package/dist/fleet-events-cF2Om88w.d.ts +24 -0
- package/dist/fleet-state-7TJ2GYT2.js +39 -0
- package/dist/{forms-notify-target-TWN4EH6K.js → forms-notify-target-2EAWCWBW.js} +42 -133
- package/dist/forms-notify-target-2EAWCWBW.js.map +1 -0
- package/dist/{github-signals-G4ILZAJ6.js → github-signals-E2WPYTBK.js} +42 -21
- package/dist/github-signals-E2WPYTBK.js.map +1 -0
- package/dist/{header-image-T7XD37JL.js → header-image-6IC53W27.js} +36 -13
- package/dist/header-image-6IC53W27.js.map +1 -0
- package/dist/header-images-SQBCE5OD.js +88 -0
- package/dist/header-images-SQBCE5OD.js.map +1 -0
- package/dist/{health-endpoint-242WG2OJ.js → health-endpoint-RFXL2F4A.js} +9 -9
- package/dist/health-mirror-L5JBEJVA.js +41 -0
- package/dist/health-mirror-L5JBEJVA.js.map +1 -0
- package/dist/import-airtable-OHVY344G.js +37 -0
- package/dist/index.d.ts +324 -21
- package/dist/index.js +215 -76
- package/dist/index.js.map +1 -1
- package/dist/{init-JN26NTWF.js → init-XRAQZYID.js} +21 -18
- package/dist/{init-JN26NTWF.js.map → init-XRAQZYID.js.map} +1 -1
- package/dist/{launch-JA7Z4CIM.js → launch-IX4Y5JJC.js} +65 -30
- package/dist/launch-IX4Y5JJC.js.map +1 -0
- package/dist/lighthouse-VHI77PFB.js +11 -0
- package/dist/{lighthouse-airtable-BIPM26SZ.js → lighthouse-airtable-3GUWHETW.js} +3 -3
- package/dist/mailchimp-XYCTEEJY.js +72 -0
- package/dist/mailchimp-XYCTEEJY.js.map +1 -0
- package/dist/migrate-GQH237A6.js +7 -0
- package/dist/migrate-GQH237A6.js.map +1 -0
- package/dist/notify-C645PGD5.js +22 -0
- package/dist/notify-C645PGD5.js.map +1 -0
- package/dist/{onboard-53CITIM7.js → onboard-O4IAHJMO.js} +9 -9
- package/dist/orchestrate-YLWQ6KK2.js +31 -0
- package/dist/orchestrate-YLWQ6KK2.js.map +1 -0
- package/dist/parity-56KA2DGR.js +12 -0
- package/dist/parity-56KA2DGR.js.map +1 -0
- package/dist/pipeline-3AANZFCR.js +12 -0
- package/dist/pipeline-3AANZFCR.js.map +1 -0
- package/dist/{preflight-3XPDUHFJ.js → preflight-TNORKGCX.js} +17 -13
- package/dist/{preflight-3XPDUHFJ.js.map → preflight-TNORKGCX.js.map} +1 -1
- package/dist/{prismic-ci-UTQ6LRR3.js → prismic-ci-G2AK53VL.js} +12 -12
- package/dist/{prismic-models-PVES6R5V.js → prismic-models-O6Z3OK3A.js} +18 -13
- package/dist/prismic-models-O6Z3OK3A.js.map +1 -0
- package/dist/prospect/types.d.ts +267 -0
- package/dist/prospect/types.js +1 -0
- package/dist/prospect/types.js.map +1 -0
- package/dist/prospect-audit-KSXUNQ5J.js +174 -0
- package/dist/prospect-audit-KSXUNQ5J.js.map +1 -0
- package/dist/prospect-audits-3PMIO73D.js +19 -0
- package/dist/prospect-audits-3PMIO73D.js.map +1 -0
- package/dist/{protection-audit-64PLLBLI.js → protection-audit-SJO53MEQ.js} +3 -3
- package/dist/recipes/sync-configs.js +3 -3
- package/dist/render-IFOGFB5T.js +10 -0
- package/dist/render-IFOGFB5T.js.map +1 -0
- package/dist/render-from-row-BWSOIYDS.js +17 -0
- package/dist/render-from-row-BWSOIYDS.js.map +1 -0
- package/dist/{renovate-dispatch-ICJGSFCE.js → renovate-dispatch-6GQWTRKX.js} +12 -12
- package/dist/{renovate-dispatch-ICJGSFCE.js.map → renovate-dispatch-6GQWTRKX.js.map} +1 -1
- package/dist/replay-C2LXMJZP.js +66 -0
- package/dist/replay-C2LXMJZP.js.map +1 -0
- package/dist/{report-6CKSWJNG.js → report-R3E3Y7HR.js} +100 -32
- package/dist/report-R3E3Y7HR.js.map +1 -0
- package/dist/report-mirror-4MNORYQ4.js +49 -0
- package/dist/report-mirror-4MNORYQ4.js.map +1 -0
- package/dist/reports/header-image/assets/headline-announcement.png +0 -0
- package/dist/reports/header-image/assets/headline-launch.png +0 -0
- package/dist/reports/header-image/assets/headline-maintenance.png +0 -0
- package/dist/reports/header-image/assets/headline-testing.png +0 -0
- package/dist/reports/header-image/assets/plate-clean.png +0 -0
- package/dist/rerender-3FM6DNRH.js +32 -0
- package/dist/rerender-3FM6DNRH.js.map +1 -0
- package/dist/{self-updating-PPQVV6UA.js → self-updating-UCIWESAX.js} +9 -9
- package/dist/{selftest-CQ6NOX52.js → selftest-VGHWPN72.js} +31 -24
- package/dist/selftest-VGHWPN72.js.map +1 -0
- package/dist/site-mirror-NIREX5ME.js +52 -0
- package/dist/site-mirror-NIREX5ME.js.map +1 -0
- package/dist/smoke-B2GQOSIZ.js +20 -0
- package/dist/smoke-B2GQOSIZ.js.map +1 -0
- package/dist/{smoke-suite-TMCSOYRK.js → smoke-suite-U3UKD3NS.js} +9 -9
- package/dist/{submissions-GJ6ITBRH.js → submissions-IQEJX6FK.js} +3 -3
- package/dist/{svelte-codemods-ZOBDHIES.js → svelte-codemods-GOKXTBHW.js} +9 -9
- package/dist/sync-CTUVXMCK.js +44 -0
- package/dist/sync-CTUVXMCK.js.map +1 -0
- package/dist/{sync-configs-CJXUX6MD.js → sync-configs-SPTLFJCC.js} +9 -9
- package/dist/{upgrade-WLX27UPC.js → upgrade-W6ZR3FJH.js} +9 -9
- package/dist/webhook-VOGOW3W6.js +38 -0
- package/dist/webhook-VOGOW3W6.js.map +1 -0
- package/dist/{websites-SADZR4XQ.js → websites-D6WYFAES.js} +6 -2
- package/dist/websites-D6WYFAES.js.map +1 -0
- package/dist/{write-audits-to-airtable-7PH75YWY.js → write-audits-to-airtable-CMKHGJNQ.js} +4 -4
- package/dist/write-audits-to-airtable-CMKHGJNQ.js.map +1 -0
- package/package.json +9 -2
- package/dist/airtable-HRKSA7V4.js +0 -9
- package/dist/announce-GIAYN67S.js.map +0 -1
- package/dist/chunk-37S6L6G4.js.map +0 -1
- package/dist/chunk-3YXDSCM6.js.map +0 -1
- package/dist/chunk-4DHQCN5H.js.map +0 -1
- package/dist/chunk-4SOCPK7A.js +0 -108
- package/dist/chunk-4SOCPK7A.js.map +0 -1
- package/dist/chunk-577HCGZO.js.map +0 -1
- package/dist/chunk-62VF32IC.js.map +0 -1
- package/dist/chunk-6QRLRT3P.js.map +0 -1
- package/dist/chunk-COZPL62X.js.map +0 -1
- package/dist/chunk-D4FVAIEJ.js.map +0 -1
- package/dist/chunk-DTTIFYAM.js.map +0 -1
- package/dist/chunk-MGR2H7F4.js.map +0 -1
- package/dist/chunk-MPBXOJ3N.js.map +0 -1
- package/dist/chunk-NWB4O5EY.js.map +0 -1
- package/dist/chunk-SEEA6RXF.js.map +0 -1
- package/dist/chunk-U5SZ4FOP.js +0 -26
- package/dist/chunk-U5SZ4FOP.js.map +0 -1
- package/dist/client-X5WUJWDE.js +0 -11
- package/dist/db-JSIZYT23.js +0 -23
- package/dist/db-JSIZYT23.js.map +0 -1
- package/dist/ensure-site-S25MDDHW.js.map +0 -1
- package/dist/forms-notify-target-TWN4EH6K.js.map +0 -1
- package/dist/github-signals-G4ILZAJ6.js.map +0 -1
- package/dist/header-image-T7XD37JL.js.map +0 -1
- package/dist/launch-JA7Z4CIM.js.map +0 -1
- package/dist/migrate-LJUFGXQZ.js +0 -7
- package/dist/orchestrate-KDNXZQX7.js +0 -27
- package/dist/prismic-models-PVES6R5V.js.map +0 -1
- package/dist/report-6CKSWJNG.js.map +0 -1
- package/dist/reports/header-image/assets/plate.png +0 -0
- package/dist/selftest-CQ6NOX52.js.map +0 -1
- /package/dist/{airtable-HRKSA7V4.js.map → airtable-ZBUPQJSC.js.map} +0 -0
- /package/dist/{client-X5WUJWDE.js.map → attachments-NLZIJ5NU.js.map} +0 -0
- /package/dist/{bump-deps-SWJB6H5V.js.map → bump-deps-CGVELRLK.js.map} +0 -0
- /package/dist/{chunk-SDUJIANJ.js.map → chunk-2NJQLSEU.js.map} +0 -0
- /package/dist/{chunk-ZTPPCHDB.js.map → chunk-3G25KIWW.js.map} +0 -0
- /package/dist/{chunk-THEFTZ7F.js.map → chunk-62CMMGEO.js.map} +0 -0
- /package/dist/{chunk-FDIFTIXC.js.map → chunk-6TWWY7ZU.js.map} +0 -0
- /package/dist/{chunk-PBWDDDQH.js.map → chunk-7BZUOZPU.js.map} +0 -0
- /package/dist/{chunk-UYCAF77E.js.map → chunk-7RJ2HMMJ.js.map} +0 -0
- /package/dist/{chunk-Q276MZ7E.js.map → chunk-7UAYMAKR.js.map} +0 -0
- /package/dist/{chunk-R6FPFMOS.js.map → chunk-BQRFQSGY.js.map} +0 -0
- /package/dist/{chunk-7J53SUT6.js.map → chunk-CROKUHJB.js.map} +0 -0
- /package/dist/{chunk-GZNBCHAZ.js.map → chunk-HEWSRXYV.js.map} +0 -0
- /package/dist/{chunk-LS6QPANO.js.map → chunk-IYSEC543.js.map} +0 -0
- /package/dist/{chunk-DC5H7KEQ.js.map → chunk-JHGHLKFS.js.map} +0 -0
- /package/dist/{chunk-TP5M2NQB.js.map → chunk-NCMZMLY7.js.map} +0 -0
- /package/dist/{chunk-WYYQK4D3.js.map → chunk-TD2NNXLZ.js.map} +0 -0
- /package/dist/{chunk-ZMIPG6TR.js.map → chunk-TVL5MVUF.js.map} +0 -0
- /package/dist/{chunk-VRWUL4TR.js.map → chunk-XHHMM5HX.js.map} +0 -0
- /package/dist/{chunk-RJB3QUSP.js.map → chunk-XIDUYLSR.js.map} +0 -0
- /package/dist/{chunk-QG6OSL4M.js.map → chunk-XUGSZP7Z.js.map} +0 -0
- /package/dist/{chunk-S56JQJ4F.js.map → chunk-Y53WOQIJ.js.map} +0 -0
- /package/dist/{chunk-ICXV25N7.js.map → chunk-Z3KYFUN6.js.map} +0 -0
- /package/dist/{lighthouse-airtable-BIPM26SZ.js.map → client-AUE3XUPO.js.map} +0 -0
- /package/dist/{convert-to-pnpm-AT52NWZB.js.map → convert-to-pnpm-QFJOEP5V.js.map} +0 -0
- /package/dist/{migrate-LJUFGXQZ.js.map → fleet-state-7TJ2GYT2.js.map} +0 -0
- /package/dist/{health-endpoint-242WG2OJ.js.map → health-endpoint-RFXL2F4A.js.map} +0 -0
- /package/dist/{orchestrate-KDNXZQX7.js.map → import-airtable-OHVY344G.js.map} +0 -0
- /package/dist/{websites-SADZR4XQ.js.map → lighthouse-VHI77PFB.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-7PH75YWY.js.map → lighthouse-airtable-3GUWHETW.js.map} +0 -0
- /package/dist/{onboard-53CITIM7.js.map → onboard-O4IAHJMO.js.map} +0 -0
- /package/dist/{prismic-ci-UTQ6LRR3.js.map → prismic-ci-G2AK53VL.js.map} +0 -0
- /package/dist/{protection-audit-64PLLBLI.js.map → protection-audit-SJO53MEQ.js.map} +0 -0
- /package/dist/{self-updating-PPQVV6UA.js.map → self-updating-UCIWESAX.js.map} +0 -0
- /package/dist/{smoke-suite-TMCSOYRK.js.map → smoke-suite-U3UKD3NS.js.map} +0 -0
- /package/dist/{submissions-GJ6ITBRH.js.map → submissions-IQEJX6FK.js.map} +0 -0
- /package/dist/{svelte-codemods-ZOBDHIES.js.map → svelte-codemods-GOKXTBHW.js.map} +0 -0
- /package/dist/{sync-configs-CJXUX6MD.js.map → sync-configs-SPTLFJCC.js.map} +0 -0
- /package/dist/{upgrade-WLX27UPC.js.map → upgrade-W6ZR3FJH.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
selfUpdating
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-62CMMGEO.js";
|
|
4
4
|
import "./chunk-MNDIED4M.js";
|
|
5
5
|
import {
|
|
6
6
|
runRecipeOverSites
|
|
@@ -9,18 +9,18 @@ import {
|
|
|
9
9
|
appendSkipNotice,
|
|
10
10
|
fleetWorkdir,
|
|
11
11
|
prepareFleetSites
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TVL5MVUF.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveSites
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-CROKUHJB.js";
|
|
16
16
|
import "./chunk-73UFRZKY.js";
|
|
17
17
|
import "./chunk-GASBX52O.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-XXTZBPUY.js";
|
|
18
|
+
import "./chunk-XHHMM5HX.js";
|
|
19
|
+
import "./chunk-6TWWY7ZU.js";
|
|
20
|
+
import "./chunk-EVBCK2KC.js";
|
|
22
21
|
import "./chunk-XTK5VIQB.js";
|
|
23
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-LBYOLBW7.js";
|
|
23
|
+
import "./chunk-XXTZBPUY.js";
|
|
24
24
|
|
|
25
25
|
// src/cli/commands/self-updating.ts
|
|
26
26
|
import { resolve } from "path";
|
|
@@ -62,4 +62,4 @@ async function runSelfUpdatingCommand(site, opts) {
|
|
|
62
62
|
export {
|
|
63
63
|
runSelfUpdatingCommand
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=self-updating-
|
|
65
|
+
//# sourceMappingURL=self-updating-UCIWESAX.js.map
|
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildReportDataForSite,
|
|
3
3
|
scoresFromRow
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HEWSRXYV.js";
|
|
5
5
|
import {
|
|
6
6
|
operatorEmail
|
|
7
7
|
} from "./chunk-5ML7FMBD.js";
|
|
8
|
+
import "./chunk-BBUSGEES.js";
|
|
8
9
|
import {
|
|
9
10
|
ELIGIBLE_STATUSES
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-62VF32IC.js";
|
|
13
|
-
import "./chunk-37S6L6G4.js";
|
|
11
|
+
} from "./chunk-PZR4EBPY.js";
|
|
12
|
+
import "./chunk-YFAXOD7Z.js";
|
|
14
13
|
import {
|
|
15
14
|
isProbablyEmail,
|
|
16
|
-
parseAddresses
|
|
15
|
+
parseAddresses
|
|
16
|
+
} from "./chunk-NDWYJLRF.js";
|
|
17
|
+
import "./chunk-F3JWOPTG.js";
|
|
18
|
+
import "./chunk-VAD43MOR.js";
|
|
19
|
+
import {
|
|
20
|
+
fetchAttachmentBytes
|
|
21
|
+
} from "./chunk-IY6256GK.js";
|
|
22
|
+
import {
|
|
23
|
+
openBase,
|
|
24
|
+
readAirtableConfig
|
|
25
|
+
} from "./chunk-HN6I2XWI.js";
|
|
26
|
+
import {
|
|
17
27
|
prepareHeaderImage,
|
|
18
28
|
renderReportEmail
|
|
19
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-ZGBEIWSC.js";
|
|
20
30
|
import "./chunk-GECESMVS.js";
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import
|
|
23
|
-
fetchAttachmentBytes
|
|
24
|
-
} from "./chunk-MPBXOJ3N.js";
|
|
25
|
-
import "./chunk-SEEA6RXF.js";
|
|
31
|
+
import "./chunk-MT2JINSS.js";
|
|
32
|
+
import "./chunk-DJZWYIPP.js";
|
|
26
33
|
import {
|
|
27
|
-
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-QG6OSL4M.js";
|
|
30
|
-
import "./chunk-DC5H7KEQ.js";
|
|
31
|
-
import "./chunk-4SOCPK7A.js";
|
|
32
|
-
import "./chunk-U5SZ4FOP.js";
|
|
34
|
+
applyReportTypeHeadline
|
|
35
|
+
} from "./chunk-5UINJNAJ.js";
|
|
33
36
|
import {
|
|
34
37
|
listWebsites,
|
|
35
38
|
siteSlug
|
|
36
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-7NYN2P6I.js";
|
|
37
40
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
defaultResendClient
|
|
42
|
+
} from "./chunk-WEKL2HYJ.js";
|
|
43
|
+
import "./chunk-XUGSZP7Z.js";
|
|
44
|
+
import "./chunk-EVBCK2KC.js";
|
|
45
|
+
import "./chunk-JHGHLKFS.js";
|
|
46
|
+
import "./chunk-3SF7D4DY.js";
|
|
41
47
|
import "./chunk-6VAL7XJT.js";
|
|
42
48
|
|
|
43
49
|
// src/recipes/selftest-email.ts
|
|
@@ -85,7 +91,8 @@ async function selftestEmail(deps) {
|
|
|
85
91
|
continue;
|
|
86
92
|
}
|
|
87
93
|
const original = await fetchAttachmentBytes(w.headerImage.url);
|
|
88
|
-
const
|
|
94
|
+
const withHeadline = await applyReportTypeHeadline(original.bytes, type);
|
|
95
|
+
const header = await prepareHeaderImage(withHeadline);
|
|
89
96
|
const slug = siteSlug(w.name);
|
|
90
97
|
const reportData = await buildReportDataForSite(w, type, now, { scores, header });
|
|
91
98
|
const { html, attachments, subject } = await renderReportEmail(reportData, {
|
|
@@ -165,4 +172,4 @@ async function runSelftestCommand(kind, site, opts) {
|
|
|
165
172
|
export {
|
|
166
173
|
runSelftestCommand
|
|
167
174
|
};
|
|
168
|
-
//# sourceMappingURL=selftest-
|
|
175
|
+
//# sourceMappingURL=selftest-VGHWPN72.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recipes/selftest-email.ts","../src/cli/commands/selftest.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { openBase, readAirtableConfig } from \"../reports/airtable/client.js\";\nimport type { AirtableBase } from \"../reports/airtable/client.js\";\nimport { listWebsites, siteSlug } from \"../reports/airtable/websites.js\";\nimport { ELIGIBLE_STATUSES } from \"../reports/due.js\";\nimport type { WebsiteRow } from \"../reports/airtable/websites.js\";\nimport { fetchAttachmentBytes } from \"../reports/airtable/attachments.js\";\nimport { prepareHeaderImage } from \"../reports/maintenance-email/header-image.js\";\nimport { applyReportTypeHeadline } from \"../reports/header-image/index.js\";\nimport { buildReportDataForSite, scoresFromRow } from \"../reports/report-data.js\";\nimport { renderReportEmail } from \"../reports/send/render-email.js\";\nimport { defaultResendClient, type ResendClient } from \"../reports/send/resend.js\";\nimport { parseAddresses, isProbablyEmail } from \"../reports/send/orchestrate.js\";\nimport { operatorEmail } from \"../util/operator.js\";\nimport type { ReportType } from \"../reports/types.js\";\n\nconst FROM_ADDRESS = \"Reddoor Reports <reports@reddoorla.com>\";\nconst REPLY_TO = \"info@reddoorla.com\";\n\nexport type SelftestEmailDeps = {\n /** Airtable handle (read-only here). Defaults to the live base from credentials. */\n base?: AirtableBase;\n /** Resend client. Defaults to the real client. */\n resend?: ResendClient;\n /** Single-site slug. Mutually exclusive with `all`. */\n site?: string;\n /** All `maintenance` sites (one email each). Mutually exclusive with `site`. */\n all?: boolean;\n /** Report type to preview. Default \"Announcement\". */\n type?: ReportType;\n /** Raw `--to` (comma- or newline-separated). Default: the operator inbox. */\n to?: string;\n /** Render only; write reports/<slug>/selftest-<type>.html, never send. */\n dryRun?: boolean;\n /** Single timestamp driving the window + completedOn. */\n now?: Date;\n};\n\nexport type SelftestEmailSiteResult =\n | { site: string; status: \"sent\" | \"dry-run\"; subject: string; recipients: string[] }\n | { site: string; status: \"skipped\"; reason: string }\n | { site: string; status: \"error\"; message: string };\n\nexport type SelftestEmailResult = { results: SelftestEmailSiteResult[] };\n\n/** Resolve the recipient list: explicit `--to` (validated) else the operator default. */\nfunction resolveRecipients(to: string | undefined): string[] {\n const operator = operatorEmail();\n const parsed = to ? parseAddresses(to) : null;\n const list = parsed ?? [operator];\n for (const addr of list) {\n if (!isProbablyEmail(addr)) {\n throw Object.assign(new Error(`--to has a malformed address: ${addr}`), { exitCode: 2 });\n }\n }\n return list;\n}\n\n/**\n * Send (or dry-render) a single report email per target site to the operator/`--to`, with NO\n * Airtable side effects (no draft, queue, or stamp). Mirrors the production render+send via the\n * shared `renderReportEmail` seam, so the preview matches a real send. One bad site never aborts\n * `--all` (per-site try/catch). Sites missing stored scores or a header image are skipped.\n */\nexport async function selftestEmail(deps: SelftestEmailDeps): Promise<SelftestEmailResult> {\n const base = deps.base ?? openBase(readAirtableConfig());\n const resend = deps.resend ?? defaultResendClient();\n const type: ReportType = deps.type ?? \"Announcement\";\n const now = deps.now ?? new Date();\n const recipients = resolveRecipients(deps.to);\n\n const websites = await listWebsites(base);\n let targets: WebsiteRow[];\n if (deps.all) {\n // The report-eligible set (maintained + hosted-only), not a hard-coded \"maintained\" —\n // the latter silently excluded hosting sites and implied a type↔status coupling that\n // doesn't exist (the requested --type drives the rendered template; single-site mode\n // applies no status filter at all).\n targets = websites.filter((w) => w.status !== null && ELIGIBLE_STATUSES.has(w.status));\n } else if (deps.site) {\n const wanted = siteSlug(deps.site);\n targets = websites.filter((w) => siteSlug(w.name) === wanted);\n } else {\n throw Object.assign(new Error(\"Provide a site slug or --all\"), { exitCode: 2 });\n }\n\n const results: SelftestEmailSiteResult[] = [];\n for (const w of targets) {\n try {\n const scores = scoresFromRow(w);\n if (!scores) {\n results.push({ site: w.name, status: \"skipped\", reason: \"missing Lighthouse scores\" });\n continue;\n }\n if (!w.headerImage) {\n results.push({ site: w.name, status: \"skipped\", reason: \"no Header image\" });\n continue;\n }\n const original = await fetchAttachmentBytes(w.headerImage.url);\n // Mirror orchestrate.ts exactly: the stored header is the CLEAN plate, so the\n // report type's headline has to be stamped on before downscaling. Omitting this\n // step made every selftest preview ship a header with an EMPTY headline band —\n // the one thing a preview exists to catch, silently wrong in the preview itself.\n const withHeadline = await applyReportTypeHeadline(original.bytes, type);\n const header = await prepareHeaderImage(withHeadline);\n const slug = siteSlug(w.name);\n const reportData = await buildReportDataForSite(w, type, now, { scores, header });\n const { html, attachments, subject } = await renderReportEmail(reportData, {\n header,\n cidName: `${slug}-header`,\n });\n\n if (deps.dryRun) {\n const path = `reports/${slug}/selftest-${type.toLowerCase()}.html`;\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, html, \"utf-8\");\n results.push({ site: w.name, status: \"dry-run\", subject, recipients });\n continue;\n }\n\n await resend.send({\n from: FROM_ADDRESS,\n to: recipients,\n replyTo: REPLY_TO,\n subject,\n html,\n attachments,\n });\n results.push({ site: w.name, status: \"sent\", subject, recipients });\n } catch (err) {\n results.push({\n site: w.name,\n status: \"error\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { results };\n}\n","import { selftestEmail, type SelftestEmailSiteResult } from \"../../recipes/selftest-email.js\";\nimport type { ReportType } from \"../../reports/types.js\";\n\nexport type SelftestCommandOptions = {\n type?: string;\n to?: string;\n all?: boolean;\n dryRun?: boolean;\n cwd?: string;\n};\n\nconst TYPES: Record<string, ReportType> = {\n announcement: \"Announcement\",\n maintenance: \"Maintenance\",\n testing: \"Testing\",\n launch: \"Launch\",\n};\n\nfunction formatResult(r: SelftestEmailSiteResult): string {\n if (r.status === \"skipped\") return `[${r.site}] skipped — ${r.reason}`;\n if (r.status === \"error\") return `[${r.site}] error: ${r.message}`;\n return `[${r.site}] ${r.status} — \"${r.subject}\" → ${r.recipients.join(\", \")}`;\n}\n\n/**\n * `selftest <kind> [site]` — operator self-tests. The only kind today is `email`: preview a\n * report email for one site (or `--all` maintenance sites) to the operator/`--to`, with no\n * Airtable side effects. Validates kind/type and the site-xor-all rule before doing any work.\n */\nexport async function runSelftestCommand(\n kind: string,\n site: string | undefined,\n opts: SelftestCommandOptions,\n): Promise<{ output: string; code: number }> {\n if (kind !== \"email\") {\n return { output: `Unknown selftest kind '${kind}'. Supported: email`, code: 2 };\n }\n if (Boolean(site) === Boolean(opts.all)) {\n return { output: \"Provide exactly one of <site> or --all.\", code: 2 };\n }\n const typeKey = (opts.type ?? \"announcement\").toLowerCase();\n const type = TYPES[typeKey];\n if (!type) {\n return {\n output: `Unknown --type '${opts.type}'. Supported: ${Object.keys(TYPES).join(\", \")}`,\n code: 2,\n };\n }\n\n try {\n const { results } = await selftestEmail({\n ...(site ? { site } : {}),\n ...(opts.all ? { all: true } : {}),\n type,\n ...(opts.to ? { to: opts.to } : {}),\n ...(opts.dryRun ? { dryRun: true } : {}),\n });\n const output =\n results.length === 0 ? \"No matching sites.\" : results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"error\") ? 1 : 0;\n return { output, code };\n } catch (err) {\n const e = err as { message?: string; exitCode?: number };\n return { output: e.message ?? String(err), code: e.exitCode ?? 1 };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mirrorHealthFields,
|
|
3
|
+
mirrorSiteFields,
|
|
4
|
+
mirrorSiteInsert
|
|
5
|
+
} from "./chunk-HHMMUR4P.js";
|
|
6
|
+
import "./chunk-P6AORG32.js";
|
|
7
|
+
import "./chunk-F3JWOPTG.js";
|
|
8
|
+
import "./chunk-VAD43MOR.js";
|
|
9
|
+
import "./chunk-7NYN2P6I.js";
|
|
10
|
+
import {
|
|
11
|
+
openDb,
|
|
12
|
+
readDbConfig
|
|
13
|
+
} from "./chunk-JHGHLKFS.js";
|
|
14
|
+
import "./chunk-3SF7D4DY.js";
|
|
15
|
+
import "./chunk-6VAL7XJT.js";
|
|
16
|
+
|
|
17
|
+
// src/db/site-mirror.ts
|
|
18
|
+
async function makeSiteMirror(open = () => openDb(readDbConfig())) {
|
|
19
|
+
let db = null;
|
|
20
|
+
let why = "";
|
|
21
|
+
try {
|
|
22
|
+
db = await open();
|
|
23
|
+
} catch (e) {
|
|
24
|
+
why = e.message;
|
|
25
|
+
}
|
|
26
|
+
const run = async (siteId, op, work) => {
|
|
27
|
+
if (!db) {
|
|
28
|
+
console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=absent reason=${why}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const matched = await work(db);
|
|
33
|
+
console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=${matched ? "1" : "missed"}`);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=0 error=${e.message}`);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
// An INSERT always lands, so it reports 1 rather than routing a row count
|
|
40
|
+
// through `missed` — there was nothing to match in the first place.
|
|
41
|
+
created: (rec) => run(rec.id, "created", async (d) => {
|
|
42
|
+
await mirrorSiteInsert(d, rec, (/* @__PURE__ */ new Date()).toISOString());
|
|
43
|
+
return true;
|
|
44
|
+
}),
|
|
45
|
+
health: (siteId, fields) => run(siteId, "health", (d) => mirrorHealthFields(d, siteId, fields)),
|
|
46
|
+
site: (siteId, fields) => run(siteId, "site", (d) => mirrorSiteFields(d, siteId, fields))
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
makeSiteMirror
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=site-mirror-NIREX5ME.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db/site-mirror.ts"],"sourcesContent":["/** #539 Phase 5: the Turso write-through for the ONE-OFF Websites writers.\n *\n * Phase 3 mirrored the nightly sweep — the audit write-back, github-signals and\n * the next-due dates. It did not touch the writers that run on their own\n * schedule or on demand: the analytics soft-fail stamp, the Renovate\n * auto-fix counter, the prismic-models verdict, `updateLaunched`, the\n * forms notify target, and the SINGLE-SITE audit write-back (only the fleet\n * path ever passed a mirror). Each of those reached Turso solely via the hourly\n * sync, which stops existing at the freeze.\n *\n * It lives in `src/db` rather than a feature folder because its callers span\n * audits, recipes, CLI commands and the send path — no one feature owns it.\n *\n * Deliberately UNLIKE `makeHealthMirrorBestEffort`, this never returns null.\n * #585 is the reason: that factory returned null without creds and the\n * dual-write silently no-opped in production for weeks, because a dead mirror\n * and a healthy one produced identical output — the only tell was an ABSENT log\n * suffix nobody was watching for. Here creds-absent is a state the mirror\n * REPORTS, so a missing SITE_MIRROR line means the wiring is gone.\n */\nimport { openDb, readDbConfig, type Db } from \"./client.js\";\nimport { mirrorHealthFields, mirrorSiteFields, mirrorSiteInsert } from \"./fleet-state.js\";\n\n/** Two ops because the Websites row is split across two Turso tables. Callers\n * pass the EXACT FieldSet the Airtable writer returned, so the mirror can never\n * carry a different payload than the write it shadows. */\nexport type SiteMirror = {\n /** A row Airtable just CREATED, as Airtable echoed it back (`ensure-site`).\n * Every other op is an UPDATE, which does nothing for a row that does not\n * exist yet — so without this a bootstrapped site is invisible to Turso and\n * every mirror the rest of the bootstrap fires reports `mirrored=missed`. */\n created: (rec: { id: string; fields: Record<string, unknown> }) => Promise<void>;\n /** Columns that live in `site_health`. */\n health: (siteId: string, fields: Record<string, unknown>) => Promise<void>;\n /** Columns that live in `sites`. */\n site: (siteId: string, fields: Record<string, unknown>) => Promise<void>;\n};\n\n/** Build the one-off writers' mirror. Never throws and never returns null:\n * Airtable is still authoritative through Phase 5, so a mirror problem must not\n * cost the write it shadows — the hourly sync converges whatever this misses.\n * `open` is injectable for tests. */\nexport async function makeSiteMirror(\n open: () => Promise<Db> = () => openDb(readDbConfig()),\n): Promise<SiteMirror> {\n let db: Db | null = null;\n let why = \"\";\n try {\n db = await open();\n } catch (e) {\n why = (e as Error).message;\n }\n\n const run = async (siteId: string, op: string, work: (db: Db) => Promise<boolean>) => {\n if (!db) {\n console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=absent reason=${why}`);\n return;\n }\n try {\n // `missed` is its own outcome: the UPDATE matched no row because the\n // hourly sync has not imported this site yet. Reporting it as mirrored=1\n // would claim a write that never landed.\n const matched = await work(db);\n console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=${matched ? \"1\" : \"missed\"}`);\n } catch (e) {\n console.log(`SITE_MIRROR site=${siteId} op=${op} mirrored=0 error=${(e as Error).message}`);\n }\n };\n\n return {\n // An INSERT always lands, so it reports 1 rather than routing a row count\n // through `missed` — there was nothing to match in the first place.\n created: (rec) =>\n run(rec.id, \"created\", async (d) => {\n await mirrorSiteInsert(d, rec, new Date().toISOString());\n return true;\n }),\n health: (siteId, fields) => run(siteId, \"health\", (d) => mirrorHealthFields(d, siteId, fields)),\n site: (siteId, fields) => run(siteId, \"site\", (d) => mirrorSiteFields(d, siteId, fields)),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0CA,eAAsB,eACpB,OAA0B,MAAM,OAAO,aAAa,CAAC,GAChC;AACrB,MAAI,KAAgB;AACpB,MAAI,MAAM;AACV,MAAI;AACF,SAAK,MAAM,KAAK;AAAA,EAClB,SAAS,GAAG;AACV,UAAO,EAAY;AAAA,EACrB;AAEA,QAAM,MAAM,OAAO,QAAgB,IAAY,SAAuC;AACpF,QAAI,CAAC,IAAI;AACP,cAAQ,IAAI,oBAAoB,MAAM,OAAO,EAAE,2BAA2B,GAAG,EAAE;AAC/E;AAAA,IACF;AACA,QAAI;AAIF,YAAM,UAAU,MAAM,KAAK,EAAE;AAC7B,cAAQ,IAAI,oBAAoB,MAAM,OAAO,EAAE,aAAa,UAAU,MAAM,QAAQ,EAAE;AAAA,IACxF,SAAS,GAAG;AACV,cAAQ,IAAI,oBAAoB,MAAM,OAAO,EAAE,qBAAsB,EAAY,OAAO,EAAE;AAAA,IAC5F;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA,IAGL,SAAS,CAAC,QACR,IAAI,IAAI,IAAI,WAAW,OAAO,MAAM;AAClC,YAAM,iBAAiB,GAAG,MAAK,oBAAI,KAAK,GAAE,YAAY,CAAC;AACvD,aAAO;AAAA,IACT,CAAC;AAAA,IACH,QAAQ,CAAC,QAAQ,WAAW,IAAI,QAAQ,UAAU,CAAC,MAAM,mBAAmB,GAAG,QAAQ,MAAM,CAAC;AAAA,IAC9F,MAAM,CAAC,QAAQ,WAAW,IAAI,QAAQ,QAAQ,CAAC,MAAM,iBAAiB,GAAG,QAAQ,MAAM,CAAC;AAAA,EAC1F;AACF;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SMOKE_TIMEOUT_MS,
|
|
3
|
+
SMOKE_UNMEASURED_PREFIX,
|
|
4
|
+
formatUnmeasuredSmokeSummary,
|
|
5
|
+
isUnmeasuredSmoke,
|
|
6
|
+
smokeAudit,
|
|
7
|
+
summarizeSmokeFailure
|
|
8
|
+
} from "./chunk-UDRHAQT7.js";
|
|
9
|
+
import "./chunk-PTDMVGKL.js";
|
|
10
|
+
import "./chunk-LBYOLBW7.js";
|
|
11
|
+
import "./chunk-XXTZBPUY.js";
|
|
12
|
+
export {
|
|
13
|
+
SMOKE_TIMEOUT_MS,
|
|
14
|
+
SMOKE_UNMEASURED_PREFIX,
|
|
15
|
+
formatUnmeasuredSmokeSummary,
|
|
16
|
+
isUnmeasuredSmoke,
|
|
17
|
+
smokeAudit,
|
|
18
|
+
summarizeSmokeFailure
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=smoke-B2GQOSIZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -5,20 +5,20 @@ import {
|
|
|
5
5
|
appendSkipNotice,
|
|
6
6
|
fleetWorkdir,
|
|
7
7
|
prepareFleetSites
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TVL5MVUF.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveSites
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CROKUHJB.js";
|
|
12
12
|
import {
|
|
13
13
|
smokeSuite
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Y53WOQIJ.js";
|
|
15
15
|
import "./chunk-R53VL3RI.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-XXTZBPUY.js";
|
|
16
|
+
import "./chunk-3G25KIWW.js";
|
|
17
|
+
import "./chunk-6TWWY7ZU.js";
|
|
18
|
+
import "./chunk-EVBCK2KC.js";
|
|
20
19
|
import "./chunk-XTK5VIQB.js";
|
|
21
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-LBYOLBW7.js";
|
|
21
|
+
import "./chunk-XXTZBPUY.js";
|
|
22
22
|
|
|
23
23
|
// src/cli/commands/smoke-suite.ts
|
|
24
24
|
import { resolve } from "path";
|
|
@@ -51,4 +51,4 @@ async function runSmokeSuiteCommand(site, opts) {
|
|
|
51
51
|
export {
|
|
52
52
|
runSmokeSuiteCommand
|
|
53
53
|
};
|
|
54
|
-
//# sourceMappingURL=smoke-suite-
|
|
54
|
+
//# sourceMappingURL=smoke-suite-U3UKD3NS.js.map
|
|
@@ -41,7 +41,7 @@ async function rescoreNewSubmissions(db, opts) {
|
|
|
41
41
|
async function loadSiteNames() {
|
|
42
42
|
try {
|
|
43
43
|
const { openBase, readAirtableConfig } = await import("./client-EPVO3FEH.js");
|
|
44
|
-
const { listWebsites } = await import("./websites-
|
|
44
|
+
const { listWebsites } = await import("./websites-D6WYFAES.js");
|
|
45
45
|
const sites = await listWebsites(openBase(readAirtableConfig()));
|
|
46
46
|
return new Map(sites.map((s) => [s.id, s.name]));
|
|
47
47
|
} catch (err) {
|
|
@@ -78,7 +78,7 @@ async function runSubmissionsCommand(action, opts) {
|
|
|
78
78
|
return { output: "--apply and --dry-run conflict. Pick one.", code: 2 };
|
|
79
79
|
}
|
|
80
80
|
const apply = opts.apply === true;
|
|
81
|
-
const { openDb, readDbConfig } = await import("./client-
|
|
81
|
+
const { openDb, readDbConfig } = await import("./client-AUE3XUPO.js");
|
|
82
82
|
const { SPAM_THRESHOLD } = await import("./spam-classifier-XLBFCO7G.js");
|
|
83
83
|
const cfg = opts.url ? { url: opts.url } : readDbConfig();
|
|
84
84
|
const db = await openDb(cfg);
|
|
@@ -119,4 +119,4 @@ export {
|
|
|
119
119
|
rescoreNewSubmissions,
|
|
120
120
|
runSubmissionsCommand
|
|
121
121
|
};
|
|
122
|
-
//# sourceMappingURL=submissions-
|
|
122
|
+
//# sourceMappingURL=submissions-IQEJX6FK.js.map
|
|
@@ -5,20 +5,20 @@ import {
|
|
|
5
5
|
appendSkipNotice,
|
|
6
6
|
fleetWorkdir,
|
|
7
7
|
prepareFleetSites
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TVL5MVUF.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveSites
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CROKUHJB.js";
|
|
12
12
|
import {
|
|
13
13
|
svelteCodemods
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IYSEC543.js";
|
|
15
15
|
import "./chunk-J7SZQUCW.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-XXTZBPUY.js";
|
|
16
|
+
import "./chunk-3G25KIWW.js";
|
|
17
|
+
import "./chunk-6TWWY7ZU.js";
|
|
18
|
+
import "./chunk-EVBCK2KC.js";
|
|
20
19
|
import "./chunk-XTK5VIQB.js";
|
|
21
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-LBYOLBW7.js";
|
|
21
|
+
import "./chunk-XXTZBPUY.js";
|
|
22
22
|
|
|
23
23
|
// src/cli/commands/svelte-codemods.ts
|
|
24
24
|
import { resolve } from "path";
|
|
@@ -51,4 +51,4 @@ async function runSvelteCodemodsCommand(site, opts) {
|
|
|
51
51
|
export {
|
|
52
52
|
runSvelteCodemodsCommand
|
|
53
53
|
};
|
|
54
|
-
//# sourceMappingURL=svelte-codemods-
|
|
54
|
+
//# sourceMappingURL=svelte-codemods-GOKXTBHW.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkFleetParity,
|
|
3
|
+
formatParityResult
|
|
4
|
+
} from "./chunk-ZBDZTJUO.js";
|
|
5
|
+
import {
|
|
6
|
+
formatReapSummary,
|
|
7
|
+
importFleetState
|
|
8
|
+
} from "./chunk-P6AORG32.js";
|
|
9
|
+
import "./chunk-VAD43MOR.js";
|
|
10
|
+
import "./chunk-7NYN2P6I.js";
|
|
11
|
+
|
|
12
|
+
// src/db/sync.ts
|
|
13
|
+
async function syncFleetState(db, io) {
|
|
14
|
+
let importSummary = await importFleetState(db, io, { reportHtml: "when-missing" });
|
|
15
|
+
let parity = await checkFleetParity(db, io);
|
|
16
|
+
let retried = false;
|
|
17
|
+
if (parity.mismatches.length > 0) {
|
|
18
|
+
retried = true;
|
|
19
|
+
importSummary = await importFleetState(db, io, { reportHtml: "when-missing" });
|
|
20
|
+
parity = await checkFleetParity(db, io);
|
|
21
|
+
}
|
|
22
|
+
return { importSummary, parity, retried };
|
|
23
|
+
}
|
|
24
|
+
function formatSyncResult(r) {
|
|
25
|
+
const lines = [];
|
|
26
|
+
if (r.importSummary.renderedHtmlMisses.length > 0) {
|
|
27
|
+
lines.push(
|
|
28
|
+
`\u26A0 ${r.importSummary.renderedHtmlMisses.length} report(s) imported WITHOUT Rendered HTML (fetch failed / URL expired): ${r.importSummary.renderedHtmlMisses.join(", ")}`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
lines.push(...formatReapSummary(r.importSummary.reaped));
|
|
32
|
+
if (r.parity.mismatches.length > 0) {
|
|
33
|
+
lines.push(formatParityResult(r.parity));
|
|
34
|
+
}
|
|
35
|
+
lines.push(
|
|
36
|
+
`FLEET_SYNC sites=${r.importSummary.sites} reports=${r.importSummary.reports} html_fetched=${r.importSummary.renderedHtmlFetched} html_skipped=${r.importSummary.renderedHtmlSkipped} retried=${r.retried ? 1 : 0} mismatches=${r.parity.mismatches.length}`
|
|
37
|
+
);
|
|
38
|
+
return lines.join("\n");
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
formatSyncResult,
|
|
42
|
+
syncFleetState
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=sync-CTUVXMCK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db/sync.ts"],"sourcesContent":["/** Phase 2 backbone of the Airtable → Turso migration (#539): the hourly sync.\n *\n * In Phase 2 readers move to Turso while writers still write Airtable, so\n * Turso is only as fresh as the last import. One sync pass = import (with\n * reportHtml \"when-missing\", so hourly runs don't re-download every report\n * attachment) followed by the parity check, so every pass both refreshes the\n * copy and PROVES it converged — the same instrument the whole cutover trusts.\n *\n * The retry exists for a specific race, not for flakiness: the importer and\n * the parity check each read Airtable separately, so a write landing between\n * those two reads makes parity flag rows the import genuinely never saw. One\n * re-import + re-check converges unless Airtable is being written continuously\n * — a persistent mismatch after the retry is real drift and must red the run.\n */\nimport type { Db } from \"./client.js\";\nimport {\n importFleetState,\n formatReapSummary,\n type ImportIo,\n type ImportSummary,\n} from \"./import-airtable.js\";\nimport { checkFleetParity, formatParityResult, type ParityResult } from \"./parity.js\";\n\nexport type SyncResult = {\n importSummary: ImportSummary;\n parity: ParityResult;\n /** True when the first parity check mismatched and the pass re-imported. */\n retried: boolean;\n};\n\nexport async function syncFleetState(db: Db, io: ImportIo): Promise<SyncResult> {\n let importSummary = await importFleetState(db, io, { reportHtml: \"when-missing\" });\n let parity = await checkFleetParity(db, io);\n let retried = false;\n if (parity.mismatches.length > 0) {\n retried = true;\n importSummary = await importFleetState(db, io, { reportHtml: \"when-missing\" });\n parity = await checkFleetParity(db, io);\n }\n return { importSummary, parity, retried };\n}\n\n/** Human lines plus the machine gate line, emitted on EVERY run (count=0\n * included) — an absent FLEET_SYNC line means the sync crashed, never that it\n * was clean. */\nexport function formatSyncResult(r: SyncResult): string {\n const lines: string[] = [];\n if (r.importSummary.renderedHtmlMisses.length > 0) {\n lines.push(\n `⚠ ${r.importSummary.renderedHtmlMisses.length} report(s) imported WITHOUT Rendered HTML ` +\n `(fetch failed / URL expired): ${r.importSummary.renderedHtmlMisses.join(\", \")}`,\n );\n }\n // The reap is the only destructive step, so every removal is NAMED and every\n // refusal is quoted in full. FLEET_REAP rides its own line rather than as new\n // keys on FLEET_SYNC: the workflow gate greps `^FLEET_SYNC .* mismatches=0$`,\n // anchored at the end, so extending that line is a contract change waiting to\n // be got wrong. A separate always-emitted line costs nothing and, like\n // FLEET_PARITY, means an absent line reads as \"never ran\", not as \"clean\".\n lines.push(...formatReapSummary(r.importSummary.reaped));\n if (r.parity.mismatches.length > 0) {\n lines.push(formatParityResult(r.parity));\n }\n lines.push(\n `FLEET_SYNC sites=${r.importSummary.sites} reports=${r.importSummary.reports} ` +\n `html_fetched=${r.importSummary.renderedHtmlFetched} ` +\n `html_skipped=${r.importSummary.renderedHtmlSkipped} ` +\n `retried=${r.retried ? 1 : 0} mismatches=${r.parity.mismatches.length}`,\n );\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;;AA8BA,eAAsB,eAAe,IAAQ,IAAmC;AAC9E,MAAI,gBAAgB,MAAM,iBAAiB,IAAI,IAAI,EAAE,YAAY,eAAe,CAAC;AACjF,MAAI,SAAS,MAAM,iBAAiB,IAAI,EAAE;AAC1C,MAAI,UAAU;AACd,MAAI,OAAO,WAAW,SAAS,GAAG;AAChC,cAAU;AACV,oBAAgB,MAAM,iBAAiB,IAAI,IAAI,EAAE,YAAY,eAAe,CAAC;AAC7E,aAAS,MAAM,iBAAiB,IAAI,EAAE;AAAA,EACxC;AACA,SAAO,EAAE,eAAe,QAAQ,QAAQ;AAC1C;AAKO,SAAS,iBAAiB,GAAuB;AACtD,QAAM,QAAkB,CAAC;AACzB,MAAI,EAAE,cAAc,mBAAmB,SAAS,GAAG;AACjD,UAAM;AAAA,MACJ,UAAK,EAAE,cAAc,mBAAmB,MAAM,2EACX,EAAE,cAAc,mBAAmB,KAAK,IAAI,CAAC;AAAA,IAClF;AAAA,EACF;AAOA,QAAM,KAAK,GAAG,kBAAkB,EAAE,cAAc,MAAM,CAAC;AACvD,MAAI,EAAE,OAAO,WAAW,SAAS,GAAG;AAClC,UAAM,KAAK,mBAAmB,EAAE,MAAM,CAAC;AAAA,EACzC;AACA,QAAM;AAAA,IACJ,oBAAoB,EAAE,cAAc,KAAK,YAAY,EAAE,cAAc,OAAO,iBAC1D,EAAE,cAAc,mBAAmB,iBACnC,EAAE,cAAc,mBAAmB,YACxC,EAAE,UAAU,IAAI,CAAC,eAAe,EAAE,OAAO,WAAW,MAAM;AAAA,EACzE;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|
|
@@ -5,27 +5,27 @@ import {
|
|
|
5
5
|
appendSkipNotice,
|
|
6
6
|
fleetWorkdir,
|
|
7
7
|
prepareFleetSites
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TVL5MVUF.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveSites
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CROKUHJB.js";
|
|
12
12
|
import {
|
|
13
13
|
ALL_CONFIG_NAMES,
|
|
14
14
|
CANONICAL_GITIGNORE_ENTRIES,
|
|
15
15
|
isConfigName,
|
|
16
16
|
mergeGitignore,
|
|
17
17
|
syncConfigs
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7UAYMAKR.js";
|
|
19
19
|
import {
|
|
20
20
|
ALL_TEMPLATES,
|
|
21
21
|
templatesByName
|
|
22
22
|
} from "./chunk-73UFRZKY.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-XXTZBPUY.js";
|
|
23
|
+
import "./chunk-3G25KIWW.js";
|
|
24
|
+
import "./chunk-6TWWY7ZU.js";
|
|
25
|
+
import "./chunk-EVBCK2KC.js";
|
|
27
26
|
import "./chunk-XTK5VIQB.js";
|
|
28
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-LBYOLBW7.js";
|
|
28
|
+
import "./chunk-XXTZBPUY.js";
|
|
29
29
|
|
|
30
30
|
// src/cli/commands/sync-configs.ts
|
|
31
31
|
import { readFile } from "fs/promises";
|
|
@@ -113,4 +113,4 @@ async function runSyncConfigsCommand(site, opts) {
|
|
|
113
113
|
export {
|
|
114
114
|
runSyncConfigsCommand
|
|
115
115
|
};
|
|
116
|
-
//# sourceMappingURL=sync-configs-
|
|
116
|
+
//# sourceMappingURL=sync-configs-SPTLFJCC.js.map
|
|
@@ -5,21 +5,21 @@ import {
|
|
|
5
5
|
appendSkipNotice,
|
|
6
6
|
fleetWorkdir,
|
|
7
7
|
prepareFleetSites
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TVL5MVUF.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveSites
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CROKUHJB.js";
|
|
12
12
|
import {
|
|
13
13
|
upgradeSvelte4to5
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Z3KYFUN6.js";
|
|
15
15
|
import "./chunk-J7SZQUCW.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-3G25KIWW.js";
|
|
17
17
|
import "./chunk-OTGB6YQO.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-XXTZBPUY.js";
|
|
18
|
+
import "./chunk-6TWWY7ZU.js";
|
|
19
|
+
import "./chunk-EVBCK2KC.js";
|
|
21
20
|
import "./chunk-XTK5VIQB.js";
|
|
22
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-LBYOLBW7.js";
|
|
22
|
+
import "./chunk-XXTZBPUY.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/commands/upgrade.ts
|
|
25
25
|
import { resolve } from "path";
|
|
@@ -60,4 +60,4 @@ async function runUpgradeCommand(upgradeName, site, opts = {}) {
|
|
|
60
60
|
export {
|
|
61
61
|
runUpgradeCommand
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=upgrade-
|
|
63
|
+
//# sourceMappingURL=upgrade-W6ZR3FJH.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPublicHttpsUrl
|
|
3
|
+
} from "./chunk-EVBCK2KC.js";
|
|
4
|
+
|
|
5
|
+
// src/forms/webhook.ts
|
|
6
|
+
function buildNewsletterWebhookBody(submission, site) {
|
|
7
|
+
return {
|
|
8
|
+
email: submission.email,
|
|
9
|
+
name: submission.name,
|
|
10
|
+
formType: submission.formType,
|
|
11
|
+
site: site.name,
|
|
12
|
+
sourceUrl: submission.sourceUrl,
|
|
13
|
+
utm: submission.utm,
|
|
14
|
+
submittedAt: submission.submittedAt
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async function forwardNewsletterToWebhook(url, submission, site, fetchImpl = fetch) {
|
|
18
|
+
if (!isPublicHttpsUrl(url)) {
|
|
19
|
+
console.error(`[newsletter-webhook] refusing non-public/non-https url for site=${site.name}`);
|
|
20
|
+
return { ok: false, status: 0 };
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetchImpl(url, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: { "content-type": "application/json" },
|
|
26
|
+
body: JSON.stringify(buildNewsletterWebhookBody(submission, site))
|
|
27
|
+
});
|
|
28
|
+
return { ok: res.ok, status: res.status };
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error(`[newsletter-webhook] forward failed for site=${site.name}: ${String(err)}`);
|
|
31
|
+
return { ok: false, status: 0 };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
buildNewsletterWebhookBody,
|
|
36
|
+
forwardNewsletterToWebhook
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=webhook-VOGOW3W6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/forms/webhook.ts"],"sourcesContent":["import type { SubmissionRow } from \"../reports/submission-row.js\";\nimport type { WebsiteRow } from \"../reports/airtable/websites.js\";\nimport { isPublicHttpsUrl } from \"../util/url.js\";\n\nexport type WebhookForwardResult = { ok: boolean; status: number };\n\n/** The JSON body POSTed to a site's newsletter webhook (e.g. a Zapier Catch\n * Hook). Lean, newsletter-relevant fields; the Zap maps them downstream. */\nexport function buildNewsletterWebhookBody(\n submission: SubmissionRow,\n site: WebsiteRow,\n): Record<string, unknown> {\n return {\n email: submission.email,\n name: submission.name,\n formType: submission.formType,\n site: site.name,\n sourceUrl: submission.sourceUrl,\n utm: submission.utm,\n submittedAt: submission.submittedAt,\n };\n}\n\n/**\n * POST a newsletter submission to a site-configured webhook. NEVER throws — a\n * disallowed URL, non-2xx response, or network error returns `{ ok: false }` so\n * the caller treats it as a swallowed side-effect. Only PUBLIC https URLs are\n * allowed (the URL is operator-set in Airtable, but this is a server-side egress\n * — so an internal/loopback/private host is refused as an SSRF guard).\n */\nexport async function forwardNewsletterToWebhook(\n url: string,\n submission: SubmissionRow,\n site: WebsiteRow,\n fetchImpl: typeof fetch = fetch,\n): Promise<WebhookForwardResult> {\n if (!isPublicHttpsUrl(url)) {\n console.error(`[newsletter-webhook] refusing non-public/non-https url for site=${site.name}`);\n return { ok: false, status: 0 };\n }\n try {\n const res = await fetchImpl(url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(buildNewsletterWebhookBody(submission, site)),\n });\n return { ok: res.ok, status: res.status };\n } catch (err) {\n console.error(`[newsletter-webhook] forward failed for site=${site.name}: ${String(err)}`);\n return { ok: false, status: 0 };\n }\n}\n"],"mappings":";;;;;AAQO,SAAS,2BACd,YACA,MACyB;AACzB,SAAO;AAAA,IACL,OAAO,WAAW;AAAA,IAClB,MAAM,WAAW;AAAA,IACjB,UAAU,WAAW;AAAA,IACrB,MAAM,KAAK;AAAA,IACX,WAAW,WAAW;AAAA,IACtB,KAAK,WAAW;AAAA,IAChB,aAAa,WAAW;AAAA,EAC1B;AACF;AASA,eAAsB,2BACpB,KACA,YACA,MACA,YAA0B,OACK;AAC/B,MAAI,CAAC,iBAAiB,GAAG,GAAG;AAC1B,YAAQ,MAAM,mEAAmE,KAAK,IAAI,EAAE;AAC5F,WAAO,EAAE,IAAI,OAAO,QAAQ,EAAE;AAAA,EAChC;AACA,MAAI;AACF,UAAM,MAAM,MAAM,UAAU,KAAK;AAAA,MAC/B,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,2BAA2B,YAAY,IAAI,CAAC;AAAA,IACnE,CAAC;AACD,WAAO,EAAE,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO;AAAA,EAC1C,SAAS,KAAK;AACZ,YAAQ,MAAM,gDAAgD,KAAK,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AACzF,WAAO,EAAE,IAAI,OAAO,QAAQ,EAAE;AAAA,EAChC;AACF;","names":[]}
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
parseNotifyRouting,
|
|
18
18
|
parseSecurityAdvisories,
|
|
19
19
|
siteSlug,
|
|
20
|
+
toFrequency,
|
|
20
21
|
toPrismicModelsVerdict,
|
|
21
22
|
toVerdict,
|
|
23
|
+
trimToNull,
|
|
22
24
|
updateA11yCounts,
|
|
23
25
|
updateAnalyticsHealth,
|
|
24
26
|
updateAuditFields,
|
|
@@ -31,7 +33,7 @@ import {
|
|
|
31
33
|
updateScores,
|
|
32
34
|
updateSecurityCounts,
|
|
33
35
|
updateSiteField
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-7NYN2P6I.js";
|
|
35
37
|
export {
|
|
36
38
|
ACTIVE_STATUSES,
|
|
37
39
|
ARCHIVED_STATUSES,
|
|
@@ -51,8 +53,10 @@ export {
|
|
|
51
53
|
parseNotifyRouting,
|
|
52
54
|
parseSecurityAdvisories,
|
|
53
55
|
siteSlug,
|
|
56
|
+
toFrequency,
|
|
54
57
|
toPrismicModelsVerdict,
|
|
55
58
|
toVerdict,
|
|
59
|
+
trimToNull,
|
|
56
60
|
updateA11yCounts,
|
|
57
61
|
updateAnalyticsHealth,
|
|
58
62
|
updateAuditFields,
|
|
@@ -66,4 +70,4 @@ export {
|
|
|
66
70
|
updateSecurityCounts,
|
|
67
71
|
updateSiteField
|
|
68
72
|
};
|
|
69
|
-
//# sourceMappingURL=websites-
|
|
73
|
+
//# sourceMappingURL=websites-D6WYFAES.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
formatFleetWriteSummary,
|
|
3
3
|
writeAuditsToAirtable,
|
|
4
4
|
writeFleetAuditsToAirtable
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-NXNPDCF3.js";
|
|
6
|
+
import "./chunk-7BZUOZPU.js";
|
|
7
7
|
import "./chunk-5L3FPQIJ.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-7NYN2P6I.js";
|
|
9
9
|
export {
|
|
10
10
|
formatFleetWriteSummary,
|
|
11
11
|
writeAuditsToAirtable,
|
|
12
12
|
writeFleetAuditsToAirtable
|
|
13
13
|
};
|
|
14
|
-
//# sourceMappingURL=write-audits-to-airtable-
|
|
14
|
+
//# sourceMappingURL=write-audits-to-airtable-CMKHGJNQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reddoorla/maintenance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"description": "Canonical maintenance configs, audits, and recipes for the reddoor stack.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,6 +25,10 @@
|
|
|
25
25
|
"types": "./dist/forms/index.d.ts",
|
|
26
26
|
"import": "./dist/forms/index.js"
|
|
27
27
|
},
|
|
28
|
+
"./audit": {
|
|
29
|
+
"types": "./dist/prospect/types.d.ts",
|
|
30
|
+
"import": "./dist/prospect/types.js"
|
|
31
|
+
},
|
|
28
32
|
"./client": {
|
|
29
33
|
"types": "./dist/client/index.d.ts",
|
|
30
34
|
"import": "./dist/client/index.js"
|
|
@@ -78,6 +82,7 @@
|
|
|
78
82
|
}
|
|
79
83
|
},
|
|
80
84
|
"devDependencies": {
|
|
85
|
+
"@anthropic-ai/sdk": "^0.120.0",
|
|
81
86
|
"@changesets/cli": "^2.31.0",
|
|
82
87
|
"@google-analytics/data": "^7.0.0",
|
|
83
88
|
"@lhci/cli": "^0.15.1",
|
|
@@ -100,7 +105,8 @@
|
|
|
100
105
|
"tsup": "^8.3.0",
|
|
101
106
|
"tsx": "^4.19.0",
|
|
102
107
|
"typescript": "^6.0.3",
|
|
103
|
-
"vitest": "^4.1.8"
|
|
108
|
+
"vitest": "^4.1.8",
|
|
109
|
+
"zod": "^4.4.3"
|
|
104
110
|
},
|
|
105
111
|
"scripts": {
|
|
106
112
|
"build": "tsup",
|
|
@@ -109,6 +115,7 @@
|
|
|
109
115
|
"test": "vitest run",
|
|
110
116
|
"test:watch": "vitest",
|
|
111
117
|
"test:coverage": "vitest run --coverage",
|
|
118
|
+
"test:time-travel": "REDDOOR_TIME_TRAVEL_DAYS=${REDDOOR_TIME_TRAVEL_DAYS:-90} vitest run",
|
|
112
119
|
"pretest:dist": "pnpm run build",
|
|
113
120
|
"test:dist": "node scripts/smoke-dist.mjs",
|
|
114
121
|
"lint": "eslint . && prettier --check .",
|