@delopay/sdk 0.277.0 → 0.279.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.
@@ -30,6 +30,100 @@ var DelopayAuthenticationError = class extends DelopayError {
30
30
  }
31
31
  };
32
32
 
33
+ // src/eventStream.ts
34
+ var LF = 10;
35
+ var CR = 13;
36
+ var EventStreamParser = class {
37
+ /**
38
+ * @param lastEventId - The id the stream resumes after, as `EventSource`
39
+ * carries it into a reconnection: a dispatch before the server names an
40
+ * id keeps this one.
41
+ */
42
+ constructor(lastEventId = "") {
43
+ this.line = "";
44
+ /** The previous chunk ended in CR: a LF opening the next one belongs to it. */
45
+ this.skipLf = false;
46
+ this.data = "";
47
+ this.hasData = false;
48
+ this.eventType = "";
49
+ this.retry = null;
50
+ this.idBuffer = lastEventId;
51
+ }
52
+ /** Feed the next piece of decoded text; returns the dispatches it completed. */
53
+ push(text) {
54
+ const out = [];
55
+ if (text.length === 0) return out;
56
+ let start = 0;
57
+ if (this.skipLf) {
58
+ this.skipLf = false;
59
+ if (text.charCodeAt(0) === LF) start = 1;
60
+ }
61
+ for (let i = start; i < text.length; i++) {
62
+ const c = text.charCodeAt(i);
63
+ if (c !== LF && c !== CR) continue;
64
+ const line = this.line + text.slice(start, i);
65
+ this.line = "";
66
+ this.processLine(line, out);
67
+ if (c === CR) {
68
+ if (i + 1 < text.length) {
69
+ if (text.charCodeAt(i + 1) === LF) i++;
70
+ } else {
71
+ this.skipLf = true;
72
+ }
73
+ }
74
+ start = i + 1;
75
+ }
76
+ this.line += text.slice(start);
77
+ return out;
78
+ }
79
+ processLine(line, out) {
80
+ if (line === "") {
81
+ this.dispatch(out);
82
+ return;
83
+ }
84
+ if (line.charCodeAt(0) === 58) return;
85
+ const colon = line.indexOf(":");
86
+ let field;
87
+ let value;
88
+ if (colon === -1) {
89
+ field = line;
90
+ value = "";
91
+ } else {
92
+ field = line.slice(0, colon);
93
+ value = line.slice(colon + 1);
94
+ if (value.charCodeAt(0) === 32) value = value.slice(1);
95
+ }
96
+ switch (field) {
97
+ case "event":
98
+ this.eventType = value;
99
+ break;
100
+ case "data":
101
+ this.data = this.hasData ? `${this.data}
102
+ ${value}` : value;
103
+ this.hasData = true;
104
+ break;
105
+ case "id":
106
+ if (!value.includes("\0")) this.idBuffer = value;
107
+ break;
108
+ case "retry":
109
+ if (/^[0-9]+$/.test(value)) {
110
+ const ms = Number(value);
111
+ if (Number.isSafeInteger(ms)) this.retry = ms;
112
+ }
113
+ break;
114
+ default:
115
+ break;
116
+ }
117
+ }
118
+ dispatch(out) {
119
+ const event = this.hasData ? { type: this.eventType || "message", data: this.data } : null;
120
+ out.push({ lastEventId: this.idBuffer, retry: this.retry, event });
121
+ this.data = "";
122
+ this.hasData = false;
123
+ this.eventType = "";
124
+ }
125
+ };
126
+
33
127
  // src/resources/apiKeys.ts
34
128
  var ApiKeys = class {
35
129
  constructor(request) {
@@ -1275,8 +1369,8 @@ var Customers = class {
1275
1369
  };
1276
1370
 
1277
1371
  // src/recordCounter.ts
1278
- var LF = 10;
1279
- var CR = 13;
1372
+ var LF2 = 10;
1373
+ var CR2 = 13;
1280
1374
  var QUOTE = 34;
1281
1375
  var BACKSLASH = 92;
1282
1376
  var OPEN_BRACE = 123;
@@ -1300,10 +1394,10 @@ var CsvRecordCounter = class {
1300
1394
  lineHasContent = true;
1301
1395
  } else if (inQuotes) {
1302
1396
  lineHasContent = true;
1303
- } else if (byte === LF) {
1397
+ } else if (byte === LF2) {
1304
1398
  newlines++;
1305
1399
  lineHasContent = false;
1306
- } else if (byte !== CR) {
1400
+ } else if (byte !== CR2) {
1307
1401
  lineHasContent = true;
1308
1402
  }
1309
1403
  }
@@ -8837,6 +8931,133 @@ var Risk = class {
8837
8931
  }
8838
8932
  };
