fixing withdrawal process
This commit is contained in:
parent
78fb5f79a8
commit
be8e3f4b1d
@ -19,7 +19,7 @@ import { NiceSelect } from "./styled/index";
|
|||||||
import { h } from "preact";
|
import { h } from "preact";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value: string;
|
value?: string;
|
||||||
onChange: (s: string) => void;
|
onChange: (s: string) => void;
|
||||||
label: string;
|
label: string;
|
||||||
list: {
|
list: {
|
||||||
@ -41,9 +41,11 @@ export function SelectList({ name, value, list, canBeNull, onChange, label, desc
|
|||||||
console.log(e.currentTarget.value, value)
|
console.log(e.currentTarget.value, value)
|
||||||
onChange(e.currentTarget.value)
|
onChange(e.currentTarget.value)
|
||||||
}}>
|
}}>
|
||||||
<option selected>
|
{value !== undefined ? <option selected>
|
||||||
{list[value]}
|
{list[value]}
|
||||||
</option>
|
</option> : <option selected disabled>
|
||||||
|
Select one option
|
||||||
|
</option>}
|
||||||
{Object.keys(list)
|
{Object.keys(list)
|
||||||
.filter((l) => l !== value)
|
.filter((l) => l !== value)
|
||||||
.map(key => <option value={key} key={key}>{list[key]}</option>)
|
.map(key => <option value={key} key={key}>{list[key]}</option>)
|
||||||
|
@ -129,6 +129,12 @@ export const WalletBox = styled.div<{ noPadding?: boolean }>`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
export const Middle = styled.div`
|
||||||
|
justify-content: space-around;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
`
|
||||||
|
|
||||||
export const PopupBox = styled.div<{ noPadding?: boolean }>`
|
export const PopupBox = styled.div<{ noPadding?: boolean }>`
|
||||||
height: 290px;
|
height: 290px;
|
||||||
@ -138,11 +144,10 @@ export const PopupBox = styled.div<{ noPadding?: boolean }>`
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
& > section {
|
& > section {
|
||||||
padding-left: ${({ noPadding }) => noPadding ? '0px' : '8px'};
|
padding: ${({ noPadding }) => noPadding ? '0px' : '8px'};
|
||||||
padding-right: ${({ noPadding }) => noPadding ? '0px' : '8px'};
|
|
||||||
// this margin will send the section up when used with a header
|
// this margin will send the section up when used with a header
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
overflow: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
table td {
|
table td {
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
@ -153,6 +158,16 @@ export const PopupBox = styled.div<{ noPadding?: boolean }>`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > section[data-expanded] {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > section[data-centered] {
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
/* flex-direction: column; */
|
||||||
|
}
|
||||||
|
|
||||||
& > header {
|
& > header {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -596,7 +611,7 @@ export const NiceSelect = styled.div`
|
|||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 10em;
|
/* width: 10em; */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: .25em;
|
border-radius: .25em;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ export function PayPage({ talerPayUri }: Props): JSX.Element {
|
|||||||
const [payErrMsg, setPayErrMsg] = useState<string | undefined>(undefined);
|
const [payErrMsg, setPayErrMsg] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const balance = useBalances()
|
const balance = useBalances()
|
||||||
const balanceWithoutError = balance?.error ? [] : (balance?.response.balances || [])
|
const balanceWithoutError = balance?.hasError ? [] : (balance?.response.balances || [])
|
||||||
|
|
||||||
const foundBalance = balanceWithoutError.find(b => payStatus && Amounts.parseOrThrow(b.available).currency === Amounts.parseOrThrow(payStatus?.amountRaw).currency)
|
const foundBalance = balanceWithoutError.find(b => payStatus && Amounts.parseOrThrow(b.available).currency === Amounts.parseOrThrow(payStatus?.amountRaw).currency)
|
||||||
const foundAmount = foundBalance ? Amounts.parseOrThrow(foundBalance.available) : undefined
|
const foundAmount = foundBalance ? Amounts.parseOrThrow(foundBalance.available) : undefined
|
||||||
@ -143,17 +143,21 @@ export function PayPage({ talerPayUri }: Props): JSX.Element {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <PaymentRequestView uri={talerPayUri} payStatus={payStatus} onClick={onClick} payErrMsg={payErrMsg} balance={foundAmount} />;
|
return <PaymentRequestView uri={talerPayUri}
|
||||||
|
payStatus={payStatus} payResult={payResult}
|
||||||
|
onClick={onClick} payErrMsg={payErrMsg}
|
||||||
|
balance={foundAmount} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaymentRequestViewProps {
|
export interface PaymentRequestViewProps {
|
||||||
payStatus: PreparePayResult;
|
payStatus: PreparePayResult;
|
||||||
|
payResult?: ConfirmPayResult;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
payErrMsg?: string;
|
payErrMsg?: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
balance: AmountJson | undefined;
|
balance: AmountJson | undefined;
|
||||||
}
|
}
|
||||||
export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance }: PaymentRequestViewProps) {
|
export function PaymentRequestView({ uri, payStatus, payResult, onClick, payErrMsg, balance }: PaymentRequestViewProps) {
|
||||||
let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
|
let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
|
||||||
const contractTerms: ContractTerms = payStatus.contractTerms;
|
const contractTerms: ContractTerms = payStatus.contractTerms;
|
||||||
|
|
||||||
@ -195,6 +199,16 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ButtonsSection() {
|
function ButtonsSection() {
|
||||||
|
if (payResult) {
|
||||||
|
if (payResult.type === ConfirmPayResultType.Pending) {
|
||||||
|
return <section>
|
||||||
|
<div>
|
||||||
|
<p>Processing...</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
if (payErrMsg) {
|
if (payErrMsg) {
|
||||||
return <section>
|
return <section>
|
||||||
<div>
|
<div>
|
||||||
@ -208,7 +222,7 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
|
|||||||
if (payStatus.status === PreparePayResultType.PaymentPossible) {
|
if (payStatus.status === PreparePayResultType.PaymentPossible) {
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess upperCased>
|
<ButtonSuccess upperCased onClick={onClick}>
|
||||||
{i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
|
{i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
|
||||||
</ButtonSuccess>
|
</ButtonSuccess>
|
||||||
</section>
|
</section>
|
||||||
@ -252,6 +266,15 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
|
|||||||
{payStatus.status === PreparePayResultType.AlreadyConfirmed &&
|
{payStatus.status === PreparePayResultType.AlreadyConfirmed &&
|
||||||
(payStatus.paid ? <SuccessBox> Already paid </SuccessBox> : <WarningBox> Already claimed </WarningBox>)
|
(payStatus.paid ? <SuccessBox> Already paid </SuccessBox> : <WarningBox> Already claimed </WarningBox>)
|
||||||
}
|
}
|
||||||
|
{payResult && payResult.type === ConfirmPayResultType.Done && (
|
||||||
|
<SuccessBox>
|
||||||
|
<h3>Payment complete</h3>
|
||||||
|
<p>{!payResult.contractTerms.fulfillment_message ?
|
||||||
|
"You will now be sent back to the merchant you came from." :
|
||||||
|
payResult.contractTerms.fulfillment_message
|
||||||
|
}</p>
|
||||||
|
</SuccessBox>
|
||||||
|
)}
|
||||||
<section>
|
<section>
|
||||||
{payStatus.status !== PreparePayResultType.InsufficientBalance && Amounts.isNonZero(totalFees) &&
|
{payStatus.status !== PreparePayResultType.InsufficientBalance && Amounts.isNonZero(totalFees) &&
|
||||||
<Part big title="Total to pay" text={amountToString(payStatus.amountEffective)} kind='negative' />
|
<Part big title="Total to pay" text={amountToString(payStatus.amountEffective)} kind='negative' />
|
||||||
|
@ -31,6 +31,7 @@ export default {
|
|||||||
title: 'cta/withdraw',
|
title: 'cta/withdraw',
|
||||||
component: TestedComponent,
|
component: TestedComponent,
|
||||||
argTypes: {
|
argTypes: {
|
||||||
|
onSwitchExchange: { action: 'onRetry' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -381,6 +382,15 @@ const termsXml = `<?xml version="1.0" encoding="utf-8"?>
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const WithdrawNewTermsXML = createExample(TestedComponent, {
|
export const WithdrawNewTermsXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -391,9 +401,15 @@ export const WithdrawNewTermsXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
@ -402,6 +418,15 @@ export const WithdrawNewTermsXML = createExample(TestedComponent, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
|
export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -412,9 +437,15 @@ export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
@ -424,6 +455,15 @@ export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
|
export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -434,9 +474,14 @@ export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
@ -446,6 +491,15 @@ export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponent, {
|
export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -456,9 +510,15 @@ export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponen
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
@ -469,6 +529,15 @@ export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponen
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawChangedTermsXML = createExample(TestedComponent, {
|
export const WithdrawChangedTermsXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -479,9 +548,15 @@ export const WithdrawChangedTermsXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
@ -490,6 +565,15 @@ export const WithdrawChangedTermsXML = createExample(TestedComponent, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawNotFoundTermsXML = createExample(TestedComponent, {
|
export const WithdrawNotFoundTermsXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -500,13 +584,28 @@ export const WithdrawNotFoundTermsXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
status: 'notfound'
|
status: 'notfound'
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
|
export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -517,7 +616,13 @@ export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
status: 'accepted'
|
status: 'accepted'
|
||||||
},
|
},
|
||||||
@ -525,6 +630,15 @@ export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
|
|||||||
|
|
||||||
|
|
||||||
export const WithdrawAcceptedTermsWithoutFee = createExample(TestedComponent, {
|
export const WithdrawAcceptedTermsWithoutFee = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.demo.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
},{
|
||||||
|
currency: 'USD',
|
||||||
|
exchangeBaseUrl: 'exchange.test.taler.net',
|
||||||
|
paytoUris: ['asd'],
|
||||||
|
}],
|
||||||
details: {
|
details: {
|
||||||
exchangeInfo: {
|
exchangeInfo: {
|
||||||
baseUrl: 'exchange.demo.taler.net'
|
baseUrl: 'exchange.demo.taler.net'
|
||||||
@ -535,9 +649,15 @@ export const WithdrawAcceptedTermsWithoutFee = createExample(TestedComponent, {
|
|||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
} as ExchangeWithdrawDetails,
|
} as ExchangeWithdrawDetails,
|
||||||
amount: 'USD:2',
|
amount: {
|
||||||
|
currency: 'USD',
|
||||||
|
value: 2,
|
||||||
|
fraction: 10000000
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwitchExchange: async () => { },
|
||||||
terms: {
|
terms: {
|
||||||
value : {
|
value: {
|
||||||
type: 'xml',
|
type: 'xml',
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
|
@ -21,18 +21,21 @@
|
|||||||
* @author Florian Dold
|
* @author Florian Dold
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AmountLike, Amounts, i18n, WithdrawUriInfoResponse } from '@gnu-taler/taler-util';
|
import { AmountJson, Amounts, ExchangeListItem, i18n, WithdrawUriInfoResponse } from '@gnu-taler/taler-util';
|
||||||
import { ExchangeWithdrawDetails } from '@gnu-taler/taler-wallet-core/src/operations/withdraw';
|
import { ExchangeWithdrawDetails } from '@gnu-taler/taler-wallet-core/src/operations/withdraw';
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
|
import { Fragment } from 'preact/jsx-runtime';
|
||||||
import { CheckboxOutlined } from '../components/CheckboxOutlined';
|
import { CheckboxOutlined } from '../components/CheckboxOutlined';
|
||||||
import { ExchangeXmlTos } from '../components/ExchangeToS';
|
import { ExchangeXmlTos } from '../components/ExchangeToS';
|
||||||
import { LogoHeader } from '../components/LogoHeader';
|
import { LogoHeader } from '../components/LogoHeader';
|
||||||
import { Part } from '../components/Part';
|
import { Part } from '../components/Part';
|
||||||
import { ButtonDestructive, ButtonSuccess, ButtonWarning, LinkSuccess, LinkWarning, TermsOfService, WalletAction } from '../components/styled';
|
import { SelectList } from '../components/SelectList';
|
||||||
|
import { ButtonSuccess, ButtonWarning, LinkSuccess, LinkWarning, TermsOfService, WalletAction } from '../components/styled';
|
||||||
|
import { useAsyncAsHook } from '../hooks/useAsyncAsHook';
|
||||||
import {
|
import {
|
||||||
acceptWithdrawal, getExchangeWithdrawalInfo, getWithdrawalDetailsForUri, onUpdateNotification, setExchangeTosAccepted
|
acceptWithdrawal, getExchangeWithdrawalInfo, getWithdrawalDetailsForUri, setExchangeTosAccepted, listExchanges
|
||||||
} from "../wxApi";
|
} from "../wxApi";
|
||||||
import { h } from 'preact';
|
import { wxMain } from '../wxBackend.js';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerWithdrawUri?: string;
|
talerWithdrawUri?: string;
|
||||||
@ -40,7 +43,8 @@ interface Props {
|
|||||||
|
|
||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
details: ExchangeWithdrawDetails;
|
details: ExchangeWithdrawDetails;
|
||||||
amount: string;
|
amount: AmountJson;
|
||||||
|
onSwitchExchange: (ex: string) => void;
|
||||||
onWithdraw: () => Promise<void>;
|
onWithdraw: () => Promise<void>;
|
||||||
onReview: (b: boolean) => void;
|
onReview: (b: boolean) => void;
|
||||||
onAccept: (b: boolean) => void;
|
onAccept: (b: boolean) => void;
|
||||||
@ -50,7 +54,8 @@ export interface ViewProps {
|
|||||||
terms: {
|
terms: {
|
||||||
value?: TermsDocument;
|
value?: TermsDocument;
|
||||||
status: TermsStatus;
|
status: TermsStatus;
|
||||||
}
|
},
|
||||||
|
knownExchanges: ExchangeListItem[]
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,15 +73,18 @@ interface TermsDocumentHtml {
|
|||||||
href: string,
|
href: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
function amountToString(text: AmountLike) {
|
function amountToString(text: AmountJson) {
|
||||||
const aj = Amounts.jsonifyAmount(text)
|
const aj = Amounts.jsonifyAmount(text)
|
||||||
const amount = Amounts.stringifyValue(aj)
|
const amount = Amounts.stringifyValue(aj)
|
||||||
return `${amount} ${aj.currency}`
|
return `${amount} ${aj.currency}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function View({ details, amount, onWithdraw, terms, reviewing, onReview, onAccept, accepted, confirmed }: ViewProps) {
|
export function View({ details, knownExchanges, amount, onWithdraw, onSwitchExchange, terms, reviewing, onReview, onAccept, accepted, confirmed }: ViewProps) {
|
||||||
const needsReview = terms.status === 'changed' || terms.status === 'new'
|
const needsReview = terms.status === 'changed' || terms.status === 'new'
|
||||||
|
|
||||||
|
const [switchingExchange, setSwitchingExchange] = useState<string | undefined>(undefined)
|
||||||
|
const exchanges = knownExchanges.reduce((prev, ex) => ({ ...prev, [ex.exchangeBaseUrl]: ex.exchangeBaseUrl }), {})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WalletAction>
|
<WalletAction>
|
||||||
<LogoHeader />
|
<LogoHeader />
|
||||||
@ -84,7 +92,7 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
|
|||||||
{i18n.str`Digital cash withdrawal`}
|
{i18n.str`Digital cash withdrawal`}
|
||||||
</h2>
|
</h2>
|
||||||
<section>
|
<section>
|
||||||
<Part title="Total to withdraw" text={amountToString(Amounts.sub(Amounts.parseOrThrow(amount), details.withdrawFee).amount)} kind='positive' />
|
<Part title="Total to withdraw" text={amountToString(Amounts.sub(amount, details.withdrawFee).amount)} kind='positive' />
|
||||||
<Part title="Chosen amount" text={amountToString(amount)} kind='neutral' />
|
<Part title="Chosen amount" text={amountToString(amount)} kind='neutral' />
|
||||||
{Amounts.isNonZero(details.withdrawFee) &&
|
{Amounts.isNonZero(details.withdrawFee) &&
|
||||||
<Part title="Exchange fee" text={amountToString(details.withdrawFee)} kind='negative' />
|
<Part title="Exchange fee" text={amountToString(details.withdrawFee)} kind='negative' />
|
||||||
@ -93,11 +101,21 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
|
|||||||
</section>
|
</section>
|
||||||
{!reviewing &&
|
{!reviewing &&
|
||||||
<section>
|
<section>
|
||||||
<LinkSuccess
|
{switchingExchange !== undefined ? <Fragment>
|
||||||
upperCased
|
<div>
|
||||||
>
|
<SelectList label="Known exchanges" list={exchanges} name="" onChange={onSwitchExchange} />
|
||||||
{i18n.str`Edit exchange`}
|
</div>
|
||||||
|
<p>
|
||||||
|
This is the list of known exchanges
|
||||||
|
</p>
|
||||||
|
<LinkSuccess upperCased onClick={() => onSwitchExchange(switchingExchange)}>
|
||||||
|
{i18n.str`Confirm exchange selection`}
|
||||||
</LinkSuccess>
|
</LinkSuccess>
|
||||||
|
</Fragment>
|
||||||
|
: <LinkSuccess upperCased onClick={() => setSwitchingExchange("")}>
|
||||||
|
{i18n.str`Switch exchange`}
|
||||||
|
</LinkSuccess>}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
{!reviewing && accepted &&
|
{!reviewing && accepted &&
|
||||||
@ -140,6 +158,9 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
|
|||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{/**
|
||||||
|
* Main action section
|
||||||
|
*/}
|
||||||
<section>
|
<section>
|
||||||
{terms.status === 'new' && !accepted && !reviewing &&
|
{terms.status === 'new' && !accepted && !reviewing &&
|
||||||
<ButtonSuccess
|
<ButtonSuccess
|
||||||
@ -178,80 +199,55 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element {
|
export function WithdrawPageWithParsedURI({ uri, uriInfo }: { uri: string, uriInfo: WithdrawUriInfoResponse }) {
|
||||||
const [uriInfo, setUriInfo] = useState<WithdrawUriInfoResponse | undefined>(undefined);
|
const [customExchange, setCustomExchange] = useState<string | undefined>(undefined)
|
||||||
const [details, setDetails] = useState<ExchangeWithdrawDetails | undefined>(undefined);
|
const [errorAccepting, setErrorAccepting] = useState<string | undefined>(undefined)
|
||||||
const [cancelled, setCancelled] = useState(false);
|
|
||||||
const [selecting, setSelecting] = useState(false);
|
|
||||||
const [error, setError] = useState<boolean>(false);
|
|
||||||
const [updateCounter, setUpdateCounter] = useState(1);
|
|
||||||
const [reviewing, setReviewing] = useState<boolean>(false)
|
const [reviewing, setReviewing] = useState<boolean>(false)
|
||||||
const [accepted, setAccepted] = useState<boolean>(false)
|
const [accepted, setAccepted] = useState<boolean>(false)
|
||||||
const [confirmed, setConfirmed] = useState<boolean>(false)
|
const [confirmed, setConfirmed] = useState<boolean>(false)
|
||||||
|
|
||||||
useEffect(() => {
|
const knownExchangesHook = useAsyncAsHook(() => listExchanges())
|
||||||
return onUpdateNotification(() => {
|
|
||||||
console.log('updating...')
|
|
||||||
setUpdateCounter(updateCounter + 1);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const knownExchanges = !knownExchangesHook || knownExchangesHook.hasError ? [] : knownExchangesHook.response.exchanges
|
||||||
console.log('on effect yes', talerWithdrawUri)
|
const withdrawAmount = Amounts.parseOrThrow(uriInfo.amount)
|
||||||
if (!talerWithdrawUri) return
|
const thisCurrencyExchanges = knownExchanges.filter(ex => ex.currency === withdrawAmount.currency)
|
||||||
const fetchData = async (): Promise<void> => {
|
|
||||||
try {
|
|
||||||
const res = await getWithdrawalDetailsForUri({ talerWithdrawUri });
|
|
||||||
setUriInfo(res);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('error', JSON.stringify(e, undefined, 2))
|
|
||||||
setError(true)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fetchData();
|
|
||||||
}, [selecting, talerWithdrawUri, updateCounter]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const exchange = customExchange || uriInfo.defaultExchangeBaseUrl || thisCurrencyExchanges[0]?.exchangeBaseUrl
|
||||||
async function fetchData() {
|
const detailsHook = useAsyncAsHook(async () => {
|
||||||
if (!uriInfo || !uriInfo.defaultExchangeBaseUrl) return
|
if (!exchange) throw Error('no default exchange')
|
||||||
try {
|
return getExchangeWithdrawalInfo({
|
||||||
const res = await getExchangeWithdrawalInfo({
|
exchangeBaseUrl: exchange,
|
||||||
exchangeBaseUrl: uriInfo.defaultExchangeBaseUrl,
|
amount: withdrawAmount,
|
||||||
amount: Amounts.parseOrThrow(uriInfo.amount),
|
|
||||||
tosAcceptedFormat: ['text/json', 'text/xml', 'text/pdf']
|
tosAcceptedFormat: ['text/json', 'text/xml', 'text/pdf']
|
||||||
})
|
})
|
||||||
setDetails(res)
|
})
|
||||||
} catch (e) {
|
|
||||||
setError(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchData()
|
|
||||||
}, [uriInfo])
|
|
||||||
|
|
||||||
if (!talerWithdrawUri) {
|
if (!detailsHook) {
|
||||||
return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>;
|
return <span><i18n.Translate>Getting withdrawal details.</i18n.Translate></span>;
|
||||||
}
|
}
|
||||||
|
if (detailsHook.hasError) {
|
||||||
|
return <span><i18n.Translate>Problems getting details: {detailsHook.message}</i18n.Translate></span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const details = detailsHook.response
|
||||||
|
|
||||||
const onAccept = async (): Promise<void> => {
|
const onAccept = async (): Promise<void> => {
|
||||||
if (!details) {
|
|
||||||
throw Error("can't accept, no exchange selected");
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
await setExchangeTosAccepted(details.exchangeDetails.exchangeBaseUrl, details.tosRequested?.tosEtag)
|
await setExchangeTosAccepted(details.exchangeInfo.baseUrl, details.tosRequested?.tosEtag)
|
||||||
setAccepted(true)
|
setAccepted(true)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(true)
|
if (e instanceof Error) {
|
||||||
|
setErrorAccepting(e.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onWithdraw = async (): Promise<void> => {
|
const onWithdraw = async (): Promise<void> => {
|
||||||
if (!details) {
|
|
||||||
throw Error("can't accept, no exchange selected");
|
|
||||||
}
|
|
||||||
setConfirmed(true)
|
setConfirmed(true)
|
||||||
console.log("accepting exchange", details.exchangeInfo.baseUrl);
|
console.log("accepting exchange", details.exchangeDetails.exchangeBaseUrl);
|
||||||
try {
|
try {
|
||||||
const res = await acceptWithdrawal(talerWithdrawUri, details.exchangeInfo.baseUrl);
|
const res = await acceptWithdrawal(uri, details.exchangeInfo.baseUrl);
|
||||||
console.log("accept withdrawal response", res);
|
console.log("accept withdrawal response", res);
|
||||||
if (res.confirmTransferUrl) {
|
if (res.confirmTransferUrl) {
|
||||||
document.location.href = res.confirmTransferUrl;
|
document.location.href = res.confirmTransferUrl;
|
||||||
@ -261,19 +257,6 @@ export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cancelled) {
|
|
||||||
return <span><i18n.Translate>Withdraw operation has been cancelled.</i18n.Translate></span>;
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
return <span><i18n.Translate>This URI is not valid anymore.</i18n.Translate></span>;
|
|
||||||
}
|
|
||||||
if (!uriInfo) {
|
|
||||||
return <span><i18n.Translate>Loading...</i18n.Translate></span>;
|
|
||||||
}
|
|
||||||
if (!details) {
|
|
||||||
return <span><i18n.Translate>Getting withdrawal details.</i18n.Translate></span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let termsContent: TermsDocument | undefined = undefined;
|
let termsContent: TermsDocument | undefined = undefined;
|
||||||
if (details.tosRequested) {
|
if (details.tosRequested) {
|
||||||
if (details.tosRequested.tosContentType === 'text/xml') {
|
if (details.tosRequested.tosContentType === 'text/xml') {
|
||||||
@ -295,14 +278,32 @@ export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element
|
|||||||
|
|
||||||
return <View onWithdraw={onWithdraw}
|
return <View onWithdraw={onWithdraw}
|
||||||
// setCancelled={setCancelled} setSelecting={setSelecting}
|
// setCancelled={setCancelled} setSelecting={setSelecting}
|
||||||
details={details} amount={uriInfo.amount}
|
details={details} amount={withdrawAmount}
|
||||||
terms={{
|
terms={{
|
||||||
status, value: termsContent
|
status, value: termsContent
|
||||||
}}
|
}}
|
||||||
|
onSwitchExchange={setCustomExchange}
|
||||||
|
knownExchanges={knownExchanges}
|
||||||
confirmed={confirmed}
|
confirmed={confirmed}
|
||||||
accepted={accepted} onAccept={onAccept}
|
accepted={accepted} onAccept={onAccept}
|
||||||
reviewing={reviewing} onReview={setReviewing}
|
reviewing={reviewing} onReview={setReviewing}
|
||||||
// terms={[]}
|
// terms={[]}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
export function WithdrawPage({ talerWithdrawUri }: Props): JSX.Element {
|
||||||
|
const uriInfoHook = useAsyncAsHook(() => !talerWithdrawUri ? Promise.reject(undefined) :
|
||||||
|
getWithdrawalDetailsForUri({ talerWithdrawUri })
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!talerWithdrawUri) {
|
||||||
|
return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>;
|
||||||
|
}
|
||||||
|
if (!uriInfoHook) {
|
||||||
|
return <span><i18n.Translate>Loading...</i18n.Translate></span>;
|
||||||
|
}
|
||||||
|
if (uriInfoHook.hasError) {
|
||||||
|
return <span><i18n.Translate>This URI is not valid anymore: {uriInfoHook.message}</i18n.Translate></span>;
|
||||||
|
}
|
||||||
|
return <WithdrawPageWithParsedURI uri={talerWithdrawUri} uriInfo={uriInfoHook.response} />
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
(C) 2016 GNUnet e.V.
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
import { ExchangesListRespose } from "@gnu-taler/taler-util";
|
||||||
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
|
interface HookOk<T> {
|
||||||
|
hasError: false;
|
||||||
|
response: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HookError {
|
||||||
|
hasError: true;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HookResponse<T> = HookOk<T> | HookError | undefined;
|
||||||
|
|
||||||
|
export function useAsyncAsHook<T> (fn: (() => Promise<T>)): HookResponse<T> {
|
||||||
|
const [result, setHookResponse] = useState<HookResponse<T>>(undefined);
|
||||||
|
useEffect(() => {
|
||||||
|
async function doAsync() {
|
||||||
|
try {
|
||||||
|
const response = await fn();
|
||||||
|
setHookResponse({ hasError: false, response });
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
setHookResponse({ hasError: true, message: e.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doAsync()
|
||||||
|
}, []);
|
||||||
|
return result;
|
||||||
|
}
|
@ -20,12 +20,13 @@ import * as wxApi from "../wxApi";
|
|||||||
|
|
||||||
|
|
||||||
interface BalancesHookOk {
|
interface BalancesHookOk {
|
||||||
error: false;
|
hasError: false;
|
||||||
response: BalancesResponse;
|
response: BalancesResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BalancesHookError {
|
interface BalancesHookError {
|
||||||
error: true;
|
hasError: true;
|
||||||
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BalancesHook = BalancesHookOk | BalancesHookError | undefined;
|
export type BalancesHook = BalancesHookOk | BalancesHookError | undefined;
|
||||||
@ -37,10 +38,12 @@ export function useBalances(): BalancesHook {
|
|||||||
try {
|
try {
|
||||||
const response = await wxApi.getBalance();
|
const response = await wxApi.getBalance();
|
||||||
console.log("got balance", balance);
|
console.log("got balance", balance);
|
||||||
setBalance({ error: false, response });
|
setBalance({ hasError: false, response });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("could not retrieve balances", e);
|
console.error("could not retrieve balances", e);
|
||||||
setBalance({ error: true });
|
if (e instanceof Error) {
|
||||||
|
setBalance({ hasError: true, message: e.message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkBalance()
|
checkBalance()
|
@ -35,14 +35,15 @@ export const NotYetLoaded = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const GotError = createExample(TestedComponent, {
|
export const GotError = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: true
|
hasError: true,
|
||||||
|
message: 'Network error'
|
||||||
},
|
},
|
||||||
Linker: NullLink,
|
Linker: NullLink,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EmptyBalance = createExample(TestedComponent, {
|
export const EmptyBalance = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: []
|
balances: []
|
||||||
},
|
},
|
||||||
@ -52,7 +53,7 @@ export const EmptyBalance = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const SomeCoins = createExample(TestedComponent, {
|
export const SomeCoins = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:10.5',
|
available: 'USD:10.5',
|
||||||
@ -68,7 +69,7 @@ export const SomeCoins = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:2.23',
|
available: 'USD:2.23',
|
||||||
@ -82,20 +83,80 @@ export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
|||||||
Linker: NullLink,
|
Linker: NullLink,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const SomeCoinsAndOutgoingMoney = createExample(TestedComponent, {
|
||||||
|
balance: {
|
||||||
|
hasError: false,
|
||||||
|
response: {
|
||||||
|
balances: [{
|
||||||
|
available: 'USD:2.23',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:5.11',
|
||||||
|
requiresUserInput: false
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Linker: NullLink,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SomeCoinsAndMovingMoney = createExample(TestedComponent, {
|
||||||
|
balance: {
|
||||||
|
hasError: false,
|
||||||
|
response: {
|
||||||
|
balances: [{
|
||||||
|
available: 'USD:2.23',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:2',
|
||||||
|
pendingOutgoing: 'USD:5.11',
|
||||||
|
requiresUserInput: false
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Linker: NullLink,
|
||||||
|
});
|
||||||
|
|
||||||
export const SomeCoinsInTwoCurrencies = createExample(TestedComponent, {
|
export const SomeCoinsInTwoCurrencies = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:2',
|
available: 'USD:2',
|
||||||
hasPendingTransactions: false,
|
hasPendingTransactions: false,
|
||||||
pendingIncoming: 'USD:5',
|
pendingIncoming: 'USD:5.1',
|
||||||
pendingOutgoing: 'USD:0',
|
pendingOutgoing: 'USD:0',
|
||||||
requiresUserInput: false
|
requiresUserInput: false
|
||||||
},{
|
},{
|
||||||
available: 'EUR:4',
|
available: 'EUR:4',
|
||||||
hasPendingTransactions: false,
|
hasPendingTransactions: false,
|
||||||
pendingIncoming: 'EUR:5',
|
pendingIncoming: 'EUR:0',
|
||||||
|
pendingOutgoing: 'EUR:3.01',
|
||||||
|
requiresUserInput: false
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Linker: NullLink,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SomeCoinsInTreeCurrencies = createExample(TestedComponent, {
|
||||||
|
balance: {
|
||||||
|
hasError: false,
|
||||||
|
response: {
|
||||||
|
balances: [{
|
||||||
|
available: 'USD:1',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'COL:2000',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'EUR:4',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'EUR:15',
|
||||||
pendingOutgoing: 'EUR:0',
|
pendingOutgoing: 'EUR:0',
|
||||||
requiresUserInput: false
|
requiresUserInput: false
|
||||||
}]
|
}]
|
||||||
@ -103,3 +164,56 @@ export const SomeCoinsInTwoCurrencies = createExample(TestedComponent, {
|
|||||||
},
|
},
|
||||||
Linker: NullLink,
|
Linker: NullLink,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export const SomeCoinsInFiveCurrencies = createExample(TestedComponent, {
|
||||||
|
balance: {
|
||||||
|
hasError: false,
|
||||||
|
response: {
|
||||||
|
balances: [{
|
||||||
|
available: 'USD:13451',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'EUR:202.02',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'EUR:0',
|
||||||
|
pendingOutgoing: 'EUR:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'ARS:30',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'JPY:51223233',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'EUR:0',
|
||||||
|
pendingOutgoing: 'EUR:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'JPY:51223233',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'EUR:0',
|
||||||
|
pendingOutgoing: 'EUR:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'DEMOKUDOS:6',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:0',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
},{
|
||||||
|
available: 'TESTKUDOS:6',
|
||||||
|
hasPendingTransactions: false,
|
||||||
|
pendingIncoming: 'USD:5',
|
||||||
|
pendingOutgoing: 'USD:0',
|
||||||
|
requiresUserInput: false
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Linker: NullLink,
|
||||||
|
});
|
||||||
|
@ -19,8 +19,9 @@ import {
|
|||||||
Balance, BalancesResponse,
|
Balance, BalancesResponse,
|
||||||
i18n
|
i18n
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { JSX, h } from "preact";
|
import { JSX, h, Fragment } from "preact";
|
||||||
import { PopupBox, Centered, ButtonPrimary } from "../components/styled/index";
|
import { ErrorMessage } from "../components/ErrorMessage";
|
||||||
|
import { PopupBox, Centered, ButtonPrimary, ErrorBox, Middle } from "../components/styled/index";
|
||||||
import { BalancesHook, useBalances } from "../hooks/useBalances";
|
import { BalancesHook, useBalances } from "../hooks/useBalances";
|
||||||
import { PageLink, renderAmount } from "../renderHtml";
|
import { PageLink, renderAmount } from "../renderHtml";
|
||||||
|
|
||||||
@ -34,34 +35,6 @@ export interface BalanceViewProps {
|
|||||||
Linker: typeof PageLink;
|
Linker: typeof PageLink;
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => void;
|
||||||
}
|
}
|
||||||
export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: BalanceViewProps) {
|
|
||||||
if (!balance) {
|
|
||||||
return <span />
|
|
||||||
}
|
|
||||||
|
|
||||||
if (balance.error) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
|
|
||||||
<p>
|
|
||||||
Click <Linker pageName="welcome">here</Linker> for help and
|
|
||||||
diagnostics.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (balance.response.balances.length === 0) {
|
|
||||||
return (
|
|
||||||
<p><i18n.Translate>
|
|
||||||
You have no balance to show. Need some{" "}
|
|
||||||
<Linker pageName="/welcome">help</Linker> getting started?
|
|
||||||
</i18n.Translate></p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return <ShowBalances wallet={balance.response}
|
|
||||||
onWithdraw={goToWalletManualWithdraw}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatPending(entry: Balance): JSX.Element {
|
function formatPending(entry: Balance): JSX.Element {
|
||||||
let incoming: JSX.Element | undefined;
|
let incoming: JSX.Element | undefined;
|
||||||
@ -74,11 +47,20 @@ function formatPending(entry: Balance): JSX.Element {
|
|||||||
if (!Amounts.isZero(pendingIncoming)) {
|
if (!Amounts.isZero(pendingIncoming)) {
|
||||||
incoming = (
|
incoming = (
|
||||||
<span><i18n.Translate>
|
<span><i18n.Translate>
|
||||||
<span style={{ color: "darkgreen" }}>
|
<span style={{ color: "darkgreen" }} title="incoming amount">
|
||||||
{"+"}
|
{"+"}
|
||||||
{renderAmount(entry.pendingIncoming)}
|
{renderAmount(entry.pendingIncoming)}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
incoming
|
</i18n.Translate></span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!Amounts.isZero(pendingOutgoing)) {
|
||||||
|
payment = (
|
||||||
|
<span><i18n.Translate>
|
||||||
|
<span style={{ color: "darkred" }} title="outgoing amount">
|
||||||
|
{"-"}
|
||||||
|
{renderAmount(entry.pendingOutgoing)}
|
||||||
|
</span>{" "}
|
||||||
</i18n.Translate></span>
|
</i18n.Translate></span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -89,36 +71,85 @@ function formatPending(entry: Balance): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (l.length === 1) {
|
if (l.length === 1) {
|
||||||
return <span>({l})</span>;
|
return <span>{l}</span>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
({l[0]}, {l[1]})
|
{l[0]}, {l[1]}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function ShowBalances({ wallet, onWithdraw }: { wallet: BalancesResponse, onWithdraw: () => void }) {
|
export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: BalanceViewProps) {
|
||||||
return <PopupBox>
|
|
||||||
<section>
|
function Content() {
|
||||||
<Centered>{wallet.balances.map((entry) => {
|
if (!balance) {
|
||||||
const av = Amounts.parseOrThrow(entry.available);
|
return <span />
|
||||||
const v = av.value + av.fraction / amountFractionalBase;
|
}
|
||||||
return (
|
|
||||||
<p key={av.currency}>
|
if (balance.hasError) {
|
||||||
<span>
|
return (<section>
|
||||||
<span style={{ fontSize: "5em", display: "block" }}>{v}</span>{" "}
|
<ErrorBox>{balance.message}</ErrorBox>
|
||||||
<span>{av.currency}</span>
|
<p>
|
||||||
</span>
|
Click <Linker pageName="welcome">here</Linker> for help and
|
||||||
{formatPending(entry)}
|
diagnostics.
|
||||||
</p>
|
</p>
|
||||||
|
</section>)
|
||||||
|
}
|
||||||
|
if (balance.response.balances.length === 0) {
|
||||||
|
return (<section data-expanded>
|
||||||
|
<Middle>
|
||||||
|
<p><i18n.Translate>
|
||||||
|
You have no balance to show. Need some{" "}
|
||||||
|
<Linker pageName="/welcome">help</Linker> getting started?
|
||||||
|
</i18n.Translate></p>
|
||||||
|
</Middle>
|
||||||
|
</section>)
|
||||||
|
}
|
||||||
|
return <section data-expanded data-centered>
|
||||||
|
<table style={{width:'100%'}}>{balance.response.balances.map((entry) => {
|
||||||
|
const av = Amounts.parseOrThrow(entry.available);
|
||||||
|
// Create our number formatter.
|
||||||
|
let formatter;
|
||||||
|
try {
|
||||||
|
formatter = new Intl.NumberFormat('en-US', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: av.currency,
|
||||||
|
currencyDisplay: 'symbol'
|
||||||
|
// These options are needed to round to whole numbers if that's what you want.
|
||||||
|
//minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
|
||||||
|
//maximumFractionDigits: 0, // (causes 2500.99 to be printed as $2,501)
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
formatter = new Intl.NumberFormat('en-US', {
|
||||||
|
// style: 'currency',
|
||||||
|
// currency: av.currency,
|
||||||
|
// These options are needed to round to whole numbers if that's what you want.
|
||||||
|
//minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
|
||||||
|
//maximumFractionDigits: 0, // (causes 2500.99 to be printed as $2,501)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const v = formatter.format(av.value + av.fraction / amountFractionalBase);
|
||||||
|
const fontSize = v.length < 8 ? '3em' : (v.length < 13 ? '2em' : '1em')
|
||||||
|
return (<tr>
|
||||||
|
<td style={{ height: 50, fontSize, width: '60%', textAlign: 'right', padding: 0 }}>{v}</td>
|
||||||
|
<td style={{ maxWidth: '2em', overflowX: 'hidden' }}>{av.currency}</td>
|
||||||
|
<td style={{ fontSize: 'small', color: 'gray' }}>{formatPending(entry)}</td>
|
||||||
|
</tr>
|
||||||
);
|
);
|
||||||
})}</Centered>
|
})}</table>
|
||||||
</section>
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
return <PopupBox>
|
||||||
|
{/* <section> */}
|
||||||
|
<Content />
|
||||||
|
{/* </section> */}
|
||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<ButtonPrimary onClick={onWithdraw} >Withdraw</ButtonPrimary>
|
<ButtonPrimary onClick={goToWalletManualWithdraw}>Withdraw</ButtonPrimary>
|
||||||
</footer>
|
</footer>
|
||||||
</PopupBox>
|
</PopupBox>
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ export function DeveloperPage(props: any): JSX.Element {
|
|||||||
<button onClick={openExtensionPage("/static/popup.html")}>wallet tab</button>
|
<button onClick={openExtensionPage("/static/popup.html")}>wallet tab</button>
|
||||||
<br />
|
<br />
|
||||||
<button onClick={confirmReset}>reset</button>
|
<button onClick={confirmReset}>reset</button>
|
||||||
<button onClick={reload}>reload chrome extension</button>
|
|
||||||
<Diagnostics diagnostics={status} timedOut={timedOut} />
|
<Diagnostics diagnostics={status} timedOut={timedOut} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -105,7 +105,7 @@ const exampleData = {
|
|||||||
} as TransactionRefund,
|
} as TransactionRefund,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Empty = createExample(TestedComponent, {
|
export const EmptyWithBalance = createExample(TestedComponent, {
|
||||||
list: [],
|
list: [],
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'TESTKUDOS:10',
|
available: 'TESTKUDOS:10',
|
||||||
@ -116,6 +116,10 @@ export const Empty = createExample(TestedComponent, {
|
|||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmptyWithNoBalance = createExample(TestedComponent, {
|
||||||
|
list: [],
|
||||||
|
balances: []
|
||||||
|
});
|
||||||
|
|
||||||
export const One = createExample(TestedComponent, {
|
export const One = createExample(TestedComponent, {
|
||||||
list: [exampleData.withdraw],
|
list: [exampleData.withdraw],
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AmountString, Balance, Transaction, TransactionsResponse } from "@gnu-taler/taler-util";
|
import { AmountString, Balance, i18n, Transaction, TransactionsResponse } from "@gnu-taler/taler-util";
|
||||||
import { h, JSX } from "preact";
|
import { h, JSX } from "preact";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { PopupBox } from "../components/styled";
|
import { PopupBox } from "../components/styled";
|
||||||
@ -28,7 +28,7 @@ export function HistoryPage(props: any): JSX.Element {
|
|||||||
TransactionsResponse | undefined
|
TransactionsResponse | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const balance = useBalances()
|
const balance = useBalances()
|
||||||
const balanceWithoutError = balance?.error ? [] : (balance?.response.balances || [])
|
const balanceWithoutError = balance?.hasError ? [] : (balance?.response.balances || [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async (): Promise<void> => {
|
const fetchData = async (): Promise<void> => {
|
||||||
@ -64,16 +64,24 @@ export function HistoryView({ list, balances }: { list: Transaction[], balances:
|
|||||||
Balance: <span>{amountToString(balances[0].available)}</span>
|
Balance: <span>{amountToString(balances[0].available)}</span>
|
||||||
</div>}
|
</div>}
|
||||||
</header>}
|
</header>}
|
||||||
|
{list.length === 0 ? <section data-expanded data-centered>
|
||||||
|
<p><i18n.Translate>
|
||||||
|
You have no history yet, here you will be able to check your last transactions.
|
||||||
|
</i18n.Translate></p>
|
||||||
|
</section> :
|
||||||
<section>
|
<section>
|
||||||
{list.slice(0, 3).map((tx, i) => (
|
{list.slice(0, 3).map((tx, i) => (
|
||||||
<TransactionItem key={i} tx={tx} multiCurrency={multiCurrency}/>
|
<TransactionItem key={i} tx={tx} multiCurrency={multiCurrency} />
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
|
}
|
||||||
<footer style={{ justifyContent: 'space-around' }}>
|
<footer style={{ justifyContent: 'space-around' }}>
|
||||||
|
{list.length > 0 &&
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
style={{ color: 'darkgreen', textDecoration: 'none' }}
|
style={{ color: 'darkgreen', textDecoration: 'none' }}
|
||||||
href={chrome.extension ? chrome.extension.getURL(`/static/wallet.html#/history`) : '#'}>VIEW MORE TRANSACTIONS</a>
|
href={chrome.extension ? chrome.extension.getURL(`/static/wallet.html#/history`) : '#'}>VIEW MORE TRANSACTIONS</a>
|
||||||
|
}
|
||||||
</footer>
|
</footer>
|
||||||
</PopupBox>
|
</PopupBox>
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import { VNode, h } from "preact";
|
|||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { EditableText } from "../components/EditableText";
|
import { EditableText } from "../components/EditableText";
|
||||||
import { SelectList } from "../components/SelectList";
|
import { SelectList } from "../components/SelectList";
|
||||||
|
import { PopupBox } from "../components/styled";
|
||||||
import { useDevContext } from "../context/devContext";
|
import { useDevContext } from "../context/devContext";
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
@ -67,10 +68,10 @@ const names: LangsNames = {
|
|||||||
|
|
||||||
export function SettingsView({ lang, changeLang, deviceName, setDeviceName, permissionsEnabled, togglePermissions, developerMode, toggleDeveloperMode }: ViewProps): VNode {
|
export function SettingsView({ lang, changeLang, deviceName, setDeviceName, permissionsEnabled, togglePermissions, developerMode, toggleDeveloperMode }: ViewProps): VNode {
|
||||||
return (
|
return (
|
||||||
<div>
|
<PopupBox>
|
||||||
<section style={{ height: 300, overflow: 'auto' }}>
|
<section>
|
||||||
<h2><i18n.Translate>Wallet</i18n.Translate></h2>
|
{/* <h2><i18n.Translate>Wallet</i18n.Translate></h2> */}
|
||||||
<SelectList
|
{/* <SelectList
|
||||||
value={lang}
|
value={lang}
|
||||||
onChange={changeLang}
|
onChange={changeLang}
|
||||||
name="lang"
|
name="lang"
|
||||||
@ -84,7 +85,7 @@ export function SettingsView({ lang, changeLang, deviceName, setDeviceName, perm
|
|||||||
name="device-id"
|
name="device-id"
|
||||||
label={i18n.str`Device name`}
|
label={i18n.str`Device name`}
|
||||||
description="(This is how you will recognize the wallet in the backup provider)"
|
description="(This is how you will recognize the wallet in the backup provider)"
|
||||||
/>
|
/> */}
|
||||||
<h2><i18n.Translate>Permissions</i18n.Translate></h2>
|
<h2><i18n.Translate>Permissions</i18n.Translate></h2>
|
||||||
<Checkbox label="Automatically open wallet based on page content"
|
<Checkbox label="Automatically open wallet based on page content"
|
||||||
name="perm"
|
name="perm"
|
||||||
@ -98,6 +99,12 @@ export function SettingsView({ lang, changeLang, deviceName, setDeviceName, perm
|
|||||||
enabled={developerMode} onToggle={toggleDeveloperMode}
|
enabled={developerMode} onToggle={toggleDeveloperMode}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
<footer style={{ justifyContent: 'space-around' }}>
|
||||||
|
<a target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
style={{ color: 'darkgreen', textDecoration: 'none' }}
|
||||||
|
href={chrome.extension ? chrome.extension.getURL(`/static/wallet.html#/settings`) : '#'}>VIEW MORE SETTINGS</a>
|
||||||
|
</footer>
|
||||||
|
</PopupBox>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -35,14 +35,15 @@ export const NotYetLoaded = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const GotError = createExample(TestedComponent, {
|
export const GotError = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: true
|
hasError: true,
|
||||||
|
message: 'Network error'
|
||||||
},
|
},
|
||||||
Linker: NullLink,
|
Linker: NullLink,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EmptyBalance = createExample(TestedComponent, {
|
export const EmptyBalance = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: []
|
balances: []
|
||||||
},
|
},
|
||||||
@ -52,7 +53,7 @@ export const EmptyBalance = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const SomeCoins = createExample(TestedComponent, {
|
export const SomeCoins = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:10.5',
|
available: 'USD:10.5',
|
||||||
@ -68,7 +69,7 @@ export const SomeCoins = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:2.23',
|
available: 'USD:2.23',
|
||||||
@ -84,7 +85,7 @@ export const SomeCoinsAndIncomingMoney = createExample(TestedComponent, {
|
|||||||
|
|
||||||
export const SomeCoinsInTwoCurrencies = createExample(TestedComponent, {
|
export const SomeCoinsInTwoCurrencies = createExample(TestedComponent, {
|
||||||
balance: {
|
balance: {
|
||||||
error: false,
|
hasError: false,
|
||||||
response: {
|
response: {
|
||||||
balances: [{
|
balances: [{
|
||||||
available: 'USD:2',
|
available: 'USD:2',
|
||||||
|
@ -41,7 +41,7 @@ export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: Balan
|
|||||||
return <span />
|
return <span />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (balance.error) {
|
if (balance.hasError) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
|
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
|
||||||
|
@ -29,7 +29,7 @@ export function HistoryPage(props: any): JSX.Element {
|
|||||||
TransactionsResponse | undefined
|
TransactionsResponse | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const balance = useBalances()
|
const balance = useBalances()
|
||||||
const balanceWithoutError = balance?.error ? [] : (balance?.response.balances || [])
|
const balanceWithoutError = balance?.hasError ? [] : (balance?.response.balances || [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async (): Promise<void> => {
|
const fetchData = async (): Promise<void> => {
|
||||||
|
@ -15,23 +15,29 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { i18n } from "@gnu-taler/taler-util";
|
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
||||||
import { VNode, h } from "preact";
|
import { VNode, h, Fragment } from "preact";
|
||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { EditableText } from "../components/EditableText";
|
import { EditableText } from "../components/EditableText";
|
||||||
import { SelectList } from "../components/SelectList";
|
import { SelectList } from "../components/SelectList";
|
||||||
|
import { ButtonPrimary, ButtonSuccess, WalletBox } from "../components/styled";
|
||||||
import { useDevContext } from "../context/devContext";
|
import { useDevContext } from "../context/devContext";
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import { useLang } from "../hooks/useLang";
|
import { useLang } from "../hooks/useLang";
|
||||||
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
export function SettingsPage(): VNode {
|
export function SettingsPage(): VNode {
|
||||||
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
||||||
const { devMode, toggleDevMode } = useDevContext()
|
const { devMode, toggleDevMode } = useDevContext()
|
||||||
const { name, update } = useBackupDeviceName()
|
const { name, update } = useBackupDeviceName()
|
||||||
const [lang, changeLang] = useLang()
|
const [lang, changeLang] = useLang()
|
||||||
|
const exchangesHook = useAsyncAsHook(() => wxApi.listExchanges());
|
||||||
|
|
||||||
return <SettingsView
|
return <SettingsView
|
||||||
lang={lang} changeLang={changeLang}
|
lang={lang} changeLang={changeLang}
|
||||||
|
knownExchanges={!exchangesHook || exchangesHook.hasError ? [] : exchangesHook.response.exchanges}
|
||||||
deviceName={name} setDeviceName={update}
|
deviceName={name} setDeviceName={update}
|
||||||
permissionsEnabled={permissionsEnabled} togglePermissions={togglePermissions}
|
permissionsEnabled={permissionsEnabled} togglePermissions={togglePermissions}
|
||||||
developerMode={devMode} toggleDeveloperMode={toggleDevMode}
|
developerMode={devMode} toggleDeveloperMode={toggleDevMode}
|
||||||
@ -47,6 +53,7 @@ export interface ViewProps {
|
|||||||
togglePermissions: () => void;
|
togglePermissions: () => void;
|
||||||
developerMode: boolean;
|
developerMode: boolean;
|
||||||
toggleDeveloperMode: () => void;
|
toggleDeveloperMode: () => void;
|
||||||
|
knownExchanges: Array<ExchangeListItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
import { strings as messages } from '../i18n/strings'
|
import { strings as messages } from '../i18n/strings'
|
||||||
@ -65,26 +72,24 @@ const names: LangsNames = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function SettingsView({ lang, changeLang, deviceName, setDeviceName, permissionsEnabled, togglePermissions, developerMode, toggleDeveloperMode }: ViewProps): VNode {
|
export function SettingsView({ knownExchanges, lang, changeLang, deviceName, setDeviceName, permissionsEnabled, togglePermissions, developerMode, toggleDeveloperMode }: ViewProps): VNode {
|
||||||
return (
|
return (
|
||||||
<div>
|
<WalletBox>
|
||||||
<section style={{ height: 300, overflow: 'auto' }}>
|
<section>
|
||||||
<h2><i18n.Translate>Wallet</i18n.Translate></h2>
|
|
||||||
<SelectList
|
<h2><i18n.Translate>Known exchanges</i18n.Translate></h2>
|
||||||
value={lang}
|
{!knownExchanges || !knownExchanges.length ? <div>
|
||||||
onChange={changeLang}
|
No exchange yet!
|
||||||
name="lang"
|
</div> :
|
||||||
list={names}
|
<dl>
|
||||||
label={i18n.str`Language`}
|
{knownExchanges.map(e => <Fragment>
|
||||||
description="(Choose your preferred lang)"
|
<dt>{e.currency}</dt>
|
||||||
/>
|
<dd>{e.exchangeBaseUrl}</dd>
|
||||||
<EditableText
|
<dd>{e.paytoUris}</dd>
|
||||||
value={deviceName}
|
</Fragment>)}
|
||||||
onChange={setDeviceName}
|
</dl>
|
||||||
name="device-id"
|
}
|
||||||
label={i18n.str`Device name`}
|
<ButtonPrimary>add exchange</ButtonPrimary>
|
||||||
description="(This is how you will recognize the wallet in the backup provider)"
|
|
||||||
/>
|
|
||||||
<h2><i18n.Translate>Permissions</i18n.Translate></h2>
|
<h2><i18n.Translate>Permissions</i18n.Translate></h2>
|
||||||
<Checkbox label="Automatically open wallet based on page content"
|
<Checkbox label="Automatically open wallet based on page content"
|
||||||
name="perm"
|
name="perm"
|
||||||
@ -98,6 +103,6 @@ export function SettingsView({ lang, changeLang, deviceName, setDeviceName, perm
|
|||||||
enabled={developerMode} onToggle={toggleDeveloperMode}
|
enabled={developerMode} onToggle={toggleDeveloperMode}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</WalletBox>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -43,6 +43,7 @@ import {
|
|||||||
AcceptManualWithdrawalResult,
|
AcceptManualWithdrawalResult,
|
||||||
AcceptManualWithdrawalRequest,
|
AcceptManualWithdrawalRequest,
|
||||||
AmountJson,
|
AmountJson,
|
||||||
|
ExchangesListRespose,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { AddBackupProviderRequest, BackupProviderState, OperationFailedError, RemoveBackupProviderRequest } from "@gnu-taler/taler-wallet-core";
|
import { AddBackupProviderRequest, BackupProviderState, OperationFailedError, RemoveBackupProviderRequest } from "@gnu-taler/taler-wallet-core";
|
||||||
import { BackupInfo } from "@gnu-taler/taler-wallet-core";
|
import { BackupInfo } from "@gnu-taler/taler-wallet-core";
|
||||||
@ -170,6 +171,10 @@ export function listKnownCurrencies(): Promise<ListOfKnownCurrencies> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function listExchanges(): Promise<ExchangesListRespose> {
|
||||||
|
return callBackend("listExchanges", {})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about the current state of wallet backups.
|
* Get information about the current state of wallet backups.
|
||||||
*/
|
*/
|
||||||
|
478
pnpm-lock.yaml
478
pnpm-lock.yaml
@ -25,6 +25,43 @@ importers:
|
|||||||
ava: 3.15.0
|
ava: 3.15.0
|
||||||
typescript: 4.4.3
|
typescript: 4.4.3
|
||||||
|
|
||||||
|
packages/anastasis-webui:
|
||||||
|
specifiers:
|
||||||
|
'@types/enzyme': ^3.10.5
|
||||||
|
'@types/jest': ^26.0.8
|
||||||
|
'@typescript-eslint/eslint-plugin': ^2.25.0
|
||||||
|
'@typescript-eslint/parser': ^2.25.0
|
||||||
|
enzyme: ^3.11.0
|
||||||
|
enzyme-adapter-preact-pure: ^3.1.0
|
||||||
|
eslint: ^6.8.0
|
||||||
|
eslint-config-preact: ^1.1.1
|
||||||
|
jest: ^26.2.2
|
||||||
|
jest-preset-preact: ^4.0.2
|
||||||
|
preact: ^10.3.1
|
||||||
|
preact-cli: ^3.0.0
|
||||||
|
preact-render-to-string: ^5.1.4
|
||||||
|
preact-router: ^3.2.1
|
||||||
|
sirv-cli: ^1.0.0-next.3
|
||||||
|
typescript: ^3.7.5
|
||||||
|
dependencies:
|
||||||
|
preact: 10.5.14
|
||||||
|
preact-render-to-string: 5.1.19_preact@10.5.14
|
||||||
|
preact-router: 3.2.1_preact@10.5.14
|
||||||
|
devDependencies:
|
||||||
|
'@types/enzyme': 3.10.9
|
||||||
|
'@types/jest': 26.0.24
|
||||||
|
'@typescript-eslint/eslint-plugin': 2.34.0_2b015b1c4b7c4a3ed9a197dc233b1a35
|
||||||
|
'@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
enzyme: 3.11.0
|
||||||
|
enzyme-adapter-preact-pure: 3.1.0_enzyme@3.11.0+preact@10.5.14
|
||||||
|
eslint: 6.8.0
|
||||||
|
eslint-config-preact: 1.1.4_eslint@6.8.0+typescript@3.9.10
|
||||||
|
jest: 26.6.3
|
||||||
|
jest-preset-preact: 4.0.2_9b3f24ae35a87c3c82fffbe3fdf70e1e
|
||||||
|
preact-cli: 3.2.2_517d24bd855b57d7e424aceed04e063b
|
||||||
|
sirv-cli: 1.0.14
|
||||||
|
typescript: 3.9.10
|
||||||
|
|
||||||
packages/idb-bridge:
|
packages/idb-bridge:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@rollup/plugin-commonjs': ^17.1.0
|
'@rollup/plugin-commonjs': ^17.1.0
|
||||||
@ -4094,6 +4131,10 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@mdn/browser-compat-data/3.3.14:
|
||||||
|
resolution: {integrity: sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@mdx-js/loader/1.6.22:
|
/@mdx-js/loader/1.6.22:
|
||||||
resolution: {integrity: sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==}
|
resolution: {integrity: sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -6342,6 +6383,10 @@ packages:
|
|||||||
'@types/react': 17.0.19
|
'@types/react': 17.0.19
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/eslint-visitor-keys/1.0.0:
|
||||||
|
resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/estree/0.0.39:
|
/@types/estree/0.0.39:
|
||||||
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
|
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -6617,6 +6662,28 @@ packages:
|
|||||||
'@types/yargs-parser': 20.2.1
|
'@types/yargs-parser': 20.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@typescript-eslint/eslint-plugin/2.34.0_2b015b1c4b7c4a3ed9a197dc233b1a35:
|
||||||
|
resolution: {integrity: sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==}
|
||||||
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
|
peerDependencies:
|
||||||
|
'@typescript-eslint/parser': ^2.0.0
|
||||||
|
eslint: ^5.0.0 || ^6.0.0
|
||||||
|
typescript: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/experimental-utils': 2.34.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
'@typescript-eslint/parser': 2.34.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
eslint: 6.8.0
|
||||||
|
functional-red-black-tree: 1.0.1
|
||||||
|
regexpp: 3.1.0
|
||||||
|
tsutils: 3.19.1_typescript@3.9.10
|
||||||
|
typescript: 3.9.10
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin/4.14.0_980e7d90d2d08155204a38366bd3b934:
|
/@typescript-eslint/eslint-plugin/4.14.0_980e7d90d2d08155204a38366bd3b934:
|
||||||
resolution: {integrity: sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==}
|
resolution: {integrity: sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -6643,6 +6710,22 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@typescript-eslint/experimental-utils/2.34.0_eslint@6.8.0+typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==}
|
||||||
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '*'
|
||||||
|
dependencies:
|
||||||
|
'@types/json-schema': 7.0.9
|
||||||
|
'@typescript-eslint/typescript-estree': 2.34.0_typescript@3.9.10
|
||||||
|
eslint: 6.8.0
|
||||||
|
eslint-scope: 5.1.1
|
||||||
|
eslint-utils: 2.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/experimental-utils/4.14.0_eslint@7.18.0+typescript@4.1.3:
|
/@typescript-eslint/experimental-utils/4.14.0_eslint@7.18.0+typescript@4.1.3:
|
||||||
resolution: {integrity: sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==}
|
resolution: {integrity: sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -6661,6 +6744,26 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@typescript-eslint/parser/2.34.0_eslint@6.8.0+typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==}
|
||||||
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: ^5.0.0 || ^6.0.0
|
||||||
|
typescript: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/eslint-visitor-keys': 1.0.0
|
||||||
|
'@typescript-eslint/experimental-utils': 2.34.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
'@typescript-eslint/typescript-estree': 2.34.0_typescript@3.9.10
|
||||||
|
eslint: 6.8.0
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
typescript: 3.9.10
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/parser/4.14.0_eslint@7.18.0+typescript@4.1.3:
|
/@typescript-eslint/parser/4.14.0_eslint@7.18.0+typescript@4.1.3:
|
||||||
resolution: {integrity: sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==}
|
resolution: {integrity: sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -6727,6 +6830,27 @@ packages:
|
|||||||
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@typescript-eslint/typescript-estree/2.34.0_typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==}
|
||||||
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
debug: 4.3.2
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
glob: 7.1.7
|
||||||
|
is-glob: 4.0.1
|
||||||
|
lodash: 4.17.21
|
||||||
|
semver: 7.3.5
|
||||||
|
tsutils: 3.19.1_typescript@3.9.10
|
||||||
|
typescript: 3.9.10
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/typescript-estree/4.14.0_typescript@4.1.3:
|
/@typescript-eslint/typescript-estree/4.14.0_typescript@4.1.3:
|
||||||
resolution: {integrity: sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==}
|
resolution: {integrity: sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -7393,10 +7517,21 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ast-metadata-inferer/0.7.0:
|
||||||
|
resolution: {integrity: sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==}
|
||||||
|
dependencies:
|
||||||
|
'@mdn/browser-compat-data': 3.3.14
|
||||||
|
dev: true
|
||||||
|
|
||||||
/ast-types-flow/0.0.7:
|
/ast-types-flow/0.0.7:
|
||||||
resolution: {integrity: sha1-9wtzXGvKGlycItmCw+Oef+ujva0=}
|
resolution: {integrity: sha1-9wtzXGvKGlycItmCw+Oef+ujva0=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/astral-regex/1.0.0:
|
||||||
|
resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/astral-regex/2.0.0:
|
/astral-regex/2.0.0:
|
||||||
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
|
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -7546,7 +7681,7 @@ packages:
|
|||||||
/axios/0.21.1:
|
/axios/0.21.1:
|
||||||
resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==}
|
resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.14.2_debug@4.3.2
|
follow-redirects: 1.14.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
|
|
||||||
@ -7554,6 +7689,24 @@ packages:
|
|||||||
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
|
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/babel-eslint/10.1.0_eslint@6.8.0:
|
||||||
|
resolution: {integrity: sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
deprecated: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>= 4.12.1'
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.14.5
|
||||||
|
'@babel/parser': 7.15.3
|
||||||
|
'@babel/traverse': 7.15.0
|
||||||
|
'@babel/types': 7.15.0
|
||||||
|
eslint: 6.8.0
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
resolve: 1.20.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/babel-esm-plugin/0.9.0_webpack@4.46.0:
|
/babel-esm-plugin/0.9.0_webpack@4.46.0:
|
||||||
resolution: {integrity: sha512-OyPyLI6LUuUqNm3HNUldAkynWrLzXkhcZo4fGTsieCgHqvbCoCIMMOwJmfG9Lmp91S7WDIuUr0mvOeI8pAb/pw==}
|
resolution: {integrity: sha512-OyPyLI6LUuUqNm3HNUldAkynWrLzXkhcZo4fGTsieCgHqvbCoCIMMOwJmfG9Lmp91S7WDIuUr0mvOeI8pAb/pw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -8464,6 +8617,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
|
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/chardet/0.7.0:
|
||||||
|
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/cheerio-select/1.5.0:
|
/cheerio-select/1.5.0:
|
||||||
resolution: {integrity: sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==}
|
resolution: {integrity: sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -8632,6 +8789,11 @@ packages:
|
|||||||
string-width: 4.2.2
|
string-width: 4.2.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cli-width/3.0.0:
|
||||||
|
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/cliui/5.0.0:
|
/cliui/5.0.0:
|
||||||
resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==}
|
resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10482,6 +10644,22 @@ packages:
|
|||||||
object.entries: 1.1.3
|
object.entries: 1.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-config-preact/1.1.4_eslint@6.8.0+typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-j00/BpjPpVoaX8UTpXFPAsfBIzuwJX+sBvgPFyb53Lqi31fM0Oiq516qYXRyaZ7q1BRCjO8s67NCLal6v/Z8Lg==}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: 6.x || 7.x
|
||||||
|
dependencies:
|
||||||
|
babel-eslint: 10.1.0_eslint@6.8.0
|
||||||
|
eslint: 6.8.0
|
||||||
|
eslint-plugin-compat: 3.13.0_eslint@6.8.0
|
||||||
|
eslint-plugin-jest: 23.20.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
eslint-plugin-react: 7.22.0_eslint@6.8.0
|
||||||
|
eslint-plugin-react-hooks: 4.2.0_eslint@6.8.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-import-resolver-node/0.3.4:
|
/eslint-import-resolver-node/0.3.4:
|
||||||
resolution: {integrity: sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==}
|
resolution: {integrity: sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10497,6 +10675,23 @@ packages:
|
|||||||
pkg-dir: 2.0.0
|
pkg-dir: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-plugin-compat/3.13.0_eslint@6.8.0:
|
||||||
|
resolution: {integrity: sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==}
|
||||||
|
engines: {node: '>=9.x'}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||||
|
dependencies:
|
||||||
|
'@mdn/browser-compat-data': 3.3.14
|
||||||
|
ast-metadata-inferer: 0.7.0
|
||||||
|
browserslist: 4.16.8
|
||||||
|
caniuse-lite: 1.0.30001251
|
||||||
|
core-js: 3.16.2
|
||||||
|
eslint: 6.8.0
|
||||||
|
find-up: 5.0.0
|
||||||
|
lodash.memoize: 4.1.2
|
||||||
|
semver: 7.3.5
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-import/2.22.1_eslint@7.18.0:
|
/eslint-plugin-import/2.22.1_eslint@7.18.0:
|
||||||
resolution: {integrity: sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==}
|
resolution: {integrity: sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -10519,6 +10714,19 @@ packages:
|
|||||||
tsconfig-paths: 3.9.0
|
tsconfig-paths: 3.9.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-plugin-jest/23.20.0_eslint@6.8.0+typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>=5'
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/experimental-utils': 2.34.0_eslint@6.8.0+typescript@3.9.10
|
||||||
|
eslint: 6.8.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
- typescript
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-jsx-a11y/6.4.1_eslint@7.18.0:
|
/eslint-plugin-jsx-a11y/6.4.1_eslint@7.18.0:
|
||||||
resolution: {integrity: sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==}
|
resolution: {integrity: sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==}
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
@ -10539,6 +10747,15 @@ packages:
|
|||||||
language-tags: 1.0.5
|
language-tags: 1.0.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-plugin-react-hooks/4.2.0_eslint@6.8.0:
|
||||||
|
resolution: {integrity: sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||||
|
dependencies:
|
||||||
|
eslint: 6.8.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-react-hooks/4.2.0_eslint@7.18.0:
|
/eslint-plugin-react-hooks/4.2.0_eslint@7.18.0:
|
||||||
resolution: {integrity: sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==}
|
resolution: {integrity: sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -10548,6 +10765,26 @@ packages:
|
|||||||
eslint: 7.18.0
|
eslint: 7.18.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-plugin-react/7.22.0_eslint@6.8.0:
|
||||||
|
resolution: {integrity: sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: ^3 || ^4 || ^5 || ^6 || ^7
|
||||||
|
dependencies:
|
||||||
|
array-includes: 3.1.2
|
||||||
|
array.prototype.flatmap: 1.2.4
|
||||||
|
doctrine: 2.1.0
|
||||||
|
eslint: 6.8.0
|
||||||
|
has: 1.0.3
|
||||||
|
jsx-ast-utils: 3.2.0
|
||||||
|
object.entries: 1.1.3
|
||||||
|
object.fromentries: 2.0.3
|
||||||
|
object.values: 1.1.2
|
||||||
|
prop-types: 15.7.2
|
||||||
|
resolve: 1.19.0
|
||||||
|
string.prototype.matchall: 4.0.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-react/7.22.0_eslint@7.18.0:
|
/eslint-plugin-react/7.22.0_eslint@7.18.0:
|
||||||
resolution: {integrity: sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==}
|
resolution: {integrity: sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -10584,6 +10821,13 @@ packages:
|
|||||||
estraverse: 4.3.0
|
estraverse: 4.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-utils/1.4.3:
|
||||||
|
resolution: {integrity: sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-utils/2.1.0:
|
/eslint-utils/2.1.0:
|
||||||
resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
|
resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -10601,6 +10845,52 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint/6.8.0:
|
||||||
|
resolution: {integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==}
|
||||||
|
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.14.5
|
||||||
|
ajv: 6.12.6
|
||||||
|
chalk: 2.4.2
|
||||||
|
cross-spawn: 6.0.5
|
||||||
|
debug: 4.3.2
|
||||||
|
doctrine: 3.0.0
|
||||||
|
eslint-scope: 5.1.1
|
||||||
|
eslint-utils: 1.4.3
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
espree: 6.2.1
|
||||||
|
esquery: 1.3.1
|
||||||
|
esutils: 2.0.3
|
||||||
|
file-entry-cache: 5.0.1
|
||||||
|
functional-red-black-tree: 1.0.1
|
||||||
|
glob-parent: 5.1.2
|
||||||
|
globals: 12.4.0
|
||||||
|
ignore: 4.0.6
|
||||||
|
import-fresh: 3.3.0
|
||||||
|
imurmurhash: 0.1.4
|
||||||
|
inquirer: 7.3.3
|
||||||
|
is-glob: 4.0.1
|
||||||
|
js-yaml: 3.14.1
|
||||||
|
json-stable-stringify-without-jsonify: 1.0.1
|
||||||
|
levn: 0.3.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
minimatch: 3.0.4
|
||||||
|
mkdirp: 0.5.5
|
||||||
|
natural-compare: 1.4.0
|
||||||
|
optionator: 0.8.3
|
||||||
|
progress: 2.0.3
|
||||||
|
regexpp: 2.0.1
|
||||||
|
semver: 6.3.0
|
||||||
|
strip-ansi: 5.2.0
|
||||||
|
strip-json-comments: 3.1.1
|
||||||
|
table: 5.4.6
|
||||||
|
text-table: 0.2.0
|
||||||
|
v8-compile-cache: 2.2.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint/7.18.0:
|
/eslint/7.18.0:
|
||||||
resolution: {integrity: sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==}
|
resolution: {integrity: sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -10652,6 +10942,15 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/espree/6.2.1:
|
||||||
|
resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
acorn: 7.4.1
|
||||||
|
acorn-jsx: 5.3.2_acorn@7.4.1
|
||||||
|
eslint-visitor-keys: 1.3.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/espree/7.3.1:
|
/espree/7.3.1:
|
||||||
resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
|
resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -10849,6 +11148,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/external-editor/3.1.0:
|
||||||
|
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
chardet: 0.7.0
|
||||||
|
iconv-lite: 0.4.24
|
||||||
|
tmp: 0.0.33
|
||||||
|
dev: true
|
||||||
|
|
||||||
/extglob/2.0.4:
|
/extglob/2.0.4:
|
||||||
resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
|
resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -10972,6 +11280,13 @@ packages:
|
|||||||
escape-string-regexp: 1.0.5
|
escape-string-regexp: 1.0.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/file-entry-cache/5.0.1:
|
||||||
|
resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
flat-cache: 2.0.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/file-entry-cache/6.0.0:
|
/file-entry-cache/6.0.0:
|
||||||
resolution: {integrity: sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==}
|
resolution: {integrity: sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -11097,6 +11412,15 @@ packages:
|
|||||||
micromatch: 3.1.10
|
micromatch: 3.1.10
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/flat-cache/2.0.1:
|
||||||
|
resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
flatted: 2.0.2
|
||||||
|
rimraf: 2.6.3
|
||||||
|
write: 1.0.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
/flat-cache/3.0.4:
|
/flat-cache/3.0.4:
|
||||||
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -11105,6 +11429,10 @@ packages:
|
|||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/flatted/2.0.2:
|
||||||
|
resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/flatted/3.1.1:
|
/flatted/3.1.1:
|
||||||
resolution: {integrity: sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==}
|
resolution: {integrity: sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -11116,7 +11444,7 @@ packages:
|
|||||||
readable-stream: 2.3.7
|
readable-stream: 2.3.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/follow-redirects/1.14.2_debug@4.3.2:
|
/follow-redirects/1.14.2:
|
||||||
resolution: {integrity: sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==}
|
resolution: {integrity: sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==}
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -11124,8 +11452,6 @@ packages:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
debug:
|
debug:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
|
||||||
debug: 4.3.2_supports-color@6.1.0
|
|
||||||
|
|
||||||
/for-each/0.3.3:
|
/for-each/0.3.3:
|
||||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
@ -11406,6 +11732,11 @@ packages:
|
|||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/get-port/3.2.0:
|
||||||
|
resolution: {integrity: sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/get-port/5.1.1:
|
/get-port/5.1.1:
|
||||||
resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
|
resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -12154,7 +12485,7 @@ packages:
|
|||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
eventemitter3: 4.0.7
|
eventemitter3: 4.0.7
|
||||||
follow-redirects: 1.14.2_debug@4.3.2
|
follow-redirects: 1.14.2
|
||||||
requires-port: 1.0.0
|
requires-port: 1.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
@ -12364,6 +12695,25 @@ packages:
|
|||||||
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
|
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/inquirer/7.3.3:
|
||||||
|
resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==}
|
||||||
|
engines: {node: '>=8.0.0'}
|
||||||
|
dependencies:
|
||||||
|
ansi-escapes: 4.3.2
|
||||||
|
chalk: 4.1.2
|
||||||
|
cli-cursor: 3.1.0
|
||||||
|
cli-width: 3.0.0
|
||||||
|
external-editor: 3.1.0
|
||||||
|
figures: 3.2.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
mute-stream: 0.0.8
|
||||||
|
run-async: 2.4.1
|
||||||
|
rxjs: 6.6.7
|
||||||
|
string-width: 4.2.2
|
||||||
|
strip-ansi: 6.0.0
|
||||||
|
through: 2.3.8
|
||||||
|
dev: true
|
||||||
|
|
||||||
/internal-ip/4.3.0:
|
/internal-ip/4.3.0:
|
||||||
resolution: {integrity: sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==}
|
resolution: {integrity: sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -13963,6 +14313,11 @@ packages:
|
|||||||
json5: 2.2.0
|
json5: 2.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/local-access/1.1.0:
|
||||||
|
resolution: {integrity: sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/locate-path/2.0.0:
|
/locate-path/2.0.0:
|
||||||
resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=}
|
resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -14588,6 +14943,10 @@ packages:
|
|||||||
thunky: 1.1.0
|
thunky: 1.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/mute-stream/0.0.8:
|
||||||
|
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/nan/2.15.0:
|
/nan/2.15.0:
|
||||||
resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==}
|
resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -15133,6 +15492,11 @@ packages:
|
|||||||
resolution: {integrity: sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=}
|
resolution: {integrity: sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/os-tmpdir/1.0.2:
|
||||||
|
resolution: {integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/overlayscrollbars/1.13.1:
|
/overlayscrollbars/1.13.1:
|
||||||
resolution: {integrity: sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ==}
|
resolution: {integrity: sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -16459,7 +16823,6 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
preact: 10.5.14
|
preact: 10.5.14
|
||||||
pretty-format: 3.8.0
|
pretty-format: 3.8.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/preact-router/3.2.1_preact@10.5.14:
|
/preact-router/3.2.1_preact@10.5.14:
|
||||||
resolution: {integrity: sha512-KEN2VN1DxUlTwzW5IFkF13YIA2OdQ2OvgJTkQREF+AA2NrHRLaGbB68EjS4IeZOa1shvQ1FvEm3bSLta4sXBhg==}
|
resolution: {integrity: sha512-KEN2VN1DxUlTwzW5IFkF13YIA2OdQ2OvgJTkQREF+AA2NrHRLaGbB68EjS4IeZOa1shvQ1FvEm3bSLta4sXBhg==}
|
||||||
@ -16533,7 +16896,6 @@ packages:
|
|||||||
|
|
||||||
/pretty-format/3.8.0:
|
/pretty-format/3.8.0:
|
||||||
resolution: {integrity: sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U=}
|
resolution: {integrity: sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U=}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/pretty-hrtime/1.0.3:
|
/pretty-hrtime/1.0.3:
|
||||||
resolution: {integrity: sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=}
|
resolution: {integrity: sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=}
|
||||||
@ -17248,6 +17610,11 @@ packages:
|
|||||||
define-properties: 1.1.3
|
define-properties: 1.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/regexpp/2.0.1:
|
||||||
|
resolution: {integrity: sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==}
|
||||||
|
engines: {node: '>=6.5.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/regexpp/3.1.0:
|
/regexpp/3.1.0:
|
||||||
resolution: {integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==}
|
resolution: {integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -17553,6 +17920,13 @@ packages:
|
|||||||
resolution: {integrity: sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=}
|
resolution: {integrity: sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rimraf/2.6.3:
|
||||||
|
resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
glob: 7.1.7
|
||||||
|
dev: true
|
||||||
|
|
||||||
/rimraf/2.7.1:
|
/rimraf/2.7.1:
|
||||||
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
|
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -17708,6 +18082,11 @@ packages:
|
|||||||
engines: {node: 6.* || >= 7.*}
|
engines: {node: 6.* || >= 7.*}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/run-async/2.4.1:
|
||||||
|
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
||||||
|
engines: {node: '>=0.12.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/run-parallel/1.2.0:
|
/run-parallel/1.2.0:
|
||||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -17720,6 +18099,13 @@ packages:
|
|||||||
aproba: 1.2.0
|
aproba: 1.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rxjs/6.6.7:
|
||||||
|
resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==}
|
||||||
|
engines: {npm: '>=2.0.0'}
|
||||||
|
dependencies:
|
||||||
|
tslib: 1.14.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/sade/1.7.4:
|
/sade/1.7.4:
|
||||||
resolution: {integrity: sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==}
|
resolution: {integrity: sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@ -17837,6 +18223,11 @@ packages:
|
|||||||
node-forge: 0.10.0
|
node-forge: 0.10.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/semiver/1.1.0:
|
||||||
|
resolution: {integrity: sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/semver-diff/3.1.1:
|
/semver-diff/3.1.1:
|
||||||
resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
|
resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -18075,6 +18466,21 @@ packages:
|
|||||||
is-arrayish: 0.3.2
|
is-arrayish: 0.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/sirv-cli/1.0.14:
|
||||||
|
resolution: {integrity: sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
console-clear: 1.1.1
|
||||||
|
get-port: 3.2.0
|
||||||
|
kleur: 3.0.3
|
||||||
|
local-access: 1.1.0
|
||||||
|
sade: 1.7.4
|
||||||
|
semiver: 1.1.0
|
||||||
|
sirv: 1.0.14
|
||||||
|
tinydate: 1.3.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/sirv/1.0.14:
|
/sirv/1.0.14:
|
||||||
resolution: {integrity: sha512-czTFDFjK9lXj0u9mJ3OmJoXFztoilYS+NdRPcJoT182w44wSEkHSiO7A2517GLJ8wKM4GjCm2OXE66Dhngbzjg==}
|
resolution: {integrity: sha512-czTFDFjK9lXj0u9mJ3OmJoXFztoilYS+NdRPcJoT182w44wSEkHSiO7A2517GLJ8wKM4GjCm2OXE66Dhngbzjg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@ -18116,6 +18522,15 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/slice-ansi/2.1.0:
|
||||||
|
resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: 3.2.1
|
||||||
|
astral-regex: 1.0.0
|
||||||
|
is-fullwidth-code-point: 2.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/slice-ansi/3.0.0:
|
/slice-ansi/3.0.0:
|
||||||
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
|
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -18797,6 +19212,16 @@ packages:
|
|||||||
object.getownpropertydescriptors: 2.1.2
|
object.getownpropertydescriptors: 2.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/table/5.4.6:
|
||||||
|
resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
ajv: 6.12.6
|
||||||
|
lodash: 4.17.21
|
||||||
|
slice-ansi: 2.1.0
|
||||||
|
string-width: 3.1.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/table/6.0.7:
|
/table/6.0.7:
|
||||||
resolution: {integrity: sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==}
|
resolution: {integrity: sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
@ -18971,6 +19396,10 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/through/2.3.8:
|
||||||
|
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/through2/2.0.5:
|
/through2/2.0.5:
|
||||||
resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
|
resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -19006,6 +19435,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/tinydate/1.3.0:
|
||||||
|
resolution: {integrity: sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/tmp/0.0.33:
|
||||||
|
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
|
||||||
|
engines: {node: '>=0.6.0'}
|
||||||
|
dependencies:
|
||||||
|
os-tmpdir: 1.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tmpl/1.0.4:
|
/tmpl/1.0.4:
|
||||||
resolution: {integrity: sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=}
|
resolution: {integrity: sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=}
|
||||||
dev: true
|
dev: true
|
||||||
@ -19171,6 +19612,16 @@ packages:
|
|||||||
/tslib/2.3.1:
|
/tslib/2.3.1:
|
||||||
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||||
|
|
||||||
|
/tsutils/3.19.1_typescript@3.9.10:
|
||||||
|
resolution: {integrity: sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
|
||||||
|
dependencies:
|
||||||
|
tslib: 1.14.1
|
||||||
|
typescript: 3.9.10
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tsutils/3.19.1_typescript@4.1.3:
|
/tsutils/3.19.1_typescript@4.1.3:
|
||||||
resolution: {integrity: sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==}
|
resolution: {integrity: sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@ -19293,6 +19744,12 @@ packages:
|
|||||||
typescript: 4.1.3
|
typescript: 4.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/typescript/3.9.10:
|
||||||
|
resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==}
|
||||||
|
engines: {node: '>=4.2.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/typescript/4.1.3:
|
/typescript/4.1.3:
|
||||||
resolution: {integrity: sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==}
|
resolution: {integrity: sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==}
|
||||||
engines: {node: '>=4.2.0'}
|
engines: {node: '>=4.2.0'}
|
||||||
@ -20363,6 +20820,13 @@ packages:
|
|||||||
typedarray-to-buffer: 3.1.5
|
typedarray-to-buffer: 3.1.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/write/1.0.3:
|
||||||
|
resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
mkdirp: 0.5.5
|
||||||
|
dev: true
|
||||||
|
|
||||||
/ws/6.2.2:
|
/ws/6.2.2:
|
||||||
resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==}
|
resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user