@uengage.io/platform-sdk 0.8.0 → 0.9.1

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 CHANGED
@@ -1,21 +1,31 @@
1
1
  # @uengage.io/platform-sdk
2
2
 
3
- Client SDK for uEngage platform services. Exposes namespaced singletons for each
4
- service domain, configured by environment variables out of the box.
3
+ Client SDK for uEngage platform services. One factory (`createClient`) returns a `PlatformClient` exposing `business`, `audit`, and `auth`. No singletons, no module-level state — each consumer constructs its own client with explicit config.
5
4
 
6
5
  CDK constructs live in a separate package: `@uengage/platform-constructs`.
7
6
 
8
7
  ## Quick start
9
8
 
10
9
  ```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.
10
+ import { createClient } from '@uengage.io/platform-sdk';
11
+
12
+ // No args: read everything from UENGAGE_* env vars (baseUrl, service
13
+ // credentials or auth token, etc.). Convenient for Lambdas where the
14
+ // deploy stack already injects the right env.
15
+ const client = createClient();
16
+
17
+ // Or override per call:
18
+ const explicit = createClient({
19
+ baseUrl: 'https://api.platform.uengage.io',
20
+ serviceId: 'my-service',
21
+ serviceSecret: process.env.MY_SERVICE_SECRET!,
22
+ scope: 'business.profile:read business.menu:read',
23
+ actorVia: 'my-service', // stamped into audit events
24
+ });
15
25
 
16
- const acme = await business.get(123, { groups: ['profile', 'gst'] });
26
+ const acme = await client.business.get(123, { groups: ['profile'] });
17
27
 
18
- audit.record({
28
+ client.audit.record({
19
29
  event_type: 'business.updated',
20
30
  tenant: { id: 'biz_123', parent_id: null },
21
31
  actor: { type: 'user', id: 'usr_42' },
@@ -24,44 +34,58 @@ audit.record({
24
34
  });
25
35
  ```
26
36
 
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://api.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
+ ### Auth modes
37
38
 
38
- Override at runtime per client:
39
+ `createClient` takes exactly one of three auth modes (or none, for fully-public calls). Passing more than one throws `ConfigError`.
39
40
 
40
41
  ```ts
41
- business
42
- .config({ baseUrl: 'https://staging.platform.uengage.io' })
43
- .auth({ secret: process.env.MY_SECRET!, serviceId: 'my-service' })
44
- .get(123);
42
+ // Service-to-service (OAuth2 client_credentials)
43
+ createClient({ serviceId: 'svc', serviceSecret: 'sup', scope: '...' });
44
+
45
+ // Static Bearer (caller already minted the token, e.g. a BFF that has
46
+ // the end user's access_token from cookie / session)
47
+ createClient({ authToken: req.headers.authorization!.slice(7) });
45
48
 
46
- // Or Bearer token:
47
- business.auth({ token: 'tok-...' }).get(123);
49
+ // Customer surface: legacy session_token → JWT (transparent rotation)
50
+ createClient({ sessionToken: req.cookies.uengage_session });
48
51
  ```
49
52
 
50
- For isolated configuration (tests, multi-tenant code paths), construct your own:
53
+ Each call returns a fresh, isolated client. Per-request scopes say a BFF binding to the calling user's token — just call `createClient` again at the start of the handler.
51
54
 
52
- ```ts
53
- import { createBusinessClient, createAuditClient } from '@uengage.io/platform-sdk';
55
+ ## Why no singleton?
54
56
 
55
- const customBusiness = createBusinessClient({
56
- baseUrl: 'https://staging.platform.uengage.io',
57
- auth: { secret: '...', serviceId: 'my-service' },
58
- });
59
- ```
57
+ Earlier versions of the SDK exported `platform`, `audit`, and `business` as module-level singletons that read configuration from `process.env`. That shape created problems in Node:
58
+
59
+ - **Module-load side effects.** Importing the SDK eagerly constructed clients even when the caller didn't use them.
60
+ - **Cross-invocation state in Lambda.** A singleton's token cache, JWKS cache, and fetch handle survived across invocations and could leak between tenants.
61
+ - **No multi-tenant story.** A single Node process couldn't act as multiple identities; only one set of `UENGAGE_*` env vars was readable.
62
+ - **First-access config locking.** `process.env` mutated after the first call was a no-op.
63
+ - **Tests needed a `_resetPlatformSingleton()` escape hatch.**
64
+
65
+ Forcing every consumer to call `createClient(...)` removes all of that. Each instance is isolated, configuration is explicit, and the only state is what the caller chose to keep.
66
+
67
+ ## Configuration
68
+
69
+ | Field | Env override | Default |
70
+ | --------------------- | -------------------------------- | --------------------------------- |
71
+ | `baseUrl` | `UENGAGE_BASE_URL` | `https://api.platform.uengage.io` |
72
+ | `authBaseUrl` | `UENGAGE_AUTH_BASE_URL` | `${baseUrl}/auth/business` |
73
+ | `customerAuthBaseUrl` | `UENGAGE_CUSTOMER_AUTH_BASE_URL` | `${baseUrl}/auth/customer` |
74
+ | `serviceId` | `UENGAGE_SERVICE_ID` | none |
75
+ | `serviceSecret` | `UENGAGE_SERVICE_SECRET` | none |
76
+ | `scope` | `UENGAGE_SCOPE` | none |
77
+ | `authToken` | `UENGAGE_AUTH_TOKEN` | none |
78
+ | `sessionToken` | `UENGAGE_SESSION_TOKEN` | none |
79
+ | `actorVia` | `UENGAGE_ACTOR_VIA` | falls back to `serviceId` |
80
+ | `expiryBufferMs` | `UENGAGE_EXPIRY_BUFFER_MS` | 30000 |
81
+ | `fetchFn` | (no env override) | `globalThis.fetch` |
82
+
83
+ `createClient()` reads env defaults; explicit fields passed to `createClient(input)` override the matching env value for that one call. Passing **any** auth-mode field explicitly (`authToken`, `sessionToken`, or the `serviceId`/`serviceSecret` pair) suppresses **every** env-derived auth default — so callers never get a silent merge of two different auth modes.
60
84
 
61
85
  ## Audit client
62
86
 
63
87
  ```ts
64
- audit.record({
88
+ client.audit.record({
65
89
  event_type: 'business.updated',
66
90
  tenant: { id: 'biz_123', parent_id: null },
67
91
  actor: { type: 'user', id: 'usr_42' },
@@ -69,31 +93,30 @@ audit.record({
69
93
  changes: { name: { before: 'Old', after: 'New' } },
70
94
  });
71
95
 
72
- await audit.flush(); // optional: drain on shutdown
96
+ await client.audit.flush(); // optional: drain on shutdown
73
97
  ```
74
98
 
75
99
  - `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.
100
+ `occurred_at`, fills `actor.via` with the configured `actorVia` (or
101
+ `serviceId`), validates the event, and enqueues it. It never throws.
102
+ - Events batch and flush every 5 s (configurable) or when the batch reaches 50.
81
103
  - Failed batches retry up to 3 times with exponential backoff
82
104
  (500 ms / 2 s / 8 s); on final failure the full batch is logged.
83
105
  - Queue overflow (default 1000) drops new events with a warning log.
84
106
  - `flush()` resolves when the queue is empty or retries are exhausted.
107
+ - If `actorVia` is unset, `record()` logs an error and drops the event.
85
108
 
86
109
  ## Business client
87
110
 
88
111
  ```ts
89
- const biz = await business.get(123);
112
+ const biz = await client.business.get(123);
90
113
  // { id: 123, parent_id: 42, profile: { name: 'Acme' } }
91
114
 
