roboto-js 1.7.4 → 1.7.5

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/.last-build CHANGED
@@ -1 +1 @@
1
- 2025-10-01T06:27:28.595Z
1
+ 2025-10-02T14:56:57.111Z
@@ -11,8 +11,12 @@ var _rbt_user = _interopRequireDefault(require("./rbt_user.cjs"));
11
11
  var _rbt_file = _interopRequireDefault(require("./rbt_file.cjs"));
12
12
  var _lodash = _interopRequireDefault(require("lodash"));
13
13
  var _idb = require("idb");
14
+ var _excluded = ["enableRealtime"],
15
+ _excluded2 = ["enableRealtime"];
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
17
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
18
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
19
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
16
20
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
17
21
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
18
22
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -1164,6 +1168,10 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1164
1168
  * - limit: An object to control the pagination of results. It includes:
1165
1169
  * - offset: The starting point from where to fetch the results.
1166
1170
  * - results: The maximum number of results to return.
1171
+ * - requestAttrs: An array of attribute paths to include in the response (e.g., ['id', 'configs.title', 'configs.description']).
1172
+ * If not provided, all attributes are returned.
1173
+ * - excludeAttrs: An array of attribute paths to exclude from the response (e.g., ['details.log', 'internalData']).
1174
+ * Excludes the specified paths and all their subpaths.
1167
1175
  * - resolveReferences: An array of attribute names whose references should be resolved in the returned objects.
1168
1176
  * - timeout: A numerical value in milliseconds to set a maximum time limit for the query execution.
1169
1177
  *
@@ -1172,6 +1180,8 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1172
1180
  * where: 'email="tom@pospa.com"',
1173
1181
  * orderBy: { column: 'timeCreated', direction: 'DESC' },
1174
1182
  * limit: { offset: 0, results: 50 },
1183
+ * requestAttrs: ['id', 'configs.title'],
1184
+ * excludeAttrs: ['details.log'],
1175
1185
  * resolveReferences: ['translatableContent']
1176
1186
  * });
1177
1187
  *
@@ -1185,6 +1195,8 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1185
1195
  var _this6 = this;
1186
1196
  var params,
1187
1197
  paramsKey,
1198
+ validParams,
1199
+ invalidParams,
1188
1200
  defaultOrderBy,
1189
1201
  defaultLimit,
1190
1202
  mergedParams,
@@ -1199,6 +1211,21 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1199
1211
  params = _args22.length > 1 && _args22[1] !== undefined ? _args22[1] : {};
1200
1212
  _context22.prev = 1;
1201
1213
  //console.log('RBTAPI.query INIT', type, params);
1214
+ // Validate parameters - reject invalid parameter names
1215
+ validParams = ['type', 'where', 'orderBy', 'limit', 'resolveReferences', 'requestAttrs', 'excludeAttrs', 'timeout', 'enableRealtime'];
1216
+ invalidParams = Object.keys(params).filter(function (key) {
1217
+ return !validParams.includes(key);
1218
+ });
1219
+ if (!(invalidParams.length > 0)) {
1220
+ _context22.next = 6;
1221
+ break;
1222
+ }
1223
+ throw new Error("Invalid query parameter(s): ".concat(invalidParams.join(', '), ". Valid parameters are: ").concat(validParams.join(', ')));
1224
+ case 6:
1225
+ // Warn if enableRealtime is passed to query() - it should only be used by load()
1226
+ if (params.enableRealtime) {
1227
+ console.warn('[roboto-js] enableRealtime should not be passed to query(), only to load(). This parameter will be ignored.');
1228
+ }
1202
1229
  params.type = type;
1203
1230
 
1204
1231
  // Default ordering and pagination
@@ -1219,11 +1246,11 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1219
1246
  paramsKey = JSON.stringify(mergedParams);
1220
1247
  cacheEntry = this.requestCache[paramsKey];
