@mirafive/protocol 0.0.0-stage → 2.0.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/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +349 -0
- package/dist/helpers.d.ts +35 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +496 -0
- package/dist/index.js.map +14 -0
- package/dist/properties.d.ts +13 -0
- package/dist/uuid.d.ts +1 -0
- package/dist/validate.d.ts +14 -0
- package/dist/wire.d.ts +163 -0
- package/fixtures/batches/invalid/amount-not-integer.json +13 -0
- package/fixtures/batches/invalid/currency-not-iso.json +13 -0
- package/fixtures/batches/invalid/event-id-not-uuid.json +9 -0
- package/fixtures/batches/invalid/location-out-of-range.json +15 -0
- package/fixtures/batches/invalid/nested-property.json +14 -0
- package/fixtures/batches/invalid/no-events.json +3 -0
- package/fixtures/batches/invalid/seq-zero.json +10 -0
- package/fixtures/batches/invalid/timestamp-without-offset.json +10 -0
- package/fixtures/batches/invalid/too-many-events.json +509 -0
- package/fixtures/batches/invalid/touchpoint-without-source.json +12 -0
- package/fixtures/batches/invalid/unknown-consent.json +12 -0
- package/fixtures/batches/invalid/unknown-external-id.json +13 -0
- package/fixtures/batches/valid/browser-t0.json +24 -0
- package/fixtures/batches/valid/browser-t1.json +41 -0
- package/fixtures/batches/valid/server-revenue.json +60 -0
- package/fixtures/event-ids.json +9 -0
- package/package.json +63 -4
- package/schema/batch.schema.json +444 -0
package/dist/wire.d.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MIRA FIVE wire format, as plain TypeScript: what every SDK sends to `/v1/batch`.
|
|
3
|
+
*
|
|
4
|
+
* The server validates it with Zod (`packages/schema` in the MIRA FIVE monorepo); `wire.test.ts`
|
|
5
|
+
* proves both describe the same shape, so these types cannot drift from what the ingest accepts.
|
|
6
|
+
* Keeping Zod out of here keeps every SDK free of runtime dependencies.
|
|
7
|
+
*/
|
|
8
|
+
/** The ingest every SDK talks to unless told otherwise. */
|
|
9
|
+
export declare const DEFAULT_HOST = "https://events.mirafive.io";
|
|
10
|
+
/** Limits the ingest enforces. SDKs apply them before sending, so one bad value never costs an event. */
|
|
11
|
+
export declare const LIMITS: {
|
|
12
|
+
readonly eventsPerBatch: 100;
|
|
13
|
+
readonly nameLength: 120;
|
|
14
|
+
readonly propertyKeys: 64;
|
|
15
|
+
readonly propertyKeyLength: 100;
|
|
16
|
+
readonly stringLength: 2048;
|
|
17
|
+
readonly arrayLength: 50;
|
|
18
|
+
readonly urlLength: 4096;
|
|
19
|
+
readonly idLength: 200;
|
|
20
|
+
/** Events older than this are rejected unless they come with a secret key (backfills). */
|
|
21
|
+
readonly maxClientAgeDays: 7;
|
|
22
|
+
};
|
|
23
|
+
/** Event names MIRA defines. Your own event names must not start with `$`. */
|
|
24
|
+
export declare const reservedEvents: readonly ["$pageview", "$screen", "$identify", "$group", "$consent_changed", "$revenue", "$app_install", "$app_open", "$touchpoint", "$engagement", "$outbound_click", "$file_download", "$form_submit"];
|
|
25
|
+
export type ReservedEvent = (typeof reservedEvents)[number];
|
|
26
|
+
/** One purpose's state. `unknown`: the banner is still open, so the event is collected at tier 0. */
|
|
27
|
+
export declare const consentStates: readonly ["granted", "denied", "unknown"];
|
|
28
|
+
export type ConsentState = (typeof consentStates)[number];
|
|
29
|
+
/**
|
|
30
|
+
* The consent an event was collected under. Server SDKs send `not_applicable` for facts only the
|
|
31
|
+
* server knows, such as a paid invoice.
|
|
32
|
+
*/
|
|
33
|
+
export type Consent = {
|
|
34
|
+
analytics: ConsentState;
|
|
35
|
+
marketing?: ConsentState;
|
|
36
|
+
} | "not_applicable";
|
|
37
|
+
/** Property values: scalars, or arrays of scalars. SDKs flatten nested objects to dot keys. */
|
|
38
|
+
export type PropertyValue = string | number | boolean | null | (string | number | boolean)[];
|
|
39
|
+
export type Properties = Record<string, PropertyValue>;
|
|
40
|
+
/** Ids of the same person in other systems, so connectors can link their money to the user. */
|
|
41
|
+
export declare const externalIdTypes: readonly ["stripe_customer", "revenuecat_app_user", "shopify_customer", "shopware_customer"];
|
|
42
|
+
export type ExternalIdType = (typeof externalIdTypes)[number];
|
|
43
|
+
export type ExternalIds = Partial<Record<ExternalIdType, string>>;
|
|
44
|
+
/** What a ledger entry is: one-time money, a subscription payment, or money taken back. */
|
|
45
|
+
export declare const revenueKinds: readonly ["charge", "subscription_payment", "refund", "dispute", "dispute_won"];
|
|
46
|
+
export type RevenueKind = (typeof revenueKinds)[number];
|
|
47
|
+
/** How often a subscription bills: every `interval_count` days, weeks, months or years. */
|
|
48
|
+
export declare const billingIntervals: readonly ["day", "week", "month", "year"];
|
|
49
|
+
export type BillingInterval = (typeof billingIntervals)[number];
|
|
50
|
+
/** Money on an event, in integer minor units. Only secret keys may send it. */
|
|
51
|
+
export interface Revenue {
|
|
52
|
+
/** Gross, tax included. Negative for a refund or dispute. */
|
|
53
|
+
amount: number;
|
|
54
|
+
/** ISO 4217, for example `EUR`. */
|
|
55
|
+
currency: string;
|
|
56
|
+
/** The provider object (`stripe:ch_123`); the ledger keeps one entry per id. */
|
|
57
|
+
entry_id?: string;
|
|
58
|
+
kind?: RevenueKind;
|
|
59
|
+
fee?: number;
|
|
60
|
+
tax?: number;
|
|
61
|
+
refund_of?: string;
|
|
62
|
+
product?: string;
|
|
63
|
+
subscription?: {
|
|
64
|
+
id: string;
|
|
65
|
+
interval?: BillingInterval;
|
|
66
|
+
interval_count?: number;
|
|
67
|
+
period_start?: string;
|
|
68
|
+
period_end?: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Touchpoints that are not a visit: a survey answer, an offline contact, a redeemed code. */
|
|
72
|
+
export declare const touchpointKinds: readonly ["survey", "offline", "code", "custom"];
|
|
73
|
+
export type TouchpointKind = (typeof touchpointKinds)[number];
|
|
74
|
+
/** The kinds a public key (browser, app) may send. The others need a secret key. */
|
|
75
|
+
export declare const publicTouchpointKinds: readonly ["survey"];
|
|
76
|
+
/** MIRA's channels a touchpoint may name. */
|
|
77
|
+
export declare const touchpointChannels: readonly ["paid_search", "paid_social", "paid_other", "organic_search", "organic_social", "ai_assistant", "email", "affiliate", "display", "video", "qr", "app_store", "referral", "direct"];
|
|
78
|
+
export type TouchpointChannel = (typeof touchpointChannels)[number];
|
|
79
|
+
/** What the SDK knows about where and how the event happened. */
|
|
80
|
+
export interface EventContext {
|
|
81
|
+
page?: {
|
|
82
|
+
url?: string;
|
|
83
|
+
referrer?: string;
|
|
84
|
+
title?: string;
|
|
85
|
+
};
|
|
86
|
+
app?: {
|
|
87
|
+
name?: string;
|
|
88
|
+
version?: string;
|
|
89
|
+
build?: string;
|
|
90
|
+
namespace?: string;
|
|
91
|
+
};
|
|
92
|
+
device?: {
|
|
93
|
+
type?: "desktop" | "mobile" | "tablet" | "tv" | "other";
|
|
94
|
+
manufacturer?: string;
|
|
95
|
+
model?: string;
|
|
96
|
+
};
|
|
97
|
+
os?: {
|
|
98
|
+
name?: string;
|
|
99
|
+
version?: string;
|
|
100
|
+
};
|
|
101
|
+
screen?: {
|
|
102
|
+
width?: number;
|
|
103
|
+
height?: number;
|
|
104
|
+
density?: number;
|
|
105
|
+
};
|
|
106
|
+
viewport?: {
|
|
107
|
+
width?: number;
|
|
108
|
+
height?: number;
|
|
109
|
+
};
|
|
110
|
+
locale?: string;
|
|
111
|
+
languages?: string[];
|
|
112
|
+
timezone?: string;
|
|
113
|
+
/** A location the site or app already has. MIRA rounds it to 2 decimals (about 1 km). */
|
|
114
|
+
location?: {
|
|
115
|
+
latitude: number;
|
|
116
|
+
longitude: number;
|
|
117
|
+
};
|
|
118
|
+
library?: {
|
|
119
|
+
name: string;
|
|
120
|
+
version: string;
|
|
121
|
+
};
|
|
122
|
+
/** Server SDKs only: the end user's IP and user agent, for geo and device. Never stored. */
|
|
123
|
+
ip?: string;
|
|
124
|
+
user_agent?: string;
|
|
125
|
+
}
|
|
126
|
+
/** One event on the wire. */
|
|
127
|
+
export interface WireEvent {
|
|
128
|
+
/** UUIDv7 made by the SDK. The same id twice is one event. */
|
|
129
|
+
event_id: string;
|
|
130
|
+
type: "track" | "page" | "screen" | "identify" | "group";
|
|
131
|
+
event: string;
|
|
132
|
+
timestamp?: string;
|
|
133
|
+
/** Only with analytics consent. */
|
|
134
|
+
anonymous_id?: string;
|
|
135
|
+
user_id?: string;
|
|
136
|
+
session_id?: string;
|
|
137
|
+
group_id?: string;
|
|
138
|
+
properties?: Properties;
|
|
139
|
+
traits?: Properties;
|
|
140
|
+
external_ids?: ExternalIds;
|
|
141
|
+
revenue?: Revenue;
|
|
142
|
+
context?: EventContext;
|
|
143
|
+
consent?: Consent;
|
|
144
|
+
}
|
|
145
|
+
/** A batch, to `/v1/batch` (JSON) or `/v1/p` (`text/plain`, from `sendBeacon`). */
|
|
146
|
+
export interface WireBatch {
|
|
147
|
+
key?: string;
|
|
148
|
+
sent_at?: string;
|
|
149
|
+
/** A random id per SDK instance, in memory only. */
|
|
150
|
+
stream?: string;
|
|
151
|
+
/** The stream's batch number from 1. A retry resends the same number. */
|
|
152
|
+
seq?: number;
|
|
153
|
+
events: WireEvent[];
|
|
154
|
+
}
|
|
155
|
+
/** The ingest's answer. Per-event problems are listed, never thrown. */
|
|
156
|
+
export interface BatchResult {
|
|
157
|
+
accepted: number;
|
|
158
|
+
duplicates: number;
|
|
159
|
+
rejected: {
|
|
160
|
+
index: number;
|
|
161
|
+
reason: string;
|
|
162
|
+
}[];
|
|
163
|
+
}
|