@object-ui/data-objectstack 4.0.11 → 4.0.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @object-ui/data-objectstack
2
2
 
3
+ ## 4.0.12
4
+
5
+ ### Patch Changes
6
+
7
+ - @object-ui/types@4.0.12
8
+ - @object-ui/core@4.0.12
9
+
3
10
  ## 4.0.11
4
11
 
5
12
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -881,6 +881,26 @@ function objectFilterEntryToAST(entry) {
881
881
  if (!field || !op) return null;
882
882
  return [String(field), op, entry.value];
883
883
  }
884
+ function translateFilterToAST(filter) {
885
+ if (filter === void 0 || filter === null) return void 0;
886
+ if (Array.isArray(filter)) {
887
+ if (filter.length === 0) return void 0;
888
+ const first = filter[0];
889
+ const isObjectForm = filter.length > 0 && typeof first === "object" && first !== null && !Array.isArray(first) && first.field !== void 0;
890
+ if (isObjectForm) {
891
+ const tuples = filter.map((entry) => objectFilterEntryToAST(entry)).filter((t) => t !== null);
892
+ if (tuples.length === 0) return void 0;
893
+ if (tuples.length === 1) return tuples[0];
894
+ return ["and", ...tuples];
895
+ }
896
+ return filter;
897
+ }
898
+ if (typeof filter === "object") {
899
+ if (Object.keys(filter).length === 0) return void 0;
900
+ return filter;
901
+ }
902
+ return void 0;
903
+ }
884
904
  var discoveryCache = /* @__PURE__ */ new Map();
885
905
  async function getSharedDiscovery(baseUrl, fetcher) {
886
906
  const key = baseUrl || "<default>";
@@ -1387,9 +1407,9 @@ var ObjectStackAdapter = class {
1387
1407
  }
1388
1408
  }
