@fjell/lib-sequelize 4.4.0 → 4.4.2

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.
Files changed (109) hide show
  1. package/dist/cjs/AggregationBuilder.cjs +31 -0
  2. package/dist/cjs/Coordinate.cjs +37 -0
  3. package/dist/cjs/Definition.cjs +46 -0
  4. package/dist/cjs/EventCoordinator.cjs +54 -0
  5. package/dist/cjs/Instance.cjs +40 -0
  6. package/dist/cjs/KeyMaster.cjs +129 -0
  7. package/dist/cjs/Operations.cjs +29 -0
  8. package/dist/cjs/Options.cjs +39 -0
  9. package/dist/cjs/QueryBuilder.cjs +290 -0
  10. package/dist/cjs/ReferenceBuilder.cjs +34 -0
  11. package/dist/cjs/RowProcessor.cjs +41 -0
  12. package/dist/cjs/contained/Instance.cjs +21 -0
  13. package/dist/cjs/contained/index.cjs +10 -0
  14. package/dist/cjs/index.cjs +23 -0
  15. package/dist/cjs/logger.cjs +10 -0
  16. package/dist/cjs/ops/all.cjs +62 -0
  17. package/dist/cjs/ops/create.cjs +154 -0
  18. package/dist/cjs/ops/find.cjs +45 -0
  19. package/dist/cjs/ops/get.cjs +85 -0
  20. package/dist/cjs/ops/one.cjs +26 -0
  21. package/dist/cjs/ops/remove.cjs +111 -0
  22. package/dist/cjs/ops/update.cjs +61 -0
  23. package/dist/cjs/primary/Instance.cjs +31 -0
  24. package/dist/cjs/primary/index.cjs +10 -0
  25. package/dist/cjs/util/general.cjs +52 -0
  26. package/dist/cjs/util/relationshipUtils.cjs +117 -0
  27. package/dist/es/AggregationBuilder.js +27 -0
  28. package/dist/es/EventCoordinator.js +48 -0
  29. package/dist/{Instance.js → es/Instance.js} +6 -5
  30. package/dist/es/KeyMaster.js +124 -0
  31. package/dist/{Operations.js → es/Operations.js} +8 -8
  32. package/dist/{Options.js → es/Options.js} +8 -11
  33. package/dist/{QueryBuilder.js → es/QueryBuilder.js} +123 -21
  34. package/dist/es/ReferenceBuilder.js +30 -0
  35. package/dist/es/RowProcessor.js +37 -0
  36. package/dist/{contained → es/contained}/Instance.js +6 -5
  37. package/dist/{index.js → es/index.js} +1 -1
  38. package/dist/{ops → es/ops}/all.js +7 -4
  39. package/dist/es/ops/create.js +150 -0
  40. package/dist/{ops → es/ops}/find.js +16 -6
  41. package/dist/es/ops/get.js +81 -0
  42. package/dist/{ops → es/ops}/one.js +2 -2
  43. package/dist/{ops → es/ops}/remove.js +51 -11
  44. package/dist/{ops → es/ops}/update.js +15 -15
  45. package/dist/{primary → es/primary}/Instance.js +6 -5
  46. package/dist/es/util/general.js +47 -0
  47. package/dist/es/util/relationshipUtils.js +112 -0
  48. package/dist/index.cjs +1279 -0
  49. package/dist/index.cjs.map +1 -0
  50. package/dist/types/AggregationBuilder.d.ts +4 -0
  51. package/dist/{Definition.d.ts → types/Definition.d.ts} +1 -1
  52. package/dist/{EventCoordinator.d.ts → types/EventCoordinator.d.ts} +1 -0
  53. package/dist/{Instance.d.ts → types/Instance.d.ts} +1 -1
  54. package/dist/types/KeyMaster.d.ts +4 -0
  55. package/dist/{Operations.d.ts → types/Operations.d.ts} +2 -2
  56. package/dist/{Options.d.ts → types/Options.d.ts} +14 -3
  57. package/dist/{QueryBuilder.d.ts → types/QueryBuilder.d.ts} +1 -0
  58. package/dist/types/ReferenceBuilder.d.ts +3 -0
  59. package/dist/{RowProcessor.d.ts → types/RowProcessor.d.ts} +3 -1
  60. package/dist/{contained → types/contained}/Instance.d.ts +2 -1
  61. package/dist/{ops → types/ops}/all.d.ts +2 -1
  62. package/dist/{ops → types/ops}/create.d.ts +3 -2
  63. package/dist/{ops → types/ops}/find.d.ts +2 -1
  64. package/dist/{ops → types/ops}/get.d.ts +2 -1
  65. package/dist/{ops → types/ops}/one.d.ts +2 -1
  66. package/dist/{ops → types/ops}/remove.d.ts +2 -1
  67. package/dist/{ops → types/ops}/update.d.ts +2 -1
  68. package/dist/{primary → types/primary}/Instance.d.ts +2 -1
  69. package/dist/types/util/general.d.ts +4 -0
  70. package/dist/types/util/relationshipUtils.d.ts +21 -0
  71. package/package.json +37 -32
  72. package/dist/EventCoordinator.js +0 -30
  73. package/dist/KeyMaster.d.ts +0 -4
  74. package/dist/KeyMaster.js +0 -84
  75. package/dist/RowProcessor.js +0 -18
  76. package/dist/ops/create.js +0 -18
  77. package/dist/ops/get.js +0 -45
  78. package/src/Coordinate.ts +0 -16
  79. package/src/Definition.ts +0 -49
  80. package/src/EventCoordinator.ts +0 -103
  81. package/src/Instance.ts +0 -44
  82. package/src/KeyMaster.ts +0 -90
  83. package/src/Operations.ts +0 -42
  84. package/src/Options.ts +0 -41
  85. package/src/QueryBuilder.ts +0 -208
  86. package/src/RowProcessor.ts +0 -23
  87. package/src/contained/Instance.ts +0 -44
  88. package/src/contained/index.ts +0 -1
  89. package/src/index.ts +0 -7
  90. package/src/logger.ts +0 -5
  91. package/src/ops/all.ts +0 -76
  92. package/src/ops/create.ts +0 -40
  93. package/src/ops/find.ts +0 -49
  94. package/src/ops/get.ts +0 -67
  95. package/src/ops/one.ts +0 -37
  96. package/src/ops/remove.ts +0 -81
  97. package/src/ops/update.ts +0 -78
  98. package/src/primary/Instance.ts +0 -40
  99. package/src/primary/index.ts +0 -1
  100. /package/dist/{Coordinate.js → es/Coordinate.js} +0 -0
  101. /package/dist/{Definition.js → es/Definition.js} +0 -0
  102. /package/dist/{contained → es/contained}/index.js +0 -0
  103. /package/dist/{logger.js → es/logger.js} +0 -0
  104. /package/dist/{primary → es/primary}/index.js +0 -0
  105. /package/dist/{Coordinate.d.ts → types/Coordinate.d.ts} +0 -0
  106. /package/dist/{contained → types/contained}/index.d.ts +0 -0
  107. /package/dist/{index.d.ts → types/index.d.ts} +0 -0
  108. /package/dist/{logger.d.ts → types/logger.d.ts} +0 -0
  109. /package/dist/{primary → types/primary}/index.d.ts +0 -0
