@mpgd/platform 0.19.0 → 0.20.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-conformance.d.ts +136 -4
- package/dist/commerce-conformance.js +485 -24
- package/dist/commerce-contract.d.ts +222 -0
- package/dist/commerce-contract.js +1 -0
- package/dist/commerce-vectors.d.ts +8 -0
- package/dist/commerce-vectors.js +38 -33
- package/dist/commerce.d.ts +3 -145
- package/dist/commerce.js +228 -228
- package/dist/index.d.ts +8 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ActiveSubscription, type CommerceBillingAuthority, type CommerceCapabilities, type CommerceErrorCode, type CommerceErrorInfo, type CommerceEvent, type CommerceLogicalProductId, type CommerceProvider, type CommercePurchaseState, type CreditBalance, type CreditDebit, type CreditEntitlement, type CreditLot, type CreditLotSpendScope, type CreditMembershipTerms, type CreditOffer, type CreditSpendInput, type CreditSpendResult, type CreditWalletClient, type FetchProductsInput, type PurchaseKind, type RequestPurchaseInput, type RequestPurchaseResult, type StoreId, type StoreProduct, type StorePurchase } from './commerce.js';
|
|
2
|
-
import type { CommerceConformanceCatalogEntry, CommerceConformanceErrorFixture, CommerceConformanceFinishResultFixture, CommerceConformanceLotFixture, CommerceConformanceProfile, CommerceConformancePurchaseFixture, CommerceConformanceRequestResultFixture, CommerceConformanceSubscriptionEventType, CommerceConformanceVector, CommerceConformanceVerifyDecision } from './commerce-vectors.js';
|
|
1
|
+
import { type ActiveSubscription, type CommerceBillingAuthority, type CommerceCapabilities, type CommerceErrorCode, type CommerceErrorInfo, type CommerceEvent, type CommerceEvidenceAuthority, type CommerceFinishOwner, type CommerceLogicalProductId, type CommerceProvider, type CommercePurchaseState, type CreditBalance, type CreditDebit, type CreditEntitlement, type CreditLot, type CreditLotSpendScope, type CreditMembershipTerms, type CreditOffer, type CreditSpendInput, type CreditSpendResult, type CreditWalletClient, type FetchProductsInput, type PurchaseKind, type RequestPurchaseInput, type RequestPurchaseResult, type StoreId, type StoreProduct, type StorePurchase } from './commerce.js';
|
|
2
|
+
import type { CommerceConformanceCatalogEntry, CommerceConformanceErrorFixture, CommerceConformanceExpectation, CommerceConformanceFinishResultFixture, CommerceConformanceLotFixture, CommerceConformanceProfile, CommerceConformancePurchaseFixture, CommerceConformanceRequestResultFixture, CommerceConformanceSubscriptionEventType, CommerceConformanceVector, CommerceConformanceVerifyDecision } from './commerce-vectors.js';
|
|
3
3
|
import type { PlatformEvidenceEnvelope } from './index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Commerce v2 conformance runner (RFC "Conformance vectors") with the in-memory
|
|
@@ -12,7 +12,11 @@ import type { PlatformEvidenceEnvelope } from './index.js';
|
|
|
12
12
|
*
|
|
13
13
|
* Store (B-phase) providers run the same vectors by supplying
|
|
14
14
|
* `createProvider` and translating the store actor steps into their own fake
|
|
15
|
-
* SDK; the reconciler, journal, backend, and matcher stay shared.
|
|
15
|
+
* SDK; the reconciler, journal, backend, and matcher stay shared. A vector
|
|
16
|
+
* flagged `profile.adaptive` then matches expectations derived from the
|
|
17
|
+
* provider's declared capabilities rather than its fixture profile; see
|
|
18
|
+
* `deriveAdaptiveCommerceConformanceExpectation` and
|
|
19
|
+
* `commerceConformanceAdaptiveSkipReason`.
|
|
16
20
|
*/
|
|
17
21
|
export declare const commerceConformanceDefaultPlayerId = "player-1";
|
|
18
22
|
export declare const commerceConformanceDefaultTitleId = "title-a";
|
|
@@ -72,6 +76,14 @@ export interface CommerceConformanceStoreActor {
|
|
|
72
76
|
readonly transactionId: string;
|
|
73
77
|
readonly ledgerEntryId: string;
|
|
74
78
|
}): void | Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* The `token` this store reports for a fixture purchase when it is not the
|
|
81
|
+
* fixture's own: a host-order store reports the transaction id (RFC "Client
|
|
82
|
+
* contract"). An adaptive run replays the fixture purchases with this token
|
|
83
|
+
* into the reference store, so the derived verify requests carry the token
|
|
84
|
+
* the provider under test reports. Absent, the fixture token is used.
|
|
85
|
+
*/
|
|
86
|
+
tokenOf?(purchase: CommerceConformancePurchaseFixture): string;
|
|
75
87
|
}
|
|
76
88
|
export interface CommerceConformanceStore extends CommerceConformanceStoreActor {
|
|
77
89
|
/** The `CommerceProvider` over this fake store. */
|
|
@@ -163,12 +175,24 @@ export interface CreateCommerceConformanceBackendInput {
|
|
|
163
175
|
readonly ledgerEntryId: string;
|
|
164
176
|
readonly logicalId: CommerceLogicalProductId;
|
|
165
177
|
}) => void | Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* When it returns true, a verify request that replays a key this backend
|
|
180
|
+
* already granted is a finalization re-read (the reference reconciler under a
|
|
181
|
+
* server-owned finish): it is answered `{ granted, ledgerEntryId,
|
|
182
|
+
* finalization: 'completed', alreadyProcessed: true }` from the backend's own
|
|
183
|
+
* grant state and runs the finalizer, consuming no queued decision. Read on
|
|
184
|
+
* every call, so the runner can decide it once the provider's capabilities
|
|
185
|
+
* are known.
|
|
186
|
+
*/
|
|
187
|
+
readonly finalizeOnReread?: () => boolean;
|
|
166
188
|
}
|
|
167
189
|
/**
|
|
168
190
|
* Fake backend: every verify call consumes the next `queueVerify` decision in
|
|
169
191
|
* order and is logged; an unqueued verify is an unscripted operation. A
|
|
170
192
|
* `granted` decision makes sure the ledger holds the entry, so a replayed
|
|
171
|
-
* grant and a host-pushed grant never create a second entry.
|
|
193
|
+
* grant and a host-pushed grant never create a second entry. With
|
|
194
|
+
* `finalizeOnReread`, a replayed granted key is answered as finalized from
|
|
195
|
+
* the backend's own state.
|
|
172
196
|
*/
|
|
173
197
|
export declare function createCommerceConformanceBackend(input?: CreateCommerceConformanceBackendInput): CommerceConformanceBackend;
|
|
174
198
|
export interface CommerceJournalRecord {
|
|
@@ -364,10 +388,33 @@ export interface CommerceConformanceFailure {
|
|
|
364
388
|
readonly expected: unknown;
|
|
365
389
|
readonly actual: unknown;
|
|
366
390
|
}
|
|
391
|
+
export type CommerceConformanceVectorStatus = 'passed' | 'failed' | 'skipped';
|
|
392
|
+
/**
|
|
393
|
+
* `CommerceConformanceExpectation` as the matcher consumes it: a derived
|
|
394
|
+
* `finishCalls` list carries the store actor's own records, whose `result` may
|
|
395
|
+
* also be `unfinished`.
|
|
396
|
+
*/
|
|
397
|
+
export interface CommerceConformanceResolvedExpectation extends Omit<CommerceConformanceExpectation, 'finishCalls'> {
|
|
398
|
+
readonly finishCalls?: readonly CommerceConformanceFinishCall[];
|
|
399
|
+
}
|
|
400
|
+
/** How an adaptive vector's expectations were derived for the provider under test. */
|
|
401
|
+
export interface CommerceConformanceAdaptation {
|
|
402
|
+
/** The provider's store id; it replaces the fixture store id in derived keys and verify requests. */
|
|
403
|
+
readonly store: StoreId;
|
|
404
|
+
readonly finish: CommerceFinishOwner;
|
|
405
|
+
readonly evidence: CommerceEvidenceAuthority;
|
|
406
|
+
/** The expectation the vector was matched against. */
|
|
407
|
+
readonly expect: CommerceConformanceResolvedExpectation;
|
|
408
|
+
}
|
|
367
409
|
export interface CommerceConformanceVectorResult {
|
|
368
410
|
readonly vector: string;
|
|
411
|
+
/** `skipped` vectors did not run; `passed` is false and `reason` says why. */
|
|
412
|
+
readonly status: CommerceConformanceVectorStatus;
|
|
369
413
|
readonly passed: boolean;
|
|
370
414
|
readonly failures: readonly CommerceConformanceFailure[];
|
|
415
|
+
readonly reason?: string;
|
|
416
|
+
/** Present when the vector ran with adaptive expectations. */
|
|
417
|
+
readonly adaptive?: CommerceConformanceAdaptation;
|
|
371
418
|
}
|
|
372
419
|
export declare function createCommerceConformanceHarness(context: CommerceConformanceContext): CommerceConformanceHarness;
|
|
373
420
|
/**
|
|
@@ -375,9 +422,94 @@ export declare function createCommerceConformanceHarness(context: CommerceConfor
|
|
|
375
422
|
* each, then matches `expect`. Matching compares only the listed fields; arrays
|
|
376
423
|
* compare in order and by length; a listed `journal` is the whole journal.
|
|
377
424
|
* Any unscripted operation fails the vector at the step that needed it.
|
|
425
|
+
*
|
|
426
|
+
* With `options.createProvider`, a vector flagged `profile.adaptive` is first
|
|
427
|
+
* checked against the provider's declared capabilities
|
|
428
|
+
* (`commerceConformanceAdaptiveSkipReason`) and then matched against
|
|
429
|
+
* expectations derived from a reference run under those capabilities
|
|
430
|
+
* (`deriveAdaptiveCommerceConformanceExpectation`). Duplicate detection needs
|
|
431
|
+
* the whole run set, so it applies through `runCommerceConformanceVectors`.
|
|
378
432
|
*/
|
|
379
433
|
export declare function runCommerceConformanceVector(vector: CommerceConformanceVector, options?: CommerceConformanceRunOptions): Promise<CommerceConformanceVectorResult>;
|
|
380
434
|
export declare function runCommerceConformanceVectors(vectors: readonly CommerceConformanceVector[], options?: CommerceConformanceRunOptions): Promise<readonly CommerceConformanceVectorResult[]>;
|
|
435
|
+
export declare function isAdaptiveCommerceConformanceVector(vector: CommerceConformanceVector): boolean;
|
|
436
|
+
/**
|
|
437
|
+
* Why an adaptive vector does not apply to a provider with `capabilities`, or
|
|
438
|
+
* `undefined` when it runs. `set` is the whole run (for duplicate detection).
|
|
439
|
+
* The rules:
|
|
440
|
+
*
|
|
441
|
+
* - a `game.requestPurchase` of a product kind the provider does not sell
|
|
442
|
+
* (`purchase.<kind>` false, by the vector catalog), or with a quantity above
|
|
443
|
+
* one without `purchase.quantity`, cannot open the store UI;
|
|
444
|
+
* - a store-side `pending` purchase needs `lifecycle.pending`;
|
|
445
|
+
* - a store `error` event needs `lifecycle.events`;
|
|
446
|
+
* - without `lifecycle.events`, a store `complete` or `update` reaches the
|
|
447
|
+
* reconciler only by polling, so the next `runtime` step after it must be
|
|
448
|
+
* `reconcile` or `start`;
|
|
449
|
+
* - a `queueFinish` script needs a `client` or `host` finish owner, since the
|
|
450
|
+
* provider never calls `finishTransaction` under `server` or `none`;
|
|
451
|
+
* - within the `purchase-<owner>-finish` family only one member runs: the
|
|
452
|
+
* one named after the provider's owner, else the first by name.
|
|
453
|
+
*/
|
|
454
|
+
export declare function commerceConformanceAdaptiveSkipReason(vector: CommerceConformanceVector, capabilities: CommerceCapabilities, set?: readonly CommerceConformanceVector[]): string | undefined;
|
|
455
|
+
/**
|
|
456
|
+
* The vector with every scripted store purchase (`complete`, `update`, and a
|
|
457
|
+
* `queueRequest` answering `purchased`) carrying the token the store actor
|
|
458
|
+
* reports for it (`CommerceConformanceStoreActor.tokenOf`).
|
|
459
|
+
*/
|
|
460
|
+
export declare function withStoreTokens(vector: CommerceConformanceVector, tokenOf: (purchase: CommerceConformancePurchaseFixture) => string): CommerceConformanceVector;
|
|
461
|
+
/**
|
|
462
|
+
* Derives the adaptive expectation for `vector` from the observable state of a
|
|
463
|
+
* finished reference run under the provider's capabilities, applying the
|
|
464
|
+
* rules the RFC table states:
|
|
465
|
+
*
|
|
466
|
+
* - `journal`: the reference journal, so the tail after `granted` is
|
|
467
|
+
* `finishing, finished` for `client`, `host`, and `server` owners and
|
|
468
|
+
* `finished` for `none`; derived keys carry the provider's store id;
|
|
469
|
+
* - `finishCalls`: the reference store's calls, `by` the owner for `client`
|
|
470
|
+
* and `host`, none for `server` and `none`;
|
|
471
|
+
* - `verifyRequests`: the reference backend's log, with the finalization
|
|
472
|
+
* re-read a `server` owner adds unless the grant already reported
|
|
473
|
+
* `finalization: 'completed'`;
|
|
474
|
+
* - `available`: what the reference store still lists once idle, so empty
|
|
475
|
+
* after a completed finish for `client`, `host`, and `server` owners.
|
|
476
|
+
*
|
|
477
|
+
* Fields the fixture does not assert stay unasserted. The derivation is
|
|
478
|
+
* refused (a skip reason) when the reference run does not end every journal
|
|
479
|
+
* key in the fixture's terminal state, since the scenario then depends on a
|
|
480
|
+
* capability the provider lacks.
|
|
481
|
+
*/
|
|
482
|
+
export declare function deriveAdaptiveCommerceConformanceExpectation(vector: CommerceConformanceVector, reference: {
|
|
483
|
+
readonly store: StoreId;
|
|
484
|
+
readonly journal: Readonly<Record<string, readonly CommercePurchaseState[]>>;
|
|
485
|
+
readonly verifyRequests: readonly CommerceVerifyRequest[];
|
|
486
|
+
readonly finishCalls: readonly CommerceConformanceFinishCall[];
|
|
487
|
+
/** What the reference store still lists (pending included) once the run is idle. */
|
|
488
|
+
readonly available: readonly StorePurchase[];
|
|
489
|
+
}): Promise<{
|
|
490
|
+
readonly expect: CommerceConformanceResolvedExpectation;
|
|
491
|
+
readonly reason?: undefined;
|
|
492
|
+
} | {
|
|
493
|
+
readonly expect?: undefined;
|
|
494
|
+
readonly reason: string;
|
|
495
|
+
}>;
|
|
496
|
+
/**
|
|
497
|
+
* A fixture journal key as the provider's store id derives it: only the
|
|
498
|
+
* encoded store segment of a `store:<store>:<transactionId>` key
|
|
499
|
+
* (`createDerivedPurchaseIdempotencyKey`) is replaced, so a transaction id
|
|
500
|
+
* that happens to contain the fixture store id is left alone. Game-chosen
|
|
501
|
+
* keys and store-specific key forms carry no such prefix and pass through.
|
|
502
|
+
*/
|
|
503
|
+
export declare function adaptDerivedPurchaseKeyStore(key: string, fixtureStore: string, providerStore: string): string;
|
|
504
|
+
/**
|
|
505
|
+
* A fixture journal key as the provider's store id derives it. When the key is
|
|
506
|
+
* the derived key of a purchase the vector scripts under the fixture store, it
|
|
507
|
+
* is re-derived with `createDerivedPurchaseIdempotencyKey` for the provider
|
|
508
|
+
* store, which also covers the store-specific key forms (`google-play` token
|
|
509
|
+
* keys, `apps-in-toss:purchase:<id>`); otherwise only the generic
|
|
510
|
+
* `store:<store>:` prefix is swapped (`adaptDerivedPurchaseKeyStore`).
|
|
511
|
+
*/
|
|
512
|
+
export declare function adaptDerivedPurchaseKey(vector: CommerceConformanceVector, key: string, providerStore: string): Promise<string>;
|
|
381
513
|
/**
|
|
382
514
|
* Partial match: an expected object asserts only its listed keys, an expected
|
|
383
515
|
* array asserts its length and each element in order, and primitives compare
|