@agent-cards/sdk 0.23.28 → 0.24.1
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/CHANGELOG.md +84 -0
- package/PREFLIGHT.md +7 -1
- package/README.md +197 -102
- package/dist/aci.d.ts +52 -22
- package/dist/aci.js +79 -15
- package/dist/adyen-merchant-hosted.generated.d.ts +2 -2
- package/dist/adyen-merchant-hosted.generated.js +586 -55
- package/dist/agent-amount.generated.js +1 -1
- package/dist/agentcard.d.ts +4 -5
- package/dist/agentcard.js +4 -5
- package/dist/amadeus.d.ts +9 -3
- package/dist/amadeus.js +33 -4
- package/dist/api-module.d.ts +1 -7
- package/dist/api-module.js +3 -5
- package/dist/{voice-retry.js → api-retry.js} +1 -1
- package/dist/api-types.d.ts +53 -0
- package/dist/{voice-types.js → api-types.js} +7 -2
- package/dist/approvals.d.ts +166 -0
- package/dist/approvals.js +213 -0
- package/dist/aurus.d.ts +33 -0
- package/dist/aurus.js +75 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/buy.d.ts +20 -101
- package/dist/buy.js +19 -74
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +2864 -249
- package/dist/cardlink-vpos.d.ts +43 -0
- package/dist/cardlink-vpos.js +90 -0
- package/dist/cdp.d.ts +3 -13
- package/dist/cdp.js +244 -175
- package/dist/checkout-com.generated.js +5 -1
- package/dist/client.d.ts +170 -22
- package/dist/client.js +281 -40
- package/dist/creditguard.generated.d.ts +4 -4
- package/dist/cybersource-flex.generated.d.ts +39 -1
- package/dist/cybersource-flex.generated.js +100 -11
- package/dist/datatrans.generated.js +22 -1
- package/dist/eghl.d.ts +40 -0
- package/dist/eghl.js +72 -0
- package/dist/elavon-converge.generated.js +5 -3
- package/dist/gmo.generated.js +7 -2
- package/dist/hold.d.ts +8 -0
- package/dist/hold.js +43 -2
- package/dist/hosted-entry.js +4 -0
- package/dist/index.d.ts +9 -15
- package/dist/index.js +6 -10
- package/dist/lifecycle.d.ts +9 -61
- package/dist/lifecycle.js +24 -10
- package/dist/merchant-card-endpoints.generated.d.ts +6 -1
- package/dist/merchant-card-endpoints.generated.js +344 -19
- package/dist/merchant-hosted.d.ts +8 -1
- package/dist/nike-order.d.ts +51 -0
- package/dist/nike-order.js +81 -0
- package/dist/oceanpayment.d.ts +38 -0
- package/dist/oceanpayment.js +70 -0
- package/dist/paddle-tokenex.generated.js +111 -11
- package/dist/payplug.d.ts +41 -0
- package/dist/payplug.js +71 -0
- package/dist/payrails.generated.js +33 -8
- package/dist/pre-claim.d.ts +11 -0
- package/dist/pre-claim.js +130 -7
- package/dist/preflight-capabilities.generated.d.ts +0 -4
- package/dist/preflight-capabilities.generated.js +0 -5
- package/dist/preflight-catalog.json +200 -6
- package/dist/preflight-playwright.d.ts +2 -2
- package/dist/preflight-playwright.js +63 -14
- package/dist/preflight-schemas.json +18 -0
- package/dist/preflight.generated.d.ts +5 -4
- package/dist/preflight.generated.js +63 -3
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +21 -0
- package/dist/prepared-processor.d.ts +18 -5
- package/dist/prepared-processor.js +48 -8
- package/dist/primer.generated.js +2889 -268
- package/dist/processout.generated.d.ts +61 -0
- package/dist/processout.generated.js +577 -0
- package/dist/requests.js +1 -1
- package/dist/shiji-sts.generated.js +111 -11
- package/dist/stripe-checkout.generated.js +2761 -319
- package/dist/substitutions.generated.js +553 -26
- package/dist/tap-payments.generated.js +111 -11
- package/dist/twoc2p.generated.js +111 -11
- package/dist/url-masks/bluesnap.d.ts +2 -0
- package/dist/url-masks/bluesnap.js +15 -0
- package/dist/url-masks/oceanpayment.d.ts +2 -0
- package/dist/url-masks/oceanpayment.js +13 -0
- package/dist/url-masks/payplug.d.ts +2 -0
- package/dist/url-masks/payplug.js +13 -0
- package/dist/url-masks/vtex_payments.d.ts +2 -0
- package/dist/url-masks/vtex_payments.js +12 -0
- package/dist/url-masks.generated.d.ts +1 -1
- package/dist/url-masks.generated.js +6 -2
- package/dist/verifone.generated.js +42 -2
- package/dist/vtex-payments.generated.d.ts +127 -0
- package/dist/vtex-payments.generated.js +544 -0
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +2 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +6 -8
- package/dist/languages.d.ts +0 -23
- package/dist/languages.js +0 -76
- package/dist/voice-pkce.d.ts +0 -49
- package/dist/voice-pkce.js +0 -147
- package/dist/voice-stream.generated.d.ts +0 -118
- package/dist/voice-stream.generated.js +0 -170
- package/dist/voice-types.d.ts +0 -735
- package/dist/voice.d.ts +0 -373
- package/dist/voice.js +0 -815
- package/readme.test.mjs +0 -53
- /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: d5ba000080ddbaa60195e0755732280bb41d62120f820d0194b904dc510ebe4d
|
|
4
4
|
// src/sha256.js
|
|
5
5
|
var K = /* @__PURE__ */ new Uint32Array([
|
|
6
6
|
1116352408,
|
|
@@ -146,6 +146,7 @@ var BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
|
146
146
|
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
147
147
|
var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
|
|
148
148
|
var MODULUS_BYTES = [128, 256, 384, 512];
|
|
149
|
+
var SMALL_MODULUS_BYTES = 64;
|
|
149
150
|
var MIN_PADDING = 8;
|
|
150
151
|
var MAX_DRAWS = 16;
|
|
151
152
|
var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
|
|
@@ -156,6 +157,9 @@ function parseRsaPublicKey(key) {
|
|
|
156
157
|
const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
|
|
157
158
|
if (named !== void 0 && named !== 17)
|
|
158
159
|
throw refuse("key");
|
|
160
|
+
const sized = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "bits") ? key.bits : void 0;
|
|
161
|
+
if (sized !== void 0 && sized !== 512)
|
|
162
|
+
throw refuse("key");
|
|
159
163
|
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
160
164
|
throw refuse("key");
|
|
161
165
|
if (typeof pin !== "string" || !SHA256_HEX.test(pin))
|
|
@@ -188,7 +192,8 @@ function parseRsaPublicKey(key) {
|
|
|
188
192
|
if (exponent.end !== rsa.end)
|
|
189
193
|
throw refuse("key");
|
|
190
194
|
const n = modulus.bytes;
|
|
191
|
-
|
|
195
|
+
const sizes = sized === 512 ? [SMALL_MODULUS_BYTES] : MODULUS_BYTES;
|
|
196
|
+
if (!sizes.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
192
197
|
throw refuse("key");
|
|
193
198
|
const e = exponent.bytes;
|
|
194
199
|
const expected = named === 17 ? [17] : [1, 0, 1];
|
|
@@ -335,9 +340,64 @@ function isPlainObject(v) {
|
|
|
335
340
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
336
341
|
}
|
|
337
342
|
var MAX_PATH_STEPS = 16;
|
|
343
|
+
var MAX_TEXT_STEPS = 2;
|
|
344
|
+
function isTextStep(step) {
|
|
345
|
+
return isPlainObject(step) && Object.keys(step).length === 1 && step.text === "json";
|
|
346
|
+
}
|
|
347
|
+
function sameStep(a, b) {
|
|
348
|
+
return a === b || isTextStep(a) && isTextStep(b);
|
|
349
|
+
}
|
|
350
|
+
function spellJson(parsed, form) {
|
|
351
|
+
const text = JSON.stringify(parsed);
|
|
352
|
+
if (form !== "php")
|
|
353
|
+
return text;
|
|
354
|
+
return text.replace(/\//g, "\\/").replace(/[\u0080-\uffff]/g, (unit) => `\\u${unit.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
355
|
+
}
|
|
356
|
+
function jsonTextForm(value) {
|
|
357
|
+
if (typeof value !== "string" || !/^[[{]/.test(value))
|
|
358
|
+
return void 0;
|
|
359
|
+
let parsed;
|
|
360
|
+
try {
|
|
361
|
+
parsed = JSON.parse(value);
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
return void 0;
|
|
365
|
+
}
|
|
366
|
+
if (parsed === null || typeof parsed !== "object")
|
|
367
|
+
return void 0;
|
|
368
|
+
for (const form of ["js", "php"]) {
|
|
369
|
+
try {
|
|
370
|
+
if (spellJson(parsed, form) === value)
|
|
371
|
+
return { parsed, form };
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return void 0;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return void 0;
|
|
378
|
+
}
|
|
379
|
+
function jsonText(value) {
|
|
380
|
+
return jsonTextForm(value)?.parsed;
|
|
381
|
+
}
|
|
338
382
|
function isJsonPath(path) {
|
|
339
383
|
return Array.isArray(path) && path.length <= MAX_PATH_STEPS && path.every((step) => typeof step === "string" ? step.length > 0 && !FORBIDDEN_KEYS.has(step) : Number.isSafeInteger(step) && step >= 0);
|
|
340
384
|
}
|
|
385
|
+
function isProfilePath(path) {
|
|
386
|
+
if (!Array.isArray(path) || path.length > MAX_PATH_STEPS)
|
|
387
|
+
return false;
|
|
388
|
+
let texts = 0;
|
|
389
|
+
for (const [i, step] of path.entries()) {
|
|
390
|
+
if (isTextStep(step)) {
|
|
391
|
+
texts += 1;
|
|
392
|
+
if (i === 0 || i === path.length - 1 || isTextStep(path[i - 1]) || texts > MAX_TEXT_STEPS)
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
else if (!isJsonPath([step])) {
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return true;
|
|
400
|
+
}
|
|
341
401
|
function jsonAt(root, path) {
|
|
342
402
|
let node = root;
|
|
343
403
|
for (const step of path) {
|
|
@@ -352,6 +412,42 @@ function jsonAt(root, path) {
|
|
|
352
412
|
}
|
|
353
413
|
return { found: true, value: node };
|
|
354
414
|
}
|
|
415
|
+
function profileAt(root, path) {
|
|
416
|
+
if (!isProfilePath(path))
|
|
417
|
+
return { found: false };
|
|
418
|
+
let node = root;
|
|
419
|
+
for (const step of path) {
|
|
420
|
+
if (isTextStep(step)) {
|
|
421
|
+
const inner = jsonText(node);
|
|
422
|
+
if (inner === void 0)
|
|
423
|
+
return { found: false };
|
|
424
|
+
node = inner;
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
const at = jsonAt(node, [step]);
|
|
428
|
+
if (!at.found)
|
|
429
|
+
return { found: false };
|
|
430
|
+
node = at.value;
|
|
431
|
+
}
|
|
432
|
+
return { found: true, value: node };
|
|
433
|
+
}
|
|
434
|
+
function editAtProfilePath(root, path, edit) {
|
|
435
|
+
const at = profileAt(root, path);
|
|
436
|
+
if (!at.found || !isPlainObject(at.value))
|
|
437
|
+
return false;
|
|
438
|
+
const k = path.findIndex(isTextStep);
|
|
439
|
+
if (k === -1) {
|
|
440
|
+
edit(at.value);
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
const holder = jsonAt(root, path.slice(0, k - 1)).value;
|
|
444
|
+
const key = path[k - 1];
|
|
445
|
+
const text = jsonTextForm(holder[key]);
|
|
446
|
+
if (!text || !editAtProfilePath(text.parsed, path.slice(k + 1), edit))
|
|
447
|
+
return false;
|
|
448
|
+
holder[key] = spellJson(text.parsed, text.form);
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
355
451
|
function roundTrips(parsed, body) {
|
|
356
452
|
try {
|
|
357
453
|
return JSON.stringify(parsed) === body;
|
|
@@ -361,17 +457,17 @@ function roundTrips(parsed, body) {
|
|
|
361
457
|
}
|
|
362
458
|
}
|
|
363
459
|
function sameSteps(a, b) {
|
|
364
|
-
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((step, i) => step
|
|
460
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((step, i) => sameStep(step, b[i]));
|
|
365
461
|
}
|
|
366
462
|
function pathsOverlap(a, b) {
|
|
367
463
|
const n = Math.min(a.length, b.length);
|
|
368
464
|
for (let i = 0; i < n; i += 1)
|
|
369
|
-
if (a[i]
|
|
465
|
+
if (!sameStep(a[i], b[i]))
|
|
370
466
|
return false;
|
|
371
467
|
return true;
|
|
372
468
|
}
|
|
373
469
|
function describePath(path) {
|
|
374
|
-
return path.length ? path.map((step) => typeof step === "number" ? `[${step}]` : `.${step}`).join("").replace(/^\./, "") : "(root)";
|
|
470
|
+
return path.length ? path.map((step) => typeof step === "number" ? `[${step}]` : isTextStep(step) ? "<json>" : `.${step}`).join("").replace(/^\./, "") : "(root)";
|
|
375
471
|
}
|
|
376
472
|
// src/substitution-primitives.js
|
|
377
473
|
var SubstitutionError = class extends Error {
|
|
@@ -420,7 +516,7 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
420
516
|
const path = Array.isArray(spec.path) ? [...spec.path] : spec.path;
|
|
421
517
|
const fields = isPlainObject(spec.fields) ? Object.fromEntries(Object.entries(spec.fields)) : null;
|
|
422
518
|
const remove = Array.isArray(spec.remove) ? [...spec.remove] : spec.remove ?? [];
|
|
423
|
-
if (!
|
|
519
|
+
if (!isProfilePath(path))
|
|
424
520
|
throw new SubstitutionError("refusing substitution path");
|
|
425
521
|
if (!fields || Object.keys(fields).length === 0)
|
|
426
522
|
throw new SubstitutionError("substitutions carry no fields");
|
|
@@ -454,7 +550,7 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
454
550
|
}
|
|
455
551
|
if (!isPlainObject(parsed))
|
|
456
552
|
throw new SubstitutionError("the paused body is not a JSON object");
|
|
457
|
-
const holder =
|
|
553
|
+
const holder = profileAt(parsed, path);
|
|
458
554
|
if (!holder.found || !isPlainObject(holder.value))
|
|
459
555
|
throw new SubstitutionError(`the paused body has no object at ${describePath(path)}`);
|
|
460
556
|
const swaps = /* @__PURE__ */ new Map();
|
|
@@ -506,15 +602,19 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
506
602
|
catch {
|
|
507
603
|
throw new SubstitutionError("the substituted body is not JSON");
|
|
508
604
|
}
|
|
509
|
-
const written =
|
|
605
|
+
const written = profileAt(out, path);
|
|
510
606
|
if (!written.found || !isPlainObject(written.value) || names.some((name) => written.value[name] !== fields[name]) || dummies.some((dummy) => swapped.includes(dummy))) {
|
|
511
607
|
throw new SubstitutionError(`the substitution did not land at ${describePath(path)}`);
|
|
512
608
|
}
|
|
513
609
|
if (remove.length === 0 && set.length === 0)
|
|
514
610
|
return swapped;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
611
|
+
if (remove.length > 0 && !editAtProfilePath(out, path, (object) => {
|
|
612
|
+
for (const key of remove)
|
|
613
|
+
if (Object.prototype.hasOwnProperty.call(object, key))
|
|
614
|
+
delete object[key];
|
|
615
|
+
})) {
|
|
616
|
+
throw new SubstitutionError(`the substitution did not land at ${describePath(path)}`);
|
|
617
|
+
}
|
|
518
618
|
for (const entry of set) {
|
|
519
619
|
const parent = jsonAt(out, entry.path.slice(0, -1));
|
|
520
620
|
if (!parent.found || !isPlainObject(parent.value))
|
package/dist/twoc2p.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: 9dd7f5576d8ac7125656bcf968be5604bf34bcabd516013e51a4768b5d84e791
|
|
4
4
|
// src/sha256.js
|
|
5
5
|
var K = /* @__PURE__ */ new Uint32Array([
|
|
6
6
|
1116352408,
|
|
@@ -146,6 +146,7 @@ var BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
|
146
146
|
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
147
147
|
var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
|
|
148
148
|
var MODULUS_BYTES = [128, 256, 384, 512];
|
|
149
|
+
var SMALL_MODULUS_BYTES = 64;
|
|
149
150
|
var MIN_PADDING = 8;
|
|
150
151
|
var MAX_DRAWS = 16;
|
|
151
152
|
var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
|
|
@@ -156,6 +157,9 @@ function parseRsaPublicKey(key) {
|
|
|
156
157
|
const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
|
|
157
158
|
if (named !== void 0 && named !== 17)
|
|
158
159
|
throw refuse("key");
|
|
160
|
+
const sized = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "bits") ? key.bits : void 0;
|
|
161
|
+
if (sized !== void 0 && sized !== 512)
|
|
162
|
+
throw refuse("key");
|
|
159
163
|
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
160
164
|
throw refuse("key");
|
|
161
165
|
if (typeof pin !== "string" || !SHA256_HEX.test(pin))
|
|
@@ -188,7 +192,8 @@ function parseRsaPublicKey(key) {
|
|
|
188
192
|
if (exponent.end !== rsa.end)
|
|
189
193
|
throw refuse("key");
|
|
190
194
|
const n = modulus.bytes;
|
|
191
|
-
|
|
195
|
+
const sizes = sized === 512 ? [SMALL_MODULUS_BYTES] : MODULUS_BYTES;
|
|
196
|
+
if (!sizes.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
192
197
|
throw refuse("key");
|
|
193
198
|
const e = exponent.bytes;
|
|
194
199
|
const expected = named === 17 ? [17] : [1, 0, 1];
|
|
@@ -684,9 +689,64 @@ function isPlainObject(v) {
|
|
|
684
689
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
685
690
|
}
|
|
686
691
|
var MAX_PATH_STEPS = 16;
|
|
692
|
+
var MAX_TEXT_STEPS = 2;
|
|
693
|
+
function isTextStep(step) {
|
|
694
|
+
return isPlainObject(step) && Object.keys(step).length === 1 && step.text === "json";
|
|
695
|
+
}
|
|
696
|
+
function sameStep(a, b) {
|
|
697
|
+
return a === b || isTextStep(a) && isTextStep(b);
|
|
698
|
+
}
|
|
699
|
+
function spellJson(parsed, form) {
|
|
700
|
+
const text2 = JSON.stringify(parsed);
|
|
701
|
+
if (form !== "php")
|
|
702
|
+
return text2;
|
|
703
|
+
return text2.replace(/\//g, "\\/").replace(/[\u0080-\uffff]/g, (unit) => `\\u${unit.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
704
|
+
}
|
|
705
|
+
function jsonTextForm(value) {
|
|
706
|
+
if (typeof value !== "string" || !/^[[{]/.test(value))
|
|
707
|
+
return void 0;
|
|
708
|
+
let parsed;
|
|
709
|
+
try {
|
|
710
|
+
parsed = JSON.parse(value);
|
|
711
|
+
}
|
|
712
|
+
catch {
|
|
713
|
+
return void 0;
|
|
714
|
+
}
|
|
715
|
+
if (parsed === null || typeof parsed !== "object")
|
|
716
|
+
return void 0;
|
|
717
|
+
for (const form of ["js", "php"]) {
|
|
718
|
+
try {
|
|
719
|
+
if (spellJson(parsed, form) === value)
|
|
720
|
+
return { parsed, form };
|
|
721
|
+
}
|
|
722
|
+
catch {
|
|
723
|
+
return void 0;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return void 0;
|
|
727
|
+
}
|
|
728
|
+
function jsonText(value) {
|
|
729
|
+
return jsonTextForm(value)?.parsed;
|
|
730
|
+
}
|
|
687
731
|
function isJsonPath(path) {
|
|
688
732
|
return Array.isArray(path) && path.length <= MAX_PATH_STEPS && path.every((step) => typeof step === "string" ? step.length > 0 && !FORBIDDEN_KEYS.has(step) : Number.isSafeInteger(step) && step >= 0);
|
|
689
733
|
}
|
|
734
|
+
function isProfilePath(path) {
|
|
735
|
+
if (!Array.isArray(path) || path.length > MAX_PATH_STEPS)
|
|
736
|
+
return false;
|
|
737
|
+
let texts = 0;
|
|
738
|
+
for (const [i, step] of path.entries()) {
|
|
739
|
+
if (isTextStep(step)) {
|
|
740
|
+
texts += 1;
|
|
741
|
+
if (i === 0 || i === path.length - 1 || isTextStep(path[i - 1]) || texts > MAX_TEXT_STEPS)
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
744
|
+
else if (!isJsonPath([step])) {
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return true;
|
|
749
|
+
}
|
|
690
750
|
function jsonAt(root, path) {
|
|
691
751
|
let node = root;
|
|
692
752
|
for (const step of path) {
|
|
@@ -701,6 +761,42 @@ function jsonAt(root, path) {
|
|
|
701
761
|
}
|
|
702
762
|
return { found: true, value: node };
|
|
703
763
|
}
|
|
764
|
+
function profileAt(root, path) {
|
|
765
|
+
if (!isProfilePath(path))
|
|
766
|
+
return { found: false };
|
|
767
|
+
let node = root;
|
|
768
|
+
for (const step of path) {
|
|
769
|
+
if (isTextStep(step)) {
|
|
770
|
+
const inner = jsonText(node);
|
|
771
|
+
if (inner === void 0)
|
|
772
|
+
return { found: false };
|
|
773
|
+
node = inner;
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
const at = jsonAt(node, [step]);
|
|
777
|
+
if (!at.found)
|
|
778
|
+
return { found: false };
|
|
779
|
+
node = at.value;
|
|
780
|
+
}
|
|
781
|
+
return { found: true, value: node };
|
|
782
|
+
}
|
|
783
|
+
function editAtProfilePath(root, path, edit) {
|
|
784
|
+
const at = profileAt(root, path);
|
|
785
|
+
if (!at.found || !isPlainObject(at.value))
|
|
786
|
+
return false;
|
|
787
|
+
const k = path.findIndex(isTextStep);
|
|
788
|
+
if (k === -1) {
|
|
789
|
+
edit(at.value);
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
const holder = jsonAt(root, path.slice(0, k - 1)).value;
|
|
793
|
+
const key = path[k - 1];
|
|
794
|
+
const text2 = jsonTextForm(holder[key]);
|
|
795
|
+
if (!text2 || !editAtProfilePath(text2.parsed, path.slice(k + 1), edit))
|
|
796
|
+
return false;
|
|
797
|
+
holder[key] = spellJson(text2.parsed, text2.form);
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
704
800
|
function roundTrips(parsed, body) {
|
|
705
801
|
try {
|
|
706
802
|
return JSON.stringify(parsed) === body;
|
|
@@ -710,17 +806,17 @@ function roundTrips(parsed, body) {
|
|
|
710
806
|
}
|
|
711
807
|
}
|
|
712
808
|
function sameSteps(a, b) {
|
|
713
|
-
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((step, i) => step
|
|
809
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((step, i) => sameStep(step, b[i]));
|
|
714
810
|
}
|
|
715
811
|
function pathsOverlap(a, b) {
|
|
716
812
|
const n = Math.min(a.length, b.length);
|
|
717
813
|
for (let i = 0; i < n; i += 1)
|
|
718
|
-
if (a[i]
|
|
814
|
+
if (!sameStep(a[i], b[i]))
|
|
719
815
|
return false;
|
|
720
816
|
return true;
|
|
721
817
|
}
|
|
722
818
|
function describePath(path) {
|
|
723
|
-
return path.length ? path.map((step) => typeof step === "number" ? `[${step}]` : `.${step}`).join("").replace(/^\./, "") : "(root)";
|
|
819
|
+
return path.length ? path.map((step) => typeof step === "number" ? `[${step}]` : isTextStep(step) ? "<json>" : `.${step}`).join("").replace(/^\./, "") : "(root)";
|
|
724
820
|
}
|
|
725
821
|
// src/substitution-primitives.js
|
|
726
822
|
var SubstitutionError = class extends Error {
|
|
@@ -769,7 +865,7 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
769
865
|
const path = Array.isArray(spec.path) ? [...spec.path] : spec.path;
|
|
770
866
|
const fields = isPlainObject(spec.fields) ? Object.fromEntries(Object.entries(spec.fields)) : null;
|
|
771
867
|
const remove = Array.isArray(spec.remove) ? [...spec.remove] : spec.remove ?? [];
|
|
772
|
-
if (!
|
|
868
|
+
if (!isProfilePath(path))
|
|
773
869
|
throw new SubstitutionError("refusing substitution path");
|
|
774
870
|
if (!fields || Object.keys(fields).length === 0)
|
|
775
871
|
throw new SubstitutionError("substitutions carry no fields");
|
|
@@ -803,7 +899,7 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
803
899
|
}
|
|
804
900
|
if (!isPlainObject(parsed))
|
|
805
901
|
throw new SubstitutionError("the paused body is not a JSON object");
|
|
806
|
-
const holder =
|
|
902
|
+
const holder = profileAt(parsed, path);
|
|
807
903
|
if (!holder.found || !isPlainObject(holder.value))
|
|
808
904
|
throw new SubstitutionError(`the paused body has no object at ${describePath(path)}`);
|
|
809
905
|
const swaps = /* @__PURE__ */ new Map();
|
|
@@ -855,15 +951,19 @@ function swapMerchantHostedFields(body, spec, ciphertext = ADYEN_JWE) {
|
|
|
855
951
|
catch {
|
|
856
952
|
throw new SubstitutionError("the substituted body is not JSON");
|
|
857
953
|
}
|
|
858
|
-
const written =
|
|
954
|
+
const written = profileAt(out, path);
|
|
859
955
|
if (!written.found || !isPlainObject(written.value) || names.some((name) => written.value[name] !== fields[name]) || dummies.some((dummy) => swapped.includes(dummy))) {
|
|
860
956
|
throw new SubstitutionError(`the substitution did not land at ${describePath(path)}`);
|
|
861
957
|
}
|
|
862
958
|
if (remove.length === 0 && set.length === 0)
|
|
863
959
|
return swapped;
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
960
|
+
if (remove.length > 0 && !editAtProfilePath(out, path, (object) => {
|
|
961
|
+
for (const key of remove)
|
|
962
|
+
if (Object.prototype.hasOwnProperty.call(object, key))
|
|
963
|
+
delete object[key];
|
|
964
|
+
})) {
|
|
965
|
+
throw new SubstitutionError(`the substitution did not land at ${describePath(path)}`);
|
|
966
|
+
}
|
|
867
967
|
for (const entry of set) {
|
|
868
968
|
const parent = jsonAt(out, entry.path.slice(0, -1));
|
|
869
969
|
if (!parent.found || !isPlainObject(parent.value))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SLASH } from '../url-mask-parts.js';
|
|
2
|
+
/**
|
|
3
|
+
* BlueSnap's payment-fields token is the card requests' only credential: whoever holds it binds a card to the
|
|
4
|
+
* merchant's token for the token's 60 minutes (payment-core processors/bluesnap.js). On BlueSnap's hosts the segment
|
|
5
|
+
* after /payment-fields-tokens/ reads {token}, and so does any run of 64 hex digits with its suffix, in any case:
|
|
6
|
+
* https://ws1.bluesnap.com/services/2/payment-fields-tokens/{token}.
|
|
7
|
+
*/
|
|
8
|
+
const HOST = /^(?:ws1|ws2|sandpay)\.bluesnap\.com\.?$/i;
|
|
9
|
+
const TOKEN_PATH = new RegExp(`(${SLASH}payment-fields-tokens${SLASH}+)[^/]*`, 'gi');
|
|
10
|
+
const TOKEN = /[0-9a-f]{64}_[12]?/gi;
|
|
11
|
+
export const mask = {
|
|
12
|
+
host: HOST,
|
|
13
|
+
named: /bluesnap\.com/i,
|
|
14
|
+
mask: (path) => path.replace(TOKEN_PATH, '$1{token}').replace(TOKEN, '{token}'),
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oceanpayment's hosted payment page posts the card to /gateway/sendPay;jsessionid=<session>, and the session in the path
|
|
3
|
+
* names the payment the page holds (payment-core processors/oceanpayment.js); the page itself and its other calls carry
|
|
4
|
+
* the same session the same way. On Oceanpayment's hosts the session after `;jsessionid=`, with the `;` or the `=`
|
|
5
|
+
* escaped once or more, reads {session}: https://secure.oceanpayment.com/gateway/sendPay;jsessionid={session}.
|
|
6
|
+
*/
|
|
7
|
+
const OCEANPAYMENT_HOST = /(?:^|\.)oceanpayment\.com\.?$/i;
|
|
8
|
+
const OCEANPAYMENT_SESSION = /((?:;|%(?:25)*3b)jsessionid(?:=|%(?:25)*3d))[^/?#;]*/gi;
|
|
9
|
+
export const mask = {
|
|
10
|
+
host: OCEANPAYMENT_HOST,
|
|
11
|
+
named: /oceanpayment\.com/i,
|
|
12
|
+
mask: (path) => path.replace(OCEANPAYMENT_SESSION, '$1{session}'),
|
|
13
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SLASH } from '../url-mask-parts.js';
|
|
2
|
+
/**
|
|
3
|
+
* PayPlug's payment page (payment-core processors/payplug.js): https://secure.payplug.com/pay/<payment id>, or
|
|
4
|
+
* /pay/test/<payment id> for a test payment. The id alone opens that payment's page, with its merchant and its total,
|
|
5
|
+
* and pays it, so on PayPlug's page host the id after /pay/ or /pay/test/ reads {payment}, in either case and behind
|
|
6
|
+
* any slash SLASH reads: https://secure.payplug.com/pay/{payment}.
|
|
7
|
+
*/
|
|
8
|
+
const PAYPLUG_PAYMENT = new RegExp(`(${SLASH}pay${SLASH}+(?:test${SLASH}+)?)[A-Za-z0-9]+`, 'gi');
|
|
9
|
+
export const mask = {
|
|
10
|
+
host: /(?:^|\.)secure\.payplug\.com\.?$/i,
|
|
11
|
+
named: /secure\.payplug\.com/i,
|
|
12
|
+
mask: (path) => path.replace(PAYPLUG_PAYMENT, '$1{payment}'),
|
|
13
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On a VTEX account's vault host (<account>.vtexvault.com, and api.vtexvault.com, Ollie's fallback) the transaction id
|
|
3
|
+
* after /transactions/ is all VTEX asks of a card post to that payment: its payments endpoint takes no authentication
|
|
4
|
+
* (payment-core processors/vtex_payments.js). So a run of 32 hex digits or more there reads {transaction}, in any case.
|
|
5
|
+
* The pattern reads a percent escape as one unit and keeps it, so the hex digits of an escaped slash before the id
|
|
6
|
+
* (%2F, %252F) never start a match and leave the id's last digits showing.
|
|
7
|
+
*/
|
|
8
|
+
const HEX_OR_ESCAPE = /%(?:25)*[0-9a-f]{2}|[0-9a-f]{32,}/gi;
|
|
9
|
+
function maskVtexTransaction(path) {
|
|
10
|
+
return path.replace(HEX_OR_ESCAPE, (token) => (token.startsWith('%') ? token : '{transaction}'));
|
|
11
|
+
}
|
|
12
|
+
export const mask = { host: /^[a-z0-9-]{1,63}\.vtexvault\.com\.?$/i, named: /vtexvault\.com/i, mask: maskVtexTransaction };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { UrlMask } from './url-mask-parts.js';
|
|
2
|
-
/** The masks of the processors registered in src/url-masks/:
|
|
2
|
+
/** The masks of the processors registered in src/url-masks/: bluesnap, oceanpayment, payplug, vtex_payments. */
|
|
3
3
|
export declare const URL_MASKS: readonly UrlMask[];
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { mask as mask0 } from './url-masks/bluesnap.js';
|
|
2
|
+
import { mask as mask1 } from './url-masks/oceanpayment.js';
|
|
3
|
+
import { mask as mask2 } from './url-masks/payplug.js';
|
|
4
|
+
import { mask as mask3 } from './url-masks/vtex_payments.js';
|
|
5
|
+
/** The masks of the processors registered in src/url-masks/: bluesnap, oceanpayment, payplug, vtex_payments. */
|
|
6
|
+
export const URL_MASKS = [mask0, mask1, mask2, mask3];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: c5965a6e2cafc3d6c3a01bc6bd55e1deb8e64fe64fd9a556f80b73f5189d4cef
|
|
4
4
|
// src/deep-freeze.js
|
|
5
5
|
function deepFreeze(value) {
|
|
6
6
|
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
@@ -16,6 +16,41 @@ function isPlainObject(v) {
|
|
|
16
16
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
17
17
|
}
|
|
18
18
|
var MAX_PATH_STEPS = 16;
|
|
19
|
+
function isTextStep(step) {
|
|
20
|
+
return isPlainObject(step) && Object.keys(step).length === 1 && step.text === "json";
|
|
21
|
+
}
|
|
22
|
+
function spellJson(parsed, form) {
|
|
23
|
+
const text = JSON.stringify(parsed);
|
|
24
|
+
if (form !== "php")
|
|
25
|
+
return text;
|
|
26
|
+
return text.replace(/\//g, "\\/").replace(/[\u0080-\uffff]/g, (unit) => `\\u${unit.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
27
|
+
}
|
|
28
|
+
function jsonTextForm(value) {
|
|
29
|
+
if (typeof value !== "string" || !/^[[{]/.test(value))
|
|
30
|
+
return void 0;
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = JSON.parse(value);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
if (parsed === null || typeof parsed !== "object")
|
|
39
|
+
return void 0;
|
|
40
|
+
for (const form of ["js", "php"]) {
|
|
41
|
+
try {
|
|
42
|
+
if (spellJson(parsed, form) === value)
|
|
43
|
+
return { parsed, form };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return void 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
function jsonText(value) {
|
|
52
|
+
return jsonTextForm(value)?.parsed;
|
|
53
|
+
}
|
|
19
54
|
function isJsonPath(path) {
|
|
20
55
|
return Array.isArray(path) && path.length <= MAX_PATH_STEPS && path.every((step) => typeof step === "string" ? step.length > 0 && !FORBIDDEN_KEYS.has(step) : Number.isSafeInteger(step) && step >= 0);
|
|
21
56
|
}
|
|
@@ -49,7 +84,12 @@ function valuesIgnoringCase(root, path) {
|
|
|
49
84
|
for (const step of path) {
|
|
50
85
|
const next = [];
|
|
51
86
|
for (const node of nodes) {
|
|
52
|
-
if (
|
|
87
|
+
if (isTextStep(step)) {
|
|
88
|
+
const inner = jsonText(node);
|
|
89
|
+
if (inner !== void 0)
|
|
90
|
+
next.push(inner);
|
|
91
|
+
}
|
|
92
|
+
else if (typeof step === "number") {
|
|
53
93
|
if (Array.isArray(node) && Number.isSafeInteger(step) && step >= 0 && step < node.length)
|
|
54
94
|
next.push(node[step]);
|
|
55
95
|
}
|