@voltro/plugin-economy 0.0.0-stage → 0.88.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 +24492 -0
- package/LICENSE +61 -0
- package/README.md +2719 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +9841 -0
- package/dist/amount.js +20 -0
- package/dist/appleIap.server.js +262 -0
- package/dist/appleIapNotifications.server.js +162 -0
- package/dist/appleIapTrust.server.js +30 -0
- package/dist/bundleValue.server.js +112 -0
- package/dist/canonicalDataJson.js +10 -0
- package/dist/capture.js +53 -0
- package/dist/codePort.fixture.js +123 -0
- package/dist/codeStore.server.js +439 -0
- package/dist/codeTables.entity.js +43 -0
- package/dist/codes.d.ts +150 -0
- package/dist/codes.js +82 -0
- package/dist/components.d.ts +397 -0
- package/dist/components.js +283 -0
- package/dist/consistency.server.js +115 -0
- package/dist/containerStore.server.js +687 -0
- package/dist/containerStore.testFixtures.js +75 -0
- package/dist/containerTables.entity.js +45 -0
- package/dist/containers.d.ts +311 -0
- package/dist/containers.fixture.js +128 -0
- package/dist/containers.js +214 -0
- package/dist/containers.server.js +39 -0
- package/dist/containersPort.fixture.js +74 -0
- package/dist/currency.js +32 -0
- package/dist/declarationFixtures.js +61 -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 +124 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +21 -0
- package/dist/events.d.ts +46 -0
- package/dist/events.js +1 -0
- package/dist/googleIap.server.js +391 -0
- package/dist/googleIapNotifications.server.js +130 -0
- package/dist/googleIapSubscription.server.js +183 -0
- package/dist/iap.d.ts +309 -0
- package/dist/iap.js +303 -0
- package/dist/iap.testFixtures.js +144 -0
- package/dist/iapAccountTables.entity.js +39 -0
- package/dist/iapAccounts.server.js +200 -0
- package/dist/iapBinding.server.js +523 -0
- package/dist/iapCheckout.server.js +97 -0
- package/dist/iapCompletion.server.js +55 -0
- package/dist/iapCurrentState.server.js +107 -0
- package/dist/iapCurrentState.testFixtures.js +22 -0
- package/dist/iapCurrentStatePort.fixture.js +63 -0
- package/dist/iapEntitlements.d.ts +79 -0
- package/dist/iapEntitlements.js +57 -0
- package/dist/iapEntitlements.server.js +48 -0
- package/dist/iapEntitlementsBinding.server.js +105 -0
- package/dist/iapEntitlementsPort.fixture.js +80 -0
- package/dist/iapInstalledEntitlements.testFixtures.js +75 -0
- package/dist/iapInstalledNotifications.testFixtures.js +93 -0
- package/dist/iapInventoryRefunds.server.js +261 -0
- package/dist/iapNotificationCustodyPort.fixture.js +67 -0
- package/dist/iapNotificationPort.fixture.js +73 -0
- package/dist/iapNotificationProcessor.server.js +134 -0
- package/dist/iapNotificationProcessor.testFixtures.js +63 -0
- package/dist/iapNotificationProcessorPort.fixture.js +55 -0
- package/dist/iapNotificationSchedule.server.js +69 -0
- package/dist/iapNotificationStore.server.js +352 -0
- package/dist/iapNotificationStore.testFixtures.js +31 -0
- package/dist/iapNotificationTables.entity.js +48 -0
- package/dist/iapNotificationTarget.server.js +36 -0
- package/dist/iapNotificationTarget.testFixtures.js +29 -0
- package/dist/iapNotifications.d.ts +644 -0
- package/dist/iapNotifications.js +6 -0
- package/dist/iapNotifications.server.js +95 -0
- package/dist/iapNotificationsBinding.server.js +232 -0
- package/dist/iapNotificationsSystemPort.fixture.js +50 -0
- package/dist/iapPlugin.testFixtures.js +59 -0
- package/dist/iapPort.fixture.js +74 -0
- package/dist/iapProviderCapture.server.js +17 -0
- package/dist/iapRecovery.d.ts +146 -0
- package/dist/iapRecovery.js +89 -0
- package/dist/iapRefundEventDelivery.server.js +82 -0
- package/dist/iapRefundEvents.js +44 -0
- package/dist/iapRefundEventsPort.fixture.js +59 -0
- package/dist/iapRefundPort.fixture.js +54 -0
- package/dist/iapRefundTables.entity.js +55 -0
- package/dist/iapRefunds.d.ts +755 -0
- package/dist/iapRefunds.js +6 -0
- package/dist/iapRefunds.server.js +553 -0
- package/dist/iapRefunds.testFixtures.js +64 -0
- package/dist/iapSpendAdmission.server.js +98 -0
- package/dist/iapStore.server.js +740 -0
- package/dist/iapStore.testFixtures.js +127 -0
- package/dist/iapTables.entity.js +80 -0
- package/dist/iapVerification.server.js +120 -0
- package/dist/index.d.ts +2984 -0
- package/dist/index.js +15 -0
- package/dist/intentionRecovery.js +133 -0
- package/dist/ledger.js +77 -0
- package/dist/loyalty.d.ts +274 -0
- package/dist/loyalty.fixture.js +92 -0
- package/dist/loyalty.js +311 -0
- package/dist/loyaltyBinding.server.js +203 -0
- package/dist/loyaltyPort.fixture.js +86 -0
- package/dist/loyaltyShopSource.server.js +90 -0
- package/dist/loyaltyStore.server.js +552 -0
- package/dist/loyaltyStore.testFixtures.js +82 -0
- package/dist/loyaltyTables.entity.js +49 -0
- package/dist/offerMerchandising.fixture.js +114 -0
- package/dist/offerMerchandising.js +282 -0
- package/dist/offerPolicies.d.ts +441 -0
- package/dist/offerPolicies.fixture.js +53 -0
- package/dist/offerPolicies.js +267 -0
- package/dist/piggyBanks.d.ts +272 -0
- package/dist/piggyBanks.fixture.js +70 -0
- package/dist/piggyBanks.js +200 -0
- package/dist/piggyBinding.server.js +204 -0
- package/dist/piggyPort.fixture.js +72 -0
- package/dist/piggyStore.server.js +610 -0
- package/dist/piggyStore.testFixtures.js +97 -0
- package/dist/piggyTables.entity.js +40 -0
- package/dist/plugin.js +1047 -0
- package/dist/port.js +12 -0
- package/dist/price.d.ts +99 -0
- package/dist/price.js +143 -0
- package/dist/purchaseRecovery.js +55 -0
- package/dist/reports.server.js +114 -0
- package/dist/rpc.d.ts +3201 -0
- package/dist/rpc.js +1200 -0
- package/dist/sanctionsTradeAuthority.server.js +79 -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 +195 -0
- package/dist/shop.testFixtures.js +113 -0
- package/dist/shopPort.fixture.js +71 -0
- package/dist/shopPresentation.js +67 -0
- package/dist/shopStore.server.js +623 -0
- package/dist/shopTables.entity.js +62 -0
- package/dist/shopUiCopy.js +56 -0
- package/dist/spendLimits.d.ts +140 -0
- package/dist/spendLimits.fixture.js +52 -0
- package/dist/spendLimits.js +154 -0
- package/dist/spendLimitsPort.fixture.js +119 -0
- package/dist/subscriptionBinding.server.js +210 -0
- package/dist/subscriptionStore.server.js +642 -0
- package/dist/subscriptionStore.testFixtures.js +71 -0
- package/dist/subscriptionTables.entity.js +36 -0
- package/dist/subscriptions.d.ts +394 -0
- package/dist/subscriptions.fixture.js +96 -0
- package/dist/subscriptions.js +212 -0
- package/dist/subscriptionsPort.fixture.js +75 -0
- package/dist/systemFixtures.js +88 -0
- package/dist/tables.entity.js +82 -0
- package/dist/testing.d.ts +4615 -0
- package/dist/testing.js +29 -0
- package/dist/tradeAuthority.server.js +171 -0
- package/dist/tradeBinding.server.js +200 -0
- package/dist/tradeComponents.js +341 -0
- package/dist/tradeEscrow.server.js +231 -0
- package/dist/tradeEscrow.testFixtures.js +132 -0
- package/dist/tradeExpiry.server.js +42 -0
- package/dist/tradeRecovery.js +47 -0
- package/dist/tradeStore.server.js +749 -0
- package/dist/tradeStore.testFixtures.js +72 -0
- package/dist/tradeTables.entity.js +65 -0
- package/dist/tradeUiCopy.js +78 -0
- package/dist/trades.d.ts +246 -0
- package/dist/trades.fixture.js +102 -0
- package/dist/trades.js +288 -0
- package/dist/tradesPort.fixture.js +93 -0
- package/dist/walletEscrow.js +105 -0
- package/dist/walletEscrow.server.js +375 -0
- package/dist/walletKeys.server.js +4 -0
- package/dist/walletStore.js +570 -0
- package/dist/web.d.ts +2257 -0
- package/dist/web.js +8 -0
- package/package.json +161 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { captureBoundMethods as t, dataObject as n, identifier as r } from "./capture.js";
|
|
3
|
+
import { captureIapCompletionReceipt as i, captureIapObservation as a, captureIapOrderReceipt as o, createIapReceiptReference as s, iapReceiptIntent as c, iapReceiptReference as l } from "./iap.js";
|
|
4
|
+
import { browserIntentionJournal as u, createIntentionRecovery as d } from "./intentionRecovery.js";
|
|
5
|
+
// src/iapRecovery.ts
|
|
6
|
+
var f = (t) => {
|
|
7
|
+
let s = n(t, [
|
|
8
|
+
"requestId",
|
|
9
|
+
"state",
|
|
10
|
+
"receipt",
|
|
11
|
+
"completion",
|
|
12
|
+
"refund"
|
|
13
|
+
], "invalid_record");
|
|
14
|
+
if (s.state !== "completed") return a(t);
|
|
15
|
+
if (Object.hasOwn(s, "refund")) throw e("invalid_record");
|
|
16
|
+
return Object.freeze({
|
|
17
|
+
requestId: r(s.requestId, "invalid_record"),
|
|
18
|
+
state: "completed",
|
|
19
|
+
receipt: o(s.receipt),
|
|
20
|
+
completion: i(s.completion)
|
|
21
|
+
});
|
|
22
|
+
}, p = (t, n) => {
|
|
23
|
+
if (t.requestId !== n.requestId) throw e("conflict");
|
|
24
|
+
if (n.state !== "not-observed" && n.state !== "pending" && "receipt" in n) {
|
|
25
|
+
if (n.receipt.offerId !== t.offerId || n.receipt.offerVersion !== t.offerVersion) throw e("conflict");
|
|
26
|
+
if (n.state === "completed") {
|
|
27
|
+
if (n.completion.orderId !== n.receipt.orderId || n.completion.channel !== t.channel || n.completion.observedAt < n.receipt.at) throw e("conflict");
|
|
28
|
+
return Object.freeze({
|
|
29
|
+
receipt: n.receipt,
|
|
30
|
+
completion: n.completion
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}, m = (n, a, u) => {
|
|
35
|
+
let m = t(a, ["restore"]), h = t(u, [
|
|
36
|
+
"read",
|
|
37
|
+
"redeem",
|
|
38
|
+
"complete"
|
|
39
|
+
]), g = 0, _, v = d(n, async (t, n) => {
|
|
40
|
+
let r = f(await h.read(t));
|
|
41
|
+
if (n(), p(t, r), r.state === "completed") throw e("invalid_record");
|
|
42
|
+
let a = c(await m.restore(t));
|
|
43
|
+
n();
|
|
44
|
+
let l = await s(a);
|
|
45
|
+
if (n(), JSON.stringify(t) !== JSON.stringify(l)) throw e("conflict");
|
|
46
|
+
let u = "receipt" in r ? r.receipt : o(await h.redeem(a));
|
|
47
|
+
n(), p(t, {
|
|
48
|
+
requestId: t.requestId,
|
|
49
|
+
state: "fulfilled",
|
|
50
|
+
receipt: u
|
|
51
|
+
});
|
|
52
|
+
let d = i(await h.complete(a, u));
|
|
53
|
+
n();
|
|
54
|
+
let g = p(t, {
|
|
55
|
+
requestId: t.requestId,
|
|
56
|
+
state: "completed",
|
|
57
|
+
receipt: u,
|
|
58
|
+
completion: d
|
|
59
|
+
});
|
|
60
|
+
if (!g) throw e("invalid_record");
|
|
61
|
+
return g;
|
|
62
|
+
}, {
|
|
63
|
+
request: (e) => l(e),
|
|
64
|
+
observation: f,
|
|
65
|
+
fulfilled: (e, t) => ({
|
|
66
|
+
requestId: e.requestId,
|
|
67
|
+
state: "completed",
|
|
68
|
+
...t
|
|
69
|
+
}),
|
|
70
|
+
resolve: p
|
|
71
|
+
});
|
|
72
|
+
return Object.freeze({
|
|
73
|
+
selectScope: (e) => {
|
|
74
|
+
let t = e === void 0 ? void 0 : r(e);
|
|
75
|
+
g++, _ = t, v.selectScope(t);
|
|
76
|
+
},
|
|
77
|
+
pending: v.pending,
|
|
78
|
+
retry: v.retry,
|
|
79
|
+
observe: v.observe,
|
|
80
|
+
begin: async (t) => {
|
|
81
|
+
let n = c(t), r = g, i = _;
|
|
82
|
+
if (i === void 0) throw e("forbidden");
|
|
83
|
+
let a = await s(n);
|
|
84
|
+
if (g !== r || _ !== i) throw e("conflict");
|
|
85
|
+
return v.begin(a);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}, h = (e, t) => u(e, t, "voltro:iap-purchase:v1:", 2048, (e) => l(e));
|
|
89
|
+
export { h as browserIapPurchaseJournal, m as createIapPurchaseRecovery };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { captureBoundMethods as t, dataObject as n, identifier as r } from "./capture.js";
|
|
3
|
+
import { shopInteger as i } from "./shop.js";
|
|
4
|
+
import { economyRefundReversed as a, economyRefunded as o } from "./iapRefundEvents.js";
|
|
5
|
+
import { Effect as s } from "effect";
|
|
6
|
+
import { systemSubject as c } from "@voltro/protocol";
|
|
7
|
+
import { createHash as l } from "node:crypto";
|
|
8
|
+
import { defineSchedule as u, publishEvent as d } from "@voltro/runtime";
|
|
9
|
+
// src/iapRefundEventDelivery.server.ts
|
|
10
|
+
var f = () => null, p = (u) => {
|
|
11
|
+
let p = n(u, [
|
|
12
|
+
"events",
|
|
13
|
+
"publisher",
|
|
14
|
+
"version",
|
|
15
|
+
"maxEvents",
|
|
16
|
+
"sanctions",
|
|
17
|
+
"abusePolicy"
|
|
18
|
+
]), m = t(p.events, [
|
|
19
|
+
"pending",
|
|
20
|
+
"read",
|
|
21
|
+
"acknowledge"
|
|
22
|
+
]), h = t(p.publisher, ["read"]), g = r(p.version), _ = i(p.maxEvents ?? 1e3, 1, 1e5);
|
|
23
|
+
if (g === "default.v1" || p.abusePolicy !== void 0 && typeof p.abusePolicy != "function" || p.abusePolicy !== void 0 && p.sanctions === void 0) throw e("invalid_input");
|
|
24
|
+
let v = p.abusePolicy ?? f, y = p.sanctions === void 0 ? void 0 : t(p.sanctions, ["recordSignal"]), b = c("economy.refund-events");
|
|
25
|
+
return s.gen(function* () {
|
|
26
|
+
let t = yield* m.pending(b);
|
|
27
|
+
if (t.length > _) return yield* s.fail(e("limit_exceeded"));
|
|
28
|
+
let r = 0, i = 0;
|
|
29
|
+
for (let c of t) {
|
|
30
|
+
let t = yield* m.read(b, c), u = t.payload.refundNumerator === 0 ? null : v(structuredClone(t)), f = u === null ? null : n(u, ["confidence"], "invalid_record");
|
|
31
|
+
if (f && (typeof f.confidence != "number" || !Number.isFinite(f.confidence) || f.confidence < 0 || f.confidence > 1)) return yield* s.fail(e("invalid_record"));
|
|
32
|
+
if (f && !y) return yield* s.fail(e("unavailable"));
|
|
33
|
+
if (yield* m.read(b, c), f && y) {
|
|
34
|
+
let n = "refund_" + l("sha256").update(JSON.stringify([t.namespace, t.payload.orderId])).digest("hex").slice(0, 56);
|
|
35
|
+
yield* y.recordSignal(b, {
|
|
36
|
+
tenantId: t.tenantId,
|
|
37
|
+
targetId: t.subjectId,
|
|
38
|
+
requestId: n,
|
|
39
|
+
category: "rmt",
|
|
40
|
+
confidence: f.confidence
|
|
41
|
+
}).pipe(s.mapError(() => e("unavailable"))), i++;
|
|
42
|
+
}
|
|
43
|
+
let p = yield* m.read(b, c), _ = yield* h.read(p.tenantId);
|
|
44
|
+
if (_.tenantId !== p.tenantId || _.deferToCommit !== void 0) return yield* s.fail(e("forbidden"));
|
|
45
|
+
if (yield* m.read(b, c), (yield* d(_, p.payload.refundNumerator === 0 ? a : o, { subjectId: p.subjectId }, p.payload).pipe(s.mapError(() => e("unavailable")))).deferred) return yield* s.fail(e("unavailable"));
|
|
46
|
+
yield* m.acknowledge(b, c, g), r++;
|
|
47
|
+
}
|
|
48
|
+
return Object.freeze({
|
|
49
|
+
scannedRows: t.length,
|
|
50
|
+
deliveredEvents: r,
|
|
51
|
+
classifiedSignals: i
|
|
52
|
+
});
|
|
53
|
+
}).pipe(s.catchDefect(() => s.fail(e("unavailable"))));
|
|
54
|
+
}, m = (t) => {
|
|
55
|
+
let i = n(t, [
|
|
56
|
+
"events",
|
|
57
|
+
"publisher",
|
|
58
|
+
"version",
|
|
59
|
+
"maxEvents",
|
|
60
|
+
"sanctions",
|
|
61
|
+
"abusePolicy",
|
|
62
|
+
"name",
|
|
63
|
+
"cron",
|
|
64
|
+
"timezone"
|
|
65
|
+
]), a = r(i.name), o = i.cron, c = i.timezone ?? "UTC";
|
|
66
|
+
if (typeof o != "string" || !o.length || o.length > 120 || typeof c != "string" || !c.length || c.length > 120) throw e("invalid_input");
|
|
67
|
+
let l = p({
|
|
68
|
+
events: i.events,
|
|
69
|
+
publisher: i.publisher,
|
|
70
|
+
version: i.version,
|
|
71
|
+
maxEvents: i.maxEvents,
|
|
72
|
+
sanctions: i.sanctions,
|
|
73
|
+
abusePolicy: i.abusePolicy
|
|
74
|
+
});
|
|
75
|
+
return u({
|
|
76
|
+
name: a,
|
|
77
|
+
cron: o,
|
|
78
|
+
timezone: c,
|
|
79
|
+
handler: () => l.pipe(s.asVoid)
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
export { p as deliverIapRefundEvents, m as iapRefundEventSchedule, f as noRefundAbuseSignal };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { Context as t, Effect as n, Schema as r } from "effect";
|
|
3
|
+
import { defineEvent as i } from "@voltro/protocol";
|
|
4
|
+
// src/iapRefundEvents.ts
|
|
5
|
+
var a = r.String.pipe(r.check(r.makeFilter((e) => e.length <= 120 && /^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(e)))), o = r.Struct({
|
|
6
|
+
eventId: a,
|
|
7
|
+
orderId: a,
|
|
8
|
+
sequence: r.Number.pipe(r.check(r.isInt()), r.check(r.isBetween({
|
|
9
|
+
minimum: 1,
|
|
10
|
+
maximum: 1e5
|
|
11
|
+
}))),
|
|
12
|
+
state: r.Literals([
|
|
13
|
+
"active",
|
|
14
|
+
"partially-refunded",
|
|
15
|
+
"revoked"
|
|
16
|
+
]),
|
|
17
|
+
refundNumerator: r.Number.pipe(r.check(r.isInt()), r.check(r.isBetween({
|
|
18
|
+
minimum: 0,
|
|
19
|
+
maximum: 1e5
|
|
20
|
+
}))),
|
|
21
|
+
refundDenominator: r.Number.pipe(r.check(r.isInt()), r.check(r.isBetween({
|
|
22
|
+
minimum: 1,
|
|
23
|
+
maximum: 1e5
|
|
24
|
+
}))),
|
|
25
|
+
observedAt: r.Number.pipe(r.check(r.isInt()), r.check(r.isBetween({
|
|
26
|
+
minimum: 0,
|
|
27
|
+
maximum: 864e13
|
|
28
|
+
})))
|
|
29
|
+
}).pipe(r.check(r.makeFilter((e) => e.refundNumerator <= e.refundDenominator && e.state === (e.refundNumerator === 0 ? "active" : e.refundNumerator === e.refundDenominator ? "revoked" : "partially-refunded")))), s = i({
|
|
30
|
+
name: "economy.refunded",
|
|
31
|
+
key: r.Struct({ subjectId: a }),
|
|
32
|
+
payload: o,
|
|
33
|
+
guards: [{ scope: "economy:events:read" }]
|
|
34
|
+
}), c = i({
|
|
35
|
+
name: "economy.refundReversed",
|
|
36
|
+
key: r.Struct({ subjectId: a }),
|
|
37
|
+
payload: o,
|
|
38
|
+
guards: [{ scope: "economy:events:read" }]
|
|
39
|
+
}), l = class extends t.Service()("@voltro/IapRefundEventsPort") {}, u = () => n.fail(e("unavailable")), d = Object.freeze({
|
|
40
|
+
pending: u,
|
|
41
|
+
read: u,
|
|
42
|
+
acknowledge: u
|
|
43
|
+
});
|
|
44
|
+
export { o as IapRefundEventPayloadSchema, l as IapRefundEventsPort, c as economyRefundReversed, s as economyRefunded, d as unavailableIapRefundEvents };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { IapRefundEventsPort as t } from "./iapRefundEvents.js";
|
|
3
|
+
import { iapRefundsFixture as n } from "./iapRefunds.testFixtures.js";
|
|
4
|
+
import { Effect as r, Layer as i } from "effect";
|
|
5
|
+
import { systemSubject as a } from "@voltro/protocol";
|
|
6
|
+
import { InMemoryDataStore as o } from "@voltro/runtime";
|
|
7
|
+
// src/iapRefundEventsPort.fixture.ts
|
|
8
|
+
var s = /* @__PURE__ */ new WeakMap(), c = r.tryPromise({
|
|
9
|
+
try: () => n(new o(), "fixture.refund.events"),
|
|
10
|
+
catch: () => e("unavailable")
|
|
11
|
+
}).pipe(r.map((t) => {
|
|
12
|
+
let n = !1, i = (t) => r.suspend(() => n ? r.fail(e("unavailable")) : t()), a = Object.freeze({
|
|
13
|
+
pending: (e) => i(() => t.refunds.events.pending(e)),
|
|
14
|
+
read: (e, n) => i(() => t.refunds.events.read(e, n)),
|
|
15
|
+
acknowledge: (e, n, r) => i(() => t.refunds.events.acknowledge(e, n, r))
|
|
16
|
+
});
|
|
17
|
+
s.set(a, t);
|
|
18
|
+
let o = r.sync(() => {
|
|
19
|
+
n = !0;
|
|
20
|
+
}).pipe(r.flatMap(() => t.f.accounts.eraseSubject(t.privacy)), r.flatMap(() => t.refunds.eraseSubject(t.privacy)));
|
|
21
|
+
return Object.freeze({
|
|
22
|
+
service: a,
|
|
23
|
+
privacy: t.privacy,
|
|
24
|
+
create: () => r.tryPromise({
|
|
25
|
+
try: () => t.observeProvider(1),
|
|
26
|
+
catch: () => e("unavailable")
|
|
27
|
+
}).pipe(r.flatMap(t.refunds.reconcile)),
|
|
28
|
+
close: o
|
|
29
|
+
});
|
|
30
|
+
})), l = i.effect(t, r.acquireRelease(c, (e) => e.close.pipe(r.orDie)).pipe(r.map((e) => e.service))), u = Object.freeze({
|
|
31
|
+
kind: "port",
|
|
32
|
+
tag: t,
|
|
33
|
+
fakeLayer: l,
|
|
34
|
+
probe: {
|
|
35
|
+
run: () => r.scoped(r.gen(function* () {
|
|
36
|
+
let n = yield* t, i = s.get(n), o = a("fixture.refund.events");
|
|
37
|
+
if (!i) return yield* r.fail(e("unavailable"));
|
|
38
|
+
let c = yield* r.tryPromise({
|
|
39
|
+
try: () => i.observeProvider(1),
|
|
40
|
+
catch: () => e("unavailable")
|
|
41
|
+
});
|
|
42
|
+
yield* i.refunds.reconcile(c);
|
|
43
|
+
let [l] = yield* n.pending(o);
|
|
44
|
+
if (!l) return yield* r.fail(e("unavailable"));
|
|
45
|
+
let u = yield* n.read(o, l);
|
|
46
|
+
return yield* n.acknowledge(o, l, "fixture.delivery.v1"), {
|
|
47
|
+
state: u.payload.state,
|
|
48
|
+
originals: u.refundedOrders,
|
|
49
|
+
pending: (yield* n.pending(o)).length
|
|
50
|
+
};
|
|
51
|
+
}).pipe(r.provide(l))),
|
|
52
|
+
expected: {
|
|
53
|
+
state: "revoked",
|
|
54
|
+
originals: 1,
|
|
55
|
+
pending: 0
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
export { l as iapRefundEventsFakeLayer, c as iapRefundEventsPortFixture, u as iapRefundEventsPortSystemFixture };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { IapRefundPort as t } from "./iapRefunds.server.js";
|
|
3
|
+
import { iapRefundsFixture as n } from "./iapRefunds.testFixtures.js";
|
|
4
|
+
import { Effect as r, Layer as i } from "effect";
|
|
5
|
+
import { InMemoryDataStore as a } from "@voltro/runtime";
|
|
6
|
+
// src/iapRefundPort.fixture.ts
|
|
7
|
+
var o = /* @__PURE__ */ new WeakMap(), s = r.tryPromise({
|
|
8
|
+
try: () => n(new a()),
|
|
9
|
+
catch: () => e("unavailable")
|
|
10
|
+
}).pipe(r.map((t) => {
|
|
11
|
+
let n = !1, i = (t) => r.suspend(() => n ? r.fail(e("unavailable")) : t()), a = Object.freeze({
|
|
12
|
+
reconcile: (e) => i(() => t.refunds.reconcile(e)),
|
|
13
|
+
rebuild: (e) => i(() => t.refunds.rebuild(e)),
|
|
14
|
+
observe: (e, n) => i(() => t.refunds.observe(e, n)),
|
|
15
|
+
exportSubject: (e) => i(() => t.refunds.exportSubject(e)),
|
|
16
|
+
eraseSubject: (e) => i(() => t.refunds.eraseSubject(e))
|
|
17
|
+
});
|
|
18
|
+
return o.set(a, t), Object.freeze({
|
|
19
|
+
service: a,
|
|
20
|
+
fixture: t,
|
|
21
|
+
close: r.sync(() => {
|
|
22
|
+
n = !0;
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
})), c = i.effect(t, r.acquireRelease(s, (e) => e.close).pipe(r.map((e) => e.service))), l = Object.freeze({
|
|
26
|
+
kind: "port",
|
|
27
|
+
tag: t,
|
|
28
|
+
fakeLayer: c,
|
|
29
|
+
probe: {
|
|
30
|
+
run: () => r.scoped(r.gen(function* () {
|
|
31
|
+
let n = yield* t, i = o.get(n);
|
|
32
|
+
if (!i) return yield* r.fail(e("unavailable"));
|
|
33
|
+
let a = yield* r.tryPromise({
|
|
34
|
+
try: () => i.observeProvider(1),
|
|
35
|
+
catch: () => e("unavailable")
|
|
36
|
+
}), s = yield* n.reconcile(a), c = yield* n.reconcile(a), l = yield* n.rebuild(a), u = yield* i.f.economy.mine(i.f.user()), d = yield* i.f.inventory.mine(i.f.user());
|
|
37
|
+
return {
|
|
38
|
+
refunded: s.currencies[0]?.refunded,
|
|
39
|
+
wallet: u[0]?.balance,
|
|
40
|
+
stock: d.length,
|
|
41
|
+
replay: c.sequence === s.sequence,
|
|
42
|
+
rebuilt: l?.sequence === s.sequence
|
|
43
|
+
};
|
|
44
|
+
}).pipe(r.provide(c))),
|
|
45
|
+
expected: {
|
|
46
|
+
refunded: "20",
|
|
47
|
+
wallet: "0",
|
|
48
|
+
stock: 0,
|
|
49
|
+
replay: !0,
|
|
50
|
+
rebuilt: !0
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
export { c as iapRefundFakeLayer, s as iapRefundPortFixture, l as iapRefundPortSystemFixture };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { boolean as e, id as t, integer as n, json as r, table as i, text as a, timestamp as o } from "@voltro/database";
|
|
2
|
+
// src/iapRefundTables.entity.ts
|
|
3
|
+
var s = () => a().maxLength(120).serverOnly(), c = () => a().maxLength(120).externalId().sensitive("pii"), l = i("_voltro_eco_iap_refund_namespaces", {
|
|
4
|
+
id: t({ prefix: "ifn" }),
|
|
5
|
+
namespace: s(),
|
|
6
|
+
admission: n().serverOnly(),
|
|
7
|
+
configurationDigest: a().maxLength(64).serverOnly(),
|
|
8
|
+
rowsCount: n().serverOnly()
|
|
9
|
+
}), u = i("_voltro_eco_iap_refund_subjects", {
|
|
10
|
+
id: t({ prefix: "ifs" }),
|
|
11
|
+
namespace: s(),
|
|
12
|
+
tenantId: c(),
|
|
13
|
+
ownerId: a().maxLength(120).nullable().externalId().sensitive("pii"),
|
|
14
|
+
erased: e().serverOnly(),
|
|
15
|
+
admission: n().serverOnly(),
|
|
16
|
+
rowsCount: n().serverOnly()
|
|
17
|
+
}).index(["namespace", "tenantId"]), d = i("_voltro_eco_iap_refund_orders", {
|
|
18
|
+
id: t({ prefix: "ifo" }),
|
|
19
|
+
namespace: s(),
|
|
20
|
+
tenantId: c(),
|
|
21
|
+
ownerKey: a().maxLength(64).serverOnly(),
|
|
22
|
+
ownerId: a().maxLength(120).nullable().externalId().sensitive("pii"),
|
|
23
|
+
orderId: a().maxLength(64).serverOnly(),
|
|
24
|
+
admission: n().serverOnly(),
|
|
25
|
+
configurationDigest: a().maxLength(64).serverOnly(),
|
|
26
|
+
receipt: r().nullable().serverOnly(),
|
|
27
|
+
erased: e().serverOnly(),
|
|
28
|
+
rowsCount: n().serverOnly()
|
|
29
|
+
}).index("voltro_eco_iap_refund_orders_owner_idx", [
|
|
30
|
+
"namespace",
|
|
31
|
+
"tenantId",
|
|
32
|
+
"ownerKey"
|
|
33
|
+
]), f = i("_voltro_eco_iap_refund_adjustments", {
|
|
34
|
+
id: t({ prefix: "ifa" }),
|
|
35
|
+
namespace: s(),
|
|
36
|
+
tenantId: c(),
|
|
37
|
+
ownerKey: a().maxLength(64).serverOnly(),
|
|
38
|
+
ownerId: a().maxLength(120).nullable().externalId().sensitive("pii"),
|
|
39
|
+
orderId: a().maxLength(64).serverOnly(),
|
|
40
|
+
sequence: n().serverOnly(),
|
|
41
|
+
receipt: r().nullable().serverOnly(),
|
|
42
|
+
at: o().serverOnly(),
|
|
43
|
+
eventState: a().maxLength(16).serverOnly(),
|
|
44
|
+
eventDeliveryVersion: a().maxLength(120).nullable().serverOnly()
|
|
45
|
+
}).index(["namespace"]).index("voltro_eco_iap_refund_adjustments_owner_idx", [
|
|
46
|
+
"namespace",
|
|
47
|
+
"tenantId",
|
|
48
|
+
"ownerKey"
|
|
49
|
+
]).index(["namespace", "orderId"]), p = [
|
|
50
|
+
l,
|
|
51
|
+
u,
|
|
52
|
+
d,
|
|
53
|
+
f
|
|
54
|
+
];
|
|
55
|
+
export { f as iapRefundAdjustmentsTable, l as iapRefundNamespacesTable, d as iapRefundOrdersTable, u as iapRefundSubjectsTable, p as iapRefundTables };
|