@supabase/postgrest-js 1.1.0 → 1.2.0

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.
Files changed (45) hide show
  1. package/dist/main/PostgrestBuilder.d.ts.map +1 -1
  2. package/dist/main/PostgrestBuilder.js +17 -3
  3. package/dist/main/PostgrestBuilder.js.map +1 -1
  4. package/dist/main/PostgrestClient.d.ts +0 -5
  5. package/dist/main/PostgrestClient.d.ts.map +1 -1
  6. package/dist/main/PostgrestClient.js +5 -0
  7. package/dist/main/PostgrestClient.js.map +1 -1
  8. package/dist/main/PostgrestFilterBuilder.d.ts +0 -170
  9. package/dist/main/PostgrestFilterBuilder.d.ts.map +1 -1
  10. package/dist/main/PostgrestFilterBuilder.js +170 -0
  11. package/dist/main/PostgrestFilterBuilder.js.map +1 -1
  12. package/dist/main/PostgrestTransformBuilder.d.ts +0 -16
  13. package/dist/main/PostgrestTransformBuilder.d.ts.map +1 -1
  14. package/dist/main/PostgrestTransformBuilder.js +16 -0
  15. package/dist/main/PostgrestTransformBuilder.js.map +1 -1
  16. package/dist/main/select-query-parser.d.ts +43 -1
  17. package/dist/main/select-query-parser.d.ts.map +1 -1
  18. package/dist/main/version.d.ts +1 -1
  19. package/dist/main/version.js +1 -1
  20. package/dist/module/PostgrestBuilder.d.ts.map +1 -1
  21. package/dist/module/PostgrestBuilder.js +17 -3
  22. package/dist/module/PostgrestBuilder.js.map +1 -1
  23. package/dist/module/PostgrestClient.d.ts +0 -5
  24. package/dist/module/PostgrestClient.d.ts.map +1 -1
  25. package/dist/module/PostgrestClient.js +5 -0
  26. package/dist/module/PostgrestClient.js.map +1 -1
  27. package/dist/module/PostgrestFilterBuilder.d.ts +0 -170
  28. package/dist/module/PostgrestFilterBuilder.d.ts.map +1 -1
  29. package/dist/module/PostgrestFilterBuilder.js +170 -0
  30. package/dist/module/PostgrestFilterBuilder.js.map +1 -1
  31. package/dist/module/PostgrestTransformBuilder.d.ts +0 -16
  32. package/dist/module/PostgrestTransformBuilder.d.ts.map +1 -1
  33. package/dist/module/PostgrestTransformBuilder.js +16 -0
  34. package/dist/module/PostgrestTransformBuilder.js.map +1 -1
  35. package/dist/module/select-query-parser.d.ts +43 -1
  36. package/dist/module/select-query-parser.d.ts.map +1 -1
  37. package/dist/module/version.d.ts +1 -1
  38. package/dist/module/version.js +1 -1
  39. package/package.json +3 -3
  40. package/src/PostgrestBuilder.ts +16 -2
  41. package/src/PostgrestClient.ts +5 -5
  42. package/src/PostgrestFilterBuilder.ts +72 -72
  43. package/src/PostgrestTransformBuilder.ts +8 -8
  44. package/src/select-query-parser.ts +46 -2
  45. package/src/version.ts +1 -1
@@ -30,6 +30,8 @@ export default class PostgrestFilterBuilder<
30
30
  Row extends Record<string, unknown>,
31
31
  Result
