@reddoorla/maintenance 0.95.0 → 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-PGT4SZZB.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-4AIYWWKV.js → chunk-62YWOFVN.js} +36 -5
- package/dist/chunk-62YWOFVN.js.map +1 -0
- package/dist/{chunk-22GKJO5F.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-DMPHP7UP.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-AEUABPAJ.js → chunk-OTEVKRAH.js} +3 -3
- package/dist/{chunk-KQB2BX4V.js → chunk-P4A6D6HO.js} +4 -4
- package/dist/chunk-P7323YVW.js +134 -0
- 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-OCNSIBMP.js → chunk-T76MA2FH.js} +135 -1
- package/dist/{chunk-OCNSIBMP.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-Y6FCXRIC.js +3972 -0
- 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/eslint.js +27 -1
- package/dist/configs/eslint.js.map +1 -1
- 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-BBEM7CBX.js → db-5K4CDEGJ.js} +45 -20
- package/dist/db-5K4CDEGJ.js.map +1 -0
- package/dist/deadletter-G4M3HSVM.js +17 -0
- package/dist/{digest-65BOZ7AT.js → digest-5AJGWS33.js} +45 -22
- package/dist/digest-5AJGWS33.js.map +1 -0
- package/dist/{digest-collectors-EHFY2OQC.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-WIDO6LGU.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-2LWF5C5B.js → forms-notify-target-4NPLX2UG.js} +5 -5
- package/dist/{freeze-A6MUCZU4.js → freeze-GUQ43EAU.js} +2 -2
- package/dist/{github-signals-GAHNOAHS.js → github-signals-DMU74SAX.js} +10 -10
- package/dist/{header-image-YN3AQRY3.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-EB76EERV.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-4RVWPZGI.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-2Q6ISEES.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-MWXENQOS.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-4VQP7JJL.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-W6CNLTWH.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-X4Z67LWW.js → prospect-audit-AJEE3Z4L.js} +16 -7
- package/dist/prospect-audit-AJEE3Z4L.js.map +1 -0
- package/dist/{prospect-audits-RVYEA4KH.js → prospect-audits-IZVQY3OQ.js} +12 -4
- 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-4GFD4MW2.js → report-RC5LGPU3.js} +22 -20
- package/dist/report-RC5LGPU3.js.map +1 -0
- package/dist/{report-mirror-IP64R7B3.js → report-mirror-KKZZ6RMZ.js} +13 -9
- package/dist/{report-mirror-IP64R7B3.js.map → report-mirror-KKZZ6RMZ.js.map} +1 -1
- package/dist/{schema-2V7BGYVT.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-MAB2PBXQ.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-UKHREAD6.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-5GKJPCIH.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-4AIYWWKV.js.map +0 -1
- package/dist/chunk-5UINJNAJ.js.map +0 -1
- package/dist/chunk-6VKYQATC.js +0 -1708
- package/dist/chunk-6VKYQATC.js.map +0 -1
- package/dist/chunk-7MKT4I5T.js +0 -62
- package/dist/chunk-7MKT4I5T.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-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-YLYXW5PH.js.map +0 -1
- package/dist/client-M2V6FHH5.js +0 -11
- package/dist/db-BBEM7CBX.js.map +0 -1
- package/dist/digest-65BOZ7AT.js.map +0 -1
- package/dist/digest-state-3KHZF7GD.js.map +0 -1
- package/dist/ensure-site-WIDO6LGU.js.map +0 -1
- package/dist/header-image-YN3AQRY3.js.map +0 -1
- package/dist/launch-4RVWPZGI.js.map +0 -1
- package/dist/match-harness-2Q6ISEES.js.map +0 -1
- package/dist/migrate-K4JETR36.js +0 -7
- package/dist/prismic-ci-6GKKZGB5.js.map +0 -1
- package/dist/prospect-audit-X4Z67LWW.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-4GFD4MW2.js.map +0 -1
- package/dist/schema-2V7BGYVT.js.map +0 -1
- package/dist/site-mirror-UKHREAD6.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-PGT4SZZB.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-22GKJO5F.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-DMPHP7UP.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-AEUABPAJ.js.map → chunk-OTEVKRAH.js.map} +0 -0
- /package/dist/{chunk-KQB2BX4V.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-M2V6FHH5.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-EHFY2OQC.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-2LWF5C5B.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-GAHNOAHS.js.map → github-signals-DMU74SAX.js.map} +0 -0
- /package/dist/{health-mirror-EB76EERV.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-K4JETR36.js.map → lighthouse-airtable-3NOFB42B.js.map} +0 -0
- /package/dist/{notify-IISTHNBR.js.map → migrate-NE3DUMTM.js.map} +0 -0
- /package/dist/{orchestrate-MWXENQOS.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-RVYEA4KH.js.map → pipeline-UUPXOS2J.js.map} +0 -0
- /package/dist/{preflight-4VQP7JJL.js.map → preflight-POZZI3GN.js.map} +0 -0
- /package/dist/{prismic-models-W6CNLTWH.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-MAB2PBXQ.js.map → selftest-AFLR7YV7.js.map} +0 -0
- /package/dist/{submissions-5GKJPCIH.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/recipes/self-updating/index.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport type { RecipeResult, Site } from \"../../types.js\";\nimport { refusedByGit, undoRefusedWrites, RESTORED_NOTE } from \"../_head-guard.js\";\nimport { templatesByName } from \"../sync-configs/templates.js\";\nimport {\n renovateActionGaps,\n withRenovatePinsFrom,\n RENOVATE_ACTION_CONFIG,\n} from \"../sync-configs/renovate-action.js\";\nimport {\n resolveOwnerRepo,\n push as gitPush,\n branchName,\n checkoutBranch,\n createBranch,\n currentBranch,\n commit as gitCommit,\n isWorkingTreeClean,\n} from \"../../util/git.js\";\nimport { siteLabel } from \"../../util/site.js\";\nimport { readGitHubConfig } from \"../../github/config.js\";\nimport { makeGitHub, type GitHub } from \"../../github/gh.js\";\nimport {\n FLEET_RULESET_NAME,\n desiredRuleset,\n healRuleset,\n rulesetGaps,\n} from \"../../github/rulesets.js\";\n\n// Deliberately NOT ci.yml: that file is per-site parameterized (netlify-site,\n// node-version, permissions), so an exact-match heal against a static template\n// would strip those values in a green auto-mergeable PR — the armed clobber\n// the 2026-08-02 architecture review found. The starter clone owns ci.yml's\n// shape. Its pinned reusable-workflow ref is sometimes bumped by Renovate\n// (v1.2.0 -> v1.3.0 across 17 repos, Jul-Aug 2026) but was not for v1.4.0 or\n// v1.4.1 — the latter was swept by hand on 2026-09-01 — so propagation is a\n// manual step to verify, never a guarantee.\nconst SELF_UPDATING_CONFIGS = [\"renovate-action\", \"renovate-config\"] as const;\n\n// Reusable-workflow jobs report their check as \"<caller-job> / <reusable-job>\".\n// The thin `ci` caller (job `ci`) calls reddoorla/.github's reusable workflow (job `ci`),\n// so the required context is \"ci / ci\", NOT \"ci\". (Provisional — verified empirically on the\n// starter during M7.1 rollout; correct here if the live checks API reports a different string.)\nconst REQUIRED_CHECK = \"ci / ci\";\n\nexport type SelfUpdatingDeps = {\n github?: GitHub;\n pushBranch?: (cwd: string, branch: string) => Promise<void>;\n};\n\nfunction resultOf(\n site: Site,\n status: RecipeResult[\"status\"],\n notes: string,\n commits: string[] = [],\n): RecipeResult {\n return { recipe: \"self-updating\", site: siteLabel(site), status, commits, notes };\n}\n\n/** True when a file's current content matches the canonical template for drift\n * purposes. Normalizes line endings + trailing whitespace so a stray trailing\n * newline (or CRLF) can't read as drift and open a needless PR every nightly run;\n * any real content change still differs. */\nfunction sameConfigContents(current: string, canonical: string): boolean {\n const norm = (s: string) => s.replace(/\\r\\n/g, \"\\n\").replace(/\\s+$/, \"\");\n return norm(current) === norm(canonical);\n}\n\nexport async function selfUpdating(site: Site, deps: SelfUpdatingDeps = {}): Promise<RecipeResult> {\n const templates = templatesByName([...SELF_UPDATING_CONFIGS]);\n\n let repo: string | null;\n try {\n repo = await resolveOwnerRepo(site);\n } catch (err) {\n // A malformed repo identity must abort before any `gh` write — surface it\n // as a recipe failure rather than letting the token reach an unintended repo.\n return resultOf(site, \"failed\", err instanceof Error ? err.message : String(err));\n }\n if (!repo) {\n return resultOf(\n site,\n \"failed\",\n \"could not determine a GitHub repo for this site — set Airtable 'Git repo', or give \" +\n \"the checkout an origin remote whose URL is a GitHub owner/repo\",\n );\n }\n\n const cfg = readGitHubConfig();\n if (!deps.github && !cfg) return resultOf(site, \"failed\", \"GITHUB_TOKEN not set\");\n const github = deps.github ?? makeGitHub({ token: cfg!.token });\n\n const base = await github.defaultBranch(repo).catch(() => \"main\");\n const actions: string[] = [];\n const commits: string[] = [];\n // Hoisted so the `finally` can restore the operator's branch even when a\n // failure (push/PR error) aborts AFTER we created + checked out the maint\n // branch. `maintBranch` stays null until createBranch succeeds, so the\n // restore is a no-op on every path that never left the operator's branch.\n let original: string | null = null;\n let maintBranch: string | null = null;\n\n try {\n // A. Renovate config on the default branch — compare CONTENT, not just\n // existence, so a present-but-STALE config (a pre-App workflow, a drifted\n // Renovate schedule window) is corrected rather than left silently\n // forever. The prior existence-only gate reported \"already self-updating\" for any\n // repo that merely HAD the files, however out of date — the very drift this\n // recipe exists to repair (e.g. the Renovate schedule-window regression).\n //\n // renovate.yml specifically is compliance-checked rather than byte-matched\n // (see renovateActionGaps / withRenovatePinsFrom in\n // ../sync-configs/renovate-action.js): Renovate legitimately bumps its own\n // digest pins forward, and a site's prettier may legitimately quote the\n // cron / RENOVATE_* scalars differently — neither is real drift (issue\n // #651; a byte-match recipe opened reddoor-starter-blux#1, a PR that\n // DOWNGRADED Renovate's own pin).\n const drifted: string[] = [];\n // Captured so the write loop below can carry a drifted renovate.yml's own\n // pins forward instead of re-fetching (and so a compliant-but-non-byte-\n // identical file's contents are available for that carry-forward too,\n // though it won't need healing).\n const currentContents = new Map<string, string | null>();\n for (const t of templates) {\n const current = await github.fileContentsOnBranch(repo, base, t.path);\n currentContents.set(t.path, current);\n if (current === null) {\n drifted.push(t.path);\n continue;\n }\n if (sameConfigContents(current, t.contents)) continue;\n if (t.config === RENOVATE_ACTION_CONFIG && renovateActionGaps(current).length === 0) {\n continue;\n }\n drifted.push(t.path);\n }\n if (drifted.length > 0) {\n const existingPR = await github.findOpenSelfUpdatingPR(repo);\n if (existingPR) {\n actions.push(`self-updating PR already open: ${existingPR}`);\n } else {\n if (!(await isWorkingTreeClean(site.path))) {\n return resultOf(site, \"failed\", \"working tree not clean — commit or stash first\");\n }\n // Capture the operator's branch BEFORE creating the maint branch so the\n // `finally` can return them to it (#2). Best-effort capture: if it fails\n // we just skip the restore rather than guess.\n try {\n original = await currentBranch(site.path);\n } catch {\n original = null;\n }\n maintBranch = branchName(\"self-updating\");\n await createBranch(site.path, maintBranch);\n // Write only the paths that actually drifted — a repo whose\n // renovate.json is stale but whose renovate.yml already passes\n // `renovateActionGaps` must not have that compliant renovate.yml\n // silently rewritten (e.g. un-quoting its scalars) in the same PR.\n // On a fresh repo every template path is missing, so `drifted`\n // already contains all of them and bootstrap is unaffected.\n // What each written path held BEFORE this run, so one git then refuses\n // can be put back exactly as it was (null = the file did not exist).\n const before = new Map<string, string | null>();\n for (const t of templates) {\n if (!drifted.includes(t.path)) continue;\n const dest = join(site.path, t.path);\n before.set(t.path, await readFile(dest, \"utf-8\").catch(() => null));\n await mkdir(dirname(dest), { recursive: true });\n // For a genuinely non-compliant renovate.yml, carry the site's own\n // (still-digest-pinned) action refs forward onto the template before\n // writing it — writing the template verbatim would put its OLDER\n // pins over the site's newer ones, re-introducing the downgrade\n // this compliance check exists to prevent (issue #651).\n const contents =\n t.config === RENOVATE_ACTION_CONFIG\n ? withRenovatePinsFrom(t.contents, currentContents.get(t.path) ?? null)\n : t.contents;\n await writeFile(dest, contents, \"utf-8\");\n }\n const sha = await gitCommit(site.path, \"ci: enable self-updating (Renovate auto-merge)\");\n if (sha) commits.push(sha);\n\n // Did git TAKE the configs? The PARTIAL drop is the one that bites: with\n // one of the two paths ignored the other still commits, so `commit()`\n // returns a SHA and — before this check — the branch was pushed and a PR\n // opened for a repo that would never become self-updating, after which\n // every later run reported \"self-updating PR already open\" forever.\n // Checked BEFORE the push, so nothing reaches GitHub on a refusal (#741).\n const refusal = await refusedByGit(site.path, drifted, \"the Renovate configuration\");\n if (refusal) {\n await undoRefusedWrites(site.path, before, refusal.missing);\n return resultOf(site, \"failed\", refusal.notes + RESTORED_NOTE, commits);\n }\n\n await (deps.pushBranch ?? gitPush)(site.path, maintBranch);\n const pr = await github.openPullRequest(repo, {\n head: maintBranch,\n base,\n title: \"Enable self-updating (Renovate)\",\n body: \"Adds scheduled Renovate and Renovate-owned merges for patch/minor updates. (ci.yml is deliberately not managed here — its shape comes from the starter and its reusable-workflow pin from Renovate.)\",\n });\n actions.push(`opened PR ${pr.url}`);\n // (Branch restore happens in the `finally` below — on success AND on a\n // failure that aborts after createBranch.)\n }\n }\n\n // B. Repo settings — check-then-ensure, each independent (self-healing).\n //\n // Platform auto-merge is DISABLED fleet-wide, and this block self-heals toward\n // OFF (it used to drive repos ON — do not \"fix\" it back).\n //\n // Why: GitHub's platform auto-merge is a per-PR flag that anyone with write\n // access can arm; the PR then merges itself later, unattended, once checks go\n // green. The org Renovate preset forbids auto-merging majors and was working\n // correctly — Renovate never armed them — but the preset has no authority over\n // a flag someone else set. On 2026-07-26 a bulk `gh pr merge --auto` sweep\n // armed it across 8 fleet repos, and the next morning two `actions/checkout`\n // MAJOR bumps merged with zero reviews (reddoor-starter#77,\n // reddoor-website#111) as soon as Renovate's own rebase cleared their\n // conflicts. Realized damage, not a hypothetical.\n //\n // The fix is to keep merges INSIDE Renovate's own run, where its `packageRules`\n // actually govern the decision. Renovate can only merge while it is running, so\n // the workflow cron (see sync-configs templates) is the merge cadence.\n //\n // Leaving the self-heal pointed at OFF makes this a drift ALARM: if someone\n // re-enables platform auto-merge, the next `self-updating` / `launch` run turns\n // it back off and records the action. `enableRepoAutoMerge` is retained in\n // `src/github/gh.ts` as the documented rollback path.\n if (await github.autoMergeEnabled(repo)) {\n await github.disableRepoAutoMerge(repo);\n actions.push(\"disabled auto-merge (platform auto-merge is not permitted fleet-wide)\");\n }\n const existingContexts = await github.branchProtectionContexts(repo, base);\n if (!existingContexts.includes(REQUIRED_CHECK)) {\n // protectBranch issues a full PUT that REPLACES required-status-check contexts.\n // Send the UNION of the branch's existing required contexts + our REQUIRED_CHECK\n // so we ADD the CI gate without silently dropping any other checks the repo\n // already requires. (When the branch has no protection yet, existingContexts is\n // [] and this is just [REQUIRED_CHECK] — the original behavior.) Dedupe defends\n // against REQUIRED_CHECK already appearing among the existing contexts.\n const contexts = [...new Set([...existingContexts, REQUIRED_CHECK])];\n await github.protectBranch(repo, base, contexts);\n actions.push(`required \"${REQUIRED_CHECK}\" check on ${base}`);\n }\n // Ruleset ensure — the layer that binds ADMINS. Classic protection above\n // keeps `enforce_admins: false`, which is exactly the hole the 2026-07-26\n // bulk `gh pr merge --auto` sweep walked through (two unreviewed MAJORS\n // merged). The 2026-08-01 audit then found the six NEWEST repos with no\n // ruleset at all — every hand-applied sweep regrows its gap at the next\n // onboard, so the recipe owns the invariant now. Spec + invariants:\n // docs/superpowers/specs/2026-08-02-ruleset-self-healing-design.md.\n //\n // Private repos are skipped BEFORE any attempt: rulesets there need a paid\n // plan, so trying would either fail every run or spam a phantom action\n // that flips this recipe to \"applied\" forever. Classic protection remains\n // their floor.\n if ((await github.repoVisibility(repo)) === \"public\") {\n // Evidence gate: only require \"ci / ci\" once that check-run has actually\n // been OBSERVED on the default branch. With an empty bypass list, a\n // required context that never fires would make the repo permanently\n // unmergeable by EVERYONE — e.g. a workflow_call-only ci.yml emits no\n // check runs. Unobserved ⇒ refs rules only; the check upgrades on a\n // later pass once real evidence exists.\n //\n // Residual risk, accepted: this proves the check fires on default-branch\n // PUSHES, not on pull_request events — a hand-edited push-only ci.yml\n // would pass the gate and then block every PR. ci.yml is deliberately\n // NOT healed by block A (per-site parameterized; see\n // SELF_UPDATING_CONFIGS), so this recipe cannot correct that drift —\n // the exposure is one bricked-PR repo, immediately visible on its next\n // PR. Un-brick path: edit the ruleset via API (ruleset ADMIN is not\n // ref-gated), then fix the ci.yml triggers by push.\n const check = (await github.checkContextObserved(repo, base, REQUIRED_CHECK))\n ? REQUIRED_CHECK\n : null;\n const existingRuleset = (await github.listRepoRulesets(repo)).find(\n (r) => r.name === FLEET_RULESET_NAME,\n );\n if (!existingRuleset) {\n await github.createRuleset(repo, desiredRuleset(check));\n actions.push(\n check === null\n ? `created ruleset \"${FLEET_RULESET_NAME}\" (refs rules only — \"${REQUIRED_CHECK}\" not yet observed on ${base})`\n : `created ruleset \"${FLEET_RULESET_NAME}\"`,\n );\n } else {\n const full = await github.getRuleset(repo, existingRuleset.id);\n const gaps = rulesetGaps(full, check);\n if (gaps.length > 0) {\n // PUT the healed payload (merge TOWARD the floor, never away — see\n // healRuleset). Recording the specific gaps makes this the drift\n // ALARM, same as the auto-merge-off action above.\n await github.updateRuleset(repo, existingRuleset.id, healRuleset(full, check));\n actions.push(`healed ruleset drift: ${gaps.join(\"; \")}`);\n }\n }\n }\n // (No per-repo RENOVATE_TOKEN planting anymore: Renovate authenticates as\n // the reddoor-renovate GitHub App, whose RENOVATE_APP_ID / _PRIVATE_KEY are\n // org-level with all-repos visibility — a new repo needs NOTHING set. The\n // old step was already redundant for new sites (the PAT was an org secret\n // too); existing per-repo copies are inert and left to rot harmlessly.\n // docs/runbooks/renovate-app-identity.md covers the migration + rollback.)\n } catch (err) {\n const done = actions.length ? ` (completed: ${actions.join(\"; \")})` : \"\";\n const message = err instanceof Error ? err.message : String(err);\n return resultOf(site, \"failed\", `${message}${done}`, commits);\n } finally {\n // Restore the operator's branch whenever we created + checked out a maint\n // branch — on SUCCESS and, critically, on FAILURE. Without this, a push/PR\n // error after createBranch strands the checkout on the maint branch with an\n // unpushed commit, and the retry then fails at createBranch (\"branch already\n // exists\"). Best-effort: a restore failure must not mask the real outcome.\n if (maintBranch !== null && original !== null && original !== maintBranch) {\n try {\n await checkoutBranch(site.path, original);\n } catch (err) {\n console.warn(\n `warning: could not restore branch ${original} after self-updating: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n }\n\n return actions.length\n ? resultOf(site, \"applied\", actions.join(\"; \"), commits)\n : resultOf(site, \"noop\", \"already self-updating\", commits);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,OAAO,UAAU,iBAAiB;AAC3C,SAAS,SAAS,YAAY;AAqC9B,IAAM,wBAAwB,CAAC,mBAAmB,iBAAiB;AAMnE,IAAM,iBAAiB;AAOvB,SAAS,SACP,MACA,QACA,OACA,UAAoB,CAAC,GACP;AACd,SAAO,EAAE,QAAQ,iBAAiB,MAAM,UAAU,IAAI,GAAG,QAAQ,SAAS,MAAM;AAClF;AAMA,SAAS,mBAAmB,SAAiB,WAA4B;AACvE,QAAM,OAAO,CAAC,MAAc,EAAE,QAAQ,SAAS,IAAI,EAAE,QAAQ,QAAQ,EAAE;AACvE,SAAO,KAAK,OAAO,MAAM,KAAK,SAAS;AACzC;AAEA,eAAsB,aAAa,MAAY,OAAyB,CAAC,GAA0B;AACjG,QAAM,YAAY,gBAAgB,CAAC,GAAG,qBAAqB,CAAC;AAE5D,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,iBAAiB,IAAI;AAAA,EACpC,SAAS,KAAK;AAGZ,WAAO,SAAS,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,EAClF;AACA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,MAAM,iBAAiB;AAC7B,MAAI,CAAC,KAAK,UAAU,CAAC,IAAK,QAAO,SAAS,MAAM,UAAU,sBAAsB;AAChF,QAAM,SAAS,KAAK,UAAU,WAAW,EAAE,OAAO,IAAK,MAAM,CAAC;AAE9D,QAAM,OAAO,MAAM,OAAO,cAAc,IAAI,EAAE,MAAM,MAAM,MAAM;AAChE,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAK3B,MAAI,WAA0B;AAC9B,MAAI,cAA6B;AAEjC,MAAI;AAeF,UAAM,UAAoB,CAAC;AAK3B,UAAM,kBAAkB,oBAAI,IAA2B;AACvD,eAAW,KAAK,WAAW;AACzB,YAAM,UAAU,MAAM,OAAO,qBAAqB,MAAM,MAAM,EAAE,IAAI;AACpE,sBAAgB,IAAI,EAAE,MAAM,OAAO;AACnC,UAAI,YAAY,MAAM;AACpB,gBAAQ,KAAK,EAAE,IAAI;AACnB;AAAA,MACF;AACA,UAAI,mBAAmB,SAAS,EAAE,QAAQ,EAAG;AAC7C,UAAI,EAAE,WAAW,0BAA0B,mBAAmB,OAAO,EAAE,WAAW,GAAG;AACnF;AAAA,MACF;AACA,cAAQ,KAAK,EAAE,IAAI;AAAA,IACrB;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,aAAa,MAAM,OAAO,uBAAuB,IAAI;AAC3D,UAAI,YAAY;AACd,gBAAQ,KAAK,kCAAkC,UAAU,EAAE;AAAA,MAC7D,OAAO;AACL,YAAI,CAAE,MAAM,mBAAmB,KAAK,IAAI,GAAI;AAC1C,iBAAO,SAAS,MAAM,UAAU,qDAAgD;AAAA,QAClF;AAIA,YAAI;AACF,qBAAW,MAAM,cAAc,KAAK,IAAI;AAAA,QAC1C,QAAQ;AACN,qBAAW;AAAA,QACb;AACA,sBAAc,WAAW,eAAe;AACxC,cAAM,aAAa,KAAK,MAAM,WAAW;AASzC,cAAM,SAAS,oBAAI,IAA2B;AAC9C,mBAAW,KAAK,WAAW;AACzB,cAAI,CAAC,QAAQ,SAAS,EAAE,IAAI,EAAG;AAC/B,gBAAM,OAAO,KAAK,KAAK,MAAM,EAAE,IAAI;AACnC,iBAAO,IAAI,EAAE,MAAM,MAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,IAAI,CAAC;AAClE,gBAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAM9C,gBAAM,WACJ,EAAE,WAAW,yBACT,qBAAqB,EAAE,UAAU,gBAAgB,IAAI,EAAE,IAAI,KAAK,IAAI,IACpE,EAAE;AACR,gBAAM,UAAU,MAAM,UAAU,OAAO;AAAA,QACzC;AACA,cAAM,MAAM,MAAM,OAAU,KAAK,MAAM,gDAAgD;AACvF,YAAI,IAAK,SAAQ,KAAK,GAAG;AAQzB,cAAM,UAAU,MAAM,aAAa,KAAK,MAAM,SAAS,4BAA4B;AACnF,YAAI,SAAS;AACX,gBAAM,kBAAkB,KAAK,MAAM,QAAQ,QAAQ,OAAO;AAC1D,iBAAO,SAAS,MAAM,UAAU,QAAQ,QAAQ,eAAe,OAAO;AAAA,QACxE;AAEA,eAAO,KAAK,cAAc,MAAS,KAAK,MAAM,WAAW;AACzD,cAAM,KAAK,MAAM,OAAO,gBAAgB,MAAM;AAAA,UAC5C,MAAM;AAAA,UACN;AAAA,UACA,OAAO;AAAA,UACP,MAAM;AAAA,QACR,CAAC;AACD,gBAAQ,KAAK,aAAa,GAAG,GAAG,EAAE;AAAA,MAGpC;AAAA,IACF;AAyBA,QAAI,MAAM,OAAO,iBAAiB,IAAI,GAAG;AACvC,YAAM,OAAO,qBAAqB,IAAI;AACtC,cAAQ,KAAK,uEAAuE;AAAA,IACtF;AACA,UAAM,mBAAmB,MAAM,OAAO,yBAAyB,MAAM,IAAI;AACzE,QAAI,CAAC,iBAAiB,SAAS,cAAc,GAAG;AAO9C,YAAM,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,kBAAkB,cAAc,CAAC,CAAC;AACnE,YAAM,OAAO,cAAc,MAAM,MAAM,QAAQ;AAC/C,cAAQ,KAAK,aAAa,cAAc,cAAc,IAAI,EAAE;AAAA,IAC9D;AAaA,QAAK,MAAM,OAAO,eAAe,IAAI,MAAO,UAAU;AAgBpD,YAAM,QAAS,MAAM,OAAO,qBAAqB,MAAM,MAAM,cAAc,IACvE,iBACA;AACJ,YAAM,mBAAmB,MAAM,OAAO,iBAAiB,IAAI,GAAG;AAAA,QAC5D,CAAC,MAAM,EAAE,SAAS;AAAA,MACpB;AACA,UAAI,CAAC,iBAAiB;AACpB,cAAM,OAAO,cAAc,MAAM,eAAe,KAAK,CAAC;AACtD,gBAAQ;AAAA,UACN,UAAU,OACN,oBAAoB,kBAAkB,8BAAyB,cAAc,yBAAyB,IAAI,MAC1G,oBAAoB,kBAAkB;AAAA,QAC5C;AAAA,MACF,OAAO;AACL,cAAM,OAAO,MAAM,OAAO,WAAW,MAAM,gBAAgB,EAAE;AAC7D,cAAM,OAAO,YAAY,MAAM,KAAK;AACpC,YAAI,KAAK,SAAS,GAAG;AAInB,gBAAM,OAAO,cAAc,MAAM,gBAAgB,IAAI,YAAY,MAAM,KAAK,CAAC;AAC7E,kBAAQ,KAAK,yBAAyB,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EAOF,SAAS,KAAK;AACZ,UAAM,OAAO,QAAQ,SAAS,gBAAgB,QAAQ,KAAK,IAAI,CAAC,MAAM;AACtE,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO,SAAS,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,IAAI,OAAO;AAAA,EAC9D,UAAE;AAMA,QAAI,gBAAgB,QAAQ,aAAa,QAAQ,aAAa,aAAa;AACzE,UAAI;AACF,cAAM,eAAe,KAAK,MAAM,QAAQ;AAAA,MAC1C,SAAS,KAAK;AACZ,gBAAQ;AAAA,UACN,qCAAqC,QAAQ,yBAC3C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,SACX,SAAS,MAAM,WAAW,QAAQ,KAAK,IAAI,GAAG,OAAO,IACrD,SAAS,MAAM,QAAQ,yBAAyB,OAAO;AAC7D;","names":[]}
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./chunk-LKGVSM2O.js";
|
|
4
4
|
import {
|
|
5
5
|
readGitHubConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CGQZFQAY.js";
|
|
7
7
|
import {
|
|
8
8
|
assertUrlSegment
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-43SW3FGW.js";
|
|
10
10
|
import {
|
|
11
11
|
lighthouseAudit,
|
|
12
12
|
readSiteConfig
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BIYQN7FH.js";
|
|
14
14
|
import {
|
|
15
15
|
smokeAudit
|
|
16
16
|
} from "./chunk-UDRHAQT7.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
a11yRoutes,
|
|
31
31
|
smokeRoutes
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-CXICCLNM.js";
|
|
33
33
|
|
|
34
34
|
// src/audits/deps.ts
|
|
35
35
|
import { readFile } from "fs/promises";
|
|
@@ -247,6 +247,7 @@ function mapDependabotAlert(raw) {
|
|
|
247
247
|
const cveId = typeof adv["cve_id"] === "string" ? adv["cve_id"] : null;
|
|
248
248
|
const rawScope = dependency["scope"];
|
|
249
249
|
const rawRelationship = dependency["relationship"];
|
|
250
|
+
const rawManifest = dependency["manifest_path"];
|
|
250
251
|
return {
|
|
251
252
|
package: packageName,
|
|
252
253
|
severity: typeof adv["severity"] === "string" ? adv["severity"] : "",
|
|
@@ -254,7 +255,8 @@ function mapDependabotAlert(raw) {
|
|
|
254
255
|
cves: cveId ? [cveId] : [],
|
|
255
256
|
url: typeof raw["html_url"] === "string" ? raw["html_url"] : null,
|
|
256
257
|
scope: rawScope === "runtime" || rawScope === "development" ? rawScope : null,
|
|
257
|
-
relationship: rawRelationship === "direct" || rawRelationship === "transitive" ? rawRelationship : null
|
|
258
|
+
relationship: rawRelationship === "direct" || rawRelationship === "transitive" || rawRelationship === "inconclusive" ? rawRelationship : null,
|
|
259
|
+
manifestPath: typeof rawManifest === "string" && rawManifest ? rawManifest : null
|
|
258
260
|
};
|
|
259
261
|
}
|
|
260
262
|
function makeGitHubRest(deps) {
|
|
@@ -397,6 +399,23 @@ function makeGitHubRest(deps) {
|
|
|
397
399
|
url = nextLink(res.headers.get("link"));
|
|
398
400
|
}
|
|
399
401
|
return out;
|
|
402
|
+
},
|
|
403
|
+
async manifestExists(repo, path) {
|
|
404
|
+
const { owner, name } = splitRepo(repo);
|
|
405
|
+
assertUrlSegment("path", owner);
|
|
406
|
+
assertUrlSegment("path", name);
|
|
407
|
+
const encoded = path.split("/").map(encodeURIComponent).join("/");
|
|
408
|
+
const res = await doFetch(`${GITHUB_API}/repos/${owner}/${name}/contents/${encoded}`, {
|
|
409
|
+
headers: baseHeaders,
|
|
410
|
+
signal: AbortSignal.timeout(DEPENDABOT_FETCH_TIMEOUT_MS)
|
|
411
|
+
});
|
|
412
|
+
if (res.status === 404) return false;
|
|
413
|
+
if (!res.ok) {
|
|
414
|
+
throw new Error(
|
|
415
|
+
`GitHub GET contents/${path} ${owner}/${name} failed (${res.status}): ${await bodyText(res)}`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
return true;
|
|
400
419
|
}
|
|
401
420
|
};
|
|
402
421
|
}
|
|
@@ -497,7 +516,25 @@ function defaultDependabotDeps() {
|
|
|
497
516
|
const cfg = readGitHubConfig();
|
|
498
517
|
if (!cfg) return null;
|
|
499
518
|
const gh = makeGitHubRest({ token: cfg.token });
|
|
500
|
-
return {
|
|
519
|
+
return {
|
|
520
|
+
listAlerts: (repo) => gh.listDependabotAlerts(repo, { state: "open" }),
|
|
521
|
+
manifestExists: (repo, path) => gh.manifestExists(repo, path)
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
async function absentManifests(deps, repo, alerts, label) {
|
|
525
|
+
const absent = /* @__PURE__ */ new Set();
|
|
526
|
+
if (!deps.manifestExists) return absent;
|
|
527
|
+
const paths = new Set(alerts.flatMap((a) => a.manifestPath ? [a.manifestPath] : []));
|
|
528
|
+
for (const path of paths) {
|
|
529
|
+
try {
|
|
530
|
+
if (!await deps.manifestExists(repo, path)) absent.add(path);
|
|
531
|
+
} catch (e) {
|
|
532
|
+
console.error(
|
|
533
|
+
`[security] ${label}: could not resolve manifest ${path} \u2014 counting its alerts: ${e instanceof Error ? e.message : String(e)}`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return absent;
|
|
501
538
|
}
|
|
502
539
|
function ghSeverityToApp(s) {
|
|
503
540
|
if (s === "critical" || s === "high" || s === "low") return s;
|
|
@@ -514,12 +551,13 @@ async function dependabotAudit(deps, repo, label) {
|
|
|
514
551
|
);
|
|
515
552
|
return null;
|
|
516
553
|
}
|
|
554
|
+
const absent = await absentManifests(deps, repo, alerts, label);
|
|
517
555
|
const counts = { low: 0, moderate: 0, high: 0, critical: 0 };
|
|
518
556
|
const advisories = [];
|
|
557
|
+
const ghostAdvisories = [];
|
|
519
558
|
for (const a of alerts) {
|
|
520
559
|
const severity = ghSeverityToApp(a.severity);
|
|
521
|
-
|
|
522
|
-
advisories.push({
|
|
560
|
+
const entry = {
|
|
523
561
|
module: a.package,
|
|
524
562
|
severity,
|
|
525
563
|
title: a.summary || "(no title)",
|
|
@@ -527,12 +565,36 @@ async function dependabotAudit(deps, repo, label) {
|
|
|
527
565
|
...a.url ? { url: a.url } : {},
|
|
528
566
|
...a.scope ? { scope: a.scope } : {},
|
|
529
567
|
...a.relationship ? { relationship: a.relationship } : {}
|
|
530
|
-
}
|
|
568
|
+
};
|
|
569
|
+
if (a.manifestPath && absent.has(a.manifestPath)) {
|
|
570
|
+
ghostAdvisories.push({ ...entry, manifestPath: a.manifestPath });
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
counts[severity] += 1;
|
|
574
|
+
advisories.push(entry);
|
|
531
575
|
}
|
|
532
|
-
const
|
|
576
|
+
const liveStatus = classify(counts);
|
|
533
577
|
const total = counts.low + counts.moderate + counts.high + counts.critical;
|
|
534
|
-
const
|
|
535
|
-
|
|
578
|
+
const liveSummary = liveStatus === "pass" ? ghostAdvisories.length > 0 ? "Dependabot: 0 live alert(s)" : "Dependabot: 0 alerts" : `Dependabot: ${total} alert(s) (${counts.critical}C/${counts.high}H/${counts.moderate}M/${counts.low}L)`;
|
|
579
|
+
if (ghostAdvisories.length === 0) {
|
|
580
|
+
return {
|
|
581
|
+
audit: "security",
|
|
582
|
+
site: label,
|
|
583
|
+
status: liveStatus,
|
|
584
|
+
summary: liveSummary,
|
|
585
|
+
details: { counts, advisories }
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
const status = liveStatus === "pass" ? "warn" : liveStatus;
|
|
589
|
+
const manifests = [...new Set(ghostAdvisories.map((g) => g.manifestPath))].join(", ");
|
|
590
|
+
const summary = `${liveSummary}; ${ghostAdvisories.length} alert(s) on a manifest GitHub no longer tracks (${manifests}) \u2014 dismiss as inaccurate`;
|
|
591
|
+
return {
|
|
592
|
+
audit: "security",
|
|
593
|
+
site: label,
|
|
594
|
+
status,
|
|
595
|
+
summary,
|
|
596
|
+
details: { counts, advisories, ghostAdvisories }
|
|
597
|
+
};
|
|
536
598
|
}
|
|
537
599
|
async function securityAudit(ctx) {
|
|
538
600
|
const spawn = ctx.spawn ?? defaultSpawn;
|
|
@@ -600,7 +662,36 @@ async function readJsonMaybe(path) {
|
|
|
600
662
|
return null;
|
|
601
663
|
}
|
|
602
664
|
}
|
|
603
|
-
|
|
665
|
+
var DEV_SERVER_TIMEOUT_MS = 12e4;
|
|
666
|
+
var PREVIEW_SERVER_TIMEOUT_MS = 5 * 6e4;
|
|
667
|
+
var PLAYWRIGHT_TIMEOUT_MS = 5 * 6e4;
|
|
668
|
+
var PLAYWRIGHT_PREVIEW_TIMEOUT_MS = 10 * 6e4;
|
|
669
|
+
function webServerBlock(opts) {
|
|
670
|
+
return `{
|
|
671
|
+
command: ${JSON.stringify(opts.command)},
|
|
672
|
+
url: ${JSON.stringify(opts.url)},
|
|
673
|
+
cwd: ${JSON.stringify(opts.sitePath)},
|
|
674
|
+
reuseExistingServer: false,
|
|
675
|
+
timeout: ${opts.timeoutMs},
|
|
676
|
+
}`;
|
|
677
|
+
}
|
|
678
|
+
function buildPlaywrightConfig(port, sitePath, previewPort) {
|
|
679
|
+
const dev = webServerBlock({
|
|
680
|
+
command: `npm run vite:dev -- --port ${port} --strictPort`,
|
|
681
|
+
url: `http://localhost:${port}/dev/a11y-fixtures`,
|
|
682
|
+
sitePath,
|
|
683
|
+
timeoutMs: DEV_SERVER_TIMEOUT_MS
|
|
684
|
+
});
|
|
685
|
+
const preview = previewPort === void 0 ? void 0 : webServerBlock({
|
|
686
|
+
command: `npm run build && npm run preview -- --port ${previewPort} --strictPort`,
|
|
687
|
+
url: `http://localhost:${previewPort}/`,
|
|
688
|
+
sitePath,
|
|
689
|
+
timeoutMs: PREVIEW_SERVER_TIMEOUT_MS
|
|
690
|
+
});
|
|
691
|
+
const webServer = preview === void 0 ? dev : `[
|
|
692
|
+
${dev},
|
|
693
|
+
${preview},
|
|
694
|
+
]`;
|
|
604
695
|
return `import { defineConfig } from "@playwright/test";
|
|
605
696
|
|
|
606
697
|
export default defineConfig({
|
|
@@ -614,24 +705,18 @@ export default defineConfig({
|
|
|
614
705
|
baseURL: "http://localhost:${port}",
|
|
615
706
|
trace: "on-first-retry",
|
|
616
707
|
},
|
|
617
|
-
webServer: {
|
|
618
|
-
// --strictPort: refuse to bump to a different port if ours is taken,
|
|
619
|
-
// so the audit fails loudly instead of probing a zombie.
|
|
620
|
-
// reuseExistingServer:false: never reuse \u2014 we control the lifecycle.
|
|
621
|
-
// cwd: playwright's default webServer.cwd is the config file's
|
|
622
|
-
// directory. Our config lives in /tmp so without this override,
|
|
623
|
-
// "npm run vite:dev" tries to read /tmp/.../package.json and
|
|
624
|
-
// ENOENTs before vite ever starts. Caltex 2026-05-28 (0.10.5).
|
|
625
|
-
command: "npm run vite:dev -- --port ${port} --strictPort",
|
|
626
|
-
url: "http://localhost:${port}/dev/a11y-fixtures",
|
|
627
|
-
cwd: ${JSON.stringify(sitePath)},
|
|
628
|
-
reuseExistingServer: false,
|
|
629
|
-
timeout: 120_000,
|
|
630
|
-
},
|
|
708
|
+
webServer: ${webServer},
|
|
631
709
|
});
|
|
632
710
|
`;
|
|
633
711
|
}
|
|
634
|
-
function
|
|
712
|
+
async function allocateDistinctPort(taken) {
|
|
713
|
+
for (let attempt = 0; attempt < 5; attempt += 1) {
|
|
714
|
+
const candidate = await findFreePort();
|
|
715
|
+
if (candidate !== taken) return candidate;
|
|
716
|
+
}
|
|
717
|
+
throw new Error(`a11y: could not allocate a second free port distinct from ${taken}`);
|
|
718
|
+
}
|
|
719
|
+
function buildSpec(axePages, smokeOrigin = "") {
|
|
635
720
|
return `import { test, expect } from "@playwright/test";
|
|
636
721
|
import AxeBuilder from "@axe-core/playwright";
|
|
637
722
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
@@ -639,6 +724,13 @@ import { dirname } from "node:path";
|
|
|
639
724
|
|
|
640
725
|
const pages = ${JSON.stringify(axePages)};
|
|
641
726
|
const smokePages = ${JSON.stringify(smokeRoutes)};
|
|
727
|
+
// Absolute origin for the hydration smoke when the site has opted its gates
|
|
728
|
+
// onto a production build (#700). The axe loop runs against the dev server via
|
|
729
|
+
// baseURL; these routes run against the built bundle on a second port, and the
|
|
730
|
+
// origin has to be explicit or they would silently fall back to baseURL \u2014 i.e.
|
|
731
|
+
// to dev \u2014 and measure exactly what this exists to stop measuring. Empty string
|
|
732
|
+
// = one server for both, the default.
|
|
733
|
+
const SMOKE_ORIGIN = ${JSON.stringify(smokeOrigin)};
|
|
642
734
|
const OUTPUT = process.env.REDDOOR_A11Y_OUTPUT;
|
|
643
735
|
|
|
644
736
|
// Playwright's default per-test timeout is 30s. We loop through every
|
|
@@ -664,7 +756,23 @@ test("a11y + hydration across configured routes", async ({ page }) => {
|
|
|
664
756
|
|
|
665
757
|
for (const { path, name } of pages) {
|
|
666
758
|
currentRoute = name;
|
|
667
|
-
await page.goto(path);
|
|
759
|
+
const response = await page.goto(path);
|
|
760
|
+
// A route that does not exist is a config problem, not a markup one. The
|
|
761
|
+
// audit used to navigate, get a 404, run axe over whatever the error page
|
|
762
|
+
// was and report the count -- for months that page was a bare fallback with
|
|
763
|
+
// nothing to flag, so a missing fixture read as green. When reddoor-website
|
|
764
|
+
// gave its 404 page a designed watermark the count went to 1 with no route
|
|
765
|
+
// and no rule in the summary, and the "violation" was bisected as markup
|
|
766
|
+
// (#680). Name it as a missing route and do not scan the error page.
|
|
767
|
+
if (!response || response.status() !== 200) {
|
|
768
|
+
violations.push({
|
|
769
|
+
id: "route-missing",
|
|
770
|
+
impact: "serious",
|
|
771
|
+
route: name,
|
|
772
|
+
help: \`\${path} returned \${response ? response.status() : "no response"}\`,
|
|
773
|
+
});
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
668
776
|
// Snap CSS transitions/animations to their resting state before axe runs.
|
|
669
777
|
// AnimateIn-style fixtures transition opacity 0->1; sampling mid-transition
|
|
670
778
|
// makes axe compute color-contrast against semi-transparent text, yielding a
|
|
@@ -697,7 +805,7 @@ test("a11y + hydration across configured routes", async ({ page }) => {
|
|
|
697
805
|
// renders empty-but-valid won't false-fail -- only a real client crash does.
|
|
698
806
|
for (const { path, name } of smokePages) {
|
|
699
807
|
currentRoute = name;
|
|
700
|
-
await page.goto(path);
|
|
808
|
+
await page.goto(SMOKE_ORIGIN + path);
|
|
701
809
|
// Let hydration + first effects run so a TDZ/ReferenceError surfaces.
|
|
702
810
|
await page.waitForTimeout(2000);
|
|
703
811
|
}
|
|
@@ -717,22 +825,45 @@ test("a11y + hydration across configured routes", async ({ page }) => {
|
|
|
717
825
|
});
|
|
718
826
|
`;
|
|
719
827
|
}
|
|
828
|
+
var NAMED_VIOLATIONS_MAX = 6;
|
|
829
|
+
function describeViolations(violations) {
|
|
830
|
+
const groups = /* @__PURE__ */ new Map();
|
|
831
|
+
for (const v of violations) {
|
|
832
|
+
const key = `${v.id}\0${v.route}`;
|
|
833
|
+
const g = groups.get(key);
|
|
834
|
+
if (g) g.n += 1;
|
|
835
|
+
else groups.set(key, { id: v.id, route: v.route, ...v.help ? { help: v.help } : {}, n: 1 });
|
|
836
|
+
}
|
|
837
|
+
const entries = [...groups.values()];
|
|
838
|
+
const shown = entries.slice(0, NAMED_VIOLATIONS_MAX).map((g) => {
|
|
839
|
+
const count = g.n > 1 ? ` \xD7${g.n}` : "";
|
|
840
|
+
const detail = g.id === "route-missing" && g.help ? ` (${g.help})` : "";
|
|
841
|
+
return `${g.id}${count} on ${g.route}${detail}`;
|
|
842
|
+
});
|
|
843
|
+
const rest = entries.length - shown.length;
|
|
844
|
+
return shown.join(", ") + (rest > 0 ? `, +${rest} more` : "");
|
|
845
|
+
}
|
|
720
846
|
async function a11yAudit(ctx) {
|
|
721
847
|
const spawn = ctx.spawn ?? defaultSpawn;
|
|
722
848
|
const site = ctx.site;
|
|
723
849
|
const label = siteLabel(site);
|
|
724
850
|
const specDir = await mkdtemp(join4(site.path, ".reddoor-a11y-spec-"));
|
|
725
851
|
try {
|
|
726
|
-
const { a11yRoutes: siteRoutes } = await readSiteConfig(site.path);
|
|
852
|
+
const { a11yRoutes: siteRoutes, gateServer } = await readSiteConfig(site.path);
|
|
727
853
|
const axePages = [
|
|
728
854
|
...a11yRoutes,
|
|
729
855
|
...(siteRoutes ?? []).map((path) => ({ path, name: path }))
|
|
730
856
|
];
|
|
731
|
-
const specPath = join4(specDir, "a11y.spec.ts");
|
|
732
|
-
await writeFile(specPath, buildSpec(axePages), "utf-8");
|
|
733
857
|
const port = await findFreePort();
|
|
858
|
+
const previewPort = gateServer === "preview" ? await allocateDistinctPort(port) : void 0;
|
|
859
|
+
const specPath = join4(specDir, "a11y.spec.ts");
|
|
860
|
+
await writeFile(
|
|
861
|
+
specPath,
|
|
862
|
+
buildSpec(axePages, previewPort === void 0 ? "" : `http://localhost:${previewPort}`),
|
|
863
|
+
"utf-8"
|
|
864
|
+
);
|
|
734
865
|
const configPath = join4(specDir, "playwright.config.ts");
|
|
735
|
-
await writeFile(configPath, buildPlaywrightConfig(port, site.path), "utf-8");
|
|
866
|
+
await writeFile(configPath, buildPlaywrightConfig(port, site.path, previewPort), "utf-8");
|
|
736
867
|
const resultsPath = join4(site.path, RESULTS_REL);
|
|
737
868
|
await rm(join4(site.path, ".reddoor-a11y"), { recursive: true, force: true });
|
|
738
869
|
let raw;
|
|
@@ -747,7 +878,10 @@ async function a11yAudit(ctx) {
|
|
|
747
878
|
// server, and runs axe over every configured route. The shared 30 s
|
|
748
879
|
// default in runAudits is fine for deps/lint/security but starves
|
|
749
880
|
// playwright (mirrors the lighthouse fix shipped earlier).
|
|
750
|
-
|
|
881
|
+
// A preview run pays for a production build before the first
|
|
882
|
+
// navigation, so the budget sized for "boot vite, then axe" would
|
|
883
|
+
// SIGKILL it mid-build and report it as an audit failure.
|
|
884
|
+
timeoutMs: previewPort === void 0 ? PLAYWRIGHT_TIMEOUT_MS : PLAYWRIGHT_PREVIEW_TIMEOUT_MS
|
|
751
885
|
}
|
|
752
886
|
);
|
|
753
887
|
} catch (err) {
|
|
@@ -774,7 +908,11 @@ async function a11yAudit(ctx) {
|
|
|
774
908
|
const hasSerious = (artifact.byImpact.serious ?? 0) > 0 || (artifact.byImpact.critical ?? 0) > 0;
|
|
775
909
|
const hasAny = artifact.totalViolations > 0;
|
|
776
910
|
const status = hasSerious ? "fail" : hasAny ? "warn" : "pass";
|
|
777
|
-
const
|
|
911
|
+
const siteRouteCount = axePages.length - a11yRoutes.length;
|
|
912
|
+
const scanned = siteRouteCount > 0 ? `${axePages.length} routes (${a11yRoutes.length} fixtures + ${siteRouteCount} from package.json)` : `${axePages.length} routes`;
|
|
913
|
+
const smokeNote = previewPort === void 0 ? `+${smokeRoutes.length} hydration smoke` : `+${smokeRoutes.length} hydration smoke on a production preview`;
|
|
914
|
+
const named = describeViolations(artifact.violations ?? []);
|
|
915
|
+
const summary = status === "pass" ? `a11y: 0 violations across ${scanned} (${smokeNote})` : `a11y: ${artifact.totalViolations} violations across ${scanned}${named ? ` \u2014 ${named}` : ""}`;
|
|
778
916
|
return {
|
|
779
917
|
audit: "a11y",
|
|
780
918
|
site: label,
|
|
@@ -1659,6 +1797,7 @@ async function functionHealthAudit(ctx) {
|
|
|
1659
1797
|
// src/audits/form-e2e.ts
|
|
1660
1798
|
var CF_TEST_SITEKEY = "1x00000000000000000000AA";
|
|
1661
1799
|
var CONTACT_PATHS = ["/contact", "/"];
|
|
1800
|
+
var FORM_E2E_TESTMODE_UNDECLARED_SUMMARY = "site /health does not declare forms.testMode \u2014 probe refused (testMode forwarding not yet rolled out here)";
|
|
1662
1801
|
var TESTMODE_SKIPPED_WORK_MS = 1e3;
|
|
1663
1802
|
var BUDGET_WARN_RATIO = 0.5;
|
|
1664
1803
|
function projectRealSubmissionMs(probeElapsedMs) {
|
|
@@ -1674,7 +1813,7 @@ function budgetThinSummary(probeElapsedMs) {
|
|
|
1674
1813
|
var TURNSTILE_HOSTNAME_REJECTED = /\[Cloudflare Turnstile\][^\n]*?\b110200\b/;
|
|
1675
1814
|
var TURNSTILE_WIDGET_ERROR = /\[Cloudflare Turnstile\][^\n]*?\b(?:110(?!200\b)\d{3}|400020|400070)\b/;
|
|
1676
1815
|
var TURNSTILE_INIT_FAILED = /\[turnstile\] widget did not render/;
|
|
1677
|
-
var TURNSTILE_API_JS = /challenges\.cloudflare\.com\/turnstile\/v0\/api\.js/;
|
|
1816
|
+
var TURNSTILE_API_JS = /challenges\.cloudflare\.com\/turnstile\/v0\/(?:[\w.-]+\/)*api\.js/;
|
|
1678
1817
|
function turnstileVerdict(health, observed) {
|
|
1679
1818
|
if (health.turnstile === false) return "fail";
|
|
1680
1819
|
if (!observed) return null;
|
|
@@ -1716,7 +1855,7 @@ async function formE2eAudit(ctx) {
|
|
|
1716
1855
|
audit: "form-e2e",
|
|
1717
1856
|
site: label,
|
|
1718
1857
|
status: "skip",
|
|
1719
|
-
summary:
|
|
1858
|
+
summary: FORM_E2E_TESTMODE_UNDECLARED_SUMMARY,
|
|
1720
1859
|
details: { checkedAt, turnstileWidget: null }
|
|
1721
1860
|
};
|
|
1722
1861
|
}
|
|
@@ -2056,4 +2195,4 @@ export {
|
|
|
2056
2195
|
runAudits,
|
|
2057
2196
|
runAuditsAcross
|
|
2058
2197
|
};
|
|
2059
|
-
//# sourceMappingURL=chunk-
|
|
2198
|
+
//# sourceMappingURL=chunk-XY7YV2YQ.js.map
|