92
- const detailed = await business.get(123, {
115
+ const detailed = await client.business.get(123, {
93
116
  groups: ['profile', 'gst', 'payment_gateway'],
94
117
  });
95
118
 
96
- const many = await business.bulk([123, 124], { groups: ['profile'] });
119
+ const many = await client.business.bulk([123, 124], { groups: ['profile'] });
97
120
  ```
98
121
 
99
122
  - `get()` returns the record or throws `BusinessApiError` (with `.status` and `.body`).
@@ -101,6 +124,33 @@ const many = await business.bulk([123, 124], { groups: ['profile'] });
101
124
  - The `profile` group (just `name`) is public; other groups need
102
125
  matching `business.<group>:read` capability for the calling service id.
103
126
 
127
+ ## Auth helpers
128
+
129
+ ```ts
130
+ import { auth } from '@uengage.io/platform-sdk';
131
+ // or: client.auth.* — same namespace either way (stateless functions)
132
+
133
+ const pkce = auth.generatePKCE();
134
+ const url = auth.createAuthorizeUrl({
135
+ authBaseUrl: 'https://api.platform.uengage.io/auth/business',
136
+ clientId: 'my-app',
137
+ redirectUri: 'https://my-app.example/cb',
138
+ tenant: 'demo-tenant',
139
+ codeChallenge: pkce.code_challenge,
140
+ state: 'csrf-state',
141
+ });
142
+ // browser navigates to `url`; on callback, exchange the code:
143
+ const tokens = await auth.exchangeCode({
144
+ authBaseUrl: 'https://api.platform.uengage.io/auth/business',
145
+ code: 'returned-code',
146
+ codeVerifier: pkce.code_verifier,
147
+ clientId: 'my-app',
148
+ redirectUri: 'https://my-app.example/cb',
149
+ });
150
+ ```
151
+
152
+ `auth` exports stateless helpers; you can import the namespace directly or reach it via any client (`client.auth`). The same object is reused across clients because there's no state to isolate.
153
+
104
154
  ## Build / test
105
155
 
106
156
  ```bash
@@ -114,5 +164,5 @@ The package publishes on a `platform-sdk-vX.Y.Z` tag push. To cut a release:
114
164
 
115
165
  1. Bump `version` in `package.json`.
116
166
  2. Open a PR; merge.
117
- 3. Tag `platform-sdk-vX.Y.Z` on `main` and push - the publish workflow runs
167
+ 3. Tag `platform-sdk-vX.Y.Z` on `main` and push the publish workflow runs
118
168
  `pnpm publish --filter @uengage.io/platform-sdk --access public`.
@@ -10,16 +10,23 @@ export { exchangeCode, parseTokenResponse, type ExchangeCodeInput, type TokenPai
10
10
  export { refresh, type RefreshInput } from './refresh';
11
11
  export { verifyAccessToken } from './verify';
12
12
  export { getIssuer, getExpiry } from './issuer';
13
+ export { loginWithPassword, type LoginWithPasswordInput } from './login';
14
+ export { requestOtp, verifyOtp, type RequestOtpInput, type RequestOtpResult, type VerifyOtpInput, } from './otp';
13
15
  import { generatePKCE } from './pkce';
14
16
  import { createAuthorizeUrl } from './authorize-url';
15
17
  import { exchangeCode } from './exchange-code';
16
18
  import { refresh } from './refresh';
17
19
  import { verifyAccessToken } from './verify';
18
20
  import { getIssuer, getExpiry } from './issuer';
21
+ import { loginWithPassword } from './login';
22
+ import { requestOtp, verifyOtp } from './otp';
19
23
  /**
20
- * Default singleton namespace for callers using the package singleton.
21
- * import { auth } from '@uengage.io/platform-sdk';
22
- * const pkce = auth.generatePKCE();
24
+ * Convenience namespace: stateless helpers grouped under one symbol.
25
+ * Identical to the named exports above; importing the namespace lets
26
+ * callers write `client.auth.refresh(...)` (it's exposed on the
27
+ * `PlatformClient` instance returned by `createClient(...)`) or
28
+ * `auth.generatePKCE()` from a top-level import. No mutable state, so
29
+ * sharing this object across clients is safe.
23
30
  */
24
31
  export declare const auth: {
25
32
  generatePKCE: typeof generatePKCE;
@@ -29,4 +36,7 @@ export declare const auth: {
29
36
  verifyAccessToken: typeof verifyAccessToken;
30
37
  getIssuer: typeof getIssuer;
31
38
  getExpiry: typeof getExpiry;
39
+ loginWithPassword: typeof loginWithPassword;
40
+ requestOtp: typeof requestOtp;
41
+ verifyOtp: typeof verifyOtp;
32
42
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.auth = exports.getExpiry = exports.getIssuer = exports.verifyAccessToken = exports.refresh = exports.parseTokenResponse = exports.exchangeCode = exports.createAuthorizeUrl = exports.generatePKCE = void 0;
3
+ exports.auth = exports.verifyOtp = exports.requestOtp = exports.loginWithPassword = exports.getExpiry = exports.getIssuer = exports.verifyAccessToken = exports.refresh = exports.parseTokenResponse = exports.exchangeCode = exports.createAuthorizeUrl = exports.generatePKCE = void 0;
4
4
  /**
5
5
  * Auth namespace: helpers for OAuth2 flows against the platform's
6
6
  * `/auth/business/*` surface. Consumers don't bake a `client_id` into
@@ -21,16 +21,26 @@ Object.defineProperty(exports, "verifyAccessToken", { enumerable: true, get: fun
21
21
  var issuer_1 = require("./issuer");
22
22
  Object.defineProperty(exports, "getIssuer", { enumerable: true, get: function () { return issuer_1.getIssuer; } });
23
23
  Object.defineProperty(exports, "getExpiry", { enumerable: true, get: function () { return issuer_1.getExpiry; } });
24
+ var login_1 = require("./login");
25
+ Object.defineProperty(exports, "loginWithPassword", { enumerable: true, get: function () { return login_1.loginWithPassword; } });
26
+ var otp_1 = require("./otp");
27
+ Object.defineProperty(exports, "requestOtp", { enumerable: true, get: function () { return otp_1.requestOtp; } });
28
+ Object.defineProperty(exports, "verifyOtp", { enumerable: true, get: function () { return otp_1.verifyOtp; } });
24
29
  const pkce_2 = require("./pkce");
25
30
  const authorize_url_2 = require("./authorize-url");
26
31
  const exchange_code_2 = require("./exchange-code");
27
32
  const refresh_2 = require("./refresh");
28
33
  const verify_2 = require("./verify");
29
34
  const issuer_2 = require("./issuer");
35
+ const login_2 = require("./login");
36
+ const otp_2 = require("./otp");
30
37
  /**
31
- * Default singleton namespace for callers using the package singleton.
32
- * import { auth } from '@uengage.io/platform-sdk';
33
- * const pkce = auth.generatePKCE();
38
+ * Convenience namespace: stateless helpers grouped under one symbol.
39
+ * Identical to the named exports above; importing the namespace lets
40
+ * callers write `client.auth.refresh(...)` (it's exposed on the
41
+ * `PlatformClient` instance returned by `createClient(...)`) or
42
+ * `auth.generatePKCE()` from a top-level import. No mutable state, so
43
+ * sharing this object across clients is safe.
34
44
  */
35
45
  exports.auth = {
36
46
  generatePKCE: pkce_2.generatePKCE,
@@ -40,5 +50,8 @@ exports.auth = {
40
50
  verifyAccessToken: verify_2.verifyAccessToken,
41
51
  getIssuer: issuer_2.getIssuer,
42
52
  getExpiry: issuer_2.getExpiry,
53
+ loginWithPassword: login_2.loginWithPassword,
54
+ requestOtp: otp_2.requestOtp,
55
+ verifyOtp: otp_2.verifyOtp,
43
56
  };
44
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXV0aC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7R0FLRztBQUNILCtCQUFxRDtBQUE1QyxvR0FBQSxZQUFZLE9BQUE7QUFDckIsaURBQTZFO0FBQXBFLG1IQUFBLGtCQUFrQixPQUFBO0FBQzNCLGlEQUt5QjtBQUp2Qiw2R0FBQSxZQUFZLE9BQUE7QUFDWixtSEFBQSxrQkFBa0IsT0FBQTtBQUlwQixxQ0FBdUQ7QUFBOUMsa0dBQUEsT0FBTyxPQUFBO0FBQ2hCLG1DQUE2QztBQUFwQywyR0FBQSxpQkFBaUIsT0FBQTtBQUMxQixtQ0FBZ0Q7QUFBdkMsbUdBQUEsU0FBUyxPQUFBO0FBQUUsbUdBQUEsU0FBUyxPQUFBO0FBRTdCLGlDQUFzQztBQUN0QyxtREFBcUQ7QUFDckQsbURBQStDO0FBQy9DLHVDQUFvQztBQUNwQyxxQ0FBNkM7QUFDN0MscUNBQWdEO0FBRWhEOzs7O0dBSUc7QUFDVSxRQUFBLElBQUksR0FBRztJQUNsQixZQUFZLEVBQVosbUJBQVk7SUFDWixrQkFBa0IsRUFBbEIsa0NBQWtCO0lBQ2xCLFlBQVksRUFBWiw0QkFBWTtJQUNaLE9BQU8sRUFBUCxpQkFBTztJQUNQLGlCQUFpQixFQUFqQiwwQkFBaUI7SUFDakIsU0FBUyxFQUFULGtCQUFTO0lBQ1QsU0FBUyxFQUFULGtCQUFTO0NBQ1YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXV0aCBuYW1lc3BhY2U6IGhlbHBlcnMgZm9yIE9BdXRoMiBmbG93cyBhZ2FpbnN0IHRoZSBwbGF0Zm9ybSdzXG4gKiBgL2F1dGgvYnVzaW5lc3MvKmAgc3VyZmFjZS4gQ29uc3VtZXJzIGRvbid0IGJha2UgYSBgY2xpZW50X2lkYCBpbnRvXG4gKiB0aGUgU0RLIGl0c2VsZiDigJQgZXZlcnkgaGVscGVyIHRha2VzIHBhcmFtZXRlcnMgZXhwbGljaXRseSBzbyBtdWx0aXBsZVxuICogT0F1dGggY2xpZW50cyAoZGFzaGJvYXJkLCBtb2JpbGUsIEJGRnMpIGNhbiBzaGFyZSBvbmUgU0RLIGluc3RhbGwuXG4gKi9cbmV4cG9ydCB7IGdlbmVyYXRlUEtDRSwgdHlwZSBQa2NlUGFpciB9IGZyb20gJy4vcGtjZSc7XG5leHBvcnQgeyBjcmVhdGVBdXRob3JpemVVcmwsIHR5cGUgQXV0aG9yaXplVXJsSW5wdXQgfSBmcm9tICcuL2F1dGhvcml6ZS11cmwnO1xuZXhwb3J0IHtcbiAgZXhjaGFuZ2VDb2RlLFxuICBwYXJzZVRva2VuUmVzcG9uc2UsXG4gIHR5cGUgRXhjaGFuZ2VDb2RlSW5wdXQsXG4gIHR5cGUgVG9rZW5QYWlyLFxufSBmcm9tICcuL2V4Y2hhbmdlLWNvZGUnO1xuZXhwb3J0IHsgcmVmcmVzaCwgdHlwZSBSZWZyZXNoSW5wdXQgfSBmcm9tICcuL3JlZnJlc2gnO1xuZXhwb3J0IHsgdmVyaWZ5QWNjZXNzVG9rZW4gfSBmcm9tICcuL3ZlcmlmeSc7XG5leHBvcnQgeyBnZXRJc3N1ZXIsIGdldEV4cGlyeSB9IGZyb20gJy4vaXNzdWVyJztcblxuaW1wb3J0IHsgZ2VuZXJhdGVQS0NFIH0gZnJvbSAnLi9wa2NlJztcbmltcG9ydCB7IGNyZWF0ZUF1dGhvcml6ZVVybCB9IGZyb20gJy4vYXV0aG9yaXplLXVybCc7XG5pbXBvcnQgeyBleGNoYW5nZUNvZGUgfSBmcm9tICcuL2V4Y2hhbmdlLWNvZGUnO1xuaW1wb3J0IHsgcmVmcmVzaCB9IGZyb20gJy4vcmVmcmVzaCc7XG5pbXBvcnQgeyB2ZXJpZnlBY2Nlc3NUb2tlbiB9IGZyb20gJy4vdmVyaWZ5JztcbmltcG9ydCB7IGdldElzc3VlciwgZ2V0RXhwaXJ5IH0gZnJvbSAnLi9pc3N1ZXInO1xuXG4vKipcbiAqIERlZmF1bHQgc2luZ2xldG9uIG5hbWVzcGFjZSBmb3IgY2FsbGVycyB1c2luZyB0aGUgcGFja2FnZSBzaW5nbGV0b24uXG4gKiAgIGltcG9ydCB7IGF1dGggfSBmcm9tICdAdWVuZ2FnZS5pby9wbGF0Zm9ybS1zZGsnO1xuICogICBjb25zdCBwa2NlID0gYXV0aC5nZW5lcmF0ZVBLQ0UoKTtcbiAqL1xuZXhwb3J0IGNvbnN0IGF1dGggPSB7XG4gIGdlbmVyYXRlUEtDRSxcbiAgY3JlYXRlQXV0aG9yaXplVXJsLFxuICBleGNoYW5nZUNvZGUsXG4gIHJlZnJlc2gsXG4gIHZlcmlmeUFjY2Vzc1Rva2VuLFxuICBnZXRJc3N1ZXIsXG4gIGdldEV4cGlyeSxcbn07XG4iXX0=
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXV0aC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7R0FLRztBQUNILCtCQUFxRDtBQUE1QyxvR0FBQSxZQUFZLE9BQUE7QUFDckIsaURBQTZFO0FBQXBFLG1IQUFBLGtCQUFrQixPQUFBO0FBQzNCLGlEQUt5QjtBQUp2Qiw2R0FBQSxZQUFZLE9BQUE7QUFDWixtSEFBQSxrQkFBa0IsT0FBQTtBQUlwQixxQ0FBdUQ7QUFBOUMsa0dBQUEsT0FBTyxPQUFBO0FBQ2hCLG1DQUE2QztBQUFwQywyR0FBQSxpQkFBaUIsT0FBQTtBQUMxQixtQ0FBZ0Q7QUFBdkMsbUdBQUEsU0FBUyxPQUFBO0FBQUUsbUdBQUEsU0FBUyxPQUFBO0FBQzdCLGlDQUF5RTtBQUFoRSwwR0FBQSxpQkFBaUIsT0FBQTtBQUMxQiw2QkFNZTtBQUxiLGlHQUFBLFVBQVUsT0FBQTtBQUNWLGdHQUFBLFNBQVMsT0FBQTtBQU1YLGlDQUFzQztBQUN0QyxtREFBcUQ7QUFDckQsbURBQStDO0FBQy9DLHVDQUFvQztBQUNwQyxxQ0FBNkM7QUFDN0MscUNBQWdEO0FBQ2hELG1DQUE0QztBQUM1QywrQkFBOEM7QUFFOUM7Ozs7Ozs7R0FPRztBQUNVLFFBQUEsSUFBSSxHQUFHO0lBQ2xCLFlBQVksRUFBWixtQkFBWTtJQUNaLGtCQUFrQixFQUFsQixrQ0FBa0I7SUFDbEIsWUFBWSxFQUFaLDRCQUFZO0lBQ1osT0FBTyxFQUFQLGlCQUFPO0lBQ1AsaUJBQWlCLEVBQWpCLDBCQUFpQjtJQUNqQixTQUFTLEVBQVQsa0JBQVM7SUFDVCxTQUFTLEVBQVQsa0JBQVM7SUFDVCxpQkFBaUIsRUFBakIseUJBQWlCO0lBQ2pCLFVBQVUsRUFBVixnQkFBVTtJQUNWLFNBQVMsRUFBVCxlQUFTO0NBQ1YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXV0aCBuYW1lc3BhY2U6IGhlbHBlcnMgZm9yIE9BdXRoMiBmbG93cyBhZ2FpbnN0IHRoZSBwbGF0Zm9ybSdzXG4gKiBgL2F1dGgvYnVzaW5lc3MvKmAgc3VyZmFjZS4gQ29uc3VtZXJzIGRvbid0IGJha2UgYSBgY2xpZW50X2lkYCBpbnRvXG4gKiB0aGUgU0RLIGl0c2VsZiDigJQgZXZlcnkgaGVscGVyIHRha2VzIHBhcmFtZXRlcnMgZXhwbGljaXRseSBzbyBtdWx0aXBsZVxuICogT0F1dGggY2xpZW50cyAoZGFzaGJvYXJkLCBtb2JpbGUsIEJGRnMpIGNhbiBzaGFyZSBvbmUgU0RLIGluc3RhbGwuXG4gKi9cbmV4cG9ydCB7IGdlbmVyYXRlUEtDRSwgdHlwZSBQa2NlUGFpciB9IGZyb20gJy4vcGtjZSc7XG5leHBvcnQgeyBjcmVhdGVBdXRob3JpemVVcmwsIHR5cGUgQXV0aG9yaXplVXJsSW5wdXQgfSBmcm9tICcuL2F1dGhvcml6ZS11cmwnO1xuZXhwb3J0IHtcbiAgZXhjaGFuZ2VDb2RlLFxuICBwYXJzZVRva2VuUmVzcG9uc2UsXG4gIHR5cGUgRXhjaGFuZ2VDb2RlSW5wdXQsXG4gIHR5cGUgVG9rZW5QYWlyLFxufSBmcm9tICcuL2V4Y2hhbmdlLWNvZGUnO1xuZXhwb3J0IHsgcmVmcmVzaCwgdHlwZSBSZWZyZXNoSW5wdXQgfSBmcm9tICcuL3JlZnJlc2gnO1xuZXhwb3J0IHsgdmVyaWZ5QWNjZXNzVG9rZW4gfSBmcm9tICcuL3ZlcmlmeSc7XG5leHBvcnQgeyBnZXRJc3N1ZXIsIGdldEV4cGlyeSB9IGZyb20gJy4vaXNzdWVyJztcbmV4cG9ydCB7IGxvZ2luV2l0aFBhc3N3b3JkLCB0eXBlIExvZ2luV2l0aFBhc3N3b3JkSW5wdXQgfSBmcm9tICcuL2xvZ2luJztcbmV4cG9ydCB7XG4gIHJlcXVlc3RPdHAsXG4gIHZlcmlmeU90cCxcbiAgdHlwZSBSZXF1ZXN0T3RwSW5wdXQsXG4gIHR5cGUgUmVxdWVzdE90cFJlc3VsdCxcbiAgdHlwZSBWZXJpZnlPdHBJbnB1dCxcbn0gZnJvbSAnLi9vdHAnO1xuXG5pbXBvcnQgeyBnZW5lcmF0ZVBLQ0UgfSBmcm9tICcuL3BrY2UnO1xuaW1wb3J0IHsgY3JlYXRlQXV0aG9yaXplVXJsIH0gZnJvbSAnLi9hdXRob3JpemUtdXJsJztcbmltcG9ydCB7IGV4Y2hhbmdlQ29kZSB9IGZyb20gJy4vZXhjaGFuZ2UtY29kZSc7XG5pbXBvcnQgeyByZWZyZXNoIH0gZnJvbSAnLi9yZWZyZXNoJztcbmltcG9ydCB7IHZlcmlmeUFjY2Vzc1Rva2VuIH0gZnJvbSAnLi92ZXJpZnknO1xuaW1wb3J0IHsgZ2V0SXNzdWVyLCBnZXRFeHBpcnkgfSBmcm9tICcuL2lzc3Vlcic7XG5pbXBvcnQgeyBsb2dpbldpdGhQYXNzd29yZCB9IGZyb20gJy4vbG9naW4nO1xuaW1wb3J0IHsgcmVxdWVzdE90cCwgdmVyaWZ5T3RwIH0gZnJvbSAnLi9vdHAnO1xuXG4vKipcbiAqIENvbnZlbmllbmNlIG5hbWVzcGFjZTogc3RhdGVsZXNzIGhlbHBlcnMgZ3JvdXBlZCB1bmRlciBvbmUgc3ltYm9sLlxuICogSWRlbnRpY2FsIHRvIHRoZSBuYW1lZCBleHBvcnRzIGFib3ZlOyBpbXBvcnRpbmcgdGhlIG5hbWVzcGFjZSBsZXRzXG4gKiBjYWxsZXJzIHdyaXRlIGBjbGllbnQuYXV0aC5yZWZyZXNoKC4uLilgIChpdCdzIGV4cG9zZWQgb24gdGhlXG4gKiBgUGxhdGZvcm1DbGllbnRgIGluc3RhbmNlIHJldHVybmVkIGJ5IGBjcmVhdGVDbGllbnQoLi4uKWApIG9yXG4gKiBgYXV0aC5nZW5lcmF0ZVBLQ0UoKWAgZnJvbSBhIHRvcC1sZXZlbCBpbXBvcnQuIE5vIG11dGFibGUgc3RhdGUsIHNvXG4gKiBzaGFyaW5nIHRoaXMgb2JqZWN0IGFjcm9zcyBjbGllbnRzIGlzIHNhZmUuXG4gKi9cbmV4cG9ydCBjb25zdCBhdXRoID0ge1xuICBnZW5lcmF0ZVBLQ0UsXG4gIGNyZWF0ZUF1dGhvcml6ZVVybCxcbiAgZXhjaGFuZ2VDb2RlLFxuICByZWZyZXNoLFxuICB2ZXJpZnlBY2Nlc3NUb2tlbixcbiAgZ2V0SXNzdWVyLFxuICBnZXRFeHBpcnksXG4gIGxvZ2luV2l0aFBhc3N3b3JkLFxuICByZXF1ZXN0T3RwLFxuICB2ZXJpZnlPdHAsXG59O1xuIl19
@@ -0,0 +1,30 @@
1
+ import { type TokenPair } from './exchange-code';
2
+ export interface LoginWithPasswordInput {
3
+ /** Defaults to `https://api.platform.uengage.io/auth/business`. */
4
+ authBaseUrl?: string;
5
+ email: string;
6
+ password: string;
7
+ /** OAuth client_id. Must be a `firstParty: true` registry entry. */
8
+ clientId: string;
9
+ /**
10
+ * Optional client_secret. Public clients (SPA / mobile) can omit it;
11
+ * the `firstParty` flag in the auth registry is the gate. Backend
12
+ * services that hold a secret should pass it for defense-in-depth.
13
+ */
14
+ clientSecret?: string;
15
+ /** Space-separated scope list; intersected with the client's allowed scopes. */
16
+ scope?: string;
17
+ fetchFn?: typeof fetch;
18
+ }
19
+ /**
20
+ * Direct email + password login (OAuth2 Resource Owner Password
21
+ * Credentials grant). Returns the standard `TokenPair`; pass
22
+ * `tokens.accessToken` to `createClient({ authToken })` to get a
23
+ * client bound to the user, or hand the refresh token to the caller's
24
+ * own session-store and use `auth.refresh(...)` later.
25
+ *
26
+ * Restricted server-side to first-party clients — partner integrations
27
+ * must use `authorization_code` + PKCE and route the user through the
28
+ * platform's own login UI.
29
+ */
30
+ export declare function loginWithPassword(input: LoginWithPasswordInput): Promise<TokenPair>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loginWithPassword = loginWithPassword;
4
+ const exchange_code_1 = require("./exchange-code");
5
+ const DEFAULT_AUTH_BASE_URL = 'https://api.platform.uengage.io/auth/business';
6
+ /**
7
+ * Direct email + password login (OAuth2 Resource Owner Password
8
+ * Credentials grant). Returns the standard `TokenPair`; pass
9
+ * `tokens.accessToken` to `createClient({ authToken })` to get a
10
+ * client bound to the user, or hand the refresh token to the caller's
11
+ * own session-store and use `auth.refresh(...)` later.
12
+ *
13
+ * Restricted server-side to first-party clients — partner integrations
14
+ * must use `authorization_code` + PKCE and route the user through the
15
+ * platform's own login UI.
16
+ */
17
+ async function loginWithPassword(input) {
18
+ const body = new URLSearchParams({
19
+ grant_type: 'password',
20
+ username: input.email,
21
+ password: input.password,
22
+ client_id: input.clientId,
23
+ });
24
+ if (input.clientSecret)
25
+ body.set('client_secret', input.clientSecret);
26
+ if (input.scope)
27
+ body.set('scope', input.scope);
28
+ const fetchFn = input.fetchFn ?? globalThis.fetch;
29
+ const res = await fetchFn(`${input.authBaseUrl ?? DEFAULT_AUTH_BASE_URL}/oauth/token`, {
30
+ method: 'POST',
31
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
32
+ body: body.toString(),
33
+ });
34
+ return (0, exchange_code_1.parseTokenResponse)(res);
35
+ }
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXV0aC9sb2dpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWlDQSw4Q0FpQkM7QUFsREQsbURBQXFFO0FBb0JyRSxNQUFNLHFCQUFxQixHQUFHLCtDQUErQyxDQUFDO0FBRTlFOzs7Ozs7Ozs7O0dBVUc7QUFDSSxLQUFLLFVBQVUsaUJBQWlCLENBQUMsS0FBNkI7SUFDbkUsTUFBTSxJQUFJLEdBQUcsSUFBSSxlQUFlLENBQUM7UUFDL0IsVUFBVSxFQUFFLFVBQVU7UUFDdEIsUUFBUSxFQUFFLEtBQUssQ0FBQyxLQUFLO1FBQ3JCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtRQUN4QixTQUFTLEVBQUUsS0FBSyxDQUFDLFFBQVE7S0FDMUIsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxLQUFLLENBQUMsWUFBWTtRQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN0RSxJQUFJLEtBQUssQ0FBQyxLQUFLO1FBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRWhELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUssVUFBVSxDQUFDLEtBQXNCLENBQUM7SUFDcEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLHFCQUFxQixjQUFjLEVBQUU7UUFDckYsTUFBTSxFQUFFLE1BQU07UUFDZCxPQUFPLEVBQUUsRUFBRSxjQUFjLEVBQUUsbUNBQW1DLEVBQUU7UUFDaEUsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7S0FDdEIsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxJQUFBLGtDQUFrQixFQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwYXJzZVRva2VuUmVzcG9uc2UsIHR5cGUgVG9rZW5QYWlyIH0gZnJvbSAnLi9leGNoYW5nZS1jb2RlJztcblxuZXhwb3J0IGludGVyZmFjZSBMb2dpbldpdGhQYXNzd29yZElucHV0IHtcbiAgLyoqIERlZmF1bHRzIHRvIGBodHRwczovL2FwaS5wbGF0Zm9ybS51ZW5nYWdlLmlvL2F1dGgvYnVzaW5lc3NgLiAqL1xuICBhdXRoQmFzZVVybD86IHN0cmluZztcbiAgZW1haWw6IHN0cmluZztcbiAgcGFzc3dvcmQ6IHN0cmluZztcbiAgLyoqIE9BdXRoIGNsaWVudF9pZC4gTXVzdCBiZSBhIGBmaXJzdFBhcnR5OiB0cnVlYCByZWdpc3RyeSBlbnRyeS4gKi9cbiAgY2xpZW50SWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNsaWVudF9zZWNyZXQuIFB1YmxpYyBjbGllbnRzIChTUEEgLyBtb2JpbGUpIGNhbiBvbWl0IGl0O1xuICAgKiB0aGUgYGZpcnN0UGFydHlgIGZsYWcgaW4gdGhlIGF1dGggcmVnaXN0cnkgaXMgdGhlIGdhdGUuIEJhY2tlbmRcbiAgICogc2VydmljZXMgdGhhdCBob2xkIGEgc2VjcmV0IHNob3VsZCBwYXNzIGl0IGZvciBkZWZlbnNlLWluLWRlcHRoLlxuICAgKi9cbiAgY2xpZW50U2VjcmV0Pzogc3RyaW5nO1xuICAvKiogU3BhY2Utc2VwYXJhdGVkIHNjb3BlIGxpc3Q7IGludGVyc2VjdGVkIHdpdGggdGhlIGNsaWVudCdzIGFsbG93ZWQgc2NvcGVzLiAqL1xuICBzY29wZT86IHN0cmluZztcbiAgZmV0Y2hGbj86IHR5cGVvZiBmZXRjaDtcbn1cblxuY29uc3QgREVGQVVMVF9BVVRIX0JBU0VfVVJMID0gJ2h0dHBzOi8vYXBpLnBsYXRmb3JtLnVlbmdhZ2UuaW8vYXV0aC9idXNpbmVzcyc7XG5cbi8qKlxuICogRGlyZWN0IGVtYWlsICsgcGFzc3dvcmQgbG9naW4gKE9BdXRoMiBSZXNvdXJjZSBPd25lciBQYXNzd29yZFxuICogQ3JlZGVudGlhbHMgZ3JhbnQpLiBSZXR1cm5zIHRoZSBzdGFuZGFyZCBgVG9rZW5QYWlyYDsgcGFzc1xuICogYHRva2Vucy5hY2Nlc3NUb2tlbmAgdG8gYGNyZWF0ZUNsaWVudCh7IGF1dGhUb2tlbiB9KWAgdG8gZ2V0IGFcbiAqIGNsaWVudCBib3VuZCB0byB0aGUgdXNlciwgb3IgaGFuZCB0aGUgcmVmcmVzaCB0b2tlbiB0byB0aGUgY2FsbGVyJ3NcbiAqIG93biBzZXNzaW9uLXN0b3JlIGFuZCB1c2UgYGF1dGgucmVmcmVzaCguLi4pYCBsYXRlci5cbiAqXG4gKiBSZXN0cmljdGVkIHNlcnZlci1zaWRlIHRvIGZpcnN0LXBhcnR5IGNsaWVudHMg4oCUIHBhcnRuZXIgaW50ZWdyYXRpb25zXG4gKiBtdXN0IHVzZSBgYXV0aG9yaXphdGlvbl9jb2RlYCArIFBLQ0UgYW5kIHJvdXRlIHRoZSB1c2VyIHRocm91Z2ggdGhlXG4gKiBwbGF0Zm9ybSdzIG93biBsb2dpbiBVSS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvZ2luV2l0aFBhc3N3b3JkKGlucHV0OiBMb2dpbldpdGhQYXNzd29yZElucHV0KTogUHJvbWlzZTxUb2tlblBhaXI+IHtcbiAgY29uc3QgYm9keSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgIGdyYW50X3R5cGU6ICdwYXNzd29yZCcsXG4gICAgdXNlcm5hbWU6IGlucHV0LmVtYWlsLFxuICAgIHBhc3N3b3JkOiBpbnB1dC5wYXNzd29yZCxcbiAgICBjbGllbnRfaWQ6IGlucHV0LmNsaWVudElkLFxuICB9KTtcbiAgaWYgKGlucHV0LmNsaWVudFNlY3JldCkgYm9keS5zZXQoJ2NsaWVudF9zZWNyZXQnLCBpbnB1dC5jbGllbnRTZWNyZXQpO1xuICBpZiAoaW5wdXQuc2NvcGUpIGJvZHkuc2V0KCdzY29wZScsIGlucHV0LnNjb3BlKTtcblxuICBjb25zdCBmZXRjaEZuID0gaW5wdXQuZmV0Y2hGbiA/PyAoZ2xvYmFsVGhpcy5mZXRjaCBhcyB0eXBlb2YgZmV0Y2gpO1xuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaEZuKGAke2lucHV0LmF1dGhCYXNlVXJsID8/IERFRkFVTFRfQVVUSF9CQVNFX1VSTH0vb2F1dGgvdG9rZW5gLCB7XG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczogeyAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICBib2R5OiBib2R5LnRvU3RyaW5nKCksXG4gIH0pO1xuICByZXR1cm4gcGFyc2VUb2tlblJlc3BvbnNlKHJlcyk7XG59XG4iXX0=
@@ -0,0 +1,43 @@
1
+ import { type TokenPair } from './exchange-code';
2
+ export interface RequestOtpInput {
3
+ /** Defaults to `https://api.platform.uengage.io/auth/customer`. */
4
+ customerAuthBaseUrl?: string;
5
+ phone: string;
6
+ /** uEngage business id; the OTP is bound to this (phone, businessId) pair. */
7
+ businessId: number;
8
+ fetchFn?: typeof fetch;
9
+ }
10
+ export interface RequestOtpResult {
11
+ requestId: string;
12
+ /** Seconds until the OTP expires server-side. Typically 300 (5 min). */
13
+ expiresIn: number;
14
+ }
15
+ /**
16
+ * Step 1 of the customer OTP login. Asks the auth surface to mint an
17
+ * OTP, persist it bound to (phone, businessId), and emit it for SMS
18
+ * delivery via the SMS-team subscriber. The plaintext OTP never
19
+ * appears in the response — the SMS team is the side channel.
20
+ *
21
+ * Throws on rate-limit (429), unknown phone-business pair (400), and
22
+ * other non-200 responses.
23
+ */
24
+ export declare function requestOtp(input: RequestOtpInput): Promise<RequestOtpResult>;
25
+ export interface VerifyOtpInput {
26
+ /** Defaults to `https://api.platform.uengage.io/auth/customer`. */
27
+ customerAuthBaseUrl?: string;
28
+ phone: string;
29
+ otp: string;
30
+ /** Returned by `requestOtp(...)`. */
31
+ requestId: string;
32
+ fetchFn?: typeof fetch;
33
+ }
34
+ /**
35
+ * Step 2 of the customer OTP login. Exchanges the (phone, otp,
36
+ * requestId) triple for an access + refresh pair. Returns the same
37
+ * `TokenPair` shape as the other login flows; pass
38
+ * `tokens.accessToken` into `createClient({ authToken })`.
39
+ *
40
+ * Throws `AuthenticationError` on `invalid_grant` (wrong OTP, expired,
41
+ * locked after too many attempts, or already consumed).
42
+ */
43
+ export declare function verifyOtp(input: VerifyOtpInput): Promise<TokenPair>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestOtp = requestOtp;
4
+ exports.verifyOtp = verifyOtp;
5
+ const errors_1 = require("../errors");
6
+ const exchange_code_1 = require("./exchange-code");
7
+ const DEFAULT_CUSTOMER_AUTH_BASE_URL = 'https://api.platform.uengage.io/auth/customer';
8
+ /**
9
+ * Step 1 of the customer OTP login. Asks the auth surface to mint an
10
+ * OTP, persist it bound to (phone, businessId), and emit it for SMS
11
+ * delivery via the SMS-team subscriber. The plaintext OTP never
12
+ * appears in the response — the SMS team is the side channel.
13
+ *
14
+ * Throws on rate-limit (429), unknown phone-business pair (400), and
15
+ * other non-200 responses.
16
+ */
17
+ async function requestOtp(input) {
18
+ const fetchFn = input.fetchFn ?? globalThis.fetch;
19
+ const res = await fetchFn(`${input.customerAuthBaseUrl ?? DEFAULT_CUSTOMER_AUTH_BASE_URL}/otp/request`, {
20
+ method: 'POST',
21
+ headers: { 'content-type': 'application/json' },
22
+ body: JSON.stringify({ phone: input.phone, businessId: input.businessId }),
23
+ });
24
+ let body;
25
+ try {
26
+ body = (await res.json());
27
+ }
28
+ catch (err) {
29
+ throw new errors_1.PlatformError(`auth server returned non-JSON: HTTP ${res.status}`, {
30
+ status: res.status,
31
+ cause: err,
32
+ });
33
+ }
34
+ if (!res.ok) {
35
+ const error = typeof body.error === 'string' ? body.error : 'otp_request_failed';
36
+ const description = typeof body.error_description === 'string' ? body.error_description : undefined;
37
+ if (res.status === 401) {
38
+ throw new errors_1.AuthenticationError(description ?? error, { cause: body });
39
+ }
40
+ throw new errors_1.PlatformError(description ?? error, { status: res.status, cause: body });
41
+ }
42
+ return {
43
+ requestId: String(body.requestId ?? ''),
44
+ expiresIn: Number(body.expiresIn ?? 0),
45
+ };
46
+ }
47
+ /**
48
+ * Step 2 of the customer OTP login. Exchanges the (phone, otp,
49
+ * requestId) triple for an access + refresh pair. Returns the same
50
+ * `TokenPair` shape as the other login flows; pass
51
+ * `tokens.accessToken` into `createClient({ authToken })`.
52
+ *
53
+ * Throws `AuthenticationError` on `invalid_grant` (wrong OTP, expired,
54
+ * locked after too many attempts, or already consumed).
55
+ */
56
+ async function verifyOtp(input) {
57
+ const body = new URLSearchParams({
58
+ grant_type: 'otp',
59
+ request_id: input.requestId,
60
+ otp: input.otp,
61
+ phone: input.phone,
62
+ });
63
+ const fetchFn = input.fetchFn ?? globalThis.fetch;
64
+ const res = await fetchFn(`${input.customerAuthBaseUrl ?? DEFAULT_CUSTOMER_AUTH_BASE_URL}/oauth/token`, {
65
+ method: 'POST',
66
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
67
+ body: body.toString(),
68
+ });
69
+ return (0, exchange_code_1.parseTokenResponse)(res);
70
+ }
71
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1dGgvb3RwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNkJBLGdDQWlDQztBQXFCRCw4QkFpQkM7QUFwR0Qsc0NBQStEO0FBQy9ELG1EQUFxRTtBQUVyRSxNQUFNLDhCQUE4QixHQUFHLCtDQUErQyxDQUFDO0FBaUJ2Rjs7Ozs7Ozs7R0FRRztBQUNJLEtBQUssVUFBVSxVQUFVLENBQUMsS0FBc0I7SUFDckQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSyxVQUFVLENBQUMsS0FBc0IsQ0FBQztJQUNwRSxNQUFNLEdBQUcsR0FBRyxNQUFNLE9BQU8sQ0FDdkIsR0FBRyxLQUFLLENBQUMsbUJBQW1CLElBQUksOEJBQThCLGNBQWMsRUFDNUU7UUFDRSxNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRTtRQUMvQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7S0FDM0UsQ0FDRixDQUFDO0lBRUYsSUFBSSxJQUE2QixDQUFDO0lBQ2xDLElBQUksQ0FBQztRQUNILElBQUksR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUE0QixDQUFDO0lBQ3ZELENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxJQUFJLHNCQUFhLENBQUMsdUNBQXVDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUMzRSxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07WUFDbEIsS0FBSyxFQUFFLEdBQUc7U0FDWCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNaLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxDQUFDLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDO1FBQ2pGLE1BQU0sV0FBVyxHQUNmLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDbEYsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSw0QkFBbUIsQ0FBQyxXQUFXLElBQUksS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUNELE1BQU0sSUFBSSxzQkFBYSxDQUFDLFdBQVcsSUFBSSxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBQ0QsT0FBTztRQUNMLFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDdkMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztLQUN2QyxDQUFDO0FBQ0osQ0FBQztBQVlEOzs7Ozs7OztHQVFHO0FBQ0ksS0FBSyxVQUFVLFNBQVMsQ0FBQyxLQUFxQjtJQUNuRCxNQUFNLElBQUksR0FBRyxJQUFJLGVBQWUsQ0FBQztRQUMvQixVQUFVLEVBQUUsS0FBSztRQUNqQixVQUFVLEVBQUUsS0FBSyxDQUFDLFNBQVM7UUFDM0IsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO1FBQ2QsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO0tBQ25CLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUssVUFBVSxDQUFDLEtBQXNCLENBQUM7SUFDcEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQ3ZCLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixJQUFJLDhCQUE4QixjQUFjLEVBQzVFO1FBQ0UsTUFBTSxFQUFFLE1BQU07UUFDZCxPQUFPLEVBQUUsRUFBRSxjQUFjLEVBQUUsbUNBQW1DLEVBQUU7UUFDaEUsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7S0FDdEIsQ0FDRixDQUFDO0lBQ0YsT0FBTyxJQUFBLGtDQUFrQixFQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBdXRoZW50aWNhdGlvbkVycm9yLCBQbGF0Zm9ybUVycm9yIH0gZnJvbSAnLi4vZXJyb3JzJztcbmltcG9ydCB7IHBhcnNlVG9rZW5SZXNwb25zZSwgdHlwZSBUb2tlblBhaXIgfSBmcm9tICcuL2V4Y2hhbmdlLWNvZGUnO1xuXG5jb25zdCBERUZBVUxUX0NVU1RPTUVSX0FVVEhfQkFTRV9VUkwgPSAnaHR0cHM6Ly9hcGkucGxhdGZvcm0udWVuZ2FnZS5pby9hdXRoL2N1c3RvbWVyJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0T3RwSW5wdXQge1xuICAvKiogRGVmYXVsdHMgdG8gYGh0dHBzOi8vYXBpLnBsYXRmb3JtLnVlbmdhZ2UuaW8vYXV0aC9jdXN0b21lcmAuICovXG4gIGN1c3RvbWVyQXV0aEJhc2VVcmw/OiBzdHJpbmc7XG4gIHBob25lOiBzdHJpbmc7XG4gIC8qKiB1RW5nYWdlIGJ1c2luZXNzIGlkOyB0aGUgT1RQIGlzIGJvdW5kIHRvIHRoaXMgKHBob25lLCBidXNpbmVzc0lkKSBwYWlyLiAqL1xuICBidXNpbmVzc0lkOiBudW1iZXI7XG4gIGZldGNoRm4/OiB0eXBlb2YgZmV0Y2g7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdE90cFJlc3VsdCB7XG4gIHJlcXVlc3RJZDogc3RyaW5nO1xuICAvKiogU2Vjb25kcyB1bnRpbCB0aGUgT1RQIGV4cGlyZXMgc2VydmVyLXNpZGUuIFR5cGljYWxseSAzMDAgKDUgbWluKS4gKi9cbiAgZXhwaXJlc0luOiBudW1iZXI7XG59XG5cbi8qKlxuICogU3RlcCAxIG9mIHRoZSBjdXN0b21lciBPVFAgbG9naW4uIEFza3MgdGhlIGF1dGggc3VyZmFjZSB0byBtaW50IGFuXG4gKiBPVFAsIHBlcnNpc3QgaXQgYm91bmQgdG8gKHBob25lLCBidXNpbmVzc0lkKSwgYW5kIGVtaXQgaXQgZm9yIFNNU1xuICogZGVsaXZlcnkgdmlhIHRoZSBTTVMtdGVhbSBzdWJzY3JpYmVyLiBUaGUgcGxhaW50ZXh0IE9UUCBuZXZlclxuICogYXBwZWFycyBpbiB0aGUgcmVzcG9uc2Ug4oCUIHRoZSBTTVMgdGVhbSBpcyB0aGUgc2lkZSBjaGFubmVsLlxuICpcbiAqIFRocm93cyBvbiByYXRlLWxpbWl0ICg0MjkpLCB1bmtub3duIHBob25lLWJ1c2luZXNzIHBhaXIgKDQwMCksIGFuZFxuICogb3RoZXIgbm9uLTIwMCByZXNwb25zZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXF1ZXN0T3RwKGlucHV0OiBSZXF1ZXN0T3RwSW5wdXQpOiBQcm9taXNlPFJlcXVlc3RPdHBSZXN1bHQ+IHtcbiAgY29uc3QgZmV0Y2hGbiA9IGlucHV0LmZldGNoRm4gPz8gKGdsb2JhbFRoaXMuZmV0Y2ggYXMgdHlwZW9mIGZldGNoKTtcbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hGbihcbiAgICBgJHtpbnB1dC5jdXN0b21lckF1dGhCYXNlVXJsID8/IERFRkFVTFRfQ1VTVE9NRVJfQVVUSF9CQVNFX1VSTH0vb3RwL3JlcXVlc3RgLFxuICAgIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczogeyAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHBob25lOiBpbnB1dC5waG9uZSwgYnVzaW5lc3NJZDogaW5wdXQuYnVzaW5lc3NJZCB9KSxcbiAgICB9LFxuICApO1xuXG4gIGxldCBib2R5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgdHJ5IHtcbiAgICBib2R5ID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgUGxhdGZvcm1FcnJvcihgYXV0aCBzZXJ2ZXIgcmV0dXJuZWQgbm9uLUpTT046IEhUVFAgJHtyZXMuc3RhdHVzfWAsIHtcbiAgICAgIHN0YXR1czogcmVzLnN0YXR1cyxcbiAgICAgIGNhdXNlOiBlcnIsXG4gICAgfSk7XG4gIH1cbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCBlcnJvciA9IHR5cGVvZiBib2R5LmVycm9yID09PSAnc3RyaW5nJyA/IGJvZHkuZXJyb3IgOiAnb3RwX3JlcXVlc3RfZmFpbGVkJztcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9XG4gICAgICB0eXBlb2YgYm9keS5lcnJvcl9kZXNjcmlwdGlvbiA9PT0gJ3N0cmluZycgPyBib2R5LmVycm9yX2Rlc2NyaXB0aW9uIDogdW5kZWZpbmVkO1xuICAgIGlmIChyZXMuc3RhdHVzID09PSA0MDEpIHtcbiAgICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkVycm9yKGRlc2NyaXB0aW9uID8/IGVycm9yLCB7IGNhdXNlOiBib2R5IH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGxhdGZvcm1FcnJvcihkZXNjcmlwdGlvbiA/PyBlcnJvciwgeyBzdGF0dXM6IHJlcy5zdGF0dXMsIGNhdXNlOiBib2R5IH0pO1xuICB9XG4gIHJldHVybiB7XG4gICAgcmVxdWVzdElkOiBTdHJpbmcoYm9keS5yZXF1ZXN0SWQgPz8gJycpLFxuICAgIGV4cGlyZXNJbjogTnVtYmVyKGJvZHkuZXhwaXJlc0luID8/IDApLFxuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeU90cElucHV0IHtcbiAgLyoqIERlZmF1bHRzIHRvIGBodHRwczovL2FwaS5wbGF0Zm9ybS51ZW5nYWdlLmlvL2F1dGgvY3VzdG9tZXJgLiAqL1xuICBjdXN0b21lckF1dGhCYXNlVXJsPzogc3RyaW5nO1xuICBwaG9uZTogc3RyaW5nO1xuICBvdHA6IHN0cmluZztcbiAgLyoqIFJldHVybmVkIGJ5IGByZXF1ZXN0T3RwKC4uLilgLiAqL1xuICByZXF1ZXN0SWQ6IHN0cmluZztcbiAgZmV0Y2hGbj86IHR5cGVvZiBmZXRjaDtcbn1cblxuLyoqXG4gKiBTdGVwIDIgb2YgdGhlIGN1c3RvbWVyIE9UUCBsb2dpbi4gRXhjaGFuZ2VzIHRoZSAocGhvbmUsIG90cCxcbiAqIHJlcXVlc3RJZCkgdHJpcGxlIGZvciBhbiBhY2Nlc3MgKyByZWZyZXNoIHBhaXIuIFJldHVybnMgdGhlIHNhbWVcbiAqIGBUb2tlblBhaXJgIHNoYXBlIGFzIHRoZSBvdGhlciBsb2dpbiBmbG93czsgcGFzc1xuICogYHRva2Vucy5hY2Nlc3NUb2tlbmAgaW50byBgY3JlYXRlQ2xpZW50KHsgYXV0aFRva2VuIH0pYC5cbiAqXG4gKiBUaHJvd3MgYEF1dGhlbnRpY2F0aW9uRXJyb3JgIG9uIGBpbnZhbGlkX2dyYW50YCAod3JvbmcgT1RQLCBleHBpcmVkLFxuICogbG9ja2VkIGFmdGVyIHRvbyBtYW55IGF0dGVtcHRzLCBvciBhbHJlYWR5IGNvbnN1bWVkKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeU90cChpbnB1dDogVmVyaWZ5T3RwSW5wdXQpOiBQcm9taXNlPFRva2VuUGFpcj4ge1xuICBjb25zdCBib2R5ID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgZ3JhbnRfdHlwZTogJ290cCcsXG4gICAgcmVxdWVzdF9pZDogaW5wdXQucmVxdWVzdElkLFxuICAgIG90cDogaW5wdXQub3RwLFxuICAgIHBob25lOiBpbnB1dC5waG9uZSxcbiAgfSk7XG4gIGNvbnN0IGZldGNoRm4gPSBpbnB1dC5mZXRjaEZuID8/IChnbG9iYWxUaGlzLmZldGNoIGFzIHR5cGVvZiBmZXRjaCk7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoRm4oXG4gICAgYCR7aW5wdXQuY3VzdG9tZXJBdXRoQmFzZVVybCA/PyBERUZBVUxUX0NVU1RPTUVSX0FVVEhfQkFTRV9VUkx9L29hdXRoL3Rva2VuYCxcbiAgICB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sXG4gICAgICBib2R5OiBib2R5LnRvU3RyaW5nKCksXG4gICAgfSxcbiAgKTtcbiAgcmV0dXJuIHBhcnNlVG9rZW5SZXNwb25zZShyZXMpO1xufVxuIl19
package/dist/client.d.ts CHANGED
@@ -1,34 +1,54 @@
1
1
  import { type AuditClient } from './audit/client';
2
2
  import { type BusinessClient } from './business/client';
3
- import { auth } from './auth';
3
+ import { auth as authNamespace } from './auth';
4
4
  /**
5
- * Caller-facing config for the unified `createClient(...)` factory and
6
- * the `platform` singleton.
5
+ * Caller-facing config for `createClient(...)`.
7
6
  *
8
- * Pick exactly one of:
9
- * - `accessToken` (string or callback) for the static Bearer flow
10
- * - `serviceId` + `serviceSecret` for OAuth2 client_credentials
7
+ * `createClient()` (no args) reads everything from the standard
8
+ * `UENGAGE_*` environment variables convenient for Lambdas that
9
+ * already have their config injected by the deploy stack. Any field
10
+ * passed explicitly overrides the matching env default for that one
11
+ * call only (no shared mutable state, no singleton).
11
12
  *
12
- * Without either, calls throw `ConfigError` on the first request.
13
+ * Auth-mode fields are mutually exclusive. Pick one:
14
+ * - `serviceId` + `serviceSecret` OAuth2 client_credentials.
15
+ * - `authToken` static Bearer token, or async
16
+ * callback that returns one.
17
+ * - `sessionToken` legacy customer session token; the
18
+ * SDK exchanges it via the customer
19
+ * auth surface and caches the JWT.
20
+ *
21
+ * Passing more than one explicitly is a `ConfigError`. Passing any one
22
+ * of them suppresses every env-derived auth default, so a caller's
23
+ * explicit override is never silently merged with env credentials of
24
+ * a different mode.
13
25
  */
14
26
  export interface ClientConfig {
15
27
  baseUrl?: string;
16
28
  /**
17
29
  * Auth surface base used to bootstrap the first client_credentials
18
- * mint. Defaults to `${baseUrl}/auth/business`. Once a token exists,
19
- * future auth calls follow the token's `iss` claim.
30
+ * mint. Defaults to `${baseUrl}/auth/business`.
20
31
  */
21
32
  authBaseUrl?: string;
22
33
  /**
23
- * Customer auth surface base used by `withSessionToken`. Defaults
24
- * to `${baseUrl}/auth/customer`.
34
+ * Customer auth surface base used by `sessionToken` exchanges.
35
+ * Defaults to `${baseUrl}/auth/customer`.
25
36
  */
26
37
  customerAuthBaseUrl?: string;
27
- accessToken?: string | (() => string | Promise<string>);
38
+ /** OAuth2 `client_credentials` clientId. Pair with `serviceSecret`. */
28
39
  serviceId?: string;
40
+ /** OAuth2 `client_credentials` clientSecret. Pair with `serviceId`. */
29
41
  serviceSecret?: string;
30
42
  /** Space-separated scope list to request when minting via client_credentials. */
31
43
  scope?: string;
44
+ /** Static Bearer JWT, or async callback that returns one. */
45
+ authToken?: string | (() => string | Promise<string>);
46
+ /**
47
+ * Legacy uEngage session token (from `addo_contacts_mapping.token`).
48
+ * The SDK POSTs it to `customerAuthBaseUrl` to mint a JWT, caches the
49
+ * result, and re-exchanges on 401 / cache miss.
50
+ */
51
+ sessionToken?: string;
32
52
  /**
33
53
  * Service identifier the audit client should stamp into `actor.via`
34
54
  * on emitted events. Defaults to `serviceId` when set; otherwise
@@ -41,48 +61,12 @@ export interface ClientConfig {
41
61
  export interface PlatformClient {
42
62
  business: BusinessClient;
43
63
  audit: AuditClient;
44
- auth: typeof auth;
45
- /**
46
- * Return a derived client bound to the supplied access token.
47
- * Inherits `baseUrl` and `fetchFn`; replaces the token source with
48
- * the new one. Use case: BFF handlers that want to call the
49
- * platform API as the end user instead of as the service.
50
- */
51
- withToken(token: string | (() => string | Promise<string>)): PlatformClient;
52
- /**
53
- * Return a derived client that exchanges a legacy customer session
54
- * token (from `addo_contacts_mapping.token`) for a Bearer JWT
55
- * transparently on each call. The session token is the persistent
56
- * credential — exchanges happen lazily on token-cache miss and on
57
- * 401 retries. When the legacy session is revoked, the next
58
- * exchange returns 401 and surfaces as `AuthenticationError`.
59
- */
60
- withSessionToken(sessionToken: string): PlatformClient;
64
+ auth: typeof authNamespace;
61
65
  }
62
66
  /**
63
- * Build a fresh, isolated client from explicit config. Each call
64
- * gets its own TokenSource state concurrent `createClient(...)` use
65
- * does not stampede the cache.
67
+ * Build a fresh, isolated client. With no args, reads `UENGAGE_*`
68
+ * env vars; explicit fields override per call. Each call gets its own
69
+ * TokenSource state concurrent `createClient(...)` use does not
70
+ * stampede the cache.
66
71
  */
67
72
  export declare function createClient(input?: ClientConfig): PlatformClient;
68
- /**
69
- * Default client. Reads config from environment variables on first
70
- * property access (so test setups that mutate `process.env` after
71
- * import work). Use `createClient(...)` when you need an isolated
72
- * instance with explicit config.
73
- *
74
- * UENGAGE_BASE_URL defaults to https://api.platform.uengage.io
75
- * UENGAGE_AUTH_BASE_URL auth surface override (default ${baseUrl}/auth/business)
76
- * UENGAGE_AUTH_TOKEN static Bearer token (overrides client_credentials)
77
- * UENGAGE_SERVICE_ID OAuth2 client_credentials clientId
78
- * UENGAGE_SERVICE_SECRET OAuth2 client_credentials clientSecret
79
- * UENGAGE_SERVICE_SCOPE optional space-separated scope list
80
- */
81
- export declare const platform: PlatformClient;
82
- /** Test-only: drop the singleton cache between cases. */
83
- export declare function _resetPlatformSingleton(): void;
84
- /**
85
- * Convenience: shorthand for `platform.withToken(token)`.
86
- * BFF handlers commonly call this once per request.
87
- */
88
- export declare function withToken(token: string | (() => string | Promise<string>)): PlatformClient;
package/dist/client.js CHANGED
@@ -1,54 +1,22 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.platform = void 0;
37
3
  exports.createClient = createClient;
38
- exports._resetPlatformSingleton = _resetPlatformSingleton;
39
- exports.withToken = withToken;
40
4
  const client_1 = require("./audit/client");
41
5
  const client_2 = require("./business/client");
6
+ const auth_1 = require("./auth");
42
7
  const token_source_1 = require("./token-source");
8
+ const errors_1 = require("./errors");
43
9
  const DEFAULT_BASE_URL = 'https://api.platform.uengage.io';
44
10
  /**
45
- * Build a fresh, isolated client from explicit config. Each call
46
- * gets its own TokenSource state concurrent `createClient(...)` use
47
- * does not stampede the cache.
11
+ * Build a fresh, isolated client. With no args, reads `UENGAGE_*`
12
+ * env vars; explicit fields override per call. Each call gets its own
13
+ * TokenSource state concurrent `createClient(...)` use does not
14
+ * stampede the cache.
48
15
  */
49
16
  function createClient(input = {}) {
50
- warnIfBrowserSecret(input);
51
- return buildClient(input);
17
+ const merged = mergeWithEnv(input);
18
+ warnIfBrowserSecret(merged);
19
+ return buildClient(merged);
52
20
  }
53
21
  function buildClient(input) {
54
22
  const baseUrl = input.baseUrl ?? DEFAULT_BASE_URL;
@@ -63,42 +31,98 @@ function buildClient(input) {
63
31
  auth,
64
32
  actorVia: input.actorVia ?? input.serviceId,
65
33
  });
66
- const client = {
34
+ return {
67
35
  business: businessClient,
68
36
  audit: auditClient,
69
37
  auth: auth_1.auth,
70
- withToken(token) {
71
- return buildClient({
72
- ...input,
73
- accessToken: token,
74
- // The new client should not also try to mint via
75
- // client_credentials on top of the supplied user token.
76
- serviceId: undefined,
77
- serviceSecret: undefined,
78
- scope: undefined,
79
- });
80
- },
81
- withSessionToken(sessionToken) {
82
- const customerAuthBaseUrl = input.customerAuthBaseUrl ?? `${baseUrl}/auth/customer`;
83
- const fetchFn = input.fetchFn ?? globalThis.fetch;
84
- // Wrap the customer-side session-exchange in a callback-style
85
- // TokenSource. The existing dedup + cache + 401-retry machinery
86
- // does the rest.
87
- return buildClient({
88
- ...input,
89
- accessToken: () => exchangeSessionToken(sessionToken, customerAuthBaseUrl, fetchFn),
90
- serviceId: undefined,
91
- serviceSecret: undefined,
92
- scope: undefined,
93
- });
94
- },
95
38
  };
96
- return client;
39
+ }
40
+ const AUTH_MODE_FIELDS = [
41
+ 'serviceId',
42
+ 'serviceSecret',
43
+ 'scope',
44
+ 'authToken',
45
+ 'sessionToken',
46
+ ];
47
+ /**
48
+ * Merge env-derived defaults with the caller's explicit input. Any
49
+ * explicit auth-mode field suppresses *all* env-derived auth defaults,
50
+ * so an explicit `{authToken}` override doesn't accidentally inherit
51
+ * `serviceId`/`serviceSecret` from env. Non-auth fields fall through
52
+ * normally (caller `baseUrl` overrides env baseUrl; absent input keeps
53
+ * env baseUrl).
54
+ */
55
+ function mergeWithEnv(input) {
56
+ const env = readEnvDefaults();
57
+ const inputHasAuth = inputHasAuthMode(input);
58
+ const envForMerge = inputHasAuth ? withoutAuthFields(env) : env;
59
+ const merged = {
60
+ baseUrl: input.baseUrl ?? envForMerge.baseUrl,
61
+ authBaseUrl: input.authBaseUrl ?? envForMerge.authBaseUrl,
62
+ customerAuthBaseUrl: input.customerAuthBaseUrl ?? envForMerge.customerAuthBaseUrl,
63
+ serviceId: input.serviceId ?? envForMerge.serviceId,
64
+ serviceSecret: input.serviceSecret ?? envForMerge.serviceSecret,
65
+ scope: input.scope ?? envForMerge.scope,
66
+ authToken: input.authToken ?? envForMerge.authToken,
67
+ sessionToken: input.sessionToken ?? envForMerge.sessionToken,
68
+ actorVia: input.actorVia ?? envForMerge.actorVia,
69
+ expiryBufferMs: input.expiryBufferMs ?? envForMerge.expiryBufferMs,
70
+ fetchFn: input.fetchFn,
71
+ };
72
+ assertExactlyOneAuthMode(merged);
73
+ return merged;
74
+ }
75
+ function readEnvDefaults() {
76
+ if (typeof process === 'undefined')
77
+ return {};
78
+ const e = process.env ?? {};
79
+ const expiry = e.UENGAGE_EXPIRY_BUFFER_MS ? Number(e.UENGAGE_EXPIRY_BUFFER_MS) : undefined;
80
+ return {
81
+ baseUrl: e.UENGAGE_BASE_URL,
82
+ authBaseUrl: e.UENGAGE_AUTH_BASE_URL,
83
+ customerAuthBaseUrl: e.UENGAGE_CUSTOMER_AUTH_BASE_URL,
84
+ serviceId: e.UENGAGE_SERVICE_ID,
85
+ serviceSecret: e.UENGAGE_SERVICE_SECRET,
86
+ scope: e.UENGAGE_SCOPE,
87
+ authToken: e.UENGAGE_AUTH_TOKEN,
88
+ sessionToken: e.UENGAGE_SESSION_TOKEN,
89
+ actorVia: e.UENGAGE_ACTOR_VIA,
90
+ expiryBufferMs: Number.isFinite(expiry) ? expiry : undefined,
91
+ };
92
+ }
93
+ function inputHasAuthMode(input) {
94
+ return AUTH_MODE_FIELDS.some((f) => input[f] !== undefined);
95
+ }
96
+ function withoutAuthFields(c) {
97
+ return {
98
+ ...c,
99
+ serviceId: undefined,
100
+ serviceSecret: undefined,
101
+ scope: undefined,
102
+ authToken: undefined,
103
+ sessionToken: undefined,
104
+ };
105
+ }
106
+ function assertExactlyOneAuthMode(input) {
107
+ const modes = [];
108
+ if (input.authToken !== undefined)
109
+ modes.push('authToken');
110
+ if (input.sessionToken !== undefined)
111
+ modes.push('sessionToken');
112
+ if (input.serviceId !== undefined || input.serviceSecret !== undefined) {
113
+ modes.push('serviceId+serviceSecret');
114
+ }
115
+ if (modes.length > 1) {
116
+ throw new errors_1.ConfigError(`createClient: pick exactly one auth mode. Got ${modes.join(', ')}. ` +
117
+ 'Use one of {serviceId, serviceSecret} | {authToken} | {sessionToken}.');
118
+ }
119
+ // Zero modes is allowed — caller may want a fully-anonymous client for
120
+ // public endpoints. The first request that needs auth will surface a
121
+ // ConfigError downstream.
97
122
  }
98
123
  /**
99
124
  * POST to the customer auth surface to exchange a legacy session
100
- * token for a fresh access token. Internal to `withSessionToken`;
101
- * callers don't see this directly.
125
+ * token for a fresh access token. Used by `createClient({ sessionToken })`.
102
126
  */
103
127
  async function exchangeSessionToken(sessionToken, customerAuthBaseUrl, fetchFn) {
104
128
  const res = await fetchFn(`${customerAuthBaseUrl}/oauth/token`, {
@@ -111,24 +135,30 @@ async function exchangeSessionToken(sessionToken, customerAuthBaseUrl, fetchFn)
111
135
  });
112
136
  if (!res.ok) {
113
137
  const text = await res.text().catch(() => '');
114
- const { AuthenticationError } = await Promise.resolve().then(() => __importStar(require('./errors')));
115
- throw new AuthenticationError(`session-token exchange failed: HTTP ${res.status} ${text}`);
138
+ throw new errors_1.AuthenticationError(`session-token exchange failed: HTTP ${res.status} ${text}`);
116
139
  }
117
140
  const json = (await res.json());
118
141
  if (!json.access_token) {
119
- const { ConfigError } = await Promise.resolve().then(() => __importStar(require('./errors')));
120
- throw new ConfigError('session-token exchange response missing access_token');
142
+ throw new errors_1.ConfigError('session-token exchange response missing access_token');
121
143
  }
122
144
  return json.access_token;
123
145
  }
124
- const auth_1 = require("./auth");
125
146
  function resolveTokenSource(input, baseUrl) {
126
147
  const authBaseUrl = input.authBaseUrl ?? `${baseUrl}/auth/business`;
127
- if (input.accessToken !== undefined) {
128
- if (typeof input.accessToken === 'string') {
129
- return (0, token_source_1.makeTokenSourceState)({ kind: 'static-string', token: input.accessToken }, { expiryBufferMs: input.expiryBufferMs, fetchFn: input.fetchFn });
148
+ const fetchFn = input.fetchFn ?? globalThis.fetch;
149
+ if (input.authToken !== undefined) {
150
+ if (typeof input.authToken === 'string') {
151
+ return (0, token_source_1.makeTokenSourceState)({ kind: 'static-string', token: input.authToken }, { expiryBufferMs: input.expiryBufferMs, fetchFn: input.fetchFn });
130
152
  }
131
- return (0, token_source_1.makeTokenSourceState)({ kind: 'callback', getToken: input.accessToken }, { expiryBufferMs: input.expiryBufferMs, fetchFn: input.fetchFn });
153
+ return (0, token_source_1.makeTokenSourceState)({ kind: 'callback', getToken: input.authToken }, { expiryBufferMs: input.expiryBufferMs, fetchFn: input.fetchFn });
154
+ }
155
+ if (input.sessionToken !== undefined) {
156
+ const customerAuthBaseUrl = input.customerAuthBaseUrl ?? `${baseUrl}/auth/customer`;
157
+ const sessionToken = input.sessionToken;
158
+ return (0, token_source_1.makeTokenSourceState)({
159
+ kind: 'callback',
160
+ getToken: () => exchangeSessionToken(sessionToken, customerAuthBaseUrl, fetchFn),
161
+ }, { expiryBufferMs: input.expiryBufferMs, fetchFn: input.fetchFn });
132
162
  }
133
163
  if (input.serviceId && input.serviceSecret) {
134
164
  return (0, token_source_1.makeTokenSourceState)({
@@ -149,60 +179,7 @@ function warnIfBrowserSecret(config) {
149
179
  if (config.serviceSecret) {
150
180
  console.warn('[uengage-platform-sdk] serviceSecret should not be used in browser environments. ' +
151
181
  'Service credentials in browser bundles are publicly visible. ' +
152
- 'Use `accessToken` with a token obtained via OAuth (or `withToken(...)` on a server-built client) instead.');
182
+ 'Use `authToken` (a Bearer obtained via OAuth) or `sessionToken` instead.');
153
183
  }
154
184
  }
155
- // ─── Default singleton ─────────────────────────────────────────────────────
156
- //
157
- // Resolved lazily on first property access (Proxy) so consumers that
158
- // mutate `process.env` after import still pick up the right values.
159
- let cachedSingleton;
160
- function singleton() {
161
- if (!cachedSingleton)
162
- cachedSingleton = buildClient(envClientConfig());
163
- return cachedSingleton;
164
- }
165
- function envClientConfig() {
166
- if (typeof process === 'undefined')
167
- return {};
168
- const e = process.env ?? {};
169
- return {
170
- baseUrl: e.UENGAGE_BASE_URL,
171
- authBaseUrl: e.UENGAGE_AUTH_BASE_URL,
172
- accessToken: e.UENGAGE_AUTH_TOKEN,
173
- serviceId: e.UENGAGE_SERVICE_ID,
174
- serviceSecret: e.UENGAGE_SERVICE_SECRET,
175
- scope: e.UENGAGE_SERVICE_SCOPE,
176
- };
177
- }
178
- /**
179
- * Default client. Reads config from environment variables on first
180
- * property access (so test setups that mutate `process.env` after
181
- * import work). Use `createClient(...)` when you need an isolated
182
- * instance with explicit config.
183
- *
184
- * UENGAGE_BASE_URL defaults to https://api.platform.uengage.io
185
- * UENGAGE_AUTH_BASE_URL auth surface override (default ${baseUrl}/auth/business)
186
- * UENGAGE_AUTH_TOKEN static Bearer token (overrides client_credentials)
187
- * UENGAGE_SERVICE_ID OAuth2 client_credentials clientId
188
- * UENGAGE_SERVICE_SECRET OAuth2 client_credentials clientSecret
189
- * UENGAGE_SERVICE_SCOPE optional space-separated scope list
190
- */
191
- exports.platform = new Proxy({}, {
192
- get(_, prop) {
193
- const s = singleton();
194
- return s[prop];
195
- },
196
- });
197
- /** Test-only: drop the singleton cache between cases. */
198
- function _resetPlatformSingleton() {
199
- cachedSingleton = undefined;
200
- }
201
- /**
202
- * Convenience: shorthand for `platform.withToken(token)`.
203
- * BFF handlers commonly call this once per request.
204
- */
205
- function withToken(token) {
206
- return singleton().withToken(token);
207
- }
208
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF5RUEsb0NBR0M7QUEwS0QsMERBRUM7QUFNRCw4QkFFQztBQWhRRCwyQ0FBcUU7QUFDckUsOENBQThFO0FBRTlFLGlEQUE2RTtBQStEN0UsTUFBTSxnQkFBZ0IsR0FBRyxpQ0FBaUMsQ0FBQztBQUUzRDs7OztHQUlHO0FBQ0gsU0FBZ0IsWUFBWSxDQUFDLFFBQXNCLEVBQUU7SUFDbkQsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsT0FBTyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLEtBQW1CO0lBQ3RDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUksZ0JBQWdCLENBQUM7SUFDbEQsTUFBTSxnQkFBZ0IsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUQsTUFBTSxJQUFJLEdBQTZCLGdCQUFnQjtRQUNyRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRTtRQUNuRCxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRWQsTUFBTSxjQUFjLEdBQUcsSUFBQSw2QkFBb0IsRUFBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZGLE1BQU0sV0FBVyxHQUFHLElBQUEsMEJBQWlCLEVBQUM7UUFDcEMsT0FBTztRQUNQLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztRQUN0QixJQUFJO1FBQ0osUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVM7S0FDNUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLEdBQW1CO1FBQzdCLFFBQVEsRUFBRSxjQUFjO1FBQ3hCLEtBQUssRUFBRSxXQUFXO1FBQ2xCLElBQUksRUFBRSxXQUFhO1FBQ25CLFNBQVMsQ0FBQyxLQUFLO1lBQ2IsT0FBTyxXQUFXLENBQUM7Z0JBQ2pCLEdBQUcsS0FBSztnQkFDUixXQUFXLEVBQUUsS0FBSztnQkFDbEIsaURBQWlEO2dCQUNqRCx3REFBd0Q7Z0JBQ3hELFNBQVMsRUFBRSxTQUFTO2dCQUNwQixhQUFhLEVBQUUsU0FBUztnQkFDeEIsS0FBSyxFQUFFLFNBQVM7YUFDakIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELGdCQUFnQixDQUFDLFlBQVk7WUFDM0IsTUFBTSxtQkFBbUIsR0FBRyxLQUFLLENBQUMsbUJBQW1CLElBQUksR0FBRyxPQUFPLGdCQUFnQixDQUFDO1lBQ3BGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUssVUFBVSxDQUFDLEtBQXNCLENBQUM7WUFDcEUsOERBQThEO1lBQzlELGdFQUFnRTtZQUNoRSxpQkFBaUI7WUFDakIsT0FBTyxXQUFXLENBQUM7Z0JBQ2pCLEdBQUcsS0FBSztnQkFDUixXQUFXLEVBQUUsR0FBRyxFQUFFLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLE9BQU8sQ0FBQztnQkFDbkYsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLGFBQWEsRUFBRSxTQUFTO2dCQUN4QixLQUFLLEVBQUUsU0FBUzthQUNqQixDQUFDLENBQUM7UUFDTCxDQUFDO0tBQ0YsQ0FBQztJQUNGLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLG9CQUFvQixDQUNqQyxZQUFvQixFQUNwQixtQkFBMkIsRUFDM0IsT0FBcUI7SUFFckIsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxtQkFBbUIsY0FBYyxFQUFFO1FBQzlELE1BQU0sRUFBRSxNQUFNO1FBQ2QsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLG1DQUFtQyxFQUFFO1FBQ2hFLElBQUksRUFBRSxJQUFJLGVBQWUsQ0FBQztZQUN4QixVQUFVLEVBQUUsZUFBZTtZQUMzQixhQUFhLEVBQUUsWUFBWTtTQUM1QixDQUFDLENBQUMsUUFBUSxFQUFFO0tBQ2QsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM5QyxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsR0FBRyx3REFBYSxVQUFVLEdBQUMsQ0FBQztRQUN6RCxNQUFNLElBQUksbUJBQW1CLENBQUMsdUNBQXVDLEdBQUcsQ0FBQyxNQUFNLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM3RixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBOEIsQ0FBQztJQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyx3REFBYSxVQUFVLEdBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksV0FBVyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztBQUMzQixDQUFDO0FBRUQsaUNBQStDO0FBRS9DLFNBQVMsa0JBQWtCLENBQUMsS0FBbUIsRUFBRSxPQUFlO0lBQzlELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLElBQUksR0FBRyxPQUFPLGdCQUFnQixDQUFDO0lBQ3BFLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwQyxJQUFJLE9BQU8sS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMxQyxPQUFPLElBQUEsbUNBQW9CLEVBQ3pCLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUNuRCxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQ2pFLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxJQUFBLG1DQUFvQixFQUN6QixFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFDakQsRUFBRSxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUNqRSxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0MsT0FBTyxJQUFBLG1DQUFvQixFQUN6QjtZQUNFLElBQUksRUFBRSxxQkFBcUI7WUFDM0IsUUFBUSxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQ3pCLFlBQVksRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNqQyxXQUFXO1lBQ1gsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO1NBQ25CLEVBQ0QsRUFBRSxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUNqRSxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUFDLE1BQW9CO0lBQy9DLE1BQU0sQ0FBQyxHQUFHLFVBQWlELENBQUM7SUFDNUQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFdBQVcsQ0FBQztJQUM5RixJQUFJLENBQUMsU0FBUztRQUFFLE9BQU87SUFDdkIsSUFBSSxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekIsT0FBTyxDQUFDLElBQUksQ0FDVixtRkFBbUY7WUFDakYsK0RBQStEO1lBQy9ELDJHQUEyRyxDQUM5RyxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsRUFBRTtBQUNGLHFFQUFxRTtBQUNyRSxvRUFBb0U7QUFFcEUsSUFBSSxlQUEyQyxDQUFDO0FBQ2hELFNBQVMsU0FBUztJQUNoQixJQUFJLENBQUMsZUFBZTtRQUFFLGVBQWUsR0FBRyxXQUFXLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztJQUN2RSxPQUFPLGVBQWUsQ0FBQztBQUN6QixDQUFDO0FBRUQsU0FBUyxlQUFlO0lBQ3RCLElBQUksT0FBTyxPQUFPLEtBQUssV0FBVztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQzlDLE1BQU0sQ0FBQyxHQUFJLE9BQXdELENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQztJQUM5RSxPQUFPO1FBQ0wsT0FBTyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0I7UUFDM0IsV0FBVyxFQUFFLENBQUMsQ0FBQyxxQkFBcUI7UUFDcEMsV0FBVyxFQUFFLENBQUMsQ0FBQyxrQkFBa0I7UUFDakMsU0FBUyxFQUFFLENBQUMsQ0FBQyxrQkFBa0I7UUFDL0IsYUFBYSxFQUFFLENBQUMsQ0FBQyxzQkFBc0I7UUFDdkMsS0FBSyxFQUFFLENBQUMsQ0FBQyxxQkFBcUI7S0FDL0IsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDVSxRQUFBLFFBQVEsR0FBbUIsSUFBSSxLQUFLLENBQUMsRUFBb0IsRUFBRTtJQUN0RSxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUk7UUFDVCxNQUFNLENBQUMsR0FBRyxTQUFTLEVBQTZDLENBQUM7UUFDakUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakIsQ0FBQztDQUNGLENBQUMsQ0FBQztBQUVILHlEQUF5RDtBQUN6RCxTQUFnQix1QkFBdUI7SUFDckMsZUFBZSxHQUFHLFNBQVMsQ0FBQztBQUM5QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLEtBQWdEO0lBQ3hFLE9BQU8sU0FBUyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVBdWRpdENsaWVudCwgdHlwZSBBdWRpdENsaWVudCB9IGZyb20gJy4vYXVkaXQvY2xpZW50JztcbmltcG9ydCB7IGNyZWF0ZUJ1c2luZXNzQ2xpZW50LCB0eXBlIEJ1c2luZXNzQ2xpZW50IH0gZnJvbSAnLi9idXNpbmVzcy9jbGllbnQnO1xuaW1wb3J0IHsgYXV0aCB9IGZyb20gJy4vYXV0aCc7XG5pbXBvcnQgeyBtYWtlVG9rZW5Tb3VyY2VTdGF0ZSwgdHlwZSBUb2tlblNvdXJjZVN0YXRlIH0gZnJvbSAnLi90b2tlbi1zb3VyY2UnO1xuaW1wb3J0IHR5cGUgeyBQbGF0Zm9ybUF1dGggfSBmcm9tICcuL2NvbmZpZyc7XG5cbi8qKlxuICogQ2FsbGVyLWZhY2luZyBjb25maWcgZm9yIHRoZSB1bmlmaWVkIGBjcmVhdGVDbGllbnQoLi4uKWAgZmFjdG9yeSBhbmRcbiAqIHRoZSBgcGxhdGZvcm1gIHNpbmdsZXRvbi5cbiAqXG4gKiBQaWNrIGV4YWN0bHkgb25lIG9mOlxuICogICAtIGBhY2Nlc3NUb2tlbmAgKHN0cmluZyBvciBjYWxsYmFjaykgZm9yIHRoZSBzdGF0aWMgQmVhcmVyIGZsb3dcbiAqICAgLSBgc2VydmljZUlkYCArIGBzZXJ2aWNlU2VjcmV0YCBmb3IgT0F1dGgyIGNsaWVudF9jcmVkZW50aWFsc1xuICpcbiAqIFdpdGhvdXQgZWl0aGVyLCBjYWxscyB0aHJvdyBgQ29uZmlnRXJyb3JgIG9uIHRoZSBmaXJzdCByZXF1ZXN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsaWVudENvbmZpZyB7XG4gIGJhc2VVcmw/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBdXRoIHN1cmZhY2UgYmFzZSB1c2VkIHRvIGJvb3RzdHJhcCB0aGUgZmlyc3QgY2xpZW50X2NyZWRlbnRpYWxzXG4gICAqIG1pbnQuIERlZmF1bHRzIHRvIGAke2Jhc2VVcmx9L2F1dGgvYnVzaW5lc3NgLiBPbmNlIGEgdG9rZW4gZXhpc3RzLFxuICAgKiBmdXR1cmUgYXV0aCBjYWxscyBmb2xsb3cgdGhlIHRva2VuJ3MgYGlzc2AgY2xhaW0uXG4gICAqL1xuICBhdXRoQmFzZVVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIEN1c3RvbWVyIGF1dGggc3VyZmFjZSBiYXNlIHVzZWQgYnkgYHdpdGhTZXNzaW9uVG9rZW5gLiBEZWZhdWx0c1xuICAgKiB0byBgJHtiYXNlVXJsfS9hdXRoL2N1c3RvbWVyYC5cbiAgICovXG4gIGN1c3RvbWVyQXV0aEJhc2VVcmw/OiBzdHJpbmc7XG4gIGFjY2Vzc1Rva2VuPzogc3RyaW5nIHwgKCgpID0+IHN0cmluZyB8IFByb21pc2U8c3RyaW5nPik7XG4gIHNlcnZpY2VJZD86IHN0cmluZztcbiAgc2VydmljZVNlY3JldD86IHN0cmluZztcbiAgLyoqIFNwYWNlLXNlcGFyYXRlZCBzY29wZSBsaXN0IHRvIHJlcXVlc3Qgd2hlbiBtaW50aW5nIHZpYSBjbGllbnRfY3JlZGVudGlhbHMuICovXG4gIHNjb3BlPzogc3RyaW5nO1xuICAvKipcbiAgICogU2VydmljZSBpZGVudGlmaWVyIHRoZSBhdWRpdCBjbGllbnQgc2hvdWxkIHN0YW1wIGludG8gYGFjdG9yLnZpYWBcbiAgICogb24gZW1pdHRlZCBldmVudHMuIERlZmF1bHRzIHRvIGBzZXJ2aWNlSWRgIHdoZW4gc2V0OyBvdGhlcndpc2VcbiAgICogYXVkaXQgYHJlY29yZCgpYCBjYWxscyBsb2cgYW4gZXJyb3IgYW5kIGRyb3AgdGhlIGV2ZW50LlxuICAgKi9cbiAgYWN0b3JWaWE/OiBzdHJpbmc7XG4gIGV4cGlyeUJ1ZmZlck1zPzogbnVtYmVyO1xuICBmZXRjaEZuPzogdHlwZW9mIGZldGNoO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBsYXRmb3JtQ2xpZW50IHtcbiAgYnVzaW5lc3M6IEJ1c2luZXNzQ2xpZW50O1xuICBhdWRpdDogQXVkaXRDbGllbnQ7XG4gIGF1dGg6IHR5cGVvZiBhdXRoO1xuICAvKipcbiAgICogUmV0dXJuIGEgZGVyaXZlZCBjbGllbnQgYm91bmQgdG8gdGhlIHN1cHBsaWVkIGFjY2VzcyB0b2tlbi5cbiAgICogSW5oZXJpdHMgYGJhc2VVcmxgIGFuZCBgZmV0Y2hGbmA7IHJlcGxhY2VzIHRoZSB0b2tlbiBzb3VyY2Ugd2l0aFxuICAgKiB0aGUgbmV3IG9uZS4gVXNlIGNhc2U6IEJGRiBoYW5kbGVycyB0aGF0IHdhbnQgdG8gY2FsbCB0aGVcbiAgICogcGxhdGZvcm0gQVBJIGFzIHRoZSBlbmQgdXNlciBpbnN0ZWFkIG9mIGFzIHRoZSBzZXJ2aWNlLlxuICAgKi9cbiAgd2l0aFRva2VuKHRva2VuOiBzdHJpbmcgfCAoKCkgPT4gc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+KSk6IFBsYXRmb3JtQ2xpZW50O1xuICAvKipcbiAgICogUmV0dXJuIGEgZGVyaXZlZCBjbGllbnQgdGhhdCBleGNoYW5nZXMgYSBsZWdhY3kgY3VzdG9tZXIgc2Vzc2lvblxuICAgKiB0b2tlbiAoZnJvbSBgYWRkb19jb250YWN0c19tYXBwaW5nLnRva2VuYCkgZm9yIGEgQmVhcmVyIEpXVFxuICAgKiB0cmFuc3BhcmVudGx5IG9uIGVhY2ggY2FsbC4gVGhlIHNlc3Npb24gdG9rZW4gaXMgdGhlIHBlcnNpc3RlbnRcbiAgICogY3JlZGVudGlhbCDigJQgZXhjaGFuZ2VzIGhhcHBlbiBsYXppbHkgb24gdG9rZW4tY2FjaGUgbWlzcyBhbmQgb25cbiAgICogNDAxIHJldHJpZXMuIFdoZW4gdGhlIGxlZ2FjeSBzZXNzaW9uIGlzIHJldm9rZWQsIHRoZSBuZXh0XG4gICAqIGV4Y2hhbmdlIHJldHVybnMgNDAxIGFuZCBzdXJmYWNlcyBhcyBgQXV0aGVudGljYXRpb25FcnJvcmAuXG4gICAqL1xuICB3aXRoU2Vzc2lvblRva2VuKHNlc3Npb25Ub2tlbjogc3RyaW5nKTogUGxhdGZvcm1DbGllbnQ7XG59XG5cbmNvbnN0IERFRkFVTFRfQkFTRV9VUkwgPSAnaHR0cHM6Ly9hcGkucGxhdGZvcm0udWVuZ2FnZS5pbyc7XG5cbi8qKlxuICogQnVpbGQgYSBmcmVzaCwgaXNvbGF0ZWQgY2xpZW50IGZyb20gZXhwbGljaXQgY29uZmlnLiBFYWNoIGNhbGxcbiAqIGdldHMgaXRzIG93biBUb2tlblNvdXJjZSBzdGF0ZSDigJQgY29uY3VycmVudCBgY3JlYXRlQ2xpZW50KC4uLilgIHVzZVxuICogZG9lcyBub3Qgc3RhbXBlZGUgdGhlIGNhY2hlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KGlucHV0OiBDbGllbnRDb25maWcgPSB7fSk6IFBsYXRmb3JtQ2xpZW50IHtcbiAgd2FybklmQnJvd3NlclNlY3JldChpbnB1dCk7XG4gIHJldHVybiBidWlsZENsaWVudChpbnB1dCk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkQ2xpZW50KGlucHV0OiBDbGllbnRDb25maWcpOiBQbGF0Zm9ybUNsaWVudCB7XG4gIGNvbnN0IGJhc2VVcmwgPSBpbnB1dC5iYXNlVXJsID8/IERFRkFVTFRfQkFTRV9VUkw7XG4gIGNvbnN0IHRva2VuU291cmNlU3RhdGUgPSByZXNvbHZlVG9rZW5Tb3VyY2UoaW5wdXQsIGJhc2VVcmwpO1xuICBjb25zdCBhdXRoOiBQbGF0Zm9ybUF1dGggfCB1bmRlZmluZWQgPSB0b2tlblNvdXJjZVN0YXRlXG4gICAgPyB7IHR5cGU6ICd0b2tlbi1zb3VyY2UnLCBzdGF0ZTogdG9rZW5Tb3VyY2VTdGF0ZSB9XG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgYnVzaW5lc3NDbGllbnQgPSBjcmVhdGVCdXNpbmVzc0NsaWVudCh7IGJhc2VVcmwsIGZldGNoRm46IGlucHV0LmZldGNoRm4sIGF1dGggfSk7XG4gIGNvbnN0IGF1ZGl0Q2xpZW50ID0gY3JlYXRlQXVkaXRDbGllbnQoe1xuICAgIGJhc2VVcmwsXG4gICAgZmV0Y2hGbjogaW5wdXQuZmV0Y2hGbixcbiAgICBhdXRoLFxuICAgIGFjdG9yVmlhOiBpbnB1dC5hY3RvclZpYSA/PyBpbnB1dC5zZXJ2aWNlSWQsXG4gIH0pO1xuXG4gIGNvbnN0IGNsaWVudDogUGxhdGZvcm1DbGllbnQgPSB7XG4gICAgYnVzaW5lc3M6IGJ1c2luZXNzQ2xpZW50LFxuICAgIGF1ZGl0OiBhdWRpdENsaWVudCxcbiAgICBhdXRoOiBhdXRoTmFtZXNwYWNlLFxuICAgIHdpdGhUb2tlbih0b2tlbikge1xuICAgICAgcmV0dXJuIGJ1aWxkQ2xpZW50KHtcbiAgICAgICAgLi4uaW5wdXQsXG4gICAgICAgIGFjY2Vzc1Rva2VuOiB0b2tlbixcbiAgICAgICAgLy8gVGhlIG5ldyBjbGllbnQgc2hvdWxkIG5vdCBhbHNvIHRyeSB0byBtaW50IHZpYVxuICAgICAgICAvLyBjbGllbnRfY3JlZGVudGlhbHMgb24gdG9wIG9mIHRoZSBzdXBwbGllZCB1c2VyIHRva2VuLlxuICAgICAgICBzZXJ2aWNlSWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VydmljZVNlY3JldDogdW5kZWZpbmVkLFxuICAgICAgICBzY29wZTogdW5kZWZpbmVkLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICB3aXRoU2Vzc2lvblRva2VuKHNlc3Npb25Ub2tlbikge1xuICAgICAgY29uc3QgY3VzdG9tZXJBdXRoQmFzZVVybCA9IGlucHV0LmN1c3RvbWVyQXV0aEJhc2VVcmwgPz8gYCR7YmFzZVVybH0vYXV0aC9jdXN0b21lcmA7XG4gICAgICBjb25zdCBmZXRjaEZuID0gaW5wdXQuZmV0Y2hGbiA/PyAoZ2xvYmFsVGhpcy5mZXRjaCBhcyB0eXBlb2YgZmV0Y2gpO1xuICAgICAgLy8gV3JhcCB0aGUgY3VzdG9tZXItc2lkZSBzZXNzaW9uLWV4Y2hhbmdlIGluIGEgY2FsbGJhY2stc3R5bGVcbiAgICAgIC8vIFRva2VuU291cmNlLiBUaGUgZXhpc3RpbmcgZGVkdXAgKyBjYWNoZSArIDQwMS1yZXRyeSBtYWNoaW5lcnlcbiAgICAgIC8vIGRvZXMgdGhlIHJlc3QuXG4gICAgICByZXR1cm4gYnVpbGRDbGllbnQoe1xuICAgICAgICAuLi5pbnB1dCxcbiAgICAgICAgYWNjZXNzVG9rZW46ICgpID0+IGV4Y2hhbmdlU2Vzc2lvblRva2VuKHNlc3Npb25Ub2tlbiwgY3VzdG9tZXJBdXRoQmFzZVVybCwgZmV0Y2hGbiksXG4gICAgICAgIHNlcnZpY2VJZDogdW5kZWZpbmVkLFxuICAgICAgICBzZXJ2aWNlU2VjcmV0OiB1bmRlZmluZWQsXG4gICAgICAgIHNjb3BlOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9LFxuICB9O1xuICByZXR1cm4gY2xpZW50O1xufVxuXG4vKipcbiAqIFBPU1QgdG8gdGhlIGN1c3RvbWVyIGF1dGggc3VyZmFjZSB0byBleGNoYW5nZSBhIGxlZ2FjeSBzZXNzaW9uXG4gKiB0b2tlbiBmb3IgYSBmcmVzaCBhY2Nlc3MgdG9rZW4uIEludGVybmFsIHRvIGB3aXRoU2Vzc2lvblRva2VuYDtcbiAqIGNhbGxlcnMgZG9uJ3Qgc2VlIHRoaXMgZGlyZWN0bHkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4Y2hhbmdlU2Vzc2lvblRva2VuKFxuICBzZXNzaW9uVG9rZW46IHN0cmluZyxcbiAgY3VzdG9tZXJBdXRoQmFzZVVybDogc3RyaW5nLFxuICBmZXRjaEZuOiB0eXBlb2YgZmV0Y2gsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaEZuKGAke2N1c3RvbWVyQXV0aEJhc2VVcmx9L29hdXRoL3Rva2VuYCwge1xuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sXG4gICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICBncmFudF90eXBlOiAnc2Vzc2lvbl90b2tlbicsXG4gICAgICBzZXNzaW9uX3Rva2VuOiBzZXNzaW9uVG9rZW4sXG4gICAgfSkudG9TdHJpbmcoKSxcbiAgfSk7XG4gIGlmICghcmVzLm9rKSB7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCkuY2F0Y2goKCkgPT4gJycpO1xuICAgIGNvbnN0IHsgQXV0aGVudGljYXRpb25FcnJvciB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9ycycpO1xuICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkVycm9yKGBzZXNzaW9uLXRva2VuIGV4Y2hhbmdlIGZhaWxlZDogSFRUUCAke3Jlcy5zdGF0dXN9ICR7dGV4dH1gKTtcbiAgfVxuICBjb25zdCBqc29uID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHsgYWNjZXNzX3Rva2VuPzogc3RyaW5nIH07XG4gIGlmICghanNvbi5hY2Nlc3NfdG9rZW4pIHtcbiAgICBjb25zdCB7IENvbmZpZ0Vycm9yIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3JzJyk7XG4gICAgdGhyb3cgbmV3IENvbmZpZ0Vycm9yKCdzZXNzaW9uLXRva2VuIGV4Y2hhbmdlIHJlc3BvbnNlIG1pc3NpbmcgYWNjZXNzX3Rva2VuJyk7XG4gIH1cbiAgcmV0dXJuIGpzb24uYWNjZXNzX3Rva2VuO1xufVxuXG5pbXBvcnQgeyBhdXRoIGFzIGF1dGhOYW1lc3BhY2UgfSBmcm9tICcuL2F1dGgnO1xuXG5mdW5jdGlvbiByZXNvbHZlVG9rZW5Tb3VyY2UoaW5wdXQ6IENsaWVudENvbmZpZywgYmFzZVVybDogc3RyaW5nKTogVG9rZW5Tb3VyY2VTdGF0ZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGF1dGhCYXNlVXJsID0gaW5wdXQuYXV0aEJhc2VVcmwgPz8gYCR7YmFzZVVybH0vYXV0aC9idXNpbmVzc2A7XG4gIGlmIChpbnB1dC5hY2Nlc3NUb2tlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBpbnB1dC5hY2Nlc3NUb2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBtYWtlVG9rZW5Tb3VyY2VTdGF0ZShcbiAgICAgICAgeyBraW5kOiAnc3RhdGljLXN0cmluZycsIHRva2VuOiBpbnB1dC5hY2Nlc3NUb2tlbiB9LFxuICAgICAgICB7IGV4cGlyeUJ1ZmZlck1zOiBpbnB1dC5leHBpcnlCdWZmZXJNcywgZmV0Y2hGbjogaW5wdXQuZmV0Y2hGbiB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VUb2tlblNvdXJjZVN0YXRlKFxuICAgICAgeyBraW5kOiAnY2FsbGJhY2snLCBnZXRUb2tlbjogaW5wdXQuYWNjZXNzVG9rZW4gfSxcbiAgICAgIHsgZXhwaXJ5QnVmZmVyTXM6IGlucHV0LmV4cGlyeUJ1ZmZlck1zLCBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuIH0sXG4gICAgKTtcbiAgfVxuICBpZiAoaW5wdXQuc2VydmljZUlkICYmIGlucHV0LnNlcnZpY2VTZWNyZXQpIHtcbiAgICByZXR1cm4gbWFrZVRva2VuU291cmNlU3RhdGUoXG4gICAgICB7XG4gICAgICAgIGtpbmQ6ICdzZXJ2aWNlLWNyZWRlbnRpYWxzJyxcbiAgICAgICAgY2xpZW50SWQ6IGlucHV0LnNlcnZpY2VJZCxcbiAgICAgICAgY2xpZW50U2VjcmV0OiBpbnB1dC5zZXJ2aWNlU2VjcmV0LFxuICAgICAgICBhdXRoQmFzZVVybCxcbiAgICAgICAgc2NvcGU6IGlucHV0LnNjb3BlLFxuICAgICAgfSxcbiAgICAgIHsgZXhwaXJ5QnVmZmVyTXM6IGlucHV0LmV4cGlyeUJ1ZmZlck1zLCBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuIH0sXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZCcm93c2VyU2VjcmV0KGNvbmZpZzogQ2xpZW50Q29uZmlnKTogdm9pZCB7XG4gIGNvbnN0IGcgPSBnbG9iYWxUaGlzIGFzIHsgd2luZG93PzogeyBkb2N1bWVudD86IHVua25vd24gfSB9O1xuICBjb25zdCBpbkJyb3dzZXIgPSB0eXBlb2YgZy53aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBnLndpbmRvdy5kb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG4gIGlmICghaW5Ccm93c2VyKSByZXR1cm47XG4gIGlmIChjb25maWcuc2VydmljZVNlY3JldCkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgICdbdWVuZ2FnZS1wbGF0Zm9ybS1zZGtdIHNlcnZpY2VTZWNyZXQgc2hvdWxkIG5vdCBiZSB1c2VkIGluIGJyb3dzZXIgZW52aXJvbm1lbnRzLiAnICtcbiAgICAgICAgJ1NlcnZpY2UgY3JlZGVudGlhbHMgaW4gYnJvd3NlciBidW5kbGVzIGFyZSBwdWJsaWNseSB2aXNpYmxlLiAnICtcbiAgICAgICAgJ1VzZSBgYWNjZXNzVG9rZW5gIHdpdGggYSB0b2tlbiBvYnRhaW5lZCB2aWEgT0F1dGggKG9yIGB3aXRoVG9rZW4oLi4uKWAgb24gYSBzZXJ2ZXItYnVpbHQgY2xpZW50KSBpbnN0ZWFkLicsXG4gICAgKTtcbiAgfVxufVxuXG4vLyDilIDilIDilIAgRGVmYXVsdCBzaW5nbGV0b24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vL1xuLy8gUmVzb2x2ZWQgbGF6aWx5IG9uIGZpcnN0IHByb3BlcnR5IGFjY2VzcyAoUHJveHkpIHNvIGNvbnN1bWVycyB0aGF0XG4vLyBtdXRhdGUgYHByb2Nlc3MuZW52YCBhZnRlciBpbXBvcnQgc3RpbGwgcGljayB1cCB0aGUgcmlnaHQgdmFsdWVzLlxuXG5sZXQgY2FjaGVkU2luZ2xldG9uOiBQbGF0Zm9ybUNsaWVudCB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIHNpbmdsZXRvbigpOiBQbGF0Zm9ybUNsaWVudCB7XG4gIGlmICghY2FjaGVkU2luZ2xldG9uKSBjYWNoZWRTaW5nbGV0b24gPSBidWlsZENsaWVudChlbnZDbGllbnRDb25maWcoKSk7XG4gIHJldHVybiBjYWNoZWRTaW5nbGV0b247XG59XG5cbmZ1bmN0aW9uIGVudkNsaWVudENvbmZpZygpOiBDbGllbnRDb25maWcge1xuICBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnKSByZXR1cm4ge307XG4gIGNvbnN0IGUgPSAocHJvY2VzcyBhcyB7IGVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfSkuZW52ID8/IHt9O1xuICByZXR1cm4ge1xuICAgIGJhc2VVcmw6IGUuVUVOR0FHRV9CQVNFX1VSTCxcbiAgICBhdXRoQmFzZVVybDogZS5VRU5HQUdFX0FVVEhfQkFTRV9VUkwsXG4gICAgYWNjZXNzVG9rZW46IGUuVUVOR0FHRV9BVVRIX1RPS0VOLFxuICAgIHNlcnZpY2VJZDogZS5VRU5HQUdFX1NFUlZJQ0VfSUQsXG4gICAgc2VydmljZVNlY3JldDogZS5VRU5HQUdFX1NFUlZJQ0VfU0VDUkVULFxuICAgIHNjb3BlOiBlLlVFTkdBR0VfU0VSVklDRV9TQ09QRSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IGNsaWVudC4gUmVhZHMgY29uZmlnIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzIG9uIGZpcnN0XG4gKiBwcm9wZXJ0eSBhY2Nlc3MgKHNvIHRlc3Qgc2V0dXBzIHRoYXQgbXV0YXRlIGBwcm9jZXNzLmVudmAgYWZ0ZXJcbiAqIGltcG9ydCB3b3JrKS4gVXNlIGBjcmVhdGVDbGllbnQoLi4uKWAgd2hlbiB5b3UgbmVlZCBhbiBpc29sYXRlZFxuICogaW5zdGFuY2Ugd2l0aCBleHBsaWNpdCBjb25maWcuXG4gKlxuICogICBVRU5HQUdFX0JBU0VfVVJMICAgICAgICAgZGVmYXVsdHMgdG8gaHR0cHM6Ly9hcGkucGxhdGZvcm0udWVuZ2FnZS5pb1xuICogICBVRU5HQUdFX0FVVEhfQkFTRV9VUkwgICAgYXV0aCBzdXJmYWNlIG92ZXJyaWRlIChkZWZhdWx0ICR7YmFzZVVybH0vYXV0aC9idXNpbmVzcylcbiAqICAgVUVOR0FHRV9BVVRIX1RPS0VOICAgICAgIHN0YXRpYyBCZWFyZXIgdG9rZW4gKG92ZXJyaWRlcyBjbGllbnRfY3JlZGVudGlhbHMpXG4gKiAgIFVFTkdBR0VfU0VSVklDRV9JRCAgICAgICBPQXV0aDIgY2xpZW50X2NyZWRlbnRpYWxzIGNsaWVudElkXG4gKiAgIFVFTkdBR0VfU0VSVklDRV9TRUNSRVQgICBPQXV0aDIgY2xpZW50X2NyZWRlbnRpYWxzIGNsaWVudFNlY3JldFxuICogICBVRU5HQUdFX1NFUlZJQ0VfU0NPUEUgICAgb3B0aW9uYWwgc3BhY2Utc2VwYXJhdGVkIHNjb3BlIGxpc3RcbiAqL1xuZXhwb3J0IGNvbnN0IHBsYXRmb3JtOiBQbGF0Zm9ybUNsaWVudCA9IG5ldyBQcm94eSh7fSBhcyBQbGF0Zm9ybUNsaWVudCwge1xuICBnZXQoXywgcHJvcCkge1xuICAgIGNvbnN0IHMgPSBzaW5nbGV0b24oKSBhcyB1bmtub3duIGFzIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj47XG4gICAgcmV0dXJuIHNbcHJvcF07XG4gIH0sXG59KTtcblxuLyoqIFRlc3Qtb25seTogZHJvcCB0aGUgc2luZ2xldG9uIGNhY2hlIGJldHdlZW4gY2FzZXMuICovXG5leHBvcnQgZnVuY3Rpb24gX3Jlc2V0UGxhdGZvcm1TaW5nbGV0b24oKTogdm9pZCB7XG4gIGNhY2hlZFNpbmdsZXRvbiA9IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBDb252ZW5pZW5jZTogc2hvcnRoYW5kIGZvciBgcGxhdGZvcm0ud2l0aFRva2VuKHRva2VuKWAuXG4gKiBCRkYgaGFuZGxlcnMgY29tbW9ubHkgY2FsbCB0aGlzIG9uY2UgcGVyIHJlcXVlc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoVG9rZW4odG9rZW46IHN0cmluZyB8ICgoKSA9PiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4pKTogUGxhdGZvcm1DbGllbnQge1xuICByZXR1cm4gc2luZ2xldG9uKCkud2l0aFRva2VuKHRva2VuKTtcbn1cbiJdfQ==
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWtGQSxvQ0FJQztBQXRGRCwyQ0FBcUU7QUFDckUsOENBQThFO0FBQzlFLGlDQUErQztBQUMvQyxpREFBNkU7QUFDN0UscUNBQTREO0FBc0U1RCxNQUFNLGdCQUFnQixHQUFHLGlDQUFpQyxDQUFDO0FBRTNEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsWUFBWSxDQUFDLFFBQXNCLEVBQUU7SUFDbkQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzVCLE9BQU8sV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFtQjtJQUN0QyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLGdCQUFnQixDQUFDO0lBQ2xELE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVELE1BQU0sSUFBSSxHQUE2QixnQkFBZ0I7UUFDckQsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUU7UUFDbkQsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUVkLE1BQU0sY0FBYyxHQUFHLElBQUEsNkJBQW9CLEVBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN2RixNQUFNLFdBQVcsR0FBRyxJQUFBLDBCQUFpQixFQUFDO1FBQ3BDLE9BQU87UUFDUCxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsSUFBSTtRQUNKLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQyxTQUFTO0tBQzVDLENBQUMs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LEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUNqRSxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUFDLE1BQW9CO0lBQy9DLE1BQU0sQ0FBQyxHQUFHLFVBQWlELENBQUM7SUFDNUQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFdBQVcsQ0FBQztJQUM5RixJQUFJLENBQUMsU0FBUztRQUFFLE9BQU87SUFDdkIsSUFBSSxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekIsT0FBTyxDQUFDLElBQUksQ0FDVixtRkFBbUY7WUFDakYsK0RBQStEO1lBQy9ELDBFQUEwRSxDQUM3RSxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVBdWRpdENsaWVudCwgdHlwZSBBdWRpdENsaWVudCB9IGZyb20gJy4vYXVkaXQvY2xpZW50JztcbmltcG9ydCB7IGNyZWF0ZUJ1c2luZXNzQ2xpZW50LCB0eXBlIEJ1c2luZXNzQ2xpZW50IH0gZnJvbSAnLi9idXNpbmVzcy9jbGllbnQnO1xuaW1wb3J0IHsgYXV0aCBhcyBhdXRoTmFtZXNwYWNlIH0gZnJvbSAnLi9hdXRoJztcbmltcG9ydCB7IG1ha2VUb2tlblNvdXJjZVN0YXRlLCB0eXBlIFRva2VuU291cmNlU3RhdGUgfSBmcm9tICcuL3Rva2VuLXNvdXJjZSc7XG5pbXBvcnQgeyBDb25maWdFcnJvciwgQXV0aGVudGljYXRpb25FcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB0eXBlIHsgUGxhdGZvcm1BdXRoIH0gZnJvbSAnLi9jb25maWcnO1xuXG4vKipcbiAqIENhbGxlci1mYWNpbmcgY29uZmlnIGZvciBgY3JlYXRlQ2xpZW50KC4uLilgLlxuICpcbiAqIGBjcmVhdGVDbGllbnQoKWAgKG5vIGFyZ3MpIHJlYWRzIGV2ZXJ5dGhpbmcgZnJvbSB0aGUgc3RhbmRhcmRcbiAqIGBVRU5HQUdFXypgIGVudmlyb25tZW50IHZhcmlhYmxlcyDigJQgY29udmVuaWVudCBmb3IgTGFtYmRhcyB0aGF0XG4gKiBhbHJlYWR5IGhhdmUgdGhlaXIgY29uZmlnIGluamVjdGVkIGJ5IHRoZSBkZXBsb3kgc3RhY2suIEFueSBmaWVsZFxuICogcGFzc2VkIGV4cGxpY2l0bHkgb3ZlcnJpZGVzIHRoZSBtYXRjaGluZyBlbnYgZGVmYXVsdCBmb3IgdGhhdCBvbmVcbiAqIGNhbGwgb25seSAobm8gc2hhcmVkIG11dGFibGUgc3RhdGUsIG5vIHNpbmdsZXRvbikuXG4gKlxuICogQXV0aC1tb2RlIGZpZWxkcyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiBQaWNrIG9uZTpcbiAqICAgLSBgc2VydmljZUlkYCArIGBzZXJ2aWNlU2VjcmV0YCAgT0F1dGgyIGNsaWVudF9jcmVkZW50aWFscy5cbiAqICAgLSBgYXV0aFRva2VuYCAgICAgICAgICAgICAgICAgICAgc3RhdGljIEJlYXJlciB0b2tlbiwgb3IgYXN5bmNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgdGhhdCByZXR1cm5zIG9uZS5cbiAqICAgLSBgc2Vzc2lvblRva2VuYCAgICAgICAgICAgICAgICAgbGVnYWN5IGN1c3RvbWVyIHNlc3Npb24gdG9rZW47IHRoZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTREsgZXhjaGFuZ2VzIGl0IHZpYSB0aGUgY3VzdG9tZXJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0aCBzdXJmYWNlIGFuZCBjYWNoZXMgdGhlIEpXVC5cbiAqXG4gKiBQYXNzaW5nIG1vcmUgdGhhbiBvbmUgZXhwbGljaXRseSBpcyBhIGBDb25maWdFcnJvcmAuIFBhc3NpbmcgYW55IG9uZVxuICogb2YgdGhlbSBzdXBwcmVzc2VzIGV2ZXJ5IGVudi1kZXJpdmVkIGF1dGggZGVmYXVsdCwgc28gYSBjYWxsZXInc1xuICogZXhwbGljaXQgb3ZlcnJpZGUgaXMgbmV2ZXIgc2lsZW50bHkgbWVyZ2VkIHdpdGggZW52IGNyZWRlbnRpYWxzIG9mXG4gKiBhIGRpZmZlcmVudCBtb2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsaWVudENvbmZpZyB7XG4gIGJhc2VVcmw/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBdXRoIHN1cmZhY2UgYmFzZSB1c2VkIHRvIGJvb3RzdHJhcCB0aGUgZmlyc3QgY2xpZW50X2NyZWRlbnRpYWxzXG4gICAqIG1pbnQuIERlZmF1bHRzIHRvIGAke2Jhc2VVcmx9L2F1dGgvYnVzaW5lc3NgLlxuICAgKi9cbiAgYXV0aEJhc2VVcmw/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBDdXN0b21lciBhdXRoIHN1cmZhY2UgYmFzZSB1c2VkIGJ5IGBzZXNzaW9uVG9rZW5gIGV4Y2hhbmdlcy5cbiAgICogRGVmYXVsdHMgdG8gYCR7YmFzZVVybH0vYXV0aC9jdXN0b21lcmAuXG4gICAqL1xuICBjdXN0b21lckF1dGhCYXNlVXJsPzogc3RyaW5nO1xuXG4gIC8vIOKUgOKUgOKUgCBBdXRoIG1vZGVzIChtdXR1YWxseSBleGNsdXNpdmUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKiogT0F1dGgyIGBjbGllbnRfY3JlZGVudGlhbHNgIGNsaWVudElkLiBQYWlyIHdpdGggYHNlcnZpY2VTZWNyZXRgLiAqL1xuICBzZXJ2aWNlSWQ/OiBzdHJpbmc7XG4gIC8qKiBPQXV0aDIgYGNsaWVudF9jcmVkZW50aWFsc2AgY2xpZW50U2VjcmV0LiBQYWlyIHdpdGggYHNlcnZpY2VJZGAuICovXG4gIHNlcnZpY2VTZWNyZXQ/OiBzdHJpbmc7XG4gIC8qKiBTcGFjZS1zZXBhcmF0ZWQgc2NvcGUgbGlzdCB0byByZXF1ZXN0IHdoZW4gbWludGluZyB2aWEgY2xpZW50X2NyZWRlbnRpYWxzLiAqL1xuICBzY29wZT86IHN0cmluZztcbiAgLyoqIFN0YXRpYyBCZWFyZXIgSldULCBvciBhc3luYyBjYWxsYmFjayB0aGF0IHJldHVybnMgb25lLiAqL1xuICBhdXRoVG9rZW4/OiBzdHJpbmcgfCAoKCkgPT4gc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+KTtcbiAgLyoqXG4gICAqIExlZ2FjeSB1RW5nYWdlIHNlc3Npb24gdG9rZW4gKGZyb20gYGFkZG9fY29udGFjdHNfbWFwcGluZy50b2tlbmApLlxuICAgKiBUaGUgU0RLIFBPU1RzIGl0IHRvIGBjdXN0b21lckF1dGhCYXNlVXJsYCB0byBtaW50IGEgSldULCBjYWNoZXMgdGhlXG4gICAqIHJlc3VsdCwgYW5kIHJlLWV4Y2hhbmdlcyBvbiA0MDEgLyBjYWNoZSBtaXNzLlxuICAgKi9cbiAgc2Vzc2lvblRva2VuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZXJ2aWNlIGlkZW50aWZpZXIgdGhlIGF1ZGl0IGNsaWVudCBzaG91bGQgc3RhbXAgaW50byBgYWN0b3IudmlhYFxuICAgKiBvbiBlbWl0dGVkIGV2ZW50cy4gRGVmYXVsdHMgdG8gYHNlcnZpY2VJZGAgd2hlbiBzZXQ7IG90aGVyd2lzZVxuICAgKiBhdWRpdCBgcmVjb3JkKClgIGNhbGxzIGxvZyBhbiBlcnJvciBhbmQgZHJvcCB0aGUgZXZlbnQuXG4gICAqL1xuICBhY3RvclZpYT86IHN0cmluZztcbiAgZXhwaXJ5QnVmZmVyTXM/OiBudW1iZXI7XG4gIGZldGNoRm4/OiB0eXBlb2YgZmV0Y2g7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGxhdGZvcm1DbGllbnQge1xuICBidXNpbmVzczogQnVzaW5lc3NDbGllbnQ7XG4gIGF1ZGl0OiBBdWRpdENsaWVudDtcbiAgYXV0aDogdHlwZW9mIGF1dGhOYW1lc3BhY2U7XG59XG5cbmNvbnN0IERFRkFVTFRfQkFTRV9VUkwgPSAnaHR0cHM6Ly9hcGkucGxhdGZvcm0udWVuZ2FnZS5pbyc7XG5cbi8qKlxuICogQnVpbGQgYSBmcmVzaCwgaXNvbGF0ZWQgY2xpZW50LiBXaXRoIG5vIGFyZ3MsIHJlYWRzIGBVRU5HQUdFXypgXG4gKiBlbnYgdmFyczsgZXhwbGljaXQgZmllbGRzIG92ZXJyaWRlIHBlciBjYWxsLiBFYWNoIGNhbGwgZ2V0cyBpdHMgb3duXG4gKiBUb2tlblNvdXJjZSBzdGF0ZSDigJQgY29uY3VycmVudCBgY3JlYXRlQ2xpZW50KC4uLilgIHVzZSBkb2VzIG5vdFxuICogc3RhbXBlZGUgdGhlIGNhY2hlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KGlucHV0OiBDbGllbnRDb25maWcgPSB7fSk6IFBsYXRmb3JtQ2xpZW50IHtcbiAgY29uc3QgbWVyZ2VkID0gbWVyZ2VXaXRoRW52KGlucHV0KTtcbiAgd2FybklmQnJvd3NlclNlY3JldChtZXJnZWQpO1xuICByZXR1cm4gYnVpbGRDbGllbnQobWVyZ2VkKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRDbGllbnQoaW5wdXQ6IENsaWVudENvbmZpZyk6IFBsYXRmb3JtQ2xpZW50IHtcbiAgY29uc3QgYmFzZVVybCA9IGlucHV0LmJhc2VVcmwgPz8gREVGQVVMVF9CQVNFX1VSTDtcbiAgY29uc3QgdG9rZW5Tb3VyY2VTdGF0ZSA9IHJlc29sdmVUb2tlblNvdXJjZShpbnB1dCwgYmFzZVVybCk7XG4gIGNvbnN0IGF1dGg6IFBsYXRmb3JtQXV0aCB8IHVuZGVmaW5lZCA9IHRva2VuU291cmNlU3RhdGVcbiAgICA/IHsgdHlwZTogJ3Rva2VuLXNvdXJjZScsIHN0YXRlOiB0b2tlblNvdXJjZVN0YXRlIH1cbiAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBidXNpbmVzc0NsaWVudCA9IGNyZWF0ZUJ1c2luZXNzQ2xpZW50KHsgYmFzZVVybCwgZmV0Y2hGbjogaW5wdXQuZmV0Y2hGbiwgYXV0aCB9KTtcbiAgY29uc3QgYXVkaXRDbGllbnQgPSBjcmVhdGVBdWRpdENsaWVudCh7XG4gICAgYmFzZVVybCxcbiAgICBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuLFxuICAgIGF1dGgsXG4gICAgYWN0b3JWaWE6IGlucHV0LmFjdG9yVmlhID8/IGlucHV0LnNlcnZpY2VJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBidXNpbmVzczogYnVzaW5lc3NDbGllbnQsXG4gICAgYXVkaXQ6IGF1ZGl0Q2xpZW50LFxuICAgIGF1dGg6IGF1dGhOYW1lc3BhY2UsXG4gIH07XG59XG5cbmNvbnN0IEFVVEhfTU9ERV9GSUVMRFMgPSBbXG4gICdzZXJ2aWNlSWQnLFxuICAnc2VydmljZVNlY3JldCcsXG4gICdzY29wZScsXG4gICdhdXRoVG9rZW4nLFxuICAnc2Vzc2lvblRva2VuJyxcbl0gYXMgY29uc3Q7XG5cbi8qKlxuICogTWVyZ2UgZW52LWRlcml2ZWQgZGVmYXVsdHMgd2l0aCB0aGUgY2FsbGVyJ3MgZXhwbGljaXQgaW5wdXQuIEFueVxuICogZXhwbGljaXQgYXV0aC1tb2RlIGZpZWxkIHN1cHByZXNzZXMgKmFsbCogZW52LWRlcml2ZWQgYXV0aCBkZWZhdWx0cyxcbiAqIHNvIGFuIGV4cGxpY2l0IGB7YXV0aFRva2VufWAgb3ZlcnJpZGUgZG9lc24ndCBhY2NpZGVudGFsbHkgaW5oZXJpdFxuICogYHNlcnZpY2VJZGAvYHNlcnZpY2VTZWNyZXRgIGZyb20gZW52LiBOb24tYXV0aCBmaWVsZHMgZmFsbCB0aHJvdWdoXG4gKiBub3JtYWxseSAoY2FsbGVyIGBiYXNlVXJsYCBvdmVycmlkZXMgZW52IGJhc2VVcmw7IGFic2VudCBpbnB1dCBrZWVwc1xuICogZW52IGJhc2VVcmwpLlxuICovXG5mdW5jdGlvbiBtZXJnZVdpdGhFbnYoaW5wdXQ6IENsaWVudENvbmZpZyk6IENsaWVudENvbmZpZyB7XG4gIGNvbnN0IGVudiA9IHJlYWRFbnZEZWZhdWx0cygpO1xuICBjb25zdCBpbnB1dEhhc0F1dGggPSBpbnB1dEhhc0F1dGhNb2RlKGlucHV0KTtcbiAgY29uc3QgZW52Rm9yTWVyZ2UgPSBpbnB1dEhhc0F1dGggPyB3aXRob3V0QXV0aEZpZWxkcyhlbnYpIDogZW52O1xuXG4gIGNvbnN0IG1lcmdlZDogQ2xpZW50Q29uZmlnID0ge1xuICAgIGJhc2VVcmw6IGlucHV0LmJhc2VVcmwgPz8gZW52Rm9yTWVyZ2UuYmFzZVVybCxcbiAgICBhdXRoQmFzZVVybDogaW5wdXQuYXV0aEJhc2VVcmwgPz8gZW52Rm9yTWVyZ2UuYXV0aEJhc2VVcmwsXG4gICAgY3VzdG9tZXJBdXRoQmFzZVVybDogaW5wdXQuY3VzdG9tZXJBdXRoQmFzZVVybCA/PyBlbnZGb3JNZXJnZS5jdXN0b21lckF1dGhCYXNlVXJsLFxuICAgIHNlcnZpY2VJZDogaW5wdXQuc2VydmljZUlkID8/IGVudkZvck1lcmdlLnNlcnZpY2VJZCxcbiAgICBzZXJ2aWNlU2VjcmV0OiBpbnB1dC5zZXJ2aWNlU2VjcmV0ID8/IGVudkZvck1lcmdlLnNlcnZpY2VTZWNyZXQsXG4gICAgc2NvcGU6IGlucHV0LnNjb3BlID8/IGVudkZvck1lcmdlLnNjb3BlLFxuICAgIGF1dGhUb2tlbjogaW5wdXQuYXV0aFRva2VuID8/IGVudkZvck1lcmdlLmF1dGhUb2tlbixcbiAgICBzZXNzaW9uVG9rZW46IGlucHV0LnNlc3Npb25Ub2tlbiA/PyBlbnZGb3JNZXJnZS5zZXNzaW9uVG9rZW4sXG4gICAgYWN0b3JWaWE6IGlucHV0LmFjdG9yVmlhID8/IGVudkZvck1lcmdlLmFjdG9yVmlhLFxuICAgIGV4cGlyeUJ1ZmZlck1zOiBpbnB1dC5leHBpcnlCdWZmZXJNcyA/PyBlbnZGb3JNZXJnZS5leHBpcnlCdWZmZXJNcyxcbiAgICBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuLFxuICB9O1xuICBhc3NlcnRFeGFjdGx5T25lQXV0aE1vZGUobWVyZ2VkKTtcbiAgcmV0dXJuIG1lcmdlZDtcbn1cblxuZnVuY3Rpb24gcmVhZEVudkRlZmF1bHRzKCk6IENsaWVudENvbmZpZyB7XG4gIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB7fTtcbiAgY29uc3QgZSA9IChwcm9jZXNzIGFzIHsgZW52PzogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB9KS5lbnYgPz8ge307XG4gIGNvbnN0IGV4cGlyeSA9IGUuVUVOR0FHRV9FWFBJUllfQlVGRkVSX01TID8gTnVtYmVyKGUuVUVOR0FHRV9FWFBJUllfQlVGRkVSX01TKSA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHtcbiAgICBiYXNlVXJsOiBlLlVFTkdBR0VfQkFTRV9VUkwsXG4gICAgYXV0aEJhc2VVcmw6IGUuVUVOR0FHRV9BVVRIX0JBU0VfVVJMLFxuICAgIGN1c3RvbWVyQXV0aEJhc2VVcmw6IGUuVUVOR0FHRV9DVVNUT01FUl9BVVRIX0JBU0VfVVJMLFxuICAgIHNlcnZpY2VJZDogZS5VRU5HQUdFX1NFUlZJQ0VfSUQsXG4gICAgc2VydmljZVNlY3JldDogZS5VRU5HQUdFX1NFUlZJQ0VfU0VDUkVULFxuICAgIHNjb3BlOiBlLlVFTkdBR0VfU0NPUEUsXG4gICAgYXV0aFRva2VuOiBlLlVFTkdBR0VfQVVUSF9UT0tFTixcbiAgICBzZXNzaW9uVG9rZW46IGUuVUVOR0FHRV9TRVNTSU9OX1RPS0VOLFxuICAgIGFjdG9yVmlhOiBlLlVFTkdBR0VfQUNUT1JfVklBLFxuICAgIGV4cGlyeUJ1ZmZlck1zOiBOdW1iZXIuaXNGaW5pdGUoZXhwaXJ5KSA/IChleHBpcnkgYXMgbnVtYmVyKSA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gaW5wdXRIYXNBdXRoTW9kZShpbnB1dDogQ2xpZW50Q29uZmlnKTogYm9vbGVhbiB7XG4gIHJldHVybiBBVVRIX01PREVfRklFTERTLnNvbWUoKGYpID0+IGlucHV0W2ZdICE9PSB1bmRlZmluZWQpO1xufVxuXG5mdW5jdGlvbiB3aXRob3V0QXV0aEZpZWxkcyhjOiBDbGllbnRDb25maWcpOiBDbGllbnRDb25maWcge1xuICByZXR1cm4ge1xuICAgIC4uLmMsXG4gICAgc2VydmljZUlkOiB1bmRlZmluZWQsXG4gICAgc2VydmljZVNlY3JldDogdW5kZWZpbmVkLFxuICAgIHNjb3BlOiB1bmRlZmluZWQsXG4gICAgYXV0aFRva2VuOiB1bmRlZmluZWQsXG4gICAgc2Vzc2lvblRva2VuOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGFzc2VydEV4YWN0bHlPbmVBdXRoTW9kZShpbnB1dDogQ2xpZW50Q29uZmlnKTogdm9pZCB7XG4gIGNvbnN0IG1vZGVzOiBzdHJpbmdbXSA9IFtdO1xuICBpZiAoaW5wdXQuYXV0aFRva2VuICE9PSB1bmRlZmluZWQpIG1vZGVzLnB1c2goJ2F1dGhUb2tlbicpO1xuICBpZiAoaW5wdXQuc2Vzc2lvblRva2VuICE9PSB1bmRlZmluZWQpIG1vZGVzLnB1c2goJ3Nlc3Npb25Ub2tlbicpO1xuICBpZiAoaW5wdXQuc2VydmljZUlkICE9PSB1bmRlZmluZWQgfHwgaW5wdXQuc2VydmljZVNlY3JldCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbW9kZXMucHVzaCgnc2VydmljZUlkK3NlcnZpY2VTZWNyZXQnKTtcbiAgfVxuICBpZiAobW9kZXMubGVuZ3RoID4gMSkge1xuICAgIHRocm93IG5ldyBDb25maWdFcnJvcihcbiAgICAgIGBjcmVhdGVDbGllbnQ6IHBpY2sgZXhhY3RseSBvbmUgYXV0aCBtb2RlLiBHb3QgJHttb2Rlcy5qb2luKCcsICcpfS4gYCArXG4gICAgICAgICdVc2Ugb25lIG9mIHtzZXJ2aWNlSWQsIHNlcnZpY2VTZWNyZXR9IHwge2F1dGhUb2tlbn0gfCB7c2Vzc2lvblRva2VufS4nLFxuICAgICk7XG4gIH1cbiAgLy8gWmVybyBtb2RlcyBpcyBhbGxvd2VkIOKAlCBjYWxsZXIgbWF5IHdhbnQgYSBmdWxseS1hbm9ueW1vdXMgY2xpZW50IGZvclxuICAvLyBwdWJsaWMgZW5kcG9pbnRzLiBUaGUgZmlyc3QgcmVxdWVzdCB0aGF0IG5lZWRzIGF1dGggd2lsbCBzdXJmYWNlIGFcbiAgLy8gQ29uZmlnRXJyb3IgZG93bnN0cmVhbS5cbn1cblxuLyoqXG4gKiBQT1NUIHRvIHRoZSBjdXN0b21lciBhdXRoIHN1cmZhY2UgdG8gZXhjaGFuZ2UgYSBsZWdhY3kgc2Vzc2lvblxuICogdG9rZW4gZm9yIGEgZnJlc2ggYWNjZXNzIHRva2VuLiBVc2VkIGJ5IGBjcmVhdGVDbGllbnQoeyBzZXNzaW9uVG9rZW4gfSlgLlxuICovXG5hc3luYyBmdW5jdGlvbiBleGNoYW5nZVNlc3Npb25Ub2tlbihcbiAgc2Vzc2lvblRva2VuOiBzdHJpbmcsXG4gIGN1c3RvbWVyQXV0aEJhc2VVcmw6IHN0cmluZyxcbiAgZmV0Y2hGbjogdHlwZW9mIGZldGNoLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hGbihgJHtjdXN0b21lckF1dGhCYXNlVXJsfS9vYXV0aC90b2tlbmAsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LFxuICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgICAgZ3JhbnRfdHlwZTogJ3Nlc3Npb25fdG9rZW4nLFxuICAgICAgc2Vzc2lvbl90b2tlbjogc2Vzc2lvblRva2VuLFxuICAgIH0pLnRvU3RyaW5nKCksXG4gIH0pO1xuICBpZiAoIXJlcy5vaykge1xuICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpLmNhdGNoKCgpID0+ICcnKTtcbiAgICB0aHJvdyBuZXcgQXV0aGVudGljYXRpb25FcnJvcihgc2Vzc2lvbi10b2tlbiBleGNoYW5nZSBmYWlsZWQ6IEhUVFAgJHtyZXMuc3RhdHVzfSAke3RleHR9YCk7XG4gIH1cbiAgY29uc3QganNvbiA9IChhd2FpdCByZXMuanNvbigpKSBhcyB7IGFjY2Vzc190b2tlbj86IHN0cmluZyB9O1xuICBpZiAoIWpzb24uYWNjZXNzX3Rva2VuKSB7XG4gICAgdGhyb3cgbmV3IENvbmZpZ0Vycm9yKCdzZXNzaW9uLXRva2VuIGV4Y2hhbmdlIHJlc3BvbnNlIG1pc3NpbmcgYWNjZXNzX3Rva2VuJyk7XG4gIH1cbiAgcmV0dXJuIGpzb24uYWNjZXNzX3Rva2VuO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlVG9rZW5Tb3VyY2UoaW5wdXQ6IENsaWVudENvbmZpZywgYmFzZVVybDogc3RyaW5nKTogVG9rZW5Tb3VyY2VTdGF0ZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGF1dGhCYXNlVXJsID0gaW5wdXQuYXV0aEJhc2VVcmwgPz8gYCR7YmFzZVVybH0vYXV0aC9idXNpbmVzc2A7XG4gIGNvbnN0IGZldGNoRm4gPSBpbnB1dC5mZXRjaEZuID8/IChnbG9iYWxUaGlzLmZldGNoIGFzIHR5cGVvZiBmZXRjaCk7XG5cbiAgaWYgKGlucHV0LmF1dGhUb2tlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBpbnB1dC5hdXRoVG9rZW4gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbWFrZVRva2VuU291cmNlU3RhdGUoXG4gICAgICAgIHsga2luZDogJ3N0YXRpYy1zdHJpbmcnLCB0b2tlbjogaW5wdXQuYXV0aFRva2VuIH0sXG4gICAgICAgIHsgZXhwaXJ5QnVmZmVyTXM6IGlucHV0LmV4cGlyeUJ1ZmZlck1zLCBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuIH0sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbWFrZVRva2VuU291cmNlU3RhdGUoXG4gICAgICB7IGtpbmQ6ICdjYWxsYmFjaycsIGdldFRva2VuOiBpbnB1dC5hdXRoVG9rZW4gfSxcbiAgICAgIHsgZXhwaXJ5QnVmZmVyTXM6IGlucHV0LmV4cGlyeUJ1ZmZlck1zLCBmZXRjaEZuOiBpbnB1dC5mZXRjaEZuIH0sXG4gICAgKTtcbiAgfVxuICBpZiAoaW5wdXQuc2Vzc2lvblRva2VuICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBjdXN0b21lckF1dGhCYXNlVXJsID0gaW5wdXQuY3VzdG9tZXJBdXRoQmFzZVVybCA/PyBgJHtiYXNlVXJsfS9hdXRoL2N1c3RvbWVyYDtcbiAgICBjb25zdCBzZXNzaW9uVG9rZW4gPSBpbnB1dC5zZXNzaW9uVG9rZW47XG4gICAgcmV0dXJuIG1ha2VUb2tlblNvdXJjZVN0YXRlKFxuICAgICAge1xuICAgICAgICBraW5kOiAnY2FsbGJhY2snLFxuICAgICAgICBnZXRUb2tlbjogKCkgPT4gZXhjaGFuZ2VTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuLCBjdXN0b21lckF1dGhCYXNlVXJsLCBmZXRjaEZuKSxcbiAgICAgIH0sXG4gICAgICB7IGV4cGlyeUJ1ZmZlck1zOiBpbnB1dC5leHBpcnlCdWZmZXJNcywgZmV0Y2hGbjogaW5wdXQuZmV0Y2hGbiB9LFxuICAgICk7XG4gIH1cbiAgaWYgKGlucHV0LnNlcnZpY2VJZCAmJiBpbnB1dC5zZXJ2aWNlU2VjcmV0KSB7XG4gICAgcmV0dXJuIG1ha2VUb2tlblNvdXJjZVN0YXRlKFxuICAgICAge1xuICAgICAgICBraW5kOiAnc2VydmljZS1jcmVkZW50aWFscycsXG4gICAgICAgIGNsaWVudElkOiBpbnB1dC5zZXJ2aWNlSWQsXG4gICAgICAgIGNsaWVudFNlY3JldDogaW5wdXQuc2VydmljZVNlY3JldCxcbiAgICAgICAgYXV0aEJhc2VVcmwsXG4gICAgICAgIHNjb3BlOiBpbnB1dC5zY29wZSxcbiAgICAgIH0sXG4gICAgICB7IGV4cGlyeUJ1ZmZlck1zOiBpbnB1dC5leHBpcnlCdWZmZXJNcywgZmV0Y2hGbjogaW5wdXQuZmV0Y2hGbiB9LFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gd2FybklmQnJvd3NlclNlY3JldChjb25maWc6IENsaWVudENvbmZpZyk6IHZvaWQge1xuICBjb25zdCBnID0gZ2xvYmFsVGhpcyBhcyB7IHdpbmRvdz86IHsgZG9jdW1lbnQ/OiB1bmtub3duIH0gfTtcbiAgY29uc3QgaW5Ccm93c2VyID0gdHlwZW9mIGcud2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZy53aW5kb3cuZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnO1xuICBpZiAoIWluQnJvd3NlcikgcmV0dXJuO1xuICBpZiAoY29uZmlnLnNlcnZpY2VTZWNyZXQpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICAnW3VlbmdhZ2UtcGxhdGZvcm0tc2RrXSBzZXJ2aWNlU2VjcmV0IHNob3VsZCBub3QgYmUgdXNlZCBpbiBicm93c2VyIGVudmlyb25tZW50cy4gJyArXG4gICAgICAgICdTZXJ2aWNlIGNyZWRlbnRpYWxzIGluIGJyb3dzZXIgYnVuZGxlcyBhcmUgcHVibGljbHkgdmlzaWJsZS4gJyArXG4gICAgICAgICdVc2UgYGF1dGhUb2tlbmAgKGEgQmVhcmVyIG9idGFpbmVkIHZpYSBPQXV0aCkgb3IgYHNlc3Npb25Ub2tlbmAgaW5zdGVhZC4nLFxuICAgICk7XG4gIH1cbn1cbiJdfQ==
package/dist/index.d.ts CHANGED
@@ -4,21 +4,4 @@ export * from './errors';
4
4
  export { auth } from './auth';
5
5
  export type { PkcePair, AuthorizeUrlInput, ExchangeCodeInput, RefreshInput, TokenPair, } from './auth';
6
6
  export { type PlatformAuth, type PlatformAuthInput, type PlatformConfig, type PlatformConfigInput, DEFAULT_BASE_URL, } from './config';
7
- export { createClient, platform, withToken, type ClientConfig, type PlatformClient, } from './client';
8
- /**
9
- * Default singleton clients. Both read defaults from the environment on
10
- * every call:
11
- * - UENGAGE_BASE_URL defaults to https://api.platform.uengage.io
12
- * - UENGAGE_AUTH_TOKEN static Bearer token
13
- * - UENGAGE_SERVICE_ID OAuth2 client_credentials clientId
14
- * - UENGAGE_SERVICE_SECRET OAuth2 client_credentials clientSecret
15
- * - UENGAGE_SERVICE_SCOPE optional space-separated scope list
16
- *
17
- * The chainable `.config({...})` / `.auth({...})` API on the audit and
18
- * business clients is preserved for back-compat. `.auth({token})`
19
- * accepts a static Bearer token; for OAuth2 client_credentials use the
20
- * unified `createClient(...)` factory instead — that builds a
21
- * TokenSource which handles caching + refresh dedup + 401 retry.
22
- */
23
- export declare const audit: import("./audit").AuditClient;
24
- export declare const business: import("./business").BusinessClient;
7
+ export { createClient, type ClientConfig, type PlatformClient } from './client';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.business = exports.audit = exports.withToken = exports.platform = exports.createClient = exports.DEFAULT_BASE_URL = exports.auth = void 0;
17
+ exports.createClient = exports.DEFAULT_BASE_URL = exports.auth = void 0;
18
18
  __exportStar(require("./audit"), exports);
19
19
  __exportStar(require("./business"), exports);
20
20
  __exportStar(require("./errors"), exports);
@@ -24,25 +24,4 @@ var config_1 = require("./config");
24
24
  Object.defineProperty(exports, "DEFAULT_BASE_URL", { enumerable: true, get: function () { return config_1.DEFAULT_BASE_URL; } });
25
25
  var client_1 = require("./client");
26
26
  Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return client_1.createClient; } });
27
- Object.defineProperty(exports, "platform", { enumerable: true, get: function () { return client_1.platform; } });
28
- Object.defineProperty(exports, "withToken", { enumerable: true, get: function () { return client_1.withToken; } });
29
- const audit_1 = require("./audit");
30
- const business_1 = require("./business");
31
- /**
32
- * Default singleton clients. Both read defaults from the environment on
33
- * every call:
34
- * - UENGAGE_BASE_URL defaults to https://api.platform.uengage.io
35
- * - UENGAGE_AUTH_TOKEN static Bearer token
36
- * - UENGAGE_SERVICE_ID OAuth2 client_credentials clientId
37
- * - UENGAGE_SERVICE_SECRET OAuth2 client_credentials clientSecret
38
- * - UENGAGE_SERVICE_SCOPE optional space-separated scope list
39
- *
40
- * The chainable `.config({...})` / `.auth({...})` API on the audit and
41
- * business clients is preserved for back-compat. `.auth({token})`
42
- * accepts a static Bearer token; for OAuth2 client_credentials use the
43
- * unified `createClient(...)` factory instead — that builds a
44
- * TokenSource which handles caching + refresh dedup + 401 retry.
45
- */
46
- exports.audit = (0, audit_1.createAuditClient)();
47
- exports.business = (0, business_1.createBusinessClient)();
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQ0FBd0I7QUFDeEIsNkNBQTJCO0FBQzNCLDJDQUF5QjtBQUN6QiwrQkFBOEI7QUFBckIsNEZBQUEsSUFBSSxPQUFBO0FBUWIsbUNBTWtCO0FBRGhCLDBHQUFBLGdCQUFnQixPQUFBO0FBRWxCLG1DQU1rQjtBQUxoQixzR0FBQSxZQUFZLE9BQUE7QUFDWixrR0FBQSxRQUFRLE9BQUE7QUFDUixtR0FBQSxTQUFTLE9BQUE7QUFLWCxtQ0FBNEM7QUFDNUMseUNBQWtEO0FBRWxEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ1UsUUFBQSxLQUFLLEdBQUcsSUFBQSx5QkFBaUIsR0FBRSxDQUFDO0FBQzVCLFFBQUEsUUFBUSxHQUFHLElBQUEsK0JBQW9CLEdBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXVkaXQnO1xuZXhwb3J0ICogZnJvbSAnLi9idXNpbmVzcyc7XG5leHBvcnQgKiBmcm9tICcuL2Vycm9ycyc7XG5leHBvcnQgeyBhdXRoIH0gZnJvbSAnLi9hdXRoJztcbmV4cG9ydCB0eXBlIHtcbiAgUGtjZVBhaXIsXG4gIEF1dGhvcml6ZVVybElucHV0LFxuICBFeGNoYW5nZUNvZGVJbnB1dCxcbiAgUmVmcmVzaElucHV0LFxuICBUb2tlblBhaXIsXG59IGZyb20gJy4vYXV0aCc7XG5leHBvcnQge1xuICB0eXBlIFBsYXRmb3JtQXV0aCxcbiAgdHlwZSBQbGF0Zm9ybUF1dGhJbnB1dCxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZyxcbiAgdHlwZSBQbGF0Zm9ybUNvbmZpZ0lucHV0LFxuICBERUZBVUxUX0JBU0VfVVJMLFxufSBmcm9tICcuL2NvbmZpZyc7XG5leHBvcnQge1xuICBjcmVhdGVDbGllbnQsXG4gIHBsYXRmb3JtLFxuICB3aXRoVG9rZW4sXG4gIHR5cGUgQ2xpZW50Q29uZmlnLFxuICB0eXBlIFBsYXRmb3JtQ2xpZW50LFxufSBmcm9tICcuL2NsaWVudCc7XG5cbmltcG9ydCB7IGNyZWF0ZUF1ZGl0Q2xpZW50IH0gZnJvbSAnLi9hdWRpdCc7XG5pbXBvcnQgeyBjcmVhdGVCdXNpbmVzc0NsaWVudCB9IGZyb20gJy4vYnVzaW5lc3MnO1xuXG4vKipcbiAqIERlZmF1bHQgc2luZ2xldG9uIGNsaWVudHMuIEJvdGggcmVhZCBkZWZhdWx0cyBmcm9tIHRoZSBlbnZpcm9ubWVudCBvblxuICogZXZlcnkgY2FsbDpcbiAqICAgLSBVRU5HQUdFX0JBU0VfVVJMICAgICAgICAgIGRlZmF1bHRzIHRvIGh0dHBzOi8vYXBpLnBsYXRmb3JtLnVlbmdhZ2UuaW9cbiAqICAgLSBVRU5HQUdFX0FVVEhfVE9LRU4gICAgICAgIHN0YXRpYyBCZWFyZXIgdG9rZW5cbiAqICAgLSBVRU5HQUdFX1NFUlZJQ0VfSUQgICAgICAgIE9BdXRoMiBjbGllbnRfY3JlZGVudGlhbHMgY2xpZW50SWRcbiAqICAgLSBVRU5HQUdFX1NFUlZJQ0VfU0VDUkVUICAgIE9BdXRoMiBjbGllbnRfY3JlZGVudGlhbHMgY2xpZW50U2VjcmV0XG4gKiAgIC0gVUVOR0FHRV9TRVJWSUNFX1NDT1BFICAgICBvcHRpb25hbCBzcGFjZS1zZXBhcmF0ZWQgc2NvcGUgbGlzdFxuICpcbiAqIFRoZSBjaGFpbmFibGUgYC5jb25maWcoey4uLn0pYCAvIGAuYXV0aCh7Li4ufSlgIEFQSSBvbiB0aGUgYXVkaXQgYW5kXG4gKiBidXNpbmVzcyBjbGllbnRzIGlzIHByZXNlcnZlZCBmb3IgYmFjay1jb21wYXQuIGAuYXV0aCh7dG9rZW59KWBcbiAqIGFjY2VwdHMgYSBzdGF0aWMgQmVhcmVyIHRva2VuOyBmb3IgT0F1dGgyIGNsaWVudF9jcmVkZW50aWFscyB1c2UgdGhlXG4gKiB1bmlmaWVkIGBjcmVhdGVDbGllbnQoLi4uKWAgZmFjdG9yeSBpbnN0ZWFkIOKAlCB0aGF0IGJ1aWxkcyBhXG4gKiBUb2tlblNvdXJjZSB3aGljaCBoYW5kbGVzIGNhY2hpbmcgKyByZWZyZXNoIGRlZHVwICsgNDAxIHJldHJ5LlxuICovXG5leHBvcnQgY29uc3QgYXVkaXQgPSBjcmVhdGVBdWRpdENsaWVudCgpO1xuZXhwb3J0IGNvbnN0IGJ1c2luZXNzID0gY3JlYXRlQnVzaW5lc3NDbGllbnQoKTtcbiJdfQ==
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQ0FBd0I7QUFDeEIsNkNBQTJCO0FBQzNCLDJDQUF5QjtBQUN6QiwrQkFBOEI7QUFBckIsNEZBQUEsSUFBSSxPQUFBO0FBUWIsbUNBTWtCO0FBRGhCLDBHQUFBLGdCQUFnQixPQUFBO0FBRWxCLG1DQUFnRjtBQUF2RSxzR0FBQSxZQUFZLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2F1ZGl0JztcbmV4cG9ydCAqIGZyb20gJy4vYnVzaW5lc3MnO1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMnO1xuZXhwb3J0IHsgYXV0aCB9IGZyb20gJy4vYXV0aCc7XG5leHBvcnQgdHlwZSB7XG4gIFBrY2VQYWlyLFxuICBBdXRob3JpemVVcmxJbnB1dCxcbiAgRXhjaGFuZ2VDb2RlSW5wdXQsXG4gIFJlZnJlc2hJbnB1dCxcbiAgVG9rZW5QYWlyLFxufSBmcm9tICcuL2F1dGgnO1xuZXhwb3J0IHtcbiAgdHlwZSBQbGF0Zm9ybUF1dGgsXG4gIHR5cGUgUGxhdGZvcm1BdXRoSW5wdXQsXG4gIHR5cGUgUGxhdGZvcm1Db25maWcsXG4gIHR5cGUgUGxhdGZvcm1Db25maWdJbnB1dCxcbiAgREVGQVVMVF9CQVNFX1VSTCxcbn0gZnJvbSAnLi9jb25maWcnO1xuZXhwb3J0IHsgY3JlYXRlQ2xpZW50LCB0eXBlIENsaWVudENvbmZpZywgdHlwZSBQbGF0Zm9ybUNsaWVudCB9IGZyb20gJy4vY2xpZW50JztcbiJdfQ==
package/dist/version.d.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  * (TS lib settings dependent) or a build-time replacement, and the
6
6
  * cost of one bump-in-two-places per release is small.
7
7
  */
8
- export declare const SDK_VERSION = "0.8.0";
8
+ export declare const SDK_VERSION = "0.9.1";
package/dist/version.js CHANGED
@@ -8,5 +8,5 @@ exports.SDK_VERSION = void 0;
8
8
  * (TS lib settings dependent) or a build-time replacement, and the
9
9
  * cost of one bump-in-two-places per release is small.
10
10
  */
11
- exports.SDK_VERSION = '0.8.0';
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7Ozs7R0FNRztBQUNVLFFBQUEsV0FBVyxHQUFHLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTWFudWFsbHktbWFpbnRhaW5lZCB2ZXJzaW9uIHN0cmluZyBzdXJmYWNlZCB2aWEgdGhlIGBVc2VyLUFnZW50YFxuICogaGVhZGVyLiBLZXB0IGluIHN5bmMgd2l0aCBgcGFja2FnZS5qc29uYCBieSBoYW5kIGJlY2F1c2UgcHVsbGluZyB0aGVcbiAqIHZhbHVlIGZyb20gcGFja2FnZS5qc29uIGF0IHJ1bnRpbWUgd291bGQgcmVxdWlyZSBlaXRoZXIgYSBKU09OIGltcG9ydFxuICogKFRTIGxpYiBzZXR0aW5ncyBkZXBlbmRlbnQpIG9yIGEgYnVpbGQtdGltZSByZXBsYWNlbWVudCwgYW5kIHRoZVxuICogY29zdCBvZiBvbmUgYnVtcC1pbi10d28tcGxhY2VzIHBlciByZWxlYXNlIGlzIHNtYWxsLlxuICovXG5leHBvcnQgY29uc3QgU0RLX1ZFUlNJT04gPSAnMC44LjAnO1xuIl19
11
+ exports.SDK_VERSION = '0.9.1';
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7Ozs7R0FNRztBQUNVLFFBQUEsV0FBVyxHQUFHLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTWFudWFsbHktbWFpbnRhaW5lZCB2ZXJzaW9uIHN0cmluZyBzdXJmYWNlZCB2aWEgdGhlIGBVc2VyLUFnZW50YFxuICogaGVhZGVyLiBLZXB0IGluIHN5bmMgd2l0aCBgcGFja2FnZS5qc29uYCBieSBoYW5kIGJlY2F1c2UgcHVsbGluZyB0aGVcbiAqIHZhbHVlIGZyb20gcGFja2FnZS5qc29uIGF0IHJ1bnRpbWUgd291bGQgcmVxdWlyZSBlaXRoZXIgYSBKU09OIGltcG9ydFxuICogKFRTIGxpYiBzZXR0aW5ncyBkZXBlbmRlbnQpIG9yIGEgYnVpbGQtdGltZSByZXBsYWNlbWVudCwgYW5kIHRoZVxuICogY29zdCBvZiBvbmUgYnVtcC1pbi10d28tcGxhY2VzIHBlciByZWxlYXNlIGlzIHNtYWxsLlxuICovXG5leHBvcnQgY29uc3QgU0RLX1ZFUlNJT04gPSAnMC45LjEnO1xuIl19
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uengage.io/platform-sdk",
3
- "version": "0.8.0",
4
- "description": "Client SDK for the uEngage platform API (audit, business, ...). Namespaced singletons with HMAC or Bearer auth.",
3
+ "version": "0.9.1",
4
+ "description": "Client SDK for the uEngage platform API (audit, business, auth). Single createClient(...) factory; OAuth2 client_credentials, static Bearer, or legacy session-token auth modes.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "files": [