@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.
@@ -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;AAQpB,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,CAyCvC,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 libLogger = logger_default.get("processing", "ReferenceBuilder");
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
- libLogger.debug(
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
- libLogger.warning(
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
- itemKey = {
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 (!itemKey) {
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
- libLogger.debug("Built full ComKey with location context", {
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
- libLogger.debug("Using empty loc array for composite item reference", {
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
- libLogger.debug("Created reference key", {
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
- libLogger.debug("Using cached reference", { itemKey, property: referenceDefinition.property });
676
+ libLogger2.debug("Using cached reference", { itemKey, property: referenceDefinition.property });
674
677
  referencedItem = context.getCached(itemKey);
675
678
  } else if (context.isInProgress(itemKey)) {
676
- libLogger.debug("Circular dependency detected, creating reference placeholder", {
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
- for (const referenceDefinition of referenceDefinitions) {
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
- item = await buildSequelizeReference(item, referenceDefinition, registry, operationContext);
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
- logger7.default(`All query configured for ${model.name} with where fields: ${options.where ? Object.keys(options.where).join(", ") : "none"}, includes: ${options.include?.length || 0}`);
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 results = await Promise.all(matchingItems.map(async (row) => {
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 ${results.length} ${model.name} records`);
1039
- return results;
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 isComKey2, isPriKey as isPriKey2 } from "@fjell/core";
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=[${isComKey2(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";
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 (isPriKey2(key)) {
1260
+ if (isPriKey3(key)) {
1112
1261
  itemData.id = key.pk;
1113
- } else if (isComKey2(key)) {
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 && finders[finder]) {
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 isComKey3,
1240
- isPriKey as isPriKey3,
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 = isPriKey3(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
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 ${isPriKey3(key) ? "primary" : "composite"} key`);
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 (isPriKey3(itemKey)) {
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 (isComKey3(itemKey)) {
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 items = await getAllOperation(models, definition, registry)(itemQuery ?? {}, locs);
1335
- if (items.length > 0) {
1336
- const result = items[0];
1337
- logger11.debug(`[ONE] Found ${models[0].name} record with key: ${result.key ? JSON.stringify(result.key) : "unknown"}`);
1338
- return result;
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 isComKey4, isPriKey as isPriKey4, isValidItemKey as isValidItemKey2, createRemoveWrapper } from "@fjell/core";
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 = isPriKey4(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
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 ${isPriKey4(key) ? "primary" : "composite"} key`);
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 (isPriKey4(key)) {
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 (isComKey4(key)) {
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 isComKey5,
1450
- isPriKey as isPriKey5
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 = isPriKey5(key) ? `primary key: pk=${key.pk}` : `composite key: pk=${key.pk}, loc=[${key.loc.map((l) => `${l.kt}=${l.lk}`).join(", ")}]`;
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 (isPriKey5(key)) {
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 (isComKey5(key)) {
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
- resultItem = await create(item, { key });
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;