@agent-cards/sdk 0.23.11 → 0.23.12

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.
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 3f5ac5b4125cab96cc0851e9b1fe705aa96635e1df05b9216e951140fb47cd43
3
+ // artifact-sha256: b3391e7d6137e269555a23062ce848aa7a7f6f02e626fd568b1e9597c02e5ce6
4
4
  // src/card-number-key.js
5
5
  var CARD_NUMBER_KEY = /^(number|card_number|cardnumber|cardNum|card_num|pan)$/i;
6
6
  // src/json-path.js
@@ -348,8 +348,79 @@ function amadeusBodyKind(body) {
348
348
  return record2(value.data) && holdsPan(value.data.mopdata) ? "card" : "other";
349
349
  return "other";
350
350
  }
351
+ // src/paddle-vgs.js
352
+ var PADDLE_VGS_PSP = "paddle_vgs";
353
+ var PADDLE_VGS_CARDS_URLS = /* @__PURE__ */ Object.freeze({
354
+ production: "https://vault.paddle.com/cards",
355
+ sandbox: "https://sandbox-vault.paddle.com/cards"
356
+ });
357
+ var BODY_LIMIT2 = 4096;
358
+ var ROOT_KEYS2 = /* @__PURE__ */ Object.freeze(["data"]);
359
+ var DATA_KEYS = /* @__PURE__ */ Object.freeze(["type", "attributes"]);
360
+ var ATTRIBUTE_KEYS = /* @__PURE__ */ Object.freeze(["pan", "cvc", "exp_month", "exp_year", "cardholder"]);
361
+ var CARD_NUMBER4 = /^[0-9]{12,19}$/;
362
+ var SECURITY_CODE2 = /^[0-9]{3,4}$/;
363
+ var NAME_LIMIT = 256;
364
+ var CONTROL = /[\u0000-\u001f\u007f]/;
365
+ var cardLikeName = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
366
+ var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
367
+ var sameKeys = (value, keys) => {
368
+ const own = Object.keys(value);
369
+ return own.length === keys.length && own.every((key, at) => key === keys[at]);
370
+ };
371
+ var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
372
+ var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
373
+ function paddleVgsEnvironment(url) {
374
+ if (url === PADDLE_VGS_CARDS_URLS.production)
375
+ return "production";
376
+ if (url === PADDLE_VGS_CARDS_URLS.sandbox)
377
+ return "sandbox";
378
+ return null;
379
+ }
380
+ function isPaddleVgsCardsUrl(url) {
381
+ return paddleVgsEnvironment(url) !== null;
382
+ }
383
+ function readBody2(body) {
384
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT2)
385
+ return null;
386
+ let value;
387
+ try {
388
+ value = JSON.parse(body);
389
+ if (!record3(value) || JSON.stringify(value) !== body)
390
+ return null;
391
+ }
392
+ catch {
393
+ return null;
394
+ }
395
+ return value;
396
+ }
397
+ function paddleVgsBodyVerdict(body) {
398
+ const value = readBody2(body);
399
+ if (value === null || !sameKeys(value, ROOT_KEYS2) || !record3(value.data) || !sameKeys(value.data, DATA_KEYS) || value.data.type !== "cards" || !record3(value.data.attributes) || !sameKeys(value.data.attributes, ATTRIBUTE_KEYS)) {
400
+ return refuse4("paddle_vgs_body_unsupported");
401
+ }
402
+ const card = value.data.attributes;
403
+ const holder = card.cardholder;
404
+ if (typeof card.pan !== "string" || !CARD_NUMBER4.test(card.pan) || typeof card.cvc !== "string" || !SECURITY_CODE2.test(card.cvc) || !Number.isInteger(card.exp_month) || card.exp_month < 1 || card.exp_month > 12 || !Number.isInteger(card.exp_year) || card.exp_year < 0 || card.exp_year > 99 || !record3(holder) || !sameKeys(holder, ["name"]) || typeof holder.name !== "string" || holder.name.length > NAME_LIMIT || CONTROL.test(holder.name) || cardLikeName(holder.name)) {
405
+ return refuse4("paddle_vgs_body_unsupported");
406
+ }
407
+ return CARD4;
408
+ }
409
+ var pin2 = (fields) => Object.freeze({
410
+ ...fields,
411
+ origins: Object.freeze([...fields.origins]),
412
+ sellerClaim: fields.sellerClaim ? Object.freeze({ ...fields.sellerClaim }) : null
413
+ });
414
+ var PADDLE_VGS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
415
+ pin2({ id: "rectangle_pro", merchant: "Rectangle Pro", origins: ["https://rectangleapp.com"], sellerClaim: null })
416
+ ]);
351
417
  // src/card-fields.js
