@delopay/sdk 0.165.0 → 0.167.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-CP5M5WR6.js → chunk-RWCROWXW.js} +491 -44
- package/dist/chunk-RWCROWXW.js.map +1 -0
- package/dist/index.cjs +489 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +283 -44
- package/dist/index.d.ts +283 -44
- package/dist/index.js +1 -1
- package/dist/internal.cjs +511 -54
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +77 -7
- package/dist/internal.d.ts +77 -7
- package/dist/internal.js +24 -12
- package/dist/internal.js.map +1 -1
- package/package.json +18 -17
- package/dist/chunk-CP5M5WR6.js.map +0 -1
package/dist/internal.cjs
CHANGED
|
@@ -1192,6 +1192,289 @@ var Customers = class {
|
|
|
1192
1192
|
}
|
|
1193
1193
|
};
|
|
1194
1194
|
|
|
1195
|
+
// src/recordCounter.ts
|
|
1196
|
+
var LF = 10;
|
|
1197
|
+
var CR = 13;
|
|
1198
|
+
var QUOTE = 34;
|
|
1199
|
+
var BACKSLASH = 92;
|
|
1200
|
+
var OPEN_BRACE = 123;
|
|
1201
|
+
var CLOSE_BRACE = 125;
|
|
1202
|
+
var OPEN_BRACKET = 91;
|
|
1203
|
+
var CLOSE_BRACKET = 93;
|
|
1204
|
+
var CsvRecordCounter = class {
|
|
1205
|
+
constructor() {
|
|
1206
|
+
this.inQuotes = false;
|
|
1207
|
+
this.newlines = 0;
|
|
1208
|
+
/** Whether anything but a line break has arrived since the last newline. */
|
|
1209
|
+
this.lineHasContent = false;
|
|
1210
|
+
}
|
|
1211
|
+
push(chunk) {
|
|
1212
|
+
let inQuotes = this.inQuotes;
|
|
1213
|
+
let newlines = this.newlines;
|
|
1214
|
+
let lineHasContent = this.lineHasContent;
|
|
1215
|
+
for (const byte of chunk) {
|
|
1216
|
+
if (byte === QUOTE) {
|
|
1217
|
+
inQuotes = !inQuotes;
|
|
1218
|
+
lineHasContent = true;
|
|
1219
|
+
} else if (inQuotes) {
|
|
1220
|
+
lineHasContent = true;
|
|
1221
|
+
} else if (byte === LF) {
|
|
1222
|
+
newlines++;
|
|
1223
|
+
lineHasContent = false;
|
|
1224
|
+
} else if (byte !== CR) {
|
|
1225
|
+
lineHasContent = true;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
this.inQuotes = inQuotes;
|
|
1229
|
+
this.newlines = newlines;
|
|
1230
|
+
this.lineHasContent = lineHasContent;
|
|
1231
|
+
}
|
|
1232
|
+
get records() {
|
|
1233
|
+
return Math.max(0, this.newlines - 1);
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* The export writer ends every line — the header and each record — with a
|
|
1237
|
+
* newline, so a whole body ends on one, outside quotes. RFC 4180 lets a
|
|
1238
|
+
* final line break be omitted, but these bodies never omit it, and without
|
|
1239
|
+
* that rule a file cut part-way through its last unquoted field
|
|
1240
|
+
* (`pay_1,12` of `pay_1,123`) would count as one more whole record and
|
|
1241
|
+
* match the figure it was announced with.
|
|
1242
|
+
*/
|
|
1243
|
+
get complete() {
|
|
1244
|
+
return this.newlines >= 1 && !this.inQuotes && !this.lineHasContent;
|
|
1245
|
+
}
|
|
1246
|
+
/**
|
|
1247
|
+
* The records that ended. An unterminated tail is not one of them — see
|
|
1248
|
+
* {@link complete}.
|
|
1249
|
+
*/
|
|
1250
|
+
finish() {
|
|
1251
|
+
return this.records;
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
var SEEKING = 0;
|
|
1255
|
+
var COUNTING = 1;
|
|
1256
|
+
var CLOSED = 2;
|
|
1257
|
+
var JsonArrayRecordCounter = class {
|
|
1258
|
+
constructor() {
|
|
1259
|
+
this.depth = 0;
|
|
1260
|
+
this.inString = false;
|
|
1261
|
+
this.escaped = false;
|
|
1262
|
+
this.topIsObject = false;
|
|
1263
|
+
this.state = SEEKING;
|
|
1264
|
+
this.count = 0;
|
|
1265
|
+
}
|
|
1266
|
+
push(chunk) {
|
|
1267
|
+
if (this.state === CLOSED) return;
|
|
1268
|
+
let { depth, inString, escaped, topIsObject, count } = this;
|
|
1269
|
+
let state = this.state;
|
|
1270
|
+
for (const byte of chunk) {
|
|
1271
|
+
if (inString) {
|
|
1272
|
+
if (escaped) escaped = false;
|
|
1273
|
+
else if (byte === BACKSLASH) escaped = true;
|
|
1274
|
+
else if (byte === QUOTE) inString = false;
|
|
1275
|
+
continue;
|
|
1276
|
+
}
|
|
1277
|
+
if (byte === QUOTE) {
|
|
1278
|
+
inString = true;
|
|
1279
|
+
} else if (byte === OPEN_BRACE || byte === OPEN_BRACKET) {
|
|
1280
|
+
if (depth === 0 && byte === OPEN_BRACE) topIsObject = true;
|
|
1281
|
+
if (byte === OPEN_BRACKET && depth === 1 && topIsObject && state === SEEKING) {
|
|
1282
|
+
state = COUNTING;
|
|
1283
|
+
}
|
|
1284
|
+
depth++;
|
|
1285
|
+
} else if (byte === CLOSE_BRACE || byte === CLOSE_BRACKET) {
|
|
1286
|
+
depth--;
|
|
1287
|
+
if (state === COUNTING) {
|
|
1288
|
+
if (depth === 2) count++;
|
|
1289
|
+
else if (depth === 1) {
|
|
1290
|
+
state = CLOSED;
|
|
1291
|
+
break;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
this.depth = depth;
|
|
1297
|
+
this.inString = inString;
|
|
1298
|
+
this.escaped = escaped;
|
|
1299
|
+
this.topIsObject = topIsObject;
|
|
1300
|
+
this.state = state;
|
|
1301
|
+
this.count = count;
|
|
1302
|
+
}
|
|
1303
|
+
get records() {
|
|
1304
|
+
return this.count;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Whether the rows array has closed. What follows it is checked by parsing
|
|
1308
|
+
* the whole document, which a cut-off body fails.
|
|
1309
|
+
*/
|
|
1310
|
+
get complete() {
|
|
1311
|
+
return this.state === CLOSED;
|
|
1312
|
+
}
|
|
1313
|
+
finish() {
|
|
1314
|
+
return this.count;
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
// src/exportDownload.ts
|
|
1319
|
+
var RECORD_COUNT_HEADER = "x-delopay-record-count";
|
|
1320
|
+
var LIST_ENVELOPE = { rows: "records", count: "record_count" };
|
|
1321
|
+
var WORKSPACE_ENVELOPE = { rows: "data", count: "total_count" };
|
|
1322
|
+
function parseRecordCount(header) {
|
|
1323
|
+
if (header === null) return null;
|
|
1324
|
+
const trimmed = header.trim();
|
|
1325
|
+
if (!/^\d+$/.test(trimmed)) return null;
|
|
1326
|
+
const value = Number(trimmed);
|
|
1327
|
+
return Number.isSafeInteger(value) ? value : null;
|
|
1328
|
+
}
|
|
1329
|
+
function counterFor(format) {
|
|
1330
|
+
if (format === "csv") return new CsvRecordCounter();
|
|
1331
|
+
if (format === "json") return new JsonArrayRecordCounter();
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
function isRecord(value) {
|
|
1335
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1336
|
+
}
|
|
1337
|
+
function announced(expected) {
|
|
1338
|
+
return expected === null ? "" : ` of the ${expected} announced`;
|
|
1339
|
+
}
|
|
1340
|
+
function incomplete(message, expected, received, requestId) {
|
|
1341
|
+
return new DelopayError(message, {
|
|
1342
|
+
status: 0,
|
|
1343
|
+
code: "EXPORT_INCOMPLETE",
|
|
1344
|
+
type: "export_incomplete",
|
|
1345
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
1346
|
+
data: { expected_records: expected, received_records: received }
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
async function downloadExport(request, call, options) {
|
|
1350
|
+
const { format } = call;
|
|
1351
|
+
const envelope = call.envelope ?? LIST_ENVELOPE;
|
|
1352
|
+
const onProgress = options?.onProgress;
|
|
1353
|
+
let latest = {
|
|
1354
|
+
phase: "preparing",
|
|
1355
|
+
receivedBytes: 0,
|
|
1356
|
+
totalBytes: null,
|
|
1357
|
+
receivedRecords: 0,
|
|
1358
|
+
expectedRecords: null
|
|
1359
|
+
};
|
|
1360
|
+
const seen = { attempt: -1, counter: null, expected: null, requestId: void 0, listenerError: null };
|
|
1361
|
+
const report = (progress) => {
|
|
1362
|
+
latest = progress;
|
|
1363
|
+
if (!onProgress) return;
|
|
1364
|
+
try {
|
|
1365
|
+
onProgress({ ...progress });
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
seen.listenerError = { error };
|
|
1368
|
+
throw error;
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
report(latest);
|
|
1372
|
+
const onDownloadProgress = (event) => {
|
|
1373
|
+
if (event.attempt !== seen.attempt) {
|
|
1374
|
+
seen.attempt = event.attempt;
|
|
1375
|
+
seen.counter = counterFor(format);
|
|
1376
|
+
seen.expected = format === "pdf" ? null : parseRecordCount(event.headers.get(RECORD_COUNT_HEADER));
|
|
1377
|
+
seen.requestId = event.headers.get("x-request-id") ?? event.headers.get("x-trace-id") ?? void 0;
|
|
1378
|
+
}
|
|
1379
|
+
if (event.chunk.byteLength > 0) seen.counter?.push(event.chunk);
|
|
1380
|
+
report({
|
|
1381
|
+
phase: "receiving",
|
|
1382
|
+
receivedBytes: event.loaded,
|
|
1383
|
+
totalBytes: event.total,
|
|
1384
|
+
receivedRecords: seen.counter?.records ?? 0,
|
|
1385
|
+
expectedRecords: seen.expected
|
|
1386
|
+
});
|
|
1387
|
+
};
|
|
1388
|
+
let result;
|
|
1389
|
+
try {
|
|
1390
|
+
result = await request(call.method, call.path, {
|
|
1391
|
+
...call.request,
|
|
1392
|
+
...options?.signal !== void 0 ? { signal: options.signal } : {},
|
|
1393
|
+
...options?.timeout !== void 0 ? { timeout: options.timeout } : {},
|
|
1394
|
+
onDownloadProgress
|
|
1395
|
+
});
|
|
1396
|
+
} catch (err) {
|
|
1397
|
+
if (seen.listenerError !== null && err === seen.listenerError.error) throw err;
|
|
1398
|
+
if (format === "json" && seen.attempt >= 0 && err instanceof SyntaxError) {
|
|
1399
|
+
const received2 = seen.counter?.records ?? 0;
|
|
1400
|
+
throw incomplete(
|
|
1401
|
+
seen.expected === null ? `Export incomplete: the body ended part-way through the JSON document, after ${received2} records` : `Export incomplete: the server announced ${seen.expected} records, and the body ended part-way through the JSON document after ${received2}`,
|
|
1402
|
+
seen.expected,
|
|
1403
|
+
received2,
|
|
1404
|
+
seen.requestId
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
throw err;
|
|
1408
|
+
}
|
|
1409
|
+
const { expected, requestId } = seen;
|
|
1410
|
+
let received = 0;
|
|
1411
|
+
if (format === "json") {
|
|
1412
|
+
const rows = isRecord(result) ? result[envelope.rows] : void 0;
|
|
1413
|
+
if (!Array.isArray(rows)) {
|
|
1414
|
+
throw incomplete(
|
|
1415
|
+
`Export incomplete: the body is not an export envelope with a "${envelope.rows}" array, so it carries 0 records${announced(expected)}`,
|
|
1416
|
+
expected,
|
|
1417
|
+
0,
|
|
1418
|
+
requestId
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
received = rows.length;
|
|
1422
|
+
const declared = isRecord(result) ? result[envelope.count] : void 0;
|
|
1423
|
+
if (typeof declared === "number" && declared !== rows.length) {
|
|
1424
|
+
throw incomplete(
|
|
1425
|
+
`Export incomplete: the file's ${envelope.count} is ${declared}, but it carries ${rows.length} records`,
|
|
1426
|
+
declared,
|
|
1427
|
+
rows.length,
|
|
1428
|
+
requestId
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
} else if (format === "csv") {
|
|
1432
|
+
const counter = seen.counter;
|
|
1433
|
+
received = counter?.finish() ?? 0;
|
|
1434
|
+
if (!counter?.complete) {
|
|
1435
|
+
throw incomplete(
|
|
1436
|
+
`Export incomplete: the CSV body ended part-way through a line, after ${received} complete records${announced(expected)}`,
|
|
1437
|
+
expected,
|
|
1438
|
+
received,
|
|
1439
|
+
requestId
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
if (expected !== null && received !== expected) {
|
|
1444
|
+
throw incomplete(
|
|
1445
|
+
`Export incomplete: the server announced ${expected} records, and the body carried ${received}`,
|
|
1446
|
+
expected,
|
|
1447
|
+
received,
|
|
1448
|
+
requestId
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
report({
|
|
1452
|
+
phase: "done",
|
|
1453
|
+
receivedBytes: latest.receivedBytes,
|
|
1454
|
+
totalBytes: latest.totalBytes,
|
|
1455
|
+
receivedRecords: received,
|
|
1456
|
+
expectedRecords: expected
|
|
1457
|
+
});
|
|
1458
|
+
return result;
|
|
1459
|
+
}
|
|
1460
|
+
var ACCEPT = {
|
|
1461
|
+
csv: "text/csv",
|
|
1462
|
+
json: "application/json",
|
|
1463
|
+
pdf: "application/pdf"
|
|
1464
|
+
};
|
|
1465
|
+
function negotiated(options, format) {
|
|
1466
|
+
const headers = { ...options.headers, Accept: ACCEPT[format] };
|
|
1467
|
+
return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
|
|
1468
|
+
}
|
|
1469
|
+
function runExport(request, method, path, base, options) {
|
|
1470
|
+
const format = options?.format ?? "json";
|
|
1471
|
+
return downloadExport(
|
|
1472
|
+
request,
|
|
1473
|
+
{ method, path, request: negotiated(base, format), format },
|
|
1474
|
+
options
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1195
1478
|
// src/resources/disputes.ts
|
|
1196
1479
|
function workspaceQuery(params) {
|
|
1197
1480
|
if (!params) return void 0;
|
|
@@ -1220,9 +1503,28 @@ var Disputes = class {
|
|
|
1220
1503
|
async workspaceAggregate(params) {
|
|
1221
1504
|
return this.request("GET", "/disputes/workspace/aggregate", { query: workspaceQuery(params) });
|
|
1222
1505
|
}
|
|
1223
|
-
/**
|
|
1224
|
-
|
|
1225
|
-
|
|
1506
|
+
/**
|
|
1507
|
+
* Export the complete filtered set, or throw on the server's explicit
|
|
1508
|
+
* export-limit refusal. `GET /disputes/workspace/export`
|
|
1509
|
+
*
|
|
1510
|
+
* The body is streamed, and held to the `X-Delopay-Record-Count` the server
|
|
1511
|
+
* announces and to its own `total_count`: a set that arrives short rejects
|
|
1512
|
+
* with `EXPORT_INCOMPLETE` rather than resolving. `options` reports the
|
|
1513
|
+
* download's progress and takes a signal and an idle timeout — see
|
|
1514
|
+
* {@link ExportTransferOptions}.
|
|
1515
|
+
*/
|
|
1516
|
+
async workspaceExport(params, options) {
|
|
1517
|
+
return downloadExport(
|
|
1518
|
+
this.request,
|
|
1519
|
+
{
|
|
1520
|
+
method: "GET",
|
|
1521
|
+
path: "/disputes/workspace/export",
|
|
1522
|
+
request: { query: workspaceQuery(params) },
|
|
1523
|
+
format: "json",
|
|
1524
|
+
envelope: WORKSPACE_ENVELOPE
|
|
1525
|
+
},
|
|
1526
|
+
options
|
|
1527
|
+
);
|
|
1226
1528
|
}
|
|
1227
1529
|
/**
|
|
1228
1530
|
* Retrieve a dispute by its ID.
|
|
@@ -4379,77 +4681,68 @@ var Export = class {
|
|
|
4379
4681
|
this.request = request;
|
|
4380
4682
|
}
|
|
4381
4683
|
async transactions(params, options) {
|
|
4382
|
-
return this.request
|
|
4383
|
-
"POST",
|
|
4384
|
-
"/export/transactions",
|
|
4385
|
-
transactionBody(params, options)
|
|
4386
|
-
);
|
|
4684
|
+
return runExport(this.request, "POST", "/export/transactions", { body: params ?? {} }, options);
|
|
4387
4685
|
}
|
|
4388
4686
|
async transactionsForProfile(params, options) {
|
|
4389
|
-
return
|
|
4687
|
+
return runExport(
|
|
4688
|
+
this.request,
|
|
4390
4689
|
"POST",
|
|
4391
4690
|
"/export/profile/transactions",
|
|
4392
|
-
|
|
4691
|
+
{ body: params ?? {} },
|
|
4692
|
+
options
|
|
4393
4693
|
);
|
|
4394
4694
|
}
|
|
4395
4695
|
async refunds(params, options) {
|
|
4396
|
-
return this.request
|
|
4696
|
+
return runExport(this.request, "POST", "/refunds/list/export", { body: params ?? {} }, options);
|
|
4397
4697
|
}
|
|
4398
4698
|
async refundsForProfile(params, options) {
|
|
4399
|
-
return
|
|
4699
|
+
return runExport(
|
|
4700
|
+
this.request,
|
|
4400
4701
|
"POST",
|
|
4401
4702
|
"/refunds/profile/list/export",
|
|
4402
|
-
|
|
4703
|
+
{ body: params ?? {} },
|
|
4704
|
+
options
|
|
4403
4705
|
);
|
|
4404
4706
|
}
|
|
4405
4707
|
async disputes(params, options) {
|
|
4406
|
-
return this.request
|
|
4708
|
+
return runExport(this.request, "GET", "/disputes/list/export", queried(params), options);
|
|
4407
4709
|
}
|
|
4408
4710
|
async disputesForProfile(params, options) {
|
|
4409
|
-
return
|
|
4711
|
+
return runExport(
|
|
4712
|
+
this.request,
|
|
4410
4713
|
"GET",
|
|
4411
4714
|
"/disputes/profile/list/export",
|
|
4412
|
-
queried(params,
|
|
4715
|
+
queried(params),
|
|
4716
|
+
options
|
|
4413
4717
|
);
|
|
4414
4718
|
}
|
|
4415
4719
|
async payouts(params, options) {
|
|
4416
|
-
return this.request
|
|
4720
|
+
return runExport(this.request, "POST", "/payouts/list/export", { body: params }, options);
|
|
4417
4721
|
}
|
|
4418
4722
|
async payoutsForProfile(params, options) {
|
|
4419
|
-
return
|
|
4723
|
+
return runExport(
|
|
4724
|
+
this.request,
|
|
4725
|
+
"POST",
|
|
4726
|
+
"/payouts/profile/list/export",
|
|
4727
|
+
{ body: params },
|
|
4728
|
+
options
|
|
4729
|
+
);
|
|
4420
4730
|
}
|
|
4421
4731
|
async subscriptions(profileId, params, options) {
|
|
4422
|
-
return
|
|
4732
|
+
return runExport(
|
|
4733
|
+
this.request,
|
|
4423
4734
|
"GET",
|
|
4424
4735
|
"/subscriptions/list/export",
|
|
4425
|
-
queried(params,
|
|
4736
|
+
queried(params, { "X-Profile-Id": profileId }),
|
|
4737
|
+
options
|
|
4426
4738
|
);
|
|
4427
4739
|
}
|
|
4428
4740
|
async auditLog(params, options) {
|
|
4429
|
-
return this.request
|
|
4741
|
+
return runExport(this.request, "GET", "/audit/export", queried(params), options);
|
|
4430
4742
|
}
|
|
4431
4743
|
};
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
json: "application/json",
|
|
4435
|
-
pdf: "application/pdf"
|
|
4436
|
-
};
|
|
4437
|
-
function negotiated(options, format) {
|
|
4438
|
-
const headers = { ...options.headers, Accept: ACCEPT[format] };
|
|
4439
|
-
return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
|
|
4440
|
-
}
|
|
4441
|
-
function transactionBody(params, options) {
|
|
4442
|
-
const format = options?.format ?? "json";
|
|
4443
|
-
return negotiated({ body: { ...params, format } }, format);
|
|
4444
|
-
}
|
|
4445
|
-
function bodied(body, options) {
|
|
4446
|
-
return negotiated({ body }, options?.format ?? "json");
|
|
4447
|
-
}
|
|
4448
|
-
function queried(params, options, headers) {
|
|
4449
|
-
return negotiated(
|
|
4450
|
-
{ query: params ?? {}, ...headers ? { headers } : {} },
|
|
4451
|
-
options?.format ?? "json"
|
|
4452
|
-
);
|
|
4744
|
+
function queried(params, headers) {
|
|
4745
|
+
return { query: params ?? {}, ...headers ? { headers } : {} };
|
|
4453
4746
|
}
|
|
4454
4747
|
|
|
4455
4748
|
// src/resources/featureMatrix.ts
|
|
@@ -4733,6 +5026,24 @@ var ExternalRecords = class {
|
|
|
4733
5026
|
async create(params) {
|
|
4734
5027
|
return this.request("POST", "/external-records", { body: params });
|
|
4735
5028
|
}
|
|
5029
|
+
/**
|
|
5030
|
+
* What this deployment will accept, per kind.
|
|
5031
|
+
* `GET /external-records/capabilities`
|
|
5032
|
+
*
|
|
5033
|
+
* Read it before offering the operator a form. Every kind is listed, so an
|
|
5034
|
+
* entry that is not served is distinguishable from a kind this release does
|
|
5035
|
+
* not know at all — and `create` says *why* it is not served: a gap
|
|
5036
|
+
* (`not_implemented`) or a rule (`not_applicable`). Treating those as the
|
|
5037
|
+
* same thing is how a caller ends up waiting for something that will never
|
|
5038
|
+
* be built.
|
|
5039
|
+
*
|
|
5040
|
+
* The answer describes the binary rather than anything a merchant owns, so
|
|
5041
|
+
* it is the same for every caller of one deployment and is safe to cache for
|
|
5042
|
+
* the life of a dashboard session.
|
|
5043
|
+
*/
|
|
5044
|
+
async capabilities() {
|
|
5045
|
+
return this.request("GET", "/external-records/capabilities");
|
|
5046
|
+
}
|
|
4736
5047
|
};
|
|
4737
5048
|
|
|
4738
5049
|
// src/resources/products.ts
|
|
@@ -5822,6 +6133,112 @@ function findIdempotencyKey(headers) {
|
|
|
5822
6133
|
}
|
|
5823
6134
|
function noop() {
|
|
5824
6135
|
}
|
|
6136
|
+
var ListenerFailure = class {
|
|
6137
|
+
constructor(cause) {
|
|
6138
|
+
this.cause = cause;
|
|
6139
|
+
}
|
|
6140
|
+
};
|
|
6141
|
+
var BodyStreamFailure = class {
|
|
6142
|
+
constructor(cause) {
|
|
6143
|
+
this.cause = cause;
|
|
6144
|
+
}
|
|
6145
|
+
};
|
|
6146
|
+
function abortError() {
|
|
6147
|
+
const error = new Error("The operation was aborted");
|
|
6148
|
+
error.name = "AbortError";
|
|
6149
|
+
return error;
|
|
6150
|
+
}
|
|
6151
|
+
function parseContentLength(header) {
|
|
6152
|
+
if (header === null || !/^\s*\d+\s*$/.test(header)) return null;
|
|
6153
|
+
const value = Number(header);
|
|
6154
|
+
return Number.isSafeInteger(value) ? value : null;
|
|
6155
|
+
}
|
|
6156
|
+
function readChunk(reader, signal) {
|
|
6157
|
+
if (signal.aborted) return Promise.reject(abortError());
|
|
6158
|
+
return new Promise((resolve, reject) => {
|
|
6159
|
+
const onAbort = () => reject(abortError());
|
|
6160
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6161
|
+
reader.read().then(
|
|
6162
|
+
(result) => {
|
|
6163
|
+
signal.removeEventListener("abort", onAbort);
|
|
6164
|
+
resolve(result);
|
|
6165
|
+
},
|
|
6166
|
+
(cause) => {
|
|
6167
|
+
signal.removeEventListener("abort", onAbort);
|
|
6168
|
+
reject(signal.aborted ? abortError() : new BodyStreamFailure(cause));
|
|
6169
|
+
}
|
|
6170
|
+
);
|
|
6171
|
+
});
|
|
6172
|
+
}
|
|
6173
|
+
function concatChunks(chunks, length) {
|
|
6174
|
+
const out = new Uint8Array(length);
|
|
6175
|
+
let offset = 0;
|
|
6176
|
+
for (const chunk of chunks) {
|
|
6177
|
+
out.set(chunk, offset);
|
|
6178
|
+
offset += chunk.byteLength;
|
|
6179
|
+
}
|
|
6180
|
+
return out.buffer;
|
|
6181
|
+
}
|
|
6182
|
+
async function receiveWithProgress(response, responseType, listener, attempt, signal, onActivity) {
|
|
6183
|
+
const headers = response.headers ?? new Headers();
|
|
6184
|
+
const total = parseContentLength(headers.get("content-length"));
|
|
6185
|
+
let loaded = 0;
|
|
6186
|
+
const notify = (chunk) => {
|
|
6187
|
+
try {
|
|
6188
|
+
listener({ loaded, total, chunk: chunk.slice(), headers, attempt });
|
|
6189
|
+
} catch (cause) {
|
|
6190
|
+
throw new ListenerFailure(cause);
|
|
6191
|
+
}
|
|
6192
|
+
};
|
|
6193
|
+
onActivity();
|
|
6194
|
+
notify(new Uint8Array(0));
|
|
6195
|
+
const body = response.body;
|
|
6196
|
+
if (!body || typeof body.getReader !== "function") {
|
|
6197
|
+
if (responseType === "blob") {
|
|
6198
|
+
const blob = await response.blob();
|
|
6199
|
+
const bytes3 = new Uint8Array(await blob.arrayBuffer());
|
|
6200
|
+
loaded = bytes3.byteLength;
|
|
6201
|
+
if (loaded > 0) notify(bytes3);
|
|
6202
|
+
return blob;
|
|
6203
|
+
}
|
|
6204
|
+
if (responseType === "arraybuffer") {
|
|
6205
|
+
const buffer = await response.arrayBuffer();
|
|
6206
|
+
loaded = buffer.byteLength;
|
|
6207
|
+
if (loaded > 0) notify(new Uint8Array(buffer));
|
|
6208
|
+
return buffer;
|
|
6209
|
+
}
|
|
6210
|
+
const text2 = await response.text();
|
|
6211
|
+
const bytes2 = new TextEncoder().encode(text2);
|
|
6212
|
+
loaded = bytes2.byteLength;
|
|
6213
|
+
if (loaded > 0) notify(bytes2);
|
|
6214
|
+
return text2 ? JSON.parse(text2) : void 0;
|
|
6215
|
+
}
|
|
6216
|
+
const reader = body.getReader();
|
|
6217
|
+
const chunks = [];
|
|
6218
|
+
try {
|
|
6219
|
+
for (; ; ) {
|
|
6220
|
+
const { done, value } = await readChunk(reader, signal);
|
|
6221
|
+
if (done) break;
|
|
6222
|
+
if (!value || value.byteLength === 0) continue;
|
|
6223
|
+
chunks.push(value);
|
|
6224
|
+
loaded += value.byteLength;
|
|
6225
|
+
onActivity();
|
|
6226
|
+
notify(value);
|
|
6227
|
+
}
|
|
6228
|
+
} catch (err) {
|
|
6229
|
+
reader.cancel().catch(noop);
|
|
6230
|
+
throw err;
|
|
6231
|
+
}
|
|
6232
|
+
const bytes = concatChunks(chunks, loaded);
|
|
6233
|
+
if (responseType === "blob") {
|
|
6234
|
+
return new Blob([bytes], { type: headers.get("content-type") ?? "" });
|
|
6235
|
+
}
|
|
6236
|
+
if (responseType === "arraybuffer") {
|
|
6237
|
+
return bytes;
|
|
6238
|
+
}
|
|
6239
|
+
const text = new TextDecoder().decode(bytes);
|
|
6240
|
+
return text ? JSON.parse(text) : void 0;
|
|
6241
|
+
}
|
|
5825
6242
|
function combineSignals(signals) {
|
|
5826
6243
|
const controller = new AbortController();
|
|
5827
6244
|
const listeners = [];
|
|
@@ -6103,7 +6520,12 @@ var Delopay = class {
|
|
|
6103
6520
|
emit("retry", { attempt, maxRetries: this.maxRetries, method, path });
|
|
6104
6521
|
}
|
|
6105
6522
|
const timeoutCtrl = new AbortController();
|
|
6106
|
-
|
|
6523
|
+
let timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
|
|
6524
|
+
const restartIdleTimer = () => {
|
|
6525
|
+
if (timeoutCtrl.signal.aborted) return;
|
|
6526
|
+
clearTimeout(timeoutId);
|
|
6527
|
+
timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
|
|
6528
|
+
};
|
|
6107
6529
|
const combined = combineSignals(
|
|
6108
6530
|
callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal]
|
|
6109
6531
|
);
|
|
@@ -6161,6 +6583,16 @@ var Delopay = class {
|
|
|
6161
6583
|
}
|
|
6162
6584
|
throw error;
|
|
6163
6585
|
}
|
|
6586
|
+
if (options?.onDownloadProgress) {
|
|
6587
|
+
return await receiveWithProgress(
|
|
6588
|
+
response,
|
|
6589
|
+
options.responseType,
|
|
6590
|
+
options.onDownloadProgress,
|
|
6591
|
+
attempt,
|
|
6592
|
+
combined.signal,
|
|
6593
|
+
restartIdleTimer
|
|
6594
|
+
);
|
|
6595
|
+
}
|
|
6164
6596
|
if (options?.responseType === "blob") {
|
|
6165
6597
|
return await response.blob();
|
|
6166
6598
|
}
|
|
@@ -6173,6 +6605,20 @@ var Delopay = class {
|
|
|
6173
6605
|
if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {
|
|
6174
6606
|
throw err;
|
|
6175
6607
|
}
|
|
6608
|
+
if (err instanceof ListenerFailure) {
|
|
6609
|
+
throw err.cause;
|
|
6610
|
+
}
|
|
6611
|
+
if (err instanceof BodyStreamFailure) {
|
|
6612
|
+
const cause = err.cause;
|
|
6613
|
+
const detail = cause instanceof Error ? cause.message : String(cause ?? "body stream failed");
|
|
6614
|
+
lastError = new DelopayError(`Network error: ${detail}`, {
|
|
6615
|
+
status: 0,
|
|
6616
|
+
code: "NETWORK",
|
|
6617
|
+
type: "network_error"
|
|
6618
|
+
});
|
|
6619
|
+
if (isRetryable && attempt < this.maxRetries) continue;
|
|
6620
|
+
throw lastError;
|
|
6621
|
+
}
|
|
6176
6622
|
if (err instanceof Error && err.name === "AbortError") {
|
|
6177
6623
|
if (callerSignal?.aborted) {
|
|
6178
6624
|
throw new DelopayError("Request aborted", {
|
|
@@ -9820,6 +10266,15 @@ var AdminPortal = class {
|
|
|
9820
10266
|
query
|
|
9821
10267
|
});
|
|
9822
10268
|
}
|
|
10269
|
+
async exportTransactions(params, options) {
|
|
10270
|
+
return runExport(
|
|
10271
|
+
this.request,
|
|
10272
|
+
"GET",
|
|
10273
|
+
"/admin-portal/transactions/export",
|
|
10274
|
+
{ query: transactionListQuery(params) },
|
|
10275
|
+
options
|
|
10276
|
+
);
|
|
10277
|
+
}
|
|
9823
10278
|
/**
|
|
9824
10279
|
* Full detail for a single transaction of ANY merchant — the same
|
|
9825
10280
|
* `PaymentResponse` the merchant `payments.retrieve` returns. Admin-scoped:
|
|
@@ -10418,11 +10873,13 @@ var AdminPortal = class {
|
|
|
10418
10873
|
}
|
|
10419
10874
|
/**
|
|
10420
10875
|
* Export a settlement statement as PDF. Returns the raw bytes as a `Blob`
|
|
10421
|
-
* with the same auth and error handling as every other call.
|
|
10876
|
+
* with the same auth and error handling as every other call. `options`
|
|
10877
|
+
* takes a signal, a timeout and an `onDownloadProgress` listener for the
|
|
10878
|
+
* download's bytes (the PDF carries a `Content-Length`, so `total` is set).
|
|
10422
10879
|
*
|
|
10423
10880
|
* `GET /admin-portal/accounts/{merchantId}/settlement/statements/{statementId}/pdf`
|
|
10424
10881
|
*/
|
|
10425
|
-
async downloadSettlementStatementPdf(merchantId, statementId, params) {
|
|
10882
|
+
async downloadSettlementStatementPdf(merchantId, statementId, params, options) {
|
|
10426
10883
|
return this.request(
|
|
10427
10884
|
"GET",
|
|
10428
10885
|
`/admin-portal/accounts/${encodeURIComponent(merchantId)}/settlement/statements/${encodeURIComponent(statementId)}/pdf`,
|
|
@@ -10431,7 +10888,8 @@ var AdminPortal = class {
|
|
|
10431
10888
|
currency: params?.currency,
|
|
10432
10889
|
include_transactions: params?.include_transactions
|
|
10433
10890
|
},
|
|
10434
|
-
responseType: "blob"
|
|
10891
|
+
responseType: "blob",
|
|
10892
|
+
...options
|
|
10435
10893
|
}
|
|
10436
10894
|
);
|
|
10437
10895
|
}
|
|
@@ -10536,17 +10994,16 @@ var AuditLogs = class {
|
|
|
10536
10994
|
return this.request("GET", `/admin-portal/audit/${encodeURIComponent(logId)}`);
|
|
10537
10995
|
}
|
|
10538
10996
|
async export(params, options) {
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10997
|
+
return runExport(
|
|
10998
|
+
this.request,
|
|
10999
|
+
"GET",
|
|
11000
|
+
"/admin-portal/audit/export",
|
|
10543
11001
|
// The format is negotiated by `Accept`, never a query field: the query
|
|
10544
11002
|
// here is the list's own filter model, and adding a key to it would fork
|
|
10545
11003
|
// the filter vocabulary the export exists to reuse.
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
return this.request("GET", "/admin-portal/audit/export", request);
|
|
11004
|
+
{ query: params },
|
|
11005
|
+
options
|
|
11006
|
+
);
|
|
10550
11007
|
}
|
|
10551
11008
|
};
|
|
10552
11009
|
|