@agent-cards/sdk 0.23.21 → 0.23.23
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 +36 -0
- package/PREFLIGHT.md +4 -0
- package/README.md +53 -4
- package/dist/aci.generated.js +3 -3
- package/dist/agent-amount.generated.d.ts +7 -0
- package/dist/agent-amount.generated.js +3 -0
- package/dist/amadeus-checkout.generated.d.ts +6 -1
- package/dist/amadeus-checkout.generated.js +26 -2
- package/dist/capabilities.generated.d.ts +2 -0
- package/dist/capabilities.generated.js +3 -0
- package/dist/card-fields.generated.js +2574 -186
- package/dist/cdp.js +103 -29
- package/dist/client.d.ts +130 -9
- package/dist/client.js +304 -115
- package/dist/creditguard.generated.js +4 -2
- package/dist/cse-body.js +11 -0
- package/dist/ebanx.d.ts +1 -1
- package/dist/ebanx.js +1 -1
- package/dist/eximbay.d.ts +46 -0
- package/dist/eximbay.js +69 -0
- package/dist/hosted-entry.js +2 -1
- package/dist/hosted-form.d.ts +5 -0
- package/dist/hosted-form.js +5 -0
- package/dist/lifecycle.d.ts +9 -4
- package/dist/lifecycle.js +16 -4
- package/dist/paygent.generated.d.ts +60 -0
- package/dist/paygent.generated.js +425 -0
- package/dist/payrexx.d.ts +91 -0
- package/dist/payrexx.generated.d.ts +91 -0
- package/dist/payrexx.generated.js +536 -0
- package/dist/payrexx.js +141 -0
- package/dist/paytrail.d.ts +58 -0
- package/dist/paytrail.js +98 -0
- package/dist/pre-claim.d.ts +27 -0
- package/dist/pre-claim.js +175 -20
- package/dist/prepared-processor.d.ts +7 -2
- package/dist/prepared-processor.js +16 -2
- package/dist/primer.generated.js +2709 -321
- package/dist/registry.d.ts +4 -3
- package/dist/registry.js +12 -4
- package/dist/sbps.d.ts +57 -0
- package/dist/sbps.generated.d.ts +96 -0
- package/dist/sbps.generated.js +427 -0
- package/dist/sbps.js +90 -0
- package/dist/stripe-checkout.generated.js +744 -27
- package/dist/toast-seal.generated.d.ts +37 -0
- package/dist/toast-seal.generated.js +625 -0
- package/dist/toast.generated.d.ts +41 -0
- package/dist/toast.generated.js +113 -0
- package/dist/transbank.d.ts +33 -0
- package/dist/transbank.js +62 -0
- package/dist/url-mask-parts.d.ts +24 -0
- package/dist/url-mask-parts.js +22 -0
- package/dist/url-masks.generated.d.ts +3 -0
- package/dist/url-masks.generated.js +2 -0
- package/package.json +4 -4
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
declare var TOAST_PSP: string;
|
|
2
|
+
declare var TOAST_CAPABILITY: string;
|
|
3
|
+
declare var TOAST_OPERATION: string;
|
|
4
|
+
declare var TOAST_PAYMENT_METHODS_URL: string;
|
|
5
|
+
declare var TOAST_KEY_ID: string;
|
|
6
|
+
declare var TOAST_KEY: Readonly<{
|
|
7
|
+
spki: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkq50dXdz/fQOwYUswZRXgh5Vghs1tcJZCv2goNsC5BO3dXC/EiejcApaE/fKVMespzDNSLsQHXrWHegpE2piyeBwMzpTbHrCG3v6MnG6Nu+9dBYxPS4T9cNMsf0V/iCPiiaTXib6r8IfOjVZTTas2nKGZEtiDfYJIS3bJ/f30SMP4dAFILvzXGALeqleB/psQ8AFc/qUZf7VZpRnoGtKoo8wD253xTmDdaiKqr09bcJZxhTWsCB9aYouqdbl6y9/5Lu+MtyBkj7LI05g5QqDSfVax0sp/Fe7RY5SYxwlR4GlMonwtbvFTMKsr6dZ1uLuNjHA/6dm+112Uqn/AxrKGwIDAQAB";
|
|
8
|
+
sha256: "5475b78c9577b1258615286307547aba18c52faa6fd7d60ad0cfcb996e21ad0e";
|
|
9
|
+
}>;
|
|
10
|
+
declare var TOAST_CIPHERTEXT_BYTES: number;
|
|
11
|
+
declare var TOAST_SUBSTITUTION: Readonly<{
|
|
12
|
+
at: "card";
|
|
13
|
+
fields: readonly string[];
|
|
14
|
+
}>;
|
|
15
|
+
declare var TOAST_REFUSAL_CODES: readonly string[];
|
|
16
|
+
declare function isToastPaymentMethodsUrl(url: any): boolean;
|
|
17
|
+
declare function isToastHost(url: any): boolean;
|
|
18
|
+
declare function isToastCiphertext(value: any): boolean;
|
|
19
|
+
declare function readToastBody(body: any): Readonly<{
|
|
20
|
+
ok: false;
|
|
21
|
+
code: any;
|
|
22
|
+
}> | Readonly<{
|
|
23
|
+
ok: false;
|
|
24
|
+
wallet: true;
|
|
25
|
+
}> | Readonly<{
|
|
26
|
+
ok: boolean;
|
|
27
|
+
sessionSecret: any;
|
|
28
|
+
postalCode: any;
|
|
29
|
+
cardData: any;
|
|
30
|
+
}>;
|
|
31
|
+
declare function toastBodyVerdict(body: any): Readonly<{
|
|
32
|
+
verdict: "card";
|
|
33
|
+
}> | Readonly<{
|
|
34
|
+
verdict: "continue";
|
|
35
|
+
}> | Readonly<{
|
|
36
|
+
verdict: "refuse";
|
|
37
|
+
code: any;
|
|
38
|
+
}>;
|
|
39
|
+
declare function toastRequestRefusal(request: any): any;
|
|
40
|
+
declare function toastRefusalMessage(code: any): any;
|
|
41
|
+
export { TOAST_CAPABILITY, TOAST_CIPHERTEXT_BYTES, TOAST_KEY, TOAST_KEY_ID, TOAST_OPERATION, TOAST_PAYMENT_METHODS_URL, TOAST_PSP, TOAST_REFUSAL_CODES, TOAST_SUBSTITUTION, isToastCiphertext, isToastHost, isToastPaymentMethodsUrl, readToastBody, toastBodyVerdict, toastRefusalMessage, toastRequestRefusal };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
+
// artifact-sha256: d0c3bda9a5b7939a6984156929cbcb7ba7d427fa38c544aad65c4593cf272d05
|
|
4
|
+
// src/toast.js
|
|
5
|
+
var TOAST_PSP = "toast";
|
|
6
|
+
var TOAST_CAPABILITY = "toast_pinned_key";
|
|
7
|
+
var TOAST_OPERATION = "toast.encrypted_card";
|
|
8
|
+
var TOAST_PAYMENT_METHODS_URL = "https://payments.toasttab.com/v1/payment-methods";
|
|
9
|
+
var TOAST_KEY_ID = "RSA-OAEP-SHA1::bacb4887-8314-4c23-98fc-d5ef7bc99e94_oo-legacy-browsers";
|
|
10
|
+
var TOAST_KEY = /* @__PURE__ */ Object.freeze({
|
|
11
|
+
spki: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkq50dXdz/fQOwYUswZRXgh5Vghs1tcJZCv2goNsC5BO3dXC/EiejcApaE/fKVMespzDNSLsQHXrWHegpE2piyeBwMzpTbHrCG3v6MnG6Nu+9dBYxPS4T9cNMsf0V/iCPiiaTXib6r8IfOjVZTTas2nKGZEtiDfYJIS3bJ/f30SMP4dAFILvzXGALeqleB/psQ8AFc/qUZf7VZpRnoGtKoo8wD253xTmDdaiKqr09bcJZxhTWsCB9aYouqdbl6y9/5Lu+MtyBkj7LI05g5QqDSfVax0sp/Fe7RY5SYxwlR4GlMonwtbvFTMKsr6dZ1uLuNjHA/6dm+112Uqn/AxrKGwIDAQAB",
|
|
12
|
+
sha256: "5475b78c9577b1258615286307547aba18c52faa6fd7d60ad0cfcb996e21ad0e"
|
|
13
|
+
});
|
|
14
|
+
var TOAST_CIPHERTEXT_BYTES = 256;
|
|
15
|
+
var TOAST_SUBSTITUTION = /* @__PURE__ */ Object.freeze({ at: "card", fields: Object.freeze(["cardData"]) });
|
|
16
|
+
var TOAST_REFUSAL_CODES = /* @__PURE__ */ Object.freeze(["toast_url_refused", "toast_foreign_key", "toast_keeps_card", "toast_body_malformed"]);
|
|
17
|
+
var BODY_LIMIT = 8192;
|
|
18
|
+
var ROOT_KEYS = /* @__PURE__ */ Object.freeze(["type", "card", "sessionSecret", "usage", "setupFutureUsage", "billingDetails"]);
|
|
19
|
+
var CARD_KEYS = /* @__PURE__ */ Object.freeze(["keyId", "cardData"]);
|
|
20
|
+
var WALLETS = /* @__PURE__ */ Object.freeze(["APPLE_PAY", "GOOGLE_PAY"]);
|
|
21
|
+
var SESSION_SECRET = /^[\x21-\x7e]{1,1024}$/;
|
|
22
|
+
var POSTAL_CODE = /^[A-Za-z0-9 -]{0,16}$/;
|
|
23
|
+
var CIPHERTEXT_B64 = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
|
|
24
|
+
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
25
|
+
var sameKeys = (value, keys) => {
|
|
26
|
+
const own = Object.keys(value);
|
|
27
|
+
return own.length === keys.length && own.every((key, at) => key === keys[at]);
|
|
28
|
+
};
|
|
29
|
+
var refuse = (code) => Object.freeze({ verdict: "refuse", code });
|
|
30
|
+
var failed = (code) => (
|
|
31
|
+
/** @type {ToastBodyReadJs} */
|
|
32
|
+
Object.freeze({ ok: false, code }));
|
|
33
|
+
var CARD = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
34
|
+
var CONTINUE = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
35
|
+
function isWalletBody(parsed) {
|
|
36
|
+
const card = parsed.card;
|
|
37
|
+
const rootOk = sameKeys(parsed, ["type", "card", "sessionSecret"]) || sameKeys(parsed, ["type", "card", "sessionSecret", "billingDetails"]) && record(parsed.billingDetails);
|
|
38
|
+
return rootOk && WALLETS.includes(parsed.type) && record(card) && sameKeys(card, ["keyId", "cardData", "wallet"]) && card.keyId === null && typeof card.cardData === "string" && record(card.wallet) && sameKeys(card.wallet, ["type"]) && card.wallet.type === parsed.type && typeof parsed.sessionSecret === "string";
|
|
39
|
+
}
|
|
40
|
+
function isToastPaymentMethodsUrl(url) {
|
|
41
|
+
return url === TOAST_PAYMENT_METHODS_URL;
|
|
42
|
+
}
|
|
43
|
+
function isToastHost(url) {
|
|
44
|
+
if (typeof url !== "string")
|
|
45
|
+
return false;
|
|
46
|
+
try {
|
|
47
|
+
return new URL(url).hostname.toLowerCase().replace(/\.$/, "") === "payments.toasttab.com";
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isToastCiphertext(value) {
|
|
54
|
+
return typeof value === "string" && CIPHERTEXT_B64.test(value);
|
|
55
|
+
}
|
|
56
|
+
function readToastBody(body) {
|
|
57
|
+
const malformed = failed("toast_body_malformed");
|
|
58
|
+
if (typeof body !== "string" || body.length > BODY_LIMIT)
|
|
59
|
+
return malformed;
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = JSON.parse(body);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return malformed;
|
|
66
|
+
}
|
|
67
|
+
if (!record(parsed) || JSON.stringify(parsed) !== body)
|
|
68
|
+
return malformed;
|
|
69
|
+
if (isWalletBody(parsed))
|
|
70
|
+
return (
|
|
71
|
+
/** @type {ToastBodyReadJs} */
|
|
72
|
+
Object.freeze({ ok: false, wallet: true }));
|
|
73
|
+
const card = parsed.card;
|
|
74
|
+
if (!sameKeys(parsed, ROOT_KEYS) || parsed.type !== "CARD" || !record(card) || !sameKeys(card, CARD_KEYS))
|
|
75
|
+
return malformed;
|
|
76
|
+
if (typeof card.keyId !== "string")
|
|
77
|
+
return malformed;
|
|
78
|
+
if (card.keyId !== TOAST_KEY_ID)
|
|
79
|
+
return failed("toast_foreign_key");
|
|
80
|
+
if (!isToastCiphertext(card.cardData))
|
|
81
|
+
return malformed;
|
|
82
|
+
if (typeof parsed.sessionSecret !== "string" || !SESSION_SECRET.test(parsed.sessionSecret))
|
|
83
|
+
return malformed;
|
|
84
|
+
if (parsed.usage !== null || parsed.setupFutureUsage !== null)
|
|
85
|
+
return failed("toast_keeps_card");
|
|
86
|
+
const billing = parsed.billingDetails;
|
|
87
|
+
if (!record(billing) || !sameKeys(billing, ["postalCode"]) || typeof billing.postalCode !== "string" || !POSTAL_CODE.test(billing.postalCode))
|
|
88
|
+
return malformed;
|
|
89
|
+
const read = { ok: true, sessionSecret: parsed.sessionSecret, postalCode: billing.postalCode, cardData: card.cardData };
|
|
90
|
+
return Object.freeze(read);
|
|
91
|
+
}
|
|
92
|
+
function toastBodyVerdict(body) {
|
|
93
|
+
const read = readToastBody(body);
|
|
94
|
+
if (read.ok)
|
|
95
|
+
return CARD;
|
|
96
|
+
return read.wallet ? CONTINUE : refuse(read.code);
|
|
97
|
+
}
|
|
98
|
+
function toastRequestRefusal(request) {
|
|
99
|
+
if (!record(request) || typeof request.method !== "string" || request.method.toUpperCase() !== "POST" || !isToastPaymentMethodsUrl(request.url))
|
|
100
|
+
return "toast_url_refused";
|
|
101
|
+
const read = readToastBody(request.body);
|
|
102
|
+
return read.ok ? null : read.code ?? "toast_body_malformed";
|
|
103
|
+
}
|
|
104
|
+
var REFUSAL_MESSAGES = /* @__PURE__ */ Object.freeze({
|
|
105
|
+
toast_url_refused: "Refusing to pay: this Toast card request does not go to the address Toast's card form sends cards to. Nothing was sent.",
|
|
106
|
+
toast_foreign_key: "Refusing to pay: this Toast card request is encrypted under a key Agentcard has not reviewed. Nothing was sent.",
|
|
107
|
+
toast_keeps_card: "Refusing to pay: this Toast checkout asks to keep the card for later payments, and Agentcard pays only a one-time guest checkout here. Nothing was sent.",
|
|
108
|
+
toast_body_malformed: "Refusing to pay: this is not the card request of Toast's card form. Nothing was sent."
|
|
109
|
+
});
|
|
110
|
+
function toastRefusalMessage(code) {
|
|
111
|
+
return Object.prototype.hasOwnProperty.call(REFUSAL_MESSAGES, code) ? REFUSAL_MESSAGES[code] : REFUSAL_MESSAGES.toast_body_malformed;
|
|
112
|
+
}
|
|
113
|
+
export { TOAST_CAPABILITY, TOAST_CIPHERTEXT_BYTES, TOAST_KEY, TOAST_KEY_ID, TOAST_OPERATION, TOAST_PAYMENT_METHODS_URL, TOAST_PSP, TOAST_REFUSAL_CODES, TOAST_SUBSTITUTION, isToastCiphertext, isToastHost, isToastPaymentMethodsUrl, readToastBody, toastBodyVerdict, toastRefusalMessage, toastRequestRefusal };
|
package/dist/transbank.d.ts
CHANGED
|
@@ -43,3 +43,36 @@ export declare function servesTransbank(vault: {
|
|
|
43
43
|
export declare function isArmedTransbankUrl(vault: {
|
|
44
44
|
isCardRequest(url: string, method?: string): boolean;
|
|
45
45
|
} | undefined, url: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* A reviewed Webpay shop, as this build reads it to send the browser back: the hosts of its checkout pages, the host of
|
|
48
|
+
* its return page, and the return page itself, exactly as its transactions name it (null while nobody has read it).
|
|
49
|
+
*/
|
|
50
|
+
export interface TransbankReturnPage {
|
|
51
|
+
readonly hosts: readonly string[];
|
|
52
|
+
readonly returnHost: string;
|
|
53
|
+
readonly returnUrl: string | null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* payment-core's TRANSBANK_MERCHANTS, every row that names its commerce code, with these three fields. A row without a
|
|
57
|
+
* code names no shop there, so it is not listed here. transbank.test.mjs pins this list to payment-core's, so a reviewed
|
|
58
|
+
* change that codes a shop there fails this package's tests until the shop is listed here too. Teleférico Santiago's
|
|
59
|
+
* row names no code yet, so no paused entry is sent back anywhere.
|
|
60
|
+
*/
|
|
61
|
+
export declare const TRANSBANK_RETURN_PAGES: readonly TransbankReturnPage[];
|
|
62
|
+
/**
|
|
63
|
+
* Where the paused Webpay entry `entryUrl` goes once the cardholder's phone has paid it: the return page of the one
|
|
64
|
+
* reviewed shop whose checkout pages include `pageOrigin` (the origin the create named, written exactly as an origin),
|
|
65
|
+
* with the entry's token as `token_ws`. The same navigation payment-core's transbankMerchantReturn builds, and the one
|
|
66
|
+
* Webpay itself sends the phone's session to. Null for a link that is not Webpay's entry, a page no reviewed shop
|
|
67
|
+
* lists, a page two list, or a shop whose return page no token can follow. `pages` is for tests.
|
|
68
|
+
*/
|
|
69
|
+
export declare function transbankMerchantReturn(entryUrl: unknown, pageOrigin: unknown, pages?: readonly TransbankReturnPage[]): string | null;
|
|
70
|
+
/**
|
|
71
|
+
* The answer the paused entry gets: a 303 to the shop's return page, which the browser follows with a GET, and which no
|
|
72
|
+
* cache keeps (the URL carries Webpay's token).
|
|
73
|
+
*/
|
|
74
|
+
export declare function transbankMerchantReturnAnswer(returnUrl: string): {
|
|
75
|
+
status: 303;
|
|
76
|
+
headers: Record<string, string>;
|
|
77
|
+
body: string;
|
|
78
|
+
};
|
package/dist/transbank.js
CHANGED
|
@@ -71,3 +71,65 @@ export function servesTransbank(vault) {
|
|
|
71
71
|
export function isArmedTransbankUrl(vault, url) {
|
|
72
72
|
return isTransbankHost(url) && servesTransbank(vault);
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* payment-core's TRANSBANK_MERCHANTS, every row that names its commerce code, with these three fields. A row without a
|
|
76
|
+
* code names no shop there, so it is not listed here. transbank.test.mjs pins this list to payment-core's, so a reviewed
|
|
77
|
+
* change that codes a shop there fails this package's tests until the shop is listed here too. Teleférico Santiago's
|
|
78
|
+
* row names no code yet, so no paused entry is sent back anywhere.
|
|
79
|
+
*/
|
|
80
|
+
export const TRANSBANK_RETURN_PAGES = Object.freeze([]);
|
|
81
|
+
// Webpay's own return fields (payment-core processors/transbank.js RETURN_FIELDS): a return page never carries one.
|
|
82
|
+
const RETURN_FIELDS = new Set(['token_ws', 'TBK_TOKEN', 'TBK_ORDEN_COMPRA', 'TBK_ID_SESION']);
|
|
83
|
+
/** `page.returnUrl` when a token can follow it, as payment-core's pinnedReturnUrl reads a row's; null otherwise. */
|
|
84
|
+
function returnPageUrl(page) {
|
|
85
|
+
const raw = page?.returnUrl;
|
|
86
|
+
if (typeof raw !== 'string' || raw.length > 1024)
|
|
87
|
+
return null;
|
|
88
|
+
let url;
|
|
89
|
+
try {
|
|
90
|
+
url = new URL(raw);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (url.protocol !== 'https:' || url.hostname !== page.returnHost || url.port || url.username || url.password || url.href !== raw
|
|
96
|
+
|| /#|\?$|\?&|&&|&$/.test(raw))
|
|
97
|
+
return null;
|
|
98
|
+
for (const [name] of url.searchParams)
|
|
99
|
+
if (RETURN_FIELDS.has(name))
|
|
100
|
+
return null;
|
|
101
|
+
return raw;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Where the paused Webpay entry `entryUrl` goes once the cardholder's phone has paid it: the return page of the one
|
|
105
|
+
* reviewed shop whose checkout pages include `pageOrigin` (the origin the create named, written exactly as an origin),
|
|
106
|
+
* with the entry's token as `token_ws`. The same navigation payment-core's transbankMerchantReturn builds, and the one
|
|
107
|
+
* Webpay itself sends the phone's session to. Null for a link that is not Webpay's entry, a page no reviewed shop
|
|
108
|
+
* lists, a page two list, or a shop whose return page no token can follow. `pages` is for tests.
|
|
109
|
+
*/
|
|
110
|
+
export function transbankMerchantReturn(entryUrl, pageOrigin, pages = TRANSBANK_RETURN_PAGES) {
|
|
111
|
+
if (!isTransbankEntryUrl(entryUrl) || typeof pageOrigin !== 'string' || pageOrigin.length > 256)
|
|
112
|
+
return null;
|
|
113
|
+
const token = new URL(entryUrl).searchParams.get('token_ws');
|
|
114
|
+
let origin;
|
|
115
|
+
try {
|
|
116
|
+
origin = new URL(pageOrigin);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (origin.protocol !== 'https:' || origin.origin !== pageOrigin || origin.port)
|
|
122
|
+
return null;
|
|
123
|
+
const listing = pages.filter((page) => Array.isArray(page?.hosts) && page.hosts.includes(origin.hostname));
|
|
124
|
+
const returnUrl = listing.length === 1 ? returnPageUrl(listing[0]) : null;
|
|
125
|
+
if (!returnUrl || !token)
|
|
126
|
+
return null;
|
|
127
|
+
return `${returnUrl}${new URL(returnUrl).search ? '&' : '?'}token_ws=${token}`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The answer the paused entry gets: a 303 to the shop's return page, which the browser follows with a GET, and which no
|
|
131
|
+
* cache keeps (the URL carries Webpay's token).
|
|
132
|
+
*/
|
|
133
|
+
export function transbankMerchantReturnAnswer(returnUrl) {
|
|
134
|
+
return { status: 303, headers: { location: returnUrl, 'cache-control': 'no-store' }, body: '' };
|
|
135
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts every URL mask is built from (client.ts redactUrl). A processor whose card request carries its own
|
|
3
|
+
* credential in the URL path writes its mask in src/url-masks/<psp id>.ts, exported as `mask`, and the build
|
|
4
|
+
* collects every such file into src/url-masks.generated.ts (scripts/generate-url-masks.mjs).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* `mask` reads a text that names the processor's host; `pathMask`, where a processor has one, reads the path of a
|
|
8
|
+
* URL already parsed on that host, which `mask` reads otherwise.
|
|
9
|
+
*/
|
|
10
|
+
export interface UrlMask {
|
|
11
|
+
host: RegExp;
|
|
12
|
+
named: RegExp;
|
|
13
|
+
mask: (path: string) => string;
|
|
14
|
+
pathMask?: (path: string) => string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A slash as the masks read one: plain, or escaped once or more in either case (%2F, %2f, %252F). A path keeps
|
|
18
|
+
* an escape as it was written, and the id behind it is the same id, so every slash a mask names reads in any of these
|
|
19
|
+
* spellings. The slashes right before an id read as a run, and a doubled slash hides nothing either.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SLASH = "(?:/|%(?:25)*2f)";
|
|
22
|
+
/** A hyphen inside an id: plain, or escaped once or more in either case (%2D, %252d). */
|
|
23
|
+
export declare const HYPHEN = "(?:-|%(?:25)*2d)";
|
|
24
|
+
export declare function maskUuids(path: string, label: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts every URL mask is built from (client.ts redactUrl). A processor whose card request carries its own
|
|
3
|
+
* credential in the URL path writes its mask in src/url-masks/<psp id>.ts, exported as `mask`, and the build
|
|
4
|
+
* collects every such file into src/url-masks.generated.ts (scripts/generate-url-masks.mjs).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A slash as the masks read one: plain, or escaped once or more in either case (%2F, %2f, %252F). A path keeps
|
|
8
|
+
* an escape as it was written, and the id behind it is the same id, so every slash a mask names reads in any of these
|
|
9
|
+
* spellings. The slashes right before an id read as a run, and a doubled slash hides nothing either.
|
|
10
|
+
*/
|
|
11
|
+
export const SLASH = '(?:/|%(?:25)*2f)';
|
|
12
|
+
/** A hyphen inside an id: plain, or escaped once or more in either case (%2D, %252d). */
|
|
13
|
+
export const HYPHEN = '(?:-|%(?:25)*2d)';
|
|
14
|
+
/**
|
|
15
|
+
* The masks that find a uuid by its shape take it in any case, with or without its hyphens, each hyphen in any
|
|
16
|
+
* spelling HYPHEN reads. The pattern reads a percent escape as one unit and keeps it, so the hex digits of an escaped
|
|
17
|
+
* separator before the id (%2F, %252F, %3D) never start a match and leave the id's last digits showing.
|
|
18
|
+
*/
|
|
19
|
+
const UUID_OR_ESCAPE = new RegExp(`%(?:25)*[0-9a-f]{2}|[0-9a-f]{8}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{4}${HYPHEN}?[0-9a-f]{12}`, 'gi');
|
|
20
|
+
export function maskUuids(path, label) {
|
|
21
|
+
return path.replace(UUID_OR_ESCAPE, (token) => (token.startsWith('%') ? token : label));
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-cards/sdk",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.23",
|
|
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",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"_comment_build": "The public SDK keeps zero runtime dependencies. Its build vendors deterministic metadata and substitution artifacts from the internal payment core (src/*.generated.ts), the voice streaming door from packages/voice/src/core (the phone package, @agent-cards/voice, ships it to phones), and the Kernel kit's inventory from the built catalog; git ignores every file it writes. TypeScript remains pinned.",
|
|
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 && node scripts/generate-kernel-native-inventory.mjs",
|
|
28
|
+
"build": "node ../payment-core/scripts/build.mjs && node scripts/generate-payment-core.mjs && node scripts/generate-voice-stream.mjs && node scripts/generate-url-masks.mjs && node scripts/generate-capabilities.mjs && node scripts/generate-agent-amount.mjs && npx -y -p typescript@5.9.3 tsc && node scripts/generate-preflight-contract.mjs && node scripts/generate-kernel-native-inventory.mjs",
|
|
29
29
|
"prepublishOnly": "pnpm build",
|
|
30
30
|
"_comment_test": "check:built runs first and names the command when a file the build generates (the copies in src/, the preflight contracts in dist/, the Kernel inventory) is missing or stale; verify:pack runs last, on the same dist.",
|
|
31
|
-
"check:built": "node scripts/generate-payment-core.mjs --check && node scripts/generate-voice-stream.mjs --check && node scripts/generate-preflight-contract.mjs --check && node scripts/generate-kernel-native-inventory.mjs --check",
|
|
31
|
+
"check:built": "node scripts/generate-payment-core.mjs --check && node scripts/generate-voice-stream.mjs --check && node scripts/generate-url-masks.mjs --check && node scripts/generate-capabilities.mjs --check && node scripts/generate-agent-amount.mjs --check && node scripts/generate-preflight-contract.mjs --check && node scripts/generate-kernel-native-inventory.mjs --check",
|
|
32
32
|
"verify:pack": "node scripts/verify-pack.mjs",
|
|
33
|
-
"test": "npm run check:built && 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 redsys.test.mjs quickpay.test.mjs paypal-hosted-fields.test.mjs paypal-card-forms.test.mjs cybersource-secure-acceptance.test.mjs ebanx.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 wix-payments.test.mjs hipay.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 hold.test.mjs paddle-tokenex.test.mjs lyra.test.mjs gopay.test.mjs twoc2p.test.mjs pay-nl.test.mjs redact-url.test.mjs hosted-entry.test.mjs comgate.test.mjs przelewy24.test.mjs tokenex-iframe.test.mjs transbank.test.mjs sumup.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs browser-tests.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs && node scripts/verify-pack.mjs",
|
|
33
|
+
"test": "npm run check:built && 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 redsys.test.mjs quickpay.test.mjs paytrail.test.mjs paypal-hosted-fields.test.mjs paypal-card-forms.test.mjs cybersource-secure-acceptance.test.mjs ebanx.test.mjs payrexx.test.mjs payrexx-follow-ups.test.mjs payrexx-adapters.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 wix-payments.test.mjs hipay.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 sbps.test.mjs hold.test.mjs paddle-tokenex.test.mjs lyra.test.mjs gopay.test.mjs paygent.test.mjs twoc2p.test.mjs pay-nl.test.mjs toast.test.mjs redact-url.test.mjs hosted-entry.test.mjs comgate.test.mjs przelewy24.test.mjs tokenex-iframe.test.mjs transbank.test.mjs sumup.test.mjs clover.test.mjs eximbay.test.mjs xendit.test.mjs omise.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs browser-tests.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs && node scripts/verify-pack.mjs",
|
|
34
34
|
"test:browser": "node browser-tests.mjs",
|
|
35
35
|
"check:payment-core": "node scripts/generate-payment-core.mjs --check",
|
|
36
36
|
"check:voice-stream": "node scripts/generate-voice-stream.mjs --check",
|