32
32
  > extends PostgrestTransformBuilder<Schema, Row, Result> {
33
+ eq<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
34
+ eq(column: string, value: unknown): this
33
35
  /**
34
36
  * Match only rows where `column` is equal to `value`.
35
37
  *
@@ -38,104 +40,107 @@ export default class PostgrestFilterBuilder<
38
40
  * @param column - The column to filter on
39
41
  * @param value - The value to filter with
40
42
  */
41
- eq<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
42
- eq(column: string, value: unknown): this
43
43
  eq(column: string, value: unknown): this {
44
44
  this.url.searchParams.append(column, `eq.${value}`)
45
45
  return this
46
46
  }
47
47
 
48
+ neq<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
49
+ neq(column: string, value: unknown): this
48
50
  /**
49
51
  * Match only rows where `column` is not equal to `value`.
50
52
  *
51
53
  * @param column - The column to filter on
52
54
  * @param value - The value to filter with
53
55
  */
54
- neq<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
55
- neq(column: string, value: unknown): this
56
56
  neq(column: string, value: unknown): this {
57
57
  this.url.searchParams.append(column, `neq.${value}`)
58
58
  return this
59
59
  }
60
60
 
61
+ gt<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
62
+ gt(column: string, value: unknown): this
61
63
  /**
62
64
  * Match only rows where `column` is greater than `value`.
63
65
  *
64
66
  * @param column - The column to filter on
65
67
  * @param value - The value to filter with
66
68
  */
67
- gt<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
68
- gt(column: string, value: unknown): this
69
69
  gt(column: string, value: unknown): this {
70
70
  this.url.searchParams.append(column, `gt.${value}`)
71
71
  return this
72
72
  }
73
73
 
74
+ gte<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
75
+ gte(column: string, value: unknown): this
74
76
  /**
75
77
  * Match only rows where `column` is greater than or equal to `value`.
76
78
  *
77
79
  * @param column - The column to filter on
78
80
  * @param value - The value to filter with
79
81
  */
80
- gte<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
81
- gte(column: string, value: unknown): this
82
82
  gte(column: string, value: unknown): this {
83
83
  this.url.searchParams.append(column, `gte.${value}`)
84
84
  return this
85
85
  }
86
86
 
87
+ lt<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
88
+ lt(column: string, value: unknown): this
87
89
  /**
88
90
  * Match only rows where `column` is less than `value`.
89
91
  *
90
92
  * @param column - The column to filter on
91
93
  * @param value - The value to filter with
92
94
  */
93
- lt<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
94
- lt(column: string, value: unknown): this
95
95
  lt(column: string, value: unknown): this {
96
96
  this.url.searchParams.append(column, `lt.${value}`)
97
97
  return this
98
98
  }
99
99
 
100
+ lte<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
101
+ lte(column: string, value: unknown): this
100
102
  /**
101
103
  * Match only rows where `column` is less than or equal to `value`.
102
104
  *
103
105
  * @param column - The column to filter on
104
106
  * @param value - The value to filter with
105
107
  */
106
- lte<ColumnName extends string & keyof Row>(column: ColumnName, value: Row[ColumnName]): this
107
- lte(column: string, value: unknown): this
108
108
  lte(column: string, value: unknown): this {
109
109
  this.url.searchParams.append(column, `lte.${value}`)
110
110
  return this
111
111
  }
112
112
 
113
+ like<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
114
+ like(column: string, pattern: string): this
113
115
  /**
114
116
  * Match only rows where `column` matches `pattern` case-sensitively.
115
117
  *
116
118
  * @param column - The column to filter on
117
119
  * @param pattern - The pattern to match with
118
120
  */
119
- like<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
120
- like(column: string, pattern: string): this
121
121
  like(column: string, pattern: string): this {
122
122
  this.url.searchParams.append(column, `like.${pattern}`)
123
123
  return this
124
124
  }
125
125
 
126
+ ilike<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
127
+ ilike(column: string, pattern: string): this
126
128
  /**
127
129
  * Match only rows where `column` matches `pattern` case-insensitively.
128
130
  *
129
131
  * @param column - The column to filter on
130
132
  * @param pattern - The pattern to match with
131
133
  */
132
- ilike<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
133
- ilike(column: string, pattern: string): this
134
134
  ilike(column: string, pattern: string): this {
135
135
  this.url.searchParams.append(column, `ilike.${pattern}`)
136
136
  return this
137
137
  }
138
138
 
139
+ is<ColumnName extends string & keyof Row>(
140
+ column: ColumnName,
141
+ value: Row[ColumnName] & (boolean | null)
142
+ ): this
143
+ is(column: string, value: boolean | null): this
139
144
  /**
140
145
  * Match only rows where `column` IS `value`.
141
146
  *
@@ -148,24 +153,19 @@ export default class PostgrestFilterBuilder<
148
153
  * @param column - The column to filter on
149
154
  * @param value - The value to filter with
150
155
  */
151
- is<ColumnName extends string & keyof Row>(
152
- column: ColumnName,
153
- value: Row[ColumnName] & (boolean | null)
154
- ): this
155
- is(column: string, value: boolean | null): this
156
156
  is(column: string, value: boolean | null): this {
157
157
  this.url.searchParams.append(column, `is.${value}`)
158
158
  return this
159
159
  }
160
160
 
161
+ in<ColumnName extends string & keyof Row>(column: ColumnName, values: Row[ColumnName][]): this
162
+ in(column: string, values: unknown[]): this
161
163
  /**
162
164
  * Match only rows where `column` is included in the `values` array.
163
165
  *
164
166
  * @param column - The column to filter on
165
167
  * @param values - The values array to filter with
166
168
  */
167
- in<ColumnName extends string & keyof Row>(column: ColumnName, values: Row[ColumnName][]): this
168
- in(column: string, values: unknown[]): this
169
169
  in(column: string, values: unknown[]): this {
170
170
  const cleanedValues = values
171
171
  .map((s) => {
@@ -179,6 +179,11 @@ export default class PostgrestFilterBuilder<
179
179
  return this
180
180
  }
181
181
 
182
+ contains<ColumnName extends string & keyof Row>(
183
+ column: ColumnName,
184
+ value: string | Row[ColumnName][] | Record<string, unknown>
185
+ ): this
186
+ contains(column: string, value: string | unknown[] | Record<string, unknown>): this
182
187
  /**
183
188
  * Only relevant for jsonb, array, and range columns. Match only rows where
184
189
  * `column` contains every element appearing in `value`.
@@ -186,11 +191,6 @@ export default class PostgrestFilterBuilder<
186
191
  * @param column - The jsonb, array, or range column to filter on
187
192
  * @param value - The jsonb, array, or range value to filter with
188
193
  */
189
- contains<ColumnName extends string & keyof Row>(
190
- column: ColumnName,
191
- value: string | Row[ColumnName][] | Record<string, unknown>
192
- ): this
193
- contains(column: string, value: string | unknown[] | Record<string, unknown>): this
194
194
  contains(column: string, value: string | unknown[] | Record<string, unknown>): this {
195
195
  if (typeof value === 'string') {
196
196
  // range types can be inclusive '[', ']' or exclusive '(', ')' so just
@@ -206,6 +206,11 @@ export default class PostgrestFilterBuilder<
206
206
  return this
207
207
  }
208
208
 
209
+ containedBy<ColumnName extends string & keyof Row>(
210
+ column: ColumnName,
211
+ value: string | Row[ColumnName][] | Record<string, unknown>
212
+ ): this
213
+ containedBy(column: string, value: string | unknown[] | Record<string, unknown>): this
209
214
  /**
210
215
  * Only relevant for jsonb, array, and range columns. Match only rows where
211
216
  * every element appearing in `column` is contained by `value`.
@@ -213,11 +218,6 @@ export default class PostgrestFilterBuilder<
213
218
  * @param column - The jsonb, array, or range column to filter on
214
219
  * @param value - The jsonb, array, or range value to filter with
215
220
  */
216
- containedBy<ColumnName extends string & keyof Row>(
217
- column: ColumnName,
218
- value: string | Row[ColumnName][] | Record<string, unknown>
219
- ): this
220
- containedBy(column: string, value: string | unknown[] | Record<string, unknown>): this
221
221
  containedBy(column: string, value: string | unknown[] | Record<string, unknown>): this {
222
222
  if (typeof value === 'string') {
223
223
  // range
@@ -232,6 +232,8 @@ export default class PostgrestFilterBuilder<
232
232
  return this
233
233
  }
234
234
 
235
+ rangeGt<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
236
+ rangeGt(column: string, range: string): this
235
237
  /**
236
238
  * Only relevant for range columns. Match only rows where every element in
237
239
  * `column` is greater than any element in `range`.
@@ -239,13 +241,13 @@ export default class PostgrestFilterBuilder<
239
241
  * @param column - The range column to filter on
240
242
  * @param range - The range to filter with
241
243
  */
242
- rangeGt<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
243
- rangeGt(column: string, range: string): this
244
244
  rangeGt(column: string, range: string): this {
245
245
  this.url.searchParams.append(column, `sr.${range}`)
246
246
  return this
247
247
  }
248
248
 
249
+ rangeGte<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
250
+ rangeGte(column: string, range: string): this
249
251
  /**
250
252
  * Only relevant for range columns. Match only rows where every element in
251
253
  * `column` is either contained in `range` or greater than any element in
@@ -254,13 +256,13 @@ export default class PostgrestFilterBuilder<
254
256
  * @param column - The range column to filter on
255
257
  * @param range - The range to filter with
256
258
  */
257
- rangeGte<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
258
- rangeGte(column: string, range: string): this
259
259
  rangeGte(column: string, range: string): this {
260
260
  this.url.searchParams.append(column, `nxl.${range}`)
261
261
  return this
262
262
  }
263
263
 
264
+ rangeLt<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
265
+ rangeLt(column: string, range: string): this
264
266
  /**
265
267
  * Only relevant for range columns. Match only rows where every element in
266
268
  * `column` is less than any element in `range`.
@@ -268,13 +270,13 @@ export default class PostgrestFilterBuilder<
268
270
  * @param column - The range column to filter on
269
271
  * @param range - The range to filter with
270
272
  */
271
- rangeLt<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
272
- rangeLt(column: string, range: string): this
273
273
  rangeLt(column: string, range: string): this {
274
274
  this.url.searchParams.append(column, `sl.${range}`)
275
275
  return this
276
276
  }
277
277
 
278
+ rangeLte<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
279
+ rangeLte(column: string, range: string): this
278
280
  /**
279
281
  * Only relevant for range columns. Match only rows where every element in
280
282
  * `column` is either contained in `range` or less than any element in
@@ -283,13 +285,13 @@ export default class PostgrestFilterBuilder<
283
285
  * @param column - The range column to filter on
284
286
  * @param range - The range to filter with
285
287
  */
286
- rangeLte<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
287
- rangeLte(column: string, range: string): this
288
288
  rangeLte(column: string, range: string): this {
289
289
  this.url.searchParams.append(column, `nxr.${range}`)
290
290
  return this
291
291
  }
292
292
 
293
+ rangeAdjacent<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
294
+ rangeAdjacent(column: string, range: string): this
293
295
  /**
294
296
  * Only relevant for range columns. Match only rows where `column` is
295
297
  * mutually exclusive to `range` and there can be no element between the two
@@ -298,13 +300,16 @@ export default class PostgrestFilterBuilder<
298
300
  * @param column - The range column to filter on
299
301
  * @param range - The range to filter with
300
302
  */
301
- rangeAdjacent<ColumnName extends string & keyof Row>(column: ColumnName, range: string): this
302
- rangeAdjacent(column: string, range: string): this
303
303
  rangeAdjacent(column: string, range: string): this {
304
304
  this.url.searchParams.append(column, `adj.${range}`)
305
305
  return this
306
306
  }
307
307
 
308
+ overlaps<ColumnName extends string & keyof Row>(
309
+ column: ColumnName,
310
+ value: string | Row[ColumnName][]
311
+ ): this
312
+ overlaps(column: string, value: string | unknown[]): this
308
313
  /**
309
314
  * Only relevant for array and range columns. Match only rows where
310
315
  * `column` and `value` have an element in common.
@@ -312,11 +317,6 @@ export default class PostgrestFilterBuilder<
312
317
  * @param column - The array or range column to filter on
313
318
  * @param value - The array or range value to filter with
314
319
  */
315
- overlaps<ColumnName extends string & keyof Row>(
316
- column: ColumnName,
317
- value: string | Row[ColumnName][]
318
- ): this
319
- overlaps(column: string, value: string | unknown[]): this
320
320
  overlaps(column: string, value: string | unknown[]): this {
321
321
  if (typeof value === 'string') {
322
322
  // range
@@ -328,16 +328,6 @@ export default class PostgrestFilterBuilder<
328
328
  return this
329
329
  }
330
330
 
331
- /**
332
- * Only relevant for text and tsvector columns. Match only rows where
333
- * `column` matches the query string in `query`.
334
- *
335
- * @param column - The text or tsvector column to filter on
336
- * @param query - The query text to match with
337
- * @param options - Named parameters
338
- * @param options.config - The text search configuration to use
339
- * @param options.type - Change how the `query` text is interpreted
340
- */
341
331
  textSearch<ColumnName extends string & keyof Row>(
342
332
  column: ColumnName,
343
333
  query: string,
@@ -348,6 +338,16 @@ export default class PostgrestFilterBuilder<
348
338
  query: string,
349
339
  options?: { config?: string; type?: 'plain' | 'phrase' | 'websearch' }
350
340
  ): this
341
+ /**
342
+ * Only relevant for text and tsvector columns. Match only rows where
343
+ * `column` matches the query string in `query`.
344
+ *
345
+ * @param column - The text or tsvector column to filter on
346
+ * @param query - The query text to match with
347
+ * @param options - Named parameters
348
+ * @param options.config - The text search configuration to use
349
+ * @param options.type - Change how the `query` text is interpreted
350
+ */
351
351
  textSearch(
352
352
  column: string,
353
353
  query: string,
@@ -366,6 +366,8 @@ export default class PostgrestFilterBuilder<
366
366
  return this
367
367
  }
368
368
 
369
+ match<ColumnName extends string & keyof Row>(query: Record<ColumnName, Row[ColumnName]>): this
370
+ match(query: Record<string, unknown>): this
369
371
  /**
370
372
  * Match only rows where each column in `query` keys is equal to its
371
373
  * associated value. Shorthand for multiple `.eq()`s.
@@ -373,8 +375,6 @@ export default class PostgrestFilterBuilder<
373
375
  * @param query - The object to filter with, with column names as keys mapped
374
376
  * to their filter values
375
377
  */
376
- match<ColumnName extends string & keyof Row>(query: Record<ColumnName, Row[ColumnName]>): this
377
- match(query: Record<string, unknown>): this
378
378
  match(query: Record<string, unknown>): this {
379
379
  Object.entries(query).forEach(([column, value]) => {
380
380
  this.url.searchParams.append(column, `eq.${value}`)
@@ -382,6 +382,12 @@ export default class PostgrestFilterBuilder<
382
382
  return this
383
383
  }
384
384
 
385
+ not<ColumnName extends string & keyof Row>(
386
+ column: ColumnName,
387
+ operator: FilterOperator,
388
+ value: Row[ColumnName]
389
+ ): this
390
+ not(column: string, operator: string, value: unknown): this
385
391
  /**
386
392
  * Match only rows which doesn't satisfy the filter.
387
393
  *
@@ -395,12 +401,6 @@ export default class PostgrestFilterBuilder<
395
401
  * PostgREST syntax
396
402
  * @param value - The value to filter with, following PostgREST syntax
397
403
  */
398
- not<ColumnName extends string & keyof Row>(
399
- column: ColumnName,
400
- operator: FilterOperator,
401
- value: Row[ColumnName]
402
- ): this
403
- not(column: string, operator: string, value: unknown): this
404
404
  not(column: string, operator: string, value: unknown): this {
405
405
  this.url.searchParams.append(column, `not.${operator}.${value}`)
406
406
  return this
@@ -425,6 +425,12 @@ export default class PostgrestFilterBuilder<
425
425
  return this
426
426
  }
427
427
 
428
+ filter<ColumnName extends string & keyof Row>(
429
+ column: ColumnName,
430
+ operator: `${'' | 'not.'}${FilterOperator}`,
431
+ value: unknown
432
+ ): this
433
+ filter(column: string, operator: string, value: unknown): this
428
434
  /**
429
435
  * Match only rows which satisfy the filter. This is an escape hatch - you
430
436
  * should use the specific filter methods wherever possible.
@@ -438,12 +444,6 @@ export default class PostgrestFilterBuilder<
438
444
  * @param operator - The operator to filter with, following PostgREST syntax
439
445
  * @param value - The value to filter with, following PostgREST syntax
440
446
  */
441
- filter<ColumnName extends string & keyof Row>(
442
- column: ColumnName,
443
- operator: `${'' | 'not.'}${FilterOperator}`,
444
- value: unknown
445
- ): this
446
- filter(column: string, operator: string, value: unknown): this
447
447
  filter(column: string, operator: string, value: unknown): this {
448
448
  this.url.searchParams.append(column, `${operator}.${value}`)
449
449
  return this
@@ -46,6 +46,14 @@ export default class PostgrestTransformBuilder<
46
46
  return this as unknown as PostgrestTransformBuilder<Schema, Row, NewResult>
47
47
  }
48
48
 
49
+ order<ColumnName extends string & keyof Row>(
50
+ column: ColumnName,
51
+ options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: undefined }
52
+ ): this
53
+ order(
54
+ column: string,
55
+ options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable: string }
56
+ ): this
49
57
  /**
50
58
  * Order the query result by `column`.
51
59
  *
@@ -62,14 +70,6 @@ export default class PostgrestTransformBuilder<
62
70
  * @param options.foreignTable - Set this to order a foreign table by foreign
63
71
  * columns
64
72
  */
65
- order<ColumnName extends string & keyof Row>(
66
- column: ColumnName,
67
- options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: undefined }
68
- ): this
69
- order(
70
- column: string,
71
- options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable: string }
72
- ): this
73
73
  order(
74
74
  column: string,
75
75
  {
@@ -38,6 +38,8 @@ type Digit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0'
38
38
 
39
39
  type Letter = Alphabet | Digit | '_'
40
40
 
41
+ type Json = string | number | boolean | null | { [key: string]: Json } | Json[]
42
+
41
43
  // /**
42
44
  // * Parsed node types.
43
45
  // * Currently only `*` and all other fields.
@@ -45,7 +47,8 @@ type Letter = Alphabet | Digit | '_'
45
47
  // type ParsedNode =
46
48
  // | { star: true }
47
49
  // | { name: string; original: string }
48
- // | { name: string; foreignTable: true };
50
+ // | { name: string; foreignTable: true }
51
+ // | { name: string; type: T };
49
52
 
50
53
  /**
51
54
  * Parser errors.
@@ -90,6 +93,8 @@ type ConstructFieldDefinition<
90
93
  }
91
94
  : Field extends { name: string; original: string }
92
95
  ? { [K in Field['name']]: Row[Field['original']] }
96
+ : Field extends { name: string; type: infer T }
97
+ ? { [K in Field['name']]: T }
93
98
  : Record<string, unknown>
94
99
 
95
100
  /**
@@ -131,17 +136,19 @@ type ParseIdentifier<Input extends string> = ReadLetters<Input>
131
136
  * A node is one of the following:
132
137
  * - `*`
133
138
  * - `field`
139
+ * - `field->json...`
134
140
  * - `field(nodes)`
135
141
  * - `field!hint(nodes)`
136
142
  * - `field!inner(nodes)`
137
143
  * - `field!hint!inner(nodes)`
138
144
  * - `renamed_field:field`
145
+ * - `renamed_field:field->json...`
139
146
  * - `renamed_field:field(nodes)`
140
147
  * - `renamed_field:field!hint(nodes)`
141
148
  * - `renamed_field:field!inner(nodes)`
142
149
  * - `renamed_field:field!hint!inner(nodes)`
143
150
  *
144
- * TODO: casting operators `::text`, JSON operators `->`, `->>`.
151
+ * TODO: casting operators `::text`, more support for JSON operators `->`, `->>`.
145
152
  */
146
153
  type ParseNode<Input extends string> = Input extends ''
147
154
  ? ParserError<'Empty string'>
@@ -225,6 +232,13 @@ type ParseNode<Input extends string> = Input extends ''
225
232
  ]
226
233
  ? // `renamed_field:field(nodes)`
227
234
  [{ name: Name; original: OriginalName; children: Fields }, EatWhitespace<Remainder>]
235
+ : ParseJsonAccessor<EatWhitespace<Remainder>> extends [
236
+ infer _PropertyName,
237
+ infer PropertyType,
238
+ `${infer Remainder}`
239
+ ]
240
+ ? // `renamed_field:field->json...`
241
+ [{ name: Name; type: PropertyType }, EatWhitespace<Remainder>]
228
242
  : ParseEmbeddedResource<EatWhitespace<Remainder>> extends ParserError<string>
229
243
  ? ParseEmbeddedResource<EatWhitespace<Remainder>>
230
244
  : // `renamed_field:field`
@@ -233,12 +247,42 @@ type ParseNode<Input extends string> = Input extends ''
233
247
  : ParseEmbeddedResource<EatWhitespace<Remainder>> extends [infer Fields, `${infer Remainder}`]
234
248
  ? // `field(nodes)`
235
249
  [{ name: Name; original: Name; children: Fields }, EatWhitespace<Remainder>]
250
+ : ParseJsonAccessor<EatWhitespace<Remainder>> extends [
251
+ infer PropertyName,
252
+ infer PropertyType,
253
+ `${infer Remainder}`
254
+ ]
255
+ ? // `field->json...`
256
+ [{ name: PropertyName; type: PropertyType }, EatWhitespace<Remainder>]
236
257
  : ParseEmbeddedResource<EatWhitespace<Remainder>> extends ParserError<string>
237
258
  ? ParseEmbeddedResource<EatWhitespace<Remainder>>
238
259
  : // `field`
239
260
  [{ name: Name; original: Name }, EatWhitespace<Remainder>]
240
261
  : ParserError<`Expected identifier at \`${Input}\``>
241
262
 
263
+ /**
264
+ * Parses a JSON property accessor of the shape `->a->b->c`. The last accessor in
265
+ * the series may convert to text by using the ->> operator instead of ->.
266
+ *
267
+ * Returns a tuple of ["Last property name", "Last property type", "Remainder of text"]
268
+ * or the original string input indicating that no opening `->` was found.
269
+ */
270
+ type ParseJsonAccessor<Input extends string> = Input extends `->${infer Remainder}`
271
+ ? Remainder extends `>${infer Remainder}`
272
+ ? ParseIdentifier<Remainder> extends [infer Name, `${infer Remainder}`]
273
+ ? [Name, string, EatWhitespace<Remainder>]
274
+ : ParserError<'Expected property name after `->>`'>
275
+ : ParseIdentifier<Remainder> extends [infer Name, `${infer Remainder}`]
276
+ ? ParseJsonAccessor<Remainder> extends [
277
+ infer PropertyName,
278
+ infer PropertyType,
279
+ `${infer Remainder}`
280
+ ]
281
+ ? [PropertyName, PropertyType, EatWhitespace<Remainder>]
282
+ : [Name, Json, EatWhitespace<Remainder>]
283
+ : ParserError<'Expected property name after `->`'>
284
+ : Input
285
+
242
286
  /**
243
287
  * Parses an embedded resource, which is an opening `(`, followed by a sequence of
244
288
  * nodes, separated by `,`, then a closing `)`.
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.1.0'
1
+ export const version = '1.2.0'