@delopay/sdk 0.164.0 → 0.166.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-GCJDY4KX.js → chunk-W57MOHOE.js} +740 -50
- package/dist/chunk-W57MOHOE.js.map +1 -0
- package/dist/index.cjs +756 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +349 -44
- package/dist/index.d.ts +349 -44
- package/dist/index.js +37 -1
- package/dist/internal.cjs +778 -60
- 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 +60 -12
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GCJDY4KX.js.map +0 -1
|
@@ -938,6 +938,289 @@ var Customers = class {
|
|
|
938
938
|
}
|
|
939
939
|
};
|
|
940
940
|
|
|
941
|
+
// src/recordCounter.ts
|
|
942
|
+
var LF = 10;
|
|
943
|
+
var CR = 13;
|
|
944
|
+
var QUOTE = 34;
|
|
945
|
+
var BACKSLASH = 92;
|
|
946
|
+
var OPEN_BRACE = 123;
|
|
947
|
+
var CLOSE_BRACE = 125;
|
|
948
|
+
var OPEN_BRACKET = 91;
|
|
949
|
+
var CLOSE_BRACKET = 93;
|
|
950
|
+
var CsvRecordCounter = class {
|
|
951
|
+
constructor() {
|
|
952
|
+
this.inQuotes = false;
|
|
953
|
+
this.newlines = 0;
|
|
954
|
+
/** Whether anything but a line break has arrived since the last newline. */
|
|
955
|
+
this.lineHasContent = false;
|
|
956
|
+
}
|
|
957
|
+
push(chunk) {
|
|
958
|
+
let inQuotes = this.inQuotes;
|
|
959
|
+
let newlines = this.newlines;
|
|
960
|
+
let lineHasContent = this.lineHasContent;
|
|
961
|
+
for (const byte of chunk) {
|
|
962
|
+
if (byte === QUOTE) {
|
|
963
|
+
inQuotes = !inQuotes;
|
|
964
|
+
lineHasContent = true;
|
|
965
|
+
} else if (inQuotes) {
|
|
966
|
+
lineHasContent = true;
|
|
967
|
+
} else if (byte === LF) {
|
|
968
|
+
newlines++;
|
|
969
|
+
lineHasContent = false;
|
|
970
|
+
} else if (byte !== CR) {
|
|
971
|
+
lineHasContent = true;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
this.inQuotes = inQuotes;
|
|
975
|
+
this.newlines = newlines;
|
|
976
|
+
this.lineHasContent = lineHasContent;
|
|
977
|
+
}
|
|
978
|
+
get records() {
|
|
979
|
+
return Math.max(0, this.newlines - 1);
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* The export writer ends every line — the header and each record — with a
|
|
983
|
+
* newline, so a whole body ends on one, outside quotes. RFC 4180 lets a
|
|
984
|
+
* final line break be omitted, but these bodies never omit it, and without
|
|
985
|
+
* that rule a file cut part-way through its last unquoted field
|
|
986
|
+
* (`pay_1,12` of `pay_1,123`) would count as one more whole record and
|
|
987
|
+
* match the figure it was announced with.
|
|
988
|
+
*/
|
|
989
|
+
get complete() {
|
|
990
|
+
return this.newlines >= 1 && !this.inQuotes && !this.lineHasContent;
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* The records that ended. An unterminated tail is not one of them — see
|
|
994
|
+
* {@link complete}.
|
|
995
|
+
*/
|
|
996
|
+
finish() {
|
|
997
|
+
return this.records;
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
var SEEKING = 0;
|
|
1001
|
+
var COUNTING = 1;
|
|
1002
|
+
var CLOSED = 2;
|
|
1003
|
+
var JsonArrayRecordCounter = class {
|
|
1004
|
+
constructor() {
|
|
1005
|
+
this.depth = 0;
|
|
1006
|
+
this.inString = false;
|
|
1007
|
+
this.escaped = false;
|
|
1008
|
+
this.topIsObject = false;
|
|
1009
|
+
this.state = SEEKING;
|
|
1010
|
+
this.count = 0;
|
|
1011
|
+
}
|
|
1012
|
+
push(chunk) {
|
|
1013
|
+
if (this.state === CLOSED) return;
|
|
1014
|
+
let { depth, inString, escaped, topIsObject, count } = this;
|
|
1015
|
+
let state = this.state;
|
|
1016
|
+
for (const byte of chunk) {
|
|
1017
|
+
if (inString) {
|
|
1018
|
+
if (escaped) escaped = false;
|
|
1019
|
+
else if (byte === BACKSLASH) escaped = true;
|
|
1020
|
+
else if (byte === QUOTE) inString = false;
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
if (byte === QUOTE) {
|
|
1024
|
+
inString = true;
|
|
1025
|
+
} else if (byte === OPEN_BRACE || byte === OPEN_BRACKET) {
|
|
1026
|
+
if (depth === 0 && byte === OPEN_BRACE) topIsObject = true;
|
|
1027
|
+
if (byte === OPEN_BRACKET && depth === 1 && topIsObject && state === SEEKING) {
|
|
1028
|
+
state = COUNTING;
|
|
1029
|
+
}
|
|
1030
|
+
depth++;
|
|
1031
|
+
} else if (byte === CLOSE_BRACE || byte === CLOSE_BRACKET) {
|
|
1032
|
+
depth--;
|
|
1033
|
+
if (state === COUNTING) {
|
|
1034
|
+
if (depth === 2) count++;
|
|
1035
|
+
else if (depth === 1) {
|
|
1036
|
+
state = CLOSED;
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
this.depth = depth;
|
|
1043
|
+
this.inString = inString;
|
|
1044
|
+
this.escaped = escaped;
|
|
1045
|
+
this.topIsObject = topIsObject;
|
|
1046
|
+
this.state = state;
|
|
1047
|
+
this.count = count;
|
|
1048
|
+
}
|
|
1049
|
+
get records() {
|
|
1050
|
+
return this.count;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Whether the rows array has closed. What follows it is checked by parsing
|
|
1054
|
+
* the whole document, which a cut-off body fails.
|
|
1055
|
+
*/
|
|
1056
|
+
get complete() {
|
|
1057
|
+
return this.state === CLOSED;
|
|
1058
|
+
}
|
|
1059
|
+
finish() {
|
|
1060
|
+
return this.count;
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
// src/exportDownload.ts
|
|
1065
|
+
var RECORD_COUNT_HEADER = "x-delopay-record-count";
|
|
1066
|
+
var LIST_ENVELOPE = { rows: "records", count: "record_count" };
|
|
1067
|
+
var WORKSPACE_ENVELOPE = { rows: "data", count: "total_count" };
|
|
1068
|
+
function parseRecordCount(header) {
|
|
1069
|
+
if (header === null) return null;
|
|
1070
|
+
const trimmed = header.trim();
|
|
1071
|
+
if (!/^\d+$/.test(trimmed)) return null;
|
|
1072
|
+
const value = Number(trimmed);
|
|
1073
|
+
return Number.isSafeInteger(value) ? value : null;
|
|
1074
|
+
}
|
|
1075
|
+
function counterFor(format) {
|
|
1076
|
+
if (format === "csv") return new CsvRecordCounter();
|
|
1077
|
+
if (format === "json") return new JsonArrayRecordCounter();
|
|
1078
|
+
return null;
|
|
1079
|
+
}
|
|
1080
|
+
function isRecord(value) {
|
|
1081
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1082
|
+
}
|
|
1083
|
+
function announced(expected) {
|
|
1084
|
+
return expected === null ? "" : ` of the ${expected} announced`;
|
|
1085
|
+
}
|
|
1086
|
+
function incomplete(message, expected, received, requestId) {
|
|
1087
|
+
return new DelopayError(message, {
|
|
1088
|
+
status: 0,
|
|
1089
|
+
code: "EXPORT_INCOMPLETE",
|
|
1090
|
+
type: "export_incomplete",
|
|
1091
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
1092
|
+
data: { expected_records: expected, received_records: received }
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
async function downloadExport(request, call, options) {
|
|
1096
|
+
const { format } = call;
|
|
1097
|
+
const envelope = call.envelope ?? LIST_ENVELOPE;
|
|
1098
|
+
const onProgress = options?.onProgress;
|
|
1099
|
+
let latest = {
|
|
1100
|
+
phase: "preparing",
|
|
1101
|
+
receivedBytes: 0,
|
|
1102
|
+
totalBytes: null,
|
|
1103
|
+
receivedRecords: 0,
|
|
1104
|
+
expectedRecords: null
|
|
1105
|
+
};
|
|
1106
|
+
const seen = { attempt: -1, counter: null, expected: null, requestId: void 0, listenerError: null };
|
|
1107
|
+
const report = (progress) => {
|
|
1108
|
+
latest = progress;
|
|
1109
|
+
if (!onProgress) return;
|
|
1110
|
+
try {
|
|
1111
|
+
onProgress({ ...progress });
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
seen.listenerError = { error };
|
|
1114
|
+
throw error;
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
report(latest);
|
|
1118
|
+
const onDownloadProgress = (event) => {
|
|
1119
|
+
if (event.attempt !== seen.attempt) {
|
|
1120
|
+
seen.attempt = event.attempt;
|
|
1121
|
+
seen.counter = counterFor(format);
|
|
1122
|
+
seen.expected = format === "pdf" ? null : parseRecordCount(event.headers.get(RECORD_COUNT_HEADER));
|
|
1123
|
+
seen.requestId = event.headers.get("x-request-id") ?? event.headers.get("x-trace-id") ?? void 0;
|
|
1124
|
+
}
|
|
1125
|
+
if (event.chunk.byteLength > 0) seen.counter?.push(event.chunk);
|
|
1126
|
+
report({
|
|
1127
|
+
phase: "receiving",
|
|
1128
|
+
receivedBytes: event.loaded,
|
|
1129
|
+
totalBytes: event.total,
|
|
1130
|
+
receivedRecords: seen.counter?.records ?? 0,
|
|
1131
|
+
expectedRecords: seen.expected
|
|
1132
|
+
});
|
|
1133
|
+
};
|
|
1134
|
+
let result;
|
|
1135
|
+
try {
|
|
1136
|
+
result = await request(call.method, call.path, {
|
|
1137
|
+
...call.request,
|
|
1138
|
+
...options?.signal !== void 0 ? { signal: options.signal } : {},
|
|
1139
|
+
...options?.timeout !== void 0 ? { timeout: options.timeout } : {},
|
|
1140
|
+
onDownloadProgress
|
|
1141
|
+
});
|
|
1142
|
+
} catch (err) {
|
|
1143
|
+
if (seen.listenerError !== null && err === seen.listenerError.error) throw err;
|
|
1144
|
+
if (format === "json" && seen.attempt >= 0 && err instanceof SyntaxError) {
|
|
1145
|
+
const received2 = seen.counter?.records ?? 0;
|
|
1146
|
+
throw incomplete(
|
|
1147
|
+
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}`,
|
|
1148
|
+
seen.expected,
|
|
1149
|
+
received2,
|
|
1150
|
+
seen.requestId
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
throw err;
|
|
1154
|
+
}
|
|
1155
|
+
const { expected, requestId } = seen;
|
|
1156
|
+
let received = 0;
|
|
1157
|
+
if (format === "json") {
|
|
1158
|
+
const rows = isRecord(result) ? result[envelope.rows] : void 0;
|
|
1159
|
+
if (!Array.isArray(rows)) {
|
|
1160
|
+
throw incomplete(
|
|
1161
|
+
`Export incomplete: the body is not an export envelope with a "${envelope.rows}" array, so it carries 0 records${announced(expected)}`,
|
|
1162
|
+
expected,
|
|
1163
|
+
0,
|
|
1164
|
+
requestId
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
received = rows.length;
|
|
1168
|
+
const declared = isRecord(result) ? result[envelope.count] : void 0;
|
|
1169
|
+
if (typeof declared === "number" && declared !== rows.length) {
|
|
1170
|
+
throw incomplete(
|
|
1171
|
+
`Export incomplete: the file's ${envelope.count} is ${declared}, but it carries ${rows.length} records`,
|
|
1172
|
+
declared,
|
|
1173
|
+
rows.length,
|
|
1174
|
+
requestId
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
} else if (format === "csv") {
|
|
1178
|
+
const counter = seen.counter;
|
|
1179
|
+
received = counter?.finish() ?? 0;
|
|
1180
|
+
if (!counter?.complete) {
|
|
1181
|
+
throw incomplete(
|
|
1182
|
+
`Export incomplete: the CSV body ended part-way through a line, after ${received} complete records${announced(expected)}`,
|
|
1183
|
+
expected,
|
|
1184
|
+
received,
|
|
1185
|
+
requestId
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (expected !== null && received !== expected) {
|
|
1190
|
+
throw incomplete(
|
|
1191
|
+
`Export incomplete: the server announced ${expected} records, and the body carried ${received}`,
|
|
1192
|
+
expected,
|
|
1193
|
+
received,
|
|
1194
|
+
requestId
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
report({
|
|
1198
|
+
phase: "done",
|
|
1199
|
+
receivedBytes: latest.receivedBytes,
|
|
1200
|
+
totalBytes: latest.totalBytes,
|
|
1201
|
+
receivedRecords: received,
|
|
1202
|
+
expectedRecords: expected
|
|
1203
|
+
});
|
|
1204
|
+
return result;
|
|
1205
|
+
}
|
|
1206
|
+
var ACCEPT = {
|
|
1207
|
+
csv: "text/csv",
|
|
1208
|
+
json: "application/json",
|
|
1209
|
+
pdf: "application/pdf"
|
|
1210
|
+
};
|
|
1211
|
+
function negotiated(options, format) {
|
|
1212
|
+
const headers = { ...options.headers, Accept: ACCEPT[format] };
|
|
1213
|
+
return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
|
|
1214
|
+
}
|
|
1215
|
+
function runExport(request, method, path, base, options) {
|
|
1216
|
+
const format = options?.format ?? "json";
|
|
1217
|
+
return downloadExport(
|
|
1218
|
+
request,
|
|
1219
|
+
{ method, path, request: negotiated(base, format), format },
|
|
1220
|
+
options
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
941
1224
|
// src/resources/disputes.ts
|
|
942
1225
|
function workspaceQuery(params) {
|
|
943
1226
|
if (!params) return void 0;
|
|
@@ -966,9 +1249,28 @@ var Disputes = class {
|
|
|
966
1249
|
async workspaceAggregate(params) {
|
|
967
1250
|
return this.request("GET", "/disputes/workspace/aggregate", { query: workspaceQuery(params) });
|
|
968
1251
|
}
|
|
969
|
-
/**
|
|
970
|
-
|
|
971
|
-
|
|
1252
|
+
/**
|
|
1253
|
+
* Export the complete filtered set, or throw on the server's explicit
|
|
1254
|
+
* export-limit refusal. `GET /disputes/workspace/export`
|
|
1255
|
+
*
|
|
1256
|
+
* The body is streamed, and held to the `X-Delopay-Record-Count` the server
|
|
1257
|
+
* announces and to its own `total_count`: a set that arrives short rejects
|
|
1258
|
+
* with `EXPORT_INCOMPLETE` rather than resolving. `options` reports the
|
|
1259
|
+
* download's progress and takes a signal and an idle timeout — see
|
|
1260
|
+
* {@link ExportTransferOptions}.
|
|
1261
|
+
*/
|
|
1262
|
+
async workspaceExport(params, options) {
|
|
1263
|
+
return downloadExport(
|
|
1264
|
+
this.request,
|
|
1265
|
+
{
|
|
1266
|
+
method: "GET",
|
|
1267
|
+
path: "/disputes/workspace/export",
|
|
1268
|
+
request: { query: workspaceQuery(params) },
|
|
1269
|
+
format: "json",
|
|
1270
|
+
envelope: WORKSPACE_ENVELOPE
|
|
1271
|
+
},
|
|
1272
|
+
options
|
|
1273
|
+
);
|
|
972
1274
|
}
|
|
973
1275
|
/**
|
|
974
1276
|
* Retrieve a dispute by its ID.
|
|
@@ -4125,77 +4427,68 @@ var Export = class {
|
|
|
4125
4427
|
this.request = request;
|
|
4126
4428
|
}
|
|
4127
4429
|
async transactions(params, options) {
|
|
4128
|
-
return this.request
|
|
4129
|
-
"POST",
|
|
4130
|
-
"/export/transactions",
|
|
4131
|
-
transactionBody(params, options)
|
|
4132
|
-
);
|
|
4430
|
+
return runExport(this.request, "POST", "/export/transactions", { body: params ?? {} }, options);
|
|
4133
4431
|
}
|
|
4134
4432
|
async transactionsForProfile(params, options) {
|
|
4135
|
-
return
|
|
4433
|
+
return runExport(
|
|
4434
|
+
this.request,
|
|
4136
4435
|
"POST",
|
|
4137
4436
|
"/export/profile/transactions",
|
|
4138
|
-
|
|
4437
|
+
{ body: params ?? {} },
|
|
4438
|
+
options
|
|
4139
4439
|
);
|
|
4140
4440
|
}
|
|
4141
4441
|
async refunds(params, options) {
|
|
4142
|
-
return this.request
|
|
4442
|
+
return runExport(this.request, "POST", "/refunds/list/export", { body: params ?? {} }, options);
|
|
4143
4443
|
}
|
|
4144
4444
|
async refundsForProfile(params, options) {
|
|
4145
|
-
return
|
|
4445
|
+
return runExport(
|
|
4446
|
+
this.request,
|
|
4146
4447
|
"POST",
|
|
4147
4448
|
"/refunds/profile/list/export",
|
|
4148
|
-
|
|
4449
|
+
{ body: params ?? {} },
|
|
4450
|
+
options
|
|
4149
4451
|
);
|
|
4150
4452
|
}
|
|
4151
4453
|
async disputes(params, options) {
|
|
4152
|
-
return this.request
|
|
4454
|
+
return runExport(this.request, "GET", "/disputes/list/export", queried(params), options);
|
|
4153
4455
|
}
|
|
4154
4456
|
async disputesForProfile(params, options) {
|
|
4155
|
-
return
|
|
4457
|
+
return runExport(
|
|
4458
|
+
this.request,
|
|
4156
4459
|
"GET",
|
|
4157
4460
|
"/disputes/profile/list/export",
|
|
4158
|
-
queried(params,
|
|
4461
|
+
queried(params),
|
|
4462
|
+
options
|
|
4159
4463
|
);
|
|
4160
4464
|
}
|
|
4161
4465
|
async payouts(params, options) {
|
|
4162
|
-
return this.request
|
|
4466
|
+
return runExport(this.request, "POST", "/payouts/list/export", { body: params }, options);
|
|
4163
4467
|
}
|
|
4164
4468
|
async payoutsForProfile(params, options) {
|
|
4165
|
-
return
|
|
4469
|
+
return runExport(
|
|
4470
|
+
this.request,
|
|
4471
|
+
"POST",
|
|
4472
|
+
"/payouts/profile/list/export",
|
|
4473
|
+
{ body: params },
|
|
4474
|
+
options
|
|
4475
|
+
);
|
|
4166
4476
|
}
|
|
4167
4477
|
async subscriptions(profileId, params, options) {
|
|
4168
|
-
return
|
|
4478
|
+
return runExport(
|
|
4479
|
+
this.request,
|
|
4169
4480
|
"GET",
|
|
4170
4481
|
"/subscriptions/list/export",
|
|
4171
|
-
queried(params,
|
|
4482
|
+
queried(params, { "X-Profile-Id": profileId }),
|
|
4483
|
+
options
|
|
4172
4484
|
);
|
|
4173
4485
|
}
|
|
4174
4486
|
async auditLog(params, options) {
|
|
4175
|
-
return this.request
|
|
4487
|
+
return runExport(this.request, "GET", "/audit/export", queried(params), options);
|
|
4176
4488
|
}
|
|
4177
4489
|
};
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
json: "application/json",
|
|
4181
|
-
pdf: "application/pdf"
|
|
4182
|
-
};
|
|
4183
|
-
function negotiated(options, format) {
|
|
4184
|
-
const headers = { ...options.headers, Accept: ACCEPT[format] };
|
|
4185
|
-
return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
|
|
4186
|
-
}
|
|
4187
|
-
function transactionBody(params, options) {
|
|
4188
|
-
const format = options?.format ?? "json";
|
|
4189
|
-
return negotiated({ body: { ...params, format } }, format);
|
|
4190
|
-
}
|
|
4191
|
-
function bodied(body, options) {
|
|
4192
|
-
return negotiated({ body }, options?.format ?? "json");
|
|
4193
|
-
}
|
|
4194
|
-
function queried(params, options, headers) {
|
|
4195
|
-
return negotiated(
|
|
4196
|
-
{ query: params ?? {}, ...headers ? { headers } : {} },
|
|
4197
|
-
options?.format ?? "json"
|
|
4198
|
-
);
|
|
4490
|
+
function queried(params, headers) {
|
|
4491
|
+
return { query: params ?? {}, ...headers ? { headers } : {} };
|
|
4199
4492
|
}
|
|
4200
4493
|
|
|
4201
4494
|
// src/resources/featureMatrix.ts
|
|
@@ -5568,6 +5861,112 @@ function findIdempotencyKey(headers) {
|
|
|
5568
5861
|
}
|
|
5569
5862
|
function noop() {
|
|
5570
5863
|
}
|
|
5864
|
+
var ListenerFailure = class {
|
|
5865
|
+
constructor(cause) {
|
|
5866
|
+
this.cause = cause;
|
|
5867
|
+
}
|
|
5868
|
+
};
|
|
5869
|
+
var BodyStreamFailure = class {
|
|
5870
|
+
constructor(cause) {
|
|
5871
|
+
this.cause = cause;
|
|
5872
|
+
}
|
|
5873
|
+
};
|
|
5874
|
+
function abortError() {
|
|
5875
|
+
const error = new Error("The operation was aborted");
|
|
5876
|
+
error.name = "AbortError";
|
|
5877
|
+
return error;
|
|
5878
|
+
}
|
|
5879
|
+
function parseContentLength(header) {
|
|
5880
|
+
if (header === null || !/^\s*\d+\s*$/.test(header)) return null;
|
|
5881
|
+
const value = Number(header);
|
|
5882
|
+
return Number.isSafeInteger(value) ? value : null;
|
|
5883
|
+
}
|
|
5884
|
+
function readChunk(reader, signal) {
|
|
5885
|
+
if (signal.aborted) return Promise.reject(abortError());
|
|
5886
|
+
return new Promise((resolve, reject) => {
|
|
5887
|
+
const onAbort = () => reject(abortError());
|
|
5888
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
5889
|
+
reader.read().then(
|
|
5890
|
+
(result) => {
|
|
5891
|
+
signal.removeEventListener("abort", onAbort);
|
|
5892
|
+
resolve(result);
|
|
5893
|
+
},
|
|
5894
|
+
(cause) => {
|
|
5895
|
+
signal.removeEventListener("abort", onAbort);
|
|
5896
|
+
reject(signal.aborted ? abortError() : new BodyStreamFailure(cause));
|
|
5897
|
+
}
|
|
5898
|
+
);
|
|
5899
|
+
});
|
|
5900
|
+
}
|
|
5901
|
+
function concatChunks(chunks, length) {
|
|
5902
|
+
const out = new Uint8Array(length);
|
|
5903
|
+
let offset = 0;
|
|
5904
|
+
for (const chunk of chunks) {
|
|
5905
|
+
out.set(chunk, offset);
|
|
5906
|
+
offset += chunk.byteLength;
|
|
5907
|
+
}
|
|
5908
|
+
return out.buffer;
|
|
5909
|
+
}
|
|
5910
|
+
async function receiveWithProgress(response, responseType, listener, attempt, signal, onActivity) {
|
|
5911
|
+
const headers = response.headers ?? new Headers();
|
|
5912
|
+
const total = parseContentLength(headers.get("content-length"));
|
|
5913
|
+
let loaded = 0;
|
|
5914
|
+
const notify = (chunk) => {
|
|
5915
|
+
try {
|
|
5916
|
+
listener({ loaded, total, chunk: chunk.slice(), headers, attempt });
|
|
5917
|
+
} catch (cause) {
|
|
5918
|
+
throw new ListenerFailure(cause);
|
|
5919
|
+
}
|
|
5920
|
+
};
|
|
5921
|
+
onActivity();
|
|
5922
|
+
notify(new Uint8Array(0));
|
|
5923
|
+
const body = response.body;
|
|
5924
|
+
if (!body || typeof body.getReader !== "function") {
|
|
5925
|
+
if (responseType === "blob") {
|
|
5926
|
+
const blob = await response.blob();
|
|
5927
|
+
const bytes3 = new Uint8Array(await blob.arrayBuffer());
|
|
5928
|
+
loaded = bytes3.byteLength;
|
|
5929
|
+
if (loaded > 0) notify(bytes3);
|
|
5930
|
+
return blob;
|
|
5931
|
+
}
|
|
5932
|
+
if (responseType === "arraybuffer") {
|
|
5933
|
+
const buffer = await response.arrayBuffer();
|
|
5934
|
+
loaded = buffer.byteLength;
|
|
5935
|
+
if (loaded > 0) notify(new Uint8Array(buffer));
|
|
5936
|
+
return buffer;
|
|
5937
|
+
}
|
|
5938
|
+
const text2 = await response.text();
|
|
5939
|
+
const bytes2 = new TextEncoder().encode(text2);
|
|
5940
|
+
loaded = bytes2.byteLength;
|
|
5941
|
+
if (loaded > 0) notify(bytes2);
|
|
5942
|
+
return text2 ? JSON.parse(text2) : void 0;
|
|
5943
|
+
}
|
|
5944
|
+
const reader = body.getReader();
|
|
5945
|
+
const chunks = [];
|
|
5946
|
+
try {
|
|
5947
|
+
for (; ; ) {
|
|
5948
|
+
const { done, value } = await readChunk(reader, signal);
|
|
5949
|
+
if (done) break;
|
|
5950
|
+
if (!value || value.byteLength === 0) continue;
|
|
5951
|
+
chunks.push(value);
|
|
5952
|
+
loaded += value.byteLength;
|
|
5953
|
+
onActivity();
|
|
5954
|
+
notify(value);
|
|
5955
|
+
}
|
|
5956
|
+
} catch (err) {
|
|
5957
|
+
reader.cancel().catch(noop);
|
|
5958
|
+
throw err;
|
|
5959
|
+
}
|
|
5960
|
+
const bytes = concatChunks(chunks, loaded);
|
|
5961
|
+
if (responseType === "blob") {
|
|
5962
|
+
return new Blob([bytes], { type: headers.get("content-type") ?? "" });
|
|
5963
|
+
}
|
|
5964
|
+
if (responseType === "arraybuffer") {
|
|
5965
|
+
return bytes;
|
|
5966
|
+
}
|
|
5967
|
+
const text = new TextDecoder().decode(bytes);
|
|
5968
|
+
return text ? JSON.parse(text) : void 0;
|
|
5969
|
+
}
|
|
5571
5970
|
function combineSignals(signals) {
|
|
5572
5971
|
const controller = new AbortController();
|
|
5573
5972
|
const listeners = [];
|
|
@@ -5849,7 +6248,12 @@ var Delopay = class {
|
|
|
5849
6248
|
emit("retry", { attempt, maxRetries: this.maxRetries, method, path });
|
|
5850
6249
|
}
|
|
5851
6250
|
const timeoutCtrl = new AbortController();
|
|
5852
|
-
|
|
6251
|
+
let timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
|
|
6252
|
+
const restartIdleTimer = () => {
|
|
6253
|
+
if (timeoutCtrl.signal.aborted) return;
|
|
6254
|
+
clearTimeout(timeoutId);
|
|
6255
|
+
timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
|
|
6256
|
+
};
|
|
5853
6257
|
const combined = combineSignals(
|
|
5854
6258
|
callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal]
|
|
5855
6259
|
);
|
|
@@ -5907,6 +6311,16 @@ var Delopay = class {
|
|
|
5907
6311
|
}
|
|
5908
6312
|
throw error;
|
|
5909
6313
|
}
|
|
6314
|
+
if (options?.onDownloadProgress) {
|
|
6315
|
+
return await receiveWithProgress(
|
|
6316
|
+
response,
|
|
6317
|
+
options.responseType,
|
|
6318
|
+
options.onDownloadProgress,
|
|
6319
|
+
attempt,
|
|
6320
|
+
combined.signal,
|
|
6321
|
+
restartIdleTimer
|
|
6322
|
+
);
|
|
6323
|
+
}
|
|
5910
6324
|
if (options?.responseType === "blob") {
|
|
5911
6325
|
return await response.blob();
|
|
5912
6326
|
}
|
|
@@ -5919,6 +6333,20 @@ var Delopay = class {
|
|
|
5919
6333
|
if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {
|
|
5920
6334
|
throw err;
|
|
5921
6335
|
}
|
|
6336
|
+
if (err instanceof ListenerFailure) {
|
|
6337
|
+
throw err.cause;
|
|
6338
|
+
}
|
|
6339
|
+
if (err instanceof BodyStreamFailure) {
|
|
6340
|
+
const cause = err.cause;
|
|
6341
|
+
const detail = cause instanceof Error ? cause.message : String(cause ?? "body stream failed");
|
|
6342
|
+
lastError = new DelopayError(`Network error: ${detail}`, {
|
|
6343
|
+
status: 0,
|
|
6344
|
+
code: "NETWORK",
|
|
6345
|
+
type: "network_error"
|
|
6346
|
+
});
|
|
6347
|
+
if (isRetryable && attempt < this.maxRetries) continue;
|
|
6348
|
+
throw lastError;
|
|
6349
|
+
}
|
|
5922
6350
|
if (err instanceof Error && err.name === "AbortError") {
|
|
5923
6351
|
if (callerSignal?.aborted) {
|
|
5924
6352
|
throw new DelopayError("Request aborted", {
|
|
@@ -6496,6 +6924,66 @@ function surchargeWordFor(branding, isDiscount, locale) {
|
|
|
6496
6924
|
locale
|
|
6497
6925
|
);
|
|
6498
6926
|
}
|
|
6927
|
+
var NOTICE_SECTIONS = ["summary", "payment"];
|
|
6928
|
+
var NOTICES_PER_SECTION = 3;
|
|
6929
|
+
var NOTICE_LABEL_MAX_LENGTH = 80;
|
|
6930
|
+
var NOTICE_ICONS = [
|
|
6931
|
+
"lock",
|
|
6932
|
+
"shield",
|
|
6933
|
+
"check",
|
|
6934
|
+
"truck",
|
|
6935
|
+
"package",
|
|
6936
|
+
"refresh",
|
|
6937
|
+
"star",
|
|
6938
|
+
"support",
|
|
6939
|
+
"globe",
|
|
6940
|
+
"tag",
|
|
6941
|
+
"heart",
|
|
6942
|
+
"leaf",
|
|
6943
|
+
"clock",
|
|
6944
|
+
"bank"
|
|
6945
|
+
];
|
|
6946
|
+
var NOTICE_ICON_FALLBACK = "check";
|
|
6947
|
+
var NOTICE_ICON_PATHS = {
|
|
6948
|
+
lock: [
|
|
6949
|
+
"M6 10h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2z",
|
|
6950
|
+
"M8 10V7a4 4 0 0 1 8 0v3"
|
|
6951
|
+
],
|
|
6952
|
+
shield: ["M12 3l7 3v6c0 4.2-2.9 7.6-7 9-4.1-1.4-7-4.8-7-9V6z", "M9 12l2.5 2.5 4-4.5"],
|
|
6953
|
+
check: ["M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z", "M8 12.5l3 3 5-6"],
|
|
6954
|
+
truck: [
|
|
6955
|
+
"M3 7.5h10v9H3z",
|
|
6956
|
+
"M13 11h4l3 3v2.5h-7z",
|
|
6957
|
+
"M8.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z",
|
|
6958
|
+
"M18.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z"
|
|
6959
|
+
],
|
|
6960
|
+
package: [
|
|
6961
|
+
"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",
|
|
6962
|
+
"M12 22V12",
|
|
6963
|
+
"M3.29 7L12 12l8.71-5"
|
|
6964
|
+
],
|
|
6965
|
+
refresh: ["M20 12a8 8 0 1 1-2.5-5.8", "M20 4v5h-5"],
|
|
6966
|
+
star: ["m12 3.6 2.6 5.3 5.9.9-4.3 4.1 1 5.8-5.2-2.7-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z"],
|
|
6967
|
+
support: [
|
|
6968
|
+
"M5 13v-1a7 7 0 0 1 14 0v1",
|
|
6969
|
+
"M3.5 14.5a1.8 1.8 0 0 1 1.8-1.8H7v5H5.3a1.8 1.8 0 0 1-1.8-1.8z",
|
|
6970
|
+
"M20.5 14.5a1.8 1.8 0 0 0-1.8-1.8H17v5h1.7a1.8 1.8 0 0 0 1.8-1.8z",
|
|
6971
|
+
"M19 17.7v.8a2.5 2.5 0 0 1-2.5 2.5H13"
|
|
6972
|
+
],
|
|
6973
|
+
globe: [
|
|
6974
|
+
"M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z",
|
|
6975
|
+
"M3 12h18",
|
|
6976
|
+
"M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18z"
|
|
6977
|
+
],
|
|
6978
|
+
tag: ["M11 3H4v7l10 10 7-7z", "M9.1 7a1.3 1.3 0 1 1-2.6 0a1.3 1.3 0 1 1 2.6 0z"],
|
|
6979
|
+
heart: ["M12 20s-7-4.4-7-9.3A3.9 3.9 0 0 1 12 8a3.9 3.9 0 0 1 7 2.7c0 4.9-7 9.3-7 9.3z"],
|
|
6980
|
+
leaf: ["M20 4c0 9-5.4 13-9.5 13A4.5 4.5 0 0 1 6 12.5C6 7 12 4 20 4z", "M4 20c2-4.5 5-7.5 9-9.5"],
|
|
6981
|
+
clock: ["M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z", "M12 7v5l3 2"],
|
|
6982
|
+
bank: ["M3 9.5 12 4l9 5.5", "M5 10v8M9.5 10v8M14.5 10v8M19 10v8", "M3 20h18"]
|
|
6983
|
+
};
|
|
6984
|
+
function isNoticeIcon(value) {
|
|
6985
|
+
return typeof value === "string" && NOTICE_ICONS.includes(value);
|
|
6986
|
+
}
|
|
6499
6987
|
var FONT_STACKS = {
|
|
6500
6988
|
inter: "'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif",
|
|
6501
6989
|
system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
|
|
@@ -6665,6 +7153,96 @@ var DEFAULT_BADGES_DARK = [
|
|
|
6665
7153
|
borderColor: "#1e40af"
|
|
6666
7154
|
}
|
|
6667
7155
|
];
|
|
7156
|
+
var DEFAULT_NOTICES = [
|
|
7157
|
+
{
|
|
7158
|
+
id: "secure",
|
|
7159
|
+
section: "summary",
|
|
7160
|
+
icon: "shield",
|
|
7161
|
+
label: "Secure payment",
|
|
7162
|
+
labelTranslations: {
|
|
7163
|
+
de: "Sichere Zahlung",
|
|
7164
|
+
fr: "Paiement s\xE9curis\xE9",
|
|
7165
|
+
es: "Pago seguro",
|
|
7166
|
+
it: "Pagamento sicuro",
|
|
7167
|
+
nl: "Veilig betalen",
|
|
7168
|
+
zh: "\u5B89\u5168\u652F\u4ED8",
|
|
7169
|
+
"zh-Hant": "\u5B89\u5168\u4ED8\u6B3E",
|
|
7170
|
+
hi: "\u0938\u0941\u0930\u0915\u094D\u0937\u093F\u0924 \u092D\u0941\u0917\u0924\u093E\u0928",
|
|
7171
|
+
ar: "\u062F\u0641\u0639 \u0622\u0645\u0646"
|
|
7172
|
+
}
|
|
7173
|
+
},
|
|
7174
|
+
{
|
|
7175
|
+
id: "ssl",
|
|
7176
|
+
section: "summary",
|
|
7177
|
+
icon: "lock",
|
|
7178
|
+
label: "Encrypted \xB7 256-bit SSL",
|
|
7179
|
+
labelTranslations: {
|
|
7180
|
+
de: "Verschl\xFCsselt \xB7 256-Bit-SSL",
|
|
7181
|
+
fr: "Chiffr\xE9 \xB7 SSL 256 bits",
|
|
7182
|
+
es: "Cifrado \xB7 SSL de 256 bits",
|
|
7183
|
+
it: "Crittografato \xB7 SSL a 256 bit",
|
|
7184
|
+
nl: "Versleuteld \xB7 256-bit SSL",
|
|
7185
|
+
zh: "\u52A0\u5BC6 \xB7 256 \u4F4D SSL",
|
|
7186
|
+
"zh-Hant": "\u52A0\u5BC6 \xB7 256 \u4F4D\u5143 SSL",
|
|
7187
|
+
hi: "\u090F\u0928\u094D\u0915\u094D\u0930\u093F\u092A\u094D\u091F\u0947\u0921 \xB7 256-\u092C\u093F\u091F SSL",
|
|
7188
|
+
ar: "\u0645\u0634\u0641\u0651\u0631 \xB7 SSL \u0628\u0637\u0648\u0644 256 \u0628\u062A"
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
];
|
|
7192
|
+
function defaultNotices() {
|
|
7193
|
+
return DEFAULT_NOTICES.map(cloneNotice);
|
|
7194
|
+
}
|
|
7195
|
+
function cloneNotice(notice) {
|
|
7196
|
+
return { ...notice, labelTranslations: { ...notice.labelTranslations } };
|
|
7197
|
+
}
|
|
7198
|
+
function hexChannels(hex) {
|
|
7199
|
+
const raw = /^#([0-9a-f]{6})$/i.exec(hex.trim())?.[1];
|
|
7200
|
+
if (!raw) return null;
|
|
7201
|
+
return [
|
|
7202
|
+
parseInt(raw.slice(0, 2), 16),
|
|
7203
|
+
parseInt(raw.slice(2, 4), 16),
|
|
7204
|
+
parseInt(raw.slice(4, 6), 16)
|
|
7205
|
+
];
|
|
7206
|
+
}
|
|
7207
|
+
function isThemeTintedBadgeColouring(textColor, fill, border) {
|
|
7208
|
+
const primary = hexChannels(textColor);
|
|
7209
|
+
const bg = hexChannels(fill);
|
|
7210
|
+
const line = hexChannels(border);
|
|
7211
|
+
if (!primary || !bg || !line) return false;
|
|
7212
|
+
const mixed = (surface, to, share) => Math.round(surface + (to - surface) * share);
|
|
7213
|
+
return primary.every((p, i) => {
|
|
7214
|
+
for (let surface = 0; surface <= 255; surface += 1) {
|
|
7215
|
+
if (mixed(surface, p, 0.08) === bg[i] && mixed(surface, p, 0.3) === line[i]) return true;
|
|
7216
|
+
}
|
|
7217
|
+
return false;
|
|
7218
|
+
});
|
|
7219
|
+
}
|
|
7220
|
+
function isDefaultBadgeSet(badges) {
|
|
7221
|
+
if (badges.length !== DEFAULT_BADGES.length) return false;
|
|
7222
|
+
const sameContent = badges.every(
|
|
7223
|
+
(badge, i) => badge.id === DEFAULT_BADGES[i]?.id && badge.label === DEFAULT_BADGES[i]?.label
|
|
7224
|
+
);
|
|
7225
|
+
if (!sameContent) return false;
|
|
7226
|
+
const colouring = (set) => set.map((b) => [b.textColor, b.backgroundColor, b.borderColor ?? ""].join("|").toLowerCase()).join("/");
|
|
7227
|
+
const mine = colouring(badges);
|
|
7228
|
+
if (mine === colouring(DEFAULT_BADGES) || mine === colouring(DEFAULT_BADGES_DARK)) return true;
|
|
7229
|
+
const [first] = badges;
|
|
7230
|
+
const border = first?.borderColor;
|
|
7231
|
+
if (!first || !border) return false;
|
|
7232
|
+
const same = (a, b) => (a ?? "").toLowerCase() === b.toLowerCase();
|
|
7233
|
+
return badges.every(
|
|
7234
|
+
(b) => same(b.textColor, first.textColor) && same(b.backgroundColor, first.backgroundColor) && same(b.borderColor, border)
|
|
7235
|
+
) && isThemeTintedBadgeColouring(first.textColor, first.backgroundColor, border);
|
|
7236
|
+
}
|
|
7237
|
+
function resolveNoticesAndBadges(savedBadges, savedNotices) {
|
|
7238
|
+
if (savedNotices !== null) {
|
|
7239
|
+
return { trustBadges: savedBadges ?? [], notices: savedNotices };
|
|
7240
|
+
}
|
|
7241
|
+
if (savedBadges === null || isDefaultBadgeSet(savedBadges)) {
|
|
7242
|
+
return { trustBadges: [], notices: defaultNotices() };
|
|
7243
|
+
}
|
|
7244
|
+
return { trustBadges: savedBadges, notices: [] };
|
|
7245
|
+
}
|
|
6668
7246
|
var METHOD_SECTION_ORDER_KEY = "methodSectionOrder";
|
|
6669
7247
|
var METHOD_SECTION_LABELS_KEY = "methodSectionLabels";
|
|
6670
7248
|
var MIN_SECTION_ORDER = 1;
|
|
@@ -6951,7 +7529,11 @@ var DEFAULT_BRANDING_BASE = {
|
|
|
6951
7529
|
var DEFAULT_BRANDING = {
|
|
6952
7530
|
...DEFAULT_BRANDING_BASE,
|
|
6953
7531
|
...LIGHT_PALETTE,
|
|
6954
|
-
|
|
7532
|
+
// No badges by default since todos#218 — notices took their place.
|
|
7533
|
+
// `DEFAULT_BADGES` stays exported because `isDefaultBadgeSet` still has to
|
|
7534
|
+
// recognise the pair on shops saved before.
|
|
7535
|
+
trustBadges: [],
|
|
7536
|
+
notices: defaultNotices(),
|
|
6955
7537
|
customFields: [],
|
|
6956
7538
|
methodSectionOrder: defaultMethodSectionOrder(),
|
|
6957
7539
|
methodSectionLabels: {}
|
|
@@ -6974,7 +7556,8 @@ var DEFAULT_BRANDING_DARK = {
|
|
|
6974
7556
|
// end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.
|
|
6975
7557
|
surchargeColor: "#fbbf24",
|
|
6976
7558
|
discountColor: "#34d399",
|
|
6977
|
-
trustBadges:
|
|
7559
|
+
trustBadges: [],
|
|
7560
|
+
notices: defaultNotices(),
|
|
6978
7561
|
customFields: [],
|
|
6979
7562
|
methodSectionOrder: defaultMethodSectionOrder(),
|
|
6980
7563
|
methodSectionLabels: {}
|
|
@@ -6986,6 +7569,7 @@ function cloneBranding(b) {
|
|
|
6986
7569
|
return {
|
|
6987
7570
|
...b,
|
|
6988
7571
|
trustBadges: b.trustBadges.map((badge) => ({ ...badge })),
|
|
7572
|
+
notices: b.notices.map(cloneNotice),
|
|
6989
7573
|
customFields: b.customFields.map(cloneCustomField),
|
|
6990
7574
|
methodSectionOrder: { ...b.methodSectionOrder },
|
|
6991
7575
|
methodSectionLabels: Object.fromEntries(
|
|
@@ -7095,6 +7679,80 @@ function encodeBadges(badges) {
|
|
|
7095
7679
|
}))
|
|
7096
7680
|
);
|
|
7097
7681
|
}
|
|
7682
|
+
var NOTICE_ID_MAX_LENGTH = 40;
|
|
7683
|
+
function capNoticeText(value) {
|
|
7684
|
+
return Array.from(value).slice(0, NOTICE_LABEL_MAX_LENGTH).join("");
|
|
7685
|
+
}
|
|
7686
|
+
function normalizeNotices(list) {
|
|
7687
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7688
|
+
const perSection = /* @__PURE__ */ new Map();
|
|
7689
|
+
const out = [];
|
|
7690
|
+
list.forEach((raw, index) => {
|
|
7691
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
7692
|
+
const src = raw;
|
|
7693
|
+
const label = typeof src["label"] === "string" ? capNoticeText(src["label"]) : "";
|
|
7694
|
+
const labelTranslations = {};
|
|
7695
|
+
for (const [locale, text] of Object.entries(parseTranslations(src["labelTranslations"]))) {
|
|
7696
|
+
labelTranslations[locale] = capNoticeText(text);
|
|
7697
|
+
}
|
|
7698
|
+
if (label.trim().length === 0 && Object.keys(labelTranslations).length === 0) return;
|
|
7699
|
+
const section = pickEnum(src["section"], NOTICE_SECTIONS, "summary");
|
|
7700
|
+
const used = perSection.get(section) ?? 0;
|
|
7701
|
+
if (used >= NOTICES_PER_SECTION) return;
|
|
7702
|
+
perSection.set(section, used + 1);
|
|
7703
|
+
let id = typeof src["id"] === "string" ? src["id"].replace(/[^A-Za-z0-9_-]/g, "").slice(0, NOTICE_ID_MAX_LENGTH) : "";
|
|
7704
|
+
if (!id || seen.has(id)) id = `notice-${index + 1}`;
|
|
7705
|
+
while (seen.has(id)) id = `${id}x`;
|
|
7706
|
+
seen.add(id);
|
|
7707
|
+
out.push({
|
|
7708
|
+
id,
|
|
7709
|
+
section,
|
|
7710
|
+
icon: isNoticeIcon(src["icon"]) ? src["icon"] : NOTICE_ICON_FALLBACK,
|
|
7711
|
+
label,
|
|
7712
|
+
labelTranslations
|
|
7713
|
+
});
|
|
7714
|
+
});
|
|
7715
|
+
return out;
|
|
7716
|
+
}
|
|
7717
|
+
function decodeNotices(raw) {
|
|
7718
|
+
if (raw === void 0) return null;
|
|
7719
|
+
let parsed;
|
|
7720
|
+
try {
|
|
7721
|
+
parsed = JSON.parse(raw);
|
|
7722
|
+
} catch {
|
|
7723
|
+
return null;
|
|
7724
|
+
}
|
|
7725
|
+
return Array.isArray(parsed) ? normalizeNotices(parsed) : null;
|
|
7726
|
+
}
|
|
7727
|
+
function parseNoticesLoose(raw) {
|
|
7728
|
+
if (typeof raw === "string") return decodeNotices(raw);
|
|
7729
|
+
return Array.isArray(raw) ? normalizeNotices(raw) : null;
|
|
7730
|
+
}
|
|
7731
|
+
function encodeNotices(notices) {
|
|
7732
|
+
return JSON.stringify(
|
|
7733
|
+
notices.map((n) => {
|
|
7734
|
+
const translations = Object.entries(n.labelTranslations).filter(
|
|
7735
|
+
([, text]) => text.trim().length > 0
|
|
7736
|
+
);
|
|
7737
|
+
return {
|
|
7738
|
+
id: n.id,
|
|
7739
|
+
section: n.section,
|
|
7740
|
+
icon: n.icon,
|
|
7741
|
+
label: n.label,
|
|
7742
|
+
...translations.length > 0 ? { labelTranslations: Object.fromEntries(translations) } : {}
|
|
7743
|
+
};
|
|
7744
|
+
})
|
|
7745
|
+
);
|
|
7746
|
+
}
|
|
7747
|
+
function noticeText(notice, locale) {
|
|
7748
|
+
return translationFor(notice.labelTranslations, locale) ?? notice.label;
|
|
7749
|
+
}
|
|
7750
|
+
function noticesIn(notices, section) {
|
|
7751
|
+
return notices.filter((n) => n.section === section).slice(0, NOTICES_PER_SECTION);
|
|
7752
|
+
}
|
|
7753
|
+
function shownNotices(notices, section, locale) {
|
|
7754
|
+
return noticesIn(notices, section).map((notice) => ({ notice, text: noticeText(notice, locale).trim() })).filter((entry) => entry.text.length > 0);
|
|
7755
|
+
}
|
|
7098
7756
|
var CUSTOM_FIELDS_MAX = 20;
|
|
7099
7757
|
var CUSTOM_FIELD_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;
|
|
7100
7758
|
var ALL_CUSTOM_FIELD_TYPES = [
|
|
@@ -7438,7 +8096,10 @@ function customFieldOptionLabel(option, locale) {
|
|
|
7438
8096
|
function decodeBranding(source) {
|
|
7439
8097
|
if (!source) return cloneBranding(DEFAULT_BRANDING);
|
|
7440
8098
|
const extras = source.sdk_ui_rules?.[BRANDING_GROUP_KEY] ?? {};
|
|
7441
|
-
const
|
|
8099
|
+
const trustRow = resolveNoticesAndBadges(
|
|
8100
|
+
decodeBadges(extras["trustBadges"]),
|
|
8101
|
+
decodeNotices(extras["notices"])
|
|
8102
|
+
);
|
|
7442
8103
|
const decodedCustomFields = decodeCustomFields(extras["customFields"]);
|
|
7443
8104
|
const displayName = s(source.merchant_name) || s(source.seller_name);
|
|
7444
8105
|
const logoUrl = s(source.merchant_logo) || s(source.logo);
|
|
@@ -7617,7 +8278,8 @@ function decodeBranding(source) {
|
|
|
7617
8278
|
totalLabel: s(extras["totalLabel"]) || DEFAULT_BRANDING.totalLabel,
|
|
7618
8279
|
showCurrencyCode: parseBool(extras["showCurrencyCode"], DEFAULT_BRANDING.showCurrencyCode),
|
|
7619
8280
|
showOrderItems: parseBool(extras["showOrderItems"], DEFAULT_BRANDING.showOrderItems),
|
|
7620
|
-
trustBadges:
|
|
8281
|
+
trustBadges: trustRow.trustBadges,
|
|
8282
|
+
notices: trustRow.notices,
|
|
7621
8283
|
customFields: decodedCustomFields ?? [],
|
|
7622
8284
|
methodSectionOrder: decodeMethodSectionOrder(extras[METHOD_SECTION_ORDER_KEY]),
|
|
7623
8285
|
methodSectionLabels: decodeMethodSectionLabels(extras[METHOD_SECTION_LABELS_KEY]),
|
|
@@ -7901,9 +8563,14 @@ function encodeBranding(branding, base) {
|
|
|
7901
8563
|
nomupayApplePayButtonType: branding.nomupayApplePayButtonType,
|
|
7902
8564
|
nomupayGooglePayButtonColor: branding.nomupayGooglePayButtonColor,
|
|
7903
8565
|
nomupayGooglePayButtonType: branding.nomupayGooglePayButtonType,
|
|
7904
|
-
|
|
8566
|
+
// Always written, `[]` included — its presence is what stops a later
|
|
8567
|
+
// decode from migrating the shop again (`resolveNoticesAndBadges`).
|
|
8568
|
+
notices: encodeNotices(branding.notices),
|
|
7905
8569
|
[METHOD_SECTION_ORDER_KEY]: encodeMethodSectionOrder(branding.methodSectionOrder)
|
|
7906
8570
|
};
|
|
8571
|
+
if (branding.trustBadges.length > 0) {
|
|
8572
|
+
extras["trustBadges"] = encodeBadges(branding.trustBadges);
|
|
8573
|
+
}
|
|
7907
8574
|
const sectionLabels = encodeMethodSectionLabels(branding.methodSectionLabels);
|
|
7908
8575
|
if (sectionLabels) extras[METHOD_SECTION_LABELS_KEY] = sectionLabels;
|
|
7909
8576
|
if (branding.customFields.length > 0) {
|
|
@@ -7969,7 +8636,10 @@ function parseImportedBranding(raw) {
|
|
|
7969
8636
|
const dflt = DEFAULT_BRANDING;
|
|
7970
8637
|
const sStr = (v, fallback) => typeof v === "string" ? v : fallback;
|
|
7971
8638
|
const sHex = (v, fallback) => typeof v === "string" && isHexColor(v) ? v : fallback;
|
|
7972
|
-
const
|
|
8639
|
+
const { trustBadges, notices } = resolveNoticesAndBadges(
|
|
8640
|
+
parseTrustBadgesLoose(root["trustBadges"]),
|
|
8641
|
+
parseNoticesLoose(root["notices"])
|
|
8642
|
+
);
|
|
7973
8643
|
const customFields = parseCustomFieldsLoose(root["customFields"]) ?? [];
|
|
7974
8644
|
const labelStyle = (() => {
|
|
7975
8645
|
const v = root["labelStyle"];
|
|
@@ -8112,6 +8782,7 @@ function parseImportedBranding(raw) {
|
|
|
8112
8782
|
showCurrencyCode: parseBool(root["showCurrencyCode"], dflt.showCurrencyCode),
|
|
8113
8783
|
showOrderItems: parseBool(root["showOrderItems"], dflt.showOrderItems),
|
|
8114
8784
|
trustBadges,
|
|
8785
|
+
notices,
|
|
8115
8786
|
customFields,
|
|
8116
8787
|
// An export writes the decoded maps; a hand-written file may carry the
|
|
8117
8788
|
// JSON strings the bag uses. Both are accepted, and neither is required.
|
|
@@ -9267,6 +9938,7 @@ var encodeNativePanes = encodePanes;
|
|
|
9267
9938
|
export {
|
|
9268
9939
|
DelopayError,
|
|
9269
9940
|
DelopayAuthenticationError,
|
|
9941
|
+
runExport,
|
|
9270
9942
|
PaypalDisputes,
|
|
9271
9943
|
Search,
|
|
9272
9944
|
isSubscriptionLifecycleWebhook,
|
|
@@ -9361,6 +10033,13 @@ export {
|
|
|
9361
10033
|
copyTranslationsKey,
|
|
9362
10034
|
checkoutCopy,
|
|
9363
10035
|
surchargeWordFor,
|
|
10036
|
+
NOTICE_SECTIONS,
|
|
10037
|
+
NOTICES_PER_SECTION,
|
|
10038
|
+
NOTICE_LABEL_MAX_LENGTH,
|
|
10039
|
+
NOTICE_ICONS,
|
|
10040
|
+
NOTICE_ICON_FALLBACK,
|
|
10041
|
+
NOTICE_ICON_PATHS,
|
|
10042
|
+
isNoticeIcon,
|
|
9364
10043
|
fontStack,
|
|
9365
10044
|
radiusValue,
|
|
9366
10045
|
fontWeightValue,
|
|
@@ -9376,6 +10055,11 @@ export {
|
|
|
9376
10055
|
isDarkSurface,
|
|
9377
10056
|
DEFAULT_BADGES,
|
|
9378
10057
|
DEFAULT_BADGES_DARK,
|
|
10058
|
+
DEFAULT_NOTICES,
|
|
10059
|
+
defaultNotices,
|
|
10060
|
+
cloneNotice,
|
|
10061
|
+
isDefaultBadgeSet,
|
|
10062
|
+
resolveNoticesAndBadges,
|
|
9379
10063
|
MIN_SECTION_ORDER,
|
|
9380
10064
|
MAX_SECTION_ORDER,
|
|
9381
10065
|
MAX_SECTION_LABEL_LENGTH,
|
|
@@ -9402,6 +10086,12 @@ export {
|
|
|
9402
10086
|
sanitizeCustomCss,
|
|
9403
10087
|
decodeBadges,
|
|
9404
10088
|
encodeBadges,
|
|
10089
|
+
decodeNotices,
|
|
10090
|
+
parseNoticesLoose,
|
|
10091
|
+
encodeNotices,
|
|
10092
|
+
noticeText,
|
|
10093
|
+
noticesIn,
|
|
10094
|
+
shownNotices,
|
|
9405
10095
|
CUSTOM_FIELDS_MAX,
|
|
9406
10096
|
CUSTOM_FIELD_KEY_PATTERN,
|
|
9407
10097
|
ALL_CUSTOM_FIELD_TYPES,
|
|
@@ -9464,4 +10154,4 @@ export {
|
|
|
9464
10154
|
decodeNativePanes,
|
|
9465
10155
|
encodeNativePanes
|
|
9466
10156
|
};
|
|
9467
|
-
//# sourceMappingURL=chunk-
|
|
10157
|
+
//# sourceMappingURL=chunk-W57MOHOE.js.map
|