@fjell/lib-sequelize 4.4.75 → 4.4.76
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/QueryBuilder.d.ts +18 -3
- package/dist/QueryBuilder.d.ts.map +1 -1
- package/dist/RowProcessor.d.ts +1 -1
- package/dist/RowProcessor.d.ts.map +1 -1
- package/dist/index.js +508 -108
- package/dist/index.js.map +4 -4
- package/dist/metrics/QueryMetrics.d.ts +31 -0
- package/dist/metrics/QueryMetrics.d.ts.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/ops/all.d.ts.map +1 -1
- package/dist/ops/create.d.ts.map +1 -1
- package/dist/ops/get.d.ts.map +1 -1
- package/dist/ops/remove.d.ts.map +1 -1
- package/dist/ops/update.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -173,7 +173,7 @@ var addReferenceQueries = (options, references, model) => {
|
|
|
173
173
|
});
|
|
174
174
|
return options;
|
|
175
175
|
};
|
|
176
|
-
var addCompoundCondition = (options, compoundCondition, model) => {
|
|
176
|
+
var addCompoundCondition = (options, compoundCondition, model, references, allReferences, registry) => {
|
|
177
177
|
options.where = options.where || {};
|
|
178
178
|
let compoundOp;
|
|
179
179
|
const compoundType = compoundCondition.compoundType;
|
|
@@ -186,7 +186,7 @@ var addCompoundCondition = (options, compoundCondition, model) => {
|
|
|
186
186
|
let conditions = {};
|
|
187
187
|
compoundCondition.conditions.forEach((condition) => {
|
|
188
188
|
if (isCondition(condition)) {
|
|
189
|
-
conditions = addCondition(conditions, condition, model);
|
|
189
|
+
conditions = addCondition(conditions, condition, model, options, references, allReferences, registry);
|
|
190
190
|
} else {
|
|
191
191
|
throw new Error(`Nested Compound conditions not supported. Model: '${model.name}', Compound condition: ${stringifyJSON(compoundCondition)}, Nested condition: ${stringifyJSON(condition)}`);
|
|
192
192
|
}
|
|
@@ -216,12 +216,267 @@ var getSequelizeOperator = (operator) => {
|
|
|
216
216
|
return Op.gte;
|
|
217
217
|
} else if (operator === "in") {
|
|
218
218
|
return Op.in;
|
|
219
|
+
} else if (operator === "!=") {
|
|
220
|
+
return Op.ne;
|
|
219
221
|
} else {
|
|
220
222
|
throw new Error(`Operator ${operator} not supported`);
|
|
221
223
|
}
|
|
222
224
|
};
|
|
223
|
-
var
|
|
224
|
-
|
|
225
|
+
var findReferenceByProperty = (propertyName, references) => {
|
|
226
|
+
if (!references || references.length === 0) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
return references.find((ref) => ref.property === propertyName) || null;
|
|
230
|
+
};
|
|
231
|
+
var getReferencesFromRegistry = (model, registry) => {
|
|
232
|
+
if (!registry) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const modelName = model.name.toLowerCase();
|
|
236
|
+
try {
|
|
237
|
+
const library = registry.get([modelName]);
|
|
238
|
+
if (library && library.options && library.options.references) {
|
|
239
|
+
return library.options.references;
|
|
240
|
+
}
|
|
241
|
+
} catch {
|
|
242
|
+
}
|
|
243
|
+
return;
|
|
244
|
+
};
|
|
245
|
+
var buildNestedInclude = (pathSegments, currentModel, references, allReferences, registry, isFirstSegment = true) => {
|
|
246
|
+
if (pathSegments.length === 0) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
const [firstSegment, ...remainingSegments] = pathSegments;
|
|
250
|
+
if (isFirstSegment) {
|
|
251
|
+
const refDef = findReferenceByProperty(firstSegment, references);
|
|
252
|
+
if (!refDef) {
|
|
253
|
+
logger3.debug(`[buildNestedInclude] No reference definition found for property '${firstSegment}'`, {
|
|
254
|
+
model: currentModel.name,
|
|
255
|
+
property: firstSegment,
|
|
256
|
+
availableReferences: references?.map((r) => r.property) || [],
|
|
257
|
+
referencesCount: references?.length || 0
|
|
258
|
+
});
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
logger3.debug(`[buildNestedInclude] Found reference definition for property '${firstSegment}'`, {
|
|
262
|
+
model: currentModel.name,
|
|
263
|
+
property: firstSegment,
|
|
264
|
+
refDef: { property: refDef.property, column: refDef.column, kta: refDef.kta }
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const association = currentModel.associations?.[firstSegment];
|
|
268
|
+
if (!association) {
|
|
269
|
+
if (isFirstSegment) {
|
|
270
|
+
logger3.debug(`[buildNestedInclude] Reference property '${firstSegment}' found but no Sequelize association exists`, {
|
|
271
|
+
model: currentModel.name,
|
|
272
|
+
property: firstSegment,
|
|
273
|
+
availableAssociations: Object.keys(currentModel.associations || {}),
|
|
274
|
+
associationsObject: currentModel.associations ? Object.keys(currentModel.associations) : "undefined"
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
logger3.debug(`[buildNestedInclude] Found Sequelize association for '${firstSegment}'`, {
|
|
280
|
+
model: currentModel.name,
|
|
281
|
+
property: firstSegment,
|
|
282
|
+
associationType: association.associationType,
|
|
283
|
+
targetModel: association.target?.name
|
|
284
|
+
});
|
|
285
|
+
const targetModel = association.target;
|
|
286
|
+
const includeConfig = {
|
|
287
|
+
model: targetModel,
|
|
288
|
+
as: firstSegment,
|
|
289
|
+
required: true
|
|
290
|
+
// Use INNER JOIN for filtering conditions
|
|
291
|
+
};
|
|
292
|
+
if (remainingSegments.length === 0) {
|
|
293
|
+
return { include: includeConfig, associationName: firstSegment };
|
|
294
|
+
}
|
|
295
|
+
let nestedReferences = getReferencesFromRegistry(targetModel, registry);
|
|
296
|
+
if (!nestedReferences) {
|
|
297
|
+
nestedReferences = allReferences?.get(targetModel.name);
|
|
298
|
+
}
|
|
299
|
+
const nestedInclude = buildNestedInclude(
|
|
300
|
+
remainingSegments,
|
|
301
|
+
targetModel,
|
|
302
|
+
nestedReferences,
|
|
303
|
+
allReferences,
|
|
304
|
+
registry,
|
|
305
|
+
false
|
|
306
|
+
// Subsequent segments don't require reference definition match
|
|
307
|
+
);
|
|
308
|
+
if (nestedInclude) {
|
|
309
|
+
includeConfig.include = [nestedInclude.include];
|
|
310
|
+
return { include: includeConfig, associationName: firstSegment };
|
|
311
|
+
}
|
|
312
|
+
const [nextSegment, ...restSegments] = remainingSegments;
|
|
313
|
+
const nextAssociation = targetModel.associations?.[nextSegment];
|
|
314
|
+
if (!nextAssociation) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
if (restSegments.length === 0) {
|
|
318
|
+
includeConfig.include = [{
|
|
319
|
+
model: nextAssociation.target,
|
|
320
|
+
as: nextSegment,
|
|
321
|
+
required: true
|
|
322
|
+
}];
|
|
323
|
+
return { include: includeConfig, associationName: firstSegment };
|
|
324
|
+
}
|
|
325
|
+
const deeperInclude = buildNestedInclude(
|
|
326
|
+
remainingSegments,
|
|
327
|
+
targetModel,
|
|
328
|
+
nestedReferences,
|
|
329
|
+
allReferences,
|
|
330
|
+
registry,
|
|
331
|
+
false
|
|
332
|
+
);
|
|
333
|
+
if (!deeperInclude) {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
includeConfig.include = [deeperInclude.include];
|
|
337
|
+
return { include: includeConfig, associationName: firstSegment };
|
|
338
|
+
};
|
|
339
|
+
var detectReferenceJoin = (fieldPath, model, references, allReferences, registry) => {
|
|
340
|
+
const pathSegments = fieldPath.split(".");
|
|
341
|
+
if (pathSegments.length < 2) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
for (let i = pathSegments.length - 1; i >= 1; i--) {
|
|
345
|
+
const referencePath = pathSegments.slice(0, i);
|
|
346
|
+
const attributePath = pathSegments.slice(i).join(".");
|
|
347
|
+
const includeResult = buildNestedInclude(referencePath, model, references, allReferences, registry);
|
|
348
|
+
if (!includeResult) {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
let finalModel = model;
|
|
352
|
+
for (const segment of referencePath) {
|
|
353
|
+
const assoc = finalModel.associations?.[segment];
|
|
354
|
+
if (!assoc) {
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
finalModel = assoc.target;
|
|
358
|
+
}
|
|
359
|
+
const attributeSegments = attributePath.split(".");
|
|
360
|
+
if (attributeSegments.length !== 1 || !finalModel.getAttributes()[attributePath]) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
logger3.debug(`Auto-detected reference join for condition '${fieldPath}'`, {
|
|
364
|
+
model: model.name,
|
|
365
|
+
referencePath: referencePath.join("."),
|
|
366
|
+
attributePath,
|
|
367
|
+
associationName: includeResult.associationName
|
|
368
|
+
});
|
|
369
|
+
return {
|
|
370
|
+
include: includeResult.include,
|
|
371
|
+
attributePath,
|
|
372
|
+
associationName: includeResult.associationName
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
};
|
|
377
|
+
var addIncludeIfNotExists = (options, newInclude) => {
|
|
378
|
+
options.include = options.include || [];
|
|
379
|
+
const exists = options.include.some((inc) => {
|
|
380
|
+
if (typeof inc === "string") {
|
|
381
|
+
return inc === newInclude.as;
|
|
382
|
+
}
|
|
383
|
+
if (inc.model === newInclude.model && inc.as === newInclude.as) {
|
|
384
|
+
if (newInclude.include && inc.include) {
|
|
385
|
+
newInclude.include.forEach((nested) => {
|
|
386
|
+
const nestedExists = inc.include.some(
|
|
387
|
+
(existingNested) => existingNested.model === nested.model && existingNested.as === nested.as
|
|
388
|
+
);
|
|
389
|
+
if (!nestedExists) {
|
|
390
|
+
inc.include.push(nested);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
} else if (newInclude.include) {
|
|
394
|
+
inc.include = newInclude.include;
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
return false;
|
|
399
|
+
});
|
|
400
|
+
if (!exists) {
|
|
401
|
+
options.include.push(newInclude);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
var addAssociationCondition = (conditions, condition, model, options, references, allReferences, registry) => {
|
|
405
|
+
const fieldPath = condition.column;
|
|
406
|
+
const pathSegments = fieldPath.split(".");
|
|
407
|
+
logger3.debug(`[addAssociationCondition] Processing condition '${fieldPath}'`, {
|
|
408
|
+
model: model.name,
|
|
409
|
+
hasReferences: !!references,
|
|
410
|
+
referencesCount: references?.length || 0,
|
|
411
|
+
pathSegmentsLength: pathSegments.length,
|
|
412
|
+
pathSegments,
|
|
413
|
+
willAttemptDetection: !!(references && pathSegments.length >= 2)
|
|
414
|
+
});
|
|
415
|
+
if (references && pathSegments.length >= 2) {
|
|
416
|
+
logger3.debug(`[addAssociationCondition] Attempting reference join detection for '${fieldPath}'`, {
|
|
417
|
+
model: model.name,
|
|
418
|
+
referencesCount: references.length,
|
|
419
|
+
references: references.map((r) => ({ property: r.property, column: r.column })),
|
|
420
|
+
pathSegments,
|
|
421
|
+
hasOptions: !!options
|
|
422
|
+
});
|
|
423
|
+
const referenceJoin = detectReferenceJoin(fieldPath, model, references, allReferences, registry);
|
|
424
|
+
if (!referenceJoin) {
|
|
425
|
+
logger3.debug(`[addAssociationCondition] Reference join detection returned null for '${fieldPath}'`, {
|
|
426
|
+
model: model.name,
|
|
427
|
+
fieldPath
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
if (referenceJoin && options) {
|
|
431
|
+
logger3.debug(`[addAssociationCondition] Reference join detected successfully for '${fieldPath}'`, {
|
|
432
|
+
model: model.name,
|
|
433
|
+
associationName: referenceJoin.associationName,
|
|
434
|
+
attributePath: referenceJoin.attributePath
|
|
435
|
+
});
|
|
436
|
+
addIncludeIfNotExists(options, referenceJoin.include);
|
|
437
|
+
const attributeName2 = referenceJoin.attributePath;
|
|
438
|
+
const associationPath = fieldPath.substring(0, fieldPath.length - attributeName2.length - 1);
|
|
439
|
+
const sequelizeAssociationColumn2 = `$${associationPath}.${attributeName2}$`;
|
|
440
|
+
const finalPathSegments = associationPath.split(".");
|
|
441
|
+
let currentModel = model;
|
|
442
|
+
let targetModel = model;
|
|
443
|
+
for (const segment of finalPathSegments) {
|
|
444
|
+
const assoc = currentModel.associations?.[segment];
|
|
445
|
+
if (!assoc) {
|
|
446
|
+
throw new Error(`Association ${segment} not found on model ${currentModel.name}`);
|
|
447
|
+
}
|
|
448
|
+
targetModel = assoc.target;
|
|
449
|
+
currentModel = targetModel;
|
|
450
|
+
}
|
|
451
|
+
if (!targetModel.getAttributes()[attributeName2]) {
|
|
452
|
+
throw new Error(`Attribute ${attributeName2} not found on associated model ${targetModel.name} for path ${associationPath}`);
|
|
453
|
+
}
|
|
454
|
+
if (condition.value === null) {
|
|
455
|
+
if (condition.operator === "==" || !condition.operator) {
|
|
456
|
+
logger3.trace(`[QueryBuilder] Setting reference condition: ${sequelizeAssociationColumn2} IS NULL`);
|
|
457
|
+
conditions[sequelizeAssociationColumn2] = {
|
|
458
|
+
[Op.is]: null
|
|
459
|
+
};
|
|
460
|
+
} else if (condition.operator === "!=") {
|
|
461
|
+
logger3.trace(`[QueryBuilder] Setting reference condition: ${sequelizeAssociationColumn2} IS NOT NULL`);
|
|
462
|
+
conditions[sequelizeAssociationColumn2] = {
|
|
463
|
+
[Op.not]: null
|
|
464
|
+
};
|
|
465
|
+
} else {
|
|
466
|
+
logger3.error(`Operator ${condition.operator} cannot be used with null value on reference`, { condition });
|
|
467
|
+
throw new Error(`Operator ${condition.operator} cannot be used with null value. Use '==' for IS NULL or '!=' for IS NOT NULL.`);
|
|
468
|
+
}
|
|
469
|
+
return conditions;
|
|
470
|
+
}
|
|
471
|
+
const conditionOp2 = getSequelizeOperator(condition.operator);
|
|
472
|
+
logger3.trace(`[QueryBuilder] Setting reference condition: ${sequelizeAssociationColumn2} = ${stringifyJSON(condition.value)} (type: ${typeof condition.value})`);
|
|
473
|
+
conditions[sequelizeAssociationColumn2] = {
|
|
474
|
+
[conditionOp2]: condition.value
|
|
475
|
+
};
|
|
476
|
+
return conditions;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const [associationName, attributeName] = fieldPath.split(".", 2);
|
|
225
480
|
if (!model.associations || !model.associations[associationName]) {
|
|
226
481
|
throw new Error(`Association ${associationName} not found on model ${model.name}`);
|
|
227
482
|
}
|
|
@@ -284,10 +539,10 @@ var addAttributeCondition = (conditions, condition, model) => {
|
|
|
284
539
|
};
|
|
285
540
|
return conditions;
|
|
286
541
|
};
|
|
287
|
-
var addCondition = (conditions, condition, model) => {
|
|
542
|
+
var addCondition = (conditions, condition, model, options, references, allReferences, registry) => {
|
|
288
543
|
const conditionColumn = condition.column;
|
|
289
544
|
if (conditionColumn.includes(".")) {
|
|
290
|
-
return addAssociationCondition(conditions, condition, model);
|
|
545
|
+
return addAssociationCondition(conditions, condition, model, options, references, allReferences, registry);
|
|
291
546
|
}
|
|
292
547
|
return addAttributeCondition(conditions, condition, model);
|
|
293
548
|
};
|
|
@@ -341,6 +596,46 @@ var addAssociationIncludes = (options, model) => {
|
|
|
341
596
|
}
|
|
342
597
|
return options;
|
|
343
598
|
};
|
|
599
|
+
var addReferenceIncludes = (options, model, referenceDefinitions) => {
|
|
600
|
+
if (!referenceDefinitions || referenceDefinitions.length === 0) {
|
|
601
|
+
return { options, includedReferences: [] };
|
|
602
|
+
}
|
|
603
|
+
const includedReferences = [];
|
|
604
|
+
options.include = options.include || [];
|
|
605
|
+
for (const refDef of referenceDefinitions) {
|
|
606
|
+
const association = model.associations && model.associations[refDef.property];
|
|
607
|
+
if (association) {
|
|
608
|
+
const alreadyIncluded = options.include.some(
|
|
609
|
+
(inc) => typeof inc === "string" && inc === refDef.property || typeof inc === "object" && inc.as === refDef.property
|
|
610
|
+
);
|
|
611
|
+
if (!alreadyIncluded) {
|
|
612
|
+
logger3.default(`Auto-detected association for reference '${refDef.property}' - using INCLUDE to prevent N+1`, {
|
|
613
|
+
property: refDef.property,
|
|
614
|
+
associationType: association.associationType,
|
|
615
|
+
targetModel: association.target.name
|
|
616
|
+
});
|
|
617
|
+
options.include.push({
|
|
618
|
+
model: association.target,
|
|
619
|
+
as: refDef.property,
|
|
620
|
+
required: false
|
|
621
|
+
// Use LEFT JOIN to preserve items without references
|
|
622
|
+
});
|
|
623
|
+
includedReferences.push(refDef.property);
|
|
624
|
+
} else {
|
|
625
|
+
logger3.debug(`Association '${refDef.property}' already included in query`, {
|
|
626
|
+
property: refDef.property
|
|
627
|
+
});
|
|
628
|
+
includedReferences.push(refDef.property);
|
|
629
|
+
}
|
|
630
|
+
} else {
|
|
631
|
+
logger3.debug(`No association found for reference '${refDef.property}' - will use separate query`, {
|
|
632
|
+
property: refDef.property,
|
|
633
|
+
availableAssociations: Object.keys(model.associations || {})
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return { options, includedReferences };
|
|
638
|
+
};
|
|
344
639
|
var addAggregationIncludes = (options, model, aggregationDefinitions) => {
|
|
345
640
|
if (!aggregationDefinitions || aggregationDefinitions.length === 0) {
|
|
346
641
|
return { options, includedAggregations: [] };
|
|
@@ -354,7 +649,7 @@ var addAggregationIncludes = (options, model, aggregationDefinitions) => {
|
|
|
354
649
|
(inc) => typeof inc === "string" && inc === aggDef.property || typeof inc === "object" && inc.as === aggDef.property
|
|
355
650
|
);
|
|
356
651
|
if (!alreadyIncluded) {
|
|
357
|
-
logger3.
|
|
652
|
+
logger3.default(`Auto-detected association for aggregation '${aggDef.property}' - using INCLUDE to prevent N+1`, {
|
|
358
653
|
property: aggDef.property,
|
|
359
654
|
associationType: association.associationType,
|
|
360
655
|
targetModel: association.target.name
|
|
@@ -381,14 +676,25 @@ var addAggregationIncludes = (options, model, aggregationDefinitions) => {
|
|
|
381
676
|
}
|
|
382
677
|
return { options, includedAggregations };
|
|
383
678
|
};
|
|
384
|
-
var buildQuery = (itemQuery, model) => {
|
|
679
|
+
var buildQuery = (itemQuery, model, references, registry) => {
|
|
385
680
|
logger3.default(`QueryBuilder build called with itemQuery: ${stringifyJSON(itemQuery)}`);
|
|
681
|
+
logger3.debug(`[buildQuery] Parameters:`, {
|
|
682
|
+
modelName: model.name,
|
|
683
|
+
referencesCount: references?.length || 0,
|
|
684
|
+
references: references?.map((r) => ({ property: r.property, column: r.column })) || [],
|
|
685
|
+
hasRegistry: !!registry,
|
|
686
|
+
hasCompoundCondition: !!itemQuery.compoundCondition
|
|
687
|
+
});
|
|
386
688
|
let options = {
|
|
387
689
|
where: {}
|
|
388
690
|
};
|
|
691
|
+
const allReferences = /* @__PURE__ */ new Map();
|
|
692
|
+
if (references) {
|
|
693
|
+
allReferences.set(model.name, references);
|
|
694
|
+
}
|
|
389
695
|
if (itemQuery.compoundCondition) {
|
|
390
696
|
logger3.default(`QueryBuilder adding conditions: ${stringifyJSON(itemQuery.compoundCondition)}`);
|
|
391
|
-
options = addCompoundCondition(options, itemQuery.compoundCondition, model);
|
|
697
|
+
options = addCompoundCondition(options, itemQuery.compoundCondition, model, references, allReferences, registry);
|
|
392
698
|
}
|
|
393
699
|
if (model.getAttributes().deletedAt || model.getAttributes().isDeleted) {
|
|
394
700
|
options = addDeleteQuery(options, model);
|
|
@@ -699,12 +1005,12 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
699
1005
|
pk: columnValue,
|
|
700
1006
|
loc: []
|
|
701
1007
|
};
|
|
702
|
-
libLogger3.
|
|
1008
|
+
libLogger3.default("Using empty loc array for composite item reference", {
|
|
703
1009
|
kta: referenceDefinition.kta,
|
|
704
1010
|
property: referenceDefinition.property
|
|
705
1011
|
});
|
|
706
1012
|
}
|
|
707
|
-
libLogger3.
|
|
1013
|
+
libLogger3.default("Created reference key", {
|
|
708
1014
|
itemKey,
|
|
709
1015
|
isCompositeItem,
|
|
710
1016
|
hasLocationColumns: !!referenceDefinition.locationColumns,
|
|
@@ -716,7 +1022,7 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
716
1022
|
libLogger3.debug("Using cached reference", { itemKey, property: referenceDefinition.property });
|
|
717
1023
|
referencedItem = context.getCached(itemKey);
|
|
718
1024
|
} else if (context.isInProgress(itemKey)) {
|
|
719
|
-
libLogger3.
|
|
1025
|
+
libLogger3.default("Circular dependency detected, creating reference placeholder", {
|
|
720
1026
|
itemKey,
|
|
721
1027
|
property: referenceDefinition.property
|
|
722
1028
|
});
|
|
@@ -879,7 +1185,7 @@ function addAggsToItem(item, aggregationDefinitions) {
|
|
|
879
1185
|
if (typeof aggregationValue !== "undefined") {
|
|
880
1186
|
aggs[aggDef.property] = aggregationValue;
|
|
881
1187
|
delete result[aggDef.property];
|
|
882
|
-
libLogger2.
|
|
1188
|
+
libLogger2.default(`Moved aggregation '${aggDef.property}' to aggs structure`, {
|
|
883
1189
|
property: aggDef.property,
|
|
884
1190
|
hasValue: typeof aggregationValue !== "undefined",
|
|
885
1191
|
valueType: Array.isArray(aggregationValue) ? "array" : typeof aggregationValue
|
|
@@ -919,7 +1225,7 @@ function removeAggsFromItem(item, aggregationDefinitions) {
|
|
|
919
1225
|
|
|
920
1226
|
// src/RowProcessor.ts
|
|
921
1227
|
var logger6 = logger_default.get("sequelize", "RowProcessor");
|
|
922
|
-
var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefinitions, registry, context, includedAggregations) => {
|
|
1228
|
+
var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefinitions, registry, context, includedAggregations, includedReferences) => {
|
|
923
1229
|
logger6.default("Processing Row", { row });
|
|
924
1230
|
const operationContext = context || createOperationContext();
|
|
925
1231
|
return contextManager.withContext(operationContext, async () => {
|
|
@@ -932,9 +1238,22 @@ var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefiniti
|
|
|
932
1238
|
try {
|
|
933
1239
|
if (referenceDefinitions && referenceDefinitions.length > 0) {
|
|
934
1240
|
const referenceStartTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
935
|
-
const referencePromises = referenceDefinitions.map((referenceDefinition) => {
|
|
936
|
-
|
|
937
|
-
|
|
1241
|
+
const referencePromises = referenceDefinitions.map(async (referenceDefinition) => {
|
|
1242
|
+
const alreadyLoaded = includedReferences && includedReferences.includes(referenceDefinition.property) && typeof item[referenceDefinition.property] !== "undefined";
|
|
1243
|
+
if (alreadyLoaded) {
|
|
1244
|
+
logger6.default(
|
|
1245
|
+
`Skipping buildSequelizeReference for '${referenceDefinition.property}' - already loaded via INCLUDE (N+1 prevention)`,
|
|
1246
|
+
{
|
|
1247
|
+
property: referenceDefinition.property,
|
|
1248
|
+
itemType: item.key.kt,
|
|
1249
|
+
hasData: item[referenceDefinition.property] ? "loaded" : "undefined"
|
|
1250
|
+
}
|
|
1251
|
+
);
|
|
1252
|
+
return item;
|
|
1253
|
+
} else {
|
|
1254
|
+
logger6.default("Processing Reference for %s to %s", item.key.kt, stringifyJSON(referenceDefinition.kta));
|
|
1255
|
+
return buildSequelizeReference(item, referenceDefinition, registry, operationContext);
|
|
1256
|
+
}
|
|
938
1257
|
});
|
|
939
1258
|
await Promise.all(referencePromises);
|
|
940
1259
|
const referenceDuration = (typeof performance !== "undefined" ? performance.now() : Date.now()) - referenceStartTime;
|
|
@@ -946,7 +1265,7 @@ var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefiniti
|
|
|
946
1265
|
for (const aggregationDefinition of aggregationDefinitions) {
|
|
947
1266
|
const alreadyLoaded = includedAggregations && includedAggregations.includes(aggregationDefinition.property) && typeof item[aggregationDefinition.property] !== "undefined";
|
|
948
1267
|
if (alreadyLoaded) {
|
|
949
|
-
logger6.
|
|
1268
|
+
logger6.default(
|
|
950
1269
|
`Skipping buildAggregation for '${aggregationDefinition.property}' - already loaded via INCLUDE (N+1 prevention)`,
|
|
951
1270
|
{
|
|
952
1271
|
property: aggregationDefinition.property,
|
|
@@ -966,11 +1285,11 @@ var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefiniti
|
|
|
966
1285
|
}
|
|
967
1286
|
if (referenceDefinitions && referenceDefinitions.length > 0) {
|
|
968
1287
|
item = addRefsToSequelizeItem(item, referenceDefinitions);
|
|
969
|
-
logger6.
|
|
1288
|
+
logger6.default("Added refs structure to item (transparent wrapper)", { key: item.key });
|
|
970
1289
|
}
|
|
971
1290
|
if (aggregationDefinitions && aggregationDefinitions.length > 0) {
|
|
972
1291
|
item = addAggsToItem(item, aggregationDefinitions);
|
|
973
|
-
logger6.
|
|
1292
|
+
logger6.default("Added aggs structure to item (transparent wrapper)", { key: item.key });
|
|
974
1293
|
}
|
|
975
1294
|
logger6.default("Processed Row: %j", stringifyJSON(item));
|
|
976
1295
|
return item;
|
|
@@ -1169,8 +1488,57 @@ function transformSequelizeError(error, itemType, key, modelName, itemData) {
|
|
|
1169
1488
|
return error;
|
|
1170
1489
|
}
|
|
1171
1490
|
|
|
1491
|
+
// src/metrics/QueryMetrics.ts
|
|
1492
|
+
var logger7 = logger_default.get("sequelize", "metrics", "QueryMetrics");
|
|
1493
|
+
var QueryMetrics = class {
|
|
1494
|
+
totalQueryCount = 0;
|
|
1495
|
+
queriesByModel = /* @__PURE__ */ new Map();
|
|
1496
|
+
LOG_INTERVAL = 10;
|
|
1497
|
+
/**
|
|
1498
|
+
* Records a query execution for a given model
|
|
1499
|
+
* @param modelName - The name of the Sequelize model the query was executed against
|
|
1500
|
+
*/
|
|
1501
|
+
recordQuery(modelName) {
|
|
1502
|
+
this.totalQueryCount++;
|
|
1503
|
+
const currentCount = this.queriesByModel.get(modelName) || 0;
|
|
1504
|
+
this.queriesByModel.set(modelName, currentCount + 1);
|
|
1505
|
+
if (this.totalQueryCount % this.LOG_INTERVAL === 0) {
|
|
1506
|
+
const modelBreakdown = Array.from(this.queriesByModel.entries()).map(([model, count]) => `${model}: ${count}`).join(", ");
|
|
1507
|
+
logger7.debug(
|
|
1508
|
+
`Query execution count: ${this.totalQueryCount} total queries. Breakdown by model: ${modelBreakdown || "none"}`
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Gets the total number of queries executed
|
|
1514
|
+
*/
|
|
1515
|
+
getTotalQueryCount() {
|
|
1516
|
+
return this.totalQueryCount;
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Gets the number of queries executed for a specific model
|
|
1520
|
+
*/
|
|
1521
|
+
getQueryCountForModel(modelName) {
|
|
1522
|
+
return this.queriesByModel.get(modelName) || 0;
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Gets a map of all model query counts
|
|
1526
|
+
*/
|
|
1527
|
+
getQueriesByModel() {
|
|
1528
|
+
return new Map(this.queriesByModel);
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Resets all metrics (useful for testing)
|
|
1532
|
+
*/
|
|
1533
|
+
reset() {
|
|
1534
|
+
this.totalQueryCount = 0;
|
|
1535
|
+
this.queriesByModel.clear();
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
var queryMetrics = new QueryMetrics();
|
|
1539
|
+
|
|
1172
1540
|
// src/ops/all.ts
|
|
1173
|
-
var
|
|
1541
|
+
var logger8 = logger_default.get("sequelize", "ops", "all");
|
|
1174
1542
|
var mergeIncludes = (existingIncludes, newIncludes) => {
|
|
1175
1543
|
const mergedIncludes = [...existingIncludes];
|
|
1176
1544
|
for (const newInclude of newIncludes) {
|
|
@@ -1197,10 +1565,16 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1197
1565
|
async (itemQuery, locations, allOptions) => {
|
|
1198
1566
|
try {
|
|
1199
1567
|
const locs = locations ?? [];
|
|
1200
|
-
|
|
1568
|
+
logger8.debug(`ALL operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc2) => `${loc2.kt}=${loc2.lk}`).join(", ") || "none"}`);
|
|
1201
1569
|
const loc = locs;
|
|
1202
1570
|
const model = models[0];
|
|
1203
|
-
let options = buildQuery(itemQuery ?? {}, model);
|
|
1571
|
+
let options = buildQuery(itemQuery ?? {}, model, references, registry);
|
|
1572
|
+
const { options: optionsWithRefs, includedReferences } = addReferenceIncludes(
|
|
1573
|
+
options,
|
|
1574
|
+
model,
|
|
1575
|
+
references || []
|
|
1576
|
+
);
|
|
1577
|
+
options = optionsWithRefs;
|
|
1204
1578
|
const { options: optionsWithAggs, includedAggregations } = addAggregationIncludes(
|
|
1205
1579
|
options,
|
|
1206
1580
|
model,
|
|
@@ -1216,7 +1590,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1216
1590
|
const relationshipInfo = buildRelationshipPath(model, locKey.kt, kta, true);
|
|
1217
1591
|
if (!relationshipInfo.found) {
|
|
1218
1592
|
const errorMessage = `Location key '${locKey.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1219
|
-
|
|
1593
|
+
logger8.error(errorMessage, { locations: loc, kta });
|
|
1220
1594
|
throw new Error(errorMessage);
|
|
1221
1595
|
}
|
|
1222
1596
|
if (relationshipInfo.isDirect) {
|
|
@@ -1227,31 +1601,31 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1227
1601
|
}
|
|
1228
1602
|
for (const locKey of directLocations) {
|
|
1229
1603
|
if (locKey.lk === void 0 || locKey.lk == null || locKey.lk === "" || typeof locKey.lk === "object" && Object.keys(locKey.lk).length === 0) {
|
|
1230
|
-
|
|
1604
|
+
logger8.error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, { locKey, locations: loc });
|
|
1231
1605
|
throw new Error(`Location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1232
1606
|
}
|
|
1233
1607
|
const foreignKeyField = locKey.kt + "Id";
|
|
1234
1608
|
if (options.where[foreignKeyField]) {
|
|
1235
|
-
|
|
1609
|
+
logger8.debug(`[ALL] Field ${foreignKeyField} already constrained by itemQuery, skipping location constraint to avoid conflicts`);
|
|
1236
1610
|
continue;
|
|
1237
1611
|
}
|
|
1238
|
-
|
|
1612
|
+
logger8.trace(`[ALL] Setting direct location where clause: ${foreignKeyField} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1239
1613
|
options.where[foreignKeyField] = {
|
|
1240
1614
|
[Op2.eq]: locKey.lk
|
|
1241
1615
|
};
|
|
1242
1616
|
}
|
|
1243
1617
|
for (const locKey of hierarchicalLocations) {
|
|
1244
1618
|
if (locKey.lk === void 0 || locKey.lk == null || locKey.lk === "" || typeof locKey.lk === "object" && Object.keys(locKey.lk).length === 0) {
|
|
1245
|
-
|
|
1619
|
+
logger8.error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`, { locKey, locations: loc });
|
|
1246
1620
|
throw new Error(`Hierarchical location key '${locKey.kt}' has invalid lk value: ${stringifyJSON(locKey.lk)}`);
|
|
1247
1621
|
}
|
|
1248
1622
|
const relationshipInfo = buildRelationshipPath(model, locKey.kt, kta);
|
|
1249
1623
|
if (relationshipInfo.found && relationshipInfo.path) {
|
|
1250
1624
|
if (options.where[relationshipInfo.path]) {
|
|
1251
|
-
|
|
1625
|
+
logger8.debug(`[ALL] Field ${relationshipInfo.path} already constrained by itemQuery, skipping hierarchical location constraint to avoid conflicts`);
|
|
1252
1626
|
continue;
|
|
1253
1627
|
}
|
|
1254
|
-
|
|
1628
|
+
logger8.trace(`[ALL] Setting hierarchical location where clause: ${relationshipInfo.path} = ${stringifyJSON(locKey.lk)} (type: ${typeof locKey.lk})`);
|
|
1255
1629
|
options.where[relationshipInfo.path] = {
|
|
1256
1630
|
[Op2.eq]: locKey.lk
|
|
1257
1631
|
};
|
|
@@ -1269,7 +1643,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1269
1643
|
const effectiveOffset = allOptions?.offset ?? itemQuery?.offset ?? 0;
|
|
1270
1644
|
const whereFields = options.where ? Object.keys(options.where).join(", ") : "none";
|
|
1271
1645
|
const includeCount = options.include?.length || 0;
|
|
1272
|
-
|
|
1646
|
+
logger8.default(
|
|
1273
1647
|
`All query configured for ${model.name} with where fields: ${whereFields}, includes: ${includeCount}, limit: ${effectiveLimit}, offset: ${effectiveOffset}`
|
|
1274
1648
|
);
|
|
1275
1649
|
const countOptions = {
|
|
@@ -1279,9 +1653,10 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1279
1653
|
if (options.include) {
|
|
1280
1654
|
countOptions.include = options.include;
|
|
1281
1655
|
}
|
|
1656
|
+
queryMetrics.recordQuery(model.name);
|
|
1282
1657
|
const countResult = await model.count(countOptions);
|
|
1283
1658
|
const total = Array.isArray(countResult) ? countResult.length : countResult;
|
|
1284
|
-
|
|
1659
|
+
logger8.debug(`[ALL] Total count for ${model.name}: ${total}`);
|
|
1285
1660
|
delete options.limit;
|
|
1286
1661
|
delete options.offset;
|
|
1287
1662
|
if (effectiveLimit !== void 0) {
|
|
@@ -1291,10 +1666,11 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1291
1666
|
options.offset = effectiveOffset;
|
|
1292
1667
|
}
|
|
1293
1668
|
try {
|
|
1294
|
-
|
|
1669
|
+
logger8.trace(`[ALL] Executing ${model.name}.findAll() with options: ${JSON.stringify(options, null, 2)}`);
|
|
1295
1670
|
} catch {
|
|
1296
|
-
|
|
1671
|
+
logger8.trace(`[ALL] Executing ${model.name}.findAll() with options containing non-serializable operators (${Object.keys(options.where || {}).length} where conditions)`);
|
|
1297
1672
|
}
|
|
1673
|
+
queryMetrics.recordQuery(model.name);
|
|
1298
1674
|
const matchingItems = await model.findAll(options);
|
|
1299
1675
|
const currentContext = contextManager.getCurrentContext();
|
|
1300
1676
|
const items = await Promise.all(matchingItems.map(async (row) => {
|
|
@@ -1305,11 +1681,12 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1305
1681
|
aggregations || [],
|
|
1306
1682
|
registry,
|
|
1307
1683
|
currentContext,
|
|
1308
|
-
includedAggregations
|
|
1684
|
+
includedAggregations,
|
|
1685
|
+
includedReferences
|
|
1309
1686
|
);
|
|
1310
1687
|
return validateKeys(processedRow, coordinate.kta);
|
|
1311
1688
|
}));
|
|
1312
|
-
|
|
1689
|
+
logger8.debug(`[ALL] Returning ${items.length} of ${total} ${model.name} records`);
|
|
1313
1690
|
return {
|
|
1314
1691
|
items,
|
|
1315
1692
|
metadata: {
|
|
@@ -1330,7 +1707,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1330
1707
|
// src/ops/create.ts
|
|
1331
1708
|
import { createCreateWrapper, isComKey as isComKey3, isPriKey as isPriKey3 } from "@fjell/core";
|
|
1332
1709
|
import { validateKeys as validateKeys2 } from "@fjell/core/validation";
|
|
1333
|
-
var
|
|
1710
|
+
var logger9 = logger_default.get("sequelize", "ops", "create");
|
|
1334
1711
|
async function validateHierarchicalChain(models, locKey, kta) {
|
|
1335
1712
|
const locatorIndex = kta.indexOf(locKey.kt);
|
|
1336
1713
|
if (locatorIndex === -1) {
|
|
@@ -1340,6 +1717,7 @@ async function validateHierarchicalChain(models, locKey, kta) {
|
|
|
1340
1717
|
try {
|
|
1341
1718
|
const chainResult = buildRelationshipChain(locatorModel, kta, locatorIndex, kta.length - 1);
|
|
1342
1719
|
if (!chainResult.success) {
|
|
1720
|
+
queryMetrics.recordQuery(locatorModel.name);
|
|
1343
1721
|
const record2 = await locatorModel.findByPk(locKey.lk);
|
|
1344
1722
|
if (!record2) {
|
|
1345
1723
|
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist`);
|
|
@@ -1352,6 +1730,7 @@ async function validateHierarchicalChain(models, locKey, kta) {
|
|
|
1352
1730
|
if (chainResult.includes && chainResult.includes.length > 0) {
|
|
1353
1731
|
queryOptions.include = chainResult.includes;
|
|
1354
1732
|
}
|
|
1733
|
+
queryMetrics.recordQuery(locatorModel.name);
|
|
1355
1734
|
const record = await locatorModel.findOne(queryOptions);
|
|
1356
1735
|
if (!record) {
|
|
1357
1736
|
throw new Error(`Referenced ${locKey.kt} with id ${locKey.lk} does not exist or chain is invalid`);
|
|
@@ -1370,8 +1749,8 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1370
1749
|
coordinate,
|
|
1371
1750
|
async (item, options) => {
|
|
1372
1751
|
const constraints = options?.key ? `key: pk=${options.key.pk}, loc=[${isComKey3(options.key) ? options.key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ") : ""}]` : options?.locations ? `locations: ${options.locations.map((loc) => `${loc.kt}=${loc.lk}`).join(", ")}` : "no constraints";
|
|
1373
|
-
|
|
1374
|
-
|
|
1752
|
+
logger9.debug(`CREATE operation called on ${models[0].name} with ${constraints}`);
|
|
1753
|
+
logger9.default(`Create configured for ${models[0].name} with ${Object.keys(item).length} item fields`);
|
|
1375
1754
|
const model = models[0];
|
|
1376
1755
|
const modelAttributes = model.getAttributes();
|
|
1377
1756
|
let itemData = { ...item };
|
|
@@ -1409,7 +1788,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1409
1788
|
if (!relationshipInfo.found) {
|
|
1410
1789
|
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1411
1790
|
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)}`;
|
|
1412
|
-
|
|
1791
|
+
logger9.error(errorMessage, { key: comKey, kta, associations });
|
|
1413
1792
|
throw new Error(errorMessage);
|
|
1414
1793
|
}
|
|
1415
1794
|
if (relationshipInfo.isDirect) {
|
|
@@ -1420,7 +1799,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1420
1799
|
}
|
|
1421
1800
|
for (const locKey of directLocations) {
|
|
1422
1801
|
if (locKey.lk == null || locKey.lk === "") {
|
|
1423
|
-
|
|
1802
|
+
logger9.error(`Composite key location '${locKey.kt}' has undefined/null lk value`, { locKey, key: comKey });
|
|
1424
1803
|
throw new Error(`Composite key location '${locKey.kt}' has undefined/null lk value`);
|
|
1425
1804
|
}
|
|
1426
1805
|
const foreignKeyField = locKey.kt + "Id";
|
|
@@ -1439,7 +1818,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1439
1818
|
if (!relationshipInfo.found) {
|
|
1440
1819
|
const associations = model.associations ? Object.keys(model.associations) : [];
|
|
1441
1820
|
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)}`;
|
|
1442
|
-
|
|
1821
|
+
logger9.error(errorMessage, { locations: options.locations, kta, associations });
|
|
1443
1822
|
throw new Error(errorMessage);
|
|
1444
1823
|
}
|
|
1445
1824
|
if (relationshipInfo.isDirect) {
|
|
@@ -1450,7 +1829,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1450
1829
|
}
|
|
1451
1830
|
for (const locKey of directLocations) {
|
|
1452
1831
|
if (locKey.lk == null || locKey.lk === "") {
|
|
1453
|
-
|
|
1832
|
+
logger9.error(`Location option '${locKey.kt}' has undefined/null lk value`, { locKey, locations: options.locations });
|
|
1454
1833
|
throw new Error(`Location option '${locKey.kt}' has undefined/null lk value`);
|
|
1455
1834
|
}
|
|
1456
1835
|
const foreignKeyField = locKey.kt + "Id";
|
|
@@ -1461,11 +1840,12 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1461
1840
|
}
|
|
1462
1841
|
}
|
|
1463
1842
|
try {
|
|
1464
|
-
|
|
1843
|
+
logger9.trace(`[CREATE] Executing ${model.name}.create() with data: ${stringifyJSON(itemData)}`);
|
|
1844
|
+
queryMetrics.recordQuery(model.name);
|
|
1465
1845
|
const createdRecord = await model.create(itemData);
|
|
1466
1846
|
const processedRecord = await processRow(createdRecord, kta, references || [], aggregations || [], registry, void 0, void 0);
|
|
1467
1847
|
const result = validateKeys2(processedRecord, kta);
|
|
1468
|
-
|
|
1848
|
+
logger9.debug(`[CREATE] Created ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${createdRecord.id}`}`);
|
|
1469
1849
|
return result;
|
|
1470
1850
|
} catch (error) {
|
|
1471
1851
|
throw transformSequelizeError(error, kta[0], options?.key, model.name, itemData);
|
|
@@ -1477,7 +1857,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1477
1857
|
// src/ops/find.ts
|
|
1478
1858
|
import { createFindWrapper } from "@fjell/core";
|
|
1479
1859
|
import { validateKeys as validateKeys3 } from "@fjell/core/validation";
|
|
1480
|
-
var
|
|
1860
|
+
var logger10 = logger_default.get("sequelize", "ops", "find");
|
|
1481
1861
|
var getFindOperation = (models, definition, registry) => {
|
|
1482
1862
|
const { options: { finders, references, aggregations } } = definition;
|
|
1483
1863
|
return createFindWrapper(
|
|
@@ -1487,20 +1867,20 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1487
1867
|
const locs = locations ?? [];
|
|
1488
1868
|
const params = finderParams ?? {};
|
|
1489
1869
|
const locationFilters = locs.map((loc) => `${loc.kt}=${loc.lk}`).join(", ") || "none";
|
|
1490
|
-
|
|
1870
|
+
logger10.debug(
|
|
1491
1871
|
`FIND operation called on ${models[0].name} with finder '${finder}' and ${locs.length} location filters: ${locationFilters}`
|
|
1492
1872
|
);
|
|
1493
|
-
|
|
1873
|
+
logger10.default(`Find configured for ${models[0].name} using finder '${finder}' with ${Object.keys(params).length} params`);
|
|
1494
1874
|
if (!finders || !finders[finder]) {
|
|
1495
|
-
|
|
1875
|
+
logger10.error(`No finders have been defined for this lib`);
|
|
1496
1876
|
throw new Error(`No finders found`);
|
|
1497
1877
|
}
|
|
1498
1878
|
const finderMethod = finders[finder];
|
|
1499
1879
|
if (!finderMethod) {
|
|
1500
|
-
|
|
1880
|
+
logger10.error(`Finder %s not found`, finder);
|
|
1501
1881
|
throw new Error(`Finder ${finder} not found`);
|
|
1502
1882
|
}
|
|
1503
|
-
|
|
1883
|
+
logger10.trace(`[FIND] Executing finder '${finder}' on ${models[0].name} with params: ${stringifyJSON(params)}, locations: ${stringifyJSON(locs)}, options: ${stringifyJSON(findOptions)}`);
|
|
1504
1884
|
const finderResult = await finderMethod(params, locs, findOptions);
|
|
1505
1885
|
const processItems = async (items) => {
|
|
1506
1886
|
return await Promise.all(items.map(async (row) => {
|
|
@@ -1512,7 +1892,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1512
1892
|
if (isOptInResult) {
|
|
1513
1893
|
const optInResult = finderResult;
|
|
1514
1894
|
const processedResults2 = optInResult.items && optInResult.items.length > 0 ? await processItems(optInResult.items) : [];
|
|
1515
|
-
|
|
1895
|
+
logger10.debug(`[FIND] Finder opted-in, found ${processedResults2.length} ${models[0].name} records using finder '${finder}' (total: ${optInResult.metadata.total})`);
|
|
1516
1896
|
return {
|
|
1517
1897
|
items: processedResults2,
|
|
1518
1898
|
metadata: optInResult.metadata
|
|
@@ -1520,7 +1900,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1520
1900
|
}
|
|
1521
1901
|
const results = finderResult;
|
|
1522
1902
|
const processedResults = results && results.length > 0 ? await processItems(results) : [];
|
|
1523
|
-
|
|
1903
|
+
logger10.debug(`[FIND] Legacy finder, found ${processedResults.length} ${models[0].name} records using finder '${finder}'`);
|
|
1524
1904
|
return {
|
|
1525
1905
|
items: processedResults,
|
|
1526
1906
|
metadata: {
|
|
@@ -1531,7 +1911,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1531
1911
|
}
|
|
1532
1912
|
};
|
|
1533
1913
|
} catch (error) {
|
|
1534
|
-
|
|
1914
|
+
logger10.error("Error in find operation", {
|
|
1535
1915
|
finder,
|
|
1536
1916
|
finderParams,
|
|
1537
1917
|
locations,
|
|
@@ -1563,7 +1943,7 @@ import {
|
|
|
1563
1943
|
validateKeys as validateKeys4
|
|
1564
1944
|
} from "@fjell/core";
|
|
1565
1945
|
import { NotFoundError } from "@fjell/core";
|
|
1566
|
-
var
|
|
1946
|
+
var logger11 = logger_default.get("sequelize", "ops", "get");
|
|
1567
1947
|
var processCompositeKey = (comKey, model, kta) => {
|
|
1568
1948
|
const where = { id: comKey.pk };
|
|
1569
1949
|
const includes = [];
|
|
@@ -1571,7 +1951,7 @@ var processCompositeKey = (comKey, model, kta) => {
|
|
|
1571
1951
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta);
|
|
1572
1952
|
if (!relationshipInfo.found) {
|
|
1573
1953
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships. Key type array: [${kta.join(", ")}], Composite key: ${stringifyJSON(comKey)}, Available associations: [${Object.keys(model.associations || {}).join(", ")}]`;
|
|
1574
|
-
|
|
1954
|
+
logger11.error(errorMessage, { key: comKey, kta });
|
|
1575
1955
|
throw new Error(errorMessage);
|
|
1576
1956
|
}
|
|
1577
1957
|
if (relationshipInfo.path) {
|
|
@@ -1598,40 +1978,53 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1598
1978
|
async (key) => {
|
|
1599
1979
|
try {
|
|
1600
1980
|
if (!isValidItemKey(key)) {
|
|
1601
|
-
|
|
1981
|
+
logger11.error("Key for Get is not a valid ItemKey: %j", key);
|
|
1602
1982
|
throw new Error("Key for Get is not a valid ItemKey");
|
|
1603
1983
|
}
|
|
1604
1984
|
const keyDescription = isPriKey4(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1605
|
-
|
|
1606
|
-
|
|
1985
|
+
logger11.debug(`GET operation called on ${models[0].name} with ${keyDescription}`);
|
|
1986
|
+
logger11.default(`Get configured for ${models[0].name} with ${isPriKey4(key) ? "primary" : "composite"} key`);
|
|
1607
1987
|
const itemKey = key;
|
|
1608
1988
|
const model = models[0];
|
|
1609
1989
|
let item;
|
|
1610
1990
|
let includedAggregations = [];
|
|
1991
|
+
let includedReferences = [];
|
|
1611
1992
|
if (isPriKey4(itemKey)) {
|
|
1612
1993
|
let options = {};
|
|
1994
|
+
const refResult = addReferenceIncludes(options, model, references || []);
|
|
1995
|
+
includedReferences = refResult.includedReferences;
|
|
1996
|
+
options = refResult.options;
|
|
1613
1997
|
const aggResult = addAggregationIncludes(options, model, aggregations || []);
|
|
1614
1998
|
includedAggregations = aggResult.includedAggregations;
|
|
1615
1999
|
options = aggResult.options;
|
|
1616
|
-
|
|
2000
|
+
logger11.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${itemKey.pk}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2001
|
+
queryMetrics.recordQuery(model.name);
|
|
1617
2002
|
item = options.include && options.include.length > 0 ? await model.findByPk(itemKey.pk, { include: options.include }) : await model.findByPk(itemKey.pk);
|
|
1618
2003
|
} else if (isComKey4(itemKey)) {
|
|
1619
2004
|
const comKey = itemKey;
|
|
1620
2005
|
if (comKey.loc.length === 0) {
|
|
1621
2006
|
let options = {};
|
|
2007
|
+
const refResult = addReferenceIncludes(options, model, references || []);
|
|
2008
|
+
includedReferences = refResult.includedReferences;
|
|
2009
|
+
options = refResult.options;
|
|
1622
2010
|
const aggResult = addAggregationIncludes(options, model, aggregations || []);
|
|
1623
2011
|
includedAggregations = aggResult.includedAggregations;
|
|
1624
2012
|
options = aggResult.options;
|
|
1625
|
-
|
|
1626
|
-
|
|
2013
|
+
logger11.debug(`[GET] Empty loc array detected - finding by primary key across all locations: ${comKey.pk}`);
|
|
2014
|
+
logger11.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${comKey.pk}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2015
|
+
queryMetrics.recordQuery(model.name);
|
|
1627
2016
|
item = options.include && options.include.length > 0 ? await model.findByPk(comKey.pk, { include: options.include }) : await model.findByPk(comKey.pk);
|
|
1628
2017
|
} else {
|
|
1629
2018
|
let queryOptions = processCompositeKey(comKey, model, kta);
|
|
2019
|
+
const refResult = addReferenceIncludes(queryOptions, model, references || []);
|
|
2020
|
+
includedReferences = refResult.includedReferences;
|
|
2021
|
+
queryOptions = refResult.options;
|
|
1630
2022
|
const aggResult = addAggregationIncludes(queryOptions, model, aggregations || []);
|
|
1631
2023
|
includedAggregations = aggResult.includedAggregations;
|
|
1632
2024
|
queryOptions = aggResult.options;
|
|
1633
|
-
|
|
1634
|
-
|
|
2025
|
+
logger11.default("Composite key query", { queryOptions });
|
|
2026
|
+
logger11.trace(`[GET] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}, ${includedReferences.length} reference includes, and ${includedAggregations.length} aggregation includes`);
|
|
2027
|
+
queryMetrics.recordQuery(model.name);
|
|
1635
2028
|
item = await model.findOne(queryOptions);
|
|
1636
2029
|
}
|
|
1637
2030
|
}
|
|
@@ -1643,8 +2036,8 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1643
2036
|
);
|
|
1644
2037
|
}
|
|
1645
2038
|
const currentContext = contextManager.getCurrentContext();
|
|
1646
|
-
const result = validateKeys4(await processRow(item, kta, references || [], aggregations || [], registry, currentContext, includedAggregations), kta);
|
|
1647
|
-
|
|
2039
|
+
const result = validateKeys4(await processRow(item, kta, references || [], aggregations || [], registry, currentContext, includedAggregations, includedReferences), kta);
|
|
2040
|
+
logger11.debug(`[GET] Retrieved ${model.name} with key: ${result.key ? JSON.stringify(result.key) : `id=${item.id}`}`);
|
|
1648
2041
|
return result;
|
|
1649
2042
|
} catch (error) {
|
|
1650
2043
|
if (error instanceof NotFoundError) throw error;
|
|
@@ -1656,21 +2049,21 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1656
2049
|
|
|
1657
2050
|
// src/ops/one.ts
|
|
1658
2051
|
import { createOneWrapper } from "@fjell/core";
|
|
1659
|
-
var
|
|
2052
|
+
var logger12 = logger_default.get("sequelize", "ops", "one");
|
|
1660
2053
|
var getOneOperation = (models, definition, registry) => {
|
|
1661
2054
|
return createOneWrapper(
|
|
1662
2055
|
definition.coordinate,
|
|
1663
2056
|
async (itemQuery, locations) => {
|
|
1664
2057
|
const locs = locations ?? [];
|
|
1665
|
-
|
|
1666
|
-
|
|
2058
|
+
logger12.debug(`ONE operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc) => `${loc.kt}=${loc.lk}`).join(", ") || "none"}`);
|
|
2059
|
+
logger12.default(`One configured for ${models[0].name} delegating to all operation`);
|
|
1667
2060
|
const result = await getAllOperation(models, definition, registry)(itemQuery ?? {}, locs, { limit: 1 });
|
|
1668
2061
|
if (result.items.length > 0) {
|
|
1669
2062
|
const item = result.items[0];
|
|
1670
|
-
|
|
2063
|
+
logger12.debug(`[ONE] Found ${models[0].name} record with key: ${item.key ? JSON.stringify(item.key) : "unknown"}`);
|
|
1671
2064
|
return item;
|
|
1672
2065
|
} else {
|
|
1673
|
-
|
|
2066
|
+
logger12.debug(`[ONE] No ${models[0].name} record found`);
|
|
1674
2067
|
return null;
|
|
1675
2068
|
}
|
|
1676
2069
|
}
|
|
@@ -1680,7 +2073,7 @@ var getOneOperation = (models, definition, registry) => {
|
|
|
1680
2073
|
// src/ops/remove.ts
|
|
1681
2074
|
import { abbrevIK, isComKey as isComKey5, isPriKey as isPriKey5, isValidItemKey as isValidItemKey2, createRemoveWrapper } from "@fjell/core";
|
|
1682
2075
|
import { NotFoundError as NotFoundError2 } from "@fjell/core";
|
|
1683
|
-
var
|
|
2076
|
+
var logger13 = logger_default.get("sequelize", "ops", "remove");
|
|
1684
2077
|
var processCompositeKey2 = (comKey, model, kta) => {
|
|
1685
2078
|
const where = { id: comKey.pk };
|
|
1686
2079
|
const includes = [];
|
|
@@ -1688,7 +2081,7 @@ var processCompositeKey2 = (comKey, model, kta) => {
|
|
|
1688
2081
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta);
|
|
1689
2082
|
if (!relationshipInfo.found) {
|
|
1690
2083
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1691
|
-
|
|
2084
|
+
logger13.error(errorMessage, { key: comKey, kta });
|
|
1692
2085
|
throw new Error(errorMessage);
|
|
1693
2086
|
}
|
|
1694
2087
|
if (relationshipInfo.path) {
|
|
@@ -1715,24 +2108,26 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1715
2108
|
async (key) => {
|
|
1716
2109
|
try {
|
|
1717
2110
|
if (!isValidItemKey2(key)) {
|
|
1718
|
-
|
|
2111
|
+
logger13.error("Key for Remove is not a valid ItemKey: %j", key);
|
|
1719
2112
|
throw new Error("Key for Remove is not a valid ItemKey");
|
|
1720
2113
|
}
|
|
1721
2114
|
const keyDescription = isPriKey5(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1722
|
-
|
|
1723
|
-
|
|
2115
|
+
logger13.debug(`REMOVE operation called on ${models[0].name} with ${keyDescription}`);
|
|
2116
|
+
logger13.default(`Remove configured for ${models[0].name} with ${isPriKey5(key) ? "primary" : "composite"} key`);
|
|
1724
2117
|
const model = models[0];
|
|
1725
2118
|
let item;
|
|
1726
2119
|
let returnItem;
|
|
1727
|
-
|
|
2120
|
+
logger13.debug("remove: %s", abbrevIK(key));
|
|
1728
2121
|
if (isPriKey5(key)) {
|
|
1729
|
-
|
|
2122
|
+
logger13.debug(`[REMOVE] Executing ${model.name}.findByPk() with pk: ${key.pk}`);
|
|
2123
|
+
queryMetrics.recordQuery(model.name);
|
|
1730
2124
|
item = await model.findByPk(key.pk);
|
|
1731
2125
|
} else if (isComKey5(key)) {
|
|
1732
2126
|
const comKey = key;
|
|
1733
2127
|
const queryOptions = processCompositeKey2(comKey, model, kta);
|
|
1734
|
-
|
|
1735
|
-
|
|
2128
|
+
logger13.default(`Remove composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(", ") : "none"}`);
|
|
2129
|
+
logger13.debug(`[REMOVE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
2130
|
+
queryMetrics.recordQuery(model.name);
|
|
1736
2131
|
item = await model.findOne(queryOptions);
|
|
1737
2132
|
}
|
|
1738
2133
|
if (!item) {
|
|
@@ -1751,13 +2146,15 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1751
2146
|
if (model.getAttributes().deletedAt) {
|
|
1752
2147
|
item.deletedAt = /* @__PURE__ */ new Date();
|
|
1753
2148
|
}
|
|
1754
|
-
|
|
2149
|
+
logger13.debug(`[REMOVE] Executing ${model.name}.save() for soft delete`);
|
|
2150
|
+
queryMetrics.recordQuery(model.name);
|
|
1755
2151
|
await item?.save();
|
|
1756
2152
|
returnItem = item?.get({ plain: true });
|
|
1757
2153
|
returnItem = addKey(item, returnItem, kta);
|
|
1758
2154
|
returnItem = populateEvents(returnItem);
|
|
1759
2155
|
} else if (options.deleteOnRemove) {
|
|
1760
|
-
|
|
2156
|
+
logger13.debug(`[REMOVE] Executing ${model.name}.destroy() for hard delete`);
|
|
2157
|
+
queryMetrics.recordQuery(model.name);
|
|
1761
2158
|
await item?.destroy();
|
|
1762
2159
|
returnItem = item?.get({ plain: true });
|
|
1763
2160
|
returnItem = addKey(item, returnItem, kta);
|
|
@@ -1765,7 +2162,7 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1765
2162
|
} else {
|
|
1766
2163
|
throw new Error("No deletedAt or isDeleted attribute found in model, and deleteOnRemove is not set");
|
|
1767
2164
|
}
|
|
1768
|
-
|
|
2165
|
+
logger13.debug(`[REMOVE] Removed ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${item.id}`}`);
|
|
1769
2166
|
const { references } = options;
|
|
1770
2167
|
if (references && references.length > 0) {
|
|
1771
2168
|
returnItem = addRefsToSequelizeItem(returnItem, references);
|
|
@@ -1789,7 +2186,7 @@ import {
|
|
|
1789
2186
|
import { validateKeys as validateKeys5 } from "@fjell/core/validation";
|
|
1790
2187
|
import { NotFoundError as NotFoundError3 } from "@fjell/core";
|
|
1791
2188
|
import { Op as Op3 } from "sequelize";
|
|
1792
|
-
var
|
|
2189
|
+
var logger14 = logger_default.get("sequelize", "ops", "update");
|
|
1793
2190
|
var mergeIncludes2 = (existingIncludes, newIncludes) => {
|
|
1794
2191
|
const mergedIncludes = [...existingIncludes];
|
|
1795
2192
|
for (const newInclude of newIncludes) {
|
|
@@ -1821,15 +2218,16 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1821
2218
|
);
|
|
1822
2219
|
}
|
|
1823
2220
|
const keyDescription = isPriKey6(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1824
|
-
|
|
2221
|
+
logger14.debug(`UPDATE operation called on ${models[0].name} with ${keyDescription}`, { options });
|
|
1825
2222
|
const { coordinate } = definition;
|
|
1826
2223
|
const { kta } = coordinate;
|
|
1827
|
-
|
|
2224
|
+
logger14.debug("update: %s, %j", abbrevIK2(key), item);
|
|
1828
2225
|
const model = models[0];
|
|
1829
2226
|
let response;
|
|
1830
2227
|
if (isPriKey6(key)) {
|
|
1831
2228
|
const priKey = key;
|
|
1832
|
-
|
|
2229
|
+
logger14.trace(`[UPDATE] Executing ${model.name}.findByPk() with pk: ${priKey.pk}`);
|
|
2230
|
+
queryMetrics.recordQuery(model.name);
|
|
1833
2231
|
response = await model.findByPk(priKey.pk);
|
|
1834
2232
|
} else if (isComKey6(key)) {
|
|
1835
2233
|
const comKey = key;
|
|
@@ -1839,7 +2237,7 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1839
2237
|
const relationshipInfo = buildRelationshipPath(model, locator.kt, kta, true);
|
|
1840
2238
|
if (!relationshipInfo.found) {
|
|
1841
2239
|
const errorMessage = `Composite key locator '${locator.kt}' cannot be resolved on model '${model.name}' or through its relationships.`;
|
|
1842
|
-
|
|
2240
|
+
logger14.error(errorMessage, { key: comKey, kta });
|
|
1843
2241
|
throw new Error(errorMessage);
|
|
1844
2242
|
}
|
|
1845
2243
|
if (relationshipInfo.isDirect) {
|
|
@@ -1858,8 +2256,9 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1858
2256
|
if (additionalIncludes.length > 0) {
|
|
1859
2257
|
queryOptions.include = mergeIncludes2([], additionalIncludes);
|
|
1860
2258
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
2259
|
+
logger14.default(`Update composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(", ") : "none"}`);
|
|
2260
|
+
logger14.trace(`[UPDATE] Executing ${model.name}.findOne() with options: ${stringifyJSON(queryOptions)}`);
|
|
2261
|
+
queryMetrics.recordQuery(model.name);
|
|
1863
2262
|
response = await model.findOne(queryOptions);
|
|
1864
2263
|
}
|
|
1865
2264
|
if (!response) {
|
|
@@ -1878,13 +2277,14 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1878
2277
|
if (aggregations && aggregations.length > 0) {
|
|
1879
2278
|
updateProps = removeAggsFromItem(updateProps, aggregations);
|
|
1880
2279
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
2280
|
+
logger14.default(`Update found ${model.name} record to modify`);
|
|
2281
|
+
logger14.default(`Update properties configured: ${Object.keys(updateProps).join(", ")}`);
|
|
2282
|
+
logger14.trace(`[UPDATE] Executing ${model.name}.update() with properties: ${stringifyJSON(updateProps)}`);
|
|
2283
|
+
queryMetrics.recordQuery(model.name);
|
|
1884
2284
|
response = await response.update(updateProps);
|
|
1885
2285
|
const processedItem = await processRow(response, kta, references || [], aggregations || [], registry, void 0, void 0);
|
|
1886
2286
|
const returnItem = validateKeys5(processedItem, kta);
|
|
1887
|
-
|
|
2287
|
+
logger14.debug(`[UPDATE] Updated ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${response.id}`}`);
|
|
1888
2288
|
return returnItem;
|
|
1889
2289
|
} catch (error) {
|
|
1890
2290
|
if (error instanceof NotFoundError3) throw error;
|
|
@@ -1896,7 +2296,7 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1896
2296
|
|
|
1897
2297
|
// src/ops/upsert.ts
|
|
1898
2298
|
import { createUpsertWrapper, isValidItemKey as isValidItemKey3, NotFoundError as NotFoundError4 } from "@fjell/core";
|
|
1899
|
-
var
|
|
2299
|
+
var logger15 = logger_default.get("sequelize", "ops", "upsert");
|
|
1900
2300
|
var getUpsertOperation = (models, definition, registry) => {
|
|
1901
2301
|
const get = getGetOperation(models, definition, registry);
|
|
1902
2302
|
const update = getUpdateOperation(models, definition, registry);
|
|
@@ -1905,31 +2305,31 @@ var getUpsertOperation = (models, definition, registry) => {
|
|
|
1905
2305
|
definition.coordinate,
|
|
1906
2306
|
async (key, item, locations, options) => {
|
|
1907
2307
|
if (!isValidItemKey3(key)) {
|
|
1908
|
-
|
|
2308
|
+
logger15.error("Key for Upsert is not a valid ItemKey: %j", key);
|
|
1909
2309
|
throw new Error(`Key for Upsert is not a valid ItemKey: ${stringifyJSON(key)}`);
|
|
1910
2310
|
}
|
|
1911
|
-
|
|
2311
|
+
logger15.debug(`[UPSERT] Attempting upsert with key: ${stringifyJSON(key)}`, { options });
|
|
1912
2312
|
let resultItem = null;
|
|
1913
2313
|
try {
|
|
1914
|
-
|
|
2314
|
+
logger15.debug(`[UPSERT] Retrieving item by key: ${stringifyJSON(key)}`);
|
|
1915
2315
|
resultItem = await get(key);
|
|
1916
2316
|
} catch (error) {
|
|
1917
2317
|
const isNotFound = error instanceof NotFoundError4 || error?.name === "NotFoundError" || error?.errorInfo?.code === "NOT_FOUND";
|
|
1918
2318
|
if (isNotFound) {
|
|
1919
|
-
|
|
2319
|
+
logger15.debug(`[UPSERT] Item not found, creating new item with key: ${stringifyJSON(key)}, errorType: ${error?.name}, errorCode: ${error?.errorInfo?.code}`);
|
|
1920
2320
|
const createOptions3 = locations ? { locations } : { key };
|
|
1921
2321
|
resultItem = await create(item, createOptions3);
|
|
1922
2322
|
} else {
|
|
1923
|
-
|
|
2323
|
+
logger15.error(`[UPSERT] Unexpected error during get operation`, { error: error?.message, name: error?.name, code: error?.errorInfo?.code });
|
|
1924
2324
|
throw error;
|
|
1925
2325
|
}
|
|
1926
2326
|
}
|
|
1927
2327
|
if (!resultItem) {
|
|
1928
2328
|
throw new Error(`Failed to retrieve or create item for key: ${stringifyJSON(key)}`);
|
|
1929
2329
|
}
|
|
1930
|
-
|
|
2330
|
+
logger15.debug(`[UPSERT] Updating item with properties, key: ${stringifyJSON(key)}`, { options });
|
|
1931
2331
|
resultItem = await update(resultItem.key, item, options);
|
|
1932
|
-
|
|
2332
|
+
logger15.debug(`[UPSERT] Item upserted successfully: ${stringifyJSON(resultItem)}`);
|
|
1933
2333
|
return resultItem;
|
|
1934
2334
|
}
|
|
1935
2335
|
);
|
|
@@ -1958,9 +2358,9 @@ var createOperations = (models, coordinate, registry, options) => {
|
|
|
1958
2358
|
};
|
|
1959
2359
|
|
|
1960
2360
|
// src/SequelizeLibrary.ts
|
|
1961
|
-
var
|
|
2361
|
+
var logger16 = logger_default.get("SequelizeLibrary");
|
|
1962
2362
|
var createSequelizeLibrary = (registry, coordinate, models, options) => {
|
|
1963
|
-
|
|
2363
|
+
logger16.debug("createSequelizeLibrary", { coordinate, models, registry, options });
|
|
1964
2364
|
const operations = createOperations(models, coordinate, registry, options);
|
|
1965
2365
|
const wrappedOperations = Library3.wrapOperations(operations, options, coordinate, registry);
|
|
1966
2366
|
const libLibrary = Library3.createLibrary(registry, coordinate, wrappedOperations, options);
|
|
@@ -1974,10 +2374,10 @@ var isSequelizeLibrary = (library) => {
|
|
|
1974
2374
|
};
|
|
1975
2375
|
|
|
1976
2376
|
// src/SequelizeLibraryFactory.ts
|
|
1977
|
-
var
|
|
2377
|
+
var logger17 = logger_default.get("InstanceFactory");
|
|
1978
2378
|
var createSequelizeLibraryFactory = (models, options) => {
|
|
1979
2379
|
return (coordinate, context) => {
|
|
1980
|
-
|
|
2380
|
+
logger17.debug("Creating Sequelize instance", {
|
|
1981
2381
|
coordinate,
|
|
1982
2382
|
registry: context.registry,
|
|
1983
2383
|
models: models.map((m) => m.name),
|
|
@@ -2022,9 +2422,9 @@ __export(primary_exports, {
|
|
|
2022
2422
|
|
|
2023
2423
|
// src/primary/SequelizeLibrary.ts
|
|
2024
2424
|
import { Primary } from "@fjell/lib";
|
|
2025
|
-
var
|
|
2425
|
+
var logger18 = logger_default.get("lib-sequelize", "primary", "library");
|
|
2026
2426
|
function createSequelizeLibrary3(keyType, models, libOptions = {}, scopes = [], registry) {
|
|
2027
|
-
|
|
2427
|
+
logger18.debug("createSequelizeLibrary", { keyType, models, libOptions, scopes });
|
|
2028
2428
|
const coordinate = createCoordinate([keyType], scopes);
|
|
2029
2429
|
const options = createOptions2(libOptions);
|
|
2030
2430
|
const operations = createOperations(models, coordinate, registry, options);
|