1221
1248
  if (!(cacheEntry && currentTime - cacheEntry.time < 10000)) {
1222
- _context22.next = 11;
1249
+ _context22.next = 16;
1223
1250
  break;
1224
1251
  }
1225
1252
  return _context22.abrupt("return", cacheEntry.val);
1226
- case 11:
1253
+ case 16:
1227
1254
  // Create the response promise
1228
1255
  responsePromise = this.axios.post('/object_service/queryObjects', [mergedParams]); // Cache the promise of processing data, not just the raw response
1229
1256
  processingPromise = responsePromise.then(function (response) {
@@ -1239,21 +1266,21 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1239
1266
  };
1240
1267
 
1241
1268
  // Await the processing promise for this call to get processed data
1242
- _context22.next = 16;
1269
+ _context22.next = 21;
1243
1270
  return processingPromise;
1244
- case 16:
1271
+ case 21:
1245
1272
  return _context22.abrupt("return", _context22.sent);
1246
- case 19:
1247
- _context22.prev = 19;
1273
+ case 24:
1274
+ _context22.prev = 24;
1248
1275
  _context22.t0 = _context22["catch"](1);
1249
1276
  delete this.requestCache[paramsKey]; // Ensure cache cleanup on error
1250
1277
  //console.log('RBTAPI.query ERROR', paramsKey, e);
1251
1278
  return _context22.abrupt("return", this._handleError(_context22.t0));
1252
- case 23:
1279
+ case 28:
1253
1280
  case "end":
1254
1281
  return _context22.stop();
1255
1282
  }
1256
- }, _callee22, this, [[1, 19]]);
1283
+ }, _callee22, this, [[1, 24]]);
1257
1284
  }));
1258
1285
  function query(_x13) {
1259
1286
  return _query.apply(this, arguments);
@@ -1319,6 +1346,8 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1319
1346
  hitLogKey,
1320
1347
  loadedObjects,
1321
1348
  bulkMissLogKey,
1349
+ enableRealtime,
1350
+ queryParams,
1322
1351
  _iterator4,
1323
1352
  _step4,
1324
1353
  obj,
@@ -1346,7 +1375,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1346
1375
  }
1347
1376
  _context24.prev = 2;
1348
1377
  if (!Array.isArray(ids)) {
1349
- _context24.next = 24;
1378
+ _context24.next = 25;
1350
1379
  break;
1351
1380
  }
1352
1381
  // For array requests, check cache for each ID and only load missing ones
@@ -1393,7 +1422,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1393
1422
  }
1394
1423
  loadedObjects = [];
1395
1424
  if (!(missingIds.length > 0)) {
1396
- _context24.next = 18;
1425
+ _context24.next = 19;
1397
1426
  break;
1398
1427
  }
1399
1428
  // Only log bulk cache miss once
@@ -1405,12 +1434,15 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1405
1434
  });
1406
1435
  this._loggedCacheEvents.add(bulkMissLogKey);
1407
1436
  }
1408
- mergedParams = _objectSpread(_objectSpread({}, params), {}, {
1437
+
1438
+ // Remove load-specific params that shouldn't be passed to query
1439
+ enableRealtime = params.enableRealtime, queryParams = _objectWithoutProperties(params, _excluded);
1440
+ mergedParams = _objectSpread(_objectSpread({}, queryParams), {}, {
1409
1441
  where: "id IN (\"".concat(missingIds.join("\",\""), "\")")
1410
1442
  });
1411
- _context24.next = 15;
1443
+ _context24.next = 16;
1412
1444
  return this.query(type, mergedParams);
1413
- case 15:
1445
+ case 16:
1414
1446
  loadedObjects = _context24.sent;
1415
1447
  // Cache the newly loaded objects
1416
1448
  _iterator4 = _createForOfIteratorHelper(loadedObjects);
@@ -1435,7 +1467,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1435
1467
  } finally {
1436
1468
  _iterator4.f();
1437
1469
  }
1438
- case 18:
1470
+ case 19:
1439
1471
  // Return combined results in original order
1440
1472
  result = [];
1441
1473
  _iterator5 = _createForOfIteratorHelper(ids);
@@ -1458,12 +1490,12 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1458
1490
  _iterator5.f();
1459
1491
  }
