@taruvi/refine-providers 1.3.3 → 1.3.4-beta.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/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import DataLoader from 'dataloader';
5
5
 
6
6
  // package.json
7
7
  var package_default = {
8
- version: "1.3.3"};
8
+ version: "1.3.4-beta.1"};
9
9
 
10
10
  // src/utils.ts
11
11
  var REFINE_OPERATOR_MAP = {
@@ -18,65 +18,306 @@ var REFINE_OPERATOR_MAP = {
18
18
  gt: "gt",
19
19
  lte: "lte",
20
20
  gte: "gte",
21
- // String operations (case-sensitive)
21
+ // String matching — Taruvi wire suffix matches platform filter_translator.
22
22
  contains: "contains",
23
23
  ncontains: "ncontains",
24
+ containss: "containss",
25
+ ncontainss: "ncontainss",
24
26
  startswith: "startswith",
25
27
  nstartswith: "nstartswith",
26
28
  endswith: "endswith",
27
29
  nendswith: "nendswith",
28
- // String operations (case-insensitive)
29
- containss: "icontains",
30
- ncontainss: "nicontains",
31
- startswiths: "istartswith",
32
- nstartswiths: "nistartswith",
33
- endswiths: "iendswith",
34
- nendswiths: "niendswith",
35
- // Array operations
30
+ startswiths: "startswiths",
31
+ nstartswiths: "nstartswiths",
32
+ endswiths: "endswiths",
33
+ nendswiths: "nendswiths",
34
+ // Refine aliases → platform insensitive tokens
35
+ icontains: "contains",
36
+ nicontains: "ncontains",
37
+ istartswith: "startswith",
38
+ nistartswith: "nstartswith",
39
+ iendswith: "endswith",
40
+ niendswith: "nendswith",
41
+ // Array / membership
36
42
  in: "in",
37
43
  nin: "nin",
44
+ ina: "ina",
45
+ nina: "nina",
38
46
  // Null checks
39
47
  null: "null",
40
48
  nnull: "nnull",
41
49
  // Range
42
50
  between: "between",
43
- nbetween: "nbetween"
51
+ nbetween: "nbetween",
52
+ // PostgreSQL array ops (pass-through suffix names)
53
+ acontains: "acontains",
54
+ nacontains: "nacontains",
55
+ acontainedby: "acontainedby",
56
+ nacontainedby: "nacontainedby",
57
+ aoverlap: "aoverlap",
58
+ naoverlap: "naoverlap",
59
+ aelement: "aelement",
60
+ naelement: "naelement",
61
+ // PostgreSQL range column ops
62
+ rcontains: "rcontains",
63
+ rcontainedby: "rcontainedby",
64
+ roverlaps: "roverlaps",
65
+ radjacent: "radjacent",
66
+ rstrictleft: "rstrictleft",
67
+ rstrictright: "rstrictright",
68
+ // Raw pattern / field search
69
+ like: "like",
70
+ ilike: "ilike",
71
+ search: "search"
44
72
  };
45
- function convertRefineFilters(filters) {
73
+ var COMMA_VALUE_OPERATORS = /* @__PURE__ */ new Set([
74
+ "in",
75
+ "nin",
76
+ "ina",
77
+ "nina",
78
+ "between",
79
+ "nbetween",
80
+ "acontains",
81
+ "nacontains",
82
+ "acontainedby",
83
+ "nacontainedby",
84
+ "aoverlap",
85
+ "naoverlap",
86
+ "aelement",
87
+ "naelement",
88
+ "rcontains",
89
+ "rcontainedby",
90
+ "roverlaps",
91
+ "radjacent",
92
+ "rstrictleft",
93
+ "rstrictright"
94
+ ]);
95
+ function isLogicalFilter(filter) {
96
+ return typeof filter === "object" && filter !== null && "operator" in filter && (filter.operator === "and" || filter.operator === "or") && "value" in filter && Array.isArray(filter.value);
97
+ }
98
+ function isFieldFilter(filter) {
99
+ return typeof filter === "object" && filter !== null && "field" in filter && "operator" in filter && typeof filter.field === "string" && typeof filter.operator === "string";
100
+ }
101
+ function isFlatFilterList(filters) {
102
+ if (!Array.isArray(filters)) return false;
103
+ return filters.every((f) => {
104
+ if (!isFieldFilter(f)) return false;
105
+ const leaf = f;
106
+ if (leaf.value === void 0 || leaf.value === null && leaf.operator !== "null") {
107
+ return false;
108
+ }
109
+ if (REFINE_OPERATOR_MAP[leaf.operator] === void 0) {
110
+ return false;
111
+ }
112
+ return true;
113
+ });
114
+ }
115
+ function isLogicalCrudFilter(filters) {
116
+ return typeof filters === "object" && filters !== null && !Array.isArray(filters) && isLogicalFilter(filters);
117
+ }
118
+ function normalizeTaruviListFilters(filters) {
119
+ if (filters === void 0 || filters === null) return void 0;
120
+ if (isLogicalCrudFilter(filters)) return filters;
121
+ if (isFlatFilterList(filters)) return filters;
122
+ if (!Array.isArray(filters) || filters.length === 0) return void 0;
123
+ if (filters.length === 1 && isLogicalFilter(filters[0])) {
124
+ return filters[0];
125
+ }
126
+ if (filters.every(isFieldFilter)) {
127
+ return filters;
128
+ }
129
+ return void 0;
130
+ }
131
+ function collectFlatLeaves(filters) {
132
+ if (!filters?.length) return [];
133
+ const leaves = [];
134
+ const walk = (group) => {
135
+ for (const filter of group) {
136
+ if (isLogicalFilter(filter)) {
137
+ if (filter.operator === "or") return false;
138
+ if (!walk(filter.value)) return false;
139
+ continue;
140
+ }
141
+ if (!isFieldFilter(filter)) return false;
142
+ const leaf = filter;
143
+ if (leaf.value === void 0 || leaf.value === null && leaf.operator !== "null") {
144
+ continue;
145
+ }
146
+ if (REFINE_OPERATOR_MAP[leaf.operator] === void 0) {
147
+ console.warn(`Unknown Refine operator: ${leaf.operator}`);
148
+ return false;
149
+ }
150
+ leaves.push({
151
+ field: leaf.field,
152
+ operator: leaf.operator,
153
+ value: leaf.value
154
+ });
155
+ }
156
+ return true;
157
+ };
158
+ if (!walk(filters)) return null;
159
+ return leaves;
160
+ }
161
+ function refineOperatorToBackendKey(operator) {
162
+ const suffix = REFINE_OPERATOR_MAP[operator];
163
+ if (suffix === void 0) return operator;
164
+ return suffix === "" ? "eq" : suffix;
165
+ }
166
+ function formatRefineLeafValue(operator, value) {
167
+ if (COMMA_VALUE_OPERATORS.has(operator)) {
168
+ return Array.isArray(value) ? value.join(",") : String(value);
169
+ }
170
+ if (operator === "null" || operator === "nnull") {
171
+ return "true";
172
+ }
173
+ return String(value);
174
+ }
175
+ function encodeLeafFlat(field, operator, value, params) {
176
+ if (value === void 0 || value === null && operator !== "null") {
177
+ return;
178
+ }
179
+ const suffix = REFINE_OPERATOR_MAP[operator];
180
+ if (suffix === void 0) {
181
+ console.warn(`Unknown Refine operator: ${operator}`);
182
+ return;
183
+ }
184
+ const paramKey = suffix ? `${field}__${suffix}` : String(field);
185
+ params[paramKey] = formatRefineLeafValue(operator, value);
186
+ }
187
+ function encodeCrudFilterBracket(filter, path, out) {
188
+ if (isLogicalFilter(filter)) {
189
+ const op = filter.operator;
190
+ out[`${path}[operator]`] = op;
191
+ const children = filter.value;
192
+ children.forEach((child, i) => {
193
+ encodeCrudFilterBracket(child, `${path}[value][${i}]`, out);
194
+ });
195
+ return;
196
+ }
197
+ if (!isFieldFilter(filter)) {
198
+ return;
199
+ }
200
+ const leaf = filter;
201
+ const { field, operator, value } = leaf;
202
+ if (value === void 0 || value === null && operator !== "null") {
203
+ return;
204
+ }
205
+ const suffix = REFINE_OPERATOR_MAP[operator];
206
+ if (suffix === void 0) {
207
+ console.warn(`Unknown Refine operator: ${operator}`);
208
+ return;
209
+ }
210
+ out[`${path}[field]`] = field;
211
+ out[`${path}[operator]`] = refineOperatorToBackendKey(operator);
212
+ out[`${path}[value]`] = formatRefineLeafValue(operator, value);
213
+ }
214
+ function isLogicalBackendNode(n) {
215
+ return !("field" in n) && (n.operator === "and" || n.operator === "or");
216
+ }
217
+ function jsonLeafValue(operator, value) {
218
+ if (operator === "null" || operator === "nnull") return true;
219
+ return value;
220
+ }
221
+ function crudFilterToBackendNodeOrNull(filter) {
222
+ if (isLogicalFilter(filter)) {
223
+ const children = filter.value.map(crudFilterToBackendNodeOrNull).filter((n) => n !== null);
224
+ if (children.length === 0) return null;
225
+ return { operator: filter.operator, value: children };
226
+ }
227
+ if (isFieldFilter(filter)) {
228
+ const leaf = filter;
229
+ if (leaf.value === void 0 || leaf.value === null && leaf.operator !== "null") {
230
+ return null;
231
+ }
232
+ if (REFINE_OPERATOR_MAP[leaf.operator] === void 0) {
233
+ console.warn(`Unknown Refine operator: ${leaf.operator}`);
234
+ return null;
235
+ }
236
+ const backendOp = refineOperatorToBackendKey(leaf.operator);
237
+ return {
238
+ field: leaf.field,
239
+ operator: backendOp,
240
+ value: jsonLeafValue(leaf.operator, leaf.value)
241
+ };
242
+ }
243
+ return null;
244
+ }
245
+ function convertRefineFiltersToBackendTree(filters) {
246
+ if (!filters?.length) return null;
247
+ const nodes = filters.map(crudFilterToBackendNodeOrNull).filter((n) => n !== null);
248
+ if (nodes.length === 0) return null;
249
+ if (nodes.length === 1 && isLogicalBackendNode(nodes[0])) {
250
+ return [nodes[0]];
251
+ }
252
+ return [{ operator: "and", value: nodes }];
253
+ }
254
+ function convertLogicalFilterToBackendTree(filter) {
255
+ const node = crudFilterToBackendNodeOrNull(filter);
256
+ if (!node || !isLogicalBackendNode(node)) return null;
257
+ return [node];
258
+ }
259
+ function encodeFlatFilterListToParams(leaves) {
260
+ const params = {};
261
+ for (const leaf of leaves) {
262
+ encodeLeafFlat(leaf.field, leaf.operator, leaf.value, params);
263
+ }
264
+ return params;
265
+ }
266
+ function convertRefineFiltersFlattened(filters) {
46
267
  if (!filters || filters.length === 0) return {};
47
268
  const params = {};
48
269
  for (const filter of filters) {
49
- if ("operator" in filter && (filter.operator === "and" || filter.operator === "or")) {
270
+ if (isLogicalFilter(filter)) {
50
271
  if (filter.value && Array.isArray(filter.value)) {
51
- const nested = convertRefineFilters(filter.value);
272
+ const nested = convertRefineFiltersFlattened(
273
+ filter.value
274
+ );
52
275
  Object.assign(params, nested);
53
276
  }
54
277
  continue;
55
278
  }
56
- if ("field" in filter && filter.field && filter.operator) {
57
- const { field, operator, value } = filter;
58
- if (value === void 0 || value === null && operator !== "null") {
59
- continue;
60
- }
61
- const suffix = REFINE_OPERATOR_MAP[operator];
62
- if (suffix === void 0) {
63
- console.warn(`Unknown Refine operator: ${operator}`);
64
- continue;
65
- }
66
- const paramKey = suffix ? `${field}__${suffix}` : String(field);
67
- if (operator === "in" || operator === "nin") {
68
- params[paramKey] = Array.isArray(value) ? value.join(",") : String(value);
69
- } else if (operator === "between" || operator === "nbetween") {
70
- params[paramKey] = Array.isArray(value) ? value.join(",") : String(value);
71
- } else if (operator === "null" || operator === "nnull") {
72
- params[paramKey] = "true";
73
- } else {
74
- params[paramKey] = String(value);
75
- }
279
+ if (isFieldFilter(filter)) {
280
+ const leaf = filter;
281
+ encodeLeafFlat(leaf.field, leaf.operator, leaf.value, params);
76
282
  }
77
283
  }
78
284
  return params;
79
285
  }
286
+ function convertRefineFilters(filters, options) {
287
+ if (!filters || filters.length === 0) return {};
288
+ if (options?.logicalEncoding === "flatten") {
289
+ return convertRefineFiltersFlattened(filters);
290
+ }
291
+ const hasLogical = filters.some(isLogicalFilter);
292
+ if (!hasLogical) {
293
+ const params = {};
294
+ for (const filter of filters) {
295
+ if (isFieldFilter(filter)) {
296
+ const leaf = filter;
297
+ encodeLeafFlat(leaf.field, leaf.operator, leaf.value, params);
298
+ }
299
+ }
300
+ return params;
301
+ }
302
+ if (filters.length === 1 && isLogicalFilter(filters[0])) {
303
+ const out2 = {};
304
+ encodeCrudFilterBracket(filters[0], "filters[0]", out2);
305
+ return out2;
306
+ }
307
+ const out = {};
308
+ out["filters[0][operator]"] = "and";
309
+ filters.forEach((f, i) => {
310
+ encodeCrudFilterBracket(f, `filters[0][value][${i}]`, out);
311
+ });
312
+ return out;
313
+ }
314
+ function applyRefineQueryParamsToDatabase(query, params) {
315
+ let result = query;
316
+ for (const [key, val] of Object.entries(params)) {
317
+ result = result.filters(key, "eq", val);
318
+ }
319
+ return result;
320
+ }
80
321
  function convertRefineSorters(sorters) {
81
322
  if (!sorters || sorters.length === 0) return void 0;
82
323
  return sorters.map((sort) => sort.order === "desc" ? `-${sort.field}` : sort.field).join(",");
@@ -132,16 +373,7 @@ function formatHaving(having) {
132
373
  continue;
133
374
  }
134
375
  const paramKey = suffix ? `${field}__${suffix}` : String(field);
135
- let paramValue;
136
- if (operator === "in" || operator === "nin") {
137
- paramValue = Array.isArray(value) ? value.join(",") : String(value);
138
- } else if (operator === "between" || operator === "nbetween") {
139
- paramValue = Array.isArray(value) ? value.join(",") : String(value);
140
- } else if (operator === "null" || operator === "nnull") {
141
- paramValue = "true";
142
- } else {
143
- paramValue = String(value);
144
- }
376
+ const paramValue = formatRefineLeafValue(operator, value);
145
377
  params.push(`${paramKey}=${paramValue}`);
146
378
  }
147
379
  }
@@ -173,45 +405,42 @@ function applyAggregations(query, meta) {
173
405
  }
174
406
  return result;
175
407
  }
176
- function applyFilters(query, filters) {
177
- if (!filters || filters.length === 0) return query;
408
+ function applyFlatFilterList(query, leaves) {
178
409
  let result = query;
179
- for (const filter of filters) {
180
- if ("operator" in filter && (filter.operator === "and" || filter.operator === "or")) {
181
- if (filter.value && Array.isArray(filter.value)) {
182
- result = applyFilters(result, filter.value);
183
- }
184
- continue;
185
- }
186
- if ("field" in filter && filter.field && filter.operator) {
187
- const { field, operator, value } = filter;
188
- if (value === void 0 || value === null && operator !== "null") continue;
189
- const suffix = REFINE_OPERATOR_MAP[operator];
190
- if (suffix === void 0) {
191
- console.warn(`Unknown Refine operator: ${operator}`);
192
- continue;
193
- }
194
- const paramKey = suffix ? `${field}__${suffix}` : String(field);
195
- let paramValue;
196
- if (operator === "in" || operator === "nin" || operator === "between" || operator === "nbetween") {
197
- paramValue = Array.isArray(value) ? value.join(",") : String(value);
198
- } else if (operator === "null" || operator === "nnull") {
199
- paramValue = "true";
200
- } else {
201
- paramValue = String(value);
202
- }
203
- result = result.filter(paramKey, "eq", paramValue);
204
- }
410
+ for (const { field, operator, value } of leaves) {
411
+ const backendOp = refineOperatorToBackendKey(operator);
412
+ const formatted = formatRefineLeafValue(operator, value);
413
+ result = result.filters(
414
+ field,
415
+ backendOp,
416
+ formatted
417
+ );
205
418
  }
206
419
  return result;
207
420
  }
208
- function applySorters(query, sorters) {
209
- if (!sorters || sorters.length === 0) return query;
210
- let result = query;
211
- for (const sorter of sorters) {
212
- result = result.sort(sorter.field, sorter.order === "desc" ? "desc" : "asc");
421
+ function applyFilters(query, filters) {
422
+ const normalized = normalizeTaruviListFilters(filters);
423
+ if (normalized === void 0) {
424
+ if (Array.isArray(filters) && filters.length > 0) {
425
+ const tree = convertRefineFiltersToBackendTree(filters);
426
+ if (tree) return query.filters(tree);
427
+ }
428
+ return query;
213
429
  }
214
- return result;
430
+ if (isFlatFilterList(normalized)) {
431
+ if (normalized.length === 0) return query;
432
+ return applyFlatFilterList(query, normalized);
433
+ }
434
+ if (isLogicalCrudFilter(normalized)) {
435
+ const tree = convertLogicalFilterToBackendTree(normalized);
436
+ if (!tree) return query;
437
+ return query.filters(tree);
438
+ }
439
+ return query;
440
+ }
441
+ function applySorters(query, sorters) {
442
+ const ordering = convertRefineSorters(sorters);
443
+ return ordering ? query.orderBy(ordering) : query;
215
444
  }
216
445
  function applyPagination(query, pagination) {
217
446
  if (!pagination || pagination.mode === "off") return query;
@@ -299,7 +528,7 @@ function dataProvider(client) {
299
528
  }
300
529
  const idColumn = getIdColumn(taruviMeta);
301
530
  let query = new Database(client).from(tableName);
302
- query = query.filter(idColumn, "in", ids.map(String));
531
+ query = query.filters(idColumn, "in", ids.map(String));
303
532
  query = applyPopulate(query, taruviMeta);
304
533
  const response = await query.execute();
305
534
  return { data: response.data };
@@ -416,7 +645,7 @@ function storageDataProvider(client) {
416
645
  const getBucketName = (resource, meta) => meta?.bucketName ?? resource;
417
646
  const buildFilters = (params) => {
418
647
  const filters = {
419
- ...convertRefineFilters(params.filters),
648
+ ...convertRefineFilters(params.filters, { logicalEncoding: "flatten" }),
420
649
  ...convertRefinePagination(params.pagination)
421
650
  };
422
651
  const ordering = convertRefineSorters(params.sorters);
@@ -924,20 +1153,27 @@ function analyticsDataProvider(client) {
924
1153
  var _cachedUser = null;
925
1154
  function authProvider(client) {
926
1155
  const auth = new Auth(client);
927
- function redirectToLogin() {
928
- _cachedUser = null;
929
- auth.login();
930
- }
931
1156
  return {
932
- login: async () => {
933
- if (auth.hasToken()) {
1157
+ login: async (params = {}) => {
1158
+ const { callbackUrl, redirect = true } = params;
1159
+ if (auth.isUserAuthenticated()) {
1160
+ return {
1161
+ success: true,
1162
+ redirectTo: callbackUrl || "/"
1163
+ };
1164
+ }
1165
+ if (redirect) {
1166
+ auth.login(callbackUrl);
934
1167
  return {
935
1168
  success: true
936
1169
  };
937
1170
  }
938
- redirectToLogin();
939
1171
  return {
940
- success: true
1172
+ success: false,
1173
+ error: {
1174
+ name: "LoginError",
1175
+ message: "Login failed. Please try again."
1176
+ }
941
1177
  };
942
1178
  },
943
1179
  logout: async (params = {}) => {
@@ -950,20 +1186,19 @@ function authProvider(client) {
950
1186
  };
951
1187
  },
952
1188
  check: async () => {
953
- if (!auth.hasToken()) {
954
- return { authenticated: false };
955
- }
956
- const isValid = await auth.isUserAuthenticated();
957
- if (!isValid) {
958
- return { authenticated: false };
1189
+ if (!auth.isUserAuthenticated()) {
1190
+ return { authenticated: false, redirectTo: "/login" };
959
1191
  }
960
1192
  return { authenticated: true };
961
1193
  },
962
1194
  onError: async (error) => {
963
1195
  const status = error?.statusCode || error?.status || error?.response?.status;
964
1196
  if (status === 401) {
965
- redirectToLogin();
966
- return { error };
1197
+ return {
1198
+ logout: true,
1199
+ redirectTo: "/login",
1200
+ error
1201
+ };
967
1202
  }
968
1203
  if (status === 403) {
969
1204
  return { error };
@@ -1102,6 +1337,6 @@ function accessControlProvider(client, options) {
1102
1337
  };
1103
1338
  }
1104
1339
 
1105
- export { REFINE_OPERATOR_MAP, _cachedUser, accessControlProvider, analyticsDataProvider, appDataProvider, authProvider, buildQueryString, buildRefineQueryParams, convertRefineFilters, convertRefinePagination, convertRefineSorters, dataProvider, functionsDataProvider, handleError, storageDataProvider, userDataProvider };
1340
+ export { REFINE_OPERATOR_MAP, _cachedUser, accessControlProvider, analyticsDataProvider, appDataProvider, applyRefineQueryParamsToDatabase, authProvider, buildQueryString, buildRefineQueryParams, collectFlatLeaves, convertLogicalFilterToBackendTree, convertRefineFilters, convertRefineFiltersToBackendTree, convertRefinePagination, convertRefineSorters, dataProvider, encodeCrudFilterBracket, encodeFlatFilterListToParams, formatRefineLeafValue, functionsDataProvider, handleError, isFlatFilterList, isLogicalCrudFilter, normalizeTaruviListFilters, refineOperatorToBackendKey, storageDataProvider, userDataProvider };
1106
1341
  //# sourceMappingURL=index.js.map
1107
1342
  //# sourceMappingURL=index.js.map