Initial project import
This commit is contained in:
210
node_modules/@stripe/stripe-js/src/index.test.ts
generated
vendored
Normal file
210
node_modules/@stripe/stripe-js/src/index.test.ts
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
import {SCRIPT_SRC} from './testUtils';
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
const dispatchScriptEvent = (eventType: string): void => {
|
||||
const injectedScript = document.querySelector(`script[src="${SCRIPT_SRC}"]`);
|
||||
|
||||
if (!injectedScript) {
|
||||
throw new Error('could not find Stripe.js script element');
|
||||
}
|
||||
|
||||
injectedScript.dispatchEvent(new Event(eventType));
|
||||
};
|
||||
|
||||
describe('Stripe module loader', () => {
|
||||
afterEach(() => {
|
||||
const script = document.querySelector(
|
||||
'script[src^="https://js.stripe.com/"]'
|
||||
);
|
||||
if (script && script.parentElement) {
|
||||
script.parentElement.removeChild(script);
|
||||
}
|
||||
|
||||
delete window.Stripe;
|
||||
jest.resetModules();
|
||||
});
|
||||
|
||||
it('injects the Stripe script as a side effect after a tick', () => {
|
||||
require('./index');
|
||||
|
||||
expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).toBe(null);
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).not.toBe(
|
||||
null
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not inject the script when Stripe is already loaded', () => {
|
||||
require('./index');
|
||||
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
|
||||
return new Promise((resolve) => setTimeout(resolve)).then(() => {
|
||||
expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('does not inject a duplicate script when one is already present', () => {
|
||||
test('when the script has a trailing slash', () => {
|
||||
require('./index');
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = SCRIPT_SRC;
|
||||
document.body.appendChild(script);
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
expect(
|
||||
document.querySelectorAll(`script[src="${SCRIPT_SRC}"]`)
|
||||
).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('ignores non-Stripe.js scripts that start with the v3 url', async () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://js.stripe.com/v3/futureBundle.js';
|
||||
document.body.appendChild(script);
|
||||
|
||||
require('./index');
|
||||
|
||||
await Promise.resolve();
|
||||
|
||||
expect(
|
||||
document.querySelectorAll('script[src^="https://js.stripe.com"]')
|
||||
).toHaveLength(2);
|
||||
|
||||
expect(
|
||||
document.querySelector(
|
||||
'script[src="https://js.stripe.com/v3/futureBundle.js"]'
|
||||
)
|
||||
).not.toBe(null);
|
||||
|
||||
expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).not.toBe(
|
||||
null
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe.each(['./index', './pure'])('loadStripe (%s.ts)', (requirePath) => {
|
||||
beforeEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
jest.spyOn(console, 'warn').mockReturnValue();
|
||||
});
|
||||
|
||||
it('resolves loadStripe with Stripe object', async () => {
|
||||
const {loadStripe} = require(requirePath);
|
||||
const stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve));
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
dispatchScriptEvent('load');
|
||||
|
||||
return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'});
|
||||
});
|
||||
|
||||
it('rejects when the script fails', async () => {
|
||||
const {loadStripe} = require(requirePath);
|
||||
const stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('error');
|
||||
|
||||
await expect(stripePromise).rejects.toEqual(
|
||||
new Error('Failed to load Stripe.js')
|
||||
);
|
||||
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects when Stripe is not added to the window for some reason', async () => {
|
||||
const {loadStripe} = require(requirePath);
|
||||
const stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('load');
|
||||
|
||||
return expect(stripePromise).rejects.toEqual(
|
||||
new Error('Stripe.js not available')
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects on first load, and succeeds on second load resolving with Stripe object', async () => {
|
||||
const {loadStripe} = require(requirePath);
|
||||
|
||||
// start of first load, expect load failure
|
||||
let stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('error');
|
||||
|
||||
await expect(stripePromise).rejects.toEqual(
|
||||
new Error('Failed to load Stripe.js')
|
||||
);
|
||||
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
|
||||
// start of second load, expect successful load
|
||||
stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve));
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
dispatchScriptEvent('load');
|
||||
|
||||
return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'});
|
||||
});
|
||||
|
||||
it('rejects on first load and second load but succeeds on third load resolving with Stripe object', async () => {
|
||||
const {loadStripe} = require(requirePath);
|
||||
|
||||
// start of first load, expect load failure
|
||||
let stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('error');
|
||||
|
||||
await expect(stripePromise).rejects.toEqual(
|
||||
new Error('Failed to load Stripe.js')
|
||||
);
|
||||
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
|
||||
// start of second load, expect load failure
|
||||
stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('error');
|
||||
|
||||
await expect(stripePromise).rejects.toEqual(
|
||||
new Error('Failed to load Stripe.js')
|
||||
);
|
||||
|
||||
expect(console.warn).not.toHaveBeenCalled();
|
||||
|
||||
// start of third load, expect success
|
||||
stripePromise = loadStripe('pk_test_foo');
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve));
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
dispatchScriptEvent('load');
|
||||
|
||||
return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadStripe (index.ts)', () => {
|
||||
it('does not cause unhandled rejects when the script fails', async () => {
|
||||
require('./index');
|
||||
|
||||
await Promise.resolve();
|
||||
dispatchScriptEvent('error');
|
||||
|
||||
// Turn the task loop to make sure the internal promise handler has been invoked
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
expect(console.warn).toHaveBeenCalledWith(
|
||||
new Error('Failed to load Stripe.js')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
38
node_modules/@stripe/stripe-js/src/index.ts
generated
vendored
Normal file
38
node_modules/@stripe/stripe-js/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import {StripeConstructor} from '../types';
|
||||
import {loadScript, initStripe, LoadStripe} from './shared';
|
||||
|
||||
let stripePromise: Promise<StripeConstructor | null> | null;
|
||||
let loadCalled = false;
|
||||
|
||||
const getStripePromise: () => Promise<StripeConstructor | null> = () => {
|
||||
if (stripePromise) {
|
||||
return stripePromise;
|
||||
}
|
||||
|
||||
stripePromise = loadScript(null).catch((error) => {
|
||||
// clear cache on error
|
||||
stripePromise = null;
|
||||
return Promise.reject(error);
|
||||
});
|
||||
return stripePromise;
|
||||
};
|
||||
|
||||
// Execute our own script injection after a tick to give users time to do their
|
||||
// own script injection.
|
||||
Promise.resolve()
|
||||
.then(() => getStripePromise())
|
||||
.catch((error) => {
|
||||
if (!loadCalled) {
|
||||
console.warn(error);
|
||||
}
|
||||
});
|
||||
|
||||
export const loadStripe: LoadStripe = (...args) => {
|
||||
loadCalled = true;
|
||||
const startTime = Date.now();
|
||||
|
||||
// if previous attempts are unsuccessful, will re-load script
|
||||
return getStripePromise().then((maybeStripe) =>
|
||||
initStripe(maybeStripe, args, startTime)
|
||||
);
|
||||
};
|
||||
146
node_modules/@stripe/stripe-js/src/pure.test.ts
generated
vendored
Normal file
146
node_modules/@stripe/stripe-js/src/pure.test.ts
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import {RELEASE_TRAIN} from './shared';
|
||||
|
||||
const SCRIPT_SRC = `https://js.stripe.com/${RELEASE_TRAIN}/stripe.js`;
|
||||
const SCRIPT_SELECTOR = `script[src^="${SCRIPT_SRC}"]`;
|
||||
|
||||
describe('pure module', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'warn').mockReturnValue();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
const scripts = Array.from(document.querySelectorAll(SCRIPT_SELECTOR));
|
||||
|
||||
for (const script of scripts) {
|
||||
if (script.parentElement) {
|
||||
script.parentElement.removeChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
delete window.Stripe;
|
||||
|
||||
jest.resetModules();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('does not inject the script if loadStripe is not called', async () => {
|
||||
require('./pure');
|
||||
|
||||
expect(document.querySelector(SCRIPT_SELECTOR)).toBe(null);
|
||||
});
|
||||
|
||||
test('it injects the script if loadStripe is called', async () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe('pk_test_foo');
|
||||
|
||||
expect(document.querySelector(SCRIPT_SELECTOR)).not.toBe(null);
|
||||
});
|
||||
|
||||
test('it can load the script with advanced fraud signals disabled', () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: false});
|
||||
loadStripe('pk_test_foo');
|
||||
|
||||
expect(
|
||||
document.querySelector(
|
||||
`script[src^="${SCRIPT_SRC}?advancedFraudSignals=false"]`
|
||||
)
|
||||
).not.toBe(null);
|
||||
});
|
||||
|
||||
test('it should throw when setting invalid load parameters', () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
|
||||
expect(() => {
|
||||
loadStripe.setLoadParameters({howdy: true});
|
||||
}).toThrow('invalid load parameters');
|
||||
});
|
||||
|
||||
test('it should warn when calling loadStripe if a script already exists when parameters are set', () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = SCRIPT_SRC;
|
||||
document.body.appendChild(script);
|
||||
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: true});
|
||||
loadStripe('pk_test_123');
|
||||
|
||||
expect(console.warn).toHaveBeenCalledTimes(1);
|
||||
expect(console.warn).toHaveBeenLastCalledWith(
|
||||
'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used'
|
||||
);
|
||||
});
|
||||
|
||||
test('it should warn when calling loadStripe if a script is added after parameters are set', () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: true});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = SCRIPT_SRC;
|
||||
document.body.appendChild(script);
|
||||
|
||||
loadStripe('pk_test_123');
|
||||
|
||||
expect(console.warn).toHaveBeenCalledTimes(1);
|
||||
expect(console.warn).toHaveBeenLastCalledWith(
|
||||
'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used'
|
||||
);
|
||||
});
|
||||
|
||||
test('it should warn when window.Stripe already exists if parameters are set', () => {
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: true});
|
||||
loadStripe('pk_test_123');
|
||||
|
||||
expect(console.warn).toHaveBeenCalledTimes(1);
|
||||
expect(console.warn).toHaveBeenLastCalledWith(
|
||||
'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used'
|
||||
);
|
||||
});
|
||||
|
||||
test('it should not warn when a script already exists if parameters are not set', () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = SCRIPT_SRC;
|
||||
document.body.appendChild(script);
|
||||
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe('pk_test_123');
|
||||
|
||||
expect(console.warn).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('it should not warn when window.Stripe already exists if parameters are not set', () => {
|
||||
window.Stripe = jest.fn((key) => ({key})) as any;
|
||||
|
||||
const {loadStripe} = require('./pure');
|
||||
loadStripe('pk_test_123');
|
||||
|
||||
expect(console.warn).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('throws an error if calling setLoadParameters after loadStripe', () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: false});
|
||||
loadStripe('pk_foo');
|
||||
|
||||
expect(() => {
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: true});
|
||||
}).toThrow('cannot change load parameters');
|
||||
});
|
||||
|
||||
test('does not throw an error if calling setLoadParameters after loadStripe but the parameters are the same', () => {
|
||||
const {loadStripe} = require('./pure');
|
||||
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: false});
|
||||
loadStripe('pk_foo');
|
||||
|
||||
expect(() => {
|
||||
loadStripe.setLoadParameters({advancedFraudSignals: false});
|
||||
}).not.toThrow('cannot change load parameters');
|
||||
});
|
||||
});
|
||||
54
node_modules/@stripe/stripe-js/src/pure.ts
generated
vendored
Normal file
54
node_modules/@stripe/stripe-js/src/pure.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
validateLoadParams,
|
||||
loadScript,
|
||||
initStripe,
|
||||
LoadStripe,
|
||||
LoadParams,
|
||||
} from './shared';
|
||||
|
||||
type SetLoadParams = (params: LoadParams) => void;
|
||||
|
||||
let loadParams: null | LoadParams;
|
||||
let loadStripeCalled = false;
|
||||
|
||||
export const loadStripe: LoadStripe & {setLoadParameters: SetLoadParams} = (
|
||||
...args
|
||||
) => {
|
||||
loadStripeCalled = true;
|
||||
const startTime = Date.now();
|
||||
|
||||
return loadScript(loadParams).then((maybeStripe) =>
|
||||
initStripe(maybeStripe, args, startTime)
|
||||
);
|
||||
};
|
||||
|
||||
loadStripe.setLoadParameters = (params): void => {
|
||||
// we won't throw an error if setLoadParameters is called with the same values as before
|
||||
if (loadStripeCalled && loadParams) {
|
||||
const validatedParams = validateLoadParams(params);
|
||||
const parameterKeys = Object.keys(validatedParams) as Array<
|
||||
keyof LoadParams
|
||||
>;
|
||||
|
||||
const sameParameters = parameterKeys.reduce(
|
||||
(previousValue, currentValue) => {
|
||||
return (
|
||||
previousValue && params[currentValue] === loadParams?.[currentValue]
|
||||
);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
if (sameParameters) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadStripeCalled) {
|
||||
throw new Error(
|
||||
'You cannot change load parameters after calling loadStripe'
|
||||
);
|
||||
}
|
||||
|
||||
loadParams = validateLoadParams(params);
|
||||
};
|
||||
74
node_modules/@stripe/stripe-js/src/shared.test.ts
generated
vendored
Normal file
74
node_modules/@stripe/stripe-js/src/shared.test.ts
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import {validateLoadParams, findScript} from './shared';
|
||||
|
||||
describe('validateLoadParams', () => {
|
||||
const INVALID_INPUTS: any[] = [
|
||||
[undefined],
|
||||
[false],
|
||||
[null],
|
||||
[true],
|
||||
[{}],
|
||||
[8],
|
||||
[{advancedFraud: true}],
|
||||
[{advancedFraudSignals: true, someOtherKey: true}],
|
||||
[{advancedFraudSignals: 'true'}],
|
||||
];
|
||||
|
||||
test.each(INVALID_INPUTS)('throws on invalid input: %p', (input) => {
|
||||
expect(() => validateLoadParams(input)).toThrow('invalid load parameters');
|
||||
});
|
||||
|
||||
test('validates valid input', () => {
|
||||
expect(validateLoadParams({advancedFraudSignals: true})).toEqual({
|
||||
advancedFraudSignals: true,
|
||||
});
|
||||
|
||||
expect(validateLoadParams({advancedFraudSignals: false})).toEqual({
|
||||
advancedFraudSignals: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('findScript', () => {
|
||||
const CASES: Array<[string, boolean]> = [
|
||||
['https://js.stripe.com/v3?advancedFraudSignals=true', true],
|
||||
['https://js.stripe.com/v3', true],
|
||||
['https://js.stripe.com/v3/', true],
|
||||
['https://js.stripe.com/v3/stripe.js', true],
|
||||
['https://js.stripe.com/v2/stripe.js', false],
|
||||
['https://js.stripe.com/versionname/stripe.js', true],
|
||||
['https://js.stripe.com/versionname/stripe.js', true],
|
||||
['https://js.stripe.com/versionname/', false],
|
||||
['https://js.stripe.com/versionname', false],
|
||||
['https://js.stripe.com/v2/', false],
|
||||
['https://js.stripe.com/v2', false],
|
||||
['https://js.stripe.com/v3?advancedFraudSignals=false', true],
|
||||
['https://js.stripe.com/v3?ab=cd', true],
|
||||
['https://js.stripe.com/v3/something.js', false],
|
||||
['https://js.stripe.com/v3/something.js?advancedFraudSignals=false', false],
|
||||
['https://js.stripe.com/v3/something.js?ab=cd', false],
|
||||
['https://js.stripe.com/versionname/stripe.js?ab=cd', true],
|
||||
];
|
||||
|
||||
afterEach(() => {
|
||||
for (const [url] of CASES) {
|
||||
const script = document.querySelector(`script[src="${url}"]`);
|
||||
|
||||
if (script && script.parentElement) {
|
||||
script.parentElement.removeChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
delete window.Stripe;
|
||||
});
|
||||
|
||||
test.each(CASES)(
|
||||
'findScript with <script src="%s"></script>',
|
||||
(url, shouldBeFound) => {
|
||||
const script = document.createElement('script');
|
||||
script.src = url;
|
||||
document.body.appendChild(script);
|
||||
|
||||
expect(!!findScript()).toBe(shouldBeFound);
|
||||
}
|
||||
);
|
||||
});
|
||||
218
node_modules/@stripe/stripe-js/src/shared.ts
generated
vendored
Normal file
218
node_modules/@stripe/stripe-js/src/shared.ts
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
import {Stripe, StripeConstructor, ReleaseTrain} from '../types';
|
||||
|
||||
export type LoadStripe = (
|
||||
...args: Parameters<StripeConstructor>
|
||||
) => Promise<Stripe | null>;
|
||||
|
||||
export interface LoadParams {
|
||||
advancedFraudSignals: boolean;
|
||||
}
|
||||
|
||||
// `_VERSION` will be rewritten by `@rollup/plugin-replace` as a string literal
|
||||
// containing the package.json version
|
||||
declare const _VERSION: string;
|
||||
|
||||
export const RELEASE_TRAIN: ReleaseTrain = 'dahlia';
|
||||
|
||||
const runtimeVersionToUrlVersion = (version: string | number) =>
|
||||
version === 3 ? 'v3' : version;
|
||||
|
||||
const ORIGIN = 'https://js.stripe.com';
|
||||
const STRIPE_JS_URL = `${ORIGIN}/${RELEASE_TRAIN}/stripe.js`;
|
||||
|
||||
const V3_URL_REGEX = /^https:\/\/js\.stripe\.com\/v3\/?(\?.*)?$/;
|
||||
const STRIPE_JS_URL_REGEX = /^https:\/\/js\.stripe\.com\/(v3|[a-z]+)\/stripe\.js(\?.*)?$/;
|
||||
const EXISTING_SCRIPT_MESSAGE =
|
||||
'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used';
|
||||
|
||||
const isStripeJSURL = (url: string): boolean =>
|
||||
V3_URL_REGEX.test(url) || STRIPE_JS_URL_REGEX.test(url);
|
||||
|
||||
export const findScript = (): HTMLScriptElement | null => {
|
||||
const scripts = document.querySelectorAll<HTMLScriptElement>(
|
||||
`script[src^="${ORIGIN}"]`
|
||||
);
|
||||
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
const script = scripts[i];
|
||||
|
||||
if (!isStripeJSURL(script.src)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const injectScript = (params: null | LoadParams): HTMLScriptElement => {
|
||||
const queryString =
|
||||
params && !params.advancedFraudSignals ? '?advancedFraudSignals=false' : '';
|
||||
const script = document.createElement('script');
|
||||
script.src = `${STRIPE_JS_URL}${queryString}`;
|
||||
|
||||
const headOrBody = document.head || document.body;
|
||||
|
||||
if (!headOrBody) {
|
||||
throw new Error(
|
||||
'Expected document.body not to be null. Stripe.js requires a <body> element.'
|
||||
);
|
||||
}
|
||||
|
||||
headOrBody.appendChild(script);
|
||||
|
||||
return script;
|
||||
};
|
||||
|
||||
const registerWrapper = (stripe: any, startTime: number): void => {
|
||||
if (!stripe || !stripe._registerWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
stripe._registerWrapper({name: 'stripe-js', version: _VERSION, startTime});
|
||||
};
|
||||
|
||||
let stripePromise: Promise<StripeConstructor | null> | null = null;
|
||||
|
||||
let onErrorListener: ((cause?: unknown) => void) | null = null;
|
||||
let onLoadListener: (() => void) | null = null;
|
||||
|
||||
const onError = (reject: (reason?: any) => void) => (cause?: unknown) => {
|
||||
reject(new Error('Failed to load Stripe.js', {cause}));
|
||||
};
|
||||
|
||||
const onLoad = (
|
||||
resolve: (
|
||||
value: StripeConstructor | PromiseLike<StripeConstructor | null> | null
|
||||
) => void,
|
||||
reject: (reason?: any) => void
|
||||
) => () => {
|
||||
if (window.Stripe) {
|
||||
resolve(window.Stripe);
|
||||
} else {
|
||||
reject(new Error('Stripe.js not available'));
|
||||
}
|
||||
};
|
||||
|
||||
export const loadScript = (
|
||||
params: null | LoadParams
|
||||
): Promise<StripeConstructor | null> => {
|
||||
// Ensure that we only attempt to load Stripe.js at most once
|
||||
if (stripePromise !== null) {
|
||||
return stripePromise;
|
||||
}
|
||||
|
||||
stripePromise = new Promise((resolve, reject) => {
|
||||
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
||||
// Resolve to null when imported server side. This makes the module
|
||||
// safe to import in an isomorphic code base.
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.Stripe && params) {
|
||||
console.warn(EXISTING_SCRIPT_MESSAGE);
|
||||
}
|
||||
|
||||
if (window.Stripe) {
|
||||
resolve(window.Stripe);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let script = findScript();
|
||||
|
||||
if (script && params) {
|
||||
console.warn(EXISTING_SCRIPT_MESSAGE);
|
||||
} else if (!script) {
|
||||
script = injectScript(params);
|
||||
} else if (
|
||||
script &&
|
||||
onLoadListener !== null &&
|
||||
onErrorListener !== null
|
||||
) {
|
||||
// remove event listeners
|
||||
script.removeEventListener('load', onLoadListener);
|
||||
script.removeEventListener('error', onErrorListener);
|
||||
|
||||
// if script exists, but we are reloading due to an error,
|
||||
// reload script to trigger 'load' event
|
||||
script.parentNode?.removeChild(script);
|
||||
script = injectScript(params);
|
||||
}
|
||||
|
||||
onLoadListener = onLoad(resolve, reject);
|
||||
onErrorListener = onError(reject);
|
||||
script.addEventListener('load', onLoadListener);
|
||||
|
||||
script.addEventListener('error', onErrorListener);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
});
|
||||
// Resets stripePromise on error
|
||||
return stripePromise.catch((error) => {
|
||||
stripePromise = null;
|
||||
return Promise.reject(error);
|
||||
});
|
||||
};
|
||||
|
||||
export const initStripe = (
|
||||
maybeStripe: StripeConstructor | null,
|
||||
args: Parameters<StripeConstructor>,
|
||||
startTime: number
|
||||
): Stripe | null => {
|
||||
if (maybeStripe === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pk = args[0];
|
||||
|
||||
if (typeof pk !== 'string') {
|
||||
throw new Error(
|
||||
`Expected publishable key to be of type string, got type ${typeof pk} instead.`
|
||||
);
|
||||
}
|
||||
|
||||
const isTestKey = pk.match(/^pk_test/);
|
||||
|
||||
// @ts-expect-error this is not publicly typed
|
||||
const version = runtimeVersionToUrlVersion(maybeStripe.version);
|
||||
const expectedVersion = RELEASE_TRAIN;
|
||||
if (isTestKey && version !== expectedVersion) {
|
||||
console.warn(
|
||||
`Stripe.js@${version} was loaded on the page, but @stripe/stripe-js@${_VERSION} expected Stripe.js@${expectedVersion}. This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning`
|
||||
);
|
||||
}
|
||||
|
||||
const stripe = maybeStripe.apply(undefined, args);
|
||||
registerWrapper(stripe, startTime);
|
||||
return stripe;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const validateLoadParams = (params: any): LoadParams => {
|
||||
const errorMessage = `invalid load parameters; expected object of shape
|
||||
|
||||
{advancedFraudSignals: boolean}
|
||||
|
||||
but received
|
||||
|
||||
${JSON.stringify(params)}
|
||||
`;
|
||||
|
||||
if (params === null || typeof params !== 'object') {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
if (
|
||||
Object.keys(params).length === 1 &&
|
||||
typeof params.advancedFraudSignals === 'boolean'
|
||||
) {
|
||||
return params;
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
};
|
||||
3
node_modules/@stripe/stripe-js/src/testUtils.ts
generated
vendored
Normal file
3
node_modules/@stripe/stripe-js/src/testUtils.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import {RELEASE_TRAIN} from './shared';
|
||||
|
||||
export const SCRIPT_SRC = `https://js.stripe.com/${RELEASE_TRAIN}/stripe.js`;
|
||||
Reference in New Issue
Block a user