@@ -0,0 +1,290 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const core = require('@fjell/core');
6
+ const sequelize = require('sequelize');
7
+ const logger$1 = require('./logger.cjs');
8
+
9
+ const logger = logger$1.default.get('sequelize', 'QueryBuilder');
10
+ const addDeleteQuery = (options, model)=>{
11
+ logger.default('Adding Delete Query', {
12
+ options
13
+ });
14
+ if (model.getAttributes().deletedAt) {
15
+ options.where['deletedAt'] = {
16
+ [sequelize.Op.eq]: null
17
+ };
18
+ } else if (model.getAttributes().isDeleted) {
19
+ options.where['isDeleted'] = {
20
+ [sequelize.Op.eq]: false
21
+ };
22
+ }
23
+ return options;
24
+ };
25
+ const addEventQueries = (options, events, model)=>{
26
+ logger.default('Adding Event Queries', {
27
+ options,
28
+ events
29
+ });
30
+ Object.keys(events).forEach((key)=>{
31
+ if (!model.getAttributes()[`${key}At`]) {
32
+ throw new Error(`Event ${key} is not supported on this model, column ${key}At not found`);
33
+ }
34
+ let whereClauses = {};
35
+ const event = events[key];
36
+ if (event.start) {
37
+ whereClauses = {
38
+ ...whereClauses,
39
+ [sequelize.Op.gte]: new Date(event.start)
40
+ };
41
+ }
42
+ if (event.end) {
43
+ whereClauses = {
44
+ ...whereClauses,
45
+ [sequelize.Op.lt]: new Date(event.end)
46
+ };
47
+ }
48
+ if (event.by) {
49
+ if (!model.getAttributes()[`${key}By`]) {
50
+ throw new Error(`Event ${key} is not supported on this model, column ${key}By not found`);
51
+ }
52
+ whereClauses = {
53
+ ...whereClauses,
54
+ [sequelize.Op.eq]: event.by
55
+ };
56
+ }
57
+ options.where[`${key}At`] = whereClauses;
58
+ });
59
+ return options;
60
+ };
61
+ // Add the references to the query
62
+ const addReferenceQueries = (options, references, model)=>{
63
+ logger.default('Adding Reference Queries', {
64
+ options,
65
+ references
66
+ });
67
+ Object.keys(references).forEach((key)=>{
68
+ logger.default('Adding Reference Query', {
69
+ key,
70
+ references
71
+ });
72
+ if (!model.getAttributes()[`${key}Id`]) {
73
+ throw new Error(`Reference ${key} is not supported on this model, column ${key}Id not found`);
74
+ }
75
+ if (core.isPriKey(references[key])) {
76
+ const priKey = references[key];
77
+ options.where[`${key}Id`] = {
78
+ [sequelize.Op.eq]: priKey.pk
79
+ };
80
+ } else if (core.isComKey(references[key])) {
81
+ throw new Error('ComKeys are not supported in Sequelize');
82
+ }
83
+ });
84
+ return options;
85
+ };
86
+ const addCompoundCondition = (options, compoundCondition, model)=>{
87
+ // Ensure options.where exists
88
+ options.where = options.where || {};
89
+ let compoundOp;
90
+ const compoundType = compoundCondition.compoundType;
91
+ if (compoundType === "AND") {
92
+ compoundOp = sequelize.Op.and;
93
+ } else {
94
+ compoundOp = sequelize.Op.or;
95
+ }
96
+ let conditions = {};
97
+ compoundCondition.conditions.forEach((condition)=>{
98
+ if (core.isCondition(condition)) {
99
+ conditions = addCondition(conditions, condition, model);
100
+ } else {
101
+ throw new Error('Nest Compound conditions not supported');
102
+ }
103
+ });
104
+ // Merge with existing where conditions instead of replacing
105
+ if (Object.keys(options.where).length > 0) {
106
+ // If there are existing conditions, wrap everything in an AND
107
+ options.where = {
108
+ [sequelize.Op.and]: [
109
+ options.where,
110
+ {
111
+ [compoundOp]: conditions
112
+ }
113
+ ]
114
+ };
115
+ } else {
116
+ // If no existing conditions, just set the compound condition
117
+ options.where[compoundOp] = conditions;
118
+ }
119
+ return options;
120
+ };
121
+ const getSequelizeOperator = (operator)=>{
122
+ if (operator === '==') {
123
+ return sequelize.Op.eq;
124
+ } else if (operator === '<') {
125
+ return sequelize.Op.lt;
126
+ } else if (operator === '>') {
127
+ return sequelize.Op.gt;
128
+ } else if (operator === '<=') {
129
+ return sequelize.Op.lte;
130
+ } else if (operator === '>=') {
131
+ return sequelize.Op.gte;
132
+ } else if (operator === 'in') {
133
+ return sequelize.Op.in;
134
+ } else {
135
+ throw new Error(`Operator ${operator} not supported`);
136
+ }
137
+ };
138
+ const addAssociationCondition = (conditions, condition, model)=>{
139
+ const [associationName, attributeName] = condition.column.split('.', 2);
140
+ // Check if the association exists on the model
141
+ if (!model.associations || !model.associations[associationName]) {
142
+ throw new Error(`Association ${associationName} not found on model ${model.name}`);
143
+ }
144
+ const association = model.associations[associationName];
145
+ const associatedModel = association.target;
146
+ // Check if the attribute exists on the associated model
147
+ if (!associatedModel.getAttributes()[attributeName]) {
148
+ throw new Error(`Attribute ${attributeName} not found on associated model ${associatedModel.name} for association ${associationName}`);
149
+ }
150
+ // Use Sequelize's $association.attribute$ syntax for querying associated models
151
+ const sequelizeAssociationColumn = `$${associationName}.${attributeName}$`;
152
+ const conditionOp = getSequelizeOperator(condition.operator);
153
+ conditions[sequelizeAssociationColumn] = {
154
+ [conditionOp]: condition.value
155
+ };
156
+ return conditions;
157
+ };
158
+ const addAttributeCondition = (conditions, condition, model)=>{
159
+ const conditionColumn = condition.column;
160
+ if (!model.getAttributes()[conditionColumn]) {
161
+ throw new Error(`Condition column ${conditionColumn} not found on model ${model.name}`);
162
+ }
163
+ const conditionOp = getSequelizeOperator(condition.operator);
164
+ conditions[conditionColumn] = {
165
+ [conditionOp]: condition.value
166
+ };
167
+ return conditions;
168
+ };
169
+ const addCondition = (conditions, condition, model)=>{
170
+ const conditionColumn = condition.column;
171
+ // Check if this is an association query (contains a dot)
172
+ if (conditionColumn.includes('.')) {
173
+ return addAssociationCondition(conditions, condition, model);
174
+ }
175
+ // Handle regular column queries
176
+ return addAttributeCondition(conditions, condition, model);
177
+ };
178
+ const collectAssociationsFromConditions = (conditions)=>{
179
+ const associations = new Set();
180
+ const processObject = (obj)=>{
181
+ if (typeof obj === 'object' && obj !== null) {
182
+ // Check string keys
183
+ Object.keys(obj).forEach((key)=>{
184
+ // Check if this is an association reference ($association.attribute$)
185
+ if (typeof key === 'string' && key.startsWith('$') && key.endsWith('$') && key.includes('.')) {
186
+ const associationName = key.substring(1, key.indexOf('.'));
187
+ associations.add(associationName);
188
+ }
189
+ // Recursively process nested objects
190
+ if (typeof obj[key] === 'object') {
191
+ processObject(obj[key]);
192
+ }
193
+ });
194
+ // Also check Symbol keys (for compound conditions like Op.and, Op.or)
195
+ Object.getOwnPropertySymbols(obj).forEach((symbol)=>{
196
+ if (typeof obj[symbol] === 'object') {
197
+ processObject(obj[symbol]);
198
+ }
199
+ });
200
+ }
201
+ // Handle arrays (for compound conditions that might be arrays)
202
+ if (Array.isArray(obj)) {
203
+ obj.forEach((item)=>{
204
+ if (typeof item === 'object') {
205
+ processObject(item);
206
+ }
207
+ });
208
+ }
209
+ };
210
+ processObject(conditions);
211
+ return associations;
212
+ };
213
+ const addAssociationIncludes = (options, model)=>{
214
+ // Collect all association names used in conditions
215
+ const referencedAssociations = collectAssociationsFromConditions(options.where);
216
+ if (referencedAssociations.size > 0) {
217
+ options.include = options.include || [];
218
+ // Add each referenced association to the include array
219
+ referencedAssociations.forEach((associationName)=>{
220
+ // Check if this association is already included
221
+ const alreadyIncluded = options.include.some((inc)=>typeof inc === 'string' && inc === associationName || typeof inc === 'object' && inc.association === associationName);
222
+ if (!alreadyIncluded && model.associations && model.associations[associationName]) {
223
+ options.include.push({
224
+ model: model.associations[associationName].target,
225
+ as: associationName,
226
+ required: false // Use LEFT JOIN so records without associations are still returned
227
+ });
228
+ }
229
+ });
230
+ }
231
+ return options;
232
+ };
233
+ const buildQuery = (itemQuery, model)=>{
234
+ logger.default('build', {
235
+ itemQuery
236
+ });
237
+ let options = {
238
+ where: {}
239
+ };
240
+ if (itemQuery.compoundCondition) {
241
+ logger.default('Adding Conditions', {
242
+ compoundCondition: itemQuery.compoundCondition
243
+ });
244
+ options = addCompoundCondition(options, itemQuery.compoundCondition, model);
245
+ }
246
+ // If the model has a deletedAt column, we need to add a delete query
247
+ if (model.getAttributes().deletedAt || model.getAttributes().isDeleted) {
248
+ options = addDeleteQuery(options, model);
249
+ }
250
+ if (itemQuery.refs) {
251
+ options = addReferenceQueries(options, itemQuery.refs, model);
252
+ }
253
+ if (itemQuery.events) {
254
+ options = addEventQueries(options, itemQuery.events, model);
255
+ }
256
+ // TODO: Once we start to support Aggs on the server-side, we'll need to parse agg queries
257
+ // Apply a limit to the result set
258
+ if (itemQuery.limit) {
259
+ logger.default('Limiting to', {
260
+ limit: itemQuery.limit
261
+ });
262
+ options.limit = itemQuery.limit;
263
+ }
264
+ // Apply an offset to the result set
265
+ if (itemQuery.offset) {
266
+ options.offset = itemQuery.offset;
267
+ }
268
+ // Add orderBy to the query
269
+ if (itemQuery.orderBy) {
270
+ itemQuery.orderBy.forEach((orderBy)=>{
271
+ if (!model.getAttributes()[orderBy.field]) {
272
+ throw new Error(`Order by field ${orderBy.field} not found on model ${model.name}`);
273
+ }
274
+ options.order = [
275
+ [
276
+ orderBy.field,
277
+ orderBy.direction
278
+ ]
279
+ ];
280
+ });
281
+ }
282
+ // Add includes for any associations referenced in conditions
283
+ options = addAssociationIncludes(options, model);
284
+ return options;
285
+ };
286
+
287
+ exports.addCompoundCondition = addCompoundCondition;
288
+ exports.addCondition = addCondition;
289
+ exports.buildQuery = buildQuery;
290
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlCdWlsZGVyLmNqcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const buildReference = async (item, referenceDefinition, registry)=>{
6
+ // Check if there is more than one key type
7
+ if (referenceDefinition.kta.length > 1) {
8
+ throw new Error("The ReferenceBuilder doesn't work with more than one key type yet");
9
+ }
10
+ // Check if dependencies exist
11
+ if (!registry) {
12
+ throw new Error("This model definition has a reference definition, but the registry is not present");
13
+ }
14
+ // Find the Library.Instance for the key type
15
+ const library = registry.get(referenceDefinition.kta);
16
+ if (!library) {
17
+ throw new Error("This model definition has a reference definition, but the dependency is not present");
18
+ }
19
+ // Create a PriKey using the column value from item
20
+ const priKey = {
21
+ kt: referenceDefinition.kta[0],
22
+ pk: item[referenceDefinition.column]
23
+ };
24
+ // Get the referenced item using the Library.Operations get method
25
+ const referencedItem = await library.operations.get(priKey);
26
+ // TODO: In a Fjell-compliant implementation, this value should be stored in the ref property
27
+ // For now, we'll just populate the property directly
28
+ // Store the result in the property on item
29
+ item[referenceDefinition.property] = referencedItem;
30
+ return item;
31
+ };
32
+
33
+ exports.buildReference = buildReference;
34
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVmZXJlbmNlQnVpbGRlci5janMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const logger$1 = require('./logger.cjs');
6
+ const KeyMaster = require('./KeyMaster.cjs');
7
+ const ReferenceBuilder = require('./ReferenceBuilder.cjs');
8
+ const AggregationBuilder = require('./AggregationBuilder.cjs');
9
+ const general = require('./util/general.cjs');
10
+ const EventCoordinator = require('./EventCoordinator.cjs');
11
+
12
+ const logger = logger$1.default.get('sequelize', 'RowProcessor');
13
+ const processRow = async (row, keyTypes, referenceDefinitions, aggregationDefinitions, registry)=>{
14
+ logger.default('Processing Row', {
15
+ row
16
+ });
17
+ let item = row.get({
18
+ plain: true
19
+ });
20
+ logger.default('Adding Key to Item with Key Types: %s', general.stringifyJSON(keyTypes));
21
+ item = KeyMaster.addKey(row, item, keyTypes);
22
+ item = EventCoordinator.populateEvents(item);
23
+ logger.default('Key Added to Item: %s', general.stringifyJSON(item.key));
24
+ if (referenceDefinitions && referenceDefinitions.length > 0) {
25
+ for (const referenceDefinition of referenceDefinitions){
26
+ logger.default('Processing Reference for %s to %s', item.key.kt, general.stringifyJSON(referenceDefinition.kta));
27
+ item = await ReferenceBuilder.buildReference(item, referenceDefinition, registry);
28
+ }
29
+ }
30
+ if (aggregationDefinitions && aggregationDefinitions.length > 0) {
31
+ for (const aggregationDefinition of aggregationDefinitions){
32
+ logger.default('Processing Aggregation for %s from %s', item.key.kt, general.stringifyJSON(aggregationDefinition.kta));
33
+ item = await AggregationBuilder.buildAggregation(item, aggregationDefinition, registry);
34
+ }
35
+ }
36
+ logger.default('Processed Row: %j', general.stringifyJSON(item));
37
+ return item;
38
+ };
39
+
40
+ exports.processRow = processRow;
41
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUm93UHJvY2Vzc29yLmNqcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const Library = require('@fjell/lib');
6
+ const Definition = require('../Definition.cjs');
7
+ const Operations = require('../Operations.cjs');
8
+
9
+ function createInstance(keyTypes, models, libOptions = {}, scopes = [], registry) {
10
+ const definition = Definition.createDefinition(keyTypes, scopes, libOptions);
11
+ const operations = Operations.createOperations(models, definition, registry);
12
+ return {
13
+ definition,
14
+ operations: Library.Contained.wrapOperations(operations, definition, registry),
15
+ models,
16
+ registry
17
+ };
18
+ }
19
+
20
+ exports.createInstance = createInstance;
21
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdGFuY2UuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const Instance = require('./Instance.cjs');
6
+
7
+
8
+
9
+ exports.createInstance = Instance.createInstance;
10
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7In0=
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const Coordinate = require('./Coordinate.cjs');
6
+ const Definition = require('./Definition.cjs');
7
+ const Instance = require('./Instance.cjs');
8
+ const Options = require('./Options.cjs');
9
+ const Operations = require('./Operations.cjs');
10
+ const index = require('./contained/index.cjs');
11
+ const index$1 = require('./primary/index.cjs');
12
+
13
+
14
+
15
+ exports.SCOPE_SEQUELIZE = Coordinate.SCOPE_SEQUELIZE;
16
+ exports.createCoordinate = Coordinate.createCoordinate;
17
+ exports.createDefinition = Definition.createDefinition;
18
+ exports.createInstance = Instance.createInstance;
19
+ exports.createOptions = Options.createOptions;
20
+ exports.createOperations = Operations.createOperations;
21
+ exports.Contained = index;
22
+ exports.Primary = index$1;
23
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4
+
5
+ const Logging = require('@fjell/logging');
6
+
7
+ const LibLogger = Logging.getLogger('@fjell/lib-sequelize');
8
+
9
+ exports.default = LibLogger;
10
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmNqcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7In0=
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const core = require('@fjell/core');
6
+ const QueryBuilder = require('../QueryBuilder.cjs');
7
+ const logger$1 = require('../logger.cjs');
8
+ const RowProcessor = require('../RowProcessor.cjs');
9
+ const sequelize = require('sequelize');
10
+
11
+ const logger = logger$1.default.get('sequelize', 'ops', 'all');
12
+ const getAllOperation = (models, definition, registry)=>{
13
+ const { coordinate, options: { references, aggregations } } = definition;
14
+ //#region Query
15
+ const all = async (itemQuery, locations)=>{
16
+ logger.default('All', {
17
+ itemQuery,
18
+ locations
19
+ });
20
+ const loc = locations || [];
21
+ // SQ Libs don't support locations
22
+ if (loc.length > 1) {
23
+ throw new Error('Not implemented for more than one location key');
24
+ }
25
+ // We have the model here?
26
+ // @ts-ignore
27
+ const model = models[0];
28
+ // We have the model here?
29
+ const options = QueryBuilder.buildQuery(itemQuery, model);
30
+ // If this has a location array, we need to add a where clause
31
+ if (loc.length === 1) {
32
+ const locKeyType = loc[0].kt;
33
+ if (model.associations[locKeyType]) {
34
+ const association = model.associations[locKeyType];
35
+ options.where = {
36
+ ...options.where,
37
+ [association.foreignKey]: {
38
+ [sequelize.Op.eq]: loc[0].lk
39
+ }
40
+ };
41
+ } else {
42
+ logger.error('Location key type not found in sequelize model association for: %s', locKeyType);
43
+ throw new Error('Location key type not found in model');
44
+ }
45
+ }
46
+ logger.default('Configured this Item Query', {
47
+ itemQuery,
48
+ options
49
+ });
50
+ const matchingItems = await model.findAll(options);
51
+ // this.logger.default('Matching Items', { matchingItems });
52
+ // TODO: Move this Up!
53
+ return await Promise.all(matchingItems.map(async (row)=>{
54
+ const processedRow = await RowProcessor.processRow(row, coordinate.kta, references, aggregations, registry);
55
+ return core.validateKeys(processedRow, coordinate.kta);
56
+ }));
57
+ };
58
+ return all;
59
+ };
60
+
61
+ exports.getAllOperation = getAllOperation;
62
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLmNqcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,154 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const core = require('@fjell/core');
6
+ const logger$1 = require('../logger.cjs');
7
+ const RowProcessor = require('../RowProcessor.cjs');
8
+ const EventCoordinator = require('../EventCoordinator.cjs');
9
+ const relationshipUtils = require('../util/relationshipUtils.cjs');
10
+
11
+ const logger = logger$1.default.get('sequelize', 'ops', 'create');
12
+ // Helper function to validate hierarchical chain exists
13
+ async function validateHierarchicalChain(models, locKey, kta) {
14
+ // Find the direct parent model that contains this locator
15
+ const locatorIndex = kta.indexOf(locKey.kt);
16
+ if (locatorIndex === -1) {
17
+ throw new Error(`Locator type '${locKey.kt}' not found in kta array`);
18
+ }
19
+ // Get the model for this locator
20
+ const locatorModel = models[locatorIndex] || models[0]; // Fallback to primary model
21
+ // Build a query to validate the chain exists
22
+ const chainResult = relationshipUtils.buildRelationshipChain(locatorModel, kta, locatorIndex, kta.length - 1);
23
+ if (!chainResult.success) {
24
+ // If we can't build a chain, just validate the record exists
25
+ const record = await locatorModel.findByPk(locKey.lk);
26
+ if (!record) {
27
+ throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist`);
28
+ }
29
+ return;
30
+ }
31
+ // Validate that the chain exists
32
+ const queryOptions = {
33
+ where: {
34
+ id: locKey.lk
35
+ }
36
+ };
37
+ if (chainResult.includes && chainResult.includes.length > 0) {
38
+ queryOptions.include = chainResult.includes;
39
+ }
40
+ const record = await locatorModel.findOne(queryOptions);
41
+ if (!record) {
42
+ throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist or chain is invalid`);
43
+ }
44
+ }
45
+ const getCreateOperation = (models, definition, registry)=>{
46
+ const create = async (item, options)=>{
47
+ logger.default('Create', {
48
+ item,
49
+ options
50
+ });
51
+ const { coordinate, options: { references, aggregations } } = definition;
52
+ const { kta } = coordinate;
53
+ // Get the primary model (first model in array)
54
+ const model = models[0];
55
+ const modelAttributes = model.getAttributes();
56
+ // Validate that all item attributes exist on the model
57
+ let itemData = {
58
+ ...item
59
+ };
60
+ // TODO: We need the opposite of processRow, something to step down from fjell to database.
61
+ itemData = EventCoordinator.extractEvents(itemData);
62
+ itemData = EventCoordinator.removeEvents(itemData);
63
+ for (const key of Object.keys(itemData)){
64
+ if (!modelAttributes[key]) {
65
+ throw new Error(`Attribute '${key}' does not exist on model ${model.name}`);
66
+ }
67
+ }
68
+ // Handle key options
69
+ // If a key is supplied, assume its contents are to be assigned to the appropriate ids.
70
+ // For most cases this will be null as key generation is often through autoIncrement.
71
+ // If this is a CItem then the locations will be present.
72
+ if (options === null || options === void 0 ? void 0 : options.key) {
73
+ const key = options.key;
74
+ if (core.isPriKey(key)) {
75
+ // Set the primary key
76
+ itemData.id = key.pk;
77
+ } else if (core.isComKey(key)) {
78
+ // Set primary key
79
+ itemData.id = key.pk;
80
+ // Process location keys - only set direct foreign keys, validate hierarchical chains
81
+ const comKey = key;
82
+ const directLocations = [];
83
+ const hierarchicalLocations = [];
84
+ // Categorize location keys as direct or hierarchical
85
+ for (const locKey of comKey.loc){
86
+ const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta, true);
87
+ if (!relationshipInfo.found) {
88
+ const errorMessage = `Composite key locator '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
89
+ logger.error(errorMessage, {
90
+ key: comKey,
91
+ kta
92
+ });
93
+ throw new Error(errorMessage);
94
+ }
95
+ if (relationshipInfo.isDirect) {
96
+ directLocations.push(locKey);
97
+ } else {
98
+ hierarchicalLocations.push(locKey);
99
+ }
100
+ }
101
+ // Set direct foreign keys
102
+ for (const locKey of directLocations){
103
+ const foreignKeyField = locKey.kt + 'Id';
104
+ itemData[foreignKeyField] = locKey.lk;
105
+ }
106
+ // Validate hierarchical chains exist
107
+ for (const locKey of hierarchicalLocations){
108
+ await validateHierarchicalChain(models, locKey, kta);
109
+ }
110
+ }
111
+ }
112
+ // Handle locations options
113
+ // This is the most frequent way relationship ids will be set
114
+ if (options === null || options === void 0 ? void 0 : options.locations) {
115
+ const directLocations = [];
116
+ const hierarchicalLocations = [];
117
+ // Categorize location keys as direct or hierarchical
118
+ for (const locKey of options.locations){
119
+ const relationshipInfo = relationshipUtils.buildRelationshipPath(model, locKey.kt, kta, true);
120
+ if (!relationshipInfo.found) {
121
+ const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
122
+ logger.error(errorMessage, {
123
+ locations: options.locations,
124
+ kta
125
+ });
126
+ throw new Error(errorMessage);
127
+ }
128
+ if (relationshipInfo.isDirect) {
129
+ directLocations.push(locKey);
130
+ } else {
131
+ hierarchicalLocations.push(locKey);
132
+ }
133
+ }
134
+ // Set direct foreign keys
135
+ for (const locKey of directLocations){
136
+ const foreignKeyField = locKey.kt + 'Id';
137
+ itemData[foreignKeyField] = locKey.lk;
138
+ }
139
+ // Validate hierarchical chains exist
140
+ for (const locKey of hierarchicalLocations){
141
+ await validateHierarchicalChain(models, locKey, kta);
142
+ }
143
+ }
144
+ // Create the record
145
+ const createdRecord = await model.create(itemData);
146
+ // Add key and events
147
+ const processedRecord = await RowProcessor.processRow(createdRecord, kta, references, aggregations, registry);
148
+ return core.validateKeys(processedRecord, kta);
149
+ };
150
+ return create;
151
+ };
152
+
153
+ exports.getCreateOperation = getCreateOperation;
154
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLmNqcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=