@agent-cards/checkout 0.19.0 → 0.21.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 +6 -753
- package/cdp.d.ts +1 -0
- package/cdp.js +2 -0
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/package.json +33 -33
- package/playwright.d.ts +1 -0
- package/playwright.js +2 -0
- package/preflight.d.ts +1 -0
- package/preflight.js +2 -0
- package/CHANGELOG.md +0 -132
- package/PREFLIGHT.md +0 -312
- package/dist/adyen-merchant-hosted.generated.d.ts +0 -277
- package/dist/adyen-merchant-hosted.generated.js +0 -1902
- package/dist/adyen.generated.d.ts +0 -24
- package/dist/adyen.generated.js +0 -64
- package/dist/attachment.d.ts +0 -11
- package/dist/attachment.js +0 -50
- package/dist/braintree.d.ts +0 -2
- package/dist/braintree.generated.d.ts +0 -10
- package/dist/braintree.generated.js +0 -302
- package/dist/braintree.js +0 -2
- package/dist/builtin-registry.generated.d.ts +0 -2
- package/dist/builtin-registry.generated.js +0 -1
- package/dist/card-fields.generated.d.ts +0 -3
- package/dist/card-fields.generated.js +0 -46
- package/dist/cdp.d.ts +0 -192
- package/dist/cdp.js +0 -2393
- package/dist/checkout-com.generated.d.ts +0 -4
- package/dist/checkout-com.generated.js +0 -183
- package/dist/client.d.ts +0 -849
- package/dist/client.js +0 -1754
- package/dist/cse-body.d.ts +0 -25
- package/dist/cse-body.js +0 -41
- package/dist/fiserv.d.ts +0 -65
- package/dist/fiserv.generated.d.ts +0 -73
- package/dist/fiserv.generated.js +0 -830
- package/dist/fiserv.js +0 -104
- package/dist/hosted-form.d.ts +0 -44
- package/dist/hosted-form.js +0 -78
- package/dist/index.d.ts +0 -18
- package/dist/index.js +0 -10
- package/dist/lifecycle.d.ts +0 -179
- package/dist/lifecycle.js +0 -395
- package/dist/mercado-checkout.d.ts +0 -20
- package/dist/mercado-checkout.generated.d.ts +0 -52
- package/dist/mercado-checkout.generated.js +0 -198
- package/dist/mercado-checkout.js +0 -108
- package/dist/merchant-handoff.d.ts +0 -54
- package/dist/merchant-handoff.js +0 -100
- package/dist/merchant-hosted.d.ts +0 -140
- package/dist/merchant-hosted.js +0 -170
- package/dist/merchant-total-watch.d.ts +0 -115
- package/dist/merchant-total-watch.js +0 -268
- package/dist/merchant-total.d.ts +0 -257
- package/dist/merchant-total.js +0 -383
- package/dist/owned-shop.generated.d.ts +0 -24
- package/dist/owned-shop.generated.js +0 -108
- package/dist/paysafe.generated.d.ts +0 -12
- package/dist/paysafe.generated.js +0 -87
- package/dist/playwright.d.ts +0 -3
- package/dist/playwright.js +0 -3
- package/dist/pre-claim.d.ts +0 -123
- package/dist/pre-claim.js +0 -386
- package/dist/preflight-capabilities.generated.d.ts +0 -1253
- package/dist/preflight-capabilities.generated.js +0 -1929
- package/dist/preflight-catalog.json +0 -4727
- package/dist/preflight-playwright.d.ts +0 -34
- package/dist/preflight-playwright.js +0 -355
- package/dist/preflight-schemas.json +0 -1122
- package/dist/preflight.d.ts +0 -1
- package/dist/preflight.generated.d.ts +0 -1965
- package/dist/preflight.generated.js +0 -570
- package/dist/preflight.js +0 -2
- package/dist/preparation.d.ts +0 -38
- package/dist/preparation.js +0 -191
- package/dist/prepared-processor.d.ts +0 -43
- package/dist/prepared-processor.js +0 -172
- package/dist/recurly.generated.d.ts +0 -1
- package/dist/recurly.generated.js +0 -87
- package/dist/registry.d.ts +0 -121
- package/dist/registry.js +0 -310
- package/dist/spreedly.generated.d.ts +0 -10
- package/dist/spreedly.generated.js +0 -332
- package/dist/stripe-checkout.d.ts +0 -81
- package/dist/stripe-checkout.generated.d.ts +0 -82
- package/dist/stripe-checkout.generated.js +0 -1093
- package/dist/stripe-checkout.js +0 -140
- package/dist/substitute.d.ts +0 -38
- package/dist/substitute.js +0 -23
- package/dist/substitutions.generated.d.ts +0 -11
- package/dist/substitutions.generated.js +0 -818
- package/examples/existing-browser.mjs +0 -63
- package/examples/preflight/classify-direct.mjs +0 -21
- package/examples/preflight/classify-kernel.mjs +0 -30
- package/examples/preflight/inspect-browser.mjs +0 -44
- package/examples/preflight/kernel-native/README.md +0 -112
- package/examples/preflight/kernel-native/documented-adapters.json +0 -113
- package/examples/preflight/kernel-native/inventory.json +0 -233
- package/examples/preflight/kernel-native/qualification.mjs +0 -182
- package/examples/preflight/kernel-profile.empty.json +0 -11
- package/examples/preflight/mollie-hosted.observations.json +0 -23
- package/examples/preflight/mollie-hosted.result.json +0 -103
- package/examples/preflight/stripe-script.direct.result.json +0 -92
- package/examples/preflight/stripe-script.observations.json +0 -16
- package/examples/preflight/stripe-script.result.json +0 -87
package/dist/registry.d.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Which outbound requests carry a raw card, and where the card sits inside them.
|
|
3
|
-
*
|
|
4
|
-
* This is the only merchant-specific knowledge in the system, and it is keyed by
|
|
5
|
-
* PSP rather than by merchant: every Shopify store shares one entry, every Stripe
|
|
6
|
-
* site shares another. The list is served from the Agentcard API at runtime so
|
|
7
|
-
* integrators pick up new processors without shipping a release.
|
|
8
|
-
*/
|
|
9
|
-
export type Encoding = 'json' | 'form';
|
|
10
|
-
/**
|
|
11
|
-
* How a paused request gets its card. `token` (the default when absent): the
|
|
12
|
-
* cardholder's device calls the processor and the runtime replays the
|
|
13
|
-
* processor's response. `cse`: the processor encrypts the card in-page
|
|
14
|
-
* (Adyen); the device returns ciphertext and the runtime substitutes it into
|
|
15
|
-
* the paused body and lets the request continue. `hosted_form`: the device
|
|
16
|
-
* submits the processor's own form and the paused request resolves with no
|
|
17
|
-
* processor answer (served only to SDKs that ask for it on sync).
|
|
18
|
-
*/
|
|
19
|
-
export type CheckoutMode = 'token' | 'cse' | 'hosted_form';
|
|
20
|
-
export interface Recognizer {
|
|
21
|
-
/** Stable id, e.g. "shopify" */
|
|
22
|
-
psp: string;
|
|
23
|
-
/** Matches the tokenization endpoint. */
|
|
24
|
-
match: RegExp;
|
|
25
|
-
/**
|
|
26
|
-
* Anchored (`^…$`) regex SOURCES for the hostnames this PSP may ever receive
|
|
27
|
-
* a card on — the server's own allowlist, served next to `match` and carried
|
|
28
|
-
* through syncRegistry() verbatim.
|
|
29
|
-
*
|
|
30
|
-
* Strings, not RegExps, because that is the wire shape and because nothing
|
|
31
|
-
* here matches with them: they exist so a transport that can only pre-filter
|
|
32
|
-
* by URL (CDP's `Fetch.enable`, which takes globs) can be armed from the
|
|
33
|
-
* registry instead of a hardcoded list. Optional so a hand-built registry
|
|
34
|
-
* (tests, pinning) still type-checks.
|
|
35
|
-
*/
|
|
36
|
-
hosts?: string[];
|
|
37
|
-
encoding: Encoding;
|
|
38
|
-
/**
|
|
39
|
-
* Request headers that must be replayed verbatim for the merchant to accept
|
|
40
|
-
* the call (signatures, client tokens). Matched case-insensitively.
|
|
41
|
-
*/
|
|
42
|
-
passthroughHeaders: RegExp[];
|
|
43
|
-
/**
|
|
44
|
-
* Form keys that carry the card number. When present, a request on this
|
|
45
|
-
* recognizer's endpoints is a card request only if its body carries one of
|
|
46
|
-
* them: a Stripe confirmation that pays with a method the page already
|
|
47
|
-
* created (`payment_method=pm_...`) carries none, so there is nothing for
|
|
48
|
-
* the cardholder to approve. Served by the API and carried through
|
|
49
|
-
* syncRegistry() verbatim.
|
|
50
|
-
*/
|
|
51
|
-
cardFields?: string[];
|
|
52
|
-
/**
|
|
53
|
-
* With cardFields: the endpoints (regex source over hostname + pathname,
|
|
54
|
-
* anchored) where a request without a card is routine and never ours, so
|
|
55
|
-
* it continues untouched; a request without a card anywhere else is refused.
|
|
56
|
-
*/
|
|
57
|
-
passWithoutCard?: string;
|
|
58
|
-
/**
|
|
59
|
-
* True when the card is encrypted inside the page before the request leaves.
|
|
60
|
-
* A digit swap is useless here; the vault must re-run the PSP's client-side
|
|
61
|
-
* crypto instead. Refused locally unless the entry also carries
|
|
62
|
-
* `mode: 'cse'`, which says the vault does exactly that.
|
|
63
|
-
*/
|
|
64
|
-
clientSideEncrypted?: boolean;
|
|
65
|
-
/** How the card reaches the processor; absent means 'token'. Carried verbatim by syncRegistry. */
|
|
66
|
-
mode?: CheckoutMode;
|
|
67
|
-
/**
|
|
68
|
-
* Dark launch: a capability name the API attaches to an entry it serves only
|
|
69
|
-
* to a client that declared it (?capabilities=). Absent on every entry in
|
|
70
|
-
* BUILTIN_REGISTRY, because a gated entry is left out of the built-in
|
|
71
|
-
* fallback. Carried verbatim by syncRegistry for a client that does declare
|
|
72
|
-
* it, so the SDK never has to act on it.
|
|
73
|
-
*/
|
|
74
|
-
capability?: string;
|
|
75
|
-
/**
|
|
76
|
-
* True when this processor cannot be taken over on an ordinary authorization:
|
|
77
|
-
* the cardholder must have approved a prepare() first. authorize() refuses
|
|
78
|
-
* such a request locally, before it prompts, when no preparation is active
|
|
79
|
-
* (PreparationRequiredError), and the API answers 409 preparation_required.
|
|
80
|
-
* Absent on every BUILTIN_REGISTRY entry today and carried verbatim by
|
|
81
|
-
* syncRegistry for a build that reaches a processor which sets it.
|
|
82
|
-
*/
|
|
83
|
-
preparationRequired?: boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Anchored regex SOURCES (a subset of `hosts`) marking the vendor's
|
|
86
|
-
* SANDBOX/TEST hostnames, so the backend and the device can tell a test host
|
|
87
|
-
* from a live one. Carried verbatim by syncRegistry; the SDK never matches
|
|
88
|
-
* with them (recognition still uses `hosts`), so it acts on neither this nor
|
|
89
|
-
* the pin below. Present in BUILTIN_REGISTRY for the host-separated processors.
|
|
90
|
-
*/
|
|
91
|
-
sandboxHosts?: string[];
|
|
92
|
-
/**
|
|
93
|
-
* True when a processor's host environment is enforced: the API refuses a
|
|
94
|
-
* create whose host environment disagrees with the row's test/live nature, and
|
|
95
|
-
* the device sends only documented test cards to a sandbox host. Absent on
|
|
96
|
-
* every entry today; carried verbatim by syncRegistry, and the SDK never acts
|
|
97
|
-
* on it.
|
|
98
|
-
*/
|
|
99
|
-
hostEnvironmentPinned?: boolean;
|
|
100
|
-
}
|
|
101
|
-
import { BUILTIN_REGISTRY } from './builtin-registry.generated.js';
|
|
102
|
-
export { BUILTIN_REGISTRY };
|
|
103
|
-
export declare function findRecognizer(url: string, registry?: Recognizer[]): Recognizer | null;
|
|
104
|
-
/**
|
|
105
|
-
* True when this processor cannot be taken over on an ordinary authorization:
|
|
106
|
-
* the cardholder must have approved a prepare() first (the `preparationRequired`
|
|
107
|
-
* field above). authorize() applies this before it prompts and refuses with
|
|
108
|
-
* PreparationRequiredError when no preparation is active; the API answers 409
|
|
109
|
-
* preparation_required for the same case. This is the SAME rule payment-core's
|
|
110
|
-
* recognizerRequiresPreparation applies on the server, a strict `=== true`, so a
|
|
111
|
-
* value that rode in over the wire (syncRegistry spreads the served JSON) cannot
|
|
112
|
-
* turn a truthy string into a gate. Absent on every BUILTIN_REGISTRY entry, so
|
|
113
|
-
* this is false for all 24 today.
|
|
114
|
-
*/
|
|
115
|
-
export declare function recognizerRequiresPreparation(rec: Pick<Recognizer, 'preparationRequired'>): boolean;
|
|
116
|
-
/**
|
|
117
|
-
* Glob url patterns covering every host in `registry` — what to hand
|
|
118
|
-
* `Fetch.enable` so a card request is ever paused. Deliberately a superset of
|
|
119
|
-
* the recognizers; isCardRequest is the exact check.
|
|
120
|
-
*/
|
|
121
|
-
export declare function cardUrlPatterns(registry: Recognizer[]): string[];
|
package/dist/registry.js
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Which outbound requests carry a raw card, and where the card sits inside them.
|
|
3
|
-
*
|
|
4
|
-
* This is the only merchant-specific knowledge in the system, and it is keyed by
|
|
5
|
-
* PSP rather than by merchant: every Shopify store shares one entry, every Stripe
|
|
6
|
-
* site shares another. The list is served from the Agentcard API at runtime so
|
|
7
|
-
* integrators pick up new processors without shipping a release.
|
|
8
|
-
*/
|
|
9
|
-
// Pinned fallback generated from the single shared processor catalog.
|
|
10
|
-
import { BUILTIN_REGISTRY } from './builtin-registry.generated.js';
|
|
11
|
-
export { BUILTIN_REGISTRY };
|
|
12
|
-
export function findRecognizer(url, registry = BUILTIN_REGISTRY) {
|
|
13
|
-
// Match the way the SERVER does, on the PARSED url — never as a substring of
|
|
14
|
-
// the raw string. `match` is unanchored, so a raw-string test classifies any
|
|
15
|
-
// URL that merely CONTAINS a tokenizer endpoint as a card request:
|
|
16
|
-
// https://evil.com/?next=https://api.stripe.com/v1/tokens
|
|
17
|
-
// The server refuses that (its hosts[] are anchored against URL.hostname), so
|
|
18
|
-
// the request could not be intercepted anyway — but the SDK had already paused
|
|
19
|
-
// it, and a pause it cannot complete becomes an ABORT. That turns an
|
|
20
|
-
// integrator's unrelated POST into a failed request.
|
|
21
|
-
//
|
|
22
|
-
// hosts[] is synced from the API precisely so the client can apply the server's
|
|
23
|
-
// own allowlist. Use it when present, and fall back to matching `match`
|
|
24
|
-
// against "hostname + pathname" (not the query) for a registry served by an
|
|
25
|
-
// older API that predates the field.
|
|
26
|
-
let parsed;
|
|
27
|
-
try {
|
|
28
|
-
parsed = new URL(url);
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
if (parsed.protocol !== 'https:' || parsed.port || parsed.username || parsed.password)
|
|
34
|
-
return null;
|
|
35
|
-
const hostPath = `${parsed.hostname.toLowerCase()}${parsed.pathname}`;
|
|
36
|
-
return (registry.find((r) => {
|
|
37
|
-
if (r.hosts && r.hosts.length > 0) {
|
|
38
|
-
const hostAllowed = r.hosts.some((h) => new RegExp(h, 'i').test(parsed.hostname));
|
|
39
|
-
if (!hostAllowed)
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
// FULLY ANCHORED, exactly as the server does it. Unanchored, any EXTENSION
|
|
43
|
-
// of a valid path is admitted on a legitimate processor host
|
|
44
|
-
// (api.stripe.com/v1/tokens/anything), which the service then refuses —
|
|
45
|
-
// and a pause the SDK cannot complete becomes an abort.
|
|
46
|
-
return new RegExp(`^(?:${r.match.source})$`, 'i').test(hostPath);
|
|
47
|
-
}) ?? null);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* True when this processor cannot be taken over on an ordinary authorization:
|
|
51
|
-
* the cardholder must have approved a prepare() first (the `preparationRequired`
|
|
52
|
-
* field above). authorize() applies this before it prompts and refuses with
|
|
53
|
-
* PreparationRequiredError when no preparation is active; the API answers 409
|
|
54
|
-
* preparation_required for the same case. This is the SAME rule payment-core's
|
|
55
|
-
* recognizerRequiresPreparation applies on the server, a strict `=== true`, so a
|
|
56
|
-
* value that rode in over the wire (syncRegistry spreads the served JSON) cannot
|
|
57
|
-
* turn a truthy string into a gate. Absent on every BUILTIN_REGISTRY entry, so
|
|
58
|
-
* this is false for all 24 today.
|
|
59
|
-
*/
|
|
60
|
-
export function recognizerRequiresPreparation(rec) {
|
|
61
|
-
return rec.preparationRequired === true;
|
|
62
|
-
}
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
// Registry -> CDP url patterns
|
|
65
|
-
//
|
|
66
|
-
// `Fetch.enable` takes GLOB url patterns (`*` = any run of characters, `?` =
|
|
67
|
-
// exactly one, `\` escapes), never regexes, so the registry's anchored host
|
|
68
|
-
// regexes have to be widened into globs before a raw-CDP integrator can arm
|
|
69
|
-
// interception with them.
|
|
70
|
-
//
|
|
71
|
-
// These patterns are only a COARSE pre-filter. Every request they pause is
|
|
72
|
-
// re-checked with the real recognizer (VaultClient.isCardRequest) before
|
|
73
|
-
// anything is intercepted, so a pattern that is too BROAD costs one extra
|
|
74
|
-
// continueRequest round-trip, while one that is too NARROW silently drops the
|
|
75
|
-
// card request on the floor and the shopper pays with their own card. Every
|
|
76
|
-
// conversion below therefore WIDENS: anything not expressible as a glob
|
|
77
|
-
// (character classes, groups, quantifiers, lookarounds) becomes `*`.
|
|
78
|
-
// ---------------------------------------------------------------------------
|
|
79
|
-
/**
|
|
80
|
-
* Glob url patterns covering every host in `registry` — what to hand
|
|
81
|
-
* `Fetch.enable` so a card request is ever paused. Deliberately a superset of
|
|
82
|
-
* the recognizers; isCardRequest is the exact check.
|
|
83
|
-
*/
|
|
84
|
-
export function cardUrlPatterns(registry) {
|
|
85
|
-
const out = new Set();
|
|
86
|
-
for (const rec of registry ?? []) {
|
|
87
|
-
for (const pattern of recognizerUrlPatterns(rec))
|
|
88
|
-
out.add(pattern);
|
|
89
|
-
}
|
|
90
|
-
return [...out];
|
|
91
|
-
}
|
|
92
|
-
function recognizerUrlPatterns(rec) {
|
|
93
|
-
const hosts = Array.isArray(rec?.hosts) ? rec.hosts.filter((h) => typeof h === 'string') : [];
|
|
94
|
-
if (hosts.length > 0) {
|
|
95
|
-
// Host text ANYWHERE in the URL, not `*://host/*`. Two reasons: a URL with
|
|
96
|
-
// userinfo (`https://u:p@host/…`) still has `host` as its hostname so the
|
|
97
|
-
// registry matches it, and isCardRequest tests `match` unanchored against
|
|
98
|
-
// the raw URL, so a URL merely carrying the host in its query also
|
|
99
|
-
// "matches" client-side. Anchoring the scheme would arm narrower than
|
|
100
|
-
// either check.
|
|
101
|
-
//
|
|
102
|
-
// Lowercased because CDP matches these globs case-SENSITIVELY against the
|
|
103
|
-
// canonical url, and a canonical url's authority is always lowercase (the
|
|
104
|
-
// URL parser folds it before the request is ever issued) — the same
|
|
105
|
-
// normalization resolveRecognizerForUrl does with url.hostname. Do not
|
|
106
|
-
// "fix" this by wildcarding the letters: `*???.??????.???*` matches most of
|
|
107
|
-
// the web and would pause every request on the page.
|
|
108
|
-
return hosts.flatMap((h) => regexSourceToGlobs(h)).map((g) => wrap(g).toLowerCase());
|
|
109
|
-
}
|
|
110
|
-
// No hosts[] — a registry pinned before the field existed, or hand-built.
|
|
111
|
-
// Fall back to widening `match`, which is the predicate isCardRequest
|
|
112
|
-
// actually applies. Path case can matter to a glob (CDP matches
|
|
113
|
-
// case-sensitively) while a hostname is always lowercased by the URL parser,
|
|
114
|
-
// so arm both spellings rather than guess.
|
|
115
|
-
return regexSourceToGlobs(rec?.match?.source ?? '')
|
|
116
|
-
.map(wrap)
|
|
117
|
-
.flatMap((g) => (g === g.toLowerCase() ? [g] : [g, g.toLowerCase()]));
|
|
118
|
-
}
|
|
119
|
-
/** `a|b` at the top level is two independent hostnames, so it is two globs. */
|
|
120
|
-
function regexSourceToGlobs(source) {
|
|
121
|
-
return splitTopLevelAlternation(source).map(branchToGlob);
|
|
122
|
-
}
|
|
123
|
-
function splitTopLevelAlternation(source) {
|
|
124
|
-
const parts = [];
|
|
125
|
-
let depth = 0;
|
|
126
|
-
let inClass = false;
|
|
127
|
-
let start = 0;
|
|
128
|
-
for (let i = 0; i < source.length; i++) {
|
|
129
|
-
const c = source[i];
|
|
130
|
-
if (c === '\\') {
|
|
131
|
-
i++;
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (inClass) {
|
|
135
|
-
if (c === ']')
|
|
136
|
-
inClass = false;
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
if (c === '[') {
|
|
140
|
-
inClass = true;
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
if (c === '(') {
|
|
144
|
-
depth++;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (c === ')') {
|
|
148
|
-
depth = Math.max(0, depth - 1);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
if (c === '|' && depth === 0) {
|
|
152
|
-
parts.push(source.slice(start, i));
|
|
153
|
-
start = i + 1;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
parts.push(source.slice(start));
|
|
157
|
-
return parts;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* One alternation-free regex source -> one glob. Literal characters survive;
|
|
161
|
-
* every construct that can match more than itself collapses to `*`. An empty
|
|
162
|
-
* result is `*` on purpose: an empty regex matches every hostname, so the glob
|
|
163
|
-
* that mirrors it has to match every URL.
|
|
164
|
-
*/
|
|
165
|
-
function branchToGlob(branch) {
|
|
166
|
-
const atoms = [];
|
|
167
|
-
let i = 0;
|
|
168
|
-
while (i < branch.length) {
|
|
169
|
-
const c = branch[i];
|
|
170
|
-
let atom;
|
|
171
|
-
if (c === '^' || c === '$') {
|
|
172
|
-
i += 1;
|
|
173
|
-
continue;
|
|
174
|
-
} // anchors constrain nothing in a glob
|
|
175
|
-
if (c === '\\') {
|
|
176
|
-
const next = branch[i + 1] ?? '';
|
|
177
|
-
i += 2;
|
|
178
|
-
// \d \w \s \b … are classes/assertions; only escaped punctuation (\., \-)
|
|
179
|
-
// is a literal character.
|
|
180
|
-
atom = /[A-Za-z0-9]/.test(next) ? '*' : globEscape(next);
|
|
181
|
-
}
|
|
182
|
-
else if (c === '[') {
|
|
183
|
-
i = skipCharClass(branch, i);
|
|
184
|
-
atom = '*';
|
|
185
|
-
}
|
|
186
|
-
else if (c === '(') {
|
|
187
|
-
i = skipGroup(branch, i); // groups, non-capturing groups, lookarounds
|
|
188
|
-
atom = '*';
|
|
189
|
-
}
|
|
190
|
-
else if (c === '.') {
|
|
191
|
-
i += 1;
|
|
192
|
-
atom = '*';
|
|
193
|
-
}
|
|
194
|
-
else if (c === ')' || c === ']') {
|
|
195
|
-
i += 1; // unbalanced closer: ignore rather than throw
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
else if (quantifierEnd(branch, i) !== null) {
|
|
199
|
-
// A quantifier with nothing in front of it. Widen whatever preceded it.
|
|
200
|
-
i = quantifierEnd(branch, i);
|
|
201
|
-
if (atoms.length > 0)
|
|
202
|
-
atoms[atoms.length - 1] = '*';
|
|
203
|
-
else
|
|
204
|
-
atoms.push('*');
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
i += 1;
|
|
209
|
-
atom = globEscape(c);
|
|
210
|
-
}
|
|
211
|
-
// `x?` / `x*` / `x+` / `x{2,3}`: the atom is optional or repeatable, so the
|
|
212
|
-
// only glob that covers every string it accepts is `*`.
|
|
213
|
-
const after = quantifierEnd(branch, i);
|
|
214
|
-
if (after !== null) {
|
|
215
|
-
i = after;
|
|
216
|
-
atom = '*';
|
|
217
|
-
}
|
|
218
|
-
atoms.push(atom);
|
|
219
|
-
}
|
|
220
|
-
return collapse(atoms).join('');
|
|
221
|
-
}
|
|
222
|
-
/** Index just past a quantifier at `i`, or null when there isn't one. */
|
|
223
|
-
function quantifierEnd(source, i) {
|
|
224
|
-
const c = source[i];
|
|
225
|
-
let end;
|
|
226
|
-
if (c === '*' || c === '+' || c === '?') {
|
|
227
|
-
end = i + 1;
|
|
228
|
-
}
|
|
229
|
-
else if (c === '{') {
|
|
230
|
-
const close = source.indexOf('}', i);
|
|
231
|
-
if (close === -1 || !/^\{\d+(,\d*)?\}$/.test(source.slice(i, close + 1)))
|
|
232
|
-
return null;
|
|
233
|
-
end = close + 1;
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
if (source[end] === '?')
|
|
239
|
-
end += 1; // lazy quantifier
|
|
240
|
-
return end;
|
|
241
|
-
}
|
|
242
|
-
function skipCharClass(source, i) {
|
|
243
|
-
let j = i + 1;
|
|
244
|
-
if (source[j] === '^')
|
|
245
|
-
j++;
|
|
246
|
-
if (source[j] === ']')
|
|
247
|
-
j++; // a leading `]` is a literal
|
|
248
|
-
for (; j < source.length; j++) {
|
|
249
|
-
if (source[j] === '\\') {
|
|
250
|
-
j++;
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
if (source[j] === ']')
|
|
254
|
-
return j + 1;
|
|
255
|
-
}
|
|
256
|
-
return source.length;
|
|
257
|
-
}
|
|
258
|
-
function skipGroup(source, i) {
|
|
259
|
-
let depth = 0;
|
|
260
|
-
let inClass = false;
|
|
261
|
-
for (let j = i; j < source.length; j++) {
|
|
262
|
-
const c = source[j];
|
|
263
|
-
if (c === '\\') {
|
|
264
|
-
j++;
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
if (inClass) {
|
|
268
|
-
if (c === ']')
|
|
269
|
-
inClass = false;
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
if (c === '[') {
|
|
273
|
-
inClass = true;
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
if (c === '(') {
|
|
277
|
-
depth++;
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
if (c === ')') {
|
|
281
|
-
depth--;
|
|
282
|
-
if (depth === 0)
|
|
283
|
-
return j + 1;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return source.length;
|
|
287
|
-
}
|
|
288
|
-
/** `*` and `?` are the glob's own wildcards; `\` is its escape. */
|
|
289
|
-
function globEscape(ch) {
|
|
290
|
-
return ch === '*' || ch === '?' || ch === '\\' ? `\\${ch}` : ch;
|
|
291
|
-
}
|
|
292
|
-
/** `**` matches exactly what `*` does; keep patterns readable. */
|
|
293
|
-
function collapse(atoms) {
|
|
294
|
-
const out = [];
|
|
295
|
-
for (const a of atoms) {
|
|
296
|
-
if (a === '*' && out[out.length - 1] === '*')
|
|
297
|
-
continue;
|
|
298
|
-
out.push(a);
|
|
299
|
-
}
|
|
300
|
-
return out;
|
|
301
|
-
}
|
|
302
|
-
/** `…host…` -> `*host*`, without doubling a `*` the conversion already emitted. */
|
|
303
|
-
function wrap(glob) {
|
|
304
|
-
let body = glob;
|
|
305
|
-
while (body.startsWith('*'))
|
|
306
|
-
body = body.slice(1);
|
|
307
|
-
while (body.length > 0 && body.endsWith('*') && !body.endsWith('\\*'))
|
|
308
|
-
body = body.slice(0, -1);
|
|
309
|
-
return body.length > 0 ? `*${body}*` : '*';
|
|
310
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
declare var SPREEDLY_TOKEN_ENDPOINT: string;
|
|
2
|
-
declare function isSpreedlyTokenRequest(url: any, method?: string): boolean;
|
|
3
|
-
declare function isPreparedSpreedlyRequest(body: any): boolean;
|
|
4
|
-
declare function isSpreedlyRequest(request: any): boolean;
|
|
5
|
-
declare function injectSpreedlyCard(body: any, card: any): {
|
|
6
|
-
body: string;
|
|
7
|
-
where: string[];
|
|
8
|
-
};
|
|
9
|
-
declare function sanitizeSpreedlyTokenResponse(body: any): string;
|
|
10
|
-
export { SPREEDLY_TOKEN_ENDPOINT, injectSpreedlyCard, isPreparedSpreedlyRequest, isSpreedlyRequest, isSpreedlyTokenRequest, sanitizeSpreedlyTokenResponse };
|