@delopay/sdk 0.274.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.
- package/README.md +2 -0
- package/dist/{chunk-R6E57AD4.js → chunk-5FGSME7D.js} +731 -71
- package/dist/chunk-5FGSME7D.js.map +1 -0
- package/dist/index-BfFLiV95.d.cts +29423 -0
- package/dist/index-BfFLiV95.d.ts +29423 -0
- package/dist/index.cjs +731 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -28877
- package/dist/index.d.ts +1 -28877
- package/dist/index.js +5 -1
- package/dist/internal.cjs +770 -70
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +31 -3
- package/dist/internal.d.ts +31 -3
- package/dist/internal.js +44 -1
- package/dist/internal.js.map +1 -1
- package/package.json +17 -18
- package/dist/chunk-R6E57AD4.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -83,6 +83,8 @@ __export(index_exports, {
|
|
|
83
83
|
InvoiceSettingsResource: () => InvoiceSettingsResource,
|
|
84
84
|
Invoices: () => Invoices,
|
|
85
85
|
LOCALIZABLE_COPY_FIELDS: () => LOCALIZABLE_COPY_FIELDS,
|
|
86
|
+
Live: () => Live,
|
|
87
|
+
LiveEventStream: () => LiveEventStream,
|
|
86
88
|
MAX_SECTION_LABEL_LENGTH: () => MAX_SECTION_LABEL_LENGTH,
|
|
87
89
|
MAX_SECTION_ORDER: () => MAX_SECTION_ORDER,
|
|
88
90
|
METHOD_SECTIONS: () => METHOD_SECTIONS,
|
|
@@ -308,6 +310,100 @@ var DelopayAuthenticationError = class extends DelopayError {
|
|
|
308
310
|
}
|
|
309
311
|
};
|
|
310
312
|
|
|
313
|
+
// src/eventStream.ts
|
|
314
|
+
var LF = 10;
|
|
315
|
+
var CR = 13;
|
|
316
|
+
var EventStreamParser = class {
|
|
317
|
+
/**
|
|
318
|
+
* @param lastEventId - The id the stream resumes after, as `EventSource`
|
|
319
|
+
* carries it into a reconnection: a dispatch before the server names an
|
|
320
|
+
* id keeps this one.
|
|
321
|
+
*/
|
|
322
|
+
constructor(lastEventId = "") {
|
|
323
|
+
this.line = "";
|
|
324
|
+
/** The previous chunk ended in CR: a LF opening the next one belongs to it. */
|
|
325
|
+
this.skipLf = false;
|
|
326
|
+
this.data = "";
|
|
327
|
+
this.hasData = false;
|
|
328
|
+
this.eventType = "";
|
|
329
|
+
this.retry = null;
|
|
330
|
+
this.idBuffer = lastEventId;
|
|
331
|
+
}
|
|
332
|
+
/** Feed the next piece of decoded text; returns the dispatches it completed. */
|
|
333
|
+
push(text) {
|
|
334
|
+
const out = [];
|
|
335
|
+
if (text.length === 0) return out;
|
|
336
|
+
let start = 0;
|
|
337
|
+
if (this.skipLf) {
|
|
338
|
+
this.skipLf = false;
|
|
339
|
+
if (text.charCodeAt(0) === LF) start = 1;
|
|
340
|
+
}
|
|
341
|
+
for (let i = start; i < text.length; i++) {
|
|
342
|
+
const c = text.charCodeAt(i);
|
|
343
|
+
if (c !== LF && c !== CR) continue;
|
|
344
|
+
const line = this.line + text.slice(start, i);
|
|
345
|
+
this.line = "";
|
|
346
|
+
this.processLine(line, out);
|
|
347
|
+
if (c === CR) {
|
|
348
|
+
if (i + 1 < text.length) {
|
|
349
|
+
if (text.charCodeAt(i + 1) === LF) i++;
|
|
350
|
+
} else {
|
|
351
|
+
this.skipLf = true;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
start = i + 1;
|
|
355
|
+
}
|
|
356
|
+
this.line += text.slice(start);
|
|
357
|
+
return out;
|
|
358
|
+
}
|
|
359
|
+
processLine(line, out) {
|
|
360
|
+
if (line === "") {
|
|
361
|
+
this.dispatch(out);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (line.charCodeAt(0) === 58) return;
|
|
365
|
+
const colon = line.indexOf(":");
|
|
366
|
+
let field;
|
|
367
|
+
let value;
|
|
368
|
+
if (colon === -1) {
|
|
369
|
+
field = line;
|
|
370
|
+
value = "";
|
|
371
|
+
} else {
|
|
372
|
+
field = line.slice(0, colon);
|
|
373
|
+
value = line.slice(colon + 1);
|
|
374
|
+
if (value.charCodeAt(0) === 32) value = value.slice(1);
|
|
375
|
+
}
|
|
376
|
+
switch (field) {
|
|
377
|
+
case "event":
|
|
378
|
+
this.eventType = value;
|
|
379
|
+
break;
|
|
380
|
+
case "data":
|
|
381
|
+
this.data = this.hasData ? `${this.data}
|
|
382
|
+
${value}` : value;
|
|
383
|
+
this.hasData = true;
|
|
384
|
+
break;
|
|
385
|
+
case "id":
|
|
386
|
+
if (!value.includes("\0")) this.idBuffer = value;
|
|
387
|
+
break;
|
|
388
|
+
case "retry":
|
|
389
|
+
if (/^[0-9]+$/.test(value)) {
|
|
390
|
+
const ms = Number(value);
|
|
391
|
+
if (Number.isSafeInteger(ms)) this.retry = ms;
|
|
392
|
+
}
|
|
393
|
+
break;
|
|
394
|
+
default:
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
dispatch(out) {
|
|
399
|
+
const event = this.hasData ? { type: this.eventType || "message", data: this.data } : null;
|
|
400
|
+
out.push({ lastEventId: this.idBuffer, retry: this.retry, event });
|
|
401
|
+
this.data = "";
|
|
402
|
+
this.hasData = false;
|
|
403
|
+
this.eventType = "";
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
311
407
|
// src/resources/apiKeys.ts
|
|
312
408
|
var ApiKeys = class {
|
|
313
409
|
constructor(request) {
|
|
@@ -911,6 +1007,23 @@ var Connectors = class {
|
|
|
911
1007
|
{ body: params }
|
|
912
1008
|
);
|
|
913
1009
|
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Fold copies of the same provider account into this connector (todos#395).
|
|
1012
|
+
* `POST /account/{accountId}/connectors/{connectorId}/consolidate`
|
|
1013
|
+
*
|
|
1014
|
+
* The copies' shops move to the connector with their on/off state, routing,
|
|
1015
|
+
* checkout layout, currencies, saved credentials, mandates and
|
|
1016
|
+
* subscriptions. A copy keeps answering for the payments made on it and
|
|
1017
|
+
* serves no shop. Send `dry_run: true` first, then confirm with the
|
|
1018
|
+
* preview's `preview_token` and a choice for every conflict.
|
|
1019
|
+
*/
|
|
1020
|
+
async consolidate(accountId, connectorId, params) {
|
|
1021
|
+
return this.request(
|
|
1022
|
+
"POST",
|
|
1023
|
+
`/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/consolidate`,
|
|
1024
|
+
{ body: params }
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
914
1027
|
/**
|
|
915
1028
|
* Switch a connector off, or back on, in one shop it serves.
|
|
916
1029
|
* `POST /account/{accountId}/connectors/{connectorId}/shops/{profileId}`
|
|
@@ -1536,8 +1649,8 @@ var Customers = class {
|
|
|
1536
1649
|
};
|
|
1537
1650
|
|
|
1538
1651
|
// src/recordCounter.ts
|
|
1539
|
-
var
|
|
1540
|
-
var
|
|
1652
|
+
var LF2 = 10;
|
|
1653
|
+
var CR2 = 13;
|
|
1541
1654
|
var QUOTE = 34;
|
|
1542
1655
|
var BACKSLASH = 92;
|
|
1543
1656
|
var OPEN_BRACE = 123;
|
|
@@ -1561,10 +1674,10 @@ var CsvRecordCounter = class {
|
|
|
1561
1674
|
lineHasContent = true;
|
|
1562
1675
|
} else if (inQuotes) {
|
|
1563
1676
|
lineHasContent = true;
|
|
1564
|
-
} else if (byte ===
|
|
1677
|
+
} else if (byte === LF2) {
|
|
1565
1678
|
newlines++;
|
|
1566
1679
|
lineHasContent = false;
|
|
1567
|
-
} else if (byte !==
|
|
1680
|
+
} else if (byte !== CR2) {
|
|
1568
1681
|
lineHasContent = true;
|
|
1569
1682
|
}
|
|
1570
1683
|
}
|
|
@@ -6054,6 +6167,55 @@ var BuyerConversations = class {
|
|
|
6054
6167
|
body: params
|
|
6055
6168
|
});
|
|
6056
6169
|
}
|
|
6170
|
+
/**
|
|
6171
|
+
* A team member's internal note. Only the team reads it: the buyer never
|
|
6172
|
+
* sees a note, and a note does not move the conversation or mark it unread.
|
|
6173
|
+
* A closed conversation takes notes as well.
|
|
6174
|
+
* `POST /buyer-conversations/{id}/notes`
|
|
6175
|
+
*/
|
|
6176
|
+
async addNote(id, params) {
|
|
6177
|
+
return this.request("POST", `/buyer-conversations/${encodeURIComponent(id)}/notes`, {
|
|
6178
|
+
body: params
|
|
6179
|
+
});
|
|
6180
|
+
}
|
|
6181
|
+
/**
|
|
6182
|
+
* Upload a file for the caller's next answer, under the shop's attachment
|
|
6183
|
+
* rules (`attachment_rules` on the conversation). It belongs to the caller
|
|
6184
|
+
* until an answer names it in `attachments`; one no answer took within a
|
|
6185
|
+
* day is cleared. Uploading again with the same `clientUploadId` returns
|
|
6186
|
+
* the file the first upload stored.
|
|
6187
|
+
* `POST /buyer-conversation-files/{conversation}`
|
|
6188
|
+
*/
|
|
6189
|
+
async uploadFile(id, file, clientUploadId, fileName) {
|
|
6190
|
+
const form = new FormData();
|
|
6191
|
+
form.append("client_upload_id", clientUploadId);
|
|
6192
|
+
if (fileName === void 0) form.append("file", file);
|
|
6193
|
+
else form.append("file", file, fileName);
|
|
6194
|
+
return this.request("POST", `/buyer-conversation-files/${encodeURIComponent(id)}`, {
|
|
6195
|
+
body: form
|
|
6196
|
+
});
|
|
6197
|
+
}
|
|
6198
|
+
/**
|
|
6199
|
+
* Download a file a message of the conversation carries.
|
|
6200
|
+
* `GET /buyer-conversation-files/{conversation}/{file}`
|
|
6201
|
+
*/
|
|
6202
|
+
async downloadFile(id, fileId) {
|
|
6203
|
+
return this.request(
|
|
6204
|
+
"GET",
|
|
6205
|
+
`/buyer-conversation-files/${encodeURIComponent(id)}/${encodeURIComponent(fileId)}`,
|
|
6206
|
+
{ responseType: "blob" }
|
|
6207
|
+
);
|
|
6208
|
+
}
|
|
6209
|
+
/**
|
|
6210
|
+
* Remove a file the caller uploaded that no answer took.
|
|
6211
|
+
* `DELETE /buyer-conversation-files/{conversation}/{file}`
|
|
6212
|
+
*/
|
|
6213
|
+
async removeFile(id, fileId) {
|
|
6214
|
+
return this.request(
|
|
6215
|
+
"DELETE",
|
|
6216
|
+
`/buyer-conversation-files/${encodeURIComponent(id)}/${encodeURIComponent(fileId)}`
|
|
6217
|
+
);
|
|
6218
|
+
}
|
|
6057
6219
|
/**
|
|
6058
6220
|
* The team has read the conversation up to its last accepted message.
|
|
6059
6221
|
* `POST /buyer-conversations/{id}/read`
|
|
@@ -7870,6 +8032,53 @@ var BuyerAccount = class {
|
|
|
7870
8032
|
}
|
|
7871
8033
|
);
|
|
7872
8034
|
}
|
|
8035
|
+
/**
|
|
8036
|
+
* Upload a file for the buyer's next message to one shop of a confirmed
|
|
8037
|
+
* record, under the shop's attachment rules (`attachment_rules` on the
|
|
8038
|
+
* message page). It belongs to the buyer until a message names it in
|
|
8039
|
+
* `attachments`; one no message took within a day is cleared. Uploading
|
|
8040
|
+
* again with the same `clientUploadId` returns the file the first upload
|
|
8041
|
+
* stored. `shop` is required here.
|
|
8042
|
+
*/
|
|
8043
|
+
async uploadRecordMessageFile(record, file, clientUploadId, query, options) {
|
|
8044
|
+
const { fileName, ...extras } = options ?? {};
|
|
8045
|
+
const form = new FormData();
|
|
8046
|
+
form.append("client_upload_id", clientUploadId);
|
|
8047
|
+
if (fileName === void 0) form.append("file", file);
|
|
8048
|
+
else form.append("file", file, fileName);
|
|
8049
|
+
return this.request(
|
|
8050
|
+
"POST",
|
|
8051
|
+
`/buyer-account/records/${encodeURIComponent(record)}/messages/files`,
|
|
8052
|
+
{
|
|
8053
|
+
body: form,
|
|
8054
|
+
query,
|
|
8055
|
+
...extras
|
|
8056
|
+
}
|
|
8057
|
+
);
|
|
8058
|
+
}
|
|
8059
|
+
/** Download a file a message of a record's conversation with one shop carries. */
|
|
8060
|
+
async downloadRecordMessageFile(record, fileId, query, options) {
|
|
8061
|
+
return this.request(
|
|
8062
|
+
"GET",
|
|
8063
|
+
`/buyer-account/records/${encodeURIComponent(record)}/messages/files/${encodeURIComponent(fileId)}`,
|
|
8064
|
+
{
|
|
8065
|
+
query,
|
|
8066
|
+
responseType: "blob",
|
|
8067
|
+
...options
|
|
8068
|
+
}
|
|
8069
|
+
);
|
|
8070
|
+
}
|
|
8071
|
+
/** Remove a file the buyer uploaded for a record's conversation that no message took. */
|
|
8072
|
+
async removeRecordMessageFile(record, fileId, query, options) {
|
|
8073
|
+
return this.request(
|
|
8074
|
+
"DELETE",
|
|
8075
|
+
`/buyer-account/records/${encodeURIComponent(record)}/messages/files/${encodeURIComponent(fileId)}`,
|
|
8076
|
+
{
|
|
8077
|
+
query,
|
|
8078
|
+
...options
|
|
8079
|
+
}
|
|
8080
|
+
);
|
|
8081
|
+
}
|
|
7873
8082
|
/**
|
|
7874
8083
|
* What the buyer spent in a period: paid purchases summed per currency,
|
|
7875
8084
|
* never converted, for the whole period, per day, week or month, per shop
|
|
@@ -8092,6 +8301,40 @@ var BuyerPortal = class {
|
|
|
8092
8301
|
...options
|
|
8093
8302
|
});
|
|
8094
8303
|
}
|
|
8304
|
+
/**
|
|
8305
|
+
* Upload a file for the buyer's next message to one shop, under the shop's
|
|
8306
|
+
* attachment rules (`attachment_rules` on the message page). It belongs to
|
|
8307
|
+
* the buyer until a message names it in `attachments`; one no message took
|
|
8308
|
+
* within a day is cleared. Uploading again with the same `clientUploadId`
|
|
8309
|
+
* returns the file the first upload stored.
|
|
8310
|
+
*/
|
|
8311
|
+
async uploadMessageFile(file, clientUploadId, query, options) {
|
|
8312
|
+
const { fileName, ...extras } = options ?? {};
|
|
8313
|
+
const form = new FormData();
|
|
8314
|
+
form.append("client_upload_id", clientUploadId);
|
|
8315
|
+
if (fileName === void 0) form.append("file", file);
|
|
8316
|
+
else form.append("file", file, fileName);
|
|
8317
|
+
return this.request("POST", "/buyer-portal/messages/files", {
|
|
8318
|
+
body: form,
|
|
8319
|
+
query,
|
|
8320
|
+
...extras
|
|
8321
|
+
});
|
|
8322
|
+
}
|
|
8323
|
+
/** Download a file a message of the buyer's conversation with one shop carries. */
|
|
8324
|
+
async downloadMessageFile(fileId, query, options) {
|
|
8325
|
+
return this.request("GET", `/buyer-portal/messages/files/${encodeURIComponent(fileId)}`, {
|
|
8326
|
+
query,
|
|
8327
|
+
responseType: "blob",
|
|
8328
|
+
...options
|
|
8329
|
+
});
|
|
8330
|
+
}
|
|
8331
|
+
/** Remove a file the buyer uploaded that no message took. */
|
|
8332
|
+
async removeMessageFile(fileId, query, options) {
|
|
8333
|
+
return this.request("DELETE", `/buyer-portal/messages/files/${encodeURIComponent(fileId)}`, {
|
|
8334
|
+
query,
|
|
8335
|
+
...options
|
|
8336
|
+
});
|
|
8337
|
+
}
|
|
8095
8338
|
/** The buyer's contact and billing details, and what they may change. */
|
|
8096
8339
|
async getProfile(options) {
|
|
8097
8340
|
return this.request("GET", "/buyer-portal/profile", { ...options });
|
|
@@ -8968,6 +9211,133 @@ var Risk = class {
|
|
|
8968
9211
|
}
|
|
8969
9212
|
};
|
|
8970
9213
|
|
|
9214
|
+
// src/resources/live.ts
|
|
9215
|
+
function readField(data, key) {
|
|
9216
|
+
let value;
|
|
9217
|
+
try {
|
|
9218
|
+
value = JSON.parse(data);
|
|
9219
|
+
} catch {
|
|
9220
|
+
return void 0;
|
|
9221
|
+
}
|
|
9222
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9223
|
+
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
9224
|
+
}
|
|
9225
|
+
function toLiveStreamEvent(event, id, retry) {
|
|
9226
|
+
switch (event.type) {
|
|
9227
|
+
case "ready": {
|
|
9228
|
+
const resumed = readField(event.data, "resumed");
|
|
9229
|
+
return { type: "ready", id, retry, resumed: typeof resumed === "boolean" ? resumed : null };
|
|
9230
|
+
}
|
|
9231
|
+
case "change": {
|
|
9232
|
+
const changes = readField(event.data, "changes");
|
|
9233
|
+
if (!Array.isArray(changes)) return { type: "resync", id };
|
|
9234
|
+
return { type: "change", id, changes };
|
|
9235
|
+
}
|
|
9236
|
+
case "resync":
|
|
9237
|
+
return { type: "resync", id };
|
|
9238
|
+
default:
|
|
9239
|
+
return null;
|
|
9240
|
+
}
|
|
9241
|
+
}
|
|
9242
|
+
var LiveEventStream = class {
|
|
9243
|
+
constructor(connection, lastEventId = null) {
|
|
9244
|
+
this.connection = connection;
|
|
9245
|
+
this._retry = null;
|
|
9246
|
+
this._lastEventId = lastEventId || null;
|
|
9247
|
+
}
|
|
9248
|
+
/**
|
|
9249
|
+
* The position to resume after: the id of the last event read, advanced by
|
|
9250
|
+
* keepalives too. `null` before the server named one. Send it as
|
|
9251
|
+
* `lastEventId` when reconnecting.
|
|
9252
|
+
*/
|
|
9253
|
+
get lastEventId() {
|
|
9254
|
+
return this._lastEventId;
|
|
9255
|
+
}
|
|
9256
|
+
/** The wait before reconnecting the server asked for, in ms; `null` until it says. */
|
|
9257
|
+
get retry() {
|
|
9258
|
+
return this._retry;
|
|
9259
|
+
}
|
|
9260
|
+
/** Close the stream; the iteration ends without an error. */
|
|
9261
|
+
close() {
|
|
9262
|
+
this.connection.close();
|
|
9263
|
+
}
|
|
9264
|
+
[Symbol.asyncIterator]() {
|
|
9265
|
+
this.iterator ?? (this.iterator = this.events());
|
|
9266
|
+
return this.iterator;
|
|
9267
|
+
}
|
|
9268
|
+
async *events() {
|
|
9269
|
+
for await (const dispatch of this.connection.dispatches) {
|
|
9270
|
+
const event = this.read(dispatch);
|
|
9271
|
+
if (event) yield event;
|
|
9272
|
+
}
|
|
9273
|
+
}
|
|
9274
|
+
read(dispatch) {
|
|
9275
|
+
this._lastEventId = dispatch.lastEventId || null;
|
|
9276
|
+
if (dispatch.retry !== null) this._retry = dispatch.retry;
|
|
9277
|
+
if (!dispatch.event) return null;
|
|
9278
|
+
return toLiveStreamEvent(dispatch.event, this._lastEventId, this._retry);
|
|
9279
|
+
}
|
|
9280
|
+
};
|
|
9281
|
+
async function openLiveStream(openStream, path, options = {}) {
|
|
9282
|
+
const connection = await openStream(path, {
|
|
9283
|
+
...options.lastEventId ? { lastEventId: options.lastEventId } : {},
|
|
9284
|
+
...options.signal ? { signal: options.signal } : {},
|
|
9285
|
+
...options.idleTimeoutMs !== void 0 ? { idleTimeoutMs: options.idleTimeoutMs } : {},
|
|
9286
|
+
...options.headers ? { headers: options.headers } : {}
|
|
9287
|
+
});
|
|
9288
|
+
return new LiveEventStream(connection, options.lastEventId ?? null);
|
|
9289
|
+
}
|
|
9290
|
+
var Live = class {
|
|
9291
|
+
constructor(request, openStream) {
|
|
9292
|
+
this.request = request;
|
|
9293
|
+
this.openStream = openStream;
|
|
9294
|
+
}
|
|
9295
|
+
/**
|
|
9296
|
+
* Open the stream of what changed in the caller's merchant, as their role
|
|
9297
|
+
* may read it. Resolves once the server answered; a `401` rejects with
|
|
9298
|
+
* `DelopayAuthenticationError`.
|
|
9299
|
+
*
|
|
9300
|
+
* The first event is `ready`. `change` names the kinds of record and, when
|
|
9301
|
+
* few, the ids that changed: read them again through the usual endpoints.
|
|
9302
|
+
* `resync`, and `ready` with `resumed: false`, mean read everything again.
|
|
9303
|
+
* The SDK does not reconnect — see {@link LiveEventStream}.
|
|
9304
|
+
*
|
|
9305
|
+
* `GET /live/stream`
|
|
9306
|
+
*
|
|
9307
|
+
* @example
|
|
9308
|
+
* ```typescript
|
|
9309
|
+
* const stream = await delopay.live.stream({ lastEventId, signal });
|
|
9310
|
+
* for await (const event of stream) {
|
|
9311
|
+
* if (event.type === 'change') refresh(event.changes);
|
|
9312
|
+
* else if (event.type === 'resync' || event.resumed === false) refreshAll();
|
|
9313
|
+
* }
|
|
9314
|
+
* lastEventId = stream.lastEventId; // reconnect after stream.retry
|
|
9315
|
+
* ```
|
|
9316
|
+
*/
|
|
9317
|
+
async stream(options) {
|
|
9318
|
+
return openLiveStream(this.openStream, "/live/stream", options);
|
|
9319
|
+
}
|
|
9320
|
+
/**
|
|
9321
|
+
* The current version of each kind of record named, in the caller's
|
|
9322
|
+
* merchant and shop. Read it before the record and send the entry's
|
|
9323
|
+
* `if_match` in the `If-Match` header of the save: a save over a newer
|
|
9324
|
+
* version is refused with `IR_16` (400), `error.data` a
|
|
9325
|
+
* `LiveChangedElsewhere` naming who made the change.
|
|
9326
|
+
*
|
|
9327
|
+
* `GET /live/versions`
|
|
9328
|
+
*/
|
|
9329
|
+
async versions(params, options) {
|
|
9330
|
+
return this.request("GET", "/live/versions", {
|
|
9331
|
+
query: {
|
|
9332
|
+
entities: params.entities.join(","),
|
|
9333
|
+
profile_id: params.profile_id,
|
|
9334
|
+
record_id: params.record_id
|
|
9335
|
+
},
|
|
9336
|
+
...options
|
|
9337
|
+
});
|
|
9338
|
+
}
|
|
9339
|
+
};
|
|
9340
|
+
|
|
8971
9341
|
// src/client.ts
|
|
8972
9342
|
var PRODUCTION_URL = "https://api.delopay.net";
|
|
8973
9343
|
var SANDBOX_URL = "https://sandbox.delopay.net";
|
|
@@ -8991,6 +9361,40 @@ function truncateRawBody(raw) {
|
|
|
8991
9361
|
if (!raw) return void 0;
|
|
8992
9362
|
return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + "\u2026" : raw;
|
|
8993
9363
|
}
|
|
9364
|
+
async function errorFromResponse(response, requestId) {
|
|
9365
|
+
const rawBody = await response.text().catch(() => "");
|
|
9366
|
+
let parsed = {};
|
|
9367
|
+
if (rawBody) {
|
|
9368
|
+
try {
|
|
9369
|
+
parsed = JSON.parse(rawBody);
|
|
9370
|
+
} catch {
|
|
9371
|
+
}
|
|
9372
|
+
}
|
|
9373
|
+
const err = parsed.error ?? parsed;
|
|
9374
|
+
const message = err.message ?? `Request failed with status ${response.status}`;
|
|
9375
|
+
const code = err.code ?? "";
|
|
9376
|
+
const type = err.error_type ?? err.type ?? "";
|
|
9377
|
+
const data = err.data && typeof err.data === "object" && !Array.isArray(err.data) ? err.data : void 0;
|
|
9378
|
+
const truncatedRaw = truncateRawBody(rawBody);
|
|
9379
|
+
const isConnectorPassthrough = type === "connector" || code.startsWith("CE_");
|
|
9380
|
+
if (response.status === 401 && !isConnectorPassthrough) {
|
|
9381
|
+
return new DelopayAuthenticationError(message, {
|
|
9382
|
+
code,
|
|
9383
|
+
type,
|
|
9384
|
+
requestId,
|
|
9385
|
+
rawBody: truncatedRaw,
|
|
9386
|
+
data
|
|
9387
|
+
});
|
|
9388
|
+
}
|
|
9389
|
+
return new DelopayError(message, {
|
|
9390
|
+
status: response.status,
|
|
9391
|
+
code,
|
|
9392
|
+
type,
|
|
9393
|
+
requestId,
|
|
9394
|
+
rawBody: truncatedRaw,
|
|
9395
|
+
data
|
|
9396
|
+
});
|
|
9397
|
+
}
|
|
8994
9398
|
function findIdempotencyKey(headers) {
|
|
8995
9399
|
for (const [k, v] of Object.entries(headers)) {
|
|
8996
9400
|
if (k.toLowerCase() === "idempotency-key") return v;
|
|
@@ -9151,6 +9555,7 @@ function redactUrlForLogging(url) {
|
|
|
9151
9555
|
});
|
|
9152
9556
|
return `${base}?${parts.join("&")}`;
|
|
9153
9557
|
}
|
|
9558
|
+
var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 45e3;
|
|
9154
9559
|
var Delopay = class {
|
|
9155
9560
|
/**
|
|
9156
9561
|
* Create a new Delopay client.
|
|
@@ -9173,6 +9578,7 @@ var Delopay = class {
|
|
|
9173
9578
|
this.baseUrl = PRODUCTION_URL;
|
|
9174
9579
|
}
|
|
9175
9580
|
const request = this.request.bind(this);
|
|
9581
|
+
const openStream = this.openEventStream.bind(this);
|
|
9176
9582
|
this.payments = new Payments(request);
|
|
9177
9583
|
this.refunds = new Refunds(request);
|
|
9178
9584
|
this.customers = new Customers(request);
|
|
@@ -9209,6 +9615,7 @@ var Delopay = class {
|
|
|
9209
9615
|
this.settings = new Settings(request);
|
|
9210
9616
|
this.messageTemplates = new MessageTemplates(request);
|
|
9211
9617
|
this.risk = new Risk(request);
|
|
9618
|
+
this.live = new Live(request, openStream);
|
|
9212
9619
|
this.subscriptions = new Subscriptions(request);
|
|
9213
9620
|
this.buyerPortal = new BuyerPortal(request);
|
|
9214
9621
|
this.buyerAccount = new BuyerAccount(request);
|
|
@@ -9285,24 +9692,12 @@ var Delopay = class {
|
|
|
9285
9692
|
this.setJwtToken(response.token);
|
|
9286
9693
|
return response;
|
|
9287
9694
|
}
|
|
9288
|
-
/**
|
|
9289
|
-
|
|
9290
|
-
*
|
|
9291
|
-
* You rarely need to call this directly — prefer the typed resource methods.
|
|
9292
|
-
* Use it only for endpoints not yet covered by a resource class.
|
|
9293
|
-
*
|
|
9294
|
-
* @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).
|
|
9295
|
-
* @param path - API path starting with `/` (e.g. `/payments`).
|
|
9296
|
-
* @param options - Optional body, query parameters, and headers.
|
|
9297
|
-
* @returns Parsed JSON response body typed as `T`.
|
|
9298
|
-
* @throws {DelopayAuthenticationError} On 401 responses.
|
|
9299
|
-
* @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.
|
|
9300
|
-
*/
|
|
9301
|
-
async request(method, path, options) {
|
|
9695
|
+
/** `path` on the base URL, with the query string `query` makes. */
|
|
9696
|
+
buildUrl(path, query) {
|
|
9302
9697
|
let url = `${this.baseUrl}${path}`;
|
|
9303
|
-
if (
|
|
9698
|
+
if (query) {
|
|
9304
9699
|
const params = new URLSearchParams();
|
|
9305
|
-
for (const [key, value] of Object.entries(
|
|
9700
|
+
for (const [key, value] of Object.entries(query)) {
|
|
9306
9701
|
if (value === void 0 || value === null) continue;
|
|
9307
9702
|
if (Array.isArray(value)) {
|
|
9308
9703
|
for (const v of value) {
|
|
@@ -9317,8 +9712,189 @@ var Delopay = class {
|
|
|
9317
9712
|
url += `?${qs}`;
|
|
9318
9713
|
}
|
|
9319
9714
|
}
|
|
9715
|
+
return url;
|
|
9716
|
+
}
|
|
9717
|
+
/** The credential header: the JWT when one is set, else the API key. */
|
|
9718
|
+
authHeaders() {
|
|
9719
|
+
if (this.jwtToken) return { Authorization: `Bearer ${this.jwtToken}` };
|
|
9720
|
+
if (this.apiKey) return { "api-key": this.apiKey };
|
|
9721
|
+
return {};
|
|
9722
|
+
}
|
|
9723
|
+
/** One debug event, when `debug` is on. */
|
|
9724
|
+
log(event, data) {
|
|
9725
|
+
if (!this.debug) return;
|
|
9726
|
+
if (this.logger) {
|
|
9727
|
+
this.logger(event, data);
|
|
9728
|
+
return;
|
|
9729
|
+
}
|
|
9730
|
+
if (event === "request")
|
|
9731
|
+
console.log(`[delopay] ${data.method} ${data.url}`);
|
|
9732
|
+
else if (event === "response")
|
|
9733
|
+
console.log(
|
|
9734
|
+
`[delopay] ${data.status} ${data.method} ${data.path}`
|
|
9735
|
+
);
|
|
9736
|
+
else
|
|
9737
|
+
console.log(
|
|
9738
|
+
`[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
|
|
9739
|
+
);
|
|
9740
|
+
}
|
|
9741
|
+
/**
|
|
9742
|
+
* Open a `GET` `text/event-stream` and read it as it arrives.
|
|
9743
|
+
*
|
|
9744
|
+
* `request()` keeps every chunk of a body until the body ends, which a
|
|
9745
|
+
* stream that stays open for half an hour must not do; this reads the body
|
|
9746
|
+
* chunk by chunk through {@link EventStreamParser} and keeps nothing it has
|
|
9747
|
+
* dispatched. Credentials, the base URL, debug logging and the mapping of a
|
|
9748
|
+
* non-2xx answer to `DelopayError` / `DelopayAuthenticationError` are the
|
|
9749
|
+
* ones `request()` uses.
|
|
9750
|
+
*
|
|
9751
|
+
* Never retried, and never reconnected: the caller owns reconnection.
|
|
9752
|
+
* Resolves once the response headers arrive; rejects on a non-2xx answer,
|
|
9753
|
+
* on a 2xx that is not `text/event-stream` (code `NOT_EVENT_STREAM`), and
|
|
9754
|
+
* with `TIMEOUT`, `NETWORK` or `ABORTED` like `request()`.
|
|
9755
|
+
*/
|
|
9756
|
+
async openEventStream(path, options = {}) {
|
|
9757
|
+
const url = this.buildUrl(path, options.query);
|
|
9758
|
+
const lastEventId = options.lastEventId ?? "";
|
|
9759
|
+
const headers = {
|
|
9760
|
+
...this.authHeaders(),
|
|
9761
|
+
Accept: "text/event-stream",
|
|
9762
|
+
...lastEventId ? { "Last-Event-ID": lastEventId } : {},
|
|
9763
|
+
...options.headers
|
|
9764
|
+
};
|
|
9765
|
+
const idleMs = options.idleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS;
|
|
9766
|
+
const callerSignal = options.signal;
|
|
9767
|
+
const aborted = () => new DelopayError("Request aborted", { status: 0, code: "ABORTED", type: "abort_error" });
|
|
9768
|
+
if (callerSignal?.aborted) throw aborted();
|
|
9769
|
+
const idleCtrl = new AbortController();
|
|
9770
|
+
const closeCtrl = new AbortController();
|
|
9771
|
+
let timer;
|
|
9772
|
+
const stopIdleTimer = () => {
|
|
9773
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
9774
|
+
timer = void 0;
|
|
9775
|
+
};
|
|
9776
|
+
const startIdleTimer = () => {
|
|
9777
|
+
stopIdleTimer();
|
|
9778
|
+
if (!idleCtrl.signal.aborted) timer = setTimeout(() => idleCtrl.abort(), idleMs);
|
|
9779
|
+
};
|
|
9780
|
+
const combined = combineSignals(
|
|
9781
|
+
callerSignal ? [idleCtrl.signal, closeCtrl.signal, callerSignal] : [idleCtrl.signal, closeCtrl.signal]
|
|
9782
|
+
);
|
|
9783
|
+
const release = () => {
|
|
9784
|
+
stopIdleTimer();
|
|
9785
|
+
combined.dispose();
|
|
9786
|
+
};
|
|
9787
|
+
const timedOut = () => new DelopayError(`Event stream silent for ${idleMs} ms`, {
|
|
9788
|
+
status: 0,
|
|
9789
|
+
code: "TIMEOUT",
|
|
9790
|
+
type: "timeout_error"
|
|
9791
|
+
});
|
|
9792
|
+
const network = (cause) => new DelopayError(
|
|
9793
|
+
`Network error: ${cause instanceof Error ? cause.message : String(cause ?? "stream failed")}`,
|
|
9794
|
+
{ status: 0, code: "NETWORK", type: "network_error" }
|
|
9795
|
+
);
|
|
9796
|
+
this.log("request", { method: "GET", url: redactUrlForLogging(url), path });
|
|
9797
|
+
startIdleTimer();
|
|
9798
|
+
let response;
|
|
9799
|
+
try {
|
|
9800
|
+
response = await fetch(url, { method: "GET", headers, signal: combined.signal });
|
|
9801
|
+
} catch (err) {
|
|
9802
|
+
release();
|
|
9803
|
+
if (callerSignal?.aborted) throw aborted();
|
|
9804
|
+
if (idleCtrl.signal.aborted) throw timedOut();
|
|
9805
|
+
throw network(err);
|
|
9806
|
+
}
|
|
9807
|
+
const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
|
|
9808
|
+
this.log("response", { status: response.status, method: "GET", path, requestId });
|
|
9809
|
+
if (!response.ok) {
|
|
9810
|
+
const error = await errorFromResponse(response, requestId);
|
|
9811
|
+
release();
|
|
9812
|
+
throw error;
|
|
9813
|
+
}
|
|
9814
|
+
const body = response.body;
|
|
9815
|
+
const contentType = response.headers?.get("content-type") ?? "";
|
|
9816
|
+
const mediaType = (contentType.split(";")[0] ?? "").trim().toLowerCase();
|
|
9817
|
+
if (mediaType !== "text/event-stream" || !body || typeof body.getReader !== "function") {
|
|
9818
|
+
release();
|
|
9819
|
+
body?.cancel().catch(noop);
|
|
9820
|
+
throw new DelopayError(
|
|
9821
|
+
mediaType === "text/event-stream" ? "The event stream has no readable body" : `Expected a text/event-stream response, got ${contentType ? `"${contentType}"` : "no content type"}`,
|
|
9822
|
+
{
|
|
9823
|
+
status: response.status,
|
|
9824
|
+
code: "NOT_EVENT_STREAM",
|
|
9825
|
+
type: "invalid_response",
|
|
9826
|
+
requestId
|
|
9827
|
+
}
|
|
9828
|
+
);
|
|
9829
|
+
}
|
|
9830
|
+
stopIdleTimer();
|
|
9831
|
+
const reader = body.getReader();
|
|
9832
|
+
const parser = new EventStreamParser(lastEventId);
|
|
9833
|
+
const decoder = new TextDecoder();
|
|
9834
|
+
const stopped = () => Boolean(callerSignal?.aborted) || closeCtrl.signal.aborted;
|
|
9835
|
+
let finished = false;
|
|
9836
|
+
const finish = () => {
|
|
9837
|
+
if (finished) return;
|
|
9838
|
+
finished = true;
|
|
9839
|
+
release();
|
|
9840
|
+
reader.cancel().catch(noop);
|
|
9841
|
+
};
|
|
9842
|
+
async function* dispatches() {
|
|
9843
|
+
try {
|
|
9844
|
+
for (; ; ) {
|
|
9845
|
+
let result;
|
|
9846
|
+
startIdleTimer();
|
|
9847
|
+
try {
|
|
9848
|
+
result = await readChunk(reader, combined.signal);
|
|
9849
|
+
} catch (err) {
|
|
9850
|
+
if (callerSignal?.aborted || closeCtrl.signal.aborted) return;
|
|
9851
|
+
if (idleCtrl.signal.aborted) throw timedOut();
|
|
9852
|
+
throw network(err instanceof BodyStreamFailure ? err.cause : err);
|
|
9853
|
+
} finally {
|
|
9854
|
+
stopIdleTimer();
|
|
9855
|
+
}
|
|
9856
|
+
if (result.done) {
|
|
9857
|
+
for (const dispatch of parser.push(decoder.decode())) {
|
|
9858
|
+
if (stopped()) return;
|
|
9859
|
+
yield dispatch;
|
|
9860
|
+
}
|
|
9861
|
+
return;
|
|
9862
|
+
}
|
|
9863
|
+
if (!result.value || result.value.byteLength === 0) continue;
|
|
9864
|
+
for (const dispatch of parser.push(decoder.decode(result.value, { stream: true }))) {
|
|
9865
|
+
if (stopped()) return;
|
|
9866
|
+
yield dispatch;
|
|
9867
|
+
}
|
|
9868
|
+
}
|
|
9869
|
+
} finally {
|
|
9870
|
+
finish();
|
|
9871
|
+
}
|
|
9872
|
+
}
|
|
9873
|
+
return {
|
|
9874
|
+
dispatches: dispatches(),
|
|
9875
|
+
close: () => {
|
|
9876
|
+
closeCtrl.abort();
|
|
9877
|
+
finish();
|
|
9878
|
+
}
|
|
9879
|
+
};
|
|
9880
|
+
}
|
|
9881
|
+
/**
|
|
9882
|
+
* Make a raw HTTP request to the Delopay API.
|
|
9883
|
+
*
|
|
9884
|
+
* You rarely need to call this directly — prefer the typed resource methods.
|
|
9885
|
+
* Use it only for endpoints not yet covered by a resource class.
|
|
9886
|
+
*
|
|
9887
|
+
* @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).
|
|
9888
|
+
* @param path - API path starting with `/` (e.g. `/payments`).
|
|
9889
|
+
* @param options - Optional body, query parameters, and headers.
|
|
9890
|
+
* @returns Parsed JSON response body typed as `T`.
|
|
9891
|
+
* @throws {DelopayAuthenticationError} On 401 responses.
|
|
9892
|
+
* @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.
|
|
9893
|
+
*/
|
|
9894
|
+
async request(method, path, options) {
|
|
9895
|
+
const url = this.buildUrl(path, options?.query);
|
|
9320
9896
|
let headers = {
|
|
9321
|
-
...this.
|
|
9897
|
+
...this.authHeaders(),
|
|
9322
9898
|
...options?.headers
|
|
9323
9899
|
};
|
|
9324
9900
|
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);
|
|
@@ -9371,23 +9947,7 @@ var Delopay = class {
|
|
|
9371
9947
|
let lastError;
|
|
9372
9948
|
let retryAfterOverrideMs = null;
|
|
9373
9949
|
const safeUrl = () => redactUrlForLogging(url);
|
|
9374
|
-
const emit = (event, data) =>
|
|
9375
|
-
if (!this.debug) return;
|
|
9376
|
-
if (this.logger) {
|
|
9377
|
-
this.logger(event, data);
|
|
9378
|
-
return;
|
|
9379
|
-
}
|
|
9380
|
-
if (event === "request")
|
|
9381
|
-
console.log(`[delopay] ${data.method} ${data.url}`);
|
|
9382
|
-
else if (event === "response")
|
|
9383
|
-
console.log(
|
|
9384
|
-
`[delopay] ${data.status} ${data.method} ${data.path}`
|
|
9385
|
-
);
|
|
9386
|
-
else
|
|
9387
|
-
console.log(
|
|
9388
|
-
`[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
|
|
9389
|
-
);
|
|
9390
|
-
};
|
|
9950
|
+
const emit = (event, data) => this.log(event, data);
|
|
9391
9951
|
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
9392
9952
|
if (attempt > 0) {
|
|
9393
9953
|
const base = Math.min(500 * 2 ** (attempt - 1), 5e3);
|
|
@@ -9419,38 +9979,7 @@ var Delopay = class {
|
|
|
9419
9979
|
const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
|
|
9420
9980
|
emit("response", { status: response.status, method, path, requestId });
|
|
9421
9981
|
if (!response.ok) {
|
|
9422
|
-
const
|
|
9423
|
-
let parsed = {};
|
|
9424
|
-
if (rawBody) {
|
|
9425
|
-
try {
|
|
9426
|
-
parsed = JSON.parse(rawBody);
|
|
9427
|
-
} catch {
|
|
9428
|
-
}
|
|
9429
|
-
}
|
|
9430
|
-
const err = parsed.error ?? parsed;
|
|
9431
|
-
const message = err.message ?? `Request failed with status ${response.status}`;
|
|
9432
|
-
const code = err.code ?? "";
|
|
9433
|
-
const type = err.error_type ?? err.type ?? "";
|
|
9434
|
-
const data = err.data && typeof err.data === "object" && !Array.isArray(err.data) ? err.data : void 0;
|
|
9435
|
-
const truncatedRaw = truncateRawBody(rawBody);
|
|
9436
|
-
const isConnectorPassthrough = type === "connector" || code.startsWith("CE_");
|
|
9437
|
-
if (response.status === 401 && !isConnectorPassthrough) {
|
|
9438
|
-
throw new DelopayAuthenticationError(message, {
|
|
9439
|
-
code,
|
|
9440
|
-
type,
|
|
9441
|
-
requestId,
|
|
9442
|
-
rawBody: truncatedRaw,
|
|
9443
|
-
data
|
|
9444
|
-
});
|
|
9445
|
-
}
|
|
9446
|
-
const error = new DelopayError(message, {
|
|
9447
|
-
status: response.status,
|
|
9448
|
-
code,
|
|
9449
|
-
type,
|
|
9450
|
-
requestId,
|
|
9451
|
-
rawBody: truncatedRaw,
|
|
9452
|
-
data
|
|
9453
|
-
});
|
|
9982
|
+
const error = await errorFromResponse(response, requestId);
|
|
9454
9983
|
const isTransientStatus = response.status >= 500 || response.status === 429;
|
|
9455
9984
|
if (isTransientStatus && isRetryable && attempt < this.maxRetries) {
|
|
9456
9985
|
if (response.status === 429) {
|
|
@@ -10918,6 +11447,13 @@ var DEFAULT_BRANDING_BASE = {
|
|
|
10918
11447
|
paypalFocusRing: "strong",
|
|
10919
11448
|
mollieFocusRing: "strong",
|
|
10920
11449
|
paypalValidTint: false,
|
|
11450
|
+
epayoutsCardLayout: "split",
|
|
11451
|
+
epayoutsLabelStyle: "above",
|
|
11452
|
+
epayoutsFieldChrome: "outlined",
|
|
11453
|
+
epayoutsFieldFontSize: "md",
|
|
11454
|
+
epayoutsFieldWeight: "regular",
|
|
11455
|
+
epayoutsFocusRing: "strong",
|
|
11456
|
+
epayoutsValidTint: false,
|
|
10921
11457
|
nomupayFormStyle: "plain",
|
|
10922
11458
|
nomupayShowLabels: true,
|
|
10923
11459
|
nomupayShowPlaceholders: true,
|
|
@@ -11948,6 +12484,66 @@ function decodeBranding(source) {
|
|
|
11948
12484
|
DEFAULT_BRANDING.whopSelection
|
|
11949
12485
|
),
|
|
11950
12486
|
paypalValidTint: parseBool(extras["paypalValidTint"], DEFAULT_BRANDING.paypalValidTint),
|
|
12487
|
+
// A look stored before todos#412 has no e-Payouts keys: the form keeps
|
|
12488
|
+
// the PayPal values it was drawn with until then.
|
|
12489
|
+
epayoutsCardLayout: pickEnum(
|
|
12490
|
+
extras["epayoutsCardLayout"],
|
|
12491
|
+
PAYPAL_CARD_LAYOUTS,
|
|
12492
|
+
pickEnum(
|
|
12493
|
+
extras["paypalCardLayout"],
|
|
12494
|
+
PAYPAL_CARD_LAYOUTS,
|
|
12495
|
+
DEFAULT_BRANDING.epayoutsCardLayout
|
|
12496
|
+
)
|
|
12497
|
+
),
|
|
12498
|
+
epayoutsLabelStyle: pickEnum(
|
|
12499
|
+
extras["epayoutsLabelStyle"],
|
|
12500
|
+
PAYPAL_LABEL_STYLES,
|
|
12501
|
+
pickEnum(
|
|
12502
|
+
extras["paypalLabelStyle"],
|
|
12503
|
+
PAYPAL_LABEL_STYLES,
|
|
12504
|
+
DEFAULT_BRANDING.epayoutsLabelStyle
|
|
12505
|
+
)
|
|
12506
|
+
),
|
|
12507
|
+
epayoutsFieldChrome: pickEnum(
|
|
12508
|
+
extras["epayoutsFieldChrome"],
|
|
12509
|
+
CARD_FIELD_CHROMES,
|
|
12510
|
+
pickEnum(
|
|
12511
|
+
extras["paypalFieldChrome"],
|
|
12512
|
+
CARD_FIELD_CHROMES,
|
|
12513
|
+
DEFAULT_BRANDING.epayoutsFieldChrome
|
|
12514
|
+
)
|
|
12515
|
+
),
|
|
12516
|
+
epayoutsFieldFontSize: pickEnum(
|
|
12517
|
+
extras["epayoutsFieldFontSize"],
|
|
12518
|
+
CARD_FIELD_FONT_SIZES,
|
|
12519
|
+
pickEnum(
|
|
12520
|
+
extras["paypalFieldFontSize"],
|
|
12521
|
+
CARD_FIELD_FONT_SIZES,
|
|
12522
|
+
DEFAULT_BRANDING.epayoutsFieldFontSize
|
|
12523
|
+
)
|
|
12524
|
+
),
|
|
12525
|
+
epayoutsFieldWeight: pickEnum(
|
|
12526
|
+
extras["epayoutsFieldWeight"],
|
|
12527
|
+
CARD_FIELD_WEIGHTS,
|
|
12528
|
+
pickEnum(
|
|
12529
|
+
extras["paypalFieldWeight"],
|
|
12530
|
+
CARD_FIELD_WEIGHTS,
|
|
12531
|
+
DEFAULT_BRANDING.epayoutsFieldWeight
|
|
12532
|
+
)
|
|
12533
|
+
),
|
|
12534
|
+
epayoutsFocusRing: pickEnum(
|
|
12535
|
+
extras["epayoutsFocusRing"],
|
|
12536
|
+
CARD_FOCUS_RINGS,
|
|
12537
|
+
pickEnum(
|
|
12538
|
+
extras["paypalFocusRing"],
|
|
12539
|
+
CARD_FOCUS_RINGS,
|
|
12540
|
+
DEFAULT_BRANDING.epayoutsFocusRing
|
|
12541
|
+
)
|
|
12542
|
+
),
|
|
12543
|
+
epayoutsValidTint: parseBool(
|
|
12544
|
+
extras["epayoutsValidTint"],
|
|
12545
|
+
parseBool(extras["paypalValidTint"], DEFAULT_BRANDING.epayoutsValidTint)
|
|
12546
|
+
),
|
|
11951
12547
|
nomupayFormStyle: pickEnum(
|
|
11952
12548
|
extras["nomupayFormStyle"],
|
|
11953
12549
|
NOMUPAY_FORM_STYLES,
|
|
@@ -12109,6 +12705,13 @@ function encodeBranding(branding, base) {
|
|
|
12109
12705
|
whopMethodIcons: String(branding.whopMethodIcons),
|
|
12110
12706
|
whopSelection: branding.whopSelection,
|
|
12111
12707
|
paypalValidTint: String(branding.paypalValidTint),
|
|
12708
|
+
epayoutsCardLayout: branding.epayoutsCardLayout,
|
|
12709
|
+
epayoutsLabelStyle: branding.epayoutsLabelStyle,
|
|
12710
|
+
epayoutsFieldChrome: branding.epayoutsFieldChrome,
|
|
12711
|
+
epayoutsFieldFontSize: branding.epayoutsFieldFontSize,
|
|
12712
|
+
epayoutsFieldWeight: branding.epayoutsFieldWeight,
|
|
12713
|
+
epayoutsFocusRing: branding.epayoutsFocusRing,
|
|
12714
|
+
epayoutsValidTint: String(branding.epayoutsValidTint),
|
|
12112
12715
|
nomupayFormStyle: branding.nomupayFormStyle,
|
|
12113
12716
|
nomupayShowLabels: String(branding.nomupayShowLabels),
|
|
12114
12717
|
nomupayShowPlaceholders: String(branding.nomupayShowPlaceholders),
|
|
@@ -12570,6 +13173,62 @@ function parseImportedBranding(raw) {
|
|
|
12570
13173
|
dflt.whopSelection
|
|
12571
13174
|
),
|
|
12572
13175
|
paypalValidTint: parseBool(root["paypalValidTint"], dflt.paypalValidTint),
|
|
13176
|
+
// A look stored before todos#412 has no e-Payouts keys: the form keeps
|
|
13177
|
+
// the PayPal values it was drawn with until then.
|
|
13178
|
+
epayoutsCardLayout: pickEnum(
|
|
13179
|
+
root["epayoutsCardLayout"],
|
|
13180
|
+
PAYPAL_CARD_LAYOUTS,
|
|
13181
|
+
pickEnum(
|
|
13182
|
+
root["paypalCardLayout"],
|
|
13183
|
+
PAYPAL_CARD_LAYOUTS,
|
|
13184
|
+
dflt.epayoutsCardLayout
|
|
13185
|
+
)
|
|
13186
|
+
),
|
|
13187
|
+
epayoutsLabelStyle: pickEnum(
|
|
13188
|
+
root["epayoutsLabelStyle"],
|
|
13189
|
+
PAYPAL_LABEL_STYLES,
|
|
13190
|
+
pickEnum(
|
|
13191
|
+
root["paypalLabelStyle"],
|
|
13192
|
+
PAYPAL_LABEL_STYLES,
|
|
13193
|
+
dflt.epayoutsLabelStyle
|
|
13194
|
+
)
|
|
13195
|
+
),
|
|
13196
|
+
epayoutsFieldChrome: pickEnum(
|
|
13197
|
+
root["epayoutsFieldChrome"],
|
|
13198
|
+
CARD_FIELD_CHROMES,
|
|
13199
|
+
pickEnum(
|
|
13200
|
+
root["paypalFieldChrome"],
|
|
13201
|
+
CARD_FIELD_CHROMES,
|
|
13202
|
+
dflt.epayoutsFieldChrome
|
|
13203
|
+
)
|
|
13204
|
+
),
|
|
13205
|
+
epayoutsFieldFontSize: pickEnum(
|
|
13206
|
+
root["epayoutsFieldFontSize"],
|
|
13207
|
+
CARD_FIELD_FONT_SIZES,
|
|
13208
|
+
pickEnum(
|
|
13209
|
+
root["paypalFieldFontSize"],
|
|
13210
|
+
CARD_FIELD_FONT_SIZES,
|
|
13211
|
+
dflt.epayoutsFieldFontSize
|
|
13212
|
+
)
|
|
13213
|
+
),
|
|
13214
|
+
epayoutsFieldWeight: pickEnum(
|
|
13215
|
+
root["epayoutsFieldWeight"],
|
|
13216
|
+
CARD_FIELD_WEIGHTS,
|
|
13217
|
+
pickEnum(
|
|
13218
|
+
root["paypalFieldWeight"],
|
|
13219
|
+
CARD_FIELD_WEIGHTS,
|
|
13220
|
+
dflt.epayoutsFieldWeight
|
|
13221
|
+
)
|
|
13222
|
+
),
|
|
13223
|
+
epayoutsFocusRing: pickEnum(
|
|
13224
|
+
root["epayoutsFocusRing"],
|
|
13225
|
+
CARD_FOCUS_RINGS,
|
|
13226
|
+
pickEnum(root["paypalFocusRing"], CARD_FOCUS_RINGS, dflt.epayoutsFocusRing)
|
|
13227
|
+
),
|
|
13228
|
+
epayoutsValidTint: parseBool(
|
|
13229
|
+
root["epayoutsValidTint"],
|
|
13230
|
+
parseBool(root["paypalValidTint"], dflt.epayoutsValidTint)
|
|
13231
|
+
),
|
|
12573
13232
|
nomupayFormStyle: pickEnum(
|
|
12574
13233
|
root["nomupayFormStyle"],
|
|
12575
13234
|
NOMUPAY_FORM_STYLES,
|
|
@@ -14108,6 +14767,8 @@ var encodeNativePanes = encodePanes;
|
|
|
14108
14767
|
InvoiceSettingsResource,
|
|
14109
14768
|
Invoices,
|
|
14110
14769
|
LOCALIZABLE_COPY_FIELDS,
|
|
14770
|
+
Live,
|
|
14771
|
+
LiveEventStream,
|
|
14111
14772
|
MAX_SECTION_LABEL_LENGTH,
|
|
14112
14773
|
MAX_SECTION_ORDER,
|
|
14113
14774
|
METHOD_SECTIONS,
|