@reddoorla/maintenance 0.49.0 → 0.50.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Site, a as AuditResult, A as AuditName, b as RecipeResult, R as RecipeName, I as InventoryProvider } from './types-DeKpgkG-.js';
2
- export { C as ConfigName } from './types-DeKpgkG-.js';
1
+ import { S as Site, a as AuditResult, A as AuditName, b as RecipeResult, R as RecipeName, I as InventoryProvider } from './types-QG-QhCYh.js';
2
+ export { C as ConfigName } from './types-QG-QhCYh.js';
3
3
  import * as airtable_lib_airtable_base_js from 'airtable/lib/airtable_base.js';
4
4
  import { F as FormType } from './types-RXY-vY-5.js';
5
5
  export { SyncConfigsOptions, syncConfigs } from './recipes/sync-configs.js';
@@ -20,9 +20,65 @@ type SpawnOptions = {
20
20
  };
21
21
  type SpawnFn = (cmd: string, args: readonly string[], opts?: SpawnOptions) => Promise<SpawnResult>;
22
22
 
23
+ /** Injected IO so the check is unit-testable without real DNS/TLS. `lookup` throws when the host
24
+ * doesn't resolve; `certValidTo` returns the cert's notAfter date, or null when there's none. */
25
+ type DomainDeps = {
26
+ lookup: (host: string) => Promise<void>;
27
+ certValidTo: (host: string) => Promise<Date | null>;
28
+ now: Date;
29
+ };
30
+
31
+ /**
32
+ * Route discovery for the deployed-URL browser audit. Pulls the site's sitemap, then samples a
33
+ * REPRESENTATIVE set of paths — bucketed by path family (first segment) and sampled round-robin —
34
+ * so every page *type* is covered, including the dynamic CMS-generated templates (Prismic
35
+ * `[uid]`/`[slug]` detail pages: blog posts, projects, portfolio items) where broken
36
+ * images / overflowing galleries / dead links hide. Taking the first N sitemap entries would skew
37
+ * to top-level static pages and miss them. Pure functions + one fetch-injected entry point.
38
+ */
39
+ type DiscoverDeps = {
40
+ /** Fetch a URL, returning its text body, or null on any non-2xx / network error. */
41
+ fetchText: (url: string) => Promise<string | null>;
42
+ };
43
+
44
+ /** One route probed across desktop engines + mobile devices, plus the internal links found on it. */
45
+ type RouteResult = {
46
+ url: string;
47
+ /** Per desktop engine (chromium/firefox/webkit): loaded with no JS error + a visible main landmark. */
48
+ desktop: Array<{
49
+ engine: string;
50
+ ok: boolean;
51
+ }>;
52
+ /** Per mobile device: loaded with no JS error and no horizontal overflow. */
53
+ mobile: Array<{
54
+ device: string;
55
+ ok: boolean;
56
+ }>;
57
+ /** Same-origin links discovered on the page (absolute URLs), for the Links check. */
58
+ links: string[];
59
+ };
60
+ type LinkResult = {
61
+ url: string;
62
+ status: number | null;
63
+ };
64
+ /** Injected browser IO. The real impl drives Playwright; tests pass a fake. */
65
+ type BrowserRunner = {
66
+ probe: (urls: string[]) => Promise<RouteResult[]>;
67
+ checkLinks: (urls: string[]) => Promise<LinkResult[]>;
68
+ close?: () => Promise<void>;
69
+ };
70
+
23
71
  type AuditContext = {
24
72
  site: Site;
25
73
  spawn?: SpawnFn;
74
+ /** Clock injection (domain + browser audits). Defaults to `new Date()`. */
75
+ now?: Date;
76
+ /** DNS/TLS injection for the domain audit (tests). Defaults to real DNS+TLS. */
77
+ domainDeps?: DomainDeps;
78
+ /** Sitemap/homepage fetch injection for the browser audit (tests). Defaults to real fetch. */
79
+ discoverDeps?: DiscoverDeps;
80
+ /** Playwright runner injection for the browser audit (tests). Defaults to real Playwright. */
81
+ browserRunner?: BrowserRunner;
26
82
  };
27
83
 
28
84
  declare function depsAudit(ctx: AuditContext): Promise<AuditResult>;
@@ -248,6 +304,20 @@ type WebsiteRow = {
248
304
  securityVulnsHigh: number | null;
249
305
  securityVulnsModerate: number | null;
250
306
  securityVulnsLow: number | null;
307
+ /** ISO timestamp the security audit last ran — gates freshness of the Security Updates auto-tick
308
+ * (clean counts only auto-tick when recent). */
309
+ lastSecurityAuditAt: string | null;
310
+ /** Domain/DNS/SSL probe (the `domain` audit). `certDaysRemaining` is days until the TLS cert
311
+ * expires (null = unresolved or no usable cert); `domainCheckedAt` is when it last ran. */
312
+ certDaysRemaining: number | null;
313
+ domainCheckedAt: string | null;
314
+ /** Deployed-URL browser probe (the `browser` audit): cross-engine render OK, mobile render OK,
315
+ * internal-links OK + broken count, and when it last ran (one timestamp gates all three). */
316
+ crossbrowserOk: boolean | null;
317
+ mobileOk: boolean | null;
318
+ linksOk: boolean | null;
319
+ brokenLinks: number | null;
320
+ browserCheckedAt: string | null;
251
321
  /** Per-site copy overrides (M6a). Blank → null → the DEFAULT_COPY value. */
252
322
  copyIntro: string | null;
253
323
  copyContact: string | null;
@@ -356,6 +426,14 @@ type ReportData = {
356
426
  headerBgColor?: string;
357
427
  };
358
428
 
429
+ /** A single auto-check outcome. `pass` + fresh ⇒ the caller ticks the box. */
430
+ type EvidenceResult = "pass" | "fail" | "unknown";
431
+ type EvidenceRecord = {
432
+ result: EvidenceResult;
433
+ checkedAt: string | null;
434
+ note: string;
435
+ };
436
+
359
437
  type DeliveryStatus = "pending" | "delivered" | "bounced" | "complained";
360
438
  type ReportRow = {
361
439
  id: string;
@@ -391,6 +469,10 @@ type ReportRow = {
391
469
  * missing/false cells read false. Maintenance/Testing reports gate approve+send on the relevant
392
470
  * subset (see src/reports/checklist.ts). */
393
471
  checklist: Record<string, boolean>;
472
+ /** Snapshot of the auto-tick evidence at draft time, keyed by checklist field → evidence
473
+ * record. Null when the report predates auto-tick or carried no auto-checked items. Drives the
474
+ * dashboard's green/amber badges; the gate still reads the booleans, not this. */
475
+ autoEvidence: Record<string, EvidenceRecord> | null;
394
476
  };
395
477
 
396
478
  type DraftOptions = {