@fjell/core 4.4.73 → 4.4.74
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 +6 -6
- package/dist/AItemService.d.ts +1 -1
- package/dist/Coordinate.d.ts +1 -6
- package/dist/event/emitter.d.ts +1 -2
- package/dist/event/events.d.ts +1 -2
- package/dist/event/matching.d.ts +1 -1
- package/dist/event/subscription.d.ts +1 -2
- package/dist/index.d.ts +7 -20
- package/dist/index.js +1113 -1276
- package/dist/item/IFactory.d.ts +1 -2
- package/dist/item/IQFactory.d.ts +1 -1
- package/dist/item/IQUtils.d.ts +1 -2
- package/dist/item/IUtils.d.ts +1 -7
- package/dist/key/KUtils.d.ts +3 -3
- package/dist/operations/OperationContext.d.ts +1 -1
- package/dist/operations/index.d.ts +1 -0
- package/dist/operations/wrappers/createActionWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createAllActionWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createAllFacetWrapper.d.ts +1 -2
- package/dist/operations/wrappers/createAllWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createCreateWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createFacetWrapper.d.ts +1 -2
- package/dist/operations/wrappers/createFindOneWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createFindWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createGetWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createOneWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createRemoveWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createUpdateWrapper.d.ts +1 -3
- package/dist/operations/wrappers/createUpsertWrapper.d.ts +1 -3
- package/dist/operations/wrappers/types.d.ts +1 -1
- package/package.json +4 -7
- package/dist/item/ItemQuery.d.ts +0 -62
- package/dist/items.d.ts +0 -74
- package/dist/keys.d.ts +0 -66
- package/dist/operations/Operations.d.ts +0 -530
- package/dist/operations/contained.d.ts +0 -65
- package/dist/operations/methods.d.ts +0 -204
- package/dist/operations/primary.d.ts +0 -57
- package/dist/operations/specialized.d.ts +0 -41
- package/dist/validation/ItemValidator.d.ts +0 -43
- package/dist/validation/KeyValidator.d.ts +0 -56
- package/dist/validation/LocationValidator.d.ts +0 -39
- package/dist/validation/QueryValidator.d.ts +0 -57
- package/dist/validation/index.d.ts +0 -17
- package/dist/validation/index.js +0 -656
- package/dist/validation/schema.d.ts +0 -23
- package/dist/validation/types.d.ts +0 -69
package/dist/index.js
CHANGED
|
@@ -3,84 +3,14 @@ import Logging from "@fjell/logging";
|
|
|
3
3
|
var LibLogger = Logging.getLogger("@fjell/core");
|
|
4
4
|
var logger_default = LibLogger;
|
|
5
5
|
|
|
6
|
-
// src/
|
|
7
|
-
var logger = logger_default.get("
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
hashFunction = (key) => JSON.stringify(key);
|
|
11
|
-
constructor(map, hashFunction) {
|
|
12
|
-
if (hashFunction) {
|
|
13
|
-
this.hashFunction = hashFunction;
|
|
14
|
-
}
|
|
15
|
-
if (map) {
|
|
16
|
-
Object.entries(map).forEach(([hashedKey, value]) => {
|
|
17
|
-
try {
|
|
18
|
-
const originalKey = JSON.parse(hashedKey);
|
|
19
|
-
this.map[hashedKey] = { originalKey, value };
|
|
20
|
-
} catch {
|
|
21
|
-
logger.warning("Cannot recover original key from legacy map entry", { hashedKey });
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
set(key, item) {
|
|
27
|
-
logger.trace("set", { key, item });
|
|
28
|
-
const hashedKey = this.hashFunction(key);
|
|
29
|
-
this.map[hashedKey] = { originalKey: key, value: item };
|
|
30
|
-
}
|
|
31
|
-
get(key) {
|
|
32
|
-
logger.trace("get", { key });
|
|
33
|
-
const hashedKey = this.hashFunction(key);
|
|
34
|
-
const entry = this.map[hashedKey];
|
|
35
|
-
return entry && this.keysEqual(entry.originalKey, key) ? entry.value : null;
|
|
36
|
-
}
|
|
37
|
-
keysEqual(key1, key2) {
|
|
38
|
-
return key1 === key2;
|
|
39
|
-
}
|
|
40
|
-
delete(key) {
|
|
41
|
-
logger.trace("delete", { key });
|
|
42
|
-
const hashedKey = this.hashFunction(key);
|
|
43
|
-
delete this.map[hashedKey];
|
|
44
|
-
}
|
|
45
|
-
keys() {
|
|
46
|
-
return Object.values(this.map).map((entry) => entry.originalKey);
|
|
47
|
-
}
|
|
48
|
-
values() {
|
|
49
|
-
return Object.values(this.map).map((entry) => entry.value);
|
|
50
|
-
}
|
|
51
|
-
includesKey(key) {
|
|
52
|
-
const hashedKey = this.hashFunction(key);
|
|
53
|
-
const entry = this.map[hashedKey];
|
|
54
|
-
return entry ? this.keysEqual(entry.originalKey, key) : false;
|
|
55
|
-
}
|
|
56
|
-
clone() {
|
|
57
|
-
const clonedMap = {};
|
|
58
|
-
Object.entries(this.map).forEach(([hashedKey, entry]) => {
|
|
59
|
-
clonedMap[hashedKey] = entry.value;
|
|
60
|
-
});
|
|
61
|
-
const clone = new _Dictionary(clonedMap, this.hashFunction);
|
|
62
|
-
clone.map = Object.assign({}, this.map);
|
|
63
|
-
return clone;
|
|
64
|
-
}
|
|
6
|
+
// src/key/KUtils.ts
|
|
7
|
+
var logger = logger_default.get("KUtils");
|
|
8
|
+
var isComKey = (key) => {
|
|
9
|
+
return key !== null && typeof key === "object" && "kt" in key && "pk" in key && "loc" in key && Array.isArray(key.loc) && key.loc.length > 0;
|
|
65
10
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
var logger2 = logger_default.get("Coordinate");
|
|
69
|
-
var createCoordinate = (kta, scopes = []) => {
|
|
70
|
-
const ktArray = Array.isArray(kta) ? kta : [kta];
|
|
71
|
-
const toString = () => {
|
|
72
|
-
logger2.debug("toString", { kta, scopes });
|
|
73
|
-
return `${ktArray.join(", ")} - ${scopes.join(", ")}`;
|
|
74
|
-
};
|
|
75
|
-
logger2.debug("createCoordinate", { kta: ktArray, scopes, toString });
|
|
76
|
-
return { kta: ktArray, scopes, toString };
|
|
11
|
+
var isPriKey = (key) => {
|
|
12
|
+
return key !== null && typeof key === "object" && "kt" in key && "pk" in key && (!("loc" in key) || !key.loc || Array.isArray(key.loc) && key.loc.length === 0);
|
|
77
13
|
};
|
|
78
|
-
|
|
79
|
-
// src/item/IFactory.ts
|
|
80
|
-
import deepmerge from "deepmerge";
|
|
81
|
-
|
|
82
|
-
// src/key/KUtils.ts
|
|
83
|
-
var logger3 = logger_default.get("KUtils");
|
|
84
14
|
var normalizeKeyValue = (value) => {
|
|
85
15
|
return String(value);
|
|
86
16
|
};
|
|
@@ -108,15 +38,15 @@ var createNormalizedHashFunction = () => {
|
|
|
108
38
|
};
|
|
109
39
|
};
|
|
110
40
|
var isPriKeyEqualNormalized = (a, b) => {
|
|
111
|
-
|
|
41
|
+
logger.trace("isPriKeyEqualNormalized", { a, b });
|
|
112
42
|
return a && b && normalizeKeyValue(a.pk) === normalizeKeyValue(b.pk) && a.kt === b.kt;
|
|
113
43
|
};
|
|
114
44
|
var isLocKeyEqualNormalized = (a, b) => {
|
|
115
|
-
|
|
45
|
+
logger.trace("isLocKeyEqualNormalized", { a, b });
|
|
116
46
|
return a && b && normalizeKeyValue(a.lk) === normalizeKeyValue(b.lk) && a.kt === b.kt;
|
|
117
47
|
};
|
|
118
48
|
var isComKeyEqualNormalized = (a, b) => {
|
|
119
|
-
|
|
49
|
+
logger.trace("isComKeyEqualNormalized", { a, b });
|
|
120
50
|
if (a && b && isPriKeyEqualNormalized({ kt: a.kt, pk: a.pk }, { kt: b.kt, pk: b.pk })) {
|
|
121
51
|
if (a.loc.length === b.loc.length) {
|
|
122
52
|
for (let i = 0; i < a.loc.length; i++) {
|
|
@@ -133,7 +63,7 @@ var isComKeyEqualNormalized = (a, b) => {
|
|
|
133
63
|
}
|
|
134
64
|
};
|
|
135
65
|
var isItemKeyEqualNormalized = (a, b) => {
|
|
136
|
-
|
|
66
|
+
logger.trace("isItemKeyEqualNormalized", { a, b });
|
|
137
67
|
if (isComKey(a) && isComKey(b)) {
|
|
138
68
|
return isComKeyEqualNormalized(a, b);
|
|
139
69
|
} else if (isPriKey(a) && isPriKey(b)) {
|
|
@@ -147,7 +77,7 @@ var isItemKeyEqualNormalized = (a, b) => {
|
|
|
147
77
|
}
|
|
148
78
|
};
|
|
149
79
|
var isItemKeyEqual = (a, b) => {
|
|
150
|
-
|
|
80
|
+
logger.trace("isKeyEqual", { a, b });
|
|
151
81
|
if (isComKey(a) && isComKey(b)) {
|
|
152
82
|
return isComKeyEqual(a, b);
|
|
153
83
|
} else if (isPriKey(a) && isPriKey(b)) {
|
|
@@ -161,15 +91,15 @@ var isItemKeyEqual = (a, b) => {
|
|
|
161
91
|
}
|
|
162
92
|
};
|
|
163
93
|
var isPriKeyEqual = (a, b) => {
|
|
164
|
-
|
|
94
|
+
logger.trace("isPriKeyEqual", { a, b });
|
|
165
95
|
return a && b && a.pk === b.pk && a.kt === b.kt;
|
|
166
96
|
};
|
|
167
97
|
var isLocKeyEqual = (a, b) => {
|
|
168
|
-
|
|
98
|
+
logger.trace("isLocKeyEqual", { a, b });
|
|
169
99
|
return a && b && a.lk === b.lk && a.kt === b.kt;
|
|
170
100
|
};
|
|
171
101
|
var isComKeyEqual = (a, b) => {
|
|
172
|
-
|
|
102
|
+
logger.trace("isComKeyEqual", { a, b });
|
|
173
103
|
if (a && b && isPriKeyEqual({ kt: a.kt, pk: a.pk }, { kt: b.kt, pk: b.pk })) {
|
|
174
104
|
if (a.loc.length === b.loc.length) {
|
|
175
105
|
for (let i = 0; i < a.loc.length; i++) {
|
|
@@ -186,23 +116,15 @@ var isComKeyEqual = (a, b) => {
|
|
|
186
116
|
}
|
|
187
117
|
};
|
|
188
118
|
var isItemKey = (key) => {
|
|
189
|
-
|
|
119
|
+
logger.trace("isItemKey", { key });
|
|
190
120
|
return key !== void 0 && (isComKey(key) || isPriKey(key));
|
|
191
121
|
};
|
|
192
|
-
var isComKey = (key) => {
|
|
193
|
-
logger3.trace("isComKey", { key });
|
|
194
|
-
return key !== void 0 && (key.pk !== void 0 && key.kt !== void 0) && (key.loc !== void 0 && Array.isArray(key.loc));
|
|
195
|
-
};
|
|
196
|
-
var isPriKey = (key) => {
|
|
197
|
-
logger3.trace("isPriKey", { key });
|
|
198
|
-
return key !== void 0 && (key.pk !== void 0 && key.kt !== void 0) && key.loc === void 0;
|
|
199
|
-
};
|
|
200
122
|
var isLocKey = (key) => {
|
|
201
|
-
|
|
123
|
+
logger.trace("isLocKey", { key });
|
|
202
124
|
return key !== void 0 && (key.lk !== void 0 && key.kt !== void 0);
|
|
203
125
|
};
|
|
204
126
|
var generateKeyArray = (key) => {
|
|
205
|
-
|
|
127
|
+
logger.trace("generateKeyArray", { key });
|
|
206
128
|
const keys = [];
|
|
207
129
|
if (isComKey(key) || isPriKey(key)) {
|
|
208
130
|
if (isComKey(key)) {
|
|
@@ -223,7 +145,7 @@ var generateKeyArray = (key) => {
|
|
|
223
145
|
return keys;
|
|
224
146
|
};
|
|
225
147
|
var constructPriKey = (pk, kt) => {
|
|
226
|
-
|
|
148
|
+
logger.trace("constructPriKey", { pk, kt });
|
|
227
149
|
let pri;
|
|
228
150
|
if (typeof pk === "string" || typeof pk === "number") {
|
|
229
151
|
pri = { kt, pk };
|
|
@@ -234,7 +156,7 @@ var constructPriKey = (pk, kt) => {
|
|
|
234
156
|
};
|
|
235
157
|
var cPK = constructPriKey;
|
|
236
158
|
var toKeyTypeArray = (ik) => {
|
|
237
|
-
|
|
159
|
+
logger.trace("toKeyTypeArray", { ik });
|
|
238
160
|
if (isComKey(ik)) {
|
|
239
161
|
const ck = ik;
|
|
240
162
|
return [ck.kt, ...ck.loc.map((l) => l.kt)];
|
|
@@ -243,7 +165,7 @@ var toKeyTypeArray = (ik) => {
|
|
|
243
165
|
}
|
|
244
166
|
};
|
|
245
167
|
var extractKeyTypeArray = (key) => {
|
|
246
|
-
|
|
168
|
+
logger.trace("extractKeyTypeArray", { key });
|
|
247
169
|
if (isComKey(key)) {
|
|
248
170
|
const ck = key;
|
|
249
171
|
return [ck.kt, ...ck.loc.map((l) => l.kt)];
|
|
@@ -252,12 +174,12 @@ var extractKeyTypeArray = (key) => {
|
|
|
252
174
|
} else if (Array.isArray(key)) {
|
|
253
175
|
return key.map((locKey) => locKey.kt);
|
|
254
176
|
} else {
|
|
255
|
-
|
|
177
|
+
logger.warning("extractKeyTypeArray: Unknown key type", { key });
|
|
256
178
|
return [];
|
|
257
179
|
}
|
|
258
180
|
};
|
|
259
181
|
var abbrevIK = (ik) => {
|
|
260
|
-
|
|
182
|
+
logger.trace("abbrevIK", { ik });
|
|
261
183
|
if (ik) {
|
|
262
184
|
if (isComKey(ik)) {
|
|
263
185
|
const ck = ik;
|
|
@@ -270,7 +192,7 @@ var abbrevIK = (ik) => {
|
|
|
270
192
|
}
|
|
271
193
|
};
|
|
272
194
|
var abbrevLKA = (keyArray) => {
|
|
273
|
-
|
|
195
|
+
logger.trace("abbrevLKA", { keyArray });
|
|
274
196
|
if (keyArray === void 0 || keyArray === null) {
|
|
275
197
|
return "null LKA";
|
|
276
198
|
} else {
|
|
@@ -284,7 +206,7 @@ var abbrevLKA = (keyArray) => {
|
|
|
284
206
|
}
|
|
285
207
|
};
|
|
286
208
|
var primaryType = (ik) => {
|
|
287
|
-
|
|
209
|
+
logger.trace("primaryType", { ik });
|
|
288
210
|
if (isComKey(ik)) {
|
|
289
211
|
return ik.kt;
|
|
290
212
|
} else {
|
|
@@ -292,7 +214,7 @@ var primaryType = (ik) => {
|
|
|
292
214
|
}
|
|
293
215
|
};
|
|
294
216
|
var itemKeyToLocKeyArray = (ik) => {
|
|
295
|
-
|
|
217
|
+
logger.trace("itemKeyToLocKeyArray", { ik: abbrevIK(ik) });
|
|
296
218
|
let lka = [];
|
|
297
219
|
if (isComKey(ik)) {
|
|
298
220
|
const ck = ik;
|
|
@@ -301,12 +223,12 @@ var itemKeyToLocKeyArray = (ik) => {
|
|
|
301
223
|
const pk = ik;
|
|
302
224
|
lka = [{ kt: pk.kt, lk: pk.pk }];
|
|
303
225
|
}
|
|
304
|
-
|
|
226
|
+
logger.trace("itemKeyToLocKeyArray Results", { ik: abbrevIK(ik), lka: abbrevLKA(lka) });
|
|
305
227
|
return lka;
|
|
306
228
|
};
|
|
307
229
|
var ikToLKA = itemKeyToLocKeyArray;
|
|
308
230
|
var locKeyArrayToItemKey = (lka) => {
|
|
309
|
-
|
|
231
|
+
logger.trace("locKeyArrayToItemKey", { lka: abbrevLKA(lka) });
|
|
310
232
|
if (lka && lka.length === 1) {
|
|
311
233
|
const priKey = cPK(lka[0].lk, lka[0].kt);
|
|
312
234
|
return priKey;
|
|
@@ -336,96 +258,13 @@ var isValidComKey = (key) => {
|
|
|
336
258
|
return key !== void 0 && key !== null && isValidPriKey(key) && isValidLocKeyArray(key.loc);
|
|
337
259
|
};
|
|
338
260
|
var isValidItemKey = (key) => {
|
|
261
|
+
if (key === null) throw new Error("Key cannot be null");
|
|
262
|
+
if (key === void 0) return false;
|
|
339
263
|
return isComKey(key) && isValidComKey(key) || isPriKey(key) && isValidPriKey(key);
|
|
340
264
|
};
|
|
341
265
|
var lkaToIK = locKeyArrayToItemKey;
|
|
342
266
|
|
|
343
|
-
//
|
|
344
|
-
var IFactory = class _IFactory {
|
|
345
|
-
item = {};
|
|
346
|
-
constructor(props = {}) {
|
|
347
|
-
this.item = deepmerge(this.item, props);
|
|
348
|
-
}
|
|
349
|
-
addRef(i, name) {
|
|
350
|
-
const ik = i.key;
|
|
351
|
-
const refName = name || primaryType(ik);
|
|
352
|
-
if (!this.item.refs) {
|
|
353
|
-
this.item.refs = {};
|
|
354
|
-
}
|
|
355
|
-
this.item.refs[refName] = ik;
|
|
356
|
-
return this;
|
|
357
|
-
}
|
|
358
|
-
static addRef(i, name) {
|
|
359
|
-
return new _IFactory().addRef(i, name);
|
|
360
|
-
}
|
|
361
|
-
addDefaultEvents() {
|
|
362
|
-
if (!this.item.events) {
|
|
363
|
-
this.item.events = {};
|
|
364
|
-
}
|
|
365
|
-
const now = /* @__PURE__ */ new Date();
|
|
366
|
-
if (!this.item.events.created) {
|
|
367
|
-
this.item.events.created = { at: now };
|
|
368
|
-
}
|
|
369
|
-
if (!this.item.events.updated) {
|
|
370
|
-
this.item.events.updated = { at: now };
|
|
371
|
-
}
|
|
372
|
-
if (!this.item.events.deleted) {
|
|
373
|
-
this.item.events.deleted = { at: null };
|
|
374
|
-
}
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
addEvent(name, at, by) {
|
|
378
|
-
if (!this.item.events) {
|
|
379
|
-
this.item.events = {};
|
|
380
|
-
}
|
|
381
|
-
this.item.events[name] = { at, by };
|
|
382
|
-
return this;
|
|
383
|
-
}
|
|
384
|
-
static addEvent(name, at, by) {
|
|
385
|
-
return new _IFactory().addEvent(name, at, by);
|
|
386
|
-
}
|
|
387
|
-
addProp(name, value) {
|
|
388
|
-
this.item[name] = value;
|
|
389
|
-
return this;
|
|
390
|
-
}
|
|
391
|
-
static addProp(name, value) {
|
|
392
|
-
return new _IFactory().addProp(name, value);
|
|
393
|
-
}
|
|
394
|
-
addProps(props) {
|
|
395
|
-
this.item = deepmerge(this.item, props);
|
|
396
|
-
return this;
|
|
397
|
-
}
|
|
398
|
-
static addProps(props) {
|
|
399
|
-
return new _IFactory().addProps(props);
|
|
400
|
-
}
|
|
401
|
-
toItem() {
|
|
402
|
-
return this.item;
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
// src/AItemService.ts
|
|
407
|
-
var AItemService = class {
|
|
408
|
-
pkType;
|
|
409
|
-
parentService = null;
|
|
410
|
-
constructor(pkType, parentService) {
|
|
411
|
-
this.pkType = pkType;
|
|
412
|
-
if (parentService) {
|
|
413
|
-
this.parentService = parentService;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
getPkType = () => {
|
|
417
|
-
return this.pkType;
|
|
418
|
-
};
|
|
419
|
-
getKeyTypes = () => {
|
|
420
|
-
let keyTypes = [this.getPkType()];
|
|
421
|
-
if (this.parentService) {
|
|
422
|
-
keyTypes = keyTypes.concat(this.parentService.getKeyTypes());
|
|
423
|
-
}
|
|
424
|
-
return keyTypes;
|
|
425
|
-
};
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// src/item/ItemQuery.ts
|
|
267
|
+
// node_modules/@fjell/types/dist/chunk-5M6KJZFD.js
|
|
429
268
|
var isCondition = (condition) => {
|
|
430
269
|
return (typeof condition.column === "string" && (Array.isArray(condition.value) && condition.value.every((item) => typeof item === "string")) || Array.isArray(condition.value) && condition.value.every((item) => typeof item === "number") || typeof condition.value === "string" || typeof condition.value === "number" || typeof condition.value === "boolean" || condition.value instanceof Date || condition.value === null) && (condition.operator ? typeof condition.operator === "string" : true);
|
|
431
270
|
};
|
|
@@ -550,63 +389,221 @@ var IQFactory = class _IQFactory {
|
|
|
550
389
|
}
|
|
551
390
|
};
|
|
552
391
|
|
|
553
|
-
// src/item/
|
|
554
|
-
import
|
|
555
|
-
var
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
params.compoundCondition = JSON.stringify(query.compoundCondition);
|
|
560
|
-
}
|
|
561
|
-
if (query.refs) {
|
|
562
|
-
params.refs = JSON.stringify(query.refs);
|
|
563
|
-
}
|
|
564
|
-
if (query.limit) {
|
|
565
|
-
params.limit = query.limit;
|
|
566
|
-
}
|
|
567
|
-
if (query.offset) {
|
|
568
|
-
params.offset = query.offset;
|
|
569
|
-
}
|
|
570
|
-
if (query.aggs) {
|
|
571
|
-
params.aggs = JSON.stringify(query.aggs);
|
|
392
|
+
// src/item/IFactory.ts
|
|
393
|
+
import deepmerge from "deepmerge";
|
|
394
|
+
var IFactory = class _IFactory {
|
|
395
|
+
item = {};
|
|
396
|
+
constructor(props = {}) {
|
|
397
|
+
this.item = deepmerge(this.item, props);
|
|
572
398
|
}
|
|
573
|
-
|
|
574
|
-
|
|
399
|
+
addRef(i, name) {
|
|
400
|
+
const ik = i.key;
|
|
401
|
+
const refName = name || primaryType(ik);
|
|
402
|
+
if (!this.item.refs) {
|
|
403
|
+
this.item.refs = {};
|
|
404
|
+
}
|
|
405
|
+
this.item.refs[refName] = ik;
|
|
406
|
+
return this;
|
|
575
407
|
}
|
|
576
|
-
|
|
577
|
-
|
|
408
|
+
static addRef(i, name) {
|
|
409
|
+
return new _IFactory().addRef(i, name);
|
|
578
410
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
const
|
|
584
|
-
if (
|
|
585
|
-
|
|
586
|
-
|
|
411
|
+
addDefaultEvents() {
|
|
412
|
+
if (!this.item.events) {
|
|
413
|
+
this.item.events = {};
|
|
414
|
+
}
|
|
415
|
+
const now = /* @__PURE__ */ new Date();
|
|
416
|
+
if (!this.item.events.created) {
|
|
417
|
+
this.item.events.created = { at: now };
|
|
418
|
+
}
|
|
419
|
+
if (!this.item.events.updated) {
|
|
420
|
+
this.item.events.updated = { at: now };
|
|
421
|
+
}
|
|
422
|
+
if (!this.item.events.deleted) {
|
|
423
|
+
this.item.events.deleted = { at: null };
|
|
587
424
|
}
|
|
425
|
+
return this;
|
|
588
426
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
427
|
+
addEvent(name, at, by) {
|
|
428
|
+
if (!this.item.events) {
|
|
429
|
+
this.item.events = {};
|
|
430
|
+
}
|
|
431
|
+
this.item.events[name] = { at, by };
|
|
432
|
+
return this;
|
|
595
433
|
}
|
|
596
|
-
|
|
597
|
-
|
|
434
|
+
static addEvent(name, at, by) {
|
|
435
|
+
return new _IFactory().addEvent(name, at, by);
|
|
598
436
|
}
|
|
599
|
-
|
|
600
|
-
|
|
437
|
+
addProp(name, value) {
|
|
438
|
+
this.item[name] = value;
|
|
439
|
+
return this;
|
|
601
440
|
}
|
|
602
|
-
|
|
603
|
-
|
|
441
|
+
static addProp(name, value) {
|
|
442
|
+
return new _IFactory().addProp(name, value);
|
|
604
443
|
}
|
|
605
|
-
|
|
606
|
-
|
|
444
|
+
addProps(props) {
|
|
445
|
+
this.item = deepmerge(this.item, props);
|
|
446
|
+
return this;
|
|
607
447
|
}
|
|
608
|
-
|
|
609
|
-
|
|
448
|
+
static addProps(props) {
|
|
449
|
+
return new _IFactory().addProps(props);
|
|
450
|
+
}
|
|
451
|
+
toItem() {
|
|
452
|
+
return this.item;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
// src/AItemService.ts
|
|
457
|
+
var AItemService = class {
|
|
458
|
+
pkType;
|
|
459
|
+
parentService = null;
|
|
460
|
+
constructor(pkType, parentService) {
|
|
461
|
+
this.pkType = pkType;
|
|
462
|
+
if (parentService) {
|
|
463
|
+
this.parentService = parentService;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
getPkType = () => {
|
|
467
|
+
return this.pkType;
|
|
468
|
+
};
|
|
469
|
+
getKeyTypes = () => {
|
|
470
|
+
let keyTypes = [this.getPkType()];
|
|
471
|
+
if (this.parentService) {
|
|
472
|
+
keyTypes = keyTypes.concat(this.parentService.getKeyTypes());
|
|
473
|
+
}
|
|
474
|
+
return keyTypes;
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// src/Coordinate.ts
|
|
479
|
+
var logger2 = logger_default.get("Coordinate");
|
|
480
|
+
var createCoordinate = (kta, scopes = []) => {
|
|
481
|
+
const ktArray = Array.isArray(kta) ? kta : [kta];
|
|
482
|
+
const toString = () => {
|
|
483
|
+
logger2.debug("toString", { kta, scopes });
|
|
484
|
+
return `${ktArray.join(", ")} - ${scopes.join(", ")}`;
|
|
485
|
+
};
|
|
486
|
+
logger2.debug("createCoordinate", { kta: ktArray, scopes, toString });
|
|
487
|
+
return { kta: ktArray, scopes, toString };
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// src/dictionary.ts
|
|
491
|
+
var logger3 = logger_default.get("Dictionary");
|
|
492
|
+
var Dictionary = class _Dictionary {
|
|
493
|
+
map = {};
|
|
494
|
+
hashFunction = (key) => JSON.stringify(key);
|
|
495
|
+
constructor(map, hashFunction) {
|
|
496
|
+
if (hashFunction) {
|
|
497
|
+
this.hashFunction = hashFunction;
|
|
498
|
+
}
|
|
499
|
+
if (map) {
|
|
500
|
+
Object.entries(map).forEach(([hashedKey, value]) => {
|
|
501
|
+
try {
|
|
502
|
+
const originalKey = JSON.parse(hashedKey);
|
|
503
|
+
this.map[hashedKey] = { originalKey, value };
|
|
504
|
+
} catch {
|
|
505
|
+
logger3.warning("Cannot recover original key from legacy map entry", { hashedKey });
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
set(key, item) {
|
|
511
|
+
logger3.trace("set", { key, item });
|
|
512
|
+
const hashedKey = this.hashFunction(key);
|
|
513
|
+
this.map[hashedKey] = { originalKey: key, value: item };
|
|
514
|
+
}
|
|
515
|
+
get(key) {
|
|
516
|
+
logger3.trace("get", { key });
|
|
517
|
+
const hashedKey = this.hashFunction(key);
|
|
518
|
+
const entry = this.map[hashedKey];
|
|
519
|
+
return entry && this.keysEqual(entry.originalKey, key) ? entry.value : null;
|
|
520
|
+
}
|
|
521
|
+
keysEqual(key1, key2) {
|
|
522
|
+
return key1 === key2;
|
|
523
|
+
}
|
|
524
|
+
delete(key) {
|
|
525
|
+
logger3.trace("delete", { key });
|
|
526
|
+
const hashedKey = this.hashFunction(key);
|
|
527
|
+
delete this.map[hashedKey];
|
|
528
|
+
}
|
|
529
|
+
keys() {
|
|
530
|
+
return Object.values(this.map).map((entry) => entry.originalKey);
|
|
531
|
+
}
|
|
532
|
+
values() {
|
|
533
|
+
return Object.values(this.map).map((entry) => entry.value);
|
|
534
|
+
}
|
|
535
|
+
includesKey(key) {
|
|
536
|
+
const hashedKey = this.hashFunction(key);
|
|
537
|
+
const entry = this.map[hashedKey];
|
|
538
|
+
return entry ? this.keysEqual(entry.originalKey, key) : false;
|
|
539
|
+
}
|
|
540
|
+
clone() {
|
|
541
|
+
const clonedMap = {};
|
|
542
|
+
Object.entries(this.map).forEach(([hashedKey, entry]) => {
|
|
543
|
+
clonedMap[hashedKey] = entry.value;
|
|
544
|
+
});
|
|
545
|
+
const clone = new _Dictionary(clonedMap, this.hashFunction);
|
|
546
|
+
clone.map = Object.assign({}, this.map);
|
|
547
|
+
return clone;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
// src/item/IQUtils.ts
|
|
552
|
+
import * as luxon from "luxon";
|
|
553
|
+
var logger4 = logger_default.get("IQUtils");
|
|
554
|
+
var queryToParams = (query) => {
|
|
555
|
+
const params = {};
|
|
556
|
+
if (query.compoundCondition) {
|
|
557
|
+
params.compoundCondition = JSON.stringify(query.compoundCondition);
|
|
558
|
+
}
|
|
559
|
+
if (query.refs) {
|
|
560
|
+
params.refs = JSON.stringify(query.refs);
|
|
561
|
+
}
|
|
562
|
+
if (query.limit) {
|
|
563
|
+
params.limit = query.limit;
|
|
564
|
+
}
|
|
565
|
+
if (query.offset) {
|
|
566
|
+
params.offset = query.offset;
|
|
567
|
+
}
|
|
568
|
+
if (query.aggs) {
|
|
569
|
+
params.aggs = JSON.stringify(query.aggs);
|
|
570
|
+
}
|
|
571
|
+
if (query.events) {
|
|
572
|
+
params.events = JSON.stringify(query.events);
|
|
573
|
+
}
|
|
574
|
+
if (query.orderBy) {
|
|
575
|
+
params.orderBy = JSON.stringify(query.orderBy);
|
|
576
|
+
}
|
|
577
|
+
return params;
|
|
578
|
+
};
|
|
579
|
+
var dateTimeReviver = function(key, value) {
|
|
580
|
+
if (typeof value === "string") {
|
|
581
|
+
const parsedDate = luxon.DateTime.fromISO(value);
|
|
582
|
+
if (parsedDate.isValid) {
|
|
583
|
+
return parsedDate.toJSDate();
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return value;
|
|
587
|
+
};
|
|
588
|
+
var paramsToQuery = (params) => {
|
|
589
|
+
const query = {};
|
|
590
|
+
if (params.compoundCondition) {
|
|
591
|
+
query.compoundCondition = JSON.parse(params.compoundCondition);
|
|
592
|
+
}
|
|
593
|
+
if (params.refs) {
|
|
594
|
+
query.refs = JSON.parse(params.refs);
|
|
595
|
+
}
|
|
596
|
+
if (params.limit) {
|
|
597
|
+
query.limit = Number(params.limit);
|
|
598
|
+
}
|
|
599
|
+
if (params.offset) {
|
|
600
|
+
query.offset = Number(params.offset);
|
|
601
|
+
}
|
|
602
|
+
if (params.aggs) {
|
|
603
|
+
query.aggs = JSON.parse(params.aggs);
|
|
604
|
+
}
|
|
605
|
+
if (params.events) {
|
|
606
|
+
query.events = JSON.parse(params.events, dateTimeReviver);
|
|
610
607
|
}
|
|
611
608
|
if (params.orderBy) {
|
|
612
609
|
query.orderBy = JSON.parse(params.orderBy);
|
|
@@ -816,115 +813,6 @@ var abbrevCondition = (condition) => {
|
|
|
816
813
|
}
|
|
817
814
|
};
|
|
818
815
|
|
|
819
|
-
// src/validation/ItemValidator.ts
|
|
820
|
-
var logger5 = logger_default.get("validation", "ItemValidator");
|
|
821
|
-
var validatePKForItem = (item, pkType) => {
|
|
822
|
-
if (!item) {
|
|
823
|
-
logger5.error("Item validation failed - item is undefined", {
|
|
824
|
-
component: "core",
|
|
825
|
-
operation: "validatePK",
|
|
826
|
-
expectedType: pkType,
|
|
827
|
-
item,
|
|
828
|
-
suggestion: "Ensure the operation returns a valid item object, not undefined/null"
|
|
829
|
-
});
|
|
830
|
-
throw new Error(
|
|
831
|
-
`Item validation failed: item is undefined. Expected item of type '${pkType}'. This usually indicates a database operation returned null/undefined unexpectedly.`
|
|
832
|
-
);
|
|
833
|
-
}
|
|
834
|
-
if (!item.key) {
|
|
835
|
-
logger5.error("Item validation failed - item missing key", {
|
|
836
|
-
component: "core",
|
|
837
|
-
operation: "validatePK",
|
|
838
|
-
expectedType: pkType,
|
|
839
|
-
item,
|
|
840
|
-
suggestion: "Ensure the item has a valid key property with kt and pk fields"
|
|
841
|
-
});
|
|
842
|
-
throw new Error(
|
|
843
|
-
`Item validation failed: item does not have a key property. Expected key with type '${pkType}'. Item: ${JSON.stringify(item)}. This indicates a database processing error.`
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
const keyTypeArray = toKeyTypeArray(item.key);
|
|
847
|
-
if (keyTypeArray[0] !== pkType) {
|
|
848
|
-
logger5.error("Key type mismatch during validation", {
|
|
849
|
-
component: "core",
|
|
850
|
-
operation: "validatePK",
|
|
851
|
-
expectedType: pkType,
|
|
852
|
-
actualType: keyTypeArray[0],
|
|
853
|
-
keyTypeArray,
|
|
854
|
-
itemKey: item.key,
|
|
855
|
-
suggestion: `Ensure the item key has kt: '${pkType}', not '${keyTypeArray[0]}'`
|
|
856
|
-
});
|
|
857
|
-
throw new Error(
|
|
858
|
-
`Item has incorrect primary key type. Expected '${pkType}', got '${keyTypeArray[0]}'. Key: ${JSON.stringify(item.key)}. This indicates a data model mismatch.`
|
|
859
|
-
);
|
|
860
|
-
}
|
|
861
|
-
return item;
|
|
862
|
-
};
|
|
863
|
-
var validatePK = (input, pkType) => {
|
|
864
|
-
logger5.trace("Checking Return Type", { input });
|
|
865
|
-
if (Array.isArray(input)) {
|
|
866
|
-
return input.map((item) => validatePKForItem(item, pkType));
|
|
867
|
-
}
|
|
868
|
-
return validatePKForItem(input, pkType);
|
|
869
|
-
};
|
|
870
|
-
var validateKeys = (item, keyTypes) => {
|
|
871
|
-
logger5.trace("Checking Return Type", { item });
|
|
872
|
-
if (!item) {
|
|
873
|
-
logger5.error("Key validation failed - item is undefined", {
|
|
874
|
-
component: "core",
|
|
875
|
-
operation: "validateKeys",
|
|
876
|
-
expectedKeyTypes: keyTypes,
|
|
877
|
-
suggestion: "Ensure the operation returns a valid item object, not undefined/null"
|
|
878
|
-
});
|
|
879
|
-
throw new Error(
|
|
880
|
-
`Key validation failed: item is undefined. Expected item with key types [${keyTypes.join(", ")}]. This usually indicates a database operation returned null/undefined unexpectedly.`
|
|
881
|
-
);
|
|
882
|
-
}
|
|
883
|
-
if (!item.key) {
|
|
884
|
-
logger5.error("Key validation failed - item missing key", {
|
|
885
|
-
component: "core",
|
|
886
|
-
operation: "validateKeys",
|
|
887
|
-
expectedKeyTypes: keyTypes,
|
|
888
|
-
item: JSON.stringify(item),
|
|
889
|
-
suggestion: "Ensure the item has a valid key property"
|
|
890
|
-
});
|
|
891
|
-
throw new Error(
|
|
892
|
-
`Key validation failed: item does not have a key property. Expected key with types [${keyTypes.join(", ")}]. Item: ${JSON.stringify(item)}. This indicates a database processing error.`
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
const keyTypeArray = toKeyTypeArray(item.key);
|
|
896
|
-
if (keyTypeArray.length !== keyTypes.length) {
|
|
897
|
-
logger5.error("Key hierarchy depth mismatch", {
|
|
898
|
-
component: "core",
|
|
899
|
-
operation: "validateKeys",
|
|
900
|
-
expectedKeyTypes: keyTypes,
|
|
901
|
-
expectedDepth: keyTypes.length,
|
|
902
|
-
actualKeyTypes: keyTypeArray,
|
|
903
|
-
actualDepth: keyTypeArray.length,
|
|
904
|
-
itemKey: item.key,
|
|
905
|
-
suggestion: `Check coordinate definition. Expected hierarchy depth of ${keyTypes.length}, got ${keyTypeArray.length}`
|
|
906
|
-
});
|
|
907
|
-
throw new Error(
|
|
908
|
-
`Item has incorrect key hierarchy depth. Expected ${keyTypes.length} levels [${keyTypes.join(" > ")}], but got ${keyTypeArray.length} levels [${keyTypeArray.join(" > ")}]. Key: ${JSON.stringify(item.key)}. This indicates a coordinate/hierarchy mismatch.`
|
|
909
|
-
);
|
|
910
|
-
}
|
|
911
|
-
const match = JSON.stringify(keyTypeArray) === JSON.stringify(keyTypes);
|
|
912
|
-
if (!match) {
|
|
913
|
-
logger5.error("Key Type Array Mismatch", {
|
|
914
|
-
component: "core",
|
|
915
|
-
operation: "validateKeys",
|
|
916
|
-
expectedKeyTypes: keyTypes,
|
|
917
|
-
actualKeyTypes: keyTypeArray,
|
|
918
|
-
itemKey: item.key,
|
|
919
|
-
suggestion: `Ensure item key matches expected hierarchy: [${keyTypes.join(" > ")}]`
|
|
920
|
-
});
|
|
921
|
-
throw new Error(
|
|
922
|
-
`Item has incorrect key types. Expected [${keyTypes.join(" > ")}], but got [${keyTypeArray.join(" > ")}]. Key: ${JSON.stringify(item.key)}. This indicates a data model mismatch.`
|
|
923
|
-
);
|
|
924
|
-
}
|
|
925
|
-
return item;
|
|
926
|
-
};
|
|
927
|
-
|
|
928
816
|
// src/item/IUtils.ts
|
|
929
817
|
var isPriItem = (item) => {
|
|
930
818
|
return !!(item && item.key && isPriKey(item.key));
|
|
@@ -933,173 +821,430 @@ var isComItem = (item) => {
|
|
|
933
821
|
return !!(item && item.key && isComKey(item.key));
|
|
934
822
|
};
|
|
935
823
|
|
|
936
|
-
// src/
|
|
937
|
-
var
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
824
|
+
// src/errors/ActionError.ts
|
|
825
|
+
var ActionError = class extends Error {
|
|
826
|
+
constructor(errorInfo, cause) {
|
|
827
|
+
super(errorInfo.message);
|
|
828
|
+
this.errorInfo = errorInfo;
|
|
829
|
+
this.name = "ActionError";
|
|
830
|
+
this.cause = cause;
|
|
831
|
+
if (!this.errorInfo.technical) {
|
|
832
|
+
this.errorInfo.technical = { timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
833
|
+
}
|
|
834
|
+
if (!this.errorInfo.technical.timestamp) {
|
|
835
|
+
this.errorInfo.technical.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
836
|
+
}
|
|
941
837
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
const actualLocationTypes = locations.map((loc) => loc.kt);
|
|
945
|
-
logger6.debug(`Validating locations for ${operation}`, {
|
|
946
|
-
expected: expectedLocationTypes,
|
|
947
|
-
actual: actualLocationTypes,
|
|
948
|
-
coordinate: keyTypeArray
|
|
949
|
-
});
|
|
950
|
-
if (actualLocationTypes.length > expectedLocationTypes.length) {
|
|
951
|
-
logger6.error("Location key array has too many elements", {
|
|
952
|
-
expected: expectedLocationTypes.length,
|
|
953
|
-
actual: actualLocationTypes.length,
|
|
954
|
-
expectedTypes: expectedLocationTypes,
|
|
955
|
-
actualTypes: actualLocationTypes,
|
|
956
|
-
coordinate,
|
|
957
|
-
operation
|
|
958
|
-
});
|
|
959
|
-
throw new Error(
|
|
960
|
-
`Invalid location key array for ${operation}: Expected at most ${expectedLocationTypes.length} location keys (hierarchy: [${expectedLocationTypes.join(", ")}]), but received ${actualLocationTypes.length} (types: [${actualLocationTypes.join(", ")}])`
|
|
961
|
-
);
|
|
838
|
+
toJSON() {
|
|
839
|
+
return this.errorInfo;
|
|
962
840
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// src/errors/ValidationError.ts
|
|
844
|
+
var ValidationError = class extends ActionError {
|
|
845
|
+
fieldErrors;
|
|
846
|
+
constructor(message, validOptions, suggestedAction, conflictingValue, fieldErrors) {
|
|
847
|
+
super({
|
|
848
|
+
code: "VALIDATION_ERROR",
|
|
849
|
+
message,
|
|
850
|
+
operation: { type: "create", name: "", params: {} },
|
|
851
|
+
// Will be filled by wrapper
|
|
852
|
+
context: { itemType: "" },
|
|
853
|
+
// Will be filled by wrapper
|
|
854
|
+
details: {
|
|
855
|
+
validOptions,
|
|
856
|
+
suggestedAction: suggestedAction || (validOptions && validOptions.length > 0 ? `Valid options are: ${validOptions.join(", ")}. Please use one of these values.` : "Check the validation requirements and ensure all fields meet the required format, type, and constraints."),
|
|
857
|
+
retryable: true,
|
|
858
|
+
conflictingValue,
|
|
859
|
+
fieldErrors
|
|
860
|
+
},
|
|
861
|
+
technical: {
|
|
862
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
this.fieldErrors = fieldErrors;
|
|
866
|
+
if (fieldErrors) {
|
|
867
|
+
if (!this.errorInfo.details) this.errorInfo.details = {};
|
|
868
|
+
this.errorInfo.details.fieldErrors = fieldErrors;
|
|
977
869
|
}
|
|
978
870
|
}
|
|
979
|
-
logger6.debug(`Location key array validation passed for ${operation}`, { locations });
|
|
980
871
|
};
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
872
|
+
|
|
873
|
+
// src/errors/NotFoundError.ts
|
|
874
|
+
var NotFoundError = class extends ActionError {
|
|
875
|
+
constructor(message, itemType, key) {
|
|
876
|
+
super({
|
|
877
|
+
code: "NOT_FOUND",
|
|
878
|
+
message,
|
|
879
|
+
operation: { type: "get", name: "", params: {} },
|
|
880
|
+
context: {
|
|
881
|
+
itemType,
|
|
882
|
+
key: typeof key === "object" ? key : { primary: key }
|
|
883
|
+
},
|
|
884
|
+
details: {
|
|
885
|
+
suggestedAction: "Verify the item ID/key is correct, check if the item was deleted, or create the item if it should exist.",
|
|
886
|
+
retryable: false
|
|
887
|
+
},
|
|
888
|
+
technical: {
|
|
889
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
this.name = "NotFoundError";
|
|
990
893
|
}
|
|
991
894
|
};
|
|
992
895
|
|
|
993
|
-
// src/
|
|
994
|
-
var
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
896
|
+
// src/errors/BusinessLogicError.ts
|
|
897
|
+
var BusinessLogicError = class extends ActionError {
|
|
898
|
+
constructor(message, suggestedAction, retryable = false) {
|
|
899
|
+
super({
|
|
900
|
+
code: "BUSINESS_LOGIC_ERROR",
|
|
901
|
+
message,
|
|
902
|
+
operation: { type: "action", name: "", params: {} },
|
|
903
|
+
context: { itemType: "" },
|
|
904
|
+
details: {
|
|
905
|
+
suggestedAction: suggestedAction || "Review the business logic requirements and ensure all conditions are met before retrying.",
|
|
906
|
+
retryable
|
|
907
|
+
},
|
|
908
|
+
technical: {
|
|
909
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
910
|
+
}
|
|
1006
911
|
});
|
|
1007
|
-
const expectedOrder = expectedLocationTypes.map(
|
|
1008
|
-
(kt, i) => ` [${i}] { kt: '${kt}', lk: <value> }`
|
|
1009
|
-
).join("\n");
|
|
1010
|
-
const actualOrder = key.loc.map(
|
|
1011
|
-
(loc, i) => ` [${i}] { kt: '${loc.kt}', lk: ${JSON.stringify(loc.lk)} }`
|
|
1012
|
-
).join("\n");
|
|
1013
|
-
throw new Error(
|
|
1014
|
-
`Location key array length mismatch for ${operation} operation.
|
|
1015
|
-
|
|
1016
|
-
Expected ${expectedLocationTypes.length} location keys but received ${actualLocationTypes.length}.
|
|
1017
|
-
|
|
1018
|
-
Expected location key order for '${keyTypeArray[0]}':
|
|
1019
|
-
${expectedOrder}
|
|
1020
|
-
|
|
1021
|
-
Received location key order:
|
|
1022
|
-
${actualOrder}`
|
|
1023
|
-
);
|
|
1024
912
|
}
|
|
1025
|
-
|
|
1026
|
-
if (expectedLocationTypes[i] !== actualLocationTypes[i]) {
|
|
1027
|
-
logger7.error("Location key array order mismatch", {
|
|
1028
|
-
position: i,
|
|
1029
|
-
expected: expectedLocationTypes[i],
|
|
1030
|
-
actual: actualLocationTypes[i],
|
|
1031
|
-
key,
|
|
1032
|
-
coordinate,
|
|
1033
|
-
operation
|
|
1034
|
-
});
|
|
1035
|
-
const expectedOrder = expectedLocationTypes.map(
|
|
1036
|
-
(kt, i2) => ` [${i2}] { kt: '${kt}', lk: <value> }`
|
|
1037
|
-
).join("\n");
|
|
1038
|
-
const actualOrder = key.loc.map(
|
|
1039
|
-
(loc, i2) => ` [${i2}] { kt: '${loc.kt}', lk: ${JSON.stringify(loc.lk)} }`
|
|
1040
|
-
).join("\n");
|
|
1041
|
-
throw new Error(
|
|
1042
|
-
`Location key array order mismatch for ${operation} operation.
|
|
1043
|
-
|
|
1044
|
-
At position ${i}, expected key type "${expectedLocationTypes[i]}" but received "${actualLocationTypes[i]}".
|
|
1045
|
-
|
|
1046
|
-
Expected location key order for '${keyTypeArray[0]}':
|
|
1047
|
-
${expectedOrder}
|
|
1048
|
-
|
|
1049
|
-
Received location key order:
|
|
1050
|
-
${actualOrder}
|
|
913
|
+
};
|
|
1051
914
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
915
|
+
// src/errors/PermissionError.ts
|
|
916
|
+
var PermissionError = class extends ActionError {
|
|
917
|
+
constructor(message, requiredPermission, currentPermissions) {
|
|
918
|
+
super({
|
|
919
|
+
code: "PERMISSION_DENIED",
|
|
920
|
+
message,
|
|
921
|
+
operation: { type: "action", name: "", params: {} },
|
|
922
|
+
context: {
|
|
923
|
+
itemType: "",
|
|
924
|
+
...requiredPermission && { requiredPermission }
|
|
925
|
+
},
|
|
926
|
+
details: {
|
|
927
|
+
...requiredPermission && {
|
|
928
|
+
suggestedAction: `Required permission: ${requiredPermission}`,
|
|
929
|
+
expectedValue: requiredPermission
|
|
930
|
+
},
|
|
931
|
+
...currentPermissions && { conflictingValue: currentPermissions },
|
|
932
|
+
retryable: false
|
|
933
|
+
},
|
|
934
|
+
technical: {
|
|
935
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
936
|
+
}
|
|
937
|
+
});
|
|
1055
938
|
}
|
|
1056
939
|
};
|
|
1057
|
-
var validateKey = (key, coordinate, operation) => {
|
|
1058
|
-
logger7.debug(`Validating key for ${operation}`, { key, coordinate: coordinate.kta });
|
|
1059
|
-
if (!key || key === null) {
|
|
1060
|
-
throw new Error(
|
|
1061
|
-
`Invalid key structure for ${operation} operation.
|
|
1062
940
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
)
|
|
941
|
+
// src/errors/DuplicateError.ts
|
|
942
|
+
var DuplicateError = class extends ActionError {
|
|
943
|
+
constructor(message, existingItemIdOrKey, duplicateField) {
|
|
944
|
+
let existingItemId = null;
|
|
945
|
+
let keyInfo = null;
|
|
946
|
+
if (typeof existingItemIdOrKey === "object" && existingItemIdOrKey !== null) {
|
|
947
|
+
existingItemId = existingItemIdOrKey.pk || existingItemIdOrKey.id || existingItemIdOrKey.primary || null;
|
|
948
|
+
if (existingItemId !== null) {
|
|
949
|
+
keyInfo = {
|
|
950
|
+
primary: existingItemId,
|
|
951
|
+
...existingItemIdOrKey
|
|
952
|
+
};
|
|
953
|
+
} else {
|
|
954
|
+
keyInfo = existingItemIdOrKey;
|
|
955
|
+
}
|
|
956
|
+
} else if (typeof existingItemIdOrKey !== "undefined") {
|
|
957
|
+
existingItemId = existingItemIdOrKey;
|
|
958
|
+
keyInfo = { primary: existingItemId };
|
|
959
|
+
}
|
|
960
|
+
super({
|
|
961
|
+
code: "DUPLICATE_ERROR",
|
|
962
|
+
message,
|
|
963
|
+
operation: { type: "create", name: "", params: {} },
|
|
964
|
+
context: {
|
|
965
|
+
itemType: "",
|
|
966
|
+
...keyInfo && { key: keyInfo },
|
|
967
|
+
...existingItemId && {
|
|
968
|
+
affectedItems: [{
|
|
969
|
+
id: existingItemId,
|
|
970
|
+
type: "",
|
|
971
|
+
displayName: `Existing item with ${duplicateField || "key"}`
|
|
972
|
+
}]
|
|
973
|
+
}
|
|
974
|
+
},
|
|
975
|
+
details: {
|
|
976
|
+
suggestedAction: duplicateField ? `An item with this ${duplicateField} already exists. Use a different ${duplicateField} value or update the existing item.` : "An item with this key already exists. Use a different key or update the existing item using upsert.",
|
|
977
|
+
retryable: false,
|
|
978
|
+
conflictingValue: duplicateField
|
|
979
|
+
},
|
|
980
|
+
technical: {
|
|
981
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
982
|
+
}
|
|
983
|
+
});
|
|
1069
984
|
}
|
|
1070
|
-
|
|
1071
|
-
const keyIsComposite = isComKey(key);
|
|
1072
|
-
const keyIsPrimary = isPriKey(key);
|
|
1073
|
-
if (isCompositeLibrary && !keyIsComposite) {
|
|
1074
|
-
logger7.error(`Composite library received primary key in ${operation}`, { key, coordinate });
|
|
1075
|
-
const keyTypeArray = coordinate.kta;
|
|
1076
|
-
throw new Error(
|
|
1077
|
-
`Invalid key type for ${operation} operation.
|
|
1078
|
-
|
|
1079
|
-
This is a composite item library. You must provide a ComKey with location keys.
|
|
985
|
+
};
|
|
1080
986
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
]
|
|
987
|
+
// src/operations/errorEnhancer.ts
|
|
988
|
+
async function executeWithContext(operation, context) {
|
|
989
|
+
try {
|
|
990
|
+
return await operation();
|
|
991
|
+
} catch (error) {
|
|
992
|
+
throw enhanceError(error, context);
|
|
1088
993
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
kt: '${keyTypeArray[0]}',
|
|
1096
|
-
pk: 'item-id',
|
|
1097
|
-
loc: [${keyTypeArray.slice(1).map((kt) => `{ kt: '${kt}', lk: 'parent-id' }`).join(", ")}]
|
|
1098
|
-
})`
|
|
1099
|
-
);
|
|
994
|
+
}
|
|
995
|
+
function executeWithContextSync(operation, context) {
|
|
996
|
+
try {
|
|
997
|
+
return operation();
|
|
998
|
+
} catch (error) {
|
|
999
|
+
throw enhanceError(error, context);
|
|
1100
1000
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1001
|
+
}
|
|
1002
|
+
function enhanceError(error, context) {
|
|
1003
|
+
if (!(error instanceof ActionError)) {
|
|
1004
|
+
return error;
|
|
1005
|
+
}
|
|
1006
|
+
error.errorInfo.operation = {
|
|
1007
|
+
type: context.operationType,
|
|
1008
|
+
name: context.operationName,
|
|
1009
|
+
params: context.params
|
|
1010
|
+
};
|
|
1011
|
+
if (!error.errorInfo.context.itemType) {
|
|
1012
|
+
error.errorInfo.context.itemType = context.itemType;
|
|
1013
|
+
}
|
|
1014
|
+
if (context.key) {
|
|
1015
|
+
const existingKey = error.errorInfo.context.key;
|
|
1016
|
+
const hasNoPrimaryKey = !existingKey || typeof existingKey.primary === "undefined";
|
|
1017
|
+
const hasNoCompositeKey = !existingKey || !existingKey.composite;
|
|
1018
|
+
const shouldOverride = hasNoPrimaryKey && hasNoCompositeKey;
|
|
1019
|
+
if (shouldOverride) {
|
|
1020
|
+
error.errorInfo.context.key = extractKeyInfo(context.key);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (context.locations && context.locations.length > 0 && !error.errorInfo.context.parentLocation) {
|
|
1024
|
+
error.errorInfo.context.parentLocation = {
|
|
1025
|
+
id: context.locations[0].lk,
|
|
1026
|
+
type: context.locations[0].kt
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
return error;
|
|
1030
|
+
}
|
|
1031
|
+
function extractKeyInfo(key) {
|
|
1032
|
+
if ("loc" in key) {
|
|
1033
|
+
const ktaArray = Array.isArray(key.kt) ? key.kt : [key.kt];
|
|
1034
|
+
const locations = Array.isArray(key.loc) ? key.loc : [];
|
|
1035
|
+
return {
|
|
1036
|
+
composite: {
|
|
1037
|
+
sk: key.pk,
|
|
1038
|
+
kta: ktaArray,
|
|
1039
|
+
locations: locations.map((loc) => ({
|
|
1040
|
+
lk: loc.lk,
|
|
1041
|
+
kt: loc.kt
|
|
1042
|
+
}))
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
} else if ("pk" in key) {
|
|
1046
|
+
return { primary: key.pk };
|
|
1047
|
+
}
|
|
1048
|
+
return { primary: JSON.stringify(key) };
|
|
1049
|
+
}
|
|
1050
|
+
function isActionError(error) {
|
|
1051
|
+
return error instanceof ActionError;
|
|
1052
|
+
}
|
|
1053
|
+
function getErrorInfo(error) {
|
|
1054
|
+
if (isActionError(error)) {
|
|
1055
|
+
return error.toJSON();
|
|
1056
|
+
}
|
|
1057
|
+
if (error instanceof Error) {
|
|
1058
|
+
return {
|
|
1059
|
+
code: "UNKNOWN_ERROR",
|
|
1060
|
+
message: error.message,
|
|
1061
|
+
technical: {
|
|
1062
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1063
|
+
stackTrace: error.stack
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
return {
|
|
1068
|
+
code: "UNKNOWN_ERROR",
|
|
1069
|
+
message: String(error),
|
|
1070
|
+
technical: {
|
|
1071
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// node_modules/@fjell/validation/dist/index.js
|
|
1077
|
+
import Logging2 from "@fjell/logging";
|
|
1078
|
+
import Logging22 from "@fjell/logging";
|
|
1079
|
+
import Logging3 from "@fjell/logging";
|
|
1080
|
+
import Logging4 from "@fjell/logging";
|
|
1081
|
+
var logger5 = Logging2.getLogger("validation.LocationValidator");
|
|
1082
|
+
var validateLocations = (locations, coordinate, operation) => {
|
|
1083
|
+
if (!locations || locations.length === 0) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
const keyTypeArray = coordinate.kta;
|
|
1087
|
+
const expectedLocationTypes = keyTypeArray.slice(1);
|
|
1088
|
+
const actualLocationTypes = locations.map((loc) => loc.kt);
|
|
1089
|
+
logger5.debug(`Validating locations for ${operation}`, {
|
|
1090
|
+
expected: expectedLocationTypes,
|
|
1091
|
+
actual: actualLocationTypes,
|
|
1092
|
+
coordinate: keyTypeArray
|
|
1093
|
+
});
|
|
1094
|
+
if (actualLocationTypes.length > expectedLocationTypes.length) {
|
|
1095
|
+
logger5.error("Location key array has too many elements", {
|
|
1096
|
+
expected: expectedLocationTypes.length,
|
|
1097
|
+
actual: actualLocationTypes.length,
|
|
1098
|
+
expectedTypes: expectedLocationTypes,
|
|
1099
|
+
actualTypes: actualLocationTypes,
|
|
1100
|
+
coordinate,
|
|
1101
|
+
operation
|
|
1102
|
+
});
|
|
1103
|
+
throw new Error(
|
|
1104
|
+
`Invalid location key array for ${operation}: Expected at most ${expectedLocationTypes.length} location keys (hierarchy: [${expectedLocationTypes.join(", ")}]), but received ${actualLocationTypes.length} (types: [${actualLocationTypes.join(", ")}])`
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
for (let i = 0; i < actualLocationTypes.length; i++) {
|
|
1108
|
+
if (expectedLocationTypes[i] !== actualLocationTypes[i]) {
|
|
1109
|
+
logger5.error("Location key array order mismatch", {
|
|
1110
|
+
position: i,
|
|
1111
|
+
expected: expectedLocationTypes[i],
|
|
1112
|
+
actual: actualLocationTypes[i],
|
|
1113
|
+
expectedHierarchy: expectedLocationTypes,
|
|
1114
|
+
actualOrder: actualLocationTypes,
|
|
1115
|
+
coordinate,
|
|
1116
|
+
operation
|
|
1117
|
+
});
|
|
1118
|
+
throw new Error(
|
|
1119
|
+
`Invalid location key array order for ${operation}: At position ${i}, expected key type "${expectedLocationTypes[i]}" but received "${actualLocationTypes[i]}". Location keys must be ordered according to the hierarchy: [${expectedLocationTypes.join(", ")}]. Received order: [${actualLocationTypes.join(", ")}]`
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
logger5.debug(`Location key array validation passed for ${operation}`, { locations });
|
|
1124
|
+
};
|
|
1125
|
+
var isComKey3 = (key) => {
|
|
1126
|
+
return typeof key !== "undefined" && (typeof key.pk !== "undefined" && typeof key.kt !== "undefined") && (typeof key.loc !== "undefined" && Array.isArray(key.loc));
|
|
1127
|
+
};
|
|
1128
|
+
var isPriKey3 = (key) => {
|
|
1129
|
+
return typeof key !== "undefined" && (typeof key.pk !== "undefined" && typeof key.kt !== "undefined") && typeof key.loc === "undefined";
|
|
1130
|
+
};
|
|
1131
|
+
var toKeyTypeArray2 = (ik) => {
|
|
1132
|
+
if (isComKey3(ik)) {
|
|
1133
|
+
const ck = ik;
|
|
1134
|
+
return [ck.kt, ...ck.loc.map((l) => l.kt)];
|
|
1135
|
+
} else {
|
|
1136
|
+
return [ik.kt];
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
var logger22 = Logging22.getLogger("validation.KeyValidator");
|
|
1140
|
+
var validateLocationKeyOrder = (key, coordinate, operation) => {
|
|
1141
|
+
const keyTypeArray = coordinate.kta;
|
|
1142
|
+
const expectedLocationTypes = keyTypeArray.slice(1);
|
|
1143
|
+
const actualLocationTypes = key.loc.map((loc) => loc.kt);
|
|
1144
|
+
if (expectedLocationTypes.length !== actualLocationTypes.length) {
|
|
1145
|
+
logger22.error("Location key array length mismatch", {
|
|
1146
|
+
expected: expectedLocationTypes.length,
|
|
1147
|
+
actual: actualLocationTypes.length,
|
|
1148
|
+
key,
|
|
1149
|
+
coordinate,
|
|
1150
|
+
operation
|
|
1151
|
+
});
|
|
1152
|
+
const expectedOrder = expectedLocationTypes.map(
|
|
1153
|
+
(kt, i) => ` [${i}] { kt: '${kt}', lk: <value> }`
|
|
1154
|
+
).join("\n");
|
|
1155
|
+
const actualOrder = key.loc.map(
|
|
1156
|
+
(loc, i) => ` [${i}] { kt: '${loc.kt}', lk: ${JSON.stringify(loc.lk)} }`
|
|
1157
|
+
).join("\n");
|
|
1158
|
+
throw new Error(
|
|
1159
|
+
`Location key array length mismatch for ${operation} operation.
|
|
1160
|
+
|
|
1161
|
+
Expected ${expectedLocationTypes.length} location keys but received ${actualLocationTypes.length}.
|
|
1162
|
+
|
|
1163
|
+
Expected location key order for '${keyTypeArray[0]}':
|
|
1164
|
+
${expectedOrder}
|
|
1165
|
+
|
|
1166
|
+
Received location key order:
|
|
1167
|
+
${actualOrder}`
|
|
1168
|
+
);
|
|
1169
|
+
}
|
|
1170
|
+
for (let i = 0; i < expectedLocationTypes.length; i++) {
|
|
1171
|
+
if (expectedLocationTypes[i] !== actualLocationTypes[i]) {
|
|
1172
|
+
logger22.error("Location key array order mismatch", {
|
|
1173
|
+
position: i,
|
|
1174
|
+
expected: expectedLocationTypes[i],
|
|
1175
|
+
actual: actualLocationTypes[i],
|
|
1176
|
+
key,
|
|
1177
|
+
coordinate,
|
|
1178
|
+
operation
|
|
1179
|
+
});
|
|
1180
|
+
const expectedOrder = expectedLocationTypes.map(
|
|
1181
|
+
(kt, i2) => ` [${i2}] { kt: '${kt}', lk: <value> }`
|
|
1182
|
+
).join("\n");
|
|
1183
|
+
const actualOrder = key.loc.map(
|
|
1184
|
+
(loc, i2) => ` [${i2}] { kt: '${loc.kt}', lk: ${JSON.stringify(loc.lk)} }`
|
|
1185
|
+
).join("\n");
|
|
1186
|
+
throw new Error(
|
|
1187
|
+
`Location key array order mismatch for ${operation} operation.
|
|
1188
|
+
|
|
1189
|
+
At position ${i}, expected key type "${expectedLocationTypes[i]}" but received "${actualLocationTypes[i]}".
|
|
1190
|
+
|
|
1191
|
+
Expected location key order for '${keyTypeArray[0]}':
|
|
1192
|
+
${expectedOrder}
|
|
1193
|
+
|
|
1194
|
+
Received location key order:
|
|
1195
|
+
${actualOrder}
|
|
1196
|
+
|
|
1197
|
+
Tip: Location keys must be ordered according to the hierarchy: [${expectedLocationTypes.join(", ")}]`
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
var validateKey = (key, coordinate, operation) => {
|
|
1203
|
+
logger22.debug(`Validating key for ${operation}`, { key, coordinate: coordinate.kta });
|
|
1204
|
+
if (!key || key === null) {
|
|
1205
|
+
throw new Error(
|
|
1206
|
+
`Invalid key structure for ${operation} operation.
|
|
1207
|
+
|
|
1208
|
+
The provided key is null or undefined.
|
|
1209
|
+
|
|
1210
|
+
Valid key formats:
|
|
1211
|
+
PriKey: { kt: string, pk: string|number }
|
|
1212
|
+
ComKey: { kt: string, pk: string|number, loc: Array<{ kt: string, lk: string|number }> }`
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
const isCompositeLibrary = coordinate.kta.length > 1;
|
|
1216
|
+
const keyIsComposite = isComKey3(key);
|
|
1217
|
+
const keyIsPrimary = isPriKey3(key);
|
|
1218
|
+
if (isCompositeLibrary && !keyIsComposite) {
|
|
1219
|
+
logger22.error(`Composite library received primary key in ${operation}`, { key, coordinate });
|
|
1220
|
+
const keyTypeArray = coordinate.kta;
|
|
1221
|
+
throw new Error(
|
|
1222
|
+
`Invalid key type for ${operation} operation.
|
|
1223
|
+
|
|
1224
|
+
This is a composite item library. You must provide a ComKey with location keys.
|
|
1225
|
+
|
|
1226
|
+
Expected: ComKey with format:
|
|
1227
|
+
{
|
|
1228
|
+
kt: '${keyTypeArray[0]}',
|
|
1229
|
+
pk: string|number,
|
|
1230
|
+
loc: [
|
|
1231
|
+
` + keyTypeArray.slice(1).map((kt) => ` { kt: '${kt}', lk: string|number }`).join(",\n") + `
|
|
1232
|
+
]
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
Received: PriKey with format:
|
|
1236
|
+
${JSON.stringify(key, null, 2)}
|
|
1237
|
+
|
|
1238
|
+
Example correct usage:
|
|
1239
|
+
library.operations.${operation}({
|
|
1240
|
+
kt: '${keyTypeArray[0]}',
|
|
1241
|
+
pk: 'item-id',
|
|
1242
|
+
loc: [${keyTypeArray.slice(1).map((kt) => `{ kt: '${kt}', lk: 'parent-id' }`).join(", ")}]
|
|
1243
|
+
})`
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
if (!isCompositeLibrary && keyIsComposite) {
|
|
1247
|
+
logger22.error(`Primary library received composite key in ${operation}`, { key, coordinate });
|
|
1103
1248
|
const keyTypeArray = coordinate.kta;
|
|
1104
1249
|
throw new Error(
|
|
1105
1250
|
`Invalid key type for ${operation} operation.
|
|
@@ -1117,7 +1262,7 @@ Example correct usage:
|
|
|
1117
1262
|
);
|
|
1118
1263
|
}
|
|
1119
1264
|
if (!keyIsPrimary && !keyIsComposite) {
|
|
1120
|
-
|
|
1265
|
+
logger22.error(`Invalid key structure in ${operation}`, { key, coordinate });
|
|
1121
1266
|
throw new Error(
|
|
1122
1267
|
`Invalid key structure for ${operation} operation.
|
|
1123
1268
|
|
|
@@ -1133,7 +1278,7 @@ Valid key formats:
|
|
|
1133
1278
|
}
|
|
1134
1279
|
const expectedKeyType = coordinate.kta[0];
|
|
1135
1280
|
if (key.kt !== expectedKeyType) {
|
|
1136
|
-
|
|
1281
|
+
logger22.error(`Key type mismatch in ${operation}`, {
|
|
1137
1282
|
expected: expectedKeyType,
|
|
1138
1283
|
received: key.kt,
|
|
1139
1284
|
key,
|
|
@@ -1152,754 +1297,218 @@ Example correct usage:
|
|
|
1152
1297
|
if (keyIsComposite) {
|
|
1153
1298
|
const comKey = key;
|
|
1154
1299
|
if (comKey.loc.length === 0) {
|
|
1155
|
-
|
|
1300
|
+
logger22.debug(`Empty loc array detected in ${operation} - will search across all locations`, { key });
|
|
1156
1301
|
} else {
|
|
1157
1302
|
validateLocationKeyOrder(comKey, coordinate, operation);
|
|
1158
1303
|
}
|
|
1159
1304
|
}
|
|
1160
|
-
|
|
1161
|
-
};
|
|
1162
|
-
var validatePriKey = (key, expectedType, operation) => {
|
|
1163
|
-
if (!key || key === null) {
|
|
1164
|
-
throw new Error(`[${operation}] PriKey is undefined or null`);
|
|
1165
|
-
}
|
|
1166
|
-
if (!key.kt) {
|
|
1167
|
-
throw new Error(`[${operation}] PriKey is missing 'kt' field`);
|
|
1168
|
-
}
|
|
1169
|
-
if (key.kt !== expectedType) {
|
|
1170
|
-
throw new Error(
|
|
1171
|
-
`[${operation}] PriKey has incorrect type.
|
|
1172
|
-
Expected: '${expectedType}'
|
|
1173
|
-
Received: '${key.kt}'`
|
|
1174
|
-
);
|
|
1175
|
-
}
|
|
1176
|
-
if (typeof key.pk === "undefined" || key.pk === null) {
|
|
1177
|
-
throw new Error(`[${operation}] PriKey is missing 'pk' field`);
|
|
1178
|
-
}
|
|
1305
|
+
logger22.debug(`Key validation passed for ${operation}`, { key });
|
|
1179
1306
|
};
|
|
1180
|
-
var
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1307
|
+
var logger32 = Logging3.getLogger("validation.ItemValidator");
|
|
1308
|
+
var validatePKForItem = (item, pkType) => {
|
|
1309
|
+
if (!item) {
|
|
1310
|
+
logger32.error("Item validation failed - item is undefined", {
|
|
1311
|
+
component: "core",
|
|
1312
|
+
operation: "validatePK",
|
|
1313
|
+
expectedType: pkType,
|
|
1314
|
+
item,
|
|
1315
|
+
suggestion: "Ensure the operation returns a valid item object, not undefined/null"
|
|
1316
|
+
});
|
|
1188
1317
|
throw new Error(
|
|
1189
|
-
`
|
|
1190
|
-
Expected: '${coordinate.kta[0]}'
|
|
1191
|
-
Received: '${key.kt}'`
|
|
1318
|
+
`Item validation failed: item is undefined. Expected item of type '${pkType}'. This usually indicates a database operation returned null/undefined unexpectedly.`
|
|
1192
1319
|
);
|
|
1193
1320
|
}
|
|
1194
|
-
if (
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
validateLocationKeyOrder(key, coordinate, operation);
|
|
1202
|
-
}
|
|
1203
|
-
};
|
|
1204
|
-
|
|
1205
|
-
// src/validation/QueryValidator.ts
|
|
1206
|
-
var logger8 = logger_default.get("validation", "QueryValidator");
|
|
1207
|
-
var validateQuery = (query, operation) => {
|
|
1208
|
-
if (typeof query === "undefined" || query === null) {
|
|
1209
|
-
return;
|
|
1210
|
-
}
|
|
1211
|
-
if (typeof query !== "object") {
|
|
1212
|
-
logger8.error(`Invalid query type for ${operation}`, { query, type: typeof query });
|
|
1213
|
-
throw new Error(
|
|
1214
|
-
`[${operation}] Invalid query parameter.
|
|
1215
|
-
|
|
1216
|
-
Expected: object or undefined
|
|
1217
|
-
Received: ${typeof query}
|
|
1218
|
-
|
|
1219
|
-
Example valid queries:
|
|
1220
|
-
{}
|
|
1221
|
-
{ filter: { status: 'active' } }
|
|
1222
|
-
{ limit: 10, sort: { field: 'name', order: 'asc' } }`
|
|
1223
|
-
);
|
|
1224
|
-
}
|
|
1225
|
-
if (Array.isArray(query)) {
|
|
1226
|
-
logger8.error(`Query cannot be an array for ${operation}`, { query });
|
|
1227
|
-
throw new Error(
|
|
1228
|
-
`[${operation}] Invalid query parameter.
|
|
1229
|
-
|
|
1230
|
-
Query cannot be an array.
|
|
1231
|
-
Received: ${JSON.stringify(query)}`
|
|
1232
|
-
);
|
|
1233
|
-
}
|
|
1234
|
-
logger8.debug(`Query validation passed for ${operation}`, { query });
|
|
1235
|
-
};
|
|
1236
|
-
var validateOperationParams = (params, operation) => {
|
|
1237
|
-
if (typeof params === "undefined") {
|
|
1238
|
-
return;
|
|
1239
|
-
}
|
|
1240
|
-
if (params === null) {
|
|
1241
|
-
logger8.error(`Params cannot be null for ${operation}`, { params });
|
|
1242
|
-
throw new Error(
|
|
1243
|
-
`[${operation}] Invalid operation parameters.
|
|
1244
|
-
|
|
1245
|
-
Parameters cannot be null.
|
|
1246
|
-
Expected: object or undefined
|
|
1247
|
-
Received: null
|
|
1248
|
-
|
|
1249
|
-
Example valid parameters:
|
|
1250
|
-
{}
|
|
1251
|
-
{ email: 'user@example.com' }
|
|
1252
|
-
{ status: 'active', limit: 10 }`
|
|
1253
|
-
);
|
|
1254
|
-
}
|
|
1255
|
-
if (typeof params !== "object") {
|
|
1256
|
-
logger8.error(`Invalid params type for ${operation}`, { params, type: typeof params });
|
|
1257
|
-
throw new Error(
|
|
1258
|
-
`[${operation}] Invalid operation parameters.
|
|
1259
|
-
|
|
1260
|
-
Expected: object or undefined
|
|
1261
|
-
Received: ${typeof params}
|
|
1262
|
-
|
|
1263
|
-
Example valid parameters:
|
|
1264
|
-
{}
|
|
1265
|
-
{ email: 'user@example.com' }
|
|
1266
|
-
{ status: 'active', limit: 10 }`
|
|
1267
|
-
);
|
|
1268
|
-
}
|
|
1269
|
-
if (Array.isArray(params)) {
|
|
1270
|
-
logger8.error(`Params cannot be an array for ${operation}`, { params });
|
|
1271
|
-
throw new Error(
|
|
1272
|
-
`[${operation}] Invalid operation parameters.
|
|
1273
|
-
|
|
1274
|
-
Parameters cannot be an array.
|
|
1275
|
-
Received: ${JSON.stringify(params)}`
|
|
1276
|
-
);
|
|
1277
|
-
}
|
|
1278
|
-
for (const [key, value] of Object.entries(params)) {
|
|
1279
|
-
const valueType = typeof value;
|
|
1280
|
-
const isValidType = valueType === "string" || valueType === "number" || valueType === "boolean" || value instanceof Date || Array.isArray(value) && value.every(
|
|
1281
|
-
(v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" || v instanceof Date
|
|
1282
|
-
);
|
|
1283
|
-
if (!isValidType) {
|
|
1284
|
-
logger8.error(`Invalid param value type for ${operation}`, { key, value, valueType });
|
|
1285
|
-
throw new Error(
|
|
1286
|
-
`[${operation}] Invalid value type for parameter "${key}".
|
|
1287
|
-
|
|
1288
|
-
Allowed types: string, number, boolean, Date, or arrays of these types
|
|
1289
|
-
Received: ${valueType}
|
|
1290
|
-
Value: ${JSON.stringify(value)}`
|
|
1291
|
-
);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
logger8.debug(`Operation params validation passed for ${operation}`, { params });
|
|
1295
|
-
};
|
|
1296
|
-
var validateFinderName = (finder, operation) => {
|
|
1297
|
-
if (!finder || typeof finder !== "string") {
|
|
1298
|
-
logger8.error(`Invalid finder name for ${operation}`, { finder, type: typeof finder });
|
|
1299
|
-
throw new Error(
|
|
1300
|
-
`[${operation}] Finder name must be a non-empty string.
|
|
1301
|
-
|
|
1302
|
-
Received: ${JSON.stringify(finder)}`
|
|
1303
|
-
);
|
|
1304
|
-
}
|
|
1305
|
-
if (finder.trim().length === 0) {
|
|
1306
|
-
logger8.error(`Empty finder name for ${operation}`, { finder });
|
|
1307
|
-
throw new Error(
|
|
1308
|
-
`[${operation}] Finder name cannot be empty or whitespace only.
|
|
1309
|
-
|
|
1310
|
-
Received: "${finder}"`
|
|
1311
|
-
);
|
|
1312
|
-
}
|
|
1313
|
-
logger8.debug(`Finder name validation passed for ${operation}`, { finder });
|
|
1314
|
-
};
|
|
1315
|
-
var validateActionName = (action, operation) => {
|
|
1316
|
-
if (!action || typeof action !== "string") {
|
|
1317
|
-
logger8.error(`Invalid action name for ${operation}`, { action, type: typeof action });
|
|
1318
|
-
throw new Error(
|
|
1319
|
-
`[${operation}] Action name must be a non-empty string.
|
|
1320
|
-
|
|
1321
|
-
Received: ${JSON.stringify(action)}`
|
|
1322
|
-
);
|
|
1323
|
-
}
|
|
1324
|
-
if (action.trim().length === 0) {
|
|
1325
|
-
logger8.error(`Empty action name for ${operation}`, { action });
|
|
1326
|
-
throw new Error(
|
|
1327
|
-
`[${operation}] Action name cannot be empty or whitespace only.
|
|
1328
|
-
|
|
1329
|
-
Received: "${action}"`
|
|
1330
|
-
);
|
|
1331
|
-
}
|
|
1332
|
-
logger8.debug(`Action name validation passed for ${operation}`, { action });
|
|
1333
|
-
};
|
|
1334
|
-
var validateFacetName = (facet, operation) => {
|
|
1335
|
-
if (!facet || typeof facet !== "string") {
|
|
1336
|
-
logger8.error(`Invalid facet name for ${operation}`, { facet, type: typeof facet });
|
|
1337
|
-
throw new Error(
|
|
1338
|
-
`[${operation}] Facet name must be a non-empty string.
|
|
1339
|
-
|
|
1340
|
-
Received: ${JSON.stringify(facet)}`
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
if (facet.trim().length === 0) {
|
|
1344
|
-
logger8.error(`Empty facet name for ${operation}`, { facet });
|
|
1345
|
-
throw new Error(
|
|
1346
|
-
`[${operation}] Facet name cannot be empty or whitespace only.
|
|
1347
|
-
|
|
1348
|
-
Received: "${facet}"`
|
|
1349
|
-
);
|
|
1350
|
-
}
|
|
1351
|
-
logger8.debug(`Facet name validation passed for ${operation}`, { facet });
|
|
1352
|
-
};
|
|
1353
|
-
|
|
1354
|
-
// src/errors/ActionError.ts
|
|
1355
|
-
var ActionError = class extends Error {
|
|
1356
|
-
constructor(errorInfo, cause) {
|
|
1357
|
-
super(errorInfo.message);
|
|
1358
|
-
this.errorInfo = errorInfo;
|
|
1359
|
-
this.name = "ActionError";
|
|
1360
|
-
this.cause = cause;
|
|
1361
|
-
if (!this.errorInfo.technical) {
|
|
1362
|
-
this.errorInfo.technical = { timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1363
|
-
}
|
|
1364
|
-
if (!this.errorInfo.technical.timestamp) {
|
|
1365
|
-
this.errorInfo.technical.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
toJSON() {
|
|
1369
|
-
return this.errorInfo;
|
|
1370
|
-
}
|
|
1371
|
-
};
|
|
1372
|
-
|
|
1373
|
-
// src/errors/ValidationError.ts
|
|
1374
|
-
var ValidationError = class extends ActionError {
|
|
1375
|
-
fieldErrors;
|
|
1376
|
-
constructor(message, validOptions, suggestedAction, conflictingValue, fieldErrors) {
|
|
1377
|
-
super({
|
|
1378
|
-
code: "VALIDATION_ERROR",
|
|
1379
|
-
message,
|
|
1380
|
-
operation: { type: "create", name: "", params: {} },
|
|
1381
|
-
// Will be filled by wrapper
|
|
1382
|
-
context: { itemType: "" },
|
|
1383
|
-
// Will be filled by wrapper
|
|
1384
|
-
details: {
|
|
1385
|
-
validOptions,
|
|
1386
|
-
suggestedAction: suggestedAction || (validOptions && validOptions.length > 0 ? `Valid options are: ${validOptions.join(", ")}. Please use one of these values.` : "Check the validation requirements and ensure all fields meet the required format, type, and constraints."),
|
|
1387
|
-
retryable: true,
|
|
1388
|
-
conflictingValue,
|
|
1389
|
-
fieldErrors
|
|
1390
|
-
},
|
|
1391
|
-
technical: {
|
|
1392
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1393
|
-
}
|
|
1394
|
-
});
|
|
1395
|
-
this.fieldErrors = fieldErrors;
|
|
1396
|
-
if (fieldErrors) {
|
|
1397
|
-
if (!this.errorInfo.details) this.errorInfo.details = {};
|
|
1398
|
-
this.errorInfo.details.fieldErrors = fieldErrors;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
};
|
|
1402
|
-
|
|
1403
|
-
// src/errors/NotFoundError.ts
|
|
1404
|
-
var NotFoundError = class extends ActionError {
|
|
1405
|
-
constructor(message, itemType, key) {
|
|
1406
|
-
super({
|
|
1407
|
-
code: "NOT_FOUND",
|
|
1408
|
-
message,
|
|
1409
|
-
operation: { type: "get", name: "", params: {} },
|
|
1410
|
-
context: {
|
|
1411
|
-
itemType,
|
|
1412
|
-
key: typeof key === "object" ? key : { primary: key }
|
|
1413
|
-
},
|
|
1414
|
-
details: {
|
|
1415
|
-
suggestedAction: "Verify the item ID/key is correct, check if the item was deleted, or create the item if it should exist.",
|
|
1416
|
-
retryable: false
|
|
1417
|
-
},
|
|
1418
|
-
technical: {
|
|
1419
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1420
|
-
}
|
|
1421
|
-
});
|
|
1422
|
-
this.name = "NotFoundError";
|
|
1423
|
-
}
|
|
1424
|
-
};
|
|
1425
|
-
|
|
1426
|
-
// src/errors/BusinessLogicError.ts
|
|
1427
|
-
var BusinessLogicError = class extends ActionError {
|
|
1428
|
-
constructor(message, suggestedAction, retryable = false) {
|
|
1429
|
-
super({
|
|
1430
|
-
code: "BUSINESS_LOGIC_ERROR",
|
|
1431
|
-
message,
|
|
1432
|
-
operation: { type: "action", name: "", params: {} },
|
|
1433
|
-
context: { itemType: "" },
|
|
1434
|
-
details: {
|
|
1435
|
-
suggestedAction: suggestedAction || "Review the business logic requirements and ensure all conditions are met before retrying.",
|
|
1436
|
-
retryable
|
|
1437
|
-
},
|
|
1438
|
-
technical: {
|
|
1439
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1440
|
-
}
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
|
|
1445
|
-
// src/errors/PermissionError.ts
|
|
1446
|
-
var PermissionError = class extends ActionError {
|
|
1447
|
-
constructor(message, requiredPermission, currentPermissions) {
|
|
1448
|
-
super({
|
|
1449
|
-
code: "PERMISSION_DENIED",
|
|
1450
|
-
message,
|
|
1451
|
-
operation: { type: "action", name: "", params: {} },
|
|
1452
|
-
context: {
|
|
1453
|
-
itemType: "",
|
|
1454
|
-
...requiredPermission && { requiredPermission }
|
|
1455
|
-
},
|
|
1456
|
-
details: {
|
|
1457
|
-
...requiredPermission && {
|
|
1458
|
-
suggestedAction: `Required permission: ${requiredPermission}`,
|
|
1459
|
-
expectedValue: requiredPermission
|
|
1460
|
-
},
|
|
1461
|
-
...currentPermissions && { conflictingValue: currentPermissions },
|
|
1462
|
-
retryable: false
|
|
1463
|
-
},
|
|
1464
|
-
technical: {
|
|
1465
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1466
|
-
}
|
|
1467
|
-
});
|
|
1468
|
-
}
|
|
1469
|
-
};
|
|
1470
|
-
|
|
1471
|
-
// src/errors/DuplicateError.ts
|
|
1472
|
-
var DuplicateError = class extends ActionError {
|
|
1473
|
-
constructor(message, existingItemIdOrKey, duplicateField) {
|
|
1474
|
-
let existingItemId = null;
|
|
1475
|
-
let keyInfo = null;
|
|
1476
|
-
if (typeof existingItemIdOrKey === "object" && existingItemIdOrKey !== null) {
|
|
1477
|
-
existingItemId = existingItemIdOrKey.pk || existingItemIdOrKey.id || existingItemIdOrKey.primary || null;
|
|
1478
|
-
if (existingItemId !== null) {
|
|
1479
|
-
keyInfo = {
|
|
1480
|
-
primary: existingItemId,
|
|
1481
|
-
...existingItemIdOrKey
|
|
1482
|
-
};
|
|
1483
|
-
} else {
|
|
1484
|
-
keyInfo = existingItemIdOrKey;
|
|
1485
|
-
}
|
|
1486
|
-
} else if (typeof existingItemIdOrKey !== "undefined") {
|
|
1487
|
-
existingItemId = existingItemIdOrKey;
|
|
1488
|
-
keyInfo = { primary: existingItemId };
|
|
1489
|
-
}
|
|
1490
|
-
super({
|
|
1491
|
-
code: "DUPLICATE_ERROR",
|
|
1492
|
-
message,
|
|
1493
|
-
operation: { type: "create", name: "", params: {} },
|
|
1494
|
-
context: {
|
|
1495
|
-
itemType: "",
|
|
1496
|
-
...keyInfo && { key: keyInfo },
|
|
1497
|
-
...existingItemId && {
|
|
1498
|
-
affectedItems: [{
|
|
1499
|
-
id: existingItemId,
|
|
1500
|
-
type: "",
|
|
1501
|
-
displayName: `Existing item with ${duplicateField || "key"}`
|
|
1502
|
-
}]
|
|
1503
|
-
}
|
|
1504
|
-
},
|
|
1505
|
-
details: {
|
|
1506
|
-
suggestedAction: duplicateField ? `An item with this ${duplicateField} already exists. Use a different ${duplicateField} value or update the existing item.` : "An item with this key already exists. Use a different key or update the existing item using upsert.",
|
|
1507
|
-
retryable: false,
|
|
1508
|
-
conflictingValue: duplicateField
|
|
1509
|
-
},
|
|
1510
|
-
technical: {
|
|
1511
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1512
|
-
}
|
|
1513
|
-
});
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
|
|
1517
|
-
// src/validation/schema.ts
|
|
1518
|
-
async function validateSchema(data, schema) {
|
|
1519
|
-
if (!schema) {
|
|
1520
|
-
return data;
|
|
1521
|
-
}
|
|
1522
|
-
try {
|
|
1523
|
-
if (schema.parseAsync) {
|
|
1524
|
-
return await schema.parseAsync(data);
|
|
1525
|
-
}
|
|
1526
|
-
const result = schema.safeParse(data);
|
|
1527
|
-
if (result.success) {
|
|
1528
|
-
return result.data;
|
|
1529
|
-
} else {
|
|
1530
|
-
throw result.error;
|
|
1531
|
-
}
|
|
1532
|
-
} catch (error) {
|
|
1533
|
-
if (error && Array.isArray(error.issues)) {
|
|
1534
|
-
const fieldErrors = error.issues.map((issue) => ({
|
|
1535
|
-
path: issue.path,
|
|
1536
|
-
message: issue.message,
|
|
1537
|
-
code: issue.code
|
|
1538
|
-
}));
|
|
1539
|
-
const validationError = new ValidationError(
|
|
1540
|
-
"Schema validation failed",
|
|
1541
|
-
// eslint-disable-next-line no-undefined
|
|
1542
|
-
void 0,
|
|
1543
|
-
// eslint-disable-next-line no-undefined
|
|
1544
|
-
void 0,
|
|
1545
|
-
// eslint-disable-next-line no-undefined
|
|
1546
|
-
void 0,
|
|
1547
|
-
fieldErrors
|
|
1548
|
-
);
|
|
1549
|
-
throw validationError;
|
|
1550
|
-
}
|
|
1551
|
-
if (error instanceof ValidationError) {
|
|
1552
|
-
throw error;
|
|
1553
|
-
}
|
|
1554
|
-
throw new ValidationError(`Validation failed: ${error.message || "Unknown error"}`);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
// src/operations/errorEnhancer.ts
|
|
1559
|
-
async function executeWithContext(operation, context) {
|
|
1560
|
-
try {
|
|
1561
|
-
return await operation();
|
|
1562
|
-
} catch (error) {
|
|
1563
|
-
throw enhanceError(error, context);
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
function executeWithContextSync(operation, context) {
|
|
1567
|
-
try {
|
|
1568
|
-
return operation();
|
|
1569
|
-
} catch (error) {
|
|
1570
|
-
throw enhanceError(error, context);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
function enhanceError(error, context) {
|
|
1574
|
-
if (!(error instanceof ActionError)) {
|
|
1575
|
-
return error;
|
|
1576
|
-
}
|
|
1577
|
-
error.errorInfo.operation = {
|
|
1578
|
-
type: context.operationType,
|
|
1579
|
-
name: context.operationName,
|
|
1580
|
-
params: context.params
|
|
1581
|
-
};
|
|
1582
|
-
if (!error.errorInfo.context.itemType) {
|
|
1583
|
-
error.errorInfo.context.itemType = context.itemType;
|
|
1584
|
-
}
|
|
1585
|
-
if (context.key) {
|
|
1586
|
-
const existingKey = error.errorInfo.context.key;
|
|
1587
|
-
const hasNoPrimaryKey = !existingKey || typeof existingKey.primary === "undefined";
|
|
1588
|
-
const hasNoCompositeKey = !existingKey || !existingKey.composite;
|
|
1589
|
-
const shouldOverride = hasNoPrimaryKey && hasNoCompositeKey;
|
|
1590
|
-
if (shouldOverride) {
|
|
1591
|
-
error.errorInfo.context.key = extractKeyInfo(context.key);
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
if (context.locations && context.locations.length > 0 && !error.errorInfo.context.parentLocation) {
|
|
1595
|
-
error.errorInfo.context.parentLocation = {
|
|
1596
|
-
id: context.locations[0].lk,
|
|
1597
|
-
type: context.locations[0].kt
|
|
1598
|
-
};
|
|
1599
|
-
}
|
|
1600
|
-
return error;
|
|
1601
|
-
}
|
|
1602
|
-
function extractKeyInfo(key) {
|
|
1603
|
-
if ("loc" in key) {
|
|
1604
|
-
const ktaArray = Array.isArray(key.kt) ? key.kt : [key.kt];
|
|
1605
|
-
const locations = Array.isArray(key.loc) ? key.loc : [];
|
|
1606
|
-
return {
|
|
1607
|
-
composite: {
|
|
1608
|
-
sk: key.pk,
|
|
1609
|
-
kta: ktaArray,
|
|
1610
|
-
locations: locations.map((loc) => ({
|
|
1611
|
-
lk: loc.lk,
|
|
1612
|
-
kt: loc.kt
|
|
1613
|
-
}))
|
|
1614
|
-
}
|
|
1615
|
-
};
|
|
1616
|
-
} else if ("pk" in key) {
|
|
1617
|
-
return { primary: key.pk };
|
|
1618
|
-
}
|
|
1619
|
-
return { primary: JSON.stringify(key) };
|
|
1620
|
-
}
|
|
1621
|
-
function isActionError(error) {
|
|
1622
|
-
return error instanceof ActionError;
|
|
1623
|
-
}
|
|
1624
|
-
function getErrorInfo(error) {
|
|
1625
|
-
if (isActionError(error)) {
|
|
1626
|
-
return error.toJSON();
|
|
1627
|
-
}
|
|
1628
|
-
if (error instanceof Error) {
|
|
1629
|
-
return {
|
|
1630
|
-
code: "UNKNOWN_ERROR",
|
|
1631
|
-
message: error.message,
|
|
1632
|
-
technical: {
|
|
1633
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1634
|
-
stackTrace: error.stack
|
|
1635
|
-
}
|
|
1636
|
-
};
|
|
1637
|
-
}
|
|
1638
|
-
return {
|
|
1639
|
-
code: "UNKNOWN_ERROR",
|
|
1640
|
-
message: String(error),
|
|
1641
|
-
technical: {
|
|
1642
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1643
|
-
}
|
|
1644
|
-
};
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
// src/event/events.ts
|
|
1648
|
-
function isCreateEvent(event) {
|
|
1649
|
-
return event.eventType === "create";
|
|
1650
|
-
}
|
|
1651
|
-
function isUpdateEvent(event) {
|
|
1652
|
-
return event.eventType === "update";
|
|
1653
|
-
}
|
|
1654
|
-
function isDeleteEvent(event) {
|
|
1655
|
-
return event.eventType === "delete";
|
|
1656
|
-
}
|
|
1657
|
-
function isActionEvent(event) {
|
|
1658
|
-
return event.eventType === "action";
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
|
-
// src/event/subscription.ts
|
|
1662
|
-
function isItemSubscription(subscription) {
|
|
1663
|
-
return "key" in subscription;
|
|
1664
|
-
}
|
|
1665
|
-
function isLocationSubscription(subscription) {
|
|
1666
|
-
return "kta" in subscription && "location" in subscription;
|
|
1667
|
-
}
|
|
1668
|
-
function generateSubscriptionId() {
|
|
1669
|
-
return `sub-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1670
|
-
}
|
|
1671
|
-
function createItemSubscription(key, options) {
|
|
1672
|
-
return {
|
|
1673
|
-
id: generateSubscriptionId(),
|
|
1674
|
-
key,
|
|
1675
|
-
eventTypes: options?.eventTypes,
|
|
1676
|
-
scopes: options?.scopes,
|
|
1677
|
-
query: options?.query
|
|
1678
|
-
};
|
|
1679
|
-
}
|
|
1680
|
-
function createLocationSubscription(kta, location, options) {
|
|
1681
|
-
return {
|
|
1682
|
-
id: generateSubscriptionId(),
|
|
1683
|
-
kta,
|
|
1684
|
-
location,
|
|
1685
|
-
eventTypes: options?.eventTypes,
|
|
1686
|
-
scopes: options?.scopes,
|
|
1687
|
-
query: options?.query
|
|
1688
|
-
};
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
// src/operations/Operations.ts
|
|
1692
|
-
function isPriKey2(key) {
|
|
1693
|
-
return !("loc" in key) || !key.loc;
|
|
1694
|
-
}
|
|
1695
|
-
function isComKey2(key) {
|
|
1696
|
-
return "loc" in key && key.loc && Array.isArray(key.loc) && key.loc.length > 0;
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
// src/event/matching.ts
|
|
1700
|
-
function doesEventMatchSubscription(event, subscription) {
|
|
1701
|
-
if (!doesScopeMatch(event.scopes, subscription.scopes)) {
|
|
1702
|
-
return false;
|
|
1703
|
-
}
|
|
1704
|
-
if (!doesEventTypeMatch(event.eventType, subscription.eventTypes)) {
|
|
1705
|
-
return false;
|
|
1706
|
-
}
|
|
1707
|
-
if (isItemSubscription(subscription)) {
|
|
1708
|
-
return doesKeyMatch(event.key, subscription.key);
|
|
1709
|
-
} else if (isLocationSubscription(subscription)) {
|
|
1710
|
-
return doesKeyMatchLocation(event.key, subscription.kta, subscription.location);
|
|
1711
|
-
}
|
|
1712
|
-
return false;
|
|
1713
|
-
}
|
|
1714
|
-
function doesScopeMatch(eventScopes, subscriptionScopes) {
|
|
1715
|
-
if (!subscriptionScopes || subscriptionScopes.length === 0) {
|
|
1716
|
-
return true;
|
|
1717
|
-
}
|
|
1718
|
-
return subscriptionScopes.some(
|
|
1719
|
-
(requiredScope) => eventScopes.includes(requiredScope)
|
|
1720
|
-
);
|
|
1721
|
-
}
|
|
1722
|
-
function doesEventTypeMatch(eventType, subscriptionEventTypes) {
|
|
1723
|
-
if (!subscriptionEventTypes || subscriptionEventTypes.length === 0) {
|
|
1724
|
-
return true;
|
|
1725
|
-
}
|
|
1726
|
-
return subscriptionEventTypes.includes(eventType);
|
|
1727
|
-
}
|
|
1728
|
-
function doesKeyMatch(eventKey, subscriptionKey) {
|
|
1729
|
-
if (isPriKey2(eventKey) && isPriKey2(subscriptionKey)) {
|
|
1730
|
-
return eventKey.pk === subscriptionKey.pk && eventKey.kt === subscriptionKey.kt;
|
|
1731
|
-
}
|
|
1732
|
-
if (isComKey2(eventKey) && isComKey2(subscriptionKey)) {
|
|
1733
|
-
const eventComKey = eventKey;
|
|
1734
|
-
const subscriptionComKey = subscriptionKey;
|
|
1735
|
-
if (eventComKey.pk !== subscriptionComKey.pk || eventComKey.kt !== subscriptionComKey.kt) {
|
|
1736
|
-
return false;
|
|
1737
|
-
}
|
|
1738
|
-
if (eventComKey.loc.length !== subscriptionComKey.loc.length) {
|
|
1739
|
-
return false;
|
|
1740
|
-
}
|
|
1741
|
-
return eventComKey.loc.every((eventLocKey, index) => {
|
|
1742
|
-
const subLocKey = subscriptionComKey.loc[index];
|
|
1743
|
-
return eventLocKey.lk === subLocKey.lk && eventLocKey.kt === subLocKey.kt;
|
|
1321
|
+
if (!item.key) {
|
|
1322
|
+
logger32.error("Item validation failed - item missing key", {
|
|
1323
|
+
component: "core",
|
|
1324
|
+
operation: "validatePK",
|
|
1325
|
+
expectedType: pkType,
|
|
1326
|
+
item,
|
|
1327
|
+
suggestion: "Ensure the item has a valid key property with kt and pk fields"
|
|
1744
1328
|
});
|
|
1329
|
+
throw new Error(
|
|
1330
|
+
`Item validation failed: item does not have a key property. Expected key with type '${pkType}'. Item: ${JSON.stringify(item)}. This indicates a database processing error.`
|
|
1331
|
+
);
|
|
1745
1332
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1333
|
+
const keyTypeArray = toKeyTypeArray2(item.key);
|
|
1334
|
+
if (keyTypeArray[0] !== pkType) {
|
|
1335
|
+
logger32.error("Key type mismatch during validation", {
|
|
1336
|
+
component: "core",
|
|
1337
|
+
operation: "validatePK",
|
|
1338
|
+
expectedType: pkType,
|
|
1339
|
+
actualType: keyTypeArray[0],
|
|
1340
|
+
keyTypeArray,
|
|
1341
|
+
itemKey: item.key,
|
|
1342
|
+
suggestion: `Ensure the item key has kt: '${pkType}', not '${keyTypeArray[0]}'`
|
|
1343
|
+
});
|
|
1344
|
+
throw new Error(
|
|
1345
|
+
`Item has incorrect primary key type. Expected '${pkType}', got '${keyTypeArray[0]}'. Key: ${JSON.stringify(item.key)}. This indicates a data model mismatch.`
|
|
1346
|
+
);
|
|
1752
1347
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1348
|
+
return item;
|
|
1349
|
+
};
|
|
1350
|
+
var validatePK = (input, pkType) => {
|
|
1351
|
+
logger32.trace("Checking Return Type", { input });
|
|
1352
|
+
if (Array.isArray(input)) {
|
|
1353
|
+
return input.map((item) => validatePKForItem(item, pkType));
|
|
1755
1354
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1355
|
+
return validatePKForItem(input, pkType);
|
|
1356
|
+
};
|
|
1357
|
+
var logger42 = Logging4.getLogger("validation.QueryValidator");
|
|
1358
|
+
var validateQuery = (query, operation) => {
|
|
1359
|
+
if (typeof query === "undefined" || query === null) {
|
|
1360
|
+
return;
|
|
1759
1361
|
}
|
|
1760
|
-
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1362
|
+
if (typeof query !== "object") {
|
|
1363
|
+
logger42.error(`Invalid query type for ${operation}`, { query, type: typeof query });
|
|
1364
|
+
throw new Error(
|
|
1365
|
+
`[${operation}] Invalid query parameter.
|
|
1366
|
+
|
|
1367
|
+
Expected: object or undefined
|
|
1368
|
+
Received: ${typeof query}
|
|
1369
|
+
|
|
1370
|
+
Example valid queries:
|
|
1371
|
+
{}
|
|
1372
|
+
{ filter: { status: 'active' } }
|
|
1373
|
+
{ limit: 10, sort: { field: 'name', order: 'asc' } }`
|
|
1374
|
+
);
|
|
1765
1375
|
}
|
|
1766
|
-
if (
|
|
1767
|
-
|
|
1376
|
+
if (Array.isArray(query)) {
|
|
1377
|
+
logger42.error(`Query cannot be an array for ${operation}`, { query });
|
|
1378
|
+
throw new Error(
|
|
1379
|
+
`[${operation}] Invalid query parameter.
|
|
1380
|
+
|
|
1381
|
+
Query cannot be an array.
|
|
1382
|
+
Received: ${JSON.stringify(query)}`
|
|
1383
|
+
);
|
|
1768
1384
|
}
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
}
|
|
1775
|
-
if (eventLocKey.lk !== subLocKey.lk || eventLocKey.kt !== subLocKey.kt) {
|
|
1776
|
-
return false;
|
|
1777
|
-
}
|
|
1385
|
+
logger42.debug(`Query validation passed for ${operation}`, { query });
|
|
1386
|
+
};
|
|
1387
|
+
var validateOperationParams = (params, operation) => {
|
|
1388
|
+
if (typeof params === "undefined") {
|
|
1389
|
+
return;
|
|
1778
1390
|
}
|
|
1779
|
-
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1391
|
+
if (params === null) {
|
|
1392
|
+
logger42.error(`Params cannot be null for ${operation}`, { params });
|
|
1393
|
+
throw new Error(
|
|
1394
|
+
`[${operation}] Invalid operation parameters.
|
|
1395
|
+
|
|
1396
|
+
Parameters cannot be null.
|
|
1397
|
+
Expected: object or undefined
|
|
1398
|
+
Received: null
|
|
1399
|
+
|
|
1400
|
+
Example valid parameters:
|
|
1401
|
+
{}
|
|
1402
|
+
{ email: 'user@example.com' }
|
|
1403
|
+
{ status: 'active', limit: 10 }`
|
|
1404
|
+
);
|
|
1792
1405
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
}
|
|
1406
|
+
if (typeof params !== "object") {
|
|
1407
|
+
logger42.error(`Invalid params type for ${operation}`, { params, type: typeof params });
|
|
1408
|
+
throw new Error(
|
|
1409
|
+
`[${operation}] Invalid operation parameters.
|
|
1798
1410
|
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
}
|
|
1806
|
-
|
|
1807
|
-
FIRESTORE: "firestore",
|
|
1808
|
-
SEQUELIZE: "sequelize",
|
|
1809
|
-
POSTGRESQL: "postgresql",
|
|
1810
|
-
MYSQL: "mysql",
|
|
1811
|
-
MONGODB: "mongodb",
|
|
1812
|
-
REDIS: "redis"
|
|
1813
|
-
};
|
|
1814
|
-
var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
|
|
1815
|
-
SubscriptionStatus2["PENDING"] = "pending";
|
|
1816
|
-
SubscriptionStatus2["ACTIVE"] = "active";
|
|
1817
|
-
SubscriptionStatus2["PAUSED"] = "paused";
|
|
1818
|
-
SubscriptionStatus2["ERROR"] = "error";
|
|
1819
|
-
SubscriptionStatus2["CANCELLED"] = "cancelled";
|
|
1820
|
-
return SubscriptionStatus2;
|
|
1821
|
-
})(SubscriptionStatus || {});
|
|
1822
|
-
var DEFAULT_EVENT_CONFIG = {
|
|
1823
|
-
maxBatchSize: 100,
|
|
1824
|
-
maxBatchWaitTime: 50,
|
|
1825
|
-
// 50ms
|
|
1826
|
-
maxRetryAttempts: 3,
|
|
1827
|
-
retryDelay: 1e3,
|
|
1828
|
-
// 1 second
|
|
1829
|
-
enableStats: true,
|
|
1830
|
-
maxSubscriptions: 1e3,
|
|
1831
|
-
subscriptionCleanupInterval: 3e5
|
|
1832
|
-
// 5 minutes
|
|
1833
|
-
};
|
|
1834
|
-
var EventSystemError = class extends Error {
|
|
1835
|
-
constructor(message, code, details) {
|
|
1836
|
-
super(message);
|
|
1837
|
-
this.code = code;
|
|
1838
|
-
this.details = details;
|
|
1839
|
-
this.name = "EventSystemError";
|
|
1411
|
+
Expected: object or undefined
|
|
1412
|
+
Received: ${typeof params}
|
|
1413
|
+
|
|
1414
|
+
Example valid parameters:
|
|
1415
|
+
{}
|
|
1416
|
+
{ email: 'user@example.com' }
|
|
1417
|
+
{ status: 'active', limit: 10 }`
|
|
1418
|
+
);
|
|
1840
1419
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1420
|
+
if (Array.isArray(params)) {
|
|
1421
|
+
logger42.error(`Params cannot be an array for ${operation}`, { params });
|
|
1422
|
+
throw new Error(
|
|
1423
|
+
`[${operation}] Invalid operation parameters.
|
|
1424
|
+
|
|
1425
|
+
Parameters cannot be an array.
|
|
1426
|
+
Received: ${JSON.stringify(params)}`
|
|
1427
|
+
);
|
|
1847
1428
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1429
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1430
|
+
const valueType = typeof value;
|
|
1431
|
+
const isValidType = valueType === "string" || valueType === "number" || valueType === "boolean" || value instanceof Date || Array.isArray(value) && value.every(
|
|
1432
|
+
(v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" || v instanceof Date
|
|
1433
|
+
);
|
|
1434
|
+
if (!isValidType) {
|
|
1435
|
+
logger42.error(`Invalid param value type for ${operation}`, { key, value, valueType });
|
|
1436
|
+
throw new Error(
|
|
1437
|
+
`[${operation}] Invalid value type for parameter "${key}".
|
|
1438
|
+
|
|
1439
|
+
Allowed types: string, number, boolean, Date, or arrays of these types
|
|
1440
|
+
Received: ${valueType}
|
|
1441
|
+
Value: ${JSON.stringify(value)}`
|
|
1442
|
+
);
|
|
1443
|
+
}
|
|
1854
1444
|
}
|
|
1445
|
+
logger42.debug(`Operation params validation passed for ${operation}`, { params });
|
|
1855
1446
|
};
|
|
1856
|
-
var
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1447
|
+
var validateFinderName = (finder, operation) => {
|
|
1448
|
+
if (!finder || typeof finder !== "string") {
|
|
1449
|
+
logger42.error(`Invalid finder name for ${operation}`, { finder, type: typeof finder });
|
|
1450
|
+
throw new Error(
|
|
1451
|
+
`[${operation}] Finder name must be a non-empty string.
|
|
1452
|
+
|
|
1453
|
+
Received: ${JSON.stringify(finder)}`
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
if (finder.trim().length === 0) {
|
|
1457
|
+
logger42.error(`Empty finder name for ${operation}`, { finder });
|
|
1458
|
+
throw new Error(
|
|
1459
|
+
`[${operation}] Finder name cannot be empty or whitespace only.
|
|
1460
|
+
|
|
1461
|
+
Received: "${finder}"`
|
|
1462
|
+
);
|
|
1860
1463
|
}
|
|
1464
|
+
logger42.debug(`Finder name validation passed for ${operation}`, { finder });
|
|
1861
1465
|
};
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
case "general":
|
|
1871
|
-
default:
|
|
1872
|
-
return new EventSystemError(message, "GENERAL_ERROR", details);
|
|
1466
|
+
var validateActionName = (action, operation) => {
|
|
1467
|
+
if (!action || typeof action !== "string") {
|
|
1468
|
+
logger42.error(`Invalid action name for ${operation}`, { action, type: typeof action });
|
|
1469
|
+
throw new Error(
|
|
1470
|
+
`[${operation}] Action name must be a non-empty string.
|
|
1471
|
+
|
|
1472
|
+
Received: ${JSON.stringify(action)}`
|
|
1473
|
+
);
|
|
1873
1474
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
}
|
|
1475
|
+
if (action.trim().length === 0) {
|
|
1476
|
+
logger42.error(`Empty action name for ${operation}`, { action });
|
|
1477
|
+
throw new Error(
|
|
1478
|
+
`[${operation}] Action name cannot be empty or whitespace only.
|
|
1878
1479
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
"
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1480
|
+
Received: "${action}"`
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
logger42.debug(`Action name validation passed for ${operation}`, { action });
|
|
1484
|
+
};
|
|
1485
|
+
var validateFacetName = (facet, operation) => {
|
|
1486
|
+
if (!facet || typeof facet !== "string") {
|
|
1487
|
+
logger42.error(`Invalid facet name for ${operation}`, { facet, type: typeof facet });
|
|
1488
|
+
throw new Error(
|
|
1489
|
+
`[${operation}] Facet name must be a non-empty string.
|
|
1490
|
+
|
|
1491
|
+
Received: ${JSON.stringify(facet)}`
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
if (facet.trim().length === 0) {
|
|
1495
|
+
logger42.error(`Empty facet name for ${operation}`, { facet });
|
|
1496
|
+
throw new Error(
|
|
1497
|
+
`[${operation}] Facet name cannot be empty or whitespace only.
|
|
1498
|
+
|
|
1499
|
+
Received: "${facet}"`
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
logger42.debug(`Facet name validation passed for ${operation}`, { facet });
|
|
1503
|
+
};
|
|
1895
1504
|
|
|
1896
1505
|
// src/operations/wrappers/createOneWrapper.ts
|
|
1897
|
-
var
|
|
1506
|
+
var logger6 = logger_default.get("operations", "wrappers", "one");
|
|
1898
1507
|
function createOneWrapper(coordinate, implementation, options = {}) {
|
|
1899
1508
|
const operationName = options.operationName || "one";
|
|
1900
1509
|
return async (query, locations) => {
|
|
1901
1510
|
if (options.debug) {
|
|
1902
|
-
|
|
1511
|
+
logger6.debug(`[${operationName}] Called with:`, { query, locations });
|
|
1903
1512
|
}
|
|
1904
1513
|
if (!options.skipValidation) {
|
|
1905
1514
|
try {
|
|
@@ -1914,7 +1523,7 @@ function createOneWrapper(coordinate, implementation, options = {}) {
|
|
|
1914
1523
|
try {
|
|
1915
1524
|
const result = await implementation(normalizedQuery, normalizedLocations);
|
|
1916
1525
|
if (options.debug) {
|
|
1917
|
-
|
|
1526
|
+
logger6.debug(`[${operationName}] Result:`, result ? "found" : "not found");
|
|
1918
1527
|
}
|
|
1919
1528
|
if (result && !options.skipValidation) {
|
|
1920
1529
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -1942,19 +1551,19 @@ function createOneWrapper(coordinate, implementation, options = {}) {
|
|
|
1942
1551
|
}
|
|
1943
1552
|
|
|
1944
1553
|
// src/operations/wrappers/createAllWrapper.ts
|
|
1945
|
-
var
|
|
1554
|
+
var logger7 = logger_default.get("operations", "wrappers", "all");
|
|
1946
1555
|
function createAllWrapper(coordinate, implementation, wrapperOptions = {}) {
|
|
1947
1556
|
const operationName = wrapperOptions.operationName || "all";
|
|
1948
1557
|
return async (query, locations, allOptions) => {
|
|
1949
1558
|
if (wrapperOptions.debug) {
|
|
1950
|
-
|
|
1559
|
+
logger7.debug(`[${operationName}] Called with:`, { query, locations, allOptions });
|
|
1951
1560
|
}
|
|
1952
1561
|
if (!wrapperOptions.skipValidation) {
|
|
1953
1562
|
validateQuery(query, operationName);
|
|
1954
1563
|
validateLocations(locations, coordinate, operationName);
|
|
1955
1564
|
if (allOptions && "limit" in allOptions && allOptions.limit != null) {
|
|
1956
1565
|
if (!Number.isInteger(allOptions.limit) || allOptions.limit < 1) {
|
|
1957
|
-
|
|
1566
|
+
logger7.error(`Invalid limit parameter in ${operationName}`, {
|
|
1958
1567
|
component: "core",
|
|
1959
1568
|
wrapper: "createAllWrapper",
|
|
1960
1569
|
operation: operationName,
|
|
@@ -1978,7 +1587,7 @@ function createAllWrapper(coordinate, implementation, wrapperOptions = {}) {
|
|
|
1978
1587
|
try {
|
|
1979
1588
|
const result = await implementation(normalizedQuery, normalizedLocations, allOptions);
|
|
1980
1589
|
if (wrapperOptions.debug) {
|
|
1981
|
-
|
|
1590
|
+
logger7.debug(`[${operationName}] Result: ${result.items.length} items, total: ${result.metadata.total}`);
|
|
1982
1591
|
}
|
|
1983
1592
|
if (!wrapperOptions.skipValidation) {
|
|
1984
1593
|
const validatedItems = validatePK(result.items, coordinate.kta[0]);
|
|
@@ -2006,12 +1615,12 @@ function createAllWrapper(coordinate, implementation, wrapperOptions = {}) {
|
|
|
2006
1615
|
}
|
|
2007
1616
|
|
|
2008
1617
|
// src/operations/wrappers/createGetWrapper.ts
|
|
2009
|
-
var
|
|
1618
|
+
var logger8 = logger_default.get("operations", "wrappers", "get");
|
|
2010
1619
|
function createGetWrapper(coordinate, implementation, options = {}) {
|
|
2011
1620
|
const operationName = options.operationName || "get";
|
|
2012
1621
|
return async (key) => {
|
|
2013
1622
|
if (options.debug) {
|
|
2014
|
-
|
|
1623
|
+
logger8.debug(`[${operationName}] Called with key:`, key);
|
|
2015
1624
|
}
|
|
2016
1625
|
if (!options.skipValidation) {
|
|
2017
1626
|
validateKey(key, coordinate, operationName);
|
|
@@ -2019,7 +1628,7 @@ function createGetWrapper(coordinate, implementation, options = {}) {
|
|
|
2019
1628
|
try {
|
|
2020
1629
|
const result = await implementation(key);
|
|
2021
1630
|
if (options.debug) {
|
|
2022
|
-
|
|
1631
|
+
logger8.debug(`[${operationName}] Result:`, result ? "found" : "not found");
|
|
2023
1632
|
}
|
|
2024
1633
|
if (result && !options.skipValidation) {
|
|
2025
1634
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -2035,7 +1644,7 @@ function createGetWrapper(coordinate, implementation, options = {}) {
|
|
|
2035
1644
|
throw options.onError(error, context);
|
|
2036
1645
|
}
|
|
2037
1646
|
if (error instanceof NotFoundError) {
|
|
2038
|
-
|
|
1647
|
+
logger8.debug(`[${operationName}] Item not found`, {
|
|
2039
1648
|
component: "core",
|
|
2040
1649
|
wrapper: "createGetWrapper",
|
|
2041
1650
|
operation: operationName,
|
|
@@ -2045,7 +1654,7 @@ function createGetWrapper(coordinate, implementation, options = {}) {
|
|
|
2045
1654
|
});
|
|
2046
1655
|
throw error;
|
|
2047
1656
|
}
|
|
2048
|
-
|
|
1657
|
+
logger8.error(`[${operationName}] Operation failed in wrapper`, {
|
|
2049
1658
|
component: "core",
|
|
2050
1659
|
wrapper: "createGetWrapper",
|
|
2051
1660
|
operation: operationName,
|
|
@@ -2065,12 +1674,12 @@ function createGetWrapper(coordinate, implementation, options = {}) {
|
|
|
2065
1674
|
}
|
|
2066
1675
|
|
|
2067
1676
|
// src/operations/wrappers/createCreateWrapper.ts
|
|
2068
|
-
var
|
|
1677
|
+
var logger9 = logger_default.get("operations", "wrappers", "create");
|
|
2069
1678
|
function createCreateWrapper(coordinate, implementation, wrapperOptions = {}) {
|
|
2070
1679
|
const operationName = wrapperOptions.operationName || "create";
|
|
2071
1680
|
return async (item, createOptions) => {
|
|
2072
1681
|
if (wrapperOptions.debug) {
|
|
2073
|
-
|
|
1682
|
+
logger9.debug(`[${operationName}] Called with:`, { item, options: createOptions });
|
|
2074
1683
|
}
|
|
2075
1684
|
if (!wrapperOptions.skipValidation) {
|
|
2076
1685
|
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
@@ -2093,7 +1702,7 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2093
1702
|
try {
|
|
2094
1703
|
const result = await implementation(item, createOptions);
|
|
2095
1704
|
if (wrapperOptions.debug) {
|
|
2096
|
-
|
|
1705
|
+
logger9.debug(`[${operationName}] Created item:`, result.key);
|
|
2097
1706
|
}
|
|
2098
1707
|
if (!wrapperOptions.skipValidation) {
|
|
2099
1708
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -2108,7 +1717,7 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2108
1717
|
};
|
|
2109
1718
|
throw wrapperOptions.onError(error, context);
|
|
2110
1719
|
}
|
|
2111
|
-
|
|
1720
|
+
logger9.error(`[${operationName}] Operation failed in wrapper`, {
|
|
2112
1721
|
component: "core",
|
|
2113
1722
|
wrapper: "createCreateWrapper",
|
|
2114
1723
|
operation: operationName,
|
|
@@ -2129,12 +1738,12 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2129
1738
|
}
|
|
2130
1739
|
|
|
2131
1740
|
// src/operations/wrappers/createUpdateWrapper.ts
|
|
2132
|
-
var
|
|
1741
|
+
var logger10 = logger_default.get("operations", "wrappers", "update");
|
|
2133
1742
|
function createUpdateWrapper(coordinate, implementation, options = {}) {
|
|
2134
1743
|
const operationName = options.operationName || "update";
|
|
2135
1744
|
return async (key, item, updateOptions) => {
|
|
2136
1745
|
if (options.debug) {
|
|
2137
|
-
|
|
1746
|
+
logger10.debug(`[${operationName}] Called with:`, { key, item, updateOptions });
|
|
2138
1747
|
}
|
|
2139
1748
|
if (!options.skipValidation) {
|
|
2140
1749
|
validateKey(key, coordinate, operationName);
|
|
@@ -2150,7 +1759,7 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2150
1759
|
try {
|
|
2151
1760
|
const result = await implementation(key, item, updateOptions);
|
|
2152
1761
|
if (options.debug) {
|
|
2153
|
-
|
|
1762
|
+
logger10.debug(`[${operationName}] Updated item:`, result.key);
|
|
2154
1763
|
}
|
|
2155
1764
|
if (!options.skipValidation) {
|
|
2156
1765
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -2174,15 +1783,18 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2174
1783
|
}
|
|
2175
1784
|
|
|
2176
1785
|
// src/operations/wrappers/createUpsertWrapper.ts
|
|
2177
|
-
var
|
|
1786
|
+
var logger11 = logger_default.get("operations", "wrappers", "upsert");
|
|
2178
1787
|
function createUpsertWrapper(coordinate, implementation, options = {}) {
|
|
2179
1788
|
const operationName = options.operationName || "upsert";
|
|
2180
1789
|
return async (key, item, locations, updateOptions) => {
|
|
2181
1790
|
if (options.debug) {
|
|
2182
|
-
|
|
1791
|
+
logger11.debug(`[${operationName}] Called with:`, { key, item, locations, updateOptions });
|
|
2183
1792
|
}
|
|
2184
1793
|
if (!options.skipValidation) {
|
|
2185
1794
|
validateKey(key, coordinate, operationName);
|
|
1795
|
+
if (locations) {
|
|
1796
|
+
validateLocations(locations, coordinate, operationName);
|
|
1797
|
+
}
|
|
2186
1798
|
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
2187
1799
|
throw new Error(
|
|
2188
1800
|
`[${operationName}] Invalid item parameter.
|
|
@@ -2195,7 +1807,7 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2195
1807
|
try {
|
|
2196
1808
|
const result = await implementation(key, item, locations, updateOptions);
|
|
2197
1809
|
if (options.debug) {
|
|
2198
|
-
|
|
1810
|
+
logger11.debug(`[${operationName}] Upserted item:`, result.key);
|
|
2199
1811
|
}
|
|
2200
1812
|
if (!options.skipValidation) {
|
|
2201
1813
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -2219,12 +1831,12 @@ Received: ${Array.isArray(item) ? "array" : typeof item}`
|
|
|
2219
1831
|
}
|
|
2220
1832
|
|
|
2221
1833
|
// src/operations/wrappers/createRemoveWrapper.ts
|
|
2222
|
-
var
|
|
1834
|
+
var logger12 = logger_default.get("operations", "wrappers", "remove");
|
|
2223
1835
|
function createRemoveWrapper(coordinate, implementation, options = {}) {
|
|
2224
1836
|
const operationName = options.operationName || "remove";
|
|
2225
1837
|
return async (key) => {
|
|
2226
1838
|
if (options.debug) {
|
|
2227
|
-
|
|
1839
|
+
logger12.debug(`[${operationName}] Called with key:`, key);
|
|
2228
1840
|
}
|
|
2229
1841
|
if (!options.skipValidation) {
|
|
2230
1842
|
validateKey(key, coordinate, operationName);
|
|
@@ -2232,7 +1844,7 @@ function createRemoveWrapper(coordinate, implementation, options = {}) {
|
|
|
2232
1844
|
try {
|
|
2233
1845
|
const result = await implementation(key);
|
|
2234
1846
|
if (options.debug) {
|
|
2235
|
-
|
|
1847
|
+
logger12.debug(`[${operationName}] Removed item:`, key);
|
|
2236
1848
|
}
|
|
2237
1849
|
return result;
|
|
2238
1850
|
} catch (error) {
|
|
@@ -2244,7 +1856,7 @@ function createRemoveWrapper(coordinate, implementation, options = {}) {
|
|
|
2244
1856
|
};
|
|
2245
1857
|
throw options.onError(error, context);
|
|
2246
1858
|
}
|
|
2247
|
-
|
|
1859
|
+
logger12.error(`[${operationName}] Operation failed in wrapper`, {
|
|
2248
1860
|
component: "core",
|
|
2249
1861
|
wrapper: "createRemoveWrapper",
|
|
2250
1862
|
operation: operationName,
|
|
@@ -2264,7 +1876,7 @@ function createRemoveWrapper(coordinate, implementation, options = {}) {
|
|
|
2264
1876
|
}
|
|
2265
1877
|
|
|
2266
1878
|
// src/operations/wrappers/createFindWrapper.ts
|
|
2267
|
-
var
|
|
1879
|
+
var logger13 = logger_default.get("operations", "wrappers", "find");
|
|
2268
1880
|
function isFindOperationResult(value) {
|
|
2269
1881
|
return value && typeof value === "object" && "items" in value && "metadata" in value && Array.isArray(value.items) && value.metadata && typeof value.metadata === "object" && "total" in value.metadata;
|
|
2270
1882
|
}
|
|
@@ -2296,7 +1908,7 @@ function createFindWrapper(coordinate, implementation, options = {}) {
|
|
|
2296
1908
|
const operationName = options.operationName || "find";
|
|
2297
1909
|
return async (finder, params, locations, findOptions) => {
|
|
2298
1910
|
if (options.debug) {
|
|
2299
|
-
|
|
1911
|
+
logger13.debug(`[${operationName}] Called:`, { finder, params, locations, findOptions });
|
|
2300
1912
|
}
|
|
2301
1913
|
if (!options.skipValidation) {
|
|
2302
1914
|
validateFinderName(finder, operationName);
|
|
@@ -2309,7 +1921,7 @@ function createFindWrapper(coordinate, implementation, options = {}) {
|
|
|
2309
1921
|
const result = await implementation(finder, normalizedParams, normalizedLocations, findOptions);
|
|
2310
1922
|
if (isFindOperationResult(result)) {
|
|
2311
1923
|
if (options.debug) {
|
|
2312
|
-
|
|
1924
|
+
logger13.debug(`[${operationName}] Finder "${finder}" opted-in to pagination, found ${result.items.length} items (total: ${result.metadata.total})`);
|
|
2313
1925
|
}
|
|
2314
1926
|
if (!options.skipValidation) {
|
|
2315
1927
|
const validatedItems = validatePK(result.items, coordinate.kta[0]);
|
|
@@ -2321,7 +1933,7 @@ function createFindWrapper(coordinate, implementation, options = {}) {
|
|
|
2321
1933
|
return result;
|
|
2322
1934
|
} else {
|
|
2323
1935
|
if (options.debug) {
|
|
2324
|
-
|
|
1936
|
+
logger13.debug(`[${operationName}] Finder "${finder}" using legacy signature, applying post-processing pagination`);
|
|
2325
1937
|
}
|
|
2326
1938
|
let validatedItems;
|
|
2327
1939
|
if (!options.skipValidation) {
|
|
@@ -2343,7 +1955,7 @@ function createFindWrapper(coordinate, implementation, options = {}) {
|
|
|
2343
1955
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2344
1956
|
const errorStack = error instanceof Error ? error.stack : null;
|
|
2345
1957
|
const errorCause = error instanceof Error && "cause" in error ? error.cause : null;
|
|
2346
|
-
|
|
1958
|
+
logger13.error(`[${operationName}] Operation failed for finder "${finder}"`, {
|
|
2347
1959
|
finder,
|
|
2348
1960
|
params,
|
|
2349
1961
|
locations,
|
|
@@ -2361,12 +1973,12 @@ function createFindWrapper(coordinate, implementation, options = {}) {
|
|
|
2361
1973
|
}
|
|
2362
1974
|
|
|
2363
1975
|
// src/operations/wrappers/createFindOneWrapper.ts
|
|
2364
|
-
var
|
|
1976
|
+
var logger14 = logger_default.get("operations", "wrappers", "findOne");
|
|
2365
1977
|
function createFindOneWrapper(coordinate, implementation, options = {}) {
|
|
2366
1978
|
const operationName = options.operationName || "findOne";
|
|
2367
1979
|
return async (finder, params, locations) => {
|
|
2368
1980
|
if (options.debug) {
|
|
2369
|
-
|
|
1981
|
+
logger14.debug(`[${operationName}] Called:`, { finder, params, locations });
|
|
2370
1982
|
}
|
|
2371
1983
|
if (!options.skipValidation) {
|
|
2372
1984
|
validateFinderName(finder, operationName);
|
|
@@ -2378,7 +1990,7 @@ function createFindOneWrapper(coordinate, implementation, options = {}) {
|
|
|
2378
1990
|
try {
|
|
2379
1991
|
const result = await implementation(finder, normalizedParams, normalizedLocations);
|
|
2380
1992
|
if (options.debug) {
|
|
2381
|
-
|
|
1993
|
+
logger14.debug(`[${operationName}] Result for finder "${finder}":`, result ? "found" : "not found");
|
|
2382
1994
|
}
|
|
2383
1995
|
if (result && !options.skipValidation) {
|
|
2384
1996
|
return validatePK(result, coordinate.kta[0]);
|
|
@@ -2402,12 +2014,12 @@ function createFindOneWrapper(coordinate, implementation, options = {}) {
|
|
|
2402
2014
|
}
|
|
2403
2015
|
|
|
2404
2016
|
// src/operations/wrappers/createActionWrapper.ts
|
|
2405
|
-
var
|
|
2017
|
+
var logger15 = logger_default.get("operations", "wrappers", "action");
|
|
2406
2018
|
function createActionWrapper(coordinate, implementation, options = {}) {
|
|
2407
2019
|
const operationName = options.operationName || "action";
|
|
2408
2020
|
return async (key, action, params) => {
|
|
2409
2021
|
if (options.debug) {
|
|
2410
|
-
|
|
2022
|
+
logger15.debug(`[${operationName}] Called:`, { key, action, params });
|
|
2411
2023
|
}
|
|
2412
2024
|
if (!options.skipValidation) {
|
|
2413
2025
|
validateKey(key, coordinate, operationName);
|
|
@@ -2418,7 +2030,7 @@ function createActionWrapper(coordinate, implementation, options = {}) {
|
|
|
2418
2030
|
try {
|
|
2419
2031
|
const result = await implementation(key, action, normalizedParams);
|
|
2420
2032
|
if (options.debug) {
|
|
2421
|
-
|
|
2033
|
+
logger15.debug(`[${operationName}] Action "${action}" completed:`, {
|
|
2422
2034
|
itemKey: result[0].key,
|
|
2423
2035
|
affectedKeys: result[1].length
|
|
2424
2036
|
});
|
|
@@ -2437,7 +2049,7 @@ function createActionWrapper(coordinate, implementation, options = {}) {
|
|
|
2437
2049
|
};
|
|
2438
2050
|
throw options.onError(error, context);
|
|
2439
2051
|
}
|
|
2440
|
-
|
|
2052
|
+
logger15.error(`[${operationName}] Action failed in wrapper`, {
|
|
2441
2053
|
component: "core",
|
|
2442
2054
|
wrapper: "createActionWrapper",
|
|
2443
2055
|
operation: operationName,
|
|
@@ -2459,12 +2071,12 @@ function createActionWrapper(coordinate, implementation, options = {}) {
|
|
|
2459
2071
|
}
|
|
2460
2072
|
|
|
2461
2073
|
// src/operations/wrappers/createAllActionWrapper.ts
|
|
2462
|
-
var
|
|
2074
|
+
var logger16 = logger_default.get("operations", "wrappers", "allAction");
|
|
2463
2075
|
function createAllActionWrapper(coordinate, implementation, options = {}) {
|
|
2464
2076
|
const operationName = options.operationName || "allAction";
|
|
2465
2077
|
return async (action, params, locations) => {
|
|
2466
2078
|
if (options.debug) {
|
|
2467
|
-
|
|
2079
|
+
logger16.debug(`[${operationName}] Called:`, { action, params, locations });
|
|
2468
2080
|
}
|
|
2469
2081
|
if (!options.skipValidation) {
|
|
2470
2082
|
validateActionName(action, operationName);
|
|
@@ -2476,7 +2088,7 @@ function createAllActionWrapper(coordinate, implementation, options = {}) {
|
|
|
2476
2088
|
try {
|
|
2477
2089
|
const result = await implementation(action, normalizedParams, normalizedLocations);
|
|
2478
2090
|
if (options.debug) {
|
|
2479
|
-
|
|
2091
|
+
logger16.debug(`[${operationName}] Action "${action}" completed:`, {
|
|
2480
2092
|
itemsAffected: result[0].length,
|
|
2481
2093
|
affectedKeys: result[1].length
|
|
2482
2094
|
});
|
|
@@ -2504,12 +2116,12 @@ function createAllActionWrapper(coordinate, implementation, options = {}) {
|
|
|
2504
2116
|
}
|
|
2505
2117
|
|
|
2506
2118
|
// src/operations/wrappers/createFacetWrapper.ts
|
|
2507
|
-
var
|
|
2119
|
+
var logger17 = logger_default.get("operations", "wrappers", "facet");
|
|
2508
2120
|
function createFacetWrapper(coordinate, implementation, options = {}) {
|
|
2509
2121
|
const operationName = options.operationName || "facet";
|
|
2510
2122
|
return async (key, facet, params) => {
|
|
2511
2123
|
if (options.debug) {
|
|
2512
|
-
|
|
2124
|
+
logger17.debug(`[${operationName}] Called:`, { key, facet, params });
|
|
2513
2125
|
}
|
|
2514
2126
|
if (!options.skipValidation) {
|
|
2515
2127
|
validateKey(key, coordinate, operationName);
|
|
@@ -2520,7 +2132,7 @@ function createFacetWrapper(coordinate, implementation, options = {}) {
|
|
|
2520
2132
|
try {
|
|
2521
2133
|
const result = await implementation(key, facet, normalizedParams);
|
|
2522
2134
|
if (options.debug) {
|
|
2523
|
-
|
|
2135
|
+
logger17.debug(`[${operationName}] Facet "${facet}" completed`);
|
|
2524
2136
|
}
|
|
2525
2137
|
return result;
|
|
2526
2138
|
} catch (error) {
|
|
@@ -2541,12 +2153,12 @@ function createFacetWrapper(coordinate, implementation, options = {}) {
|
|
|
2541
2153
|
}
|
|
2542
2154
|
|
|
2543
2155
|
// src/operations/wrappers/createAllFacetWrapper.ts
|
|
2544
|
-
var
|
|
2156
|
+
var logger18 = logger_default.get("operations", "wrappers", "allFacet");
|
|
2545
2157
|
function createAllFacetWrapper(coordinate, implementation, options = {}) {
|
|
2546
2158
|
const operationName = options.operationName || "allFacet";
|
|
2547
2159
|
return async (facet, params, locations) => {
|
|
2548
2160
|
if (options.debug) {
|
|
2549
|
-
|
|
2161
|
+
logger18.debug(`[${operationName}] Called:`, { facet, params, locations });
|
|
2550
2162
|
}
|
|
2551
2163
|
if (!options.skipValidation) {
|
|
2552
2164
|
validateFacetName(facet, operationName);
|
|
@@ -2558,7 +2170,7 @@ function createAllFacetWrapper(coordinate, implementation, options = {}) {
|
|
|
2558
2170
|
try {
|
|
2559
2171
|
const result = await implementation(facet, normalizedParams, normalizedLocations);
|
|
2560
2172
|
if (options.debug) {
|
|
2561
|
-
|
|
2173
|
+
logger18.debug(`[${operationName}] Facet "${facet}" completed`);
|
|
2562
2174
|
}
|
|
2563
2175
|
return result;
|
|
2564
2176
|
} catch (error) {
|
|
@@ -2577,6 +2189,247 @@ function createAllFacetWrapper(coordinate, implementation, options = {}) {
|
|
|
2577
2189
|
}
|
|
2578
2190
|
};
|
|
2579
2191
|
}
|
|
2192
|
+
|
|
2193
|
+
// src/event/events.ts
|
|
2194
|
+
function isCreateEvent(event) {
|
|
2195
|
+
return event.eventType === "create";
|
|
2196
|
+
}
|
|
2197
|
+
function isUpdateEvent(event) {
|
|
2198
|
+
return event.eventType === "update";
|
|
2199
|
+
}
|
|
2200
|
+
function isDeleteEvent(event) {
|
|
2201
|
+
return event.eventType === "delete";
|
|
2202
|
+
}
|
|
2203
|
+
function isActionEvent(event) {
|
|
2204
|
+
return event.eventType === "action";
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
// src/event/subscription.ts
|
|
2208
|
+
function isItemSubscription(subscription) {
|
|
2209
|
+
return "key" in subscription;
|
|
2210
|
+
}
|
|
2211
|
+
function isLocationSubscription(subscription) {
|
|
2212
|
+
return "kta" in subscription && "location" in subscription;
|
|
2213
|
+
}
|
|
2214
|
+
function generateSubscriptionId() {
|
|
2215
|
+
return `sub-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2216
|
+
}
|
|
2217
|
+
function createItemSubscription(key, options) {
|
|
2218
|
+
return {
|
|
2219
|
+
id: generateSubscriptionId(),
|
|
2220
|
+
key,
|
|
2221
|
+
eventTypes: options?.eventTypes,
|
|
2222
|
+
scopes: options?.scopes,
|
|
2223
|
+
query: options?.query
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
function createLocationSubscription(kta, location, options) {
|
|
2227
|
+
return {
|
|
2228
|
+
id: generateSubscriptionId(),
|
|
2229
|
+
kta,
|
|
2230
|
+
location,
|
|
2231
|
+
eventTypes: options?.eventTypes,
|
|
2232
|
+
scopes: options?.scopes,
|
|
2233
|
+
query: options?.query
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
// src/event/matching.ts
|
|
2238
|
+
function doesEventMatchSubscription(event, subscription) {
|
|
2239
|
+
if (!doesScopeMatch(event.scopes, subscription.scopes)) {
|
|
2240
|
+
return false;
|
|
2241
|
+
}
|
|
2242
|
+
if (!doesEventTypeMatch(event.eventType, subscription.eventTypes)) {
|
|
2243
|
+
return false;
|
|
2244
|
+
}
|
|
2245
|
+
if (isItemSubscription(subscription)) {
|
|
2246
|
+
return doesKeyMatch(event.key, subscription.key);
|
|
2247
|
+
} else if (isLocationSubscription(subscription)) {
|
|
2248
|
+
return doesKeyMatchLocation(event.key, subscription.kta, subscription.location);
|
|
2249
|
+
}
|
|
2250
|
+
return false;
|
|
2251
|
+
}
|
|
2252
|
+
function doesScopeMatch(eventScopes, subscriptionScopes) {
|
|
2253
|
+
if (!subscriptionScopes || subscriptionScopes.length === 0) {
|
|
2254
|
+
return true;
|
|
2255
|
+
}
|
|
2256
|
+
return subscriptionScopes.some(
|
|
2257
|
+
(requiredScope) => eventScopes.includes(requiredScope)
|
|
2258
|
+
);
|
|
2259
|
+
}
|
|
2260
|
+
function doesEventTypeMatch(eventType, subscriptionEventTypes) {
|
|
2261
|
+
if (!subscriptionEventTypes || subscriptionEventTypes.length === 0) {
|
|
2262
|
+
return true;
|
|
2263
|
+
}
|
|
2264
|
+
return subscriptionEventTypes.includes(eventType);
|
|
2265
|
+
}
|
|
2266
|
+
function doesKeyMatch(eventKey, subscriptionKey) {
|
|
2267
|
+
if (isPriKey(eventKey) && isPriKey(subscriptionKey)) {
|
|
2268
|
+
return eventKey.pk === subscriptionKey.pk && eventKey.kt === subscriptionKey.kt;
|
|
2269
|
+
}
|
|
2270
|
+
if (isComKey(eventKey) && isComKey(subscriptionKey)) {
|
|
2271
|
+
const eventComKey = eventKey;
|
|
2272
|
+
const subscriptionComKey = subscriptionKey;
|
|
2273
|
+
if (eventComKey.pk !== subscriptionComKey.pk || eventComKey.kt !== subscriptionComKey.kt) {
|
|
2274
|
+
return false;
|
|
2275
|
+
}
|
|
2276
|
+
if (eventComKey.loc.length !== subscriptionComKey.loc.length) {
|
|
2277
|
+
return false;
|
|
2278
|
+
}
|
|
2279
|
+
return eventComKey.loc.every((eventLocKey, index) => {
|
|
2280
|
+
const subLocKey = subscriptionComKey.loc[index];
|
|
2281
|
+
return eventLocKey.lk === subLocKey.lk && eventLocKey.kt === subLocKey.kt;
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
return false;
|
|
2285
|
+
}
|
|
2286
|
+
function doesKeyMatchLocation(eventKey, subscriptionKta, subscriptionLocation) {
|
|
2287
|
+
const targetItemType = subscriptionKta[subscriptionKta.length - 1];
|
|
2288
|
+
if (eventKey.kt !== targetItemType) {
|
|
2289
|
+
return false;
|
|
2290
|
+
}
|
|
2291
|
+
if (isPriKey(eventKey)) {
|
|
2292
|
+
return subscriptionLocation.length === 0;
|
|
2293
|
+
}
|
|
2294
|
+
if (isComKey(eventKey)) {
|
|
2295
|
+
const comKey = eventKey;
|
|
2296
|
+
return doesLocationMatch(comKey.loc, subscriptionLocation, subscriptionKta);
|
|
2297
|
+
}
|
|
2298
|
+
return false;
|
|
2299
|
+
}
|
|
2300
|
+
function doesLocationMatch(eventLocation, subscriptionLocation, _subscriptionKta) {
|
|
2301
|
+
if (subscriptionLocation.length === 0) {
|
|
2302
|
+
return true;
|
|
2303
|
+
}
|
|
2304
|
+
if (eventLocation.length < subscriptionLocation.length) {
|
|
2305
|
+
return false;
|
|
2306
|
+
}
|
|
2307
|
+
for (let i = 0; i < subscriptionLocation.length; i++) {
|
|
2308
|
+
const eventLocKey = eventLocation[i];
|
|
2309
|
+
const subLocKey = subscriptionLocation[i];
|
|
2310
|
+
if (!eventLocKey || !subLocKey) {
|
|
2311
|
+
return false;
|
|
2312
|
+
}
|
|
2313
|
+
if (eventLocKey.lk !== subLocKey.lk || eventLocKey.kt !== subLocKey.kt) {
|
|
2314
|
+
return false;
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
return true;
|
|
2318
|
+
}
|
|
2319
|
+
function findMatchingSubscriptions(event, subscriptions) {
|
|
2320
|
+
return subscriptions.filter(
|
|
2321
|
+
(subscription) => doesEventMatchSubscription(event, subscription)
|
|
2322
|
+
);
|
|
2323
|
+
}
|
|
2324
|
+
function extractLocationValues(location) {
|
|
2325
|
+
return location.map((locKey) => String(locKey.lk));
|
|
2326
|
+
}
|
|
2327
|
+
function compareLocationValues(location1, location2) {
|
|
2328
|
+
if (location1.length !== location2.length) {
|
|
2329
|
+
return false;
|
|
2330
|
+
}
|
|
2331
|
+
return location1.every((locKey1, index) => {
|
|
2332
|
+
const locKey2 = location2[index];
|
|
2333
|
+
return locKey1.lk === locKey2.lk && locKey1.kt === locKey2.kt;
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// src/event/types.ts
|
|
2338
|
+
var STANDARD_EVENT_TYPES = {
|
|
2339
|
+
CREATE: "create",
|
|
2340
|
+
UPDATE: "update",
|
|
2341
|
+
DELETE: "delete",
|
|
2342
|
+
ACTION: "action"
|
|
2343
|
+
};
|
|
2344
|
+
var STANDARD_SCOPES = {
|
|
2345
|
+
FIRESTORE: "firestore",
|
|
2346
|
+
SEQUELIZE: "sequelize",
|
|
2347
|
+
POSTGRESQL: "postgresql",
|
|
2348
|
+
MYSQL: "mysql",
|
|
2349
|
+
MONGODB: "mongodb",
|
|
2350
|
+
REDIS: "redis"
|
|
2351
|
+
};
|
|
2352
|
+
var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
|
|
2353
|
+
SubscriptionStatus2["PENDING"] = "pending";
|
|
2354
|
+
SubscriptionStatus2["ACTIVE"] = "active";
|
|
2355
|
+
SubscriptionStatus2["PAUSED"] = "paused";
|
|
2356
|
+
SubscriptionStatus2["ERROR"] = "error";
|
|
2357
|
+
SubscriptionStatus2["CANCELLED"] = "cancelled";
|
|
2358
|
+
return SubscriptionStatus2;
|
|
2359
|
+
})(SubscriptionStatus || {});
|
|
2360
|
+
var DEFAULT_EVENT_CONFIG = {
|
|
2361
|
+
maxBatchSize: 100,
|
|
2362
|
+
maxBatchWaitTime: 50,
|
|
2363
|
+
// 50ms
|
|
2364
|
+
maxRetryAttempts: 3,
|
|
2365
|
+
retryDelay: 1e3,
|
|
2366
|
+
// 1 second
|
|
2367
|
+
enableStats: true,
|
|
2368
|
+
maxSubscriptions: 1e3,
|
|
2369
|
+
subscriptionCleanupInterval: 3e5
|
|
2370
|
+
// 5 minutes
|
|
2371
|
+
};
|
|
2372
|
+
var EventSystemError = class extends Error {
|
|
2373
|
+
constructor(message, code, details) {
|
|
2374
|
+
super(message);
|
|
2375
|
+
this.code = code;
|
|
2376
|
+
this.details = details;
|
|
2377
|
+
this.name = "EventSystemError";
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
var SubscriptionError = class extends EventSystemError {
|
|
2381
|
+
constructor(message, subscriptionId, details) {
|
|
2382
|
+
super(message, "SUBSCRIPTION_ERROR", { subscriptionId, ...details });
|
|
2383
|
+
this.subscriptionId = subscriptionId;
|
|
2384
|
+
this.name = "SubscriptionError";
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
var EventEmissionError = class extends EventSystemError {
|
|
2388
|
+
constructor(message, eventType, details) {
|
|
2389
|
+
super(message, "EVENT_EMISSION_ERROR", { eventType, ...details });
|
|
2390
|
+
this.eventType = eventType;
|
|
2391
|
+
this.name = "EventEmissionError";
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
var EventMatchingError = class extends EventSystemError {
|
|
2395
|
+
constructor(message, details) {
|
|
2396
|
+
super(message, "EVENT_MATCHING_ERROR", details);
|
|
2397
|
+
this.name = "EventMatchingError";
|
|
2398
|
+
}
|
|
2399
|
+
};
|
|
2400
|
+
function createEventSystemError(type, message, details) {
|
|
2401
|
+
switch (type) {
|
|
2402
|
+
case "subscription":
|
|
2403
|
+
return new SubscriptionError(message, details?.subscriptionId || "unknown", details);
|
|
2404
|
+
case "emission":
|
|
2405
|
+
return new EventEmissionError(message, details?.eventType || "unknown", details);
|
|
2406
|
+
case "matching":
|
|
2407
|
+
return new EventMatchingError(message, details);
|
|
2408
|
+
case "general":
|
|
2409
|
+
default:
|
|
2410
|
+
return new EventSystemError(message, "GENERAL_ERROR", details);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
function isEventSystemError(error) {
|
|
2414
|
+
return error instanceof EventSystemError;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
// src/event/index.ts
|
|
2418
|
+
var EVENT_SYSTEM_VERSION = "1.0.0";
|
|
2419
|
+
var SUPPORTED_EVENT_TYPES = [
|
|
2420
|
+
"create",
|
|
2421
|
+
"update",
|
|
2422
|
+
"delete",
|
|
2423
|
+
"action"
|
|
2424
|
+
];
|
|
2425
|
+
var SUPPORTED_SCOPES = [
|
|
2426
|
+
"firestore",
|
|
2427
|
+
"sequelize",
|
|
2428
|
+
"postgresql",
|
|
2429
|
+
"mysql",
|
|
2430
|
+
"mongodb",
|
|
2431
|
+
"redis"
|
|
2432
|
+
];
|
|
2580
2433
|
export {
|
|
2581
2434
|
AItemService,
|
|
2582
2435
|
ActionError,
|
|
@@ -2649,7 +2502,6 @@ export {
|
|
|
2649
2502
|
isComKey,
|
|
2650
2503
|
isComKeyEqual,
|
|
2651
2504
|
isComKeyEqualNormalized,
|
|
2652
|
-
isCondition,
|
|
2653
2505
|
isCreateEvent,
|
|
2654
2506
|
isDeleteEvent,
|
|
2655
2507
|
isEventSystemError,
|
|
@@ -2661,8 +2513,6 @@ export {
|
|
|
2661
2513
|
isLocKeyEqual,
|
|
2662
2514
|
isLocKeyEqualNormalized,
|
|
2663
2515
|
isLocationSubscription,
|
|
2664
|
-
isComKey2 as isOperationComKey,
|
|
2665
|
-
isPriKey2 as isOperationPriKey,
|
|
2666
2516
|
isPriItem,
|
|
2667
2517
|
isPriKey,
|
|
2668
2518
|
isPriKeyEqual,
|
|
@@ -2673,7 +2523,6 @@ export {
|
|
|
2673
2523
|
isValidItemKey,
|
|
2674
2524
|
isValidLocKey,
|
|
2675
2525
|
isValidLocKeyArray,
|
|
2676
|
-
isValidLocations,
|
|
2677
2526
|
isValidPriKey,
|
|
2678
2527
|
itemKeyToLocKeyArray,
|
|
2679
2528
|
lkaToIK,
|
|
@@ -2681,17 +2530,5 @@ export {
|
|
|
2681
2530
|
paramsToQuery,
|
|
2682
2531
|
primaryType,
|
|
2683
2532
|
queryToParams,
|
|
2684
|
-
toKeyTypeArray
|
|
2685
|
-
validateActionName,
|
|
2686
|
-
validateComKey,
|
|
2687
|
-
validateFacetName,
|
|
2688
|
-
validateFinderName,
|
|
2689
|
-
validateKey,
|
|
2690
|
-
validateKeys,
|
|
2691
|
-
validateLocations,
|
|
2692
|
-
validateOperationParams,
|
|
2693
|
-
validatePK,
|
|
2694
|
-
validatePriKey,
|
|
2695
|
-
validateQuery,
|
|
2696
|
-
validateSchema
|
|
2533
|
+
toKeyTypeArray
|
|
2697
2534
|
};
|