@mpgd/platform 0.20.0 → 0.21.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 +26 -51
- package/dist/commerce-conformance.js +65 -461
- package/dist/commerce-wallet.d.ts +324 -0
- package/dist/commerce-wallet.js +2087 -0
- package/dist/commerce.d.ts +28 -2
- package/dist/commerce.js +32 -7
- package/package.json +6 -2
package/dist/commerce.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type tags } from 'typia';
|
|
2
2
|
import { PlatformOperationError, type CommerceAdapter, type CommerceCapabilities } from './index.js';
|
|
3
|
-
import type { ActiveSubscription, CommerceErrorCode, CommerceErrorInfo, CommerceEvent, CommerceLogicalProductId, CommerceProvider, FetchProductsInput, FinishTransactionInput, FinishTransactionResult, GetAvailablePurchasesInput, IsoTimestamp, NonEmptyString, NonNegativeInteger, PurchaseKind, RequestPurchaseInput, RequestPurchaseResult, StoreId, StoreProduct, StorePurchase } from './commerce-contract.js';
|
|
3
|
+
import type { ActiveSubscription, CommerceErrorCode, CommerceErrorInfo, CommerceEvent, CommerceLogicalProductId, CommerceProvider, FetchProductsInput, FinishTransactionInput, FinishTransactionResult, GetAvailablePurchasesInput, IsoTimestamp, NonEmptyString, NonNegativeInteger, PositiveQuantity, PurchaseKind, RequestPurchaseInput, RequestPurchaseResult, StoreId, StoreProduct, StorePurchase } from './commerce-contract.js';
|
|
4
4
|
export { createUnsupportedCommerceCapabilities, deriveLegacyCommerceCapabilities, type LegacyCommerceCapabilities, } from './commerce-capabilities.js';
|
|
5
5
|
export type { CommerceAccountBindingPolicy, CommerceAuthorityCapabilities, CommerceCapabilities, CommerceCatalogCapabilities, CommerceEvidenceAuthority, CommerceFinishOwner, CommerceLifecycleCapabilities, CommercePurchaseCapabilities, } from './index.js';
|
|
6
6
|
/**
|
|
@@ -46,6 +46,12 @@ export interface CreditSpendInput {
|
|
|
46
46
|
readonly currency: NonEmptyString;
|
|
47
47
|
readonly amount: number & tags.ExclusiveMinimum<0>;
|
|
48
48
|
readonly idempotencyKey: NonEmptyString;
|
|
49
|
+
/**
|
|
50
|
+
* The offer being bought; the wallet prices the spend against it and issues
|
|
51
|
+
* an entitlement. Without it the spend is a plain debit of `amount` with no
|
|
52
|
+
* entitlement, an owner-side form the conformance vectors use; a wallet
|
|
53
|
+
* service should require it from game clients.
|
|
54
|
+
*/
|
|
49
55
|
readonly logicalId?: CommerceLogicalProductId;
|
|
50
56
|
}
|
|
51
57
|
export interface CreditDebit {
|
|
@@ -56,6 +62,8 @@ export type CreditSpendResult = {
|
|
|
56
62
|
readonly status: 'debited';
|
|
57
63
|
readonly entitlementId: NonEmptyString;
|
|
58
64
|
readonly debits: readonly CreditDebit[];
|
|
65
|
+
/** When the wallet settled the spend; a replay repeats the original time. */
|
|
66
|
+
readonly createdAt?: IsoTimestamp;
|
|
59
67
|
/** A repeated idempotency key returns the original debits. */
|
|
60
68
|
readonly alreadyProcessed?: boolean;
|
|
61
69
|
} | {
|
|
@@ -69,6 +77,8 @@ export interface CreditEntitlement {
|
|
|
69
77
|
readonly idempotencyKey: NonEmptyString;
|
|
70
78
|
readonly createdAt: IsoTimestamp;
|
|
71
79
|
readonly debits: readonly CreditDebit[];
|
|
80
|
+
/** Units bought at spend time; the provider reports it rather than deriving one from today's price. */
|
|
81
|
+
readonly quantity?: PositiveQuantity;
|
|
72
82
|
}
|
|
73
83
|
export interface CreditBalance {
|
|
74
84
|
readonly titleId: NonEmptyString;
|
|
@@ -99,6 +109,13 @@ export interface CreditLot {
|
|
|
99
109
|
/** Derived from the origin, never supplied by the caller. */
|
|
100
110
|
readonly spendScope: CreditLotSpendScope;
|
|
101
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* The client a consuming project implements against its wallet service.
|
|
114
|
+
* `createCreditCommerceProvider` (`@mpgd/platform/commerce-wallet`) turns it
|
|
115
|
+
* into a `CommerceProvider`. A `spend` of a membership offer starts the
|
|
116
|
+
* membership under the spend's idempotency key as its subscription id; the
|
|
117
|
+
* wallet service alone renews, lapses, and expires it.
|
|
118
|
+
*/
|
|
102
119
|
export interface CreditWalletClient {
|
|
103
120
|
readonly store: StoreId;
|
|
104
121
|
listOffers(input: {
|
|
@@ -108,6 +125,7 @@ export interface CreditWalletClient {
|
|
|
108
125
|
listUnredeemed(input: {
|
|
109
126
|
readonly titleId: string;
|
|
110
127
|
}): Promise<readonly CreditEntitlement[]>;
|
|
128
|
+
/** Redeems an entitlement for the ledger entry that granted it; the wallet service verifies the pair. */
|
|
111
129
|
redeem(input: {
|
|
112
130
|
readonly entitlementId: string;
|
|
113
131
|
readonly ledgerEntryId: string;
|
|
@@ -117,7 +135,15 @@ export interface CreditWalletClient {
|
|
|
117
135
|
getBalance(input: {
|
|
118
136
|
readonly titleId: string;
|
|
119
137
|
}): Promise<CreditBalance>;
|
|
120
|
-
|
|
138
|
+
/** Memberships the wallet service reports as active for the title; absent when the wallet sells none. */
|
|
139
|
+
getActiveSubscriptions?(input: {
|
|
140
|
+
readonly titleId: string;
|
|
141
|
+
}): Promise<readonly ActiveSubscription[]>;
|
|
142
|
+
/** With `input.titleId`, only events that concern that title (platform memberships concern every title). */
|
|
143
|
+
subscribe?(listener: (event: CommerceEvent) => void, input?: CreditWalletSubscribeInput): () => void;
|
|
144
|
+
}
|
|
145
|
+
export interface CreditWalletSubscribeInput {
|
|
146
|
+
readonly titleId?: string;
|
|
121
147
|
}
|
|
122
148
|
export interface CommerceBridgeGetCapabilitiesPayload {
|
|
123
149
|
readonly protocol: typeof commerceProtocol;
|
package/dist/commerce.js
CHANGED
|
@@ -3650,7 +3650,7 @@ export const assertCreditSpendInput = (() => {
|
|
|
3650
3650
|
})();
|
|
3651
3651
|
export const assertCreditSpendResult = (() => {
|
|
3652
3652
|
const _iv0 = new Set(["ACCOUNT_BINDING_REQUIRED", "ACTION_REQUIRED", "ALREADY_OWNED", "CONFIGURATION_REQUIRED", "INSUFFICIENT_BALANCE", "INVALID_RESPONSE", "IN_PROGRESS", "ITEM_UNAVAILABLE", "NETWORK", "NOT_PREPARED", "OUTCOME_UNKNOWN", "STORE_UNAVAILABLE", "UNKNOWN", "USER_CANCELLED"]);
|
|
3653
|
-
const _ae0 = "({ readonly status: \"debited\"; readonly entitlementId: NonEmptyString; readonly debits: readonly CreditDebit[]; readonly alreadyProcessed?: boolean; } | { readonly status: \"rejected\"; readonly error: CommerceErrorInfo; })";
|
|
3653
|
+
const _ae0 = "({ readonly status: \"debited\"; readonly entitlementId: NonEmptyString; readonly debits: readonly CreditDebit[]; readonly createdAt?: IsoTimestamp; readonly alreadyProcessed?: boolean; } | { readonly status: \"rejected\"; readonly error: CommerceErrorInfo; })";
|
|
3654
3654
|
const _av0 = new Set(["ACCOUNT_BINDING_REQUIRED", "ACTION_REQUIRED", "ALREADY_OWNED", "CONFIGURATION_REQUIRED", "INSUFFICIENT_BALANCE", "INVALID_RESPONSE", "IN_PROGRESS", "ITEM_UNAVAILABLE", "NETWORK", "NOT_PREPARED", "OUTCOME_UNKNOWN", "STORE_UNAVAILABLE", "UNKNOWN", "USER_CANCELLED"]);
|
|
3655
3655
|
const _ae1 = "(\"ACCOUNT_BINDING_REQUIRED\" | \"ACTION_REQUIRED\" | \"ALREADY_OWNED\" | \"CONFIGURATION_REQUIRED\" | \"INSUFFICIENT_BALANCE\" | \"INVALID_RESPONSE\" | \"IN_PROGRESS\" | \"ITEM_UNAVAILABLE\" | \"NETWORK\" | \"NOT_PREPARED\" | \"OUTCOME_UNKNOWN\" | \"STORE_UNAVAILABLE\" | \"UNKNOWN\" | \"USER_CANCELLED\")";
|
|
3656
3656
|
const _ao0 = (input, _path, _exceptionable = true) => ("debited" === input.status || _assertGuard_1._assertGuard(_exceptionable, {
|
|
@@ -3688,13 +3688,23 @@ export const assertCreditSpendResult = (() => {
|
|
|
3688
3688
|
path: _path + ".debits",
|
|
3689
3689
|
expected: "ReadonlyArray<CreditDebit>",
|
|
3690
3690
|
value: input.debits
|
|
3691
|
+
}, _errorFactory)) && (undefined === input.createdAt || "string" === typeof input.createdAt && (_isFormatDateTime_1._isFormatDateTime(input.createdAt) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3692
|
+
method: "typia.createAssertEquals",
|
|
3693
|
+
path: _path + ".createdAt",
|
|
3694
|
+
expected: "string & CommerceDateTimeFormat",
|
|
3695
|
+
value: input.createdAt
|
|
3696
|
+
}, _errorFactory)) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3697
|
+
method: "typia.createAssertEquals",
|
|
3698
|
+
path: _path + ".createdAt",
|
|
3699
|
+
expected: "((string & CommerceDateTimeFormat) | undefined)",
|
|
3700
|
+
value: input.createdAt
|
|
3691
3701
|
}, _errorFactory)) && (undefined === input.alreadyProcessed || "boolean" === typeof input.alreadyProcessed || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3692
3702
|
method: "typia.createAssertEquals",
|
|
3693
3703
|
path: _path + ".alreadyProcessed",
|
|
3694
3704
|
expected: "(boolean | undefined)",
|
|
3695
3705
|
value: input.alreadyProcessed
|
|
3696
3706
|
}, _errorFactory)) && (3 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
|
|
3697
|
-
if (["status", "entitlementId", "debits", "alreadyProcessed"].some(prop => key === prop))
|
|
3707
|
+
if (["status", "entitlementId", "debits", "createdAt", "alreadyProcessed"].some(prop => key === prop))
|
|
3698
3708
|
return true;
|
|
3699
3709
|
const value = input[key];
|
|
3700
3710
|
if (undefined === value)
|
|
@@ -3813,8 +3823,8 @@ export const assertCreditSpendResult = (() => {
|
|
|
3813
3823
|
value: input
|
|
3814
3824
|
}, _errorFactory);
|
|
3815
3825
|
})();
|
|
3816
|
-
const _io0 = (input, _exceptionable = true) => "debited" === input.status && ("string" === typeof input.entitlementId && 1 <= input.entitlementId.length) && (Array.isArray(input.debits) && input.debits.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable))) && (undefined === input.alreadyProcessed || "boolean" === typeof input.alreadyProcessed) && (3 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
3817
|
-
if (["status", "entitlementId", "debits", "alreadyProcessed"].some(prop => key === prop))
|
|
3826
|
+
const _io0 = (input, _exceptionable = true) => "debited" === input.status && ("string" === typeof input.entitlementId && 1 <= input.entitlementId.length) && (Array.isArray(input.debits) && input.debits.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable))) && (undefined === input.createdAt || "string" === typeof input.createdAt && _isFormatDateTime_1._isFormatDateTime(input.createdAt)) && (undefined === input.alreadyProcessed || "boolean" === typeof input.alreadyProcessed) && (3 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
3827
|
+
if (["status", "entitlementId", "debits", "createdAt", "alreadyProcessed"].some(prop => key === prop))
|
|
3818
3828
|
return true;
|
|
3819
3829
|
const value = input[key];
|
|
3820
3830
|
if (undefined === value)
|
|
@@ -3944,8 +3954,23 @@ export const assertCreditEntitlement = (() => {
|
|
|
3944
3954
|
path: _path + ".debits",
|
|
3945
3955
|
expected: "ReadonlyArray<CreditDebit>",
|
|
3946
3956
|
value: input.debits
|
|
3957
|
+
}, _errorFactory)) && (undefined === input.quantity || "number" === typeof input.quantity && (_isTypeUint32_1._isTypeUint32(input.quantity) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3958
|
+
method: "typia.createAssertEquals",
|
|
3959
|
+
path: _path + ".quantity",
|
|
3960
|
+
expected: "number & CommerceUint32",
|
|
3961
|
+
value: input.quantity
|
|
3962
|
+
}, _errorFactory)) && (1 <= input.quantity || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3963
|
+
method: "typia.createAssertEquals",
|
|
3964
|
+
path: _path + ".quantity",
|
|
3965
|
+
expected: "number & CommerceMinimum<1>",
|
|
3966
|
+
value: input.quantity
|
|
3967
|
+
}, _errorFactory)) || _assertGuard_1._assertGuard(_exceptionable, {
|
|
3968
|
+
method: "typia.createAssertEquals",
|
|
3969
|
+
path: _path + ".quantity",
|
|
3970
|
+
expected: "((number & CommerceUint32 & CommerceMinimum<1>) | undefined)",
|
|
3971
|
+
value: input.quantity
|
|
3947
3972
|
}, _errorFactory)) && (6 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
|
|
3948
|
-
if (["entitlementId", "titleId", "logicalId", "idempotencyKey", "createdAt", "debits"].some(prop => key === prop))
|
|
3973
|
+
if (["entitlementId", "titleId", "logicalId", "idempotencyKey", "createdAt", "debits", "quantity"].some(prop => key === prop))
|
|
3949
3974
|
return true;
|
|
3950
3975
|
const value = input[key];
|
|
3951
3976
|
if (undefined === value)
|
|
@@ -3990,8 +4015,8 @@ export const assertCreditEntitlement = (() => {
|
|
|
3990
4015
|
value: value
|
|
3991
4016
|
}, _errorFactory);
|
|
3992
4017
|
})));
|
|
3993
|
-
const _io0 = (input, _exceptionable = true) => "string" === typeof input.entitlementId && 1 <= input.entitlementId.length && ("string" === typeof input.titleId && 1 <= input.titleId.length) && ("string" === typeof input.logicalId && 1 <= input.logicalId.length) && ("string" === typeof input.idempotencyKey && 1 <= input.idempotencyKey.length) && ("string" === typeof input.createdAt && _isFormatDateTime_1._isFormatDateTime(input.createdAt)) && (Array.isArray(input.debits) && input.debits.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable))) && (6 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
3994
|
-
if (["entitlementId", "titleId", "logicalId", "idempotencyKey", "createdAt", "debits"].some(prop => key === prop))
|
|
4018
|
+
const _io0 = (input, _exceptionable = true) => "string" === typeof input.entitlementId && 1 <= input.entitlementId.length && ("string" === typeof input.titleId && 1 <= input.titleId.length) && ("string" === typeof input.logicalId && 1 <= input.logicalId.length) && ("string" === typeof input.idempotencyKey && 1 <= input.idempotencyKey.length) && ("string" === typeof input.createdAt && _isFormatDateTime_1._isFormatDateTime(input.createdAt)) && (Array.isArray(input.debits) && input.debits.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable))) && (undefined === input.quantity || "number" === typeof input.quantity && (_isTypeUint32_1._isTypeUint32(input.quantity) && 1 <= input.quantity)) && (6 === Object.keys(input).length || Object.keys(input).every(key => {
|
|
4019
|
+
if (["entitlementId", "titleId", "logicalId", "idempotencyKey", "createdAt", "debits", "quantity"].some(prop => key === prop))
|
|
3995
4020
|
return true;
|
|
3996
4021
|
const value = input[key];
|
|
3997
4022
|
if (undefined === value)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/platform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Shared platform gateway, monetization, ads, leaderboard, identity, lifecycle, and storage contracts for mpgd games.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"./commerce-conformance": {
|
|
57
57
|
"types": "./dist/commerce-conformance.d.ts",
|
|
58
58
|
"default": "./dist/commerce-conformance.js"
|
|
59
|
+
},
|
|
60
|
+
"./commerce-wallet": {
|
|
61
|
+
"types": "./dist/commerce-wallet.d.ts",
|
|
62
|
+
"default": "./dist/commerce-wallet.js"
|
|
59
63
|
}
|
|
60
64
|
},
|
|
61
65
|
"files": [
|
|
@@ -80,6 +84,6 @@
|
|
|
80
84
|
"lint": "ttsc --noEmit",
|
|
81
85
|
"format": "ttsc format",
|
|
82
86
|
"fix": "ttsc fix",
|
|
83
|
-
"test": "vitest run && node test/capability-conformance-dist-import.mjs && node test/storage-conformance-dist-import.mjs && node test/ads-dist-import.mjs && node test/commerce-dist-import.mjs && node test/commerce-conformance-dist-import.mjs && cd ../.. && node tools/run-ttsx.mjs packages/platform/test/commerce-derived-key-parity.ts"
|
|
87
|
+
"test": "vitest run && node test/capability-conformance-dist-import.mjs && node test/storage-conformance-dist-import.mjs && node test/ads-dist-import.mjs && node test/commerce-dist-import.mjs && node test/commerce-conformance-dist-import.mjs && node test/wallet-commerce-dist-import.mjs && cd ../.. && node tools/run-ttsx.mjs packages/platform/test/commerce-derived-key-parity.ts"
|
|
84
88
|
}
|
|
85
89
|
}
|