@mpgd/adapter-capacitor 0.18.0 → 0.19.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/dist/commerce-bridge.d.ts +6 -0
- package/dist/commerce-bridge.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -0
- package/dist/store-commerce-provider.js +30 -7
- package/dist/store-sdk.d.ts +27 -1
- package/package.json +7 -7
|
@@ -62,6 +62,12 @@ export interface CreateBridgeCommerceProviderInput {
|
|
|
62
62
|
*/
|
|
63
63
|
readonly acceptsFinishRetry?: boolean;
|
|
64
64
|
/**
|
|
65
|
+
* The bridge host accepts `FinishTransactionInput.revoked` (same contract,
|
|
66
|
+
* and its provider declares `acceptsRevokedFinish`). Absent, the provider
|
|
67
|
+
* does not declare it and callers never send `revoked`.
|
|
68
|
+
*/
|
|
69
|
+
readonly acceptsRevokedFinish?: boolean;
|
|
70
|
+
/**
|
|
65
71
|
* The host's purchase presentation facts
|
|
66
72
|
* (`CommerceProviderBridge.subscribePresentation`), each fact of a call
|
|
67
73
|
* that opened no sheet delivered before that call's answer. Only with it
|
package/dist/commerce-bridge.js
CHANGED
|
@@ -241,6 +241,7 @@ export function createBridgeCommerceProvider(input) {
|
|
|
241
241
|
const provider = {
|
|
242
242
|
store: input.store,
|
|
243
243
|
...(input.acceptsFinishRetry === true ? { acceptsFinishRetry: true } : {}),
|
|
244
|
+
...(input.acceptsRevokedFinish === true ? { acceptsRevokedFinish: true } : {}),
|
|
244
245
|
async getCapabilities() {
|
|
245
246
|
return (await send('commerce.v2.getCapabilities', { protocol: commerceProtocol }))
|
|
246
247
|
.capabilities;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { createNativePurchasePresentation, purchasePresentationTimeoutMs, type N
|
|
|
7
7
|
export { createCapacitorProviderRegistry, createDegradedCommerceCapabilities, createDegradedNotificationCapabilities, type CapacitorCommerceServiceProvider, type CapacitorNotificationServiceProvider, type CapacitorNotificationsV2Service, type CapacitorProviderCapabilitySnapshot, type CapacitorProviderRegistry, type CapacitorServiceProvider, type NativeBridge, } from './providers.js';
|
|
8
8
|
export { assertCommerceBridgeResult, commerceV2InvalidPayloadBridgeErrorCode, commerceV2MethodUnsupportedBridgeErrorCode, createBridgeCommerceProvider, createCommerceProviderBridge, createCommerceServiceProvider, type CommerceProviderBridge, type CreateBridgeCommerceProviderInput, type CreateCommerceProviderBridgeInput, type CreateCommerceServiceProviderInput, } from './commerce-bridge.js';
|
|
9
9
|
export { accountBindingLookupFailedStoreCode, createStoreCommerceProvider, purchaseGateFailedStoreCode, purchaseGateTimeoutMs, purchasesPausedStoreCode, recoverableErrorCodes, type CreateStoreCommerceProviderInput, type StoreCommerceCapabilityOverrides, type StoreCommerceProductMapping, type StoreCommerceProvider, type StorePurchaseGate, type StorePurchaseGateDecision, type StorePurchaseGateRequest, } from './store-commerce-provider.js';
|
|
10
|
-
export { defaultStoreSdkErrorCodeMap, normalizeStoreSdkError, type StoreSdk, type StoreSdkCapabilities, type StoreSdkError, type StoreSdkErrorCodeMap, type StoreSdkEvent, type StoreSdkEventName, type StoreSdkEventOf, type StoreSdkFetchProductsInput, type StoreSdkFinishTransactionInput, type StoreSdkFinishTransactionResult, type StoreSdkGetAvailablePurchasesInput, type StoreSdkProduct, type StoreSdkPurchase, type StoreSdkRequestPurchaseInput, type StoreSdkRequestPurchaseResult, } from './store-sdk.js';
|
|
10
|
+
export { defaultStoreSdkErrorCodeMap, normalizeStoreSdkError, type StoreSdk, type StoreSdkCapabilities, type StoreSdkError, type StoreSdkErrorCodeMap, type StoreSdkEvent, type StoreSdkEventName, type StoreSdkEventOf, type StoreSdkFetchProductsInput, type StoreSdkFinishTransactionInput, type StoreSdkGrantedFinishTransactionInput, type StoreSdkRevokedFinishTransactionInput, type StoreSdkFinishTransactionResult, type StoreSdkGetAvailablePurchasesInput, type StoreSdkProduct, type StoreSdkPurchase, type StoreSdkRequestPurchaseInput, type StoreSdkRequestPurchaseResult, } from './store-sdk.js';
|
|
11
11
|
export { createCapacitorAppEvents, type CapacitorAppEventsApi, type CapacitorIncomingUrlKind, type CapacitorVisibilitySource, } from './app-events.js';
|
|
12
12
|
export { CapacitorNativeHttpError, createCapacitorNativeJsonTransport, type CapacitorJsonRequest, type CapacitorJsonResponse, type CapacitorNativeHttpErrorCode, type CapacitorNativeJsonTransport, type CreateCapacitorNativeJsonTransportInput, } from './native-http.js';
|
|
13
13
|
export { createCapacitorViewport, type CapacitorViewportBaseState, type CapacitorOccupiedSurfaceInput, type CapacitorViewportController, type CapacitorViewportHost, } from './viewport.js';
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,7 @@ export function createCapacitorPlatformGateway(input) {
|
|
|
76
76
|
store: commerceProvider.commerce.store,
|
|
77
77
|
// The host below is this package's, on the same contract.
|
|
78
78
|
acceptsFinishRetry: commerceProvider.commerce.acceptsFinishRetry === true,
|
|
79
|
+
acceptsRevokedFinish: commerceProvider.commerce.acceptsRevokedFinish === true,
|
|
79
80
|
request: (method, payload) => request(method, payload),
|
|
80
81
|
// The provider's channel (`NativeBridge`) may carry other protocols.
|
|
81
82
|
// Only an envelope that names another protocol is dropped; anything
|
|
@@ -349,11 +349,15 @@ export function createStoreCommerceProvider(input) {
|
|
|
349
349
|
};
|
|
350
350
|
const finishTransaction = sdk.finishTransaction;
|
|
351
351
|
const restorePurchases = sdk.restorePurchases;
|
|
352
|
+
/** The SDK reads `revoked` and has a finish to take it. */
|
|
353
|
+
const revokedFinish = finishTransaction !== undefined && sdk.acceptsRevokedFinish === true;
|
|
352
354
|
const provider = {
|
|
353
355
|
store,
|
|
354
356
|
...(presentation === undefined ? {} : { presentation: presentation.presentation }),
|
|
355
357
|
// `retry` is forwarded to the SDK below.
|
|
356
358
|
...(finishTransaction === undefined ? {} : { acceptsFinishRetry: true }),
|
|
359
|
+
// `revoked` is forwarded only to an SDK that reads it.
|
|
360
|
+
...(revokedFinish ? { acceptsRevokedFinish: true } : {}),
|
|
357
361
|
getCapabilities,
|
|
358
362
|
async fetchProducts(request = {}) {
|
|
359
363
|
const type = request.type ?? 'all';
|
|
@@ -476,7 +480,14 @@ export function createStoreCommerceProvider(input) {
|
|
|
476
480
|
const purchase = toStorePurchase(candidate);
|
|
477
481
|
// A revoked purchase is not recoverable, and a pending one is listed
|
|
478
482
|
// only on request; both still reach the reconciler through events.
|
|
479
|
-
|
|
483
|
+
// An SDK that finishes revoked transactions keeps its unfinished
|
|
484
|
+
// revoked consumables listed (the only kind a revoked finish takes):
|
|
485
|
+
// the reconciler finishes them once the backend answered for them,
|
|
486
|
+
// and verifies or grants none of them. A revoked purchase of another
|
|
487
|
+
// kind, or of a SKU the catalog does not map, stays filtered.
|
|
488
|
+
if ((purchase.state === 'revoked'
|
|
489
|
+
&& !(revokedFinish && bySku.get(candidate.sku)?.kind === 'consumable'))
|
|
490
|
+
|| (purchase.state === 'pending' && !includePending)) {
|
|
480
491
|
continue;
|
|
481
492
|
}
|
|
482
493
|
purchases.push(purchase);
|
|
@@ -488,14 +499,26 @@ export function createStoreCommerceProvider(input) {
|
|
|
488
499
|
// Finishing is authorized by a ledger entry only; the id is validated
|
|
489
500
|
// before the store hears about it.
|
|
490
501
|
const finish = assertFinishTransactionInput(request);
|
|
502
|
+
if (finish.revoked === true && !revokedFinish) {
|
|
503
|
+
// Never an ordinary finish in its place: the SDK cannot tell the
|
|
504
|
+
// two apart, and this one would run without a grant.
|
|
505
|
+
return { finished: false };
|
|
506
|
+
}
|
|
491
507
|
let reported;
|
|
492
508
|
try {
|
|
493
|
-
reported = await finishTransaction.call(sdk,
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
509
|
+
reported = await finishTransaction.call(sdk, finish.revoked === true
|
|
510
|
+
? {
|
|
511
|
+
transactionId: finish.transactionId,
|
|
512
|
+
isConsumable: true,
|
|
513
|
+
revoked: true,
|
|
514
|
+
...(finish.ledgerEntryId === undefined ? {} : { ledgerEntryId: finish.ledgerEntryId }),
|
|
515
|
+
}
|
|
516
|
+
: {
|
|
517
|
+
transactionId: finish.transactionId,
|
|
518
|
+
isConsumable: finish.isConsumable,
|
|
519
|
+
ledgerEntryId: finish.ledgerEntryId,
|
|
520
|
+
...(finish.retry === true ? { retry: true } : {}),
|
|
521
|
+
});
|
|
499
522
|
}
|
|
500
523
|
catch (error) {
|
|
501
524
|
throw normalize(error);
|
package/dist/store-sdk.d.ts
CHANGED
|
@@ -21,6 +21,16 @@ export interface StoreSdk {
|
|
|
21
21
|
getAvailablePurchases(input: StoreSdkGetAvailablePurchasesInput): Promise<readonly StoreSdkPurchase[]>;
|
|
22
22
|
/** Present when `capabilities.finish` is 'client' or 'host'. Called only after a ledger grant. */
|
|
23
23
|
finishTransaction?(input: StoreSdkFinishTransactionInput): Promise<StoreSdkFinishTransactionResult>;
|
|
24
|
+
/**
|
|
25
|
+
* `finishTransaction` reads `revoked`: it finishes a transaction it still
|
|
26
|
+
* lists as revoked, and only that. `createStoreCommerceProvider` then
|
|
27
|
+
* declares `CommerceProvider.acceptsRevokedFinish` and keeps the revoked
|
|
28
|
+
* consumables `getAvailablePurchases` reports (still unfinished in the
|
|
29
|
+
* store) in its list, so the reconciler can finish them on a later launch; an SDK
|
|
30
|
+
* without it never receives the field, so a store that would read the call
|
|
31
|
+
* as an ordinary finish (a consume) is never asked.
|
|
32
|
+
*/
|
|
33
|
+
readonly acceptsRevokedFinish?: boolean;
|
|
24
34
|
/** Asks the store to resynchronize, for example `AppStore.sync`. */
|
|
25
35
|
restorePurchases?(): Promise<void>;
|
|
26
36
|
addListener<TEvent extends StoreSdkEventName>(eventName: TEvent, listener: (event: StoreSdkEventOf<TEvent>) => void): () => void;
|
|
@@ -126,13 +136,29 @@ export interface StoreSdkPurchase {
|
|
|
126
136
|
/** Store-specific detail the provider never reads; kept for diagnostics only. */
|
|
127
137
|
readonly raw?: Readonly<Record<string, unknown>>;
|
|
128
138
|
}
|
|
129
|
-
|
|
139
|
+
/**
|
|
140
|
+
* What `StoreSdk.finishTransaction` is asked to finish: a purchase the
|
|
141
|
+
* backend ledger granted, or (only for an SDK that declares
|
|
142
|
+
* `acceptsRevokedFinish`) a consumable the store revoked while it was still
|
|
143
|
+
* unfinished, which no grant stands for.
|
|
144
|
+
*/
|
|
145
|
+
export type StoreSdkFinishTransactionInput = StoreSdkGrantedFinishTransactionInput | StoreSdkRevokedFinishTransactionInput;
|
|
146
|
+
export interface StoreSdkGrantedFinishTransactionInput {
|
|
130
147
|
readonly transactionId: string;
|
|
131
148
|
readonly isConsumable: boolean;
|
|
132
149
|
/** `FinishTransactionInput.retry`: an earlier finish of this purchase was asked for. */
|
|
133
150
|
readonly retry?: boolean;
|
|
134
151
|
/** The ledger entry that authorized the finish; a plugin may record it. */
|
|
135
152
|
readonly ledgerEntryId: string;
|
|
153
|
+
readonly revoked?: false;
|
|
154
|
+
}
|
|
155
|
+
/** `RevokedFinishTransactionInput`: finish a revoked consumable, granting nothing. */
|
|
156
|
+
export interface StoreSdkRevokedFinishTransactionInput {
|
|
157
|
+
readonly transactionId: string;
|
|
158
|
+
readonly isConsumable: true;
|
|
159
|
+
readonly revoked: true;
|
|
160
|
+
/** The reversed grant's ledger entry; absent when nothing was ever granted. */
|
|
161
|
+
readonly ledgerEntryId?: string;
|
|
136
162
|
}
|
|
137
163
|
export interface StoreSdkFinishTransactionResult {
|
|
138
164
|
readonly finished: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/adapter-capacitor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Capacitor platform adapter for mpgd Android and iOS shells.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@capacitor/app": "8.1.1",
|
|
54
|
-
"@mpgd/
|
|
55
|
-
"@mpgd/game-services": "0.
|
|
56
|
-
"@mpgd/
|
|
57
|
-
"@mpgd/platform": "0.
|
|
58
|
-
"@mpgd/
|
|
54
|
+
"@mpgd/bridge": "0.18.1",
|
|
55
|
+
"@mpgd/capacitor-game-services": "0.9.6",
|
|
56
|
+
"@mpgd/game-services": "0.33.0",
|
|
57
|
+
"@mpgd/platform": "0.35.0",
|
|
58
|
+
"@mpgd/target-config": "0.24.6"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@capacitor-community/admob": "^8.1.0",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"ttsc": "0.34.2",
|
|
93
93
|
"typescript": "7.0.2",
|
|
94
94
|
"vitest": "^4.0.0",
|
|
95
|
-
"@mpgd/game-runtime": "0.
|
|
95
|
+
"@mpgd/game-runtime": "0.10.0"
|
|
96
96
|
},
|
|
97
97
|
"main": "./dist/index.js",
|
|
98
98
|
"types": "./dist/index.d.ts",
|