pepay 0.7.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 (128) hide show
  1. package/README.md +50 -0
  2. package/dist/cjs/client.cjs +44 -0
  3. package/dist/cjs/client.js.map +1 -0
  4. package/dist/cjs/config.cjs +59 -0
  5. package/dist/cjs/config.js.map +1 -0
  6. package/dist/cjs/errors.cjs +69 -0
  7. package/dist/cjs/errors.js.map +1 -0
  8. package/dist/cjs/http.cjs +422 -0
  9. package/dist/cjs/http.js.map +1 -0
  10. package/dist/cjs/index.cjs +22 -0
  11. package/dist/cjs/index.js.map +1 -0
  12. package/dist/cjs/resources/access.cjs +20 -0
  13. package/dist/cjs/resources/access.js.map +1 -0
  14. package/dist/cjs/resources/apiKeys.cjs +20 -0
  15. package/dist/cjs/resources/apiKeys.js.map +1 -0
  16. package/dist/cjs/resources/base.cjs +25 -0
  17. package/dist/cjs/resources/base.js.map +1 -0
  18. package/dist/cjs/resources/commerce.cjs +128 -0
  19. package/dist/cjs/resources/commerce.js.map +1 -0
  20. package/dist/cjs/resources/events.cjs +168 -0
  21. package/dist/cjs/resources/events.js.map +1 -0
  22. package/dist/cjs/resources/invoices.cjs +255 -0
  23. package/dist/cjs/resources/invoices.js.map +1 -0
  24. package/dist/cjs/resources/paymentSessions.cjs +32 -0
  25. package/dist/cjs/resources/paymentSessions.js.map +1 -0
  26. package/dist/cjs/resources/settlement.cjs +17 -0
  27. package/dist/cjs/resources/settlement.js.map +1 -0
  28. package/dist/cjs/resources/tokens.cjs +20 -0
  29. package/dist/cjs/resources/tokens.js.map +1 -0
  30. package/dist/cjs/resources/wallets.cjs +39 -0
  31. package/dist/cjs/resources/wallets.js.map +1 -0
  32. package/dist/cjs/types.cjs +3 -0
  33. package/dist/cjs/types.js.map +1 -0
  34. package/dist/cjs/utils.cjs +84 -0
  35. package/dist/cjs/utils.js.map +1 -0
  36. package/dist/cjs/ws/eventEmitter.cjs +29 -0
  37. package/dist/cjs/ws/eventEmitter.js.map +1 -0
  38. package/dist/cjs/ws/pepayEventStream.cjs +237 -0
  39. package/dist/cjs/ws/pepayEventStream.js.map +1 -0
  40. package/dist/cjs/ws/pepayWebSocket.cjs +126 -0
  41. package/dist/cjs/ws/pepayWebSocket.js.map +1 -0
  42. package/dist/cjs/ws/wsResource.cjs +104 -0
  43. package/dist/cjs/ws/wsResource.js.map +1 -0
  44. package/dist/esm/client.d.ts +30 -0
  45. package/dist/esm/client.d.ts.map +1 -0
  46. package/dist/esm/client.js +40 -0
  47. package/dist/esm/client.js.map +1 -0
  48. package/dist/esm/config.d.ts +8 -0
  49. package/dist/esm/config.d.ts.map +1 -0
  50. package/dist/esm/config.js +55 -0
  51. package/dist/esm/config.js.map +1 -0
  52. package/dist/esm/errors.d.ts +73 -0
  53. package/dist/esm/errors.d.ts.map +1 -0
  54. package/dist/esm/errors.js +58 -0
  55. package/dist/esm/errors.js.map +1 -0
  56. package/dist/esm/http.d.ts +18 -0
  57. package/dist/esm/http.d.ts.map +1 -0
  58. package/dist/esm/http.js +418 -0
  59. package/dist/esm/http.js.map +1 -0
  60. package/dist/esm/index.d.ts +4 -0
  61. package/dist/esm/index.d.ts.map +1 -0
  62. package/dist/esm/index.js +4 -0
  63. package/dist/esm/index.js.map +1 -0
  64. package/dist/esm/resources/access.d.ts +12 -0
  65. package/dist/esm/resources/access.d.ts.map +1 -0
  66. package/dist/esm/resources/access.js +16 -0
  67. package/dist/esm/resources/access.js.map +1 -0
  68. package/dist/esm/resources/apiKeys.d.ts +11 -0
  69. package/dist/esm/resources/apiKeys.d.ts.map +1 -0
  70. package/dist/esm/resources/apiKeys.js +16 -0
  71. package/dist/esm/resources/apiKeys.js.map +1 -0
  72. package/dist/esm/resources/base.d.ts +12 -0
  73. package/dist/esm/resources/base.d.ts.map +1 -0
  74. package/dist/esm/resources/base.js +21 -0
  75. package/dist/esm/resources/base.js.map +1 -0
  76. package/dist/esm/resources/commerce.d.ts +63 -0
  77. package/dist/esm/resources/commerce.d.ts.map +1 -0
  78. package/dist/esm/resources/commerce.js +124 -0
  79. package/dist/esm/resources/commerce.js.map +1 -0
  80. package/dist/esm/resources/events.d.ts +9 -0
  81. package/dist/esm/resources/events.d.ts.map +1 -0
  82. package/dist/esm/resources/events.js +164 -0
  83. package/dist/esm/resources/events.js.map +1 -0
  84. package/dist/esm/resources/invoices.d.ts +21 -0
  85. package/dist/esm/resources/invoices.d.ts.map +1 -0
  86. package/dist/esm/resources/invoices.js +251 -0
  87. package/dist/esm/resources/invoices.js.map +1 -0
  88. package/dist/esm/resources/paymentSessions.d.ts +15 -0
  89. package/dist/esm/resources/paymentSessions.d.ts.map +1 -0
  90. package/dist/esm/resources/paymentSessions.js +28 -0
  91. package/dist/esm/resources/paymentSessions.js.map +1 -0
  92. package/dist/esm/resources/settlement.d.ts +9 -0
  93. package/dist/esm/resources/settlement.d.ts.map +1 -0
  94. package/dist/esm/resources/settlement.js +13 -0
  95. package/dist/esm/resources/settlement.js.map +1 -0
  96. package/dist/esm/resources/tokens.d.ts +17 -0
  97. package/dist/esm/resources/tokens.d.ts.map +1 -0
  98. package/dist/esm/resources/tokens.js +16 -0
  99. package/dist/esm/resources/tokens.js.map +1 -0
  100. package/dist/esm/resources/wallets.d.ts +22 -0
  101. package/dist/esm/resources/wallets.d.ts.map +1 -0
  102. package/dist/esm/resources/wallets.js +35 -0
  103. package/dist/esm/resources/wallets.js.map +1 -0
  104. package/dist/esm/types.d.ts +263 -0
  105. package/dist/esm/types.d.ts.map +1 -0
  106. package/dist/esm/types.js +2 -0
  107. package/dist/esm/types.js.map +1 -0
  108. package/dist/esm/utils.d.ts +11 -0
  109. package/dist/esm/utils.d.ts.map +1 -0
  110. package/dist/esm/utils.js +73 -0
  111. package/dist/esm/utils.js.map +1 -0
  112. package/dist/esm/ws/eventEmitter.d.ts +8 -0
  113. package/dist/esm/ws/eventEmitter.d.ts.map +1 -0
  114. package/dist/esm/ws/eventEmitter.js +25 -0
  115. package/dist/esm/ws/eventEmitter.js.map +1 -0
  116. package/dist/esm/ws/pepayEventStream.d.ts +45 -0
  117. package/dist/esm/ws/pepayEventStream.d.ts.map +1 -0
  118. package/dist/esm/ws/pepayEventStream.js +233 -0
  119. package/dist/esm/ws/pepayEventStream.js.map +1 -0
  120. package/dist/esm/ws/pepayWebSocket.d.ts +37 -0
  121. package/dist/esm/ws/pepayWebSocket.d.ts.map +1 -0
  122. package/dist/esm/ws/pepayWebSocket.js +122 -0
  123. package/dist/esm/ws/pepayWebSocket.js.map +1 -0
  124. package/dist/esm/ws/wsResource.d.ts +25 -0
  125. package/dist/esm/ws/wsResource.d.ts.map +1 -0
  126. package/dist/esm/ws/wsResource.js +100 -0
  127. package/dist/esm/ws/wsResource.js.map +1 -0
  128. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Pepay SDK
