@workos-inc/node 10.7.0 → 10.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,7 +49,7 @@ var SubtleCryptoProvider = class extends CryptoProvider {
49
49
  return await crypto.subtle.verify(algorithm, key, hmac, bufferB);
50
50
  }
51
51
  async encrypt(plaintext, key, iv, aad) {
52
- const actualIv = iv || crypto.getRandomValues(new Uint8Array(32));
52
+ const actualIv = iv || crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));
53
53
  const cryptoKey = await this.subtleCrypto.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt"]);
54
54
  const encryptParams = {
55
55
  name: "AES-GCM",
@@ -95,23 +95,31 @@ var SubtleCryptoProvider = class extends CryptoProvider {
95
95
  };
96
96
  const byteHexMapping = new Array(256);
97
97
  for (let i = 0; i < byteHexMapping.length; i++) byteHexMapping[i] = i.toString(16).padStart(2, "0");
98
- //#endregion
99
- //#region src/common/net/http-client.ts
98
+ /**
99
+ * Upper bound on a server-provided `Retry-After` delay. Caps how long a
100
+ * single retry can sleep so an aggressive proxy or an HTTP-date far in the
101
+ * future can't hang the caller indefinitely.
102
+ */
103
+ const MAXIMUM_RETRY_AFTER_TIME_IN_MILLISECONDS = 6e4;
100
104
  var HttpClient = class HttpClient {
101
105
  baseURL;
102
106
  options;
103
- MAX_RETRY_ATTEMPTS = 3;
107
+ MAX_RETRY_ATTEMPTS;
104
108
  BACKOFF_MULTIPLIER = 1.5;
105
109
  MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;
110
+ MAXIMUM_SLEEP_TIME_IN_MILLISECONDS = 8e3;
106
111
  RETRY_STATUS_CODES = [
107
112
  408,
113
+ 429,
108
114
  500,
109
115
  502,
116
+ 503,
110
117
  504
111
118
  ];
112
119
  constructor(baseURL, options) {
113
120
  this.baseURL = baseURL;
114
121
  this.options = options;
122
+ this.MAX_RETRY_ATTEMPTS = options?.maxRetries ?? 3;
115
123
  }
116
124
  static getResourceURL(baseURL, path, params) {
117
125
  const queryString = HttpClient.getQueryString(params);
@@ -132,13 +140,38 @@ var HttpClient = class HttpClient {
132
140
  if (entity === null || entity instanceof URLSearchParams) return entity;
133
141
  return JSON.stringify(entity);
134
142
  }
135
- static isPathRetryable(path) {
136
- return path.startsWith("/vault/") || path.startsWith("/audit_logs/events");
143
+ /**
144
+ * Generate a random idempotency key used to make retried write requests
145
+ * safe. Mirrors the behavior of the other WorkOS SDKs (Kotlin, Go), which
146
+ * attach an `Idempotency-Key` header to POST requests that did not already
147
+ * specify one, so a retried request is not applied more than once.
148
+ */
149
+ static generateIdempotencyKey() {
150
+ return `retry-${globalThis.crypto.randomUUID()}`;
151
+ }
152
+ /**
153
+ * Parse a `Retry-After` header value into milliseconds. Supports both the
154
+ * delay-seconds form (e.g. `120`) and the HTTP-date form. The result is
155
+ * capped at {@link MAXIMUM_RETRY_AFTER_TIME_IN_MILLISECONDS}. Returns
156
+ * `null` when the value is absent or unparseable so the caller falls back
157
+ * to the computed exponential backoff.
158
+ */
159
+ static parseRetryAfter(headerValue) {
160
+ if (headerValue == null) return null;
161
+ const trimmed = headerValue.trim();
162
+ if (trimmed === "") return null;
163
+ if (/^\d+$/.test(trimmed)) return Math.min(Number(trimmed) * 1e3, MAXIMUM_RETRY_AFTER_TIME_IN_MILLISECONDS);
164
+ const asDate = Date.parse(trimmed);
165
+ if (!Number.isNaN(asDate)) {
166
+ const delta = asDate - Date.now();
167
+ return delta < 0 ? 0 : Math.min(delta, MAXIMUM_RETRY_AFTER_TIME_IN_MILLISECONDS);
168
+ }
169
+ return null;
137
170
  }
138
171
  getSleepTimeInMilliseconds(retryAttempt) {
139
- return this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS * Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt) * (Math.random() + .5);
172
+ return Math.min(this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS * Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt), this.MAXIMUM_SLEEP_TIME_IN_MILLISECONDS) * (Math.random() + .5);
140
173
  }
141
- sleep = (retryAttempt) => new Promise((resolve) => setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt)));
174
+ sleep = (retryAttempt, retryAfterMs) => new Promise((resolve) => setTimeout(resolve, retryAfterMs != null ? retryAfterMs : this.getSleepTimeInMilliseconds(retryAttempt)));
142
175
  };
143
176
  var HttpClientResponse = class {
144
177
  _statusCode;
@@ -172,17 +205,19 @@ var ParseError = class extends Error {
172
205
  rawBody;
173
206
  rawStatus;
174
207
  requestID;
175
- constructor({ message, rawBody, rawStatus, requestID }) {
208
+ rawHeaders;
209
+ constructor({ message, rawBody, rawStatus, requestID, rawHeaders }) {
176
210
  super(message);
177
211
  this.rawBody = rawBody;
178
212
  this.rawStatus = rawStatus;
179
213
  this.requestID = requestID;
214
+ this.rawHeaders = rawHeaders;
180
215
  }
181
216
  };
182
217
  //#endregion
183
218
  //#region src/common/net/fetch-client.ts
184
219
  const DEFAULT_FETCH_TIMEOUT = 6e4;
185
- var FetchHttpClient = class extends HttpClient {
220
+ var FetchHttpClient = class FetchHttpClient extends HttpClient {
186
221
  baseURL;
187
222
  options;
188
223
  _fetchFn;
@@ -198,57 +233,39 @@ var FetchHttpClient = class extends HttpClient {
198
233
  }
199
234
  async get(path, options) {
200
235
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
201
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "GET", null, options.headers);
202
- else return await this.fetchRequest(resourceURL, "GET", null, options.headers);
236
+ return await this.fetchRequestWithRetry(resourceURL, "GET", null, options.headers, options.maxRetries);
203
237
  }
204
238
  async post(path, entity, options) {
205
239
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
206
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "POST", HttpClient.getBody(entity), {
207
- ...HttpClient.getContentTypeHeader(entity),
208
- ...options.headers
209
- });
210
- else return await this.fetchRequest(resourceURL, "POST", HttpClient.getBody(entity), {
240
+ return await this.fetchRequestWithRetry(resourceURL, "POST", HttpClient.getBody(entity), {
211
241
  ...HttpClient.getContentTypeHeader(entity),
212
242
  ...options.headers
213
- });
243
+ }, options.maxRetries);
214
244
  }
215
245
  async put(path, entity, options) {
216
246
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
217
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "PUT", HttpClient.getBody(entity), {
218
- ...HttpClient.getContentTypeHeader(entity),
219
- ...options.headers
220
- });
221
- else return await this.fetchRequest(resourceURL, "PUT", HttpClient.getBody(entity), {
247
+ return await this.fetchRequestWithRetry(resourceURL, "PUT", HttpClient.getBody(entity), {
222
248
  ...HttpClient.getContentTypeHeader(entity),
223
249
  ...options.headers
224
- });
250
+ }, options.maxRetries);
225
251
  }
226
252
  async patch(path, entity, options) {
227
253
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
228
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "PATCH", HttpClient.getBody(entity), {
229
- ...HttpClient.getContentTypeHeader(entity),
230
- ...options.headers
231
- });
232
- else return await this.fetchRequest(resourceURL, "PATCH", HttpClient.getBody(entity), {
254
+ return await this.fetchRequestWithRetry(resourceURL, "PATCH", HttpClient.getBody(entity), {
233
255
  ...HttpClient.getContentTypeHeader(entity),
234
256
  ...options.headers
235
- });
257
+ }, options.maxRetries);
236
258
  }
237
259
  async delete(path, options) {
238
260
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
239
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "DELETE", null, options.headers);
240
- else return await this.fetchRequest(resourceURL, "DELETE", null, options.headers);
261
+ return await this.fetchRequestWithRetry(resourceURL, "DELETE", null, options.headers, options.maxRetries);
241
262
  }
242
263
  async deleteWithBody(path, entity, options) {
243
264
  const resourceURL = HttpClient.getResourceURL(this.baseURL, path, options.params);
244
- if (HttpClient.isPathRetryable(path)) return await this.fetchRequestWithRetry(resourceURL, "DELETE", HttpClient.getBody(entity), {
245
- ...HttpClient.getContentTypeHeader(entity),
246
- ...options.headers
247
- });
248
- else return await this.fetchRequest(resourceURL, "DELETE", HttpClient.getBody(entity), {
265
+ return await this.fetchRequestWithRetry(resourceURL, "DELETE", HttpClient.getBody(entity), {
249
266
  ...HttpClient.getContentTypeHeader(entity),
250
267
  ...options.headers
251
- });
268
+ }, options.maxRetries);
252
269
  }
253
270
  async fetchRequest(url, method, body, headers) {
254
271
  const requestBody = body || (method === "POST" || method === "PUT" || method === "PATCH" ? "" : void 0);
@@ -283,7 +300,8 @@ var FetchHttpClient = class extends HttpClient {
283
300
  message: error.message,
284
301
  rawBody,
285
302
  requestID,
286
- rawStatus: res.status
303
+ rawStatus: res.status,
304
+ rawHeaders: res.headers
287
305
  });
