hanzio 1.2.0 → 2.0.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.
Files changed (145) hide show
  1. package/README.md +786 -239
  2. package/dist/api-wrapper/builders.d.ts +4 -3
  3. package/dist/api-wrapper/create-client.d.ts +1 -1
  4. package/dist/api-wrapper/describe.d.ts +16 -0
  5. package/dist/api-wrapper/endpoint.d.ts +18 -0
  6. package/dist/api-wrapper/errors.d.ts +39 -2
  7. package/dist/api-wrapper/index.d.ts +5 -0
  8. package/dist/api-wrapper/otel.d.ts +44 -0
  9. package/dist/api-wrapper/paginate.d.ts +12 -0
  10. package/dist/api-wrapper/redaction.d.ts +2 -0
  11. package/dist/api-wrapper/shared.d.ts +16 -2
  12. package/dist/api-wrapper/testing.d.ts +23 -0
  13. package/dist/api-wrapper/transport.d.ts +4 -5
  14. package/dist/api-wrapper/types.d.ts +103 -18
  15. package/dist/array/index.d.ts +50 -4
  16. package/dist/cache/createCache.d.ts +31 -0
  17. package/dist/cache/index.d.ts +19 -2
  18. package/dist/color/contrast.d.ts +40 -0
  19. package/dist/color/index.d.ts +2 -0
  20. package/dist/{math → color}/metricsSeriesColors.d.ts +14 -7
  21. package/dist/cool-console-log/index.d.ts +34 -5
  22. package/dist/crypto/encoding.d.ts +18 -0
  23. package/dist/crypto/hash.d.ts +33 -0
  24. package/dist/crypto/index.d.ts +4 -0
  25. package/dist/crypto/sealer.d.ts +25 -0
  26. package/dist/crypto/webhook.d.ts +20 -0
  27. package/dist/date/index.d.ts +46 -2
  28. package/dist/emitter/index.d.ts +21 -0
  29. package/dist/error/index.d.ts +12 -0
  30. package/dist/format/index.d.ts +102 -0
  31. package/dist/function/index.d.ts +60 -0
  32. package/dist/guard/index.d.ts +20 -0
  33. package/dist/i18n/index.d.ts +37 -0
  34. package/dist/index-0zvtcbzy.js +224 -0
  35. package/dist/index-181e6vfw.js +29 -0
  36. package/dist/index-8r2vdzjg.js +87 -0
  37. package/dist/index-hy7kbb99.js +157 -0
  38. package/dist/{src/secrets/infisical.js → index-j1ybktbr.js} +500 -538
  39. package/dist/index-k9yx6bne.js +89 -0
  40. package/dist/index-kj1phgrx.js +169 -0
  41. package/dist/index-mnkcfyx8.js +78 -0
  42. package/dist/{p-queue/index.js → index-pwt0dz63.js} +7 -11
  43. package/dist/index-rp5pqghz.js +157 -0
  44. package/dist/index-srt06xd2.js +15 -0
  45. package/dist/index-wjyb9bsd.js +263 -0
  46. package/dist/index.d.ts +7 -7
  47. package/dist/jwt/index.d.ts +50 -2
  48. package/dist/math/index.d.ts +2 -2
  49. package/dist/math/linearRegressionTrend.d.ts +14 -1
  50. package/dist/math/scale.d.ts +8 -0
  51. package/dist/object/index.d.ts +19 -0
  52. package/dist/p-queue/index.d.ts +1 -1
  53. package/dist/promise/index.d.ts +97 -2
  54. package/dist/sitemap/index.d.ts +48 -6
  55. package/dist/src/api-wrapper/index.js +60 -1130
  56. package/dist/src/api-wrapper/testing.js +20 -0
  57. package/dist/{cool-console-log → src/cool-console-log}/index.js +80 -33
  58. package/dist/src/crypto/index.js +195 -0
  59. package/dist/src/format/index.js +211 -0
  60. package/dist/src/i18n/index.js +36 -0
  61. package/dist/src/index.js +739 -3145
  62. package/dist/src/jwt/index.js +138 -92
  63. package/dist/src/p-queue/index.js +9 -437
  64. package/dist/src/secrets/index.js +44 -1428
  65. package/dist/src/secrets/vite.js +6 -39
  66. package/dist/src/secrets/worker.js +10 -273
  67. package/dist/src/sitemap/index.js +183 -511
  68. package/dist/src/storage/index.js +119 -0
  69. package/dist/src/zod/index.js +340 -167
  70. package/dist/state/index.d.ts +21 -0
  71. package/dist/storage/index.d.ts +58 -0
  72. package/dist/string/index.d.ts +75 -2
  73. package/dist/typedswitch/index.d.ts +31 -24
  74. package/dist/types/index.d.ts +11 -0
  75. package/dist/url/index.d.ts +50 -1
  76. package/dist/zod/index.d.ts +32 -3
  77. package/dist/zod/introspect.d.ts +19 -0
  78. package/dist/zod/jsonToZodSchemaMapper.d.ts +3 -1
  79. package/dist/zod/zodMinMaxFilter.d.ts +22 -3
  80. package/dist/zod/zodToTypeString.d.ts +8 -3
  81. package/package.json +78 -7
  82. package/src/api-wrapper/actions-impl.ts +11 -72
  83. package/src/api-wrapper/builders.ts +32 -25
  84. package/src/api-wrapper/create-client.ts +171 -41
  85. package/src/api-wrapper/describe.ts +157 -0
  86. package/src/api-wrapper/endpoint.ts +26 -0
  87. package/src/api-wrapper/error-reporting.ts +7 -1
  88. package/src/api-wrapper/errors.ts +107 -2
  89. package/src/api-wrapper/headers.ts +11 -6
  90. package/src/api-wrapper/index.ts +5 -0
  91. package/src/api-wrapper/otel.ts +139 -0
  92. package/src/api-wrapper/paginate.ts +28 -0
  93. package/src/api-wrapper/redaction.ts +42 -0
  94. package/src/api-wrapper/shared.ts +21 -2
  95. package/src/api-wrapper/testing.ts +48 -0
  96. package/src/api-wrapper/transport.ts +41 -43
  97. package/src/api-wrapper/types.ts +185 -18
  98. package/src/array/index.ts +195 -42
  99. package/src/cache/createCache.ts +157 -0
  100. package/src/cache/index.ts +132 -147
  101. package/src/color/contrast.ts +163 -0
  102. package/src/color/index.ts +22 -0
  103. package/src/{math → color}/metricsSeriesColors.ts +47 -49
  104. package/src/cool-console-log/index.ts +128 -41
  105. package/src/crypto/encoding.ts +83 -0
  106. package/src/crypto/hash.ts +170 -0
  107. package/src/crypto/index.ts +26 -0
  108. package/src/crypto/sealer.ts +168 -0
  109. package/src/crypto/webhook.ts +86 -0
  110. package/src/date/index.ts +109 -34
  111. package/src/emitter/index.ts +82 -0
  112. package/src/error/index.ts +63 -0
  113. package/src/format/index.ts +389 -0
  114. package/src/function/index.ts +201 -0
  115. package/src/guard/index.ts +80 -0
  116. package/src/i18n/index.ts +125 -0
  117. package/src/index.ts +11 -7
  118. package/src/jwt/index.ts +199 -125
  119. package/src/math/index.ts +5 -10
  120. package/src/math/linearRegressionTrend.ts +33 -8
  121. package/src/math/scale.ts +17 -0
  122. package/src/object/index.ts +99 -0
  123. package/src/p-queue/index.ts +2 -0
  124. package/src/promise/index.ts +304 -9
  125. package/src/sitemap/index.ts +293 -130
  126. package/src/state/index.ts +133 -81
  127. package/src/storage/index.ts +187 -0
  128. package/src/string/index.ts +261 -23
  129. package/src/typedswitch/index.ts +58 -38
  130. package/src/types/index.ts +14 -0
  131. package/src/url/index.ts +146 -1
  132. package/src/zod/index.ts +105 -9
  133. package/src/zod/introspect.ts +103 -0
  134. package/src/zod/jsonToZodSchemaMapper.ts +44 -21
  135. package/src/zod/zodMinMaxFilter.ts +37 -13
  136. package/src/zod/zodToTypeString.ts +184 -181
  137. package/dist/api-wrapper/index.js +0 -250
  138. package/dist/gzip/index.d.ts +0 -2
  139. package/dist/gzip/index.js +0 -16
  140. package/dist/index.js +0 -1823
  141. package/dist/jwt/index.js +0 -19
  142. package/dist/sitemap/index.js +0 -552
  143. package/dist/src/gzip/index.js +0 -16
  144. package/dist/src/secrets/loaders.js +0 -1529
  145. package/dist/zod/index.js +0 -210
@@ -1,5 +1,17 @@
1
- // src/secrets/infisical.ts
2
- import { z as z2 } from "zod";
1
+ import {
2
+ createCache2
3
+ } from "./index-k9yx6bne.js";
4
+ import {
5
+ ok2,
6
+ err2,
7
+ promiseTimeout2,
8
+ exponentialBackoff2,
9
+ anySignal2
10
+ } from "./index-0zvtcbzy.js";
11
+ import {
12
+ buildQueryString2,
13
+ parseRetryAfter2
14
+ } from "./index-mnkcfyx8.js";
3
15
  // src/api-wrapper/headers.ts
