@nosslabs/iap 0.3.0 → 0.3.1
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 +33 -0
- package/dist/index.cjs +11 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -4
- package/dist/index.d.ts +27 -4
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -822,6 +822,24 @@ type EventName<TEntitlement extends EntitlementBase = EntitlementBase> = keyof E
|
|
|
822
822
|
type EventPayload<K extends EventName<TEntitlement>, TEntitlement extends EntitlementBase = EntitlementBase> = EventMap<TEntitlement>[K];
|
|
823
823
|
type Unsubscribe = () => void;
|
|
824
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Convenience context the library passes to a function-form
|
|
827
|
+
* {@link AppUserId} fetcher. `authHeaders` is the result of awaiting
|
|
828
|
+
* `backend.getAuthHeaders()` — the same headers the library will use
|
|
829
|
+
* for its own backend requests. Resolved fresh per purchase so token
|
|
830
|
+
* refresh keeps working.
|
|
831
|
+
*
|
|
832
|
+
* It's a convenience, not a contract: fetchers may legitimately ignore
|
|
833
|
+
* the parameter. Use it when your UUID-minting endpoint shares auth
|
|
834
|
+
* with your IAP backend; ignore it (and close over your own auth
|
|
835
|
+
* state) when it doesn't.
|
|
836
|
+
*
|
|
837
|
+
* For consumers using a custom `BackendAdapter` (no `getAuthHeaders`
|
|
838
|
+
* configured), `authHeaders` is `{}`.
|
|
839
|
+
*/
|
|
840
|
+
interface AppUserIdFetcherContext {
|
|
841
|
+
authHeaders: Record<string, string>;
|
|
842
|
+
}
|
|
825
843
|
/**
|
|
826
844
|
* Value supplied to `iap.purchase({ appUserId })`. Either a UUID v4
|
|
827
845
|
* string the caller already has (e.g. from local cache / app state) or
|
|
@@ -830,9 +848,14 @@ type Unsubscribe = () => void;
|
|
|
830
848
|
* persists on first call, returns the existing UUID on later calls).
|
|
831
849
|
*
|
|
832
850
|
* The fetcher is invoked **fresh on every purchase** — iap caches
|
|
833
|
-
* nothing. The backend owns the mint-or-lookup idempotency.
|
|
834
|
-
*
|
|
835
|
-
*
|
|
851
|
+
* nothing. The backend owns the mint-or-lookup idempotency.
|
|
852
|
+
*
|
|
853
|
+
* Two fetcher shapes are supported:
|
|
854
|
+
* - `() => Promise<string>` — closes over its own auth state.
|
|
855
|
+
* - `(ctx) => Promise<string>` — receives `ctx.authHeaders` populated
|
|
856
|
+
* from `backend.getAuthHeaders()` so the auth wired up for IAP
|
|
857
|
+
* requests can be reused without redefining a helper. See
|
|
858
|
+
* {@link AppUserIdFetcherContext}.
|
|
836
859
|
*
|
|
837
860
|
* Either form is validated as UUID v4 before being forwarded to
|
|
838
861
|
* StoreKit's `appAccountToken` (iOS) / Play Billing's
|
|
@@ -840,7 +863,7 @@ type Unsubscribe = () => void;
|
|
|
840
863
|
* `IAPError(INVALID_APP_USER_ID)`. A throwing/rejecting fetcher
|
|
841
864
|
* surfaces as `IAPError(APP_USER_ID_FETCH_FAILED, cause: <original>)`.
|
|
842
865
|
*/
|
|
843
|
-
type AppUserId = string | (() => Promise<string>);
|
|
866
|
+
type AppUserId = string | (() => Promise<string>) | ((ctx: AppUserIdFetcherContext) => Promise<string>);
|
|
844
867
|
/**
|
|
845
868
|
* Options accepted by `iap.purchase(...)`. `productId` is required;
|
|
846
869
|
* `appUserId` is optional — when omitted, no `applicationUsername` is
|
package/dist/index.d.ts
CHANGED
|
@@ -822,6 +822,24 @@ type EventName<TEntitlement extends EntitlementBase = EntitlementBase> = keyof E
|
|
|
822
822
|
type EventPayload<K extends EventName<TEntitlement>, TEntitlement extends EntitlementBase = EntitlementBase> = EventMap<TEntitlement>[K];
|
|
823
823
|
type Unsubscribe = () => void;
|
|
824
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Convenience context the library passes to a function-form
|
|
827
|
+
* {@link AppUserId} fetcher. `authHeaders` is the result of awaiting
|
|
828
|
+
* `backend.getAuthHeaders()` — the same headers the library will use
|
|
829
|
+
* for its own backend requests. Resolved fresh per purchase so token
|
|
830
|
+
* refresh keeps working.
|
|
831
|
+
*
|
|
832
|
+
* It's a convenience, not a contract: fetchers may legitimately ignore
|
|
833
|
+
* the parameter. Use it when your UUID-minting endpoint shares auth
|
|
834
|
+
* with your IAP backend; ignore it (and close over your own auth
|
|
835
|
+
* state) when it doesn't.
|
|
836
|
+
*
|
|
837
|
+
* For consumers using a custom `BackendAdapter` (no `getAuthHeaders`
|
|
838
|
+
* configured), `authHeaders` is `{}`.
|
|
839
|
+
*/
|
|
840
|
+
interface AppUserIdFetcherContext {
|
|
841
|
+
authHeaders: Record<string, string>;
|
|
842
|
+
}
|
|
825
843
|
/**
|
|
826
844
|
* Value supplied to `iap.purchase({ appUserId })`. Either a UUID v4
|
|
827
845
|
* string the caller already has (e.g. from local cache / app state) or
|
|
@@ -830,9 +848,14 @@ type Unsubscribe = () => void;
|
|
|
830
848
|
* persists on first call, returns the existing UUID on later calls).
|
|
831
849
|
*
|
|
832
850
|
* The fetcher is invoked **fresh on every purchase** — iap caches
|
|
833
|
-
* nothing. The backend owns the mint-or-lookup idempotency.
|
|
834
|
-
*
|
|
835
|
-
*
|
|
851
|
+
* nothing. The backend owns the mint-or-lookup idempotency.
|
|
852
|
+
*
|
|
853
|
+
* Two fetcher shapes are supported:
|
|
854
|
+
* - `() => Promise<string>` — closes over its own auth state.
|
|
855
|
+
* - `(ctx) => Promise<string>` — receives `ctx.authHeaders` populated
|
|
856
|
+
* from `backend.getAuthHeaders()` so the auth wired up for IAP
|
|
857
|
+
* requests can be reused without redefining a helper. See
|
|
858
|
+
* {@link AppUserIdFetcherContext}.
|
|
836
859
|
*
|
|
837
860
|
* Either form is validated as UUID v4 before being forwarded to
|
|
838
861
|
* StoreKit's `appAccountToken` (iOS) / Play Billing's
|
|
@@ -840,7 +863,7 @@ type Unsubscribe = () => void;
|
|
|
840
863
|
* `IAPError(INVALID_APP_USER_ID)`. A throwing/rejecting fetcher
|
|
841
864
|
* surfaces as `IAPError(APP_USER_ID_FETCH_FAILED, cause: <original>)`.
|
|
842
865
|
*/
|
|
843
|
-
type AppUserId = string | (() => Promise<string>);
|
|
866
|
+
type AppUserId = string | (() => Promise<string>) | ((ctx: AppUserIdFetcherContext) => Promise<string>);
|
|
844
867
|
/**
|
|
845
868
|
* Options accepted by `iap.purchase(...)`. `productId` is required;
|
|
846
869
|
* `appUserId` is optional — when omitted, no `applicationUsername` is
|
package/dist/index.js
CHANGED
|
@@ -1230,7 +1230,11 @@ var PurchaseOrchestrator = class {
|
|
|
1230
1230
|
message: `Product "${productId}" is not in the configured catalog.`
|
|
1231
1231
|
});
|
|
1232
1232
|
}
|
|
1233
|
-
|
|
1233
|
+
let resolvedAppUserId;
|
|
1234
|
+
if (appUserId !== void 0) {
|
|
1235
|
+
const ctx = typeof appUserId === "function" ? { authHeaders: await this.deps.getAuthHeaders() } : { authHeaders: {} };
|
|
1236
|
+
resolvedAppUserId = await resolveAppUserId(appUserId, ctx);
|
|
1237
|
+
}
|
|
1234
1238
|
this.inFlight.add(productId);
|
|
1235
1239
|
this.deps.emitter.emit("purchase-started", { productId });
|
|
1236
1240
|
try {
|
|
@@ -1347,11 +1351,11 @@ var PurchaseOrchestrator = class {
|
|
|
1347
1351
|
return { status: "verification_failed", productId, error: iapError };
|
|
1348
1352
|
}
|
|
1349
1353
|
};
|
|
1350
|
-
async function resolveAppUserId(supply) {
|
|
1354
|
+
async function resolveAppUserId(supply, ctx) {
|
|
1351
1355
|
let resolved;
|
|
1352
1356
|
if (typeof supply === "function") {
|
|
1353
1357
|
try {
|
|
1354
|
-
resolved = await supply();
|
|
1358
|
+
resolved = await supply(ctx);
|
|
1355
1359
|
} catch (cause) {
|
|
1356
1360
|
throw new IAPError({
|
|
1357
1361
|
code: IAPErrorCode.APP_USER_ID_FETCH_FAILED,
|
|
@@ -1849,6 +1853,8 @@ function createIAP(input) {
|
|
|
1849
1853
|
state.logger.debug(`Resolved ${validated.data.length} product(s) from backend manifest.`);
|
|
1850
1854
|
}
|
|
1851
1855
|
state.adapter = await selectNativeAdapter({ products: state.products });
|
|
1856
|
+
const configGetAuthHeaders = state.config.backend.getAuthHeaders;
|
|
1857
|
+
const getAuthHeaders = configGetAuthHeaders ? async () => configGetAuthHeaders() : async () => ({});
|
|
1852
1858
|
const sharedDeps = {
|
|
1853
1859
|
nativeAdapter: state.adapter,
|
|
1854
1860
|
backend: state.backend,
|
|
@@ -1862,7 +1868,8 @@ function createIAP(input) {
|
|
|
1862
1868
|
},
|
|
1863
1869
|
setCachePersisted: (cachedAt) => {
|
|
1864
1870
|
state.cachedAt = cachedAt;
|
|
1865
|
-
}
|
|
1871
|
+
},
|
|
1872
|
+
getAuthHeaders
|
|
1866
1873
|
};
|
|
1867
1874
|
state.orchestrator = new PurchaseOrchestrator({
|
|
1868
1875
|
...sharedDeps,
|