1389
1409
  if (params.$filter !== void 0 && params.$filter !== null) {
1390
- const isEmpty = Array.isArray(params.$filter) ? params.$filter.length === 0 : typeof params.$filter === "object" && Object.keys(params.$filter).length === 0;
1391
- if (!isEmpty) {
1392
- queryParams.set("filter", JSON.stringify(params.$filter));
1410
+ const translated = translateFilterToAST(params.$filter);
1411
+ if (translated !== void 0) {
1412
+ queryParams.set("filter", JSON.stringify(translated));
1393
1413
  }
1394
1414
  }
1395
1415
  const baseUrl = this.baseUrl.replace(/\/$/, "");
package/dist/index.js CHANGED
@@ -838,6 +838,26 @@ function objectFilterEntryToAST(entry) {
838
838
  if (!field || !op) return null;
839
839
  return [String(field), op, entry.value];
840
840
  }
841
+ function translateFilterToAST(filter) {
842
+ if (filter === void 0 || filter === null) return void 0;
843
+ if (Array.isArray(filter)) {
844
+ if (filter.length === 0) return void 0;
845
+ const first = filter[0];
846
+ const isObjectForm = filter.length > 0 && typeof first === "object" && first !== null && !Array.isArray(first) && first.field !== void 0;
847
+ if (isObjectForm) {
848
+ const tuples = filter.map((entry) => objectFilterEntryToAST(entry)).filter((t) => t !== null);
849
+ if (tuples.length === 0) return void 0;
850
+ if (tuples.length === 1) return tuples[0];
851
+ return ["and", ...tuples];
852
+ }
853
+ return filter;
854
+ }
855
+ if (typeof filter === "object") {
856
+ if (Object.keys(filter).length === 0) return void 0;
857
+ return filter;
858
+ }
859
+ return void 0;
860
+ }
841
861
  var discoveryCache = /* @__PURE__ */ new Map();
842
862
  async function getSharedDiscovery(baseUrl, fetcher) {
843
863
  const key = baseUrl || "<default>";
@@ -1344,9 +1364,9 @@ var ObjectStackAdapter = class {
1344
1364
  }
1345
1365
  }
1346
1366
  if (params.$filter !== void 0 && params.$filter !== null) {
1347
- const isEmpty = Array.isArray(params.$filter) ? params.$filter.length === 0 : typeof params.$filter === "object" && Object.keys(params.$filter).length === 0;
1348
- if (!isEmpty) {
1349
- queryParams.set("filter", JSON.stringify(params.$filter));
1367
+ const translated = translateFilterToAST(params.$filter);
1368
+ if (translated !== void 0) {
1369
+ queryParams.set("filter", JSON.stringify(translated));
1350
1370
  }
1351
1371
  }
1352
1372
  const baseUrl = this.baseUrl.replace(/\/$/, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/data-objectstack",
3
- "version": "4.0.11",
3
+ "version": "4.0.12",
4
4
  "description": "ObjectStack Data Adapter for Object UI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,8 +23,8 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@objectstack/client": "^4.0.5",
26
- "@object-ui/core": "4.0.11",
27
- "@object-ui/types": "4.0.11"
26
+ "@object-ui/core": "4.0.12",
27
+ "@object-ui/types": "4.0.12"
28
28
  },
29
29
  "devDependencies": {
30
30
  "tsup": "^8.5.1",
package/src/index.ts CHANGED
@@ -78,6 +78,54 @@ function objectFilterEntryToAST(entry: any): [string, string, any] | null {
78
78
  return [String(field), op, entry.value];
79
79
  }
80
80
 
81
+ /**
82
+ * Translate any of the filter shapes accepted by ObjectUI into the AST format
83
+ * understood by the ObjectStack server's `parseFilterAST()`.
84
+ *
85
+ * Accepted inputs:
86
+ * - `[{ field, operator, value }, ...]` — ViewFilterRule[] from view configs
87
+ * - `[field, op, value]` — single AST tuple (passed through)
88
+ * - `['and'|'or', ...children]` — logical AST node (passed through)
89
+ * - `[[...], [...]]` — legacy nested AST (passed through)
90
+ * - `{ field: value }` / `{ field: { $op: value } }` — MongoDB-style object
91
+ *
92
+ * Returns `undefined` when the input is empty/unrecognized so callers can
93
+ * skip emitting `?filter=` entirely.
94
+ */
95
+ function translateFilterToAST(filter: unknown): unknown | undefined {
96
+ if (filter === undefined || filter === null) return undefined;
97
+
98
+ if (Array.isArray(filter)) {
99
+ if (filter.length === 0) return undefined;
100
+
101
+ // Object form: [{ field, operator, value }, ...]
102
+ const first = filter[0];
103
+ const isObjectForm = filter.length > 0
104
+ && typeof first === 'object'
105
+ && first !== null
106
+ && !Array.isArray(first)
107
+ && (first as any).field !== undefined;
108
+ if (isObjectForm) {
109
+ const tuples = (filter as any[])
110
+ .map(entry => objectFilterEntryToAST(entry))
111
+ .filter((t): t is [string, string, any] => t !== null);
112
+ if (tuples.length === 0) return undefined;
113
+ if (tuples.length === 1) return tuples[0];
114
+ return ['and', ...tuples];
115
+ }
116
+
117
+ // Already AST — pass through.
118
+ return filter;
119
+ }
120
+
121
+ if (typeof filter === 'object') {
122
+ if (Object.keys(filter as Record<string, unknown>).length === 0) return undefined;
123
+ return filter;
124
+ }
125
+
126
+ return undefined;
127
+ }
128
+
81
129
  // Module-level discovery cache. Multiple ObjectStackAdapter instances pointed
82
130
  // at the same baseUrl (e.g. ConditionalAuthWrapper's throwaway adapter +
83
131
  // AdapterProvider's main adapter) would otherwise each fire `/discovery`. By
@@ -844,13 +892,15 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
844
892
  }
845
893
  }
846
894
 
847
- // Filter — drop empty arrays/objects so we don't send `?filter=%5B%5D`
895
+ // Filter — translate ViewFilterRule[] (`[{field, operator, value}]`)
896
+ // and other shapes into AST tuples the server understands. Without this,
897
+ // server-driven views (e.g. `at_risk_accounts`, `hot_leads`) ship raw
898
+ // `[{field,operator,value}]` arrays which `parseFilterAST` silently
899
+ // discards, returning every record instead of the filtered subset.
848
900
  if (params.$filter !== undefined && params.$filter !== null) {
849
- const isEmpty = Array.isArray(params.$filter)
850
- ? params.$filter.length === 0
851
- : typeof params.$filter === 'object' && Object.keys(params.$filter).length === 0;
852
- if (!isEmpty) {
853
- queryParams.set('filter', JSON.stringify(params.$filter));
901
+ const translated = translateFilterToAST(params.$filter);
902
+ if (translated !== undefined) {
903
+ queryParams.set('filter', JSON.stringify(translated));
854
904
  }
855
905
  }
856
906