@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.
Files changed (177) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +2719 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +9841 -0
  6. package/dist/amount.js +20 -0
  7. package/dist/appleIap.server.js +262 -0
  8. package/dist/appleIapNotifications.server.js +162 -0
  9. package/dist/appleIapTrust.server.js +30 -0
  10. package/dist/bundleValue.server.js +112 -0
  11. package/dist/canonicalDataJson.js +10 -0
  12. package/dist/capture.js +53 -0
  13. package/dist/codePort.fixture.js +123 -0
  14. package/dist/codeStore.server.js +439 -0
  15. package/dist/codeTables.entity.js +43 -0
  16. package/dist/codes.d.ts +150 -0
  17. package/dist/codes.js +82 -0
  18. package/dist/components.d.ts +397 -0
  19. package/dist/components.js +283 -0
  20. package/dist/consistency.server.js +115 -0
  21. package/dist/containerStore.server.js +687 -0
  22. package/dist/containerStore.testFixtures.js +75 -0
  23. package/dist/containerTables.entity.js +45 -0
  24. package/dist/containers.d.ts +311 -0
  25. package/dist/containers.fixture.js +128 -0
  26. package/dist/containers.js +214 -0
  27. package/dist/containers.server.js +39 -0
  28. package/dist/containersPort.fixture.js +74 -0
  29. package/dist/currency.js +32 -0
  30. package/dist/declarationFixtures.js +61 -0
  31. package/dist/economy-app/events/economy.refundReversed.event.ts +1 -0
  32. package/dist/economy-app/events/economy.refunded.event.ts +1 -0
  33. package/dist/economyPort.fixture.js +124 -0
  34. package/dist/errors.d.ts +14 -0
  35. package/dist/errors.js +21 -0
  36. package/dist/events.d.ts +46 -0
  37. package/dist/events.js +1 -0
  38. package/dist/googleIap.server.js +391 -0
  39. package/dist/googleIapNotifications.server.js +130 -0
  40. package/dist/googleIapSubscription.server.js +183 -0
  41. package/dist/iap.d.ts +309 -0
  42. package/dist/iap.js +303 -0
  43. package/dist/iap.testFixtures.js +144 -0
  44. package/dist/iapAccountTables.entity.js +39 -0
  45. package/dist/iapAccounts.server.js +200 -0
  46. package/dist/iapBinding.server.js +523 -0
  47. package/dist/iapCheckout.server.js +97 -0
  48. package/dist/iapCompletion.server.js +55 -0
  49. package/dist/iapCurrentState.server.js +107 -0
  50. package/dist/iapCurrentState.testFixtures.js +22 -0
  51. package/dist/iapCurrentStatePort.fixture.js +63 -0
  52. package/dist/iapEntitlements.d.ts +79 -0
  53. package/dist/iapEntitlements.js +57 -0
  54. package/dist/iapEntitlements.server.js +48 -0
  55. package/dist/iapEntitlementsBinding.server.js +105 -0
  56. package/dist/iapEntitlementsPort.fixture.js +80 -0
  57. package/dist/iapInstalledEntitlements.testFixtures.js +75 -0
  58. package/dist/iapInstalledNotifications.testFixtures.js +93 -0
  59. package/dist/iapInventoryRefunds.server.js +261 -0
  60. package/dist/iapNotificationCustodyPort.fixture.js +67 -0
  61. package/dist/iapNotificationPort.fixture.js +73 -0
  62. package/dist/iapNotificationProcessor.server.js +134 -0
  63. package/dist/iapNotificationProcessor.testFixtures.js +63 -0
  64. package/dist/iapNotificationProcessorPort.fixture.js +55 -0
  65. package/dist/iapNotificationSchedule.server.js +69 -0
  66. package/dist/iapNotificationStore.server.js +352 -0
  67. package/dist/iapNotificationStore.testFixtures.js +31 -0
  68. package/dist/iapNotificationTables.entity.js +48 -0
  69. package/dist/iapNotificationTarget.server.js +36 -0
  70. package/dist/iapNotificationTarget.testFixtures.js +29 -0
  71. package/dist/iapNotifications.d.ts +644 -0
  72. package/dist/iapNotifications.js +6 -0
  73. package/dist/iapNotifications.server.js +95 -0
  74. package/dist/iapNotificationsBinding.server.js +232 -0
  75. package/dist/iapNotificationsSystemPort.fixture.js +50 -0
  76. package/dist/iapPlugin.testFixtures.js +59 -0
  77. package/dist/iapPort.fixture.js +74 -0
  78. package/dist/iapProviderCapture.server.js +17 -0
  79. package/dist/iapRecovery.d.ts +146 -0
  80. package/dist/iapRecovery.js +89 -0
  81. package/dist/iapRefundEventDelivery.server.js +82 -0
  82. package/dist/iapRefundEvents.js +44 -0
  83. package/dist/iapRefundEventsPort.fixture.js +59 -0
  84. package/dist/iapRefundPort.fixture.js +54 -0
  85. package/dist/iapRefundTables.entity.js +55 -0
  86. package/dist/iapRefunds.d.ts +755 -0
  87. package/dist/iapRefunds.js +6 -0
  88. package/dist/iapRefunds.server.js +553 -0
  89. package/dist/iapRefunds.testFixtures.js +64 -0
  90. package/dist/iapSpendAdmission.server.js +98 -0
  91. package/dist/iapStore.server.js +740 -0
  92. package/dist/iapStore.testFixtures.js +127 -0
  93. package/dist/iapTables.entity.js +80 -0
  94. package/dist/iapVerification.server.js +120 -0
  95. package/dist/index.d.ts +2984 -0
  96. package/dist/index.js +15 -0
  97. package/dist/intentionRecovery.js +133 -0
  98. package/dist/ledger.js +77 -0
  99. package/dist/loyalty.d.ts +274 -0
  100. package/dist/loyalty.fixture.js +92 -0
  101. package/dist/loyalty.js +311 -0
  102. package/dist/loyaltyBinding.server.js +203 -0
  103. package/dist/loyaltyPort.fixture.js +86 -0
  104. package/dist/loyaltyShopSource.server.js +90 -0
  105. package/dist/loyaltyStore.server.js +552 -0
  106. package/dist/loyaltyStore.testFixtures.js +82 -0
  107. package/dist/loyaltyTables.entity.js +49 -0
  108. package/dist/offerMerchandising.fixture.js +114 -0
  109. package/dist/offerMerchandising.js +282 -0
  110. package/dist/offerPolicies.d.ts +441 -0
  111. package/dist/offerPolicies.fixture.js +53 -0
  112. package/dist/offerPolicies.js +267 -0
  113. package/dist/piggyBanks.d.ts +272 -0
  114. package/dist/piggyBanks.fixture.js +70 -0
  115. package/dist/piggyBanks.js +200 -0
  116. package/dist/piggyBinding.server.js +204 -0
  117. package/dist/piggyPort.fixture.js +72 -0
  118. package/dist/piggyStore.server.js +610 -0
  119. package/dist/piggyStore.testFixtures.js +97 -0
  120. package/dist/piggyTables.entity.js +40 -0
  121. package/dist/plugin.js +1047 -0
  122. package/dist/port.js +12 -0
  123. package/dist/price.d.ts +99 -0
  124. package/dist/price.js +143 -0
  125. package/dist/purchaseRecovery.js +55 -0
  126. package/dist/reports.server.js +114 -0
  127. package/dist/rpc.d.ts +3201 -0
  128. package/dist/rpc.js +1200 -0
  129. package/dist/sanctionsTradeAuthority.server.js +79 -0
  130. package/dist/server.d.ts +3856 -0
  131. package/dist/server.js +43 -0
  132. package/dist/shop.d.ts +279 -0
  133. package/dist/shop.js +195 -0
  134. package/dist/shop.testFixtures.js +113 -0
  135. package/dist/shopPort.fixture.js +71 -0
  136. package/dist/shopPresentation.js +67 -0
  137. package/dist/shopStore.server.js +623 -0
  138. package/dist/shopTables.entity.js +62 -0
  139. package/dist/shopUiCopy.js +56 -0
  140. package/dist/spendLimits.d.ts +140 -0
  141. package/dist/spendLimits.fixture.js +52 -0
  142. package/dist/spendLimits.js +154 -0
  143. package/dist/spendLimitsPort.fixture.js +119 -0
  144. package/dist/subscriptionBinding.server.js +210 -0
  145. package/dist/subscriptionStore.server.js +642 -0
  146. package/dist/subscriptionStore.testFixtures.js +71 -0
  147. package/dist/subscriptionTables.entity.js +36 -0
  148. package/dist/subscriptions.d.ts +394 -0
  149. package/dist/subscriptions.fixture.js +96 -0
  150. package/dist/subscriptions.js +212 -0
  151. package/dist/subscriptionsPort.fixture.js +75 -0
  152. package/dist/systemFixtures.js +88 -0
  153. package/dist/tables.entity.js +82 -0
  154. package/dist/testing.d.ts +4615 -0
  155. package/dist/testing.js +29 -0
  156. package/dist/tradeAuthority.server.js +171 -0
  157. package/dist/tradeBinding.server.js +200 -0
  158. package/dist/tradeComponents.js +341 -0
  159. package/dist/tradeEscrow.server.js +231 -0
  160. package/dist/tradeEscrow.testFixtures.js +132 -0
  161. package/dist/tradeExpiry.server.js +42 -0
  162. package/dist/tradeRecovery.js +47 -0
  163. package/dist/tradeStore.server.js +749 -0
  164. package/dist/tradeStore.testFixtures.js +72 -0
  165. package/dist/tradeTables.entity.js +65 -0
  166. package/dist/tradeUiCopy.js +78 -0
  167. package/dist/trades.d.ts +246 -0
  168. package/dist/trades.fixture.js +102 -0
  169. package/dist/trades.js +288 -0
  170. package/dist/tradesPort.fixture.js +93 -0
  171. package/dist/walletEscrow.js +105 -0
  172. package/dist/walletEscrow.server.js +375 -0
  173. package/dist/walletKeys.server.js +4 -0
  174. package/dist/walletStore.js +570 -0
  175. package/dist/web.d.ts +2257 -0
  176. package/dist/web.js +8 -0
  177. package/package.json +161 -4
