@omen.foundation/node-microservice-runtime 0.1.64 → 0.1.67
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/collector-manager.cjs +17 -1
- package/dist/collector-manager.d.ts +3 -0
- package/dist/collector-manager.d.ts.map +1 -1
- package/dist/collector-manager.js +21 -1
- package/dist/collector-manager.js.map +1 -1
- package/package.json +4 -1
- package/.env +0 -13
- package/env.sample +0 -13
- package/scripts/generate-openapi.mjs +0 -114
- package/scripts/lib/cli-utils.mjs +0 -58
- package/scripts/prepare-cjs.mjs +0 -44
- package/scripts/publish-service.mjs +0 -1119
- package/scripts/validate-service.mjs +0 -103
- package/scripts/ws-test.mjs +0 -25
- package/src/auth.ts +0 -117
- package/src/cli/index.ts +0 -725
- package/src/collector-manager.ts +0 -1240
- package/src/decorators.ts +0 -207
- package/src/dependency.ts +0 -211
- package/src/dev.ts +0 -17
- package/src/discovery.ts +0 -88
- package/src/docs.ts +0 -262
- package/src/env.ts +0 -148
- package/src/errors.ts +0 -55
- package/src/federation.ts +0 -559
- package/src/index.ts +0 -84
- package/src/inventory.ts +0 -491
- package/src/logger.ts +0 -727
- package/src/message.ts +0 -19
- package/src/requester.ts +0 -126
- package/src/routing.ts +0 -42
- package/src/runtime.ts +0 -1071
- package/src/services.ts +0 -459
- package/src/storage.ts +0 -206
- package/src/types/beamable-sdk-api.d.ts +0 -5
- package/src/types.ts +0 -117
- package/src/utils/urls.ts +0 -53
- package/src/websocket.ts +0 -170
- package/test-downloads/collector-test +0 -0
- package/test-downloads/collector-test.gz +0 -0
- package/tsconfig.base.json +0 -31
- package/tsconfig.build.json +0 -10
- package/tsconfig.cjs.json +0 -16
- package/tsconfig.dev.json +0 -14
package/src/inventory.ts
DELETED
|
@@ -1,491 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import type { Logger } from 'pino';
|
|
3
|
-
import type { BoundBeamApi } from './services.js';
|
|
4
|
-
import { MissingScopesError } from './errors.js';
|
|
5
|
-
|
|
6
|
-
export interface CurrencyProperty {
|
|
7
|
-
name: string;
|
|
8
|
-
value: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface ItemProperty {
|
|
12
|
-
name: string;
|
|
13
|
-
value: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface ItemCreateRequest {
|
|
17
|
-
contentId: string;
|
|
18
|
-
properties: ItemProperty[];
|
|
19
|
-
reqId?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface ItemDeleteRequest {
|
|
23
|
-
contentId: string;
|
|
24
|
-
id: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface ItemUpdateRequest {
|
|
28
|
-
contentId: string;
|
|
29
|
-
id: string;
|
|
30
|
-
properties: ItemProperty[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface CurrencyView {
|
|
34
|
-
id: string;
|
|
35
|
-
amount: string | number | bigint;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface InventoryView {
|
|
39
|
-
currencies?: CurrencyView[];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface PreviewVipBonusResponse {
|
|
43
|
-
currencies: Array<{ id: string; amount: string | number | bigint; originalAmount?: string | number | bigint }>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface MultipliersGetResponse {
|
|
47
|
-
[key: string]: unknown;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface TransferRequestPayload {
|
|
51
|
-
recipientPlayer: string;
|
|
52
|
-
currencies?: Record<string, string>;
|
|
53
|
-
transaction?: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface InventoryUpdatePayload {
|
|
57
|
-
transaction?: string;
|
|
58
|
-
applyVipBonus?: boolean;
|
|
59
|
-
currencies?: Record<string, string>;
|
|
60
|
-
currencyProperties?: Record<string, CurrencyProperty[]>;
|
|
61
|
-
newItems?: Array<ItemCreateRequest>;
|
|
62
|
-
deleteItems?: Array<ItemDeleteRequest>;
|
|
63
|
-
updateItems?: Array<ItemUpdateRequest>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface InventoryCurrencyChanges {
|
|
67
|
-
[currencyId: string]: bigint;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface InventoryBuilderOptions {
|
|
71
|
-
transaction?: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export class InventoryUpdateBuilder {
|
|
75
|
-
private readonly currencyChanges: Map<string, bigint> = new Map();
|
|
76
|
-
private readonly currencyPropertyUpdates: Map<string, CurrencyProperty[]> = new Map();
|
|
77
|
-
private readonly newItemRequests: Array<ItemCreateRequest & { reqId: string }> = [];
|
|
78
|
-
private readonly deleteItemRequests: ItemDeleteRequest[] = [];
|
|
79
|
-
private readonly updateItemRequests: ItemUpdateRequest[] = [];
|
|
80
|
-
private applyVipBonusFlag?: boolean;
|
|
81
|
-
|
|
82
|
-
applyVipBonus(apply: boolean): this {
|
|
83
|
-
this.applyVipBonusFlag = apply;
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
currencyChange(currencyId: string, delta: bigint | number): this {
|
|
88
|
-
const normalizedId = this.normalizeId(currencyId, 'currency');
|
|
89
|
-
const current = this.currencyChanges.get(normalizedId) ?? BigInt(0);
|
|
90
|
-
const next = current + BigInt(delta);
|
|
91
|
-
if (next === BigInt(0)) {
|
|
92
|
-
this.currencyChanges.delete(normalizedId);
|
|
93
|
-
} else {
|
|
94
|
-
this.currencyChanges.set(normalizedId, next);
|
|
95
|
-
}
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
setCurrencyProperties(currencyId: string, properties: CurrencyProperty[]): this {
|
|
100
|
-
const normalizedId = this.normalizeId(currencyId, 'currency');
|
|
101
|
-
this.currencyPropertyUpdates.set(normalizedId, [...properties]);
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
addItem(contentId: string, properties: Record<string, string> = {}, requestId: string = randomUUID()): this {
|
|
106
|
-
const normalizedId = this.normalizeId(contentId, 'item');
|
|
107
|
-
const itemProperties = Object.entries(properties).map<ItemProperty>(([name, value]) => ({
|
|
108
|
-
name,
|
|
109
|
-
value,
|
|
110
|
-
}));
|
|
111
|
-
this.newItemRequests.push({
|
|
112
|
-
contentId: normalizedId,
|
|
113
|
-
properties: itemProperties,
|
|
114
|
-
reqId: requestId,
|
|
115
|
-
});
|
|
116
|
-
return this;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
deleteItem(contentId: string, itemId: bigint | number | string): this {
|
|
120
|
-
const normalizedId = this.normalizeId(contentId, 'item');
|
|
121
|
-
this.deleteItemRequests.push({
|
|
122
|
-
contentId: normalizedId,
|
|
123
|
-
id: this.toIdentifier(itemId),
|
|
124
|
-
});
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
updateItem(contentId: string, itemId: bigint | number | string, properties: Record<string, string>): this {
|
|
129
|
-
const normalizedId = this.normalizeId(contentId, 'item');
|
|
130
|
-
const normalizedProperties = Object.entries(properties).map<ItemProperty>(([name, value]) => ({
|
|
131
|
-
name,
|
|
132
|
-
value,
|
|
133
|
-
}));
|
|
134
|
-
this.updateItemRequests.push({
|
|
135
|
-
contentId: normalizedId,
|
|
136
|
-
id: this.toIdentifier(itemId),
|
|
137
|
-
properties: normalizedProperties,
|
|
138
|
-
});
|
|
139
|
-
return this;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
merge(other: InventoryUpdateBuilder): this {
|
|
143
|
-
for (const [currencyId, delta] of other.currencyChanges.entries()) {
|
|
144
|
-
this.currencyChange(currencyId, delta);
|
|
145
|
-
}
|
|
146
|
-
for (const [currencyId, props] of other.currencyPropertyUpdates.entries()) {
|
|
147
|
-
this.currencyPropertyUpdates.set(currencyId, [...props]);
|
|
148
|
-
}
|
|
149
|
-
for (const item of other.newItemRequests) {
|
|
150
|
-
this.newItemRequests.push({ ...item });
|
|
151
|
-
}
|
|
152
|
-
for (const item of other.deleteItemRequests) {
|
|
153
|
-
this.deleteItemRequests.push({ ...item });
|
|
154
|
-
}
|
|
155
|
-
for (const item of other.updateItemRequests) {
|
|
156
|
-
this.updateItemRequests.push({
|
|
157
|
-
contentId: item.contentId,
|
|
158
|
-
id: this.toIdentifier(item.id),
|
|
159
|
-
properties: [...item.properties],
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
if (other.applyVipBonusFlag !== undefined) {
|
|
163
|
-
this.applyVipBonusFlag = other.applyVipBonusFlag;
|
|
164
|
-
}
|
|
165
|
-
return this;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
isEmpty(): boolean {
|
|
169
|
-
return (
|
|
170
|
-
this.currencyChanges.size === 0 &&
|
|
171
|
-
this.currencyPropertyUpdates.size === 0 &&
|
|
172
|
-
this.newItemRequests.length === 0 &&
|
|
173
|
-
this.deleteItemRequests.length === 0 &&
|
|
174
|
-
this.updateItemRequests.length === 0 &&
|
|
175
|
-
this.applyVipBonusFlag === undefined
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
toRequest(options: InventoryBuilderOptions = {}): InventoryUpdatePayload {
|
|
180
|
-
const payload: InventoryUpdatePayload = {};
|
|
181
|
-
|
|
182
|
-
if (options.transaction) {
|
|
183
|
-
payload.transaction = options.transaction;
|
|
184
|
-
}
|
|
185
|
-
if (this.applyVipBonusFlag !== undefined) {
|
|
186
|
-
payload.applyVipBonus = this.applyVipBonusFlag;
|
|
187
|
-
}
|
|
188
|
-
if (this.currencyChanges.size > 0) {
|
|
189
|
-
const currencies: Record<string, string> = {};
|
|
190
|
-
for (const [currencyId, delta] of this.currencyChanges.entries()) {
|
|
191
|
-
currencies[currencyId] = delta.toString();
|
|
192
|
-
}
|
|
193
|
-
payload.currencies = currencies;
|
|
194
|
-
}
|
|
195
|
-
if (this.currencyPropertyUpdates.size > 0) {
|
|
196
|
-
const currencyProperties: Record<string, CurrencyProperty[]> = {};
|
|
197
|
-
for (const [currencyId, properties] of this.currencyPropertyUpdates.entries()) {
|
|
198
|
-
currencyProperties[currencyId] = properties.map<CurrencyProperty>((property) => ({ ...property }));
|
|
199
|
-
}
|
|
200
|
-
payload.currencyProperties = currencyProperties;
|
|
201
|
-
}
|
|
202
|
-
if (this.newItemRequests.length > 0) {
|
|
203
|
-
payload.newItems = this.newItemRequests.map((item) => ({
|
|
204
|
-
contentId: item.contentId,
|
|
205
|
-
properties: item.properties.map<ItemProperty>((property) => ({ ...property })),
|
|
206
|
-
reqId: item.reqId,
|
|
207
|
-
}));
|
|
208
|
-
}
|
|
209
|
-
if (this.deleteItemRequests.length > 0) {
|
|
210
|
-
payload.deleteItems = this.deleteItemRequests.map((item) => ({
|
|
211
|
-
contentId: item.contentId,
|
|
212
|
-
id: this.toIdentifier(item.id),
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
if (this.updateItemRequests.length > 0) {
|
|
216
|
-
payload.updateItems = this.updateItemRequests.map((item) => ({
|
|
217
|
-
contentId: item.contentId,
|
|
218
|
-
id: this.toIdentifier(item.id),
|
|
219
|
-
properties: item.properties.map<ItemProperty>((property) => ({ ...property })),
|
|
220
|
-
}));
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return payload;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private normalizeId(value: string, kind: 'currency' | 'item'): string {
|
|
227
|
-
const trimmed = value.trim();
|
|
228
|
-
if (!trimmed) {
|
|
229
|
-
throw new Error(`Invalid ${kind} identifier: "${value}"`);
|
|
230
|
-
}
|
|
231
|
-
return trimmed;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
private toIdentifier(value: bigint | number | string): string {
|
|
235
|
-
if (typeof value === 'bigint') {
|
|
236
|
-
return value.toString();
|
|
237
|
-
}
|
|
238
|
-
if (typeof value === 'number') {
|
|
239
|
-
if (!Number.isFinite(value)) {
|
|
240
|
-
throw new Error(`Invalid numeric identifier: ${value}`);
|
|
241
|
-
}
|
|
242
|
-
return Math.trunc(value).toString();
|
|
243
|
-
}
|
|
244
|
-
const trimmed = value.trim();
|
|
245
|
-
if (!trimmed) {
|
|
246
|
-
throw new Error('Identifier cannot be empty.');
|
|
247
|
-
}
|
|
248
|
-
return trimmed;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
interface InventoryServiceDependencies {
|
|
253
|
-
api: BoundBeamApi;
|
|
254
|
-
logger: Logger;
|
|
255
|
-
userId: string;
|
|
256
|
-
scopeChecker: (scopes: string[]) => void;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export class InventoryService {
|
|
260
|
-
private readonly api: BoundBeamApi;
|
|
261
|
-
private readonly logger: Logger;
|
|
262
|
-
private readonly userId: string;
|
|
263
|
-
private readonly ensureScopes: (scopes: string[]) => void;
|
|
264
|
-
|
|
265
|
-
constructor(dependencies: InventoryServiceDependencies) {
|
|
266
|
-
this.api = dependencies.api;
|
|
267
|
-
this.logger = dependencies.logger.child({ component: 'InventoryService' });
|
|
268
|
-
this.userId = dependencies.userId;
|
|
269
|
-
this.ensureScopes = dependencies.scopeChecker;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
createBuilder(): InventoryUpdateBuilder {
|
|
273
|
-
return new InventoryUpdateBuilder();
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
async update(
|
|
277
|
-
builderOrCallback: InventoryUpdateBuilder | ((builder: InventoryUpdateBuilder) => void | Promise<void>),
|
|
278
|
-
options: InventoryBuilderOptions = {},
|
|
279
|
-
): Promise<void> {
|
|
280
|
-
const builder = builderOrCallback instanceof InventoryUpdateBuilder ? builderOrCallback : this.createBuilder();
|
|
281
|
-
if (!(builderOrCallback instanceof InventoryUpdateBuilder)) {
|
|
282
|
-
await builderOrCallback(builder);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (builder.isEmpty()) {
|
|
286
|
-
this.logger.debug('Inventory update skipped because builder produced no changes.');
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
this.ensureScopes(['server']);
|
|
291
|
-
const payload = builder.toRequest(options);
|
|
292
|
-
await this.invokeInventoryPut(payload);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
async setCurrencies(currencyValues: Record<string, bigint | number>, transaction?: string): Promise<void> {
|
|
296
|
-
this.ensureScopes(['server']);
|
|
297
|
-
const current = await this.getCurrencies(Object.keys(currencyValues));
|
|
298
|
-
const deltas: Record<string, bigint> = {};
|
|
299
|
-
for (const [currencyId, target] of Object.entries(currencyValues)) {
|
|
300
|
-
const currentVal = current[currencyId] ?? BigInt(0);
|
|
301
|
-
const targetValue = BigInt(target);
|
|
302
|
-
const delta = targetValue - currentVal;
|
|
303
|
-
if (delta !== BigInt(0)) {
|
|
304
|
-
deltas[currencyId] = delta;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (Object.keys(deltas).length === 0) {
|
|
309
|
-
this.logger.debug('No currency adjustments required; request skipped.');
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
await this.update((builder) => {
|
|
314
|
-
for (const [currencyId, delta] of Object.entries(deltas)) {
|
|
315
|
-
builder.currencyChange(currencyId, delta);
|
|
316
|
-
}
|
|
317
|
-
}, { transaction });
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async addCurrencies(currencyDeltas: Record<string, bigint | number>, transaction?: string): Promise<void> {
|
|
321
|
-
await this.update((builder) => {
|
|
322
|
-
for (const [currencyId, delta] of Object.entries(currencyDeltas)) {
|
|
323
|
-
builder.currencyChange(currencyId, delta);
|
|
324
|
-
}
|
|
325
|
-
}, { transaction });
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
async addItem(contentId: string, properties: Record<string, string> = {}, transaction?: string): Promise<void> {
|
|
329
|
-
await this.update((builder) => {
|
|
330
|
-
builder.addItem(contentId, properties);
|
|
331
|
-
}, { transaction });
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
async deleteItem(contentId: string, itemId: bigint | number | string, transaction?: string): Promise<void> {
|
|
335
|
-
await this.update((builder) => {
|
|
336
|
-
builder.deleteItem(contentId, itemId);
|
|
337
|
-
}, { transaction });
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
async updateItem(
|
|
341
|
-
contentId: string,
|
|
342
|
-
itemId: bigint | number | string,
|
|
343
|
-
properties: Record<string, string>,
|
|
344
|
-
transaction?: string,
|
|
345
|
-
): Promise<void> {
|
|
346
|
-
await this.update((builder) => {
|
|
347
|
-
builder.updateItem(contentId, itemId, properties);
|
|
348
|
-
}, { transaction });
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
async setCurrencyProperties(
|
|
352
|
-
currencyId: string,
|
|
353
|
-
properties: CurrencyProperty[],
|
|
354
|
-
transaction?: string,
|
|
355
|
-
): Promise<void> {
|
|
356
|
-
await this.update((builder) => {
|
|
357
|
-
builder.setCurrencyProperties(currencyId, properties);
|
|
358
|
-
}, { transaction });
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
async previewCurrencyGain(currencyChanges: Record<string, bigint | number>): Promise<PreviewVipBonusResponse> {
|
|
362
|
-
this.ensureScopes(['server']);
|
|
363
|
-
const payload: InventoryUpdatePayload = {
|
|
364
|
-
currencies: Object.fromEntries(
|
|
365
|
-
Object.entries(currencyChanges).map(([currencyId, amount]) => [currencyId, BigInt(amount).toString()]),
|
|
366
|
-
),
|
|
367
|
-
};
|
|
368
|
-
const response = await this.invokePreview(payload);
|
|
369
|
-
return response;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
async getMultipliers(): Promise<MultipliersGetResponse> {
|
|
373
|
-
this.ensureScopes(['server']);
|
|
374
|
-
const response = await this.invokeGetMultipliers();
|
|
375
|
-
return response;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
async getInventory(scope?: string): Promise<InventoryView> {
|
|
379
|
-
this.ensureScopes(['server']);
|
|
380
|
-
const response = await this.invokeGetInventory(scope);
|
|
381
|
-
return response;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
async getCurrencies(currencyIds?: string[]): Promise<Record<string, bigint>> {
|
|
385
|
-
const scope = Array.isArray(currencyIds) && currencyIds.length > 0 ? currencyIds.join(',') : 'currency';
|
|
386
|
-
const view = await this.getInventory(scope);
|
|
387
|
-
const result: Record<string, bigint> = {};
|
|
388
|
-
for (const currency of view.currencies ?? []) {
|
|
389
|
-
result[currency.id] = BigInt(currency.amount);
|
|
390
|
-
}
|
|
391
|
-
return result;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
async sendCurrency(
|
|
395
|
-
request: Omit<TransferRequestPayload, 'recipientPlayer'> & { recipientPlayer: string | number },
|
|
396
|
-
): Promise<void> {
|
|
397
|
-
this.ensureScopes(['server']);
|
|
398
|
-
const payload: TransferRequestPayload = {
|
|
399
|
-
recipientPlayer: this.toIdentifier(request.recipientPlayer),
|
|
400
|
-
currencies: Object.fromEntries(
|
|
401
|
-
Object.entries(request.currencies ?? {}).map(([currencyId, amount]) => [currencyId, BigInt(amount).toString()]),
|
|
402
|
-
),
|
|
403
|
-
transaction: request.transaction,
|
|
404
|
-
};
|
|
405
|
-
const response = this.api.inventoryPutTransferByObjectId?.(this.userId, payload);
|
|
406
|
-
if (!response || typeof (response as Promise<unknown>).then !== 'function') {
|
|
407
|
-
throw new Error('inventoryPutTransferByObjectId API is unavailable in the current SDK.');
|
|
408
|
-
}
|
|
409
|
-
await response;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
private async invokeInventoryPut(payload: InventoryUpdatePayload): Promise<void> {
|
|
413
|
-
const response = this.api.inventoryPutByObjectId?.(this.userId, payload);
|
|
414
|
-
if (!response || typeof (response as Promise<unknown>).then !== 'function') {
|
|
415
|
-
throw new Error('inventoryPutByObjectId API is unavailable in the current SDK.');
|
|
416
|
-
}
|
|
417
|
-
await response;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
private async invokePreview(payload: InventoryUpdatePayload): Promise<PreviewVipBonusResponse> {
|
|
421
|
-
const response = this.api.inventoryPutPreviewByObjectId?.(this.userId, payload);
|
|
422
|
-
if (!response || typeof (response as Promise<unknown>).then !== 'function') {
|
|
423
|
-
throw new Error('inventoryPutPreviewByObjectId API is unavailable in the current SDK.');
|
|
424
|
-
}
|
|
425
|
-
const result = await response;
|
|
426
|
-
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
427
|
-
return result as PreviewVipBonusResponse;
|
|
428
|
-
}
|
|
429
|
-
return (result as { body: PreviewVipBonusResponse }).body;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
private async invokeGetMultipliers(): Promise<MultipliersGetResponse> {
|
|
433
|
-
const response = this.api.inventoryGetMultipliersByObjectId?.(this.userId);
|
|
434
|
-
if (!response || typeof (response as Promise<unknown>).then !== 'function') {
|
|
435
|
-
throw new Error('inventoryGetMultipliersByObjectId API is unavailable in the current SDK.');
|
|
436
|
-
}
|
|
437
|
-
const result = await response;
|
|
438
|
-
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
439
|
-
return result as MultipliersGetResponse;
|
|
440
|
-
}
|
|
441
|
-
return (result as { body: MultipliersGetResponse }).body;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
private async invokeGetInventory(scope?: string): Promise<InventoryView> {
|
|
445
|
-
const response = this.api.inventoryGetByObjectId?.(this.userId, scope);
|
|
446
|
-
if (!response || typeof (response as Promise<unknown>).then !== 'function') {
|
|
447
|
-
throw new Error('inventoryGetByObjectId API is unavailable in the current SDK.');
|
|
448
|
-
}
|
|
449
|
-
const result = await response;
|
|
450
|
-
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
451
|
-
return result as InventoryView;
|
|
452
|
-
}
|
|
453
|
-
return (result as { body: InventoryView }).body;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
private toIdentifier(value: string | number | bigint): string {
|
|
457
|
-
if (typeof value === 'string') {
|
|
458
|
-
const trimmed = value.trim();
|
|
459
|
-
if (!trimmed) {
|
|
460
|
-
throw new Error('Identifier cannot be empty.');
|
|
461
|
-
}
|
|
462
|
-
return trimmed;
|
|
463
|
-
}
|
|
464
|
-
if (typeof value === 'number') {
|
|
465
|
-
if (!Number.isFinite(value)) {
|
|
466
|
-
throw new Error(`Invalid numeric identifier: ${value}`);
|
|
467
|
-
}
|
|
468
|
-
return Math.trunc(value).toString();
|
|
469
|
-
}
|
|
470
|
-
return value.toString();
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
export function createInventoryService(
|
|
475
|
-
api: BoundBeamApi,
|
|
476
|
-
logger: Logger,
|
|
477
|
-
userId: string,
|
|
478
|
-
hasScopes: (scopes: string[]) => boolean,
|
|
479
|
-
): InventoryService {
|
|
480
|
-
return new InventoryService({
|
|
481
|
-
api,
|
|
482
|
-
logger,
|
|
483
|
-
userId,
|
|
484
|
-
scopeChecker: (requiredScopes: string[]) => {
|
|
485
|
-
if (!hasScopes(requiredScopes)) {
|
|
486
|
-
throw new MissingScopesError(requiredScopes);
|
|
487
|
-
}
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
|