@mpgd/game-services 0.21.1 → 0.22.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/README.md +30 -0
- package/dist/admob-ssv-conformance.js +3 -1
- package/dist/app-store-recovery.js +5 -0
- package/dist/client.d.ts +39 -1
- package/dist/client.js +198 -0
- package/dist/commerce-evidence-registry.d.ts +406 -0
- package/dist/commerce-evidence-registry.js +773 -0
- package/dist/commerce-ledger.d.ts +64 -0
- package/dist/commerce-ledger.js +146 -0
- package/dist/commerce-reconciler.d.ts +191 -0
- package/dist/commerce-reconciler.js +1251 -0
- package/dist/contract.d.ts +4 -1
- package/dist/contract.js +8 -0
- package/dist/evidence-verification.d.ts +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/monetization-operation-store.d.ts +20 -0
- package/dist/monetization-operation-store.js +80 -0
- package/dist/monetization-recovery.d.ts +57 -2
- package/dist/monetization-recovery.js +102 -8
- package/dist/operation-results.d.ts +14 -0
- package/dist/operations.d.ts +2 -1
- package/dist/platform-order.d.ts +47 -0
- package/dist/platform-order.js +86 -0
- package/dist/runtime.js +12 -1
- package/dist/server.d.ts +43 -1
- package/dist/server.js +305 -7
- package/dist/types.d.ts +79 -3
- package/dist/types.js +97 -6
- package/package.json +18 -6
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import type { ProductGrant } from '@mpgd/catalog';
|
|
2
2
|
import type { LeaderboardScoreInput, LogicalAdPlacementId, LogicalProductId, PlatformEvidenceEnvelope, PlatformTarget } from '@mpgd/platform';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type { StoreId } from '@mpgd/platform/commerce';
|
|
4
|
+
import type { ClaimAdRewardResponse, PurchaseGrantFinalization, PurchaseLedgerStatusRequest, PurchaseLedgerStatusResponse, VerifyPurchaseResponse } from './operation-results.js';
|
|
5
|
+
export type { ClaimAdRewardResponse, PurchaseGrantFinalization, PurchaseGrantFinalizationAction, PurchaseLedgerStatus, PurchaseLedgerStatusRequest, PurchaseLedgerStatusResponse, VerifyPurchaseResponse, } from './operation-results.js';
|
|
5
6
|
export type { PlatformEvidenceEnvelope } from '@mpgd/platform';
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The closed v1 purchase target list. The deployment target of a v1 verify
|
|
9
|
+
* request names its store implicitly (`android` is Google Play, `ios` the App
|
|
10
|
+
* Store, `ait` Apps in Toss); `resolveLegacyCommerceStoreId` is that mapping.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated `VerifyPurchaseRequest.target` is open since commerce v2 C2
|
|
13
|
+
* (`GameServicesStoreTarget` is `StoreId`); C4 removes this alias.
|
|
14
|
+
*/
|
|
15
|
+
export type GameServicesLegacyStoreTarget = Extract<PlatformTarget, 'microsoft-store' | 'android' | 'ios' | 'ait' | 'oneplay'>;
|
|
16
|
+
/**
|
|
17
|
+
* An open store or deployment target identifier (RFC "Open store ids"). The
|
|
18
|
+
* request validator bounds its shape; the backend's commerce evidence
|
|
19
|
+
* registry decides which stores it serves.
|
|
20
|
+
*/
|
|
21
|
+
export type GameServicesStoreTarget = StoreId;
|
|
7
22
|
export type GameServicesAdRewardTarget = GameServicesLedgerTarget;
|
|
8
23
|
export type GameServicesLeaderboardTarget = Extract<PlatformTarget, 'browser' | 'microsoft-store' | 'android' | 'ios' | 'ait' | 'reddit'>;
|
|
9
24
|
export type GameServicesLedgerTarget = Extract<PlatformTarget, 'browser' | 'microsoft-store' | 'android' | 'ios' | 'ait' | 'reddit' | 'verse8' | 'oneplay'>;
|
|
@@ -13,7 +28,17 @@ export type EntitlementIdempotencyKey = PurchaseIdempotencyKey | AdRewardIdempot
|
|
|
13
28
|
export type EntitlementLedgerSource = 'purchase' | 'ad_reward' | 'admin';
|
|
14
29
|
export type EntitlementLedgerPayload = Record<string, string | number | boolean>;
|
|
15
30
|
export interface VerifyPurchaseRequest {
|
|
31
|
+
/** The ledger (deployment platform) target; see `store` for the store the purchase was made in. */
|
|
16
32
|
readonly target: GameServicesStoreTarget;
|
|
33
|
+
/**
|
|
34
|
+
* The open store id the purchase was made in (RFC "Open store ids"), for
|
|
35
|
+
* example `google-play` or `credit-wallet`. A v1 request without it names
|
|
36
|
+
* its store through `target`: `android` is `google-play`, `ios` is
|
|
37
|
+
* `app-store`, `ait` is `apps-in-toss`, `reddit` is `devvit`, and every
|
|
38
|
+
* other target (`microsoft-store`, `verse8`, `oneplay`) is its own store id
|
|
39
|
+
* (`resolveLegacyCommerceStoreId`).
|
|
40
|
+
*/
|
|
41
|
+
readonly store?: StoreId;
|
|
17
42
|
/** Deployment config key used to resolve game-owned platform product identifiers. */
|
|
18
43
|
readonly deploymentTarget?: string;
|
|
19
44
|
readonly playerId: string;
|
|
@@ -62,6 +87,44 @@ export interface EntitlementLedgerResult {
|
|
|
62
87
|
readonly ledgerEntryId: string;
|
|
63
88
|
readonly alreadyProcessed: boolean;
|
|
64
89
|
}
|
|
90
|
+
/** Why a grant was reversed (RFC "Revocation and expiry entries"). */
|
|
91
|
+
export type EntitlementRevocationReason = 'refund' | 'chargeback' | 'voided' | 'admin';
|
|
92
|
+
/**
|
|
93
|
+
* A `revoke` ledger entry: it references the grant it reverses and never
|
|
94
|
+
* removes it, so the ledger stays append-only. Store notification handlers
|
|
95
|
+
* (a Play voided purchase, an App Store refund, an Apps in Toss or Devvit
|
|
96
|
+
* refunded order) write one through `revokeEntitlementGrant`; the entry's
|
|
97
|
+
* `idempotencyKey` makes the notification replay-safe.
|
|
98
|
+
*/
|
|
99
|
+
export interface EntitlementLedgerRevocation {
|
|
100
|
+
readonly playerId: string;
|
|
101
|
+
/** The `ledgerEntryId` of the grant this entry reverses. */
|
|
102
|
+
readonly revokesLedgerEntryId: string;
|
|
103
|
+
readonly idempotencyKey: string;
|
|
104
|
+
readonly reason: EntitlementRevocationReason;
|
|
105
|
+
readonly revokedAt: string;
|
|
106
|
+
readonly payload: EntitlementLedgerPayload;
|
|
107
|
+
/** The notification's own authority identity, when the handler has one. */
|
|
108
|
+
readonly evidenceVerificationId?: string;
|
|
109
|
+
}
|
|
110
|
+
export interface EntitlementRevocationTransaction extends EntitlementLedgerRevocation {
|
|
111
|
+
readonly ledgerEntryId: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A subscription `period` ledger entry: it extends an earlier grant with a
|
|
115
|
+
* renewal period and its expiry. This is the shape only; no reference store
|
|
116
|
+
* verifier writes one until a subscription verifier exists.
|
|
117
|
+
*/
|
|
118
|
+
export interface EntitlementLedgerPeriod {
|
|
119
|
+
readonly playerId: string;
|
|
120
|
+
/** The `ledgerEntryId` of the subscription grant this period extends. */
|
|
121
|
+
readonly extendsLedgerEntryId: string;
|
|
122
|
+
readonly idempotencyKey: string;
|
|
123
|
+
readonly periodIndex: number;
|
|
124
|
+
readonly startedAt: string;
|
|
125
|
+
readonly expiresAt: string;
|
|
126
|
+
readonly payload: EntitlementLedgerPayload;
|
|
127
|
+
}
|
|
65
128
|
export interface ProductGrantTransaction {
|
|
66
129
|
readonly ledgerEntryId: string;
|
|
67
130
|
readonly playerId: string;
|
|
@@ -83,6 +146,14 @@ export interface LeaderboardScoreTransaction extends RecordLeaderboardScoreReque
|
|
|
83
146
|
*/
|
|
84
147
|
export declare function assertVerifyPurchaseRequest(input: VerifyPurchaseRequest): VerifyPurchaseRequest;
|
|
85
148
|
export declare function assertVerifyPurchaseResponse(input: VerifyPurchaseResponse): VerifyPurchaseResponse;
|
|
149
|
+
/** Bounds one ledger status read; a client asks for the grants of one journal window. */
|
|
150
|
+
export declare const maxPurchaseLedgerStatusEntries = 256;
|
|
151
|
+
/**
|
|
152
|
+
* Validates an untrusted ledger status read. Failures throw
|
|
153
|
+
* `GameServicesRequestValidationError` so transports can answer with a stable 400.
|
|
154
|
+
*/
|
|
155
|
+
export declare function assertPurchaseLedgerStatusRequest(input: PurchaseLedgerStatusRequest): PurchaseLedgerStatusRequest;
|
|
156
|
+
export declare function assertPurchaseLedgerStatusResponse(input: PurchaseLedgerStatusResponse): PurchaseLedgerStatusResponse;
|
|
86
157
|
export declare function assertPurchaseGrantFinalization(input: PurchaseGrantFinalization): PurchaseGrantFinalization;
|
|
87
158
|
/**
|
|
88
159
|
* Validates an untrusted ad reward claim. Failures throw
|
|
@@ -98,6 +169,11 @@ export declare function assertRecordLeaderboardScoreRequest(input: RecordLeaderb
|
|
|
98
169
|
export declare function assertRecordLeaderboardScoreResponse(input: RecordLeaderboardScoreResponse): RecordLeaderboardScoreResponse;
|
|
99
170
|
export declare function assertEntitlementLedgerGrant(input: EntitlementLedgerGrant): EntitlementLedgerGrant;
|
|
100
171
|
export declare function assertEntitlementLedgerResult(input: EntitlementLedgerResult): EntitlementLedgerResult;
|
|
172
|
+
export declare function assertEntitlementLedgerRevocation(input: EntitlementLedgerRevocation): EntitlementLedgerRevocation;
|
|
173
|
+
export declare function assertEntitlementRevocationTransaction(input: EntitlementRevocationTransaction): EntitlementRevocationTransaction;
|
|
174
|
+
export declare function assertEntitlementLedgerPeriod(input: EntitlementLedgerPeriod): EntitlementLedgerPeriod;
|
|
101
175
|
export declare function assertProductGrantTransaction(input: ProductGrantTransaction): ProductGrantTransaction;
|
|
102
176
|
export declare function assertLeaderboardScoreTransaction(input: LeaderboardScoreTransaction): LeaderboardScoreTransaction;
|
|
177
|
+
/** A store id is a bounded kebab-case identifier such as `google-play` or `credit-wallet`. */
|
|
178
|
+
export declare function assertCommerceStoreId(input: unknown, label?: string): asserts input is StoreId;
|
|
103
179
|
export declare function assertGameServicesDeploymentTarget(input: unknown): asserts input is string;
|
package/dist/types.js
CHANGED
|
@@ -7,6 +7,9 @@ export function assertVerifyPurchaseRequest(input) {
|
|
|
7
7
|
return validateRequest(() => {
|
|
8
8
|
assertRecord(input, 'VerifyPurchaseRequest');
|
|
9
9
|
assertStoreTarget(input.target);
|
|
10
|
+
if (input.store !== undefined) {
|
|
11
|
+
assertCommerceStoreId(input.store, 'store');
|
|
12
|
+
}
|
|
10
13
|
assertOptionalGameServicesDeploymentTarget(input.deploymentTarget);
|
|
11
14
|
assertRequestString(input.playerId, 'playerId');
|
|
12
15
|
assertRequestString(input.productId, 'productId');
|
|
@@ -29,6 +32,49 @@ export function assertVerifyPurchaseResponse(input) {
|
|
|
29
32
|
}
|
|
30
33
|
return input;
|
|
31
34
|
}
|
|
35
|
+
/** Bounds one ledger status read; a client asks for the grants of one journal window. */
|
|
36
|
+
export const maxPurchaseLedgerStatusEntries = 256;
|
|
37
|
+
/**
|
|
38
|
+
* Validates an untrusted ledger status read. Failures throw
|
|
39
|
+
* `GameServicesRequestValidationError` so transports can answer with a stable 400.
|
|
40
|
+
*/
|
|
41
|
+
export function assertPurchaseLedgerStatusRequest(input) {
|
|
42
|
+
return validateRequest(() => {
|
|
43
|
+
assertRecord(input, 'PurchaseLedgerStatusRequest');
|
|
44
|
+
if (!Array.isArray(input.ledgerEntryIds)) {
|
|
45
|
+
throw new Error('ledgerEntryIds must be an array.');
|
|
46
|
+
}
|
|
47
|
+
if (input.ledgerEntryIds.length > maxPurchaseLedgerStatusEntries) {
|
|
48
|
+
throw new Error(`ledgerEntryIds must not exceed ${String(maxPurchaseLedgerStatusEntries)} entries.`);
|
|
49
|
+
}
|
|
50
|
+
for (const ledgerEntryId of input.ledgerEntryIds) {
|
|
51
|
+
assertRequestString(ledgerEntryId, 'ledgerEntryIds[]');
|
|
52
|
+
}
|
|
53
|
+
assertRequestString(input.playerId, 'playerId');
|
|
54
|
+
return input;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export function assertPurchaseLedgerStatusResponse(input) {
|
|
58
|
+
assertRecord(input, 'PurchaseLedgerStatusResponse');
|
|
59
|
+
if (!Array.isArray(input.statuses)) {
|
|
60
|
+
throw new Error('statuses must be an array.');
|
|
61
|
+
}
|
|
62
|
+
for (const status of input.statuses) {
|
|
63
|
+
assertRecord(status, 'statuses[]');
|
|
64
|
+
assertNonEmptyString(status.ledgerEntryId, 'statuses[].ledgerEntryId');
|
|
65
|
+
if (status.status !== 'active' && status.status !== 'reversed' && status.status !== 'unknown') {
|
|
66
|
+
throw new Error('statuses[].status must be active, reversed, or unknown.');
|
|
67
|
+
}
|
|
68
|
+
assertOptionalNonEmptyString(status.reversedBy, 'statuses[].reversedBy');
|
|
69
|
+
if (status.status === 'reversed' && status.reversedBy === undefined) {
|
|
70
|
+
throw new Error('a reversed status names the entry that reversed it.');
|
|
71
|
+
}
|
|
72
|
+
if (status.status !== 'reversed' && status.reversedBy !== undefined) {
|
|
73
|
+
throw new Error('only a reversed status names a reversing entry.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return input;
|
|
77
|
+
}
|
|
32
78
|
export function assertPurchaseGrantFinalization(input) {
|
|
33
79
|
assertRecord(input, 'PurchaseGrantFinalization');
|
|
34
80
|
if (input.status !== 'completed' && input.status !== 'pending') {
|
|
@@ -124,6 +170,38 @@ export function assertEntitlementLedgerResult(input) {
|
|
|
124
170
|
assertBoolean(input.alreadyProcessed, 'alreadyProcessed');
|
|
125
171
|
return input;
|
|
126
172
|
}
|
|
173
|
+
export function assertEntitlementLedgerRevocation(input) {
|
|
174
|
+
assertRecord(input, 'EntitlementLedgerRevocation');
|
|
175
|
+
assertNonEmptyString(input.playerId, 'playerId');
|
|
176
|
+
assertNonEmptyString(input.revokesLedgerEntryId, 'revokesLedgerEntryId');
|
|
177
|
+
assertNonEmptyString(input.idempotencyKey, 'idempotencyKey');
|
|
178
|
+
assertRevocationReason(input.reason);
|
|
179
|
+
assertNonEmptyString(input.revokedAt, 'revokedAt');
|
|
180
|
+
assertPayload(input.payload);
|
|
181
|
+
assertOptionalNonEmptyString(input.evidenceVerificationId, 'evidenceVerificationId');
|
|
182
|
+
return input;
|
|
183
|
+
}
|
|
184
|
+
export function assertEntitlementRevocationTransaction(input) {
|
|
185
|
+
assertEntitlementLedgerRevocation(input);
|
|
186
|
+
assertNonEmptyString(input.ledgerEntryId, 'ledgerEntryId');
|
|
187
|
+
return input;
|
|
188
|
+
}
|
|
189
|
+
export function assertEntitlementLedgerPeriod(input) {
|
|
190
|
+
assertRecord(input, 'EntitlementLedgerPeriod');
|
|
191
|
+
assertNonEmptyString(input.playerId, 'playerId');
|
|
192
|
+
assertNonEmptyString(input.extendsLedgerEntryId, 'extendsLedgerEntryId');
|
|
193
|
+
assertNonEmptyString(input.idempotencyKey, 'idempotencyKey');
|
|
194
|
+
if (!Number.isSafeInteger(input.periodIndex) || input.periodIndex < 0) {
|
|
195
|
+
throw new Error('periodIndex must be a non-negative integer.');
|
|
196
|
+
}
|
|
197
|
+
assertNonEmptyString(input.startedAt, 'startedAt');
|
|
198
|
+
assertNonEmptyString(input.expiresAt, 'expiresAt');
|
|
199
|
+
if (!(Date.parse(input.expiresAt) > Date.parse(input.startedAt))) {
|
|
200
|
+
throw new Error('expiresAt must be a timestamp after startedAt.');
|
|
201
|
+
}
|
|
202
|
+
assertPayload(input.payload);
|
|
203
|
+
return input;
|
|
204
|
+
}
|
|
127
205
|
export function assertProductGrantTransaction(input) {
|
|
128
206
|
assertRecord(input, 'ProductGrantTransaction');
|
|
129
207
|
assertNonEmptyString(input.ledgerEntryId, 'ledgerEntryId');
|
|
@@ -150,13 +228,21 @@ function assertRecord(input, label) {
|
|
|
150
228
|
throw new Error(`${label} must be an object.`);
|
|
151
229
|
}
|
|
152
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* The purchase target is open (RFC "Open store ids"): any bounded kebab-case
|
|
233
|
+
* identifier passes here, and the backend's commerce evidence registry decides
|
|
234
|
+
* whether the store it names is served.
|
|
235
|
+
*/
|
|
153
236
|
function assertStoreTarget(input) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
237
|
+
assertCommerceStoreId(input, 'target');
|
|
238
|
+
}
|
|
239
|
+
/** A store id is a bounded kebab-case identifier such as `google-play` or `credit-wallet`. */
|
|
240
|
+
export function assertCommerceStoreId(input, label = 'store') {
|
|
241
|
+
if (typeof input !== 'string'
|
|
242
|
+
|| input.length === 0
|
|
243
|
+
|| input.length > 64
|
|
244
|
+
|| !/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(input)) {
|
|
245
|
+
throw new Error(`${label} must be a lowercase kebab-case store identifier.`);
|
|
160
246
|
}
|
|
161
247
|
}
|
|
162
248
|
function assertAdRewardTarget(input) {
|
|
@@ -262,6 +348,11 @@ function assertPurchaseGrantFinalizationAction(input) {
|
|
|
262
348
|
throw new Error('finalization.action must be acknowledge, consume, finish, or complete.');
|
|
263
349
|
}
|
|
264
350
|
}
|
|
351
|
+
function assertRevocationReason(input) {
|
|
352
|
+
if (input !== 'refund' && input !== 'chargeback' && input !== 'voided' && input !== 'admin') {
|
|
353
|
+
throw new Error('reason must be refund, chargeback, voided, or admin.');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
265
356
|
function assertLedgerSource(input) {
|
|
266
357
|
if (input !== 'purchase' && input !== 'ad_reward' && input !== 'admin') {
|
|
267
358
|
throw new Error('source must be purchase, ad_reward, or admin.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/game-services",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Client, contract, server, store, and test helpers for authoritative mpgd game services.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -77,6 +77,18 @@
|
|
|
77
77
|
"types": "./dist/apps-in-toss-partner-api.d.ts",
|
|
78
78
|
"default": "./dist/apps-in-toss-partner-api.js"
|
|
79
79
|
},
|
|
80
|
+
"./commerce-evidence-registry": {
|
|
81
|
+
"types": "./dist/commerce-evidence-registry.d.ts",
|
|
82
|
+
"default": "./dist/commerce-evidence-registry.js"
|
|
83
|
+
},
|
|
84
|
+
"./commerce-reconciler": {
|
|
85
|
+
"types": "./dist/commerce-reconciler.d.ts",
|
|
86
|
+
"default": "./dist/commerce-reconciler.js"
|
|
87
|
+
},
|
|
88
|
+
"./monetization-operation-store": {
|
|
89
|
+
"types": "./dist/monetization-operation-store.d.ts",
|
|
90
|
+
"default": "./dist/monetization-operation-store.js"
|
|
91
|
+
},
|
|
80
92
|
"./client": {
|
|
81
93
|
"types": "./dist/client.d.ts",
|
|
82
94
|
"default": "./dist/client.js"
|
|
@@ -190,9 +202,9 @@
|
|
|
190
202
|
"@orpc/client": "2.0.0-beta.14",
|
|
191
203
|
"@orpc/contract": "2.0.0-beta.14",
|
|
192
204
|
"@orpc/server": "2.0.0-beta.14",
|
|
193
|
-
"@mpgd/
|
|
194
|
-
"@mpgd/
|
|
195
|
-
"@mpgd/
|
|
205
|
+
"@mpgd/analytics": "0.4.8",
|
|
206
|
+
"@mpgd/catalog": "0.9.3",
|
|
207
|
+
"@mpgd/platform": "0.22.0"
|
|
196
208
|
},
|
|
197
209
|
"peerDependencies": {
|
|
198
210
|
"@apple/app-store-server-library": "^3.1.0"
|
|
@@ -221,8 +233,8 @@
|
|
|
221
233
|
"fix": "ttsc fix",
|
|
222
234
|
"build": "cd ../.. && node tools/run-ttsx.mjs tools/package/build-packages.ts @mpgd/game-services",
|
|
223
235
|
"test:packed-transport": "pnpm build && node test/runtime-transport-package-import.mjs && node test/reward-evidence-import.mjs",
|
|
224
|
-
"test:unit": "cd ../.. && node tools/run-ttsx.mjs packages/game-services/src/client.test.ts && node tools/run-ttsx.mjs packages/game-services/src/client-progress.test.ts && node tools/run-ttsx.mjs packages/game-services/src/runtime.test.ts && node tools/run-ttsx.mjs packages/game-services/src/types.test.ts && node tools/run-ttsx.mjs packages/game-services/src/server.test.ts && node tools/run-ttsx.mjs packages/game-services/src/google-play-purchase.test.ts && node tools/run-ttsx.mjs packages/game-services/src/google-play-publisher-client.test.ts && node tools/run-ttsx.mjs packages/game-services/src/microsoft-store-purchase.test.ts && node tools/run-ttsx.mjs packages/game-services/src/microsoft-store-identity.test.ts && node tools/run-ttsx.mjs packages/game-services/src/platform-order.test.ts && node tools/run-ttsx.mjs packages/game-services/src/progress-link.test.ts && node tools/run-ttsx.mjs packages/game-services/src/notification-delivery.test.ts && node tools/run-ttsx.mjs packages/game-services/src/admob-ssv.test.ts && node tools/run-ttsx.mjs packages/game-services/src/app-store-verifier.test.ts && node tools/run-ttsx.mjs packages/game-services/src/apps-in-toss-evidence-verification-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/apps-in-toss-partner-api.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-durability-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-transport.test.ts && node tools/run-ttsx.mjs packages/game-services/src/guest-session.test.ts && node tools/run-ttsx.mjs packages/game-services/src/client-reward-evidence.test.ts && node tools/run-ttsx.mjs packages/game-services/src/ad-reward-verifier-registry.test.ts && node tools/run-ttsx.mjs packages/game-services/src/oneplay-reward.test.ts && node tools/run-ttsx.mjs packages/game-services/src/oneplay-purchase.test.ts",
|
|
225
|
-
"test:recovery": "cd ../.. && node tools/run-ttsx.mjs packages/game-services/src/monetization-recovery.test.ts && node tools/run-ttsx.mjs packages/game-services/src/app-store-recovery.test.ts",
|
|
236
|
+
"test:unit": "cd ../.. && node tools/run-ttsx.mjs packages/game-services/src/client.test.ts && node tools/run-ttsx.mjs packages/game-services/src/client-progress.test.ts && node tools/run-ttsx.mjs packages/game-services/src/runtime.test.ts && node tools/run-ttsx.mjs packages/game-services/src/types.test.ts && node tools/run-ttsx.mjs packages/game-services/src/server.test.ts && node tools/run-ttsx.mjs packages/game-services/src/google-play-purchase.test.ts && node tools/run-ttsx.mjs packages/game-services/src/google-play-publisher-client.test.ts && node tools/run-ttsx.mjs packages/game-services/src/microsoft-store-purchase.test.ts && node tools/run-ttsx.mjs packages/game-services/src/microsoft-store-identity.test.ts && node tools/run-ttsx.mjs packages/game-services/src/platform-order.test.ts && node tools/run-ttsx.mjs packages/game-services/src/progress-link.test.ts && node tools/run-ttsx.mjs packages/game-services/src/notification-delivery.test.ts && node tools/run-ttsx.mjs packages/game-services/src/admob-ssv.test.ts && node tools/run-ttsx.mjs packages/game-services/src/app-store-verifier.test.ts && node tools/run-ttsx.mjs packages/game-services/src/apps-in-toss-evidence-verification-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/apps-in-toss-partner-api.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-durability-conformance.test.ts && node tools/run-ttsx.mjs packages/game-services/src/verified-leaderboard-transport.test.ts && node tools/run-ttsx.mjs packages/game-services/src/guest-session.test.ts && node tools/run-ttsx.mjs packages/game-services/src/client-reward-evidence.test.ts && node tools/run-ttsx.mjs packages/game-services/src/ad-reward-verifier-registry.test.ts && node tools/run-ttsx.mjs packages/game-services/src/oneplay-reward.test.ts && node tools/run-ttsx.mjs packages/game-services/src/oneplay-purchase.test.ts && node tools/run-ttsx.mjs packages/game-services/src/commerce-registry-routing.test.ts && node tools/run-ttsx.mjs packages/game-services/src/commerce-registry-server.test.ts && node tools/run-ttsx.mjs packages/game-services/src/commerce-ledger-revocation.test.ts",
|
|
237
|
+
"test:recovery": "cd ../.. && node tools/run-ttsx.mjs packages/game-services/src/monetization-recovery.test.ts && node tools/run-ttsx.mjs packages/game-services/src/app-store-recovery.test.ts && node tools/run-ttsx.mjs packages/game-services/src/commerce-reconciler.test.ts && node tools/run-ttsx.mjs packages/game-services/src/commerce-reconciler-conformance.test.ts",
|
|
226
238
|
"test": "pnpm test:unit && pnpm test:app-store-server && pnpm test:recovery && pnpm test:packed-transport",
|
|
227
239
|
"test:app-store-server": "vitest run"
|
|
228
240
|
}
|