@reopt-ai/data-contract 0.6.2 → 0.7.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.
Files changed (103) hide show
  1. package/dist/client.cjs +228 -321
  2. package/dist/client.cjs.map +1 -1
  3. package/dist/client.d.cts +57 -71
  4. package/dist/client.d.cts.map +1 -0
  5. package/dist/client.d.ts +57 -71
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +228 -322
  8. package/dist/client.js.map +1 -1
  9. package/dist/control.cjs +158 -54
  10. package/dist/control.cjs.map +1 -1
  11. package/dist/control.d.cts +124 -140
  12. package/dist/control.d.cts.map +1 -0
  13. package/dist/control.d.ts +124 -140
  14. package/dist/control.d.ts.map +1 -0
  15. package/dist/control.js +134 -54
  16. package/dist/control.js.map +1 -1
  17. package/dist/events-BUIeU60t.d.cts +142 -0
  18. package/dist/events-BUIeU60t.d.cts.map +1 -0
  19. package/dist/events-BUIeU60t.d.ts +142 -0
  20. package/dist/events-BUIeU60t.d.ts.map +1 -0
  21. package/dist/events.cjs +110 -15
  22. package/dist/events.cjs.map +1 -1
  23. package/dist/events.d.cts +2 -59
  24. package/dist/events.d.ts +2 -59
  25. package/dist/events.js +101 -15
  26. package/dist/events.js.map +1 -1
  27. package/dist/identity.cjs +150 -55
  28. package/dist/identity.cjs.map +1 -1
  29. package/dist/identity.d.cts +21 -20
  30. package/dist/identity.d.cts.map +1 -0
  31. package/dist/identity.d.ts +21 -20
  32. package/dist/identity.d.ts.map +1 -0
  33. package/dist/identity.js +126 -56
  34. package/dist/identity.js.map +1 -1
  35. package/dist/index.cjs +46 -25
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +37 -54
  38. package/dist/index.d.cts.map +1 -0
  39. package/dist/index.d.ts +37 -54
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +36 -25
  42. package/dist/index.js.map +1 -1
  43. package/dist/ingest.cjs +152 -57
  44. package/dist/ingest.cjs.map +1 -1
  45. package/dist/ingest.d.cts +185 -196
  46. package/dist/ingest.d.cts.map +1 -0
  47. package/dist/ingest.d.ts +185 -196
  48. package/dist/ingest.d.ts.map +1 -0
  49. package/dist/ingest.js +126 -57
  50. package/dist/ingest.js.map +1 -1
  51. package/dist/query.cjs +284 -84
  52. package/dist/query.cjs.map +1 -1
  53. package/dist/query.d.cts +458 -471
  54. package/dist/query.d.cts.map +1 -0
  55. package/dist/query.d.ts +458 -471
  56. package/dist/query.d.ts.map +1 -0
  57. package/dist/query.js +245 -84
  58. package/dist/query.js.map +1 -1
  59. package/dist/report.cjs +104 -74
  60. package/dist/report.cjs.map +1 -1
  61. package/dist/report.d.cts +182 -136
  62. package/dist/report.d.cts.map +1 -0
  63. package/dist/report.d.ts +182 -136
  64. package/dist/report.d.ts.map +1 -0
  65. package/dist/report.js +93 -74
  66. package/dist/report.js.map +1 -1
  67. package/dist/version-B_0qb1_K.cjs +53 -0
  68. package/dist/version-B_0qb1_K.cjs.map +1 -0
  69. package/dist/version-C09Cyf4R.js +12 -0
  70. package/dist/version-C09Cyf4R.js.map +1 -0
  71. package/dist/{version-BANKB6Og.d.ts → version-CGujUGWd.d.cts} +5 -3
  72. package/dist/version-CGujUGWd.d.cts.map +1 -0
  73. package/dist/{version-BANKB6Og.d.cts → version-CGujUGWd.d.ts} +5 -3
  74. package/dist/version-CGujUGWd.d.ts.map +1 -0
  75. package/package.json +69 -28
  76. package/dist/chunk-33BCA2LH.js +0 -53
  77. package/dist/chunk-33BCA2LH.js.map +0 -1
  78. package/dist/chunk-3EEANNYN.cjs +0 -62
  79. package/dist/chunk-3EEANNYN.cjs.map +0 -1
  80. package/dist/chunk-AOS53KAV.cjs +0 -19
  81. package/dist/chunk-AOS53KAV.cjs.map +0 -1
  82. package/dist/chunk-BA52YA7N.cjs +0 -179
  83. package/dist/chunk-BA52YA7N.cjs.map +0 -1
  84. package/dist/chunk-DUJSYMYY.js +0 -179
  85. package/dist/chunk-DUJSYMYY.js.map +0 -1
  86. package/dist/chunk-FMOKJTQD.js +0 -160
  87. package/dist/chunk-FMOKJTQD.js.map +0 -1
  88. package/dist/chunk-FP2X3PRK.js +0 -62
  89. package/dist/chunk-FP2X3PRK.js.map +0 -1
  90. package/dist/chunk-FQSCQSMP.cjs +0 -160
  91. package/dist/chunk-FQSCQSMP.cjs.map +0 -1
  92. package/dist/chunk-FUGY5ANJ.cjs +0 -361
  93. package/dist/chunk-FUGY5ANJ.cjs.map +0 -1
  94. package/dist/chunk-IY4MXH35.js +0 -204
  95. package/dist/chunk-IY4MXH35.js.map +0 -1
  96. package/dist/chunk-L3WJGIKD.js +0 -361
  97. package/dist/chunk-L3WJGIKD.js.map +0 -1
  98. package/dist/chunk-LA5F5KR6.cjs +0 -204
  99. package/dist/chunk-LA5F5KR6.cjs.map +0 -1
  100. package/dist/chunk-YSAEOYPD.cjs +0 -53
  101. package/dist/chunk-YSAEOYPD.cjs.map +0 -1
  102. package/dist/chunk-ZCKVMUIQ.js +0 -19
  103. package/dist/chunk-ZCKVMUIQ.js.map +0 -1
