first commit
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# `analytics-event-schema.ts`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the canonical Zod schema for `AnalyticsEvent` and a `validateAnalyticsEvent` parse helper. The schema lets consumers validate untrusted payloads (iframe postMessage bridges, browser extension messages, recovered IndexedDB rows) before handing them to the tracker. The helper wraps `safeParse` so the boundary failure mode is a typed `AnalyticsBrowserError(INVALID_EVENT)` carrying the full Zod issue list on `error.context.issues` — no raw `ZodError` leaks past the boundary.
|
||||
|
||||
## Features
|
||||
|
||||
- Single source of truth for the on-wire and in-memory shape of an analytics event.
|
||||
- Required: `id`, `name`, `timestamp`, `sessionId`, `anonymousId`, `properties` (record). Optional: `userId`.
|
||||
- Boundary-failure translation: every Zod issue is collected into `error.context.issues` so observability tooling can render the full failure tree.
|
||||
- Schema is exported directly so downstream packages can `.merge` / `.extend` to add domain-specific shape (e.g. an e-commerce analytics extension).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { validateAnalyticsEvent } from "@suaveplan/analytics-browser/schema";
|
||||
|
||||
const safe = validateAnalyticsEvent(unknownPayload);
|
||||
tracker.track(safe.name, safe.properties);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import z from "zod";
|
||||
import { AnalyticsEventSchema } from "@suaveplan/analytics-browser/schema";
|
||||
|
||||
// Domain-specific extension — every commerce event additionally carries
|
||||
// a non-empty `cartId`. Composition stays within the Zod model so the
|
||||
// .issues path stays intact when validation fails.
|
||||
const CommerceEventSchema = AnalyticsEventSchema.extend({
|
||||
properties: z
|
||||
.record(z.string(), z.unknown())
|
||||
.refine((p) => typeof p.cartId === "string" && p.cartId.length > 0, {
|
||||
message: "missing cartId",
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `AnalyticsEventSchema: z.ZodType<AnalyticsEvent>` — the raw Zod schema.
|
||||
- `validateAnalyticsEvent(input: unknown): AnalyticsEvent` — parses and returns; throws `AnalyticsBrowserError(INVALID_EVENT)` on failure with `error.context.issues` exposing the Zod issue array.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The schema deliberately uses `z.string().min(1)` rather than `z.string()` for every identifier so a producer cannot bypass validation by sending an empty string. `properties` uses `z.record(z.string(), z.unknown())` rather than a stricter shape because tracker callers attach arbitrary metadata; if a downstream consumer needs a stricter contract they SHOULD `.extend` the schema as shown above. The helper does not log on failure — that is the caller's decision — and never swallows errors silently.
|
||||
Reference in New Issue
Block a user