1460
1492
  return _context24.abrupt("return", result);
1461
- case 24:
1493
+ case 25:
1462
1494
  // For single object requests, check cache first
1463
1495
  _cacheKey3 = "".concat(type, ":").concat(ids);
1464
1496
  _cached = this._objectCache.get(_cacheKey3);
1465
1497
  if (!_cached) {
1466
- _context24.next = 31;
1498
+ _context24.next = 32;
1467
1499
  break;
1468
1500
  }
1469
1501
  // Only log cache hits once per object to reduce spam
@@ -1486,18 +1518,18 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1486
1518
  _cached._initRealtime();
1487
1519
  }
1488
1520
  return _context24.abrupt("return", _cached);
1489
- case 31:
1521
+ case 32:
1490
1522
  // Check if we're already loading this object
1491
1523
  pendingKey = "".concat(type, ":").concat(ids);
1492
1524
  if (!this._pendingLoads.has(pendingKey)) {
1493
- _context24.next = 36;
1525
+ _context24.next = 37;
1494
1526
  break;
1495
1527
  }
1496
- _context24.next = 35;
1528
+ _context24.next = 36;
1497
1529
  return this._pendingLoads.get(pendingKey);
1498
- case 35:
1499
- return _context24.abrupt("return", _context24.sent);
1500
1530
  case 36:
1531
+ return _context24.abrupt("return", _context24.sent);
1532
+ case 37:
1501
1533
  // Only log cache miss once per object to reduce spam
1502
1534
  missLogKey = "miss:".concat(_cacheKey3);
1503
1535
  if (!this._loggedCacheEvents.has(missLogKey)) {
@@ -1510,17 +1542,19 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1510
1542
 
1511
1543
  // Create the loading promise and store it to prevent duplicate requests
1512
1544
  loadPromise = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() {
1513
- var res, _obj2, _setLogKey;
1545
+ var _enableRealtime, _queryParams, res, _obj2, _setLogKey;
1514
1546
  return _regeneratorRuntime().wrap(function _callee23$(_context23) {
1515
1547
  while (1) switch (_context23.prev = _context23.next) {
1516
1548
  case 0:
1517
1549
  _context23.prev = 0;
1518
- mergedParams = _objectSpread(_objectSpread({}, params), {}, {
1550
+ // Remove load-specific params that shouldn't be passed to query
1551
+ _enableRealtime = params.enableRealtime, _queryParams = _objectWithoutProperties(params, _excluded2);
1552
+ mergedParams = _objectSpread(_objectSpread({}, _queryParams), {}, {
1519
1553
  where: "id=\"".concat(ids, "\"")
1520
1554
  });
1521
- _context23.next = 4;
1555
+ _context23.next = 5;
1522
1556
  return _this8.query(type, mergedParams);
1523
- case 4:
1557
+ case 5:
1524
1558
  res = _context23.sent;
1525
1559
  _obj2 = res[0];
1526
1560
  if (_obj2) {
@@ -1538,34 +1572,34 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
1538
1572
  }
1539
1573
  }
1540
1574
  return _context23.abrupt("return", _obj2);
1541
- case 8:
1542
- _context23.prev = 8;
1575
+ case 9:
1576
+ _context23.prev = 9;
1543
1577
  // Remove from pending loads
1544
1578
  _this8._pendingLoads["delete"](pendingKey);
1545
- return _context23.finish(8);
1546
- case 11:
1579
+ return _context23.finish(9);
1580
+ case 12:
1547
1581
  case "end":
1548
1582
  return _context23.stop();
1549
1583
  }
1550
- }, _callee23, null, [[0,, 8, 11]]);
1584
+ }, _callee23, null, [[0,, 9, 12]]);
1551
1585
  }))(); // Store the promise so other concurrent requests can await it
