@crvouga/mockingbird-service-stripe 2.1.0 → 2.2.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 +18 -4
- package/README.md +6 -1
- package/dist/{chunk-IWIBLNQX.js → chunk-4G5L7P7I.js} +2 -2
- package/dist/{chunk-LUKVBQDH.js → chunk-7ZVXTTT4.js} +230 -24
- package/dist/chunk-7ZVXTTT4.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-LUKVBQDH.js.map +0 -7
- /package/dist/{chunk-IWIBLNQX.js.map → chunk-4G5L7P7I.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-stripe
|
|
2
2
|
|
|
3
|
+
## 2.2.1 (2026-10-05)
|
|
4
|
+
|
|
5
|
+
### Fixes and improvements
|
|
6
|
+
|
|
7
|
+
- validate card element input ([d53f042](https://github.com/crvouga/mockingbird/commit/d53f042089ee20b2708b489e5412065013309a55))
|
|
8
|
+
- reject empty customer account filters ([b7910c7](https://github.com/crvouga/mockingbird/commit/b7910c73ad24fb1ae6767fc83effce76bfd09eaa))
|
|
9
|
+
- render split card elements independently ([99e9a5d](https://github.com/crvouga/mockingbird/commit/99e9a5d82f9189ca5d347ff5d071d05f2d9fbf21))
|
|
10
|
+
|
|
11
|
+
## 2.2.0 (2026-10-04)
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- add scripted local API mock ([4a76a11](https://github.com/crvouga/mockingbird/commit/4a76a114e2efad45934e0a93cf29576fd418e15c))
|
|
16
|
+
|
|
17
|
+
### Fixes and improvements
|
|
18
|
+
|
|
19
|
+
- support embedded route parameters ([127cad9](https://github.com/crvouga/mockingbird/commit/127cad997ef106950c1b866070eea191ba54403f))
|
|
20
|
+
|
|
3
21
|
## 2.1.0 (2026-10-04)
|
|
4
22
|
|
|
5
23
|
### Features
|
|
@@ -12,10 +30,6 @@
|
|
|
12
30
|
- fill the embedded viewport ([c1a35a4](https://github.com/crvouga/mockingbird/commit/c1a35a4789389ee9cd06c286d09bd47c4d06c71e))
|
|
13
31
|
- make dialog cleanup immediate ([0c1a3c5](https://github.com/crvouga/mockingbird/commit/0c1a3c5b12584d50c19dcae595b951b8e5417b9c))
|
|
14
32
|
|
|
15
|
-
### Dependencies
|
|
16
|
-
|
|
17
|
-
- `@crvouga/mockingbird-service-sqlite`
|
|
18
|
-
|
|
19
33
|
## 2.0.0 (2026-10-04)
|
|
20
34
|
|
|
21
35
|
### ⚠️ Breaking changes
|
package/README.md
CHANGED
|
@@ -252,7 +252,12 @@ finalize; a customer credit balance is applied at finalize; `void` works only on
|
|
|
252
252
|
payment mode, inactive prices, mixed currencies, quantities below 1, `trial_end` under 48 h.
|
|
253
253
|
- `POST /__admin/checkout/sessions/:id/complete {"card": "4242…"}` does the same without a browser;
|
|
254
254
|
`…/expire` and `…/async_payment_succeeded` too.
|
|
255
|
-
- `GET /v3` — the Stripe.js stand-in: `Stripe(pk)`, `elements()` → `create("payment"|"card")
|
|
255
|
+
- `GET /v3` — the Stripe.js stand-in: `Stripe(pk)`, `elements()` → combined `create("payment"|"card")`
|
|
256
|
+
or split `create("cardNumber"|"cardExpiry"|"cardCvc")` inputs. Split inputs share card data
|
|
257
|
+
within their `Elements` group, add no visible labels, and the combined card honors
|
|
258
|
+
`hidePostalCode`. Card inputs format number/expiry/CVC values, report field-level `empty`,
|
|
259
|
+
`complete`, `brand`, and validation errors through change events, and refuse tokenization until
|
|
260
|
+
all required split or combined values are valid. It also provides
|
|
256
261
|
`confirmPayment`, `confirmSetup`, `confirmCardPayment`, `confirmCardSetup`,
|
|
257
262
|
`retrievePaymentIntent`, `retrieveSetupIntent`, `createPaymentMethod`, `handleCardAction`. It calls
|
|
258
263
|
`POST /v1/{payment,setup}_intents/:id/confirm` with the publishable key and `client_secret` (the
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
parseDuration,
|
|
5
5
|
resolveAdminPrefix,
|
|
6
6
|
validateAccounts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7ZVXTTT4.js";
|
|
8
8
|
|
|
9
9
|
// src/server.ts
|
|
10
10
|
import { readFileSync } from "node:fs";
|
|
@@ -874,4 +874,4 @@ export {
|
|
|
874
874
|
createServer2 as createServer,
|
|
875
875
|
serveTarget
|
|
876
876
|
};
|
|
877
|
-
//# sourceMappingURL=chunk-
|
|
877
|
+
//# sourceMappingURL=chunk-4G5L7P7I.js.map
|
|
@@ -1028,7 +1028,40 @@ var decodeBody = (contentType, bytes) => {
|
|
|
1028
1028
|
return { kind: "bytes", value: bytes };
|
|
1029
1029
|
};
|
|
1030
1030
|
var readBody = async (message) => {
|
|
1031
|
-
|
|
1031
|
+
if (!(message instanceof Request) || !message.body) {
|
|
1032
|
+
if (message instanceof Request)
|
|
1033
|
+
message.signal.throwIfAborted();
|
|
1034
|
+
return decodeBody(message.headers.get("content-type"), new Uint8Array(await message.arrayBuffer()));
|
|
1035
|
+
}
|
|
1036
|
+
message.signal.throwIfAborted();
|
|
1037
|
+
const reader = message.body.getReader();
|
|
1038
|
+
const cancel = () => {
|
|
1039
|
+
void reader.cancel(message.signal.reason).catch(() => {
|
|
1040
|
+
});
|
|
1041
|
+
};
|
|
1042
|
+
message.signal.addEventListener("abort", cancel, { once: true });
|
|
1043
|
+
const chunks = [];
|
|
1044
|
+
let size = 0;
|
|
1045
|
+
try {
|
|
1046
|
+
for (; ; ) {
|
|
1047
|
+
message.signal.throwIfAborted();
|
|
1048
|
+
const { done, value } = await reader.read();
|
|
1049
|
+
message.signal.throwIfAborted();
|
|
1050
|
+
if (done)
|
|
1051
|
+
break;
|
|
1052
|
+
chunks.push(value);
|
|
1053
|
+
size += value.byteLength;
|
|
1054
|
+
}
|
|
1055
|
+
} finally {
|
|
1056
|
+
message.signal.removeEventListener("abort", cancel);
|
|
1057
|
+
reader.releaseLock();
|
|
1058
|
+
}
|
|
1059
|
+
const bytes = new Uint8Array(size);
|
|
1060
|
+
let offset = 0;
|
|
1061
|
+
for (const chunk of chunks) {
|
|
1062
|
+
bytes.set(chunk, offset);
|
|
1063
|
+
offset += chunk.byteLength;
|
|
1064
|
+
}
|
|
1032
1065
|
return decodeBody(message.headers.get("content-type"), bytes);
|
|
1033
1066
|
};
|
|
1034
1067
|
|
|
@@ -1743,7 +1776,42 @@ var verifyOperations = (document2, handlers) => {
|
|
|
1743
1776
|
}
|
|
1744
1777
|
return problems;
|
|
1745
1778
|
};
|
|
1746
|
-
var
|
|
1779
|
+
var escapePattern = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1780
|
+
var serviceRoute = (template) => {
|
|
1781
|
+
const names = [];
|
|
1782
|
+
let pattern = "", end = 0;
|
|
1783
|
+
for (const match of template.matchAll(/\{([^}]+)\}/g)) {
|
|
1784
|
+
pattern += `${escapePattern(template.slice(end, match.index))}([^/]+?)`;
|
|
1785
|
+
const name = match[1];
|
|
1786
|
+
if (!name)
|
|
1787
|
+
throw new Error(`Invalid OpenAPI route template: ${template}`);
|
|
1788
|
+
names.push(name);
|
|
1789
|
+
end = match.index + match[0].length;
|
|
1790
|
+
}
|
|
1791
|
+
pattern += escapePattern(template.slice(end));
|
|
1792
|
+
const matcher = new RegExp(`^${pattern}$`);
|
|
1793
|
+
const path = template.split("/").map((segment, index) => {
|
|
1794
|
+
if (!segment.includes("{"))
|
|
1795
|
+
return segment;
|
|
1796
|
+
const literal = /^\{([^}]+)\}$/.exec(segment);
|
|
1797
|
+
if (literal)
|
|
1798
|
+
return `:${literal[1]}`;
|
|
1799
|
+
let expression = "", offset = 0;
|
|
1800
|
+
for (const match of segment.matchAll(/\{[^}]+\}/g)) {
|
|
1801
|
+
expression += `${escapePattern(segment.slice(offset, match.index))}[^/]+?`;
|
|
1802
|
+
offset = match.index + match[0].length;
|
|
1803
|
+
}
|
|
1804
|
+
expression += escapePattern(segment.slice(offset));
|
|
1805
|
+
return `:mockingbirdSegment${index}{${expression}}`;
|
|
1806
|
+
}).join("/");
|
|
1807
|
+
return {
|
|
1808
|
+
path,
|
|
1809
|
+
params: (pathname) => {
|
|
1810
|
+
const values = matcher.exec(pathname);
|
|
1811
|
+
return Object.fromEntries(names.map((name, index) => [name, decodeURIComponent(values?.[index + 1] ?? "")]));
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
};
|
|
1747
1815
|
var routeOrder = (a, b) => {
|
|
1748
1816
|
const sa = a.path.split("/");
|
|
1749
1817
|
const sb = b.path.split("/");
|
|
@@ -1778,6 +1846,7 @@ var createService = (options) => {
|
|
|
1778
1846
|
for (const operation of operations) {
|
|
1779
1847
|
const metadata = operationMetadata(operation.operation);
|
|
1780
1848
|
const handler = options.handlers[operation.operationId];
|
|
1849
|
+
const registeredRoute = serviceRoute(operation.path);
|
|
1781
1850
|
const route = async (c) => {
|
|
1782
1851
|
const request = c.req.raw;
|
|
1783
1852
|
if (!metadata.supported || !handler) {
|
|
@@ -1787,7 +1856,7 @@ var createService = (options) => {
|
|
|
1787
1856
|
const context = {
|
|
1788
1857
|
request,
|
|
1789
1858
|
url,
|
|
1790
|
-
params:
|
|
1859
|
+
params: registeredRoute.params(url.pathname),
|
|
1791
1860
|
query: queryOf(url),
|
|
1792
1861
|
body: await readBody(request),
|
|
1793
1862
|
sqlite: options.sqlite,
|
|
@@ -1799,7 +1868,7 @@ var createService = (options) => {
|
|
|
1799
1868
|
const short = await options.before?.(context);
|
|
1800
1869
|
return withIssues(request, short ?? await handler(context));
|
|
1801
1870
|
};
|
|
1802
|
-
app.on(operation.method.toUpperCase(),
|
|
1871
|
+
app.on(operation.method.toUpperCase(), registeredRoute.path, route);
|
|
1803
1872
|
}
|
|
1804
1873
|
return {
|
|
1805
1874
|
app,
|
|
@@ -2268,7 +2337,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
2268
2337
|
};
|
|
2269
2338
|
|
|
2270
2339
|
// ../core/dist/version.js
|
|
2271
|
-
var PACKAGE_VERSION = true ? "2.1
|
|
2340
|
+
var PACKAGE_VERSION = true ? "2.2.1" : UNRELEASED_VERSION;
|
|
2272
2341
|
|
|
2273
2342
|
// ../core/dist/signing.js
|
|
2274
2343
|
var encoder = new TextEncoder();
|
|
@@ -11748,9 +11817,120 @@ var stripeJs = (base2) => `/* Mockingbird Stripe.js stand-in */
|
|
|
11748
11817
|
["cvc", "CVC", "stripe-mock-cvc", "123"],
|
|
11749
11818
|
["zip", "ZIP", "stripe-mock-zip", "94107"],
|
|
11750
11819
|
];
|
|
11751
|
-
function
|
|
11820
|
+
function fieldsFor(type, options) {
|
|
11821
|
+
var names = type === "cardNumber" ? ["card"]
|
|
11822
|
+
: type === "cardExpiry" ? ["exp"]
|
|
11823
|
+
: type === "cardCvc" ? ["cvc"]
|
|
11824
|
+
: type === "postalCode" ? ["zip"]
|
|
11825
|
+
: FIELDS.map(function (field) { return field[0]; });
|
|
11826
|
+
if (type === "card" && options && options.hidePostalCode) {
|
|
11827
|
+
names = names.filter(function (name) { return name !== "zip"; });
|
|
11828
|
+
}
|
|
11829
|
+
return FIELDS.filter(function (field) { return names.indexOf(field[0]) !== -1; });
|
|
11830
|
+
}
|
|
11831
|
+
function digits(value) { return String(value || "").replace(/\\D/g, ""); }
|
|
11832
|
+
function brandOf(value) {
|
|
11833
|
+
var number = digits(value);
|
|
11834
|
+
if (/^3[47]/.test(number)) return "amex";
|
|
11835
|
+
if (/^(5[1-5]|2[2-7])/.test(number)) return "mastercard";
|
|
11836
|
+
if (/^(6011|65)/.test(number)) return "discover";
|
|
11837
|
+
if (/^4/.test(number)) return "visa";
|
|
11838
|
+
return "unknown";
|
|
11839
|
+
}
|
|
11840
|
+
function luhn(number) {
|
|
11841
|
+
var sum = 0;
|
|
11842
|
+
var alternate = false;
|
|
11843
|
+
for (var index = number.length - 1; index >= 0; index -= 1) {
|
|
11844
|
+
var digit = Number(number[index]);
|
|
11845
|
+
if (alternate) { digit *= 2; if (digit > 9) digit -= 9; }
|
|
11846
|
+
sum += digit;
|
|
11847
|
+
alternate = !alternate;
|
|
11848
|
+
}
|
|
11849
|
+
return number.length > 0 && sum % 10 === 0;
|
|
11850
|
+
}
|
|
11851
|
+
function cardError(code, message) {
|
|
11852
|
+
return { type: "validation_error", code: code, message: message };
|
|
11853
|
+
}
|
|
11854
|
+
function validateField(element, name) {
|
|
11855
|
+
var raw = element.value(name);
|
|
11856
|
+
if (name === "card") {
|
|
11857
|
+
var number = digits(raw);
|
|
11858
|
+
var brand = brandOf(number);
|
|
11859
|
+
var expected = brand === "amex" ? 15 : 16;
|
|
11860
|
+
if (!number || number.length < expected) return cardError("incomplete_number", "Your card number is incomplete.");
|
|
11861
|
+
if (number.length !== expected || !luhn(number)) return cardError("invalid_number", "Your card number is invalid.");
|
|
11862
|
+
}
|
|
11863
|
+
if (name === "exp") {
|
|
11864
|
+
var expiry = digits(raw);
|
|
11865
|
+
if (expiry.length < 4) return cardError("incomplete_expiry", "Your card's expiration date is incomplete.");
|
|
11866
|
+
var month = Number(expiry.slice(0, 2));
|
|
11867
|
+
var year = 2000 + Number(expiry.slice(2, 4));
|
|
11868
|
+
if (month < 1 || month > 12) return cardError("invalid_expiry_month", "Your card's expiration month is invalid.");
|
|
11869
|
+
var now = new Date();
|
|
11870
|
+
if (year < now.getFullYear() || (year === now.getFullYear() && month < now.getMonth() + 1)) {
|
|
11871
|
+
return cardError("invalid_expiry_year_past", "Your card's expiration year is in the past.");
|
|
11872
|
+
}
|
|
11873
|
+
}
|
|
11874
|
+
if (name === "cvc") {
|
|
11875
|
+
var cvc = digits(raw);
|
|
11876
|
+
var cvcLength = brandOf(element.value("card")) === "amex" ? 4 : 3;
|
|
11877
|
+
if (cvc.length < cvcLength) return cardError("incomplete_cvc", "Your card's security code is incomplete.");
|
|
11878
|
+
if (cvc.length !== cvcLength) return cardError("invalid_cvc", "Your card's security code is invalid.");
|
|
11879
|
+
}
|
|
11880
|
+
if (name === "zip" && !String(raw || "").trim()) {
|
|
11881
|
+
return cardError("incomplete_zip", "Your postal code is incomplete.");
|
|
11882
|
+
}
|
|
11883
|
+
return null;
|
|
11884
|
+
}
|
|
11885
|
+
function stateOf(element) {
|
|
11886
|
+
var fields = fieldsFor(element.type, element.options);
|
|
11887
|
+
var empty = fields.every(function (field) { return String(element.value(field[0]) || "") === ""; });
|
|
11888
|
+
var error = null;
|
|
11889
|
+
for (var index = 0; index < fields.length && !error; index += 1) error = validateField(element, fields[index][0]);
|
|
11890
|
+
var event = { complete: !error, empty: empty, elementType: element.type };
|
|
11891
|
+
if (error) event.error = error;
|
|
11892
|
+
if (element.type === "card" || element.type === "cardNumber") event.brand = brandOf(element.value("card"));
|
|
11893
|
+
return event;
|
|
11894
|
+
}
|
|
11895
|
+
function cardValidationOf(element) {
|
|
11896
|
+
var card = element.card();
|
|
11897
|
+
var values = {
|
|
11898
|
+
card: card.number,
|
|
11899
|
+
exp: String(card.exp_month || "").padStart(2, "0") + "/" + String(card.exp_year || "").slice(-2),
|
|
11900
|
+
cvc: card.cvc,
|
|
11901
|
+
};
|
|
11902
|
+
var cardView = { value: function (name) { return values[name] || ""; } };
|
|
11903
|
+
var names = ["card", "exp", "cvc"];
|
|
11904
|
+
for (var index = 0; index < names.length; index += 1) {
|
|
11905
|
+
var error = validateField(cardView, names[index]);
|
|
11906
|
+
if (error) return error;
|
|
11907
|
+
}
|
|
11908
|
+
return null;
|
|
11909
|
+
}
|
|
11910
|
+
function formatInput(element, input) {
|
|
11911
|
+
if (input.name === "card") {
|
|
11912
|
+
var number = digits(input.value).slice(0, 19);
|
|
11913
|
+
var brand = brandOf(number);
|
|
11914
|
+
var sizes = brand === "amex" ? [4, 6, 5] : [4, 4, 4, 4, 3];
|
|
11915
|
+
var groups = [];
|
|
11916
|
+
var offset = 0;
|
|
11917
|
+
sizes.forEach(function (size) {
|
|
11918
|
+
if (offset < number.length) groups.push(number.slice(offset, offset + size));
|
|
11919
|
+
offset += size;
|
|
11920
|
+
});
|
|
11921
|
+
input.value = groups.join(" ");
|
|
11922
|
+
} else if (input.name === "exp") {
|
|
11923
|
+
var expiry = digits(input.value).slice(0, 4);
|
|
11924
|
+
input.value = expiry.length > 2 ? expiry.slice(0, 2) + "/" + expiry.slice(2) : expiry;
|
|
11925
|
+
} else if (input.name === "cvc") {
|
|
11926
|
+
var limit = brandOf(element.value("card")) === "amex" ? 4 : 3;
|
|
11927
|
+
input.value = digits(input.value).slice(0, limit);
|
|
11928
|
+
}
|
|
11929
|
+
}
|
|
11930
|
+
function Element(type, options, group) {
|
|
11752
11931
|
this.type = type;
|
|
11753
11932
|
this.options = options || {};
|
|
11933
|
+
this.group = group;
|
|
11754
11934
|
this.node = null;
|
|
11755
11935
|
this.handlers = {};
|
|
11756
11936
|
}
|
|
@@ -11760,45 +11940,63 @@ var stripeJs = (base2) => `/* Mockingbird Stripe.js stand-in */
|
|
|
11760
11940
|
var root = document.createElement("div");
|
|
11761
11941
|
root.setAttribute("data-testid", "stripe-mock-element");
|
|
11762
11942
|
root.setAttribute("data-element-type", this.type);
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11943
|
+
var split = this.type === "cardNumber" || this.type === "cardExpiry" || this.type === "cardCvc" || this.type === "postalCode";
|
|
11944
|
+
var self = this;
|
|
11945
|
+
fieldsFor(this.type, this.options).forEach(function (field) {
|
|
11766
11946
|
var input = document.createElement("input");
|
|
11767
11947
|
input.name = field[0];
|
|
11768
11948
|
input.setAttribute("data-testid", field[2]);
|
|
11949
|
+
input.setAttribute("aria-label", field[1]);
|
|
11769
11950
|
input.placeholder = field[3];
|
|
11770
|
-
|
|
11771
|
-
|
|
11951
|
+
input.addEventListener("input", function () {
|
|
11952
|
+
formatInput(self, input);
|
|
11953
|
+
self.emit("change", stateOf(self));
|
|
11954
|
+
});
|
|
11955
|
+
input.addEventListener("focus", function () { self.emit("focus", { elementType: self.type }); });
|
|
11956
|
+
input.addEventListener("blur", function () { self.emit("blur", { elementType: self.type }); });
|
|
11957
|
+
if (split) {
|
|
11958
|
+
root.appendChild(input);
|
|
11959
|
+
} else {
|
|
11960
|
+
var label = document.createElement("label");
|
|
11961
|
+
label.textContent = field[1];
|
|
11962
|
+
label.appendChild(input);
|
|
11963
|
+
root.appendChild(label);
|
|
11964
|
+
}
|
|
11772
11965
|
});
|
|
11773
11966
|
host.appendChild(root);
|
|
11774
11967
|
this.node = root;
|
|
11775
|
-
var self = this;
|
|
11776
|
-
root.addEventListener("input", function () { self.emit("change", { complete: true, empty: false, elementType: self.type }); });
|
|
11777
11968
|
setTimeout(function () { self.emit("ready", { elementType: self.type }); }, 0);
|
|
11778
11969
|
return this;
|
|
11779
11970
|
};
|
|
11780
11971
|
Element.prototype.value = function (name) {
|
|
11781
11972
|
var input = this.node && this.node.querySelector('[name="' + name + '"]');
|
|
11782
|
-
|
|
11973
|
+
if (input) return input.value;
|
|
11974
|
+
for (var index = 0; index < this.group.length; index += 1) {
|
|
11975
|
+
var sibling = this.group[index];
|
|
11976
|
+
var siblingInput = sibling !== this && sibling.node && sibling.node.querySelector('[name="' + name + '"]');
|
|
11977
|
+
if (siblingInput) return siblingInput.value;
|
|
11978
|
+
}
|
|
11979
|
+
return "";
|
|
11783
11980
|
};
|
|
11784
11981
|
Element.prototype.card = function () {
|
|
11785
|
-
var exp = (this.value("exp") || "
|
|
11786
|
-
var year = Number(exp[1] || "
|
|
11982
|
+
var exp = String(this.value("exp") || "").split("/");
|
|
11983
|
+
var year = Number(exp[1] || "0");
|
|
11787
11984
|
return {
|
|
11788
|
-
number: (this.value("card")
|
|
11789
|
-
exp_month: Number(exp[0] || "
|
|
11985
|
+
number: digits(this.value("card")),
|
|
11986
|
+
exp_month: Number(exp[0] || "0"),
|
|
11790
11987
|
exp_year: year < 100 ? 2000 + year : year,
|
|
11791
|
-
cvc: this.value("cvc")
|
|
11988
|
+
cvc: digits(this.value("cvc")),
|
|
11792
11989
|
};
|
|
11793
11990
|
};
|
|
11991
|
+
Element.prototype.validation = function () { return stateOf(this); };
|
|
11794
11992
|
Element.prototype.on = function (name, handler) { (this.handlers[name] = this.handlers[name] || []).push(handler); return this; };
|
|
11795
11993
|
Element.prototype.off = function (name, handler) { this.handlers[name] = (this.handlers[name] || []).filter(function (h) { return h !== handler; }); return this; };
|
|
11796
11994
|
Element.prototype.once = function (name, handler) { var self = this; var wrapped = function (e) { self.off(name, wrapped); handler(e); }; return this.on(name, wrapped); };
|
|
11797
11995
|
Element.prototype.emit = function (name, event) { (this.handlers[name] || []).forEach(function (h) { h(event); }); };
|
|
11798
|
-
Element.prototype.update = function (options) { this.options = Object.assign(this.options, options || {}); };
|
|
11996
|
+
Element.prototype.update = function (options) { this.options = Object.assign(this.options, options || {}); if (this.node) this.emit("change", stateOf(this)); };
|
|
11799
11997
|
Element.prototype.focus = function () { var input = this.node && this.node.querySelector("input"); if (input) input.focus(); };
|
|
11800
|
-
Element.prototype.blur = function () {};
|
|
11801
|
-
Element.prototype.clear = function () { if (this.node) this.node.querySelectorAll("input").forEach(function (i) { i.value = ""; }); };
|
|
11998
|
+
Element.prototype.blur = function () { var input = this.node && this.node.querySelector("input"); if (input && input.blur) input.blur(); };
|
|
11999
|
+
Element.prototype.clear = function () { if (this.node) this.node.querySelectorAll("input").forEach(function (i) { i.value = ""; }); this.emit("change", stateOf(this)); };
|
|
11802
12000
|
Element.prototype.collapse = function () {};
|
|
11803
12001
|
Element.prototype.unmount = function () { if (this.node && this.node.parentNode) this.node.parentNode.removeChild(this.node); this.node = null; };
|
|
11804
12002
|
Element.prototype.destroy = Element.prototype.unmount;
|
|
@@ -11814,7 +12012,7 @@ var stripeJs = (base2) => `/* Mockingbird Stripe.js stand-in */
|
|
|
11814
12012
|
return {
|
|
11815
12013
|
_clientSecret: clientSecret,
|
|
11816
12014
|
_elements: created,
|
|
11817
|
-
create: function (type, opts) { var element = new Element(type, opts); created.push(element); return element; },
|
|
12015
|
+
create: function (type, opts) { var element = new Element(type, opts, created); created.push(element); return element; },
|
|
11818
12016
|
getElement: function (type) {
|
|
11819
12017
|
var elementType = type && type.__elementType ? type.__elementType : type;
|
|
11820
12018
|
return created.filter(function (e) { return e.type === elementType || (e.type === "payment" && type && type.type === "payment"); })[0] || null;
|
|
@@ -11845,6 +12043,13 @@ var stripeJs = (base2) => `/* Mockingbird Stripe.js stand-in */
|
|
|
11845
12043
|
"4000051230000072": "tok_hsa",
|
|
11846
12044
|
};
|
|
11847
12045
|
Stripe.prototype.createToken = function (element) {
|
|
12046
|
+
var validation = element && typeof element.validation === "function" ? cardValidationOf(element) : null;
|
|
12047
|
+
if (validation) {
|
|
12048
|
+
return Promise.resolve({ error: validation });
|
|
12049
|
+
}
|
|
12050
|
+
if (!element) {
|
|
12051
|
+
return Promise.resolve({ error: cardError("incomplete_number", "Your card number is incomplete.") });
|
|
12052
|
+
}
|
|
11848
12053
|
var card = element && typeof element.card === "function" ? element.card() : null;
|
|
11849
12054
|
var number = card && String(card.number || "").replace(/[\\s-]/g, "");
|
|
11850
12055
|
var token = number && CARD_TOKENS[number];
|
|
@@ -13358,6 +13563,7 @@ var paymentMethodHandlers = (services) => ({
|
|
|
13358
13563
|
render: renderPaymentMethod
|
|
13359
13564
|
});
|
|
13360
13565
|
const account = stringOf(params, "customer_account");
|
|
13566
|
+
if (context.query.customer_account === "") throw parameterInvalidEmpty("customer_account");
|
|
13361
13567
|
if (account !== null && account !== "")
|
|
13362
13568
|
throw resourceMissing("customer", account, "customer_account", 400);
|
|
13363
13569
|
return jsonRes(200, page);
|
|
@@ -18950,4 +19156,4 @@ export {
|
|
|
18950
19156
|
createRuntime2 as createRuntime,
|
|
18951
19157
|
StripeAPI
|
|
18952
19158
|
};
|
|
18953
|
-
//# sourceMappingURL=chunk-
|
|
19159
|
+
//# sourceMappingURL=chunk-7ZVXTTT4.js.map
|