/** * report-ack — the decision behind what POST /report answers (#1840). * * Pure on purpose. The handler in http.ts does the I/O (parse, write the disk * ledger, append to the blob store); this module turns what happened into the * acknowledgement body and the HTTP status, so the one rule that matters can * be unit-tested without a Netlify context: * * a beacon that was persisted NOWHERE is never a 2xx. * * That rule exists because the hosted endpoint answered 200 for six weeks of * bradfrost.com beacons while capturing none of them — `@netlify/blobs` was * external to an unbundled function, the import threw, the capture became a * no-op, and the reporter logged `beacon: sent (200)`. */ /** Where a beacon ended up. `disk` is durable on a live repo, `blobs` on serverless. */ export type ReportStoreKind = 'blobs' | 'disk' | 'none'; export interface IngestAck { /** The body parsed as a usage report (has a product id). */ recorded: boolean; /** The report is durably held somewhere a flush or a ledger can read it. */ persisted: boolean; /** Which store took it; `none` on the failure path this module exists for. */ store: ReportStoreKind; /** Set when the request carried `X-Eddie-Report-Probe: 1`: validated, nothing written. */ probe?: boolean; product?: string; reportCount?: number; reason?: string; } export declare const PROBE_HEADER = "x-eddie-report-probe"; /** * Read the probe header. `true` = probe (prove the store is reachable, write * nothing); `false` = a real beacon; `null` = the header carried a value this * endpoint does not recognise. Unrecognised values are rejected rather than * treated as "not a probe": a mistyped probe that fell open into a real beacon * would seed the ledger with the synthetic product the probe exists to keep out. */ export declare function parseProbeHeader(headerValue: string | string[] | null | undefined): boolean | null; /** Body + status for a request whose probe header could not be read. */ export declare function invalidProbeAck(headerValue: unknown): { status: number; body: { error: string; }; }; /** Collapse the two persistence outcomes into the one store the ack names. */ export declare function resolveStore(outcome: { blobs: boolean; disk: boolean; }): ReportStoreKind; export declare function buildAck(input: { recorded: boolean; probe: boolean; store: ReportStoreKind; product?: string; reportCount?: number; reason?: string; }): IngestAck; /** * HTTP status for an ack. 400 for a body that is not a report; 503 whenever * nothing could hold the report (or, for a probe, nothing could); 202 for a * captured beacon; 200 for a probe that found a working store. */ export declare function ackStatus(ack: IngestAck): number; //# sourceMappingURL=report-ack.d.ts.map