commit 2d6f79e1922121945b620fa9c4386319a2e389dc parent eec30d10621905c72c5245bd3d89df43a1736453 Author: Florian Dold <florian@dold.me> Date: Fri, 15 May 2026 21:41:49 +0200 format via prettier Diffstat:
414 files changed, 3920 insertions(+), 3075 deletions(-)
diff --git a/packages/aml-backoffice-ui/src/Routing.tsx b/packages/aml-backoffice-ui/src/Routing.tsx @@ -169,7 +169,7 @@ function PrivateRouting({ officer }: { officer: OfficerReady }): VNode { case "decide": { return ( <DecisionWizard - officer={officer} + officer={officer} account={location.values.cid} formId={ location.params.formId ? location.params.formId[0] : undefined @@ -198,7 +198,7 @@ function PrivateRouting({ officer }: { officer: OfficerReady }): VNode { case "decideWithStep": { return ( <DecisionWizard - officer={officer} + officer={officer} account={location.values.cid} formId={ location.params.formId ? location.params.formId[0] : undefined @@ -228,7 +228,7 @@ function PrivateRouting({ officer }: { officer: OfficerReady }): VNode { case "decideNew": { return ( <DecisionWizard - officer={officer} + officer={officer} account={location.values.cid} newPayto={decodeCrockFromURI(location.values.payto)} formId={ @@ -260,7 +260,7 @@ function PrivateRouting({ officer }: { officer: OfficerReady }): VNode { return ( <DecisionWizard account={location.values.cid} - officer={officer} + officer={officer} newPayto={decodeCrockFromURI(location.values.payto)} formId={ location.params.formId ? location.params.formId[0] : undefined diff --git a/packages/aml-backoffice-ui/src/components/HandleAccountNotReady.tsx b/packages/aml-backoffice-ui/src/components/HandleAccountNotReady.tsx @@ -25,11 +25,11 @@ export function HandleSessionNotReady({ officer: OfficerNotReady; }): VNode { if (officer.state === "not-found") { - return <CreateSession officer={officer}/>; + return <CreateSession officer={officer} />; } if (officer.state === "locked") { - return <UnlockSession officer={officer}/>; + return <UnlockSession officer={officer} />; } assertUnreachable(officer); } diff --git a/packages/aml-backoffice-ui/src/components/MeasureList.tsx b/packages/aml-backoffice-ui/src/components/MeasureList.tsx @@ -89,9 +89,7 @@ export function MeasureList({ routeToNew }: { routeToNew: RouteDefinition }) { } } - const ms = computeMeasureInformation( - measures.body, - ); + const ms = computeMeasureInformation(measures.body); return ( <div> diff --git a/packages/aml-backoffice-ui/src/components/NewMeasure.tsx b/packages/aml-backoffice-ui/src/components/NewMeasure.tsx @@ -574,8 +574,8 @@ const formDesign = ( ? !form.check ? i18n.str`Missing check or program` : undefined - : programAndCheckMatch(i18n, summary, value, form.check) ?? - programAndContextMatch(i18n, summary, value, form.context); + : (programAndCheckMatch(i18n, summary, value, form.check) ?? + programAndContextMatch(i18n, summary, value, form.context)); }, }, { diff --git a/packages/aml-backoffice-ui/src/hooks/officer.ts b/packages/aml-backoffice-ui/src/hooks/officer.ts @@ -52,7 +52,7 @@ interface OfficerCompatible { /** * @deprecated * use session - * + * * remove when not used anymore, since 2026-04 */ account: LockedAccount | undefined; diff --git a/packages/aml-backoffice-ui/src/hooks/server-info.ts b/packages/aml-backoffice-ui/src/hooks/server-info.ts @@ -24,7 +24,7 @@ import { OperationOk, opFixedSuccess, TalerExchangeResultByMethod2, - TalerHttpError + TalerHttpError, } from "@gnu-taler/taler-util"; // FIX default import https://github.com/microsoft/TypeScript/issues/49189 import { useExchangeApiContext } from "@gnu-taler/web-util/browser"; diff --git a/packages/aml-backoffice-ui/src/pages/AccountDetails.tsx b/packages/aml-backoffice-ui/src/pages/AccountDetails.tsx @@ -197,7 +197,8 @@ export function AccountDetails({ const time = format(new Date(), "yyyyMMdd_HHmmss"); - const downloadPdf = safeFunctionHandler(i18n.str`download pdf`, + const downloadPdf = safeFunctionHandler( + i18n.str`download pdf`, lib.exchange.getAmlAttributesForAccountAsPdf.bind(lib.exchange), session ? [session, account] : undefined, ); @@ -210,10 +211,10 @@ export function AccountDetails({ file: `account_${time}_${account}.pdf`, }); }; - downloadPdf.onFail = (fail) =>{ - switch(fail.case) { + downloadPdf.onFail = (fail) => { + switch (fail.case) { case HttpStatusCode.NoContent: - return i18n.str`The account has no KYC info.` + return i18n.str`The account has no KYC info.`; case HttpStatusCode.Forbidden: return i18n.str`Invalid session.`; case HttpStatusCode.NotFound: @@ -225,7 +226,7 @@ export function AccountDetails({ default: assertUnreachable(fail.case); } - } + }; return ( <div class="min-w-60"> diff --git a/packages/aml-backoffice-ui/src/pages/AccountList.tsx b/packages/aml-backoffice-ui/src/pages/AccountList.tsx @@ -168,14 +168,15 @@ export function AccountList({ : `not-investigated`; const time = format(new Date(), "yyyyMMdd_HHmmss"); - const downloadCsv = safeFunctionHandler(i18n.str`download csv`, + const downloadCsv = safeFunctionHandler( + i18n.str`download csv`, lib.exchange.getAmlAccountsAsOtherFormat.bind(lib.exchange), session ? [session, "text/csv"] : undefined, ); downloadCsv.onFail = (fail) => { - switch(fail.case) { + switch (fail.case) { case HttpStatusCode.NoContent: - return i18n.str`Ther are no accounts in the resultset.` + return i18n.str`Ther are no accounts in the resultset.`; case HttpStatusCode.Forbidden: return i18n.str`Invalid session.`; case HttpStatusCode.NotFound: @@ -183,15 +184,16 @@ export function AccountList({ case HttpStatusCode.Conflict: return i18n.str`The session is disabled. Contact the administrator`; } - } - const downloadXls = safeFunctionHandler(i18n.str`download xls`, + }; + const downloadXls = safeFunctionHandler( + i18n.str`download xls`, lib.exchange.getAmlAccountsAsOtherFormat.bind(lib.exchange), session ? [session, "application/vnd.ms-excel"] : undefined, ); downloadXls.onFail = (fail) => { - switch(fail.case) { + switch (fail.case) { case HttpStatusCode.NoContent: - return i18n.str`Ther are no accounts in the resultset.` + return i18n.str`Ther are no accounts in the resultset.`; case HttpStatusCode.Forbidden: return i18n.str`Invalid session.`; case HttpStatusCode.NotFound: @@ -199,7 +201,7 @@ export function AccountList({ case HttpStatusCode.Conflict: return i18n.str`The session is disabled. Contact the administrator`; } - } + }; downloadCsv.onSuccess = (result) => { setExported({ diff --git a/packages/aml-backoffice-ui/src/pages/Dashboard.tsx b/packages/aml-backoffice-ui/src/pages/Dashboard.tsx @@ -70,7 +70,11 @@ function EventMetrics(): VNode { AmlSpaDialect.TESTING; if (dialect === "gls") { - return <div>No dashboard configured for dialect <code>gls</code>.</div>; + return ( + <div> + No dashboard configured for dialect <code>gls</code>. + </div> + ); } const resp = useTopsServerStatistics(); diff --git a/packages/anastasis-core/src/crypto.ts b/packages/anastasis-core/src/crypto.ts @@ -72,11 +72,11 @@ export async function userIdentifierDerive( const canonIdData = canonicalJson(idData); const hashInput = stringToBytes(canonIdData); const result = await hashArgon2id( - hashInput, // password + hashInput, // password decodeCrock(serverSalt), // salt - 3, // iterations - 1024, // memoryLimit (kibibytes) - 64, // hashLength + 3, // iterations + 1024, // memoryLimit (kibibytes) + 64, // hashLength ); return encodeCrock(result); } @@ -346,11 +346,11 @@ export async function secureAnswerHash( questionSalt: TruthSalt, ): Promise<SecureAnswerHash> { const powResult = await hashArgon2id( - stringToBytes(answer), // password + stringToBytes(answer), // password decodeCrock(questionSalt), // salt - 3, // iterations - 1024, // memorySize (kibibytes) - 64, // hashLength + 3, // iterations + 1024, // memorySize (kibibytes) + 64, // hashLength ); const kdfResult = kdfKw({ outputLength: 64, diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts @@ -43,7 +43,10 @@ import { URL, j2s, } from "@gnu-taler/taler-util"; -import { HttpResponse, createPlatformHttpLib } from "@gnu-taler/taler-util/http"; +import { + HttpResponse, + createPlatformHttpLib, +} from "@gnu-taler/taler-util/http"; import { anastasisData } from "./anastasis-data.js"; import { codecForChallengeInstructionMessage, diff --git a/packages/anastasis-core/src/reducer-types.ts b/packages/anastasis-core/src/reducer-types.ts @@ -336,8 +336,7 @@ export type AuthenticationProviderStatus = | AuthenticationProviderStatusError | AuthenticationProviderStatusOk; -export interface ReducerStateBackupUserAttributesCollecting - extends ReducerStateBackup { +export interface ReducerStateBackupUserAttributesCollecting extends ReducerStateBackup { backup_state: BackupStates.UserAttributesCollecting; selected_country: string; currencies: string[]; diff --git a/packages/anastasis-core/src/validators.ts b/packages/anastasis-core/src/validators.ts @@ -4,25 +4,40 @@ function isPrime(num: number): boolean { return num > 1; } -export function AL_NID_check(s: string): boolean { return true } -export function BE_NRN_check(s: string): boolean { return true } -export function CH_AHV_check(s: string): boolean { return true } -export function CZ_BN_check(s: string): boolean { return true } -export function DE_TIN_check(s: string): boolean { return true } -export function DE_SVN_check(s: string): boolean { return true } -export function ES_DNI_check(s: string): boolean { return true } -export function IN_AADHAR_check(s: string): boolean { return true } +export function AL_NID_check(s: string): boolean { + return true; +} +export function BE_NRN_check(s: string): boolean { + return true; +} +export function CH_AHV_check(s: string): boolean { + return true; +} +export function CZ_BN_check(s: string): boolean { + return true; +} +export function DE_TIN_check(s: string): boolean { + return true; +} +export function DE_SVN_check(s: string): boolean { + return true; +} +export function ES_DNI_check(s: string): boolean { + return true; +} +export function IN_AADHAR_check(s: string): boolean { + return true; +} export function IT_CF_check(s: string): boolean { - return true + return true; } export function XX_SQUARE_check(s: string): boolean { - const n = parseInt(s, 10) - const r = Math.sqrt(n) + const n = parseInt(s, 10); + const r = Math.sqrt(n); return n === r * r; } export function XY_PRIME_check(s: string): boolean { - const n = parseInt(s, 10) - return isPrime(n) + const n = parseInt(s, 10); + return isPrime(n); } - diff --git a/packages/anastasis-webui/src/components/menu/index.tsx b/packages/anastasis-webui/src/components/menu/index.tsx @@ -85,8 +85,8 @@ export function NotificationCard({ n.type === "ERROR" ? "message is-danger" : n.type === "WARN" - ? "message is-warning" - : "message is-info" + ? "message is-warning" + : "message is-info" } > <div class="message-header"> diff --git a/packages/anastasis-webui/src/declaration.d.ts b/packages/anastasis-webui/src/declaration.d.ts @@ -33,5 +33,5 @@ declare module "jed" { const x: any; export = x; } -declare var __VERSION__ : string; -declare var __GIT_HASH__ : string; +declare var __VERSION__: string; +declare var __GIT_HASH__: string; diff --git a/packages/anastasis-webui/src/hooks/index.ts b/packages/anastasis-webui/src/hooks/index.ts @@ -71,4 +71,4 @@ export function useBackendInstanceToken( } return [token, setToken]; -} -\ No newline at end of file +} diff --git a/packages/anastasis-webui/src/index.html b/packages/anastasis-webui/src/index.html @@ -15,7 +15,7 @@ @author Sebastian Javier Marchano --> -<!DOCTYPE html> +<!doctype html> <html lang="en" class="has-aside-left has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded" @@ -26,7 +26,10 @@ <meta name="viewport" content="width=device-width,initial-scale=1" /> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> <link rel="icon" href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx @@ -241,8 +241,7 @@ export function AuthenticationEditorScreen(): VNode { </p> {authAvailableSet.size > 0 && ( <p class="block"> - We couldn't find provider for some of the authentication - methods. + We couldn't find provider for some of the authentication methods. </p> )} </div> diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx @@ -264,8 +264,8 @@ export function ChallengeOverviewScreen(): VNode { const opa = !atLeastThereIsOnePolicySolved ? undefined : policy.isPolicySolved - ? undefined - : "0.6"; + ? undefined + : "0.6"; return ( <div diff --git a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx @@ -77,7 +77,6 @@ export function EditPoliciesScreen({ const policies = reducer.currentReducerState.policies ?? []; const policy = policies[policy_index]; - function sendChanges(): void { const newMethods: MethodProvider[] = []; allAuthMethods.forEach((method, index) => { diff --git a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.tsx @@ -76,8 +76,8 @@ export function SecretEditorScreen(): VNode { const errors = !secretName ? "Add a secret name" : !secretValue && !secretFile - ? "Add a secret value or a choose a file to upload" - : undefined; + ? "Add a secret value or a choose a file to upload" + : undefined; function goNextIfNoErrors(): void { if (!errors) secretNext(); } diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx @@ -248,8 +248,8 @@ export function SolveScreen(): VNode { !selectedChallenge || !authMethods[selectedChallenge.type as KnownAuthMethods] ? SolveNotImplemented - : authMethods[selectedChallenge.type as KnownAuthMethods].solve ?? - SolveNotImplemented; + : (authMethods[selectedChallenge.type as KnownAuthMethods].solve ?? + SolveNotImplemented); return <SolveDialog id={selectedUuid} />; } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx @@ -49,8 +49,8 @@ export function AuthMethodIbanSetup({ const errors = !name ? "Add an account name" : !account - ? "Add an account IBAN number" - : undefined; + ? "Add an account IBAN number" + : undefined; function goNextIfNoErrors(): void { if (!errors) addIbanAuth(); } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx @@ -55,14 +55,14 @@ export function AuthMethodPostSetup({ const errors = !fullName ? "The full name is missing" : !street - ? "The street is missing" - : !city - ? "The city is missing" - : !postcode - ? "The postcode is missing" - : !country - ? "The country is missing" - : undefined; + ? "The street is missing" + : !city + ? "The city is missing" + : !postcode + ? "The postcode is missing" + : !country + ? "The country is missing" + : undefined; function goNextIfNoErrors(): void { if (!errors) addPostAuth(); diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx @@ -39,8 +39,8 @@ export function AuthMethodQuestionSetup({ const errors = !questionText ? "Add your security question" : !answerText - ? "Add the answer to your question" - : undefined; + ? "Add the answer to your question" + : undefined; function goNextIfNoErrors(): void { if (!errors) addQuestionAuth(); } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx @@ -48,10 +48,10 @@ export function AuthMethodSmsSetup({ const errors = !mobileNumber ? "Add a mobile number" : !mobileNumber.startsWith("+") - ? "Mobile number should start with '+'" - : !isJustNumbers(mobileNumber) - ? "Mobile number can't have other than numbers" - : undefined; + ? "Mobile number should start with '+'" + : !isJustNumbers(mobileNumber) + ? "Mobile number can't have other than numbers" + : undefined; function goNextIfNoErrors(): void { if (!errors) addSmsAuth(); } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx @@ -57,8 +57,8 @@ export function AuthMethodTotpSetup({ const errors = !name ? "The TOTP name is missing" : !testCodeMatches - ? "The test code doesn't match" - : undefined; + ? "The test code doesn't match" + : undefined; function goNextIfNoErrors(): void { if (!errors) addTotpAuth(); } diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx @@ -60,7 +60,7 @@ const ALL_METHODS = [ "totp", "iban", ] as const; -export type KnownAuthMethods = typeof ALL_METHODS[number]; +export type KnownAuthMethods = (typeof ALL_METHODS)[number]; export function isKnownAuthMethods(value: string): value is KnownAuthMethods { return ALL_METHODS.includes(value as KnownAuthMethods); } diff --git a/packages/anastasis-webui/src/scss/_custom-calendar.scss b/packages/anastasis-webui/src/scss/_custom-calendar.scss @@ -30,14 +30,14 @@ --primary-card-color: #fff; --primary-background-color: #f2f2f2; - --box-shadow-lvl-1: 0 1px 3px rgba(0, 0, 0, 0.12), - 0 1px 2px rgba(0, 0, 0, 0.24); - --box-shadow-lvl-2: 0 3px 6px rgba(0, 0, 0, 0.16), - 0 3px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-3: 0 10px 20px rgba(0, 0, 0, 0.19), - 0 6px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-4: 0 14px 28px rgba(0, 0, 0, 0.25), - 0 10px 10px rgba(0, 0, 0, 0.22); + --box-shadow-lvl-1: + 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + --box-shadow-lvl-2: + 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-3: + 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-4: + 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } .home .datePicker div { @@ -55,7 +55,9 @@ width: 90vw; max-width: 448px; transform-origin: top left; - transition: transform 0.22s ease-in-out, opacity 0.22s ease-in-out; + transition: + transform 0.22s ease-in-out, + opacity 0.22s ease-in-out; top: 50%; left: 50%; opacity: 0; @@ -176,7 +178,9 @@ left: calc(50% - 21px); background: var(--primary-color); border-radius: 50%; - transition: transform 0.22s, opacity 0.22s; + transition: + transform 0.22s, + opacity 0.22s; transform: scale(0); opacity: 0; } diff --git a/packages/auditor-backoffice-ui/src/components/menu/SideBar.tsx b/packages/auditor-backoffice-ui/src/components/menu/SideBar.tsx @@ -28,7 +28,10 @@ export function Sidebar(props: any): VNode { console.log(configData); return ( - <aside class="aside is-placed-left is-expanded" style={{ overflowY: "scroll" }}> + <aside + class="aside is-placed-left is-expanded" + style={{ overflowY: "scroll" }} + > <div class="aside-tools"> <div class="aside-tools-label"> <div> @@ -47,52 +50,52 @@ export function Sidebar(props: any): VNode { <ul class="menu-list"> <li> <a href={"/key-figures"} class="has-icon"> - <span class="icon"> - <i class="mdi mdi-bank" /> - </span> + <span class="icon"> + <i class="mdi mdi-bank" /> + </span> <span class="menu-item-label"> - <i18n.Translate>Key figures</i18n.Translate> - </span> + <i18n.Translate>Key figures</i18n.Translate> + </span> </a> </li> <li> <a href={"/critical-errors"} class="has-icon"> - <span class="icon"> - <i class="mdi mdi-alert" /> - </span> + <span class="icon"> + <i class="mdi mdi-alert" /> + </span> <span class="menu-item-label"> - <i18n.Translate>Critical errors</i18n.Translate> - </span> + <i18n.Translate>Critical errors</i18n.Translate> + </span> </a> </li> <li> <a href={"/operating-status"} class="has-icon"> - <span class="icon"> - <i class="mdi mdi-close-network" /> - </span> + <span class="icon"> + <i class="mdi mdi-close-network" /> + </span> <span class="menu-item-label"> - <i18n.Translate>Operating status</i18n.Translate> - </span> + <i18n.Translate>Operating status</i18n.Translate> + </span> </a> </li> <li> <a href={"/detail-view"} class="has-icon"> - <span class="icon"> - <i class="mdi mdi-format-wrap-tight" /> - </span> + <span class="icon"> + <i class="mdi mdi-format-wrap-tight" /> + </span> <span class="menu-item-label"> - <i18n.Translate>Inconsistencies</i18n.Translate> - </span> + <i18n.Translate>Inconsistencies</i18n.Translate> + </span> </a> </li> <li> <a href={"/settings"} class="has-icon"> - <span class="icon"> - <i class="mdi mdi-square-edit-outline" /> - </span> + <span class="icon"> + <i class="mdi mdi-square-edit-outline" /> + </span> <span class="menu-item-label"> - <i18n.Translate>Settings</i18n.Translate> - </span> + <i18n.Translate>Settings</i18n.Translate> + </span> </a> </li> </ul> @@ -100,4 +103,4 @@ export function Sidebar(props: any): VNode { </div> </aside> ); -} -\ No newline at end of file +} diff --git a/packages/auditor-backoffice-ui/src/context/config.ts b/packages/auditor-backoffice-ui/src/context/config.ts @@ -26,4 +26,5 @@ import { AuditorBackend } from "../declaration.js"; const Context = createContext<AuditorBackend.VersionResponse>(null!); export const ConfigContextProvider = Context.Provider; -export const useConfigContext = (): AuditorBackend.VersionResponse => useContext(Context); +export const useConfigContext = (): AuditorBackend.VersionResponse => + useContext(Context); diff --git a/packages/auditor-backoffice-ui/src/context/entity.ts b/packages/auditor-backoffice-ui/src/context/entity.ts @@ -44,4 +44,5 @@ const EntityDataContext = createContext<EntityDataType>({} as any); export const EntityDataContextProvider = EntityDataContext.Provider; -export const useEntityDataContext = (): EntityDataType => useContext(EntityDataContext); +export const useEntityDataContext = (): EntityDataType => + useContext(EntityDataContext); diff --git a/packages/auditor-backoffice-ui/src/hooks/useSettings.ts b/packages/auditor-backoffice-ui/src/hooks/useSettings.ts @@ -32,24 +32,24 @@ export interface Settings { const defaultSettings: Settings = { advanceOrderMode: false, dateFormat: "ymd", -} +}; export const codecForSettings = (): Codec<Settings> => buildCodecForObject<Settings>() .property("advanceOrderMode", codecForBoolean()) - .property("dateFormat", codecForEither( - codecForConstString("ymd"), - codecForConstString("dmy"), - codecForConstString("mdy"), - )) + .property( + "dateFormat", + codecForEither( + codecForConstString("ymd"), + codecForConstString("dmy"), + codecForConstString("mdy"), + ), + ) .build("Settings"); const SETTINGS_KEY = buildStorageKey("merchant-settings", codecForSettings()); -export function useSettings(): [ - Readonly<Settings>, - (s: Settings) => void, -] { +export function useSettings(): [Readonly<Settings>, (s: Settings) => void] { const { value, update } = useLocalStorage(SETTINGS_KEY, defaultSettings); // const parsed: Settings = value ?? defaultSettings; @@ -62,12 +62,15 @@ export function useSettings(): [ export function dateFormatForSettings(s: Settings): string { switch (s.dateFormat) { - case "ymd": return "yyyy/MM/dd" - case "dmy": return "dd/MM/yyyy" - case "mdy": return "MM/dd/yyyy" + case "ymd": + return "yyyy/MM/dd"; + case "dmy": + return "dd/MM/yyyy"; + case "mdy": + return "MM/dd/yyyy"; } } export function datetimeFormatForSettings(s: Settings): string { - return dateFormatForSettings(s) + " HH:mm:ss" -} -\ No newline at end of file + return dateFormatForSettings(s) + " HH:mm:ss"; +} diff --git a/packages/auditor-backoffice-ui/src/index.html b/packages/auditor-backoffice-ui/src/index.html @@ -15,7 +15,7 @@ @author Sebastian Javier Marchano --> -<!DOCTYPE html> +<!doctype html> <html lang="en" class="has-aside-left has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded" diff --git a/packages/auditor-backoffice-ui/src/scss/_custom-calendar.scss b/packages/auditor-backoffice-ui/src/scss/_custom-calendar.scss @@ -30,14 +30,14 @@ --primary-card-color: #fff; --primary-background-color: #f2f2f2; - --box-shadow-lvl-1: 0 1px 3px rgba(0, 0, 0, 0.12), - 0 1px 2px rgba(0, 0, 0, 0.24); - --box-shadow-lvl-2: 0 3px 6px rgba(0, 0, 0, 0.16), - 0 3px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-3: 0 10px 20px rgba(0, 0, 0, 0.19), - 0 6px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-4: 0 14px 28px rgba(0, 0, 0, 0.25), - 0 10px 10px rgba(0, 0, 0, 0.22); + --box-shadow-lvl-1: + 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + --box-shadow-lvl-2: + 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-3: + 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-4: + 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } .datePicker { @@ -51,7 +51,9 @@ width: 90vw; max-width: 448px; transform-origin: top left; - transition: transform 0.22s ease-in-out, opacity 0.22s ease-in-out; + transition: + transform 0.22s ease-in-out, + opacity 0.22s ease-in-out; top: 50%; left: 50%; opacity: 0; @@ -172,7 +174,9 @@ left: calc(50% - 21px); background: var(--primary-color); border-radius: 50%; - transition: transform 0.22s, opacity 0.22s; + transition: + transform 0.22s, + opacity 0.22s; transform: scale(0); opacity: 0; } diff --git a/packages/auditor-backoffice-ui/src/scss/main.scss b/packages/auditor-backoffice-ui/src/scss/main.scss @@ -84,7 +84,7 @@ $tooltip-color: red; pointer-events: none; } -.toast>.message { +.toast > .message { white-space: pre-wrap; opacity: 80%; } @@ -107,7 +107,7 @@ div { } } -input[type="checkbox"]:indeterminate+.check { +input[type="checkbox"]:indeterminate + .check { background: red !important; } @@ -185,11 +185,11 @@ div[data-tooltip]::before { position: absolute; } -.modal-card-body>p { +.modal-card-body > p { padding: 1em; } -.modal-card-body>p.warning { +.modal-card-body > p.warning { background-color: #fffbdd; border: solid 1px #f2e9bf; -} -\ No newline at end of file +} diff --git a/packages/bank-ui/src/components/Cashouts/index.ts b/packages/bank-ui/src/components/Cashouts/index.ts @@ -21,7 +21,12 @@ import { TalerCorebankApi, TalerError, } from "@gnu-taler/taler-util"; -import { ErrorLoading, Loading, RouteDefinition, utils } from "@gnu-taler/web-util/browser"; +import { + ErrorLoading, + Loading, + RouteDefinition, + utils, +} from "@gnu-taler/web-util/browser"; import { VNode } from "preact"; import { useComponentState } from "./state.js"; diff --git a/packages/bank-ui/src/components/Cashouts/state.ts b/packages/bank-ui/src/components/Cashouts/state.ts @@ -46,6 +46,6 @@ export function useComponentState({ status: "ready", error: undefined, cashouts: result.body.cashouts, - routeCashoutDetails + routeCashoutDetails, }; } diff --git a/packages/bank-ui/src/components/Cashouts/views.tsx b/packages/bank-ui/src/components/Cashouts/views.tsx @@ -34,7 +34,6 @@ import { Fragment, VNode, h } from "preact"; import { State } from "./index.js"; import { useConversionInfo } from "../../hooks/regional.js"; - const TALER_SCREEN_ID = 3; export function FailedView({ error }: State.Failed) { diff --git a/packages/bank-ui/src/components/Transactions/index.ts b/packages/bank-ui/src/components/Transactions/index.ts @@ -15,7 +15,12 @@ */ import { AbsoluteTime, AmountJson, TalerError } from "@gnu-taler/taler-util"; -import { ErrorLoading, Loading, RouteDefinition, utils } from "@gnu-taler/web-util/browser"; +import { + ErrorLoading, + Loading, + RouteDefinition, + utils, +} from "@gnu-taler/web-util/browser"; import { VNode } from "preact"; import { useComponentState } from "./state.js"; diff --git a/packages/bank-ui/src/components/Transactions/views.tsx b/packages/bank-ui/src/components/Transactions/views.tsx @@ -232,7 +232,8 @@ export function ReadyView({ aria-label="Pagination" > <div class="flex flex-1 justify-between sm:justify-end"> - <button type="button" + <button + type="button" name="first page" class="relative disabled:bg-gray-100 disabled:text-gray-500 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!onGoStart} @@ -240,7 +241,8 @@ export function ReadyView({ > <i18n.Translate>First page</i18n.Translate> </button> - <button type="button" + <button + type="button" name="next page" class="relative disabled:bg-gray-100 disabled:text-gray-500 ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!onGoNext} diff --git a/packages/bank-ui/src/hooks/bank-state.ts b/packages/bank-ui/src/hooks/bank-state.ts @@ -33,7 +33,6 @@ import { useLocalStorage, } from "@gnu-taler/web-util/browser"; - export type ChallengeInProgess = | LoginChallenge | DeleteAccountChallenge diff --git a/packages/bank-ui/src/hooks/form.ts b/packages/bank-ui/src/hooks/form.ts @@ -72,7 +72,6 @@ function constructFormHandler<T>( updateForm: (d: FormValues<T>) => void, errors: FormErrors<T> | undefined, ): FormHandler<T> { - const keys = Object.keys(form) as Array<keyof T>; const handler = keys.reduce((prev, fieldName) => { @@ -105,11 +104,11 @@ function constructFormHandler<T>( /** * FIXME: Consider sending this to web-utils - * - * - * @param defaultValue - * @param check - * @returns + * + * + * @param defaultValue + * @param check + * @returns */ export function useFormState<T>( defaultValue: FormValues<T>, diff --git a/packages/bank-ui/src/hooks/regional.ts b/packages/bank-ui/src/hooks/regional.ts @@ -31,7 +31,7 @@ import { TalerHttpError, TokenAuth, assertUnreachable, - opFixedSuccess + opFixedSuccess, } from "@gnu-taler/taler-util"; import { useBankCoreApiContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; @@ -108,7 +108,7 @@ export function useConversionRateForUser( async function fetcher() { return await conversionForUser(username).getRate( - token != null ? { type: "bearer", token } : undefined + token != null ? { type: "bearer", token } : undefined, ); } const { data, error } = useSWR< @@ -145,7 +145,8 @@ function buildEstimatorWithTheBackend( | "cashout-rate-from-debit", ): EstimatorFunction { return async (amount, fee) => { - const auth: TokenAuth | undefined = token != null ? { type: "bearer", token } : undefined; + const auth: TokenAuth | undefined = + token != null ? { type: "bearer", token } : undefined; let resp; switch (estimation) { case "cashin-rate-from-credit": { diff --git a/packages/bank-ui/src/index.html b/packages/bank-ui/src/index.html @@ -24,7 +24,10 @@ <meta name="taler-support" content="uri,api" /> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> <link rel="icon" href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" diff --git a/packages/bank-ui/src/pages/AccountPage/index.ts b/packages/bank-ui/src/pages/AccountPage/index.ts @@ -20,7 +20,12 @@ import { TalerCorebankApi, TalerError, } from "@gnu-taler/taler-util"; -import { ErrorLoading, Loading, RouteDefinition, utils } from "@gnu-taler/web-util/browser"; +import { + ErrorLoading, + Loading, + RouteDefinition, + utils, +} from "@gnu-taler/web-util/browser"; import { Fragment, VNode } from "preact"; import { LoginForm } from "../LoginForm.js"; diff --git a/packages/bank-ui/src/pages/BankFrame.tsx b/packages/bank-ui/src/pages/BankFrame.tsx @@ -168,39 +168,38 @@ export function BankFrame({ </div> </li> ); - })} <li class="pl-2"> - <div class="flex items-center justify-between"> - <span class="flex flex-grow flex-col"> - <span - class="text-sm text-black font-medium leading-6 " - id="availability-label" - > - <i18n.Translate>Show debug information</i18n.Translate> - </span> - </span> - <button - type="button" - name={`debug switch`} - data-enabled={showDebugInfo} - class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" - role="switch" - aria-checked="false" - aria-labelledby="availability-label" - aria-describedby="availability-description" - onClick={() => { - update("showDebugInfo", !showDebugInfo) - }} - > - <span - aria-hidden="true" - data-enabled={showDebugInfo} - class="translate-x-5 data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out" - ></span> - </button> - </div> - </li> + <div class="flex items-center justify-between"> + <span class="flex flex-grow flex-col"> + <span + class="text-sm text-black font-medium leading-6 " + id="availability-label" + > + <i18n.Translate>Show debug information</i18n.Translate> + </span> + </span> + <button + type="button" + name={`debug switch`} + data-enabled={showDebugInfo} + class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" + role="switch" + aria-checked="false" + aria-labelledby="availability-label" + aria-describedby="availability-description" + onClick={() => { + update("showDebugInfo", !showDebugInfo); + }} + > + <span + aria-hidden="true" + data-enabled={showDebugInfo} + class="translate-x-5 data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out" + ></span> + </button> + </div> + </li> </ul> </li> </Header> @@ -346,7 +345,8 @@ function AppActivity(): VNode { <p class="ml-2 my-auto text-sm text-gray-500">{lastEvent.url}</p> {!status ? ( - <button type="button" + <button + type="button" onClick={() => { if (cancelRequest) cancelRequest(lastEvent.id); }} diff --git a/packages/bank-ui/src/pages/ConversionRateClassDetails.tsx b/packages/bank-ui/src/pages/ConversionRateClassDetails.tsx @@ -165,7 +165,8 @@ function Form({ ), ); - const deleteClass = safeFunctionHandler(i18n.str`delete conversion rate class`, + const deleteClass = safeFunctionHandler( + i18n.str`delete conversion rate class`, (token: AccessToken) => lib.bank.deleteConversionRateClass(token, classId), !creds || section !== "delete" || detailsResult.num_users > 0 ? undefined @@ -205,7 +206,8 @@ function Form({ cashout_rounding_mode: status.result.conv.cashout_rounding_mode, }; - const updateClass = safeFunctionHandler(i18n.str`update conversion rate class`, + const updateClass = safeFunctionHandler( + i18n.str`update conversion rate class`, lib.bank.updateConversionRateClass.bind(lib.bank), !creds || !input ? undefined : [creds.token, classId, input], ); @@ -906,7 +908,8 @@ function TestConversionClass({ const in_fee = Amounts.parseOrThrow(info.conversion_rate.cashin_fee); const out_fee = Amounts.parseOrThrow(info.conversion_rate.cashout_fee); - const calculate = safeFunctionHandler(i18n.str`calculate cashout fee`, + const calculate = safeFunctionHandler( + i18n.str`calculate cashout fee`, async (amount: AmountJson) => { const respCashin = await calculateCashinFromDebit(amount, in_fee); if (respCashin.type === "fail") { @@ -1298,7 +1301,8 @@ function AccountsOnConversionClass({ classId }: { classId: number }): VNode { </td> <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> {classId === item.conversion_rate_class_id ? ( - <button type="button" + <button + type="button" class="disabled:opacity-50 disabled:bg-gray-600 disabled:hover:bg-gray-600 disabled:cursor-default cursor-pointer rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600" onClick={async () => { if (token) { @@ -1314,7 +1318,8 @@ function AccountsOnConversionClass({ classId }: { classId: number }): VNode { <i18n.Translate>Remove</i18n.Translate> </button> ) : ( - <button type="button" + <button + type="button" class="disabled:opacity-50 disabled:bg-gray-600 disabled:hover:bg-gray-600 disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" onClick={async () => { if (token) { @@ -1344,7 +1349,8 @@ function AccountsOnConversionClass({ classId }: { classId: number }): VNode { aria-label="Pagination" > <div class="flex flex-1 justify-between sm:justify-end"> - <button type="button" + <button + type="button" name="first page" class="relative disabled:bg-gray-100 disabled:text-gray-500 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!userListResult.loadFirst} @@ -1352,7 +1358,8 @@ function AccountsOnConversionClass({ classId }: { classId: number }): VNode { > <i18n.Translate>First page</i18n.Translate> </button> - <button type="button" + <button + type="button" name="next page" class="relative disabled:bg-gray-100 disabled:text-gray-500 ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!userListResult.loadNext} diff --git a/packages/bank-ui/src/pages/LoginForm.tsx b/packages/bank-ui/src/pages/LoginForm.tsx @@ -100,7 +100,9 @@ export function LoginForm({ [], ); logout.onSuccess = session.logOut; - logout.onFail = (fail) => { return undefined } + logout.onFail = (fail) => { + return undefined; + }; const tokenRequest = { scope: "readwrite", diff --git a/packages/bank-ui/src/pages/OperationState/index.ts b/packages/bank-ui/src/pages/OperationState/index.ts @@ -23,7 +23,12 @@ import { TalerError, WithdrawUriResult, } from "@gnu-taler/taler-util"; -import { ErrorLoading, Loading, RouteDefinition, utils } from "@gnu-taler/web-util/browser"; +import { + ErrorLoading, + Loading, + RouteDefinition, + utils, +} from "@gnu-taler/web-util/browser"; import { VNode } from "preact"; import { useComponentState } from "./state.js"; @@ -106,7 +111,7 @@ export namespace State { account: string; onAbort: () => void; - + error: undefined; details: { account: Paytos.URI; diff --git a/packages/bank-ui/src/pages/OperationState/views.tsx b/packages/bank-ui/src/pages/OperationState/views.tsx @@ -112,7 +112,7 @@ export function NeedConfirmationView({ if (!settings.showWithdrawalSuccess) { notifyInfo(i18n.str`Wire transfer completed!`); } - onAbort() + onAbort(); }; confirm.onFail = (fail) => { switch (fail.case) { diff --git a/packages/bank-ui/src/pages/PaymentOptions.tsx b/packages/bank-ui/src/pages/PaymentOptions.tsx @@ -70,7 +70,7 @@ export interface PaymentOptionProps { limit: IntAmountJson; balance: AmountJson; tab: "charge-wallet" | "wire-transfer" | undefined; - + onOperationCreated: (wopid: string) => void; onClose: () => void; @@ -100,7 +100,6 @@ export function PaymentOptions({ onOperationCreated, onClose, routeOperationDetails, - }: PaymentOptionProps): VNode { const { i18n } = useTranslationContext(); @@ -207,7 +206,6 @@ export function PaymentOptions({ focus limit={limit} balance={balance} - onOperationCreated={onOperationCreated} onOperationAborted={onClose} routeCancel={routeClose} @@ -218,7 +216,6 @@ export function PaymentOptions({ focus limit={limit} balance={balance} - onSuccess={onClose} routeCashout={routeCashout} routeCancel={routeClose} diff --git a/packages/bank-ui/src/pages/QrCodeSection.tsx b/packages/bank-ui/src/pages/QrCodeSection.tsx @@ -60,7 +60,8 @@ export function QrCodeSection({ lib: { bank: api }, } = useBankCoreApiContext(); - const abort = safeFunctionHandler(i18n.str`abort withdrawal`, + const abort = safeFunctionHandler( + i18n.str`abort withdrawal`, (creds: UserAndToken) => api.abortWithdrawalById(creds, withdrawUri.withdrawalOperationId), !creds ? undefined : [creds], diff --git a/packages/bank-ui/src/pages/RegistrationPage.tsx b/packages/bank-ui/src/pages/RegistrationPage.tsx @@ -13,7 +13,11 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { assertUnreachable, HttpStatusCode, TalerErrorCode } from "@gnu-taler/taler-util"; +import { + assertUnreachable, + HttpStatusCode, + TalerErrorCode, +} from "@gnu-taler/taler-util"; import { ButtonBetter, LocalNotificationBanner, @@ -116,7 +120,8 @@ function RegistrationForm({ password, }; - const register = safeFunctionHandler(i18n.str`register new account`, + const register = safeFunctionHandler( + i18n.str`register new account`, (account: TalerCorebankApi.RegisterAccountRequest) => api.createAccount(undefined, account), !!errors || !reg ? undefined : [reg], @@ -126,7 +131,7 @@ function RegistrationForm({ setUsername(undefined); setPassword(undefined); setRepeatPassword(undefined); - setName(undefined) + setName(undefined); onRegistrationSuccesful(acc.username, acc.password); }; diff --git a/packages/bank-ui/src/pages/SolveMFA.tsx b/packages/bank-ui/src/pages/SolveMFA.tsx @@ -329,7 +329,7 @@ export function SolveMFAChallenges({ selectChallenge.onFail = (fail) => { return undefined; }; - + return ( <Fragment> <LocalNotificationBanner notification={notification} /> diff --git a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx @@ -22,7 +22,7 @@ import { TalerUriAction, TalerUris, UserAndToken, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { Attention, @@ -45,10 +45,7 @@ import { usePreferences } from "../hooks/preferences.js"; import { useSessionState } from "../hooks/session.js"; import { undefinedIfEmpty } from "../utils.js"; import { OperationState } from "./OperationState/index.js"; -import { - InputAmount, - doAutoFocus, -} from "./PaytoWireTransferForm.js"; +import { InputAmount, doAutoFocus } from "./PaytoWireTransferForm.js"; import { IntAmountJson } from "./regional/CreateCashout.js"; const TALER_SCREEN_ID = 112; @@ -103,7 +100,8 @@ function OldWithdrawalForm({ : undefined, }); - const start = safeFunctionHandler(i18n.str`create withdrawal`, + const start = safeFunctionHandler( + i18n.str`create withdrawal`, (creds: UserAndToken, amount: AmountString) => api.createWithdrawal( creds, diff --git a/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx b/packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx @@ -13,7 +13,11 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AccessToken, assertUnreachable, TalerCorebankApi } from "@gnu-taler/taler-util"; +import { + AccessToken, + assertUnreachable, + TalerCorebankApi, +} from "@gnu-taler/taler-util"; import { ButtonBetter, LocalNotificationBanner, diff --git a/packages/bank-ui/src/pages/admin/AccountForm.tsx b/packages/bank-ui/src/pages/admin/AccountForm.tsx @@ -698,7 +698,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ type="button" name="is public" data-enabled={ - form.isPublic ?? defaultValue.isPublic ? "true" : "false" + (form.isPublic ?? defaultValue.isPublic) ? "true" : "false" } class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" role="switch" @@ -713,7 +713,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ <span aria-hidden="true" data-enabled={ - form.isPublic ?? defaultValue.isPublic ? "true" : "false" + (form.isPublic ?? defaultValue.isPublic) ? "true" : "false" } class="translate-x-5 data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out" ></span> @@ -743,7 +743,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ type="button" name="is exchange" data-enabled={ - form.isExchange ?? defaultValue.isExchange + (form.isExchange ?? defaultValue.isExchange) ? "true" : "false" } @@ -760,7 +760,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ <span aria-hidden="true" data-enabled={ - form.isExchange ?? defaultValue.isExchange + (form.isExchange ?? defaultValue.isExchange) ? "true" : "false" } diff --git a/packages/bank-ui/src/pages/admin/AccountList.tsx b/packages/bank-ui/src/pages/admin/AccountList.tsx @@ -210,7 +210,8 @@ export function AccountList({ aria-label="Pagination" > <div class="flex flex-1 justify-between sm:justify-end"> - <button type="button" + <button + type="button" name="first page" class="relative disabled:bg-gray-100 disabled:text-gray-500 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!result.loadFirst} @@ -218,7 +219,8 @@ export function AccountList({ > <i18n.Translate>First page</i18n.Translate> </button> - <button type="button" + <button + type="button" name="next page" class="relative disabled:bg-gray-100 disabled:text-gray-500 ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!result.loadNext} diff --git a/packages/bank-ui/src/pages/admin/ConversionClassList.tsx b/packages/bank-ui/src/pages/admin/ConversionClassList.tsx @@ -28,7 +28,7 @@ import { Loading, RenderAmount, RouteDefinition, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; @@ -38,7 +38,6 @@ import { useConversionRateClasses, } from "../../hooks/regional.js"; - const TALER_SCREEN_ID = 130; interface Props { @@ -249,7 +248,8 @@ export function ConversionClassList({ aria-label="Pagination" > <div class="flex flex-1 justify-between sm:justify-end"> - <button type="button" + <button + type="button" name="first page" class="relative disabled:bg-gray-100 disabled:text-gray-500 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!result.loadFirst} @@ -257,7 +257,8 @@ export function ConversionClassList({ > <i18n.Translate>First page</i18n.Translate> </button> - <button type="button" + <button + type="button" name="next page" class="relative disabled:bg-gray-100 disabled:text-gray-500 ml-3 inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0" disabled={!result.loadNext} diff --git a/packages/bank-ui/src/pages/admin/ConversionRateClassForm.tsx b/packages/bank-ui/src/pages/admin/ConversionRateClassForm.tsx @@ -16,11 +16,11 @@ import { DecimalNumber, RoundingMode, - TalerCorebankApi + TalerCorebankApi, } from "@gnu-taler/taler-util"; import { ShowInputErrorLabel, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { ComponentChildren, VNode, h } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx b/packages/bank-ui/src/pages/admin/CreateNewAccount.tsx @@ -62,7 +62,9 @@ export function CreateNewAccount({ const create = safeFunctionHandler( i18n.str`create account`, api.createAccount.bind(api), - !submitAccount || !token ? undefined : [{ type: "bearer", token }, submitAccount], + !submitAccount || !token + ? undefined + : [{ type: "bearer", token }, submitAccount], ); create.onSuccess = (success, token, account) => { notifyInfo(i18n.str`Account created with password "${account.password}".`); diff --git a/packages/challenger-ui/src/context/preferences.ts b/packages/challenger-ui/src/context/preferences.ts @@ -68,10 +68,7 @@ export function usePreferences(): [ } export function getAllBooleanPreferences(): Array<keyof Preferences> { - return [ - "showChallangeSetup", - "showDebugInfo", - ]; + return ["showChallangeSetup", "showDebugInfo"]; } export function getLabelForPreferences( diff --git a/packages/challenger-ui/src/hooks/session.ts b/packages/challenger-ui/src/hooks/session.ts @@ -121,10 +121,8 @@ export function useSessionState(): SessionStateHandler { lastAddress: lastAddr, }); }, - sent(info) { - }, - failed(info) { - }, + sent(info) {}, + failed(info) {}, completed(info) { if (!state) { update({ diff --git a/packages/challenger-ui/src/index.html b/packages/challenger-ui/src/index.html @@ -24,7 +24,10 @@ <meta name="taler-support" content="uri,api" /> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> <link rel="icon" href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" diff --git a/packages/challenger-ui/src/main.js b/packages/challenger-ui/src/main.js @@ -1,2 +1,2 @@ // intentionally empty -import "./scss/main.css"; -\ No newline at end of file +import "./scss/main.css"; diff --git a/packages/challenger-ui/src/pages/CallengeCompleted.tsx b/packages/challenger-ui/src/pages/CallengeCompleted.tsx @@ -22,21 +22,21 @@ export function CallengeCompleted(): VNode { const { state } = useSessionState(); const { i18n } = useTranslationContext(); - + useEffect(() => { - window.location.href = state?.completedURL ?? "#" - },[]) + window.location.href = state?.completedURL ?? "#"; + }, []); return ( <div class="m-4"> - <Attention - title={i18n.str`Challenge completed`} - type="success" - > + <Attention title={i18n.str`Challenge completed`} type="success"> <i18n.Translate> - You will be redirected to <a href={state?.completedURL} class="break-all">" - {state?.completedURL} - "</a> + You will be redirected to{" "} + <a href={state?.completedURL} class="break-all"> + " + {state?.completedURL} + " + </a> </i18n.Translate> </Attention> </div> diff --git a/packages/challenger-ui/src/pages/MissingParams.tsx b/packages/challenger-ui/src/pages/MissingParams.tsx @@ -15,8 +15,6 @@ */ import { VNode, h } from "preact"; -export function MissingParams() :VNode { - return <div> - missing params: {window.location.href} - </div> -} -\ No newline at end of file +export function MissingParams(): VNode { + return <div>missing params: {window.location.href}</div>; +} diff --git a/packages/challenger-ui/src/pages/NonceNotFound.tsx b/packages/challenger-ui/src/pages/NonceNotFound.tsx @@ -13,9 +13,7 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - useTranslationContext -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; type Form = { diff --git a/packages/challenger-ui/src/settings.ts b/packages/challenger-ui/src/settings.ts @@ -19,14 +19,13 @@ import { buildCodecForObject, canonicalizeBaseUrl, codecForString, - codecOptional + codecOptional, } from "@gnu-taler/taler-util"; export interface ChallengerUiSettings { // Where challenger backend is localted // default: window.origin without "webui/" backendBaseURL?: string; - } /** @@ -51,7 +50,9 @@ function removeUndefineField<T extends object>(obj: T): T { }, obj); } -export function fetchSettings(listener: (s: ChallengerUiSettings) => void): void { +export function fetchSettings( + listener: (s: ChallengerUiSettings) => void, +): void { fetch("./settings.json") .then((resp) => resp.json()) .then((json) => codecForChallengerUISettings().decode(json)) diff --git a/packages/idb-bridge/src/backend-interface.ts b/packages/idb-bridge/src/backend-interface.ts @@ -47,7 +47,6 @@ export enum StoreLevel { UpdateExisting, } - export interface IndexGetQuery { direction: IDBCursorDirection; objectStoreName: string; diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts @@ -1,5 +1,5 @@ import test from "ava"; -import { BridgeIDBCursor,BridgeIDBRequest } from "../bridge-idb.js"; +import { BridgeIDBCursor, BridgeIDBRequest } from "../bridge-idb.js"; import { createdb, initTestIndexedDB } from "./wptsupport.js"; test.before("test DB initialization", initTestIndexedDB); diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts @@ -1,7 +1,12 @@ import test from "ava"; import { BridgeIDBVersionChangeEvent } from "../bridge-idb.js"; import FakeEvent from "../util/FakeEvent.js"; -import { createdb, format_value, initTestIndexedDB, useTestIndexedDb } from "./wptsupport.js"; +import { + createdb, + format_value, + initTestIndexedDB, + useTestIndexedDb, +} from "./wptsupport.js"; import { IDBDatabase } from "../idbtypes.js"; test.before("test DB initialization", initTestIndexedDB); @@ -155,7 +160,7 @@ test("WPT idbfactory-open7.htm", async (t) => { function open_current_db(e: any) { console.log("open7 - opening current DB"); const name = e.target.result.name; - console.log(`open7 - name is ${name}`) + console.log(`open7 - name is ${name}`); var open_rq3 = indexedDB.open(name); open_rq3.onsuccess = function (e: any) { console.log("open7 - success opening current DB"); @@ -265,19 +270,22 @@ test("WPT idbfactory-open9.htm", async (t) => { var name = format_value(val); var dbname = "test-db-does-not-exist"; - await t.notThrowsAsync(async () => { - return new Promise<void>((resolve, reject) => { - indexedDB.deleteDatabase(dbname); - var rq = indexedDB.open(dbname, val); - rq.onupgradeneeded = function () { - var db = rq.result; - t.deepEqual(db.version, expected_version, "version"); - rq!.transaction!.abort(); - }; - rq.onsuccess = () => t.fail("open should fail"); - rq.onerror = () => resolve(); - }); - }, "Calling open() with version argument " + name + " should not throw."); + await t.notThrowsAsync( + async () => { + return new Promise<void>((resolve, reject) => { + indexedDB.deleteDatabase(dbname); + var rq = indexedDB.open(dbname, val); + rq.onupgradeneeded = function () { + var db = rq.result; + t.deepEqual(db.version, expected_version, "version"); + rq!.transaction!.abort(); + }; + rq.onsuccess = () => t.fail("open should fail"); + rq.onerror = () => resolve(); + }); + }, + "Calling open() with version argument " + name + " should not throw.", + ); } await should_work(1.5, 1); diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts @@ -26,13 +26,11 @@ test("WPT idbtransaction-oncomplete.htm", async (t) => { stages.push("success"); // Making a totally new transaction to check - db - .transaction("store") - .objectStore("store") - .count().onsuccess = function (e: any) { - t.deepEqual(stages, ["upgradeneeded", "complete", "success"]); - resolve(); - }; + db.transaction("store").objectStore("store").count().onsuccess = + function (e: any) { + t.deepEqual(stages, ["upgradeneeded", "complete", "success"]); + resolve(); + }; // XXX: Make one with real transactions, not only open() versionchange one /*db.transaction.objectStore('store').openCursor().onsuccess = function(e) { diff --git a/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts b/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts @@ -1,5 +1,9 @@ import test from "ava"; -import { assert_key_equals, createdb, initTestIndexedDB } from "./wptsupport.js"; +import { + assert_key_equals, + createdb, + initTestIndexedDB, +} from "./wptsupport.js"; test.before("test DB initialization", initTestIndexedDB); diff --git a/packages/idb-bridge/src/idbpromutil.ts b/packages/idb-bridge/src/idbpromutil.ts @@ -23,4 +23,4 @@ export function promiseFromTransaction( reject(); }; }); -} -\ No newline at end of file +} diff --git a/packages/idb-bridge/src/tree/b+tree.ts b/packages/idb-bridge/src/tree/b+tree.ts @@ -465,7 +465,7 @@ export default class BTree<K = any, V = any> var tmp = {} as { value: R }; var nu = this.greedyClone(); nu.editAll((k, v, i) => { - return (tmp.value = callback(v, k, i)), tmp as any; + return ((tmp.value = callback(v, k, i)), tmp as any); }); return nu as any as BTree<K, R>; } @@ -547,8 +547,8 @@ export default class BTree<K = any, V = any> continue; case 1: if (++i < leaf.keys.length) { - (reusedArray![0] = leaf.keys[i]), - (reusedArray![1] = leaf.values[i]); + ((reusedArray![0] = leaf.keys[i]), + (reusedArray![1] = leaf.values[i])); return { done: false, value: reusedArray as [K, V] }; } state = 2; @@ -620,12 +620,12 @@ export default class BTree<K = any, V = any> continue; case 1: if (--i >= 0) { - (reusedArray![0] = leaf.keys[i]), - (reusedArray![1] = leaf.values[i]); + ((reusedArray![0] = leaf.keys[i]), + (reusedArray![1] = leaf.values[i])); return { done: false, value: reusedArray as [K, V] }; } state = 2; - continue jump; + continue jump; case 2: // Advance to the next leaf node for (var level = -1; ; ) { @@ -670,9 +670,9 @@ export default class BTree<K = any, V = any> var nodequeue: BNode<K, V>[][], nodeindex: number[]; if (nextnode.isLeaf) { - (nodequeue = EmptyArray), (nodeindex = EmptyArray); // avoid allocations + ((nodequeue = EmptyArray), (nodeindex = EmptyArray)); // avoid allocations } else { - (nodequeue = []), (nodeindex = []); + ((nodequeue = []), (nodeindex = [])); for (var d = 0; !nextnode.isLeaf; d++) { nodequeue[d] = (nextnode as BNodeInternal<K, V>).children; nodeindex[d] = diff --git a/packages/idb-bridge/src/tree/interfaces.ts b/packages/idb-bridge/src/tree/interfaces.ts @@ -75,8 +75,7 @@ export interface ISet<K = any> extends ISetSource<K>, ISetSink<K> {} * describe the complete interface of either class, but merely the common * interface shared by both. */ export interface IMap<K = any, V = any> - extends IMapSource<K, V>, - IMapSink<K, V> {} + extends IMapSource<K, V>, IMapSink<K, V> {} /** An data source that provides read-only access to a set of items called * "keys" in sorted order. This is a subinterface of ISortedMapSource. */ @@ -115,8 +114,7 @@ export interface ISortedSetSource<K = any> extends ISetSource<K> { /** An data source that provides read-only access to items in sorted order. */ export interface ISortedMapSource<K = any, V = any> - extends IMapSource<K, V>, - ISortedSetSource<K> { + extends IMapSource<K, V>, ISortedSetSource<K> { /** Returns the next pair whose key is larger than the specified key (or undefined if there is none) */ nextHigherPair(key: K): [K, V] | undefined; /** Returns the next pair whose key is smaller than the specified key (or undefined if there is none) */ @@ -194,8 +192,7 @@ export interface ISortedSet<K = any> extends ISortedSetSource<K>, ISetSink<K> {} /** An interface for a sorted map (dictionary), * not including functional/persistent methods. */ export interface ISortedMap<K = any, V = any> - extends IMap<K, V>, - ISortedMapSource<K, V> { + extends IMap<K, V>, ISortedMapSource<K, V> { // All of the following methods should be in IMap but are left out of IMap // so that IMap is compatible with ES6 Map. @@ -331,9 +328,7 @@ export interface ISortedSetF<K = any> extends ISetF<K>, ISortedSetSource<K> { } export interface ISortedMapF<K = any, V = any> - extends ISortedSetF<K>, - IMapF<K, V>, - ISortedMapSource<K, V> { + extends ISortedSetF<K>, IMapF<K, V>, ISortedMapSource<K, V> { /** Returns a copy of the tree with the specified range of keys removed. */ withoutRange( low: K, diff --git a/packages/idb-bridge/src/util/fakeDOMStringList.ts b/packages/idb-bridge/src/util/fakeDOMStringList.ts @@ -14,7 +14,6 @@ * permissions and limitations under the License. */ - /** @public */ export interface FakeDOMStringList extends Array<string> { contains: (value: string) => boolean; diff --git a/packages/idb-bridge/src/util/key-storage.ts b/packages/idb-bridge/src/util/key-storage.ts @@ -290,7 +290,7 @@ function internalReadBytes(dv: DataView, offset: number): [number, Uint8Array] { * Same as DataView.getFloat64, but logically pad input * with zeroes on the right if read offset would be out * of bounds. - * + * * This allows reading from buffers where zeros have been * truncated. */ diff --git a/packages/idb-bridge/src/util/structuredClone.test.ts b/packages/idb-bridge/src/util/structuredClone.test.ts @@ -102,7 +102,7 @@ test("revive", (t) => { t.deepEqual(structuredRevive({ $: "undef" }), undefined); t.deepEqual(structuredRevive({ x: { $: "undef" } }), { x: undefined }); - t.deepEqual(structuredRevive({ $: "date", val: 42}), new Date(42)); + t.deepEqual(structuredRevive({ $: "date", val: 42 }), new Date(42)); { const x = { foo: 42, bar: {} } as any; diff --git a/packages/idb-bridge/src/util/validateKeyPath.ts b/packages/idb-bridge/src/util/validateKeyPath.ts @@ -42,7 +42,8 @@ export const validateKeyPath = ( // https://mathiasbynens.be/demo/javascript-identifier-regex for ECMAScript 5.1 / Unicode v7.0.0, with // reserved words at beginning removed // tslint:disable-next-line max-line-length - const validIdentifierRegex = /^(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])(?:[\$0-9A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])*$/; + const validIdentifierRegex = + /^(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])(?:[\$0-9A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])*$/; if (myKeyPath.length >= 1 && validIdentifierRegex.test(myKeyPath)) { return; } diff --git a/packages/idb-bridge/src/util/valueToKey.ts b/packages/idb-bridge/src/util/valueToKey.ts @@ -19,7 +19,7 @@ import { DataError } from "./errors.js"; /** * Algorithm to "convert a value to a key". - * + * * https://www.w3.org/TR/IndexedDB/#convert-value-to-key */ export function valueToKey( diff --git a/packages/kyc-ui/src/hooks/kyc.ts b/packages/kyc-ui/src/hooks/kyc.ts @@ -59,7 +59,7 @@ export function useKycInfo(token?: AccessToken) { return true; }, async (ct, result) => { - if (!result || (result instanceof TalerError) || result.type === "fail") + if (!result || result instanceof TalerError || result.type === "fail") return undefined; if (!result.body.requirements.length) return undefined; diff --git a/packages/kyc-ui/src/index.html b/packages/kyc-ui/src/index.html @@ -24,7 +24,10 @@ <meta name="taler-support" content="uri,api" /> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> <link rel="icon" href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5T/48i2/8J+VP/Qn3//3ryn/795Tf/WrpP/2LCW/8B6T//w4Nb///////Pn4P+/d0v/9u3n/+7d0v/EhV7//v///+HDr//fxLD/zph2/+TJt//8/Pv/woBX//Lm3f/y5dz/v3hN//bu6f/JjGn/4sW0///////Df1j/8OLZ//v6+P+/elH/+vj1//jy7f+/elL//////+zYzP/Eg13//////967p//MlHT/wn5X///////v4Nb/yY1s///////jw7H/06KG////////////z5t9/+fNvf//////x4pn//Pp4v/8+vn/w39X/8WEX///////5s/A/9CbfP//////27Oc/9y2n////////////9itlf/gu6f//////86Vdf/r2Mz//////8SCXP/Df1j//////+7d0v/KkG7//////+HBrf/VpYr////////////RnoH/5sq6///////Ii2n/8ubf//39/P/Cf1j/xohk/+bNvv//////wn5W//Tq4//58/D/wHxV//7+/f/59fH/v3xU//39/P/w4Nf/xIFb///////hw7H/yo9t/+/f1f/AeU3/+/n2/+nSxP/FhmD//////9qzm//Upon/4MSx/96+qf//////xINc/+3bz//48e3/v3hN//Pn3///////6M+//752S//gw6//06aK/8J+VP/kzLr/zZd1/8OCWv/q18r/17KZ/9Ooi//fv6r/v3dK/+vWyP///////v39///////27un/1aeK/9Opjv/m1cf/1KCC/9a0nP/n08T/0Jx8/82YdP/QnHz/16yR//jx7P///////v39///////+/f3///7+///////+//7//v7+///////+/v7//v/+/////////////////////////v7//v79///////////////////+/v/+/Pv//v39///+/v/+/Pv///7+//7+/f/+/Pv//v39//79/P/+/Pv///7+////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" diff --git a/packages/kyc-ui/src/pages/FillForm.tsx b/packages/kyc-ui/src/pages/FillForm.tsx @@ -35,7 +35,7 @@ import { useAsyncAsHook, useExchangeApiContext, useLocalNotificationBetter, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useFormMeta } from "../../../web-util/src/hooks/useForm.js"; diff --git a/packages/kyc-ui/src/pages/Start.tsx b/packages/kyc-ui/src/pages/Start.tsx @@ -175,7 +175,7 @@ function LinkGenerator({ req }: { req: KycRequirementInformation }): VNode { const [loading, setLoading] = useState<LinkGeneration>({ state: LinkGenerationState.WAIT, }); - + const [notification, safeFunctionHandler] = useLocalNotificationBetter(); const { lib } = useExchangeApiContext(); diff --git a/packages/kyc-ui/src/settings.ts b/packages/kyc-ui/src/settings.ts @@ -19,14 +19,13 @@ import { buildCodecForObject, canonicalizeBaseUrl, codecForString, - codecOptional + codecOptional, } from "@gnu-taler/taler-util"; export interface KycUiSettings { // Where exchange backend is localted // default: window.origin without "webui/" backendBaseURL?: string; - } /** diff --git a/packages/merchant-backoffice-ui/src/AdminRoutes.tsx b/packages/merchant-backoffice-ui/src/AdminRoutes.tsx @@ -48,7 +48,6 @@ export function AdminRoutes(): VNode { onConfirm={() => { route(InstancePaths.bank_list); }} - /> </Router> ); diff --git a/packages/merchant-backoffice-ui/src/Application.tsx b/packages/merchant-backoffice-ui/src/Application.tsx @@ -248,12 +248,9 @@ function OnConfigError({ } } -const swrCacheEvictor = new (class - implements - CacheEvictor< - TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction - > -{ +const swrCacheEvictor = new (class implements CacheEvictor< + TalerMerchantManagementCacheEviction | TalerMerchantInstanceCacheEviction +> { async notifySuccess( op: | TalerMerchantManagementCacheEviction diff --git a/packages/merchant-backoffice-ui/src/components/ChartJS.tsx b/packages/merchant-backoffice-ui/src/components/ChartJS.tsx @@ -3,7 +3,10 @@ import { BarController, BarElement, CategoryScale, - Chart, ChartData, ChartOptions, Filler, + Chart, + ChartData, + ChartOptions, + Filler, Legend, LinearScale, LineController, @@ -11,7 +14,7 @@ import { PointElement, TimeScale, Title, - Tooltip + Tooltip, } from "chart.js"; import { h, VNode } from "preact"; import { useEffect, useRef } from "preact/hooks"; diff --git a/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx b/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx @@ -629,7 +629,10 @@ export function SolveMFAChallenges({ <i18n.Translate>Continue</i18n.Translate> </ButtonBetterBulma> {!enough ? undefined : ( - <ButtonBetterBulma type="button" onClick={onCompleted.withArgs(solved)}> + <ButtonBetterBulma + type="button" + onClick={onCompleted.withArgs(solved)} + > <i18n.Translate>Complete</i18n.Translate> </ButtonBetterBulma> )} diff --git a/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx b/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx @@ -65,10 +65,18 @@ export function FormProvider<T>({ const [{ showDebugInfo }] = useCommonPreferences(); return ( <FormContext.Provider value={value}> - <form onSubmit={(e) => { - e.preventDefault() - }}>{children}</form> - {showDebugInfo ? <pre>{JSON.stringify({form: value.object, errors}, undefined, 2)}</pre> : undefined} + <form + onSubmit={(e) => { + e.preventDefault(); + }} + > + {children} + </form> + {showDebugInfo ? ( + <pre> + {JSON.stringify({ form: value.object, errors }, undefined, 2)} + </pre> + ) : undefined} </FormContext.Provider> ); } diff --git a/packages/merchant-backoffice-ui/src/components/form/Input.tsx b/packages/merchant-backoffice-ui/src/components/form/Input.tsx @@ -103,16 +103,16 @@ export function InternalTextInputSwitch({ ref={focus ? doAutoFocus : undefined} class={hasError ? "textarea is-danger" : "textarea"} rows={3} - onKeyDown={e => { - console.log("asd") + onKeyDown={(e) => { + console.log("asd"); if (e.ctrlKey && e.key === "Enter") { // e.preventDefault() - const f = e.currentTarget.form + const f = e.currentTarget.form; // FIXME: why this requestSubmit doesnt trigger form submission? if (f) { - console.log(f.checkValidity()) - console.log(f.reportValidity()) - console.log(f.requestSubmit()) + console.log(f.checkValidity()); + console.log(f.reportValidity()); + console.log(f.requestSubmit()); } } }} @@ -136,13 +136,15 @@ export function InternalTextInputSwitch({ inputType === "search" || inputType === "url" ) { - return <input - {...(rest as any)} - ref={focus ? doAutoFocus : undefined} - class={hasError ? "input is-danger" : "input"} - type={inputType} - inputMode={inputType} - />; + return ( + <input + {...(rest as any)} + ref={focus ? doAutoFocus : undefined} + class={hasError ? "input is-danger" : "input"} + type={inputType} + inputMode={inputType} + /> + ); } return ( <input diff --git a/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx b/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx @@ -59,7 +59,11 @@ export function InputBoolean<T>({ <div class="field-label is-normal"> <label class="label"> {label} - {tooltip && <Tooltip text={tooltip} ><i class="icon mdi mdi-information" /></Tooltip>} + {tooltip && ( + <Tooltip text={tooltip}> + <i class="icon mdi mdi-information" /> + </Tooltip> + )} </label> </div> <div class="field-body is-flex-grow-3"> diff --git a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx @@ -18,10 +18,7 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { - Amounts, - AmountString -} from "@gnu-taler/taler-util"; +import { Amounts, AmountString } from "@gnu-taler/taler-util"; import { ComponentChildren, h, VNode } from "preact"; import { useCurrenciesContext } from "../../context/currency.js"; import { useSessionContext } from "../../context/session.js"; diff --git a/packages/merchant-backoffice-ui/src/components/form/InputDurationDropdown.tsx b/packages/merchant-backoffice-ui/src/components/form/InputDurationDropdown.tsx @@ -172,11 +172,11 @@ export function InputDurationDropdown<T>({ ); useEffect(() => { - if (value === undefined && !numStr) return - const nu = bestInitialUnit(value) - setUnit(nu) - setNumStr(defaultToInputNumberString(value, nu)) - },[value]) + if (value === undefined && !numStr) return; + const nu = bestInitialUnit(value); + setUnit(nu); + setNumStr(defaultToInputNumberString(value, nu)); + }, [value]); // const strValue = durationToString(i18n, value); return ( @@ -241,7 +241,7 @@ export function InputDurationDropdown<T>({ setUnit(u); const duration = defaultFromInputToDuration(numStr, u); if (!duration || duration.d_ms === "forever") { - setNumStr("") + setNumStr(""); } onChange( (useProtocolDuration && duration diff --git a/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx b/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx @@ -50,7 +50,7 @@ export function InputGroup<T>({ <div class="card"> <header class="card-header" - style={fixed ? undefined :{ cursor: "pointer" }} + style={fixed ? undefined : { cursor: "pointer" }} onClick={fixed ? undefined : (): void => setActive(!active)} > <p class="card-header-title"> diff --git a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx @@ -90,15 +90,17 @@ export function InputImage<T>({ return; } if (theFile.size > MAX_IMAGE_UPLOAD_SIZE) { - setSizeError(i18n.str`The image was normalized to be smaller than 1 MB`); + setSizeError( + i18n.str`The image was normalized to be smaller than 1 MB`, + ); normalizeImagesize(theFile, onChange as any); // return onChange(undefined!); return; } setSizeError(undefined); - toDataSrc(theFile).then(r => { + toDataSrc(theFile).then((r) => { onChange(r as T[keyof T]); - }) + }); }} /> {help} diff --git a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx @@ -300,7 +300,7 @@ export function InputPaytoForm<T>({ targetType: value.target, targetPath: value.path2 ? `${path1WithSlash}${value.path2}` - : path1WithSlash ?? "", + : (path1WithSlash ?? ""), params: value.params ?? {}, isKnown: false as const, } as PaytoUri); diff --git a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx @@ -175,7 +175,11 @@ export function InputStock<T>({ object={addedStock} valueHandler={setAddedStock as any} > - <InputNumber name="current" label={i18n.str`Current`} readonly /> + <InputNumber + name="current" + label={i18n.str`Current`} + readonly + /> <InputNumber name="incoming" label={i18n.str`Incoming`} /> <InputNumber name="lost" label={i18n.str`Lost`} /> </FormProvider> diff --git a/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx b/packages/merchant-backoffice-ui/src/components/form/InputToggle.tsx @@ -100,7 +100,7 @@ export function InputToggle<T>({ }} readonly={readonly} name={String(name)} - style={{visibility:"inherit", appearance:"none"}} + style={{ visibility: "inherit", appearance: "none" }} disabled={readonly} onChange={onCheckboxClick} /> diff --git a/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx @@ -39,7 +39,7 @@ export interface Props<T> extends InputProps<T> { inputExtra?: any; children?: ComponentChildren; side?: ComponentChildren; - focus?:boolean; + focus?: boolean; autoComplete?: SupportedAutocomplete; } diff --git a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx @@ -68,22 +68,22 @@ export function NavigationBar({ </span> </div> - <div class="navbar-menu " > - <a - class="navbar-start is-justify-content-center is-flex-grow-1 has-tooltip-fixed" - href="https://tutorials.taler.net/merchant/merchant-backoffice" - target="_blank" - data-tooltip={i18n.str`Follow this link to find video tutorials on how you can use the GNU Taler components.`} - rel="noreferrer" - style={{"--pos-x": 100}} - > - <img src={logo} style={{ height: 35, margin: 10 }} /> - <img - src={question} - style={{ height: 20, marginTop: "auto", marginBottom: "auto" }} - /> - </a> - </div> + <div class="navbar-menu "> + <a + class="navbar-start is-justify-content-center is-flex-grow-1 has-tooltip-fixed" + href="https://tutorials.taler.net/merchant/merchant-backoffice" + target="_blank" + data-tooltip={i18n.str`Follow this link to find video tutorials on how you can use the GNU Taler components.`} + rel="noreferrer" + style={{ "--pos-x": 100 }} + > + <img src={logo} style={{ height: 35, margin: 10 }} /> + <img + src={question} + style={{ height: 20, marginTop: "auto", marginBottom: "auto" }} + /> + </a> + </div> </nav> ); } diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx @@ -28,9 +28,7 @@ import { ComponentChildren, Fragment, h, VNode } from "preact"; import { useCurrenciesContext } from "../../context/currency.js"; import { useSessionContext } from "../../context/session.js"; import { useSettingsContext } from "../../context/settings.js"; -import { - useInstanceKYCSimplifiedWorstStatusLongPolling -} from "../../hooks/instance.js"; +import { useInstanceKYCSimplifiedWorstStatusLongPolling } from "../../hooks/instance.js"; import { UIElement, usePreference } from "../../hooks/preference.js"; import { LangSelector } from "./LangSelector.js"; diff --git a/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx @@ -36,7 +36,7 @@ export function CreatedSuccessfully({ onConfirm, onCreateAnother, }: Props): VNode { - const { i18n } = useTranslationContext() + const { i18n } = useTranslationContext(); return ( <div class="columns is-fullwidth is-vcentered mt-3"> <div class="column" /> @@ -49,11 +49,20 @@ export function CreatedSuccessfully({ </div> <div class="buttons is-right"> {onCreateAnother && ( - <button type="button" class="button is-info" onClick={onCreateAnother}> + <button + type="button" + class="button is-info" + onClick={onCreateAnother} + > <i18n.Translate>Create another</i18n.Translate> </button> )} - <button type="button" class="button is-info" ref={focus ? doAutoFocus : undefined} onClick={onConfirm}> + <button + type="button" + class="button is-info" + ref={focus ? doAutoFocus : undefined} + onClick={onConfirm} + > <i18n.Translate>Continue</i18n.Translate> </button> </div> diff --git a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx @@ -60,7 +60,7 @@ interface Props { categories: TalerMerchantApi.CategoryListEntry[]; groups: TalerMerchantApi.GroupEntry[]; pots: TalerMerchantApi.PotEntry[]; - children?: ComponentChildren, + children?: ComponentChildren; } export function ProductForm({ @@ -79,8 +79,8 @@ export function ProductForm({ !initial || !initial.categories ? [] : categories - .filter((c) => initial.categories?.indexOf(c.category_id) !== -1) - .map((c) => ({ id: String(c.category_id), description: c.name })); + .filter((c) => initial.categories?.indexOf(c.category_id) !== -1) + .map((c) => ({ id: String(c.category_id), description: c.name })); const groupMap = new Map<number, string>(); for (const c of groups) { groupMap.set(c.group_serial, c.group_name); @@ -111,12 +111,12 @@ export function ProductForm({ !initial || initial.total_stock === -1 ? undefined : { - current: initial.total_stock || 0, - lost: initial.total_lost || 0, - sold: initial.total_sold || 0, - address: initial.address, - nextRestock: initial.next_restock, - }, + current: initial.total_stock || 0, + lost: initial.total_lost || 0, + sold: initial.total_sold || 0, + address: initial.address, + nextRestock: initial.next_restock, + }, }); const errors = undefinedIfEmpty<FormErrors<Entity>>({ @@ -280,7 +280,9 @@ export function ProductForm({ help={i18n.str`Search by group name or id`} tooltip={i18n.str`Categories where this product will be listed on.`} values={[0, ...groupMap.keys()]} - toStr={(g: number) => (!g ? i18n.str`Select one` : groupMap.get(g)!)} + toStr={(g: number) => + !g ? i18n.str`Select one` : groupMap.get(g)! + } fromStr={(d) => Number.parseInt(d, 10)} readonly={groups.length === 0} /> diff --git a/packages/merchant-backoffice-ui/src/context/session.ts b/packages/merchant-backoffice-ui/src/context/session.ts @@ -22,7 +22,7 @@ import { buildCodecForObject, codecForString, codecForURL, - codecOptional + codecOptional, } from "@gnu-taler/taler-util"; import { buildStorageKey, @@ -59,7 +59,6 @@ interface LoggedIn { //instance access token token: AccessToken | undefined; - } interface LoggedOut { diff --git a/packages/merchant-backoffice-ui/src/hooks/access-tokens.ts b/packages/merchant-backoffice-ui/src/hooks/access-tokens.ts @@ -21,7 +21,11 @@ import { TalerMerchantManagementResultByMethod, TokenInfo, } from "@gnu-taler/taler-util"; -import { buildPaginatedResult, ListPointer, useListPointer } from "@gnu-taler/web-util/browser"; +import { + buildPaginatedResult, + ListPointer, + useListPointer, +} from "@gnu-taler/web-util/browser"; import _useSWR, { SWRHook, mutate } from "swr"; import { useSessionContext } from "../context/session.js"; import { PAGINATED_LIST_REQUEST } from "../utils/constants.js"; @@ -38,11 +42,12 @@ export function revalidateInstanceAccessTokens() { ); } - export function useInstanceAccessTokens() { const { state, lib } = useSessionContext(); - const [pointer, setPointer] = useListPointer((row:TokenInfo) => String(row.serial)) + const [pointer, setPointer] = useListPointer((row: TokenInfo) => + String(row.serial), + ); async function fetcher([token, pointer]: [ AccessToken, diff --git a/packages/merchant-backoffice-ui/src/hooks/bank.ts b/packages/merchant-backoffice-ui/src/hooks/bank.ts @@ -37,8 +37,7 @@ export function useInstanceBankAccounts() { const { state, lib } = useSessionContext(); async function fetcher([token, _bid]: [AccessToken, string]) { - return await lib.instance.listBankAccounts(token, { - }); + return await lib.instance.listBankAccounts(token, {}); } const { data, error } = useSWR< diff --git a/packages/merchant-backoffice-ui/src/hooks/category.ts b/packages/merchant-backoffice-ui/src/hooks/category.ts @@ -35,8 +35,7 @@ export function useInstanceCategories() { const { state, lib } = useSessionContext(); async function fetcher([token, _bid]: [AccessToken, string]) { - return await lib.instance.listCategories(token, { - }); + return await lib.instance.listCategories(token, {}); } const { data, error } = useSWR< diff --git a/packages/merchant-backoffice-ui/src/hooks/exchanges.ts b/packages/merchant-backoffice-ui/src/hooks/exchanges.ts @@ -38,7 +38,7 @@ export function useBackendExchanges() { async function fetcher([]: [AccessToken, string]) { const list = await lib.instance.listExchanges(); if (list.type === "ok") { - list.body.exchanges.sort(importantFirst); + list.body.exchanges.sort(importantFirst); } return list; } diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts @@ -19,7 +19,11 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AccessToken, MerchantAuthMethod, TalerMerchantApi } from "@gnu-taler/taler-util"; +import { + AccessToken, + MerchantAuthMethod, + TalerMerchantApi, +} from "@gnu-taler/taler-util"; import { useMerchantApiContext } from "@gnu-taler/web-util/browser"; import * as tests from "@gnu-taler/web-util/testing"; import { expect } from "chai"; @@ -78,9 +82,12 @@ describe("instance api interaction with details", () => { name: "other_name", } as TalerMerchantApi.QueryInstancesResponse, }); - api.instance.updateCurrentInstance("undefined" as AccessToken, { - name: "other_name", - } as TalerMerchantApi.InstanceReconfigurationMessage); + api.instance.updateCurrentInstance( + "undefined" as AccessToken, + { + name: "other_name", + } as TalerMerchantApi.InstanceReconfigurationMessage, + ); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -228,7 +235,7 @@ describe("instance api interaction with details", () => { env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, { request: { method: "token", - password: "asd" + password: "asd", } as TalerMerchantApi.InstanceAuthConfigurationMessage, }); env.addRequestExpectation(API_GET_CURRENT_INSTANCE, { @@ -241,10 +248,13 @@ describe("instance api interaction with details", () => { } as TalerMerchantApi.QueryInstancesResponse, }); - api.instance.updateCurrentInstanceAuthentication("undefined" as AccessToken, { - method: MerchantAuthMethod.TOKEN, - password: "asd" - }); + api.instance.updateCurrentInstanceAuthentication( + "undefined" as AccessToken, + { + method: MerchantAuthMethod.TOKEN, + password: "asd", + }, + ); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -380,9 +390,12 @@ describe("instance admin api interaction with listing", () => { }, }); - api.instance.createInstance("undefined" as AccessToken, { - name: "other_name", - } as TalerMerchantApi.InstanceConfigurationMessage); + api.instance.createInstance( + "undefined" as AccessToken, + { + name: "other_name", + } as TalerMerchantApi.InstanceConfigurationMessage, + ); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -628,7 +641,9 @@ describe("instance admin api interaction with listing", () => { }, }); - api.instance.deleteInstance("undefined" as AccessToken, "the_id", { purge: true }); + api.instance.deleteInstance("undefined" as AccessToken, "the_id", { + purge: true, + }); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -712,9 +727,12 @@ describe("instance management api interaction with listing", () => { }, }); - api.instance.updateCurrentInstance("undefined" as AccessToken, { - name: "other_name", - } as TalerMerchantApi.InstanceConfigurationMessage); + api.instance.updateCurrentInstance( + "undefined" as AccessToken, + { + name: "other_name", + } as TalerMerchantApi.InstanceConfigurationMessage, + ); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts b/packages/merchant-backoffice-ui/src/hooks/instance.ts @@ -178,11 +178,13 @@ export function useAvailableCurrencies(): string[] { ? undefined : kyc.body; - const cs = !status ? [] : status.kyc_data.map((st) => - st.status === MerchantAccountKycStatus.READY - ? st.exchange_currency - : undefined, - ); + const cs = !status + ? [] + : status.kyc_data.map((st) => + st.status === MerchantAccountKycStatus.READY + ? st.exchange_currency + : undefined, + ); return cs.filter((c): c is string => !!c); } diff --git a/packages/merchant-backoffice-ui/src/hooks/pots.ts b/packages/merchant-backoffice-ui/src/hooks/pots.ts @@ -15,7 +15,11 @@ */ // FIX default import https://github.com/microsoft/TypeScript/issues/49189 -import { AccessToken, TalerHttpError, TalerMerchantManagementResultByMethod } from "@gnu-taler/taler-util"; +import { + AccessToken, + TalerHttpError, + TalerMerchantManagementResultByMethod, +} from "@gnu-taler/taler-util"; import _useSWR, { SWRHook, mutate } from "swr"; import { useSessionContext } from "../context/session.js"; const useSWR = _useSWR as unknown as SWRHook; @@ -31,8 +35,7 @@ export function useInstanceMoneyPots() { const { state, lib } = useSessionContext(); async function fetcher([token, _bid]: [AccessToken, string]) { - return await lib.instance.listMoneyPots(token, { - }); + return await lib.instance.listMoneyPots(token, {}); } const { data, error } = useSWR< diff --git a/packages/merchant-backoffice-ui/src/hooks/preference.ts b/packages/merchant-backoffice-ui/src/hooks/preference.ts @@ -78,7 +78,6 @@ const defaultSettings: Preferences = { persona: undefined, }; - export const codecForPreferences = (): Codec<Preferences> => buildCodecForObject<Preferences>() .property("hideKycUntil", codecForAbsoluteTime) @@ -101,7 +100,7 @@ export const codecForPreferences = (): Codec<Preferences> => codecForConstString("point-of-sale"), codecForConstString("digital-publishing"), codecForConstString("e-commerce"), - ) + ), ), ) .build("Preferences"); diff --git a/packages/merchant-backoffice-ui/src/hooks/product.test.ts b/packages/merchant-backoffice-ui/src/hooks/product.test.ts @@ -21,10 +21,7 @@ import * as tests from "@gnu-taler/web-util/testing"; import { expect } from "chai"; -import { - useInstanceProducts, - useProductDetails, -} from "./product.js"; +import { useInstanceProducts, useProductDetails } from "./product.js"; import { ApiMockEnvironment } from "./testing.js"; import { API_CREATE_PRODUCT, @@ -80,7 +77,10 @@ describe("product api interaction with listing", () => { env.addRequestExpectation(API_LIST_PRODUCTS, { response: { - products: [{ product_id: "1234", product_serial: 1 }, { product_id: "2345", product_serial: 2 }], + products: [ + { product_id: "1234", product_serial: 1 }, + { product_id: "2345", product_serial: 2 }, + ], }, }); env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), { @@ -99,9 +99,12 @@ describe("product api interaction with listing", () => { } as TalerMerchantApi.ProductDetailResponse, }); - api.instance.addProduct("undefined" as AccessToken, { - price: "ARS:23", - } as any); + api.instance.addProduct( + "undefined" as AccessToken, + { + price: "ARS:23", + } as any, + ); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -218,7 +221,10 @@ describe("product api interaction with listing", () => { env.addRequestExpectation(API_LIST_PRODUCTS, { response: { - products: [{ product_id: "1234", product_serial: 1 }, { product_id: "2345", product_serial: 2 }], + products: [ + { product_id: "1234", product_serial: 1 }, + { product_id: "2345", product_serial: 2 }, + ], }, }); env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), { diff --git a/packages/merchant-backoffice-ui/src/hooks/statistics.ts b/packages/merchant-backoffice-ui/src/hooks/statistics.ts @@ -23,7 +23,7 @@ import { StatisticsAmount, StatisticsCounter, TalerHttpError, - TalerMerchantManagementErrorsByMethod + TalerMerchantManagementErrorsByMethod, } from "@gnu-taler/taler-util"; import _useSWR, { mutate, SWRHook } from "swr"; import { useSessionContext } from "../context/session.js"; @@ -32,7 +32,7 @@ const useSWR = _useSWR as unknown as SWRHook; export type MerchantStatsSlug = | MerchantOrderStatsSlug | MerchantRevenueStatsSlug; - + export const MERCHANT_ORDER_STATS_SLUG = [ "orders-created", "orders-claimed", diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts b/packages/merchant-backoffice-ui/src/hooks/transfer.test.ts @@ -130,9 +130,7 @@ describe("transfer listing pagination", () => { }; const hookBehavior = await tests.hookBehaveLikeThis( () => { - const query = useInstanceConfirmedTransfers( - { payto_uri: "payto://" }, - ); + const query = useInstanceConfirmedTransfers({ payto_uri: "payto://" }); return { query }; }, {}, @@ -152,7 +150,6 @@ describe("transfer listing pagination", () => { // }); // expect(query.isReachingEnd).true; // expect(query.isReachingStart).true; - }, ], env.buildTestingContext(), @@ -193,9 +190,7 @@ describe("transfer listing pagination", () => { const hookBehavior = await tests.hookBehaveLikeThis( () => { - const query = useInstanceConfirmedTransfers( - { payto_uri: "payto://" }, - ); + const query = useInstanceConfirmedTransfers({ payto_uri: "payto://" }); return { query }; }, {}, diff --git a/packages/merchant-backoffice-ui/src/hooks/webhooks.ts b/packages/merchant-backoffice-ui/src/hooks/webhooks.ts @@ -18,7 +18,7 @@ import { AccessToken, TalerHttpError, - TalerMerchantManagementResultByMethod + TalerMerchantManagementResultByMethod, } from "@gnu-taler/taler-util"; import _useSWR, { SWRHook, mutate } from "swr"; import { useSessionContext } from "../context/session.js"; @@ -37,8 +37,7 @@ export function useInstanceWebhooks() { const { state, lib } = useSessionContext(); async function fetcher([token, _bid]: [AccessToken, string]) { - return await lib.instance.listWebhooks(token, { - }); + return await lib.instance.listWebhooks(token, {}); } const { data, error } = useSWR< @@ -54,7 +53,6 @@ export function useInstanceWebhooks() { return data; } - export function revalidateWebhookDetails() { return mutate( (key) => Array.isArray(key) && key[key.length - 1] === "getWebhookDetails", diff --git a/packages/merchant-backoffice-ui/src/index.dev.html b/packages/merchant-backoffice-ui/src/index.dev.html @@ -15,7 +15,7 @@ @author Sebastian Javier Marchano --> -<!DOCTYPE html> +<!doctype html> <html lang="en" class="has-aside-left has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded" @@ -23,22 +23,28 @@ <head> <meta charset="utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1" /> + <meta + name="viewport" + content="width=device-width, height=device-height, initial-scale=1" + /> <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="taler-support" content="uri,api" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; manifest-src 'self';frame-src blob:; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> - <link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"> - <link rel="manifest" href="manifest.json"> - <meta name="theme-color" content="#db7093"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; manifest-src 'self';frame-src blob:; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> + <link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" /> + <link rel="manifest" href="manifest.json" /> + <meta name="theme-color" content="#db7093" /> <script> /** - * Hide install prompt but save it in case the app wants to trigger it. + * Hide install prompt but save it in case the app wants to trigger it. */ - window.addEventListener('beforeinstallprompt', (e) => { + window.addEventListener("beforeinstallprompt", (e) => { window.pwdInstallPrompt = e; e.preventDefault(); - }) + }); </script> <link rel="icon" diff --git a/packages/merchant-backoffice-ui/src/index.prod.html b/packages/merchant-backoffice-ui/src/index.prod.html @@ -15,7 +15,7 @@ @author Sebastian Javier Marchano --> -<!DOCTYPE html> +<!doctype html> <html lang="en" class="has-aside-left has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded" @@ -27,7 +27,10 @@ <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="taler-support" content="uri,api" /> - <meta http-equiv="Content-Security-Policy" content="default-src 'none'; frame-src blob:; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'"> + <meta + http-equiv="Content-Security-Policy" + content="default-src 'none'; frame-src blob:; script-src 'self'; connect-src *; img-src 'self' data:; style-src 'self';font-src 'self';base-uri 'self';form-action 'self'" + /> <link rel="icon" diff --git a/packages/merchant-backoffice-ui/src/lang.ts b/packages/merchant-backoffice-ui/src/lang.ts @@ -81,7 +81,7 @@ msgstr "" #, c-format msgid "Supported version \"%1$s\", server version \"%2$s\"." msgstr "" -` +`; const msgs = Object.entries( strings[key].locale_data.messages as Record<string, string[]>, ); @@ -90,14 +90,16 @@ msgstr "" return false; }); empty.forEach((msg) => { - const search = new RegExp(`\n\n(#.*\n)+msgid "${msg[0]}"\nmsgstr .*\n\n`,"gm"); - const res = search.exec(content) + const search = new RegExp( + `\n\n(#.*\n)+msgid "${msg[0]}"\nmsgstr .*\n\n`, + "gm", + ); + const res = search.exec(content); if (res) { - console.log(res[0].trim()) + console.log(res[0].trim()); } }); - - }) + }); break; } case "SHOW_STATS": { diff --git a/packages/merchant-backoffice-ui/src/manifest.json b/packages/merchant-backoffice-ui/src/manifest.json @@ -11,4 +11,4 @@ "theme_color": "#db7093", "background_color": "#222222", "display": "fullscreen" -} -\ No newline at end of file +} diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx @@ -108,7 +108,7 @@ export function CreatePage({ onConfirm, onBack, forceId }: Props): VNode { console.log("invalid phone regex", e); } } - + const errors = undefinedIfEmpty<FormErrors<Entity>>({ id: !value.id ? i18n.str`Required` diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx @@ -17,9 +17,7 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { - TalerMerchantApi -} from "@gnu-taler/taler-util"; +import { TalerMerchantApi } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { CreatePage } from "./CreatePage.js"; diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx b/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx @@ -83,18 +83,20 @@ export function View({ purge: boolean, challengeIds: string[], ) => { - const resp = await lib.instance.deleteInstance(token, instance.id, { challengeIds, purge }); + const resp = await lib.instance.deleteInstance(token, instance.id, { + challengeIds, + purge, + }); if (resp.type === "fail" && resp.case === HttpStatusCode.Accepted) { await maybeTryFirstMFA( lib.instance, mfa, resp.body, deleteAction.lambda((ids) => [token, instance, purge, ids]), - ) + ); } - return resp - } - , + return resp; + }, ); const [deleting, setDeleting] = useState<TalerMerchantApi.Instance>(); diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx @@ -23,7 +23,7 @@ import { HttpStatusCode, TalerError, TalerMerchantApi, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js"; @@ -61,7 +61,6 @@ export default function Instances({ } } - return ( <Fragment> <View @@ -69,7 +68,6 @@ export default function Instances({ onUpdate={onUpdate} onChangePassword={onChangePassword} onCreate={onCreate} - /> </Fragment> ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create-pos/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create-pos/CreatePage.tsx @@ -59,7 +59,6 @@ interface Props { onBack?: () => void; } - export function CreatePage({ onCreated, onBack }: Props): VNode { const { i18n } = useTranslationContext(); @@ -79,7 +78,7 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { const data: TalerMerchantApi.LoginTokenRequest = { scope: LoginTokenScope.OrderPos_Refreshable, description: `POS access from: ${state.name}`, - duration: Duration.toTalerProtocolDuration(Duration.fromSpec({days:10})), + duration: Duration.toTalerProtocolDuration(Duration.fromSpec({ days: 10 })), }; const create = safeFunctionHandler( @@ -89,13 +88,18 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { request: TalerMerchantApi.LoginTokenRequest, challengeIds: string[], ) => { - const resp = await lib.instance.createAccessToken(session.instance, pwd, request, { - challengeIds, - }) + const resp = await lib.instance.createAccessToken( + session.instance, + pwd, + request, + { + challengeIds, + }, + ); if (resp.type === "fail" && resp.case === HttpStatusCode.Accepted) { - await maybeTryFirstMFA(lib.instance, mfa, resp.body) + await maybeTryFirstMFA(lib.instance, mfa, resp.body); } - return resp + return resp; }, !!errors || !state.password ? undefined : [state.password, data, []], ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create-pos/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create-pos/index.tsx @@ -19,14 +19,11 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { - AbsoluteTime, - TalerMerchantApi -} from "@gnu-taler/taler-util"; +import { AbsoluteTime, TalerMerchantApi } from "@gnu-taler/taler-util"; import { QR_Generic, Time, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create/CreatePage.tsx @@ -130,13 +130,18 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { request: TalerMerchantApi.LoginTokenRequest, challengeIds: string[], ) => { - const resp = await lib.instance.createAccessToken(session.instance, pwd, request, { - challengeIds, - }) + const resp = await lib.instance.createAccessToken( + session.instance, + pwd, + request, + { + challengeIds, + }, + ); if (resp.type === "fail" && resp.case === HttpStatusCode.Accepted) { - await maybeTryFirstMFA(lib.instance, mfa, resp.body) + await maybeTryFirstMFA(lib.instance, mfa, resp.body); } - return resp + return resp; }, !!errors || !state.password ? undefined : [state.password, data, []], ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/create/index.tsx @@ -26,7 +26,6 @@ import { useState } from "preact/hooks"; import { ConfirmModal, Row } from "../../../../components/modal/index.js"; import { CreatePage } from "./CreatePage.js"; - const TALER_SCREEN_ID = 109; export type Entity = TalerMerchantApi.LoginTokenRequest; @@ -58,7 +57,8 @@ export default function AccessTokenCreatePage({ <tr> <td colSpan={3}> <i18n.Translate> - Copy the value of the access token and save it, as you cannot retrieve it again. + Copy the value of the access token and save it, as you + cannot retrieve it again. </i18n.Translate> </td> </tr> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/list/Table.tsx @@ -20,7 +20,10 @@ */ import { TokenInfo } from "@gnu-taler/taler-util"; -import { PaginationControl, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + PaginationControl, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; import { Fragment, h, VNode } from "preact"; import { StateUpdater, useState } from "preact/hooks"; @@ -46,7 +49,7 @@ export function CardTable({ tokens, onCreate, onDelete, - paginator + paginator, }: Props): VNode { const [rowSelection, rowSelectionHandler] = useState<string[]>([]); @@ -100,11 +103,7 @@ interface TableProps { paginator: PaginationControl; } -function Table({ - tokens, - onDelete, - paginator -}: TableProps): VNode { +function Table({ tokens, onDelete, paginator }: TableProps): VNode { const { i18n } = useTranslationContext(); const [preferences] = usePreference(); return ( diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accessTokens/list/index.tsx @@ -103,8 +103,7 @@ export default function AccessTokenListPage({ onCreate }: Props): VNode { <section class="section is-main-section"> <LocalNotificationBannerBulma notification={notification} /> - - <p style={{marginBottom: 10}}> + <p style={{ marginBottom: 10 }}> <a href={"#/access-token/new-pos"} class="has-icon"> <i class="icon mdi mdi-account-plus" /> <span class="menu-item-label"> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx @@ -180,7 +180,7 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { !session.token || !request ? undefined : [session.token, request, []], ); add.onSuccess = (resp) => { - onCreated(resp.h_wire) + onCreated(resp.h_wire); }; add.onFail = (fail) => { switch (fail.case) { diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx @@ -39,7 +39,7 @@ import { CreatePage } from "./CreatePage.js"; export type Entity = TalerMerchantApi.AccountAddDetails; interface Props { onBack?: () => void; - onConfirm: (id:string) => void; + onConfirm: (id: string) => void; } export default function CreateValidator({ onConfirm, onBack }: Props): VNode { diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/Table.tsx @@ -256,7 +256,8 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { <Tooltip text={i18n.str`Delete selected accounts from the database`} > - <button type="button" + <button + type="button" class="button is-danger is-small" onClick={() => onDelete(acc)} > @@ -298,7 +299,8 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { <Tooltip text={i18n.str`Delete selected accounts from the database`} > - <button type="button" + <button + type="button" class="button is-danger is-small" onClick={() => onDelete(acc)} > @@ -340,7 +342,8 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { <Tooltip text={i18n.str`Delete selected accounts from the database`} > - <button type="button" + <button + type="button" class="button is-danger is-small" onClick={() => onDelete(acc)} > @@ -382,7 +385,8 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { <Tooltip text={i18n.str`Delete selected accounts from the database`} > - <button type="button" + <button + type="button" class="button is-danger is-small" onClick={() => onDelete(acc)} > diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx @@ -314,7 +314,7 @@ export function UpdatePage({ account, onUpdated, onBack }: Props): VNode { /> ); } - const payto = Result.unpack(Paytos.fromString(account.payto_uri)) + const payto = Result.unpack(Paytos.fromString(account.payto_uri)); return ( <Fragment> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx @@ -23,11 +23,9 @@ import { HttpStatusCode, TalerError, TalerMerchantApi, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; @@ -53,8 +51,6 @@ export default function UpdateValidator({ const { state, lib } = useSessionContext(); const result = useBankAccountDetails(bid); - - const { i18n } = useTranslationContext(); if (!result) return <Loading />; @@ -75,7 +71,6 @@ export default function UpdateValidator({ } } - return ( <Fragment> <UpdatePage diff --git a/packages/merchant-backoffice-ui/src/paths/instance/categories/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/categories/create/index.tsx @@ -30,13 +30,9 @@ interface Props { } export default function CreateCategory({ onConfirm, onBack }: Props): VNode { - return ( <> - <CreatePage - onBack={onBack} - onCreated={onConfirm} - /> + <CreatePage onBack={onBack} onCreated={onConfirm} /> </> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/categories/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/categories/list/index.tsx @@ -22,7 +22,7 @@ import { HttpStatusCode, TalerError, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; @@ -66,7 +66,6 @@ export default function ListCategories({ onCreate, onSelect }: Props): VNode { return ( <Fragment> - <section class="section is-main-section"> <CardTable devices={result.body.categories} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/exchanges/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/exchanges/list/index.tsx @@ -25,20 +25,18 @@ import { TalerError, TalerMerchantApi, TranslatedString, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { NotificationCardBulma, Time, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; -import { - ConfirmModal -} from "../../../../components/modal/index.js"; +import { ConfirmModal } from "../../../../components/modal/index.js"; import { useBackendExchanges } from "../../../../hooks/exchanges.js"; import { ListPage } from "./ListPage.js"; @@ -147,7 +145,9 @@ function ShowExchangeStatus({ onCancel={onCancel} > <p style={{ paddingTop: 0 }}> - <b><i18n.Translate>This payment service is unavailable.</i18n.Translate></b>{" "} + <b> + <i18n.Translate>This payment service is unavailable.</i18n.Translate> + </b>{" "} <i18n.Translate> Next update will be at{" "} <Time diff --git a/packages/merchant-backoffice-ui/src/paths/instance/groups/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/groups/create/index.tsx @@ -27,14 +27,13 @@ interface Props { onConfirm: () => void; } -export default function CreateProductGroup({ onConfirm, onBack }: Props): VNode { - +export default function CreateProductGroup({ + onConfirm, + onBack, +}: Props): VNode { return ( <> - <CreatePage - onBack={onBack} - onCreated={onConfirm} - /> + <CreatePage onBack={onBack} onCreated={onConfirm} /> </> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/groups/list/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/groups/list/UpdatePage.tsx @@ -22,13 +22,13 @@ import { assertUnreachable, HttpStatusCode, - TalerMerchantApi + TalerMerchantApi, } from "@gnu-taler/taler-util"; import { ButtonBetterBulma, LocalNotificationBannerBulma, useLocalNotificationBetter, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/groups/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/groups/list/index.tsx @@ -22,7 +22,7 @@ import { HttpStatusCode, TalerError, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; @@ -59,7 +59,6 @@ export default function ListProductGroups({ onCreate }: Props): VNode { return ( <Fragment> - <section class="section is-main-section"> <CardTable devices={result.body.groups} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx @@ -23,7 +23,7 @@ import { assertUnreachable, Paytos, Result, - TalerMerchantApi + TalerMerchantApi, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx @@ -143,8 +143,7 @@ function ShowInstructionForKycRedirect({ )} <p style={{ paddingTop: 0 }}> <i18n.Translate> - The server responded with "{e.payto_uri}" which is - invalid. + The server responded with "{e.payto_uri}" which is invalid. </i18n.Translate> </p> </ConfirmModal> @@ -181,8 +180,8 @@ function ShowInstructionForKycRedirect({ )} <p style={{ paddingTop: 0 }}> <i18n.Translate> - The server is still synchronizing with the payment - service provider. + The server is still synchronizing with the payment service + provider. </i18n.Translate> </p> </ConfirmModal> @@ -361,9 +360,8 @@ function ShowInstructionForKycRedirect({ )} <p style={{ paddingTop: 0 }}> <i18n.Translate> - The server could not contact the payment service provider - due to a timeout, contact the system administrator or check again - later. + The server could not contact the payment service provider due to a + timeout, contact the system administrator or check again later. </i18n.Translate> </p> </ConfirmModal> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx @@ -23,7 +23,7 @@ import { HttpStatusCode, TalerError, TalerMerchantApi, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; @@ -43,7 +43,6 @@ interface Props { onConfirm: (id: string) => void; } export default function OrderCreate({ onConfirm, onBack }: Props): VNode { - const detailsResult = useInstanceDetails(); // FIXME: if the product list is big the will bring a lot of info const inventoryResult = useInstanceProducts(); @@ -85,7 +84,6 @@ export default function OrderCreate({ onConfirm, onBack }: Props): VNode { return ( <Fragment> - <CreatePage onBack={onBack} focus diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx @@ -666,7 +666,7 @@ function PaidPage({ }); }); } - const refundTaken = Amounts.stringify(totalRefundedTaken) + const refundTaken = Amounts.stringify(totalRefundedTaken); const maxTotalFee = Amounts.add(totalRefundedTaken, maxDepositFee).amount; const shouldBeWiredMinimum = Amounts.sub(amount, maxTotalFee).amount; // we have a minimum but not a price value @@ -1112,7 +1112,9 @@ export function DetailPage({ onBack, onSelectWireTransfer, }: Props): VNode { - const [showRefund, setShowRefund] = useState<TalerMerchantApi.CheckPaymentPaidResponse | undefined>(undefined); + const [showRefund, setShowRefund] = useState< + TalerMerchantApi.CheckPaymentPaidResponse | undefined + >(undefined); const { i18n } = useTranslationContext(); const DetailByStatus = function () { switch (selected.order_status) { diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx @@ -19,9 +19,7 @@ import { TalerErrorCode, assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; @@ -35,10 +33,14 @@ const TALER_SCREEN_ID = 45; export interface Props { oid: string; onBack: () => void; - onSelectWireTransfer: (id:number) => void; + onSelectWireTransfer: (id: number) => void; } -export default function Update({ oid, onBack, onSelectWireTransfer }: Props): VNode { +export default function Update({ + oid, + onBack, + onSelectWireTransfer, +}: Props): VNode { const result = useOrderDetailsWithLongPoll(oid); const { i18n } = useTranslationContext(); @@ -66,7 +68,6 @@ export default function Update({ oid, onBack, onSelectWireTransfer }: Props): VN return ( <Fragment> - <DetailPage onBack={onBack} onSelectWireTransfer={onSelectWireTransfer} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx @@ -20,7 +20,10 @@ */ import { TalerMerchantApi } from "@gnu-taler/taler-util"; -import { PaginationControl, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + PaginationControl, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { WithId } from "../../../../declaration.js"; import { OrderListSection } from "./index.js"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx @@ -151,7 +151,7 @@ interface TableProps { export function PaginationRow({ paginator }: { paginator: PaginationControl }) { const { i18n } = useTranslationContext(); if (!paginator.loadNext && !paginator.loadPrev) { - return <Fragment /> + return <Fragment />; } return ( <div diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx @@ -32,7 +32,7 @@ interface Props { export function CreatedSuccessfully({ entity, onConfirm }: Props): VNode { const { i18n } = useTranslationContext(); const { state } = useSessionContext(); - const issuer = state.backendUrl.href.replace(/.*:\/\//, ""); // remove http(s):// + const issuer = state.backendUrl.href.replace(/.*:\/\//, ""); // remove http(s):// const qrText = `otpauth://totp/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`; const qrTextSafe = `otpauth://totp/${ entity.otp_device_id diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx @@ -20,7 +20,10 @@ */ import { TalerMerchantApi } from "@gnu-taler/taler-util"; -import { LocalNotificationBannerBulma, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + LocalNotificationBannerBulma, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { useSessionContext } from "../../../../context/session.js"; @@ -43,10 +46,7 @@ export default function CreateValidator({ onConfirm, onBack }: Props): VNode { return ( <> - <CreatePage - onBack={onBack} - onCreated={setCreated} - /> + <CreatePage onBack={onBack} onCreated={setCreated} /> </> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx @@ -23,11 +23,11 @@ import { HttpStatusCode, TalerError, TalerMerchantApi, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { LocalNotificationBannerBulma, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; @@ -68,7 +68,7 @@ export default function UpdateValidator({ return <NotFoundPageOrAdminCreate />; } case HttpStatusCode.Unauthorized: { - return <LoginPage focus /> + return <LoginPage focus />; } default: { assertUnreachable(result); @@ -97,8 +97,8 @@ export default function UpdateValidator({ otp_device_description: d.otp_device_description, otp_device_id: d.id, otp_key: d.otp_key, - otp_ctr: d.otp_ctr - }) + otp_ctr: d.otp_ctr, + }); }} /> </Fragment> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/password/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/password/index.tsx @@ -82,7 +82,6 @@ export default function PasswordPage({ onCancel, onChange }: Props): VNode { next: string, challengeIds: string[], ) => { - const created = await lib.instance.createAccessToken( instanceId, current, @@ -109,7 +108,7 @@ export default function PasswordPage({ onCancel, onChange }: Props): VNode { if (updated.type === "fail" && updated.case === HttpStatusCode.Accepted) { await maybeTryFirstMFA(lib.instance, mfa, updated.body); } - return updated + return updated; }, !session.token ? undefined : [session.token, "", "", []], ); @@ -235,7 +234,7 @@ export function AdminPassword({ if (resp.type === "fail" && resp.case === HttpStatusCode.Accepted) { await maybeTryFirstMFA(lib.instance, mfa, resp.body); } - return resp + return resp; }, !session.token ? undefined : [session.token, instanceId, "", []], ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/password/stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/password/stories.tsx @@ -25,4 +25,3 @@ export default { title: "Pages/Token", component: TestedComponent, }; - diff --git a/packages/merchant-backoffice-ui/src/paths/instance/pots/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/pots/create/index.tsx @@ -28,13 +28,9 @@ interface Props { } export default function CreateMoneyPots({ onConfirm, onBack }: Props): VNode { - return ( <> - <CreatePage - onBack={onBack} - onCreated={onConfirm} - /> + <CreatePage onBack={onBack} onCreated={onConfirm} /> </> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/pots/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/pots/update/UpdatePage.tsx @@ -27,7 +27,7 @@ import { InternationalizationAPI, PotDetailResponse, TalerMerchantApi, - TranslatedString + TranslatedString, } from "@gnu-taler/taler-util"; import { ButtonBetterBulma, diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx @@ -41,10 +41,11 @@ import { Tooltip } from "../../../../components/Tooltip.js"; import { useSessionContext } from "../../../../context/session.js"; import { useInstanceCategories } from "../../../../hooks/category.js"; import { useInstanceProductGroups } from "../../../../hooks/groups.js"; +import { useInstanceMoneyPots } from "../../../../hooks/pots.js"; import { - useInstanceMoneyPots -} from "../../../../hooks/pots.js"; -import { LimitedKycActionWarning, MissingBankAccountsWarning } from "../../accounts/list/index.js"; + LimitedKycActionWarning, + MissingBankAccountsWarning, +} from "../../accounts/list/index.js"; const TALER_SCREEN_ID = 87; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx @@ -29,13 +29,9 @@ interface Props { onConfirm: () => void; } export default function CreateProduct({ onConfirm, onBack }: Props): VNode { - return ( <Fragment> - <CreatePage - onBack={onBack} - onCreate={onConfirm} - /> + <CreatePage onBack={onBack} onCreate={onConfirm} /> </Fragment> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx @@ -19,7 +19,12 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util"; +import { + HttpStatusCode, + TalerError, + TalerMerchantApi, + assertUnreachable, +} from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; @@ -51,7 +56,7 @@ export default function UpdateProduct({ return <NotFoundPageOrAdminCreate />; } case HttpStatusCode.Unauthorized: { - return <LoginPage focus /> + return <LoginPage focus />; } default: { assertUnreachable(result); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reports/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reports/create/index.tsx @@ -27,14 +27,13 @@ interface Props { onConfirm: () => void; } -export default function CreateScheduledReport({ onConfirm, onBack }: Props): VNode { - +export default function CreateScheduledReport({ + onConfirm, + onBack, +}: Props): VNode { return ( <> - <CreatePage - onBack={onBack} - onCreated={onConfirm} - /> + <CreatePage onBack={onBack} onCreated={onConfirm} /> </> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/statistics/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/statistics/list/index.tsx @@ -22,7 +22,7 @@ import { AbsoluteTime, Duration, - StatisticBucketRange + StatisticBucketRange, } from "@gnu-taler/taler-util"; import { VNode, h } from "preact"; import { useState } from "preact/hooks"; @@ -31,13 +31,12 @@ import "chartjs-adapter-date-fns"; import { useSessionContext } from "../../../../context/session.js"; import { MerchantOrderStatsSlug, - MerchantRevenueStatsSlug + MerchantRevenueStatsSlug, } from "../../../../hooks/statistics.js"; import { OrdersChart } from "./OrdersChart.js"; import { RevenueChart } from "./RevenueChart.js"; interface Props {} - export interface StatSlug { slug: string; text: string; @@ -82,7 +81,7 @@ export default function Statistics({}: Props): VNode { const availableCurrencies = Object.keys(config.currencies); // FIXME: throw meaningful error if backend is missconfigured // it should always have at least 1 currency - + const [revenueChartFilter, setRevenueChartFilter] = useState<RevenueChartFilter>({ range: StatisticBucketRange.Quarter, diff --git a/packages/merchant-backoffice-ui/src/paths/instance/statistics/list/testing.ts b/packages/merchant-backoffice-ui/src/paths/instance/statistics/list/testing.ts @@ -20,7 +20,7 @@ */ import { - StatisticBucketRange, + StatisticBucketRange, StatisticsAmount, StatisticsCounter, } from "@gnu-taler/taler-util"; @@ -31,414 +31,374 @@ export function addTestValues( ) { // FIXME only for testing; const ordersCreated = { - "intervals": [ - { - "start_time": { - "t_s": 1763155101 - }, - "cumulative_counter": 0 - }, - { - "start_time": { - "t_s": 1763155041 - }, - "cumulative_counter": 19 - }, - { - "start_time": { - "t_s": 1763154901 - }, - "cumulative_counter": 2 - }, - { - "start_time": { - "t_s": 1760153641 - }, - "cumulative_counter": 9 - } + intervals: [ + { + start_time: { + t_s: 1763155101, + }, + cumulative_counter: 0, + }, + { + start_time: { + t_s: 1763155041, + }, + cumulative_counter: 19, + }, + { + start_time: { + t_s: 1763154901, + }, + cumulative_counter: 2, + }, + { + start_time: { + t_s: 1760153641, + }, + cumulative_counter: 9, + }, ], - "buckets": [], - "intervals_description": "number of orders created (but not necessarily claimed by wallets)" + buckets: [], + intervals_description: + "number of orders created (but not necessarily claimed by wallets)", }; const ordersClaimed = { - "intervals": [ - { - "start_time": { - "t_s": 1763155101 - }, - "cumulative_counter": 5 - }, - { - "start_time": { - "t_s": 1763155041 - }, - "cumulative_counter": 19 - }, - { - "start_time": { - "t_s": 1763154901 - }, - "cumulative_counter": 2 - }, - { - "start_time": { - "t_s": 1763154641 - }, - "cumulative_counter": 9 - }, - { - "start_time": { - "t_s": 1760153641 - }, - "cumulative_counter": 3 - } + intervals: [ + { + start_time: { + t_s: 1763155101, + }, + cumulative_counter: 5, + }, + { + start_time: { + t_s: 1763155041, + }, + cumulative_counter: 19, + }, + { + start_time: { + t_s: 1763154901, + }, + cumulative_counter: 2, + }, + { + start_time: { + t_s: 1763154641, + }, + cumulative_counter: 9, + }, + { + start_time: { + t_s: 1760153641, + }, + cumulative_counter: 3, + }, ], - "buckets": [], - "intervals_description": "number of orders claimed" + buckets: [], + intervals_description: "number of orders claimed", }; const ordersPaid = { - "intervals": [ - { - "start_time": { - "t_s": 1763155101 - }, - "cumulative_counter": 5 - }, - { - "start_time": { - "t_s": 1763155041 - }, - "cumulative_counter": 19 - }, - { - "start_time": { - "t_s": 1763154901 - }, - "cumulative_counter": 2 - }, - { - "start_time": { - "t_s": 1763154641 - }, - "cumulative_counter": 9 - }, - { - "start_time": { - "t_s": 1760153641 - }, - "cumulative_counter": 3 - } - ], - "buckets": [], - "intervals_description": "number of orders paid" + intervals: [ + { + start_time: { + t_s: 1763155101, + }, + cumulative_counter: 5, + }, + { + start_time: { + t_s: 1763155041, + }, + cumulative_counter: 19, + }, + { + start_time: { + t_s: 1763154901, + }, + cumulative_counter: 2, + }, + { + start_time: { + t_s: 1763154641, + }, + cumulative_counter: 9, + }, + { + start_time: { + t_s: 1760153641, + }, + cumulative_counter: 3, + }, + ], + buckets: [], + intervals_description: "number of orders paid", }; const ordersSettled = { - "intervals": [ - { - "start_time": { - "t_s": 1763155101 - }, - "cumulative_counter": 4 - }, - { - "start_time": { - "t_s": 1763155041 - }, - "cumulative_counter": 19 - }, - { - "start_time": { - "t_s": 1763154901 - }, - "cumulative_counter": 2 - }, - { - "start_time": { - "t_s": 1763154641 - }, - "cumulative_counter": 9 - }, - { - "start_time": { - "t_s": 1760153641 - }, - "cumulative_counter": 3 - } - ], - "buckets": [], - "intervals_description": "number of orders settled" - } + intervals: [ + { + start_time: { + t_s: 1763155101, + }, + cumulative_counter: 4, + }, + { + start_time: { + t_s: 1763155041, + }, + cumulative_counter: 19, + }, + { + start_time: { + t_s: 1763154901, + }, + cumulative_counter: 2, + }, + { + start_time: { + t_s: 1763154641, + }, + cumulative_counter: 9, + }, + { + start_time: { + t_s: 1760153641, + }, + cumulative_counter: 3, + }, + ], + buckets: [], + intervals_description: "number of orders settled", + }; const depositFees: StatisticsAmount = { - "intervals": [], - "buckets": [ - { - "start_time": { - "t_s": 1763157600 - }, - "end_time": { - "t_s": 1763078400 - }, - "range": StatisticBucketRange.Hour, - "cumulative_amounts": [ - "EUR:0.11" - ] - }, - { - "start_time": { - "t_s": 1763078400 - }, - "end_time": { - "t_s": 1763164800 - }, - "range": StatisticBucketRange.Day, - "cumulative_amounts": [ - "EUR:0.21" - ] - }, - { - "start_time": { - "t_s": 1762732800 - }, - "end_time": { - "t_s": 1763337600 - }, - "range": StatisticBucketRange.Week, - "cumulative_amounts": [ - "EUR:0.31" - ] - }, - { - "start_time": { - "t_s": 1761955200 - }, - "end_time": { - "t_s": 1764547200 - }, - "range": StatisticBucketRange.Month, - "cumulative_amounts": [ - "EUR:0.51" - ] - }, - { - "start_time": { - "t_s": 1751328000 - }, - "end_time": { - "t_s": 1759276800 - }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:3.10" - ] - }, - { - "start_time": { - "t_s": 1759276800 - }, - "end_time": { - "t_s": 1767225600 - }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:1.11" - ] - }, - { - "start_time": { - "t_s": 1735689600 - }, - "end_time": { - "t_s": 1767225600 - }, - "range": StatisticBucketRange.Year, - "cumulative_amounts": [ - "EUR:2.11" - ] - } + intervals: [], + buckets: [ + { + start_time: { + t_s: 1763157600, + }, + end_time: { + t_s: 1763078400, + }, + range: StatisticBucketRange.Hour, + cumulative_amounts: ["EUR:0.11"], + }, + { + start_time: { + t_s: 1763078400, + }, + end_time: { + t_s: 1763164800, + }, + range: StatisticBucketRange.Day, + cumulative_amounts: ["EUR:0.21"], + }, + { + start_time: { + t_s: 1762732800, + }, + end_time: { + t_s: 1763337600, + }, + range: StatisticBucketRange.Week, + cumulative_amounts: ["EUR:0.31"], + }, + { + start_time: { + t_s: 1761955200, + }, + end_time: { + t_s: 1764547200, + }, + range: StatisticBucketRange.Month, + cumulative_amounts: ["EUR:0.51"], + }, + { + start_time: { + t_s: 1751328000, + }, + end_time: { + t_s: 1759276800, + }, + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:3.10"], + }, + { + start_time: { + t_s: 1759276800, + }, + end_time: { + t_s: 1767225600, + }, + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:1.11"], + }, + { + start_time: { + t_s: 1735689600, + }, + end_time: { + t_s: 1767225600, + }, + range: StatisticBucketRange.Year, + cumulative_amounts: ["EUR:2.11"], + }, ], - "buckets_description": "deposit fees we or our customers paid to the payment service (includes those waived on refunds)" - } + buckets_description: + "deposit fees we or our customers paid to the payment service (includes those waived on refunds)", + }; const paymentsReceived: StatisticsAmount = { - "intervals": [], - "buckets": [ + intervals: [], + buckets: [ { - "start_time": { - "t_s": 1763146800 + start_time: { + t_s: 1763146800, }, - "end_time": { - "t_s": 1763078400 + end_time: { + t_s: 1763078400, }, - "range": StatisticBucketRange.Hour, - "cumulative_amounts": [ - "EUR:4.89" - ] + range: StatisticBucketRange.Hour, + cumulative_amounts: ["EUR:4.89"], }, { - "start_time": { - "t_s": 1763078400 + start_time: { + t_s: 1763078400, }, - "end_time": { - "t_s": 1763164800 + end_time: { + t_s: 1763164800, }, - "range": StatisticBucketRange.Day, - "cumulative_amounts": [ - "EUR:14.89" - ] + range: StatisticBucketRange.Day, + cumulative_amounts: ["EUR:14.89"], }, { - "start_time": { - "t_s": 1762732800 + start_time: { + t_s: 1762732800, }, - "end_time": { - "t_s": 1763337600 + end_time: { + t_s: 1763337600, }, - "range": StatisticBucketRange.Week, - "cumulative_amounts": [ - "EUR:27.89" - ] + range: StatisticBucketRange.Week, + cumulative_amounts: ["EUR:27.89"], }, { - "start_time": { - "t_s": 1761955200 + start_time: { + t_s: 1761955200, }, - "end_time": { - "t_s": 1764547200 + end_time: { + t_s: 1764547200, }, - "range": StatisticBucketRange.Month, - "cumulative_amounts": [ - "EUR:34.89" - ] + range: StatisticBucketRange.Month, + cumulative_amounts: ["EUR:34.89"], }, { - "start_time": { - "t_s": 1751328000 + start_time: { + t_s: 1751328000, }, - "end_time": { - "t_s": 1759276800 + end_time: { + t_s: 1759276800, }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:18.99" - ] + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:18.99"], }, { - "start_time": { - "t_s": 1759276800 + start_time: { + t_s: 1759276800, }, - "end_time": { - "t_s": 1767225600 + end_time: { + t_s: 1767225600, }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:34.89" - ] + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:34.89"], }, { - "start_time": { - "t_s": 1735689600 + start_time: { + t_s: 1735689600, }, - "end_time": { - "t_s": 1767225600 + end_time: { + t_s: 1767225600, }, - "range": StatisticBucketRange.Year, - "cumulative_amounts": [ - "EUR:54.89" - ] - } + range: StatisticBucketRange.Year, + cumulative_amounts: ["EUR:54.89"], + }, ], - "buckets_description": "amount customers paid to us (excluded deposit fees paid by us or customers, wire fees are still deducted by the payment service)" - } + buckets_description: + "amount customers paid to us (excluded deposit fees paid by us or customers, wire fees are still deducted by the payment service)", + }; const testRefundsBuckets: StatisticsAmount = { - intervals: [], + intervals: [], buckets: [ { - "start_time": { - "t_s": 1763146800 + start_time: { + t_s: 1763146800, }, - "end_time": { - "t_s": 1763078400 + end_time: { + t_s: 1763078400, }, - "range": StatisticBucketRange.Hour, - "cumulative_amounts": [ - "EUR:0" - ] + range: StatisticBucketRange.Hour, + cumulative_amounts: ["EUR:0"], }, { - "start_time": { - "t_s": 1763078400 + start_time: { + t_s: 1763078400, }, - "end_time": { - "t_s": 1763164800 + end_time: { + t_s: 1763164800, }, - "range": StatisticBucketRange.Day, - "cumulative_amounts": [ - "EUR:2" - ] + range: StatisticBucketRange.Day, + cumulative_amounts: ["EUR:2"], }, { - "start_time": { - "t_s": 1762732800 + start_time: { + t_s: 1762732800, }, - "end_time": { - "t_s": 1763337600 + end_time: { + t_s: 1763337600, }, - "range": StatisticBucketRange.Week, - "cumulative_amounts": [ - "EUR:3" - ] + range: StatisticBucketRange.Week, + cumulative_amounts: ["EUR:3"], }, { - "start_time": { - "t_s": 1761955200 + start_time: { + t_s: 1761955200, }, - "end_time": { - "t_s": 1764547200 + end_time: { + t_s: 1764547200, }, - "range": StatisticBucketRange.Month, - "cumulative_amounts": [ - "EUR:4" - ] + range: StatisticBucketRange.Month, + cumulative_amounts: ["EUR:4"], }, { - "start_time": { - "t_s": 1751328000 + start_time: { + t_s: 1751328000, }, - "end_time": { - "t_s": 1759276800 + end_time: { + t_s: 1759276800, }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:8" - ] + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:8"], }, { - "start_time": { - "t_s": 1759276800 + start_time: { + t_s: 1759276800, }, - "end_time": { - "t_s": 1767225600 + end_time: { + t_s: 1767225600, }, - "range": StatisticBucketRange.Quarter, - "cumulative_amounts": [ - "EUR:6" - ] + range: StatisticBucketRange.Quarter, + cumulative_amounts: ["EUR:6"], }, { - "start_time": { - "t_s": 1735689600 + start_time: { + t_s: 1735689600, }, - "end_time": { - "t_s": 1767225600 + end_time: { + t_s: 1767225600, }, - "range": StatisticBucketRange.Year, - "cumulative_amounts": [ - "EUR:7", - "KUDOS:23" - ] - } + range: StatisticBucketRange.Year, + cumulative_amounts: ["EUR:7", "KUDOS:23"], + }, ], - "buckets_description": "refunds granted by us to our customers" - } + buckets_description: "refunds granted by us to our customers", + }; ordersStats.set("orders-created", ordersCreated); ordersStats.set("orders-claimed", ordersClaimed); ordersStats.set("orders-paid", ordersPaid); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx @@ -183,8 +183,8 @@ export function CreatePage({ editable_defaults: { amount: !state.amount_editable ? undefined - : state.amount ?? Amounts.stringify(zero), - summary: !state.summary_editable ? undefined : state.summary ?? "", + : (state.amount ?? Amounts.stringify(zero)), + summary: !state.summary_editable ? undefined : (state.summary ?? ""), currency: cList.length === 1 || !state.currency_editable ? undefined diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/index.tsx @@ -40,7 +40,7 @@ interface Props { export default function CreateTemplate({ onConfirm, onBack }: Props): VNode { const result = useInstanceDetails(); - + if (!result) return <Loading />; if (result instanceof TalerError) { return <ErrorLoadingMerchant error={result} />; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx @@ -44,8 +44,8 @@ export function QrPage({ id: templateId, onBack }: Props): VNode { const { state } = useSessionContext(); const merchantBaseUrl = state.backendUrl.href as HostPortPath; - const uri = TalerUris.createTalerPayTemplate(merchantBaseUrl, templateId) - const stringUri = TalerUris.toString(uri) + const uri = TalerUris.createTalerPayTemplate(merchantBaseUrl, templateId); + const stringUri = TalerUris.toString(uri); const printThis = useRef<HTMLElement>(null); return ( diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx @@ -103,9 +103,9 @@ function UpdateFixedOrderPage({ template, onUpdated, onBack }: Props): VNode { const [notification, safeFunctionHandler] = useLocalNotificationBetter(); if (template.template_contract.template_type !== TemplateType.FIXED_ORDER) { - return <Fragment /> + return <Fragment />; } - + const cList = Object.values(config.currencies).map((d) => d.name); const supportedCurrencies = Object.keys(config.currencies); const currentAmount = @@ -223,8 +223,8 @@ function UpdateFixedOrderPage({ template, onUpdated, onBack }: Props): VNode { template_description: state.description!, template_contract, editable_defaults: { - amount: !state.amount_editable ? undefined : state.amount ?? zero, - summary: !state.summary_editable ? undefined : state.summary ?? "", + amount: !state.amount_editable ? undefined : (state.amount ?? zero), + summary: !state.summary_editable ? undefined : (state.summary ?? ""), currency: cList.length === 1 || !state.currency_editable ? undefined @@ -419,10 +419,10 @@ function UpdateFixedOrderPage({ template, onUpdated, onBack }: Props): VNode { ); } function UpdatePaivanaPage({ template, onUpdated, onBack }: Props): VNode { - return <div>unsupported paivana template</div> + return <div>unsupported paivana template</div>; } function UpdateInventoryPage({ template, onUpdated, onBack }: Props): VNode { - return <div>unsupported inventory template</div> + return <div>unsupported inventory template</div>; } export function UpdatePage(props: Props): VNode { diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx @@ -25,7 +25,11 @@ import { TalerMerchantApi, assertUnreachable, } from "@gnu-taler/taler-util"; -import { LocalNotificationBannerBulma, useLocalNotificationBetter, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + LocalNotificationBannerBulma, + useLocalNotificationBetter, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/CreatePage.tsx @@ -71,12 +71,12 @@ const lastDayNextMonth = endOfMonth(nextMonth); const afterLastDayNextMonth = addDays(lastDayNextMonth, 1); const firstDayNextMonthAnd30Days = addDays(firstDayNextMonth, 30); -const MINUTE = TalerProtocolDuration.fromSpec({minutes: 1}) -const HOUR = TalerProtocolDuration.fromSpec({hours: 1}) -const DAY = TalerProtocolDuration.fromSpec({days: 1}) -const MONTH = TalerProtocolDuration.fromSpec({days: 30}) -const THREE_MONTH = TalerProtocolDuration.fromSpec({days: 90}) -const YEAR = TalerProtocolDuration.fromSpec({days: 365}) +const MINUTE = TalerProtocolDuration.fromSpec({ minutes: 1 }); +const HOUR = TalerProtocolDuration.fromSpec({ hours: 1 }); +const DAY = TalerProtocolDuration.fromSpec({ days: 1 }); +const MONTH = TalerProtocolDuration.fromSpec({ days: 30 }); +const THREE_MONTH = TalerProtocolDuration.fromSpec({ days: 90 }); +const YEAR = TalerProtocolDuration.fromSpec({ days: 365 }); export function CreatePage({ onCreated, onBack }: Props): VNode { const { state: session, lib } = useSessionContext(); @@ -231,7 +231,15 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { name="validity_granularity" label={i18n.str`Validity Granularity`} tooltip={i18n.str`Rounds the validity to a specific unit of time.`} - values={[undefined, "MINUTE", "HOUR", "DAY", "MONTH", "THREE_MONTH", "YEAR"]} + values={[ + undefined, + "MINUTE", + "HOUR", + "DAY", + "MONTH", + "THREE_MONTH", + "YEAR", + ]} toStr={(str) => { if (str === "MINUTE") return i18n.str`1 minute`; if (str === "HOUR") return i18n.str`1 hour`; @@ -248,7 +256,7 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { if (str === "MONTH") return MONTH; if (str === "THREE_MONTH") return THREE_MONTH; if (str === "YEAR") return YEAR; - return undefined + return undefined; }} /> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/tokenfamilies/create/index.tsx @@ -29,13 +29,9 @@ interface Props { onConfirm: () => void; } export default function CreateTokenFamily({ onConfirm, onBack }: Props): VNode { - return ( <Fragment> - <CreatePage - onBack={onBack} - onCreated={onConfirm} - /> + <CreatePage onBack={onBack} onCreated={onConfirm} /> </Fragment> ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/DetailsPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/DetailsPage.tsx @@ -5,7 +5,7 @@ import { ExpectedTransferDetails, ExpectedTransferEntry, HttpStatusCode, - TalerError + TalerError, } from "@gnu-taler/taler-util"; import { ButtonBetterBulma, @@ -25,9 +25,7 @@ import { datetimeFormatForPreferences, usePreference, } from "../../../../hooks/preference.js"; -import { - useInstanceIncomingTransferDetails -} from "../../../../hooks/transfer.js"; +import { useInstanceIncomingTransferDetails } from "../../../../hooks/transfer.js"; import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js"; import { getOrderAmountAndMaxDepositFee } from "../../orders/details/DetailPage.js"; diff --git a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx @@ -98,13 +98,11 @@ function ListTransferWithBank({ let incoming: PaginatedResult<ExpectedTransferEntry[]>; { - const result = useInstanceIncomingTransfers( - { - payto_uri: form.payto_uri === "" ? undefined : form.payto_uri, - verified: form.verified, - confirmed: false, - }, - ); + const result = useInstanceIncomingTransfers({ + payto_uri: form.payto_uri === "" ? undefined : form.payto_uri, + verified: form.verified, + confirmed: false, + }); if (!result) return <Loading />; if (result instanceof TalerError) { @@ -127,13 +125,11 @@ function ListTransferWithBank({ } let confirmed: PaginatedResult<TransferDetails[]>; { - const result = useInstanceConfirmedTransfers( - { - payto_uri: form.payto_uri === "" ? undefined : form.payto_uri, - // expected: form.expected, - verified: form.verified, - }, - ); + const result = useInstanceConfirmedTransfers({ + payto_uri: form.payto_uri === "" ? undefined : form.payto_uri, + // expected: form.expected, + verified: form.verified, + }); if (!result) return <Loading />; if (result instanceof TalerError) { @@ -202,8 +198,8 @@ function ListTransferInternal({ return d; }} toStr={(d) => { - const pt = Result.orUndefined(Paytos.fromString(d)) - return pt?.displayName ?? d + const pt = Result.orUndefined(Paytos.fromString(d)); + return pt?.displayName ?? d; }} placeholder={i18n.str`All accounts`} tooltip={i18n.str`Filter by account address`} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/DeletePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/DeletePage.tsx @@ -83,7 +83,7 @@ export function DeletePage({ instanceId, onBack, onDeleted }: Props): VNode { const resp = await lib.instance.deleteCurrentInstance(token, { purge, challengeIds, - }) + }); if (resp.type === "fail" && resp.case === HttpStatusCode.Accepted) { await maybeTryFirstMFA( lib.instance, @@ -92,7 +92,7 @@ export function DeletePage({ instanceId, onBack, onDeleted }: Props): VNode { remove.lambda((ids: string[]) => [token, purge, ids]), ); } - return resp + return resp; }, !session.token ? undefined : [session.token, form.purge!!, []], ); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx @@ -91,7 +91,7 @@ export function UpdatePage({ }: Props): VNode { const { state, config, lib } = useSessionContext(); - const initial = convert(selected) + const initial = convert(selected); const [value, valueHandler] = useState<Partial<Entity>>(initial); const { i18n } = useTranslationContext(); @@ -192,7 +192,9 @@ export function UpdatePage({ } return resp; }, - hasErrors || cleanForm || !state.token ? undefined : [state.token, result, []], + hasErrors || cleanForm || !state.token + ? undefined + : [state.token, result, []], ); update.onSuccess = onConfirm; update.onFail = (fail) => { @@ -322,8 +324,10 @@ function deepEqual(obj1: unknown, obj2: unknown): boolean { if (obj1 === obj2) return true; if ( - typeof obj1 !== 'object' || obj1 === null || - typeof obj2 !== 'object' || obj2 === null + typeof obj1 !== "object" || + obj1 === null || + typeof obj2 !== "object" || + obj2 === null ) { return false; } @@ -333,8 +337,9 @@ function deepEqual(obj1: unknown, obj2: unknown): boolean { if (keys1.length !== keys2.length) return false; - return keys1.every(key => - Object.prototype.hasOwnProperty.call(obj2, key) && - deepEqual((obj1 as any)[key], (obj2 as any)[key]) + return keys1.every( + (key) => + Object.prototype.hasOwnProperty.call(obj2, key) && + deepEqual((obj1 as any)[key], (obj2 as any)[key]), ); } diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx @@ -18,11 +18,9 @@ import { TalerError, TalerMerchantInstanceHttpClient, TalerMerchantManagementResultByMethod, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js"; @@ -67,7 +65,6 @@ function CommonUpdate( | undefined, updateInstance: typeof TalerMerchantInstanceHttpClient.prototype.updateCurrentInstance, ): VNode { - const { i18n } = useTranslationContext(); const { state } = useSessionContext(); const [deleting, setDeleting] = useState<boolean>(); @@ -90,8 +87,6 @@ function CommonUpdate( } } - - return ( <Fragment> <UpdatePage @@ -104,7 +99,8 @@ function CommonUpdate( <div class="columns"> <div class="column" /> <div class="column is-four-fifths"> - <button type="button" + <button + type="button" class="button " onClick={() => { setDeleting(true); diff --git a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/UpdatePage.tsx @@ -218,19 +218,16 @@ export function UpdatePage({ webhook, onConfirm, onBack }: Props): VNode { <i18n.Translate>Cancel</i18n.Translate> </button> )} - <Tooltip - text={ - hasErrors - ? i18n.str`Please complete the marked fields` - : i18n.str`Confirm operation` - } - > - <ButtonBetterBulma - onClick={update} - type="submit" + <Tooltip + text={ + hasErrors + ? i18n.str`Please complete the marked fields` + : i18n.str`Confirm operation` + } > - <i18n.Translate>Confirm</i18n.Translate> - </ButtonBetterBulma> + <ButtonBetterBulma onClick={update} type="submit"> + <i18n.Translate>Confirm</i18n.Translate> + </ButtonBetterBulma> </Tooltip> </div> </FormProvider> diff --git a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx @@ -31,7 +31,6 @@ import { import InstanceCreatePage from "../../paths/admin/create/index.js"; import { InstancePaths } from "../../Routing.js"; - const TALER_SCREEN_ID = 81; function NotFoundPage(): VNode { @@ -63,7 +62,7 @@ export function NotFoundPageOrAdminCreate(): VNode { onConfirm={() => { // we need to clear everything since we take some // 404 as "default instance don't exist" - cleanAllCache() + cleanAllCache(); route(InstancePaths.bank_list); }} /> @@ -71,5 +70,5 @@ export function NotFoundPageOrAdminCreate(): VNode { ); } - return <NotFoundPage /> + return <NotFoundPage />; } diff --git a/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss b/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss @@ -30,14 +30,14 @@ --primary-card-color: #fff; --primary-background-color: #f2f2f2; - --box-shadow-lvl-1: 0 1px 3px rgba(0, 0, 0, 0.12), - 0 1px 2px rgba(0, 0, 0, 0.24); - --box-shadow-lvl-2: 0 3px 6px rgba(0, 0, 0, 0.16), - 0 3px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-3: 0 10px 20px rgba(0, 0, 0, 0.19), - 0 6px 6px rgba(0, 0, 0, 0.23); - --box-shadow-lvl-4: 0 14px 28px rgba(0, 0, 0, 0.25), - 0 10px 10px rgba(0, 0, 0, 0.22); + --box-shadow-lvl-1: + 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + --box-shadow-lvl-2: + 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-3: + 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); + --box-shadow-lvl-4: + 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } .datePicker { @@ -51,7 +51,9 @@ width: 90vw; max-width: 448px; transform-origin: top left; - transition: transform 0.22s ease-in-out, opacity 0.22s ease-in-out; + transition: + transform 0.22s ease-in-out, + opacity 0.22s ease-in-out; top: 50%; left: 50%; opacity: 0; @@ -172,7 +174,9 @@ left: calc(50% - 21px); background: var(--primary-color); border-radius: 50%; - transition: transform 0.22s, opacity 0.22s; + transition: + transform 0.22s, + opacity 0.22s; transform: scale(0); opacity: 0; } diff --git a/packages/merchant-backoffice-ui/src/scss/_loading.scss b/packages/merchant-backoffice-ui/src/scss/_loading.scss @@ -63,5 +63,5 @@ width: 24px; height: 24px; margin: 2px; - border-width: 4px ; + border-width: 4px; } diff --git a/packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css b/packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css @@ -1,7 +1,8 @@ @font-face { font-family: "Material Design Icons"; src: url("./fonts/materialdesignicons-webfont-4.9.95.eot"); - src: url("./fonts/materialdesignicons-webfont-4.9.95.woff2") format("woff2"), + src: + url("./fonts/materialdesignicons-webfont-4.9.95.woff2") format("woff2"), url("./fonts/materialdesignicons-webfont-4.9.95.woff") format("woff"), url("./fonts/materialdesignicons-webfont-4.9.95.ttf") format("truetype"); font-weight: normal; diff --git a/packages/merchant-backoffice-ui/src/scss/main.scss b/packages/merchant-backoffice-ui/src/scss/main.scss @@ -70,7 +70,6 @@ $tooltip-color: red; top: 0; } - div { &.is-loading { position: relative; @@ -89,7 +88,7 @@ div { } } -input[type="checkbox"]:indeterminate+.check { +input[type="checkbox"]:indeterminate + .check { background: red !important; } @@ -188,15 +187,15 @@ div[data-tooltip]::before { position: absolute; } -.modal-card-body>p { +.modal-card-body > p { padding: 1em; } -.modal-card-body>p.warning { +.modal-card-body > p.warning { background-color: #fffbdd; border: solid 1px #f2e9bf; } - input.mfa-code::-webkit-outer-spin-button, +input.mfa-code::-webkit-outer-spin-button, input.mfa-code::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; @@ -207,7 +206,7 @@ input.mfa-code:focus { } /* Firefox */ -input.mfa-code[type=number] { +input.mfa-code[type="number"] { -moz-appearance: textfield; } @@ -227,10 +226,10 @@ input.mfa-code[type=number] { * Removing this will make all tables with button on the right * to show a horizontal side bar even when there is space for it */ -div.buttons.is-right{ +div.buttons.is-right { margin-right: 18px; } div.menu.is-menu-main a { display: flex; -} -\ No newline at end of file +} diff --git a/packages/merchant-backoffice-ui/src/scss/toggle.scss b/packages/merchant-backoffice-ui/src/scss/toggle.scss @@ -46,21 +46,21 @@ $green: #56c080; background: linear-gradient(to bottom, #ccc 0%, #bbb 100%); } - .toggle-checkbox:checked+& { + .toggle-checkbox:checked + & { background: $green; &:before { left: 30px; } } - .toggle-checkbox:not(checked)+& { + .toggle-checkbox:not(checked) + & { background: $grey-lighter; &:before { left: 4px; } } - .toggle-checkbox:indeterminate+& { + .toggle-checkbox:indeterminate + & { background: rgba(0, 0, 0, 0.301); &:before { @@ -68,7 +68,6 @@ $green: #56c080; background: rgba(0, 0, 0, 0.301); } } - } .toggle-checkbox { @@ -80,4 +79,4 @@ $green: #56c080; margin-left: 5px; position: relative; top: 2px; -} -\ No newline at end of file +} diff --git a/packages/merchant-backoffice-ui/src/settings.ts b/packages/merchant-backoffice-ui/src/settings.ts @@ -21,7 +21,7 @@ import { codecForBoolean, codecForList, codecForString, - codecOptional + codecOptional, } from "@gnu-taler/taler-util"; export interface MerchantUiSettings { @@ -80,11 +80,11 @@ export function buildDefaultBackendBaseURL(): string { ).href; /** * By default, merchant backend serves the html content - * from the /webui root. This should cover most of the + * from the /webui root. This should cover most of the * cases and the rootPath will be the merchant backend * URL where the instances are */ return canonicalizeBaseUrl(currentLocation.replace("/webui", "")); } - throw Error("No default URL") + throw Error("No default URL"); } diff --git a/packages/merchant-backoffice-ui/src/utils/amount.ts b/packages/merchant-backoffice-ui/src/utils/amount.ts @@ -22,7 +22,7 @@ import { /** * merge refund with the same description and a difference less than one minute - * + * * @param prev list of refunds that will hold the merged refunds * @param cur new refund to add to the list * @returns list with the new refund, may be merged with the last diff --git a/packages/merchant-backoffice-ui/src/utils/constants.ts b/packages/merchant-backoffice-ui/src/utils/constants.ts @@ -35,7 +35,6 @@ export const CROCKFORD_BASE32_REGEX = export const URL_REGEX = /^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/; - const PAGINATED_LIST_SIZE = 20; // when doing paginated request, ask for one more // and use it to know if there are more to request diff --git a/packages/merchant-backoffice-ui/src/utils/regex.test.ts b/packages/merchant-backoffice-ui/src/utils/regex.test.ts @@ -64,7 +64,6 @@ describe("amount format", () => { "LONGESTCURR:1,000,000.123,123", ]; - it("should be valid", () => { valids.forEach((v) => expect(v).match(AMOUNT_REGEX)); }); diff --git a/packages/merchant-backoffice-ui/src/utils/table.ts b/packages/merchant-backoffice-ui/src/utils/table.ts @@ -16,7 +16,6 @@ import { WithId } from "../declaration.js"; - /** * * @author Sebastian Javier Marchano (sebasjm) diff --git a/packages/merchant-backoffice-ui/src/utils/types.ts b/packages/merchant-backoffice-ui/src/utils/types.ts @@ -20,5 +20,4 @@ export interface KeyValue { [key: string]: string; } - export type ValueOrFunction<T> = T | ((p: T) => T); diff --git a/packages/taler-harness/src/env-full.ts b/packages/taler-harness/src/env-full.ts @@ -78,23 +78,27 @@ export async function runEnvFull(t: GlobalTestState): Promise<void> { await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }, + { adminAccessToken }, + ); console.log("setup done!"); } diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts @@ -568,8 +568,8 @@ export async function createSimpleTestkudosEnvironmentV3( const paivana = await PaivanaService.create(t, { destination: "https://grothoff.org/", - httpPort: 8088 - }) + httpPort: 8088, + }); const exchange = ExchangeService.create(t, { name: "testexchange-1", @@ -714,7 +714,7 @@ export async function createSimpleTestkudosEnvironmentV3( ); if (opts.paivanaWebsite) { - const instanceUrl = merchant.makeInstanceBaseUrl("admin") + const instanceUrl = merchant.makeInstanceBaseUrl("admin"); const api = new TalerMerchantInstanceHttpClient(instanceUrl); const t = await api.addTemplate(merchantAdminAccessToken, { template_id: "paivana", @@ -724,10 +724,10 @@ export async function createSimpleTestkudosEnvironmentV3( choices: [{ amount: "TESTKUDOS:1" }], website_regex: opts.paivanaWebsite, summary: "test", - } - }) - paivana.setMerchant(instanceUrl, merchantAdminAccessToken) - await paivana.start() + }, + }); + paivana.setMerchant(instanceUrl, merchantAdminAccessToken); + await paivana.start(); } console.log("setup done!"); @@ -1519,9 +1519,8 @@ export async function createKycTestkudosEnvironmentFull( ); const wireGatewayApi = new TalerWireGatewayHttpClient( - bankApi.getWireGatewayAPI( - exchangeBankAccount.wireGatewayAuth.username, - ).href, + bankApi.getWireGatewayAPI(exchangeBankAccount.wireGatewayAuth.username) + .href, { httpClient: harnessHttpLib, }, @@ -1667,9 +1666,8 @@ export async function createKycTestkudosEnvironment( ); const wireGatewayApi = new TalerWireGatewayHttpClient( - bankApi.getWireGatewayAPI( - exchangeBankAccount.wireGatewayAuth.username, - ).href, + bankApi.getWireGatewayAPI(exchangeBankAccount.wireGatewayAuth.username) + .href, { httpClient: harnessHttpLib, }, diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts @@ -684,8 +684,7 @@ class BankServiceBase { protected globalTestState: GlobalTestState, protected bankConfig: BankConfig, protected configFile: string, - - ) { } + ) {} } export type RestrictionFlag = "credit-restriction" | "debit-restriction"; @@ -711,7 +710,8 @@ export interface HarnessExchangeBankAccount { */ export class FakebankService extends BankServiceBase - implements BankServiceHandle { + implements BankServiceHandle +{ proc: ProcessWrapper | undefined; http = createPlatformHttpLib({ enableThrottling: false }); @@ -754,7 +754,7 @@ export class FakebankService type: "basic", username: "admin", password: "admin-password", - } + }; } static fromExistingConfig( @@ -914,7 +914,7 @@ export class LibeufinNexusService { private gc: GlobalTestState, private bc: NexusConfig, private configFile: string, - ) { } + ) {} async dbinit(): Promise<void> { await sh( @@ -930,7 +930,8 @@ export class LibeufinNexusService { */ export class LibeufinBankService extends BankServiceBase - implements BankServiceHandle { + implements BankServiceHandle +{ proc: ProcessWrapper | undefined; http = createPlatformHttpLib({ enableThrottling: false }); @@ -994,7 +995,7 @@ export class LibeufinBankService } getAdminAuth(): BasicOrTokenAuth { - return this.adminAuth + return this.adminAuth; } static fromExistingConfig( @@ -1111,27 +1112,32 @@ export class LibeufinBankService succeedOrThrow(await bankClient.getConfig()); // Create admin token const token = succeedOrThrow( - await bankClient.createAccessToken("admin", { - type: "basic", - username: "admin", - password: "admin-password" - }, { - scope: "readwrite", - }), + await bankClient.createAccessToken( + "admin", + { + type: "basic", + username: "admin", + password: "admin-password", + }, + { + scope: "readwrite", + }, + ), ); this.adminAuth = { type: "bearer", - token: token.access_token + token: token.access_token, }; // Register accounts for (const acc of this.accounts) { - succeedOrThrow(await bankClient.createAccount(this.adminAuth, { - username: acc.accountName, - password: acc.accountPassword, - name: acc.accountName - })) + succeedOrThrow( + await bankClient.createAccount(this.adminAuth, { + username: acc.accountName, + password: acc.accountPassword, + name: acc.accountName, + }), + ); } - } async pingUntilAvailable(): Promise<void> { @@ -1178,25 +1184,22 @@ export interface PaivanaServiceHandle { /** * Implementation of the bank service using the "taler-fakebank-run" tool. */ -export class PaivanaService - implements PaivanaServiceHandle { +export class PaivanaService implements PaivanaServiceHandle { public proc: ProcessWrapper | undefined; // public paivanaApiBaseUrl: string; - get paivanaApiBaseUrl() { - return this.baseUrl + return this.baseUrl; } constructor( private globalState: GlobalTestState, private config: PaivanaConfig, private configFile: string, - ) { } + ) {} http = createPlatformHttpLib({ enableThrottling: false }); - /** */ static async create( @@ -1210,7 +1213,11 @@ export class PaivanaService config.setString("paivana", "port", `${pc.httpPort}`); config.setString("paivana", "serve", "tcp"); config.setString("paivana", "DESTINATION_BASE_URL", pc.destination); - config.setString("paivana", "SECRET", Math.random().toString().substring(2, 6)); + config.setString( + "paivana", + "SECRET", + Math.random().toString().substring(2, 6), + ); config.setString( "paivana", "base_url", @@ -1229,13 +1236,12 @@ export class PaivanaService ): PaivanaService { const testDir = opts.overridePath ?? gc.testDir; const cfgFilename = testDir + `/paivana.conf`; - const config = Configuration.load( - cfgFilename, - ConfigSources["paivana"], - ); + const config = Configuration.load(cfgFilename, ConfigSources["paivana"]); const pc: PaivanaConfig = { httpPort: config.getNumber("paivana", "port").required(), - destination: config.getString("paivana", "DESTINATION_BASE_URL").required(), + destination: config + .getString("paivana", "DESTINATION_BASE_URL") + .required(), secret: config.getString("paivana", "secret").required(), }; return new PaivanaService(gc, pc, cfgFilename); @@ -1254,7 +1260,6 @@ export class PaivanaService return `http://localhost:${this.config.httpPort}/`; } - setMerchant(backendUrl: string, authToken: AccessToken): void { const config = Configuration.load( this.configFile, @@ -1263,7 +1268,6 @@ export class PaivanaService config.setString("paivana", "MERCHANT_BACKEND_URL", backendUrl); config.setString("paivana", "MERCHANT_ACCESS_TOKEN", authToken); config.writeTo(this.configFile, { excludeDefaults: true }); - } get port() { return this.config.httpPort; @@ -1277,12 +1281,7 @@ export class PaivanaService } this.proc = this.globalState.spawnService( "paivana-httpd", - [ - "-c", - this.configFile, - "-L", - "INFO", - ], + ["-c", this.configFile, "-L", "INFO"], "paivana", ); await this.pingUntilAvailable(); @@ -1677,7 +1676,7 @@ export class ExchangeService implements ExchangeServiceInterface { private exchangeConfig: ExchangeConfig, private configFilename: string, private keyPair: EddsaKeyPair, - ) { } + ) {} get name() { return this.exchangeConfig.name; @@ -2158,7 +2157,7 @@ export class BrowserService { constructor( private globalState: GlobalTestState, private type: "firefox" | "chrome", - ) { } + ) {} async stop(): Promise<void> { const driver = this.driver; @@ -2197,8 +2196,8 @@ export class BrowserService { `web-browser`, process.env.BROWSER_PATH ? { - PATH: process.env.BROWSER_PATH, - } + PATH: process.env.BROWSER_PATH, + } : undefined, ); break; @@ -2216,8 +2215,8 @@ export class BrowserService { `web-browser`, process.env.BROWSER_PATH ? { - PATH: process.env.BROWSER_PATH, - } + PATH: process.env.BROWSER_PATH, + } : undefined, ); break; @@ -2258,7 +2257,7 @@ export class MerchantService implements MerchantServiceInterface { private globalState: GlobalTestState, private merchantConfig: MerchantConfig, private configFilename: string, - ) { } + ) {} private currentTimetravelOffsetMs: number | undefined; @@ -2905,7 +2904,7 @@ export class WalletClient { return client.call(operation, payload); } - constructor(private args: WalletClientArgs) { } + constructor(private args: WalletClientArgs) {} async connect(): Promise<void> { const waiter = this.waiter; @@ -2987,9 +2986,11 @@ export class WalletCli { ? `--crypto-worker=${cliOpts.cryptoWorkerType}` : ""; const logName = `wallet-${self.name}`; - const command = `taler-wallet-cli ${self.timetravelArg ?? "" - } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${self.dbfile - }' api '${op}' ${shellWrap(JSON.stringify(payload))}`; + const command = `taler-wallet-cli ${ + self.timetravelArg ?? "" + } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${ + self.dbfile + }' api '${op}' ${shellWrap(JSON.stringify(payload))}`; const resp = await sh(self.globalTestState, logName, command); logger.trace(`command: ${j2s(command)}`); logger.info("--- wallet core response ---"); diff --git a/packages/taler-harness/src/harness/tops.ts b/packages/taler-harness/src/harness/tops.ts @@ -749,9 +749,8 @@ export async function createTopsEnvironment( ); const wireGatewayApi = new TalerWireGatewayHttpClient( - bankApi.getWireGatewayAPI( - exchangeBankAccount.wireGatewayAuth.username, - ).href, + bankApi.getWireGatewayAPI(exchangeBankAccount.wireGatewayAuth.username) + .href, { httpClient: harnessHttpLib, }, diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -114,7 +114,12 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call( WalletApiOperation.TestingWaitTransactionsFinal, {}, @@ -139,7 +144,12 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call( WalletApiOperation.TestingWaitTransactionsFinal, {}, @@ -164,7 +174,12 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call( WalletApiOperation.TestingWaitTransactionsFinal, {}, diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-mixed-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-mixed-merchant.ts @@ -38,7 +38,8 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) { walletClient: walletOne, bankClient, exchange, - merchant, merchantAdminAccessToken, + merchant, + merchantAdminAccessToken, } = await createSimpleTestkudosEnvironmentV3( t, defaultCoinConfig.map((x) => x("TESTKUDOS")), @@ -76,7 +77,12 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call( WalletApiOperation.TestingWaitTransactionsFinal, {}, @@ -100,7 +106,12 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient: walletTwo, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient: walletTwo, + merchant, + order, + merchantAdminAccessToken, + }); await walletTwo.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } @@ -121,7 +132,12 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) { minimum_age: 9, }; - await makeTestPaymentV2(t, { walletClient: walletThree, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient: walletThree, + merchant, + order, + merchantAdminAccessToken, + }); await walletThree.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } } diff --git a/packages/taler-harness/src/integrationtests/test-claim-loop.ts b/packages/taler-harness/src/integrationtests/test-claim-loop.ts @@ -38,8 +38,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runClaimLoopTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); await withdrawViaBankV3(t, { walletClient, @@ -65,7 +70,10 @@ export async function runClaimLoopTest(t: GlobalTestState) { // Query private order status before claiming it. let orderStatusBefore = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatusBefore.order_status === "unpaid"); @@ -80,7 +88,10 @@ export async function runClaimLoopTest(t: GlobalTestState) { // Query private order status after claiming it. let orderStatusAfter = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatusAfter.order_status === "claimed"); diff --git a/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts b/packages/taler-harness/src/integrationtests/test-clause-schnorr.ts @@ -55,8 +55,13 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { name: "rsa_dummy", }); - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t, coinConfig); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t, coinConfig); // Withdraw digital cash into the wallet. @@ -74,7 +79,12 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Test JSON normalization of contract terms: Does the wallet @@ -85,7 +95,12 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order: order2, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order: order2, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); // Test JSON normalization of contract terms: Does the wallet @@ -96,7 +111,12 @@ export async function runClauseSchnorrTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order: order3, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order: order3, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } diff --git a/packages/taler-harness/src/integrationtests/test-denom-lost-complex.ts b/packages/taler-harness/src/integrationtests/test-denom-lost-complex.ts @@ -24,7 +24,10 @@ import { TalerWireGatewayHttpClient, TransactionMajorState, } from "@gnu-taler/taler-util"; -import { WalletApiOperation, WithdrawalGroupStatus } from "@gnu-taler/taler-wallet-core"; +import { + WalletApiOperation, + WithdrawalGroupStatus, +} from "@gnu-taler/taler-wallet-core"; import { createSimpleTestkudosEnvironmentV3 } from "../harness/environments.js"; import { getTestHarnessPaytoForLabel, diff --git a/packages/taler-harness/src/integrationtests/test-deposit-fault.ts b/packages/taler-harness/src/integrationtests/test-deposit-fault.ts @@ -160,7 +160,7 @@ export async function runDepositFaultTest(t: GlobalTestState) { caughtDeposit.resolve(JSON.parse(td.decode(ctx.requestBody))); } }, - async modifyResponse(ctx: FaultInjectionResponseContext) { }, + async modifyResponse(ctx: FaultInjectionResponseContext) {}, }); const depositResp = await walletClient.call( diff --git a/packages/taler-harness/src/integrationtests/test-donau-keychange.ts b/packages/taler-harness/src/integrationtests/test-donau-keychange.ts @@ -233,7 +233,7 @@ export async function runDonauKeychangeTest(t: GlobalTestState) { t.assertDeepEqual(r2.type, ConfirmPayResultType.Pending); - // Merchant should still be running and not crash! + // Merchant should still be running and not crash! orderStatus = succeedOrThrow( await merchantClient.getOrderDetails( diff --git a/packages/taler-harness/src/integrationtests/test-exchange-kyc-auth.ts b/packages/taler-harness/src/integrationtests/test-exchange-kyc-auth.ts @@ -245,7 +245,6 @@ export async function runExchangeKycAuthTest(t: GlobalTestState) { await exchange.runWirewatchOnce(); - // Now, kyc auth must work with explicit account key and both reserve pubs! { diff --git a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts @@ -173,17 +173,21 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { adminAccessToken }, + ); console.log("setup done!"); diff --git a/packages/taler-harness/src/integrationtests/test-fee-regression.ts b/packages/taler-harness/src/integrationtests/test-fee-regression.ts @@ -71,8 +71,8 @@ export async function createMyTestkudosEnvironment( const paivana = await PaivanaService.create(t, { destination: "https://grothoff.org/", - httpPort: 8088 - }) + httpPort: 8088, + }); let receiverName = "Exchange"; let exchangeBankUsername = "exchange"; @@ -178,14 +178,17 @@ export async function createMyTestkudosEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - const {accessToken: adminAccessToken} = await merchant.addDefaultInstance(); - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, { - adminAccessToken - }); + const { accessToken: adminAccessToken } = await merchant.addDefaultInstance(); + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { + adminAccessToken, + }, + ); console.log("setup done!"); @@ -217,8 +220,13 @@ export async function createMyTestkudosEnvironment( export async function runFeeRegressionTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchantAdminAccessToken, merchant } = - await createMyTestkudosEnvironment(t); + const { + walletClient, + bankClient, + exchange, + merchantAdminAccessToken, + merchant, + } = await createMyTestkudosEnvironment(t); // Withdraw digital cash into the wallet. @@ -242,7 +250,12 @@ export async function runFeeRegressionTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); diff --git a/packages/taler-harness/src/integrationtests/test-kyc-merchant-aggregate.ts b/packages/taler-harness/src/integrationtests/test-kyc-merchant-aggregate.ts @@ -59,7 +59,8 @@ export async function runKycMerchantAggregateTest(t: GlobalTestState) { bankClient, exchange, bank, - exchangeBankAccount, merchantAdminAccessToken, + exchangeBankAccount, + merchantAdminAccessToken, } = await createKycTestkudosEnvironmentFull(t, { adjustExchangeConfig }); // Withdraw digital cash into the wallet. @@ -81,9 +82,9 @@ export async function runKycMerchantAggregateTest(t: GlobalTestState) { bankAdminAuth: bank.getAdminAuth(), }); - await makeTestPaymentV2(t, { - merchant, merchantAdminAccessToken, + merchant, + merchantAdminAccessToken, walletClient, order: { amount: "TESTKUDOS:20", @@ -109,8 +110,8 @@ export async function runKycMerchantAggregateTest(t: GlobalTestState) { const kycStatusUrl = new URL("private/kyc", merchant.makeInstanceBaseUrl()); const resp = await harnessHttpLib.fetch(kycStatusUrl.href, { headers: { - Authorization: `Bearer ${merchantAdminAccessToken}` - } + Authorization: `Bearer ${merchantAdminAccessToken}`, + }, }); console.log(`mechant kyc status: ${resp.status}`); diff --git a/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts b/packages/taler-harness/src/integrationtests/test-libeufin-bank.ts @@ -106,17 +106,21 @@ export async function runLibeufinBankTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { adminAccessToken }, + ); const { walletClient } = await createWalletDaemonWithClient(t, { name: "wallet", diff --git a/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts b/packages/taler-harness/src/integrationtests/test-merchant-exchange-confusion.ts @@ -137,17 +137,21 @@ export async function createConfusedMerchantTestkudosEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { adminAccessToken }, + ); console.log("setup done!"); @@ -174,8 +178,13 @@ export async function createConfusedMerchantTestkudosEnvironment( export async function runMerchantExchangeConfusionTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, faultyExchange, faultyMerchant, merchantAdminAccessToken } = - await createConfusedMerchantTestkudosEnvironment(t); + const { + walletClient, + bankClient, + faultyExchange, + faultyMerchant, + merchantAdminAccessToken, + } = await createConfusedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. @@ -214,9 +223,13 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-one", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-one", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts @@ -22,7 +22,7 @@ import { HttpStatusCode, MerchantAuthMethod, TalerMerchantManagementHttpClient, - URL + URL, } from "@gnu-taler/taler-util"; import { ExchangeService, @@ -31,7 +31,7 @@ import { MerchantService, getTestHarnessPaytoForLabel, harnessHttpLib, - setupDb + setupDb, } from "../harness/harness.js"; /** @@ -81,34 +81,41 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { } // Add an instance, no auth! - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - auth: { - method: MerchantAuthMethod.TOKEN, - password: "admin-pwd" - }, - }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + auth: { + method: MerchantAuthMethod.TOKEN, + password: "admin-pwd", + }, + }); // Add an instance, no auth! - await merchant.addInstanceWithWireAccount({ - id: "myinst", - name: "Second Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - auth: { - method: MerchantAuthMethod.TOKEN, - password: "myinst-pwd" + await merchant.addInstanceWithWireAccount( + { + id: "myinst", + name: "Second Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + auth: { + method: MerchantAuthMethod.TOKEN, + password: "myinst-pwd", + }, }, - }, {adminAccessToken}); + { adminAccessToken }, + ); const merchantApi = new TalerMerchantManagementHttpClient( merchant.makeInstanceBaseUrl(), ); - const adminPwd = await merchantApi.createAccessToken("admin", "admin-pwd", MERCHANT_DEFAULT_LOGIN_SCOPE) - t.assertTrue(adminPwd.type === "ok") - + const adminPwd = await merchantApi.createAccessToken( + "admin", + "admin-pwd", + MERCHANT_DEFAULT_LOGIN_SCOPE, + ); + t.assertTrue(adminPwd.type === "ok"); // Check that deleting an instance checks the auth // of the default instance. diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts @@ -85,12 +85,13 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { } // Add an instance, no auth! - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - auth: MERCHANT_DEFAULT_AUTH, - }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + auth: MERCHANT_DEFAULT_AUTH, + }); // Add it again, should be idempotent // FIXME: this fails, means we lost idempotentcy with password auth? @@ -102,12 +103,16 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { // }); // Add an instance, no auth! - const {accessToken: myInstAccessToken} = await merchant.addInstanceWithWireAccount({ - id: "myinst", - name: "Second Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - auth: MERCHANT_DEFAULT_AUTH, - }, {adminAccessToken}); + const { accessToken: myInstAccessToken } = + await merchant.addInstanceWithWireAccount( + { + id: "myinst", + name: "Second Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + auth: MERCHANT_DEFAULT_AUTH, + }, + { adminAccessToken }, + ); const merchantAdminAccessToken = adminAccessToken; @@ -116,21 +121,29 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { ); { - const r = succeedOrThrow(await merchantClient.listInstances(merchantAdminAccessToken)); + const r = succeedOrThrow( + await merchantClient.listInstances(merchantAdminAccessToken), + ); t.assertDeepEqual(r.instances.length, 2); } { const fullDetails = succeedOrThrow( - await merchantClient.getInstanceDetails(merchantAdminAccessToken, "admin"), + await merchantClient.getInstanceDetails( + merchantAdminAccessToken, + "admin", + ), ); t.assertDeepEqual(fullDetails.auth.method, "token"); } - await merchantClient.updateCurrentInstanceAuthentication(merchantAdminAccessToken, { - method: MerchantAuthMethod.TOKEN, - password: "foobar", - }); + await merchantClient.updateCurrentInstanceAuthentication( + merchantAdminAccessToken, + { + method: MerchantAuthMethod.TOKEN, + password: "foobar", + }, + ); const { access_token: auth } = succeedOrThrow( await merchantClient.createAccessToken("admin", "foobar", { @@ -174,7 +187,10 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { // Check that deleting an instance checks the auth // of the default instance. { - const res = await merchantClient.deleteInstance(myInstAccessToken, "myinst"); + const res = await merchantClient.deleteInstance( + myInstAccessToken, + "myinst", + ); t.assertTrue(res.type === "fail"); t.assertTrue(res.case === HttpStatusCode.Unauthorized); } diff --git a/packages/taler-harness/src/integrationtests/test-merchant-longpolling.ts b/packages/taler-harness/src/integrationtests/test-merchant-longpolling.ts @@ -37,8 +37,13 @@ import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; */ export async function runMerchantLongpollingTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -76,9 +81,13 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-one", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-one", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts b/packages/taler-harness/src/integrationtests/test-merchant-refund-api.ts @@ -68,7 +68,10 @@ async function testRefundApiWithFulfillmentUrl( ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -96,7 +99,10 @@ async function testRefundApiWithFulfillmentUrl( // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); @@ -118,7 +124,10 @@ async function testRefundApiWithFulfillmentUrl( }); orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); @@ -186,7 +195,10 @@ async function testRefundApiWithFulfillmentMessage( ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -214,7 +226,10 @@ async function testRefundApiWithFulfillmentMessage( // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); @@ -281,8 +296,13 @@ async function testRefundApiWithFulfillmentMessage( export async function runMerchantRefundApiTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. diff --git a/packages/taler-harness/src/integrationtests/test-merchant-self-provision-forgot-password.ts b/packages/taler-harness/src/integrationtests/test-merchant-self-provision-forgot-password.ts @@ -69,7 +69,7 @@ export async function runMerchantSelfProvisionForgotPasswordTest( additionalMerchantConfig(m) { m.modifyConfig(async (cfg) => { cfg.setString("merchant", "ENABLE_SELF_PROVISIONING", "yes"); - configureTestMerchantMfa(cfg, mfaConfig); + configureTestMerchantMfa(cfg, mfaConfig); }); }, }); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts b/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts @@ -633,7 +633,7 @@ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) { merchantBaseUrl, exchange, bankClient, - merchantAccessToken: merchantAdminAccessToken + merchantAccessToken: merchantAdminAccessToken, }); await testWithoutClaimToken(t, { @@ -641,7 +641,7 @@ export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) { merchantBaseUrl, exchange, bankClient, - merchantAccessToken: merchantAdminAccessToken + merchantAccessToken: merchantAdminAccessToken, }); } diff --git a/packages/taler-harness/src/integrationtests/test-multiexchange.ts b/packages/taler-harness/src/integrationtests/test-multiexchange.ts @@ -157,23 +157,27 @@ export async function runMultiExchangeTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }, + { adminAccessToken }, + ); const { walletClient, walletService } = await createWalletDaemonWithClient( t, @@ -208,7 +212,12 @@ export async function runMultiExchangeTest(t: GlobalTestState) { console.log("making test payment"); - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken: adminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken: adminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } diff --git a/packages/taler-harness/src/integrationtests/test-otp.ts b/packages/taler-harness/src/integrationtests/test-otp.ts @@ -41,8 +41,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runOtpTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), diff --git a/packages/taler-harness/src/integrationtests/test-paivana-repurchase.ts b/packages/taler-harness/src/integrationtests/test-paivana-repurchase.ts @@ -179,7 +179,7 @@ export async function runPaivanaRepurchaseTest(t: GlobalTestState) { }, ), ); - console.log("asdasdasd",orderStatus) + console.log("asdasdasd", orderStatus); // check that merchant also think is paid for this session t.assertTrue(orderStatus.order_status === "paid"); } @@ -220,7 +220,7 @@ export async function runPaivanaRepurchaseTest(t: GlobalTestState) { t.assertTrue(!!res.headers.get("Set-Cookie")); t.assertTrue(res.status === 303); - await waitMs(600) + await waitMs(600); } } diff --git a/packages/taler-harness/src/integrationtests/test-paivana.ts b/packages/taler-harness/src/integrationtests/test-paivana.ts @@ -33,7 +33,7 @@ import { TalerUriAction, TalerUris, timestampRoundedToBuffer, - WalletNotification + WalletNotification, } from "@gnu-taler/taler-util"; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -88,12 +88,11 @@ export async function runPaivanaTest(t: GlobalTestState) { const uri = Result.unpack(TalerUris.fromString(templateURI)); t.assertTrue(uri.type === TalerUriAction.PayTemplate); - const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), ); - const session = createPaivanaSessionFor(website) + const session = createPaivanaSessionFor(website); logger.info("1) PAIVANA ID created", JSON.stringify(session)); @@ -169,7 +168,6 @@ export async function runPaivanaTest(t: GlobalTestState) { await merchantClient.getOrderIdForSessionAndUrl(session.paivanaId, website), ); - logger.info(`---- STATE ${website}`, { order_id: order.order_id, nonce: session.nonce, @@ -192,9 +190,8 @@ export async function runPaivanaTest(t: GlobalTestState) { }, ); - t.assertTrue(res.headers.get("location") === website) + t.assertTrue(res.headers.get("location") === website); t.assertTrue(res.status === 303); - } runPaivanaTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/test-pay-paid.ts b/packages/taler-harness/src/integrationtests/test-pay-paid.ts @@ -45,8 +45,13 @@ import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; export async function runPayPaidTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bank, faultyExchange, faultyMerchant, merchantAdminAccessToken } = - await createFaultInjectedMerchantTestkudosEnvironment(t); + const { + walletClient, + bank, + faultyExchange, + faultyMerchant, + merchantAdminAccessToken, + } = await createFaultInjectedMerchantTestkudosEnvironment(t); // Withdraw digital cash into the wallet. @@ -88,9 +93,13 @@ export async function runPayPaidTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-one", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-one", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -159,9 +168,13 @@ export async function runPayPaidTest(t: GlobalTestState) { */ orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-two", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-two", + }, + ), ); console.log( @@ -198,9 +211,13 @@ export async function runPayPaidTest(t: GlobalTestState) { ); let orderStatusTwo = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderRespTwo.order_id, { - sessionId: "mysession-two", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderRespTwo.order_id, + { + sessionId: "mysession-two", + }, + ), ); t.assertTrue(orderStatusTwo.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-payment-claim.ts b/packages/taler-harness/src/integrationtests/test-payment-claim.ts @@ -50,7 +50,10 @@ export async function runPaymentClaimTest(t: GlobalTestState) { merchant.makeInstanceBaseUrl(), ); - const w2 = await createWalletDaemonWithClient(t, { name: "w2", persistent: true }); + const w2 = await createWalletDaemonWithClient(t, { + name: "w2", + persistent: true, + }); // Withdraw digital cash into the wallet. diff --git a/packages/taler-harness/src/integrationtests/test-payment-deleted.ts b/packages/taler-harness/src/integrationtests/test-payment-deleted.ts @@ -37,8 +37,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runPaymentDeletedTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // First, make a "free" payment when we don't even have // any money in the @@ -67,7 +72,10 @@ export async function runPaymentDeletedTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -86,7 +94,11 @@ export async function runPaymentDeletedTest(t: GlobalTestState) { ); succeedOrThrow( - await merchantClient.deleteOrder(merchantAdminAccessToken, orderResp.order_id, true), + await merchantClient.deleteOrder( + merchantAdminAccessToken, + orderResp.order_id, + true, + ), ); const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, { diff --git a/packages/taler-harness/src/integrationtests/test-payment-forgettable.ts b/packages/taler-harness/src/integrationtests/test-payment-forgettable.ts @@ -32,8 +32,13 @@ import { TalerMerchantApi } from "@gnu-taler/taler-util"; export async function runPaymentForgettableTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -59,7 +64,12 @@ export async function runPaymentForgettableTest(t: GlobalTestState) { }, }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); } console.log("testing with forgettable field without hash"); @@ -77,7 +87,12 @@ export async function runPaymentForgettableTest(t: GlobalTestState) { }, }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); } await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); diff --git a/packages/taler-harness/src/integrationtests/test-payment-idempotency.ts b/packages/taler-harness/src/integrationtests/test-payment-idempotency.ts @@ -36,8 +36,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runPaymentIdempotencyTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -67,7 +72,10 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -113,7 +121,10 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) { // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); diff --git a/packages/taler-harness/src/integrationtests/test-payment-multiple.ts b/packages/taler-harness/src/integrationtests/test-payment-multiple.ts @@ -40,7 +40,7 @@ import { async function setupTest(t: GlobalTestState): Promise<{ merchant: MerchantService; - merchantAdminAccessToken: AccessToken, + merchantAdminAccessToken: AccessToken; exchange: ExchangeService; bankClient: TalerCorebankApiClient; }> { @@ -115,17 +115,21 @@ async function setupTest(t: GlobalTestState): Promise<{ await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { adminAccessToken }, + ); console.log("setup done!"); @@ -145,7 +149,8 @@ async function setupTest(t: GlobalTestState): Promise<{ export async function runPaymentMultipleTest(t: GlobalTestState) { // Set up test environment - const { merchant, bankClient, exchange, merchantAdminAccessToken } = await setupTest(t); + const { merchant, bankClient, exchange, merchantAdminAccessToken } = + await setupTest(t); const { walletClient } = await createWalletDaemonWithClient(t, { name: "default", @@ -179,7 +184,10 @@ export async function runPaymentMultipleTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -197,7 +205,10 @@ export async function runPaymentMultipleTest(t: GlobalTestState) { // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); diff --git a/packages/taler-harness/src/integrationtests/test-payment-template.ts b/packages/taler-harness/src/integrationtests/test-payment-template.ts @@ -39,8 +39,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runPaymentTemplateTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), diff --git a/packages/taler-harness/src/integrationtests/test-payment-transient.ts b/packages/taler-harness/src/integrationtests/test-payment-transient.ts @@ -43,8 +43,13 @@ import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; export async function runPaymentTransientTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bank, faultyMerchant, faultyExchange, merchantAdminAccessToken } = - await createFaultInjectedMerchantTestkudosEnvironment(t); + const { + walletClient, + bank, + faultyMerchant, + faultyExchange, + merchantAdminAccessToken, + } = await createFaultInjectedMerchantTestkudosEnvironment(t); const merchantClient = new TalerMerchantInstanceHttpClient( faultyMerchant.makeInstanceBaseUrl(), @@ -75,9 +80,13 @@ export async function runPaymentTransientTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-one", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-one", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-payment-zero.ts b/packages/taler-harness/src/integrationtests/test-payment-zero.ts @@ -33,14 +33,24 @@ import { TransactionMajorState } from "@gnu-taler/taler-util"; export async function runPaymentZeroTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // First, make a "free" payment when we don't even have // any money in the // Withdraw digital cash into the wallet. - await withdrawViaBankV3(t, { walletClient, bankClient, exchange, amount: "TESTKUDOS:20" }); + await withdrawViaBankV3(t, { + walletClient, + bankClient, + exchange, + amount: "TESTKUDOS:20", + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); diff --git a/packages/taler-harness/src/integrationtests/test-paywall-flow.ts b/packages/taler-harness/src/integrationtests/test-paywall-flow.ts @@ -40,8 +40,13 @@ import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; export async function runPaywallFlowTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), @@ -81,9 +86,13 @@ export async function runPaywallFlowTest(t: GlobalTestState) { const firstOrderId = orderResp.order_id; let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-one", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-one", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -156,9 +165,13 @@ export async function runPaywallFlowTest(t: GlobalTestState) { */ orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id, { - sessionId: "mysession-two", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + { + sessionId: "mysession-two", + }, + ), ); // Should be claimed (not paid!) because of a new session ID @@ -205,9 +218,13 @@ export async function runPaywallFlowTest(t: GlobalTestState) { const secondOrderId = orderResp.order_id; orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, secondOrderId, { - sessionId: "mysession-three", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + secondOrderId, + { + sessionId: "mysession-three", + }, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -238,9 +255,13 @@ export async function runPaywallFlowTest(t: GlobalTestState) { // The first order should now be paid under "mysession-three", // as the wallet did re-purchase detection orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, firstOrderId, { - sessionId: "mysession-three", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + firstOrderId, + { + sessionId: "mysession-three", + }, + ), ); console.log(`order status (mysession-three)`, j2s(orderStatus)); @@ -250,9 +271,13 @@ export async function runPaywallFlowTest(t: GlobalTestState) { // Check that with a completely new session ID, the status would NOT // be paid. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, firstOrderId, { - sessionId: "mysession-four", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + firstOrderId, + { + sessionId: "mysession-four", + }, + ), ); console.log(`order status (mysession-four)`, j2s(orderStatus)); diff --git a/packages/taler-harness/src/integrationtests/test-peer-pull-large.ts b/packages/taler-harness/src/integrationtests/test-peer-pull-large.ts @@ -28,9 +28,7 @@ import { createWalletDaemonWithClient, withdrawViaBankV3, } from "../harness/environments.js"; -import { - GlobalTestState, -} from "../harness/harness.js"; +import { GlobalTestState } from "../harness/harness.js"; const coinCommon = { cipher: "RSA" as const, @@ -53,10 +51,7 @@ const coinConfigList: CoinConfig[] = [ ]; const purse_expiration = AbsoluteTime.toProtocolTimestamp( - AbsoluteTime.addDuration( - AbsoluteTime.now(), - Duration.fromSpec({ days: 2 }), - ), + AbsoluteTime.addDuration(AbsoluteTime.now(), Duration.fromSpec({ days: 2 })), ); /** @@ -73,8 +68,8 @@ export async function runPeerPullLargeTest(t: GlobalTestState) { ] = await Promise.all([ createSimpleTestkudosEnvironmentV3(t, coinConfigList), createWalletDaemonWithClient(t, { - name: "w2" - }) + name: "w2", + }), ]); // Withdraw digital cash into the wallet. @@ -102,7 +97,7 @@ export async function runPeerPullLargeTest(t: GlobalTestState) { transactionId: initiate.transactionId, txState: { major: TransactionMajorState.Pending, - minor: TransactionMinorState.Ready + minor: TransactionMinorState.Ready, }, }); @@ -136,7 +131,7 @@ export async function runPeerPullLargeTest(t: GlobalTestState) { txState: { major: TransactionMajorState.Done, }, - }) + }), ]); } diff --git a/packages/taler-harness/src/integrationtests/test-refund-auto.ts b/packages/taler-harness/src/integrationtests/test-refund-auto.ts @@ -37,8 +37,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runRefundAutoTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), @@ -77,7 +82,10 @@ export async function runRefundAutoTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -95,16 +103,23 @@ export async function runRefundAutoTest(t: GlobalTestState) { // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); const ref = succeedOrThrow( - await merchantClient.addRefund(merchantAdminAccessToken, orderResp.order_id, { - refund: "TESTKUDOS:5", - reason: "foo", - }), + await merchantClient.addRefund( + merchantAdminAccessToken, + orderResp.order_id, + { + refund: "TESTKUDOS:5", + reason: "foo", + }, + ), ); console.log(ref); @@ -152,7 +167,10 @@ export async function runRefundAutoTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -170,7 +188,10 @@ export async function runRefundAutoTest(t: GlobalTestState) { // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); diff --git a/packages/taler-harness/src/integrationtests/test-refund.ts b/packages/taler-harness/src/integrationtests/test-refund.ts @@ -81,7 +81,10 @@ export async function runRefundTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); @@ -99,7 +102,10 @@ export async function runRefundTest(t: GlobalTestState) { // Check if payment was successful. orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "paid"); @@ -115,10 +121,14 @@ export async function runRefundTest(t: GlobalTestState) { } const ref = succeedOrThrow( - await merchantClient.addRefund(merchantAdminAccessToken, orderResp.order_id, { - refund: "TESTKUDOS:5", - reason: "foo", - }), + await merchantClient.addRefund( + merchantAdminAccessToken, + orderResp.order_id, + { + refund: "TESTKUDOS:5", + reason: "foo", + }, + ), ); console.log(ref); diff --git a/packages/taler-harness/src/integrationtests/test-repurchase.ts b/packages/taler-harness/src/integrationtests/test-repurchase.ts @@ -67,9 +67,13 @@ export async function runRepurchaseTest(t: GlobalTestState) { ); let orderOneStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderOneResp.order_id, { - sessionId: "session1", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderOneResp.order_id, + { + sessionId: "session1", + }, + ), ); t.assertTrue(orderOneStatus.order_status === "unpaid"); @@ -105,9 +109,13 @@ export async function runRepurchaseTest(t: GlobalTestState) { ); let orderTwoStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderTwoResp.order_id, { - sessionId: "session2", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderTwoResp.order_id, + { + sessionId: "session2", + }, + ), ); t.assertTrue(orderTwoStatus.order_status === "unpaid"); @@ -153,10 +161,14 @@ export async function runRepurchaseTest(t: GlobalTestState) { ); let orderThreeStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderThreeResp.order_id, { - // Go back to session1 - sessionId: "session1", - }), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderThreeResp.order_id, + { + // Go back to session1 + sessionId: "session1", + }, + ), ); t.assertTrue(orderThreeStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-revocation.ts b/packages/taler-harness/src/integrationtests/test-revocation.ts @@ -93,8 +93,8 @@ async function createTestEnvironment( }); const paivana = await PaivanaService.create(t, { destination: "https://grothoff.org/", - httpPort: 8088 - }) + httpPort: 8088, + }); let receiverName = "Exchange"; let exchangeBankUsername = "exchange"; @@ -159,17 +159,21 @@ async function createTestEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + }); - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - }, {adminAccessToken}); + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + }, + { adminAccessToken }, + ); console.log("setup done!"); @@ -203,8 +207,13 @@ async function createTestEnvironment( export async function runRevocationTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createTestEnvironment(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createTestEnvironment(t); // Withdraw digital cash into the wallet. @@ -234,7 +243,12 @@ export async function runRevocationTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", } satisfies TalerMerchantApi.Order; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.ClearDb, {}); @@ -267,7 +281,12 @@ export async function runRevocationTest(t: GlobalTestState) { console.log("wallet balance", bal); } - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); } runRevocationTest.timeoutMs = 120000; diff --git a/packages/taler-harness/src/integrationtests/test-simple-payment.ts b/packages/taler-harness/src/integrationtests/test-simple-payment.ts @@ -56,7 +56,12 @@ export async function runSimplePaymentTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", } satisfies TalerMerchantApi.Order; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); } diff --git a/packages/taler-harness/src/integrationtests/test-stored-backups.ts b/packages/taler-harness/src/integrationtests/test-stored-backups.ts @@ -17,7 +17,10 @@ /** * Imports. */ -import { TalerCorebankApiClient, TalerMerchantApi } from "@gnu-taler/taler-util"; +import { + TalerCorebankApiClient, + TalerMerchantApi, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { makeTestPaymentV2, @@ -67,7 +70,12 @@ export async function runStoredBackupsTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", } satisfies TalerMerchantApi.Order; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); const txn1 = await walletClient.call(WalletApiOperation.GetTransactions, {}); diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-postal.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-postal.ts @@ -28,7 +28,7 @@ import { succeedOrThrow, TalerExchangeHttpClient, TalerMerchantInstanceHttpClient, - TalerProtocolTimestamp + TalerProtocolTimestamp, } from "@gnu-taler/taler-util"; import { startFakeChallenger } from "../harness/fake-challenger.js"; import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; @@ -61,11 +61,14 @@ export async function runTopsAmlCustomAddrPostalTest(t: GlobalTestState) { ); // Do KYC auth transfer { - const kycStatus = await merchantClient.getCurrentInstanceKycStatus(merchantAdminAccessToken, { - reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated - timeout: 30000, - }); - t.assertTrue(kycStatus.type === "ok") + const kycStatus = await merchantClient.getCurrentInstanceKycStatus( + merchantAdminAccessToken, + { + reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated + timeout: 30000, + }, + ); + t.assertTrue(kycStatus.type === "ok"); console.log(`kyc status: ${j2s(kycStatus)}`); @@ -96,11 +99,14 @@ export async function runTopsAmlCustomAddrPostalTest(t: GlobalTestState) { // Wait for auth transfer to be registered by the exchange { - const kycStatus = await merchantClient.getCurrentInstanceKycStatus(merchantAdminAccessToken, { - reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated - timeout: 30000, - }); - t.assertTrue(kycStatus.type === "ok") + const kycStatus = await merchantClient.getCurrentInstanceKycStatus( + merchantAdminAccessToken, + { + reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated + timeout: 30000, + }, + ); + t.assertTrue(kycStatus.type === "ok"); logger.info(`kyc status after transfer: ${j2s(kycStatus)}`); t.assertDeepEqual(kycStatus.body.kyc_data[0].status, "kyc-required"); @@ -155,10 +161,13 @@ export async function runTopsAmlCustomAddrPostalTest(t: GlobalTestState) { await merchant.runKyccheckOnce(); { - const kycStatus = await merchantClient.getCurrentInstanceKycStatus(merchantAdminAccessToken, { - reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated - timeout: 30000, - }); + const kycStatus = await merchantClient.getCurrentInstanceKycStatus( + merchantAdminAccessToken, + { + reason: KycStatusLongPollingReason.AUTH_TRANSFER, // FIXME: deprecated + timeout: 30000, + }, + ); logger.info(`kyc status after accept-tos: ${j2s(kycStatus)}`); } diff --git a/packages/taler-harness/src/integrationtests/test-tos-format.ts b/packages/taler-harness/src/integrationtests/test-tos-format.ts @@ -19,9 +19,7 @@ */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; -import { - createSimpleTestkudosEnvironmentV2, -} from "../harness/environments.js"; +import { createSimpleTestkudosEnvironmentV2 } from "../harness/environments.js"; import * as fs from "node:fs"; /** @@ -30,68 +28,85 @@ import * as fs from "node:fs"; export async function runTermOfServiceFormatTest(t: GlobalTestState) { // Set up test environment const tosDir = t.testDir + `/tos/`; - const langs = ["es", "en", "de"] + const langs = ["es", "en", "de"]; - langs.forEach(l => { - const langDir = tosDir + l + "/" + langs.forEach((l) => { + const langDir = tosDir + l + "/"; fs.mkdirSync(langDir, { recursive: true }); fs.writeFileSync(langDir + "v1.txt", "text content"); fs.writeFileSync(langDir + "v1.md", "markdown content"); fs.writeFileSync(langDir + "v1.html", "html content"); }); - const { walletClient, exchange, } = - await createSimpleTestkudosEnvironmentV2(t, undefined, { + const { walletClient, exchange } = await createSimpleTestkudosEnvironmentV2( + t, + undefined, + { additionalExchangeConfig: (ex) => { ex.changeConfig((cfg) => { - cfg.setString("exchange", "terms_etag", "v1") - cfg.setString("exchange", "terms_dir", tosDir) - }) - } - }); - + cfg.setString("exchange", "terms_etag", "v1"); + cfg.setString("exchange", "terms_dir", tosDir); + }); + }, + }, + ); { - const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, { - exchangeBaseUrl: exchange.baseUrl, - }) + const tos = await walletClient.client.call( + WalletApiOperation.GetExchangeTos, + { + exchangeBaseUrl: exchange.baseUrl, + }, + ); t.assertDeepEqual(tos.content, "text content"); } { - const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, { - exchangeBaseUrl: exchange.baseUrl, - acceptedFormat: ["text/html"] - }) + const tos = await walletClient.client.call( + WalletApiOperation.GetExchangeTos, + { + exchangeBaseUrl: exchange.baseUrl, + acceptedFormat: ["text/html"], + }, + ); t.assertDeepEqual(tos.content, "html content"); } { - const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, { - exchangeBaseUrl: exchange.baseUrl, - acceptedFormat: ["text/markdown"] - }) + const tos = await walletClient.client.call( + WalletApiOperation.GetExchangeTos, + { + exchangeBaseUrl: exchange.baseUrl, + acceptedFormat: ["text/markdown"], + }, + ); t.assertDeepEqual(tos.content, "markdown content"); } { - const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, { - exchangeBaseUrl: exchange.baseUrl, - acceptedFormat: ["text/markdown", "text/html"] - }) + const tos = await walletClient.client.call( + WalletApiOperation.GetExchangeTos, + { + exchangeBaseUrl: exchange.baseUrl, + acceptedFormat: ["text/markdown", "text/html"], + }, + ); // prefer markdown since its the first one in the list t.assertDeepEqual(tos.content, "markdown content"); } { - const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, { - exchangeBaseUrl: exchange.baseUrl, - acceptedFormat: ["text/pdf", "text/html"] - }) + const tos = await walletClient.client.call( + WalletApiOperation.GetExchangeTos, + { + exchangeBaseUrl: exchange.baseUrl, + acceptedFormat: ["text/pdf", "text/html"], + }, + ); // there is no pdf so fallback in html t.assertDeepEqual(tos.content, "html content"); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-balance-zero.ts b/packages/taler-harness/src/integrationtests/test-wallet-balance-zero.ts @@ -36,8 +36,13 @@ export async function runWalletBalanceZeroTest(t: GlobalTestState) { const coinConfig = makeNoFeeCoinConfig("TESTKUDOS"); console.log(`coin config ${j2s(coinConfig)}`); - const { merchant, walletClient, exchange, bankClient, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t, coinConfig); + const { + merchant, + walletClient, + exchange, + bankClient, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t, coinConfig); const wres = await withdrawViaBankV3(t, { amount: "TESTKUDOS:10", diff --git a/packages/taler-harness/src/integrationtests/test-wallet-balance.ts b/packages/taler-harness/src/integrationtests/test-wallet-balance.ts @@ -157,14 +157,15 @@ async function createMyEnvironment( await merchant.start(); await merchant.pingUntilAvailable(); - const {accessToken: merchantAdminAccessToken} = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [`payto://void/merchant-default?receiver-name=Merchant`], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); + const { accessToken: merchantAdminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [`payto://void/merchant-default?receiver-name=Merchant`], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); const { walletClient, walletService } = await createWalletDaemonWithClient( t, @@ -200,8 +201,13 @@ async function createMyEnvironment( export async function runWalletBalanceTest(t: GlobalTestState) { // Set up test environment - const { merchant, walletClient, exchange, bankClient, merchantAdminAccessToken } = - await createMyEnvironment(t); + const { + merchant, + walletClient, + exchange, + bankClient, + merchantAdminAccessToken, + } = await createMyEnvironment(t); const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), @@ -238,7 +244,10 @@ export async function runWalletBalanceTest(t: GlobalTestState) { console.log("created order with merchant"); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-merchant.ts b/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-merchant.ts @@ -65,10 +65,8 @@ const coinConfigList: CoinConfig[] = [ export async function runWalletBlockedPayMerchantTest(t: GlobalTestState) { // Set up test environment - const { bank, exchange, merchant, merchantAdminAccessToken } = await createSimpleTestkudosEnvironmentV2( - t, - coinConfigList, - ); + const { bank, exchange, merchant, merchantAdminAccessToken } = + await createSimpleTestkudosEnvironmentV2(t, coinConfigList); const bankClient = new TalerCorebankApiClient(bank.baseUrl); @@ -124,7 +122,10 @@ export async function runWalletBlockedPayMerchantTest(t: GlobalTestState) { ); let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails(merchantAdminAccessToken, orderResp.order_id), + await merchantClient.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), ); t.assertTrue(orderStatus.order_status === "unpaid"); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-peer-pull.ts b/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-peer-pull.ts @@ -69,10 +69,8 @@ export async function runWalletBlockedPayPeerPullTest(t: GlobalTestState) { }, ]; - const { bank, exchange, merchant, merchantAdminAccessToken } = await createSimpleTestkudosEnvironmentV2( - t, - coinConfigList, - ); + const { bank, exchange, merchant, merchantAdminAccessToken } = + await createSimpleTestkudosEnvironmentV2(t, coinConfigList); // Withdraw digital cash into the wallet. diff --git a/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-peer-push.ts b/packages/taler-harness/src/integrationtests/test-wallet-blocked-pay-peer-push.ts @@ -68,10 +68,8 @@ export async function runWalletBlockedPayPeerPushTest(t: GlobalTestState) { }, ]; - const { bank, exchange, merchant, merchantAdminAccessToken } = await createSimpleTestkudosEnvironmentV2( - t, - coinConfigList, - ); + const { bank, exchange, merchant, merchantAdminAccessToken } = + await createSimpleTestkudosEnvironmentV2(t, coinConfigList); const bankClient = new TalerCorebankApiClient(bank.baseUrl); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-cli-termination.ts b/packages/taler-harness/src/integrationtests/test-wallet-cli-termination.ts @@ -20,10 +20,7 @@ import { AmountString } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; -import { - GlobalTestState, - setupDb, -} from "../harness/harness.js"; +import { GlobalTestState, setupDb } from "../harness/harness.js"; import { createSimpleTestkudosEnvironmentV3 } from "harness/environments.js"; /** @@ -34,11 +31,8 @@ export async function runWalletCliTerminationTest(t: GlobalTestState) { const coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")); - const { - exchange, - bankClient, - walletClient, - } = await createSimpleTestkudosEnvironmentV3(t, coinConfig, {}); + const { exchange, bankClient, walletClient } = + await createSimpleTestkudosEnvironmentV3(t, coinConfig, {}); await walletClient.call(WalletApiOperation.WithdrawTestBalance, { corebankApiBaseUrl: bankClient.baseUrl, diff --git a/packages/taler-harness/src/integrationtests/test-wallet-contacts-basic.ts b/packages/taler-harness/src/integrationtests/test-wallet-contacts-basic.ts @@ -41,7 +41,7 @@ export async function runWalletContactsBasicTest(t: GlobalTestState) { petname: "", mailboxBaseUri: "https://mailbox.example.com", mailboxAddress: "BOBPKEY", - source: "test" + source: "test", }; const contactAlice: ContactEntry = { alias: "@alice", @@ -49,16 +49,15 @@ export async function runWalletContactsBasicTest(t: GlobalTestState) { petname: "", mailboxBaseUri: "https://mailbox.example.com", mailboxAddress: "ALICEPKEY", - source: "test" + source: "test", }; - await walletClient.call(WalletApiOperation.AddContact, { + await walletClient.call(WalletApiOperation.AddContact, { contact: contactAlice, }); - await walletClient.call(WalletApiOperation.AddContact, { + await walletClient.call(WalletApiOperation.AddContact, { contact: contactBob, }); - { const bi = await walletClient.call(WalletApiOperation.GetContacts, {}); t.assertDeepEqual(bi.contacts.length, 2); @@ -73,7 +72,6 @@ export async function runWalletContactsBasicTest(t: GlobalTestState) { t.assertDeepEqual(bi.contacts.length, 1); t.assertDeepEqual(bi.contacts[0].alias, "@alice"); } - } runWalletContactsBasicTest.suites = ["wallet", "wallet-contacts"]; diff --git a/packages/taler-harness/src/integrationtests/test-wallet-cryptoworker.ts b/packages/taler-harness/src/integrationtests/test-wallet-cryptoworker.ts @@ -17,9 +17,7 @@ /** * Imports. */ -import { - WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState, WalletCli } from "../harness/harness.js"; /** diff --git a/packages/taler-harness/src/integrationtests/test-wallet-dd48.ts b/packages/taler-harness/src/integrationtests/test-wallet-dd48.ts @@ -188,7 +188,7 @@ export async function runWalletDd48Test(t: GlobalTestState) { x.type === NotificationType.ExchangeStateTransition && x.oldExchangeState == null && x.newExchangeState?.exchangeEntryStatus === - ExchangeEntryStatus.Ephemeral, + ExchangeEntryStatus.Ephemeral, ), ); diff --git a/packages/taler-harness/src/integrationtests/test-wallet-gendb.ts b/packages/taler-harness/src/integrationtests/test-wallet-gendb.ts @@ -42,8 +42,13 @@ import { export async function runWalletGenDbTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -62,7 +67,12 @@ export async function runWalletGenDbTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); const purseExpiration = AbsoluteTime.toProtocolTimestamp( diff --git a/packages/taler-harness/src/integrationtests/test-wallet-mailbox-basic.ts b/packages/taler-harness/src/integrationtests/test-wallet-mailbox-basic.ts @@ -19,10 +19,12 @@ */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { GlobalTestState } from "../harness/harness.js"; +import { createSimpleTestkudosEnvironmentV3 } from "../harness/environments.js"; import { - createSimpleTestkudosEnvironmentV3, -} from "../harness/environments.js"; -import { MailboxMessageRecord, TalerPreciseTimestamp, TalerProtocolTimestamp } from "@gnu-taler/taler-util"; + MailboxMessageRecord, + TalerPreciseTimestamp, + TalerProtocolTimestamp, +} from "@gnu-taler/taler-util"; /** * Run test for basic mailbox operations. @@ -33,9 +35,15 @@ export async function runWalletMailboxBasicTest(t: GlobalTestState) { const { commonDb, merchant, walletClient, bankClient, exchange } = await createSimpleTestkudosEnvironmentV3(t); const mailboxBaseUrl = "https://example.com"; - const mbConf = await walletClient.call(WalletApiOperation.GetMailbox, mailboxBaseUrl); + const mbConf = await walletClient.call( + WalletApiOperation.GetMailbox, + mailboxBaseUrl, + ); - const mbConfAgain = await walletClient.call(WalletApiOperation.GetMailbox, mailboxBaseUrl); + const mbConfAgain = await walletClient.call( + WalletApiOperation.GetMailbox, + mailboxBaseUrl, + ); t.assertDeepEqual(mbConf, mbConfAgain); const messageBob: MailboxMessageRecord = { originMailboxBaseUrl: mailboxBaseUrl, @@ -54,9 +62,11 @@ export async function runWalletMailboxBasicTest(t: GlobalTestState) { message: messageAlice, }); - { - const bi = await walletClient.call(WalletApiOperation.GetMailboxMessages, {}); + const bi = await walletClient.call( + WalletApiOperation.GetMailboxMessages, + {}, + ); t.assertDeepEqual(bi.messages.length, 2); } @@ -65,11 +75,13 @@ export async function runWalletMailboxBasicTest(t: GlobalTestState) { }); { - const bi = await walletClient.call(WalletApiOperation.GetMailboxMessages, {}); + const bi = await walletClient.call( + WalletApiOperation.GetMailboxMessages, + {}, + ); t.assertDeepEqual(bi.messages.length, 1); t.assertDeepEqual(bi.messages[0], messageAlice); } - } runWalletMailboxBasicTest.suites = ["wallet", "wallet-mailbox"]; diff --git a/packages/taler-harness/src/integrationtests/test-wallet-refresh.ts b/packages/taler-harness/src/integrationtests/test-wallet-refresh.ts @@ -46,8 +46,13 @@ import { export async function runWalletRefreshTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -66,7 +71,12 @@ export async function runWalletRefreshTest(t: GlobalTestState) { fulfillment_url: "taler://fulfillment-success/thx", }; - await makeTestPaymentV2(t, { walletClient, merchant, order, merchantAdminAccessToken }); + await makeTestPaymentV2(t, { + walletClient, + merchant, + order, + merchantAdminAccessToken, + }); await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); const txns = await walletClient.call(WalletApiOperation.GetTransactions, { diff --git a/packages/taler-harness/src/integrationtests/test-wallettesting.ts b/packages/taler-harness/src/integrationtests/test-wallettesting.ts @@ -33,8 +33,13 @@ import { GlobalTestState, setupDb } from "../harness/harness.js"; export async function runWallettestingTest(t: GlobalTestState) { const db = await setupDb(t); - const { bankClient, walletClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t, undefined, {}); + const { + bankClient, + walletClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t, undefined, {}); await walletClient.call(WalletApiOperation.RunIntegrationTest, { amountToSpend: "TESTKUDOS:5" as AmountString, diff --git a/packages/taler-harness/src/integrationtests/test-web-merchant-login.ts b/packages/taler-harness/src/integrationtests/test-web-merchant-login.ts @@ -19,10 +19,7 @@ */ import { createSimpleTestkudosEnvironmentV3 } from "harness/environments.js"; import { By } from "selenium-webdriver"; -import { - GlobalTestState, - MERCHANT_DEFAULT_AUTH, -} from "../harness/harness.js"; +import { GlobalTestState, MERCHANT_DEFAULT_AUTH } from "../harness/harness.js"; /** * Do basic checks on instance management and authentication. @@ -49,7 +46,7 @@ export async function runWebMerchantLoginTest(t: GlobalTestState) { const submit = await form.findElement(By.css("button[type=submit]")); await browser.sleep(100); - const inferedUsername = await username.getAttribute("value") + const inferedUsername = await username.getAttribute("value"); t.assertTrue(inferedUsername === "admin"); await password.sendKeys(MERCHANT_DEFAULT_AUTH.password); await submit.click(); diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-conflict.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-conflict.ts @@ -44,35 +44,25 @@ export async function runWithdrawalConflictTest(t: GlobalTestState) { createSimpleTestkudosEnvironmentV3(t), createWalletDaemonWithClient(t, { name: "w2", - }) + }), ]); const user = await bankClient.createRandomBankUser(); bankClient.setAuth(user); // Create a withdrawal operation const amount = "TESTKUDOS:10"; - const wop = await bankClient.createWithdrawalOperation( - user.username, - amount, - ); + const wop = await bankClient.createWithdrawalOperation(user.username, amount); const [wdetails, wprepare1, wprepare2] = await Promise.all([ - wallet1.call( - WalletApiOperation.GetWithdrawalDetailsForUri, - { - talerWithdrawUri: wop.taler_withdraw_uri, - }, - ), wallet1.call( - WalletApiOperation.PrepareBankIntegratedWithdrawal, - { - talerWithdrawUri: wop.taler_withdraw_uri, - }, - ), wallet2.call( - WalletApiOperation.PrepareBankIntegratedWithdrawal, - { - talerWithdrawUri: wop.taler_withdraw_uri, - }, - ) + wallet1.call(WalletApiOperation.GetWithdrawalDetailsForUri, { + talerWithdrawUri: wop.taler_withdraw_uri, + }), + wallet1.call(WalletApiOperation.PrepareBankIntegratedWithdrawal, { + talerWithdrawUri: wop.taler_withdraw_uri, + }), + wallet2.call(WalletApiOperation.PrepareBankIntegratedWithdrawal, { + talerWithdrawUri: wop.taler_withdraw_uri, + }), ]); t.logStep("stopping bank"); @@ -91,7 +81,7 @@ export async function runWithdrawalConflictTest(t: GlobalTestState) { transactionId: wprepare2.transactionId, amount, exchangeBaseUrl: wprepare2.info.defaultExchangeBaseUrl!, - }) + }), ]); t.logStep("withdrawals-confirmed-by-wallets"); @@ -110,7 +100,7 @@ export async function runWithdrawalConflictTest(t: GlobalTestState) { major: TransactionMajorState.Pending, minor: TransactionMinorState.BankRegisterReserve, }, - }) + }), ]); await bank.start(); @@ -143,21 +133,21 @@ export async function runWithdrawalConflictTest(t: GlobalTestState) { wallet2.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: wprepare2.transactionId, txState: expectedFinalStates, - }) + }), ]); const [tx1, tx2] = await Promise.all([ wallet1.call(WalletApiOperation.GetTransactionById, { - transactionId: wprepare1.transactionId + transactionId: wprepare1.transactionId, }), wallet2.call(WalletApiOperation.GetTransactionById, { - transactionId: wprepare2.transactionId - }) + transactionId: wprepare2.transactionId, + }), ]); // FIXME one of them should succeed - t.assertTrue(tx1.txState.major === TransactionMajorState.Failed) - t.assertTrue(tx2.txState.major === TransactionMajorState.Failed) + t.assertTrue(tx1.txState.major === TransactionMajorState.Failed); + t.assertTrue(tx2.txState.major === TransactionMajorState.Failed); /*if (tx1.txState.major === TransactionMajorState.Done) { t.assertTrue(tx2.txState.major === TransactionMajorState.Aborted || tx2.txState.major === TransactionMajorState.Failed) diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-conversion.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-conversion.ts @@ -202,23 +202,27 @@ export async function runWithdrawalConversionTest(t: GlobalTestState) { await merchant.start(); await merchant.pingUntilAvailable(); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }); - - await merchant.addInstanceWithWireAccount({ - id: "minst1", - name: "minst1", - paytoUris: [getTestHarnessPaytoForLabel("minst1")], - defaultWireTransferDelay: Duration.toTalerProtocolDuration( - Duration.fromSpec({ minutes: 1 }), - ), - }, { adminAccessToken }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [getTestHarnessPaytoForLabel("merchant-default")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + await merchant.addInstanceWithWireAccount( + { + id: "minst1", + name: "minst1", + paytoUris: [getTestHarnessPaytoForLabel("minst1")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }, + { adminAccessToken }, + ); const { walletClient } = await createWalletDaemonWithClient(t, { name: "wallet", diff --git a/packages/taler-util/src/CancellationToken.ts b/packages/taler-util/src/CancellationToken.ts @@ -172,7 +172,10 @@ class CancellationToken { } = CancellationToken.create(); let timer: NodeJS.Timeout | null; - timer = setTimeout(() => originalCancel(`CancellationToken.timeout ${ms}`), ms); + timer = setTimeout( + () => originalCancel(`CancellationToken.timeout ${ms}`), + ms, + ); const disposeTimer = () => { if (timer == null) return; clearTimeout(timer); diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts @@ -122,7 +122,7 @@ export class TalerCorebankApiClient { type: "basic", username: this.args.auth.username, password: this.args.auth.password, - }) + }); } async getAccountBalance( @@ -237,8 +237,8 @@ export class TalerCorebankApiClient { headers: authHeaders({ type: "basic", username, - password - }) + password, + }), }); // FIXME: Validate! const acctInfo: TalerCorebankApi.AccountData = diff --git a/packages/taler-util/src/clk.ts b/packages/taler-util/src/clk.ts @@ -614,11 +614,12 @@ export namespace clk { } } - export type GetArgType<T> = T extends Program<any, infer AT> - ? AT - : T extends CommandGroup<any, infer AT> + export type GetArgType<T> = + T extends Program<any, infer AT> ? AT - : any; + : T extends CommandGroup<any, infer AT> + ? AT + : any; export function program<PN extends keyof any>( argKey: PN, diff --git a/packages/taler-util/src/contract-terms.ts b/packages/taler-util/src/contract-terms.ts @@ -25,10 +25,7 @@ import { kdf, stringToBytes, } from "./taler-crypto.js"; -import { - AmountString, - Integer, -} from "./types-taler-common.js"; +import { AmountString, Integer } from "./types-taler-common.js"; import { MerchantContractTerms, MerchantContractTermsV0, @@ -232,7 +229,9 @@ export namespace ContractTermsUtil { throw Error("not implemented yet"); } - export function validateParsed(contractTerms: MerchantContractTerms): boolean { + export function validateParsed( + contractTerms: MerchantContractTerms, + ): boolean { // validate trusted/expected domains if (contractTerms.version === MerchantContractVersion.V1) { const regex = new RegExp("^(\\*\\.)?([\\w\\d]+\\.)+[\\w\\d]+$"); @@ -279,15 +278,17 @@ export namespace ContractTermsUtil { export function extractAmounts( contractTerms: MerchantContractTerms, choiceIndex: Integer | undefined, - ): { - available: true, - amountRaw: AmountString, - maxFee: AmountString, - } | { - available: false, - amountRaw: undefined, - maxFee: undefined, - } { + ): + | { + available: true; + amountRaw: AmountString; + maxFee: AmountString; + } + | { + available: false; + amountRaw: undefined; + maxFee: undefined; + } { let amountRaw: AmountString; let maxFee: AmountString; switch (contractTerms.version) { @@ -321,7 +322,9 @@ export namespace ContractTermsUtil { }; } - export function getV0CompatChoiceIndex(terms: MerchantContractTermsV1): number | undefined { + export function getV0CompatChoiceIndex( + terms: MerchantContractTermsV1, + ): number | undefined { // Select the first choice that doesn't have // and non-currency inputs. let firstGood: number | undefined = undefined; @@ -342,7 +345,9 @@ export namespace ContractTermsUtil { * Returns undefined if downgrading is not possible. This can happen * when the contract only offers token payments. */ - export function downgradeContractTerms(terms: MerchantContractTerms): MerchantContractTermsV0 | undefined { + export function downgradeContractTerms( + terms: MerchantContractTerms, + ): MerchantContractTermsV0 | undefined { if (terms.version == MerchantContractVersion.V0) { return terms; } @@ -381,6 +386,6 @@ export namespace ContractTermsUtil { public_reorder_url: terms.public_reorder_url, summary_i18n: terms.summary_i18n, version: MerchantContractVersion.V0, - } + }; } } diff --git a/packages/taler-util/src/helpers.ts b/packages/taler-util/src/helpers.ts @@ -23,7 +23,6 @@ */ import { URL } from "./url.js"; - /** * Canonicalize a base url, typically for the exchange. * diff --git a/packages/taler-util/src/http-client/README.md b/packages/taler-util/src/http-client/README.md @@ -23,17 +23,20 @@ These API defines: The https clients follows this decisions for consistency. To make it easier to keep track with the spec: - * One API component per file. - * All functions should have a comment that points to the respective Spec - * All functions should be in order as described in the spec + +- One API component per file. +- All functions should have a comment that points to the respective Spec +- All functions should be in order as described in the spec To make it easier to spot incomatible usage use strong typing: - * If the request ended successfully (the operation is committed or the data return is the expected) then return OperationOk - * If the operation fail with an error code documented in the spec then return OperationFail (or OperationAlternative if the failure contains a body) - * If the response contains any other error or the response is unreadable then throw an TalerError with all the information - * Function arguments should use types from the protocol when possible + +- If the request ended successfully (the operation is committed or the data return is the expected) then return OperationOk +- If the operation fail with an error code documented in the spec then return OperationFail (or OperationAlternative if the failure contains a body) +- If the response contains any other error or the response is unreadable then throw an TalerError with all the information +- Function arguments should use types from the protocol when possible To make it easier to reuse - * Class instance should be thread safe and methods should be reentrant - * Only use Taler HttpRequestLibrary interface to make a request - * Do not expose http: URL parameters and Headers can be string arguments + +- Class instance should be thread safe and methods should be reentrant +- Only use Taler HttpRequestLibrary interface to make a request +- Do not expose http: URL parameters and Headers can be string arguments diff --git a/packages/taler-util/src/http-client/bank-conversion.ts b/packages/taler-util/src/http-client/bank-conversion.ts @@ -115,7 +115,7 @@ export class TalerBankConversionHttpClient { const url = new URL(`rate`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "GET", - headers: authHeaders(auth) + headers: authHeaders(auth), }); switch (resp.status) { case HttpStatusCode.Ok: @@ -147,7 +147,7 @@ export class TalerBankConversionHttpClient { } const resp = await this.httpLib.fetch(url.href, { method: "GET", - headers: authHeaders(auth) + headers: authHeaders(auth), }); switch (resp.status) { case HttpStatusCode.Ok: @@ -198,7 +198,7 @@ export class TalerBankConversionHttpClient { } const resp = await this.httpLib.fetch(url.href, { method: "GET", - headers: authHeaders(auth) + headers: authHeaders(auth), }); switch (resp.status) { case HttpStatusCode.Ok: @@ -230,7 +230,10 @@ export class TalerBankConversionHttpClient { * https://docs.taler.net/core/api-bank-conversion-info.html#post--conversion-rate * */ - async updateConversionRate(auth: BasicOrTokenAuth | undefined, body: ConversionRate) { + async updateConversionRate( + auth: BasicOrTokenAuth | undefined, + body: ConversionRate, + ) { const url = new URL(`conversion-rate`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", diff --git a/packages/taler-util/src/http-client/bank-integration.ts b/packages/taler-util/src/http-client/bank-integration.ts @@ -27,14 +27,14 @@ import { opKnownHttpFailure, opKnownTalerFailure, opSuccessFromHttp, - opUnknownHttpFailure + opUnknownHttpFailure, } from "../operation.js"; import { TalerErrorCode } from "../taler-error-codes.js"; import { BankWithdrawalOperationPostRequest, WithdrawalOperationStatusFlag, codecForBankWithdrawalOperationPostResponse, - codecForBankWithdrawalOperationStatus + codecForBankWithdrawalOperationStatus, } from "../types-taler-bank-integration.js"; import { LongPollParams } from "../types-taler-common.js"; import { codecForIntegrationBankConfig } from "../types-taler-corebank.js"; diff --git a/packages/taler-util/src/http-client/bank-wire.ts b/packages/taler-util/src/http-client/bank-wire.ts @@ -49,10 +49,12 @@ import { TalerErrorCode, } from "../index.js"; -export type TalerWireGatewayResultByMethod<prop extends keyof TalerWireGatewayHttpClient> = - ResultByMethod<TalerWireGatewayHttpClient, prop>; -export type TalerWireGatewayErrorsByMethod<prop extends keyof TalerWireGatewayHttpClient> = - FailCasesByMethod<TalerWireGatewayHttpClient, prop>; +export type TalerWireGatewayResultByMethod< + prop extends keyof TalerWireGatewayHttpClient, +> = ResultByMethod<TalerWireGatewayHttpClient, prop>; +export type TalerWireGatewayErrorsByMethod< + prop extends keyof TalerWireGatewayHttpClient, +> = FailCasesByMethod<TalerWireGatewayHttpClient, prop>; /** * The API is used by the exchange to trigger transactions and query @@ -304,7 +306,10 @@ export class TalerWireGatewayHttpClient { * https://docs.taler.net/core/api-bank-wire.html#post--admin-add-kycauth * */ - async addKycAuth(req: { body: TalerWireGatewayApi.AddKycauthRequest; auth?: BasicOrTokenAuth }) { + async addKycAuth(req: { + body: TalerWireGatewayApi.AddKycauthRequest; + auth?: BasicOrTokenAuth; + }) { const url = new URL(`admin/add-kycauth`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", @@ -324,7 +329,10 @@ export class TalerWireGatewayHttpClient { } /** https://docs.taler.net/core/api-bank-wire.html#post--admin-add-mapped */ - async addMapped(req: { body: TalerWireGatewayApi.AddMappedRequest; auth?: BasicOrTokenAuth }) { + async addMapped(req: { + body: TalerWireGatewayApi.AddMappedRequest; + auth?: BasicOrTokenAuth; + }) { const url = new URL(`admin/add-mapped`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts @@ -52,15 +52,17 @@ export function authHeaders(auth?: BasicOrTokenAuth): Record<string, string> { switch (auth.type) { case "basic": { const credentials = `${auth.username}:${auth.password}`; - const authEncoded: string = base64FromArrayBuffer(stringToBytes(credentials)); + const authEncoded: string = base64FromArrayBuffer( + stringToBytes(credentials), + ); return { - Authorization: `Basic ${authEncoded}` - } + Authorization: `Basic ${authEncoded}`, + }; } case "bearer": { return { - Authorization: makeBearerTokenAuthHeader(auth.token) - } + Authorization: makeBearerTokenAuthHeader(auth.token), + }; } } } @@ -93,4 +95,3 @@ export interface CacheEvictor<T> { export const nullEvictor: CacheEvictor<unknown> = { notifySuccess: () => Promise.resolve(), }; - diff --git a/packages/taler-util/src/http-common.ts b/packages/taler-util/src/http-common.ts @@ -536,4 +536,4 @@ export function getDefaultHeaders(method: string): Record<string, string> { headers["Accept"] = "application/json"; return headers; -} -\ No newline at end of file +} diff --git a/packages/taler-util/src/http-impl.node.ts b/packages/taler-util/src/http-impl.node.ts @@ -92,7 +92,9 @@ export class HttpLibImpl implements HttpRequestLibrary { if (logger.shouldLogTrace()) { if (opt?.body != null) { - logger.trace(`request ${rid} ${method} ${url}: ${JSON.stringify(opt.body, undefined, 2)}`); + logger.trace( + `request ${rid} ${method} ${url}: ${JSON.stringify(opt.body, undefined, 2)}`, + ); } else { logger.trace(`request ${rid} ${method} ${url}`); } diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts @@ -1,5 +1,5 @@ export * from "./amounts.js"; -export * from "./bank-api-client.js" +export * from "./bank-api-client.js"; export * from "./base64.js"; export * from "./bech32.js"; export * from "./bitcoin.js"; @@ -35,7 +35,7 @@ export * from "./i18n.js"; export * from "./iban.js"; export * from "./invariants.js"; export * from "./kdf.js"; -export {sha256, HashSha256} from "./sha256.js"; +export { sha256, HashSha256 } from "./sha256.js"; export * from "./libtool-version.js"; export * from "./logging.js"; diff --git a/packages/taler-util/src/longpool-queue.ts b/packages/taler-util/src/longpool-queue.ts @@ -28,9 +28,9 @@ type LongpollRunFn<T> = (timeoutMs: number) => Promise<T>; export class LongpollQueue { private idCounter: number = 0; private queue: (() => void)[] = []; - private permits: number = PERMITS + private permits: number = PERMITS; - constructor() { } + constructor() {} async run<T>( url: URL, @@ -56,7 +56,7 @@ export class LongpollQueue { const numWaiting = this.queue.length; const numConcurrent = PERMITS - this.permits; logger.info( - `running long-poll ${rid} to ${hostname} with ${numWaiting} waiting and ${numConcurrent} running` + `running long-poll ${rid} to ${hostname} with ${numWaiting} waiting and ${numConcurrent} running`, ); try { const timeoutMs = Math.round(Math.max(10000, 30000 / (numWaiting + 1))); @@ -76,12 +76,10 @@ export class LongpollQueue { try { await cancellationToken.racePromise(promcap.promise); } finally { - logger.info( - `long-poll ${rid} to ${hostname} cancelled while queued`, - ); + logger.info(`long-poll ${rid} to ${hostname} cancelled while queued`); triggerNextLongpoll(); } return doRunLongpoll(); } } -} -\ No newline at end of file +} diff --git a/packages/taler-util/src/performance.ts b/packages/taler-util/src/performance.ts @@ -87,8 +87,8 @@ export namespace PerformanceStat { ): PerformanceStat | undefined { if ( (evt.type === ObservabilityEventType.HttpFetchFinishSuccess || - evt.type === ObservabilityEventType.HttpFetchFinishError - ) && !evt.longPolling + evt.type === ObservabilityEventType.HttpFetchFinishError) && + !evt.longPolling ) { return { type: PerformanceStatType.HttpFetch, @@ -217,22 +217,31 @@ export namespace PerformanceTable { */ function insertOrIncrement(tab: PerformanceTable, stat: PerformanceStat) { if (!tab[stat.type]) { - tab[stat.type] = []; - tab[stat.type]?.push(stat); - return; + tab[stat.type] = []; + tab[stat.type]?.push(stat); + return; } - const index = tab[stat.type]!!.findIndex( - (el) => PerformanceStat.equals(el, stat), + const index = tab[stat.type]!!.findIndex((el) => + PerformanceStat.equals(el, stat), ); if (index === -1) { tab[stat.type]?.push(stat); } else { const existing = tab[stat.type]!![index]; - existing.avgDurationMs = Math.floor((existing.avgDurationMs + stat.totalDurationMs) / 2); - existing.maxDurationMs = Math.max(existing.maxDurationMs, stat.maxDurationMs); - existing.minDurationMs = Math.min(existing.minDurationMs, stat.minDurationMs); - existing.totalDurationMs = existing.totalDurationMs + stat.totalDurationMs; + existing.avgDurationMs = Math.floor( + (existing.avgDurationMs + stat.totalDurationMs) / 2, + ); + existing.maxDurationMs = Math.max( + existing.maxDurationMs, + stat.maxDurationMs, + ); + existing.minDurationMs = Math.min( + existing.minDurationMs, + stat.minDurationMs, + ); + existing.totalDurationMs = + existing.totalDurationMs + stat.totalDurationMs; existing.count += 1; tab[stat.type]!![index] = existing; } @@ -243,7 +252,7 @@ export namespace PerformanceTable { */ function sort(tab: PerformanceTable) { for (const k of Object.keys(tab)) { - const key = k as keyof typeof tab + const key = k as keyof typeof tab; tab[key]!!.sort((a, b) => b.avgDurationMs - a.avgDurationMs); } } diff --git a/packages/taler-util/src/prng-browser.ts b/packages/taler-util/src/prng-browser.ts @@ -13,7 +13,8 @@ export function loadBrowserPrng() { // Initialize PRNG if environment provides CSPRNG. // If not, methods calling randombytes will throw. // @ts-expect-error self is not defined - const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : nullRandom; + const cr = + typeof self !== "undefined" ? self.crypto || self.msCrypto : nullRandom; const QUOTA = 65536; setPRNG(function (x: Uint8Array, n: number) { diff --git a/packages/taler-util/src/promises.ts b/packages/taler-util/src/promises.ts @@ -28,7 +28,7 @@ export interface OpenedPromise<T> { /** * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers - * + * * Get an unresolved promise together with its extracted resolve / reject * function. * diff --git a/packages/taler-util/src/punycode.ts b/packages/taler-util/src/punycode.ts @@ -254,7 +254,6 @@ const decode = function (input: string) { for ( let index = basic > 0 ? basic + 1 : 0; index < inputLength /* no final expression */; - ) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, diff --git a/packages/taler-util/src/qr.ts b/packages/taler-util/src/qr.ts @@ -135,7 +135,7 @@ function encodePaytoAsEpcQr(paytoUri: string): EncodeResult { } // declare const __qr_id: unique symbol; -export type SupportedBankQr = ("epc-qr" | "spc");// & { [__qr_id]: true }; +export type SupportedBankQr = "epc-qr" | "spc"; // & { [__qr_id]: true }; /** * Specification of a QR code that includes payment information. */ diff --git a/packages/taler-util/src/taler-crypto.test.ts b/packages/taler-util/src/taler-crypto.test.ts @@ -455,30 +455,26 @@ test("edx test vector", async (t) => { test("chacha20 test vector", async (t) => { const key = new Uint8Array([ - 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ]); const nonce = new Uint8Array([ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4a, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, ]); const plaintextBytes = new Uint8Array([ - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e + 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, + 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, + 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e, ]); // encrypt @@ -488,122 +484,124 @@ test("chacha20 test vector", async (t) => { const plaintext = chacha20_ietf_xor(key, nonce, ciphertext, 1); const decoder = new TextDecoder(); const plaintextStr = decoder.decode(plaintextBytes); - t.deepEqual(plaintextStr, 'Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.'); + t.deepEqual( + plaintextStr, + "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.", + ); }); - test("chacha20poly1305 test vector", async (t) => { const key = new Uint8Array([ - 0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , 0x88 , 0x89 , 0x8a , 0x8b , 0x8c , 0x8d , 0x8e , 0x8f, - 0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , 0x98 , 0x99 , 0x9a , 0x9b , 0x9c , 0x9d , 0x9e , 0x9f + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, ]); const nonce = new Uint8Array([ - 0x07, 0x00, 0x00, 0x00, - 0x40, 0x41, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, + 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, ]); const aad = new Uint8Array([ - 0x50, 0x51, 0x52, 0x53, - 0xc0, 0xc1, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, + 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, ]); const plaintextBytes = new Uint8Array([ - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e + 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, + 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, + 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e, ]); const polyKey = new Uint8Array([ - 0x7b, 0xac, 0x2b, 0x25, - 0x2d, 0xb4, 0x47, 0xaf, - 0x09, 0xb6, 0x7a, 0x55, - 0xa4, 0xe9, 0x55, 0x84, - 0x0a, 0xe1, 0xd6, 0x73, - 0x10, 0x75, 0xd9, 0xeb, - 0x2a, 0x93, 0x75, 0x78, - 0x3e, 0xd5, 0x53, 0xff, + 0x7b, 0xac, 0x2b, 0x25, 0x2d, 0xb4, 0x47, 0xaf, 0x09, 0xb6, 0x7a, 0x55, + 0xa4, 0xe9, 0x55, 0x84, 0x0a, 0xe1, 0xd6, 0x73, 0x10, 0x75, 0xd9, 0xeb, + 0x2a, 0x93, 0x75, 0x78, 0x3e, 0xd5, 0x53, 0xff, ]); const polyOtk = new Uint8Array([ - 0x25, 0x2b, 0xac, 0x7b, - 0xaf, 0x47, 0xb4, 0x2d, - 0x55, 0x7a, 0xb6, 0x09, - 0x84, 0x55, 0xe9, 0xa4, - 0x73, 0xd6, 0xe1, 0x0a, - 0xeb, 0xd9, 0x75, 0x10, - 0x78, 0x75, 0x93, 0x25, - 0xff, 0x53, 0xd5, 0x3e, - 0xde, 0xcc, 0x7e, 0xa2, - 0xb4, 0x4d, 0xdb, 0xad, - 0xe4, 0x9c, 0x17, 0xd1, - 0xd8, 0x43, 0x0b, 0xc9, - 0x8c, 0x94, 0xb7, 0xbc, - 0x8b, 0x7d, 0x4b, 0x4b, - 0x39, 0x27, 0xf6, 0x7d, + 0x25, 0x2b, 0xac, 0x7b, 0xaf, 0x47, 0xb4, 0x2d, 0x55, 0x7a, 0xb6, 0x09, + 0x84, 0x55, 0xe9, 0xa4, 0x73, 0xd6, 0xe1, 0x0a, 0xeb, 0xd9, 0x75, 0x10, + 0x78, 0x75, 0x93, 0x25, 0xff, 0x53, 0xd5, 0x3e, 0xde, 0xcc, 0x7e, 0xa2, + 0xb4, 0x4d, 0xdb, 0xad, 0xe4, 0x9c, 0x17, 0xd1, 0xd8, 0x43, 0x0b, 0xc9, + 0x8c, 0x94, 0xb7, 0xbc, 0x8b, 0x7d, 0x4b, 0x4b, 0x39, 0x27, 0xf6, 0x7d, 0x16, 0x69, 0xa4, 0x32, ]); const block0 = chacha20_ietf(64, key, nonce); t.deepEqual(block0.slice(0, 32), polyKey); // encrypt - const ciphertext = chacha20poly1305_ietf_encrypt(plaintextBytes, aad, nonce, key); + const ciphertext = chacha20poly1305_ietf_encrypt( + plaintextBytes, + aad, + nonce, + key, + ); // decrypt const plaintext = chacha20poly1305_ietf_decrypt(ciphertext, aad, nonce, key); t.false(plaintext === undefined); const decoder = new TextDecoder(); const plaintextStr = decoder.decode(plaintext); - t.deepEqual(plaintextStr, 'Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.'); + t.deepEqual( + plaintextStr, + "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.", + ); }); - // TV are from RFC9180. Not all intermediate steps tested. test("rfc9180 HPKE DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, ChaCha20Poly1305 test vector", async (t) => { const info = new Uint8Array([ - 0x4f, 0x64, 0x65, 0x20, - 0x6f, 0x6e, 0x20, 0x61, - 0x20, 0x47, 0x72, 0x65, - 0x63, 0x69, 0x61, 0x6e, - 0x20, 0x55, 0x72, 0x6e, + 0x4f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x47, 0x72, 0x65, + 0x63, 0x69, 0x61, 0x6e, 0x20, 0x55, 0x72, 0x6e, ]); const pkEm = new Uint8Array([ - 0x1a, 0xfa, 0x08, 0xd3, 0xde, 0xc0, 0x47, 0xa6, - 0x43, 0x88, 0x51, 0x63, 0xf1, 0x18, 0x04, 0x76, - 0xfa, 0x7d, 0xdb, 0x54, 0xc6, 0xa8, 0x02, 0x9e, + 0x1a, 0xfa, 0x08, 0xd3, 0xde, 0xc0, 0x47, 0xa6, 0x43, 0x88, 0x51, 0x63, + 0xf1, 0x18, 0x04, 0x76, 0xfa, 0x7d, 0xdb, 0x54, 0xc6, 0xa8, 0x02, 0x9e, 0xa3, 0x3f, 0x95, 0x79, 0x6b, 0xf2, 0xac, 0x4a, ]); const pkRm = new Uint8Array([ - 0x43, 0x10, 0xee, 0x97, 0xd8, 0x8c, 0xc1, 0xf0, 0x88, 0xa5, 0x57, 0x6c, 0x77, 0xab, 0x0c, 0xf5, 0xc3, 0xac, 0x79, 0x7f, 0x3d, 0x95, 0x13, 0x9c, 0x6c, 0x84, 0xb5, 0x42, 0x9c, 0x59, 0x66, 0x2a, + 0x43, 0x10, 0xee, 0x97, 0xd8, 0x8c, 0xc1, 0xf0, 0x88, 0xa5, 0x57, 0x6c, + 0x77, 0xab, 0x0c, 0xf5, 0xc3, 0xac, 0x79, 0x7f, 0x3d, 0x95, 0x13, 0x9c, + 0x6c, 0x84, 0xb5, 0x42, 0x9c, 0x59, 0x66, 0x2a, ]); const skRm = new Uint8Array([ - 0x80, 0x57, 0x99, 0x1e, 0xef, 0x8f, 0x1f, 0x1a, 0xf1, 0x8f, 0x4a, 0x94, 0x91, 0xd1, 0x6a, 0x1c, 0xe3, 0x33, 0xf6, 0x95, 0xd4, 0xdb, 0x8e, 0x38, 0xda, 0x75, 0x97, 0x5c, 0x44, 0x78, 0xe0, 0xfb + 0x80, 0x57, 0x99, 0x1e, 0xef, 0x8f, 0x1f, 0x1a, 0xf1, 0x8f, 0x4a, 0x94, + 0x91, 0xd1, 0x6a, 0x1c, 0xe3, 0x33, 0xf6, 0x95, 0xd4, 0xdb, 0x8e, 0x38, + 0xda, 0x75, 0x97, 0x5c, 0x44, 0x78, 0xe0, 0xfb, ]); const skEm = new Uint8Array([ - 0xf4, 0xec, 0x9b, 0x33, 0xb7, 0x92, 0xc3, 0x72, 0xc1, 0xd2, 0xc2, 0x06, 0x35, 0x07, 0xb6, 0x84, 0xef, 0x92, 0x5b, 0x8c, 0x75, 0xa4, 0x2d, 0xbc, 0xbf, 0x57, 0xd6, 0x3c, 0xcd, 0x38, 0x16, 0x00, + 0xf4, 0xec, 0x9b, 0x33, 0xb7, 0x92, 0xc3, 0x72, 0xc1, 0xd2, 0xc2, 0x06, + 0x35, 0x07, 0xb6, 0x84, 0xef, 0x92, 0x5b, 0x8c, 0x75, 0xa4, 0x2d, 0xbc, + 0xbf, 0x57, 0xd6, 0x3c, 0xcd, 0x38, 0x16, 0x00, ]); const enc = pkEm; const key = new Uint8Array([ - 0xad, 0x27, 0x44, 0xde, 0x8e, 0x17, 0xf4, 0xeb, 0xba, 0x57, 0x5b, 0x3f, 0x5f, 0x5a, 0x8f, 0xa1, 0xf6, 0x9c, 0x2a, 0x07, 0xf6, 0xe7, 0x50, 0x0b, 0xc6, 0x0c, 0xa6, 0xe3, 0xe3, 0xec, 0x1c, 0x91, + 0xad, 0x27, 0x44, 0xde, 0x8e, 0x17, 0xf4, 0xeb, 0xba, 0x57, 0x5b, 0x3f, + 0x5f, 0x5a, 0x8f, 0xa1, 0xf6, 0x9c, 0x2a, 0x07, 0xf6, 0xe7, 0x50, 0x0b, + 0xc6, 0x0c, 0xa6, 0xe3, 0xe3, 0xec, 0x1c, 0x91, ]); const pt = new Uint8Array([ - 0x42, 0x65, 0x61, 0x75, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x75, 0x74, 0x68, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x74, 0x68, 0x20, 0x62, 0x65, 0x61, 0x75, 0x74, 0x79, - ]); - const aad = new Uint8Array([ - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x30, + 0x42, 0x65, 0x61, 0x75, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, + 0x75, 0x74, 0x68, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x74, 0x68, 0x20, 0x62, + 0x65, 0x61, 0x75, 0x74, 0x79, ]); + const aad = new Uint8Array([0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2d, 0x30]); const ct = new Uint8Array([ - 0x1c, 0x52, 0x50, 0xd8, 0x03, 0x4e, 0xc2, 0xb7, 0x84, 0xba, 0x2c, 0xfd, 0x69, 0xdb, 0xdb, 0x8a, 0xf4, 0x06, 0xcf, 0xe3, 0xff, 0x93, 0x8e, 0x13, 0x1f, 0x0d, 0xef, 0x8c, 0x8b, 0x60, 0xb4, 0xdb, 0x21, 0x99, 0x3c, 0x62, 0xce, 0x81, 0x88, 0x3d, 0x2d, 0xd1, 0xb5, 0x1a, 0x28, + 0x1c, 0x52, 0x50, 0xd8, 0x03, 0x4e, 0xc2, 0xb7, 0x84, 0xba, 0x2c, 0xfd, + 0x69, 0xdb, 0xdb, 0x8a, 0xf4, 0x06, 0xcf, 0xe3, 0xff, 0x93, 0x8e, 0x13, + 0x1f, 0x0d, 0xef, 0x8c, 0x8b, 0x60, 0xb4, 0xdb, 0x21, 0x99, 0x3c, 0x62, + 0xce, 0x81, 0x88, 0x3d, 0x2d, 0xd1, 0xb5, 0x1a, 0x28, ]); const nonce = new Uint8Array([ 0x5c, 0x4d, 0x98, 0x15, 0x06, 0x61, 0xb8, 0x48, 0x85, 0x3b, 0x54, 0x7f, ]); const ss = new Uint8Array([ - 0x0b, 0xbe, 0x78, 0x49, 0x04, 0x12, 0xb4, 0xbb, 0xea, 0x48, 0x12, 0x66, 0x6f, 0x79, 0x16, 0x93, 0x2b, 0x82, 0x8b, 0xba, 0x79, 0x94, 0x24, 0x24, 0xab, 0xb6, 0x52, 0x44, 0x93, 0x0d, 0x69, 0xa7, + 0x0b, 0xbe, 0x78, 0x49, 0x04, 0x12, 0xb4, 0xbb, 0xea, 0x48, 0x12, 0x66, + 0x6f, 0x79, 0x16, 0x93, 0x2b, 0x82, 0x8b, 0xba, 0x79, 0x94, 0x24, 0x24, + 0xab, 0xb6, 0x52, 0x44, 0x93, 0x0d, 0x69, 0xa7, ]); const [enc_cand, ss_cand] = hpkeKemEncapsNorand(pkRm, skEm); t.deepEqual(enc_cand, enc); diff --git a/packages/taler-util/src/taler-crypto.ts b/packages/taler-util/src/taler-crypto.ts @@ -31,7 +31,11 @@ import { Logger } from "./logging.js"; import * as nacl from "./nacl-fast.js"; import { secretbox } from "./nacl-fast.js"; import { TalerProtocolDuration, TalerProtocolTimestamp } from "./time.js"; -import { CoinPublicKeyString, EcdhePublicKey, HashCodeString } from "./types-taler-common.js"; +import { + CoinPublicKeyString, + EcdhePublicKey, + HashCodeString, +} from "./types-taler-common.js"; import { CoinEnvelope, DenomKeyType, @@ -1726,13 +1730,13 @@ export function toHexString(byteArray: Uint8Array) { // DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, ChaCha20Poly1305 // A X25519 public key -export type HpkePublicKey = Uint8Array +export type HpkePublicKey = Uint8Array; // A X25519 secret key export type HpkeSecretKey = Uint8Array; // An X25519 public key -export type HpkeEncapsulation = Uint8Array +export type HpkeEncapsulation = Uint8Array; // This makes sure that sender confusion is // avoided. @@ -1753,13 +1757,12 @@ export enum HpkeMode { // Necessary when we support anything // else than the oneshot APIs export interface HpkeContext { - key: Uint8Array, - nonce: Uint8Array, - seq: number, - role: HpkeRole, + key: Uint8Array; + nonce: Uint8Array; + seq: number; + role: HpkeRole; } - export function hkdf_extract_sha256( ikm: Uint8Array, salt?: Uint8Array, @@ -1767,7 +1770,6 @@ export function hkdf_extract_sha256( salt = salt ?? new Uint8Array(64); // extract return hmacSha256(salt, ikm); - } export function hkdf_expand_sha256( @@ -1775,7 +1777,6 @@ export function hkdf_expand_sha256( prk: Uint8Array, info?: Uint8Array, ): Uint8Array { - info = info ?? new Uint8Array(0); // expand @@ -1801,20 +1802,26 @@ export function hkdf_expand_sha256( return output.slice(0, outputLength); } - export function hpkeLabeledExpand( ctx: string, prk: Uint8Array, label: string, info: Uint8Array, suiteId: Uint8Array, - outLength: number) : Uint8Array { + outLength: number, +): Uint8Array { const outLenBytes = new ArrayBuffer(2); const out = new DataView(outLenBytes); out.setUint16(0, outLength); const labelBytes = stringToBytes(label); const ctxBytes = stringToBytes(ctx); - const labeledInfo = new Uint8Array([...(new Uint8Array(outLenBytes)), ...ctxBytes, ...suiteId, ...labelBytes, ...info]); + const labeledInfo = new Uint8Array([ + ...new Uint8Array(outLenBytes), + ...ctxBytes, + ...suiteId, + ...labelBytes, + ...info, + ]); return hkdf_expand_sha256(outLength, prk, labeledInfo); } @@ -1823,11 +1830,16 @@ export function hpkeLabeledExtract( label: Uint8Array, ikm: Uint8Array, suiteId: Uint8Array, - salt?: Uint8Array): Uint8Array { + salt?: Uint8Array, +): Uint8Array { const ctxBytes = stringToBytes(ctx); - const labeledIkm = new Uint8Array([...ctxBytes, ...suiteId, ...label, ...ikm]); + const labeledIkm = new Uint8Array([ + ...ctxBytes, + ...suiteId, + ...label, + ...ikm, + ]); return hkdf_extract_sha256(labeledIkm, salt); - } export function ecdh_x25519( @@ -1847,43 +1859,49 @@ export function ecdh_x25519( export function hpkeKemEncapsNorand( pkR: Uint8Array, - skE: Uint8Array): [HpkeEncapsulation, Uint8Array] { + skE: Uint8Array, +): [HpkeEncapsulation, Uint8Array] { const enc = ecdhGetPublic(skE); const kem_context = new Uint8Array([...enc, ...pkR]); - const dh = ecdh_x25519 (skE, pkR); - const suiteId = new Uint8Array([0x4B,0x45,0x4D,0x00,0x20]); - const prk = hpkeLabeledExtract("HPKE-v1", - stringToBytes("eae_prk"), - dh, - suiteId); - const ss = hpkeLabeledExpand("HPKE-v1", - prk, - "shared_secret", - kem_context, - suiteId, - 32); + const dh = ecdh_x25519(skE, pkR); + const suiteId = new Uint8Array([0x4b, 0x45, 0x4d, 0x00, 0x20]); + const prk = hpkeLabeledExtract( + "HPKE-v1", + stringToBytes("eae_prk"), + dh, + suiteId, + ); + const ss = hpkeLabeledExpand( + "HPKE-v1", + prk, + "shared_secret", + kem_context, + suiteId, + 32, + ); return [enc, ss]; } -export function hpkeKemDecaps( - skR: Uint8Array, - enc: Uint8Array): Uint8Array { +export function hpkeKemDecaps(skR: Uint8Array, enc: Uint8Array): Uint8Array { const pkR = ecdhGetPublic(skR); const dh = ecdh_x25519(skR, enc); const kem_context = new Uint8Array([...enc, ...pkR]); - const suiteId = new Uint8Array([0x4B,0x45,0x4D,0x00,0x20]); - const prk = hpkeLabeledExtract("HPKE-v1", - stringToBytes("eae_prk"), - dh, - suiteId); - const ss = hpkeLabeledExpand("HPKE-v1", - prk, - "shared_secret", - kem_context, - suiteId, - 32); + const suiteId = new Uint8Array([0x4b, 0x45, 0x4d, 0x00, 0x20]); + const prk = hpkeLabeledExtract( + "HPKE-v1", + stringToBytes("eae_prk"), + dh, + suiteId, + ); + const ss = hpkeLabeledExpand( + "HPKE-v1", + prk, + "shared_secret", + kem_context, + suiteId, + 32, + ); return ss; - } export function hpkeKeySchedule( @@ -1892,12 +1910,13 @@ export function hpkeKeySchedule( sharedSecret: Uint8Array, info: Uint8Array, psk?: Uint8Array, - pskId?: Uint8Array) : HpkeContext { + pskId?: Uint8Array, +): HpkeContext { const suiteId = new ArrayBuffer(4 + 3 * 2); const v = new DataView(suiteId); v.setUint8(0, 0x48); // "H" v.setUint8(1, 0x50); // "P" - v.setUint8(2, 0x4B); // "K" + v.setUint8(2, 0x4b); // "K" v.setUint8(3, 0x45); // "E" v.setUint16(4, 32); // kemID (DHKEM(X25519, HKDF-256)) v.setUint16(6, 1); // KDF ID (HKDF-SHA256) @@ -1919,60 +1938,71 @@ export function hpkeKeySchedule( } } const suiteIdBytes = new Uint8Array(suiteId); - const pskIdHash = hpkeLabeledExtract("HPKE-v1", - stringToBytes("psk_id_hash"), - new Uint8Array([]), - suiteIdBytes); - const infoHash = hpkeLabeledExtract("HPKE-v1", - stringToBytes("info_hash"), - info, - suiteIdBytes); + const pskIdHash = hpkeLabeledExtract( + "HPKE-v1", + stringToBytes("psk_id_hash"), + new Uint8Array([]), + suiteIdBytes, + ); + const infoHash = hpkeLabeledExtract( + "HPKE-v1", + stringToBytes("info_hash"), + info, + suiteIdBytes, + ); const keyScheduleCtx = new Uint8Array([mode, ...pskIdHash, ...infoHash]); - const secret = hpkeLabeledExtract("HPKE-v1", - stringToBytes("secret"), - psk || new Uint8Array([]), - suiteIdBytes, - sharedSecret); - const ctxKey = hpkeLabeledExpand("HPKE-v1", - secret, - "key", - keyScheduleCtx, - suiteIdBytes, - 32); // key 32 bytes / 256 bit - const ctxNonce = hpkeLabeledExpand("HPKE-v1", - secret, - "base_nonce", - keyScheduleCtx, - suiteIdBytes, - 12); // nonce 12 bytes + const secret = hpkeLabeledExtract( + "HPKE-v1", + stringToBytes("secret"), + psk || new Uint8Array([]), + suiteIdBytes, + sharedSecret, + ); + const ctxKey = hpkeLabeledExpand( + "HPKE-v1", + secret, + "key", + keyScheduleCtx, + suiteIdBytes, + 32, + ); // key 32 bytes / 256 bit + const ctxNonce = hpkeLabeledExpand( + "HPKE-v1", + secret, + "base_nonce", + keyScheduleCtx, + suiteIdBytes, + 12, + ); // nonce 12 bytes // We do not support secret export hence no secret export labeledExtract - return {key: ctxKey, nonce: ctxNonce, role: role, seq: 0}; + return { key: ctxKey, nonce: ctxNonce, role: role, seq: 0 }; } - export function hpkeSenderSetupNorand( pkR: HpkePublicKey, skE: HpkeSecretKey, - info: Uint8Array) : [HpkeEncapsulation, HpkeContext] { + info: Uint8Array, +): [HpkeEncapsulation, HpkeContext] { const [enc, sharedSecret] = hpkeKemEncapsNorand(pkR, skE); - const ctx = hpkeKeySchedule(HpkeRole.Sender, - HpkeMode.Base, - sharedSecret, - info); + const ctx = hpkeKeySchedule( + HpkeRole.Sender, + HpkeMode.Base, + sharedSecret, + info, + ); return [enc, ctx]; } - export function hpkeSenderSetup( pkR: HpkePublicKey, - info: Uint8Array) : [HpkeEncapsulation, HpkeContext] { + info: Uint8Array, +): [HpkeEncapsulation, HpkeContext] { const keypair = createEcdheKeyPair(); return hpkeSenderSetupNorand(pkR, keypair.ecdhePriv, info); } -export function hpkeComputeNonce( - ctx: HpkeContext) : Uint8Array { +export function hpkeComputeNonce(ctx: HpkeContext): Uint8Array { const nonce = new ArrayBuffer(12); const seqNboBuf = new ArrayBuffer(8); const v = new DataView(nonce); @@ -1997,13 +2027,11 @@ export function hpkeSealOneshotNorand( skE: HpkeSecretKey, info: Uint8Array, aad: Uint8Array, - plaintext: Uint8Array): Uint8Array { + plaintext: Uint8Array, +): Uint8Array { const [enc, ctx] = hpkeSenderSetupNorand(pkR, skE, info); const nonce = hpkeComputeNonce(ctx); - const ct = chacha20poly1305_ietf_encrypt(plaintext, - aad, - nonce, - ctx.key); + const ct = chacha20poly1305_ietf_encrypt(plaintext, aad, nonce, ctx.key); ctx.seq++; return new Uint8Array([...enc, ...ct]); } @@ -2012,56 +2040,51 @@ export function hpkeSealOneshot( pkR: HpkePublicKey, info: Uint8Array, aad: Uint8Array, - plaintext: Uint8Array): Uint8Array { + plaintext: Uint8Array, +): Uint8Array { const [enc, ctx] = hpkeSenderSetup(pkR, info); const nonce = hpkeComputeNonce(ctx); - const ct = chacha20poly1305_ietf_encrypt(plaintext, - aad, - nonce, - ctx.key); + const ct = chacha20poly1305_ietf_encrypt(plaintext, aad, nonce, ctx.key); ctx.seq++; return new Uint8Array([...enc, ...ct]); } - export function hpkeReceiverSetup( enc: Uint8Array, skR: HpkeSecretKey, - info: Uint8Array) : HpkeContext { + info: Uint8Array, +): HpkeContext { const sharedSecret = hpkeKemDecaps(skR, enc); - return hpkeKeySchedule(HpkeRole.Receiver, - HpkeMode.Base, - sharedSecret, - info); + return hpkeKeySchedule(HpkeRole.Receiver, HpkeMode.Base, sharedSecret, info); } export function hpkeOpenOneshot( skR: HpkeSecretKey, info: Uint8Array, aad: Uint8Array, - ciphertext: Uint8Array): Uint8Array | undefined { + ciphertext: Uint8Array, +): Uint8Array | undefined { try { const enc = ciphertext.slice(0, 32); - const ctx = hpkeReceiverSetup(enc, - skR, - info); + const ctx = hpkeReceiverSetup(enc, skR, info); const nonce = hpkeComputeNonce(ctx); - return chacha20poly1305_ietf_decrypt(ciphertext.slice(32), - aad, - nonce, - ctx.key); + return chacha20poly1305_ietf_decrypt( + ciphertext.slice(32), + aad, + nonce, + ctx.key, + ); } catch (e) { - logger.error("hpkeOpenOneshot failed:" + e) + logger.error("hpkeOpenOneshot failed:" + e); return undefined; } } -export function hpkeSecretKeyGetPublic( - sk: HpkeSecretKey) : HpkePublicKey { +export function hpkeSecretKeyGetPublic(sk: HpkeSecretKey): HpkePublicKey { return ecdhGetPublic(sk as Uint8Array) as HpkePublicKey; } -export function hpkeCreateSecretKey() : HpkeSecretKey { +export function hpkeCreateSecretKey(): HpkeSecretKey { const keypair = createEcdheKeyPair(); return keypair.ecdhePriv as HpkeSecretKey; } @@ -2069,11 +2092,16 @@ export function hpkeCreateSecretKey() : HpkeSecretKey { // RFC 8439 ChaCha20-Poly1305 (IETF variants) function chacha20_toUint32(data: Uint8Array | number[], index: number): number { - return data[index++] ^ (data[index++] << 8) ^ (data[index++] << 16) ^ (data[index] << 24) + return ( + data[index++] ^ + (data[index++] << 8) ^ + (data[index++] << 16) ^ + (data[index] << 24) + ); } function chacha20_rotl(data: number, shift: number): number { - return ((data << shift) | (data >>> (32 - shift))) + return (data << shift) | (data >>> (32 - shift)); } export function chacha20_quarterround( @@ -2081,7 +2109,8 @@ export function chacha20_quarterround( a: number, b: number, c: number, - d: number) { + d: number, +) { out[d] = chacha20_rotl(out[d] ^ (out[a] += out[b]), 16); out[b] = chacha20_rotl(out[b] ^ (out[c] += out[d]), 12); out[d] = chacha20_rotl(out[d] ^ (out[a] += out[b]), 8); @@ -2093,8 +2122,7 @@ export function chacha20_quarterround( out[d] >>>= 0; } -export function chacha20_block( - input: number[]) : Uint8Array { +export function chacha20_block(input: number[]): Uint8Array { const out = Array<number>(64).fill(0); // copy param array to x const x = Array.from(input); @@ -2104,27 +2132,27 @@ export function chacha20_block( // 10 loops × 2 rounds/loop = 20 rounds for (i = 0; i < 20; i += 2) { // Odd round - chacha20_quarterround(x, 0, 4, 8, 12) - chacha20_quarterround(x, 1, 5, 9, 13) - chacha20_quarterround(x, 2, 6, 10, 14) - chacha20_quarterround(x, 3, 7, 11, 15) + chacha20_quarterround(x, 0, 4, 8, 12); + chacha20_quarterround(x, 1, 5, 9, 13); + chacha20_quarterround(x, 2, 6, 10, 14); + chacha20_quarterround(x, 3, 7, 11, 15); // Even round - chacha20_quarterround(x, 0, 5, 10, 15) - chacha20_quarterround(x, 1, 6, 11, 12) - chacha20_quarterround(x, 2, 7, 8, 13) - chacha20_quarterround(x, 3, 4, 9, 14) + chacha20_quarterround(x, 0, 5, 10, 15); + chacha20_quarterround(x, 1, 6, 11, 12); + chacha20_quarterround(x, 2, 7, 8, 13); + chacha20_quarterround(x, 3, 4, 9, 14); } for (i = 0; i < 16; i++) { // out[i] = x[i] + in[i] - let tmp = x[i] + input[i] + let tmp = x[i] + input[i]; // update pad - out[bytesWritten++] = tmp & 0xFF - out[bytesWritten++] = (tmp >>> 8) & 0xFF - out[bytesWritten++] = (tmp >>> 16) & 0xFF - out[bytesWritten++] = (tmp >>> 24) & 0xFF + out[bytesWritten++] = tmp & 0xff; + out[bytesWritten++] = (tmp >>> 8) & 0xff; + out[bytesWritten++] = (tmp >>> 16) & 0xff; + out[bytesWritten++] = (tmp >>> 24) & 0xff; } return new Uint8Array([...out]); } @@ -2133,8 +2161,9 @@ export function chacha20_ietf_xor( key: Uint8Array, nonce: Uint8Array, m: Uint8Array, - c?: number) : Uint8Array { - invariant (0 != m.length); + c?: number, +): Uint8Array { + invariant(0 != m.length); var bytesWritten = 0; const out = new Uint8Array(m.length); const sigma: number[] = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]; @@ -2156,7 +2185,7 @@ export function chacha20_ietf_xor( const param: number[] = [ ...sigma, ...keybytes, - c? c: 0, // Counter, index is 12 + c ? c : 0, // Counter, index is 12 ...noncebytes, ]; for (let i = 0; i < m.length; i++) { @@ -2172,17 +2201,17 @@ export function chacha20_ietf_xor( bytesWritten = 0; } invariant(pad != undefined); - out[i] = m[i] ^ pad[bytesWritten++] + out[i] = m[i] ^ pad[bytesWritten++]; } return out; } - export function chacha20_ietf( outBytes: number, key: Uint8Array, - nonce: Uint8Array) : Uint8Array { + nonce: Uint8Array, +): Uint8Array { var bytesWritten = 0; const m = Array<number>(outBytes).fill(0); const out = new Uint8Array(m.length); @@ -2221,7 +2250,7 @@ export function chacha20_ietf( bytesWritten = 0; } invariant(pad != undefined); - out[i] = m[i] ^ pad[bytesWritten++] + out[i] = m[i] ^ pad[bytesWritten++]; } return out; @@ -2231,7 +2260,8 @@ export function chacha20poly1305_ietf_encrypt( m: Uint8Array, ad: Uint8Array, npub: Uint8Array, - k: Uint8Array) : Uint8Array { + k: Uint8Array, +): Uint8Array { invariant(k.length == 32); invariant(npub.length == 12); const slenBuf = new ArrayBuffer(8); @@ -2257,7 +2287,8 @@ export function chacha20poly1305_ietf_decrypt( ct: Uint8Array, ad: Uint8Array, npub: Uint8Array, - k: Uint8Array) : Uint8Array | undefined { + k: Uint8Array, +): Uint8Array | undefined { invariant(k.length == 32); invariant(npub.length == 12); const slenBuf = new ArrayBuffer(8); @@ -2270,7 +2301,7 @@ export function chacha20poly1305_ietf_decrypt( p.update(ad, 0, ad.length); p.update(pad0, 0, (0x10 - ad.length) & 0xf); p.update(ct, 0, mlen); - p.update(pad0, 0, (0x10 - (mlen)) & 0xf); + p.update(pad0, 0, (0x10 - mlen) & 0xf); slenDv.setBigUint64(0, BigInt(ad.length), true); p.update(new Uint8Array(slenBuf), 0, 8); slenDv.setBigUint64(0, BigInt(mlen), true); @@ -2278,7 +2309,7 @@ export function chacha20poly1305_ietf_decrypt( p.finish(tag, 0); if (nacl.crypto_verify_16(tag, 0, ct, mlen) !== 0) { return undefined; - }; + } const m = chacha20_ietf_xor(k, npub, ct.slice(0, mlen), 1); return m; } diff --git a/packages/taler-util/src/taleruri.test.ts b/packages/taler-util/src/taleruri.test.ts @@ -39,7 +39,7 @@ import { stringifyRefundUri, stringifyRestoreUri, stringifyWithdrawExchange, - stringifyWithdrawUri + stringifyWithdrawUri, } from "./taleruri.js"; import { AmountString } from "./types-taler-common.js"; @@ -419,7 +419,8 @@ import { AmountString } from "./types-taler-common.js"; test("taler pay template URI (stringify, case-sensitive)", (t) => { const url1 = stringifyPayTemplateUri({ - merchantBaseUrl: "http://merchant.example.com:1234/InstanceName/" as HostPortPath, + merchantBaseUrl: + "http://merchant.example.com:1234/InstanceName/" as HostPortPath, templateId: "FEGHYJY48FEGU6WETYIOIDEDE2QW3OCZVY", }); t.deepEqual( @@ -641,7 +642,10 @@ import { AmountString } from "./types-taler-common.js"; mailboxBaseUri: "https://mailbox.example.com/mb", mailboxIdentity: "SOMEHASHOFPUBKEY", }); - t.deepEqual(url, "taler://add-contact/email/bob@example.com/mailbox.example.com/mb/SOMEHASHOFPUBKEY?sourceBaseUrl=https%3A%2F%2Ftaldir.example.com"); + t.deepEqual( + url, + "taler://add-contact/email/bob@example.com/mailbox.example.com/mb/SOMEHASHOFPUBKEY?sourceBaseUrl=https%3A%2F%2Ftaldir.example.com", + ); }); /** diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts @@ -297,7 +297,8 @@ export namespace TalerUris { return result; } case TalerUriAction.PayTemplate: { - if (p.fulfillmentUrl) result.push(["fulfillment_url", p.fulfillmentUrl]); + if (p.fulfillmentUrl) + result.push(["fulfillment_url", p.fulfillmentUrl]); if (p.sessionId) result.push(["session_id", p.sessionId]); return result; } @@ -408,47 +409,47 @@ export namespace TalerUris { export type InvalidTargetPathDetail = | { - uriType: TalerUriAction.Pay; - } + uriType: TalerUriAction.Pay; + } | { - uriType: TalerUriAction.Withdraw; - } + uriType: TalerUriAction.Withdraw; + } | { - uriType: TalerUriAction.Refund; - pos: 0; - } + uriType: TalerUriAction.Refund; + pos: 0; + } | { - uriType: TalerUriAction.Refund; - pos: 1; - } + uriType: TalerUriAction.Refund; + pos: 1; + } | { - uriType: TalerUriAction.PayPull; - pos: 0; - } + uriType: TalerUriAction.PayPull; + pos: 0; + } | { - uriType: TalerUriAction.PayPush; - pos: 0; - } + uriType: TalerUriAction.PayPush; + pos: 0; + } | { - uriType: TalerUriAction.PayTemplate; - pos: 0; - } + uriType: TalerUriAction.PayTemplate; + pos: 0; + } | { - uriType: TalerUriAction.WithdrawExchange; - pos: 0; - } + uriType: TalerUriAction.WithdrawExchange; + pos: 0; + } | { - uriType: TalerUriAction.WithdrawExchange; - pos: 1; - } + uriType: TalerUriAction.WithdrawExchange; + pos: 1; + } | { - uriType: TalerUriAction.AddExchange; - pos: 0; - } + uriType: TalerUriAction.AddExchange; + pos: 0; + } | { - uriType: TalerUriAction.AddContact; - pos: 0; - }; + uriType: TalerUriAction.AddContact; + pos: 0; + }; export function fromString( s: string, @@ -459,17 +460,17 @@ export namespace TalerUris { | ResultError<TalerUriParseError.UNSUPPORTED, { uriType: string }> | ResultError<TalerUriParseError.INCOMPLETE, { uriType: string }> | ResultError< - TalerUriParseError.COMPONENTS_LENGTH, - { uriType: TalerUriAction } - > + TalerUriParseError.COMPONENTS_LENGTH, + { uriType: TalerUriAction } + > | ResultError< - TalerUriParseError.INVALID_TARGET_PATH, - InvalidTargetPathDetail - > + TalerUriParseError.INVALID_TARGET_PATH, + InvalidTargetPathDetail + > | ResultError< - TalerUriParseError.INVALID_PARAMETER, - { uriType: TalerUriAction; name: string } - > { + TalerUriParseError.INVALID_PARAMETER, + { uriType: TalerUriAction; name: string } + > { // check prefix let isHttp = false; const prefixCheck = opts.ignoreUppercase ? s.toLowerCase() : s; diff --git a/packages/taler-util/src/taleruris.test.ts b/packages/taler-util/src/taleruris.test.ts @@ -406,7 +406,8 @@ test("taler-new pay template URI (stringify)", (t) => { test("taler-new pay template URI (stringify, case-sensitive)", (t) => { const url1 = TalerUris.toString({ type: TalerUriAction.PayTemplate, - merchantBaseUrl: "http://merchant.example.com:1234/InstanceName/" as HostPortPath, + merchantBaseUrl: + "http://merchant.example.com:1234/InstanceName/" as HostPortPath, templateId: "FEGHYJY48FEGU6WETYIOIDEDE2QW3OCZVY", }); t.deepEqual( diff --git a/packages/taler-util/src/timer.ts b/packages/taler-util/src/timer.ts @@ -97,7 +97,8 @@ export const performanceNow: () => bigint = (() => { return () => BigInt(new Date().getTime()) * BigInt(1000) * BigInt(1000); })(); -export const performanceDelta = (start: bigint, end: bigint) => Number((end - start) / 1000n / 1000n); +export const performanceDelta = (start: bigint, end: bigint) => + Number((end - start) / 1000n / 1000n); const nullTimerHandle = { clear() { diff --git a/packages/taler-util/src/types-taler-common.ts b/packages/taler-util/src/types-taler-common.ts @@ -225,7 +225,7 @@ export const codecForInternationalizedString = export const codecForCurrencySpecificiation = (): Codec<CurrencySpecification> => -buildCodecForObject<CurrencySpecification>() + buildCodecForObject<CurrencySpecification>() .property("name", codecForString()) .property("num_fractional_input_digits", codecForNumber()) .property("num_fractional_normal_digits", codecForNumber()) diff --git a/packages/taler-util/src/types-taler-corebank.ts b/packages/taler-util/src/types-taler-corebank.ts @@ -33,7 +33,11 @@ import { import { PaytoString, codecForPaytoString } from "./payto.js"; import { codecForTalerUriString, TalerUriString } from "./taleruri.js"; import { codecForTimestamp } from "./time.js"; -import { codecForConversionRate, ConversionRate, RoundingMode } from "./types-taler-bank-conversion.js"; +import { + codecForConversionRate, + ConversionRate, + RoundingMode, +} from "./types-taler-bank-conversion.js"; import { WithdrawalOperationStatusFlag } from "./types-taler-bank-integration.js"; import { AmountString, @@ -792,8 +796,6 @@ export interface MonitorWithConversion { talerOutVolume: AmountString; } - - export const codecForIntegrationBankConfig = (): Codec<IntegrationConfig> => buildCodecForObject<IntegrationConfig>() .property("name", codecForConstString("taler-bank-integration")) @@ -955,11 +957,13 @@ export const codecForConversionRateClass = (): Codec<ConversionRateClass> => .property("cashout_ratio", codecOptional(codecForDecimalNumber())) .property( "cashout_rounding_mode", - codecOptional(codecForEither( - codecForConstString("zero"), - codecForConstString("up"), - codecForConstString("nearest"), - )), + codecOptional( + codecForEither( + codecForConstString("zero"), + codecForConstString("up"), + codecForConstString("nearest"), + ), + ), ) .property("conversion_rate_class_id", codecForNumber()) .property("description", codecOptional(codecForString())) @@ -1116,4 +1120,3 @@ export const codecForMonitorWithCashout = (): Codec<MonitorWithConversion> => .property("talerOutCount", codecForNumber()) .property("talerOutVolume", codecForAmountString()) .build("TalerCorebankApi.MonitorWithCashout"); - diff --git a/packages/taler-util/src/types-taler-kyc-aml.ts b/packages/taler-util/src/types-taler-kyc-aml.ts @@ -22,11 +22,9 @@ import { codecForAny, codecForList, codecOptional, - LegitimizationRuleSet + LegitimizationRuleSet, } from "./index.js"; -import { - Timestamp -} from "./types-taler-common.js"; +import { Timestamp } from "./types-taler-common.js"; // https://docs.taler.net/taler-kyc-manual.html#implementing-your-own-aml-programs @@ -213,7 +211,6 @@ export interface AmlOutcome { new_measures?: string; } - export const codecForAmlProgramInput = (): Codec<AmlProgramInput> => buildCodecForObject<AmlProgramInput>() .property("aml_history", codecOptional(codecForList(codecForAny()))) diff --git a/packages/taler-util/src/types-taler-mailbox.ts b/packages/taler-util/src/types-taler-mailbox.ts @@ -24,14 +24,8 @@ import { codecForNumber, codecOptional, } from "./codec.js"; -import { - codecForString, - codecForConstString, -} from "./index.js"; -import { - codecForDuration, - codecForTimestamp, -} from "./time.js"; +import { codecForString, codecForConstString } from "./index.js"; +import { codecForDuration, codecForTimestamp } from "./time.js"; import { AmountString, codecForEddsaPublicKey, @@ -55,7 +49,6 @@ export const codecForTalerMailboxConfigResponse = .property("delivery_period", codecForDuration) .build("TalerMailboxApi.VersionResponse"); - export interface TalerMailboxConfigResponse { // libtool-style representation of the Mailbox protocol version, see // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning @@ -112,28 +105,21 @@ export const codecForMailboxRegisterPaymentRequired = .property("talerUri", codecOptional(codecForString())) .build("MailboxRegisterPaymentRequired"); -export const codecForMailboxRegisterResult = - (): Codec<MailboxRegisterResult> => - buildCodecForUnion<MailboxRegisterResult>() - .discriminateOn("status") - .alternative("ok", codecForMailboxRegisterOk()) - .alternative( - "payment-required", - codecForMailboxRegisterPaymentRequired(), - ) - .build("MailboxRegisterResult"); - +export const codecForMailboxRegisterResult = (): Codec<MailboxRegisterResult> => + buildCodecForUnion<MailboxRegisterResult>() + .discriminateOn("status") + .alternative("ok", codecForMailboxRegisterOk()) + .alternative("payment-required", codecForMailboxRegisterPaymentRequired()) + .build("MailboxRegisterResult"); export const codecForTalerMailboxRegisterRequest = (): Codec<MailboxRegisterRequest> => -buildCodecForObject<MailboxRegisterRequest>() + buildCodecForObject<MailboxRegisterRequest>() .property("mailbox_metadata", codecForTalerMailboxMetadata()) .property("signature", codecForString()) .build("TalerMailboxApi.MailboxRegisterRequest"); - export interface MailboxRegisterRequest { - // Mailbox metadata. mailbox_metadata: MailboxMetadata; @@ -143,22 +129,18 @@ export interface MailboxRegisterRequest { // The signature is created over the SHA-512 hash // of (encryptionKeyType||encryptionKey||expiration) signature: EddsaSignatureString; - } -export const codecForTalerMailboxMetadata = - (): Codec<MailboxMetadata> => -buildCodecForObject<MailboxMetadata>() - .property("signing_key", codecForEddsaPublicKey()) - .property("signing_key_type", codecForConstString("EdDSA")) - .property("encryption_key", codecForString()) - .property("encryption_key_type", codecForConstString("X25519")) - .property("expiration", codecForTimestamp) - .build("TalerMailboxApi.MailboxMessageKeys"); - +export const codecForTalerMailboxMetadata = (): Codec<MailboxMetadata> => + buildCodecForObject<MailboxMetadata>() + .property("signing_key", codecForEddsaPublicKey()) + .property("signing_key_type", codecForConstString("EdDSA")) + .property("encryption_key", codecForString()) + .property("encryption_key_type", codecForConstString("X25519")) + .property("expiration", codecForTimestamp) + .build("TalerMailboxApi.MailboxMessageKeys"); export interface MailboxMetadata { - // The mailbox signing key. // Note that $H_MAILBOX == H(singingKey). // Note also how this key cannot be updated @@ -186,7 +168,6 @@ export interface MailboxMetadata { expiration: Timestamp; } - export const codecForTalerMailboxRateLimitedResponse = (): Codec<MailboxRateLimitedResponse> => buildCodecForObject<MailboxRateLimitedResponse>() @@ -196,7 +177,6 @@ export const codecForTalerMailboxRateLimitedResponse = .build("TalerMailboxApi.MailboxRateLimitedResponse"); export interface MailboxRateLimitedResponse { - // Taler error code, TALER_EC_MAILBOX_DELIVERY_RATE_LIMITED. code: number; @@ -205,5 +185,4 @@ export interface MailboxRateLimitedResponse { // The human readable error message. hint: string; - } diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts @@ -5407,10 +5407,7 @@ export const codecForTemplateContractDetails = TemplateType.INVENTORY_CART, codecForTemplateContractInventoryCart(), ) - .alternative( - TemplateType.PAIVANA, - codecForTemplateContractPaivana(), - ) + .alternative(TemplateType.PAIVANA, codecForTemplateContractPaivana()) .alternativeOnMissing( TemplateType.FIXED_ORDER, codecForTemplateContractFixedOrder(), diff --git a/packages/taler-util/src/types-taler-prepared-transfer.ts b/packages/taler-util/src/types-taler-prepared-transfer.ts @@ -143,12 +143,13 @@ export interface Unregistration { authorization_sig: EddsaSignature; } -export const codeForSubjectFormat = (): Codec<TalerPreparedTransferApi.SubjectFormat> => - codecForEither( - codecForConstString("SIMPLE"), - codecForConstString("URI"), - codecForConstString("CH_QR_BILL"), - ); +export const codeForSubjectFormat = + (): Codec<TalerPreparedTransferApi.SubjectFormat> => + codecForEither( + codecForConstString("SIMPLE"), + codecForConstString("URI"), + codecForConstString("CH_QR_BILL"), + ); export const codecForPreparedTransferConfig = (): Codec<TalerPreparedTransferApi.PreparedTransferConfig> => @@ -164,7 +165,13 @@ export const codecForRegistrationRequest = (): Codec<TalerPreparedTransferApi.RegistrationRequest> => buildCodecForObject<TalerPreparedTransferApi.RegistrationRequest>() .property("credit_amount", codecForAmountString()) - .property("type", codecForEither(codecForConstString("reserve"), codecForConstString("kyc"))) + .property( + "type", + codecForEither( + codecForConstString("reserve"), + codecForConstString("kyc"), + ), + ) .property("alg", codecForEither(codecForConstString("EdDSA"))) .property("account_pub", codecForEddsaPublicKey()) .property("authorization_pub", codecForEddsaPublicKey()) @@ -172,34 +179,38 @@ export const codecForRegistrationRequest = .property("recurrent", codecForBoolean()) .build("TalerWireGatewayApi.RegistrationRequest"); -export const codecForTransferSubject = (): Codec<TalerPreparedTransferApi.TransferSubject> => - buildCodecForUnion<TalerPreparedTransferApi.TransferSubject>() - .discriminateOn("type") - .alternative("SIMPLE", codecForSimpleSubject()) - .alternative("URI", codecForUriSubject()) - .alternative("CH_QR_BILL", codecForSwissQrBillSubject()) - .build("TalerPreparedTransferApi.TransferSubject"); - -export const codecForSimpleSubject = (): Codec<TalerPreparedTransferApi.SimpleSubject> => - buildCodecForObject<TalerPreparedTransferApi.SimpleSubject>() - .property("type", codecForConstString("SIMPLE")) - .property("credit_amount", codecForAmountString()) - .property("subject", codecForString()) - .build("TalerPreparedTransferApi.SimpleSubject"); - -export const codecForUriSubject = (): Codec<TalerPreparedTransferApi.UriSubject> => - buildCodecForObject<TalerPreparedTransferApi.UriSubject>() - .property("type", codecForConstString("URI")) - .property("credit_amount", codecForAmountString()) - .property("uri", codecForStringURL()) - .build("TalerPreparedTransferApi.UriSubject"); - -export const codecForSwissQrBillSubject = (): Codec<TalerPreparedTransferApi.SwissQrBillSubject> => - buildCodecForObject<TalerPreparedTransferApi.SwissQrBillSubject>() - .property("type", codecForConstString("CH_QR_BILL")) - .property("credit_amount", codecForAmountString()) - .property("qr_reference_number", codecForString()) - .build("TalerPreparedTransferApi.SwissQrBillSubject"); +export const codecForTransferSubject = + (): Codec<TalerPreparedTransferApi.TransferSubject> => + buildCodecForUnion<TalerPreparedTransferApi.TransferSubject>() + .discriminateOn("type") + .alternative("SIMPLE", codecForSimpleSubject()) + .alternative("URI", codecForUriSubject()) + .alternative("CH_QR_BILL", codecForSwissQrBillSubject()) + .build("TalerPreparedTransferApi.TransferSubject"); + +export const codecForSimpleSubject = + (): Codec<TalerPreparedTransferApi.SimpleSubject> => + buildCodecForObject<TalerPreparedTransferApi.SimpleSubject>() + .property("type", codecForConstString("SIMPLE")) + .property("credit_amount", codecForAmountString()) + .property("subject", codecForString()) + .build("TalerPreparedTransferApi.SimpleSubject"); + +export const codecForUriSubject = + (): Codec<TalerPreparedTransferApi.UriSubject> => + buildCodecForObject<TalerPreparedTransferApi.UriSubject>() + .property("type", codecForConstString("URI")) + .property("credit_amount", codecForAmountString()) + .property("uri", codecForStringURL()) + .build("TalerPreparedTransferApi.UriSubject"); + +export const codecForSwissQrBillSubject = + (): Codec<TalerPreparedTransferApi.SwissQrBillSubject> => + buildCodecForObject<TalerPreparedTransferApi.SwissQrBillSubject>() + .property("type", codecForConstString("CH_QR_BILL")) + .property("credit_amount", codecForAmountString()) + .property("qr_reference_number", codecForString()) + .build("TalerPreparedTransferApi.SwissQrBillSubject"); export const codecForRegistrationResponse = (): Codec<TalerPreparedTransferApi.RegistrationResponse> => @@ -208,9 +219,10 @@ export const codecForRegistrationResponse = .property("expiration", codecForTimestamp) .build("TalerWireGatewayApi.RegistrationResponse"); -export const codecForUnregistration = (): Codec<TalerPreparedTransferApi.Unregistration> => - buildCodecForObject<TalerPreparedTransferApi.Unregistration>() - .property("timestamp", codecForString()) - .property("authorization_pub", codecForEddsaPublicKey()) - .property("authorization_sig", codecForEddsaSignature()) - .build("TalerPreparedTransferApi.Unregistration"); +export const codecForUnregistration = + (): Codec<TalerPreparedTransferApi.Unregistration> => + buildCodecForObject<TalerPreparedTransferApi.Unregistration>() + .property("timestamp", codecForString()) + .property("authorization_pub", codecForEddsaPublicKey()) + .property("authorization_sig", codecForEddsaSignature()) + .build("TalerPreparedTransferApi.Unregistration"); diff --git a/packages/taler-util/src/types-taler-wire-gateway.ts b/packages/taler-util/src/types-taler-wire-gateway.ts @@ -29,7 +29,11 @@ import { codecForStringURL, codecOptional, } from "./codec.js"; -import { codecForEddsaSignature, EddsaSignature, TalerWireGatewayApi } from "./index.js"; +import { + codecForEddsaSignature, + EddsaSignature, + TalerWireGatewayApi, +} from "./index.js"; import { codecForAmountString } from "./amounts.js"; import { PaytoString, codecForPaytoString } from "./payto.js"; import { codecForTimestamp } from "./time.js"; @@ -299,7 +303,11 @@ export interface BankWireTransferList { debit_account: string; } -export type WireTransferStatus = "pending" | "transient_failure" | "permanent_failure" | "success"; +export type WireTransferStatus = + | "pending" + | "transient_failure" + | "permanent_failure" + | "success"; export interface BankWireTransferListStatus { // Opaque ID of the wire transfer initiation performed by the bank. @@ -365,26 +373,32 @@ export interface BankWireTransferStatus { timestamp: Timestamp; } -export const codecForWireConfigResponse = (): Codec<TalerWireGatewayApi.WireConfig> => - buildCodecForObject<TalerWireGatewayApi.WireConfig>() - .property("currency", codecForString()) - .property("implementation", codecForString()) - .property("name", codecForConstString("taler-wire-gateway")) - .property("support_account_check", codecForBoolean()) - .property("version", codecForString()) - .build("TalerWireGatewayApi.WireConfig"); - -export const codecForTransferResponse = (): Codec<TalerWireGatewayApi.TransferResponse> => - buildCodecForObject<TalerWireGatewayApi.TransferResponse>() - .property("row_id", codecForNumber()) - .property("timestamp", codecForTimestamp) - .build("TalerWireGatewayApi.TransferResponse"); - -export const codecForIncomingHistory = (): Codec<TalerWireGatewayApi.IncomingHistory> => - buildCodecForObject<TalerWireGatewayApi.IncomingHistory>() - .property("credit_account", codecForPaytoString()) - .property("incoming_transactions", codecForList(codecForIncomingBankTransaction())) - .build("TalerWireGatewayApi.IncomingHistory"); +export const codecForWireConfigResponse = + (): Codec<TalerWireGatewayApi.WireConfig> => + buildCodecForObject<TalerWireGatewayApi.WireConfig>() + .property("currency", codecForString()) + .property("implementation", codecForString()) + .property("name", codecForConstString("taler-wire-gateway")) + .property("support_account_check", codecForBoolean()) + .property("version", codecForString()) + .build("TalerWireGatewayApi.WireConfig"); + +export const codecForTransferResponse = + (): Codec<TalerWireGatewayApi.TransferResponse> => + buildCodecForObject<TalerWireGatewayApi.TransferResponse>() + .property("row_id", codecForNumber()) + .property("timestamp", codecForTimestamp) + .build("TalerWireGatewayApi.TransferResponse"); + +export const codecForIncomingHistory = + (): Codec<TalerWireGatewayApi.IncomingHistory> => + buildCodecForObject<TalerWireGatewayApi.IncomingHistory>() + .property("credit_account", codecForPaytoString()) + .property( + "incoming_transactions", + codecForList(codecForIncomingBankTransaction()), + ) + .build("TalerWireGatewayApi.IncomingHistory"); export const codecForIncomingBankTransaction = (): Codec<TalerWireGatewayApi.IncomingBankTransaction> => @@ -435,11 +449,15 @@ export const codecForIncomingWadTransaction = .property("authorization_sig", codecOptional(codecForEddsaSignature())) .build("TalerWireGatewayApi.IncomingWadTransaction"); -export const codecForOutgoingHistory = (): Codec<TalerWireGatewayApi.OutgoingHistory> => - buildCodecForObject<TalerWireGatewayApi.OutgoingHistory>() - .property("debit_account", codecForPaytoString()) - .property("outgoing_transactions", codecForList(codecForOutgoingBankTransaction())) - .build("TalerWireGatewayApi.OutgoingHistory"); +export const codecForOutgoingHistory = + (): Codec<TalerWireGatewayApi.OutgoingHistory> => + buildCodecForObject<TalerWireGatewayApi.OutgoingHistory>() + .property("debit_account", codecForPaytoString()) + .property( + "outgoing_transactions", + codecForList(codecForOutgoingBankTransaction()), + ) + .build("TalerWireGatewayApi.OutgoingHistory"); export const codecForOutgoingBankTransaction = (): Codec<TalerWireGatewayApi.OutgoingBankTransaction> => @@ -452,17 +470,19 @@ export const codecForOutgoingBankTransaction = .property("exchange_base_url", codecForString()) .build("TalerWireGatewayApi.OutgoingBankTransaction"); -export const codecForAddIncomingResponse = (): Codec<TalerWireGatewayApi.AddIncomingResponse> => - buildCodecForObject<TalerWireGatewayApi.AddIncomingResponse>() - .property("row_id", codecForNumber()) - .property("timestamp", codecForTimestamp) - .build("TalerWireGatewayApi.AddIncomingResponse"); - -export const codecForBankWireTransferList = (): Codec<TalerWireGatewayApi.BankWireTransferList> => - buildCodecForObject<TalerWireGatewayApi.BankWireTransferList>() - .property("debit_account", codecForPaytoString()) - .property("transfers", codecForList(codecForBankWireTransferListStatus())) - .build("TalerWireGatewayApi.BankWireTransferList"); +export const codecForAddIncomingResponse = + (): Codec<TalerWireGatewayApi.AddIncomingResponse> => + buildCodecForObject<TalerWireGatewayApi.AddIncomingResponse>() + .property("row_id", codecForNumber()) + .property("timestamp", codecForTimestamp) + .build("TalerWireGatewayApi.AddIncomingResponse"); + +export const codecForBankWireTransferList = + (): Codec<TalerWireGatewayApi.BankWireTransferList> => + buildCodecForObject<TalerWireGatewayApi.BankWireTransferList>() + .property("debit_account", codecForPaytoString()) + .property("transfers", codecForList(codecForBankWireTransferListStatus())) + .build("TalerWireGatewayApi.BankWireTransferList"); export const codecForBankWireTransferStatus = (): Codec<TalerWireGatewayApi.BankWireTransferStatus> => diff --git a/packages/taler-util/src/types.test.ts b/packages/taler-util/src/types.test.ts @@ -15,14 +15,20 @@ */ import test from "ava"; -import { codecForMerchantContractTerms, EddsaPublicKeyString, MerchantContractTerms } from "./index.js"; +import { + codecForMerchantContractTerms, + EddsaPublicKeyString, + MerchantContractTerms, +} from "./index.js"; test("contract terms validation", (t) => { const c = { nonce: "123123123", h_wire: "123", amount: "EUR:1.5", - exchanges: [{ master_pub: "foo" as EddsaPublicKeyString, priority: 1, url: "foo" }], + exchanges: [ + { master_pub: "foo" as EddsaPublicKeyString, priority: 1, url: "foo" }, + ], fulfillment_url: "foo", max_fee: "EUR:1.5", merchant_pub: "12345", @@ -58,7 +64,9 @@ test("contract terms validation (locations)", (t) => { nonce: "123123123", h_wire: "123", amount: "EUR:1.5", - exchanges: [{ master_pub: "foo" as EddsaPublicKeyString, priority: 1, url: "foo" }], + exchanges: [ + { master_pub: "foo" as EddsaPublicKeyString, priority: 1, url: "foo" }, + ], fulfillment_url: "foo", max_fee: "EUR:1.5", merchant_pub: "12345", diff --git a/packages/taler-wallet-core/src/coinSelection.ts b/packages/taler-wallet-core/src/coinSelection.ts @@ -63,10 +63,7 @@ import { PaymentBalanceDetails, } from "./balance.js"; import { getAutoRefreshExecuteThreshold } from "./common.js"; -import { - DenominationRecord, - WalletIndexedDbTransaction, -} from "./db.js"; +import { DenominationRecord, WalletIndexedDbTransaction } from "./db.js"; import { checkExchangeInScopeTx, ExchangeDetails, diff --git a/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts b/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts @@ -25,9 +25,7 @@ import { SynchronousCryptoWorkerPlain } from "./synchronousWorkerPlain.js"; * The synchronous crypto worker produced by this factory doesn't run in the * background, but actually blocks the caller until the operation is done. */ -export class SynchronousCryptoWorkerFactoryPlain - implements CryptoWorkerFactory -{ +export class SynchronousCryptoWorkerFactoryPlain implements CryptoWorkerFactory { startWorker(): CryptoWorker { return new SynchronousCryptoWorkerPlain(); } diff --git a/packages/taler-wallet-core/src/observable-wrappers.ts b/packages/taler-wallet-core/src/observable-wrappers.ts @@ -128,9 +128,9 @@ export function getCallerInfo(up: number = 2): string { return identifies.slice(up, up + 2).join("/"); } -export class ObservableDbAccess<Stores extends StoreMap> - implements DbAccess<Stores> -{ +export class ObservableDbAccess< + Stores extends StoreMap, +> implements DbAccess<Stores> { constructor( private impl: DbAccess<Stores>, private oc: ObservabilityContext, diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts @@ -418,9 +418,7 @@ export class RecoupTransactionContext implements TransactionContext { }); } - async updateTransactionMeta( - tx: WalletIndexedDbTransaction, - ): Promise<void> { + async updateTransactionMeta(tx: WalletIndexedDbTransaction): Promise<void> { const recoupRec = await tx.recoupGroups.get(this.recoupGroupId); if (!recoupRec) { await tx.transactionsMeta.delete(this.transactionId); diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -432,9 +432,7 @@ export class WithdrawTransactionContext implements TransactionContext { /** * Update the metadata of the transaction in the database. */ - async updateTransactionMeta( - tx: WalletIndexedDbTransaction, - ): Promise<void> { + async updateTransactionMeta(tx: WalletIndexedDbTransaction): Promise<void> { const ctx = this; const wgRecord = await tx.withdrawalGroups.get(ctx.withdrawalGroupId); if (!wgRecord) { @@ -503,9 +501,7 @@ export class WithdrawTransactionContext implements TransactionContext { }); } - async deleteTransactionInTx( - tx: WalletIndexedDbTransaction, - ): Promise<void> { + async deleteTransactionInTx(tx: WalletIndexedDbTransaction): Promise<void> { const [rec, h] = await this.getRecordHandle(tx); if (!rec) { return; diff --git a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx @@ -14,11 +14,14 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Amounts, ScopeInfo, ScopeType, WalletBalance } from "@gnu-taler/taler-util"; -import { Fragment, VNode, h } from "preact"; import { - TableWithRoundRows -} from "./styled/index.js"; + Amounts, + ScopeInfo, + ScopeType, + WalletBalance, +} from "@gnu-taler/taler-util"; +import { Fragment, VNode, h } from "preact"; +import { TableWithRoundRows } from "./styled/index.js"; export function BalanceTable({ balances, @@ -50,7 +53,7 @@ export function BalanceTable({ {Amounts.stringifyValue(av, 2)} <div style={{ fontSize: "small", color: "grey" }}> {entry.scopeInfo.type === ScopeType.Exchange || - entry.scopeInfo.type === ScopeType.Auditor + entry.scopeInfo.type === ScopeType.Auditor ? entry.scopeInfo.url : undefined} </div> diff --git a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx @@ -34,7 +34,11 @@ import { WithdrawalExchangeAccountDetails, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { QR_Bank, QR_SwissBank, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + QR_Bank, + QR_SwissBank, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { ComponentChildren, Fragment, h, VNode } from "preact"; import { useEffect, useRef, useState } from "preact/hooks"; import { useBackendContext } from "../context/backend.js"; @@ -262,7 +266,7 @@ function IBANAccountInfoTable({ return ( <Fragment> - <tr> + <tr> <td colSpan={3}> {!qrCodes.length ? undefined : ( <div style={{ overflowY: "auto", height: "95%", padding: 5 }}> @@ -301,7 +305,8 @@ function IBANAccountInfoTable({ </div> )} </td> - </tr> <table> + </tr>{" "} + <table> <tbody> <tr> <td colSpan={3}> diff --git a/packages/taler-wallet-webextension/src/components/Checkbox.tsx b/packages/taler-wallet-webextension/src/components/Checkbox.tsx @@ -31,7 +31,6 @@ export function Checkbox({ label, description, }: Props): VNode { - return ( <div> <input diff --git a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx @@ -47,14 +47,26 @@ export function ErrorMessage({ </button> )} </div> - {showErrorDetail && description && <p> - {description instanceof Error && !showMore ? description.message : description.toString()} - {description instanceof Error && <div> - <a href="#" onClick={(e) => { - setShowMore(!showMore) - e.preventDefault() - }}>{showMore ? i18n.str`show less` : i18n.str`show more`} </a> </div>} - </p>} + {showErrorDetail && description && ( + <p> + {description instanceof Error && !showMore + ? description.message + : description.toString()} + {description instanceof Error && ( + <div> + <a + href="#" + onClick={(e) => { + setShowMore(!showMore); + e.preventDefault(); + }} + > + {showMore ? i18n.str`show less` : i18n.str`show more`}{" "} + </a>{" "} + </div> + )} + </p> + )} </ErrorBox> ); } diff --git a/packages/taler-wallet-webextension/src/components/Modal.tsx b/packages/taler-wallet-webextension/src/components/Modal.tsx @@ -52,7 +52,16 @@ const Body = styled.div` export function Modal({ title, children, onClose }: Props): VNode { return ( - <div style={{ top: 0, left: 0, position: "fixed", width: "100%", height: "100%",zIndex:100 }}> + <div + style={{ + top: 0, + left: 0, + position: "fixed", + width: "100%", + height: "100%", + zIndex: 100, + }} + > <FullSize onClick={onClose?.onClick}> <div onClick={(e) => e.stopPropagation()} diff --git a/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx b/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx @@ -42,7 +42,7 @@ export function MultiActionButton<T>({ actions, onClick: doClick, }: Props<T>): VNode { - const defaultAction = actions.length > 0 ? actions[0] : "" as T; + const defaultAction = actions.length > 0 ? actions[0] : ("" as T); const [opened, setOpened] = useState(false); const [selected, setSelected] = useState<T>(defaultAction); diff --git a/packages/taler-wallet-webextension/src/components/Part.tsx b/packages/taler-wallet-webextension/src/components/Part.tsx @@ -24,11 +24,7 @@ import { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import arrowDown from "../svg/chevron-down.inline.svg"; -import { - ExtraLargeText, - LargeText, - SmallBoldText -} from "./styled/index.js"; +import { ExtraLargeText, LargeText, SmallBoldText } from "./styled/index.js"; export type Kind = "positive" | "negative" | "neutral"; interface Props { @@ -59,8 +55,8 @@ export function Part({ {!showSign || kind === "neutral" ? undefined : kind === "positive" - ? "+" - : "-"} + ? "+" + : "-"} {text} </Text> </div> diff --git a/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx @@ -22,7 +22,7 @@ import { TalerUris, TranslatedString, assertUnreachable, - parsePayUri + parsePayUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { QR_Taler, useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -35,7 +35,11 @@ import { Amount } from "./Amount.js"; import { Part } from "./Part.js"; import { LinkSuccess, WarningBox } from "./styled/index.js"; -export function PaymentButtons({ paymentState: state }: { paymentState: PaymentStates }): VNode { +export function PaymentButtons({ + paymentState: state, +}: { + paymentState: PaymentStates; +}): VNode { const { i18n } = useTranslationContext(); switch (state.status) { @@ -77,66 +81,69 @@ export function PaymentButtons({ paymentState: state }: { paymentState: PaymentS case "no-enough-balance": { let BalanceMessage = ""; - const { balanceDetails, amount } = state + const { balanceDetails, amount } = state; if (!balanceDetails) { - BalanceMessage = i18n.str`Balance is not enough.`; - } else switch (balanceDetails.causeHint) { - case InsufficientBalanceHint.MerchantAcceptInsufficient: { - BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue( - balanceDetails.balanceReceiverAcceptable, - )} ${amount.currency + BalanceMessage = i18n.str`Balance is not enough.`; + } else + switch (balanceDetails.causeHint) { + case InsufficientBalanceHint.MerchantAcceptInsufficient: { + BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue( + balanceDetails.balanceReceiverAcceptable, + )} ${ + amount.currency }. To know more you can check which exchange and auditors the merchant trust.`; - break; - } - case InsufficientBalanceHint.MerchantDepositInsufficient: { - BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue( - balanceDetails.balanceReceiverDepositable, - )} ${amount.currency + break; + } + case InsufficientBalanceHint.MerchantDepositInsufficient: { + BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue( + balanceDetails.balanceReceiverDepositable, + )} ${ + amount.currency }. To know more you can check which wire methods the merchant accepts.`; - break; - } - case InsufficientBalanceHint.AgeRestricted: { - BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( - balanceDetails.balanceAgeAcceptable, - )} ${amount.currency} to pay for this contract which is restricted.`; - break; - } - case InsufficientBalanceHint.WalletBalanceMaterialInsufficient: { - BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( - balanceDetails.balanceMaterial, - )} ${amount.currency + break; + } + case InsufficientBalanceHint.AgeRestricted: { + BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( + balanceDetails.balanceAgeAcceptable, + )} ${amount.currency} to pay for this contract which is restricted.`; + break; + } + case InsufficientBalanceHint.WalletBalanceMaterialInsufficient: { + BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( + balanceDetails.balanceMaterial, + )} ${ + amount.currency } to spend right know. There are some coins that need to be refreshed.`; - break; - } - case InsufficientBalanceHint.WalletBalanceAvailableInsufficient: { - BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( - balanceDetails.balanceAvailable, - )} ${amount.currency} available.`; - break; - } - case InsufficientBalanceHint.ExchangeMissingGlobalFees: { - BalanceMessage = i18n.str`Provider is missing the global fee configuration, this likely means it is misconfigured.`; - break; - } - case InsufficientBalanceHint.FeesNotCovered: { - BalanceMessage = i18n.str`Balance looks like it should be enough, but doesn't cover all fees requested by the merchant and payment processor. Please ensure there is at least ${Amounts.stringifyValue( - Amounts.stringify( - Amounts.sub( - amount, - balanceDetails.maxEffectiveSpendAmount, - ).amount, - ), - )} ${amount.currency + break; + } + case InsufficientBalanceHint.WalletBalanceAvailableInsufficient: { + BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( + balanceDetails.balanceAvailable, + )} ${amount.currency} available.`; + break; + } + case InsufficientBalanceHint.ExchangeMissingGlobalFees: { + BalanceMessage = i18n.str`Provider is missing the global fee configuration, this likely means it is misconfigured.`; + break; + } + case InsufficientBalanceHint.FeesNotCovered: { + BalanceMessage = i18n.str`Balance looks like it should be enough, but doesn't cover all fees requested by the merchant and payment processor. Please ensure there is at least ${Amounts.stringifyValue( + Amounts.stringify( + Amounts.sub(amount, balanceDetails.maxEffectiveSpendAmount) + .amount, + ), + )} ${ + amount.currency } more balance in your wallet or ask your merchant to cover more of the fees.`; - break; - } - case undefined: { - BalanceMessage = i18n.str`Balance is not enough.`; - break; + break; + } + case undefined: { + BalanceMessage = i18n.str`Balance is not enough.`; + break; + } + default: + assertUnreachable(balanceDetails.causeHint); } - default: - assertUnreachable(balanceDetails.causeHint); - } return ( <Fragment> @@ -147,7 +154,9 @@ export function PaymentButtons({ paymentState: state }: { paymentState: PaymentS <Button variant="contained" color="success" - onClick={() => state.goToWalletManualWithdraw(Amounts.stringify(amount))} + onClick={() => + state.goToWalletManualWithdraw(Amounts.stringify(amount)) + } > <i18n.Translate>Get digital cash</i18n.Translate> </Button> @@ -166,7 +175,7 @@ function PayWithMobile({ uri }: { uri: string }): VNode { const { i18n } = useTranslationContext(); const api = useBackendContext(); - const payUri = Result.orUndefined( TalerUris.fromString(uri)); + const payUri = Result.orUndefined(TalerUris.fromString(uri)); const [showQR, setShowQR] = useState<string | undefined>(undefined); async function sharePrivatePaymentURI() { diff --git a/packages/taler-wallet-webextension/src/components/ShowBanksForPaytoPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowBanksForPaytoPopup.tsx @@ -13,9 +13,7 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - BankingChoiceSpec -} from "@gnu-taler/taler-util"; +import { BankingChoiceSpec } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; @@ -37,7 +35,10 @@ const BanksTable = styled.table` } `; -interface Props { banks: BankingChoiceSpec[], onClose: ButtonHandler }; +interface Props { + banks: BankingChoiceSpec[]; + onClose: ButtonHandler; +} export function ShowBanksForPaytoPopup({ banks, onClose }: Props): VNode { const { i18n } = useTranslationContext(); @@ -47,12 +48,13 @@ export function ShowBanksForPaytoPopup({ banks, onClose }: Props): VNode { <div style={{ overflowY: "auto", height: "95%", padding: 5 }}> <BanksTable> {banks.map((b, idx) => { - - return <tr key={idx}> - <td> - <a href={b.uri}>{b.label}</a> - </td> - </tr> + return ( + <tr key={idx}> + <td> + <a href={b.uri}>{b.label}</a> + </td> + </tr> + ); })} </BanksTable> </div> diff --git a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx @@ -210,7 +210,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode { </td> <td>{contractTerms.summary}</td> </tr> - {"amount" in contractTerms ? + {"amount" in contractTerms ? ( <tr> <td> <i18n.Translate>Amount</i18n.Translate> @@ -219,16 +219,19 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode { <Amount value={contractTerms.amount} /> </td> </tr> - : undefined} - {"choices" in contractTerms ? + ) : undefined} + {"choices" in contractTerms ? ( <tr> <td> <i18n.Translate>Choices</i18n.Translate> </td> <td> - <i18n.Translate>This purchase have {contractTerms.choices.length} choices</i18n.Translate> + <i18n.Translate> + This purchase have {contractTerms.choices.length} choices + </i18n.Translate> </td> - </tr> : undefined} + </tr> + ) : undefined} <tr> <td> <i18n.Translate>Merchant name</i18n.Translate> @@ -324,8 +327,8 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode { !contractTerms.auto_refund ? Duration.getZero() : Duration.fromTalerProtocolDuration( - contractTerms.auto_refund, - ), + contractTerms.auto_refund, + ), )} format="dd MMMM yyyy, HH:mm" /> @@ -363,7 +366,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode { <td>Public reorder URL</td> <td>{contractTerms.public_reorder_url}</td> </tr> */} - {"max_fee" in contractTerms ? + {"max_fee" in contractTerms ? ( <tr> <td> <i18n.Translate>Max deposit fee</i18n.Translate> @@ -372,7 +375,7 @@ export function ShowView({ contractTerms, hideHandler }: States.Show): VNode { <Amount value={contractTerms.max_fee} /> </td> </tr> - : undefined} + ) : undefined} {/* <tr> <td>Extra</td> <td> diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx b/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx @@ -34,7 +34,7 @@ export const Ready = tests.createExample(ShowTosContentView, { en: "en", }, value: "es", - onChange: (() => { }) as any + onChange: (() => {}) as any, }, tosFormat: { list: { @@ -42,18 +42,18 @@ export const Ready = tests.createExample(ShowTosContentView, { en: "en", }, value: "es", - onChange: (() => { }) as any + onChange: (() => {}) as any, }, terms: { content: { type: "plain", - content: "hola" + content: "hola", }, status: ExchangeTosStatus.Accepted, - version: "1" + version: "1", }, status: "show-content", termsAccepted: { button: {}, - } + }, }); diff --git a/packages/taler-wallet-webextension/src/components/Time.tsx b/packages/taler-wallet-webextension/src/components/Time.tsx @@ -19,9 +19,9 @@ import { formatISO, format } from "date-fns"; import { h, VNode } from "preact"; /** - * + * * @deprecated use web-util - * @returns + * @returns */ export function Time({ timestamp, diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts @@ -14,7 +14,12 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AmountJson, AmountString, PaytoUri, ScopeInfo } from "@gnu-taler/taler-util"; +import { + AmountJson, + AmountString, + PaytoUri, + ScopeInfo, +} from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts @@ -31,7 +31,7 @@ export function useComponentState({ }: Props): State { const api = useBackendContext(); const { pushAlertOnError } = useAlertContext(); - const [amount, setAmount] = useState(Amounts.zeroOfCurrency(scope.currency)) + const [amount, setAmount] = useState(Amounts.zeroOfCurrency(scope.currency)); const amountStr = Amounts.stringify(amount); const hook = useAsyncAsHook(async () => { @@ -55,8 +55,14 @@ export function useComponentState({ // }; // } - const debitAmount = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.effectiveDepositAmount); - const toBeReceived = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.totalDepositCost); + const debitAmount = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.effectiveDepositAmount); + const toBeReceived = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.totalDepositCost); // const { deposit, uri, amount } = hook.response; async function doDeposit(): Promise<void> { const resp = await api.wallet.call(WalletApiOperation.CreateDepositGroup, { @@ -76,11 +82,11 @@ export function useComponentState({ error: Amounts.isZero(amount) ? "Can't be zero" : undefined, }, confirm: { - onClick: Amounts.isZero(toBeReceived) ? undefined : pushAlertOnError(doDeposit), - + onClick: Amounts.isZero(toBeReceived) + ? undefined + : pushAlertOnError(doDeposit), }, - fee: Amounts.sub(toBeReceived, debitAmount) - .amount, + fee: Amounts.sub(toBeReceived, debitAmount).amount, cost: Amounts.parseOrThrow(toBeReceived), effective: Amounts.parseOrThrow(debitAmount), cancel, diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/stories.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/stories.tsx @@ -31,7 +31,7 @@ export const Ready = tests.createExample(ReadyView, { status: "ready", confirm: {}, amount: { - value: Amounts.parseOrThrow("EUR:1") + value: Amounts.parseOrThrow("EUR:1"), }, account: parsePaytoUri("payto://iban/DE1231231231")!, cost: Amounts.parseOrThrow("EUR:1.2"), diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts @@ -19,7 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AmountString, Amounts, ScopeType, parsePayUri, parsePaytoUri } from "@gnu-taler/taler-util"; +import { + AmountString, + Amounts, + ScopeType, + parsePayUri, + parsePaytoUri, +} from "@gnu-taler/taler-util"; import { expect } from "chai"; import { createWalletApiMock } from "../../test-utils.js"; import { useComponentState } from "./state.js"; @@ -28,23 +34,18 @@ import { Props } from "./index.js"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; describe("Deposit CTA states", () => { - it("should be ready after loading", async () => { const { handler, TestingContext } = createWalletApiMock(); - handler.addWalletCallResponse( - WalletApiOperation.CheckDeposit, - undefined, - { - effectiveDepositAmount: "EUR:0" as AmountString, - totalDepositCost: "EUR:0" as AmountString, - fees: { - coin: "EUR:0" as AmountString, - refresh: "EUR:0" as AmountString, - wire: "EUR:0" as AmountString, - }, + handler.addWalletCallResponse(WalletApiOperation.CheckDeposit, undefined, { + effectiveDepositAmount: "EUR:0" as AmountString, + totalDepositCost: "EUR:0" as AmountString, + fees: { + coin: "EUR:0" as AmountString, + refresh: "EUR:0" as AmountString, + wire: "EUR:0" as AmountString, }, - ); + }); const props = { account: parsePaytoUri("payto://refund/asdasdas")!, diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx @@ -50,7 +50,6 @@ export function ReadyView(state: State.Ready): VNode { /> } /> - </section> <section> <Button diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/index.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/index.ts @@ -20,7 +20,11 @@ import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { StateViewMap, compose } from "../../utils/index.js"; import { useComponentState } from "./state.js"; -import { InsertLostView, InsertPendingRefreshView, UnknownView } from "./views.js"; +import { + InsertLostView, + InsertPendingRefreshView, + UnknownView, +} from "./views.js"; export interface Props { talerExperimentUri: string | undefined; @@ -28,7 +32,12 @@ export interface Props { onSuccess: () => Promise<void>; } -export type State = State.Loading | State.LoadingUriError | State.Unknown | State.InsertLost | State.PendingRefresh; +export type State = + | State.Loading + | State.LoadingUriError + | State.Unknown + | State.InsertLost + | State.PendingRefresh; export namespace State { export interface Loading { diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/state.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/state.ts @@ -33,15 +33,18 @@ export function useComponentState({ async function doApply(): Promise<void> { if (!talerExperimentUri) return; await api.wallet.call(WalletApiOperation.ApplyDevExperiment, { - devExperimentUri: talerExperimentUri - }) + devExperimentUri: talerExperimentUri, + }); // const resp = await api.wallet.call(WalletApiOperation.CreateDepositGroup, { // amount: Amounts.stringify(amount), // depositPaytoUri: uri, // }); onSuccess(); } - const uri = talerExperimentUri === undefined ? undefined : parseDevExperimentUri(talerExperimentUri); + const uri = + talerExperimentUri === undefined + ? undefined + : parseDevExperimentUri(talerExperimentUri); if (!uri) { return { @@ -79,5 +82,5 @@ export function useComponentState({ status: "unknown", error: undefined, experimentId: uri.devExperimentId, - } + }; } diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/test.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/test.ts @@ -61,5 +61,4 @@ describe("DevExperiment CTA states", () => { expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); - }); diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/views.tsx b/packages/taler-wallet-webextension/src/cta/DevExperiment/views.tsx @@ -29,46 +29,47 @@ import { State } from "./index.js"; export function InsertLostView(state: State.InsertLost): VNode { const { i18n } = useTranslationContext(); - return <Fragment> - <section> - <Part - title={i18n.str`Experiment`} - text={i18n.str`Insert lost denomination`} - /> - </section> - <section> - <Button - variant="contained" - color="success" - onClick={state.confirm.onClick} - > - <i18n.Translate>Apply</i18n.Translate> - </Button> - </section> - </Fragment> + return ( + <Fragment> + <section> + <Part + title={i18n.str`Experiment`} + text={i18n.str`Insert lost denomination`} + /> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={state.confirm.onClick} + > + <i18n.Translate>Apply</i18n.Translate> + </Button> + </section> + </Fragment> + ); } export function InsertPendingRefreshView(state: State.PendingRefresh): VNode { const { i18n } = useTranslationContext(); - return <Fragment> - <section> - <Part - title={i18n.str`Experiment`} - text={i18n.str`Pending refresh`} - /> - </section> - <section> - <Button - variant="contained" - color="success" - onClick={state.confirm.onClick} - > - <i18n.Translate>Apply</i18n.Translate> - </Button> - </section> - </Fragment> + return ( + <Fragment> + <section> + <Part title={i18n.str`Experiment`} text={i18n.str`Pending refresh`} /> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={state.confirm.onClick} + > + <i18n.Translate>Apply</i18n.Translate> + </Button> + </section> + </Fragment> + ); } export function UnknownView(state: State.Unknown): VNode { - return <div>unknown experiment "{state.experimentId}"</div> + return <div>unknown experiment "{state.experimentId}"</div>; } diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts @@ -19,7 +19,11 @@ import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; -import { AmountFieldHandler, ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; +import { + AmountFieldHandler, + ButtonHandler, + TextFieldHandler, +} from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js"; diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts @@ -15,7 +15,12 @@ */ /* eslint-disable react-hooks/rules-of-hooks */ -import { AmountJson, Amounts, AmountString, TalerProtocolTimestamp } from "@gnu-taler/taler-util"; +import { + AmountJson, + Amounts, + AmountString, + TalerProtocolTimestamp, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { isFuture, parse } from "date-fns"; import { useState } from "preact/hooks"; @@ -37,7 +42,7 @@ export function useComponentState({ const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListExchanges, { - filterByScope: scope + filterByScope: scope, }), ); const { i18n } = useTranslationContext(); @@ -73,12 +78,14 @@ export function useComponentState({ const exchangeList = hook.response.exchanges; return () => { - const [amount, setAmount] = useState<AmountJson>(Amounts.zeroOfCurrency(scope.currency)); + const [amount, setAmount] = useState<AmountJson>( + Amounts.zeroOfCurrency(scope.currency), + ); const [subject, setSubject] = useState<string | undefined>(); const [timestamp, setTimestamp] = useState<string | undefined>(); const { pushAlertOnError } = useAlertContext(); - const amountStr = Amounts.stringify(amount) + const amountStr = Amounts.stringify(amount); const selectedExchange = useSelectedExchange({ scope, defaultExchange: undefined, @@ -100,7 +107,7 @@ export function useComponentState({ }, ); return resp; - },[amountStr]); + }, [amountStr]); // if (!hook) { // return { @@ -132,9 +139,15 @@ export function useComponentState({ // const { amountEffective, amountRaw } = hook.response; // const requestAmount = Amounts.parseOrThrow(amountRaw); // const toBeReceived = Amounts.parseOrThrow(amountEffective); - const requestAmount = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountRaw); - const toBeReceived = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountEffective); - + const requestAmount = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.amountRaw); + const toBeReceived = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.amountEffective); + let purse_expiration: TalerProtocolTimestamp | undefined = undefined; let timestampError: string | undefined = undefined; diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx @@ -37,8 +37,8 @@ export const Ready = tests.createExample(ReadyView, { value: { currency: "ARS", value: 1, - fraction: 0, - } + fraction: 0, + }, }, expiration: { value: "2/12/12", diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx @@ -89,11 +89,7 @@ export function ReadyView({ big /> <p> - <AmountField - label={i18n.str`Amount`} - handler={amount} - required - /> + <AmountField label={i18n.str`Amount`} handler={amount} required /> </p> <p> <TextField @@ -153,7 +149,7 @@ export function ReadyView({ /> </section> <section> - <TermsOfService key="terms" exchangeUrl={exchangeUrl} > + <TermsOfService key="terms" exchangeUrl={exchangeUrl}> <Button onClick={create.onClick} variant="contained" color="success"> <i18n.Translate>Create</i18n.Translate> </Button> diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts @@ -30,10 +30,7 @@ export interface Props { onSuccess: (tx: string) => Promise<void>; } -export type State = - | State.Loading - | State.LoadingUriError - | PaymentStates; +export type State = State.Loading | State.LoadingUriError | PaymentStates; export namespace State { export interface Loading { @@ -46,14 +43,13 @@ export namespace State { retry: ButtonHandler; error: ErrorAlert; } - } const viewMapping: StateViewMap<State> = { loading: Loading, error: ErrorAlertView, - "confirmed": ReadyView, + confirmed: ReadyView, "no-enough-balance": ReadyView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -86,8 +86,9 @@ export function useComponentState({ // const raw = Amounts.parseOrThrow(amountRaw); // const summary: string | undefined = contractTerms.summary; - const expiration: AbsoluteTime = - contractTerms.purse_expiration ? AbsoluteTime.fromProtocolTimestamp(contractTerms.purse_expiration) : AbsoluteTime.never(); + const expiration: AbsoluteTime = contractTerms.purse_expiration + ? AbsoluteTime.fromProtocolTimestamp(contractTerms.purse_expiration) + : AbsoluteTime.never(); const foundBalance = hook.response.balance.balances.find( (b) => Amounts.parseOrThrow(b.available).currency === amount.currency, diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx @@ -31,9 +31,7 @@ const inFiveMinutes = AbsoluteTime.addDuration( Duration.fromSpec({ minutes: 5 }), ); -export function ReadyView( - state: PaymentStates, -): VNode { +export function ReadyView(state: PaymentStates): VNode { const { i18n } = useTranslationContext(); const { summary, effective, amount, expiration } = state; @@ -44,7 +42,7 @@ export function ReadyView( <Fragment> <section style={{ textAlign: "left" }}> <Part title={i18n.str`Subject`} text={<div>{summary}</div>} /> - {!effective ? undefined : + {!effective ? undefined : ( <Part title={i18n.str`Details`} text={ @@ -53,7 +51,7 @@ export function ReadyView( /> } /> - } + )} {willExpireSoon && ( <Part title={i18n.str`Expires at`} @@ -64,7 +62,6 @@ export function ReadyView( </section> <PaymentButtons paymentState={state} /> - </Fragment> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts @@ -20,7 +20,7 @@ import { MerchantContractChoice, MerchantInfo, PaymentInsufficientBalanceDetails, - TransactionIdStr + TransactionIdStr, } from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; @@ -37,13 +37,9 @@ export interface Props { onSuccess: (tx: string) => Promise<void>; } -export type State = - | State.Loading - | State.LoadingUriError - | PaymentStates; +export type State = State.Loading | State.LoadingUriError | PaymentStates; export namespace State { - export interface Loading { status: "loading"; error: undefined; @@ -57,7 +53,7 @@ export namespace State { interface BaseInfo { amount: AmountJson; summary: string; - minimum_age: number | undefined, + minimum_age: number | undefined; expiration: AbsoluteTime; merchant: MerchantInfo | undefined; transactionId: TransactionIdStr; @@ -71,22 +67,26 @@ export namespace State { status: "no-enough-balance"; balanceDetails: PaymentInsufficientBalanceDetails | undefined; effective: undefined; - choices: undefined | { - list: MerchantContractChoice[] - index: number; - select: (d: number) => void; - }, + choices: + | undefined + | { + list: MerchantContractChoice[]; + index: number; + select: (d: number) => void; + }; } export interface Ready extends BaseInfo { status: "ready"; payHandler: ButtonHandler; effective: AmountJson; - choices: undefined | { - list: MerchantContractChoice[] - index: number; - select: (d: number) => void; - }, + choices: + | undefined + | { + list: MerchantContractChoice[]; + index: number; + select: (d: number) => void; + }; } export interface Confirmed extends BaseInfo { @@ -95,7 +95,6 @@ export namespace State { message?: string; paid: boolean; } - } const viewMapping: StateViewMap<State> = { diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -22,7 +22,7 @@ import { ConfirmPayResultType, GetChoicesForPaymentResult, NotificationType, - PreparePayResultType + PreparePayResultType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -42,7 +42,7 @@ export function useComponentState({ const { pushAlertOnError } = useAlertContext(); const api = useBackendContext(); const { i18n } = useTranslationContext(); - const [selectedChoice, onSelectChoice] = useState<number>(0) + const [selectedChoice, onSelectChoice] = useState<number>(0); const hook = useAsyncAsHook(async () => { if (!talerPayUri) throw Error("ERROR_NO-URI-FOR-PAYMENT"); @@ -55,11 +55,12 @@ export function useComponentState({ let choicesForPayment: GetChoicesForPaymentResult | undefined; if (payStatus.status === PreparePayResultType.ChoiceSelection) { - - choicesForPayment = await api.wallet.call(WalletApiOperation.GetChoicesForPayment, { - transactionId: payStatus.transactionId - }); - + choicesForPayment = await api.wallet.call( + WalletApiOperation.GetChoicesForPayment, + { + transactionId: payStatus.transactionId, + }, + ); } return { payStatus, uri: talerPayUri, choicesForPayment }; }, []); @@ -109,7 +110,7 @@ export function useComponentState({ async function doPayment(): Promise<void> { const res = await api.wallet.call(WalletApiOperation.ConfirmPay, { transactionId: payStatus.transactionId, - choiceIndex: selectedChoice + choiceIndex: selectedChoice, }); // handle confirm pay if (res.type !== ConfirmPayResultType.Done) { @@ -129,13 +130,14 @@ export function useComponentState({ onClick: pushAlertOnError(doPayment), }; - const expiration: AbsoluteTime = - AbsoluteTime.fromProtocolTimestamp(payStatus.contractTerms.pay_deadline); + const expiration: AbsoluteTime = AbsoluteTime.fromProtocolTimestamp( + payStatus.contractTerms.pay_deadline, + ); const baseResult = { shareUri: hook.response.uri, transactionId: payStatus.transactionId, - receiver: payStatus.contractTerms.merchant, + receiver: payStatus.contractTerms.merchant, summary: payStatus.contractTerms.summary, merchant: payStatus.contractTerms.merchant, error: undefined, @@ -150,15 +152,20 @@ export function useComponentState({ const { choices: choicesDetails } = choicesForPayment!; const selectedChoiceData = choicesDetails[selectedChoice]; const amount = Amounts.parseOrThrow(selectedChoiceData.amountRaw); - + const choices = { - list: payStatus.contractTerms.version === 1 ? payStatus.contractTerms.choices : [], - index: selectedChoice, - select: onSelectChoice, - } + list: + payStatus.contractTerms.version === 1 + ? payStatus.contractTerms.choices + : [], + index: selectedChoice, + select: onSelectChoice, + }; switch (selectedChoiceData.status) { case ChoiceSelectionDetailType.PaymentPossible: { - const effective = Amounts.parseOrThrow(selectedChoiceData.amountEffective) + const effective = Amounts.parseOrThrow( + selectedChoiceData.amountEffective, + ); return { status: "ready", payHandler, @@ -179,10 +186,9 @@ export function useComponentState({ }; } default: { - assertUnreachable(selectedChoiceData) + assertUnreachable(selectedChoiceData); } } - } const amount = Amounts.parseOrThrow(payStatus.amountRaw); @@ -193,7 +199,6 @@ export function useComponentState({ : Amounts.zeroOfCurrency(amount.currency) : amount; - if (payStatus.status === PreparePayResultType.InsufficientBalance) { return { status: "no-enough-balance", @@ -211,7 +216,10 @@ export function useComponentState({ amount, effective: undefined, paid: payStatus.paid, - message: payStatus.paid && payStatus.contractTerms.fulfillment_message ? payStatus.contractTerms.fulfillment_message : undefined, + message: + payStatus.paid && payStatus.contractTerms.fulfillment_message + ? payStatus.contractTerms.fulfillment_message + : undefined, ...baseResult, }; } diff --git a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx @@ -19,10 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { - AbsoluteTime, - Amounts -} from "@gnu-taler/taler-util"; +import { AbsoluteTime, Amounts } from "@gnu-taler/taler-util"; import * as tests from "@gnu-taler/web-util/testing"; import { nullFunction } from "../../mui/handlers.js"; import { BaseView } from "./views.js"; diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -28,7 +28,7 @@ import { NotificationType, PreparePayResultInsufficientBalance, PreparePayResultPaymentPossible, - PreparePayResultType + PreparePayResultType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import * as tests from "@gnu-taler/web-util/testing"; @@ -267,7 +267,6 @@ describe("Payment CTA states", () => { } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, { type: ConfirmPayResultType.Done, contractTerms: {}, @@ -320,7 +319,6 @@ describe("Payment CTA states", () => { } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, { type: ConfirmPayResultType.Pending, lastError: { code: 1 }, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx @@ -18,7 +18,7 @@ import { AbsoluteTime, Amounts, Duration, - TranslatedString + TranslatedString, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; @@ -49,8 +49,8 @@ const inFiveMinutes = AbsoluteTime.addDuration( export function BaseView(state: PaymentStates): VNode { const { i18n } = useTranslationContext(); - - const willExpireSoon = AbsoluteTime.cmp(state.expiration, inFiveMinutes) === -1; + const willExpireSoon = + AbsoluteTime.cmp(state.expiration, inFiveMinutes) === -1; // const choices = state.contractTerms.version && state.contractTerms.version === 1 ? state.contractTerms.choices : []; @@ -79,13 +79,13 @@ export function BaseView(state: PaymentStates): VNode { text={state.summary as TranslatedString} kind="neutral" /> - {!state.merchant ? undefined : + {!state.merchant ? undefined : ( <Part title={i18n.str`Merchant`} text={<MerchantDetails merchant={state.merchant} />} kind="neutral" /> - } + )} {willExpireSoon && ( <Part title={i18n.str`Expires at`} @@ -93,7 +93,8 @@ export function BaseView(state: PaymentStates): VNode { kind="neutral" /> )} - {state.status === "confirmed" || state.choices === undefined ? undefined : + {state.status === "confirmed" || + state.choices === undefined ? undefined : ( <TableWithRoundRows> {state.choices.list.map((entry, idx) => { const selected = state.choices!.index === idx; @@ -105,7 +106,9 @@ export function BaseView(state: PaymentStates): VNode { onClick={() => state.choices!.select(idx)} style={{ cursor: !selected ? "pointer" : "default" }} > - <td style={{ borderWidth: selected ? 4 : 1 }}>{av.currency}</td> + <td style={{ borderWidth: selected ? 4 : 1 }}> + {av.currency} + </td> <td style={{ fontSize: "2em", @@ -115,23 +118,24 @@ export function BaseView(state: PaymentStates): VNode { > {Amounts.stringifyValue(av, 2)} </td> - <td style={{ - borderWidth: selected ? 4 : 1, - width: "100%", - textAlign: "right", - }}>{entry.description}</td> - + <td + style={{ + borderWidth: selected ? 4 : 1, + width: "100%", + textAlign: "right", + }} + > + {entry.description} + </td> </tr> ); })} </TableWithRoundRows> - } + )} </section> <EnabledBySettings name="advancedMode"> <section style={{ textAlign: "left" }}> - <ShowFullContractTermPopup - transactionId={state.transactionId} - /> + <ShowFullContractTermPopup transactionId={state.transactionId} /> </section> </EnabledBySettings> @@ -149,9 +153,7 @@ function ShowImportantMessage({ state }: { state: PaymentStates }): VNode { <SuccessBox> <i18n.Translate> Already paid, you are going to be redirected to{" "} - <a href={state.message}> - {state.message} - </a> + <a href={state.message}>{state.message}</a> </i18n.Translate> </SuccessBox> ); diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx @@ -35,9 +35,7 @@ export function ReadyView({ <section style={{ textAlign: "left" }}> {!amount ? undefined : ( <p> - <AmountField label={i18n.str`Amount`} - handler={amount} - /> + <AmountField label={i18n.str`Amount`} handler={amount} /> </p> )} {!summary ? undefined : ( diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts @@ -17,7 +17,7 @@ import { Amounts, NotificationType, - TransactionType + TransactionType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; diff --git a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx @@ -112,10 +112,8 @@ export function ReadyView(state: State.Ready): VNode { color="success" onClick={state.accept.onClick} > - {/* Accept <Amount value={state.awaitingAmount} /> */} - <i18n.Translate> - Accept - </i18n.Translate> + {/* Accept <Amount value={state.awaitingAmount} /> */} + <i18n.Translate>Accept</i18n.Translate> </Button> </section> </Fragment> diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts @@ -23,7 +23,11 @@ import { import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; -import { AmountFieldHandler, ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; +import { + AmountFieldHandler, + ButtonHandler, + TextFieldHandler, +} from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; import { ReadyView } from "./views.js"; diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts @@ -17,7 +17,7 @@ import { AmountJson, Amounts, - TalerProtocolTimestamp + TalerProtocolTimestamp, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -28,20 +28,18 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState({ - scope, - onClose, - onSuccess, -}: Props): State { +export function useComponentState({ scope, onClose, onSuccess }: Props): State { const api = useBackendContext(); const { pushAlertOnError } = useAlertContext(); // const amount = Amounts.parseOrThrow(amountStr); const { i18n } = useTranslationContext(); - const [amount, setAmount] = useState<AmountJson>(Amounts.zeroOfCurrency(scope.currency)); + const [amount, setAmount] = useState<AmountJson>( + Amounts.zeroOfCurrency(scope.currency), + ); const [subject, setSubject] = useState<string | undefined>(); const [timestamp, setTimestamp] = useState<string | undefined>(); - const amountStr = Amounts.stringify(amount) + const amountStr = Amounts.stringify(amount); const hook = useAsyncAsHook(async () => { return await api.wallet.call(WalletApiOperation.CheckPeerPushDebit, { @@ -50,8 +48,14 @@ export function useComponentState({ }); }, [amountStr]); - const debitAmount = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountEffective); - const toBeReceived = !hook || hook.hasError ? Amounts.zeroOfCurrency(scope.currency) : Amounts.parseOrThrow(hook.response.amountRaw); + const debitAmount = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.amountEffective); + const toBeReceived = + !hook || hook.hasError + ? Amounts.zeroOfCurrency(scope.currency) + : Amounts.parseOrThrow(hook.response.amountRaw); let purse_expiration: TalerProtocolTimestamp | undefined = undefined; let timestampError: string | undefined = undefined; @@ -92,7 +96,10 @@ export function useComponentState({ } const unableToCreate = - !subject || Amounts.isZero(amount) || Amounts.isZero(debitAmount) || !purse_expiration; + !subject || + Amounts.isZero(amount) || + Amounts.isZero(debitAmount) || + !purse_expiration; return { status: "ready", @@ -129,4 +136,3 @@ export function useComponentState({ error: undefined, }; } - diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx @@ -37,8 +37,8 @@ export const Ready = tests.createExample(ReadyView, { value: { currency: "ARS", value: 1, - fraction: 0, - } + fraction: 0, + }, }, expiration: { value: "20/1/2022", diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx @@ -63,11 +63,7 @@ export function ReadyView({ <Fragment> <section style={{ textAlign: "left" }}> <p> - <AmountField - label={i18n.str`Amount`} - handler={amount} - required - /> + <AmountField label={i18n.str`Amount`} handler={amount} required /> </p> <p> <TextField diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -18,7 +18,7 @@ import { AmountJson, CurrencySpecification, ExchangeListItem, - ScopeInfo + ScopeInfo, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -246,7 +246,11 @@ export function SuccessView(state: State.Success): VNode { </TermsOfService> </section> {state.talerWithdrawUri ? ( - <WithdrawWithMobile talerWithdrawUri={Result.unpack(TalerUris.fromString(state.talerWithdrawUri))} /> + <WithdrawWithMobile + talerWithdrawUri={Result.unpack( + TalerUris.fromString(state.talerWithdrawUri), + )} + /> ) : undefined} </Fragment> ); @@ -279,4 +283,3 @@ function WithdrawWithMobile({ </section> ); } - diff --git a/packages/taler-wallet-webextension/src/hooks/useSelectedContact.ts b/packages/taler-wallet-webextension/src/hooks/useSelectedContact.ts @@ -14,10 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - ContactEntry, - ScopeInfo -} from "@gnu-taler/taler-util"; +import { ContactEntry, ScopeInfo } from "@gnu-taler/taler-util"; import { useState } from "preact/hooks"; import { useAlertContext } from "../context/alert.js"; import { ButtonHandler } from "../mui/handlers.js"; @@ -50,9 +47,7 @@ interface Props { list: ContactEntry[]; } -export function useSelectedContact({ - list, -}: Props): State { +export function useSelectedContact({ list }: Props): State { const [isSelecting, setIsSelecting] = useState(false); const [selectedContact, setSelectedContact] = useState<string | undefined>( undefined, @@ -67,9 +62,7 @@ export function useSelectedContact({ } if (isSelecting) { - const currentContact = - selectedContact ?? - list[0].alias; + const currentContact = selectedContact ?? list[0].alias; return { status: "selecting-contact", error: undefined, @@ -99,7 +92,7 @@ export function useSelectedContact({ }; } { - const found = false + const found = false; if (found) return { status: "ready", diff --git a/packages/taler-wallet-webextension/src/hooks/useSelectedExchange.ts b/packages/taler-wallet-webextension/src/hooks/useSelectedExchange.ts @@ -14,10 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - ExchangeListItem, - ScopeInfo -} from "@gnu-taler/taler-util"; +import { ExchangeListItem, ScopeInfo } from "@gnu-taler/taler-util"; import { useState } from "preact/hooks"; import { useAlertContext } from "../context/alert.js"; import { ButtonHandler } from "../mui/handlers.js"; @@ -78,9 +75,7 @@ export function useSelectedExchange({ if (isSelecting) { const currentExchange = - selectedExchange ?? - defaultExchange ?? - list[0].exchangeBaseUrl; + selectedExchange ?? defaultExchange ?? list[0].exchangeBaseUrl; return { status: "selecting-exchange", error: undefined, diff --git a/packages/taler-wallet-webextension/src/mui/Avatar.tsx b/packages/taler-wallet-webextension/src/mui/Avatar.tsx @@ -59,8 +59,8 @@ export function Avatar({ variant, children, ...rest }: Props): VNode { variant === "square" ? theme.shape.squareBorder : variant === "rounded" - ? theme.shape.roundBorder - : theme.shape.circularBorder; + ? theme.shape.roundBorder + : theme.shape.circularBorder; return ( <div class={[root, borderStyle].join(" ")} {...rest}> {children} diff --git a/packages/taler-wallet-webextension/src/mui/Button.tsx b/packages/taler-wallet-webextension/src/mui/Button.tsx @@ -371,11 +371,15 @@ function ButtonBase({ ); } return ( - <button onClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - doClick(); - }} class={classNames} {...rest}> + <button + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + doClick(); + }} + class={classNames} + {...rest} + > {children} </button> ); diff --git a/packages/taler-wallet-webextension/src/mui/Grid.tsx b/packages/taler-wallet-webextension/src/mui/Grid.tsx @@ -290,32 +290,32 @@ export function Grid({ (xs === "auto" ? sizeVariantAuto : xs === "true" - ? sizeVariantExpand - : sizeVariantXS), + ? sizeVariantExpand + : sizeVariantXS), sm && (sm === "auto" ? sizeVariantAuto : sm === "true" - ? sizeVariantExpand - : sizeVariantSM), + ? sizeVariantExpand + : sizeVariantSM), md && (md === "auto" ? sizeVariantAuto : md === "true" - ? sizeVariantExpand - : sizeVariantMD), + ? sizeVariantExpand + : sizeVariantMD), lg && (lg === "auto" ? sizeVariantAuto : lg === "true" - ? sizeVariantExpand - : sizeVariantLG), + ? sizeVariantExpand + : sizeVariantLG), xl && (xl === "auto" ? sizeVariantAuto : xl === "true" - ? sizeVariantExpand - : sizeVariantXL), + ? sizeVariantExpand + : sizeVariantXL), container && columnGapVariant, container && rowGapVariant, ].join(" ")} diff --git a/packages/taler-wallet-webextension/src/mui/Typography.tsx b/packages/taler-wallet-webextension/src/mui/Typography.tsx @@ -96,8 +96,8 @@ export function Typography({ const Component = inline ? "span" : paragraph === true - ? "p" - : defaultVariantMapping[variant as "h1"] || "span"; + ? "p" + : defaultVariantMapping[variant as "h1"] || "span"; const alignStyle = align == "inherit" diff --git a/packages/taler-wallet-webextension/src/mui/input/InputFilled.tsx b/packages/taler-wallet-webextension/src/mui/input/InputFilled.tsx @@ -89,9 +89,9 @@ const filledRootStyle = css` border-top-left-radius: ${theme.shape.borderRadius}px; border-top-right-radius: ${theme.shape.borderRadius}px; transition: ${theme.transitions.create("background-color", { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, -})}; + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + })}; // when is not disabled underline &:hover { background-color: ${backgroundColorHover}; @@ -124,9 +124,9 @@ const underlineStyle = css` right: 0px; transform: scaleX(0); transition: ${theme.transitions.create("transform", { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, -})}; + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + })}; pointer-events: none; } &[data-focused]:after { @@ -139,8 +139,8 @@ const underlineStyle = css` &:before { border-bottom: 1px solid ${theme.palette.mode === "light" - ? "rgba(0, 0, 0, 0.42)" - : "rgba(255, 255, 255, 0.7)"}; + ? "rgba(0, 0, 0, 0.42)" + : "rgba(255, 255, 255, 0.7)"}; left: 0px; bottom: 0px; right: 0px; @@ -156,8 +156,8 @@ const underlineStyle = css` @media (hover: none) { border-bottom: 1px solid ${theme.palette.mode === "light" - ? "rgba(0, 0, 0, 0.42)" - : "rgba(255, 255, 255, 0.7)"}; + ? "rgba(0, 0, 0, 0.42)" + : "rgba(255, 255, 255, 0.7)"}; } } &[data-disabled]:before { diff --git a/packages/taler-wallet-webextension/src/mui/input/InputStandard.tsx b/packages/taler-wallet-webextension/src/mui/input/InputStandard.tsx @@ -82,9 +82,9 @@ const underlineStyle = css` right: 0px; transform: scaleX(0); transition: ${theme.transitions.create("transform", { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, -})}; + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + })}; pointer-events: none; } &[data-focused]:after { @@ -97,8 +97,8 @@ const underlineStyle = css` &:before { border-bottom: 1px solid ${theme.palette.mode === "light" - ? "rgba(0, 0, 0, 0.42)" - : "rgba(255, 255, 255, 0.7)"}; + ? "rgba(0, 0, 0, 0.42)" + : "rgba(255, 255, 255, 0.7)"}; left: 0px; bottom: 0px; right: 0px; @@ -114,8 +114,8 @@ const underlineStyle = css` @media (hover: none) { border-bottom: 1px solid ${theme.palette.mode === "light" - ? "rgba(0, 0, 0, 0.42)" - : "rgba(255, 255, 255, 0.7)"}; + ? "rgba(0, 0, 0, 0.42)" + : "rgba(255, 255, 255, 0.7)"}; } } &[data-disabled]:before { diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -510,7 +510,8 @@ function setAlertedIcon(): void { } interface OffscreenCanvasRenderingContext2D - extends CanvasState, + extends + CanvasState, CanvasTransform, CanvasCompositing, CanvasImageSmoothing, diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts @@ -19,7 +19,7 @@ import { CrossBrowserPermissionsApi, ForegroundPlatformAPI, Settings, - defaultSettings + defaultSettings, } from "./api.js"; import chromePlatform, { containsClipboardPermissions as chromeClipContains, diff --git a/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx b/packages/taler-wallet-webextension/src/popup/Balance.stories.tsx @@ -37,10 +37,10 @@ export const SomeCoins = tests.createExample(TestedComponent, { { flags: [], available: "USD:10.5" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -57,10 +57,10 @@ export const SomeCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "EUR:1" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -70,10 +70,10 @@ export const SomeCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "TESTKUDOS:2000" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -83,10 +83,10 @@ export const SomeCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "JPY:4" as AmountString, - + pendingIncoming: "EUR:15" as AmountString, pendingOutgoing: "EUR:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -103,10 +103,10 @@ export const NoCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "EUR:3" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -116,10 +116,10 @@ export const NoCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "USD:2" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -129,10 +129,10 @@ export const NoCoinsInTreeCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "ARS:1" as AmountString, - + pendingIncoming: "EUR:15" as AmountString, pendingOutgoing: "EUR:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -149,10 +149,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "USD:0" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -162,10 +162,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "ARS:13451" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -175,10 +175,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "EUR:202.02" as AmountString, - + pendingIncoming: "EUR:0" as AmountString, pendingOutgoing: "EUR:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -188,10 +188,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "JPY:0" as AmountString, - + pendingIncoming: "EUR:0" as AmountString, pendingOutgoing: "EUR:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -201,10 +201,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "JPY:51223233" as AmountString, - + pendingIncoming: "EUR:0" as AmountString, pendingOutgoing: "EUR:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -214,10 +214,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "DEMOKUDOS:6" as AmountString, - + pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, @@ -227,10 +227,10 @@ export const SomeCoinsInFiveCurrencies = tests.createExample(TestedComponent, { { flags: [], available: "TESTKUDOS:6" as AmountString, - + pendingIncoming: "USD:5" as AmountString, pendingOutgoing: "USD:0" as AmountString, - + scopeInfo: { currency: "TESTKUDOS", type: ScopeType.Auditor, diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -127,7 +127,11 @@ function useComponentState({ }, goToWalletManualWithdraw: { onClick: pushAlertOnError(async () => { - goToWalletManualWithdraw(state.response.balances.length ? state.response.balances[0].scopeInfo : undefined); + goToWalletManualWithdraw( + state.response.balances.length + ? state.response.balances[0].scopeInfo + : undefined, + ); }), }, goToWalletDeposit, diff --git a/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx b/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx @@ -31,23 +31,31 @@ export function NoBalanceHelp({ goToWalletManualWithdraw: ButtonHandler; }): VNode { const { i18n } = useTranslationContext(); - return (<Fragment> - - <Paper class={margin}> - <Alert title={i18n.str`Your wallet is empty.`} severity="info"> - <Button - fullWidth - color="info" - variant="outlined" - onClick={goToWalletManualWithdraw.onClick} - > - <i18n.Translate>Get digital cash</i18n.Translate> - </Button> - </Alert> - </Paper> - <a target="_bank" rel="noreferrer" href="https://demo.taler.net/" style={{ display: "block" }}> - <i18n.Translate>Try the demo bank and withdraw test money.</i18n.Translate> » - </a> - </Fragment> + return ( + <Fragment> + <Paper class={margin}> + <Alert title={i18n.str`Your wallet is empty.`} severity="info"> + <Button + fullWidth + color="info" + variant="outlined" + onClick={goToWalletManualWithdraw.onClick} + > + <i18n.Translate>Get digital cash</i18n.Translate> + </Button> + </Alert> + </Paper> + <a + target="_bank" + rel="noreferrer" + href="https://demo.taler.net/" + style={{ display: "block" }} + > + <i18n.Translate> + Try the demo bank and withdraw test money. + </i18n.Translate>{" "} + » + </a> + </Fragment> ); } diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx @@ -81,18 +81,22 @@ function ContentByUriType({ return ( <div> <p> - <i18n.Translate>This page has a add exchange action.</i18n.Translate> + <i18n.Translate> + This page has a add exchange action. + </i18n.Translate> </p> <Button variant="contained" color="success" onClick={onConfirm}> <i18n.Translate>Open add exchange page</i18n.Translate> </Button> </div> ); - case TalerUriAction.AddContact: + case TalerUriAction.AddContact: return ( <div> <p> - <i18n.Translate>This page has an add contact action.</i18n.Translate> + <i18n.Translate> + This page has an add contact action. + </i18n.Translate> </p> <Button variant="contained" color="success" onClick={onConfirm}> <i18n.Translate>Open add contact page</i18n.Translate> diff --git a/packages/taler-wallet-webextension/src/pwa/index.html b/packages/taler-wallet-webextension/src/pwa/index.html @@ -83,7 +83,14 @@ } </script> <button onclick="openPopup()">Open Popup</button> - <button onclick="closeWallet();openWallet()">Restart Wallet</button> + <button + onclick=" + closeWallet(); + openWallet(); + " + > + Restart Wallet + </button> <button onclick="reloadWallet()">Refresh Frame</button> <div style="height: 8px"></div> <iframe id="wallet-window" name="wallet" src="wallet.html" width=""> diff --git a/packages/taler-wallet-webextension/src/pwa/popup.html b/packages/taler-wallet-webextension/src/pwa/popup.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html> <head> <meta charset="utf-8" /> diff --git a/packages/taler-wallet-webextension/src/pwa/stories.html b/packages/taler-wallet-webextension/src/pwa/stories.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html> <head> <title>Stories</title> diff --git a/packages/taler-wallet-webextension/src/pwa/tests.html b/packages/taler-wallet-webextension/src/pwa/tests.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html> <head> <title>Mocha Tests</title> diff --git a/packages/taler-wallet-webextension/src/wallet/AddContact/index.ts b/packages/taler-wallet-webextension/src/wallet/AddContact/index.ts @@ -15,7 +15,11 @@ */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { ContactEntry, OperationFail, OperationOk } from "@gnu-taler/taler-util"; +import { + ContactEntry, + OperationFail, + OperationOk, +} from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { ErrorAlert } from "../../context/alert.js"; import { TextFieldHandler } from "../../mui/handlers.js"; @@ -30,10 +34,7 @@ export interface Props { noDebounce?: boolean; } -export type State = - | State.LoadingUriError - | State.Confirm - | State.Verify; +export type State = State.LoadingUriError | State.Confirm | State.Verify; export namespace State { export interface LoadingUriError { @@ -58,11 +59,10 @@ export namespace State { onCancel: () => Promise<void>; onAccept: () => Promise<void>; - alias: TextFieldHandler, - aliasType: TextFieldHandler, - mailboxUri: TextFieldHandler, - result: OperationOk<"ok"> - | OperationFail<"already-added"> + alias: TextFieldHandler; + aliasType: TextFieldHandler; + mailboxUri: TextFieldHandler; + result: OperationOk<"ok"> | OperationFail<"already-added">; } } const viewMapping: StateViewMap<State> = { diff --git a/packages/taler-wallet-webextension/src/wallet/AddContact/state.ts b/packages/taler-wallet-webextension/src/wallet/AddContact/state.ts @@ -15,7 +15,11 @@ */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { ContactEntry, opFixedSuccess, opKnownFailure } from "@gnu-taler/taler-util"; +import { + ContactEntry, + opFixedSuccess, + opKnownFailure, +} from "@gnu-taler/taler-util"; import { useCallback, useState } from "preact/hooks"; import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; @@ -23,7 +27,11 @@ import { withSafe } from "../../mui/handlers.js"; import { RecursiveState } from "../../utils/index.js"; import { Props, State } from "./index.js"; -export function useComponentState({ onBack, contact, noDebounce }: Props): RecursiveState<State> { +export function useComponentState({ + onBack, + contact, + noDebounce, +}: Props): RecursiveState<State> { const [alias, setAlias] = useState<string>(); const [aliasType, setAliasType] = useState<string>(); const [mailboxUri, setMailboxUri] = useState<string>(); @@ -32,15 +40,24 @@ export function useComponentState({ onBack, contact, noDebounce }: Props): Recur const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.GetContacts, {}), ); - const walletContacts = !hook ? [] : hook.hasError ? [] : hook.response.contacts - + const walletContacts = !hook + ? [] + : hook.hasError + ? [] + : hook.response.contacts; + if (!contactInState) { return (): State => { - const found = (!contact) ? -1 : walletContacts.findIndex((e) => (e.alias == contact.alias) && (e.aliasType == contact.aliasType)); - const result = (found !== -1) ? - opKnownFailure("already-added"as const) : - opFixedSuccess("ok"as const); - const [inputError, setInputError] = useState<string>() + const found = !contact + ? -1 + : walletContacts.findIndex( + (e) => e.alias == contact.alias && e.aliasType == contact.aliasType, + ); + const result = + found !== -1 + ? opKnownFailure("already-added" as const) + : opFixedSuccess("ok" as const); + const [inputError, setInputError] = useState<string>(); return { status: "verify", @@ -48,38 +65,44 @@ export function useComponentState({ onBack, contact, noDebounce }: Props): Recur onCancel: onBack, onAccept: async () => { if (!result || result.type !== "ok") return; - setContactInState(contact) + setContactInState(contact); }, alias: { value: alias ?? "", error: inputError, - onInput: withSafe(async (x) => {setAlias(x)}, (e) => { - setInputError(e.message) - }) + onInput: withSafe( + async (x) => { + setAlias(x); + }, + (e) => { + setInputError(e.message); + }, + ), }, aliasType: { value: aliasType ?? "", error: inputError, onInput: withSafe(setAliasType, (e) => { - setInputError(e.message) - }) + setInputError(e.message); + }), }, mailboxUri: { value: mailboxUri ?? "", error: inputError, onInput: withSafe(setMailboxUri, (e) => { - setInputError(e.message) - }) + setInputError(e.message); + }), }, result, }; - - } + }; } async function addContactInternal(): Promise<void> { if (!contactInState) return; - await api.wallet.call(WalletApiOperation.AddContact, { contact: contactInState }); + await api.wallet.call(WalletApiOperation.AddContact, { + contact: contactInState, + }); onBack(); } return { @@ -88,5 +111,5 @@ export function useComponentState({ onBack, contact, noDebounce }: Props): Recur onCancel: onBack, onConfirm: addContactInternal, contact: contactInState ?? contact, - } + }; } diff --git a/packages/taler-wallet-webextension/src/wallet/AddContact/stories.tsx b/packages/taler-wallet-webextension/src/wallet/AddContact/stories.tsx @@ -19,7 +19,6 @@ * @author Sebastian Javier Marchano (sebasjm) */ - export default { title: "example", }; diff --git a/packages/taler-wallet-webextension/src/wallet/AddContact/views.tsx b/packages/taler-wallet-webextension/src/wallet/AddContact/views.tsx @@ -19,7 +19,7 @@ import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { ErrorMessage } from "../../components/ErrorMessage.js"; import { - Centered, + Centered, Input, LargeText, LightText, @@ -68,9 +68,7 @@ export function VerifyContactView({ if (result.type == "ok") { return ( <LightText> - <i18n.Translate> - Contact info valid. - </i18n.Translate> + <i18n.Translate>Contact info valid.</i18n.Translate> </LightText> ); } @@ -162,7 +160,7 @@ export function ConfirmAddContactView({ onInput: pushAlertOnError(async (d: string) => { setPetname(d); }), - } + }; const state = useAsyncAsHook(async () => { const b = await api.wallet.call(WalletApiOperation.GetContacts, {}); const contacts = b.contacts; @@ -175,7 +173,9 @@ export function ConfirmAddContactView({ async function onAddContact(): Promise<void> { contact.petname = petname ?? contact.alias; console.log(contact); - await api.wallet.call(WalletApiOperation.AddContact, { contact: contact }).then(); + await api.wallet + .call(WalletApiOperation.AddContact, { contact: contact }) + .then(); onConfirm(); } return ( @@ -185,21 +185,36 @@ export function ConfirmAddContactView({ <i18n.Translate>Review contact</i18n.Translate> </LargeText> <SmallText style={{ marginTop: 5 }}> - <b><i18n.Translate>Contact alias</i18n.Translate></b>: {contact.alias} + <b> + <i18n.Translate>Contact alias</i18n.Translate> + </b> + : {contact.alias} </SmallText> - <SmallText style={{ marginTop: 5 }}> - <b><i18n.Translate>Alias type</i18n.Translate></b>: {contact.aliasType} + <SmallText style={{ marginTop: 5 }}> + <b> + <i18n.Translate>Alias type</i18n.Translate> + </b> + : {contact.aliasType} </SmallText> <SmallText style={{ marginTop: 5 }}> - <b><i18n.Translate>Mailbox service</i18n.Translate></b>: {contact.mailboxBaseUri} + <b> + <i18n.Translate>Mailbox service</i18n.Translate> + </b> + : {contact.mailboxBaseUri} </SmallText> <SmallText style={{ marginTop: 5, marginBottom: 5 }}> - <b><i18n.Translate>Mailbox address</i18n.Translate></b>: {contact.mailboxAddress.toUpperCase().slice(0,8)}[...] + <b> + <i18n.Translate>Mailbox address</i18n.Translate> + </b> + : {contact.mailboxAddress.toUpperCase().slice(0, 8)}[...] </SmallText> - {(contact.source) && ( - <SmallText style={{ marginTop: 5 }}> - <b><i18n.Translate>Contact source</i18n.Translate></b>: {contact.source} - </SmallText> + {contact.source && ( + <SmallText style={{ marginTop: 5 }}> + <b> + <i18n.Translate>Contact source</i18n.Translate> + </b> + : {contact.source} + </SmallText> )} <TextField label="Petname" @@ -210,10 +225,11 @@ export function ConfirmAddContactView({ onChange={petnameHandler.onInput} error={petnameHandler.error} /> - </section> + </section> - <footer style={{padding: 8}}> - <Button style={{ margin: 4 }} + <footer style={{ padding: 8 }}> + <Button + style={{ margin: 4 }} key="cancel" variant="contained" color="secondary" diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/index.ts b/packages/taler-wallet-webextension/src/wallet/AddExchange/index.ts @@ -14,7 +14,12 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { OperationAlternative, OperationFail, OperationOk, TalerExchangeApi } from "@gnu-taler/taler-util"; +import { + OperationAlternative, + OperationFail, + OperationOk, + TalerExchangeApi, +} from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; @@ -29,12 +34,12 @@ export interface Props { noDebounce?: boolean; } -export type State = State.Loading +export type State = + | State.Loading | State.LoadingUriError | State.Confirm | State.Verify; - export namespace State { export interface Loading { status: "loading"; @@ -63,17 +68,18 @@ export namespace State { onCancel: () => Promise<void>; onAccept: () => Promise<void>; - url: TextFieldHandler, + url: TextFieldHandler; loading: boolean; - knownExchanges: URL[], - result: OperationOk<TalerExchangeApi.ExchangeKeysResponse> - | OperationAlternative<"invalid-version", string> - | OperationAlternative<"invalid-currency", string> - | OperationFail<"not-found"> - | OperationFail<"already-active"> - | OperationFail<"invalid-protocol"> - | undefined, - expectedCurrency: string | undefined, + knownExchanges: URL[]; + result: + | OperationOk<TalerExchangeApi.ExchangeKeysResponse> + | OperationAlternative<"invalid-version", string> + | OperationAlternative<"invalid-currency", string> + | OperationFail<"not-found"> + | OperationFail<"already-active"> + | OperationFail<"invalid-protocol"> + | undefined; + expectedCurrency: string | undefined; } } const viewMapping: StateViewMap<State> = { diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/state.ts b/packages/taler-wallet-webextension/src/wallet/AddExchange/state.ts @@ -14,7 +14,14 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { ExchangeEntryStatus, TalerExchangeHttpClient, canonicalizeBaseUrl, opKnownFailure, opKnownFailureWithBody, succeedOrThrow } from "@gnu-taler/taler-util"; +import { + ExchangeEntryStatus, + TalerExchangeHttpClient, + canonicalizeBaseUrl, + opKnownFailure, + opKnownFailureWithBody, + succeedOrThrow, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { BrowserFetchHttpLib } from "@gnu-taler/web-util/browser"; import { useCallback, useEffect, useState } from "preact/hooks"; @@ -27,12 +34,12 @@ import { Props, State } from "./index.js"; function urlFromInput(str: string): URL { let result: URL; try { - result = new URL(str) + result = new URL(str); } catch (original) { try { - result = new URL(`https://${str}`) + result = new URL(`https://${str}`); } catch (e) { - throw original + throw original; } } if (!result.pathname.endsWith("/")) { @@ -43,57 +50,83 @@ function urlFromInput(str: string): URL { return result; } -export function useComponentState({ onBack, currency, noDebounce }: Props): RecursiveState<State> { +export function useComponentState({ + onBack, + currency, + noDebounce, +}: Props): RecursiveState<State> { const [verified, setVerified] = useState<string>(); const api = useBackendContext(); const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListExchanges, {}), ); - const walletExchanges = !hook ? [] : hook.hasError ? [] : hook.response.exchanges - const used = walletExchanges.filter(e => e.exchangeEntryStatus === ExchangeEntryStatus.Used); - const preset = walletExchanges.filter(e => e.exchangeEntryStatus === ExchangeEntryStatus.Preset); + const walletExchanges = !hook + ? [] + : hook.hasError + ? [] + : hook.response.exchanges; + const used = walletExchanges.filter( + (e) => e.exchangeEntryStatus === ExchangeEntryStatus.Used, + ); + const preset = walletExchanges.filter( + (e) => e.exchangeEntryStatus === ExchangeEntryStatus.Preset, + ); if (!verified) { return (): State => { - const checkExchangeBaseUrl_memo = useCallback(async function checkExchangeBaseUrl(str: string) { - const baseUrl = urlFromInput(str) - if (baseUrl.protocol !== "http:" && baseUrl.protocol !== "https:") { - return opKnownFailure("invalid-protocol"as const) - } - const found = used.findIndex((e) => e.exchangeBaseUrl === baseUrl.href); - if (found !== -1) { - return opKnownFailure("already-active"as const); - } + const checkExchangeBaseUrl_memo = useCallback( + async function checkExchangeBaseUrl(str: string) { + const baseUrl = urlFromInput(str); + if (baseUrl.protocol !== "http:" && baseUrl.protocol !== "https:") { + return opKnownFailure("invalid-protocol" as const); + } + const found = used.findIndex( + (e) => e.exchangeBaseUrl === baseUrl.href, + ); + if (found !== -1) { + return opKnownFailure("already-active" as const); + } - /** - * FIXME: For some reason typescript doesn't like the next BrowserFetchHttpLib - * - * │ src/wallet/AddExchange/state.ts(68,63): error TS2345: Argument of type 'BrowserFetchHttpLib' is not assignable to parameter of ty - * │ Types of property 'fetch' are incompatible. - * │ Type '(requestUrl: string, options?: HttpRequestOptions | undefined) => Promise<HttpResponse>' is not assignable to type '(ur - * │ Types of parameters 'options' and 'opt' are incompatible. - * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/http-common", { wi - * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/http-common", { - * │ Types of property 'cancellationToken' are incompatible. - * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/Cancellation - * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/Cancellati - * │ Types have separate declarations of a private property '_isCancelled'. - * - */ - const api = new TalerExchangeHttpClient(baseUrl.href, { - httpClient: new BrowserFetchHttpLib(), - }); - const config = succeedOrThrow(await api.getConfig()) - if (currency !== undefined && currency !== config.currency) { - return opKnownFailureWithBody("invalid-currency"as const, config.currency) - } - const keys = await api.getKeys() - return keys - }, [used]) + /** + * FIXME: For some reason typescript doesn't like the next BrowserFetchHttpLib + * + * │ src/wallet/AddExchange/state.ts(68,63): error TS2345: Argument of type 'BrowserFetchHttpLib' is not assignable to parameter of ty + * │ Types of property 'fetch' are incompatible. + * │ Type '(requestUrl: string, options?: HttpRequestOptions | undefined) => Promise<HttpResponse>' is not assignable to type '(ur + * │ Types of parameters 'options' and 'opt' are incompatible. + * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/http-common", { wi + * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/http-common", { + * │ Types of property 'cancellationToken' are incompatible. + * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/Cancellation + * │ Type 'import("$PATH/wallet.git/packages/taler-util/lib/Cancellati + * │ Types have separate declarations of a private property '_isCancelled'. + * + */ + const api = new TalerExchangeHttpClient(baseUrl.href, { + httpClient: new BrowserFetchHttpLib(), + }); + const config = succeedOrThrow(await api.getConfig()); + if (currency !== undefined && currency !== config.currency) { + return opKnownFailureWithBody( + "invalid-currency" as const, + config.currency, + ); + } + const keys = await api.getKeys(); + return keys; + }, + [used], + ); - const { result, value: url, loading, update, error: requestError } = useDebounce(checkExchangeBaseUrl_memo, noDebounce ?? false) - const [inputError, setInputError] = useState<string>() + const { + result, + value: url, + loading, + update, + error: requestError, + } = useDebounce(checkExchangeBaseUrl_memo, noDebounce ?? false); + const [inputError, setInputError] = useState<string>(); return { status: "verify", @@ -102,20 +135,20 @@ export function useComponentState({ onBack, currency, noDebounce }: Props): Recu expectedCurrency: currency, onAccept: async () => { if (!result || result.type !== "ok") return; - setVerified(result.body.base_url) + setVerified(result.body.base_url); }, result, loading, - knownExchanges: preset.map(e => new URL(e.exchangeBaseUrl)), + knownExchanges: preset.map((e) => new URL(e.exchangeBaseUrl)), url: { value: url ?? "", error: inputError ?? requestError, onInput: withSafe(update, (e) => { - setInputError(e.message) - }) + setInputError(e.message); + }), }, }; - } + }; } async function onConfirm() { @@ -132,12 +165,10 @@ export function useComponentState({ onBack, currency, noDebounce }: Props): Recu error: undefined, onCancel: onBack, onConfirm, - url: verified + url: verified, }; } - - function useDebounce<T>( onTrigger: (v: string) => Promise<T>, disabled: boolean, @@ -173,7 +204,7 @@ function useDebounce<T>( setError(er); } else { // @ts-expect-error cause still not in typescript - setError(new Error('unknown error on debounce', { cause: er })) + setError(new Error("unknown error on debounce", { cause: er })); } setLoading(false); setResult(undefined); @@ -191,4 +222,3 @@ function useDebounce<T>( update: disabled ? onTrigger : setValue, }; } - diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/stories.tsx b/packages/taler-wallet-webextension/src/wallet/AddExchange/stories.tsx @@ -19,7 +19,6 @@ * @author Sebastian Javier Marchano (sebasjm) */ - export default { title: "example", }; diff --git a/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts b/packages/taler-wallet-webextension/src/wallet/AddExchange/test.ts @@ -64,7 +64,7 @@ describe("AddExchange states", () => { lastUpdateTimestamp: undefined, noFees: false, peerPaymentsDisabled: false, - currencySpec: {} as any + currencySpec: {} as any, }, ], }, diff --git a/packages/taler-wallet-webextension/src/wallet/Contacts.tsx b/packages/taler-wallet-webextension/src/wallet/Contacts.tsx @@ -47,10 +47,7 @@ interface Props { onMessageSent?: () => Promise<void>; } -export function ContactsPage({ - tid, - onMessageSent -}: Props): VNode { +export function ContactsPage({ tid, onMessageSent }: Props): VNode { const transactionId = tid as TransactionIdStr; //FIXME: validate const { i18n } = useTranslationContext(); const api = useBackendContext(); @@ -59,19 +56,23 @@ export function ContactsPage({ const state = useAsyncAsHook(async () => { const b = await api.wallet.call(WalletApiOperation.GetContacts, {}); const contacts = b.contacts; - const filteredContacts = contacts.filter(c => (!search) ? true : ( - c.petname.toLowerCase().includes(search.toLowerCase()) || - c.alias.toLowerCase().includes(search.toLowerCase()) || - c.aliasType.toLowerCase().includes(search.toLowerCase()) || - c.mailboxBaseUri.toLowerCase().includes(search.toLowerCase()) || - c.source.toLowerCase().includes(search.toLowerCase())) - ); - const tx = tid? - await api.wallet.call(WalletApiOperation.GetTransactionById, {transactionId}) - : undefined; + const filteredContacts = contacts.filter((c) => + !search + ? true + : c.petname.toLowerCase().includes(search.toLowerCase()) || + c.alias.toLowerCase().includes(search.toLowerCase()) || + c.aliasType.toLowerCase().includes(search.toLowerCase()) || + c.mailboxBaseUri.toLowerCase().includes(search.toLowerCase()) || + c.source.toLowerCase().includes(search.toLowerCase()), + ); + const tx = tid + ? await api.wallet.call(WalletApiOperation.GetTransactionById, { + transactionId, + }) + : undefined; return { contacts: filteredContacts, - transaction: tx + transaction: tx, }; }, [search, tid]); @@ -106,17 +107,21 @@ export function ContactsPage({ if (!t) { return; } - if ((t.type != TransactionType.PeerPushDebit) && - (t.type != TransactionType.PeerPullCredit)) { + if ( + t.type != TransactionType.PeerPushDebit && + t.type != TransactionType.PeerPullCredit + ) { return; } if (!t.talerUri) { return; } - await api.wallet.call(WalletApiOperation.SendTalerUriMailboxMessage, { - contact: c, - talerUri: t.talerUri, - }).then(); + await api.wallet + .call(WalletApiOperation.SendTalerUriMailboxMessage, { + contact: c, + talerUri: t.talerUri, + }) + .then(); if (onMessageSent) { onMessageSent(); } @@ -144,7 +149,6 @@ interface ContactProps { onSendUriMessage: (c: ContactEntry, t?: Transaction) => Promise<void>; } - function ContactLayout(props: ContactProps): VNode { const { i18n } = useTranslationContext(); return ( @@ -154,31 +158,52 @@ function ContactLayout(props: ContactProps): VNode { <SmallText style={{ marginTop: 5 }}> <i18n.Translate>Alias</i18n.Translate>: {props.contact.alias} </SmallText> - <SmallText style={{ marginTop: 5 }}> + <SmallText style={{ marginTop: 5 }}> <i18n.Translate>Type</i18n.Translate>: {props.contact.aliasType} </SmallText> <SmallText style={{ marginTop: 5 }}> <i18n.Translate>Source</i18n.Translate>: {props.contact.source} </SmallText> - <SmallLightText style={{ marginTop: 5, marginBotton: 5 }}> - <i18n.Translate>Mailbox</i18n.Translate>: {props.contact.mailboxBaseUri} + <SmallLightText style={{ marginTop: 5, marginBotton: 5 }}> + <i18n.Translate>Mailbox</i18n.Translate>:{" "} + {props.contact.mailboxBaseUri} </SmallLightText> </p> {!props.transaction && ( - <Button variant="contained" onClick={() => { return props.onDeleteContact(props.contact)}} color="error"> + <Button + variant="contained" + onClick={() => { + return props.onDeleteContact(props.contact); + }} + color="error" + > <i18n.Translate>Delete</i18n.Translate> </Button> )} - {(props.transaction && (props.transaction.type == TransactionType.PeerPushDebit)) && ( - <Button variant="contained" color="warning" onClick={() => { return props.onSendUriMessage(props.contact, props.transaction)}}> - <i18n.Translate>Send Cash</i18n.Translate> - </Button> - )} - {(props.transaction && (props.transaction.type == TransactionType.PeerPullCredit)) && ( - <Button variant="contained" color="success" onClick={() => { return props.onSendUriMessage(props.contact, props.transaction)}}> - <i18n.Translate>Request Cash</i18n.Translate> - </Button> - )} + {props.transaction && + props.transaction.type == TransactionType.PeerPushDebit && ( + <Button + variant="contained" + color="warning" + onClick={() => { + return props.onSendUriMessage(props.contact, props.transaction); + }} + > + <i18n.Translate>Send Cash</i18n.Translate> + </Button> + )} + {props.transaction && + props.transaction.type == TransactionType.PeerPullCredit && ( + <Button + variant="contained" + color="success" + onClick={() => { + return props.onSendUriMessage(props.contact, props.transaction); + }} + > + <i18n.Translate>Request Cash</i18n.Translate> + </Button> + )} </Paper> ); } @@ -209,32 +234,33 @@ export function ContactsView({ value={search.value} onChange={search.onInput} /> - {(contacts.length == 0) ? ( + {contacts.length == 0 ? ( <Centered style={{ marginTop: 20 }}> <BoldLight> <i18n.Translate>No contacts found.</i18n.Translate> </BoldLight> </Centered> - ) : - ( - <Grid item container columns={1} spacing={1} style={{ marginTop: 20 }}> - { - contacts.map((c, _) => ( - <Grid item xs={1}> - <ContactLayout - contact={c} - transaction={transaction} - onDeleteContact={onDeleteContact} - onSendUriMessage={onSendUriMessage} - /> - </Grid> - )) - } - </Grid> + ) : ( + <Grid + item + container + columns={1} + spacing={1} + style={{ marginTop: 20 }} + > + {contacts.map((c, _) => ( + <Grid item xs={1}> + <ContactLayout + contact={c} + transaction={transaction} + onDeleteContact={onDeleteContact} + onSendUriMessage={onSendUriMessage} + /> + </Grid> + ))} + </Grid> )} - </section> + </section> </Fragment> ); } - - diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts @@ -188,7 +188,8 @@ function getBalanceForScope( const bs = b.scopeInfo; if (bs.type !== scope.type) return false; if (bs.currency !== scope.currency) return false; - if (scope.type === ScopeType.Global || bs.type === ScopeType.Global) return false; + if (scope.type === ScopeType.Global || bs.type === ScopeType.Global) + return false; if (scope.url !== bs.url) return false; return true; }); diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts @@ -26,7 +26,7 @@ import { ExchangeTosStatus, ExchangeUpdateStatus, ScopeInfo, - ScopeType + ScopeType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import * as tests from "@gnu-taler/web-util/testing"; @@ -99,7 +99,6 @@ describe("Destination selection states", () => { if (state.error) expect.fail(); expect(state.goToBank.onClick).eq(undefined); expect(state.goToWallet.onClick).eq(undefined); - }, ], TestingContext, @@ -136,7 +135,6 @@ describe("Destination selection states", () => { if (state.error) expect.fail(); expect(state.goToBank.onClick).not.eq(undefined); expect(state.goToWallet.onClick).not.eq(undefined); - }, ], TestingContext, diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx @@ -277,7 +277,7 @@ export function ReadySendView({ onSelectAccount, goToWallet, previous, - disablePeerPayments + disablePeerPayments, }: State.Ready): VNode { const { i18n } = useTranslationContext(); diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx @@ -257,7 +257,7 @@ function timelineExample() { }, }, ], - refresh: [ + refresh: [ { group: "0.1", from: { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx @@ -135,7 +135,7 @@ export function TosContentView({ <Button variant="outlined" onClick={onClose.onClick}> <i18n.Translate>Close</i18n.Translate> </Button> - <TermsOfService exchangeUrl={exchangeUrl} readOnly > + <TermsOfService exchangeUrl={exchangeUrl} readOnly> s </TermsOfService> </div> @@ -893,13 +893,16 @@ function RenderFeePairByValue({ list: FeeDescriptionPair[]; sorting?: (a: string, b: string) => number; }): VNode { - const grouped = list.reduce((prev, cur) => { - if (!prev[cur.group]) { - prev[cur.group] = []; - } - prev[cur.group].push(cur); - return prev; - }, {} as Record<string, FeeDescriptionPair[]>); + const grouped = list.reduce( + (prev, cur) => { + if (!prev[cur.group]) { + prev[cur.group] = []; + } + prev[cur.group].push(cur); + return prev; + }, + {} as Record<string, FeeDescriptionPair[]>, + ); const p = Object.keys(grouped) .sort(sorting) .map((i, idx) => <FeePairRowsGroup key={idx} infos={grouped[i]} />); @@ -918,13 +921,16 @@ function RenderFeeDescriptionByValue({ list: FeeDescription[]; sorting?: (a: string, b: string) => number; }): VNode { - const grouped = list.reduce((prev, cur) => { - if (!prev[cur.group]) { - prev[cur.group] = []; - } - prev[cur.group].push(cur); - return prev; - }, {} as Record<string, FeeDescription[]>); + const grouped = list.reduce( + (prev, cur) => { + if (!prev[cur.group]) { + prev[cur.group] = []; + } + prev[cur.group].push(cur); + return prev; + }, + {} as Record<string, FeeDescription[]>, + ); const p = Object.keys(grouped) .sort(sorting) .map((i, idx) => <FeeDescriptionRowsGroup key={idx} infos={grouped[i]} />); diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx @@ -179,8 +179,7 @@ export const SomeBalanceWithNoTransactions = tests.createExample( flags: [], pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, @@ -206,13 +205,11 @@ export const OneSimpleTransaction = tests.createExample(TestedComponent, { available: "USD:10" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -227,8 +224,7 @@ export const TwoTransactionsAndZeroBalance = tests.createExample( scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -236,13 +232,11 @@ export const TwoTransactionsAndZeroBalance = tests.createExample( available: "USD:0" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -263,8 +257,7 @@ export const OneTransactionPending = tests.createExample(TestedComponent, { scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -272,13 +265,11 @@ export const OneTransactionPending = tests.createExample(TestedComponent, { available: "USD:10" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -306,8 +297,7 @@ export const SomeTransactions = tests.createExample(TestedComponent, { scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -315,13 +305,11 @@ export const SomeTransactions = tests.createExample(TestedComponent, { available: "USD:10" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -408,8 +396,7 @@ export const SomeTransactionsInDifferentStates = tests.createExample( scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -417,13 +404,11 @@ export const SomeTransactionsInDifferentStates = tests.createExample( available: "USD:10" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -447,8 +432,7 @@ export const SomeTransactionsWithTwoCurrencies = tests.createExample( scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -456,13 +440,11 @@ export const SomeTransactionsWithTwoCurrencies = tests.createExample( available: "USD:0" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -470,13 +452,11 @@ export const SomeTransactionsWithTwoCurrencies = tests.createExample( available: "TESTKUDOS:10" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -490,8 +470,7 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -499,13 +478,11 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { available: "USD:1000" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -513,13 +490,11 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { available: "EUR:881" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -527,13 +502,11 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { available: "COL:4043000.5" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -541,13 +514,11 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { available: "JPY:11564450.6" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -555,13 +526,11 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { available: "GBP:736" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -576,8 +545,7 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample( scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -585,13 +553,11 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample( available: "USD:881001321230000" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -599,13 +565,11 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample( available: "EUR:10" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -613,27 +577,23 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample( available: "COL:443000123123000.5123123" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, - }, { flags: [], available: "JPY:1564450000000.6123123" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, { @@ -641,13 +601,11 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample( available: "GBP:736001231231200.23123" as AmountString, pendingIncoming: "TESTKUDOS:0" as AmountString, pendingOutgoing: "TESTKUDOS:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], @@ -666,8 +624,7 @@ export const PeerToPeer = tests.createExample(TestedComponent, { scope: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, balances: [ { @@ -675,13 +632,11 @@ export const PeerToPeer = tests.createExample(TestedComponent, { available: "USD:10" as AmountString, pendingIncoming: "USD:0" as AmountString, pendingOutgoing: "USD:0" as AmountString, - - + scopeInfo: { currency: "Ásd", type: ScopeType.Auditor, - url: "http://auditor.taler.ar", - + url: "http://auditor.taler.ar", }, }, ], diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -76,7 +76,7 @@ export function HistoryPage({ const tx = await api.wallet.call(WalletApiOperation.GetTransactionsV2, { scopeInfo: showSearch ? undefined : selectedScope, includeRefreshes: settings.showRefeshTransactions, - limit: -100 + limit: -100, }); return { balances, transactions: tx.transactions }; }, [selectedScope, search]); diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts @@ -14,7 +14,12 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { WalletBankAccountInfo, ScopeInfo, PaytoString, WireTypeDetails } from "@gnu-taler/taler-util"; +import { + WalletBankAccountInfo, + ScopeInfo, + PaytoString, + WireTypeDetails, +} from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; diff --git a/packages/taler-wallet-webextension/src/wallet/QrReader.stories.tsx b/packages/taler-wallet-webextension/src/wallet/QrReader.stories.tsx @@ -26,6 +26,4 @@ export default { title: "qr reader", }; -export const Reading = tests.createExample(QrReaderPage, { - -}); +export const Reading = tests.createExample(QrReaderPage, {}); diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -71,7 +71,6 @@ const commonTransaction: TransactionCommon = { transactionId: "txn:deposit:12" as TransactionIdStr, type: TransactionType.Deposit, stId: 1, - } as Omit< Omit<Omit<TransactionCommon, "extendedStatus">, "frozen">, "pending" @@ -201,7 +200,8 @@ const exampleData = { pull_debit: { ...commonTransaction, type: TransactionType.PeerPullDebit, - info: { iconId: "", + info: { + iconId: "", expiration: { t_s: new Date().getTime() / 1000 + 2 * 60 * 60, diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx @@ -50,9 +50,7 @@ export function WelcomePage(): VNode { export interface ViewProps { permissionToggle: ToggleHandler; } -export function View({ - permissionToggle, -}: ViewProps): VNode { +export function View({ permissionToggle }: ViewProps): VNode { const { i18n } = useTranslationContext(); return ( <Fragment> @@ -70,8 +68,8 @@ export function View({ <Fragment> <p> <i18n.Translate> - Also pinning the GNU Taler Wallet to your browser allows - you to quick access without keyboard: + Also pinning the GNU Taler Wallet to your browser allows you to + quick access without keyboard: </i18n.Translate> </p> <ol style={{ paddingLeft: 40 }}> diff --git a/packages/web-util/src/components/Attention.tsx b/packages/web-util/src/components/Attention.tsx @@ -1,17 +1,27 @@ -import { Duration, TranslatedString, assertUnreachable } from "@gnu-taler/taler-util"; +import { + Duration, + TranslatedString, + assertUnreachable, +} from "@gnu-taler/taler-util"; import { ComponentChildren, Fragment, VNode, h } from "preact"; interface Props { - type?: "info" | "success" | "warning" | "danger" | "low", - onClose?: () => void, - title: TranslatedString | VNode, - children?: ComponentChildren, - timeout?: Duration, + type?: "info" | "success" | "warning" | "danger" | "low"; + onClose?: () => void; + title: TranslatedString | VNode; + children?: ComponentChildren; + timeout?: Duration; } -export function Attention({ type = "info", title, children, onClose, timeout = Duration.getForever() }: Props): VNode { - - return <div class={`group attention-${type} mt-2 shadow-lg`}> - {/* {timeout.d_ms === "forever" ? undefined : <style>{` +export function Attention({ + type = "info", + title, + children, + onClose, + timeout = Duration.getForever(), +}: Props): VNode { + return ( + <div class={`group attention-${type} mt-2 shadow-lg`}> + {/* {timeout.d_ms === "forever" ? undefined : <style>{` .progress { animation: notificationTimeoutBar ${Math.round(timeout.d_ms / 1000)}s ease-in-out; animation-fill-mode:both; @@ -24,57 +34,95 @@ export function Attention({ type = "info", title, children, onClose, timeout = D `}</style> } */} - <div data-timed={timeout.d_ms !== "forever"} class="rounded-md data-[timed=true]:rounded-b-none group-[.attention-info]:bg-blue-50 group-[.attention-low]:bg-gray-100 group-[.attention-warning]:bg-yellow-50 group-[.attention-danger]:bg-red-50 group-[.attention-success]:bg-green-50 p-4 shadow"> - <div class="flex"> - <div > - {type === "low" ? undefined : - <svg xmlns="http://www.w3.org/2000/svg" stroke="none" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 group-[.attention-info]:text-blue-400 group-[.attention-warning]:text-yellow-400 group-[.attention-danger]:text-red-400 group-[.attention-success]:text-green-400"> - {(() => { - switch (type) { - case "info": - return <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" /> - case "warning": - return <path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" /> - case "danger": - return <path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" /> - case "success": - return <path fill-rule="evenodd" d="M7.493 18.75c-.425 0-.82-.236-.975-.632A7.48 7.48 0 016 15.375c0-1.75.599-3.358 1.602-4.634.151-.192.373-.309.6-.397.473-.183.89-.514 1.212-.924a9.042 9.042 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75 2.25 2.25 0 012.25 2.25c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H14.23c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23h-.777zM2.331 10.977a11.969 11.969 0 00-.831 4.398 12 12 0 00.52 3.507c.26.85 1.084 1.368 1.973 1.368H4.9c.445 0 .72-.498.523-.898a8.963 8.963 0 01-.924-3.977c0-1.708.476-3.305 1.302-4.666.245-.403-.028-.959-.5-.959H4.25c-.832 0-1.612.453-1.918 1.227z" /> - default: - assertUnreachable(type) - } - })()} - </svg> - } - </div> - <div class="ml-3 w-full"> - <h3 class="text-sm font-bold group-[.attention-info]:text-blue-800 group-[.attention-success]:text-green-800 group-[.attention-warning]:text-yellow-800 group-[.attention-danger]:text-red-800"> - {title} - </h3> - <div class="mt-2 text-sm group-[.attention-info]:text-blue-700 group-[.attention-warning]:text-yellow-700 group-[.attention-danger]:text-red-700 group-[.attention-success]:text-green-700"> - {children} - </div> - </div> - {onClose && + <div + data-timed={timeout.d_ms !== "forever"} + class="rounded-md data-[timed=true]:rounded-b-none group-[.attention-info]:bg-blue-50 group-[.attention-low]:bg-gray-100 group-[.attention-warning]:bg-yellow-50 group-[.attention-danger]:bg-red-50 group-[.attention-success]:bg-green-50 p-4 shadow" + > + <div class="flex"> <div> - <button type="button" class="font-semibold items-center rounded bg-transparent px-2 py-1 text-xs text-gray-900 hover:bg-gray-50" - onClick={(e) => { - e.preventDefault(); - onClose(); - }} - > - <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> - <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" /> + {type === "low" ? undefined : ( + <svg + xmlns="http://www.w3.org/2000/svg" + stroke="none" + viewBox="0 0 24 24" + fill="currentColor" + class="w-8 h-8 group-[.attention-info]:text-blue-400 group-[.attention-warning]:text-yellow-400 group-[.attention-danger]:text-red-400 group-[.attention-success]:text-green-400" + > + {(() => { + switch (type) { + case "info": + return ( + <path + fill-rule="evenodd" + d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" + /> + ); + case "warning": + return ( + <path + fill-rule="evenodd" + d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" + /> + ); + case "danger": + return ( + <path + fill-rule="evenodd" + d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" + /> + ); + case "success": + return ( + <path + fill-rule="evenodd" + d="M7.493 18.75c-.425 0-.82-.236-.975-.632A7.48 7.48 0 016 15.375c0-1.75.599-3.358 1.602-4.634.151-.192.373-.309.6-.397.473-.183.89-.514 1.212-.924a9.042 9.042 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75 2.25 2.25 0 012.25 2.25c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H14.23c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23h-.777zM2.331 10.977a11.969 11.969 0 00-.831 4.398 12 12 0 00.52 3.507c.26.85 1.084 1.368 1.973 1.368H4.9c.445 0 .72-.498.523-.898a8.963 8.963 0 01-.924-3.977c0-1.708.476-3.305 1.302-4.666.245-.403-.028-.959-.5-.959H4.25c-.832 0-1.612.453-1.918 1.227z" + /> + ); + default: + assertUnreachable(type); + } + })()} </svg> - </button> + )} + </div> + <div class="ml-3 w-full"> + <h3 class="text-sm font-bold group-[.attention-info]:text-blue-800 group-[.attention-success]:text-green-800 group-[.attention-warning]:text-yellow-800 group-[.attention-danger]:text-red-800"> + {title} + </h3> + <div class="mt-2 text-sm group-[.attention-info]:text-blue-700 group-[.attention-warning]:text-yellow-700 group-[.attention-danger]:text-red-700 group-[.attention-success]:text-green-700"> + {children} + </div> </div> - } + {onClose && ( + <div> + <button + type="button" + class="font-semibold items-center rounded bg-transparent px-2 py-1 text-xs text-gray-900 hover:bg-gray-50" + onClick={(e) => { + e.preventDefault(); + onClose(); + }} + > + <svg + class="h-5 w-5" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" + > + <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" /> + </svg> + </button> + </div> + )} + </div> </div> + {timeout.d_ms === "forever" ? undefined : ( + <div class="meter group-[.attention-info]:bg-blue-50 group-[.attention-low]:bg-gray-100 group-[.attention-warning]:bg-yellow-50 group-[.attention-danger]:bg-red-50 group-[.attention-success]:bg-green-50 h-1 relative overflow-hidden -mt-1"> + <span class="w-full h-full block"> + <span class="h-full block progress group-[.attention-info]:bg-blue-600 group-[.attention-low]:bg-gray-600 group-[.attention-warning]:bg-yellow-600 group-[.attention-danger]:bg-red-600 group-[.attention-success]:bg-green-600"></span> + </span> + </div> + )} </div> - {timeout.d_ms === "forever" ? undefined : - <div class="meter group-[.attention-info]:bg-blue-50 group-[.attention-low]:bg-gray-100 group-[.attention-warning]:bg-yellow-50 group-[.attention-danger]:bg-red-50 group-[.attention-success]:bg-green-50 h-1 relative overflow-hidden -mt-1"> - <span class="w-full h-full block"><span class="h-full block progress group-[.attention-info]:bg-blue-600 group-[.attention-low]:bg-gray-600 group-[.attention-warning]:bg-yellow-600 group-[.attention-danger]:bg-red-600 group-[.attention-success]:bg-green-600"></span></span> - </div> - } - - </div> + ); } diff --git a/packages/web-util/src/components/CopyButton.tsx b/packages/web-util/src/components/CopyButton.tsx @@ -3,25 +3,58 @@ import { useEffect, useState } from "preact/hooks"; export function CopyIcon(): VNode { return ( - <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> - <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" /> + <svg + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 24 24" + stroke-width="1.5" + stroke="currentColor" + class="w-6 h-6" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" + /> </svg> - ) -}; + ); +} export function CopiedIcon(): VNode { return ( - <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> - <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /> + <svg + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 24 24" + stroke-width="1.5" + stroke="currentColor" + class="w-6 h-6" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M4.5 12.75l6 6 9-13.5" + /> </svg> - ) -}; + ); +} -export function CopyButton({ class: clazz, children, getContent }: { children?: ComponentChildren, class: string, getContent: () => string }): VNode { +export function CopyButton({ + class: clazz, + children, + getContent, +}: { + children?: ComponentChildren; + class: string; + getContent: () => string; +}): VNode { const [copied, setCopied] = useState(false); function copyText(): void { if (!navigator.clipboard && !window.isSecureContext) { - prompt("Clipboard is not available on insecure context (http).", getContent()); + prompt( + "Clipboard is not available on insecure context (http).", + getContent(), + ); } if (navigator.clipboard) { navigator.clipboard.writeText(getContent() || ""); @@ -38,10 +71,13 @@ export function CopyButton({ class: clazz, children, getContent }: { children?: if (!copied) { return ( - <button class={clazz} onClick={e => { - e.preventDefault() - copyText() - }} > + <button + class={clazz} + onClick={(e) => { + e.preventDefault(); + copyText(); + }} + > <CopyIcon /> {children} </button> diff --git a/packages/web-util/src/components/ErrorLoading.tsx b/packages/web-util/src/components/ErrorLoading.tsx @@ -21,7 +21,10 @@ import { assertUnreachable, } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; -import { useCommonPreferences, useTranslationContext } from "../index.browser.js"; +import { + useCommonPreferences, + useTranslationContext, +} from "../index.browser.js"; import { Attention } from "./Attention.js"; export function DebugInfo({ error }: { error: any }): VNode { diff --git a/packages/web-util/src/components/ErrorLoadingMerchant.tsx b/packages/web-util/src/components/ErrorLoadingMerchant.tsx @@ -22,10 +22,13 @@ import { } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { Attention } from "./Attention.js"; -import { useCommonPreferences, useTranslationContext } from "../index.browser.js"; +import { + useCommonPreferences, + useTranslationContext, +} from "../index.browser.js"; export function ErrorLoading({ error }: { error: TalerError }): VNode { - const [{ showDebugInfo }, ] = useCommonPreferences(); + const [{ showDebugInfo }] = useCommonPreferences(); const { i18n } = useTranslationContext(); switch (error.errorDetail.code) { ////////////////// @@ -177,7 +180,10 @@ export function ErrorLoading({ error }: { error: TalerError }): VNode { const { requestMethod, requestUrl, httpStatusCode, errorResponse } = error.errorDetail; return ( - <Attention type="danger" title={i18n.str`The server's response was unexpected.`}> + <Attention + type="danger" + title={i18n.str`The server's response was unexpected.`} + > {error.message} {showDebugInfo && ( <pre class="whitespace-break-spaces "> diff --git a/packages/web-util/src/components/Footer.tsx b/packages/web-util/src/components/Footer.tsx @@ -16,7 +16,7 @@ export function Footer({ testingUrlKey && typeof localStorage !== "undefined" && localStorage.getItem(testingUrlKey) - ? localStorage.getItem(testingUrlKey) ?? undefined + ? (localStorage.getItem(testingUrlKey) ?? undefined) : undefined; const versionText = VERSION ? ( GIT_HASH ? ( diff --git a/packages/web-util/src/components/LangSelector.tsx b/packages/web-util/src/components/LangSelector.tsx @@ -139,7 +139,7 @@ export function LangSelector({ <ul class="absolute m-0 max-h-60 overflow-auto rounded-md bg-white py-1 text-base text-left shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" tabIndex={-1} - style={type === "icon" ? {marginLeft: -110} : {}} + style={type === "icon" ? { marginLeft: -110 } : {}} role="listbox" aria-labelledby="listbox-label" aria-activedescendant="listbox-option-3" diff --git a/packages/web-util/src/components/Loading.tsx b/packages/web-util/src/components/Loading.tsx @@ -35,7 +35,7 @@ export function Loading(): VNode { function Spinner(): VNode { return ( - <div class="lds-ring m-auto" > + <div class="lds-ring m-auto"> <div /> <div /> <div /> diff --git a/packages/web-util/src/components/NotificationBanner.tsx b/packages/web-util/src/components/NotificationBanner.tsx @@ -119,9 +119,8 @@ export function LocalNotificationBannerBulma({ ) : ( <div>{msg.description[0]}</div> )} - {moreInfo || msg.description.length === 1 ? ( - undefined - ) : ( + {moreInfo || + msg.description.length === 1 ? undefined : ( <a onClick={() => setMoreInfo(true)} type="button" diff --git a/packages/web-util/src/components/NotificationCardBulma.tsx b/packages/web-util/src/components/NotificationCardBulma.tsx @@ -8,7 +8,6 @@ export interface NotificationCard { type: MessageType; } - interface Props { notification?: NotificationCard; } @@ -22,11 +21,13 @@ export function NotificationCardBulma({ <div class="columns is-vcentered"> <div class="column is-12"> <article - class={n.type === "ERROR" - ? "message is-danger" - : n.type === "WARN" - ? "message is-warning" - : "message is-info"} + class={ + n.type === "ERROR" + ? "message is-danger" + : n.type === "WARN" + ? "message is-warning" + : "message is-info" + } > <div class="message-header"> <p>{n.message}</p> diff --git a/packages/web-util/src/components/Pagination.tsx b/packages/web-util/src/components/Pagination.tsx @@ -3,9 +3,9 @@ import { useTranslationContext } from "../index.browser.js"; /** * Common pagination footer for tables. - * - * @param param0 - * @returns + * + * @param param0 + * @returns */ export function Pagination({ onFirstPage, diff --git a/packages/web-util/src/components/ShowInputErrorLabel.tsx b/packages/web-util/src/components/ShowInputErrorLabel.tsx @@ -24,6 +24,10 @@ export function ShowInputErrorLabel({ isDirty: boolean; }): VNode { if (message && isDirty) - return <div class="text-base" style={{ color: "red" }}>{message}</div>; - return <div class="text-base" > </div>; + return ( + <div class="text-base" style={{ color: "red" }}> + {message} + </div> + ); + return <div class="text-base"> </div>; } diff --git a/packages/web-util/src/context/activity.ts b/packages/web-util/src/context/activity.ts @@ -73,7 +73,7 @@ export interface ExchangeLib { export interface BankLib { bank: TalerCoreBankHttpClient; conversion: TalerBankConversionHttpClient; - conversionForUser(username:string): TalerBankConversionHttpClient; + conversionForUser(username: string): TalerBankConversionHttpClient; conversionForClass(classId: number): TalerBankConversionHttpClient; } diff --git a/packages/web-util/src/context/challenger-api.ts b/packages/web-util/src/context/challenger-api.ts @@ -22,7 +22,7 @@ import { LibtoolVersion, ObservabilityEvent, ObservableHttpClientLibrary, - TalerError + TalerError, } from "@gnu-taler/taler-util"; import { ComponentChildren, @@ -37,7 +37,7 @@ import { APIClient, ActiviyTracker, ChallengerLib, - Subscriber + Subscriber, } from "./activity.js"; import { useTranslationContext } from "./translation.js"; @@ -67,7 +67,7 @@ enum VersionHint { type Evictors = { challenger?: CacheEvictor<ChallengerCacheEviction>; -} +}; type ConfigResult<T> = | undefined @@ -178,7 +178,11 @@ function buildChallengerApiClient( }, }); - const challenger = new ChallengerHttpClient(url.href, httpLib, evictors.challenger); + const challenger = new ChallengerHttpClient( + url.href, + httpLib, + evictors.challenger, + ); async function getRemoteConfig(): Promise<ChallengerApi.ChallengerTermsOfServiceResponse> { const resp = await challenger.getConfig(); @@ -186,7 +190,9 @@ function buildChallengerApiClient( if (resp.detail) { throw TalerError.fromUncheckedDetail(resp.detail); } else { - throw TalerError.fromException(new Error("failed to get challenger remote config")) + throw TalerError.fromException( + new Error("failed to get challenger remote config"), + ); } } return resp.body; diff --git a/packages/web-util/src/context/index.ts b/packages/web-util/src/context/index.ts @@ -2,7 +2,7 @@ export { ApiContextProvider, useApiContext } from "./api.js"; export { InternationalizationAPI, TranslationProvider, - useTranslationContext + useTranslationContext, } from "./translation.js"; export * from "./bank-api.js"; export * from "./challenger-api.js"; diff --git a/packages/web-util/src/context/merchant-api.ts b/packages/web-util/src/context/merchant-api.ts @@ -23,7 +23,7 @@ import { TalerMerchantApi, TalerMerchantInstanceCacheEviction, TalerMerchantManagementCacheEviction, - TalerMerchantManagementHttpClient + TalerMerchantManagementHttpClient, } from "@gnu-taler/taler-util"; import { ComponentChildren, @@ -196,7 +196,9 @@ function buildMerchantApiClient( if (resp.detail) { throw TalerError.fromUncheckedDetail(resp.detail); } else { - throw TalerError.fromException(new Error("failed to get merchant remote config")) + throw TalerError.fromException( + new Error("failed to get merchant remote config"), + ); } } return resp.body; diff --git a/packages/web-util/src/context/translation.ts b/packages/web-util/src/context/translation.ts @@ -82,13 +82,15 @@ export const TranslationProvider = ({ forceLang__testing: forceLang, source, }: Props): VNode => { - - const completeness = Object.keys(SUPPORTED_LANGS).reduce((map, lang) => { - if (lang !== "en" && source[lang] && source[lang].completeness ) { - map[lang] = source[lang].completeness - } - return map - }, { en: 100 } as Record<string,number>) + const completeness = Object.keys(SUPPORTED_LANGS).reduce( + (map, lang) => { + if (lang !== "en" && source[lang] && source[lang].completeness) { + map[lang] = source[lang].completeness; + } + return map; + }, + { en: 100 } as Record<string, number>, + ); const { value: lang, update: changeLanguage } = useLang( initial, diff --git a/packages/web-util/src/forms/Dialog.tsx b/packages/web-util/src/forms/Dialog.tsx @@ -1,15 +1,32 @@ import { ComponentChildren, VNode, h } from "preact"; -export function Dialog({ children, onClose }: { onClose?: () => void; children: ComponentChildren }): VNode { - return <div class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true" onClick={onClose}> - <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div> +export function Dialog({ + children, + onClose, +}: { + onClose?: () => void; + children: ComponentChildren; +}): VNode { + return ( + <div + class="relative z-10" + aria-labelledby="modal-title" + role="dialog" + aria-modal="true" + onClick={onClose} + > + <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div> - <div class="fixed inset-0 z-10 w-screen overflow-y-auto"> - <div class="flex min-h-full items-center justify-center p-4 text-center "> - <div class="relative transform overflow-hidden rounded-lg bg-white p-1 text-left shadow-xl transition-all" onClick={(e) => e.stopPropagation()}> - {children} + <div class="fixed inset-0 z-10 w-screen overflow-y-auto"> + <div class="flex min-h-full items-center justify-center p-4 text-center "> + <div + class="relative transform overflow-hidden rounded-lg bg-white p-1 text-left shadow-xl transition-all" + onClick={(e) => e.stopPropagation()} + > + {children} + </div> </div> </div> </div> - </div> + ); } diff --git a/packages/web-util/src/forms/fields/InputInteger.tsx b/packages/web-util/src/forms/fields/InputInteger.tsx @@ -2,9 +2,7 @@ import { VNode, h } from "preact"; import { InputLine } from "./InputLine.js"; import { UIFormProps } from "../FormProvider.js"; -export function InputInteger( - props: UIFormProps<number>, -): VNode { +export function InputInteger(props: UIFormProps<number>): VNode { return ( <InputLine type="number" diff --git a/packages/web-util/src/forms/fields/InputIsoDate.tsx b/packages/web-util/src/forms/fields/InputIsoDate.tsx @@ -134,9 +134,9 @@ export function InputIsoDate( // The date is always *stored* as an ISO date. // !!!!! why? /** - * form and fields should only care about how the information is asked + * form and fields should only care about how the information is asked * to the user and should not care about how is store or sent to the server - * + * * this format here should always be the 'pattern' of the field */ onChange( diff --git a/packages/web-util/src/forms/fields/InputPhone.tsx b/packages/web-util/src/forms/fields/InputPhone.tsx @@ -2,9 +2,7 @@ import { VNode, h } from "preact"; import { InputLine } from "./InputLine.js"; import { UIFormProps } from "../FormProvider.js"; -export function InputPhone( - props: UIFormProps<number>, -): VNode { +export function InputPhone(props: UIFormProps<number>): VNode { return ( <InputLine type="tel" diff --git a/packages/web-util/src/forms/fields/InputSecret.tsx b/packages/web-util/src/forms/fields/InputSecret.tsx @@ -2,8 +2,6 @@ import { VNode, h } from "preact"; import { InputLine } from "./InputLine.js"; import { UIFormProps } from "../FormProvider.js"; -export function InputSecret( - props: UIFormProps<string>, -): VNode { +export function InputSecret(props: UIFormProps<string>): VNode { return <InputLine type="password" {...props} />; } diff --git a/packages/web-util/src/forms/fields/InputSelectMultiple.stories.tsx b/packages/web-util/src/forms/fields/InputSelectMultiple.stories.tsx @@ -102,7 +102,7 @@ export const SimpleComment = tests.createExample(TestedComponent, { }); export const WithInitialValue = tests.createExample(TestedComponent, { initial: { - pets:["one"] + pets: ["one"], }, design, }); diff --git a/packages/web-util/src/forms/fields/InputText.tsx b/packages/web-util/src/forms/fields/InputText.tsx @@ -2,8 +2,6 @@ import { VNode, h } from "preact"; import { UIFormProps } from "../FormProvider.js"; import { InputLine } from "./InputLine.js"; -export function InputText( - props: UIFormProps<string>, -): VNode { +export function InputText(props: UIFormProps<string>): VNode { return <InputLine type="text" {...props} />; } diff --git a/packages/web-util/src/forms/fields/InputToggle.stories.tsx b/packages/web-util/src/forms/fields/InputToggle.stories.tsx @@ -89,22 +89,19 @@ export const StartUndefinedOnlyTwoStates = tests.createExample( }, ); -export const UseTrueValue = tests.createExample( - TestedComponent, - { - initial: {}, - design: { - type: "single-column", - fields: [ - { - type: "toggle", - label: "do you accept?" as TranslatedString, - required: true, - id: "accept", - trueValue: "YES", - onlyTrueValue: true, - }, - ], - }, +export const UseTrueValue = tests.createExample(TestedComponent, { + initial: {}, + design: { + type: "single-column", + fields: [ + { + type: "toggle", + label: "do you accept?" as TranslatedString, + required: true, + id: "accept", + trueValue: "YES", + onlyTrueValue: true, + }, + ], }, -); +}); diff --git a/packages/web-util/src/forms/forms-types.ts b/packages/web-util/src/forms/forms-types.ts @@ -479,7 +479,6 @@ const codecForUiFormVoid = (): Codec<UIFormVoid> => .property("type", codecForConstString("void")) .build("UIFormVoid"); - const codecForUIFormFieldPhone = (): Codec<UIFormFieldPhone> => codecForUIFormFieldBaseConfigTemplate<UIFormFieldPhone>() .property("type", codecForConstString("phone")) diff --git a/packages/web-util/src/forms/forms-ui.tsx b/packages/web-util/src/forms/forms-ui.tsx @@ -52,7 +52,7 @@ export function DefaultForm<T>({ {JSON.stringify( shorten ? redactFileContents(status.result ?? {}) - : status.result ?? {}, + : (status.result ?? {}), undefined, 2, )} diff --git a/packages/web-util/src/forms/gana/VQF_902_14.ts b/packages/web-util/src/forms/gana/VQF_902_14.ts @@ -46,7 +46,7 @@ export function VQF_902_14( type: "textArea", required: true, validator(text, form) { - return !text ? i18n.str`can't be empty` : undefined + return !text ? i18n.str`can't be empty` : undefined; }, }, ], diff --git a/packages/web-util/src/forms/gana/VQF_902_1_customer.stories.tsx b/packages/web-util/src/forms/gana/VQF_902_1_customer.stories.tsx @@ -38,21 +38,22 @@ export default { title: "vqf_902_1_customer" }; export const DisabledForm = tests.createExample(DefaultForm, { disabled: true, initial: { - "CORRESPONDENCE_LANGUAGE": "en", - "CUSTOMER_TYPE": "NATURAL_PERSON", - "CUSTOMER_TYPE_VQF": "NATURAL_PERSON", - "DATE_OF_BIRTH": "1980-01-09", - "DOMICILE_ADDRESS": "asd", - "FORM_ID": "vqf_902_1_customer", - "FORM_VERSION": 1, - "FULL_NAME": "asd", - "NATIONALITY": "AR", - "PERSONAL_IDENTIFICATION_DOCUMENT_COPY": { - "CONTENTS": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=", - "ENCODING": "base64", - "FILENAME": "Glosario-Pagos-Minoristas.pdf", - "MIME_TYPE": "application/pdf" - } + CORRESPONDENCE_LANGUAGE: "en", + CUSTOMER_TYPE: "NATURAL_PERSON", + CUSTOMER_TYPE_VQF: "NATURAL_PERSON", + DATE_OF_BIRTH: "1980-01-09", + DOMICILE_ADDRESS: "asd", + FORM_ID: "vqf_902_1_customer", + FORM_VERSION: 1, + FULL_NAME: "asd", + NATIONALITY: "AR", + PERSONAL_IDENTIFICATION_DOCUMENT_COPY: { + CONTENTS: + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=", + ENCODING: "base64", + FILENAME: "Glosario-Pagos-Minoristas.pdf", + MIME_TYPE: "application/pdf", + }, }, design: design_VQF_902_1_customer(i18n), }); diff --git a/packages/web-util/src/forms/gana/VQF_902_1_customer.ts b/packages/web-util/src/forms/gana/VQF_902_1_customer.ts @@ -15,13 +15,7 @@ */ import { TalerFormAttributes } from "@gnu-taler/taler-util"; -import { - format, - intervalToDuration, - isFuture, - isValid, - parse -} from "date-fns"; +import { format, intervalToDuration, isFuture, isValid, parse } from "date-fns"; import { DoubleColumnFormDesign, InternationalizationAPI, @@ -78,7 +72,7 @@ export function design_VQF_902_1_customer( i18n: InternationalizationAPI, ): DoubleColumnFormDesign { const today = format(new Date(), "yyyy-MM-dd"); - + return { type: "double-column", title: i18n.str`Identification form (basic customer information)`, diff --git a/packages/web-util/src/forms/gana/VQF_902_1_officer.ts b/packages/web-util/src/forms/gana/VQF_902_1_officer.ts @@ -15,7 +15,14 @@ */ import { TalerFormAttributes } from "@gnu-taler/taler-util"; -import { format, intervalToDuration, isFuture, isToday, isValid, parse } from "date-fns"; +import { + format, + intervalToDuration, + isFuture, + isToday, + isValid, + parse, +} from "date-fns"; import { DoubleColumnFormDesign, FormMetadata, @@ -137,7 +144,7 @@ export function VQF_902_1_officer( start: time, end: new Date(), }); - if ( years && years > 120) { + if (years && years > 120) { return i18n.str`it can't be greater than 120 years`; } return undefined; diff --git a/packages/web-util/src/forms/gana/VQF_902_9_customer.ts b/packages/web-util/src/forms/gana/VQF_902_9_customer.ts @@ -84,7 +84,7 @@ export function VQF_902_9_customer( start: time, end: new Date(), }); - if (years && years > 120) { + if (years && years > 120) { return i18n.str`it can't be greater than 120 years`; } return undefined; diff --git a/packages/web-util/src/forms/gana/VQF_902_9_officer.ts b/packages/web-util/src/forms/gana/VQF_902_9_officer.ts @@ -82,7 +82,7 @@ export function VQF_902_9_officer( start: time, end: new Date(), }); - if (years && years > 120) { + if (years && years > 120) { return i18n.str`it can't be greater than 120 years`; } return undefined; diff --git a/packages/web-util/src/forms/gana/accept-tos.ts b/packages/web-util/src/forms/gana/accept-tos.ts @@ -43,8 +43,8 @@ export type AcceptTermOfServiceContext = { tosVersion?: string; }; -function normalize(str:string) { - return str.replace(/ /g, "-") +function normalize(str: string) { + return str.replace(/ /g, "-"); } /** * @@ -57,7 +57,9 @@ export function acceptTos( context: AcceptTermOfServiceContext, ): SingleColumnFormDesign { const myFields: UIFormElementConfig[] = []; - const tosFileName = ! context.provider_name ? "TermsOfService.pdf" : `${normalize(context.provider_name)}_TermsOfService.PDF`; + const tosFileName = !context.provider_name + ? "TermsOfService.pdf" + : `${normalize(context.provider_name)}_TermsOfService.PDF`; if (context.link_only) { myFields.push({ type: "external-link", diff --git a/packages/web-util/src/forms/gana/gls_merchant_onboarding.ts b/packages/web-util/src/forms/gana/gls_merchant_onboarding.ts @@ -364,14 +364,15 @@ export function gls_merchant_onboarding( fields: [ { type: "caption", - label: "Please complete the customer registration and identification for the authorized representative and other persons listed in this form.", + label: + "Please complete the customer registration and identification for the authorized representative and other persons listed in this form.", }, { type: "external-link", url: "https://kontoeroeffnung.gls.de/kundenanlage/gks-v", id: "none", label: "GLS Customer Registration", - } + }, ], }, ], diff --git a/packages/web-util/src/hooks/useAsync.ts b/packages/web-util/src/hooks/useAsync.ts @@ -138,8 +138,7 @@ export function useLongPolling<Res>( }); } - return () => { - }; + return () => {}; }, [result]); /** diff --git a/packages/web-util/src/hooks/useAsyncAsHook.ts b/packages/web-util/src/hooks/useAsyncAsHook.ts @@ -45,9 +45,9 @@ export type HookResponseWithRetry<T> = | ((HookOk<T> | HookError) & WithRetry) | undefined; - /** - * @deprecated use useAsyncWithRetry - */ +/** + * @deprecated use useAsyncWithRetry + */ export function useAsyncAsHook<T>( fn: () => Promise<T | false>, deps?: any[], @@ -95,16 +95,16 @@ export function useAsyncAsHook<T>( /** * @deprecated - * + * * Convert an async function named $fetcher into a hook behavior * with a retry function condition. - * - * The $retry function is called every time $fetcher finalize + * + * The $retry function is called every time $fetcher finalize * and if $retry returns true the $fetcher is called again - * - * @param fetcher - * @param retry - * @returns + * + * @param fetcher + * @param retry + * @returns */ export function useAsyncWithRetry<Res>( fetcher: (() => Promise<Res>) | undefined, diff --git a/packages/web-util/src/hooks/useLang.ts b/packages/web-util/src/hooks/useLang.ts @@ -23,44 +23,59 @@ import { /** * If the translation is under this threshold then * browser won't automatically switch to default lang. - * + * */ const MIN_LANG_COVERAGE_THRESHOLD = 85; /** * choose the best from the browser config based on the completeness * on the translation */ -function getBrowserLang(completeness: Record<string, number>): string | undefined { +function getBrowserLang( + completeness: Record<string, number>, +): string | undefined { if (typeof window === "undefined") return undefined; if (window.navigator.language) { - if (completeness[window.navigator.language] >= MIN_LANG_COVERAGE_THRESHOLD) { - return window.navigator.language + if ( + completeness[window.navigator.language] >= MIN_LANG_COVERAGE_THRESHOLD + ) { + return window.navigator.language; } } if (window.navigator.languages) { - const match = Object.entries(completeness).filter(([code, value]) => { - if (value < MIN_LANG_COVERAGE_THRESHOLD) return false; //do not consider langs below 90% - return window.navigator.languages.findIndex(l => l.startsWith(code)) !== -1 - }).map(([code, value]) => ({ code, value })) + const match = Object.entries(completeness) + .filter(([code, value]) => { + if (value < MIN_LANG_COVERAGE_THRESHOLD) return false; //do not consider langs below 90% + return ( + window.navigator.languages.findIndex((l) => l.startsWith(code)) !== -1 + ); + }) + .map(([code, value]) => ({ code, value })); if (match.length > 0) { - let max = match[0] - match.forEach(v => { + let max = match[0]; + match.forEach((v) => { if (v.value > max.value) { - max = v + max = v; } - }) - return max.code + }); + return max.code; } - }; + } return undefined; } const langPreferenceKey = buildStorageKey("lang-preference"); -export function useLang(initial: string | undefined, completeness: Record<string, number>): Required<StorageState> { - const defaultValue = (getBrowserLang(completeness) || initial || "en").substring(0, 2); +export function useLang( + initial: string | undefined, + completeness: Record<string, number>, +): Required<StorageState> { + const defaultValue = ( + getBrowserLang(completeness) || + initial || + "en" + ).substring(0, 2); return useLocalStorage(langPreferenceKey, defaultValue); } diff --git a/packages/web-util/src/hooks/useLocalStorage.ts b/packages/web-util/src/hooks/useLocalStorage.ts @@ -128,12 +128,16 @@ export function useLocalStorage<Type = string>( }; } -function convert<Type>(updated: string | undefined, key: StorageKey<Type>, defaultValue?: Type): Type | undefined { +function convert<Type>( + updated: string | undefined, + key: StorageKey<Type>, + defaultValue?: Type, +): Type | undefined { if (updated === undefined) return defaultValue; //optional try { return key.codec.decode(JSON.parse(updated)); } catch (e) { - console.error("Decoding error", e) + console.error("Decoding error", e); //decode error return defaultValue; } diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts @@ -459,9 +459,9 @@ function sanitizeFunctionArguments(args: any[]): string { .join(", "); } -interface AppEvents<Errors,Args> { - 'on-success': { userId: string; timestamp: number }; - 'on-fail': undefined; // Or void if no payload +interface AppEvents<Errors, Args> { + "on-success": { userId: string; timestamp: number }; + "on-fail": undefined; // Or void if no payload } /** diff --git a/packages/web-util/src/index.build.ts b/packages/web-util/src/index.build.ts @@ -100,7 +100,7 @@ function buildTimePlugin() { throw Error("esbuild build options does not specify outdir"); } build.onEnd(() => { - const destination = path.join(outDir, 'build-time.txt'); + const destination = path.join(outDir, "build-time.txt"); fs.writeFileSync(destination, new Date().toUTCString()); }); }, @@ -263,7 +263,7 @@ function getPackageAndGitRoot(meta: undefined | ImportMeta) { GIT_ROOT = path.join(GIT_ROOT, "../"); } if (GIT_ROOT === "/") { - return { version: 'not defined', hash: 'not defined', baseDir } + return { version: "not defined", hash: "not defined", baseDir }; } const hash = git_hash(GIT_ROOT); @@ -350,15 +350,17 @@ export async function build(config: BuildParams) { const res = await esbuild.build(esBuildOptions); fs.writeFileSync(`${esBuildOptions.outdir}/version.txt`, version); if (res.metafile) { - fs.writeFileSync(`${esBuildOptions.outdir}/build-metadata.json`, JSON.stringify(res.metafile)); + fs.writeFileSync( + `${esBuildOptions.outdir}/build-metadata.json`, + JSON.stringify(res.metafile), + ); } return res; } -const liveReloadType = process.env.SERVER_DIR ? "poll" : "ws" +const liveReloadType = process.env.SERVER_DIR ? "poll" : "ws"; -const LIVE_RELOAD_SCRIPT = - `./node_modules/@gnu-taler/web-util/lib/live-reload-${liveReloadType}.mjs`; +const LIVE_RELOAD_SCRIPT = `./node_modules/@gnu-taler/web-util/lib/live-reload-${liveReloadType}.mjs`; const LIVE_RELOAD_SCRIPT_LOCALLY = `./lib/live-reload-${liveReloadType}.mjs`; /** @@ -388,7 +390,7 @@ export function initializeDev( ): () => Promise<esbuild.BuildResult> { function buildDevelopment() { const { esBuildOptions } = computeConfig(config); - esBuildOptions.plugins?.push(buildTimePlugin()) + esBuildOptions.plugins?.push(buildTimePlugin()); if (!options.dontDoLiveReload) { esBuildOptions.inject = [LIVE_RELOAD_SCRIPT]; } diff --git a/packages/web-util/src/utils/buildPaginatedResult.ts b/packages/web-util/src/utils/buildPaginatedResult.ts @@ -5,7 +5,7 @@ export type PaginationControl = { loadNext?(): void; loadPrev?(): void; loadFirst?(): void; -} +}; export type PaginatedResult<T> = OperationOk<T> & PaginationControl; /** @@ -56,12 +56,12 @@ export function buildPaginatedResult<R>( /** * based on the pointer and the max result set - * + * * return relative pos and list to show - * @param data - * @param offset - * @param max - * @returns + * @param data + * @param offset + * @param max + * @returns */ function __compute_for_ui<R>(data: Array<R>, offset: ListPointer, max: number) { // we ask for N but show N-1 diff --git a/packages/web-util/src/utils/http-impl.browser.ts b/packages/web-util/src/utils/http-impl.browser.ts @@ -97,7 +97,7 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary { const myBody = !options?.compress || !encodedBody ? encodedBody - : (await compress(options.compress, encodedBody)); + : await compress(options.compress, encodedBody); const requestHeadersMap = getDefaultHeaders(requestMethod); if (requestHeader) { @@ -108,7 +108,7 @@ export class BrowserHttpLibDepreacted implements HttpRequestLibrary { } if (options?.compress) { - requestHeadersMap["Content-Encoding"] = options.compress + requestHeadersMap["Content-Encoding"] = options.compress; } return new Promise<HttpResponse>((resolve, reject) => { @@ -272,4 +272,4 @@ export async function compress( writer.write(buf); writer.close(); return new Response(cs.readable).arrayBuffer(); -} -\ No newline at end of file +} diff --git a/packages/web-util/src/utils/observable.ts b/packages/web-util/src/utils/observable.ts @@ -247,11 +247,11 @@ function onBrowserStorageUpdate(cb: (changes: Changes) => void): void { export function browserStorageMap( backend: ObservableMap<string, string>, ): ObservableMap<string, string> { - getAllContent().then(content => { + getAllContent().then((content) => { Object.entries(content ?? {}).forEach(([k, v]) => { backend.set(k, v as string); }); - }) + }); backend.onAnyUpdate(async () => { const result: Record<string, string> = {}; diff --git a/packages/web-util/src/utils/route.ts b/packages/web-util/src/utils/route.ts @@ -28,9 +28,9 @@ export type EmptyObject = Record<string, never>; /** * FIXME: receive parameters * maybe return URL for reverse function instead of string - * @param pattern - * @param reverse - * @returns + * @param pattern + * @param reverse + * @returns */ export function urlPattern< T extends Record<string, string | undefined> = EmptyObject, @@ -106,10 +106,8 @@ export function findMatch<T extends ObjectOf<RouteDefinition>>( * get the type of the params of a location * */ -type RouteParamsType< - RouteType, - Key extends keyof RouteType, -> = RouteType[Key] extends RouteDefinition<infer ParamType> ? ParamType : never; +type RouteParamsType<RouteType, Key extends keyof RouteType> = + RouteType[Key] extends RouteDefinition<infer ParamType> ? ParamType : never; /** * Helps to create a map of a type with the key