288
306
  throw error;
289
307
  }
@@ -310,19 +328,21 @@ var FetchHttpClient = class extends HttpClient {
310
328
  throw error;
311
329
  }
312
330
  }
313
- async fetchRequestWithRetry(url, method, body, headers) {
331
+ async fetchRequestWithRetry(url, method, body, headers, maxRetries) {
332
+ const maxRetryAttempts = maxRetries ?? this.MAX_RETRY_ATTEMPTS;
333
+ const requestHeaders = FetchHttpClient.withIdempotencyKey(method, headers, maxRetryAttempts);
314
334
  let response;
315
335
  let retryAttempts = 1;
316
336
  const makeRequest = async () => {
317
337
  let requestError = null;
318
338
  try {
319
- response = await this.fetchRequest(url, method, body, headers);
339
+ response = await this.fetchRequest(url, method, body, requestHeaders);
320
340
  } catch (e) {
321
341
  requestError = e;
322
342
  }
323
- if (this.shouldRetryRequest(requestError, retryAttempts)) {
343
+ if (this.shouldRetryRequest(requestError, retryAttempts, maxRetryAttempts)) {
324
344
  retryAttempts++;
325
- await this.sleep(retryAttempts);
345
+ await this.sleep(retryAttempts, FetchHttpClient.getRetryAfterMs(requestError));
326
346
  return makeRequest();
327
347
  }
328
348
  if (requestError != null) throw requestError;
@@ -330,14 +350,37 @@ var FetchHttpClient = class extends HttpClient {
330
350
  };
331
351
  return makeRequest();
332
352
  }
333
- shouldRetryRequest(requestError, retryAttempt) {
334
- if (retryAttempt > this.MAX_RETRY_ATTEMPTS) return false;
353
+ shouldRetryRequest(requestError, retryAttempt, maxRetryAttempts) {
354
+ if (retryAttempt > maxRetryAttempts) return false;
335
355
  if (requestError != null) {
336
356
  if (requestError instanceof TypeError) return true;
337
357
  if (requestError instanceof HttpClientError && this.RETRY_STATUS_CODES.includes(requestError.response.status)) return true;
358
+ if (requestError instanceof ParseError && this.RETRY_STATUS_CODES.includes(requestError.rawStatus)) return true;
338
359
  }
339
360
  return false;
340
361
  }
362
+ static withIdempotencyKey(method, headers, maxRetryAttempts) {
363
+ if (method !== "POST" || maxRetryAttempts <= 0 || FetchHttpClient.hasHeader(headers, "Idempotency-Key")) return headers;
364
+ return {
365
+ ...headers,
366
+ "Idempotency-Key": HttpClient.generateIdempotencyKey()
367
+ };
368
+ }
369
+ static hasHeader(headers, name) {
370
+ if (!headers) return false;
371
+ const target = name.toLowerCase();
372
+ return Object.keys(headers).some((key) => key.toLowerCase() === target);
373
+ }
374
+ static getRetryAfterMs(requestError) {
375
+ let headers;
376
+ if (requestError instanceof HttpClientError) headers = requestError.response?.headers;
377
+ else if (requestError instanceof ParseError) headers = requestError.rawHeaders;
378
+ else return null;
379
+ let value;
380
+ if (headers && typeof headers.get === "function") value = headers.get("Retry-After");
381
+ else if (headers && typeof headers === "object") value = headers["Retry-After"] ?? headers["retry-after"];
382
+ return HttpClient.parseRetryAfter(value);
383
+ }
341
384
  };
342
385
  var FetchHttpClientResponse = class FetchHttpClientResponse extends HttpClientResponse {
343
386
  _res;
@@ -416,7 +459,7 @@ var GenericServerException = class extends Error {
416
459
  };
417
460
  //#endregion
418
461
  //#region src/common/exceptions/authentication.exception.ts
419
- const AUTHENTICATION_ERROR_CODES = new Set([
462
+ const AUTHENTICATION_ERROR_CODES = /* @__PURE__ */ new Set([
420
463
  "email_verification_required",
421
464
  "organization_selection_required",
422
465
  "mfa_enrollment",
@@ -778,6 +821,9 @@ const deserializeAuthenticationEvent = (authenticationEvent) => ({
778
821
  userId: authenticationEvent.user_id
779
822
  });
780
823
  //#endregion
824
+ //#region src/multi-factor-auth/serializers/sms.serializer.ts
825
+ const deserializeSms = (sms) => ({ phoneNumber: sms.phone_number });
826
+ //#endregion
781
827
  //#region src/multi-factor-auth/serializers/totp.serializer.ts
782
828
  const deserializeTotp = (totp) => {
783
829
  return {
@@ -802,7 +848,8 @@ const deserializeFactor$1 = (factor) => ({
802
848
  createdAt: factor.created_at,
803
849
  updatedAt: factor.updated_at,
804
850
  type: factor.type,
805
- totp: deserializeTotp(factor.totp),
851
+ ...factor.sms ? { sms: deserializeSms(factor.sms) } : {},
852
+ ...factor.totp ? { totp: deserializeTotp(factor.totp) } : {},
806
853
  userId: factor.user_id
807
854
  });
808
855
  const deserializeFactorWithSecrets$1 = (factor) => ({
@@ -869,6 +916,16 @@ const serializeCreateMagicAuthOptions = (options) => ({
869
916
  //#region src/user-management/serializers/create-password-reset-options.serializer.ts
870
917
  const serializeCreatePasswordResetOptions = (options) => ({ email: options.email });
871
918
  //#endregion
919
+ //#region src/user-management/serializers/create-user-api-key-options.serializer.ts
920
+ function serializeCreateUserApiKeyOptions(options) {
921
+ return {
922
+ name: options.name,
923
+ organization_id: options.organizationId,
924
+ permissions: options.permissions,
925
+ expires_at: options.expiresAt?.toISOString()
926
+ };
927
+ }
928
+ //#endregion
872
929
  //#region src/user-management/serializers/email-verification.serializer.ts
873
930
  const deserializeEmailVerification = (emailVerification) => ({
874
931
  object: emailVerification.object,
@@ -935,6 +992,17 @@ const deserializeInvitationEvent = (invitation) => ({
935
992
  //#region src/user-management/serializers/list-sessions-options.serializer.ts
936
993
  const serializeListSessionsOptions = (options) => ({ ...options });
937
994
  //#endregion
995
+ //#region src/user-management/serializers/list-user-api-keys-options.serializer.ts
996
+ function serializeListUserApiKeysOptions(options) {
997
+ return {
998
+ limit: options.limit,
999
+ before: options.before,
1000
+ after: options.after,
1001
+ order: options.order,
1002
+ organization_id: options.organizationId
1003
+ };
1004
+ }
1005
+ //#endregion
938
1006
  //#region src/user-management/serializers/magic-auth.serializer.ts
939
1007
  const deserializeMagicAuth = (magicAuth) => ({
940
1008
  object: magicAuth.object,
@@ -1040,6 +1108,34 @@ const serializeUpdateUserOptions = (options) => ({
1040
1108
  metadata: options.metadata
1041
1109
  });
1042
1110
  //#endregion
1111
+ //#region src/user-management/serializers/user-api-key.serializer.ts
1112
+ function deserializeUserApiKey(apiKey) {
1113
+ return {
1114
+ object: apiKey.object,
1115
+ id: apiKey.id,
1116
+ owner: {
1117
+ type: "user",
1118
+ id: apiKey.owner.id,
1119
+ organizationId: apiKey.owner.organization_id
1120
+ },
1121
+ name: apiKey.name,
1122
+ obfuscatedValue: apiKey.obfuscated_value,
1123
+ lastUsedAt: apiKey.last_used_at,
1124
+ expiresAt: apiKey.expires_at,
1125
+ permissions: apiKey.permissions,
1126
+ createdAt: apiKey.created_at,
1127
+ updatedAt: apiKey.updated_at
1128
+ };
1129
+ }
1130
+ //#endregion
1131
+ //#region src/user-management/serializers/user-api-key-with-value.serializer.ts
1132
+ function deserializeUserApiKeyWithValue(apiKey) {
1133
+ return {
1134
+ ...deserializeUserApiKey(apiKey),
1135
+ value: apiKey.value
1136
+ };
1137
+ }
1138
+ //#endregion
1043
1139
  //#region src/user-management/serializers/organization-membership.serializer.ts
1044
1140
  const deserializeOrganizationMembership = (organizationMembership) => ({
1045
1141
  object: organizationMembership.object,
@@ -1397,7 +1493,11 @@ function deserializeApiKey(apiKey) {
1397
1493
  return {
1398
1494
  object: apiKey.object,
1399
1495
  id: apiKey.id,
1400
- owner: apiKey.owner,
1496
+ owner: apiKey.owner.type === "user" ? {
1497
+ type: "user",
1498
+ id: apiKey.owner.id,
1499
+ organizationId: apiKey.owner.organization_id
1500
+ } : apiKey.owner,
1401
1501
  name: apiKey.name,
1402
1502
  obfuscatedValue: apiKey.obfuscated_value,
1403
1503
  lastUsedAt: apiKey.last_used_at,
@@ -2013,6 +2113,244 @@ var PKCE = class {
2013
2113
  }
2014
2114
  };
2015
2115
  //#endregion
2116
+ //#region src/utils/jose.ts
2117
+ let _josePromise;
2118
+ /**
2119
+ * Dynamically imports the jose library using import() to support Node.js 20.0-20.18.
2120
+ *
2121
+ * The jose library is ESM-only and cannot be loaded via require() in Node.js versions
2122
+ * before 20.19.0. This wrapper uses dynamic import() which works in both ESM and CJS
2123
+ * across all Node.js 20+ versions.
2124
+ *
2125
+ * This workaround can be removed when Node.js 20 reaches end-of-life (April 2026),
2126
+ * at which point we can bump to Node.js 22+ and use direct imports.
2127
+ *
2128
+ * @returns Promise that resolves to the jose module
2129
+ */
2130
+ function getJose() {
2131
+ return _josePromise ??= import("./webapi-BgpV54gi.mjs");
2132
+ }
2133
+ //#endregion
2134
+ //#region src/agents/serializers/agent-registration.serializer.ts
2135
+ function deserializeAgentRegistration(registration) {
2136
+ return {
2137
+ id: registration.id,
2138
+ agentIdentity: {
2139
+ id: registration.agent_identity.id,
2140
+ userlandUserId: registration.agent_identity.userland_user_id,
2141
+ createdAt: registration.agent_identity.created_at,
2142
+ updatedAt: registration.agent_identity.updated_at
2143
+ },
2144
+ organizationId: registration.organization_id,
2145
+ status: registration.status,
2146
+ kind: registration.kind,
2147
+ claim: registration.claim ? {
2148
+ id: registration.claim.id,
2149
+ claimCompletion: registration.claim.claim_completion ? {
2150
+ id: registration.claim.claim_completion.id,
2151
+ createdAt: registration.claim.claim_completion.created_at,
2152
+ updatedAt: registration.claim.claim_completion.updated_at,
2153
+ expiresAt: registration.claim.claim_completion.expires_at,
2154
+ claimedAt: registration.claim.claim_completion.claimed_at
2155
+ } : null,
2156
+ createdAt: registration.claim.created_at,
2157
+ updatedAt: registration.claim.updated_at,
2158
+ expiresAt: registration.claim.expires_at
2159
+ } : null,
2160
+ createdAt: registration.created_at,
2161
+ updatedAt: registration.updated_at
2162
+ };
2163
+ }
2164
+ //#endregion
2165
+ //#region src/agents/serializers/claim-attempt.serializer.ts
2166
+ function serializeLinkClaimAttemptToExternalUserOptions(options) {
2167
+ return {
2168
+ type: "link_external_user",
2169
+ claim_attempt_token: options.claimAttemptToken,
2170
+ user: {
2171
+ email: options.user.email,
2172
+ external_id: options.user.externalId
2173
+ },
2174
+ ...options.organizationId !== void 0 && { organization_id: options.organizationId }
2175
+ };
2176
+ }
2177
+ function deserializeClaimAttemptResponse(response) {
2178
+ return {
2179
+ id: response.id,
2180
+ status: response.status,
2181
+ userCode: response.user_code,
2182
+ organizations: response.organizations
2183
+ };
2184
+ }
2185
+ //#endregion
2186
+ //#region src/agents/serializers/validate-agent-credential.serializer.ts
2187
+ function serializeValidateAgentCredentialOptions(options) {
2188
+ return {
2189
+ type: options.type,
2190
+ credential: options.credential,
2191
+ ...options.type === "access_token" && options.audience !== void 0 && { audience: options.audience }
2192
+ };
2193
+ }
2194
+ function deserializeAgentCredentialValidation(validation) {
2195
+ if (!validation.valid || validation.registration_id == null) return {
2196
+ valid: false,
2197
+ registrationId: null,
2198
+ expiresAt: null,
2199
+ claims: null
2200
+ };
2201
+ return {
2202
+ valid: true,
2203
+ registrationId: validation.registration_id,
2204
+ expiresAt: validation.expires_at,
2205
+ claims: null
2206
+ };
2207
+ }
2208
+ function deserializeAgentAccessTokenClaims(payload) {
2209
+ return {
2210
+ issuer: payload.iss,
2211
+ audience: payload.aud,
2212
+ registrationId: payload.sub,
2213
+ jti: payload.jti,
2214
+ organizationId: payload.org_id,
2215
+ scope: payload.scope,
2216
+ actor: payload.act,
2217
+ expiresAt: payload.exp,
2218
+ issuedAt: payload.iat
2219
+ };
2220
+ }
2221
+ //#endregion
2222
+ //#region src/agents/agents.ts
2223
+ /**
2224
+ * A decoded JWT payload is only an agent credential if it carries every claim
2225
+ * the SDK guarantees. A token signed by the same JWKS for another purpose
2226
+ * (e.g. a user session) lacks these and is rejected rather than reported valid
2227
+ * with empty identifiers.
2228
+ */
2229
+ function hasRequiredAgentClaims(payload) {
2230
+ return typeof payload.iss === "string" && (typeof payload.aud === "string" || Array.isArray(payload.aud)) && typeof payload.sub === "string" && typeof payload.jti === "string" && typeof payload.org_id === "string" && typeof payload.exp === "number" && typeof payload.iat === "number";
2231
+ }
2232
+ var Agents = class {
2233
+ workos;
2234
+ _jwks;
2235
+ constructor(workos) {
2236
+ this.workos = workos;
2237
+ }
2238
+ /**
2239
+ * Link a claim attempt to an external user
2240
+ *
2241
+ * Link an external user to a claim attempt and retrieve the code needed
2242
+ * for the agent to complete the claim. The user is looked up by external
2243
+ * ID; if no user exists, one is created. When the user belongs to multiple
2244
+ * organizations, an explicit organization must be provided.
2245
+ *
2246
+ * @param options - Object containing the claim attempt token, user details, and optional organization ID.
2247
+ * @returns {Promise<ClaimAttemptResponse>}
2248
+ * @throws {BadRequestException} 400 - Invalid request, email mismatch, or wrong account.
2249
+ * @throws {ForbiddenException} 403 - Claim denied or auth method disabled.
2250
+ * @throws {ConflictException} 409 - Organization selection required, external ID conflict, or already claimed.
2251
+ * @throws {GoneException} 410 - Claim or user code expired.
2252
+ */
2253
+ async linkClaimAttemptToExternalUser(options) {
2254
+ const { data } = await this.workos.patch("/agents/claims/attempts", serializeLinkClaimAttemptToExternalUserOptions(options));
2255
+ return deserializeClaimAttemptResponse(data);
2256
+ }
2257
+ /**
2258
+ * Get an agent registration
2259
+ *
2260
+ * Retrieve a single agent registration scoped to the API key's environment.
2261
+ * @param id - Unique identifier of the agent registration.
2262
+ *
2263
+ * @example
2264
+ * "agent_reg_01EHZNVPK3SFK441A1RGBFSHRT"
2265
+ *
2266
+ * @returns {Promise<AgentRegistration>}
2267
+ * @throws {NotFoundException} 404
2268
+ */
2269
+ async getRegistration(id) {
2270
+ const { data } = await this.workos.get(`/agents/registrations/${encodeURIComponent(id)}`);
2271
+ return deserializeAgentRegistration(data);
2272
+ }
2273
+ /**
2274
+ * Validate an agent credential
2275
+ *
2276
+ * For `access_token` credentials, the token is decoded and verified locally
2277
+ * against the environment's JWKS and its claims are returned — no network
2278
+ * request is made unless `checkForRevoked` is set, in which case the WorkOS
2279
+ * API is also called to confirm the token has not been revoked.
2280
+ *
2281
+ * For `api_key` credentials, the WorkOS API is always called to validate the
2282
+ * key against the environment.
2283
+ *
2284
+ * @param options - Object containing the credential type and value.
2285
+ * @returns {Promise<AgentCredentialValidation>}
2286
+ */
2287
+ async validateCredential(options) {
2288
+ if (options.type === "access_token") return this.validateAccessToken(options);
2289
+ return this.validateCredentialRemotely(options);
2290
+ }
2291
+ async validateAccessToken(options) {
2292
+ const claims = await this.verifyAccessTokenClaims(options.credential, options.audience);
2293
+ if (!claims) return {
2294
+ valid: false,
2295
+ registrationId: null,
2296
+ expiresAt: null,
2297
+ claims: null
2298
+ };
2299
+ if (!options.checkForRevoked) return {
2300
+ valid: true,
2301
+ registrationId: claims.registrationId,
2302
+ expiresAt: (/* @__PURE__ */ new Date(claims.expiresAt * 1e3)).toISOString(),
2303
+ claims
2304
+ };
2305
+ const remote = await this.validateCredentialRemotely(options);
2306
+ if (!remote.valid) return remote;
2307
+ if (remote.registrationId !== claims.registrationId) return {
2308
+ valid: false,
2309
+ registrationId: null,
2310
+ expiresAt: null,
2311
+ claims: null
2312
+ };
2313
+ return {
2314
+ ...remote,
2315
+ claims
2316
+ };
2317
+ }
2318
+ async validateCredentialRemotely(options) {
2319
+ const { data } = await this.workos.post("/agents/credentials/validate", serializeValidateAgentCredentialOptions(options));
2320
+ return deserializeAgentCredentialValidation(data);
2321
+ }
2322
+ /**
2323
+ * Verifies an access token's signature, audience, and time claims against the
2324
+ * environment's JWKS and returns its decoded claims, or `null` when the token
2325
+ * is invalid (bad signature, wrong audience, expired, malformed, or missing
2326
+ * the agent identity claims). Errors that are not JWT validation failures
2327
+ * (e.g. network errors fetching the JWKS) propagate.
2328
+ *
2329
+ * The audience defaults to the client ID; resource-scoped tokens carry the
2330
+ * resource as their audience and require it to be passed explicitly.
2331
+ */
2332
+ async verifyAccessTokenClaims(credential, audience) {
2333
+ const { jwtVerify } = await getJose();
2334
+ const jwks = await this.getJWKS();
2335
+ try {
2336
+ const { payload } = await jwtVerify(credential, jwks, { audience: audience ?? this.workos.clientId });
2337
+ if (!hasRequiredAgentClaims(payload)) return null;
2338
+ if (payload.exp * 1e3 <= Date.now()) return null;
2339
+ return deserializeAgentAccessTokenClaims(payload);
2340
+ } catch (e) {
2341
+ if (e instanceof Error && "code" in e && typeof e.code === "string" && (e.code.startsWith("ERR_JWT_") || e.code.startsWith("ERR_JWS_"))) return null;
2342
+ throw e;
2343
+ }
2344
+ }
2345
+ async getJWKS() {
2346
+ const { clientId } = this.workos;
2347
+ if (!clientId) throw new Error("Missing client ID. Did you provide it when initializing WorkOS?");
2348
+ const { createRemoteJWKSet } = await getJose();
2349
+ this._jwks ??= createRemoteJWKSet(new URL(`${this.workos.baseURL}/sso/jwks/${clientId}`), { cooldownDuration: 1e3 * 60 * 5 });
2350
+ return this._jwks;
2351
+ }
2352
+ };
2353
+ //#endregion
2016
2354
  //#region src/api-keys/serializers/create-organization-api-key-options.serializer.ts
2017
2355
  function serializeCreateOrganizationApiKeyOptions(options) {
2018
2356
  return {
@@ -2039,7 +2377,10 @@ function deserializeCreatedApiKey(apiKey) {
2039
2377
  //#endregion
2040
2378
  //#region src/api-keys/serializers/validate-api-key.serializer.ts
2041
2379
  function deserializeValidateApiKeyResponse(response) {
2042
- return { apiKey: response.api_key ? deserializeApiKey(response.api_key) : null };
2380
+ return {
2381
+ apiKey: response.api_key ? deserializeApiKey(response.api_key) : null,
2382
+ ...typeof response.agent_registration_id === "undefined" ? void 0 : { agentRegistrationId: response.agent_registration_id }
2383
+ };
2043
2384
  }
2044
2385
  //#endregion
2045
2386
  //#region src/api-keys/api-keys.ts
@@ -2808,34 +3149,231 @@ var Passwordless = class {
2808
3149
  }
2809
3150
  };
2810
3151
  //#endregion
2811
- //#region src/pipes/serializers/access-token.serializer.ts
2812
- function deserializeAccessToken(serialized) {
2813
- return {
2814
- object: "access_token",
2815
- accessToken: serialized.access_token,
2816
- expiresAt: serialized.expires_at ? new Date(Date.parse(serialized.expires_at)) : null,
2817
- scopes: serialized.scopes,
2818
- missingScopes: serialized.missing_scopes
2819
- };
2820
- }
3152
+ //#region src/pipes/serializers/data-integration-credential.serializer.ts
3153
+ const deserializeDataIntegrationCredential = (response) => ({
3154
+ type: response.type,
3155
+ clientId: response.client_id ?? null,
3156
+ redactedClientSecret: response.redacted_client_secret ?? null
3157
+ });
2821
3158
  //#endregion
2822
- //#region src/pipes/serializers/get-access-token.serializer.ts
2823
- function serializeGetAccessTokenOptions(options) {
2824
- return {
2825
- user_id: options.userId,
2826
- organization_id: options.organizationId
2827
- };
2828
- }
2829
- function deserializeGetAccessTokenResponse(response) {
2830
- if (response.active) return {
2831
- active: true,
2832
- accessToken: deserializeAccessToken(response.access_token)
2833
- };
2834
- return {
2835
- active: false,
2836
- error: response.error
2837
- };
2838
- }
3159
+ //#region src/pipes/serializers/data-integration-custom-provider.serializer.ts
3160
+ const deserializeDataIntegrationCustomProvider = (response) => ({
3161
+ name: response.name,
3162
+ authorizationUrl: response.authorization_url ?? null,
3163
+ tokenUrl: response.token_url ?? null,
3164
+ refreshTokenUrl: response.refresh_token_url ?? null,
3165
+ pkceEnabled: response.pkce_enabled,
3166
+ requestScopeSeparator: response.request_scope_separator,
3167
+ scopesRequired: response.scopes_required,
3168
+ clientSecretRequired: response.client_secret_required,
3169
+ additionalAuthorizationParameters: response.additional_authorization_parameters,
3170
+ tokenBodyContentType: response.token_body_content_type,
3171
+ authenticateVia: response.authenticate_via
3172
+ });
3173
+ //#endregion
3174
+ //#region src/pipes/serializers/data-integration.serializer.ts
3175
+ const deserializeDataIntegration = (response) => ({
3176
+ object: response.object,
3177
+ id: response.id,
3178
+ slug: response.slug,
3179
+ integrationType: response.integration_type,
3180
+ description: response.description ?? null,
3181
+ enabled: response.enabled,
3182
+ state: response.state,
3183
+ scopes: response.scopes ?? null,
3184
+ redirectUri: response.redirect_uri,
3185
+ credentials: deserializeDataIntegrationCredential(response.credentials),
3186
+ customProvider: response.custom_provider != null ? deserializeDataIntegrationCustomProvider(response.custom_provider) : null,
3187
+ createdAt: new Date(response.created_at),
3188
+ updatedAt: new Date(response.updated_at)
3189
+ });
3190
+ //#endregion
3191
+ //#region src/pipes/serializers/connected-account.serializer.ts
3192
+ const deserializeConnectedAccount = (response) => ({
3193
+ object: response.object,
3194
+ id: response.id,
3195
+ userId: response.user_id ?? null,
3196
+ organizationId: response.organization_id ?? null,
3197
+ scopes: response.scopes,
3198
+ authMethod: response.auth_method,
3199
+ apiKeyLast4: response.api_key_last_4 ?? null,
3200
+ state: response.state,
3201
+ createdAt: response.created_at,
3202
+ updatedAt: response.updated_at
3203
+ });
3204
+ //#endregion
3205
+ //#region src/pipes/serializers/data-integration-authorize-url-response.serializer.ts
3206
+ const deserializeDataIntegrationAuthorizeUrlResponse = (response) => ({ url: response.url });
3207
+ //#endregion
3208
+ //#region src/pipes/serializers/data-integration-credentials-response-credential.serializer.ts
3209
+ const deserializeDataIntegrationCredentialsResponseCredential = (response) => ({
3210
+ object: response.object,
3211
+ authMethod: response.auth_method,
3212
+ value: response.value,
3213
+ expiresAt: response.expires_at ?? null,
3214
+ scopes: response.scopes,
3215
+ missingScopes: response.missing_scopes
3216
+ });
3217
+ //#endregion
3218
+ //#region src/pipes/serializers/data-integration-credentials-response.serializer.ts
3219
+ const deserializeDataIntegrationCredentialsResponse = (response) => ({
3220
+ active: response.active,
3221
+ credential: response.credential != null ? deserializeDataIntegrationCredentialsResponseCredential(response.credential) : void 0,
3222
+ error: response.error
3223
+ });
3224
+ //#endregion
3225
+ //#region src/pipes/serializers/data-integration-access-token-response-access-token.serializer.ts
3226
+ const deserializeDataIntegrationAccessTokenResponseAccessToken = (response) => ({
3227
+ object: response.object,
3228
+ accessToken: response.access_token,
3229
+ expiresAt: response.expires_at != null ? new Date(response.expires_at) : null,
3230
+ scopes: response.scopes,
3231
+ missingScopes: response.missing_scopes
3232
+ });
3233
+ //#endregion
3234
+ //#region src/pipes/serializers/data-integration-access-token-response.serializer.ts
3235
+ const deserializeDataIntegrationAccessTokenResponse = (response) => {
3236
+ switch (response.active) {
3237
+ case true: return {
3238
+ active: true,
3239
+ accessToken: deserializeDataIntegrationAccessTokenResponseAccessToken(response.access_token)
3240
+ };
3241
+ case false: return {
3242
+ active: false,
3243
+ error: response.error
3244
+ };
3245
+ default: throw new Error(`Unknown active: ${String(response.active)}`);
3246
+ }
3247
+ };
3248
+ //#endregion
3249
+ //#region src/pipes/serializers/data-integrations-list-response-data-connected-account.serializer.ts
3250
+ const deserializeDataIntegrationsListResponseDataConnectedAccount = (response) => ({
3251
+ object: response.object,
3252
+ id: response.id,
3253
+ userId: response.user_id ?? null,
3254
+ organizationId: response.organization_id ?? null,
3255
+ scopes: response.scopes,
3256
+ authMethod: response.auth_method,
3257
+ apiKeyLast4: response.api_key_last_4 ?? null,
3258
+ state: response.state,
3259
+ createdAt: response.created_at,
3260
+ updatedAt: response.updated_at,
3261
+ userlandUserId: response.userland_user_id ?? null
3262
+ });
3263
+ //#endregion
3264
+ //#region src/pipes/serializers/data-integrations-list-response-data.serializer.ts
3265
+ const deserializeDataIntegrationsListResponseData = (response) => ({
3266
+ object: response.object,
3267
+ id: response.id,
3268
+ name: response.name,
3269
+ description: response.description ?? null,
3270
+ slug: response.slug,
3271
+ integrationType: response.integration_type,
3272
+ credentialsType: response.credentials_type,
3273
+ scopes: response.scopes ?? null,
3274
+ authMethods: response.auth_methods,
3275
+ ownership: response.ownership,
3276
+ createdAt: response.created_at,
3277
+ updatedAt: response.updated_at,
3278
+ connectedAccount: response.connected_account != null ? deserializeDataIntegrationsListResponseDataConnectedAccount(response.connected_account) : null
3279
+ });
3280
+ //#endregion
3281
+ //#region src/pipes/serializers/data-integrations-list-response.serializer.ts
3282
+ const deserializeDataIntegrationsListResponse = (response) => ({
3283
+ object: response.object,
3284
+ data: response.data.map(deserializeDataIntegrationsListResponseData)
3285
+ });
3286
+ //#endregion
3287
+ //#region src/pipes/serializers/data-integration-credentials-dto.serializer.ts
3288
+ const serializeDataIntegrationCredentialsDto = (model) => ({
3289
+ type: model.type,
3290
+ client_id: model.clientId,
3291
+ client_secret: model.clientSecret
3292
+ });
3293
+ //#endregion
3294
+ //#region src/pipes/serializers/custom-provider-definition.serializer.ts
3295
+ const serializeCustomProviderDefinition = (model) => ({
3296
+ name: model.name,
3297
+ authorization_url: model.authorizationUrl,
3298
+ token_url: model.tokenUrl,
3299
+ refresh_token_url: model.refreshTokenUrl,
3300
+ pkce_enabled: model.pkceEnabled,
3301
+ request_scope_separator: model.requestScopeSeparator,
3302
+ scopes_required: model.scopesRequired,
3303
+ client_secret_required: model.clientSecretRequired,
3304
+ additional_authorization_parameters: model.additionalAuthorizationParameters,
3305
+ token_body_content_type: model.tokenBodyContentType,
3306
+ authenticate_via: model.authenticateVia
3307
+ });
3308
+ //#endregion
3309
+ //#region src/pipes/serializers/create-data-integration.serializer.ts
3310
+ const serializeCreateDataIntegration = (model) => ({
3311
+ provider: model.provider,
3312
+ description: model.description,
3313
+ enabled: model.enabled,
3314
+ scopes: model.scopes,
3315
+ credentials: model.credentials != null ? serializeDataIntegrationCredentialsDto(model.credentials) : void 0,
3316
+ custom_provider: model.customProvider != null ? serializeCustomProviderDefinition(model.customProvider) : void 0
3317
+ });
3318
+ //#endregion
3319
+ //#region src/pipes/serializers/update-custom-provider-definition.serializer.ts
3320
+ const serializeUpdateCustomProviderDefinition = (model) => ({
3321
+ name: model.name,
3322
+ authorization_url: model.authorizationUrl,
3323
+ token_url: model.tokenUrl,
3324
+ refresh_token_url: model.refreshTokenUrl,
3325
+ pkce_enabled: model.pkceEnabled,
3326
+ request_scope_separator: model.requestScopeSeparator,
3327
+ scopes_required: model.scopesRequired,
3328
+ client_secret_required: model.clientSecretRequired,
3329
+ additional_authorization_parameters: model.additionalAuthorizationParameters,
3330
+ token_body_content_type: model.tokenBodyContentType,
3331
+ authenticate_via: model.authenticateVia
3332
+ });
3333
+ //#endregion
3334
+ //#region src/pipes/serializers/update-data-integration.serializer.ts
3335
+ const serializeUpdateDataIntegration = (model) => ({
3336
+ description: model.description,
3337
+ enabled: model.enabled,
3338
+ scopes: model.scopes,
3339
+ credentials: model.credentials != null ? serializeDataIntegrationCredentialsDto(model.credentials) : void 0,
3340
+ custom_provider: model.customProvider != null ? serializeUpdateCustomProviderDefinition(model.customProvider) : void 0
3341
+ });
3342
+ //#endregion
3343
+ //#region src/pipes/serializers/data-integrations-upsert-api-key-request.serializer.ts
3344
+ const serializeDataIntegrationsUpsertApiKeyRequest = (model) => ({
3345
+ user_id: model.userId,
3346
+ organization_id: model.organizationId,
3347
+ secret: model.secret
3348
+ });
3349
+ //#endregion
3350
+ //#region src/pipes/serializers/data-integrations-get-data-integration-authorize-url-request.serializer.ts
3351
+ const serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest = (model) => ({
3352
+ user_id: model.userId,
3353
+ organization_id: model.organizationId,
3354
+ return_to: model.returnTo
3355
+ });
3356
+ //#endregion
3357
+ //#region src/pipes/serializers/data-integrations-vend-credentials-request.serializer.ts
3358
+ const serializeDataIntegrationsVendCredentialsRequest = (model) => ({
3359
+ user_id: model.userId,
3360
+ organization_id: model.organizationId
3361
+ });
3362
+ //#endregion
3363
+ //#region src/pipes/serializers/data-integrations-get-user-token-request.serializer.ts
3364
+ const serializeDataIntegrationsGetUserTokenRequest = (model) => ({
3365
+ user_id: model.userId,
3366
+ organization_id: model.organizationId
3367
+ });
3368
+ //#endregion
3369
+ //#region src/pipes/serializers/connected-account-dto.serializer.ts
3370
+ const serializeConnectedAccountDto = (model) => ({
3371
+ access_token: model.accessToken,
3372
+ refresh_token: model.refreshToken,
3373
+ expires_at: model.expiresAt != null ? model.expiresAt.toISOString() : void 0,
3374
+ scopes: model.scopes,
3375
+ state: model.state
3376
+ });
2839
3377
  //#endregion
2840
3378
  //#region src/pipes/pipes.ts
2841
3379
  var Pipes = class {
@@ -2843,9 +3381,311 @@ var Pipes = class {
2843
3381
  constructor(workos) {
2844
3382
  this.workos = workos;
2845
3383
  }
2846
- async getAccessToken({ provider, ...options }) {
2847
- const { data } = await this.workos.post(`data-integrations/${provider}/token`, serializeGetAccessTokenOptions(options));
2848
- return deserializeGetAccessTokenResponse(data);
3384
+ /**
3385
+ * List data integrations
3386
+ *
3387
+ * Lists the environment's data integrations configured with `custom` or `organization` credentials, including custom providers.
3388
+ * @param options - Pagination and filter options.
3389
+ * @returns {Promise<AutoPaginatable<DataIntegration, PaginationOptions>>}
3390
+ * @throws {UnauthorizedException} 401
3391
+ */
3392
+ async listDataIntegrations(options) {
3393
+ const paginationOptions = options;
3394
+ return new AutoPaginatable(await fetchAndDeserialize(this.workos, "/data-integrations", deserializeDataIntegration, paginationOptions), (params) => fetchAndDeserialize(this.workos, "/data-integrations", deserializeDataIntegration, params), paginationOptions);
3395
+ }
3396
+ /**
3397
+ * Create a data integration
3398
+ *
3399
+ * Creates a data integration for a provider. Set `credentials.type` to `custom` to use your own OAuth app credentials, or `organization` to have each organization supply its own. For a built-in provider, pass its slug as `provider`. For a custom provider, pass a new slug plus a `custom_provider` definition.
3400
+ * @param options - Object containing provider.
3401
+ * @param options.provider - The provider to create a Data Integration for. For a built-in provider use its slug (e.g. `github`, `slack`). For a custom provider, this is the new provider slug and `custom_provider` must be supplied. A custom provider slug cannot shadow an existing global provider slug.
3402
+ * @example "github"
3403
+ * @param options.description - An optional description of the Data Integration.
3404
+ * @example "Production GitHub app"
3405
+ * @param options.enabled - Whether the Data Integration is enabled. Defaults to `false`.
3406
+ * @example true
3407
+ * @param options.scopes - The OAuth scopes to request for the Data Integration. Defaults to the provider's configured scopes when omitted.
3408
+ * @example ["repo","read:org"]
3409
+ * @param options.credentials - The credentials to configure for the Data Integration. Required for both built-in and custom providers.
3410
+ * @param options.customProvider - The OAuth definition for a custom provider. Supply this to define a custom provider; omit it to create an integration for a built-in provider.
3411
+ * @returns {Promise<DataIntegration>}
3412
+ * @throws {BadRequestException} 400
3413
+ * @throws {UnauthorizedException} 401
3414
+ * @throws {NotFoundException} 404
3415
+ * @throws {UnprocessableEntityException} 422
3416
+ */
3417
+ async createDataIntegration(options) {
3418
+ const payload = options;
3419
+ const { data } = await this.workos.post("/data-integrations", serializeCreateDataIntegration(payload));
3420
+ return deserializeDataIntegration(data);
3421
+ }
3422
+ /**
3423
+ * Get a data integration
3424
+ *
3425
+ * Retrieves a data integration by its slug.
3426
+ * @param options - The request options.
3427
+ * @param options.slug - The slug identifier of the data integration.
3428
+ * @example "github"
3429
+ * @returns {Promise<DataIntegration>}
3430
+ * @throws {UnauthorizedException} 401
3431
+ * @throws {NotFoundException} 404
3432
+ */
3433
+ async getDataIntegration(options) {
3434
+ const { slug } = options;
3435
+ const { data } = await this.workos.get(`/data-integrations/${encodeURIComponent(slug)}`);
3436
+ return deserializeDataIntegration(data);
3437
+ }
3438
+ /**
3439
+ * Update a data integration
3440
+ *
3441
+ * Updates the description, enabled state, or custom credentials of a data integration. For custom providers, `custom_provider` updates the OAuth definition.
3442
+ * @param options - The request body.
3443
+ * @param options.slug - The slug identifier of the data integration.
3444
+ * @example "github"
3445
+ * @param options.description - An optional description of the Data Integration.
3446
+ * @example "Production GitHub app"
3447
+ * @param options.enabled - Whether the Data Integration is enabled.
3448
+ * @example true
3449
+ * @param options.scopes - The OAuth scopes to request for the Data Integration. Pass `null` to reset to the provider's configured scopes.
3450
+ * @example ["repo","read:org"]
3451
+ * @param options.credentials - New credentials for the Data Integration. When provided, rotates the stored client secret.
3452
+ * @param options.customProvider - Updates to a custom provider's OAuth definition. Only valid for custom-provider integrations.
3453
+ * @returns {Promise<DataIntegration>}
3454
+ * @throws {BadRequestException} 400
3455
+ * @throws {UnauthorizedException} 401
3456
+ * @throws {NotFoundException} 404
3457
+ * @throws {UnprocessableEntityException} 422
3458
+ */
3459
+ async updateDataIntegration(options) {
3460
+ const { slug, ...payload } = options;
3461
+ const { data } = await this.workos.put(`/data-integrations/${encodeURIComponent(slug)}`, serializeUpdateDataIntegration(payload));
3462
+ return deserializeDataIntegration(data);
3463
+ }
3464
+ /**
3465
+ * Delete a data integration
3466
+ *
3467
+ * Deletes a data integration and all of its connected installations. For a custom provider, also deletes the custom provider definition.
3468
+ * @param options - The request options.
3469
+ * @param options.slug - The slug identifier of the data integration.
3470
+ * @example "github"
3471
+ * @returns {Promise<void>}
3472
+ * @throws {UnauthorizedException} 401
3473
+ * @throws {NotFoundException} 404
3474
+ */
3475
+ async deleteDataIntegration(options) {
3476
+ const { slug } = options;
3477
+ await this.workos.delete(`/data-integrations/${encodeURIComponent(slug)}`);
3478
+ }
3479
+ /**
3480
+ * Upsert an API key for a connected account
3481
+ *
3482
+ * Creates or updates an API-key-based installation for the specified integration and user. If an installation already exists, the stored API key is rotated to the new value.
3483
+ * @param options - Object containing userId, secret.
3484
+ * @param options.slug - The identifier of the integration.
3485
+ * @example "github"
3486
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3487
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3488
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization.
3489
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3490
+ * @param options.secret - The API key secret to store for this integration.
3491
+ * @example "sk-1234567890abcdef"
3492
+ * @returns {Promise<ConnectedAccount>}
3493
+ * @throws {BadRequestException} 400
3494
+ * @throws {UnauthorizedException} 401
3495
+ * @throws {AuthorizationException} 403
3496
+ * @throws {NotFoundException} 404
3497
+ * @throws {UnprocessableEntityException} 422
3498
+ */
3499
+ async updateDataIntegrationApiKey(options) {
3500
+ const { slug, ...payload } = options;
3501
+ const { data } = await this.workos.put(`/data-integrations/${encodeURIComponent(slug)}/api-key`, serializeDataIntegrationsUpsertApiKeyRequest(payload));
3502
+ return deserializeConnectedAccount(data);
3503
+ }
3504
+ /**
3505
+ * Get authorization URL
3506
+ *
3507
+ * Generates an OAuth authorization URL to initiate the connection flow for a user. Redirect the user to the returned URL to begin the OAuth flow with the third-party provider.
3508
+ * @param options - Object containing userId.
3509
+ * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`).
3510
+ * @example "github"
3511
+ * @param options.userId - The ID of the user to authorize.
3512
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3513
+ * @param options.organizationId - An organization ID to scope the authorization to a specific organization.
3514
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3515
+ * @param options.returnTo - The URL to redirect the user to after authorization.
3516
+ * @example "https://example.com/callback"
3517
+ * @returns {Promise<DataIntegrationAuthorizeUrlResponse>}
3518
+ * @throws {BadRequestException} 400
3519
+ * @throws {UnauthorizedException} 401
3520
+ * @throws {AuthorizationException} 403
3521
+ * @throws {NotFoundException} 404
3522
+ */
3523
+ async authorizeDataIntegration(options) {
3524
+ const { slug, ...payload } = options;
3525
+ const { data } = await this.workos.post(`/data-integrations/${encodeURIComponent(slug)}/authorize`, serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest(payload));
3526
+ return deserializeDataIntegrationAuthorizeUrlResponse(data);
3527
+ }
3528
+ /**
3529
+ * Vend credentials for a connected account
3530
+ *
3531
+ * Returns credentials for a user's connected account. Branches on the installation's `auth_method`: OAuth installations return an access token (refreshed if needed); API-key installations return the stored secret.
3532
+ * @param options - Object containing userId.
3533
+ * @param options.slug - The identifier of the integration.
3534
+ * @example "github"
3535
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3536
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3537
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization.
3538
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3539
+ * @returns {Promise<DataIntegrationCredentialsResponse>}
3540
+ * @throws {BadRequestException} 400
3541
+ * @throws {UnauthorizedException} 401
3542
+ * @throws {NotFoundException} 404
3543
+ */
3544
+ async createDataIntegrationCredential(options) {
3545
+ const { slug, ...payload } = options;
3546
+ const { data } = await this.workos.post(`/data-integrations/${encodeURIComponent(slug)}/credentials`, serializeDataIntegrationsVendCredentialsRequest(payload));
3547
+ return deserializeDataIntegrationCredentialsResponse(data);
3548
+ }
3549
+ /**
3550
+ * Get an access token for a connected account
3551
+ *
3552
+ * Fetches a valid OAuth access token for a user's connected account. WorkOS automatically handles token refresh, ensuring you always receive a valid, non-expired token.
3553
+ * @param options - Object containing userId.
3554
+ * @param options.provider - The identifier of the integration.
3555
+ * @example "github"
3556
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3557
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3558
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization.
3559
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3560
+ * @returns {Promise<DataIntegrationAccessTokenResponse>}
3561
+ * @throws {BadRequestException} 400
3562
+ * @throws {UnauthorizedException} 401
3563
+ * @throws {NotFoundException} 404
3564
+ * @throws {UnprocessableEntityException} 422
3565
+ */
3566
+ async getAccessToken(options) {
3567
+ const { provider, ...payload } = options;
3568
+ const { data } = await this.workos.post(`/data-integrations/${encodeURIComponent(provider)}/token`, serializeDataIntegrationsGetUserTokenRequest(payload));
3569
+ return deserializeDataIntegrationAccessTokenResponse(data);
3570
+ }
3571
+ /**
3572
+ * Get a connected account
3573
+ *
3574
+ * Retrieves a user's [connected account](https://workos.com/docs/reference/pipes/connected-account) for a specific provider.
3575
+ * @param options - Additional query options.
3576
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3577
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3578
+ * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`).
3579
+ * @example "github"
3580
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization.
3581
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3582
+ * @returns {Promise<ConnectedAccount>}
3583
+ * @throws {UnauthorizedException} 401
3584
+ * @throws {NotFoundException} 404
3585
+ */
3586
+ async getUserConnectedAccount(options) {
3587
+ const { userId, slug } = options;
3588
+ const { data } = await this.workos.get(`/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, { query: { ...options.organizationId !== void 0 && { organization_id: options.organizationId } } });
3589
+ return deserializeConnectedAccount(data);
3590
+ }
3591
+ /**
3592
+ * Import a connected account
3593
+ *
3594
+ * Imports a [connected account](https://workos.com/docs/reference/pipes/connected-account) for a user by providing OAuth tokens directly. Use this to migrate existing connections or set up connections without going through the OAuth flow.
3595
+ * @param options - The request body.
3596
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3597
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3598
+ * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`).
3599
+ * @example "github"
3600
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization.
3601
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3602
+ * @param options.accessToken - The OAuth access token for the connected account.
3603
+ * @example "gho_16C7e42F292c6912E7710c838347Ae178B4a"
3604
+ * @param options.refreshToken - The OAuth refresh token for the connected account.
3605
+ * @example "ghr_xxxxxxxxxxxxxxxxxxxx"
3606
+ * @param options.expiresAt - The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire.
3607
+ * @example "2025-12-31T23:59:59.000Z"
3608
+ * @param options.scopes - The OAuth scopes granted for this connection.
3609
+ * @example ["repo","user:email"]
3610
+ * @param options.state - Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided.
3611
+ * @example "connected"
3612
+ * @returns {Promise<ConnectedAccount>}
3613
+ * @throws {UnauthorizedException} 401
3614
+ * @throws {NotFoundException} 404
3615
+ * @throws {ConflictException} 409
3616
+ * @throws {UnprocessableEntityException} 422
3617
+ */
3618
+ async createUserConnectedAccount(options) {
3619
+ const { userId, slug, organizationId, ...payload } = options;
3620
+ const { data } = await this.workos.post(`/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, serializeConnectedAccountDto(payload), { query: { ...options.organizationId !== void 0 && { organization_id: options.organizationId } } });
3621
+ return deserializeConnectedAccount(data);
3622
+ }
3623
+ /**
3624
+ * Update a connected account
3625
+ *
3626
+ * Updates a user's [connected account](https://workos.com/docs/reference/pipes/connected-account) tokens, scopes, or state for a specific provider.
3627
+ * @param options - The request body.
3628
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3629
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3630
+ * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`).
3631
+ * @example "github"
3632
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization.
3633
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3634
+ * @param options.accessToken - The OAuth access token for the connected account.
3635
+ * @example "gho_16C7e42F292c6912E7710c838347Ae178B4a"
3636
+ * @param options.refreshToken - The OAuth refresh token for the connected account.
3637
+ * @example "ghr_xxxxxxxxxxxxxxxxxxxx"
3638
+ * @param options.expiresAt - The ISO-8601 timestamp when the access token expires. Required when `access_token` is provided for tokens that expire.
3639
+ * @example "2025-12-31T23:59:59.000Z"
3640
+ * @param options.scopes - The OAuth scopes granted for this connection.
3641
+ * @example ["repo","user:email"]
3642
+ * @param options.state - Explicitly set the state of the connected account. When omitted, the state is derived from the token combination provided.
3643
+ * @example "connected"
3644
+ * @returns {Promise<ConnectedAccount>}
3645
+ * @throws {UnauthorizedException} 401
3646
+ * @throws {NotFoundException} 404
3647
+ */
3648
+ async updateUserConnectedAccount(options) {
3649
+ const { userId, slug, organizationId, ...payload } = options;
3650
+ const { data } = await this.workos.put(`/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, serializeConnectedAccountDto(payload), { query: { ...options.organizationId !== void 0 && { organization_id: options.organizationId } } });
3651
+ return deserializeConnectedAccount(data);
3652
+ }
3653
+ /**
3654
+ * Delete a connected account
3655
+ *
3656
+ * Disconnects WorkOS's account for the user, including removing any stored access and refresh tokens. The user will need to reauthorize if they want to reconnect. This does not revoke access on the provider side.
3657
+ * @param options - Additional query options.
3658
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier.
3659
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3660
+ * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`).
3661
+ * @example "github"
3662
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization.
3663
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3664
+ * @returns {Promise<void>}
3665
+ * @throws {UnauthorizedException} 401
3666
+ * @throws {NotFoundException} 404
3667
+ */
3668
+ async deleteUserConnectedAccount(options) {
3669
+ const { userId, slug } = options;
3670
+ await this.workos.delete(`/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, { ...options.organizationId !== void 0 && { organization_id: options.organizationId } });
3671
+ }
3672
+ /**
3673
+ * List providers for a user
3674
+ *
3675
+ * Retrieves a list of available providers and the user's connection status for each. Returns all providers configured for your environment, along with the user's [connected account](https://workos.com/docs/reference/pipes/connected-account) information where applicable.
3676
+ * @param options - Additional query options.
3677
+ * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier to list providers and connected accounts for.
3678
+ * @example "user_01EHZNVPK3SFK441A1RGBFSHRT"
3679
+ * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to filter connections for a specific organization.
3680
+ * @example "org_01EHZNVPK3SFK441A1RGBFSHRT"
3681
+ * @returns {Promise<DataIntegrationsListResponse>}
3682
+ * @throws {UnauthorizedException} 401
3683
+ * @throws {NotFoundException} 404
3684
+ */
3685
+ async listUserDataProviders(options) {
3686
+ const { userId } = options;
3687
+ const { data } = await this.workos.get(`/user_management/users/${encodeURIComponent(userId)}/data_providers`, { query: { ...options.organizationId !== void 0 && { organization_id: options.organizationId } } });
3688
+ return deserializeDataIntegrationsListResponse(data);
2849
3689
  }
2850
3690
  };
2851
3691
  //#endregion
@@ -3208,9 +4048,6 @@ const deserializeChallenge = (challenge) => ({
3208
4048
  authenticationFactorId: challenge.authentication_factor_id
3209
4049
  });
3210
4050
  //#endregion
3211
- //#region src/multi-factor-auth/serializers/sms.serializer.ts
3212
- const deserializeSms = (sms) => ({ phoneNumber: sms.phone_number });
3213
- //#endregion
3214
4051
  //#region src/multi-factor-auth/serializers/factor.serializer.ts
3215
4052
  const deserializeFactor = (factor) => ({
3216
4053
  object: factor.object,
@@ -3606,7 +4443,9 @@ function isJson(val) {
3606
4443
  }
3607
4444
  return !0;
3608
4445
  }
3609
- const enc = /* @__PURE__ */ new TextEncoder(), dec = /* @__PURE__ */ new TextDecoder(), jsBase64Enabled = /* @__PURE__ */ (() => typeof Uint8Array.fromBase64 == "function" && typeof Uint8Array.prototype.toBase64 == "function" && typeof Uint8Array.prototype.toHex == "function")();
4446
+ const enc = /* @__PURE__ */ new TextEncoder();
4447
+ const dec = /* @__PURE__ */ new TextDecoder();
4448
+ const jsBase64Enabled = /* @__PURE__ */ (() => typeof Uint8Array.fromBase64 == "function" && typeof Uint8Array.prototype.toBase64 == "function" && typeof Uint8Array.prototype.toHex == "function")();
3610
4449
  function b64ToU8(str) {
3611
4450
  return jsBase64Enabled ? Uint8Array.fromBase64(str, { alphabet: "base64url" }) : base64ToUint8Array$1(str);
3612
4451
  }
@@ -3635,7 +4474,8 @@ const defaults = /* @__PURE__ */ Object.freeze({
3635
4474
  ttl: 0,
3636
4475
  timestampSkewSec: 60,
3637
4476
  localtimeOffsetMsec: 0
3638
- }), algorithms = /* @__PURE__ */ Object.freeze({
4477
+ });
4478
+ const algorithms = /* @__PURE__ */ Object.freeze({
3639
4479
  "aes-128-ctr": /* @__PURE__ */ Object.freeze({
3640
4480
  keyBits: 128,
3641
4481
  ivBits: 128,
@@ -3959,6 +4799,10 @@ let RefreshSessionFailureReason = /* @__PURE__ */ function(RefreshSessionFailure
3959
4799
  RefreshSessionFailureReason["INVALID_GRANT"] = "invalid_grant";
3960
4800
  RefreshSessionFailureReason["MFA_ENROLLMENT"] = "mfa_enrollment";
3961
4801
  RefreshSessionFailureReason["SSO_REQUIRED"] = "sso_required";
4802
+ RefreshSessionFailureReason["RATE_LIMIT_EXCEEDED"] = "rate_limit_exceeded";
4803
+ RefreshSessionFailureReason["TIMEOUT"] = "timeout";
4804
+ RefreshSessionFailureReason["SERVER_ERROR"] = "server_error";
4805
+ RefreshSessionFailureReason["NETWORK_ERROR"] = "network_error";
3962
4806
  return RefreshSessionFailureReason;
3963
4807
  }({});
3964
4808
  //#endregion
@@ -3978,24 +4822,6 @@ const serializeUpdateOrganizationMembershipOptions = (options) => ({
3978
4822
  role_slugs: options.roleSlugs
3979
4823
  });
3980
4824
  //#endregion
3981
- //#region src/utils/jose.ts
3982
- let _josePromise;
3983
- /**
3984
- * Dynamically imports the jose library using import() to support Node.js 20.0-20.18.
3985
- *
3986
- * The jose library is ESM-only and cannot be loaded via require() in Node.js versions
3987
- * before 20.19.0. This wrapper uses dynamic import() which works in both ESM and CJS
3988
- * across all Node.js 20+ versions.
3989
- *
3990
- * This workaround can be removed when Node.js 20 reaches end-of-life (April 2026),
3991
- * at which point we can bump to Node.js 22+ and use direct imports.
3992
- *
3993
- * @returns Promise that resolves to the jose module
3994
- */
3995
- function getJose() {
3996
- return _josePromise ??= import("./webapi-S8D5YgJz.mjs");
3997
- }
3998
- //#endregion
3999
4825
  //#region src/user-management/session.ts
4000
4826
  var CookieSession = class {
4001
4827
  userManagement;
@@ -4056,7 +4882,8 @@ var CookieSession = class {
4056
4882
  const session = await unsealData(this.sessionData, { password: this.cookiePassword });
4057
4883
  if (!session.refreshToken || !session.user) return {
4058
4884
  authenticated: false,
4059
- reason: "invalid_session_cookie"
4885
+ reason: "invalid_session_cookie",
4886
+ retryable: false
4060
4887
  };
4061
4888
  const { org_id: organizationIdFromUserManagementAccessToken } = decodeJwt(session.accessToken);
4062
4889
  try {
@@ -4089,10 +4916,14 @@ var CookieSession = class {
4089
4916
  impersonator: session.impersonator
4090
4917
  };
4091
4918
  } catch (error) {
4092
- if (error instanceof OauthException && (error.error === "invalid_grant" || error.error === "mfa_enrollment" || error.error === "sso_required")) return {
4919
+ const terminalReason = classifyTerminalRefreshError(error);
4920
+ if (terminalReason) return {
4093
4921
  authenticated: false,
4094
- reason: error.error
4922
+ reason: terminalReason,
4923
+ retryable: false
4095
4924
  };
4925
+ const retryableFailure = classifyRetryableRefreshError(error);
4926
+ if (retryableFailure) return retryableFailure;
4096
4927
  throw error;
4097
4928
  }
4098
4929
  }
@@ -4125,6 +4956,62 @@ var CookieSession = class {
4125
4956
  }
4126
4957
  }
4127
4958
  };
4959
+ /**
4960
+ * Classifies an error thrown while refreshing as a terminal authentication
4961
+ * failure — the session is over and the user must re-authenticate — returning
4962
+ * the matching failure reason, or `null` when the error is not a recognized
4963
+ * terminal failure (and may still be retryable or should be rethrown).
4964
+ */
4965
+ function classifyTerminalRefreshError(error) {
4966
+ if (error instanceof OauthException && error.error === "invalid_grant") return "invalid_grant";
4967
+ if (error instanceof AuthenticationException) {
4968
+ const code = error.code;
4969
+ if (code === "mfa_enrollment") return "mfa_enrollment";
4970
+ if (code === "sso_required") return "sso_required";
4971
+ }
4972
+ return null;
4973
+ }
4974
+ function classifyRetryableRefreshError(error) {
4975
+ if (error instanceof RateLimitExceededException) return {
4976
+ authenticated: false,
4977
+ reason: "rate_limit_exceeded",
4978
+ retryable: true,
4979
+ retryAfter: error.retryAfter ?? void 0,
4980
+ error
4981
+ };
4982
+ const status = getErrorStatus(error);
4983
+ if (status === 429) return {
4984
+ authenticated: false,
4985
+ reason: "rate_limit_exceeded",
4986
+ retryable: true,
4987
+ error
4988
+ };
4989
+ if (status === 408) return {
4990
+ authenticated: false,
4991
+ reason: "timeout",
4992
+ retryable: true,
4993
+ error
4994
+ };
4995
+ if (status !== void 0 && status >= 500) return {
4996
+ authenticated: false,
4997
+ reason: "server_error",
4998
+ retryable: true,
4999
+ error
5000
+ };
5001
+ if (isNetworkError(error)) return {
5002
+ authenticated: false,
5003
+ reason: "network_error",
5004
+ retryable: true,
5005
+ error
5006
+ };
5007
+ return null;
5008
+ }
5009
+ function getErrorStatus(error) {
5010
+ if (error instanceof OauthException || error instanceof GenericServerException) return error.status;
5011
+ }
5012
+ function isNetworkError(error) {
5013
+ return error instanceof TypeError || error instanceof Error && error.cause instanceof TypeError;
5014
+ }
4128
5015
  //#endregion
4129
5016
  //#region src/user-management/user-management.ts
4130
5017
  var UserManagement = class {
@@ -4608,6 +5495,34 @@ var UserManagement = class {
4608
5495
  await this.workos.delete(`/user_management/users/${userId}`);
4609
5496
  }
4610
5497
  /**
5498
+ * List API keys for a user
5499
+ *
5500
+ * Get a list of API keys owned by a specific user.
5501
+ * @param userId - Unique identifier of the user.
5502
+ * @param options - Pagination and filter options.
5503
+ * @returns {Promise<AutoPaginatable<UserApiKey, SerializedListUserApiKeysOptions>>}
5504
+ * @throws {NotFoundException} 404
5505
+ */
5506
+ async listUserApiKeys(userId, options) {
5507
+ const serializedOptions = options ? serializeListUserApiKeysOptions(options) : void 0;
5508
+ return new AutoPaginatable(await fetchAndDeserialize(this.workos, `/user_management/users/${userId}/api_keys`, deserializeUserApiKey, serializedOptions), (params) => fetchAndDeserialize(this.workos, `/user_management/users/${userId}/api_keys`, deserializeUserApiKey, params), serializedOptions);
5509
+ }
5510
+ /**
5511
+ * Create an API key for a user
5512
+ *
5513
+ * Create a new API key owned by a user. The user must have an active membership in the specified organization.
5514
+ * @param userId - Unique identifier of the user.
5515
+ * @param options - Object containing the API key properties.
5516
+ * @returns {Promise<UserApiKeyWithValue>}
5517
+ * @throws {BadRequestException} 400
5518
+ * @throws {NotFoundException} 404
5519
+ * @throws {UnprocessableEntityException} 422
5520
+ */
5521
+ async createUserApiKey(userId, options, requestOptions = {}) {
5522
+ const { data } = await this.workos.post(`/user_management/users/${userId}/api_keys`, serializeCreateUserApiKeyOptions(options), requestOptions);
5523
+ return deserializeUserApiKeyWithValue(data);
5524
+ }
5525
+ /**
4611
5526
  * Get user identities
4612
5527
  *
4613
5528
  * Get a list of identities associated with the user. A user can have multiple associated identities after going through [identity linking](https://workos.com/docs/authkit/identity-linking). Currently only OAuth identities are supported. More provider types may be added in the future.
@@ -5222,7 +6137,7 @@ var FeatureFlagsRuntimeClient = class extends EventEmitter {
5222
6137
  }
5223
6138
  emitChanges(previous, current) {
5224
6139
  if (!previous || !current) return;
5225
- const allKeys = new Set([...Object.keys(previous), ...Object.keys(current)]);
6140
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(current)]);
5226
6141
  for (const key of allKeys) {
5227
6142
  const prev = previous[key];
5228
6143
  const curr = current[key];
@@ -7072,7 +7987,7 @@ var Vault = class {
7072
7987
  */
7073
7988
  async deleteObject(options) {
7074
7989
  const { id } = options;
7075
- await this.workos.delete(`/vault/v1/kv/${encodeURIComponent(id)}`, { query: { ...options.versionCheck !== void 0 && { version_check: options.versionCheck } } });
7990
+ await this.workos.delete(`/vault/v1/kv/${encodeURIComponent(id)}`, { ...options.versionCheck !== void 0 && { version_check: options.versionCheck } });
7076
7991
  }
7077
7992
  /**
7078
7993
  * Describe an object
@@ -7154,7 +8069,7 @@ var Vault = class {
7154
8069
  };
7155
8070
  //#endregion
7156
8071
  //#region package.json
7157
- var version = "10.7.0";
8072
+ var version = "10.9.0";
7158
8073
  //#endregion
7159
8074
  //#region src/workos.ts
7160
8075
  const DEFAULT_HOSTNAME = "api.workos.com";
@@ -7171,6 +8086,7 @@ var WorkOS = class {
7171
8086
  pkce;
7172
8087
  hasApiKey;
7173
8088
  actions;
8089
+ agents = new Agents(this);
7174
8090
  apiKeys = new ApiKeys(this);
7175
8091
  auditLogs = new AuditLogs(this);
7176
8092
  authorization = new Authorization(this);
@@ -7255,6 +8171,7 @@ var WorkOS = class {
7255
8171
  return new FetchHttpClient(this.baseURL, {
7256
8172
  ...options.config,
7257
8173
  timeout: options.timeout,
8174
+ maxRetries: options.maxRetries,
7258
8175
  headers
7259
8176
  });
7260
8177
  }
@@ -7278,7 +8195,8 @@ var WorkOS = class {
7278
8195
  try {
7279
8196
  res = await this.client.post(path, entity, {
7280
8197
  params: options.query,
7281
- headers: requestHeaders
8198
+ headers: requestHeaders,
8199
+ maxRetries: options.maxRetries
7282
8200
  });
7283
8201
  } catch (error) {
7284
8202
  this.handleHttpError({
@@ -7298,7 +8216,8 @@ var WorkOS = class {
7298
8216
  try {
7299
8217
  res = await this.client.get(path, {
7300
8218
  params: options.query,
7301
- headers: requestHeaders
8219
+ headers: requestHeaders,
8220
+ maxRetries: options.maxRetries
7302
8221
  });
7303
8222
  } catch (error) {
7304
8223
  this.handleHttpError({
@@ -7317,7 +8236,8 @@ var WorkOS = class {
7317
8236
  try {
7318
8237
  res = await this.client.put(path, entity, {
7319
8238
  params: options.query,
7320
- headers: requestHeaders
8239
+ headers: requestHeaders,
8240
+ maxRetries: options.maxRetries
7321
8241
  });
7322
8242
  } catch (error) {
7323
8243
  this.handleHttpError({
@@ -7336,7 +8256,8 @@ var WorkOS = class {
7336
8256
  try {
7337
8257
  res = await this.client.patch(path, entity, {
7338
8258
  params: options.query,
7339
- headers: requestHeaders
8259
+ headers: requestHeaders,
8260
+ maxRetries: options.maxRetries
7340
8261
  });
7341
8262
  } catch (error) {
7342
8263
  this.handleHttpError({
@@ -7500,4 +8421,4 @@ function createWorkOS(options) {
7500
8421
  //#endregion
7501
8422
  export { FetchHttpClient as A, NoApiKeyProvidedException as C, isAuthenticationErrorData as D, AuthenticationException as E, GenericServerException as O, NotFoundException as S, BadRequestException as T, UnprocessableEntityException as _, DomainDataState as a, RateLimitExceededException as b, FeatureFlagsRuntimeClient as c, serializeRevokeSessionOptions as d, AuthenticateWithSessionCookieFailureReason as f, Actions as g, AutoPaginatable as h, OrganizationDomainVerificationStrategy as i, SubtleCryptoProvider as j, ApiKeyRequiredException as k, CookieSession as l, Webhooks as m, ConnectionType as n, GenerateLinkIntent as o, PKCE as p, OrganizationDomainState as r, WorkOS as s, createWorkOS as t, RefreshSessionFailureReason as u, UnauthorizedException as v, ConflictException as w, OauthException as x, SignatureVerificationException as y };
7502
8423
 
7503
- //# sourceMappingURL=factory-BjWO1KkE.mjs.map
8424
+ //# sourceMappingURL=factory-BdXIrbcU.mjs.map