@reddoorla/maintenance 0.85.2 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/airtable-ZBUPQJSC.js +9 -0
- package/dist/{announce-GIAYN67S.js → announce-I2Z4JN3I.js} +58 -30
- package/dist/announce-I2Z4JN3I.js.map +1 -0
- package/dist/attachments-NLZIJ5NU.js +9 -0
- package/dist/{bump-deps-SWJB6H5V.js → bump-deps-CGVELRLK.js} +9 -9
- package/dist/{chunk-SDUJIANJ.js → chunk-2NJQLSEU.js} +3 -3
- package/dist/chunk-2NQUCS7O.js +243 -0
- package/dist/chunk-2NQUCS7O.js.map +1 -0
- package/dist/{chunk-ZTPPCHDB.js → chunk-3G25KIWW.js} +4 -4
- package/dist/{chunk-DTTIFYAM.js → chunk-3JQ2FO3D.js} +44 -405
- package/dist/chunk-3JQ2FO3D.js.map +1 -0
- package/dist/chunk-3SF7D4DY.js +359 -0
- package/dist/chunk-3SF7D4DY.js.map +1 -0
- package/dist/{chunk-37S6L6G4.js → chunk-5UINJNAJ.js} +72 -2
- package/dist/chunk-5UINJNAJ.js.map +1 -0
- package/dist/{chunk-THEFTZ7F.js → chunk-62CMMGEO.js} +5 -5
- package/dist/{chunk-FDIFTIXC.js → chunk-6TWWY7ZU.js} +2 -2
- package/dist/{chunk-PBWDDDQH.js → chunk-7BZUOZPU.js} +2 -2
- package/dist/{chunk-577HCGZO.js → chunk-7NYN2P6I.js} +44 -26
- package/dist/chunk-7NYN2P6I.js.map +1 -0
- package/dist/{chunk-UYCAF77E.js → chunk-7RJ2HMMJ.js} +3 -3
- package/dist/{chunk-Q276MZ7E.js → chunk-7UAYMAKR.js} +2 -2
- package/dist/{chunk-MGR2H7F4.js → chunk-BBUSGEES.js} +58 -45
- package/dist/chunk-BBUSGEES.js.map +1 -0
- package/dist/chunk-BNM5POSJ.js +284 -0
- package/dist/chunk-BNM5POSJ.js.map +1 -0
- package/dist/{chunk-R6FPFMOS.js → chunk-BQRFQSGY.js} +3 -3
- package/dist/{chunk-NWB4O5EY.js → chunk-C6CLRKPV.js} +5 -5
- package/dist/chunk-C6CLRKPV.js.map +1 -0
- package/dist/{chunk-7J53SUT6.js → chunk-CROKUHJB.js} +4 -4
- package/dist/chunk-DEWJMMG3.js +274 -0
- package/dist/chunk-DEWJMMG3.js.map +1 -0
- package/dist/{chunk-SEEA6RXF.js → chunk-DJZWYIPP.js} +2 -2
- package/dist/chunk-DJZWYIPP.js.map +1 -0
- package/dist/chunk-EVBCK2KC.js +68 -0
- package/dist/chunk-EVBCK2KC.js.map +1 -0
- package/dist/chunk-F3JWOPTG.js +202 -0
- package/dist/chunk-F3JWOPTG.js.map +1 -0
- package/dist/{chunk-GZNBCHAZ.js → chunk-HEWSRXYV.js} +4 -4
- package/dist/chunk-HHMMUR4P.js +335 -0
- package/dist/chunk-HHMMUR4P.js.map +1 -0
- package/dist/chunk-HSI6Q7MI.js +1238 -0
- package/dist/chunk-HSI6Q7MI.js.map +1 -0
- package/dist/{chunk-MPBXOJ3N.js → chunk-IY6256GK.js} +33 -2
- package/dist/chunk-IY6256GK.js.map +1 -0
- package/dist/{chunk-LS6QPANO.js → chunk-IYSEC543.js} +2 -2
- package/dist/{chunk-DC5H7KEQ.js → chunk-JHGHLKFS.js} +2 -2
- package/dist/{chunk-4DHQCN5H.js → chunk-LBYOLBW7.js} +17 -2
- package/dist/chunk-LBYOLBW7.js.map +1 -0
- package/dist/{chunk-6QRLRT3P.js → chunk-MT2JINSS.js} +16 -265
- package/dist/chunk-MT2JINSS.js.map +1 -0
- package/dist/{chunk-TP5M2NQB.js → chunk-NCMZMLY7.js} +3 -3
- package/dist/{chunk-COZPL62X.js → chunk-NDWYJLRF.js} +24 -139
- package/dist/chunk-NDWYJLRF.js.map +1 -0
- package/dist/{chunk-3YXDSCM6.js → chunk-NXNPDCF3.js} +29 -11
- package/dist/chunk-NXNPDCF3.js.map +1 -0
- package/dist/chunk-NYUYNYQL.js +48 -0
- package/dist/chunk-NYUYNYQL.js.map +1 -0
- package/dist/chunk-P6AORG32.js +415 -0
- package/dist/chunk-P6AORG32.js.map +1 -0
- package/dist/chunk-PTDMVGKL.js +31 -0
- package/dist/chunk-PTDMVGKL.js.map +1 -0
- package/dist/{chunk-D4FVAIEJ.js → chunk-PZR4EBPY.js} +5 -2
- package/dist/chunk-PZR4EBPY.js.map +1 -0
- package/dist/{chunk-LTB6KVJW.js → chunk-SDDPUAWH.js} +13 -11
- package/dist/{chunk-LTB6KVJW.js.map → chunk-SDDPUAWH.js.map} +1 -1
- package/dist/{chunk-WYYQK4D3.js → chunk-TD2NNXLZ.js} +13 -13
- package/dist/{chunk-ZMIPG6TR.js → chunk-TVL5MVUF.js} +4 -4
- package/dist/chunk-UDRHAQT7.js +172 -0
- package/dist/chunk-UDRHAQT7.js.map +1 -0
- package/dist/chunk-VAD43MOR.js +72 -0
- package/dist/chunk-VAD43MOR.js.map +1 -0
- package/dist/chunk-VSBFM7DS.js +229 -0
- package/dist/chunk-VSBFM7DS.js.map +1 -0
- package/dist/{chunk-VRWUL4TR.js → chunk-XHHMM5HX.js} +2 -2
- package/dist/{chunk-RJB3QUSP.js → chunk-XIDUYLSR.js} +3 -3
- package/dist/{chunk-QG6OSL4M.js → chunk-XUGSZP7Z.js} +2 -2
- package/dist/{chunk-S56JQJ4F.js → chunk-Y53WOQIJ.js} +3 -3
- package/dist/{chunk-62VF32IC.js → chunk-YFAXOD7Z.js} +10 -6
- package/dist/chunk-YFAXOD7Z.js.map +1 -0
- package/dist/{chunk-ICXV25N7.js → chunk-Z3KYFUN6.js} +3 -3
- package/dist/chunk-ZBDZTJUO.js +129 -0
- package/dist/chunk-ZBDZTJUO.js.map +1 -0
- package/dist/chunk-ZGBEIWSC.js +146 -0
- package/dist/chunk-ZGBEIWSC.js.map +1 -0
- package/dist/cli/bin.js +51 -28
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +30 -1
- package/dist/cli/commands/audit.js +69 -33
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/client-AUE3XUPO.js +11 -0
- package/dist/{convert-to-pnpm-AT52NWZB.js → convert-to-pnpm-QFJOEP5V.js} +9 -9
- package/dist/db-UXNIZ2RG.js +217 -0
- package/dist/db-UXNIZ2RG.js.map +1 -0
- package/dist/{digest-UVHYZUYE.js → digest-FW6QMZZJ.js} +26 -22
- package/dist/{digest-UVHYZUYE.js.map → digest-FW6QMZZJ.js.map} +1 -1
- package/dist/dump-P6EBSIOH.js +68 -0
- package/dist/dump-P6EBSIOH.js.map +1 -0
- package/dist/email-KJXASVH5.js +195 -0
- package/dist/email-KJXASVH5.js.map +1 -0
- package/dist/{ensure-site-S25MDDHW.js → ensure-site-4DCEBAPM.js} +25 -16
- package/dist/ensure-site-4DCEBAPM.js.map +1 -0
- package/dist/fleet-events-cF2Om88w.d.ts +24 -0
- package/dist/fleet-state-7TJ2GYT2.js +39 -0
- package/dist/{forms-notify-target-TWN4EH6K.js → forms-notify-target-2EAWCWBW.js} +42 -133
- package/dist/forms-notify-target-2EAWCWBW.js.map +1 -0
- package/dist/{github-signals-G4ILZAJ6.js → github-signals-E2WPYTBK.js} +42 -21
- package/dist/github-signals-E2WPYTBK.js.map +1 -0
- package/dist/{header-image-T7XD37JL.js → header-image-6IC53W27.js} +36 -13
- package/dist/header-image-6IC53W27.js.map +1 -0
- package/dist/header-images-SQBCE5OD.js +88 -0
- package/dist/header-images-SQBCE5OD.js.map +1 -0
- package/dist/{health-endpoint-242WG2OJ.js → health-endpoint-RFXL2F4A.js} +9 -9
- package/dist/health-mirror-L5JBEJVA.js +41 -0
- package/dist/health-mirror-L5JBEJVA.js.map +1 -0
- package/dist/import-airtable-OHVY344G.js +37 -0
- package/dist/index.d.ts +324 -21
- package/dist/index.js +215 -76
- package/dist/index.js.map +1 -1
- package/dist/{init-JN26NTWF.js → init-XRAQZYID.js} +21 -18
- package/dist/{init-JN26NTWF.js.map → init-XRAQZYID.js.map} +1 -1
- package/dist/{launch-JA7Z4CIM.js → launch-IX4Y5JJC.js} +65 -30
- package/dist/launch-IX4Y5JJC.js.map +1 -0
- package/dist/lighthouse-VHI77PFB.js +11 -0
- package/dist/{lighthouse-airtable-BIPM26SZ.js → lighthouse-airtable-3GUWHETW.js} +3 -3
- package/dist/mailchimp-XYCTEEJY.js +72 -0
- package/dist/mailchimp-XYCTEEJY.js.map +1 -0
- package/dist/migrate-GQH237A6.js +7 -0
- package/dist/migrate-GQH237A6.js.map +1 -0
- package/dist/notify-C645PGD5.js +22 -0
- package/dist/notify-C645PGD5.js.map +1 -0
- package/dist/{onboard-53CITIM7.js → onboard-O4IAHJMO.js} +9 -9
- package/dist/orchestrate-YLWQ6KK2.js +31 -0
- package/dist/orchestrate-YLWQ6KK2.js.map +1 -0
- package/dist/parity-56KA2DGR.js +12 -0
- package/dist/parity-56KA2DGR.js.map +1 -0
- package/dist/pipeline-3AANZFCR.js +12 -0
- package/dist/pipeline-3AANZFCR.js.map +1 -0
- package/dist/{preflight-3XPDUHFJ.js → preflight-TNORKGCX.js} +17 -13
- package/dist/{preflight-3XPDUHFJ.js.map → preflight-TNORKGCX.js.map} +1 -1
- package/dist/{prismic-ci-UTQ6LRR3.js → prismic-ci-G2AK53VL.js} +12 -12
- package/dist/{prismic-models-PVES6R5V.js → prismic-models-O6Z3OK3A.js} +18 -13
- package/dist/prismic-models-O6Z3OK3A.js.map +1 -0
- package/dist/prospect/types.d.ts +267 -0
- package/dist/prospect/types.js +1 -0
- package/dist/prospect/types.js.map +1 -0
- package/dist/prospect-audit-KSXUNQ5J.js +174 -0
- package/dist/prospect-audit-KSXUNQ5J.js.map +1 -0
- package/dist/prospect-audits-3PMIO73D.js +19 -0
- package/dist/prospect-audits-3PMIO73D.js.map +1 -0
- package/dist/{protection-audit-64PLLBLI.js → protection-audit-SJO53MEQ.js} +3 -3
- package/dist/recipes/sync-configs.js +3 -3
- package/dist/render-IFOGFB5T.js +10 -0
- package/dist/render-IFOGFB5T.js.map +1 -0
- package/dist/render-from-row-BWSOIYDS.js +17 -0
- package/dist/render-from-row-BWSOIYDS.js.map +1 -0
- package/dist/{renovate-dispatch-ICJGSFCE.js → renovate-dispatch-6GQWTRKX.js} +12 -12
- package/dist/{renovate-dispatch-ICJGSFCE.js.map → renovate-dispatch-6GQWTRKX.js.map} +1 -1
- package/dist/replay-C2LXMJZP.js +66 -0
- package/dist/replay-C2LXMJZP.js.map +1 -0
- package/dist/{report-6CKSWJNG.js → report-R3E3Y7HR.js} +100 -32
- package/dist/report-R3E3Y7HR.js.map +1 -0
- package/dist/report-mirror-4MNORYQ4.js +49 -0
- package/dist/report-mirror-4MNORYQ4.js.map +1 -0
- package/dist/reports/header-image/assets/headline-announcement.png +0 -0
- package/dist/reports/header-image/assets/headline-launch.png +0 -0
- package/dist/reports/header-image/assets/headline-maintenance.png +0 -0
- package/dist/reports/header-image/assets/headline-testing.png +0 -0
- package/dist/reports/header-image/assets/plate-clean.png +0 -0
- package/dist/rerender-3FM6DNRH.js +32 -0
- package/dist/rerender-3FM6DNRH.js.map +1 -0
- package/dist/{self-updating-PPQVV6UA.js → self-updating-UCIWESAX.js} +9 -9
- package/dist/{selftest-CQ6NOX52.js → selftest-VGHWPN72.js} +31 -24
- package/dist/selftest-VGHWPN72.js.map +1 -0
- package/dist/site-mirror-NIREX5ME.js +52 -0
- package/dist/site-mirror-NIREX5ME.js.map +1 -0
- package/dist/smoke-B2GQOSIZ.js +20 -0
- package/dist/smoke-B2GQOSIZ.js.map +1 -0
- package/dist/{smoke-suite-TMCSOYRK.js → smoke-suite-U3UKD3NS.js} +9 -9
- package/dist/{submissions-GJ6ITBRH.js → submissions-IQEJX6FK.js} +3 -3
- package/dist/{svelte-codemods-ZOBDHIES.js → svelte-codemods-GOKXTBHW.js} +9 -9
- package/dist/sync-CTUVXMCK.js +44 -0
- package/dist/sync-CTUVXMCK.js.map +1 -0
- package/dist/{sync-configs-CJXUX6MD.js → sync-configs-SPTLFJCC.js} +9 -9
- package/dist/{upgrade-WLX27UPC.js → upgrade-W6ZR3FJH.js} +9 -9
- package/dist/webhook-VOGOW3W6.js +38 -0
- package/dist/webhook-VOGOW3W6.js.map +1 -0
- package/dist/{websites-SADZR4XQ.js → websites-D6WYFAES.js} +6 -2
- package/dist/websites-D6WYFAES.js.map +1 -0
- package/dist/{write-audits-to-airtable-7PH75YWY.js → write-audits-to-airtable-CMKHGJNQ.js} +4 -4
- package/dist/write-audits-to-airtable-CMKHGJNQ.js.map +1 -0
- package/package.json +9 -2
- package/dist/airtable-HRKSA7V4.js +0 -9
- package/dist/announce-GIAYN67S.js.map +0 -1
- package/dist/chunk-37S6L6G4.js.map +0 -1
- package/dist/chunk-3YXDSCM6.js.map +0 -1
- package/dist/chunk-4DHQCN5H.js.map +0 -1
- package/dist/chunk-4SOCPK7A.js +0 -108
- package/dist/chunk-4SOCPK7A.js.map +0 -1
- package/dist/chunk-577HCGZO.js.map +0 -1
- package/dist/chunk-62VF32IC.js.map +0 -1
- package/dist/chunk-6QRLRT3P.js.map +0 -1
- package/dist/chunk-COZPL62X.js.map +0 -1
- package/dist/chunk-D4FVAIEJ.js.map +0 -1
- package/dist/chunk-DTTIFYAM.js.map +0 -1
- package/dist/chunk-MGR2H7F4.js.map +0 -1
- package/dist/chunk-MPBXOJ3N.js.map +0 -1
- package/dist/chunk-NWB4O5EY.js.map +0 -1
- package/dist/chunk-SEEA6RXF.js.map +0 -1
- package/dist/chunk-U5SZ4FOP.js +0 -26
- package/dist/chunk-U5SZ4FOP.js.map +0 -1
- package/dist/client-X5WUJWDE.js +0 -11
- package/dist/db-JSIZYT23.js +0 -23
- package/dist/db-JSIZYT23.js.map +0 -1
- package/dist/ensure-site-S25MDDHW.js.map +0 -1
- package/dist/forms-notify-target-TWN4EH6K.js.map +0 -1
- package/dist/github-signals-G4ILZAJ6.js.map +0 -1
- package/dist/header-image-T7XD37JL.js.map +0 -1
- package/dist/launch-JA7Z4CIM.js.map +0 -1
- package/dist/migrate-LJUFGXQZ.js +0 -7
- package/dist/orchestrate-KDNXZQX7.js +0 -27
- package/dist/prismic-models-PVES6R5V.js.map +0 -1
- package/dist/report-6CKSWJNG.js.map +0 -1
- package/dist/reports/header-image/assets/plate.png +0 -0
- package/dist/selftest-CQ6NOX52.js.map +0 -1
- /package/dist/{airtable-HRKSA7V4.js.map → airtable-ZBUPQJSC.js.map} +0 -0
- /package/dist/{client-X5WUJWDE.js.map → attachments-NLZIJ5NU.js.map} +0 -0
- /package/dist/{bump-deps-SWJB6H5V.js.map → bump-deps-CGVELRLK.js.map} +0 -0
- /package/dist/{chunk-SDUJIANJ.js.map → chunk-2NJQLSEU.js.map} +0 -0
- /package/dist/{chunk-ZTPPCHDB.js.map → chunk-3G25KIWW.js.map} +0 -0
- /package/dist/{chunk-THEFTZ7F.js.map → chunk-62CMMGEO.js.map} +0 -0
- /package/dist/{chunk-FDIFTIXC.js.map → chunk-6TWWY7ZU.js.map} +0 -0
- /package/dist/{chunk-PBWDDDQH.js.map → chunk-7BZUOZPU.js.map} +0 -0
- /package/dist/{chunk-UYCAF77E.js.map → chunk-7RJ2HMMJ.js.map} +0 -0
- /package/dist/{chunk-Q276MZ7E.js.map → chunk-7UAYMAKR.js.map} +0 -0
- /package/dist/{chunk-R6FPFMOS.js.map → chunk-BQRFQSGY.js.map} +0 -0
- /package/dist/{chunk-7J53SUT6.js.map → chunk-CROKUHJB.js.map} +0 -0
- /package/dist/{chunk-GZNBCHAZ.js.map → chunk-HEWSRXYV.js.map} +0 -0
- /package/dist/{chunk-LS6QPANO.js.map → chunk-IYSEC543.js.map} +0 -0
- /package/dist/{chunk-DC5H7KEQ.js.map → chunk-JHGHLKFS.js.map} +0 -0
- /package/dist/{chunk-TP5M2NQB.js.map → chunk-NCMZMLY7.js.map} +0 -0
- /package/dist/{chunk-WYYQK4D3.js.map → chunk-TD2NNXLZ.js.map} +0 -0
- /package/dist/{chunk-ZMIPG6TR.js.map → chunk-TVL5MVUF.js.map} +0 -0
- /package/dist/{chunk-VRWUL4TR.js.map → chunk-XHHMM5HX.js.map} +0 -0
- /package/dist/{chunk-RJB3QUSP.js.map → chunk-XIDUYLSR.js.map} +0 -0
- /package/dist/{chunk-QG6OSL4M.js.map → chunk-XUGSZP7Z.js.map} +0 -0
- /package/dist/{chunk-S56JQJ4F.js.map → chunk-Y53WOQIJ.js.map} +0 -0
- /package/dist/{chunk-ICXV25N7.js.map → chunk-Z3KYFUN6.js.map} +0 -0
- /package/dist/{lighthouse-airtable-BIPM26SZ.js.map → client-AUE3XUPO.js.map} +0 -0
- /package/dist/{convert-to-pnpm-AT52NWZB.js.map → convert-to-pnpm-QFJOEP5V.js.map} +0 -0
- /package/dist/{migrate-LJUFGXQZ.js.map → fleet-state-7TJ2GYT2.js.map} +0 -0
- /package/dist/{health-endpoint-242WG2OJ.js.map → health-endpoint-RFXL2F4A.js.map} +0 -0
- /package/dist/{orchestrate-KDNXZQX7.js.map → import-airtable-OHVY344G.js.map} +0 -0
- /package/dist/{websites-SADZR4XQ.js.map → lighthouse-VHI77PFB.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-7PH75YWY.js.map → lighthouse-airtable-3GUWHETW.js.map} +0 -0
- /package/dist/{onboard-53CITIM7.js.map → onboard-O4IAHJMO.js.map} +0 -0
- /package/dist/{prismic-ci-UTQ6LRR3.js.map → prismic-ci-G2AK53VL.js.map} +0 -0
- /package/dist/{protection-audit-64PLLBLI.js.map → protection-audit-SJO53MEQ.js.map} +0 -0
- /package/dist/{self-updating-PPQVV6UA.js.map → self-updating-UCIWESAX.js.map} +0 -0
- /package/dist/{smoke-suite-TMCSOYRK.js.map → smoke-suite-U3UKD3NS.js.map} +0 -0
- /package/dist/{submissions-GJ6ITBRH.js.map → submissions-IQEJX6FK.js.map} +0 -0
- /package/dist/{svelte-codemods-ZOBDHIES.js.map → svelte-codemods-GOKXTBHW.js.map} +0 -0
- /package/dist/{sync-configs-CJXUX6MD.js.map → sync-configs-SPTLFJCC.js.map} +0 -0
- /package/dist/{upgrade-WLX27UPC.js.map → upgrade-W6ZR3FJH.js.map} +0 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { a as AuditResult } from '../types-OIQZ5hWN.js';
|
|
2
|
+
|
|
3
|
+
/** Every pipeline stage resolves to this. A failed stage degrades its report
|
|
4
|
+
* section to "not measured" — it never kills the run (spec: error handling). */
|
|
5
|
+
type StageResult<T> = {
|
|
6
|
+
ok: true;
|
|
7
|
+
data: T;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: string;
|
|
11
|
+
};
|
|
12
|
+
type RobotsAgentAccess = {
|
|
13
|
+
agent: string;
|
|
14
|
+
/** May this agent fetch "/" per robots.txt? (No robots.txt → allowed.) */
|
|
15
|
+
allowed: boolean;
|
|
16
|
+
/** The deciding rule, e.g. "User-agent: GPTBot → Disallow: /". Null = no rule matched. */
|
|
17
|
+
matchedRule: string | null;
|
|
18
|
+
};
|
|
19
|
+
type PageExtract = {
|
|
20
|
+
title: string | null;
|
|
21
|
+
metaDescription: string | null;
|
|
22
|
+
canonical: string | null;
|
|
23
|
+
/** property/name → content for og:* and twitter:* metas. */
|
|
24
|
+
social: Record<string, string>;
|
|
25
|
+
/** `level` is 1-6 (H1-H6). */
|
|
26
|
+
headings: {
|
|
27
|
+
level: number;
|
|
28
|
+
text: string;
|
|
29
|
+
}[];
|
|
30
|
+
/** Raw text of each <script type="application/ld+json"> block. */
|
|
31
|
+
jsonLd: string[];
|
|
32
|
+
images: {
|
|
33
|
+
total: number;
|
|
34
|
+
withAlt: number;
|
|
35
|
+
};
|
|
36
|
+
hasViewportMeta: boolean;
|
|
37
|
+
/** Visible text, whitespace-collapsed. */
|
|
38
|
+
text: string;
|
|
39
|
+
};
|
|
40
|
+
type PageCapture = {
|
|
41
|
+
url: string;
|
|
42
|
+
/** HTTP status of the raw fetch. Null = the fetch itself failed. */
|
|
43
|
+
status: number | null;
|
|
44
|
+
/** Extract of the raw HTTP HTML (what non-JS crawlers see). */
|
|
45
|
+
raw: PageExtract | null;
|
|
46
|
+
/** Extract of the Playwright-rendered DOM (what a browser sees). */
|
|
47
|
+
rendered: PageExtract | null;
|
|
48
|
+
error: string | null;
|
|
49
|
+
};
|
|
50
|
+
type CrawlResult = {
|
|
51
|
+
/** Normalized origin, e.g. "https://example.com". */
|
|
52
|
+
origin: string;
|
|
53
|
+
robotsTxt: string | null;
|
|
54
|
+
/** One entry per agent in crawl.ts's ALL_AGENTS (6 AI + 2 classical). */
|
|
55
|
+
agentAccess: RobotsAgentAccess[];
|
|
56
|
+
sitemap: {
|
|
57
|
+
present: boolean;
|
|
58
|
+
urlCount: number;
|
|
59
|
+
};
|
|
60
|
+
llmsTxt: {
|
|
61
|
+
present: boolean;
|
|
62
|
+
firstLine: string | null;
|
|
63
|
+
};
|
|
64
|
+
/** Per sidecar, the error that stopped us fetching it, or null. A fetch that
|
|
65
|
+
* FAILED must never be reported as "the site has no robots.txt" — that would
|
|
66
|
+
* claim the crawlers are unrestricted when we simply did not look. */
|
|
67
|
+
sidecarErrors: {
|
|
68
|
+
robots: string | null;
|
|
69
|
+
llms: string | null;
|
|
70
|
+
sitemap: string | null;
|
|
71
|
+
};
|
|
72
|
+
/** Lower-cased homepage response headers (security-header check input). */
|
|
73
|
+
homeHeaders: Record<string, string>;
|
|
74
|
+
pages: PageCapture[];
|
|
75
|
+
};
|
|
76
|
+
type ChecksResult = {
|
|
77
|
+
/** False when the robots.txt fetch itself failed, so "no AI crawler is
|
|
78
|
+
* blocked" would be our silence rather than the site's answer. The report
|
|
79
|
+
* must say "not measured" for crawler access when this is false. */
|
|
80
|
+
crawlerAccessMeasured: boolean;
|
|
81
|
+
crawlerAccess: {
|
|
82
|
+
blockedAi: string[];
|
|
83
|
+
allowedAi: string[];
|
|
84
|
+
blockedClassical: string[];
|
|
85
|
+
};
|
|
86
|
+
jsDependence: {
|
|
87
|
+
/** 0..1 — fraction of rendered words absent from the raw HTML, weighted by
|
|
88
|
+
* page size (total missing words / total rendered words across every
|
|
89
|
+
* comparable page) — or null when no page produced a comparable pair.
|
|
90
|
+
* Never 0 for "nothing measured": a page whose raw fetch was blocked, or
|
|
91
|
+
* whose rendered text tokenizes to nothing, drops out of the average
|
|
92
|
+
* rather than forcing it toward a false "perfectly crawlable". */
|
|
93
|
+
avgMissing: number | null;
|
|
94
|
+
perPage: {
|
|
95
|
+
url: string;
|
|
96
|
+
/** 0..1 — this page's own missing fraction (unweighted). */
|
|
97
|
+
missing: number;
|
|
98
|
+
/** Token count wordSet(rendered.text) produced for this page — the
|
|
99
|
+
* weight avgMissing gives it, and why a "coming soon" stub can't swing
|
|
100
|
+
* the headline number the way a full page does. */
|
|
101
|
+
renderedWords: number;
|
|
102
|
+
}[];
|
|
103
|
+
};
|
|
104
|
+
schema: {
|
|
105
|
+
typesFound: string[];
|
|
106
|
+
missingExpected: string[];
|
|
107
|
+
invalidBlocks: number;
|
|
108
|
+
};
|
|
109
|
+
meta: {
|
|
110
|
+
pageCount: number;
|
|
111
|
+
missingTitle: number;
|
|
112
|
+
missingDescription: number;
|
|
113
|
+
missingCanonical: number;
|
|
114
|
+
missingSocial: number;
|
|
115
|
+
/** Pages where neither the raw nor the rendered fetch produced an extract
|
|
116
|
+
* — excluded from pageCount and every other meta denominator above, so a
|
|
117
|
+
* report reading "1 of 2 pages missing a description" doesn't silently
|
|
118
|
+
* hide the third page that produced nothing at all. */
|
|
119
|
+
pagesWithoutExtract: number;
|
|
120
|
+
};
|
|
121
|
+
headings: {
|
|
122
|
+
pagesWithoutH1: number;
|
|
123
|
+
pagesWithLevelSkips: number;
|
|
124
|
+
};
|
|
125
|
+
securityHeaders: {
|
|
126
|
+
present: string[];
|
|
127
|
+
missing: string[];
|
|
128
|
+
};
|
|
129
|
+
/** False when the sitemap.xml fetch itself failed (crawl.sidecarErrors.sitemap
|
|
130
|
+
* !== null), so `sitemapPresent: false` would otherwise read as "confirmed
|
|
131
|
+
* absent" rather than "we never got an answer". The report must say "not
|
|
132
|
+
* measured" for sitemap presence when this is false, and computeScores must
|
|
133
|
+
* treat it as neutral rather than penalizing the technical component for a
|
|
134
|
+
* fetch we could not complete. */
|
|
135
|
+
sitemapMeasured: boolean;
|
|
136
|
+
sitemapPresent: boolean;
|
|
137
|
+
/** Same as sitemapMeasured, for the llms.txt fetch (crawl.sidecarErrors.llms). */
|
|
138
|
+
llmsTxtMeasured: boolean;
|
|
139
|
+
llmsTxtPresent: boolean;
|
|
140
|
+
viewportOk: boolean;
|
|
141
|
+
};
|
|
142
|
+
type BuyerQuestion = {
|
|
143
|
+
question: string;
|
|
144
|
+
answered: "yes" | "partial" | "no";
|
|
145
|
+
/** Is there a passage an AI answer could quote verbatim? */
|
|
146
|
+
quotable: boolean;
|
|
147
|
+
page: string | null;
|
|
148
|
+
evidence: string | null;
|
|
149
|
+
};
|
|
150
|
+
type Fix = {
|
|
151
|
+
title: string;
|
|
152
|
+
why: string;
|
|
153
|
+
impact: "high" | "medium" | "low";
|
|
154
|
+
effort: "low" | "medium" | "high";
|
|
155
|
+
tier: "crawl" | "content" | "technical";
|
|
156
|
+
};
|
|
157
|
+
type AnalyzeResult = {
|
|
158
|
+
/** The business's proper name, as a searchable proper noun — "Acme Roofing",
|
|
159
|
+
* not a description of it. Empty string when the site never states one,
|
|
160
|
+
* which is itself a finding. This is what the visibility probes query and
|
|
161
|
+
* brand-match against; `business` below is prose and unsearchable. */
|
|
162
|
+
businessName: string;
|
|
163
|
+
/** The model's read of what this company does, for whom, where. */
|
|
164
|
+
business: string;
|
|
165
|
+
entityClarity: {
|
|
166
|
+
score: number;
|
|
167
|
+
missing: string[];
|
|
168
|
+
};
|
|
169
|
+
buyerQuestions: BuyerQuestion[];
|
|
170
|
+
/** Standalone searches for the visibility probes — what a buyer types before
|
|
171
|
+
* they know this company exists. Distinct from `buyerQuestions`, which are
|
|
172
|
+
* phrased about this site and are unanswerable on their own; see the schema
|
|
173
|
+
* comment in analyze.ts for what that cost us. Never mentions the business. */
|
|
174
|
+
categoryQueries: string[];
|
|
175
|
+
fixes: Fix[];
|
|
176
|
+
narrative: {
|
|
177
|
+
findability: string;
|
|
178
|
+
readability: string;
|
|
179
|
+
answers: string;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
type ProbeAnswer = {
|
|
183
|
+
engine: string;
|
|
184
|
+
query: string;
|
|
185
|
+
/** "branded" ("who is X" / "X reviews") always echoes the name back even when
|
|
186
|
+
* an engine knows nothing real, so it cannot be trusted as a discoverability
|
|
187
|
+
* signal. "category" is a real buyer question — the one the score is built
|
|
188
|
+
* from. "competitor" is a head-to-head comparison query. */
|
|
189
|
+
kind: "branded" | "category" | "competitor";
|
|
190
|
+
domainCited: boolean;
|
|
191
|
+
brandMentioned: boolean;
|
|
192
|
+
citedDomains: string[];
|
|
193
|
+
/** First ~300 chars of the engine's answer — the report's receipt. */
|
|
194
|
+
snippet: string;
|
|
195
|
+
/** True when `snippet` is a truncated prefix of a longer answer — set
|
|
196
|
+
* right where the truncation happens (probes.ts's SNIPPET_CHARS), so the
|
|
197
|
+
* renderer never has to re-derive "was this cut short?" from a length
|
|
198
|
+
* check of its own against a constant it can't see. */
|
|
199
|
+
truncated: boolean;
|
|
200
|
+
/** ISO-8601, set when the answer came back — this stage's whole output is
|
|
201
|
+
* quotable claims about a live third party, and answer engines' answers
|
|
202
|
+
* drift, so a disputed line in a report needs a date attached. */
|
|
203
|
+
askedAt: string;
|
|
204
|
+
};
|
|
205
|
+
type ProbesResult = {
|
|
206
|
+
answers: ProbeAnswer[];
|
|
207
|
+
/** 0..100 — fraction of CATEGORY answers (real buyer questions) where the
|
|
208
|
+
* prospect was cited or mentioned. Null — never 0 — when no category query
|
|
209
|
+
* ran at all, e.g. the analyze stage failed and supplied no buyer questions.
|
|
210
|
+
* Deliberately excludes branded answers: "who is X"/"X reviews" echo the name
|
|
211
|
+
* back even when the engine knows nothing real, which would put a floor
|
|
212
|
+
* under the score that has nothing to do with discoverability. */
|
|
213
|
+
visibilityScore: number | null;
|
|
214
|
+
/** Did any branded query produce a real citation of the prospect's own
|
|
215
|
+
* domain — not merely an echo of the name in prose. Reported separately from
|
|
216
|
+
* visibilityScore because it answers a different question ("does the engine
|
|
217
|
+
* know this business exists at all") from the one the score answers ("would
|
|
218
|
+
* it surface this business to someone who didn't already name it"). */
|
|
219
|
+
brandedRecognized: boolean;
|
|
220
|
+
competitorsSeen: {
|
|
221
|
+
domain: string;
|
|
222
|
+
count: number;
|
|
223
|
+
}[];
|
|
224
|
+
};
|
|
225
|
+
type LighthouseScores = {
|
|
226
|
+
performance: number | null;
|
|
227
|
+
accessibility: number | null;
|
|
228
|
+
bestPractices: number | null;
|
|
229
|
+
seo: number | null;
|
|
230
|
+
summary: string;
|
|
231
|
+
status: AuditResult["status"];
|
|
232
|
+
};
|
|
233
|
+
type Scores = {
|
|
234
|
+
findability: number | null;
|
|
235
|
+
readability: number | null;
|
|
236
|
+
answers: number | null;
|
|
237
|
+
aiVisibility: number | null;
|
|
238
|
+
};
|
|
239
|
+
type ProspectAuditResult = {
|
|
240
|
+
url: string;
|
|
241
|
+
/** The resolved searchable proper NOUN — "Acme Roofing", not a description
|
|
242
|
+
* of it (mirrors `AnalyzeResult.businessName`, the value this is usually
|
|
243
|
+
* copied from). Distinct from `AnalyzeResult.business` (prose, nested
|
|
244
|
+
* under `analyze.data`) — the two share a root name only because they're
|
|
245
|
+
* one level apart, not because they hold the same kind of value. Null
|
|
246
|
+
* when no name was ever resolved (operator override empty, model returned
|
|
247
|
+
* none) — itself a finding, not an error. Persisted verbatim into the
|
|
248
|
+
* database's `business` COLUMN (kept as-is; a rename there would need its
|
|
249
|
+
* own migration for no benefit) — map at that one boundary, not here. */
|
|
250
|
+
businessName: string | null;
|
|
251
|
+
generatedAt: string;
|
|
252
|
+
scores: Scores;
|
|
253
|
+
/** The crawl is the one fatal stage (see pipeline.ts): a crawl failure
|
|
254
|
+
* throws before a ProspectAuditResult is ever built, so the `ok:false`
|
|
255
|
+
* branch of StageResult can never appear here. Narrowed to the success
|
|
256
|
+
* shape only, so consumers never handle the impossible branch. */
|
|
257
|
+
crawl: {
|
|
258
|
+
ok: true;
|
|
259
|
+
data: CrawlResult;
|
|
260
|
+
};
|
|
261
|
+
checks: StageResult<ChecksResult>;
|
|
262
|
+
lighthouse: StageResult<LighthouseScores>;
|
|
263
|
+
analyze: StageResult<AnalyzeResult>;
|
|
264
|
+
probes: StageResult<ProbesResult>;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export type { AnalyzeResult, BuyerQuestion, ChecksResult, CrawlResult, Fix, LighthouseScores, PageCapture, PageExtract, ProbeAnswer, ProbesResult, ProspectAuditResult, RobotsAgentAccess, Scores, StageResult };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hostnameOf,
|
|
3
|
+
isHttpUrl
|
|
4
|
+
} from "./chunk-EVBCK2KC.js";
|
|
5
|
+
|
|
6
|
+
// src/cli/commands/prospect-audit.ts
|
|
7
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
8
|
+
import { resolve } from "path";
|
|
9
|
+
|
|
10
|
+
// src/dashboard/handler-helpers.ts
|
|
11
|
+
var DEFAULT_DASHBOARD_BASE_URL = "https://reddoor-maintenance.netlify.app";
|
|
12
|
+
function resolveDashboardBaseUrl(raw) {
|
|
13
|
+
return (raw?.trim() || DEFAULT_DASHBOARD_BASE_URL).replace(/\/$/, "");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/cli/commands/prospect-audit.ts
|
|
17
|
+
function fail(message) {
|
|
18
|
+
return { output: message, code: 2 };
|
|
19
|
+
}
|
|
20
|
+
function errorMessage(err) {
|
|
21
|
+
return err instanceof Error ? err.message : String(err);
|
|
22
|
+
}
|
|
23
|
+
function scoreLine(label, value) {
|
|
24
|
+
return `${label.padEnd(14)} ${value === null ? "not measured" : String(value).padStart(3)}`;
|
|
25
|
+
}
|
|
26
|
+
function auditStatus(result) {
|
|
27
|
+
const allStagesOk = result.checks.ok && result.lighthouse.ok && result.analyze.ok && result.probes.ok;
|
|
28
|
+
return allStagesOk ? "complete" : "partial";
|
|
29
|
+
}
|
|
30
|
+
function slugify(s) {
|
|
31
|
+
const slug = s.toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
32
|
+
return slug || "prospect";
|
|
33
|
+
}
|
|
34
|
+
async function writeRecoveryFiles(result, html) {
|
|
35
|
+
const dir = resolve("reports");
|
|
36
|
+
await mkdir(dir, { recursive: true });
|
|
37
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
38
|
+
const base = `prospect-audit-${slugify(hostnameOf(result.url))}-${stamp}`;
|
|
39
|
+
const htmlPath = resolve(dir, `${base}.html`);
|
|
40
|
+
const jsonPath = resolve(dir, `${base}.json`);
|
|
41
|
+
await writeFile(htmlPath, html, "utf-8");
|
|
42
|
+
await writeFile(jsonPath, JSON.stringify(result, null, 2), "utf-8");
|
|
43
|
+
return { htmlPath, jsonPath };
|
|
44
|
+
}
|
|
45
|
+
function summarize(result, link, file, warnings, recovery, email) {
|
|
46
|
+
const lines = [
|
|
47
|
+
`Prospect audit \u2014 ${result.businessName ?? result.url}`,
|
|
48
|
+
"",
|
|
49
|
+
scoreLine("Findability", result.scores.findability),
|
|
50
|
+
scoreLine("Readability", result.scores.readability),
|
|
51
|
+
scoreLine("Answers", result.scores.answers),
|
|
52
|
+
scoreLine("AI Visibility", result.scores.aiVisibility)
|
|
53
|
+
];
|
|
54
|
+
for (const [name, stage] of [
|
|
55
|
+
["checks", result.checks],
|
|
56
|
+
["lighthouse", result.lighthouse],
|
|
57
|
+
["analyze", result.analyze],
|
|
58
|
+
["probes", result.probes]
|
|
59
|
+
]) {
|
|
60
|
+
if (!stage.ok) lines.push(` ! ${name} not measured \u2014 ${stage.error}`);
|
|
61
|
+
}
|
|
62
|
+
if (file) lines.push("", `Report written to ${file}`);
|
|
63
|
+
if (link) lines.push("", `Shareable link: ${link}`);
|
|
64
|
+
if (email?.sent) {
|
|
65
|
+
lines.push("", `Emailed to ${email.recipients.join(", ")} (${email.messageId})`);
|
|
66
|
+
}
|
|
67
|
+
for (const w of warnings) lines.push("", `! ${w}`);
|
|
68
|
+
if (recovery) {
|
|
69
|
+
lines.push(
|
|
70
|
+
"",
|
|
71
|
+
"Neither --out nor the database took this report \u2014 wrote a recovery copy instead:",
|
|
72
|
+
` ${recovery.htmlPath}`,
|
|
73
|
+
` ${recovery.jsonPath}`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
return lines.join("\n");
|
|
77
|
+
}
|
|
78
|
+
async function runProspectAuditCommand(url, opts) {
|
|
79
|
+
if (!isHttpUrl(url)) {
|
|
80
|
+
return fail(`"${url}" is not a URL. Pass the full address, e.g. https://example.com`);
|
|
81
|
+
}
|
|
82
|
+
const canPersist = Boolean(process.env.TURSO_DATABASE_URL);
|
|
83
|
+
if (!canPersist && !opts.out) {
|
|
84
|
+
return fail(
|
|
85
|
+
"No TURSO_DATABASE_URL, so the report cannot be saved or shared. Re-run with --out <file>, or set the Turso credentials."
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const { runProspectAudit } = await import("./pipeline-3AANZFCR.js");
|
|
89
|
+
const onStage = (name, status, detail) => {
|
|
90
|
+
if (status === "start") console.error(`\u2026 ${name}`);
|
|
91
|
+
else if (status === "ok") console.error(`\u2713 ${name}`);
|
|
92
|
+
else console.error(`! ${name} \u2014 ${detail ?? "failed"}`);
|
|
93
|
+
};
|
|
94
|
+
const business = opts.business?.trim();
|
|
95
|
+
const result = await runProspectAudit(
|
|
96
|
+
url,
|
|
97
|
+
{
|
|
98
|
+
...business ? { business } : {},
|
|
99
|
+
...opts.competitors ? {
|
|
100
|
+
competitors: opts.competitors.split(",").map((c) => c.trim()).filter(Boolean)
|
|
101
|
+
} : {},
|
|
102
|
+
...opts.probes === false ? { probes: false } : {}
|
|
103
|
+
},
|
|
104
|
+
{ ...opts.deps ?? {}, onStage }
|
|
105
|
+
);
|
|
106
|
+
const { renderProspectReport } = await import("./render-IFOGFB5T.js");
|
|
107
|
+
const html = renderProspectReport(result);
|
|
108
|
+
const warnings = [];
|
|
109
|
+
let file = null;
|
|
110
|
+
if (opts.out) {
|
|
111
|
+
try {
|
|
112
|
+
await writeFile(opts.out, html, "utf-8");
|
|
113
|
+
file = opts.out;
|
|
114
|
+
} catch (err) {
|
|
115
|
+
warnings.push(`Could not write --out (${opts.out}): ${errorMessage(err)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
let link = null;
|
|
119
|
+
let token = null;
|
|
120
|
+
let auditId = null;
|
|
121
|
+
if (canPersist) {
|
|
122
|
+
try {
|
|
123
|
+
const { openDb, readDbConfig } = await import("./client-AUE3XUPO.js");
|
|
124
|
+
const { createProspectAudit } = await import("./prospect-audits-3PMIO73D.js");
|
|
125
|
+
const db = await openDb(readDbConfig());
|
|
126
|
+
const created = await createProspectAudit(db, {
|
|
127
|
+
url: result.url,
|
|
128
|
+
// Map at the boundary: ProspectAuditResult.businessName is the field
|
|
129
|
+
// name (Item 2 — it's a resolved NAME, not a description); the
|
|
130
|
+
// `prospect_audits.business` column keeps its existing name, since
|
|
131
|
+
// renaming a column needs its own migration for no benefit here.
|
|
132
|
+
business: result.businessName,
|
|
133
|
+
status: auditStatus(result),
|
|
134
|
+
resultJson: JSON.stringify(result)
|
|
135
|
+
});
|
|
136
|
+
auditId = created.id;
|
|
137
|
+
token = created.token;
|
|
138
|
+
link = `${resolveDashboardBaseUrl(process.env.DASHBOARD_BASE_URL)}/r/${token}`;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
warnings.push(`Could not save to the database: ${errorMessage(err)}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const delivered = file !== null || link !== null;
|
|
144
|
+
const recovery = delivered ? null : await writeRecoveryFiles(result, html);
|
|
145
|
+
const code = delivered ? 0 : 1;
|
|
146
|
+
let email = null;
|
|
147
|
+
if (opts.email) {
|
|
148
|
+
try {
|
|
149
|
+
const { sendAuditEmail, parseProspectAuditRecipients } = await import("./email-KJXASVH5.js");
|
|
150
|
+
const recipients = parseProspectAuditRecipients(process.env.PROSPECT_AUDIT_RECIPIENTS);
|
|
151
|
+
email = await sendAuditEmail(result, { link, recipients, auditId });
|
|
152
|
+
if (!email.sent) {
|
|
153
|
+
warnings.push(`Could not email the audit sheet: ${email.reason}`);
|
|
154
|
+
}
|
|
155
|
+
} catch (err) {
|
|
156
|
+
warnings.push(`Could not email the audit sheet: ${errorMessage(err)}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (opts.json) {
|
|
160
|
+
return {
|
|
161
|
+
output: JSON.stringify(
|
|
162
|
+
{ result, out: file, link, token, recovery, warnings, email },
|
|
163
|
+
null,
|
|
164
|
+
2
|
|
165
|
+
),
|
|
166
|
+
code
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return { output: summarize(result, link, file, warnings, recovery, email), code };
|
|
170
|
+
}
|
|
171
|
+
export {
|
|
172
|
+
runProspectAuditCommand
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=prospect-audit-KSXUNQ5J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/prospect-audit.ts","../src/dashboard/handler-helpers.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { hostnameOf, isHttpUrl } from \"../../util/url.js\";\nimport { resolveDashboardBaseUrl } from \"../../dashboard/handler-helpers.js\";\nimport type { ProspectAuditStatus } from \"../../db/prospect-audits.js\";\nimport type { PipelineDeps, StageName } from \"../../prospect/pipeline.js\";\nimport type { ProspectAuditResult } from \"../../prospect/types.js\";\nimport type { SendAuditEmailResult } from \"../../prospect/email.js\";\n\nexport type ProspectAuditCliOptions = {\n business?: string;\n /** Comma-separated competitor domains. */\n competitors?: string;\n /** cac sets this false for `--no-probes`. */\n probes?: boolean;\n out?: string;\n json?: boolean;\n /**\n * Email the internal sheet (scores, what wasn't measured and why, top\n * fixes, and the shareable link) to `PROSPECT_AUDIT_RECIPIENTS`, once the\n * report is rendered and the `--out`/Turso delivery attempts finish. A\n * missing/empty recipients var, or a Resend failure, is a warning — never a\n * crash — because by the time this runs the audit is already delivered (or\n * recovered) by the code above it.\n */\n email?: boolean;\n /** Test seam: injected pipeline deps. Never set from the CLI. */\n deps?: PipelineDeps;\n};\n\ntype RecoveryWrite = { htmlPath: string; jsonPath: string };\n\nfunction fail(message: string): { output: string; code: number } {\n return { output: message, code: 2 };\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction scoreLine(label: string, value: number | null): string {\n return `${label.padEnd(14)} ${value === null ? \"not measured\" : String(value).padStart(3)}`;\n}\n\n/** Item 3: the `status` column exists to answer, without deserializing the\n * whole result_json, whether this was a clean run or a degraded one. crawl\n * is excluded — it's the one fatal stage (see pipeline.ts), so by the time a\n * ProspectAuditResult exists it was always ok. Every other stage's\n * StageResult already collapses \"failed\" and \"deliberately skipped\"\n * (--no-probes, the checks→analyze cascade) into the same `ok: false` — both\n * mean the report has a \"not measured\" section, so both count as partial\n * here too. */\nfunction auditStatus(result: ProspectAuditResult): ProspectAuditStatus {\n const allStagesOk =\n result.checks.ok && result.lighthouse.ok && result.analyze.ok && result.probes.ok;\n return allStagesOk ? \"complete\" : \"partial\";\n}\n\n/** Filesystem-safe, never empty. Collapses anything outside [a-z0-9.-] to a\n * single dash so a hostname becomes a sane filename fragment. */\nfunction slugify(s: string): string {\n const slug = s\n .toLowerCase()\n .replace(/[^a-z0-9.-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return slug || \"prospect\";\n}\n\n/**\n * Last-resort write when NEITHER `--out` nor the database persist made it —\n * the one situation a paid, already-run audit must never end in silently. Lands\n * in `reports/`, mirroring header-image.ts's own convention for CLI-written\n * artifacts (mkdir -p, resolved against cwd), rather than a bare file dropped\n * into whatever directory the operator happened to be standing in when they\n * ran the command — often unrelated to this repo at all in fleet-tool usage.\n */\nasync function writeRecoveryFiles(\n result: ProspectAuditResult,\n html: string,\n): Promise<RecoveryWrite> {\n const dir = resolve(\"reports\");\n await mkdir(dir, { recursive: true });\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const base = `prospect-audit-${slugify(hostnameOf(result.url))}-${stamp}`;\n const htmlPath = resolve(dir, `${base}.html`);\n const jsonPath = resolve(dir, `${base}.json`);\n await writeFile(htmlPath, html, \"utf-8\");\n await writeFile(jsonPath, JSON.stringify(result, null, 2), \"utf-8\");\n return { htmlPath, jsonPath };\n}\n\nfunction summarize(\n result: ProspectAuditResult,\n link: string | null,\n file: string | null,\n warnings: string[],\n recovery: RecoveryWrite | null,\n email: SendAuditEmailResult | null,\n): string {\n const lines = [\n `Prospect audit — ${result.businessName ?? result.url}`,\n \"\",\n scoreLine(\"Findability\", result.scores.findability),\n scoreLine(\"Readability\", result.scores.readability),\n scoreLine(\"Answers\", result.scores.answers),\n scoreLine(\"AI Visibility\", result.scores.aiVisibility),\n ];\n for (const [name, stage] of [\n [\"checks\", result.checks],\n [\"lighthouse\", result.lighthouse],\n [\"analyze\", result.analyze],\n [\"probes\", result.probes],\n ] as const) {\n if (!stage.ok) lines.push(` ! ${name} not measured — ${stage.error}`);\n }\n if (file) lines.push(\"\", `Report written to ${file}`);\n if (link) lines.push(\"\", `Shareable link: ${link}`);\n if (email?.sent) {\n lines.push(\"\", `Emailed to ${email.recipients.join(\", \")} (${email.messageId})`);\n }\n for (const w of warnings) lines.push(\"\", `! ${w}`);\n if (recovery) {\n lines.push(\n \"\",\n \"Neither --out nor the database took this report — wrote a recovery copy instead:\",\n ` ${recovery.htmlPath}`,\n ` ${recovery.jsonPath}`,\n );\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Run one prospect audit end to end. Progress goes to stderr so `--json` stdout\n * stays pipeable. Persistence needs Turso; without it `--out` is mandatory,\n * because an audit nobody can read afterwards is just a bill.\n *\n * By the time `runProspectAudit` resolves, the money is already spent — only\n * the crawl is fatal, every other stage degrades rather than throwing. So the\n * `--out` write and the database persist below are each wrapped in their own\n * try/catch and attempted independently: a bad `--out` path must not cost a\n * working Turso persist (or vice versa), and if BOTH fail — or persist fails\n * with no `--out` given at all — a recovery copy goes to `reports/` rather\n * than the run ending with nothing anywhere. `--json` only changes the SHAPE\n * of stdout; it still runs the same `--out`/persist/recovery logic beneath it.\n */\nexport async function runProspectAuditCommand(\n url: string,\n opts: ProspectAuditCliOptions,\n): Promise<{ output: string; code: number }> {\n if (!isHttpUrl(url)) {\n return fail(`\"${url}\" is not a URL. Pass the full address, e.g. https://example.com`);\n }\n const canPersist = Boolean(process.env.TURSO_DATABASE_URL);\n if (!canPersist && !opts.out) {\n return fail(\n \"No TURSO_DATABASE_URL, so the report cannot be saved or shared. Re-run with --out <file>, or set the Turso credentials.\",\n );\n }\n\n const { runProspectAudit } = await import(\"../../prospect/pipeline.js\");\n const onStage = (name: StageName, status: \"start\" | \"ok\" | \"fail\", detail?: string): void => {\n if (status === \"start\") console.error(`… ${name}`);\n else if (status === \"ok\") console.error(`✓ ${name}`);\n else console.error(`! ${name} — ${detail ?? \"failed\"}`);\n };\n\n const business = opts.business?.trim();\n const result = await runProspectAudit(\n url,\n {\n ...(business ? { business } : {}),\n ...(opts.competitors\n ? {\n competitors: opts.competitors\n .split(\",\")\n .map((c) => c.trim())\n .filter(Boolean),\n }\n : {}),\n ...(opts.probes === false ? { probes: false } : {}),\n },\n { ...(opts.deps ?? {}), onStage },\n );\n\n const { renderProspectReport } = await import(\"../../prospect/render.js\");\n const html = renderProspectReport(result);\n\n const warnings: string[] = [];\n\n let file: string | null = null;\n if (opts.out) {\n try {\n await writeFile(opts.out, html, \"utf-8\");\n file = opts.out;\n } catch (err) {\n warnings.push(`Could not write --out (${opts.out}): ${errorMessage(err)}`);\n }\n }\n\n let link: string | null = null;\n let token: string | null = null;\n let auditId: string | null = null;\n if (canPersist) {\n try {\n const { openDb, readDbConfig } = await import(\"../../db/client.js\");\n const { createProspectAudit } = await import(\"../../db/prospect-audits.js\");\n const db = await openDb(readDbConfig());\n const created = await createProspectAudit(db, {\n url: result.url,\n // Map at the boundary: ProspectAuditResult.businessName is the field\n // name (Item 2 — it's a resolved NAME, not a description); the\n // `prospect_audits.business` column keeps its existing name, since\n // renaming a column needs its own migration for no benefit here.\n business: result.businessName,\n status: auditStatus(result),\n resultJson: JSON.stringify(result),\n });\n auditId = created.id;\n token = created.token;\n link = `${resolveDashboardBaseUrl(process.env.DASHBOARD_BASE_URL)}/r/${token}`;\n } catch (err) {\n warnings.push(`Could not save to the database: ${errorMessage(err)}`);\n }\n }\n\n const delivered = file !== null || link !== null;\n const recovery = delivered ? null : await writeRecoveryFiles(result, html);\n const code = delivered ? 0 : 1;\n\n // The audit is already delivered (or recovered) above — an email failure\n // must never take that away. Same independent try/catch shape as the\n // --out write and the Turso persist: record a warning, keep going, never\n // touch `code`. Dynamically imported for the same reason db/client.js and\n // prospect/render.js are above: it reaches `resend` (a devDependency) and\n // must stay out of bin.js's static import graph (see bin.ts's\n // central-dep-blocker comment).\n let email: SendAuditEmailResult | null = null;\n if (opts.email) {\n try {\n const { sendAuditEmail, parseProspectAuditRecipients } =\n await import(\"../../prospect/email.js\");\n const recipients = parseProspectAuditRecipients(process.env.PROSPECT_AUDIT_RECIPIENTS);\n email = await sendAuditEmail(result, { link, recipients, auditId });\n if (!email.sent) {\n warnings.push(`Could not email the audit sheet: ${email.reason}`);\n }\n } catch (err) {\n warnings.push(`Could not email the audit sheet: ${errorMessage(err)}`);\n }\n }\n\n if (opts.json) {\n return {\n output: JSON.stringify(\n { result, out: file, link, token, recovery, warnings, email },\n null,\n 2,\n ),\n code,\n };\n }\n\n return { output: summarize(result, link, file, warnings, recovery, email), code };\n}\n","/**\n * Small pure helpers extracted from the Netlify dashboard handlers\n * (fleet-homepage.mts, site-dashboard.mts) so their non-glue logic is\n * unit-testable without booting a Netlify function.\n */\n\nconst DEFAULT_DASHBOARD_BASE_URL = \"https://reddoor-maintenance.netlify.app\";\n\n/**\n * Resolve the dashboard's public base URL from the optional DASHBOARD_BASE_URL\n * env var: trim it, fall back to the canonical Netlify URL when unset/blank,\n * and strip a trailing slash so callers can append `/s/:slug` cleanly.\n */\nexport function resolveDashboardBaseUrl(raw: string | undefined): string {\n return (raw?.trim() || DEFAULT_DASHBOARD_BASE_URL).replace(/\\/$/, \"\");\n}\n\n/**\n * Resolve the requested site slug from the path param (Netlify\n * `ctx.params.slug`) or, lacking it, the `?slug=` query param. Null when\n * neither is present (→ the handler's presence-only health check).\n */\nexport function resolveSlug(\n paramSlug: string | undefined,\n querySlug: string | null,\n): string | null {\n return paramSlug ?? querySlug ?? null;\n}\n\n/**\n * Build a 502 for an UNEXPECTED handler failure (an Airtable 429/500, a network\n * timeout). Logs the real error server-side so the operator sees it in the\n * function logs, but returns a generic, retry-able body — never the error/stack\n * itself — so a transient backend hiccup degrades to a clean \"try again\" rather\n * than an unhandled rejection (whose surfaced status/body we don't control).\n * Use in each handler's top-level catch around the Airtable + render section.\n */\nexport function handlerError(service: string, err: unknown): Response {\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n console.error(`[${service}] unexpected failure: ${detail}`);\n return new Response(\"Temporarily unavailable — please retry in a moment.\", {\n status: 502,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" },\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_RECENT_PROSPECT_AUDITS,
|
|
3
|
+
createProspectAudit,
|
|
4
|
+
generateToken,
|
|
5
|
+
getProspectAuditByToken,
|
|
6
|
+
isValidToken,
|
|
7
|
+
listRecentProspectAudits,
|
|
8
|
+
newProspectAuditId
|
|
9
|
+
} from "./chunk-NYUYNYQL.js";
|
|
10
|
+
export {
|
|
11
|
+
MAX_RECENT_PROSPECT_AUDITS,
|
|
12
|
+
createProspectAudit,
|
|
13
|
+
generateToken,
|
|
14
|
+
getProspectAuditByToken,
|
|
15
|
+
isValidToken,
|
|
16
|
+
listRecentProspectAudits,
|
|
17
|
+
newProspectAuditId
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=prospect-audits-3PMIO73D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
} from "./chunk-MNDIED4M.js";
|
|
4
4
|
import {
|
|
5
5
|
makeGitHub
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-XHHMM5HX.js";
|
|
7
|
+
import "./chunk-LBYOLBW7.js";
|
|
8
8
|
|
|
9
9
|
// src/audits/protection-coverage.ts
|
|
10
10
|
var RENOVATE_WORKFLOW_FILE = "renovate.yml";
|
|
@@ -165,4 +165,4 @@ export {
|
|
|
165
165
|
protectionAuditExitCode,
|
|
166
166
|
runProtectionAuditCommand
|
|
167
167
|
};
|
|
168
|
-
//# sourceMappingURL=protection-audit-
|
|
168
|
+
//# sourceMappingURL=protection-audit-SJO53MEQ.js.map
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
ALL_CONFIG_NAMES,
|
|
3
3
|
isConfigName,
|
|
4
4
|
syncConfigs
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-7UAYMAKR.js";
|
|
6
6
|
import "../chunk-73UFRZKY.js";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-XXTZBPUY.js";
|
|
7
|
+
import "../chunk-3G25KIWW.js";
|
|
9
8
|
import "../chunk-XTK5VIQB.js";
|
|
9
|
+
import "../chunk-XXTZBPUY.js";
|
|
10
10
|
export {
|
|
11
11
|
ALL_CONFIG_NAMES,
|
|
12
12
|
isConfigName,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderReportFromRow,
|
|
3
|
+
requireLighthouse,
|
|
4
|
+
windowDays
|
|
5
|
+
} from "./chunk-ZGBEIWSC.js";
|
|
6
|
+
import "./chunk-GECESMVS.js";
|
|
7
|
+
import "./chunk-MT2JINSS.js";
|
|
8
|
+
import "./chunk-DJZWYIPP.js";
|
|
9
|
+
import "./chunk-5UINJNAJ.js";
|
|
10
|
+
import "./chunk-7NYN2P6I.js";
|
|
11
|
+
import "./chunk-EVBCK2KC.js";
|
|
12
|
+
export {
|
|
13
|
+
renderReportFromRow,
|
|
14
|
+
requireLighthouse,
|
|
15
|
+
windowDays
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=render-from-row-BWSOIYDS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -2,19 +2,19 @@ import {
|
|
|
2
2
|
isRenovatePR
|
|
3
3
|
} from "./chunk-PZQ3WED2.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
openBase,
|
|
6
|
+
readAirtableConfig
|
|
7
|
+
} from "./chunk-HN6I2XWI.js";
|
|
8
8
|
import {
|
|
9
9
|
allActionableVulnsTransitive,
|
|
10
10
|
isDashboardVisible,
|
|
11
11
|
listWebsites,
|
|
12
12
|
updateAutoFixAttempts
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7NYN2P6I.js";
|
|
14
14
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
makeGitHub
|
|
16
|
+
} from "./chunk-XHHMM5HX.js";
|
|
17
|
+
import "./chunk-LBYOLBW7.js";
|
|
18
18
|
import "./chunk-6VAL7XJT.js";
|
|
19
19
|
|
|
20
20
|
// src/github/renovate-dispatch.ts
|
|
@@ -130,10 +130,10 @@ async function runRenovateDispatchCommand(opts) {
|
|
|
130
130
|
for (const f of result.failed) lines.push(` \u21B3 ${f.repo}: ${f.error}`);
|
|
131
131
|
}
|
|
132
132
|
const attemptUpdates = computeAutoFixAttemptUpdates(websites, result);
|
|
133
|
-
const attemptTally = await applyAutoFixAttemptUpdates(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
);
|
|
133
|
+
const attemptTally = await applyAutoFixAttemptUpdates(attemptUpdates, async (id, attempts) => {
|
|
134
|
+
const fields = await updateAutoFixAttempts(base, id, attempts);
|
|
135
|
+
await opts.siteMirror?.health(id, fields);
|
|
136
|
+
});
|
|
137
137
|
lines.push(formatRenovateDispatchSummary(result));
|
|
138
138
|
lines.push(formatAutoFixAttemptsSummary(attemptTally));
|
|
139
139
|
return { output: lines.join("\n"), code: 0 };
|
|
@@ -141,4 +141,4 @@ async function runRenovateDispatchCommand(opts) {
|
|
|
141
141
|
export {
|
|
142
142
|
runRenovateDispatchCommand
|
|
143
143
|
};
|
|
144
|
-
//# sourceMappingURL=renovate-dispatch-
|
|
144
|
+
//# sourceMappingURL=renovate-dispatch-6GQWTRKX.js.map
|