@raphiniert/ra-data-postgrest 2.0.0-alpha.0 → 2.0.0-alpha.3

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/src/urlBuilder.ts CHANGED
@@ -44,13 +44,21 @@ const postgrestOperators = [
44
44
  'and',
45
45
  ] as const;
46
46
 
47
- export type PostgRestOperator = typeof postgrestOperators[number];
47
+ type ParsedFiltersResult = {
48
+ filter: any;
49
+ select: any;
50
+ };
51
+
52
+ export type PostgRestOperator = (typeof postgrestOperators)[number];
48
53
 
49
54
  export const parseFilters = (
50
- filter: Record<string, any>,
55
+ params: any,
51
56
  defaultListOp: PostgRestOperator
52
- ) => {
53
- let result = {};
57
+ ): Partial<ParsedFiltersResult> => {
58
+ const { filter, meta = {} } = params;
59
+
60
+ let result: Partial<ParsedFiltersResult> = {};
61
+ result.filter = {};
54
62
  Object.keys(filter).forEach(function (key) {
55
63
  // key: the name of the object key
56
64
 
@@ -64,33 +72,72 @@ export const parseFilters = (
64
72
  if (['like', 'ilike'].includes(operation)) {
65
73
  // we split the search term in words
66
74
  values = filter[key].trim().split(/\s+/);
75
+ }
76
+ // CASE: Logical operator
77
+ else if (['or', 'and'].includes(operation)) {
78
+ // we extract each value entries and make it dot separated string.
79
+ const { filter: subFilter } = parseFilters(
80
+ { filter: filter[key] },
81
+ defaultListOp
82
+ );
83
+
84
+ // something like { "age@lt": 18 } and { "age@gt": 21 }
85
+ const filterExpressions: string[] = [];
86
+ Object.entries(subFilter).forEach(([op, val]) => {
87
+ if (Array.isArray(val))
88
+ filterExpressions.push(...val.map(v => [op, v].join('.')));
89
+ else filterExpressions.push([op, val].join('.'));
90
+ });
91
+
92
+ // finally we flatten all as single string and enclose with bracket.
93
+ values = [`(${filterExpressions.join(',')})`];
67
94
  } else {
68
95
  values = [filter[key]];
69
96
  }
70
97
 
71
98
  values.forEach(value => {
72
- // if operator is intentionally blank, rpc syntax
73
- let op = operation.includes('like')
74
- ? `${operation}.*${value}*`
75
- : operation.length == 0
76
- ? `${value}`
77
- : `${operation}.${value}`;
78
-
79
- if (result[splitKey[0]] === undefined) {
80
- // first operator for the key, we add it to the dict
81
- result[splitKey[0]] = op;
99
+ let op: string = (() => {
100
+ // if operator is intentionally blank, rpc syntax
101
+ if (operation.length === 0) return `${value}`;
102
+
103
+ if (operation.includes('like'))
104
+ return `${operation}.*${value}*`;
105
+ if (['and', 'or'].includes(operation)) return `${value}`;
106
+ if (['cs', 'cd'].includes(operation))
107
+ return `${operation}.{${value}}`;
108
+ return `${operation}.${value}`;
109
+ })();
110
+
111
+ // If resulting filter haven't contains the fieldname, then add it.
112
+ if (result.filter[splitKey[0]] === undefined) {
113
+ // first operator for the key,
114
+ if (['and', 'or'].includes(operation)) {
115
+ result.filter[operation] = op;
116
+ } else {
117
+ // we add it to the dict
118
+ result.filter[splitKey[0]] = op;
119
+ }
82
120
  } else {
83
121
  if (!Array.isArray(result[splitKey[0]])) {
84
122
  // second operator, we transform to an array
85
- result[splitKey[0]] = [result[splitKey[0]], op];
123
+ result.filter[splitKey[0]] = [
124
+ result.filter[splitKey[0]],
125
+ op,
126
+ ];
86
127
  } else {
87
128
  // third and subsequent, we add to array
88
- result[splitKey[0]].push(op);
129
+ result.filter[splitKey[0]].push(op);
89
130
  }
90
131
  }
91
132
  });
92
133
  });
93
134
 
135
+ if (meta?.columns) {
136
+ result.select = Array.isArray(meta.columns)
137
+ ? meta.columns.join(',')
138
+ : meta.columns;
139
+ }
140
+
94
141
  return result;
95
142
  };
96
143
 
@@ -140,8 +187,10 @@ export const isCompoundKey = (primaryKey: PrimaryKey): Boolean => {
140
187
  export const getQuery = (
141
188
  primaryKey: PrimaryKey,
142
189
  ids: Identifier | Array<Identifier>,
143
- resource: string
144
- ): string => {
190
+ resource: string,
191
+ meta: any = null
192
+ ): any => {
193
+ let result: any = {};
145
194
  if (Array.isArray(ids) && ids.length > 1) {
146
195
  // no standardized query with multiple ids possible for rpc endpoints which are api-exposed database functions
147
196
  if (resource.startsWith('rpc/')) {
@@ -153,17 +202,18 @@ export const getQuery = (
153
202
  }
154
203
 
155
204
  if (isCompoundKey(primaryKey)) {
156
- // TODO: Should be URL encoded
157
- return `or=(${ids.map(id => {
158
- const primaryKeyParams = decodeId(id, primaryKey);
159
- return `and(${primaryKey
160
- .map((key, i) => `${key}.eq.${primaryKeyParams[i]}`)
161
- .join(',')})`;
162
- })})`;
205
+ result = {
206
+ or: `(${ids.map(id => {
207
+ const primaryKeyParams = decodeId(id, primaryKey);
208
+ return `and(${primaryKey
209
+ .map((key, i) => `${key}.eq.${primaryKeyParams[i]}`)
210
+ .join(',')})`;
211
+ })})`,
212
+ };
163
213
  } else {
164
- return new URLSearchParams({
214
+ result = {
165
215
  [primaryKey[0]]: `in.(${ids.join(',')})`,
166
- }).toString();
216
+ };
167
217
  }
168
218
  } else {
169
219
  // if ids is one Identifier
@@ -171,27 +221,34 @@ export const getQuery = (
171
221
  const primaryKeyParams = decodeId(id, primaryKey);
172
222
 
173
223
  if (isCompoundKey(primaryKey)) {
174
- if (resource.startsWith('rpc/'))
175
- // TODO: Should be URL encoded
176
- return `${primaryKey
177
- .map(
178
- (key: string, i: any) => `${key}=${primaryKeyParams[i]}`
179
- )
180
- .join('&')}`;
181
- // TODO: Should be URL encoded
182
- else
183
- return `and=(${primaryKey
184
- .map(
224
+ if (resource.startsWith('rpc/')) {
225
+ result = {};
226
+ primaryKey.map(
227
+ (key: string, i: any) =>
228
+ (result[key] = `${primaryKeyParams[i]}`)
229
+ );
230
+ } else {
231
+ result = {
232
+ and: `(${primaryKey.map(
185
233
  (key: string, i: any) =>
186
234
  `${key}.eq.${primaryKeyParams[i]}`
187
- )
188
- .join(',')})`;
235
+ )})`,
236
+ };
237
+ }
189
238
  } else {
190
- return new URLSearchParams([
191
- [primaryKey[0], `eq.${id}`],
192
- ]).toString();
239
+ result = {
240
+ [primaryKey[0]]: `eq.${id}`,
241
+ };
193
242
  }
194
243
  }
244
+
245
+ if (meta && meta.columns) {
246
+ result.select = Array.isArray(meta.columns)
247
+ ? meta.columns.join(',')
248
+ : meta.columns;
249
+ }
250
+
251
+ return result;
195
252
  };
196
253
 
197
254
  export const getKeyData = (primaryKey: PrimaryKey, data: object): object => {