@native-engagement/sdk 0.8.0 → 0.8.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,25 +1,91 @@
1
1
  # Native Engagement SDK
2
2
 
3
- Authenticated JavaScript and TypeScript access to Native Engagement's canonical HTTPS contracts. Requires Node.js 24.22.1 or newer in the 24 LTS line. This package contains the remote client; local execution, desktop processes and channel credentials remain with their authorized owners.
3
+ JavaScript and TypeScript access to Native Engagement. Requires Node.js 24.22.1+ in the 24 LTS line.
4
4
 
5
5
  ```sh
6
- npm install @native-engagement/sdk@beta
6
+ npm install @native-engagement/sdk@0.8.1
7
7
  ```
8
8
 
9
+ ## Account and password sign-in
10
+
11
+ The SDK supports browser-based account sign-in through OAuth Authorization Code with S256 PKCE. Enter your account, password and any MFA challenge on the identity service's browser page. The SDK receives a validated authorization result; your application does not collect the password.
12
+
9
13
  ```js
10
- import { RemoteNativeEngagementSdk } from '@native-engagement/sdk';
11
-
12
- const client = new RemoteNativeEngagementSdk({
13
- baseUrl: 'https://engagement.shipkitx.com',
14
- accessToken: () => process.env.NATIVE_ENGAGEMENT_BEARER_TOKEN ?? ''
15
- });
16
- console.log(await client.contracts());
17
- // For an authorized operation, obtain its schema and provide its exact input:
18
- // await client.query({ name: 'conversation.list', payload: { ... } });
14
+ import { createNativePublicLogin, openNativeLoginPage,
15
+ RemoteNativeEngagementSdk, prospectClient } from '@native-engagement/sdk';
16
+
17
+ const origin = 'https://engagement.shipkitx.com';
18
+ const login = await createNativePublicLogin(origin);
19
+ const grant = await login.authorize(AbortSignal.timeout(180_000), openNativeLoginPage);
20
+ const sdk = new RemoteNativeEngagementSdk({ baseUrl: origin, accessToken: () => grant.accessToken });
21
+ const prospects = prospectClient(sdk);
19
22
  ```
20
23
 
21
- The service validates identity, tenant membership, account permissions and current grants. Installing this package grants no business access. Supply a short-lived authorized access token through a protected environment or your token provider; never commit credentials. Writes require an idempotencyKey. Unknown external effects must be inspected using their original operation, rather than resubmitted.
24
+ `openNativeLoginPage` opens the system browser on macOS, Windows and Linux. Applications with their own browser UI can supply an `async authorizationUrl => { ... }` callback instead. The browser callback must reach the Node.js process on its configured loopback address. Use a local Node.js process for this flow; a browser-only application should use the service's web login.
25
+
26
+ Public configuration comes from `/releases/cli-login.json` on the exact HTTPS center, with pinned issuer, public client, resource and business scopes. Your administrator must provision your account and tenant permissions. Current directory and Profile grants govern every operation.
27
+
28
+ Keep the short-lived grant in memory or your protected credential store. Sign in again after expiry; an active identity-service browser session can reuse SSO. The SDK does not automatically persist credentials. Sign out with `await login.revoke(grant)`. For automation, supply a separately authorized access token through a token provider or protected process environment. Password arguments and password-grant login are not offered.
29
+
30
+ ## Complete import, creation and association
31
+
32
+ Country, industry, address, contact name/title and original score are optional `profile` strings. Source URLs are optional; supply the actual credential-free HTTP(S) source page when known. Source reference/version, observation time and current/historical status remain explicit. Persist and reuse the complete input and its idempotency key when retrying.
33
+
34
+ ```js
35
+ const observedAt = new Date().toISOString();
36
+ const input = {
37
+ idempotencyKey: 'research-november-v1', batchRef: 'research-november-v1', datasetRef: 'November research',
38
+ rows: [{
39
+ rowRef: 'row-1', sourceRef: 'reviewed-research-file', sourceVersion: 'v1',
40
+ selection: 'SELECTED', displayName: 'Example Company',
41
+ companyIdentity: { namespace: 'reviewed-company', value: 'company-001' },
42
+ profile: { observedAt, temporalStatus: 'CURRENT', country: 'CN', industry: 'Logistics',
43
+ address: 'Shanghai', contactName: 'Research Contact', contactTitle: 'Director', score: '8/10' },
44
+ contacts: [{ channel: 'EMAIL', value: 'research@example.test', observation: {
45
+ sourceRef: 'reviewed-research-file', sourceVersion: 'v1', observedAt,
46
+ temporalStatus: 'CURRENT', verificationStatus: 'PUBLIC_UNVERIFIED'
47
+ } }]
48
+ }]
49
+ };
50
+ const preview = await prospects.preview(input); // No business write.
51
+ console.log(preview.rows); // Review HELD/REJECTED outcomes before importing.
52
+ await prospects.import(input);
53
+ const batch = await prospects.batch(input.batchRef);
54
+ const imported = batch.rows.find(row => row.status === 'IMPORTED');
55
+ if (!imported?.prospectRef) throw Error('Review the import receipt');
56
+ const company = await prospects.company(imported.prospectRef);
57
+ console.log(company.profileObservations, company.contacts);
58
+
59
+ const route = company.contacts.find(item => item.channel === 'EMAIL');
60
+ const source = route?.observations.find(item => item.temporalStatus === 'CURRENT');
61
+ if (!route || !source) throw Error('A current imported email observation is required');
62
+ const create = {
63
+ idempotencyKey: 'research-november-engagement-001', engagementRef: 'research-november-engagement-001',
64
+ prospectRef: company.prospectRef, contactRouteRef: route.contactRouteRef,
65
+ sourceRef: source.sourceRef, sourceVersion: source.sourceVersion, observedAt: source.observedAt,
66
+ whyFit: 'Reviewed logistics fit', whyNow: 'Reviewed current opportunity'
67
+ };
68
+ await prospects.createEngagement(create);
69
+ const associated = await prospects.engagements(company.prospectRef, { limit: 20 });
70
+ console.log(associated.entries); // Continue with associated.nextCursor when present.
71
+ ```
72
+
73
+ Creation uses an exact imported CURRENT observation, current authorization and STOP policy. It records why-fit/why-now without sending or scheduling work. Changed source rows require a new version; names, emails and domains are not stable company identifiers. Score strings retain their original scale. Original research and verification belong to the archive/Knowledge owner; Native Engagement owns imported observations, provenance, receipts and engagement facts.
74
+
75
+ ## Batch pagination
76
+
77
+ Each response has at most 100 entries; total history has no 100-batch cap. Concurrent imports can shift offset pages; restart from the first page when refreshing. Associated engagements use a separate signed cursor.
78
+
79
+ ```js
80
+ let offset = 0;
81
+ for (;;) {
82
+ const page = await prospects.batches({ offset, limit: 20 });
83
+ console.log(page.total, page.entries);
84
+ if (page.nextOffset === null) break;
85
+ offset = page.nextOffset;
86
+ }
87
+ ```
22
88
 
23
- Exports: RemoteNativeEngagementSdk, RemoteNativeEngagementError and their TypeScript types. SDK responses preserve the service's structured result and error semantics.
89
+ Exports include `RemoteNativeEngagementSdk`, `RemoteNativeEngagementError`, `prospectClient`, `createNativePublicLogin`, `openNativeLoginPage`, `NativePublicLogin`, `NativeLoginConfiguration`, `NativeLoginGrant`, `RemoteSdkOptions` and Prospect DTOs. Generic `contracts`, `schema`, `query` and `command` remain available. Commands require a stable idempotency key. Unknown external effects require original-operation inspection.
24
90
 