1552
1586
  this._pendingLoads.set(pendingKey, loadPromise);
1553
- _context24.next = 42;
1587
+ _context24.next = 43;
1554
1588
  return loadPromise;
1555
- case 42:
1556
- return _context24.abrupt("return", _context24.sent);
1557
1589
  case 43:
1558
- _context24.next = 48;
1590
+ return _context24.abrupt("return", _context24.sent);
1591
+ case 44:
1592
+ _context24.next = 49;
1559
1593
  break;
1560
- case 45:
1561
- _context24.prev = 45;
1594
+ case 46:
1595
+ _context24.prev = 46;
1562
1596
  _context24.t0 = _context24["catch"](2);
1563
1597
  return _context24.abrupt("return", this._handleError(_context24.t0));
1564
- case 48:
1598
+ case 49:
1565
1599
  case "end":
1566
1600
  return _context24.stop();
1567
1601
  }
1568
- }, _callee24, this, [[2, 45]]);
1602
+ }, _callee24, this, [[2, 46]]);
1569
1603
  }));
1570
1604
  function load(_x14, _x15) {
1571
1605
  return _load.apply(this, arguments);
@@ -588,6 +588,10 @@ export default class RbtApi {
588
588
  * - limit: An object to control the pagination of results. It includes:
589
589
  * - offset: The starting point from where to fetch the results.
590
590
  * - results: The maximum number of results to return.
591
+ * - requestAttrs: An array of attribute paths to include in the response (e.g., ['id', 'configs.title', 'configs.description']).
592
+ * If not provided, all attributes are returned.
593
+ * - excludeAttrs: An array of attribute paths to exclude from the response (e.g., ['details.log', 'internalData']).
594
+ * Excludes the specified paths and all their subpaths.
591
595
  * - resolveReferences: An array of attribute names whose references should be resolved in the returned objects.
592
596
  * - timeout: A numerical value in milliseconds to set a maximum time limit for the query execution.
593
597
  *
@@ -596,6 +600,8 @@ export default class RbtApi {
596
600
  * where: 'email="tom@pospa.com"',
597
601
  * orderBy: { column: 'timeCreated', direction: 'DESC' },
598
602
  * limit: { offset: 0, results: 50 },
603
+ * requestAttrs: ['id', 'configs.title'],
604
+ * excludeAttrs: ['details.log'],
599
605
  * resolveReferences: ['translatableContent']
600
606
  * });
601
607
  *
@@ -606,6 +612,18 @@ export default class RbtApi {
606
612
  let paramsKey;
607
613
  try {
608
614
  //console.log('RBTAPI.query INIT', type, params);
615
+
616
+ // Validate parameters - reject invalid parameter names
617
+ const validParams = ['type', 'where', 'orderBy', 'limit', 'resolveReferences', 'requestAttrs', 'excludeAttrs', 'timeout', 'enableRealtime'];
618
+ const invalidParams = Object.keys(params).filter(key => !validParams.includes(key));
619
+ if (invalidParams.length > 0) {
620
+ throw new Error(`Invalid query parameter(s): ${invalidParams.join(', ')}. Valid parameters are: ${validParams.join(', ')}`);
621
+ }
622
+
623
+ // Warn if enableRealtime is passed to query() - it should only be used by load()
624
+ if (params.enableRealtime) {
625
+ console.warn('[roboto-js] enableRealtime should not be passed to query(), only to load(). This parameter will be ignored.');
626
+ }
609
627
  params.type = type;
610
628
 
611
629
  // Default ordering and pagination
@@ -753,8 +771,14 @@ export default class RbtApi {
753
771
  });
754
772
  this._loggedCacheEvents.add(bulkMissLogKey);
755
773
  }
774
+
775
+ // Remove load-specific params that shouldn't be passed to query
776
+ const {
777
+ enableRealtime,
778
+ ...queryParams
779
+ } = params;
756
780
  mergedParams = {
757
- ...params,
781
+ ...queryParams,
758
782
  where: `id IN ("${missingIds.join(`","`)}")`
759
783
  };
760
784
  loadedObjects = await this.query(type, mergedParams);
@@ -837,8 +861,13 @@ export default class RbtApi {
837
861
  // Create the loading promise and store it to prevent duplicate requests
838
862
  const loadPromise = (async () => {
839
863
  try {
864
+ // Remove load-specific params that shouldn't be passed to query
865
+ const {
866
+ enableRealtime,
867
+ ...queryParams
868
+ } = params;
840
869
  mergedParams = {
841
- ...params,
870
+ ...queryParams,
842
871
  where: `id="${ids}"`
843
872
  };
844
873
  let res = await this.query(type, mergedParams);
package/dist/rbt_api.js CHANGED
@@ -1,4 +1,8 @@
1
+ var _excluded = ["enableRealtime"],
2
+ _excluded2 = ["enableRealtime"];
1
3
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
5
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
2
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
8
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -1119,6 +1123,10 @@ var RbtApi = /*#__PURE__*/function () {
1119
1123
  * - limit: An object to control the pagination of results. It includes:
1120
1124
  * - offset: The starting point from where to fetch the results.
1121
1125
  * - results: The maximum number of results to return.
1126
+ * - requestAttrs: An array of attribute paths to include in the response (e.g., ['id', 'configs.title', 'configs.description']).
1127
+ * If not provided, all attributes are returned.
1128
+ * - excludeAttrs: An array of attribute paths to exclude from the response (e.g., ['details.log', 'internalData']).
1129
+ * Excludes the specified paths and all their subpaths.
1122
1130
  * - resolveReferences: An array of attribute names whose references should be resolved in the returned objects.
1123
1131
  * - timeout: A numerical value in milliseconds to set a maximum time limit for the query execution.
1124
1132
  *
@@ -1127,6 +1135,8 @@ var RbtApi = /*#__PURE__*/function () {
1127
1135
  * where: 'email="tom@pospa.com"',
1128
1136
  * orderBy: { column: 'timeCreated', direction: 'DESC' },
1129
1137
  * limit: { offset: 0, results: 50 },
1138
+ * requestAttrs: ['id', 'configs.title'],
1139
+ * excludeAttrs: ['details.log'],
1130
1140
  * resolveReferences: ['translatableContent']
1131
1141
  * });
1132
1142
  *
@@ -1140,6 +1150,8 @@ var RbtApi = /*#__PURE__*/function () {
1140
1150
  var _this6 = this;
1141
1151
  var params,
1142
1152
  paramsKey,
1153
+ validParams,
1154
+ invalidParams,
1143
1155
  defaultOrderBy,
1144
1156
  defaultLimit,
1145
1157
  mergedParams,
@@ -1155,6 +1167,21 @@ var RbtApi = /*#__PURE__*/function () {
1155
1167
  params = _args20.length > 1 && _args20[1] !== undefined ? _args20[1] : {};
1156
1168
  _context20.p = 1;
1157
1169
  //console.log('RBTAPI.query INIT', type, params);
1170
+ // Validate parameters - reject invalid parameter names
1171
+ validParams = ['type', 'where', 'orderBy', 'limit', 'resolveReferences', 'requestAttrs', 'excludeAttrs', 'timeout', 'enableRealtime'];
1172
+ invalidParams = Object.keys(params).filter(function (key) {
1173
+ return !validParams.includes(key);
1174
+ });
1175
+ if (!(invalidParams.length > 0)) {
1176
+ _context20.n = 2;
1177
+ break;
1178
+ }
1179
+ throw new Error("Invalid query parameter(s): ".concat(invalidParams.join(', '), ". Valid parameters are: ").concat(validParams.join(', ')));
1180
+ case 2:
1181
+ // Warn if enableRealtime is passed to query() - it should only be used by load()
1182
+ if (params.enableRealtime) {
1183
+ console.warn('[roboto-js] enableRealtime should not be passed to query(), only to load(). This parameter will be ignored.');
1184
+ }
1158
1185
  params.type = type;
1159
1186
 
1160
1187
  // Default ordering and pagination
@@ -1175,11 +1202,11 @@ var RbtApi = /*#__PURE__*/function () {
1175
1202
  paramsKey = JSON.stringify(mergedParams);
1176
1203
  cacheEntry = this.requestCache[paramsKey];
1177
1204
  if (!(cacheEntry && currentTime - cacheEntry.time < 10000)) {
1178
- _context20.n = 2;
1205
+ _context20.n = 3;
1179
1206
  break;
1180
1207
  }
1181
1208
  return _context20.a(2, cacheEntry.val);
1182
- case 2:
1209
+ case 3:
1183
1210
  // Create the response promise
1184
1211
  responsePromise = this.axios.post('/object_service/queryObjects', [mergedParams]); // Cache the promise of processing data, not just the raw response
1185
1212
  processingPromise = responsePromise.then(function (response) {
@@ -1195,18 +1222,18 @@ var RbtApi = /*#__PURE__*/function () {
1195
1222
  };
1196
1223
 
1197
1224
  // Await the processing promise for this call to get processed data
1198
- _context20.n = 3;
1225
+ _context20.n = 4;
1199
1226
  return processingPromise;
1200
- case 3:
1201
- return _context20.a(2, _context20.v);
1202
1227
  case 4:
1203
- _context20.p = 4;
1228
+ return _context20.a(2, _context20.v);
1229
+ case 5:
1230
+ _context20.p = 5;
1204
1231
  _t15 = _context20.v;
1205
1232
  delete this.requestCache[paramsKey]; // Ensure cache cleanup on error
1206
1233
  //console.log('RBTAPI.query ERROR', paramsKey, e);
1207
1234
  return _context20.a(2, this._handleError(_t15));
1208
1235
  }
1209
- }, _callee20, this, [[1, 4]]);
1236
+ }, _callee20, this, [[1, 5]]);
1210
1237
  }));
1211
1238
  function query(_x11) {
1212
1239
  return _query.apply(this, arguments);
@@ -1272,6 +1299,8 @@ var RbtApi = /*#__PURE__*/function () {
1272
1299
  hitLogKey,
1273
1300
  loadedObjects,
1274
1301
  bulkMissLogKey,
1302
+ enableRealtime,
1303
+ queryParams,
1275
1304
  _iterator4,
1276
1305
  _step4,
1277
1306
  obj,
@@ -1359,7 +1388,10 @@ var RbtApi = /*#__PURE__*/function () {
1359
1388
  });
1360
1389
  this._loggedCacheEvents.add(bulkMissLogKey);
1361
1390
  }
1362
- mergedParams = _objectSpread(_objectSpread({}, params), {}, {
1391
+
1392
+ // Remove load-specific params that shouldn't be passed to query
1393
+ enableRealtime = params.enableRealtime, queryParams = _objectWithoutProperties(params, _excluded);
1394
+ mergedParams = _objectSpread(_objectSpread({}, queryParams), {}, {
1363
1395
  where: "id IN (\"".concat(missingIds.join("\",\""), "\")")
1364
1396
  });
1365
1397
  _context22.n = 2;
@@ -1464,12 +1496,14 @@ var RbtApi = /*#__PURE__*/function () {
1464
1496
 
1465
1497
  // Create the loading promise and store it to prevent duplicate requests
1466
1498
  loadPromise = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee21() {
1467
- var res, _obj2, _setLogKey;
1499
+ var _enableRealtime, _queryParams, res, _obj2, _setLogKey;
1468
1500
  return _regenerator().w(function (_context21) {
1469
1501
  while (1) switch (_context21.p = _context21.n) {
1470
1502
  case 0:
1471
1503
  _context21.p = 0;
1472
- mergedParams = _objectSpread(_objectSpread({}, params), {}, {
1504
+ // Remove load-specific params that shouldn't be passed to query
1505
+ _enableRealtime = params.enableRealtime, _queryParams = _objectWithoutProperties(params, _excluded2);
1506
+ mergedParams = _objectSpread(_objectSpread({}, _queryParams), {}, {
1473
1507
  where: "id=\"".concat(ids, "\"")
1474
1508
  });
1475
1509
  _context21.n = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roboto-js",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "dist/cjs/index.cjs",
package/src/rbt_api.js CHANGED
@@ -693,6 +693,10 @@ export default class RbtApi {
693
693
  * - limit: An object to control the pagination of results. It includes:
694
694
  * - offset: The starting point from where to fetch the results.
695
695
  * - results: The maximum number of results to return.
696
+ * - requestAttrs: An array of attribute paths to include in the response (e.g., ['id', 'configs.title', 'configs.description']).
697
+ * If not provided, all attributes are returned.
698
+ * - excludeAttrs: An array of attribute paths to exclude from the response (e.g., ['details.log', 'internalData']).
699
+ * Excludes the specified paths and all their subpaths.
696
700
  * - resolveReferences: An array of attribute names whose references should be resolved in the returned objects.
697
701
  * - timeout: A numerical value in milliseconds to set a maximum time limit for the query execution.
698
702
  *
@@ -701,6 +705,8 @@ export default class RbtApi {
701
705
  * where: 'email="tom@pospa.com"',
702
706
  * orderBy: { column: 'timeCreated', direction: 'DESC' },
703
707
  * limit: { offset: 0, results: 50 },
708
+ * requestAttrs: ['id', 'configs.title'],
709
+ * excludeAttrs: ['details.log'],
704
710
  * resolveReferences: ['translatableContent']
705
711
  * });
706
712
  *
@@ -712,6 +718,19 @@ export default class RbtApi {
712
718
  let paramsKey;
713
719
  try {
714
720
  //console.log('RBTAPI.query INIT', type, params);
721
+
722
+ // Validate parameters - reject invalid parameter names
723
+ const validParams = ['type', 'where', 'orderBy', 'limit', 'resolveReferences', 'requestAttrs', 'excludeAttrs', 'timeout', 'enableRealtime'];
724
+ const invalidParams = Object.keys(params).filter(key => !validParams.includes(key));
725
+ if (invalidParams.length > 0) {
726
+ throw new Error(`Invalid query parameter(s): ${invalidParams.join(', ')}. Valid parameters are: ${validParams.join(', ')}`);
727
+ }
728
+
729
+ // Warn if enableRealtime is passed to query() - it should only be used by load()
730
+ if (params.enableRealtime) {
731
+ console.warn('[roboto-js] enableRealtime should not be passed to query(), only to load(). This parameter will be ignored.');
732
+ }
733
+
715
734
  params.type = type;
716
735
 
717
736
  // Default ordering and pagination
@@ -843,7 +862,9 @@ export default class RbtApi {
843
862
  this._loggedCacheEvents.add(bulkMissLogKey);
844
863
  }
845
864
 
846
- mergedParams = { ...params, where: `id IN ("${missingIds.join(`","`)}")` };
865
+ // Remove load-specific params that shouldn't be passed to query
866
+ const { enableRealtime, ...queryParams } = params;
867
+ mergedParams = { ...queryParams, where: `id IN ("${missingIds.join(`","`)}")` };
847
868
  loadedObjects = await this.query(type, mergedParams);
848
869
 
849
870
  // Cache the newly loaded objects
@@ -913,7 +934,9 @@ export default class RbtApi {
913
934
  // Create the loading promise and store it to prevent duplicate requests
914
935
  const loadPromise = (async () => {
915
936
  try {
916
- mergedParams = { ...params, where: `id="${ids}"` };
937
+ // Remove load-specific params that shouldn't be passed to query
938
+ const { enableRealtime, ...queryParams } = params;
939
+ mergedParams = { ...queryParams, where: `id="${ids}"` };
917
940
  let res = await this.query(type, mergedParams);
918
941
  const obj = res[0];
919
942