@infosoftas/s4-orders-js-sdk 0.0.1-alpha1
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/.prettierignore +1 -0
- package/.prettierrc.json +7 -0
- package/package.json +41 -0
- package/src/App.scss +24 -0
- package/src/App.tsx +184 -0
- package/src/ErrorBoundary.tsx +41 -0
- package/src/api/OrdersApi.ts +44 -0
- package/src/api/SubscribeApi.ts +51 -0
- package/src/assets/styles/forms.scss +105 -0
- package/src/assets/styles/general.scss +38 -0
- package/src/assets/styles/variables.scss +29 -0
- package/src/components/Alert/Alert.tsx +22 -0
- package/src/components/Alert/alert.scss +21 -0
- package/src/components/Button/Button.tsx +43 -0
- package/src/components/Button/button.scss +48 -0
- package/src/components/FormFields/EmailField.tsx +53 -0
- package/src/components/FormFields/FormFields.helper.ts +16 -0
- package/src/components/FormFields/FormFieldsMapper.ts +13 -0
- package/src/components/FormFields/NameField.tsx +46 -0
- package/src/components/FormFields/PhoneField.tsx +55 -0
- package/src/components/Loader/Loader.tsx +22 -0
- package/src/components/Loader/loader.scss +37 -0
- package/src/components/MainIframe/MainIframe.tsx +42 -0
- package/src/components/OrderForm/OrderForm.tsx +235 -0
- package/src/components/OrderForm/orderForm.scss +10 -0
- package/src/constants/index.ts +8 -0
- package/src/enums/api.ts +4 -0
- package/src/enums/general.ts +12 -0
- package/src/hooks/useIframe.tsx +59 -0
- package/src/hooks/useMessageEvent.tsx +142 -0
- package/src/hooks/useQueryParams.ts +5 -0
- package/src/index.tsx +22 -0
- package/src/types/api.ts +12 -0
- package/src/types/general.ts +50 -0
- package/src/types/order.ts +41 -0
- package/src/utils/fetcher.ts +89 -0
- package/src/utils/helper.ts +18 -0
- package/src/utils/order.helper.ts +48 -0
- package/tsconfig.json +41 -0
- package/webpack.config.js +103 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { useEffect, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { MessageEventTypeEnum } from 'Enums/general';
|
|
4
|
+
import { CompleteOrderParamsType, OrderInfoType } from 'Types/order';
|
|
5
|
+
import useQueryParams from './useQueryParams';
|
|
6
|
+
|
|
7
|
+
const useMessageEvent = (
|
|
8
|
+
messageCallback: (data: CompleteOrderParamsType) => Promise<void>,
|
|
9
|
+
handleMessageEvent: (type: MessageEventTypeEnum) => void,
|
|
10
|
+
showIframe: boolean,
|
|
11
|
+
orderInfo: OrderInfoType | null
|
|
12
|
+
) => {
|
|
13
|
+
const queryParams = useQueryParams();
|
|
14
|
+
|
|
15
|
+
const handleMessage = useCallback(
|
|
16
|
+
async (event: MessageEvent) => {
|
|
17
|
+
// Vipps handler
|
|
18
|
+
if (event.data.type === MessageEventTypeEnum.VIPPS_COMPLETE) {
|
|
19
|
+
await messageCallback({
|
|
20
|
+
orderId: event.data.orderId || '',
|
|
21
|
+
agreementId: event.data.agreementId || '',
|
|
22
|
+
orderInfo: orderInfo || null,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// SwedbankPay handler
|
|
27
|
+
if (event.data.type === MessageEventTypeEnum.COMPLETE) {
|
|
28
|
+
await messageCallback({
|
|
29
|
+
orderId: event.data.orderId || '',
|
|
30
|
+
agreementId: event.data.agreementId || '',
|
|
31
|
+
orderInfo: orderInfo || null,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (event.data.type === MessageEventTypeEnum.CANCEL) {
|
|
35
|
+
handleMessageEvent(event.data.type);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
[orderInfo]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
window.addEventListener('message', handleMessage, false);
|
|
43
|
+
|
|
44
|
+
return () => {
|
|
45
|
+
window.removeEventListener('message', handleMessage, false);
|
|
46
|
+
};
|
|
47
|
+
}, [handleMessage]);
|
|
48
|
+
|
|
49
|
+
// Vipps
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (
|
|
52
|
+
queryParams.get('orderId') &&
|
|
53
|
+
queryParams.get('agreementId') &&
|
|
54
|
+
top &&
|
|
55
|
+
window !== top
|
|
56
|
+
) {
|
|
57
|
+
top?.postMessage(
|
|
58
|
+
{
|
|
59
|
+
type: MessageEventTypeEnum.VIPPS_COMPLETE,
|
|
60
|
+
orderId: queryParams.get('orderId'),
|
|
61
|
+
agreementId: queryParams.get('agreementId'),
|
|
62
|
+
},
|
|
63
|
+
top?.location?.origin || '*'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}, [queryParams.get('orderId'), queryParams.get('agreementId')]);
|
|
67
|
+
|
|
68
|
+
//Vipps
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (
|
|
71
|
+
queryParams.get('orderId') &&
|
|
72
|
+
queryParams.get('agreementId')
|
|
73
|
+
// !showIframe
|
|
74
|
+
) {
|
|
75
|
+
messageCallback({
|
|
76
|
+
orderId: queryParams.get('orderId') || '',
|
|
77
|
+
agreementId: queryParams.get('agreementId') || '',
|
|
78
|
+
orderInfo: orderInfo || null,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}, [
|
|
82
|
+
queryParams.get('orderId'),
|
|
83
|
+
queryParams.get('agreementId'),
|
|
84
|
+
// showIframe,
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
// SwedbankPay
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (
|
|
90
|
+
queryParams.get('action') &&
|
|
91
|
+
queryParams.get('S4OrderId') &&
|
|
92
|
+
queryParams.get('TransactionId') &&
|
|
93
|
+
top &&
|
|
94
|
+
window !== top
|
|
95
|
+
) {
|
|
96
|
+
top?.postMessage(
|
|
97
|
+
{
|
|
98
|
+
type: queryParams.get('action'),
|
|
99
|
+
orderId: queryParams.get('S4OrderId'),
|
|
100
|
+
agreementId: queryParams.get('TransactionId'),
|
|
101
|
+
},
|
|
102
|
+
top?.location?.origin || '*'
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}, [
|
|
106
|
+
queryParams.get('S4OrderId'),
|
|
107
|
+
queryParams.get('TransactionId'),
|
|
108
|
+
queryParams.get('action'),
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
// SwedbankPay
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (
|
|
114
|
+
queryParams.get('S4OrderId') &&
|
|
115
|
+
queryParams.get('TransactionId') &&
|
|
116
|
+
queryParams.get('action') === MessageEventTypeEnum.COMPLETE &&
|
|
117
|
+
!showIframe
|
|
118
|
+
) {
|
|
119
|
+
messageCallback({
|
|
120
|
+
orderId: queryParams.get('S4OrderId') || '',
|
|
121
|
+
agreementId: queryParams.get('TransactionId') || '',
|
|
122
|
+
orderInfo: orderInfo || null,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
queryParams.get('action') === MessageEventTypeEnum.CANCEL &&
|
|
128
|
+
!showIframe
|
|
129
|
+
) {
|
|
130
|
+
handleMessageEvent(
|
|
131
|
+
queryParams.get('action') as MessageEventTypeEnum
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}, [
|
|
135
|
+
queryParams.get('action'),
|
|
136
|
+
queryParams.get('S4OrderId'),
|
|
137
|
+
queryParams.get('TransactionId'),
|
|
138
|
+
showIframe,
|
|
139
|
+
]);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export default useMessageEvent;
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createRoot, Root } from 'react-dom/client';
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
|
|
4
|
+
import { ConfigType } from 'Types/general';
|
|
5
|
+
import { createSubscriber, mapSubscriberToUser } from 'API/SubscribeApi';
|
|
6
|
+
import App from './App';
|
|
7
|
+
|
|
8
|
+
let root: Root;
|
|
9
|
+
|
|
10
|
+
export const orderComponent = {
|
|
11
|
+
init: function (config: ConfigType) {
|
|
12
|
+
const domNode = document.getElementById(config.domElementId);
|
|
13
|
+
root = createRoot(domNode || document.createElement('div'));
|
|
14
|
+
const reactElement = createElement(App, config);
|
|
15
|
+
root.render(reactElement);
|
|
16
|
+
},
|
|
17
|
+
remove: function () {
|
|
18
|
+
(root as Root)?.unmount();
|
|
19
|
+
},
|
|
20
|
+
createSubscriber,
|
|
21
|
+
mapSubscriberToUser,
|
|
22
|
+
};
|
package/src/types/api.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PaymentMethodEnum } from 'Enums/general';
|
|
2
|
+
import { OrderFormInputsType } from './order';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
sdkOrderCallback: () => void;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type OrderFormFiledType = {
|
|
11
|
+
name: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
readOnly?: boolean;
|
|
14
|
+
label?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type PaymentMethodOptionsType = {
|
|
18
|
+
[key in PaymentMethodEnum]: {
|
|
19
|
+
generateSubscriberContact?: boolean;
|
|
20
|
+
accountId?: string;
|
|
21
|
+
orderFormFields: OrderFormFiledType[];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type ConfigType = {
|
|
26
|
+
domElementId: string;
|
|
27
|
+
moduleTitle?: string;
|
|
28
|
+
templatePackageId: string;
|
|
29
|
+
subscriberId: string;
|
|
30
|
+
userId: string;
|
|
31
|
+
identityProviderId: string;
|
|
32
|
+
organizationId: string;
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
redirectUrl?: string;
|
|
35
|
+
showIframe?: boolean;
|
|
36
|
+
availablePaymentMethods?: { label: string; value: PaymentMethodEnum }[];
|
|
37
|
+
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
38
|
+
language?: string;
|
|
39
|
+
merchantAgreementUrl?: string;
|
|
40
|
+
settings?: {
|
|
41
|
+
successText?: string;
|
|
42
|
+
failureText?: string;
|
|
43
|
+
buttonText?: string;
|
|
44
|
+
orderDefaultValues?: OrderFormInputsType;
|
|
45
|
+
paymentMethodLabel?: string;
|
|
46
|
+
errorReqMsg?: string;
|
|
47
|
+
errorInvalidEmailMsg?: string;
|
|
48
|
+
errorInvalidPhoneMsg?: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PaymentMethodEnum } from 'Enums/general';
|
|
2
|
+
|
|
3
|
+
export type OrderFormInputsType = {
|
|
4
|
+
name?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
phoneNumber?: string;
|
|
7
|
+
paymentMethod?: PaymentMethodEnum;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type VippsMobilePay = {
|
|
11
|
+
phoneNumber?: string;
|
|
12
|
+
merchantRedirectUrl: string;
|
|
13
|
+
merchantAgreementUrl: string;
|
|
14
|
+
generateSubscriberContact?: boolean;
|
|
15
|
+
accountId?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type SwedbankPay = {
|
|
19
|
+
accountId?: string;
|
|
20
|
+
completeUrl: string;
|
|
21
|
+
cancelUrl: string;
|
|
22
|
+
language?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type AgreementsType = {
|
|
26
|
+
paymentProvider: PaymentMethodEnum;
|
|
27
|
+
vippsMobilePay?: VippsMobilePay;
|
|
28
|
+
swedbankPay?: SwedbankPay;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type OrderInfoType = {
|
|
32
|
+
subscriberId: string;
|
|
33
|
+
paymentMethod: string;
|
|
34
|
+
orderId: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type CompleteOrderParamsType = {
|
|
38
|
+
orderId: string;
|
|
39
|
+
agreementId: string;
|
|
40
|
+
orderInfo: OrderInfoType | null;
|
|
41
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { HttpStatusCode } from 'Enums/api';
|
|
2
|
+
import { ApiResponseType } from 'Types/api';
|
|
3
|
+
import { BASE_API } from 'Constants/index';
|
|
4
|
+
|
|
5
|
+
export type Method =
|
|
6
|
+
| 'GET'
|
|
7
|
+
| 'POST'
|
|
8
|
+
| 'PUT'
|
|
9
|
+
| 'DELETE'
|
|
10
|
+
| 'HEAD'
|
|
11
|
+
| 'OPTIONS'
|
|
12
|
+
| 'PATCH';
|
|
13
|
+
|
|
14
|
+
type Fetcher<T> = {
|
|
15
|
+
url: string;
|
|
16
|
+
params?: Record<string, string | string[]>;
|
|
17
|
+
method?: Method;
|
|
18
|
+
headers?: HeadersInit;
|
|
19
|
+
body?: T;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function createHeader<T>(options: Fetcher<T>): Fetcher<T> {
|
|
23
|
+
const accessToken = localStorage.getItem('authTokenKey') || '';
|
|
24
|
+
|
|
25
|
+
const headers = new Headers({
|
|
26
|
+
accept: 'application/json',
|
|
27
|
+
...(accessToken && {
|
|
28
|
+
Authorization: `Bearer ${accessToken}`,
|
|
29
|
+
}),
|
|
30
|
+
...options.headers,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!(options.body instanceof FormData)) {
|
|
34
|
+
headers.append('Content-Type', 'application/json');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return { method: 'GET', ...options, headers };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function fetcher<ResponseType, BodyType = void>(
|
|
41
|
+
options: Fetcher<BodyType>
|
|
42
|
+
): Promise<ApiResponseType<ResponseType> | ResponseType> {
|
|
43
|
+
const { url, method, headers, body, params } = createHeader(options);
|
|
44
|
+
|
|
45
|
+
const endpoint = new URL(`${BASE_API}${url}`);
|
|
46
|
+
|
|
47
|
+
if (params) {
|
|
48
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
value.forEach((v) => endpoint.searchParams.append(key, v));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
endpoint.searchParams.append(key, value);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return new Promise<ApiResponseType<ResponseType> | ResponseType>(
|
|
58
|
+
(resolve, reject) => {
|
|
59
|
+
return fetch(endpoint.toString(), {
|
|
60
|
+
method,
|
|
61
|
+
headers,
|
|
62
|
+
body: body instanceof FormData ? body : JSON.stringify(body),
|
|
63
|
+
})
|
|
64
|
+
.then(async (response) => {
|
|
65
|
+
if (response.status === HttpStatusCode.UNAUTHORIZED) {
|
|
66
|
+
localStorage.removeItem('authTokenKey');
|
|
67
|
+
reject({ message: 'Not Authorized user!' });
|
|
68
|
+
} else if (response.status === HttpStatusCode.FORBIDDEN) {
|
|
69
|
+
reject({ message: 'Something Wrong with permission!' });
|
|
70
|
+
} else {
|
|
71
|
+
const data = await response?.json();
|
|
72
|
+
if (response.ok) {
|
|
73
|
+
resolve(data);
|
|
74
|
+
} else {
|
|
75
|
+
const message =
|
|
76
|
+
data.message || data.details || data.title;
|
|
77
|
+
reject({ ...data, message });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.catch((error) => {
|
|
82
|
+
console.log(error, 'error');
|
|
83
|
+
reject(error?.response);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default fetcher;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { WRONG_MSG } from 'Constants/index';
|
|
2
|
+
|
|
3
|
+
export const prepareErrorMessage = (error: Error, defaultMsg?: string) => {
|
|
4
|
+
if (typeof error === 'string') {
|
|
5
|
+
try {
|
|
6
|
+
const parsedError = JSON.parse(error);
|
|
7
|
+
return (parsedError as { message: string }).message;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
return error;
|
|
10
|
+
}
|
|
11
|
+
} else {
|
|
12
|
+
return (
|
|
13
|
+
((error as { message: string })?.message as string) ||
|
|
14
|
+
defaultMsg ||
|
|
15
|
+
WRONG_MSG
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MessageEventTypeEnum, PaymentMethodEnum } from 'Enums/general';
|
|
2
|
+
import { OrderFormInputsType, AgreementsType } from 'Types/order';
|
|
3
|
+
|
|
4
|
+
type AgreementModelType = {
|
|
5
|
+
paymentMethod: PaymentMethodEnum;
|
|
6
|
+
redirectUrl: string;
|
|
7
|
+
data: OrderFormInputsType;
|
|
8
|
+
generateSubscriberContact: boolean;
|
|
9
|
+
language: string;
|
|
10
|
+
merchantAgreementUrl: string;
|
|
11
|
+
accountId?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const prepareAgreementModel = ({
|
|
15
|
+
paymentMethod,
|
|
16
|
+
redirectUrl,
|
|
17
|
+
data,
|
|
18
|
+
generateSubscriberContact,
|
|
19
|
+
language,
|
|
20
|
+
merchantAgreementUrl,
|
|
21
|
+
accountId,
|
|
22
|
+
}: AgreementModelType): AgreementsType => {
|
|
23
|
+
const model: AgreementsType = {
|
|
24
|
+
paymentProvider: paymentMethod,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
if (paymentMethod === PaymentMethodEnum.SwedbankPay) {
|
|
28
|
+
model.swedbankPay = {
|
|
29
|
+
cancelUrl: `${redirectUrl}?action=${MessageEventTypeEnum.CANCEL}`,
|
|
30
|
+
completeUrl: `${redirectUrl}?action=${MessageEventTypeEnum.COMPLETE}`,
|
|
31
|
+
language,
|
|
32
|
+
accountId,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return model;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
...model,
|
|
40
|
+
vippsMobilePay: {
|
|
41
|
+
generateSubscriberContact,
|
|
42
|
+
merchantAgreementUrl,
|
|
43
|
+
accountId,
|
|
44
|
+
phoneNumber: data.phoneNumber,
|
|
45
|
+
merchantRedirectUrl: redirectUrl,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es5",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"downlevelIteration": true,
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"checkJs": false,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"allowSyntheticDefaultImports": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"moduleResolution": "node",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"isolatedModules": false,
|
|
18
|
+
"noEmit": false,
|
|
19
|
+
"noImplicitAny": true,
|
|
20
|
+
"jsx": "react-jsx",
|
|
21
|
+
"baseUrl": "src",
|
|
22
|
+
"sourceMap": true,
|
|
23
|
+
"inlineSources": true,
|
|
24
|
+
"sourceRoot": "/",
|
|
25
|
+
"paths": {
|
|
26
|
+
"*": ["*"],
|
|
27
|
+
"API": ["api"],
|
|
28
|
+
"API/*": ["api/*"],
|
|
29
|
+
"Component/*": ["components/*"],
|
|
30
|
+
"Utils/*": ["utils/*"],
|
|
31
|
+
"Hooks/*": ["hooks/*"],
|
|
32
|
+
"Models/*": ["models/*"],
|
|
33
|
+
"Types/*": ["types/*"],
|
|
34
|
+
"Enums/*": ["enums/*"],
|
|
35
|
+
"Constants/*": ["constants/*"],
|
|
36
|
+
"Assets/*": ["assets/*"]
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"include": ["src"],
|
|
40
|
+
"exclude": ["node_modules"]
|
|
41
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
3
|
+
const Dotenv = require('dotenv-webpack');
|
|
4
|
+
|
|
5
|
+
const envEnum = {
|
|
6
|
+
qa: 'qa',
|
|
7
|
+
dev: 'dev',
|
|
8
|
+
prod: 'production',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = (env) => {
|
|
12
|
+
const enableSourceMap = env.mode === 'dev' ? true : false;
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
mode: env.mode,
|
|
16
|
+
target: 'web',
|
|
17
|
+
entry: './src/index.tsx',
|
|
18
|
+
devtool: enableSourceMap ? 'inline-source-map' : false,
|
|
19
|
+
experiments: {
|
|
20
|
+
outputModule: true,
|
|
21
|
+
},
|
|
22
|
+
resolve: {
|
|
23
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
24
|
+
alias: {
|
|
25
|
+
Src: path.resolve(__dirname, 'src'),
|
|
26
|
+
API: path.resolve(__dirname, 'src/api'),
|
|
27
|
+
Component: path.resolve(__dirname, 'src/components'),
|
|
28
|
+
Utils: path.resolve(__dirname, 'src/utils'),
|
|
29
|
+
Hooks: path.resolve(__dirname, 'src/hooks'),
|
|
30
|
+
Models: path.resolve(__dirname, 'src/models'),
|
|
31
|
+
Types: path.resolve(__dirname, 'src/types'),
|
|
32
|
+
Enums: path.resolve(__dirname, 'src/enums'),
|
|
33
|
+
Constants: path.resolve(__dirname, 'src/constants'),
|
|
34
|
+
Assets: path.resolve(__dirname, 'src/assets'),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
output: {
|
|
38
|
+
filename: 'script.js',
|
|
39
|
+
path: path.resolve(__dirname, 'dist'),
|
|
40
|
+
publicPath: '/',
|
|
41
|
+
library: {
|
|
42
|
+
type: 'module',
|
|
43
|
+
},
|
|
44
|
+
clean: true,
|
|
45
|
+
asyncChunks: false,
|
|
46
|
+
},
|
|
47
|
+
plugins: [
|
|
48
|
+
new MiniCssExtractPlugin({
|
|
49
|
+
filename: 'css/style.css',
|
|
50
|
+
}),
|
|
51
|
+
new Dotenv({
|
|
52
|
+
path: `./.env.${
|
|
53
|
+
env.mode === envEnum.prod ? 'prod' : env.mode || 'prod'
|
|
54
|
+
}`, // Path to .env file (this is the default)
|
|
55
|
+
safe: false, // load .env.example (defaults to "false" which does not use dotenv-safe)
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
module: {
|
|
59
|
+
rules: [
|
|
60
|
+
{
|
|
61
|
+
test: /\.(js|jsx)$/,
|
|
62
|
+
exclude: /node_modules/,
|
|
63
|
+
use: {
|
|
64
|
+
loader: 'babel-loader',
|
|
65
|
+
options: {
|
|
66
|
+
presets: [
|
|
67
|
+
'@babel/preset-env',
|
|
68
|
+
'@babel/preset-react',
|
|
69
|
+
'@babel/preset-typescript',
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
test: /\.(ts|tsx)$/,
|
|
76
|
+
exclude: /node_modules/,
|
|
77
|
+
use: ['ts-loader'],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
test: /\.scss$/,
|
|
81
|
+
use: [
|
|
82
|
+
{
|
|
83
|
+
loader: 'style-loader',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
loader: 'css-loader', // translates CSS into CommonJS
|
|
87
|
+
options: { sourceMap: enableSourceMap },
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
loader: 'sass-loader', // compiles Scss to CSS
|
|
91
|
+
options: {
|
|
92
|
+
sourceMap: enableSourceMap,
|
|
93
|
+
sassOptions: {
|
|
94
|
+
javascriptEnabled: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
};
|