@@ -0,0 +1,523 @@
1
+ import { EconomyError as e, economyError as t } from "./errors.js";
2
+ import { captureBoundMethods as n, captureQueryTables as r, dataList as i, dataObject as a, declaredSources as o, identifier as s } from "./capture.js";
3
+ import { captureCurrencies as c } from "./currency.js";
4
+ import { IapPort as l, captureIapObservation as u, captureIapService as ee, defineIapCatalog as te, iapChannel as d, iapEnvironment as f, iapReceiptIntent as p, iapReceiptReference as ne } from "./iap.js";
5
+ import { bindIapEntitlementsSystem as re } from "./iapEntitlementsBinding.server.js";
6
+ import { canonicalDataJson as m } from "./canonicalDataJson.js";
7
+ import { bindIapNotificationsSystem as ie } from "./iapNotificationsBinding.server.js";
8
+ import { iapAccountTables as ae } from "./iapAccountTables.entity.js";
9
+ import { IapAccountsPort as oe, dataStoreIapAccountOwners as se, dataStoreIapAccounts as ce } from "./iapAccounts.server.js";
10
+ import { readVerifiedIapPurchase as le } from "./iapVerification.server.js";
11
+ import { iapTables as ue } from "./iapTables.entity.js";
12
+ import { captureIapCompletionService as de } from "./iapCompletion.server.js";
13
+ import { dataStoreIap as fe, resolveIapStoreOptions as pe } from "./iapStore.server.js";
14
+ import { captureIapCheckoutOrigins as me, captureIapCheckoutReturnUrl as h, captureIapCheckoutService as he, captureIapDelivery as ge, captureIapDeliveryService as _e, captureIapManagementService as ve, captureIapManagementUrl as ye, iapCheckoutIntent as be, iapCheckoutStart as xe } from "./iapCheckout.server.js";
15
+ import { iapAccountDescriptor as Se, iapCheckEntitlementDescriptor as Ce, iapCheckoutDescriptor as we, iapCheckoutRpcClientImports as Te, iapCompleteDescriptor as Ee, iapCompletionRpcClientImports as De, iapEntitledDescriptor as Oe, iapEntitlementRpcClientImports as ke, iapManageDescriptor as Ae, iapManageRpcClientImports as je, iapReceiptDescriptor as g, iapRedeemDescriptor as Me, iapRefundReceiptSources as Ne, iapRpcClientImports as Pe } from "./rpc.js";
16
+ import { Context as _, Effect as v, Layer as y } from "effect";
17
+ // src/iapBinding.server.ts
18
+ var b = class extends _.Service()("@voltro/IapSystemPort") {}, x = (e) => n(e, [
19
+ "initialize",
20
+ "account",
21
+ "complete",
22
+ "redeem",
23
+ "receipt",
24
+ "exportSubject",
25
+ "eraseSubject"
26
+ ]), S = () => v.fail(t("unavailable")), C = Object.freeze({
27
+ initialize: S,
28
+ account: S,
29
+ complete: S,
30
+ redeem: S,
31
+ receipt: S,
32
+ exportSubject: S,
33
+ eraseSubject: S
34
+ }), w = (n) => n instanceof e ? n : t("unavailable"), T = (e, _) => {
35
+ if (e === void 0) return;
36
+ if (!_.realMoney) throw t("real_money_disabled");
37
+ let C = a(e, [
38
+ "version",
39
+ "products",
40
+ "providers",
41
+ "namespace",
42
+ "admission",
43
+ "inventory",
44
+ "systemAccount",
45
+ "maxHistoryRows",
46
+ "now",
47
+ "notifications",
48
+ "entitlements",
49
+ "service",
50
+ "querySources"
51
+ ]), T = s(C.version), E = c(_.currencies);
52
+ if (T === "default.v1") throw t("invalid_input");
53
+ let D = te(C.products, E, !0);
54
+ if (D.length === 0) throw t("invalid_input");
55
+ let O = C.service === void 0 ? void 0 : x(C.service);
56
+ if (_.replacedWallet && !O || O && [
57
+ "providers",
58
+ "namespace",
59
+ "admission",
60
+ "inventory",
61
+ "systemAccount",
62
+ "maxHistoryRows",
63
+ "now"
64
+ ].some((e) => C[e] !== void 0)) throw t("invalid_input");
65
+ let k = C.querySources === void 0 ? void 0 : a(C.querySources, ["receipt"]);
66
+ if (O && !k) throw t("invalid_input");
67
+ let A = k ? r(k.receipt) : [], j = O ? [] : i(C.providers, 4).map((e) => {
68
+ let n = a(e, [
69
+ "channel",
70
+ "environment",
71
+ "applicationId",
72
+ "create",
73
+ "createCompletion",
74
+ "createNotifications",
75
+ "createCurrentState",
76
+ "createCheckout",
77
+ "checkoutReturnOrigins",
78
+ "createDeliveries",
79
+ "createManagement"
80
+ ]);
81
+ if (typeof n.create != "function" || n.createCompletion !== void 0 && typeof n.createCompletion != "function" || n.createNotifications !== void 0 && typeof n.createNotifications != "function" || n.createCurrentState !== void 0 && typeof n.createCurrentState != "function" || n.createCheckout !== void 0 && typeof n.createCheckout != "function" || n.createCheckout === void 0 != (n.checkoutReturnOrigins === void 0) || n.createDeliveries !== void 0 && typeof n.createDeliveries != "function" || n.createManagement !== void 0 && typeof n.createManagement != "function") throw t("invalid_input");
82
+ return Object.freeze({
83
+ channel: d(n.channel),
84
+ environment: f(n.environment),
85
+ applicationId: s(n.applicationId),
86
+ create: n.create,
87
+ createCompletion: n.createCompletion,
88
+ createNotifications: n.createNotifications,
89
+ createCurrentState: n.createCurrentState,
90
+ createCheckout: n.createCheckout,
91
+ checkoutReturnOrigins: n.checkoutReturnOrigins === void 0 ? void 0 : me(n.checkoutReturnOrigins),
92
+ createDeliveries: n.createDeliveries,
93
+ createManagement: n.createManagement
94
+ });
95
+ });
96
+ if (!O && (D.some((e) => e.kind === "subscription") && C.entitlements === void 0 || j.length === 0 || new Set(j.map((e) => e.channel)).size !== j.length || D.some((e) => !j.some((t) => t.channel === e.channel)) || j.some((e) => !D.some((t) => t.channel === e.channel)))) throw t("invalid_input");
97
+ let M = O ? void 0 : pe({
98
+ realMoney: !0,
99
+ namespace: C.namespace,
100
+ currencies: E,
101
+ economy: _.economy,
102
+ verification: { verify: S },
103
+ admission: C.admission,
104
+ inventory: C.inventory,
105
+ systemAccount: C.systemAccount,
106
+ maxHistoryRows: C.maxHistoryRows,
107
+ now: C.now ?? _.now
108
+ }), N, P, F, I = !1, L = 0, R = [], z = [], B = [], V = ie(C.notifications, {
109
+ namespace: M?.namespace ?? T,
110
+ channels: D.map((e) => e.channel),
111
+ declarations: j,
112
+ itemOrders: D.some((e) => e.offer.items.length > 0),
113
+ economy: _.economy,
114
+ isActive: () => I,
115
+ replacedIap: O !== void 0,
116
+ deliver: (e, t) => Le(e, t)
117
+ });
118
+ if (V?.status.orderDisposition === "custom" && A.length === 0) throw t("invalid_input");
119
+ let H = re(C.entitlements, {
120
+ replacedIap: O !== void 0,
121
+ subscriptionOffers: D.filter((e) => e.kind === "subscription").map((e) => e.offer.id),
122
+ refundDispositionInstalled: V?.dispositionSource !== void 0,
123
+ now: M?.now ?? _.now,
124
+ historyRows: M?.maxHistoryRows ?? null,
125
+ isActive: () => I
126
+ }), U = (e) => {
127
+ try {
128
+ return e();
129
+ } catch (e) {
130
+ return v.fail(w(e));
131
+ }
132
+ }, W = (e) => v.suspend(() => {
133
+ let t = O ?? P, n = L;
134
+ return I && t ? v.suspend(() => e(t)).pipe(v.flatMap((e) => I && L === n && (O ?? P) === t ? v.succeed(e) : S()), v.catchDefect(() => S())) : S();
135
+ }), G = (e) => {
136
+ let n = structuredClone(e);
137
+ if (n.type !== "user") throw t("forbidden");
138
+ return s(n.id), s(n.tenantId), n;
139
+ }, K = (e) => {
140
+ let n = a(e, [
141
+ "tenantId",
142
+ "subjectId",
143
+ "kind"
144
+ ]);
145
+ if (n.kind !== "guest" && n.kind !== "user") throw t("invalid_input");
146
+ return Object.freeze({
147
+ tenantId: s(n.tenantId),
148
+ subjectId: s(n.subjectId),
149
+ kind: n.kind
150
+ });
151
+ }, q = () => v.suspend(() => {
152
+ let e = O ?? P, n = L;
153
+ return !N || !e ? S() : (I = !1, v.suspend(() => e.initialize()).pipe(v.flatMap(() => O && V ? V.initialize() : v.void), v.flatMap(() => H ? H.initialize() : v.void), v.flatMap(() => v.try({
154
+ try: () => {
155
+ if (L !== n || (O ?? P) !== e) throw t("unavailable");
156
+ I = !0;
157
+ },
158
+ catch: w
159
+ })), v.catchDefect(() => S())));
160
+ }), J = Object.freeze({
161
+ initialize: q,
162
+ account: (e, n) => U(() => {
163
+ let r = G(e), i = d(n);
164
+ if (!D.some((e) => e.channel === i)) throw t("forbidden");
165
+ return W((e) => e.account(r, i));
166
+ }),
167
+ redeem: (e, t) => U(() => {
168
+ let n = G(e), r = p(t);
169
+ return W((e) => e.redeem(n, r));
170
+ }),
171
+ complete: (e, t) => U(() => {
172
+ let n = G(e), r = p(t);
173
+ return W((e) => e.complete(n, r));
174
+ }),
175
+ receipt: (e, n) => U(() => {
176
+ let r = G(e), i = ne(n);
177
+ return W((e) => e.receipt(r, i).pipe(v.flatMap((e) => v.try({
178
+ try: () => {
179
+ let n = u(e);
180
+ if (n.requestId !== i.requestId || "receipt" in n && (n.receipt.offerId !== i.offerId || n.receipt.offerVersion !== i.offerVersion)) throw t("conflict");
181
+ return n;
182
+ },
183
+ catch: w
184
+ }))));
185
+ }),
186
+ exportSubject: (e) => U(() => {
187
+ let t = K(e);
188
+ return W((e) => v.gen(function* () {
189
+ let n = yield* e.exportSubject(t), r = O && V ? {
190
+ system: n,
191
+ notifications: yield* V.service.exportSubject(t)
192
+ } : n;
193
+ return H?.custom ? {
194
+ system: r,
195
+ entitlements: yield* H.service.exportSubject(t)
196
+ } : r;
197
+ }));
198
+ }),
199
+ eraseSubject: (e) => U(() => {
200
+ let t = K(e);
201
+ return W((e) => v.gen(function* () {
202
+ H?.custom && (yield* H.service.eraseSubject(t)), yield* e.eraseSubject(t), O && V && (yield* V.service.eraseSubject(t));
203
+ }));
204
+ })
205
+ }), Fe = (e, n) => U(() => {
206
+ let r = G(e), i = be(n), a = d(i.channel), o = L, s = B.find((e) => e.channel === a), c = D.find((e) => e.channel === a && e.offer.id === i.offerId && e.offer.version === i.offerVersion);
207
+ if (!I || !s) return S();
208
+ if (!c) return v.fail(t("forbidden"));
209
+ let l = h(i.returnUrl, s.origins), u = Object.freeze({
210
+ tenantId: r.tenantId,
211
+ ownerId: r.id
212
+ });
213
+ return (M?.admission.checkout ? M.admission.checkout(Object.freeze({
214
+ scope: u,
215
+ product: c,
216
+ at: s.now()
217
+ })) : v.void).pipe(v.flatMap(() => s.accounts.read(u, a, s.environment)), v.flatMap((e) => xe(s.service, Object.freeze({
218
+ scope: u,
219
+ product: c,
220
+ requestId: i.requestId,
221
+ accountToken: e,
222
+ returnUrl: l,
223
+ at: s.now()
224
+ }))), v.flatMap((e) => I && L === o ? v.succeed(e) : S()));
225
+ }), Ie = /* @__PURE__ */ new Set([
226
+ "forbidden",
227
+ "limit_exceeded",
228
+ "already_redeemed",
229
+ "conflict",
230
+ "erased",
231
+ "not_found"
232
+ ]), Le = (e, t) => v.suspend(() => {
233
+ let n = R.find((t) => t.channel === e);
234
+ return n ? I ? n.service.read(t).pipe(v.flatMap((t) => {
235
+ if (t === null) return v.succeed(!1);
236
+ let r = ge(t);
237
+ return n.owners.owner(r.accountToken).pipe(v.flatMap((t) => t === null ? v.succeed(!0) : J.redeem({
238
+ type: "user",
239
+ id: t.ownerId,
240
+ tenantId: t.tenantId
241
+ }, {
242
+ channel: e,
243
+ offerId: r.offerId,
244
+ offerVersion: r.offerVersion,
245
+ requestId: r.requestId,
246
+ receipt: r.receipt
247
+ }).pipe(v.as(!0), v.catchIf((e) => Ie.has(e.code), () => v.succeed(!0)))));
248
+ }), v.catchDefect(() => S())) : S() : v.succeed(!1);
249
+ }), Re = (e, t) => U(() => {
250
+ let n = G(e), r = d(t.channel), i = z.find((e) => e.channel === r), a = B.find((e) => e.channel === r)?.origins;
251
+ if (!I || !i || !a) return S();
252
+ let o = h(t.returnUrl, a), s = Object.freeze({
253
+ tenantId: n.tenantId,
254
+ ownerId: n.id
255
+ }), c = L;
256
+ return v.all([i.accounts.observe(s, r, i.environment), i.originals(n)]).pipe(v.flatMap(([e, t]) => i.service.open({
257
+ accountToken: e,
258
+ originals: t,
259
+ returnUrl: o,
260
+ at: i.now()
261
+ })), v.flatMap((e) => v.try({
262
+ try: () => ye(e),
263
+ catch: w
264
+ })), v.flatMap((e) => I && L === c ? v.succeed(e) : S()), v.catchDefect(() => S()));
265
+ }), ze = Object.freeze({
266
+ read: (e, t, n) => U(() => {
267
+ let r = structuredClone(e), i = d(t), a = f(n);
268
+ return v.suspend(() => I && F ? F.read(r, i, a) : S());
269
+ }),
270
+ observe: (e, t, n) => U(() => {
271
+ let r = structuredClone(e), i = d(t), a = f(n);
272
+ return v.suspend(() => I && F ? F.observe(r, i, a) : S());
273
+ }),
274
+ prepareBinding: (e, t, n, r) => U(() => {
275
+ let i = structuredClone(e), a = d(t), o = f(n);
276
+ return v.suspend(() => I && F ? F.prepareBinding(i, a, o, r) : S());
277
+ }),
278
+ exportSubject: (e) => U(() => {
279
+ let t = K(e);
280
+ return v.suspend(() => I && F ? F.exportSubject(t) : S());
281
+ }),
282
+ eraseSubject: (e) => U(() => {
283
+ let t = K(e);
284
+ return v.suspend(() => I && F ? F.eraseSubject(t) : S());
285
+ })
286
+ }), Y = O ? A : [.../* @__PURE__ */ new Set([
287
+ ...o(g.source).filter((e) => M?.inventory !== void 0 || !e.startsWith("voltro_inv_")),
288
+ ...V?.status.orderDisposition === "sql" ? Ne : [],
289
+ ...A
290
+ ])], Be = H ? H.custom ? H.querySources : [.../* @__PURE__ */ new Set([...Y, ...H.querySources])] : [], X = O !== void 0 || j.some((e) => e.createCompletion !== void 0), Z = j.some((e) => e.createCheckout !== void 0), Q = j.some((e) => e.createManagement !== void 0 && e.createCheckout !== void 0), Ve = [
291
+ {
292
+ ...g,
293
+ source: Y,
294
+ execute: (e, t) => J.receipt(t.request.subject, e)
295
+ },
296
+ ...H ? [{
297
+ ...Oe,
298
+ source: Be,
299
+ execute: (e, t) => H.service.entitled(t.request.subject, e.offerId)
300
+ }, {
301
+ ...Ce,
302
+ execute: (e, t) => H.service.entitled(t.request.subject, e.offerId)
303
+ }] : [],
304
+ {
305
+ ...Se,
306
+ execute: (e, t) => J.account(t.request.subject, e.channel)
307
+ },
308
+ {
309
+ ...Me,
310
+ execute: (e, t) => J.redeem(t.request.subject, e)
311
+ },
312
+ ...X ? [{
313
+ ...Ee,
314
+ execute: (e, t) => J.complete(t.request.subject, e)
315
+ }] : [],
316
+ ...Z ? [{
317
+ ...we,
318
+ execute: (e, t) => Fe(t.request.subject, e)
319
+ }] : [],
320
+ ...Q ? [{
321
+ ...Ae,
322
+ execute: (e, t) => Re(t.request.subject, e)
323
+ }] : []
324
+ ], $ = y.merge(y.succeed(l, ee(J)), y.succeed(b, x(J))), He = Object.freeze({
325
+ backend: O ? "custom" : "sql",
326
+ version: T,
327
+ providers: j.map((e) => ({
328
+ channel: e.channel,
329
+ environment: e.environment,
330
+ applicationId: e.applicationId,
331
+ completionInstalled: e.createCompletion !== void 0,
332
+ checkoutInstalled: e.createCheckout !== void 0,
333
+ deliveriesInstalled: e.createDeliveries !== void 0 && V !== void 0,
334
+ managementInstalled: e.createManagement !== void 0 && e.createCheckout !== void 0
335
+ })),
336
+ products: D.map((e) => ({
337
+ channel: e.channel,
338
+ kind: e.kind,
339
+ offerId: e.offer.id,
340
+ offerVersion: e.offer.version,
341
+ storeProductId: e.storeProductId
342
+ })),
343
+ verificationSource: "custom",
344
+ admissionSource: O ? "app-owned" : "prepared-sql",
345
+ itemParticipant: O ? "app-owned" : M?.inventory ? "prepared-sql" : "none",
346
+ budgets: O ? null : Object.freeze({ historyRows: M.maxHistoryRows }),
347
+ receiptFulfillmentInstalled: !0,
348
+ notificationInstalled: V !== void 0,
349
+ providerCompletionInstalled: X,
350
+ subscriptionEntitlementsInstalled: H !== void 0,
351
+ entitlementsSystem: H?.status ?? null,
352
+ refundDebtInstalled: V !== void 0,
353
+ clientRecoveryInstalled: !1,
354
+ gmActionsInstalled: !1,
355
+ notificationSystem: V?.status ?? null
356
+ }), Ue = (e) => {
357
+ if (N !== void 0 && N !== e) throw Error("IAP system cannot cross app stores");
358
+ if (N = e, I = !1, L++, P = void 0, F = void 0, !M) {
359
+ V?.bind(e, void 0, []), H?.bind(e, void 0);
360
+ return;
361
+ }
362
+ let r = L, i = () => {
363
+ if (L !== r || N !== e) throw t("unavailable");
364
+ return M.now();
365
+ }, a = j.map((t) => {
366
+ let r = ce(e, {
367
+ realMoney: !0,
368
+ channel: t.channel,
369
+ environment: t.environment,
370
+ applicationId: t.applicationId
371
+ }), a = Object.freeze({
372
+ realMoney: !0,
373
+ channel: t.channel,
374
+ environment: t.environment,
375
+ applicationId: t.applicationId,
376
+ products: Object.freeze(D.filter((e) => e.channel === t.channel).map((e) => Object.freeze({
377
+ offer: e.offer,
378
+ channel: e.channel,
379
+ kind: e.kind
380
+ }))),
381
+ currencies: E,
382
+ accounts: r,
383
+ now: i
384
+ }), o = n(t.create(a), ["initialize", "verify"]), s = t.createCompletion === void 0 ? void 0 : de(t.createCompletion(a)), c = t.createCheckout === void 0 ? void 0 : he(t.createCheckout(a)), l = t.createDeliveries === void 0 ? void 0 : _e(t.createDeliveries(a)), u = t.createManagement === void 0 ? void 0 : ve(t.createManagement(a));
385
+ return Object.freeze({
386
+ ...t,
387
+ context: a,
388
+ accounts: r,
389
+ verification: o,
390
+ completion: s,
391
+ checkoutService: c,
392
+ deliveryService: l,
393
+ managementService: u
394
+ });
395
+ });
396
+ R = Object.freeze(a.flatMap((t) => t.deliveryService ? [Object.freeze({
397
+ channel: t.channel,
398
+ service: t.deliveryService,
399
+ owners: se(e, {
400
+ realMoney: !0,
401
+ channel: t.channel,
402
+ environment: t.environment,
403
+ applicationId: t.applicationId
404
+ })
405
+ })] : [])), B = Object.freeze(a.flatMap((e) => e.checkoutService && e.checkoutReturnOrigins ? [Object.freeze({
406
+ channel: e.channel,
407
+ environment: e.environment,
408
+ origins: e.checkoutReturnOrigins,
409
+ service: e.checkoutService,
410
+ accounts: e.accounts,
411
+ now: i
412
+ })] : []));
413
+ let o = (e, n) => {
414
+ let r = a.find((t) => t.channel === e && t.environment === n);
415
+ if (!r) throw t("forbidden");
416
+ return r;
417
+ };
418
+ F = Object.freeze({
419
+ read: (e, t, n) => U(() => o(t, n).accounts.read(e, t, n)),
420
+ observe: (e, t, n) => U(() => o(t, n).accounts.observe(e, t, n)),
421
+ prepareBinding: (e, t, n, r) => U(() => o(t, n).accounts.prepareBinding(e, t, n, r)),
422
+ exportSubject: (e) => v.gen(function* () {
423
+ let t = [];
424
+ for (let n of a) t.push({
425
+ channel: n.channel,
426
+ environment: n.environment,
427
+ data: yield* n.accounts.exportSubject(e)
428
+ });
429
+ return { bindings: t };
430
+ }),
431
+ eraseSubject: (e) => v.gen(function* () {
432
+ for (let t of a) yield* t.accounts.eraseSubject(e);
433
+ })
434
+ });
435
+ let s = { verify: ((e, n) => U(() => {
436
+ let r = a.find((e) => e.channel === n.channel), i = D.find((e) => e.channel === n.channel && e.offer.id === n.offerId && e.offer.version === n.offerVersion);
437
+ return !r || !i ? v.fail(t("forbidden")) : r.verification.verify(e, n).pipe(v.flatMap((e) => v.try({
438
+ try: () => {
439
+ let n = le(e);
440
+ if (n.facts.applicationId !== r.applicationId || n.facts.environment !== r.environment || m(n.product) !== m(i) || m(n.currencies) !== m(E)) throw t("forbidden");
441
+ return e;
442
+ },
443
+ catch: w
444
+ })));
445
+ })) }, c = fe(e, {
446
+ realMoney: !0,
447
+ ...M,
448
+ verification: s,
449
+ refundDisposition: V?.dispositionSource,
450
+ now: i
451
+ }), l = F;
452
+ z = Object.freeze(a.flatMap((e) => e.managementService ? [Object.freeze({
453
+ channel: e.channel,
454
+ environment: e.environment,
455
+ service: e.managementService,
456
+ accounts: e.accounts,
457
+ now: i,
458
+ originals: (t) => c.subscriptionOriginals(t, e.channel)
459
+ })] : [])), V?.bind(e, c, a.map((e) => ({
460
+ declaration: e,
461
+ context: e.context
462
+ }))), H?.bind(e, c), P = Object.freeze({
463
+ ...c,
464
+ initialize: () => v.gen(function* () {
465
+ for (let e of a) yield* e.verification.initialize(), e.completion && (yield* e.completion.initialize()), e.checkoutService && (yield* e.checkoutService.initialize()), e.deliveryService && (yield* e.deliveryService.initialize()), e.managementService && (yield* e.managementService.initialize());
466
+ V && (yield* V.initialize());
467
+ }),
468
+ account: (e, n) => U(() => {
469
+ let r = G(e), i = a.find((e) => e.channel === n);
470
+ return i ? i.accounts.read({
471
+ tenantId: r.tenantId,
472
+ ownerId: r.id
473
+ }, i.channel, i.environment) : v.fail(t("forbidden"));
474
+ }),
475
+ complete: (e, t) => U(() => {
476
+ let n = G(e), r = p(t), i = a.find((e) => e.channel === r.channel), o = L;
477
+ if (!i?.completion) return S();
478
+ let s = i.completion;
479
+ return c.prepareCompletion(n, r).pipe(v.flatMap((e) => v.suspend(() => I && L === o ? s.complete(e) : S())));
480
+ }),
481
+ exportSubject: (e) => v.gen(function* () {
482
+ return {
483
+ accounts: yield* l.exportSubject(e),
484
+ orders: yield* c.exportSubject(e),
485
+ ...V ? { notifications: yield* V.service.exportSubject(e) } : {}
486
+ };
487
+ }),
488
+ eraseSubject: (e) => l.eraseSubject(e).pipe(v.flatMap(() => V ? V.service.eraseSubject(e) : v.void), v.flatMap(() => c.eraseSubject(e)))
489
+ });
490
+ }, We = O ? $ : y.merge($, y.succeed(oe, ze)), Ge = V ? y.merge(We, V.layer) : We;
491
+ return Object.freeze({
492
+ service: J,
493
+ activate: q,
494
+ bind: Ue,
495
+ routes: Ve,
496
+ status: He,
497
+ notifications: V?.service,
498
+ entitlements: H?.service,
499
+ refundEvents: V?.events,
500
+ httpRoutes: V?.httpRoutes ?? [],
501
+ rpcClientDescriptors: [
502
+ ...Pe,
503
+ ...X ? De : [],
504
+ ...Z ? Te : [],
505
+ ...Q ? je : [],
506
+ ...H ? ke : []
507
+ ],
508
+ layer: H ? y.merge(Ge, H.layer) : Ge,
509
+ tables: [...M ? [...ae, ...ue] : [], ...V?.tables ?? []],
510
+ roles: [...M ? [
511
+ "iapAccounts",
512
+ "iapAccountTokens",
513
+ "iapNamespaces",
514
+ "iapSubjects",
515
+ "iapOrders",
516
+ "iapReceipts"
517
+ ] : [], ...V?.roles ?? []],
518
+ deactivate: () => {
519
+ I = !1, L++, P = void 0, F = void 0, B = [], R = [], z = [], V?.deactivate(), H?.deactivate();
520
+ }
521
+ });
522
+ };
523
+ export { b as IapSystemPort, T as bindIapSystem, x as captureIapSystemService, C as unavailableIap };
@@ -0,0 +1,97 @@
1
+ import { EconomyError as e, economyError as t } from "./errors.js";
2
+ import { captureBoundMethods as n, dataList as r, dataObject as i, identifier as a } from "./capture.js";
3
+ import { iapTimestamp as o } from "./iap.js";
4
+ import { Effect as s } from "effect";
5
+ // src/iapCheckout.server.ts
6
+ var c = (e) => n(e, ["initialize", "start"]), l = (e) => {
7
+ let n = r(e, 16).map((e) => {
8
+ if (typeof e != "string") throw t("invalid_input");
9
+ let n;
10
+ try {
11
+ n = new URL(e);
12
+ } catch {
13
+ throw t("invalid_input");
14
+ }
15
+ let r = n.hostname === "localhost" || n.hostname === "127.0.0.1";
16
+ if (n.origin !== e || n.protocol !== "https:" && !(n.protocol === "http:" && r)) throw t("invalid_input");
17
+ return e;
18
+ });
19
+ if (n.length === 0) throw t("invalid_input");
20
+ return Object.freeze(n);
21
+ }, u = (e, n) => {
22
+ if (typeof e != "string" || e.length > 2048) throw t("invalid_input");
23
+ let r;
24
+ try {
25
+ r = new URL(e);
26
+ } catch {
27
+ throw t("invalid_input");
28
+ }
29
+ if (!n.includes(r.origin) || r.username || r.password) throw t("forbidden");
30
+ return r.toString();
31
+ }, d = (e, n) => {
32
+ let r = i(e, [
33
+ "checkoutId",
34
+ "redirectUrl",
35
+ "expiresAt"
36
+ ], "invalid_record");
37
+ if (typeof r.checkoutId != "string" || r.checkoutId.length === 0 || r.checkoutId.length > 512 || /[\u0000- \u007f]/.test(r.checkoutId)) throw t("invalid_record");
38
+ let a;
39
+ try {
40
+ a = new URL(r.redirectUrl);
41
+ } catch {
42
+ throw t("invalid_record");
43
+ }
44
+ if (a.protocol !== "https:" && (a.protocol !== "http:" || a.hostname !== "localhost" && a.hostname !== "127.0.0.1")) throw t("invalid_record");
45
+ let s = o(r.expiresAt);
46
+ if (s <= n) throw t("invalid_record");
47
+ return Object.freeze({
48
+ checkoutId: r.checkoutId,
49
+ redirectUrl: a.toString(),
50
+ expiresAt: s
51
+ });
52
+ }, f = (e) => {
53
+ let n = i(e, [
54
+ "channel",
55
+ "offerId",
56
+ "offerVersion",
57
+ "requestId",
58
+ "returnUrl"
59
+ ]);
60
+ if (typeof n.channel != "string" || typeof n.returnUrl != "string") throw t("invalid_input");
61
+ return Object.freeze({
62
+ channel: n.channel,
63
+ offerId: a(n.offerId),
64
+ offerVersion: a(n.offerVersion),
65
+ requestId: a(n.requestId),
66
+ returnUrl: n.returnUrl
67
+ });
68
+ }, p = (n) => n instanceof e ? n : t("unavailable"), m = (e, n) => s.suspend(() => e.start(n)).pipe(s.flatMap((e) => s.try({
69
+ try: () => d(e, n.at),
70
+ catch: p
71
+ })), s.catchDefect(() => s.fail(t("unavailable")))), h = (e) => n(e, ["initialize", "read"]), g = (e) => {
72
+ let n = i(e, [
73
+ "accountToken",
74
+ "offerId",
75
+ "offerVersion",
76
+ "requestId",
77
+ "receipt"
78
+ ], "invalid_record");
79
+ if (typeof n.accountToken != "string" || typeof n.receipt != "string" || n.receipt.length === 0 || n.receipt.length > 65536 || /[\u0000-\u0020\u007f]/.test(n.receipt)) throw t("invalid_record");
80
+ return Object.freeze({
81
+ accountToken: n.accountToken,
82
+ offerId: a(n.offerId, "invalid_record"),
83
+ offerVersion: a(n.offerVersion, "invalid_record"),
84
+ requestId: a(n.requestId, "invalid_record"),
85
+ receipt: n.receipt
86
+ });
87
+ }, _ = (e) => n(e, ["initialize", "open"]), v = (e) => {
88
+ let n = i(e, ["url"], "invalid_record"), r;
89
+ try {
90
+ r = new URL(n.url);
91
+ } catch {
92
+ throw t("invalid_record");
93
+ }
94
+ if (r.protocol !== "https:") throw t("invalid_record");
95
+ return Object.freeze({ url: r.toString() });
96
+ };
97
+ export { l as captureIapCheckoutOrigins, u as captureIapCheckoutReturnUrl, c as captureIapCheckoutService, d as captureIapCheckoutSession, g as captureIapDelivery, h as captureIapDeliveryService, _ as captureIapManagementService, v as captureIapManagementUrl, p as iapCheckoutFailure, f as iapCheckoutIntent, m as iapCheckoutStart };
@@ -0,0 +1,55 @@
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 { captureCurrencies as a } from "./currency.js";
4
+ import { captureIapCompletionReceipt as o, defineIapCatalog as s, iapChannel as c, iapEnvironment as l, iapTimestamp as u } from "./iap.js";
5
+ import { canonicalDataJson as d } from "./canonicalDataJson.js";
6
+ import { Context as f, Effect as p } from "effect";
7
+ // src/iapCompletion.server.ts
8
+ var m = class extends f.Service()("@voltro/IapCompletionPort") {}, h = /* @__PURE__ */ new WeakMap(), g = (e, t) => {
9
+ let n = Object.freeze({ orderId: i(e) });
10
+ return h.set(n, t), n;
11
+ }, _ = (e) => {
12
+ let n = typeof e == "object" && e ? h.get(e) : void 0;
13
+ return n ? p.suspend(n) : p.fail(t("forbidden"));
14
+ }, v = (n) => n instanceof e ? n : t("unavailable"), y = (e) => n(e, ["initialize", "complete"]), b = (e, f) => {
15
+ let m = r(e, [
16
+ "realMoney",
17
+ "channel",
18
+ "environment",
19
+ "applicationId",
20
+ "products",
21
+ "currencies",
22
+ "accounts",
23
+ "now"
24
+ ]);
25
+ if (m.realMoney !== !0) throw t(m.realMoney === !1 ? "real_money_disabled" : "invalid_input");
26
+ let h = c(m.channel), g = l(m.environment), y = i(m.applicationId), b = a(m.currencies), x = s(m.products, b, !0);
27
+ if (!x.length || x.some((e) => e.channel !== h)) throw t("invalid_input");
28
+ let S = n(m.accounts, ["read", "prepareBinding"]), C = n(f, ["initialize", "complete"]), w = m.now ?? Date.now;
29
+ if (typeof w != "function") throw t("invalid_input");
30
+ return Object.freeze({
31
+ initialize: () => p.suspend(() => C.initialize()).pipe(p.catchDefect(() => p.fail(t("unavailable")))),
32
+ complete: (e) => _(e).pipe(p.flatMap((e) => p.try({
33
+ try: () => {
34
+ let n = x.find((t) => t.channel === e.intent.channel && t.offer.id === e.intent.offerId && t.offer.version === e.intent.offerVersion);
35
+ if (!n || e.facts.channel !== h || e.facts.environment !== g || e.facts.applicationId !== y || d(e.product) !== d(n) || d(e.currencies) !== d(b)) throw t("forbidden");
36
+ return Object.freeze({
37
+ ...e,
38
+ at: u(w())
39
+ });
40
+ },
41
+ catch: v
42
+ })), p.flatMap((e) => S.read(e.scope, h, g).pipe(p.map((t) => Object.freeze({
43
+ ...e,
44
+ accountToken: t
45
+ })))), p.flatMap((e) => p.suspend(() => C.complete(e)).pipe(p.flatMap((n) => p.try({
46
+ try: () => {
47
+ let r = o(n);
48
+ if (r.orderId !== e.orderId || r.channel !== h || r.observedAt < e.at) throw t("invalid_record");
49
+ return r;
50
+ },
51
+ catch: v
52
+ })))), p.catchDefect(() => p.fail(t("unavailable"))))
53
+ });
54
+ };
55
+ export { m as IapCompletionPort, y as captureIapCompletionService, b as iapCompletionPort, g as issueAcceptedIapCompletion };