352
418
  function processorGate(recognizer, url, body) {
419
+ if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
420
+ if (url !== void 0 && !isPaddleVgsCardsUrl(url))
421
+ return { verdict: "refuse", code: "paddle_vgs_url_refused" };
422
+ return paddleVgsBodyVerdict(body);
423
+ }
353
424
  if (recognizer && recognizer.psp === GRAVY_PSP)
354
425
  return gravyBodyVerdict(body);
355
426
  if (recognizer && recognizer.psp === MONERIS_PSP) {
@@ -470,12 +541,12 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
470
541
  var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
471
542
  var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
472
543
  var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
473
- var BODY_LIMIT2 = 16384;
544
+ var BODY_LIMIT3 = 16384;
474
545
  var RESPONSE_LIMIT = 32768;
475
- var ROOT_KEYS2 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
546
+ var ROOT_KEYS3 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
476
547
  var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
477
548
  var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
478
- var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
549
+ var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
479
550
  var owns4 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
480
551
  var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
481
552
  var text = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
@@ -498,7 +569,7 @@ function isPrimerTokenizeUrl(url, method = "POST") {
498
569
  return parsed.href === url && parsed.protocol === "https:" && !parsed.port && !parsed.username && !parsed.password && !parsed.search && !parsed.hash && PRIMER_PCI_HOSTS.includes(parsed.hostname) && parsed.pathname === PRIMER_TOKENIZE_PATH;
499
570
  }
500
571
  function judgeBody(body) {
501
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT2)
572
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT3)
502
573
  return null;
503
574
  let value;
504
575
  try {
@@ -507,12 +578,12 @@ function judgeBody(body) {
507
578
  catch {
508
579
  return null;
509
580
  }
510
- if (!record3(value) || !roundTrips(value, body))
581
+ if (!record4(value) || !roundTrips(value, body))
511
582
  return null;
512
- if (!Object.keys(value).every((key) => ROOT_KEYS2.includes(key)) || !owns4(value, "paymentInstrument"))
583
+ if (!Object.keys(value).every((key) => ROOT_KEYS3.includes(key)) || !owns4(value, "paymentInstrument"))
513
584
  return null;
514
585
  const instrument = value.paymentInstrument;
515
- if (!record3(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns4(instrument, key)))
586
+ if (!record4(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns4(instrument, key)))
516
587
  return null;
517
588
  if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH, instrument.expirationMonth) || !exact(YEAR, instrument.expirationYear))
518
589
  return null;
@@ -540,7 +611,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
540
611
  var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
541
612
  var API_VERSION = /^2\.[0-9]{1,2}$/;
