@nosslabs/iap 8.1.0 → 8.2.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 +57 -0
- package/README.md +25 -4
- package/dist/index.cjs +96 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +96 -18
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
package/dist/index.d.cts
CHANGED
|
@@ -1729,6 +1729,11 @@ interface IAP<TEntitlement extends EntitlementBase = EntitlementBase> {
|
|
|
1729
1729
|
* A no-op after `destroy()`, rather than an error: a teardown racing a
|
|
1730
1730
|
* "delete my data" tap is a real sequence, not a programming mistake.
|
|
1731
1731
|
*
|
|
1732
|
+
* It also throws if the storage backend cannot be reached at all — an
|
|
1733
|
+
* uninstalled `@capacitor/preferences`, say. Individual key failures are
|
|
1734
|
+
* logged and the rest still cleared, but reporting success having erased
|
|
1735
|
+
* nothing is the one outcome a delete-everything control must not have.
|
|
1736
|
+
*
|
|
1732
1737
|
* It does **not** revoke the purchase. The store still owns it, and a
|
|
1733
1738
|
* restore will bring the entitlement back — which is correct: the user
|
|
1734
1739
|
* paid.
|
package/dist/index.d.ts
CHANGED
|
@@ -1729,6 +1729,11 @@ interface IAP<TEntitlement extends EntitlementBase = EntitlementBase> {
|
|
|
1729
1729
|
* A no-op after `destroy()`, rather than an error: a teardown racing a
|
|
1730
1730
|
* "delete my data" tap is a real sequence, not a programming mistake.
|
|
1731
1731
|
*
|
|
1732
|
+
* It also throws if the storage backend cannot be reached at all — an
|
|
1733
|
+
* uninstalled `@capacitor/preferences`, say. Individual key failures are
|
|
1734
|
+
* logged and the rest still cleared, but reporting success having erased
|
|
1735
|
+
* nothing is the one outcome a delete-everything control must not have.
|
|
1736
|
+
*
|
|
1732
1737
|
* It does **not** revoke the purchase. The store still owns it, and a
|
|
1733
1738
|
* restore will bring the entitlement back — which is correct: the user
|
|
1734
1739
|
* paid.
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Capacitor } from '@capacitor/core';
|
|
2
2
|
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { Preferences } from '@capacitor/preferences';
|
|
5
4
|
|
|
6
5
|
var __defProp = Object.defineProperty;
|
|
7
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -1977,39 +1976,122 @@ init_errors();
|
|
|
1977
1976
|
var PreferencesAdapter = class {
|
|
1978
1977
|
prefix;
|
|
1979
1978
|
knownKeys = /* @__PURE__ */ new Set();
|
|
1979
|
+
/**
|
|
1980
|
+
* Boxed, and that is not incidental — see {@link PreferencesAdapter.preferences}.
|
|
1981
|
+
*/
|
|
1982
|
+
plugin = null;
|
|
1980
1983
|
constructor(namespace) {
|
|
1981
1984
|
this.prefix = `${namespace}.`;
|
|
1982
1985
|
}
|
|
1986
|
+
/**
|
|
1987
|
+
* The plugin, inside a box.
|
|
1988
|
+
*
|
|
1989
|
+
* The box is load-bearing. `registerPlugin()` hands back a **Proxy** that
|
|
1990
|
+
* answers any property, `then` included — so resolving a promise *with*
|
|
1991
|
+
* the plugin makes it look like a thenable, and promise assimilation
|
|
1992
|
+
* calls `Preferences.then()`. On web that rejects with
|
|
1993
|
+
* `"Preferences.then()" is not implemented on web`, from inside
|
|
1994
|
+
* `await this.preferences()`, for every storage operation.
|
|
1995
|
+
*
|
|
1996
|
+
* Wrapping it in a plain object means the promise resolves with something
|
|
1997
|
+
* that has no `then`, so nothing is assimilated.
|
|
1998
|
+
*/
|
|
1999
|
+
preferences() {
|
|
2000
|
+
this.plugin ??= import('@capacitor/preferences').then((mod) => ({ preferences: mod.Preferences })).catch((cause) => {
|
|
2001
|
+
if (isModuleNotFound(cause)) throw notInstalled(cause);
|
|
2002
|
+
this.plugin = null;
|
|
2003
|
+
throw new IAPError({
|
|
2004
|
+
code: IAPErrorCode.STORAGE_ERROR,
|
|
2005
|
+
message: "Could not load @capacitor/preferences. The package is installed, so this is most likely a chunk that failed to load; it is worth retrying.",
|
|
2006
|
+
cause,
|
|
2007
|
+
recoverable: true
|
|
2008
|
+
});
|
|
2009
|
+
});
|
|
2010
|
+
return this.plugin;
|
|
2011
|
+
}
|
|
2012
|
+
/**
|
|
2013
|
+
* Resolve the plugin now, so a missing one is reported at `initialize()`.
|
|
2014
|
+
*
|
|
2015
|
+
* See the note on lazy loading above for why this is not left to the first
|
|
2016
|
+
* `get()`.
|
|
2017
|
+
*/
|
|
2018
|
+
async ensureAvailable() {
|
|
2019
|
+
await this.preferences();
|
|
2020
|
+
}
|
|
1983
2021
|
async get(key) {
|
|
2022
|
+
const { preferences } = await this.preferences();
|
|
1984
2023
|
try {
|
|
1985
|
-
const result = await
|
|
2024
|
+
const result = await preferences.get({ key: this.prefix + key });
|
|
1986
2025
|
return result.value;
|
|
1987
2026
|
} catch (cause) {
|
|
1988
2027
|
throw wrap(cause, `Preferences.get failed for "${key}".`);
|
|
1989
2028
|
}
|
|
1990
2029
|
}
|
|
1991
2030
|
async set(key, value) {
|
|
2031
|
+
const { preferences } = await this.preferences();
|
|
1992
2032
|
try {
|
|
1993
|
-
await
|
|
2033
|
+
await preferences.set({ key: this.prefix + key, value });
|
|
1994
2034
|
this.knownKeys.add(key);
|
|
1995
2035
|
} catch (cause) {
|
|
1996
2036
|
throw wrap(cause, `Preferences.set failed for "${key}".`);
|
|
1997
2037
|
}
|
|
1998
2038
|
}
|
|
1999
2039
|
async remove(key) {
|
|
2040
|
+
const { preferences } = await this.preferences();
|
|
2000
2041
|
try {
|
|
2001
|
-
await
|
|
2042
|
+
await preferences.remove({ key: this.prefix + key });
|
|
2002
2043
|
this.knownKeys.delete(key);
|
|
2003
2044
|
} catch (cause) {
|
|
2004
2045
|
throw wrap(cause, `Preferences.remove failed for "${key}".`);
|
|
2005
2046
|
}
|
|
2006
2047
|
}
|
|
2007
2048
|
async clear() {
|
|
2049
|
+
const { preferences } = await this.preferences();
|
|
2008
2050
|
const keys = [...this.knownKeys];
|
|
2009
|
-
|
|
2010
|
-
|
|
2051
|
+
const failed = [];
|
|
2052
|
+
const errors = [];
|
|
2053
|
+
await Promise.all(
|
|
2054
|
+
keys.map(async (key) => {
|
|
2055
|
+
try {
|
|
2056
|
+
await preferences.remove({ key: this.prefix + key });
|
|
2057
|
+
this.knownKeys.delete(key);
|
|
2058
|
+
} catch (cause) {
|
|
2059
|
+
failed.push(key);
|
|
2060
|
+
errors.push(cause);
|
|
2061
|
+
}
|
|
2062
|
+
})
|
|
2063
|
+
);
|
|
2064
|
+
if (failed.length > 0) {
|
|
2065
|
+
throw wrap(errors[0], `Preferences.clear failed for ${failed.length} key(s).`);
|
|
2066
|
+
}
|
|
2011
2067
|
}
|
|
2012
2068
|
};
|
|
2069
|
+
function isModuleNotFound(cause) {
|
|
2070
|
+
let current = cause;
|
|
2071
|
+
for (let depth = 0; depth < 5 && current; depth += 1) {
|
|
2072
|
+
const code = current.code;
|
|
2073
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
2074
|
+
const message = current instanceof Error ? current.message : String(current);
|
|
2075
|
+
if (/cannot find (module|package)|could not resolve|failed to resolve/i.test(message)) {
|
|
2076
|
+
return true;
|
|
2077
|
+
}
|
|
2078
|
+
const next = current.cause;
|
|
2079
|
+
if (next === current) break;
|
|
2080
|
+
current = next;
|
|
2081
|
+
}
|
|
2082
|
+
return false;
|
|
2083
|
+
}
|
|
2084
|
+
function notInstalled(cause) {
|
|
2085
|
+
return new IAPError({
|
|
2086
|
+
code: IAPErrorCode.INVALID_CONFIG,
|
|
2087
|
+
message: 'storage.type is "preferences" (the default) but @capacitor/preferences is not installed. Install it (npm i @capacitor/preferences && npx cap sync), or choose storage that needs no plugin: storage.type "memory", or "custom" with your own adapter.',
|
|
2088
|
+
// The per-code hint for INVALID_CONFIG sends the reader to check field
|
|
2089
|
+
// paths against the config schema. There are none to check, and no
|
|
2090
|
+
// config change fixes this — the message above already says what to do.
|
|
2091
|
+
includeHint: false,
|
|
2092
|
+
cause
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2013
2095
|
function wrap(cause, message) {
|
|
2014
2096
|
return new IAPError({
|
|
2015
2097
|
code: IAPErrorCode.STORAGE_ERROR,
|
|
@@ -2110,12 +2192,7 @@ var EntitlementCache = class {
|
|
|
2110
2192
|
try {
|
|
2111
2193
|
await this.storage.set(ENTITLEMENTS_KEY, JSON.stringify(envelope));
|
|
2112
2194
|
} catch (cause) {
|
|
2113
|
-
throw
|
|
2114
|
-
code: IAPErrorCode.STORAGE_ERROR,
|
|
2115
|
-
message: "Failed to persist entitlement cache.",
|
|
2116
|
-
cause,
|
|
2117
|
-
recoverable: true
|
|
2118
|
-
});
|
|
2195
|
+
throw toIAPError(cause, "Failed to persist entitlement cache.", IAPErrorCode.STORAGE_ERROR);
|
|
2119
2196
|
}
|
|
2120
2197
|
return cachedAt;
|
|
2121
2198
|
}
|
|
@@ -3062,6 +3139,7 @@ async function initializeIap(state, refreshEntitlements) {
|
|
|
3062
3139
|
state.logger.debug("initialize() called more than once; ignoring.");
|
|
3063
3140
|
return;
|
|
3064
3141
|
}
|
|
3142
|
+
await state.storage.ensureAvailable?.();
|
|
3065
3143
|
const platform = getPlatform();
|
|
3066
3144
|
if (!isNative()) {
|
|
3067
3145
|
state.logger.info("Native purchases unavailable on web; entitlement queries still functional.");
|
|
@@ -3355,6 +3433,7 @@ async function resetIap(state) {
|
|
|
3355
3433
|
recoverable: true
|
|
3356
3434
|
});
|
|
3357
3435
|
}
|
|
3436
|
+
await state.storage.ensureAvailable?.();
|
|
3358
3437
|
const previous = state.entitlements;
|
|
3359
3438
|
state.entitlements = [];
|
|
3360
3439
|
state.cachedAt = null;
|
|
@@ -3531,12 +3610,11 @@ var UnfinishedTransactionsStore = class {
|
|
|
3531
3610
|
try {
|
|
3532
3611
|
await this.storage.set(STORE_KEY2, JSON.stringify(entries));
|
|
3533
3612
|
} catch (cause) {
|
|
3534
|
-
throw
|
|
3535
|
-
code: IAPErrorCode.STORAGE_ERROR,
|
|
3536
|
-
message: "Failed to persist unfinished transactions list.",
|
|
3613
|
+
throw toIAPError(
|
|
3537
3614
|
cause,
|
|
3538
|
-
|
|
3539
|
-
|
|
3615
|
+
"Failed to persist unfinished transactions list.",
|
|
3616
|
+
IAPErrorCode.STORAGE_ERROR
|
|
3617
|
+
);
|
|
3540
3618
|
}
|
|
3541
3619
|
}
|
|
3542
3620
|
async safeClear() {
|
|
@@ -3799,7 +3877,7 @@ function resolveLogger(level, candidate) {
|
|
|
3799
3877
|
init_errors();
|
|
3800
3878
|
|
|
3801
3879
|
// src/version.ts
|
|
3802
|
-
var VERSION = "8.
|
|
3880
|
+
var VERSION = "8.2.0";
|
|
3803
3881
|
|
|
3804
3882
|
export { DEFAULT_PERMANENT_ERROR_CODES, HttpBackendAdapter, HttpClient, IAPError, IAPErrorCode, VERSION, createIAP, errorHint, isExpired, isIAPError, verifyPurchaseOnDevice };
|
|
3805
3883
|
//# sourceMappingURL=index.js.map
|