TD-681: Migrate to Vite (#219)

This commit is contained in:
Ildar Galeev 2023-07-31 15:13:49 +03:00 committed by GitHub
parent 1c448dcc40
commit 8d4dd2fa4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 2390 additions and 16007 deletions

View File

@ -23,7 +23,7 @@ jobs:
- name: Set checkout version
uses: jossef/action-set-json-field@v2
with:
file: ./dist/env.json
file: ./dist/v1/env.json
field: version
value: ${{ github.sha }}
- name: Deploy image

1
.gitignore vendored
View File

@ -2,4 +2,3 @@
/dist/
Dockerfile
.DS_Store
/.cache-loader/

5
.idea/.gitignore vendored
View File

@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CamelCaseConfig">
<option name="cb5State" value="false" />
<option name="cb6State" value="false" />
<option name="cb7State" value="false" />
</component>
</project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/.cache-loader" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,58 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<HTMLCodeStyleSettings>
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
<option name="HTML_ENFORCE_QUOTES" value="true" />
</HTMLCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</TypeScriptCodeStyleSettings>
<VueCodeStyleSettings>
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
</VueCodeStyleSettings>
<codeStyleSettings language="HTML">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Vue">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/checkout.iml" filepath="$PROJECT_DIR$/.idea/checkout.iml" />
</modules>
</component>
</project>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="AUTOMATIC" />
<option name="myRunOnSave" value="true" />
<option name="myRunOnReformat" value="true" />
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,json}" />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -27,7 +27,6 @@ package-lock.json
package.json
node_modules
dist
.cache-loader
# VS Code
.vscode

View File

@ -1,5 +0,0 @@
{
"recommendations": [
"eamodio.toggle-excluded-files"
]
}

21
.vscode/settings.json vendored
View File

@ -1,21 +0,0 @@
{
"cSpell.words": [
"Unmount",
"Euroset",
"QPS"
],
"typescript.tsdk": "./node_modules/typescript/lib",
"prettier.configPath": ".prettierrc",
"prettier.prettierPath": "node_modules/prettier",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"files.exclude": {
".cache-loader": true,
".vscode": true,
"**/.DS_Store": true,
"**/.git": true,
"**/.hg": true,
"**/.svn": true,
"**/CVS": true
},
}

View File

@ -12,5 +12,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="src/app/index.tsx"></script>
</body>
</html>

View File

@ -1,49 +0,0 @@
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
name: 'checkout',
stats: {
children: false,
moduleTrace: false,
modules: false
},
entry: {
app: ['./src/app/polyfills.ts', './src/app/index.tsx']
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
},
resolve: {
modules: ['node_modules', path.join(__dirname, 'src/app')],
extensions: ['.ts', '.tsx', '.js', '.mjs'],
alias: {
checkout: __dirname + '/../src/app'
}
},
plugins: [
new HtmlWebpackPlugin({
template: './src/app/index.html',
filename: 'checkout.html'
}),
new CopyWebpackPlugin(
[
{ from: './src/app/finish-interaction.html' },
{ from: './src/appConfig.json', to: '..' },
{ from: './src/env.json', to: '..' },
{ from: './src/locale/*.json', to: './locale', flatten: true },
{ from: './src/assets', to: '../assets' }
],
{ logLevel: 'warn' }
)
]
};

View File

@ -1,90 +0,0 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const path = require('path');
const os = require('os');
module.exports = (env) => ({
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: [
{
loader: 'thread-loader',
options: {
workers: Math.round(os.cpus().length / 2)
}
},
'cache-loader',
{
loader: 'ts-loader',
options: {
transpileOnly: true,
happyPackMode: true,
// TODO: после закрытия issue https://github.com/Igorbek/typescript-plugin-styled-components/issues/14
// добавить минификацию styled-components под prod
...(env === 'development'
? { getCustomTransformers: path.join(__dirname, './ts-transformers.js') }
: {})
}
}
],
exclude: /node_modules/
},
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto'
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
minimize: true,
modules: true,
namedExport: true,
localIdentName: '[local]__[hash:5]'
}
}
]
},
{
test: /\.(jpeg|jpg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[hash:8].[ext]',
outputPath: './assets/',
mimetype: 'mimetype=image/jpeg'
}
}
]
},
{
test: /\.svg$/,
oneOf: [
{
loader: 'svg-react-loader',
issuer: /\.tsx?$/,
options: {
classIdPrefix: '[name]-[hash:8]__',
uniqueIdPrefix: true
}
}
],
exclude: /node_modules/
}
]
},
plugins: [
new ForkTsCheckerWebpackPlugin({
checkSyntacticErrors: true,
formatter: 'codeframe',
tslint: true
})
]
});

