@fjell/lib-sequelize 4.4.5 → 4.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Coordinate.cjs +9 -22
- package/dist/cjs/Definition.cjs +5 -26
- package/dist/cjs/Instance.cjs +26 -10
- package/dist/cjs/InstanceFactory.cjs +25 -0
- package/dist/cjs/Operations.cjs +7 -2
- package/dist/cjs/Options.cjs +14 -7
- package/dist/cjs/QueryBuilder.cjs +31 -25
- package/dist/cjs/contained/Instance.cjs +15 -8
- package/dist/cjs/index.cjs +7 -4
- package/dist/cjs/ops/all.cjs +44 -20
- package/dist/cjs/ops/create.cjs +138 -40
- package/dist/cjs/ops/find.cjs +9 -7
- package/dist/cjs/ops/get.cjs +9 -5
- package/dist/cjs/ops/one.cjs +7 -6
- package/dist/cjs/ops/remove.cjs +10 -7
- package/dist/cjs/ops/update.cjs +10 -7
- package/dist/cjs/primary/Instance.cjs +16 -9
- package/dist/cjs/util/general.cjs +1 -5
- package/dist/es/Coordinate.js +9 -3
- package/dist/es/Definition.js +5 -7
- package/dist/es/Instance.js +26 -11
- package/dist/es/InstanceFactory.js +21 -0
- package/dist/es/Operations.js +7 -2
- package/dist/es/Options.js +14 -7
- package/dist/es/QueryBuilder.js +31 -25
- package/dist/es/contained/Instance.js +15 -8
- package/dist/es/index.js +4 -3
- package/dist/es/ops/all.js +44 -20
- package/dist/es/ops/create.js +139 -41
- package/dist/es/ops/find.js +9 -7
- package/dist/es/ops/get.js +9 -5
- package/dist/es/ops/one.js +7 -6
- package/dist/es/ops/remove.js +11 -8
- package/dist/es/ops/update.js +11 -8
- package/dist/es/primary/Instance.js +16 -9
- package/dist/es/util/general.js +2 -5
- package/dist/index.cjs +412 -216
- package/dist/index.cjs.map +1 -1
- package/dist/types/AggregationBuilder.d.ts +1 -1
- package/dist/types/Coordinate.d.ts +3 -2
- package/dist/types/Definition.d.ts +3 -3
- package/dist/types/Instance.d.ts +22 -2
- package/dist/types/InstanceFactory.d.ts +14 -0
- package/dist/types/Operations.d.ts +3 -2
- package/dist/types/Options.d.ts +1 -1
- package/dist/types/Registry.d.ts +6 -0
- package/dist/types/contained/Instance.d.ts +3 -3
- package/dist/types/index.d.ts +4 -1
- package/dist/types/primary/Instance.d.ts +2 -2
- package/package.json +23 -23
package/dist/index.cjs
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const Library = require('@fjell/lib');
|
|
6
|
-
const deepmerge = require('deepmerge');
|
|
7
6
|
const Logging = require('@fjell/logging');
|
|
7
|
+
const registry = require('@fjell/registry');
|
|
8
8
|
const core = require('@fjell/core');
|
|
9
9
|
const sequelize = require('sequelize');
|
|
10
|
+
require('deepmerge');
|
|
10
11
|
|
|
11
12
|
function _interopNamespaceDefault(e) {
|
|
12
13
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
|
@@ -27,20 +28,58 @@ function _interopNamespaceDefault(e) {
|
|
|
27
28
|
|
|
28
29
|
const Library__namespace = /*#__PURE__*/_interopNamespaceDefault(Library);
|
|
29
30
|
|
|
31
|
+
const DEFAULT_SEQUELIZE_OPTIONS = {
|
|
32
|
+
deleteOnRemove: false,
|
|
33
|
+
references: [],
|
|
34
|
+
aggregations: []
|
|
35
|
+
};
|
|
36
|
+
const createOptions = (sequelizeOptions)=>{
|
|
37
|
+
// Create the base lib options
|
|
38
|
+
const baseOptions = Library__namespace.createOptions(sequelizeOptions);
|
|
39
|
+
var _sequelizeOptions_deleteOnRemove, _sequelizeOptions_references, _sequelizeOptions_aggregations;
|
|
40
|
+
// Add Sequelize-specific defaults
|
|
41
|
+
const result = {
|
|
42
|
+
...baseOptions,
|
|
43
|
+
deleteOnRemove: (_sequelizeOptions_deleteOnRemove = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.deleteOnRemove) !== null && _sequelizeOptions_deleteOnRemove !== void 0 ? _sequelizeOptions_deleteOnRemove : DEFAULT_SEQUELIZE_OPTIONS.deleteOnRemove,
|
|
44
|
+
references: (_sequelizeOptions_references = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.references) !== null && _sequelizeOptions_references !== void 0 ? _sequelizeOptions_references : DEFAULT_SEQUELIZE_OPTIONS.references,
|
|
45
|
+
aggregations: (_sequelizeOptions_aggregations = sequelizeOptions === null || sequelizeOptions === void 0 ? void 0 : sequelizeOptions.aggregations) !== null && _sequelizeOptions_aggregations !== void 0 ? _sequelizeOptions_aggregations : DEFAULT_SEQUELIZE_OPTIONS.aggregations
|
|
46
|
+
};
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const logger$1.default = Logging.getLogger('@fjell/lib-sequelize');
|
|
51
|
+
|
|
52
|
+
const logger$i = logger$1.default.get('Coordinate');
|
|
30
53
|
const SCOPE_SEQUELIZE = 'sequelize';
|
|
31
54
|
const createCoordinate = (kta, scopes)=>{
|
|
32
|
-
|
|
55
|
+
logger$i.debug('createCoordinate', {
|
|
56
|
+
kta,
|
|
57
|
+
scopes
|
|
58
|
+
});
|
|
59
|
+
const coordinate = registry.createCoordinate(kta, [
|
|
33
60
|
SCOPE_SEQUELIZE,
|
|
34
61
|
...scopes || []
|
|
35
62
|
]);
|
|
36
63
|
return coordinate;
|
|
37
64
|
};
|
|
38
65
|
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
const logger$h = logger$1.default.get('lib-sequelize', 'Definition');
|
|
67
|
+
const createDefinition = (kta, scopes, libOptions)=>{
|
|
68
|
+
logger$h.debug('createDefinition', {
|
|
69
|
+
kta,
|
|
70
|
+
scopes,
|
|
71
|
+
libOptions
|
|
72
|
+
});
|
|
73
|
+
const coordinate = createCoordinate(kta, scopes);
|
|
74
|
+
const options = createOptions(libOptions);
|
|
75
|
+
return {
|
|
76
|
+
coordinate,
|
|
77
|
+
options
|
|
78
|
+
};
|
|
41
79
|
};
|
|
80
|
+
|
|
42
81
|
//Recursive implementation of jSON.stringify;
|
|
43
|
-
const
|
|
82
|
+
const stringifyJSON = function(obj, visited = new Set()) {
|
|
44
83
|
const arrOfKeyVals = [];
|
|
45
84
|
const arrVals = [];
|
|
46
85
|
let objKeys = [];
|
|
@@ -55,7 +94,7 @@ const general.stringifyJSON = function(obj, visited = new Set()) {
|
|
|
55
94
|
// Add array to visited before processing its elements
|
|
56
95
|
visited.add(obj);
|
|
57
96
|
obj.forEach(function(el) {
|
|
58
|
-
arrVals.push(
|
|
97
|
+
arrVals.push(stringifyJSON(el, visited));
|
|
59
98
|
});
|
|
60
99
|
return '[' + arrVals + ']';
|
|
61
100
|
}
|
|
@@ -73,7 +112,7 @@ const general.stringifyJSON = function(obj, visited = new Set()) {
|
|
|
73
112
|
else if (typeof keyValOut === 'string') arrOfKeyVals.push(keyOut + '"' + keyValOut + '"');
|
|
74
113
|
else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null) arrOfKeyVals.push(keyOut + keyValOut);
|
|
75
114
|
else if (keyValOut instanceof Object) {
|
|
76
|
-
arrOfKeyVals.push(keyOut +
|
|
115
|
+
arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));
|
|
77
116
|
}
|
|
78
117
|
});
|
|
79
118
|
return '{' + arrOfKeyVals + '}';
|
|
@@ -81,39 +120,9 @@ const general.stringifyJSON = function(obj, visited = new Set()) {
|
|
|
81
120
|
return '';
|
|
82
121
|
};
|
|
83
122
|
|
|
84
|
-
const
|
|
85
|
-
deleteOnRemove: false,
|
|
86
|
-
references: [],
|
|
87
|
-
aggregations: []
|
|
88
|
-
};
|
|
89
|
-
const createOptions = (libOptions)=>{
|
|
90
|
-
const options = Library__namespace.createOptions(libOptions);
|
|
91
|
-
return deepmerge(DEFAULT_OPTIONS, clean(options));
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const logger$1.default = Logging.getLogger('@fjell/lib-sequelize');
|
|
95
|
-
|
|
96
|
-
const logger$f = logger$1.default.get('lib-sequelize', 'Definition');
|
|
97
|
-
function createDefinition(kta, scopes, libOptions) {
|
|
98
|
-
logger$f.debug('createDefinition', {
|
|
99
|
-
kta,
|
|
100
|
-
scopes,
|
|
101
|
-
libOptions
|
|
102
|
-
});
|
|
103
|
-
const coordinate = createCoordinate(kta, scopes);
|
|
104
|
-
const options = createOptions(libOptions);
|
|
105
|
-
const definition = Library__namespace.createDefinition(coordinate, options);
|
|
106
|
-
return {
|
|
107
|
-
...definition,
|
|
108
|
-
options
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const logger$e = logger$1.default.get('sequelize', 'QueryBuilder');
|
|
123
|
+
const logger$g = logger$1.default.get('sequelize', 'QueryBuilder');
|
|
113
124
|
const addDeleteQuery = (options, model)=>{
|
|
114
|
-
logger$
|
|
115
|
-
options
|
|
116
|
-
});
|
|
125
|
+
logger$g.default(`QueryBuilder adding delete query with options: ${stringifyJSON(options)}`);
|
|
117
126
|
if (model.getAttributes().deletedAt) {
|
|
118
127
|
options.where['deletedAt'] = {
|
|
119
128
|
[sequelize.Op.eq]: null
|
|
@@ -126,10 +135,7 @@ const addDeleteQuery = (options, model)=>{
|
|
|
126
135
|
return options;
|
|
127
136
|
};
|
|
128
137
|
const addEventQueries = (options, events, model)=>{
|
|
129
|
-
logger$
|
|
130
|
-
options,
|
|
131
|
-
events
|
|
132
|
-
});
|
|
138
|
+
logger$g.default(`QueryBuilder adding event queries with options: ${stringifyJSON(options)}, events: ${stringifyJSON(events)}`);
|
|
133
139
|
Object.keys(events).forEach((key)=>{
|
|
134
140
|
if (!model.getAttributes()[`${key}At`]) {
|
|
135
141
|
throw new Error(`Event ${key} is not supported on this model, column ${key}At not found`);
|
|
@@ -163,20 +169,22 @@ const addEventQueries = (options, events, model)=>{
|
|
|
163
169
|
};
|
|
164
170
|
// Add the references to the query
|
|
165
171
|
const addReferenceQueries = (options, references, model)=>{
|
|
166
|
-
logger$
|
|
167
|
-
options,
|
|
168
|
-
references
|
|
169
|
-
});
|
|
172
|
+
logger$g.default(`QueryBuilder adding reference queries with options: ${stringifyJSON(options)}, references: ${stringifyJSON(references)}`);
|
|
170
173
|
Object.keys(references).forEach((key)=>{
|
|
171
|
-
logger$
|
|
172
|
-
key,
|
|
173
|
-
references
|
|
174
|
-
});
|
|
174
|
+
logger$g.default(`QueryBuilder adding reference query for key: ${key}, references: ${stringifyJSON(references)}`);
|
|
175
175
|
if (!model.getAttributes()[`${key}Id`]) {
|
|
176
176
|
throw new Error(`Reference ${key} is not supported on this model, column ${key}Id not found`);
|
|
177
177
|
}
|
|
178
178
|
if (core.isPriKey(references[key])) {
|
|
179
179
|
const priKey = references[key];
|
|
180
|
+
if (priKey.pk == null || priKey.pk === '' || typeof priKey.pk === 'object' && Object.keys(priKey.pk).length === 0) {
|
|
181
|
+
logger$g.error(`Reference key '${key}' has invalid pk value: ${stringifyJSON(priKey.pk)}`, {
|
|
182
|
+
priKey,
|
|
183
|
+
references
|
|
184
|
+
});
|
|
185
|
+
throw new Error(`Reference key '${key}' has invalid pk value: ${stringifyJSON(priKey.pk)}`);
|
|
186
|
+
}
|
|
187
|
+
logger$g.trace(`[QueryBuilder] Setting reference where clause: ${key}Id = ${stringifyJSON(priKey.pk)} (type: ${typeof priKey.pk})`);
|
|
180
188
|
options.where[`${key}Id`] = {
|
|
181
189
|
[sequelize.Op.eq]: priKey.pk
|
|
182
190
|
};
|
|
@@ -253,6 +261,13 @@ const addAssociationCondition = (conditions, condition, model)=>{
|
|
|
253
261
|
// Use Sequelize's $association.attribute$ syntax for querying associated models
|
|
254
262
|
const sequelizeAssociationColumn = `$${associationName}.${attributeName}$`;
|
|
255
263
|
const conditionOp = getSequelizeOperator(condition.operator);
|
|
264
|
+
if (condition.value == null && condition.operator !== '==' && condition.operator !== 'in') {
|
|
265
|
+
logger$g.error(`Association condition for '${associationName}.${attributeName}' has undefined/null value`, {
|
|
266
|
+
condition
|
|
267
|
+
});
|
|
268
|
+
throw new Error(`Association condition for '${associationName}.${attributeName}' has undefined/null value`);
|
|
269
|
+
}
|
|
270
|
+
logger$g.trace(`[QueryBuilder] Setting association condition: ${sequelizeAssociationColumn} = ${stringifyJSON(condition.value)} (type: ${typeof condition.value})`);
|
|
256
271
|
conditions[sequelizeAssociationColumn] = {
|
|
257
272
|
[conditionOp]: condition.value
|
|
258
273
|
};
|
|
@@ -264,6 +279,13 @@ const addAttributeCondition = (conditions, condition, model)=>{
|
|
|
264
279
|
throw new Error(`Condition column ${conditionColumn} not found on model ${model.name}`);
|
|
265
280
|
}
|
|
266
281
|
const conditionOp = getSequelizeOperator(condition.operator);
|
|
282
|
+
if (condition.value == null && condition.operator !== '==' && condition.operator !== 'in') {
|
|
283
|
+
logger$g.error(`Attribute condition for '${conditionColumn}' has undefined/null value`, {
|
|
284
|
+
condition
|
|
285
|
+
});
|
|
286
|
+
throw new Error(`Attribute condition for '${conditionColumn}' has undefined/null value`);
|
|
287
|
+
}
|
|
288
|
+
logger$g.trace(`[QueryBuilder] Setting attribute condition: ${conditionColumn} = ${stringifyJSON(condition.value)} (type: ${typeof condition.value})`);
|
|
267
289
|
conditions[conditionColumn] = {
|
|
268
290
|
[conditionOp]: condition.value
|
|
269
291
|
};
|
|
@@ -334,16 +356,12 @@ const addAssociationIncludes = (options, model)=>{
|
|
|
334
356
|
return options;
|
|
335
357
|
};
|
|
336
358
|
const buildQuery = (itemQuery, model)=>{
|
|
337
|
-
logger$
|
|
338
|
-
itemQuery
|
|
339
|
-
});
|
|
359
|
+
logger$g.default(`QueryBuilder build called with itemQuery: ${stringifyJSON(itemQuery)}`);
|
|
340
360
|
let options = {
|
|
341
361
|
where: {}
|
|
342
362
|
};
|
|
343
363
|
if (itemQuery.compoundCondition) {
|
|
344
|
-
logger$
|
|
345
|
-
compoundCondition: itemQuery.compoundCondition
|
|
346
|
-
});
|
|
364
|
+
logger$g.default(`QueryBuilder adding conditions: ${stringifyJSON(itemQuery.compoundCondition)}`);
|
|
347
365
|
options = addCompoundCondition(options, itemQuery.compoundCondition, model);
|
|
348
366
|
}
|
|
349
367
|
// If the model has a deletedAt column, we need to add a delete query
|
|
@@ -359,9 +377,7 @@ const buildQuery = (itemQuery, model)=>{
|
|
|
359
377
|
// TODO: Once we start to support Aggs on the server-side, we'll need to parse agg queries
|
|
360
378
|
// Apply a limit to the result set
|
|
361
379
|
if (itemQuery.limit) {
|
|
362
|
-
logger$
|
|
363
|
-
limit: itemQuery.limit
|
|
364
|
-
});
|
|
380
|
+
logger$g.default(`QueryBuilder applying limit: ${itemQuery.limit}`);
|
|
365
381
|
options.limit = itemQuery.limit;
|
|
366
382
|
}
|
|
367
383
|
// Apply an offset to the result set
|
|
@@ -497,10 +513,10 @@ const buildQuery = (itemQuery, model)=>{
|
|
|
497
513
|
return result;
|
|
498
514
|
};
|
|
499
515
|
|
|
500
|
-
const logger$
|
|
516
|
+
const logger$f = logger$1.default.get('sequelize', 'KeyMaster');
|
|
501
517
|
// Helper function to extract location key value from item
|
|
502
518
|
const extractLocationKeyValue = (model, item, locatorType, kta)=>{
|
|
503
|
-
logger$
|
|
519
|
+
logger$f.default('Extracting location key value', {
|
|
504
520
|
locatorType,
|
|
505
521
|
kta
|
|
506
522
|
});
|
|
@@ -555,7 +571,7 @@ const extractLocationKeyValue = (model, item, locatorType, kta)=>{
|
|
|
555
571
|
}
|
|
556
572
|
};
|
|
557
573
|
const removeKey = (item)=>{
|
|
558
|
-
logger$
|
|
574
|
+
logger$f.default('Removing Key', {
|
|
559
575
|
item
|
|
560
576
|
});
|
|
561
577
|
delete item.key;
|
|
@@ -589,7 +605,7 @@ const removeKey = (item)=>{
|
|
|
589
605
|
// return item;
|
|
590
606
|
// }
|
|
591
607
|
const addKey = (model, item, keyTypes)=>{
|
|
592
|
-
logger$
|
|
608
|
+
logger$f.default('Adding Key', {
|
|
593
609
|
item
|
|
594
610
|
});
|
|
595
611
|
const key = {};
|
|
@@ -615,7 +631,7 @@ const addKey = (model, item, keyTypes)=>{
|
|
|
615
631
|
});
|
|
616
632
|
} catch (error) {
|
|
617
633
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
618
|
-
logger$
|
|
634
|
+
logger$f.error(`Failed to extract location key for '${locatorType}'`, {
|
|
619
635
|
error: errorMessage,
|
|
620
636
|
item,
|
|
621
637
|
keyTypes
|
|
@@ -638,7 +654,7 @@ const addKey = (model, item, keyTypes)=>{
|
|
|
638
654
|
return item;
|
|
639
655
|
};
|
|
640
656
|
|
|
641
|
-
const logger$
|
|
657
|
+
const logger$e = logger$1.default.get('sequelize', 'ReferenceBuilder');
|
|
642
658
|
const buildReference = async (item, referenceDefinition, registry, context)=>{
|
|
643
659
|
// Check if there is more than one key type
|
|
644
660
|
if (referenceDefinition.kta.length > 1) {
|
|
@@ -668,13 +684,13 @@ const buildReference = async (item, referenceDefinition, registry, context)=>{
|
|
|
668
684
|
if (context) {
|
|
669
685
|
// Check if we already have this item cached
|
|
670
686
|
if (context.isCached(priKey)) {
|
|
671
|
-
logger$
|
|
687
|
+
logger$e.default('Using cached reference', {
|
|
672
688
|
priKey,
|
|
673
689
|
property: referenceDefinition.property
|
|
674
690
|
});
|
|
675
691
|
referencedItem = context.getCached(priKey);
|
|
676
692
|
} else if (context.isInProgress(priKey)) {
|
|
677
|
-
logger$
|
|
693
|
+
logger$e.default('Circular dependency detected, creating reference placeholder', {
|
|
678
694
|
priKey,
|
|
679
695
|
property: referenceDefinition.property
|
|
680
696
|
});
|
|
@@ -719,7 +735,7 @@ function _define_property(obj, key, value) {
|
|
|
719
735
|
}
|
|
720
736
|
return obj;
|
|
721
737
|
}
|
|
722
|
-
const logger$
|
|
738
|
+
const logger$d = logger$1.default.get('sequelize', 'OperationContext');
|
|
723
739
|
/**
|
|
724
740
|
* Serialize an ItemKey to a string for use in sets and maps
|
|
725
741
|
*/ const OperationContext.serializeKey = (key)=>{
|
|
@@ -743,7 +759,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
743
759
|
cache,
|
|
744
760
|
markInProgress (key) {
|
|
745
761
|
const serialized = OperationContext.serializeKey(key);
|
|
746
|
-
logger$
|
|
762
|
+
logger$d.default('Marking key as in progress', {
|
|
747
763
|
key,
|
|
748
764
|
serialized
|
|
749
765
|
});
|
|
@@ -751,7 +767,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
751
767
|
},
|
|
752
768
|
markComplete (key) {
|
|
753
769
|
const serialized = OperationContext.serializeKey(key);
|
|
754
|
-
logger$
|
|
770
|
+
logger$d.default('Marking key as complete', {
|
|
755
771
|
key,
|
|
756
772
|
serialized
|
|
757
773
|
});
|
|
@@ -760,7 +776,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
760
776
|
isInProgress (key) {
|
|
761
777
|
const serialized = OperationContext.serializeKey(key);
|
|
762
778
|
const result = inProgress.has(serialized);
|
|
763
|
-
logger$
|
|
779
|
+
logger$d.default('Checking if key is in progress', {
|
|
764
780
|
key,
|
|
765
781
|
serialized,
|
|
766
782
|
result
|
|
@@ -770,7 +786,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
770
786
|
getCached (key) {
|
|
771
787
|
const serialized = OperationContext.serializeKey(key);
|
|
772
788
|
const result = cache.get(serialized);
|
|
773
|
-
logger$
|
|
789
|
+
logger$d.default('Getting cached item', {
|
|
774
790
|
key,
|
|
775
791
|
serialized,
|
|
776
792
|
found: !!result
|
|
@@ -779,7 +795,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
779
795
|
},
|
|
780
796
|
setCached (key, item) {
|
|
781
797
|
const serialized = OperationContext.serializeKey(key);
|
|
782
|
-
logger$
|
|
798
|
+
logger$d.default('Caching item', {
|
|
783
799
|
key,
|
|
784
800
|
serialized
|
|
785
801
|
});
|
|
@@ -788,7 +804,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
788
804
|
isCached (key) {
|
|
789
805
|
const serialized = OperationContext.serializeKey(key);
|
|
790
806
|
const result = cache.has(serialized);
|
|
791
|
-
logger$
|
|
807
|
+
logger$d.default('Checking if key is cached', {
|
|
792
808
|
key,
|
|
793
809
|
serialized,
|
|
794
810
|
result
|
|
@@ -806,7 +822,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
806
822
|
const contextId = Math.random().toString(36).substring(7);
|
|
807
823
|
this.contexts.set(contextId, context);
|
|
808
824
|
this.currentContextId = contextId;
|
|
809
|
-
logger$
|
|
825
|
+
logger$d.default('Set current context', {
|
|
810
826
|
contextId
|
|
811
827
|
});
|
|
812
828
|
return contextId;
|
|
@@ -816,7 +832,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
816
832
|
*/ getCurrentContext() {
|
|
817
833
|
if (this.currentContextId) {
|
|
818
834
|
const context = this.contexts.get(this.currentContextId);
|
|
819
|
-
logger$
|
|
835
|
+
logger$d.default('Got current context', {
|
|
820
836
|
contextId: this.currentContextId,
|
|
821
837
|
found: !!context
|
|
822
838
|
});
|
|
@@ -828,7 +844,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
828
844
|
* Clear the current context
|
|
829
845
|
*/ clearCurrentContext() {
|
|
830
846
|
if (this.currentContextId) {
|
|
831
|
-
logger$
|
|
847
|
+
logger$d.default('Clearing current context', {
|
|
832
848
|
contextId: this.currentContextId
|
|
833
849
|
});
|
|
834
850
|
this.contexts.delete(this.currentContextId);
|
|
@@ -857,7 +873,7 @@ const logger$b = logger$1.default.get('sequelize', 'OperationContext');
|
|
|
857
873
|
// Global context manager instance
|
|
858
874
|
const OperationContext.contextManager = new ContextManager();
|
|
859
875
|
|
|
860
|
-
const logger$
|
|
876
|
+
const logger$c = logger$1.default.get('sequelize', 'AggregationBuilder');
|
|
861
877
|
const buildAggregation = async (item, aggregationDefinition, registry, context)=>{
|
|
862
878
|
const location = core.ikToLKA(item.key);
|
|
863
879
|
// Get the library instance from the registry using the key type array
|
|
@@ -872,7 +888,7 @@ const buildAggregation = async (item, aggregationDefinition, registry, context)=
|
|
|
872
888
|
// Check if this aggregation is already cached
|
|
873
889
|
if (context.cache.has(aggregationCacheKey)) {
|
|
874
890
|
const cachedResult = context.cache.get(aggregationCacheKey);
|
|
875
|
-
logger$
|
|
891
|
+
logger$c.default('Using cached aggregation result', {
|
|
876
892
|
aggregationCacheKey,
|
|
877
893
|
property: aggregationDefinition.property
|
|
878
894
|
});
|
|
@@ -912,7 +928,7 @@ const buildAggregation = async (item, aggregationDefinition, registry, context)=
|
|
|
912
928
|
});
|
|
913
929
|
};
|
|
914
930
|
|
|
915
|
-
const logger$
|
|
931
|
+
const logger$b = logger$1.default.get("sequelize", "EventCoordinator");
|
|
916
932
|
//#endregion
|
|
917
933
|
const populateEvents = (item)=>{
|
|
918
934
|
const events = {
|
|
@@ -930,7 +946,7 @@ const populateEvents = (item)=>{
|
|
|
930
946
|
return item;
|
|
931
947
|
};
|
|
932
948
|
const extractEvents = (item)=>{
|
|
933
|
-
logger$
|
|
949
|
+
logger$b.default('Extracting Events to database fields', {
|
|
934
950
|
item
|
|
935
951
|
});
|
|
936
952
|
if (item.events) {
|
|
@@ -948,16 +964,16 @@ const extractEvents = (item)=>{
|
|
|
948
964
|
return item;
|
|
949
965
|
};
|
|
950
966
|
const removeEvents = (item)=>{
|
|
951
|
-
logger$
|
|
967
|
+
logger$b.default('Removing Events', {
|
|
952
968
|
item
|
|
953
969
|
});
|
|
954
970
|
delete item.events;
|
|
955
971
|
return item;
|
|
956
972
|
};
|
|
957
973
|
|
|
958
|
-
const logger$
|
|
974
|
+
const logger$a = logger$1.default.get('sequelize', 'RowProcessor');
|
|
959
975
|
const processRow = async (row, keyTypes, referenceDefinitions, aggregationDefinitions, registry, context)=>{
|
|
960
|
-
logger$
|
|
976
|
+
logger$a.default('Processing Row', {
|
|
961
977
|
row
|
|
962
978
|
});
|
|
963
979
|
// Use provided context or create new one
|
|
@@ -967,22 +983,22 @@ const processRow = async (row, keyTypes, referenceDefinitions, aggregationDefini
|
|
|
967
983
|
let item = row.get({
|
|
968
984
|
plain: true
|
|
969
985
|
});
|
|
970
|
-
logger$
|
|
986
|
+
logger$a.default('Adding Key to Item with Key Types: %s', stringifyJSON(keyTypes));
|
|
971
987
|
item = addKey(row, item, keyTypes);
|
|
972
988
|
item = populateEvents(item);
|
|
973
|
-
logger$
|
|
989
|
+
logger$a.default('Key Added to Item: %s', stringifyJSON(item.key));
|
|
974
990
|
// Mark this item as in progress to detect circular references
|
|
975
991
|
operationContext.markInProgress(item.key);
|
|
976
992
|
try {
|
|
977
993
|
if (referenceDefinitions && referenceDefinitions.length > 0) {
|
|
978
994
|
for (const referenceDefinition of referenceDefinitions){
|
|
979
|
-
logger$
|
|
995
|
+
logger$a.default('Processing Reference for %s to %s', item.key.kt, stringifyJSON(referenceDefinition.kta));
|
|
980
996
|
item = await buildReference(item, referenceDefinition, registry, operationContext);
|
|
981
997
|
}
|
|
982
998
|
}
|
|
983
999
|
if (aggregationDefinitions && aggregationDefinitions.length > 0) {
|
|
984
1000
|
for (const aggregationDefinition of aggregationDefinitions){
|
|
985
|
-
logger$
|
|
1001
|
+
logger$a.default('Processing Aggregation for %s from %s', item.key.kt, stringifyJSON(aggregationDefinition.kta));
|
|
986
1002
|
item = await buildAggregation(item, aggregationDefinition, registry, operationContext);
|
|
987
1003
|
}
|
|
988
1004
|
}
|
|
@@ -992,12 +1008,12 @@ const processRow = async (row, keyTypes, referenceDefinitions, aggregationDefini
|
|
|
992
1008
|
// Mark this item as complete
|
|
993
1009
|
operationContext.markComplete(item.key);
|
|
994
1010
|
}
|
|
995
|
-
logger$
|
|
1011
|
+
logger$a.default('Processed Row: %j', stringifyJSON(item));
|
|
996
1012
|
return item;
|
|
997
1013
|
});
|
|
998
1014
|
};
|
|
999
1015
|
|
|
1000
|
-
const logger$
|
|
1016
|
+
const logger$9 = logger$1.default.get('sequelize', 'ops', 'all');
|
|
1001
1017
|
// Helper function to merge includes avoiding duplicates
|
|
1002
1018
|
const mergeIncludes$1 = (existingIncludes, newIncludes)=>{
|
|
1003
1019
|
const mergedIncludes = [
|
|
@@ -1022,10 +1038,8 @@ const all.getAllOperation = (models, definition, registry)=>{
|
|
|
1022
1038
|
const { coordinate, options: { references, aggregations } } = definition;
|
|
1023
1039
|
//#region Query
|
|
1024
1040
|
const all = async (itemQuery, locations)=>{
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
locations
|
|
1028
|
-
});
|
|
1041
|
+
var _options_include;
|
|
1042
|
+
logger$9.debug(`ALL operation called on ${models[0].name} with ${(locations === null || locations === void 0 ? void 0 : locations.length) || 0} location filters: ${(locations === null || locations === void 0 ? void 0 : locations.map((loc)=>`${loc.kt}=${loc.lk}`).join(', ')) || 'none'}`);
|
|
1029
1043
|
const loc = locations || [];
|
|
1030
1044
|
// @ts-ignore
|
|
1031
1045
|
const model = models[0];
|
|
@@ -1042,7 +1056,7 @@ const all.getAllOperation = (models, definition, registry)=>{
|
|
|
1042
1056
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta, true);
|
|
1043
1057
|
if (!relationshipInfo.found) {
|
|
1044
1058
|
const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1045
|
-
logger$
|
|
1059
|
+
logger$9.error(errorMessage, {
|
|
1046
1060
|
locations: loc,
|
|
1047
1061
|
kta
|
|
1048
1062
|
});
|
|
@@ -1056,24 +1070,44 @@ const all.getAllOperation = (models, definition, registry)=>{
|
|
|
1056
1070
|
}
|
|
1057
1071
|
// Handle direct location keys (simple foreign key constraints)
|
|
1058
1072
|
for (const locKey of directLocations){
|
|
1073
|
+
if (locKey.lk === undefined || locKey.lk == null || locKey.lk === '' || typeof locKey.lk === 'object' && Object.keys(locKey.lk).length === 0) {
|
|
1074
|
+
logger$9.error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, {
|
|
1075
|
+
locKey,
|
|
1076
|
+
locations: loc
|
|
1077
|
+
});
|
|
1078
|
+
throw new Error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1079
|
+
}
|
|
1059
1080
|
const foreignKeyField = locKey.kt + 'Id';
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
[
|
|
1063
|
-
|
|
1064
|
-
|
|
1081
|
+
// Check if this field already has a condition from the itemQuery
|
|
1082
|
+
if (options.where[foreignKeyField]) {
|
|
1083
|
+
logger$9.debug(`[ALL] Field ${foreignKeyField} already constrained by itemQuery, skipping location constraint to avoid conflicts`);
|
|
1084
|
+
continue; // Skip this location constraint to avoid conflicts
|
|
1085
|
+
}
|
|
1086
|
+
logger$9.trace(`[ALL] Setting direct location where clause: ${foreignKeyField} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1087
|
+
options.where[foreignKeyField] = {
|
|
1088
|
+
[sequelize.Op.eq]: locKey.lk
|
|
1065
1089
|
};
|
|
1066
1090
|
}
|
|
1067
1091
|
// Handle hierarchical location keys (requires relationship traversal)
|
|
1068
1092
|
for (const locKey of hierarchicalLocations){
|
|
1093
|
+
if (locKey.lk === undefined || locKey.lk == null || locKey.lk === '' || typeof locKey.lk === 'object' && Object.keys(locKey.lk).length === 0) {
|
|
1094
|
+
logger$9.error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, {
|
|
1095
|
+
locKey,
|
|
1096
|
+
locations: loc
|
|
1097
|
+
});
|
|
1098
|
+
throw new Error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1099
|
+
}
|
|
1069
1100
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta);
|
|
1070
1101
|
if (relationshipInfo.found && relationshipInfo.path) {
|
|
1102
|
+
// Check if this field already has a condition from the itemQuery
|
|
1103
|
+
if (options.where[relationshipInfo.path]) {
|
|
1104
|
+
logger$9.debug(`[ALL] Field ${relationshipInfo.path} already constrained by itemQuery, skipping hierarchical location constraint to avoid conflicts`);
|
|
1105
|
+
continue; // Skip this location constraint to avoid conflicts
|
|
1106
|
+
}
|
|
1071
1107
|
// Add the relationship constraint using the path
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
[
|
|
1075
|
-
[sequelize.Op.eq]: locKey.lk
|
|
1076
|
-
}
|
|
1108
|
+
logger$9.trace(`[ALL] Setting hierarchical location where clause: ${relationshipInfo.path} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1109
|
+
options.where[relationshipInfo.path] = {
|
|
1110
|
+
[sequelize.Op.eq]: locKey.lk
|
|
1077
1111
|
};
|
|
1078
1112
|
// Add necessary includes for the relationship traversal
|
|
1079
1113
|
if (relationshipInfo.includes) {
|
|
@@ -1087,63 +1121,134 @@ const all.getAllOperation = (models, definition, registry)=>{
|
|
|
1087
1121
|
options.include = mergeIncludes$1(existingIncludes, additionalIncludes);
|
|
1088
1122
|
}
|
|
1089
1123
|
}
|
|
1090
|
-
logger$
|
|
1091
|
-
|
|
1092
|
-
options
|
|
1093
|
-
}
|
|
1124
|
+
logger$9.default(`All query configured for ${model.name} with where fields: ${options.where ? Object.keys(options.where).join(', ') : 'none'}, includes: ${((_options_include = options.include) === null || _options_include === void 0 ? void 0 : _options_include.length) || 0}`);
|
|
1125
|
+
try {
|
|
1126
|
+
logger$9.trace(`[ALL] Executing ${model.name}.findAll() with options: ${JSON.stringify(options, null, 2)}`);
|
|
1127
|
+
} catch {
|
|
1128
|
+
// Fallback for cases where JSON.stringify fails on Sequelize operators
|
|
1129
|
+
logger$9.trace(`[ALL] Executing ${model.name}.findAll() with options containing non-serializable operators (${Object.keys(options.where || {}).length} where conditions)`);
|
|
1130
|
+
}
|
|
1094
1131
|
const matchingItems = await model.findAll(options);
|
|
1095
1132
|
// this.logger.default('Matching Items', { matchingItems });
|
|
1096
1133
|
// Get the current context from context manager
|
|
1097
1134
|
const context = OperationContext.contextManager.getCurrentContext();
|
|
1098
1135
|
// TODO: Move this Up!
|
|
1099
|
-
|
|
1136
|
+
const results = await Promise.all(matchingItems.map(async (row)=>{
|
|
1100
1137
|
const processedRow = await processRow(row, coordinate.kta, references, aggregations, registry, context);
|
|
1101
1138
|
return core.validateKeys(processedRow, coordinate.kta);
|
|
1102
1139
|
}));
|
|
1140
|
+
logger$9.debug(`[ALL] Returning ${results.length} ${model.name} records`);
|
|
1141
|
+
return results;
|
|
1103
1142
|
};
|
|
1104
1143
|
return all;
|
|
1105
1144
|
};
|
|
1106
1145
|
|
|
1107
|
-
const logger$
|
|
1146
|
+
const logger$8 = logger$1.default.get('sequelize', 'ops', 'create');
|
|
1147
|
+
// Helper function to translate PostgreSQL errors to meaningful messages
|
|
1148
|
+
function translateDatabaseError(error, itemData, modelName) {
|
|
1149
|
+
var _error_original, _error_original1, _error_original2;
|
|
1150
|
+
const originalMessage = error.message || '';
|
|
1151
|
+
const errorCode = (_error_original = error.original) === null || _error_original === void 0 ? void 0 : _error_original.code;
|
|
1152
|
+
const constraint = (_error_original1 = error.original) === null || _error_original1 === void 0 ? void 0 : _error_original1.constraint;
|
|
1153
|
+
const detail = (_error_original2 = error.original) === null || _error_original2 === void 0 ? void 0 : _error_original2.detail;
|
|
1154
|
+
logger$8.error('Database error during create operation', {
|
|
1155
|
+
errorCode,
|
|
1156
|
+
constraint,
|
|
1157
|
+
detail,
|
|
1158
|
+
originalMessage,
|
|
1159
|
+
modelName,
|
|
1160
|
+
itemData: JSON.stringify(itemData, null, 2)
|
|
1161
|
+
});
|
|
1162
|
+
// Handle specific PostgreSQL error codes
|
|
1163
|
+
switch(errorCode){
|
|
1164
|
+
case '23505':
|
|
1165
|
+
if (constraint) {
|
|
1166
|
+
return new Error(`Duplicate value violates unique constraint '${constraint}'. ${detail || ''}`);
|
|
1167
|
+
}
|
|
1168
|
+
return new Error(`Duplicate value detected. This record already exists. ${detail || ''}`);
|
|
1169
|
+
case '23503':
|
|
1170
|
+
if (constraint) {
|
|
1171
|
+
return new Error(`Foreign key constraint '${constraint}' violated. Referenced record does not exist. ${detail || ''}`);
|
|
1172
|
+
}
|
|
1173
|
+
return new Error(`Referenced record does not exist. Check that all related records are valid. ${detail || ''}`);
|
|
1174
|
+
case '23502':
|
|
1175
|
+
var _error_original3;
|
|
1176
|
+
const column = (_error_original3 = error.original) === null || _error_original3 === void 0 ? void 0 : _error_original3.column;
|
|
1177
|
+
if (column) {
|
|
1178
|
+
return new Error(`Required field '${column}' cannot be null`);
|
|
1179
|
+
}
|
|
1180
|
+
return new Error(`Required field is missing or null`);
|
|
1181
|
+
case '23514':
|
|
1182
|
+
if (constraint) {
|
|
1183
|
+
return new Error(`Check constraint '${constraint}' violated. ${detail || ''}`);
|
|
1184
|
+
}
|
|
1185
|
+
return new Error(`Data validation failed. Check constraint violated. ${detail || ''}`);
|
|
1186
|
+
case '22001':
|
|
1187
|
+
return new Error(`Data too long for field. Check string lengths. ${detail || ''}`);
|
|
1188
|
+
case '22003':
|
|
1189
|
+
return new Error(`Numeric value out of range. Check number values. ${detail || ''}`);
|
|
1190
|
+
case '42703':
|
|
1191
|
+
var _error_original4;
|
|
1192
|
+
const undefinedColumn = (_error_original4 = error.original) === null || _error_original4 === void 0 ? void 0 : _error_original4.column;
|
|
1193
|
+
if (undefinedColumn) {
|
|
1194
|
+
return new Error(`Column '${undefinedColumn}' does not exist in table '${modelName}'`);
|
|
1195
|
+
}
|
|
1196
|
+
return new Error(`Referenced column does not exist`);
|
|
1197
|
+
case '42P01':
|
|
1198
|
+
return new Error(`Table '${modelName}' does not exist`);
|
|
1199
|
+
default:
|
|
1200
|
+
// For unknown errors, provide the original message with context
|
|
1201
|
+
return new Error(`Database error in ${modelName}.create(): ${originalMessage}. Item data: ${JSON.stringify(itemData, null, 2)}`);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1108
1204
|
// Helper function to validate hierarchical chain exists
|
|
1109
1205
|
async function validateHierarchicalChain(models, locKey, kta) {
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1206
|
+
try {
|
|
1207
|
+
// Find the direct parent model that contains this locator
|
|
1208
|
+
const locatorIndex = kta.indexOf(locKey.kt);
|
|
1209
|
+
if (locatorIndex === -1) {
|
|
1210
|
+
throw new Error(`Locator type '${locKey.kt}' not found in kta array`);
|
|
1211
|
+
}
|
|
1212
|
+
// Get the model for this locator
|
|
1213
|
+
const locatorModel = models[locatorIndex] || models[0]; // Fallback to primary model
|
|
1214
|
+
// Build a query to validate the chain exists
|
|
1215
|
+
const chainResult = buildRelationshipChain(locatorModel, kta, locatorIndex, kta.length - 1);
|
|
1216
|
+
if (!chainResult.success) {
|
|
1217
|
+
// If we can't build a chain, just validate the record exists
|
|
1218
|
+
const record = await locatorModel.findByPk(locKey.lk);
|
|
1219
|
+
if (!record) {
|
|
1220
|
+
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist`);
|
|
1221
|
+
}
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
// Validate that the chain exists
|
|
1225
|
+
const queryOptions = {
|
|
1226
|
+
where: {
|
|
1227
|
+
id: locKey.lk
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
if (chainResult.includes && chainResult.includes.length > 0) {
|
|
1231
|
+
queryOptions.include = chainResult.includes;
|
|
1232
|
+
}
|
|
1233
|
+
const record = await locatorModel.findOne(queryOptions);
|
|
1122
1234
|
if (!record) {
|
|
1123
|
-
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist`);
|
|
1235
|
+
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist or chain is invalid`);
|
|
1124
1236
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
// Add context to validation errors
|
|
1239
|
+
if (error.original) {
|
|
1240
|
+
throw translateDatabaseError(error, {
|
|
1241
|
+
locKey,
|
|
1242
|
+
kta
|
|
1243
|
+
}, locKey.kt);
|
|
1131
1244
|
}
|
|
1132
|
-
|
|
1133
|
-
if (chainResult.includes && chainResult.includes.length > 0) {
|
|
1134
|
-
queryOptions.include = chainResult.includes;
|
|
1135
|
-
}
|
|
1136
|
-
const record = await locatorModel.findOne(queryOptions);
|
|
1137
|
-
if (!record) {
|
|
1138
|
-
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist or chain is invalid`);
|
|
1245
|
+
throw error;
|
|
1139
1246
|
}
|
|
1140
1247
|
}
|
|
1141
1248
|
const getCreateOperation = (models, definition, registry)=>{
|
|
1142
1249
|
const create = async (item, options)=>{
|
|
1143
|
-
logger$
|
|
1144
|
-
|
|
1145
|
-
options
|
|
1146
|
-
});
|
|
1250
|
+
logger$8.debug(`CREATE operation called on ${models[0].name} with ${(options === null || options === void 0 ? void 0 : options.key) ? `key: pk=${options.key.pk}, loc=[${core.isComKey(options.key) ? options.key.loc.map((l)=>`${l.kt}=${l.lk}`).join(', ') : ''}]` : (options === null || options === void 0 ? void 0 : options.locations) ? `locations: ${options.locations.map((loc)=>`${loc.kt}=${loc.lk}`).join(', ')}` : 'no constraints'}`);
|
|
1251
|
+
logger$8.default(`Create configured for ${models[0].name} with ${Object.keys(item).length} item fields`);
|
|
1147
1252
|
const { coordinate, options: { references, aggregations } } = definition;
|
|
1148
1253
|
const { kta } = coordinate;
|
|
1149
1254
|
// Get the primary model (first model in array)
|
|
@@ -1156,11 +1261,17 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1156
1261
|
// TODO: We need the opposite of processRow, something to step down from fjell to database.
|
|
1157
1262
|
itemData = extractEvents(itemData);
|
|
1158
1263
|
itemData = removeEvents(itemData);
|
|
1264
|
+
// Validate that all item attributes exist on the model
|
|
1265
|
+
const invalidAttributes = [];
|
|
1159
1266
|
for (const key of Object.keys(itemData)){
|
|
1160
1267
|
if (!modelAttributes[key]) {
|
|
1161
|
-
|
|
1268
|
+
invalidAttributes.push(key);
|
|
1162
1269
|
}
|
|
1163
1270
|
}
|
|
1271
|
+
if (invalidAttributes.length > 0) {
|
|
1272
|
+
const availableAttributes = Object.keys(modelAttributes).join(', ');
|
|
1273
|
+
throw new Error(`Invalid attributes for model '${model.name}': [${invalidAttributes.join(', ')}]. ` + `Available attributes: [${availableAttributes}]. ` + `Item data: ${JSON.stringify(itemData, null, 2)}`);
|
|
1274
|
+
}
|
|
1164
1275
|
// Handle key options
|
|
1165
1276
|
// If a key is supplied, assume its contents are to be assigned to the appropriate ids.
|
|
1166
1277
|
// For most cases this will be null as key generation is often through autoIncrement.
|
|
@@ -1181,10 +1292,12 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1181
1292
|
for (const locKey of comKey.loc){
|
|
1182
1293
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta, true);
|
|
1183
1294
|
if (!relationshipInfo.found) {
|
|
1184
|
-
const
|
|
1185
|
-
|
|
1295
|
+
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1296
|
+
const errorMessage = `Composite key locator '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships. ` + `Available associations: [${associations.join(', ')}]. ` + `KTA: [${kta.join(', ')}]. ` + `Composite key: ${JSON.stringify(comKey, null, 2)}`;
|
|
1297
|
+
logger$8.error(errorMessage, {
|
|
1186
1298
|
key: comKey,
|
|
1187
|
-
kta
|
|
1299
|
+
kta,
|
|
1300
|
+
associations
|
|
1188
1301
|
});
|
|
1189
1302
|
throw new Error(errorMessage);
|
|
1190
1303
|
}
|
|
@@ -1196,6 +1309,13 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1196
1309
|
}
|
|
1197
1310
|
// Set direct foreign keys
|
|
1198
1311
|
for (const locKey of directLocations){
|
|
1312
|
+
if (locKey.lk == null || locKey.lk === '') {
|
|
1313
|
+
logger$8.error(`Composite key location '${locKey.kt}' has undefined/null lk value`, {
|
|
1314
|
+
locKey,
|
|
1315
|
+
key: comKey
|
|
1316
|
+
});
|
|
1317
|
+
throw new Error(`Composite key location '${locKey.kt}' has undefined/null lk value`);
|
|
1318
|
+
}
|
|
1199
1319
|
const foreignKeyField = locKey.kt + 'Id';
|
|
1200
1320
|
itemData[foreignKeyField] = locKey.lk;
|
|
1201
1321
|
}
|
|
@@ -1214,10 +1334,12 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1214
1334
|
for (const locKey of options.locations){
|
|
1215
1335
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta, true);
|
|
1216
1336
|
if (!relationshipInfo.found) {
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1337
|
+
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1338
|
+
const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships. ` + `Available associations: [${associations.join(', ')}]. ` + `KTA: [${kta.join(', ')}]. ` + `Locations: ${JSON.stringify(options.locations, null, 2)}`;
|
|
1339
|
+
logger$8.error(errorMessage, {
|
|
1219
1340
|
locations: options.locations,
|
|
1220
|
-
kta
|
|
1341
|
+
kta,
|
|
1342
|
+
associations
|
|
1221
1343
|
});
|
|
1222
1344
|
throw new Error(errorMessage);
|
|
1223
1345
|
}
|
|
@@ -1229,6 +1351,13 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1229
1351
|
}
|
|
1230
1352
|
// Set direct foreign keys
|
|
1231
1353
|
for (const locKey of directLocations){
|
|
1354
|
+
if (locKey.lk == null || locKey.lk === '') {
|
|
1355
|
+
logger$8.error(`Location option '${locKey.kt}' has undefined/null lk value`, {
|
|
1356
|
+
locKey,
|
|
1357
|
+
locations: options.locations
|
|
1358
|
+
});
|
|
1359
|
+
throw new Error(`Location option '${locKey.kt}' has undefined/null lk value`);
|
|
1360
|
+
}
|
|
1232
1361
|
const foreignKeyField = locKey.kt + 'Id';
|
|
1233
1362
|
itemData[foreignKeyField] = locKey.lk;
|
|
1234
1363
|
}
|
|
@@ -1238,50 +1367,58 @@ const getCreateOperation = (models, definition, registry)=>{
|
|
|
1238
1367
|
}
|
|
1239
1368
|
}
|
|
1240
1369
|
// Create the record
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1370
|
+
try {
|
|
1371
|
+
logger$8.trace(`[CREATE] Executing ${model.name}.create() with data: ${stringifyJSON(itemData)}`);
|
|
1372
|
+
const createdRecord = await model.create(itemData);
|
|
1373
|
+
// Add key and events
|
|
1374
|
+
const processedRecord = await processRow(createdRecord, kta, references, aggregations, registry);
|
|
1375
|
+
const result = core.validateKeys(processedRecord, kta);
|
|
1376
|
+
logger$8.debug(`[CREATE] Created ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${createdRecord.id}`}`);
|
|
1377
|
+
return result;
|
|
1378
|
+
} catch (error) {
|
|
1379
|
+
throw translateDatabaseError(error, itemData, model.name);
|
|
1380
|
+
}
|
|
1245
1381
|
};
|
|
1246
1382
|
return create;
|
|
1247
1383
|
};
|
|
1248
1384
|
|
|
1249
|
-
const logger$
|
|
1385
|
+
const logger$7 = logger$1.default.get('sequelize', 'ops', 'find');
|
|
1250
1386
|
const getFindOperation = (models, definition, registry)=>{
|
|
1251
1387
|
const { options: { finders, references, aggregations } } = definition;
|
|
1252
1388
|
const find = async (finder, finderParams, locations)=>{
|
|
1253
|
-
logger$
|
|
1254
|
-
|
|
1255
|
-
finderParams,
|
|
1256
|
-
locations
|
|
1257
|
-
});
|
|
1389
|
+
logger$7.debug(`FIND operation called on ${models[0].name} with finder '${finder}' and ${(locations === null || locations === void 0 ? void 0 : locations.length) || 0} location filters: ${(locations === null || locations === void 0 ? void 0 : locations.map((loc)=>`${loc.kt}=${loc.lk}`).join(', ')) || 'none'}`);
|
|
1390
|
+
logger$7.default(`Find configured for ${models[0].name} using finder '${finder}' with ${Object.keys(finderParams).length} params`);
|
|
1258
1391
|
// Note that we execute the createFinders function here because we want to make sure we're always getting the
|
|
1259
1392
|
// most up to date methods.
|
|
1260
1393
|
if (finders && finders[finder]) {
|
|
1261
1394
|
const finderMethod = finders[finder];
|
|
1262
1395
|
if (finderMethod) {
|
|
1396
|
+
logger$7.trace(`[FIND] Executing finder '${finder}' on ${models[0].name} with params: ${stringifyJSON(finderParams)}, locations: ${stringifyJSON(locations)}`);
|
|
1263
1397
|
const results = await finderMethod(finderParams, locations);
|
|
1264
1398
|
if (results && results.length > 0) {
|
|
1265
|
-
|
|
1399
|
+
const processedResults = await Promise.all(results.map(async (row)=>{
|
|
1266
1400
|
const processedRow = await processRow(row, definition.coordinate.kta, references, aggregations, registry);
|
|
1267
1401
|
return core.validateKeys(processedRow, definition.coordinate.kta);
|
|
1268
1402
|
}));
|
|
1403
|
+
logger$7.debug(`[FIND] Found ${processedResults.length} ${models[0].name} records using finder '${finder}'`);
|
|
1404
|
+
return processedResults;
|
|
1269
1405
|
} else {
|
|
1406
|
+
logger$7.debug(`[FIND] Found 0 ${models[0].name} records using finder '${finder}'`);
|
|
1270
1407
|
return [];
|
|
1271
1408
|
}
|
|
1272
1409
|
} else {
|
|
1273
|
-
logger$
|
|
1410
|
+
logger$7.error(`Finder %s not found`, finder);
|
|
1274
1411
|
throw new Error(`Finder ${finder} not found`);
|
|
1275
1412
|
}
|
|
1276
1413
|
} else {
|
|
1277
|
-
logger$
|
|
1414
|
+
logger$7.error(`No finders have been defined for this lib`);
|
|
1278
1415
|
throw new Error(`No finders found`);
|
|
1279
1416
|
}
|
|
1280
1417
|
};
|
|
1281
1418
|
return find;
|
|
1282
1419
|
};
|
|
1283
1420
|
|
|
1284
|
-
const logger$
|
|
1421
|
+
const logger$6 = logger$1.default.get('sequelize', 'ops', 'get');
|
|
1285
1422
|
// Helper function to process composite key and build query options
|
|
1286
1423
|
const processCompositeKey$1 = (comKey, model, kta)=>{
|
|
1287
1424
|
const where = {
|
|
@@ -1292,7 +1429,7 @@ const processCompositeKey$1 = (comKey, model, kta)=>{
|
|
|
1292
1429
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locator.kt, kta);
|
|
1293
1430
|
if (!relationshipInfo.found) {
|
|
1294
1431
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1295
|
-
logger$
|
|
1432
|
+
logger$6.error(errorMessage, {
|
|
1296
1433
|
key: comKey,
|
|
1297
1434
|
kta
|
|
1298
1435
|
});
|
|
@@ -1322,27 +1459,28 @@ const getGetOperation = (models, definition, registry)=>{
|
|
|
1322
1459
|
const { coordinate, options: { references, aggregations } } = definition;
|
|
1323
1460
|
const { kta } = coordinate;
|
|
1324
1461
|
const get = async (key)=>{
|
|
1325
|
-
logger$4.default('Get', {
|
|
1326
|
-
key
|
|
1327
|
-
});
|
|
1328
1462
|
if (!core.isValidItemKey(key)) {
|
|
1329
|
-
logger$
|
|
1463
|
+
logger$6.error('Key for Get is not a valid ItemKey: %j', key);
|
|
1330
1464
|
throw new Error('Key for Get is not a valid ItemKey');
|
|
1331
1465
|
}
|
|
1466
|
+
logger$6.debug(`GET operation called on ${models[0].name} with ${core.isPriKey(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l)=>`${l.kt}=${l.lk}`).join(', ')}]`}`);
|
|
1467
|
+
logger$6.default(`Get configured for ${models[0].name} with ${core.isPriKey(key) ? 'primary' : 'composite'} key`);
|
|
1332
1468
|
const itemKey = key;
|
|
1333
1469
|
// @ts-ignore
|
|
1334
1470
|
const model = models[0];
|
|
1335
1471
|
let item;
|
|
1336
1472
|
if (core.isPriKey(itemKey)) {
|
|
1337
1473
|
// This is the easy case because we can just find the item by its primary key
|
|
1474
|
+
logger$6.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${itemKey.pk}`);
|
|
1338
1475
|
item = await model.findByPk(itemKey.pk);
|
|
1339
1476
|
} else if (core.isComKey(itemKey)) {
|
|
1340
1477
|
// This is a composite key, so we need to build a where clause based on the composite key's locators
|
|
1341
1478
|
const comKey = itemKey;
|
|
1342
1479
|
const queryOptions = processCompositeKey$1(comKey, model, kta);
|
|
1343
|
-
logger$
|
|
1480
|
+
logger$6.default('Composite key query', {
|
|
1344
1481
|
queryOptions
|
|
1345
1482
|
});
|
|
1483
|
+
logger$6.trace(`[GET] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
1346
1484
|
item = await model.findOne(queryOptions);
|
|
1347
1485
|
}
|
|
1348
1486
|
if (!item) {
|
|
@@ -1350,30 +1488,33 @@ const getGetOperation = (models, definition, registry)=>{
|
|
|
1350
1488
|
} else {
|
|
1351
1489
|
// Get the current context from context manager
|
|
1352
1490
|
const context = OperationContext.contextManager.getCurrentContext();
|
|
1353
|
-
|
|
1491
|
+
const result = core.validateKeys(await processRow(item, kta, references, aggregations, registry, context), kta);
|
|
1492
|
+
logger$6.debug(`[GET] Retrieved ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${item.id}`}`);
|
|
1493
|
+
return result;
|
|
1354
1494
|
}
|
|
1355
1495
|
};
|
|
1356
1496
|
return get;
|
|
1357
1497
|
};
|
|
1358
1498
|
|
|
1359
|
-
const logger$
|
|
1499
|
+
const logger$5 = logger$1.default.get('sequelize', 'ops', 'one');
|
|
1360
1500
|
const getOneOperation = (models, definition, registry)=>{
|
|
1361
1501
|
const one = async (itemQuery, locations = [])=>{
|
|
1362
|
-
logger$
|
|
1363
|
-
|
|
1364
|
-
locations
|
|
1365
|
-
});
|
|
1502
|
+
logger$5.debug(`ONE operation called on ${models[0].name} with ${locations.length} location filters: ${locations.map((loc)=>`${loc.kt}=${loc.lk}`).join(', ') || 'none'}`);
|
|
1503
|
+
logger$5.default(`One configured for ${models[0].name} delegating to all operation`);
|
|
1366
1504
|
const items = await all.getAllOperation(models, definition, registry)(itemQuery, locations);
|
|
1367
1505
|
if (items.length > 0) {
|
|
1368
|
-
|
|
1506
|
+
const result = items[0];
|
|
1507
|
+
logger$5.debug(`[ONE] Found ${models[0].name} record with key: ${result.key ? JSON.stringify(result.key) : 'unknown'}`);
|
|
1508
|
+
return result;
|
|
1369
1509
|
} else {
|
|
1510
|
+
logger$5.debug(`[ONE] No ${models[0].name} record found`);
|
|
1370
1511
|
return null;
|
|
1371
1512
|
}
|
|
1372
1513
|
};
|
|
1373
1514
|
return one;
|
|
1374
1515
|
};
|
|
1375
1516
|
|
|
1376
|
-
const logger$
|
|
1517
|
+
const logger$4 = logger$1.default.get('sequelize', 'ops', 'remove');
|
|
1377
1518
|
// Helper function to process composite key and build query options
|
|
1378
1519
|
const processCompositeKey = (comKey, model, kta)=>{
|
|
1379
1520
|
const where = {
|
|
@@ -1384,7 +1525,7 @@ const processCompositeKey = (comKey, model, kta)=>{
|
|
|
1384
1525
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locator.kt, kta);
|
|
1385
1526
|
if (!relationshipInfo.found) {
|
|
1386
1527
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1387
|
-
logger$
|
|
1528
|
+
logger$4.error(errorMessage, {
|
|
1388
1529
|
key: comKey,
|
|
1389
1530
|
kta
|
|
1390
1531
|
});
|
|
@@ -1415,27 +1556,26 @@ registry)=>{
|
|
|
1415
1556
|
const { coordinate, options } = definition;
|
|
1416
1557
|
const { kta } = coordinate;
|
|
1417
1558
|
const remove = async (key)=>{
|
|
1418
|
-
logger$2.default('Remove', {
|
|
1419
|
-
key
|
|
1420
|
-
});
|
|
1421
1559
|
if (!core.isValidItemKey(key)) {
|
|
1422
|
-
logger$
|
|
1560
|
+
logger$4.error('Key for Remove is not a valid ItemKey: %j', key);
|
|
1423
1561
|
throw new Error('Key for Remove is not a valid ItemKey');
|
|
1424
1562
|
}
|
|
1563
|
+
logger$4.debug(`REMOVE operation called on ${models[0].name} with ${core.isPriKey(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l)=>`${l.kt}=${l.lk}`).join(', ')}]`}`);
|
|
1564
|
+
logger$4.default(`Remove configured for ${models[0].name} with ${core.isPriKey(key) ? 'primary' : 'composite'} key`);
|
|
1425
1565
|
// @ts-ignore
|
|
1426
1566
|
const model = models[0];
|
|
1427
1567
|
let item;
|
|
1428
1568
|
let returnItem;
|
|
1429
|
-
logger$
|
|
1569
|
+
logger$4.debug('remove: %s', core.abbrevIK(key));
|
|
1430
1570
|
if (core.isPriKey(key)) {
|
|
1571
|
+
logger$4.debug(`[REMOVE] Executing ${model.name}.findByPk() with pk: ${key.pk}`);
|
|
1431
1572
|
item = await model.findByPk(key.pk);
|
|
1432
1573
|
} else if (core.isComKey(key)) {
|
|
1433
1574
|
// This is a composite key, so we need to build a where clause based on the composite key's locators
|
|
1434
1575
|
const comKey = key;
|
|
1435
1576
|
const queryOptions = processCompositeKey(comKey, model, kta);
|
|
1436
|
-
logger$
|
|
1437
|
-
|
|
1438
|
-
});
|
|
1577
|
+
logger$4.default(`Remove composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(', ') : 'none'}`);
|
|
1578
|
+
logger$4.debug(`[REMOVE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
1439
1579
|
item = await model.findOne(queryOptions);
|
|
1440
1580
|
}
|
|
1441
1581
|
if (!item) {
|
|
@@ -1451,6 +1591,7 @@ registry)=>{
|
|
|
1451
1591
|
item.deletedAt = new Date();
|
|
1452
1592
|
}
|
|
1453
1593
|
// Save the object
|
|
1594
|
+
logger$4.debug(`[REMOVE] Executing ${model.name}.save() for soft delete`);
|
|
1454
1595
|
await (item === null || item === void 0 ? void 0 : item.save());
|
|
1455
1596
|
returnItem = item === null || item === void 0 ? void 0 : item.get({
|
|
1456
1597
|
plain: true
|
|
@@ -1458,6 +1599,7 @@ registry)=>{
|
|
|
1458
1599
|
returnItem = addKey(item, returnItem, kta);
|
|
1459
1600
|
returnItem = populateEvents(returnItem);
|
|
1460
1601
|
} else if (options.deleteOnRemove) {
|
|
1602
|
+
logger$4.debug(`[REMOVE] Executing ${model.name}.destroy() for hard delete`);
|
|
1461
1603
|
await (item === null || item === void 0 ? void 0 : item.destroy());
|
|
1462
1604
|
returnItem = item === null || item === void 0 ? void 0 : item.get({
|
|
1463
1605
|
plain: true
|
|
@@ -1467,12 +1609,13 @@ registry)=>{
|
|
|
1467
1609
|
} else {
|
|
1468
1610
|
throw new Error('No deletedAt or isDeleted attribute found in model, and deleteOnRemove is not set');
|
|
1469
1611
|
}
|
|
1612
|
+
logger$4.debug(`[REMOVE] Removed ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${item.id}`}`);
|
|
1470
1613
|
return returnItem;
|
|
1471
1614
|
};
|
|
1472
1615
|
return remove;
|
|
1473
1616
|
};
|
|
1474
1617
|
|
|
1475
|
-
const logger$
|
|
1618
|
+
const logger$3 = logger$1.default.get('sequelize', 'ops', 'update');
|
|
1476
1619
|
// Helper function to merge includes avoiding duplicates
|
|
1477
1620
|
const mergeIncludes = (existingIncludes, newIncludes)=>{
|
|
1478
1621
|
const mergedIncludes = [
|
|
@@ -1496,9 +1639,10 @@ const mergeIncludes = (existingIncludes, newIncludes)=>{
|
|
|
1496
1639
|
const getUpdateOperation = (models, definition, registry)=>{
|
|
1497
1640
|
const { options: { references, aggregations } } = definition;
|
|
1498
1641
|
const update = async (key, item)=>{
|
|
1642
|
+
logger$3.debug(`UPDATE operation called on ${models[0].name} with ${core.isPriKey(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l)=>`${l.kt}=${l.lk}`).join(', ')}]`}`);
|
|
1499
1643
|
const { coordinate } = definition;
|
|
1500
1644
|
const { kta } = coordinate;
|
|
1501
|
-
logger$
|
|
1645
|
+
logger$3.debug('update: %s, %j', core.abbrevIK(key), item);
|
|
1502
1646
|
// Find the object we're updating
|
|
1503
1647
|
// @ts-ignore
|
|
1504
1648
|
const model = models[0];
|
|
@@ -1506,6 +1650,7 @@ const getUpdateOperation = (models, definition, registry)=>{
|
|
|
1506
1650
|
if (core.isPriKey(key)) {
|
|
1507
1651
|
// Find the model by using the PK
|
|
1508
1652
|
const priKey = key;
|
|
1653
|
+
logger$3.trace(`[UPDATE] Executing ${model.name}.findByPk() with pk: ${priKey.pk}`);
|
|
1509
1654
|
response = await model.findByPk(priKey.pk);
|
|
1510
1655
|
} else if (core.isComKey(key)) {
|
|
1511
1656
|
const comKey = key;
|
|
@@ -1519,7 +1664,7 @@ const getUpdateOperation = (models, definition, registry)=>{
|
|
|
1519
1664
|
const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locator.kt, kta, true);
|
|
1520
1665
|
if (!relationshipInfo.found) {
|
|
1521
1666
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1522
|
-
logger$
|
|
1667
|
+
logger$3.error(errorMessage, {
|
|
1523
1668
|
key: comKey,
|
|
1524
1669
|
kta
|
|
1525
1670
|
});
|
|
@@ -1547,9 +1692,8 @@ const getUpdateOperation = (models, definition, registry)=>{
|
|
|
1547
1692
|
if (additionalIncludes.length > 0) {
|
|
1548
1693
|
queryOptions.include = mergeIncludes([], additionalIncludes);
|
|
1549
1694
|
}
|
|
1550
|
-
logger$
|
|
1551
|
-
|
|
1552
|
-
});
|
|
1695
|
+
logger$3.default(`Update composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(', ') : 'none'}`);
|
|
1696
|
+
logger$3.trace(`[UPDATE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
1553
1697
|
response = await model.findOne(queryOptions);
|
|
1554
1698
|
}
|
|
1555
1699
|
if (response) {
|
|
@@ -1558,13 +1702,15 @@ const getUpdateOperation = (models, definition, registry)=>{
|
|
|
1558
1702
|
// TODO: We need the opposite of processRow, something to step down from fjell to database.
|
|
1559
1703
|
updateProps = extractEvents(updateProps);
|
|
1560
1704
|
updateProps = removeEvents(updateProps);
|
|
1561
|
-
logger$
|
|
1562
|
-
logger$
|
|
1705
|
+
logger$3.default(`Update found ${model.name} record to modify`);
|
|
1706
|
+
logger$3.default(`Update properties configured: ${Object.keys(updateProps).join(', ')}`);
|
|
1563
1707
|
// Update the object
|
|
1708
|
+
logger$3.trace(`[UPDATE] Executing ${model.name}.update() with properties: ${stringifyJSON(updateProps)}`);
|
|
1564
1709
|
response = await response.update(updateProps);
|
|
1565
1710
|
// Populate the key and events
|
|
1566
1711
|
const processedItem = await processRow(response, kta, references, aggregations, registry);
|
|
1567
1712
|
const returnItem = core.validateKeys(processedItem, kta);
|
|
1713
|
+
logger$3.debug(`[UPDATE] Updated ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${response.id}`}`);
|
|
1568
1714
|
return returnItem;
|
|
1569
1715
|
} else {
|
|
1570
1716
|
throw new Library.NotFoundError('update', coordinate, key);
|
|
@@ -1573,8 +1719,13 @@ const getUpdateOperation = (models, definition, registry)=>{
|
|
|
1573
1719
|
return update;
|
|
1574
1720
|
};
|
|
1575
1721
|
|
|
1576
|
-
const createOperations = (models,
|
|
1722
|
+
const createOperations = (models, coordinate, registry, options)=>{
|
|
1577
1723
|
const operations = {};
|
|
1724
|
+
// Create a definition-like object for backward compatibility with existing operation functions
|
|
1725
|
+
const definition = {
|
|
1726
|
+
coordinate,
|
|
1727
|
+
options
|
|
1728
|
+
};
|
|
1578
1729
|
operations.all = all.getAllOperation(models, definition, registry);
|
|
1579
1730
|
operations.one = getOneOperation(models, definition, registry);
|
|
1580
1731
|
operations.create = getCreateOperation(models, definition, registry);
|
|
@@ -1588,25 +1739,62 @@ const createOperations = (models, definition, registry)=>{
|
|
|
1588
1739
|
return operations;
|
|
1589
1740
|
};
|
|
1590
1741
|
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1742
|
+
const logger$2 = logger$1.default.get("Instance");
|
|
1743
|
+
/**
|
|
1744
|
+
* Creates a new Sequelize instance that extends the fjell-lib instance
|
|
1745
|
+
* with Sequelize-specific functionality
|
|
1746
|
+
*/ const createInstance$2 = (registry, coordinate, models, options)=>{
|
|
1747
|
+
logger$2.debug("createInstance", {
|
|
1748
|
+
coordinate,
|
|
1597
1749
|
models,
|
|
1598
|
-
registry
|
|
1750
|
+
registry,
|
|
1751
|
+
options
|
|
1752
|
+
});
|
|
1753
|
+
// Create Sequelize-specific operations
|
|
1754
|
+
const operations = createOperations(models, coordinate, registry, options);
|
|
1755
|
+
// Create the base fjell-lib instance
|
|
1756
|
+
const libInstance = Library__namespace.createInstance(registry, coordinate, operations, options);
|
|
1757
|
+
return {
|
|
1758
|
+
...libInstance,
|
|
1759
|
+
models
|
|
1599
1760
|
};
|
|
1600
|
-
}
|
|
1761
|
+
};
|
|
1762
|
+
/**
|
|
1763
|
+
* Type guard to check if an object is a Sequelize Instance
|
|
1764
|
+
*/ const isInstance = (instance)=>{
|
|
1765
|
+
return instance != null && instance.coordinate != null && instance.operations != null && instance.options != null && instance.registry != null && instance.models != null && Array.isArray(instance.models);
|
|
1766
|
+
};
|
|
1767
|
+
|
|
1768
|
+
const logger$1 = logger$1.default.get("InstanceFactory");
|
|
1769
|
+
/**
|
|
1770
|
+
* Factory function for creating Sequelize instances
|
|
1771
|
+
* This extends the fjell-lib pattern by adding Sequelize-specific models
|
|
1772
|
+
*/ const createInstanceFactory = (models, options)=>{
|
|
1773
|
+
return (coordinate, context)=>{
|
|
1774
|
+
logger$1.debug("Creating Sequelize instance", {
|
|
1775
|
+
coordinate,
|
|
1776
|
+
registry: context.registry,
|
|
1777
|
+
models: models.map((m)=>m.name),
|
|
1778
|
+
options
|
|
1779
|
+
});
|
|
1780
|
+
return createInstance$2(context.registry, coordinate, models, options);
|
|
1781
|
+
};
|
|
1782
|
+
};
|
|
1601
1783
|
|
|
1602
1784
|
function createInstance$1(keyTypes, models, libOptions = {}, scopes = [], registry) {
|
|
1603
|
-
|
|
1604
|
-
const
|
|
1785
|
+
// Create coordinate and options separately following new pattern
|
|
1786
|
+
const coordinate = createCoordinate(keyTypes, scopes);
|
|
1787
|
+
const options = createOptions(libOptions);
|
|
1788
|
+
// Create operations with the new signature
|
|
1789
|
+
const operations = createOperations(models, coordinate, registry, options);
|
|
1790
|
+
// Wrap operations for contained pattern
|
|
1791
|
+
const wrappedOperations = Library.Contained.wrapOperations(operations, options, coordinate, registry);
|
|
1605
1792
|
return {
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1793
|
+
coordinate,
|
|
1794
|
+
registry,
|
|
1795
|
+
operations: wrappedOperations,
|
|
1796
|
+
options,
|
|
1797
|
+
models
|
|
1610
1798
|
};
|
|
1611
1799
|
}
|
|
1612
1800
|
|
|
@@ -1623,15 +1811,21 @@ function createInstance(keyType, models, libOptions = {}, scopes = [], registry)
|
|
|
1623
1811
|
libOptions,
|
|
1624
1812
|
scopes
|
|
1625
1813
|
});
|
|
1626
|
-
|
|
1814
|
+
// Create coordinate and options separately following new pattern
|
|
1815
|
+
const coordinate = createCoordinate([
|
|
1627
1816
|
keyType
|
|
1628
|
-
], scopes
|
|
1629
|
-
const
|
|
1817
|
+
], scopes);
|
|
1818
|
+
const options = createOptions(libOptions);
|
|
1819
|
+
// Create operations with the new signature
|
|
1820
|
+
const operations = createOperations(models, coordinate, registry, options);
|
|
1821
|
+
// Wrap operations for primary pattern
|
|
1822
|
+
const wrappedOperations = Library.Primary.wrapOperations(operations, options, coordinate, registry);
|
|
1630
1823
|
return {
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1824
|
+
coordinate,
|
|
1825
|
+
registry,
|
|
1826
|
+
operations: wrappedOperations,
|
|
1827
|
+
options,
|
|
1828
|
+
models
|
|
1635
1829
|
};
|
|
1636
1830
|
}
|
|
1637
1831
|
|
|
@@ -1646,6 +1840,8 @@ exports.SCOPE_SEQUELIZE = SCOPE_SEQUELIZE;
|
|
|
1646
1840
|
exports.createCoordinate = createCoordinate;
|
|
1647
1841
|
exports.createDefinition = createDefinition;
|
|
1648
1842
|
exports.createInstance = createInstance$2;
|
|
1843
|
+
exports.createInstanceFactory = createInstanceFactory;
|
|
1649
1844
|
exports.createOperations = createOperations;
|
|
1650
1845
|
exports.createOptions = createOptions;
|
|
1846
|
+
exports.isInstance = isInstance;
|
|
1651
1847
|
//# sourceMappingURL=index.cjs.map
|