@nosslabs/iap 7.0.0-next.0 → 7.1.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 +89 -0
- package/README.md +4 -4
- package/dist/index.cjs +330 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -8
- package/dist/index.d.ts +53 -8
- package/dist/index.js +330 -21
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,95 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [7.1.0] — 2026-07-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `iap.getStorefront(): Promise<Storefront | null>` — reads the user's App
|
|
13
|
+
Store / Google Play storefront (the country their store account is registered
|
|
14
|
+
to). Returns the new exported `Storefront` type, with `countryCode` normalized
|
|
15
|
+
to ISO 3166-1 alpha-2 across platforms (iOS reports alpha-3, Android alpha-2);
|
|
16
|
+
the raw native value is preserved on `countryCodeRaw`, plus the Apple
|
|
17
|
+
`storefrontId` (iOS only) and `platform`. Resolves `null` on web, when the
|
|
18
|
+
installed `@capgo/native-purchases` build doesn't register the native
|
|
19
|
+
`getStorefront` method, or when the storefront is unavailable (e.g. EU
|
|
20
|
+
alternative distribution). Read it live and treat it as a UX/targeting hint —
|
|
21
|
+
for compliance/entitlement decisions, trust the server-side signed storefront.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Anchored the `7.x` line to **Capacitor 7**: peer dependencies narrowed to
|
|
26
|
+
`@capacitor/*: ^7.0.0` and `@capgo/native-purchases: ^7.16.2` (dropping the
|
|
27
|
+
`^8.0.0` allowances). The `^7.16.2` range admits the Capacitor-7 capgo build
|
|
28
|
+
that adds native `getStorefront`. Capacitor-8 support will ship in
|
|
29
|
+
`@nosslabs/iap` v8. (`getStorefront()` itself still degrades gracefully on
|
|
30
|
+
capgo builds that predate the native method.)
|
|
31
|
+
|
|
32
|
+
## [7.0.0] — 2026-05-14
|
|
33
|
+
|
|
34
|
+
**GA of the Capacitor 7+ line.** `@latest` on npm moves from `5.0.0`
|
|
35
|
+
(Cap-5 maintenance) to `7.0.0` (Cap-7+). Cap-5 consumers stay on
|
|
36
|
+
`5.x` — `^5` ranges don't auto-resolve to `7.x`. The `5.x` maintenance
|
|
37
|
+
branch continues to receive patches.
|
|
38
|
+
|
|
39
|
+
### Changed (BREAKING, vs `5.0.0` — bundled with the Cap-5→Cap-7 swap)
|
|
40
|
+
|
|
41
|
+
- **EventMap pruning.** Removed two events from the public
|
|
42
|
+
`EventMap` that were declared but never emitted in any prior
|
|
43
|
+
release: `'price-stale'` and `'error'`. Subscriptions to either
|
|
44
|
+
never fired, so no runtime behavior changes — only consumers who
|
|
45
|
+
had `iap.on('price-stale', …)` or `iap.on('error', …)` in their
|
|
46
|
+
TypeScript code need to remove those calls. The
|
|
47
|
+
`'recovery-dropped-permanent'` event (introduced in 0.4 / `5.0.0`)
|
|
48
|
+
remains.
|
|
49
|
+
- `IAPErrorOptions` is now file-local (was wrongly exported from
|
|
50
|
+
`src/lib/errors.ts` but never re-exported through `src/index.ts`,
|
|
51
|
+
so no consumer had access to it). No package-root-exported symbol
|
|
52
|
+
changes.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- **`AppUserIdFetcherContext`** is now re-exported from the package
|
|
57
|
+
root, so a separately-defined async fetcher can be typed
|
|
58
|
+
explicitly:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import type { AppUserIdFetcherContext } from '@nosslabs/iap';
|
|
62
|
+
|
|
63
|
+
const fetchUuid = async ({ authHeaders }: AppUserIdFetcherContext) => {
|
|
64
|
+
const r = await fetch('/api/iap/uuid', { method: 'POST', headers: authHeaders });
|
|
65
|
+
return (await r.json()).uuid;
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Fixed (since `7.0.0-next.0`)
|
|
70
|
+
|
|
71
|
+
- **iOS `Cannot find product for id <id>` now maps to
|
|
72
|
+
`PRODUCT_NOT_FOUND`** (previously fell through to `STORE_ERROR`).
|
|
73
|
+
The capgo plugin uses two different messages for the same
|
|
74
|
+
semantic on iOS vs Android; the adapter now handles both.
|
|
75
|
+
- **`refresh()` is safe to detach from the IAP instance.** Internal
|
|
76
|
+
callbacks no longer reference `this.refresh()`, so
|
|
77
|
+
`const { refresh } = iap;` works without a strict-mode `this`
|
|
78
|
+
binding error. Regression test added.
|
|
79
|
+
|
|
80
|
+
### Notes
|
|
81
|
+
|
|
82
|
+
- Adapter JSDoc for `getOwnedTransactions()` now documents an iOS
|
|
83
|
+
quirk worth knowing: `@capgo/native-purchases`'s `getPurchases()`
|
|
84
|
+
bundles `Transaction.currentEntitlements` *plus* `Transaction.all`
|
|
85
|
+
(historical + revoked subscriptions). Android-side PENDING
|
|
86
|
+
purchases are filtered out (`purchaseState !== '1'`); iOS-side
|
|
87
|
+
historical transactions are not filtered and pass through to the
|
|
88
|
+
backend's `/restore` endpoint. Attesto evaluates each receipt and
|
|
89
|
+
returns per-transaction validity, so this is the documented
|
|
90
|
+
contract.
|
|
91
|
+
- Android user-cancellation reminder (carried from `7.0.0-next.0`):
|
|
92
|
+
Google Play Billing collapses user-cancel and other billing
|
|
93
|
+
errors into the same plugin rejection, so an Android cancel
|
|
94
|
+
surfaces as `status: 'failed'` rather than `'cancelled'`. iOS
|
|
95
|
+
still distinguishes reliably.
|
|
96
|
+
|
|
8
97
|
## [7.0.0-next.0] — 2026-05-14
|
|
9
98
|
|
|
10
99
|
First release of the **Capacitor 7+** line, published on the `@next`
|
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
> Thin Capacitor IAP orchestrator. Server-side validation via [Attesto](https://attesto.nossdev.com).
|
|
4
4
|
|
|
5
|
-
**Status: `7.0.0
|
|
5
|
+
**Status: `7.0.0` — GA on `@latest`** (the Capacitor 7+ line, built on `@capgo/native-purchases`). The Capacitor 5 line (`cordova-plugin-purchase`) continues as `5.x` from the `5.x` branch — `^5` ranges still resolve to `5.x`. See the [CHANGELOG](./CHANGELOG.md) for the GA delta and [Migration](https://iap.nossdev.com/migration/) for upgrading from `5.x`.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @nosslabs/iap
|
|
8
|
+
npm install @nosslabs/iap @capgo/native-purchases
|
|
9
9
|
npx cap sync
|
|
10
10
|
```
|
|
11
11
|
|
|
@@ -77,8 +77,8 @@ It does **not**: talk to Attesto directly, define entitlement business logic, ma
|
|
|
77
77
|
|
|
78
78
|
| `@nosslabs/iap` | Capacitor | Native plugin | dist-tag | Status |
|
|
79
79
|
|---|---|---|---|---|
|
|
80
|
-
| 7.x | 7.x (also runs on 8.x) | `@capgo/native-purchases 7.16.x` (or `^8` on Cap 8) | `@
|
|
81
|
-
| 5.x | 5.x | `cordova-plugin-purchase ^13.x` |
|
|
80
|
+
| 7.x | 7.x (also runs on 8.x) | `@capgo/native-purchases 7.16.x` (or `^8` on Cap 8) | `@latest` | **Current** |
|
|
81
|
+
| 5.x | 5.x | `cordova-plugin-purchase ^13.x` | (pinned via `^5`) | Maintenance |
|
|
82
82
|
|
|
83
83
|
## Optional peer dependency
|
|
84
84
|
|
package/dist/index.cjs
CHANGED
|
@@ -139,11 +139,293 @@ var init_platform = __esm({
|
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
+
// src/lib/iso-country.ts
|
|
143
|
+
function toAlpha2(code) {
|
|
144
|
+
if (!code) return null;
|
|
145
|
+
const normalized = code.trim().toUpperCase();
|
|
146
|
+
if (normalized.length === 2) return normalized;
|
|
147
|
+
if (normalized.length === 3) return ALPHA3_TO_ALPHA2[normalized] ?? null;
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
var ALPHA3_TO_ALPHA2;
|
|
151
|
+
var init_iso_country = __esm({
|
|
152
|
+
"src/lib/iso-country.ts"() {
|
|
153
|
+
ALPHA3_TO_ALPHA2 = {
|
|
154
|
+
ABW: "AW",
|
|
155
|
+
AFG: "AF",
|
|
156
|
+
AGO: "AO",
|
|
157
|
+
AIA: "AI",
|
|
158
|
+
ALA: "AX",
|
|
159
|
+
ALB: "AL",
|
|
160
|
+
AND: "AD",
|
|
161
|
+
ARE: "AE",
|
|
162
|
+
ARG: "AR",
|
|
163
|
+
ARM: "AM",
|
|
164
|
+
ASM: "AS",
|
|
165
|
+
ATA: "AQ",
|
|
166
|
+
ATF: "TF",
|
|
167
|
+
ATG: "AG",
|
|
168
|
+
AUS: "AU",
|
|
169
|
+
AUT: "AT",
|
|
170
|
+
AZE: "AZ",
|
|
171
|
+
BDI: "BI",
|
|
172
|
+
BEL: "BE",
|
|
173
|
+
BEN: "BJ",
|
|
174
|
+
BES: "BQ",
|
|
175
|
+
BFA: "BF",
|
|
176
|
+
BGD: "BD",
|
|
177
|
+
BGR: "BG",
|
|
178
|
+
BHR: "BH",
|
|
179
|
+
BHS: "BS",
|
|
180
|
+
BIH: "BA",
|
|
181
|
+
BLM: "BL",
|
|
182
|
+
BLR: "BY",
|
|
183
|
+
BLZ: "BZ",
|
|
184
|
+
BMU: "BM",
|
|
185
|
+
BOL: "BO",
|
|
186
|
+
BRA: "BR",
|
|
187
|
+
BRB: "BB",
|
|
188
|
+
BRN: "BN",
|
|
189
|
+
BTN: "BT",
|
|
190
|
+
BVT: "BV",
|
|
191
|
+
BWA: "BW",
|
|
192
|
+
CAF: "CF",
|
|
193
|
+
CAN: "CA",
|
|
194
|
+
CCK: "CC",
|
|
195
|
+
CHE: "CH",
|
|
196
|
+
CHL: "CL",
|
|
197
|
+
CHN: "CN",
|
|
198
|
+
CIV: "CI",
|
|
199
|
+
CMR: "CM",
|
|
200
|
+
COD: "CD",
|
|
201
|
+
COG: "CG",
|
|
202
|
+
COK: "CK",
|
|
203
|
+
COL: "CO",
|
|
204
|
+
COM: "KM",
|
|
205
|
+
CPV: "CV",
|
|
206
|
+
CRI: "CR",
|
|
207
|
+
CUB: "CU",
|
|
208
|
+
CUW: "CW",
|
|
209
|
+
CXR: "CX",
|
|
210
|
+
CYM: "KY",
|
|
211
|
+
CYP: "CY",
|
|
212
|
+
CZE: "CZ",
|
|
213
|
+
DEU: "DE",
|
|
214
|
+
DJI: "DJ",
|
|
215
|
+
DMA: "DM",
|
|
216
|
+
DNK: "DK",
|
|
217
|
+
DOM: "DO",
|
|
218
|
+
DZA: "DZ",
|
|
219
|
+
ECU: "EC",
|
|
220
|
+
EGY: "EG",
|
|
221
|
+
ERI: "ER",
|
|
222
|
+
ESH: "EH",
|
|
223
|
+
ESP: "ES",
|
|
224
|
+
EST: "EE",
|
|
225
|
+
ETH: "ET",
|
|
226
|
+
FIN: "FI",
|
|
227
|
+
FJI: "FJ",
|
|
228
|
+
FLK: "FK",
|
|
229
|
+
FRA: "FR",
|
|
230
|
+
FRO: "FO",
|
|
231
|
+
FSM: "FM",
|
|
232
|
+
GAB: "GA",
|
|
233
|
+
GBR: "GB",
|
|
234
|
+
GEO: "GE",
|
|
235
|
+
GGY: "GG",
|
|
236
|
+
GHA: "GH",
|
|
237
|
+
GIB: "GI",
|
|
238
|
+
GIN: "GN",
|
|
239
|
+
GLP: "GP",
|
|
240
|
+
GMB: "GM",
|
|
241
|
+
GNB: "GW",
|
|
242
|
+
GNQ: "GQ",
|
|
243
|
+
GRC: "GR",
|
|
244
|
+
GRD: "GD",
|
|
245
|
+
GRL: "GL",
|
|
246
|
+
GTM: "GT",
|
|
247
|
+
GUF: "GF",
|
|
248
|
+
GUM: "GU",
|
|
249
|
+
GUY: "GY",
|
|
250
|
+
HKG: "HK",
|
|
251
|
+
HMD: "HM",
|
|
252
|
+
HND: "HN",
|
|
253
|
+
HRV: "HR",
|
|
254
|
+
HTI: "HT",
|
|
255
|
+
HUN: "HU",
|
|
256
|
+
IDN: "ID",
|
|
257
|
+
IMN: "IM",
|
|
258
|
+
IND: "IN",
|
|
259
|
+
IOT: "IO",
|
|
260
|
+
IRL: "IE",
|
|
261
|
+
IRN: "IR",
|
|
262
|
+
IRQ: "IQ",
|
|
263
|
+
ISL: "IS",
|
|
264
|
+
ISR: "IL",
|
|
265
|
+
ITA: "IT",
|
|
266
|
+
JAM: "JM",
|
|
267
|
+
JEY: "JE",
|
|
268
|
+
JOR: "JO",
|
|
269
|
+
JPN: "JP",
|
|
270
|
+
KAZ: "KZ",
|
|
271
|
+
KEN: "KE",
|
|
272
|
+
KGZ: "KG",
|
|
273
|
+
KHM: "KH",
|
|
274
|
+
KIR: "KI",
|
|
275
|
+
KNA: "KN",
|
|
276
|
+
KOR: "KR",
|
|
277
|
+
KWT: "KW",
|
|
278
|
+
LAO: "LA",
|
|
279
|
+
LBN: "LB",
|
|
280
|
+
LBR: "LR",
|
|
281
|
+
LBY: "LY",
|
|
282
|
+
LCA: "LC",
|
|
283
|
+
LIE: "LI",
|
|
284
|
+
LKA: "LK",
|
|
285
|
+
LSO: "LS",
|
|
286
|
+
LTU: "LT",
|
|
287
|
+
LUX: "LU",
|
|
288
|
+
LVA: "LV",
|
|
289
|
+
MAC: "MO",
|
|
290
|
+
MAF: "MF",
|
|
291
|
+
MAR: "MA",
|
|
292
|
+
MCO: "MC",
|
|
293
|
+
MDA: "MD",
|
|
294
|
+
MDG: "MG",
|
|
295
|
+
MDV: "MV",
|
|
296
|
+
MEX: "MX",
|
|
297
|
+
MHL: "MH",
|
|
298
|
+
MKD: "MK",
|
|
299
|
+
MLI: "ML",
|
|
300
|
+
MLT: "MT",
|
|
301
|
+
MMR: "MM",
|
|
302
|
+
MNE: "ME",
|
|
303
|
+
MNG: "MN",
|
|
304
|
+
MNP: "MP",
|
|
305
|
+
MOZ: "MZ",
|
|
306
|
+
MRT: "MR",
|
|
307
|
+
MSR: "MS",
|
|
308
|
+
MTQ: "MQ",
|
|
309
|
+
MUS: "MU",
|
|
310
|
+
MWI: "MW",
|
|
311
|
+
MYS: "MY",
|
|
312
|
+
MYT: "YT",
|
|
313
|
+
NAM: "NA",
|
|
314
|
+
NCL: "NC",
|
|
315
|
+
NER: "NE",
|
|
316
|
+
NFK: "NF",
|
|
317
|
+
NGA: "NG",
|
|
318
|
+
NIC: "NI",
|
|
319
|
+
NIU: "NU",
|
|
320
|
+
NLD: "NL",
|
|
321
|
+
NOR: "NO",
|
|
322
|
+
NPL: "NP",
|
|
323
|
+
NRU: "NR",
|
|
324
|
+
NZL: "NZ",
|
|
325
|
+
OMN: "OM",
|
|
326
|
+
PAK: "PK",
|
|
327
|
+
PAN: "PA",
|
|
328
|
+
PCN: "PN",
|
|
329
|
+
PER: "PE",
|
|
330
|
+
PHL: "PH",
|
|
331
|
+
PLW: "PW",
|
|
332
|
+
PNG: "PG",
|
|
333
|
+
POL: "PL",
|
|
334
|
+
PRI: "PR",
|
|
335
|
+
PRK: "KP",
|
|
336
|
+
PRT: "PT",
|
|
337
|
+
PRY: "PY",
|
|
338
|
+
PSE: "PS",
|
|
339
|
+
PYF: "PF",
|
|
340
|
+
QAT: "QA",
|
|
341
|
+
REU: "RE",
|
|
342
|
+
ROU: "RO",
|
|
343
|
+
RUS: "RU",
|
|
344
|
+
RWA: "RW",
|
|
345
|
+
SAU: "SA",
|
|
346
|
+
SDN: "SD",
|
|
347
|
+
SEN: "SN",
|
|
348
|
+
SGP: "SG",
|
|
349
|
+
SGS: "GS",
|
|
350
|
+
SHN: "SH",
|
|
351
|
+
SJM: "SJ",
|
|
352
|
+
SLB: "SB",
|
|
353
|
+
SLE: "SL",
|
|
354
|
+
SLV: "SV",
|
|
355
|
+
SMR: "SM",
|
|
356
|
+
SOM: "SO",
|
|
357
|
+
SPM: "PM",
|
|
358
|
+
SRB: "RS",
|
|
359
|
+
SSD: "SS",
|
|
360
|
+
STP: "ST",
|
|
361
|
+
SUR: "SR",
|
|
362
|
+
SVK: "SK",
|
|
363
|
+
SVN: "SI",
|
|
364
|
+
SWE: "SE",
|
|
365
|
+
SWZ: "SZ",
|
|
366
|
+
SXM: "SX",
|
|
367
|
+
SYC: "SC",
|
|
368
|
+
SYR: "SY",
|
|
369
|
+
TCA: "TC",
|
|
370
|
+
TCD: "TD",
|
|
371
|
+
TGO: "TG",
|
|
372
|
+
THA: "TH",
|
|
373
|
+
TJK: "TJ",
|
|
374
|
+
TKL: "TK",
|
|
375
|
+
TKM: "TM",
|
|
376
|
+
TLS: "TL",
|
|
377
|
+
TON: "TO",
|
|
378
|
+
TTO: "TT",
|
|
379
|
+
TUN: "TN",
|
|
380
|
+
TUR: "TR",
|
|
381
|
+
TUV: "TV",
|
|
382
|
+
TWN: "TW",
|
|
383
|
+
TZA: "TZ",
|
|
384
|
+
UGA: "UG",
|
|
385
|
+
UKR: "UA",
|
|
386
|
+
UMI: "UM",
|
|
387
|
+
URY: "UY",
|
|
388
|
+
USA: "US",
|
|
389
|
+
UZB: "UZ",
|
|
390
|
+
VAT: "VA",
|
|
391
|
+
VCT: "VC",
|
|
392
|
+
VEN: "VE",
|
|
393
|
+
VGB: "VG",
|
|
394
|
+
VIR: "VI",
|
|
395
|
+
VNM: "VN",
|
|
396
|
+
VUT: "VU",
|
|
397
|
+
WLF: "WF",
|
|
398
|
+
WSM: "WS",
|
|
399
|
+
YEM: "YE",
|
|
400
|
+
ZAF: "ZA",
|
|
401
|
+
ZMB: "ZM",
|
|
402
|
+
ZWE: "ZW"
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
142
407
|
// src/adapters/native/capgo/native-adapter.ts
|
|
143
408
|
var native_adapter_exports = {};
|
|
144
409
|
__export(native_adapter_exports, {
|
|
145
410
|
CapgoNativeAdapter: () => CapgoNativeAdapter
|
|
146
411
|
});
|
|
412
|
+
function nativeStorefrontRegistered() {
|
|
413
|
+
const headers = core.Capacitor.PluginHeaders;
|
|
414
|
+
return headers?.find((h) => h.name === "NativePurchases")?.methods?.some((m) => m.name === "getStorefront") ?? false;
|
|
415
|
+
}
|
|
416
|
+
function normalizeStorefront(raw) {
|
|
417
|
+
const code = raw?.countryCode?.trim();
|
|
418
|
+
if (!code) return null;
|
|
419
|
+
const platform = getPlatform() === "android" ? "google" : "apple";
|
|
420
|
+
return {
|
|
421
|
+
// alpha-2 when recognized; otherwise the uppercased raw code as a
|
|
422
|
+
// best-effort fallback (see `Storefront.countryCode`).
|
|
423
|
+
countryCode: toAlpha2(code) ?? code.toUpperCase(),
|
|
424
|
+
countryCodeRaw: code,
|
|
425
|
+
storefrontId: raw.storefrontId,
|
|
426
|
+
platform
|
|
427
|
+
};
|
|
428
|
+
}
|
|
147
429
|
function normalizeProduct(p, type) {
|
|
148
430
|
const priceMicros = Math.round(p.price * 1e6).toString();
|
|
149
431
|
return {
|
|
@@ -202,7 +484,7 @@ function mapPurchaseError(error, productId) {
|
|
|
202
484
|
cause: error
|
|
203
485
|
});
|
|
204
486
|
}
|
|
205
|
-
if (lower.includes("product not found")) {
|
|
487
|
+
if (lower.includes("product not found") || lower.includes("cannot find product")) {
|
|
206
488
|
return new exports.IAPError({
|
|
207
489
|
code: exports.IAPErrorCode.PRODUCT_NOT_FOUND,
|
|
208
490
|
message: `Product "${productId}" was not found in the store catalog.`,
|
|
@@ -219,6 +501,7 @@ var CapgoNativeAdapter;
|
|
|
219
501
|
var init_native_adapter = __esm({
|
|
220
502
|
"src/adapters/native/capgo/native-adapter.ts"() {
|
|
221
503
|
init_errors();
|
|
504
|
+
init_iso_country();
|
|
222
505
|
init_platform();
|
|
223
506
|
CapgoNativeAdapter = class {
|
|
224
507
|
async isAvailable() {
|
|
@@ -302,6 +585,24 @@ var init_native_adapter = __esm({
|
|
|
302
585
|
});
|
|
303
586
|
}
|
|
304
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Read the current storefront from the native plugin — which is expected to
|
|
590
|
+
* source it from StoreKit 2 `Storefront.current` on iOS (alpha-3) and
|
|
591
|
+
* `getBillingConfigAsync()` on Android (alpha-2) — normalizing `countryCode`
|
|
592
|
+
* to alpha-2. Silent like {@link CapgoNativeAdapter.isAvailable}: any
|
|
593
|
+
* unavailability — older plugin (no native method registered), native
|
|
594
|
+
* rejection, or empty country — resolves to `null` rather than throwing.
|
|
595
|
+
*/
|
|
596
|
+
async getStorefront() {
|
|
597
|
+
if (!nativeStorefrontRegistered()) return null;
|
|
598
|
+
const np = nativePurchases.NativePurchases;
|
|
599
|
+
try {
|
|
600
|
+
const raw = await np.getStorefront?.();
|
|
601
|
+
return raw ? normalizeStorefront(raw) : null;
|
|
602
|
+
} catch {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
305
606
|
async dispose() {
|
|
306
607
|
}
|
|
307
608
|
};
|
|
@@ -832,6 +1133,9 @@ var WebStubAdapter = class {
|
|
|
832
1133
|
message: "Subscription management is not supported on the web platform."
|
|
833
1134
|
});
|
|
834
1135
|
}
|
|
1136
|
+
async getStorefront() {
|
|
1137
|
+
return null;
|
|
1138
|
+
}
|
|
835
1139
|
};
|
|
836
1140
|
|
|
837
1141
|
// src/adapters/native/index.ts
|
|
@@ -1737,6 +2041,24 @@ function createIAP(input) {
|
|
|
1737
2041
|
cachedAt: null,
|
|
1738
2042
|
products: Object.freeze([...config.products ?? []])
|
|
1739
2043
|
};
|
|
2044
|
+
async function refreshEntitlements() {
|
|
2045
|
+
requireInitialized(state);
|
|
2046
|
+
const previous = state.entitlements;
|
|
2047
|
+
const fetched = await state.backend.getEntitlements();
|
|
2048
|
+
const next = freezeAll(fetched);
|
|
2049
|
+
try {
|
|
2050
|
+
state.cachedAt = await state.cache.save(next);
|
|
2051
|
+
} catch (error) {
|
|
2052
|
+
state.logger.warn(
|
|
2053
|
+
"Failed to persist refreshed entitlements; in-memory state still updated.",
|
|
2054
|
+
error
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
state.entitlements = next;
|
|
2058
|
+
if (!entitlementsEqual(previous, next)) {
|
|
2059
|
+
state.emitter.emit("entitlements-changed", { entitlements: next, previous });
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
1740
2062
|
return {
|
|
1741
2063
|
async initialize() {
|
|
1742
2064
|
if (state.destroyed) {
|
|
@@ -1838,7 +2160,7 @@ function createIAP(input) {
|
|
|
1838
2160
|
logger: state.logger,
|
|
1839
2161
|
onResume: async () => {
|
|
1840
2162
|
try {
|
|
1841
|
-
await
|
|
2163
|
+
await refreshEntitlements();
|
|
1842
2164
|
} catch (error) {
|
|
1843
2165
|
state.logger.warn("refreshOnResume: refresh() failed.", error);
|
|
1844
2166
|
}
|
|
@@ -1849,7 +2171,7 @@ function createIAP(input) {
|
|
|
1849
2171
|
state.logger.debug("Cache exceeds TTL; scheduling background refresh.");
|
|
1850
2172
|
queueMicrotask(() => {
|
|
1851
2173
|
if (!state.initialized || state.destroyed) return;
|
|
1852
|
-
|
|
2174
|
+
refreshEntitlements().catch((error) => {
|
|
1853
2175
|
state.logger.warn("TTL background refresh failed.", error);
|
|
1854
2176
|
});
|
|
1855
2177
|
});
|
|
@@ -1857,24 +2179,7 @@ function createIAP(input) {
|
|
|
1857
2179
|
state.initialized = true;
|
|
1858
2180
|
state.emitter.emit("ready", void 0);
|
|
1859
2181
|
},
|
|
1860
|
-
|
|
1861
|
-
requireInitialized(state);
|
|
1862
|
-
const previous = state.entitlements;
|
|
1863
|
-
const fetched = await state.backend.getEntitlements();
|
|
1864
|
-
const next = freezeAll(fetched);
|
|
1865
|
-
try {
|
|
1866
|
-
state.cachedAt = await state.cache.save(next);
|
|
1867
|
-
} catch (error) {
|
|
1868
|
-
state.logger.warn(
|
|
1869
|
-
"Failed to persist refreshed entitlements; in-memory state still updated.",
|
|
1870
|
-
error
|
|
1871
|
-
);
|
|
1872
|
-
}
|
|
1873
|
-
state.entitlements = next;
|
|
1874
|
-
if (!entitlementsEqual(previous, next)) {
|
|
1875
|
-
state.emitter.emit("entitlements-changed", { entitlements: next, previous });
|
|
1876
|
-
}
|
|
1877
|
-
},
|
|
2182
|
+
refresh: refreshEntitlements,
|
|
1878
2183
|
async destroy() {
|
|
1879
2184
|
if (state.destroyed) return;
|
|
1880
2185
|
state.destroyed = true;
|
|
@@ -1932,6 +2237,10 @@ function createIAP(input) {
|
|
|
1932
2237
|
}
|
|
1933
2238
|
return state.adapter.getProducts(state.products.map((p) => ({ id: p.id, type: p.type })));
|
|
1934
2239
|
},
|
|
2240
|
+
async getStorefront() {
|
|
2241
|
+
requireInitialized(state);
|
|
2242
|
+
return state.adapter?.getStorefront?.() ?? null;
|
|
2243
|
+
},
|
|
1935
2244
|
hasEntitlement(key) {
|
|
1936
2245
|
return state.entitlements.some((e) => e.key === key);
|
|
1937
2246
|
},
|