2
+
3
+ Pepay API wrapper for Node.js and browsers.
4
+
5
+ ## Requirements
6
+ - Node.js 18+ for server integrations
7
+ - Evergreen browsers for client integrations (session token flows)
8
+
9
+ ## Install
10
+ ```bash
11
+ npm install pepay
12
+ ```
13
+
14
+ ```bash
15
+ yarn add pepay
16
+ ```
17
+
18
+ ```bash
19
+ pnpm add pepay
20
+ ```
21
+
22
+ ## Usage
23
+ ```ts
24
+ import { Pepay } from 'pepay';
25
+
26
+ const pepay = new Pepay({
27
+ apiKey: process.env.PEPAY_API_KEY,
28
+ baseUrl: 'https://api-beta.pepay.io',
29
+ environment: 'devnet'
30
+ });
31
+
32
+ const invoice = await pepay.invoices.create({
33
+ amount_usd: 49.99,
34
+ description: 'Starter plan'
35
+ });
36
+
37
+ console.log(invoice);
38
+ ```
39
+
40
+ ## Authentication
41
+ - `apiKey` -> `x-api-key` (merchant scope)
42
+ - `commerceApiKey` -> `x-commerce-api-key` (commerce scope)
43
+ - `userAccessToken` -> `User-Authorization` (commerce user routes)
44
+ - `sessionToken` + `signature` -> `x-session-token` + `x-signature` (payor/session)
45
+
46
+ ## Browser safety
47
+ Server API keys are blocked by default in browsers. Use session tokens or ws tokens for client apps.
48
+
49
+ ## Support
50
+ Email `contact@pepay.io` for access or onboarding help.
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Pepay = void 0;
4
+ const http_js_1 = require("./http.js");
5
+ const config_js_1 = require("./config.js");
6
+ const invoices_js_1 = require("./resources/invoices.js");
7
+ const tokens_js_1 = require("./resources/tokens.js");
8
+ const commerce_js_1 = require("./resources/commerce.js");
9
+ const events_js_1 = require("./resources/events.js");
10
+ const wsResource_js_1 = require("./ws/wsResource.js");
11
+ const access_js_1 = require("./resources/access.js");
12
+ const wallets_js_1 = require("./resources/wallets.js");
13
+ const settlement_js_1 = require("./resources/settlement.js");
14
+ const paymentSessions_js_1 = require("./resources/paymentSessions.js");
15
+ const apiKeys_js_1 = require("./resources/apiKeys.js");
16
+ class Pepay {
17
+ constructor(config) {
18
+ this.configState = (0, config_js_1.resolveConfig)(config);
19
+ this.http = new http_js_1.PepayHttpClient(this.configState);
20
+ this.invoices = new invoices_js_1.InvoicesResource(this.http);
21
+ this.tokens = new tokens_js_1.TokensResource(this.http);
22
+ this.commerce = new commerce_js_1.CommerceResource(this.http);
23
+ this.events = new events_js_1.EventsResource(this.http);
24
+ this.ws = new wsResource_js_1.WsResource(this.http, this.configState);
25
+ this.access = new access_js_1.AccessResource(this.http);
26
+ this.wallets = new wallets_js_1.WalletsResource(this.http);
27
+ this.settlement = new settlement_js_1.SettlementResource(this.http);
28
+ this.paymentSessions = new paymentSessions_js_1.PaymentSessionsResource(this.http);
29
+ this.apiKeys = new apiKeys_js_1.ApiKeysResource(this.http);
30
+ }
31
+ config(update) {
32
+ this.configState = (0, config_js_1.resolveConfig)({ ...this.configState, ...update });
33
+ this.http.updateConfig(this.configState);
34
+ this.ws.updateConfig(this.configState);
35
+ }
36
+ withAuth(auth) {
37
+ return new Pepay({ ...this.configState, ...auth });
38
+ }
39
+ getConfig() {
40
+ return { ...this.configState };
41
+ }
42
+ }
43
+ exports.Pepay = Pepay;
44
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;AAAA,uCAA4C;AAC5C,2CAA4C;AAE5C,yDAA2D;AAC3D,qDAAuD;AACvD,yDAA2D;AAC3D,qDAAuD;AACvD,sDAAgD;AAChD,qDAAuD;AACvD,uDAAyD;AACzD,6DAA+D;AAC/D,uEAAyE;AACzE,uDAAyD;AAEzD,MAAa,KAAK;IAehB,YAAY,MAAyB;QACnC,IAAI,CAAC,WAAW,GAAG,IAAA,yBAAa,EAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,IAAI,yBAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,0BAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,0BAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,GAAG,IAAI,0BAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,0BAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,4BAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,IAAI,kCAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe,GAAG,IAAI,4CAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG,IAAI,4BAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,CAAC,MAAkC;QACvC,IAAI,CAAC,WAAW,GAAG,IAAA,yBAAa,EAAC,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,QAAQ,CAAC,IAAqB;QAC5B,OAAO,IAAI,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC;CACF;AA3CD,sBA2CC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_RETRYABLE_STATUS_CODES = exports.DEFAULT_WS_IDLE_TIMEOUT_MS = exports.DEFAULT_WS_HEARTBEAT_MS = exports.DEFAULT_MAX_RETRIES = exports.DEFAULT_TIMEOUT_MS = void 0;
4
+ exports.resolveConfig = resolveConfig;
5
+ const utils_js_1 = require("./utils.js");
6
+ exports.DEFAULT_TIMEOUT_MS = 30000;
7
+ exports.DEFAULT_MAX_RETRIES = 2;
8
+ exports.DEFAULT_WS_HEARTBEAT_MS = 30000;
9
+ exports.DEFAULT_WS_IDLE_TIMEOUT_MS = 120000;
10
+ exports.DEFAULT_RETRYABLE_STATUS_CODES = [500, 503];
11
+ function resolveConfig(input) {
12
+ const envBaseUrl = typeof process !== 'undefined' ? process.env.PEPAY_API_URL || process.env.API_BASE_URL : undefined;
13
+ const envEnvironment = typeof process !== 'undefined' ? process.env.PEPAY_ENVIRONMENT : undefined;
14
+ const envTimeout = typeof process !== 'undefined' ? process.env.PEPAY_TIMEOUT_MS : undefined;
15
+ const envRetries = typeof process !== 'undefined' ? process.env.PEPAY_MAX_RETRIES : undefined;
16
+ const envRetryMaxElapsed = typeof process !== 'undefined' ? process.env.PEPAY_RETRY_MAX_ELAPSED_MS : undefined;
17
+ const envTelemetry = typeof process !== 'undefined' ? process.env.PEPAY_TELEMETRY : undefined;
18
+ const envRetryable = typeof process !== 'undefined' ? process.env.PEPAY_RETRYABLE_STATUS_CODES : undefined;
19
+ const envWsBase = typeof process !== 'undefined' ? process.env.PEPAY_WS_BASE_URL : undefined;
20
+ const envWsHeartbeat = typeof process !== 'undefined' ? process.env.PEPAY_WS_HEARTBEAT_MS : undefined;
21
+ const envWsIdle = typeof process !== 'undefined' ? process.env.PEPAY_WS_IDLE_TIMEOUT_MS : undefined;
22
+ const baseUrl = input.baseUrl || envBaseUrl || utils_js_1.DEFAULT_BASE_URL;
23
+ const websocketBaseUrl = input.websocketBaseUrl || envWsBase || (0, utils_js_1.toWebSocketBaseUrl)(baseUrl);
24
+ const timeoutMs = input.timeoutMs ?? (envTimeout ? Number(envTimeout) : undefined) ?? exports.DEFAULT_TIMEOUT_MS;
25
+ const maxRetries = input.maxRetries ?? (envRetries ? Number(envRetries) : undefined) ?? exports.DEFAULT_MAX_RETRIES;
26
+ const retryMaxElapsedMs = input.retryMaxElapsedMs ?? (envRetryMaxElapsed ? Number(envRetryMaxElapsed) : undefined);
27
+ const telemetry = input.telemetry ?? (envTelemetry ? envTelemetry === 'true' : false);
28
+ const wsHeartbeatMs = input.wsHeartbeatMs ?? (envWsHeartbeat ? Number(envWsHeartbeat) : undefined) ?? exports.DEFAULT_WS_HEARTBEAT_MS;
29
+ const wsIdleTimeoutMs = input.wsIdleTimeoutMs ?? (envWsIdle ? Number(envWsIdle) : undefined) ?? exports.DEFAULT_WS_IDLE_TIMEOUT_MS;
30
+ const retryableStatusCodes = input.retryableStatusCodes
31
+ ?? (envRetryable
32
+ ? envRetryable
33
+ .split(',')
34
+ .map((value) => Number(value.trim()))
35
+ .filter((value) => Number.isFinite(value) && value > 0)
36
+ : undefined)
37
+ ?? exports.DEFAULT_RETRYABLE_STATUS_CODES;
38
+ const normalized = {
39
+ ...input,
40
+ baseUrl,
41
+ websocketBaseUrl,
42
+ environment: input.environment || envEnvironment || undefined,
43
+ timeoutMs,
44
+ maxRetries,
45
+ retryMaxElapsedMs,
46
+ telemetry,
47
+ wsHeartbeatMs,
48
+ wsIdleTimeoutMs,
49
+ wsPingMessage: input.wsPingMessage,
50
+ retryableStatusCodes
51
+ };
52
+ if ((0, utils_js_1.isBrowserRuntime)() && !normalized.allowServerKeysInBrowser) {
53
+ if (normalized.apiKey || normalized.commerceApiKey) {
54
+ throw new Error('Server API keys are not allowed in browser runtime. Use session tokens or ws_token for client-side integrations.');
55
+ }
56
+ }
57
+ return normalized;
58
+ }
59
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;;AASA,sCAoDC;AA5DD,yCAAoF;AAEvE,QAAA,kBAAkB,GAAG,KAAM,CAAC;AAC5B,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,uBAAuB,GAAG,KAAM,CAAC;AACjC,QAAA,0BAA0B,GAAG,MAAO,CAAC;AACrC,QAAA,8BAA8B,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEzD,SAAgB,aAAa,CAAC,KAAwB;IACpD,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IACtH,MAAM,cAAc,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;IAClG,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,MAAM,kBAAkB,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/G,MAAM,YAAY,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,MAAM,YAAY,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3G,MAAM,SAAS,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,cAAc,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC;IACtG,MAAM,SAAS,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,UAAU,IAAI,2BAAgB,CAAC;IAChE,MAAM,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,IAAI,SAAS,IAAI,IAAA,6BAAkB,EAAC,OAAO,CAAC,CAAC;IAE5F,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,0BAAkB,CAAC;IACzG,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,2BAAmB,CAAC;IAC5G,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnH,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtF,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,+BAAuB,CAAC;IAC9H,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,kCAA0B,CAAC;IAC3H,MAAM,oBAAoB,GAAG,KAAK,CAAC,oBAAoB;WAClD,CAAC,YAAY;YACd,CAAC,CAAC,YAAY;iBACX,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;iBACpC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;YACzD,CAAC,CAAC,SAAS,CAAC;WACX,sCAA8B,CAAC;IAEpC,MAAM,UAAU,GAAsB;QACpC,GAAG,KAAK;QACR,OAAO;QACP,gBAAgB;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAK,cAAmD,IAAI,SAAS;QACnG,SAAS;QACT,UAAU;QACV,iBAAiB;QACjB,SAAS;QACT,aAAa;QACb,eAAe;QACf,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,oBAAoB;KACrB,CAAC;IAEF,IAAI,IAAA,2BAAgB,GAAE,IAAI,CAAC,UAAU,CAAC,wBAAwB,EAAE,CAAC;QAC/D,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,kHAAkH,CAAC,CAAC;QACtI,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PepayPollingTimeoutError = exports.PepayHttpError = exports.PepayCircuitBreakerError = exports.PepayInvalidCursorError = exports.PepayValidationError = exports.PepayRateLimitError = exports.PepayAuthError = exports.PepayError = void 0;
4
+ class PepayError extends Error {
5
+ constructor(message, options) {
6
+ super(message);
7
+ this.name = 'PepayError';
8
+ this.code = options?.code;
9
+ this.status = options?.status;
10
+ this.details = options?.details;
11
+ this.requestId = options?.requestId;
12
+ this.idempotencyKey = options?.idempotencyKey;
13
+ }
14
+ }
15
+ exports.PepayError = PepayError;
16
+ class PepayAuthError extends PepayError {
17
+ constructor(message, options) {
18
+ super(message, options);
19
+ this.name = 'PepayAuthError';
20
+ }
21
+ }
22
+ exports.PepayAuthError = PepayAuthError;
23
+ class PepayRateLimitError extends PepayError {
24
+ constructor(message, options) {
25
+ super(message, options);
26
+ this.name = 'PepayRateLimitError';
27
+ this.retryAfter = options?.retryAfter;
28
+ }
29
+ }
30
+ exports.PepayRateLimitError = PepayRateLimitError;
31
+ class PepayValidationError extends PepayError {
32
+ constructor(message, options) {
33
+ super(message, options);
34
+ this.name = 'PepayValidationError';
35
+ }
36
+ }
37
+ exports.PepayValidationError = PepayValidationError;
38
+ class PepayInvalidCursorError extends PepayValidationError {
39
+ constructor(message, options) {
40
+ super(message, options);
41
+ this.name = 'PepayInvalidCursorError';
42
+ }
43
+ }
44
+ exports.PepayInvalidCursorError = PepayInvalidCursorError;
45
+ class PepayCircuitBreakerError extends PepayError {
46
+ constructor(message, options) {
47
+ super(message, options);
48
+ this.name = 'PepayCircuitBreakerError';
49
+ this.state = options?.state;
50
+ this.openUntil = options?.openUntil;
51
+ this.failureCount = options?.failureCount;
52
+ }
53
+ }
54
+ exports.PepayCircuitBreakerError = PepayCircuitBreakerError;
55
+ class PepayHttpError extends PepayError {
56
+ constructor(message, options) {
57
+ super(message, options);
58
+ this.name = 'PepayHttpError';
59
+ }
60
+ }
61
+ exports.PepayHttpError = PepayHttpError;
62
+ class PepayPollingTimeoutError extends PepayError {
63
+ constructor(message, options) {
64
+ super(message, options);
65
+ this.name = 'PepayPollingTimeoutError';
66
+ }
67
+ }
68
+ exports.PepayPollingTimeoutError = PepayPollingTimeoutError;
69
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,UAAW,SAAQ,KAAK;IAOnC,YAAY,OAAe,EAAE,OAM5B;QACC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,CAAC;QACpC,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,cAAc,CAAC;IAChD,CAAC;CACF;AAtBD,gCAsBC;AAED,MAAa,cAAe,SAAQ,UAAU;IAC5C,YAAY,OAAe,EAAE,OAA+D;QAC1F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED,MAAa,mBAAoB,SAAQ,UAAU;IAGjD,YAAY,OAAe,EAAE,OAAoF;QAC/G,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;IACxC,CAAC;CACF;AARD,kDAQC;AAED,MAAa,oBAAqB,SAAQ,UAAU;IAClD,YAAY,OAAe,EAAE,OAA+D;QAC1F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AALD,oDAKC;AAED,MAAa,uBAAwB,SAAQ,oBAAoB;IAC/D,YAAY,OAAe,EAAE,OAA+D;QAC1F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AALD,0DAKC;AAED,MAAa,wBAAyB,SAAQ,UAAU;IAKtD,YAAY,OAAe,EAAE,OAA0H;QACrJ,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,CAAC;QACpC,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;IAC5C,CAAC;CACF;AAZD,4DAYC;AAED,MAAa,cAAe,SAAQ,UAAU;IAC5C,YAAY,OAAe,EAAE,OAA4G;QACvI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED,MAAa,wBAAyB,SAAQ,UAAU;IACtD,YAAY,OAAe,EAAE,OAA8C;QACzE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AALD,4DAKC"}
@@ -0,0 +1,422 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PepayHttpClient = void 0;
4
+ const errors_js_1 = require("./errors.js");
5
+ const utils_js_1 = require("./utils.js");
6
+ class PepayHttpClient {
7
+ constructor(config) {
8
+ this.config = config;
9
+ this.circuitState = {
10
+ state: 'closed',
11
+ failureCount: 0,
12
+ successCount: 0,
13
+ halfOpenInFlight: 0
14
+ };
15
+ }
16
+ updateConfig(config) {
17
+ this.config = config;
18
+ }
19
+ async request(method, path, options = {}) {
20
+ const url = (0, utils_js_1.joinUrl)(this.config.baseUrl || '', path) + (0, utils_js_1.buildQuery)(options.query);
21
+ const headers = this.buildHeaders(method, options);
22
+ const startedAt = Date.now();
23
+ const body = options && 'body' in options ? options.body : undefined;
24
+ const payload = body !== undefined ? JSON.stringify(body) : undefined;
25
+ const retries = options.retries ?? this.config.maxRetries ?? 0;
26
+ const timeoutMs = options.timeoutMs ?? this.config.timeoutMs ?? 30000;
27
+ const retryMaxElapsedMs = options.retryMaxElapsedMs ?? this.config.retryMaxElapsedMs;
28
+ let attempt = 0;
29
+ while (true) {
30
+ this.assertCircuitState();
31
+ const controller = typeof AbortController !== 'undefined' ? new AbortController() : undefined;
32
+ if (controller && options.signal) {
33
+ if (options.signal.aborted) {
34
+ controller.abort();
35
+ }
36
+ else {
37
+ options.signal.addEventListener('abort', () => controller.abort(), { once: true });
38
+ }
39
+ }
40
+ const timeout = controller ? setTimeout(() => controller.abort(), timeoutMs) : undefined;
41
+ const isHalfOpenAttempt = this.circuitState.state === 'half_open';
42
+ if (isHalfOpenAttempt) {
43
+ const halfOpenMax = this.getCircuitConfig()?.halfOpenMaxRequests ?? 1;
44
+ if (this.circuitState.halfOpenInFlight >= halfOpenMax) {
45
+ throw new errors_js_1.PepayCircuitBreakerError('Circuit breaker is half-open; waiting for trial request to complete.', {
46
+ code: 'CIRCUIT_BREAKER_OPEN',
47
+ status: 503,
48
+ state: this.circuitState.state,
49
+ openUntil: this.circuitState.openUntil,
50
+ failureCount: this.circuitState.failureCount
51
+ });
52
+ }
53
+ this.circuitState.halfOpenInFlight += 1;
54
+ }
55
+ try {
56
+ this.config.onRequest?.({
57
+ method,
58
+ url,
59
+ headers: redactHeaders(headers),
60
+ attempt,
61
+ idempotencyKey: headers['Idempotency-Key']
62
+ });
63
+ const requestInit = {
64
+ method,
65
+ headers,
66
+ body: payload,
67
+ signal: controller?.signal
68
+ };
69
+ if (this.config.dispatcher) {
70
+ requestInit.dispatcher = this.config.dispatcher;
71
+ }
72
+ if (this.config.httpAgent) {
73
+ requestInit.agent = this.config.httpAgent;
74
+ }
75
+ const response = await (this.config.fetch || fetch)(url, requestInit);
76
+ if (timeout)
77
+ clearTimeout(timeout);
78
+ this.config.onResponse?.({
79
+ method,
80
+ url,
81
+ status: response.status,
82
+ headers: redactHeaders(headers),
83
+ attempt,
84
+ durationMs: Date.now() - startedAt
85
+ });
86
+ if (response.ok) {
87
+ this.onCircuitSuccess();
88
+ if (response.status === 204)
89
+ return undefined;
90
+ const contentType = response.headers.get('content-type') || '';
91
+ if (contentType.includes('application/json')) {
92
+ return (await response.json());
93
+ }
94
+ const text = await response.text();
95
+ return text;
96
+ }
97
+ const retryAfterHeader = response.headers.get('retry-after');
98
+ const retryAfter = retryAfterHeader ? Number(retryAfterHeader) : undefined;
99
+ const requestId = response.headers.get('x-request-id') || response.headers.get('request-id') || undefined;
100
+ const errorPayload = await this.parseError(response);
101
+ const code = typeof errorPayload?.code === 'string' ? errorPayload.code : undefined;
102
+ const message = (typeof errorPayload?.message === 'string' && errorPayload.message) ||
103
+ (typeof errorPayload?.error === 'string' && errorPayload.error) ||
104
+ response.statusText ||
105
+ 'Request failed';
106
+ if (response.status === 401 || response.status === 403) {
107
+ throw new errors_js_1.PepayAuthError(message, { code, status: response.status, details: errorPayload });
108
+ }
109
+ if (response.status === 400) {
110
+ if (code === 'INVALID_CURSOR') {
111
+ throw new errors_js_1.PepayInvalidCursorError(message, { code, status: response.status, details: errorPayload });
112
+ }
113
+ throw new errors_js_1.PepayValidationError(message, { code, status: response.status, details: errorPayload });
114
+ }
115
+ if (response.status === 429) {
116
+ throw new errors_js_1.PepayRateLimitError(message, { code, status: response.status, details: errorPayload, retryAfter });
117
+ }
118
+ throw new errors_js_1.PepayHttpError(message, {
119
+ code,
120
+ status: response.status,
121
+ details: errorPayload,
122
+ requestId,
123
+ idempotencyKey: headers['Idempotency-Key']
124
+ });
125
+ }
126
+ catch (error) {
127
+ this.onCircuitFailure(error);
128
+ if (timeout)
129
+ clearTimeout(timeout);
130
+ const isAbort = error instanceof Error && error.name === 'AbortError';
131
+ const isPepayError = error instanceof errors_js_1.PepayHttpError || error instanceof errors_js_1.PepayAuthError || error instanceof errors_js_1.PepayValidationError || error instanceof errors_js_1.PepayRateLimitError;
132
+ const elapsedMs = Date.now() - startedAt;
133
+ if (retryMaxElapsedMs !== undefined && elapsedMs >= retryMaxElapsedMs) {
134
+ this.config.onError?.({
135
+ method,
136
+ url,
137
+ headers: redactHeaders(headers),
138
+ attempt,
139
+ error,
140
+ elapsedMs,
141
+ willRetry: false
142
+ });
143
+ throw error;
144
+ }
145
+ if (isPepayError && error instanceof errors_js_1.PepayRateLimitError && attempt < retries) {
146
+ this.config.onError?.({
147
+ method,
148
+ url,
149
+ headers: redactHeaders(headers),
150
+ attempt,
151
+ error,
152
+ elapsedMs,
153
+ willRetry: true
154
+ });
155
+ const delay = (0, utils_js_1.getRetryDelay)(attempt, this.config.retry, error.retryAfter);
156
+ await (0, utils_js_1.sleep)(delay);
157
+ attempt += 1;
158
+ continue;
159
+ }
160
+ if (isPepayError && error instanceof errors_js_1.PepayHttpError && error.status && this.isRetryableStatus(error.status) && attempt < retries) {
161
+ this.config.onError?.({
162
+ method,
163
+ url,
164
+ headers: redactHeaders(headers),
165
+ attempt,
166
+ error,
167
+ elapsedMs,
168
+ willRetry: true
169
+ });
170
+ const delay = (0, utils_js_1.getRetryDelay)(attempt, this.config.retry, undefined);
171
+ await (0, utils_js_1.sleep)(delay);
172
+ attempt += 1;
173
+ continue;
174
+ }
175
+ if (!isPepayError && (isAbort || attempt < retries)) {
176
+ this.config.onError?.({
177
+ method,
178
+ url,
179
+ headers: redactHeaders(headers),
180
+ attempt,
181
+ error,
182
+ elapsedMs,
183
+ willRetry: true
184
+ });
185
+ const delay = (0, utils_js_1.getRetryDelay)(attempt, this.config.retry, undefined);
186
+ await (0, utils_js_1.sleep)(delay);
187
+ attempt += 1;
188
+ continue;
189
+ }
190
+ this.config.onError?.({
191
+ method,
192
+ url,
193
+ headers: redactHeaders(headers),
194
+ attempt,
195
+ error,
196
+ elapsedMs,
197
+ willRetry: false
198
+ });
199
+ throw error;
200
+ }
201
+ finally {
202
+ if (isHalfOpenAttempt) {
203
+ this.circuitState.halfOpenInFlight = Math.max(0, this.circuitState.halfOpenInFlight - 1);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ buildHeaders(method, options) {
209
+ const headers = {
210
+ 'Content-Type': 'application/json',
211
+ ...this.config.defaultHeaders,
212
+ ...options.headers
213
+ };
214
+ const auth = { ...this.config, ...options.auth };
215
+ const authScope = options.authScope;
216
+ const hasMerchantKey = Boolean(auth.apiKey);
217
+ const hasCommerceKey = Boolean(auth.commerceApiKey);
218
+ const hasAlternateAuth = Boolean(auth.bearerToken || auth.userAccessToken || auth.sessionToken || auth.signature);
219
+ this.applyScopedApiKey(headers, auth, authScope, {
220
+ hasMerchantKey,
221
+ hasCommerceKey,
222
+ hasAlternateAuth
223
+ });
224
+ if (auth.bearerToken)
225
+ headers['Authorization'] = `Bearer ${auth.bearerToken}`;
226
+ if (auth.userAccessToken) {
227
+ headers['User-Authorization'] = auth.userAccessToken.startsWith('Bearer ')
228
+ ? auth.userAccessToken
229
+ : `Bearer ${auth.userAccessToken}`;
230
+ }
231
+ if (auth.sessionToken)
232
+ headers['x-session-token'] = auth.sessionToken;
233
+ if (auth.signature)
234
+ headers['x-signature'] = auth.signature;
235
+ if (this.config.apiVersion)
236
+ headers['X-Pepay-API-Version'] = this.config.apiVersion;
237
+ if (this.config.telemetry)
238
+ headers['X-Pepay-Telemetry'] = '1';
239
+ const appInfo = this.config.appInfo;
240
+ if (appInfo) {
241
+ headers['X-Pepay-Client-Info'] = (0, utils_js_1.stripUndefined)({
242
+ name: appInfo.name,
243
+ version: appInfo.version,
244
+ url: appInfo.url
245
+ }).name ? JSON.stringify((0, utils_js_1.stripUndefined)({ name: appInfo.name, version: appInfo.version, url: appInfo.url })) : '';
246
+ }
247
+ if (this.config.userAgent) {
248
+ headers['X-Pepay-User-Agent'] = this.config.userAgent;
249
+ }
250
+ if (['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
251
+ if (!headers['Idempotency-Key']) {
252
+ headers['Idempotency-Key'] = options.idempotencyKey || (0, utils_js_1.generateIdempotencyKey)();
253
+ }
254
+ }
255
+ return headers;
256
+ }
257
+ async parseError(response) {
258
+ const contentType = response.headers.get('content-type') || '';
259
+ if (contentType.includes('application/json')) {
260
+ try {
261
+ return (await response.json());
262
+ }
263
+ catch {
264
+ return null;
265
+ }
266
+ }
267
+ return null;
268
+ }
269
+ isRetryableStatus(status) {
270
+ const retryable = this.config.retryableStatusCodes || [];
271
+ return retryable.includes(status);
272
+ }
273
+ applyScopedApiKey(headers, auth, authScope, flags) {
274
+ if (authScope === 'merchant') {
275
+ if (flags.hasMerchantKey) {
276
+ headers['x-api-key'] = auth.apiKey;
277
+ return;
278
+ }
279
+ if (flags.hasCommerceKey && !flags.hasAlternateAuth) {
280
+ throw new errors_js_1.PepayValidationError('Merchant API key required for this endpoint.', {
281
+ code: 'AUTH_REQUIRED',
282
+ status: 400,
283
+ details: { requiredScope: 'merchant' }
284
+ });
285
+ }
286
+ return;
287
+ }
288
+ if (authScope === 'commerce') {
289
+ if (flags.hasCommerceKey) {
290
+ headers['x-commerce-api-key'] = auth.commerceApiKey;
291
+ return;
292
+ }
293
+ if (flags.hasMerchantKey && !flags.hasAlternateAuth) {
294
+ throw new errors_js_1.PepayValidationError('Commerce API key required for this endpoint.', {
295
+ code: 'AUTH_REQUIRED',
296
+ status: 400,
297
+ details: { requiredScope: 'commerce' }
298
+ });
299
+ }
300
+ return;
301
+ }
302
+ if (flags.hasMerchantKey) {
303
+ headers['x-api-key'] = auth.apiKey;
304
+ return;
305
+ }
306
+ if (flags.hasCommerceKey) {
307
+ headers['x-commerce-api-key'] = auth.commerceApiKey;
308
+ }
309
+ }
310
+ getCircuitConfig() {
311
+ return this.config.circuitBreaker;
312
+ }
313
+ assertCircuitState() {
314
+ const cfg = this.getCircuitConfig();
315
+ if (!isCircuitBreakerEnabled(cfg))
316
+ return;
317
+ const now = Date.now();
318
+ const state = this.circuitState;
319
+ if (state.state === 'open') {
320
+ if (state.openUntil && now >= state.openUntil) {
321
+ state.state = 'half_open';
322
+ state.failureCount = 0;
323
+ state.successCount = 0;
324
+ state.openUntil = undefined;
325
+ state.halfOpenInFlight = 0;
326
+ cfg?.onStateChange?.({ state: state.state, failureCount: state.failureCount, successCount: state.successCount });
327
+ return;
328
+ }
329
+ throw new errors_js_1.PepayCircuitBreakerError('Circuit breaker is open; requests are paused. Try again later or adjust circuitBreaker config.', {
330
+ code: 'CIRCUIT_BREAKER_OPEN',
331
+ status: 503,
332
+ state: state.state,
333
+ openUntil: state.openUntil,
334
+ failureCount: state.failureCount
335
+ });
336
+ }
337
+ }
338
+ onCircuitSuccess() {
339
+ const cfg = this.getCircuitConfig();
340
+ if (!isCircuitBreakerEnabled(cfg))
341
+ return;
342
+ const state = this.circuitState;
343
+ if (state.state === 'half_open') {
344
+ state.successCount += 1;
345
+ const threshold = cfg?.successThreshold ?? 1;
346
+ if (state.successCount >= threshold) {
347
+ state.state = 'closed';
348
+ state.failureCount = 0;
349
+ state.successCount = 0;
350
+ state.openUntil = undefined;
351
+ state.halfOpenInFlight = 0;
352
+ cfg?.onStateChange?.({ state: state.state, failureCount: state.failureCount, successCount: state.successCount });
353
+ }
354
+ return;
355
+ }
356
+ state.failureCount = 0;
357
+ }
358
+ onCircuitFailure(error) {
359
+ const cfg = this.getCircuitConfig();
360
+ if (!isCircuitBreakerEnabled(cfg))
361
+ return;
362
+ const shouldTrip = cfg?.shouldTrip || defaultShouldTrip;
363
+ if (!shouldTrip(error))
364
+ return;
365
+ const state = this.circuitState;
366
+ state.failureCount += 1;
367
+ if (state.state === 'half_open') {
368
+ this.openCircuit(cfg);
369
+ return;
370
+ }
371
+ const threshold = cfg?.failureThreshold ?? 5;
372
+ if (state.failureCount >= threshold) {
373
+ this.openCircuit(cfg);
374
+ }
375
+ }
376
+ openCircuit(cfg) {
377
+ const state = this.circuitState;
378
+ state.state = 'open';
379
+ state.successCount = 0;
380
+ state.halfOpenInFlight = 0;
381
+ const resetTimeout = cfg?.resetTimeoutMs ?? 30000;
382
+ state.openUntil = Date.now() + resetTimeout;
383
+ cfg?.onStateChange?.({ state: state.state, failureCount: state.failureCount, successCount: state.successCount, openUntil: state.openUntil });
384
+ }
385
+ }
386
+ exports.PepayHttpClient = PepayHttpClient;
387
+ function redactHeaders(headers) {
388
+ const redacted = {};
389
+ const sensitive = new Set([
390
+ 'authorization',
391
+ 'user-authorization',
392
+ 'x-api-key',
393
+ 'x-commerce-api-key',
394
+ 'x-session-token',
395
+ 'x-signature'
396
+ ]);
397
+ for (const [key, value] of Object.entries(headers)) {
398
+ if (sensitive.has(key.toLowerCase())) {
399
+ redacted[key] = '[REDACTED]';
400
+ }
401
+ else {
402
+ redacted[key] = value;
403
+ }
404
+ }
405
+ return redacted;
406
+ }
407
+ function isCircuitBreakerEnabled(config) {
408
+ return Boolean(config?.enabled);
409
+ }
410
+ function defaultShouldTrip(error) {
411
+ if (error instanceof Error && error.name === 'AbortError')
412
+ return false;
413
+ if (error instanceof errors_js_1.PepayRateLimitError)
414
+ return false;
415
+ if (error instanceof errors_js_1.PepayAuthError || error instanceof errors_js_1.PepayValidationError || error instanceof errors_js_1.PepayInvalidCursorError)
416
+ return false;
417
+ if (error instanceof errors_js_1.PepayHttpError) {
418
+ return Boolean(error.status && error.status >= 500);
419
+ }
420
+ return true;
421
+ }
422
+ //# sourceMappingURL=http.js.map