# `consent.ts` _(no submodules)_ ## Purpose Implements the `ConsentPolicy` SPI bundled with `@suaveplan/analytics-browser`. The tracker calls `policy.isAllowed(event)` before any sampling, scrubbing, or queueing decision, so a `false` return short-circuits the entire pipeline and emits a `drop` event with reason `consent`. Two built-in policies ship with the package: `AllowAllPolicy` (default) and `DoNotTrackPolicy` (honours `navigator.doNotTrack === "1"`). Downstream consumers can implement their own policy — e.g. one that consults a stored cookie-banner preference — by implementing the interface from `@suaveplan/analytics-browser/types`. ## Features - Lazy navigator lookup — both policies are constructable in SSR / Node contexts where `navigator` is undefined; the policy simply permits the event in that case. - Zero state — both built-ins are stateless and reentrant. - Strict equality on `"1"` — matches the W3C Tracking Preference Expression spec; values `"0"` or `"unspecified"` permit tracking. ## Usage: Basic ```ts import { DoNotTrackPolicy } from "@suaveplan/analytics-browser/consent"; import { AnalyticsTracker } from "@suaveplan/analytics-browser/tracker"; const tracker = new AnalyticsTracker(transport, { consentPolicy: new DoNotTrackPolicy(), }); tracker.track("page_loaded"); // dropped if navigator.doNotTrack === "1" ``` ## Usage: Advanced ```ts import type { AnalyticsEvent, ConsentPolicy, } from "@suaveplan/analytics-browser/types"; class CookieBannerPolicy implements ConsentPolicy { public constructor(private readonly read: () => "granted" | "denied") {} public isAllowed(_event: AnalyticsEvent): boolean { return this.read() === "granted"; } } ``` ## API Reference - `class AllowAllPolicy implements ConsentPolicy` — `isAllowed(event) → true`. - `class DoNotTrackPolicy implements ConsentPolicy` — returns `false` iff `typeof navigator !== "undefined" && navigator.doNotTrack === "1"`. ## Implementation Notes `DoNotTrackPolicy` reads `navigator.doNotTrack` on every call rather than caching at construction time. This is deliberate: the spec lets the user toggle the preference at runtime in some browsers (notably in private windows), and caching would freeze the decision at construction. The cost is a single property read per event — negligible compared with the JSON serialisation that follows on the happy path. Both classes pass their `event` argument with a leading underscore name to signal it is intentionally unused; lint rules permit underscore-prefixed unused parameters.