View File

@ -1,10 +0,0 @@
const path = require('path');
const _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;

View File

@ -1,17 +0,0 @@
const path = require('path');
module.exports = {
name: 'initializer',
stats: {
children: false,
moduleTrace: false,
modules: false
},
entry: {
checkout: './src/initializer/index.ts'
},
resolve: {
modules: ['node_modules', path.join(__dirname, 'src/initializer')],
extensions: ['.ts', '.js']
}
};

View File

@ -1,13 +0,0 @@
const helpers = require('./helpers');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const prepareOutputConfig = (outputPath, jsFilenamePattern = '[name]', cssFilenamePattern = '[name]') => ({
output: {
filename: `${jsFilenamePattern}.js`,
path: helpers.root(outputPath),
publicPath: './'
},
plugins: [new MiniCssExtractPlugin({ filename: `${cssFilenamePattern}.css` })]
});
module.exports = prepareOutputConfig;

View File

@ -1,6 +0,0 @@
const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
const styledComponentsTransformer = createStyledComponentsTransformer({ ssr: false, displayName: true });
const getCustomTransformers = () => ({ before: [styledComponentsTransformer] });
module.exports = getCustomTransformers;

View File

@ -1,32 +0,0 @@
const path = require('path');
const WriteFilePlugin = require('write-file-webpack-plugin');
const merge = require('webpack-merge');
const checkoutConfig = require('./checkout-config');
const initializerConfig = require('./initializer-config');
const prepareOutputConfig = require('./prepare-output-config');
const commonConfig = require('./common-config');
const commonDevConfig = {
devtool: 'source-map',
plugins: [
new WriteFilePlugin({
log: false
})
],
devServer: {
contentBase: path.join(__dirname, '../dist'),
compress: true,
disableHostCheck: false,
stats: 'minimal'
}
};
const baseOutput = 'dist';
const prepareModule = (env, baseConfig, outputPath) =>
merge(baseConfig, commonConfig(env), prepareOutputConfig(outputPath), commonDevConfig);
module.exports = (env, { mode }) => [
prepareModule(mode, checkoutConfig, `${baseOutput}/v1`),
prepareModule(mode, initializerConfig, baseOutput)
];

View File

@ -1,32 +0,0 @@
const webpack = require('webpack');
const merge = require('webpack-merge');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const checkoutConfig = require('./checkout-config');
const initializerConfig = require('./initializer-config');
const prepareOutputConfig = require('./prepare-output-config');
const commonConfig = require('./common-config');
const commonProdConfig = {
devtool: 'source-map',
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new BundleAnalyzerPlugin({
analyzerMode: 'disabled'
})
]
};
const baseOutput = 'dist';
const prepareModule = (env, baseConfig, outputPath, jsPattern, cssPattern) =>
merge(baseConfig, commonConfig(env), prepareOutputConfig(outputPath, jsPattern, cssPattern), commonProdConfig);
module.exports = (env, { mode }) => [
prepareModule(mode, checkoutConfig, `${baseOutput}/v1`, '[name].[hash:20]', '[hash:20]'),
prepareModule(mode, initializerConfig, baseOutput)
];

