@fjell/lib-sequelize 4.4.68 → 4.4.70
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/RowProcessor.d.ts.map +1 -1
- package/dist/index.js +242 -70
- package/dist/index.js.map +4 -4
- package/dist/ops/all.d.ts.map +1 -1
- package/dist/ops/create.d.ts.map +1 -1
- package/dist/ops/find.d.ts.map +1 -1
- package/dist/ops/remove.d.ts.map +1 -1
- package/dist/ops/update.d.ts.map +1 -1
- package/dist/ops/upsert.d.ts.map +1 -1
- package/dist/processing/ReferenceBuilder.d.ts.map +1 -1
- package/dist/processing/RefsAdapter.d.ts +80 -0
- package/dist/processing/RefsAdapter.d.ts.map +1 -0
- package/dist/processing/index.d.ts +2 -0
- package/dist/processing/index.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RowProcessor.d.ts","sourceRoot":"","sources":["../src/RowProcessor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,KAAK,OAAO,MAAM,YAAY,CAAC;AACtC,OAAO,EAEL,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"RowProcessor.d.ts","sourceRoot":"","sources":["../src/RowProcessor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,KAAK,OAAO,MAAM,YAAY,CAAC;AACtC,OAAO,EAEL,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AASpB,YAAY,EAAE,gBAAgB,EAAE,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,CAAC;AAElD,eAAO,MAAM,UAAU,GAAU,CAAC,SAAS,MAAM,EAC/C,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACvB,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EACpB,UAAU,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAClD,sBAAsB,4BAA4B,EAAE,EACpD,wBAAwB,qBAAqB,EAAE,EAC/C,UAAU,OAAO,CAAC,QAAQ,EAC1B,UAAU,gBAAgB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CA8DvC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -580,11 +580,11 @@ var removeEvents = (item) => {
|
|
|
580
580
|
|
|
581
581
|
// src/processing/ReferenceBuilder.ts
|
|
582
582
|
var buildSequelizeReference = async (item, referenceDefinition, registry, context) => {
|
|
583
|
-
const
|
|
583
|
+
const libLogger2 = logger_default.get("processing", "ReferenceBuilder");
|
|
584
584
|
const isCompositeItem = referenceDefinition.kta.length > 1;
|
|
585
585
|
const primaryKeyType = referenceDefinition.kta[0];
|
|
586
586
|
if (isCompositeItem) {
|
|
587
|
-
|
|
587
|
+
libLogger2.debug(
|
|
588
588
|
"Detected composite item reference - will use ComKey with empty loc array",
|
|
589
589
|
{
|
|
590
590
|
kta: referenceDefinition.kta,
|
|
@@ -619,18 +619,15 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
619
619
|
} else if (referenceDefinition.locationColumns && referenceDefinition.locationColumns.length > 0) {
|
|
620
620
|
const locationTypes = referenceDefinition.kta.slice(1);
|
|
621
621
|
const loc = [];
|
|
622
|
+
let hasNullLocation = false;
|
|
622
623
|
for (let i = 0; i < referenceDefinition.locationColumns.length; i++) {
|
|
623
624
|
const columnName = referenceDefinition.locationColumns[i];
|
|
624
625
|
const locValue = item[columnName];
|
|
625
626
|
if (locValue == null) {
|
|
626
|
-
|
|
627
|
+
libLogger2.warning(
|
|
627
628
|
`Location column '${columnName}' is null/undefined for reference '${referenceDefinition.property}'. Falling back to empty loc array search.`
|
|
628
629
|
);
|
|
629
|
-
|
|
630
|
-
kt: primaryKeyType,
|
|
631
|
-
pk: columnValue,
|
|
632
|
-
loc: []
|
|
633
|
-
};
|
|
630
|
+
hasNullLocation = true;
|
|
634
631
|
break;
|
|
635
632
|
}
|
|
636
633
|
loc.push({
|
|
@@ -638,13 +635,19 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
638
635
|
lk: locValue
|
|
639
636
|
});
|
|
640
637
|
}
|
|
641
|
-
if (
|
|
638
|
+
if (hasNullLocation) {
|
|
639
|
+
itemKey = {
|
|
640
|
+
kt: primaryKeyType,
|
|
641
|
+
pk: columnValue,
|
|
642
|
+
loc: []
|
|
643
|
+
};
|
|
644
|
+
} else {
|
|
642
645
|
itemKey = {
|
|
643
646
|
kt: primaryKeyType,
|
|
644
647
|
pk: columnValue,
|
|
645
648
|
loc
|
|
646
649
|
};
|
|
647
|
-
|
|
650
|
+
libLogger2.debug("Built full ComKey with location context", {
|
|
648
651
|
itemKey,
|
|
649
652
|
locationColumns: referenceDefinition.locationColumns,
|
|
650
653
|
property: referenceDefinition.property
|
|
@@ -656,12 +659,12 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
656
659
|
pk: columnValue,
|
|
657
660
|
loc: []
|
|
658
661
|
};
|
|
659
|
-
|
|
662
|
+
libLogger2.debug("Using empty loc array for composite item reference", {
|
|
660
663
|
kta: referenceDefinition.kta,
|
|
661
664
|
property: referenceDefinition.property
|
|
662
665
|
});
|
|
663
666
|
}
|
|
664
|
-
|
|
667
|
+
libLogger2.debug("Created reference key", {
|
|
665
668
|
itemKey,
|
|
666
669
|
isCompositeItem,
|
|
667
670
|
hasLocationColumns: !!referenceDefinition.locationColumns,
|
|
@@ -670,10 +673,10 @@ var buildSequelizeReference = async (item, referenceDefinition, registry, contex
|
|
|
670
673
|
let referencedItem;
|
|
671
674
|
if (context) {
|
|
672
675
|
if (context.isCached(itemKey)) {
|
|
673
|
-
|
|
676
|
+
libLogger2.debug("Using cached reference", { itemKey, property: referenceDefinition.property });
|
|
674
677
|
referencedItem = context.getCached(itemKey);
|
|
675
678
|
} else if (context.isInProgress(itemKey)) {
|
|
676
|
-
|
|
679
|
+
libLogger2.debug("Circular dependency detected, creating reference placeholder", {
|
|
677
680
|
itemKey,
|
|
678
681
|
property: referenceDefinition.property
|
|
679
682
|
});
|
|
@@ -707,6 +710,107 @@ var stripSequelizeReferenceItems = (item, referenceDefinitions) => {
|
|
|
707
710
|
return result;
|
|
708
711
|
};
|
|
709
712
|
|
|
713
|
+
// src/processing/RefsAdapter.ts
|
|
714
|
+
import { isComKey as isComKey2, isPriKey as isPriKey2 } from "@fjell/core";
|
|
715
|
+
var libLogger = logger_default.get("sequelize", "processing", "RefsAdapter");
|
|
716
|
+
function buildKeyFromForeignKey(refDef, foreignKeyValue, item) {
|
|
717
|
+
const primaryKeyType = refDef.kta[0];
|
|
718
|
+
const isCompositeItem = refDef.kta.length > 1;
|
|
719
|
+
if (!isCompositeItem) {
|
|
720
|
+
return {
|
|
721
|
+
kt: primaryKeyType,
|
|
722
|
+
pk: foreignKeyValue
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
const loc = [];
|
|
726
|
+
if (refDef.locationColumns && refDef.locationColumns.length > 0) {
|
|
727
|
+
for (let i = 0; i < refDef.locationColumns.length; i++) {
|
|
728
|
+
const columnName = refDef.locationColumns[i];
|
|
729
|
+
const locValue = item[columnName];
|
|
730
|
+
if (locValue != null) {
|
|
731
|
+
const locationType = refDef.kta[i + 1];
|
|
732
|
+
loc.push({
|
|
733
|
+
kt: locationType,
|
|
734
|
+
lk: locValue
|
|
735
|
+
});
|
|
736
|
+
} else {
|
|
737
|
+
libLogger.debug(
|
|
738
|
+
`Location column '${columnName}' is null/undefined for reference '${refDef.property}'. Using empty loc array.`
|
|
739
|
+
);
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return {
|
|
745
|
+
kt: primaryKeyType,
|
|
746
|
+
pk: foreignKeyValue,
|
|
747
|
+
loc: loc.length > 0 ? loc : []
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function addRefsToSequelizeItem(item, referenceDefinitions) {
|
|
751
|
+
const refs = {};
|
|
752
|
+
for (const refDef of referenceDefinitions) {
|
|
753
|
+
const foreignKeyValue = item[refDef.column];
|
|
754
|
+
const refName = refDef.property;
|
|
755
|
+
if (foreignKeyValue != null) {
|
|
756
|
+
const key = buildKeyFromForeignKey(refDef, foreignKeyValue, item);
|
|
757
|
+
const populatedItem = item[refDef.property];
|
|
758
|
+
refs[refName] = {
|
|
759
|
+
key,
|
|
760
|
+
item: populatedItem
|
|
761
|
+
};
|
|
762
|
+
} else {
|
|
763
|
+
refs[refName] = {
|
|
764
|
+
key: {
|
|
765
|
+
kt: refDef.kta[0],
|
|
766
|
+
pk: null
|
|
767
|
+
// Will be handled as null reference
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return {
|
|
773
|
+
...item,
|
|
774
|
+
refs
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function updateForeignKeysFromRefs(item, refs, referenceDefinitions) {
|
|
778
|
+
for (const refDef of referenceDefinitions) {
|
|
779
|
+
const refName = refDef.property;
|
|
780
|
+
const ref = refs[refName];
|
|
781
|
+
if (ref && ref.key) {
|
|
782
|
+
if (isPriKey2(ref.key)) {
|
|
783
|
+
item[refDef.column] = ref.key.pk;
|
|
784
|
+
} else if (isComKey2(ref.key)) {
|
|
785
|
+
item[refDef.column] = ref.key.pk;
|
|
786
|
+
if (refDef.locationColumns && ref.key.loc) {
|
|
787
|
+
ref.key.loc.forEach((locItem, index) => {
|
|
788
|
+
if (refDef.locationColumns && refDef.locationColumns[index]) {
|
|
789
|
+
item[refDef.locationColumns[index]] = locItem.lk;
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
if (ref.item) {
|
|
795
|
+
item[refDef.property] = ref.item;
|
|
796
|
+
}
|
|
797
|
+
} else if (ref == null) {
|
|
798
|
+
if (refName in refs) {
|
|
799
|
+
item[refDef.column] = null;
|
|
800
|
+
delete item[refDef.property];
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
function removeRefsFromSequelizeItem(item, referenceDefinitions) {
|
|
806
|
+
const result = { ...item };
|
|
807
|
+
if (result.refs) {
|
|
808
|
+
updateForeignKeysFromRefs(result, result.refs, referenceDefinitions);
|
|
809
|
+
delete result.refs;
|
|
810
|
+
}
|
|
811
|
+
return result;
|
|
812
|
+
}
|
|
813
|
+
|
|
710
814
|
// src/RowProcessor.ts
|
|
711
815
|
var logger6 = logger_default.get("sequelize", "RowProcessor");
|
|
712
816
|
var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefinitions, registry, context) => {
|
|
@@ -721,9 +825,15 @@ var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefiniti
|
|
|
721
825
|
operationContext.markInProgress(item.key);
|
|
722
826
|
try {
|
|
723
827
|
if (referenceDefinitions && referenceDefinitions.length > 0) {
|
|
724
|
-
|
|
828
|
+
const referenceStartTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
829
|
+
const referencePromises = referenceDefinitions.map((referenceDefinition) => {
|
|
725
830
|
logger6.default("Processing Reference for %s to %s", item.key.kt, stringifyJSON(referenceDefinition.kta));
|
|
726
|
-
|
|
831
|
+
return buildSequelizeReference(item, referenceDefinition, registry, operationContext);
|
|
832
|
+
});
|
|
833
|
+
await Promise.all(referencePromises);
|
|
834
|
+
const referenceDuration = (typeof performance !== "undefined" ? performance.now() : Date.now()) - referenceStartTime;
|
|
835
|
+
if (referenceDuration > 100) {
|
|
836
|
+
logger6.info(`\u23F1\uFE0F REFERENCE_BUILDER_PERF: Loaded ${referenceDefinitions.length} references in parallel for ${item.key.kt} - ${referenceDuration.toFixed(2)}ms`);
|
|
727
837
|
}
|
|
728
838
|
}
|
|
729
839
|
if (aggregationDefinitions && aggregationDefinitions.length > 0) {
|
|
@@ -736,6 +846,10 @@ var processRow = async (row, keyTypes, referenceDefinitions, aggregationDefiniti
|
|
|
736
846
|
} finally {
|
|
737
847
|
operationContext.markComplete(item.key);
|
|
738
848
|
}
|
|
849
|
+
if (referenceDefinitions && referenceDefinitions.length > 0) {
|
|
850
|
+
item = addRefsToSequelizeItem(item, referenceDefinitions);
|
|
851
|
+
logger6.debug("Added refs structure to item (transparent wrapper)", { key: item.key });
|
|
852
|
+
}
|
|
739
853
|
logger6.default("Processed Row: %j", stringifyJSON(item));
|
|
740
854
|
return item;
|
|
741
855
|
});
|
|
@@ -958,7 +1072,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
958
1072
|
const { coordinate, options: { references, aggregations } } = definition;
|
|
959
1073
|
return createAllWrapper(
|
|
960
1074
|
coordinate,
|
|
961
|
-
async (itemQuery, locations) => {
|
|
1075
|
+
async (itemQuery, locations, allOptions) => {
|
|
962
1076
|
try {
|
|
963
1077
|
const locs = locations ?? [];
|
|
964
1078
|
logger7.debug(`ALL operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc2) => `${loc2.kt}=${loc2.lk}`).join(", ") || "none"}`);
|
|
@@ -1023,7 +1137,30 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1023
1137
|
options.include = mergeIncludes(existingIncludes, additionalIncludes);
|
|
1024
1138
|
}
|
|
1025
1139
|
}
|
|
1026
|
-
|
|
1140
|
+
const effectiveLimit = allOptions?.limit ?? itemQuery?.limit;
|
|
1141
|
+
const effectiveOffset = allOptions?.offset ?? itemQuery?.offset ?? 0;
|
|
1142
|
+
const whereFields = options.where ? Object.keys(options.where).join(", ") : "none";
|
|
1143
|
+
const includeCount = options.include?.length || 0;
|
|
1144
|
+
logger7.default(
|
|
1145
|
+
`All query configured for ${model.name} with where fields: ${whereFields}, includes: ${includeCount}, limit: ${effectiveLimit}, offset: ${effectiveOffset}`
|
|
1146
|
+
);
|
|
1147
|
+
const countOptions = {
|
|
1148
|
+
where: options.where,
|
|
1149
|
+
distinct: true
|
|
1150
|
+
};
|
|
1151
|
+
if (options.include) {
|
|
1152
|
+
countOptions.include = options.include;
|
|
1153
|
+
}
|
|
1154
|
+
const total = await model.count(countOptions);
|
|
1155
|
+
logger7.debug(`[ALL] Total count for ${model.name}: ${total}`);
|
|
1156
|
+
delete options.limit;
|
|
1157
|
+
delete options.offset;
|
|
1158
|
+
if (effectiveLimit !== void 0) {
|
|
1159
|
+
options.limit = effectiveLimit;
|
|
1160
|
+
}
|
|
1161
|
+
if (effectiveOffset > 0) {
|
|
1162
|
+
options.offset = effectiveOffset;
|
|
1163
|
+
}
|
|
1027
1164
|
try {
|
|
1028
1165
|
logger7.trace(`[ALL] Executing ${model.name}.findAll() with options: ${JSON.stringify(options, null, 2)}`);
|
|
1029
1166
|
} catch {
|
|
@@ -1031,12 +1168,21 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1031
1168
|
}
|
|
1032
1169
|
const matchingItems = await model.findAll(options);
|
|
1033
1170
|
const currentContext = contextManager.getCurrentContext();
|
|
1034
|
-
const
|
|
1171
|
+
const items = await Promise.all(matchingItems.map(async (row) => {
|
|
1035
1172
|
const processedRow = await processRow(row, coordinate.kta, references || [], aggregations || [], registry, currentContext);
|
|
1036
1173
|
return validateKeys(processedRow, coordinate.kta);
|
|
1037
1174
|
}));
|
|
1038
|
-
logger7.debug(`[ALL] Returning ${
|
|
1039
|
-
return
|
|
1175
|
+
logger7.debug(`[ALL] Returning ${items.length} of ${total} ${model.name} records`);
|
|
1176
|
+
return {
|
|
1177
|
+
items,
|
|
1178
|
+
metadata: {
|
|
1179
|
+
total,
|
|
1180
|
+
returned: items.length,
|
|
1181
|
+
limit: effectiveLimit,
|
|
1182
|
+
offset: effectiveOffset,
|
|
1183
|
+
hasMore: effectiveOffset + items.length < total
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1040
1186
|
} catch (error) {
|
|
1041
1187
|
throw transformSequelizeError(error, coordinate.kta[0]);
|
|
1042
1188
|
}
|
|
@@ -1045,7 +1191,7 @@ var getAllOperation = (models, definition, registry) => {
|
|
|
1045
1191
|
};
|
|
1046
1192
|
|
|
1047
1193
|
// src/ops/create.ts
|
|
1048
|
-
import { createCreateWrapper, isComKey as
|
|
1194
|
+
import { createCreateWrapper, isComKey as isComKey3, isPriKey as isPriKey3 } from "@fjell/core";
|
|
1049
1195
|
import { validateKeys as validateKeys2 } from "@fjell/core/validation";
|
|
1050
1196
|
var logger8 = logger_default.get("sequelize", "ops", "create");
|
|
1051
1197
|
async function validateHierarchicalChain(models, locKey, kta) {
|
|
@@ -1086,7 +1232,7 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1086
1232
|
return createCreateWrapper(
|
|
1087
1233
|
coordinate,
|
|
1088
1234
|
async (item, options) => {
|
|
1089
|
-
const constraints = options?.key ? `key: pk=${options.key.pk}, loc=[${
|
|
1235
|
+
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";
|
|
1090
1236
|
logger8.debug(`CREATE operation called on ${models[0].name} with ${constraints}`);
|
|
1091
1237
|
logger8.default(`Create configured for ${models[0].name} with ${Object.keys(item).length} item fields`);
|
|
1092
1238
|
const model = models[0];
|
|
@@ -1094,6 +1240,9 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1094
1240
|
let itemData = { ...item };
|
|
1095
1241
|
itemData = extractEvents(itemData);
|
|
1096
1242
|
itemData = removeEvents(itemData);
|
|
1243
|
+
if (references && references.length > 0) {
|
|
1244
|
+
itemData = removeRefsFromSequelizeItem(itemData, references);
|
|
1245
|
+
}
|
|
1097
1246
|
const invalidAttributes = [];
|
|
1098
1247
|
for (const key of Object.keys(itemData)) {
|
|
1099
1248
|
if (!modelAttributes[key]) {
|
|
@@ -1108,9 +1257,9 @@ var getCreateOperation = (models, definition, registry) => {
|
|
|
1108
1257
|
}
|
|
1109
1258
|
if (options?.key) {
|
|
1110
1259
|
const key = options.key;
|
|
1111
|
-
if (
|
|
1260
|
+
if (isPriKey3(key)) {
|
|
1112
1261
|
itemData.id = key.pk;
|
|
1113
|
-
} else if (
|
|
1262
|
+
} else if (isComKey3(key)) {
|
|
1114
1263
|
itemData.id = key.pk;
|
|
1115
1264
|
const comKey = key;
|
|
1116
1265
|
const directLocations = [];
|
|
@@ -1193,7 +1342,7 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1193
1342
|
const { options: { finders, references, aggregations } } = definition;
|
|
1194
1343
|
return createFindWrapper(
|
|
1195
1344
|
definition.coordinate,
|
|
1196
|
-
async (finder, finderParams, locations) => {
|
|
1345
|
+
async (finder, finderParams, locations, findOptions) => {
|
|
1197
1346
|
try {
|
|
1198
1347
|
const locs = locations ?? [];
|
|
1199
1348
|
const params = finderParams ?? {};
|
|
@@ -1202,30 +1351,45 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1202
1351
|
`FIND operation called on ${models[0].name} with finder '${finder}' and ${locs.length} location filters: ${locationFilters}`
|
|
1203
1352
|
);
|
|
1204
1353
|
logger9.default(`Find configured for ${models[0].name} using finder '${finder}' with ${Object.keys(params).length} params`);
|
|
1205
|
-
if (finders
|
|
1206
|
-
const finderMethod = finders[finder];
|
|
1207
|
-
if (finderMethod) {
|
|
1208
|
-
logger9.trace(`[FIND] Executing finder '${finder}' on ${models[0].name} with params: ${stringifyJSON(params)}, locations: ${stringifyJSON(locs)}`);
|
|
1209
|
-
const results = await finderMethod(params, locs);
|
|
1210
|
-
if (results && results.length > 0) {
|
|
1211
|
-
const processedResults = await Promise.all(results.map(async (row) => {
|
|
1212
|
-
const processedRow = await processRow(row, definition.coordinate.kta, references || [], aggregations || [], registry);
|
|
1213
|
-
return validateKeys3(processedRow, definition.coordinate.kta);
|
|
1214
|
-
}));
|
|
1215
|
-
logger9.debug(`[FIND] Found ${processedResults.length} ${models[0].name} records using finder '${finder}'`);
|
|
1216
|
-
return processedResults;
|
|
1217
|
-
} else {
|
|
1218
|
-
logger9.debug(`[FIND] Found 0 ${models[0].name} records using finder '${finder}'`);
|
|
1219
|
-
return [];
|
|
1220
|
-
}
|
|
1221
|
-
} else {
|
|
1222
|
-
logger9.error(`Finder %s not found`, finder);
|
|
1223
|
-
throw new Error(`Finder ${finder} not found`);
|
|
1224
|
-
}
|
|
1225
|
-
} else {
|
|
1354
|
+
if (!finders || !finders[finder]) {
|
|
1226
1355
|
logger9.error(`No finders have been defined for this lib`);
|
|
1227
1356
|
throw new Error(`No finders found`);
|
|
1228
1357
|
}
|
|
1358
|
+
const finderMethod = finders[finder];
|
|
1359
|
+
if (!finderMethod) {
|
|
1360
|
+
logger9.error(`Finder %s not found`, finder);
|
|
1361
|
+
throw new Error(`Finder ${finder} not found`);
|
|
1362
|
+
}
|
|
1363
|
+
logger9.trace(`[FIND] Executing finder '${finder}' on ${models[0].name} with params: ${stringifyJSON(params)}, locations: ${stringifyJSON(locs)}, options: ${stringifyJSON(findOptions)}`);
|
|
1364
|
+
const finderResult = await finderMethod(params, locs, findOptions);
|
|
1365
|
+
const processItems = async (items) => {
|
|
1366
|
+
return await Promise.all(items.map(async (row) => {
|
|
1367
|
+
const processedRow = await processRow(row, definition.coordinate.kta, references || [], aggregations || [], registry);
|
|
1368
|
+
return validateKeys3(processedRow, definition.coordinate.kta);
|
|
1369
|
+
}));
|
|
1370
|
+
};
|
|
1371
|
+
const isOptInResult = finderResult && typeof finderResult === "object" && "items" in finderResult && "metadata" in finderResult;
|
|
1372
|
+
if (isOptInResult) {
|
|
1373
|
+
const optInResult = finderResult;
|
|
1374
|
+
const processedResults2 = optInResult.items && optInResult.items.length > 0 ? await processItems(optInResult.items) : [];
|
|
1375
|
+
logger9.debug(`[FIND] Finder opted-in, found ${processedResults2.length} ${models[0].name} records using finder '${finder}' (total: ${optInResult.metadata.total})`);
|
|
1376
|
+
return {
|
|
1377
|
+
items: processedResults2,
|
|
1378
|
+
metadata: optInResult.metadata
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
const results = finderResult;
|
|
1382
|
+
const processedResults = results && results.length > 0 ? await processItems(results) : [];
|
|
1383
|
+
logger9.debug(`[FIND] Legacy finder, found ${processedResults.length} ${models[0].name} records using finder '${finder}'`);
|
|
1384
|
+
return {
|
|
1385
|
+
items: processedResults,
|
|
1386
|
+
metadata: {
|
|
1387
|
+
total: processedResults.length,
|
|
1388
|
+
returned: processedResults.length,
|
|
1389
|
+
offset: 0,
|
|
1390
|
+
hasMore: false
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1229
1393
|
} catch (error) {
|
|
1230
1394
|
throw transformSequelizeError(error, definition.coordinate.kta[0]);
|
|
1231
1395
|
}
|
|
@@ -1236,8 +1400,8 @@ var getFindOperation = (models, definition, registry) => {
|
|
|
1236
1400
|
// src/ops/get.ts
|
|
1237
1401
|
import {
|
|
1238
1402
|
createGetWrapper,
|
|
1239
|
-
isComKey as
|
|
1240
|
-
isPriKey as
|
|
1403
|
+
isComKey as isComKey4,
|
|
1404
|
+
isPriKey as isPriKey4,
|
|
1241
1405
|
isValidItemKey,
|
|
1242
1406
|
validateKeys as validateKeys4
|
|
1243
1407
|
} from "@fjell/core";
|
|
@@ -1280,16 +1444,16 @@ var getGetOperation = (models, definition, registry) => {
|
|
|
1280
1444
|
logger10.error("Key for Get is not a valid ItemKey: %j", key);
|
|
1281
1445
|
throw new Error("Key for Get is not a valid ItemKey");
|
|
1282
1446
|
}
|
|
1283
|
-
const keyDescription =
|
|
1447
|
+
const keyDescription = isPriKey4(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1284
1448
|
logger10.debug(`GET operation called on ${models[0].name} with ${keyDescription}`);
|
|
1285
|
-
logger10.default(`Get configured for ${models[0].name} with ${
|
|
1449
|
+
logger10.default(`Get configured for ${models[0].name} with ${isPriKey4(key) ? "primary" : "composite"} key`);
|
|
1286
1450
|
const itemKey = key;
|
|
1287
1451
|
const model = models[0];
|
|
1288
1452
|
let item;
|
|
1289
|
-
if (
|
|
1453
|
+
if (isPriKey4(itemKey)) {
|
|
1290
1454
|
logger10.trace(`[GET] Executing ${model.name}.findByPk() with pk: ${itemKey.pk}`);
|
|
1291
1455
|
item = await model.findByPk(itemKey.pk);
|
|
1292
|
-
} else if (
|
|
1456
|
+
} else if (isComKey4(itemKey)) {
|
|
1293
1457
|
const comKey = itemKey;
|
|
1294
1458
|
if (comKey.loc.length === 0) {
|
|
1295
1459
|
logger10.debug(`[GET] Empty loc array detected - finding by primary key across all locations: ${comKey.pk}`);
|
|
@@ -1331,11 +1495,11 @@ var getOneOperation = (models, definition, registry) => {
|
|
|
1331
1495
|
const locs = locations ?? [];
|
|
1332
1496
|
logger11.debug(`ONE operation called on ${models[0].name} with ${locs.length} location filters: ${locs.map((loc) => `${loc.kt}=${loc.lk}`).join(", ") || "none"}`);
|
|
1333
1497
|
logger11.default(`One configured for ${models[0].name} delegating to all operation`);
|
|
1334
|
-
const
|
|
1335
|
-
if (items.length > 0) {
|
|
1336
|
-
const
|
|
1337
|
-
logger11.debug(`[ONE] Found ${models[0].name} record with key: ${
|
|
1338
|
-
return
|
|
1498
|
+
const result = await getAllOperation(models, definition, registry)(itemQuery ?? {}, locs, { limit: 1 });
|
|
1499
|
+
if (result.items.length > 0) {
|
|
1500
|
+
const item = result.items[0];
|
|
1501
|
+
logger11.debug(`[ONE] Found ${models[0].name} record with key: ${item.key ? JSON.stringify(item.key) : "unknown"}`);
|
|
1502
|
+
return item;
|
|
1339
1503
|
} else {
|
|
1340
1504
|
logger11.debug(`[ONE] No ${models[0].name} record found`);
|
|
1341
1505
|
return null;
|
|
@@ -1345,7 +1509,7 @@ var getOneOperation = (models, definition, registry) => {
|
|
|
1345
1509
|
};
|
|
1346
1510
|
|
|
1347
1511
|
// src/ops/remove.ts
|
|
1348
|
-
import { abbrevIK, isComKey as
|
|
1512
|
+
import { abbrevIK, isComKey as isComKey5, isPriKey as isPriKey5, isValidItemKey as isValidItemKey2, createRemoveWrapper } from "@fjell/core";
|
|
1349
1513
|
import { NotFoundError as NotFoundError2 } from "@fjell/core";
|
|
1350
1514
|
var logger12 = logger_default.get("sequelize", "ops", "remove");
|
|
1351
1515
|
var processCompositeKey2 = (comKey, model, kta) => {
|
|
@@ -1385,17 +1549,17 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1385
1549
|
logger12.error("Key for Remove is not a valid ItemKey: %j", key);
|
|
1386
1550
|
throw new Error("Key for Remove is not a valid ItemKey");
|
|
1387
1551
|
}
|
|
1388
|
-
const keyDescription =
|
|
1552
|
+
const keyDescription = isPriKey5(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1389
1553
|
logger12.debug(`REMOVE operation called on ${models[0].name} with ${keyDescription}`);
|
|
1390
|
-
logger12.default(`Remove configured for ${models[0].name} with ${
|
|
1554
|
+
logger12.default(`Remove configured for ${models[0].name} with ${isPriKey5(key) ? "primary" : "composite"} key`);
|
|
1391
1555
|
const model = models[0];
|
|
1392
1556
|
let item;
|
|
1393
1557
|
let returnItem;
|
|
1394
1558
|
logger12.debug("remove: %s", abbrevIK(key));
|
|
1395
|
-
if (
|
|
1559
|
+
if (isPriKey5(key)) {
|
|
1396
1560
|
logger12.debug(`[REMOVE] Executing ${model.name}.findByPk() with pk: ${key.pk}`);
|
|
1397
1561
|
item = await model.findByPk(key.pk);
|
|
1398
|
-
} else if (
|
|
1562
|
+
} else if (isComKey5(key)) {
|
|
1399
1563
|
const comKey = key;
|
|
1400
1564
|
const queryOptions = processCompositeKey2(comKey, model, kta);
|
|
1401
1565
|
logger12.default(`Remove composite key query for ${model.name} with where fields: ${queryOptions.where ? Object.keys(queryOptions.where).join(", ") : "none"}`);
|
|
@@ -1433,6 +1597,10 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1433
1597
|
throw new Error("No deletedAt or isDeleted attribute found in model, and deleteOnRemove is not set");
|
|
1434
1598
|
}
|
|
1435
1599
|
logger12.debug(`[REMOVE] Removed ${model.name} with key: ${returnItem.key ? JSON.stringify(returnItem.key) : `id=${item.id}`}`);
|
|
1600
|
+
const { references } = options;
|
|
1601
|
+
if (references && references.length > 0) {
|
|
1602
|
+
returnItem = addRefsToSequelizeItem(returnItem, references);
|
|
1603
|
+
}
|
|
1436
1604
|
return returnItem;
|
|
1437
1605
|
} catch (error) {
|
|
1438
1606
|
if (error instanceof NotFoundError2) throw error;
|
|
@@ -1446,8 +1614,8 @@ var getRemoveOperation = (models, definition, _registry) => {
|
|
|
1446
1614
|
import {
|
|
1447
1615
|
abbrevIK as abbrevIK2,
|
|
1448
1616
|
createUpdateWrapper,
|
|
1449
|
-
isComKey as
|
|
1450
|
-
isPriKey as
|
|
1617
|
+
isComKey as isComKey6,
|
|
1618
|
+
isPriKey as isPriKey6
|
|
1451
1619
|
} from "@fjell/core";
|
|
1452
1620
|
import { validateKeys as validateKeys5 } from "@fjell/core/validation";
|
|
1453
1621
|
import { NotFoundError as NotFoundError3 } from "@fjell/core";
|
|
@@ -1483,18 +1651,18 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1483
1651
|
"UpdateOptions.replace is not supported for SQL databases. SQL UPDATE operations are always partial (they only update specified fields). To replace an entire record, use remove() followed by create(), or explicitly set all fields you want to change/clear."
|
|
1484
1652
|
);
|
|
1485
1653
|
}
|
|
1486
|
-
const keyDescription =
|
|
1654
|
+
const keyDescription = isPriKey6(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
|
|
1487
1655
|
logger13.debug(`UPDATE operation called on ${models[0].name} with ${keyDescription}`, { options });
|
|
1488
1656
|
const { coordinate } = definition;
|
|
1489
1657
|
const { kta } = coordinate;
|
|
1490
1658
|
logger13.debug("update: %s, %j", abbrevIK2(key), item);
|
|
1491
1659
|
const model = models[0];
|
|
1492
1660
|
let response;
|
|
1493
|
-
if (
|
|
1661
|
+
if (isPriKey6(key)) {
|
|
1494
1662
|
const priKey = key;
|
|
1495
1663
|
logger13.trace(`[UPDATE] Executing ${model.name}.findByPk() with pk: ${priKey.pk}`);
|
|
1496
1664
|
response = await model.findByPk(priKey.pk);
|
|
1497
|
-
} else if (
|
|
1665
|
+
} else if (isComKey6(key)) {
|
|
1498
1666
|
const comKey = key;
|
|
1499
1667
|
const where = { id: comKey.pk };
|
|
1500
1668
|
const additionalIncludes = [];
|
|
@@ -1535,6 +1703,9 @@ var getUpdateOperation = (models, definition, registry) => {
|
|
|
1535
1703
|
let updateProps = removeKey(item);
|
|
1536
1704
|
updateProps = extractEvents(updateProps);
|
|
1537
1705
|
updateProps = removeEvents(updateProps);
|
|
1706
|
+
if (references && references.length > 0) {
|
|
1707
|
+
updateProps = removeRefsFromSequelizeItem(updateProps, references);
|
|
1708
|
+
}
|
|
1538
1709
|
logger13.default(`Update found ${model.name} record to modify`);
|
|
1539
1710
|
logger13.default(`Update properties configured: ${Object.keys(updateProps).join(", ")}`);
|
|
1540
1711
|
logger13.trace(`[UPDATE] Executing ${model.name}.update() with properties: ${stringifyJSON(updateProps)}`);
|
|
@@ -1560,7 +1731,7 @@ var getUpsertOperation = (models, definition, registry) => {
|
|
|
1560
1731
|
const create = getCreateOperation(models, definition, registry);
|
|
1561
1732
|
return createUpsertWrapper(
|
|
1562
1733
|
definition.coordinate,
|
|
1563
|
-
async (key, item, options) => {
|
|
1734
|
+
async (key, item, locations, options) => {
|
|
1564
1735
|
if (!isValidItemKey3(key)) {
|
|
1565
1736
|
logger14.error("Key for Upsert is not a valid ItemKey: %j", key);
|
|
1566
1737
|
throw new Error(`Key for Upsert is not a valid ItemKey: ${stringifyJSON(key)}`);
|
|
@@ -1574,7 +1745,8 @@ var getUpsertOperation = (models, definition, registry) => {
|
|
|
1574
1745
|
const isNotFound = error instanceof NotFoundError4 || error?.name === "NotFoundError" || error?.errorInfo?.code === "NOT_FOUND";
|
|
1575
1746
|
if (isNotFound) {
|
|
1576
1747
|
logger14.debug(`[UPSERT] Item not found, creating new item with key: ${stringifyJSON(key)}, errorType: ${error?.name}, errorCode: ${error?.errorInfo?.code}`);
|
|
1577
|
-
|
|
1748
|
+
const createOptions3 = locations ? { locations } : { key };
|
|
1749
|
+
resultItem = await create(item, createOptions3);
|
|
1578
1750
|
} else {
|
|
1579
1751
|
logger14.error(`[UPSERT] Unexpected error during get operation`, { error: error?.message, name: error?.name, code: error?.errorInfo?.code });
|
|
1580
1752
|
throw error;
|