@chipmobilesdk/rn-payment 0.6.0 → 0.7.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 (295) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +1 -1
  3. package/lib/commonjs/adapter/createStoreProvider.js +110 -0
  4. package/lib/commonjs/adapter/createStoreProvider.js.map +1 -0
  5. package/lib/commonjs/adapter/iap-adapter.js +393 -0
  6. package/lib/commonjs/adapter/iap-adapter.js.map +1 -0
  7. package/lib/commonjs/adapter/iapShapes.js +169 -0
  8. package/lib/commonjs/adapter/iapShapes.js.map +1 -0
  9. package/lib/commonjs/adapter/port.js +6 -0
  10. package/lib/commonjs/adapter/port.js.map +1 -0
  11. package/lib/commonjs/config/types.js +2 -0
  12. package/lib/commonjs/config/types.js.map +1 -0
  13. package/lib/commonjs/config/validate.js +181 -0
  14. package/lib/commonjs/config/validate.js.map +1 -0
  15. package/lib/commonjs/core/mutex.js +31 -0
  16. package/lib/commonjs/core/mutex.js.map +1 -0
  17. package/lib/commonjs/core/retry.js +37 -0
  18. package/lib/commonjs/core/retry.js.map +1 -0
  19. package/lib/commonjs/core/timers.js +207 -0
  20. package/lib/commonjs/core/timers.js.map +1 -0
  21. package/lib/commonjs/diagnostics/errors.js +83 -0
  22. package/lib/commonjs/diagnostics/errors.js.map +1 -0
  23. package/lib/commonjs/diagnostics/events.js +126 -0
  24. package/lib/commonjs/diagnostics/events.js.map +1 -0
  25. package/lib/commonjs/diagnostics/messageKeys.js +70 -0
  26. package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
  27. package/lib/commonjs/engine/connection.js +189 -0
  28. package/lib/commonjs/engine/connection.js.map +1 -0
  29. package/lib/commonjs/engine/engine.js +279 -0
  30. package/lib/commonjs/engine/engine.js.map +1 -0
  31. package/lib/commonjs/engine/finalize.js +325 -0
  32. package/lib/commonjs/engine/finalize.js.map +1 -0
  33. package/lib/commonjs/engine/foreground.js +26 -0
  34. package/lib/commonjs/engine/foreground.js.map +1 -0
  35. package/lib/commonjs/engine/internals.js +31 -0
  36. package/lib/commonjs/engine/internals.js.map +1 -0
  37. package/lib/commonjs/engine/pending.js +102 -0
  38. package/lib/commonjs/engine/pending.js.map +1 -0
  39. package/lib/commonjs/engine/products.js +198 -0
  40. package/lib/commonjs/engine/products.js.map +1 -0
  41. package/lib/commonjs/engine/purchase.js +395 -0
  42. package/lib/commonjs/engine/purchase.js.map +1 -0
  43. package/lib/commonjs/engine/purchaseFailure.js +77 -0
  44. package/lib/commonjs/engine/purchaseFailure.js.map +1 -0
  45. package/lib/commonjs/engine/receiptValidation.js +90 -0
  46. package/lib/commonjs/engine/receiptValidation.js.map +1 -0
  47. package/lib/commonjs/engine/state.js +201 -0
  48. package/lib/commonjs/engine/state.js.map +1 -0
  49. package/lib/commonjs/engine/subscriptions.js +122 -0
  50. package/lib/commonjs/engine/subscriptions.js.map +1 -0
  51. package/lib/commonjs/engine/sync.js +163 -0
  52. package/lib/commonjs/engine/sync.js.map +1 -0
  53. package/lib/commonjs/entitlements/aggregate.js +212 -0
  54. package/lib/commonjs/entitlements/aggregate.js.map +1 -0
  55. package/lib/commonjs/entitlements/mapping.js +41 -0
  56. package/lib/commonjs/entitlements/mapping.js.map +1 -0
  57. package/lib/commonjs/entitlements/policy.js +110 -0
  58. package/lib/commonjs/entitlements/policy.js.map +1 -0
  59. package/lib/commonjs/index.js +266 -0
  60. package/lib/commonjs/index.js.map +1 -0
  61. package/lib/commonjs/package.json +1 -0
  62. package/lib/commonjs/persistence/mmkv-store.js +149 -0
  63. package/lib/commonjs/persistence/mmkv-store.js.map +1 -0
  64. package/lib/commonjs/persistence/snapshot.js +229 -0
  65. package/lib/commonjs/persistence/snapshot.js.map +1 -0
  66. package/lib/commonjs/react/PaymentProvider.js +96 -0
  67. package/lib/commonjs/react/PaymentProvider.js.map +1 -0
  68. package/lib/commonjs/react/hooks.js +202 -0
  69. package/lib/commonjs/react/hooks.js.map +1 -0
  70. package/lib/commonjs/testing/conformance.js +136 -0
  71. package/lib/commonjs/testing/conformance.js.map +1 -0
  72. package/lib/commonjs/testing/fakeStore.js +281 -0
  73. package/lib/commonjs/testing/fakeStore.js.map +1 -0
  74. package/lib/commonjs/testing/index.js +45 -0
  75. package/lib/commonjs/testing/index.js.map +1 -0
  76. package/lib/module/adapter/createStoreProvider.js +106 -0
  77. package/lib/module/adapter/createStoreProvider.js.map +1 -0
  78. package/lib/module/adapter/iap-adapter.js +383 -0
  79. package/lib/module/adapter/iap-adapter.js.map +1 -0
  80. package/lib/module/adapter/iapShapes.js +160 -0
  81. package/lib/module/adapter/iapShapes.js.map +1 -0
  82. package/lib/module/adapter/port.js +4 -0
  83. package/lib/module/adapter/port.js.map +1 -0
  84. package/lib/module/config/types.js +2 -0
  85. package/lib/module/config/types.js.map +1 -0
  86. package/lib/module/config/validate.js +175 -0
  87. package/lib/module/config/validate.js.map +1 -0
  88. package/lib/module/core/mutex.js +22 -0
  89. package/lib/module/core/mutex.js.map +1 -0
  90. package/lib/module/core/retry.js +33 -0
  91. package/lib/module/core/retry.js.map +1 -0
  92. package/lib/module/core/timers.js +198 -0
  93. package/lib/module/core/timers.js.map +1 -0
  94. package/lib/module/diagnostics/errors.js +76 -0
  95. package/lib/module/diagnostics/errors.js.map +1 -0
  96. package/lib/module/diagnostics/events.js +117 -0
  97. package/lib/module/diagnostics/events.js.map +1 -0
  98. package/lib/module/diagnostics/messageKeys.js +64 -0
  99. package/lib/module/diagnostics/messageKeys.js.map +1 -0
  100. package/lib/module/engine/connection.js +185 -0
  101. package/lib/module/engine/connection.js.map +1 -0
  102. package/lib/module/engine/engine.js +274 -0
  103. package/lib/module/engine/engine.js.map +1 -0
  104. package/lib/module/engine/finalize.js +322 -0
  105. package/lib/module/engine/finalize.js.map +1 -0
  106. package/lib/module/engine/foreground.js +21 -0
  107. package/lib/module/engine/foreground.js.map +1 -0
  108. package/lib/module/engine/internals.js +26 -0
  109. package/lib/module/engine/internals.js.map +1 -0
  110. package/lib/module/engine/pending.js +95 -0
  111. package/lib/module/engine/pending.js.map +1 -0
  112. package/lib/module/engine/products.js +195 -0
  113. package/lib/module/engine/products.js.map +1 -0
  114. package/lib/module/engine/purchase.js +390 -0
  115. package/lib/module/engine/purchase.js.map +1 -0
  116. package/lib/module/engine/purchaseFailure.js +72 -0
  117. package/lib/module/engine/purchaseFailure.js.map +1 -0
  118. package/lib/module/engine/receiptValidation.js +87 -0
  119. package/lib/module/engine/receiptValidation.js.map +1 -0
  120. package/lib/module/engine/state.js +196 -0
  121. package/lib/module/engine/state.js.map +1 -0
  122. package/lib/module/engine/subscriptions.js +119 -0
  123. package/lib/module/engine/subscriptions.js.map +1 -0
  124. package/lib/module/engine/sync.js +158 -0
  125. package/lib/module/engine/sync.js.map +1 -0
  126. package/lib/module/entitlements/aggregate.js +204 -0
  127. package/lib/module/entitlements/aggregate.js.map +1 -0
  128. package/lib/module/entitlements/mapping.js +35 -0
  129. package/lib/module/entitlements/mapping.js.map +1 -0
  130. package/lib/module/entitlements/policy.js +104 -0
  131. package/lib/module/entitlements/policy.js.map +1 -0
  132. package/lib/module/index.js +59 -0
  133. package/lib/module/index.js.map +1 -0
  134. package/lib/module/package.json +1 -0
  135. package/lib/module/persistence/mmkv-store.js +144 -0
  136. package/lib/module/persistence/mmkv-store.js.map +1 -0
  137. package/lib/module/persistence/snapshot.js +221 -0
  138. package/lib/module/persistence/snapshot.js.map +1 -0
  139. package/lib/module/react/PaymentProvider.js +90 -0
  140. package/lib/module/react/PaymentProvider.js.map +1 -0
  141. package/lib/module/react/hooks.js +192 -0
  142. package/lib/module/react/hooks.js.map +1 -0
  143. package/lib/module/testing/conformance.js +130 -0
  144. package/lib/module/testing/conformance.js.map +1 -0
  145. package/lib/module/testing/fakeStore.js +276 -0
  146. package/lib/module/testing/fakeStore.js.map +1 -0
  147. package/lib/module/testing/index.js +13 -0
  148. package/lib/module/testing/index.js.map +1 -0
  149. package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts +45 -0
  150. package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts.map +1 -0
  151. package/lib/typescript/commonjs/adapter/iap-adapter.d.ts +80 -0
  152. package/lib/typescript/commonjs/adapter/iap-adapter.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/adapter/iapShapes.d.ts +94 -0
  154. package/lib/typescript/commonjs/adapter/iapShapes.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/adapter/port.d.ts +184 -0
  156. package/lib/typescript/commonjs/adapter/port.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/config/types.d.ts +326 -0
  158. package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/config/validate.d.ts +63 -0
  160. package/lib/typescript/commonjs/config/validate.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/core/mutex.d.ts +17 -0
  162. package/lib/typescript/commonjs/core/mutex.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/core/retry.d.ts +19 -0
  164. package/lib/typescript/commonjs/core/retry.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/core/timers.d.ts +142 -0
  166. package/lib/typescript/commonjs/core/timers.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/diagnostics/errors.d.ts +55 -0
  168. package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/diagnostics/events.d.ts +158 -0
  170. package/lib/typescript/commonjs/diagnostics/events.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +54 -0
  172. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
  173. package/lib/typescript/commonjs/engine/connection.d.ts +30 -0
  174. package/lib/typescript/commonjs/engine/connection.d.ts.map +1 -0
  175. package/lib/typescript/commonjs/engine/engine.d.ts +93 -0
  176. package/lib/typescript/commonjs/engine/engine.d.ts.map +1 -0
  177. package/lib/typescript/commonjs/engine/finalize.d.ts +53 -0
  178. package/lib/typescript/commonjs/engine/finalize.d.ts.map +1 -0
  179. package/lib/typescript/commonjs/engine/foreground.d.ts +15 -0
  180. package/lib/typescript/commonjs/engine/foreground.d.ts.map +1 -0
  181. package/lib/typescript/commonjs/engine/internals.d.ts +28 -0
  182. package/lib/typescript/commonjs/engine/internals.d.ts.map +1 -0
  183. package/lib/typescript/commonjs/engine/pending.d.ts +51 -0
  184. package/lib/typescript/commonjs/engine/pending.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/engine/products.d.ts +82 -0
  186. package/lib/typescript/commonjs/engine/products.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/engine/purchase.d.ts +61 -0
  188. package/lib/typescript/commonjs/engine/purchase.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/engine/purchaseFailure.d.ts +15 -0
  190. package/lib/typescript/commonjs/engine/purchaseFailure.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/engine/receiptValidation.d.ts +42 -0
  192. package/lib/typescript/commonjs/engine/receiptValidation.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/engine/state.d.ts +46 -0
  194. package/lib/typescript/commonjs/engine/state.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/engine/subscriptions.d.ts +61 -0
  196. package/lib/typescript/commonjs/engine/subscriptions.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/engine/sync.d.ts +36 -0
  198. package/lib/typescript/commonjs/engine/sync.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/entitlements/aggregate.d.ts +97 -0
  200. package/lib/typescript/commonjs/entitlements/aggregate.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/entitlements/mapping.d.ts +27 -0
  202. package/lib/typescript/commonjs/entitlements/mapping.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/entitlements/policy.d.ts +75 -0
  204. package/lib/typescript/commonjs/entitlements/policy.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/index.d.ts +44 -0
  206. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/package.json +1 -0
  208. package/lib/typescript/commonjs/persistence/mmkv-store.d.ts +45 -0
  209. package/lib/typescript/commonjs/persistence/mmkv-store.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/persistence/snapshot.d.ts +106 -0
  211. package/lib/typescript/commonjs/persistence/snapshot.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/react/PaymentProvider.d.ts +57 -0
  213. package/lib/typescript/commonjs/react/PaymentProvider.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/react/hooks.d.ts +80 -0
  215. package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/testing/conformance.d.ts +41 -0
  217. package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/testing/fakeStore.d.ts +69 -0
  219. package/lib/typescript/commonjs/testing/fakeStore.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/testing/index.d.ts +12 -0
  221. package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
  222. package/lib/typescript/module/adapter/createStoreProvider.d.ts +45 -0
  223. package/lib/typescript/module/adapter/createStoreProvider.d.ts.map +1 -0
  224. package/lib/typescript/module/adapter/iap-adapter.d.ts +80 -0
  225. package/lib/typescript/module/adapter/iap-adapter.d.ts.map +1 -0
  226. package/lib/typescript/module/adapter/iapShapes.d.ts +94 -0
  227. package/lib/typescript/module/adapter/iapShapes.d.ts.map +1 -0
  228. package/lib/typescript/module/adapter/port.d.ts +184 -0
  229. package/lib/typescript/module/adapter/port.d.ts.map +1 -0
  230. package/lib/typescript/module/config/types.d.ts +326 -0
  231. package/lib/typescript/module/config/types.d.ts.map +1 -0
  232. package/lib/typescript/module/config/validate.d.ts +63 -0
  233. package/lib/typescript/module/config/validate.d.ts.map +1 -0
  234. package/lib/typescript/module/core/mutex.d.ts +17 -0
  235. package/lib/typescript/module/core/mutex.d.ts.map +1 -0
  236. package/lib/typescript/module/core/retry.d.ts +19 -0
  237. package/lib/typescript/module/core/retry.d.ts.map +1 -0
  238. package/lib/typescript/module/core/timers.d.ts +142 -0
  239. package/lib/typescript/module/core/timers.d.ts.map +1 -0
  240. package/lib/typescript/module/diagnostics/errors.d.ts +55 -0
  241. package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
  242. package/lib/typescript/module/diagnostics/events.d.ts +158 -0
  243. package/lib/typescript/module/diagnostics/events.d.ts.map +1 -0
  244. package/lib/typescript/module/diagnostics/messageKeys.d.ts +54 -0
  245. package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
  246. package/lib/typescript/module/engine/connection.d.ts +30 -0
  247. package/lib/typescript/module/engine/connection.d.ts.map +1 -0
  248. package/lib/typescript/module/engine/engine.d.ts +93 -0
  249. package/lib/typescript/module/engine/engine.d.ts.map +1 -0
  250. package/lib/typescript/module/engine/finalize.d.ts +53 -0
  251. package/lib/typescript/module/engine/finalize.d.ts.map +1 -0
  252. package/lib/typescript/module/engine/foreground.d.ts +15 -0
  253. package/lib/typescript/module/engine/foreground.d.ts.map +1 -0
  254. package/lib/typescript/module/engine/internals.d.ts +28 -0
  255. package/lib/typescript/module/engine/internals.d.ts.map +1 -0
  256. package/lib/typescript/module/engine/pending.d.ts +51 -0
  257. package/lib/typescript/module/engine/pending.d.ts.map +1 -0
  258. package/lib/typescript/module/engine/products.d.ts +82 -0
  259. package/lib/typescript/module/engine/products.d.ts.map +1 -0
  260. package/lib/typescript/module/engine/purchase.d.ts +61 -0
  261. package/lib/typescript/module/engine/purchase.d.ts.map +1 -0
  262. package/lib/typescript/module/engine/purchaseFailure.d.ts +15 -0
  263. package/lib/typescript/module/engine/purchaseFailure.d.ts.map +1 -0
  264. package/lib/typescript/module/engine/receiptValidation.d.ts +42 -0
  265. package/lib/typescript/module/engine/receiptValidation.d.ts.map +1 -0
  266. package/lib/typescript/module/engine/state.d.ts +46 -0
  267. package/lib/typescript/module/engine/state.d.ts.map +1 -0
  268. package/lib/typescript/module/engine/subscriptions.d.ts +61 -0
  269. package/lib/typescript/module/engine/subscriptions.d.ts.map +1 -0
  270. package/lib/typescript/module/engine/sync.d.ts +36 -0
  271. package/lib/typescript/module/engine/sync.d.ts.map +1 -0
  272. package/lib/typescript/module/entitlements/aggregate.d.ts +97 -0
  273. package/lib/typescript/module/entitlements/aggregate.d.ts.map +1 -0
  274. package/lib/typescript/module/entitlements/mapping.d.ts +27 -0
  275. package/lib/typescript/module/entitlements/mapping.d.ts.map +1 -0
  276. package/lib/typescript/module/entitlements/policy.d.ts +75 -0
  277. package/lib/typescript/module/entitlements/policy.d.ts.map +1 -0
  278. package/lib/typescript/module/index.d.ts +44 -0
  279. package/lib/typescript/module/index.d.ts.map +1 -0
  280. package/lib/typescript/module/package.json +1 -0
  281. package/lib/typescript/module/persistence/mmkv-store.d.ts +45 -0
  282. package/lib/typescript/module/persistence/mmkv-store.d.ts.map +1 -0
  283. package/lib/typescript/module/persistence/snapshot.d.ts +106 -0
  284. package/lib/typescript/module/persistence/snapshot.d.ts.map +1 -0
  285. package/lib/typescript/module/react/PaymentProvider.d.ts +57 -0
  286. package/lib/typescript/module/react/PaymentProvider.d.ts.map +1 -0
  287. package/lib/typescript/module/react/hooks.d.ts +80 -0
  288. package/lib/typescript/module/react/hooks.d.ts.map +1 -0
  289. package/lib/typescript/module/testing/conformance.d.ts +41 -0
  290. package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
  291. package/lib/typescript/module/testing/fakeStore.d.ts +69 -0
  292. package/lib/typescript/module/testing/fakeStore.d.ts.map +1 -0
  293. package/lib/typescript/module/testing/index.d.ts +12 -0
  294. package/lib/typescript/module/testing/index.d.ts.map +1 -0
  295. package/package.json +49 -13
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FAILURE_CODES = void 0;
7
+ exports.mapFailure = mapFailure;
8
+ /**
9
+ * What a refused purchase means to the app (PAY-19).
10
+ *
11
+ * The store answers with a reason of its own; this turns it into the result the
12
+ * app sees, under the code it can branch on, so no store vocabulary leaks out.
13
+ * Split from the flow next door, which is about the sequence of calls.
14
+ */
15
+
16
+ const FAILURE_CODES = exports.FAILURE_CODES = {
17
+ network_error: 'PAYMENT_NETWORK_ERROR',
18
+ unknown_product: 'PAYMENT_UNKNOWN_PRODUCT',
19
+ ineligible: 'PAYMENT_INELIGIBLE',
20
+ product_unavailable_in_region: 'PAYMENT_PRODUCT_UNAVAILABLE_IN_REGION'
21
+ };
22
+
23
+ /** Maps a provider failure onto the public vocabulary, so no store code leaks out. */
24
+ function mapFailure(reason, productKey, status) {
25
+ switch (reason) {
26
+ case 'user_cancelled':
27
+ return {
28
+ kind: 'user_cancelled',
29
+ productKey
30
+ };
31
+ case 'already_owned':
32
+ return {
33
+ kind: 'already_owned',
34
+ productKey
35
+ };
36
+ case 'ineligible':
37
+ return {
38
+ kind: 'ineligible',
39
+ productKey
40
+ };
41
+ case 'unknown_product':
42
+ return {
43
+ kind: 'unknown_product',
44
+ productKey
45
+ };
46
+ case 'product_unavailable_in_region':
47
+ return {
48
+ kind: 'product_unavailable_in_region',
49
+ productKey
50
+ };
51
+ case 'not_ready':
52
+ // The engine's real status, not a guess (PAY-19).
53
+ return {
54
+ kind: 'not_ready',
55
+ status
56
+ };
57
+ case 'network_error':
58
+ return {
59
+ kind: 'network_error',
60
+ productKey
61
+ };
62
+ case 'timeout':
63
+ return {
64
+ kind: 'timeout',
65
+ productKey
66
+ };
67
+ case 'store_error':
68
+ return {
69
+ kind: 'store_error',
70
+ productKey,
71
+ code: 'PAYMENT_STORE_ERROR'
72
+ };
73
+ }
74
+ }
75
+
76
+ /** Plan-change parameters, which only `subscriptions.ts` supplies. */
77
+ //# sourceMappingURL=purchaseFailure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FAILURE_CODES","exports","network_error","unknown_product","ineligible","product_unavailable_in_region","mapFailure","reason","productKey","status","kind","code"],"sourceRoot":"../../../src","sources":["engine/purchaseFailure.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKO,MAAMA,aAAwE,GAAAC,OAAA,CAAAD,aAAA,GAAG;EACvFE,aAAa,EAAE,uBAAuB;EACtCC,eAAe,EAAE,yBAAyB;EAC1CC,UAAU,EAAE,oBAAoB;EAChCC,6BAA6B,EAAE;AAChC,CAAC;;AAED;AACO,SAASC,UAAUA,CACzBC,MAA6B,EAC7BC,UAAsB,EACtBC,MAAyB,EACR;EACjB,QAAQF,MAAM;IACb,KAAK,gBAAgB;MACpB,OAAO;QAAEG,IAAI,EAAE,gBAAgB;QAAEF;MAAW,CAAC;IAC9C,KAAK,eAAe;MACnB,OAAO;QAAEE,IAAI,EAAE,eAAe;QAAEF;MAAW,CAAC;IAC7C,KAAK,YAAY;MAChB,OAAO;QAAEE,IAAI,EAAE,YAAY;QAAEF;MAAW,CAAC;IAC1C,KAAK,iBAAiB;MACrB,OAAO;QAAEE,IAAI,EAAE,iBAAiB;QAAEF;MAAW,CAAC;IAC/C,KAAK,+BAA+B;MACnC,OAAO;QAAEE,IAAI,EAAE,+BAA+B;QAAEF;MAAW,CAAC;IAC7D,KAAK,WAAW;MACf;MACA,OAAO;QAAEE,IAAI,EAAE,WAAW;QAAED;MAAO,CAAC;IACrC,KAAK,eAAe;MACnB,OAAO;QAAEC,IAAI,EAAE,eAAe;QAAEF;MAAW,CAAC;IAC7C,KAAK,SAAS;MACb,OAAO;QAAEE,IAAI,EAAE,SAAS;QAAEF;MAAW,CAAC;IACvC,KAAK,aAAa;MACjB,OAAO;QAAEE,IAAI,EAAE,aAAa;QAAEF,UAAU;QAAEG,IAAI,EAAE;MAAsB,CAAC;EACzE;AACD;;AAEA","ignoreList":[]}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createReceiptValidation = createReceiptValidation;
7
+ var _mutex = require("../core/mutex.js");
8
+ var _errors = require("../diagnostics/errors.js");
9
+ /**
10
+ * Asking the app's backend whether a purchase is real (FR-069a, FR-072b).
11
+ *
12
+ * The hook is optional and bounded by a timeout, and its answer decides whether
13
+ * an entitlement is granted — so what happens when it throws, times out, or is
14
+ * absent is the whole point of this module. Split from the flow next door,
15
+ * which is about the sequence of store calls.
16
+ *
17
+ * A hook that could not answer is never an implicit approval: the configured
18
+ * `onValidationUnavailable` decides, and the default refuses.
19
+ */
20
+
21
+ /** What the backend decided about one purchase. */
22
+
23
+ function createReceiptValidation(deps) {
24
+ const {
25
+ resolved
26
+ } = deps;
27
+ const askHook = (hook, candidate) => (0, _mutex.withTimeout)(hook(candidate), resolved.timeouts.validateMs, () => new _errors.PaymentError({
28
+ code: 'PAYMENT_VALIDATION_UNAVAILABLE',
29
+ message: 'The validation hook did not answer in time',
30
+ operation: 'validate',
31
+ retryable: true
32
+ }));
33
+
34
+ /**
35
+ * Runs the app's backend check, if configured.
36
+ *
37
+ * Called for newly completed purchases only (FR-069a) — sync and restore trust
38
+ * a decision already made, which is what keeps restore working while the
39
+ * backend is unreachable.
40
+ */
41
+ const validate = async (purchase, productKey, correlationId) => {
42
+ const hook = deps.config.validateTransaction;
43
+ if (!hook) {
44
+ return {
45
+ outcome: 'approved'
46
+ };
47
+ }
48
+ const entry = resolved.entries.get(productKey);
49
+ try {
50
+ const decision = await askHook(hook, {
51
+ productKey,
52
+ productType: entry?.productType ?? 'one_time_permanent',
53
+ verificationPayload: purchase.verificationPayload ?? '',
54
+ correlationId,
55
+ transactionId: purchase.transactionId,
56
+ platform: deps.platform
57
+ });
58
+ deps.emit({
59
+ type: 'validation_decided',
60
+ productKey,
61
+ decision: decision.approved ? 'approved' : 'rejected'
62
+ });
63
+ return decision.approved ? {
64
+ outcome: 'approved'
65
+ } : {
66
+ outcome: 'rejected',
67
+ reason: decision.reason
68
+ };
69
+ } catch {
70
+ // A hook that throws is unavailable, never an implicit approval (FR-072b).
71
+ const fallback = resolved.onValidationUnavailable;
72
+ deps.emit({
73
+ type: 'validation_unavailable',
74
+ productKey,
75
+ fallback
76
+ });
77
+ return fallback === 'grant_and_queue' ? {
78
+ outcome: 'granted_pending_revalidation'
79
+ } : {
80
+ outcome: 'rejected',
81
+ reason: 'validation_unavailable'
82
+ };
83
+ }
84
+ };
85
+ return {
86
+ askHook,
87
+ validate
88
+ };
89
+ }
90
+ //# sourceMappingURL=receiptValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_mutex","require","_errors","createReceiptValidation","deps","resolved","askHook","hook","candidate","withTimeout","timeouts","validateMs","PaymentError","code","message","operation","retryable","validate","purchase","productKey","correlationId","config","validateTransaction","outcome","entry","entries","get","decision","productType","verificationPayload","transactionId","platform","emit","type","approved","reason","fallback","onValidationUnavailable"],"sourceRoot":"../../../src","sources":["engine/receiptValidation.ts"],"mappings":";;;;;;AAeA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAhBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAeA;;AAMO,SAASE,uBAAuBA,CAACC,IAA2B,EAAE;EACpE,MAAM;IAAEC;EAAS,CAAC,GAAGD,IAAI;EAEzB,MAAME,OAAO,GAAGA,CACfC,IAAuD,EACvDC,SAA2E,KAE3E,IAAAC,kBAAW,EACVF,IAAI,CAACC,SAAS,CAAC,EACfH,QAAQ,CAACK,QAAQ,CAACC,UAAU,EAC5B,MACC,IAAIC,oBAAY,CAAC;IAChBC,IAAI,EAAE,gCAAgC;IACtCC,OAAO,EAAE,4CAA4C;IACrDC,SAAS,EAAE,UAAU;IACrBC,SAAS,EAAE;EACZ,CAAC,CACH,CAAC;;EAEF;AACD;AACA;AACA;AACA;AACA;AACA;EACC,MAAMC,QAAQ,GAAG,MAAAA,CAChBC,QAA0B,EAC1BC,UAAsB,EACtBC,aAAqB,KAKjB;IACJ,MAAMb,IAAI,GAAGH,IAAI,CAACiB,MAAM,CAACC,mBAAmB;IAC5C,IAAI,CAACf,IAAI,EAAE;MACV,OAAO;QAAEgB,OAAO,EAAE;MAAW,CAAC;IAC/B;IAEA,MAAMC,KAAK,GAAGnB,QAAQ,CAACoB,OAAO,CAACC,GAAG,CAACP,UAAU,CAAC;IAC9C,IAAI;MACH,MAAMQ,QAAQ,GAAG,MAAMrB,OAAO,CAACC,IAAI,EAAE;QACpCY,UAAU;QACVS,WAAW,EAAEJ,KAAK,EAAEI,WAAW,IAAI,oBAAoB;QACvDC,mBAAmB,EAAEX,QAAQ,CAACW,mBAAmB,IAAI,EAAE;QACvDT,aAAa;QACbU,aAAa,EAAEZ,QAAQ,CAACY,aAAa;QACrCC,QAAQ,EAAE3B,IAAI,CAAC2B;MAChB,CAAC,CAAC;MACF3B,IAAI,CAAC4B,IAAI,CAAC;QACTC,IAAI,EAAE,oBAAoB;QAC1Bd,UAAU;QACVQ,QAAQ,EAAEA,QAAQ,CAACO,QAAQ,GAAG,UAAU,GAAG;MAC5C,CAAC,CAAC;MACF,OAAOP,QAAQ,CAACO,QAAQ,GACrB;QAAEX,OAAO,EAAE;MAAW,CAAC,GACvB;QAAEA,OAAO,EAAE,UAAU;QAAEY,MAAM,EAAER,QAAQ,CAACQ;MAAO,CAAC;IACpD,CAAC,CAAC,MAAM;MACP;MACA,MAAMC,QAAQ,GAAG/B,QAAQ,CAACgC,uBAAuB;MACjDjC,IAAI,CAAC4B,IAAI,CAAC;QAAEC,IAAI,EAAE,wBAAwB;QAAEd,UAAU;QAAEiB;MAAS,CAAC,CAAC;MACnE,OAAOA,QAAQ,KAAK,iBAAiB,GAClC;QAAEb,OAAO,EAAE;MAA+B,CAAC,GAC3C;QAAEA,OAAO,EAAE,UAAU;QAAEY,MAAM,EAAE;MAAyB,CAAC;IAC7D;EACD,CAAC;EAED,OAAO;IAAE7B,OAAO;IAAEW;EAAS,CAAC;AAC7B","ignoreList":[]}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createEngineState = createEngineState;
7
+ var _rnCore = require("@chipmobilesdk/rn-core");
8
+ var _errors = require("../diagnostics/errors.js");
9
+ var _events = require("../diagnostics/events.js");
10
+ var _aggregate = require("../entitlements/aggregate.js");
11
+ var _snapshot = require("../persistence/snapshot.js");
12
+ var _pending = require("./pending.js");
13
+ /**
14
+ * The engine's state and the one way it changes (PAY-10).
15
+ *
16
+ * Status, the persisted snapshot, entitlements and pending purchases live here
17
+ * with the listeners that hear about them. Every change goes through `commit`
18
+ * (the snapshot) or `setStatus`, so diffing and emission are written once:
19
+ * an entitlement is granted or revoked exactly once however many sources it has
20
+ * (FR-079), a renewal that changes nothing emits nothing (FR-068), and an
21
+ * unchanged map is the same object (PERF-03).
22
+ */
23
+
24
+ function createEngineState(config, resolved, provider, store, now) {
25
+ // A listener that throws is a consumer bug, so it goes to the app's own logger
26
+ // rather than back into the event stream (FR-080, FR-081).
27
+ const emitter = (0, _events.createEmitter)((error, event) => {
28
+ config.logger?.error?.('payment event listener threw', {
29
+ eventType: event.type,
30
+ reason: (0, _errors.redact)(error)
31
+ });
32
+ });
33
+ const listenerOptions = {
34
+ onListenerError: error => config.logger?.error?.('payment listener threw', {
35
+ reason: (0, _errors.redact)(error)
36
+ })
37
+ };
38
+
39
+ /**
40
+ * Why an entitlement that was held is held no more, from what its sources left
41
+ * behind (PAY-12): a backend rejection, a consumed item, an expired
42
+ * subscription — or, when the store simply stopped reporting it, a refund.
43
+ */
44
+ function revokeReason(sources) {
45
+ const records = state.snapshot.purchases.filter(record => sources.includes(record.productKey));
46
+ if (records.some(record => record.validationState === 'rejected')) {
47
+ return 'validation_rejected';
48
+ }
49
+ if (records.some(record => record.state === 'consumed')) {
50
+ return 'consumed';
51
+ }
52
+ const at = now();
53
+ if (records.some(record => record.expiresAt !== undefined && record.expiresAt <= at)) {
54
+ return 'expired';
55
+ }
56
+ return 'revoked_by_store';
57
+ }
58
+ function publishPending(next) {
59
+ // Diffed: a sync that changes nothing is the common case, and an app
60
+ // rendering "payment pending" has no use for a re-render that says the same.
61
+ if ((0, _pending.samePending)(state.pending, next)) {
62
+ return;
63
+ }
64
+ state.pending = next;
65
+ state.pendingListeners.notify(next);
66
+ }
67
+ function recompute() {
68
+ if (state.disposed) {
69
+ return;
70
+ }
71
+ const previous = state.entitlements;
72
+ state.entitlements = (0, _aggregate.shareUnchanged)(previous, (0, _aggregate.aggregate)({
73
+ config: resolved,
74
+ snapshot: state.snapshot,
75
+ hasSynced: state.hasSynced,
76
+ reportsGraceAndHoldDistinctly: provider.capabilities().reportsGraceAndHoldDistinctly,
77
+ now: now()
78
+ }));
79
+ for (const change of (0, _aggregate.diffEntitlements)(previous, state.entitlements)) {
80
+ if (change.next === 'entitled') {
81
+ state.emit({
82
+ type: 'entitlement_granted',
83
+ entitlementKey: change.key,
84
+ sources: change.sources
85
+ });
86
+ } else if (change.previous === 'entitled') {
87
+ state.emit({
88
+ type: 'entitlement_revoked',
89
+ entitlementKey: change.key,
90
+ reason: revokeReason(previous[change.key]?.sources ?? [])
91
+ });
92
+ }
93
+ }
94
+ if (state.entitlements !== previous) {
95
+ state.entitlementListeners.notify(state.entitlements);
96
+ }
97
+ publishPending((0, _pending.derivePending)({
98
+ config: resolved,
99
+ snapshot: state.snapshot,
100
+ hasSynced: state.hasSynced,
101
+ now: now()
102
+ }));
103
+ }
104
+ const state = {
105
+ config,
106
+ resolved,
107
+ provider,
108
+ store,
109
+ now,
110
+ emitter,
111
+ statusListeners: (0, _rnCore.createListenerSet)(listenerOptions),
112
+ entitlementListeners: (0, _rnCore.createListenerSet)(listenerOptions),
113
+ pendingListeners: (0, _rnCore.createListenerSet)(listenerOptions),
114
+ disposed: false,
115
+ hasSynced: false,
116
+ snapshot: (0, _snapshot.emptySnapshot)(config.scopeToken),
117
+ entitlements: (0, _aggregate.initialEntitlements)(resolved),
118
+ status: {
119
+ kind: resolved.enabled ? 'not_started' : 'disabled',
120
+ blockedOperations: []
121
+ },
122
+ pending: _pending.UNKNOWN_PENDING,
123
+ emit(event) {
124
+ emitter.emit({
125
+ ...event,
126
+ timestamp: event.timestamp ?? now()
127
+ });
128
+ },
129
+ setStatus(next) {
130
+ if (state.disposed) {
131
+ return;
132
+ }
133
+ state.status = {
134
+ ...state.status,
135
+ ...next
136
+ };
137
+ state.emit({
138
+ type: 'initialization',
139
+ status: state.status.kind,
140
+ unavailableReason: state.status.unavailableReason,
141
+ retryable: state.status.retryable
142
+ });
143
+ state.statusListeners.notify(state.status);
144
+ },
145
+ commit(next) {
146
+ // Read before the swap: a transition is "pending before, not pending now",
147
+ // and only the commit sees both sides (FR-104).
148
+ const ended = (0, _pending.pendingTransitions)(state.snapshot, next, resolved, transactionId => provider.pendingEndReason?.(transactionId));
149
+ state.snapshot = next;
150
+ if (store.save(next) === false) {
151
+ // The write-intent-first guarantee (FR-042) did not hold for this write.
152
+ // Said out loud: the app learns its finalize queue may not survive a kill.
153
+ state.emit({
154
+ type: 'internal_error',
155
+ code: 'PAYMENT_STORAGE_UNAVAILABLE',
156
+ operation: 'persist'
157
+ });
158
+ }
159
+ // Before `recompute`, so `settled` precedes the `entitlement_granted` it
160
+ // causes (FR-102).
161
+ for (const transition of ended) {
162
+ state.emit({
163
+ type: 'purchase_pending_resolved',
164
+ productKey: transition.productKey,
165
+ outcome: transition.outcome
166
+ });
167
+ }
168
+ recompute();
169
+ },
170
+ hydrate() {
171
+ state.snapshot = store.load(config.scopeToken);
172
+ // A record with `lastSyncedAt` was written by a sync that succeeded, so it
173
+ // is a basis for asserting entitlement — and the only one a build with
174
+ // selling disabled will ever have (FR-012, FR-053).
175
+ if (state.snapshot.lastSyncedAt !== undefined) {
176
+ state.hasSynced = true;
177
+ }
178
+ if (!store.isDurable()) {
179
+ state.emit({
180
+ type: 'config_warning',
181
+ detail: 'Local storage unavailable; entitlements will not survive restart'
182
+ });
183
+ }
184
+ recompute();
185
+ },
186
+ forget() {
187
+ store.clearAll();
188
+ state.snapshot = (0, _snapshot.emptySnapshot)(config.scopeToken);
189
+ state.hasSynced = false;
190
+ // Back to `unknown`, not `not_entitled`: after a logout there is no basis
191
+ // for either claim until the next sync.
192
+ state.entitlements = (0, _aggregate.initialEntitlements)(resolved);
193
+ state.entitlementListeners.notify(state.entitlements);
194
+ // No `purchase_pending_resolved`: the records were discarded locally, not
195
+ // ended at the store.
196
+ publishPending(_pending.UNKNOWN_PENDING);
197
+ }
198
+ };
199
+ return state;
200
+ }
201
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_rnCore","require","_errors","_events","_aggregate","_snapshot","_pending","createEngineState","config","resolved","provider","store","now","emitter","createEmitter","error","event","logger","eventType","type","reason","redact","listenerOptions","onListenerError","revokeReason","sources","records","state","snapshot","purchases","filter","record","includes","productKey","some","validationState","at","expiresAt","undefined","publishPending","next","samePending","pending","pendingListeners","notify","recompute","disposed","previous","entitlements","shareUnchanged","aggregate","hasSynced","reportsGraceAndHoldDistinctly","capabilities","change","diffEntitlements","emit","entitlementKey","key","entitlementListeners","derivePending","statusListeners","createListenerSet","emptySnapshot","scopeToken","initialEntitlements","status","kind","enabled","blockedOperations","UNKNOWN_PENDING","timestamp","setStatus","unavailableReason","retryable","commit","ended","pendingTransitions","transactionId","pendingEndReason","save","code","operation","transition","outcome","hydrate","load","lastSyncedAt","isDurable","detail","forget","clearAll"],"sourceRoot":"../../../src","sources":["engine/state.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createSubscriptions = createSubscriptions;
7
+ var _mapping = require("../entitlements/mapping.js");
8
+ /**
9
+ * Subscription plan changes and the route to the store's management screen (US12).
10
+ *
11
+ * Two platform rules drive this module:
12
+ *
13
+ * - **Proration is the app's decision, inside what the store permits** (FR-065).
14
+ * Whether a user who upgrades gets charged immediately, keeps their remaining
15
+ * time, or starts a fresh period is a product and pricing choice, so the
16
+ * package forwards it rather than picking.
17
+ * - **Cancellation belongs to the store.** Platforms forbid an app presenting its
18
+ * own cancellation screen, so this module offers only a route to the store's
19
+ * (FR-066) — there is deliberately no self-built alternative anywhere in the
20
+ * package.
21
+ */
22
+
23
+ /**
24
+ * How already-paid time is handled when a plan changes.
25
+ *
26
+ * Named for the user-visible effect rather than mirroring a store's enum, so the
27
+ * same vocabulary will map onto StoreKit later (FR-004).
28
+ */
29
+
30
+ /** Store-specific replacement codes stay here, behind the neutral vocabulary above. */
31
+ const PRORATION_CODES = {
32
+ immediate_with_time_proration: 'WITH_TIME_PRORATION',
33
+ immediate_and_charge_full_price: 'CHARGE_FULL_PRICE',
34
+ immediate_and_charge_prorated_price: 'CHARGE_PRORATED_PRICE',
35
+ deferred: 'DEFERRED'
36
+ };
37
+ function createSubscriptions(deps) {
38
+ const {
39
+ resolved
40
+ } = deps;
41
+ return {
42
+ async changePlan(fromProductKey, toProductKey, mode, options) {
43
+ if (!deps.provider.capabilities().supportsPlanChange) {
44
+ return {
45
+ kind: 'unsupported'
46
+ };
47
+ }
48
+ const target = resolved.entries.get(toProductKey);
49
+ if (!target) {
50
+ return {
51
+ kind: 'unknown_product',
52
+ productKey: toProductKey
53
+ };
54
+ }
55
+ if (!resolved.entries.has(fromProductKey)) {
56
+ return {
57
+ kind: 'unknown_product',
58
+ productKey: fromProductKey
59
+ };
60
+ }
61
+
62
+ // The store needs the *token* of the subscription being replaced, not its
63
+ // product id — that is how it knows which active purchase to migrate, and
64
+ // it is why a plan change needs a live local record rather than just two
65
+ // product keys.
66
+ const active = deps.snapshot().purchases.find(p => p.productKey === fromProductKey && p.productType === 'subscription' && p.state === 'purchased');
67
+ if (!active) {
68
+ // No subscription to replace. Treated as a plain purchase would be
69
+ // surprising — the caller asked to *change* something that is not there,
70
+ // which almost always means its own state is stale.
71
+ return {
72
+ kind: 'already_owned',
73
+ productKey: fromProductKey
74
+ };
75
+ }
76
+
77
+ // Routed through the normal purchase flow on purpose: a plan change is a
78
+ // purchase, so it must inherit the single-flight lock, the environment
79
+ // guard, validation, and the finalization queue rather than reimplementing
80
+ // any of them.
81
+ return deps.purchase(toProductKey, {
82
+ ...options,
83
+ replaceProductKey: fromProductKey,
84
+ prorationMode: PRORATION_CODES[mode]
85
+ });
86
+ },
87
+ async openManagement(productKey) {
88
+ const storeProductId = productKey ? (0, _mapping.storeIdForProductKey)(resolved, productKey) : undefined;
89
+ // No-ops rather than throwing where the platform has no such screen: this
90
+ // is wired to a button, and a button that crashes is worse than one that
91
+ // does nothing on a platform that cannot honour it.
92
+ await deps.provider.openSubscriptionManagement(storeProductId);
93
+ },
94
+ async confirmPriceChange(productKey) {
95
+ if (!deps.provider.capabilities().supportsPriceChangeConfirmation) {
96
+ return {
97
+ kind: 'unsupported'
98
+ };
99
+ }
100
+ const storeProductId = (0, _mapping.storeIdForProductKey)(resolved, productKey);
101
+ if (!storeProductId) {
102
+ return {
103
+ kind: 'failed',
104
+ code: 'PAYMENT_UNKNOWN_PRODUCT'
105
+ };
106
+ }
107
+ const outcome = await deps.provider.confirmPriceChange(storeProductId);
108
+ if (!outcome.ok) {
109
+ return {
110
+ kind: 'failed',
111
+ code: 'PAYMENT_STORE_ERROR'
112
+ };
113
+ }
114
+ return outcome.confirmed ? {
115
+ kind: 'confirmed'
116
+ } : {
117
+ kind: 'dismissed'
118
+ };
119
+ }
120
+ };
121
+ }
122
+ //# sourceMappingURL=subscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_mapping","require","PRORATION_CODES","immediate_with_time_proration","immediate_and_charge_full_price","immediate_and_charge_prorated_price","deferred","createSubscriptions","deps","resolved","changePlan","fromProductKey","toProductKey","mode","options","provider","capabilities","supportsPlanChange","kind","target","entries","get","productKey","has","active","snapshot","purchases","find","p","productType","state","purchase","replaceProductKey","prorationMode","openManagement","storeProductId","storeIdForProductKey","undefined","openSubscriptionManagement","confirmPriceChange","supportsPriceChangeConfirmation","code","outcome","ok","confirmed"],"sourceRoot":"../../../src","sources":["engine/subscriptions.ts"],"mappings":"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","ignoreList":[]}