8839
8933
 
8934
+ // src/resources/live.ts
8935
+ function readField(data, key) {
8936
+ let value;
8937
+ try {
8938
+ value = JSON.parse(data);
8939
+ } catch {
8940
+ return void 0;
8941
+ }
8942
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
8943
+ return Object.getOwnPropertyDescriptor(value, key)?.value;
8944
+ }
8945
+ function toLiveStreamEvent(event, id, retry) {
8946
+ switch (event.type) {
8947
+ case "ready": {
8948
+ const resumed = readField(event.data, "resumed");
8949
+ return { type: "ready", id, retry, resumed: typeof resumed === "boolean" ? resumed : null };
8950
+ }
8951
+ case "change": {
8952
+ const changes = readField(event.data, "changes");
8953
+ if (!Array.isArray(changes)) return { type: "resync", id };
8954
+ return { type: "change", id, changes };
8955
+ }
8956
+ case "resync":
8957
+ return { type: "resync", id };
8958
+ default:
8959
+ return null;
8960
+ }
8961
+ }
8962
+ var LiveEventStream = class {
8963
+ constructor(connection, lastEventId = null) {
8964
+ this.connection = connection;
8965
+ this._retry = null;
8966
+ this._lastEventId = lastEventId || null;
8967
+ }
8968
+ /**
8969
+ * The position to resume after: the id of the last event read, advanced by
8970
+ * keepalives too. `null` before the server named one. Send it as
8971
+ * `lastEventId` when reconnecting.
8972
+ */
8973
+ get lastEventId() {
8974
+ return this._lastEventId;
8975
+ }
8976
+ /** The wait before reconnecting the server asked for, in ms; `null` until it says. */
8977
+ get retry() {
8978
+ return this._retry;
8979
+ }
8980
+ /** Close the stream; the iteration ends without an error. */
8981
+ close() {
8982
+ this.connection.close();
8983
+ }
8984
+ [Symbol.asyncIterator]() {
8985
+ this.iterator ?? (this.iterator = this.events());
8986
+ return this.iterator;
8987
+ }
8988
+ async *events() {
8989
+ for await (const dispatch of this.connection.dispatches) {
8990
+ const event = this.read(dispatch);
8991
+ if (event) yield event;
8992
+ }
8993
+ }
8994
+ read(dispatch) {
8995
+ this._lastEventId = dispatch.lastEventId || null;
8996
+ if (dispatch.retry !== null) this._retry = dispatch.retry;
8997
+ if (!dispatch.event) return null;
8998
+ return toLiveStreamEvent(dispatch.event, this._lastEventId, this._retry);
8999
+ }
9000
+ };
9001
+ async function openLiveStream(openStream, path, options = {}) {
9002
+ const connection = await openStream(path, {
9003
+ ...options.lastEventId ? { lastEventId: options.lastEventId } : {},
9004
+ ...options.signal ? { signal: options.signal } : {},
9005
+ ...options.idleTimeoutMs !== void 0 ? { idleTimeoutMs: options.idleTimeoutMs } : {},
9006
+ ...options.headers ? { headers: options.headers } : {}
9007
+ });
9008
+ return new LiveEventStream(connection, options.lastEventId ?? null);
9009
+ }
9010
+ var Live = class {
9011
+ constructor(request, openStream) {
9012
+ this.request = request;
9013
+ this.openStream = openStream;
9014
+ }
9015
+ /**
9016
+ * Open the stream of what changed in the caller's merchant, as their role
9017
+ * may read it. Resolves once the server answered; a `401` rejects with
9018
+ * `DelopayAuthenticationError`.
9019
+ *
9020
+ * The first event is `ready`. `change` names the kinds of record and, when
9021
+ * few, the ids that changed: read them again through the usual endpoints.
9022
+ * `resync`, and `ready` with `resumed: false`, mean read everything again.
9023
+ * The SDK does not reconnect — see {@link LiveEventStream}.
9024
+ *
9025
+ * `GET /live/stream`
9026
+ *
9027
+ * @example
9028
+ * ```typescript
9029
+ * const stream = await delopay.live.stream({ lastEventId, signal });
9030
+ * for await (const event of stream) {
9031
+ * if (event.type === 'change') refresh(event.changes);
9032
+ * else if (event.type === 'resync' || event.resumed === false) refreshAll();
9033
+ * }
9034
+ * lastEventId = stream.lastEventId; // reconnect after stream.retry
9035
+ * ```
9036
+ */
9037
+ async stream(options) {
9038
+ return openLiveStream(this.openStream, "/live/stream", options);
9039
+ }
9040
+ /**
9041
+ * The current version of each kind of record named, in the caller's
9042
+ * merchant and shop. Read it before the record and send the entry's
9043
+ * `if_match` in the `If-Match` header of the save: a save over a newer
9044
+ * version is refused with `IR_16` (400), `error.data` a
9045
+ * `LiveChangedElsewhere` naming who made the change.
9046
+ *
9047
+ * `GET /live/versions`
9048
+ */
9049
+ async versions(params, options) {
9050
+ return this.request("GET", "/live/versions", {
9051
+ query: {
9052
+ entities: params.entities.join(","),
9053
+ profile_id: params.profile_id,
9054
+ record_id: params.record_id
9055
+ },
9056
+ ...options
9057
+ });
9058
+ }
9059
+ };
9060
+
8840
9061
  // src/client.ts
