Commit ad06a479 by xuzhenzhao

feat(custom): toolkit

payment
test units
lib add d.ts
parent 6a9ba37f
import { Utils } from '../src/Utils/Utils'
import {PayError, Payment, PayType} from '../src/Payment/Payment'
const payment = new Payment()
const MOCK_GOODS = {
totalAmount: 100,
orderId: 1
}
Utils.setCookie('uid', '130959612')
Utils.setCookie('accessToken', '33441f9c4be74a357b1d416d4aa616eaMjIwNw')
test('test: getBalance', async () => {
const balance = await payment.getBalance()
expect(balance).toBeGreaterThanOrEqual(0)
})
// test('test: computeAmount', () => {
// const {payAmount, payBalance} = payment.computeAmount(100)
// expect(payBalance).toBe(payment.balance)
// })
test('test: 余额支付', async () => {
const res = await payment.toPay({
totalAmount: MOCK_GOODS.totalAmount,
orderId: MOCK_GOODS.orderId,
payType: PayType.BALANCE,
quitUrl: 'https://www.baidu.com',
returnUrl: 'https://www.baidu.com',
redirectUrl: 'https://www.baidu.com'
})
if (res) {
const {errorType, success} = res
expect(errorType === PayError.VALIDATE)
}
})
// test('test: 微信支付')
// test('test: 支付宝支付')
// test('test: 微信 + 余额支付')
// test('test: 支付宝 + 余额支付')
// test('test: createBackInfoUrl')
// test('test: 订单查询')
// test('test: getPayMethodList')
// test('test: getPayChannel')
\ No newline at end of file
import {beforeAll, describe, expect, test} from '@jest/globals'
import {Utils} from '@/Utils/Utils'
import {PayError, Payment, PayType} from '@/Payment/Payment'
import {defaultRequest, DefaultResponse} from "@/Request/Request";
import {ACCESS_TOKEN, UID} from "@/Const";
const globalDatabase: any = {
/**
* 1块钱商品
* https://testnewm.ydl.com/consult/#/pages/jieyou/DownOrder?product_id=88220606058062&uid=130959612&accessToken=33441f9c4be74a357b1d416d4aa616eaMjIwNw&ffrom=m
*/
MOCK_GOODS: {
productId: 88220606058062,
productSpecs: [
{
standardProductSpecId: 255539,
amount: 1
}
],
type: 1,
totalPrice: 1
}
}
const createOrder = async ():Promise<{orderId: number, title: string, payId: number, money: number}> => {
const res = await defaultRequest.post<any, DefaultResponse>('https://testapi.ydl.com/api/consult/user/order/submitWorriesConsultOrder', globalDatabase.MOCK_GOODS)
return res.data
}
beforeAll(async () => {
//
/**
* 测试账号:15706780002 ydl123456
* 请保证账户余额为1.9元
*/
Utils.setCookie(UID, '130959612')
Utils.setCookie(ACCESS_TOKEN, '33441f9c4be74a357b1d416d4aa616eaMjIwNw')
globalDatabase.payment = new Payment()
})
describe('测试用余额购买1块钱商品', () => {
test('test:获取账户余额', async () => {
const balance = await globalDatabase.payment.getBalance()
expect(balance).toBeGreaterThanOrEqual(1)
})
test('test: 测试余额支付', async () => {
const {orderId, money} = await createOrder()
const res = await globalDatabase.payment.toPay({
totalAmount: money,
payType: PayType.BALANCE,
orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(true)
})
})
describe('测试用0.9元余额 + 0.1元支付宝金额支付', () => {
test('test:获取账户余额', async () => {
const balance = await globalDatabase.payment.getBalance()
expect(balance).toBe(0.9)
})
test('test: 使用余额+支付宝支付', async () => {
const {orderId, money} = await createOrder()
const res = await globalDatabase.payment.toPay({
totalAmount: money,
payType: PayType.ALIPAY_BALANCE,
orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(false)
expect(res.errorType).toBe(PayError.ALIPAY_H5_BREAK)
})
})
describe('测试用0.9元余额 + 0.1元微信金额支付', () => {
test('test:获取账户余额', async () => {
const balance = await globalDatabase.payment.getBalance()
expect(balance).toBe(0.9)
})
test('test: 使用余额+微信支付', async () => {
const {orderId, money} = await createOrder()
const res = await globalDatabase.payment.toPay({
totalAmount: money,
payType: PayType.WECHAT_BALANCE,
orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(false)
expect(res.errorType).toBe(PayError.WECHAT_H5_BREAK)
})
})
import {beforeAll, describe, expect, test} from '@jest/globals'
import {Utils} from '@/Utils/Utils'
import {PayError, Payment, PayType} from '@/Payment/Payment'
import {defaultRequest, DefaultResponse} from "@/Request/Request";
import {ACCESS_TOKEN, UID} from "@/Const";
const globalDatabase: any = {
/**
* 1块钱商品
* https://testnewm.ydl.com/consult/#/pages/jieyou/DownOrder?product_id=88220606058062&uid=130959612&accessToken=33441f9c4be74a357b1d416d4aa616eaMjIwNw&ffrom=m
*/
MOCK_GOODS: {
productId: 88220606058062,
productSpecs: [
{
standardProductSpecId: 255539,
amount: 1
}
],
type: 1,
totalPrice: 1
}
}
const createOrder = async (): Promise<{ orderId: number, title: string, payId: number, money: number }> => {
const res = await defaultRequest.post<any, DefaultResponse>('https://testapi.ydl.com/api/consult/user/order/submitWorriesConsultOrder', globalDatabase.MOCK_GOODS)
return res.data
}
beforeAll(async () => {
//
/**
* 测试账号:15706780002 ydl123456
* 请保证账户余额为0元
*/
Utils.setCookie(UID, '130959612')
Utils.setCookie(ACCESS_TOKEN, '33441f9c4be74a357b1d416d4aa616eaMjIwNw')
globalDatabase.payment = new Payment()
})
describe('测试无余额支付情况', () => {
test('test:获取账户余额', async () => {
const balance = await globalDatabase.payment.getBalance()
expect(balance).toBe(0)
})
test('test: 测试余额支付', async () => {
const res = await globalDatabase.payment.toPay({
totalAmount: 1,
payType: PayType.BALANCE,
orderId: globalDatabase.MOCK_GOODS.orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(false)
expect(res.errorMessage).toBe('余额不足')
})
})
describe('测试无余额使用支付宝支付', () => {
test('test: 使用支付宝支付', async () => {
const {orderId, money} = await createOrder()
const res = await globalDatabase.payment.toPay({
totalAmount: money,
payType: PayType.ALIPAY,
orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(false)
expect(res.errorType).toBe(PayError.ALIPAY_H5_BREAK)
})
})
describe('测试无余额使用微信支付', () => {
test('test: 使用微信支付', async () => {
const {orderId, money} = await createOrder()
const res = await globalDatabase.payment.toPay({
totalAmount: money,
payType: PayType.WECHAT_BALANCE,
orderId,
redirectUrl: window.encodeURIComponent('https://www.baidu.com'),
returnUrl: 'https://www.baidu.com',
quitUrl: 'https://www.baidu.com'
})
expect(res.success).toBe(false)
expect(res.errorType).toBe(PayError.WECHAT_H5_BREAK)
})
})
\ No newline at end of file
import {describe, expect, test} from '@jest/globals'
import {BACK_ORDER_ID, BACK_PAY_ID, PayChannel, PayError, PayErrorMessage, Payment, PayType} from "@/Payment/Payment";
describe('测试: 创建实例', () => {
test('payChannels', () => {
const payment = new Payment({
payChannels: [PayChannel.WX_MWEB, PayChannel.WX_JSAPI]
})
expect(payment.limitPayChannels).toEqual([PayChannel.WX_MWEB, PayChannel.WX_JSAPI])
})
test('no params', () => {
const payment = new Payment()
expect(payment.limitPayChannels).toEqual(Object.keys(PayChannel).map(key => key))
})
})
test('测试订单查询链接', () => {
const testPayId = 111
const testOrderId = 222
const backUrl = Payment.createBackInfoUrl(window.location.href, testPayId, testOrderId)
expect(backUrl).toContain(BACK_PAY_ID)
expect(backUrl).toContain(BACK_ORDER_ID)
expect(backUrl).toContain(testPayId.toString())
expect(backUrl).toContain(testOrderId.toString())
expect(backUrl).toContain(window.location.origin)
})
test('测试价格计算', () => {
const payment = new Payment()
const goodsPrice = 0.3
const balance = 0.1
const {payAmount, payBalance} = payment.computeAmount(goodsPrice, balance)
expect(payAmount).toBe(0.2)
expect(payBalance).toBe(0.1)
})
describe('测试支付入参校验', () => {
const othersParams = {
orderId: 111111111111,
totalAmount: 100,
}
test('ali payType', async () => {
const payment = new Payment({
payChannels: [PayChannel.WX_JSAPI, PayChannel.WX_JSAPI]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.ALIPAY
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.ALIPAY_PAY_CHANNEL_MISSING)
})
test('wechat patType', async () => {
const payment = new Payment({
payChannels: [PayChannel.ALI_WAP]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.WECHAT
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.WECHAT_PAY_CHANNEL_MISSING)
})
test('wechat redirect missing', async () => {
const payment = new Payment({
payChannels: [PayChannel.WX_MWEB, PayChannel.WX_JSAPI]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.WECHAT
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.WECHAT_REDIRECT_URL_MISSING)
})
test('wechat redirect encode', async () => {
const payment = new Payment({
payChannels: [PayChannel.WX_MWEB, PayChannel.WX_JSAPI]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.WECHAT,
redirectUrl: 'https://m.ydl.com'
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.WECHAT_REDIRECT_URL_ENCODE)
})
test('alipay quitUrl missing', async () => {
const payment = new Payment({
payChannels: [PayChannel.ALI_WAP]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.ALIPAY
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.ALIPAY_QUIT_URL_MISSING)
})
test('alipay returnUrl missing', async () => {
const payment = new Payment({
payChannels: [PayChannel.ALI_WAP]
})
const {errorMessage, errorType, success} = await payment.toPay({
...othersParams,
payType: PayType.ALIPAY,
quitUrl: 'https://m.ydl.com'
})
expect(success).toBe(false)
expect(errorType).toBe(PayError.VALIDATE)
expect(errorMessage).toBe(PayErrorMessage.ALIPAY_RETURN_URL_MISSING)
})
})
test('测试微信浏览器支付方式', () => {
const payment = new Payment()
const methods = payment.getPayMethodList(100)
expect(methods.length).toBe(1)
expect(methods[0].value).toBe(PayType.WECHAT)
})
......@@ -2,5 +2,11 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleFileExtensions: ['ts', 'tsx', 'js', 'json']
testEnvironmentOptions: {
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.3 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1 wechatdevtools/1.06.2208010 MicroMessenger/8.0.5 Language/zh_CN webview/16601963014137226 webdebugger port/60125 token/0e6423f01c6f63d782b58ad418b07059'
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
\ No newline at end of file
......@@ -2,46 +2,53 @@
"name": "@ydl-packages/toolkit",
"version": "1.0.1-next.2",
"description": "",
"main": "./dist/index.umd.js",
"main": "./dist/index.mjs",
"scripts": {
"lib": "npx vite build"
"lib": "npx vite build",
"test": "npx jest __tests__"
},
"keywords": [],
"author": "",
"keywords": [
"pay",
"toolkit",
"utils"
],
"author": "xuzhenzhao",
"license": "ISC",
"type": "module",
"files": [
"dist"
],
"module": "./dist/index.js",
"module": "./dist/index.mjs",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.umd.cjs"
"import": "./dist/index.mjs",
"require": "./dist/index.umd.js"
}
},
"types": "'./dist/index.d.ts",
"dependencies": {
"@types/consola": "^2.2.5",
"axios": "^0.27.2",
"blueimp-md5": "^2.19.0",
"consola": "^2.15.3",
"js-cookie": "^3.0.1",
"mathjs": "^11.0.1",
"qs": "^6.11.0",
"regenerator-runtime": "^0.13.9",
"ts-jest": "^28.0.7",
"@types/jest": "^28.1.6"
"regenerator-runtime": "^0.13.9"
},
"devDependencies": {
"@jest/globals": "^28.1.3",
"@types/consola": "^2.2.5",
"@types/jest": "^28.1.6",
"ts-jest": "^28.0.7",
"vite-plugin-dts": "^1.4.1",
"@types/blueimp-md5": "^2.18.0",
"@types/js-cookie": "^3.0.2",
"@types/node": "^18.6.2",
"@types/qs": "^6.9.7",
"typedoc": "^0.23.9",
"typedoc-theme-hierarchy": "^3.0.0",
"typescript": "^4.7.4",
"jest": "^28.1.3",
"jest-environment-jsdom": "^28.1.3",
"ts-node": "^10.9.1"
"ts-node": "^10.9.1",
"typedoc": "^0.23.9",
"typedoc-theme-hierarchy": "^3.0.0",
"typescript": "^4.7.4"
}
}
......@@ -15,7 +15,11 @@ export type BackInfo = {
}
export type OrderStateCallBack = (params: BackInfo & { isPay: boolean }) => void
export const enum PayType {
export type PaymentParams = {
payChannels?: PayChannel[]
}
export enum PayType {
/**
* 余额支付
*/
......@@ -55,7 +59,10 @@ export const enum PayType {
}
export const enum PayChannel {
/**
* 余额支付方式默认支持, 无需声明
*/
export enum PayChannel {
WX_MWEB = 'WX_MWEB',
WX_JSAPI = 'WX_JSAPI',
WX_NATIVE = 'WX_NATIVE',
......@@ -75,30 +82,46 @@ export type ToPayParams = {
* 支付宝h5支付失败回调地址
* doc: https://opendocs.alipay.com/open/203/105285#%E9%87%8D%E8%A6%81%E5%85%A5%E5%8F%82%E8%AF%B4%E6%98%8E_3
*/
quitUrl: string;
quitUrl?: string;
/**
* 支付宝h5支付成功回调地址
* doc: https://opendocs.alipay.com/open/203/105285#%E9%87%8D%E8%A6%81%E5%85%A5%E5%8F%82%E8%AF%B4%E6%98%8E_3
*/
returnUrl: string;
returnUrl?: string;
/**
* 微信h5支付回调地址
* doc: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/combine/chapter10_1.shtml
*/
redirectUrl: string
redirectUrl?: string
}
export enum PayError {
WECHAT_JSSDK = "WECHAT_JSSDK",
BALANCE = 'BALANCE',
VALIDATE = 'VALIDATE',
BACKEND = 'BACKEND'
BACKEND = 'BACKEND',
WECHAT_H5_BREAK = 'WECHAT_H5_BREAK',
ALIPAY_H5_BREAK = 'ALIPAY_H5_BREAK',
UNKNOWN = 'UNKNOWN'
}
export enum PayErrorMessage {
BALANCE_EMPTY = '余额不足',
WECHAT_REDIRECT_URL_MISSING= `请填写微信回调地址页面 'redirectUrl`,
WECHAT_REDIRECT_URL_ENCODE = 'redirectUrl需要encode',
WECHAT_PAY_CHANNEL_MISSING =`缺少持的渠道参数:'WX_MWEB','WX_JSAPI'`,
ALIPAY_QUIT_URL_MISSING = `缺少支付失败回调地址:'quitUrl'`,
ALIPAY_RETURN_URL_MISSING = `缺少支付成功回调地址:'returnUrl'`,
ALIPAY_PAY_CHANNEL_MISSING = `缺少持的渠道参数:'ALI_WAP'`,
WECHAT_JSSDK_PAY_ERROR = '微信JSSDK支付失败',
WECHAT_H5_PAY_BREAK = '微信h5支付中断',
ALIPAY_H5_PAY_BREAK = '支付宝支付中断'
}
export type ToPayReturns = {
errorMessage?: string
errorMessage?: PayErrorMessage
errorType: PayError
success: boolean
redirectUrl?: string
}
export interface DoUnifiedParams extends Omit<ToPayParams, 'totalAmount' | 'redirectUrl'> {
......
import { DO_UNIFIED_ORDER, MY_BALANCE, IS_PAY } from "./API";
import {DO_UNIFIED_ORDER, IS_PAY, MY_BALANCE} from "./API";
import md5 from 'blueimp-md5'
import qs from 'qs'
import { Utils } from "../Utils/Utils";
import { bignumber, subtract } from 'mathjs'
import { createRequest, defaultRequest } from "../Request/Request";
import { BackInfo, BACK_ORDER_ID, BACK_PAY_ID, DoUnifiedParams, FULL_PAY_METHODS, OrderStateCallBack, PayChannel, PayError, PayMethod, PayType, ToPayParams, ToPayReturns, WechatPayParams } from "./Defined";
import { ACCESS_TOKEN, UID } from "../Const";
import {Utils} from "@/Utils/Utils";
import {bignumber, subtract} from 'mathjs'
import {createRequest, defaultRequest, DefaultResponse} from "@/Request/Request";
import {
BACK_ORDER_ID,
BACK_PAY_ID,
BackInfo,
DoUnifiedParams,
FULL_PAY_METHODS,
OrderStateCallBack,
PayChannel,
PayError,
PayErrorMessage,
PaymentParams,
PayMethod,
PayType,
ToPayParams,
ToPayReturns,
WechatPayParams
} from "./Defined";
import {ACCESS_TOKEN, UID} from "@/Const";
export * from './Defined'
const SESSION_KEY = 'dc59cf294f37d237c1f06240568ffe21'
const createRequestForPhp = () => {
const comp = (a: string, b: string): number => {
if (a > b) {
return -1;
} else if (a == b) return 0;
else return 1;
}
const genSign = (data: Record<string, any>): string => {
let keyArr: string[] = [];
for (let i in data) {
keyArr.push(i);
const comp = (a: string, b: string): number => {
if (a > b) {
return -1;
} else if (a == b) return 0;
else return 1;
}
keyArr.sort(comp);
const tempArr: string[] = [];
for (let i in keyArr) {
tempArr.push(keyArr[i] + "=" + data[keyArr[i]]);
const genSign = (data: Record<string, any>): string => {
let keyArr: string[] = [];
for (let i in data) {
keyArr.push(i);
}
keyArr.sort(comp);
const tempArr: string[] = [];
for (let i in keyArr) {
tempArr.push(keyArr[i] + "=" + data[keyArr[i]]);
}
return md5(tempArr.join("&") + SESSION_KEY);
}
return md5(tempArr.join("&") + SESSION_KEY);
}
const request = createRequest()
const request = createRequest()
request.interceptors.request.use((config) => {
const requestData = {
...config.data,
ts: parseInt((Date.now() / 1000).toString()).toString(),
[UID]: Utils.getCookie(UID),
[ACCESS_TOKEN]: Utils.getCookie(ACCESS_TOKEN)
}
return {
...config,
transformRequest: [function (data: any, headers: any) {
return qs.stringify(requestData)
}],
headers: {
'content-type': 'application/x-www-form-urlencoded',
Authorization: `Ydl ${genSign(requestData)}`,
[UID]: Utils.getCookie(UID),
[ACCESS_TOKEN]: Utils.getCookie(ACCESS_TOKEN)
}
}
})
return request
request.interceptors.request.use((config) => {
const requestData = {
...config.data,
ts: parseInt((Date.now() / 1000).toString()).toString(),
[UID]: Utils.getCookie(UID),
[ACCESS_TOKEN]: Utils.getCookie(ACCESS_TOKEN)
}
return {
...config,
transformRequest: [function (data: any, headers: any) {
return qs.stringify(requestData)
}],
headers: {
'content-type': 'application/x-www-form-urlencoded',
Authorization: `Ydl ${genSign(requestData)}`,
[UID]: Utils.getCookie(UID),
[ACCESS_TOKEN]: Utils.getCookie(ACCESS_TOKEN)
}
}
})
return request
}
const requestForPhp = createRequestForPhp()
......@@ -63,197 +80,260 @@ const requestForPhp = createRequestForPhp()
const requestForJava = defaultRequest
export class Payment {
balance = 0;
constructor() {
this.getBalance()
}
balance = 0;
limitPayChannels: PayChannel[] = []
public async getBalance(): Promise<number> {
try {
const { data: res } = await requestForPhp.post(MY_BALANCE, { balance: 1 })
if (res.data && res.data.balance) {
this.balance = Number(res.data.balance)
}
return this.balance
} catch (err) {
console.log(err)
return 0
constructor(paymentParams?: PaymentParams) {
this.limitPayChannels = paymentParams?.payChannels ?? Object.keys(PayChannel).map(key => key) as PayChannel[]
}
}
public getPayMethodList(totalAmount: number): PayMethod[] {
return FULL_PAY_METHODS.filter(({ value }) => {
switch (value) {
case PayType.BALANCE:
return this.balance > 0
case PayType.WECHAT:
return this.balance === 0
case PayType.WECHAT_BALANCE:
return this.balance > 0 && this.balance < totalAmount
case PayType.ALIPAY:
return this.balance === 0 && !Utils.isWechat()
case PayType.ALIPAY_BALANCE:
return this.balance > 0 && this.balance < totalAmount && !Utils.isWechat()
case PayType.HUABEI:
return this.balance === 0 && !Utils.isWechat()
case PayType.HUABEI_BALANCE:
return this.balance > 0 && this.balance < totalAmount && !Utils.isWechat()
}
return true
}).map(item => {
const { payBalance } = this.computeAmount(totalAmount)
switch (item.value) {
case PayType.BALANCE:
return {
...item,
label: `余额支付(¥${payBalance})`,
disabled: this.balance > 0 && this.balance < totalAmount
}
}
return item
})
}
public async getBalance(): Promise<number> {
try {
const {data: res} = await requestForPhp.post(MY_BALANCE, {balance: 1})
if (res.data && res.data.balance) {
this.balance = Number(res.data.balance)
}
return this.balance
} catch (err) {
return 0
}
}
computeAmount(totalAmount: number): { payAmount: number, payBalance: number } {
let payBalance = 0, payAmount = 0
if (this.balance === 0) {
payAmount = totalAmount
} else if (this.balance > 0 && this.balance < totalAmount) {
payBalance = this.balance
payAmount = subtract(bignumber(totalAmount), bignumber(this.balance)).toNumber()
} else {
payBalance = totalAmount
public getPayMethodList(totalAmount: number): PayMethod[] {
return FULL_PAY_METHODS.filter(({value}) => {
switch (value) {
case PayType.BALANCE:
return this.balance > 0
case PayType.WECHAT:
return this.balance === 0
case PayType.WECHAT_BALANCE:
return this.balance > 0 && this.balance < totalAmount
case PayType.ALIPAY:
return this.balance === 0 && !Utils.isWechat()
case PayType.ALIPAY_BALANCE:
return this.balance > 0 && this.balance < totalAmount && !Utils.isWechat()
case PayType.HUABEI:
return this.balance === 0 && !Utils.isWechat()
case PayType.HUABEI_BALANCE:
return this.balance > 0 && this.balance < totalAmount && !Utils.isWechat()
}
return true
}).map(item => {
const {payBalance} = this.computeAmount(totalAmount, this.balance)
switch (item.value) {
case PayType.BALANCE:
return {
...item,
label: `余额支付(¥${payBalance})`,
disabled: this.balance > 0 && this.balance < totalAmount
}
}
return item
})
}
return { payAmount, payBalance }
}
async toPay(params: ToPayParams): Promise<ToPayReturns | void> {
const { totalAmount, payType, returnUrl, orderId, redirectUrl } = params
let quitUrl = params.quitUrl
// validate
switch (payType) {
case PayType.BALANCE:
if (this.balance < totalAmount) {
return { errorMessage: '余额不足', success: false, errorType: PayError.VALIDATE }
computeAmount(totalAmount: number, balance: number): { payAmount: number, payBalance: number } {
let payBalance = 0, payAmount = 0
if (balance === 0) {
payAmount = totalAmount
} else if (balance > 0 && balance < totalAmount) {
payBalance = balance
payAmount = subtract(bignumber(totalAmount), bignumber(balance)).toNumber()
} else {
payBalance = totalAmount
}
return {payAmount, payBalance}
}
if (!redirectUrl) {
return { errorMessage: '请填写微信回调地址页面', success: false, errorType: PayError.VALIDATE }
}
if (decodeURIComponent(redirectUrl) === redirectUrl) {
return { errorMessage: 'redirectUrl需要encode', success: false, errorType: PayError.VALIDATE }
}
// hack, 后端微信redirectUrl用的quitUrl
const payChannel = this.getPayChannel(payType)
if (payChannel === PayChannel.WX_MWEB || payChannel === PayChannel.WX_JSAPI) {
quitUrl = redirectUrl
}
const doUnifiedParams: DoUnifiedParams = {
returnUrl,
quitUrl,
orderId,
payType,
...this.computeAmount(totalAmount),
}
if (payChannel !== null) {
doUnifiedParams.payChannel = payChannel
}
const { data: res } = await requestForJava.post(DO_UNIFIED_ORDER, doUnifiedParams)
if (res.code !== '200') return { errorMessage: res.msg, success: false, errorType: PayError.BACKEND }
if (params.payType === PayType.BALANCE && res.data.balancePayResult) {
return { success: res.data.balancePayResult === 'true', errorType: PayError.BALANCE }
} else if (payChannel === PayChannel.WX_JSAPI) {
const isPaySucc = await this.wechatPayJSSDK(res.data)
return { errorMessage: isPaySucc ? '' : '微信支付失败', success: isPaySucc, errorType: PayError.WECHAT_JSSDK }
} else if (payChannel === PayChannel.WX_MWEB) {
window.location.replace(res.data.content)
} else if (payChannel === PayChannel.ALI_WAP) {
window.location.replace(res.data.content)
}
}
getPayChannel(payType: PayType): PayChannel | null {
switch (payType) {
case PayType.WECHAT_BALANCE:
case PayType.WECHAT:
return Utils.isWechat() ? PayChannel.WX_JSAPI : PayChannel.WX_MWEB
case PayType.ALIPAY:
case PayType.ALIPAY_BALANCE:
case PayType.HUABEI:
case PayType.HUABEI_BALANCE:
case PayType.HUABEI_STAGE:
case PayType.HUABEI_STAGE_BALANCE:
return PayChannel.ALI_WAP
async toPay(params: ToPayParams): Promise<ToPayReturns> {
const {totalAmount, payType, returnUrl, orderId, redirectUrl} = params
let quitUrl = params.quitUrl
// validate start >>>
switch (payType) {
case PayType.BALANCE:
if (this.balance < totalAmount) {
return {errorMessage: PayErrorMessage.BALANCE_EMPTY, success: false, errorType: PayError.VALIDATE}
}
break
case PayType.WECHAT_BALANCE:
case PayType.WECHAT:
if (this.limitPayChannels.includes(PayChannel.WX_MWEB) && this.limitPayChannels.includes(PayChannel.WX_JSAPI)) {
if (!redirectUrl) {
return {
errorMessage: PayErrorMessage.WECHAT_REDIRECT_URL_MISSING,
success: false,
errorType: PayError.VALIDATE
}
} else if (decodeURIComponent(redirectUrl) === redirectUrl) {
return {
errorMessage: PayErrorMessage.WECHAT_REDIRECT_URL_ENCODE,
success: false,
errorType: PayError.VALIDATE
}
}
} else {
return {
errorMessage: PayErrorMessage.WECHAT_PAY_CHANNEL_MISSING,
success: false,
errorType: PayError.VALIDATE
}
}
break
case PayType.ALIPAY:
case PayType.ALIPAY_BALANCE:
case PayType.HUABEI:
case PayType.HUABEI_BALANCE:
case PayType.HUABEI_STAGE:
case PayType.HUABEI_STAGE_BALANCE:
if (this.limitPayChannels.includes(PayChannel.ALI_WAP)) {
if (!quitUrl) {
return {
errorMessage: PayErrorMessage.ALIPAY_QUIT_URL_MISSING,
success: false,
errorType: PayError.VALIDATE
}
} else if (!returnUrl) {
return {
errorMessage: PayErrorMessage.ALIPAY_RETURN_URL_MISSING,
success: false,
errorType: PayError.VALIDATE
}
}
} else {
return {
errorMessage: PayErrorMessage.ALIPAY_PAY_CHANNEL_MISSING,
success: false,
errorType: PayError.VALIDATE
}
}
break
}
// validate end <<<
// hack, 后端微信redirectUrl用的quitUrl
const payChannel = this.getPayChannel(payType)
if (payChannel === PayChannel.WX_MWEB || payChannel === PayChannel.WX_JSAPI) {
quitUrl = redirectUrl
}
const doUnifiedParams: DoUnifiedParams = {
returnUrl,
quitUrl,
orderId,
payType,
...this.computeAmount(totalAmount, this.balance),
}
if (payChannel !== null) {
doUnifiedParams.payChannel = payChannel
}
const res = await requestForJava.post<DoUnifiedParams, DefaultResponse>(DO_UNIFIED_ORDER, doUnifiedParams)
if (res.code !== '200') return {errorMessage: res.msg as any, success: false, errorType: PayError.BACKEND}
if (params.payType === PayType.BALANCE && res.data.balancePayResult) {
return {success: res.data.balancePayResult === 'true', errorType: PayError.BALANCE}
} else if (payChannel === PayChannel.WX_JSAPI) {
const isPaySucc = await this.wechatPayJSSDK(res.data)
return {
errorMessage: isPaySucc ? undefined : PayErrorMessage.WECHAT_JSSDK_PAY_ERROR,
success: isPaySucc,
errorType: PayError.WECHAT_JSSDK
}
} else if (payChannel === PayChannel.WX_MWEB) {
return {
redirectUrl: res.data.content,
success: false,
errorType: PayError.WECHAT_H5_BREAK,
errorMessage: PayErrorMessage.WECHAT_H5_PAY_BREAK
}
} else if (payChannel === PayChannel.ALI_WAP) {
return {
redirectUrl: res.data.content,
success: false,
errorType: PayError.ALIPAY_H5_BREAK,
errorMessage: PayErrorMessage.ALIPAY_H5_PAY_BREAK
}
}
return {success: false, errorType: PayError.UNKNOWN}
}
return null
}
wechatPayJSSDK(wechatPayParams: WechatPayParams): Promise<boolean> {
const { appId, timeStamp, nonceStr, signType, paySign, package: packageAlias } = wechatPayParams
return new Promise((resolve) => {
window.WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: appId, //公众号名称,由商户传入
timeStamp: timeStamp, //时间戳,自1970年以来的秒数
nonceStr: nonceStr, //随机串
package: packageAlias,
signType: signType, //微信签名方式:
paySign: paySign //微信签名
},
(res: any) => {
if (res.err_msg === "get_brand_wcpay_request:ok") {
resolve(true)
} else {
resolve(false)
console.error(res)
}
getPayChannel(payType: PayType): PayChannel | null {
switch (payType) {
case PayType.WECHAT_BALANCE:
case PayType.WECHAT:
return Utils.isWechat() ? PayChannel.WX_JSAPI : PayChannel.WX_MWEB
case PayType.ALIPAY:
case PayType.ALIPAY_BALANCE:
case PayType.HUABEI:
case PayType.HUABEI_BALANCE:
case PayType.HUABEI_STAGE:
case PayType.HUABEI_STAGE_BALANCE:
return PayChannel.ALI_WAP
}
);
})
}
static async loopValidateOrderState(count = 0, callBack: OrderStateCallBack): Promise<void> {
const [, queryString] = window.location.href.split('?')
const query = queryString ? qs.parse(queryString, { ignoreQueryPrefix: true }) : {}
const returnParams: BackInfo = { payId: Number(query[BACK_PAY_ID]), orderId: Number(query[BACK_ORDER_ID]) }
const checkLoop = () => {
if (--count > 0) {
setTimeout(() => {
this.loopValidateOrderState(count, callBack)
}, 1000)
} else {
callBack({ isPay: false, ...returnParams })
}
return null
}
if (query[BACK_PAY_ID]) {
try {
const { data: res } = await requestForJava.post(IS_PAY, {
payId: query[BACK_PAY_ID]
wechatPayJSSDK(wechatPayParams: WechatPayParams): Promise<boolean> {
const {appId, timeStamp, nonceStr, signType, paySign, package: packageAlias} = wechatPayParams
return new Promise((resolve) => {
window.WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: appId, //公众号名称,由商户传入
timeStamp: timeStamp, //时间戳,自1970年以来的秒数
nonceStr: nonceStr, //随机串
package: packageAlias,
signType: signType, //微信签名方式:
paySign: paySign //微信签名
},
(res: any) => {
if (res.err_msg === "get_brand_wcpay_request:ok") {
resolve(true)
} else {
resolve(false)
console.error(res)
}
}
);
})
if (res.code === '200' && res.data === true) {
callBack({ isPay: true, ...returnParams })
} else {
checkLoop()
}
static async loopValidateOrderState(count = 0, callBack: OrderStateCallBack): Promise<void> {
const [, queryString] = window.location.href.split('?')
const query = queryString ? qs.parse(queryString, {ignoreQueryPrefix: true}) : {}
const returnParams: BackInfo = {payId: Number(query[BACK_PAY_ID]), orderId: Number(query[BACK_ORDER_ID])}
const checkLoop = () => {
if (--count > 0) {
setTimeout(() => {
this.loopValidateOrderState(count, callBack)
}, 1000)
} else {
callBack({isPay: false, ...returnParams})
}
}
if (query[BACK_PAY_ID]) {
try {
const res = await requestForJava.post<Record<string, string>, DefaultResponse>(IS_PAY, {
payId: query[BACK_PAY_ID]
})
if (res.code === '200' && res.data === true) {
callBack({isPay: true, ...returnParams})
} else {
checkLoop()
}
} catch (err) {
checkLoop()
}
}
} catch (err) {
checkLoop()
}
}
}
/**
* 创建订单查询页面链接, 返回的url不做encode处理
* @param url
* @param backPayId
* @param backOrderId
*/
static createBackInfoUrl(url: string, backPayId: number, backOrderId: number): string {
const [path, queryString] = url.split('?')
const query = queryString ? qs.parse(queryString, { ignoreQueryPrefix: true }) : {}
query[BACK_PAY_ID] = backPayId.toString()
query[BACK_ORDER_ID] = backOrderId.toString()
return `${path}?${qs.stringify(query)}`
}
/**
* 创建订单查询页面链接, 返回的url不做encode处理
* @param url
* @param backPayId
* @param backOrderId
*/
static createBackInfoUrl(url: string, backPayId: number, backOrderId: number): string {
const [path, queryString] = url.split('?')
const query = queryString ? qs.parse(queryString, {ignoreQueryPrefix: true}) : {}
query[BACK_PAY_ID] = backPayId.toString()
query[BACK_ORDER_ID] = backOrderId.toString()
return `${path}?${qs.stringify(query)}`
}
}
import axios, { Axios, AxiosRequestConfig } from 'axios'
import { ACCESS_TOKEN, UID } from '../Const'
import { Utils } from '../Utils/Utils'
import axios, {Axios, AxiosRequestConfig} from 'axios'
import {ACCESS_TOKEN, UID} from '../Const'
import {Utils} from '../Utils/Utils'
export const createRequest = axios.create
......@@ -14,4 +14,13 @@ defaultRequest.interceptors.request.use((config) => {
},
}
})
export { defaultRequest }
\ No newline at end of file
defaultRequest.interceptors.response.use((response) => {
return response.data
}, err => Promise.reject(err))
export {defaultRequest}
export type DefaultResponse = {
code: string
data: any
msg: string
}
\ No newline at end of file
......@@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es2015", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
......@@ -46,7 +46,7 @@
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
......
import path from 'path'
import { defineConfig } from 'vite'
import {defineConfig} from 'vite'
import dts from 'vite-plugin-dts'
export default defineConfig(() => {
return {
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
},
build: {
target: "es2015",
lib: {
entry: path.resolve(__dirname, 'src/index'),
name: 'toolkit',
......@@ -13,6 +21,7 @@ export default defineConfig(() => {
sourcemap: 'inline'
},
outDir: path.resolve(__dirname, 'dist')
}
},
plugins: [dts()]
}
})
\ No newline at end of file
......@@ -17,6 +17,7 @@ importers:
packages/toolkit:
specifiers:
'@jest/globals': ^28.1.3
'@types/blueimp-md5': ^2.18.0
'@types/consola': ^2.2.5
'@types/jest': ^28.1.6
......@@ -37,7 +38,9 @@ importers:
typedoc: ^0.23.9
typedoc-theme-hierarchy: ^3.0.0
typescript: ^4.7.4
vite-plugin-dts: ^1.4.1
dependencies:
'@jest/globals': 28.1.3
'@types/consola': 2.2.5
'@types/jest': 28.1.6
axios: 0.27.2
......@@ -48,6 +51,7 @@ importers:
qs: 6.11.0
regenerator-runtime: 0.13.9
ts-jest: 28.0.7_bi2kohzqnxavgozw3csgny5hju
vite-plugin-dts: 1.4.1
devDependencies:
'@types/blueimp-md5': 2.18.0
'@types/js-cookie': 3.0.2
......@@ -830,18 +834,55 @@ packages:
read-yaml-file: 1.1.0
dev: true
/@microsoft/api-extractor-model/7.23.0:
resolution: {integrity: sha512-h+2aVyf8IYidPZp+N+yIc/LY/aBwRZ1Vxlsx7rU31807bba5ScJ94bj7OjsPMje0vRYALf+yjZToYT0HdP6omA==}
dependencies:
'@microsoft/tsdoc': 0.14.1
'@microsoft/tsdoc-config': 0.16.1
'@rushstack/node-core-library': 3.50.1
dev: false
/@microsoft/api-extractor/7.29.2:
resolution: {integrity: sha512-MwT/Xi1DperfrBO+SU3f/xKdyR6bMvk59/WN6w7g1rHmDBMegan3Ya6npMo+abJAgQOtp6uExY/elHXcYE/Ofw==}
hasBin: true
dependencies:
'@microsoft/api-extractor-model': 7.23.0
'@microsoft/tsdoc': 0.14.1
'@microsoft/tsdoc-config': 0.16.1
'@rushstack/node-core-library': 3.50.1
'@rushstack/rig-package': 0.3.14
'@rushstack/ts-command-line': 4.12.2
colors: 1.2.5
lodash: 4.17.21
resolve: 1.17.0
semver: 7.3.7
source-map: 0.6.1
typescript: 4.7.4
dev: false
/@microsoft/tsdoc-config/0.16.1:
resolution: {integrity: sha512-2RqkwiD4uN6MLnHFljqBlZIXlt/SaUT6cuogU1w2ARw4nKuuppSmR0+s+NC+7kXBQykd9zzu0P4HtBpZT5zBpQ==}
dependencies:
'@microsoft/tsdoc': 0.14.1
ajv: 6.12.6
jju: 1.4.0
resolve: 1.19.0
dev: false
/@microsoft/tsdoc/0.14.1:
resolution: {integrity: sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw==}
dev: false
/@nodelib/fs.scandir/2.1.5:
resolution: {integrity: sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=}
engines: {node: '>= 8'}
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
dev: true
/@nodelib/fs.stat/2.0.5:
resolution: {integrity: sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos=}
engines: {node: '>= 8'}
dev: true
/@nodelib/fs.walk/1.2.8:
resolution: {integrity: sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po=}
......@@ -849,7 +890,36 @@ packages:
dependencies:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.13.0
dev: true
/@rushstack/node-core-library/3.50.1:
resolution: {integrity: sha512-9d2xE7E9yQEBS6brTptdP8cslt6iL5+UnkY2lRxQQ4Q/jlXtsrWCCJCxwr56W/eJEe9YT/yHR4mMn5QY64Ps2w==}
dependencies:
'@types/node': 12.20.24
colors: 1.2.5
fs-extra: 7.0.1
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.17.0
semver: 7.3.7
timsort: 0.3.0
z-schema: 5.0.3
dev: false
/@rushstack/rig-package/0.3.14:
resolution: {integrity: sha512-Ic9EN3kWJCK6iOxEDtwED9nrM146zCDrQaUxbeGOF+q/VLZ/HNHPw+aLqrqmTl0ZT66Sf75Qk6OG+rySjTorvQ==}
dependencies:
resolve: 1.17.0
strip-json-comments: 3.1.1
dev: false
/@rushstack/ts-command-line/4.12.2:
resolution: {integrity: sha512-poBtnumLuWmwmhCEkVAgynWgtnF9Kygekxyp4qtQUSbBrkuyPQTL85c8Cva1YfoUpOdOXxezMAkUt0n5SNKGqw==}
dependencies:
'@types/argparse': 1.0.38
argparse: 1.0.10
colors: 1.2.5
string-argv: 0.3.1
dev: false
/@sinclair/typebox/0.24.27:
resolution: {integrity: sha512-K7C7IlQ3zLePEZleUN21ceBA2aLcMnLHTLph8QWk1JK37L90obdpY+QGY8bXMKxf1ht1Z0MNewvXxWv0oGDYFg==}
......@@ -869,6 +939,15 @@ packages:
engines: {node: '>= 10'}
dev: true
/@ts-morph/common/0.13.0:
resolution: {integrity: sha512-fEJ6j7Cu8yiWjA4UmybOBH9Efgb/64ZTWuvCF4KysGu4xz8ettfyaqFt8WZ1btCxXsGZJjZ2/3svOF6rL+UFdQ==}
dependencies:
fast-glob: 3.2.11
minimatch: 5.1.0
mkdirp: 1.0.4
path-browserify: 1.0.1
dev: false
/@tsconfig/node10/1.0.9:
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
......@@ -881,6 +960,10 @@ packages:
/@tsconfig/node16/1.0.3:
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
/@types/argparse/1.0.38:
resolution: {integrity: sha1-qB/YYG1IH4c6OADG665PHXaKVqk=}
dev: false
/@types/babel__core/7.1.19:
resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==}
dependencies:
......@@ -964,6 +1047,10 @@ packages:
resolution: {integrity: sha1-7nceK6Sz3Fs3KTXVSf2WF780W4w=}
dev: true
/@types/node/12.20.24:
resolution: {integrity: sha1-w3rGnLKUivtM75X0JPoAN5camlw=}
dev: false
/@types/node/12.20.55:
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
dev: true
......@@ -1045,6 +1132,15 @@ packages:
- supports-color
dev: true
/ajv/6.12.6:
resolution: {integrity: sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=}
dependencies:
fast-deep-equal: 3.1.3
fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.4.1
uri-js: 4.4.1
dev: false
/ansi-colors/4.1.3:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
......@@ -1226,7 +1322,6 @@ packages:
resolution: {integrity: sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4=}
dependencies:
balanced-match: 1.0.2
dev: true
/braces/3.0.2:
resolution: {integrity: sha1-NFThpGLujVmeI23zNs2epPiv4Qc=}
......@@ -1376,6 +1471,10 @@ packages:
resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
/code-block-writer/11.0.3:
resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==}
dev: false
/collect-v8-coverage/1.0.1:
resolution: {integrity: sha1-zCyOlPwYu9/+ZNZTRXDIpnOyf1k=}
......@@ -1396,12 +1495,23 @@ packages:
/color-name/1.1.4:
resolution: {integrity: sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=}
/colors/1.2.5:
resolution: {integrity: sha1-icetmjdLwDDfgBMkH2gTbtiDWvw=}
engines: {node: '>=0.1.90'}
dev: false
/combined-stream/1.0.8:
resolution: {integrity: sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=}
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: 1.0.0
/commander/2.20.3:
resolution: {integrity: sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=}
requiresBuild: true
dev: false
optional: true
/complex.js/2.1.1:
resolution: {integrity: sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==}
dev: false
......@@ -1946,6 +2056,10 @@ packages:
tmp: 0.0.33
dev: true
/fast-deep-equal/3.1.3:
resolution: {integrity: sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=}
dev: false
/fast-glob/3.2.11:
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
engines: {node: '>=8.6.0'}
......@@ -1955,7 +2069,6 @@ packages:
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.5
dev: true
/fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=}
......@@ -1968,7 +2081,6 @@ packages:
resolution: {integrity: sha1-YWdg+Ip1Jr38WWt8q4wYk4w2uYw=}
dependencies:
reusify: 1.0.4
dev: true
/fb-watchman/2.0.1:
resolution: {integrity: sha1-/IT7OdJwnPP/bXQ3BhV7tXCKioU=}
......@@ -2046,7 +2158,6 @@ packages:
graceful-fs: 4.2.10
jsonfile: 6.1.0
universalify: 2.0.0
dev: true
/fs-extra/7.0.1:
resolution: {integrity: sha1-TxicRKoSO4lfcigE9V6iPq3DSOk=}
......@@ -2055,7 +2166,6 @@ packages:
graceful-fs: 4.2.10
jsonfile: 4.0.0
universalify: 0.1.2
dev: true
/fs-extra/8.1.0:
resolution: {integrity: sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA=}
......@@ -2129,7 +2239,6 @@ packages:
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
dev: true
/glob/7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
......@@ -2270,6 +2379,11 @@ packages:
engines: {node: '>= 4'}
dev: true
/import-lazy/4.0.0:
resolution: {integrity: sha1-6OtidIOgpD2jwD8+NVSL5csMwVM=}
engines: {node: '>=8'}
dev: false
/import-local/3.1.0:
resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==}
engines: {node: '>=8'}
......@@ -2370,7 +2484,6 @@ packages:
/is-extglob/2.1.1:
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
engines: {node: '>=0.10.0'}
dev: true
/is-fullwidth-code-point/3.0.0:
resolution: {integrity: sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=}
......@@ -2385,7 +2498,6 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
dev: true
/is-interactive/1.0.0:
resolution: {integrity: sha1-zqbmrlyHCnsKAAQHC3tYfgJSkS4=}
......@@ -2920,6 +3032,10 @@ packages:
- supports-color
- ts-node
/jju/1.4.0:
resolution: {integrity: sha1-o6vicYryQaKykE+EpiWXDzia4yo=}
dev: false
/js-cookie/3.0.1:
resolution: {integrity: sha1-njm0xsL1ZWNwjX0x9vXyGHOpJBQ=}
engines: {node: '>=12'}
......@@ -2985,6 +3101,10 @@ packages:
/json-parse-even-better-errors/2.3.1:
resolution: {integrity: sha1-fEeAWpQxmSjgV3dAXcEuH3pO4C0=}
/json-schema-traverse/0.4.1:
resolution: {integrity: sha1-afaofZUTq4u4/mO9sJecRI5oRmA=}
dev: false
/json5/2.2.1:
resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
engines: {node: '>=6'}
......@@ -2998,7 +3118,6 @@ packages:
resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=}
optionalDependencies:
graceful-fs: 4.2.10
dev: true
/jsonfile/6.1.0:
resolution: {integrity: sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4=}
......@@ -3006,7 +3125,6 @@ packages:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.10
dev: true
/kind-of/6.0.3:
resolution: {integrity: sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=}
......@@ -3060,6 +3178,14 @@ packages:
p-locate: 5.0.0
dev: true
/lodash.get/4.4.2:
resolution: {integrity: sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=}
dev: false
/lodash.isequal/4.5.0:
resolution: {integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA=}
dev: false
/lodash.memoize/4.1.2:
resolution: {integrity: sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=}
dev: false
......@@ -3070,7 +3196,6 @@ packages:
/lodash/4.17.21:
resolution: {integrity: sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=}
dev: true
/log-symbols/4.1.0:
resolution: {integrity: sha1-P727lbRoOsn8eFER55LlWNSr1QM=}
......@@ -3166,7 +3291,6 @@ packages:
/merge2/1.4.1:
resolution: {integrity: sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=}
engines: {node: '>= 8'}
dev: true
/micromatch/4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
......@@ -3204,7 +3328,6 @@ packages:
engines: {node: '>=10'}
dependencies:
brace-expansion: 2.0.1
dev: true
/minimist-options/4.1.0:
resolution: {integrity: sha1-wGVXE8U6ii69d/+iR9NCxA8BBhk=}
......@@ -3231,6 +3354,12 @@ packages:
minimist: 1.2.6
dev: true
/mkdirp/1.0.4:
resolution: {integrity: sha1-PrXtYmInVteaXw4qIh3+utdcL34=}
engines: {node: '>=10'}
hasBin: true
dev: false
/ms/2.1.2:
resolution: {integrity: sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=}
......@@ -3400,6 +3529,10 @@ packages:
resolution: {integrity: sha1-4aHAhcVps9wIMhGE8Zo5zCf3wws=}
dev: true
/path-browserify/1.0.1:
resolution: {integrity: sha1-2YRUqcN1PVeQhg8W9ohnueRr4f0=}
dev: false
/path-exists/4.0.0:
resolution: {integrity: sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=}
engines: {node: '>=8'}
......@@ -3505,7 +3638,6 @@ packages:
/punycode/2.1.1:
resolution: {integrity: sha1-tYsBCsQMIsVldhbI0sLALHv0eew=}
engines: {node: '>=6'}
dev: true
/qs/6.11.0:
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
......@@ -3516,7 +3648,6 @@ packages:
/queue-microtask/1.2.3:
resolution: {integrity: sha1-SSkii7xyTfrEPg77BYyve2z7YkM=}
dev: true
/quick-lru/4.0.1:
resolution: {integrity: sha1-W4h48ROlgheEjGSCAmxz4bpXcn8=}
......@@ -3606,6 +3737,19 @@ packages:
resolution: {integrity: sha1-XOhCuUsFFGwOAwdphdHQ5+SMkMk=}
engines: {node: '>=10'}
/resolve/1.17.0:
resolution: {integrity: sha1-sllBtUloIxzC0bt2p5y38sC/hEQ=}
dependencies:
path-parse: 1.0.7
dev: false
/resolve/1.19.0:
resolution: {integrity: sha1-GvW/YwQJc0oGfK4pMYqsf6KaJnw=}
dependencies:
is-core-module: 2.10.0
path-parse: 1.0.7
dev: false
/resolve/1.22.1:
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
hasBin: true
......@@ -3625,7 +3769,6 @@ packages:
/reusify/1.0.4:
resolution: {integrity: sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: true
/rimraf/2.6.3:
resolution: {integrity: sha1-stEE/g2Psnz54KHNqCYt04M8bKs=}
......@@ -3657,7 +3800,6 @@ packages:
resolution: {integrity: sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4=}
dependencies:
queue-microtask: 1.2.3
dev: true
/rxjs/7.5.6:
resolution: {integrity: sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==}
......@@ -3826,6 +3968,11 @@ packages:
mixme: 0.5.4
dev: true
/string-argv/0.3.1:
resolution: {integrity: sha1-leL77AQnrhkYSTX4FtdKqkxcGdo=}
engines: {node: '>=0.6.19'}
dev: false
/string-length/4.0.2:
resolution: {integrity: sha1-qKjce9XBqCubPIuH4SX2aHG25Xo=}
engines: {node: '>=10'}
......@@ -3958,6 +4105,10 @@ packages:
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
dev: true
/timsort/0.3.0:
resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=}
dev: false
/tiny-emitter/2.1.0:
resolution: {integrity: sha1-HRpW7fxRxD6GPLtTgqcjMONVVCM=}
dev: false
......@@ -4036,6 +4187,13 @@ packages:
yargs-parser: 21.1.1
dev: false
/ts-morph/14.0.0:
resolution: {integrity: sha512-tO8YQ1dP41fw8GVmeQAdNsD8roZi1JMqB7YwZrqU856DvmG5/710e41q2XauzTYrygH9XmMryaFeLo+kdCziyA==}
dependencies:
'@ts-morph/common': 0.13.0
code-block-writer: 11.0.3
dev: false
/ts-node/10.9.1_cvilj4l3ytrlnvtlqw3tscihve:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
......@@ -4159,12 +4317,10 @@ packages:
/universalify/0.1.2:
resolution: {integrity: sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=}
engines: {node: '>= 4.0.0'}
dev: true
/universalify/2.0.0:
resolution: {integrity: sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc=}
engines: {node: '>= 10.0.0'}
dev: true
/update-browserslist-db/1.0.5_browserslist@4.21.3:
resolution: {integrity: sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==}
......@@ -4176,6 +4332,12 @@ packages:
escalade: 3.1.1
picocolors: 1.0.0
/uri-js/4.4.1:
resolution: {integrity: sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=}
dependencies:
punycode: 2.1.1
dev: false
/user-home/2.0.0:
resolution: {integrity: sha1-nHC/2Babwdy/SGBODwS4tJzenp8=}
engines: {node: '>=0.10.0'}
......@@ -4205,6 +4367,28 @@ packages:
spdx-expression-parse: 3.0.1
dev: true
/validator/13.7.0:
resolution: {integrity: sha1-T5ZYuhO6jz2C7ogdNRZInqhcCFc=}
engines: {node: '>= 0.10'}
dev: false
/vite-plugin-dts/1.4.1:
resolution: {integrity: sha512-jo7E4ZeheD2o48oGiI3EygPbej7ZkGFHg3GVTt7Wuo6NgzThLvuzGGuduaFpnhJOGi1piDFsu6oui/wDKIIORQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
vite: '>=2.4.4'
dependencies:
'@microsoft/api-extractor': 7.29.2
'@rushstack/node-core-library': 3.50.1
chalk: 4.1.2
debug: 4.3.4
fast-glob: 3.2.11
fs-extra: 10.1.0
ts-morph: 14.0.0
transitivePeerDependencies:
- supports-color
dev: false
/vite/3.0.5:
resolution: {integrity: sha512-bRvrt9Tw8EGW4jj64aYFTnVg134E8hgDxyl/eEHnxiGqYk7/pTPss6CWlurqPOUzqvEoZkZ58Ws+Iu8MB87iMA==}
engines: {node: ^14.18.0 || >=16.0.0}
......@@ -4450,3 +4634,15 @@ packages:
/yocto-queue/0.1.0:
resolution: {integrity: sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=}
engines: {node: '>=10'}
/z-schema/5.0.3:
resolution: {integrity: sha512-sGvEcBOTNum68x9jCpCVGPFJ6mWnkD0YxOcddDlJHRx3tKdB2q8pCHExMVZo/AV/6geuVJXG7hljDaWG8+5GDw==}
engines: {node: '>=8.0.0'}
hasBin: true
dependencies:
lodash.get: 4.4.2
lodash.isequal: 4.5.0
validator: 13.7.0
optionalDependencies:
commander: 2.20.3
dev: false
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment