@reddoorla/maintenance 0.95.1 → 0.96.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 +37 -2
- package/dist/airtable-SJV4ZSMS.js +9 -0
- package/dist/{announce-CLQYX5I4.js → announce-45HVP4J4.js} +7 -7
- package/dist/{blux-4KNXUP2K.js → blux-RUFMNOUJ.js} +5 -5
- package/dist/{bump-deps-C5G2EFBB.js → bump-deps-EL3TKMIL.js} +6 -6
- package/dist/{chunk-XN37VTDB.js → chunk-37B4LVB3.js} +2 -2
- package/dist/{chunk-BVEDKMNG.js → chunk-3EA43S3R.js} +28 -10
- package/dist/chunk-3EA43S3R.js.map +1 -0
- package/dist/{chunk-XHHMM5HX.js → chunk-43SW3FGW.js} +63 -1
- package/dist/chunk-43SW3FGW.js.map +1 -0
- package/dist/{chunk-WMBLR5VA.js → chunk-44SDGPGQ.js} +3 -3
- package/dist/chunk-4UTJ4G6P.js +52 -0
- package/dist/chunk-4UTJ4G6P.js.map +1 -0
- package/dist/{chunk-R53VL3RI.js → chunk-5CJVUPJU.js} +1 -1
- package/dist/{chunk-R53VL3RI.js.map → chunk-5CJVUPJU.js.map} +1 -1
- package/dist/{chunk-KJRVMMM3.js → chunk-62YWOFVN.js} +36 -5
- package/dist/chunk-62YWOFVN.js.map +1 -0
- package/dist/{chunk-VSGMCCGQ.js → chunk-6INOBNRO.js} +2 -2
- package/dist/{chunk-BYGPUUCT.js → chunk-72FJZ6LO.js} +43 -11
- package/dist/chunk-72FJZ6LO.js.map +1 -0
- package/dist/{chunk-5GUJ36TL.js → chunk-74QRWE6G.js} +2 -2
- package/dist/chunk-A5QKNOXW.js +72 -0
- package/dist/chunk-A5QKNOXW.js.map +1 -0
- package/dist/{chunk-2NQUCS7O.js → chunk-BIYQN7FH.js} +3 -1
- package/dist/{chunk-2NQUCS7O.js.map → chunk-BIYQN7FH.js.map} +1 -1
- package/dist/{chunk-S7RYFUIK.js → chunk-CA6ADGOC.js} +2 -2
- package/dist/chunk-CGQZFQAY.js +38 -0
- package/dist/chunk-CGQZFQAY.js.map +1 -0
- package/dist/{chunk-YLYXW5PH.js → chunk-CXICCLNM.js} +34 -4
- package/dist/chunk-CXICCLNM.js.map +1 -0
- package/dist/{chunk-KZRR4NFG.js → chunk-D3CTOCUR.js} +3 -3
- package/dist/{chunk-CWXTNPNZ.js → chunk-DVJNYPFR.js} +3 -3
- package/dist/chunk-DVJNYPFR.js.map +1 -0
- package/dist/{chunk-AVEQUR44.js → chunk-EASYCD6F.js} +60 -17
- package/dist/chunk-EASYCD6F.js.map +1 -0
- package/dist/{chunk-BCKEP5S6.js → chunk-ECDJDHKT.js} +2 -2
- package/dist/{chunk-BI2VI6EM.js → chunk-EQQ4H6L3.js} +2 -2
- package/dist/{chunk-WVNDEYXL.js → chunk-GEUC5VGM.js} +11 -5
- package/dist/chunk-GEUC5VGM.js.map +1 -0
- package/dist/{chunk-Z2K4JPQ3.js → chunk-H445EH33.js} +2 -2
- package/dist/chunk-IHHAYXKY.js +351 -0
- package/dist/chunk-IHHAYXKY.js.map +1 -0
- package/dist/{chunk-FUWFLAWQ.js → chunk-IMYL67JV.js} +3 -3
- package/dist/{chunk-3Z6X3BHU.js → chunk-KN52PM63.js} +7 -2
- package/dist/{chunk-3Z6X3BHU.js.map → chunk-KN52PM63.js.map} +1 -1
- package/dist/{chunk-WJMPCVOR.js → chunk-LAJ3FF54.js} +12 -4
- package/dist/chunk-LAJ3FF54.js.map +1 -0
- package/dist/{chunk-5UINJNAJ.js → chunk-MZZDMBDT.js} +16 -3
- package/dist/chunk-MZZDMBDT.js.map +1 -0
- package/dist/{chunk-DFKBTBO3.js → chunk-NVLREB5R.js} +35 -6
- package/dist/chunk-NVLREB5R.js.map +1 -0
- package/dist/{chunk-R5IMFAFR.js → chunk-OTEVKRAH.js} +3 -3
- package/dist/{chunk-2ZAZ7ETT.js → chunk-P4A6D6HO.js} +4 -4
- package/dist/{chunk-XPJQXSC4.js → chunk-P7323YVW.js} +27 -5
- package/dist/chunk-P7323YVW.js.map +1 -0
- package/dist/{chunk-4763KQ6O.js → chunk-PXRN2MER.js} +2 -2
- package/dist/{chunk-TR3HFH6J.js → chunk-QFSL2L2B.js} +67 -10
- package/dist/chunk-QFSL2L2B.js.map +1 -0
- package/dist/{chunk-2LYOAB2E.js → chunk-RRE74VWI.js} +2 -2
- package/dist/{chunk-LM2NHRCJ.js → chunk-SHGIDTYF.js} +4 -4
- package/dist/chunk-SHGIDTYF.js.map +1 -0
- package/dist/{chunk-ZQV7UQNE.js → chunk-SQ4FSNYL.js} +2 -2
- package/dist/{chunk-C3IQQKXL.js → chunk-T76MA2FH.js} +110 -1
- package/dist/{chunk-C3IQQKXL.js.map → chunk-T76MA2FH.js.map} +1 -1
- package/dist/{chunk-6R56OKJZ.js → chunk-UIITN37J.js} +2 -2
- package/dist/{chunk-CJ2RMTT7.js → chunk-VEIIUCYL.js} +2 -2
- package/dist/{chunk-SVAAONYB.js → chunk-WQLNUEZL.js} +12 -2
- package/dist/{chunk-SVAAONYB.js.map → chunk-WQLNUEZL.js.map} +1 -1
- package/dist/{chunk-WSJ7RO54.js → chunk-XED2DNAI.js} +23 -5
- package/dist/chunk-XED2DNAI.js.map +1 -0
- package/dist/{chunk-FSGICFXB.js → chunk-XG2A6GIG.js} +17 -5
- package/dist/chunk-XG2A6GIG.js.map +1 -0
- package/dist/{chunk-TO7DJYLZ.js → chunk-XY7YV2YQ.js} +178 -39
- package/dist/chunk-XY7YV2YQ.js.map +1 -0
- package/dist/{chunk-HTABUCF4.js → chunk-Y5BVR4HW.js} +3 -3
- package/dist/{chunk-ZCL7C5LH.js → chunk-Y6FCXRIC.js} +1661 -387
- package/dist/chunk-Y6FCXRIC.js.map +1 -0
- package/dist/{chunk-2SLED3NB.js → chunk-YDZ7XGPZ.js} +1 -1
- package/dist/{chunk-2SLED3NB.js.map → chunk-YDZ7XGPZ.js.map} +1 -1
- package/dist/{chunk-QF6IQQFP.js → chunk-Z7FDJ35L.js} +18 -12
- package/dist/chunk-Z7FDJ35L.js.map +1 -0
- package/dist/{chunk-5EEMTJMT.js → chunk-ZH5LOQET.js} +4 -4
- package/dist/cli/bin.js +49 -31
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +18 -18
- package/dist/client-L7NAUG6J.js +11 -0
- package/dist/configs/playwright-a11y.d.ts +11 -1
- package/dist/configs/playwright-a11y.js +3 -1
- package/dist/{convert-to-pnpm-YTFREUJK.js → convert-to-pnpm-4DON7IFS.js} +6 -6
- package/dist/{db-XKZYDCKM.js → db-5K4CDEGJ.js} +45 -20
- package/dist/db-5K4CDEGJ.js.map +1 -0
- package/dist/deadletter-G4M3HSVM.js +17 -0
- package/dist/{digest-7UBGUBRK.js → digest-5AJGWS33.js} +45 -22
- package/dist/digest-5AJGWS33.js.map +1 -0
- package/dist/{digest-collectors-DJFN5ZDK.js → digest-collectors-MC5NWEUA.js} +12 -10
- package/dist/{digest-state-3KHZF7GD.js → digest-state-ZDPKR7MW.js} +18 -2
- package/dist/digest-state-ZDPKR7MW.js.map +1 -0
- package/dist/{ensure-site-OAAE5YE2.js → ensure-site-XESZHZEB.js} +39 -11
- package/dist/ensure-site-XESZHZEB.js.map +1 -0
- package/dist/{fleet-state-UEVZ3X3J.js → fleet-state-GJWGKTLD.js} +6 -4
- package/dist/{forms-notify-target-UC6PF3AE.js → forms-notify-target-4NPLX2UG.js} +5 -5
- package/dist/{freeze-A6MUCZU4.js → freeze-GUQ43EAU.js} +2 -2
- package/dist/{github-signals-TX5FPYP6.js → github-signals-DMU74SAX.js} +10 -10
- package/dist/{header-image-PSPT7CUM.js → header-image-BRTOLHJF.js} +6 -5
- package/dist/header-image-BRTOLHJF.js.map +1 -0
- package/dist/{health-endpoint-KVCJYWET.js → health-endpoint-UCLMSSCN.js} +8 -7
- package/dist/{health-endpoint-KVCJYWET.js.map → health-endpoint-UCLMSSCN.js.map} +1 -1
- package/dist/{health-mirror-XJAKA3EY.js → health-mirror-ONRT4DQ5.js} +7 -7
- package/dist/{import-airtable-TAKSN4NV.js → import-airtable-IIK2QUUF.js} +3 -3
- package/dist/index.d.ts +135 -4
- package/dist/index.js +68 -34
- package/dist/index.js.map +1 -1
- package/dist/{init-FFE4FCO2.js → init-3LMZTCVD.js} +19 -18
- package/dist/{init-FFE4FCO2.js.map → init-3LMZTCVD.js.map} +1 -1
- package/dist/{launch-UD36AHUN.js → launch-XTDMC6LD.js} +209 -61
- package/dist/launch-XTDMC6LD.js.map +1 -0
- package/dist/{lighthouse-VHI77PFB.js → lighthouse-52WSPZ5D.js} +2 -2
- package/dist/{lighthouse-airtable-YMH4UA7R.js → lighthouse-airtable-3NOFB42B.js} +3 -3
- package/dist/{match-harness-QRG6XZAR.js → match-harness-OW45CB5H.js} +14 -7
- package/dist/match-harness-OW45CB5H.js.map +1 -0
- package/dist/migrate-NE3DUMTM.js +7 -0
- package/dist/{notify-IISTHNBR.js → notify-K3WVH3DM.js} +3 -3
- package/dist/{onboard-TM2KESGF.js → onboard-CZYBWVWH.js} +6 -6
- package/dist/{orchestrate-HYVQPRCE.js → orchestrate-TGDFGY52.js} +8 -8
- package/dist/{parity-CAJ477PS.js → parity-AEKYSLN6.js} +5 -5
- package/dist/{pipeline-YROAY6DT.js → pipeline-UUPXOS2J.js} +3 -3
- package/dist/{preflight-RYIP54NY.js → preflight-POZZI3GN.js} +9 -9
- package/dist/{prismic-ci-6GKKZGB5.js → prismic-ci-AHY5ULJR.js} +38 -8
- package/dist/prismic-ci-AHY5ULJR.js.map +1 -0
- package/dist/{prismic-models-P6FWWVRS.js → prismic-models-URYGODNY.js} +9 -9
- package/dist/prospect/types.d.ts +72 -0
- package/dist/prospect/types.js +1 -1
- package/dist/{prospect-audit-PRHU53HS.js → prospect-audit-AJEE3Z4L.js} +16 -7
- package/dist/prospect-audit-AJEE3Z4L.js.map +1 -0
- package/dist/{prospect-audits-R3LWF6U7.js → prospect-audits-IZVQY3OQ.js} +4 -2
- package/dist/protection-audit-3J3UEOVT.js +413 -0
- package/dist/protection-audit-3J3UEOVT.js.map +1 -0
- package/dist/recipes/sync-configs.js +3 -3
- package/dist/{render-YGNGTX3W.js → render-MHUUHPLN.js} +36 -9
- package/dist/render-MHUUHPLN.js.map +1 -0
- package/dist/{render-from-row-IFSBHWDH.js → render-from-row-65DC6ZP3.js} +4 -4
- package/dist/{renovate-dispatch-U5Q52SKT.js → renovate-dispatch-ONJMBUHJ.js} +3 -3
- package/dist/{replay-PCSQOGCZ.js → replay-4FVFOMHH.js} +10 -23
- package/dist/replay-4FVFOMHH.js.map +1 -0
- package/dist/{report-LQS4ECTM.js → report-RC5LGPU3.js} +22 -20
- package/dist/report-RC5LGPU3.js.map +1 -0
- package/dist/{report-mirror-HDTOJE64.js → report-mirror-KKZZ6RMZ.js} +13 -9
- package/dist/{report-mirror-HDTOJE64.js.map → report-mirror-KKZZ6RMZ.js.map} +1 -1
- package/dist/{schema-A4WCPIF4.js → schema-KWUQEZ5O.js} +1 -1
- package/dist/schema-KWUQEZ5O.js.map +1 -0
- package/dist/{self-updating-MWXIZLL7.js → self-updating-RKKIYNV4.js} +8 -7
- package/dist/{self-updating-MWXIZLL7.js.map → self-updating-RKKIYNV4.js.map} +1 -1
- package/dist/{selftest-VXTHRPRN.js → selftest-AFLR7YV7.js} +10 -10
- package/dist/site-lookup-DTOLJ4EA.js +27 -0
- package/dist/site-lookup-DTOLJ4EA.js.map +1 -0
- package/dist/{site-mirror-WON4FTJ2.js → site-mirror-H2FYMN55.js} +23 -9
- package/dist/site-mirror-H2FYMN55.js.map +1 -0
- package/dist/{smoke-suite-7DGITCTZ.js → smoke-suite-BWHR3XX5.js} +8 -7
- package/dist/{smoke-suite-7DGITCTZ.js.map → smoke-suite-BWHR3XX5.js.map} +1 -1
- package/dist/{submissions-OVZPVBYG.js → submissions-II5J35QM.js} +4 -4
- package/dist/{submissions-3I3GAQAX.js → submissions-JDZP35JM.js} +49 -9
- package/dist/submissions-JDZP35JM.js.map +1 -0
- package/dist/{svelte-codemods-WSV2FGNG.js → svelte-codemods-QWGIRNN6.js} +6 -6
- package/dist/{sync-K3PKHVLH.js → sync-NKPDCMYW.js} +5 -5
- package/dist/{sync-configs-RRIHNLIJ.js → sync-configs-HGLQV55H.js} +6 -6
- package/dist/{upgrade-VTD6V4HS.js → upgrade-WZ44IARG.js} +6 -6
- package/dist/util/git.d.ts +48 -9
- package/dist/util/git.js +1 -1
- package/dist/{webflow-IRKOIT7S.js → webflow-624FEBFD.js} +4 -4
- package/dist/{websites-TB4TCAWM.js → websites-6DHIHJ2D.js} +4 -2
- package/dist/{write-audits-to-airtable-53EVXKMU.js → write-audits-to-airtable-BIK6LNVC.js} +5 -5
- package/dist/write-audits-to-airtable-BIK6LNVC.js.map +1 -0
- package/package.json +3 -2
- package/dist/airtable-JGCPS7JH.js +0 -9
- package/dist/chunk-5UINJNAJ.js.map +0 -1
- package/dist/chunk-AVEQUR44.js.map +0 -1
- package/dist/chunk-BVEDKMNG.js.map +0 -1
- package/dist/chunk-BYGPUUCT.js.map +0 -1
- package/dist/chunk-CWXTNPNZ.js.map +0 -1
- package/dist/chunk-DFKBTBO3.js.map +0 -1
- package/dist/chunk-FSGICFXB.js.map +0 -1
- package/dist/chunk-GASBX52O.js +0 -12
- package/dist/chunk-GASBX52O.js.map +0 -1
- package/dist/chunk-KJRVMMM3.js.map +0 -1
- package/dist/chunk-LM2NHRCJ.js.map +0 -1
- package/dist/chunk-QF6IQQFP.js.map +0 -1
- package/dist/chunk-TO7DJYLZ.js.map +0 -1
- package/dist/chunk-TR3HFH6J.js.map +0 -1
- package/dist/chunk-WJMPCVOR.js.map +0 -1
- package/dist/chunk-WSJ7RO54.js.map +0 -1
- package/dist/chunk-WVNDEYXL.js.map +0 -1
- package/dist/chunk-XHHMM5HX.js.map +0 -1
- package/dist/chunk-XPJQXSC4.js.map +0 -1
- package/dist/chunk-YLYXW5PH.js.map +0 -1
- package/dist/chunk-ZCL7C5LH.js.map +0 -1
- package/dist/client-G2WGWPCA.js +0 -11
- package/dist/db-XKZYDCKM.js.map +0 -1
- package/dist/digest-7UBGUBRK.js.map +0 -1
- package/dist/digest-state-3KHZF7GD.js.map +0 -1
- package/dist/ensure-site-OAAE5YE2.js.map +0 -1
- package/dist/header-image-PSPT7CUM.js.map +0 -1
- package/dist/launch-UD36AHUN.js.map +0 -1
- package/dist/match-harness-QRG6XZAR.js.map +0 -1
- package/dist/migrate-Y7R4CESL.js +0 -7
- package/dist/prismic-ci-6GKKZGB5.js.map +0 -1
- package/dist/prospect-audit-PRHU53HS.js.map +0 -1
- package/dist/protection-audit-SJO53MEQ.js +0 -168
- package/dist/protection-audit-SJO53MEQ.js.map +0 -1
- package/dist/render-YGNGTX3W.js.map +0 -1
- package/dist/replay-PCSQOGCZ.js.map +0 -1
- package/dist/report-LQS4ECTM.js.map +0 -1
- package/dist/schema-A4WCPIF4.js.map +0 -1
- package/dist/site-mirror-WON4FTJ2.js.map +0 -1
- package/dist/submissions-3I3GAQAX.js.map +0 -1
- /package/dist/{airtable-JGCPS7JH.js.map → airtable-SJV4ZSMS.js.map} +0 -0
- /package/dist/{announce-CLQYX5I4.js.map → announce-45HVP4J4.js.map} +0 -0
- /package/dist/{blux-4KNXUP2K.js.map → blux-RUFMNOUJ.js.map} +0 -0
- /package/dist/{bump-deps-C5G2EFBB.js.map → bump-deps-EL3TKMIL.js.map} +0 -0
- /package/dist/{chunk-XN37VTDB.js.map → chunk-37B4LVB3.js.map} +0 -0
- /package/dist/{chunk-WMBLR5VA.js.map → chunk-44SDGPGQ.js.map} +0 -0
- /package/dist/{chunk-VSGMCCGQ.js.map → chunk-6INOBNRO.js.map} +0 -0
- /package/dist/{chunk-5GUJ36TL.js.map → chunk-74QRWE6G.js.map} +0 -0
- /package/dist/{chunk-S7RYFUIK.js.map → chunk-CA6ADGOC.js.map} +0 -0
- /package/dist/{chunk-KZRR4NFG.js.map → chunk-D3CTOCUR.js.map} +0 -0
- /package/dist/{chunk-BCKEP5S6.js.map → chunk-ECDJDHKT.js.map} +0 -0
- /package/dist/{chunk-BI2VI6EM.js.map → chunk-EQQ4H6L3.js.map} +0 -0
- /package/dist/{chunk-Z2K4JPQ3.js.map → chunk-H445EH33.js.map} +0 -0
- /package/dist/{chunk-FUWFLAWQ.js.map → chunk-IMYL67JV.js.map} +0 -0
- /package/dist/{chunk-R5IMFAFR.js.map → chunk-OTEVKRAH.js.map} +0 -0
- /package/dist/{chunk-2ZAZ7ETT.js.map → chunk-P4A6D6HO.js.map} +0 -0
- /package/dist/{chunk-4763KQ6O.js.map → chunk-PXRN2MER.js.map} +0 -0
- /package/dist/{chunk-2LYOAB2E.js.map → chunk-RRE74VWI.js.map} +0 -0
- /package/dist/{chunk-ZQV7UQNE.js.map → chunk-SQ4FSNYL.js.map} +0 -0
- /package/dist/{chunk-6R56OKJZ.js.map → chunk-UIITN37J.js.map} +0 -0
- /package/dist/{chunk-CJ2RMTT7.js.map → chunk-VEIIUCYL.js.map} +0 -0
- /package/dist/{chunk-HTABUCF4.js.map → chunk-Y5BVR4HW.js.map} +0 -0
- /package/dist/{chunk-5EEMTJMT.js.map → chunk-ZH5LOQET.js.map} +0 -0
- /package/dist/{client-G2WGWPCA.js.map → client-L7NAUG6J.js.map} +0 -0
- /package/dist/{convert-to-pnpm-YTFREUJK.js.map → convert-to-pnpm-4DON7IFS.js.map} +0 -0
- /package/dist/{digest-collectors-DJFN5ZDK.js.map → deadletter-G4M3HSVM.js.map} +0 -0
- /package/dist/{fleet-state-UEVZ3X3J.js.map → digest-collectors-MC5NWEUA.js.map} +0 -0
- /package/dist/{freeze-A6MUCZU4.js.map → fleet-state-GJWGKTLD.js.map} +0 -0
- /package/dist/{forms-notify-target-UC6PF3AE.js.map → forms-notify-target-4NPLX2UG.js.map} +0 -0
- /package/dist/{import-airtable-TAKSN4NV.js.map → freeze-GUQ43EAU.js.map} +0 -0
- /package/dist/{github-signals-TX5FPYP6.js.map → github-signals-DMU74SAX.js.map} +0 -0
- /package/dist/{health-mirror-XJAKA3EY.js.map → health-mirror-ONRT4DQ5.js.map} +0 -0
- /package/dist/{lighthouse-VHI77PFB.js.map → import-airtable-IIK2QUUF.js.map} +0 -0
- /package/dist/{lighthouse-airtable-YMH4UA7R.js.map → lighthouse-52WSPZ5D.js.map} +0 -0
- /package/dist/{migrate-Y7R4CESL.js.map → lighthouse-airtable-3NOFB42B.js.map} +0 -0
- /package/dist/{notify-IISTHNBR.js.map → migrate-NE3DUMTM.js.map} +0 -0
- /package/dist/{orchestrate-HYVQPRCE.js.map → notify-K3WVH3DM.js.map} +0 -0
- /package/dist/{onboard-TM2KESGF.js.map → onboard-CZYBWVWH.js.map} +0 -0
- /package/dist/{parity-CAJ477PS.js.map → orchestrate-TGDFGY52.js.map} +0 -0
- /package/dist/{pipeline-YROAY6DT.js.map → parity-AEKYSLN6.js.map} +0 -0
- /package/dist/{prospect-audits-R3LWF6U7.js.map → pipeline-UUPXOS2J.js.map} +0 -0
- /package/dist/{preflight-RYIP54NY.js.map → preflight-POZZI3GN.js.map} +0 -0
- /package/dist/{prismic-models-P6FWWVRS.js.map → prismic-models-URYGODNY.js.map} +0 -0
- /package/dist/{render-from-row-IFSBHWDH.js.map → prospect-audits-IZVQY3OQ.js.map} +0 -0
- /package/dist/{websites-TB4TCAWM.js.map → render-from-row-65DC6ZP3.js.map} +0 -0
- /package/dist/{renovate-dispatch-U5Q52SKT.js.map → renovate-dispatch-ONJMBUHJ.js.map} +0 -0
- /package/dist/{selftest-VXTHRPRN.js.map → selftest-AFLR7YV7.js.map} +0 -0
- /package/dist/{submissions-OVZPVBYG.js.map → submissions-II5J35QM.js.map} +0 -0
- /package/dist/{svelte-codemods-WSV2FGNG.js.map → svelte-codemods-QWGIRNN6.js.map} +0 -0
- /package/dist/{sync-K3PKHVLH.js.map → sync-NKPDCMYW.js.map} +0 -0
- /package/dist/{sync-configs-RRIHNLIJ.js.map → sync-configs-HGLQV55H.js.map} +0 -0
- /package/dist/{upgrade-VTD6V4HS.js.map → upgrade-WZ44IARG.js.map} +0 -0
- /package/dist/{webflow-IRKOIT7S.js.map → webflow-624FEBFD.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-53EVXKMU.js.map → websites-6DHIHJ2D.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/reports/airtable/ensure-site.ts","../src/cli/commands/ensure-site.ts"],"sourcesContent":["import type { FieldSet, Records } from \"airtable\";\nimport type { AirtableBase } from \"./client.js\";\nimport { WEBSITES_TABLE, mapRow, siteSlug, type WebsiteRow } from \"./websites.js\";\nimport { toAirtableStatus } from \"./site-status.js\";\n\nexport type EnsureSiteInput = {\n /** Canonical slug — matches by siteSlug(Name); the Name on create when no displayName given. */\n slug: string;\n /** Human display name written to Name on create, and — unlike every other\n * input — UPDATED on an existing row when it differs (#664). Name is\n * consumed VERBATIM in client-facing copy (forms auto-reply intro, report\n * subjects), so a bare machine slug there reads as \"Thanks for reaching out\n * to acme-co.\" — and the row that has it is exactly the one created before\n * the name was settled, which only this command re-run can fix. Must\n * slugify to the same slug or the row wouldn't be found on re-run. */\n displayName?: string;\n url?: string;\n pointOfContact?: string;\n /** owner/repo. Default on create: `reddoorla/<slug>`. */\n gitRepo?: string;\n};\n\n/** #539 Phase 5. Structurally typed rather than importing the db layer's\n * `SiteMirror`, so this module stays the leaf it has always been — a real\n * `SiteMirror` satisfies it. Two ops because `ensureSite` has two write paths,\n * and the create one is the reason this exists: every other site mirror is an\n * UPDATE, which does nothing for a row that does not exist yet. */\nexport type EnsureSiteMirror = {\n created: (rec: { id: string; fields: Record<string, unknown> }) => Promise<void>;\n site: (siteId: string, fields: Record<string, unknown>) => Promise<void>;\n /** #645. Does Turso hold a row for this site id? Optional so every pre-#645\n * caller (and every hand-built test mirror) is byte-for-byte unchanged —\n * absent means the heal below never runs. */\n hasRow?: (siteId: string) => Promise<boolean>;\n};\n\nexport type EnsureSiteResult = {\n status: \"created\" | \"exists\";\n siteId: string;\n /** Airtable column names written on the exists path (create path writes all). */\n updatedFields: string[];\n /** Inputs that DIFFERED from an existing non-blank cell and were left\n * untouched (fill-blanks-only) — surfaced so a resumed bootstrap with a\n * corrected value doesn't silently discard it. */\n skippedMismatches: string[];\n /** #645. True when the site existed in Airtable but had NO Turso row and this\n * run inserted one. Surfaced rather than logged-only because it is the\n * difference between \"nothing to do\" and \"this site's leads were being\n * dropped until just now\". */\n healedDbRow: boolean;\n};\n\n/** Column-name map (load-bearing magic strings — see websites.ts's mapRow header). */\nconst COLS = {\n url: \"url\",\n pointOfContact: \"point of contact\",\n gitRepo: \"Git repo\",\n} as const;\n\n/**\n * Find-or-create the Websites row for a slug so a new site exists in the fleet\n * inventory (audits, form-ingest slug resolution, reports) from day one.\n *\n * Fill-blanks-only on the exists path: this command runs from a bootstrap skill\n * that may be re-run to resume — it must never clobber operator-edited cells.\n * The one exception is `displayName` (#664): `--name` targets Name and nothing\n * else, so a differing value IS the operator's edit, and the create message\n * sends them back here to make it. Frequencies are deliberately NOT set\n * (launch flips the lifecycle); Status is only written on create (\"building\" —\n * Airtable's \"in development\" until the stage-2 vocabulary switch flips).\n */\nexport async function ensureSite(\n base: AirtableBase,\n input: EnsureSiteInput,\n mirror?: EnsureSiteMirror,\n): Promise<EnsureSiteResult> {\n const slug = siteSlug(input.slug);\n if (!slug) throw new Error(`ensure-site: '${input.slug}' does not slugify to a usable slug`);\n if (input.displayName && siteSlug(input.displayName) !== slug)\n throw new Error(\n `ensure-site: display name '${input.displayName}' slugifies to '${siteSlug(input.displayName)}', not '${slug}' — the row would not be found on re-run`,\n );\n\n // Paged inline rather than through `listWebsites` so the RAW stored record\n // survives alongside the mapped row: the #645 heal below re-inserts what\n // Airtable STORED (the same contract as the create path's mirror), and a\n // mapped `WebsiteRow` cannot be turned back into a FieldSet. Same single\n // select `listWebsites` issues — no extra Airtable read.\n const raw: Array<{ id: string; fields: Record<string, unknown> }> = [];\n await base(WEBSITES_TABLE)\n .select({ pageSize: 100 })\n .eachPage((records, fetchNextPage) => {\n for (const rec of records) raw.push({ id: rec.id, fields: rec.fields });\n fetchNextPage();\n });\n let existing: WebsiteRow | undefined;\n let existingRaw: { id: string; fields: Record<string, unknown> } | undefined;\n for (const rec of raw) {\n const row = mapRow(rec);\n if (siteSlug(row.name) === slug) {\n existing = row;\n existingRaw = rec;\n break;\n }\n }\n\n if (!existing || !existingRaw) {\n const fields: FieldSet = {\n Name: input.displayName ?? slug,\n Status: toAirtableStatus(\"building\"),\n [COLS.gitRepo]: input.gitRepo ?? `reddoorla/${slug}`,\n };\n if (input.url) fields[COLS.url] = input.url;\n if (input.pointOfContact) fields[COLS.pointOfContact] = input.pointOfContact;\n const created = (await base(WEBSITES_TABLE).create([{ fields }])) as Records<FieldSet>;\n const rec = created[0]!;\n // The mirror gets what Airtable STORED, never the `fields` we sent: parity\n // diffs Turso against the stored record, so mapping our own payload would\n // diverge the moment Airtable normalises a value.\n await mirror?.created({ id: rec.id, fields: rec.fields as Record<string, unknown> });\n return {\n status: \"created\",\n siteId: rec.id,\n updatedFields: [],\n skippedMismatches: [],\n // The create path just inserted the row; there is nothing to heal, and a\n // `hasRow` probe here would be a round-trip whose answer is already known.\n healedDbRow: false,\n };\n }\n\n // #645. THE gap: before this, `exists` meant \"Airtable has it\" and said nothing\n // about Turso. Post-flip (#643) the form-ingest lookup reads Turso ONLY, so a\n // site with an Airtable row and no Turso row has every lead answered\n // `unknown-site` — silently, permanently, and with no alarm once Phase 6 (#646)\n // deletes `mirror_missed`. `ensure-site` is the command an operator already\n // re-runs to finish a half-created site, so the heal belongs here.\n //\n // FIRST, before the fill-blanks update below: `mirror.site` is an UPDATE, and\n // under the freeze a no-match THROWS (`SITE_MIRROR … no such row in Turso`).\n // Healing second would abort ensure-site on exactly the site it exists to\n // repair. `mirrorSiteInsert` is an upsert, so a lost race just re-writes.\n let healedDbRow = false;\n if (mirror?.hasRow && !(await mirror.hasRow(existingRaw.id))) {\n await mirror.created(existingRaw);\n healedDbRow = true;\n }\n\n const updates: FieldSet = {};\n const skippedMismatches: string[] = [];\n const blank = (v: unknown) => v === null || v === undefined || v === \"\";\n const consider = (column: string, provided: string | undefined, current: unknown) => {\n if (!provided) return;\n if (blank(current)) updates[column] = provided;\n else if (current !== provided) skippedMismatches.push(column);\n };\n consider(COLS.url, input.url, existing.url || null);\n consider(COLS.pointOfContact, input.pointOfContact, existing.pointOfContact);\n consider(COLS.gitRepo, input.gitRepo, existing.gitRepo);\n // #664: Name is NOT fill-blanks. It is never blank (the slug match found it),\n // and `--name` is the only way to retitle a row created before the display\n // name was settled — the slugify guard above already proved the new value\n // resolves to the same row. Goes through the same update + mirror below, so\n // Turso gets it too.\n if (input.displayName && existing.name !== input.displayName) {\n updates[\"Name\"] = input.displayName;\n }\n\n const updatedFields = Object.keys(updates);\n if (updatedFields.length > 0) {\n await base(WEBSITES_TABLE).update([{ id: existing.id, fields: updates }]);\n // The fill-blanks path writes real cells too — a resumed bootstrap that only\n // filled a blank `url` would otherwise leave Turso stale until the sync.\n await mirror?.site(existing.id, updates);\n }\n return { status: \"exists\", siteId: existing.id, updatedFields, skippedMismatches, healedDbRow };\n}\n","import { openBase, readAirtableConfig } from \"../../reports/airtable/client.js\";\nimport { ensureSite } from \"../../reports/airtable/ensure-site.js\";\n\nexport type EnsureSiteCommandOptions = {\n name?: string;\n url?: string;\n contact?: string;\n gitRepo?: string;\n cwd?: string;\n};\n\n/**\n * `ensure-site <slug>` — create/verify the fleet-inventory row for a new site.\n * Day-one step of the /new-site bootstrap skill. Fill-blanks-only; safe to re-run.\n */\nexport async function runEnsureSiteCommand(\n slug: string | undefined,\n opts: EnsureSiteCommandOptions,\n): Promise<{ output: string; code: number }> {\n if (!slug) return { output: \"Provide a <slug> (e.g. `ensure-site roalson`).\", code: 2 };\n try {\n const base = openBase(readAirtableConfig());\n // #539 Phase 5: bootstrapping a site CREATES the Websites row, so this is\n // the one site path that needs an INSERT mirror — every other one updates.\n const { makeSiteMirror } = await import(\"../../db/site-mirror.js\");\n const result = await ensureSite(\n base,\n {\n slug,\n ...(opts.name ? { displayName: opts.name } : {}),\n ...(opts.url ? { url: opts.url } : {}),\n ...(opts.contact ? { pointOfContact: opts.contact } : {}),\n ...(opts.gitRepo ? { gitRepo: opts.gitRepo } : {}),\n },\n await makeSiteMirror(),\n );\n // #664: a Name change on the exists path is a rename the operator asked\n // for with --name, not a blank the bootstrap filled — say so.\n const renamed = result.updatedFields.includes(\"Name\") ? ` — Name set to \"${opts.name}\"` : \"\";\n const blanks = result.updatedFields.filter((f) => f !== \"Name\");\n const filled = blanks.length > 0 ? ` — filled blank field(s): ${blanks.join(\", \")}` : \"\";\n const skipped =\n result.skippedMismatches.length > 0\n ? ` — differs from existing, left untouched (edit in Airtable): ${result.skippedMismatches.join(\", \")}`\n : \"\";\n // #645. Loud, and its own clause: a healed row means this site's leads were\n // being answered `unknown-site` and dropped until this run.\n const healed = result.healedDbRow\n ? ` — HEALED: the Turso row was MISSING and has been inserted; leads for this slug were being dropped (run \\`db replay-deadletters\\`)`\n : \"\";\n const nameNote =\n result.status === \"created\" && !opts.name\n ? ` — Name set to \"${slug}\"; retitle in Airtable before forms/announce go live (or re-run with --name)`\n : \"\";\n return {\n output: `[${slug}] ${result.status} (${result.siteId})${healed}${renamed}${filled}${skipped}${nameNote}`,\n code: 0,\n };\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":[]}
|
|
@@ -14,12 +14,13 @@ import {
|
|
|
14
14
|
mirrorSiteField,
|
|
15
15
|
mirrorSiteFields,
|
|
16
16
|
mirrorSiteInsert,
|
|
17
|
+
siteRowExists,
|
|
17
18
|
storeRenderedHtml
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-GEUC5VGM.js";
|
|
20
|
+
import "./chunk-UIITN37J.js";
|
|
20
21
|
import "./chunk-F3JWOPTG.js";
|
|
21
22
|
import "./chunk-VAD43MOR.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-KN52PM63.js";
|
|
23
24
|
export {
|
|
24
25
|
REPORT_LIST_COLUMNS,
|
|
25
26
|
getReportById,
|
|
@@ -36,6 +37,7 @@ export {
|
|
|
36
37
|
mirrorSiteField,
|
|
37
38
|
mirrorSiteFields,
|
|
38
39
|
mirrorSiteInsert,
|
|
40
|
+
siteRowExists,
|
|
39
41
|
storeRenderedHtml
|
|
40
42
|
};
|
|
41
|
-
//# sourceMappingURL=fleet-state-
|
|
43
|
+
//# sourceMappingURL=fleet-state-GJWGKTLD.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
describeNotifyTarget
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-PXRN2MER.js";
|
|
4
|
+
import "./chunk-Z7FDJ35L.js";
|
|
5
5
|
import "./chunk-5ML7FMBD.js";
|
|
6
6
|
import "./chunk-NO74DXDP.js";
|
|
7
7
|
import "./chunk-I7NHLVVI.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
siteSlug,
|
|
17
17
|
toAirtableStatus,
|
|
18
18
|
updateSiteField
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-KN52PM63.js";
|
|
20
20
|
import "./chunk-2OP4JKIQ.js";
|
|
21
21
|
import "./chunk-6VAL7XJT.js";
|
|
22
22
|
|
|
@@ -144,7 +144,7 @@ async function runFormsNotifyTargetCommand(site, opts) {
|
|
|
144
144
|
return { output: `--set must be 'on' or 'off' (got '${opts.set}')`, code: 2 };
|
|
145
145
|
}
|
|
146
146
|
try {
|
|
147
|
-
const { makeSiteMirror } = await import("./site-mirror-
|
|
147
|
+
const { makeSiteMirror } = await import("./site-mirror-H2FYMN55.js");
|
|
148
148
|
const result = await formsNotifyTarget({
|
|
149
149
|
siteMirror: await makeSiteMirror(),
|
|
150
150
|
site: site.trim(),
|
|
@@ -164,4 +164,4 @@ export {
|
|
|
164
164
|
formatNotifyTarget,
|
|
165
165
|
runFormsNotifyTargetCommand
|
|
166
166
|
};
|
|
167
|
-
//# sourceMappingURL=forms-notify-target-
|
|
167
|
+
//# sourceMappingURL=forms-notify-target-4NPLX2UG.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TURSO_IS_AUTHORITATIVE,
|
|
3
3
|
mirrorWrite
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WQLNUEZL.js";
|
|
5
5
|
export {
|
|
6
6
|
TURSO_IS_AUTHORITATIVE,
|
|
7
7
|
mirrorWrite
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=freeze-
|
|
9
|
+
//# sourceMappingURL=freeze-GUQ43EAU.js.map
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
} from "./chunk-PZQ3WED2.js";
|
|
4
4
|
import {
|
|
5
5
|
formatFleetWriteSummary
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-ZH5LOQET.js";
|
|
7
|
+
import "./chunk-37B4LVB3.js";
|
|
8
|
+
import "./chunk-WQLNUEZL.js";
|
|
9
9
|
import {
|
|
10
10
|
detectSignalEvents,
|
|
11
11
|
fleetSweptEvent
|
|
@@ -18,15 +18,15 @@ import {
|
|
|
18
18
|
listWebsites,
|
|
19
19
|
siteSlug,
|
|
20
20
|
updateGitHubSignals
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-KN52PM63.js";
|
|
22
22
|
import {
|
|
23
23
|
makeGitHub
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-43SW3FGW.js";
|
|
25
25
|
import {
|
|
26
26
|
recordFleetEventsBestEffort
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
27
|
+
} from "./chunk-EQQ4H6L3.js";
|
|
28
|
+
import "./chunk-6INOBNRO.js";
|
|
29
|
+
import "./chunk-T76MA2FH.js";
|
|
30
30
|
import "./chunk-LBYOLBW7.js";
|
|
31
31
|
import "./chunk-6VAL7XJT.js";
|
|
32
32
|
|
|
@@ -91,7 +91,7 @@ async function runGitHubSignalsCommand(opts, deps = {}) {
|
|
|
91
91
|
);
|
|
92
92
|
const sweptAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
93
93
|
const makeMirror = deps.makeMirror ?? (async () => {
|
|
94
|
-
const { makeHealthMirrorBestEffort } = await import("./health-mirror-
|
|
94
|
+
const { makeHealthMirrorBestEffort } = await import("./health-mirror-ONRT4DQ5.js");
|
|
95
95
|
return makeHealthMirrorBestEffort();
|
|
96
96
|
});
|
|
97
97
|
const mirror = await makeMirror();
|
|
@@ -156,4 +156,4 @@ export {
|
|
|
156
156
|
githubSignalsExitCode,
|
|
157
157
|
runGitHubSignalsCommand
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=github-signals-
|
|
159
|
+
//# sourceMappingURL=github-signals-DMU74SAX.js.map
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
} from "./chunk-HN6I2XWI.js";
|
|
8
8
|
import {
|
|
9
9
|
generateHeaderImage
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-MZZDMBDT.js";
|
|
11
11
|
import {
|
|
12
12
|
ACTIVE_STATUSES,
|
|
13
13
|
listWebsites,
|
|
14
14
|
siteSlug
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-KN52PM63.js";
|
|
16
16
|
import "./chunk-6VAL7XJT.js";
|
|
17
17
|
|
|
18
18
|
// src/cli/commands/header-image.ts
|
|
@@ -54,7 +54,8 @@ async function generateForTargets(targets, opts, generate = generateHeaderImage)
|
|
|
54
54
|
slug: siteSlug(row.name),
|
|
55
55
|
// `exactOptionalPropertyTypes` rejects an explicit `settleMs: undefined`
|
|
56
56
|
// against `settleMs?: number`, so omit the key entirely when unset.
|
|
57
|
-
...settleMs === void 0 ? {} : { settleMs }
|
|
57
|
+
...settleMs === void 0 ? {} : { settleMs },
|
|
58
|
+
...opts.consentSelector === void 0 ? {} : { consentSelector: opts.consentSelector }
|
|
58
59
|
});
|
|
59
60
|
if (opts.writeAirtable) {
|
|
60
61
|
await uploadAttachment(row.id, "Header image", gen.bytes, gen.filename, gen.contentType, {
|
|
@@ -102,7 +103,7 @@ async function runHeaderImageCommand(site, opts) {
|
|
|
102
103
|
}
|
|
103
104
|
let withStore = opts;
|
|
104
105
|
if (opts.writeAirtable && !opts.storeDb && process.env.TURSO_DATABASE_URL) {
|
|
105
|
-
const { openDb, readDbConfig } = await import("./client-
|
|
106
|
+
const { openDb, readDbConfig } = await import("./client-L7NAUG6J.js");
|
|
106
107
|
const { storeHeaderImage } = await import("./header-images-SQBCE5OD.js");
|
|
107
108
|
const db = await openDb(readDbConfig());
|
|
108
109
|
withStore = { ...opts, storeDb: (id, img) => storeHeaderImage(db, id, img) };
|
|
@@ -115,4 +116,4 @@ export {
|
|
|
115
116
|
resolveTargets,
|
|
116
117
|
runHeaderImageCommand
|
|
117
118
|
};
|
|
118
|
-
//# sourceMappingURL=header-image-
|
|
119
|
+
//# sourceMappingURL=header-image-BRTOLHJF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/header-image.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { openBase, readAirtableConfig } from \"../../reports/airtable/client.js\";\nimport { listWebsites, siteSlug, ACTIVE_STATUSES } from \"../../reports/airtable/websites.js\";\nimport type { WebsiteRow } from \"../../reports/airtable/websites.js\";\nimport { uploadAttachment } from \"../../reports/airtable/attachments.js\";\nimport { generateHeaderImage } from \"../../reports/header-image/index.js\";\nimport type { StoredHeaderImage } from \"../../db/header-images.js\";\n\nexport type HeaderImageOptions = {\n all?: boolean;\n force?: boolean;\n writeAirtable?: boolean;\n outDir?: string;\n settleMs?: string;\n consentSelector?: string;\n /** Injected Turso store for the dual-write (#539, design D5): while Airtable\n * is still written (until the Phase 5 freeze), every upload ALSO lands the\n * bytes in sites.header_image* so the Turso read layer serves a real image.\n * Absent → Airtable-only (a local run without Turso env still works). */\n storeDb?: (siteId: string, img: StoredHeaderImage) => Promise<void>;\n};\n\n/** Which rows this invocation should act on. Pure, so it is unit-tested. */\nexport function resolveTargets(\n rows: readonly WebsiteRow[],\n // `| undefined` spelled out because `exactOptionalPropertyTypes` otherwise\n // rejects the caller passing through possibly-undefined CLI flags.\n opts: { site?: string | undefined; all?: boolean | undefined; force?: boolean | undefined },\n): WebsiteRow[] {\n if (opts.site) {\n const want = siteSlug(opts.site);\n return rows.filter((r) => siteSlug(r.name) === want);\n }\n if (!opts.all) return [];\n return rows.filter((r) => {\n if (!r.url) return false;\n if (r.status === null || !ACTIVE_STATUSES.has(r.status)) return false;\n return opts.force ? true : !r.headerImage;\n });\n}\n\n/** Parse the `--settle-ms <ms>` flag. Unset → undefined (the generator's own\n * default settle). `Number(\"abc\")` is NaN, which would sail through as a NaN\n * timeout and silently skip the settle entirely, so anything non-finite or\n * negative is rejected up front rather than producing a subtly-wrong capture. */\nexport function parseSettleMs(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const n = Number(value);\n if (!Number.isFinite(n) || n < 0) {\n throw Object.assign(\n new Error(`--settle-ms must be a non-negative number of milliseconds, got \"${value}\"`),\n { exitCode: 2 },\n );\n }\n return n;\n}\n\n/** Injected in tests so the file-writing branch can be exercised without\n * driving a real browser (mirrors `GenerateInput.shooter`). */\ntype Generate = typeof generateHeaderImage;\n\n/**\n * Generate a header image per target row and either upload it to Airtable or\n * write it locally for review. Split out of {@link runHeaderImageCommand} so\n * the local-output path is testable without an Airtable base.\n */\nexport async function generateForTargets(\n targets: readonly WebsiteRow[],\n opts: HeaderImageOptions,\n generate: Generate = generateHeaderImage,\n): Promise<{ output: string; code: number }> {\n const outDir = resolve(opts.outDir ?? \"reports\");\n const settleMs = parseSettleMs(opts.settleMs);\n // `reports/` does not exist on a fresh checkout, so the writeFile() below\n // would throw ENOENT for the first operator to run the default (local) path.\n // Create it once, before the loop, rather than per site.\n if (!opts.writeAirtable) await mkdir(outDir, { recursive: true });\n\n const lines: string[] = [];\n let failed = 0;\n\n for (const row of targets) {\n try {\n const gen = await generate({\n url: row.url,\n slug: siteSlug(row.name),\n // `exactOptionalPropertyTypes` rejects an explicit `settleMs: undefined`\n // against `settleMs?: number`, so omit the key entirely when unset.\n ...(settleMs === undefined ? {} : { settleMs }),\n ...(opts.consentSelector === undefined ? {} : { consentSelector: opts.consentSelector }),\n });\n if (opts.writeAirtable) {\n // replaceIn: the field must hold exactly the current header — see\n // uploadAttachment, where appending left readers on a stale [0].\n await uploadAttachment(row.id, \"Header image\", gen.bytes, gen.filename, gen.contentType, {\n replaceIn: \"Websites\",\n });\n let stored = \"\";\n if (opts.storeDb) {\n // Dual-write. A Turso failure must not void the Airtable upload —\n // but it must be VISIBLE, never a silent divergence.\n try {\n await opts.storeDb(row.id, {\n bytes: gen.bytes,\n filename: gen.filename,\n contentType: gen.contentType,\n generatedAt: new Date().toISOString(),\n });\n stored = \" + turso\";\n } catch (err) {\n stored = ` (⚠ turso store FAILED: ${err instanceof Error ? err.message : String(err)})`;\n }\n }\n lines.push(\n `✔ ${row.name} — uploaded ${gen.filename} (${(gen.bytes.byteLength / 1024 / 1024).toFixed(2)} MB)${stored}`,\n );\n } else {\n const path = resolve(outDir, gen.filename);\n await writeFile(path, gen.bytes);\n lines.push(`✔ ${row.name} — wrote ${path} (review, then re-run with --write-airtable)`);\n }\n } catch (err) {\n failed++;\n lines.push(`✖ ${row.name} — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n lines.push(`${targets.length - failed}/${targets.length} generated.`);\n return { output: lines.join(\"\\n\"), code: failed > 0 ? 1 : 0 };\n}\n\n/**\n * `header-image [site]` — capture a site's live homepage and composite its\n * report header image. Defaults to writing the JPEG locally so the operator can\n * eyeball it; `--write-airtable` uploads it to the Websites row's Header image\n * field. `--all` backfills every live site that has no header image yet.\n */\nexport async function runHeaderImageCommand(\n site: string | undefined,\n opts: HeaderImageOptions,\n): Promise<{ output: string; code: number }> {\n const base = openBase(readAirtableConfig());\n const rows = await listWebsites(base);\n const targets = resolveTargets(rows, { site, all: opts.all, force: opts.force });\n if (targets.length === 0) {\n return {\n output: site ? `No site matched \"${site}\".` : \"No sites need a header image.\",\n code: 1,\n };\n }\n // Wire the Turso dual-write when the env is present; a local run without it\n // still works Airtable-only (the store is per-site error-isolated above).\n let withStore = opts;\n if (opts.writeAirtable && !opts.storeDb && process.env.TURSO_DATABASE_URL) {\n const { openDb, readDbConfig } = await import(\"../../db/client.js\");\n const { storeHeaderImage } = await import(\"../../db/header-images.js\");\n const db = await openDb(readDbConfig());\n withStore = { ...opts, storeDb: (id, img) => storeHeaderImage(db, id, img) };\n }\n return generateForTargets(targets, withStore);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,20 +5,21 @@ import {
|
|
|
5
5
|
appendSkipNotice,
|
|
6
6
|
fleetWorkdir,
|
|
7
7
|
prepareFleetSites
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SHGIDTYF.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveSites
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-H445EH33.js";
|
|
12
12
|
import {
|
|
13
13
|
healthEndpoint
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-XED2DNAI.js";
|
|
15
|
+
import "./chunk-5CJVUPJU.js";
|
|
16
|
+
import "./chunk-4UTJ4G6P.js";
|
|
17
|
+
import "./chunk-SQ4FSNYL.js";
|
|
17
18
|
import "./chunk-Z3JXLULD.js";
|
|
18
19
|
import "./chunk-LBYOLBW7.js";
|
|
19
20
|
import "./chunk-RARREDQE.js";
|
|
20
21
|
import "./chunk-XXTZBPUY.js";
|
|
21
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-EASYCD6F.js";
|
|
22
23
|
|
|
23
24
|
// src/cli/commands/health-endpoint.ts
|
|
24
25
|
import { resolve } from "path";
|
|
@@ -51,4 +52,4 @@ async function runHealthEndpointCommand(site, opts) {
|
|
|
51
52
|
export {
|
|
52
53
|
runHealthEndpointCommand
|
|
53
54
|
};
|
|
54
|
-
//# sourceMappingURL=health-endpoint-
|
|
55
|
+
//# sourceMappingURL=health-endpoint-UCLMSSCN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/health-endpoint.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { healthEndpoint } from \"../../recipes/health-endpoint/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type HealthEndpointCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runHealthEndpointCommand(\n site: string | undefined,\n opts: HealthEndpointCommandOptions,\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 = await runRecipeOverSites(\"health-endpoint\", sites, (s) => healthEndpoint(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/health-endpoint.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { healthEndpoint } from \"../../recipes/health-endpoint/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type HealthEndpointCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runHealthEndpointCommand(\n site: string | undefined,\n opts: HealthEndpointCommandOptions,\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 = await runRecipeOverSites(\"health-endpoint\", sites, (s) => healthEndpoint(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAcxB,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,yBACpB,MACA,MAC2C;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM,mBAAmB,mBAAmB,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC;AAE3F,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mirrorHealthFields,
|
|
3
3
|
mirrorScheduleFields
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-GEUC5VGM.js";
|
|
5
|
+
import "./chunk-UIITN37J.js";
|
|
6
6
|
import {
|
|
7
7
|
TURSO_IS_AUTHORITATIVE
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WQLNUEZL.js";
|
|
9
9
|
import "./chunk-F3JWOPTG.js";
|
|
10
10
|
import "./chunk-VAD43MOR.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-KN52PM63.js";
|
|
12
12
|
import {
|
|
13
13
|
openDb,
|
|
14
14
|
readDbConfig
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-6INOBNRO.js";
|
|
16
|
+
import "./chunk-T76MA2FH.js";
|
|
17
17
|
import "./chunk-6VAL7XJT.js";
|
|
18
18
|
|
|
19
19
|
// src/audits/health-mirror.ts
|
|
@@ -43,4 +43,4 @@ export {
|
|
|
43
43
|
makeHealthMirrorBestEffort,
|
|
44
44
|
makeScheduleMirrorBestEffort
|
|
45
45
|
};
|
|
46
|
-
//# sourceMappingURL=health-mirror-
|
|
46
|
+
//# sourceMappingURL=health-mirror-ONRT4DQ5.js.map
|
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
renderedHtmlUrl,
|
|
15
15
|
scheduleColumnFor,
|
|
16
16
|
siteValueFor
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-UIITN37J.js";
|
|
18
18
|
import "./chunk-VAD43MOR.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-KN52PM63.js";
|
|
20
20
|
export {
|
|
21
21
|
EXCLUDED_WEBSITE_FIELDS,
|
|
22
22
|
HEALTH_BOOLEAN,
|
|
@@ -34,4 +34,4 @@ export {
|
|
|
34
34
|
scheduleColumnFor,
|
|
35
35
|
siteValueFor
|
|
36
36
|
};
|
|
37
|
-
//# sourceMappingURL=import-airtable-
|
|
37
|
+
//# sourceMappingURL=import-airtable-IIK2QUUF.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -315,14 +315,27 @@ type DependabotAlert = {
|
|
|
315
315
|
scope: "runtime" | "development" | null;
|
|
316
316
|
/** Dependency graph relationship (`dependency.relationship`), or null when GitHub reports
|
|
317
317
|
* "unknown"/nothing. "transitive" means no direct-dep bump can fix it — Renovate's vuln
|
|
318
|
-
* alerts have no fix vehicle until the weekly lockfile-maintenance window.
|
|
319
|
-
|
|
318
|
+
* alerts have no fix vehicle until the weekly lockfile-maintenance window. "inconclusive"
|
|
319
|
+
* is what GitHub stamps on an alert filed against a manifest its dependency graph still
|
|
320
|
+
* tracks but the tree no longer holds (#702) — kept, never folded to null, because it is
|
|
321
|
+
* the secondary tell for a ghost alert. */
|
|
322
|
+
relationship: "direct" | "transitive" | "inconclusive" | null;
|
|
323
|
+
/** The manifest the alert was filed against (`dependency.manifest_path`, e.g.
|
|
324
|
+
* `package-lock.json`), or null when absent. GitHub retains a manifest after the file is
|
|
325
|
+
* deleted from the default branch and keeps filing alerts against that frozen snapshot;
|
|
326
|
+
* the audit resolves this path with {@link GitHubRest.manifestExists} to tell a ghost from
|
|
327
|
+
* a live vulnerability (#702). */
|
|
328
|
+
manifestPath: string | null;
|
|
320
329
|
};
|
|
321
330
|
|
|
322
331
|
/** The Dependabot fetch the security audit needs, injectable for tests. The real default is
|
|
323
332
|
* built from GITHUB_TOKEN; absent token (or a site with no gitRepo) → pnpm/npm audit fallback. */
|
|
324
333
|
type DependabotDeps = {
|
|
325
334
|
listAlerts: (repo: string) => Promise<DependabotAlert[]>;
|
|
335
|
+
/** Whether an alert's `manifestPath` is still on the default branch. Optional: without it
|
|
336
|
+
* every alert counts, which is the loud direction. A lookup that THROWS also counts the
|
|
337
|
+
* alert — an API hiccup must never quietly suppress a real vulnerability (#702). */
|
|
338
|
+
manifestExists?: (repo: string, path: string) => Promise<boolean>;
|
|
326
339
|
};
|
|
327
340
|
declare function securityAudit(ctx: AuditContext): Promise<AuditResult>;
|
|
328
341
|
|
|
@@ -418,6 +431,84 @@ declare function onboard(site: Site, opts?: OnboardOptions): Promise<RecipeResul
|
|
|
418
431
|
*/
|
|
419
432
|
declare function a11yFixturesPage(site: Site): Promise<RecipeResult>;
|
|
420
433
|
|
|
434
|
+
type HealthEndpointDeps = {
|
|
435
|
+
spawn: SpawnFn;
|
|
436
|
+
/** Resolve the TARGET repo's own prettier. Injected so a test can assert the
|
|
437
|
+
* absolute-path spawn without a populated `node_modules`. */
|
|
438
|
+
resolvePrettier?: (repoRoot: string) => Promise<string | null>;
|
|
439
|
+
};
|
|
440
|
+
/**
|
|
441
|
+
* Writes a resilient `src/routes/health/+server.ts` if the route doesn't already
|
|
442
|
+
* exist. The function-health audit fetches this endpoint; existing sites need it
|
|
443
|
+
* or the Report Health Gate blocks their Maintenance reports on "unknown". Operator
|
|
444
|
+
* edits to an existing endpoint are never clobbered (noop on existing file).
|
|
445
|
+
*
|
|
446
|
+
* Two heterogeneity fixes the fleet rollout exposed: (1) it detects whether the
|
|
447
|
+
* site has a `$lib/prismicio` module and writes the Prismic-free variant when it
|
|
448
|
+
* doesn't (a static import of a missing module fails the build); (2) it runs the
|
|
449
|
+
* SITE's own prettier on the written file before committing, so the file matches
|
|
450
|
+
* that site's formatting config (tabs/spaces, quote style vary fleet-wide) and
|
|
451
|
+
* doesn't red the CI format check. Prettier is best-effort — a site without it
|
|
452
|
+
* installed commits unformatted with a flag note rather than failing the recipe.
|
|
453
|
+
*/
|
|
454
|
+
declare function healthEndpoint(site: Site, deps?: HealthEndpointDeps): Promise<RecipeResult>;
|
|
455
|
+
|
|
456
|
+
type SmokeSuiteDeps = {
|
|
457
|
+
spawn: SpawnFn;
|
|
458
|
+
/** Resolve the TARGET repo's own prettier. Injected so a test can assert the
|
|
459
|
+
* absolute-path spawn without a populated `node_modules`. */
|
|
460
|
+
resolvePrettier?: (repoRoot: string) => Promise<string | null>;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Adds the smoke suite to a site: the `tests/smoke/*` specs, a `test:smoke` /
|
|
464
|
+
* `test:unit` script split, `@playwright/test`, and a `playwright.config.ts`
|
|
465
|
+
* that honors `REDDOOR_SMOKE_PORT` (R1.1). Conservative + partial-apply — every
|
|
466
|
+
* file is noop-if-exists, every `package.json` script/dep is add-if-absent, and
|
|
467
|
+
* an existing config that isn't a recognizable shared-base shape is left
|
|
468
|
+
* untouched and flagged for a manual R1.1 patch (never a destructive write).
|
|
469
|
+
* A site with no `package.json` noops (not a node project). Branch+commit per site.
|
|
470
|
+
*/
|
|
471
|
+
declare function smokeSuite(site: Site, deps?: SmokeSuiteDeps): Promise<RecipeResult>;
|
|
472
|
+
|
|
473
|
+
type MatchHarnessOptions = {
|
|
474
|
+
/** The live reference URL the harness gates against. Required — a harness
|
|
475
|
+
* with no reference cannot produce evidence, only an absence of errors. */
|
|
476
|
+
ref: string;
|
|
477
|
+
/** Candidate origin. Defaults to the SvelteKit dev server. */
|
|
478
|
+
cand?: string;
|
|
479
|
+
/** Breakpoint matrix. Defaults to the fleet's 1440 / 834 / 390. */
|
|
480
|
+
matrix?: number[];
|
|
481
|
+
};
|
|
482
|
+
type MatchHarnessDeps = {
|
|
483
|
+
spawn: SpawnFn;
|
|
484
|
+
/** Previously shipped renders per relative path; injectable so the
|
|
485
|
+
* safe-replace path is testable before a second version exists. */
|
|
486
|
+
previous?: Readonly<Record<string, readonly string[]>>;
|
|
487
|
+
/** Previously shipped BLOCK bodies per target file; injectable for the same
|
|
488
|
+
* reason, and empty in the shipped table until a body is superseded. */
|
|
489
|
+
blockPrevious?: Readonly<Record<string, readonly string[]>>;
|
|
490
|
+
/** Resolve the TARGET repo's own prettier. Injected so a test can assert the
|
|
491
|
+
* absolute-path spawn without a populated `node_modules`. */
|
|
492
|
+
resolvePrettier?: (repoRoot: string) => Promise<string | null>;
|
|
493
|
+
};
|
|
494
|
+
/**
|
|
495
|
+
* Installs the matching harness into a site: the dev-guarded `/dev/match/[uid]`
|
|
496
|
+
* route, a `site-pages.js` scaffold and its fixture-vs-model test,
|
|
497
|
+
* `matching/harness.json` + the read layer, the round scripts, the site records,
|
|
498
|
+
* and the `.gitignore` / `.prettierignore` / `CLAUDE.md` blocks.
|
|
499
|
+
*
|
|
500
|
+
* Install-if-absent throughout. Files a site edits are never rewritten. A
|
|
501
|
+
* recipe-owned script that matches a previously shipped render is safe-replaced;
|
|
502
|
+
* one that has been hand-edited is FLAGGED in the notes and left alone.
|
|
503
|
+
*
|
|
504
|
+
* ONE EXCEPTION TO PER-FILE INDEPENDENCE: the scripts in MATCH_HARNESS_COUPLED
|
|
505
|
+
* upgrade as a SET. If any one of them is hand-edited, none of them is written,
|
|
506
|
+
* because gate.sh calls `harness.mjs --check-run` and next.mjs imports from
|
|
507
|
+
* harness.mjs — upgrading the others around a pinned one leaves a harness that
|
|
508
|
+
* cannot run at all. See the measurement on MATCH_HARNESS_COUPLED.
|
|
509
|
+
*/
|
|
510
|
+
declare function matchHarness(site: Site, opts: MatchHarnessOptions, deps?: MatchHarnessDeps): Promise<RecipeResult>;
|
|
511
|
+
|
|
421
512
|
type InitStepResult = {
|
|
422
513
|
kind: "recipe";
|
|
423
514
|
result: RecipeResult;
|
|
@@ -1166,6 +1257,13 @@ type SiteMirror = {
|
|
|
1166
1257
|
health: (siteId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
1167
1258
|
/** Columns that live in `sites`. */
|
|
1168
1259
|
site: (siteId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
1260
|
+
/** #645. Does Turso hold a row for this site id? A pure READ, so it is the one
|
|
1261
|
+
* op here that neither logs a SITE_MIRROR line nor throws under the freeze —
|
|
1262
|
+
* `ensure-site` uses it to decide whether to heal, and a probe that threw
|
|
1263
|
+
* would sink the very command that repairs the gap. Creds-absent answers
|
|
1264
|
+
* `true` ("assume present"), so a mirror that cannot read can never provoke
|
|
1265
|
+
* a blind insert. */
|
|
1266
|
+
hasRow: (siteId: string) => Promise<boolean>;
|
|
1169
1267
|
};
|
|
1170
1268
|
|
|
1171
1269
|
type ShootOptions = {
|
|
@@ -1174,6 +1272,9 @@ type ShootOptions = {
|
|
|
1174
1272
|
height: number;
|
|
1175
1273
|
deviceScaleFactor: number;
|
|
1176
1274
|
settleMs: number;
|
|
1275
|
+
/** Extra CSS selector(s) hidden before the shutter, for a site whose consent
|
|
1276
|
+
* or interstitial UI the class/id heuristic misses. */
|
|
1277
|
+
consentSelector?: string;
|
|
1177
1278
|
};
|
|
1178
1279
|
/** Injected browser IO. The real impl drives Playwright; tests pass a fake. */
|
|
1179
1280
|
type Shooter = {
|
|
@@ -1187,8 +1288,11 @@ type GenerateInput = {
|
|
|
1187
1288
|
slug?: string;
|
|
1188
1289
|
/** Injected browser IO (tests). */
|
|
1189
1290
|
shooter?: Shooter;
|
|
1190
|
-
/** Per-site settle override for animation-heavy
|
|
1291
|
+
/** Per-site settle override for animation-heavy homepages. */
|
|
1191
1292
|
settleMs?: number;
|
|
1293
|
+
/** Extra CSS selector(s) hidden before the shutter, for consent or
|
|
1294
|
+
* interstitial UI the capture's class/id heuristic misses (#654). */
|
|
1295
|
+
consentSelector?: string;
|
|
1192
1296
|
};
|
|
1193
1297
|
type GeneratedHeaderImage = {
|
|
1194
1298
|
bytes: Uint8Array;
|
|
@@ -1452,6 +1556,15 @@ type SubmissionRow = {
|
|
|
1452
1556
|
* was attempted: a non-newsletter form, a spam row, a site with no destination
|
|
1453
1557
|
* configured, or a row written before 0005. See ingest.ts for the token grammar. */
|
|
1454
1558
|
fanoutStatus?: string | null;
|
|
1559
|
+
/** Resend's bounce classification, kept so a content rejection by the CLIENT's
|
|
1560
|
+
* mail filter can be told apart from a dead mailbox (#783). Null for a
|
|
1561
|
+
* complaint, and for every row written before migration 0018. */
|
|
1562
|
+
bounceType?: string | null;
|
|
1563
|
+
bounceSubType?: string | null;
|
|
1564
|
+
bounceMessage?: string | null;
|
|
1565
|
+
/** ISO-8601 of the operator saying "this address is not dead" (#783). The row
|
|
1566
|
+
* keeps its bounce record and stops counting toward the alarm. */
|
|
1567
|
+
bounceAckAt?: string | null;
|
|
1455
1568
|
};
|
|
1456
1569
|
|
|
1457
1570
|
type ScreenOutTotals = {
|
|
@@ -1474,6 +1587,13 @@ type AttentionItem = {
|
|
|
1474
1587
|
/** Stable identity for diffing: `vuln:<siteId>`, `delivery:<reportId>`. */
|
|
1475
1588
|
key: string;
|
|
1476
1589
|
kind: "vuln" | "delivery" | "renovate" | "lighthouse" | "ci" | "analytics" | "preflight" | "turnstile" | "notify-bounce"
|
|
1590
|
+
/** #645. Leads captured by the dead-letter because their site could not be
|
|
1591
|
+
* placed — a store outage during the lookup, or (since #645) a slug with no
|
|
1592
|
+
* Turso row at all. Until this kind existed a dropped lead had NO alarm
|
|
1593
|
+
* anywhere: the queue could fill and nothing said so. Keyed by SLUG, not by
|
|
1594
|
+
* site id, because the whole point of the worst case is that the slug
|
|
1595
|
+
* resolves to no site. */
|
|
1596
|
+
| "deadletter"
|
|
1477
1597
|
/** The nightly Prismic model sweep. THREE item flavors share this kind —
|
|
1478
1598
|
* `prismic-drift:` (repo and Prismic diverge), `prismic-unknown:` (the check
|
|
1479
1599
|
* ran and could not answer), `prismic-stale:` (nobody has re-established the
|
|
@@ -1612,6 +1732,17 @@ type CockpitModel = {
|
|
|
1612
1732
|
* invisible to every fleet op, so the Needs-you feed surfaces them as amber watch
|
|
1613
1733
|
* rows (optional for back-compat). */
|
|
1614
1734
|
unrecognizedStatus?: OffFleetSiteEntry[];
|
|
1735
|
+
/** #786. Attention items that belong to NO site card. The grid is built from
|
|
1736
|
+
* the visible sites and items are grouped onto it by `siteName`, so an item
|
|
1737
|
+
* naming a site the fleet does not have matched nothing and was dropped —
|
|
1738
|
+
* silently, on the one surface the operator actually watches.
|
|
1739
|
+
*
|
|
1740
|
+
* The collector that produces them is the one whose entire point is that the
|
|
1741
|
+
* site is missing: a dead letter for a slug resolving to no fleet row means
|
|
1742
|
+
* leads are being dropped RIGHT NOW. Kept general rather than
|
|
1743
|
+
* dead-letter-specific, so a future card-less item lands here instead of
|
|
1744
|
+
* vanishing the same way. Optional for back-compat with hand-built models. */
|
|
1745
|
+
cardless?: AttentionItem[];
|
|
1615
1746
|
};
|
|
1616
1747
|
/** The cockpit's alarm verdict for ONE site, for the /s/<slug> page header. */
|
|
1617
1748
|
type SiteAlarmContext = {
|
|
@@ -1702,4 +1833,4 @@ declare function loadPlate(): Promise<Uint8Array>;
|
|
|
1702
1833
|
/** Read a headline overlay (transparent PNG, ink-box cropped). */
|
|
1703
1834
|
declare function loadHeadline(kind: HeadlineKind): Promise<Uint8Array>;
|
|
1704
1835
|
|
|
1705
|
-
export { ALL_AUDIT_NAMES, ALL_RECIPE_NAMES, type AirtableInventoryOptions, AuditName, AuditResult, BLURRED_CID, type BumpDepsOptions, type BundledImage, CHECK_CID, type ConvertToPnpmOptions, DEFAULT_INIT_STEPS, type DraftOptions, type DraftResult, type DueItem, type GenerateInput, type GeneratedHeaderImage, type HeaderImage, type InitOptions, type InitResult, type InitStep, type InitStepResult, InventoryProvider, type LighthouseScores, type LocalPathOptions, type OnboardAudit, type OnboardOptions, type OrchestrateOptions, RecipeName, RecipeResult, type RefreshHeaderDeps, type RenderResult, type ReportData, type ReportType, Site, type UpgradeSvelte4to5Options, a11yAudit, a11yFixturesPage, bumpDeps, convertToPnpm, depsAudit, domainFromUrl, draftReportForSite, findDueReports, fromAirtableBase, fromJsonFile, generateHeaderImage, init, isRecipeName, lighthouseAudit, lintAudit, loadBundledImages, loadHeadline, loadPlate, localPath, onboard, renderCockpitHtml, renderReportHtml, renderSiteDashboardHtml, runAudits, runAuditsAcross, securityAudit, selfCaretRange, selfPackageVersion, sendApprovedReports, svelteCodemods, upgradeSvelte4to5, verifyBasicAuth };
|
|
1836
|
+
export { ALL_AUDIT_NAMES, ALL_RECIPE_NAMES, type AirtableInventoryOptions, AuditName, AuditResult, BLURRED_CID, type BumpDepsOptions, type BundledImage, CHECK_CID, type ConvertToPnpmOptions, DEFAULT_INIT_STEPS, type DraftOptions, type DraftResult, type DueItem, type GenerateInput, type GeneratedHeaderImage, type HeaderImage, type InitOptions, type InitResult, type InitStep, type InitStepResult, InventoryProvider, type LighthouseScores, type LocalPathOptions, type OnboardAudit, type OnboardOptions, type OrchestrateOptions, RecipeName, RecipeResult, type RefreshHeaderDeps, type RenderResult, type ReportData, type ReportType, Site, type UpgradeSvelte4to5Options, a11yAudit, a11yFixturesPage, bumpDeps, convertToPnpm, depsAudit, domainFromUrl, draftReportForSite, findDueReports, fromAirtableBase, fromJsonFile, generateHeaderImage, healthEndpoint, init, isRecipeName, lighthouseAudit, lintAudit, loadBundledImages, loadHeadline, loadPlate, localPath, matchHarness, onboard, renderCockpitHtml, renderReportHtml, renderSiteDashboardHtml, runAudits, runAuditsAcross, securityAudit, selfCaretRange, selfPackageVersion, sendApprovedReports, smokeSuite, svelteCodemods, upgradeSvelte4to5, verifyBasicAuth };
|