17625
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,16 +3,18 @@
"version": "0.1.0",
"private": true,
"scripts": {
"clear": "rimraf dist && rimraf .cache-loader",
"build": "npm run clear && webpack --mode production --colors --progress --config config/webpack.prod.js",
"start": "npm run clear && webpack-dev-server --mode development --colors --progress --config config/webpack.dev.js --port 7050 --host ::",
"dev": "vite --c vite.config.app.ts",
"build:app": "vite build --c vite.config.app.ts",
"build:checkout": "vite build --c vite.config.checkout.ts",
"build": "npm run build:checkout && npm run build:app",
"preview": "npm run build && vite --c vite.config.preview.ts",
"test": "jest",
"test:watch": "jest --watch",
"check": "npm run lint:fix; npm run prettier:check",
"fix": "npm run lint:fix; npm run prettier:fix",
"prettier:fix": "prettier \"**\" --write",
"prettier:check": "prettier \"**\" --list-different",
"lint:fix": "tslint \"src/**/*.@(ts|tsx)\" -e \"**/*.d.ts\""
"lint:fix": "tslint \"src/**/*.@(ts|tsx)\" -e \"**/*.d.ts\"",
"check": "npm run lint:fix; npm run prettier:check",
"fix": "npm run lint:fix; npm run prettier:fix"
},
"license": "Apache-2.0",
"dependencies": {
@ -43,37 +45,20 @@
"@types/react": "18.2.14",
"@types/react-dom": "18.2.6",
"@types/react-test-renderer": "18.0.0",
"cache-loader": "4.1.0",
"concurrently": "7.0.0",
"copy-webpack-plugin": "~5.1.1",
"css-loader": "~1.0.1",
"file-loader": "~2.0.0",
"fork-ts-checker-webpack-plugin": "~4.1.1",
"html-webpack-plugin": "~3.2.0",
"identity-obj-proxy": "~3.0.0",
"@vitejs/plugin-react": "4.0.3",
"jest": "29.5.0",
"jest-environment-jsdom": "29.5.0",
"mini-css-extract-plugin": "~0.4.5",
"prettier": "~1.19.1",
"react-test-renderer": "18.2.0",
"rimraf": "~2.6.2",
"style-loader": "~0.23.1",
"svg-react-loader": "~0.4.6",
"thread-loader": "~2.1.2",
"ts-jest": "29.1.0",
"ts-loader": "~5.3.3",
"tslint": "~5.11.0",
"tslint-config-prettier": "~1.18.0",
"tslint-immutable": "~4.5.1",
"tslint-loader": "~3.5.4",
"tslint-react": "~3.6.0",
"typescript": "4.5.4",
"typescript-plugin-styled-components": "~1.0.0",
"webpack": "~4.29.0",
"webpack-bundle-analyzer": "~3.6.0",
"webpack-cli": "~3.3.0",
"webpack-dev-server": "~3.11.0",
"webpack-merge": "~4.2.1",
"write-file-webpack-plugin": "~4.5.0"
"vite": "4.4.6",
"vite-plugin-static-copy": "0.17.0",
"vite-plugin-svgr": "3.2.0",
"vite-tsconfig-paths": "4.2.0"
}
}

View File

@ -3,4 +3,4 @@ import { getNocacheValue } from 'checkout/utils';
import { fetchCapi } from './fetch-capi';
export const getAppConfig = (): Promise<AppConfig> =>
fetchCapi({ endpoint: `../appConfig.json?nocache=${getNocacheValue()}` });
fetchCapi({ endpoint: `./appConfig.json?nocache=${getNocacheValue()}` });

View File

@ -5,4 +5,4 @@ export interface Env {
version: string;
}
export const getEnv = (): Promise<Env> => fetchCapi({ endpoint: `../env.json?nocache=${getNocacheValue()}` });
export const getEnv = (): Promise<Env> => fetchCapi({ endpoint: `./env.json?nocache=${getNocacheValue()}` });

View File

@ -4,9 +4,10 @@ import { FieldError, UseFormRegister } from 'react-hook-form';
import { validateCardHolder } from './validate-card-holder';
import { Locale } from 'checkout/locale';
import { formatCardHolder } from './format-card-holder';
import { User, Input } from 'checkout/components';
import { Input } from 'checkout/components';
import { CardFormInputs } from '../../card-form-inputs';
import isNil from 'checkout/utils/is-nil';
import { ReactComponent as UserIcon } from '../../../../../../../ui/icon/user.svg';
export type CardHolderProps = {
register: UseFormRegister<CardFormInputs>;
@ -21,7 +22,7 @@ export const CardHolder = ({ register, locale, fieldError, isDirty }: CardHolder
required: true,
validate: (value) => !validateCardHolder(value) || 'Card holder is invalid'
})}
icon={<User />}
icon={<UserIcon />}
placeholder={locale['form.input.cardholder.placeholder']}
mark={true}
id="card-holder-input"

View File

