@economist/web-apple-pay 1.1.0 → 1.3.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 +27 -2
- package/dist/index.js +76 -0
- package/dist/src/apple-pay-button.js +76 -0
- package/dist/src/apple-pay-button.stories.js +1276 -0
- package/dist/src/apple-pay-modal.stories.js +1118 -0
- package/dist/src/clients/payment-checkout/config.d.ts +1 -0
- package/dist/src/clients/payment-checkout/detects.js +3 -0
- package/dist/src/clients/payment-checkout/index.d.ts +1 -0
- package/dist/src/clients/payment-checkout/index.js +59 -0
- package/dist/src/clients/payment-checkout/session.d.ts +2 -0
- package/dist/src/clients/payment-checkout/session.js +67 -0
- package/dist/src/clients/payment-checkout/types.d.ts +14 -0
- package/dist/src/clients/payment-checkout/types.js +14 -0
- package/dist/src/index.js +76 -0
- package/dist/src/stories/fixtures/offer.d.ts +2 -0
- package/dist/src/stories/fixtures/offer.js +28 -0
- package/dist/src/stories/utils/story-env.d.ts +11 -0
- package/dist/src/stories/utils/story-env.js +141 -0
- package/dist/src/types/offer.types.d.ts +0 -10
- package/package.json +8 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface ApplePayRuntimeConfig {
|
|
2
2
|
merchantId: string;
|
|
3
3
|
debugBypassEnabled?: boolean;
|
|
4
|
+
walletApiBaseUrl: string;
|
|
4
5
|
}
|
|
5
6
|
export declare const configureApplePay: (config: ApplePayRuntimeConfig) => void;
|
|
6
7
|
export declare const getApplePayConfig: () => ApplePayRuntimeConfig | null;
|
|
@@ -29,6 +29,9 @@ var isApplePayAvailable = async () => {
|
|
|
29
29
|
}
|
|
30
30
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
31
31
|
if (!merchantId) {
|
|
32
|
+
console.warn(
|
|
33
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
34
|
+
);
|
|
32
35
|
return false;
|
|
33
36
|
}
|
|
34
37
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const apiFetch: <T>(path: string, options?: RequestInit) => Promise<T>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var getApplePayConfig = () => runtimeConfig;
|
|
4
|
+
|
|
5
|
+
// src/clients/payment-checkout/types.ts
|
|
6
|
+
var ApiError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
body;
|
|
9
|
+
constructor(status, body) {
|
|
10
|
+
super(`API request failed with status ${status}`);
|
|
11
|
+
this.name = "ApiError";
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/clients/payment-checkout/index.ts
|
|
18
|
+
var getWalletApiBaseUrl = () => {
|
|
19
|
+
const config = getApplePayConfig();
|
|
20
|
+
if (!config?.walletApiBaseUrl) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return config.walletApiBaseUrl;
|
|
26
|
+
};
|
|
27
|
+
var apiFetch = async (path, options = {}) => {
|
|
28
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
29
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
30
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
31
|
+
const headers = new Headers(options.headers);
|
|
32
|
+
if (!headers.has("Accept")) {
|
|
33
|
+
headers.set("Accept", "application/json");
|
|
34
|
+
}
|
|
35
|
+
if (!headers.has("Content-Type")) {
|
|
36
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
37
|
+
headers.set("Content-Type", "application/json");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
41
|
+
...options,
|
|
42
|
+
headers
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const contentType = response.headers.get("content-type") || "";
|
|
46
|
+
if (contentType.includes("application/json")) {
|
|
47
|
+
const errorBody = await response.json();
|
|
48
|
+
throw new ApiError(response.status, errorBody);
|
|
49
|
+
}
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
throw new Error(
|
|
52
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return response.json();
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
apiFetch
|
|
59
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var getApplePayConfig = () => runtimeConfig;
|
|
4
|
+
|
|
5
|
+
// src/clients/payment-checkout/types.ts
|
|
6
|
+
var ApiError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
body;
|
|
9
|
+
constructor(status, body) {
|
|
10
|
+
super(`API request failed with status ${status}`);
|
|
11
|
+
this.name = "ApiError";
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/clients/payment-checkout/index.ts
|
|
18
|
+
var getWalletApiBaseUrl = () => {
|
|
19
|
+
const config = getApplePayConfig();
|
|
20
|
+
if (!config?.walletApiBaseUrl) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return config.walletApiBaseUrl;
|
|
26
|
+
};
|
|
27
|
+
var apiFetch = async (path, options = {}) => {
|
|
28
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
29
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
30
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
31
|
+
const headers = new Headers(options.headers);
|
|
32
|
+
if (!headers.has("Accept")) {
|
|
33
|
+
headers.set("Accept", "application/json");
|
|
34
|
+
}
|
|
35
|
+
if (!headers.has("Content-Type")) {
|
|
36
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
37
|
+
headers.set("Content-Type", "application/json");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
41
|
+
...options,
|
|
42
|
+
headers
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const contentType = response.headers.get("content-type") || "";
|
|
46
|
+
if (contentType.includes("application/json")) {
|
|
47
|
+
const errorBody = await response.json();
|
|
48
|
+
throw new ApiError(response.status, errorBody);
|
|
49
|
+
}
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
throw new Error(
|
|
52
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return response.json();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/clients/payment-checkout/session.ts
|
|
59
|
+
var getExpressCheckoutSession = () => {
|
|
60
|
+
return apiFetch("/v1/wallet/session", {
|
|
61
|
+
method: "GET",
|
|
62
|
+
credentials: "include"
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export {
|
|
66
|
+
getExpressCheckoutSession
|
|
67
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type SessionResponse = {
|
|
2
|
+
loggedIn: false;
|
|
3
|
+
userType: 'new-eligible-user';
|
|
4
|
+
} | {
|
|
5
|
+
loggedIn: true;
|
|
6
|
+
emailAddress: string;
|
|
7
|
+
contactId: string;
|
|
8
|
+
userType: 'active-subscription' | 'b2b-user' | 'new-eligible-user';
|
|
9
|
+
};
|
|
10
|
+
export declare class ApiError extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly body: unknown;
|
|
13
|
+
constructor(status: number, body: unknown);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/clients/payment-checkout/types.ts
|
|
2
|
+
var ApiError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
body;
|
|
5
|
+
constructor(status, body) {
|
|
6
|
+
super(`API request failed with status ${status}`);
|
|
7
|
+
this.name = "ApiError";
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.body = body;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
ApiError
|
|
14
|
+
};
|
package/dist/src/index.js
CHANGED
|
@@ -775,6 +775,9 @@ var isApplePayAvailable = async () => {
|
|
|
775
775
|
}
|
|
776
776
|
const merchantId = getApplePayConfig()?.merchantId;
|
|
777
777
|
if (!merchantId) {
|
|
778
|
+
console.warn(
|
|
779
|
+
"[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
|
|
780
|
+
);
|
|
778
781
|
return false;
|
|
779
782
|
}
|
|
780
783
|
return await applePaySession.canMakePaymentsWithActiveCard(merchantId);
|
|
@@ -784,6 +787,67 @@ var isApplePayAvailable = async () => {
|
|
|
784
787
|
}
|
|
785
788
|
};
|
|
786
789
|
|
|
790
|
+
// src/clients/payment-checkout/types.ts
|
|
791
|
+
var ApiError = class extends Error {
|
|
792
|
+
status;
|
|
793
|
+
body;
|
|
794
|
+
constructor(status, body) {
|
|
795
|
+
super(`API request failed with status ${status}`);
|
|
796
|
+
this.name = "ApiError";
|
|
797
|
+
this.status = status;
|
|
798
|
+
this.body = body;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
// src/clients/payment-checkout/index.ts
|
|
803
|
+
var getWalletApiBaseUrl = () => {
|
|
804
|
+
const config = getApplePayConfig();
|
|
805
|
+
if (!config?.walletApiBaseUrl) {
|
|
806
|
+
throw new Error(
|
|
807
|
+
"[web-apple-pay] Missing walletApiBaseUrl. Call configureApplePay({ merchantId, walletApiBaseUrl, ... }) before making wallet API requests."
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
return config.walletApiBaseUrl;
|
|
811
|
+
};
|
|
812
|
+
var apiFetch = async (path, options = {}) => {
|
|
813
|
+
const baseUrl = getWalletApiBaseUrl();
|
|
814
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
815
|
+
const hasBody = options.body !== void 0 && options.body !== null;
|
|
816
|
+
const headers = new Headers(options.headers);
|
|
817
|
+
if (!headers.has("Accept")) {
|
|
818
|
+
headers.set("Accept", "application/json");
|
|
819
|
+
}
|
|
820
|
+
if (!headers.has("Content-Type")) {
|
|
821
|
+
if (hasBody || method !== "GET" && method !== "HEAD") {
|
|
822
|
+
headers.set("Content-Type", "application/json");
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
826
|
+
...options,
|
|
827
|
+
headers
|
|
828
|
+
});
|
|
829
|
+
if (!response.ok) {
|
|
830
|
+
const contentType = response.headers.get("content-type") || "";
|
|
831
|
+
if (contentType.includes("application/json")) {
|
|
832
|
+
const errorBody = await response.json();
|
|
833
|
+
throw new ApiError(response.status, errorBody);
|
|
834
|
+
}
|
|
835
|
+
const errorText = await response.text();
|
|
836
|
+
throw new Error(
|
|
837
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
return response.json();
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// src/clients/payment-checkout/session.ts
|
|
844
|
+
var getExpressCheckoutSession = () => {
|
|
845
|
+
return apiFetch("/v1/wallet/session", {
|
|
846
|
+
method: "GET",
|
|
847
|
+
credentials: "include"
|
|
848
|
+
});
|
|
849
|
+
};
|
|
850
|
+
|
|
787
851
|
// src/apple-pay-button.ts
|
|
788
852
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
789
853
|
var APPLE_PAY_EXCLUDED_VARIANTS = ["bundle", "insider_print"];
|
|
@@ -841,6 +905,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
841
905
|
this.style.display = "none";
|
|
842
906
|
return;
|
|
843
907
|
}
|
|
908
|
+
const sessionData = await this.#fetchSession();
|
|
909
|
+
if (sessionData?.loggedIn && (sessionData.userType === "active-subscription" || sessionData.userType === "b2b-user")) {
|
|
910
|
+
this.style.display = "none";
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
844
913
|
this.style.removeProperty("display");
|
|
845
914
|
ensureApplePayLogoSymbol();
|
|
846
915
|
const template = document.createElement("template");
|
|
@@ -883,6 +952,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
883
952
|
button.setAttribute("disabled", "");
|
|
884
953
|
button.setAttribute("aria-disabled", "true");
|
|
885
954
|
}
|
|
955
|
+
async #fetchSession() {
|
|
956
|
+
try {
|
|
957
|
+
return await getExpressCheckoutSession();
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
886
962
|
};
|
|
887
963
|
|
|
888
964
|
// src/index.ts
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/stories/fixtures/offer.ts
|
|
2
|
+
var STORYBOOK_SAMPLE_OFFER = {
|
|
3
|
+
sku_id: "TEG-APPLEPAY-STORY-001",
|
|
4
|
+
display_name: "Economist Digital",
|
|
5
|
+
price: {
|
|
6
|
+
purchase: 12,
|
|
7
|
+
pre_discount: 24,
|
|
8
|
+
currency_code: "USD",
|
|
9
|
+
discounted: true,
|
|
10
|
+
tax: { inclusive: false }
|
|
11
|
+
},
|
|
12
|
+
product: {
|
|
13
|
+
type: "subscription",
|
|
14
|
+
variant: "digital",
|
|
15
|
+
offer_type: "standard"
|
|
16
|
+
},
|
|
17
|
+
subscription_options: {
|
|
18
|
+
free_trial: false,
|
|
19
|
+
renewal_interval: { duration: 1, unit: "month" },
|
|
20
|
+
renewal_price: 12,
|
|
21
|
+
auto_renewal: true,
|
|
22
|
+
variable_term: false,
|
|
23
|
+
display_name: "Monthly"
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export {
|
|
27
|
+
STORYBOOK_SAMPLE_OFFER
|
|
28
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionResponse } from '../../clients/payment-checkout/types';
|
|
2
|
+
export type ApplePayStoryEnvironmentOptions = {
|
|
3
|
+
applePaySupported: boolean;
|
|
4
|
+
sessionResponse?: SessionResponse;
|
|
5
|
+
sessionStatus?: number;
|
|
6
|
+
debugBypassEnabled?: boolean;
|
|
7
|
+
bypassApplePayChecks?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const applyApplePayStoryEnvironment: ({ applePaySupported, sessionResponse, sessionStatus, debugBypassEnabled, bypassApplePayChecks, }: ApplePayStoryEnvironmentOptions) => void;
|
|
10
|
+
export declare const withApplePayStoryEnvironment: <TArgs>(options: ApplePayStoryEnvironmentOptions, renderFn: (args: TArgs) => HTMLElement) => (args: TArgs) => HTMLElement;
|
|
11
|
+
export declare const clickWhenElementReady: (root: ParentNode, selector: string, maxAttempts?: number) => void;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// src/clients/payment-checkout/config.ts
|
|
2
|
+
var runtimeConfig = null;
|
|
3
|
+
var configureApplePay = (config) => {
|
|
4
|
+
runtimeConfig = {
|
|
5
|
+
...config
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
var resetApplePayConfig = () => {
|
|
9
|
+
runtimeConfig = null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/stories/utils/story-env.ts
|
|
13
|
+
var STORYBOOK_WALLET_BASE_URL = "https://storybook-wallet.economist.com";
|
|
14
|
+
var STORYBOOK_SAFARI_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15";
|
|
15
|
+
var defaultSessionResponse = {
|
|
16
|
+
loggedIn: false,
|
|
17
|
+
userType: "new-eligible-user"
|
|
18
|
+
};
|
|
19
|
+
var resetStoryEnvironment = null;
|
|
20
|
+
var createFetchMock = (sessionResponse, sessionStatus = 200) => {
|
|
21
|
+
return async (input) => {
|
|
22
|
+
const requestUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
23
|
+
if (requestUrl.endsWith("/v1/wallet/session")) {
|
|
24
|
+
if (sessionStatus >= 400) {
|
|
25
|
+
return new Response("Session initialization failed", {
|
|
26
|
+
status: sessionStatus,
|
|
27
|
+
statusText: "Session Init Error"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return new Response(JSON.stringify(sessionResponse), {
|
|
31
|
+
status: 200,
|
|
32
|
+
headers: { "content-type": "application/json" }
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return new Response("Not Found", {
|
|
36
|
+
status: 404,
|
|
37
|
+
statusText: "Not Found"
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
var applyApplePayStoryEnvironment = ({
|
|
42
|
+
applePaySupported,
|
|
43
|
+
sessionResponse = defaultSessionResponse,
|
|
44
|
+
sessionStatus = 200,
|
|
45
|
+
debugBypassEnabled = false,
|
|
46
|
+
bypassApplePayChecks = false
|
|
47
|
+
}) => {
|
|
48
|
+
if (resetStoryEnvironment) {
|
|
49
|
+
resetStoryEnvironment();
|
|
50
|
+
resetStoryEnvironment = null;
|
|
51
|
+
}
|
|
52
|
+
const originalFetch = globalThis.fetch;
|
|
53
|
+
const originalHref = window.location.href;
|
|
54
|
+
const originalUserAgent = navigator.userAgent;
|
|
55
|
+
const originalMaxTouchPoints = navigator.maxTouchPoints;
|
|
56
|
+
const originalApplePaySessionDescriptor = Object.getOwnPropertyDescriptor(
|
|
57
|
+
window,
|
|
58
|
+
"ApplePaySession"
|
|
59
|
+
);
|
|
60
|
+
const mockApplePaySession = {
|
|
61
|
+
canMakePayments: () => applePaySupported,
|
|
62
|
+
canMakePaymentsWithActiveCard: async () => applePaySupported
|
|
63
|
+
};
|
|
64
|
+
Object.defineProperty(window, "ApplePaySession", {
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: mockApplePaySession
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(navigator, "userAgent", {
|
|
70
|
+
configurable: true,
|
|
71
|
+
writable: true,
|
|
72
|
+
value: STORYBOOK_SAFARI_UA
|
|
73
|
+
});
|
|
74
|
+
Object.defineProperty(navigator, "maxTouchPoints", {
|
|
75
|
+
configurable: true,
|
|
76
|
+
writable: true,
|
|
77
|
+
value: 0
|
|
78
|
+
});
|
|
79
|
+
globalThis.fetch = createFetchMock(sessionResponse, sessionStatus);
|
|
80
|
+
const nextUrl = new URL(window.location.href);
|
|
81
|
+
if (bypassApplePayChecks) {
|
|
82
|
+
nextUrl.searchParams.set("BYPASS_APPLE_PAY_CHECKS", "1");
|
|
83
|
+
} else {
|
|
84
|
+
nextUrl.searchParams.delete("BYPASS_APPLE_PAY_CHECKS");
|
|
85
|
+
}
|
|
86
|
+
window.history.replaceState({}, "", nextUrl.toString());
|
|
87
|
+
configureApplePay({
|
|
88
|
+
merchantId: "merchant.com.economist.storybook",
|
|
89
|
+
walletApiBaseUrl: STORYBOOK_WALLET_BASE_URL,
|
|
90
|
+
debugBypassEnabled
|
|
91
|
+
});
|
|
92
|
+
resetStoryEnvironment = () => {
|
|
93
|
+
resetApplePayConfig();
|
|
94
|
+
globalThis.fetch = originalFetch;
|
|
95
|
+
window.history.replaceState({}, "", originalHref);
|
|
96
|
+
Object.defineProperty(navigator, "userAgent", {
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: originalUserAgent
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(navigator, "maxTouchPoints", {
|
|
102
|
+
configurable: true,
|
|
103
|
+
writable: true,
|
|
104
|
+
value: originalMaxTouchPoints
|
|
105
|
+
});
|
|
106
|
+
if (originalApplePaySessionDescriptor) {
|
|
107
|
+
Object.defineProperty(
|
|
108
|
+
window,
|
|
109
|
+
"ApplePaySession",
|
|
110
|
+
originalApplePaySessionDescriptor
|
|
111
|
+
);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
delete window.ApplePaySession;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
var withApplePayStoryEnvironment = (options, renderFn) => (args) => {
|
|
118
|
+
applyApplePayStoryEnvironment(options);
|
|
119
|
+
return renderFn(args);
|
|
120
|
+
};
|
|
121
|
+
var clickWhenElementReady = (root, selector, maxAttempts = 5) => {
|
|
122
|
+
let attempts = 0;
|
|
123
|
+
const tryClick = () => {
|
|
124
|
+
const element = root.querySelector(selector);
|
|
125
|
+
if (element) {
|
|
126
|
+
element.click();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (attempts >= maxAttempts) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
attempts += 1;
|
|
133
|
+
requestAnimationFrame(tryClick);
|
|
134
|
+
};
|
|
135
|
+
requestAnimationFrame(tryClick);
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
applyApplePayStoryEnvironment,
|
|
139
|
+
clickWhenElementReady,
|
|
140
|
+
withApplePayStoryEnvironment
|
|
141
|
+
};
|
|
@@ -71,13 +71,3 @@ export type Offer = {
|
|
|
71
71
|
content?: Content;
|
|
72
72
|
meta_data?: MetaData;
|
|
73
73
|
};
|
|
74
|
-
/** Total number of items matching the relevant lookup. */
|
|
75
|
-
export type ResponseModelMetaTotal = {
|
|
76
|
-
total: number;
|
|
77
|
-
};
|
|
78
|
-
export type ResponsePostPricedSkuOffer = {
|
|
79
|
-
/** Offer list. */
|
|
80
|
-
data: Offer[] | null;
|
|
81
|
-
/** Set of key value pairs. */
|
|
82
|
-
meta: ResponseModelMetaTotal | null;
|
|
83
|
-
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@economist/web-apple-pay",
|
|
3
3
|
"description": "Web component package for Apple Pay checkout UI",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"test": "jest",
|
|
24
24
|
"test:coverage": "npm run test -- --coverage",
|
|
25
|
+
"storybook": "storybook dev -p 6006",
|
|
26
|
+
"build-storybook": "storybook build",
|
|
25
27
|
"lint": "eslint .",
|
|
26
28
|
"lint:fix": "npm run lint -- --fix",
|
|
27
29
|
"tsc": "tsc --project tsconfig.json",
|
|
@@ -32,6 +34,10 @@
|
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
36
|
"@eslint/js": "^9.25.1",
|
|
37
|
+
"@storybook/addon-essentials": "^8.6.18",
|
|
38
|
+
"@storybook/addon-interactions": "^8.6.18",
|
|
39
|
+
"@storybook/test": "^8.6.18",
|
|
40
|
+
"@storybook/web-components-vite": "^8.6.18",
|
|
35
41
|
"@types/jest": "29.5.3",
|
|
36
42
|
"esbuild": "^0.25.3",
|
|
37
43
|
"eslint": "^9.25.1",
|
|
@@ -39,6 +45,7 @@
|
|
|
39
45
|
"jest": "^29.7.0",
|
|
40
46
|
"jest-environment-jsdom": "^29.7.0",
|
|
41
47
|
"prettier": "3.0.1",
|
|
48
|
+
"storybook": "^8.6.18",
|
|
42
49
|
"ts-jest": "29.2.5",
|
|
43
50
|
"ts-node": "10.9.1",
|
|
44
51
|
"typescript": "^5.8.2",
|