542
613
  function readHeaders(headers) {
543
- if (!record3(headers))
614
+ if (!record4(headers))
544
615
  return null;
545
616
  const folded = /* @__PURE__ */ new Map();
546
617
  for (const [name, value] of Object.entries(headers)) {
@@ -587,7 +658,7 @@ function onTokenizePath(url) {
587
658
  }
588
659
  }
589
660
  function primerTokenizeRefusal(request) {
590
- if (!record3(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
661
+ if (!record4(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
591
662
  return "unsupported";
592
663
  return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
593
664
  }
@@ -602,7 +673,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
602
673
  return "unsupported";
603
674
  if (new URL(url).hostname !== LIVE_PCI_HOST)
604
675
  return null;
605
- return primerCardOnFileDisclosure(url, policy) && record3(options) && options.keepOnFile === true ? null : "keep_on_file";
676
+ return primerCardOnFileDisclosure(url, policy) && record4(options) && options.keepOnFile === true ? null : "keep_on_file";
606
677
  }
607
678
  function primerRefusalMessage(reason) {
608
679
  if (reason === "keep_on_file")
@@ -686,7 +757,7 @@ function readAnswer(body) {
686
757
  return null;
687
758
  try {
688
759
  const value = JSON.parse(body);
689
- return record3(value) ? value : null;
760
+ return record4(value) ? value : null;
690
761
  }
691
762
  catch {
692
763
  return null;
@@ -695,16 +766,16 @@ function readAnswer(body) {
695
766
  var tokenValue = (value) => exact(TOKEN, value) && !panLike(value);
696
767
  var optional = (value, key, check) => !owns4(value, key) || value[key] === null || check(value[key]);
697
768
  function cardDetails(data) {
698
- if (!record3(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
769
+ if (!record4(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
699
770
  return null;
700
- if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record3))
771
+ if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record4))
701
772
  return null;
702
773
  const safe = { last4Digits: data.last4Digits };
703
774
  for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
704
775
  if (owns4(data, key) && data[key] !== null)
705
776
  safe[key] = data[key];
706
777
  }
707
- if (record3(data.binData)) {
778
+ if (record4(data.binData)) {
708
779
  const bin = {};
709
780
  for (const key of BIN_KEYS) {
710
781
  if (!owns4(data.binData, key) || data.binData[key] === null)
@@ -720,7 +791,7 @@ function cardDetails(data) {
720
791
  function threeDsSummary(value) {
721
792
  if (value === void 0 || value === null)
722
793
  return null;
723
- if (!record3(value) || !exact(CODE, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
794
+ if (!record4(value) || !exact(CODE, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
724
795
  return void 0;
725
796
  const safe = { responseCode: value.responseCode };
726
797
  for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
@@ -748,7 +819,7 @@ function rebuildToken(value) {
748
819
  }
749
820
  function primerErrorId(body) {
750
821
  const value = readAnswer(body);
751
- const id = value && record3(value.error) ? value.error.errorId : null;
822
+ const id = value && record4(value.error) ? value.error.errorId : null;
752
823
  return exact(ERROR_ID, id) && !panLike(id) ? id : null;
753
824
  }
754
825
  function matchesCard(details, card) {
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 0abf1d62c20303c4496e1d26b64b1c36ad517919d23f2d14e3f0b6763694551f
3
+ // artifact-sha256: dd47d4d2d97c39acb2385272d1a2bf3e647741839234283b848b67fd5ce5c114
4
4
  // src/deep-freeze.js
5
5
  function deepFreeze(value) {
6
6
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
@@ -1418,6 +1418,33 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1418
1418
  // A checked "remember" asks Worldline to keep the card for later purchases.
1419
1419
  token: "remember"
1420
1420
  }
1421
+ },
1422
+ {
1423
+ psp: "paddle_vgs",
1424
+ // Paddle's checkout frame (buy.paddle.com) on a checkout whose card method names VGS as its
1425
+ // tokenizer: one JSON:API POST to /cards on vault.paddle.com, a VGS inbound proxy Paddle runs
1426
+ // (sandbox-vault.paddle.com in test), with the checkout's own bearer JWT. PAN@
1427
+ // data.attributes.pan, with cvc, exp_month (1 to 12) and exp_year (two digits) beside it, all
1428
+ // numbers but the pan and the cvc. paddle-vgs.js holds the request rule the pause decision, the
1429
+ // API's create, the prepared bind and the device all read: exactly one of the two URLs, the
1430
+ // frame's Content-Type and bearer, and the frame's body byte for byte. VGS answers with the
1431
+ // stored card's id, which the frame sends on to Paddle's /pay. The frame aborts this request
1432
+ // after 10 seconds and sends it once more, so the lane is prepared only (preparationRequired):
1433
+ // the cardholder approves before the agent clicks Pay. The card leaves the cardholder's device
1434
+ // by a direct fetch, since the proxy answers any origin. The checkouts that name TokenEx or
1435
+ // Spreedly send the card elsewhere and are not this entry.
1436
+ // Ships dark: served only to a client that declares `paddle_vgs_cards`, gated off for every org
1437
+ // until an operator lists one (`paddle_vgs:<org>`), and autopilot never sends this request
1438
+ // (autopilot.js DEVICE_REPLAY_REFUSED_OPERATIONS). The environment is pinned (S7):
1439
+ // sandbox-vault only on test rows and only with documented test cards, vault only on live rows.
1440
+ capability: "paddle_vgs_cards",
1441
+ match: "(?:sandbox-)?vault\\.paddle\\.com/cards",
1442
+ hosts: ["^vault\\.paddle\\.com$", "^sandbox-vault\\.paddle\\.com$"],
1443
+ sandboxHosts: ["^sandbox-vault\\.paddle\\.com$"],
1444
+ hostEnvironmentPinned: true,
1445
+ preparationRequired: true,
1446
+ encoding: "json",
1447
+ passthroughHeaders: ["^authorization$"]
1421
1448
  }
1422
1449
  ]);
1423
1450
  var PSP_RECOGNIZERS = deepFreeze(PROCESSOR_DEFINITIONS.map(({ compose, encryptedCardFields, deviceSteps, deviceEncrypt, ...definition }) => definition));
@@ -1520,6 +1547,15 @@ var pin = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fiel
1520
1547
  var MONERIS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
1521
1548
  pin({ id: "jack_org_raisin", merchant: "Jack.org", origins: ["https://jack.akaraisin.com"], profileIds: ["htL7TR9H7ICYN2B"] })
1522
1549
  ]);
1550
+ // src/paddle-vgs.js
1551
+ var pin2 = (fields) => Object.freeze({
1552
+ ...fields,
1553
+ origins: Object.freeze([...fields.origins]),
1554
+ sellerClaim: fields.sellerClaim ? Object.freeze({ ...fields.sellerClaim }) : null
1555
+ });
1556
+ var PADDLE_VGS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
1557
+ pin2({ id: "rectangle_pro", merchant: "Rectangle Pro", origins: ["https://rectangleapp.com"], sellerClaim: null })
1558
+ ]);
1523
1559
  // src/cybersource-secure-acceptance.js
1524
1560
  var SA_BODY_LIMIT = 32 * 1024;
1525
1561
  var SA_REPLY_LIMIT = 64 * 1024;
@@ -1607,6 +1643,7 @@ var ALLOWED_MEDIA_TYPES = {
1607
1643
  jwe: ["application/jwt"]
1608
1644
  };
1609
1645
  var JWE_CONTENT_TYPE = "application/jwt; charset=utf-8";
1646
+ var PADDLE_VGS_MEDIA_TYPE = "application/vnd.api+json";
1610
1647
  function contentTypeFor(pspOrEntry, headers) {
1611
1648
  const rec = trustedClientRecognizer(pspOrEntry);
1612
1649
  if (rec.encoding === "jwe") {
@@ -1616,6 +1653,13 @@ function contentTypeFor(pspOrEntry, headers) {
1616
1653
  throw new Error("Refusing to pay: this processor takes its sealed card only as application/jwt.");
1617
1654
  return JWE_CONTENT_TYPE;
1618
1655
  }
1656
+ if (rec.psp === "paddle_vgs") {
1657
+ const captured = Object.entries(headers || {}).find(([k]) => /^content-type$/i.test(k));
1658
+ if (!captured || typeof captured[1] !== "string" || captured[1].trim().toLowerCase() !== PADDLE_VGS_MEDIA_TYPE) {
1659
+ throw new Error("Refusing to pay: this processor takes its card only as application/vnd.api+json.");
1660
+ }
1661
+ return PADDLE_VGS_MEDIA_TYPE;
1662
+ }
1619
1663
  const encoding = rec && rec.encoding === "form" ? "form" : "json";
1620
1664
  const allowed = ALLOWED_MEDIA_TYPES[encoding];
1621
1665
  const fallback = allowed[0];
@@ -1635,6 +1679,8 @@ function replayHeaders(pspOrEntry, captured = {}) {
1635
1679
  const headers = { "content-type": contentTypeFor(rec, captured) };
1636
1680
  if (rec.psp === "creditguard")
1637
1681
  headers.accept = "application/json";
1682
+ if (rec.psp === "paddle_vgs")
1683
+ headers.accept = PADDLE_VGS_MEDIA_TYPE;
1638
1684
  for (const [name, value] of Object.entries(captured)) {
1639
1685
  if (rec.headers.some((pattern) => pattern.test(name)) && !HEADER_NEVER_FORWARD.test(name))
1640
1686
  headers[name] = value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-cards/sdk",
3
- "version": "0.23.11",
3
+ "version": "0.23.12",
4
4
  "description": "Agentcard's SDK: one client, Agentcard, with two modules. checkout pauses a browser purchase and pays it with the person's own card; voice connects a person to your product once and approves a purchase by voice inside it. Card data never enters your process.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -27,7 +27,7 @@
27
27
  "_comment_build": "The public SDK keeps zero runtime dependencies. Its build vendors deterministic metadata and substitution artifacts from the internal payment core, and the voice streaming door from packages/voice/src/core (the phone package, @agent-cards/voice, ships it to phones); TypeScript remains pinned.",
28
28
  "build": "node ../payment-core/scripts/build.mjs && node scripts/generate-payment-core.mjs && node scripts/generate-voice-stream.mjs && npx -y -p typescript@5.9.3 tsc && node scripts/generate-preflight-contract.mjs",
29
29
  "prepublishOnly": "pnpm build",
30
- "test": "node test.mjs && node --test lifecycle.test.mjs merchant-abort.test.mjs preparation.test.mjs braintree.test.mjs pre-claim.test.mjs ekashu.test.mjs paypal-hosted-fields.test.mjs cybersource-secure-acceptance.test.mjs autopilot.test.mjs stripe-checkout.test.mjs stripe-setup.test.mjs stripe-legacy-checkout.test.mjs payment-core.test.mjs prepared-processor.test.mjs merchant-hosted.test.mjs merchant-total.test.mjs sandbox-declaration.test.mjs minimum-delay.test.mjs paysafe.test.mjs payu.test.mjs attachment.test.mjs worker-targets.test.mjs mercado-checkout.test.mjs mercado-polling.test.mjs amadeus.test.mjs pelecard.test.mjs aci.test.mjs primer.test.mjs payrails.test.mjs elavon-converge.test.mjs voice.test.mjs agentcard.test.mjs buy.test.mjs readme.test.mjs gmo.test.mjs cybersource-flex.test.mjs juspay-gate.test.mjs card-endpoint.test.mjs card-endpoint-fastspring.test.mjs card-endpoint-navigation.test.mjs merchant-session-probe.test.mjs datatrans.test.mjs authorize-net-dpm.test.mjs creditguard.test.mjs eprotect.test.mjs wspay.test.mjs shiji-sts.test.mjs worldline-mycheckout.test.mjs verifone.test.mjs gravy.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs",
30
+ "test": "node test.mjs && node --test lifecycle.test.mjs merchant-abort.test.mjs preparation.test.mjs braintree.test.mjs pre-claim.test.mjs ekashu.test.mjs paypal-hosted-fields.test.mjs cybersource-secure-acceptance.test.mjs autopilot.test.mjs stripe-checkout.test.mjs stripe-setup.test.mjs stripe-legacy-checkout.test.mjs payment-core.test.mjs prepared-processor.test.mjs merchant-hosted.test.mjs merchant-total.test.mjs sandbox-declaration.test.mjs minimum-delay.test.mjs paysafe.test.mjs payu.test.mjs attachment.test.mjs worker-targets.test.mjs mercado-checkout.test.mjs mercado-polling.test.mjs amadeus.test.mjs pelecard.test.mjs aci.test.mjs primer.test.mjs payrails.test.mjs elavon-converge.test.mjs voice.test.mjs agentcard.test.mjs buy.test.mjs readme.test.mjs gmo.test.mjs cybersource-flex.test.mjs juspay-gate.test.mjs card-endpoint.test.mjs card-endpoint-fastspring.test.mjs card-endpoint-navigation.test.mjs merchant-session-probe.test.mjs datatrans.test.mjs authorize-net-dpm.test.mjs creditguard.test.mjs eprotect.test.mjs wspay.test.mjs shiji-sts.test.mjs worldline-mycheckout.test.mjs verifone.test.mjs gravy.test.mjs paddle-vgs.test.mjs redact-url.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs",
31
31
  "test:browser": "node browser.test.mjs && node stripe-browser.test.mjs && node preparation-browser.test.mjs && node checkout-com-browser.test.mjs && node paysafe-preparation-browser.test.mjs && node owned-shop-browser.test.mjs && node spreedly-browser.test.mjs && node worker-browser.test.mjs && node amadeus-browser.test.mjs && node adyen-merchant-hosted-browser.test.mjs && node adyen-merchant-frames-browser.test.mjs && node fiserv-browser.test.mjs && node gmo-browser.test.mjs && node cybersource-flex-browser.test.mjs && node juspay-browser.test.mjs && node card-endpoint-browser.test.mjs && node datatrans-browser.test.mjs && node authorize-net-dpm-browser.test.mjs && node pelecard-browser.test.mjs && node aci-browser.test.mjs && node creditguard-browser.test.mjs && node primer-browser.test.mjs && node payrails-browser.test.mjs && node elavon-converge-browser.test.mjs && node eprotect-browser.test.mjs && node wspay-browser.test.mjs && node shiji-sts-browser.test.mjs && node worldline-mycheckout-browser.test.mjs && node paypal-hosted-fields-browser.test.mjs && node cybersource-secure-acceptance-browser.test.mjs && node gravy-browser.test.mjs",
32
32
  "check:payment-core": "node scripts/generate-payment-core.mjs --check",
33
33
  "check:voice-stream": "node scripts/generate-voice-stream.mjs --check",