package/dist/client.js CHANGED
@@ -1,336 +1,242 @@
1
- import {
2
- zIngestResponse
3
- } from "./chunk-DUJSYMYY.js";
4
- import {
5
- CONTROL_API_PATHS,
6
- ORG_KEY_HEADER,
7
- PLATFORM_KEY_HEADER,
8
- zCreateOrganizationResponse,
9
- zCreateProjectResponse,
10
- zDeleteProjectResponse,
11
- zEventMetaResponse,
12
- zRotateClientSecretResponse,
13
- zRotateOrganizationKeyResponse,
14
- zUpdateOrganizationQuotaResponse
15
- } from "./chunk-IY4MXH35.js";
16
- import {
17
- QUERY_API_PATHS,
18
- zEventsTimeseriesResponse,
19
- zFunnelResponse,
20
- zRetentionResponse,
21
- zTrafficOverviewResponse,
22
- zTrafficSourcesResponse
23
- } from "./chunk-L3WJGIKD.js";
24
- import {
25
- DataApiError
26
- } from "./chunk-33BCA2LH.js";
27
- import "./chunk-FMOKJTQD.js";
28
- import {
29
- CLIENT_ID_HEADER,
30
- CLIENT_SECRET_HEADER,
31
- CONTRACT_VERSION,
32
- CONTRACT_VERSION_HEADER,
33
- REQUEST_ID_HEADER
34
- } from "./chunk-ZCKVMUIQ.js";
35
- import "./chunk-FP2X3PRK.js";
36
-
37
- // src/client.ts
38
- var TRACK_PATH = "/api/track";
39
- var DEFAULTS = {
40
- timeoutMs: 1e4,
41
- maxRetries: 2,
42
- baseDelayMs: 500,
43
- maxDelayMs: 2e4
1
+ import { i as CONTRACT_VERSION_HEADER, n as CLIENT_SECRET_HEADER, r as CONTRACT_VERSION, t as CLIENT_ID_HEADER } from "./version-C09Cyf4R.js";
2
+ import { DataApiError } from "./index.js";
3
+ import { zIngestResponse } from "./ingest.js";
4
+ import { QUERY_API_PATHS, zEventsTimeseriesResponse, zFunnelResponse, zRetentionResponse, zTrafficOverviewResponse, zTrafficSourcesResponse } from "./query.js";
5
+ import { CONTROL_API_PATHS, ORG_KEY_HEADER, PLATFORM_KEY_HEADER, zCreateOrganizationResponse, zCreateProjectResponse, zDeleteProjectResponse, zEventMetaResponse, zRotateClientSecretResponse, zRotateOrganizationKeyResponse, zUpdateOrganizationQuotaResponse } from "./control.js";
6
+ //#region src/client.ts
7
+ const TRACK_PATH = "/api/track";
8
+ const DEFAULTS = {
9
+ timeoutMs: 1e4,
10
+ maxRetries: 2,
11
+ baseDelayMs: 500,
12
+ maxDelayMs: 2e4
44
13
  };
45
14
  function normalizeBaseUrl(baseUrl) {
46
- return baseUrl.replace(/\/+$/, "");
15
+ return baseUrl.replace(/\/+$/, "");
47
16
  }
48
17
  function parseRetryAfter(header) {
49
- if (!header) return void 0;
50
- const seconds = Number(header);
51
- if (Number.isFinite(seconds) && seconds >= 0) return Math.round(seconds * 1e3);
52
- const at = Date.parse(header);
53
- if (Number.isFinite(at)) return Math.max(0, at - Date.now());
54
- return void 0;
18
+ if (!header) return void 0;
19
+ const seconds = Number(header);
20
+ if (Number.isFinite(seconds) && seconds >= 0) return Math.round(seconds * 1e3);
21
+ const at = Date.parse(header);
22
+ if (Number.isFinite(at)) return Math.max(0, at - Date.now());
55
23
  }
56
24
  function sleep(ms, signal) {
57
- return new Promise((resolve, reject) => {
58
- if (signal?.aborted) {
59
- reject(signal.reason ?? new Error("Aborted"));
60
- return;
61
- }
62
- const timer = setTimeout(() => {
63
- signal?.removeEventListener("abort", onAbort);
64
- resolve();
65
- }, ms);
66
- const onAbort = () => {
67
- clearTimeout(timer);
68
- reject(signal?.reason ?? new Error("Aborted"));
69
- };
70
- signal?.addEventListener("abort", onAbort, { once: true });
71
- });
25
+ return new Promise((resolve, reject) => {
26
+ if (signal?.aborted) {
27
+ reject(signal.reason ?? new Error("Aborted"));
28
+ return;
29
+ }
30
+ const timer = setTimeout(() => {
31
+ signal?.removeEventListener("abort", onAbort);
32
+ resolve();
33
+ }, ms);
34
+ const onAbort = () => {
35
+ clearTimeout(timer);
36
+ reject(signal?.reason ?? new Error("Aborted"));
37
+ };
38
+ signal?.addEventListener("abort", onAbort, { once: true });
39
+ });
72
40
  }
73
41
  function backoffDelay(attempt, retry) {
74
- const exponential = retry.baseDelayMs * 2 ** attempt;
75
- const capped = Math.min(exponential, retry.maxDelayMs);
76
- return Math.round(capped * (0.5 + Math.random() * 0.5));
42
+ const exponential = retry.baseDelayMs * 2 ** attempt;
43
+ const capped = Math.min(exponential, retry.maxDelayMs);
44
+ return Math.round(capped * (.5 + Math.random() * .5));
77
45
  }
78
46
  function toApiError(status, rawBody, retryAfterMs, requestId) {
79
- let parsed;
80
- try {
81
- parsed = JSON.parse(rawBody);
82
- } catch {
83
- return new DataApiError({
84
- message: `reopt-data responded ${status} with a non-JSON body`,
85
- status,
86
- code: status >= 500 ? "internal_error" : "unknown_error",
87
- requestId,
88
- retryAfterMs,
89
- details: rawBody.slice(0, 2e3)
90
- });
91
- }
92
- const body = parsed ?? {};
93
- const code = typeof body.code === "string" ? body.code : status >= 500 ? "internal_error" : "unknown_error";
94
- const message = typeof body.message === "string" && body.message || typeof body.error === "string" && body.error || `reopt-data responded ${status}`;
95
- return new DataApiError({
96
- message,
97
- status,
98
- code,
99
- requestId: (typeof body.requestId === "string" ? body.requestId : void 0) ?? requestId,
100
- retryAfterMs,
101
- details: body.errors ?? void 0
102
- });
47
+ let parsed;
48
+ try {
49
+ parsed = JSON.parse(rawBody);
50
+ } catch {
51
+ return new DataApiError({
52
+ message: `reopt-data responded ${status} with a non-JSON body`,
53
+ status,
54
+ code: status >= 500 ? "internal_error" : "unknown_error",
55
+ requestId,
56
+ retryAfterMs,
57
+ details: rawBody.slice(0, 2e3)
58
+ });
59
+ }
60
+ const body = parsed ?? {};
61
+ const code = typeof body.code === "string" ? body.code : status >= 500 ? "internal_error" : "unknown_error";
62
+ const message = typeof body.message === "string" && body.message || typeof body.error === "string" && body.error || `reopt-data responded ${status}`;
63
+ return new DataApiError({
64
+ message,
65
+ status,
66
+ code,
67
+ requestId: (typeof body.requestId === "string" ? body.requestId : void 0) ?? requestId,
68
+ retryAfterMs,
69
+ details: body.errors ?? void 0
70
+ });
103
71
  }
104
72
  function createDataClient(options) {
105
- const baseUrl = normalizeBaseUrl(options.baseUrl);
106
- const doFetch = options.fetch ?? globalThis.fetch;
107
- if (typeof doFetch !== "function") {
108
- throw new TypeError("createDataClient: no fetch implementation available \u2014 pass options.fetch");
109
- }
110
- const timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;
111
- const retry = {
112
- maxRetries: options.retry?.maxRetries ?? DEFAULTS.maxRetries,
113
- baseDelayMs: options.retry?.baseDelayMs ?? DEFAULTS.baseDelayMs,
114
- maxDelayMs: options.retry?.maxDelayMs ?? DEFAULTS.maxDelayMs,
115
- respectRetryAfter: options.retry?.respectRetryAfter ?? true
116
- };
117
- const userAgent = options.userAgent ? `reopt-data-contract/${CONTRACT_VERSION} ${options.userAgent}` : `reopt-data-contract/${CONTRACT_VERSION}`;
118
- function requireClientCredentials() {
119
- if (!options.clientId || !options.clientSecret) {
120
- throw new DataApiError({
121
- message: "createDataClient was given no client credentials \u2014 pass clientId and clientSecret to use the ingest or query planes",
122
- status: 0,
123
- code: "credentials_missing"
124
- });
125
- }
126
- return { clientId: options.clientId, clientSecret: options.clientSecret };
127
- }
128
- async function requestOnce(method, path, body, extraHeaders, signal) {
129
- const controller = new AbortController();
130
- const timer = setTimeout(
131
- () => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)),
132
- timeoutMs
133
- );
134
- const onCallerAbort = () => controller.abort(signal?.reason ?? new Error("Aborted"));
135
- signal?.addEventListener("abort", onCallerAbort, { once: true });
136
- try {
137
- return await doFetch(`${baseUrl}${path}`, {
138
- method,
139
- headers: {
140
- "content-type": "application/json",
141
- "user-agent": userAgent,
142
- ...options.clientId && options.clientSecret ? { [CLIENT_ID_HEADER]: options.clientId, [CLIENT_SECRET_HEADER]: options.clientSecret } : {},
143
- ...extraHeaders
144
- },
145
- body: JSON.stringify(body),
146
- signal: controller.signal
147
- });
148
- } finally {
149
- clearTimeout(timer);
150
- signal?.removeEventListener("abort", onCallerAbort);
151
- }
152
- }
153
- async function send(method, path, body, parse, extraHeaders = {}, signal) {
154
- let lastError;
155
- for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {
156
- let response;
157
- try {
158
- response = await requestOnce(method, path, body, extraHeaders, signal);
159
- } catch (cause) {
160
- if (signal?.aborted) throw cause;
161
- lastError = new DataApiError({
162
- message: cause instanceof Error ? cause.message : String(cause),
163
- status: 0,
164
- code: "network_error",
165
- details: cause
166
- });
167
- if (attempt < retry.maxRetries) {
168
- await sleep(backoffDelay(attempt, retry), signal);
169
- continue;
170
- }
171
- throw lastError;
172
- }
173
- const requestId = response.headers.get(REQUEST_ID_HEADER) ?? void 0;
174
- const serverContractVersion = response.headers.get(CONTRACT_VERSION_HEADER);
175
- const rawBody = await response.text();
176
- if (serverContractVersion !== CONTRACT_VERSION) {
177
- throw new DataApiError({
178
- message: serverContractVersion ? `reopt-data contract ${serverContractVersion} does not match client contract ${CONTRACT_VERSION}` : "reopt-data response did not declare its contract version",
179
- status: response.status,
180
- code: "contract_mismatch",
181
- requestId,
182
- details: { expected: CONTRACT_VERSION, received: serverContractVersion }
183
- });
184
- }
185
- if (response.ok) {
186
- let json;
187
- try {
188
- json = JSON.parse(rawBody);
189
- } catch (cause) {
190
- throw new DataApiError({
191
- message: "reopt-data returned a 2xx with an unparseable body",
192
- status: response.status,
193
- code: "contract_mismatch",
194
- requestId,
195
- details: cause
196
- });
197
- }
198
- try {
199
- return parse(json);
200
- } catch (cause) {
201
- throw new DataApiError({
202
- message: "reopt-data returned a 2xx that does not match the contract",
203
- status: response.status,
204
- code: "contract_mismatch",
205
- requestId,
206
- details: cause
207
- });
208
- }
209
- }
210
- const retryAfterMs = retry.respectRetryAfter ? parseRetryAfter(response.headers.get("retry-after")) : void 0;
211
- lastError = toApiError(response.status, rawBody, retryAfterMs, requestId);
212
- if (!lastError.retryable || attempt === retry.maxRetries) throw lastError;
213
- await sleep(retryAfterMs ?? backoffDelay(attempt, retry), signal);
214
- }
215
- throw lastError ?? new DataApiError({ message: "reopt-data request failed", status: 0, code: "network_error" });
216
- }
217
- async function post(path, body, parse, signal) {
218
- requireClientCredentials();
219
- return send("POST", path, body, parse, {}, signal);
220
- }
221
- return {
222
- ingest: {
223
- track(events, init) {
224
- return post(TRACK_PATH, events, (value) => zIngestResponse.parse(value), init?.signal);
225
- }
226
- },
227
- query: {
228
- eventsTimeseries(input, init) {
229
- return post(
230
- QUERY_API_PATHS.eventsTimeseries,
231
- input,
232
- (value) => zEventsTimeseriesResponse.parse(value),
233
- init?.signal
234
- );
235
- },
236
- funnel(input, init) {
237
- return post(QUERY_API_PATHS.funnel, input, (value) => zFunnelResponse.parse(value), init?.signal);
238
- },
239
- retention(input, init) {
240
- return post(QUERY_API_PATHS.retention, input, (value) => zRetentionResponse.parse(value), init?.signal);
241
- },
242
- trafficOverview(input, init) {
243
- return post(
244
- QUERY_API_PATHS.trafficOverview,
245
- input,
246
- (value) => zTrafficOverviewResponse.parse(value),
247
- init?.signal
248
- );
249
- },
250
- trafficSources(input, init) {
251
- return post(
252
- QUERY_API_PATHS.trafficSources,
253
- input,
254
- (value) => zTrafficSourcesResponse.parse(value),
255
- init?.signal
256
- );
257
- }
258
- },
259
- control: {
260
- createOrganization(input, auth, init) {
261
- return send(
262
- "POST",
263
- CONTROL_API_PATHS.organizations,
264
- input,
265
- (value) => zCreateOrganizationResponse.parse(value),
266
- { [PLATFORM_KEY_HEADER]: auth.platformKey },
267
- init?.signal
268
- );
269
- },
270
- rotateOrgKey(organizationId, auth, init) {
271
- return send(
272
- "POST",
273
- CONTROL_API_PATHS.organizationKeys(organizationId),
274
- {},
275
- (value) => zRotateOrganizationKeyResponse.parse(value),
276
- { [PLATFORM_KEY_HEADER]: auth.platformKey },
277
- init?.signal
278
- );
279
- },
280
- updateOrganizationQuota(organizationId, input, auth, init) {
281
- return send(
282
- "PATCH",
283
- CONTROL_API_PATHS.organization(organizationId),
284
- input,
285
- (value) => zUpdateOrganizationQuotaResponse.parse(value),
286
- { [PLATFORM_KEY_HEADER]: auth.platformKey },
287
- init?.signal
288
- );
289
- },
290
- createProject(input, auth, init) {
291
- return send(
292
- "POST",
293
- CONTROL_API_PATHS.projects,
294
- input,
295
- (value) => zCreateProjectResponse.parse(value),
296
- { [ORG_KEY_HEADER]: auth.orgKey },
297
- init?.signal
298
- );
299
- },
300
- rotateServerClientSecret(projectId, clientId, auth, init) {
301
- return send(
302
- "POST",
303
- CONTROL_API_PATHS.clientRotate(projectId, clientId),
304
- {},
305
- (value) => zRotateClientSecretResponse.parse(value),
306
- { [ORG_KEY_HEADER]: auth.orgKey },
307
- init?.signal
308
- );
309
- },
310
- deleteProject(projectId, input, auth, init) {
311
- return send(
312
- "DELETE",
313
- CONTROL_API_PATHS.project(projectId),
314
- input,
315
- (value) => zDeleteProjectResponse.parse(value),
316
- { [ORG_KEY_HEADER]: auth.orgKey },
317
- init?.signal
318
- );
319
- },
320
- upsertEventMeta(projectId, name, input, auth, init) {
321
- return send(
322
- "PUT",
323
- CONTROL_API_PATHS.projectEvent(projectId, name),
324
- input,
325
- (value) => zEventMetaResponse.parse(value),
326
- { [ORG_KEY_HEADER]: auth.orgKey },
327
- init?.signal
328
- );
329
- }
330
- }
331
- };
73
+ const baseUrl = normalizeBaseUrl(options.baseUrl);
74
+ const doFetch = options.fetch ?? globalThis.fetch;
75
+ if (typeof doFetch !== "function") throw new TypeError("createDataClient: no fetch implementation available — pass options.fetch");
76
+ const timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;
77
+ const retry = {
78
+ maxRetries: options.retry?.maxRetries ?? DEFAULTS.maxRetries,
79
+ baseDelayMs: options.retry?.baseDelayMs ?? DEFAULTS.baseDelayMs,
80
+ maxDelayMs: options.retry?.maxDelayMs ?? DEFAULTS.maxDelayMs,
81
+ respectRetryAfter: options.retry?.respectRetryAfter ?? true
82
+ };
83
+ const userAgent = options.userAgent ? `reopt-data-contract/${CONTRACT_VERSION} ${options.userAgent}` : `reopt-data-contract/${CONTRACT_VERSION}`;
84
+ function requireClientCredentials() {
85
+ if (!options.clientId || !options.clientSecret) throw new DataApiError({
86
+ message: "createDataClient was given no client credentials — pass clientId and clientSecret to use the ingest or query planes",
87
+ status: 0,
88
+ code: "credentials_missing"
89
+ });
90
+ return {
91
+ clientId: options.clientId,
92
+ clientSecret: options.clientSecret
93
+ };
94
+ }
95
+ async function requestOnce(method, path, body, extraHeaders, signal) {
96
+ const controller = new AbortController();
97
+ const timer = setTimeout(() => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)), timeoutMs);
98
+ const onCallerAbort = () => controller.abort(signal?.reason ?? new Error("Aborted"));
99
+ signal?.addEventListener("abort", onCallerAbort, { once: true });
100
+ try {
101
+ return await doFetch(`${baseUrl}${path}`, {
102
+ method,
103
+ headers: {
104
+ "content-type": "application/json",
105
+ "user-agent": userAgent,
106
+ ...options.clientId && options.clientSecret ? {
107
+ [CLIENT_ID_HEADER]: options.clientId,
108
+ [CLIENT_SECRET_HEADER]: options.clientSecret
109
+ } : {},
110
+ ...extraHeaders
111
+ },
112
+ body: JSON.stringify(body),
113
+ signal: controller.signal
114
+ });
115
+ } finally {
116
+ clearTimeout(timer);
117
+ signal?.removeEventListener("abort", onCallerAbort);
118
+ }
119
+ }
120
+ async function send(method, path, body, parse, extraHeaders = {}, signal) {
121
+ let lastError;
122
+ for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {
123
+ let response;
124
+ try {
125
+ response = await requestOnce(method, path, body, extraHeaders, signal);
126
+ } catch (cause) {
127
+ if (signal?.aborted) throw cause;
128
+ lastError = new DataApiError({
129
+ message: cause instanceof Error ? cause.message : String(cause),
130
+ status: 0,
131
+ code: "network_error",
132
+ details: cause
133
+ });
134
+ if (attempt < retry.maxRetries) {
135
+ await sleep(backoffDelay(attempt, retry), signal);
136
+ continue;
137
+ }
138
+ throw lastError;
139
+ }
140
+ const requestId = response.headers.get("x-request-id") ?? void 0;
141
+ const serverContractVersion = response.headers.get(CONTRACT_VERSION_HEADER);
142
+ const rawBody = await response.text();
143
+ if (serverContractVersion !== "0.7.0") throw new DataApiError({
144
+ message: serverContractVersion ? `reopt-data contract ${serverContractVersion} does not match client contract ${CONTRACT_VERSION}` : "reopt-data response did not declare its contract version",
145
+ status: response.status,
146
+ code: "contract_mismatch",
147
+ requestId,
148
+ details: {
149
+ expected: CONTRACT_VERSION,
150
+ received: serverContractVersion
151
+ }
152
+ });
153
+ if (response.ok) {
154
+ let json;
155
+ try {
156
+ json = JSON.parse(rawBody);
157
+ } catch (cause) {
158
+ throw new DataApiError({
159
+ message: "reopt-data returned a 2xx with an unparseable body",
160
+ status: response.status,
161
+ code: "contract_mismatch",
162
+ requestId,
163
+ details: cause
164
+ });
165
+ }
166
+ try {
167
+ return parse(json);
168
+ } catch (cause) {
169
+ throw new DataApiError({
170
+ message: "reopt-data returned a 2xx that does not match the contract",
171
+ status: response.status,
172
+ code: "contract_mismatch",
173
+ requestId,
174
+ details: cause
175
+ });
176
+ }
177
+ }
178
+ const retryAfterMs = retry.respectRetryAfter ? parseRetryAfter(response.headers.get("retry-after")) : void 0;
179
+ lastError = toApiError(response.status, rawBody, retryAfterMs, requestId);
180
+ if (!lastError.retryable || attempt === retry.maxRetries) throw lastError;
181
+ await sleep(retryAfterMs ?? backoffDelay(attempt, retry), signal);
182
+ }
183
+ throw lastError ?? new DataApiError({
184
+ message: "reopt-data request failed",
185
+ status: 0,
186
+ code: "network_error"
187
+ });
188
+ }
189
+ async function post(path, body, parse, signal) {
190
+ requireClientCredentials();
191
+ return send("POST", path, body, parse, {}, signal);
192
+ }
193
+ return {
194
+ ingest: { track(events, init) {
195
+ return post(TRACK_PATH, events, (value) => zIngestResponse.parse(value), init?.signal);
196
+ } },
197
+ query: {
198
+ eventsTimeseries(input, init) {
199
+ return post(QUERY_API_PATHS.eventsTimeseries, input, (value) => zEventsTimeseriesResponse.parse(value), init?.signal);
200
+ },
201
+ funnel(input, init) {
202
+ return post(QUERY_API_PATHS.funnel, input, (value) => zFunnelResponse.parse(value), init?.signal);
203
+ },
204
+ retention(input, init) {
205
+ return post(QUERY_API_PATHS.retention, input, (value) => zRetentionResponse.parse(value), init?.signal);
206
+ },
207
+ trafficOverview(input, init) {
208
+ return post(QUERY_API_PATHS.trafficOverview, input, (value) => zTrafficOverviewResponse.parse(value), init?.signal);
209
+ },
210
+ trafficSources(input, init) {
211
+ return post(QUERY_API_PATHS.trafficSources, input, (value) => zTrafficSourcesResponse.parse(value), init?.signal);
212
+ }
213
+ },
214
+ control: {
215
+ createOrganization(input, auth, init) {
216
+ return send("POST", CONTROL_API_PATHS.organizations, input, (value) => zCreateOrganizationResponse.parse(value), { [PLATFORM_KEY_HEADER]: auth.platformKey }, init?.signal);
217
+ },
218
+ rotateOrgKey(organizationId, auth, init) {
219
+ return send("POST", CONTROL_API_PATHS.organizationKeys(organizationId), {}, (value) => zRotateOrganizationKeyResponse.parse(value), { [PLATFORM_KEY_HEADER]: auth.platformKey }, init?.signal);
220
+ },
221
+ updateOrganizationQuota(organizationId, input, auth, init) {
222
+ return send("PATCH", CONTROL_API_PATHS.organization(organizationId), input, (value) => zUpdateOrganizationQuotaResponse.parse(value), { [PLATFORM_KEY_HEADER]: auth.platformKey }, init?.signal);
223
+ },
224
+ createProject(input, auth, init) {
225
+ return send("POST", CONTROL_API_PATHS.projects, input, (value) => zCreateProjectResponse.parse(value), { [ORG_KEY_HEADER]: auth.orgKey }, init?.signal);
226
+ },
227
+ rotateServerClientSecret(projectId, clientId, auth, init) {
228
+ return send("POST", CONTROL_API_PATHS.clientRotate(projectId, clientId), {}, (value) => zRotateClientSecretResponse.parse(value), { [ORG_KEY_HEADER]: auth.orgKey }, init?.signal);
229
+ },
230
+ deleteProject(projectId, input, auth, init) {
231
+ return send("DELETE", CONTROL_API_PATHS.project(projectId), input, (value) => zDeleteProjectResponse.parse(value), { [ORG_KEY_HEADER]: auth.orgKey }, init?.signal);
232
+ },
233
+ upsertEventMeta(projectId, name, input, auth, init) {
234
+ return send("PUT", CONTROL_API_PATHS.projectEvent(projectId, name), input, (value) => zEventMetaResponse.parse(value), { [ORG_KEY_HEADER]: auth.orgKey }, init?.signal);
235
+ }
236
+ }
237
+ };
332
238
  }
333
- export {
334
- createDataClient
335
- };
239
+ //#endregion
240
+ export { createDataClient };
241
+
336
242
  //# sourceMappingURL=client.js.map