summaryrefslogtreecommitdiff
path: root/backoffice/index.js
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-10 00:04:51 -0300
committerSebastian <sebasjm@gmail.com>2024-04-10 00:04:51 -0300
commit240d647da85de6b575d15c37efec04757541e3dc (patch)
tree97b843adb1d58dcfa1e9975f8bcca0bf949ae08c /backoffice/index.js
parent4de26eda8131028d64a0b8189ad3ee2624862c6a (diff)
downloadwallet-core-240d647da85de6b575d15c37efec04757541e3dc.tar.gz
wallet-core-240d647da85de6b575d15c37efec04757541e3dc.tar.bz2
wallet-core-240d647da85de6b575d15c37efec04757541e3dc.zip
built from de32e0217c54f26a54813f56c378155bcacf4416
Diffstat (limited to 'backoffice/index.js')
-rw-r--r--backoffice/index.js13008
1 files changed, 7946 insertions, 5062 deletions
diff --git a/backoffice/index.js b/backoffice/index.js
index 0f6480523..915c5dba0 100644
--- a/backoffice/index.js
+++ b/backoffice/index.js
@@ -9504,12 +9504,21 @@ var TalerErrorCode;
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED"] = 2175] = "MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH"] = 2200] = "MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID"] = 2201] = "MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_TOKEN_FAMILY_CONFLICT"] = 2225] = "MERCHANT_POST_TOKEN_FAMILY_CONFLICT";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_PATCH_TOKEN_FAMILY_NOT_FOUND"] = 2226] = "MERCHANT_PATCH_TOKEN_FAMILY_NOT_FOUND";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED"] = 2251] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED"] = 2252] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND"] = 2253] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE"] = 2254] = "MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH"] = 2255] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY"] = 2256] = "MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_AWAITING_KEYS"] = 2258] = "MERCHANT_EXCHANGE_TRANSFERS_AWAITING_KEYS";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_AWAITING_LIST"] = 2259] = "MERCHANT_EXCHANGE_TRANSFERS_AWAITING_LIST";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_FATAL_NO_EXCHANGE"] = 2260] = "MERCHANT_EXCHANGE_TRANSFERS_FATAL_NO_EXCHANGE";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_FATAL_NOT_FOUND"] = 2261] = "MERCHANT_EXCHANGE_TRANSFERS_FATAL_NOT_FOUND";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_RATE_LIMITED"] = 2262] = "MERCHANT_EXCHANGE_TRANSFERS_RATE_LIMITED";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_TRANSIENT_FAILURE"] = 2263] = "MERCHANT_EXCHANGE_TRANSFERS_TRANSIENT_FAILURE";
+ TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_HARD_FAILURE"] = 2264] = "MERCHANT_EXCHANGE_TRANSFERS_HARD_FAILURE";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND"] = 2300] = "MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED"] = 2301] = "MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED";
TalerErrorCode2[TalerErrorCode2["MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE"] = 2302] = "MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE";
@@ -9545,13 +9554,6 @@ var TalerErrorCode;
TalerErrorCode2[TalerErrorCode2["MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND"] = 2555] = "MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND";
TalerErrorCode2[TalerErrorCode2["MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED"] = 2556] = "MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED";
TalerErrorCode2[TalerErrorCode2["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION"] = 2557] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_AWAITING_KEYS"] = 2258] = "MERCHANT_EXCHANGE_TRANSFERS_AWAITING_KEYS";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_AWAITING_LIST"] = 2259] = "MERCHANT_EXCHANGE_TRANSFERS_AWAITING_LIST";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_FATAL_NO_EXCHANGE"] = 2260] = "MERCHANT_EXCHANGE_TRANSFERS_FATAL_NO_EXCHANGE";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_FATAL_NOT_FOUND"] = 2261] = "MERCHANT_EXCHANGE_TRANSFERS_FATAL_NOT_FOUND";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_RATE_LIMITED"] = 2262] = "MERCHANT_EXCHANGE_TRANSFERS_RATE_LIMITED";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_TRANSIENT_FAILURE"] = 2263] = "MERCHANT_EXCHANGE_TRANSFERS_TRANSIENT_FAILURE";
- TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_HARD_FAILURE"] = 2264] = "MERCHANT_EXCHANGE_TRANSFERS_HARD_FAILURE";
TalerErrorCode2[TalerErrorCode2["MERCHANT_EXCHANGE_TRANSFERS_CONFLICTING_TRANSFERS"] = 2563] = "MERCHANT_EXCHANGE_TRANSFERS_CONFLICTING_TRANSFERS";
TalerErrorCode2[TalerErrorCode2["MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS"] = 2600] = "MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS";
TalerErrorCode2[TalerErrorCode2["MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH"] = 2601] = "MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH";
@@ -9679,6 +9681,8 @@ var TalerErrorCode;
TalerErrorCode2[TalerErrorCode2["WALLET_EXCHANGE_UNAVAILABLE"] = 7032] = "WALLET_EXCHANGE_UNAVAILABLE";
TalerErrorCode2[TalerErrorCode2["WALLET_EXCHANGE_ENTRY_USED"] = 7033] = "WALLET_EXCHANGE_ENTRY_USED";
TalerErrorCode2[TalerErrorCode2["WALLET_DB_UNAVAILABLE"] = 7034] = "WALLET_DB_UNAVAILABLE";
+ TalerErrorCode2[TalerErrorCode2["WALLET_TALER_URI_MALFORMED"] = 7035] = "WALLET_TALER_URI_MALFORMED";
+ TalerErrorCode2[TalerErrorCode2["WALLET_CORE_REQUEST_CANCELLED"] = 7036] = "WALLET_CORE_REQUEST_CANCELLED";
TalerErrorCode2[TalerErrorCode2["ANASTASIS_GENERIC_BACKEND_TIMEOUT"] = 8e3] = "ANASTASIS_GENERIC_BACKEND_TIMEOUT";
TalerErrorCode2[TalerErrorCode2["ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST"] = 8001] = "ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST";
TalerErrorCode2[TalerErrorCode2["ANASTASIS_GENERIC_BACKEND_ERROR"] = 8002] = "ANASTASIS_GENERIC_BACKEND_ERROR";
@@ -9746,6 +9750,8 @@ var TalerErrorCode;
TalerErrorCode2[TalerErrorCode2["ANASTASIS_REDUCER_INTERNAL_ERROR"] = 8419] = "ANASTASIS_REDUCER_INTERNAL_ERROR";
TalerErrorCode2[TalerErrorCode2["ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED"] = 8420] = "ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED";
TalerErrorCode2[TalerErrorCode2["DONAU_GENERIC_KEYS_MISSING"] = 8607] = "DONAU_GENERIC_KEYS_MISSING";
+ TalerErrorCode2[TalerErrorCode2["DONAU_CHARITY_SIGNATURE_INVALID"] = 8608] = "DONAU_CHARITY_SIGNATURE_INVALID";
+ TalerErrorCode2[TalerErrorCode2["DONAU_CHARITY_NOT_FOUND"] = 8609] = "DONAU_CHARITY_NOT_FOUND";
TalerErrorCode2[TalerErrorCode2["LIBEUFIN_NEXUS_GENERIC_ERROR"] = 9e3] = "LIBEUFIN_NEXUS_GENERIC_ERROR";
TalerErrorCode2[TalerErrorCode2["LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION"] = 9001] = "LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION";
TalerErrorCode2[TalerErrorCode2["LIBEUFIN_SANDBOX_GENERIC_ERROR"] = 9500] = "LIBEUFIN_SANDBOX_GENERIC_ERROR";
@@ -9941,6 +9947,38 @@ var amountFractionalBase = 1e8;
var amountFractionalLength = 8;
var amountMaxValue = 2 ** 52;
var FRAC_SEPARATOR = ".";
+var Amount = class _Amount {
+ static from(a5) {
+ return new _Amount(Amounts.parseOrThrow(a5), 0);
+ }
+ static zeroOfCurrency(currency) {
+ return new _Amount(Amounts.zeroOfCurrency(currency), 0);
+ }
+ add(...a5) {
+ if (this.saturated) {
+ return this;
+ }
+ const r3 = Amounts.add(this.val, ...a5);
+ return new _Amount(r3.amount, r3.saturated ? 1 : 0);
+ }
+ mult(n2) {
+ if (this.saturated) {
+ return this;
+ }
+ const r3 = Amounts.mult(this, n2);
+ return new _Amount(r3.amount, r3.saturated ? 1 : 0);
+ }
+ toJson() {
+ return { ...this.val };
+ }
+ toString() {
+ return Amounts.stringify(this.val);
+ }
+ constructor(val, saturated) {
+ this.val = val;
+ this.saturated = saturated;
+ }
+};
function codecForAmountString() {
return {
decode(x6, c4) {
@@ -9984,6 +10022,9 @@ var Amounts = class _Amounts {
if (typeof amt === "string") {
return _Amounts.parseOrThrow(amt);
}
+ if (amt instanceof Amount) {
+ return amt.toJson();
+ }
return amt;
}
static divmod(a1, a22) {
@@ -10203,6 +10244,9 @@ var Amounts = class _Amounts {
* throw if the input is not a valid amount.
*/
static parseOrThrow(s5) {
+ if (s5 instanceof Amount) {
+ return s5.toJson();
+ }
if (typeof s5 === "object") {
if (typeof s5.currency !== "string") {
throw Error("invalid amount object");
@@ -11977,14 +12021,21 @@ function parseURL(input, options) {
});
}
var URLImpl = class {
+ //Include URL type for "url" and "base" params.
constructor(url, base2) {
let parsedBase = null;
if (base2 !== void 0) {
+ if (base2 instanceof URL) {
+ base2 = base2.href;
+ }
parsedBase = basicURLParse(base2);
if (parsedBase === null) {
throw new TypeError(`Invalid base URL: ${base2}`);
}
}
+ if (url instanceof URL) {
+ url = url.href;
+ }
const parsedURL = basicURLParse(url, { baseURL: parsedBase });
if (parsedURL === null) {
throw new TypeError(`Invalid URL: ${url}`);
@@ -12162,7 +12213,7 @@ if (useOwnUrlImp || !_URLSearchParams) {
globalThis.URLSearchParams = URLSearchParamsImpl;
_URLSearchParams = URLSearchParamsImpl;
}
-var URLSearchParams = _URLSearchParams;
+var URLSearchParams2 = _URLSearchParams;
// ../taler-util/lib/helpers.js
function canonicalizeBaseUrl(url) {
@@ -12467,9 +12518,69 @@ var ObjectCodecBuilder = class {
};
}
};
+var UnionCodecBuilder = class {
+ constructor(discriminator, baseCodec) {
+ this.discriminator = discriminator;
+ this.baseCodec = baseCodec;
+ this.alternatives = /* @__PURE__ */ new Map();
+ }
+ /**
+ * Define a property for the object.
+ */
+ alternative(tagValue, codec) {
+ if (!codec) {
+ throw Error("inner codec must be defined");
+ }
+ this.alternatives.set(tagValue, { codec, tagValue });
+ return this;
+ }
+ /**
+ * Return the built codec.
+ *
+ * @param objectDisplayName name of the object that this codec operates on,
+ * used in error messages.
+ */
+ build(objectDisplayName) {
+ const alternatives = this.alternatives;
+ const discriminator = this.discriminator;
+ const baseCodec = this.baseCodec;
+ return {
+ decode(x6, c4) {
+ if (!c4) {
+ c4 = {
+ path: [`(${objectDisplayName})`]
+ };
+ }
+ const d5 = x6[discriminator];
+ if (d5 === void 0) {
+ throw new DecodingError(`expected tag for ${objectDisplayName} at ${renderContext(c4)}.${String(discriminator)}`);
+ }
+ const alt = alternatives.get(d5);
+ if (!alt) {
+ throw new DecodingError(`unknown tag for ${objectDisplayName} ${d5} at ${renderContext(c4)}.${String(discriminator)}`);
+ }
+ const altDecoded = alt.codec.decode(x6);
+ if (baseCodec) {
+ const baseDecoded = baseCodec.decode(x6, c4);
+ return { ...baseDecoded, ...altDecoded };
+ } else {
+ return altDecoded;
+ }
+ }
+ };
+ }
+};
+var UnionCodecPreBuilder = class {
+ discriminateOn(discriminator, baseCodec) {
+ return new UnionCodecBuilder(discriminator, baseCodec);
+ }
+};
function buildCodecForObject() {
return new ObjectCodecBuilder();
}
+function buildCodecForUnion() {
+ return new UnionCodecPreBuilder();
+}
function codecForMap(innerCodec) {
if (!innerCodec) {
throw Error("inner codec must be defined");
@@ -12487,6 +12598,23 @@ function codecForMap(innerCodec) {
}
};
}
+function codecForList(innerCodec) {
+ if (!innerCodec) {
+ throw Error("inner codec must be defined");
+ }
+ return {
+ decode(x6, c4) {
+ const arr = [];
+ if (!Array.isArray(x6)) {
+ throw new DecodingError(`expected array at ${renderContext(c4)}`);
+ }
+ for (const i4 in x6) {
+ arr.push(innerCodec.decode(x6[i4], joinContext(c4, `[${i4}]`)));
+ }
+ return arr;
+ }
+ };
+}
function codecForNumber() {
return {
decode(x6, c4) {
@@ -12537,6 +12665,16 @@ function codecForConstString(s5) {
}
};
}
+function codecForConstNumber(n2) {
+ return {
+ decode(x6, c4) {
+ if (x6 === n2) {
+ return x6;
+ }
+ throw new DecodingError(`expected number constant "${n2}" at ${renderContext(c4)} but got ${typeof x6}`);
+ }
+ };
+}
function codecOptional(innerCodec) {
return {
decode(x6, c4) {
@@ -13031,7 +13169,17 @@ var Duration;
return Math.ceil(d5.d_ms / 1e3 / 60 / 60 / 24 / 365);
}
Duration2.toIntegerYears = toIntegerYears;
- Duration2.fromSpec = durationFromSpec;
+ function fromSpec(spec) {
+ let d_ms = 0;
+ d_ms += (spec.seconds ?? 0) * SECONDS;
+ d_ms += (spec.minutes ?? 0) * MINUTES;
+ d_ms += (spec.hours ?? 0) * HOURS;
+ d_ms += (spec.days ?? 0) * DAYS;
+ d_ms += (spec.months ?? 0) * MONTHS;
+ d_ms += (spec.years ?? 0) * YEARS;
+ return { d_ms };
+ }
+ Duration2.fromSpec = fromSpec;
function getForever() {
return { d_ms: "forever" };
}
@@ -13074,36 +13222,36 @@ var Duration;
Duration2.clamp = clamp;
})(Duration || (Duration = {}));
var AbsoluteTime;
-(function(AbsoluteTime2) {
+(function(AbsoluteTime3) {
function getStampMsNow() {
return (/* @__PURE__ */ new Date()).getTime();
}
- AbsoluteTime2.getStampMsNow = getStampMsNow;
+ AbsoluteTime3.getStampMsNow = getStampMsNow;
function getStampMsNever() {
return Number.MAX_SAFE_INTEGER;
}
- AbsoluteTime2.getStampMsNever = getStampMsNever;
+ AbsoluteTime3.getStampMsNever = getStampMsNever;
function now2() {
return {
t_ms: (/* @__PURE__ */ new Date()).getTime() + timeshift,
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.now = now2;
+ AbsoluteTime3.now = now2;
function never() {
return {
t_ms: "never",
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.never = never;
+ AbsoluteTime3.never = never;
function fromMilliseconds(ms) {
return {
t_ms: ms,
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.fromMilliseconds = fromMilliseconds;
+ AbsoluteTime3.fromMilliseconds = fromMilliseconds;
function cmp(t1, t22) {
if (t1.t_ms === "never") {
if (t22.t_ms === "never") {
@@ -13122,7 +13270,7 @@ var AbsoluteTime;
}
return -1;
}
- AbsoluteTime2.cmp = cmp;
+ AbsoluteTime3.cmp = cmp;
function min(t1, t22) {
if (t1.t_ms === "never") {
return { t_ms: t22.t_ms, [opaque_AbsoluteTime]: true };
@@ -13132,7 +13280,7 @@ var AbsoluteTime;
}
return { t_ms: Math.min(t1.t_ms, t22.t_ms), [opaque_AbsoluteTime]: true };
}
- AbsoluteTime2.min = min;
+ AbsoluteTime3.min = min;
function max(t1, t22) {
if (t1.t_ms === "never") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
@@ -13142,7 +13290,7 @@ var AbsoluteTime;
}
return { t_ms: Math.max(t1.t_ms, t22.t_ms), [opaque_AbsoluteTime]: true };
}
- AbsoluteTime2.max = max;
+ AbsoluteTime3.max = max;
function difference2(t1, t22) {
if (t1.t_ms === "never") {
return { d_ms: "forever" };
@@ -13152,15 +13300,15 @@ var AbsoluteTime;
}
return { d_ms: Math.abs(t1.t_ms - t22.t_ms) };
}
- AbsoluteTime2.difference = difference2;
+ AbsoluteTime3.difference = difference2;
function isExpired(t4) {
return cmp(t4, now2()) <= 0;
}
- AbsoluteTime2.isExpired = isExpired;
+ AbsoluteTime3.isExpired = isExpired;
function isNever(t4) {
return t4.t_ms === "never";
}
- AbsoluteTime2.isNever = isNever;
+ AbsoluteTime3.isNever = isNever;
function fromProtocolTimestamp(t4) {
if (t4.t_s === "never") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
@@ -13170,14 +13318,14 @@ var AbsoluteTime;
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.fromProtocolTimestamp = fromProtocolTimestamp;
+ AbsoluteTime3.fromProtocolTimestamp = fromProtocolTimestamp;
function fromStampMs(stampMs) {
return {
t_ms: stampMs,
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.fromStampMs = fromStampMs;
+ AbsoluteTime3.fromStampMs = fromStampMs;
function fromPreciseTimestamp(t4) {
if (t4.t_s === "never") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
@@ -13188,14 +13336,14 @@ var AbsoluteTime;
[opaque_AbsoluteTime]: true
};
}
- AbsoluteTime2.fromPreciseTimestamp = fromPreciseTimestamp;
+ AbsoluteTime3.fromPreciseTimestamp = fromPreciseTimestamp;
function toStampMs(at2) {
if (at2.t_ms === "never") {
return Number.MAX_SAFE_INTEGER;
}
return at2.t_ms;
}
- AbsoluteTime2.toStampMs = toStampMs;
+ AbsoluteTime3.toStampMs = toStampMs;
function toPreciseTimestamp(at2) {
if (at2.t_ms == "never") {
return {
@@ -13209,7 +13357,7 @@ var AbsoluteTime;
off_us
};
}
- AbsoluteTime2.toPreciseTimestamp = toPreciseTimestamp;
+ AbsoluteTime3.toPreciseTimestamp = toPreciseTimestamp;
function toProtocolTimestamp(at2) {
if (at2.t_ms === "never") {
return { t_s: "never" };
@@ -13218,7 +13366,7 @@ var AbsoluteTime;
t_s: Math.floor(at2.t_ms / 1e3)
};
}
- AbsoluteTime2.toProtocolTimestamp = toProtocolTimestamp;
+ AbsoluteTime3.toProtocolTimestamp = toProtocolTimestamp;
function isBetween(t4, start, end) {
if (cmp(t4, start) < 0) {
return false;
@@ -13228,7 +13376,7 @@ var AbsoluteTime;
}
return true;
}
- AbsoluteTime2.isBetween = isBetween;
+ AbsoluteTime3.isBetween = isBetween;
function toIsoString(t4) {
if (t4.t_ms === "never") {
return "<never>";
@@ -13236,14 +13384,14 @@ var AbsoluteTime;
return new Date(t4.t_ms).toISOString();
}
}
- AbsoluteTime2.toIsoString = toIsoString;
+ AbsoluteTime3.toIsoString = toIsoString;
function addDuration(t1, d5) {
if (t1.t_ms === "never" || d5.d_ms === "forever") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
}
return { t_ms: t1.t_ms + d5.d_ms, [opaque_AbsoluteTime]: true };
}
- AbsoluteTime2.addDuration = addDuration;
+ AbsoluteTime3.addDuration = addDuration;
function remaining(t1) {
if (t1.t_ms === "never") {
return Duration.getForever();
@@ -13254,7 +13402,7 @@ var AbsoluteTime;
}
return Duration.fromMilliseconds(Math.max(0, t1.t_ms - stampNow.t_ms));
}
- AbsoluteTime2.remaining = remaining;
+ AbsoluteTime3.remaining = remaining;
function subtractDuraction(t1, d5) {
if (t1.t_ms === "never") {
return { t_ms: "never", [opaque_AbsoluteTime]: true };
@@ -13264,14 +13412,14 @@ var AbsoluteTime;
}
return { t_ms: Math.max(0, t1.t_ms - d5.d_ms), [opaque_AbsoluteTime]: true };
}
- AbsoluteTime2.subtractDuraction = subtractDuraction;
+ AbsoluteTime3.subtractDuraction = subtractDuraction;
function stringify(t4) {
if (t4.t_ms === "never") {
return "never";
}
return new Date(t4.t_ms).toISOString();
}
- AbsoluteTime2.stringify = stringify;
+ AbsoluteTime3.stringify = stringify;
})(AbsoluteTime || (AbsoluteTime = {}));
var SECONDS = 1e3;
var MINUTES = SECONDS * 60;
@@ -13279,16 +13427,6 @@ var HOURS = MINUTES * 60;
var DAYS = HOURS * 24;
var MONTHS = DAYS * 30;
var YEARS = DAYS * 365;
-function durationFromSpec(spec) {
- let d_ms = 0;
- d_ms += (spec.seconds ?? 0) * SECONDS;
- d_ms += (spec.minutes ?? 0) * MINUTES;
- d_ms += (spec.hours ?? 0) * HOURS;
- d_ms += (spec.days ?? 0) * DAYS;
- d_ms += (spec.months ?? 0) * MONTHS;
- d_ms += (spec.years ?? 0) * YEARS;
- return { d_ms };
-}
function durationMin(d1, d22) {
if (d1.d_ms === "forever") {
return { d_ms: d22.d_ms };
@@ -13313,8 +13451,27 @@ function durationMul(d5, n2) {
}
return { d_ms: Math.round(d5.d_ms * n2) };
}
+var codecForAbsoluteTime = {
+ decode(x6, c4) {
+ if (x6 === void 0) {
+ throw Error(`got undefined and expected absolute time at ${renderContext(c4)}`);
+ }
+ const t_ms = x6.t_ms;
+ if (typeof t_ms === "string") {
+ if (t_ms === "never") {
+ return { t_ms: "never", [opaque_AbsoluteTime]: true };
+ }
+ } else if (typeof t_ms === "number") {
+ return { t_ms, [opaque_AbsoluteTime]: true };
+ }
+ throw Error(`expected timestamp at ${renderContext(c4)}`);
+ }
+};
var codecForTimestamp = {
decode(x6, c4) {
+ if (x6 === void 0) {
+ throw Error(`got undefined and expected timestamp at ${renderContext(c4)}`);
+ }
const t_ms = x6.t_ms;
if (typeof t_ms === "string") {
if (t_ms === "never") {
@@ -13336,6 +13493,21 @@ var codecForTimestamp = {
throw Error(`expected protocol timestamp at ${renderContext(c4)}`);
}
};
+var codecForDuration = {
+ decode(x6, c4) {
+ const d_us = x6.d_us;
+ if (typeof d_us === "string") {
+ if (d_us === "forever") {
+ return { d_us: "forever" };
+ }
+ throw Error(`expected duration at ${renderContext(c4)}`);
+ }
+ if (typeof d_us === "number") {
+ return { d_us };
+ }
+ throw Error(`expected duration at ${renderContext(c4)}`);
+ }
+};
// ../taler-util/lib/taler-types.js
var DenomKeyType;
@@ -13381,6 +13553,8 @@ var DenominationPubKey;
}
DenominationPubKey2.cmp = cmp;
})(DenominationPubKey || (DenominationPubKey = {}));
+var codecForLocation = () => buildCodecForObject().property("country", codecOptional(codecForString())).property("country_subdivision", codecOptional(codecForString())).property("building_name", codecOptional(codecForString())).property("building_number", codecOptional(codecForString())).property("district", codecOptional(codecForString())).property("street", codecOptional(codecForString())).property("post_code", codecOptional(codecForString())).property("town", codecOptional(codecForString())).property("town_location", codecOptional(codecForString())).property("address_lines", codecOptional(codecForList(codecForString()))).build("Location");
+var codecForInternationalizedString = () => codecForMap(codecForString());
var codecForNgDenominations = codecForAny();
var ExchangeProtocolVersion;
(function(ExchangeProtocolVersion2) {
@@ -14123,6 +14297,19 @@ function generateFakeSegwitAddress(reservePub, addr) {
}
// ../taler-util/lib/payto.js
+function codecForPaytoString() {
+ return {
+ decode(x6, c4) {
+ if (typeof x6 !== "string") {
+ throw new DecodingError(`expected string at ${renderContext(c4)} but got ${typeof x6}`);
+ }
+ if (!x6.startsWith(paytoPfx)) {
+ throw new DecodingError(`expected start with payto at ${renderContext(c4)} but got "${x6}"`);
+ }
+ return x6;
+ }
+ };
+}
var paytoPfx = "payto://";
function stringifyPaytoUri(p4) {
const url = new URL(`${paytoPfx}${p4.targetType}/${p4.targetPath}`);
@@ -14144,7 +14331,7 @@ function parsePaytoUri(s5) {
const targetType = acct.slice(0, firstSlashPos);
const targetPath = acct.slice(firstSlashPos + 1);
const params = {};
- const searchParams = new URLSearchParams(search || "");
+ const searchParams = new URLSearchParams2(search || "");
searchParams.forEach((v3, k5) => {
params[k5] = v3;
});
@@ -14187,10 +14374,12 @@ function parsePaytoUri(s5) {
const msg = /\b([A-Z0-9]{52})\b/.exec(params["message"]);
const reserve = !msg ? params["subject"] : msg[0];
const segwitAddrs = !reserve ? [] : generateFakeSegwitAddress(reserve, targetPath);
+ const uppercased = targetType.toUpperCase();
const result = {
isKnown: true,
targetPath,
targetType,
+ address: uppercased,
params,
segwitAddrs
};
@@ -14204,25 +14393,244 @@ function parsePaytoUri(s5) {
};
}
+// ../taler-util/lib/http-common.js
+var textEncoder = new TextEncoder();
+var logger3 = new Logger("http.ts");
+var DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
+var Headers2 = class {
+ constructor() {
+ this.headerMap = /* @__PURE__ */ new Map();
+ }
+ get(name) {
+ const r3 = this.headerMap.get(name.toLowerCase());
+ if (r3) {
+ return r3;
+ }
+ return null;
+ }
+ set(name, value) {
+ const normalizedName = name.toLowerCase();
+ const existing = this.headerMap.get(normalizedName);
+ if (existing !== void 0) {
+ this.headerMap.set(normalizedName, existing + "," + value);
+ } else {
+ this.headerMap.set(normalizedName, value);
+ }
+ }
+ toJSON() {
+ const m5 = {};
+ this.headerMap.forEach((v3, k5) => m5[k5] = v3);
+ return m5;
+ }
+};
+async function readTalerErrorResponse(httpResponse) {
+ const contentType = httpResponse.headers.get("content-type");
+ if (contentType !== "application/json") {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ contentType: contentType || "<null>"
+ }, "Error response did not even contain JSON. The request URL might be wrong or the service might be unavailable.");
+ }
+ let errJson;
+ try {
+ errJson = await httpResponse.json();
+ } catch (e4) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ validationError: e4.toString()
+ }, "Couldn't parse JSON format from error response");
+ }
+ const talerErrorCode = errJson.code;
+ if (typeof talerErrorCode !== "number") {
+ logger3.warn(`malformed error response (status ${httpResponse.status}): ${j2s(errJson)}`);
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status
+ }, "Error response did not contain error code");
+ }
+ return errJson;
+}
+async function readSuccessResponseJsonOrErrorCode(httpResponse, codec) {
+ if (!(httpResponse.status >= 200 && httpResponse.status < 300)) {
+ return {
+ isError: true,
+ talerErrorResponse: await readTalerErrorResponse(httpResponse)
+ };
+ }
+ let respJson;
+ try {
+ respJson = await httpResponse.json();
+ } catch (e4) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ validationError: e4.toString()
+ }, "Couldn't parse JSON format from response");
+ }
+ let parsedResponse;
+ try {
+ parsedResponse = codec.decode(respJson);
+ } catch (e4) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ validationError: e4.toString()
+ }, "Response invalid");
+ }
+ return {
+ isError: false,
+ response: parsedResponse
+ };
+}
+function throwUnexpectedRequestError(httpResponse, talerErrorResponse) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ errorResponse: talerErrorResponse
+ }, `Unexpected HTTP status ${httpResponse.status} in response`);
+}
+async function readSuccessResponseJsonOrThrow(httpResponse, codec) {
+ const r3 = await readSuccessResponseJsonOrErrorCode(httpResponse, codec);
+ if (!r3.isError) {
+ return r3.response;
+ }
+ throwUnexpectedRequestError(httpResponse, r3.talerErrorResponse);
+}
+function encodeBody(body) {
+ if (body == null) {
+ return new ArrayBuffer(0);
+ }
+ if (typeof body === "string") {
+ return textEncoder.encode(body).buffer;
+ } else if (ArrayBuffer.isView(body)) {
+ return body.buffer;
+ } else if (body instanceof ArrayBuffer) {
+ return body;
+ } else if (typeof body === "object") {
+ return textEncoder.encode(JSON.stringify(body)).buffer;
+ }
+ throw new TypeError("unsupported request body type");
+}
+function getDefaultHeaders(method) {
+ const headers = {};
+ if (method === "POST" || method === "PUT" || method === "PATCH") {
+ headers["Content-Type"] = "application/json";
+ }
+ headers["Accept"] = "application/json";
+ return headers;
+}
+function makeBasicAuthHeader(username, password) {
+ const auth = `${username}:${password}`;
+ const authEncoded = base64FromArrayBuffer(stringToBytes(auth));
+ return `Basic ${authEncoded}`;
+}
+
+// ../taler-util/lib/operation.js
+async function opSuccessFromHttp(resp, codec) {
+ const body = await readSuccessResponseJsonOrThrow(resp, codec);
+ return { type: "ok", body };
+}
+function opFixedSuccess(body) {
+ return { type: "ok", body };
+}
+function opEmptySuccess(resp) {
+ return { type: "ok", body: void 0 };
+}
+async function opKnownAlternativeFailure(resp, s5, codec) {
+ const body = await readSuccessResponseJsonOrThrow(resp, codec);
+ return { type: "fail", case: s5, body };
+}
+async function opKnownHttpFailure(s5, resp) {
+ const detail = await readTalerErrorResponse(resp);
+ return { type: "fail", case: s5, detail };
+}
+function opKnownTalerFailure(s5, detail) {
+ return { type: "fail", case: s5, detail };
+}
+function opUnknownFailure(resp, error2) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, {
+ requestUrl: resp.requestUrl,
+ requestMethod: resp.requestMethod,
+ httpStatusCode: resp.status,
+ errorResponse: error2
+ }, `Unexpected HTTP status ${resp.status} in response`);
+}
+
// ../taler-util/lib/taleruri.js
-function parseWithdrawUri(s5) {
- const pi = parseProtoInfo(s5, "withdraw");
- if (!pi) {
- return void 0;
+function codecForTalerUriString() {
+ return {
+ decode(x6, c4) {
+ if (typeof x6 !== "string") {
+ throw new DecodingError(`expected string at ${renderContext(c4)} but got ${typeof x6}`);
+ }
+ if (parseTalerUri(x6) === void 0) {
+ throw new DecodingError(`invalid taler URI at ${renderContext(c4)} but got "${x6}"`);
+ }
+ return x6;
+ }
+ };
+}
+function parseWithdrawUriWithError(s5) {
+ const pi = parseProtoInfoWithError(s5, "withdraw");
+ if (pi.type === "fail") {
+ return pi;
}
- const parts = pi.rest.split("/");
+ const parts = pi.body.rest.split("/");
if (parts.length < 2) {
- return void 0;
+ return opKnownTalerFailure(TalerErrorCode.WALLET_TALER_URI_MALFORMED, {
+ code: TalerErrorCode.WALLET_TALER_URI_MALFORMED
+ });
}
const host = parts[0].toLowerCase();
const pathSegments = parts.slice(1, parts.length - 1);
const withdrawId = parts[parts.length - 1];
const p4 = [host, ...pathSegments].join("/");
- return {
+ const result = {
type: TalerUriAction.Withdraw,
- bankIntegrationApiBaseUrl: canonicalizeBaseUrl(`${pi.innerProto}://${p4}/`),
+ bankIntegrationApiBaseUrl: canonicalizeBaseUrl(`${pi.body.innerProto}://${p4}/`),
withdrawalOperationId: withdrawId
};
+ return opFixedSuccess(result);
+}
+function parseWithdrawUri(s5) {
+ const r3 = parseWithdrawUriWithError(s5);
+ if (r3.type === "fail")
+ return void 0;
+ return r3.body;
+}
+function parseAddExchangeUriWithError(s5) {
+ const pi = parseProtoInfoWithError(s5, "add-exchange");
+ if (pi.type === "fail") {
+ return pi;
+ }
+ const parts = pi.body.rest.split("/");
+ if (parts.length < 2) {
+ return opKnownTalerFailure(TalerErrorCode.WALLET_TALER_URI_MALFORMED, {
+ code: TalerErrorCode.WALLET_TALER_URI_MALFORMED
+ });
+ }
+ const host = parts[0].toLowerCase();
+ const pathSegments = parts.slice(1, parts.length - 1);
+ const p4 = [host, ...pathSegments].join("/");
+ const result = {
+ type: TalerUriAction.AddExchange,
+ exchangeBaseUrl: canonicalizeBaseUrl(`${pi.body.innerProto}://${p4}/`)
+ };
+ return opFixedSuccess(result);
+}
+function parseAddExchangeUri(s5) {
+ const r3 = parseAddExchangeUriWithError(s5);
+ if (r3.type === "fail")
+ return void 0;
+ return r3.body;
}
var TalerUriType;
(function(TalerUriType2) {
@@ -14249,6 +14657,7 @@ var TalerUriAction;
TalerUriAction2["Restore"] = "restore";
TalerUriAction2["DevExperiment"] = "dev-experiment";
TalerUriAction2["WithdrawExchange"] = "withdraw-exchange";
+ TalerUriAction2["AddExchange"] = "add-exchange";
})(TalerUriAction || (TalerUriAction = {}));
function parseProtoInfo(s5, action) {
const pfxPlain = `taler://${action}/`;
@@ -14267,6 +14676,30 @@ function parseProtoInfo(s5, action) {
return void 0;
}
}
+function parseProtoInfoWithError(s5, action) {
+ if (!s5.toLowerCase().startsWith("taler://") && !s5.toLowerCase().startsWith("taler+http://")) {
+ return opKnownTalerFailure(TalerErrorCode.WALLET_TALER_URI_MALFORMED, {
+ code: TalerErrorCode.WALLET_TALER_URI_MALFORMED
+ });
+ }
+ const pfxPlain = `taler://${action}/`;
+ const pfxHttp = `taler+http://${action}/`;
+ if (s5.toLowerCase().startsWith(pfxPlain)) {
+ return opFixedSuccess({
+ innerProto: "https",
+ rest: s5.substring(pfxPlain.length)
+ });
+ } else if (s5.toLowerCase().startsWith(pfxHttp)) {
+ return opFixedSuccess({
+ innerProto: "http",
+ rest: s5.substring(pfxHttp.length)
+ });
+ } else {
+ return opKnownTalerFailure(TalerErrorCode.WALLET_TALER_URI_MALFORMED, {
+ code: TalerErrorCode.WALLET_TALER_URI_MALFORMED
+ });
+ }
+}
var parsers = {
[TalerUriAction.Pay]: parsePayUri,
[TalerUriAction.PayPull]: parsePayPullUri,
@@ -14276,15 +14709,63 @@ var parsers = {
[TalerUriAction.Refund]: parseRefundUri,
[TalerUriAction.Withdraw]: parseWithdrawUri,
[TalerUriAction.DevExperiment]: parseDevExperimentUri,
- [TalerUriAction.WithdrawExchange]: parseWithdrawExchangeUri
+ [TalerUriAction.WithdrawExchange]: parseWithdrawExchangeUri,
+ [TalerUriAction.AddExchange]: parseAddExchangeUri
};
+function parseTalerUri(string2) {
+ const https = string2.startsWith("taler://");
+ const http = string2.startsWith("taler+http://");
+ if (!https && !http)
+ return void 0;
+ const actionStart = https ? 8 : 13;
+ const actionEnd = string2.indexOf("/", actionStart + 1);
+ const action = string2.substring(actionStart, actionEnd);
+ const found = Object.values(TalerUriAction).find((x6) => x6 === action);
+ if (!found)
+ return void 0;
+ return parsers[found](string2);
+}
+function stringifyTalerUri(uri) {
+ switch (uri.type) {
+ case TalerUriAction.DevExperiment: {
+ return stringifyDevExperimentUri(uri);
+ }
+ case TalerUriAction.Pay: {
+ return stringifyPayUri(uri);
+ }
+ case TalerUriAction.PayPull: {
+ return stringifyPayPullUri(uri);
+ }
+ case TalerUriAction.PayPush: {
+ return stringifyPayPushUri(uri);
+ }
+ case TalerUriAction.PayTemplate: {
+ return stringifyPayTemplateUri(uri);
+ }
+ case TalerUriAction.Restore: {
+ return stringifyRestoreUri(uri);
+ }
+ case TalerUriAction.Refund: {
+ return stringifyRefundUri(uri);
+ }
+ case TalerUriAction.Withdraw: {
+ return stringifyWithdrawUri(uri);
+ }
+ case TalerUriAction.WithdrawExchange: {
+ return stringifyWithdrawExchange(uri);
+ }
+ case TalerUriAction.AddExchange: {
+ return stringifyAddExchange(uri);
+ }
+ }
+}
function parsePayUri(s5) {
const pi = parseProtoInfo(s5, "pay");
if (!pi) {
return void 0;
}
const c4 = pi?.rest.split("?");
- const q5 = new URLSearchParams(c4[1] ?? "");
+ const q5 = new URLSearchParams2(c4[1] ?? "");
const claimToken = q5.get("c") ?? void 0;
const noncePriv = q5.get("n") ?? void 0;
const parts = c4[0].split("/");
@@ -14316,7 +14797,7 @@ function parsePayTemplateUri(uriString) {
if (parts.length < 2) {
return void 0;
}
- const q5 = new URLSearchParams(c4[1] ?? "");
+ const q5 = new URLSearchParams2(c4[1] ?? "");
const params = {};
q5.forEach((v3, k5) => {
params[k5] = v3;
@@ -14390,7 +14871,7 @@ function parseWithdrawExchangeUri(s5) {
const pathSegments = parts.slice(1, parts.length - 1);
const hostAndSegments = [host, ...pathSegments].join("/");
const exchangeBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${hostAndSegments}/`);
- const q5 = new URLSearchParams(c4[1] ?? "");
+ const q5 = new URLSearchParams2(c4[1] ?? "");
const amount = q5.get("a") ?? void 0;
return {
type: TalerUriAction.WithdrawExchange,
@@ -14457,6 +14938,38 @@ function parseRestoreUri(uri) {
providers
};
}
+function stringifyPayUri({ merchantBaseUrl, orderId, sessionId, claimToken, noncePriv }) {
+ const { proto, path, query } = getUrlInfo(merchantBaseUrl, {
+ c: claimToken,
+ n: noncePriv
+ });
+ return `${proto}://pay/${path}${orderId}/${sessionId}${query}`;
+}
+function stringifyPayPullUri({ contractPriv, exchangeBaseUrl }) {
+ const { proto, path } = getUrlInfo(exchangeBaseUrl);
+ return `${proto}://pay-pull/${path}${contractPriv}`;
+}
+function stringifyPayPushUri({ contractPriv, exchangeBaseUrl }) {
+ const { proto, path } = getUrlInfo(exchangeBaseUrl);
+ return `${proto}://pay-push/${path}${contractPriv}`;
+}
+function stringifyRestoreUri({ providers, walletRootPriv }) {
+ const list = providers.map((url) => `${encodeURIComponent(new URL2(url).href)}`).join(",");
+ return `taler://restore/${walletRootPriv}/${list}`;
+}
+function stringifyWithdrawExchange({ exchangeBaseUrl, exchangePub, amount }) {
+ const { proto, path, query } = getUrlInfo(exchangeBaseUrl, {
+ a: amount
+ });
+ return `${proto}://withdraw-exchange/${path}${exchangePub ?? ""}${query}`;
+}
+function stringifyAddExchange({ exchangeBaseUrl }) {
+ const { proto, path } = getUrlInfo(exchangeBaseUrl);
+ return `${proto}://add-exchange/${path}`;
+}
+function stringifyDevExperimentUri({ devExperimentId }) {
+ return `taler://dev-experiment/${devExperimentId}`;
+}
function stringifyPayTemplateUri({ merchantBaseUrl, templateId, templateParams }) {
const { proto, path, query } = getUrlInfo(merchantBaseUrl, templateParams);
return `${proto}://pay-template/${path}${templateId}${query}`;
@@ -14465,6 +14978,10 @@ function stringifyRefundUri({ merchantBaseUrl, orderId }) {
const { proto, path } = getUrlInfo(merchantBaseUrl);
return `${proto}://refund/${path}${orderId}/`;
}
+function stringifyWithdrawUri({ bankIntegrationApiBaseUrl, withdrawalOperationId }) {
+ const { proto, path } = getUrlInfo(bankIntegrationApiBaseUrl);
+ return `${proto}://withdraw/${path}${withdrawalOperationId}`;
+}
function getUrlInfo(baseUrl, params = {}) {
const url = new URL2(baseUrl);
let proto;
@@ -14485,7 +15002,7 @@ function getUrlInfo(baseUrl, params = {}) {
if (!path.endsWith("/")) {
path = path + "/";
}
- const qp = new URLSearchParams();
+ const qp = new URLSearchParams2();
let withParams = false;
Object.entries(params).forEach(([name, value]) => {
if (value !== void 0) {
@@ -14498,6 +15015,78 @@ function getUrlInfo(baseUrl, params = {}) {
}
// ../taler-util/lib/http-client/types.js
+var codecForAccessToken = codecForString;
+var codecForTokenSuccessResponse = () => buildCodecForObject().property("access_token", codecForAccessToken()).property("expiration", codecForTimestamp).build("TalerAuthentication.TokenSuccessResponse");
+var codecForTokenSuccessResponseMerchant = () => buildCodecForObject().property("token", codecForAccessToken()).property("expiration", codecForTimestamp).build("TalerAuthentication.TokenSuccessResponseMerchant");
+var codecForCurrencySpecificiation = () => buildCodecForObject().property("name", codecForString()).property("num_fractional_input_digits", codecForNumber()).property("num_fractional_normal_digits", codecForNumber()).property("num_fractional_trailing_zero_digits", codecForNumber()).property("alt_unit_names", codecForMap(codecForString())).build("CurrencySpecification");
+var codecForExchangeConfigInfo = () => buildCodecForObject().property("base_url", codecForString()).property("currency", codecForString()).property("master_pub", codecForString()).build("TalerMerchantApi.ExchangeConfigInfo");
+var codecForMerchantConfig = () => buildCodecForObject().property("name", codecForConstString("taler-merchant")).property("currency", codecForString()).property("version", codecForString()).property("currencies", codecForMap(codecForCurrencySpecificiation())).property("exchanges", codecForList(codecForExchangeConfigInfo())).build("TalerMerchantApi.VersionResponse");
+var codecForClaimResponse = () => buildCodecForObject().property("contract_terms", codecForContractTerms()).property("sig", codecForString()).build("TalerMerchantApi.ClaimResponse");
+var codecForPaymentResponse = () => buildCodecForObject().property("pos_confirmation", codecOptional(codecForString())).property("sig", codecForString()).build("TalerMerchantApi.PaymentResponse");
+var codecForStatusPaid = () => buildCodecForObject().property("refund_amount", codecForAmountString()).property("refund_pending", codecForBoolean()).property("refund_taken", codecForAmountString()).property("refunded", codecForBoolean()).property("type", codecForConstString("paid")).build("TalerMerchantApi.StatusPaid");
+var codecForStatusGoto = () => buildCodecForObject().property("public_reorder_url", codecForURL()).property("type", codecForConstString("goto")).build("TalerMerchantApi.StatusGotoResponse");
+var codecForStatusStatusUnpaid = () => buildCodecForObject().property("type", codecForConstString("unpaid")).property("already_paid_order_id", codecOptional(codecForString())).property("fulfillment_url", codecOptional(codecForString())).property("taler_pay_uri", codecForTalerUriString()).build("TalerMerchantApi.PaymentResponse");
+var codecForPaidRefundStatusResponse = () => buildCodecForObject().property("pos_confirmation", codecOptional(codecForString())).property("refunded", codecForBoolean()).build("TalerMerchantApi.PaidRefundStatusResponse");
+var codecForMerchantAbortPayRefundSuccessStatus = () => buildCodecForObject().property("exchange_pub", codecForString()).property("exchange_sig", codecForString()).property("exchange_status", codecForConstNumber(200)).property("type", codecForConstString("success")).build("TalerMerchantApi.MerchantAbortPayRefundSuccessStatus");
+var codecForMerchantAbortPayRefundFailureStatus = () => buildCodecForObject().property("exchange_code", codecForNumber()).property("exchange_reply", codecForAny()).property("exchange_status", codecForNumber()).property("type", codecForConstString("failure")).build("TalerMerchantApi.MerchantAbortPayRefundFailureStatus");
+var codecForMerchantAbortPayRefundStatus = () => buildCodecForUnion().discriminateOn("type").alternative("success", codecForMerchantAbortPayRefundSuccessStatus()).alternative("failure", codecForMerchantAbortPayRefundFailureStatus()).build("TalerMerchantApi.MerchantAbortPayRefundStatus");
+var codecForAbortResponse = () => buildCodecForObject().property("refunds", codecForList(codecForMerchantAbortPayRefundStatus())).build("TalerMerchantApi.AbortResponse");
+var codecForWalletRefundResponse = () => buildCodecForObject().property("merchant_pub", codecForString()).property("refund_amount", codecForAmountString()).property("refunds", codecForList(codecForMerchantCoinRefundStatus())).build("TalerMerchantApi.AbortResponse");
+var codecForMerchantCoinRefundSuccessStatus = () => buildCodecForObject().property("type", codecForConstString("success")).property("coin_pub", codecForString()).property("exchange_status", codecForConstNumber(200)).property("exchange_sig", codecForString()).property("rtransaction_id", codecForNumber()).property("refund_amount", codecForAmountString()).property("exchange_pub", codecForString()).property("execution_time", codecForTimestamp).build("TalerMerchantApi.MerchantCoinRefundSuccessStatus");
+var codecForMerchantCoinRefundFailureStatus = () => buildCodecForObject().property("type", codecForConstString("failure")).property("coin_pub", codecForString()).property("exchange_status", codecForNumber()).property("rtransaction_id", codecForNumber()).property("refund_amount", codecForAmountString()).property("exchange_code", codecOptional(codecForNumber())).property("exchange_reply", codecOptional(codecForAny())).property("execution_time", codecForTimestamp).build("TalerMerchantApi.MerchantCoinRefundFailureStatus");
+var codecForMerchantCoinRefundStatus = () => buildCodecForUnion().discriminateOn("type").alternative("success", codecForMerchantCoinRefundSuccessStatus()).alternative("failure", codecForMerchantCoinRefundFailureStatus()).build("TalerMerchantApi.MerchantCoinRefundStatus");
+var codecForQueryInstancesResponse = () => buildCodecForObject().property("name", codecForString()).property("user_type", codecForString()).property("email", codecOptional(codecForString())).property("website", codecOptional(codecForString())).property("logo", codecOptional(codecForString())).property("merchant_pub", codecForString()).property("address", codecForLocation()).property("jurisdiction", codecForLocation()).property("use_stefan", codecForBoolean()).property("default_wire_transfer_delay", codecForDuration).property("default_pay_delay", codecForDuration).property("auth", buildCodecForObject().property("method", codecForEither(codecForConstString("token"), codecForConstString("external"))).build("TalerMerchantApi.QueryInstancesResponse.auth")).build("TalerMerchantApi.QueryInstancesResponse");
+var codecForAccountKycRedirects = () => buildCodecForObject().property("pending_kycs", codecForList(codecForMerchantAccountKycRedirect())).property("timeout_kycs", codecForList(codecForExchangeKycTimeout())).build("TalerMerchantApi.AccountKycRedirects");
+var codecForMerchantAccountKycRedirect = () => buildCodecForObject().property("kyc_url", codecForURL()).property("aml_status", codecForNumber()).property("exchange_url", codecForURL()).property("payto_uri", codecForPaytoString()).build("TalerMerchantApi.MerchantAccountKycRedirect");
+var codecForExchangeKycTimeout = () => buildCodecForObject().property("exchange_url", codecForURL()).property("exchange_code", codecForNumber()).property("exchange_http_status", codecForNumber()).build("TalerMerchantApi.ExchangeKycTimeout");
+var codecForAccountAddResponse = () => buildCodecForObject().property("h_wire", codecForString()).property("salt", codecForString()).build("TalerMerchantApi.AccountAddResponse");
+var codecForAccountsSummaryResponse = () => buildCodecForObject().property("accounts", codecForList(codecForBankAccountSummaryEntry())).build("TalerMerchantApi.AccountsSummaryResponse");
+var codecForBankAccountSummaryEntry = () => buildCodecForObject().property("payto_uri", codecForPaytoString()).property("h_wire", codecForString()).build("TalerMerchantApi.BankAccountSummaryEntry");
+var codecForBankAccountEntry = () => buildCodecForObject().property("payto_uri", codecForPaytoString()).property("h_wire", codecForString()).property("salt", codecForString()).property("credit_facade_url", codecOptional(codecForURL())).property("active", codecOptional(codecForBoolean())).build("TalerMerchantApi.BankAccountEntry");
+var codecForInventorySummaryResponse = () => buildCodecForObject().property("products", codecForList(codecForInventoryEntry())).build("TalerMerchantApi.InventorySummaryResponse");
+var codecForInventoryEntry = () => buildCodecForObject().property("product_id", codecForString()).property("product_serial", codecForNumber()).build("TalerMerchantApi.InventoryEntry");
+var codecForProductDetail = () => buildCodecForObject().property("description", codecForString()).property("description_i18n", codecForInternationalizedString()).property("unit", codecForString()).property("price", codecForAmountString()).property("image", codecForString()).property("taxes", codecForList(codecForTax())).property("address", codecForLocation()).property("next_restock", codecForTimestamp).property("total_stock", codecForNumber()).property("total_sold", codecForNumber()).property("total_lost", codecForNumber()).property("minimum_age", codecOptional(codecForNumber())).build("TalerMerchantApi.ProductDetail");
+var codecForTax = () => buildCodecForObject().property("name", codecForString()).property("tax", codecForAmountString()).build("TalerMerchantApi.Tax");
+var codecForPostOrderResponse = () => buildCodecForObject().property("order_id", codecForString()).property("token", codecOptional(codecForString())).build("TalerMerchantApi.PostOrderResponse");
+var codecForOutOfStockResponse = () => buildCodecForObject().property("product_id", codecForString()).property("available_quantity", codecForNumber()).property("requested_quantity", codecForNumber()).property("restock_expected", codecForTimestamp).build("TalerMerchantApi.OutOfStockResponse");
+var codecForOrderHistory = () => buildCodecForObject().property("orders", codecForList(codecForOrderHistoryEntry())).build("TalerMerchantApi.OrderHistory");
+var codecForOrderHistoryEntry = () => buildCodecForObject().property("order_id", codecForString()).property("row_id", codecForNumber()).property("timestamp", codecForTimestamp).property("amount", codecForAmountString()).property("summary", codecForString()).property("refundable", codecForBoolean()).property("paid", codecForBoolean()).build("TalerMerchantApi.OrderHistoryEntry");
+var codecForMerchant = () => buildCodecForObject().property("name", codecForString()).property("email", codecOptional(codecForString())).property("logo", codecOptional(codecForString())).property("website", codecOptional(codecForString())).property("address", codecOptional(codecForLocation())).property("jurisdiction", codecOptional(codecForLocation())).build("TalerMerchantApi.MerchantInfo");
+var codecForExchange = () => buildCodecForObject().property("master_pub", codecForString()).property("priority", codecForNumber()).property("url", codecForString()).build("TalerMerchantApi.Exchange");
+var codecForContractTerms = () => buildCodecForObject().property("order_id", codecForString()).property("fulfillment_url", codecOptional(codecForString())).property("fulfillment_message", codecOptional(codecForString())).property("fulfillment_message_i18n", codecOptional(codecForInternationalizedString())).property("merchant_base_url", codecForString()).property("h_wire", codecForString()).property("auto_refund", codecOptional(codecForDuration)).property("wire_method", codecForString()).property("summary", codecForString()).property("summary_i18n", codecOptional(codecForInternationalizedString())).property("nonce", codecForString()).property("amount", codecForAmountString()).property("pay_deadline", codecForTimestamp).property("refund_deadline", codecForTimestamp).property("wire_transfer_deadline", codecForTimestamp).property("timestamp", codecForTimestamp).property("delivery_location", codecOptional(codecForLocation())).property("delivery_date", codecOptional(codecForTimestamp)).property("max_fee", codecForAmountString()).property("merchant", codecForMerchant()).property("merchant_pub", codecForString()).property("exchanges", codecForList(codecForExchange())).property("products", codecForList(codecForProduct())).property("extra", codecForAny()).build("TalerMerchantApi.ContractTerms");
+var codecForProduct = () => buildCodecForObject().property("product_id", codecOptional(codecForString())).property("description", codecForString()).property("description_i18n", codecOptional(codecForInternationalizedString())).property("quantity", codecOptional(codecForNumber())).property("unit", codecOptional(codecForString())).property("price", codecOptional(codecForAmountString())).property("image", codecOptional(codecForString())).property("taxes", codecOptional(codecForList(codecForTax()))).property("delivery_date", codecOptional(codecForTimestamp)).build("TalerMerchantApi.Product");
+var codecForCheckPaymentPaidResponse = () => buildCodecForObject().property("order_status", codecForConstString("paid")).property("refunded", codecForBoolean()).property("refund_pending", codecForBoolean()).property("wired", codecForBoolean()).property("deposit_total", codecForAmountString()).property("exchange_code", codecForNumber()).property("exchange_http_status", codecForNumber()).property("refund_amount", codecForAmountString()).property("contract_terms", codecForContractTerms()).property("wire_reports", codecForList(codecForTransactionWireReport())).property("wire_details", codecForList(codecForTransactionWireTransfer())).property("refund_details", codecForList(codecForRefundDetails())).property("order_status_url", codecForURL()).build("TalerMerchantApi.CheckPaymentPaidResponse");
+var codecForCheckPaymentUnpaidResponse = () => buildCodecForObject().property("order_status", codecForConstString("unpaid")).property("taler_pay_uri", codecForTalerUriString()).property("creation_time", codecForTimestamp).property("summary", codecForString()).property("total_amount", codecForAmountString()).property("already_paid_order_id", codecOptional(codecForString())).property("already_paid_fulfillment_url", codecOptional(codecForString())).property("order_status_url", codecForString()).build("TalerMerchantApi.CheckPaymentPaidResponse");
+var codecForCheckPaymentClaimedResponse = () => buildCodecForObject().property("order_status", codecForConstString("claimed")).property("contract_terms", codecForContractTerms()).build("TalerMerchantApi.CheckPaymentClaimedResponse");
+var codecForMerchantOrderPrivateStatusResponse = () => buildCodecForUnion().discriminateOn("order_status").alternative("paid", codecForCheckPaymentPaidResponse()).alternative("unpaid", codecForCheckPaymentUnpaidResponse()).alternative("claimed", codecForCheckPaymentClaimedResponse()).build("TalerMerchantApi.MerchantOrderStatusResponse");
+var codecForRefundDetails = () => buildCodecForObject().property("reason", codecForString()).property("pending", codecForBoolean()).property("timestamp", codecForTimestamp).property("amount", codecForAmountString()).build("TalerMerchantApi.RefundDetails");
+var codecForTransactionWireTransfer = () => buildCodecForObject().property("exchange_url", codecForURL()).property("wtid", codecForString()).property("execution_time", codecForTimestamp).property("amount", codecForAmountString()).property("confirmed", codecForBoolean()).build("TalerMerchantApi.TransactionWireTransfer");
+var codecForTransactionWireReport = () => buildCodecForObject().property("code", codecForNumber()).property("hint", codecForString()).property("exchange_code", codecForNumber()).property("exchange_http_status", codecForNumber()).property("coin_pub", codecForString()).build("TalerMerchantApi.TransactionWireReport");
+var codecForMerchantRefundResponse = () => buildCodecForObject().property("taler_refund_uri", codecForTalerUriString()).property("h_contract", codecForString()).build("TalerMerchantApi.MerchantRefundResponse");
+var codecForTansferList = () => buildCodecForObject().property("transfers", codecForList(codecForTransferDetails())).build("TalerMerchantApi.TransferList");
+var codecForTransferDetails = () => buildCodecForObject().property("credit_amount", codecForAmountString()).property("wtid", codecForString()).property("payto_uri", codecForPaytoString()).property("exchange_url", codecForURL()).property("transfer_serial_id", codecForNumber()).property("execution_time", codecOptional(codecForTimestamp)).property("verified", codecOptional(codecForBoolean())).property("confirmed", codecOptional(codecForBoolean())).build("TalerMerchantApi.TransferDetails");
+var codecForOtpDeviceSummaryResponse = () => buildCodecForObject().property("otp_devices", codecForList(codecForOtpDeviceEntry())).build("TalerMerchantApi.OtpDeviceSummaryResponse");
+var codecForOtpDeviceEntry = () => buildCodecForObject().property("otp_device_id", codecForString()).property("device_description", codecForString()).build("TalerMerchantApi.OtpDeviceEntry");
+var codecForOtpDeviceDetails = () => buildCodecForObject().property("device_description", codecForString()).property("otp_algorithm", codecForNumber()).property("otp_ctr", codecOptional(codecForNumber())).property("otp_timestamp", codecForNumber()).property("otp_code", codecOptional(codecForString())).build("TalerMerchantApi.OtpDeviceDetails");
+var codecForTemplateSummaryResponse = () => buildCodecForObject().property("templates", codecForList(codecForTemplateEntry())).build("TalerMerchantApi.TemplateSummaryResponse");
+var codecForTemplateEntry = () => buildCodecForObject().property("template_id", codecForString()).property("template_description", codecForString()).build("TalerMerchantApi.TemplateEntry");
+var codecForTemplateDetails = () => buildCodecForObject().property("template_description", codecForString()).property("otp_id", codecOptional(codecForString())).property("template_contract", codecForTemplateContractDetails()).property("required_currency", codecOptional(codecForString())).property("editable_defaults", codecOptional(codecForTemplateContractDetailsDefaults())).build("TalerMerchantApi.TemplateDetails");
+var codecForTemplateContractDetails = () => buildCodecForObject().property("summary", codecOptional(codecForString())).property("currency", codecOptional(codecForString())).property("amount", codecOptional(codecForAmountString())).property("minimum_age", codecForNumber()).property("pay_duration", codecForDuration).build("TalerMerchantApi.TemplateContractDetails");
+var codecForTemplateContractDetailsDefaults = () => buildCodecForObject().property("summary", codecOptional(codecForString())).property("currency", codecOptional(codecForString())).property("amount", codecOptional(codecForAmountString())).property("minimum_age", codecOptional(codecForNumber())).property("pay_duration", codecOptional(codecForDuration)).build("TalerMerchantApi.TemplateContractDetailsDefaults");
+var codecForWalletTemplateDetails = () => buildCodecForObject().property("template_contract", codecForTemplateContractDetails()).property("required_currency", codecOptional(codecForString())).property("editable_defaults", codecOptional(codecForTemplateContractDetailsDefaults())).build("TalerMerchantApi.WalletTemplateDetails");
+var codecForWebhookSummaryResponse = () => buildCodecForObject().property("webhooks", codecForList(codecForWebhookEntry())).build("TalerMerchantApi.WebhookSummaryResponse");
+var codecForWebhookEntry = () => buildCodecForObject().property("webhook_id", codecForString()).property("event_type", codecForString()).build("TalerMerchantApi.WebhookEntry");
+var codecForWebhookDetails = () => buildCodecForObject().property("event_type", codecForString()).property("url", codecForString()).property("http_method", codecForString()).property("header_template", codecOptional(codecForString())).property("body_template", codecOptional(codecForString())).build("TalerMerchantApi.WebhookDetails");
+var codecForTokenFamilyKind = () => codecForEither(codecForConstString("discount"), codecForConstString("subscription"));
+var codecForTokenFamilyDetails = () => buildCodecForObject().property("slug", codecForString()).property("name", codecForString()).property("description", codecForString()).property("description_i18n", codecForInternationalizedString()).property("valid_after", codecForTimestamp).property("valid_before", codecForTimestamp).property("duration", codecForDuration).property("kind", codecForTokenFamilyKind()).property("issued", codecForNumber()).property("redeemed", codecForNumber()).build("TalerMerchantApi.TokenFamilyDetails");
+var codecForTokenFamiliesList = () => buildCodecForObject().property("token_families", codecForList(codecForTokenFamilySummary())).build("TalerMerchantApi.TokenFamiliesList");
+var codecForTokenFamilySummary = () => buildCodecForObject().property("slug", codecForString()).property("name", codecForString()).property("valid_after", codecForTimestamp).property("valid_before", codecForTimestamp).property("kind", codecForTokenFamilyKind()).build("TalerMerchantApi.TokenFamilySummary");
+var codecForInstancesResponse = () => buildCodecForObject().property("instances", codecForList(codecForInstance())).build("TalerMerchantApi.InstancesResponse");
+var codecForInstance = () => buildCodecForObject().property("name", codecForString()).property("user_type", codecForString()).property("website", codecOptional(codecForString())).property("logo", codecOptional(codecForString())).property("id", codecForString()).property("merchant_pub", codecForString()).property("payment_targets", codecForList(codecForString())).property("deleted", codecForBoolean()).build("TalerMerchantApi.Instance");
+var codecForRevenueConfig = () => buildCodecForObject().property("name", codecForConstString("taler-revenue")).property("version", codecForString()).property("currency", codecForString()).property("implementation", codecOptional(codecForString())).build("TalerRevenueApi.RevenueConfig");
+var codecForRevenueIncomingHistory = () => buildCodecForObject().property("credit_account", codecForPaytoString()).property("incoming_transactions", codecForList(codecForRevenueIncomingBankTransaction())).build("TalerRevenueApi.MerchantIncomingHistory");
+var codecForRevenueIncomingBankTransaction = () => buildCodecForObject().property("amount", codecForAmountString()).property("date", codecForTimestamp).property("debit_account", codecForPaytoString()).property("row_id", codecForNumber()).property("subject", codecForString()).build("TalerRevenueApi.RevenueIncomingBankTransaction");
+var codecForURL = codecForString;
var TalerCorebankApi;
(function(TalerCorebankApi2) {
let MonitorTimeframeParam;
@@ -14523,6 +15112,14 @@ var TalerExchangeApi;
AmlState2[AmlState2["frozen"] = 2] = "frozen";
})(AmlState = TalerExchangeApi2.AmlState || (TalerExchangeApi2.AmlState = {}));
})(TalerExchangeApi || (TalerExchangeApi = {}));
+var TalerMerchantApi;
+(function(TalerMerchantApi37) {
+ let TokenFamilyKind;
+ (function(TokenFamilyKind2) {
+ TokenFamilyKind2["Discount"] = "discount";
+ TokenFamilyKind2["Subscription"] = "subscription";
+ })(TokenFamilyKind = TalerMerchantApi37.TokenFamilyKind || (TalerMerchantApi37.TokenFamilyKind = {}));
+})(TalerMerchantApi || (TalerMerchantApi = {}));
// ../taler-util/lib/http-status-codes.js
var HttpStatusCode;
@@ -14590,9 +15187,17 @@ var HttpStatusCode;
HttpStatusCode2[HttpStatusCode2["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
})(HttpStatusCode || (HttpStatusCode = {}));
-// ../taler-util/lib/http-common.js
-var textEncoder = new TextEncoder();
-var logger3 = new Logger("http.ts");
+// ../taler-util/lib/http-impl.missing.js
+var HttpLibImpl = class {
+ fetch(url, opt) {
+ throw new Error("Method not implemented.");
+ }
+};
+
+// ../taler-util/lib/http.js
+function createPlatformHttpLib(args) {
+ return new HttpLibImpl(args);
+}
// ../taler-util/lib/libtool-version.js
var LibtoolVersion;
@@ -14635,6 +15240,97 @@ var logger4 = new Logger("MerchantApiClient.ts");
// ../taler-util/lib/RequestThrottler.js
var logger5 = new Logger("RequestThrottler.ts");
+var MAX_PER_SECOND = 100;
+var MAX_PER_MINUTE = 500;
+var MAX_PER_HOUR = 2e3;
+var OriginState = class {
+ constructor() {
+ this.tokensSecond = MAX_PER_SECOND;
+ this.tokensMinute = MAX_PER_MINUTE;
+ this.tokensHour = MAX_PER_HOUR;
+ this.lastUpdate = AbsoluteTime.now();
+ }
+ refill() {
+ const now2 = AbsoluteTime.now();
+ if (AbsoluteTime.cmp(now2, this.lastUpdate) < 0) {
+ this.lastUpdate = now2;
+ return;
+ }
+ const d5 = AbsoluteTime.difference(now2, this.lastUpdate);
+ if (d5.d_ms === "forever") {
+ throw Error("assertion failed");
+ }
+ this.tokensSecond = Math.min(MAX_PER_SECOND, this.tokensSecond + d5.d_ms / 1e3);
+ this.tokensMinute = Math.min(MAX_PER_MINUTE, this.tokensMinute + d5.d_ms / 1e3 / 60);
+ this.tokensHour = Math.min(MAX_PER_HOUR, this.tokensHour + d5.d_ms / 1e3 / 60 / 60);
+ this.lastUpdate = now2;
+ }
+ /**
+ * Return true if the request for this origin should be throttled.
+ * Otherwise, take a token out of the respective buckets.
+ */
+ applyThrottle() {
+ this.refill();
+ if (this.tokensSecond < 1) {
+ logger5.warn("request throttled (per second limit exceeded)");
+ return true;
+ }
+ if (this.tokensMinute < 1) {
+ logger5.warn("request throttled (per minute limit exceeded)");
+ return true;
+ }
+ if (this.tokensHour < 1) {
+ logger5.warn("request throttled (per hour limit exceeded)");
+ return true;
+ }
+ this.tokensSecond--;
+ this.tokensMinute--;
+ this.tokensHour--;
+ return false;
+ }
+};
+var RequestThrottler = class {
+ constructor() {
+ this.perOriginInfo = {};
+ }
+ /**
+ * Get the throttling state for an origin, or
+ * initialize if no state is associated with the
+ * origin yet.
+ */
+ getState(origin) {
+ const s5 = this.perOriginInfo[origin];
+ if (s5) {
+ return s5;
+ }
+ const ns = this.perOriginInfo[origin] = new OriginState();
+ return ns;
+ }
+ /**
+ * Apply throttling to a request.
+ *
+ * @returns whether the request should be throttled.
+ */
+ applyThrottle(requestUrl) {
+ const origin = new URL(requestUrl).origin;
+ return this.getState(origin).applyThrottle();
+ }
+ /**
+ * Get the throttle statistics for a particular URL.
+ */
+ getThrottleStats(requestUrl) {
+ const origin = new URL(requestUrl).origin;
+ const state = this.getState(origin);
+ return {
+ tokensHour: state.tokensHour,
+ tokensMinute: state.tokensMinute,
+ tokensSecond: state.tokensSecond,
+ maxTokensHour: MAX_PER_HOUR,
+ maxTokensMinute: MAX_PER_MINUTE,
+ maxTokensSecond: MAX_PER_SECOND
+ };
+ }
+};
// ../taler-util/lib/ReserveTransaction.js
var ReserveTransactionType;
@@ -14656,6 +15352,39 @@ var CreditDebitIndicator;
CreditDebitIndicator2["Debit"] = "debit";
})(CreditDebitIndicator || (CreditDebitIndicator = {}));
+// ../taler-util/lib/base64.js
+function base64FromArrayBuffer(arrayBuffer) {
+ var base64 = "";
+ var encodings2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var bytes = new Uint8Array(arrayBuffer);
+ var byteLength = bytes.byteLength;
+ var byteRemainder = byteLength % 3;
+ var mainLength = byteLength - byteRemainder;
+ var a5, b4, c4, d5;
+ var chunk;
+ for (var i4 = 0; i4 < mainLength; i4 = i4 + 3) {
+ chunk = bytes[i4] << 16 | bytes[i4 + 1] << 8 | bytes[i4 + 2];
+ a5 = (chunk & 16515072) >> 18;
+ b4 = (chunk & 258048) >> 12;
+ c4 = (chunk & 4032) >> 6;
+ d5 = chunk & 63;
+ base64 += encodings2[a5] + encodings2[b4] + encodings2[c4] + encodings2[d5];
+ }
+ if (byteRemainder == 1) {
+ chunk = bytes[mainLength];
+ a5 = (chunk & 252) >> 2;
+ b4 = (chunk & 3) << 4;
+ base64 += encodings2[a5] + encodings2[b4] + "==";
+ } else if (byteRemainder == 2) {
+ chunk = bytes[mainLength] << 8 | bytes[mainLength + 1];
+ a5 = (chunk & 64512) >> 10;
+ b4 = (chunk & 1008) >> 4;
+ c4 = (chunk & 15) << 2;
+ base64 += encodings2[a5] + encodings2[b4] + encodings2[c4] + "=";
+ }
+ return base64;
+}
+
// ../taler-util/lib/contract-terms.js
var logger8 = new Logger("contractTerms.ts");
var ContractTermsUtil;
@@ -14824,6 +15553,72 @@ var ContractTermsUtil;
})(ContractTermsUtil || (ContractTermsUtil = {}));
// ../taler-util/lib/errors.js
+function makeErrorDetail(code, detail, hint) {
+ if (!hint && !detail.hint) {
+ hint = getDefaultHint(code);
+ }
+ const when = AbsoluteTime.now();
+ return { code, when, hint, ...detail };
+}
+function getDefaultHint(code) {
+ const errName = TalerErrorCode[code];
+ if (errName) {
+ return `Error (${errName})`;
+ } else {
+ return `Error (<unknown>)`;
+ }
+}
+var TalerError = class _TalerError extends Error {
+ constructor(d5, cause) {
+ super(d5.hint ?? `Error (code ${d5.code})`);
+ this.errorDetail = d5;
+ this.cause = cause;
+ Object.setPrototypeOf(this, _TalerError.prototype);
+ }
+ static fromDetail(code, detail, hint, cause) {
+ if (!hint) {
+ hint = getDefaultHint(code);
+ }
+ const when = AbsoluteTime.now();
+ return new _TalerError({ code, when, hint, ...detail }, cause);
+ }
+ static fromUncheckedDetail(d5, c4) {
+ return new _TalerError({ ...d5 }, c4);
+ }
+ static fromException(e4) {
+ const errDetail = getErrorDetailFromException(e4);
+ return new _TalerError(errDetail, e4);
+ }
+ hasErrorCode(code) {
+ return this.errorDetail.code === code;
+ }
+ toString() {
+ return `TalerError: ${JSON.stringify(this.errorDetail)}`;
+ }
+};
+function getErrorDetailFromException(e4) {
+ if (e4 instanceof TalerError) {
+ return e4.errorDetail;
+ }
+ if (e4 instanceof CancellationToken.CancellationError) {
+ const err2 = makeErrorDetail(TalerErrorCode.WALLET_CORE_REQUEST_CANCELLED, {});
+ return err2;
+ }
+ if (e4 instanceof Error) {
+ const err2 = makeErrorDetail(TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION, {
+ stack: e4.stack
+ }, `unexpected exception (message: ${e4.message})`);
+ return err2;
+ }
+ let excString;
+ try {
+ excString = e4.toString();
+ } catch (e5) {
+ excString = "can't stringify exception";
+ }
+ const err = makeErrorDetail(TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION, {}, `unexpected exception (not an exception, ${excString})`);
+ return err;
+}
function assertUnreachable(x6) {
throw new Error("Didn't expect to get here");
}
@@ -14927,12 +15722,19 @@ var TransactionType;
TransactionType2["PeerPullDebit"] = "peer-pull-debit";
TransactionType2["PeerPullCredit"] = "peer-pull-credit";
TransactionType2["Recoup"] = "recoup";
+ TransactionType2["DenomLoss"] = "denom-loss";
})(TransactionType || (TransactionType = {}));
var WithdrawalType;
(function(WithdrawalType2) {
WithdrawalType2["TalerBankIntegrationApi"] = "taler-bank-integration-api";
WithdrawalType2["ManualTransfer"] = "manual-transfer";
})(WithdrawalType || (WithdrawalType = {}));
+var DenomLossEventType;
+(function(DenomLossEventType2) {
+ DenomLossEventType2["DenomExpired"] = "denom-expired";
+ DenomLossEventType2["DenomVanished"] = "denom-vanished";
+ DenomLossEventType2["DenomUnoffered"] = "denom-unoffered";
+})(DenomLossEventType || (DenomLossEventType = {}));
var PaymentStatus;
(function(PaymentStatus2) {
PaymentStatus2["Aborted"] = "aborted";
@@ -14973,6 +15775,7 @@ var ScopeType;
var CoinStatus;
(function(CoinStatus2) {
CoinStatus2["Fresh"] = "fresh";
+ CoinStatus2["DenomLoss"] = "denom-loss";
CoinStatus2["FreshSuspended"] = "fresh-suspended";
CoinStatus2["Dormant"] = "dormant";
})(CoinStatus || (CoinStatus = {}));
@@ -15077,6 +15880,2006 @@ var ProviderPaymentType;
ProviderPaymentType2["TermsChanged"] = "terms-changed";
})(ProviderPaymentType || (ProviderPaymentType = {}));
+// ../taler-util/lib/http-client/utils.js
+function makeBearerTokenAuthHeader(token) {
+ return `Bearer secret-token:${token}`;
+}
+function addPaginationParams(url, pagination) {
+ if (!pagination)
+ return;
+ if (pagination.offset) {
+ url.searchParams.set("start", pagination.offset);
+ }
+ const order = !pagination || pagination.order === "asc" ? 1 : -1;
+ const limit = !pagination || !pagination.limit || pagination.limit === 0 ? 5 : Math.abs(pagination.limit);
+ url.searchParams.set("delta", String(order * limit));
+}
+function addMerchantPaginationParams(url, pagination) {
+ if (!pagination)
+ return;
+ if (pagination.offset) {
+ url.searchParams.set("offset", pagination.offset);
+ }
+ const order = !pagination || pagination.order === "asc" ? 1 : -1;
+ const limit = !pagination || !pagination.limit || pagination.limit === 0 ? 5 : Math.abs(pagination.limit);
+ url.searchParams.set("limit", String(order * limit));
+}
+function addLongPollingParam(url, param) {
+ if (!param)
+ return;
+ if (param.timeoutMs) {
+ url.searchParams.set("long_poll_ms", String(param.timeoutMs));
+ }
+}
+var nullEvictor = {
+ notifySuccess: () => Promise.resolve()
+};
+
+// ../taler-util/lib/http-client/bank-conversion.js
+var TalerBankConversionCacheEviction;
+(function(TalerBankConversionCacheEviction2) {
+ TalerBankConversionCacheEviction2[TalerBankConversionCacheEviction2["UPDATE_RATE"] = 0] = "UPDATE_RATE";
+})(TalerBankConversionCacheEviction || (TalerBankConversionCacheEviction = {}));
+
+// ../taler-util/lib/http-client/authentication.js
+var TalerAuthenticationHttpClient = class {
+ constructor(baseUrl, httpClient) {
+ this.baseUrl = baseUrl;
+ this.PROTOCOL_VERSION = "0:0:0";
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+ isCompatible(version) {
+ const compare2 = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
+ return compare2?.compatible ?? false;
+ }
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token
+ *
+ * @returns
+ */
+ async createAccessTokenBasic(username, password, body) {
+ const url = new URL(`token`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBasicAuthHeader(username, password)
+ },
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTokenSuccessResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ *
+ * @returns
+ */
+ async createAccessTokenBearer(token, body) {
+ const url = new URL(`token`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(token)
+ },
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTokenSuccessResponseMerchant());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ async deleteAccessToken(token) {
+ const url = new URL(`token`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(token)
+ }
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+};
+
+// ../taler-util/lib/http-client/bank-core.js
+var TalerCoreBankCacheEviction;
+(function(TalerCoreBankCacheEviction2) {
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["DELETE_ACCOUNT"] = 0] = "DELETE_ACCOUNT";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["CREATE_ACCOUNT"] = 1] = "CREATE_ACCOUNT";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["UPDATE_ACCOUNT"] = 2] = "UPDATE_ACCOUNT";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["UPDATE_PASSWORD"] = 3] = "UPDATE_PASSWORD";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["CREATE_TRANSACTION"] = 4] = "CREATE_TRANSACTION";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["CONFIRM_WITHDRAWAL"] = 5] = "CONFIRM_WITHDRAWAL";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["ABORT_WITHDRAWAL"] = 6] = "ABORT_WITHDRAWAL";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["CREATE_WITHDRAWAL"] = 7] = "CREATE_WITHDRAWAL";
+ TalerCoreBankCacheEviction2[TalerCoreBankCacheEviction2["CREATE_CASHOUT"] = 8] = "CREATE_CASHOUT";
+})(TalerCoreBankCacheEviction || (TalerCoreBankCacheEviction = {}));
+
+// ../taler-util/lib/http-client/merchant.js
+var TalerMerchantInstanceCacheEviction;
+(function(TalerMerchantInstanceCacheEviction2) {
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_ORDER"] = 0] = "CREATE_ORDER";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_ORDER"] = 1] = "UPDATE_ORDER";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_ORDER"] = 2] = "DELETE_ORDER";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_CURRENT_INSTANCE"] = 3] = "UPDATE_CURRENT_INSTANCE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_CURRENT_INSTANCE"] = 4] = "DELETE_CURRENT_INSTANCE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_BANK_ACCOUNT"] = 5] = "CREATE_BANK_ACCOUNT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_BANK_ACCOUNT"] = 6] = "UPDATE_BANK_ACCOUNT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_BANK_ACCOUNT"] = 7] = "DELETE_BANK_ACCOUNT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_PRODUCT"] = 8] = "CREATE_PRODUCT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_PRODUCT"] = 9] = "UPDATE_PRODUCT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_PRODUCT"] = 10] = "DELETE_PRODUCT";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_TRANSFER"] = 11] = "CREATE_TRANSFER";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_TRANSFER"] = 12] = "DELETE_TRANSFER";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_DEVICE"] = 13] = "CREATE_DEVICE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_DEVICE"] = 14] = "UPDATE_DEVICE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_DEVICE"] = 15] = "DELETE_DEVICE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_TEMPLATE"] = 16] = "CREATE_TEMPLATE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_TEMPLATE"] = 17] = "UPDATE_TEMPLATE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_TEMPLATE"] = 18] = "DELETE_TEMPLATE";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_WEBHOOK"] = 19] = "CREATE_WEBHOOK";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_WEBHOOK"] = 20] = "UPDATE_WEBHOOK";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_WEBHOOK"] = 21] = "DELETE_WEBHOOK";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["CREATE_TOKENFAMILY"] = 22] = "CREATE_TOKENFAMILY";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["UPDATE_TOKENFAMILY"] = 23] = "UPDATE_TOKENFAMILY";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["DELETE_TOKENFAMILY"] = 24] = "DELETE_TOKENFAMILY";
+ TalerMerchantInstanceCacheEviction2[TalerMerchantInstanceCacheEviction2["LAST"] = 25] = "LAST";
+})(TalerMerchantInstanceCacheEviction || (TalerMerchantInstanceCacheEviction = {}));
+var TalerMerchantManagementCacheEviction;
+(function(TalerMerchantManagementCacheEviction2) {
+ TalerMerchantManagementCacheEviction2[TalerMerchantManagementCacheEviction2["CREATE_INSTANCE"] = 26] = "CREATE_INSTANCE";
+ TalerMerchantManagementCacheEviction2[TalerMerchantManagementCacheEviction2["UPDATE_INSTANCE"] = 27] = "UPDATE_INSTANCE";
+ TalerMerchantManagementCacheEviction2[TalerMerchantManagementCacheEviction2["DELETE_INSTANCE"] = 28] = "DELETE_INSTANCE";
+})(TalerMerchantManagementCacheEviction || (TalerMerchantManagementCacheEviction = {}));
+var TalerMerchantInstanceHttpClient = class {
+ constructor(baseUrl, httpClient, cacheEvictor) {
+ this.baseUrl = baseUrl;
+ this.PROTOCOL_VERSION = "10:0:6";
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ this.cacheEvictor = cacheEvictor ?? nullEvictor;
+ }
+ isCompatible(version) {
+ const compare2 = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
+ return compare2?.compatible ?? false;
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--config
+ *
+ */
+ async getConfig() {
+ const url = new URL(`config`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET"
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForMerchantConfig());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Wallet API
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-orders-$ORDER_ID-claim
+ */
+ async claimOrder(orderId, body) {
+ const url = new URL(`orders/${orderId}/claim`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForClaimResponse());
+ }
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-orders-$ORDER_ID-pay
+ */
+ async makePayment(orderId, body) {
+ const url = new URL(`orders/${orderId}/pay`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForPaymentResponse());
+ }
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.PaymentRequired:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.RequestTimeout:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Gone:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.PreconditionFailed:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.GatewayTimeout:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-orders-$ORDER_ID
+ */
+ async getPaymentStatus(orderId, params = {}) {
+ const url = new URL(`orders/${orderId}`, this.baseUrl);
+ if (params.allowRefundedForRepurchase !== void 0) {
+ url.searchParams.set("allow_refunded_for_repurchase", params.allowRefundedForRepurchase ? "YES" : "NO");
+ }
+ if (params.awaitRefundObtained !== void 0) {
+ url.searchParams.set("await_refund_obtained", params.allowRefundedForRepurchase ? "YES" : "NO");
+ }
+ if (params.claimToken !== void 0) {
+ url.searchParams.set("token", params.claimToken);
+ }
+ if (params.contractTermHash !== void 0) {
+ url.searchParams.set("h_contract", params.contractTermHash);
+ }
+ if (params.refund !== void 0) {
+ url.searchParams.set("refund", params.refund);
+ }
+ if (params.sessionId !== void 0) {
+ url.searchParams.set("session_id", params.sessionId);
+ }
+ if (params.timeout !== void 0) {
+ url.searchParams.set("timeout_ms", String(params.timeout));
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET"
+ // body,
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForStatusPaid());
+ case HttpStatusCode.Accepted:
+ return opSuccessFromHttp(resp, codecForStatusGoto());
+ case HttpStatusCode.PaymentRequired:
+ return opSuccessFromHttp(resp, codecForStatusStatusUnpaid());
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotAcceptable:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#demonstrating-payment
+ */
+ async demostratePayment(orderId, body) {
+ const url = new URL(`orders/${orderId}/paid`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForPaidRefundStatusResponse());
+ }
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#aborting-incomplete-payments
+ */
+ async abortIncompletePayment(orderId, body) {
+ const url = new URL(`orders/${orderId}/abort`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForAbortResponse());
+ }
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#obtaining-refunds
+ */
+ async obtainRefund(orderId, body) {
+ const url = new URL(`orders/${orderId}/refund`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForWalletRefundResponse());
+ }
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Management
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-auth
+ */
+ async updateCurrentInstanceAuthentication(token, body) {
+ const url = new URL(`private/auth`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private
+ */
+ async updateCurrentInstance(token, body) {
+ const url = new URL(`private`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private
+ *
+ */
+ async getCurrentInstanceDetails(token) {
+ const url = new URL(`private`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForQueryInstancesResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private
+ */
+ async deleteCurrentInstance(token, params = {}) {
+ const url = new URL(`private`, this.baseUrl);
+ if (params.purge !== void 0) {
+ url.searchParams.set("purge", params.purge ? "YES" : "NO");
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--instances-$INSTANCE-private-kyc
+ */
+ async getCurrentIntanceKycStatus(token, params = {}) {
+ const url = new URL(`private/kyc`, this.baseUrl);
+ if (params.wireHash) {
+ url.searchParams.set("h_wire", params.wireHash);
+ }
+ if (params.exchangeURL) {
+ url.searchParams.set("exchange_url", params.exchangeURL);
+ }
+ if (params.timeout) {
+ url.searchParams.set("timeout_ms", String(params.timeout));
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Accepted:
+ return opSuccessFromHttp(resp, codecForAccountKycRedirects());
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownAlternativeFailure(resp, resp.status, codecForAccountKycRedirects());
+ case HttpStatusCode.ServiceUnavailable:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.GatewayTimeout:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Bank Accounts
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-accounts
+ */
+ async addBankAccount(token, body) {
+ const url = new URL(`private/accounts`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT);
+ return opSuccessFromHttp(resp, codecForAccountAddResponse());
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-accounts-$H_WIRE
+ */
+ async updateBankAccount(token, wireAccount, body) {
+ const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-accounts
+ */
+ async listBankAccounts(token, params) {
+ const url = new URL(`private/accounts`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForAccountsSummaryResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-accounts-$H_WIRE
+ */
+ async getBankAccountDetails(token, wireAccount) {
+ const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForBankAccountEntry());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-accounts-$H_WIRE
+ */
+ async deleteBankAccount(token, wireAccount) {
+ const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Inventory Management
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-products
+ */
+ async addProduct(token, body) {
+ const url = new URL(`private/products`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_PRODUCT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
+ */
+ async updateProduct(token, productId, body) {
+ const url = new URL(`private/products/${productId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-products
+ */
+ async listProducts(token, params) {
+ const url = new URL(`private/products`, this.baseUrl);
+ addMerchantPaginationParams(url, params);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForInventorySummaryResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
+ */
+ async getProductDetails(token, productId) {
+ const url = new URL(`private/products/${productId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForProductDetail());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#reserving-inventory
+ */
+ async lockProduct(token, productId, body) {
+ const url = new URL(`private/products/${productId}/lock`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Gone:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#removing-products-from-inventory
+ */
+ async deleteProduct(token, productId) {
+ const url = new URL(`private/products/${productId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_PRODUCT);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Payment processing
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-orders
+ */
+ async createOrder(token, body) {
+ const url = new URL(`private/orders`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ return this.procesOrderCreationResponse(resp);
+ }
+ async procesOrderCreationResponse(resp) {
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_ORDER);
+ return opSuccessFromHttp(resp, codecForPostOrderResponse());
+ }
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Gone:
+ return opKnownAlternativeFailure(resp, resp.status, codecForOutOfStockResponse());
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#inspecting-orders
+ */
+ async listOrders(token, params = {}) {
+ const url = new URL(`private/orders`, this.baseUrl);
+ if (params.date) {
+ url.searchParams.set("date_s", String(params.date));
+ }
+ if (params.fulfillmentUrl) {
+ url.searchParams.set("fulfillment_url", params.fulfillmentUrl);
+ }
+ if (params.paid !== void 0) {
+ url.searchParams.set("paid", params.paid ? "YES" : "NO");
+ }
+ if (params.refunded !== void 0) {
+ url.searchParams.set("refunded", params.refunded ? "YES" : "NO");
+ }
+ if (params.sessionId) {
+ url.searchParams.set("session_id", params.sessionId);
+ }
+ if (params.timeout) {
+ url.searchParams.set("timeout", String(params.timeout));
+ }
+ if (params.wired !== void 0) {
+ url.searchParams.set("wired", params.wired ? "YES" : "NO");
+ }
+ addMerchantPaginationParams(url, params);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForOrderHistory());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-orders-$ORDER_ID
+ */
+ async getOrderDetails(token, orderId, params = {}) {
+ const url = new URL(`private/orders/${orderId}`, this.baseUrl);
+ if (params.allowRefundedForRepurchase !== void 0) {
+ url.searchParams.set("allow_refunded_for_repurchase", params.allowRefundedForRepurchase ? "YES" : "NO");
+ }
+ if (params.sessionId) {
+ url.searchParams.set("session_id", params.sessionId);
+ }
+ if (params.timeout) {
+ url.searchParams.set("timeout_ms", String(params.timeout));
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForMerchantOrderPrivateStatusResponse());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.GatewayTimeout:
+ return opKnownAlternativeFailure(resp, resp.status, codecForOutOfStockResponse());
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#private-order-data-cleanup
+ */
+ async forgetOrder(token, orderId, body) {
+ const url = new URL(`private/orders/${orderId}/forget`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-orders-$ORDER_ID
+ */
+ async deleteOrder(token, orderId) {
+ const url = new URL(`private/orders/${orderId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_ORDER);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Refunds
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-orders-$ORDER_ID-refund
+ */
+ async addRefund(token, orderId, body) {
+ const url = new URL(`private/orders/${orderId}/refund`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_ORDER);
+ return opSuccessFromHttp(resp, codecForMerchantRefundResponse());
+ }
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Gone:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Wire Transfer
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-transfers
+ */
+ async informWireTransfer(token, body) {
+ const url = new URL(`private/transfers`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TRANSFER);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-transfers
+ */
+ async listWireTransfers(token, params = {}) {
+ const url = new URL(`private/transfers`, this.baseUrl);
+ if (params.after) {
+ url.searchParams.set("after", String(params.after));
+ }
+ if (params.before) {
+ url.searchParams.set("before", String(params.before));
+ }
+ if (params.paytoURI) {
+ url.searchParams.set("payto_uri", params.paytoURI);
+ }
+ if (params.verified !== void 0) {
+ url.searchParams.set("verified", params.verified ? "YES" : "NO");
+ }
+ addMerchantPaginationParams(url, params);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTansferList());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-transfers-$TID
+ */
+ async deleteWireTransfer(token, transferId) {
+ const url = new URL(`private/transfers/${transferId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TRANSFER);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // OTP Devices
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-otp-devices
+ */
+ async addOtpDevice(token, body) {
+ const url = new URL(`private/otp-devices`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_DEVICE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
+ */
+ async updateOtpDevice(token, deviceId, body) {
+ const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_DEVICE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-otp-devices
+ */
+ async listOtpDevices(token, params) {
+ const url = new URL(`private/otp-devices`, this.baseUrl);
+ addMerchantPaginationParams(url, params);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForOtpDeviceSummaryResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
+ */
+ async getOtpDeviceDetails(token, deviceId, params = {}) {
+ const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
+ if (params.faketime) {
+ url.searchParams.set("faketime", String(params.faketime));
+ }
+ if (params.price) {
+ url.searchParams.set("price", params.price);
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForOtpDeviceDetails());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
+ */
+ async deleteOtpDevice(token, deviceId) {
+ const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_DEVICE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // Templates
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-templates
+ */
+ async addTemplate(token, body) {
+ const url = new URL(`private/templates`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
+ */
+ async updateTemplate(token, templateId, body) {
+ const url = new URL(`private/templates/${templateId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#inspecting-template
+ */
+ async listTemplates(token, params) {
+ const url = new URL(`private/templates`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTemplateSummaryResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
+ */
+ async getTemplateDetails(token, templateId) {
+ const url = new URL(`private/templates/${templateId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTemplateDetails());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
+ */
+ async deleteTemplate(token, templateId) {
+ const url = new URL(`private/templates/${templateId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-templates-$TEMPLATE_ID
+ */
+ async useTemplateGetInfo(templateId) {
+ const url = new URL(`templates/${templateId}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET"
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForWalletTemplateDetails());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-templates-$TEMPLATE_ID
+ */
+ async useTemplateCreateOrder(templateId, body) {
+ const url = new URL(`templates/${templateId}`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body
+ });
+ return this.procesOrderCreationResponse(resp);
+ }
+ //
+ // Webhooks
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-private-webhooks
+ */
+ async addWebhook(token, body) {
+ const url = new URL(`private/webhooks`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
+ */
+ async updateWebhook(token, webhookId, body) {
+ const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-webhooks
+ */
+ async listWebhooks(token, params) {
+ const url = new URL(`private/webhooks`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForWebhookSummaryResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
+ */
+ async getWebhookDetails(token, webhookId) {
+ const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opSuccessFromHttp(resp, codecForWebhookDetails());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
+ */
+ async deleteWebhook(token, webhookId) {
+ const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ //
+ // token families
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-private-tokenfamilies
+ */
+ async createTokenFamily(token, body) {
+ const url = new URL(`private/tokenfamilies`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.CREATE_TOKENFAMILY);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
+ */
+ async updateTokenFamily(token, tokenSlug, body) {
+ const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.UPDATE_TOKENFAMILY);
+ return opSuccessFromHttp(resp, codecForTokenFamilyDetails());
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-tokenfamilies
+ */
+ async listTokenFamilies(token, params) {
+ const url = new URL(`private/tokenfamilies`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTokenFamiliesList());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
+ */
+ async getTokenFamilyDetails(token, tokenSlug) {
+ const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForTokenFamilyDetails());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
+ */
+ async deleteTokenFamily(token, tokenSlug) {
+ const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheEvictor.notifySuccess(TalerMerchantInstanceCacheEviction.DELETE_TOKENFAMILY);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * Get the auth api against the current instance
+ *
+ * https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-token
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-token
+ */
+ getAuthenticationAPI() {
+ return new URL(`private/`, this.baseUrl);
+ }
+};
+var TalerMerchantManagementHttpClient = class extends TalerMerchantInstanceHttpClient {
+ constructor(baseUrl, httpClient, cacheEvictor) {
+ super(baseUrl, httpClient, cacheEvictor);
+ this.baseUrl = baseUrl;
+ this.cacheManagementEvictor = cacheEvictor ?? nullEvictor;
+ }
+ getSubInstanceAPI(instanceId) {
+ return new URL(`instances/${instanceId}/`, this.baseUrl);
+ }
+ //
+ // Instance Management
+ //
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post--management-instances
+ */
+ async createInstance(token, body) {
+ const url = new URL(`management/instances`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.CREATE_INSTANCE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#post--management-instances-$INSTANCE-auth
+ */
+ async updateInstanceAuthentication(token, instanceId, body) {
+ const url = new URL(`management/instances/${instanceId}/auth`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "POST",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#patch--management-instances-$INSTANCE
+ */
+ async updateInstance(token, instanceId, body) {
+ const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "PATCH",
+ body,
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.UPDATE_INSTANCE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--management-instances
+ */
+ async listInstances(token, params) {
+ const url = new URL(`management/instances`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForInstancesResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE
+ *
+ */
+ async getInstanceDetails(token, instanceId) {
+ const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForQueryInstancesResponse());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#delete--management-instances-$INSTANCE
+ */
+ async deleteInstance(token, instanceId, params = {}) {
+ const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
+ if (params.purge !== void 0) {
+ url.searchParams.set("purge", params.purge ? "YES" : "NO");
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "DELETE",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.NoContent: {
+ this.cacheManagementEvictor.notifySuccess(TalerMerchantManagementCacheEviction.DELETE_INSTANCE);
+ return opEmptySuccess(resp);
+ }
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE-kyc
+ */
+ async getIntanceKycStatus(token, instanceId, params) {
+ const url = new URL(`management/instances/${instanceId}/kyc`, this.baseUrl);
+ if (params.wireHash) {
+ url.searchParams.set("h_wire", params.wireHash);
+ }
+ if (params.exchangeURL) {
+ url.searchParams.set("exchange_url", params.exchangeURL);
+ }
+ if (params.timeout) {
+ url.searchParams.set("timeout_ms", String(params.timeout));
+ }
+ const headers = {};
+ if (token) {
+ headers.Authorization = makeBearerTokenAuthHeader(token);
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Accepted:
+ return opSuccessFromHttp(resp, codecForAccountKycRedirects());
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.ServiceUnavailable:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+};
+
+// ../taler-util/lib/http-client/bank-revenue.js
+var TalerRevenueHttpClient = class {
+ constructor(baseUrl, httpClient) {
+ this.baseUrl = baseUrl;
+ this.PROTOCOL_VERSION = "0:0:0";
+ this.httpLib = httpClient ?? createPlatformHttpLib();
+ }
+ isCompatible(version) {
+ const compare2 = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
+ return compare2?.compatible ?? false;
+ }
+ /**
+ * https://docs.taler.net/core/api-bank-revenue.html#get--config
+ *
+ */
+ async getConfig(auth) {
+ const url = new URL(`config`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: auth ? makeBasicAuthHeader(auth.username, auth.password) : void 0
+ }
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForRevenueConfig());
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+ /**
+ * https://docs.taler.net/core/api-bank-revenue.html#get--history
+ *
+ * @returns
+ */
+ async getHistory(auth, params) {
+ const url = new URL(`history`, this.baseUrl);
+ addPaginationParams(url, params);
+ addLongPollingParam(url, params);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: auth ? makeBasicAuthHeader(auth.username, auth.password) : void 0
+ }
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForRevenueIncomingHistory());
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await readTalerErrorResponse(resp));
+ }
+ }
+};
+
// ../taler-util/lib/i18n.js
var jedLib = __toESM(require_jed(), 1);
var logger9 = new Logger("i18n/index.ts");
@@ -15199,8 +18002,64 @@ var ObservabilityEventType;
ObservabilityEventType2["CryptoStart"] = "crypto-start";
ObservabilityEventType2["CryptoFinishSuccess"] = "crypto-finish-success";
ObservabilityEventType2["CryptoFinishError"] = "crypto-finish-error";
+ ObservabilityEventType2["Message"] = "message";
})(ObservabilityEventType || (ObservabilityEventType = {}));
+// ../taler-util/lib/observability.js
+var seqId = 1e3;
+var ObservableHttpClientLibrary = class {
+ constructor(impl, oc) {
+ this.impl = impl;
+ this.oc = oc;
+ this.cancelatorById = /* @__PURE__ */ new Map();
+ }
+ cancelRequest(id) {
+ const cancelator = this.cancelatorById.get(id);
+ if (!cancelator)
+ return;
+ cancelator.cancel();
+ }
+ async fetch(url, opt) {
+ const id = `req-${seqId}`;
+ seqId = seqId + 1;
+ const cancelator = CancellationToken.create();
+ if (opt?.cancellationToken) {
+ opt.cancellationToken.onCancelled(cancelator.cancel);
+ }
+ this.cancelatorById.set(id, cancelator);
+ this.oc.observe({
+ id,
+ when: AbsoluteTime.now(),
+ type: ObservabilityEventType.HttpFetchStart,
+ url
+ });
+ const optsWithCancel = opt ?? {};
+ optsWithCancel.cancellationToken = cancelator.token;
+ try {
+ const res = await this.impl.fetch(url, optsWithCancel);
+ this.oc.observe({
+ id,
+ when: AbsoluteTime.now(),
+ type: ObservabilityEventType.HttpFetchFinishSuccess,
+ url,
+ status: res.status
+ });
+ return res;
+ } catch (e4) {
+ this.oc.observe({
+ id,
+ when: AbsoluteTime.now(),
+ type: ObservabilityEventType.HttpFetchFinishError,
+ url,
+ error: getErrorDetailFromException(e4)
+ });
+ throw e4;
+ } finally {
+ this.cancelatorById.delete(id);
+ }
+ }
+};
+
// ../taler-util/lib/rfc3548.js
var encTable2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
function encodeRfc3548Base32(data) {
@@ -15398,6 +18257,14 @@ init_hooks_module();
init_preact_module();
init_hooks_module();
init_preact_module();
+init_hooks_module();
+init_preact_module();
+init_hooks_module();
+init_preact_module();
+init_hooks_module();
+init_preact_module();
+init_hooks_module();
+init_preact_module();
init_preact_module();
init_preact_module();
init_hooks_module();
@@ -15778,8 +18645,8 @@ function getBrowserLang(completeness) {
return void 0;
}
var langPreferenceKey = buildStorageKey("lang-preference");
-function useLang(initial2, completeness) {
- const defaultValue = (getBrowserLang(completeness) || initial2 || "en").substring(0, 2);
+function useLang(initial22, completeness) {
+ const defaultValue = (getBrowserLang(completeness) || initial22 || "en").substring(0, 2);
return useLocalStorage(langPreferenceKey, defaultValue);
}
var storage2 = memoryMap();
@@ -15870,18 +18737,10 @@ function strToUTF8Arr(sDOMStr) {
}
return aBytes;
}
-var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
- ErrorType2[ErrorType2["CLIENT"] = 0] = "CLIENT";
- ErrorType2[ErrorType2["SERVER"] = 1] = "SERVER";
- ErrorType2[ErrorType2["UNREADABLE"] = 2] = "UNREADABLE";
- ErrorType2[ErrorType2["TIMEOUT"] = 3] = "TIMEOUT";
- ErrorType2[ErrorType2["UNEXPECTED"] = 4] = "UNEXPECTED";
- return ErrorType2;
-})(ErrorType || {});
async function defaultRequestHandler(baseUrl, endpoint, options = {}) {
const requestHeaders = {};
if (options.token) {
- requestHeaders.Authorization = `Bearer ${options.token}`;
+ requestHeaders.Authorization = `Bearer secret-token:${options.token}`;
} else if (options.basicAuth) {
requestHeaders.Authorization = `Basic ${base64encode(
`${options.basicAuth.username}:${options.basicAuth.password}`
@@ -16100,8 +18959,166 @@ function validateURL(baseUrl, endpoint) {
}
}
var logger11 = new Logger("browserHttpLib");
+var BrowserFetchHttpLib = class {
+ constructor(args) {
+ this.throttle = new RequestThrottler();
+ this.throttlingEnabled = true;
+ this.requireTls = false;
+ this.throttlingEnabled = args?.enableThrottling ?? true;
+ this.requireTls = args?.requireTls ?? false;
+ }
+ async fetch(requestUrl, options) {
+ const requestMethod = options?.method ?? "GET";
+ const requestBody = options?.body;
+ const requestHeader = options?.headers;
+ const requestTimeout = options?.timeout ?? Duration.fromMilliseconds(DEFAULT_REQUEST_TIMEOUT_MS);
+ const requestCancel = options?.cancellationToken;
+ const parsedUrl = new URL(requestUrl);
+ if (this.throttlingEnabled && this.throttle.applyThrottle(requestUrl)) {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED,
+ {
+ requestMethod,
+ requestUrl,
+ throttleStats: this.throttle.getThrottleStats(requestUrl)
+ },
+ `request to origin ${parsedUrl.origin} was throttled`
+ );
+ }
+ if (this.requireTls && parsedUrl.protocol !== "https:") {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_NETWORK_ERROR,
+ {
+ requestMethod,
+ requestUrl
+ },
+ `request to ${parsedUrl.origin} is not possible with protocol ${parsedUrl.protocol}`
+ );
+ }
+ const myBody = requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH" ? encodeBody(requestBody) : void 0;
+ const requestHeadersMap = getDefaultHeaders(requestMethod);
+ if (requestHeader) {
+ Object.entries(requestHeader).forEach(([key, value]) => {
+ if (value === void 0)
+ return;
+ requestHeadersMap[key] = value;
+ });
+ }
+ const controller = new AbortController();
+ let timeoutId;
+ if (requestTimeout.d_ms !== "forever") {
+ timeoutId = setTimeout(() => {
+ controller.abort(TalerErrorCode.GENERIC_TIMEOUT);
+ }, requestTimeout.d_ms);
+ }
+ if (requestCancel) {
+ requestCancel.onCancelled(() => {
+ controller.abort(TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR);
+ });
+ }
+ try {
+ const response = await fetch(requestUrl, {
+ headers: requestHeadersMap,
+ body: myBody,
+ method: requestMethod,
+ signal: controller.signal
+ });
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+ const headerMap = new Headers2();
+ response.headers.forEach((value, key) => {
+ headerMap.set(key, value);
+ });
+ return {
+ headers: headerMap,
+ status: response.status,
+ requestMethod,
+ requestUrl,
+ json: makeJsonHandler(response, requestUrl, requestMethod),
+ text: makeTextHandler(response, requestUrl, requestMethod),
+ bytes: async () => (await response.blob()).arrayBuffer()
+ };
+ } catch (e22) {
+ if (controller.signal) {
+ throw TalerError.fromDetail(
+ controller.signal.reason,
+ {
+ requestUrl,
+ requestMethod,
+ timeoutMs: requestTimeout.d_ms === "forever" ? 0 : requestTimeout.d_ms
+ },
+ `HTTP request failed.`
+ );
+ }
+ throw e22;
+ }
+ }
+};
+function makeTextHandler(response, requestUrl, requestMethod) {
+ return async function getTextFromResponse() {
+ let respText;
+ try {
+ respText = await response.text();
+ } catch (e22) {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+ {
+ requestUrl,
+ requestMethod,
+ httpStatusCode: response.status
+ },
+ "Invalid text from HTTP response"
+ );
+ }
+ return respText;
+ };
+}
+function makeJsonHandler(response, requestUrl, requestMethod) {
+ let responseJson = void 0;
+ return async function getJsonFromResponse() {
+ if (responseJson === void 0) {
+ try {
+ responseJson = await response.json();
+ } catch (e22) {
+ const message = e22 instanceof Error ? `Invalid JSON from HTTP response: ${e22.message}` : "Invalid JSON from HTTP response";
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+ {
+ requestUrl,
+ requestMethod,
+ httpStatusCode: response.status
+ },
+ message
+ );
+ }
+ }
+ if (responseJson === null || typeof responseJson !== "object") {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+ {
+ requestUrl,
+ requestMethod,
+ httpStatusCode: response.status
+ },
+ "Invalid JSON from HTTP response: null or not object"
+ );
+ }
+ return responseJson;
+ };
+}
+function urlPattern(pattern, reverse) {
+ const url = reverse;
+ return {
+ pattern: new RegExp(pattern),
+ url
+ };
+}
+var nullRountDef = {
+ pattern: new RegExp(/.*/),
+ url: () => ""
+};
var Context = B({ request: defaultRequestHandler });
-var useApiContext = () => q2(Context);
function buildFormatLongFn(args) {
return function() {
var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
@@ -23215,7 +26232,7 @@ var initial = {
};
var Context2 = B(initial);
var TranslationProvider = ({
- initial: initial2,
+ initial: initial22,
children,
forceLang,
source,
@@ -23229,7 +26246,7 @@ var TranslationProvider = ({
it: !completenessProp || !completenessProp["it"] ? 0 : completenessProp["it"],
sv: !completenessProp || !completenessProp["sv"] ? 0 : completenessProp["sv"]
};
- const { value: lang, update: changeLanguage } = useLang(initial2, completeness);
+ const { value: lang, update: changeLanguage } = useLang(initial22, completeness);
h2(() => {
if (forceLang) {
changeLanguage(forceLang);
@@ -23250,6 +26267,205 @@ var TranslationProvider = ({
});
};
var useTranslationContext = () => q2(Context2);
+var ActiviyTracker = class {
+ constructor() {
+ this.observers = new Array();
+ this.notify = this.notify.bind(this);
+ this.subscribe = this.subscribe.bind(this);
+ }
+ notify(data) {
+ this.observers.forEach((observer) => observer(data));
+ }
+ subscribe(func) {
+ this.observers.push(func);
+ return () => {
+ this.observers.forEach((observer, index) => {
+ if (observer === func) {
+ this.observers.splice(index, 1);
+ }
+ });
+ };
+ }
+};
+var BankContext = B(void 0);
+var MerchantContext = B(void 0);
+var useMerchantApiContext = () => q2(MerchantContext);
+var CONFIG_FAIL_TRY_AGAIN_MS2 = 5e3;
+var MerchantApiProvider = ({
+ baseUrl,
+ children,
+ evictors = {},
+ frameOnError
+}) => {
+ const [checked, setChecked] = p3();
+ const [merchantEndpoint, changeMerchantEndpoint] = p3(baseUrl);
+ const { getRemoteConfig, VERSION: VERSION2, lib, cancelRequest, onActivity } = buildMerchantApiClient(merchantEndpoint, evictors);
+ h2(() => {
+ let keepRetrying = true;
+ async function testConfig() {
+ try {
+ const config = await getRemoteConfig();
+ if (LibtoolVersion.compare(VERSION2, config.version)) {
+ setChecked({ type: "ok", config, hints: [] });
+ } else {
+ setChecked({
+ type: "incompatible",
+ result: config,
+ supported: VERSION2
+ });
+ }
+ } catch (error2) {
+ if (error2 instanceof TalerError) {
+ if (keepRetrying) {
+ setTimeout(() => {
+ testConfig();
+ }, CONFIG_FAIL_TRY_AGAIN_MS2);
+ }
+ setChecked({ type: "error", error: error2 });
+ } else {
+ setChecked({ type: "error", error: TalerError.fromException(error2) });
+ }
+ }
+ }
+ testConfig();
+ return () => {
+ keepRetrying = false;
+ };
+ }, []);
+ if (!checked || checked.type !== "ok") {
+ return h(frameOnError, { state: checked }, []);
+ }
+ const value = {
+ url: merchantEndpoint,
+ config: checked.config,
+ onActivity,
+ lib,
+ cancelRequest,
+ changeBackend: changeMerchantEndpoint,
+ hints: checked.hints
+ };
+ return h(MerchantContext.Provider, {
+ value,
+ children
+ });
+};
+function buildMerchantApiClient(url, evictors) {
+ const httpFetch = new BrowserFetchHttpLib({
+ enableThrottling: true,
+ requireTls: false
+ });
+ const tracker = new ActiviyTracker();
+ const httpLib = new ObservableHttpClientLibrary(httpFetch, {
+ observe(ev) {
+ tracker.notify(ev);
+ }
+ });
+ const instance = new TalerMerchantManagementHttpClient(
+ url.href,
+ httpLib,
+ evictors.management
+ );
+ const authenticate = new TalerAuthenticationHttpClient(
+ instance.getAuthenticationAPI().href,
+ httpLib
+ );
+ const rootUrl = url;
+ function getSubInstanceAPI(instanceId) {
+ const newURL = new URL(`instance/${instanceId}/`, rootUrl);
+ const api = buildMerchantApiClient(newURL, evictors);
+ return api.lib;
+ }
+ async function getRemoteConfig() {
+ const resp = await instance.getConfig();
+ if (resp.type === "fail") {
+ throw TalerError.fromUncheckedDetail(resp.detail);
+ }
+ return resp.body;
+ }
+ return {
+ getRemoteConfig,
+ VERSION: instance.PROTOCOL_VERSION,
+ lib: {
+ instance,
+ authenticate,
+ subInstanceApi: getSubInstanceAPI
+ },
+ onActivity: tracker.subscribe,
+ cancelRequest: httpLib.cancelRequest
+ };
+}
+var Context3 = B(void 0);
+var useNavigationContext = () => q2(Context3);
+function getPathAndParamsFromWindow() {
+ const path = typeof window !== "undefined" ? window.location.hash.substring(1) : "/";
+ const params = {};
+ if (typeof window !== "undefined") {
+ for (const [key, value] of new URLSearchParams(window.location.search)) {
+ params[key] = value;
+ }
+ }
+ return { path, params };
+}
+var { path: initialPath, params: initialParams } = getPathAndParamsFromWindow();
+var PopStateEventType = "popstate";
+var BrowserHashNavigationProvider = ({
+ children
+}) => {
+ const [{ path, params }, setState] = p3({
+ path: initialPath,
+ params: initialParams
+ });
+ if (typeof window === "undefined") {
+ throw Error(
+ "Can't use BrowserHashNavigationProvider if there is no window object"
+ );
+ }
+ function navigateTo(path2) {
+ const { params: params2 } = getPathAndParamsFromWindow();
+ setState({ path: path2, params: params2 });
+ window.location.href = path2;
+ }
+ h2(() => {
+ function eventListener() {
+ setState(getPathAndParamsFromWindow());
+ }
+ window.addEventListener(PopStateEventType, eventListener);
+ return () => {
+ window.removeEventListener(PopStateEventType, eventListener);
+ };
+ }, []);
+ return h(Context3.Provider, {
+ value: { path, params, navigateTo },
+ children
+ });
+};
+function createHeadMetaTag(uri, onNotFound) {
+ const meta = document.createElement("meta");
+ meta.setAttribute("name", "taler-uri");
+ meta.setAttribute("content", stringifyTalerUri(uri));
+ document.head.appendChild(meta);
+ let walletFound = false;
+ window.addEventListener("beforeunload", () => {
+ walletFound = true;
+ });
+ setTimeout(() => {
+ if (!walletFound && onNotFound) {
+ onNotFound();
+ }
+ }, 10);
+}
+var Context4 = B(void 0);
+var TalerWalletIntegrationBrowserProvider = ({
+ children
+}) => {
+ const value = {
+ publishTalerAction: createHeadMetaTag
+ };
+ return h(Context4.Provider, {
+ value,
+ children
+ });
+};
var utils_exports = {};
__export2(utils_exports, {
compose: () => compose,
@@ -23271,8 +26487,8 @@ function compose(hook, viewMap) {
return ComposedComponent;
}
return (p4) => {
- const h37 = withHook(() => hook(p4));
- return h37();
+ const h41 = withHook(() => hook(p4));
+ return h41();
};
}
function recursive(hook) {
@@ -23288,8 +26504,8 @@ function recursive(hook) {
return ComposedComponent;
}
return (p4) => {
- const h37 = withHook(() => hook(p4));
- return h37();
+ const h41 = withHook(() => hook(p4));
+ return h41();
};
}
function saveVNodeForInspection(obj) {
@@ -23339,6 +26555,930 @@ var FormContext = B({});
init_preact_module();
init_hooks_module();
+// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/core/dist/index.mjs
+init_compat_module();
+var import_shim = __toESM(require_shim(), 1);
+
+// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/_internal/dist/index.mjs
+init_compat_module();
+var noop = () => {
+};
+var UNDEFINED = (
+ /*#__NOINLINE__*/
+ noop()
+);
+var OBJECT = Object;
+var isUndefined = (v3) => v3 === UNDEFINED;
+var isFunction = (v3) => typeof v3 == "function";
+var mergeObjects = (a5, b4) => ({
+ ...a5,
+ ...b4
+});
+var isPromiseLike = (x6) => isFunction(x6.then);
+var table = /* @__PURE__ */ new WeakMap();
+var counter = 0;
+var stableHash = (arg) => {
+ const type = typeof arg;
+ const constructor = arg && arg.constructor;
+ const isDate3 = constructor == Date;
+ let result;
+ let index;
+ if (OBJECT(arg) === arg && !isDate3 && constructor != RegExp) {
+ result = table.get(arg);
+ if (result)
+ return result;
+ result = ++counter + "~";
+ table.set(arg, result);
+ if (constructor == Array) {
+ result = "@";
+ for (index = 0; index < arg.length; index++) {
+ result += stableHash(arg[index]) + ",";
+ }
+ table.set(arg, result);
+ }
+ if (constructor == OBJECT) {
+ result = "#";
+ const keys = OBJECT.keys(arg).sort();
+ while (!isUndefined(index = keys.pop())) {
+ if (!isUndefined(arg[index])) {
+ result += index + ":" + stableHash(arg[index]) + ",";
+ }
+ }
+ table.set(arg, result);
+ }
+ } else {
+ result = isDate3 ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
+ }
+ return result;
+};
+var SWRGlobalState = /* @__PURE__ */ new WeakMap();
+var EMPTY_CACHE = {};
+var INITIAL_CACHE = {};
+var STR_UNDEFINED = "undefined";
+var isWindowDefined = typeof window != STR_UNDEFINED;
+var isDocumentDefined = typeof document != STR_UNDEFINED;
+var hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED;
+var createCacheHelper = (cache2, key) => {
+ const state = SWRGlobalState.get(cache2);
+ return [
+ // Getter
+ () => !isUndefined(key) && cache2.get(key) || EMPTY_CACHE,
+ // Setter
+ (info) => {
+ if (!isUndefined(key)) {
+ const prev = cache2.get(key);
+ if (!(key in INITIAL_CACHE)) {
+ INITIAL_CACHE[key] = prev;
+ }
+ state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);
+ }
+ },
+ // Subscriber
+ state[6],
+ // Get server cache snapshot
+ () => {
+ if (!isUndefined(key)) {
+ if (key in INITIAL_CACHE)
+ return INITIAL_CACHE[key];
+ }
+ return !isUndefined(key) && cache2.get(key) || EMPTY_CACHE;
+ }
+ ];
+};
+var online = true;
+var isOnline = () => online;
+var [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
+ window.addEventListener.bind(window),
+ window.removeEventListener.bind(window)
+] : [
+ noop,
+ noop
+];
+var isVisible = () => {
+ const visibilityState = isDocumentDefined && document.visibilityState;
+ return isUndefined(visibilityState) || visibilityState !== "hidden";
+};
+var initFocus = (callback) => {
+ if (isDocumentDefined) {
+ document.addEventListener("visibilitychange", callback);
+ }
+ onWindowEvent("focus", callback);
+ return () => {
+ if (isDocumentDefined) {
+ document.removeEventListener("visibilitychange", callback);
+ }
+ offWindowEvent("focus", callback);
+ };
+};
+var initReconnect = (callback) => {
+ const onOnline = () => {
+ online = true;
+ callback();
+ };
+ const onOffline = () => {
+ online = false;
+ };
+ onWindowEvent("online", onOnline);
+ onWindowEvent("offline", onOffline);
+ return () => {
+ offWindowEvent("online", onOnline);
+ offWindowEvent("offline", onOffline);
+ };
+};
+var preset = {
+ isOnline,
+ isVisible
+};
+var defaultConfigOptions = {
+ initFocus,
+ initReconnect
+};
+var IS_REACT_LEGACY = !bn.useId;
+var IS_SERVER = !isWindowDefined || "Deno" in window;
+var rAF = (f3) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f3) : setTimeout(f3, 1);
+var useIsomorphicLayoutEffect = IS_SERVER ? h2 : s2;
+var navigatorConnection = typeof navigator !== "undefined" && navigator.connection;
+var slowConnection = !IS_SERVER && navigatorConnection && ([
+ "slow-2g",
+ "2g"
+].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
+var serialize = (key) => {
+ if (isFunction(key)) {
+ try {
+ key = key();
+ } catch (err) {
+ key = "";
+ }
+ }
+ const args = key;
+ key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : "";
+ return [
+ key,
+ args
+ ];
+};
+var __timestamp = 0;
+var getTimestamp = () => ++__timestamp;
+var FOCUS_EVENT = 0;
+var RECONNECT_EVENT = 1;
+var MUTATE_EVENT = 2;
+var ERROR_REVALIDATE_EVENT = 3;
+var events = {
+ __proto__: null,
+ ERROR_REVALIDATE_EVENT,
+ FOCUS_EVENT,
+ MUTATE_EVENT,
+ RECONNECT_EVENT
+};
+async function internalMutate(...args) {
+ const [cache2, _key, _data, _opts] = args;
+ const options = mergeObjects({
+ populateCache: true,
+ throwOnError: true
+ }, typeof _opts === "boolean" ? {
+ revalidate: _opts
+ } : _opts || {});
+ let populateCache = options.populateCache;
+ const rollbackOnErrorOption = options.rollbackOnError;
+ let optimisticData = options.optimisticData;
+ const revalidate = options.revalidate !== false;
+ const rollbackOnError = (error2) => {
+ return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error2) : rollbackOnErrorOption !== false;
+ };
+ const throwOnError = options.throwOnError;
+ if (isFunction(_key)) {
+ const keyFilter = _key;
+ const matchedKeys = [];
+ const it = cache2.keys();
+ for (const key of it) {
+ if (
+ // Skip the special useSWRInfinite and useSWRSubscription keys.
+ !/^\$(inf|sub)\$/.test(key) && keyFilter(cache2.get(key)._k)
+ ) {
+ matchedKeys.push(key);
+ }
+ }
+ return Promise.all(matchedKeys.map(mutateByKey));
+ }
+ return mutateByKey(_key);
+ async function mutateByKey(_k) {
+ const [key] = serialize(_k);
+ if (!key)
+ return;
+ const [get, set2] = createCacheHelper(cache2, key);
+ const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
+ const startRevalidate = () => {
+ const revalidators = EVENT_REVALIDATORS[key];
+ if (revalidate) {
+ delete FETCH[key];
+ delete PRELOAD[key];
+ if (revalidators && revalidators[0]) {
+ return revalidators[0](MUTATE_EVENT).then(() => get().data);
+ }
+ }
+ return get().data;
+ };
+ if (args.length < 3) {
+ return startRevalidate();
+ }
+ let data = _data;
+ let error2;
+ const beforeMutationTs = getTimestamp();
+ MUTATION[key] = [
+ beforeMutationTs,
+ 0
+ ];
+ const hasOptimisticData = !isUndefined(optimisticData);
+ const state = get();
+ const displayedData = state.data;
+ const currentData = state._c;
+ const committedData = isUndefined(currentData) ? displayedData : currentData;
+ if (hasOptimisticData) {
+ optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
+ set2({
+ data: optimisticData,
+ _c: committedData
+ });
+ }
+ if (isFunction(data)) {
+ try {
+ data = data(committedData);
+ } catch (err) {
+ error2 = err;
+ }
+ }
+ if (data && isPromiseLike(data)) {
+ data = await data.catch((err) => {
+ error2 = err;
+ });
+ if (beforeMutationTs !== MUTATION[key][0]) {
+ if (error2)
+ throw error2;
+ return data;
+ } else if (error2 && hasOptimisticData && rollbackOnError(error2)) {
+ populateCache = true;
+ set2({
+ data: committedData,
+ _c: UNDEFINED
+ });
+ }
+ }
+ if (populateCache) {
+ if (!error2) {
+ if (isFunction(populateCache)) {
+ const populateCachedData = populateCache(data, committedData);
+ set2({
+ data: populateCachedData,
+ error: UNDEFINED,
+ _c: UNDEFINED
+ });
+ } else {
+ set2({
+ data,
+ error: UNDEFINED,
+ _c: UNDEFINED
+ });
+ }
+ }
+ }
+ MUTATION[key][1] = getTimestamp();
+ Promise.resolve(startRevalidate()).then(() => {
+ set2({
+ _c: UNDEFINED
+ });
+ });
+ if (error2) {
+ if (throwOnError)
+ throw error2;
+ return;
+ }
+ return data;
+ }
+}
+var revalidateAllKeys = (revalidators, type) => {
+ for (const key in revalidators) {
+ if (revalidators[key][0])
+ revalidators[key][0](type);
+ }
+};
+var initCache = (provider, options) => {
+ if (!SWRGlobalState.has(provider)) {
+ const opts = mergeObjects(defaultConfigOptions, options);
+ const EVENT_REVALIDATORS = {};
+ const mutate2 = internalMutate.bind(UNDEFINED, provider);
+ let unmount = noop;
+ const subscriptions = {};
+ const subscribe = (key, callback) => {
+ const subs = subscriptions[key] || [];
+ subscriptions[key] = subs;
+ subs.push(callback);
+ return () => subs.splice(subs.indexOf(callback), 1);
+ };
+ const setter = (key, value, prev) => {
+ provider.set(key, value);
+ const subs = subscriptions[key];
+ if (subs) {
+ for (const fn2 of subs) {
+ fn2(value, prev);
+ }
+ }
+ };
+ const initProvider = () => {
+ if (!SWRGlobalState.has(provider)) {
+ SWRGlobalState.set(provider, [
+ EVENT_REVALIDATORS,
+ {},
+ {},
+ {},
+ mutate2,
+ setter,
+ subscribe
+ ]);
+ if (!IS_SERVER) {
+ const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, FOCUS_EVENT)));
+ const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, RECONNECT_EVENT)));
+ unmount = () => {
+ releaseFocus && releaseFocus();
+ releaseReconnect && releaseReconnect();
+ SWRGlobalState.delete(provider);
+ };
+ }
+ }
+ };
+ initProvider();
+ return [
+ provider,
+ mutate2,
+ initProvider,
+ unmount
+ ];
+ }
+ return [
+ provider,
+ SWRGlobalState.get(provider)[4]
+ ];
+};
+var onErrorRetry = (_3, __, config, revalidate, opts) => {
+ const maxRetryCount = config.errorRetryCount;
+ const currentRetryCount = opts.retryCount;
+ const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
+ if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) {
+ return;
+ }
+ setTimeout(revalidate, timeout, opts);
+};
+var compare = (currentData, newData) => stableHash(currentData) == stableHash(newData);
+var [cache, mutate] = initCache(/* @__PURE__ */ new Map());
+var defaultConfig = mergeObjects(
+ {
+ // events
+ onLoadingSlow: noop,
+ onSuccess: noop,
+ onError: noop,
+ onErrorRetry,
+ onDiscarded: noop,
+ // switches
+ revalidateOnFocus: true,
+ revalidateOnReconnect: true,
+ revalidateIfStale: true,
+ shouldRetryOnError: true,
+ // timeouts
+ errorRetryInterval: slowConnection ? 1e4 : 5e3,
+ focusThrottleInterval: 5 * 1e3,
+ dedupingInterval: 2 * 1e3,
+ loadingTimeout: slowConnection ? 5e3 : 3e3,
+ // providers
+ compare,
+ isPaused: () => false,
+ cache,
+ mutate,
+ fallback: {}
+ },
+ // use web preset by default
+ preset
+);
+var mergeConfigs = (a5, b4) => {
+ const v3 = mergeObjects(a5, b4);
+ if (b4) {
+ const { use: u1, fallback: f1 } = a5;
+ const { use: u22, fallback: f22 } = b4;
+ if (u1 && u22) {
+ v3.use = u1.concat(u22);
+ }
+ if (f1 && f22) {
+ v3.fallback = mergeObjects(f1, f22);
+ }
+ }
+ return v3;
+};
+var SWRConfigContext = B({});
+var SWRConfig = (props) => {
+ const { value } = props;
+ const parentConfig = q2(SWRConfigContext);
+ const isFunctionalConfig = isFunction(value);
+ const config = F(() => isFunctionalConfig ? value(parentConfig) : value, [
+ isFunctionalConfig,
+ parentConfig,
+ value
+ ]);
+ const extendedConfig = F(() => isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [
+ isFunctionalConfig,
+ parentConfig,
+ config
+ ]);
+ const provider = config && config.provider;
+ const cacheContextRef = _2(UNDEFINED);
+ if (provider && !cacheContextRef.current) {
+ cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config);
+ }
+ const cacheContext = cacheContextRef.current;
+ if (cacheContext) {
+ extendedConfig.cache = cacheContext[0];
+ extendedConfig.mutate = cacheContext[1];
+ }
+ useIsomorphicLayoutEffect(() => {
+ if (cacheContext) {
+ cacheContext[2] && cacheContext[2]();
+ return cacheContext[3];
+ }
+ }, []);
+ return h(SWRConfigContext.Provider, mergeObjects(props, {
+ value: extendedConfig
+ }));
+};
+var INFINITE_PREFIX = "$inf$";
+var enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
+var use = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
+var setupDevTools = () => {
+ if (enableDevtools) {
+ window.__SWR_DEVTOOLS_REACT__ = bn;
+ }
+};
+var normalize = (args) => {
+ return isFunction(args[1]) ? [
+ args[0],
+ args[1],
+ args[2] || {}
+ ] : [
+ args[0],
+ null,
+ (args[1] === null ? args[2] : args[1]) || {}
+ ];
+};
+var useSWRConfig = () => {
+ return mergeObjects(defaultConfig, q2(SWRConfigContext));
+};
+var middleware = (useSWRNext) => (key_, fetcher_, config) => {
+ const fetcher = fetcher_ && ((...args) => {
+ const [key] = serialize(key_);
+ const [, , , PRELOAD] = SWRGlobalState.get(cache);
+ if (key.startsWith(INFINITE_PREFIX)) {
+ return fetcher_(...args);
+ }
+ const req = PRELOAD[key];
+ if (isUndefined(req))
+ return fetcher_(...args);
+ delete PRELOAD[key];
+ return req;
+ });
+ return useSWRNext(key_, fetcher, config);
+};
+var BUILT_IN_MIDDLEWARE = use.concat(middleware);
+var withArgs = (hook) => {
+ return function useSWRArgs(...args) {
+ const fallbackConfig = useSWRConfig();
+ const [key, fn2, _config] = normalize(args);
+ const config = mergeConfigs(fallbackConfig, _config);
+ let next = hook;
+ const { use: use3 } = config;
+ const middleware2 = (use3 || []).concat(BUILT_IN_MIDDLEWARE);
+ for (let i4 = middleware2.length; i4--; ) {
+ next = middleware2[i4](next);
+ }
+ return next(key, fn2 || config.fetcher || null, config);
+ };
+};
+var subscribeCallback = (key, callbacks, callback) => {
+ const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
+ keyedRevalidators.push(callback);
+ return () => {
+ const index = keyedRevalidators.indexOf(callback);
+ if (index >= 0) {
+ keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
+ keyedRevalidators.pop();
+ }
+ };
+};
+setupDevTools();
+
+// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/core/dist/index.mjs
+var use2 = bn.use || ((promise) => {
+ if (promise.status === "pending") {
+ throw promise;
+ } else if (promise.status === "fulfilled") {
+ return promise.value;
+ } else if (promise.status === "rejected") {
+ throw promise.reason;
+ } else {
+ promise.status = "pending";
+ promise.then((v3) => {
+ promise.status = "fulfilled";
+ promise.value = v3;
+ }, (e4) => {
+ promise.status = "rejected";
+ promise.reason = e4;
+ });
+ throw promise;
+ }
+});
+var WITH_DEDUPE = {
+ dedupe: true
+};
+var useSWRHandler = (_key, fetcher, config) => {
+ const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config;
+ const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
+ const [key, fnArg] = serialize(_key);
+ const initialMountedRef = _2(false);
+ const unmountedRef = _2(false);
+ const keyRef = _2(key);
+ const fetcherRef = _2(fetcher);
+ const configRef = _2(config);
+ const getConfig = () => configRef.current;
+ const isActive = () => getConfig().isVisible() && getConfig().isOnline();
+ const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key);
+ const stateDependencies = _2({}).current;
+ const fallback = isUndefined(fallbackData) ? config.fallback[key] : fallbackData;
+ const isEqual = (prev, current) => {
+ for (const _3 in stateDependencies) {
+ const t4 = _3;
+ if (t4 === "data") {
+ if (!compare2(prev[t4], current[t4])) {
+ if (!isUndefined(prev[t4])) {
+ return false;
+ }
+ if (!compare2(returnedData, current[t4])) {
+ return false;
+ }
+ }
+ } else {
+ if (current[t4] !== prev[t4]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ const getSnapshot = F(() => {
+ const shouldStartRequest = (() => {
+ if (!key)
+ return false;
+ if (!fetcher)
+ return false;
+ if (!isUndefined(revalidateOnMount))
+ return revalidateOnMount;
+ if (getConfig().isPaused())
+ return false;
+ if (suspense)
+ return false;
+ if (!isUndefined(revalidateIfStale))
+ return revalidateIfStale;
+ return true;
+ })();
+ const getSelectedCache = (state) => {
+ const snapshot = mergeObjects(state);
+ delete snapshot._k;
+ if (!shouldStartRequest) {
+ return snapshot;
+ }
+ return {
+ isValidating: true,
+ isLoading: true,
+ ...snapshot
+ };
+ };
+ const cachedData2 = getCache();
+ const initialData = getInitialCache();
+ const clientSnapshot = getSelectedCache(cachedData2);
+ const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData);
+ let memorizedSnapshot = clientSnapshot;
+ return [
+ () => {
+ const newSnapshot = getSelectedCache(getCache());
+ const compareResult = isEqual(newSnapshot, memorizedSnapshot);
+ if (compareResult) {
+ memorizedSnapshot.data = newSnapshot.data;
+ memorizedSnapshot.isLoading = newSnapshot.isLoading;
+ memorizedSnapshot.isValidating = newSnapshot.isValidating;
+ memorizedSnapshot.error = newSnapshot.error;
+ return memorizedSnapshot;
+ } else {
+ memorizedSnapshot = newSnapshot;
+ return newSnapshot;
+ }
+ },
+ () => serverSnapshot
+ ];
+ }, [
+ cache2,
+ key
+ ]);
+ const cached = (0, import_shim.useSyncExternalStore)(T2(
+ (callback) => subscribeCache(key, (current, prev) => {
+ if (!isEqual(prev, current))
+ callback();
+ }),
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [
+ cache2,
+ key
+ ]
+ ), getSnapshot[0], getSnapshot[1]);
+ const isInitialMount = !initialMountedRef.current;
+ const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
+ const cachedData = cached.data;
+ const data = isUndefined(cachedData) ? fallback : cachedData;
+ const error2 = cached.error;
+ const laggyDataRef = _2(data);
+ const returnedData = keepPreviousData ? isUndefined(cachedData) ? laggyDataRef.current : cachedData : data;
+ const shouldDoInitialRevalidation = (() => {
+ if (hasRevalidator && !isUndefined(error2))
+ return false;
+ if (isInitialMount && !isUndefined(revalidateOnMount))
+ return revalidateOnMount;
+ if (getConfig().isPaused())
+ return false;
+ if (suspense)
+ return isUndefined(data) ? false : revalidateIfStale;
+ return isUndefined(data) || revalidateIfStale;
+ })();
+ const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation);
+ const isValidating = isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating;
+ const isLoading = isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading;
+ const revalidate = T2(
+ async (revalidateOpts) => {
+ const currentFetcher = fetcherRef.current;
+ if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
+ return false;
+ }
+ let newData;
+ let startAt;
+ let loading = true;
+ const opts = revalidateOpts || {};
+ const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
+ const callbackSafeguard = () => {
+ if (IS_REACT_LEGACY) {
+ return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
+ }
+ return key === keyRef.current;
+ };
+ const finalState = {
+ isValidating: false,
+ isLoading: false
+ };
+ const finishRequestAndUpdateState = () => {
+ setCache(finalState);
+ };
+ const cleanupState = () => {
+ const requestInfo = FETCH[key];
+ if (requestInfo && requestInfo[1] === startAt) {
+ delete FETCH[key];
+ }
+ };
+ const initialState = {
+ isValidating: true
+ };
+ if (isUndefined(getCache().data)) {
+ initialState.isLoading = true;
+ }
+ try {
+ if (shouldStartNewRequest) {
+ setCache(initialState);
+ if (config.loadingTimeout && isUndefined(getCache().data)) {
+ setTimeout(() => {
+ if (loading && callbackSafeguard()) {
+ getConfig().onLoadingSlow(key, config);
+ }
+ }, config.loadingTimeout);
+ }
+ FETCH[key] = [
+ currentFetcher(fnArg),
+ getTimestamp()
+ ];
+ }
+ [newData, startAt] = FETCH[key];
+ newData = await newData;
+ if (shouldStartNewRequest) {
+ setTimeout(cleanupState, config.dedupingInterval);
+ }
+ if (!FETCH[key] || FETCH[key][1] !== startAt) {
+ if (shouldStartNewRequest) {
+ if (callbackSafeguard()) {
+ getConfig().onDiscarded(key);
+ }
+ }
+ return false;
+ }
+ finalState.error = UNDEFINED;
+ const mutationInfo = MUTATION[key];
+ if (!isUndefined(mutationInfo) && // case 1
+ (startAt <= mutationInfo[0] || // case 2
+ startAt <= mutationInfo[1] || // case 3
+ mutationInfo[1] === 0)) {
+ finishRequestAndUpdateState();
+ if (shouldStartNewRequest) {
+ if (callbackSafeguard()) {
+ getConfig().onDiscarded(key);
+ }
+ }
+ return false;
+ }
+ const cacheData = getCache().data;
+ finalState.data = compare2(cacheData, newData) ? cacheData : newData;
+ if (shouldStartNewRequest) {
+ if (callbackSafeguard()) {
+ getConfig().onSuccess(newData, key, config);
+ }
+ }
+ } catch (err) {
+ cleanupState();
+ const currentConfig = getConfig();
+ const { shouldRetryOnError } = currentConfig;
+ if (!currentConfig.isPaused()) {
+ finalState.error = err;
+ if (shouldStartNewRequest && callbackSafeguard()) {
+ currentConfig.onError(err, key, currentConfig);
+ if (shouldRetryOnError === true || isFunction(shouldRetryOnError) && shouldRetryOnError(err)) {
+ if (isActive()) {
+ currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => {
+ const revalidators = EVENT_REVALIDATORS[key];
+ if (revalidators && revalidators[0]) {
+ revalidators[0](events.ERROR_REVALIDATE_EVENT, _opts);
+ }
+ }, {
+ retryCount: (opts.retryCount || 0) + 1,
+ dedupe: true
+ });
+ }
+ }
+ }
+ }
+ }
+ loading = false;
+ finishRequestAndUpdateState();
+ return true;
+ },
+ // `setState` is immutable, and `eventsCallback`, `fnArg`, and
+ // `keyValidating` are depending on `key`, so we can exclude them from
+ // the deps array.
+ //
+ // FIXME:
+ // `fn` and `config` might be changed during the lifecycle,
+ // but they might be changed every render like this.
+ // `useSWR('key', () => fetch('/api/'), { suspense: true })`
+ // So we omit the values from the deps array
+ // even though it might cause unexpected behaviors.
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [
+ key,
+ cache2
+ ]
+ );
+ const boundMutate = T2(
+ // Use callback to make sure `keyRef.current` returns latest result every time
+ (...args) => {
+ return internalMutate(cache2, keyRef.current, ...args);
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ []
+ );
+ useIsomorphicLayoutEffect(() => {
+ fetcherRef.current = fetcher;
+ configRef.current = config;
+ if (!isUndefined(cachedData)) {
+ laggyDataRef.current = cachedData;
+ }
+ });
+ useIsomorphicLayoutEffect(() => {
+ if (!key)
+ return;
+ const softRevalidate = revalidate.bind(UNDEFINED, WITH_DEDUPE);
+ let nextFocusRevalidatedAt = 0;
+ const onRevalidate = (type, opts = {}) => {
+ if (type == events.FOCUS_EVENT) {
+ const now2 = Date.now();
+ if (getConfig().revalidateOnFocus && now2 > nextFocusRevalidatedAt && isActive()) {
+ nextFocusRevalidatedAt = now2 + getConfig().focusThrottleInterval;
+ softRevalidate();
+ }
+ } else if (type == events.RECONNECT_EVENT) {
+ if (getConfig().revalidateOnReconnect && isActive()) {
+ softRevalidate();
+ }
+ } else if (type == events.MUTATE_EVENT) {
+ return revalidate();
+ } else if (type == events.ERROR_REVALIDATE_EVENT) {
+ return revalidate(opts);
+ }
+ return;
+ };
+ const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
+ unmountedRef.current = false;
+ keyRef.current = key;
+ initialMountedRef.current = true;
+ setCache({
+ _k: fnArg
+ });
+ if (shouldDoInitialRevalidation) {
+ if (isUndefined(data) || IS_SERVER) {
+ softRevalidate();
+ } else {
+ rAF(softRevalidate);
+ }
+ }
+ return () => {
+ unmountedRef.current = true;
+ unsubEvents();
+ };
+ }, [
+ key
+ ]);
+ useIsomorphicLayoutEffect(() => {
+ let timer2;
+ function next() {
+ const interval = isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
+ if (interval && timer2 !== -1) {
+ timer2 = setTimeout(execute, interval);
+ }
+ }
+ function execute() {
+ if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
+ revalidate(WITH_DEDUPE).then(next);
+ } else {
+ next();
+ }
+ }
+ next();
+ return () => {
+ if (timer2) {
+ clearTimeout(timer2);
+ timer2 = -1;
+ }
+ };
+ }, [
+ refreshInterval,
+ refreshWhenHidden,
+ refreshWhenOffline,
+ key
+ ]);
+ x3(returnedData);
+ if (suspense && isUndefined(data) && key) {
+ if (!IS_REACT_LEGACY && IS_SERVER) {
+ throw new Error("Fallback data is required when using suspense in SSR.");
+ }
+ fetcherRef.current = fetcher;
+ configRef.current = config;
+ unmountedRef.current = false;
+ const req = PRELOAD[key];
+ if (!isUndefined(req)) {
+ const promise = boundMutate(req);
+ use2(promise);
+ }
+ if (isUndefined(error2)) {
+ const promise = revalidate(WITH_DEDUPE);
+ if (!isUndefined(returnedData)) {
+ promise.status = "fulfilled";
+ promise.value = true;
+ }
+ use2(promise);
+ } else {
+ throw error2;
+ }
+ }
+ return {
+ mutate: boundMutate,
+ get data() {
+ stateDependencies.data = true;
+ return returnedData;
+ },
+ get error() {
+ stateDependencies.error = true;
+ return error2;
+ },
+ get isValidating() {
+ stateDependencies.isValidating = true;
+ return isValidating;
+ },
+ get isLoading() {
+ stateDependencies.isLoading = true;
+ return isLoading;
+ }
+ };
+};
+var SWRConfig2 = OBJECT.defineProperty(SWRConfig, "defaultValue", {
+ value: defaultConfig
+});
+var useSWR = withArgs(useSWRHandler);
+
// ../../node_modules/.pnpm/@babel+runtime@7.19.4/node_modules/@babel/runtime/helpers/esm/extends.js
function _extends() {
_extends = Object.assign ? Object.assign.bind() : function(target) {
@@ -23638,9 +27778,9 @@ function createHashHistory(props) {
}
var transitionManager = createTransitionManager();
function setState(nextState) {
- _extends(history2, nextState);
- history2.length = globalHistory.length;
- transitionManager.notifyListeners(history2.location, history2.action);
+ _extends(history3, nextState);
+ history3.length = globalHistory.length;
+ transitionManager.notifyListeners(history3.location, history3.action);
}
var forceNextPop = false;
var ignorePath = null;
@@ -23654,7 +27794,7 @@ function createHashHistory(props) {
replaceHashPath(encodedPath2);
} else {
var location2 = getDOMLocation();
- var prevLocation = history2.location;
+ var prevLocation = history3.location;
if (!forceNextPop && locationsAreEqual$$1(prevLocation, location2))
return;
if (ignorePath === createPath(location2))
@@ -23682,7 +27822,7 @@ function createHashHistory(props) {
}
}
function revertPop(fromLocation) {
- var toLocation = history2.location;
+ var toLocation = history3.location;
var toIndex = allPaths.lastIndexOf(createPath(toLocation));
if (toIndex === -1)
toIndex = 0;
@@ -23712,7 +27852,7 @@ function createHashHistory(props) {
function push(path2, state) {
false ? tiny_warning_esm_default(state === void 0, "Hash history cannot push state; it is ignored") : void 0;
var action = "PUSH";
- var location2 = createLocation(path2, void 0, void 0, history2.location);
+ var location2 = createLocation(path2, void 0, void 0, history3.location);
transitionManager.confirmTransitionTo(location2, action, getUserConfirmation, function(ok) {
if (!ok)
return;
@@ -23722,7 +27862,7 @@ function createHashHistory(props) {
if (hashChanged) {
ignorePath = path3;
pushHashPath(encodedPath2);
- var prevIndex = allPaths.lastIndexOf(createPath(history2.location));
+ var prevIndex = allPaths.lastIndexOf(createPath(history3.location));
var nextPaths = allPaths.slice(0, prevIndex + 1);
nextPaths.push(path3);
allPaths = nextPaths;
@@ -23739,7 +27879,7 @@ function createHashHistory(props) {
function replace(path2, state) {
false ? tiny_warning_esm_default(state === void 0, "Hash history cannot replace state; it is ignored") : void 0;
var action = "REPLACE";
- var location2 = createLocation(path2, void 0, void 0, history2.location);
+ var location2 = createLocation(path2, void 0, void 0, history3.location);
transitionManager.confirmTransitionTo(location2, action, getUserConfirmation, function(ok) {
if (!ok)
return;
@@ -23750,7 +27890,7 @@ function createHashHistory(props) {
ignorePath = path3;
replaceHashPath(encodedPath2);
}
- var prevIndex = allPaths.indexOf(createPath(history2.location));
+ var prevIndex = allPaths.indexOf(createPath(history3.location));
if (prevIndex !== -1)
allPaths[prevIndex] = path3;
setState({
@@ -23804,7 +27944,7 @@ function createHashHistory(props) {
unlisten();
};
}
- var history2 = {
+ var history3 = {
length: globalHistory.length,
action: "POP",
location: initialLocation,
@@ -23817,10 +27957,10 @@ function createHashHistory(props) {
block,
listen
};
- return history2;
+ return history3;
}
-// src/ApplicationReadyRoutes.tsx
+// src/Routing.tsx
init_preact_module();
// ../../node_modules/.pnpm/preact-router@3.2.1_preact@10.11.3/node_modules/preact-router/dist/preact-router.es.js
@@ -24112,9 +28252,667 @@ Router.Route = Route;
Router.Link = Link;
Router.exec = exec;
-// src/ApplicationReadyRoutes.tsx
+// src/Routing.tsx
+init_hooks_module();
+
+// src/components/exception/loading.tsx
+init_preact_module();
+function Loading() {
+ return /* @__PURE__ */ h(
+ "div",
+ {
+ class: "columns is-centered is-vcentered",
+ style: {
+ height: "calc(100% - 3rem)",
+ position: "absolute",
+ width: "100%"
+ }
+ },
+ /* @__PURE__ */ h(Spinner, null)
+ );
+}
+function Spinner() {
+ return /* @__PURE__ */ h("div", { class: "lds-ring" }, /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null));
+}
+
+// src/components/menu/index.tsx
+init_preact_module();
init_hooks_module();
+// src/AdminRoutes.tsx
+init_preact_module();
+
+// src/paths/admin/create/index.tsx
+init_preact_module();
+init_hooks_module();
+
+// src/context/session.ts
+var codecForSessionStateLoggedIn = () => buildCodecForObject().property("status", codecForConstString("loggedIn")).property("instance", codecForString()).property("impersonate", codecOptional(codecForImpresonate())).property("token", codecOptional(codecForString())).property("isAdmin", codecForBoolean()).build("SessionState.LoggedIn");
+var codecForSessionStateExpired = () => buildCodecForObject().property("status", codecForConstString("expired")).property("instance", codecForString()).property("impersonate", codecOptional(codecForImpresonate())).property("isAdmin", codecForBoolean()).build("SessionState.Expired");
+var codecForSessionStateLoggedOut = () => buildCodecForObject().property("status", codecForConstString("loggedOut")).property("instance", codecForString()).property("isAdmin", codecForBoolean()).build("SessionState.LoggedOut");
+var codecForImpresonate = () => buildCodecForObject().property("originalInstance", codecForString()).property(
+ "originalToken",
+ codecOptional(codecForString())
+).property("originalBackendUrl", codecForString()).build("SessionState.Impersonate");
+var codecForSessionState = () => buildCodecForUnion().discriminateOn("status").alternative("loggedIn", codecForSessionStateLoggedIn()).alternative("loggedOut", codecForSessionStateLoggedOut()).alternative("expired", codecForSessionStateExpired()).build("SessionState");
+function inferInstanceName(url) {
+ const match6 = INSTANCE_ID_LOOKUP.exec(url.href);
+ return !match6 || !match6[1] ? DEFAULT_ADMIN_USERNAME : match6[1];
+}
+var defaultState = (url) => {
+ const instance = inferInstanceName(url);
+ return {
+ status: "loggedIn",
+ instance,
+ isAdmin: instance === DEFAULT_ADMIN_USERNAME,
+ token: void 0,
+ impersonate: void 0
+ };
+};
+var SESSION_STATE_KEY = buildStorageKey(
+ "merchant-session",
+ codecForSessionState()
+);
+var DEFAULT_ADMIN_USERNAME = "default";
+var INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/;
+function useSessionContext() {
+ const { url: merchantUrl, changeBackend } = useMerchantApiContext();
+ const { value: state, update } = useLocalStorage(
+ SESSION_STATE_KEY,
+ defaultState(merchantUrl)
+ );
+ return {
+ state,
+ logOut() {
+ const instance = inferInstanceName(merchantUrl);
+ const nextState = {
+ status: "loggedOut",
+ instance,
+ isAdmin: instance === DEFAULT_ADMIN_USERNAME
+ };
+ update(nextState);
+ },
+ deImpersonate() {
+ if (state.status === "loggedOut" || state.status === "expired") {
+ return;
+ }
+ if (state.impersonate === void 0) {
+ return;
+ }
+ const newURL = new URL(`./`, state.impersonate.originalBackendUrl);
+ changeBackend(newURL);
+ const nextState = {
+ status: "loggedIn",
+ isAdmin: state.impersonate.originalInstance === DEFAULT_ADMIN_USERNAME,
+ instance: state.impersonate.originalInstance,
+ token: state.impersonate.originalToken,
+ impersonate: void 0
+ };
+ update(nextState);
+ },
+ impersonate(info) {
+ if (state.status === "loggedOut" || state.status === "expired") {
+ return;
+ }
+ changeBackend(info.baseUrl);
+ const nextState = {
+ status: "loggedIn",
+ isAdmin: info.instance === DEFAULT_ADMIN_USERNAME,
+ instance: info.instance,
+ // FIXME: bank and merchant should have consistent behavior
+ token: info.token?.substring("secret-token:".length),
+ impersonate: {
+ originalBackendUrl: merchantUrl.href,
+ originalToken: state.token,
+ originalInstance: state.instance
+ }
+ };
+ update(nextState);
+ },
+ expired() {
+ if (state.status === "loggedOut")
+ return;
+ const nextState = {
+ ...state,
+ status: "expired",
+ token: void 0
+ };
+ update(nextState);
+ },
+ logIn(info) {
+ const nextState = {
+ impersonate: void 0,
+ ...state,
+ status: "loggedIn",
+ // FIXME: bank and merchant should have consistent behavior
+ token: info.token?.substring("secret-token:".length)
+ // token: info.token,
+ };
+ update(nextState);
+ cleanAllCache();
+ }
+ };
+}
+function cleanAllCache() {
+ mutate(() => true, void 0, { revalidate: false });
+}
+
+// src/paths/admin/create/CreatePage.tsx
+init_preact_module();
+init_hooks_module();
+
+// src/components/exception/AsyncButton.tsx
+init_preact_module();
+
+// src/components/modal/index.tsx
+init_preact_module();
+init_hooks_module();
+
+// src/utils/constants.ts
+var PAYTO_REGEX = /^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-\.\~\(\)@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-\.\~\(\)@_%:!$'*+,;=]*&?)*$/;
+var CROCKFORD_BASE32_REGEX = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+[*~$=U]*$/;
+var URL_REGEX = /^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/;
+var PAGINATED_LIST_SIZE = 5;
+var PAGINATED_LIST_REQUEST = PAGINATED_LIST_SIZE + 1;
+var DEFAULT_REQUEST_TIMEOUT = 10;
+var MAX_IMAGE_SIZE = 1024 * 1024;
+var INSTANCE_ID_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_.@-]+$/;
+var COUNTRY_TABLE = {
+ AE: "U.A.E.",
+ AF: "Afghanistan",
+ AL: "Albania",
+ AM: "Armenia",
+ AN: "Netherlands Antilles",
+ AR: "Argentina",
+ AT: "Austria",
+ AU: "Australia",
+ AZ: "Azerbaijan",
+ BA: "Bosnia and Herzegovina",
+ BD: "Bangladesh",
+ BE: "Belgium",
+ BG: "Bulgaria",
+ BH: "Bahrain",
+ BN: "Brunei Darussalam",
+ BO: "Bolivia",
+ BR: "Brazil",
+ BT: "Bhutan",
+ BY: "Belarus",
+ BZ: "Belize",
+ CA: "Canada",
+ CG: "Congo",
+ CH: "Switzerland",
+ CI: "Cote d'Ivoire",
+ CL: "Chile",
+ CM: "Cameroon",
+ CN: "People's Republic of China",
+ CO: "Colombia",
+ CR: "Costa Rica",
+ CS: "Serbia and Montenegro",
+ CZ: "Czech Republic",
+ DE: "Germany",
+ DK: "Denmark",
+ DO: "Dominican Republic",
+ DZ: "Algeria",
+ EC: "Ecuador",
+ EE: "Estonia",
+ EG: "Egypt",
+ ER: "Eritrea",
+ ES: "Spain",
+ ET: "Ethiopia",
+ FI: "Finland",
+ FO: "Faroe Islands",
+ FR: "France",
+ GB: "United Kingdom",
+ GD: "Caribbean",
+ GE: "Georgia",
+ GL: "Greenland",
+ GR: "Greece",
+ GT: "Guatemala",
+ HK: "Hong Kong",
+ // HK: "Hong Kong S.A.R.",
+ HN: "Honduras",
+ HR: "Croatia",
+ HT: "Haiti",
+ HU: "Hungary",
+ ID: "Indonesia",
+ IE: "Ireland",
+ IL: "Israel",
+ IN: "India",
+ IQ: "Iraq",
+ IR: "Iran",
+ IS: "Iceland",
+ IT: "Italy",
+ JM: "Jamaica",
+ JO: "Jordan",
+ JP: "Japan",
+ KE: "Kenya",
+ KG: "Kyrgyzstan",
+ KH: "Cambodia",
+ KR: "South Korea",
+ KW: "Kuwait",
+ KZ: "Kazakhstan",
+ LA: "Laos",
+ LB: "Lebanon",
+ LI: "Liechtenstein",
+ LK: "Sri Lanka",
+ LT: "Lithuania",
+ LU: "Luxembourg",
+ LV: "Latvia",
+ LY: "Libya",
+ MA: "Morocco",
+ MC: "Principality of Monaco",
+ MD: "Moldava",
+ // MD: "Moldova",
+ ME: "Montenegro",
+ MK: "Former Yugoslav Republic of Macedonia",
+ ML: "Mali",
+ MM: "Myanmar",
+ MN: "Mongolia",
+ MO: "Macau S.A.R.",
+ MT: "Malta",
+ MV: "Maldives",
+ MX: "Mexico",
+ MY: "Malaysia",
+ NG: "Nigeria",
+ NI: "Nicaragua",
+ NL: "Netherlands",
+ NO: "Norway",
+ NP: "Nepal",
+ NZ: "New Zealand",
+ OM: "Oman",
+ PA: "Panama",
+ PE: "Peru",
+ PH: "Philippines",
+ PK: "Islamic Republic of Pakistan",
+ PL: "Poland",
+ PR: "Puerto Rico",
+ PT: "Portugal",
+ PY: "Paraguay",
+ QA: "Qatar",
+ RE: "Reunion",
+ RO: "Romania",
+ RS: "Serbia",
+ RU: "Russia",
+ RW: "Rwanda",
+ SA: "Saudi Arabia",
+ SE: "Sweden",
+ SG: "Singapore",
+ SI: "Slovenia",
+ SK: "Slovak",
+ SN: "Senegal",
+ SO: "Somalia",
+ SR: "Suriname",
+ SV: "El Salvador",
+ SY: "Syria",
+ TH: "Thailand",
+ TJ: "Tajikistan",
+ TM: "Turkmenistan",
+ TN: "Tunisia",
+ TR: "Turkey",
+ TT: "Trinidad and Tobago",
+ TW: "Taiwan",
+ TZ: "Tanzania",
+ UA: "Ukraine",
+ US: "United States",
+ UY: "Uruguay",
+ VA: "Vatican",
+ VE: "Venezuela",
+ VN: "Viet Nam",
+ YE: "Yemen",
+ ZA: "South Africa",
+ ZW: "Zimbabwe"
+};
+
+// src/components/form/FormProvider.tsx
+init_preact_module();
+init_hooks_module();
+var noUpdater = () => (s5) => s5;
+function FormProvider({
+ object: object2 = {},
+ errors: errors2 = {},
+ name = "",
+ valueHandler,
+ children
+}) {
+ const initialObject = F(() => object2, []);
+ const value = F(
+ () => ({
+ errors: errors2,
+ object: object2,
+ initialObject,
+ valueHandler: valueHandler ? valueHandler : noUpdater,
+ name,
+ toStr: {},
+ fromStr: {}
+ }),
+ [errors2, object2, valueHandler]
+ );
+ return /* @__PURE__ */ h(FormContext2.Provider, { value }, /* @__PURE__ */ h(
+ "form",
+ {
+ class: "field",
+ onSubmit: (e4) => {
+ e4.preventDefault();
+ }
+ },
+ children
+ ));
+}
+var FormContext2 = B(null);
+function useFormContext() {
+ return q2(FormContext2);
+}
+
+// src/components/form/Input.tsx
+init_preact_module();
+
+// src/components/form/useField.tsx
+init_hooks_module();
+function useField(name) {
+ const { errors: errors2, object: object2, initialObject, toStr, fromStr, valueHandler } = useFormContext();
+ const [isDirty, setDirty] = p3(false);
+ const updateField = (field) => (value2) => {
+ setDirty(true);
+ return valueHandler((prev) => {
+ return setValueDeeper(prev, String(field).split("."), value2);
+ });
+ };
+ const defaultToString4 = (f3) => String(!f3 ? "" : f3);
+ const defaultFromString4 = (v3) => v3;
+ const value = readField(object2, String(name));
+ const initial3 = readField(initialObject, String(name));
+ const hasError = readField(errors2, String(name));
+ return {
+ error: isDirty ? hasError : void 0,
+ required: !isDirty && hasError,
+ value,
+ initial: initial3,
+ onChange: updateField(name),
+ toStr: toStr[name] ? toStr[name] : defaultToString4,
+ fromStr: fromStr[name] ? fromStr[name] : defaultFromString4
+ };
+}
+var readField = (object2, name) => {
+ return name.split(".").reduce((prev, current) => prev && prev[current], object2);
+};
+var setValueDeeper = (object2, names2, value) => {
+ if (names2.length === 0)
+ return value;
+ const [head, ...rest] = names2;
+ return { ...object2, [head]: setValueDeeper(object2[head] || {}, rest, value) };
+};
+
+// src/components/form/Input.tsx
+var defaultToString = (f3) => f3 || "";
+var defaultFromString = (v3) => v3;
+var TextInput = ({ inputType, error: error2, ...rest }) => inputType === "multiline" ? /* @__PURE__ */ h(
+ "textarea",
+ {
+ ...rest,
+ class: error2 ? "textarea is-danger" : "textarea",
+ rows: "3"
+ }
+) : /* @__PURE__ */ h(
+ "input",
+ {
+ ...rest,
+ class: error2 ? "input is-danger" : "input",
+ type: inputType
+ }
+);
+function Input({
+ name,
+ readonly,
+ placeholder,
+ tooltip,
+ label,
+ expand,
+ help,
+ children,
+ inputType,
+ inputExtra,
+ side,
+ fromStr = defaultFromString,
+ toStr = defaultToString
+}) {
+ const { error: error2, value, onChange, required } = useField(name);
+ return /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, label, tooltip && /* @__PURE__ */ h("span", { class: "icon has-tooltip-right", "data-tooltip": tooltip }, /* @__PURE__ */ h("i", { class: "mdi mdi-information" })))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h(
+ "p",
+ {
+ class: expand ? "control is-expanded has-icons-right" : "control has-icons-right"
+ },
+ /* @__PURE__ */ h(
+ TextInput,
+ {
+ error: error2,
+ ...inputExtra,
+ inputType,
+ placeholder,
+ readonly,
+ disabled: readonly,
+ name: String(name),
+ value: toStr(value),
+ onChange: (e4) => onChange(fromStr(e4.currentTarget.value))
+ }
+ ),
+ help,
+ children,
+ required && /* @__PURE__ */ h("span", { class: "icon has-text-danger is-right" }, /* @__PURE__ */ h("i", { class: "mdi mdi-alert" }))
+ ), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2)), side));
+}
+
+// src/components/modal/index.tsx
+function ConfirmModal({
+ active,
+ description,
+ onCancel,
+ onConfirm,
+ children,
+ danger,
+ disabled,
+ label = "Confirm"
+}) {
+ const { i18n: i18n2 } = useTranslationContext();
+ return /* @__PURE__ */ h("div", { class: active ? "modal is-active" : "modal" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card", style: { maxWidth: 700 } }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, !description ? null : /* @__PURE__ */ h("p", { class: "modal-card-title" }, /* @__PURE__ */ h("b", null, description)), /* @__PURE__ */ h("button", { class: "delete ", "aria-label": "close", onClick: onCancel })), /* @__PURE__ */ h("section", { class: "modal-card-body" }, children), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, onConfirm ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ "button",
+ {
+ class: danger ? "button is-danger " : "button is-info ",
+ disabled,
+ onClick: onConfirm
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, label)
+ )) : /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Close"))))), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "modal-close is-large ",
+ "aria-label": "close",
+ onClick: onCancel
+ }
+ ));
+}
+function SimpleModal({ onCancel, children }) {
+ return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("section", { class: "modal-card-body is-main-section" }, children)), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "modal-close is-large ",
+ "aria-label": "close",
+ onClick: onCancel
+ }
+ ));
+}
+function DeleteModal({
+ element,
+ onCancel,
+ onConfirm
+}) {
+ return /* @__PURE__ */ h(
+ ConfirmModal,
+ {
+ label: `Delete instance`,
+ description: `Delete the instance "${element.name}"`,
+ danger: true,
+ active: true,
+ onCancel,
+ onConfirm: () => onConfirm(element.id)
+ },
+ /* @__PURE__ */ h("p", null, "If you delete the instance named ", /* @__PURE__ */ h("b", null, '"', element.name, '"'), " (ID:", " ", /* @__PURE__ */ h("b", null, element.id), "), the merchant will no longer be able to process orders or refunds"),
+ /* @__PURE__ */ h("p", null, "This action deletes the instance private key, but preserves all transaction data. You can still access that data after deleting the instance."),
+ /* @__PURE__ */ h("p", { class: "warning" }, "Deleting an instance ", /* @__PURE__ */ h("b", null, "cannot be undone"), ".")
+ );
+}
+function PurgeModal({
+ element,
+ onCancel,
+ onConfirm
+}) {
+ return /* @__PURE__ */ h(
+ ConfirmModal,
+ {
+ label: `Purge the instance`,
+ description: `Purge the instance "${element.name}"`,
+ danger: true,
+ active: true,
+ onCancel,
+ onConfirm: () => onConfirm(element.id)
+ },
+ /* @__PURE__ */ h("p", null, "If you purge the instance named ", /* @__PURE__ */ h("b", null, '"', element.name, '"'), " (ID:", " ", /* @__PURE__ */ h("b", null, element.id), "), you will also delete all it's transaction data."),
+ /* @__PURE__ */ h("p", null, "The instance will disappear from your list, and you will no longer be able to access it's data."),
+ /* @__PURE__ */ h("p", { class: "warning" }, "Purging an instance ", /* @__PURE__ */ h("b", null, "cannot be undone"), ".")
+ );
+}
+function SetTokenNewInstanceModal({
+ onCancel,
+ onClear,
+ onConfirm
+}) {
+ const [form, setValue] = p3({
+ new_token: "",
+ repeat_token: ""
+ });
+ const { i18n: i18n2 } = useTranslationContext();
+ const errors2 = {
+ new_token: !form.new_token ? i18n2.str`cannot be empty` : form.new_token === form.old_token ? i18n2.str`cannot be the same as the old access token` : void 0,
+ repeat_token: form.new_token !== form.repeat_token ? i18n2.str`is not the same` : void 0
+ };
+ const hasErrors = Object.keys(errors2).some(
+ (k5) => errors2[k5] !== void 0
+ );
+ return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`You are setting the access token for the new instance`), /* @__PURE__ */ h("button", { class: "delete ", "aria-label": "close", onClick: onCancel })), /* @__PURE__ */ h("section", { class: "modal-card-body is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
+ FormProvider,
+ {
+ errors: errors2,
+ object: form,
+ valueHandler: setValue
+ },
+ /* @__PURE__ */ h(
+ Input,
+ {
+ name: "new_token",
+ label: i18n2.str`New access token`,
+ tooltip: i18n2.str`next access token to be used`,
+ inputType: "password"
+ }
+ ),
+ /* @__PURE__ */ h(
+ Input,
+ {
+ name: "repeat_token",
+ label: i18n2.str`Repeat access token`,
+ tooltip: i18n2.str`confirm the same access token`,
+ inputType: "password"
+ }
+ )
+ ), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "With external authorization method no check will be done by the merchant backend"))), /* @__PURE__ */ h("div", { class: "column" }))), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, onClear && /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button is-danger",
+ onClick: onClear,
+ disabled: onClear === void 0
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Set external authorization")
+ ), /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button is-info",
+ onClick: () => onConfirm(form.new_token),
+ disabled: hasErrors
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Set access token")
+ )))), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "modal-close is-large ",
+ "aria-label": "close",
+ onClick: onCancel
+ }
+ ));
+}
+function LoadingModal({ onCancel }) {
+ const { i18n: i18n2 } = useTranslationContext();
+ return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, /* @__PURE__ */ h("p", { class: "modal-card-title" }, /* @__PURE__ */ h(i18n2.Translate, null, "Operation in progress..."))), /* @__PURE__ */ h("section", { class: "modal-card-body" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h(Spinner, null), /* @__PURE__ */ h("div", { class: "column" })), /* @__PURE__ */ h("p", null, i18n2.str`The operation will be automatically canceled after ${DEFAULT_REQUEST_TIMEOUT} seconds`)), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel"))))), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "modal-close is-large ",
+ "aria-label": "close",
+ onClick: onCancel
+ }
+ ));
+}
+
+// src/hooks/async.ts
+init_hooks_module();
+function useAsync(fn2, { slowTolerance: tooLong } = { slowTolerance: 1e3 }) {
+ const [data, setData] = p3(void 0);
+ const [isLoading, setLoading] = p3(false);
+ const [error2, setError] = p3(void 0);
+ const [isSlow, setSlow] = p3(false);
+ const request = async (...args) => {
+ if (!fn2)
+ return;
+ setLoading(true);
+ const handler = setTimeout(() => {
+ setSlow(true);
+ }, tooLong);
+ try {
+ const result = await fn2(...args);
+ setData(result);
+ } catch (error3) {
+ setError(error3);
+ }
+ setLoading(false);
+ setSlow(false);
+ clearTimeout(handler);
+ };
+ function cancel() {
+ setLoading(false);
+ setSlow(false);
+ }
+ return {
+ request,
+ cancel,
+ data,
+ isSlow,
+ isLoading,
+ error: error2
+ };
+}
+
+// src/components/exception/AsyncButton.tsx
+function AsyncButton({ onClick, disabled, children, ...rest }) {
+ const { isSlow, isLoading, request, cancel } = useAsync(onClick);
+ const { i18n: i18n2 } = useTranslationContext();
+ if (isSlow) {
+ return /* @__PURE__ */ h(LoadingModal, { onCancel: cancel });
+ }
+ if (isLoading) {
+ return /* @__PURE__ */ h("button", { class: "button" }, /* @__PURE__ */ h(i18n2.Translate, null, "Loading..."));
+ }
+ return /* @__PURE__ */ h("span", { ...rest }, /* @__PURE__ */ h("button", { class: "button is-success", onClick: request, disabled }, children));
+}
+
+// src/components/instance/DefaultInstanceFormFields.tsx
+init_preact_module();
+
// ../../node_modules/.pnpm/date-fns@2.29.3/node_modules/date-fns/esm/_lib/toInteger/index.js
function toInteger2(dirtyNumber) {
if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
@@ -26172,2054 +30970,6 @@ function isFuture(dirtyDate) {
return toDate2(dirtyDate).getTime() > Date.now();
}
-// src/InstanceRoutes.tsx
-init_preact_module();
-init_hooks_module();
-
-// src/components/exception/loading.tsx
-init_preact_module();
-function Loading() {
- return /* @__PURE__ */ h(
- "div",
- {
- class: "columns is-centered is-vcentered",
- style: {
- height: "calc(100% - 3rem)",
- position: "absolute",
- width: "100%"
- }
- },
- /* @__PURE__ */ h(Spinner, null)
- );
-}
-function Spinner() {
- return /* @__PURE__ */ h("div", { class: "lds-ring" }, /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null), /* @__PURE__ */ h("div", null));
-}
-
-// src/components/menu/index.tsx
-init_preact_module();
-init_hooks_module();
-
-// src/AdminRoutes.tsx
-init_preact_module();
-
-// src/paths/admin/create/index.tsx
-init_preact_module();
-init_hooks_module();
-
-// src/context/backend.ts
-init_preact_module();
-init_hooks_module();
-
-// src/hooks/index.ts
-init_hooks_module();
-var calculateRootPath = () => {
- const rootPath = typeof window !== void 0 ? window.location.origin + window.location.pathname : "/";
- return rootPath.replace("/webui/", "");
-};
-var loginTokenCodec = buildCodecForObject().property("token", codecForString()).property("expiration", codecForTimestamp).build("loginToken");
-var TOKENS_KEY = buildStorageKey("merchant-token", codecForMap(loginTokenCodec));
-function useBackendURL(url) {
- const [value, setter] = useSimpleLocalStorage(
- "merchant-base-url",
- url || calculateRootPath()
- );
- const checkedSetter = (v3) => {
- return setter((p4) => (v3 instanceof Function ? v3(p4 ?? "") : v3).replace(/\/$/, ""));
- };
- return [value, checkedSetter];
-}
-function useBackendDefaultToken() {
- const { update: setToken, value: tokenMap, reset } = useLocalStorage(TOKENS_KEY, {});
- function updateToken(value) {
- if (value === void 0) {
- reset();
- } else {
- const res = { ...tokenMap, "default": value };
- setToken(res);
- }
- }
- return [tokenMap["default"], updateToken];
-}
-function useBackendInstanceToken(id) {
- const { update: setToken, value: tokenMap, reset } = useLocalStorage(TOKENS_KEY, {});
- const [defaultToken, defaultSetToken] = useBackendDefaultToken();
- if (id === "default") {
- return [defaultToken, defaultSetToken];
- }
- function updateToken(value) {
- if (value === void 0) {
- reset();
- } else {
- const res = { ...tokenMap, [id]: value };
- setToken(res);
- }
- }
- return [tokenMap[id], updateToken];
-}
-function useSimpleLocalStorage(key, initialValue) {
- const [storedValue, setStoredValue] = p3(
- () => {
- return typeof window !== "undefined" ? window.localStorage.getItem(key) || initialValue : initialValue;
- }
- );
- const setValue = (value) => {
- setStoredValue((p4) => {
- const toStore = value instanceof Function ? value(p4) : value;
- if (typeof window !== "undefined") {
- if (!toStore) {
- window.localStorage.removeItem(key);
- } else {
- window.localStorage.setItem(key, toStore);
- }
- }
- return toStore;
- });
- };
- return [storedValue, setValue];
-}
-
-// src/context/backend.ts
-var BackendContext = B({
- url: "",
- alreadyTriedLogin: false,
- token: void 0,
- updateToken: () => null
-});
-function useBackendContextState(defaultUrl) {
- const [url] = useBackendURL(defaultUrl);
- const [token, updateToken] = useBackendDefaultToken();
- return {
- url,
- token,
- alreadyTriedLogin: token !== void 0,
- updateToken
- };
-}
-var BackendContextProvider = ({
- children,
- defaultUrl
-}) => {
- const value = useBackendContextState(defaultUrl);
- return h(BackendContext.Provider, { value, children });
-};
-var useBackendContext = () => q2(BackendContext);
-
-// src/hooks/backend.ts
-init_hooks_module();
-
-// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/core/dist/index.mjs
-init_compat_module();
-var import_shim = __toESM(require_shim(), 1);
-
-// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/_internal/dist/index.mjs
-init_compat_module();
-var noop = () => {
-};
-var UNDEFINED = (
- /*#__NOINLINE__*/
- noop()
-);
-var OBJECT = Object;
-var isUndefined = (v3) => v3 === UNDEFINED;
-var isFunction = (v3) => typeof v3 == "function";
-var mergeObjects = (a5, b4) => ({
- ...a5,
- ...b4
-});
-var isPromiseLike = (x6) => isFunction(x6.then);
-var table = /* @__PURE__ */ new WeakMap();
-var counter = 0;
-var stableHash = (arg) => {
- const type = typeof arg;
- const constructor = arg && arg.constructor;
- const isDate3 = constructor == Date;
- let result;
- let index;
- if (OBJECT(arg) === arg && !isDate3 && constructor != RegExp) {
- result = table.get(arg);
- if (result)
- return result;
- result = ++counter + "~";
- table.set(arg, result);
- if (constructor == Array) {
- result = "@";
- for (index = 0; index < arg.length; index++) {
- result += stableHash(arg[index]) + ",";
- }
- table.set(arg, result);
- }
- if (constructor == OBJECT) {
- result = "#";
- const keys = OBJECT.keys(arg).sort();
- while (!isUndefined(index = keys.pop())) {
- if (!isUndefined(arg[index])) {
- result += index + ":" + stableHash(arg[index]) + ",";
- }
- }
- table.set(arg, result);
- }
- } else {
- result = isDate3 ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
- }
- return result;
-};
-var SWRGlobalState = /* @__PURE__ */ new WeakMap();
-var EMPTY_CACHE = {};
-var INITIAL_CACHE = {};
-var STR_UNDEFINED = "undefined";
-var isWindowDefined = typeof window != STR_UNDEFINED;
-var isDocumentDefined = typeof document != STR_UNDEFINED;
-var hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED;
-var createCacheHelper = (cache2, key) => {
- const state = SWRGlobalState.get(cache2);
- return [
- // Getter
- () => !isUndefined(key) && cache2.get(key) || EMPTY_CACHE,
- // Setter
- (info) => {
- if (!isUndefined(key)) {
- const prev = cache2.get(key);
- if (!(key in INITIAL_CACHE)) {
- INITIAL_CACHE[key] = prev;
- }
- state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);
- }
- },
- // Subscriber
- state[6],
- // Get server cache snapshot
- () => {
- if (!isUndefined(key)) {
- if (key in INITIAL_CACHE)
- return INITIAL_CACHE[key];
- }
- return !isUndefined(key) && cache2.get(key) || EMPTY_CACHE;
- }
- ];
-};
-var online = true;
-var isOnline = () => online;
-var [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
- window.addEventListener.bind(window),
- window.removeEventListener.bind(window)
-] : [
- noop,
- noop
-];
-var isVisible = () => {
- const visibilityState = isDocumentDefined && document.visibilityState;
- return isUndefined(visibilityState) || visibilityState !== "hidden";
-};
-var initFocus = (callback) => {
- if (isDocumentDefined) {
- document.addEventListener("visibilitychange", callback);
- }
- onWindowEvent("focus", callback);
- return () => {
- if (isDocumentDefined) {
- document.removeEventListener("visibilitychange", callback);
- }
- offWindowEvent("focus", callback);
- };
-};
-var initReconnect = (callback) => {
- const onOnline = () => {
- online = true;
- callback();
- };
- const onOffline = () => {
- online = false;
- };
- onWindowEvent("online", onOnline);
- onWindowEvent("offline", onOffline);
- return () => {
- offWindowEvent("online", onOnline);
- offWindowEvent("offline", onOffline);
- };
-};
-var preset = {
- isOnline,
- isVisible
-};
-var defaultConfigOptions = {
- initFocus,
- initReconnect
-};
-var IS_REACT_LEGACY = !bn.useId;
-var IS_SERVER = !isWindowDefined || "Deno" in window;
-var rAF = (f3) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f3) : setTimeout(f3, 1);
-var useIsomorphicLayoutEffect = IS_SERVER ? h2 : s2;
-var navigatorConnection = typeof navigator !== "undefined" && navigator.connection;
-var slowConnection = !IS_SERVER && navigatorConnection && ([
- "slow-2g",
- "2g"
-].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
-var serialize = (key) => {
- if (isFunction(key)) {
- try {
- key = key();
- } catch (err) {
- key = "";
- }
- }
- const args = key;
- key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : "";
- return [
- key,
- args
- ];
-};
-var __timestamp = 0;
-var getTimestamp = () => ++__timestamp;
-var FOCUS_EVENT = 0;
-var RECONNECT_EVENT = 1;
-var MUTATE_EVENT = 2;
-var ERROR_REVALIDATE_EVENT = 3;
-var events = {
- __proto__: null,
- ERROR_REVALIDATE_EVENT,
- FOCUS_EVENT,
- MUTATE_EVENT,
- RECONNECT_EVENT
-};
-async function internalMutate(...args) {
- const [cache2, _key, _data, _opts] = args;
- const options = mergeObjects({
- populateCache: true,
- throwOnError: true
- }, typeof _opts === "boolean" ? {
- revalidate: _opts
- } : _opts || {});
- let populateCache = options.populateCache;
- const rollbackOnErrorOption = options.rollbackOnError;
- let optimisticData = options.optimisticData;
- const revalidate = options.revalidate !== false;
- const rollbackOnError = (error2) => {
- return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error2) : rollbackOnErrorOption !== false;
- };
- const throwOnError = options.throwOnError;
- if (isFunction(_key)) {
- const keyFilter = _key;
- const matchedKeys = [];
- const it = cache2.keys();
- for (const key of it) {
- if (
- // Skip the special useSWRInfinite and useSWRSubscription keys.
- !/^\$(inf|sub)\$/.test(key) && keyFilter(cache2.get(key)._k)
- ) {
- matchedKeys.push(key);
- }
- }
- return Promise.all(matchedKeys.map(mutateByKey));
- }
- return mutateByKey(_key);
- async function mutateByKey(_k) {
- const [key] = serialize(_k);
- if (!key)
- return;
- const [get, set2] = createCacheHelper(cache2, key);
- const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
- const startRevalidate = () => {
- const revalidators = EVENT_REVALIDATORS[key];
- if (revalidate) {
- delete FETCH[key];
- delete PRELOAD[key];
- if (revalidators && revalidators[0]) {
- return revalidators[0](MUTATE_EVENT).then(() => get().data);
- }
- }
- return get().data;
- };
- if (args.length < 3) {
- return startRevalidate();
- }
- let data = _data;
- let error2;
- const beforeMutationTs = getTimestamp();
- MUTATION[key] = [
- beforeMutationTs,
- 0
- ];
- const hasOptimisticData = !isUndefined(optimisticData);
- const state = get();
- const displayedData = state.data;
- const currentData = state._c;
- const committedData = isUndefined(currentData) ? displayedData : currentData;
- if (hasOptimisticData) {
- optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
- set2({
- data: optimisticData,
- _c: committedData
- });
- }
- if (isFunction(data)) {
- try {
- data = data(committedData);
- } catch (err) {
- error2 = err;
- }
- }
- if (data && isPromiseLike(data)) {
- data = await data.catch((err) => {
- error2 = err;
- });
- if (beforeMutationTs !== MUTATION[key][0]) {
- if (error2)
- throw error2;
- return data;
- } else if (error2 && hasOptimisticData && rollbackOnError(error2)) {
- populateCache = true;
- set2({
- data: committedData,
- _c: UNDEFINED
- });
- }
- }
- if (populateCache) {
- if (!error2) {
- if (isFunction(populateCache)) {
- const populateCachedData = populateCache(data, committedData);
- set2({
- data: populateCachedData,
- error: UNDEFINED,
- _c: UNDEFINED
- });
- } else {
- set2({
- data,
- error: UNDEFINED,
- _c: UNDEFINED
- });
- }
- }
- }
- MUTATION[key][1] = getTimestamp();
- Promise.resolve(startRevalidate()).then(() => {
- set2({
- _c: UNDEFINED
- });
- });
- if (error2) {
- if (throwOnError)
- throw error2;
- return;
- }
- return data;
- }
-}
-var revalidateAllKeys = (revalidators, type) => {
- for (const key in revalidators) {
- if (revalidators[key][0])
- revalidators[key][0](type);
- }
-};
-var initCache = (provider, options) => {
- if (!SWRGlobalState.has(provider)) {
- const opts = mergeObjects(defaultConfigOptions, options);
- const EVENT_REVALIDATORS = {};
- const mutate2 = internalMutate.bind(UNDEFINED, provider);
- let unmount = noop;
- const subscriptions = {};
- const subscribe = (key, callback) => {
- const subs = subscriptions[key] || [];
- subscriptions[key] = subs;
- subs.push(callback);
- return () => subs.splice(subs.indexOf(callback), 1);
- };
- const setter = (key, value, prev) => {
- provider.set(key, value);
- const subs = subscriptions[key];
- if (subs) {
- for (const fn2 of subs) {
- fn2(value, prev);
- }
- }
- };
- const initProvider = () => {
- if (!SWRGlobalState.has(provider)) {
- SWRGlobalState.set(provider, [
- EVENT_REVALIDATORS,
- {},
- {},
- {},
- mutate2,
- setter,
- subscribe
- ]);
- if (!IS_SERVER) {
- const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, FOCUS_EVENT)));
- const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, RECONNECT_EVENT)));
- unmount = () => {
- releaseFocus && releaseFocus();
- releaseReconnect && releaseReconnect();
- SWRGlobalState.delete(provider);
- };
- }
- }
- };
- initProvider();
- return [
- provider,
- mutate2,
- initProvider,
- unmount
- ];
- }
- return [
- provider,
- SWRGlobalState.get(provider)[4]
- ];
-};
-var onErrorRetry = (_3, __, config, revalidate, opts) => {
- const maxRetryCount = config.errorRetryCount;
- const currentRetryCount = opts.retryCount;
- const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
- if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) {
- return;
- }
- setTimeout(revalidate, timeout, opts);
-};
-var compare = (currentData, newData) => stableHash(currentData) == stableHash(newData);
-var [cache, mutate] = initCache(/* @__PURE__ */ new Map());
-var defaultConfig = mergeObjects(
- {
- // events
- onLoadingSlow: noop,
- onSuccess: noop,
- onError: noop,
- onErrorRetry,
- onDiscarded: noop,
- // switches
- revalidateOnFocus: true,
- revalidateOnReconnect: true,
- revalidateIfStale: true,
- shouldRetryOnError: true,
- // timeouts
- errorRetryInterval: slowConnection ? 1e4 : 5e3,
- focusThrottleInterval: 5 * 1e3,
- dedupingInterval: 2 * 1e3,
- loadingTimeout: slowConnection ? 5e3 : 3e3,
- // providers
- compare,
- isPaused: () => false,
- cache,
- mutate,
- fallback: {}
- },
- // use web preset by default
- preset
-);
-var mergeConfigs = (a5, b4) => {
- const v3 = mergeObjects(a5, b4);
- if (b4) {
- const { use: u1, fallback: f1 } = a5;
- const { use: u22, fallback: f22 } = b4;
- if (u1 && u22) {
- v3.use = u1.concat(u22);
- }
- if (f1 && f22) {
- v3.fallback = mergeObjects(f1, f22);
- }
- }
- return v3;
-};
-var SWRConfigContext = B({});
-var SWRConfig = (props) => {
- const { value } = props;
- const parentConfig = q2(SWRConfigContext);
- const isFunctionalConfig = isFunction(value);
- const config = F(() => isFunctionalConfig ? value(parentConfig) : value, [
- isFunctionalConfig,
- parentConfig,
- value
- ]);
- const extendedConfig = F(() => isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [
- isFunctionalConfig,
- parentConfig,
- config
- ]);
- const provider = config && config.provider;
- const cacheContextRef = _2(UNDEFINED);
- if (provider && !cacheContextRef.current) {
- cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config);
- }
- const cacheContext = cacheContextRef.current;
- if (cacheContext) {
- extendedConfig.cache = cacheContext[0];
- extendedConfig.mutate = cacheContext[1];
- }
- useIsomorphicLayoutEffect(() => {
- if (cacheContext) {
- cacheContext[2] && cacheContext[2]();
- return cacheContext[3];
- }
- }, []);
- return h(SWRConfigContext.Provider, mergeObjects(props, {
- value: extendedConfig
- }));
-};
-var INFINITE_PREFIX = "$inf$";
-var enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
-var use = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
-var setupDevTools = () => {
- if (enableDevtools) {
- window.__SWR_DEVTOOLS_REACT__ = bn;
- }
-};
-var normalize = (args) => {
- return isFunction(args[1]) ? [
- args[0],
- args[1],
- args[2] || {}
- ] : [
- args[0],
- null,
- (args[1] === null ? args[2] : args[1]) || {}
- ];
-};
-var useSWRConfig = () => {
- return mergeObjects(defaultConfig, q2(SWRConfigContext));
-};
-var middleware = (useSWRNext) => (key_, fetcher_, config) => {
- const fetcher = fetcher_ && ((...args) => {
- const [key] = serialize(key_);
- const [, , , PRELOAD] = SWRGlobalState.get(cache);
- if (key.startsWith(INFINITE_PREFIX)) {
- return fetcher_(...args);
- }
- const req = PRELOAD[key];
- if (isUndefined(req))
- return fetcher_(...args);
- delete PRELOAD[key];
- return req;
- });
- return useSWRNext(key_, fetcher, config);
-};
-var BUILT_IN_MIDDLEWARE = use.concat(middleware);
-var withArgs = (hook) => {
- return function useSWRArgs(...args) {
- const fallbackConfig = useSWRConfig();
- const [key, fn2, _config] = normalize(args);
- const config = mergeConfigs(fallbackConfig, _config);
- let next = hook;
- const { use: use3 } = config;
- const middleware2 = (use3 || []).concat(BUILT_IN_MIDDLEWARE);
- for (let i4 = middleware2.length; i4--; ) {
- next = middleware2[i4](next);
- }
- return next(key, fn2 || config.fetcher || null, config);
- };
-};
-var subscribeCallback = (key, callbacks, callback) => {
- const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
- keyedRevalidators.push(callback);
- return () => {
- const index = keyedRevalidators.indexOf(callback);
- if (index >= 0) {
- keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
- keyedRevalidators.pop();
- }
- };
-};
-setupDevTools();
-
-// ../../node_modules/.pnpm/swr@2.2.2_react@18.2.0/node_modules/swr/core/dist/index.mjs
-var use2 = bn.use || ((promise) => {
- if (promise.status === "pending") {
- throw promise;
- } else if (promise.status === "fulfilled") {
- return promise.value;
- } else if (promise.status === "rejected") {
- throw promise.reason;
- } else {
- promise.status = "pending";
- promise.then((v3) => {
- promise.status = "fulfilled";
- promise.value = v3;
- }, (e4) => {
- promise.status = "rejected";
- promise.reason = e4;
- });
- throw promise;
- }
-});
-var WITH_DEDUPE = {
- dedupe: true
-};
-var useSWRHandler = (_key, fetcher, config) => {
- const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config;
- const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
- const [key, fnArg] = serialize(_key);
- const initialMountedRef = _2(false);
- const unmountedRef = _2(false);
- const keyRef = _2(key);
- const fetcherRef = _2(fetcher);
- const configRef = _2(config);
- const getConfig = () => configRef.current;
- const isActive = () => getConfig().isVisible() && getConfig().isOnline();
- const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key);
- const stateDependencies = _2({}).current;
- const fallback = isUndefined(fallbackData) ? config.fallback[key] : fallbackData;
- const isEqual = (prev, current) => {
- for (const _3 in stateDependencies) {
- const t4 = _3;
- if (t4 === "data") {
- if (!compare2(prev[t4], current[t4])) {
- if (!isUndefined(prev[t4])) {
- return false;
- }
- if (!compare2(returnedData, current[t4])) {
- return false;
- }
- }
- } else {
- if (current[t4] !== prev[t4]) {
- return false;
- }
- }
- }
- return true;
- };
- const getSnapshot = F(() => {
- const shouldStartRequest = (() => {
- if (!key)
- return false;
- if (!fetcher)
- return false;
- if (!isUndefined(revalidateOnMount))
- return revalidateOnMount;
- if (getConfig().isPaused())
- return false;
- if (suspense)
- return false;
- if (!isUndefined(revalidateIfStale))
- return revalidateIfStale;
- return true;
- })();
- const getSelectedCache = (state) => {
- const snapshot = mergeObjects(state);
- delete snapshot._k;
- if (!shouldStartRequest) {
- return snapshot;
- }
- return {
- isValidating: true,
- isLoading: true,
- ...snapshot
- };
- };
- const cachedData2 = getCache();
- const initialData = getInitialCache();
- const clientSnapshot = getSelectedCache(cachedData2);
- const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData);
- let memorizedSnapshot = clientSnapshot;
- return [
- () => {
- const newSnapshot = getSelectedCache(getCache());
- const compareResult = isEqual(newSnapshot, memorizedSnapshot);
- if (compareResult) {
- memorizedSnapshot.data = newSnapshot.data;
- memorizedSnapshot.isLoading = newSnapshot.isLoading;
- memorizedSnapshot.isValidating = newSnapshot.isValidating;
- memorizedSnapshot.error = newSnapshot.error;
- return memorizedSnapshot;
- } else {
- memorizedSnapshot = newSnapshot;
- return newSnapshot;
- }
- },
- () => serverSnapshot
- ];
- }, [
- cache2,
- key
- ]);
- const cached = (0, import_shim.useSyncExternalStore)(T2(
- (callback) => subscribeCache(key, (current, prev) => {
- if (!isEqual(prev, current))
- callback();
- }),
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [
- cache2,
- key
- ]
- ), getSnapshot[0], getSnapshot[1]);
- const isInitialMount = !initialMountedRef.current;
- const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
- const cachedData = cached.data;
- const data = isUndefined(cachedData) ? fallback : cachedData;
- const error2 = cached.error;
- const laggyDataRef = _2(data);
- const returnedData = keepPreviousData ? isUndefined(cachedData) ? laggyDataRef.current : cachedData : data;
- const shouldDoInitialRevalidation = (() => {
- if (hasRevalidator && !isUndefined(error2))
- return false;
- if (isInitialMount && !isUndefined(revalidateOnMount))
- return revalidateOnMount;
- if (getConfig().isPaused())
- return false;
- if (suspense)
- return isUndefined(data) ? false : revalidateIfStale;
- return isUndefined(data) || revalidateIfStale;
- })();
- const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation);
- const isValidating = isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating;
- const isLoading = isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading;
- const revalidate = T2(
- async (revalidateOpts) => {
- const currentFetcher = fetcherRef.current;
- if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
- return false;
- }
- let newData;
- let startAt;
- let loading = true;
- const opts = revalidateOpts || {};
- const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
- const callbackSafeguard = () => {
- if (IS_REACT_LEGACY) {
- return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
- }
- return key === keyRef.current;
- };
- const finalState = {
- isValidating: false,
- isLoading: false
- };
- const finishRequestAndUpdateState = () => {
- setCache(finalState);
- };
- const cleanupState = () => {
- const requestInfo = FETCH[key];
- if (requestInfo && requestInfo[1] === startAt) {
- delete FETCH[key];
- }
- };
- const initialState = {
- isValidating: true
- };
- if (isUndefined(getCache().data)) {
- initialState.isLoading = true;
- }
- try {
- if (shouldStartNewRequest) {
- setCache(initialState);
- if (config.loadingTimeout && isUndefined(getCache().data)) {
- setTimeout(() => {
- if (loading && callbackSafeguard()) {
- getConfig().onLoadingSlow(key, config);
- }
- }, config.loadingTimeout);
- }
- FETCH[key] = [
- currentFetcher(fnArg),
- getTimestamp()
- ];
- }
- [newData, startAt] = FETCH[key];
- newData = await newData;
- if (shouldStartNewRequest) {
- setTimeout(cleanupState, config.dedupingInterval);
- }
- if (!FETCH[key] || FETCH[key][1] !== startAt) {
- if (shouldStartNewRequest) {
- if (callbackSafeguard()) {
- getConfig().onDiscarded(key);
- }
- }
- return false;
- }
- finalState.error = UNDEFINED;
- const mutationInfo = MUTATION[key];
- if (!isUndefined(mutationInfo) && // case 1
- (startAt <= mutationInfo[0] || // case 2
- startAt <= mutationInfo[1] || // case 3
- mutationInfo[1] === 0)) {
- finishRequestAndUpdateState();
- if (shouldStartNewRequest) {
- if (callbackSafeguard()) {
- getConfig().onDiscarded(key);
- }
- }
- return false;
- }
- const cacheData = getCache().data;
- finalState.data = compare2(cacheData, newData) ? cacheData : newData;
- if (shouldStartNewRequest) {
- if (callbackSafeguard()) {
- getConfig().onSuccess(newData, key, config);
- }
- }
- } catch (err) {
- cleanupState();
- const currentConfig = getConfig();
- const { shouldRetryOnError } = currentConfig;
- if (!currentConfig.isPaused()) {
- finalState.error = err;
- if (shouldStartNewRequest && callbackSafeguard()) {
- currentConfig.onError(err, key, currentConfig);
- if (shouldRetryOnError === true || isFunction(shouldRetryOnError) && shouldRetryOnError(err)) {
- if (isActive()) {
- currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => {
- const revalidators = EVENT_REVALIDATORS[key];
- if (revalidators && revalidators[0]) {
- revalidators[0](events.ERROR_REVALIDATE_EVENT, _opts);
- }
- }, {
- retryCount: (opts.retryCount || 0) + 1,
- dedupe: true
- });
- }
- }
- }
- }
- }
- loading = false;
- finishRequestAndUpdateState();
- return true;
- },
- // `setState` is immutable, and `eventsCallback`, `fnArg`, and
- // `keyValidating` are depending on `key`, so we can exclude them from
- // the deps array.
- //
- // FIXME:
- // `fn` and `config` might be changed during the lifecycle,
- // but they might be changed every render like this.
- // `useSWR('key', () => fetch('/api/'), { suspense: true })`
- // So we omit the values from the deps array
- // even though it might cause unexpected behaviors.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [
- key,
- cache2
- ]
- );
- const boundMutate = T2(
- // Use callback to make sure `keyRef.current` returns latest result every time
- (...args) => {
- return internalMutate(cache2, keyRef.current, ...args);
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- []
- );
- useIsomorphicLayoutEffect(() => {
- fetcherRef.current = fetcher;
- configRef.current = config;
- if (!isUndefined(cachedData)) {
- laggyDataRef.current = cachedData;
- }
- });
- useIsomorphicLayoutEffect(() => {
- if (!key)
- return;
- const softRevalidate = revalidate.bind(UNDEFINED, WITH_DEDUPE);
- let nextFocusRevalidatedAt = 0;
- const onRevalidate = (type, opts = {}) => {
- if (type == events.FOCUS_EVENT) {
- const now2 = Date.now();
- if (getConfig().revalidateOnFocus && now2 > nextFocusRevalidatedAt && isActive()) {
- nextFocusRevalidatedAt = now2 + getConfig().focusThrottleInterval;
- softRevalidate();
- }
- } else if (type == events.RECONNECT_EVENT) {
- if (getConfig().revalidateOnReconnect && isActive()) {
- softRevalidate();
- }
- } else if (type == events.MUTATE_EVENT) {
- return revalidate();
- } else if (type == events.ERROR_REVALIDATE_EVENT) {
- return revalidate(opts);
- }
- return;
- };
- const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
- unmountedRef.current = false;
- keyRef.current = key;
- initialMountedRef.current = true;
- setCache({
- _k: fnArg
- });
- if (shouldDoInitialRevalidation) {
- if (isUndefined(data) || IS_SERVER) {
- softRevalidate();
- } else {
- rAF(softRevalidate);
- }
- }
- return () => {
- unmountedRef.current = true;
- unsubEvents();
- };
- }, [
- key
- ]);
- useIsomorphicLayoutEffect(() => {
- let timer2;
- function next() {
- const interval = isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
- if (interval && timer2 !== -1) {
- timer2 = setTimeout(execute, interval);
- }
- }
- function execute() {
- if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
- revalidate(WITH_DEDUPE).then(next);
- } else {
- next();
- }
- }
- next();
- return () => {
- if (timer2) {
- clearTimeout(timer2);
- timer2 = -1;
- }
- };
- }, [
- refreshInterval,
- refreshWhenHidden,
- refreshWhenOffline,
- key
- ]);
- x3(returnedData);
- if (suspense && isUndefined(data) && key) {
- if (!IS_REACT_LEGACY && IS_SERVER) {
- throw new Error("Fallback data is required when using suspense in SSR.");
- }
- fetcherRef.current = fetcher;
- configRef.current = config;
- unmountedRef.current = false;
- const req = PRELOAD[key];
- if (!isUndefined(req)) {
- const promise = boundMutate(req);
- use2(promise);
- }
- if (isUndefined(error2)) {
- const promise = revalidate(WITH_DEDUPE);
- if (!isUndefined(returnedData)) {
- promise.status = "fulfilled";
- promise.value = true;
- }
- use2(promise);
- } else {
- throw error2;
- }
- }
- return {
- mutate: boundMutate,
- get data() {
- stateDependencies.data = true;
- return returnedData;
- },
- get error() {
- stateDependencies.error = true;
- return error2;
- },
- get isValidating() {
- stateDependencies.isValidating = true;
- return isValidating;
- },
- get isLoading() {
- stateDependencies.isLoading = true;
- return isLoading;
- }
- };
-};
-var SWRConfig2 = OBJECT.defineProperty(SWRConfig, "defaultValue", {
- value: defaultConfig
-});
-var useSWR = withArgs(useSWRHandler);
-
-// src/context/instance.ts
-init_preact_module();
-init_hooks_module();
-var Context3 = B({});
-var InstanceContextProvider = Context3.Provider;
-var useInstanceContext = () => q2(Context3);
-
-// src/hooks/backend.ts
-function useMatchMutate() {
- const { cache: cache2, mutate: mutate2 } = useSWRConfig();
- if (!(cache2 instanceof Map)) {
- throw new Error(
- "matchMutate requires the cache provider to be a Map instance"
- );
- }
- return function matchRegexMutate(re) {
- return mutate2((key) => {
- if (!key || !re)
- return true;
- if (typeof key === "string" && re.test(key))
- return true;
- if (typeof key === "object" && re.test(key[0]))
- return true;
- return false;
- }, void 0, {
- revalidate: true
- });
- };
-}
-function useBackendInstancesTestForAdmin() {
- const { request } = useBackendBaseRequest();
- const [result, setResult] = p3({ loading: true });
- h2(() => {
- request(`/management/instances`).then((data) => setResult(data)).catch(
- (error2) => setResult(error2.cause)
- );
- }, [request]);
- return result;
-}
-var CHECK_CONFIG_INTERVAL_OK = 5 * 60 * 1e3;
-var CHECK_CONFIG_INTERVAL_FAIL = 2 * 1e3;
-function useBackendConfig() {
- const { request } = useBackendBaseRequest();
- const [result, setResult] = p3({ data: { loading: true }, timer: 0 });
- h2(() => {
- if (result.timer) {
- clearTimeout(result.timer);
- }
- function tryConfig() {
- request(`/config`).then((data) => {
- const timer2 = setTimeout(() => {
- tryConfig();
- }, CHECK_CONFIG_INTERVAL_OK);
- setResult({ data, timer: timer2 });
- }).catch((error2) => {
- const timer2 = setTimeout(() => {
- tryConfig();
- }, CHECK_CONFIG_INTERVAL_FAIL);
- const data = error2.cause;
- setResult({ data, timer: timer2 });
- });
- }
- tryConfig();
- }, [request]);
- return result.data;
-}
-function useCredentialsChecker() {
- const { request } = useApiContext();
- async function requestNewLoginToken(baseUrl, token) {
- const data = {
- scope: "write",
- duration: {
- d_us: "forever"
- },
- refreshable: true
- };
- try {
- const response = await request(baseUrl, `/private/token`, {
- method: "POST",
- token,
- data
- });
- return { valid: true, token: response.data.token, expiration: response.data.expiration };
- } catch (error2) {
- if (error2 instanceof RequestError) {
- return { valid: false, cause: error2.cause };
- }
- return {
- valid: false,
- cause: {
- type: ErrorType.UNEXPECTED,
- loading: false,
- info: {
- hasToken: true,
- status: 0,
- options: {},
- url: `/private/token`,
- payload: {}
- },
- exception: error2,
- message: error2 instanceof Error ? error2.message : "unpexepected error"
- }
- };
- }
- }
- ;
- async function refreshLoginToken(baseUrl, token) {
- if (AbsoluteTime.isExpired(AbsoluteTime.fromProtocolTimestamp(token.expiration))) {
- return {
- valid: false,
- cause: {
- type: ErrorType.CLIENT,
- status: HttpStatusCode.Unauthorized,
- message: "login token expired, login again.",
- info: {
- hasToken: true,
- status: 401,
- options: {},
- url: `/private/token`,
- payload: {}
- },
- payload: {}
- }
- };
- }
- return requestNewLoginToken(baseUrl, token.token);
- }
- return { requestNewLoginToken, refreshLoginToken };
-}
-function useBackendBaseRequest() {
- const { url: backend, token: loginToken } = useBackendContext();
- const { request: requestHandler } = useApiContext();
- const token = loginToken?.token;
- const request = T2(
- function requestImpl(endpoint, options = {}) {
- return requestHandler(backend, endpoint, { ...options, token }).then((res) => {
- return res;
- }).catch((err) => {
- throw err;
- });
- },
- [backend, token]
- );
- return { request };
-}
-function useBackendInstanceRequest() {
- const { url: rootBackendUrl, token: rootToken } = useBackendContext();
- const { token: instanceToken, id, admin } = useInstanceContext();
- const { request: requestHandler } = useApiContext();
- const { baseUrl, token: loginToken } = !admin ? { baseUrl: rootBackendUrl, token: rootToken } : { baseUrl: rootBackendUrl, token: instanceToken };
- const token = loginToken?.token;
- const request = T2(
- function requestImpl(endpoint, options = {}) {
- return requestHandler(baseUrl, endpoint, { token, ...options });
- },
- [baseUrl, token]
- );
- const multiFetcher = T2(
- function multiFetcherImpl(args) {
- const [endpoints] = args;
- return Promise.all(
- endpoints.map(
- (endpoint) => requestHandler(baseUrl, endpoint, { token })
- )
- );
- },
- [baseUrl, token]
- );
- const fetcher = T2(
- function fetcherImpl(endpoint) {
- return requestHandler(baseUrl, endpoint, { token });
- },
- [baseUrl, token]
- );
- const orderFetcher = T2(
- function orderFetcherImpl(args) {
- const [endpoint, paid, refunded, wired, searchDate, delta] = args;
- const date_s = delta && delta < 0 && searchDate ? Math.floor(searchDate.getTime() / 1e3) + 1 : searchDate !== void 0 ? Math.floor(searchDate.getTime() / 1e3) : void 0;
- const params = {};
- if (paid !== void 0)
- params.paid = paid;
- if (delta !== void 0)
- params.delta = delta;
- if (refunded !== void 0)
- params.refunded = refunded;
- if (wired !== void 0)
- params.wired = wired;
- if (date_s !== void 0)
- params.date_s = date_s;
- if (delta === 0) {
- return Promise.resolve({
- ok: true,
- data: { orders: [] }
- });
- }
- return requestHandler(baseUrl, endpoint, { params, token });
- },
- [baseUrl, token]
- );
- const transferFetcher = T2(
- function transferFetcherImpl(args) {
- const [endpoint, payto_uri, verified, position, delta] = args;
- const params = {};
- if (payto_uri !== void 0)
- params.payto_uri = payto_uri;
- if (verified !== void 0)
- params.verified = verified;
- if (delta === 0) {
- return Promise.resolve({
- ok: true,
- data: { transfers: [] }
- });
- }
- if (delta !== void 0) {
- params.limit = delta;
- }
- if (position !== void 0)
- params.offset = position;
- return requestHandler(baseUrl, endpoint, { params, token });
- },
- [baseUrl, token]
- );
- const templateFetcher = T2(
- function templateFetcherImpl(args) {
- const [endpoint, position, delta] = args;
- const params = {};
- if (delta === 0) {
- return Promise.resolve({
- ok: true,
- data: { templates: [] }
- });
- }
- if (delta !== void 0) {
- params.limit = delta;
- }
- if (position !== void 0)
- params.offset = position;
- return requestHandler(baseUrl, endpoint, { params, token });
- },
- [baseUrl, token]
- );
- const webhookFetcher = T2(
- function webhookFetcherImpl(args) {
- const [endpoint, position, delta] = args;
- const params = {};
- if (delta === 0) {
- return Promise.resolve({
- ok: true,
- data: { webhooks: [] }
- });
- }
- if (delta !== void 0) {
- params.limit = delta;
- }
- if (position !== void 0)
- params.offset = position;
- return requestHandler(baseUrl, endpoint, { params, token });
- },
- [baseUrl, token]
- );
- return {
- request,
- fetcher,
- multiFetcher,
- orderFetcher,
- transferFetcher,
- templateFetcher,
- webhookFetcher
- };
-}
-
-// src/hooks/instance.ts
-var useSWR2 = useSWR;
-function useAdminAPI() {
- const { request } = useBackendBaseRequest();
- const mutateAll = useMatchMutate();
- const createInstance = async (instance) => {
- await request(`/management/instances`, {
- method: "POST",
- data: instance
- });
- mutateAll(/\/management\/instances/);
- };
- const deleteInstance = async (id) => {
- await request(`/management/instances/${id}`, {
- method: "DELETE"
- });
- mutateAll(/\/management\/instances/);
- };
- const purgeInstance = async (id) => {
- await request(`/management/instances/${id}`, {
- method: "DELETE",
- params: {
- purge: "YES"
- }
- });
- mutateAll(/\/management\/instances/);
- };
- return { createInstance, deleteInstance, purgeInstance };
-}
-function useManagementAPI(instanceId) {
- const mutateAll = useMatchMutate();
- const { url: backendURL } = useBackendContext();
- const { updateToken } = useBackendContext();
- const { request } = useBackendBaseRequest();
- const { requestNewLoginToken } = useCredentialsChecker();
- const updateInstance = async (instance) => {
- await request(`/management/instances/${instanceId}`, {
- method: "PATCH",
- data: instance
- });
- mutateAll(/\/management\/instances/);
- };
- const deleteInstance = async () => {
- await request(`/management/instances/${instanceId}`, {
- method: "DELETE"
- });
- mutateAll(/\/management\/instances/);
- };
- const clearAccessToken = async (currentToken) => {
- await request(`/management/instances/${instanceId}/auth`, {
- method: "POST",
- token: currentToken,
- data: { method: "external" }
- });
- mutateAll(/\/management\/instances/);
- };
- const setNewAccessToken = async (currentToken, newToken) => {
- await request(`/management/instances/${instanceId}/auth`, {
- method: "POST",
- token: currentToken,
- data: { method: "token", token: newToken }
- });
- const resp = await requestNewLoginToken(backendURL, newToken);
- if (resp.valid) {
- const { token, expiration } = resp;
- updateToken({ token, expiration });
- } else {
- updateToken(void 0);
- }
- mutateAll(/\/management\/instances/);
- };
- return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken };
-}
-function useInstanceAPI() {
- const { mutate: mutate2 } = useSWRConfig();
- const { url: backendURL, updateToken } = useBackendContext();
- const {
- token: adminToken
- } = useBackendContext();
- const { request } = useBackendInstanceRequest();
- const { requestNewLoginToken } = useCredentialsChecker();
- const updateInstance = async (instance) => {
- await request(`/private/`, {
- method: "PATCH",
- data: instance
- });
- if (adminToken)
- mutate2(["/private/instances", adminToken, backendURL], null);
- mutate2([`/private/`], null);
- };
- const deleteInstance = async () => {
- await request(`/private/`, {
- method: "DELETE"
- // token: adminToken,
- });
- if (adminToken)
- mutate2(["/private/instances", adminToken, backendURL], null);
- mutate2([`/private/`], null);
- };
- const clearAccessToken = async (currentToken) => {
- await request(`/private/auth`, {
- method: "POST",
- token: currentToken,
- data: { method: "external" }
- });
- mutate2([`/private/`], null);
- };
- const setNewAccessToken = async (currentToken, newToken) => {
- await request(`/private/auth`, {
- method: "POST",
- token: currentToken,
- data: { method: "token", token: newToken }
- });
- const resp = await requestNewLoginToken(backendURL, newToken);
- if (resp.valid) {
- const { token, expiration } = resp;
- updateToken({ token, expiration });
- } else {
- updateToken(void 0);
- }
- mutate2([`/private/`], null);
- };
- return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken };
-}
-function useInstanceDetails() {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR2([`/private/`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false,
- revalidateIfStale: false,
- errorRetryCount: 0,
- errorRetryInterval: 1,
- shouldRetryOnError: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data)
- return data;
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-function useInstanceKYCDetails() {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2 } = useSWR2([`/private/kyc`], fetcher, {
- refreshInterval: 60 * 1e3,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateIfStale: false,
- revalidateOnMount: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false,
- errorRetryCount: 0,
- errorRetryInterval: 1,
- shouldRetryOnError: false
- });
- if (data) {
- if (data.info?.status === 202)
- return { ok: true, data: { type: "redirect", status: data.data } };
- return { ok: true, data: { type: "ok" } };
- }
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-function useManagedInstanceDetails(instanceId) {
- const { request } = useBackendBaseRequest();
- const { data, error: error2, isValidating } = useSWR2([`/management/instances/${instanceId}`], request, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false,
- errorRetryCount: 0,
- errorRetryInterval: 1,
- shouldRetryOnError: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data)
- return data;
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-function useBackendInstances() {
- const { request } = useBackendBaseRequest();
- const { data, error: error2, isValidating } = useSWR2(["/management/instances"], request);
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data)
- return data;
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-
-// src/paths/admin/create/CreatePage.tsx
-init_preact_module();
-init_hooks_module();
-
-// src/components/exception/AsyncButton.tsx
-init_preact_module();
-
-// src/components/modal/index.tsx
-init_preact_module();
-init_hooks_module();
-
-// src/utils/constants.ts
-var PAYTO_REGEX = /^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-\.\~\(\)@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-\.\~\(\)@_%:!$'*+,;=]*&?)*$/;
-var INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/;
-var CROCKFORD_BASE32_REGEX = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+[*~$=U]*$/;
-var URL_REGEX = /^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/;
-var PAGE_SIZE = 20;
-var MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1;
-var DEFAULT_REQUEST_TIMEOUT = 10;
-var MAX_IMAGE_SIZE = 1024 * 1024;
-var INSTANCE_ID_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_.@-]+$/;
-var COUNTRY_TABLE = {
- AE: "U.A.E.",
- AF: "Afghanistan",
- AL: "Albania",
- AM: "Armenia",
- AN: "Netherlands Antilles",
- AR: "Argentina",
- AT: "Austria",
- AU: "Australia",
- AZ: "Azerbaijan",
- BA: "Bosnia and Herzegovina",
- BD: "Bangladesh",
- BE: "Belgium",
- BG: "Bulgaria",
- BH: "Bahrain",
- BN: "Brunei Darussalam",
- BO: "Bolivia",
- BR: "Brazil",
- BT: "Bhutan",
- BY: "Belarus",
- BZ: "Belize",
- CA: "Canada",
- CG: "Congo",
- CH: "Switzerland",
- CI: "Cote d'Ivoire",
- CL: "Chile",
- CM: "Cameroon",
- CN: "People's Republic of China",
- CO: "Colombia",
- CR: "Costa Rica",
- CS: "Serbia and Montenegro",
- CZ: "Czech Republic",
- DE: "Germany",
- DK: "Denmark",
- DO: "Dominican Republic",
- DZ: "Algeria",
- EC: "Ecuador",
- EE: "Estonia",
- EG: "Egypt",
- ER: "Eritrea",
- ES: "Spain",
- ET: "Ethiopia",
- FI: "Finland",
- FO: "Faroe Islands",
- FR: "France",
- GB: "United Kingdom",
- GD: "Caribbean",
- GE: "Georgia",
- GL: "Greenland",
- GR: "Greece",
- GT: "Guatemala",
- HK: "Hong Kong",
- // HK: "Hong Kong S.A.R.",
- HN: "Honduras",
- HR: "Croatia",
- HT: "Haiti",
- HU: "Hungary",
- ID: "Indonesia",
- IE: "Ireland",
- IL: "Israel",
- IN: "India",
- IQ: "Iraq",
- IR: "Iran",
- IS: "Iceland",
- IT: "Italy",
- JM: "Jamaica",
- JO: "Jordan",
- JP: "Japan",
- KE: "Kenya",
- KG: "Kyrgyzstan",
- KH: "Cambodia",
- KR: "South Korea",
- KW: "Kuwait",
- KZ: "Kazakhstan",
- LA: "Laos",
- LB: "Lebanon",
- LI: "Liechtenstein",
- LK: "Sri Lanka",
- LT: "Lithuania",
- LU: "Luxembourg",
- LV: "Latvia",
- LY: "Libya",
- MA: "Morocco",
- MC: "Principality of Monaco",
- MD: "Moldava",
- // MD: "Moldova",
- ME: "Montenegro",
- MK: "Former Yugoslav Republic of Macedonia",
- ML: "Mali",
- MM: "Myanmar",
- MN: "Mongolia",
- MO: "Macau S.A.R.",
- MT: "Malta",
- MV: "Maldives",
- MX: "Mexico",
- MY: "Malaysia",
- NG: "Nigeria",
- NI: "Nicaragua",
- NL: "Netherlands",
- NO: "Norway",
- NP: "Nepal",
- NZ: "New Zealand",
- OM: "Oman",
- PA: "Panama",
- PE: "Peru",
- PH: "Philippines",
- PK: "Islamic Republic of Pakistan",
- PL: "Poland",
- PR: "Puerto Rico",
- PT: "Portugal",
- PY: "Paraguay",
- QA: "Qatar",
- RE: "Reunion",
- RO: "Romania",
- RS: "Serbia",
- RU: "Russia",
- RW: "Rwanda",
- SA: "Saudi Arabia",
- SE: "Sweden",
- SG: "Singapore",
- SI: "Slovenia",
- SK: "Slovak",
- SN: "Senegal",
- SO: "Somalia",
- SR: "Suriname",
- SV: "El Salvador",
- SY: "Syria",
- TH: "Thailand",
- TJ: "Tajikistan",
- TM: "Turkmenistan",
- TN: "Tunisia",
- TR: "Turkey",
- TT: "Trinidad and Tobago",
- TW: "Taiwan",
- TZ: "Tanzania",
- UA: "Ukraine",
- US: "United States",
- UY: "Uruguay",
- VA: "Vatican",
- VE: "Venezuela",
- VN: "Viet Nam",
- YE: "Yemen",
- ZA: "South Africa",
- ZW: "Zimbabwe"
-};
-
-// src/components/form/FormProvider.tsx
-init_preact_module();
-init_hooks_module();
-var noUpdater = () => (s5) => s5;
-function FormProvider({
- object: object2 = {},
- errors: errors2 = {},
- name = "",
- valueHandler,
- children
-}) {
- const initialObject = F(() => object2, []);
- const value = F(
- () => ({
- errors: errors2,
- object: object2,
- initialObject,
- valueHandler: valueHandler ? valueHandler : noUpdater,
- name,
- toStr: {},
- fromStr: {}
- }),
- [errors2, object2, valueHandler]
- );
- return /* @__PURE__ */ h(FormContext2.Provider, { value }, /* @__PURE__ */ h(
- "form",
- {
- class: "field",
- onSubmit: (e4) => {
- e4.preventDefault();
- }
- },
- children
- ));
-}
-var FormContext2 = B(null);
-function useFormContext() {
- return q2(FormContext2);
-}
-
-// src/components/form/Input.tsx
-init_preact_module();
-
-// src/components/form/useField.tsx
-init_hooks_module();
-function useField(name) {
- const { errors: errors2, object: object2, initialObject, toStr, fromStr, valueHandler } = useFormContext();
- const [isDirty, setDirty] = p3(false);
- const updateField = (field) => (value2) => {
- setDirty(true);
- return valueHandler((prev) => {
- return setValueDeeper(prev, String(field).split("."), value2);
- });
- };
- const defaultToString5 = (f3) => String(!f3 ? "" : f3);
- const defaultFromString5 = (v3) => v3;
- const value = readField(object2, String(name));
- const initial2 = readField(initialObject, String(name));
- const hasError = readField(errors2, String(name));
- return {
- error: isDirty ? hasError : void 0,
- required: !isDirty && hasError,
- value,
- initial: initial2,
- onChange: updateField(name),
- toStr: toStr[name] ? toStr[name] : defaultToString5,
- fromStr: fromStr[name] ? fromStr[name] : defaultFromString5
- };
-}
-var readField = (object2, name) => {
- return name.split(".").reduce((prev, current) => prev && prev[current], object2);
-};
-var setValueDeeper = (object2, names2, value) => {
- if (names2.length === 0)
- return value;
- const [head, ...rest] = names2;
- return { ...object2, [head]: setValueDeeper(object2[head] || {}, rest, value) };
-};
-
-// src/components/form/Input.tsx
-var defaultToString = (f3) => f3 || "";
-var defaultFromString = (v3) => v3;
-var TextInput = ({ inputType, error: error2, ...rest }) => inputType === "multiline" ? /* @__PURE__ */ h(
- "textarea",
- {
- ...rest,
- class: error2 ? "textarea is-danger" : "textarea",
- rows: "3"
- }
-) : /* @__PURE__ */ h(
- "input",
- {
- ...rest,
- class: error2 ? "input is-danger" : "input",
- type: inputType
- }
-);
-function Input({
- name,
- readonly,
- placeholder,
- tooltip,
- label,
- expand,
- help,
- children,
- inputType,
- inputExtra,
- side,
- fromStr = defaultFromString,
- toStr = defaultToString
-}) {
- const { error: error2, value, onChange, required } = useField(name);
- return /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, label, tooltip && /* @__PURE__ */ h("span", { class: "icon has-tooltip-right", "data-tooltip": tooltip }, /* @__PURE__ */ h("i", { class: "mdi mdi-information" })))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h(
- "p",
- {
- class: expand ? "control is-expanded has-icons-right" : "control has-icons-right"
- },
- /* @__PURE__ */ h(
- TextInput,
- {
- error: error2,
- ...inputExtra,
- inputType,
- placeholder,
- readonly,
- disabled: readonly,
- name: String(name),
- value: toStr(value),
- onChange: (e4) => onChange(fromStr(e4.currentTarget.value))
- }
- ),
- help,
- children,
- required && /* @__PURE__ */ h("span", { class: "icon has-text-danger is-right" }, /* @__PURE__ */ h("i", { class: "mdi mdi-alert" }))
- ), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2)), side));
-}
-
-// src/components/modal/index.tsx
-function ConfirmModal({
- active,
- description,
- onCancel,
- onConfirm,
- children,
- danger,
- disabled,
- label = "Confirm"
-}) {
- const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: active ? "modal is-active" : "modal" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card", style: { maxWidth: 700 } }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, !description ? null : /* @__PURE__ */ h("p", { class: "modal-card-title" }, /* @__PURE__ */ h("b", null, description)), /* @__PURE__ */ h("button", { class: "delete ", "aria-label": "close", onClick: onCancel })), /* @__PURE__ */ h("section", { class: "modal-card-body" }, children), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, onConfirm ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
- "button",
- {
- class: danger ? "button is-danger " : "button is-info ",
- disabled,
- onClick: onConfirm
- },
- /* @__PURE__ */ h(i18n2.Translate, null, label)
- )) : /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Close"))))), /* @__PURE__ */ h(
- "button",
- {
- class: "modal-close is-large ",
- "aria-label": "close",
- onClick: onCancel
- }
- ));
-}
-function SimpleModal({ onCancel, children }) {
- return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("section", { class: "modal-card-body is-main-section" }, children)), /* @__PURE__ */ h(
- "button",
- {
- class: "modal-close is-large ",
- "aria-label": "close",
- onClick: onCancel
- }
- ));
-}
-function DeleteModal({
- element,
- onCancel,
- onConfirm
-}) {
- return /* @__PURE__ */ h(
- ConfirmModal,
- {
- label: `Delete instance`,
- description: `Delete the instance "${element.name}"`,
- danger: true,
- active: true,
- onCancel,
- onConfirm: () => onConfirm(element.id)
- },
- /* @__PURE__ */ h("p", null, "If you delete the instance named ", /* @__PURE__ */ h("b", null, '"', element.name, '"'), " (ID:", " ", /* @__PURE__ */ h("b", null, element.id), "), the merchant will no longer be able to process orders or refunds"),
- /* @__PURE__ */ h("p", null, "This action deletes the instance private key, but preserves all transaction data. You can still access that data after deleting the instance."),
- /* @__PURE__ */ h("p", { class: "warning" }, "Deleting an instance ", /* @__PURE__ */ h("b", null, "cannot be undone"), ".")
- );
-}
-function PurgeModal({
- element,
- onCancel,
- onConfirm
-}) {
- return /* @__PURE__ */ h(
- ConfirmModal,
- {
- label: `Purge the instance`,
- description: `Purge the instance "${element.name}"`,
- danger: true,
- active: true,
- onCancel,
- onConfirm: () => onConfirm(element.id)
- },
- /* @__PURE__ */ h("p", null, "If you purge the instance named ", /* @__PURE__ */ h("b", null, '"', element.name, '"'), " (ID:", " ", /* @__PURE__ */ h("b", null, element.id), "), you will also delete all it's transaction data."),
- /* @__PURE__ */ h("p", null, "The instance will disappear from your list, and you will no longer be able to access it's data."),
- /* @__PURE__ */ h("p", { class: "warning" }, "Purging an instance ", /* @__PURE__ */ h("b", null, "cannot be undone"), ".")
- );
-}
-function SetTokenNewInstanceModal({
- onCancel,
- onClear,
- onConfirm
-}) {
- const [form, setValue] = p3({
- new_token: "",
- repeat_token: ""
- });
- const { i18n: i18n2 } = useTranslationContext();
- const errors2 = {
- new_token: !form.new_token ? i18n2.str`cannot be empty` : form.new_token === form.old_token ? i18n2.str`cannot be the same as the old access token` : void 0,
- repeat_token: form.new_token !== form.repeat_token ? i18n2.str`is not the same` : void 0
- };
- const hasErrors = Object.keys(errors2).some(
- (k5) => errors2[k5] !== void 0
- );
- return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`You are setting the access token for the new instance`), /* @__PURE__ */ h("button", { class: "delete ", "aria-label": "close", onClick: onCancel })), /* @__PURE__ */ h("section", { class: "modal-card-body is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
- FormProvider,
- {
- errors: errors2,
- object: form,
- valueHandler: setValue
- },
- /* @__PURE__ */ h(
- Input,
- {
- name: "new_token",
- label: i18n2.str`New access token`,
- tooltip: i18n2.str`next access token to be used`,
- inputType: "password"
- }
- ),
- /* @__PURE__ */ h(
- Input,
- {
- name: "repeat_token",
- label: i18n2.str`Repeat access token`,
- tooltip: i18n2.str`confirm the same access token`,
- inputType: "password"
- }
- )
- ), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "With external authorization method no check will be done by the merchant backend"))), /* @__PURE__ */ h("div", { class: "column" }))), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, onClear && /* @__PURE__ */ h(
- "button",
- {
- class: "button is-danger",
- onClick: onClear,
- disabled: onClear === void 0
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Set external authorization")
- ), /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
- "button",
- {
- class: "button is-info",
- onClick: () => onConfirm(form.new_token),
- disabled: hasErrors
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Set access token")
- )))), /* @__PURE__ */ h(
- "button",
- {
- class: "modal-close is-large ",
- "aria-label": "close",
- onClick: onCancel
- }
- ));
-}
-function LoadingModal({ onCancel }) {
- const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "modal is-active" }, /* @__PURE__ */ h("div", { class: "modal-background ", onClick: onCancel }), /* @__PURE__ */ h("div", { class: "modal-card" }, /* @__PURE__ */ h("header", { class: "modal-card-head" }, /* @__PURE__ */ h("p", { class: "modal-card-title" }, /* @__PURE__ */ h(i18n2.Translate, null, "Operation in progress..."))), /* @__PURE__ */ h("section", { class: "modal-card-body" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h(Spinner, null), /* @__PURE__ */ h("div", { class: "column" })), /* @__PURE__ */ h("p", null, i18n2.str`The operation will be automatically canceled after ${DEFAULT_REQUEST_TIMEOUT} seconds`)), /* @__PURE__ */ h("footer", { class: "modal-card-foot" }, /* @__PURE__ */ h("div", { class: "buttons is-right", style: { width: "100%" } }, /* @__PURE__ */ h("button", { class: "button ", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel"))))), /* @__PURE__ */ h(
- "button",
- {
- class: "modal-close is-large ",
- "aria-label": "close",
- onClick: onCancel
- }
- ));
-}
-
-// src/hooks/async.ts
-init_hooks_module();
-function useAsync(fn2, { slowTolerance: tooLong } = { slowTolerance: 1e3 }) {
- const [data, setData] = p3(void 0);
- const [isLoading, setLoading] = p3(false);
- const [error2, setError] = p3(void 0);
- const [isSlow, setSlow] = p3(false);
- const request = async (...args) => {
- if (!fn2)
- return;
- setLoading(true);
- const handler = setTimeout(() => {
- setSlow(true);
- }, tooLong);
- try {
- const result = await fn2(...args);
- setData(result);
- } catch (error3) {
- setError(error3);
- }
- setLoading(false);
- setSlow(false);
- clearTimeout(handler);
- };
- function cancel() {
- setLoading(false);
- setSlow(false);
- }
- return {
- request,
- cancel,
- data,
- isSlow,
- isLoading,
- error: error2
- };
-}
-
-// src/components/exception/AsyncButton.tsx
-function AsyncButton({ onClick, disabled, children, ...rest }) {
- const { isSlow, isLoading, request, cancel } = useAsync(onClick);
- const { i18n: i18n2 } = useTranslationContext();
- if (isSlow) {
- return /* @__PURE__ */ h(LoadingModal, { onCancel: cancel });
- }
- if (isLoading) {
- return /* @__PURE__ */ h("button", { class: "button" }, /* @__PURE__ */ h(i18n2.Translate, null, "Loading..."));
- }
- return /* @__PURE__ */ h("span", { ...rest }, /* @__PURE__ */ h("button", { class: "button is-success", onClick: request, disabled }, children));
-}
-
-// src/components/instance/DefaultInstanceFormFields.tsx
-init_preact_module();
-
// src/components/form/InputDuration.tsx
init_preact_module();
init_hooks_module();
@@ -28285,11 +31035,11 @@ function DurationPicker({
));
}
function InputNumber({
- initial: initial2,
+ initial: initial3,
onChange
}) {
const [value, handler] = p3({
- v: toTwoDigitString(initial2)
+ v: toTwoDigitString(initial3)
});
return /* @__PURE__ */ h(
"input",
@@ -28300,7 +31050,7 @@ function InputNumber({
e4.preventDefault();
const n2 = Number.parseInt(e4.currentTarget.value, 10);
if (isNaN(n2))
- return handler({ v: toTwoDigitString(initial2) });
+ return handler({ v: toTwoDigitString(initial3) });
return handler({ v: toTwoDigitString(n2) });
},
style: {
@@ -28655,7 +31405,7 @@ function InputToggle({
disabled: readonly,
onChange: onCheckboxClick
}
- ), /* @__PURE__ */ h("div", { class: "toggle-switch" })), help), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2))));
+ ), /* @__PURE__ */ h("div", { class: `toggle-switch ${readonly ? "disabled" : ""}`, style: { cursor: readonly ? "default" : void 0 } })), help), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2))));
}
// src/components/form/InputWithAddon.tsx
@@ -28711,12 +31461,12 @@ function DefaultInstanceFormFields({
showId
}) {
const { i18n: i18n2 } = useTranslationContext();
- const { url: backendURL } = useBackendContext();
+ const { url: backendUrl } = useMerchantApiContext();
return /* @__PURE__ */ h(p2, null, showId && /* @__PURE__ */ h(
InputWithAddon,
{
name: "id",
- addonBefore: `${backendURL}/instances/`,
+ addonBefore: new URL("instances/", backendUrl.href).href,
readonly: readonlyId,
label: i18n2.str`Identifier`,
tooltip: i18n2.str`Name of the instance in URLs. The 'default' instance is special in that it is used to administer other instances.`
@@ -28917,26 +31667,34 @@ function CreatePage({ onCreate, onBack, forceId }) {
// src/paths/admin/create/index.tsx
function Create({ onBack, onConfirm, forceId }) {
- const { createInstance } = useAdminAPI();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- const { requestNewLoginToken } = useCredentialsChecker();
- const { url: backendURL, updateToken } = useBackendContext();
+ const { lib } = useMerchantApiContext();
+ const { state, logIn } = useSessionContext();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
CreatePage,
{
onBack,
forceId,
onCreate: async (d5) => {
+ if (state.status !== "loggedIn")
+ return;
try {
- await createInstance(d5);
+ await lib.instance.createInstance(state.token, d5);
if (d5.auth.token) {
- const resp = await requestNewLoginToken(backendURL, d5.auth.token);
- if (resp.valid) {
- const { token, expiration } = resp;
- updateToken({ token, expiration });
- } else {
- updateToken(void 0);
+ const result = await lib.authenticate.createAccessTokenBearer(
+ d5.auth.token,
+ {
+ scope: "write",
+ duration: {
+ d_us: "forever"
+ },
+ refreshable: true
+ }
+ );
+ if (result.type === "ok") {
+ const { token } = result.body;
+ logIn({ token });
}
}
onConfirm();
@@ -28960,6 +31718,222 @@ function Create({ onBack, onConfirm, forceId }) {
init_preact_module();
init_hooks_module();
+// src/components/ErrorLoadingMerchant.tsx
+init_preact_module();
+function ErrorLoadingMerchant({ error: error2, showDetail }) {
+ const { i18n: i18n2 } = useTranslationContext();
+ switch (error2.errorDetail.code) {
+ case TalerErrorCode.GENERIC_TIMEOUT: {
+ if (error2.hasErrorCode(TalerErrorCode.GENERIC_TIMEOUT)) {
+ const { requestMethod, requestUrl, timeoutMs } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`The request reached a timeout, check your connection.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, timeoutMs }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR: {
+ if (error2.hasErrorCode(TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR)) {
+ const { requestMethod, requestUrl, timeoutMs } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`The request was cancelled.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, timeoutMs }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT: {
+ if (error2.hasErrorCode(TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT)) {
+ const { requestMethod, requestUrl, timeoutMs } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`The request reached a timeout, check your connection.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, timeoutMs }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED: {
+ if (error2.hasErrorCode(TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED)) {
+ const { requestMethod, requestUrl, throttleStats } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`A lot of request were made to the same server and this action was throttled.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, throttleStats }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE: {
+ if (error2.hasErrorCode(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE)) {
+ const { requestMethod, requestUrl, httpStatusCode, validationError } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`The response of the request is malformed.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, httpStatusCode, validationError }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.WALLET_NETWORK_ERROR: {
+ if (error2.hasErrorCode(TalerErrorCode.WALLET_NETWORK_ERROR)) {
+ const { requestMethod, requestUrl } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`Could not complete the request due to a network problem.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ case TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR: {
+ if (error2.hasErrorCode(TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR)) {
+ const { requestMethod, requestUrl, httpStatusCode, errorResponse } = error2.errorDetail;
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`Unexpected request error.`,
+ description: error2.message,
+ details: JSON.stringify({ requestMethod, requestUrl, httpStatusCode, errorResponse }, void 0, 2)
+ }
+ }
+ );
+ }
+ assertUnreachable(1);
+ }
+ default: {
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "ERROR",
+ message: i18n2.str`Unexpected error.`,
+ description: error2.message,
+ details: JSON.stringify(error2.errorDetail, void 0, 2)
+ }
+ }
+ );
+ }
+ }
+}
+
+// src/hooks/instance.ts
+var useSWR2 = useSWR;
+function revalidateInstanceDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getCurrentInstanceDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useInstanceDetails() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token]) {
+ return await instance.getCurrentInstanceDetails(token);
+ }
+ const { data, error: error2 } = useSWR2([session.token, "getCurrentInstanceDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+function useInstanceKYCDetails() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token]) {
+ return await instance.getCurrentIntanceKycStatus(token, {});
+ }
+ const { data, error: error2 } = useSWR2([session.token, "getCurrentIntanceKycStatus"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+function revalidateManagedInstanceDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getInstanceDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useManagedInstanceDetails(instanceId) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, instanceId2]) {
+ return await instance.getInstanceDetails(token, instanceId2);
+ }
+ const { data, error: error2 } = useSWR2([session.token, instanceId, "getInstanceDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+function revalidateBackendInstances() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listInstances",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useBackendInstances() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token]) {
+ return await instance.listInstances(token);
+ }
+ const { data, error: error2 } = useSWR2([session.token, "listInstances"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+
// src/paths/admin/list/View.tsx
init_preact_module();
init_hooks_module();
@@ -28972,7 +31946,6 @@ function CardTable({
onCreate,
onUpdate,
onPurge,
- setInstanceName,
onDelete,
selected
}) {
@@ -29014,7 +31987,6 @@ function CardTable({
instances,
onPurge,
onUpdate,
- setInstanceName,
onDelete,
rowSelection,
rowSelectionHandler
@@ -29027,7 +31999,6 @@ function toggleSelected(id) {
function Table({
rowSelection,
rowSelectionHandler,
- setInstanceName,
instances,
onUpdate,
onDelete,
@@ -29051,16 +32022,7 @@ function Table({
checked: rowSelection.indexOf(i4.id) != -1,
onClick: () => rowSelectionHandler(toggleSelected(i4.id))
}
- ), /* @__PURE__ */ h("span", { class: "check" }))), /* @__PURE__ */ h("td", null, /* @__PURE__ */ h(
- "a",
- {
- href: `#/orders?instance=${i4.id}`,
- onClick: (e4) => {
- setInstanceName(i4.id);
- }
- },
- i4.id
- )), /* @__PURE__ */ h("td", null, i4.name), /* @__PURE__ */ h("td", { class: "is-actions-cell right-sticky" }, /* @__PURE__ */ h("div", { class: "buttons is-right" }, /* @__PURE__ */ h(
+ ), /* @__PURE__ */ h("span", { class: "check" }))), /* @__PURE__ */ h("td", null, i4.id), /* @__PURE__ */ h("td", null, i4.name), /* @__PURE__ */ h("td", { class: "is-actions-cell right-sticky" }, /* @__PURE__ */ h("div", { class: "buttons is-right" }, /* @__PURE__ */ h(
"button",
{
class: "button is-small is-success jb-modal",
@@ -29089,7 +32051,7 @@ function Table({
}
function EmptyTable() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no instances yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no instances yet, add more pressing the + sign")));
}
function notEmpty(value) {
return value !== null && value !== void 0;
@@ -29105,7 +32067,6 @@ function View({
onDelete,
onPurge,
onUpdate,
- setInstanceName,
selected
}) {
const [show, setShow] = p3("active");
@@ -29141,7 +32102,6 @@ function View({
instances: showingInstances,
onDelete,
onPurge,
- setInstanceName,
onUpdate,
selected,
onCreate
@@ -29149,39 +32109,228 @@ function View({
));
}
+// src/paths/login/index.tsx
+init_preact_module();
+init_hooks_module();
+var tokenRequest = {
+ scope: "write",
+ duration: {
+ d_us: "forever"
+ },
+ refreshable: true
+};
+function LoginPage(_p) {
+ const [token, setToken] = p3("");
+ const [notif, setNotif] = p3(void 0);
+ const { state, logIn, impersonate } = useSessionContext();
+ const { lib } = useMerchantApiContext();
+ const { i18n: i18n2 } = useTranslationContext();
+ async function doImpersonateImpl(instanceId) {
+ const newInstanceApi = lib.subInstanceApi(instanceId);
+ const cfg = await newInstanceApi.instance.getConfig();
+ if (cfg.type !== "ok") {
+ setNotif({
+ message: "Could not load the configuration of this instance.",
+ description: newInstanceApi.instance.baseUrl,
+ type: "ERROR"
+ });
+ return;
+ }
+ const result = await newInstanceApi.authenticate.createAccessTokenBearer(
+ token,
+ tokenRequest
+ );
+ if (result.type === "ok") {
+ const { token: token2 } = result.body;
+ impersonate({ instance: instanceId, baseUrl: new URL(newInstanceApi.instance.baseUrl), token: token2 });
+ return;
+ } else {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ setNotif({
+ message: "Your password is incorrect",
+ type: "ERROR"
+ });
+ return;
+ }
+ case HttpStatusCode.NotFound: {
+ setNotif({
+ message: "Your instance not found",
+ type: "ERROR"
+ });
+ return;
+ }
+ }
+ }
+ }
+ async function doLoginImpl() {
+ const result = await lib.authenticate.createAccessTokenBearer(
+ token,
+ tokenRequest
+ );
+ if (result.type === "ok") {
+ const { token: token2 } = result.body;
+ logIn({ token: token2 });
+ return;
+ } else {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ setNotif({
+ message: "Your password is incorrect",
+ type: "ERROR"
+ });
+ return;
+ }
+ case HttpStatusCode.NotFound: {
+ setNotif({
+ message: "Your instance not found",
+ type: "ERROR"
+ });
+ return;
+ }
+ }
+ }
+ }
+ if (state.status === "loggedIn" && state.impersonate !== void 0) {
+ return /* @__PURE__ */ h("div", { class: "columns is-centered", style: { margin: "auto" } }, /* @__PURE__ */ h("div", { class: "column is-two-thirds " }, /* @__PURE__ */ h("div", { class: "modal-card", style: { width: "100%", margin: 0 } }, /* @__PURE__ */ h(
+ "header",
+ {
+ class: "modal-card-head",
+ style: { border: "1px solid", borderBottom: 0 }
+ },
+ /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`Login required`)
+ ), /* @__PURE__ */ h(
+ "section",
+ {
+ class: "modal-card-body",
+ style: { border: "1px solid", borderTop: 0, borderBottom: 0 }
+ },
+ /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "Need the access token for the instance", " ", /* @__PURE__ */ h("b", null, '"', state.instance, '"'))),
+ /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access Token"))), /* @__PURE__ */ h("div", { class: "field-body" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control is-expanded" }, /* @__PURE__ */ h(
+ "input",
+ {
+ class: "input",
+ type: "password",
+ placeholder: "current access token",
+ name: "token",
+ onKeyPress: (e4) => e4.keyCode === 13 ? doImpersonateImpl(state.instance) : null,
+ value: token,
+ onInput: (e4) => setToken(e4?.currentTarget.value)
+ }
+ )))))
+ ), /* @__PURE__ */ h(
+ "footer",
+ {
+ class: "modal-card-foot ",
+ style: {
+ justifyContent: "flex-end",
+ border: "1px solid",
+ borderTop: 0
+ }
+ },
+ /* @__PURE__ */ h(AsyncButton2, { onClick: () => doImpersonateImpl(state.instance) }, /* @__PURE__ */ h(i18n2.Translate, null, "Confirm"))
+ ))));
+ }
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h("div", { class: "columns is-centered", style: { margin: "auto" } }, /* @__PURE__ */ h("div", { class: "column is-two-thirds " }, /* @__PURE__ */ h("div", { class: "modal-card", style: { width: "100%", margin: 0 } }, /* @__PURE__ */ h(
+ "header",
+ {
+ class: "modal-card-head",
+ style: { border: "1px solid", borderBottom: 0 }
+ },
+ /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`Login required`)
+ ), /* @__PURE__ */ h(
+ "section",
+ {
+ class: "modal-card-body",
+ style: { border: "1px solid", borderTop: 0, borderBottom: 0 }
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Please enter your access token for ", /* @__PURE__ */ h("b", null, '"', state.instance, '"'), "."),
+ /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access Token"))), /* @__PURE__ */ h("div", { class: "field-body" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control is-expanded" }, /* @__PURE__ */ h(
+ "input",
+ {
+ class: "input",
+ type: "password",
+ placeholder: "current access token",
+ name: "token",
+ onKeyPress: (e4) => e4.keyCode === 13 ? doLoginImpl() : null,
+ value: token,
+ onInput: (e4) => setToken(e4?.currentTarget.value)
+ }
+ )))))
+ ), /* @__PURE__ */ h(
+ "footer",
+ {
+ class: "modal-card-foot ",
+ style: {
+ justifyContent: "space-between",
+ border: "1px solid",
+ borderTop: 0
+ }
+ },
+ /* @__PURE__ */ h("div", null),
+ /* @__PURE__ */ h(AsyncButton2, { type: "is-info", onClick: doLoginImpl }, /* @__PURE__ */ h(i18n2.Translate, null, "Confirm"))
+ )))));
+}
+function AsyncButton2({
+ onClick,
+ disabled,
+ type = "",
+ children
+}) {
+ const [running, setRunning] = p3(false);
+ return /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button " + type,
+ disabled: disabled || running,
+ onClick: () => {
+ setRunning(true);
+ onClick().then(() => {
+ setRunning(false);
+ }).catch(() => {
+ setRunning(false);
+ });
+ }
+ },
+ children
+ );
+}
+
// src/paths/admin/list/index.tsx
function Instances({
- onUnauthorized,
- onLoadError,
- onNotFound,
onCreate,
- onUpdate,
- setInstanceName
+ onUpdate
}) {
const result = useBackendInstances();
const [deleting, setDeleting] = p3(null);
const [purging, setPurging] = p3(null);
- const { deleteInstance, purgeInstance } = useAdminAPI();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
View,
{
- instances: result.data.instances,
+ instances: result.body.instances,
onDelete: setDeleting,
onCreate,
onPurge: setPurging,
onUpdate,
- setInstanceName,
selected: !!deleting
}
), deleting && /* @__PURE__ */ h(
@@ -29190,8 +32339,11 @@ function Instances({
element: deleting,
onCancel: () => setDeleting(null),
onConfirm: async () => {
+ if (state.status !== "loggedIn") {
+ return;
+ }
try {
- await deleteInstance(deleting.id);
+ await lib.instance.deleteInstance(state.token, deleting.id);
setNotif({
message: i18n2.str`Instance "${deleting.name}" (ID: ${deleting.id}) has been deleted`,
type: "SUCCESS"
@@ -29212,8 +32364,11 @@ function Instances({
element: purging,
onCancel: () => setPurging(null),
onConfirm: async () => {
+ if (state.status !== "loggedIn") {
+ return;
+ }
try {
- await purgeInstance(purging.id);
+ await lib.instance.deleteInstance(state.token, purging.id, { purge: true });
setNotif({
message: i18n2.str`Instance '${purging.name}' (ID: ${purging.id}) has been disabled`,
type: "SUCCESS"
@@ -29276,13 +32431,6 @@ function NavigationBar({ onMobileMenu, title }) {
// src/components/menu/SideBar.tsx
init_preact_module();
-// src/context/config.ts
-init_preact_module();
-init_hooks_module();
-var Context4 = B(null);
-var ConfigContextProvider = Context4.Provider;
-var useConfigContext = () => q2(Context4);
-
// src/components/menu/LangSelector.tsx
init_preact_module();
init_hooks_module();
@@ -38969,56 +42117,62 @@ function LangSelector() {
// src/components/menu/SideBar.tsx
var VERSION = true ? "0.9.3-dev.27" : void 0;
-function Sidebar({
- mobile,
- instance,
- onShowSettings,
- onLogout,
- admin,
- mimic,
- isPasswordOk
-}) {
- const config = useConfigContext();
- const { url: backendURL } = useBackendContext();
+function Sidebar({ mobile }) {
const { i18n: i18n2 } = useTranslationContext();
const kycStatus = useInstanceKYCDetails();
- const needKYC = kycStatus.ok && kycStatus.data.type === "redirect";
- return /* @__PURE__ */ h("aside", { class: "aside is-placed-left is-expanded", style: { overflowY: "scroll" } }, mobile && /* @__PURE__ */ h(
- "div",
- {
- class: "footer",
- onClick: (e4) => {
- return e4.stopImmediatePropagation();
- }
- },
- /* @__PURE__ */ h(LangSelector, null)
- ), /* @__PURE__ */ h("div", { class: "aside-tools" }, /* @__PURE__ */ h("div", { class: "aside-tools-label" }, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("b", null, "Taler"), " Backoffice"), /* @__PURE__ */ h(
- "div",
- {
- class: "is-size-7 has-text-right",
- style: { lineHeight: 0, marginTop: -10 }
- },
- VERSION,
- " (",
- config.version,
- ")"
- ))), /* @__PURE__ */ h("div", { class: "menu is-menu-main" }, instance ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/orders", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-cash-register" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Orders")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/inventory", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-shopping" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Inventory")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/transfers", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-arrow-left-right" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Transfers")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/templates", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Templates")))), needKYC && /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/kyc", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-account-check" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, "KYC Status")))), /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Configuration")), /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/bank", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-bank" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Bank account")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/otp-devices", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-lock" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "OTP Devices")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/webhooks", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Webhooks")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/settings", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-square-edit-outline" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Settings")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/token", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-security" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access token")))))) : void 0, /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Connection")), /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h(
- "a",
- {
- class: "has-icon is-state-info is-hoverable",
- onClick: () => onShowSettings()
- },
- /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })),
- /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Interface"))
- )), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("span", { style: { width: "3rem" }, class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-web" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, new URL(backendURL).hostname))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("span", { style: { width: "3rem" }, class: "icon" }, "ID"), /* @__PURE__ */ h("span", { class: "menu-item-label" }, !instance ? "default" : instance))), admin && !mimic && /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Instances")), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/instance/new", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-plus" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "New")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/instances", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-format-list-bulleted" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "List"))))), isPasswordOk ? /* @__PURE__ */ h("li", null, /* @__PURE__ */ h(
- "a",
+ const needKYC = kycStatus !== void 0 && !(kycStatus instanceof TalerError) && kycStatus.type === "ok" && !!kycStatus.body;
+ const { state, logOut } = useSessionContext();
+ const isLoggedIn = state.status === "loggedIn";
+ const hasToken = isLoggedIn && state.token !== void 0;
+ const { config, url: backendURL } = useMerchantApiContext();
+ return /* @__PURE__ */ h(
+ "aside",
{
- class: "has-icon is-state-info is-hoverable",
- onClick: () => onLogout()
+ class: "aside is-placed-left is-expanded",
+ style: { overflowY: "scroll" }
},
- /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-logout default" })),
- /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Log out"))
- )) : void 0)));
+ mobile && /* @__PURE__ */ h(
+ "div",
+ {
+ class: "footer",
+ onClick: (e4) => {
+ return e4.stopImmediatePropagation();
+ }
+ },
+ /* @__PURE__ */ h(LangSelector, null)
+ ),
+ /* @__PURE__ */ h("div", { class: "aside-tools" }, /* @__PURE__ */ h("div", { class: "aside-tools-label" }, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("b", null, "Taler"), " Backoffice"), /* @__PURE__ */ h(
+ "div",
+ {
+ class: "is-size-7 has-text-right",
+ style: { lineHeight: 0, marginTop: -10 }
+ },
+ VERSION,
+ " (",
+ config.version,
+ ")"
+ ))),
+ /* @__PURE__ */ h("div", { class: "menu is-menu-main" }, isLoggedIn ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/orders", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-cash-register" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Orders")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/inventory", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-shopping" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Inventory")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/transfers", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-arrow-left-right" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Transfers")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/templates", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Templates")))), needKYC && /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/kyc", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-account-check" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, "KYC Status")))), /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Configuration")), /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/bank", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-bank" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Bank account")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/otp-devices", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-lock" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "OTP Devices")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/webhooks", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Webhooks")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/settings", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-square-edit-outline" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Settings")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/token", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-security" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access token")))))) : void 0, /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Connection")), /* @__PURE__ */ h("ul", { class: "menu-list" }, /* @__PURE__ */ h("li", null, /* @__PURE__ */ h(
+ "a",
+ {
+ class: "has-icon is-state-info is-hoverable",
+ href: "/interface"
+ },
+ /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-newspaper" })),
+ /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Interface"))
+ )), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("span", { style: { width: "3rem" }, class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-web" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, backendURL.hostname))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("span", { style: { width: "3rem" }, class: "icon" }, "ID"), /* @__PURE__ */ h("span", { class: "menu-item-label" }, state.instance))), state.isAdmin && /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("p", { class: "menu-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Instances")), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/instance/new", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-plus" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "New")))), /* @__PURE__ */ h("li", null, /* @__PURE__ */ h("a", { href: "/instances", class: "has-icon" }, /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-format-list-bulleted" })), /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "List"))))), hasToken ? /* @__PURE__ */ h("li", null, /* @__PURE__ */ h(
+ "a",
+ {
+ class: "has-icon is-state-info is-hoverable",
+ onClick: (e4) => {
+ logOut();
+ e4.preventDefault();
+ }
+ },
+ /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-logout default" })),
+ /* @__PURE__ */ h("span", { class: "menu-item-label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Log out"))
+ )) : void 0))
+ );
}
// src/components/menu/index.tsx
@@ -39086,20 +42240,12 @@ function WithTitle({
}, [title]);
return /* @__PURE__ */ h(p2, null, children);
}
-function Menu({
- onLogout,
- onShowSettings,
- title,
- instance,
- path,
- admin,
- setInstanceName,
- isPasswordOk
-}) {
+function Menu(_p) {
const [mobileOpen, setMobileOpen] = p3(false);
- const titleWithSubtitle = title ? title : !admin ? getInstanceTitle(path, instance) : getAdminTitle(path, instance);
- const adminInstance = instance === "default";
- const mimic = admin && !adminInstance;
+ const { state, deImpersonate } = useSessionContext();
+ const { path } = useNavigationContext();
+ const titleWithSubtitle = !state.isAdmin ? getInstanceTitle(path, state.instance) : getAdminTitle(path, state.instance);
+ const isLoggedIn = state.status === "loggedIn";
return /* @__PURE__ */ h(WithTitle, { title: titleWithSubtitle }, /* @__PURE__ */ h(
"div",
{
@@ -39113,33 +42259,30 @@ function Menu({
title: titleWithSubtitle
}
),
- onLogout && /* @__PURE__ */ h(
- Sidebar,
- {
- onShowSettings,
- onLogout,
- admin,
- mimic,
- instance,
- mobile: mobileOpen,
- isPasswordOk
- }
- ),
- mimic && /* @__PURE__ */ h("nav", { class: "level", style: {
- zIndex: 100,
- position: "fixed",
- width: "50%",
- marginLeft: "20%"
- } }, /* @__PURE__ */ h("div", { class: "level-item has-text-centered has-background-warning" }, /* @__PURE__ */ h("p", { class: "is-size-5" }, "You are viewing the instance ", /* @__PURE__ */ h("b", null, '"', instance, '"'), ".", " ", /* @__PURE__ */ h(
- "a",
+ isLoggedIn && /* @__PURE__ */ h(Sidebar, { mobile: mobileOpen }),
+ state.status !== "loggedOut" && state.impersonate !== void 0 && /* @__PURE__ */ h(
+ "nav",
{
- href: "#/instances",
- onClick: (e4) => {
- setInstanceName("default");
+ class: "level",
+ style: {
+ zIndex: 100,
+ position: "fixed",
+ width: "50%",
+ marginLeft: "20%"
}
},
- "go back"
- ))))
+ /* @__PURE__ */ h("div", { class: "level-item has-text-centered has-background-warning" }, /* @__PURE__ */ h("p", { class: "is-size-5" }, "You are viewing the instance ", /* @__PURE__ */ h("b", null, '"', state.instance, '"'), ".", " ", /* @__PURE__ */ h(
+ "a",
+ {
+ href: "#/instances",
+ onClick: (e4) => {
+ deImpersonate();
+ e4.preventDefault();
+ }
+ },
+ "go back"
+ )))
+ )
));
}
function NotificationCard({
@@ -39178,150 +42321,82 @@ function NotConnectedAppMenu({
)
);
}
-function NotYetReadyAppMenu({
- onLogout,
- onShowSettings,
- title,
- isPasswordOk
-}) {
- const [mobileOpen, setMobileOpen] = p3(false);
- h2(() => {
- document.title = `Taler Backoffice: ${title}`;
- }, [title]);
- return /* @__PURE__ */ h(
- "div",
- {
- class: mobileOpen ? "has-aside-mobile-expanded" : "",
- onClick: () => setMobileOpen(false)
- },
- /* @__PURE__ */ h(
- NavigationBar,
- {
- onMobileMenu: () => setMobileOpen(!mobileOpen),
- title
- }
- ),
- onLogout && /* @__PURE__ */ h(Sidebar, { onShowSettings, onLogout, instance: "", mobile: mobileOpen, isPasswordOk })
- );
-}
// src/hooks/bank.ts
-init_hooks_module();
var useSWR3 = useSWR;
-function useBankAccountAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const createBankAccount = async (data) => {
- const res = await request(`/private/accounts`, {
- method: "POST",
- data
- });
- await mutateAll(/.*private\/accounts.*/);
- return res;
- };
- const updateBankAccount = async (h_wire, data) => {
- const res = await request(`/private/accounts/${h_wire}`, {
- method: "PATCH",
- data
- });
- await mutateAll(/.*private\/accounts.*/);
- return res;
- };
- const deleteBankAccount = async (h_wire) => {
- const res = await request(`/private/accounts/${h_wire}`, {
- method: "DELETE"
- });
- await mutateAll(/.*private\/accounts.*/);
- return res;
- };
- return {
- createBankAccount,
- updateBankAccount,
- deleteBankAccount
- };
+function revalidateInstanceBankAccounts() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listBankAccounts",
+ void 0,
+ { revalidate: true }
+ );
}
-function useInstanceBankAccounts(args, updatePosition) {
- const { fetcher } = useBackendInstanceRequest();
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR3([`/private/accounts`], fetcher);
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- }, [
- afterData
- /*, beforeData*/
- ]);
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.accounts.length < totalAfter;
- const isReachingStart = false;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
- return;
- if (afterData.data.accounts.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = `${afterData.data.accounts[afterData.data.accounts.length - 1].h_wire}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- },
- loadMorePrev: () => {
- }
- };
- const accounts = !afterData ? [] : (afterData || lastAfter).data.accounts;
- if (loadingAfter)
- return { loading: true, data: { accounts } };
- if (
- /*beforeData &&*/
- afterData
- ) {
- return { ok: true, data: { accounts }, ...pagination };
+function useInstanceBankAccounts() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, bid]) {
+ return await instance.listBankAccounts(token, {
+ // limit: PAGINATED_LIST_REQUEST,
+ // offset: bid,
+ // order: "dec",
+ });
}
- return { loading: true };
+ const { data, error: error2 } = useSWR3([session.token, "offset", "listBankAccounts"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return data;
+}
+function revalidateBankAccountDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getBankAccountDetails",
+ void 0,
+ { revalidate: true }
+ );
}
function useBankAccountDetails(h_wire) {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR3([`/private/accounts/${h_wire}`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data) {
- return data;
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, wireId]) {
+ return await instance.getBankAccountDetails(token, wireId);
}
+ const { data, error: error2 } = useSWR3([session.token, h_wire, "getBankAccountDetails"], fetcher);
+ if (data)
+ return data;
if (error2)
- return error2.cause;
- return { loading: true };
+ return error2;
+ return void 0;
}
-// src/hooks/useSettings.ts
+// src/hooks/preference.ts
var defaultSettings = {
advanceOrderMode: false,
+ hideKycUntil: AbsoluteTime.never(),
+ hideMissingAccountUntil: AbsoluteTime.never(),
dateFormat: "ymd"
};
-var codecForSettings = () => buildCodecForObject().property("advanceOrderMode", codecForBoolean()).property("dateFormat", codecForEither(
- codecForConstString("ymd"),
- codecForConstString("dmy"),
- codecForConstString("mdy")
-)).build("Settings");
-var SETTINGS_KEY = buildStorageKey("merchant-settings", codecForSettings());
-function useSettings() {
- const { value, update } = useLocalStorage(SETTINGS_KEY, defaultSettings);
- return [value, update];
+var codecForPreferences = () => buildCodecForObject().property("advanceOrderMode", codecForBoolean()).property("hideKycUntil", codecForAbsoluteTime).property("hideMissingAccountUntil", codecForAbsoluteTime).property(
+ "dateFormat",
+ codecForEither(
+ codecForConstString("ymd"),
+ codecForConstString("dmy"),
+ codecForConstString("mdy")
+ )
+).build("Preferences");
+var PREFERENCES_KEY = buildStorageKey(
+ "merchant-preferences",
+ codecForPreferences()
+);
+function usePreference() {
+ const { value, update } = useLocalStorage(PREFERENCES_KEY, defaultSettings);
+ function updateField(k5, v3) {
+ const newValue = { ...value, [k5]: v3 };
+ update(newValue);
+ }
+ return [value, updateField, update];
}
function dateFormatForSettings(s5) {
switch (s5.dateFormat) {
@@ -39436,13 +42511,13 @@ function InputPaytoForm({
const paths = !initialPayto ? [] : initialPayto.targetPath.split("/");
const initialPath1 = paths.length >= 1 ? paths[0] : void 0;
const initialPath2 = paths.length >= 2 ? paths[1] : void 0;
- const initial2 = initialPayto === void 0 ? defaultTarget : {
+ const initial3 = initialPayto === void 0 ? defaultTarget : {
target: initialPayto.targetType,
params: initialPayto.params,
path1: initialPath1,
path2: initialPath2
};
- const [value, setValue] = p3(initial2);
+ const [value, setValue] = p3(initial3);
const { i18n: i18n2 } = useTranslationContext();
const errors2 = {
target: value.target === noTargetValue ? i18n2.str`required` : void 0,
@@ -39586,26 +42661,138 @@ function InputPaytoForm({
));
}
-// src/paths/instance/accounts/create/CreatePage.tsx
-var accountAuthType = ["none", "basic"];
-function isValidURL(s5) {
+// src/paths/instance/accounts/update/UpdatePage.tsx
+init_preact_module();
+init_hooks_module();
+var accountAuthType = ["unedit", "none", "basic"];
+function UpdatePage({ account, onUpdate, onBack }) {
+ const { i18n: i18n2 } = useTranslationContext();
+ const [state, setState] = p3(account);
+ if (state.credit_facade_credentials?.type === "unedit") {
+ state.credit_facade_credentials = void 0;
+ }
+ const facadeURL = safeConvertURL(state.credit_facade_url);
+ const errors2 = {
+ credit_facade_url: !state.credit_facade_url ? void 0 : !facadeURL ? i18n2.str`Invalid url` : !facadeURL.href.endsWith("/") ? i18n2.str`URL should end with a '/'` : facadeURL.searchParams.size > 0 ? i18n2.str`URL should not contain params` : facadeURL.hash ? i18n2.str`URL should not hash param` : void 0,
+ credit_facade_credentials: undefinedIfEmpty({
+ username: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.username ? i18n2.str`required` : void 0,
+ password: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.password ? i18n2.str`required` : void 0,
+ repeatPassword: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.repeatPassword ? i18n2.str`required` : state.credit_facade_credentials.repeatPassword !== state.credit_facade_credentials.password ? i18n2.str`doesn't match` : void 0
+ })
+ };
+ const hasErrors = Object.keys(errors2).some(
+ (k5) => errors2[k5] !== void 0
+ );
+ const submitForm = () => {
+ if (hasErrors)
+ return Promise.reject();
+ const credit_facade_url = !state.credit_facade_url ? void 0 : facadeURL?.href;
+ const credit_facade_credentials = credit_facade_url == void 0 || state.credit_facade_credentials === void 0 ? void 0 : state.credit_facade_credentials.type === "basic" ? {
+ type: "basic",
+ password: state.credit_facade_credentials.password,
+ username: state.credit_facade_credentials.username
+ } : {
+ type: "none"
+ };
+ return onUpdate({ credit_facade_credentials, credit_facade_url });
+ };
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, "Account: ", /* @__PURE__ */ h("b", null, account.id.substring(0, 8), "..."))))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
+ FormProvider,
+ {
+ object: state,
+ valueHandler: setState,
+ errors: errors2
+ },
+ /* @__PURE__ */ h(
+ InputPaytoForm,
+ {
+ name: "payto_uri",
+ label: i18n2.str`Account`,
+ readonly: true
+ }
+ ),
+ /* @__PURE__ */ h(
+ Input,
+ {
+ name: "credit_facade_url",
+ label: i18n2.str`Account info URL`,
+ help: "https://bank.com",
+ expand: true,
+ tooltip: i18n2.str`From where the merchant can download information about incoming wire transfers to this account`
+ }
+ ),
+ /* @__PURE__ */ h(
+ InputSelector,
+ {
+ name: "credit_facade_credentials.type",
+ label: i18n2.str`Auth type`,
+ tooltip: i18n2.str`Choose the authentication type for the account info URL`,
+ values: accountAuthType,
+ toStr: (str) => {
+ if (str === "none")
+ return "Without authentication";
+ if (str === "basic")
+ return "With authentication";
+ return "Do not change";
+ }
+ }
+ ),
+ state.credit_facade_credentials?.type === "basic" ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
+ Input,
+ {
+ name: "credit_facade_credentials.username",
+ label: i18n2.str`Username`,
+ tooltip: i18n2.str`Username to access the account information.`
+ }
+ ), /* @__PURE__ */ h(
+ Input,
+ {
+ name: "credit_facade_credentials.password",
+ inputType: "password",
+ label: i18n2.str`Password`,
+ tooltip: i18n2.str`Password to access the account information.`
+ }
+ ), /* @__PURE__ */ h(
+ Input,
+ {
+ name: "credit_facade_credentials.repeatPassword",
+ inputType: "password",
+ label: i18n2.str`Repeat password`
+ }
+ )) : void 0
+ ), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ AsyncButton,
+ {
+ disabled: hasErrors,
+ "data-tooltip": hasErrors ? i18n2.str`Need to complete marked fields` : "confirm operation",
+ onClick: submitForm
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Confirm")
+ )))))));
+}
+function safeConvertURL(s5) {
+ if (!s5)
+ return void 0;
try {
- const u4 = new URL("/", s5);
- return true;
+ return new URL(s5);
} catch (e4) {
- return false;
+ return void 0;
}
}
+
+// src/paths/instance/accounts/create/CreatePage.tsx
+var accountAuthType2 = ["none", "basic"];
function CreatePage2({ onCreate, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
const [state, setState] = p3({});
+ const facadeURL = safeConvertURL(state.credit_facade_url);
const errors2 = {
payto_uri: !state.payto_uri ? i18n2.str`required` : void 0,
credit_facade_credentials: !state.credit_facade_credentials ? void 0 : undefinedIfEmpty({
username: state.credit_facade_credentials.type === "basic" && !state.credit_facade_credentials.username ? i18n2.str`required` : void 0,
password: state.credit_facade_credentials.type === "basic" && !state.credit_facade_credentials.password ? i18n2.str`required` : void 0
}),
- credit_facade_url: !state.credit_facade_url ? void 0 : !isValidURL(state.credit_facade_url) ? i18n2.str`not valid url` : void 0,
+ credit_facade_url: !state.credit_facade_url ? void 0 : !facadeURL ? i18n2.str`Invalid url` : !facadeURL.href.endsWith("/") ? i18n2.str`URL should end with a '/'` : facadeURL.searchParams.size > 0 ? i18n2.str`URL should not contain params` : facadeURL.hash ? i18n2.str`URL should not hash param` : void 0,
repeatPassword: !state.credit_facade_credentials ? void 0 : state.credit_facade_credentials.type === "basic" && (!state.credit_facade_credentials.password || state.credit_facade_credentials.password !== state.repeatPassword) ? i18n2.str`is not the same` : void 0
};
const hasErrors = Object.keys(errors2).some(
@@ -39614,7 +42801,7 @@ function CreatePage2({ onCreate, onBack }) {
const submitForm = () => {
if (hasErrors)
return Promise.reject();
- const credit_facade_url = !state.credit_facade_url ? void 0 : new URL("/", state.credit_facade_url).href;
+ const credit_facade_url = !state.credit_facade_url ? void 0 : facadeURL?.href;
const credit_facade_credentials = credit_facade_url == void 0 ? void 0 : state.credit_facade_credentials?.type === "basic" ? {
type: "basic",
password: state.credit_facade_credentials.password,
@@ -39658,7 +42845,7 @@ function CreatePage2({ onCreate, onBack }) {
name: "credit_facade_credentials.type",
label: i18n2.str`Auth type`,
tooltip: i18n2.str`Choose the authentication type for the account info URL`,
- values: accountAuthType,
+ values: accountAuthType2,
toStr: (str) => {
if (str === "none")
return "Without authentication";
@@ -39702,15 +42889,70 @@ function CreatePage2({ onCreate, onBack }) {
// src/paths/instance/accounts/create/index.tsx
function CreateValidator({ onConfirm, onBack }) {
- const { createBankAccount } = useBankAccountAPI();
+ const { lib: api } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
CreatePage2,
{
onBack,
- onCreate: (request) => {
- return createBankAccount(request).then((d5) => {
+ onCreate: async (request) => {
+ const revenueAPI = !request.credit_facade_url ? void 0 : new URL("./", request.credit_facade_url);
+ if (revenueAPI) {
+ const resp = await testRevenueAPI(
+ revenueAPI,
+ request.credit_facade_credentials
+ );
+ if (resp.type === "fail") {
+ switch (resp.case) {
+ case 0 /* NO_CONFIG */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`The endpoint doesn't seems to be a Taler Revenue API`
+ });
+ return;
+ }
+ case 1 /* CLIENT_BAD_REQUEST */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Server replied with "bad request".`
+ });
+ return;
+ }
+ case 2 /* UNAUTHORIZED */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Unauthorized, try with another credentials.`
+ });
+ return;
+ }
+ case 3 /* NOT_FOUND */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Check facade URL, server replied with "not found".`
+ });
+ return;
+ }
+ case 4 /* GENERIC_ERROR */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: resp.detail.hint
+ });
+ return;
+ }
+ default: {
+ assertUnreachable(resp.case);
+ }
+ }
+ }
+ }
+ return api.instance.addBankAccount(state.token, request).then(() => {
onConfirm();
}).catch((error2) => {
setNotif({
@@ -39723,11 +42965,118 @@ function CreateValidator({ onConfirm, onBack }) {
}
));
}
+async function testRevenueAPI(revenueAPI, creds) {
+ const api = new TalerRevenueHttpClient(
+ revenueAPI.href,
+ new BrowserFetchHttpLib()
+ );
+ const auth = creds === void 0 ? void 0 : creds.type === "none" ? void 0 : creds.type === "basic" ? {
+ username: creds.username,
+ password: creds.password
+ } : void 0;
+ try {
+ const config = await api.getConfig(auth);
+ if (config.type === "fail") {
+ switch (config.case) {
+ case HttpStatusCode.Unauthorized: {
+ return {
+ type: "fail",
+ case: 2 /* UNAUTHORIZED */,
+ detail: {
+ code: 1
+ }
+ };
+ }
+ case HttpStatusCode.NotFound: {
+ return {
+ type: "fail",
+ case: 0 /* NO_CONFIG */,
+ detail: {
+ code: 1
+ }
+ };
+ }
+ }
+ }
+ const history3 = await api.getHistory(auth);
+ if (history3.type === "fail") {
+ switch (history3.case) {
+ case HttpStatusCode.BadRequest: {
+ return {
+ type: "fail",
+ case: 1 /* CLIENT_BAD_REQUEST */,
+ detail: {
+ code: 1
+ }
+ };
+ }
+ case HttpStatusCode.Unauthorized: {
+ return {
+ type: "fail",
+ case: 2 /* UNAUTHORIZED */,
+ detail: {
+ code: 1
+ }
+ };
+ }
+ case HttpStatusCode.NotFound: {
+ return {
+ type: "fail",
+ case: 3 /* NOT_FOUND */,
+ detail: {
+ code: 1
+ }
+ };
+ }
+ }
+ }
+ } catch (err) {
+ if (err instanceof TalerError) {
+ return {
+ type: "fail",
+ case: 4 /* GENERIC_ERROR */,
+ detail: err.errorDetail
+ };
+ }
+ }
+ return opFixedSuccess(void 0);
+}
// src/paths/instance/accounts/list/index.tsx
init_preact_module();
init_hooks_module();
+// src/paths/notfound/index.tsx
+init_preact_module();
+function NotFoundPage() {
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("p", null, "That page doesn't exist."), /* @__PURE__ */ h(Link, { href: "/" }, /* @__PURE__ */ h("h4", null, "Back to Home")));
+}
+function NotFoundPageOrAdminCreate() {
+ const { state } = useSessionContext();
+ const { i18n: i18n2 } = useTranslationContext();
+ if (state.isAdmin && state.instance === DEFAULT_ADMIN_USERNAME) {
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ message: i18n2.str`No 'default' instance configured yet.`,
+ description: i18n2.str`Create a 'default' instance to begin using the merchant backoffice.`,
+ type: "INFO"
+ }
+ }
+ ), /* @__PURE__ */ h(
+ Create,
+ {
+ forceId: DEFAULT_ADMIN_USERNAME,
+ onConfirm: () => {
+ route("/bank" /* bank_list */);
+ }
+ }
+ ));
+ }
+ return /* @__PURE__ */ h(NotFoundPage, null);
+}
+
// src/paths/instance/accounts/list/ListPage.tsx
init_preact_module();
@@ -39738,11 +43087,7 @@ function CardTable2({
accounts,
onCreate,
onDelete,
- onSelect,
- onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onSelect
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -39760,22 +43105,14 @@ function CardTable2({
onDelete,
onSelect,
rowSelection,
- rowSelectionHandler,
- onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ rowSelectionHandler
}
) : /* @__PURE__ */ h(EmptyTable2, null)))));
}
function Table2({
accounts,
- onLoadMoreAfter,
onDelete,
- onSelect,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onSelect
}) {
const { i18n: i18n2 } = useTranslationContext();
const emptyList = { "bitcoin": [], "x-taler-bank": [], "iban": [], "unknown": [] };
@@ -39912,7 +43249,7 @@ function Table2({
}
function EmptyTable2() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no accounts yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no accounts yet, add more pressing the + sign")));
}
// src/paths/instance/accounts/list/ListPage.tsx
@@ -39920,12 +43257,10 @@ function ListPage({
devices,
onCreate,
onDelete,
- onSelect,
- onLoadMoreBefore,
- onLoadMoreAfter
+ onSelect
+ // onLoadMoreBefore,
+ // onLoadMoreAfter,
}) {
- const form = { payto_uri: "" };
- const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(
CardTable2,
{
@@ -39935,63 +43270,65 @@ function ListPage({
})),
onCreate,
onDelete,
- onSelect,
- onLoadMoreBefore,
- hasMoreBefore: !onLoadMoreBefore,
- onLoadMoreAfter,
- hasMoreAfter: !onLoadMoreAfter
+ onSelect
}
));
}
// src/paths/instance/accounts/list/index.tsx
function ListOtpDevices({
- onUnauthorized,
- onLoadError,
onCreate,
- onSelect,
- onNotFound
+ onSelect
}) {
- const [position, setPosition] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
const [notif, setNotif] = p3(void 0);
- const { deleteBankAccount } = useBankAccountAPI();
- const result = useInstanceBankAccounts({ position }, (id) => setPosition(id));
- if (result.loading)
+ const { lib: api } = useMerchantApiContext();
+ const { state } = useSessionContext();
+ const result = useInstanceBankAccounts();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
- }
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), result.data.accounts.length < 1 && /* @__PURE__ */ h(NotificationCard, { notification: {
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
+ }
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), result.body.accounts.length < 1 && /* @__PURE__ */ h(NotificationCard, { notification: {
type: "WARN",
message: i18n2.str`You need to associate a bank account to receive revenue.`,
description: i18n2.str`Without this the merchant backend will refuse to create new orders.`
} }), /* @__PURE__ */ h(
ListPage,
{
- devices: result.data.accounts,
- onLoadMoreBefore: result.isReachingStart ? result.loadMorePrev : void 0,
- onLoadMoreAfter: result.isReachingEnd ? result.loadMore : void 0,
+ devices: result.body.accounts,
onCreate,
onSelect: (e4) => {
onSelect(e4.h_wire);
},
- onDelete: (e4) => deleteBankAccount(e4.h_wire).then(
- () => setNotif({
- message: i18n2.str`bank account delete successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not delete the bank account`,
- type: "ERROR",
- description: error2.message
- })
- )
+ onDelete: (e4) => {
+ return api.instance.deleteBankAccount(state.token, e4.h_wire).then(
+ () => setNotif({
+ message: i18n2.str`bank account delete successfully`,
+ type: "SUCCESS"
+ })
+ ).catch(
+ (error2) => setNotif({
+ message: i18n2.str`could not delete the bank account`,
+ type: "ERROR",
+ description: error2.message
+ })
+ );
+ }
}
));
}
@@ -39999,153 +43336,95 @@ function ListOtpDevices({
// src/paths/instance/accounts/update/index.tsx
init_preact_module();
init_hooks_module();
-
-// src/paths/instance/accounts/update/UpdatePage.tsx
-init_preact_module();
-init_hooks_module();
-var accountAuthType2 = ["unedit", "none", "basic"];
-function UpdatePage({ account, onUpdate, onBack }) {
- const { i18n: i18n2 } = useTranslationContext();
- const [state, setState] = p3(account);
- if (state.credit_facade_credentials?.type === "unedit") {
- state.credit_facade_credentials = void 0;
- }
- const errors2 = {
- credit_facade_url: !state.credit_facade_url ? void 0 : !isValidURL2(state.credit_facade_url) ? i18n2.str`invalid url` : void 0,
- credit_facade_credentials: undefinedIfEmpty({
- username: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.username ? i18n2.str`required` : void 0,
- password: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.password ? i18n2.str`required` : void 0,
- repeatPassword: state.credit_facade_credentials?.type !== "basic" ? void 0 : !state.credit_facade_credentials.repeatPassword ? i18n2.str`required` : state.credit_facade_credentials.repeatPassword !== state.credit_facade_credentials.password ? i18n2.str`doesn't match` : void 0
- })
- };
- const hasErrors = Object.keys(errors2).some(
- (k5) => errors2[k5] !== void 0
- );
- const submitForm = () => {
- if (hasErrors)
- return Promise.reject();
- const credit_facade_url = !state.credit_facade_url ? void 0 : new URL("/", state.credit_facade_url).href;
- const credit_facade_credentials = credit_facade_url == void 0 || state.credit_facade_credentials === void 0 ? void 0 : state.credit_facade_credentials.type === "basic" ? {
- type: "basic",
- password: state.credit_facade_credentials.password,
- username: state.credit_facade_credentials.username
- } : {
- type: "none"
- };
- return onUpdate({ credit_facade_credentials, credit_facade_url });
- };
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, "Account: ", /* @__PURE__ */ h("b", null, account.id.substring(0, 8), "..."))))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
- FormProvider,
- {
- object: state,
- valueHandler: setState,
- errors: errors2
- },
- /* @__PURE__ */ h(
- InputPaytoForm,
- {
- name: "payto_uri",
- label: i18n2.str`Account`,
- readonly: true
- }
- ),
- /* @__PURE__ */ h(
- Input,
- {
- name: "credit_facade_url",
- label: i18n2.str`Account info URL`,
- help: "https://bank.com",
- expand: true,
- tooltip: i18n2.str`From where the merchant can download information about incoming wire transfers to this account`
- }
- ),
- /* @__PURE__ */ h(
- InputSelector,
- {
- name: "credit_facade_credentials.type",
- label: i18n2.str`Auth type`,
- tooltip: i18n2.str`Choose the authentication type for the account info URL`,
- values: accountAuthType2,
- toStr: (str) => {
- if (str === "none")
- return "Without authentication";
- if (str === "basic")
- return "With authentication";
- return "Do not change";
- }
- }
- ),
- state.credit_facade_credentials?.type === "basic" ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
- Input,
- {
- name: "credit_facade_credentials.username",
- label: i18n2.str`Username`,
- tooltip: i18n2.str`Username to access the account information.`
- }
- ), /* @__PURE__ */ h(
- Input,
- {
- name: "credit_facade_credentials.password",
- inputType: "password",
- label: i18n2.str`Password`,
- tooltip: i18n2.str`Password to access the account information.`
- }
- ), /* @__PURE__ */ h(
- Input,
- {
- name: "credit_facade_credentials.repeatPassword",
- inputType: "password",
- label: i18n2.str`Repeat password`
- }
- )) : void 0
- ), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
- AsyncButton,
- {
- disabled: hasErrors,
- "data-tooltip": hasErrors ? i18n2.str`Need to complete marked fields` : "confirm operation",
- onClick: submitForm
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Confirm")
- )))))));
-}
-function isValidURL2(s5) {
- try {
- const u4 = new URL("/", s5);
- return true;
- } catch (e4) {
- return false;
- }
-}
-
-// src/paths/instance/accounts/update/index.tsx
function UpdateValidator({
bid,
onConfirm,
- onBack,
- onUnauthorized,
- onNotFound,
- onLoadError
+ onBack
}) {
- const { updateBankAccount } = useBankAccountAPI();
+ const { lib: api } = useMerchantApiContext();
+ const { state } = useSessionContext();
const result = useBankAccountDetails(bid);
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UpdatePage,
{
- account: { ...result.data, id: bid },
+ account: { ...result.body, id: bid },
onBack,
- onUpdate: (data) => {
- return updateBankAccount(bid, data).then(onConfirm).catch((error2) => {
+ onUpdate: async (request) => {
+ const revenueAPI = !request.credit_facade_url ? void 0 : new URL("./", request.credit_facade_url);
+ if (revenueAPI) {
+ const resp = await testRevenueAPI(
+ revenueAPI,
+ request.credit_facade_credentials
+ );
+ if (resp.type === "fail") {
+ switch (resp.case) {
+ case 0 /* NO_CONFIG */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`The endpoint doesn't seems to be a Taler Revenue API`
+ });
+ return;
+ }
+ case 1 /* CLIENT_BAD_REQUEST */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Server replied with "bad request".`
+ });
+ return;
+ }
+ case 2 /* UNAUTHORIZED */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Unauthorized, try with another credentials.`
+ });
+ return;
+ }
+ case 3 /* NOT_FOUND */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: i18n2.str`Check facade URL, server replied with "not found".`
+ });
+ return;
+ }
+ case 4 /* GENERIC_ERROR */: {
+ setNotif({
+ message: i18n2.str`Could not create account`,
+ type: "ERROR",
+ description: resp.detail.hint
+ });
+ return;
+ }
+ default: {
+ assertUnreachable(resp.case);
+ }
+ }
+ }
+ }
+ return api.instance.updateBankAccount(state.token, bid, request).then(onConfirm).catch((error2) => {
setNotif({
message: i18n2.str`could not update account`,
type: "ERROR",
@@ -40188,22 +43467,40 @@ function EmptyTable3() {
}
// src/paths/instance/kyc/list/index.tsx
-function ListKYC({
- onUnauthorized,
- onLoadError,
- onNotFound
-}) {
+function ListKYC(_p) {
const result = useInstanceKYCDetails();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
- }
- const status = result.data.type === "ok" ? void 0 : result.data.status;
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.GatewayTimeout: {
+ return /* @__PURE__ */ h("div", null);
+ }
+ case HttpStatusCode.BadGateway: {
+ const status2 = result.body;
+ if (!status2) {
+ return /* @__PURE__ */ h("div", null, "no kyc required");
+ }
+ return /* @__PURE__ */ h(ListPage2, { status: status2 });
+ }
+ case HttpStatusCode.ServiceUnavailable: {
+ return /* @__PURE__ */ h("div", null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h("div", null);
+ }
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h("div", null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
+ }
+ const status = result.body;
if (!status) {
return /* @__PURE__ */ h("div", null, "no kyc required");
}
@@ -40214,260 +43511,146 @@ function ListKYC({
init_preact_module();
init_hooks_module();
-// src/hooks/order.ts
+// src/hooks/product.ts
init_hooks_module();
+
+// src/hooks/webhooks.ts
var useSWR4 = useSWR;
-function useOrderAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const createOrder = async (data) => {
- const res = await request(
- `/private/orders`,
- {
- method: "POST",
- data
- }
- );
- await mutateAll(/.*private\/orders.*/);
- return res;
- };
- const refundOrder = async (orderId, data) => {
- mutateAll(/@"\/private\/orders"@/);
- const res = request(
- `/private/orders/${orderId}/refund`,
- {
- method: "POST",
- data
- }
- );
- await mutateAll(/.*private\/orders.*/);
- return res;
- };
- const forgetOrder = async (orderId, data) => {
- mutateAll(/@"\/private\/orders"@/);
- const res = request(`/private/orders/${orderId}/forget`, {
- method: "PATCH",
- data
- });
- await mutateAll(/.*private\/orders.*/);
- return res;
- };
- const deleteOrder = async (orderId) => {
- mutateAll(/@"\/private\/orders"@/);
- const res = request(`/private/orders/${orderId}`, {
- method: "DELETE"
- });
- await mutateAll(/.*private\/orders.*/);
- return res;
- };
- const getPaymentURL = async (orderId) => {
- return request(
- `/private/orders/${orderId}`,
- {
- method: "GET"
- }
- ).then((res) => {
- const url = res.data.order_status === "unpaid" ? res.data.taler_pay_uri : res.data.contract_terms.fulfillment_url;
- const response = res;
- response.data = url || "";
- return response;
- });
- };
- return { createOrder, forgetOrder, deleteOrder, refundOrder, getPaymentURL };
+function revalidateInstanceWebhooks() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listWebhooks",
+ void 0,
+ { revalidate: true }
+ );
}
-function useOrderDetails(oderId) {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR4([`/private/orders/${oderId}`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data)
- return data;
+function useInstanceWebhooks() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, bid]) {
+ return await instance.listWebhooks(token, {
+ // limit: PAGINATED_LIST_REQUEST,
+ // offset: bid,
+ // order: "dec",
+ });
+ }
+ const { data, error: error2 } = useSWR4([session.token, "offset", "listWebhooks"], fetcher);
if (error2)
- return error2.cause;
- return { loading: true };
-}
-function useInstanceOrders(args, updateFilter) {
- const { orderFetcher } = useBackendInstanceRequest();
- const [pageBefore, setPageBefore] = p3(1);
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const totalBefore = args?.date ? pageBefore * PAGE_SIZE : 0;
- const {
- data: beforeData,
- error: beforeError,
- isValidating: loadingBefore
- } = useSWR4(
- [
- `/private/orders`,
- args?.paid,
- args?.refunded,
- args?.wired,
- args?.date,
- totalBefore
- ],
- orderFetcher
- );
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR4(
- [
- `/private/orders`,
- args?.paid,
- args?.refunded,
- args?.wired,
- args?.date,
- -totalAfter
- ],
- orderFetcher
- );
- const [lastBefore, setLastBefore] = p3({ loading: true });
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- if (beforeData)
- setLastBefore(beforeData);
- }, [afterData, beforeData]);
- if (beforeError)
- return beforeError.cause;
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.orders.length < totalAfter;
- const isReachingStart = args?.date === void 0 || beforeData && beforeData.data.orders.length < totalBefore;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return data;
+}
+function buildPaginatedResult(data, offset, setOffset, getId) {
+ const isLastPage = data.length < PAGINATED_LIST_REQUEST;
+ const isFirstPage = offset === void 0;
+ const result = structuredClone(data);
+ if (result.length == PAGINATED_LIST_REQUEST) {
+ result.pop();
+ }
+ return {
+ type: "ok",
+ body: result,
+ isLastPage,
+ isFirstPage,
+ loadNext: () => {
+ if (!result.length)
return;
- if (afterData.data.orders.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = afterData.data.orders[afterData.data.orders.length - 1].timestamp.t_s;
- if (from && from !== "never" && updateFilter)
- updateFilter(new Date(from * 1e3));
- }
+ const id = getId(result[result.length - 1]);
+ setOffset(id);
},
- loadMorePrev: () => {
- if (!beforeData || isReachingStart)
- return;
- if (beforeData.data.orders.length < MAX_RESULT_SIZE) {
- setPageBefore(pageBefore + 1);
- } else if (beforeData) {
- const from = beforeData.data.orders[beforeData.data.orders.length - 1].timestamp.t_s;
- if (from && from !== "never" && updateFilter)
- updateFilter(new Date(from * 1e3));
- }
+ loadFirst: () => {
+ setOffset(void 0);
}
};
- const orders = !beforeData || !afterData ? [] : (beforeData || lastBefore).data.orders.slice().reverse().concat((afterData || lastAfter).data.orders);
- if (loadingAfter || loadingBefore)
- return { loading: true, data: { orders } };
- if (beforeData && afterData) {
- return { ok: true, data: { orders }, ...pagination };
+}
+function revalidateWebhookDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getWebhookDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useWebhookDetails(webhookId) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([hookId, token]) {
+ return await instance.getWebhookDetails(token, hookId);
}
- return { loading: true };
+ const { data, error: error2 } = useSWR4([webhookId, session.token, "getWebhookDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
}
// src/hooks/product.ts
var useSWR5 = useSWR;
-function useProductAPI() {
- const mutateAll = useMatchMutate();
- const { mutate: mutate2 } = useSWRConfig();
- const { request } = useBackendInstanceRequest();
- const createProduct = async (data) => {
- const res = await request(`/private/products`, {
- method: "POST",
- data
- });
- return await mutateAll(/.*\/private\/products.*/);
- };
- const updateProduct = async (productId, data) => {
- const r3 = await request(`/private/products/${productId}`, {
- method: "PATCH",
- data
- });
- return await mutateAll(/.*\/private\/products.*/);
- };
- const deleteProduct = async (productId) => {
- await request(`/private/products/${productId}`, {
- method: "DELETE"
- });
- await mutate2([`/private/products`]);
- };
- const lockProduct = async (productId, data) => {
- await request(`/private/products/${productId}/lock`, {
- method: "POST",
- data
- });
- return await mutateAll(/.*"\/private\/products.*/);
- };
- const getProduct = async (productId) => {
- await request(`/private/products/${productId}`, {
- method: "GET"
- });
- return;
- };
- return { createProduct, updateProduct, deleteProduct, lockProduct, getProduct };
+function notUndefined(c4) {
+ return c4 !== void 0;
+}
+function revalidateInstanceProducts() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listProductsWithId",
+ void 0,
+ { revalidate: true }
+ );
}
function useInstanceProducts() {
- const { fetcher, multiFetcher } = useBackendInstanceRequest();
- const { data: list, error: listError } = useSWR5([`/private/products`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- const paths = (list?.data.products || []).map(
- (p4) => `/private/products/${p4.product_id}`
- );
- const { data: products, error: productError } = useSWR5([paths], multiFetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (listError)
- return listError.cause;
- if (productError)
- return productError.cause;
- if (products) {
- const dataWithId = products.map((d5) => {
- return {
- ...d5.data,
- id: d5.info?.url.replace(/.*\/private\/products\//, "") || ""
- };
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ const [offset, setOffset] = p3();
+ async function fetcher([token, bid]) {
+ const list = await instance.listProducts(token, {
+ limit: PAGINATED_LIST_REQUEST,
+ offset: bid === void 0 ? void 0 : String(bid),
+ order: "dec"
});
- return { ok: true, data: dataWithId };
+ if (list.type !== "ok") {
+ return list;
+ }
+ const all = await Promise.all(
+ list.body.products.map(async (c4) => {
+ const r3 = await instance.getProductDetails(token, c4.product_id);
+ if (r3.type === "fail") {
+ return void 0;
+ }
+ return { ...r3.body, id: c4.product_id, serial: c4.product_serial };
+ })
+ );
+ const products = all.filter(notUndefined);
+ return opFixedSuccess({ products });
}
- return { loading: true };
+ const { data, error: error2 } = useSWR5([session.token, offset, "listProductsWithId"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return buildPaginatedResult(data.body.products, offset, setOffset, (d5) => d5.serial);
+}
+function revalidateProductDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getProductDetails",
+ void 0,
+ { revalidate: true }
+ );
}
function useProductDetails(productId) {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR5([`/private/products/${productId}`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([pid, token]) {
+ return await instance.getProductDetails(token, pid);
+ }
+ const { data, error: error2 } = useSWR5([productId, session.token, "getProductDetails"], fetcher);
if (data)
return data;
if (error2)
- return error2.cause;
- return { loading: true };
+ return error2;
+ return void 0;
}
// src/paths/instance/orders/create/CreatePage.tsx
@@ -40488,7 +43671,7 @@ function InputCurrency({
children,
side
}) {
- const config = useConfigContext();
+ const { config } = useMerchantApiContext();
return /* @__PURE__ */ h(
InputWithAddon,
{
@@ -40540,7 +43723,6 @@ var DatePicker = class extends d {
*/
getDaysByMonth(month, year) {
const calendar = [];
- const date2 = new Date(year, month, 1);
const firstDay = new Date(year, month, 1).getDay();
const lastDate = new Date(year, month + 1, 0).getDate();
let day = 0;
@@ -40767,7 +43949,7 @@ function InputDate({
}) {
const [opened, setOpened] = p3(false);
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
+ const [settings] = usePreference();
const { error: error2, required, value, onChange } = useField(name);
let strValue = "";
if (!value) {
@@ -43481,10 +46663,10 @@ function NonInventoryProductFrom({
}
)));
}
-function ProductForm({ onSubscribe, initial: initial2 }) {
+function ProductForm({ onSubscribe, initial: initial3 }) {
const [value, valueHandler] = p3({
taxes: [],
- ...initial2
+ ...initial3
});
let errors2 = {};
try {
@@ -43570,7 +46752,7 @@ function ProductList({ list, actions = [] }) {
const totalPrice = !entry.price ? "0" : Amounts.stringify(
Amounts.mult(
Amounts.parseOrThrow(entry.price),
- entry.quantity
+ entry.quantity ?? 0
).amount
);
return /* @__PURE__ */ h("tr", { key: index }, /* @__PURE__ */ h("td", null, /* @__PURE__ */ h(
@@ -43627,9 +46809,13 @@ function toFloat(amount) {
}
// src/paths/instance/orders/create/CreatePage.tsx
-function with_defaults2(config, currency) {
- const defaultPayDeadline = Duration.fromTalerProtocolDuration(config.default_pay_delay);
- const defaultWireDeadline = Duration.fromTalerProtocolDuration(config.default_wire_transfer_delay);
+function with_defaults2(config, _currency) {
+ const defaultPayDeadline = Duration.fromTalerProtocolDuration(
+ config.default_pay_delay
+ );
+ const defaultWireDeadline = Duration.fromTalerProtocolDuration(
+ config.default_wire_transfer_delay
+ );
return {
inventoryProducts: {},
products: [],
@@ -43651,11 +46837,11 @@ function CreatePage3({
instanceConfig,
instanceInventory
}) {
- const config = useConfigContext();
+ const { config } = useMerchantApiContext();
const instance_default = with_defaults2(instanceConfig, config.currency);
const [value, valueHandler] = p3(instance_default);
const zero = Amounts.zeroOfCurrency(config.currency);
- const [settings, updateSettings] = useSettings();
+ const [settings, updateSettings] = usePreference();
const inventoryList = Object.values(value.inventoryProducts || {});
const productList = Object.values(value.products || {});
const { i18n: i18n2 } = useTranslationContext();
@@ -43666,7 +46852,10 @@ function CreatePage3({
order_price: !value.pricing?.order_price ? i18n2.str`required` : !parsedPrice ? i18n2.str`not valid` : Amounts.isZero(parsedPrice) ? i18n2.str`must be greater than 0` : void 0
}),
payments: undefinedIfEmpty({
- refund_deadline: !value.payments?.refund_deadline ? void 0 : value.payments.pay_deadline && Duration.cmp(value.payments.refund_deadline, value.payments.pay_deadline) === -1 ? i18n2.str`refund deadline cannot be before pay deadline` : value.payments.wire_transfer_deadline && Duration.cmp(
+ refund_deadline: !value.payments?.refund_deadline ? void 0 : value.payments.pay_deadline && Duration.cmp(
+ value.payments.refund_deadline,
+ value.payments.pay_deadline
+ ) === -1 ? i18n2.str`refund deadline cannot be before pay deadline` : value.payments.wire_transfer_deadline && Duration.cmp(
value.payments.wire_transfer_deadline,
value.payments.refund_deadline
) === -1 ? i18n2.str`wire transfer deadline cannot be before refund deadline` : void 0,
@@ -43699,11 +46888,27 @@ function CreatePage3({
summary: order.pricing.summary,
products: productList,
extra: undefinedIfEmpty(value.extra),
- pay_deadline: !value.payments.pay_deadline ? i18n2.str`required` : AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), value.payments.pay_deadline)),
- // : undefined,
- wire_transfer_deadline: value.payments.wire_transfer_deadline ? AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), value.payments.wire_transfer_deadline)) : void 0,
- refund_deadline: value.payments.refund_deadline ? AbsoluteTime.toProtocolTimestamp(AbsoluteTime.addDuration(AbsoluteTime.now(), value.payments.refund_deadline)) : void 0,
- auto_refund: value.payments.auto_refund_deadline ? Duration.toTalerProtocolDuration(value.payments.auto_refund_deadline) : void 0,
+ pay_deadline: AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ value.payments.pay_deadline
+ )
+ ),
+ wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ value.payments.wire_transfer_deadline
+ )
+ ),
+ refund_deadline: AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ value.payments.refund_deadline
+ )
+ ),
+ auto_refund: value.payments.auto_refund_deadline ? Duration.toTalerProtocolDuration(
+ value.payments.auto_refund_deadline
+ ) : void 0,
max_fee: value.payments.max_fee,
delivery_date: value.shipping.delivery_date ? { t_s: value.shipping.delivery_date.getTime() / 1e3 } : void 0,
delivery_location: value.shipping.delivery_location,
@@ -43754,7 +46959,7 @@ function CreatePage3({
if (!cur.price)
return zero;
const p4 = Amounts.parseOrThrow(cur.price);
- return Amounts.add(prev, Amounts.mult(p4, cur.quantity).amount).amount;
+ return Amounts.add(prev, Amounts.mult(p4, cur.quantity ?? 0).amount).amount;
}, zero);
const hasProducts = inventoryList.length > 0 || productList.length > 0;
const totalPrice = Amounts.add(totalPriceInventory, totalPriceProducts);
@@ -43777,24 +46982,32 @@ function CreatePage3({
parsedPrice ?? Amounts.zeroOfCurrency(config.currency),
totalPrice.amount
);
- const minAgeByProducts = allProducts.reduce(
- (cur, prev) => !prev.minimum_age || cur > prev.minimum_age ? cur : prev.minimum_age,
+ const minAgeByProducts = inventoryList.reduce(
+ (cur, prev) => !prev.product.minimum_age || cur > prev.product.minimum_age ? cur : prev.product.minimum_age,
0
);
const noDefault_payDeadline = !instance_default.payments || !instance_default.payments.pay_deadline;
const noDefault_wireDeadline = !instance_default.payments || !instance_default.payments.wire_transfer_deadline;
const requiresSomeTalerOptions = noDefault_payDeadline || noDefault_wireDeadline;
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "tabs is-toggle is-fullwidth is-small" }, /* @__PURE__ */ h("ul", null, /* @__PURE__ */ h("li", { class: !settings.advanceOrderMode ? "is-active" : "", onClick: () => {
- updateSettings({
- ...settings,
- advanceOrderMode: false
- });
- } }, /* @__PURE__ */ h("a", null, /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "Simple")))), /* @__PURE__ */ h("li", { class: settings.advanceOrderMode ? "is-active" : "", onClick: () => {
- updateSettings({
- ...settings,
- advanceOrderMode: true
- });
- } }, /* @__PURE__ */ h("a", null, /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "Advanced")))))), /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "tabs is-toggle is-fullwidth is-small" }, /* @__PURE__ */ h("ul", null, /* @__PURE__ */ h(
+ "li",
+ {
+ class: !settings.advanceOrderMode ? "is-active" : "",
+ onClick: () => {
+ updateSettings("advanceOrderMode", false);
+ }
+ },
+ /* @__PURE__ */ h("a", null, /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "Simple")))
+ ), /* @__PURE__ */ h(
+ "li",
+ {
+ class: settings.advanceOrderMode ? "is-active" : "",
+ onClick: () => {
+ updateSettings("advanceOrderMode", true);
+ }
+ },
+ /* @__PURE__ */ h("a", null, /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "Advanced")))
+ ))), /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
InputGroup,
{
name: "inventory_products",
@@ -43931,16 +47144,23 @@ function CreatePage3({
withForever: true,
withoutClear: true,
tooltip: i18n2.str`Time for the customer to pay for the offer before it expires. Inventory products will be reserved until this deadline. Time start to run after the order is created.`,
- side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h("button", { class: "button", onClick: () => {
- const c4 = {
- ...value,
- payments: {
- ...value.payments ?? {},
- pay_deadline: instance_default.payments?.pay_deadline
+ side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: () => {
+ const c4 = {
+ ...value,
+ payments: {
+ ...value.payments ?? {},
+ pay_deadline: instance_default.payments?.pay_deadline
+ }
+ };
+ valueHandler(c4);
}
- };
- valueHandler(c4);
- } }, /* @__PURE__ */ h(i18n2.Translate, null, "default")))
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "default")
+ ))
}
),
settings.advanceOrderMode && /* @__PURE__ */ h(
@@ -43948,19 +47168,31 @@ function CreatePage3({
{
name: "payments.refund_deadline",
label: i18n2.str`Refund time`,
- help: /* @__PURE__ */ h(DeadlineHelp, { duration: value.payments?.refund_deadline }),
+ help: /* @__PURE__ */ h(
+ DeadlineHelp,
+ {
+ duration: value.payments?.refund_deadline
+ }
+ ),
withForever: true,
withoutClear: true,
tooltip: i18n2.str`Time while the order can be refunded by the merchant. Time starts after the order is created.`,
- side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h("button", { class: "button", onClick: () => {
- valueHandler({
- ...value,
- payments: {
- ...value.payments ?? {},
- refund_deadline: instance_default.payments?.refund_deadline
+ side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: () => {
+ valueHandler({
+ ...value,
+ payments: {
+ ...value.payments ?? {},
+ refund_deadline: instance_default.payments?.refund_deadline
+ }
+ });
}
- });
- } }, /* @__PURE__ */ h(i18n2.Translate, null, "default")))
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "default")
+ ))
}
),
(settings.advanceOrderMode || noDefault_wireDeadline) && /* @__PURE__ */ h(
@@ -43968,19 +47200,31 @@ function CreatePage3({
{
name: "payments.wire_transfer_deadline",
label: i18n2.str`Wire transfer time`,
- help: /* @__PURE__ */ h(DeadlineHelp, { duration: value.payments?.wire_transfer_deadline }),
+ help: /* @__PURE__ */ h(
+ DeadlineHelp,
+ {
+ duration: value.payments?.wire_transfer_deadline
+ }
+ ),
withoutClear: true,
withForever: true,
tooltip: i18n2.str`Time for the exchange to make the wire transfer. Time starts after the order is created.`,
- side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h("button", { class: "button", onClick: () => {
- valueHandler({
- ...value,
- payments: {
- ...value.payments ?? {},
- wire_transfer_deadline: instance_default.payments?.wire_transfer_deadline
+ side: /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: () => {
+ valueHandler({
+ ...value,
+ payments: {
+ ...value.payments ?? {},
+ wire_transfer_deadline: instance_default.payments?.wire_transfer_deadline
+ }
+ });
}
- });
- } }, /* @__PURE__ */ h(i18n2.Translate, null, "default")))
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "default")
+ ))
}
),
settings.advanceOrderMode && /* @__PURE__ */ h(
@@ -43988,7 +47232,12 @@ function CreatePage3({
{
name: "payments.auto_refund_deadline",
label: i18n2.str`Auto-refund time`,
- help: /* @__PURE__ */ h(DeadlineHelp, { duration: value.payments?.auto_refund_deadline }),
+ help: /* @__PURE__ */ h(
+ DeadlineHelp,
+ {
+ duration: value.payments?.auto_refund_deadline
+ }
+ ),
tooltip: i18n2.str`Time until which the wallet will automatically check for refunds without user interaction.`,
withForever: true
}
@@ -44026,36 +47275,67 @@ function CreatePage3({
label: i18n2.str`Additional information`,
tooltip: i18n2.str`Custom information to be included in the contract for this order.`
},
- Object.keys(value.extra ?? {}).map((key) => {
+ Object.keys(value.extra ?? {}).map((key, idx) => {
return /* @__PURE__ */ h(
Input,
{
name: `extra.${key}`,
+ key: String(idx),
inputType: "multiline",
label: key,
tooltip: i18n2.str`You must enter a value in JavaScript Object Notation (JSON).`,
- side: /* @__PURE__ */ h("button", { class: "button", onClick: (e4) => {
- if (value.extra && value.extra[key] !== void 0) {
- console.log(value.extra);
- delete value.extra[key];
- }
- valueHandler({
- ...value
- });
- } }, "remove")
+ side: /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: (e4) => {
+ if (value.extra && value.extra[key] !== void 0) {
+ console.log(value.extra);
+ delete value.extra[key];
+ }
+ valueHandler({
+ ...value
+ });
+ e4.preventDefault();
+ }
+ },
+ "remove"
+ )
}
);
}),
- /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Custom field name"), /* @__PURE__ */ h("span", { class: "icon has-tooltip-right", "data-tooltip": "new extra field" }, /* @__PURE__ */ h("i", { class: "mdi mdi-information" })))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h("input", { class: "input ", value: newField, onChange: (e4) => setNewField(e4.currentTarget.value) })))), /* @__PURE__ */ h("button", { class: "button", onClick: (e4) => {
- setNewField("");
- valueHandler({
- ...value,
- extra: {
- ...value.extra ?? {},
- [newField]: ""
+ /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Custom field name"), /* @__PURE__ */ h(
+ "span",
+ {
+ class: "icon has-tooltip-right",
+ "data-tooltip": "new extra field"
+ },
+ /* @__PURE__ */ h("i", { class: "mdi mdi-information" })
+ ))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h(
+ "input",
+ {
+ class: "input ",
+ value: newField,
+ onChange: (e4) => setNewField(e4.currentTarget.value)
+ }
+ )))), /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: (e4) => {
+ setNewField("");
+ valueHandler({
+ ...value,
+ extra: {
+ ...value.extra ?? {},
+ [newField]: ""
+ }
+ });
+ e4.preventDefault();
}
- });
- } }, "add"))
+ },
+ "add"
+ ))
)
), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
"button",
@@ -44075,8 +47355,7 @@ function asProduct(p4) {
unit: p4.product.unit,
quantity: p4.quantity,
description: p4.product.description,
- taxes: p4.product.taxes,
- minimum_age: p4.product.minimum_age
+ taxes: p4.product.taxes
};
}
function DeadlineHelp({ duration }) {
@@ -44101,40 +47380,63 @@ function DeadlineHelp({ duration }) {
// src/paths/instance/orders/create/index.tsx
function OrderCreate({
onConfirm,
- onBack,
- onLoadError,
- onNotFound,
- onUnauthorized
+ onBack
}) {
- const { createOrder } = useOrderAPI();
+ const { lib } = useMerchantApiContext();
const [notif, setNotif] = p3(void 0);
+ const { state } = useSessionContext();
const detailsResult = useInstanceDetails();
const inventoryResult = useInstanceProducts();
- if (detailsResult.loading)
+ if (!detailsResult)
return /* @__PURE__ */ h(Loading, null);
- if (inventoryResult.loading)
+ if (detailsResult instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: detailsResult });
+ }
+ if (detailsResult.type === "fail") {
+ switch (detailsResult.case) {
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ default: {
+ assertUnreachable(detailsResult);
+ }
+ }
+ }
+ if (!inventoryResult)
return /* @__PURE__ */ h(Loading, null);
- if (!detailsResult.ok) {
- if (detailsResult.type === ErrorType.CLIENT && detailsResult.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (detailsResult.type === ErrorType.CLIENT && detailsResult.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(detailsResult);
- }
- if (!inventoryResult.ok) {
- if (inventoryResult.type === ErrorType.CLIENT && inventoryResult.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (inventoryResult.type === ErrorType.CLIENT && inventoryResult.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(inventoryResult);
+ if (inventoryResult instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: inventoryResult });
+ }
+ if (inventoryResult.type === "fail") {
+ switch (inventoryResult.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(inventoryResult);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
CreatePage3,
{
onBack,
onCreate: (request) => {
- createOrder(request).then((r3) => {
- return onConfirm(r3.data.order_id);
+ lib.instance.createOrder(state.token, request).then((r3) => {
+ if (r3.type === "ok") {
+ return onConfirm(r3.body.order_id);
+ } else {
+ setNotif({
+ message: "could not create order",
+ type: "ERROR"
+ });
+ }
}).catch((error2) => {
setNotif({
message: "could not create order",
@@ -44143,8 +47445,8 @@ function OrderCreate({
});
});
},
- instanceConfig: detailsResult.data,
- instanceInventory: inventoryResult.data
+ instanceConfig: detailsResult.body,
+ instanceInventory: inventoryResult.body
}
));
}
@@ -44153,6 +47455,60 @@ function OrderCreate({
init_preact_module();
init_hooks_module();
+// src/hooks/order.ts
+var useSWR6 = useSWR;
+function revalidateOrderDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getOrderDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useOrderDetails(oderId) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([dId, token]) {
+ return await instance.getOrderDetails(token, dId);
+ }
+ const { data, error: error2 } = useSWR6([oderId, session.token, "getOrderDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+function revalidateInstanceOrders() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listOrders",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useInstanceOrders(args, updatePosition = () => {
+}) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, o3, p4, r3, w5, d5]) {
+ return await instance.listOrders(token, {
+ limit: PAGINATED_LIST_REQUEST,
+ offset: o3,
+ order: "dec",
+ paid: p4,
+ refunded: r3,
+ wired: w5,
+ date: d5
+ });
+ }
+ const { data, error: error2 } = useSWR6([session.token, args?.position, args?.paid, args?.refunded, args?.wired, args?.date, "listOrders"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return buildPaginatedResult(data.body.orders, args?.position, updatePosition, (d5) => String(d5.row_id));
+}
+
// src/paths/instance/orders/details/DetailPage.tsx
init_preact_module();
init_hooks_module();
@@ -44189,9 +47545,7 @@ function CardTable3({
onCopyURL,
onSelect,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -44205,9 +47559,7 @@ function CardTable3({
rowSelection,
rowSelectionHandler,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}
) : /* @__PURE__ */ h(EmptyTable4, null)))));
}
@@ -44217,20 +47569,11 @@ function Table3({
onRefund,
onCopyURL,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
- return /* @__PURE__ */ h("div", { class: "table-container" }, hasMoreBefore && /* @__PURE__ */ h(
- "button",
- {
- class: "button is-fullwidth",
- onClick: onLoadMoreBefore
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "load newer orders")
- ), /* @__PURE__ */ h("table", { class: "table is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", { style: { minWidth: 100 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Date")), /* @__PURE__ */ h("th", { style: { minWidth: 100 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Amount")), /* @__PURE__ */ h("th", { style: { minWidth: 400 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Summary")), /* @__PURE__ */ h("th", { style: { minWidth: 50 } }))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
+ const [settings] = usePreference();
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h("button", { class: "button is-fullwidth", onClick: onLoadMoreBefore }, /* @__PURE__ */ h(i18n2.Translate, null, "load first page")), /* @__PURE__ */ h("table", { class: "table is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", { style: { minWidth: 100 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Date")), /* @__PURE__ */ h("th", { style: { minWidth: 100 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Amount")), /* @__PURE__ */ h("th", { style: { minWidth: 400 } }, /* @__PURE__ */ h(i18n2.Translate, null, "Summary")), /* @__PURE__ */ h("th", { style: { minWidth: 50 } }))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
return /* @__PURE__ */ h("tr", { key: i4.id }, /* @__PURE__ */ h(
"td",
{
@@ -44272,18 +47615,19 @@ function Table3({
},
/* @__PURE__ */ h(i18n2.Translate, null, "copy url")
))));
- }))), hasMoreAfter && /* @__PURE__ */ h(
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
+ "data-tooltip": i18n2.str`load more orders after the last one`,
onClick: onLoadMoreAfter
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load older orders")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
));
}
function EmptyTable4() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "No orders have been found matching your query!")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "No orders have been found matching your query!")));
}
function RefundModal({
order,
@@ -44291,10 +47635,10 @@ function RefundModal({
onConfirm
}) {
const [form, setValue] = p3({});
- const [settings] = useSettings();
+ const [settings] = usePreference();
const { i18n: i18n2 } = useTranslationContext();
const refunds = (order.order_status === "paid" ? order.refund_details : []).reduce(mergeRefunds, []);
- const config = useConfigContext();
+ const { config } = useMerchantApiContext();
const totalRefunded = refunds.map((r3) => r3.amount).reduce(
(p4, c4) => Amounts.add(p4, Amounts.parseOrThrow(c4)).amount,
Amounts.zeroOfCurrency(config.currency)
@@ -44403,7 +47747,7 @@ function Timeline({ events: e4 }) {
type: "now"
});
events2.sort((a5, b4) => a5.when.getTime() - b4.when.getTime());
- const [settings] = useSettings();
+ const [settings] = usePreference();
const [state, setState] = p3(events2);
h2(() => {
const handle = setTimeout(() => {
@@ -44548,6 +47892,8 @@ function ClaimedPage({
id,
order
}) {
+ const now2 = /* @__PURE__ */ new Date();
+ const refundable = order.contract_terms.refund_deadline.t_s !== "never" && now2.getTime() < order.contract_terms.refund_deadline.t_s * 1e3;
const events2 = [];
if (order.contract_terms.timestamp.t_s !== "never") {
events2.push({
@@ -44563,20 +47909,13 @@ function ClaimedPage({
type: "deadline"
});
}
- if (order.contract_terms.refund_deadline.t_s !== "never") {
+ if (order.contract_terms.refund_deadline.t_s !== "never" && refundable) {
events2.push({
when: new Date(order.contract_terms.refund_deadline.t_s * 1e3),
description: "refund deadline",
type: "deadline"
});
}
- if (order.contract_terms.wire_transfer_deadline.t_s !== "never") {
- events2.push({
- when: new Date(order.contract_terms.wire_transfer_deadline.t_s * 1e3),
- description: "wire deadline",
- type: "deadline"
- });
- }
if (order.contract_terms.delivery_date && order.contract_terms.delivery_date.t_s !== "never") {
events2.push({
when: new Date(order.contract_terms.delivery_date?.t_s * 1e3),
@@ -44586,7 +47925,7 @@ function ClaimedPage({
}
const [value, valueHandler] = p3(order);
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
+ const [settings] = usePreference();
return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-10" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h(i18n2.Translate, null, "Order"), " #", id, /* @__PURE__ */ h("div", { class: "tag is-info ml-4" }, /* @__PURE__ */ h(i18n2.Translate, null, "claimed"))))), /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("h1", { class: "title" }, order.contract_terms.amount)))), /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left", style: { maxWidth: "100%" } }, /* @__PURE__ */ h("div", { class: "level-item", style: { maxWidth: "100%" } }, /* @__PURE__ */ h(
"div",
{
@@ -44597,8 +47936,10 @@ function ClaimedPage({
textOverflow: "ellipsis"
}
},
- /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("b", null, /* @__PURE__ */ h(i18n2.Translate, null, "claimed at"), ":"), " ", format(
- new Date(order.contract_terms.timestamp.t_s * 1e3),
+ /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("b", null, /* @__PURE__ */ h(i18n2.Translate, null, "claimed at"), ":"), " ", order.contract_terms.timestamp.t_s === "never" ? "never" : format(
+ new Date(
+ order.contract_terms.timestamp.t_s * 1e3
+ ),
datetimeFormatForSettings(settings)
))
)))))), /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-4" }, /* @__PURE__ */ h("div", { class: "title" }, /* @__PURE__ */ h(i18n2.Translate, null, "Timeline")), /* @__PURE__ */ h(Timeline, { events: events2 })), /* @__PURE__ */ h("div", { class: "column is-8" }, /* @__PURE__ */ h("div", { class: "title" }, /* @__PURE__ */ h(i18n2.Translate, null, "Payment details")), /* @__PURE__ */ h(
@@ -44639,22 +47980,10 @@ function PaidPage({
order,
onRefund
}) {
+ const now2 = /* @__PURE__ */ new Date();
+ const refundable = order.contract_terms.refund_deadline.t_s !== "never" && now2.getTime() < order.contract_terms.refund_deadline.t_s * 1e3;
const events2 = [];
- if (order.contract_terms.timestamp.t_s !== "never") {
- events2.push({
- when: new Date(order.contract_terms.timestamp.t_s * 1e3),
- description: "order created",
- type: "start"
- });
- }
- if (order.contract_terms.pay_deadline.t_s !== "never") {
- events2.push({
- when: new Date(order.contract_terms.pay_deadline.t_s * 1e3),
- description: "pay deadline",
- type: "deadline"
- });
- }
- if (order.contract_terms.refund_deadline.t_s !== "never") {
+ if (order.contract_terms.refund_deadline.t_s !== "never" && refundable) {
events2.push({
when: new Date(order.contract_terms.refund_deadline.t_s * 1e3),
description: "refund deadline",
@@ -44685,59 +48014,61 @@ function PaidPage({
});
}
});
- if (order.wire_details && order.wire_details.length) {
- if (order.wire_details.length > 1) {
- let last = null;
- let first = null;
- let total = null;
- order.wire_details.forEach((w5) => {
- if (last === null || last.execution_time.t_s < w5.execution_time.t_s) {
- last = w5;
- }
- if (first === null || first.execution_time.t_s > w5.execution_time.t_s) {
- first = w5;
- }
- total = total === null ? Amounts.parseOrThrow(w5.amount) : Amounts.add(total, Amounts.parseOrThrow(w5.amount)).amount;
- });
- const last_time = last.execution_time.t_s;
- if (last_time !== "never") {
- events2.push({
- when: new Date(last_time * 1e3),
- description: `wired ${Amounts.stringify(total)}`,
- type: "wired-range"
- });
- }
- const first_time = first.execution_time.t_s;
- if (first_time !== "never") {
- events2.push({
- when: new Date(first_time * 1e3),
- description: `wire transfer started...`,
- type: "wired-range"
+ const ra = !order.refunded ? void 0 : Amounts.parse(order.refund_amount);
+ const am = Amounts.parseOrThrow(order.contract_terms.amount);
+ if (ra && Amounts.cmp(ra, am) === 1) {
+ if (order.wire_details && order.wire_details.length) {
+ if (order.wire_details.length > 1) {
+ let last = null;
+ let first = null;
+ let total = null;
+ order.wire_details.forEach((w5) => {
+ if (last === null || last.execution_time.t_s < w5.execution_time.t_s) {
+ last = w5;
+ }
+ if (first === null || first.execution_time.t_s > w5.execution_time.t_s) {
+ first = w5;
+ }
+ total = total === null ? Amounts.parseOrThrow(w5.amount) : Amounts.add(total, Amounts.parseOrThrow(w5.amount)).amount;
});
- }
- } else {
- order.wire_details.forEach((e4) => {
- if (e4.execution_time.t_s !== "never") {
+ const last_time = last.execution_time.t_s;
+ if (last_time !== "never") {
events2.push({
- when: new Date(e4.execution_time.t_s * 1e3),
- description: `wired ${e4.amount}`,
- type: "wired"
+ when: new Date(last_time * 1e3),
+ description: `wired ${Amounts.stringify(total)}`,
+ type: "wired-range"
});
}
- });
+ const first_time = first.execution_time.t_s;
+ if (first_time !== "never") {
+ events2.push({
+ when: new Date(first_time * 1e3),
+ description: `wire transfer started...`,
+ type: "wired-range"
+ });
+ }
+ } else {
+ order.wire_details.forEach((e4) => {
+ if (e4.execution_time.t_s !== "never") {
+ events2.push({
+ when: new Date(e4.execution_time.t_s * 1e3),
+ description: `wired ${e4.amount}`,
+ type: "wired"
+ });
+ }
+ });
+ }
}
}
- const now2 = /* @__PURE__ */ new Date();
const nextEvent = events2.find((e4) => {
return e4.when.getTime() > now2.getTime();
});
const [value, valueHandler] = p3(order);
- const { url: backendURL } = useBackendContext();
+ const { url: backendUrl } = useMerchantApiContext();
const refundurl = stringifyRefundUri({
- merchantBaseUrl: backendURL,
+ merchantBaseUrl: backendUrl.href,
orderId: order.contract_terms.order_id
});
- const refundable = (/* @__PURE__ */ new Date()).getTime() < order.contract_terms.refund_deadline.t_s * 1e3;
const { i18n: i18n2 } = useTranslationContext();
const amount = Amounts.parseOrThrow(order.contract_terms.amount);
const refund_taken = order.refund_details.reduce((prev, cur) => {
@@ -44838,7 +48169,7 @@ function UnpaidPage({
}) {
const [value, valueHandler] = p3(order);
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
+ const [settings] = usePreference();
return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("h1", { class: "title" }, /* @__PURE__ */ h(i18n2.Translate, null, "Order"), " #", id)), /* @__PURE__ */ h("div", { class: "tag is-dark" }, /* @__PURE__ */ h(i18n2.Translate, null, "unpaid")))), /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left", style: { maxWidth: "100%" } }, /* @__PURE__ */ h("div", { class: "level-item", style: { maxWidth: "100%" } }, /* @__PURE__ */ h(
"div",
{
@@ -44930,44 +48261,59 @@ function DetailPage({ id, selected, onRefund, onBack }) {
}
// src/paths/instance/orders/details/index.tsx
-function Update({
- oid,
- onBack,
- onLoadError,
- onNotFound,
- onUnauthorized
-}) {
- const { refundOrder } = useOrderAPI();
+function Update({ oid, onBack }) {
const result = useOrderDetails(oid);
const [notif, setNotif] = p3(void 0);
+ const { lib: api } = useMerchantApiContext();
+ const { state } = useSessionContext();
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.BadGateway: {
+ return /* @__PURE__ */ h("div", null, "Failed to obtain a response from the exchange");
+ }
+ case HttpStatusCode.GatewayTimeout: {
+ return /* @__PURE__ */ h("div", null, "The merchant's interaction with the exchange took too long");
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
DetailPage,
{
onBack,
id: oid,
- onRefund: (id, value) => refundOrder(id, value).then(
- () => setNotif({
- message: i18n2.str`refund created successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not create the refund`,
- type: "ERROR",
- description: error2.message
- })
- ),
- selected: result.data
+ onRefund: (id, value) => {
+ if (state.status !== "loggedIn") {
+ return;
+ }
+ api.instance.addRefund(state.token, id, value).then(
+ () => setNotif({
+ message: i18n2.str`refund created successfully`,
+ type: "SUCCESS"
+ })
+ ).catch(
+ (error2) => setNotif({
+ message: i18n2.str`could not create the refund`,
+ type: "ERROR",
+ description: error2.message
+ })
+ );
+ },
+ selected: result.body
}
));
}
@@ -44976,12 +48322,62 @@ function Update({
init_preact_module();
init_hooks_module();
+// src/components/form/JumpToElementById.tsx
+init_preact_module();
+init_hooks_module();
+function JumpToElementById({ testIfExist, onSelect, placeholder, description }) {
+ const { i18n: i18n2 } = useTranslationContext();
+ const [error2, setError] = p3(
+ void 0
+ );
+ const [id, setId] = p3();
+ async function check(currentId) {
+ if (!currentId) {
+ setError(i18n2.str`missing id`);
+ return;
+ }
+ try {
+ const exi = await testIfExist(currentId);
+ if (exi) {
+ onSelect(currentId);
+ setError(void 0);
+ } else {
+ setError(i18n2.str`not found`);
+ }
+ } catch {
+ setError(i18n2.str`not found`);
+ }
+ }
+ return /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("div", { class: "field has-addons" }, /* @__PURE__ */ h("div", { class: "control" }, /* @__PURE__ */ h(
+ "input",
+ {
+ class: error2 ? "input is-danger" : "input",
+ type: "text",
+ value: id ?? "",
+ onChange: (e4) => setId(e4.currentTarget.value),
+ placeholder
+ }
+ ), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2)), /* @__PURE__ */ h(
+ "span",
+ {
+ class: "has-tooltip-bottom",
+ "data-tooltip": description
+ },
+ /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: (e4) => check(id)
+ },
+ /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-arrow-right" }))
+ )
+ )))));
+}
+
// src/paths/instance/orders/list/ListPage.tsx
init_preact_module();
init_hooks_module();
function ListPage3({
- hasMoreAfter,
- hasMoreBefore,
onLoadMoreAfter,
onLoadMoreBefore,
orders,
@@ -45007,7 +48403,7 @@ function ListPage3({
const { i18n: i18n2 } = useTranslationContext();
const dateTooltip = i18n2.str`select date to show nearby orders`;
const [pickDate, setPickDate] = p3(false);
- const [settings] = useSettings();
+ const [settings] = usePreference();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-two-thirds" }, /* @__PURE__ */ h("div", { class: "tabs", style: { overflow: "inherit" } }, /* @__PURE__ */ h("ul", null, /* @__PURE__ */ h("li", { class: isNotPaidActive }, /* @__PURE__ */ h(
"div",
{
@@ -45063,7 +48459,7 @@ function ListPage3({
class: "input",
type: "text",
readonly: true,
- value: !jumpToDate ? "" : format(jumpToDate, dateFormatForSettings(settings)),
+ value: !jumpToDate || jumpToDate.t_ms === "never" ? "" : format(jumpToDate.t_ms, dateFormatForSettings(settings)),
placeholder: i18n2.str`date (${dateFormatForSettings(settings)})`,
onClick: () => {
setPickDate(true);
@@ -45083,7 +48479,9 @@ function ListPage3({
{
opened: pickDate,
closeFunction: () => setPickDate(false),
- dateReceiver: onSelectDate
+ dateReceiver: (d5) => {
+ onSelectDate(AbsoluteTime.fromMilliseconds(d5.getTime()));
+ }
}
), /* @__PURE__ */ h(
CardTable3,
@@ -45093,96 +48491,56 @@ function ListPage3({
onCopyURL,
onSelect: onSelectOrder,
onRefund: onRefundOrder,
- hasMoreAfter,
- hasMoreBefore,
onLoadMoreAfter,
onLoadMoreBefore
}
));
}
-// src/components/form/JumpToElementById.tsx
-init_preact_module();
-init_hooks_module();
-function JumpToElementById({ testIfExist, onSelect, placeholder, description }) {
- const { i18n: i18n2 } = useTranslationContext();
- const [error2, setError] = p3(
- void 0
- );
- const [id, setId] = p3();
- async function check(currentId) {
- if (!currentId) {
- setError(i18n2.str`missing id`);
- return;
- }
- try {
- await testIfExist(currentId);
- onSelect(currentId);
- setError(void 0);
- } catch {
- setError(i18n2.str`not found`);
- }
- }
- return /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("div", { class: "field has-addons" }, /* @__PURE__ */ h("div", { class: "control" }, /* @__PURE__ */ h(
- "input",
- {
- class: error2 ? "input is-danger" : "input",
- type: "text",
- value: id ?? "",
- onChange: (e4) => setId(e4.currentTarget.value),
- placeholder
- }
- ), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2)), /* @__PURE__ */ h(
- "span",
- {
- class: "has-tooltip-bottom",
- "data-tooltip": description
- },
- /* @__PURE__ */ h(
- "button",
- {
- class: "button",
- onClick: (e4) => check(id)
- },
- /* @__PURE__ */ h("span", { class: "icon" }, /* @__PURE__ */ h("i", { class: "mdi mdi-arrow-right" }))
- )
- )))));
-}
-
// src/paths/instance/orders/list/index.tsx
-function OrderList({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound
-}) {
- const [filter, setFilter] = p3({ paid: "no" });
+function OrderList({ onCreate, onSelect }) {
+ const [filter, setFilter] = p3({ paid: false });
const [orderToBeRefunded, setOrderToBeRefunded] = p3(void 0);
const setNewDate = (date2) => setFilter((prev) => ({ ...prev, date: date2 }));
- const result = useInstanceOrders(filter, setNewDate);
- const { refundOrder, getPaymentURL } = useOrderAPI();
+ const result = useInstanceOrders(
+ filter,
+ (d5) => setFilter({ ...filter, position: d5 })
+ );
+ const { lib } = useMerchantApiContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ const { state } = useSessionContext();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
- }
- const isNotPaidActive = filter.paid === "no" ? "is-active" : "";
- const isPaidActive = filter.paid === "yes" && filter.wired === void 0 ? "is-active" : "";
- const isRefundedActive = filter.refunded === "yes" ? "is-active" : "";
- const isNotWiredActive = filter.wired === "no" && filter.paid === "yes" ? "is-active" : "";
- const isWiredActive = filter.wired === "yes" ? "is-active" : "";
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
+ }
+ const isNotPaidActive = filter.paid === false ? "is-active" : "";
+ const isPaidActive = filter.paid === true && filter.wired === void 0 ? "is-active" : "";
+ const isRefundedActive = filter.refunded === true ? "is-active" : "";
+ const isNotWiredActive = filter.wired === false && filter.paid === true ? "is-active" : "";
+ const isWiredActive = filter.wired === true ? "is-active" : "";
const isAllActive = filter.paid === void 0 && filter.refunded === void 0 && filter.wired === void 0 ? "is-active" : "";
return /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
JumpToElementById,
{
- testIfExist: getPaymentURL,
+ testIfExist: async (order) => {
+ const resp = await lib.instance.getOrderDetails(state.token, order);
+ return resp.type === "ok";
+ },
onSelect,
description: i18n2.str`jump to order with the given product ID`,
placeholder: i18n2.str`order id`
@@ -45190,11 +48548,9 @@ function OrderList({
), /* @__PURE__ */ h(
ListPage3,
{
- orders: result.data.orders.map((o3) => ({ ...o3, id: o3.order_id })),
- onLoadMoreBefore: result.loadMorePrev,
- hasMoreBefore: !result.isReachingStart,
- onLoadMoreAfter: result.loadMore,
- hasMoreAfter: !result.isReachingEnd,
+ orders: result.body.map((o3) => ({ ...o3, id: o3.order_id })),
+ onLoadMoreBefore: result.isFirstPage ? void 0 : result.loadFirst,
+ onLoadMoreAfter: result.isLastPage ? void 0 : result.loadNext,
onSelectOrder: (order) => onSelect(order.id),
onRefundOrder: (value) => setOrderToBeRefunded(value),
isAllActive,
@@ -45204,77 +48560,80 @@ function OrderList({
isNotPaidActive,
isRefundedActive,
jumpToDate: filter.date,
- onCopyURL: (id) => getPaymentURL(id).then((resp) => copyToClipboard(resp.data)),
- onCreate,
onSelectDate: setNewDate,
+ onCopyURL: async (id) => {
+ const resp = await lib.instance.getOrderDetails(state.token, id);
+ if (resp.type === "ok") {
+ if (resp.body.order_status === "unpaid") {
+ copyToClipboard(resp.body.taler_pay_uri);
+ } else {
+ if (resp.body.contract_terms.fulfillment_url) {
+ copyToClipboard(resp.body.contract_terms.fulfillment_url);
+ }
+ }
+ copyToClipboard(resp.body.order_status);
+ }
+ },
+ onCreate,
onShowAll: () => setFilter({}),
- onShowNotPaid: () => setFilter({ paid: "no" }),
- onShowPaid: () => setFilter({ paid: "yes" }),
- onShowRefunded: () => setFilter({ refunded: "yes" }),
- onShowNotWired: () => setFilter({ wired: "no", paid: "yes" }),
- onShowWired: () => setFilter({ wired: "yes" })
+ onShowNotPaid: () => setFilter({ paid: false }),
+ onShowPaid: () => setFilter({ paid: true }),
+ onShowRefunded: () => setFilter({ refunded: true }),
+ onShowNotWired: () => setFilter({ wired: false, paid: true }),
+ onShowWired: () => setFilter({ wired: true })
}
), orderToBeRefunded && /* @__PURE__ */ h(
RefundModalForTable,
{
id: orderToBeRefunded.order_id,
onCancel: () => setOrderToBeRefunded(void 0),
- onConfirm: (value) => refundOrder(orderToBeRefunded.order_id, value).then(
- () => setNotif({
- message: i18n2.str`refund created successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not create the refund`,
- type: "ERROR",
- description: error2.message
- })
- ).then(() => setOrderToBeRefunded(void 0)),
- onLoadError: (error2) => {
- setNotif({
- message: i18n2.str`could not create the refund`,
- type: "ERROR",
- description: error2.message
- });
- setOrderToBeRefunded(void 0);
- return /* @__PURE__ */ h("div", null);
- },
- onUnauthorized,
- onNotFound: () => {
- setNotif({
- message: i18n2.str`could not get the order to refund`,
- type: "ERROR"
- // description: error.message
- });
- setOrderToBeRefunded(void 0);
- return /* @__PURE__ */ h("div", null);
+ onConfirm: (value) => {
+ lib.instance.addRefund(state.token, orderToBeRefunded.order_id, value).then(
+ () => setNotif({
+ message: i18n2.str`refund created successfully`,
+ type: "SUCCESS"
+ })
+ ).catch(
+ (error2) => setNotif({
+ message: i18n2.str`could not create the refund`,
+ type: "ERROR",
+ description: error2.message
+ })
+ ).then(() => setOrderToBeRefunded(void 0));
}
}
));
}
-function RefundModalForTable({
- id,
- onUnauthorized,
- onLoadError,
- onNotFound,
- onConfirm,
- onCancel
-}) {
+function RefundModalForTable({ id, onConfirm, onCancel }) {
const result = useOrderDetails(id);
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.BadGateway: {
+ return /* @__PURE__ */ h("div", null, "Failed to obtain a response from the exchange");
+ }
+ case HttpStatusCode.GatewayTimeout: {
+ return /* @__PURE__ */ h("div", null, "The merchant's interaction with the exchange took too long");
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(
RefundModal,
{
- order: result.data,
+ order: result.body,
onCancel,
onConfirm
}
@@ -45288,6 +48647,101 @@ async function copyToClipboard(text) {
init_preact_module();
init_hooks_module();
+// src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
+init_preact_module();
+
+// src/components/exception/QR.tsx
+init_preact_module();
+init_hooks_module();
+var import_qrcode_generator = __toESM(require_qrcode(), 1);
+function QR({ text }) {
+ const divRef = _2(null);
+ h2(() => {
+ const qr = (0, import_qrcode_generator.default)(0, "L");
+ qr.addData(text);
+ qr.make();
+ if (divRef.current) {
+ divRef.current.innerHTML = qr.createSvgTag({
+ scalable: true
+ });
+ }
+ });
+ return /* @__PURE__ */ h(
+ "div",
+ {
+ style: {
+ width: "100%",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center"
+ }
+ },
+ /* @__PURE__ */ h(
+ "div",
+ {
+ style: { width: "50%", minWidth: 200, maxWidth: 300 },
+ ref: divRef
+ }
+ )
+ );
+}
+
+// src/components/notifications/CreatedSuccessfully.tsx
+init_preact_module();
+function CreatedSuccessfully({
+ children,
+ onConfirm,
+ onCreateAnother
+}) {
+ return /* @__PURE__ */ h("div", { class: "columns is-fullwidth is-vcentered mt-3" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h("div", { class: "card" }, /* @__PURE__ */ h("header", { class: "card-header has-background-success" }, /* @__PURE__ */ h("p", { class: "card-header-title has-text-white-ter" }, "Success.")), /* @__PURE__ */ h("div", { class: "card-content" }, children)), /* @__PURE__ */ h("div", { class: "buttons is-right" }, onCreateAnother && /* @__PURE__ */ h("button", { class: "button is-info", onClick: onCreateAnother }, "Create another"), /* @__PURE__ */ h("button", { class: "button is-info", onClick: onConfirm }, "Continue"))), /* @__PURE__ */ h("div", { class: "column" }));
+}
+
+// src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
+function CreatedSuccessfully2({
+ entity,
+ onConfirm
+}) {
+ const { i18n: i18n2 } = useTranslationContext();
+ const { url: backendUrl } = useMerchantApiContext();
+ const { state } = useSessionContext();
+ const issuer = backendUrl.href;
+ const qrText = `otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`;
+ const qrTextSafe = `otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0, 6)}...`;
+ return /* @__PURE__ */ h(CreatedSuccessfully, { onConfirm }, /* @__PURE__ */ h("p", { class: "is-size-5" }, /* @__PURE__ */ h(i18n2.Translate, null, "You can scan the next QR code with your device or save the key before continuing.")), /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, "ID")), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h(
+ "input",
+ {
+ readonly: true,
+ class: "input",
+ value: entity.otp_device_id
+ }
+ ))))), /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Description"))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h(
+ "input",
+ {
+ class: "input",
+ readonly: true,
+ value: entity.otp_device_description
+ }
+ ))))), /* @__PURE__ */ h(
+ QR,
+ {
+ text: qrText
+ }
+ ), /* @__PURE__ */ h(
+ "div",
+ {
+ style: {
+ color: "grey",
+ fontSize: "small",
+ width: 200,
+ textAlign: "center",
+ margin: "auto",
+ wordBreak: "break-all"
+ }
+ },
+ qrTextSafe
+ ));
+}
+
// src/paths/instance/otp_devices/create/CreatePage.tsx
init_preact_module();
init_hooks_module();
@@ -45295,7 +48749,6 @@ var algorithms = [0, 1, 2];
var algorithmsNames = ["off", "30s 8d TOTP-SHA1", "30s 8d eTOTP-SHA1"];
function CreatePage4({ onCreate, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
- const backend = useBackendContext();
const [state, setState] = p3({});
const [showKey, setShowKey] = p3(false);
const errors2 = {
@@ -45346,7 +48799,7 @@ function CreatePage4({ onCreate, onBack }) {
fromStr: (v3) => Number(v3)
}
),
- state.otp_algorithm && state.otp_algorithm > 0 ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
+ state.otp_algorithm ? /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
InputWithAddon,
{
expand: true,
@@ -45370,6 +48823,7 @@ function CreatePage4({ onCreate, onBack }) {
...s5,
otp_key: randomRfc3548Base32Key()
}));
+ e4.preventDefault();
}
},
/* @__PURE__ */ h(i18n2.Translate, null, "random")
@@ -45387,207 +48841,10 @@ function CreatePage4({ onCreate, onBack }) {
))), /* @__PURE__ */ h("div", { class: "column" }))));
}
-// src/hooks/otp.ts
-init_hooks_module();
-var useSWR6 = useSWR;
-function useOtpDeviceAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const createOtpDevice = async (data) => {
- const res = await request(`/private/otp-devices`, {
- method: "POST",
- data
- });
- await mutateAll(/.*private\/otp-devices.*/);
- return res;
- };
- const updateOtpDevice = async (deviceId, data) => {
- const res = await request(`/private/otp-devices/${deviceId}`, {
- method: "PATCH",
- data
- });
- await mutateAll(/.*private\/otp-devices.*/);
- return res;
- };
- const deleteOtpDevice = async (deviceId) => {
- const res = await request(`/private/otp-devices/${deviceId}`, {
- method: "DELETE"
- });
- await mutateAll(/.*private\/otp-devices.*/);
- return res;
- };
- return {
- createOtpDevice,
- updateOtpDevice,
- deleteOtpDevice
- };
-}
-function useInstanceOtpDevices(args, updatePosition) {
- const { fetcher } = useBackendInstanceRequest();
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR6([`/private/otp-devices`], fetcher);
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- }, [
- afterData
- /*, beforeData*/
- ]);
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.otp_devices.length < totalAfter;
- const isReachingStart = true;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
- return;
- if (afterData.data.otp_devices.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = `${afterData.data.otp_devices[afterData.data.otp_devices.length - 1].otp_device_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- },
- loadMorePrev: () => {
- }
- };
- const otp_devices = !afterData ? [] : (afterData || lastAfter).data.otp_devices;
- if (loadingAfter)
- return { loading: true, data: { otp_devices } };
- if (
- /*beforeData &&*/
- afterData
- ) {
- return { ok: true, data: { otp_devices }, ...pagination };
- }
- return { loading: true };
-}
-function useOtpDeviceDetails(deviceId) {
- const { fetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR6([`/private/otp-devices/${deviceId}`], fetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data) {
- return data;
- }
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-
-// src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
-init_preact_module();
-
-// src/components/exception/QR.tsx
-init_preact_module();
-init_hooks_module();
-var import_qrcode_generator = __toESM(require_qrcode(), 1);
-function QR({ text }) {
- const divRef = _2(null);
- h2(() => {
- const qr = (0, import_qrcode_generator.default)(0, "L");
- qr.addData(text);
- qr.make();
- if (divRef.current) {
- divRef.current.innerHTML = qr.createSvgTag({
- scalable: true
- });
- }
- });
- return /* @__PURE__ */ h(
- "div",
- {
- style: {
- width: "100%",
- display: "flex",
- flexDirection: "column",
- alignItems: "center"
- }
- },
- /* @__PURE__ */ h(
- "div",
- {
- style: { width: "50%", minWidth: 200, maxWidth: 300 },
- ref: divRef
- }
- )
- );
-}
-
-// src/components/notifications/CreatedSuccessfully.tsx
-init_preact_module();
-function CreatedSuccessfully({
- children,
- onConfirm,
- onCreateAnother
-}) {
- return /* @__PURE__ */ h("div", { class: "columns is-fullwidth is-vcentered mt-3" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h("div", { class: "card" }, /* @__PURE__ */ h("header", { class: "card-header has-background-success" }, /* @__PURE__ */ h("p", { class: "card-header-title has-text-white-ter" }, "Success.")), /* @__PURE__ */ h("div", { class: "card-content" }, children)), /* @__PURE__ */ h("div", { class: "buttons is-right" }, onCreateAnother && /* @__PURE__ */ h("button", { class: "button is-info", onClick: onCreateAnother }, "Create another"), /* @__PURE__ */ h("button", { class: "button is-info", onClick: onConfirm }, "Continue"))), /* @__PURE__ */ h("div", { class: "column" }));
-}
-
-// src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx
-function CreatedSuccessfully2({
- entity,
- onConfirm
-}) {
- const { i18n: i18n2 } = useTranslationContext();
- const { url: backendURL } = useBackendContext();
- const { id: instanceId } = useInstanceContext();
- const issuer = new URL(backendURL).hostname;
- const qrText = `otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`;
- const qrTextSafe = `otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0, 6)}...`;
- return /* @__PURE__ */ h(CreatedSuccessfully, { onConfirm }, /* @__PURE__ */ h("p", { class: "is-size-5" }, /* @__PURE__ */ h(i18n2.Translate, null, "You can scan the next QR code with your device or save the key before continuing.")), /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, "ID")), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h(
- "input",
- {
- readonly: true,
- class: "input",
- value: entity.otp_device_id
- }
- ))))), /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Description"))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control" }, /* @__PURE__ */ h(
- "input",
- {
- class: "input",
- readonly: true,
- value: entity.otp_device_description
- }
- ))))), /* @__PURE__ */ h(
- QR,
- {
- text: qrText
- }
- ), /* @__PURE__ */ h(
- "div",
- {
- style: {
- color: "grey",
- fontSize: "small",
- width: 200,
- textAlign: "center",
- margin: "auto",
- wordBreak: "break-all"
- }
- },
- qrTextSafe
- ));
-}
-
// src/paths/instance/otp_devices/create/index.tsx
function CreateValidator2({ onConfirm, onBack }) {
- const { createOtpDevice } = useOtpDeviceAPI();
+ const { lib: api } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
const [created, setCreated] = p3(null);
@@ -45599,7 +48856,7 @@ function CreateValidator2({ onConfirm, onBack }) {
{
onBack,
onCreate: (request) => {
- return createOtpDevice(request).then((d5) => {
+ return api.instance.addOtpDevice(state.token, request).then((d5) => {
setCreated(request);
}).catch((error2) => {
setNotif({
@@ -45617,6 +48874,55 @@ function CreateValidator2({ onConfirm, onBack }) {
init_preact_module();
init_hooks_module();
+// src/hooks/otp.ts
+var useSWR7 = useSWR;
+function revalidateInstanceOtpDevices() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listOtpDevices",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useInstanceOtpDevices() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, bid]) {
+ return await instance.listOtpDevices(token, {
+ // limit: PAGINATED_LIST_REQUEST,
+ // offset: bid,
+ // order: "dec",
+ });
+ }
+ const { data, error: error2 } = useSWR7([session.token, "offset", "listOtpDevices"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return data;
+}
+function revalidateOtpDeviceDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getOtpDeviceDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useOtpDeviceDetails(deviceId) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([dId, token]) {
+ return await instance.getOtpDeviceDetails(token, dId);
+ }
+ const { data, error: error2 } = useSWR7([deviceId, session.token, "getOtpDeviceDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+
// src/paths/instance/otp_devices/list/ListPage.tsx
init_preact_module();
@@ -45629,9 +48935,7 @@ function CardTable4({
onDelete,
onSelect,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -45651,9 +48955,7 @@ function CardTable4({
rowSelection,
rowSelectionHandler,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}
) : /* @__PURE__ */ h(EmptyTable5, null)))));
}
@@ -45662,19 +48964,17 @@ function Table4({
onLoadMoreAfter,
onDelete,
onSelect,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "table-container" }, hasMoreBefore && /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more devices before the first one`,
onClick: onLoadMoreBefore
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load newer devices")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load first page")
), /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "ID")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Description")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
return /* @__PURE__ */ h("tr", { key: i4.otp_device_id }, /* @__PURE__ */ h(
"td",
@@ -45699,19 +48999,19 @@ function Table4({
},
"Delete"
))));
- }))), hasMoreAfter && /* @__PURE__ */ h(
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more devices after the last one`,
onClick: onLoadMoreAfter
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load older devices")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
));
}
function EmptyTable5() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no devices yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no devices yet, add more pressing the + sign")));
}
// src/paths/instance/otp_devices/list/ListPage.tsx
@@ -45723,8 +49023,6 @@ function ListPage4({
onLoadMoreBefore,
onLoadMoreAfter
}) {
- const form = { payto_uri: "" };
- const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(
CardTable4,
{
@@ -45736,57 +49034,60 @@ function ListPage4({
onDelete,
onSelect,
onLoadMoreBefore,
- hasMoreBefore: !onLoadMoreBefore,
- onLoadMoreAfter,
- hasMoreAfter: !onLoadMoreAfter
+ onLoadMoreAfter
}
));
}
// src/paths/instance/otp_devices/list/index.tsx
-function ListOtpDevices2({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound
-}) {
- const [position, setPosition] = p3(void 0);
+function ListOtpDevices2({ onCreate, onSelect }) {
const { i18n: i18n2 } = useTranslationContext();
const [notif, setNotif] = p3(void 0);
- const { deleteOtpDevice } = useOtpDeviceAPI();
- const result = useInstanceOtpDevices({ position }, (id) => setPosition(id));
- if (result.loading)
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
+ const result = useInstanceOtpDevices();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
ListPage4,
{
- devices: result.data.otp_devices,
- onLoadMoreBefore: result.isReachingStart ? result.loadMorePrev : void 0,
- onLoadMoreAfter: result.isReachingEnd ? result.loadMore : void 0,
+ devices: result.body.otp_devices,
+ onLoadMoreBefore: void 0,
+ onLoadMoreAfter: void 0,
onCreate,
onSelect: (e4) => {
onSelect(e4.otp_device_id);
},
- onDelete: (e4) => deleteOtpDevice(e4.otp_device_id).then(
- () => setNotif({
- message: i18n2.str`validator delete successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not delete the validator`,
- type: "ERROR",
- description: error2.message
- })
- )
+ onDelete: (e4) => {
+ return lib.instance.deleteOtpDevice(state.token, e4.otp_device_id).then(
+ () => setNotif({
+ message: i18n2.str`validator delete successfully`,
+ type: "SUCCESS"
+ })
+ ).catch(
+ (error2) => setNotif({
+ message: i18n2.str`could not delete the validator`,
+ type: "ERROR",
+ description: error2.message
+ })
+ );
+ }
}
));
}
@@ -45903,24 +49204,31 @@ function UpdatePage2({ device, onUpdate, onBack }) {
function UpdateValidator2({
vid,
onConfirm,
- onBack,
- onUnauthorized,
- onNotFound,
- onLoadError
+ onBack
}) {
- const { updateOtpDevice } = useOtpDeviceAPI();
const result = useOtpDeviceDetails(vid);
const [notif, setNotif] = p3(void 0);
const [keyUpdated, setKeyUpdated] = p3(null);
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
if (keyUpdated) {
return /* @__PURE__ */ h(CreatedSuccessfully2, { entity: keyUpdated, onConfirm });
@@ -45930,24 +49238,45 @@ function UpdateValidator2({
{
device: {
id: vid,
- otp_algorithm: result.data.otp_algorithm,
- otp_device_description: result.data.device_description,
- otp_key: void 0,
- otp_ctr: result.data.otp_ctr
+ otp_algorithm: result.body.otp_algorithm,
+ otp_device_description: result.body.device_description,
+ otp_key: "",
+ otp_ctr: result.body.otp_ctr
},
onBack,
onUpdate: async (newInfo) => {
- return updateOtpDevice(vid, newInfo).then((d5) => {
- if (newInfo.otp_key) {
- setKeyUpdated({
- otp_algorithm: newInfo.otp_algorithm,
- otp_device_description: newInfo.otp_device_description,
- otp_device_id: newInfo.id,
- otp_key: newInfo.otp_key,
- otp_ctr: newInfo.otp_ctr
- });
+ return lib.instance.updateOtpDevice(state.token, vid, newInfo).then((d5) => {
+ if (d5.type === "ok") {
+ if (newInfo.otp_key) {
+ setKeyUpdated({
+ otp_algorithm: newInfo.otp_algorithm,
+ otp_device_description: newInfo.otp_device_description,
+ otp_device_id: newInfo.id,
+ otp_key: newInfo.otp_key,
+ otp_ctr: newInfo.otp_ctr
+ });
+ } else {
+ onConfirm();
+ }
} else {
- onConfirm();
+ switch (d5.case) {
+ case HttpStatusCode.NotFound: {
+ setNotif({
+ message: i18n2.str`Could not update template`,
+ type: "ERROR",
+ description: i18n2.str`Template id is unknown`
+ });
+ break;
+ }
+ case HttpStatusCode.Conflict: {
+ setNotif({
+ message: i18n2.str`Could not update template`,
+ type: "ERROR",
+ description: i18n2.str`The provided information is inconsistent with the current state of the template`
+ });
+ break;
+ }
+ }
}
}).catch((error2) => {
setNotif({
@@ -46078,20 +49407,20 @@ function InputStock({
}
// src/components/product/ProductForm.tsx
-function ProductForm2({ onSubscribe, initial: initial2, alreadyExist }) {
+function ProductForm2({ onSubscribe, initial: initial3, alreadyExist }) {
const [value, valueHandler] = p3({
address: {},
description_i18n: {},
taxes: [],
next_restock: { t_s: "never" },
price: ":0",
- ...initial2,
- stock: !initial2 || initial2.total_stock === -1 ? void 0 : {
- current: initial2.total_stock || 0,
- lost: initial2.total_lost || 0,
- sold: initial2.total_sold || 0,
- address: initial2.address,
- nextRestock: initial2.next_restock
+ ...initial3,
+ stock: !initial3 || initial3.total_stock === -1 ? void 0 : {
+ current: initial3.total_stock || 0,
+ lost: initial3.total_lost || 0,
+ sold: initial3.total_sold || 0,
+ address: initial3.address,
+ nextRestock: initial3.next_restock
}
});
let errors2 = {};
@@ -46130,7 +49459,7 @@ function ProductForm2({ onSubscribe, initial: initial2, alreadyExist }) {
h2(() => {
onSubscribe(hasErrors ? void 0 : submit);
}, [submit, hasErrors]);
- const { url: backendURL } = useBackendContext();
+ const { url: backendUrl } = useMerchantApiContext();
const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h(
FormProvider,
@@ -46144,7 +49473,7 @@ function ProductForm2({ onSubscribe, initial: initial2, alreadyExist }) {
InputWithAddon,
{
name: "product_id",
- addonBefore: `${backendURL}/product/`,
+ addonBefore: new URL("product/", backendUrl.href).href,
label: i18n2.str`ID`,
tooltip: i18n2.str`product identification to use in URLs (for internal use only)`
}
@@ -46235,7 +49564,8 @@ function CreatePage5({ onCreate, onBack }) {
// src/paths/instance/products/create/index.tsx
function CreateProduct({ onConfirm, onBack }) {
- const { createProduct } = useProductAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
@@ -46243,7 +49573,7 @@ function CreateProduct({ onConfirm, onBack }) {
{
onBack,
onCreate: (request) => {
- return createProduct(request).then(() => onConfirm()).catch((error2) => {
+ return lib.instance.addProduct(state.token, request).then(() => onConfirm()).catch((error2) => {
setNotif({
message: i18n2.str`could not create product`,
type: "ERROR",
@@ -46267,7 +49597,9 @@ function CardTable5({
onCreate,
onSelect,
onUpdate,
- onDelete
+ onDelete,
+ onLoadMoreAfter,
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3(
void 0
@@ -46287,6 +49619,8 @@ function CardTable5({
onSelect,
onDelete,
onUpdate,
+ onLoadMoreAfter,
+ onLoadMoreBefore,
rowSelection,
rowSelectionHandler
}
@@ -46298,11 +49632,13 @@ function Table5({
instances,
onSelect,
onUpdate,
- onDelete
+ onDelete,
+ onLoadMoreAfter,
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
- return /* @__PURE__ */ h("div", { class: "table-container" }, /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Image")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Description")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Price per unit")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Taxes")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Sales")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Stock")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Sold")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
+ const [settings] = usePreference();
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h("button", { class: "button is-fullwidth", onClick: onLoadMoreBefore }, /* @__PURE__ */ h(i18n2.Translate, null, "load first page")), /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Image")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Description")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Price per unit")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Taxes")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Sales")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Stock")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Sold")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
const restStockInfo = !i4.next_restock ? "" : i4.next_restock.t_s === "never" ? "never" : `restock at ${format(
new Date(i4.next_restock.t_s * 1e3),
dateFormatForSettings(settings)
@@ -46412,12 +49748,20 @@ function Table5({
{
product: i4,
onUpdate: (prod) => onUpdate(i4.id, prod).then(
- (r3) => rowSelectionHandler(void 0)
+ () => rowSelectionHandler(void 0)
),
onCancel: () => rowSelectionHandler(void 0)
}
))));
- }))));
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button is-fullwidth",
+ "data-tooltip": i18n2.str`load more products after the last one`,
+ onClick: onLoadMoreAfter
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
+ ));
}
function FastProductWithInfiniteStockUpdateForm({
product,
@@ -46441,7 +49785,7 @@ function FastProductWithInfiniteStockUpdateForm({
tooltip: i18n2.str`update the product with new price`
}
)
- ), /* @__PURE__ */ h("div", { class: "buttons is-expanded" }, /* @__PURE__ */ h("div", { class: "buttons mt-5" }, /* @__PURE__ */ h("button", { class: "button mt-5", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Clone"))), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, /* @__PURE__ */ h("button", { class: "button", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ ), /* @__PURE__ */ h("div", { class: "buttons is-expanded" }, /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, /* @__PURE__ */ h("button", { class: "button", onClick: onCancel }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
"span",
{
class: "has-tooltip-left",
@@ -46537,7 +49881,7 @@ function FastProductUpdateForm(props) {
}
function EmptyTable6() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no products yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no products yet, add more pressing the + sign")));
}
function difference(price, tax) {
if (!tax)
@@ -46553,30 +49897,40 @@ function sum(taxes) {
// src/paths/instance/products/list/index.tsx
function ProductList2({
- onUnauthorized,
- onLoadError,
onCreate,
- onSelect,
- onNotFound
+ onSelect
}) {
const result = useInstanceProducts();
- const { deleteProduct, updateProduct, getProduct } = useProductAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [deleting, setDeleting] = p3(null);
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
JumpToElementById,
{
- testIfExist: getProduct,
+ testIfExist: async (id) => {
+ const resp = await lib.instance.getProductDetails(state.token, id);
+ return resp.type === "ok";
+ },
onSelect,
description: i18n2.str`jump to product with the given product ID`,
placeholder: i18n2.str`product id`
@@ -46584,20 +49938,26 @@ function ProductList2({
), /* @__PURE__ */ h(
CardTable5,
{
- instances: result.data,
+ instances: result.body,
+ onLoadMoreBefore: result.isFirstPage ? void 0 : result.loadFirst,
+ onLoadMoreAfter: result.isLastPage ? void 0 : result.loadNext,
onCreate,
- onUpdate: (id, prod) => updateProduct(id, prod).then(
- () => setNotif({
- message: i18n2.str`product updated successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not update the product`,
- type: "ERROR",
- description: error2.message
- })
- ),
+ onUpdate: async (id, prod) => {
+ try {
+ await lib.instance.updateProduct(state.token, id, prod);
+ setNotif({
+ message: i18n2.str`product updated successfully`,
+ type: "SUCCESS"
+ });
+ } catch (error2) {
+ setNotif({
+ message: i18n2.str`could not update the product`,
+ type: "ERROR",
+ description: error2 instanceof Error ? error2.message : void 0
+ });
+ }
+ return;
+ },
onSelect: (product) => onSelect(product.id),
onDelete: (prod) => setDeleting(prod)
}
@@ -46611,7 +49971,7 @@ function ProductList2({
onCancel: () => setDeleting(null),
onConfirm: async () => {
try {
- await deleteProduct(deleting.id);
+ await lib.instance.deleteProduct(state.token, deleting.id);
setNotif({
message: i18n2.str`Product "${deleting.description}" (ID: ${deleting.id}) has been deleted`,
type: "SUCCESS"
@@ -46668,31 +50028,38 @@ function UpdatePage3({ product, onUpdate, onBack }) {
function UpdateProduct({
pid,
onConfirm,
- onBack,
- onUnauthorized,
- onNotFound,
- onLoadError
+ onBack
}) {
- const { updateProduct } = useProductAPI();
const result = useProductDetails(pid);
const [notif, setNotif] = p3(void 0);
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UpdatePage3,
{
- product: { ...result.data, product_id: pid },
+ product: { ...result.body, product_id: pid },
onBack,
onUpdate: (data) => {
- return updateProduct(pid, data).then(onConfirm).catch((error2) => {
+ return lib.instance.updateProduct(state.token, pid, data).then(onConfirm).catch((error2) => {
setNotif({
message: i18n2.str`could not create product`,
type: "ERROR",
@@ -46708,279 +50075,82 @@ function UpdateProduct({
init_preact_module();
init_hooks_module();
-// src/hooks/templates.ts
-init_hooks_module();
-var useSWR7 = useSWR;
-function useTemplateAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const createTemplate = async (data) => {
- const res = await request(`/private/templates`, {
- method: "POST",
- data
- });
- await mutateAll(/.*private\/templates.*/);
- return res;
- };
- const updateTemplate = async (templateId, data) => {
- const res = await request(`/private/templates/${templateId}`, {
- method: "PATCH",
- data
- });
- await mutateAll(/.*private\/templates.*/);
- return res;
- };
- const deleteTemplate = async (templateId) => {
- const res = await request(`/private/templates/${templateId}`, {
- method: "DELETE"
- });
- await mutateAll(/.*private\/templates.*/);
- return res;
- };
- const createOrderFromTemplate = async (templateId, data) => {
- const res = await request(
- `/templates/${templateId}`,
- {
- method: "POST",
- data
- }
- );
- await mutateAll(/.*private\/templates.*/);
- return res;
- };
- const testTemplateExist = async (templateId) => {
- const res = await request(`/private/templates/${templateId}`, { method: "GET" });
- return res;
- };
- return {
- createTemplate,
- updateTemplate,
- deleteTemplate,
- testTemplateExist,
- createOrderFromTemplate
- };
-}
-function useInstanceTemplates(args, updatePosition) {
- const { templateFetcher } = useBackendInstanceRequest();
- const [pageBefore, setPageBefore] = p3(1);
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const totalBefore = args?.position ? pageBefore * PAGE_SIZE : 0;
- const {
- data: beforeData,
- error: beforeError,
- isValidating: loadingBefore
- } = useSWR7(
- [
- `/private/templates`,
- args?.position,
- totalBefore
- ],
- templateFetcher
- );
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR7([`/private/templates`, args?.position, -totalAfter], templateFetcher);
- const [lastBefore, setLastBefore] = p3({ loading: true });
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- if (beforeData)
- setLastBefore(beforeData);
- }, [afterData, beforeData]);
- if (beforeError)
- return beforeError.cause;
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.templates.length < totalAfter;
- const isReachingStart = args?.position === void 0 || beforeData && beforeData.data.templates.length < totalBefore;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
- return;
- if (afterData.data.templates.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = `${afterData.data.templates[afterData.data.templates.length - 1].template_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- },
- loadMorePrev: () => {
- if (!beforeData || isReachingStart)
- return;
- if (beforeData.data.templates.length < MAX_RESULT_SIZE) {
- setPageBefore(pageBefore + 1);
- } else if (beforeData) {
- const from = `${beforeData.data.templates[beforeData.data.templates.length - 1].template_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- }
- };
- const templates = !beforeData || !afterData ? [] : (beforeData || lastBefore).data.templates.slice().reverse().concat((afterData || lastAfter).data.templates);
- if (loadingAfter || loadingBefore)
- return { loading: true, data: { templates } };
- if (beforeData && afterData) {
- return { ok: true, data: { templates }, ...pagination };
- }
- return { loading: true };
-}
-function useTemplateDetails(templateId) {
- const { templateFetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR7([`/private/templates/${templateId}`], templateFetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data) {
- return data;
- }
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-
// src/paths/instance/templates/create/CreatePage.tsx
init_preact_module();
init_hooks_module();
-
-// src/components/form/InputTab.tsx
-init_preact_module();
-var defaultToString4 = (f3) => f3 || "";
-var defaultFromString4 = (v3) => v3;
-function InputTab({
- name,
- readonly,
- expand,
- placeholder,
- tooltip,
- label,
- help,
- values,
- fromStr = defaultFromString4,
- toStr = defaultToString4
-}) {
- const { error: error2, value, onChange, required } = useField(name);
- return /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, label, tooltip && /* @__PURE__ */ h("span", { class: "icon has-tooltip-right", "data-tooltip": tooltip }, /* @__PURE__ */ h("i", { class: "mdi mdi-information" })))), /* @__PURE__ */ h("div", { class: "field-body is-flex-grow-3" }, /* @__PURE__ */ h("div", { class: "field has-icons-right" }, /* @__PURE__ */ h("p", { class: expand ? "control is-expanded " : "control " }, /* @__PURE__ */ h("div", { class: "tabs is-toggle is-fullwidth is-small" }, /* @__PURE__ */ h("ul", null, values.map((v3, i4) => {
- return /* @__PURE__ */ h(
- "li",
- {
- key: i4,
- class: value === v3 ? "is-active" : "",
- onClick: (e4) => {
- onChange(v3);
- }
- },
- /* @__PURE__ */ h("a", { style: { cursor: "initial" } }, /* @__PURE__ */ h("span", null, toStr(v3)))
- );
- }))), help), required && /* @__PURE__ */ h("span", { class: "icon has-text-danger is-right", style: { height: "2.5em" } }, /* @__PURE__ */ h("i", { class: "mdi mdi-alert" })), error2 && /* @__PURE__ */ h("p", { class: "help is-danger" }, error2))));
-}
-
-// src/paths/instance/templates/create/CreatePage.tsx
function CreatePage6({ onCreate, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
- const { url: backendURL } = useBackendContext();
+ const { url: backendUrl, config } = useMerchantApiContext();
const devices = useInstanceOtpDevices();
const [state, setState] = p3({
minimum_age: 0,
pay_duration: {
d_ms: 1e3 * 60 * 30
//30 min
- },
- type: 3 /* NON_FIXED */
+ }
});
+ function updateState(up) {
+ setState((old) => {
+ const newState = up(old);
+ if (!newState.amount_editable) {
+ newState.currency_editable = false;
+ }
+ return newState;
+ });
+ }
const parsedPrice = !state.amount ? void 0 : Amounts.parse(state.amount);
const errors2 = {
id: !state.id ? i18n2.str`should not be empty` : !/[a-zA-Z0-9]*/.test(state.id) ? i18n2.str`no valid. only characters and numbers` : void 0,
description: !state.description ? i18n2.str`should not be empty` : void 0,
- amount: !(state.type === 1 /* FIXED_PRICE */ || state.type === 0 /* BOTH_FIXED */) ? void 0 : !state.amount ? i18n2.str`required` : !parsedPrice ? i18n2.str`not valid` : Amounts.isZero(parsedPrice) ? i18n2.str`must be greater than 0` : void 0,
- summary: !(state.type === 2 /* FIXED_SUMMARY */ || state.type === 0 /* BOTH_FIXED */) ? void 0 : !state.summary ? i18n2.str`required` : void 0,
+ amount: !state.amount ? void 0 : !parsedPrice ? i18n2.str`not valid` : Amounts.isZero(parsedPrice) ? i18n2.str`must be greater than 0` : void 0,
minimum_age: state.minimum_age && state.minimum_age < 0 ? i18n2.str`should be greater that 0` : void 0,
pay_duration: !state.pay_duration ? i18n2.str`can't be empty` : state.pay_duration.d_ms === "forever" ? void 0 : state.pay_duration.d_ms < 1e3 ? i18n2.str`to short` : void 0
};
+ const cList = Object.values(config.currencies).map((d5) => d5.name);
const hasErrors = Object.keys(errors2).some(
(k5) => errors2[k5] !== void 0
);
const submitForm = () => {
- if (hasErrors || state.type === void 0)
+ if (hasErrors)
return Promise.reject();
- switch (state.type) {
- case 1 /* FIXED_PRICE */:
- return onCreate({
- template_id: state.id,
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- amount: state.amount
- // summary: state.summary,
- },
- otp_id: state.otpId
- });
- case 2 /* FIXED_SUMMARY */:
- return onCreate({
- template_id: state.id,
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- // amount: state.amount!,
- summary: state.summary
- },
- otp_id: state.otpId
- });
- case 3 /* NON_FIXED */:
- return onCreate({
- template_id: state.id,
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration)
- // amount: state.amount!,
- // summary: state.summary,
- },
- otp_id: state.otpId
- });
- case 0 /* BOTH_FIXED */:
- return onCreate({
- template_id: state.id,
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- amount: state.amount,
- summary: state.summary
- },
- otp_id: state.otpId
- });
- default:
- assertUnreachable(state.type);
- }
- ;
+ return onCreate({
+ template_id: state.id,
+ template_description: state.description,
+ template_contract: {
+ minimum_age: state.minimum_age,
+ pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
+ amount: state.amount_editable ? void 0 : state.amount,
+ summary: state.summary_editable ? void 0 : state.summary,
+ currency: cList.length > 1 && state.currency_editable ? void 0 : config.currency
+ },
+ editable_defaults: {
+ amount: !state.amount_editable ? void 0 : state.amount,
+ summary: !state.summary_editable ? void 0 : state.summary,
+ currency: cList.length === 1 || !state.currency_editable ? void 0 : config.currency
+ },
+ otp_id: state.otpId
+ });
};
- const deviceList = !devices.ok ? [] : devices.data.otp_devices;
+ const deviceList = !devices || devices instanceof TalerError || devices.type === "fail" ? [] : devices.body.otp_devices;
+ const deviceMap = deviceList.reduce(
+ (prev, cur) => {
+ prev[cur.otp_device_id] = cur.device_description;
+ return prev;
+ },
+ {}
+ );
return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
FormProvider,
{
object: state,
- valueHandler: setState,
+ valueHandler: updateState,
errors: errors2
},
/* @__PURE__ */ h(
InputWithAddon,
{
name: "id",
- help: `${backendURL}/templates/${state.id ?? ""}`,
+ help: new URL(`templates/${state.id ?? ""}`, backendUrl.href).href,
label: i18n2.str`Identifier`,
tooltip: i18n2.str`Name of the template in URLs.`
}
@@ -46995,62 +50165,47 @@ function CreatePage6({ onCreate, onBack }) {
}
),
/* @__PURE__ */ h(
- InputTab,
- {
- name: "type",
- label: i18n2.str`Type`,
- help: (() => {
- if (state.type === void 0)
- return "";
- switch (state.type) {
- case 3 /* NON_FIXED */:
- return i18n2.str`User will be able to input price and summary before payment.`;
- case 1 /* FIXED_PRICE */:
- return i18n2.str`User will be able to add a summary before payment.`;
- case 2 /* FIXED_SUMMARY */:
- return i18n2.str`User will be able to set the price before payment.`;
- case 0 /* BOTH_FIXED */:
- return i18n2.str`User will not be able to change the price or the summary.`;
- }
- })(),
- tooltip: i18n2.str`Define what the user be allowed to modify`,
- values: [
- 3 /* NON_FIXED */,
- 1 /* FIXED_PRICE */,
- 2 /* FIXED_SUMMARY */,
- 0 /* BOTH_FIXED */
- ],
- toStr: (v3) => {
- switch (v3) {
- case 3 /* NON_FIXED */:
- return i18n2.str`Simple`;
- case 1 /* FIXED_PRICE */:
- return i18n2.str`With price`;
- case 2 /* FIXED_SUMMARY */:
- return i18n2.str`With summary`;
- case 0 /* BOTH_FIXED */:
- return i18n2.str`With price and summary`;
- }
- }
- }
- ),
- state.type === 0 /* BOTH_FIXED */ || state.type === 2 /* FIXED_SUMMARY */ ? /* @__PURE__ */ h(
Input,
{
name: "summary",
inputType: "multiline",
- label: i18n2.str`Fixed summary`,
+ label: i18n2.str`Summary`,
tooltip: i18n2.str`If specified, this template will create order with the same summary`
}
- ) : void 0,
- state.type === 0 /* BOTH_FIXED */ || state.type === 1 /* FIXED_PRICE */ ? /* @__PURE__ */ h(
+ ),
+ /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "summary_editable",
+ label: i18n2.str`Summary is editable`,
+ tooltip: i18n2.str`Allow the user to change the summary.`
+ }
+ ),
+ /* @__PURE__ */ h(
InputCurrency,
{
name: "amount",
- label: i18n2.str`Fixed price`,
+ label: i18n2.str`Amount`,
tooltip: i18n2.str`If specified, this template will create order with the same price`
}
- ) : void 0,
+ ),
+ /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "amount_editable",
+ label: i18n2.str`Amount is editable`,
+ tooltip: i18n2.str`Allow the user to select the amount to pay.`
+ }
+ ),
+ cList.length > 1 && /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "currency_editable",
+ readonly: !state.amount_editable,
+ label: i18n2.str`Currency is editable`,
+ tooltip: i18n2.str`Allow the user to change currency.`
+ }
+ ), /* @__PURE__ */ h(TextField, { name: "sc", label: i18n2.str`Supported currencies` }, /* @__PURE__ */ h(i18n2.Translate, null, "supported currencies: ", cList.join(", ")))),
/* @__PURE__ */ h(
InputNumber2,
{
@@ -47069,35 +50224,32 @@ function CreatePage6({ onCreate, onBack }) {
tooltip: i18n2.str`How much time has the customer to complete the payment once the order was created.`
}
),
- /* @__PURE__ */ h(
- Input,
+ !deviceList.length ? /* @__PURE__ */ h(
+ TextField,
{
name: "otpId",
label: i18n2.str`OTP device`,
- readonly: true,
- side: /* @__PURE__ */ h(
- "button",
- {
- class: "button is-danger",
- "data-tooltip": i18n2.str`without otp device`,
- onClick: () => {
- setState((v3) => ({ ...v3, otpId: void 0 }));
- }
- },
- /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "remove"))
- ),
- tooltip: i18n2.str`Use to verify transaction in offline mode.`
- }
- ),
- /* @__PURE__ */ h(
- InputSearchOnList,
+ tooltip: i18n2.str`Use to verify transaction while offline.`
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "No OTP device."),
+ "\xA0",
+ /* @__PURE__ */ h("a", { href: "/otp-devices/new" }, /* @__PURE__ */ h(i18n2.Translate, null, "Add one first"))
+ ) : /* @__PURE__ */ h(
+ InputSelector,
{
- label: i18n2.str`Search device`,
- onChange: (p4) => setState((v3) => ({ ...v3, otpId: p4?.id })),
- list: deviceList.map((e4) => ({
- description: e4.device_description,
- id: e4.otp_device_id
- }))
+ name: "otpId",
+ label: i18n2.str`OTP device`,
+ values: [
+ void 0,
+ ...deviceList.map((e4) => e4.otp_device_id)
+ ],
+ toStr: (v3) => {
+ if (!v3) {
+ return i18n2.str`No device`;
+ }
+ return deviceMap[v3];
+ },
+ tooltip: i18n2.str`Use to verify transaction in offline mode.`
}
)
), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
@@ -47113,7 +50265,8 @@ function CreatePage6({ onCreate, onBack }) {
// src/paths/instance/templates/create/index.tsx
function CreateTransfer({ onConfirm, onBack }) {
- const { createTemplate } = useTemplateAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
@@ -47121,7 +50274,7 @@ function CreateTransfer({ onConfirm, onBack }) {
{
onBack,
onCreate: (request) => {
- return createTemplate(request).then(() => onConfirm()).catch((error2) => {
+ return lib.instance.addTemplate(state.token, request).then(() => onConfirm()).catch((error2) => {
setNotif({
message: i18n2.str`could not inform template`,
type: "ERROR",
@@ -47137,6 +50290,57 @@ function CreateTransfer({ onConfirm, onBack }) {
init_preact_module();
init_hooks_module();
+// src/hooks/templates.ts
+init_hooks_module();
+var useSWR8 = useSWR;
+function revalidateInstanceTemplates() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listTemplates",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useInstanceTemplates() {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ const [offset, setOffset] = p3();
+ async function fetcher([token, bid]) {
+ return await instance.listTemplates(token, {
+ limit: PAGINATED_LIST_REQUEST,
+ offset: bid,
+ order: "dec"
+ });
+ }
+ const { data, error: error2 } = useSWR8([session.token, offset, "listTemplates"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return buildPaginatedResult(data.body.templates, offset, setOffset, (d5) => d5.template_id);
+}
+function revalidateTemplateDetails() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "getTemplateDetails",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useTemplateDetails(templateId) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([tid, token]) {
+ return await instance.getTemplateDetails(token, tid);
+ }
+ const { data, error: error2 } = useSWR8([templateId, session.token, "getTemplateDetails"], fetcher);
+ if (data)
+ return data;
+ if (error2)
+ return error2;
+ return void 0;
+}
+
// src/paths/instance/templates/list/ListPage.tsx
init_preact_module();
@@ -47151,9 +50355,7 @@ function CardTable6({
onQR,
onNewOrder,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -47175,9 +50377,7 @@ function CardTable6({
rowSelection,
rowSelectionHandler,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}
) : /* @__PURE__ */ h(EmptyTable7, null)))));
}
@@ -47188,19 +50388,17 @@ function Table6({
onNewOrder,
onQR,
onSelect,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "table-container" }, hasMoreBefore && /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more templates before the first one`,
onClick: onLoadMoreBefore
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load newer templates")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load first page")
), /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "ID")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Description")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
return /* @__PURE__ */ h("tr", { key: i4.template_id }, /* @__PURE__ */ h(
"td",
@@ -47241,19 +50439,19 @@ function Table6({
},
"QR"
))));
- }))), hasMoreAfter && /* @__PURE__ */ h(
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more templates after the last one`,
onClick: onLoadMoreAfter
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load older templates")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
));
}
function EmptyTable7() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no templates yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no templates yet, add more pressing the + sign")));
}
// src/paths/instance/templates/list/ListPage.tsx
@@ -47267,8 +50465,6 @@ function ListPage5({
onLoadMoreBefore,
onLoadMoreAfter
}) {
- const form = { payto_uri: "" };
- const { i18n: i18n2 } = useTranslationContext();
return /* @__PURE__ */ h(
CardTable6,
{
@@ -47282,42 +50478,49 @@ function ListPage5({
onSelect,
onNewOrder,
onLoadMoreBefore,
- hasMoreBefore: !onLoadMoreBefore,
- onLoadMoreAfter,
- hasMoreAfter: !onLoadMoreAfter
+ onLoadMoreAfter
}
);
}
// src/paths/instance/templates/list/index.tsx
function ListTemplates({
- onUnauthorized,
- onLoadError,
onCreate,
onQR,
onSelect,
- onNewOrder,
- onNotFound
+ onNewOrder
}) {
- const [position, setPosition] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
const [notif, setNotif] = p3(void 0);
- const { deleteTemplate, testTemplateExist } = useTemplateAPI();
- const result = useInstanceTemplates({ position }, (id) => setPosition(id));
+ const { lib } = useMerchantApiContext();
+ const result = useInstanceTemplates();
const [deleting, setDeleting] = p3(null);
- if (result.loading)
+ const { state } = useSessionContext();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
JumpToElementById,
{
- testIfExist: testTemplateExist,
+ testIfExist: async (id) => {
+ const resp = await lib.instance.getTemplateDetails(state.token, id);
+ return resp.type === "ok";
+ },
onSelect,
description: i18n2.str`jump to template with the given template ID`,
placeholder: i18n2.str`template id`
@@ -47325,9 +50528,9 @@ function ListTemplates({
), /* @__PURE__ */ h(
ListPage5,
{
- templates: result.data.templates,
- onLoadMoreBefore: result.isReachingStart ? result.loadMorePrev : void 0,
- onLoadMoreAfter: result.isReachingEnd ? result.loadMore : void 0,
+ templates: result.body,
+ onLoadMoreBefore: result.isFirstPage ? void 0 : result.loadFirst,
+ onLoadMoreAfter: result.isLastPage ? void 0 : result.loadNext,
onCreate,
onSelect: (e4) => {
onSelect(e4.template_id);
@@ -47352,7 +50555,7 @@ function ListTemplates({
onCancel: () => setDeleting(null),
onConfirm: async () => {
try {
- await deleteTemplate(deleting.template_id);
+ await lib.instance.deleteTemplate(state.token, deleting.template_id);
setNotif({
message: i18n2.str`Template "${deleting.template_description}" (ID: ${deleting.template_id}) has been deleted`,
type: "SUCCESS"
@@ -47374,77 +50577,26 @@ function ListTemplates({
// src/paths/instance/templates/qr/index.tsx
init_preact_module();
-init_hooks_module();
// src/paths/instance/templates/qr/QrPage.tsx
init_preact_module();
-init_hooks_module();
function QrPage({ contract, id: templateId, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
- const { url: backendURL } = useBackendContext();
- const { id: instanceId } = useInstanceContext();
- const config = useConfigContext();
- const [state, setState] = p3({
- amount: contract.amount,
- summary: contract.summary
- });
- const errors2 = {};
- const fixedAmount = !!contract.amount;
- const fixedSummary = !!contract.summary;
- const templateParams = {};
- if (!fixedAmount) {
- if (state.amount) {
- templateParams.amount = state.amount;
- } else {
- templateParams.amount = config.currency;
- }
- }
- if (!fixedSummary) {
- templateParams.summary = state.summary ?? "";
- }
- const merchantBaseUrl = new URL(backendURL).href;
+ const { config, url: backendUrl } = useMerchantApiContext();
+ const merchantBaseUrl = backendUrl.href;
const payTemplateUri = stringifyPayTemplateUri({
merchantBaseUrl,
templateId,
- templateParams
+ templateParams: {}
});
- const issuer = encodeURIComponent(
- `${new URL(backendURL).host}/${instanceId}`
- );
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h("p", { class: "is-size-5 mt-5 mb-5" }, /* @__PURE__ */ h(i18n2.Translate, null, "Here you can specify a default value for fields that are not fixed. Default values can be edited by the customer before the payment.")), /* @__PURE__ */ h("p", null), /* @__PURE__ */ h(
- FormProvider,
- {
- object: state,
- valueHandler: setState,
- errors: errors2
- },
- /* @__PURE__ */ h(
- InputCurrency,
- {
- name: "amount",
- label: fixedAmount ? i18n2.str`Fixed amount` : i18n2.str`Default amount`,
- readonly: fixedAmount,
- tooltip: i18n2.str`Amount of the order`
- }
- ),
- /* @__PURE__ */ h(
- Input,
- {
- name: "summary",
- inputType: "multiline",
- readonly: fixedSummary,
- label: fixedSummary ? i18n2.str`Fixed summary` : i18n2.str`Default summary`,
- tooltip: i18n2.str`Title of the order to be shown to the customer`
- }
- )
- ), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { id: "printThis" }, /* @__PURE__ */ h(QR, { text: payTemplateUri }), /* @__PURE__ */ h("pre", { style: { textAlign: "center" } }, /* @__PURE__ */ h("a", { href: payTemplateUri }, payTemplateUri))), /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h("p", null), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
"button",
{
class: "button is-info",
onClick: () => saveAsPDF(templateId)
},
/* @__PURE__ */ h(i18n2.Translate, null, "Print")
- ))), /* @__PURE__ */ h("div", { class: "column" }))), /* @__PURE__ */ h("section", { id: "printThis" }, /* @__PURE__ */ h(QR, { text: payTemplateUri }), /* @__PURE__ */ h("pre", { style: { textAlign: "center" } }, /* @__PURE__ */ h("a", { href: payTemplateUri }, payTemplateUri))));
+ ))), /* @__PURE__ */ h("div", { class: "column" }))));
}
function saveAsPDF(name) {
const printWindow = window.open("", "", "height=400,width=800");
@@ -47461,30 +50613,34 @@ function saveAsPDF(name) {
printWindow.document.body.appendChild(divContents.cloneNode(true));
printWindow.addEventListener("load", () => {
printWindow.print();
- printWindow.close();
});
}
// src/paths/instance/templates/qr/index.tsx
function TemplateQrPage({
tid,
- onBack,
- onLoadError,
- onNotFound,
- onUnauthorized
+ onBack
}) {
const result = useTemplateDetails(tid);
- const [notif, setNotif] = p3(void 0);
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
}
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(QrPage, { contract: result.data.template_contract, id: tid, onBack }));
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
+ }
+ return /* @__PURE__ */ h(QrPage, { contract: result.body.template_contract, id: tid, onBack });
}
// src/paths/instance/templates/update/index.tsx
@@ -47496,87 +50652,74 @@ init_preact_module();
init_hooks_module();
function UpdatePage4({ template, onUpdate, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
- const { url: backendURL } = useBackendContext();
- const intialStep = template.template_contract.amount === void 0 && template.template_contract.summary === void 0 ? 3 /* NON_FIXED */ : template.template_contract.summary === void 0 ? 1 /* FIXED_PRICE */ : template.template_contract.amount === void 0 ? 2 /* FIXED_SUMMARY */ : 0 /* BOTH_FIXED */;
+ const { url: backendUrl, config } = useMerchantApiContext();
const [state, setState] = p3({
- amount: template.template_contract.amount,
description: template.template_description,
minimum_age: template.template_contract.minimum_age,
otpId: template.otp_id,
- pay_duration: template.template_contract.pay_duration ? Duration.fromTalerProtocolDuration(template.template_contract.pay_duration) : void 0,
- summary: template.template_contract.summary,
- type: intialStep
+ pay_duration: template.template_contract.pay_duration ? Duration.fromTalerProtocolDuration(
+ template.template_contract.pay_duration
+ ) : void 0,
+ summary: template.editable_defaults?.summary ?? template.template_contract.summary,
+ amount: template.editable_defaults?.amount ?? template.template_contract.amount,
+ currency_editable: !!template.editable_defaults?.currency,
+ summary_editable: !!template.editable_defaults?.summary,
+ amount_editable: !!template.editable_defaults?.amount
});
+ function updateState(up) {
+ setState((old) => {
+ const newState = up(old);
+ if (!newState.amount_editable) {
+ newState.currency_editable = false;
+ }
+ return newState;
+ });
+ }
const devices = useInstanceOtpDevices();
- const deviceList = !devices.ok ? [] : devices.data.otp_devices;
+ const deviceList = !devices || devices instanceof TalerError || devices.type === "fail" ? [] : devices.body.otp_devices;
+ const deviceMap = deviceList.reduce(
+ (prev, cur) => {
+ prev[cur.otp_device_id] = cur.device_description;
+ return prev;
+ },
+ {}
+ );
const parsedPrice = !state.amount ? void 0 : Amounts.parse(state.amount);
const errors2 = {
description: !state.description ? i18n2.str`should not be empty` : void 0,
- amount: !(state.type === 1 /* FIXED_PRICE */ || state.type === 0 /* BOTH_FIXED */) ? void 0 : !state.amount ? i18n2.str`required` : !parsedPrice ? i18n2.str`not valid` : Amounts.isZero(parsedPrice) ? i18n2.str`must be greater than 0` : void 0,
- summary: !(state.type === 2 /* FIXED_SUMMARY */ || state.type === 0 /* BOTH_FIXED */) ? void 0 : !state.summary ? i18n2.str`required` : void 0,
+ amount: !state.amount ? void 0 : !parsedPrice ? i18n2.str`not valid` : Amounts.isZero(parsedPrice) ? i18n2.str`must be greater than 0` : void 0,
minimum_age: state.minimum_age && state.minimum_age < 0 ? i18n2.str`should be greater that 0` : void 0,
pay_duration: !state.pay_duration ? i18n2.str`can't be empty` : state.pay_duration.d_ms === "forever" ? void 0 : state.pay_duration.d_ms < 1e3 ? i18n2.str`to short` : void 0
};
+ const cList = Object.values(config.currencies).map((d5) => d5.name);
const hasErrors = Object.keys(errors2).some(
(k5) => errors2[k5] !== void 0
);
const submitForm = () => {
- if (hasErrors || state.type === void 0)
+ if (hasErrors)
return Promise.reject();
- switch (state.type) {
- case 1 /* FIXED_PRICE */:
- return onUpdate({
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- amount: state.amount
- // summary: state.summary,
- },
- otp_id: state.otpId
- });
- case 2 /* FIXED_SUMMARY */:
- return onUpdate({
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- // amount: state.amount!,
- summary: state.summary
- },
- otp_id: state.otpId
- });
- case 3 /* NON_FIXED */:
- return onUpdate({
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration)
- // amount: state.amount!,
- // summary: state.summary,
- },
- otp_id: state.otpId
- });
- case 0 /* BOTH_FIXED */:
- return onUpdate({
- template_description: state.description,
- template_contract: {
- minimum_age: state.minimum_age,
- pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
- amount: state.amount,
- summary: state.summary
- },
- otp_id: state.otpId
- });
- default:
- assertUnreachable(state.type);
- }
+ return onUpdate({
+ template_description: state.description,
+ template_contract: {
+ minimum_age: state.minimum_age,
+ pay_duration: Duration.toTalerProtocolDuration(state.pay_duration),
+ amount: state.amount_editable ? void 0 : state.amount,
+ summary: state.summary_editable ? void 0 : state.summary,
+ currency: cList.length > 1 && state.currency_editable ? void 0 : config.currency
+ },
+ editable_defaults: {
+ amount: !state.amount_editable ? void 0 : state.amount,
+ summary: !state.summary_editable ? void 0 : state.summary,
+ currency: cList.length === 1 || !state.currency_editable ? void 0 : config.currency
+ },
+ otp_id: state.otpId
+ });
};
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, backendURL, "/templates/", template.otp_id)))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, new URL(`templates/${template.id}`, backendUrl.href).href)))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
FormProvider,
{
object: state,
- valueHandler: setState,
+ valueHandler: updateState,
errors: errors2
},
/* @__PURE__ */ h(
@@ -47589,60 +50732,47 @@ function UpdatePage4({ template, onUpdate, onBack }) {
}
),
/* @__PURE__ */ h(
- InputTab,
- {
- name: "type",
- label: i18n2.str`Type`,
- help: (() => {
- switch (state.type) {
- case 3 /* NON_FIXED */:
- return i18n2.str`User will be able to input price and summary before payment.`;
- case 1 /* FIXED_PRICE */:
- return i18n2.str`User will be able to add a summary before payment.`;
- case 2 /* FIXED_SUMMARY */:
- return i18n2.str`User will be able to set the price before payment.`;
- case 0 /* BOTH_FIXED */:
- return i18n2.str`User will not be able to change the price or the summary.`;
- }
- })(),
- tooltip: i18n2.str`Define what the user be allowed to modify`,
- values: [
- 3 /* NON_FIXED */,
- 1 /* FIXED_PRICE */,
- 2 /* FIXED_SUMMARY */,
- 0 /* BOTH_FIXED */
- ],
- toStr: (v3) => {
- switch (v3) {
- case 3 /* NON_FIXED */:
- return i18n2.str`Simple`;
- case 1 /* FIXED_PRICE */:
- return i18n2.str`With price`;
- case 2 /* FIXED_SUMMARY */:
- return i18n2.str`With summary`;
- case 0 /* BOTH_FIXED */:
- return i18n2.str`With price and summary`;
- }
- }
- }
- ),
- state.type === 0 /* BOTH_FIXED */ || state.type === 2 /* FIXED_SUMMARY */ ? /* @__PURE__ */ h(
Input,
{
name: "summary",
inputType: "multiline",
- label: i18n2.str`Fixed summary`,
+ label: i18n2.str`Summary`,
tooltip: i18n2.str`If specified, this template will create order with the same summary`
}
- ) : void 0,
- state.type === 0 /* BOTH_FIXED */ || state.type === 1 /* FIXED_PRICE */ ? /* @__PURE__ */ h(
+ ),
+ /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "summary_editable",
+ label: i18n2.str`Summary is editable`,
+ tooltip: i18n2.str`Allow the user to change the summary.`
+ }
+ ),
+ /* @__PURE__ */ h(
InputCurrency,
{
name: "amount",
- label: i18n2.str`Fixed price`,
+ label: i18n2.str`Amount`,
tooltip: i18n2.str`If specified, this template will create order with the same price`
}
- ) : void 0,
+ ),
+ /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "amount_editable",
+ label: i18n2.str`Amount is editable`,
+ tooltip: i18n2.str`Allow the user to select the amount to pay.`
+ }
+ ),
+ cList.length > 1 && /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
+ InputToggle,
+ {
+ name: "currency_editable",
+ readonly: !state.amount_editable,
+ label: i18n2.str`Currency is editable`,
+ tooltip: i18n2.str`Allow the user to change currency.`
+ }
+ ), /* @__PURE__ */ h(TextField, { name: "sc", label: i18n2.str`Supported currencies` }, /* @__PURE__ */ h(i18n2.Translate, null, "supported currencies: ", cList.join(", ")))),
/* @__PURE__ */ h(
InputNumber2,
{
@@ -47661,35 +50791,32 @@ function UpdatePage4({ template, onUpdate, onBack }) {
tooltip: i18n2.str`How much time has the customer to complete the payment once the order was created.`
}
),
- /* @__PURE__ */ h(
- Input,
+ !deviceList.length ? /* @__PURE__ */ h(
+ TextField,
{
name: "otpId",
label: i18n2.str`OTP device`,
- readonly: true,
- side: /* @__PURE__ */ h(
- "button",
- {
- class: "button is-danger",
- "data-tooltip": i18n2.str`remove otp device for this template`,
- onClick: () => {
- setState((v3) => ({ ...v3, otpId: null }));
- }
- },
- /* @__PURE__ */ h("span", null, /* @__PURE__ */ h(i18n2.Translate, null, "remove"))
- ),
- tooltip: i18n2.str`Use to verify transaction in offline mode.`
- }
- ),
- /* @__PURE__ */ h(
- InputSearchOnList,
+ tooltip: i18n2.str`Use to verify transaction while offline.`
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "No OTP device."),
+ "\xA0",
+ /* @__PURE__ */ h("a", { href: "/otp-devices/new" }, /* @__PURE__ */ h(i18n2.Translate, null, "Add one first"))
+ ) : /* @__PURE__ */ h(
+ InputSelector,
{
- label: i18n2.str`Search device`,
- onChange: (p4) => setState((v3) => ({ ...v3, otpId: p4?.id })),
- list: deviceList.map((e4) => ({
- description: e4.device_description,
- id: e4.otp_device_id
- }))
+ name: "otpId",
+ label: i18n2.str`OTP device`,
+ values: [
+ void 0,
+ ...deviceList.map((e4) => e4.otp_device_id)
+ ],
+ toStr: (v3) => {
+ if (!v3) {
+ return i18n2.str`No device`;
+ }
+ return deviceMap[v3];
+ },
+ tooltip: i18n2.str`Use to verify transaction in offline mode.`
}
)
), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
@@ -47707,31 +50834,38 @@ function UpdatePage4({ template, onUpdate, onBack }) {
function UpdateTemplate({
tid,
onConfirm,
- onBack,
- onUnauthorized,
- onNotFound,
- onLoadError
+ onBack
}) {
- const { updateTemplate } = useTemplateAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const result = useTemplateDetails(tid);
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UpdatePage4,
{
- template: { ...result.data },
+ template: { ...result.body, id: tid },
onBack,
onUpdate: (data) => {
- return updateTemplate(tid, data).then(onConfirm).catch((error2) => {
+ return lib.instance.updateTemplate(state.token, tid, data).then(onConfirm).catch((error2) => {
setNotif({
message: i18n2.str`could not update template`,
type: "ERROR",
@@ -47753,12 +50887,13 @@ init_hooks_module();
function UsePage({ id, template, onCreateOrder, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
const [state, setState] = p3({
- amount: template.template_contract.amount,
- summary: template.template_contract.summary
+ currency: template.editable_defaults?.currency ?? template.template_contract.currency,
+ amount: template.editable_defaults?.amount ?? template.template_contract.amount,
+ summary: template.editable_defaults?.summary ?? template.template_contract.summary
});
const errors2 = {
- amount: !template.template_contract.amount && !state.amount ? i18n2.str`Amount is required` : void 0,
- summary: !template.template_contract.summary && !state.summary ? i18n2.str`Order summary is required` : void 0
+ amount: !state.amount ? i18n2.str`Amount is required` : void 0,
+ summary: !state.summary ? i18n2.str`Order summary is required` : void 0
};
const hasErrors = Object.keys(errors2).some(
(k5) => errors2[k5] !== void 0
@@ -47815,32 +50950,47 @@ function UsePage({ id, template, onCreateOrder, onBack }) {
function TemplateUsePage({
tid,
onOrderCreated,
- onBack,
- onLoadError,
- onNotFound,
- onUnauthorized
+ onBack
}) {
- const { createOrderFromTemplate } = useTemplateAPI();
+ const { lib } = useMerchantApiContext();
const result = useTemplateDetails(tid);
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UsePage,
{
- template: result.data,
+ template: result.body,
id: tid,
onBack,
onCreateOrder: (request) => {
- return createOrderFromTemplate(tid, request).then((res) => onOrderCreated(res.data.order_id)).catch((error2) => {
+ return lib.instance.useTemplateCreateOrder(tid, request).then((res) => {
+ if (res.type === "ok") {
+ onOrderCreated(res.body.order_id);
+ } else {
+ setNotif({
+ message: i18n2.str`could not create order from template`,
+ type: "ERROR"
+ });
+ }
+ }).catch((error2) => {
setNotif({
message: i18n2.str`could not create order from template`,
type: "ERROR",
@@ -47854,11 +51004,17 @@ function TemplateUsePage({
// src/paths/instance/token/index.tsx
init_preact_module();
+init_hooks_module();
// src/paths/instance/token/DetailPage.tsx
init_preact_module();
init_hooks_module();
-function DetailPage2({ instanceId, hasToken, onBack, onNewToken, onClearToken }) {
+function DetailPage2({
+ hasToken,
+ onBack,
+ onNewToken,
+ onClearToken
+}) {
const [form, setValue] = p3({
old_token: "",
new_token: "",
@@ -47873,14 +51029,14 @@ function DetailPage2({ instanceId, hasToken, onBack, onNewToken, onClearToken })
const hasErrors = Object.keys(errors2).some(
(k5) => errors2[k5] !== void 0
);
- const instance = useInstanceContext();
- const text = i18n2.str`You are updating the access token from instance with id "${instance.id}"`;
+ const { state } = useSessionContext();
+ const text = i18n2.str`You are updating the access token from instance with id "${state.instance}"`;
async function submitForm() {
if (hasErrors)
return;
- const oldToken = hasToken ? `secret-token:${form.old_token}` : void 0;
- const newToken = `secret-token:${form.new_token}`;
- onNewToken(oldToken, newToken);
+ const oldToken = hasToken ? form.old_token : void 0;
+ const newToken = form.new_token;
+ onNewToken(oldToken, `secret-token:${newToken}`);
}
return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, text)))))), /* @__PURE__ */ h("hr", null), !hasToken && /* @__PURE__ */ h(
NotificationCard,
@@ -47905,7 +51061,7 @@ function DetailPage2({ instanceId, hasToken, onBack, onNewToken, onClearToken })
class: "button",
onClick: () => {
if (hasToken) {
- const oldToken = `secret-token:${form.old_token}`;
+ const oldToken = form.old_token;
onClearToken(oldToken);
} else {
onClearToken(void 0);
@@ -47929,50 +51085,57 @@ function DetailPage2({ instanceId, hasToken, onBack, onNewToken, onClearToken })
tooltip: i18n2.str`confirm the same access token`,
inputType: "password"
}
- ))), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("button", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
+ )), /* @__PURE__ */ h("div", { class: "buttons is-right mt-5" }, onBack && /* @__PURE__ */ h("a", { class: "button", onClick: onBack }, /* @__PURE__ */ h(i18n2.Translate, null, "Cancel")), /* @__PURE__ */ h(
AsyncButton,
{
+ type: "submit",
disabled: hasErrors,
"data-tooltip": hasErrors ? i18n2.str`Need to complete marked fields` : "confirm operation",
onClick: submitForm
},
/* @__PURE__ */ h(i18n2.Translate, null, "Confirm change")
- ))), /* @__PURE__ */ h("div", { class: "column" }))));
+ )))), /* @__PURE__ */ h("div", { class: "column" }))));
}
// src/paths/instance/token/index.tsx
-init_hooks_module();
function Token({
- onLoadError,
onChange,
- onUnauthorized,
- onNotFound,
onCancel
}) {
const { i18n: i18n2 } = useTranslationContext();
+ const { lib } = useMerchantApiContext();
+ const { logIn } = useSessionContext();
const [notif, setNotif] = p3(void 0);
- const { clearAccessToken, setNewAccessToken } = useInstanceAPI();
- const { id } = useInstanceContext();
const result = useInstanceDetails();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
- }
- const hasToken = result.data.auth.method === "token";
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
+ }
+ const hasToken = result.body.auth.method === "token";
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
DetailPage2,
{
- instanceId: id,
onBack: onCancel,
hasToken,
onClearToken: async (currentToken) => {
try {
- await clearAccessToken(currentToken);
+ await lib.instance.updateCurrentInstanceAuthentication(currentToken, {
+ method: "external"
+ });
onChange();
} catch (error2) {
if (error2 instanceof Error) {
@@ -47986,8 +51149,26 @@ function Token({
},
onNewToken: async (currentToken, newToken) => {
try {
- await setNewAccessToken(currentToken, newToken);
- onChange();
+ await lib.instance.updateCurrentInstanceAuthentication(currentToken, {
+ token: newToken,
+ method: "token"
+ });
+ const resp = await lib.authenticate.createAccessTokenBearer(newToken, {
+ scope: "write",
+ duration: {
+ d_us: "forever"
+ },
+ refreshable: true
+ });
+ if (resp.type === "ok") {
+ logIn({ token: resp.body.token });
+ onChange();
+ } else {
+ setNotif({
+ message: i18n2.str`Failed to set new token`,
+ type: "ERROR"
+ });
+ }
} catch (error2) {
if (error2 instanceof Error) {
setNotif({
@@ -48006,111 +51187,11 @@ function Token({
init_preact_module();
init_hooks_module();
-// src/hooks/transfer.ts
-init_hooks_module();
-var useSWR8 = useSWR;
-function useTransferAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const informTransfer = async (data) => {
- const res = await request(`/private/transfers`, {
- method: "POST",
- data
- });
- await mutateAll(/.*private\/transfers.*/);
- return res;
- };
- return { informTransfer };
-}
-function useInstanceTransfers(args, updatePosition) {
- const { transferFetcher } = useBackendInstanceRequest();
- const [pageBefore, setPageBefore] = p3(1);
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const totalBefore = args?.position !== void 0 ? pageBefore * PAGE_SIZE : 0;
- const {
- data: beforeData,
- error: beforeError,
- isValidating: loadingBefore
- } = useSWR8(
- [
- `/private/transfers`,
- args?.payto_uri,
- args?.verified,
- args?.position,
- totalBefore
- ],
- transferFetcher
- );
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR8(
- [
- `/private/transfers`,
- args?.payto_uri,
- args?.verified,
- args?.position,
- -totalAfter
- ],
- transferFetcher
- );
- const [lastBefore, setLastBefore] = p3({ loading: true });
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- if (beforeData)
- setLastBefore(beforeData);
- }, [afterData, beforeData]);
- if (beforeError)
- return beforeError.cause;
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.transfers.length < totalAfter;
- const isReachingStart = args?.position === void 0 || beforeData && beforeData.data.transfers.length < totalBefore;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
- return;
- if (afterData.data.transfers.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = `${afterData.data.transfers[afterData.data.transfers.length - 1].transfer_serial_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- },
- loadMorePrev: () => {
- if (!beforeData || isReachingStart)
- return;
- if (beforeData.data.transfers.length < MAX_RESULT_SIZE) {
- setPageBefore(pageBefore + 1);
- } else if (beforeData) {
- const from = `${beforeData.data.transfers[beforeData.data.transfers.length - 1].transfer_serial_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- }
- };
- const transfers = !beforeData || !afterData ? [] : (beforeData || lastBefore).data.transfers.slice().reverse().concat((afterData || lastAfter).data.transfers);
- if (loadingAfter || loadingBefore)
- return { loading: true, data: { transfers } };
- if (beforeData && afterData) {
- return { ok: true, data: { transfers }, ...pagination };
- }
- return { loading: true };
-}
-
// src/paths/instance/transfers/create/CreatePage.tsx
init_preact_module();
init_hooks_module();
function CreatePage7({ accounts, onCreate, onBack }) {
const { i18n: i18n2 } = useTranslationContext();
- const { currency } = useConfigContext();
const [state, setState] = p3({
wtid: "",
// payto_uri: ,
@@ -48187,18 +51268,19 @@ function CreatePage7({ accounts, onCreate, onBack }) {
// src/paths/instance/transfers/create/index.tsx
function CreateTransfer2({ onConfirm, onBack }) {
- const { informTransfer } = useTransferAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
const instance = useInstanceBankAccounts();
- const accounts = !instance.ok ? [] : instance.data.accounts.map((a5) => a5.payto_uri);
+ const accounts = !instance || instance instanceof TalerError || instance.type === "fail" ? [] : instance.body.accounts.map((a5) => a5.payto_uri);
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
CreatePage7,
{
onBack,
accounts,
onCreate: (request) => {
- return informTransfer(request).then(() => onConfirm()).catch((error2) => {
+ return lib.instance.informWireTransfer(state.token, request).then(() => onConfirm()).catch((error2) => {
setNotif({
message: i18n2.str`could not inform transfer`,
type: "ERROR",
@@ -48214,6 +51296,38 @@ function CreateTransfer2({ onConfirm, onBack }) {
init_preact_module();
init_hooks_module();
+// src/hooks/transfer.ts
+var useSWR9 = useSWR;
+function revalidateInstanceTransfers() {
+ return mutate(
+ (key) => Array.isArray(key) && key[key.length - 1] === "listWireTransfers",
+ void 0,
+ { revalidate: true }
+ );
+}
+function useInstanceTransfers(args, updatePosition = () => {
+}) {
+ const { state: session } = useSessionContext();
+ const { lib: { instance } } = useMerchantApiContext();
+ async function fetcher([token, o3, p4, v3]) {
+ return await instance.listWireTransfers(token, {
+ paytoURI: p4,
+ verified: v3,
+ limit: PAGINATED_LIST_REQUEST,
+ offset: o3,
+ order: "dec"
+ });
+ }
+ const { data, error: error2 } = useSWR9([session.token, args?.position, args?.payto_uri, args?.verified, "listWireTransfers"], fetcher);
+ if (error2)
+ return error2;
+ if (data === void 0)
+ return void 0;
+ if (data.type !== "ok")
+ return data;
+ return buildPaginatedResult(data.body.transfers, args?.position, updatePosition, (d5) => String(d5.transfer_serial_id));
+}
+
// src/paths/instance/transfers/list/ListPage.tsx
init_preact_module();
@@ -48225,9 +51339,7 @@ function CardTable7({
onCreate,
onDelete,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -48246,9 +51358,7 @@ function CardTable7({
rowSelection,
rowSelectionHandler,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}
) : /* @__PURE__ */ h(EmptyTable8, null)))));
}
@@ -48256,20 +51366,18 @@ function Table7({
instances,
onLoadMoreAfter,
onDelete,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
- return /* @__PURE__ */ h("div", { class: "table-container" }, hasMoreBefore && /* @__PURE__ */ h(
+ const [settings] = usePreference();
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more transfers before the first one`,
onClick: onLoadMoreBefore
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load newer transfers")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load first page")
), /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "ID")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Credit")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Address")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Exchange URL")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Confirmed")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Verified")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Executed at")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
return /* @__PURE__ */ h("tr", { key: i4.id }, /* @__PURE__ */ h("td", null, i4.id), /* @__PURE__ */ h("td", null, i4.credit_amount), /* @__PURE__ */ h("td", null, i4.payto_uri), /* @__PURE__ */ h("td", null, i4.exchange_url), /* @__PURE__ */ h("td", null, i4.confirmed ? i18n2.str`yes` : i18n2.str`no`), /* @__PURE__ */ h("td", null, i4.verified ? i18n2.str`yes` : i18n2.str`no`), /* @__PURE__ */ h("td", null, i4.execution_time ? i4.execution_time.t_s == "never" ? i18n2.str`never` : format(
i4.execution_time.t_s * 1e3,
@@ -48283,19 +51391,19 @@ function Table7({
},
"Delete"
) : void 0));
- }))), hasMoreAfter && /* @__PURE__ */ h(
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
- "data-tooltip": i18n2.str`load more transfer after the last one`,
+ "data-tooltip": i18n2.str`load more transfers after the last one`,
onClick: onLoadMoreAfter
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load older transfers")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
));
}
function EmptyTable8() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no transfer yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no transfer yet, add more pressing the + sign")));
}
// src/paths/instance/transfers/list/ListPage.tsx
@@ -48329,6 +51437,12 @@ function ListPage6({
name: "payto_uri",
label: i18n2.str`Account URI`,
values: accounts,
+ fromStr: (d5) => {
+ const idx = accounts.indexOf(d5);
+ if (idx === -1)
+ return void 0;
+ return d5;
+ },
placeholder: i18n2.str`Select one account`,
tooltip: i18n2.str`filter by account address`
}
@@ -48365,24 +51479,19 @@ function ListPage6({
onCreate,
onDelete,
onLoadMoreBefore,
- hasMoreBefore: !onLoadMoreBefore,
- onLoadMoreAfter,
- hasMoreAfter: !onLoadMoreAfter
+ onLoadMoreAfter
}
));
}
// src/paths/instance/transfers/list/index.tsx
function ListTransfer({
- onUnauthorized,
- onLoadError,
- onCreate,
- onNotFound
+ onCreate
}) {
const setFilter = (s5) => setForm({ ...form, verified: s5 });
const [position, setPosition] = p3(void 0);
const instance = useInstanceBankAccounts();
- const accounts = !instance.ok ? [] : instance.data.accounts.map((a5) => a5.payto_uri);
+ const accounts = !instance || instance instanceof TalerError || instance.type === "fail" ? [] : instance.body.accounts.map((a5) => a5.payto_uri);
const [form, setForm] = p3({ payto_uri: "" });
const shoulUseDefaultAccount = accounts.length === 1;
h2(() => {
@@ -48390,8 +51499,8 @@ function ListTransfer({
setForm({ ...form, payto_uri: accounts[0] });
}
}, [shoulUseDefaultAccount]);
- const isVerifiedTransfers = form.verified === "yes";
- const isNonVerifiedTransfers = form.verified === "no";
+ const isVerifiedTransfers = form.verified === true;
+ const isNonVerifiedTransfers = form.verified === false;
const isAllTransfers = form.verified === void 0;
const result = useInstanceTransfers(
{
@@ -48401,29 +51510,38 @@ function ListTransfer({
},
(id) => setPosition(id)
);
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(
ListPage6,
{
accounts,
- transfers: result.data.transfers,
- onLoadMoreBefore: result.isReachingStart ? result.loadMorePrev : void 0,
- onLoadMoreAfter: result.isReachingEnd ? result.loadMore : void 0,
+ transfers: result.body,
+ onLoadMoreBefore: result.isFirstPage ? void 0 : result.loadFirst,
+ onLoadMoreAfter: result.isLastPage ? void 0 : result.loadNext,
onCreate,
onDelete: () => {
null;
},
onShowAll: () => setFilter(void 0),
- onShowUnverified: () => setFilter("no"),
- onShowVerified: () => setFilter("yes"),
+ onShowUnverified: () => setFilter(false),
+ onShowVerified: () => setFilter(true),
isAllTransfers,
isVerifiedTransfers,
isNonVerifiedTransfers,
@@ -48454,7 +51572,7 @@ function UpdatePage5({
selected,
onBack
}) {
- const { id } = useInstanceContext();
+ const { state } = useSessionContext();
const [value, valueHandler] = p3(convert2(selected));
const { i18n: i18n2 } = useTranslationContext();
const errors2 = {
@@ -48481,7 +51599,7 @@ function UpdatePage5({
};
await onUpdate(result);
};
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, /* @__PURE__ */ h(i18n2.Translate, null, "Instance id"), ": ", /* @__PURE__ */ h("b", null, id))))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("section", { class: "section" }, /* @__PURE__ */ h("section", { class: "hero is-hero-bar" }, /* @__PURE__ */ h("div", { class: "hero-body" }, /* @__PURE__ */ h("div", { class: "level" }, /* @__PURE__ */ h("div", { class: "level-left" }, /* @__PURE__ */ h("div", { class: "level-item" }, /* @__PURE__ */ h("span", { class: "is-size-4" }, /* @__PURE__ */ h(i18n2.Translate, null, "Instance id"), ": ", /* @__PURE__ */ h("b", null, state.instance))))))), /* @__PURE__ */ h("hr", null), /* @__PURE__ */ h("div", { class: "columns" }, /* @__PURE__ */ h("div", { class: "column" }), /* @__PURE__ */ h("div", { class: "column is-four-fifths" }, /* @__PURE__ */ h(
FormProvider,
{
errors: errors2,
@@ -48510,46 +51628,56 @@ function UpdatePage5({
// src/paths/instance/update/index.tsx
function Update2(props) {
- const { updateInstance } = useInstanceAPI();
+ const { lib } = useMerchantApiContext();
+ const updateInstance = lib.instance.updateCurrentInstance.bind(lib.instance);
const result = useInstanceDetails();
return CommonUpdate(props, result, updateInstance);
}
function AdminUpdate(props) {
- const { updateInstance } = useManagementAPI(
- props.instanceId
- );
+ const { lib } = useMerchantApiContext();
+ const t4 = lib.subInstanceApi(props.instanceId).instance;
+ const updateInstance = t4.updateCurrentInstance.bind(t4);
const result = useManagedInstanceDetails(props.instanceId);
return CommonUpdate(props, result, updateInstance);
}
function CommonUpdate({
onBack,
- onConfirm,
- onLoadError,
- onNotFound,
- onUpdateError,
- onUnauthorized
+ onConfirm
}, result, updateInstance) {
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ const { state } = useSessionContext();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UpdatePage5,
{
onBack,
isLoading: false,
- selected: result.data,
+ selected: result.body,
onUpdate: (d5) => {
- return updateInstance(d5).then(onConfirm).catch(
+ if (state.status !== "loggedIn") {
+ return Promise.resolve();
+ }
+ return updateInstance(state.token, d5).then(onConfirm).catch(
(error2) => setNotif({
- message: i18n2.str`Failed to create instance`,
+ message: i18n2.str`Failed to update instance`,
type: "ERROR",
description: error2.message
})
@@ -48563,101 +51691,6 @@ function CommonUpdate({
init_preact_module();
init_hooks_module();
-// src/hooks/webhooks.ts
-init_hooks_module();
-var useSWR9 = useSWR;
-function useWebhookAPI() {
- const mutateAll = useMatchMutate();
- const { request } = useBackendInstanceRequest();
- const createWebhook = async (data) => {
- const res = await request(`/private/webhooks`, {
- method: "POST",
- data
- });
- await mutateAll(/.*private\/webhooks.*/);
- return res;
- };
- const updateWebhook = async (webhookId, data) => {
- const res = await request(`/private/webhooks/${webhookId}`, {
- method: "PATCH",
- data
- });
- await mutateAll(/.*private\/webhooks.*/);
- return res;
- };
- const deleteWebhook = async (webhookId) => {
- const res = await request(`/private/webhooks/${webhookId}`, {
- method: "DELETE"
- });
- await mutateAll(/.*private\/webhooks.*/);
- return res;
- };
- return { createWebhook, updateWebhook, deleteWebhook };
-}
-function useInstanceWebhooks(args, updatePosition) {
- const { webhookFetcher } = useBackendInstanceRequest();
- const [pageBefore, setPageBefore] = p3(1);
- const [pageAfter, setPageAfter] = p3(1);
- const totalAfter = pageAfter * PAGE_SIZE;
- const totalBefore = args?.position ? pageBefore * PAGE_SIZE : 0;
- const {
- data: afterData,
- error: afterError,
- isValidating: loadingAfter
- } = useSWR9([`/private/webhooks`, args?.position, -totalAfter], webhookFetcher);
- const [lastAfter, setLastAfter] = p3({ loading: true });
- h2(() => {
- if (afterData)
- setLastAfter(afterData);
- }, [afterData]);
- if (afterError)
- return afterError.cause;
- const isReachingEnd = afterData && afterData.data.webhooks.length < totalAfter;
- const isReachingStart = true;
- const pagination = {
- isReachingEnd,
- isReachingStart,
- loadMore: () => {
- if (!afterData || isReachingEnd)
- return;
- if (afterData.data.webhooks.length < MAX_RESULT_SIZE) {
- setPageAfter(pageAfter + 1);
- } else {
- const from = `${afterData.data.webhooks[afterData.data.webhooks.length - 1].webhook_id}`;
- if (from && updatePosition)
- updatePosition(from);
- }
- },
- loadMorePrev: () => {
- return;
- }
- };
- const webhooks = !afterData ? [] : (afterData || lastAfter).data.webhooks;
- if (loadingAfter)
- return { loading: true, data: { webhooks } };
- if (afterData) {
- return { ok: true, data: { webhooks }, ...pagination };
- }
- return { loading: true };
-}
-function useWebhookDetails(webhookId) {
- const { webhookFetcher } = useBackendInstanceRequest();
- const { data, error: error2, isValidating } = useSWR9([`/private/webhooks/${webhookId}`], webhookFetcher, {
- refreshInterval: 0,
- refreshWhenHidden: false,
- revalidateOnFocus: false,
- revalidateOnReconnect: false,
- refreshWhenOffline: false
- });
- if (isValidating)
- return { loading: true, data: data?.data };
- if (data)
- return data;
- if (error2)
- return error2.cause;
- return { loading: true };
-}
-
// src/paths/instance/webhooks/create/CreatePage.tsx
init_preact_module();
init_hooks_module();
@@ -48757,15 +51790,16 @@ function CreatePage8({ onCreate, onBack }) {
// src/paths/instance/webhooks/create/index.tsx
function CreateWebhook({ onConfirm, onBack }) {
- const { createWebhook } = useWebhookAPI();
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
CreatePage8,
{
onBack,
onCreate: (request) => {
- return createWebhook(request).then(() => onConfirm()).catch((error2) => {
+ return lib.instance.addWebhook(state.token, request).then(() => onConfirm()).catch((error2) => {
setNotif({
message: i18n2.str`could not inform template`,
type: "ERROR",
@@ -48793,9 +51827,7 @@ function CardTable8({
onDelete,
onSelect,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const [rowSelection, rowSelectionHandler] = p3([]);
const { i18n: i18n2 } = useTranslationContext();
@@ -48815,9 +51847,7 @@ function CardTable8({
rowSelection,
rowSelectionHandler,
onLoadMoreAfter,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}
) : /* @__PURE__ */ h(EmptyTable9, null)))));
}
@@ -48826,19 +51856,17 @@ function Table8({
onLoadMoreAfter,
onDelete,
onSelect,
- onLoadMoreBefore,
- hasMoreAfter,
- hasMoreBefore
+ onLoadMoreBefore
}) {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "table-container" }, hasMoreBefore && /* @__PURE__ */ h(
+ return /* @__PURE__ */ h("div", { class: "table-container" }, onLoadMoreBefore && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more webhooks before the first one`,
onClick: onLoadMoreBefore
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load newer webhooks")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load first page")
), /* @__PURE__ */ h("table", { class: "table is-fullwidth is-striped is-hoverable is-fullwidth" }, /* @__PURE__ */ h("thead", null, /* @__PURE__ */ h("tr", null, /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "ID")), /* @__PURE__ */ h("th", null, /* @__PURE__ */ h(i18n2.Translate, null, "Event type")), /* @__PURE__ */ h("th", null))), /* @__PURE__ */ h("tbody", null, instances.map((i4) => {
return /* @__PURE__ */ h("tr", { key: i4.webhook_id }, /* @__PURE__ */ h(
"td",
@@ -48863,19 +51891,19 @@ function Table8({
},
"Delete"
))));
- }))), hasMoreAfter && /* @__PURE__ */ h(
+ }))), onLoadMoreAfter && /* @__PURE__ */ h(
"button",
{
class: "button is-fullwidth",
"data-tooltip": i18n2.str`load more webhooks after the last one`,
onClick: onLoadMoreAfter
},
- /* @__PURE__ */ h(i18n2.Translate, null, "load older webhooks")
+ /* @__PURE__ */ h(i18n2.Translate, null, "load next page")
));
}
function EmptyTable9() {
const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-emoticon-sad mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no webhooks yet, add more pressing the + sign")));
+ return /* @__PURE__ */ h("div", { class: "content has-text-grey has-text-centered" }, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h("span", { class: "icon is-large" }, /* @__PURE__ */ h("i", { class: "mdi mdi-magnify mdi-48px" }))), /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "There is no webhooks yet, add more pressing the + sign")));
}
// src/paths/instance/webhooks/list/ListPage.tsx
@@ -48900,57 +51928,60 @@ function ListPage7({
onDelete,
onSelect,
onLoadMoreBefore,
- hasMoreBefore: !onLoadMoreBefore,
- onLoadMoreAfter,
- hasMoreAfter: !onLoadMoreAfter
+ onLoadMoreAfter
}
));
}
// src/paths/instance/webhooks/list/index.tsx
-function ListWebhooks({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound
-}) {
- const [position, setPosition] = p3(void 0);
+function ListWebhooks({ onCreate, onSelect }) {
const { i18n: i18n2 } = useTranslationContext();
const [notif, setNotif] = p3(void 0);
- const { deleteWebhook } = useWebhookAPI();
- const result = useInstanceWebhooks({ position }, (id) => setPosition(id));
- if (result.loading)
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
+ const result = useInstanceWebhooks();
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
ListPage7,
{
- webhooks: result.data.webhooks,
- onLoadMoreBefore: result.isReachingStart ? result.loadMorePrev : void 0,
- onLoadMoreAfter: result.isReachingEnd ? result.loadMore : void 0,
+ webhooks: result.body.webhooks,
+ onLoadMoreBefore: void 0,
+ onLoadMoreAfter: void 0,
onCreate,
onSelect: (e4) => {
onSelect(e4.webhook_id);
},
- onDelete: (e4) => deleteWebhook(e4.webhook_id).then(
- () => setNotif({
- message: i18n2.str`webhook delete successfully`,
- type: "SUCCESS"
- })
- ).catch(
- (error2) => setNotif({
- message: i18n2.str`could not delete the webhook`,
- type: "ERROR",
- description: error2.message
- })
- )
+ onDelete: (e4) => {
+ return lib.instance.deleteWebhook(state.token, e4.webhook_id).then(
+ () => setNotif({
+ message: i18n2.str`webhook delete successfully`,
+ type: "SUCCESS"
+ })
+ ).catch(
+ (error2) => setNotif({
+ message: i18n2.str`could not delete the webhook`,
+ type: "ERROR",
+ description: error2.message
+ })
+ );
+ }
}
));
}
@@ -49043,31 +52074,38 @@ function UpdatePage6({ webhook, onUpdate, onBack }) {
function UpdateWebhook({
tid,
onConfirm,
- onBack,
- onUnauthorized,
- onNotFound,
- onLoadError
+ onBack
}) {
- const { updateWebhook } = useWebhookAPI();
+ const { lib } = useMerchantApiContext();
+ const { state } = useSessionContext();
const result = useWebhookDetails(tid);
const [notif, setNotif] = p3(void 0);
const { i18n: i18n2 } = useTranslationContext();
- if (result.loading)
+ if (!result)
return /* @__PURE__ */ h(Loading, null);
- if (!result.ok) {
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized)
- return onUnauthorized();
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound)
- return onNotFound();
- return onLoadError(result);
+ if (result instanceof TalerError) {
+ return /* @__PURE__ */ h(ErrorLoadingMerchant, { error: result });
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return /* @__PURE__ */ h(NotFoundPageOrAdminCreate, null);
+ }
+ case HttpStatusCode.Unauthorized: {
+ return /* @__PURE__ */ h(LoginPage, null);
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(
UpdatePage6,
{
- webhook: { ...result.data, id: tid },
+ webhook: { ...result.body, id: tid },
onBack,
onUpdate: (data) => {
- return updateWebhook(tid, data).then(onConfirm).catch((error2) => {
+ return lib.instance.updateWebhook(state.token, tid, data).then(onConfirm).catch((error2) => {
setNotif({
message: i18n2.str`could not update template`,
type: "ERROR",
@@ -49079,145 +52117,6 @@ function UpdateWebhook({
));
}
-// src/paths/login/index.tsx
-init_preact_module();
-init_hooks_module();
-function normalizeToken(r3) {
- return `secret-token:${r3}`;
-}
-function LoginPage({ onConfirm }) {
- const { url: backendURL } = useBackendContext();
- const { admin, id } = useInstanceContext();
- const { requestNewLoginToken } = useCredentialsChecker();
- const [token, setToken] = p3("");
- const [notif, setNotif] = p3(void 0);
- const { i18n: i18n2 } = useTranslationContext();
- const doLogin = T2(async function doLoginImpl() {
- const secretToken = normalizeToken(token);
- const baseUrl = id === void 0 ? backendURL : `${backendURL}/instances/${id}`;
- const result = await requestNewLoginToken(baseUrl, secretToken);
- if (result.valid) {
- const { token: token2, expiration } = result;
- onConfirm({ token: token2, expiration });
- } else {
- onConfirm(void 0);
- setNotif({
- message: "Your password is incorrect",
- type: "ERROR"
- });
- }
- }, [id, token]);
- if (admin && id !== "default") {
- return /* @__PURE__ */ h("div", { class: "columns is-centered", style: { margin: "auto" } }, /* @__PURE__ */ h("div", { class: "column is-two-thirds " }, /* @__PURE__ */ h("div", { class: "modal-card", style: { width: "100%", margin: 0 } }, /* @__PURE__ */ h(
- "header",
- {
- class: "modal-card-head",
- style: { border: "1px solid", borderBottom: 0 }
- },
- /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`Login required`)
- ), /* @__PURE__ */ h(
- "section",
- {
- class: "modal-card-body",
- style: { border: "1px solid", borderTop: 0, borderBottom: 0 }
- },
- /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "Need the access token for the instance.")),
- /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access Token"))), /* @__PURE__ */ h("div", { class: "field-body" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control is-expanded" }, /* @__PURE__ */ h(
- "input",
- {
- class: "input",
- type: "password",
- placeholder: "current access token",
- name: "token",
- onKeyPress: (e4) => e4.keyCode === 13 ? doLogin() : null,
- value: token,
- onInput: (e4) => setToken(e4?.currentTarget.value)
- }
- )))))
- ), /* @__PURE__ */ h(
- "footer",
- {
- class: "modal-card-foot ",
- style: {
- justifyContent: "flex-end",
- border: "1px solid",
- borderTop: 0
- }
- },
- /* @__PURE__ */ h(
- AsyncButton2,
- {
- onClick: doLogin
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Confirm")
- )
- ))));
- }
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h("div", { class: "columns is-centered", style: { margin: "auto" } }, /* @__PURE__ */ h("div", { class: "column is-two-thirds " }, /* @__PURE__ */ h("div", { class: "modal-card", style: { width: "100%", margin: 0 } }, /* @__PURE__ */ h(
- "header",
- {
- class: "modal-card-head",
- style: { border: "1px solid", borderBottom: 0 }
- },
- /* @__PURE__ */ h("p", { class: "modal-card-title" }, i18n2.str`Login required`)
- ), /* @__PURE__ */ h(
- "section",
- {
- class: "modal-card-body",
- style: { border: "1px solid", borderTop: 0, borderBottom: 0 }
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Please enter your access token."),
- /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Access Token"))), /* @__PURE__ */ h("div", { class: "field-body" }, /* @__PURE__ */ h("div", { class: "field" }, /* @__PURE__ */ h("p", { class: "control is-expanded" }, /* @__PURE__ */ h(
- "input",
- {
- class: "input",
- type: "password",
- placeholder: "current access token",
- name: "token",
- onKeyPress: (e4) => e4.keyCode === 13 ? doLogin() : null,
- value: token,
- onInput: (e4) => setToken(e4?.currentTarget.value)
- }
- )))))
- ), /* @__PURE__ */ h(
- "footer",
- {
- class: "modal-card-foot ",
- style: {
- justifyContent: "space-between",
- border: "1px solid",
- borderTop: 0
- }
- },
- /* @__PURE__ */ h("div", null),
- /* @__PURE__ */ h(
- AsyncButton2,
- {
- type: "is-info",
- onClick: doLogin
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Confirm")
- )
- )))));
-}
-function AsyncButton2({ onClick, disabled, type = "", children }) {
- const [running, setRunning] = p3(false);
- return /* @__PURE__ */ h("button", { class: "button " + type, disabled: disabled || running, onClick: () => {
- setRunning(true);
- onClick().then(() => {
- setRunning(false);
- }).catch(() => {
- setRunning(false);
- });
- } }, children);
-}
-
-// src/paths/notfound/index.tsx
-init_preact_module();
-function NotFoundPage() {
- return /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("p", null, "That page doesn't exist."), /* @__PURE__ */ h(Link, { href: "/" }, /* @__PURE__ */ h("h4", null, "Back to Home")));
-}
-
// src/paths/settings/index.tsx
init_preact_module();
function getBrowserLang2() {
@@ -49233,12 +52132,14 @@ function Settings({ onClose }) {
const { i18n: i18n2 } = useTranslationContext();
const borwserLang = getBrowserLang2();
const { update } = useLang(void 0, {});
- const [value, updateValue] = useSettings();
+ const [value, , updateValue] = usePreference();
const errors2 = {};
function valueHandler(s5) {
const next = s5(value);
const v3 = {
advanceOrderMode: next.advanceOrderMode ?? false,
+ hideMissingAccountUntil: next.hideMissingAccountUntil ?? AbsoluteTime.never(),
+ hideKycUntil: next.hideKycUntil ?? AbsoluteTime.never(),
dateFormat: next.dateFormat ?? "ymd"
};
updateValue(v3);
@@ -49251,13 +52152,21 @@ function Settings({ onClose }) {
object: value,
valueHandler
},
- /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Language"), /* @__PURE__ */ h("span", { class: "icon has-tooltip-right", "data-tooltip": "Force language setting instance of taking the browser" }, /* @__PURE__ */ h("i", { class: "mdi mdi-information" })))), /* @__PURE__ */ h("div", { class: "field field-body has-addons is-flex-grow-3" }, /* @__PURE__ */ h(LangSelector, null), "\xA0", borwserLang !== void 0 && /* @__PURE__ */ h(
+ /* @__PURE__ */ h("div", { class: "field is-horizontal" }, /* @__PURE__ */ h("div", { class: "field-label is-normal" }, /* @__PURE__ */ h("label", { class: "label" }, /* @__PURE__ */ h(i18n2.Translate, null, "Language"), /* @__PURE__ */ h(
+ "span",
+ {
+ class: "icon has-tooltip-right",
+ "data-tooltip": "Force language setting instance of taking the browser"
+ },
+ /* @__PURE__ */ h("i", { class: "mdi mdi-information" })
+ ))), /* @__PURE__ */ h("div", { class: "field field-body has-addons is-flex-grow-3" }, /* @__PURE__ */ h(LangSelector, null), "\xA0", borwserLang !== void 0 && /* @__PURE__ */ h(
"button",
{
"data-tooltip": i18n2.str`generate random secret key`,
class: "button is-info mr-2",
onClick: (e4) => {
update(borwserLang.substring(0, 2));
+ e4.preventDefault();
}
},
/* @__PURE__ */ h(i18n2.Translate, null, "Set default")
@@ -49286,161 +52195,59 @@ function Settings({ onClose }) {
return "day month year";
return "choose one";
},
- values: [
- "ymd",
- "mdy",
- "dmy"
- ],
+ values: ["ymd", "mdy", "dmy"],
tooltip: i18n2.str`how the date is going to be displayed`
}
)
- ))), /* @__PURE__ */ h("div", { class: "column" }))), onClose && /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h(
- "button",
- {
- class: "button",
- onClick: onClose
- },
- /* @__PURE__ */ h(i18n2.Translate, null, "Close")
- )));
+ ))), /* @__PURE__ */ h("div", { class: "column" }))), onClose && /* @__PURE__ */ h("section", { class: "section is-main-section" }, /* @__PURE__ */ h("button", { class: "button", onClick: onClose }, /* @__PURE__ */ h(i18n2.Translate, null, "Close"))));
}
-// src/InstanceRoutes.tsx
-var noop2 = () => {
+// src/Routing.tsx
+var privatePages = {
+ home: urlPattern(/\/home/, () => "#/home"),
+ go: urlPattern(/\/home/, () => "#/home")
};
-function InstanceRoutes({
- id,
- admin,
- path,
- // onUnauthorized,
- onLoginPass,
- setInstanceName
-}) {
- const [defaultToken, updateDefaultToken] = useBackendDefaultToken();
- const [token, updateToken] = useBackendInstanceToken(id);
- const { i18n: i18n2 } = useTranslationContext();
+var publicPages = {
+ home: urlPattern(/\/home/, () => "#/home"),
+ go: urlPattern(/\/home/, () => "#/home")
+};
+var history2 = createHashHistory();
+function Routing(_p) {
+ const { state } = useSessionContext();
const [globalNotification, setGlobalNotification] = p3(void 0);
- const changeToken = (token2) => {
- if (admin) {
- updateToken(token2);
- } else {
- updateDefaultToken(token2);
- }
- onLoginPass();
- };
const [error2] = P2();
- const value = F(
- () => ({ id, token, admin, changeToken }),
- [id, token, admin]
- );
+ const [preference] = usePreference();
+ const now2 = AbsoluteTime.now();
const instance = useInstanceBankAccounts();
- const accounts = !instance.ok ? void 0 : instance.data.accounts;
- function ServerErrorRedirectTo(to) {
- return function ServerErrorRedirectToImpl(error3) {
- if (error3.type === ErrorType.TIMEOUT) {
- setGlobalNotification({
- message: i18n2.str`The request to the backend take too long and was cancelled`,
- description: i18n2.str`Diagnostic from ${error3.info.url} is "${error3.message}"`,
- type: "ERROR",
- to
- });
- } else {
- setGlobalNotification({
- message: i18n2.str`The backend reported a problem: HTTP status #${error3.status}`,
- description: i18n2.str`Diagnostic from ${error3.info.url} is '${error3.message}'`,
- details: error3.type === ErrorType.CLIENT || error3.type === ErrorType.SERVER ? error3.payload.detail : void 0,
- type: "ERROR",
- to
- });
- }
- return /* @__PURE__ */ h(Redirect, { to });
- };
- }
- const LoginPageAccessDenied = () => {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
- NotificationCard,
+ const accounts = !instance || instance instanceof TalerError || instance.type === "fail" ? void 0 : instance.body;
+ const shouldWarnAboutMissingBankAccounts = !state.isAdmin && accounts !== void 0 && accounts.accounts.length < 1 && (AbsoluteTime.isNever(preference.hideMissingAccountUntil) || AbsoluteTime.cmp(now2, preference.hideMissingAccountUntil) > 1);
+ const shouldLogin = state.status === "loggedOut" || state.status === "expired";
+ if (shouldLogin) {
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Welcome!" }), /* @__PURE__ */ h(LoginPage, null));
+ }
+ if (shouldWarnAboutMissingBankAccounts) {
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(Menu, null), /* @__PURE__ */ h(BankAccountBanner, null), /* @__PURE__ */ h(
+ CreateValidator,
{
- notification: {
- message: i18n2.str`Access denied`,
- description: i18n2.str`Session expired or password changed.`,
- type: "ERROR"
+ onConfirm: () => {
+ route("/bank" /* bank_list */);
}
}
- ), /* @__PURE__ */ h(LoginPage, { onConfirm: changeToken }));
- };
- function IfAdminCreateDefaultOr(Next) {
- return function IfAdminCreateDefaultOrImpl(props) {
- if (admin && id === "default") {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`No 'default' instance configured yet.`,
- description: i18n2.str`Create a 'default' instance to begin using the merchant backoffice.`,
- type: "INFO"
- }
- }
- ), /* @__PURE__ */ h(
- Create,
- {
- forceId: "default",
- onConfirm: () => {
- route("/bank" /* bank_list */);
- }
- }
- ));
- }
- if (props) {
- return /* @__PURE__ */ h(Next, { ...props });
- }
- return /* @__PURE__ */ h(Next, null);
- };
+ ));
}
- const clearTokenAndGoToRoot = () => {
- route("/");
- updateToken(void 0);
- updateDefaultToken(void 0);
- };
- if (accounts !== void 0 && !admin && accounts.length < 1) {
- return /* @__PURE__ */ h(InstanceContextProvider, { value }, /* @__PURE__ */ h(
- Menu,
- {
- instance: id,
- admin,
- onShowSettings: () => {
- route("/interface" /* interface */);
- },
- path,
- onLogout: clearTokenAndGoToRoot,
- setInstanceName,
- isPasswordOk: defaultToken !== void 0
- }
- ), /* @__PURE__ */ h(NotificationCard, { notification: {
- type: "INFO",
- message: i18n2.str`You need to associate a bank account to receive revenue.`,
- description: i18n2.str`Without this the merchant backend will refuse to create new orders.`
- } }), /* @__PURE__ */ h(CreateValidator, { onConfirm: () => {
- } }));
- }
- return /* @__PURE__ */ h(InstanceContextProvider, { value }, /* @__PURE__ */ h(
- Menu,
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(Menu, null), /* @__PURE__ */ h(KycBanner, null), /* @__PURE__ */ h(NotificationCard, { notification: globalNotification }), error2 && /* @__PURE__ */ h(
+ NotificationCard,
{
- instance: id,
- admin,
- onShowSettings: () => {
- route("/interface" /* interface */);
- },
- path,
- onLogout: clearTokenAndGoToRoot,
- setInstanceName,
- isPasswordOk: defaultToken !== void 0
- }
- ), /* @__PURE__ */ h(KycBanner, null), /* @__PURE__ */ h(NotificationCard, { notification: globalNotification }), error2 && /* @__PURE__ */ h(NotificationCard, { notification: {
- message: "Internal error, please repot",
- type: "ERROR",
- description: /* @__PURE__ */ h("pre", null, error2 instanceof Error ? error2.stack : String(error2))
- } }), /* @__PURE__ */ h(
+ notification: {
+ message: "Internal error, please repot",
+ type: "ERROR",
+ description: /* @__PURE__ */ h("pre", null, error2 instanceof Error ? error2.stack : String(error2))
+ }
+ }
+ ), /* @__PURE__ */ h(
Router,
{
+ history: history2,
onChange: (e4) => {
const movingOutFromNotification = globalNotification && e4.url !== globalNotification.to;
if (movingOutFromNotification) {
@@ -49449,7 +52256,7 @@ function InstanceRoutes({
}
},
/* @__PURE__ */ h(Route, { path: "/", component: Redirect, to: "/orders" /* order_list */ }),
- admin && /* @__PURE__ */ h(
+ state.isAdmin && /* @__PURE__ */ h(
Route,
{
path: "/instances" /* list_instances */,
@@ -49457,26 +52264,23 @@ function InstanceRoutes({
onCreate: () => {
route("/instance/new" /* new_instance */);
},
- onUpdate: (id2) => {
- route(`/instance/${id2}/update`);
- },
- setInstanceName,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/error" /* error */)
+ onUpdate: (id) => {
+ route(`/instance/${id}/update`);
+ }
}
),
- admin && /* @__PURE__ */ h(
+ state.isAdmin && /* @__PURE__ */ h(
Route,
{
path: "/instance/new" /* new_instance */,
component: Create,
onBack: () => route("/instances" /* list_instances */),
onConfirm: () => {
- route("/orders" /* order_list */);
+ route("/instances" /* list_instances */);
}
}
),
- admin && /* @__PURE__ */ h(
+ state.isAdmin && /* @__PURE__ */ h(
Route,
{
path: "/instance/:id/update" /* update_instance */,
@@ -49484,10 +52288,7 @@ function InstanceRoutes({
onBack: () => route("/instances" /* list_instances */),
onConfirm: () => {
route("/instances" /* list_instances */);
- },
- onUpdateError: ServerErrorRedirectTo("/instances" /* list_instances */),
- onLoadError: ServerErrorRedirectTo("/instances" /* list_instances */),
- onNotFound: NotFoundPage
+ }
}
),
/* @__PURE__ */ h(
@@ -49500,11 +52301,7 @@ function InstanceRoutes({
},
onConfirm: () => {
route(`/`);
- },
- onUpdateError: noop2,
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/error" /* error */)
+ }
}
),
/* @__PURE__ */ h(
@@ -49517,10 +52314,7 @@ function InstanceRoutes({
},
onCancel: () => {
route("/orders" /* order_list */);
- },
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/error" /* error */)
+ }
}
),
/* @__PURE__ */ h(
@@ -49528,15 +52322,12 @@ function InstanceRoutes({
{
path: "/inventory" /* inventory_list */,
component: ProductList2,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/inventory/new" /* inventory_new */);
},
- onSelect: (id2) => {
- route("/inventory/:pid/update" /* inventory_update */.replace(":pid", id2));
- },
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage)
+ onSelect: (id) => {
+ route("/inventory/:pid/update" /* inventory_update */.replace(":pid", id));
+ }
}
),
/* @__PURE__ */ h(
@@ -49544,15 +52335,12 @@ function InstanceRoutes({
{
path: "/inventory/:pid/update" /* inventory_update */,
component: UpdateProduct,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/inventory" /* inventory_list */),
onConfirm: () => {
route("/inventory" /* inventory_list */);
},
onBack: () => {
route("/inventory" /* inventory_list */);
- },
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage)
+ }
}
),
/* @__PURE__ */ h(
@@ -49573,15 +52361,12 @@ function InstanceRoutes({
{
path: "/bank" /* bank_list */,
component: ListOtpDevices,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/bank/new" /* bank_new */);
},
- onSelect: (id2) => {
- route("/bank/:bid/update" /* bank_update */.replace(":bid", id2));
- },
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage)
+ onSelect: (id) => {
+ route("/bank/:bid/update" /* bank_update */.replace(":bid", id));
+ }
}
),
/* @__PURE__ */ h(
@@ -49589,15 +52374,12 @@ function InstanceRoutes({
{
path: "/bank/:bid/update" /* bank_update */,
component: UpdateValidator,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/inventory" /* inventory_list */),
onConfirm: () => {
route("/bank" /* bank_list */);
},
onBack: () => {
route("/bank" /* bank_list */);
- },
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage)
+ }
}
),
/* @__PURE__ */ h(
@@ -49621,12 +52403,9 @@ function InstanceRoutes({
onCreate: () => {
route("/order/new" /* order_new */);
},
- onSelect: (id2) => {
- route("/order/:oid/details" /* order_details */.replace(":oid", id2));
- },
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage)
+ onSelect: (id) => {
+ route("/order/:oid/details" /* order_details */.replace(":oid", id));
+ }
}
),
/* @__PURE__ */ h(
@@ -49634,9 +52413,6 @@ function InstanceRoutes({
{
path: "/order/:oid/details" /* order_details */,
component: Update,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/orders" /* order_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/orders" /* order_list */);
}
@@ -49660,9 +52436,6 @@ function InstanceRoutes({
{
path: "/transfers" /* transfers_list */,
component: ListTransfer,
- onUnauthorized: LoginPageAccessDenied,
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/transfer/new" /* transfers_new */);
}
@@ -49686,14 +52459,11 @@ function InstanceRoutes({
{
path: "/webhooks" /* webhooks_list */,
component: ListWebhooks,
- onUnauthorized: LoginPageAccessDenied,
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/webhooks/new" /* webhooks_new */);
},
- onSelect: (id2) => {
- route("/webhooks/:tid/update" /* webhooks_update */.replace(":tid", id2));
+ onSelect: (id) => {
+ route("/webhooks/:tid/update" /* webhooks_update */.replace(":tid", id));
}
}
),
@@ -49705,9 +52475,6 @@ function InstanceRoutes({
onConfirm: () => {
route("/webhooks" /* webhooks_list */);
},
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/webhooks" /* webhooks_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/webhooks" /* webhooks_list */);
}
@@ -49731,14 +52498,11 @@ function InstanceRoutes({
{
path: "/otp-devices" /* otp_devices_list */,
component: ListOtpDevices2,
- onUnauthorized: LoginPageAccessDenied,
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/otp-devices/new" /* otp_devices_new */);
},
- onSelect: (id2) => {
- route("/otp-devices/:vid/update" /* otp_devices_update */.replace(":vid", id2));
+ onSelect: (id) => {
+ route("/otp-devices/:vid/update" /* otp_devices_update */.replace(":vid", id));
}
}
),
@@ -49750,9 +52514,6 @@ function InstanceRoutes({
onConfirm: () => {
route("/otp-devices" /* otp_devices_list */);
},
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/otp-devices" /* otp_devices_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/otp-devices" /* otp_devices_list */);
}
@@ -49776,20 +52537,17 @@ function InstanceRoutes({
{
path: "/templates" /* templates_list */,
component: ListTemplates,
- onUnauthorized: LoginPageAccessDenied,
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
- onLoadError: ServerErrorRedirectTo("/settings" /* settings */),
onCreate: () => {
route("/templates/new" /* templates_new */);
},
- onNewOrder: (id2) => {
- route("/templates/:tid/use" /* templates_use */.replace(":tid", id2));
+ onNewOrder: (id) => {
+ route("/templates/:tid/use" /* templates_use */.replace(":tid", id));
},
- onQR: (id2) => {
- route("/templates/:tid/qr" /* templates_qr */.replace(":tid", id2));
+ onQR: (id) => {
+ route("/templates/:tid/qr" /* templates_qr */.replace(":tid", id));
},
- onSelect: (id2) => {
- route("/templates/:tid/update" /* templates_update */.replace(":tid", id2));
+ onSelect: (id) => {
+ route("/templates/:tid/update" /* templates_update */.replace(":tid", id));
}
}
),
@@ -49801,9 +52559,6 @@ function InstanceRoutes({
onConfirm: () => {
route("/templates" /* templates_list */);
},
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/templates" /* templates_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/templates" /* templates_list */);
}
@@ -49827,12 +52582,9 @@ function InstanceRoutes({
{
path: "/templates/:tid/use" /* templates_use */,
component: TemplateUsePage,
- onOrderCreated: (id2) => {
- route("/order/:oid/details" /* order_details */.replace(":oid", id2));
+ onOrderCreated: (id) => {
+ route("/order/:oid/details" /* order_details */.replace(":oid", id));
},
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/templates" /* templates_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/templates" /* templates_list */);
}
@@ -49843,9 +52595,6 @@ function InstanceRoutes({
{
path: "/templates/:tid/qr" /* templates_qr */,
component: TemplateQrPage,
- onUnauthorized: LoginPageAccessDenied,
- onLoadError: ServerErrorRedirectTo("/templates" /* templates_list */),
- onNotFound: IfAdminCreateDefaultOr(NotFoundPage),
onBack: () => {
route("/templates" /* templates_list */);
}
@@ -49867,263 +52616,398 @@ function AdminInstanceUpdatePage({
id,
...rest
}) {
- const [token, changeToken] = useBackendInstanceToken(id);
- const updateLoginStatus = (token2) => {
- changeToken(token2);
- };
- const value = F(
- () => ({ id, token, admin: true, changeToken }),
- [id, token]
- );
- const { i18n: i18n2 } = useTranslationContext();
- return /* @__PURE__ */ h(InstanceContextProvider, { value }, /* @__PURE__ */ h(
+ return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
AdminUpdate,
{
...rest,
- instanceId: id,
- onLoadError: (error2) => {
- const notif = error2.type === ErrorType.TIMEOUT ? {
- message: i18n2.str`The request to the backend take too long and was cancelled`,
- description: i18n2.str`Diagnostic from ${error2.info.url} is '${error2.message}'`,
- type: "ERROR"
- } : {
- message: i18n2.str`The backend reported a problem: HTTP status #${error2.status}`,
- description: i18n2.str`Diagnostic from ${error2.info.url} is '${error2.message}'`,
- details: error2.type === ErrorType.CLIENT || error2.type === ErrorType.SERVER ? error2.payload.detail : void 0,
- type: "ERROR"
- };
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotificationCard, { notification: notif }), /* @__PURE__ */ h(LoginPage, { onConfirm: updateLoginStatus }));
- },
- onUnauthorized: () => {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(
- NotificationCard,
+ instanceId: id
+ }
+ ));
+}
+function BankAccountBanner() {
+ const { i18n: i18n2 } = useTranslationContext();
+ const [, updatePref] = usePreference();
+ const now2 = AbsoluteTime.now();
+ const oneDay = { d_ms: 1e3 * 60 * 60 * 24 };
+ const tomorrow = AbsoluteTime.addDuration(now2, oneDay);
+ return /* @__PURE__ */ h(
+ NotificationCard,
+ {
+ notification: {
+ type: "INFO",
+ message: i18n2.str`You need to associate a bank account to receive revenue.`,
+ description: /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "Without this the merchant backend will refuse to create new orders.")), /* @__PURE__ */ h("div", { class: "buttons is-right" }, /* @__PURE__ */ h(
+ "button",
{
- notification: {
- message: i18n2.str`Access denied`,
- description: i18n2.str`The access token provided is invalid`,
- type: "ERROR"
- }
- }
- ), /* @__PURE__ */ h(LoginPage, { onConfirm: updateLoginStatus }));
+ class: "button",
+ onClick: () => updatePref("hideMissingAccountUntil", tomorrow)
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Hide for today")
+ )))
}
}
- ));
+ );
}
function KycBanner() {
const kycStatus = useInstanceKYCDetails();
const { i18n: i18n2 } = useTranslationContext();
- const [settings] = useSettings();
- const today = format(/* @__PURE__ */ new Date(), dateFormatForSettings(settings));
- const [lastHide, setLastHide] = useSimpleLocalStorage("kyc-last-hide");
- const hasBeenHidden = today === lastHide;
- const needsToBeShown = kycStatus.ok && kycStatus.data.type === "redirect";
- if (hasBeenHidden || !needsToBeShown)
+ const [prefs, updatePref] = usePreference();
+ const now2 = AbsoluteTime.now();
+ const needsToBeShown = kycStatus !== void 0 && !(kycStatus instanceof TalerError) && kycStatus.type === "ok" && !!kycStatus.body;
+ const hidden = AbsoluteTime.cmp(now2, prefs.hideKycUntil) < 1;
+ if (hidden || !needsToBeShown)
return /* @__PURE__ */ h(p2, null);
+ const oneDay = { d_ms: 1e3 * 60 * 60 * 24 };
+ const tomorrow = AbsoluteTime.addDuration(now2, oneDay);
return /* @__PURE__ */ h(
NotificationCard,
{
notification: {
type: "WARN",
message: "KYC verification needed",
- description: /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("p", null, "Some transfer are on hold until a KYC process is completed. Go to the KYC section in the left panel for more information"), /* @__PURE__ */ h("div", { class: "buttons is-right" }, /* @__PURE__ */ h("button", { class: "button", onClick: () => setLastHide(today) }, /* @__PURE__ */ h(i18n2.Translate, null, "Hide for today"))))
+ description: /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("p", null, /* @__PURE__ */ h(i18n2.Translate, null, "Some transfer are on hold until a KYC process is completed. Go to the KYC section in the left panel for more information")), /* @__PURE__ */ h("div", { class: "buttons is-right" }, /* @__PURE__ */ h(
+ "button",
+ {
+ class: "button",
+ onClick: () => updatePref("hideKycUntil", tomorrow)
+ },
+ /* @__PURE__ */ h(i18n2.Translate, null, "Hide for today")
+ )))
}
}
);
}
-// src/ApplicationReadyRoutes.tsx
-function ApplicationReadyRoutes() {
- const { i18n: i18n2 } = useTranslationContext();
- const [unauthorized, setUnauthorized] = p3(false);
- const {
- url: backendURL,
- updateToken,
- alreadyTriedLogin
- } = useBackendContext();
- function updateLoginStatus(token) {
- updateToken(token);
- setUnauthorized(false);
- }
- const result = useBackendInstancesTestForAdmin();
- const clearTokenAndGoToRoot = () => {
- route("/");
- };
- const [showSettings, setShowSettings] = p3(false);
- const unauthorizedAdmin = !result.loading && !result.ok && result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized;
- if (!alreadyTriedLogin && !result.ok) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Welcome!" }), /* @__PURE__ */ h(LoginPage, { onConfirm: updateToken }));
- }
- if (showSettings) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotYetReadyAppMenu, { onShowSettings: () => setShowSettings(true), title: "UI Settings", onLogout: clearTokenAndGoToRoot, isPasswordOk: false }), /* @__PURE__ */ h(Settings, { onClose: () => setShowSettings(false) }));
- }
- if (result.loading) {
- return /* @__PURE__ */ h(NotYetReadyAppMenu, { onShowSettings: () => setShowSettings(true), title: "Loading...", isPasswordOk: false });
- }
- let admin = result.ok || unauthorizedAdmin;
- let instanceNameByBackendURL;
- if (!admin) {
- const path = new URL(backendURL).pathname;
- const match6 = INSTANCE_ID_LOOKUP.exec(path);
- if (!match6 || !match6[1]) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotYetReadyAppMenu, { onShowSettings: () => setShowSettings(true), title: "Error", onLogout: clearTokenAndGoToRoot, isPasswordOk: false }), /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`Couldn't access the server.`,
- description: i18n2.str`Could not infer instance id from url ${backendURL}`,
- type: "ERROR"
- }
- }
- ));
+// src/context/settings.ts
+init_preact_module();
+init_hooks_module();
+var initial2 = {};
+var Context5 = B(initial2);
+var SettingsProvider = ({
+ children,
+ value
+}) => {
+ return h(Context5.Provider, {
+ value,
+ children
+ });
+};
+
+// src/settings.ts
+var defaultSettings2 = {
+ backendBaseURL: buildDefaultBackendBaseURL()
+};
+var codecForBankUISettings = () => buildCodecForObject().property("backendBaseURL", codecOptional(codecForString())).build("MerchantUiSettings");
+function removeUndefineField(obj) {
+ const keys = Object.keys(obj);
+ return keys.reduce((prev, cur) => {
+ if (typeof prev[cur] === "undefined") {
+ delete prev[cur];
}
- instanceNameByBackendURL = match6[1];
+ return prev;
+ }, obj);
+}
+function fetchSettings(listener) {
+ fetch("./settings.json").then((resp) => resp.json()).then((json) => codecForBankUISettings().decode(json)).then(
+ (result) => listener({
+ ...defaultSettings2,
+ ...removeUndefineField(result)
+ })
+ ).catch((e4) => {
+ console.log("failed to fetch settings", e4);
+ listener(defaultSettings2);
+ });
+}
+function buildDefaultBackendBaseURL() {
+ if (typeof window !== "undefined") {
+ const currentLocation = new URL(
+ window.location.pathname,
+ window.location.origin
+ ).href;
+ return canonicalizeBaseUrl(currentLocation.replace("/webui", ""));
}
- if (unauthorized || unauthorizedAdmin) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotYetReadyAppMenu, { onShowSettings: () => setShowSettings(true), title: "Login", onLogout: clearTokenAndGoToRoot, isPasswordOk: false }), /* @__PURE__ */ h(
- NotificationCard,
+ throw Error("No default URL");
+}
+
+// src/Application.tsx
+var WITH_LOCAL_STORAGE_CACHE = false;
+function Application() {
+ const [settings, setSettings] = p3();
+ h2(() => {
+ fetchSettings(setSettings);
+ }, []);
+ if (!settings)
+ return /* @__PURE__ */ h(Loading, null);
+ const baseUrl = getInitialBackendBaseURL(settings.backendBaseURL);
+ return /* @__PURE__ */ h(SettingsProvider, { value: settings }, /* @__PURE__ */ h(
+ TranslationProvider,
+ {
+ source: strings,
+ completeness: {
+ es: strings["es"].completeness,
+ de: strings["de"].completeness
+ }
+ },
+ /* @__PURE__ */ h(MerchantApiProvider, { baseUrl: new URL("./", baseUrl), frameOnError: OnConfigError, evictors: {
+ management: swrCacheEvictor
+ } }, /* @__PURE__ */ h(
+ SWRConfig2,
{
- notification: {
- message: i18n2.str`Access denied`,
- description: i18n2.str`Check your token is valid`,
- type: "ERROR"
+ value: {
+ provider: WITH_LOCAL_STORAGE_CACHE ? localStorageProvider : void 0,
+ // normally, do not revalidate
+ revalidateOnFocus: false,
+ revalidateOnReconnect: false,
+ revalidateIfStale: false,
+ revalidateOnMount: void 0,
+ focusThrottleInterval: void 0,
+ // normally, do not refresh
+ refreshInterval: void 0,
+ dedupingInterval: 2e3,
+ refreshWhenHidden: false,
+ refreshWhenOffline: false,
+ // ignore errors
+ shouldRetryOnError: false,
+ errorRetryCount: 0,
+ errorRetryInterval: void 0,
+ // do not go to loading again if already has data
+ keepPreviousData: true
}
- }
- ), /* @__PURE__ */ h(LoginPage, { onConfirm: updateLoginStatus }));
- }
- const history2 = createHashHistory();
- return /* @__PURE__ */ h(Router, { history: history2 }, /* @__PURE__ */ h(
- Route,
- {
- default: true,
- component: DefaultMainRoute,
- admin,
- onUnauthorized: () => setUnauthorized(true),
- onLoginPass: () => {
- setUnauthorized(false);
},
- instanceNameByBackendURL
- }
+ /* @__PURE__ */ h(TalerWalletIntegrationBrowserProvider, null, /* @__PURE__ */ h(BrowserHashNavigationProvider, null, /* @__PURE__ */ h(Routing, null)))
+ ))
));
}
-function DefaultMainRoute({
- instance,
- admin,
- onUnauthorized,
- onLoginPass,
- instanceNameByBackendURL,
- url
- //from preact-router
-}) {
- const [instanceName, setInstanceName] = p3(
- instanceNameByBackendURL || instance || "default"
- );
- return /* @__PURE__ */ h(
- InstanceRoutes,
- {
- admin,
- path: url,
- onUnauthorized,
- onLoginPass,
- id: instanceName,
- setInstanceName
+function getInitialBackendBaseURL(backendFromSettings) {
+ const overrideUrl = typeof localStorage !== "undefined" ? localStorage.getItem("merchant-base-url") : void 0;
+ let result;
+ if (overrideUrl) {
+ result = overrideUrl;
+ } else {
+ if (!backendFromSettings) {
+ console.error(
+ "ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'"
+ );
+ result = buildDefaultBackendBaseURL();
+ } else {
+ result = backendFromSettings;
}
- );
+ }
+ try {
+ return canonicalizeBaseUrl(result);
+ } catch (e4) {
+ return canonicalizeBaseUrl(window.origin);
+ }
}
-
-// src/Application.tsx
-function Application() {
- return /* @__PURE__ */ h(BackendContextProvider, null, /* @__PURE__ */ h(TranslationProvider, { source: strings }, /* @__PURE__ */ h(ApplicationStatusRoutes, null)));
+function localStorageProvider() {
+ const map3 = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
+ window.addEventListener("beforeunload", () => {
+ const appCache = JSON.stringify(Array.from(map3.entries()));
+ localStorage.setItem("app-cache", appCache);
+ });
+ return map3;
}
-function ApplicationStatusRoutes() {
- const result = useBackendConfig();
+function OnConfigError({ state }) {
const { i18n: i18n2 } = useTranslationContext();
- const configData = result.ok && result.data ? result.data : void 0;
- const ctx = F(() => configData, [configData]);
- if (!result.ok) {
- if (result.loading)
- return /* @__PURE__ */ h(Loading, null);
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.Unauthorized) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Login" }), /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`Checking the /config endpoint got authorization error`,
- type: "ERROR",
- description: `The /config endpoint of the backend server should be accessible`
- }
- }
- ));
- }
- if (result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Error" }), /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`Could not find /config endpoint on this URL`,
- type: "ERROR",
- description: `Check the URL or contact the system administrator.`
- }
- }
- ));
- }
- if (result.type === ErrorType.SERVER) {
- /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Error" }), /* @__PURE__ */ h(
+ if (!state) {
+ return /* @__PURE__ */ h(i18n2.Translate, null, "checking compatibility with server...");
+ }
+ switch (state.type) {
+ case "error": {
+ return /* @__PURE__ */ h(
NotificationCard,
{
notification: {
- message: i18n2.str`Server response with an error code`,
- type: "ERROR",
- description: i18n2.str`Got message "${result.message}" from ${result.info?.url}`
+ message: i18n2.str`Contacting the server failed`,
+ description: state.error.message,
+ details: JSON.stringify(state.error.errorDetail, void 0, 2),
+ type: "ERROR"
}
}
- ));
+ );
}
- if (result.type === ErrorType.UNREADABLE) {
- /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Error" }), /* @__PURE__ */ h(
+ case "incompatible": {
+ return /* @__PURE__ */ h(
NotificationCard,
{
notification: {
- message: i18n2.str`Response from server is unreadable, http status: ${result.status}`,
- type: "ERROR",
- description: i18n2.str`Got message "${result.message}" from ${result.info?.url}`
+ message: i18n2.str`The server version is not supported`,
+ description: i18n2.str`Supported version "${state.supported}", server version "${state.result.version}".`,
+ type: "WARN"
}
}
- ));
+ );
}
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Error" }), /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`Unexpected Error`,
- type: "ERROR",
- description: i18n2.str`Got message "${result.message}" from ${result.info?.url}`
- }
- }
- ));
+ default:
+ assertUnreachable(state);
}
- const SUPPORTED_VERSION = "8:1:4";
- if (result.data && !LibtoolVersion.compare(
- SUPPORTED_VERSION,
- result.data.version
- )?.compatible) {
- return /* @__PURE__ */ h(p2, null, /* @__PURE__ */ h(NotConnectedAppMenu, { title: "Error" }), /* @__PURE__ */ h(
- NotificationCard,
- {
- notification: {
- message: i18n2.str`Incompatible version`,
- type: "ERROR",
- description: i18n2.str`Merchant backend server version ${result.data.version} is not compatible with the supported version ${SUPPORTED_VERSION}`
- }
+}
+var swrCacheEvictor = new class {
+ async notifySuccess(op) {
+ switch (op) {
+ case TalerMerchantManagementCacheEviction.CREATE_INSTANCE: {
+ await Promise.all([
+ revalidateBackendInstances()
+ ]);
+ return;
}
- ));
+ case TalerMerchantManagementCacheEviction.UPDATE_INSTANCE: {
+ await Promise.all([
+ revalidateManagedInstanceDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantManagementCacheEviction.DELETE_INSTANCE: {
+ await Promise.all([
+ revalidateBackendInstances()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_CURRENT_INSTANCE: {
+ await Promise.all([
+ revalidateInstanceDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_CURRENT_INSTANCE: {
+ await Promise.all([
+ revalidateInstanceDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_BANK_ACCOUNT: {
+ await Promise.all([
+ revalidateInstanceBankAccounts()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_BANK_ACCOUNT: {
+ await Promise.all([
+ revalidateBankAccountDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_BANK_ACCOUNT: {
+ await Promise.all([
+ revalidateInstanceBankAccounts()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_PRODUCT: {
+ await Promise.all([
+ revalidateInstanceProducts()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_PRODUCT: {
+ await Promise.all([
+ revalidateProductDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_PRODUCT: {
+ await Promise.all([
+ revalidateInstanceProducts()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_TRANSFER: {
+ await Promise.all([
+ revalidateInstanceTransfers()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_TRANSFER: {
+ await Promise.all([
+ revalidateInstanceTransfers()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_DEVICE: {
+ await Promise.all([
+ revalidateInstanceOtpDevices()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_DEVICE: {
+ await Promise.all([
+ revalidateOtpDeviceDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_DEVICE: {
+ await Promise.all([
+ revalidateInstanceOtpDevices()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_TEMPLATE: {
+ await Promise.all([
+ revalidateInstanceTemplates()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_TEMPLATE: {
+ await Promise.all([
+ revalidateTemplateDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_TEMPLATE: {
+ await Promise.all([
+ revalidateInstanceTemplates()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_WEBHOOK: {
+ await Promise.all([
+ revalidateInstanceWebhooks()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_WEBHOOK: {
+ await Promise.all([
+ revalidateWebhookDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_WEBHOOK: {
+ await Promise.all([
+ revalidateInstanceWebhooks()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.CREATE_ORDER: {
+ await Promise.all([
+ revalidateInstanceOrders()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.UPDATE_ORDER: {
+ await Promise.all([
+ revalidateOrderDetails()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.DELETE_ORDER: {
+ await Promise.all([
+ revalidateInstanceOrders()
+ ]);
+ return;
+ }
+ case TalerMerchantInstanceCacheEviction.LAST:
+ }
}
- return /* @__PURE__ */ h("div", { class: "has-navbar-fixed-top" }, /* @__PURE__ */ h(ConfigContextProvider, { value: ctx }, /* @__PURE__ */ h(ApplicationReadyRoutes, null)));
-}
+}();
// src/index.tsx
init_preact_module();
var app = document.getElementById("app");
-P(/* @__PURE__ */ h(Application, null), app);
+if (app) {
+ P(/* @__PURE__ */ h(Application, null), app);
+} else {
+ console.error("HTML element with id 'app' not found.");
+}
/*! Bundled license information:
jed/jed.js: