@reopt-ai/data-contract 0.1.0 → 0.2.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/dist/chunk-2SJPZP2D.js +178 -0
- package/dist/chunk-2SJPZP2D.js.map +1 -0
- package/dist/{chunk-ZQVRSCTW.cjs → chunk-CSTC3ADG.cjs} +2 -2
- package/dist/{chunk-IAOPUBJU.js.map → chunk-CSTC3ADG.cjs.map} +1 -1
- package/dist/{chunk-DHSMXB54.cjs → chunk-GCLUMVPA.cjs} +9 -9
- package/dist/{chunk-DHSMXB54.cjs.map → chunk-GCLUMVPA.cjs.map} +1 -1
- package/dist/{chunk-IAOPUBJU.js → chunk-IKOEYZVT.js} +2 -2
- package/dist/chunk-IKOEYZVT.js.map +1 -0
- package/dist/chunk-LBSBZO7O.cjs +178 -0
- package/dist/chunk-LBSBZO7O.cjs.map +1 -0
- package/dist/{chunk-SJYY42BP.js → chunk-SC7TFGTO.js} +2 -2
- package/dist/client.cjs +97 -20
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +27 -1
- package/dist/client.d.ts +27 -1
- package/dist/client.js +84 -7
- package/dist/client.js.map +1 -1
- package/dist/control.cjs +45 -0
- package/dist/control.cjs.map +1 -0
- package/dist/control.d.cts +181 -0
- package/dist/control.d.ts +181 -0
- package/dist/control.js +45 -0
- package/dist/control.js.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/ingest.d.cts +6 -6
- package/dist/ingest.d.ts +6 -6
- package/dist/query.cjs +3 -3
- package/dist/query.d.cts +6 -6
- package/dist/query.d.ts +6 -6
- package/dist/query.js +2 -2
- package/package.json +16 -11
- package/dist/chunk-ZQVRSCTW.cjs.map +0 -1
- /package/dist/{chunk-SJYY42BP.js.map → chunk-SC7TFGTO.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/chunk-LBSBZO7O.cjs","../src/control.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACSA,0BAAkB;AAIX,IAAM,oBAAA,EAAsB,oBAAA;AAC5B,IAAM,eAAA,EAAiB,eAAA;AASvB,IAAM,YAAA,EAAc,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA;AAI7C,IAAM,yBAAA,EAA2B,MAAA,CAAE,MAAA,CAAO;AAAA,EAC/C,UAAA,EAAY,WAAA;AAAA,EACZ,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA;AAAA,EAC/B,IAAA,EAAM,MAAA,CACH,MAAA,CAAO,CAAA,CACP,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,GAAG,CAAA,CACP,KAAA,CAAM,cAAA,EAAgB,4CAA4C,CAAA,CAClE,QAAA,CAAS,CAAA;AAAA,EACZ,iBAAA,EAAmB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC3D,kBAAA,EAAoB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAA,CAAE,QAAA,CAAS;AAC9D,CAAC,CAAA;AAGM,IAAM,cAAA,EAAgB,MAAA,CAAE,MAAA,CAAO;AAAA,EACpC,EAAA,EAAI,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACb,UAAA,EAAY,WAAA;AAAA,EACZ,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACf,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACf,iBAAA,EAAmB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA;AAAA,EAClC,kBAAA,EAAoB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI;AACrC,CAAC,CAAA;AAEM,IAAM,4BAAA,EAA8B,MAAA,CAAE,MAAA,CAAO;AAAA;AAAA,EAElD,OAAA,EAAS,MAAA,CAAE,OAAA,CAAQ,CAAA;AAAA,EACnB,YAAA,EAAc,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQd,MAAA,EAAQ,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AAC9B,CAAC,CAAA;AAGM,IAAM,+BAAA,EAAiC,MAAA,CAAE,MAAA,CAAO;AAAA,EACrD,cAAA,EAAgB,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACzB,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,EAEpB,MAAA,EAAQ,MAAA,CAAE,MAAA,CAAO;AACnB,CAAC,CAAA;AAGM,IAAM,8BAAA,EAAgC,MAAA,CAC1C,MAAA,CAAO;AAAA,EACN,iBAAA,EAAmB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC3D,kBAAA,EAAoB,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAA,CAAE,QAAA,CAAS;AAC9D,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,KAAA,EAAA,GAAU,KAAA,CAAM,kBAAA,IAAsB,KAAA,EAAA,GAAa,KAAA,CAAM,mBAAA,IAAuB,KAAA,CAAA,EAAW;AAAA,EAClG,OAAA,EAAS;AACX,CAAC,CAAA;AAGI,IAAM,iCAAA,EAAmC,MAAA,CAAE,MAAA,CAAO,EAAE,YAAA,EAAc,cAAc,CAAC,CAAA;AAKjF,IAAM,oBAAA,EAAsB,MAAA,CAAE,MAAA,CAAO;AAAA,EAC1C,UAAA,EAAY,WAAA;AAAA,EACZ,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA;AAAA,EAC/B,MAAA,EAAQ,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA;AAAA,EAErC,QAAA,EAAU,2BAAA,CAAU,QAAA,CAAS,CAAA;AAAA,EAC7B,aAAA,EAAe,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,IAAI,CAAA,CAAE,QAAA,CAAS;AAC5D,CAAC,CAAA;AAGM,IAAM,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO;AAAA,EAC/B,EAAA,EAAI,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACb,UAAA,EAAY,WAAA;AAAA,EACZ,cAAA,EAAgB,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACzB,IAAA,EAAM,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,EAEf,QAAA,EAAU,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACnB,aAAA,EAAe,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA,CAAE,QAAA,CAAS;AAC3C,CAAC,CAAA;AAEM,IAAM,uBAAA,EAAyB,MAAA,CAAE,MAAA,CAAO;AAAA,EAC7C,OAAA,EAAS,MAAA,CAAE,OAAA,CAAQ,CAAA;AAAA,EACnB,OAAA,EAAS,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,OAAA,EAAS,MAAA,CAAE,MAAA,CAAO;AAAA,IAChB,OAAA,EAAS,MAAA,CAAE,MAAA,CAAO;AAAA,MAChB,EAAA,EAAI,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,MAEb,QAAA,EAAU,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,MACnB,MAAA,EAAQ,MAAA,CAAE,KAAA,CAAM,MAAA,CAAE,MAAA,CAAO,CAAC;AAAA,IAC5B,CAAC,CAAA;AAAA,IACD,MAAA,EAAQ,MAAA,CAAE,MAAA,CAAO;AAAA,MACf,EAAA,EAAI,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,MAEb,YAAA,EAAc,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,MAClC,MAAA,EAAQ,MAAA,CAAE,KAAA,CAAM,MAAA,CAAE,MAAA,CAAO,CAAC;AAAA,IAC5B,CAAC;AAAA,EACH,CAAC;AACH,CAAC,CAAA;AAGM,IAAM,4BAAA,EAA8B,MAAA,CAAE,MAAA,CAAO;AAAA,EAClD,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EACpB,QAAA,EAAU,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,EAEnB,YAAA,EAAc,MAAA,CAAE,MAAA,CAAO;AACzB,CAAC,CAAA;AAGM,IAAM,oBAAA,EAAsB,MAAA,CAAE,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM1C,KAAA,EAAO,MAAA,CAAE,OAAA,CAAQ,IAAI,CAAA;AAAA;AAAA,EAErB,UAAA,EAAY;AACd,CAAC,CAAA;AAGM,IAAM,uBAAA,EAAyB,MAAA,CAAE,MAAA,CAAO;AAAA,EAC7C,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA;AAAA,EAEpB,KAAA,EAAO,MAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,gBAAgB,CAAC,CAAA;AAAA;AAAA,EAE1C,SAAA,EAAW,0BAAA,CAAS,QAAA,CAAS;AAC/B,CAAC,CAAA;AAKM,IAAM,oBAAA,EAAsB;AAAA;AAAA,EAEjC,cAAA;AAAA;AAAA,EAEA,6BAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBAAA;AAAA;AAAA,EAEA,8BAAA;AAAA;AAAA,EAEA,WAAA;AAAA;AAAA,EAEA,mBAAA;AAAA;AAAA,EAEA,cAAA;AAAA;AAAA,EAEA;AACF,CAAA;AACO,IAAM,kBAAA,EAAoB,MAAA,CAAE,IAAA,CAAK,mBAAmB,CAAA;AAGpD,IAAM,cAAA,EAAgB,MAAA,CAAE,MAAA,CAAO;AAAA,EACpC,MAAA,EAAQ,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,GAAA,CAAI,CAAA;AAAA,EACvB,IAAA,EAAM,iBAAA;AAAA,EACN,KAAA,EAAO,MAAA,CAAE,MAAA,CAAO,CAAA;AAAA,EAChB,OAAA,EAAS,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC7B,MAAA,EAAQ,MAAA,CAAE,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,CAAA;AAAA,EAC7B,SAAA,EAAW,MAAA,CAAE,MAAA,CAAO,CAAA,CAAE,QAAA,CAAS;AACjC,CAAC,CAAA;AAIM,IAAM,kBAAA,EAAoB;AAAA,EAC/B,aAAA,EAAe,uBAAA;AAAA,EACf,YAAA,EAAc,CAAC,EAAA,EAAA,GAAe,CAAA,sBAAA,EAAyB,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA;AACC,EAAA;AACpE,EAAA;AACyD,EAAA;AAE7C,EAAA;AACxB;AD5DwE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/chunk-LBSBZO7O.cjs","sourcesContent":[null,"/**\n * `POST /api/v1/organizations` · `/api/v1/projects` and friends — the\n * provisioning contract.\n *\n * A project-scoped client credential cannot authenticate the creation of the\n * project it is scoped to, and an organization key cannot authenticate the\n * creation of its own organization. So provisioning runs on two credentials\n * above the client one: a platform key that creates organizations and writes\n * quotas, and an organization key that creates and deletes projects inside one\n * organization.\n *\n * Quota writes sit with the platform key on purpose. Organization keys are held\n * one-per-workspace by the caller and so have a wide exposure surface; a leaked\n * one that could raise its own limits would turn a credential leak into an\n * unbounded bill.\n */\nimport { z } from \"zod\";\nimport { zInstant } from \"./index.js\";\nimport { zTimezone } from \"./query.js\";\n\nexport const PLATFORM_KEY_HEADER = \"reopt-platform-key\";\nexport const ORG_KEY_HEADER = \"reopt-org-key\";\n\n/**\n * The caller's own id for the thing being provisioned.\n *\n * Preferred over an `Idempotency-Key` header because this domain has a real\n * natural key — the caller already has a stable id for the workspace or brand —\n * and a header would make the caller store a second one just to retry safely.\n */\nexport const zExternalId = z.string().min(1).max(191);\n\n// ─── Organizations ──────────────────────────────────────────────────────────\n\nexport const zCreateOrganizationInput = z.object({\n externalId: zExternalId,\n name: z.string().min(1).max(200),\n slug: z\n .string()\n .min(1)\n .max(100)\n .regex(/^[a-z0-9-]+$/, \"lowercase letters, digits and hyphens only\")\n .optional(),\n monthlyEventQuota: z.number().int().nonnegative().optional(),\n monthlyCreditQuota: z.number().int().nonnegative().optional(),\n});\nexport type CreateOrganizationInput = z.input<typeof zCreateOrganizationInput>;\n\nexport const zOrganization = z.object({\n id: z.string(),\n externalId: zExternalId,\n name: z.string(),\n slug: z.string(),\n monthlyEventQuota: z.number().int(),\n monthlyCreditQuota: z.number().int(),\n});\n\nexport const zCreateOrganizationResponse = z.object({\n /** `false` when this externalId already had an organization. */\n created: z.boolean(),\n organization: zOrganization,\n /**\n * Plaintext, returned here and nowhere else.\n *\n * Absent when `created` is `false`: re-issuing on every retry would let a\n * retry quietly multiply live credentials. A caller that lost the key rotates\n * instead — see `POST /api/v1/organizations/{id}/keys`.\n */\n orgKey: z.string().optional(),\n});\nexport type CreateOrganizationResponse = z.infer<typeof zCreateOrganizationResponse>;\n\nexport const zRotateOrganizationKeyResponse = z.object({\n organizationId: z.string(),\n keyPrefix: z.string(),\n /** Plaintext, returned once. Every previously issued key is revoked immediately. */\n orgKey: z.string(),\n});\nexport type RotateOrganizationKeyResponse = z.infer<typeof zRotateOrganizationKeyResponse>;\n\nexport const zUpdateOrganizationQuotaInput = z\n .object({\n monthlyEventQuota: z.number().int().nonnegative().optional(),\n monthlyCreditQuota: z.number().int().nonnegative().optional(),\n })\n .refine((value) => value.monthlyEventQuota !== undefined || value.monthlyCreditQuota !== undefined, {\n message: \"at least one quota must be given\",\n });\nexport type UpdateOrganizationQuotaInput = z.input<typeof zUpdateOrganizationQuotaInput>;\n\nexport const zUpdateOrganizationQuotaResponse = z.object({ organization: zOrganization });\nexport type UpdateOrganizationQuotaResponse = z.infer<typeof zUpdateOrganizationQuotaResponse>;\n\n// ─── Projects ───────────────────────────────────────────────────────────────\n\nexport const zCreateProjectInput = z.object({\n externalId: zExternalId,\n name: z.string().min(1).max(200),\n domain: z.string().max(253).optional(),\n /** Becomes the project's default for every query that omits one. */\n timezone: zTimezone.optional(),\n retentionDays: z.number().int().min(1).max(3650).optional(),\n});\nexport type CreateProjectInput = z.input<typeof zCreateProjectInput>;\n\nexport const zProject = z.object({\n id: z.string(),\n externalId: zExternalId,\n organizationId: z.string(),\n name: z.string(),\n /** The applied value — `\"UTC\"` when none was given. */\n timezone: z.string(),\n retentionDays: z.number().int().nullable(),\n});\n\nexport const zCreateProjectResponse = z.object({\n created: z.boolean(),\n project: zProject,\n /**\n * Two credentials, not one. A key embedded in a browser bundle must not also\n * be able to read the project's analytics, so the browser write key and the\n * server secret are separate rows with different reach.\n */\n clients: z.object({\n browser: z.object({\n id: z.string(),\n /** Public by design, and recoverable — it ships in page source anyway. */\n writeKey: z.string(),\n scopes: z.array(z.string()),\n }),\n server: z.object({\n id: z.string(),\n /** Plaintext, returned once. Absent when `created` is `false`. */\n clientSecret: z.string().optional(),\n scopes: z.array(z.string()),\n }),\n }),\n});\nexport type CreateProjectResponse = z.infer<typeof zCreateProjectResponse>;\n\nexport const zRotateClientSecretResponse = z.object({\n projectId: z.string(),\n clientId: z.string(),\n /** Plaintext, returned once. The previous secret stops working immediately. */\n clientSecret: z.string(),\n});\nexport type RotateClientSecretResponse = z.infer<typeof zRotateClientSecretResponse>;\n\nexport const zDeleteProjectInput = z.object({\n /**\n * A field in the body rather than `?purge=true`. This deletes the project's\n * Postgres rows and every analytics row behind it, with no undo — and a query\n * parameter is far too easy to fire from shell history or a mis-copied URL.\n */\n purge: z.literal(true),\n /** Checked against the project on record; a mismatch is refused. */\n externalId: zExternalId,\n});\nexport type DeleteProjectInput = z.input<typeof zDeleteProjectInput>;\n\nexport const zDeleteProjectResponse = z.object({\n projectId: z.string(),\n /** Idempotent, but it still says which of the two happened. */\n purge: z.enum([\"queued\", \"already-absent\"]),\n /** When the purge was marked. Absent for `already-absent`. */\n purgingAt: zInstant.optional(),\n});\nexport type DeleteProjectResponse = z.infer<typeof zDeleteProjectResponse>;\n\n// ─── Errors ─────────────────────────────────────────────────────────────────\n\nexport const CONTROL_ERROR_CODES = [\n /** 401 — missing or invalid platform key / organization key. */\n \"unauthorized\",\n /** 403 — the organization key belongs to a different organization. */\n \"organization_scope_mismatch\",\n /**\n * 409 — this externalId exists with a materially different configuration.\n * Only fields whose change alters results are compared (see the docs); a\n * renamed brand is not a conflict.\n */\n \"external_id_conflict\",\n /** 409 — the externalId in a delete body does not match the project's. */\n \"project_external_id_mismatch\",\n /** 404 — no such organization or project, on an endpoint that is not idempotent. */\n \"not_found\",\n /** 400 — input failed the schema. */\n \"validation_failed\",\n /** 429 — per-credential rate limit. */\n \"rate_limited\",\n /** 500 — unexpected server failure. */\n \"internal_error\",\n] as const;\nexport const zControlErrorCode = z.enum(CONTROL_ERROR_CODES);\nexport type ControlErrorCode = z.infer<typeof zControlErrorCode>;\n\nexport const zControlError = z.object({\n status: z.number().int(),\n code: zControlErrorCode,\n error: z.string(),\n message: z.string().optional(),\n errors: z.unknown().optional(),\n requestId: z.string().optional(),\n});\nexport type ControlError = z.infer<typeof zControlError>;\n\n/** Paths, so the client and the route handlers cannot drift apart. */\nexport const CONTROL_API_PATHS = {\n organizations: \"/api/v1/organizations\",\n organization: (id: string) => `/api/v1/organizations/${encodeURIComponent(id)}`,\n organizationKeys: (id: string) => `/api/v1/organizations/${encodeURIComponent(id)}/keys`,\n projects: \"/api/v1/projects\",\n project: (id: string) => `/api/v1/projects/${encodeURIComponent(id)}`,\n clientRotate: (projectId: string, clientId: string) =>\n `/api/v1/projects/${encodeURIComponent(projectId)}/clients/${encodeURIComponent(clientId)}/rotate`,\n} as const;\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
zDate,
|
|
3
3
|
zInstant
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IKOEYZVT.js";
|
|
5
5
|
|
|
6
6
|
// src/query.ts
|
|
7
7
|
import { z } from "zod";
|
|
@@ -242,4 +242,4 @@ export {
|
|
|
242
242
|
zQueryError,
|
|
243
243
|
QUERY_API_PATHS
|
|
244
244
|
};
|
|
245
|
-
//# sourceMappingURL=chunk-
|
|
245
|
+
//# sourceMappingURL=chunk-SC7TFGTO.js.map
|
package/dist/client.cjs
CHANGED
|
@@ -6,14 +6,25 @@ var _chunkHRKELGGHcjs = require('./chunk-HRKELGGH.cjs');
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var _chunkDHSMXB54cjs = require('./chunk-DHSMXB54.cjs');
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
|
|
14
|
+
var _chunkLBSBZO7Ocjs = require('./chunk-LBSBZO7O.cjs');
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
var _chunkGCLUMVPAcjs = require('./chunk-GCLUMVPA.cjs');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _chunkCSTC3ADGcjs = require('./chunk-CSTC3ADG.cjs');
|
|
17
28
|
|
|
18
29
|
// src/client.ts
|
|
19
30
|
var TRACK_PATH = "/api/track";
|
|
@@ -61,7 +72,7 @@ function toApiError(status, rawBody, retryAfterMs, requestId) {
|
|
|
61
72
|
try {
|
|
62
73
|
parsed = JSON.parse(rawBody);
|
|
63
74
|
} catch (e) {
|
|
64
|
-
return new (0,
|
|
75
|
+
return new (0, _chunkCSTC3ADGcjs.DataApiError)({
|
|
65
76
|
message: `reopt-data responded ${status} with a non-JSON body`,
|
|
66
77
|
status,
|
|
67
78
|
code: status >= 500 ? "internal_error" : "unknown_error",
|
|
@@ -73,7 +84,7 @@ function toApiError(status, rawBody, retryAfterMs, requestId) {
|
|
|
73
84
|
const body = _nullishCoalesce(parsed, () => ( {}));
|
|
74
85
|
const code = typeof body.code === "string" ? body.code : status >= 500 ? "internal_error" : "unknown_error";
|
|
75
86
|
const message = typeof body.message === "string" && body.message || typeof body.error === "string" && body.error || `reopt-data responded ${status}`;
|
|
76
|
-
return new (0,
|
|
87
|
+
return new (0, _chunkCSTC3ADGcjs.DataApiError)({
|
|
77
88
|
message,
|
|
78
89
|
status,
|
|
79
90
|
code,
|
|
@@ -95,8 +106,8 @@ function createDataClient(options) {
|
|
|
95
106
|
maxDelayMs: _nullishCoalesce(_optionalChain([options, 'access', _11 => _11.retry, 'optionalAccess', _12 => _12.maxDelayMs]), () => ( DEFAULTS.maxDelayMs)),
|
|
96
107
|
respectRetryAfter: _nullishCoalesce(_optionalChain([options, 'access', _13 => _13.retry, 'optionalAccess', _14 => _14.respectRetryAfter]), () => ( true))
|
|
97
108
|
};
|
|
98
|
-
const userAgent = options.userAgent ? `reopt-data-contract/${
|
|
99
|
-
async function
|
|
109
|
+
const userAgent = options.userAgent ? `reopt-data-contract/${_chunkCSTC3ADGcjs.CONTRACT_VERSION} ${options.userAgent}` : `reopt-data-contract/${_chunkCSTC3ADGcjs.CONTRACT_VERSION}`;
|
|
110
|
+
async function requestOnce(method, path, body, extraHeaders, signal) {
|
|
100
111
|
const controller = new AbortController();
|
|
101
112
|
const timer = setTimeout(
|
|
102
113
|
() => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)),
|
|
@@ -106,12 +117,13 @@ function createDataClient(options) {
|
|
|
106
117
|
_optionalChain([signal, 'optionalAccess', _16 => _16.addEventListener, 'call', _17 => _17("abort", onCallerAbort, { once: true })]);
|
|
107
118
|
try {
|
|
108
119
|
return await doFetch(`${baseUrl}${path}`, {
|
|
109
|
-
method
|
|
120
|
+
method,
|
|
110
121
|
headers: {
|
|
111
122
|
"content-type": "application/json",
|
|
112
123
|
"user-agent": userAgent,
|
|
113
|
-
[
|
|
114
|
-
[
|
|
124
|
+
[_chunkCSTC3ADGcjs.CLIENT_ID_HEADER]: options.clientId,
|
|
125
|
+
[_chunkCSTC3ADGcjs.CLIENT_SECRET_HEADER]: options.clientSecret,
|
|
126
|
+
...extraHeaders
|
|
115
127
|
},
|
|
116
128
|
body: JSON.stringify(body),
|
|
117
129
|
signal: controller.signal
|
|
@@ -121,15 +133,15 @@ function createDataClient(options) {
|
|
|
121
133
|
_optionalChain([signal, 'optionalAccess', _18 => _18.removeEventListener, 'call', _19 => _19("abort", onCallerAbort)]);
|
|
122
134
|
}
|
|
123
135
|
}
|
|
124
|
-
async function
|
|
136
|
+
async function send(method, path, body, parse, extraHeaders = {}, signal) {
|
|
125
137
|
let lastError;
|
|
126
138
|
for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {
|
|
127
139
|
let response;
|
|
128
140
|
try {
|
|
129
|
-
response = await
|
|
141
|
+
response = await requestOnce(method, path, body, extraHeaders, signal);
|
|
130
142
|
} catch (cause) {
|
|
131
143
|
if (_optionalChain([signal, 'optionalAccess', _20 => _20.aborted])) throw cause;
|
|
132
|
-
lastError = new (0,
|
|
144
|
+
lastError = new (0, _chunkCSTC3ADGcjs.DataApiError)({
|
|
133
145
|
message: cause instanceof Error ? cause.message : String(cause),
|
|
134
146
|
status: 0,
|
|
135
147
|
code: "network_error",
|
|
@@ -141,14 +153,14 @@ function createDataClient(options) {
|
|
|
141
153
|
}
|
|
142
154
|
throw lastError;
|
|
143
155
|
}
|
|
144
|
-
const requestId = _nullishCoalesce(response.headers.get(
|
|
156
|
+
const requestId = _nullishCoalesce(response.headers.get(_chunkCSTC3ADGcjs.REQUEST_ID_HEADER), () => ( void 0));
|
|
145
157
|
const rawBody = await response.text();
|
|
146
158
|
if (response.ok) {
|
|
147
159
|
let json;
|
|
148
160
|
try {
|
|
149
161
|
json = JSON.parse(rawBody);
|
|
150
162
|
} catch (cause) {
|
|
151
|
-
throw new (0,
|
|
163
|
+
throw new (0, _chunkCSTC3ADGcjs.DataApiError)({
|
|
152
164
|
message: "reopt-data returned a 2xx with an unparseable body",
|
|
153
165
|
status: response.status,
|
|
154
166
|
code: "contract_mismatch",
|
|
@@ -159,7 +171,7 @@ function createDataClient(options) {
|
|
|
159
171
|
try {
|
|
160
172
|
return parse(json);
|
|
161
173
|
} catch (cause) {
|
|
162
|
-
throw new (0,
|
|
174
|
+
throw new (0, _chunkCSTC3ADGcjs.DataApiError)({
|
|
163
175
|
message: "reopt-data returned a 2xx that does not match the contract",
|
|
164
176
|
status: response.status,
|
|
165
177
|
code: "contract_mismatch",
|
|
@@ -173,7 +185,10 @@ function createDataClient(options) {
|
|
|
173
185
|
if (!lastError.retryable || attempt === retry.maxRetries) throw lastError;
|
|
174
186
|
await sleep(_nullishCoalesce(retryAfterMs, () => ( backoffDelay(attempt, retry))), signal);
|
|
175
187
|
}
|
|
176
|
-
throw _nullishCoalesce(lastError, () => ( new (0,
|
|
188
|
+
throw _nullishCoalesce(lastError, () => ( new (0, _chunkCSTC3ADGcjs.DataApiError)({ message: "reopt-data request failed", status: 0, code: "network_error" })));
|
|
189
|
+
}
|
|
190
|
+
function post(path, body, parse, signal) {
|
|
191
|
+
return send("POST", path, body, parse, {}, signal);
|
|
177
192
|
}
|
|
178
193
|
return {
|
|
179
194
|
ingest: {
|
|
@@ -184,17 +199,79 @@ function createDataClient(options) {
|
|
|
184
199
|
query: {
|
|
185
200
|
eventsTimeseries(input, init) {
|
|
186
201
|
return post(
|
|
187
|
-
|
|
202
|
+
_chunkGCLUMVPAcjs.QUERY_API_PATHS.eventsTimeseries,
|
|
188
203
|
input,
|
|
189
|
-
(value) =>
|
|
204
|
+
(value) => _chunkGCLUMVPAcjs.zEventsTimeseriesResponse.parse(value),
|
|
190
205
|
_optionalChain([init, 'optionalAccess', _22 => _22.signal])
|
|
191
206
|
);
|
|
192
207
|
},
|
|
193
208
|
funnel(input, init) {
|
|
194
|
-
return post(
|
|
209
|
+
return post(_chunkGCLUMVPAcjs.QUERY_API_PATHS.funnel, input, (value) => _chunkGCLUMVPAcjs.zFunnelResponse.parse(value), _optionalChain([init, 'optionalAccess', _23 => _23.signal]));
|
|
195
210
|
},
|
|
196
211
|
retention(input, init) {
|
|
197
|
-
return post(
|
|
212
|
+
return post(_chunkGCLUMVPAcjs.QUERY_API_PATHS.retention, input, (value) => _chunkGCLUMVPAcjs.zRetentionResponse.parse(value), _optionalChain([init, 'optionalAccess', _24 => _24.signal]));
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
control: {
|
|
216
|
+
createOrganization(input, auth, init) {
|
|
217
|
+
return send(
|
|
218
|
+
"POST",
|
|
219
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.organizations,
|
|
220
|
+
input,
|
|
221
|
+
(value) => _chunkLBSBZO7Ocjs.zCreateOrganizationResponse.parse(value),
|
|
222
|
+
{ [_chunkLBSBZO7Ocjs.PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
223
|
+
_optionalChain([init, 'optionalAccess', _25 => _25.signal])
|
|
224
|
+
);
|
|
225
|
+
},
|
|
226
|
+
rotateOrgKey(organizationId, auth, init) {
|
|
227
|
+
return send(
|
|
228
|
+
"POST",
|
|
229
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.organizationKeys(organizationId),
|
|
230
|
+
{},
|
|
231
|
+
(value) => _chunkLBSBZO7Ocjs.zRotateOrganizationKeyResponse.parse(value),
|
|
232
|
+
{ [_chunkLBSBZO7Ocjs.PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
233
|
+
_optionalChain([init, 'optionalAccess', _26 => _26.signal])
|
|
234
|
+
);
|
|
235
|
+
},
|
|
236
|
+
updateOrganizationQuota(organizationId, input, auth, init) {
|
|
237
|
+
return send(
|
|
238
|
+
"PATCH",
|
|
239
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.organization(organizationId),
|
|
240
|
+
input,
|
|
241
|
+
(value) => _chunkLBSBZO7Ocjs.zUpdateOrganizationQuotaResponse.parse(value),
|
|
242
|
+
{ [_chunkLBSBZO7Ocjs.PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
243
|
+
_optionalChain([init, 'optionalAccess', _27 => _27.signal])
|
|
244
|
+
);
|
|
245
|
+
},
|
|
246
|
+
createProject(input, auth, init) {
|
|
247
|
+
return send(
|
|
248
|
+
"POST",
|
|
249
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.projects,
|
|
250
|
+
input,
|
|
251
|
+
(value) => _chunkLBSBZO7Ocjs.zCreateProjectResponse.parse(value),
|
|
252
|
+
{ [_chunkLBSBZO7Ocjs.ORG_KEY_HEADER]: auth.orgKey },
|
|
253
|
+
_optionalChain([init, 'optionalAccess', _28 => _28.signal])
|
|
254
|
+
);
|
|
255
|
+
},
|
|
256
|
+
rotateServerClientSecret(projectId, clientId, auth, init) {
|
|
257
|
+
return send(
|
|
258
|
+
"POST",
|
|
259
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.clientRotate(projectId, clientId),
|
|
260
|
+
{},
|
|
261
|
+
(value) => _chunkLBSBZO7Ocjs.zRotateClientSecretResponse.parse(value),
|
|
262
|
+
{ [_chunkLBSBZO7Ocjs.ORG_KEY_HEADER]: auth.orgKey },
|
|
263
|
+
_optionalChain([init, 'optionalAccess', _29 => _29.signal])
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
deleteProject(projectId, input, auth, init) {
|
|
267
|
+
return send(
|
|
268
|
+
"DELETE",
|
|
269
|
+
_chunkLBSBZO7Ocjs.CONTROL_API_PATHS.project(projectId),
|
|
270
|
+
input,
|
|
271
|
+
(value) => _chunkLBSBZO7Ocjs.zDeleteProjectResponse.parse(value),
|
|
272
|
+
{ [_chunkLBSBZO7Ocjs.ORG_KEY_HEADER]: auth.orgKey },
|
|
273
|
+
_optionalChain([init, 'optionalAccess', _30 => _30.signal])
|
|
274
|
+
);
|
|
198
275
|
}
|
|
199
276
|
}
|
|
200
277
|
};
|
package/dist/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/client.cjs","../src/client.ts"],"names":[],"mappings":"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","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/client.cjs","sourcesContent":[null,"/**\n * `createDataClient` — typed fetch over the ingest and query planes.\n *\n * Deliberately stateless: no queue, no buffer, no background flush. Batch\n * assembly and cursor management belong to the caller (a forwarder already has\n * a cursor and byte-batching; duplicating that here would give it two).\n *\n * Every response is parsed with the contract schema, so a server that drifts\n * from the contract surfaces as `contract_mismatch` instead of quietly\n * returning something the caller then mis-reads.\n */\nimport {\n CLIENT_ID_HEADER,\n CLIENT_SECRET_HEADER,\n CONTRACT_VERSION,\n DataApiError,\n REQUEST_ID_HEADER,\n type ClientCredentials,\n} from \"./index.js\";\nimport { zIngestResponse, type IngestResponse, type ITrackHandlerPayload } from \"./ingest.js\";\nimport {\n QUERY_API_PATHS,\n zEventsTimeseriesResponse,\n zFunnelResponse,\n zRetentionResponse,\n type EventsTimeseriesInput,\n type EventsTimeseriesResponse,\n type FunnelInput,\n type FunnelResponse,\n type RetentionInput,\n type RetentionResponse,\n} from \"./query.js\";\n\nconst TRACK_PATH = \"/api/track\";\n\nexport interface DataClientRetryOptions {\n /** Attempts after the first. Only 429 and 5xx are retried. Default 2. */\n maxRetries?: number;\n /** First backoff step; doubles each attempt, with jitter. Default 500ms. */\n baseDelayMs?: number;\n /** Cap on a single backoff step. Default 20s. */\n maxDelayMs?: number;\n /** Prefer the server's `Retry-After` over the computed backoff. Default true. */\n respectRetryAfter?: boolean;\n}\n\nexport interface DataClientOptions extends ClientCredentials {\n /** Origin of the reopt-data deployment, e.g. `https://data.reopt.app`. Trailing slash ignored. */\n baseUrl: string;\n /** Injected so callers can pass a framework-instrumented fetch. Defaults to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /** Per-attempt timeout. Default 10s. */\n timeoutMs?: number;\n retry?: DataClientRetryOptions;\n /** Appended to the default `reopt-data-contract/<version>`. */\n userAgent?: string;\n}\n\nexport interface DataRequestInit {\n signal?: AbortSignal;\n}\n\nexport interface DataClient {\n ingest: {\n /**\n * `POST /api/track`. Send events as one batch; splitting to stay under\n * the 512KB body cap is the caller's job, since only the caller knows how\n * to resume a partially-sent range.\n */\n track(events: ITrackHandlerPayload[], init?: DataRequestInit): Promise<IngestResponse>;\n };\n query: {\n eventsTimeseries(input: EventsTimeseriesInput, init?: DataRequestInit): Promise<EventsTimeseriesResponse>;\n funnel(input: FunnelInput, init?: DataRequestInit): Promise<FunnelResponse>;\n retention(input: RetentionInput, init?: DataRequestInit): Promise<RetentionResponse>;\n };\n}\n\nconst DEFAULTS = {\n timeoutMs: 10_000,\n maxRetries: 2,\n baseDelayMs: 500,\n maxDelayMs: 20_000,\n} as const;\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, \"\");\n}\n\n/** `Retry-After` is either delta-seconds or an HTTP date; both are legal. */\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (Number.isFinite(seconds) && seconds >= 0) return Math.round(seconds * 1000);\n\n const at = Date.parse(header);\n if (Number.isFinite(at)) return Math.max(0, at - Date.now());\n\n return undefined;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"Aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(signal?.reason ?? new Error(\"Aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction backoffDelay(attempt: number, retry: Required<DataClientRetryOptions>): number {\n const exponential = retry.baseDelayMs * 2 ** attempt;\n const capped = Math.min(exponential, retry.maxDelayMs);\n // Full jitter — a fleet of forwarders that all got 429 should not all come\n // back at the same instant.\n return Math.round(capped * (0.5 + Math.random() * 0.5));\n}\n\n/**\n * Body of a non-2xx response. Both planes share `{ status, code, error, ... }`,\n * so one reader covers them; anything else is reported as `internal_error`\n * with the raw text kept in `details`.\n */\nfunction toApiError(\n status: number,\n rawBody: string,\n retryAfterMs: number | undefined,\n requestId?: string\n): DataApiError {\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n return new DataApiError({\n message: `reopt-data responded ${status} with a non-JSON body`,\n status,\n code: status >= 500 ? \"internal_error\" : \"unknown_error\",\n requestId,\n retryAfterMs,\n details: rawBody.slice(0, 2000),\n });\n }\n\n const body = (parsed ?? {}) as Record<string, unknown>;\n const code = typeof body.code === \"string\" ? body.code : status >= 500 ? \"internal_error\" : \"unknown_error\";\n const message =\n (typeof body.message === \"string\" && body.message) ||\n (typeof body.error === \"string\" && body.error) ||\n `reopt-data responded ${status}`;\n\n return new DataApiError({\n message,\n status,\n code,\n requestId: (typeof body.requestId === \"string\" ? body.requestId : undefined) ?? requestId,\n retryAfterMs,\n details: body.errors ?? undefined,\n });\n}\n\nexport function createDataClient(options: DataClientOptions): DataClient {\n const baseUrl = normalizeBaseUrl(options.baseUrl);\n const doFetch = options.fetch ?? globalThis.fetch;\n if (typeof doFetch !== \"function\") {\n throw new TypeError(\"createDataClient: no fetch implementation available — pass options.fetch\");\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;\n const retry: Required<DataClientRetryOptions> = {\n maxRetries: options.retry?.maxRetries ?? DEFAULTS.maxRetries,\n baseDelayMs: options.retry?.baseDelayMs ?? DEFAULTS.baseDelayMs,\n maxDelayMs: options.retry?.maxDelayMs ?? DEFAULTS.maxDelayMs,\n respectRetryAfter: options.retry?.respectRetryAfter ?? true,\n };\n\n const userAgent = options.userAgent\n ? `reopt-data-contract/${CONTRACT_VERSION} ${options.userAgent}`\n : `reopt-data-contract/${CONTRACT_VERSION}`;\n\n async function postOnce(path: string, body: unknown, signal?: AbortSignal): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n const onCallerAbort = () => controller.abort(signal?.reason ?? new Error(\"Aborted\"));\n signal?.addEventListener(\"abort\", onCallerAbort, { once: true });\n\n try {\n return await doFetch(`${baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": userAgent,\n [CLIENT_ID_HEADER]: options.clientId,\n [CLIENT_SECRET_HEADER]: options.clientSecret,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n async function post<T>(path: string, body: unknown, parse: (value: unknown) => T, signal?: AbortSignal): Promise<T> {\n let lastError: DataApiError | undefined;\n\n for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {\n let response: Response;\n try {\n response = await postOnce(path, body, signal);\n } catch (cause) {\n // A caller-initiated abort is not a transport failure — propagate it.\n if (signal?.aborted) throw cause;\n lastError = new DataApiError({\n message: cause instanceof Error ? cause.message : String(cause),\n status: 0,\n code: \"network_error\",\n details: cause,\n });\n if (attempt < retry.maxRetries) {\n await sleep(backoffDelay(attempt, retry), signal);\n continue;\n }\n throw lastError;\n }\n\n const requestId = response.headers.get(REQUEST_ID_HEADER) ?? undefined;\n const rawBody = await response.text();\n\n if (response.ok) {\n let json: unknown;\n try {\n json = JSON.parse(rawBody);\n } catch (cause) {\n throw new DataApiError({\n message: \"reopt-data returned a 2xx with an unparseable body\",\n status: response.status,\n code: \"contract_mismatch\",\n requestId,\n details: cause,\n });\n }\n\n try {\n return parse(json);\n } catch (cause) {\n throw new DataApiError({\n message: \"reopt-data returned a 2xx that does not match the contract\",\n status: response.status,\n code: \"contract_mismatch\",\n requestId,\n details: cause,\n });\n }\n }\n\n const retryAfterMs = retry.respectRetryAfter ? parseRetryAfter(response.headers.get(\"retry-after\")) : undefined;\n lastError = toApiError(response.status, rawBody, retryAfterMs, requestId);\n\n if (!lastError.retryable || attempt === retry.maxRetries) throw lastError;\n await sleep(retryAfterMs ?? backoffDelay(attempt, retry), signal);\n }\n\n /* c8 ignore next -- the loop either returns or throws */\n throw lastError ?? new DataApiError({ message: \"reopt-data request failed\", status: 0, code: \"network_error\" });\n }\n\n return {\n ingest: {\n track(events, init) {\n return post(TRACK_PATH, events, (value) => zIngestResponse.parse(value), init?.signal);\n },\n },\n query: {\n eventsTimeseries(input, init) {\n return post(\n QUERY_API_PATHS.eventsTimeseries,\n input,\n (value) => zEventsTimeseriesResponse.parse(value),\n init?.signal\n );\n },\n funnel(input, init) {\n return post(QUERY_API_PATHS.funnel, input, (value) => zFunnelResponse.parse(value), init?.signal);\n },\n retention(input, init) {\n return post(QUERY_API_PATHS.retention, input, (value) => zRetentionResponse.parse(value), init?.signal);\n },\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/client.cjs","../src/client.ts"],"names":[],"mappings":"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","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/client.cjs","sourcesContent":[null,"/**\n * `createDataClient` — typed fetch over the ingest and query planes.\n *\n * Deliberately stateless: no queue, no buffer, no background flush. Batch\n * assembly and cursor management belong to the caller (a forwarder already has\n * a cursor and byte-batching; duplicating that here would give it two).\n *\n * Every response is parsed with the contract schema, so a server that drifts\n * from the contract surfaces as `contract_mismatch` instead of quietly\n * returning something the caller then mis-reads.\n */\nimport {\n CLIENT_ID_HEADER,\n CLIENT_SECRET_HEADER,\n CONTRACT_VERSION,\n DataApiError,\n REQUEST_ID_HEADER,\n type ClientCredentials,\n} from \"./index.js\";\nimport { zIngestResponse, type IngestResponse, type ITrackHandlerPayload } from \"./ingest.js\";\nimport {\n CONTROL_API_PATHS,\n ORG_KEY_HEADER,\n PLATFORM_KEY_HEADER,\n zCreateOrganizationResponse,\n zCreateProjectResponse,\n zDeleteProjectResponse,\n zRotateClientSecretResponse,\n zRotateOrganizationKeyResponse,\n zUpdateOrganizationQuotaResponse,\n type CreateOrganizationInput,\n type CreateOrganizationResponse,\n type CreateProjectInput,\n type CreateProjectResponse,\n type DeleteProjectInput,\n type DeleteProjectResponse,\n type RotateClientSecretResponse,\n type RotateOrganizationKeyResponse,\n type UpdateOrganizationQuotaInput,\n type UpdateOrganizationQuotaResponse,\n} from \"./control.js\";\nimport {\n QUERY_API_PATHS,\n zEventsTimeseriesResponse,\n zFunnelResponse,\n zRetentionResponse,\n type EventsTimeseriesInput,\n type EventsTimeseriesResponse,\n type FunnelInput,\n type FunnelResponse,\n type RetentionInput,\n type RetentionResponse,\n} from \"./query.js\";\n\nconst TRACK_PATH = \"/api/track\";\n\nexport interface DataClientRetryOptions {\n /** Attempts after the first. Only 429 and 5xx are retried. Default 2. */\n maxRetries?: number;\n /** First backoff step; doubles each attempt, with jitter. Default 500ms. */\n baseDelayMs?: number;\n /** Cap on a single backoff step. Default 20s. */\n maxDelayMs?: number;\n /** Prefer the server's `Retry-After` over the computed backoff. Default true. */\n respectRetryAfter?: boolean;\n}\n\nexport interface DataClientOptions extends ClientCredentials {\n /** Origin of the reopt-data deployment, e.g. `https://data.reopt.app`. Trailing slash ignored. */\n baseUrl: string;\n /** Injected so callers can pass a framework-instrumented fetch. Defaults to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /** Per-attempt timeout. Default 10s. */\n timeoutMs?: number;\n retry?: DataClientRetryOptions;\n /** Appended to the default `reopt-data-contract/<version>`. */\n userAgent?: string;\n}\n\nexport interface DataRequestInit {\n signal?: AbortSignal;\n}\n\n/**\n * Provisioning credentials are passed per call rather than held on the client,\n * because they are a different authority from the client credential the rest of\n * the surface uses — and because a long-lived object holding the platform key\n * is a wider blast radius than a value the caller reads at the moment it needs\n * it.\n */\nexport interface PlatformAuth {\n platformKey: string;\n}\n\nexport interface OrganizationAuth {\n orgKey: string;\n}\n\nexport interface DataClient {\n ingest: {\n /**\n * `POST /api/track`. Send events as one batch; splitting to stay under\n * the 512KB body cap is the caller's job, since only the caller knows how\n * to resume a partially-sent range.\n */\n track(events: ITrackHandlerPayload[], init?: DataRequestInit): Promise<IngestResponse>;\n };\n query: {\n eventsTimeseries(input: EventsTimeseriesInput, init?: DataRequestInit): Promise<EventsTimeseriesResponse>;\n funnel(input: FunnelInput, init?: DataRequestInit): Promise<FunnelResponse>;\n retention(input: RetentionInput, init?: DataRequestInit): Promise<RetentionResponse>;\n };\n control: {\n /** Idempotent on `externalId`. `orgKey` comes back only on first creation. */\n createOrganization(\n input: CreateOrganizationInput,\n auth: PlatformAuth,\n init?: DataRequestInit\n ): Promise<CreateOrganizationResponse>;\n /** Issues a new key and revokes every previous one. The recovery path for a lost key. */\n rotateOrgKey(\n organizationId: string,\n auth: PlatformAuth,\n init?: DataRequestInit\n ): Promise<RotateOrganizationKeyResponse>;\n updateOrganizationQuota(\n organizationId: string,\n input: UpdateOrganizationQuotaInput,\n auth: PlatformAuth,\n init?: DataRequestInit\n ): Promise<UpdateOrganizationQuotaResponse>;\n /** Idempotent on `externalId`. `clientSecret` comes back only on first creation. */\n createProject(\n input: CreateProjectInput,\n auth: OrganizationAuth,\n init?: DataRequestInit\n ): Promise<CreateProjectResponse>;\n rotateServerClientSecret(\n projectId: string,\n clientId: string,\n auth: OrganizationAuth,\n init?: DataRequestInit\n ): Promise<RotateClientSecretResponse>;\n /** Irreversible. Idempotent: a project that is already gone still answers 202. */\n deleteProject(\n projectId: string,\n input: DeleteProjectInput,\n auth: OrganizationAuth,\n init?: DataRequestInit\n ): Promise<DeleteProjectResponse>;\n };\n}\n\nconst DEFAULTS = {\n timeoutMs: 10_000,\n maxRetries: 2,\n baseDelayMs: 500,\n maxDelayMs: 20_000,\n} as const;\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, \"\");\n}\n\n/** `Retry-After` is either delta-seconds or an HTTP date; both are legal. */\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (Number.isFinite(seconds) && seconds >= 0) return Math.round(seconds * 1000);\n\n const at = Date.parse(header);\n if (Number.isFinite(at)) return Math.max(0, at - Date.now());\n\n return undefined;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"Aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(signal?.reason ?? new Error(\"Aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction backoffDelay(attempt: number, retry: Required<DataClientRetryOptions>): number {\n const exponential = retry.baseDelayMs * 2 ** attempt;\n const capped = Math.min(exponential, retry.maxDelayMs);\n // Full jitter — a fleet of forwarders that all got 429 should not all come\n // back at the same instant.\n return Math.round(capped * (0.5 + Math.random() * 0.5));\n}\n\n/**\n * Body of a non-2xx response. Both planes share `{ status, code, error, ... }`,\n * so one reader covers them; anything else is reported as `internal_error`\n * with the raw text kept in `details`.\n */\nfunction toApiError(\n status: number,\n rawBody: string,\n retryAfterMs: number | undefined,\n requestId?: string\n): DataApiError {\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n return new DataApiError({\n message: `reopt-data responded ${status} with a non-JSON body`,\n status,\n code: status >= 500 ? \"internal_error\" : \"unknown_error\",\n requestId,\n retryAfterMs,\n details: rawBody.slice(0, 2000),\n });\n }\n\n const body = (parsed ?? {}) as Record<string, unknown>;\n const code = typeof body.code === \"string\" ? body.code : status >= 500 ? \"internal_error\" : \"unknown_error\";\n const message =\n (typeof body.message === \"string\" && body.message) ||\n (typeof body.error === \"string\" && body.error) ||\n `reopt-data responded ${status}`;\n\n return new DataApiError({\n message,\n status,\n code,\n requestId: (typeof body.requestId === \"string\" ? body.requestId : undefined) ?? requestId,\n retryAfterMs,\n details: body.errors ?? undefined,\n });\n}\n\nexport function createDataClient(options: DataClientOptions): DataClient {\n const baseUrl = normalizeBaseUrl(options.baseUrl);\n const doFetch = options.fetch ?? globalThis.fetch;\n if (typeof doFetch !== \"function\") {\n throw new TypeError(\"createDataClient: no fetch implementation available — pass options.fetch\");\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;\n const retry: Required<DataClientRetryOptions> = {\n maxRetries: options.retry?.maxRetries ?? DEFAULTS.maxRetries,\n baseDelayMs: options.retry?.baseDelayMs ?? DEFAULTS.baseDelayMs,\n maxDelayMs: options.retry?.maxDelayMs ?? DEFAULTS.maxDelayMs,\n respectRetryAfter: options.retry?.respectRetryAfter ?? true,\n };\n\n const userAgent = options.userAgent\n ? `reopt-data-contract/${CONTRACT_VERSION} ${options.userAgent}`\n : `reopt-data-contract/${CONTRACT_VERSION}`;\n\n async function requestOnce(\n method: \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body: unknown,\n extraHeaders: Record<string, string>,\n signal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n const onCallerAbort = () => controller.abort(signal?.reason ?? new Error(\"Aborted\"));\n signal?.addEventListener(\"abort\", onCallerAbort, { once: true });\n\n try {\n return await doFetch(`${baseUrl}${path}`, {\n method,\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": userAgent,\n [CLIENT_ID_HEADER]: options.clientId,\n [CLIENT_SECRET_HEADER]: options.clientSecret,\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n async function send<T>(\n method: \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body: unknown,\n parse: (value: unknown) => T,\n extraHeaders: Record<string, string> = {},\n signal?: AbortSignal\n ): Promise<T> {\n let lastError: DataApiError | undefined;\n\n for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {\n let response: Response;\n try {\n response = await requestOnce(method, path, body, extraHeaders, signal);\n } catch (cause) {\n // A caller-initiated abort is not a transport failure — propagate it.\n if (signal?.aborted) throw cause;\n lastError = new DataApiError({\n message: cause instanceof Error ? cause.message : String(cause),\n status: 0,\n code: \"network_error\",\n details: cause,\n });\n if (attempt < retry.maxRetries) {\n await sleep(backoffDelay(attempt, retry), signal);\n continue;\n }\n throw lastError;\n }\n\n const requestId = response.headers.get(REQUEST_ID_HEADER) ?? undefined;\n const rawBody = await response.text();\n\n if (response.ok) {\n let json: unknown;\n try {\n json = JSON.parse(rawBody);\n } catch (cause) {\n throw new DataApiError({\n message: \"reopt-data returned a 2xx with an unparseable body\",\n status: response.status,\n code: \"contract_mismatch\",\n requestId,\n details: cause,\n });\n }\n\n try {\n return parse(json);\n } catch (cause) {\n throw new DataApiError({\n message: \"reopt-data returned a 2xx that does not match the contract\",\n status: response.status,\n code: \"contract_mismatch\",\n requestId,\n details: cause,\n });\n }\n }\n\n const retryAfterMs = retry.respectRetryAfter ? parseRetryAfter(response.headers.get(\"retry-after\")) : undefined;\n lastError = toApiError(response.status, rawBody, retryAfterMs, requestId);\n\n if (!lastError.retryable || attempt === retry.maxRetries) throw lastError;\n await sleep(retryAfterMs ?? backoffDelay(attempt, retry), signal);\n }\n\n /* c8 ignore next -- the loop either returns or throws */\n throw lastError ?? new DataApiError({ message: \"reopt-data request failed\", status: 0, code: \"network_error\" });\n }\n\n function post<T>(path: string, body: unknown, parse: (value: unknown) => T, signal?: AbortSignal): Promise<T> {\n return send(\"POST\", path, body, parse, {}, signal);\n }\n\n return {\n ingest: {\n track(events, init) {\n return post(TRACK_PATH, events, (value) => zIngestResponse.parse(value), init?.signal);\n },\n },\n query: {\n eventsTimeseries(input, init) {\n return post(\n QUERY_API_PATHS.eventsTimeseries,\n input,\n (value) => zEventsTimeseriesResponse.parse(value),\n init?.signal\n );\n },\n funnel(input, init) {\n return post(QUERY_API_PATHS.funnel, input, (value) => zFunnelResponse.parse(value), init?.signal);\n },\n retention(input, init) {\n return post(QUERY_API_PATHS.retention, input, (value) => zRetentionResponse.parse(value), init?.signal);\n },\n },\n control: {\n createOrganization(input, auth, init) {\n return send(\n \"POST\",\n CONTROL_API_PATHS.organizations,\n input,\n (value) => zCreateOrganizationResponse.parse(value),\n { [PLATFORM_KEY_HEADER]: auth.platformKey },\n init?.signal\n );\n },\n rotateOrgKey(organizationId, auth, init) {\n return send(\n \"POST\",\n CONTROL_API_PATHS.organizationKeys(organizationId),\n {},\n (value) => zRotateOrganizationKeyResponse.parse(value),\n { [PLATFORM_KEY_HEADER]: auth.platformKey },\n init?.signal\n );\n },\n updateOrganizationQuota(organizationId, input, auth, init) {\n return send(\n \"PATCH\",\n CONTROL_API_PATHS.organization(organizationId),\n input,\n (value) => zUpdateOrganizationQuotaResponse.parse(value),\n { [PLATFORM_KEY_HEADER]: auth.platformKey },\n init?.signal\n );\n },\n createProject(input, auth, init) {\n return send(\n \"POST\",\n CONTROL_API_PATHS.projects,\n input,\n (value) => zCreateProjectResponse.parse(value),\n { [ORG_KEY_HEADER]: auth.orgKey },\n init?.signal\n );\n },\n rotateServerClientSecret(projectId, clientId, auth, init) {\n return send(\n \"POST\",\n CONTROL_API_PATHS.clientRotate(projectId, clientId),\n {},\n (value) => zRotateClientSecretResponse.parse(value),\n { [ORG_KEY_HEADER]: auth.orgKey },\n init?.signal\n );\n },\n deleteProject(projectId, input, auth, init) {\n return send(\n \"DELETE\",\n CONTROL_API_PATHS.project(projectId),\n input,\n (value) => zDeleteProjectResponse.parse(value),\n { [ORG_KEY_HEADER]: auth.orgKey },\n init?.signal\n );\n },\n },\n };\n}\n"]}
|
package/dist/client.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ClientCredentials } from './index.cjs';
|
|
2
2
|
import { ITrackHandlerPayload, IngestResponse } from './ingest.cjs';
|
|
3
|
+
import { CreateOrganizationInput, CreateOrganizationResponse, RotateOrganizationKeyResponse, UpdateOrganizationQuotaInput, UpdateOrganizationQuotaResponse, CreateProjectInput, CreateProjectResponse, RotateClientSecretResponse, DeleteProjectInput, DeleteProjectResponse } from './control.cjs';
|
|
3
4
|
import { EventsTimeseriesInput, EventsTimeseriesResponse, FunnelInput, FunnelResponse, RetentionInput, RetentionResponse } from './query.cjs';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
@@ -39,6 +40,19 @@ interface DataClientOptions extends ClientCredentials {
|
|
|
39
40
|
interface DataRequestInit {
|
|
40
41
|
signal?: AbortSignal;
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Provisioning credentials are passed per call rather than held on the client,
|
|
45
|
+
* because they are a different authority from the client credential the rest of
|
|
46
|
+
* the surface uses — and because a long-lived object holding the platform key
|
|
47
|
+
* is a wider blast radius than a value the caller reads at the moment it needs
|
|
48
|
+
* it.
|
|
49
|
+
*/
|
|
50
|
+
interface PlatformAuth {
|
|
51
|
+
platformKey: string;
|
|
52
|
+
}
|
|
53
|
+
interface OrganizationAuth {
|
|
54
|
+
orgKey: string;
|
|
55
|
+
}
|
|
42
56
|
interface DataClient {
|
|
43
57
|
ingest: {
|
|
44
58
|
/**
|
|
@@ -53,7 +67,19 @@ interface DataClient {
|
|
|
53
67
|
funnel(input: FunnelInput, init?: DataRequestInit): Promise<FunnelResponse>;
|
|
54
68
|
retention(input: RetentionInput, init?: DataRequestInit): Promise<RetentionResponse>;
|
|
55
69
|
};
|
|
70
|
+
control: {
|
|
71
|
+
/** Idempotent on `externalId`. `orgKey` comes back only on first creation. */
|
|
72
|
+
createOrganization(input: CreateOrganizationInput, auth: PlatformAuth, init?: DataRequestInit): Promise<CreateOrganizationResponse>;
|
|
73
|
+
/** Issues a new key and revokes every previous one. The recovery path for a lost key. */
|
|
74
|
+
rotateOrgKey(organizationId: string, auth: PlatformAuth, init?: DataRequestInit): Promise<RotateOrganizationKeyResponse>;
|
|
75
|
+
updateOrganizationQuota(organizationId: string, input: UpdateOrganizationQuotaInput, auth: PlatformAuth, init?: DataRequestInit): Promise<UpdateOrganizationQuotaResponse>;
|
|
76
|
+
/** Idempotent on `externalId`. `clientSecret` comes back only on first creation. */
|
|
77
|
+
createProject(input: CreateProjectInput, auth: OrganizationAuth, init?: DataRequestInit): Promise<CreateProjectResponse>;
|
|
78
|
+
rotateServerClientSecret(projectId: string, clientId: string, auth: OrganizationAuth, init?: DataRequestInit): Promise<RotateClientSecretResponse>;
|
|
79
|
+
/** Irreversible. Idempotent: a project that is already gone still answers 202. */
|
|
80
|
+
deleteProject(projectId: string, input: DeleteProjectInput, auth: OrganizationAuth, init?: DataRequestInit): Promise<DeleteProjectResponse>;
|
|
81
|
+
};
|
|
56
82
|
}
|
|
57
83
|
declare function createDataClient(options: DataClientOptions): DataClient;
|
|
58
84
|
|
|
59
|
-
export { type DataClient, type DataClientOptions, type DataClientRetryOptions, type DataRequestInit, createDataClient };
|
|
85
|
+
export { type DataClient, type DataClientOptions, type DataClientRetryOptions, type DataRequestInit, type OrganizationAuth, type PlatformAuth, createDataClient };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ClientCredentials } from './index.js';
|
|
2
2
|
import { ITrackHandlerPayload, IngestResponse } from './ingest.js';
|
|
3
|
+
import { CreateOrganizationInput, CreateOrganizationResponse, RotateOrganizationKeyResponse, UpdateOrganizationQuotaInput, UpdateOrganizationQuotaResponse, CreateProjectInput, CreateProjectResponse, RotateClientSecretResponse, DeleteProjectInput, DeleteProjectResponse } from './control.js';
|
|
3
4
|
import { EventsTimeseriesInput, EventsTimeseriesResponse, FunnelInput, FunnelResponse, RetentionInput, RetentionResponse } from './query.js';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
@@ -39,6 +40,19 @@ interface DataClientOptions extends ClientCredentials {
|
|
|
39
40
|
interface DataRequestInit {
|
|
40
41
|
signal?: AbortSignal;
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Provisioning credentials are passed per call rather than held on the client,
|
|
45
|
+
* because they are a different authority from the client credential the rest of
|
|
46
|
+
* the surface uses — and because a long-lived object holding the platform key
|
|
47
|
+
* is a wider blast radius than a value the caller reads at the moment it needs
|
|
48
|
+
* it.
|
|
49
|
+
*/
|
|
50
|
+
interface PlatformAuth {
|
|
51
|
+
platformKey: string;
|
|
52
|
+
}
|
|
53
|
+
interface OrganizationAuth {
|
|
54
|
+
orgKey: string;
|
|
55
|
+
}
|
|
42
56
|
interface DataClient {
|
|
43
57
|
ingest: {
|
|
44
58
|
/**
|
|
@@ -53,7 +67,19 @@ interface DataClient {
|
|
|
53
67
|
funnel(input: FunnelInput, init?: DataRequestInit): Promise<FunnelResponse>;
|
|
54
68
|
retention(input: RetentionInput, init?: DataRequestInit): Promise<RetentionResponse>;
|
|
55
69
|
};
|
|
70
|
+
control: {
|
|
71
|
+
/** Idempotent on `externalId`. `orgKey` comes back only on first creation. */
|
|
72
|
+
createOrganization(input: CreateOrganizationInput, auth: PlatformAuth, init?: DataRequestInit): Promise<CreateOrganizationResponse>;
|
|
73
|
+
/** Issues a new key and revokes every previous one. The recovery path for a lost key. */
|
|
74
|
+
rotateOrgKey(organizationId: string, auth: PlatformAuth, init?: DataRequestInit): Promise<RotateOrganizationKeyResponse>;
|
|
75
|
+
updateOrganizationQuota(organizationId: string, input: UpdateOrganizationQuotaInput, auth: PlatformAuth, init?: DataRequestInit): Promise<UpdateOrganizationQuotaResponse>;
|
|
76
|
+
/** Idempotent on `externalId`. `clientSecret` comes back only on first creation. */
|
|
77
|
+
createProject(input: CreateProjectInput, auth: OrganizationAuth, init?: DataRequestInit): Promise<CreateProjectResponse>;
|
|
78
|
+
rotateServerClientSecret(projectId: string, clientId: string, auth: OrganizationAuth, init?: DataRequestInit): Promise<RotateClientSecretResponse>;
|
|
79
|
+
/** Irreversible. Idempotent: a project that is already gone still answers 202. */
|
|
80
|
+
deleteProject(projectId: string, input: DeleteProjectInput, auth: OrganizationAuth, init?: DataRequestInit): Promise<DeleteProjectResponse>;
|
|
81
|
+
};
|
|
56
82
|
}
|
|
57
83
|
declare function createDataClient(options: DataClientOptions): DataClient;
|
|
58
84
|
|
|
59
|
-
export { type DataClient, type DataClientOptions, type DataClientRetryOptions, type DataRequestInit, createDataClient };
|
|
85
|
+
export { type DataClient, type DataClientOptions, type DataClientRetryOptions, type DataRequestInit, type OrganizationAuth, type PlatformAuth, createDataClient };
|
package/dist/client.js
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
zIngestResponse
|
|
3
3
|
} from "./chunk-FRJK7OCQ.js";
|
|
4
|
+
import {
|
|
5
|
+
CONTROL_API_PATHS,
|
|
6
|
+
ORG_KEY_HEADER,
|
|
7
|
+
PLATFORM_KEY_HEADER,
|
|
8
|
+
zCreateOrganizationResponse,
|
|
9
|
+
zCreateProjectResponse,
|
|
10
|
+
zDeleteProjectResponse,
|
|
11
|
+
zRotateClientSecretResponse,
|
|
12
|
+
zRotateOrganizationKeyResponse,
|
|
13
|
+
zUpdateOrganizationQuotaResponse
|
|
14
|
+
} from "./chunk-2SJPZP2D.js";
|
|
4
15
|
import {
|
|
5
16
|
QUERY_API_PATHS,
|
|
6
17
|
zEventsTimeseriesResponse,
|
|
7
18
|
zFunnelResponse,
|
|
8
19
|
zRetentionResponse
|
|
9
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-SC7TFGTO.js";
|
|
10
21
|
import {
|
|
11
22
|
CLIENT_ID_HEADER,
|
|
12
23
|
CLIENT_SECRET_HEADER,
|
|
13
24
|
CONTRACT_VERSION,
|
|
14
25
|
DataApiError,
|
|
15
26
|
REQUEST_ID_HEADER
|
|
16
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-IKOEYZVT.js";
|
|
17
28
|
|
|
18
29
|
// src/client.ts
|
|
19
30
|
var TRACK_PATH = "/api/track";
|
|
@@ -96,7 +107,7 @@ function createDataClient(options) {
|
|
|
96
107
|
respectRetryAfter: options.retry?.respectRetryAfter ?? true
|
|
97
108
|
};
|
|
98
109
|
const userAgent = options.userAgent ? `reopt-data-contract/${CONTRACT_VERSION} ${options.userAgent}` : `reopt-data-contract/${CONTRACT_VERSION}`;
|
|
99
|
-
async function
|
|
110
|
+
async function requestOnce(method, path, body, extraHeaders, signal) {
|
|
100
111
|
const controller = new AbortController();
|
|
101
112
|
const timer = setTimeout(
|
|
102
113
|
() => controller.abort(new Error(`reopt-data request timed out after ${timeoutMs}ms`)),
|
|
@@ -106,12 +117,13 @@ function createDataClient(options) {
|
|
|
106
117
|
signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
107
118
|
try {
|
|
108
119
|
return await doFetch(`${baseUrl}${path}`, {
|
|
109
|
-
method
|
|
120
|
+
method,
|
|
110
121
|
headers: {
|
|
111
122
|
"content-type": "application/json",
|
|
112
123
|
"user-agent": userAgent,
|
|
113
124
|
[CLIENT_ID_HEADER]: options.clientId,
|
|
114
|
-
[CLIENT_SECRET_HEADER]: options.clientSecret
|
|
125
|
+
[CLIENT_SECRET_HEADER]: options.clientSecret,
|
|
126
|
+
...extraHeaders
|
|
115
127
|
},
|
|
116
128
|
body: JSON.stringify(body),
|
|
117
129
|
signal: controller.signal
|
|
@@ -121,12 +133,12 @@ function createDataClient(options) {
|
|
|
121
133
|
signal?.removeEventListener("abort", onCallerAbort);
|
|
122
134
|
}
|
|
123
135
|
}
|
|
124
|
-
async function
|
|
136
|
+
async function send(method, path, body, parse, extraHeaders = {}, signal) {
|
|
125
137
|
let lastError;
|
|
126
138
|
for (let attempt = 0; attempt <= retry.maxRetries; attempt++) {
|
|
127
139
|
let response;
|
|
128
140
|
try {
|
|
129
|
-
response = await
|
|
141
|
+
response = await requestOnce(method, path, body, extraHeaders, signal);
|
|
130
142
|
} catch (cause) {
|
|
131
143
|
if (signal?.aborted) throw cause;
|
|
132
144
|
lastError = new DataApiError({
|
|
@@ -175,6 +187,9 @@ function createDataClient(options) {
|
|
|
175
187
|
}
|
|
176
188
|
throw lastError ?? new DataApiError({ message: "reopt-data request failed", status: 0, code: "network_error" });
|
|
177
189
|
}
|
|
190
|
+
function post(path, body, parse, signal) {
|
|
191
|
+
return send("POST", path, body, parse, {}, signal);
|
|
192
|
+
}
|
|
178
193
|
return {
|
|
179
194
|
ingest: {
|
|
180
195
|
track(events, init) {
|
|
@@ -196,6 +211,68 @@ function createDataClient(options) {
|
|
|
196
211
|
retention(input, init) {
|
|
197
212
|
return post(QUERY_API_PATHS.retention, input, (value) => zRetentionResponse.parse(value), init?.signal);
|
|
198
213
|
}
|
|
214
|
+
},
|
|
215
|
+
control: {
|
|
216
|
+
createOrganization(input, auth, init) {
|
|
217
|
+
return send(
|
|
218
|
+
"POST",
|
|
219
|
+
CONTROL_API_PATHS.organizations,
|
|
220
|
+
input,
|
|
221
|
+
(value) => zCreateOrganizationResponse.parse(value),
|
|
222
|
+
{ [PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
223
|
+
init?.signal
|
|
224
|
+
);
|
|
225
|
+
},
|
|
226
|
+
rotateOrgKey(organizationId, auth, init) {
|
|
227
|
+
return send(
|
|
228
|
+
"POST",
|
|
229
|
+
CONTROL_API_PATHS.organizationKeys(organizationId),
|
|
230
|
+
{},
|
|
231
|
+
(value) => zRotateOrganizationKeyResponse.parse(value),
|
|
232
|
+
{ [PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
233
|
+
init?.signal
|
|
234
|
+
);
|
|
235
|
+
},
|
|
236
|
+
updateOrganizationQuota(organizationId, input, auth, init) {
|
|
237
|
+
return send(
|
|
238
|
+
"PATCH",
|
|
239
|
+
CONTROL_API_PATHS.organization(organizationId),
|
|
240
|
+
input,
|
|
241
|
+
(value) => zUpdateOrganizationQuotaResponse.parse(value),
|
|
242
|
+
{ [PLATFORM_KEY_HEADER]: auth.platformKey },
|
|
243
|
+
init?.signal
|
|
244
|
+
);
|
|
245
|
+
},
|
|
246
|
+
createProject(input, auth, init) {
|
|
247
|
+
return send(
|
|
248
|
+
"POST",
|
|
249
|
+
CONTROL_API_PATHS.projects,
|
|
250
|
+
input,
|
|
251
|
+
(value) => zCreateProjectResponse.parse(value),
|
|
252
|
+
{ [ORG_KEY_HEADER]: auth.orgKey },
|
|
253
|
+
init?.signal
|
|
254
|
+
);
|
|
255
|
+
},
|
|
256
|
+
rotateServerClientSecret(projectId, clientId, auth, init) {
|
|
257
|
+
return send(
|
|
258
|
+
"POST",
|
|
259
|
+
CONTROL_API_PATHS.clientRotate(projectId, clientId),
|
|
260
|
+
{},
|
|
261
|
+
(value) => zRotateClientSecretResponse.parse(value),
|
|
262
|
+
{ [ORG_KEY_HEADER]: auth.orgKey },
|
|
263
|
+
init?.signal
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
deleteProject(projectId, input, auth, init) {
|
|
267
|
+
return send(
|
|
268
|
+
"DELETE",
|
|
269
|
+
CONTROL_API_PATHS.project(projectId),
|
|
270
|
+
input,
|
|
271
|
+
(value) => zDeleteProjectResponse.parse(value),
|
|
272
|
+
{ [ORG_KEY_HEADER]: auth.orgKey },
|
|
273
|
+
init?.signal
|
|
274
|
+
);
|
|
275
|
+
}
|
|
199
276
|
}
|
|
200
277
|
};
|
|
201
278
|
}
|