@reopt-ai/data-contract 0.1.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.
@@ -0,0 +1,270 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `POST /api/track` — the ingest contract.
5
+ *
6
+ * The request shape is shared by both credential modes. The *response* shape
7
+ * is where server-ingest differs: it reports per-event rejections instead of
8
+ * failing a whole batch, because a forwarder that stalls on one malformed row
9
+ * stops forwarding forever.
10
+ *
11
+ * Absorbed from the former internal `@reopt/ingest-contract`; that package is
12
+ * now a deprecated re-export of this module.
13
+ */
14
+
15
+ /** Event names the pipeline reserves for its own session bookkeeping. */
16
+ declare const RESERVED_EVENT_NAMES: readonly ["session_start", "session_end", "screen_view"];
17
+ /** Hard cap enforced by the route before the body is even parsed. */
18
+ declare const MAX_TRACK_PAYLOAD_BYTES = 512000;
19
+ declare const zTrackPayload: z.ZodObject<{
20
+ name: z.ZodString;
21
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
22
+ profileId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
23
+ }, z.core.$strip>;
24
+ declare const zIdentifyPayload: z.ZodObject<{
25
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
26
+ firstName: z.ZodOptional<z.ZodString>;
27
+ lastName: z.ZodOptional<z.ZodString>;
28
+ email: z.ZodOptional<z.ZodEmail>;
29
+ avatar: z.ZodOptional<z.ZodURL>;
30
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ }, z.core.$strip>;
32
+ declare const zIncrementPayload: z.ZodObject<{
33
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
34
+ property: z.ZodString;
35
+ value: z.ZodOptional<z.ZodNumber>;
36
+ }, z.core.$strip>;
37
+ declare const zDecrementPayload: z.ZodObject<{
38
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
39
+ property: z.ZodString;
40
+ value: z.ZodOptional<z.ZodNumber>;
41
+ }, z.core.$strip>;
42
+ declare const zTrackHandlerPayload: z.ZodDiscriminatedUnion<[z.ZodObject<{
43
+ eventId: z.ZodUUID;
44
+ timestamp: z.ZodNumber;
45
+ type: z.ZodLiteral<"track">;
46
+ payload: z.ZodObject<{
47
+ name: z.ZodString;
48
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
49
+ profileId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
50
+ }, z.core.$strip>;
51
+ }, z.core.$strip>, z.ZodObject<{
52
+ eventId: z.ZodUUID;
53
+ timestamp: z.ZodNumber;
54
+ type: z.ZodLiteral<"identify">;
55
+ payload: z.ZodObject<{
56
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
57
+ firstName: z.ZodOptional<z.ZodString>;
58
+ lastName: z.ZodOptional<z.ZodString>;
59
+ email: z.ZodOptional<z.ZodEmail>;
60
+ avatar: z.ZodOptional<z.ZodURL>;
61
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ }, z.core.$strip>;
63
+ }, z.core.$strip>, z.ZodObject<{
64
+ eventId: z.ZodUUID;
65
+ timestamp: z.ZodNumber;
66
+ type: z.ZodLiteral<"increment">;
67
+ payload: z.ZodObject<{
68
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
69
+ property: z.ZodString;
70
+ value: z.ZodOptional<z.ZodNumber>;
71
+ }, z.core.$strip>;
72
+ }, z.core.$strip>, z.ZodObject<{
73
+ eventId: z.ZodUUID;
74
+ timestamp: z.ZodNumber;
75
+ type: z.ZodLiteral<"decrement">;
76
+ payload: z.ZodObject<{
77
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
78
+ property: z.ZodString;
79
+ value: z.ZodOptional<z.ZodNumber>;
80
+ }, z.core.$strip>;
81
+ }, z.core.$strip>], "type">;
82
+ type ITrackPayload = z.infer<typeof zTrackPayload>;
83
+ type IIdentifyPayload = z.infer<typeof zIdentifyPayload>;
84
+ type IIncrementPayload = z.infer<typeof zIncrementPayload>;
85
+ type IDecrementPayload = z.infer<typeof zDecrementPayload>;
86
+ type ITrackHandlerPayload = z.infer<typeof zTrackHandlerPayload>;
87
+ /**
88
+ * Decided by the credential presented, never by a header the caller sets:
89
+ * `reopt-write-key` alone → `browser`, `reopt-client-id` + `reopt-client-secret`
90
+ * → `server`. A separate mode header could disagree with the credential; this
91
+ * cannot.
92
+ *
93
+ * `browser` keeps the 5-second click dedup and device-scoped sessions.
94
+ * `server` drops both and relies solely on `eventId` idempotency — a server
95
+ * batch legitimately contains the same event name many times within one second,
96
+ * and its "device" is a process, not a person.
97
+ */
98
+ declare const INGEST_MODES: readonly ["browser", "server"];
99
+ declare const zIngestMode: z.ZodEnum<{
100
+ browser: "browser";
101
+ server: "server";
102
+ }>;
103
+ type IngestMode = z.infer<typeof zIngestMode>;
104
+ /**
105
+ * Why a single event in a batch was dropped. These are permanent: re-sending
106
+ * the same row produces the same rejection, so a forwarder should count it as
107
+ * skipped and advance its cursor rather than retry.
108
+ */
109
+ declare const INGEST_REJECTION_REASONS: readonly ["validation_failed", "reserved_name", "duplicate_in_batch"];
110
+ declare const zIngestRejectionReason: z.ZodEnum<{
111
+ validation_failed: "validation_failed";
112
+ reserved_name: "reserved_name";
113
+ duplicate_in_batch: "duplicate_in_batch";
114
+ }>;
115
+ type IngestRejectionReason = z.infer<typeof zIngestRejectionReason>;
116
+ declare const zIngestRejection: z.ZodObject<{
117
+ eventId: z.ZodString;
118
+ index: z.ZodNumber;
119
+ reason: z.ZodEnum<{
120
+ validation_failed: "validation_failed";
121
+ reserved_name: "reserved_name";
122
+ duplicate_in_batch: "duplicate_in_batch";
123
+ }>;
124
+ message: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strip>;
126
+ type IngestRejection = z.infer<typeof zIngestRejection>;
127
+ /** 200 — accepted and handed to the materialize queue. */
128
+ declare const zIngestOkResponse: z.ZodObject<{
129
+ queued: z.ZodBoolean;
130
+ accepted: z.ZodNumber;
131
+ duplicates: z.ZodNumber;
132
+ rejected: z.ZodArray<z.ZodObject<{
133
+ eventId: z.ZodString;
134
+ index: z.ZodNumber;
135
+ reason: z.ZodEnum<{
136
+ validation_failed: "validation_failed";
137
+ reserved_name: "reserved_name";
138
+ duplicate_in_batch: "duplicate_in_batch";
139
+ }>;
140
+ message: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strip>>;
142
+ status: z.ZodLiteral<"ok">;
143
+ requestId: z.ZodString;
144
+ mode: z.ZodEnum<{
145
+ browser: "browser";
146
+ server: "server";
147
+ }>;
148
+ }, z.core.$strip>;
149
+ /**
150
+ * 202 — raw events landed, but enqueueing the materialize task failed. No data
151
+ * is lost: the `replay-unmaterialized` cron picks these up. A forwarder should
152
+ * treat this as success and advance its cursor. Carries the same counts as 200
153
+ * so the reconciliation below works here too.
154
+ */
155
+ declare const zIngestAcceptedResponse: z.ZodObject<{
156
+ backgroundQueued: z.ZodLiteral<false>;
157
+ replay: z.ZodLiteral<"unmaterialized-raw-events">;
158
+ accepted: z.ZodNumber;
159
+ duplicates: z.ZodNumber;
160
+ rejected: z.ZodArray<z.ZodObject<{
161
+ eventId: z.ZodString;
162
+ index: z.ZodNumber;
163
+ reason: z.ZodEnum<{
164
+ validation_failed: "validation_failed";
165
+ reserved_name: "reserved_name";
166
+ duplicate_in_batch: "duplicate_in_batch";
167
+ }>;
168
+ message: z.ZodOptional<z.ZodString>;
169
+ }, z.core.$strip>>;
170
+ status: z.ZodLiteral<"accepted">;
171
+ requestId: z.ZodString;
172
+ mode: z.ZodEnum<{
173
+ browser: "browser";
174
+ server: "server";
175
+ }>;
176
+ }, z.core.$strip>;
177
+ declare const zIngestResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
178
+ queued: z.ZodBoolean;
179
+ accepted: z.ZodNumber;
180
+ duplicates: z.ZodNumber;
181
+ rejected: z.ZodArray<z.ZodObject<{
182
+ eventId: z.ZodString;
183
+ index: z.ZodNumber;
184
+ reason: z.ZodEnum<{
185
+ validation_failed: "validation_failed";
186
+ reserved_name: "reserved_name";
187
+ duplicate_in_batch: "duplicate_in_batch";
188
+ }>;
189
+ message: z.ZodOptional<z.ZodString>;
190
+ }, z.core.$strip>>;
191
+ status: z.ZodLiteral<"ok">;
192
+ requestId: z.ZodString;
193
+ mode: z.ZodEnum<{
194
+ browser: "browser";
195
+ server: "server";
196
+ }>;
197
+ }, z.core.$strip>, z.ZodObject<{
198
+ backgroundQueued: z.ZodLiteral<false>;
199
+ replay: z.ZodLiteral<"unmaterialized-raw-events">;
200
+ accepted: z.ZodNumber;
201
+ duplicates: z.ZodNumber;
202
+ rejected: z.ZodArray<z.ZodObject<{
203
+ eventId: z.ZodString;
204
+ index: z.ZodNumber;
205
+ reason: z.ZodEnum<{
206
+ validation_failed: "validation_failed";
207
+ reserved_name: "reserved_name";
208
+ duplicate_in_batch: "duplicate_in_batch";
209
+ }>;
210
+ message: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>>;
212
+ status: z.ZodLiteral<"accepted">;
213
+ requestId: z.ZodString;
214
+ mode: z.ZodEnum<{
215
+ browser: "browser";
216
+ server: "server";
217
+ }>;
218
+ }, z.core.$strip>], "status">;
219
+ type IngestOkResponse = z.infer<typeof zIngestOkResponse>;
220
+ type IngestAcceptedResponse = z.infer<typeof zIngestAcceptedResponse>;
221
+ type IngestResponse = z.infer<typeof zIngestResponse>;
222
+ /**
223
+ * The reconciliation a forwarder runs on every 2xx:
224
+ *
225
+ * accepted + duplicates + rejected.length === events sent
226
+ *
227
+ * A mismatch means the server silently dropped something, which is exactly the
228
+ * failure mode this contract exists to make impossible to miss.
229
+ */
230
+ declare function reconcileIngestResponse(response: IngestResponse, sentCount: number): boolean;
231
+ /**
232
+ * Stable machine-readable codes. Branch on these, never on `error`/`message`,
233
+ * which are prose and may be reworded.
234
+ */
235
+ declare const INGEST_ERROR_CODES: readonly ["unauthorized", "invalid_json", "payload_too_large", "empty_batch", "alias_unsupported", "project_without_organization", "validation_failed", "rate_limited", "quota_exceeded", "internal_error"];
236
+ declare const zIngestErrorCode: z.ZodEnum<{
237
+ unauthorized: "unauthorized";
238
+ validation_failed: "validation_failed";
239
+ rate_limited: "rate_limited";
240
+ internal_error: "internal_error";
241
+ invalid_json: "invalid_json";
242
+ payload_too_large: "payload_too_large";
243
+ empty_batch: "empty_batch";
244
+ alias_unsupported: "alias_unsupported";
245
+ project_without_organization: "project_without_organization";
246
+ quota_exceeded: "quota_exceeded";
247
+ }>;
248
+ type IngestErrorCode = z.infer<typeof zIngestErrorCode>;
249
+ declare const zIngestError: z.ZodObject<{
250
+ status: z.ZodNumber;
251
+ code: z.ZodEnum<{
252
+ unauthorized: "unauthorized";
253
+ validation_failed: "validation_failed";
254
+ rate_limited: "rate_limited";
255
+ internal_error: "internal_error";
256
+ invalid_json: "invalid_json";
257
+ payload_too_large: "payload_too_large";
258
+ empty_batch: "empty_batch";
259
+ alias_unsupported: "alias_unsupported";
260
+ project_without_organization: "project_without_organization";
261
+ quota_exceeded: "quota_exceeded";
262
+ }>;
263
+ error: z.ZodString;
264
+ message: z.ZodOptional<z.ZodString>;
265
+ errors: z.ZodOptional<z.ZodUnknown>;
266
+ requestId: z.ZodOptional<z.ZodString>;
267
+ }, z.core.$strip>;
268
+ type IngestError = z.infer<typeof zIngestError>;
269
+
270
+ export { type IDecrementPayload, type IIdentifyPayload, type IIncrementPayload, INGEST_ERROR_CODES, INGEST_MODES, INGEST_REJECTION_REASONS, type ITrackHandlerPayload, type ITrackPayload, type IngestAcceptedResponse, type IngestError, type IngestErrorCode, type IngestMode, type IngestOkResponse, type IngestRejection, type IngestRejectionReason, type IngestResponse, MAX_TRACK_PAYLOAD_BYTES, RESERVED_EVENT_NAMES, reconcileIngestResponse, zDecrementPayload, zIdentifyPayload, zIncrementPayload, zIngestAcceptedResponse, zIngestError, zIngestErrorCode, zIngestMode, zIngestOkResponse, zIngestRejection, zIngestRejectionReason, zIngestResponse, zTrackHandlerPayload, zTrackPayload };
package/dist/ingest.js ADDED
@@ -0,0 +1,43 @@
1
+ import {
2
+ INGEST_ERROR_CODES,
3
+ INGEST_MODES,
4
+ INGEST_REJECTION_REASONS,
5
+ MAX_TRACK_PAYLOAD_BYTES,
6
+ RESERVED_EVENT_NAMES,
7
+ reconcileIngestResponse,
8
+ zDecrementPayload,
9
+ zIdentifyPayload,
10
+ zIncrementPayload,
11
+ zIngestAcceptedResponse,
12
+ zIngestError,
13
+ zIngestErrorCode,
14
+ zIngestMode,
15
+ zIngestOkResponse,
16
+ zIngestRejection,
17
+ zIngestRejectionReason,
18
+ zIngestResponse,
19
+ zTrackHandlerPayload,
20
+ zTrackPayload
21
+ } from "./chunk-FRJK7OCQ.js";
22
+ export {
23
+ INGEST_ERROR_CODES,
24
+ INGEST_MODES,
25
+ INGEST_REJECTION_REASONS,
26
+ MAX_TRACK_PAYLOAD_BYTES,
27
+ RESERVED_EVENT_NAMES,
28
+ reconcileIngestResponse,
29
+ zDecrementPayload,
30
+ zIdentifyPayload,
31
+ zIncrementPayload,
32
+ zIngestAcceptedResponse,
33
+ zIngestError,
34
+ zIngestErrorCode,
35
+ zIngestMode,
36
+ zIngestOkResponse,
37
+ zIngestRejection,
38
+ zIngestRejectionReason,
39
+ zIngestResponse,
40
+ zTrackHandlerPayload,
41
+ zTrackPayload
42
+ };
43
+ //# sourceMappingURL=ingest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/query.cjs ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+ var _chunkDHSMXB54cjs = require('./chunk-DHSMXB54.cjs');
27
+
28
+
29
+
30
+ var _chunkZQVRSCTWcjs = require('./chunk-ZQVRSCTW.cjs');
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+ exports.QUERY_API_PATHS = _chunkDHSMXB54cjs.QUERY_API_PATHS; exports.QUERY_ERROR_CODES = _chunkDHSMXB54cjs.QUERY_ERROR_CODES; exports.isValidTimeZone = _chunkDHSMXB54cjs.isValidTimeZone; exports.zChannelFilter = _chunkDHSMXB54cjs.zChannelFilter; exports.zDate = _chunkZQVRSCTWcjs.zDate; exports.zEventsTimeseriesData = _chunkDHSMXB54cjs.zEventsTimeseriesData; exports.zEventsTimeseriesInput = _chunkDHSMXB54cjs.zEventsTimeseriesInput; exports.zEventsTimeseriesResponse = _chunkDHSMXB54cjs.zEventsTimeseriesResponse; exports.zFunnelData = _chunkDHSMXB54cjs.zFunnelData; exports.zFunnelInput = _chunkDHSMXB54cjs.zFunnelInput; exports.zFunnelResponse = _chunkDHSMXB54cjs.zFunnelResponse; exports.zFunnelStep = _chunkDHSMXB54cjs.zFunnelStep; exports.zGranularity = _chunkDHSMXB54cjs.zGranularity; exports.zInstant = _chunkZQVRSCTWcjs.zInstant; exports.zQueryEnvelope = _chunkDHSMXB54cjs.zQueryEnvelope; exports.zQueryError = _chunkDHSMXB54cjs.zQueryError; exports.zQueryErrorCode = _chunkDHSMXB54cjs.zQueryErrorCode; exports.zQueryMeta = _chunkDHSMXB54cjs.zQueryMeta; exports.zRetentionCell = _chunkDHSMXB54cjs.zRetentionCell; exports.zRetentionData = _chunkDHSMXB54cjs.zRetentionData; exports.zRetentionInput = _chunkDHSMXB54cjs.zRetentionInput; exports.zRetentionInterval = _chunkDHSMXB54cjs.zRetentionInterval; exports.zRetentionResponse = _chunkDHSMXB54cjs.zRetentionResponse; exports.zTimeseriesBreakdown = _chunkDHSMXB54cjs.zTimeseriesBreakdown; exports.zTimeseriesPoint = _chunkDHSMXB54cjs.zTimeseriesPoint; exports.zTimezone = _chunkDHSMXB54cjs.zTimezone;
59
+ //# sourceMappingURL=query.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/query.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,uhDAAC","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/query.cjs"}