25
- This beta is distributed with license `UNLICENSED`; publication does not grant an open-source license. Product documentation: https://engagement.shipkitx.com/downloads
91
+ This beta uses license `UNLICENSED`. [Sign-in and MCP OAuth guide](https://engagement.shipkitx.com/releases/authentication.md) · [Downloads](https://engagement.shipkitx.com/downloads)
@@ -1 +1,50 @@
1
- No third-party runtime code is bundled. Node.js built-in modules are provided by the host.
1
+ oauth4webapi@3.8.8
2
+
3
+ The MIT License (MIT)
4
+
5
+ Copyright (c) 2022 Filip Skokan
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+
25
+
26
+ ---
27
+
28
+ openid-client@6.8.7
29
+
30
+ The MIT License (MIT)
31
+
32
+ Copyright (c) 2016 Filip Skokan
33
+
34
+ Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ of this software and associated documentation files (the "Software"), to deal
36
+ in the Software without restriction, including without limitation the rights
37
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
+ copies of the Software, and to permit persons to whom the Software is
39
+ furnished to do so, subject to the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be included in all
42
+ copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50
+ SOFTWARE.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,126 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
+ /** Public DTOs shared by the Agent SDK; runtime validation is the canonical JSON Schema. */
4
+ export type ProspectTemporalStatus = "CURRENT" | "HISTORICAL";
5
+ export interface ProspectObservation {
6
+ sourceRef: string;
7
+ sourceVersion: string;
8
+ sourceUrl?: string;
9
+ observedAt: string;
10
+ temporalStatus: ProspectTemporalStatus;
11
+ verificationStatus: "PUBLIC_UNVERIFIED" | "VERIFIED";
12
+ verifiedAt?: string;
13
+ assetRef?: string;
14
+ }
15
+ export interface ProspectProfile {
16
+ observedAt: string;
17
+ temporalStatus: ProspectTemporalStatus;
18
+ sourceUrl?: string;
19
+ country?: string;
20
+ industry?: string;
21
+ address?: string;
22
+ contactName?: string;
23
+ contactTitle?: string;
24
+ score?: string;
25
+ }
26
+ export interface ProspectImportRow {
27
+ rowRef: string;
28
+ sourceRef: string;
29
+ sourceVersion: string;
30
+ selection: "SELECTED" | "HELD";
31
+ displayName: string;
32
+ companyIdentity: {
33
+ namespace: string;
34
+ value: string;
35
+ };
36
+ contacts: {
37
+ channel: "EMAIL" | "PHONE" | "WHATSAPP" | "FAX" | "URL";
38
+ value: string;
39
+ observation: ProspectObservation;
40
+ }[];
41
+ profile?: ProspectProfile;
42
+ }
43
+ export interface ProspectImportInput {
44
+ idempotencyKey: string;
45
+ batchRef: string;
46
+ datasetRef: string;
47
+ rows: ProspectImportRow[];
48
+ metadata?: {
49
+ sourceRef: string;
50
+ sourceVersion: string;
51
+ observedAt: string;
52
+ temporalStatus: ProspectTemporalStatus;
53
+ };
54
+ }
55
+ export interface ProspectBatchView {
56
+ tenantId: string;
57
+ batchRef: string;
58
+ datasetRef: string;
59
+ fingerprint: string;
60
+ metadata?: ProspectImportInput["metadata"];
61
+ rows: {
62
+ rowRef: string;
63
+ status: "IMPORTED" | "DUPLICATE" | "HELD" | "REJECTED";
64
+ prospectRef?: string;
65
+ contactRouteRefs?: string[];
66
+ sourceRef?: string;
67
+ sourceVersion?: string;
68
+ displayName?: string;
69
+ record?: ProspectImportRow;
70
+ code?: string;
71
+ message?: string;
72
+ duplicateOfBatchRef?: string;
73
+ }[];
74
+ }
75
+ export interface ProspectCompanyView {
76
+ tenantId: string;
77
+ prospectRef: string;
78
+ companyIdentity: ProspectImportRow["companyIdentity"];
79
+ displayName: string;
80
+ contacts: {
81
+ contactRouteRef: string;
82
+ channel: string;
83
+ value: string;
84
+ normalizedValue: string;
85
+ observations: ProspectObservation[];
86
+ }[];
87
+ profileObservations?: (ProspectProfile & {
88
+ sourceRef: string;
89
+ sourceVersion: string;
90
+ rowRef: string;
91
+ contactRouteRefs: string[];
92
+ })[];
93
+ datasetRefs: string[];
94
+ suppressions?: unknown[];
95
+ }
96
+ export interface ProspectPageInput {
97
+ offset?: number;
98
+ limit?: number;
99
+ datasetRef?: string;
100
+ }
101
+ export interface ProspectPage<T> {
102
+ tenantId: string;
103
+ entries: T[];
104
+ total: number;
105
+ offset: number;
106
+ limit: number;
107
+ nextOffset: number | null;
108
+ sources: {
109
+ name: string;
110
+ count: number;
111
+ }[];
112
+ }
113
+ export interface ProspectEngagementInput {
114
+ idempotencyKey: string;
115
+ engagementRef: string;
116
+ prospectRef: string;
117
+ contactRouteRef: string;
118
+ sourceRef: string;
119
+ sourceVersion: string;
120
+ observedAt: string;
121
+ whyFit: string;
122
+ whyNow: string;
123
+ }
3
124
  export interface AgentStackScope {
4
125
  readonly authorityRef: string;
5
126
  readonly sourcePrincipal: Readonly<{
@@ -28,6 +149,84 @@ export interface TenantContextInput {
28
149
  /** 只由验证签名的 Agent Stack 适配器产生,HTTP 业务 payload 不得提供。 */
29
150
  readonly agentStack?: AgentStackScope | undefined;
30
151
  }
152
+ export interface CommunicationOwnership {
153
+ readonly kind: "COMMUNICATION";
154
+ readonly accountRef: string;
155
+ readonly profileRef: string;
156
+ readonly displayName: string;
157
+ readonly basis: {
158
+ readonly kind: "HUMAN_DECLARED";
159
+ readonly principalRef: string;
160
+ readonly operationKey: string;
161
+ } | {
162
+ readonly kind: "DELEGATED_NATIVE_OBSERVATION";
163
+ readonly principalRef: string;
164
+ readonly operationKey: string;
165
+ readonly dispatchRef: string;
166
+ readonly reportDigest: string;
167
+ readonly policyRef: string;
168
+ readonly policyVersion: number;
169
+ readonly policyDigest: string;
170
+ };
171
+ }
172
+ export interface EngagementControl {
173
+ readonly tenantId: string;
174
+ readonly engagementRef: string;
175
+ readonly version: number;
176
+ readonly state: "AGENT_CONTROLLED" | "HANDOFF_REQUESTED" | "HUMAN_CONTROLLED";
177
+ readonly controlScope: "ENGAGEMENT_OUTBOUND_AUTOMATION";
178
+ readonly handoffRef?: string;
179
+ readonly requestedBy?: string;
180
+ readonly requestedAt?: string;
181
+ readonly reason?: string;
182
+ readonly assigneeRef?: string;
183
+ readonly controlledBy?: string;
184
+ readonly controlledAt?: string;
185
+ readonly resumedBy?: string;
186
+ readonly resumedAt?: string;
187
+ readonly sessionCorrelationRef?: string;
188
+ }
189
+ export interface ProspectEngagementBasis {
190
+ readonly whyFit: string;
191
+ readonly whyNow: string;
192
+ readonly contactRouteRef: string;
193
+ readonly sourceRef: string;
194
+ readonly sourceVersion: string;
195
+ readonly observedAt: string;
196
+ }
197
+ export type InteractionOutcome = "CONFIRMED" | "UNCERTAIN" | "FAILED";
198
+ export interface ActionReceipt {
199
+ readonly tenantId: string;
200
+ readonly receiptRef: string;
201
+ readonly commandName: string;
202
+ readonly commandVersion: string;
203
+ readonly idempotencyKey: string;
204
+ readonly outcome: InteractionOutcome;
205
+ readonly entityRefs: readonly string[];
206
+ readonly interactionRef?: string | undefined;
207
+ readonly observedAt: string;
208
+ readonly idempotentReplay: boolean;
209
+ readonly executionStatus?: "QUEUED" | "ACCEPTED" | "UNCERTAIN" | "FAILED" | "CANCELLED";
210
+ }
211
+ export type NextActionType = "CONTACT" | "REPLY" | "WAIT_FOR_REPLY" | "VERIFY_UNCERTAIN_ACTION" | "REVIEW_FAILED_ACTION" | "REVIEW" | "REVIEW_MESSAGE" | "QUEUE_APPROVED_MESSAGE" | "WAIT_FOR_EXECUTION" | "FOLLOW_UP_DUE" | "NONE_SUPPRESSED" | "HANDOFF_READY";
212
+ export interface NextAction {
213
+ readonly tenantId: string;
214
+ readonly engagementRef: string;
215
+ readonly type: NextActionType;
216
+ readonly rationale: string;
217
+ readonly requiresHuman: boolean;
218
+ readonly sourceInteractionRefs: readonly string[];
219
+ readonly handoffRef?: string;
220
+ readonly assessmentRef?: string;
221
+ readonly assessmentVersion?: number;
222
+ readonly dueAt?: string;
223
+ readonly channel?: string;
224
+ readonly routeRef?: string;
225
+ readonly messageRef?: string;
226
+ readonly profileRef?: string;
227
+ readonly policyRequirements?: readonly string[];
228
+ readonly missingPrerequisites?: readonly string[];
229
+ }
31
230
  declare const EXECUTION_NODE_PROTOCOL = "ne-execution-node/1.0";
32
231
  export interface NodeProof {
33
232
  protocol: typeof EXECUTION_NODE_PROTOCOL;
@@ -43,6 +242,32 @@ export interface NodeProof {
43
242
  bodyDigest: string;
44
243
  signature: string;
45
244
  }
245
+ export type WorkbenchSummary = ({
246
+ readonly prospectRef: string;
247
+ readonly ownership?: never;
248
+ } | {
249
+ readonly prospectRef?: never;
250
+ readonly ownership: CommunicationOwnership;
251
+ }) & {
252
+ readonly tenantId: string;
253
+ readonly engagementRef: string;
254
+ readonly displayName: string;
255
+ readonly status: "ACTIVE" | "SUPPRESSED";
256
+ readonly control: EngagementControl;
257
+ readonly nextAction: NextAction;
258
+ readonly openTasks: number;
259
+ readonly interactionCount: number;
260
+ readonly candidateRef?: string;
261
+ readonly prospectBasis?: ProspectEngagementBasis;
262
+ };
263
+ export interface EngagementCatalogPage {
264
+ readonly tenantId: string;
265
+ readonly entries: readonly WorkbenchSummary[];
266
+ readonly revision: string;
267
+ readonly nextCursor: string | null;
268
+ readonly total: null;
269
+ readonly totalMeaning: "NOT_COMPUTED";
270
+ }
46
271
  export interface ContractExecutionRequest {
47
272
  /** Transport possession proof is separate from verified identity. */
48
273
  readonly transportProof?: NodeProof | undefined;
@@ -87,5 +312,51 @@ export declare class RemoteNativeEngagementSdk {
87
312
  enquiry(payload: Readonly<Record<string, unknown>>): Promise<unknown>;
88
313
  agentStackPreflight(payload: Readonly<Record<string, unknown>>): Promise<unknown>;
89
314
  }
315
+ export type WorkClient = Pick<RemoteNativeEngagementSdk, "query" | "command">;
316
+ /** Authenticated API parity; the service resolves identity and enforces every contract. */
317
+ export declare function prospectClient(client: WorkClient): {
318
+ preview: (input: ProspectImportInput) => Promise<ProspectBatchView>;
319
+ import: (input: ProspectImportInput) => Promise<ActionReceipt>;
320
+ batch: (batchRef: string) => Promise<ProspectBatchView>;
321
+ batches: (input?: ProspectPageInput) => Promise<ProspectPage<ProspectBatchView>>;
322
+ company: (prospectRef: string) => Promise<ProspectCompanyView>;
323
+ companies: (input?: ProspectPageInput & {
324
+ keyword?: string;
325
+ }) => Promise<ProspectPage<ProspectCompanyView>>;
326
+ createEngagement: (input: ProspectEngagementInput) => Promise<ActionReceipt>;
327
+ engagements: (prospectRef: string, input?: {
328
+ limit?: number;
329
+ cursor?: string;
330
+ }) => Promise<EngagementCatalogPage>;
331
+ };
332
+ export interface NativeLoginConfiguration {
333
+ issuer: string;
334
+ clientId: string;
335
+ resource: string;
336
+ redirectUri: string;
337
+ scopes: string[];
338
+ authorizationEndpoint: string;
339
+ tokenEndpoint: string;
340
+ jwksUri: string;
341
+ revocationEndpoint: string;
342
+ }
343
+ export interface NativeLoginGrant {
344
+ accessToken: string;
345
+ refreshToken: string | null;
346
+ subject: string;
347
+ expiresAt: number;
348
+ }
349
+ export declare class NativePublicLogin {
350
+ readonly installation: NativeLoginConfiguration;
351
+ private readonly config;
352
+ constructor(installation: NativeLoginConfiguration, fetcher?: typeof fetch);
353
+ authorize(signal: AbortSignal, open: (url: string) => Promise<void>): Promise<NativeLoginGrant>;
354
+ revoke(grant: NativeLoginGrant): Promise<void>;
355
+ refresh(grant: NativeLoginGrant): Promise<NativeLoginGrant>;
356
+ }
357
+ /** Discover the center's dedicated public client. Password entry stays in its browser UI. */
358
+ export declare function createNativePublicLogin(serviceOrigin?: string, fetcher?: typeof fetch): Promise<NativePublicLogin>;
359
+ /** Open the authorization page in the operating system browser; never pass a password. */
360
+ export declare function openNativeLoginPage(address: string): Promise<void>;
90
361
 
91
362
  export {};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- function l(t){return t==="SEND_BUDGET_EXHAUSTED"?{retryable:!0,hint:"WAIT_FOR_ACCOUNT_BUDGET_AND_RETRY_SAME_KEY"}:t==="SEND_GATE_DISABLED"?{retryable:!1,hint:"REQUIRE_ACCOUNT_OWNER_TO_ENABLE_SENDING"}:t==="SEND_RESERVATION_REQUIRED"?{retryable:!1,hint:"CANCEL_AND_REVIEW_A_NEW_RESERVED_INTENT"}:["AUTH_VERIFICATION_UNAVAILABLE","AGENT_STACK_AUTHORITY_UNAVAILABLE","REDIS_RATE_LIMIT_UNAVAILABLE","SERVICE_NOT_CONFIGURED","RATE_LIMIT_EXCEEDED"].includes(t)?{retryable:!0,hint:"WAIT_AND_RETRY_SAME_IDEMPOTENCY_KEY"}:["AUTH_TOKEN_EXPIRED","AUTHENTICATION_REQUIRED","AUTH_TOKEN_REVOKED"].includes(t)?{retryable:!1,hint:"REAUTHENTICATE_AND_RECHECK_CURRENT_AUTHORITY"}:["ENTITY_CONFLICT","SEARCH_CURSOR_STALE","HOST_INBOX_CURSOR_STALE"].includes(t)?{retryable:!1,hint:"READ_CURRENT_STATE_AND_REPLAN"}:t==="IDEMPOTENCY_CONFLICT"?{retryable:!1,hint:"RESTORE_ORIGINAL_INPUT_FOR_KEY"}:["HOST_EXECUTION_FAILED","HOST_BRIDGE_UNAVAILABLE"].includes(t)?{retryable:!1,hint:"VERIFY_KNOWN_OPERATION_BEFORE_ANY_SEND"}:t==="SUPPRESSED"?{retryable:!1,hint:"STOP_CONTACT_AND_REQUIRE_HUMAN_REVIEW"}:t.startsWith("AUTH")||t==="TENANT_NOT_PROVISIONED"?{retryable:!1,hint:"REQUIRE_OPERATOR_AUTHORITY_REVIEW"}:{retryable:!1,hint:"FIX_INPUT_OR_INSPECT_STATE_BEFORE_RETRY"}}var f=class extends Error{code;statusCode;details;constructor(e,r,o,s={}){super(r),this.code=e,this.statusCode=o,this.details=s,this.name="NativeEngagementError"}};function p(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new f("VALIDATION_FAILED",`${e} must be an object.`,400,{field:e});return t}function I(t){let e=p(t??{},"payload"),r=e.idempotencyKey;if(typeof r!="string"||!r.trim()||r.length>1024*1024)throw new f("VALIDATION_FAILED","Every command requires a bounded idempotencyKey.",400,{field:"idempotencyKey"});return e}async function h(t,e=2*1024*1024){if(Number(t.headers.get("content-length"))>e||!t.body)throw Error("NODE_REMOTE_RESPONSE_TOO_LARGE");let r=t.body.getReader(),o=[],s=0;try{for(;;){let n=await r.read();if(n.done)break;if(s+=n.value.byteLength,s>e)throw Error("NODE_REMOTE_RESPONSE_TOO_LARGE");o.push(n.value)}let a=new Uint8Array(s),c=0;for(let n of o)a.set(n,c),c+=n.byteLength;return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(a))}finally{await r.cancel().catch(()=>{}),r.releaseLock()}}var E=class extends Error{constructor(r,o,s,a={}){super(o);this.code=r;this.status=s;this.details=a;this.name="RemoteNativeEngagementError";let c=l(r);this.retryable=c.retryable,this.hint=c.hint;let n=a.retryAfterSeconds,d=a.reasonCode;this.retryAfterSeconds=Number.isInteger(n)&&Number(n)>=0&&Number(n)<=3600?Number(n):void 0,this.reasonCode=typeof d=="string"&&/^[A-Z][A-Z_]{1,120}$/.test(d)?d:void 0}code;status;details;retryable;hint;retryAfterSeconds;reasonCode};function R(t){let e;try{e=new URL(t)}catch{throw new Error("Invalid native-engagement service URL.")}let r=e.hostname==="127.0.0.1"||e.hostname==="localhost"||e.hostname==="[::1]";if(!(e.protocol==="https:"||e.protocol==="http:"&&r)||e.username||e.password||e.search||e.hash||e.pathname!=="/")throw new Error("native-engagement requires HTTPS or HTTP loopback without URL credentials.");return e.origin}var A=class{#o;#i;#s;#r;#t;#n;constructor(e){if(this.#o=R(e.baseUrl),this.#i=e.accessToken,this.#s=e.fetchImpl??fetch,this.#n=e.tenantId,this.#r=e.nodeProof,this.#t=e.maximumResponseBytes??16*1024*1024,!Number.isSafeInteger(this.#t)||this.#t<1024||this.#t>64*1024*1024)throw Error("Invalid maximum JSON response size.")}async#e(e,r,o,s=!0,a=3e4,c){let n={accept:"application/json","content-type":"application/json"};if(s){let i=await this.#i();if(!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(i))throw new E("AUTHENTICATION_REQUIRED","An access token is required for the remote operation.",401);n.authorization=`Bearer ${i}`,this.#n&&(n["x-tenant-id"]=this.#n)}this.#r&&/^\/v1\/(query|command)\/execution\.node\./.test(r)&&(n["x-execution-node-proof"]=Buffer.from(JSON.stringify(this.#r(e,r,o??{}))).toString("base64url"));let d=await this.#s(`${this.#o}${r}`,{method:e,headers:n,...e==="POST"?{body:JSON.stringify(o??{})}:{},redirect:"error",signal:c?AbortSignal.any([c,AbortSignal.timeout(a)]):AbortSignal.timeout(a)}),u;try{u=await h(d,this.#r&&r.includes("/execution.node.")?2*1024*1024:this.#t)}catch{throw new E("REMOTE_RESPONSE_INVALID","The service did not return valid JSON.",d.status)}if(!d.ok){let i=u&&typeof u=="object"&&"error"in u?u.error:void 0;throw new E(i?.code??"REMOTE_REQUEST_FAILED",i?.message??"The native-engagement service rejected the request.",d.status,i?.details&&typeof i.details=="object"&&!Array.isArray(i.details)?i.details:{})}return u}contracts(){return this.#e("GET","/v1/contracts",void 0,!1)}schema(e){return this.#e("GET",`/v1/contracts/${encodeURIComponent(e)}`,void 0,!1)}query(e,r){let o=["channel.status.inspect","profile.host.inspect","wechat.session.inspect","wechat.thread.observe","browser.session.inspect","browser.thread.observe"].includes(e.name)?12e4:3e4;return this.#e("POST",`/v1/query/${encodeURIComponent(e.name)}`,e.payload,!0,o,r)}command(e,r){try{I(e.payload)}catch{throw new E("VALIDATION_FAILED","Every command requires a bounded idempotencyKey.",400)}let o=["conversation.source.sync","conversation.source.rebase","wechat.conversation.sync","wechat.thread.link","wechat.watch.resume"].includes(e.name)||e.name==="asset.speech.synthesize"?12e4:["message.text.execute","message.text.verify","wechat.message.execute","wechat.message.verify"].includes(e.name)?18e4:["asset.parse","message.attachment.capture","work.content.prepare","work.mail.content.prepare","work.source.content.prepare"].includes(e.name)?2e5:3e4;return this.#e("POST",`/v1/command/${encodeURIComponent(e.name)}`,e.payload,!0,o,r)}search(e){return this.#e("POST","/v1/search",e)}enquiry(e){return this.#e("POST","/v1/enquiry",e)}agentStackPreflight(e){return this.#e("POST","/v1/integrations/agent-stack/preflight",e)}};export{E as RemoteNativeEngagementError,A as RemoteNativeEngagementSdk};
1
+ function ge(e){return e==="SEND_BUDGET_EXHAUSTED"?{retryable:!0,hint:"WAIT_FOR_ACCOUNT_BUDGET_AND_RETRY_SAME_KEY"}:e==="SEND_GATE_DISABLED"?{retryable:!1,hint:"REQUIRE_ACCOUNT_OWNER_TO_ENABLE_SENDING"}:e==="SEND_RESERVATION_REQUIRED"?{retryable:!1,hint:"CANCEL_AND_REVIEW_A_NEW_RESERVED_INTENT"}:["AUTH_VERIFICATION_UNAVAILABLE","AGENT_STACK_AUTHORITY_UNAVAILABLE","REDIS_RATE_LIMIT_UNAVAILABLE","SERVICE_NOT_CONFIGURED","RATE_LIMIT_EXCEEDED"].includes(e)?{retryable:!0,hint:"WAIT_AND_RETRY_SAME_IDEMPOTENCY_KEY"}:["AUTH_TOKEN_EXPIRED","AUTHENTICATION_REQUIRED","AUTH_TOKEN_REVOKED"].includes(e)?{retryable:!1,hint:"REAUTHENTICATE_AND_RECHECK_CURRENT_AUTHORITY"}:["ENTITY_CONFLICT","SEARCH_CURSOR_STALE","HOST_INBOX_CURSOR_STALE"].includes(e)?{retryable:!1,hint:"READ_CURRENT_STATE_AND_REPLAN"}:e==="IDEMPOTENCY_CONFLICT"?{retryable:!1,hint:"RESTORE_ORIGINAL_INPUT_FOR_KEY"}:["HOST_EXECUTION_FAILED","HOST_BRIDGE_UNAVAILABLE"].includes(e)?{retryable:!1,hint:"VERIFY_KNOWN_OPERATION_BEFORE_ANY_SEND"}:e==="SUPPRESSED"?{retryable:!1,hint:"STOP_CONTACT_AND_REQUIRE_HUMAN_REVIEW"}:e.startsWith("AUTH")||e==="TENANT_NOT_PROVISIONED"?{retryable:!1,hint:"REQUIRE_OPERATOR_AUTHORITY_REVIEW"}:{retryable:!1,hint:"FIX_INPUT_OR_INSPECT_STATE_BEFORE_RETRY"}}var S=class extends Error{code;statusCode;details;constructor(t,n,r,o={}){super(n),this.code=t,this.statusCode=r,this.details=o,this.name="NativeEngagementError"}};function Be(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new S("VALIDATION_FAILED",`${t} must be an object.`,400,{field:t});return e}function Re(e){let t=Be(e??{},"payload"),n=t.idempotencyKey;if(typeof n!="string"||!n.trim()||n.length>1024*1024)throw new S("VALIDATION_FAILED","Every command requires a bounded idempotencyKey.",400,{field:"idempotencyKey"});return t}async function $e(e,t=2*1024*1024){if(Number(e.headers.get("content-length"))>t||!e.body)throw Error("NODE_REMOTE_RESPONSE_TOO_LARGE");let n=e.body.getReader(),r=[],o=0;try{for(;;){let i=await n.read();if(i.done)break;if(o+=i.value.byteLength,o>t)throw Error("NODE_REMOTE_RESPONSE_TOO_LARGE");r.push(i.value)}let s=new Uint8Array(o),a=0;for(let i of r)s.set(i,a),a+=i.byteLength;return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(s))}finally{await n.cancel().catch(()=>{}),n.releaseLock()}}var U=class extends Error{constructor(n,r,o,s={}){super(r);this.code=n;this.status=o;this.details=s;this.name="RemoteNativeEngagementError";let a=ge(n);this.retryable=a.retryable,this.hint=a.hint;let i=s.retryAfterSeconds,c=s.reasonCode;this.retryAfterSeconds=Number.isInteger(i)&&Number(i)>=0&&Number(i)<=3600?Number(i):void 0,this.reasonCode=typeof c=="string"&&/^[A-Z][A-Z_]{1,120}$/.test(c)?c:void 0}code;status;details;retryable;hint;retryAfterSeconds;reasonCode};function Ft(e){let t;try{t=new URL(e)}catch{throw new Error("Invalid native-engagement service URL.")}let n=t.hostname==="127.0.0.1"||t.hostname==="localhost"||t.hostname==="[::1]";if(!(t.protocol==="https:"||t.protocol==="http:"&&n)||t.username||t.password||t.search||t.hash||t.pathname!=="/")throw new Error("native-engagement requires HTTPS or HTTP loopback without URL credentials.");return t.origin}var Fe=class{#o;#a;#s;#n;#t;#r;constructor(t){if(this.#o=Ft(t.baseUrl),this.#a=t.accessToken,this.#s=t.fetchImpl??fetch,this.#r=t.tenantId,this.#n=t.nodeProof,this.#t=t.maximumResponseBytes??16*1024*1024,!Number.isSafeInteger(this.#t)||this.#t<1024||this.#t>64*1024*1024)throw Error("Invalid maximum JSON response size.")}async#e(t,n,r,o=!0,s=3e4,a){let i={accept:"application/json","content-type":"application/json"};if(o){let d=await this.#a();if(!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(d))throw new U("AUTHENTICATION_REQUIRED","An access token is required for the remote operation.",401);i.authorization=`Bearer ${d}`,this.#r&&(i["x-tenant-id"]=this.#r)}this.#n&&/^\/v1\/(query|command)\/execution\.node\./.test(n)&&(i["x-execution-node-proof"]=Buffer.from(JSON.stringify(this.#n(t,n,r??{}))).toString("base64url"));let c=await this.#s(`${this.#o}${n}`,{method:t,headers:i,...t==="POST"?{body:JSON.stringify(r??{})}:{},redirect:"error",signal:a?AbortSignal.any([a,AbortSignal.timeout(s)]):AbortSignal.timeout(s)}),u;try{u=await $e(c,this.#n&&n.includes("/execution.node.")?2*1024*1024:this.#t)}catch{throw new U("REMOTE_RESPONSE_INVALID","The service did not return valid JSON.",c.status)}if(!c.ok){let d=u&&typeof u=="object"&&"error"in u?u.error:void 0;throw new U(d?.code??"REMOTE_REQUEST_FAILED",d?.message??"The native-engagement service rejected the request.",c.status,d?.details&&typeof d.details=="object"&&!Array.isArray(d.details)?d.details:{})}return u}contracts(){return this.#e("GET","/v1/contracts",void 0,!1)}schema(t){return this.#e("GET",`/v1/contracts/${encodeURIComponent(t)}`,void 0,!1)}query(t,n){let r=["channel.status.inspect","profile.host.inspect","wechat.session.inspect","wechat.thread.observe","browser.session.inspect","browser.thread.observe"].includes(t.name)?12e4:3e4;return this.#e("POST",`/v1/query/${encodeURIComponent(t.name)}`,t.payload,!0,r,n)}command(t,n){try{Re(t.payload)}catch{throw new U("VALIDATION_FAILED","Every command requires a bounded idempotencyKey.",400)}let r=["conversation.source.sync","conversation.source.rebase","wechat.conversation.sync","wechat.thread.link","wechat.watch.resume"].includes(t.name)||t.name==="asset.speech.synthesize"?12e4:["message.text.execute","message.text.verify","wechat.message.execute","wechat.message.verify"].includes(t.name)?18e4:["asset.parse","message.attachment.capture","work.content.prepare","work.mail.content.prepare","work.source.content.prepare"].includes(t.name)?2e5:3e4;return this.#e("POST",`/v1/command/${encodeURIComponent(t.name)}`,t.payload,!0,r,n)}search(t){return this.#e("POST","/v1/search",t)}enquiry(t){return this.#e("POST","/v1/enquiry",t)}agentStackPreflight(t){return this.#e("POST","/v1/integrations/agent-stack/preflight",t)}};async function Ye(e,t){let n=await e;if(!n?.ok||n.contractName!==t||n.result===void 0)throw Error("INVALID_PROSPECT_RESPONSE");return n.result}function Yt(e){let t=(r,o)=>Ye(e.query({name:r,payload:o}),r),n=(r,o)=>Ye(e.command({name:r,payload:o}),r);return{preview:r=>t("prospect.batch.preview",{...r}),import:r=>n("prospect.batch.import",{...r}),batch:r=>t("prospect.batch.get",{batchRef:r}),batches:(r={})=>t("prospect.batch.list",{...r}),company:r=>t("prospect.company.get",{prospectRef:r}),companies:(r={})=>t("prospect.catalog.list",{...r}),createEngagement:r=>n("prospect.engagement.create",{...r}),engagements:(r,o={})=>t("engagement.catalog.list",{...o,prospectRef:r})}}var Ee;(typeof navigator>"u"||!navigator.userAgent?.startsWith?.("Mozilla/5.0 "))&&(Ee="oauth4webapi/v3.8.8");function $(e,t){if(e==null)return!1;try{return e instanceof t||Object.getPrototypeOf(e)[Symbol.toStringTag]===t.prototype[Symbol.toStringTag]}catch{return!1}}var R="ERR_INVALID_ARG_VALUE",E="ERR_INVALID_ARG_TYPE";function y(e,t,n){let r=new TypeError(e,{cause:n});return Object.assign(r,{code:t}),r}var I=Symbol(),de=Symbol(),he=Symbol(),k=Symbol();var j=Symbol(),P=Symbol(),Qt=new TextEncoder,Zt=new TextDecoder;function K(e){return typeof e=="string"?Qt.encode(e):Zt.decode(e)}var Ae;Uint8Array.prototype.toBase64?Ae=e=>(e instanceof ArrayBuffer&&(e=new Uint8Array(e)),e.toBase64({alphabet:"base64url",omitPadding:!0})):Ae=t=>{t instanceof ArrayBuffer&&(t=new Uint8Array(t));let n=[];for(let r=0;r<t.byteLength;r+=32768)n.push(String.fromCharCode.apply(null,t.subarray(r,r+32768)));return btoa(n.join("")).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")};var Se;Uint8Array.fromBase64?Se=e=>{try{return Uint8Array.fromBase64(e,{alphabet:"base64url"})}catch(t){throw y("The input to be decoded is not correctly encoded.",R,t)}}:Se=e=>{try{let t=atob(e.replace(/-/g,"+").replace(/_/g,"/").replace(/\s/g,"")),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}catch(t){throw y("The input to be decoded is not correctly encoded.",R,t)}};function J(e){return typeof e=="string"?Se(e):Ae(e)}var w=class extends Error{code;constructor(t,n){super(t,n),this.name=this.constructor.name,this.code=pe,Error.captureStackTrace?.(this,this.constructor)}},M=class extends Error{code;constructor(t,n){super(t,n),this.name=this.constructor.name,n?.code&&(this.code=n?.code),Error.captureStackTrace?.(this,this.constructor)}};function h(e,t,n){return new M(e,{code:t,cause:n})}function N(e){return!(e===null||typeof e!="object"||Array.isArray(e))}function ke(e){$(e,Headers)&&(e=Object.fromEntries(e.entries()));let t=new Headers(e??{});if(Ee&&!t.has("user-agent")&&t.set("user-agent",Ee),t.has("authorization"))throw y('"options.headers" must not include the "authorization" header name',R);return t}function tt(e,t){if(t!==void 0){if(typeof t=="function"&&(t=t(e.href)),!(t instanceof AbortSignal))throw y('"options.signal" must return or be an instance of AbortSignal',E);return t}}function se(e,t,n,r,o){try{if(typeof e!="number"||!Number.isFinite(e))throw y(`${n} must be a number`,E,o);if(e>0)return;if(t){if(e!==0)throw y(`${n} must be a non-negative number`,R,o);return}throw y(`${n} must be a positive number`,R,o)}catch(s){throw r?h(s.message,r,o):s}}function _(e,t,n,r){try{if(typeof e!="string")throw y(`${t} must be a string`,E,r);if(e.length===0)throw y(`${t} must not be empty`,R,r)}catch(o){throw n?h(o.message,n,r):o}}function nt(e){en(e,"application/json")}function rt(e,...t){let n='"response" content-type must be ';if(t.length>2){let r=t.pop();n+=`${t.join(", ")}, or ${r}`}else t.length===2?n+=`${t[0]} or ${t[1]}`:n+=t[0];return h(n,De,e)}function Xt(e,...t){if(!t.includes(le(e)))throw rt(e,...t)}function en(e,t){if(le(e)!==t)throw rt(e,t)}function xe(){return J(crypto.getRandomValues(new Uint8Array(32)))}function ot(){return xe()}function at(){return xe()}function st(){return xe()}async function it(e){return _(e,"codeVerifier"),J(await crypto.subtle.digest("SHA-256",K(e)))}function ct(e){let t=e?.[de];return typeof t=="number"&&Number.isFinite(t)?t:0}function ut(e){let t=e?.[he];return typeof t=="number"&&Number.isFinite(t)&&Math.sign(t)!==-1?t:30}function W(){return Math.floor(Date.now()/1e3)}function C(e){if(typeof e!="object"||e===null)throw y('"as" must be an object',E);_(e.issuer,'"as.issuer"')}function F(e){if(typeof e!="object"||e===null)throw y('"client" must be an object',E);_(e.client_id,'"client.client_id"')}function Oe(e){return _(e,'"clientSecret"'),(t,n,r,o)=>{r.set("client_id",n.client_id),r.set("client_secret",e)}}function dt(){return(e,t,n,r)=>{n.set("client_id",t.client_id)}}var tn=URL.parse?(e,t)=>URL.parse(e,t):(e,t)=>{try{return new URL(e,t)}catch{return null}};function ht(e,t){if(t&&e.protocol!=="https:")throw h("only requests to HTTPS are allowed",Le,e);if(e.protocol!=="https:"&&e.protocol!=="http:")throw h("only HTTP and HTTPS requests are allowed",Ue,e)}function Qe(e,t,n,r){let o;if(typeof e!="string"||!(o=tn(e)))throw h(`authorization server metadata does not contain a valid ${n?`"as.mtls_endpoint_aliases.${t}"`:`"as.${t}"`}`,e===void 0?xn:On,{attribute:n?`mtls_endpoint_aliases.${t}`:t});return ht(o,r),o}function Y(e,t,n,r){return n&&e.mtls_endpoint_aliases&&t in e.mtls_endpoint_aliases?Qe(e.mtls_endpoint_aliases[t],t,n,r):Qe(e[t],t,n,r)}function lt(e){return e instanceof q?e.cause.some(t=>t.scheme==="dpop"&&t.parameters.error==="use_dpop_nonce"):e instanceof z?e.error==="use_dpop_nonce":!1}var z=class extends Error{cause;code;error;status;error_description;response;constructor(t,n){super(t,n),this.name=this.constructor.name,this.code=In,this.cause=n.cause,this.error=n.cause.error,this.status=n.response.status,this.error_description=n.cause.error_description,Object.defineProperty(this,"response",{enumerable:!1,value:n.response}),Error.captureStackTrace?.(this,this.constructor)}},V=class extends Error{cause;code;error;error_description;constructor(t,n){super(t,n),this.name=this.constructor.name,this.code=kn,this.cause=n.cause,this.error=n.cause.get("error"),this.error_description=n.cause.get("error_description")??void 0,Error.captureStackTrace?.(this,this.constructor)}},q=class extends Error{cause;code;response;status;constructor(t,n){super(t,n),this.name=this.constructor.name,this.code=Tn,this.cause=n.cause,this.status=n.response.status,this.response=n.response,Object.defineProperty(this,"response",{enumerable:!1}),Error.captureStackTrace?.(this,this.constructor)}},ie="[a-zA-Z0-9!#$%&\\'\\*\\+\\-\\.\\^_`\\|~]+",nn="[a-zA-Z0-9\\-\\._\\~\\+\\/]+={0,2}",rn='"((?:[^"\\\\]|\\\\[\\s\\S])*)"',on="("+ie+")\\s*=\\s*"+rn,an="("+ie+")\\s*=\\s*("+ie+")",sn=new RegExp("^[,\\s]*("+ie+")"),cn=new RegExp("^[,\\s]*"+on+"[,\\s]*(.*)"),un=new RegExp("^[,\\s]*"+an+"[,\\s]*(.*)"),dn=new RegExp("^("+nn+")(?:$|[,\\s])(.*)");function hn(e){if(!$(e,Response))throw y('"response" must be an instance of Response',E);let t=e.headers.get("www-authenticate");if(t===null)return;let n=[],r=t;for(;r;){let o=r.match(sn),s=o?.[1].toLowerCase();if(!s)return;let a=r.substring(o[0].length);if(a&&!a.match(/^[\s,]/))return;let i=a.match(/^\s+(.*)$/),c=!!i;r=i?i[1]:void 0;let u={},d;if(c)for(;r;){let m,p;if(o=r.match(cn)){[,m,p,r]=o,p.includes("\\")&&(p=p.replace(/\\([\s\S])/g,"$1")),u[m.toLowerCase()]=p;continue}if(o=r.match(un)){[,m,p,r]=o,u[m.toLowerCase()]=p;continue}if(o=r.match(dn)){if(Object.keys(u).length)break;[,d,r]=o;break}return}else r=a||void 0;let l={scheme:s,parameters:u};d&&(l.token68=d),n.push(l)}if(n.length)return n}async function ln(e){if(e.status>399&&e.status<500){He(e),nt(e);try{let t=await e.clone().json();if(N(t)&&typeof t.error=="string"&&t.error.length)return t}catch{}}}async function ft(e,t,n){if(e.status!==t){mn(e);let r;throw(r=await ln(e))?(await e.body?.cancel(),new z("server responded with an error in the response body",{cause:r,response:e})):h(`"response" is not a conform ${n} response (unexpected HTTP status code)`,me,e)}}function fn(e){if(!Ce.has(e))throw y('"options.DPoP" is not a valid DPoPHandle',R)}var H,ae,be;function Pe(e,t,n,r){H||=new WeakMap,H.set(e,{jwks:t,uat:n,get age(){return W()-this.uat}}),r&&Object.assign(r,{jwks:structuredClone(t),uat:n})}function pn(e){return!(typeof e!="object"||e===null||!("uat"in e)||typeof e.uat!="number"||W()-e.uat>=300||!("jwks"in e)||!N(e.jwks)||!Array.isArray(e.jwks.keys)||!Array.prototype.every.call(e.jwks.keys,N))}function Ze(e,t){H?.delete(e),delete t?.jwks,delete t?.uat}async function Te(e,t,n){let{alg:r,kid:o}=n;Dn(n),!H?.has(e)&&pn(t?.[P])&&Pe(e,t?.[P].jwks,t?.[P].uat);let s,a;if(H?.has(e)){if({jwks:s,age:a}=H.get(e),a>=300)return Ze(e,t?.[P]),Te(e,t,n)}else{let p=await Nn(e,t);s=p.jwks,a=W()-p.uat,Pe(e,s,p.uat,t?.[P])}let i;switch(r.slice(0,2)){case"RS":case"PS":i="RSA";break;case"ES":i="EC";break;case"Ed":i="OKP";break;case"ML":i="AKP";break;default:throw new w("unsupported JWS algorithm",{cause:{alg:r}})}let c=s.keys.filter(p=>{if(p.kty!==i||o!==void 0&&o!==p.kid||p.alg!==void 0&&r!==p.alg||p.use!==void 0&&p.use!=="sig"||p.key_ops?.includes("verify")===!1)return!1;switch(!0){case(r==="ES256"&&p.crv!=="P-256"):case(r==="ES384"&&p.crv!=="P-384"):case(r==="ES512"&&p.crv!=="P-521"):case(r==="Ed25519"&&p.crv!=="Ed25519"):case(r==="EdDSA"&&p.crv!=="Ed25519"):return!1}return!0}),{0:u,length:d}=c;if(!d){if(a>=60)return Ze(e,t?.[P]),Te(e,t,n);throw h("error when selecting a JWT verification key, no applicable keys found",Xe,{header:n,candidates:c,jwks_uri:new URL(e.jwks_uri)})}if(d!==1)throw h('error when selecting a JWT verification key, multiple applicable keys found, a "kid" JWT Header Parameter is required',Xe,{header:n,candidates:c,jwks_uri:new URL(e.jwks_uri)});be||=new WeakMap;let l=be.get(u);l||(l=new Map,be.set(u,l));let m=l.get(r);return m||(m=Kn(r,u).catch(p=>{throw l.delete(r),p}),l.set(r,m)),m}function le(e){return e.headers.get("content-type")?.split(";")[0]}async function pt(e,t,n,r,o,s,a){return await n(e,t,o,s),s.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"),(a?.[k]||fetch)(r.href,{body:o,headers:Object.fromEntries(s.entries()),method:"POST",redirect:"manual",signal:tt(r,a?.signal)})}async function mt(e,t,n,r,o,s){let a=Y(e,"token_endpoint",t.use_mtls_endpoint_aliases,s?.[I]!==!0);o.set("grant_type",r);let i=ke(s?.headers);i.set("accept","application/json"),s?.DPoP!==void 0&&(fn(s.DPoP),await s.DPoP.addProof(a,i,"POST"));let c=await pt(e,t,n,a,o,i,s);return s?.DPoP?.cacheNonce(c,a),c}async function yt(e,t,n,r,o){C(e),F(t),_(r,'"refreshToken"');let s=new URLSearchParams(o?.additionalParameters);return s.set("refresh_token",r),mt(e,t,n,"refresh_token",s,o)}var wt=new WeakMap,Ie=new WeakMap;function fe(e){if(!e.id_token)return;let t=wt.get(e);if(!t)throw y('"ref" was already garbage collected or did not resolve from the proper sources',R);return t}async function _t(e,t,n){if(C(e),!Ie.has(t))throw y('"ref" does not contain a processed JWT Response to verify the signature of',R);let{0:r,1:o,2:s}=Ie.get(t).split("."),a=JSON.parse(K(J(r)));if(a.alg.startsWith("HS"))throw new w("unsupported JWS algorithm",{cause:{alg:a.alg}});let i;i=await Te(e,n,a),await Hn(r,o,i,J(s))}async function Ne(e,t,n,r,o,s){if(C(e),F(t),!$(n,Response))throw y('"response" must be an instance of Response',E);await ft(n,200,"Token Endpoint"),He(n);let a=await Ct(n);if(_(a.access_token,'"response" body "access_token" property',f,{body:a}),_(a.token_type,'"response" body "token_type" property',f,{body:a}),a.token_type=a.token_type.toLowerCase(),a.expires_in!==void 0){let i=typeof a.expires_in!="number"?parseFloat(a.expires_in):a.expires_in;se(i,!0,'"response" body "expires_in" property',f,{body:a}),a.expires_in=i}if(a.refresh_token!==void 0&&_(a.refresh_token,'"response" body "refresh_token" property',f,{body:a}),a.scope!==void 0&&typeof a.scope!="string")throw h('"response" body "scope" property must be a string',f,{body:a});if(a.id_token!==void 0){_(a.id_token,'"response" body "id_token" property',f,{body:a});let i=[];t.require_auth_time===!0&&i.push("auth_time"),t.default_max_age!==void 0&&(se(t.default_max_age,!0,'"client.default_max_age"'),i.push("auth_time")),r?.length&&i.push(...r);let{claims:c,jwt:u}=await bn(e,t,a.id_token,i,o);An(t,c),En(c),Ie.set(n,u),wt.set(a,c)}if(s?.[a.token_type]!==void 0)s[a.token_type](n,a);else if(a.token_type!=="dpop"&&a.token_type!=="bearer")throw new w("unsupported `token_type` value",{cause:{body:a}});return a}function mn(e){let t;if(t=hn(e))throw new q("server responded with a challenge in the WWW-Authenticate HTTP Header",{cause:t,response:e})}async function gt(e,t,n,r){return Ne(e,t,n,void 0,r?.[j],r?.recognizedTokenTypes)}function yn(e,t){if(Array.isArray(t.claims.aud)){if(!t.claims.aud.includes(e))throw h('unexpected JWT "aud" (audience) claim value',T,{expected:e,claims:t.claims,claim:"aud"})}else if(t.claims.aud!==e)throw h('unexpected JWT "aud" (audience) claim value',T,{expected:e,claims:t.claims,claim:"aud"});return t}function wn(e,t){let n=e[je]?.(t)??e.issuer;if(t.claims.iss!==n)throw h('unexpected JWT "iss" (issuer) claim value',T,{expected:n,claims:t.claims,claim:"iss"});return t}var Ce=new WeakSet;function _n(e){return Ce.add(e),e}var ve=Symbol();async function Rt(e,t,n,r,o,s,a){if(C(e),F(t),!Ce.has(r))throw y('"callbackParameters" must be an instance of URLSearchParams obtained from "validateAuthResponse()", or "validateJwtAuthResponse()',R);_(o,'"redirectUri"');let i=O(r,"code");if(!i)throw h('no authorization code in "callbackParameters"',f);let c=new URLSearchParams(a?.additionalParameters);return c.set("redirect_uri",o),c.set("code",i),s!==ve&&(_(s,'"codeVerifier"'),c.set("code_verifier",s)),mt(e,t,n,"authorization_code",c,a)}var bt={aud:"audience",c_hash:"code hash",client_id:"client id",exp:"expiration time",iat:"issued at",iss:"issuer",jti:"jwt id",nonce:"nonce",s_hash:"state hash",sub:"subject",ath:"access token hash",htm:"http method",htu:"http uri",cnf:"confirmation",auth_time:"authentication time"};function gn(e,t){for(let n of e)if(t.claims[n]===void 0)throw h(`JWT "${n}" (${bt[n]}) claim missing`,f,{claims:t.claims});return t}function Rn(e,t){if(typeof t.claims[e]!="string")throw h(`unexpected JWT "${e}" (${bt[e]}) claim type`,f,{claims:t.claims});return t}function bn(e,t,n,r,o){return jn(n,zn.bind(void 0,t.id_token_signed_response_alg,e.id_token_signing_alg_values_supported,"RS256"),ct(t),ut(t),o).then(gn.bind(void 0,["aud","exp","iat","iss","sub",...r])).then(wn.bind(void 0,e)).then(yn.bind(void 0,t.client_id)).then(Rn.bind(void 0,"sub"))}function Et(e,t){if(t===ue)return t;let n=t===void 0;return n&&(t=e.default_max_age),t===void 0?ue:(se(t,!0,n?'"client.default_max_age"':'"maxAge" argument'),t)}function En(e){e.auth_time!==void 0&&se(e.auth_time,!0,'ID Token "auth_time" (authentication time)',f,{claims:e})}function At(e,t,n){if(n===ue)return;let r=W()+ct(e),o=ut(e);if(t.auth_time+n<r-o)throw h("too much time has elapsed since the last End-User authentication",B,{claims:t,now:r,tolerance:o,claim:"auth_time"})}function St(e,t){let n=t===ce?void 0:t;if(e.nonce!==n)throw h('unexpected ID Token "nonce" claim value',T,{expected:n,claims:e,claim:"nonce"})}function An(e,t){if(Array.isArray(t.aud)&&t.aud.length!==1){if(t.azp===void 0)throw h('ID Token "aud" (audience) claim includes additional untrusted audiences',T,{claims:t,claim:"aud"});if(t.azp!==e.client_id)throw h('unexpected ID Token "azp" (authorized party) claim value',T,{expected:e.client_id,claims:t,claim:"azp"})}}var ce=Symbol(),ue=Symbol();async function Pt(e,t,n,r){return typeof r?.expectedNonce=="string"||typeof r?.maxAge=="number"||r?.requireIdToken?Sn(e,t,n,r.expectedNonce,r.maxAge,r[j],r.recognizedTokenTypes):Pn(e,t,n,r?.maxAge,r?.[j],r?.recognizedTokenTypes)}async function Sn(e,t,n,r,o,s,a){let i=[];switch(r){case void 0:r=ce;break;case ce:break;default:_(r,'"expectedNonce" argument'),i.push("nonce")}o=Et(t,o),o!==ue&&i.push("auth_time");let c=await Ne(e,t,n,i,s,a);_(c.id_token,'"response" body "id_token" property',f,{body:c});let u=fe(c);return At(t,u,o),St(u,r),c}async function Pn(e,t,n,r,o,s){let a=await Ne(e,t,n,void 0,o,s),i=fe(a);return i&&(At(t,i,Et(t,r)),St(i,ce)),a}var Tn="OAUTH_WWW_AUTHENTICATE_CHALLENGE",In="OAUTH_RESPONSE_BODY_ERROR",pe="OAUTH_UNSUPPORTED_OPERATION",kn="OAUTH_AUTHORIZATION_RESPONSE_ERROR";var G="OAUTH_PARSE_ERROR",f="OAUTH_INVALID_RESPONSE";var De="OAUTH_RESPONSE_IS_NOT_JSON",me="OAUTH_RESPONSE_IS_NOT_CONFORM",Le="OAUTH_HTTP_REQUEST_FORBIDDEN",Ue="OAUTH_REQUEST_PROTOCOL_FORBIDDEN",B="OAUTH_JWT_TIMESTAMP_CHECK_FAILED",T="OAUTH_JWT_CLAIM_COMPARISON_FAILED",Tt="OAUTH_JSON_ATTRIBUTE_COMPARISON_FAILED",Xe="OAUTH_KEY_SELECTION_FAILED",xn="OAUTH_MISSING_SERVER_METADATA",On="OAUTH_INVALID_SERVER_METADATA";async function It(e,t,n,r,o){C(e),F(t),_(r,'"token"');let s=Y(e,"revocation_endpoint",t.use_mtls_endpoint_aliases,o?.[I]!==!0),a=new URLSearchParams(o?.additionalParameters);a.set("token",r);let i=ke(o?.headers);return i.delete("accept"),pt(e,t,n,s,a,i,o)}async function kt(e){if(!$(e,Response))throw y('"response" must be an instance of Response',E);await ft(e,200,"Revocation Endpoint")}function He(e){if(e.bodyUsed)throw y('"response" body has been used already',R)}async function Nn(e,t){C(e);let n=Y(e,"jwks_uri",!1,t?.[I]!==!0),r=ke(t?.headers);r.set("accept","application/json"),r.append("accept","application/jwk-set+json");let o=Object.fromEntries(r.entries()),s=JSON.stringify(o),a=t?.[k]||fetch,i=tt(n,t?.signal);ae||=new WeakMap;let c=ae.get(e)??new Set;for(let d of c)if(d.url===n.href&&d.headers===s&&d.fetch===a&&d.signal===i)return d.promise;let u={url:n.href,headers:s,fetch:a,signal:i,promise:Promise.resolve().then(()=>a(n.href,{body:void 0,headers:o,method:"GET",redirect:"manual",signal:i})).then(Cn).then(d=>{let l=W();return Pe(e,d,l),{jwks:d,uat:l}}).finally(()=>{c.delete(u),c.size||ae.delete(e)})};return c.add(u),ae.set(e,c),u.promise}async function Cn(e){if(!$(e,Response))throw y('"response" must be an instance of Response',E);if(e.status!==200)throw h('"response" is not a conform JSON Web Key Set response (unexpected HTTP status code)',me,e);He(e);let t=await Ct(e,n=>Xt(n,"application/json","application/jwk-set+json"));if(!Array.isArray(t.keys))throw h('"response" body "keys" property must be an array',f,{body:t});if(!Array.prototype.every.call(t.keys,N))throw h('"response" body "keys" property members must be JWK formatted objects',f,{body:t});return t}function vn(e){switch(e){case"PS256":case"ES256":case"RS256":case"PS384":case"ES384":case"RS384":case"PS512":case"ES512":case"RS512":case"Ed25519":case"EdDSA":case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return!0;default:return!1}}function Dn(e){if(!vn(e.alg))throw new w('unsupported JWS "alg" identifier',{cause:{alg:e.alg}})}function et(e){let{algorithm:t}=e;if(typeof t.modulusLength!="number"||t.modulusLength<2048)throw new w(`unsupported ${t.name} modulusLength`,{cause:e})}function Ln(e){let{algorithm:t}=e;switch(t.namedCurve){case"P-256":return"SHA-256";case"P-384":return"SHA-384";case"P-521":return"SHA-512";default:throw new w("unsupported ECDSA namedCurve",{cause:e})}}function Un(e){switch(e.algorithm.name){case"ECDSA":return{name:e.algorithm.name,hash:Ln(e)};case"RSA-PSS":switch(et(e),e.algorithm.hash.name){case"SHA-256":case"SHA-384":case"SHA-512":return{name:e.algorithm.name,saltLength:parseInt(e.algorithm.hash.name.slice(-3),10)>>3};default:throw new w("unsupported RSA-PSS hash name",{cause:e})}case"RSASSA-PKCS1-v1_5":return et(e),e.algorithm.name;case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":case"Ed25519":return e.algorithm.name}throw new w("unsupported CryptoKey algorithm name",{cause:e})}async function Hn(e,t,n,r){let o=K(`${e}.${t}`),s=Un(n);if(!await crypto.subtle.verify(s,n,r,o))throw h("JWT signature verification failed",f,{key:n,data:o,signature:r,algorithm:s})}async function jn(e,t,n,r,o){let{0:s,1:a,length:i}=e.split(".");if(i===5)if(o!==void 0)e=await o(e),{0:s,1:a,length:i}=e.split(".");else throw new w("JWE decryption is not configured",{cause:e});if(i!==3)throw h("Invalid JWT",f,e);let c;try{c=JSON.parse(K(J(s)))}catch(l){throw h("failed to parse JWT Header body as base64url encoded JSON",G,l)}if(!N(c))throw h("JWT Header must be a top level object",f,e);if(t(c),c.crit!==void 0)throw new w('no JWT "crit" header parameter extensions are supported',{cause:{header:c}});let u;try{u=JSON.parse(K(J(a)))}catch(l){throw h("failed to parse JWT Payload body as base64url encoded JSON",G,l)}if(!N(u))throw h("JWT Payload must be a top level object",f,e);let d=W()+n;if(u.exp!==void 0){if(typeof u.exp!="number")throw h('unexpected JWT "exp" (expiration time) claim type',f,{claims:u});if(u.exp<=d-r)throw h('unexpected JWT "exp" (expiration time) claim value, expiration is past current timestamp',B,{claims:u,now:d,tolerance:r,claim:"exp"})}if(u.iat!==void 0&&typeof u.iat!="number")throw h('unexpected JWT "iat" (issued at) claim type',f,{claims:u});if(u.iss!==void 0&&typeof u.iss!="string")throw h('unexpected JWT "iss" (issuer) claim type',f,{claims:u});if(u.nbf!==void 0){if(typeof u.nbf!="number")throw h('unexpected JWT "nbf" (not before) claim type',f,{claims:u});if(u.nbf>d+r)throw h('unexpected JWT "nbf" (not before) claim value',B,{claims:u,now:d,tolerance:r,claim:"nbf"})}if(u.aud!==void 0&&typeof u.aud!="string"&&!Array.isArray(u.aud))throw h('unexpected JWT "aud" (audience) claim type',f,{claims:u});return{header:c,claims:u,jwt:e}}async function Jn(e){if(e.bodyUsed)throw y("form_post Request instances must contain a readable body",R,{cause:e});return e.text()}async function xt(e){if(e.method!=="POST")throw y("form_post responses are expected to use the POST method",R,{cause:e});if(le(e)!=="application/x-www-form-urlencoded")throw y("form_post responses are expected to use the application/x-www-form-urlencoded content-type",R,{cause:e});return Jn(e)}function zn(e,t,n,r){if(e!==void 0){if(typeof e=="string"?r.alg!==e:!e.includes(r.alg))throw h('unexpected JWT "alg" header parameter',f,{header:r,expected:e,reason:"client configuration"});return}if(Array.isArray(t)){if(!t.includes(r.alg))throw h('unexpected JWT "alg" header parameter',f,{header:r,expected:t,reason:"authorization server metadata"});return}if(n!==void 0){if(typeof n=="string"?r.alg!==n:typeof n=="function"?!n(r.alg):!n.includes(r.alg))throw h('unexpected JWT "alg" header parameter',f,{header:r,expected:n,reason:"default value"});return}throw h('missing client or server configuration to verify used JWT "alg" header parameter',void 0,{client:e,issuer:t,fallback:n})}function O(e,t){let{0:n,length:r}=e.getAll(t);if(r>1)throw h(`"${t}" parameter must be provided only once`,f);return n}var Ot=Symbol(),qn=Symbol();function Nt(e,t,n,r){if(C(e),F(t),n instanceof URL&&(n=n.searchParams),!(n instanceof URLSearchParams))throw y('"parameters" must be an instance of URLSearchParams, or URL',E);if(O(n,"response"))throw h('"parameters" contains a JARM response, use validateJwtAuthResponse() instead of validateAuthResponse()',f,{parameters:n});let o=O(n,"iss"),s=O(n,"state");if(!o&&e.authorization_response_iss_parameter_supported)throw h('response parameter "iss" (issuer) missing',f,{parameters:n});if(o&&o!==e.issuer)throw h('unexpected "iss" (issuer) response parameter value',f,{expected:e.issuer,parameters:n});switch(r){case void 0:case qn:if(s!==void 0)throw h('unexpected "state" response parameter encountered',f,{expected:void 0,parameters:n});break;case Ot:break;default:if(_(r,'"expectedState" argument'),s!==r)throw h(s===void 0?'response parameter "state" missing':'unexpected "state" response parameter value',f,{expected:r,parameters:n})}if(O(n,"error"))throw new V("authorization response from the server is an error",{cause:n});let i=O(n,"id_token"),c=O(n,"token");if(i!==void 0||c!==void 0)throw new w("implicit and hybrid flows are not supported");return _n(new URLSearchParams(n))}function Wn(e){switch(e){case"PS256":case"PS384":case"PS512":return{name:"RSA-PSS",hash:`SHA-${e.slice(-3)}`};case"RS256":case"RS384":case"RS512":return{name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.slice(-3)}`};case"ES256":case"ES384":return{name:"ECDSA",namedCurve:`P-${e.slice(-3)}`};case"ES512":return{name:"ECDSA",namedCurve:"P-521"};case"EdDSA":return"Ed25519";case"Ed25519":case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return e;default:throw new w("unsupported JWS algorithm",{cause:{alg:e}})}}async function Kn(e,t){let{ext:n,key_ops:r,use:o,...s}=t;return crypto.subtle.importKey("jwk",s,Wn(e),!0,["verify"])}async function Ct(e,t=nt){let n;try{n=await e.json()}catch(r){throw t(e),h('failed to parse "response" body as JSON',G,r)}if(!N(n))throw h('"response" body must be a top level object',f,{body:n});return n}var je=Symbol();var X,vt;(typeof navigator>"u"||!navigator.userAgent?.startsWith?.("Mozilla/5.0 "))&&(vt="openid-client/v6.8.7",X={"user-agent":vt});var b=e=>ze.get(e),ze,Je;function Vn(e){return e!==void 0?Oe(e):(Je||=new WeakMap,(t,n,r,o)=>{let s;return(s=Je.get(n))||(Gn(n.client_secret,'"metadata.client_secret"'),s=Oe(n.client_secret),Je.set(n,s)),s(t,n,r,o)})}function Gn(e,t){if(typeof e!="string")throw A(`${t} must be a string`,we);if(e.length===0)throw A(`${t} must not be empty`,ee)}function qe(){return dt()}var ye=k;var ee="ERR_INVALID_ARG_VALUE",we="ERR_INVALID_ARG_TYPE";function A(e,t,n){let r=new TypeError(e,{cause:n});return Object.assign(r,{code:t}),r}function Dt(e){return it(e)}function Lt(){return ot()}function Ut(){return st()}function Ht(){return at()}var Z=class extends Error{code;constructor(t,n){super(t,n),this.name=this.constructor.name,this.code=n?.code,Error.captureStackTrace?.(this,this.constructor)}},mo=new TextDecoder;function g(e,t,n){return new Z(e,{cause:t,code:n})}function v(e){if(e instanceof TypeError||e instanceof Z||e instanceof z||e instanceof V||e instanceof q)throw e;if(e instanceof M)switch(e.code){case Le:throw g("only requests to HTTPS are allowed",e,e.code);case Ue:throw g("only requests to HTTP or HTTPS are allowed",e,e.code);case me:throw g("unexpected HTTP response status code",e.cause,e.code);case De:throw g("unexpected response content-type",e.cause,e.code);case G:throw g("parsing error occured",e,e.code);case f:throw g("invalid response encountered",e,e.code);case T:throw g("unexpected JWT claim value encountered",e,e.code);case Tt:throw g("unexpected JSON attribute value encountered",e,e.code);case B:throw g("JWT timestamp claim value failed validation",e,e.code);default:throw g(e.message,e,e.code)}if(e instanceof w)throw g("unsupported operation",e,e.code);if(e instanceof DOMException)switch(e.name){case"OperationError":throw g("runtime operation error",e,pe);case"NotSupportedError":throw g("runtime unsupported operation",e,pe);case"TimeoutError":throw g("operation timed out",e,"OAUTH_TIMEOUT");case"AbortError":throw g("operation aborted",e,"OAUTH_ABORT")}throw new Z("something went wrong",{cause:e})}function Bn(e){return{supportsPKCE:{__proto__:null,value(t="S256"){return e.code_challenge_methods_supported?.includes(t)===!0}}}}function $n(e){Object.defineProperties(e,Bn(e))}var Fn=Symbol(),D=class{constructor(t,n,r,o){if(typeof n!="string"||!n.length)throw A('"clientId" must be a non-empty string',we);if(typeof r=="string"&&(r={client_secret:r}),r?.client_id!==void 0&&n!==r.client_id)throw A('"clientId" and "metadata.client_id" must be the same',ee);let s={...structuredClone(r),client_id:n};s[de]=r?.[de]??0,s[he]=r?.[he]??30;let a;o?a=o:typeof s.client_secret=="string"&&s.client_secret.length?a=Vn(s.client_secret):a=qe();let i=Object.freeze(s),c=structuredClone(t);Fn in t&&(c[je]=({claims:{tid:d}})=>t.issuer.replace("{tenantid}",d));let u=Object.freeze(c);ze||=new WeakMap,ze.set(this,{__proto__:null,as:u,c:i,auth:a,tlsOnly:!0,jwksCache:{}})}serverMetadata(){let t=structuredClone(b(this).as);return $n(t),t}clientMetadata(){return structuredClone(b(this).c)}get timeout(){return b(this).timeout}set timeout(t){b(this).timeout=t}get[ye](){return b(this).fetch}set[ye](t){b(this).fetch=t}};Object.freeze(D.prototype);function Yn(e){let t;if(e.expires_in!==void 0){let n=new Date;n.setSeconds(n.getSeconds()+e.expires_in),t=n.getTime()}return{expiresIn:{__proto__:null,value(){if(t){let n=Date.now();return t>n?Math.floor((t-n)/1e3):0}}},claims:{__proto__:null,value(){return fe(e)}}}}function jt(e){Object.defineProperties(e,Yn(e))}function Jt(e){te(e),b(e).nonRepudiation=t=>{let{as:n,fetch:r,tlsOnly:o,timeout:s,jwksCache:a}=b(e);return _t(n,t,{[k]:r,[I]:!o,headers:new Headers(X),signal:_e(s),[P]:a}).catch(v)}}function Qn(e){return e=new URL(e),e.search="",e.hash="",e.href}function Zn(e,t){try{return Object.getPrototypeOf(e)[Symbol.toStringTag]===t}catch{return!1}}async function We(e,t,n,r,o){if(te(e),o?.flag!==Q&&!(t instanceof URL)&&!Zn(t,"Request"))throw A('"currentUrl" must be an instance of URL, or Request',we);let s,a,{as:i,c,auth:u,fetch:d,tlsOnly:l,jarm:m,hybrid:p,nonRepudiation:L,timeout:re,decrypt:Mt,implicit:Vt}=b(e);if(o?.flag===Q)s=o.authResponse,a=o.redirectUri;else{if(!(t instanceof URL)){let x=t;switch(t=new URL(t.url),x.method){case"GET":break;case"POST":let Ge=new URLSearchParams(await xt(x));if(p)t.hash=Ge.toString();else for(let[Bt,$t]of Ge.entries())t.searchParams.append(Bt,$t);break;default:throw A("unexpected Request HTTP method",ee)}}switch(a=Qn(t),!0){case!!m:s=await m(t,n?.expectedState);break;case!!p:s=await p(t,n?.expectedNonce,n?.expectedState,n?.maxAge);break;case!!Vt:throw new TypeError("authorizationCodeGrant() cannot be used by response_type=id_token clients");default:try{s=Nt(i,c,t.searchParams,n?.expectedState)}catch(x){v(x)}}}let Ve=await Rt(i,c,u,s,a,n?.pkceCodeVerifier||ve,{additionalParameters:r,[k]:d,[I]:!l,DPoP:o?.DPoP,headers:new Headers(X),signal:_e(re)}).catch(v);(typeof n?.expectedNonce=="string"||typeof n?.maxAge=="number")&&(n.idTokenExpected=!0);let Gt=Pt(i,c,Ve,{expectedNonce:n?.expectedNonce,maxAge:n?.maxAge,requireIdToken:n?.idTokenExpected,[j]:Mt}),oe;try{oe=await Gt}catch(x){if(qt(x,o))return We(e,void 0,n,r,{...o,flag:Q,authResponse:s,redirectUri:a});v(x)}return oe.id_token&&await L?.(Ve),jt(oe),oe}async function Ke(e,t,n,r){te(e),n=new URLSearchParams(n);let{as:o,c:s,auth:a,fetch:i,tlsOnly:c,nonRepudiation:u,timeout:d,decrypt:l}=b(e),m=await yt(o,s,a,t,{[k]:i,[I]:!c,additionalParameters:n,DPoP:r?.DPoP,headers:new Headers(X),signal:_e(d)}).catch(v),p=gt(o,s,m,{[j]:l}),L;try{L=await p}catch(re){if(qt(re,r))return Ke(e,t,n,{...r,flag:Q});v(re)}return L.id_token&&await u?.(m),jt(L),L}function zt(e,t){te(e);let{as:n,c:r,tlsOnly:o,hybrid:s,jarm:a,implicit:i}=b(e),c=Y(n,"authorization_endpoint",!1,o);if(t=new URLSearchParams(t),t.has("client_id")||t.set("client_id",r.client_id),!t.has("request_uri")&&!t.has("request")){if(t.has("response_type")||t.set("response_type",s?"code id_token":i?"id_token":"code"),i&&!t.has("nonce"))throw A("response_type=id_token clients must provide a nonce parameter in their authorization request parameters",ee);a&&t.set("response_mode","jwt")}for(let[u,d]of t.entries())c.searchParams.append(u,d);return c}function te(e){if(!(e instanceof D))throw A('"config" must be an instance of Configuration',we);if(Object.getPrototypeOf(e)!==D.prototype)throw A("subclassing Configuration is not allowed",ee)}function _e(e){return e?AbortSignal.timeout(e*1e3):void 0}function qt(e,t){return t?.DPoP&&t.flag!==Q?lt(e):!1}var Q=Symbol();async function Wt(e,t,n){te(e);let{as:r,c:o,auth:s,fetch:a,tlsOnly:i,timeout:c}=b(e);return It(r,o,s,t,{[k]:a,[I]:!i,additionalParameters:new URLSearchParams(n),headers:new Headers(X),signal:_e(c)}).then(kt).catch(v)}import{createServer as er}from"node:http";async function Kt(e,t,n){n.throwIfAborted();let r=new URL(e);if(r.protocol!=="http:"||r.hostname!=="127.0.0.1"||!r.port||r.search||r.hash||r.username||r.password)throw Error("DESKTOP_LOGIN_CALLBACK_INVALID");let o,s,a=!1,i=new Promise((d,l)=>{o=d,s=l});i.catch(()=>{});let c=er((d,l)=>{l.setHeader("cache-control","no-store"),l.setHeader("content-security-policy","default-src 'none'"),l.setHeader("content-type","text/plain; charset=utf-8");let m;try{m=new URL(d.url??"/",r.origin)}catch{l.writeHead(400).end("Invalid callback.");return}if(a||d.method!=="GET"||!["127.0.0.1","::ffff:127.0.0.1"].includes(d.socket.remoteAddress??"")||d.headers.host!==r.host||m.origin+m.pathname!==e||m.searchParams.getAll("state").length!==1||m.searchParams.get("state")!==t||m.searchParams.getAll("code").length!==1&&!m.searchParams.has("error")){l.writeHead(400).end("Invalid callback.");return}a=!0,l.end("Authorization received. Return to Native Engagement."),o(m)});c.maxConnections=4,c.requestTimeout=3e3,c.headersTimeout=3e3,c.keepAliveTimeout=1e3,c.maxHeadersCount=32;let u=()=>{s(Error("DESKTOP_LOGIN_CANCELLED")),c.close(),c.closeAllConnections()};n.addEventListener("abort",u,{once:!0});try{await new Promise((d,l)=>{c.once("error",l),c.listen({host:"127.0.0.1",port:Number(r.port),signal:n},()=>{c.removeListener("error",l),d()})})}catch(d){throw n.removeEventListener("abort",u),d}return{callback:i,async close(){n.removeEventListener("abort",u),c.closeAllConnections(),await new Promise(d=>c.close(()=>d()))}}}var Me=3e4,ne=class{installation;config;constructor(t,n=fetch){this.installation=t;let r=t,o=new URL(r.issuer);if(o.protocol!=="https:"||o.username||o.password||o.search||o.hash)throw Error("DESKTOP_LOGIN_CONFIGURATION_INVALID");for(let s of[r.authorizationEndpoint,r.tokenEndpoint,r.jwksUri,r.revocationEndpoint]){let a=new URL(s);if(a.origin!==o.origin||a.protocol!=="https:"||a.username||a.password||a.search||a.hash)throw Error("DESKTOP_LOGIN_CONFIGURATION_INVALID")}this.config=new D({issuer:r.issuer,authorization_endpoint:r.authorizationEndpoint,token_endpoint:r.tokenEndpoint,jwks_uri:r.jwksUri,revocation_endpoint:r.revocationEndpoint,response_types_supported:["code"],code_challenge_methods_supported:["S256"]},r.clientId,{token_endpoint_auth_method:"none"},qe()),this.config.timeout=Me/1e3,Jt(this.config),this.config[ye]=async(s,a)=>{if(![r.tokenEndpoint,r.jwksUri,r.revocationEndpoint].includes(String(s)))throw Error("DESKTOP_LOGIN_ENDPOINT_CHANGED");let{body:i,...c}=a;return n(s,{...c,...i!==void 0?{body:i instanceof Uint8Array?new Uint8Array(i).buffer:i}:{},redirect:"error",signal:a.signal?AbortSignal.any([a.signal,AbortSignal.timeout(Me)]):AbortSignal.timeout(Me)})}}async authorize(t,n){let r=this.installation,o=Ht(),s=Ut(),a=Lt(),i=await Kt(r.redirectUri,o,t);try{let c=zt(this.config,{redirect_uri:r.redirectUri,state:o,nonce:s,scope:r.scopes.join(" "),resource:r.resource,code_challenge:await Dt(a),code_challenge_method:"S256"});t.throwIfAborted(),await n(c.href);let u=await i.callback;t.throwIfAborted();let d=await We(this.config,u,{expectedState:o,expectedNonce:s,pkceCodeVerifier:a,idTokenExpected:!0},{resource:r.resource}),l=d.claims()?.sub,m=Number(d.expires_in);if(!d.access_token||!l||!Number.isSafeInteger(m)||m<1||m>86400)throw Error("DESKTOP_LOGIN_GRANT_INVALID");return{accessToken:d.access_token,refreshToken:d.refresh_token??null,subject:l,expiresAt:Date.now()+m*1e3}}finally{await i.close()}}async revoke(t){await Wt(this.config,t.refreshToken??t.accessToken,{token_type_hint:t.refreshToken?"refresh_token":"access_token"})}async refresh(t){if(!t.refreshToken)throw Error("DESKTOP_LOGIN_REQUIRED");let n=await Ke(this.config,t.refreshToken,{resource:this.installation.resource}),r=Number(n.expires_in),o=n.claims()?.sub??t.subject;if(!n.access_token||o!==t.subject||!Number.isSafeInteger(r)||r<1||r>86400)throw Error("DESKTOP_LOGIN_GRANT_INVALID");return{accessToken:n.access_token,refreshToken:n.refresh_token??t.refreshToken,subject:o,expiresAt:Date.now()+r*1e3}}};import{execFile as tr}from"node:child_process";var nr=new Set(["openid","engagement:read","engagement:write","work:read","asset:reader","message:draft"]);async function rr(e="https://engagement.shipkitx.com",t=fetch){let n=new URL(e);if(n.protocol!=="https:"||n.origin!==e||n.username||n.password)throw Error("NATIVE_PUBLIC_LOGIN_HTTPS_CENTER_REQUIRED");let r=await t(e+"/releases/cli-login.json",{redirect:"error",signal:AbortSignal.timeout(1e4)});if(!r.ok||!r.body||Number(r.headers.get("content-length"))>32768)throw Error("NATIVE_PUBLIC_LOGIN_CONFIGURATION_UNAVAILABLE");let o=r.body.getReader(),s=[],a=0;try{for(;;){let d=await o.read();if(d.done)break;if(a+=d.value.byteLength,a>32768)throw Error("NATIVE_PUBLIC_LOGIN_CONFIGURATION_TOO_LARGE");s.push(d.value)}}finally{await o.cancel().catch(()=>{})}let i;try{i=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(Buffer.concat(s)))}catch{throw Error("NATIVE_PUBLIC_LOGIN_CONFIGURATION_INVALID")}let c=i.result?.login;if(i.ok!==!0||i.result?.serviceOrigin!==e||!c||new URL(c.issuer).origin!==e||c.resource!==e+"/mcp"||c.clientId!=="native-engagement-cli"||!Array.isArray(c.scopes)||!c.scopes.includes("openid")||c.scopes.some(d=>!nr.has(d)))throw Error("NATIVE_PUBLIC_LOGIN_CONFIGURATION_INVALID");let u=new URL(c.redirectUri);if(u.protocol!=="http:"||u.hostname!=="127.0.0.1"||!u.port||u.username||u.password||u.search||u.hash)throw Error("NATIVE_PUBLIC_LOGIN_CALLBACK_INVALID");return new ne(c,t)}async function or(e){let t=new URL(e);if(t.protocol!=="https:"||t.username||t.password)throw Error("NATIVE_PUBLIC_LOGIN_AUTHORIZATION_URL_INVALID");let n=process.platform==="darwin"?"/usr/bin/open":process.platform==="win32"?"rundll32.exe":"/usr/bin/xdg-open",r=process.platform==="win32"?["url.dll,FileProtocolHandler",e]:[e];await new Promise((o,s)=>tr(n,r,{timeout:1e4,windowsHide:!0},a=>a?s(Error("NATIVE_PUBLIC_LOGIN_BROWSER_UNAVAILABLE")):o()))}export{ne as NativePublicLogin,U as RemoteNativeEngagementError,Fe as RemoteNativeEngagementSdk,rr as createNativePublicLogin,or as openNativeLoginPage,Yt as prospectClient};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@native-engagement/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "description": "Authenticated remote TypeScript client for Native Engagement",
6
6
  "engines": {
package/release.json CHANGED
@@ -1,7 +1,18 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "sourceCommit": "5402e30207f693b0a0e28cb49e54720b402e1db9",
3
+ "sourceCommit": "915a91b708bce3794bfdf49456c7e2e26444deca",
4
4
  "channel": "beta",
5
- "bundledComponents": [],
6
- "lockSha256": "421cbab359e454443023383a61d63b1fc9f562e79c4e7c5174b09bdfb640d76c"
5
+ "bundledComponents": [
6
+ {
7
+ "name": "oauth4webapi",
8
+ "version": "3.8.8",
9
+ "license": "MIT"
10
+ },
11
+ {
12
+ "name": "openid-client",
13
+ "version": "6.8.7",
14
+ "license": "MIT"
15
+ }
16
+ ],
17
+ "lockSha256": "73717ad8c76ee4d041f3dc4beb2e8118b1e8796d4bc999d926e450d06f068996"
7
18
  }