@taruvi/refine-providers 1.3.4-beta.0 → 1.3.4-beta.2
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/README.md +9 -12
- package/dist/index.cjs +135 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -3
- package/dist/index.d.ts +42 -3
- package/dist/index.js +130 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -108,7 +108,12 @@ mutate({ resource: "posts", id: 1 });
|
|
|
108
108
|
|
|
109
109
|
### Filtering
|
|
110
110
|
|
|
111
|
-
List
|
|
111
|
+
List `getList` filters use an explicit **`TaruviListFilters`** shape:
|
|
112
|
+
|
|
113
|
+
- **`FlatFilterLeaf[]`** (array of `{ field, operator, value }`) → top-level **`field__op`** query params via `Database.filters(field, op, value)` (including FK traversal like `department_id.name`).
|
|
114
|
+
- **`LogicalCrudFilter`** (object `{ operator: "and" | "or", value: [...] }`) → JSON **`filters`** tree via `Database.filters(tree)`.
|
|
115
|
+
|
|
116
|
+
Legacy Refine **`CrudFilter[]`** is still accepted: all field leaves → flat array; a single root `and`/`or` object → logical object; mixed lists fall back to the JSON tree. Bracket keys from `convertRefineFilters` remain for helpers / Storage flatten mode.
|
|
112
117
|
|
|
113
118
|
Full support for Refine filter operators:
|
|
114
119
|
|
|
@@ -126,15 +131,7 @@ const { data } = useList({
|
|
|
126
131
|
|
|
127
132
|
**Refine → backend operator mapping (important):**
|
|
128
133
|
|
|
129
|
-
|
|
130
|
-
|-----------------|------------------------------|------------------------|
|
|
131
|
-
| `containss` | `contains` | Case-insensitive substring (ILIKE-style) |
|
|
132
|
-
| `contains` | `containss` | Case-sensitive substring |
|
|
133
|
-
| `startswith`, `endswith` | same name | Case-insensitive |
|
|
134
|
-
| `startswiths`, `endswiths` | same name | Case-sensitive |
|
|
135
|
-
| `icontains` / `nicontains` | pass-through | Aliases; platform normalizes `icontains` → `contains` |
|
|
136
|
-
|
|
137
|
-
Other operators (`eq`, `in`, `between`, array/range ops, etc.) follow `REFINE_OPERATOR_MAP` in [`src/utils.ts`](src/utils.ts).
|
|
134
|
+
Wire suffixes match the platform (`contains` = case-insensitive, `containss` = case-sensitive). Refine aliases map to the same tokens, e.g. `icontains` → `contains`. See `REFINE_OPERATOR_MAP` in [`src/utils.ts`](src/utils.ts).
|
|
138
135
|
|
|
139
136
|
**More operators:**
|
|
140
137
|
|
|
@@ -143,8 +140,8 @@ Other operators (`eq`, `in`, `between`, array/range ops, etc.) follow `REFINE_OP
|
|
|
143
140
|
| `eq` | Equal | `status = "active"` |
|
|
144
141
|
| `ne` | Not equal | `status != "deleted"` |
|
|
145
142
|
| `lt`, `gt`, `lte`, `gte` | Comparison | `age >= 18` |
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
143
|
+
| `contains`, `ncontains` | Case-insensitive contains / not | FK traversal, search UX |
|
|
144
|
+
| `containss`, `ncontainss` | Case-sensitive contains / not | |
|
|
148
145
|
| `startswith`, `endswith` | Case-insensitive prefix/suffix | |
|
|
149
146
|
| `startswiths`, `endswiths` | Case-sensitive prefix/suffix | |
|
|
150
147
|
| `in`, `nin`, `ina`, `nina` | Array membership | |
|
package/dist/index.cjs
CHANGED
|
@@ -11,7 +11,7 @@ var DataLoader__default = /*#__PURE__*/_interopDefault(DataLoader);
|
|
|
11
11
|
|
|
12
12
|
// package.json
|
|
13
13
|
var package_default = {
|
|
14
|
-
version: "1.3.4-beta.
|
|
14
|
+
version: "1.3.4-beta.2"};
|
|
15
15
|
|
|
16
16
|
// src/utils.ts
|
|
17
17
|
var REFINE_OPERATOR_MAP = {
|
|
@@ -24,23 +24,26 @@ var REFINE_OPERATOR_MAP = {
|
|
|
24
24
|
gt: "gt",
|
|
25
25
|
lte: "lte",
|
|
26
26
|
gte: "gte",
|
|
27
|
-
// String
|
|
28
|
-
contains: "
|
|
29
|
-
ncontains: "
|
|
27
|
+
// String matching — Taruvi wire suffix matches platform filter_translator.
|
|
28
|
+
contains: "contains",
|
|
29
|
+
ncontains: "ncontains",
|
|
30
30
|
containss: "containss",
|
|
31
31
|
ncontainss: "ncontainss",
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
nendswith: "nendswiths",
|
|
32
|
+
startswith: "startswith",
|
|
33
|
+
nstartswith: "nstartswith",
|
|
34
|
+
endswith: "endswith",
|
|
35
|
+
nendswith: "nendswith",
|
|
37
36
|
startswiths: "startswiths",
|
|
38
37
|
nstartswiths: "nstartswiths",
|
|
39
38
|
endswiths: "endswiths",
|
|
40
39
|
nendswiths: "nendswiths",
|
|
41
|
-
//
|
|
42
|
-
icontains: "
|
|
43
|
-
nicontains: "
|
|
40
|
+
// Refine aliases → platform insensitive tokens
|
|
41
|
+
icontains: "contains",
|
|
42
|
+
nicontains: "ncontains",
|
|
43
|
+
istartswith: "startswith",
|
|
44
|
+
nistartswith: "nstartswith",
|
|
45
|
+
iendswith: "endswith",
|
|
46
|
+
niendswith: "nendswith",
|
|
44
47
|
// Array / membership
|
|
45
48
|
in: "in",
|
|
46
49
|
nin: "nin",
|
|
@@ -101,6 +104,66 @@ function isLogicalFilter(filter) {
|
|
|
101
104
|
function isFieldFilter(filter) {
|
|
102
105
|
return typeof filter === "object" && filter !== null && "field" in filter && "operator" in filter && typeof filter.field === "string" && typeof filter.operator === "string";
|
|
103
106
|
}
|
|
107
|
+
function isFlatFilterList(filters) {
|
|
108
|
+
if (!Array.isArray(filters)) return false;
|
|
109
|
+
return filters.every((f) => {
|
|
110
|
+
if (!isFieldFilter(f)) return false;
|
|
111
|
+
const leaf = f;
|
|
112
|
+
if (leaf.value === void 0 || leaf.value === null && leaf.operator !== "null") {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (REFINE_OPERATOR_MAP[leaf.operator] === void 0) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function isLogicalCrudFilter(filters) {
|
|
122
|
+
return typeof filters === "object" && filters !== null && !Array.isArray(filters) && isLogicalFilter(filters);
|
|
123
|
+
}
|
|
124
|
+
function normalizeTaruviListFilters(filters) {
|
|
125
|
+
if (filters === void 0 || filters === null) return void 0;
|
|
126
|
+
if (isLogicalCrudFilter(filters)) return filters;
|
|
127
|
+
if (isFlatFilterList(filters)) return filters;
|
|
128
|
+
if (!Array.isArray(filters) || filters.length === 0) return void 0;
|
|
129
|
+
if (filters.length === 1 && isLogicalFilter(filters[0])) {
|
|
130
|
+
return filters[0];
|
|
131
|
+
}
|
|
132
|
+
if (filters.every(isFieldFilter)) {
|
|
133
|
+
return filters;
|
|
134
|
+
}
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
function collectFlatLeaves(filters) {
|
|
138
|
+
if (!filters?.length) return [];
|
|
139
|
+
const leaves = [];
|
|
140
|
+
const walk = (group) => {
|
|
141
|
+
for (const filter of group) {
|
|
142
|
+
if (isLogicalFilter(filter)) {
|
|
143
|
+
if (filter.operator === "or") return false;
|
|
144
|
+
if (!walk(filter.value)) return false;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!isFieldFilter(filter)) return false;
|
|
148
|
+
const leaf = filter;
|
|
149
|
+
if (leaf.value === void 0 || leaf.value === null && leaf.operator !== "null") {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (REFINE_OPERATOR_MAP[leaf.operator] === void 0) {
|
|
153
|
+
console.warn(`Unknown Refine operator: ${leaf.operator}`);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
leaves.push({
|
|
157
|
+
field: leaf.field,
|
|
158
|
+
operator: leaf.operator,
|
|
159
|
+
value: leaf.value
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
};
|
|
164
|
+
if (!walk(filters)) return null;
|
|
165
|
+
return leaves;
|
|
166
|
+
}
|
|
104
167
|
function refineOperatorToBackendKey(operator) {
|
|
105
168
|
const suffix = REFINE_OPERATOR_MAP[operator];
|
|
106
169
|
if (suffix === void 0) return operator;
|
|
@@ -194,6 +257,18 @@ function convertRefineFiltersToBackendTree(filters) {
|
|
|
194
257
|
}
|
|
195
258
|
return [{ operator: "and", value: nodes }];
|
|
196
259
|
}
|
|
260
|
+
function convertLogicalFilterToBackendTree(filter) {
|
|
261
|
+
const node = crudFilterToBackendNodeOrNull(filter);
|
|
262
|
+
if (!node || !isLogicalBackendNode(node)) return null;
|
|
263
|
+
return [node];
|
|
264
|
+
}
|
|
265
|
+
function encodeFlatFilterListToParams(leaves) {
|
|
266
|
+
const params = {};
|
|
267
|
+
for (const leaf of leaves) {
|
|
268
|
+
encodeLeafFlat(leaf.field, leaf.operator, leaf.value, params);
|
|
269
|
+
}
|
|
270
|
+
return params;
|
|
271
|
+
}
|
|
197
272
|
function convertRefineFiltersFlattened(filters) {
|
|
198
273
|
if (!filters || filters.length === 0) return {};
|
|
199
274
|
const params = {};
|
|
@@ -336,11 +411,38 @@ function applyAggregations(query, meta) {
|
|
|
336
411
|
}
|
|
337
412
|
return result;
|
|
338
413
|
}
|
|
414
|
+
function applyFlatFilterList(query, leaves) {
|
|
415
|
+
let result = query;
|
|
416
|
+
for (const { field, operator, value } of leaves) {
|
|
417
|
+
const backendOp = refineOperatorToBackendKey(operator);
|
|
418
|
+
const formatted = formatRefineLeafValue(operator, value);
|
|
419
|
+
result = result.filters(
|
|
420
|
+
field,
|
|
421
|
+
backendOp,
|
|
422
|
+
formatted
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
339
427
|
function applyFilters(query, filters) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
428
|
+
const normalized = normalizeTaruviListFilters(filters);
|
|
429
|
+
if (normalized === void 0) {
|
|
430
|
+
if (Array.isArray(filters) && filters.length > 0) {
|
|
431
|
+
const tree = convertRefineFiltersToBackendTree(filters);
|
|
432
|
+
if (tree) return query.filters(tree);
|
|
433
|
+
}
|
|
434
|
+
return query;
|
|
435
|
+
}
|
|
436
|
+
if (isFlatFilterList(normalized)) {
|
|
437
|
+
if (normalized.length === 0) return query;
|
|
438
|
+
return applyFlatFilterList(query, normalized);
|
|
439
|
+
}
|
|
440
|
+
if (isLogicalCrudFilter(normalized)) {
|
|
441
|
+
const tree = convertLogicalFilterToBackendTree(normalized);
|
|
442
|
+
if (!tree) return query;
|
|
443
|
+
return query.filters(tree);
|
|
444
|
+
}
|
|
445
|
+
return query;
|
|
344
446
|
}
|
|
345
447
|
function applySorters(query, sorters) {
|
|
346
448
|
const ordering = convertRefineSorters(sorters);
|
|
@@ -362,6 +464,16 @@ function applyAllowedActions(query, meta) {
|
|
|
362
464
|
if (!meta?.allowedActions?.length) return query;
|
|
363
465
|
return query.allowedActions(meta.allowedActions);
|
|
364
466
|
}
|
|
467
|
+
function applySearchAndFields(query, meta) {
|
|
468
|
+
if (!meta) return query;
|
|
469
|
+
let result = query;
|
|
470
|
+
const search = meta.search?.trim();
|
|
471
|
+
if (search) result = result.search(search);
|
|
472
|
+
const select = meta.select;
|
|
473
|
+
const fields = typeof select === "string" ? select.trim() : Array.isArray(select) ? select.map(String).join(",") : "";
|
|
474
|
+
if (fields) result = result.fields(fields);
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
365
477
|
function isGraphQuery(meta) {
|
|
366
478
|
return !!(meta?.format || meta?.graph_types || meta?.include || meta?.depth);
|
|
367
479
|
}
|
|
@@ -399,6 +511,7 @@ function dataProvider(client) {
|
|
|
399
511
|
query = applyPagination(query, pagination);
|
|
400
512
|
query = applyPopulate(query, taruviMeta);
|
|
401
513
|
query = applyAggregations(query, taruviMeta);
|
|
514
|
+
query = applySearchAndFields(query, taruviMeta);
|
|
402
515
|
query = applyAllowedActions(query, taruviMeta);
|
|
403
516
|
const response = await query.execute();
|
|
404
517
|
return { data: response.data, total: response.total };
|
|
@@ -1249,15 +1362,21 @@ exports.applyRefineQueryParamsToDatabase = applyRefineQueryParamsToDatabase;
|
|
|
1249
1362
|
exports.authProvider = authProvider;
|
|
1250
1363
|
exports.buildQueryString = buildQueryString;
|
|
1251
1364
|
exports.buildRefineQueryParams = buildRefineQueryParams;
|
|
1365
|
+
exports.collectFlatLeaves = collectFlatLeaves;
|
|
1366
|
+
exports.convertLogicalFilterToBackendTree = convertLogicalFilterToBackendTree;
|
|
1252
1367
|
exports.convertRefineFilters = convertRefineFilters;
|
|
1253
1368
|
exports.convertRefineFiltersToBackendTree = convertRefineFiltersToBackendTree;
|
|
1254
1369
|
exports.convertRefinePagination = convertRefinePagination;
|
|
1255
1370
|
exports.convertRefineSorters = convertRefineSorters;
|
|
1256
1371
|
exports.dataProvider = dataProvider;
|
|
1257
1372
|
exports.encodeCrudFilterBracket = encodeCrudFilterBracket;
|
|
1373
|
+
exports.encodeFlatFilterListToParams = encodeFlatFilterListToParams;
|
|
1258
1374
|
exports.formatRefineLeafValue = formatRefineLeafValue;
|
|
1259
1375
|
exports.functionsDataProvider = functionsDataProvider;
|
|
1260
1376
|
exports.handleError = handleError;
|
|
1377
|
+
exports.isFlatFilterList = isFlatFilterList;
|
|
1378
|
+
exports.isLogicalCrudFilter = isLogicalCrudFilter;
|
|
1379
|
+
exports.normalizeTaruviListFilters = normalizeTaruviListFilters;
|
|
1261
1380
|
exports.refineOperatorToBackendKey = refineOperatorToBackendKey;
|
|
1262
1381
|
exports.storageDataProvider = storageDataProvider;
|
|
1263
1382
|
exports.userDataProvider = userDataProvider;
|