4
16
  var CANONICAL_HEADER_NAMES = {
5
17
  "content-type": "Content-Type",
@@ -47,7 +59,12 @@ function buildFetchBody(body, headers, configError) {
47
59
  return body;
48
60
  if (hasJsonContentType(headers))
49
61
  return JSON.stringify(body);
50
- if (typeof body === "object" && (Object.getPrototypeOf(body) === Object.prototype || Object.getPrototypeOf(body) === null) && configError) {
62
+ const isJsonLike = Array.isArray(body) || typeof body === "object" && (Object.getPrototypeOf(body) === Object.prototype || Object.getPrototypeOf(body) === null);
63
+ if (isJsonLike && getHeader(headers, "content-type") === undefined) {
64
+ headers["Content-Type"] = "application/json";
65
+ return JSON.stringify(body);
66
+ }
67
+ if (isJsonLike && configError) {
51
68
  throw configError("Request body is a plain object but Content-Type is not application/json");
52
69
  }
53
70
  return body;
@@ -197,9 +214,12 @@ function tryParseJson(body) {
197
214
  // src/api-wrapper/errors.ts
198
215
  var MAX_BODY_PREVIEW = 500;
199
216
 
200
- class ApiError extends Error {
217
+ class ApiError2 extends Error {
201
218
  context;
202
219
  cause;
220
+ get category() {
221
+ return "unknown";
222
+ }
203
223
  constructor(message, context, options) {
204
224
  super(message);
205
225
  this.name = "ApiError";
@@ -209,13 +229,14 @@ class ApiError extends Error {
209
229
  toJSON() {
210
230
  return {
211
231
  name: this.name,
232
+ category: this.category,
212
233
  message: this.message,
213
234
  context: this.context
214
235
  };
215
236
  }
216
237
  }
217
238
 
218
- class HttpResponseError extends ApiError {
239
+ class HttpResponseError2 extends ApiError2 {
219
240
  status;
220
241
  body;
221
242
  bodyJson;
@@ -231,6 +252,9 @@ class HttpResponseError extends ApiError {
231
252
  this.requestId = getHeader(responseHeaders, "x-request-id") ?? getHeader(responseHeaders, "x-correlation-id");
232
253
  this.bodyJson = tryParseJson(body);
233
254
  }
255
+ get category() {
256
+ return this.status >= 500 ? "server_error" : "client_error";
257
+ }
234
258
  toJSON() {
235
259
  return {
236
260
  ...super.toJSON(),
@@ -243,25 +267,31 @@ class HttpResponseError extends ApiError {
243
267
  }
244
268
  }
245
269
 
246
- class ResponseValidationError extends ApiError {
270
+ class ResponseValidationError2 extends ApiError2 {
247
271
  zodError;
248
272
  rawResponse;
249
273
  issues;
250
274
  validationIssues;
251
- constructor(zodError, rawResponse, context) {
275
+ invalidJson;
276
+ constructor(zodError, rawResponse, context, options = {}) {
252
277
  const issues = formatZodIssues(zodError, rawResponse);
253
278
  const summary = renderIssueSummary(issues);
254
279
  super(`Response validation failed (${context.method} ${context.url}):
255
280
  ${summary}`, context, { cause: zodError });
256
281
  this.name = "ResponseValidationError";
282
+ this.invalidJson = options.invalidJson ?? false;
257
283
  this.zodError = zodError;
258
284
  this.rawResponse = rawResponse;
259
285
  this.issues = issues;
260
286
  this.validationIssues = issues.map((i) => `${i.path}: ${i.message}`).join("; ");
261
287
  }
288
+ get category() {
289
+ return "output_validation";
290
+ }
262
291
  toJSON() {
263
292
  return {
264
293
  ...super.toJSON(),
294
+ invalidJson: this.invalidJson,
265
295
  issues: this.issues,
266
296
  validationIssues: this.validationIssues,
267
297
  rawResponsePreview: previewValue(this.rawResponse, 1000)
@@ -269,7 +299,7 @@ ${summary}`, context, { cause: zodError });
269
299
  }
270
300
  }
271
301
 
272
- class RequestValidationError extends ApiError {
302
+ class RequestValidationError2 extends ApiError2 {
273
303
  zodError;
274
304
  target;
275
305
  rawInput;
@@ -287,6 +317,9 @@ ${summary}`, context, { cause: zodError });
287
317
  this.issues = issues;
288
318
  this.validationIssues = issues.map((i) => `${i.path}: ${i.message}`).join("; ");
289
319
  }
320
+ get category() {
321
+ return "input_validation";
322
+ }
290
323
  toJSON() {
291
324
  return {
292
325
  ...super.toJSON(),
@@ -297,63 +330,92 @@ ${summary}`, context, { cause: zodError });
297
330
  }
298
331
  }
299
332
 
300
- class RequestTimeoutError extends ApiError {
333
+ class RequestTimeoutError2 extends ApiError2 {
301
334
  timeoutMs;
302
335
  constructor(timeoutMs, context) {
303
336
  super(`Request timed out after ${timeoutMs}ms: ${context.method} ${context.url}`, context);
304
337
  this.name = "RequestTimeoutError";
305
338
  this.timeoutMs = timeoutMs;
306
339
  }
340
+ get category() {
341
+ return "timeout";
342
+ }
307
343
  }
308
344
 
309
- class NetworkError extends ApiError {
345
+ class NetworkError2 extends ApiError2 {
310
346
  constructor(message, context, cause) {
311
347
  super(message, context, { cause });
312
348
  this.name = "NetworkError";
313
349
  }
350
+ get category() {
351
+ return "network";
352
+ }
314
353
  }
315
354
 
316
- class RequestAbortedError extends ApiError {
355
+ class RequestAbortedError2 extends ApiError2 {
317
356
  constructor(context, cause) {
318
357
  super(`Request aborted: ${context.method} ${context.url}`, context, {
319
358
  cause
320
359
  });
321
360
  this.name = "RequestAbortedError";
322
361
  }
362
+ get category() {
363
+ return "aborted";
364
+ }
323
365
  }
324
366
 
325
- class ConfigError extends ApiError {
367
+ class ConfigError2 extends ApiError2 {
326
368
  constructor(message, context) {
327
369
  super(message, context);
328
370
  this.name = "ConfigError";
329
371
  }
372
+ get category() {
373
+ return "config";
374
+ }
375
+ }
376
+
377
+ class ApiResponseError2 extends ApiError2 {
378
+ data;
379
+ constructor(message, data, context, cause) {
380
+ super(message, context, { cause });
381
+ this.name = "ApiResponseError";
382
+ this.data = data;
383
+ }
384
+ get category() {
385
+ return "response_rejected";
386
+ }
387
+ toJSON() {
388
+ return {
389
+ ...super.toJSON(),
390
+ dataPreview: previewValue(this.data, 1000)
391
+ };
392
+ }
330
393
  }
331
394
 
332
- class ActionError extends ApiError {
395
+ class ActionError2 extends ApiError2 {
333
396
  constructor(message, context, cause) {
334
397
  super(message, context, { cause });
335
398
  this.name = "ActionError";
336
399
  }
400
+ get category() {
401
+ return "action";
402
+ }
337
403
  }
338
- var isApiError = (e) => e instanceof ApiError;
339
- var isHttpResponseError = (e) => e instanceof HttpResponseError;
340
- var isResponseValidationError = (e) => e instanceof ResponseValidationError;
341
- var isRequestValidationError = (e) => e instanceof RequestValidationError;
342
- var isRequestTimeoutError = (e) => e instanceof RequestTimeoutError;
343
- var isNetworkError = (e) => e instanceof NetworkError;
344
- var isRequestAbortedError = (e) => e instanceof RequestAbortedError;
345
- var isConfigError = (e) => e instanceof ConfigError;
346
- var isActionError = (e) => e instanceof ActionError;
347
- function isNonRetryableApiError(error) {
348
- return error instanceof HttpResponseError || error instanceof ResponseValidationError || error instanceof RequestValidationError || error instanceof ConfigError || error instanceof RequestAbortedError;
404
+ var isApiError2 = (e) => e instanceof ApiError2;
405
+ var isHttpResponseError2 = (e) => e instanceof HttpResponseError2;
406
+ var isResponseValidationError2 = (e) => e instanceof ResponseValidationError2;
407
+ var isRequestValidationError2 = (e) => e instanceof RequestValidationError2;
408
+ var isRequestTimeoutError2 = (e) => e instanceof RequestTimeoutError2;
409
+ var isNetworkError2 = (e) => e instanceof NetworkError2;
410
+ var isRequestAbortedError2 = (e) => e instanceof RequestAbortedError2;
411
+ var isConfigError2 = (e) => e instanceof ConfigError2;
412
+ var isActionError2 = (e) => e instanceof ActionError2;
413
+ var isApiResponseError2 = (e) => e instanceof ApiResponseError2;
414
+ function isNonRetryableApiError2(error) {
415
+ return error instanceof HttpResponseError2 || error instanceof ResponseValidationError2 || error instanceof ApiResponseError2 || error instanceof RequestValidationError2 || error instanceof ConfigError2 || error instanceof RequestAbortedError2;
349
416
  }
350
417
  // src/api-wrapper/builders.ts
351
418
  import { ZodError as ZodError2 } from "zod";
352
- function formatQueryString(queryParams, doNotEncode) {
353
- if (Object.keys(queryParams).length === 0)
354
- return "";
355
- return doNotEncode ? Object.entries(queryParams).map(([key, value]) => `${key}=${value}`).join("&") : new URLSearchParams(queryParams).toString();
356
- }
357
419
  function buildUrl(options) {
358
420
  const {
359
421
  endpoint,
@@ -367,7 +429,7 @@ function buildUrl(options) {
367
429
  } = options;
368
430
  let finalUrl;
369
431
  if (url) {
370
- finalUrl = replacePathParams(url, params, configError);
432
+ finalUrl = replaceUrlPathParams(url, params, configError);
371
433
  } else {
372
434
  const defaultBaseUrl = defaultBaseApiUrl ?? Object.keys(baseApiUrls)[0];
373
435
  if (!defaultBaseUrl) {
@@ -380,9 +442,11 @@ function buildUrl(options) {
380
442
  }
381
443
  const baseUrl = typeof configBaseUrl === "function" ? configBaseUrl() : configBaseUrl;
382
444
  const path = typeof endpoint.path === "function" ? endpoint.path(baseUrl) : endpoint.path;
383
- finalUrl = `${baseUrl}${replacePathParams(path, params, configError)}`;
445
+ finalUrl = joinUrlPath(baseUrl, replacePathParams(path, params, configError));
384
446
  }
385
- const queryString = formatQueryString(queryParams, doNotEncodeQueryParams);
447
+ const queryString = buildQueryString2(queryParams, {
448
+ encode: !doNotEncodeQueryParams
449
+ });
386
450
  return {
387
451
  finalUrl,
388
452
  fullUrl: queryString ? `${finalUrl}?${queryString}` : finalUrl
@@ -395,7 +459,7 @@ function buildPathParams(endpoint, params, ctx) {
395
459
  return endpoint.reqParamsSchema.parse(params);
396
460
  } catch (error) {
397
461
  if (error instanceof ZodError2) {
398
- throw new RequestValidationError(error, "params", params, ctx());
462
+ throw new RequestValidationError2(error, "params", params, ctx());
399
463
  }
400
464
  throw error;
401
465
  }
@@ -408,15 +472,14 @@ function buildQueryParams(endpoint, query, ctx) {
408
472
  parsedQuery = endpoint.reqQuerySchema.parse(query);
409
473
  } catch (error) {
410
474
  if (error instanceof ZodError2) {
411
- throw new RequestValidationError(error, "query", query, ctx());
475
+ throw new RequestValidationError2(error, "query", query, ctx());
412
476
  }
413
477
  throw error;
414
478
  }
415
479
  } else {
416
480
  parsedQuery = query ?? {};
417
481
  }
418
- const merged = { ...defaultParams, ...parsedQuery };
419
- return Object.fromEntries(Object.entries(merged).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)]));
482
+ return { ...defaultParams, ...parsedQuery };
420
483
  }
421
484
  function buildRequestBody(endpoint, body, ctx) {
422
485
  if (!endpoint.reqBodySchema)
@@ -426,7 +489,7 @@ function buildRequestBody(endpoint, body, ctx) {
426
489
  parsedBody = endpoint.reqBodySchema.parse(body);
427
490
  } catch (error) {
428
491
  if (error instanceof ZodError2) {
429
- throw new RequestValidationError(error, "body", body, ctx());
492
+ throw new RequestValidationError2(error, "body", body, ctx());
430
493
  }
431
494
  throw error;
432
495
  }
@@ -449,7 +512,7 @@ function buildHeaders(endpoint, headers, defaultHeaders, ctx) {
449
512
  parsedHeaders = endpoint.reqHeadersSchema.parse(headers);
450
513
  } catch (error) {
451
514
  if (error instanceof ZodError2) {
452
- throw new RequestValidationError(error, "headers", headers, ctx());
515
+ throw new RequestValidationError2(error, "headers", headers, ctx());
453
516
  }
454
517
  throw error;
455
518
  }
@@ -463,8 +526,20 @@ function buildHeaders(endpoint, headers, defaultHeaders, ctx) {
463
526
  ...parsedHeaders
464
527
  });
465
528
  }
529
+ function joinUrlPath(base, path) {
530
+ if (!path || path.startsWith("?"))
531
+ return `${base}${path}`;
532
+ return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
533
+ }
534
+ function replaceUrlPathParams(url, params, configError) {
535
+ const origin = url.match(/^[a-z][a-z\d+.-]*:\/\/[^/?#]*/i)?.[0] ?? "";
536
+ const rest = url.slice(origin.length);
537
+ const suffixIndex = rest.search(/[?#]/);
538
+ const path = suffixIndex === -1 ? rest : rest.slice(0, suffixIndex);
539
+ return `${origin}${replacePathParams(path, params, configError)}${rest.slice(path.length)}`;
540
+ }
466
541
  function replacePathParams(path, params, configError) {
467
- return path.replace(/:(\w+)/g, (_, key) => {
542
+ return path.replace(/:([A-Za-z_]\w*)/g, (_, key) => {
468
543
  const value = params?.[key];
469
544
  if (value === undefined) {
470
545
  throw configError(`Missing required path parameter: ${key}`);
@@ -475,57 +550,12 @@ function replacePathParams(path, params, configError) {
475
550
 
476
551
  // src/api-wrapper/actions-impl.ts
477
552
  function createActionCache() {
478
- const store = new Map;
479
- const isExpired = (entry) => entry.expiresAt !== undefined && entry.expiresAt <= Date.now();
480
- const cache = async (key, fn, options) => {
481
- const existing = store.get(key);
482
- if (existing && !isExpired(existing)) {
483
- if (existing.inflight)
484
- return existing.inflight;
485
- if (existing.hasValue)
486
- return existing.value;
487
- }
488
- const promise = (async () => fn())();
489
- const entry = {
490
- hasValue: false,
491
- inflight: promise,
492
- expiresAt: options?.ttlMs !== undefined ? Date.now() + options.ttlMs : undefined
493
- };
494
- store.set(key, entry);
495
- try {
496
- const value = await promise;
497
- entry.value = value;
498
- entry.hasValue = true;
499
- entry.inflight = undefined;
500
- return value;
501
- } catch (error) {
502
- store.delete(key);
503
- throw error;
504
- }
505
- };
506
- cache.get = (key) => {
507
- const entry = store.get(key);
508
- if (!entry || !entry.hasValue)
509
- return;
510
- if (isExpired(entry)) {
511
- store.delete(key);
512
- return;
513
- }
514
- return entry.value;
515
- };
516
- cache.set = (key, value, options) => {
517
- store.set(key, {
518
- value,
519
- hasValue: true,
520
- expiresAt: options?.ttlMs !== undefined ? Date.now() + options.ttlMs : undefined
521
- });
522
- };
523
- cache.invalidate = (key) => {
524
- store.delete(key);
525
- };
526
- cache.clear = () => {
527
- store.clear();
528
- };
553
+ const store = createCache2();
554
+ const cache = (key, fn, options) => store.getOrSet(key, fn, options);
555
+ cache.get = (key) => store.get(key);
556
+ cache.set = (key, value, options) => store.set(key, value, options);
557
+ cache.invalidate = (key) => store.delete(key);
558
+ cache.clear = () => store.clear();
529
559
  return cache;
530
560
  }
531
561
  function makeDefineAction() {
@@ -539,12 +569,125 @@ function makeDefineAction() {
539
569
  const def = args[0];
540
570
  return {
541
571
  ...def,
542
- noRuntimeInput: true
572
+ noRuntimeInput: def.input === undefined
543
573
  };
544
574
  }
545
575
  return defineAction;
546
576
  }
547
- var defineAction = makeDefineAction();
577
+ var defineAction2 = makeDefineAction();
578
+
579
+ // src/api-wrapper/describe.ts
580
+ var BODY_PREVIEW = 500;
581
+ var schemaByTarget = {
582
+ body: "reqBodySchema",
583
+ query: "reqQuerySchema",
584
+ params: "reqParamsSchema",
585
+ headers: "reqHeadersSchema",
586
+ input: "the action input schema"
587
+ };
588
+ function headline(error) {
589
+ if (error instanceof HttpResponseError2) {
590
+ const status = `HTTP ${error.status}`;
591
+ if (error.status >= 500) {
592
+ return `server error (${status}): the API failed while handling the request`;
593
+ }
594
+ if (error.status === 401 || error.status === 403) {
595
+ return `request rejected (${status}): check credentials and permissions`;
596
+ }
597
+ if (error.status === 404) {
598
+ return `request rejected (${status}): check the path and the IDs in it`;
599
+ }
600
+ if (error.status === 429)
601
+ return `rate limited (${status})`;
602
+ return `request rejected (${status}): check params, query and body`;
603
+ }
604
+ if (error instanceof RequestValidationError2) {
605
+ return `input validation failed: the caller's ${error.target} doesn't match ${schemaByTarget[error.target]} (nothing was sent)`;
606
+ }
607
+ if (error instanceof ResponseValidationError2) {
608
+ return error.invalidJson ? "output validation failed: the response body is not valid JSON" : "output validation failed: the response doesn't match resSchema";
609
+ }
610
+ if (error instanceof ApiResponseError2) {
611
+ return `response rejected by checkResponse: ${error.message}`;
612
+ }
613
+ if (error instanceof RequestTimeoutError2) {
614
+ return `timed out after ${error.timeoutMs}ms`;
615
+ }
616
+ const labels = {
617
+ network: `network error: couldn't reach the API (${error.message})`,
618
+ aborted: "aborted by the caller",
619
+ config: `configuration error: ${error.message}`,
620
+ action: `action failed: ${error.message}`
621
+ };
622
+ return labels[error.category] ?? error.message;
623
+ }
624
+ function details(error) {
625
+ if (error instanceof HttpResponseError2) {
626
+ const body = error.bodyJson === undefined ? error.body : previewValue(error.bodyJson, BODY_PREVIEW);
627
+ return body ? [
628
+ ` response: ${body.length > BODY_PREVIEW ? `${body.slice(0, BODY_PREVIEW)}…` : body}`
629
+ ] : [];
630
+ }
631
+ if (error instanceof ResponseValidationError2 || error instanceof RequestValidationError2) {
632
+ const lines = [renderIssueSummary(error.issues)];
633
+ if (error instanceof ResponseValidationError2 && !error.invalidJson) {
634
+ lines.push(" fix: update resSchema (or resFormatter), or mark changed fields optional");
635
+ }
636
+ return lines;
637
+ }
638
+ if (error instanceof ApiResponseError2) {
639
+ return [` response: ${previewValue(error.data, BODY_PREVIEW)}`];
640
+ }
641
+ if (error instanceof ActionError2 && error.cause instanceof Error) {
642
+ return error.cause.stack ? [` cause: ${error.cause.stack}`] : [];
643
+ }
644
+ return [];
645
+ }
646
+ function describeApiError2(error) {
647
+ const { context } = error;
648
+ const sent = error.category !== "input_validation" && error.category !== "config";
649
+ const meta = [
650
+ context.url ? `${context.method} ${context.url}` : context.method,
651
+ ...sent ? [`attempt ${context.attempt + 1}/${context.maxRetries + 1}`] : [],
652
+ `${context.elapsedMs}ms`
653
+ ];
654
+ if (error instanceof HttpResponseError2 && error.requestId) {
655
+ meta.push(`request id ${error.requestId}`);
656
+ }
657
+ return [
658
+ `✗ ${context.endpoint} failed: ${headline(error)}`,
659
+ ` ${meta.join(" · ")}`,
660
+ ...details(error)
661
+ ].join(`
662
+ `);
663
+ }
664
+ function apiErrorLogAttributes2(error) {
665
+ const { context } = error;
666
+ const attributes = {
667
+ errorName: error.name,
668
+ category: error.category,
669
+ endpoint: context.endpoint,
670
+ method: context.method,
671
+ url: context.url,
672
+ attempt: context.attempt,
673
+ maxRetries: context.maxRetries,
674
+ elapsedMs: context.elapsedMs
675
+ };
676
+ if (error instanceof HttpResponseError2) {
677
+ attributes.status = error.status;
678
+ if (error.requestId)
679
+ attributes.requestId = error.requestId;
680
+ }
681
+ if (error instanceof ResponseValidationError2 || error instanceof RequestValidationError2) {
682
+ attributes.issueCount = error.issues.length;
683
+ attributes.issues = error.validationIssues;
684
+ }
685
+ if (error instanceof RequestValidationError2)
686
+ attributes.target = error.target;
687
+ if (error instanceof RequestTimeoutError2)
688
+ attributes.timeoutMs = error.timeoutMs;
689
+ return attributes;
690
+ }
548
691
 
549
692
  // src/api-wrapper/redaction.ts
550
693
  var SENSITIVE_HEADER_KEYS = new Set([
@@ -567,6 +710,16 @@ var SENSITIVE_BODY_KEYS = new Set([
567
710
  "apikey",
568
711
  "api_key"
569
712
  ]);
713
+ var SENSITIVE_QUERY_KEYS = new Set([
714
+ ...SENSITIVE_BODY_KEYS,
715
+ "key",
716
+ "code",
717
+ "sig",
718
+ "signature",
719
+ "x-amz-signature",
720
+ "x-amz-credential",
721
+ "x-amz-security-token"
722
+ ]);
570
723
  function redactHeaders(headers) {
571
724
  if (!headers)
572
725
  return;
@@ -595,9 +748,29 @@ function redactBody(body) {
595
748
  }
596
749
  return out;
597
750
  }
751
+ function redactUrl(url) {
752
+ const queryStart = url.indexOf("?");
753
+ if (queryStart === -1)
754
+ return url;
755
+ const hashStart = url.indexOf("#", queryStart);
756
+ const query = url.slice(queryStart + 1, hashStart === -1 ? undefined : hashStart);
757
+ const redacted = query.split("&").map((pair) => {
758
+ const [key = ""] = pair.split("=", 1);
759
+ return SENSITIVE_QUERY_KEYS.has(decodeKey(key).toLowerCase()) ? `${key}=[REDACTED]` : pair;
760
+ }).join("&");
761
+ return `${url.slice(0, queryStart + 1)}${redacted}${hashStart === -1 ? "" : url.slice(hashStart)}`;
762
+ }
763
+ function decodeKey(key) {
764
+ try {
765
+ return decodeURIComponent(key.replace(/\+/g, " "));
766
+ } catch {
767
+ return key;
768
+ }
769
+ }
598
770
  function defaultRedactContext(ctx) {
599
771
  return {
600
772
  ...ctx,
773
+ url: redactUrl(ctx.url),
601
774
  requestHeaders: redactHeaders(ctx.requestHeaders),
602
775
  requestBody: redactBody(ctx.requestBody),
603
776
  meta: ctx.meta
@@ -610,11 +783,15 @@ function applyErrorContextRedaction(ctx, config) {
610
783
  return config.redact ? config.redact(base) : base;
611
784
  }
612
785
  async function reportApiError(err, config) {
786
+ const rawUrl = err.context.url;
613
787
  err.context = applyErrorContextRedaction(err.context, config);
788
+ if (rawUrl && rawUrl !== err.context.url) {
789
+ err.message = err.message.split(rawUrl).join(err.context.url);
790
+ }
614
791
  try {
615
792
  await config.onError?.(err);
616
793
  } catch {}
617
- config.logger?.error?.(err);
794
+ config.logger?.error?.(describeApiError2(err), apiErrorLogAttributes2(err));
618
795
  return err;
619
796
  }
620
797
 
@@ -648,7 +825,7 @@ async function validateResponse(schema, data, ctx) {
648
825
  return await schema.parseAsync(data);
649
826
  } catch (error) {
650
827
  if (error instanceof ZodError3) {
651
- throw new ResponseValidationError(error, data, ctx());
828
+ throw new ResponseValidationError2(error, data, ctx());
652
829
  }
653
830
  throw error;
654
831
  }
@@ -656,27 +833,27 @@ async function validateResponse(schema, data, ctx) {
656
833
  async function httpRequest(config, ctx) {
657
834
  const timeoutController = new AbortController;
658
835
  const timeout = config.timeoutMs === undefined ? undefined : setTimeout(() => timeoutController.abort(), config.timeoutMs);
659
- const signal = mergeSignals(timeoutController.signal, config.userSignal);
836
+ const signal = anySignal2(timeoutController.signal, config.userSignal);
660
837
  try {
661
838
  return await config.fetchFn(config.fullUrl, {
662
839
  method: config.method,
663
840
  headers: config.headers,
664
- body: buildFetchBody(config.body, config.headers, (msg) => new ConfigError(msg, ctx())),
841
+ body: buildFetchBody(config.body, config.headers, (msg) => new ConfigError2(msg, ctx())),
665
842
  signal
666
843
  });
667
844
  } catch (error) {
668
845
  if (isDomAbortError(error)) {
669
846
  if (config.userSignal?.aborted) {
670
- throw new RequestAbortedError(ctx(), error);
847
+ throw new RequestAbortedError2(ctx(), error);
671
848
  }
672
849
  if (timeoutController.signal.aborted && config.timeoutMs !== undefined) {
673
- throw new RequestTimeoutError(config.timeoutMs, ctx());
850
+ throw new RequestTimeoutError2(config.timeoutMs, ctx());
674
851
  }
675
- throw new RequestAbortedError(ctx(), error);
852
+ throw new RequestAbortedError2(ctx(), error);
676
853
  }
677
- if (error instanceof ConfigError)
854
+ if (error instanceof ConfigError2)
678
855
  throw error;
679
- throw new NetworkError(error instanceof Error ? error.message : String(error), ctx(), error);
856
+ throw new NetworkError2(error instanceof Error ? error.message : String(error), ctx(), error);
680
857
  } finally {
681
858
  if (timeout)
682
859
  clearTimeout(timeout);
@@ -685,24 +862,6 @@ async function httpRequest(config, ctx) {
685
862
  function isDomAbortError(error) {
686
863
  return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
687
864
  }
688
- function mergeSignals(a, b) {
689
- if (!b)
690
- return a;
691
- const anyFn = AbortSignal.any;
692
- if (typeof anyFn === "function")
693
- return anyFn([a, b]);
694
- const controller = new AbortController;
695
- const onAbort = () => controller.abort();
696
- if (a.aborted)
697
- controller.abort();
698
- else
699
- a.addEventListener("abort", onAbort, { once: true });
700
- if (b.aborted)
701
- controller.abort();
702
- else
703
- b.addEventListener("abort", onAbort, { once: true });
704
- return controller.signal;
705
- }
706
865
  async function readErrorResponse(response) {
707
866
  const body = await response.text();
708
867
  return {
@@ -715,23 +874,15 @@ function getRetryDelay(params) {
715
874
  const maxDelay = params.maxRetryDelayMs ?? 30000;
716
875
  const { retryDelay, attempt, response } = params;
717
876
  if (response && (response.status === 429 || response.status === 503)) {
718
- const retryAfter = response.headers.get("retry-after");
719
- if (retryAfter) {
720
- const seconds = Number(retryAfter);
721
- if (Number.isFinite(seconds)) {
722
- return Math.min(Math.max(0, seconds * 1000), maxDelay);
723
- }
724
- const dateMs = Date.parse(retryAfter);
725
- if (!Number.isNaN(dateMs)) {
726
- return Math.min(Math.max(0, dateMs - Date.now()), maxDelay);
727
- }
728
- }
877
+ const retryAfterMs = parseRetryAfter2(response.headers.get("retry-after"));
878
+ if (retryAfterMs !== undefined)
879
+ return Math.min(retryAfterMs, maxDelay);
729
880
  }
730
881
  const delayMs = typeof retryDelay === "function" ? retryDelay(attempt) : retryDelay;
731
882
  return Math.min(delayMs, maxDelay);
732
883
  }
733
884
  function shouldAttemptRetryOnError(error) {
734
- return !isNonRetryableApiError(error);
885
+ return !isNonRetryableApiError2(error);
735
886
  }
736
887
  function shouldAttemptRetryOnHttp(retryCtx) {
737
888
  const { error, response } = retryCtx;
@@ -760,7 +911,12 @@ async function makeRequestWithRetry(args) {
760
911
  while (true) {
761
912
  let response;
762
913
  try {
763
- logger?.debug?.("API request", config);
914
+ logger?.debug?.("API request", {
915
+ endpoint: endpointName,
916
+ method,
917
+ url: redactUrl(fullUrl),
918
+ attempt: retryCount
919
+ });
764
920
  response = await httpRequest(config, (over) => ctx({ attempt: retryCount, ...over }));
765
921
  await onResponse?.({
766
922
  endpoint: endpointName,
@@ -791,12 +947,12 @@ async function makeRequestWithRetry(args) {
791
947
  delayMs,
792
948
  nextAttempt: retryCount + 1
793
949
  });
950
+ await sleepBeforeRetry(delayMs, config.userSignal, () => ctx({ attempt: retryCount }));
794
951
  retryCount++;
795
- await delay(delayMs);
796
952
  continue;
797
953
  }
798
954
  const { body, headers: responseHeaders } = await readErrorResponse(response);
799
- throw new HttpResponseError(response.status, body, responseHeaders, ctx({ attempt: retryCount }));
955
+ throw new HttpResponseError2(response.status, body, responseHeaders, ctx({ attempt: retryCount }));
800
956
  }
801
957
  return {
802
958
  validatedData: await validateFn(response, retryCount),
@@ -804,7 +960,7 @@ async function makeRequestWithRetry(args) {
804
960
  httpStatus: response.status
805
961
  };
806
962
  } catch (error) {
807
- if (isNonRetryableApiError(error)) {
963
+ if (isNonRetryableApiError2(error) && !(error instanceof ApiResponseError2)) {
808
964
  throw error;
809
965
  }
810
966
  const retryCtx = {
@@ -829,8 +985,8 @@ async function makeRequestWithRetry(args) {
829
985
  delayMs,
830
986
  nextAttempt: retryCount + 1
831
987
  });
988
+ await sleepBeforeRetry(delayMs, config.userSignal, () => ctx({ attempt: retryCount }));
832
989
  retryCount++;
833
- await delay(delayMs);
834
990
  }
835
991
  }
836
992
  }
@@ -843,7 +999,7 @@ async function validateAndTransformResponse(endpoint, response, ctx) {
843
999
  try {
844
1000
  responseData = text === "" ? undefined : JSON.parse(text);
845
1001
  } catch (error) {
846
- throw new ResponseValidationError(makeJsonParseZodError(error, text), text, ctx());
1002
+ throw new ResponseValidationError2(makeJsonParseZodError(error, text), text, ctx(), { invalidJson: true });
847
1003
  }
848
1004
  } else {
849
1005
  responseData = text;
@@ -852,13 +1008,17 @@ async function validateAndTransformResponse(endpoint, response, ctx) {
852
1008
  const data = await validateResponse(endpoint.resSchema, transformedData, ctx);
853
1009
  return { data, responseSizeBytes };
854
1010
  }
855
- function defaultShouldRetry(ctx) {
1011
+ function defaultShouldRetry2(ctx) {
856
1012
  if (ctx.error)
857
1013
  return shouldAttemptRetryOnError(ctx.error);
858
1014
  return shouldAttemptRetryOnHttp(ctx);
859
1015
  }
860
- function delay(ms) {
861
- return new Promise((resolve) => setTimeout(resolve, ms));
1016
+ async function sleepBeforeRetry(ms, signal, ctx) {
1017
+ try {
1018
+ await promiseTimeout2(ms, { signal });
1019
+ } catch (error) {
1020
+ throw new RequestAbortedError2(ctx(), error);
1021
+ }
862
1022
  }
863
1023
 
864
1024
  // src/api-wrapper/create-client.ts
@@ -882,7 +1042,7 @@ function resolveActionInvocation(action, actionName, first, second) {
882
1042
  if (isActionInvokeOptionsOnly(first)) {
883
1043
  return { input: undefined, options: first };
884
1044
  }
885
- throw new ConfigError(`Action "${actionName}" does not accept input; pass only optional { signal, meta }`, {
1045
+ throw new ConfigError2(`Action "${actionName}" does not accept input; pass only optional { signal, meta }`, {
886
1046
  endpoint: actionName,
887
1047
  method: "GET",
888
1048
  url: "",
@@ -916,9 +1076,11 @@ function createApiClientImpl(apiConfig) {
916
1076
  ...over
917
1077
  });
918
1078
  if (!endpoint) {
919
- throw await reportApiError(new ConfigError(`Unknown API endpoint: ${String(endpointKey)}`, ctx()), apiConfig);
1079
+ throw await reportApiError(new ConfigError2(`Unknown API endpoint: ${String(endpointKey)}`, ctx()), apiConfig);
920
1080
  }
921
1081
  baseContext.method = endpoint.method;
1082
+ if (typeof endpoint.path === "string")
1083
+ baseContext.url = endpoint.path;
922
1084
  let pathParams;
923
1085
  let queryParams;
924
1086
  let body;
@@ -927,9 +1089,10 @@ function createApiClientImpl(apiConfig) {
927
1089
  pathParams = buildPathParams(endpoint, rawInput.reqParams, ctx);
928
1090
  queryParams = buildQueryParams(endpoint, rawInput.reqQuery, ctx);
929
1091
  body = buildRequestBody(endpoint, rawInput.reqBody, ctx);
930
- headers = buildHeaders(endpoint, rawInput.reqHeaders, apiConfig.defaultHeaders ?? {}, ctx);
1092
+ const defaultHeaders = typeof apiConfig.defaultHeaders === "function" ? await apiConfig.defaultHeaders() : apiConfig.defaultHeaders;
1093
+ headers = buildHeaders(endpoint, rawInput.reqHeaders, defaultHeaders ?? {}, ctx);
931
1094
  } catch (e) {
932
- if (e instanceof ApiError)
1095
+ if (e instanceof ApiError2)
933
1096
  throw await reportApiError(e, apiConfig);
934
1097
  throw e;
935
1098
  }
@@ -943,19 +1106,19 @@ function createApiClientImpl(apiConfig) {
943
1106
  defaultBaseApiUrl: apiConfig.defaultBaseApiUrl,
944
1107
  url: input.url,
945
1108
  doNotEncodeQueryParams: endpoint.doNotEncodeQueryParams,
946
- configError: (msg) => new ConfigError(msg, ctx())
1109
+ configError: (msg) => new ConfigError2(msg, ctx())
947
1110
  });
948
1111
  fullUrl = built.fullUrl;
949
1112
  } catch (e) {
950
- if (e instanceof ApiError)
1113
+ if (e instanceof ApiError2)
951
1114
  throw await reportApiError(e, apiConfig);
952
1115
  throw e;
953
1116
  }
954
1117
  baseContext.url = fullUrl;
955
1118
  baseContext.requestHeaders = headers;
956
1119
  baseContext.requestBody = body;
957
- if (apiConfig.onRequest) {
958
- try {
1120
+ const execute = async () => {
1121
+ if (apiConfig.onRequest) {
959
1122
  const result = await apiConfig.onRequest({
960
1123
  endpoint: endpointName,
961
1124
  method: endpoint.method,
@@ -968,29 +1131,30 @@ function createApiClientImpl(apiConfig) {
968
1131
  headers = result.headers;
969
1132
  if (result && "body" in result)
970
1133
  body = result.body;
971
- } catch (e) {
972
- if (e instanceof ApiError)
973
- throw await reportApiError(e, apiConfig);
974
- throw e;
975
1134
  }
976
- }
977
- const config = {
978
- method: endpoint.method,
979
- fullUrl,
980
- body,
981
- headers,
982
- timeoutMs: input.timeoutMs ?? apiConfig.timeoutMs,
983
- fetchFn: input.fetch ?? apiConfig.fetch ?? fetch,
984
- userSignal: input.signal
985
- };
986
- try {
1135
+ const config = {
1136
+ method: endpoint.method,
1137
+ fullUrl,
1138
+ body,
1139
+ headers,
1140
+ timeoutMs: input.timeoutMs ?? apiConfig.timeoutMs,
1141
+ fetchFn: input.fetch ?? apiConfig.fetch ?? fetch,
1142
+ userSignal: input.signal
1143
+ };
987
1144
  const result = await makeRequestWithRetry({
988
1145
  config,
989
1146
  maxRetries,
990
- retryDelay: apiConfig.retryDelayMs ?? 300,
1147
+ retryDelay: apiConfig.retryDelayMs ?? ((attempt) => exponentialBackoff2(attempt + 1, {
1148
+ baseMs: 300,
1149
+ maxMs: apiConfig.maxRetryDelayMs
1150
+ })),
991
1151
  maxRetryDelayMs: apiConfig.maxRetryDelayMs,
992
- validateFn: (response, attempt) => validateAndTransformResponse(endpoint, response, (over) => ctx({ attempt, ...over })),
993
- shouldRetry: apiConfig.shouldRetry ?? defaultShouldRetry,
1152
+ validateFn: async (response, attempt) => {
1153
+ const validated = await validateAndTransformResponse(endpoint, response, (over) => ctx({ attempt, ...over }));
1154
+ await runCheckResponse(validated.data, response.status, attempt);
1155
+ return validated;
1156
+ },
1157
+ shouldRetry: apiConfig.shouldRetry ?? defaultShouldRetry2,
994
1158
  logger: apiConfig.logger,
995
1159
  ctx,
996
1160
  endpointName,
@@ -1000,22 +1164,61 @@ function createApiClientImpl(apiConfig) {
1000
1164
  onResponse: apiConfig.onResponse,
1001
1165
  onRetry: apiConfig.onRetry
1002
1166
  });
1003
- const responseTimeMs = elapsed();
1004
- const responseSizeMb = result.validatedData.responseSizeBytes / (1024 * 1024);
1005
- const requestBodySizeMb = calculateSizeInMb(config.body);
1006
1167
  return {
1007
1168
  data: result.validatedData.data,
1008
- requestBodySizeMb,
1009
- responseSizeMb,
1010
- responseTimeMs,
1169
+ requestBodySizeMb: calculateSizeInMb(config.body),
1170
+ responseSizeMb: result.validatedData.responseSizeBytes / (1024 * 1024),
1171
+ responseTimeMs: elapsed(),
1011
1172
  httpStatus: result.httpStatus,
1012
1173
  retryCount: result.retryCount
1013
1174
  };
1014
- } catch (error) {
1015
- if (error instanceof ApiError)
1016
- throw await reportApiError(error, apiConfig);
1017
- throw error;
1018
- }
1175
+ };
1176
+ const runCheckResponse = async (data, httpStatus, attempt) => {
1177
+ if (!apiConfig.checkResponse)
1178
+ return;
1179
+ try {
1180
+ await apiConfig.checkResponse(data, {
1181
+ endpoint: endpointName,
1182
+ method: endpoint.method,
1183
+ url: fullUrl,
1184
+ httpStatus,
1185
+ attempt,
1186
+ meta: input.meta
1187
+ });
1188
+ } catch (error) {
1189
+ if (error instanceof ApiError2)
1190
+ throw error;
1191
+ throw new ApiResponseError2(error instanceof Error ? error.message : String(error), data, ctx({ attempt }), error);
1192
+ }
1193
+ };
1194
+ const run = async () => {
1195
+ try {
1196
+ return await execute();
1197
+ } catch (error) {
1198
+ if (error instanceof ApiError2) {
1199
+ throw await reportApiError(error, apiConfig);
1200
+ }
1201
+ throw error;
1202
+ }
1203
+ };
1204
+ const middleware = apiConfig.use ?? [];
1205
+ if (middleware.length === 0)
1206
+ return run();
1207
+ const middlewareContext = {
1208
+ client: apiConfig.name,
1209
+ endpoint: String(endpointKey),
1210
+ method: endpoint.method,
1211
+ url: fullUrl,
1212
+ headers,
1213
+ meta: input.meta
1214
+ };
1215
+ const dispatch = (index) => {
1216
+ const current = middleware[index];
1217
+ if (!current)
1218
+ return run();
1219
+ return current(middlewareContext, () => dispatch(index + 1));
1220
+ };
1221
+ return dispatch(0);
1019
1222
  };
1020
1223
  async function invokeAction(name, rawInput, options = {}) {
1021
1224
  const action = actions[name];
@@ -1038,9 +1241,17 @@ function createApiClientImpl(apiConfig) {
1038
1241
  ...over
1039
1242
  });
1040
1243
  apiConfig.logger?.debug?.("Action start", { action: actionName });
1244
+ let parsedInput = inputForHandler;
1245
+ if (action.input) {
1246
+ const parsed = await action.input.safeParseAsync(rawInput);
1247
+ if (!parsed.success) {
1248
+ throw await reportApiError(new RequestValidationError2(parsed.error, "input", rawInput, ctx()), apiConfig);
1249
+ }
1250
+ parsedInput = parsed.data;
1251
+ }
1041
1252
  try {
1042
1253
  const result = await action.handler({
1043
- input: inputForHandler,
1254
+ input: parsedInput,
1044
1255
  api: proxy,
1045
1256
  signal: options.signal,
1046
1257
  meta: options.meta,
@@ -1053,10 +1264,10 @@ function createApiClientImpl(apiConfig) {
1053
1264
  });
1054
1265
  return result;
1055
1266
  } catch (error) {
1056
- if (error instanceof ApiError) {
1267
+ if (error instanceof ApiError2) {
1057
1268
  throw await reportApiError(error, apiConfig);
1058
1269
  }
1059
- const wrapped = new ActionError(`Action ${actionName} failed: ${error instanceof Error ? error.message : String(error)}`, ctx(), error);
1270
+ const wrapped = new ActionError2(`Action ${actionName} failed: ${error instanceof Error ? error.message : String(error)}`, ctx(), error);
1060
1271
  throw await reportApiError(wrapped, apiConfig);
1061
1272
  }
1062
1273
  }
@@ -1071,7 +1282,26 @@ function createApiClientImpl(apiConfig) {
1071
1282
  }
1072
1283
  return invokeEndpoint(key, input ?? {});
1073
1284
  };
1074
- const client = { request, cache };
1285
+ const safe = new Proxy({}, {
1286
+ get(_target, prop) {
1287
+ if (typeof prop !== "string")
1288
+ return;
1289
+ if (!(prop in apiConfig.endpoints) && !(prop in actions)) {
1290
+ return;
1291
+ }
1292
+ return async (...args) => {
1293
+ try {
1294
+ const method = Reflect.get(proxy, prop);
1295
+ return ok2(await method(...args));
1296
+ } catch (error) {
1297
+ if (error instanceof ApiError2)
1298
+ return err2(error);
1299
+ throw error;
1300
+ }
1301
+ };
1302
+ }
1303
+ });
1304
+ const client = { request, cache, safe };
1075
1305
  const proxy = new Proxy(client, {
1076
1306
  get(target, prop, receiver) {
1077
1307
  if (prop in target || typeof prop !== "string") {
@@ -1095,9 +1325,23 @@ function createApiClientImpl(apiConfig) {
1095
1325
  } else if (rawActions) {
1096
1326
  actions = rawActions;
1097
1327
  }
1328
+ const reserved = [
1329
+ ...Object.keys(apiConfig.endpoints),
1330
+ ...Object.keys(actions)
1331
+ ].filter((key) => (key in client));
1332
+ if (reserved.length > 0) {
1333
+ throw new ConfigError2(`Endpoint/action name(s) are reserved by the client: ${reserved.join(", ")}`, {
1334
+ endpoint: reserved[0],
1335
+ method: "GET",
1336
+ url: "",
1337
+ attempt: 0,
1338
+ maxRetries: 0,
1339
+ elapsedMs: 0
1340
+ });
1341
+ }
1098
1342
  const collisions = Object.keys(actions).filter((key) => (key in apiConfig.endpoints));
1099
1343
  if (collisions.length > 0) {
1100
- throw new ConfigError(`Action name(s) collide with endpoint name(s): ${collisions.join(", ")}`, {
1344
+ throw new ConfigError2(`Action name(s) collide with endpoint name(s): ${collisions.join(", ")}`, {
1101
1345
  endpoint: collisions[0],
1102
1346
  method: "GET",
1103
1347
  url: "",
@@ -1108,370 +1352,88 @@ function createApiClientImpl(apiConfig) {
1108
1352
  }
1109
1353
  return proxy;
1110
1354
  }
1111
- var createApiClient = (apiConfig) => createApiClientImpl(apiConfig);
1112
- // src/secrets/errors.ts
1113
- class SecretLoadError extends Error {
1114
- code;
1115
- operation;
1116
- status;
1117
- constructor(code, message, details = {}) {
1118
- super(message);
1119
- this.name = "SecretLoadError";
1120
- this.code = code;
1121
- this.operation = details.operation;
1122
- this.status = details.status;
1123
- }
1355
+ var createApiClient2 = (apiConfig) => createApiClientImpl(apiConfig);
1356
+ // src/api-wrapper/paginate.ts
1357
+ async function* paginate2(fetchPage, getNext, options = {}) {
1358
+ const { maxPages = Number.POSITIVE_INFINITY, signal } = options;
1359
+ let cursor;
1360
+ for (let count = 0;count < maxPages; count++) {
1361
+ signal?.throwIfAborted();
1362
+ const page = await fetchPage(cursor);
1363
+ yield page;
1364
+ const next = getNext(page);
1365
+ if (next == null)
1366
+ return;
1367
+ cursor = next;
1368
+ }
1369
+ }
1370
+ // src/api-wrapper/otel.ts
1371
+ var SPAN_KIND_CLIENT = 2;
1372
+ var SPAN_STATUS_ERROR = 2;
1373
+ function otelMiddleware2(tracer, options = {}) {
1374
+ const { spanName, attributes, includeQuery = true, inject } = options;
1375
+ return (context, next) => {
1376
+ const url = includeQuery ? redactUrl(context.url) : context.url.split(/[?#]/, 1)[0];
1377
+ const name = spanName?.(context) ?? (context.client ? `${context.client}.${context.endpoint}` : context.endpoint);
1378
+ return tracer.startActiveSpan(name, {
1379
+ kind: SPAN_KIND_CLIENT,
1380
+ attributes: {
1381
+ "http.request.method": context.method,
1382
+ "url.full": url,
1383
+ "server.address": hostOf(context.url),
1384
+ "api.client": context.client,
1385
+ "api.endpoint": context.endpoint,
1386
+ ...attributes?.(context)
1387
+ }
1388
+ }, async (span) => {
1389
+ inject?.(context.headers);
1390
+ try {
1391
+ const result = await next();
1392
+ span.setAttributes({
1393
+ "http.response.status_code": result.httpStatus,
1394
+ "http.request.resend_count": result.retryCount || undefined,
1395
+ "http.response.body.size": Math.round(result.responseSizeMb * 1024 * 1024)
1396
+ });
1397
+ return result;
1398
+ } catch (error) {
1399
+ recordFailure(span, error);
1400
+ throw error;
1401
+ } finally {
1402
+ span.end();
1403
+ }
1404
+ });
1405
+ };
1124
1406
  }
1125
-
1126
- // src/secrets/deadline.ts
1127
- async function withSecretDeadline(options, operation) {
1128
- const timeoutMs = options.timeoutMs ?? 30000;
1129
- if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {
1130
- throw new SecretLoadError("CONFIGURATION", "Secret timeoutMs must be a positive finite timer duration.");
1131
- }
1132
- const controller = new AbortController;
1133
- const cancel = () => controller.abort(new SecretLoadError("ABORTED", "Secret loading was cancelled."));
1134
- if (options.signal?.aborted) {
1135
- cancel();
1407
+ function recordFailure(span, error) {
1408
+ if (error instanceof ApiError2) {
1409
+ const isHttp = error instanceof HttpResponseError2;
1410
+ span.setAttributes({
1411
+ "error.type": isHttp ? String(error.status) : error.name,
1412
+ "api.error.category": error.category,
1413
+ "http.response.status_code": isHttp ? error.status : undefined,
1414
+ "http.request.resend_count": error.context.attempt || undefined
1415
+ });
1136
1416
  } else {
1137
- options.signal?.addEventListener("abort", cancel, { once: true });
1138
- }
1139
- const timer = setTimeout(() => controller.abort(new SecretLoadError("TIMEOUT", `Secret loading timed out after ${timeoutMs}ms.`)), timeoutMs);
1140
- let rejectOnAbort = () => {};
1141
- try {
1142
- const aborted = new Promise((_, reject) => {
1143
- rejectOnAbort = () => reject(controller.signal.reason);
1144
- controller.signal.addEventListener("abort", rejectOnAbort, { once: true });
1417
+ span.setAttributes({
1418
+ "error.type": error instanceof Error ? error.name : "unknown"
1145
1419
  });
1146
- if (controller.signal.aborted) {
1147
- throw controller.signal.reason;
1148
- }
1149
- return await Promise.race([operation(controller.signal), aborted]);
1150
- } finally {
1151
- clearTimeout(timer);
1152
- options.signal?.removeEventListener("abort", cancel);
1153
- controller.signal.removeEventListener("abort", rejectOnAbort);
1154
1420
  }
1155
- }
1156
-
1157
- // src/secrets/environment.ts
1158
- function getProcessEnvironment() {
1159
- return typeof process === "undefined" ? undefined : process.env;
1160
- }
1161
- function resolveSecretEnvironment(option, env) {
1162
- const explicit = typeof option === "function" ? option() : option;
1163
- if (typeof explicit === "object" && explicit !== null) {
1164
- if (typeof explicit.slug !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(explicit.slug)) {
1165
- throw new SecretLoadError("CONFIGURATION", "Custom secret environment requires a valid slug.");
1166
- }
1167
- return explicit.slug;
1168
- }
1169
- const selected = explicit ?? env?.SECRETS_ENV;
1170
- if (selected !== undefined) {
1171
- if (selected === "production" || selected === "prod") {
1172
- return "prod";
1173
- }
1174
- if (selected === "development" || selected === "dev") {
1175
- return "dev";
1176
- }
1177
- if (selected === "staging") {
1178
- return "staging";
1179
- }
1180
- throw new SecretLoadError("CONFIGURATION", "Invalid secret environment. Use dev, staging, prod, or an explicit { slug } option.");
1181
- }
1182
- if (env?.NODE_ENV === "production" || env?.NODE_ENV === "prod") {
1183
- return "prod";
1184
- }
1185
- if (env?.NODE_ENV === "staging") {
1186
- return "staging";
1187
- }
1188
- return "dev";
1189
- }
1190
-
1191
- // src/secrets/infisical-cli.ts
1192
- async function readInfisicalCliToken(options) {
1193
- const { execFile } = await import("node:child_process").catch(() => {
1194
- throw new SecretLoadError("CLI", "Infisical CLI fallback requires a runtime with subprocess support. Provide Infisical client credentials or a custom secret loader.");
1421
+ span.recordException(error instanceof Error ? error : String(error));
1422
+ span.setStatus({
1423
+ code: SPAN_STATUS_ERROR,
1424
+ message: error instanceof Error ? error.message.split(`
1425
+ `, 1)[0] : String(error)
1195
1426
  });
1196
- options.signal.throwIfAborted();
1197
- const env = {
1198
- ...getProcessEnvironment(),
1199
- INFISICAL_DISABLE_UPDATE_CHECK: "true"
1200
- };
1201
- delete env.INFISICAL_TOKEN;
1202
- delete env.INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN;
1203
- delete env.TOKEN;
1204
- try {
1205
- const stdout = await new Promise((resolve, reject) => {
1206
- const child = execFile("infisical", [
1207
- "user",
1208
- "get",
1209
- "token",
1210
- "--plain",
1211
- `--domain=${options.siteUrl}`,
1212
- "--silent"
1213
- ], {
1214
- env,
1215
- encoding: "utf8",
1216
- shell: false,
1217
- timeout: options.timeoutMs ?? 30000,
1218
- signal: options.signal,
1219
- killSignal: "SIGKILL",
1220
- maxBuffer: 10485760,
1221
- windowsHide: true
1222
- }, (error, output) => {
1223
- if (error) {
1224
- reject(error);
1225
- } else {
1226
- resolve(output);
1227
- }
1228
- });
1229
- child.stdin?.end();
1230
- });
1231
- return stdout.trim();
1232
- } catch (error) {
1233
- if (options.signal.aborted) {
1234
- throw options.signal.reason;
1235
- }
1236
- const failure = error;
1237
- if (failure?.code === "ENOENT") {
1238
- throw new SecretLoadError("CLI", "Infisical CLI not found. Install infisical and ensure it is on PATH, or provide Infisical client credentials.");
1239
- }
1240
- if (failure?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
1241
- throw new SecretLoadError("CLI", "Infisical CLI output exceeded the 10 MiB limit.");
1242
- }
1243
- if (failure?.killed) {
1244
- throw new SecretLoadError("TIMEOUT", `Infisical CLI timed out after ${(options.timeoutMs ?? 30000) / 1000} seconds or was terminated.`);
1245
- }
1246
- throw new SecretLoadError("CLI", `Infisical CLI session token failed. Run infisical login --domain=${options.siteUrl} and verify access to the configured organization, project, and environment.`);
1247
- }
1248
- }
1249
-
1250
- // src/secrets/infisical-config.ts
1251
- function validateInfisicalScope(options) {
1252
- validateInfisicalOrganizationId(options.organizationId);
1253
- let url;
1254
- try {
1255
- url = new URL(options.siteUrl);
1256
- } catch {
1257
- throw new SecretLoadError("CONFIGURATION", "Invalid Infisical siteUrl.");
1258
- }
1259
- if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
1260
- throw new SecretLoadError("CONFIGURATION", "Infisical siteUrl must be an HTTP(S) URL without credentials, query, or fragment.");
1261
- }
1262
- if (!options.projectId.trim() || !options.environment.trim() || !(options.secretPath ?? "/").startsWith("/")) {
1263
- throw new SecretLoadError("CONFIGURATION", "Infisical requires a projectId, environment, and absolute secretPath.");
1264
- }
1265
1427
  }
1266
- function validateInfisicalOrganizationId(organizationId) {
1267
- if (typeof organizationId !== "string" || !organizationId.trim() || /\s/.test(organizationId)) {
1268
- throw new SecretLoadError("CONFIGURATION", "Infisical organizationId is required and must be a nonempty ID without whitespace.");
1269
- }
1270
- }
1271
-
1272
- // src/secrets/infisical-session.ts
1273
- import { z } from "zod";
1274
- var sessionClaimsSchema = z.object({
1275
- organizationId: z.string().optional(),
1276
- subOrganizationId: z.string().optional(),
1277
- exp: z.number().finite().optional()
1278
- });
1279
- function parseInfisicalSessionToken(token) {
1280
- let claims;
1428
+ function hostOf(url) {
1281
1429
  try {
1282
- if (!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token)) {
1283
- throw new Error("Invalid token format");
1284
- }
1285
- const payload = token.split(".")[1];
1286
- const json = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
1287
- claims = sessionClaimsSchema.parse(JSON.parse(json));
1430
+ return new URL(url).hostname;
1288
1431
  } catch {
1289
- throw new SecretLoadError("AUTHENTICATION", "Infisical returned an invalid user session token. Run infisical login for the configured domain.");
1290
- }
1291
- if (claims.exp !== undefined && claims.exp <= Date.now() / 1000) {
1292
- throw new SecretLoadError("AUTHENTICATION", "Infisical user session has expired. Run infisical login for the configured domain.");
1293
- }
1294
- return { organizationId: claims.subOrganizationId ?? claims.organizationId };
1295
- }
1296
-
1297
- // src/secrets/infisical.ts
1298
- var DEFAULT_INFISICAL_SITE_URL = "https://eu.infisical.com";
1299
- var defaultFetch = globalThis.fetch;
1300
- var infisicalAuthResponseSchema = z2.object({ accessToken: z2.string() });
1301
- var infisicalSecretSchema = z2.object({
1302
- secretKey: z2.string(),
1303
- secretValue: z2.string()
1304
- });
1305
- var infisicalSecretsResponseSchema = z2.object({
1306
- secrets: z2.array(infisicalSecretSchema)
1307
- });
1308
- async function fetchInfisicalSecrets(options) {
1309
- validateInfisicalScope(options);
1310
- return withSecretDeadline(options, async (signal) => {
1311
- let operation = "login";
1312
- try {
1313
- const infisical = createInfisicalApiClient(options.siteUrl);
1314
- const { data: auth } = await infisical.request("login", {
1315
- signal,
1316
- reqBody: {
1317
- clientId: options.clientId,
1318
- clientSecret: options.clientSecret
1319
- }
1320
- });
1321
- signal.throwIfAborted();
1322
- operation = "listSecrets";
1323
- return await listInfisicalSecrets(infisical, auth.accessToken, {
1324
- ...options,
1325
- signal
1326
- });
1327
- } catch (error) {
1328
- throwInfisicalHttpError(error, operation, signal);
1329
- }
1330
- });
1331
- }
1332
- async function loadInfisicalSecrets(options) {
1333
- validateInfisicalScope(options);
1334
- const env = getProcessEnvironment();
1335
- const clientId = env?.[options.clientIdEnvKey];
1336
- const clientSecret = env?.[options.clientSecretEnvKey];
1337
- const mode = options.auth ?? "auto";
1338
- if (!["auto", "http", "cli"].includes(mode)) {
1339
- throw new SecretLoadError("CONFIGURATION", "Invalid Infisical auth mode.");
1340
- }
1341
- const useHttp = mode === "http" || mode === "auto" && Boolean(clientId && clientSecret);
1342
- if (useHttp) {
1343
- if (!clientId || !clientSecret) {
1344
- throw new SecretLoadError("AUTHENTICATION", "Infisical HTTP authentication requires both client credentials.");
1345
- }
1346
- options.reportSource?.("Infisical HTTP");
1347
- return fetchInfisicalSecrets({ ...options, clientId, clientSecret });
1348
- }
1349
- options.reportSource?.(`Infisical CLI session (organization=${options.organizationId} project=${options.projectId} environment=${options.environment})`);
1350
- return withSecretDeadline(options, (signal) => fetchInfisicalSessionSecrets({ ...options, signal }));
1351
- }
1352
- async function fetchInfisicalSessionSecrets(options) {
1353
- const { signal } = options;
1354
- let token = await readInfisicalCliToken(options);
1355
- signal.throwIfAborted();
1356
- const session = parseInfisicalSessionToken(token);
1357
- const infisical = createInfisicalApiClient(options.siteUrl);
1358
- let operation = "selectOrganization";
1359
- try {
1360
- if (session.organizationId !== options.organizationId) {
1361
- const { data } = await infisical.request("selectOrganization", {
1362
- signal,
1363
- reqHeaders: {
1364
- Authorization: `Bearer ${token}`,
1365
- "User-Agent": "hanzio/secrets"
1366
- },
1367
- reqBody: { organizationId: options.organizationId }
1368
- });
1369
- signal.throwIfAborted();
1370
- if (data.isMfaEnabled) {
1371
- throw new SecretLoadError("AUTHENTICATION", "Infisical requires MFA for this organization. Complete infisical login for the target organization and configured domain before loading secrets.", { operation });
1372
- }
1373
- const scopedSession = parseInfisicalSessionToken(data.token);
1374
- if (scopedSession.organizationId !== options.organizationId) {
1375
- throw new SecretLoadError("AUTHENTICATION", "Infisical returned a session for a different organization.", { operation });
1376
- }
1377
- token = data.token;
1378
- }
1379
- signal.throwIfAborted();
1380
- operation = "listSecrets";
1381
- return await listInfisicalSecrets(infisical, token, options);
1382
- } catch (error) {
1383
- throwInfisicalHttpError(error, operation, signal);
1384
- }
1385
- }
1386
- async function listInfisicalSecrets(infisical, token, options) {
1387
- const { data } = await infisical.request("listSecrets", {
1388
- signal: options.signal,
1389
- reqHeaders: { Authorization: `Bearer ${token}` },
1390
- reqQuery: {
1391
- environment: options.environment,
1392
- projectId: options.projectId,
1393
- secretPath: options.secretPath ?? "/",
1394
- viewSecretValue: true,
1395
- expandSecretReferences: true,
1396
- includeImports: true
1397
- }
1398
- });
1399
- const wantedKeys = new Set(options.keys);
1400
- return Object.fromEntries(data.secrets.filter((secret) => wantedKeys.has(secret.secretKey)).map((secret) => [secret.secretKey, secret.secretValue]));
1401
- }
1402
- function throwInfisicalHttpError(error, operation, signal) {
1403
- if (signal.aborted) {
1404
- throw signal.reason;
1405
- }
1406
- if (error instanceof SecretLoadError) {
1407
- throw error;
1432
+ return;
1408
1433
  }
1409
- const status = error instanceof HttpResponseError ? error.status : undefined;
1410
- const guidance = operation === "selectOrganization" && (status === 401 || status === 403) ? " Run infisical login for the target organization and configured domain, then verify your access." : "";
1411
- throw new SecretLoadError("HTTP", `Infisical HTTP ${operation} failed${status ? ` (status ${status})` : ""}.${guidance}`, { operation, status });
1412
- }
1413
- function createInfisicalApiClient(siteUrl) {
1414
- return createApiClient({
1415
- name: "infisical",
1416
- baseApiUrls: {
1417
- infisical: siteUrl
1418
- },
1419
- defaultBaseApiUrl: "infisical",
1420
- fetch: getFetch(),
1421
- retries: 1,
1422
- endpoints: {
1423
- selectOrganization: {
1424
- method: "POST",
1425
- path: "/api/v3/auth/select-organization",
1426
- reqHeadersSchema: z2.object({
1427
- Authorization: z2.string(),
1428
- "User-Agent": z2.string()
1429
- }),
1430
- reqBodySchema: z2.object({ organizationId: z2.string() }),
1431
- resSchema: z2.object({
1432
- token: z2.string().min(1),
1433
- isMfaEnabled: z2.boolean().optional()
1434
- }),
1435
- reqBodyFormat: "json"
1436
- },
1437
- login: {
1438
- method: "POST",
1439
- path: "/api/v1/auth/universal-auth/login",
1440
- reqBodySchema: z2.object({
1441
- clientId: z2.string(),
1442
- clientSecret: z2.string()
1443
- }),
1444
- resSchema: infisicalAuthResponseSchema,
1445
- reqBodyFormat: "json"
1446
- },
1447
- listSecrets: {
1448
- method: "GET",
1449
- path: "/api/v4/secrets",
1450
- reqHeadersSchema: z2.object({
1451
- Authorization: z2.string()
1452
- }),
1453
- reqQuerySchema: z2.object({
1454
- projectId: z2.string(),
1455
- environment: z2.string(),
1456
- secretPath: z2.string(),
1457
- viewSecretValue: z2.boolean(),
1458
- expandSecretReferences: z2.boolean(),
1459
- includeImports: z2.boolean()
1460
- }),
1461
- resSchema: infisicalSecretsResponseSchema
1462
- }
1463
- }
1464
- });
1465
1434
  }
1466
- function getFetch() {
1467
- const fetchFn = globalThis.fetch ?? defaultFetch;
1468
- return (input, init) => {
1469
- init?.signal?.throwIfAborted();
1470
- return fetchFn(input, init);
1471
- };
1435
+ // src/api-wrapper/endpoint.ts
1436
+ function defineEndpoint2(endpoint) {
1437
+ return endpoint;
1472
1438
  }
1473
- export {
1474
- DEFAULT_INFISICAL_SITE_URL,
1475
- fetchInfisicalSecrets,
1476
- loadInfisicalSecrets
1477
- };
1439
+ export { ApiError2, HttpResponseError2, ResponseValidationError2, RequestValidationError2, RequestTimeoutError2, NetworkError2, RequestAbortedError2, ConfigError2, ApiResponseError2, ActionError2, isApiError2, isHttpResponseError2, isResponseValidationError2, isRequestValidationError2, isRequestTimeoutError2, isNetworkError2, isRequestAbortedError2, isConfigError2, isActionError2, isApiResponseError2, isNonRetryableApiError2, defineAction2, describeApiError2, apiErrorLogAttributes2, defaultShouldRetry2, createApiClient2, paginate2, otelMiddleware2, defineEndpoint2 };