8841
9062
  var PRODUCTION_URL = "https://api.delopay.net";
8842
9063
  var SANDBOX_URL = "https://sandbox.delopay.net";
@@ -8860,6 +9081,40 @@ function truncateRawBody(raw) {
8860
9081
  if (!raw) return void 0;
8861
9082
  return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + "\u2026" : raw;
8862
9083
  }
9084
+ async function errorFromResponse(response, requestId) {
9085
+ const rawBody = await response.text().catch(() => "");
9086
+ let parsed = {};
9087
+ if (rawBody) {
9088
+ try {
9089
+ parsed = JSON.parse(rawBody);
9090
+ } catch {
9091
+ }
9092
+ }
9093
+ const err = parsed.error ?? parsed;
9094
+ const message = err.message ?? `Request failed with status ${response.status}`;
9095
+ const code = err.code ?? "";
9096
+ const type = err.error_type ?? err.type ?? "";
9097
+ const data = err.data && typeof err.data === "object" && !Array.isArray(err.data) ? err.data : void 0;
9098
+ const truncatedRaw = truncateRawBody(rawBody);
9099
+ const isConnectorPassthrough = type === "connector" || code.startsWith("CE_");
9100
+ if (response.status === 401 && !isConnectorPassthrough) {
9101
+ return new DelopayAuthenticationError(message, {
9102
+ code,
9103
+ type,
9104
+ requestId,
9105
+ rawBody: truncatedRaw,
9106
+ data
9107
+ });
9108
+ }
9109
+ return new DelopayError(message, {
9110
+ status: response.status,
9111
+ code,
9112
+ type,
9113
+ requestId,
9114
+ rawBody: truncatedRaw,
9115
+ data
9116
+ });
9117
+ }
8863
9118
  function findIdempotencyKey(headers) {
8864
9119
  for (const [k, v] of Object.entries(headers)) {
8865
9120
  if (k.toLowerCase() === "idempotency-key") return v;
@@ -9020,6 +9275,7 @@ function redactUrlForLogging(url) {
9020
9275
  });
9021
9276
  return `${base}?${parts.join("&")}`;
9022
9277
  }
