@object-ui/data-objectstack 3.4.0 → 4.0.1
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 +15 -0
- package/dist/index.cjs +63 -1
- package/dist/index.js +63 -1
- package/package.json +3 -3
- package/src/index.ts +87 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @object-ui/data-objectstack
|
|
2
2
|
|
|
3
|
+
## 4.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @object-ui/types@4.0.1
|
|
8
|
+
- @object-ui/core@4.0.1
|
|
9
|
+
|
|
10
|
+
## 4.0.0
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @object-ui/types@4.0.0
|
|
16
|
+
- @object-ui/core@4.0.0
|
|
17
|
+
|
|
3
18
|
## 3.4.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -829,6 +829,57 @@ function calculateAutoLayout(items, canvasWidth, padding = 40, gap = 40) {
|
|
|
829
829
|
}
|
|
830
830
|
|
|
831
831
|
// src/index.ts
|
|
832
|
+
var FILTER_OPERATOR_ALIASES = {
|
|
833
|
+
equals: "=",
|
|
834
|
+
eq: "=",
|
|
835
|
+
"==": "=",
|
|
836
|
+
not_equals: "!=",
|
|
837
|
+
notequals: "!=",
|
|
838
|
+
ne: "!=",
|
|
839
|
+
greater_than: ">",
|
|
840
|
+
greaterthan: ">",
|
|
841
|
+
gt: ">",
|
|
842
|
+
greater_than_or_equal: ">=",
|
|
843
|
+
greater_than_or_equals: ">=",
|
|
844
|
+
greaterthanorequal: ">=",
|
|
845
|
+
gte: ">=",
|
|
846
|
+
less_than: "<",
|
|
847
|
+
lessthan: "<",
|
|
848
|
+
lt: "<",
|
|
849
|
+
less_than_or_equal: "<=",
|
|
850
|
+
less_than_or_equals: "<=",
|
|
851
|
+
lessthanorequal: "<=",
|
|
852
|
+
lte: "<=",
|
|
853
|
+
in: "in",
|
|
854
|
+
not_in: "nin",
|
|
855
|
+
notin: "nin",
|
|
856
|
+
nin: "nin",
|
|
857
|
+
contains: "contains",
|
|
858
|
+
not_contains: "notcontains",
|
|
859
|
+
notcontains: "notcontains",
|
|
860
|
+
starts_with: "startswith",
|
|
861
|
+
startswith: "startswith",
|
|
862
|
+
ends_with: "endswith",
|
|
863
|
+
endswith: "endswith",
|
|
864
|
+
between: "between",
|
|
865
|
+
is_null: "isnull",
|
|
866
|
+
isnull: "isnull",
|
|
867
|
+
is_not_null: "isnotnull",
|
|
868
|
+
isnotnull: "isnotnull"
|
|
869
|
+
};
|
|
870
|
+
function normalizeFilterOperator(op) {
|
|
871
|
+
if (typeof op !== "string") return null;
|
|
872
|
+
const lower = op.toLowerCase();
|
|
873
|
+
return FILTER_OPERATOR_ALIASES[lower] ?? FILTER_OPERATOR_ALIASES[op] ?? op;
|
|
874
|
+
}
|
|
875
|
+
function objectFilterEntryToAST(entry) {
|
|
876
|
+
if (!entry || typeof entry !== "object") return null;
|
|
877
|
+
const field = entry.field ?? entry.name;
|
|
878
|
+
const rawOp = entry.operator ?? entry.op ?? "=";
|
|
879
|
+
const op = normalizeFilterOperator(rawOp);
|
|
880
|
+
if (!field || !op) return null;
|
|
881
|
+
return [String(field), op, entry.value];
|
|
882
|
+
}
|
|
832
883
|
var discoveryCache = /* @__PURE__ */ new Map();
|
|
833
884
|
async function getSharedDiscovery(baseUrl, fetcher) {
|
|
834
885
|
const key = baseUrl || "<default>";
|
|
@@ -1322,7 +1373,18 @@ var ObjectStackAdapter = class {
|
|
|
1322
1373
|
const isEmpty = Array.isArray(params.$filter) ? params.$filter.length === 0 : typeof params.$filter === "object" && Object.keys(params.$filter).length === 0;
|
|
1323
1374
|
if (!isEmpty) {
|
|
1324
1375
|
if (Array.isArray(params.$filter)) {
|
|
1325
|
-
|
|
1376
|
+
const isObjectForm = params.$filter.length > 0 && typeof params.$filter[0] === "object" && !Array.isArray(params.$filter[0]) && params.$filter[0].field !== void 0;
|
|
1377
|
+
if (isObjectForm) {
|
|
1378
|
+
const tuples = params.$filter.map((entry) => objectFilterEntryToAST(entry)).filter((t) => t !== null);
|
|
1379
|
+
if (tuples.length === 0) {
|
|
1380
|
+
} else if (tuples.length === 1) {
|
|
1381
|
+
options.filters = tuples[0];
|
|
1382
|
+
} else {
|
|
1383
|
+
options.filters = ["and", ...tuples];
|
|
1384
|
+
}
|
|
1385
|
+
} else {
|
|
1386
|
+
options.filters = params.$filter;
|
|
1387
|
+
}
|
|
1326
1388
|
} else {
|
|
1327
1389
|
options.filters = convertFiltersToAST(params.$filter);
|
|
1328
1390
|
}
|
package/dist/index.js
CHANGED
|
@@ -787,6 +787,57 @@ function calculateAutoLayout(items, canvasWidth, padding = 40, gap = 40) {
|
|
|
787
787
|
}
|
|
788
788
|
|
|
789
789
|
// src/index.ts
|
|
790
|
+
var FILTER_OPERATOR_ALIASES = {
|
|
791
|
+
equals: "=",
|
|
792
|
+
eq: "=",
|
|
793
|
+
"==": "=",
|
|
794
|
+
not_equals: "!=",
|
|
795
|
+
notequals: "!=",
|
|
796
|
+
ne: "!=",
|
|
797
|
+
greater_than: ">",
|
|
798
|
+
greaterthan: ">",
|
|
799
|
+
gt: ">",
|
|
800
|
+
greater_than_or_equal: ">=",
|
|
801
|
+
greater_than_or_equals: ">=",
|
|
802
|
+
greaterthanorequal: ">=",
|
|
803
|
+
gte: ">=",
|
|
804
|
+
less_than: "<",
|
|
805
|
+
lessthan: "<",
|
|
806
|
+
lt: "<",
|
|
807
|
+
less_than_or_equal: "<=",
|
|
808
|
+
less_than_or_equals: "<=",
|
|
809
|
+
lessthanorequal: "<=",
|
|
810
|
+
lte: "<=",
|
|
811
|
+
in: "in",
|
|
812
|
+
not_in: "nin",
|
|
813
|
+
notin: "nin",
|
|
814
|
+
nin: "nin",
|
|
815
|
+
contains: "contains",
|
|
816
|
+
not_contains: "notcontains",
|
|
817
|
+
notcontains: "notcontains",
|
|
818
|
+
starts_with: "startswith",
|
|
819
|
+
startswith: "startswith",
|
|
820
|
+
ends_with: "endswith",
|
|
821
|
+
endswith: "endswith",
|
|
822
|
+
between: "between",
|
|
823
|
+
is_null: "isnull",
|
|
824
|
+
isnull: "isnull",
|
|
825
|
+
is_not_null: "isnotnull",
|
|
826
|
+
isnotnull: "isnotnull"
|
|
827
|
+
};
|
|
828
|
+
function normalizeFilterOperator(op) {
|
|
829
|
+
if (typeof op !== "string") return null;
|
|
830
|
+
const lower = op.toLowerCase();
|
|
831
|
+
return FILTER_OPERATOR_ALIASES[lower] ?? FILTER_OPERATOR_ALIASES[op] ?? op;
|
|
832
|
+
}
|
|
833
|
+
function objectFilterEntryToAST(entry) {
|
|
834
|
+
if (!entry || typeof entry !== "object") return null;
|
|
835
|
+
const field = entry.field ?? entry.name;
|
|
836
|
+
const rawOp = entry.operator ?? entry.op ?? "=";
|
|
837
|
+
const op = normalizeFilterOperator(rawOp);
|
|
838
|
+
if (!field || !op) return null;
|
|
839
|
+
return [String(field), op, entry.value];
|
|
840
|
+
}
|
|
790
841
|
var discoveryCache = /* @__PURE__ */ new Map();
|
|
791
842
|
async function getSharedDiscovery(baseUrl, fetcher) {
|
|
792
843
|
const key = baseUrl || "<default>";
|
|
@@ -1280,7 +1331,18 @@ var ObjectStackAdapter = class {
|
|
|
1280
1331
|
const isEmpty = Array.isArray(params.$filter) ? params.$filter.length === 0 : typeof params.$filter === "object" && Object.keys(params.$filter).length === 0;
|
|
1281
1332
|
if (!isEmpty) {
|
|
1282
1333
|
if (Array.isArray(params.$filter)) {
|
|
1283
|
-
|
|
1334
|
+
const isObjectForm = params.$filter.length > 0 && typeof params.$filter[0] === "object" && !Array.isArray(params.$filter[0]) && params.$filter[0].field !== void 0;
|
|
1335
|
+
if (isObjectForm) {
|
|
1336
|
+
const tuples = params.$filter.map((entry) => objectFilterEntryToAST(entry)).filter((t) => t !== null);
|
|
1337
|
+
if (tuples.length === 0) {
|
|
1338
|
+
} else if (tuples.length === 1) {
|
|
1339
|
+
options.filters = tuples[0];
|
|
1340
|
+
} else {
|
|
1341
|
+
options.filters = ["and", ...tuples];
|
|
1342
|
+
}
|
|
1343
|
+
} else {
|
|
1344
|
+
options.filters = params.$filter;
|
|
1345
|
+
}
|
|
1284
1346
|
} else {
|
|
1285
1347
|
options.filters = convertFiltersToAST(params.$filter);
|
|
1286
1348
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/data-objectstack",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
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.4",
|
|
26
|
-
"@object-ui/core": "
|
|
27
|
-
"@object-ui/types": "
|
|
26
|
+
"@object-ui/core": "4.0.1",
|
|
27
|
+
"@object-ui/types": "4.0.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"tsup": "^8.5.1",
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,66 @@ import {
|
|
|
18
18
|
createErrorFromResponse,
|
|
19
19
|
} from './errors';
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Map human-readable filter operator names produced by SDUI view configs
|
|
23
|
+
* (e.g. `lead.view.ts`) to the canonical operator symbols expected by the
|
|
24
|
+
* ObjectStack server's filter AST. Unknown operators fall through unchanged
|
|
25
|
+
* so existing AST-style entries keep working.
|
|
26
|
+
*/
|
|
27
|
+
const FILTER_OPERATOR_ALIASES: Record<string, string> = {
|
|
28
|
+
equals: '=',
|
|
29
|
+
eq: '=',
|
|
30
|
+
'==': '=',
|
|
31
|
+
not_equals: '!=',
|
|
32
|
+
notequals: '!=',
|
|
33
|
+
ne: '!=',
|
|
34
|
+
greater_than: '>',
|
|
35
|
+
greaterthan: '>',
|
|
36
|
+
gt: '>',
|
|
37
|
+
greater_than_or_equal: '>=',
|
|
38
|
+
greater_than_or_equals: '>=',
|
|
39
|
+
greaterthanorequal: '>=',
|
|
40
|
+
gte: '>=',
|
|
41
|
+
less_than: '<',
|
|
42
|
+
lessthan: '<',
|
|
43
|
+
lt: '<',
|
|
44
|
+
less_than_or_equal: '<=',
|
|
45
|
+
less_than_or_equals: '<=',
|
|
46
|
+
lessthanorequal: '<=',
|
|
47
|
+
lte: '<=',
|
|
48
|
+
in: 'in',
|
|
49
|
+
not_in: 'nin',
|
|
50
|
+
notin: 'nin',
|
|
51
|
+
nin: 'nin',
|
|
52
|
+
contains: 'contains',
|
|
53
|
+
not_contains: 'notcontains',
|
|
54
|
+
notcontains: 'notcontains',
|
|
55
|
+
starts_with: 'startswith',
|
|
56
|
+
startswith: 'startswith',
|
|
57
|
+
ends_with: 'endswith',
|
|
58
|
+
endswith: 'endswith',
|
|
59
|
+
between: 'between',
|
|
60
|
+
is_null: 'isnull',
|
|
61
|
+
isnull: 'isnull',
|
|
62
|
+
is_not_null: 'isnotnull',
|
|
63
|
+
isnotnull: 'isnotnull',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function normalizeFilterOperator(op: unknown): string | null {
|
|
67
|
+
if (typeof op !== 'string') return null;
|
|
68
|
+
const lower = op.toLowerCase();
|
|
69
|
+
return FILTER_OPERATOR_ALIASES[lower] ?? FILTER_OPERATOR_ALIASES[op] ?? op;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function objectFilterEntryToAST(entry: any): [string, string, any] | null {
|
|
73
|
+
if (!entry || typeof entry !== 'object') return null;
|
|
74
|
+
const field = entry.field ?? entry.name;
|
|
75
|
+
const rawOp = entry.operator ?? entry.op ?? '=';
|
|
76
|
+
const op = normalizeFilterOperator(rawOp);
|
|
77
|
+
if (!field || !op) return null;
|
|
78
|
+
return [String(field), op, entry.value];
|
|
79
|
+
}
|
|
80
|
+
|
|
21
81
|
// Module-level discovery cache. Multiple ObjectStackAdapter instances pointed
|
|
22
82
|
// at the same baseUrl (e.g. ConditionalAuthWrapper's throwaway adapter +
|
|
23
83
|
// AdapterProvider's main adapter) would otherwise each fire `/discovery`. By
|
|
@@ -749,8 +809,33 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
|
|
|
749
809
|
: typeof params.$filter === 'object' && Object.keys(params.$filter).length === 0;
|
|
750
810
|
if (!isEmpty) {
|
|
751
811
|
if (Array.isArray(params.$filter)) {
|
|
752
|
-
//
|
|
753
|
-
|
|
812
|
+
// Two array shapes are accepted from upstream:
|
|
813
|
+
// 1. AST tuples: [field, op, value] — pass through.
|
|
814
|
+
// 2. Object form: [{ field, operator, value }, ...] — server-driven
|
|
815
|
+
// view configs (lead.view.ts etc.) use this. Translate each
|
|
816
|
+
// entry into the AST tuple shape and map human-readable
|
|
817
|
+
// operator names (`greater_than_or_equal`, `in`, `contains`,
|
|
818
|
+
// …) to the canonical symbols the server understands.
|
|
819
|
+
const isObjectForm = params.$filter.length > 0
|
|
820
|
+
&& typeof params.$filter[0] === 'object'
|
|
821
|
+
&& !Array.isArray(params.$filter[0])
|
|
822
|
+
&& (params.$filter[0] as any).field !== undefined;
|
|
823
|
+
if (isObjectForm) {
|
|
824
|
+
const tuples = (params.$filter as any[])
|
|
825
|
+
.map(entry => objectFilterEntryToAST(entry))
|
|
826
|
+
.filter((t): t is [string, string, any] => t !== null);
|
|
827
|
+
if (tuples.length === 0) {
|
|
828
|
+
// All entries were unrecognized — drop the filter rather than
|
|
829
|
+
// sending a malformed array.
|
|
830
|
+
} else if (tuples.length === 1) {
|
|
831
|
+
options.filters = tuples[0];
|
|
832
|
+
} else {
|
|
833
|
+
options.filters = ['and', ...tuples];
|
|
834
|
+
}
|
|
835
|
+
} else {
|
|
836
|
+
// Already in AST format
|
|
837
|
+
options.filters = params.$filter;
|
|
838
|
+
}
|
|
754
839
|
} else {
|
|
755
840
|
options.filters = convertFiltersToAST(params.$filter);
|
|
756
841
|
}
|