@voltro/plugin-economy 0.0.0-stage → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24329 -0
- package/LICENSE +61 -0
- package/README.md +2719 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +9189 -0
- package/dist/amount.js +21 -0
- package/dist/appleIap.server.js +263 -0
- package/dist/appleIapNotifications.server.js +163 -0
- package/dist/appleIapTrust.server.js +31 -0
- package/dist/bundleValue.server.js +113 -0
- package/dist/canonicalDataJson.js +11 -0
- package/dist/capture.js +54 -0
- package/dist/codePort.fixture.js +124 -0
- package/dist/codeStore.server.js +440 -0
- package/dist/codeTables.entity.js +44 -0
- package/dist/codes.d.ts +150 -0
- package/dist/codes.js +83 -0
- package/dist/components.d.ts +397 -0
- package/dist/components.js +284 -0
- package/dist/consistency.server.js +116 -0
- package/dist/containerStore.server.js +688 -0
- package/dist/containerStore.testFixtures.js +76 -0
- package/dist/containerTables.entity.js +46 -0
- package/dist/containers.d.ts +311 -0
- package/dist/containers.fixture.js +129 -0
- package/dist/containers.js +215 -0
- package/dist/containers.server.js +40 -0
- package/dist/containersPort.fixture.js +75 -0
- package/dist/currency.js +33 -0
- package/dist/declarationFixtures.js +62 -0
- package/dist/economy-app/events/economy.refundReversed.event.ts +1 -0
- package/dist/economy-app/events/economy.refunded.event.ts +1 -0
- package/dist/economyPort.fixture.js +125 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +22 -0
- package/dist/events.d.ts +46 -0
- package/dist/events.js +1 -0
- package/dist/googleIap.server.js +392 -0
- package/dist/googleIapNotifications.server.js +131 -0
- package/dist/googleIapSubscription.server.js +184 -0
- package/dist/iap.d.ts +309 -0
- package/dist/iap.js +304 -0
- package/dist/iap.testFixtures.js +145 -0
- package/dist/iapAccountTables.entity.js +40 -0
- package/dist/iapAccounts.server.js +201 -0
- package/dist/iapBinding.server.js +524 -0
- package/dist/iapCheckout.server.js +98 -0
- package/dist/iapCompletion.server.js +56 -0
- package/dist/iapCurrentState.server.js +108 -0
- package/dist/iapCurrentState.testFixtures.js +23 -0
- package/dist/iapCurrentStatePort.fixture.js +64 -0
- package/dist/iapEntitlements.d.ts +79 -0
- package/dist/iapEntitlements.js +58 -0
- package/dist/iapEntitlements.server.js +49 -0
- package/dist/iapEntitlementsBinding.server.js +106 -0
- package/dist/iapEntitlementsPort.fixture.js +81 -0
- package/dist/iapInstalledEntitlements.testFixtures.js +76 -0
- package/dist/iapInstalledNotifications.testFixtures.js +94 -0
- package/dist/iapInventoryRefunds.server.js +262 -0
- package/dist/iapNotificationCustodyPort.fixture.js +68 -0
- package/dist/iapNotificationPort.fixture.js +74 -0
- package/dist/iapNotificationProcessor.server.js +135 -0
- package/dist/iapNotificationProcessor.testFixtures.js +64 -0
- package/dist/iapNotificationProcessorPort.fixture.js +56 -0
- package/dist/iapNotificationSchedule.server.js +70 -0
- package/dist/iapNotificationStore.server.js +353 -0
- package/dist/iapNotificationStore.testFixtures.js +32 -0
- package/dist/iapNotificationTables.entity.js +49 -0
- package/dist/iapNotificationTarget.server.js +37 -0
- package/dist/iapNotificationTarget.testFixtures.js +30 -0
- package/dist/iapNotifications.d.ts +644 -0
- package/dist/iapNotifications.js +6 -0
- package/dist/iapNotifications.server.js +96 -0
- package/dist/iapNotificationsBinding.server.js +233 -0
- package/dist/iapNotificationsSystemPort.fixture.js +51 -0
- package/dist/iapPlugin.testFixtures.js +60 -0
- package/dist/iapPort.fixture.js +75 -0
- package/dist/iapProviderCapture.server.js +18 -0
- package/dist/iapRecovery.d.ts +146 -0
- package/dist/iapRecovery.js +90 -0
- package/dist/iapRefundEventDelivery.server.js +83 -0
- package/dist/iapRefundEvents.js +45 -0
- package/dist/iapRefundEventsPort.fixture.js +60 -0
- package/dist/iapRefundPort.fixture.js +55 -0
- package/dist/iapRefundTables.entity.js +56 -0
- package/dist/iapRefunds.d.ts +755 -0
- package/dist/iapRefunds.js +6 -0
- package/dist/iapRefunds.server.js +554 -0
- package/dist/iapRefunds.testFixtures.js +65 -0
- package/dist/iapSpendAdmission.server.js +99 -0
- package/dist/iapStore.server.js +741 -0
- package/dist/iapStore.testFixtures.js +128 -0
- package/dist/iapTables.entity.js +81 -0
- package/dist/iapVerification.server.js +121 -0
- package/dist/index.d.ts +2984 -0
- package/dist/index.js +15 -0
- package/dist/intentionRecovery.js +134 -0
- package/dist/ledger.js +78 -0
- package/dist/loyalty.d.ts +274 -0
- package/dist/loyalty.fixture.js +93 -0
- package/dist/loyalty.js +312 -0
- package/dist/loyaltyBinding.server.js +204 -0
- package/dist/loyaltyPort.fixture.js +87 -0
- package/dist/loyaltyShopSource.server.js +91 -0
- package/dist/loyaltyStore.server.js +553 -0
- package/dist/loyaltyStore.testFixtures.js +83 -0
- package/dist/loyaltyTables.entity.js +50 -0
- package/dist/offerMerchandising.fixture.js +115 -0
- package/dist/offerMerchandising.js +283 -0
- package/dist/offerPolicies.d.ts +441 -0
- package/dist/offerPolicies.fixture.js +54 -0
- package/dist/offerPolicies.js +268 -0
- package/dist/piggyBanks.d.ts +272 -0
- package/dist/piggyBanks.fixture.js +71 -0
- package/dist/piggyBanks.js +201 -0
- package/dist/piggyBinding.server.js +205 -0
- package/dist/piggyPort.fixture.js +73 -0
- package/dist/piggyStore.server.js +611 -0
- package/dist/piggyStore.testFixtures.js +98 -0
- package/dist/piggyTables.entity.js +41 -0
- package/dist/plugin.js +1048 -0
- package/dist/port.js +13 -0
- package/dist/price.d.ts +99 -0
- package/dist/price.js +144 -0
- package/dist/purchaseRecovery.js +56 -0
- package/dist/reports.server.js +115 -0
- package/dist/rpc.d.ts +3201 -0
- package/dist/rpc.js +1201 -0
- package/dist/sanctionsTradeAuthority.server.js +80 -0
- package/dist/server.d.ts +3856 -0
- package/dist/server.js +43 -0
- package/dist/shop.d.ts +279 -0
- package/dist/shop.js +196 -0
- package/dist/shop.testFixtures.js +114 -0
- package/dist/shopPort.fixture.js +72 -0
- package/dist/shopPresentation.js +68 -0
- package/dist/shopStore.server.js +624 -0
- package/dist/shopTables.entity.js +63 -0
- package/dist/shopUiCopy.js +57 -0
- package/dist/spendLimits.d.ts +140 -0
- package/dist/spendLimits.fixture.js +53 -0
- package/dist/spendLimits.js +155 -0
- package/dist/spendLimitsPort.fixture.js +120 -0
- package/dist/subscriptionBinding.server.js +211 -0
- package/dist/subscriptionStore.server.js +643 -0
- package/dist/subscriptionStore.testFixtures.js +72 -0
- package/dist/subscriptionTables.entity.js +37 -0
- package/dist/subscriptions.d.ts +394 -0
- package/dist/subscriptions.fixture.js +97 -0
- package/dist/subscriptions.js +213 -0
- package/dist/subscriptionsPort.fixture.js +76 -0
- package/dist/systemFixtures.js +89 -0
- package/dist/tables.entity.js +83 -0
- package/dist/testing.d.ts +4615 -0
- package/dist/testing.js +29 -0
- package/dist/tradeAuthority.server.js +172 -0
- package/dist/tradeBinding.server.js +201 -0
- package/dist/tradeComponents.js +342 -0
- package/dist/tradeEscrow.server.js +232 -0
- package/dist/tradeEscrow.testFixtures.js +133 -0
- package/dist/tradeExpiry.server.js +43 -0
- package/dist/tradeRecovery.js +48 -0
- package/dist/tradeStore.server.js +750 -0
- package/dist/tradeStore.testFixtures.js +73 -0
- package/dist/tradeTables.entity.js +66 -0
- package/dist/tradeUiCopy.js +79 -0
- package/dist/trades.d.ts +246 -0
- package/dist/trades.fixture.js +103 -0
- package/dist/trades.js +289 -0
- package/dist/tradesPort.fixture.js +94 -0
- package/dist/walletEscrow.js +106 -0
- package/dist/walletEscrow.server.js +376 -0
- package/dist/walletKeys.server.js +5 -0
- package/dist/walletStore.js +571 -0
- package/dist/web.d.ts +2257 -0
- package/dist/web.js +9 -0
- package/package.json +161 -4
package/dist/loyalty.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { captureBoundMethods as t, dataList as n, dataObject as r, identifier as i } from "./capture.js";
|
|
3
|
+
import { economyAmount as a, nonNegativeAmount as o, positiveAmount as s } from "./amount.js";
|
|
4
|
+
import { captureCurrencies as c } from "./currency.js";
|
|
5
|
+
import { defineShopOffer as l, shopInteger as u } from "./shop.js";
|
|
6
|
+
import { Context as d } from "effect";
|
|
7
|
+
//#region src/loyalty.ts
|
|
8
|
+
var f = (t, n) => {
|
|
9
|
+
let a = r(t, [
|
|
10
|
+
"id",
|
|
11
|
+
"kind",
|
|
12
|
+
"bps",
|
|
13
|
+
"badgeId",
|
|
14
|
+
"items",
|
|
15
|
+
"currencies"
|
|
16
|
+
]), o = i(a.id);
|
|
17
|
+
if (a.kind === "xpMultiplier" || a.kind === "discount") return r(t, [
|
|
18
|
+
"id",
|
|
19
|
+
"kind",
|
|
20
|
+
"bps"
|
|
21
|
+
]), Object.freeze({
|
|
22
|
+
id: o,
|
|
23
|
+
kind: a.kind,
|
|
24
|
+
bps: u(a.bps, +(a.kind === "xpMultiplier"), a.kind === "xpMultiplier" ? 1e5 : 1e4)
|
|
25
|
+
});
|
|
26
|
+
if (a.kind === "chatBadge") return r(t, [
|
|
27
|
+
"id",
|
|
28
|
+
"kind",
|
|
29
|
+
"badgeId"
|
|
30
|
+
]), Object.freeze({
|
|
31
|
+
id: o,
|
|
32
|
+
kind: "chatBadge",
|
|
33
|
+
badgeId: i(a.badgeId)
|
|
34
|
+
});
|
|
35
|
+
if (a.kind !== "inboxGift") throw e("invalid_input");
|
|
36
|
+
r(t, [
|
|
37
|
+
"id",
|
|
38
|
+
"kind",
|
|
39
|
+
"items",
|
|
40
|
+
"currencies"
|
|
41
|
+
]);
|
|
42
|
+
let s = l({
|
|
43
|
+
id: o,
|
|
44
|
+
titleKey: o,
|
|
45
|
+
price: { kind: "free" },
|
|
46
|
+
items: a.items,
|
|
47
|
+
currencies: a.currencies
|
|
48
|
+
}, n);
|
|
49
|
+
return Object.freeze({
|
|
50
|
+
id: o,
|
|
51
|
+
kind: "inboxGift",
|
|
52
|
+
items: s.items,
|
|
53
|
+
currencies: s.currencies
|
|
54
|
+
});
|
|
55
|
+
}, p = (t, a, l = !1) => {
|
|
56
|
+
let u = r(t, [
|
|
57
|
+
"id",
|
|
58
|
+
"version",
|
|
59
|
+
"titleKey",
|
|
60
|
+
"pointsFrom",
|
|
61
|
+
"tiers",
|
|
62
|
+
"decay"
|
|
63
|
+
]), d = c(a);
|
|
64
|
+
if (typeof l != "boolean") throw e("invalid_input");
|
|
65
|
+
let p = n(u.pointsFrom, 32).map((t) => {
|
|
66
|
+
let n = r(t, [
|
|
67
|
+
"id",
|
|
68
|
+
"kind",
|
|
69
|
+
"currency",
|
|
70
|
+
"numerator",
|
|
71
|
+
"denominator"
|
|
72
|
+
]), a = i(n.id), o = i(n.currency);
|
|
73
|
+
if (n.kind !== "purchase.real" && n.kind !== "purchase.virtual") throw e("invalid_input");
|
|
74
|
+
if (n.kind === "purchase.real") {
|
|
75
|
+
if (!l) throw e("real_money_disabled");
|
|
76
|
+
if (!/^[A-Z]{3}$/.test(o)) throw e("invalid_currency");
|
|
77
|
+
} else if (!d.some((e) => e.id === o)) throw e("invalid_currency");
|
|
78
|
+
return Object.freeze({
|
|
79
|
+
id: a,
|
|
80
|
+
kind: n.kind,
|
|
81
|
+
currency: o,
|
|
82
|
+
numerator: s(n.numerator).toString(),
|
|
83
|
+
denominator: s(n.denominator).toString()
|
|
84
|
+
});
|
|
85
|
+
}), m = n(u.tiers, 128).map((t) => {
|
|
86
|
+
let a = r(t, [
|
|
87
|
+
"id",
|
|
88
|
+
"at",
|
|
89
|
+
"perks"
|
|
90
|
+
]), s = Object.freeze(n(a.perks, 32).map((e) => f(e, d)));
|
|
91
|
+
if (new Set(s.map((e) => e.id)).size !== s.length) throw e("invalid_input");
|
|
92
|
+
return Object.freeze({
|
|
93
|
+
id: i(a.id),
|
|
94
|
+
at: o(a.at).toString(),
|
|
95
|
+
perks: s
|
|
96
|
+
});
|
|
97
|
+
}), h = u.decay ?? "none";
|
|
98
|
+
if (!p.length || new Set(p.map((e) => e.id)).size !== p.length || !m.length || m[0].at !== "0" || new Set(m.map((e) => e.id)).size !== m.length || m.some((e, t) => t > 0 && BigInt(e.at) <= BigInt(m[t - 1].at)) || h !== "none" && h !== "seasonal") throw e("invalid_input");
|
|
99
|
+
return Object.freeze({
|
|
100
|
+
id: i(u.id),
|
|
101
|
+
version: i(u.version ?? "1"),
|
|
102
|
+
titleKey: i(u.titleKey),
|
|
103
|
+
pointsFrom: Object.freeze(p),
|
|
104
|
+
tiers: Object.freeze(m),
|
|
105
|
+
decay: h
|
|
106
|
+
});
|
|
107
|
+
}, m = (t, n, r, a, s = !1) => {
|
|
108
|
+
let c = p(t, a, s).pointsFrom.find((e) => e.id === i(n));
|
|
109
|
+
if (!c) throw e("not_found");
|
|
110
|
+
return o(o(r) * BigInt(c.numerator) / BigInt(c.denominator)).toString();
|
|
111
|
+
}, h = ({ loyalty: e, points: t }) => e.tiers.filter((e) => BigInt(e.at) <= o(t)).at(-1).id, g = (t) => {
|
|
112
|
+
let n = r(t, [
|
|
113
|
+
"loyalty",
|
|
114
|
+
"currencies",
|
|
115
|
+
"realMoney",
|
|
116
|
+
"points",
|
|
117
|
+
"rulesVersion"
|
|
118
|
+
]), a = c(n.currencies), s = n.realMoney ?? !1;
|
|
119
|
+
if (typeof s != "boolean") throw e("invalid_input");
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
loyalty: p(n.loyalty, a, s),
|
|
122
|
+
currencies: a,
|
|
123
|
+
realMoney: s,
|
|
124
|
+
points: o(n.points).toString(),
|
|
125
|
+
rulesVersion: i(n.rulesVersion ?? "default.v1")
|
|
126
|
+
});
|
|
127
|
+
}, _ = (t, n = h) => {
|
|
128
|
+
let r = g(t);
|
|
129
|
+
if (typeof n != "function" || n !== h && r.rulesVersion === "default.v1") throw e("invalid_input");
|
|
130
|
+
let a = i(n(r)), o = r.loyalty.tiers.find((e) => e.id === a);
|
|
131
|
+
if (!o || BigInt(o.at) > BigInt(r.points)) throw e("invalid_input");
|
|
132
|
+
return o;
|
|
133
|
+
}, v = (e) => e.loyalty.tiers.find((t) => t.id === e.tierId).perks, y = (t, a = v) => {
|
|
134
|
+
let { tierId: o, ...s } = r(t, [
|
|
135
|
+
"loyalty",
|
|
136
|
+
"currencies",
|
|
137
|
+
"realMoney",
|
|
138
|
+
"points",
|
|
139
|
+
"rulesVersion",
|
|
140
|
+
"tierId"
|
|
141
|
+
]), c = g(s), l = i(o), u = c.loyalty.tiers.find((e) => e.id === l);
|
|
142
|
+
if (!u || BigInt(u.at) > BigInt(c.points) || typeof a != "function" || a !== v && c.rulesVersion === "default.v1") throw e("invalid_input");
|
|
143
|
+
let d = Object.freeze(n(a(Object.freeze({
|
|
144
|
+
...c,
|
|
145
|
+
tierId: l
|
|
146
|
+
})), 32).map((e) => f(e, c.currencies)));
|
|
147
|
+
if (new Set(d.map((e) => e.id)).size !== d.length || d.some((e) => !u.perks.some((t) => JSON.stringify(t) === JSON.stringify(e)))) throw e("invalid_input");
|
|
148
|
+
return d;
|
|
149
|
+
}, b = (t, c = "none") => {
|
|
150
|
+
if (c !== "none" && c !== "seasonal") throw e("invalid_input");
|
|
151
|
+
let l = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set(), f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), h = (t, n = !1) => {
|
|
152
|
+
if (typeof t != "string" || (n ? s(t) : o(t)).toString() !== t) throw e("invalid_record");
|
|
153
|
+
return BigInt(t);
|
|
154
|
+
}, g = 0, _ = Object.freeze(n(t, 1e5, "invalid_record").map((t, n) => {
|
|
155
|
+
let s = r(t, [
|
|
156
|
+
"id",
|
|
157
|
+
"sequence",
|
|
158
|
+
"kind",
|
|
159
|
+
"at",
|
|
160
|
+
"sourceId",
|
|
161
|
+
"purchaseId",
|
|
162
|
+
"seasonId",
|
|
163
|
+
"purchaseAmount",
|
|
164
|
+
"numerator",
|
|
165
|
+
"denominator",
|
|
166
|
+
"delta",
|
|
167
|
+
"originalId",
|
|
168
|
+
"refundId",
|
|
169
|
+
"totalRefunded"
|
|
170
|
+
], "invalid_record"), _ = i(s.id, "invalid_record"), v = u(s.at, 0, 864e13), y = u(s.sequence, 1, 1e5), b = s.seasonId === null ? null : i(s.seasonId, "invalid_record");
|
|
171
|
+
if (l.has(_) || y !== n + 1 || v < g || c === "none" && b !== null || c === "seasonal" && b === null || typeof s.delta != "string" || a(s.delta).toString() !== s.delta) throw e("invalid_record");
|
|
172
|
+
l.add(_), g = v;
|
|
173
|
+
let x, S = a(s.delta);
|
|
174
|
+
if (s.kind === "credit") {
|
|
175
|
+
r(t, [
|
|
176
|
+
"id",
|
|
177
|
+
"sequence",
|
|
178
|
+
"kind",
|
|
179
|
+
"at",
|
|
180
|
+
"sourceId",
|
|
181
|
+
"purchaseId",
|
|
182
|
+
"seasonId",
|
|
183
|
+
"purchaseAmount",
|
|
184
|
+
"numerator",
|
|
185
|
+
"denominator",
|
|
186
|
+
"delta"
|
|
187
|
+
], "invalid_record");
|
|
188
|
+
let n = i(s.sourceId, "invalid_record"), a = i(s.purchaseId, "invalid_record"), o = h(s.purchaseAmount), c = h(s.numerator, !0), l = h(s.denominator, !0), u = JSON.stringify([n, a]);
|
|
189
|
+
if (d.has(u) || S !== o * c / l || S < 0n) throw e("invalid_record");
|
|
190
|
+
d.add(u), x = Object.freeze({
|
|
191
|
+
id: _,
|
|
192
|
+
sequence: y,
|
|
193
|
+
kind: "credit",
|
|
194
|
+
at: v,
|
|
195
|
+
sourceId: n,
|
|
196
|
+
purchaseId: a,
|
|
197
|
+
seasonId: b,
|
|
198
|
+
purchaseAmount: o.toString(),
|
|
199
|
+
numerator: c.toString(),
|
|
200
|
+
denominator: l.toString(),
|
|
201
|
+
delta: S.toString()
|
|
202
|
+
}), m.set(_, {
|
|
203
|
+
entry: x,
|
|
204
|
+
refunded: 0n,
|
|
205
|
+
remaining: S
|
|
206
|
+
});
|
|
207
|
+
} else if (s.kind === "reverse") {
|
|
208
|
+
r(t, [
|
|
209
|
+
"id",
|
|
210
|
+
"sequence",
|
|
211
|
+
"kind",
|
|
212
|
+
"at",
|
|
213
|
+
"originalId",
|
|
214
|
+
"refundId",
|
|
215
|
+
"seasonId",
|
|
216
|
+
"totalRefunded",
|
|
217
|
+
"delta"
|
|
218
|
+
], "invalid_record");
|
|
219
|
+
let n = i(s.originalId, "invalid_record"), a = i(s.refundId, "invalid_record"), o = m.get(n), c = h(s.totalRefunded);
|
|
220
|
+
if (!o || o.entry.seasonId !== b || c <= o.refunded || c > BigInt(o.entry.purchaseAmount) || f.has(JSON.stringify([o.entry.sourceId, a]))) throw e("invalid_record");
|
|
221
|
+
let l = (BigInt(o.entry.purchaseAmount) - c) * BigInt(o.entry.numerator) / BigInt(o.entry.denominator);
|
|
222
|
+
if (S !== l - o.remaining || S > 0n) throw e("invalid_record");
|
|
223
|
+
f.add(JSON.stringify([o.entry.sourceId, a])), o.refunded = c, o.remaining = l, x = Object.freeze({
|
|
224
|
+
id: _,
|
|
225
|
+
sequence: y,
|
|
226
|
+
kind: "reverse",
|
|
227
|
+
at: v,
|
|
228
|
+
originalId: n,
|
|
229
|
+
refundId: a,
|
|
230
|
+
seasonId: b,
|
|
231
|
+
totalRefunded: c.toString(),
|
|
232
|
+
delta: S.toString()
|
|
233
|
+
});
|
|
234
|
+
} else throw e("invalid_record");
|
|
235
|
+
let C = (p.get(b) ?? 0n) + S;
|
|
236
|
+
return p.set(b, o(C)), x;
|
|
237
|
+
}));
|
|
238
|
+
return Object.freeze({
|
|
239
|
+
entries: _,
|
|
240
|
+
balances: Object.freeze([...p].sort(([e], [t]) => (e ?? "") < (t ?? "") ? -1 : +((e ?? "") > (t ?? ""))).map(([e, t]) => Object.freeze({
|
|
241
|
+
seasonId: e,
|
|
242
|
+
points: t.toString()
|
|
243
|
+
}))),
|
|
244
|
+
credits: Object.freeze([...m.values()].map((e) => Object.freeze({
|
|
245
|
+
id: e.entry.id,
|
|
246
|
+
refundedAmount: e.refunded.toString(),
|
|
247
|
+
remainingPoints: e.remaining.toString()
|
|
248
|
+
})))
|
|
249
|
+
});
|
|
250
|
+
}, x = class extends d.Service()("@voltro/LoyaltyPort") {}, S = (e) => t(e, [
|
|
251
|
+
"list",
|
|
252
|
+
"mine",
|
|
253
|
+
"credit",
|
|
254
|
+
"reverse",
|
|
255
|
+
"receipt",
|
|
256
|
+
"rebuild",
|
|
257
|
+
"exportSubject",
|
|
258
|
+
"eraseSubject"
|
|
259
|
+
]), C = (e) => {
|
|
260
|
+
let t = r(e, [
|
|
261
|
+
"tenantId",
|
|
262
|
+
"ownerId",
|
|
263
|
+
"loyaltyId",
|
|
264
|
+
"sourceId",
|
|
265
|
+
"purchaseId",
|
|
266
|
+
"requestId"
|
|
267
|
+
]);
|
|
268
|
+
return Object.freeze({
|
|
269
|
+
tenantId: i(t.tenantId),
|
|
270
|
+
ownerId: i(t.ownerId),
|
|
271
|
+
loyaltyId: i(t.loyaltyId),
|
|
272
|
+
sourceId: i(t.sourceId),
|
|
273
|
+
purchaseId: i(t.purchaseId),
|
|
274
|
+
requestId: i(t.requestId)
|
|
275
|
+
});
|
|
276
|
+
}, w = (e) => {
|
|
277
|
+
let t = r(e, [
|
|
278
|
+
"tenantId",
|
|
279
|
+
"ownerId",
|
|
280
|
+
"loyaltyId",
|
|
281
|
+
"originalId",
|
|
282
|
+
"refundId",
|
|
283
|
+
"requestId"
|
|
284
|
+
]);
|
|
285
|
+
return Object.freeze({
|
|
286
|
+
tenantId: i(t.tenantId),
|
|
287
|
+
ownerId: i(t.ownerId),
|
|
288
|
+
loyaltyId: i(t.loyaltyId),
|
|
289
|
+
originalId: i(t.originalId),
|
|
290
|
+
refundId: i(t.refundId),
|
|
291
|
+
requestId: i(t.requestId)
|
|
292
|
+
});
|
|
293
|
+
}, T = (e) => {
|
|
294
|
+
let t = r(e, ["loyaltyId"]);
|
|
295
|
+
return Object.freeze({ loyaltyId: i(t.loyaltyId) });
|
|
296
|
+
}, E = (e) => {
|
|
297
|
+
let t = r(e, ["requestId"]);
|
|
298
|
+
return Object.freeze({ requestId: i(t.requestId) });
|
|
299
|
+
}, D = (e) => {
|
|
300
|
+
let t = r(e, [
|
|
301
|
+
"tenantId",
|
|
302
|
+
"ownerId",
|
|
303
|
+
"loyaltyId"
|
|
304
|
+
]);
|
|
305
|
+
return Object.freeze({
|
|
306
|
+
tenantId: i(t.tenantId),
|
|
307
|
+
ownerId: i(t.ownerId),
|
|
308
|
+
loyaltyId: i(t.loyaltyId)
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
//#endregion
|
|
312
|
+
export { x as LoyaltyPort, S as captureLoyaltyService, v as defaultLoyaltyPerks, h as defaultLoyaltyTier, p as defineLoyalty, C as loyaltyCreditIntent, T as loyaltyMineIntent, m as loyaltyPointsForPurchase, D as loyaltyRebuildIntent, E as loyaltyReceiptIntent, w as loyaltyReverseIntent, b as projectLoyaltyPoints, y as resolveLoyaltyPerks, _ as resolveLoyaltyTier };
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { EconomyError as e, economyError as t } from "./errors.js";
|
|
2
|
+
import { captureQueryTables as n, dataList as r, dataObject as i, declaredSources as a, identifier as o } from "./capture.js";
|
|
3
|
+
import { loyaltyListDescriptor as s, loyaltyMineDescriptor as c, loyaltyReceiptDescriptor as l, loyaltyRpcClientImports as u } from "./rpc.js";
|
|
4
|
+
import { LoyaltyPort as d, captureLoyaltyService as f, defaultLoyaltyPerks as p, defaultLoyaltyTier as m, defineLoyalty as h, loyaltyCreditIntent as g, loyaltyMineIntent as _, loyaltyRebuildIntent as v, loyaltyReceiptIntent as y, loyaltyReverseIntent as b } from "./loyalty.js";
|
|
5
|
+
import { loyaltyTables as x } from "./loyaltyTables.entity.js";
|
|
6
|
+
import { dataStoreLoyalty as S, resolveLoyaltyStoreOptions as C } from "./loyaltyStore.server.js";
|
|
7
|
+
import { Effect as w, Layer as T } from "effect";
|
|
8
|
+
//#region src/loyaltyBinding.server.ts
|
|
9
|
+
var E = () => w.fail(t("unavailable")), D = Object.freeze({
|
|
10
|
+
list: E,
|
|
11
|
+
mine: E,
|
|
12
|
+
credit: E,
|
|
13
|
+
reverse: E,
|
|
14
|
+
receipt: E,
|
|
15
|
+
rebuild: E,
|
|
16
|
+
exportSubject: E,
|
|
17
|
+
eraseSubject: E
|
|
18
|
+
}), O = (E, D) => {
|
|
19
|
+
if (E === void 0) return;
|
|
20
|
+
let O = i(E, [
|
|
21
|
+
"loyalty",
|
|
22
|
+
"receiptSource",
|
|
23
|
+
"seasonSource",
|
|
24
|
+
"version",
|
|
25
|
+
"tier",
|
|
26
|
+
"perks",
|
|
27
|
+
"allowedServices",
|
|
28
|
+
"maxHistoryRows",
|
|
29
|
+
"maxDefinitionRows",
|
|
30
|
+
"maxSeasonRows",
|
|
31
|
+
"now",
|
|
32
|
+
"service",
|
|
33
|
+
"querySources"
|
|
34
|
+
]), k = O.service === void 0 ? void 0 : f(O.service);
|
|
35
|
+
if (k && [
|
|
36
|
+
"receiptSource",
|
|
37
|
+
"seasonSource",
|
|
38
|
+
"tier",
|
|
39
|
+
"perks",
|
|
40
|
+
"allowedServices",
|
|
41
|
+
"maxHistoryRows",
|
|
42
|
+
"maxDefinitionRows",
|
|
43
|
+
"maxSeasonRows",
|
|
44
|
+
"now"
|
|
45
|
+
].some((e) => O[e] !== void 0)) throw t("invalid_input");
|
|
46
|
+
let A = O.querySources === void 0 ? void 0 : i(O.querySources, [
|
|
47
|
+
"list",
|
|
48
|
+
"mine",
|
|
49
|
+
"receipt"
|
|
50
|
+
]);
|
|
51
|
+
if (k && !A) throw t("invalid_input");
|
|
52
|
+
let j = A ? Object.freeze({
|
|
53
|
+
list: n(A.list),
|
|
54
|
+
mine: n(A.mine),
|
|
55
|
+
receipt: n(A.receipt)
|
|
56
|
+
}) : void 0, M = k ? void 0 : C({
|
|
57
|
+
currencies: D.currencies,
|
|
58
|
+
realMoney: D.realMoney,
|
|
59
|
+
loyalty: O.loyalty,
|
|
60
|
+
receiptSource: O.receiptSource,
|
|
61
|
+
seasonSource: O.seasonSource,
|
|
62
|
+
version: O.version,
|
|
63
|
+
tier: O.tier,
|
|
64
|
+
perks: O.perks,
|
|
65
|
+
allowedServices: O.allowedServices ?? D.allowedServices,
|
|
66
|
+
maxHistoryRows: O.maxHistoryRows,
|
|
67
|
+
maxDefinitionRows: O.maxDefinitionRows,
|
|
68
|
+
maxSeasonRows: O.maxSeasonRows,
|
|
69
|
+
now: O.now ?? D.now
|
|
70
|
+
}), N = M?.loyalty ?? Object.freeze(r(O.loyalty, 32).map((e) => h(e, D.currencies, D.realMoney)));
|
|
71
|
+
if (!N.length || new Set(N.map((e) => e.id)).size !== N.length) throw t("invalid_input");
|
|
72
|
+
let P = M?.version ?? o(O.version);
|
|
73
|
+
if (P === "default.v1") throw t("invalid_input");
|
|
74
|
+
let F = new Set(M?.allowedServices ?? D.allowedServices), I, L = !1, R, z = (e) => w.suspend(() => {
|
|
75
|
+
let n = k ?? I;
|
|
76
|
+
return L && n ? e(n) : w.fail(t("unavailable"));
|
|
77
|
+
}), B = (n) => {
|
|
78
|
+
try {
|
|
79
|
+
return n();
|
|
80
|
+
} catch (n) {
|
|
81
|
+
return w.fail(n instanceof e ? n : t("invalid_input"));
|
|
82
|
+
}
|
|
83
|
+
}, V = (e) => {
|
|
84
|
+
let n = structuredClone(e);
|
|
85
|
+
if (n.type !== "user") throw t("forbidden");
|
|
86
|
+
return o(n.id), o(n.tenantId), n;
|
|
87
|
+
}, H = (e) => {
|
|
88
|
+
let n = structuredClone(e);
|
|
89
|
+
if (n.type !== "system" && (n.type !== "service" || !F.has(n.service))) throw t("forbidden");
|
|
90
|
+
return n;
|
|
91
|
+
}, U = (e) => {
|
|
92
|
+
let n = i(e, [
|
|
93
|
+
"tenantId",
|
|
94
|
+
"subjectId",
|
|
95
|
+
"kind"
|
|
96
|
+
]);
|
|
97
|
+
if (n.kind !== "user" && n.kind !== "guest") throw t("invalid_input");
|
|
98
|
+
return Object.freeze({
|
|
99
|
+
tenantId: o(n.tenantId),
|
|
100
|
+
subjectId: o(n.subjectId),
|
|
101
|
+
kind: n.kind
|
|
102
|
+
});
|
|
103
|
+
}, W = Object.freeze({
|
|
104
|
+
list: (e) => B(() => {
|
|
105
|
+
let t = V(e);
|
|
106
|
+
return z((e) => e.list(t));
|
|
107
|
+
}),
|
|
108
|
+
mine: (e, t) => B(() => {
|
|
109
|
+
let n = V(e), r = _(t);
|
|
110
|
+
return z((e) => e.mine(n, r));
|
|
111
|
+
}),
|
|
112
|
+
credit: (e, t) => B(() => {
|
|
113
|
+
let n = H(e), r = g(t);
|
|
114
|
+
return z((e) => e.credit(n, r));
|
|
115
|
+
}),
|
|
116
|
+
reverse: (e, t) => B(() => {
|
|
117
|
+
let n = H(e), r = b(t);
|
|
118
|
+
return z((e) => e.reverse(n, r));
|
|
119
|
+
}),
|
|
120
|
+
receipt: (e, t) => B(() => {
|
|
121
|
+
let n = V(e), r = y(t);
|
|
122
|
+
return z((e) => e.receipt(n, r));
|
|
123
|
+
}),
|
|
124
|
+
rebuild: (e, t) => B(() => {
|
|
125
|
+
let n = H(e), r = v(t);
|
|
126
|
+
return z((e) => e.rebuild(n, r));
|
|
127
|
+
}),
|
|
128
|
+
exportSubject: (e) => B(() => {
|
|
129
|
+
let t = U(e);
|
|
130
|
+
return z((e) => e.exportSubject(t));
|
|
131
|
+
}),
|
|
132
|
+
eraseSubject: (e) => B(() => {
|
|
133
|
+
let t = U(e);
|
|
134
|
+
return z((e) => e.eraseSubject(t));
|
|
135
|
+
})
|
|
136
|
+
}), G = (e, t) => k ? j[e] : [.../* @__PURE__ */ new Set([...t, ...j?.[e] ?? []])], K = [
|
|
137
|
+
{
|
|
138
|
+
...s,
|
|
139
|
+
source: G("list", a(s.source)),
|
|
140
|
+
execute: (e, t) => W.list(t.request.subject)
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
...c,
|
|
144
|
+
source: G("mine", a(c.source)),
|
|
145
|
+
execute: (e, t) => W.mine(t.request.subject, e)
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
...l,
|
|
149
|
+
source: G("receipt", a(l.source)),
|
|
150
|
+
execute: (e, t) => W.receipt(t.request.subject, e)
|
|
151
|
+
}
|
|
152
|
+
], q = M ? x : [], J = Object.freeze({
|
|
153
|
+
backend: k ? "custom" : "sql",
|
|
154
|
+
version: P,
|
|
155
|
+
slots: Object.freeze({
|
|
156
|
+
tier: k || M?.tier !== m ? "custom" : "default",
|
|
157
|
+
perks: k || M?.perks !== p ? "custom" : "default"
|
|
158
|
+
}),
|
|
159
|
+
receiptSource: k ? "app-owned" : "custom",
|
|
160
|
+
seasonSource: k ? "app-owned" : M?.seasonSource ? "custom" : "none",
|
|
161
|
+
loyalty: Object.freeze(N.map((e) => Object.freeze({
|
|
162
|
+
id: e.id,
|
|
163
|
+
version: e.version,
|
|
164
|
+
decay: e.decay,
|
|
165
|
+
sourceKinds: e.pointsFrom.length,
|
|
166
|
+
realSourceKinds: e.pointsFrom.filter((e) => e.kind === "purchase.real").length,
|
|
167
|
+
tierKinds: e.tiers.length
|
|
168
|
+
}))),
|
|
169
|
+
budgets: k ? null : Object.freeze({
|
|
170
|
+
historyRows: M.maxHistoryRows,
|
|
171
|
+
definitionRows: M.maxDefinitionRows,
|
|
172
|
+
seasonRows: M.maxSeasonRows
|
|
173
|
+
}),
|
|
174
|
+
virtualPointsInstalled: !0,
|
|
175
|
+
realReceiptVerificationInstalled: !1,
|
|
176
|
+
perkEffectsInstalled: !1,
|
|
177
|
+
automaticConsumptionInstalled: !1,
|
|
178
|
+
gmActionsInstalled: !1
|
|
179
|
+
});
|
|
180
|
+
return Object.freeze({
|
|
181
|
+
service: W,
|
|
182
|
+
layer: T.succeed(d, W),
|
|
183
|
+
tables: q,
|
|
184
|
+
routes: K,
|
|
185
|
+
status: J,
|
|
186
|
+
rpcClientDescriptors: u,
|
|
187
|
+
roles: M ? [
|
|
188
|
+
"loyaltyTenants",
|
|
189
|
+
"loyaltyDefinitions",
|
|
190
|
+
"loyaltySubjects",
|
|
191
|
+
"loyaltyEntries",
|
|
192
|
+
"loyaltySeasons"
|
|
193
|
+
] : [],
|
|
194
|
+
bind: (e) => {
|
|
195
|
+
if (R !== void 0 && R !== e) throw Error("Loyalty system cannot cross app stores");
|
|
196
|
+
R = e, M && (I = S(e, M)), L = !0;
|
|
197
|
+
},
|
|
198
|
+
deactivate: () => {
|
|
199
|
+
L = !1, I = void 0;
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
//#endregion
|
|
204
|
+
export { O as bindLoyaltySystem, D as unavailableLoyalty };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { LoyaltyPort as e } from "./loyalty.js";
|
|
2
|
+
import { economyPlugin as t } from "./plugin.js";
|
|
3
|
+
import { shopMachine as n } from "./shop.testFixtures.js";
|
|
4
|
+
import { loyaltyStoreFixture as r } from "./loyaltyStore.testFixtures.js";
|
|
5
|
+
import { Effect as i, Layer as a } from "effect";
|
|
6
|
+
import { InMemoryDataStore as o } from "@voltro/runtime";
|
|
7
|
+
//#region src/loyaltyPort.fixture.ts
|
|
8
|
+
var s = {
|
|
9
|
+
app: {
|
|
10
|
+
name: "loyalty-fixture",
|
|
11
|
+
type: "api",
|
|
12
|
+
voltroVersion: "0.83.1"
|
|
13
|
+
},
|
|
14
|
+
config: {},
|
|
15
|
+
env: {},
|
|
16
|
+
logger: {
|
|
17
|
+
info() {},
|
|
18
|
+
warn() {},
|
|
19
|
+
error() {},
|
|
20
|
+
debug() {}
|
|
21
|
+
}
|
|
22
|
+
}, c = i.gen(function* () {
|
|
23
|
+
let e = new o(), a = yield* i.promise(() => r(e, "fixture")), c = a.options, l = yield* a.base.shop.buy(a.base.user, a.base.buy), u = t({
|
|
24
|
+
currencies: c.currencies,
|
|
25
|
+
now: c.now,
|
|
26
|
+
loyalty: {
|
|
27
|
+
loyalty: c.loyalty,
|
|
28
|
+
receiptSource: c.receiptSource,
|
|
29
|
+
seasonSource: c.seasonSource,
|
|
30
|
+
version: c.version,
|
|
31
|
+
tier: c.tier,
|
|
32
|
+
perks: c.perks,
|
|
33
|
+
allowedServices: c.allowedServices,
|
|
34
|
+
maxHistoryRows: c.maxHistoryRows,
|
|
35
|
+
maxDefinitionRows: c.maxDefinitionRows,
|
|
36
|
+
maxSeasonRows: c.maxSeasonRows,
|
|
37
|
+
now: c.now
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
yield* i.promise(async () => {
|
|
41
|
+
await u.bindDataStore?.(e);
|
|
42
|
+
});
|
|
43
|
+
let d = yield* u.economy.loyalty().credit(n, a.credit(l.orderId));
|
|
44
|
+
return Object.freeze({
|
|
45
|
+
store: e,
|
|
46
|
+
plugin: u,
|
|
47
|
+
base: a,
|
|
48
|
+
purchase: l,
|
|
49
|
+
accepted: d,
|
|
50
|
+
close: i.suspend(() => u.onDeactivate?.(s))
|
|
51
|
+
});
|
|
52
|
+
}), l = a.effectContext(i.acquireRelease(c, (e) => e.close).pipe(i.flatMap((e) => a.build(e.plugin.services)))), u = Object.freeze({
|
|
53
|
+
kind: "port",
|
|
54
|
+
tag: e,
|
|
55
|
+
fakeLayer: l,
|
|
56
|
+
probe: {
|
|
57
|
+
run: () => i.scoped(i.gen(function* () {
|
|
58
|
+
let t = yield* e, r = {
|
|
59
|
+
type: "user",
|
|
60
|
+
id: "a",
|
|
61
|
+
tenantId: "fixture",
|
|
62
|
+
kind: "guest"
|
|
63
|
+
}, i = yield* t.receipt(r, { requestId: "credit" });
|
|
64
|
+
if (i.state !== "fulfilled" || i.receipt.entry.kind !== "credit") throw Error("Actual fixture purchase evidence was not admitted");
|
|
65
|
+
let a = i.receipt.entry, o = yield* t.credit(n, {
|
|
66
|
+
tenantId: "fixture",
|
|
67
|
+
ownerId: "a",
|
|
68
|
+
loyaltyId: "vip",
|
|
69
|
+
sourceId: a.sourceId,
|
|
70
|
+
purchaseId: a.purchaseId,
|
|
71
|
+
requestId: "credit"
|
|
72
|
+
}), s = yield* t.mine(r, { loyaltyId: "vip" });
|
|
73
|
+
return {
|
|
74
|
+
same: i.receipt.operationId === o.operationId,
|
|
75
|
+
points: s.points,
|
|
76
|
+
tier: s.tierId
|
|
77
|
+
};
|
|
78
|
+
}).pipe(i.provide(l))),
|
|
79
|
+
expected: {
|
|
80
|
+
same: !0,
|
|
81
|
+
points: "10",
|
|
82
|
+
tier: "silver"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
//#endregion
|
|
87
|
+
export { l as loyaltyFakeLayer, c as loyaltyPortFixture, u as loyaltyPortSystemFixture };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { EconomyError as e, economyError as t } from "./errors.js";
|
|
2
|
+
import { captureBoundMethods as n, dataObject as r, identifier as i } from "./capture.js";
|
|
3
|
+
import { shopBuyIntent as a } from "./shop.js";
|
|
4
|
+
import { shopOrdersTable as o } from "./shopTables.entity.js";
|
|
5
|
+
import { Effect as s, Result as c } from "effect";
|
|
6
|
+
import { eq as l, queryFor as u } from "@voltro/database";
|
|
7
|
+
//#region src/loyaltyShopSource.server.ts
|
|
8
|
+
var d = (d, f) => {
|
|
9
|
+
let p = r(f, ["shop", "refunds"]), m = n(p.shop, ["receipt"]), h = p.refunds === void 0 ? void 0 : n(p.refunds, ["read"]);
|
|
10
|
+
return Object.freeze({
|
|
11
|
+
purchase: (n) => {
|
|
12
|
+
try {
|
|
13
|
+
let f = r(n, [
|
|
14
|
+
"tenantId",
|
|
15
|
+
"ownerId",
|
|
16
|
+
"source",
|
|
17
|
+
"purchaseId"
|
|
18
|
+
]), p = r(f.source, [
|
|
19
|
+
"id",
|
|
20
|
+
"kind",
|
|
21
|
+
"currency",
|
|
22
|
+
"numerator",
|
|
23
|
+
"denominator"
|
|
24
|
+
]), h = i(f.tenantId), g = i(f.ownerId), _ = i(f.purchaseId), v = i(p.currency);
|
|
25
|
+
if (p.kind !== "purchase.virtual") throw t("forbidden");
|
|
26
|
+
return s.tryPromise({
|
|
27
|
+
try: async () => {
|
|
28
|
+
let e = (await d.query(u(o).where(l("id", _)).limit(1).descriptor))[0];
|
|
29
|
+
if (!e) throw t("not_found");
|
|
30
|
+
if (e.tenantId !== h || e.ownerId !== g) throw t("forbidden");
|
|
31
|
+
if (e.state !== "fulfilled") throw t(e.state === "erased" ? "erased" : "not_found");
|
|
32
|
+
let n = r(e.intent, [
|
|
33
|
+
"request",
|
|
34
|
+
"offer",
|
|
35
|
+
"currencies",
|
|
36
|
+
"realMoney",
|
|
37
|
+
"rulesVersion",
|
|
38
|
+
"price",
|
|
39
|
+
"adjustments",
|
|
40
|
+
"quotedAt",
|
|
41
|
+
"at",
|
|
42
|
+
"counters"
|
|
43
|
+
], "invalid_record"), i = r(n.request, [
|
|
44
|
+
"tenantId",
|
|
45
|
+
"ownerId",
|
|
46
|
+
"offerId",
|
|
47
|
+
"offerVersion",
|
|
48
|
+
"offerDigest",
|
|
49
|
+
"requestId",
|
|
50
|
+
"currency",
|
|
51
|
+
"qty"
|
|
52
|
+
], "invalid_record");
|
|
53
|
+
if (i.tenantId !== h || i.ownerId !== g) throw t("invalid_record");
|
|
54
|
+
let { tenantId: f, ownerId: p, ...y } = i, b = a({
|
|
55
|
+
...y,
|
|
56
|
+
currency: y.currency ?? void 0
|
|
57
|
+
}), x = Object.freeze({
|
|
58
|
+
type: "user",
|
|
59
|
+
tenantId: h,
|
|
60
|
+
id: g
|
|
61
|
+
}), S = await s.runPromise(s.result(m.receipt(x, {
|
|
62
|
+
...b,
|
|
63
|
+
currency: b.currency ?? void 0
|
|
64
|
+
})));
|
|
65
|
+
if (c.isFailure(S)) throw S.failure;
|
|
66
|
+
if (S.success.state !== "fulfilled") throw t("not_found");
|
|
67
|
+
let C = S.success.receipt;
|
|
68
|
+
if (C.orderId !== _ || C.pricePaid.kind !== "virtual" || C.pricePaid.currency !== v) throw t("forbidden");
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
tenantId: h,
|
|
71
|
+
ownerId: g,
|
|
72
|
+
authorityId: "economy.shop.sql.v1",
|
|
73
|
+
purchaseId: _,
|
|
74
|
+
kind: "purchase.virtual",
|
|
75
|
+
currency: C.pricePaid.currency,
|
|
76
|
+
amount: C.pricePaid.amount,
|
|
77
|
+
settledAt: C.at,
|
|
78
|
+
refundedAmount: "0"
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
catch: (n) => n instanceof e ? n : t("unavailable")
|
|
82
|
+
});
|
|
83
|
+
} catch (n) {
|
|
84
|
+
return s.fail(n instanceof e ? n : t("invalid_input"));
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
refund: (e) => h ? h.read(e) : s.fail(t("not_found"))
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { d as shopLoyaltyReceiptSource };
|