9278
+ var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 45e3;
9023
9279
  var Delopay = class {
9024
9280
  /**
9025
9281
  * Create a new Delopay client.
@@ -9042,6 +9298,7 @@ var Delopay = class {
9042
9298
  this.baseUrl = PRODUCTION_URL;
9043
9299
  }
9044
9300
  const request = this.request.bind(this);
9301
+ const openStream = this.openEventStream.bind(this);
9045
9302
  this.payments = new Payments(request);
9046
9303
  this.refunds = new Refunds(request);
9047
9304
  this.customers = new Customers(request);
@@ -9078,6 +9335,7 @@ var Delopay = class {
9078
9335
  this.settings = new Settings(request);
9079
9336
  this.messageTemplates = new MessageTemplates(request);
9080
9337
  this.risk = new Risk(request);
9338
+ this.live = new Live(request, openStream);
9081
9339
  this.subscriptions = new Subscriptions(request);
9082
9340
  this.buyerPortal = new BuyerPortal(request);
9083
9341
  this.buyerAccount = new BuyerAccount(request);
@@ -9154,24 +9412,12 @@ var Delopay = class {
9154
9412
  this.setJwtToken(response.token);
9155
9413
  return response;
9156
9414
  }
9157
- /**
9158
- * Make a raw HTTP request to the Delopay API.
9159
- *
9160
- * You rarely need to call this directly — prefer the typed resource methods.
9161
- * Use it only for endpoints not yet covered by a resource class.
9162
- *
9163
- * @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).
9164
- * @param path - API path starting with `/` (e.g. `/payments`).
9165
- * @param options - Optional body, query parameters, and headers.
9166
- * @returns Parsed JSON response body typed as `T`.
9167
- * @throws {DelopayAuthenticationError} On 401 responses.
9168
- * @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.
9169
- */
9170
- async request(method, path, options) {
9415
+ /** `path` on the base URL, with the query string `query` makes. */
9416
+ buildUrl(path, query) {
9171
9417
  let url = `${this.baseUrl}${path}`;
9172
- if (options?.query) {
9418
+ if (query) {
9173
9419
  const params = new URLSearchParams();
9174
- for (const [key, value] of Object.entries(options.query)) {
9420
+ for (const [key, value] of Object.entries(query)) {
9175
9421
  if (value === void 0 || value === null) continue;
9176
9422
  if (Array.isArray(value)) {
9177
9423
  for (const v of value) {
@@ -9186,8 +9432,189 @@ var Delopay = class {
9186
9432
  url += `?${qs}`;
9187
9433
  }
9188
9434
  }
9435
+ return url;
9436
+ }
9437
+ /** The credential header: the JWT when one is set, else the API key. */
9438
+ authHeaders() {
9439
+ if (this.jwtToken) return { Authorization: `Bearer ${this.jwtToken}` };
9440
+ if (this.apiKey) return { "api-key": this.apiKey };
9441
+ return {};
9442
+ }
9443
+ /** One debug event, when `debug` is on. */
9444
+ log(event, data) {
9445
+ if (!this.debug) return;
9446
+ if (this.logger) {
9447
+ this.logger(event, data);
9448
+ return;
9449
+ }
9450
+ if (event === "request")
9451
+ console.log(`[delopay] ${data.method} ${data.url}`);
9452
+ else if (event === "response")
9453
+ console.log(
9454
+ `[delopay] ${data.status} ${data.method} ${data.path}`
9455
+ );
9456
+ else
9457
+ console.log(
9458
+ `[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
9459
+ );
9460
+ }
9461
+ /**
9462
+ * Open a `GET` `text/event-stream` and read it as it arrives.
9463
+ *
9464
+ * `request()` keeps every chunk of a body until the body ends, which a
9465
+ * stream that stays open for half an hour must not do; this reads the body
9466
+ * chunk by chunk through {@link EventStreamParser} and keeps nothing it has
9467
+ * dispatched. Credentials, the base URL, debug logging and the mapping of a
9468
+ * non-2xx answer to `DelopayError` / `DelopayAuthenticationError` are the
9469
+ * ones `request()` uses.
9470
+ *
9471
+ * Never retried, and never reconnected: the caller owns reconnection.
9472
+ * Resolves once the response headers arrive; rejects on a non-2xx answer,
9473
+ * on a 2xx that is not `text/event-stream` (code `NOT_EVENT_STREAM`), and
9474
+ * with `TIMEOUT`, `NETWORK` or `ABORTED` like `request()`.
9475
+ */
9476
+ async openEventStream(path, options = {}) {
9477
+ const url = this.buildUrl(path, options.query);
9478
+ const lastEventId = options.lastEventId ?? "";
9479
+ const headers = {
9480
+ ...this.authHeaders(),
9481
+ Accept: "text/event-stream",
9482
+ ...lastEventId ? { "Last-Event-ID": lastEventId } : {},
9483
+ ...options.headers
9484
+ };
9485
+ const idleMs = options.idleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS;
9486
+ const callerSignal = options.signal;
9487
+ const aborted = () => new DelopayError("Request aborted", { status: 0, code: "ABORTED", type: "abort_error" });
9488
+ if (callerSignal?.aborted) throw aborted();
9489
+ const idleCtrl = new AbortController();
9490
+ const closeCtrl = new AbortController();
9491
+ let timer;
9492
+ const stopIdleTimer = () => {
9493
+ if (timer !== void 0) clearTimeout(timer);
9494
+ timer = void 0;
9495
+ };
9496
+ const startIdleTimer = () => {
9497
+ stopIdleTimer();
9498
+ if (!idleCtrl.signal.aborted) timer = setTimeout(() => idleCtrl.abort(), idleMs);
9499
+ };
9500
+ const combined = combineSignals(
9501
+ callerSignal ? [idleCtrl.signal, closeCtrl.signal, callerSignal] : [idleCtrl.signal, closeCtrl.signal]
9502
+ );
9503
+ const release = () => {
9504
+ stopIdleTimer();
9505
+ combined.dispose();
9506
+ };
9507
+ const timedOut = () => new DelopayError(`Event stream silent for ${idleMs} ms`, {
9508
+ status: 0,
9509
+ code: "TIMEOUT",
9510
+ type: "timeout_error"
9511
+ });
9512
+ const network = (cause) => new DelopayError(
9513
+ `Network error: ${cause instanceof Error ? cause.message : String(cause ?? "stream failed")}`,
9514
+ { status: 0, code: "NETWORK", type: "network_error" }
9515
+ );
9516
+ this.log("request", { method: "GET", url: redactUrlForLogging(url), path });
9517
+ startIdleTimer();
9518
+ let response;
9519
+ try {
9520
+ response = await fetch(url, { method: "GET", headers, signal: combined.signal });
9521
+ } catch (err) {
9522
+ release();
9523
+ if (callerSignal?.aborted) throw aborted();
9524
+ if (idleCtrl.signal.aborted) throw timedOut();
9525
+ throw network(err);
9526
+ }
9527
+ const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
9528
+ this.log("response", { status: response.status, method: "GET", path, requestId });
9529
+ if (!response.ok) {
9530
+ const error = await errorFromResponse(response, requestId);
9531
+ release();
9532
+ throw error;
9533
+ }
9534
+ const body = response.body;
9535
+ const contentType = response.headers?.get("content-type") ?? "";
9536
+ const mediaType = (contentType.split(";")[0] ?? "").trim().toLowerCase();
9537
+ if (mediaType !== "text/event-stream" || !body || typeof body.getReader !== "function") {
9538
+ release();
9539
+ body?.cancel().catch(noop);
9540
+ throw new DelopayError(
9541
+ mediaType === "text/event-stream" ? "The event stream has no readable body" : `Expected a text/event-stream response, got ${contentType ? `"${contentType}"` : "no content type"}`,
9542
+ {
9543
+ status: response.status,
9544
+ code: "NOT_EVENT_STREAM",
9545
+ type: "invalid_response",
9546
+ requestId
9547
+ }
9548
+ );
9549
+ }
9550
+ stopIdleTimer();
9551
+ const reader = body.getReader();
9552
+ const parser = new EventStreamParser(lastEventId);
9553
+ const decoder = new TextDecoder();
9554
+ const stopped = () => Boolean(callerSignal?.aborted) || closeCtrl.signal.aborted;
9555
+ let finished = false;
9556
+ const finish = () => {
9557
+ if (finished) return;
9558
+ finished = true;
9559
+ release();
9560
+ reader.cancel().catch(noop);
9561
+ };
9562
+ async function* dispatches() {
9563
+ try {
9564
+ for (; ; ) {
9565
+ let result;
9566
+ startIdleTimer();
9567
+ try {
9568
+ result = await readChunk(reader, combined.signal);
9569
+ } catch (err) {
9570
+ if (callerSignal?.aborted || closeCtrl.signal.aborted) return;
9571
+ if (idleCtrl.signal.aborted) throw timedOut();
9572
+ throw network(err instanceof BodyStreamFailure ? err.cause : err);
9573
+ } finally {
9574
+ stopIdleTimer();
9575
+ }
9576
+ if (result.done) {
9577
+ for (const dispatch of parser.push(decoder.decode())) {
9578
+ if (stopped()) return;
9579
+ yield dispatch;
9580
+ }
9581
+ return;
9582
+ }
9583
+ if (!result.value || result.value.byteLength === 0) continue;
9584
+ for (const dispatch of parser.push(decoder.decode(result.value, { stream: true }))) {
9585
+ if (stopped()) return;
9586
+ yield dispatch;
9587
+ }
9588
+ }
9589
+ } finally {
9590
+ finish();
9591
+ }
9592
+ }
9593
+ return {
9594
+ dispatches: dispatches(),
9595
+ close: () => {
9596
+ closeCtrl.abort();
9597
+ finish();
9598
+ }
9599
+ };
9600
+ }
9601
+ /**
9602
+ * Make a raw HTTP request to the Delopay API.
9603
+ *
9604
+ * You rarely need to call this directly — prefer the typed resource methods.
9605
+ * Use it only for endpoints not yet covered by a resource class.
9606
+ *
9607
+ * @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).
9608
+ * @param path - API path starting with `/` (e.g. `/payments`).
9609
+ * @param options - Optional body, query parameters, and headers.
9610
+ * @returns Parsed JSON response body typed as `T`.
9611
+ * @throws {DelopayAuthenticationError} On 401 responses.
9612
+ * @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.
9613
+ */
9614
+ async request(method, path, options) {
9615
+ const url = this.buildUrl(path, options?.query);
9189
9616
  let headers = {
9190
- ...this.jwtToken ? { Authorization: `Bearer ${this.jwtToken}` } : this.apiKey ? { "api-key": this.apiKey } : {},
9617
+ ...this.authHeaders(),
9191
9618
  ...options?.headers
9192
9619
  };
9193
9620
  const isRawBody = options?.body !== void 0 && options?.body !== null && (options.body instanceof FormData || options.body instanceof Blob || options.body instanceof ArrayBuffer || options.body instanceof URLSearchParams);
@@ -9240,23 +9667,7 @@ var Delopay = class {
9240
9667
  let lastError;
9241
9668
  let retryAfterOverrideMs = null;
9242
9669
  const safeUrl = () => redactUrlForLogging(url);
9243
- const emit = (event, data) => {
9244
- if (!this.debug) return;
9245
- if (this.logger) {
9246
- this.logger(event, data);
9247
- return;
9248
- }
9249
- if (event === "request")
9250
- console.log(`[delopay] ${data.method} ${data.url}`);
9251
- else if (event === "response")
9252
- console.log(
9253
- `[delopay] ${data.status} ${data.method} ${data.path}`
9254
- );
9255
- else
9256
- console.log(
9257
- `[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
9258
- );
9259
- };
9670
+ const emit = (event, data) => this.log(event, data);
9260
9671
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
9261
9672
  if (attempt > 0) {
9262
9673
  const base = Math.min(500 * 2 ** (attempt - 1), 5e3);
@@ -9288,38 +9699,7 @@ var Delopay = class {
9288
9699
  const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
9289
9700
  emit("response", { status: response.status, method, path, requestId });
9290
9701
  if (!response.ok) {
9291
- const rawBody = await response.text().catch(() => "");
9292
- let parsed = {};
9293
- if (rawBody) {
9294
- try {
9295
- parsed = JSON.parse(rawBody);
9296
- } catch {
9297
- }
9298
- }
9299
- const err = parsed.error ?? parsed;
9300
- const message = err.message ?? `Request failed with status ${response.status}`;
9301
- const code = err.code ?? "";
9302
- const type = err.error_type ?? err.type ?? "";
9303
- const data = err.data && typeof err.data === "object" && !Array.isArray(err.data) ? err.data : void 0;
9304
- const truncatedRaw = truncateRawBody(rawBody);
9305
- const isConnectorPassthrough = type === "connector" || code.startsWith("CE_");
9306
- if (response.status === 401 && !isConnectorPassthrough) {
9307
- throw new DelopayAuthenticationError(message, {
9308
- code,
9309
- type,
9310
- requestId,
9311
- rawBody: truncatedRaw,
9312
- data
9313
- });
9314
- }
9315
- const error = new DelopayError(message, {
9316
- status: response.status,
9317
- code,
9318
- type,
9319
- requestId,
9320
- rawBody: truncatedRaw,
9321
- data
9322
- });
9702
+ const error = await errorFromResponse(response, requestId);
9323
9703
  const isTransientStatus = response.status >= 500 || response.status === 429;
9324
9704
  if (isTransientStatus && isRetryable && attempt < this.maxRetries) {
9325
9705
  if (response.status === 429) {
@@ -10787,6 +11167,13 @@ var DEFAULT_BRANDING_BASE = {
10787
11167
  paypalFocusRing: "strong",
10788
11168
  mollieFocusRing: "strong",
10789
11169
  paypalValidTint: false,
11170
+ epayoutsCardLayout: "split",
11171
+ epayoutsLabelStyle: "above",
11172
+ epayoutsFieldChrome: "outlined",
11173
+ epayoutsFieldFontSize: "md",
11174
+ epayoutsFieldWeight: "regular",
11175
+ epayoutsFocusRing: "strong",
11176
+ epayoutsValidTint: false,
10790
11177
  nomupayFormStyle: "plain",
10791
11178
  nomupayShowLabels: true,
10792
11179
  nomupayShowPlaceholders: true,
@@ -11817,6 +12204,66 @@ function decodeBranding(source) {
11817
12204
  DEFAULT_BRANDING.whopSelection
11818
12205
  ),
11819
12206
  paypalValidTint: parseBool(extras["paypalValidTint"], DEFAULT_BRANDING.paypalValidTint),
12207
+ // A look stored before todos#412 has no e-Payouts keys: the form keeps
12208
+ // the PayPal values it was drawn with until then.
12209
+ epayoutsCardLayout: pickEnum(
12210
+ extras["epayoutsCardLayout"],
12211
+ PAYPAL_CARD_LAYOUTS,
12212
+ pickEnum(
12213
+ extras["paypalCardLayout"],
12214
+ PAYPAL_CARD_LAYOUTS,
12215
+ DEFAULT_BRANDING.epayoutsCardLayout
12216
+ )
12217
+ ),
12218
+ epayoutsLabelStyle: pickEnum(
12219
+ extras["epayoutsLabelStyle"],
12220
+ PAYPAL_LABEL_STYLES,
12221
+ pickEnum(
12222
+ extras["paypalLabelStyle"],
12223
+ PAYPAL_LABEL_STYLES,
12224
+ DEFAULT_BRANDING.epayoutsLabelStyle
12225
+ )
12226
+ ),
12227
+ epayoutsFieldChrome: pickEnum(
12228
+ extras["epayoutsFieldChrome"],
12229
+ CARD_FIELD_CHROMES,
12230
+ pickEnum(
12231
+ extras["paypalFieldChrome"],
12232
+ CARD_FIELD_CHROMES,
12233
+ DEFAULT_BRANDING.epayoutsFieldChrome
12234
+ )
12235
+ ),
12236
+ epayoutsFieldFontSize: pickEnum(
12237
+ extras["epayoutsFieldFontSize"],
12238
+ CARD_FIELD_FONT_SIZES,
12239
+ pickEnum(
12240
+ extras["paypalFieldFontSize"],
12241
+ CARD_FIELD_FONT_SIZES,
12242
+ DEFAULT_BRANDING.epayoutsFieldFontSize
12243
+ )
12244
+ ),
12245
+ epayoutsFieldWeight: pickEnum(
12246
+ extras["epayoutsFieldWeight"],
12247
+ CARD_FIELD_WEIGHTS,
12248
+ pickEnum(
12249
+ extras["paypalFieldWeight"],
12250
+ CARD_FIELD_WEIGHTS,
12251
+ DEFAULT_BRANDING.epayoutsFieldWeight
12252
+ )
12253
+ ),
12254
+ epayoutsFocusRing: pickEnum(
12255
+ extras["epayoutsFocusRing"],
12256
+ CARD_FOCUS_RINGS,
12257
+ pickEnum(
12258
+ extras["paypalFocusRing"],
12259
+ CARD_FOCUS_RINGS,
12260
+ DEFAULT_BRANDING.epayoutsFocusRing
12261
+ )
12262
+ ),
12263
+ epayoutsValidTint: parseBool(
12264
+ extras["epayoutsValidTint"],
12265
+ parseBool(extras["paypalValidTint"], DEFAULT_BRANDING.epayoutsValidTint)
12266
+ ),
11820
12267
  nomupayFormStyle: pickEnum(
11821
12268
  extras["nomupayFormStyle"],
11822
12269
  NOMUPAY_FORM_STYLES,
@@ -11978,6 +12425,13 @@ function encodeBranding(branding, base) {
11978
12425
  whopMethodIcons: String(branding.whopMethodIcons),
11979
12426
  whopSelection: branding.whopSelection,
11980
12427
  paypalValidTint: String(branding.paypalValidTint),
12428
+ epayoutsCardLayout: branding.epayoutsCardLayout,
12429
+ epayoutsLabelStyle: branding.epayoutsLabelStyle,
12430
+ epayoutsFieldChrome: branding.epayoutsFieldChrome,
12431
+ epayoutsFieldFontSize: branding.epayoutsFieldFontSize,
12432
+ epayoutsFieldWeight: branding.epayoutsFieldWeight,
12433
+ epayoutsFocusRing: branding.epayoutsFocusRing,
12434
+ epayoutsValidTint: String(branding.epayoutsValidTint),
11981
12435
  nomupayFormStyle: branding.nomupayFormStyle,
11982
12436
  nomupayShowLabels: String(branding.nomupayShowLabels),
11983
12437
  nomupayShowPlaceholders: String(branding.nomupayShowPlaceholders),
@@ -12439,6 +12893,62 @@ function parseImportedBranding(raw) {
12439
12893
  dflt.whopSelection
12440
12894
  ),
12441
12895
  paypalValidTint: parseBool(root["paypalValidTint"], dflt.paypalValidTint),
12896
+ // A look stored before todos#412 has no e-Payouts keys: the form keeps
12897
+ // the PayPal values it was drawn with until then.
12898
+ epayoutsCardLayout: pickEnum(
12899
+ root["epayoutsCardLayout"],
12900
+ PAYPAL_CARD_LAYOUTS,
12901
+ pickEnum(
12902
+ root["paypalCardLayout"],
12903
+ PAYPAL_CARD_LAYOUTS,
12904
+ dflt.epayoutsCardLayout
12905
+ )
12906
+ ),
12907
+ epayoutsLabelStyle: pickEnum(
12908
+ root["epayoutsLabelStyle"],
12909
+ PAYPAL_LABEL_STYLES,
12910
+ pickEnum(
12911
+ root["paypalLabelStyle"],
12912
+ PAYPAL_LABEL_STYLES,
12913
+ dflt.epayoutsLabelStyle
12914
+ )
12915
+ ),
12916
+ epayoutsFieldChrome: pickEnum(
12917
+ root["epayoutsFieldChrome"],
12918
+ CARD_FIELD_CHROMES,
12919
+ pickEnum(
12920
+ root["paypalFieldChrome"],
12921
+ CARD_FIELD_CHROMES,
12922
+ dflt.epayoutsFieldChrome
12923
+ )
12924
+ ),
12925
+ epayoutsFieldFontSize: pickEnum(
12926
+ root["epayoutsFieldFontSize"],
12927
+ CARD_FIELD_FONT_SIZES,
12928
+ pickEnum(
12929
+ root["paypalFieldFontSize"],
12930
+ CARD_FIELD_FONT_SIZES,
12931
+ dflt.epayoutsFieldFontSize
12932
+ )
12933
+ ),
12934
+ epayoutsFieldWeight: pickEnum(
12935
+ root["epayoutsFieldWeight"],
12936
+ CARD_FIELD_WEIGHTS,
12937
+ pickEnum(
12938
+ root["paypalFieldWeight"],
12939
+ CARD_FIELD_WEIGHTS,
12940
+ dflt.epayoutsFieldWeight
12941
+ )
12942
+ ),
12943
+ epayoutsFocusRing: pickEnum(
12944
+ root["epayoutsFocusRing"],
12945
+ CARD_FOCUS_RINGS,
12946
+ pickEnum(root["paypalFocusRing"], CARD_FOCUS_RINGS, dflt.epayoutsFocusRing)
12947
+ ),
12948
+ epayoutsValidTint: parseBool(
12949
+ root["epayoutsValidTint"],
12950
+ parseBool(root["paypalValidTint"], dflt.epayoutsValidTint)
12951
+ ),
12442
12952
  nomupayFormStyle: pickEnum(
12443
12953
  root["nomupayFormStyle"],
12444
12954
  NOMUPAY_FORM_STYLES,
@@ -13952,6 +14462,9 @@ export {
13952
14462
  Settings,
13953
14463
  MessageTemplates,
13954
14464
  Risk,
14465
+ LiveEventStream,
14466
+ openLiveStream,
14467
+ Live,
13955
14468
  Delopay,
13956
14469
  leaf,
13957
14470
  allOf,
@@ -14169,4 +14682,4 @@ export {
14169
14682
  decodeNativePanes,
14170
14683
  encodeNativePanes
14171
14684
  };
14172
- //# sourceMappingURL=chunk-424242UX.js.map
14685
+ //# sourceMappingURL=chunk-5FGSME7D.js.map