@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 +118 -0
- package/dist/audit/client.d.ts +29 -0
- package/dist/audit/client.js +169 -0
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.js +11 -0
- package/dist/audit/schema.d.ts +239 -0
- package/dist/audit/schema.js +33 -0
- package/dist/audit/sign.d.ts +24 -0
- package/dist/audit/sign.js +30 -0
- package/dist/business/client.d.ts +19 -0
- package/dist/business/client.js +74 -0
- package/dist/business/index.d.ts +2 -0
- package/dist/business/index.js +9 -0
- package/dist/business/schema.d.ts +31 -0
- package/dist/business/schema.js +9 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +84 -0
- package/dist/http.d.ts +15 -0
- package/dist/http.js +40 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +38 -0
- package/package.json +40 -0
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1ZGl0L2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFEQSw4Q0E4SkM7QUFuTkQsK0JBQTRCO0FBRTVCLHNDQUttQjtBQUNuQixrQ0FBdUM7QUFDdkMscUNBQTZEO0FBK0I3RCxNQUFNLElBQUksR0FBRyxrQkFBa0IsQ0FBQztBQUNoQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFMUMsTUFBTSxXQUFXLEdBQUc7SUFDbEIsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7SUFDZixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQztJQUNkLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO0lBQ2QsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7SUFDZixLQUFLO1FBQ0gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ21CLENBQUM7QUFFdkIsU0FBZ0IsaUJBQWlCLENBQUMsUUFBMEIsRUFBRTtJQUM1RCxNQUFNLEtBQUssR0FBRyxJQUFJLG9CQUFXLEVBQUUsQ0FBQztJQUNoQyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQztJQUN0RCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztJQUM5QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQztJQUNoRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQztJQUU5QyxNQUFNLEVBQ0osZUFBZSxFQUFFLEVBQUUsRUFDbkIsWUFBWSxFQUFFLEVBQUUsRUFDaEIsWUFBWSxFQUFFLEVBQUUsRUFDaEIsV0FBVyxFQUFFLEVBQUUsRUFDZixHQUFHLElBQUksRUFDUixHQUFHLEtBQUssQ0FBQztJQUNW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LEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVsaWQgfSBmcm9tICd1bGlkJztcbmltcG9ydCB0eXBlIHsgTG9nZ2VyIH0gZnJvbSAnQHVlbmdhZ2UuaW8vanMtbG9nZ2VyJztcbmltcG9ydCB7XG4gIENvbmZpZ1N0YXRlLFxuICB0eXBlIFBsYXRmb3JtQXV0aCxcbiAgdHlwZSBQbGF0Zm9ybUF1dGhJbnB1dCxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZ0lucHV0LFxufSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgYnVpbGRIZWFkZXJzIH0gZnJvbSAnLi4vaHR0cCc7XG5pbXBvcnQgeyBhdWRpdEV2ZW50U2NoZW1hLCB0eXBlIEF1ZGl0RXZlbnQgfSBmcm9tICcuL3NjaGVtYSc7XG5cbi8qKlxuICogQ2FsbGVyLWZhY2luZyBldmVudCBzaGFwZS4gVGhlIFNESyBmaWxsczpcbiAqICAgLSBgZXZlbnRfaWRgICAgKFVMSUQsIGdlbmVyYXRlZCBwZXIgY2FsbClcbiAqICAgLSBgb2NjdXJyZWRfYXRgIChVVEMgSVNPIDg2MDEgYXQgdGhlIHRpbWUgb2YgYHJlY29yZCgpYClcbiAqICAgLSBgYWN0b3IudmlhYCAgKGFsd2F5cyBzZXQgdG8gdGhlIGNvbmZpZ3VyZWQgc2VydmljZUlkLCBzbyBjYWxsZXJzXG4gKiAgICAgICAgICAgICAgICAgICBjYW4ndCBkcmlmdCBmcm9tIHRoZSBzZXJ2aWNlIGlkZW50aXR5IHVzZWQgZm9yIGF1dGgpXG4gKi9cbmV4cG9ydCB0eXBlIEF1ZGl0RXZlbnRJbnB1dCA9IE9taXQ8QXVkaXRFdmVudCwgJ2V2ZW50X2lkJyB8ICdvY2N1cnJlZF9hdCcgfCAnYWN0b3InPiAmIHtcbiAgYWN0b3I6IE9taXQ8QXVkaXRFdmVudFsnYWN0b3InXSwgJ3ZpYSc+O1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBBdWRpdENsaWVudElucHV0IGV4dGVuZHMgUGxhdGZvcm1Db25maWdJbnB1dCB7XG4gIC8qKiBEZWZhdWx0IDUwMDAuICovXG4gIGZsdXNoSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgNTAuICovXG4gIG1heEJhdGNoU2l6ZT86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgMTAwMC4gTmV3IGV2ZW50cyBwYXN0IHRoaXMgYXJlIGRyb3BwZWQgd2l0aCBhIHdhcm5pbmcuICovXG4gIG1heFF1ZXVlU2l6ZT86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgdHJ1ZS4gU2V0IGZhbHNlIHRvIGRpc2FibGUgdGhlIGF1dG8tZmx1c2ggdGltZXIgKHRlc3Qgb25seSkuICovXG4gIGVuYWJsZVRpbWVyPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdWRpdENsaWVudCB7XG4gIGNvbmZpZyhpbnB1dDogUGxhdGZvcm1Db25maWdJbnB1dCk6IEF1ZGl0Q2xpZW50O1xuICBhdXRoKGlucHV0OiBQbGF0Zm9ybUF1dGhJbnB1dCB8IFBsYXRmb3JtQXV0aCk6IEF1ZGl0Q2xpZW50O1xuICByZWNvcmQoZXZlbnQ6IEF1ZGl0RXZlbnRJbnB1dCk6IHZvaWQ7XG4gIGZsdXNoKCk6IFByb21pc2U8dm9pZD47XG59XG5cbmNvbnN0IFBBVEggPSAnL3YxL2F1ZGl0L2V2ZW50cyc7XG5jb25zdCBSRVRSWV9ERUxBWVNfTVMgPSBbNTAwLCAyMDAwLCA4MDAwXTtcblxuY29uc3QgTk9PUF9MT0dHRVIgPSB7XG4gIGVycm9yOiAoKSA9PiB7fSxcbiAgd2FybjogKCkgPT4ge30sXG4gIGluZm86ICgpID0+IHt9LFxuICBkZWJ1ZzogKCkgPT4ge30sXG4gIGNoaWxkKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxufSBhcyB1bmtub3duIGFzIExvZ2dlcjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGl0Q2xpZW50KGlucHV0OiBBdWRpdENsaWVudElucHV0ID0ge30pOiBBdWRpdENsaWVudCB7XG4gIGNvbnN0IHN0YXRlID0gbmV3IENvbmZpZ1N0YXRlKCk7XG4gIGNvbnN0IGZsdXNoSW50ZXJ2YWxNcyA9IGlucHV0LmZsdXNoSW50ZXJ2YWxNcyA/PyA1MDAwO1xuICBjb25zdCBtYXhCYXRjaFNpemUgPSBpbnB1dC5tYXhCYXRjaFNpemUgPz8gNTA7XG4gIGNvbnN0IG1heFF1ZXVlU2l6ZSA9IGlucHV0Lm1heFF1ZXVlU2l6ZSA/PyAxMDAwO1xuICBjb25zdCBlbmFibGVUaW1lciA9IGlucHV0LmVuYWJsZVRpbWVyID8/IHRydWU7XG5cbiAgY29uc3Qge1xuICAgIGZsdXNoSW50ZXJ2YWxNczogX2YsXG4gICAgbWF4QmF0Y2hTaXplOiBfYixcbiAgICBtYXhRdWV1ZVNpemU6IF9xLFxuICAgIGVuYWJsZVRpbWVyOiBfdCxcbiAgICAuLi5yZXN0XG4gIH0gPSBpbnB1dDtcbiAgdm9pZCBfZjtcbiAgdm9pZCBfYjtcbiAgdm9pZCBfcTtcbiAgdm9pZCBfdDtcbiAgc3RhdGUuYXBwbHkocmVzdCk7XG5cbiAgY29uc3QgcXVldWU6IEF1ZGl0RXZlbnRbXSA9IFtdO1xuICBjb25zdCBpbmZsaWdodDogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgZnVuY3Rpb24gZ2V0TG9nZ2VyKCk6IExvZ2dlciB7XG4gICAgcmV0dXJuIHN0YXRlLnJlc29sdmUoKS5sb2dnZXIgPz8gTk9PUF9MT0dHRVI7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTZXJ2aWNlSWQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb25maWcgPSBzdGF0ZS5yZXNvbHZlKCk7XG4gICAgaWYgKCFjb25maWcuYXV0aCB8fCBjb25maWcuYXV0aC50eXBlICE9PSAnaG1hYycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2F1ZGl0IGNsaWVudCByZXF1aXJlcyBITUFDIGF1dGggKHNldCBQTEFURk9STV9TSUdOSU5HX1NFQ1JFVCArIFBMQVRGT1JNX1NFUlZJQ0VfSUQsIG9yIGNhbGwgLmF1dGgoe3NlY3JldCwgc2VydmljZUlkfSkpJyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBjb25maWcuYXV0aC5zZXJ2aWNlSWQ7XG4gIH1cblxuICBjb25zdCBjbGllbnQ6IEF1ZGl0Q2xpZW50ID0ge1xuICAgIGNvbmZpZyhvcHRzKSB7XG4gICAgICBzdGF0ZS5hcHBseShvcHRzKTtcbiAgICAgIHJldHVybiBjbGllbnQ7XG4gICAgfSxcbiAgICBhdXRoKG9wdHMpIHtcbiAgICAgIHN0YXRlLnNldEF1dGgob3B0cyk7XG4gICAgICByZXR1cm4gY2xpZW50O1xuICAgIH0sXG4gICAgcmVjb3JkKGlucHV0KSB7XG4gICAgICBjb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoKTtcbiAgICAgIGxldCBzZXJ2aWNlSWQ6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIHNlcnZpY2VJZCA9IGdldFNlcnZpY2VJZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignYXVkaXRfc2RrLm5vX2F1dGgnLCB7XG4gICAgICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX05PX0FVVEgnLCBjYXRlZ29yeTogJ2VuZ2luZWVyaW5nJyB9LFxuICAgICAgICAgIGNvbnRleHQ6IHsgbWVzc2FnZTogKGVyciBhcyBFcnJvcikubWVzc2FnZSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjYW5kaWRhdGU6IEF1ZGl0RXZlbnQgPSB7XG4gICAgICAgIC4uLmlucHV0LFxuICAgICAgICBldmVudF9pZDogdWxpZCgpLFxuICAgICAgICBvY2N1cnJlZF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1xcLlxcZHszfVokLywgJ1onKSxcbiAgICAgICAgYWN0b3I6IHsgLi4uaW5wdXQuYWN0b3IsIHZpYTogc2VydmljZUlkIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXVkaXRFdmVudFNjaGVtYS5zYWZlUGFyc2UoY2FuZGlkYXRlKTtcbiAgICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdhdWRpdF9zZGsuaW52YWxpZF9ldmVudCcsIHtcbiAgICAgICAgICBlcnJvcjogeyBjb2RlOiAnQVVESVRfSU5WQUxJRF9FVkVOVCcsIGNhdGVnb3J5OiAnZW5naW5lZXJpbmcnIH0sXG4gICAgICAgICAgY29udGV4dDogeyBpc3N1ZXM6IHJlc3VsdC5lcnJvci5pc3N1ZXMsIGV2ZW50OiBjYW5kaWRhdGUgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChxdWV1ZS5sZW5ndGggPj0gbWF4UXVldWVTaXplKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdhdWRpdF9zZGsucXVldWVfZnVsbCcsIHtcbiAgICAgICAgICBjb250ZXh0OiB7IGRyb3BwZWRfZXZlbnRfaWQ6IGNhbmRpZGF0ZS5ldmVudF9pZCwgbWF4X3F1ZXVlX3NpemU6IG1heFF1ZXVlU2l6ZSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcXVldWUucHVzaChyZXN1bHQuZGF0YSk7XG4gICAgICBpZiAocXVldWUubGVuZ3RoID49IG1heEJhdGNoU2l6ZSkge1xuICAgICAgICB2b2lkIHNjaGVkdWxlU2VuZCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgZmx1c2goKSB7XG4gICAgICBhd2FpdCBzY2hlZHVsZVNlbmQoKTtcbiAgICAgIHdoaWxlIChpbmZsaWdodC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4uaW5mbGlnaHRdKTtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHNjaGVkdWxlU2VuZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYmF0Y2ggPSBxdWV1ZS5zcGxpY2UoMCwgbWF4QmF0Y2hTaXplKTtcbiAgICAgIGNvbnN0IHNlbmQgPSBzZW5kV2l0aFJldHJpZXMoYmF0Y2gpO1xuICAgICAgaW5mbGlnaHQucHVzaChzZW5kKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNlbmQ7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjb25zdCBpZHggPSBpbmZsaWdodC5pbmRleE9mKHNlbmQpO1xuICAgICAgICBpZiAoaWR4ICE9PSAtMSkgaW5mbGlnaHQuc3BsaWNlKGlkeCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gc2VuZFdpdGhSZXRyaWVzKGV2ZW50czogQXVkaXRFdmVudFtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKCk7XG4gICAgY29uc3QgYm9keSA9IEpTT04uc3RyaW5naWZ5KHsgZXZlbnRzIH0pO1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDw9IFJFVFJZX0RFTEFZU19NUy5sZW5ndGg7IGF0dGVtcHQrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgb2sgPSBhd2FpdCBzZW5kT25jZShib2R5KTtcbiAgICAgICAgaWYgKG9rKSByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc3QgZSA9IGVyciBhcyBFcnJvcjtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ2F1ZGl0X3Nkay5zZW5kX2Vycm9yJywge1xuICAgICAgICAgIGNvbnRleHQ6IHsgYXR0ZW1wdCwgbWVzc2FnZTogZS5tZXNzYWdlLCBiYXRjaF9zaXplOiBldmVudHMubGVuZ3RoIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGF0dGVtcHQgPCBSRVRSWV9ERUxBWVNfTVMubGVuZ3RoKSB7XG4gICAgICAgIGF3YWl0IHNsZWVwKFJFVFJZX0RFTEFZU19NU1thdHRlbXB0XSk7XG4gICAgICB9XG4gICAgfVxuICAgIGxvZ2dlci5lcnJvcignYXVkaXRfc2RrLnNlbmRfZmFpbGVkJywge1xuICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX1NFTkRfRkFJTEVEJywgY2F0ZWdvcnk6ICdlbmdpbmVlcmluZycgfSxcbiAgICAgIGNvbnRleHQ6IHsgYmF0Y2hfc2l6ZTogZXZlbnRzLmxlbmd0aCwgZXZlbnRzIH0sXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBzZW5kT25jZShib2R5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSBzdGF0ZS5yZXNvbHZlKCk7XG4gICAgY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKCk7XG4gICAgY29uc3QgaGVhZGVycyA9IGJ1aWxkSGVhZGVycyhjb25maWcsIHsgbWV0aG9kOiAnUE9TVCcsIHBhdGg6IFBBVEgsIGJvZHkgfSk7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgY29uZmlnLmZldGNoRm4oYCR7Y29uZmlnLmJhc2VVcmx9JHtQQVRIfWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGJvZHksXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgPj0gNTAwKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFyZXMub2sgJiYgcmVzLnN0YXR1cyAhPT0gMjAyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ2F1ZGl0X3Nkay5yZWplY3RlZCcsIHtcbiAgICAgICAgZXJyb3I6IHsgY29kZTogJ0FVRElUX1JFSkVDVEVEJywgY2F0ZWdvcnk6ICdlbmdpbmVlcmluZycgfSxcbiAgICAgICAgY29udGV4dDogeyBzdGF0dXM6IHJlcy5zdGF0dXMgfSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgbGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gIGlmIChlbmFibGVUaW1lcikge1xuICAgIHRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdm9pZCBzY2hlZHVsZVNlbmQoKTtcbiAgICB9LCBmbHVzaEludGVydmFsTXMpO1xuICAgIGlmICh0eXBlb2YgdGltZXIudW5yZWYgPT09ICdmdW5jdGlvbicpIHRpbWVyLnVucmVmKCk7XG4gIH1cblxuICByZXR1cm4gY2xpZW50O1xufVxuXG5mdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xufVxuIl19
|
|
@@ -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,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
|
package/dist/config.d.ts
ADDED
|
@@ -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=
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|