From 70151490bd79d38f8064b720fc124d1774a18235 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 5 Apr 2024 10:30:19 -0300 Subject: fix listing, add cache invalidation, fix codec for accounts --- packages/taler-util/src/http-client/merchant.ts | 173 ++++++++++++++++++------ packages/taler-util/src/http-client/types.ts | 4 +- packages/taler-util/src/time.ts | 6 + 3 files changed, 141 insertions(+), 42 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts index cfe3155d1..23d7c76df 100644 --- a/packages/taler-util/src/http-client/merchant.ts +++ b/packages/taler-util/src/http-client/merchant.ts @@ -81,9 +81,36 @@ export type TalerMerchantInstanceErrorsByMethod< export enum TalerMerchantInstanceCacheEviction { CREATE_ORDER, + UPDATE_ORDER, + DELETE_ORDER, + UPDATE_CURRENT_INSTANCE, + DELETE_CURRENT_INSTANCE, + CREATE_BANK_ACCOUNT, + UPDATE_BANK_ACCOUNT, + DELETE_BANK_ACCOUNT, + CREATE_PRODUCT, + UPDATE_PRODUCT, + DELETE_PRODUCT, + CREATE_TRANSFER, + DELETE_TRANSFER, + CREATE_DEVICE, + UPDATE_DEVICE, + DELETE_DEVICE, + CREATE_TEMPLATE, + UPDATE_TEMPLATE, + DELETE_TEMPLATE, + CREATE_WEBHOOK, + UPDATE_WEBHOOK, + DELETE_WEBHOOK, + CREATE_TOKENFAMILY, + UPDATE_TOKENFAMILY, + DELETE_TOKENFAMILY, + LAST, } export enum TalerMerchantManagementCacheEviction { - CREATE_INSTANCE, + CREATE_INSTANCE = TalerMerchantInstanceCacheEviction.LAST + 1, + UPDATE_INSTANCE, + DELETE_INSTANCE, } /** * Protocol version spoken with the core bank. @@ -150,8 +177,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForClaimResponse()); + } case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -173,8 +202,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForPaymentResponse()); + } case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.PaymentRequired: @@ -274,8 +305,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForPaidRefundStatusResponse()); + } case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: @@ -302,8 +335,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForAbortResponse()); + } case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: @@ -330,8 +365,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForWalletRefundResponse()); + } case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: @@ -399,8 +436,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -461,8 +500,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -550,8 +591,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT); return opSuccessFromHttp(resp, codecForAccountAddResponse()); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -583,8 +626,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -669,8 +714,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -704,8 +751,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_PRODUCT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: // FIXME: missing in docs @@ -738,8 +787,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -831,8 +882,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -860,8 +913,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_PRODUCT); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1049,8 +1104,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opEmptySuccess(resp); + } case HttpStatusCode.NoContent: return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: // FIXME: missing in docs @@ -1082,8 +1139,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_ORDER); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1120,8 +1179,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER); return opSuccessFromHttp(resp, codecForMerchantRefundResponse()); + } case HttpStatusCode.Forbidden: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Unauthorized: // FIXME: missing in docs @@ -1161,8 +1222,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TRANSFER); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1234,8 +1297,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TRANSFER); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1271,8 +1336,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_DEVICE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1302,8 +1369,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_DEVICE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1396,8 +1465,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_DEVICE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1430,8 +1501,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1461,8 +1534,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1544,8 +1619,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1615,8 +1692,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1647,8 +1726,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1731,8 +1812,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1766,8 +1849,10 @@ export class TalerMerchantInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TOKENFAMILY); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1797,8 +1882,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TOKENFAMILY); return opSuccessFromHttp(resp, codecForTokenFamilyDetails()); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1883,8 +1970,10 @@ export class TalerMerchantInstanceHttpClient { headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TOKENFAMILY); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -1913,15 +2002,15 @@ export type TalerMerchantManagementErrorsByMethod< > = FailCasesByMethod; export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttpClient { - readonly cacheManagementEvictor: CacheEvictor; + readonly cacheManagementEvictor: CacheEvictor; constructor( readonly baseUrl: string, httpClient?: HttpRequestLibrary, - cacheManagementEvictor?: CacheEvictor, - cacheEvictor?: CacheEvictor, + // cacheManagementEvictor?: CacheEvictor, + cacheEvictor?: CacheEvictor, ) { super(baseUrl, httpClient, cacheEvictor); - this.cacheManagementEvictor = cacheManagementEvictor ?? nullEvictor; + this.cacheManagementEvictor = cacheEvictor ?? nullEvictor; } getSubInstanceAPI(instanceId: string) { @@ -1953,9 +2042,7 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp switch (resp.status) { case HttpStatusCode.NoContent: { - this.cacheManagementEvictor.notifySuccess( - TalerMerchantManagementCacheEviction.CREATE_INSTANCE, - ); + this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.CREATE_INSTANCE); return opEmptySuccess(resp); } case HttpStatusCode.Unauthorized: // FIXME: missing in docs @@ -2022,8 +2109,10 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.UPDATE_INSTANCE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -2112,8 +2201,10 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp headers, }); switch (resp.status) { - case HttpStatusCode.NoContent: + case HttpStatusCode.NoContent: { + this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.DELETE_INSTANCE); return opEmptySuccess(resp); + } case HttpStatusCode.Unauthorized: // FIXME: missing in docs return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts index dd2161deb..ea7ba341b 100644 --- a/packages/taler-util/src/http-client/types.ts +++ b/packages/taler-util/src/http-client/types.ts @@ -777,7 +777,7 @@ export const codecForTransferDetails = .property("payto_uri", codecForPaytoString()) .property("exchange_url", codecForURL()) .property("transfer_serial_id", codecForNumber()) - .property("execution_time", codecForTimestamp) + .property("execution_time", codecOptional(codecForTimestamp)) .property("verified", codecOptional(codecForBoolean())) .property("confirmed", codecOptional(codecForBoolean())) .build("TalerMerchantApi.TransferDetails"); @@ -3781,6 +3781,8 @@ export namespace TalerMerchantApi { // List of accounts that are known for the instance. accounts: BankAccountSummaryEntry[]; } + + // TODO: missing in docs export interface BankAccountSummaryEntry { // payto:// URI of the account. payto_uri: PaytoString; diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts index 2e24856ee..95b4911a0 100644 --- a/packages/taler-util/src/time.ts +++ b/packages/taler-util/src/time.ts @@ -604,6 +604,9 @@ export function durationAdd(d1: Duration, d2: Duration): Duration { export const codecForAbsoluteTime: Codec = { decode(x: any, c?: Context): AbsoluteTime { + if (x === undefined) { + throw Error(`got undefined and expected absolute time at ${renderContext(c)}`); + } const t_ms = x.t_ms; if (typeof t_ms === "string") { if (t_ms === "never") { @@ -619,6 +622,9 @@ export const codecForAbsoluteTime: Codec = { export const codecForTimestamp: Codec = { decode(x: any, c?: Context): TalerProtocolTimestamp { // Compatibility, should be removed soon. + if (x === undefined) { + throw Error(`got undefined and expected timestamp at ${renderContext(c)}`); + } const t_ms = x.t_ms; if (typeof t_ms === "string") { if (t_ms === "never") { -- cgit v1.2.3