@ -2,13 +2,14 @@ import * as React from 'react';
import { FieldError, UseFormRegister, UseFormWatch } from 'react-hook-form';
import styled from 'styled-components';
import { CardTypeIcon } from './card-type-icon';
import { validateCardNumber } from './validate-card-number';
import { Card, Input } from 'checkout/components';
import { Input } from 'checkout/components';
import { Locale } from 'checkout/locale';
import { formatCardNumber } from './format-card-number';
import isNil from 'checkout/utils/is-nil';
import { CardFormInputs } from '../../card-form-inputs';
import { ReactComponent as CardIcon } from '../../../../../../../ui/icon/card.svg';
import { CardTypeIcon } from 'checkout/components/ui/card-type-icon';
const InputContainer = styled.div`
width: 100%;
@ -36,7 +37,7 @@ export const CardNumber = ({ register, locale, fieldError, isDirty, watch }: Car
required: true,
validate: (value) => !validateCardNumber(value) || 'Card number is invalid'
})}
icon={<Card />}
icon={<CardIcon />}
placeholder={locale['form.input.card.placeholder']}
mark={true}
type="tel"

View File

@ -1,58 +0,0 @@
import * as React from 'react';
import { number } from 'card-validator';
import styled, { keyframes } from 'styled-components';
import * as cardIcons from 'checkout/components/ui/icon/card';
interface CardTypeIconProps {
cardNumber: string;
className?: string;
}
const growth = keyframes`
from {
transform: scale(0);
}
to {
transform: scale(1);
}
`;
const cardIconsMapping = {
visa: cardIcons.Visa,
mastercard: cardIcons.Mastercard,
maestro: cardIcons.Maestro,
mir: cardIcons.Mir,
'american-express': cardIcons.AmericanExpress,
'diners-club': cardIcons.DinersClub,
discover: cardIcons.Discover,
jcb: cardIcons.Jcb,
unionpay: cardIcons.Unionpay,
elo: cardIcons.Elo,
hipercard: cardIcons.Hipercard
};
export function getCardIconClass(cardNumber: string) {
const { card } = number(cardNumber);
if (!card) {
return;
}
return (cardIconsMapping as any)[card.type];
}
const CardTypeIconDef = styled<React.FC<CardTypeIconProps>>(({ cardNumber, className }) => {
const Icon = getCardIconClass(cardNumber);
return Icon ? <Icon className={className} /> : null;
})`
position: absolute;
top: 15px;
right: 15px;
width: 31px;
height: 19px;
animation: ${growth} 0.5s;
background: #fff;
`;
export const CardTypeIcon = ({ cardNumber }: CardTypeIconProps) => {
return <CardTypeIconDef cardNumber={cardNumber} />;
};

View File

@ -1,2 +1 @@
export * from './card-number';
export * from './card-type-icon';

View File

@ -4,9 +4,10 @@ import { FieldError, UseFormRegister } from 'react-hook-form';
import { validateExpireDate } from './validate-expire-date';
import { Locale } from 'checkout/locale';
import { formatExpiry } from './format-expiry';
import { Calendar, Input } from 'checkout/components';
import { Input } from 'checkout/components';
import { CardFormInputs } from '../../card-form-inputs';
import isNil from 'checkout/utils/is-nil';
import { ReactComponent as CalendarIcon } from '../../../../../../../ui/icon/calendar.svg';
export type ExpireDateProps = {
register: UseFormRegister<CardFormInputs>;
@ -21,7 +22,7 @@ export const ExpireDate = ({ register, locale, fieldError, isDirty }: ExpireDate
required: true,
validate: (value) => !validateExpireDate(value) || 'Exp date is invalid'
})}
icon={<Calendar />}
icon={<CalendarIcon />}
placeholder={locale['form.input.expiry.placeholder']}
mark={true}
type="tel"

View File

@ -5,10 +5,11 @@ import { FieldError, UseFormRegister } from 'react-hook-form';
import { validateSecureCode } from './validate-secure-code';
import { Locale } from 'checkout/locale';
import { formatCVC } from './format-cvc';
import { Lock, Input } from 'checkout/components';
import { Input } from 'checkout/components';
import { safeVal } from 'checkout/utils';
import { CardFormInputs } from '../../card-form-inputs';
import isNil from 'checkout/utils/is-nil';
import { ReactComponent as LockIcon } from '../../../../../../../ui/icon/lock.svg';
export interface SecureCodeProps {
register: UseFormRegister<CardFormInputs>;
@ -30,7 +31,7 @@ export const SecureCode = ({ cardNumber, locale, obscureCardCvv, register, field
required: true,
validate: (value) => !validateSecureCode(value, { cardNumber }) || 'Secure code is invalid'
})}
icon={<Lock />}
icon={<LockIcon />}
placeholder={getPlaceholder(cardNumber, locale)}
mark={true}
type={obscureCardCvv ? 'password' : 'tel'}

View File

@ -7,8 +7,8 @@ import { validateAmount } from './validate-amount';
import { Locale } from 'checkout/locale';
import { InvoiceTemplateLineCostRange, InvoiceTemplateLineCostUnlim } from 'checkout/backend';
import { formatAmount } from './format-amount';
import { Amount as AmountIcon } from 'checkout/components';
import isNil from 'checkout/utils/is-nil';
import { ReactComponent as AmountIcon } from '../../../../../../ui/icon/amount.svg';
export type AmountProps = {
register: UseFormRegister<any>;

View File

@ -0,0 +1,57 @@
import * as React from 'react';
import { number } from 'card-validator';
import styled, { keyframes } from 'styled-components';
import { ReactComponent as Mir } from './icon/card/mir.svg';
import { ReactComponent as Unionpay } from './icon/card/unionpay.svg';
import { ReactComponent as Visa } from './icon/card/visa.svg';
import { ReactComponent as Mastercard } from './icon/card/mastercard.svg';
import { ReactComponent as Maestro } from './icon/card/maestro.svg';
const growth = keyframes`
from {
transform: scale(0);
}
to {
transform: scale(1);
}
`;
const getIconInstance = (cardNumber: string) => {
const { card } = number(cardNumber);
if (!card) {
return null;
}
switch (card.type) {
case 'mir':
return Mir;
case 'unionpay':
return Unionpay;
case 'maestro':
return Maestro;
case 'mastercard':
return Mastercard;
case 'visa':
return Visa;
default:
return null;
}
};
type CardTypeIconProps = React.FC<{
cardNumber: string;
className?: string;
}>;
export const CardTypeIcon = styled<CardTypeIconProps>(({ cardNumber, className }) => {
const Icon = getIconInstance(cardNumber);
return Icon ? <Icon className={className} /> : null;
})`
position: absolute;
top: 15px;
right: 15px;
width: 31px;
height: 19px;
animation: ${growth} 0.5s;
background: #fff;
`;

View File

@ -1,7 +1,9 @@
import * as React from 'react';
import { ChevronLeft, ChevronRight } from 'checkout/components';
import { styled, css } from 'styled-components';
import { ReactComponent as ChevronLeftIcon } from '../icon/chevron-left.svg';
import { ReactComponent as ChevronRightIcon } from '../icon/chevron-right.svg';
const Button = styled.button<{ disabled?: boolean }>`
border: none;
background: none;
@ -37,6 +39,6 @@ export type ChevronButtonProps = {
export const ChevronButton: React.FC<ChevronButtonProps> = ({ id, onClick, type, disabled }) => (
<Button aria-disabled={disabled} id={id} onClick={onClick} disabled={disabled}>
{type === 'left' && <ChevronLeft />} {type === 'right' && <ChevronRight />}
{type === 'left' && <ChevronLeftIcon />} {type === 'right' && <ChevronRightIcon />}
</Button>
);

View File

@ -1,9 +0,0 @@
<svg width="17" height="17" xmlns="http://www.w3.org/2000/svg">
<path
id="icon"
d="M8.5 7.3l-6-6-1.2 1.2 6 6-6 6 1.2 1.2 6-6 6 6 1.2-1.2-6-6 6-6-1.2-1.2z"
stroke="#e75542"
fill-rule="nonzero"
fill="#e75542"
/>
</svg>

Before

Width:  |  Height:  |  Size: 265 B

View File

@ -1,11 +0,0 @@
export { default as Mastercard } from './mastercard.svg';
export { default as Visa } from './visa.svg';
export { default as Mir } from './mir.svg';
export { default as Maestro } from './maestro.svg';
export { default as AmericanExpress } from './american-express.svg';
export { default as DinersClub } from './diners-club.svg';
export { default as Discover } from './discover.svg';
export { default as Elo } from './elo.svg';
export { default as Hipercard } from './hipercard.svg';
export { default as Unionpay } from './unionpay.svg';
export { default as Jcb } from './jcb.svg';

View File

@ -1,8 +0,0 @@
<svg viewBox="0 0 18 18" width="18" height="18" xmlns="http://www.w3.org/2000/svg">
<path
id="icon"
d="M9 7.59L1.93.5.5 1.93 7.6 9 .5 16.07l1.42 1.42L9 10.4l7.07 7.08 1.42-1.42L10.4 9l7.08-7.07L16.07.5 9 7.6z"
fill="#FFF"
fill-rule="evenodd"
/>
</svg>

Before

Width:  |  Height:  |  Size: 292 B

View File

@ -1,14 +0,0 @@
export { default as Amount } from './amount.svg';
export { default as BoldCross } from './bold-cross.svg';
export { default as Calendar } from './calendar.svg';
export { default as Card } from './card.svg';
export { default as Checkmark } from './checkmark.svg';
export { default as ChevronLeft } from './chevron-left.svg';
export { default as ChevronRight } from './chevron-right.svg';
export { default as Cross } from './cross.svg';
export { default as Letter } from './letter.svg';
export { default as Lock } from './lock.svg';
export { default as Phone } from './phone.svg';
export { default as User } from './user.svg';
export { default as Bank } from './bank.svg';
export * from './card';

View File

@ -1,7 +0,0 @@
<svg width="19" height="18" xmlns="http://www.w3.org/2000/svg">
<g id="icon" fill="none" fill-rule="evenodd">
<path fill="#FFF" d="M.5 0h18v18H.5z" />
<path d="M2 4l6.3 5a2 2 0 0 0 2.4 0L17 4" stroke="#181818" />
<rect stroke="#181818" stroke-width="2" x="2" y="4" width="15" height="10" rx="2" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 342 B

View File

@ -1,11 +0,0 @@
<svg width="18" height="18" xmlns="http://www.w3.org/2000/svg">
<g id="icon" fill="none" fill-rule="evenodd">
<path fill="#FFF" d="M0 0h18v18H0z" />
<path
d="M14 4v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h6a2 2 0 0 1 2 2z"
stroke="#181818"
stroke-width="2"
/>
<path fill="#181818" d="M7 11h4v1H7z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 397 B

View File

@ -1,7 +1,6 @@
export * from './list';
export * from './link';
export * from './loader';
export * from './icon';
export * from './round-icon';
export * from './input';
export * from './button';

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import { motion } from 'framer-motion';
import styled, { css } from 'styled-components';
import { Checkmark } from 'checkout/components/ui/icon';
import { ReactComponent as Checkmark } from '../icon/checkmark.svg';
const fadeIn = {
hidden: { opacity: 0 },

View File

@ -1,32 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Checkout</title>
</head>
<body>
<script>
function inIframe() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
parent.window.postMessage('finish-interaction', '*');
if (!inIframe()) {
try {
window.close();
} catch (e) {
console.error(e);
}
}
</script>
</body>
</html>

View File

@ -1,5 +1,4 @@
import { domReady } from './dom-ready';
import { HtmlIntegration } from './html-integration';
import { PopupInitializer } from './popup-initializer';
import { environment, Configurator } from '../environment';
@ -8,15 +7,5 @@ const init = (origin: string): Configurator => ({
});
domReady().then((origin) => {
const ValityCheckout = (environment.ValityCheckout = init(origin));
const htmlIntegration = new HtmlIntegration(origin);
if (htmlIntegration.isAvailable) {
const userConfig = htmlIntegration.getUserConfig();
const checkout = ValityCheckout.configure(userConfig);
const payButton = htmlIntegration.renderPayButton(userConfig.label);
payButton.onclick = (e: Event) => {
e.preventDefault();
checkout.open();
};
}
environment.ValityCheckout = init(origin);
});

5
types/svg.d.ts vendored
View File

@ -1,4 +1 @@
declare module '*.svg' {
const value: React.FC<React.SVGProps<SVGSVGElement>>;
export default value;
}
/// <reference types="vite-plugin-svgr/client" />

51
vite.config.app.ts Normal file
View File

@ -0,0 +1,51 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
base: './',
build: {
outDir: 'dist/v1',
rollupOptions: {
input: {
app: './checkout.html'
}
}
},
plugins: [
react(),
svgr(),
tsconfigPaths(),
viteStaticCopy({
targets: [
{
src: 'src/appConfig.json',
dest: './'
},
{
src: 'src/env.json',
dest: './'
},
{
src: 'src/assets/*',
dest: './assets'
},
{
src: 'src/locale/*.json',
dest: './locale'
}
]
})
],
server: {
port: 7050,
proxy: {
'^/v1': {
target: 'http://localhost:7050',
rewrite: (path) => path.replace(/^\/v1/, '')
}
}
}
});

16
vite.config.checkout.ts Normal file
View File

@ -0,0 +1,16 @@
import { defineConfig } from 'vite';
export default defineConfig({
build: {
outDir: 'dist',
lib: {
entry: './src/initializer/index.ts',
name: 'checkout'
},
rollupOptions: {
output: {
entryFileNames: 'checkout.js'
}
}
}
});

3
vite.config.preview.ts Normal file
View File

@ -0,0 +1,3 @@
export default {
root: './dist'
};