@uengage.io/platform-sdk 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.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # @uengage.io/platform-sdk
2
+
3
+ Client SDK for uEngage platform services. Exposes namespaced singletons for each
4
+ service domain, configured by environment variables out of the box.
5
+
6
+ CDK constructs live in a separate package: `@uengage/platform-constructs`.
7
+
8
+ ## Quick start
9
+
10
+ ```ts
11
+ import { audit, business } from '@uengage.io/platform-sdk';
12
+
13
+ // Reads PLATFORM_BASE_URL, PLATFORM_SIGNING_SECRET, PLATFORM_SERVICE_ID
14
+ // (or PLATFORM_AUTH_TOKEN) from the environment.
15
+
16
+ const acme = await business.get(123, { groups: ['business_details', 'gst'] });
17
+
18
+ audit.record({
19
+ event_type: 'business.updated',
20
+ tenant: { id: 'biz_123', parent_id: null },
21
+ actor: { type: 'user', id: 'usr_42' },
22
+ resource: { type: 'business', id: 'biz_123' },
23
+ changes: { name: { before: 'Old', after: 'New' } },
24
+ });
25
+ ```
26
+
27
+ ## Configuration
28
+
29
+ Both clients read defaults from `process.env`:
30
+
31
+ | Variable | Purpose | Default |
32
+ | ------------------------- | -------------------------------------------- | ----------------------------- |
33
+ | `PLATFORM_BASE_URL` | Platform API base URL | `https://platform.uengage.io` |
34
+ | `PLATFORM_SIGNING_SECRET` | Hex HMAC secret for service-to-service calls | none |
35
+ | `PLATFORM_SERVICE_ID` | Caller service id for HMAC | none |
36
+ | `PLATFORM_AUTH_TOKEN` | Bearer token (overrides HMAC if set) | none |
37
+
38
+ Override at runtime per client:
39
+
40
+ ```ts
41
+ business
42
+ .config({ baseUrl: 'https://staging.platform.uengage.io' })
43
+ .auth({ secret: process.env.MY_SECRET!, serviceId: 'my-service' })
44
+ .get(123);
45
+
46
+ // Or Bearer token:
47
+ business.auth({ token: 'tok-...' }).get(123);
48
+ ```
49
+
50
+ For isolated configuration (tests, multi-tenant code paths), construct your own:
51
+
52
+ ```ts
53
+ import { createBusinessClient, createAuditClient } from '@uengage.io/platform-sdk';
54
+
55
+ const customBusiness = createBusinessClient({
56
+ baseUrl: 'https://staging.platform.uengage.io',
57
+ auth: { secret: '...', serviceId: 'my-service' },
58
+ });
59
+ ```
60
+
61
+ ## Audit client
62
+
63
+ ```ts
64
+ audit.record({
65
+ event_type: 'business.updated',
66
+ tenant: { id: 'biz_123', parent_id: null },
67
+ actor: { type: 'user', id: 'usr_42' },
68
+ resource: { type: 'business', id: 'biz_123' },
69
+ changes: { name: { before: 'Old', after: 'New' } },
70
+ });
71
+
72
+ await audit.flush(); // optional: drain on shutdown
73
+ ```
74
+
75
+ - `record()` is fire-and-forget. It generates `event_id` (ULID) and
76
+ `occurred_at`, fills `actor.via` with the configured `serviceId`,
77
+ validates the event, and enqueues it. It never throws.
78
+ - Events batch and flush every 5 s (configurable via `flushIntervalMs`)
79
+ or when the batch reaches 50 (`maxBatchSize`).
80
+ - Requests are HMAC-SHA256 signed.
81
+ - Failed batches retry up to 3 times with exponential backoff
82
+ (500 ms / 2 s / 8 s); on final failure the full batch is logged.
83
+ - Queue overflow (default 1000) drops new events with a warning log.
84
+ - `flush()` resolves when the queue is empty or retries are exhausted.
85
+
86
+ ## Business client
87
+
88
+ ```ts
89
+ const biz = await business.get(123);
90
+ // { id: 123, parent_id: 42, business_details: { name: 'Acme' } }
91
+
92
+ const detailed = await business.get(123, {
93
+ groups: ['business_details', 'gst', 'payment_gateway'],
94
+ });
95
+
96
+ const many = await business.bulk([123, 124], { groups: ['business_details'] });
97
+ ```
98
+
99
+ - `get()` returns the record or throws `BusinessApiError` (with `.status` and `.body`).
100
+ - `bulk()` returns matched records in input order; missing ids are dropped silently.
101
+ - The `business_details` group (just `name`) is public; other groups need
102
+ matching `business:read.<group>` capability for the calling service id.
103
+
104
+ ## Build / test
105
+
106
+ ```bash
107
+ pnpm --filter @uengage.io/platform-sdk build
108
+ pnpm --filter @uengage.io/platform-sdk test
109
+ ```
110
+
111
+ ## Publish
112
+
113
+ The package publishes on a `platform-sdk-vX.Y.Z` tag push. To cut a release:
114
+
115
+ 1. Bump `version` in `package.json`.
116
+ 2. Open a PR; merge.
117
+ 3. Tag `platform-sdk-vX.Y.Z` on `main` and push - the publish workflow runs
118
+ `pnpm publish --filter @uengage.io/platform-sdk --access public`.
@@ -0,0 +1,29 @@
1
+ import { type PlatformAuth, type PlatformAuthInput, type PlatformConfigInput } from '../config';
2
+ import { type AuditEvent } from './schema';
3
+ /**
4
+ * Caller-facing event shape. The SDK fills:
5
+ * - `event_id` (ULID, generated per call)
6
+ * - `occurred_at` (UTC ISO 8601 at the time of `record()`)
7
+ * - `actor.via` (always set to the configured serviceId, so callers
8
+ * can't drift from the service identity used for auth)
9
+ */
10
+ export type AuditEventInput = Omit<AuditEvent, 'event_id' | 'occurred_at' | 'actor'> & {
11
+ actor: Omit<AuditEvent['actor'], 'via'>;
12
+ };
13
+ export interface AuditClientInput extends PlatformConfigInput {
14
+ /** Default 5000. */
15
+ flushIntervalMs?: number;
16
+ /** Default 50. */
17
+ maxBatchSize?: number;
18
+ /** Default 1000. New events past this are dropped with a warning. */
19
+ maxQueueSize?: number;
20
+ /** Default true. Set false to disable the auto-flush timer (test only). */
21
+ enableTimer?: boolean;
22
+ }
23
+ export interface AuditClient {
24
+ config(input: PlatformConfigInput): AuditClient;
25
+ auth(input: PlatformAuthInput | PlatformAuth): AuditClient;
26
+ record(event: AuditEventInput): void;
27
+ flush(): Promise<void>;
28
+ }
29
+ export declare function createAuditClient(input?: AuditClientInput): AuditClient;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuditClient = createAuditClient;
4
+ const ulid_1 = require("ulid");
5
+ const config_1 = require("../config");
6
+ const http_1 = require("../http");
7
+ const schema_1 = require("./schema");
8
+ const PATH = '/v1/audit/events';
9
+ const RETRY_DELAYS_MS = [500, 2000, 8000];
10
+ const NOOP_LOGGER = {
11
+ error: () => { },
12
+ warn: () => { },
13
+ info: () => { },
14
+ debug: () => { },
15
+ child() {
16
+ return this;
17
+ },
18
+ };
19
+ function createAuditClient(input = {}) {
20
+ const state = new config_1.ConfigState();
21
+ const flushIntervalMs = input.flushIntervalMs ?? 5000;
22
+ const maxBatchSize = input.maxBatchSize ?? 50;
23
+ const maxQueueSize = input.maxQueueSize ?? 1000;
24
+ const enableTimer = input.enableTimer ?? true;
25
+ const { flushIntervalMs: _f, maxBatchSize: _b, maxQueueSize: _q, enableTimer: _t, ...rest } = input;
26
+ void _f;
27
+ void _b;
28
+ void _q;
29
+ void _t;
30
+ state.apply(rest);
31
+ const queue = [];
32
+ const inflight = [];
33
+ function getLogger() {
34
+ return state.resolve().logger ?? NOOP_LOGGER;
35
+ }
36
+ function getServiceId() {
37
+ const config = state.resolve();
38
+ if (!config.auth || config.auth.type !== 'hmac') {
39
+ throw new Error('audit client requires HMAC auth (set PLATFORM_SIGNING_SECRET + PLATFORM_SERVICE_ID, or call .auth({secret, serviceId}))');
40
+ }
41
+ return config.auth.serviceId;
42
+ }
43
+ const client = {
44
+ config(opts) {
45
+ state.apply(opts);
46
+ return client;
47
+ },
48
+ auth(opts) {
49
+ state.setAuth(opts);
50
+ return client;
51
+ },
52
+ record(input) {
53
+ const logger = getLogger();
54
+ let serviceId;
55
+ try {
56
+ serviceId = getServiceId();
57
+ }
58
+ catch (err) {
59
+ logger.error('audit_sdk.no_auth', {
60
+ error: { code: 'AUDIT_NO_AUTH', category: 'engineering' },
61
+ context: { message: err.message },
62
+ });
63
+ return;
64
+ }
65
+ const candidate = {
66
+ ...input,
67
+ event_id: (0, ulid_1.ulid)(),
68
+ occurred_at: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
69
+ actor: { ...input.actor, via: serviceId },
70
+ };
71
+ const result = schema_1.auditEventSchema.safeParse(candidate);
72
+ if (!result.success) {
73
+ logger.error('audit_sdk.invalid_event', {
74
+ error: { code: 'AUDIT_INVALID_EVENT', category: 'engineering' },
75
+ context: { issues: result.error.issues, event: candidate },
76
+ });
77
+ return;
78
+ }
79
+ if (queue.length >= maxQueueSize) {
80
+ logger.warn('audit_sdk.queue_full', {
81
+ context: { dropped_event_id: candidate.event_id, max_queue_size: maxQueueSize },
82
+ });
83
+ return;
84
+ }
85
+ queue.push(result.data);
86
+ if (queue.length >= maxBatchSize) {
87
+ void scheduleSend();
88
+ }
89
+ },
90
+ async flush() {
91
+ await scheduleSend();
92
+ while (inflight.length > 0) {
93
+ await Promise.allSettled([...inflight]);
94
+ }
95
+ },
96
+ };
97
+ async function scheduleSend() {
98
+ while (queue.length > 0) {
99
+ const batch = queue.splice(0, maxBatchSize);
100
+ const send = sendWithRetries(batch);
101
+ inflight.push(send);
102
+ try {
103
+ await send;
104
+ }
105
+ finally {
106
+ const idx = inflight.indexOf(send);
107
+ if (idx !== -1)
108
+ inflight.splice(idx, 1);
109
+ }
110
+ }
111
+ }
112
+ async function sendWithRetries(events) {
113
+ const logger = getLogger();
114
+ const body = JSON.stringify({ events });
115
+ for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {
116
+ try {
117
+ const ok = await sendOnce(body);
118
+ if (ok)
119
+ return;
120
+ }
121
+ catch (err) {
122
+ const e = err;
123
+ logger.warn('audit_sdk.send_error', {
124
+ context: { attempt, message: e.message, batch_size: events.length },
125
+ });
126
+ }
127
+ if (attempt < RETRY_DELAYS_MS.length) {
128
+ await sleep(RETRY_DELAYS_MS[attempt]);
129
+ }
130
+ }
131
+ logger.error('audit_sdk.send_failed', {
132
+ error: { code: 'AUDIT_SEND_FAILED', category: 'engineering' },
133
+ context: { batch_size: events.length, events },
134
+ });
135
+ }
136
+ async function sendOnce(body) {
137
+ const config = state.resolve();
138
+ const logger = getLogger();
139
+ const headers = (0, http_1.buildHeaders)(config, { method: 'POST', path: PATH, body });
140
+ const res = await config.fetchFn(`${config.baseUrl}${PATH}`, {
141
+ method: 'POST',
142
+ headers,
143
+ body,
144
+ });
145
+ if (res.status >= 500)
146
+ return false;
147
+ if (!res.ok && res.status !== 202) {
148
+ logger.error('audit_sdk.rejected', {
149
+ error: { code: 'AUDIT_REJECTED', category: 'engineering' },
150
+ context: { status: res.status },
151
+ });
152
+ return true;
153
+ }
154
+ return true;
155
+ }
156
+ let timer;
157
+ if (enableTimer) {
158
+ timer = setInterval(() => {
159
+ void scheduleSend();
160
+ }, flushIntervalMs);
161
+ if (typeof timer.unref === 'function')
162
+ timer.unref();
163
+ }
164
+ return client;
165
+ }
166
+ function sleep(ms) {
167
+ return new Promise((r) => setTimeout(r, ms));
168
+ }
169
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1ZGl0L2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFEQSw4Q0E4SkM7QUFuTkQsK0JBQTRCO0FBRTVCLHNDQUttQjtBQUNuQixrQ0FBdUM7QUFDdkMscUNBQTZEO0FBK0I3RCxNQUFNLElBQUksR0FBRyxrQkFBa0IsQ0FBQztBQUNoQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFMUMsTUFBTSxXQUFXLEdBQUc7SUFDbEIsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7SUFDZixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7SUFDZixLQUFLO1FBQ0gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ21CLENBQUM7QUFFdkIsU0FBZ0IsaUJBQWlCLENBQUMsUUFBMEIsRUFBRTtJQUM1RCxNQUFNLEtBQUssR0FBRyxJQUFJLG9CQUFXLEVBQUUsQ0FBQztJQUNoQyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQztJQUN0RCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztJQUM5QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQztJQUNoRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQztJQUU5QyxNQUFNLEVBQ0osZUFBZSxFQUFFLEVBQUUsRUFDbkIsWUFBWSxFQUFFLEVBQUUsRUFDaEIsWUFBWSxFQUFFLEVBQUUsRUFDaEIsV0FBVyxFQUFFLEVBQUUsRUFDZixHQUFHLElBQUksRUFDUixHQUFHLEtBQUssQ0FBQztJQUNWLEtBQUssRUFBRSxDQUFDO0lBQ1IsS0FBSyxFQUFFLENBQUM7SUFDUixLQUFLLEVBQUUsQ0FBQztJQUNSLEtBQUssRUFBRSxDQUFDO0lBQ1IsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQixNQUFNLEtBQUssR0FBaUIsRUFBRSxDQUFDO0lBQy9CLE1BQU0sUUFBUSxHQUFvQixFQUFFLENBQUM7SUFFckMsU0FBUyxTQUFTO1FBQ2hCLE9BQU8sS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sSUFBSSxXQUFXLENBQUM7SUFDL0MsQ0FBQztJQUVELFNBQVMsWUFBWTtRQUNuQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FDYix5SEFBeUgsQ0FDMUgsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQy9CLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBZ0I7UUFDMUIsTUFBTSxDQUFDLElBQUk7WUFDVCxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSTtZQUNQLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEIsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUNELE1BQU0sQ0FBQyxLQUFLO1lBQ1YsTUFBTSxNQUFNLEdBQUcsU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxTQUFpQixDQUFDO1lBQ3RCLElBQUksQ0FBQztnQkFDSCxTQUFTLEdBQUcsWUFBWSxFQUFFLENBQUM7WUFDN0IsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRTtvQkFDaEMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO29CQUN6RCxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUcsR0FBYSxDQUFDLE9BQU8sRUFBRTtpQkFDN0MsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxTQUFTLEdBQWU7Z0JBQzVCLEdBQUcsS0FBSztnQkFDUixRQUFRLEVBQUUsSUFBQSxXQUFJLEdBQUU7Z0JBQ2hCLFdBQVcsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDO2dCQUMvRCxLQUFLLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRTthQUMxQyxDQUFDO1lBQ0YsTUFBTSxNQUFNLEdBQUcseUJBQWdCLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUU7b0JBQ3RDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxxQkFBcUIsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO29CQUMvRCxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtpQkFDM0QsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNqQyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFO29CQUNsQyxPQUFPLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUU7aUJBQ2hGLENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUNELEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hCLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDakMsS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQztRQUNELEtBQUssQ0FBQyxLQUFLO1lBQ1QsTUFBTSxZQUFZLEVBQUUsQ0FBQztZQUNyQixPQUFPLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzNCLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUMxQyxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7SUFFRixLQUFLLFVBQVUsWUFBWTtRQUN6QixPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDNUMsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDO1lBQ2IsQ0FBQztvQkFBUyxDQUFDO2dCQUNULE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ25DLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQztvQkFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMxQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLFVBQVUsZUFBZSxDQUFDLE1BQW9CO1FBQ2pELE1BQU0sTUFBTSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3hDLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE9BQU8sSUFBSSxlQUFlLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbkUsSUFBSSxDQUFDO2dCQUNILE1BQU0sRUFBRSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLEVBQUU7b0JBQUUsT0FBTztZQUNqQixDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixNQUFNLENBQUMsR0FBRyxHQUFZLENBQUM7Z0JBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUU7b0JBQ2xDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRTtpQkFDcEUsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksT0FBTyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDeEMsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFO1lBQ3BDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO1lBQzdELE9BQU8sRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRTtTQUMvQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxVQUFVLFFBQVEsQ0FBQyxJQUFZO1FBQ2xDLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMvQixNQUFNLE1BQU0sR0FBRyxTQUFTLEVBQUUsQ0FBQztRQUMzQixNQUFNLE9BQU8sR0FBRyxJQUFBLG1CQUFZLEVBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDM0UsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLEVBQUUsRUFBRTtZQUMzRCxNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU87WUFDUCxJQUFJO1NBQ0wsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUc7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUU7Z0JBQ2pDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO2dCQUMxRCxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRTthQUNoQyxDQUFDLENBQUM7WUFDSCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLEtBQWlELENBQUM7SUFDdEQsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixLQUFLLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUN2QixLQUFLLFlBQVksRUFBRSxDQUFDO1FBQ3RCLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUNwQixJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssS0FBSyxVQUFVO1lBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3ZELENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUMsRUFBVTtJQUN2QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVsaWQgfSBmcm9tICd1bGlkJztcbmltcG9ydCB0eXBlIHsgTG9nZ2VyIH0gZnJvbSAnQHVlbmdhZ2UuaW8vanMtbG9nZ2VyJztcbmltcG9ydCB7XG4gIENvbmZpZ1N0YXRlLFxuICB0eXBlIFBsYXRmb3JtQXV0aCxcbiAgdHlwZSBQbGF0Zm9ybUF1dGhJbnB1dCxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZ0lucHV0LFxufSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgYnVpbGRIZWFkZXJzIH0gZnJvbSAnLi4vaHR0cCc7XG5pbXBvcnQgeyBhdWRpdEV2ZW50U2NoZW1hLCB0eXBlIEF1ZGl0RXZlbnQgfSBmcm9tICcuL3NjaGVtYSc7XG5cbi8qKlxuICogQ2FsbGVyLWZhY2luZyBldmVudCBzaGFwZS4gVGhlIFNESyBmaWxsczpcbiAqICAgLSBgZXZlbnRfaWRgICAgKFVMSUQsIGdlbmVyYXRlZCBwZXIgY2FsbClcbiAqICAgLSBgb2NjdXJyZWRfYXRgIChVVEMgSVNPIDg2MDEgYXQgdGhlIHRpbWUgb2YgYHJlY29yZCgpYClcbiAqICAgLSBgYWN0b3IudmlhYCAgKGFsd2F5cyBzZXQgdG8gdGhlIGNvbmZpZ3VyZWQgc2VydmljZUlkLCBzbyBjYWxsZXJzXG4gKiAgICAgICAgICAgICAgICAgICBjYW4ndCBkcmlmdCBmcm9tIHRoZSBzZXJ2aWNlIGlkZW50aXR5IHVzZWQgZm9yIGF1dGgpXG4gKi9cbmV4cG9ydCB0eXBlIEF1ZGl0RXZlbnRJbnB1dCA9IE9taXQ8QXVkaXRFdmVudCwgJ2V2ZW50X2lkJyB8ICdvY2N1cnJlZF9hdCcgfCAnYWN0b3InPiAmIHtcbiAgYWN0b3I6IE9taXQ8QXVkaXRFdmVudFsnYWN0b3InXSwgJ3ZpYSc+O1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBBdWRpdENsaWVudElucHV0IGV4dGVuZHMgUGxhdGZvcm1Db25maWdJbnB1dCB7XG4gIC8qKiBEZWZhdWx0IDUwMDAuICovXG4gIGZsdXNoSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgNTAuICovXG4gIG1heEJhdGNoU2l6ZT86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgMTAwMC4gTmV3IGV2ZW50cyBwYXN0IHRoaXMgYXJlIGRyb3BwZWQgd2l0aCBhIHdhcm5pbmcuICovXG4gIG1heFF1ZXVlU2l6ZT86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgdHJ1ZS4gU2V0IGZhbHNlIHRvIGRpc2FibGUgdGhlIGF1dG8tZmx1c2ggdGltZXIgKHRlc3Qgb25seSkuICovXG4gIGVuYWJsZVRpbWVyPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdWRpdENsaWVudCB7XG4gIGNvbmZpZyhpbnB1dDogUGxhdGZvcm1Db25maWdJbnB1dCk6IEF1ZGl0Q2xpZW50O1xuICBhdXRoKGlucHV0OiBQbGF0Zm9ybUF1dGhJbnB1dCB8IFBsYXRmb3JtQXV0aCk6IEF1ZGl0Q2xpZW50O1xuICByZWNvcmQoZXZlbnQ6IEF1ZGl0RXZlbnRJbnB1dCk6IHZvaWQ7XG4gIGZsdXNoKCk6IFByb21pc2U8dm9pZD47XG59XG5cbmNvbnN0IFBBVEggPSAnL3YxL2F1ZGl0L2V2ZW50cyc7XG5jb25zdCBSRVRSWV9ERUxBWVNfTVMgPSBbNTAwLCAyMDAwLCA4MDAwXTtcblxuY29uc3QgTk9PUF9MT0dHRVIgPSB7XG4gIGVycm9yOiAoKSA9PiB7fSxcbiAgd2FybjogKCkgPT4ge30sXG4gIGluZm86ICgpID0+IHt9LFxuICBkZWJ1ZzogKCkgPT4ge30sXG4gIGNoaWxkKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxufSBhcyB1bmtub3duIGFzIExvZ2dlcjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGl0Q2xpZW50KGlucHV0OiBBdWRpdENsaWVudElucHV0ID0ge30pOiBBdWRpdENsaWVudCB7XG4gIGNvbnN0IHN0YXRlID0gbmV3IENvbmZpZ1N0YXRlKCk7XG4gIGNvbnN0IGZsdXNoSW50ZXJ2YWxNcyA9IGlucHV0LmZsdXNoSW50ZXJ2YWxNcyA/PyA1MDAwO1xuICBjb25zdCBtYXhCYXRjaFNpemUgPSBpbnB1dC5tYXhCYXRjaFNpemUgPz8gNTA7XG4gIGNvbnN0IG1heFF1ZXVlU2l6ZSA9IGlucHV0Lm1heFF1ZXVlU2l6ZSA/PyAxMDAwO1xuICBjb25zdCBlbmFibGVUaW1lciA9IGlucHV0LmVuYWJsZVRpbWVyID8/IHRydWU7XG5cbiAgY29uc3Qge1xuICAgIGZsdXNoSW50ZXJ2YWxNczogX2YsXG4gICAgbWF4QmF0Y2hTaXplOiBfYixcbiAgICBtYXhRdWV1ZVNpemU6IF9xLFxuICAgIGVuYWJsZVRpbWVyOiBfdCxcbiAgICAuLi5yZXN0XG4gIH0gPSBpbnB1dDtcbiAgdm9pZCBfZjtcbiAgdm9pZCBfYjtcbiAgdm9pZCBfcTtcbiAgdm9pZCBfdDtcbiAgc3RhdGUuYXBwbHkocmVzdCk7XG5cbiAgY29uc3QgcXVldWU6IEF1ZGl0RXZlbnRbXSA9IFtdO1xuICBjb25zdCBpbmZsaWdodDogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgZnVuY3Rpb24gZ2V0TG9nZ2VyKCk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHN0YXRlLnJlc29sdmUoKS5sb2dnZXIgPz8gTk9PUF9MT0dHRVI7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTZXJ2aWNlSWQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb25maWcgPSBzdGF0ZS5yZXNvbHZlKCk7XG4gICAgaWYgKCFjb25maWcuYXV0aCB8fCBjb25maWcuYXV0aC50eXBlICE9PSAnaG1hYycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2F1ZGl0IGNsaWVudCByZXF1aXJlcyBITUFDIGF1dGggKHNldCBQTEFURk9STV9TSUdOSU5HX1NFQ1JFVCArIFBMQVRGT1JNX1NFUlZJQ0VfSUQsIG9yIGNhbGwgLmF1dGgoe3NlY3JldCwgc2VydmljZUlkfSkpJyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBjb25maWcuYXV0aC5zZXJ2aWNlSWQ7XG4gIH1cblxuICBjb25zdCBjbGllbnQ6IEF1ZGl0Q2xpZW50ID0ge1xuICAgIGNvbmZpZyhvcHRzKSB7XG4gICAgICBzdGF0ZS5hcHBseShvcHRzKTtcbiAgICAgIHJldHVybiBjbGllbnQ7XG4gICAgfSxcbiAgICBhdXRoKG9wdHMpIHtcbiAgICAgIHN0YXRlLnNldEF1dGgob3B0cyk7XG4gICAgICByZXR1cm4gY2xpZW50O1xuICAgIH0sXG4gICAgcmVjb3JkKGlucHV0KSB7XG4gICAgICBjb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoKTtcbiAgICAgIGxldCBzZXJ2aWNlSWQ6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIHNlcnZpY2VJZCA9IGdldFNlcnZpY2VJZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignYXVkaXRfc2RrLm5vX2F1dGgnLCB7XG4gICAgICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX05PX0FVVEgnLCBjYXRlZ29yeTogJ2VuZ2luZWVyaW5nJyB9LFxuICAgICAgICAgIGNvbnRleHQ6IHsgbWVzc2FnZTogKGVyciBhcyBFcnJvcikubWVzc2FnZSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW5kaWRhdGU6IEF1ZGl0RXZlbnQgPSB7XG4gICAgICAgIC4uLmlucHV0LFxuICAgICAgICBldmVudF9pZDogdWxpZCgpLFxuICAgICAgICBvY2N1cnJlZF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1xcLlxcZHszfVokLywgJ1onKSxcbiAgICAgICAgYWN0b3I6IHsgLi4uaW5wdXQuYWN0b3IsIHZpYTogc2VydmljZUlkIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXVkaXRFdmVudFNjaGVtYS5zYWZlUGFyc2UoY2FuZGlkYXRlKTtcbiAgICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdhdWRpdF9zZGsuaW52YWxpZF9ldmVudCcsIHtcbiAgICAgICAgICBlcnJvcjogeyBjb2RlOiAnQVVESVRfSU5WQUxJRF9FVkVOVCcsIGNhdGVnb3J5OiAnZW5naW5lZXJpbmcnIH0sXG4gICAgICAgICAgY29udGV4dDogeyBpc3N1ZXM6IHJlc3VsdC5lcnJvci5pc3N1ZXMsIGV2ZW50OiBjYW5kaWRhdGUgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChxdWV1ZS5sZW5ndGggPj0gbWF4UXVldWVTaXplKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdhdWRpdF9zZGsucXVldWVfZnVsbCcsIHtcbiAgICAgICAgICBjb250ZXh0OiB7IGRyb3BwZWRfZXZlbnRfaWQ6IGNhbmRpZGF0ZS5ldmVudF9pZCwgbWF4X3F1ZXVlX3NpemU6IG1heFF1ZXVlU2l6ZSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcXVldWUucHVzaChyZXN1bHQuZGF0YSk7XG4gICAgICBpZiAocXVldWUubGVuZ3RoID49IG1heEJhdGNoU2l6ZSkge1xuICAgICAgICB2b2lkIHNjaGVkdWxlU2VuZCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgZmx1c2goKSB7XG4gICAgICBhd2FpdCBzY2hlZHVsZVNlbmQoKTtcbiAgICAgIHdoaWxlIChpbmZsaWdodC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4uaW5mbGlnaHRdKTtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHNjaGVkdWxlU2VuZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYmF0Y2ggPSBxdWV1ZS5zcGxpY2UoMCwgbWF4QmF0Y2hTaXplKTtcbiAgICAgIGNvbnN0IHNlbmQgPSBzZW5kV2l0aFJldHJpZXMoYmF0Y2gpO1xuICAgICAgaW5mbGlnaHQucHVzaChzZW5kKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNlbmQ7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjb25zdCBpZHggPSBpbmZsaWdodC5pbmRleE9mKHNlbmQpO1xuICAgICAgICBpZiAoaWR4ICE9PSAtMSkgaW5mbGlnaHQuc3BsaWNlKGlkeCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gc2VuZFdpdGhSZXRyaWVzKGV2ZW50czogQXVkaXRFdmVudFtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKCk7XG4gICAgY29uc3QgYm9keSA9IEpTT04uc3RyaW5naWZ5KHsgZXZlbnRzIH0pO1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDw9IFJFVFJZX0RFTEFZU19NUy5sZW5ndGg7IGF0dGVtcHQrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgb2sgPSBhd2FpdCBzZW5kT25jZShib2R5KTtcbiAgICAgICAgaWYgKG9rKSByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc3QgZSA9IGVyciBhcyBFcnJvcjtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ2F1ZGl0X3Nkay5zZW5kX2Vycm9yJywge1xuICAgICAgICAgIGNvbnRleHQ6IHsgYXR0ZW1wdCwgbWVzc2FnZTogZS5tZXNzYWdlLCBiYXRjaF9zaXplOiBldmVudHMubGVuZ3RoIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGF0dGVtcHQgPCBSRVRSWV9ERUxBWVNfTVMubGVuZ3RoKSB7XG4gICAgICAgIGF3YWl0IHNsZWVwKFJFVFJZX0RFTEFZU19NU1thdHRlbXB0XSk7XG4gICAgICB9XG4gICAgfVxuICAgIGxvZ2dlci5lcnJvcignYXVkaXRfc2RrLnNlbmRfZmFpbGVkJywge1xuICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX1NFTkRfRkFJTEVEJywgY2F0ZWdvcnk6ICdlbmdpbmVlcmluZycgfSxcbiAgICAgIGNvbnRleHQ6IHsgYmF0Y2hfc2l6ZTogZXZlbnRzLmxlbmd0aCwgZXZlbnRzIH0sXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBzZW5kT25jZShib2R5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSBzdGF0ZS5yZXNvbHZlKCk7XG4gICAgY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKCk7XG4gICAgY29uc3QgaGVhZGVycyA9IGJ1aWxkSGVhZGVycyhjb25maWcsIHsgbWV0aG9kOiAnUE9TVCcsIHBhdGg6IFBBVEgsIGJvZHkgfSk7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgY29uZmlnLmZldGNoRm4oYCR7Y29uZmlnLmJhc2VVcmx9JHtQQVRIfWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGJvZHksXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgPj0gNTAwKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFyZXMub2sgJiYgcmVzLnN0YXR1cyAhPT0gMjAyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ2F1ZGl0X3Nkay5yZWplY3RlZCcsIHtcbiAgICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX1JFSkVDVEVEJywgY2F0ZWdvcnk6ICdlbmdpbmVlcmluZycgfSxcbiAgICAgICAgY29udGV4dDogeyBzdGF0dXM6IHJlcy5zdGF0dXMgfSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgbGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gIGlmIChlbmFibGVUaW1lcikge1xuICAgIHRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdm9pZCBzY2hlZHVsZVNlbmQoKTtcbiAgICB9LCBmbHVzaEludGVydmFsTXMpO1xuICAgIGlmICh0eXBlb2YgdGltZXIudW5yZWYgPT09ICdmdW5jdGlvbicpIHRpbWVyLnVucmVmKCk7XG4gIH1cblxuICByZXR1cm4gY2xpZW50O1xufVxuXG5mdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xufVxuIl19
@@ -0,0 +1,3 @@
1
+ export { auditEventSchema, auditBatchSchema, type AuditEvent, type AuditBatch } from './schema';
2
+ export { signRequest, type SignRequestParams } from './sign';
3
+ export { createAuditClient, type AuditClient, type AuditClientInput, type AuditEventInput, } from './client';
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuditClient = exports.signRequest = exports.auditBatchSchema = exports.auditEventSchema = void 0;
4
+ var schema_1 = require("./schema");
5
+ Object.defineProperty(exports, "auditEventSchema", { enumerable: true, get: function () { return schema_1.auditEventSchema; } });
6
+ Object.defineProperty(exports, "auditBatchSchema", { enumerable: true, get: function () { return schema_1.auditBatchSchema; } });
7
+ var sign_1 = require("./sign");
8
+ Object.defineProperty(exports, "signRequest", { enumerable: true, get: function () { return sign_1.signRequest; } });
9
+ var client_1 = require("./client");
10
+ Object.defineProperty(exports, "createAuditClient", { enumerable: true, get: function () { return client_1.createAuditClient; } });
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXVkaXQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQWdHO0FBQXZGLDBHQUFBLGdCQUFnQixPQUFBO0FBQUUsMEdBQUEsZ0JBQWdCLE9BQUE7QUFDM0MsK0JBQTZEO0FBQXBELG1HQUFBLFdBQVcsT0FBQTtBQUNwQixtQ0FLa0I7QUFKaEIsMkdBQUEsaUJBQWlCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBhdWRpdEV2ZW50U2NoZW1hLCBhdWRpdEJhdGNoU2NoZW1hLCB0eXBlIEF1ZGl0RXZlbnQsIHR5cGUgQXVkaXRCYXRjaCB9IGZyb20gJy4vc2NoZW1hJztcbmV4cG9ydCB7IHNpZ25SZXF1ZXN0LCB0eXBlIFNpZ25SZXF1ZXN0UGFyYW1zIH0gZnJvbSAnLi9zaWduJztcbmV4cG9ydCB7XG4gIGNyZWF0ZUF1ZGl0Q2xpZW50LFxuICB0eXBlIEF1ZGl0Q2xpZW50LFxuICB0eXBlIEF1ZGl0Q2xpZW50SW5wdXQsXG4gIHR5cGUgQXVkaXRFdmVudElucHV0LFxufSBmcm9tICcuL2NsaWVudCc7XG4iXX0=
@@ -0,0 +1,239 @@
1
+ import { z } from 'zod';
2
+ export declare const auditEventSchema: z.ZodObject<{
3
+ event_id: z.ZodString;
4
+ event_type: z.ZodString;
5
+ occurred_at: z.ZodString;
6
+ tenant: z.ZodObject<{
7
+ id: z.ZodString;
8
+ parent_id: z.ZodNullable<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ id: string;
11
+ parent_id: string | null;
12
+ }, {
13
+ id: string;
14
+ parent_id: string | null;
15
+ }>;
16
+ actor: z.ZodObject<{
17
+ type: z.ZodEnum<["user", "service", "system"]>;
18
+ id: z.ZodString;
19
+ via: z.ZodString;
20
+ }, "strip", z.ZodTypeAny, {
21
+ type: "user" | "service" | "system";
22
+ id: string;
23
+ via: string;
24
+ }, {
25
+ type: "user" | "service" | "system";
26
+ id: string;
27
+ via: string;
28
+ }>;
29
+ resource: z.ZodObject<{
30
+ type: z.ZodString;
31
+ id: z.ZodString;
32
+ }, "strip", z.ZodTypeAny, {
33
+ type: string;
34
+ id: string;
35
+ }, {
36
+ type: string;
37
+ id: string;
38
+ }>;
39
+ changes: z.ZodRecord<z.ZodString, z.ZodObject<{
40
+ before: z.ZodUnknown;
41
+ after: z.ZodUnknown;
42
+ }, "strip", z.ZodTypeAny, {
43
+ before?: unknown;
44
+ after?: unknown;
45
+ }, {
46
+ before?: unknown;
47
+ after?: unknown;
48
+ }>>;
49
+ request_id: z.ZodOptional<z.ZodString>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ event_id: string;
52
+ event_type: string;
53
+ occurred_at: string;
54
+ tenant: {
55
+ id: string;
56
+ parent_id: string | null;
57
+ };
58
+ actor: {
59
+ type: "user" | "service" | "system";
60
+ id: string;
61
+ via: string;
62
+ };
63
+ resource: {
64
+ type: string;
65
+ id: string;
66
+ };
67
+ changes: Record<string, {
68
+ before?: unknown;
69
+ after?: unknown;
70
+ }>;
71
+ request_id?: string | undefined;
72
+ }, {
73
+ event_id: string;
74
+ event_type: string;
75
+ occurred_at: string;
76
+ tenant: {
77
+ id: string;
78
+ parent_id: string | null;
79
+ };
80
+ actor: {
81
+ type: "user" | "service" | "system";
82
+ id: string;
83
+ via: string;
84
+ };
85
+ resource: {
86
+ type: string;
87
+ id: string;
88
+ };
89
+ changes: Record<string, {
90
+ before?: unknown;
91
+ after?: unknown;
92
+ }>;
93
+ request_id?: string | undefined;
94
+ }>;
95
+ export type AuditEvent = z.infer<typeof auditEventSchema>;
96
+ export declare const auditBatchSchema: z.ZodObject<{
97
+ events: z.ZodArray<z.ZodObject<{
98
+ event_id: z.ZodString;
99
+ event_type: z.ZodString;
100
+ occurred_at: z.ZodString;
101
+ tenant: z.ZodObject<{
102
+ id: z.ZodString;
103
+ parent_id: z.ZodNullable<z.ZodString>;
104
+ }, "strip", z.ZodTypeAny, {
105
+ id: string;
106
+ parent_id: string | null;
107
+ }, {
108
+ id: string;
109
+ parent_id: string | null;
110
+ }>;
111
+ actor: z.ZodObject<{
112
+ type: z.ZodEnum<["user", "service", "system"]>;
113
+ id: z.ZodString;
114
+ via: z.ZodString;
115
+ }, "strip", z.ZodTypeAny, {
116
+ type: "user" | "service" | "system";
117
+ id: string;
118
+ via: string;
119
+ }, {
120
+ type: "user" | "service" | "system";
121
+ id: string;
122
+ via: string;
123
+ }>;
124
+ resource: z.ZodObject<{
125
+ type: z.ZodString;
126
+ id: z.ZodString;
127
+ }, "strip", z.ZodTypeAny, {
128
+ type: string;
129
+ id: string;
130
+ }, {
131
+ type: string;
132
+ id: string;
133
+ }>;
134
+ changes: z.ZodRecord<z.ZodString, z.ZodObject<{
135
+ before: z.ZodUnknown;
136
+ after: z.ZodUnknown;
137
+ }, "strip", z.ZodTypeAny, {
138
+ before?: unknown;
139
+ after?: unknown;
140
+ }, {
141
+ before?: unknown;
142
+ after?: unknown;
143
+ }>>;
144
+ request_id: z.ZodOptional<z.ZodString>;
145
+ }, "strip", z.ZodTypeAny, {
146
+ event_id: string;
147
+ event_type: string;
148
+ occurred_at: string;
149
+ tenant: {
150
+ id: string;
151
+ parent_id: string | null;
152
+ };
153
+ actor: {
154
+ type: "user" | "service" | "system";
155
+ id: string;
156
+ via: string;
157
+ };
158
+ resource: {
159
+ type: string;
160
+ id: string;
161
+ };
162
+ changes: Record<string, {
163
+ before?: unknown;
164
+ after?: unknown;
165
+ }>;
166
+ request_id?: string | undefined;
167
+ }, {
168
+ event_id: string;
169
+ event_type: string;
170
+ occurred_at: string;
171
+ tenant: {
172
+ id: string;
173
+ parent_id: string | null;
174
+ };
175
+ actor: {
176
+ type: "user" | "service" | "system";
177
+ id: string;
178
+ via: string;
179
+ };
180
+ resource: {
181
+ type: string;
182
+ id: string;
183
+ };
184
+ changes: Record<string, {
185
+ before?: unknown;
186
+ after?: unknown;
187
+ }>;
188
+ request_id?: string | undefined;
189
+ }>, "many">;
190
+ }, "strip", z.ZodTypeAny, {
191
+ events: {
192
+ event_id: string;
193
+ event_type: string;
194
+ occurred_at: string;
195
+ tenant: {
196
+ id: string;
197
+ parent_id: string | null;
198
+ };
199
+ actor: {
200
+ type: "user" | "service" | "system";
201
+ id: string;
202
+ via: string;
203
+ };
204
+ resource: {
205
+ type: string;
206
+ id: string;
207
+ };
208
+ changes: Record<string, {
209
+ before?: unknown;
210
+ after?: unknown;
211
+ }>;
212
+ request_id?: string | undefined;
213
+ }[];
214
+ }, {
215
+ events: {
216
+ event_id: string;
217
+ event_type: string;
218
+ occurred_at: string;
219
+ tenant: {
220
+ id: string;
221
+ parent_id: string | null;
222
+ };
223
+ actor: {
224
+ type: "user" | "service" | "system";
225
+ id: string;
226
+ via: string;
227
+ };
228
+ resource: {
229
+ type: string;
230
+ id: string;
231
+ };
232
+ changes: Record<string, {
233
+ before?: unknown;
234
+ after?: unknown;
235
+ }>;
236
+ request_id?: string | undefined;
237
+ }[];
238
+ }>;
239
+ export type AuditBatch = z.infer<typeof auditBatchSchema>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.auditBatchSchema = exports.auditEventSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.auditEventSchema = zod_1.z.object({
6
+ event_id: zod_1.z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/, 'must be a ULID'),
7
+ event_type: zod_1.z
8
+ .string()
9
+ .regex(/^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$/, 'must be "<resource>.<operation>"'),
10
+ occurred_at: zod_1.z.string().datetime({ offset: false }),
11
+ tenant: zod_1.z.object({
12
+ id: zod_1.z.string().min(1),
13
+ parent_id: zod_1.z.string().nullable(),
14
+ }),
15
+ actor: zod_1.z.object({
16
+ type: zod_1.z.enum(['user', 'service', 'system']),
17
+ id: zod_1.z.string().min(1),
18
+ via: zod_1.z.string().min(1),
19
+ }),
20
+ resource: zod_1.z.object({
21
+ type: zod_1.z.string().min(1),
22
+ id: zod_1.z.string().min(1),
23
+ }),
24
+ changes: zod_1.z.record(zod_1.z.string(), zod_1.z.object({
25
+ before: zod_1.z.unknown(),
26
+ after: zod_1.z.unknown(),
27
+ })),
28
+ request_id: zod_1.z.string().optional(),
29
+ });
30
+ exports.auditBatchSchema = zod_1.z.object({
31
+ events: zod_1.z.array(exports.auditEventSchema).min(1).max(100),
32
+ });
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1ZGl0L3NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBd0I7QUFFWCxRQUFBLGdCQUFnQixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDdkMsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsZ0JBQWdCLENBQUM7SUFDeEUsVUFBVSxFQUFFLE9BQUM7U0FDVixNQUFNLEVBQUU7U0FDUixLQUFLLENBQUMsb0NBQW9DLEVBQUUsa0NBQWtDLENBQUM7SUFDbEYsV0FBVyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDbkQsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLENBQUM7UUFDZixFQUFFLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDckIsU0FBUyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7S0FDakMsQ0FBQztJQUNGLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2QsSUFBSSxFQUFFLE9BQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLEVBQUUsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyQixHQUFHLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7S0FDdkIsQ0FBQztJQUNGLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2pCLElBQUksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QixFQUFFLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7S0FDdEIsQ0FBQztJQUNGLE9BQU8sRUFBRSxPQUFDLENBQUMsTUFBTSxDQUNmLE9BQUMsQ0FBQyxNQUFNLEVBQUUsRUFDVixPQUFDLENBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUU7UUFDbkIsS0FBSyxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUU7S0FDbkIsQ0FBQyxDQUNIO0lBQ0QsVUFBVSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDbEMsQ0FBQyxDQUFDO0FBSVUsUUFBQSxnQkFBZ0IsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3ZDLE1BQU0sRUFBRSxPQUFDLENBQUMsS0FBSyxDQUFDLHdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7Q0FDbEQsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeiB9IGZyb20gJ3pvZCc7XG5cbmV4cG9ydCBjb25zdCBhdWRpdEV2ZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBldmVudF9pZDogei5zdHJpbmcoKS5yZWdleCgvXlswLTlBLUhKS01OUC1UVi1aXXsyNn0kLywgJ211c3QgYmUgYSBVTElEJyksXG4gIGV2ZW50X3R5cGU6IHpcbiAgICAuc3RyaW5nKClcbiAgICAucmVnZXgoL15bYS16XVthLXowLTlfXSpcXC5bYS16XVthLXowLTlfXSokLywgJ211c3QgYmUgXCI8cmVzb3VyY2U+LjxvcGVyYXRpb24+XCInKSxcbiAgb2NjdXJyZWRfYXQ6IHouc3RyaW5nKCkuZGF0ZXRpbWUoeyBvZmZzZXQ6IGZhbHNlIH0pLFxuICB0ZW5hbnQ6IHoub2JqZWN0KHtcbiAgICBpZDogei5zdHJpbmcoKS5taW4oMSksXG4gICAgcGFyZW50X2lkOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gIH0pLFxuICBhY3Rvcjogei5vYmplY3Qoe1xuICAgIHR5cGU6IHouZW51bShbJ3VzZXInLCAnc2VydmljZScsICdzeXN0ZW0nXSksXG4gICAgaWQ6IHouc3RyaW5nKCkubWluKDEpLFxuICAgIHZpYTogei5zdHJpbmcoKS5taW4oMSksXG4gIH0pLFxuICByZXNvdXJjZTogei5vYmplY3Qoe1xuICAgIHR5cGU6IHouc3RyaW5nKCkubWluKDEpLFxuICAgIGlkOiB6LnN0cmluZygpLm1pbigxKSxcbiAgfSksXG4gIGNoYW5nZXM6IHoucmVjb3JkKFxuICAgIHouc3RyaW5nKCksXG4gICAgei5vYmplY3Qoe1xuICAgICAgYmVmb3JlOiB6LnVua25vd24oKSxcbiAgICAgIGFmdGVyOiB6LnVua25vd24oKSxcbiAgICB9KSxcbiAgKSxcbiAgcmVxdWVzdF9pZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCB0eXBlIEF1ZGl0RXZlbnQgPSB6LmluZmVyPHR5cGVvZiBhdWRpdEV2ZW50U2NoZW1hPjtcblxuZXhwb3J0IGNvbnN0IGF1ZGl0QmF0Y2hTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGV2ZW50czogei5hcnJheShhdWRpdEV2ZW50U2NoZW1hKS5taW4oMSkubWF4KDEwMCksXG59KTtcblxuZXhwb3J0IHR5cGUgQXVkaXRCYXRjaCA9IHouaW5mZXI8dHlwZW9mIGF1ZGl0QmF0Y2hTY2hlbWE+O1xuIl19
@@ -0,0 +1,24 @@
1
+ export interface SignRequestParams {
2
+ method: string;
3
+ path: string;
4
+ serviceId: string;
5
+ timestamp: string;
6
+ nonce: string;
7
+ /** Raw JSON body string, or empty string for no body. */
8
+ body: string;
9
+ secret: string;
10
+ }
11
+ /**
12
+ * HMAC-SHA256 signature over a canonical request representation. Producer
13
+ * (this SDK) and verifier (`serviceAuthMiddleware` in `@uengage/common`) must
14
+ * compute the same canonical string, so any change here MUST be mirrored
15
+ * there. The canonical form is newline-separated, with no trailing newline:
16
+ *
17
+ * <METHOD>
18
+ * <PATH>
19
+ * <X-Service-Id>
20
+ * <X-Timestamp>
21
+ * <X-Nonce>
22
+ * <sha256-hex of body, or empty string for no body>
23
+ */
24
+ export declare function signRequest(params: SignRequestParams): string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signRequest = signRequest;
4
+ const node_crypto_1 = require("node:crypto");
5
+ /**
6
+ * HMAC-SHA256 signature over a canonical request representation. Producer
7
+ * (this SDK) and verifier (`serviceAuthMiddleware` in `@uengage/common`) must
8
+ * compute the same canonical string, so any change here MUST be mirrored
9
+ * there. The canonical form is newline-separated, with no trailing newline:
10
+ *
11
+ * <METHOD>
12
+ * <PATH>
13
+ * <X-Service-Id>
14
+ * <X-Timestamp>
15
+ * <X-Nonce>
16
+ * <sha256-hex of body, or empty string for no body>
17
+ */
18
+ function signRequest(params) {
19
+ const bodyHash = params.body ? (0, node_crypto_1.createHash)('sha256').update(params.body).digest('hex') : '';
20
+ const canonical = [
21
+ params.method.toUpperCase(),
22
+ params.path,
23
+ params.serviceId,
24
+ params.timestamp,
25
+ params.nonce,
26
+ bodyHash,
27
+ ].join('\n');
28
+ return (0, node_crypto_1.createHmac)('sha256', params.secret).update(canonical).digest('hex');
29
+ }
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdWRpdC9zaWduLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMEJBLGtDQVdDO0FBckNELDZDQUFxRDtBQWFyRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixXQUFXLENBQUMsTUFBeUI7SUFDbkQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBQSx3QkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDM0YsTUFBTSxTQUFTLEdBQUc7UUFDaEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUU7UUFDM0IsTUFBTSxDQUFDLElBQUk7UUFDWCxNQUFNLENBQUMsU0FBUztRQUNoQixNQUFNLENBQUMsU0FBUztRQUNoQixNQUFNLENBQUMsS0FBSztRQUNaLFFBQVE7S0FDVCxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNiLE9BQU8sSUFBQSx3QkFBVSxFQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSG1hYywgY3JlYXRlSGFzaCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcblxuZXhwb3J0IGludGVyZmFjZSBTaWduUmVxdWVzdFBhcmFtcyB7XG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHNlcnZpY2VJZDogc3RyaW5nO1xuICB0aW1lc3RhbXA6IHN0cmluZztcbiAgbm9uY2U6IHN0cmluZztcbiAgLyoqIFJhdyBKU09OIGJvZHkgc3RyaW5nLCBvciBlbXB0eSBzdHJpbmcgZm9yIG5vIGJvZHkuICovXG4gIGJvZHk6IHN0cmluZztcbiAgc2VjcmV0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSE1BQy1TSEEyNTYgc2lnbmF0dXJlIG92ZXIgYSBjYW5vbmljYWwgcmVxdWVzdCByZXByZXNlbnRhdGlvbi4gUHJvZHVjZXJcbiAqICh0aGlzIFNESykgYW5kIHZlcmlmaWVyIChgc2VydmljZUF1dGhNaWRkbGV3YXJlYCBpbiBgQHVlbmdhZ2UvY29tbW9uYCkgbXVzdFxuICogY29tcHV0ZSB0aGUgc2FtZSBjYW5vbmljYWwgc3RyaW5nLCBzbyBhbnkgY2hhbmdlIGhlcmUgTVVTVCBiZSBtaXJyb3JlZFxuICogdGhlcmUuIFRoZSBjYW5vbmljYWwgZm9ybSBpcyBuZXdsaW5lLXNlcGFyYXRlZCwgd2l0aCBubyB0cmFpbGluZyBuZXdsaW5lOlxuICpcbiAqICAgPE1FVEhPRD5cbiAqICAgPFBBVEg+XG4gKiAgIDxYLVNlcnZpY2UtSWQ+XG4gKiAgIDxYLVRpbWVzdGFtcD5cbiAqICAgPFgtTm9uY2U+XG4gKiAgIDxzaGEyNTYtaGV4IG9mIGJvZHksIG9yIGVtcHR5IHN0cmluZyBmb3Igbm8gYm9keT5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25SZXF1ZXN0KHBhcmFtczogU2lnblJlcXVlc3RQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCBib2R5SGFzaCA9IHBhcmFtcy5ib2R5ID8gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHBhcmFtcy5ib2R5KS5kaWdlc3QoJ2hleCcpIDogJyc7XG4gIGNvbnN0IGNhbm9uaWNhbCA9IFtcbiAgICBwYXJhbXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgcGFyYW1zLnBhdGgsXG4gICAgcGFyYW1zLnNlcnZpY2VJZCxcbiAgICBwYXJhbXMudGltZXN0YW1wLFxuICAgIHBhcmFtcy5ub25jZSxcbiAgICBib2R5SGFzaCxcbiAgXS5qb2luKCdcXG4nKTtcbiAgcmV0dXJuIGNyZWF0ZUhtYWMoJ3NoYTI1NicsIHBhcmFtcy5zZWNyZXQpLnVwZGF0ZShjYW5vbmljYWwpLmRpZ2VzdCgnaGV4Jyk7XG59XG4iXX0=
@@ -0,0 +1,19 @@
1
+ import { type PlatformAuth, type PlatformAuthInput, type PlatformConfigInput } from '../config';
2
+ import type { BusinessGroupName, BusinessRecord } from './schema';
3
+ export interface BusinessGetOptions {
4
+ groups?: readonly BusinessGroupName[];
5
+ }
6
+ export interface BusinessClient {
7
+ config(input: PlatformConfigInput): BusinessClient;
8
+ auth(input: PlatformAuthInput | PlatformAuth): BusinessClient;
9
+ /** GET /v1/business/:id - returns the record or throws BusinessApiError. */
10
+ get(id: number, opts?: BusinessGetOptions): Promise<BusinessRecord>;
11
+ /** GET /v1/business/bulk - returns matched records (missing ids dropped). */
12
+ bulk(ids: readonly number[], opts?: BusinessGetOptions): Promise<BusinessRecord[]>;
13
+ }
14
+ export declare class BusinessApiError extends Error {
15
+ readonly status: number;
16
+ readonly body: string;
17
+ constructor(status: number, body: string);
18
+ }
19
+ export declare function createBusinessClient(input?: PlatformConfigInput): BusinessClient;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BusinessApiError = void 0;
4
+ exports.createBusinessClient = createBusinessClient;
5
+ const config_1 = require("../config");
6
+ const http_1 = require("../http");
7
+ class BusinessApiError extends Error {
8
+ status;
9
+ body;
10
+ constructor(status, body) {
11
+ super(`business API ${status}: ${body}`);
12
+ this.name = 'BusinessApiError';
13
+ this.status = status;
14
+ this.body = body;
15
+ }
16
+ }
17
+ exports.BusinessApiError = BusinessApiError;
18
+ function createBusinessClient(input = {}) {
19
+ const state = new config_1.ConfigState();
20
+ state.apply(input);
21
+ const client = {
22
+ config(opts) {
23
+ state.apply(opts);
24
+ return client;
25
+ },
26
+ auth(opts) {
27
+ state.setAuth(opts);
28
+ return client;
29
+ },
30
+ async get(id, opts = {}) {
31
+ if (!Number.isInteger(id) || id <= 0) {
32
+ throw new Error(`business.get: id must be a positive integer (got ${id})`);
33
+ }
34
+ const path = `/v1/business/${id}`;
35
+ const query = opts.groups?.length ? `?groups=${opts.groups.join(',')}` : '';
36
+ const config = state.resolve();
37
+ const headers = (0, http_1.buildHeaders)(config, { method: 'GET', path });
38
+ const res = await config.fetchFn(`${config.baseUrl}${path}${query}`, {
39
+ method: 'GET',
40
+ headers,
41
+ });
42
+ if (!res.ok) {
43
+ throw new BusinessApiError(res.status, await res.text());
44
+ }
45
+ return (await res.json());
46
+ },
47
+ async bulk(ids, opts = {}) {
48
+ if (ids.length === 0) {
49
+ throw new Error('business.bulk: ids must not be empty');
50
+ }
51
+ for (const n of ids) {
52
+ if (!Number.isInteger(n) || n <= 0) {
53
+ throw new Error(`business.bulk: every id must be a positive integer (got ${n})`);
54
+ }
55
+ }
56
+ const path = '/v1/business/bulk';
57
+ const params = new URLSearchParams({ ids: ids.join(',') });
58
+ if (opts.groups?.length)
59
+ params.set('groups', opts.groups.join(','));
60
+ const config = state.resolve();
61
+ const headers = (0, http_1.buildHeaders)(config, { method: 'GET', path });
62
+ const res = await config.fetchFn(`${config.baseUrl}${path}?${params.toString()}`, {
63
+ method: 'GET',
64
+ headers,
65
+ });
66
+ if (!res.ok) {
67
+ throw new BusinessApiError(res.status, await res.text());
68
+ }
69
+ return (await res.json());
70
+ },
71
+ };
72
+ return client;
73
+ }
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2J1c2luZXNzL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFrQ0Esb0RBd0RDO0FBMUZELHNDQUttQjtBQUNuQixrQ0FBdUM7QUFnQnZDLE1BQWEsZ0JBQWlCLFNBQVEsS0FBSztJQUNoQyxNQUFNLENBQVM7SUFDZixJQUFJLENBQVM7SUFFdEIsWUFBWSxNQUFjLEVBQUUsSUFBWTtRQUN0QyxLQUFLLENBQUMsZ0JBQWdCLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBVkQsNENBVUM7QUFFRCxTQUFnQixvQkFBb0IsQ0FBQyxRQUE2QixFQUFFO0lBQ2xFLE1BQU0sS0FBSyxHQUFHLElBQUksb0JBQVcsRUFBRSxDQUFDO0lBQ2hDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFbkIsTUFBTSxNQUFNLEdBQW1CO1FBQzdCLE1BQU0sQ0FBQyxJQUFJO1lBQ1QsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsQixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUk7WUFDUCxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BCLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLEdBQUcsRUFBRTtZQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sSUFBSSxL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SUFFRixPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29uZmlnU3RhdGUsXG4gIHR5cGUgUGxhdGZvcm1BdXRoLFxuICB0eXBlIFBsYXRmb3JtQXV0aElucHV0LFxuICB0eXBlIFBsYXRmb3JtQ29uZmlnSW5wdXQsXG59IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBidWlsZEhlYWRlcnMgfSBmcm9tICcuLi9odHRwJztcbmltcG9ydCB0eXBlIHsgQnVzaW5lc3NHcm91cE5hbWUsIEJ1c2luZXNzUmVjb3JkIH0gZnJvbSAnLi9zY2hlbWEnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1c2luZXNzR2V0T3B0aW9ucyB7XG4gIGdyb3Vwcz86IHJlYWRvbmx5IEJ1c2luZXNzR3JvdXBOYW1lW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NDbGllbnQge1xuICBjb25maWcoaW5wdXQ6IFBsYXRmb3JtQ29uZmlnSW5wdXQpOiBCdXNpbmVzc0NsaWVudDtcbiAgYXV0aChpbnB1dDogUGxhdGZvcm1BdXRoSW5wdXQgfCBQbGF0Zm9ybUF1dGgpOiBCdXNpbmVzc0NsaWVudDtcbiAgLyoqIEdFVCAvdjEvYnVzaW5lc3MvOmlkIC0gcmV0dXJucyB0aGUgcmVjb3JkIG9yIHRocm93cyBCdXNpbmVzc0FwaUVycm9yLiAqL1xuICBnZXQoaWQ6IG51bWJlciwgb3B0cz86IEJ1c2luZXNzR2V0T3B0aW9ucyk6IFByb21pc2U8QnVzaW5lc3NSZWNvcmQ+O1xuICAvKiogR0VUIC92MS9idXNpbmVzcy9idWxrIC0gcmV0dXJucyBtYXRjaGVkIHJlY29yZHMgKG1pc3NpbmcgaWRzIGRyb3BwZWQpLiAqL1xuICBidWxrKGlkczogcmVhZG9ubHkgbnVtYmVyW10sIG9wdHM/OiBCdXNpbmVzc0dldE9wdGlvbnMpOiBQcm9taXNlPEJ1c2luZXNzUmVjb3JkW10+O1xufVxuXG5leHBvcnQgY2xhc3MgQnVzaW5lc3NBcGlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG4gIHJlYWRvbmx5IGJvZHk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzdGF0dXM6IG51bWJlciwgYm9keTogc3RyaW5nKSB7XG4gICAgc3VwZXIoYGJ1c2luZXNzIEFQSSAke3N0YXR1c306ICR7Ym9keX1gKTtcbiAgICB0aGlzLm5hbWUgPSAnQnVzaW5lc3NBcGlFcnJvcic7XG4gICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQnVzaW5lc3NDbGllbnQoaW5wdXQ6IFBsYXRmb3JtQ29uZmlnSW5wdXQgPSB7fSk6IEJ1c2luZXNzQ2xpZW50IHtcbiAgY29uc3Qgc3RhdGUgPSBuZXcgQ29uZmlnU3RhdGUoKTtcbiAgc3RhdGUuYXBwbHkoaW5wdXQpO1xuXG4gIGNvbnN0IGNsaWVudDogQnVzaW5lc3NDbGllbnQgPSB7XG4gICAgY29uZmlnKG9wdHMpIHtcbiAgICAgIHN0YXRlLmFwcGx5KG9wdHMpO1xuICAgICAgcmV0dXJuIGNsaWVudDtcbiAgICB9LFxuICAgIGF1dGgob3B0cykge1xuICAgICAgc3RhdGUuc2V0QXV0aChvcHRzKTtcbiAgICAgIHJldHVybiBjbGllbnQ7XG4gICAgfSxcbiAgICBhc3luYyBnZXQoaWQsIG9wdHMgPSB7fSkge1xuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGlkKSB8fCBpZCA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgYnVzaW5lc3MuZ2V0OiBpZCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciAoZ290ICR7aWR9KWApO1xuICAgICAgfVxuICAgICAgY29uc3QgcGF0aCA9IGAvdjEvYnVzaW5lc3MvJHtpZH1gO1xuICAgICAgY29uc3QgcXVlcnkgPSBvcHRzLmdyb3Vwcz8ubGVuZ3RoID8gYD9ncm91cHM9JHtvcHRzLmdyb3Vwcy5qb2luKCcsJyl9YCA6ICcnO1xuICAgICAgY29uc3QgY29uZmlnID0gc3RhdGUucmVzb2x2ZSgpO1xuICAgICAgY29uc3QgaGVhZGVycyA9IGJ1aWxkSGVhZGVycyhjb25maWcsIHsgbWV0aG9kOiAnR0VUJywgcGF0aCB9KTtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGNvbmZpZy5mZXRjaEZuKGAke2NvbmZpZy5iYXNlVXJsfSR7cGF0aH0ke3F1ZXJ5fWAsIHtcbiAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgIH0pO1xuICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEJ1c2luZXNzQXBpRXJyb3IocmVzLnN0YXR1cywgYXdhaXQgcmVzLnRleHQoKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKGF3YWl0IHJlcy5qc29uKCkpIGFzIEJ1c2luZXNzUmVjb3JkO1xuICAgIH0sXG4gICAgYXN5bmMgYnVsayhpZHMsIG9wdHMgPSB7fSkge1xuICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdidXNpbmVzcy5idWxrOiBpZHMgbXVzdCBub3QgYmUgZW1wdHknKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgbiBvZiBpZHMpIHtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG4pIHx8IG4gPD0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgYnVzaW5lc3MuYnVsazogZXZlcnkgaWQgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIgKGdvdCAke259KWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBwYXRoID0gJy92MS9idXNpbmVzcy9idWxrJztcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBpZHM6IGlkcy5qb2luKCcsJykgfSk7XG4gICAgICBpZiAob3B0cy5ncm91cHM/Lmxlbmd0aCkgcGFyYW1zLnNldCgnZ3JvdXBzJywgb3B0cy5ncm91cHMuam9pbignLCcpKTtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IHN0YXRlLnJlc29sdmUoKTtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBidWlsZEhlYWRlcnMoY29uZmlnLCB7IG1ldGhvZDogJ0dFVCcsIHBhdGggfSk7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBjb25maWcuZmV0Y2hGbihgJHtjb25maWcuYmFzZVVybH0ke3BhdGh9PyR7cGFyYW1zLnRvU3RyaW5nKCl9YCwge1xuICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgfSk7XG4gICAgICBpZiAoIXJlcy5vaykge1xuICAgICAgICB0aHJvdyBuZXcgQnVzaW5lc3NBcGlFcnJvcihyZXMuc3RhdHVzLCBhd2FpdCByZXMudGV4dCgpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoYXdhaXQgcmVzLmpzb24oKSkgYXMgQnVzaW5lc3NSZWNvcmRbXTtcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBjbGllbnQ7XG59XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export { BUSINESS_GROUPS, type BusinessGroupName, type BusinessRecord, type BusinessDetails, type BusinessGst, type BusinessPaymentGateway, } from './schema';
2
+ export { createBusinessClient, BusinessApiError, type BusinessClient, type BusinessGetOptions, } from './client';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BusinessApiError = exports.createBusinessClient = exports.BUSINESS_GROUPS = void 0;
4
+ var schema_1 = require("./schema");
5
+ Object.defineProperty(exports, "BUSINESS_GROUPS", { enumerable: true, get: function () { return schema_1.BUSINESS_GROUPS; } });
6
+ var client_1 = require("./client");
7
+ Object.defineProperty(exports, "createBusinessClient", { enumerable: true, get: function () { return client_1.createBusinessClient; } });
8
+ Object.defineProperty(exports, "BusinessApiError", { enumerable: true, get: function () { return client_1.BusinessApiError; } });
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVzaW5lc3MvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBT2tCO0FBTmhCLHlHQUFBLGVBQWUsT0FBQTtBQU9qQixtQ0FLa0I7QUFKaEIsOEdBQUEsb0JBQW9CLE9BQUE7QUFDcEIsMEdBQUEsZ0JBQWdCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge1xuICBCVVNJTkVTU19HUk9VUFMsXG4gIHR5cGUgQnVzaW5lc3NHcm91cE5hbWUsXG4gIHR5cGUgQnVzaW5lc3NSZWNvcmQsXG4gIHR5cGUgQnVzaW5lc3NEZXRhaWxzLFxuICB0eXBlIEJ1c2luZXNzR3N0LFxuICB0eXBlIEJ1c2luZXNzUGF5bWVudEdhdGV3YXksXG59IGZyb20gJy4vc2NoZW1hJztcbmV4cG9ydCB7XG4gIGNyZWF0ZUJ1c2luZXNzQ2xpZW50LFxuICBCdXNpbmVzc0FwaUVycm9yLFxuICB0eXBlIEJ1c2luZXNzQ2xpZW50LFxuICB0eXBlIEJ1c2luZXNzR2V0T3B0aW9ucyxcbn0gZnJvbSAnLi9jbGllbnQnO1xuIl19
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Group names recognised by the business read API. Mirrors the GROUPS
3
+ * registry in services/business; if the server adds a group, add it here.
4
+ */
5
+ export declare const BUSINESS_GROUPS: readonly ["business_details", "gst", "payment_gateway"];
6
+ export type BusinessGroupName = (typeof BUSINESS_GROUPS)[number];
7
+ export interface BusinessDetails {
8
+ name: string | null;
9
+ }
10
+ export interface BusinessGst {
11
+ state: string | null;
12
+ gst_no: string | null;
13
+ }
14
+ export interface BusinessPaymentGateway {
15
+ razorpay: {
16
+ key: string | null;
17
+ secret: string | null;
18
+ };
19
+ }
20
+ /**
21
+ * Response shape from GET /v1/business/:id and the entries returned by
22
+ * GET /v1/business/bulk. Group keys are optional - the server includes
23
+ * only the groups that were both requested and authorized for the caller.
24
+ */
25
+ export interface BusinessRecord {
26
+ id: number;
27
+ parent_id: number | null;
28
+ business_details?: BusinessDetails;
29
+ gst?: BusinessGst;
30
+ payment_gateway?: BusinessPaymentGateway;
31
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BUSINESS_GROUPS = void 0;
4
+ /**
5
+ * Group names recognised by the business read API. Mirrors the GROUPS
6
+ * registry in services/business; if the server adds a group, add it here.
7
+ */
8
+ exports.BUSINESS_GROUPS = ['business_details', 'gst', 'payment_gateway'];
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2J1c2luZXNzL3NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7O0dBR0c7QUFDVSxRQUFBLGVBQWUsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHcm91cCBuYW1lcyByZWNvZ25pc2VkIGJ5IHRoZSBidXNpbmVzcyByZWFkIEFQSS4gTWlycm9ycyB0aGUgR1JPVVBTXG4gKiByZWdpc3RyeSBpbiBzZXJ2aWNlcy9idXNpbmVzczsgaWYgdGhlIHNlcnZlciBhZGRzIGEgZ3JvdXAsIGFkZCBpdCBoZXJlLlxuICovXG5leHBvcnQgY29uc3QgQlVTSU5FU1NfR1JPVVBTID0gWydidXNpbmVzc19kZXRhaWxzJywgJ2dzdCcsICdwYXltZW50X2dhdGV3YXknXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEJ1c2luZXNzR3JvdXBOYW1lID0gKHR5cGVvZiBCVVNJTkVTU19HUk9VUFMpW251bWJlcl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NEZXRhaWxzIHtcbiAgbmFtZTogc3RyaW5nIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCdXNpbmVzc0dzdCB7XG4gIHN0YXRlOiBzdHJpbmcgfCBudWxsO1xuICBnc3Rfbm86IHN0cmluZyB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NQYXltZW50R2F0ZXdheSB7XG4gIHJhem9ycGF5OiB7XG4gICAga2V5OiBzdHJpbmcgfCBudWxsO1xuICAgIHNlY3JldDogc3RyaW5nIHwgbnVsbDtcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNwb25zZSBzaGFwZSBmcm9tIEdFVCAvdjEvYnVzaW5lc3MvOmlkIGFuZCB0aGUgZW50cmllcyByZXR1cm5lZCBieVxuICogR0VUIC92MS9idXNpbmVzcy9idWxrLiBHcm91cCBrZXlzIGFyZSBvcHRpb25hbCAtIHRoZSBzZXJ2ZXIgaW5jbHVkZXNcbiAqIG9ubHkgdGhlIGdyb3VwcyB0aGF0IHdlcmUgYm90aCByZXF1ZXN0ZWQgYW5kIGF1dGhvcml6ZWQgZm9yIHRoZSBjYWxsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NSZWNvcmQge1xuICBpZDogbnVtYmVyO1xuICBwYXJlbnRfaWQ6IG51bWJlciB8IG51bGw7XG4gIGJ1c2luZXNzX2RldGFpbHM/OiBCdXNpbmVzc0RldGFpbHM7XG4gIGdzdD86IEJ1c2luZXNzR3N0O1xuICBwYXltZW50X2dhdGV3YXk/OiBCdXNpbmVzc1BheW1lbnRHYXRld2F5O1xufVxuIl19
@@ -0,0 +1,64 @@
1
+ import type { Logger } from '@uengage.io/js-logger';
2
+ export declare const DEFAULT_BASE_URL = "https://platform.uengage.io";
3
+ /**
4
+ * Resolved auth state. Discriminated by `type` so consumers can narrow.
5
+ */
6
+ export type PlatformAuth = {
7
+ type: 'hmac';
8
+ secret: string;
9
+ serviceId: string;
10
+ } | {
11
+ type: 'bearer';
12
+ token: string;
13
+ };
14
+ export interface PlatformConfig {
15
+ baseUrl: string;
16
+ auth?: PlatformAuth;
17
+ fetchFn: typeof fetch;
18
+ logger?: Logger;
19
+ }
20
+ /**
21
+ * Caller-facing input shape. `auth` accepts either a discriminated
22
+ * PlatformAuth or the looser PlatformAuthInput - the looser form is
23
+ * also what `.auth()` accepts.
24
+ */
25
+ export interface PlatformConfigInput {
26
+ baseUrl?: string;
27
+ auth?: PlatformAuthInput | PlatformAuth;
28
+ fetchFn?: typeof fetch;
29
+ logger?: Logger;
30
+ }
31
+ /**
32
+ * `.auth()` shape. Pass either `{token}` (Bearer) or `{secret, serviceId}`
33
+ * (HMAC). Mixing both throws.
34
+ */
35
+ export interface PlatformAuthInput {
36
+ token?: string;
37
+ secret?: string;
38
+ serviceId?: string;
39
+ }
40
+ /**
41
+ * Resolve env-defaulted config. Re-read on every call so that callers can
42
+ * set env vars after the SDK has been imported and still pick them up on
43
+ * the next request.
44
+ */
45
+ export declare function envDefaults(): PlatformConfig;
46
+ /**
47
+ * Coerce `.auth()` input or `config({auth})` input into a typed PlatformAuth.
48
+ * Throws if the input has no usable credentials or mixes HMAC + Bearer.
49
+ */
50
+ export declare function normalizeAuth(input: PlatformAuthInput | PlatformAuth): PlatformAuth;
51
+ /**
52
+ * Mutable config shared by clients. `apply()` and `setAuth()` are how the
53
+ * chainable `.config()` / `.auth()` methods write back. `resolve()` produces
54
+ * the effective config for one request, falling back to current env state
55
+ * for fields the caller hasn't pinned.
56
+ */
57
+ export declare class ConfigState {
58
+ private overrides;
59
+ private explicitAuth;
60
+ private hasExplicitAuth;
61
+ apply(input: PlatformConfigInput): void;
62
+ setAuth(input: PlatformAuthInput | PlatformAuth): void;
63
+ resolve(): PlatformConfig;
64
+ }
package/dist/config.js ADDED
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigState = exports.DEFAULT_BASE_URL = void 0;
4
+ exports.envDefaults = envDefaults;
5
+ exports.normalizeAuth = normalizeAuth;
6
+ exports.DEFAULT_BASE_URL = 'https://platform.uengage.io';
7
+ /**
8
+ * Resolve env-defaulted config. Re-read on every call so that callers can
9
+ * set env vars after the SDK has been imported and still pick them up on
10
+ * the next request.
11
+ */
12
+ function envDefaults() {
13
+ return {
14
+ baseUrl: process.env.PLATFORM_BASE_URL ?? exports.DEFAULT_BASE_URL,
15
+ auth: envAuth(),
16
+ fetchFn: globalThis.fetch,
17
+ };
18
+ }
19
+ function envAuth() {
20
+ const secret = process.env.PLATFORM_SIGNING_SECRET;
21
+ const serviceId = process.env.PLATFORM_SERVICE_ID;
22
+ const token = process.env.PLATFORM_AUTH_TOKEN;
23
+ if (token)
24
+ return { type: 'bearer', token };
25
+ if (secret && serviceId)
26
+ return { type: 'hmac', secret, serviceId };
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Coerce `.auth()` input or `config({auth})` input into a typed PlatformAuth.
31
+ * Throws if the input has no usable credentials or mixes HMAC + Bearer.
32
+ */
33
+ function normalizeAuth(input) {
34
+ if ('type' in input)
35
+ return input;
36
+ if (input.token) {
37
+ if (input.secret || input.serviceId) {
38
+ throw new Error('auth(): pass either {token} or {secret, serviceId}, not both');
39
+ }
40
+ return { type: 'bearer', token: input.token };
41
+ }
42
+ if (input.secret && input.serviceId) {
43
+ return { type: 'hmac', secret: input.secret, serviceId: input.serviceId };
44
+ }
45
+ throw new Error('auth(): must provide either {token} or {secret, serviceId}');
46
+ }
47
+ /**
48
+ * Mutable config shared by clients. `apply()` and `setAuth()` are how the
49
+ * chainable `.config()` / `.auth()` methods write back. `resolve()` produces
50
+ * the effective config for one request, falling back to current env state
51
+ * for fields the caller hasn't pinned.
52
+ */
53
+ class ConfigState {
54
+ overrides = {};
55
+ explicitAuth;
56
+ hasExplicitAuth = false;
57
+ apply(input) {
58
+ if (input.baseUrl !== undefined)
59
+ this.overrides.baseUrl = input.baseUrl;
60
+ if (input.fetchFn !== undefined)
61
+ this.overrides.fetchFn = input.fetchFn;
62
+ if (input.logger !== undefined)
63
+ this.overrides.logger = input.logger;
64
+ if (input.auth !== undefined) {
65
+ this.explicitAuth = normalizeAuth(input.auth);
66
+ this.hasExplicitAuth = true;
67
+ }
68
+ }
69
+ setAuth(input) {
70
+ this.explicitAuth = normalizeAuth(input);
71
+ this.hasExplicitAuth = true;
72
+ }
73
+ resolve() {
74
+ const env = envDefaults();
75
+ return {
76
+ baseUrl: this.overrides.baseUrl ?? env.baseUrl,
77
+ auth: this.hasExplicitAuth ? this.explicitAuth : env.auth,
78
+ fetchFn: (this.overrides.fetchFn ?? env.fetchFn),
79
+ logger: this.overrides.logger,
80
+ };
81
+ }
82
+ }
83
+ exports.ConfigState = ConfigState;
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2Q0Esa0NBTUM7QUFlRCxzQ0FZQztBQTVFWSxRQUFBLGdCQUFnQixHQUFHLDZCQUE2QixDQUFDO0FBc0M5RDs7OztHQUlHO0FBQ0gsU0FBZ0IsV0FBVztJQUN6QixPQUFPO1FBQ0wsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLElBQUksd0JBQWdCO1FBQzFELElBQUksRUFBRSxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQXFCO0tBQzFDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxPQUFPO0lBQ2QsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQztJQUNuRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO0lBQ2xELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUM7SUFDOUMsSUFBSSxLQUFLO1FBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDNUMsSUFBSSxNQUFNLElBQUksU0FBUztRQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNwRSxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLEtBQXVDO0lBQ25FLElBQUksTUFBTSxJQUFJLEtBQUs7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNsQyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQixJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztRQUNsRixDQUFDO1FBQ0QsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzVFLENBQUM7SUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUM7QUFDaEYsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBYSxXQUFXO0lBQ2QsU0FBUyxHQUF3QixFQUFFLENBQUM7SUFDcEMsWUFBWSxDQUEyQjtJQUN2QyxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBRWhDLEtBQUssQ0FBQyxLQUEwQjtRQUM5QixJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssU0FBUztZQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDeEUsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQ3hFLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxTQUFTO1lBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNyRSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQXVDO1FBQzdDLElBQUksQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO0lBQzlCLENBQUM7SUFFRCxPQUFPO1FBQ0wsTUFBTSxHQUFHLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFDMUIsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sSUFBSSxHQUFHLENBQUMsT0FBTztZQUM5QyxJQUFJLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUk7WUFDekQsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBaUI7WUFDaEUsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBNEI7U0FDcEQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQTdCRCxrQ0E2QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IExvZ2dlciB9IGZyb20gJ0B1ZW5nYWdlLmlvL2pzLWxvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0JBU0VfVVJMID0gJ2h0dHBzOi8vcGxhdGZvcm0udWVuZ2FnZS5pbyc7XG5cbi8qKlxuICogUmVzb2x2ZWQgYXV0aCBzdGF0ZS4gRGlzY3JpbWluYXRlZCBieSBgdHlwZWAgc28gY29uc3VtZXJzIGNhbiBuYXJyb3cuXG4gKi9cbmV4cG9ydCB0eXBlIFBsYXRmb3JtQXV0aCA9XG4gIHwgeyB0eXBlOiAnaG1hYyc7IHNlY3JldDogc3RyaW5nOyBzZXJ2aWNlSWQ6IHN0cmluZyB9XG4gIHwgeyB0eXBlOiAnYmVhcmVyJzsgdG9rZW46IHN0cmluZyB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBsYXRmb3JtQ29uZmlnIHtcbiAgYmFzZVVybDogc3RyaW5nO1xuICBhdXRoPzogUGxhdGZvcm1BdXRoO1xuICBmZXRjaEZuOiB0eXBlb2YgZmV0Y2g7XG4gIGxvZ2dlcj86IExvZ2dlcjtcbn1cblxuLyoqXG4gKiBDYWxsZXItZmFjaW5nIGlucHV0IHNoYXBlLiBgYXV0aGAgYWNjZXB0cyBlaXRoZXIgYSBkaXNjcmltaW5hdGVkXG4gKiBQbGF0Zm9ybUF1dGggb3IgdGhlIGxvb3NlciBQbGF0Zm9ybUF1dGhJbnB1dCAtIHRoZSBsb29zZXIgZm9ybSBpc1xuICogYWxzbyB3aGF0IGAuYXV0aCgpYCBhY2NlcHRzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsYXRmb3JtQ29uZmlnSW5wdXQge1xuICBiYXNlVXJsPzogc3RyaW5nO1xuICBhdXRoPzogUGxhdGZvcm1BdXRoSW5wdXQgfCBQbGF0Zm9ybUF1dGg7XG4gIGZldGNoRm4/OiB0eXBlb2YgZmV0Y2g7XG4gIGxvZ2dlcj86IExvZ2dlcjtcbn1cblxuLyoqXG4gKiBgLmF1dGgoKWAgc2hhcGUuIFBhc3MgZWl0aGVyIGB7dG9rZW59YCAoQmVhcmVyKSBvciBge3NlY3JldCwgc2VydmljZUlkfWBcbiAqIChITUFDKS4gTWl4aW5nIGJvdGggdGhyb3dzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsYXRmb3JtQXV0aElucHV0IHtcbiAgdG9rZW4/OiBzdHJpbmc7XG4gIHNlY3JldD86IHN0cmluZztcbiAgc2VydmljZUlkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlc29sdmUgZW52LWRlZmF1bHRlZCBjb25maWcuIFJlLXJlYWQgb24gZXZlcnkgY2FsbCBzbyB0aGF0IGNhbGxlcnMgY2FuXG4gKiBzZXQgZW52IHZhcnMgYWZ0ZXIgdGhlIFNESyBoYXMgYmVlbiBpbXBvcnRlZCBhbmQgc3RpbGwgcGljayB0aGVtIHVwIG9uXG4gKiB0aGUgbmV4dCByZXF1ZXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW52RGVmYXVsdHMoKTogUGxhdGZvcm1Db25maWcge1xuICByZXR1cm4ge1xuICAgIGJhc2VVcmw6IHByb2Nlc3MuZW52LlBMQVRGT1JNX0JBU0VfVVJMID8/IERFRkFVTFRfQkFTRV9VUkwsXG4gICAgYXV0aDogZW52QXV0aCgpLFxuICAgIGZldGNoRm46IGdsb2JhbFRoaXMuZmV0Y2ggYXMgdHlwZW9mIGZldGNoLFxuICB9O1xufVxuXG5mdW5jdGlvbiBlbnZBdXRoKCk6IFBsYXRmb3JtQXV0aCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlY3JldCA9IHByb2Nlc3MuZW52LlBMQVRGT1JNX1NJR05JTkdfU0VDUkVUO1xuICBjb25zdCBzZXJ2aWNlSWQgPSBwcm9jZXNzLmVudi5QTEFURk9STV9TRVJWSUNFX0lEO1xuICBjb25zdCB0b2tlbiA9IHByb2Nlc3MuZW52LlBMQVRGT1JNX0FVVEhfVE9LRU47XG4gIGlmICh0b2tlbikgcmV0dXJuIHsgdHlwZTogJ2JlYXJlcicsIHRva2VuIH07XG4gIGlmIChzZWNyZXQgJiYgc2VydmljZUlkKSByZXR1cm4geyB0eXBlOiAnaG1hYycsIHNlY3JldCwgc2VydmljZUlkIH07XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQ29lcmNlIGAuYXV0aCgpYCBpbnB1dCBvciBgY29uZmlnKHthdXRofSlgIGlucHV0IGludG8gYSB0eXBlZCBQbGF0Zm9ybUF1dGguXG4gKiBUaHJvd3MgaWYgdGhlIGlucHV0IGhhcyBubyB1c2FibGUgY3JlZGVudGlhbHMgb3IgbWl4ZXMgSE1BQyArIEJlYXJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUF1dGgoaW5wdXQ6IFBsYXRmb3JtQXV0aElucHV0IHwgUGxhdGZvcm1BdXRoKTogUGxhdGZvcm1BdXRoIHtcbiAgaWYgKCd0eXBlJyBpbiBpbnB1dCkgcmV0dXJuIGlucHV0O1xuICBpZiAoaW5wdXQudG9rZW4pIHtcbiAgICBpZiAoaW5wdXQuc2VjcmV0IHx8IGlucHV0LnNlcnZpY2VJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhdXRoKCk6IHBhc3MgZWl0aGVyIHt0b2tlbn0gb3Ige3NlY3JldCwgc2VydmljZUlkfSwgbm90IGJvdGgnKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgdHlwZTogJ2JlYXJlcicsIHRva2VuOiBpbnB1dC50b2tlbiB9O1xuICB9XG4gIGlmIChpbnB1dC5zZWNyZXQgJiYgaW5wdXQuc2VydmljZUlkKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogJ2htYWMnLCBzZWNyZXQ6IGlucHV0LnNlY3JldCwgc2VydmljZUlkOiBpbnB1dC5zZXJ2aWNlSWQgfTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ2F1dGgoKTogbXVzdCBwcm92aWRlIGVpdGhlciB7dG9rZW59IG9yIHtzZWNyZXQsIHNlcnZpY2VJZH0nKTtcbn1cblxuLyoqXG4gKiBNdXRhYmxlIGNvbmZpZyBzaGFyZWQgYnkgY2xpZW50cy4gYGFwcGx5KClgIGFuZCBgc2V0QXV0aCgpYCBhcmUgaG93IHRoZVxuICogY2hhaW5hYmxlIGAuY29uZmlnKClgIC8gYC5hdXRoKClgIG1ldGhvZHMgd3JpdGUgYmFjay4gYHJlc29sdmUoKWAgcHJvZHVjZXNcbiAqIHRoZSBlZmZlY3RpdmUgY29uZmlnIGZvciBvbmUgcmVxdWVzdCwgZmFsbGluZyBiYWNrIHRvIGN1cnJlbnQgZW52IHN0YXRlXG4gKiBmb3IgZmllbGRzIHRoZSBjYWxsZXIgaGFzbid0IHBpbm5lZC5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbmZpZ1N0YXRlIHtcbiAgcHJpdmF0ZSBvdmVycmlkZXM6IFBsYXRmb3JtQ29uZmlnSW5wdXQgPSB7fTtcbiAgcHJpdmF0ZSBleHBsaWNpdEF1dGg6IFBsYXRmb3JtQXV0aCB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBoYXNFeHBsaWNpdEF1dGggPSBmYWxzZTtcblxuICBhcHBseShpbnB1dDogUGxhdGZvcm1Db25maWdJbnB1dCk6IHZvaWQge1xuICAgIGlmIChpbnB1dC5iYXNlVXJsICE9PSB1bmRlZmluZWQpIHRoaXMub3ZlcnJpZGVzLmJhc2VVcmwgPSBpbnB1dC5iYXNlVXJsO1xuICAgIGlmIChpbnB1dC5mZXRjaEZuICE9PSB1bmRlZmluZWQpIHRoaXMub3ZlcnJpZGVzLmZldGNoRm4gPSBpbnB1dC5mZXRjaEZuO1xuICAgIGlmIChpbnB1dC5sb2dnZXIgIT09IHVuZGVmaW5lZCkgdGhpcy5vdmVycmlkZXMubG9nZ2VyID0gaW5wdXQubG9nZ2VyO1xuICAgIGlmIChpbnB1dC5hdXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZXhwbGljaXRBdXRoID0gbm9ybWFsaXplQXV0aChpbnB1dC5hdXRoKTtcbiAgICAgIHRoaXMuaGFzRXhwbGljaXRBdXRoID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBzZXRBdXRoKGlucHV0OiBQbGF0Zm9ybUF1dGhJbnB1dCB8IFBsYXRmb3JtQXV0aCk6IHZvaWQge1xuICAgIHRoaXMuZXhwbGljaXRBdXRoID0gbm9ybWFsaXplQXV0aChpbnB1dCk7XG4gICAgdGhpcy5oYXNFeHBsaWNpdEF1dGggPSB0cnVlO1xuICB9XG5cbiAgcmVzb2x2ZSgpOiBQbGF0Zm9ybUNvbmZpZyB7XG4gICAgY29uc3QgZW52ID0gZW52RGVmYXVsdHMoKTtcbiAgICByZXR1cm4ge1xuICAgICAgYmFzZVVybDogdGhpcy5vdmVycmlkZXMuYmFzZVVybCA/PyBlbnYuYmFzZVVybCxcbiAgICAgIGF1dGg6IHRoaXMuaGFzRXhwbGljaXRBdXRoID8gdGhpcy5leHBsaWNpdEF1dGggOiBlbnYuYXV0aCxcbiAgICAgIGZldGNoRm46ICh0aGlzLm92ZXJyaWRlcy5mZXRjaEZuID8/IGVudi5mZXRjaEZuKSBhcyB0eXBlb2YgZmV0Y2gsXG4gICAgICBsb2dnZXI6IHRoaXMub3ZlcnJpZGVzLmxvZ2dlciBhcyBMb2dnZXIgfCB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxufVxuIl19
package/dist/http.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { PlatformConfig } from './config';
2
+ export interface SignedHeaderParams {
3
+ method: string;
4
+ /** URL pathname only, without query string. Must match `c.req.path` server-side. */
5
+ path: string;
6
+ /** Raw JSON body string, or empty for none. */
7
+ body?: string;
8
+ }
9
+ /**
10
+ * Build the headers required for a request to the platform API, given the
11
+ * effective auth on `config`. With no auth configured we still return any
12
+ * non-auth headers (e.g. content-type) - some endpoints accept anonymous
13
+ * callers and the server decides whether to allow.
14
+ */
15
+ export declare function buildHeaders(config: PlatformConfig, params: SignedHeaderParams): Record<string, string>;
package/dist/http.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildHeaders = buildHeaders;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const sign_1 = require("./audit/sign");
6
+ /**
7
+ * Build the headers required for a request to the platform API, given the
8
+ * effective auth on `config`. With no auth configured we still return any
9
+ * non-auth headers (e.g. content-type) - some endpoints accept anonymous
10
+ * callers and the server decides whether to allow.
11
+ */
12
+ function buildHeaders(config, params) {
13
+ const headers = {};
14
+ if (params.body !== undefined)
15
+ headers['content-type'] = 'application/json';
16
+ if (!config.auth)
17
+ return headers;
18
+ if (config.auth.type === 'bearer') {
19
+ headers['authorization'] = `Bearer ${config.auth.token}`;
20
+ return headers;
21
+ }
22
+ // HMAC
23
+ const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
24
+ const nonce = (0, node_crypto_1.randomUUID)();
25
+ const signature = (0, sign_1.signRequest)({
26
+ method: params.method,
27
+ path: params.path,
28
+ serviceId: config.auth.serviceId,
29
+ timestamp,
30
+ nonce,
31
+ body: params.body ?? '',
32
+ secret: config.auth.secret,
33
+ });
34
+ headers['x-service-id'] = config.auth.serviceId;
35
+ headers['x-timestamp'] = timestamp;
36
+ headers['x-nonce'] = nonce;
37
+ headers['x-signature'] = signature;
38
+ return headers;
39
+ }
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBa0JBLG9DQStCQztBQWpERCw2Q0FBeUM7QUFDekMsdUNBQTJDO0FBVzNDOzs7OztHQUtHO0FBQ0gsU0FBZ0IsWUFBWSxDQUMxQixNQUFzQixFQUN0QixNQUEwQjtJQUUxQixNQUFNLE9BQU8sR0FBMkIsRUFBRSxDQUFDO0lBQzNDLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTO1FBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLGtCQUFrQixDQUFDO0lBRTVFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtRQUFFLE9BQU8sT0FBTyxDQUFDO0lBRWpDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDbEMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxHQUFHLFVBQVUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN6RCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsT0FBTztJQUNQLE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNyRSxNQUFNLEtBQUssR0FBRyxJQUFBLHdCQUFVLEdBQUUsQ0FBQztJQUMzQixNQUFNLFNBQVMsR0FBRyxJQUFBLGtCQUFXLEVBQUM7UUFDNUIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1FBQ3JCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtRQUNqQixTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTO1FBQ2hDLFNBQVM7UUFDVCxLQUFLO1FBQ0wsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRTtRQUN2QixNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNO0tBQzNCLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUNoRCxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsU0FBUyxDQUFDO0lBQ25DLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDM0IsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUNuQyxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IHNpZ25SZXF1ZXN0IH0gZnJvbSAnLi9hdWRpdC9zaWduJztcbmltcG9ydCB0eXBlIHsgUGxhdGZvcm1Db25maWcgfSBmcm9tICcuL2NvbmZpZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2lnbmVkSGVhZGVyUGFyYW1zIHtcbiAgbWV0aG9kOiBzdHJpbmc7XG4gIC8qKiBVUkwgcGF0aG5hbWUgb25seSwgd2l0aG91dCBxdWVyeSBzdHJpbmcuIE11c3QgbWF0Y2ggYGMucmVxLnBhdGhgIHNlcnZlci1zaWRlLiAqL1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBSYXcgSlNPTiBib2R5IHN0cmluZywgb3IgZW1wdHkgZm9yIG5vbmUuICovXG4gIGJvZHk/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGhlYWRlcnMgcmVxdWlyZWQgZm9yIGEgcmVxdWVzdCB0byB0aGUgcGxhdGZvcm0gQVBJLCBnaXZlbiB0aGVcbiAqIGVmZmVjdGl2ZSBhdXRoIG9uIGBjb25maWdgLiBXaXRoIG5vIGF1dGggY29uZmlndXJlZCB3ZSBzdGlsbCByZXR1cm4gYW55XG4gKiBub24tYXV0aCBoZWFkZXJzIChlLmcuIGNvbnRlbnQtdHlwZSkgLSBzb21lIGVuZHBvaW50cyBhY2NlcHQgYW5vbnltb3VzXG4gKiBjYWxsZXJzIGFuZCB0aGUgc2VydmVyIGRlY2lkZXMgd2hldGhlciB0byBhbGxvdy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSGVhZGVycyhcbiAgY29uZmlnOiBQbGF0Zm9ybUNvbmZpZyxcbiAgcGFyYW1zOiBTaWduZWRIZWFkZXJQYXJhbXMsXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAocGFyYW1zLmJvZHkgIT09IHVuZGVmaW5lZCkgaGVhZGVyc1snY29udGVudC10eXBlJ10gPSAnYXBwbGljYXRpb24vanNvbic7XG5cbiAgaWYgKCFjb25maWcuYXV0aCkgcmV0dXJuIGhlYWRlcnM7XG5cbiAgaWYgKGNvbmZpZy5hdXRoLnR5cGUgPT09ICdiZWFyZXInKSB7XG4gICAgaGVhZGVyc1snYXV0aG9yaXphdGlvbiddID0gYEJlYXJlciAke2NvbmZpZy5hdXRoLnRva2VufWA7XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cblxuICAvLyBITUFDXG4gIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5yZXBsYWNlKC9cXC5cXGR7M31aJC8sICdaJyk7XG4gIGNvbnN0IG5vbmNlID0gcmFuZG9tVVVJRCgpO1xuICBjb25zdCBzaWduYXR1cmUgPSBzaWduUmVxdWVzdCh7XG4gICAgbWV0aG9kOiBwYXJhbXMubWV0aG9kLFxuICAgIHBhdGg6IHBhcmFtcy5wYXRoLFxuICAgIHNlcnZpY2VJZDogY29uZmlnLmF1dGguc2VydmljZUlkLFxuICAgIHRpbWVzdGFtcCxcbiAgICBub25jZSxcbiAgICBib2R5OiBwYXJhbXMuYm9keSA/PyAnJyxcbiAgICBzZWNyZXQ6IGNvbmZpZy5hdXRoLnNlY3JldCxcbiAgfSk7XG4gIGhlYWRlcnNbJ3gtc2VydmljZS1pZCddID0gY29uZmlnLmF1dGguc2VydmljZUlkO1xuICBoZWFkZXJzWyd4LXRpbWVzdGFtcCddID0gdGltZXN0YW1wO1xuICBoZWFkZXJzWyd4LW5vbmNlJ10gPSBub25jZTtcbiAgaGVhZGVyc1sneC1zaWduYXR1cmUnXSA9IHNpZ25hdHVyZTtcbiAgcmV0dXJuIGhlYWRlcnM7XG59XG4iXX0=
@@ -0,0 +1,17 @@
1
+ export * from './audit';
2
+ export * from './business';
3
+ export { type PlatformAuth, type PlatformAuthInput, type PlatformConfig, type PlatformConfigInput, DEFAULT_BASE_URL, } from './config';
4
+ /**
5
+ * Default singleton clients. Both read defaults from the environment on
6
+ * every call:
7
+ * - PLATFORM_BASE_URL (defaults to https://platform.uengage.io)
8
+ * - PLATFORM_SIGNING_SECRET HMAC secret hex
9
+ * - PLATFORM_SERVICE_ID HMAC service id
10
+ * - PLATFORM_AUTH_TOKEN Bearer token (overrides HMAC if set)
11
+ *
12
+ * Override per-instance with `.config({...})` and/or `.auth({...})`. For
13
+ * isolated configuration (tests, multi-tenant code paths), construct your
14
+ * own via `createAuditClient(...)` or `createBusinessClient(...)` instead.
15
+ */
16
+ export declare const audit: import("./audit").AuditClient;
17
+ export declare const business: import("./business").BusinessClient;
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.business = exports.audit = exports.DEFAULT_BASE_URL = void 0;
18
+ __exportStar(require("./audit"), exports);
19
+ __exportStar(require("./business"), exports);
20
+ var config_1 = require("./config");
21
+ Object.defineProperty(exports, "DEFAULT_BASE_URL", { enumerable: true, get: function () { return config_1.DEFAULT_BASE_URL; } });
22
+ const audit_1 = require("./audit");
23
+ const business_1 = require("./business");
24
+ /**
25
+ * Default singleton clients. Both read defaults from the environment on
26
+ * every call:
27
+ * - PLATFORM_BASE_URL (defaults to https://platform.uengage.io)
28
+ * - PLATFORM_SIGNING_SECRET HMAC secret hex
29
+ * - PLATFORM_SERVICE_ID HMAC service id
30
+ * - PLATFORM_AUTH_TOKEN Bearer token (overrides HMAC if set)
31
+ *
32
+ * Override per-instance with `.config({...})` and/or `.auth({...})`. For
33
+ * isolated configuration (tests, multi-tenant code paths), construct your
34
+ * own via `createAuditClient(...)` or `createBusinessClient(...)` instead.
35
+ */
36
+ exports.audit = (0, audit_1.createAuditClient)();
37
+ exports.business = (0, business_1.createBusinessClient)();
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQ0FBd0I7QUFDeEIsNkNBQTJCO0FBQzNCLG1DQU1rQjtBQURoQiwwR0FBQSxnQkFBZ0IsT0FBQTtBQUdsQixtQ0FBNEM7QUFDNUMseUNBQWtEO0FBRWxEOzs7Ozs7Ozs7OztHQVdHO0FBQ1UsUUFBQSxLQUFLLEdBQUcsSUFBQSx5QkFBaUIsR0FBRSxDQUFDO0FBQzVCLFFBQUEsUUFBUSxHQUFHLElBQUEsK0JBQW9CLEdBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXVkaXQnO1xuZXhwb3J0ICogZnJvbSAnLi9idXNpbmVzcyc7XG5leHBvcnQge1xuICB0eXBlIFBsYXRmb3JtQXV0aCxcbiAgdHlwZSBQbGF0Zm9ybUF1dGhJbnB1dCxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZyxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZ0lucHV0LFxuICBERUZBVUxUX0JBU0VfVVJMLFxufSBmcm9tICcuL2NvbmZpZyc7XG5cbmltcG9ydCB7IGNyZWF0ZUF1ZGl0Q2xpZW50IH0gZnJvbSAnLi9hdWRpdCc7XG5pbXBvcnQgeyBjcmVhdGVCdXNpbmVzc0NsaWVudCB9IGZyb20gJy4vYnVzaW5lc3MnO1xuXG4vKipcbiAqIERlZmF1bHQgc2luZ2xldG9uIGNsaWVudHMuIEJvdGggcmVhZCBkZWZhdWx0cyBmcm9tIHRoZSBlbnZpcm9ubWVudCBvblxuICogZXZlcnkgY2FsbDpcbiAqICAgLSBQTEFURk9STV9CQVNFX1VSTCAgICAgICAgICAoZGVmYXVsdHMgdG8gaHR0cHM6Ly9wbGF0Zm9ybS51ZW5nYWdlLmlvKVxuICogICAtIFBMQVRGT1JNX1NJR05JTkdfU0VDUkVUICAgIEhNQUMgc2VjcmV0IGhleFxuICogICAtIFBMQVRGT1JNX1NFUlZJQ0VfSUQgICAgICAgIEhNQUMgc2VydmljZSBpZFxuICogICAtIFBMQVRGT1JNX0FVVEhfVE9LRU4gICAgICAgIEJlYXJlciB0b2tlbiAob3ZlcnJpZGVzIEhNQUMgaWYgc2V0KVxuICpcbiAqIE92ZXJyaWRlIHBlci1pbnN0YW5jZSB3aXRoIGAuY29uZmlnKHsuLi59KWAgYW5kL29yIGAuYXV0aCh7Li4ufSlgLiBGb3JcbiAqIGlzb2xhdGVkIGNvbmZpZ3VyYXRpb24gKHRlc3RzLCBtdWx0aS10ZW5hbnQgY29kZSBwYXRocyksIGNvbnN0cnVjdCB5b3VyXG4gKiBvd24gdmlhIGBjcmVhdGVBdWRpdENsaWVudCguLi4pYCBvciBgY3JlYXRlQnVzaW5lc3NDbGllbnQoLi4uKWAgaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGF1ZGl0ID0gY3JlYXRlQXVkaXRDbGllbnQoKTtcbmV4cG9ydCBjb25zdCBidXNpbmVzcyA9IGNyZWF0ZUJ1c2luZXNzQ2xpZW50KCk7XG4iXX0=
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@uengage.io/platform-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Client SDK for the uEngage platform API (audit, business, ...). Namespaced singletons with HMAC or Bearer auth.",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist/",
9
+ "README.md"
10
+ ],
11
+ "engines": {
12
+ "node": ">=18.0.0"
13
+ },
14
+ "license": "MIT",
15
+ "keywords": [
16
+ "uengage",
17
+ "platform",
18
+ "sdk",
19
+ "audit",
20
+ "business",
21
+ "hmac"
22
+ ],
23
+ "dependencies": {
24
+ "ulid": "^2.3.0",
25
+ "zod": "^3.23.8",
26
+ "@uengage.io/js-logger": "0.9.3"
27
+ },
28
+ "devDependencies": {
29
+ "@types/jest": "^29.5.14",
30
+ "@types/node": "^20.14.10",
31
+ "jest": "^29.7.0",
32
+ "ts-jest": "^29.2.5",
33
+ "typescript": "^5.5.4"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "typecheck": "tsc --noEmit",
38
+ "test": "jest"
39
+ }
40
+ }