@omen.foundation/node-microservice-runtime 0.1.76 → 0.1.77
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/auth.cjs +97 -0
- package/dist/cli/commands/scaffold.js +17 -1
- package/dist/cli/commands/scaffold.js.map +1 -1
- package/dist/collector-manager.cjs +957 -0
- package/dist/decorators.cjs +181 -0
- package/dist/dependency.cjs +165 -0
- package/dist/dev.cjs +34 -0
- package/dist/discovery.cjs +79 -0
- package/dist/docs.cjs +206 -0
- package/dist/env-loader.cjs +187 -0
- package/dist/env.cjs +125 -0
- package/dist/errors.cjs +58 -0
- package/dist/federation.cjs +356 -0
- package/dist/index.cjs +66 -0
- package/dist/inventory.cjs +361 -0
- package/dist/logger.cjs +545 -0
- package/dist/message.cjs +19 -0
- package/dist/requester.cjs +100 -0
- package/dist/routing.cjs +39 -0
- package/dist/runtime.cjs +841 -0
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +63 -8
- package/dist/runtime.js.map +1 -1
- package/dist/services.cjs +356 -0
- package/dist/storage.cjs +147 -0
- package/dist/types.cjs +2 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/urls.cjs +55 -0
- package/dist/websocket.cjs +142 -0
- package/package.json +1 -1
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InventoryService = exports.InventoryUpdateBuilder = void 0;
|
|
4
|
+
exports.createInventoryService = createInventoryService;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const errors_js_1 = require("./errors.js");
|
|
7
|
+
class InventoryUpdateBuilder {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.currencyChanges = new Map();
|
|
10
|
+
this.currencyPropertyUpdates = new Map();
|
|
11
|
+
this.newItemRequests = [];
|
|
12
|
+
this.deleteItemRequests = [];
|
|
13
|
+
this.updateItemRequests = [];
|
|
14
|
+
}
|
|
15
|
+
applyVipBonus(apply) {
|
|
16
|
+
this.applyVipBonusFlag = apply;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
currencyChange(currencyId, delta) {
|
|
20
|
+
var _a;
|
|
21
|
+
const normalizedId = this.normalizeId(currencyId, 'currency');
|
|
22
|
+
const current = (_a = this.currencyChanges.get(normalizedId)) !== null && _a !== void 0 ? _a : BigInt(0);
|
|
23
|
+
const next = current + BigInt(delta);
|
|
24
|
+
if (next === BigInt(0)) {
|
|
25
|
+
this.currencyChanges.delete(normalizedId);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.currencyChanges.set(normalizedId, next);
|
|
29
|
+
}
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
setCurrencyProperties(currencyId, properties) {
|
|
33
|
+
const normalizedId = this.normalizeId(currencyId, 'currency');
|
|
34
|
+
this.currencyPropertyUpdates.set(normalizedId, [...properties]);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
addItem(contentId, properties = {}, requestId = (0, node_crypto_1.randomUUID)()) {
|
|
38
|
+
const normalizedId = this.normalizeId(contentId, 'item');
|
|
39
|
+
const itemProperties = Object.entries(properties).map(([name, value]) => ({
|
|
40
|
+
name,
|
|
41
|
+
value,
|
|
42
|
+
}));
|
|
43
|
+
this.newItemRequests.push({
|
|
44
|
+
contentId: normalizedId,
|
|
45
|
+
properties: itemProperties,
|
|
46
|
+
reqId: requestId,
|
|
47
|
+
});
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
deleteItem(contentId, itemId) {
|
|
51
|
+
const normalizedId = this.normalizeId(contentId, 'item');
|
|
52
|
+
this.deleteItemRequests.push({
|
|
53
|
+
contentId: normalizedId,
|
|
54
|
+
id: this.toIdentifier(itemId),
|
|
55
|
+
});
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
updateItem(contentId, itemId, properties) {
|
|
59
|
+
const normalizedId = this.normalizeId(contentId, 'item');
|
|
60
|
+
const normalizedProperties = Object.entries(properties).map(([name, value]) => ({
|
|
61
|
+
name,
|
|
62
|
+
value,
|
|
63
|
+
}));
|
|
64
|
+
this.updateItemRequests.push({
|
|
65
|
+
contentId: normalizedId,
|
|
66
|
+
id: this.toIdentifier(itemId),
|
|
67
|
+
properties: normalizedProperties,
|
|
68
|
+
});
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
merge(other) {
|
|
72
|
+
for (const [currencyId, delta] of other.currencyChanges.entries()) {
|
|
73
|
+
this.currencyChange(currencyId, delta);
|
|
74
|
+
}
|
|
75
|
+
for (const [currencyId, props] of other.currencyPropertyUpdates.entries()) {
|
|
76
|
+
this.currencyPropertyUpdates.set(currencyId, [...props]);
|
|
77
|
+
}
|
|
78
|
+
for (const item of other.newItemRequests) {
|
|
79
|
+
this.newItemRequests.push({ ...item });
|
|
80
|
+
}
|
|
81
|
+
for (const item of other.deleteItemRequests) {
|
|
82
|
+
this.deleteItemRequests.push({ ...item });
|
|
83
|
+
}
|
|
84
|
+
for (const item of other.updateItemRequests) {
|
|
85
|
+
this.updateItemRequests.push({
|
|
86
|
+
contentId: item.contentId,
|
|
87
|
+
id: this.toIdentifier(item.id),
|
|
88
|
+
properties: [...item.properties],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (other.applyVipBonusFlag !== undefined) {
|
|
92
|
+
this.applyVipBonusFlag = other.applyVipBonusFlag;
|
|
93
|
+
}
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
isEmpty() {
|
|
97
|
+
return (this.currencyChanges.size === 0 &&
|
|
98
|
+
this.currencyPropertyUpdates.size === 0 &&
|
|
99
|
+
this.newItemRequests.length === 0 &&
|
|
100
|
+
this.deleteItemRequests.length === 0 &&
|
|
101
|
+
this.updateItemRequests.length === 0 &&
|
|
102
|
+
this.applyVipBonusFlag === undefined);
|
|
103
|
+
}
|
|
104
|
+
toRequest(options = {}) {
|
|
105
|
+
const payload = {};
|
|
106
|
+
if (options.transaction) {
|
|
107
|
+
payload.transaction = options.transaction;
|
|
108
|
+
}
|
|
109
|
+
if (this.applyVipBonusFlag !== undefined) {
|
|
110
|
+
payload.applyVipBonus = this.applyVipBonusFlag;
|
|
111
|
+
}
|
|
112
|
+
if (this.currencyChanges.size > 0) {
|
|
113
|
+
const currencies = {};
|
|
114
|
+
for (const [currencyId, delta] of this.currencyChanges.entries()) {
|
|
115
|
+
currencies[currencyId] = delta.toString();
|
|
116
|
+
}
|
|
117
|
+
payload.currencies = currencies;
|
|
118
|
+
}
|
|
119
|
+
if (this.currencyPropertyUpdates.size > 0) {
|
|
120
|
+
const currencyProperties = {};
|
|
121
|
+
for (const [currencyId, properties] of this.currencyPropertyUpdates.entries()) {
|
|
122
|
+
currencyProperties[currencyId] = properties.map((property) => ({ ...property }));
|
|
123
|
+
}
|
|
124
|
+
payload.currencyProperties = currencyProperties;
|
|
125
|
+
}
|
|
126
|
+
if (this.newItemRequests.length > 0) {
|
|
127
|
+
payload.newItems = this.newItemRequests.map((item) => ({
|
|
128
|
+
contentId: item.contentId,
|
|
129
|
+
properties: item.properties.map((property) => ({ ...property })),
|
|
130
|
+
reqId: item.reqId,
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
if (this.deleteItemRequests.length > 0) {
|
|
134
|
+
payload.deleteItems = this.deleteItemRequests.map((item) => ({
|
|
135
|
+
contentId: item.contentId,
|
|
136
|
+
id: this.toIdentifier(item.id),
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
if (this.updateItemRequests.length > 0) {
|
|
140
|
+
payload.updateItems = this.updateItemRequests.map((item) => ({
|
|
141
|
+
contentId: item.contentId,
|
|
142
|
+
id: this.toIdentifier(item.id),
|
|
143
|
+
properties: item.properties.map((property) => ({ ...property })),
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
return payload;
|
|
147
|
+
}
|
|
148
|
+
normalizeId(value, kind) {
|
|
149
|
+
const trimmed = value.trim();
|
|
150
|
+
if (!trimmed) {
|
|
151
|
+
throw new Error(`Invalid ${kind} identifier: "${value}"`);
|
|
152
|
+
}
|
|
153
|
+
return trimmed;
|
|
154
|
+
}
|
|
155
|
+
toIdentifier(value) {
|
|
156
|
+
if (typeof value === 'bigint') {
|
|
157
|
+
return value.toString();
|
|
158
|
+
}
|
|
159
|
+
if (typeof value === 'number') {
|
|
160
|
+
if (!Number.isFinite(value)) {
|
|
161
|
+
throw new Error(`Invalid numeric identifier: ${value}`);
|
|
162
|
+
}
|
|
163
|
+
return Math.trunc(value).toString();
|
|
164
|
+
}
|
|
165
|
+
const trimmed = value.trim();
|
|
166
|
+
if (!trimmed) {
|
|
167
|
+
throw new Error('Identifier cannot be empty.');
|
|
168
|
+
}
|
|
169
|
+
return trimmed;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.InventoryUpdateBuilder = InventoryUpdateBuilder;
|
|
173
|
+
class InventoryService {
|
|
174
|
+
constructor(dependencies) {
|
|
175
|
+
this.api = dependencies.api;
|
|
176
|
+
this.logger = dependencies.logger.child({ component: 'InventoryService' });
|
|
177
|
+
this.userId = dependencies.userId;
|
|
178
|
+
this.ensureScopes = dependencies.scopeChecker;
|
|
179
|
+
}
|
|
180
|
+
createBuilder() {
|
|
181
|
+
return new InventoryUpdateBuilder();
|
|
182
|
+
}
|
|
183
|
+
async update(builderOrCallback, options = {}) {
|
|
184
|
+
const builder = builderOrCallback instanceof InventoryUpdateBuilder ? builderOrCallback : this.createBuilder();
|
|
185
|
+
if (!(builderOrCallback instanceof InventoryUpdateBuilder)) {
|
|
186
|
+
await builderOrCallback(builder);
|
|
187
|
+
}
|
|
188
|
+
if (builder.isEmpty()) {
|
|
189
|
+
this.logger.debug('Inventory update skipped because builder produced no changes.');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this.ensureScopes(['server']);
|
|
193
|
+
const payload = builder.toRequest(options);
|
|
194
|
+
await this.invokeInventoryPut(payload);
|
|
195
|
+
}
|
|
196
|
+
async setCurrencies(currencyValues, transaction) {
|
|
197
|
+
var _a;
|
|
198
|
+
this.ensureScopes(['server']);
|
|
199
|
+
const current = await this.getCurrencies(Object.keys(currencyValues));
|
|
200
|
+
const deltas = {};
|
|
201
|
+
for (const [currencyId, target] of Object.entries(currencyValues)) {
|
|
202
|
+
const currentVal = (_a = current[currencyId]) !== null && _a !== void 0 ? _a : BigInt(0);
|
|
203
|
+
const targetValue = BigInt(target);
|
|
204
|
+
const delta = targetValue - currentVal;
|
|
205
|
+
if (delta !== BigInt(0)) {
|
|
206
|
+
deltas[currencyId] = delta;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (Object.keys(deltas).length === 0) {
|
|
210
|
+
this.logger.debug('No currency adjustments required; request skipped.');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
await this.update((builder) => {
|
|
214
|
+
for (const [currencyId, delta] of Object.entries(deltas)) {
|
|
215
|
+
builder.currencyChange(currencyId, delta);
|
|
216
|
+
}
|
|
217
|
+
}, { transaction });
|
|
218
|
+
}
|
|
219
|
+
async addCurrencies(currencyDeltas, transaction) {
|
|
220
|
+
await this.update((builder) => {
|
|
221
|
+
for (const [currencyId, delta] of Object.entries(currencyDeltas)) {
|
|
222
|
+
builder.currencyChange(currencyId, delta);
|
|
223
|
+
}
|
|
224
|
+
}, { transaction });
|
|
225
|
+
}
|
|
226
|
+
async addItem(contentId, properties = {}, transaction) {
|
|
227
|
+
await this.update((builder) => {
|
|
228
|
+
builder.addItem(contentId, properties);
|
|
229
|
+
}, { transaction });
|
|
230
|
+
}
|
|
231
|
+
async deleteItem(contentId, itemId, transaction) {
|
|
232
|
+
await this.update((builder) => {
|
|
233
|
+
builder.deleteItem(contentId, itemId);
|
|
234
|
+
}, { transaction });
|
|
235
|
+
}
|
|
236
|
+
async updateItem(contentId, itemId, properties, transaction) {
|
|
237
|
+
await this.update((builder) => {
|
|
238
|
+
builder.updateItem(contentId, itemId, properties);
|
|
239
|
+
}, { transaction });
|
|
240
|
+
}
|
|
241
|
+
async setCurrencyProperties(currencyId, properties, transaction) {
|
|
242
|
+
await this.update((builder) => {
|
|
243
|
+
builder.setCurrencyProperties(currencyId, properties);
|
|
244
|
+
}, { transaction });
|
|
245
|
+
}
|
|
246
|
+
async previewCurrencyGain(currencyChanges) {
|
|
247
|
+
this.ensureScopes(['server']);
|
|
248
|
+
const payload = {
|
|
249
|
+
currencies: Object.fromEntries(Object.entries(currencyChanges).map(([currencyId, amount]) => [currencyId, BigInt(amount).toString()])),
|
|
250
|
+
};
|
|
251
|
+
const response = await this.invokePreview(payload);
|
|
252
|
+
return response;
|
|
253
|
+
}
|
|
254
|
+
async getMultipliers() {
|
|
255
|
+
this.ensureScopes(['server']);
|
|
256
|
+
const response = await this.invokeGetMultipliers();
|
|
257
|
+
return response;
|
|
258
|
+
}
|
|
259
|
+
async getInventory(scope) {
|
|
260
|
+
this.ensureScopes(['server']);
|
|
261
|
+
const response = await this.invokeGetInventory(scope);
|
|
262
|
+
return response;
|
|
263
|
+
}
|
|
264
|
+
async getCurrencies(currencyIds) {
|
|
265
|
+
var _a;
|
|
266
|
+
const scope = Array.isArray(currencyIds) && currencyIds.length > 0 ? currencyIds.join(',') : 'currency';
|
|
267
|
+
const view = await this.getInventory(scope);
|
|
268
|
+
const result = {};
|
|
269
|
+
for (const currency of (_a = view.currencies) !== null && _a !== void 0 ? _a : []) {
|
|
270
|
+
result[currency.id] = BigInt(currency.amount);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
async sendCurrency(request) {
|
|
275
|
+
var _a, _b, _c;
|
|
276
|
+
this.ensureScopes(['server']);
|
|
277
|
+
const payload = {
|
|
278
|
+
recipientPlayer: this.toIdentifier(request.recipientPlayer),
|
|
279
|
+
currencies: Object.fromEntries(Object.entries((_a = request.currencies) !== null && _a !== void 0 ? _a : {}).map(([currencyId, amount]) => [currencyId, BigInt(amount).toString()])),
|
|
280
|
+
transaction: request.transaction,
|
|
281
|
+
};
|
|
282
|
+
const response = (_c = (_b = this.api).inventoryPutTransferByObjectId) === null || _c === void 0 ? void 0 : _c.call(_b, this.userId, payload);
|
|
283
|
+
if (!response || typeof response.then !== 'function') {
|
|
284
|
+
throw new Error('inventoryPutTransferByObjectId API is unavailable in the current SDK.');
|
|
285
|
+
}
|
|
286
|
+
await response;
|
|
287
|
+
}
|
|
288
|
+
async invokeInventoryPut(payload) {
|
|
289
|
+
var _a, _b;
|
|
290
|
+
const response = (_b = (_a = this.api).inventoryPutByObjectId) === null || _b === void 0 ? void 0 : _b.call(_a, this.userId, payload);
|
|
291
|
+
if (!response || typeof response.then !== 'function') {
|
|
292
|
+
throw new Error('inventoryPutByObjectId API is unavailable in the current SDK.');
|
|
293
|
+
}
|
|
294
|
+
await response;
|
|
295
|
+
}
|
|
296
|
+
async invokePreview(payload) {
|
|
297
|
+
var _a, _b;
|
|
298
|
+
const response = (_b = (_a = this.api).inventoryPutPreviewByObjectId) === null || _b === void 0 ? void 0 : _b.call(_a, this.userId, payload);
|
|
299
|
+
if (!response || typeof response.then !== 'function') {
|
|
300
|
+
throw new Error('inventoryPutPreviewByObjectId API is unavailable in the current SDK.');
|
|
301
|
+
}
|
|
302
|
+
const result = await response;
|
|
303
|
+
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
return result.body;
|
|
307
|
+
}
|
|
308
|
+
async invokeGetMultipliers() {
|
|
309
|
+
var _a, _b;
|
|
310
|
+
const response = (_b = (_a = this.api).inventoryGetMultipliersByObjectId) === null || _b === void 0 ? void 0 : _b.call(_a, this.userId);
|
|
311
|
+
if (!response || typeof response.then !== 'function') {
|
|
312
|
+
throw new Error('inventoryGetMultipliersByObjectId API is unavailable in the current SDK.');
|
|
313
|
+
}
|
|
314
|
+
const result = await response;
|
|
315
|
+
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
return result.body;
|
|
319
|
+
}
|
|
320
|
+
async invokeGetInventory(scope) {
|
|
321
|
+
var _a, _b;
|
|
322
|
+
const response = (_b = (_a = this.api).inventoryGetByObjectId) === null || _b === void 0 ? void 0 : _b.call(_a, this.userId, scope);
|
|
323
|
+
if (!response || typeof response.then !== 'function') {
|
|
324
|
+
throw new Error('inventoryGetByObjectId API is unavailable in the current SDK.');
|
|
325
|
+
}
|
|
326
|
+
const result = await response;
|
|
327
|
+
if (!result || typeof result !== 'object' || !('body' in result)) {
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
return result.body;
|
|
331
|
+
}
|
|
332
|
+
toIdentifier(value) {
|
|
333
|
+
if (typeof value === 'string') {
|
|
334
|
+
const trimmed = value.trim();
|
|
335
|
+
if (!trimmed) {
|
|
336
|
+
throw new Error('Identifier cannot be empty.');
|
|
337
|
+
}
|
|
338
|
+
return trimmed;
|
|
339
|
+
}
|
|
340
|
+
if (typeof value === 'number') {
|
|
341
|
+
if (!Number.isFinite(value)) {
|
|
342
|
+
throw new Error(`Invalid numeric identifier: ${value}`);
|
|
343
|
+
}
|
|
344
|
+
return Math.trunc(value).toString();
|
|
345
|
+
}
|
|
346
|
+
return value.toString();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.InventoryService = InventoryService;
|
|
350
|
+
function createInventoryService(api, logger, userId, hasScopes) {
|
|
351
|
+
return new InventoryService({
|
|
352
|
+
api,
|
|
353
|
+
logger,
|
|
354
|
+
userId,
|
|
355
|
+
scopeChecker: (requiredScopes) => {
|
|
356
|
+
if (!hasScopes(requiredScopes)) {
|
|
357
|
+
throw new errors_js_1.MissingScopesError(requiredScopes);
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
}
|