spice-js 2.7.9 → 2.7.11

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.
@@ -1353,7 +1353,14 @@ class SpiceModel {
1353
1353
 
1354
1354
 
1355
1355
  buildJoinMetadata(nestings, args) {
1356
- // Decide which aliases we can join: only when map.type===MODEL AND reference is a STRING keyspace.
1356
+ var _args$columns;
1357
+
1358
+ // Normalize any double backticks to single backticks early (handles URL encoding issues)
1359
+ if (args.columns && typeof args.columns === "string") {
1360
+ args.columns = args.columns.replace(/``/g, "`");
1361
+ } // Decide which aliases we can join: only when map.type===MODEL AND reference is a STRING keyspace.
1362
+
1363
+
1357
1364
  var mappedNestings = _.compact(_.uniq(nestings).map(alias => {
1358
1365
  var prop = this.props[alias];
1359
1366
  if (!(prop == null ? void 0 : prop.map) || prop.map.type !== _2.MapType.MODEL) return null;
@@ -1381,7 +1388,7 @@ class SpiceModel {
1381
1388
  // then normalize names and add default aliases
1382
1389
  //console.log("Columns in BuildJoinMetadata", args.columns);
1383
1390
 
1384
- this[_columns] = "" + args.columns;
1391
+ this[_columns] = (_args$columns = args.columns) != null ? _args$columns : '';
1385
1392
  args.columns = this.prepColumns(args.columns, protectedAliases, arrayAliases);
1386
1393
  args.columns = this.fixColumnName(args.columns, protectedAliases); //console.log("Columns in BuildJoinMetadata after fixColumnName", args.columns);
1387
1394
 
@@ -1545,7 +1552,8 @@ class SpiceModel {
1545
1552
  yield _this12.run_hook(results.data, "list", "after");
1546
1553
  }
1547
1554
 
1548
- results.data = _this12.filterResultsByColumns(results.data, args.columns);
1555
+ results.data = _this12.filterResultsByColumns(results.data, args.columns); //console.log("results.data", results.data);
1556
+
1549
1557
  return results;
1550
1558
  });
1551
1559
 
@@ -1981,6 +1989,34 @@ class SpiceModel {
1981
1989
  that.addModifier(modifier);
1982
1990
  });
1983
1991
  }
1992
+ /**
1993
+ * Checks if a field is present in the columns string.
1994
+ * Used to skip modifier execution when the field isn't requested.
1995
+ * @param {string} fieldName - The field name to check for
1996
+ * @param {string} columns - Comma-separated column string
1997
+ * @returns {boolean} - True if field is in columns or columns is empty (fetch all)
1998
+ */
1999
+
2000
+
2001
+ isFieldInColumns(fieldName, columns) {
2002
+ // No columns filter = include all
2003
+ if (!columns || columns === '') return true;
2004
+ var tokens = columns.split(',');
2005
+
2006
+ for (var col of tokens) {
2007
+ var trimmed = col.trim(); // Check if this column starts with the field name (exact match or nested like "fieldName.subfield")
2008
+
2009
+ var firstPart = trimmed.split('.')[0]; // Handle backtick-wrapped column names
2010
+
2011
+ var cleanFirstPart = firstPart.startsWith('`') && firstPart.endsWith('`') ? firstPart.slice(1, -1) : firstPart;
2012
+
2013
+ if (cleanFirstPart === fieldName) {
2014
+ return true;
2015
+ }
2016
+ }
2017
+
2018
+ return false;
2019
+ }
1984
2020
 
1985
2021
  createMofifier(properties) {
1986
2022
  var _this17 = this;
@@ -1998,6 +2034,11 @@ class SpiceModel {
1998
2034
  when: properties[i].map.when || "read",
1999
2035
  execute: function () {
2000
2036
  var _execute = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns) {
2037
+ // Skip if columns are specified but this field isn't included
2038
+ if (!_this17.isFieldInColumns(i, columns)) {
2039
+ return data;
2040
+ }
2041
+
2001
2042
  return yield _this17.mapToObject(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args, type, mapping_dept, level, columns);
2002
2043
  });
2003
2044
 
@@ -2019,6 +2060,11 @@ class SpiceModel {
2019
2060
  when: properties[i].map.when || "read",
2020
2061
  execute: function () {
2021
2062
  var _execute2 = _asyncToGenerator(function* (data, old_data, ctx, type, args, mapping_dept, level, columns) {
2063
+ // Skip if columns are specified but this field isn't included
2064
+ if (!_this17.isFieldInColumns(i, columns)) {
2065
+ return data;
2066
+ }
2067
+
2022
2068
  return yield _this17.mapToObjectArray(data, _.isString(properties[i].map.reference) ? spice.models[properties[i].map.reference] : properties[i].map.reference, i, properties[i].map.destination || i, properties[i], args, type, mapping_dept, level, columns);
2023
2069
  });
2024
2070
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-js",
3
- "version": "2.7.9",
3
+ "version": "2.7.11",
4
4
  "description": "spice",
5
5
  "main": "build/index.js",
6
6
  "repository": {
@@ -1168,6 +1168,11 @@ export default class SpiceModel {
1168
1168
  * @returns {Object} - { mappedNestings, protectedAliases, arrayAliases }
1169
1169
  */
1170
1170
  buildJoinMetadata(nestings, args) {
1171
+ // Normalize any double backticks to single backticks early (handles URL encoding issues)
1172
+ if (args.columns && typeof args.columns === "string") {
1173
+ args.columns = args.columns.replace(/``/g, "`");
1174
+ }
1175
+
1171
1176
  // Decide which aliases we can join: only when map.type===MODEL AND reference is a STRING keyspace.
1172
1177
  const mappedNestings = _.compact(
1173
1178
  _.uniq(nestings).map((alias) => {
@@ -1204,7 +1209,10 @@ export default class SpiceModel {
1204
1209
  // Columns: first prepare (prefix base table, rewrite array alias.field → ARRAY proj),
1205
1210
  // then normalize names and add default aliases
1206
1211
  //console.log("Columns in BuildJoinMetadata", args.columns);
1207
- this[_columns] = `${args.columns}`;
1212
+
1213
+ this[_columns] = args.columns ?? '';
1214
+
1215
+
1208
1216
  args.columns = this.prepColumns(
1209
1217
  args.columns,
1210
1218
  protectedAliases,
@@ -1384,6 +1392,7 @@ export default class SpiceModel {
1384
1392
  }
1385
1393
 
1386
1394
  results.data = this.filterResultsByColumns(results.data, args.columns);
1395
+ //console.log("results.data", results.data);
1387
1396
  return results;
1388
1397
  };
1389
1398
 
@@ -1573,8 +1582,8 @@ export default class SpiceModel {
1573
1582
  const childPath =
1574
1583
  this[_current_path] ?
1575
1584
  `${this[_current_path]}.${source_property}`
1576
- : source_property;
1577
-
1585
+ : source_property;
1586
+
1578
1587
  // ⚡ Wrap in profiler track() to ensure proper async context for child operations
1579
1588
  const fetchRelated = async () => {
1580
1589
  return await Promise.allSettled(
@@ -1804,6 +1813,34 @@ export default class SpiceModel {
1804
1813
  });
1805
1814
  }
1806
1815
 
1816
+ /**
1817
+ * Checks if a field is present in the columns string.
1818
+ * Used to skip modifier execution when the field isn't requested.
1819
+ * @param {string} fieldName - The field name to check for
1820
+ * @param {string} columns - Comma-separated column string
1821
+ * @returns {boolean} - True if field is in columns or columns is empty (fetch all)
1822
+ */
1823
+ isFieldInColumns(fieldName, columns) {
1824
+ // No columns filter = include all
1825
+ if (!columns || columns === '') return true;
1826
+
1827
+ const tokens = columns.split(',');
1828
+ for (const col of tokens) {
1829
+ const trimmed = col.trim();
1830
+ // Check if this column starts with the field name (exact match or nested like "fieldName.subfield")
1831
+ const firstPart = trimmed.split('.')[0];
1832
+ // Handle backtick-wrapped column names
1833
+ const cleanFirstPart = firstPart.startsWith('`') && firstPart.endsWith('`')
1834
+ ? firstPart.slice(1, -1)
1835
+ : firstPart;
1836
+
1837
+ if (cleanFirstPart === fieldName) {
1838
+ return true;
1839
+ }
1840
+ }
1841
+ return false;
1842
+ }
1843
+
1807
1844
  createMofifier(properties) {
1808
1845
  for (let i in properties) {
1809
1846
  if (properties[i].map) {
@@ -1815,6 +1852,10 @@ export default class SpiceModel {
1815
1852
  this.addModifier({
1816
1853
  when: properties[i].map.when || "read",
1817
1854
  execute: async (data, old_data, ctx, type, args, mapping_dept, level, columns) => {
1855
+ // Skip if columns are specified but this field isn't included
1856
+ if (!this.isFieldInColumns(i, columns)) {
1857
+ return data;
1858
+ }
1818
1859
  return await this.mapToObject(
1819
1860
  data,
1820
1861
  _.isString(properties[i].map.reference) ?
@@ -1838,6 +1879,10 @@ export default class SpiceModel {
1838
1879
  this.addModifier({
1839
1880
  when: properties[i].map.when || "read",
1840
1881
  execute: async (data, old_data, ctx, type, args, mapping_dept, level, columns) => {
1882
+ // Skip if columns are specified but this field isn't included
1883
+ if (!this.isFieldInColumns(i, columns)) {
1884
+ return data;
1885
+ }
1841
1886
  return await this.mapToObjectArray(
1842
1887
  data,
1843
1888
  _.isString(properties[i].map.reference) ?