spice-js 2.7.20 → 2.7.22

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.
@@ -494,7 +494,7 @@ class SpiceModel {
494
494
  args = {};
495
495
  }
496
496
  if (_.isString(args.id)) {
497
- var _args9;
497
+ var _args9, _results, _results2, _results3, _results4, _results5, _results6;
498
498
  if (args.skip_hooks !== true) {
499
499
  yield _this4.run_hook(args, "get", "before");
500
500
  }
@@ -568,13 +568,16 @@ class SpiceModel {
568
568
  });
569
569
  }
570
570
  }
571
- if (results.type !== undefined && results.type !== _this4.type) {
571
+ if (!results) {
572
+ results = {};
573
+ }
574
+ if (((_results = results) == null ? void 0 : _results.type) !== undefined && ((_results2 = results) == null ? void 0 : _results2.type) !== _this4.type) {
572
575
  throw new Error(_this4.type + " does not exist type");
573
576
  }
574
- if (results._type !== undefined && results._type !== _this4.type) {
577
+ if (((_results3 = results) == null ? void 0 : _results3._type) !== undefined && ((_results4 = results) == null ? void 0 : _results4._type) !== _this4.type) {
575
578
  throw new Error(_this4.type + " does not exist _type");
576
579
  }
577
- if (results.deleted === undefined || results.deleted === false) {
580
+ if (((_results5 = results) == null ? void 0 : _results5.deleted) === undefined || ((_results6 = results) == null ? void 0 : _results6.deleted) === false) {
578
581
  if (args.skip_read_serialize !== true && args.skip_serialize !== true) {
579
582
  // ⚡ Pass columns to do_serialize so it can skip irrelevant modifiers
580
583
  results = yield _this4.do_serialize(results, "read", {}, args, yield _this4.propsToBeRemoved(results));
@@ -1033,33 +1036,65 @@ class SpiceModel {
1033
1036
  }
1034
1037
  filterResultsByColumns(data, columns) {
1035
1038
  if (columns && columns !== "") {
1036
- // Remove backticks and replace meta().id with id
1037
1039
  var cleanedColumns = columns.replace(/`/g, "").replace(/meta\(\)\.id/g, "id");
1038
-
1039
- // Process each column by splitting on comma and trimming
1040
- var columnList = cleanedColumns.split(",").map(col => col.trim()).map(col => {
1041
- // Check for alias with AS (case-insensitive)
1040
+ var columnPaths = cleanedColumns.split(",").map(col => col.trim()).map(col => {
1042
1041
  var aliasMatch = col.match(/\s+AS\s+([\w]+)/i);
1043
1042
  if (aliasMatch) {
1044
- return aliasMatch[1].trim();
1045
- }
1046
- // Otherwise, for dot-notation, keep the first segment after removing
1047
- // the base model prefix (e.g. user.group.name -> group).
1048
- if (col.includes(".")) {
1049
- var pathParts = col.split(".").map(part => part.trim()).filter(part => part !== "");
1050
- if (pathParts[0] === this.type && pathParts.length > 1) {
1051
- pathParts = pathParts.slice(1);
1052
- }
1053
- return pathParts[0];
1043
+ return {
1044
+ original: col,
1045
+ path: col.replace(/\s+AS\s+[\w]+/i, "").trim(),
1046
+ alias: aliasMatch[1].trim()
1047
+ };
1054
1048
  }
1055
- return col;
1049
+ return {
1050
+ original: col,
1051
+ path: col,
1052
+ alias: null
1053
+ };
1056
1054
  });
1057
-
1058
- // Ensure that essential keys are always picked
1059
1055
  var requiredKeys = ["_permissions", "_permissions_", "id"];
1060
- var finalKeys = [...new Set([...columnList, ...requiredKeys])];
1061
- return data.map(entry => _.pick(entry, finalKeys));
1056
+ return data.map(entry => {
1057
+ var result = {};
1058
+
1059
+ // Add required keys
1060
+ requiredKeys.forEach(key => {
1061
+ if (entry.hasOwnProperty(key)) {
1062
+ result[key] = entry[key];
1063
+ }
1064
+ });
1065
+
1066
+ // Process each column path
1067
+ columnPaths.forEach(_ref10 => {
1068
+ var {
1069
+ path,
1070
+ alias
1071
+ } = _ref10;
1072
+ var actualPath = path;
1073
+
1074
+ // Remove table prefix if it matches this.type
1075
+ if (path.includes(".")) {
1076
+ var parts = path.split(".");
1077
+ if (parts[0] === this.type) {
1078
+ actualPath = parts.slice(1).join(".");
1079
+ }
1080
+ }
1081
+ var value = _.get(entry, actualPath);
1082
+ if (value !== undefined) {
1083
+ if (alias) {
1084
+ result[alias] = value;
1085
+ } else if (actualPath.includes(".")) {
1086
+ // For nested paths, use the last part as the key
1087
+ var key = actualPath.split(".").pop();
1088
+ result[key] = value;
1089
+ } else {
1090
+ result[actualPath] = value;
1091
+ }
1092
+ }
1093
+ });
1094
+ return result;
1095
+ });
1062
1096
  }
1097
+ console.log("filterResultsByColumns", data);
1063
1098
  return data;
1064
1099
  }
1065
1100
  extractNestings(string, localType) {
@@ -1100,12 +1135,12 @@ class SpiceModel {
1100
1135
  }
1101
1136
  createJoinSection(mappedNestings) {
1102
1137
  if (!mappedNestings || mappedNestings.length === 0) return "";
1103
- return mappedNestings.map(_ref10 => {
1138
+ return mappedNestings.map(_ref11 => {
1104
1139
  var {
1105
1140
  alias,
1106
1141
  reference,
1107
1142
  is_array
1108
- } = _ref10;
1143
+ } = _ref11;
1109
1144
  var keyspace = (0, _fix.fixCollection)(reference);
1110
1145
  if (is_array === true) {
1111
1146
  return "LEFT NEST `" + keyspace + "` AS `" + alias + "` ON KEYS `" + this.type + "`.`" + alias + "`";
@@ -1250,8 +1285,8 @@ class SpiceModel {
1250
1285
  // Profiling: use track() for proper async context forking
1251
1286
  var p = (_this10$_ctx = _this10[_ctx]) == null ? void 0 : _this10$_ctx.profiler;
1252
1287
  var doList = /*#__PURE__*/function () {
1253
- var _ref11 = _asyncToGenerator(function* () {
1254
- var _args10, _args11;
1288
+ var _ref12 = _asyncToGenerator(function* () {
1289
+ var _args10, _args11, _args12;
1255
1290
  if (args.mapping_dept) _this10[_mapping_dept] = args.mapping_dept;
1256
1291
  if (args.mapping_dept_exempt) _this10[_mapping_dept_exempt] = args.mapping_dept_exempt;
1257
1292
 
@@ -1267,15 +1302,12 @@ class SpiceModel {
1267
1302
  var originalColumns = args.columns;
1268
1303
 
1269
1304
  // Find alias tokens from query/columns/sort
1270
- var nestings = [..._this10.extractNestings(((_args10 = args) == null ? void 0 : _args10.query) || "", _this10.type),
1271
- //...this.extractNestings(args?.columns || "", this.type),
1272
- ..._this10.extractNestings(((_args11 = args) == null ? void 0 : _args11.sort) || "", _this10.type)];
1305
+ var nestings = [..._this10.extractNestings(((_args10 = args) == null ? void 0 : _args10.query) || "", _this10.type), ..._this10.extractNestings(((_args11 = args) == null ? void 0 : _args11.columns) || "", _this10.type), ..._this10.extractNestings(((_args12 = args) == null ? void 0 : _args12.sort) || "", _this10.type)];
1273
1306
 
1274
1307
  // Build join metadata and prepare columns
1275
1308
  var {
1276
1309
  mappedNestings
1277
1310
  } = _this10.buildJoinMetadata(nestings, args);
1278
-
1279
1311
  // Build JOIN/NEST from the mapped keyspaces
1280
1312
  args._join = _this10.createJoinSection(mappedNestings);
1281
1313
 
@@ -1325,20 +1357,20 @@ class SpiceModel {
1325
1357
  if (args.skip_hooks !== true) {
1326
1358
  yield _this10.run_hook(results.data, "list", "after");
1327
1359
  }
1328
- results.data = _this10.filterResultsByColumns(results.data, args.columns);
1360
+ results.data = _this10.filterResultsByColumns(results.data, originalColumns);
1329
1361
  //console.log("results.data", results.data);
1330
1362
  return results;
1331
1363
  });
1332
1364
  return function doList() {
1333
- return _ref11.apply(this, arguments);
1365
+ return _ref12.apply(this, arguments);
1334
1366
  };
1335
1367
  }();
1336
1368
  try {
1337
1369
  if (p) {
1338
- var _args12, _args13;
1370
+ var _args13, _args14;
1339
1371
  return yield p.track(_this10.type + ".list", doList, {
1340
- limit: (_args12 = args) == null ? void 0 : _args12.limit,
1341
- offset: (_args13 = args) == null ? void 0 : _args13.offset
1372
+ limit: (_args13 = args) == null ? void 0 : _args13.limit,
1373
+ offset: (_args14 = args) == null ? void 0 : _args14.offset
1342
1374
  });
1343
1375
  }
1344
1376
  return yield doList();
@@ -1384,7 +1416,7 @@ class SpiceModel {
1384
1416
  // Profiling: use track() for proper async context forking
1385
1417
  var p = (_this11$_ctx = _this11[_ctx]) == null ? void 0 : _this11$_ctx.profiler;
1386
1418
  var doFetch = /*#__PURE__*/function () {
1387
- var _ref12 = _asyncToGenerator(function* () {
1419
+ var _ref13 = _asyncToGenerator(function* () {
1388
1420
  if (args.is_custom_query === "true" && args.ids.length > 0) {
1389
1421
  return yield _this11.database.query(query);
1390
1422
  } else if (args.is_full_text === "true") {
@@ -1396,7 +1428,7 @@ class SpiceModel {
1396
1428
  }
1397
1429
  });
1398
1430
  return function doFetch() {
1399
- return _ref12.apply(this, arguments);
1431
+ return _ref13.apply(this, arguments);
1400
1432
  };
1401
1433
  }();
1402
1434
  if (p) {
@@ -1405,12 +1437,12 @@ class SpiceModel {
1405
1437
  return yield doFetch();
1406
1438
  })();
1407
1439
  }
1408
- addHook(_ref13) {
1440
+ addHook(_ref14) {
1409
1441
  var {
1410
1442
  operation,
1411
1443
  when,
1412
1444
  execute
1413
- } = _ref13;
1445
+ } = _ref14;
1414
1446
  this[_hooks][operation][when].push(execute);
1415
1447
  }
1416
1448
  run_hook(data, op, when, old_data) {
@@ -1532,7 +1564,7 @@ class SpiceModel {
1532
1564
 
1533
1565
  // ⚡ Wrap in profiler track() to ensure proper async context for child operations
1534
1566
  var fetchRelated = /*#__PURE__*/function () {
1535
- var _ref14 = _asyncToGenerator(function* () {
1567
+ var _ref15 = _asyncToGenerator(function* () {
1536
1568
  return yield Promise.allSettled(_.map(classes, obj => {
1537
1569
  var objInstance = new obj(_extends({}, _this13[_args], {
1538
1570
  skip_cache: _this13[_skip_cache],
@@ -1550,7 +1582,7 @@ class SpiceModel {
1550
1582
  }));
1551
1583
  });
1552
1584
  return function fetchRelated() {
1553
- return _ref14.apply(this, arguments);
1585
+ return _ref15.apply(this, arguments);
1554
1586
  };
1555
1587
  }();
1556
1588
  var returned_all;
@@ -1650,7 +1682,7 @@ class SpiceModel {
1650
1682
 
1651
1683
  // ⚡ Wrap in profiler track() to ensure proper async context for child operations
1652
1684
  var fetchRelated = /*#__PURE__*/function () {
1653
- var _ref15 = _asyncToGenerator(function* () {
1685
+ var _ref16 = _asyncToGenerator(function* () {
1654
1686
  return yield Promise.allSettled(_.map(classes, obj => {
1655
1687
  return new obj(_extends({}, _this14[_args], {
1656
1688
  skip_cache: _this14[_skip_cache],
@@ -1667,7 +1699,7 @@ class SpiceModel {
1667
1699
  }));
1668
1700
  });
1669
1701
  return function fetchRelated() {
1670
- return _ref15.apply(this, arguments);
1702
+ return _ref16.apply(this, arguments);
1671
1703
  };
1672
1704
  }();
1673
1705
  var returned_all;
@@ -1715,11 +1747,11 @@ class SpiceModel {
1715
1747
  return original_is_array ? data : data[0];
1716
1748
  })();
1717
1749
  }
1718
- addModifier(_ref16) {
1750
+ addModifier(_ref17) {
1719
1751
  var {
1720
1752
  when,
1721
1753
  execute
1722
- } = _ref16;
1754
+ } = _ref17;
1723
1755
  if (this[_serializers][when]) {
1724
1756
  this[_serializers][when]["modifiers"].push(execute);
1725
1757
  }
@@ -1849,7 +1881,7 @@ class SpiceModel {
1849
1881
  // Profiling: use track() for proper async context forking
1850
1882
  var p = (_this16$_ctx = _this16[_ctx]) == null ? void 0 : _this16$_ctx.profiler;
1851
1883
  var doSerialize = /*#__PURE__*/function () {
1852
- var _ref17 = _asyncToGenerator(function* () {
1884
+ var _ref18 = _asyncToGenerator(function* () {
1853
1885
  var _this16$_serializers, _this16$_serializers$;
1854
1886
  // Early exit if serialization should not run.
1855
1887
  if (!_this16.shouldSerializerRun(args, type)) {
@@ -1917,7 +1949,7 @@ class SpiceModel {
1917
1949
  return originalIsArray ? data : data[0];
1918
1950
  });
1919
1951
  return function doSerialize() {
1920
- return _ref17.apply(this, arguments);
1952
+ return _ref18.apply(this, arguments);
1921
1953
  };
1922
1954
  }();
1923
1955
  try {
@@ -20,7 +20,7 @@ function resolveDriverName(requestedDriverName, providers) {
20
20
  if (providers === void 0) {
21
21
  providers = {};
22
22
  }
23
- if (requestedDriverName && requestedDriverName !== "sharepoint" && resolveStorageDriver(providers[requestedDriverName])) {
23
+ if (requestedDriverName && resolveStorageDriver(providers[requestedDriverName])) {
24
24
  return requestedDriverName;
25
25
  }
26
26
  var fallbackDriverName = ["firebase", "s3", "minio", "local"].find(driverName => resolveStorageDriver(providers[driverName]));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-js",
3
- "version": "2.7.20",
3
+ "version": "2.7.22",
4
4
  "description": "spice",
5
5
  "main": "build/index.js",
6
6
  "repository": {
@@ -619,14 +619,17 @@ export default class SpiceModel {
619
619
  });
620
620
  }
621
621
  }
622
+ if (!results) {
623
+ results = {};
624
+ }
622
625
 
623
- if (results.type !== undefined && results.type !== this.type) {
626
+ if (results?.type !== undefined && results?.type !== this.type) {
624
627
  throw new Error(`${this.type} does not exist type`);
625
628
  }
626
- if (results._type !== undefined && results._type !== this.type) {
629
+ if (results?._type !== undefined && results?._type !== this.type) {
627
630
  throw new Error(`${this.type} does not exist _type`);
628
631
  }
629
- if (results.deleted === undefined || results.deleted === false) {
632
+ if (results?.deleted === undefined || results?.deleted === false) {
630
633
  if (
631
634
  args.skip_read_serialize !== true &&
632
635
  args.skip_serialize !== true
@@ -1125,42 +1128,68 @@ export default class SpiceModel {
1125
1128
 
1126
1129
  filterResultsByColumns(data, columns) {
1127
1130
  if (columns && columns !== "") {
1128
- // Remove backticks and replace meta().id with id
1129
1131
  const cleanedColumns = columns
1130
1132
  .replace(/`/g, "")
1131
1133
  .replace(/meta\(\)\.id/g, "id");
1132
1134
 
1133
- // Process each column by splitting on comma and trimming
1134
- const columnList = cleanedColumns
1135
+ const columnPaths = cleanedColumns
1135
1136
  .split(",")
1136
1137
  .map((col) => col.trim())
1137
1138
  .map((col) => {
1138
- // Check for alias with AS (case-insensitive)
1139
1139
  const aliasMatch = col.match(/\s+AS\s+([\w]+)/i);
1140
1140
  if (aliasMatch) {
1141
- return aliasMatch[1].trim();
1142
- }
1143
- // Otherwise, for dot-notation, keep the first segment after removing
1144
- // the base model prefix (e.g. user.group.name -> group).
1145
- if (col.includes(".")) {
1146
- let pathParts = col
1147
- .split(".")
1148
- .map((part) => part.trim())
1149
- .filter((part) => part !== "");
1150
- if (pathParts[0] === this.type && pathParts.length > 1) {
1151
- pathParts = pathParts.slice(1);
1152
- }
1153
- return pathParts[0];
1141
+ return {
1142
+ original: col,
1143
+ path: col.replace(/\s+AS\s+[\w]+/i, "").trim(),
1144
+ alias: aliasMatch[1].trim(),
1145
+ };
1154
1146
  }
1155
- return col;
1147
+ return { original: col, path: col, alias: null };
1156
1148
  });
1157
1149
 
1158
- // Ensure that essential keys are always picked
1159
1150
  const requiredKeys = ["_permissions", "_permissions_", "id"];
1160
- const finalKeys = [...new Set([...columnList, ...requiredKeys])];
1161
1151
 
1162
- return data.map((entry) => _.pick(entry, finalKeys));
1152
+ return data.map((entry) => {
1153
+ const result = {};
1154
+
1155
+ // Add required keys
1156
+ requiredKeys.forEach((key) => {
1157
+ if (entry.hasOwnProperty(key)) {
1158
+ result[key] = entry[key];
1159
+ }
1160
+ });
1161
+
1162
+ // Process each column path
1163
+ columnPaths.forEach(({ path, alias }) => {
1164
+ let actualPath = path;
1165
+
1166
+ // Remove table prefix if it matches this.type
1167
+ if (path.includes(".")) {
1168
+ const parts = path.split(".");
1169
+ if (parts[0] === this.type) {
1170
+ actualPath = parts.slice(1).join(".");
1171
+ }
1172
+ }
1173
+
1174
+ const value = _.get(entry, actualPath);
1175
+
1176
+ if (value !== undefined) {
1177
+ if (alias) {
1178
+ result[alias] = value;
1179
+ } else if (actualPath.includes(".")) {
1180
+ // For nested paths, use the last part as the key
1181
+ const key = actualPath.split(".").pop();
1182
+ result[key] = value;
1183
+ } else {
1184
+ result[actualPath] = value;
1185
+ }
1186
+ }
1187
+ });
1188
+
1189
+ return result;
1190
+ });
1163
1191
  }
1192
+ console.log("filterResultsByColumns", data);
1164
1193
  return data;
1165
1194
  }
1166
1195
 
@@ -1397,13 +1426,12 @@ export default class SpiceModel {
1397
1426
  // Find alias tokens from query/columns/sort
1398
1427
  const nestings = [
1399
1428
  ...this.extractNestings(args?.query || "", this.type),
1400
- //...this.extractNestings(args?.columns || "", this.type),
1429
+ ...this.extractNestings(args?.columns || "", this.type),
1401
1430
  ...this.extractNestings(args?.sort || "", this.type),
1402
1431
  ];
1403
1432
 
1404
1433
  // Build join metadata and prepare columns
1405
1434
  const { mappedNestings } = this.buildJoinMetadata(nestings, args);
1406
-
1407
1435
  // Build JOIN/NEST from the mapped keyspaces
1408
1436
  args._join = this.createJoinSection(mappedNestings);
1409
1437
 
@@ -1478,7 +1506,7 @@ export default class SpiceModel {
1478
1506
  await this.run_hook(results.data, "list", "after");
1479
1507
  }
1480
1508
 
1481
- results.data = this.filterResultsByColumns(results.data, args.columns);
1509
+ results.data = this.filterResultsByColumns(results.data, originalColumns);
1482
1510
  //console.log("results.data", results.data);
1483
1511
  return results;
1484
1512
  };
@@ -16,11 +16,7 @@ function resolveStorageDriver(driver) {
16
16
  }
17
17
 
18
18
  function resolveDriverName(requestedDriverName, providers = {}) {
19
- if (
20
- requestedDriverName &&
21
- requestedDriverName !== "sharepoint" &&
22
- resolveStorageDriver(providers[requestedDriverName])
23
- ) {
19
+ if (requestedDriverName && resolveStorageDriver(providers[requestedDriverName])) {
24
20
  return requestedDriverName;
25
21
  }
26
22