@tap-payments/apple-pay-button 0.0.0-test

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Tap Payments
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # apple-pay-button
2
+
3
+ Handling Apple Pay button in React and vanilla JS
4
+
5
+ ## Install
6
+
7
+ This is a [React](https://reactjs.org/) module available through the
8
+ [npm registry](https://www.npmjs.com/). Installation is done using the
9
+ [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
10
+
11
+ ```console
12
+ npm install @tap-payments/apple-pay-button
13
+ ```
14
+
15
+ ---------------------------- OR -------------------------
16
+
17
+ ```console
18
+ yarn add @tap-payments/apple-pay-button
19
+ ```
20
+
21
+ ## Examples
22
+
23
+ ### ES6
24
+
25
+ ```js
26
+ import React from 'react'
27
+ import { ApplePayButton, ButtonStyle, SupportedNetworks, Scope } from '@tap-payments/apple-pay-button'
28
+
29
+ const App = () => {
30
+ return (
31
+ <ApplePayButton
32
+ // required (The public Key provided by Tap)
33
+ publicKey={'pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxzh'}
34
+ // required
35
+ merchant={{
36
+ // required (The merchant domain name)
37
+ domain: 'example.com',
38
+ // optional (The merchant identifier provided by Tap)
39
+ id: '1xxxxx8'
40
+ }}
41
+ // required
42
+ transaction={{
43
+ // required (The amount to be charged)
44
+ amount: '12',
45
+ // required (The currency of the amount)
46
+ currency: 'KWD',
47
+ // required (The description/label of the transaction)
48
+ label: 'to Merchant'
49
+ }}
50
+ // optional (The scope of the SDK and it can be one of these scopes:
51
+ // [TapToken,AppleToken], by default it is TapToken)
52
+ scope={Scope.TapToken}
53
+ // optional (The supported networks for the Apple Pay button and it
54
+ // can be one of these networks: [Mada,Visa,MasterCard], by default
55
+ // we bring all the supported networks from tap merchant configuration)
56
+ supportedNetworks={[SupportedNetworks.Mada, SupportedNetworks.Visa, SupportedNetworks.MasterCard]}
57
+ // optional (The style of the Apple Pay button and it can be one of
58
+ // these styles: [White,WhiteOutline,Black], by default it is WhiteOutline)
59
+ buttonStyle={ButtonStyle.WhiteOutline}
60
+ // optional (The billing contact information)
61
+ billingContact={{
62
+ // required
63
+ email: {
64
+ // required
65
+ address: 'test@gmail.com'
66
+ },
67
+ // required
68
+ name: {
69
+ // required
70
+ first: 'test',
71
+ // required
72
+ last: 'tester',
73
+ // optional
74
+ middle: 'test'
75
+ },
76
+ // required
77
+ phone: {
78
+ number: '10XXXXXX56',
79
+ code: '+20'
80
+ }
81
+ }}
82
+ // optional (A callback function that will be called when you cancel
83
+ // the payment process)
84
+ onCancel={() => console.log('cancelled')}
85
+ // optional (A callback function that will be called when you have an error)
86
+ onError={(err) => console.error(err)}
87
+ // optional (A async function that will be called after creating the token
88
+ // successfully)
89
+ onSuccess={async (token) => {
90
+ // do your stuff here...
91
+ console.log(token)
92
+ }}
93
+ />
94
+ )
95
+ }
96
+ ```
97
+
98
+ ### Vanilla JS
99
+
100
+ ```js
101
+ // coming soon...
102
+ ```
103
+
104
+ ## Configurations
105
+
106
+ | Name | Type | R/O | Description |
107
+ | -------------------- | --------------------- | ---------- | -------------------------------------------------------------------------- |
108
+ | publicKey | `string` | `required` | The public Key provided by Tap |
109
+ | merchant.id | `string` | `optional` | The merchant identifier provided by Tap |
110
+ | merchant.domain | `string` | `required` | The merchant domain name |
111
+ | transaction.amount | `string` | `required` | The amount to be charged |
112
+ | transaction.currency | `string` | `required` | The currency of the amount |
113
+ | transaction.label | `string` | `required` | The description/label of the transaction |
114
+ | scope | `Scope` | `optional` | The scope of the SDK |
115
+ | supportedNetworks | `SupportedNetworks[]` | `optional` | The supported networks for the Apple Pay button |
116
+ | buttonStyle | `ButtonStyle` | `optional` | The style of the Apple Pay button |
117
+ | billingContact | `BillingContact` | `optional` | The billing contact information |
118
+ | onCancel | `function` | `optional` | A callback function that will be called when you cancel the process |
119
+ | onError | `function` | `optional` | A callback function that will be called when you have an error |
120
+ | onSuccess | `function` | `optional` | A async function that will be called after creating the token successfully |
@@ -0,0 +1,74 @@
1
+ import { Scope, ButtonStyle, MerchantCapabilities, SupportedNetworks } from '../constants';
2
+ export interface ApplePayRequestData {
3
+ countryCode: string;
4
+ currencyCode: string;
5
+ merchantCapabilities: Array<typeof MerchantCapabilities[keyof typeof MerchantCapabilities]>;
6
+ supportedNetworks: Array<typeof SupportedNetworks[keyof typeof SupportedNetworks]>;
7
+ billingContact?: {
8
+ phoneNumber: string;
9
+ emailAddress: string;
10
+ givenName: string;
11
+ familyName: string;
12
+ };
13
+ total: {
14
+ label: string;
15
+ amount: number;
16
+ };
17
+ }
18
+ export interface ApplePayButtonProps {
19
+ publicKey: string;
20
+ merchant: {
21
+ id?: string;
22
+ domain: string;
23
+ };
24
+ scope?: typeof Scope[keyof typeof Scope];
25
+ supportedNetworks?: Array<typeof SupportedNetworks[keyof typeof SupportedNetworks]>;
26
+ buttonStyle?: typeof ButtonStyle[keyof typeof ButtonStyle];
27
+ billingContact?: {
28
+ name: {
29
+ first: string;
30
+ middle?: string;
31
+ last: string;
32
+ };
33
+ email: {
34
+ address: string;
35
+ };
36
+ phone: {
37
+ code: string;
38
+ number: string;
39
+ };
40
+ };
41
+ transaction: {
42
+ amount: string;
43
+ currency: string;
44
+ label: string;
45
+ };
46
+ onCancel?: () => void;
47
+ onError?: (error: any) => void;
48
+ onSuccess?: (data: Record<string, any>) => Promise<void>;
49
+ }
50
+ export interface MerchantResponse {
51
+ id: string;
52
+ name: string;
53
+ country_code: string;
54
+ session_token: string;
55
+ [other: string]: string;
56
+ }
57
+ export interface PaymentMethod {
58
+ id: string;
59
+ image: string;
60
+ name: string;
61
+ payment_type: string;
62
+ supported_card_brands: Array<typeof SupportedNetworks[keyof typeof SupportedNetworks]>;
63
+ supported_currencies: string[];
64
+ }
65
+ export interface PaymentOptionsResponse {
66
+ id: string;
67
+ country: string;
68
+ currency: string;
69
+ payment_methods: PaymentMethod[];
70
+ }
71
+ export interface ProfileResponse {
72
+ merchant: MerchantResponse;
73
+ payment_options: PaymentOptionsResponse;
74
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { MerchantResponse, ApplePayRequestData, ProfileResponse } from '../@types';
2
+ import BaseService from './base';
3
+ declare class APPService extends BaseService {
4
+ constructor();
5
+ init(publicKey: string, merchantId?: string): Promise<ProfileResponse>;
6
+ appleSession(merchant: MerchantResponse, validationURL: string, merchantRegisteredDomain: string): Promise<any>;
7
+ tapTokenization(applePaymentData: Record<string, string>, merchant: MerchantResponse): Promise<any>;
8
+ createCharge(publicKey: string, merchant: MerchantResponse, request: ApplePayRequestData, cardToken: string): Promise<import("axios").AxiosResponse<any, any>>;
9
+ }
10
+ declare const appService: APPService;
11
+ export default appService;
@@ -0,0 +1,217 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = function (d, b) {
3
+ extendStatics = Object.setPrototypeOf ||
4
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
+ return extendStatics(d, b);
7
+ };
8
+ return function (d, b) {
9
+ if (typeof b !== "function" && b !== null)
10
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
+ extendStatics(d, b);
12
+ function __() { this.constructor = d; }
13
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
+ };
15
+ })();
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (_) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
52
+ import BaseService from './base';
53
+ import httpClient from './httpClient';
54
+ var APPService = (function (_super) {
55
+ __extends(APPService, _super);
56
+ function APPService() {
57
+ return _super.call(this, httpClient) || this;
58
+ }
59
+ Object.defineProperty(APPService.prototype, "init", {
60
+ enumerable: false,
61
+ configurable: true,
62
+ writable: true,
63
+ value: function (publicKey, merchantId) {
64
+ return __awaiter(this, void 0, void 0, function () {
65
+ var body, data;
66
+ return __generator(this, function (_a) {
67
+ switch (_a.label) {
68
+ case 0:
69
+ body = {
70
+ headers: { authorization: "Bearer ".concat(publicKey) },
71
+ reqBody: { public_key: publicKey, merchant_id: merchantId }
72
+ };
73
+ return [4, this.post('/init', body)];
74
+ case 1:
75
+ data = (_a.sent()).data;
76
+ if (data.errors)
77
+ throw data;
78
+ return [2, {
79
+ merchant: data.merchant,
80
+ payment_options: data.payment_options
81
+ }];
82
+ }
83
+ });
84
+ });
85
+ }
86
+ });
87
+ Object.defineProperty(APPService.prototype, "appleSession", {
88
+ enumerable: false,
89
+ configurable: true,
90
+ writable: true,
91
+ value: function (merchant, validationURL, merchantRegisteredDomain) {
92
+ return __awaiter(this, void 0, void 0, function () {
93
+ var body, data;
94
+ return __generator(this, function (_a) {
95
+ switch (_a.label) {
96
+ case 0:
97
+ body = {
98
+ validationUrl: validationURL,
99
+ origin: merchantRegisteredDomain,
100
+ merchantIdentifier: 'merchant.tap.gosell',
101
+ merchantId: merchant.id,
102
+ merchantName: merchant.name,
103
+ session_token: merchant.session_token
104
+ };
105
+ return [4, this.post('/session', body)];
106
+ case 1:
107
+ data = (_a.sent()).data;
108
+ if (data.errors)
109
+ throw data;
110
+ return [2, data];
111
+ }
112
+ });
113
+ });
114
+ }
115
+ });
116
+ Object.defineProperty(APPService.prototype, "tapTokenization", {
117
+ enumerable: false,
118
+ configurable: true,
119
+ writable: true,
120
+ value: function (applePaymentData, merchant) {
121
+ return __awaiter(this, void 0, void 0, function () {
122
+ var body, data;
123
+ return __generator(this, function (_a) {
124
+ switch (_a.label) {
125
+ case 0:
126
+ body = {
127
+ method: 'POST',
128
+ path: '/v2/token',
129
+ headers: {
130
+ session_token: merchant.session_token
131
+ },
132
+ reqBody: {
133
+ type: 'applepay',
134
+ token_data: applePaymentData
135
+ }
136
+ };
137
+ return [4, this.post('/api', body)];
138
+ case 1:
139
+ data = (_a.sent()).data;
140
+ if (data.errors)
141
+ throw data;
142
+ return [2, data];
143
+ }
144
+ });
145
+ });
146
+ }
147
+ });
148
+ Object.defineProperty(APPService.prototype, "createCharge", {
149
+ enumerable: false,
150
+ configurable: true,
151
+ writable: true,
152
+ value: function (publicKey, merchant, request, cardToken) {
153
+ var body = {
154
+ method: 'POST',
155
+ path: '/v2/charge',
156
+ headers: {
157
+ session_token: merchant.session_token
158
+ },
159
+ reqBody: {
160
+ id: null,
161
+ amount: request.total.amount,
162
+ currency: request.currencyCode,
163
+ public_key: publicKey,
164
+ product: 'GOSELL',
165
+ threeDSecure: true,
166
+ save_card: false,
167
+ fee: 0,
168
+ statement_descriptor: 'Sample',
169
+ description: 'Test Description',
170
+ metadata: {},
171
+ reference: {
172
+ transaction: 'txn_0001',
173
+ order: 'ord_0001'
174
+ },
175
+ receipt: {
176
+ email: false,
177
+ sms: true
178
+ },
179
+ customer: {
180
+ id: null,
181
+ first_name: 'Hala',
182
+ middle_name: null,
183
+ last_name: 'Q.',
184
+ email: 'email@email.com',
185
+ phone: {
186
+ country_code: '965',
187
+ number: '00000000'
188
+ }
189
+ },
190
+ source: {
191
+ id: cardToken
192
+ },
193
+ hashstring: null,
194
+ post: {
195
+ url: null
196
+ },
197
+ redirect: {
198
+ url: 'https://jslib.gosell.io/demo?token=63cce645332aa501e6cf768f&mode=popup'
199
+ },
200
+ ipaddress: null,
201
+ selected_currency: request.currencyCode,
202
+ selected_amount: request.total.amount,
203
+ merchant: {
204
+ id: merchant.id
205
+ },
206
+ order: {
207
+ id: 'ord_06CO2023731xt7V22SC0X487'
208
+ }
209
+ }
210
+ };
211
+ return this.post('/api', body);
212
+ }
213
+ });
214
+ return APPService;
215
+ }(BaseService));
216
+ var appService = new APPService();
217
+ export default appService;
@@ -0,0 +1,9 @@
1
+ import { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ export default class BaseService {
3
+ httpClient: AxiosInstance;
4
+ constructor(httpClient: AxiosInstance);
5
+ get(url: string, config?: AxiosRequestConfig<any>): Promise<import("axios").AxiosResponse<any, any>>;
6
+ post(url: string, data?: any, config?: AxiosRequestConfig<any>): Promise<import("axios").AxiosResponse<any, any>>;
7
+ put(url: string, data?: any, config?: AxiosRequestConfig<any>): Promise<import("axios").AxiosResponse<any, any>>;
8
+ delete(url: string, config?: AxiosRequestConfig<any>): Promise<import("axios").AxiosResponse<any, any>>;
9
+ }
@@ -0,0 +1,45 @@
1
+ var BaseService = (function () {
2
+ function BaseService(httpClient) {
3
+ Object.defineProperty(this, "httpClient", {
4
+ enumerable: true,
5
+ configurable: true,
6
+ writable: true,
7
+ value: void 0
8
+ });
9
+ this.httpClient = httpClient;
10
+ }
11
+ Object.defineProperty(BaseService.prototype, "get", {
12
+ enumerable: false,
13
+ configurable: true,
14
+ writable: true,
15
+ value: function (url, config) {
16
+ return this.httpClient.get(url, config);
17
+ }
18
+ });
19
+ Object.defineProperty(BaseService.prototype, "post", {
20
+ enumerable: false,
21
+ configurable: true,
22
+ writable: true,
23
+ value: function (url, data, config) {
24
+ return this.httpClient.post(url, data, config);
25
+ }
26
+ });
27
+ Object.defineProperty(BaseService.prototype, "put", {
28
+ enumerable: false,
29
+ configurable: true,
30
+ writable: true,
31
+ value: function (url, data, config) {
32
+ return this.httpClient.put(url, data, config);
33
+ }
34
+ });
35
+ Object.defineProperty(BaseService.prototype, "delete", {
36
+ enumerable: false,
37
+ configurable: true,
38
+ writable: true,
39
+ value: function (url, config) {
40
+ return this.httpClient.delete(url, config);
41
+ }
42
+ });
43
+ return BaseService;
44
+ }());
45
+ export default BaseService;
@@ -0,0 +1,2 @@
1
+ declare const httpClient: import("axios").AxiosInstance;
2
+ export default httpClient;
@@ -0,0 +1,16 @@
1
+ import axios from 'axios';
2
+ var MW_BASE_URL = 'https://checkout.payments.tap.company/api';
3
+ var httpClient = axios.create({
4
+ baseURL: MW_BASE_URL,
5
+ headers: {
6
+ 'Content-Type': 'application/json',
7
+ Accept: 'application/json'
8
+ }
9
+ });
10
+ httpClient.interceptors.request.use(function (config) {
11
+ return config;
12
+ });
13
+ httpClient.interceptors.response.use(function (response) {
14
+ return response;
15
+ });
16
+ export default httpClient;
@@ -0,0 +1,21 @@
1
+ export declare const Scope: {
2
+ readonly AppleToken: "AppleToken";
3
+ readonly TapToken: "TapToken";
4
+ };
5
+ export declare const ButtonStyle: {
6
+ readonly Black: "black";
7
+ readonly White: "white";
8
+ readonly WhiteOutline: "whiteOutline";
9
+ };
10
+ export declare const MerchantCapabilities: {
11
+ readonly Supports3DS: "supports3DS";
12
+ readonly SupportsCredit: "supportsCredit";
13
+ readonly SupportsDebit: "supportsDebit";
14
+ };
15
+ export declare const SupportedNetworks: {
16
+ readonly Amex: "amex";
17
+ readonly Mada: "mada";
18
+ readonly MasterCard: "masterCard";
19
+ readonly Visa: "visa";
20
+ };
21
+ export declare const ApplePayVersion = 5;
@@ -0,0 +1,21 @@
1
+ export var Scope = {
2
+ AppleToken: 'AppleToken',
3
+ TapToken: 'TapToken'
4
+ };
5
+ export var ButtonStyle = {
6
+ Black: 'black',
7
+ White: 'white',
8
+ WhiteOutline: 'whiteOutline'
9
+ };
10
+ export var MerchantCapabilities = {
11
+ Supports3DS: 'supports3DS',
12
+ SupportsCredit: 'supportsCredit',
13
+ SupportsDebit: 'supportsDebit'
14
+ };
15
+ export var SupportedNetworks = {
16
+ Amex: 'amex',
17
+ Mada: 'mada',
18
+ MasterCard: 'masterCard',
19
+ Visa: 'visa'
20
+ };
21
+ export var ApplePayVersion = 5;
@@ -0,0 +1,51 @@
1
+ .button-applepay-tap {
2
+ appearance: none;
3
+ border: none;
4
+ cursor: pointer;
5
+ -webkit-user-select: none;
6
+ user-select: none;
7
+ display: flex;
8
+ position: relative;
9
+ -webkit-box-pack: center;
10
+ -ms-flex-pack: center;
11
+ -webkit-justify-content: center;
12
+ justify-content: center;
13
+ -webkit-align-items: center;
14
+ -webkit-box-align: center;
15
+ -ms-flex-align: center;
16
+ align-items: center;
17
+ -webkit-margin-end: 8px;
18
+ margin-inline-end: 8px;
19
+ min-width: 96px;
20
+ max-width: 300px;
21
+ min-height: 40px;
22
+ border-radius: 9px;
23
+ background-color: white;
24
+ width: 100%;
25
+ }
26
+
27
+ .button-applepay-tap:disabled {
28
+ cursor: default;
29
+ }
30
+
31
+ .img-container {
32
+ height: 24px;
33
+ max-width: 80px;
34
+ }
35
+
36
+ .img-container img {
37
+ height: 100%;
38
+ width: 100%;
39
+ transform: scale(1.5);
40
+ filter: invert(0);
41
+ }
42
+
43
+ .whiteOutline {
44
+ border: solid 1px gray;
45
+ }
46
+ .dark {
47
+ background-color: black;
48
+ }
49
+ .dark .img-container img {
50
+ filter: invert(1);
51
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { ApplePayButtonProps } from '../../@types';
3
+ import './ApplePayButton.css';
4
+ export type { ApplePayButtonProps };
5
+ export declare function ApplePayButton(props: ApplePayButtonProps): JSX.Element;
6
+ export declare function renderApplePayButton(config: ApplePayButtonProps, elementId: string): {
7
+ unmount: () => void;
8
+ };
@@ -0,0 +1,43 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import React from 'react';
14
+ import { createRoot } from 'react-dom/client';
15
+ import { createElementAndInject } from '../../utils';
16
+ import { useApplePay } from '../../hooks/useApplePay';
17
+ import { ButtonStyle, Scope } from '../../constants';
18
+ import './ApplePayButton.css';
19
+ var ApplePay = React.memo(function (_a) {
20
+ var publicKey = _a.publicKey, merchant = _a.merchant, transaction = _a.transaction, billingContact = _a.billingContact, supportedNetworks = _a.supportedNetworks, onCancel = _a.onCancel, onError = _a.onError, onSuccess = _a.onSuccess, _b = _a.scope, scope = _b === void 0 ? Scope.TapToken : _b, _c = _a.buttonStyle, buttonStyle = _c === void 0 ? ButtonStyle.WhiteOutline : _c;
21
+ var _d = useApplePay({
22
+ publicKey: publicKey,
23
+ merchant: merchant,
24
+ transaction: transaction,
25
+ billingContact: billingContact,
26
+ supportedNetworks: supportedNetworks,
27
+ onCancel: onCancel,
28
+ onError: onError,
29
+ onSuccess: onSuccess,
30
+ scope: scope
31
+ }), loading = _d.loading, onApplePayButtonClicked = _d.onApplePayButtonClicked, disabled = _d.disabled;
32
+ return (_jsx("button", __assign({ className: "button-applepay-tap ".concat(buttonStyle), onClick: onApplePayButtonClicked, disabled: loading || disabled }, { children: _jsx("div", __assign({ className: 'img-container' }, { children: _jsx("img", { loading: 'eager', src: 'https://back-end.b-cdn.net/payment_methods/apple_pay.svg' }) })) })));
33
+ });
34
+ export function ApplePayButton(props) {
35
+ return _jsx(ApplePay, __assign({}, props));
36
+ }
37
+ export function renderApplePayButton(config, elementId) {
38
+ var el = createElementAndInject(elementId);
39
+ var root = createRoot(el);
40
+ root.render(_jsx(ApplePay, __assign({}, config)));
41
+ var unmount = function () { return root.unmount(); };
42
+ return { unmount: unmount };
43
+ }
@@ -0,0 +1,3 @@
1
+ import { ApplePayButtonProps, ApplePayButton, renderApplePayButton } from './ApplePayButton';
2
+ export { ApplePayButton, renderApplePayButton };
3
+ export type { ApplePayButtonProps };
@@ -0,0 +1,2 @@
1
+ import { ApplePayButton, renderApplePayButton } from './ApplePayButton';
2
+ export { ApplePayButton, renderApplePayButton };
@@ -0,0 +1 @@
1
+ export * from './useScript';
@@ -0,0 +1 @@
1
+ export * from './useScript';
@@ -0,0 +1,9 @@
1
+ import { ApplePayButtonProps } from '../@types';
2
+ declare type UseApplePayProps = Omit<ApplePayButtonProps, 'buttonStyle'>;
3
+ interface UseApplePayReturnProps {
4
+ loading: boolean;
5
+ onApplePayButtonClicked: () => Promise<void>;
6
+ disabled: boolean;
7
+ }
8
+ export declare const useApplePay: ({ publicKey, merchant, transaction, billingContact, onCancel, onError, onSuccess, scope, supportedNetworks }: UseApplePayProps) => UseApplePayReturnProps;
9
+ export {};
@@ -0,0 +1,202 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (_) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { useCallback, useEffect, useState } from 'react';
49
+ import appService from '../api/app.service';
50
+ import { ApplePayVersion } from '../constants';
51
+ import { getApplePayPaymentMethod, getApplePayRequest, validateCurrency, validateSupportedNetworks } from '../utils/config';
52
+ export var useApplePay = function (_a) {
53
+ var publicKey = _a.publicKey, merchant = _a.merchant, transaction = _a.transaction, billingContact = _a.billingContact, onCancel = _a.onCancel, onError = _a.onError, onSuccess = _a.onSuccess, scope = _a.scope, supportedNetworks = _a.supportedNetworks;
54
+ var _b = useState(false), loading = _b[0], setLoading = _b[1];
55
+ var _c = useState(null), profileData = _c[0], setProfile = _c[1];
56
+ var getMerchantData = useCallback(function () {
57
+ setLoading(true);
58
+ appService
59
+ .init(publicKey, merchant.id)
60
+ .then(function (data) {
61
+ setProfile(data);
62
+ })
63
+ .catch(function (error) {
64
+ onError && onError(error.errors || error);
65
+ })
66
+ .finally(function () {
67
+ setLoading(false);
68
+ });
69
+ }, [merchant, onError, publicKey]);
70
+ useEffect(function () {
71
+ getMerchantData();
72
+ }, [getMerchantData]);
73
+ var onApplePayButtonClicked = function () { return __awaiter(void 0, void 0, void 0, function () {
74
+ var ApplePaySession, paymentMethod, currency, cardBrands, request, session_1;
75
+ var _a;
76
+ return __generator(this, function (_b) {
77
+ ApplePaySession = window.ApplePaySession;
78
+ if (!ApplePaySession) {
79
+ console.error('ApplePaySession is not available, please check if you are using Safari browser');
80
+ return [2];
81
+ }
82
+ if (!profileData) {
83
+ console.error('The profile data is not available, please check networks and try again');
84
+ return [2];
85
+ }
86
+ try {
87
+ paymentMethod = getApplePayPaymentMethod((profileData === null || profileData === void 0 ? void 0 : profileData.payment_options.payment_methods) || []);
88
+ currency = validateCurrency(transaction.currency, paymentMethod.supported_currencies);
89
+ cardBrands = validateSupportedNetworks(paymentMethod.supported_card_brands, supportedNetworks);
90
+ request = getApplePayRequest({
91
+ countryCode: profileData === null || profileData === void 0 ? void 0 : profileData.merchant.country_code,
92
+ transaction: __assign(__assign({}, transaction), { currency: currency }),
93
+ billingContact: billingContact,
94
+ supportedNetworks: cardBrands
95
+ });
96
+ console.info("Creating ApplePaySession with version: ".concat(ApplePayVersion, " and request: ").concat(JSON.stringify(request)));
97
+ session_1 = new ApplePaySession(ApplePayVersion, request);
98
+ session_1.oncancel = function () {
99
+ console.info('oncancel event');
100
+ if (onCancel)
101
+ onCancel();
102
+ };
103
+ session_1.onvalidatemerchant = function (event) { return __awaiter(void 0, void 0, void 0, function () {
104
+ var merchantSession, error_1;
105
+ return __generator(this, function (_a) {
106
+ switch (_a.label) {
107
+ case 0:
108
+ console.info('Creating merchant session and validating merchant session');
109
+ console.info('onvalidatemerchant event', event);
110
+ setLoading(true);
111
+ _a.label = 1;
112
+ case 1:
113
+ _a.trys.push([1, 3, , 4]);
114
+ console.info("creating merchant session for merchantData: ".concat(JSON.stringify(profileData === null || profileData === void 0 ? void 0 : profileData.merchant), " and validationURL: ").concat(event.validationURL, " and merchant.domain: ").concat(merchant.domain));
115
+ return [4, appService.appleSession(profileData === null || profileData === void 0 ? void 0 : profileData.merchant, event.validationURL, merchant.domain)];
116
+ case 2:
117
+ merchantSession = (_a.sent()).body;
118
+ console.info('merchantSession', merchantSession);
119
+ session_1.completeMerchantValidation(merchantSession);
120
+ console.info('merchantSession completed successfully!');
121
+ return [3, 4];
122
+ case 3:
123
+ error_1 = _a.sent();
124
+ console.error('error in onvalidatemerchant', error_1);
125
+ session_1.completePayment({ status: 'STATUS_FAILURE' });
126
+ throw error_1;
127
+ case 4:
128
+ setLoading(false);
129
+ return [2];
130
+ }
131
+ });
132
+ }); };
133
+ session_1.onpaymentauthorized = function (event) { return __awaiter(void 0, void 0, void 0, function () {
134
+ var _a, data, error_2;
135
+ return __generator(this, function (_b) {
136
+ switch (_b.label) {
137
+ case 0:
138
+ setLoading(true);
139
+ console.info('onpaymentauthorized event', event);
140
+ _b.label = 1;
141
+ case 1:
142
+ _b.trys.push([1, 9, , 10]);
143
+ _a = scope;
144
+ switch (_a) {
145
+ case 'AppleToken': return [3, 2];
146
+ case 'TapToken': return [3, 4];
147
+ }
148
+ return [3, 7];
149
+ case 2: return [4, (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(event.payment.token.paymentData))];
150
+ case 3:
151
+ _b.sent();
152
+ session_1.completePayment({ status: 'STATUS_SUCCESS' });
153
+ return [3, 8];
154
+ case 4: return [4, appService.tapTokenization(event.payment.token.paymentData, profileData === null || profileData === void 0 ? void 0 : profileData.merchant)];
155
+ case 5:
156
+ data = _b.sent();
157
+ return [4, (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(data))];
158
+ case 6:
159
+ _b.sent();
160
+ session_1.completePayment({ status: 'STATUS_SUCCESS' });
161
+ return [3, 8];
162
+ case 7:
163
+ console.error('We only support AppleToken and ApplePay for now');
164
+ console.info('Completing payment with status: STATUS_FAILURE');
165
+ session_1.completePayment({ status: 'STATUS_FAILURE' });
166
+ _b.label = 8;
167
+ case 8: return [3, 10];
168
+ case 9:
169
+ error_2 = _b.sent();
170
+ console.error('error in onpaymentauthorized', error_2);
171
+ session_1.completePayment({ status: 'STATUS_FAILURE' });
172
+ throw error_2;
173
+ case 10:
174
+ setLoading(false);
175
+ return [2];
176
+ }
177
+ });
178
+ }); };
179
+ session_1.begin();
180
+ }
181
+ catch (e) {
182
+ if (!onError)
183
+ return [2];
184
+ if (e.errors) {
185
+ onError(e.errors);
186
+ return [2];
187
+ }
188
+ if ((_a = e.response) === null || _a === void 0 ? void 0 : _a.data.errors) {
189
+ onError(e.response.data.errors);
190
+ return [2];
191
+ }
192
+ if (e.message) {
193
+ onError([{ description: e.message, code: '400' }]);
194
+ return [2];
195
+ }
196
+ onError(e);
197
+ }
198
+ return [2];
199
+ });
200
+ }); };
201
+ return { loading: loading, onApplePayButtonClicked: onApplePayButtonClicked, disabled: !profileData };
202
+ };
@@ -0,0 +1 @@
1
+ export declare function useScript(src: string, async?: boolean): "loading" | "ready" | "idle" | "error";
@@ -0,0 +1,39 @@
1
+ import { useEffect, useState } from 'react';
2
+ export function useScript(src, async) {
3
+ if (async === void 0) { async = true; }
4
+ var _a = useState(src ? 'loading' : 'idle'), status = _a[0], setStatus = _a[1];
5
+ useEffect(function () {
6
+ if (!src) {
7
+ setStatus('idle');
8
+ return;
9
+ }
10
+ var script = document.querySelector("script[src=\"".concat(src, "\"]"));
11
+ if (!script) {
12
+ script = document.createElement('script');
13
+ script.src = src;
14
+ script.async = async;
15
+ script.setAttribute('data-status', 'loading');
16
+ document.body.appendChild(script);
17
+ var setAttributeFromEvent = function (event) {
18
+ script.setAttribute('data-status', event.type === 'load' ? 'ready' : 'error');
19
+ };
20
+ script.addEventListener('load', setAttributeFromEvent);
21
+ script.addEventListener('error', setAttributeFromEvent);
22
+ }
23
+ else {
24
+ setStatus(script.getAttribute('data-status'));
25
+ }
26
+ var setStateFromEvent = function (event) {
27
+ setStatus(event.type === 'load' ? 'ready' : 'error');
28
+ };
29
+ script.addEventListener('load', setStateFromEvent);
30
+ script.addEventListener('error', setStateFromEvent);
31
+ return function () {
32
+ if (script) {
33
+ script.removeEventListener('load', setStateFromEvent);
34
+ script.removeEventListener('error', setStateFromEvent);
35
+ }
36
+ };
37
+ }, [src]);
38
+ return status;
39
+ }
@@ -0,0 +1,4 @@
1
+ import { ApplePayButtonProps, ApplePayButton } from './features/ApplePayButton';
2
+ import { ButtonStyle, Scope, SupportedNetworks } from './constants';
3
+ export type { ApplePayButtonProps };
4
+ export { ApplePayButton, ButtonStyle, Scope, SupportedNetworks };
package/build/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { ApplePayButton, renderApplePayButton } from './features/ApplePayButton';
2
+ import { ButtonStyle, Scope, SupportedNetworks } from './constants';
3
+ export { ApplePayButton, ButtonStyle, Scope, SupportedNetworks };
4
+ window['TapSDKs'] = {
5
+ renderApplePayButton: renderApplePayButton,
6
+ ButtonStyle: ButtonStyle,
7
+ Scope: Scope,
8
+ SupportedNetworks: SupportedNetworks
9
+ };
@@ -0,0 +1,8 @@
1
+ import { ApplePayButtonProps, ApplePayRequestData, PaymentMethod } from '../@types';
2
+ import { SupportedNetworks } from '../constants';
3
+ export declare const validateSupportedNetworks: (supportedNetworksConfig: Array<(typeof SupportedNetworks)[keyof typeof SupportedNetworks]>, supportedNetworks: ApplePayButtonProps['supportedNetworks']) => ("amex" | "mada" | "masterCard" | "visa")[];
4
+ export declare const validateCurrency: (currency: string, currencies: string[]) => string;
5
+ export declare const getApplePayRequest: ({ transaction, billingContact, supportedNetworks, countryCode }: Pick<ApplePayButtonProps, "supportedNetworks" | "transaction" | "billingContact"> & {
6
+ countryCode: string;
7
+ }) => ApplePayRequestData;
8
+ export declare const getApplePayPaymentMethod: (paymentMethods: Array<PaymentMethod>) => PaymentMethod;
@@ -0,0 +1,54 @@
1
+ import { MerchantCapabilities } from '../constants';
2
+ export var validateSupportedNetworks = function (supportedNetworksConfig, supportedNetworks) {
3
+ var toLowerCase = function (item) { return item.toLowerCase(); };
4
+ if (!supportedNetworks)
5
+ return supportedNetworksConfig.map(toLowerCase);
6
+ if (supportedNetworks.length === 0)
7
+ return supportedNetworksConfig.map(toLowerCase);
8
+ if (supportedNetworks.length > supportedNetworksConfig.length) {
9
+ throw new Error("The supported networks list is not valid");
10
+ }
11
+ supportedNetworks.forEach(function (network) {
12
+ var isSupported = supportedNetworksConfig.some(function (item) { return item.toLowerCase() === network.toLowerCase(); });
13
+ if (!isSupported) {
14
+ throw new Error("The supported network ".concat(network, " is not supported"));
15
+ }
16
+ });
17
+ return supportedNetworks;
18
+ };
19
+ export var validateCurrency = function (currency, currencies) {
20
+ var isSupported = currencies.some(function (item) { return item.toLowerCase() === currency.toLowerCase(); });
21
+ if (!isSupported) {
22
+ throw new Error("The currency \"".concat(currency, "\" is not supported, you have to use one of these currencies: ").concat(currencies));
23
+ }
24
+ return currency;
25
+ };
26
+ export var getApplePayRequest = function (_a) {
27
+ var transaction = _a.transaction, billingContact = _a.billingContact, supportedNetworks = _a.supportedNetworks, countryCode = _a.countryCode;
28
+ return {
29
+ countryCode: countryCode,
30
+ currencyCode: transaction.currency,
31
+ merchantCapabilities: [MerchantCapabilities.Supports3DS],
32
+ supportedNetworks: supportedNetworks,
33
+ billingContact: billingContact && {
34
+ phoneNumber: billingContact.phone.code + billingContact.phone.number,
35
+ emailAddress: billingContact.email.address,
36
+ givenName: billingContact.name.first,
37
+ familyName: billingContact.name.last
38
+ },
39
+ total: {
40
+ amount: Number(transaction.amount),
41
+ label: transaction.label
42
+ }
43
+ };
44
+ };
45
+ export var getApplePayPaymentMethod = function (paymentMethods) {
46
+ var paymentMethod = paymentMethods.find(function (_a) {
47
+ var name = _a.name, payment_type = _a.payment_type;
48
+ return [name, payment_type].some(function (item) { return item.toLowerCase() === 'apple_pay'; });
49
+ });
50
+ if (!paymentMethod) {
51
+ throw new Error('Apple Pay is not configured in your payment options');
52
+ }
53
+ return paymentMethod;
54
+ };
@@ -0,0 +1,3 @@
1
+ export declare const createElementAndInject: (id: string) => HTMLDivElement;
2
+ export declare const reactElement: (elementId: string) => import("react-dom/client").Root;
3
+ export declare const removeElement: (elementId: string) => void;
@@ -0,0 +1,20 @@
1
+ import { createRoot } from 'react-dom/client';
2
+ export var createElementAndInject = function (id) {
3
+ var element = document.createElement('div');
4
+ element.setAttribute('id', id);
5
+ document.body.appendChild(element);
6
+ return element;
7
+ };
8
+ export var reactElement = function (elementId) {
9
+ var element = document.getElementById(elementId);
10
+ if (!element) {
11
+ element = createElementAndInject('tap-apple-pay-sdk-element');
12
+ }
13
+ return createRoot(element);
14
+ };
15
+ export var removeElement = function (elementId) {
16
+ var el = document.getElementById(elementId);
17
+ if (!el)
18
+ return;
19
+ el.remove();
20
+ };
@@ -0,0 +1 @@
1
+ export * from './html';
@@ -0,0 +1 @@
1
+ export * from './html';
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@tap-payments/apple-pay-button",
3
+ "version": "0.0.0-test",
4
+ "description": "Apple Pay Button React Component",
5
+ "main": "build/index.js",
6
+ "module": "build/index.js",
7
+ "types": "build/index.d.ts",
8
+ "files": [
9
+ "build",
10
+ "README.md"
11
+ ],
12
+ "scripts": {
13
+ "prepare": "npx husky install",
14
+ "prettier": "prettier --list-different \"src/**/*.{md,mdx,ts,js,tsx,jsx,json}\" *.json *.js",
15
+ "prettier:fix": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md,css,json}\" *.json *.js",
16
+ "lint": "eslint src --color --ext .js,.jsx,.ts,.tsx,.json",
17
+ "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
18
+ "start": "cross-env NODE_ENV=development webpack serve",
19
+ "build": "cross-env NODE_ENV=production webpack",
20
+ "copy:files": "copyfiles -u 1 src/**/*.css build/",
21
+ "tsc:alias": "tsc-alias -p tsconfig.json",
22
+ "ts:build": "rm -rf build && tsc && yarn tsc:alias && yarn copy:files",
23
+ "push": "npm publish --access public"
24
+ },
25
+ "keywords": [],
26
+ "author": {
27
+ "name": "Ahmed Elsharkawy",
28
+ "email": "a.elsharkawy@tap.company"
29
+ },
30
+ "license": "ISC",
31
+ "devDependencies": {
32
+ "@babel/core": "^7.18.6",
33
+ "@babel/preset-env": "^7.18.6",
34
+ "@babel/preset-react": "^7.18.6",
35
+ "@babel/preset-typescript": "^7.18.6",
36
+ "@types/crypto-js": "^4.1.1",
37
+ "@types/react": "^18.0.15",
38
+ "@types/react-dom": "^18.0.6",
39
+ "@typescript-eslint/eslint-plugin": "^5.30.5",
40
+ "@typescript-eslint/parser": "^5.30.5",
41
+ "babel-loader": "^8.2.5",
42
+ "copyfiles": "^2.4.1",
43
+ "cross-env": "^7.0.3",
44
+ "css-loader": "^6.7.1",
45
+ "css-minimizer-webpack-plugin": "^4.0.0",
46
+ "eslint": "^8.19.0",
47
+ "eslint-config-airbnb": "^19.0.4",
48
+ "eslint-config-prettier": "^8.5.0",
49
+ "eslint-plugin-import": "^2.26.0",
50
+ "eslint-plugin-jsx-a11y": "^6.6.0",
51
+ "eslint-plugin-node": "^11.1.0",
52
+ "eslint-plugin-prettier": "^4.2.1",
53
+ "eslint-plugin-react": "^7.30.1",
54
+ "eslint-plugin-react-hooks": "^4.6.0",
55
+ "file-loader": "^6.2.0",
56
+ "fork-ts-checker-webpack-plugin": "^7.2.12",
57
+ "html-loader": "^3.1.2",
58
+ "html-webpack-plugin": "^5.5.0",
59
+ "husky": "^8.0.1",
60
+ "lint-staged": "^13.0.3",
61
+ "mini-css-extract-plugin": "^2.6.1",
62
+ "prettier": "^2.7.1",
63
+ "sass": "^1.53.0",
64
+ "sass-loader": "^13.0.2",
65
+ "style-loader": "^3.3.1",
66
+ "terser-webpack-plugin": "^5.3.3",
67
+ "tsc-alias": "^1.6.11",
68
+ "typescript": "^4.7.4",
69
+ "webpack": "^5.73.0",
70
+ "webpack-cli": "^4.10.0",
71
+ "webpack-dev-server": "^4.9.3",
72
+ "webpack-merge": "^5.8.0"
73
+ },
74
+ "dependencies": {
75
+ "axios": "^1.2.2",
76
+ "react": ">=17.0.2",
77
+ "react-dom": ">=17.0.2"
78
+ },
79
+ "peerDependencies": {
80
+ "react": ">=17.0.2",
81
+ "react-dom": ">=17.0.2"
82
+ },
83
+ "lint-staged": {
84
+ "src/**/*.{ts,tsx,json,js,jsx}": [
85
+ "yarn run prettier:fix",
86
+ "yarn run lint",
87
+ "git add ."
88
+ ]
89
+ },
90
+ "browserslist": {
91
+ "production": [
92
+ ">0.2%",
93
+ "not dead",
94
+ "not op_mini all"
95
+ ],
96
+ "development": [
97
+ "last 1 chrome version",
98
+ "last 1 firefox version",
99
+ "last 1 safari version"
100
+ ]
101
+ }
102
+ }