pqb 0.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.
Files changed (122) hide show
  1. package/dist/index.d.ts +3630 -0
  2. package/dist/index.esm.js +4587 -0
  3. package/dist/index.esm.js.map +1 -0
  4. package/dist/index.js +4691 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +59 -0
  7. package/rollup.config.js +35 -0
  8. package/src/adapter.test.ts +10 -0
  9. package/src/adapter.ts +171 -0
  10. package/src/columnSchema/array.ts +21 -0
  11. package/src/columnSchema/boolean.ts +10 -0
  12. package/src/columnSchema/columnType.test.ts +129 -0
  13. package/src/columnSchema/columnType.ts +77 -0
  14. package/src/columnSchema/columnTypes.ts +145 -0
  15. package/src/columnSchema/columnsSchema.test.ts +32 -0
  16. package/src/columnSchema/columnsSchema.ts +100 -0
  17. package/src/columnSchema/commonMethods.ts +130 -0
  18. package/src/columnSchema/dateTime.ts +104 -0
  19. package/src/columnSchema/enum.ts +13 -0
  20. package/src/columnSchema/index.ts +11 -0
  21. package/src/columnSchema/json/array.ts +55 -0
  22. package/src/columnSchema/json/discriminatedUnion.ts +91 -0
  23. package/src/columnSchema/json/enum.ts +29 -0
  24. package/src/columnSchema/json/instanceOf.ts +16 -0
  25. package/src/columnSchema/json/intersection.ts +23 -0
  26. package/src/columnSchema/json/lazy.ts +22 -0
  27. package/src/columnSchema/json/literal.ts +12 -0
  28. package/src/columnSchema/json/map.ts +29 -0
  29. package/src/columnSchema/json/nativeEnum.ts +30 -0
  30. package/src/columnSchema/json/nullable.ts +33 -0
  31. package/src/columnSchema/json/nullish.ts +30 -0
  32. package/src/columnSchema/json/object.ts +206 -0
  33. package/src/columnSchema/json/optional.ts +28 -0
  34. package/src/columnSchema/json/record.ts +40 -0
  35. package/src/columnSchema/json/scalarTypes.ts +117 -0
  36. package/src/columnSchema/json/set.ts +34 -0
  37. package/src/columnSchema/json/tuple.ts +40 -0
  38. package/src/columnSchema/json/typeBase.ts +202 -0
  39. package/src/columnSchema/json/union.ts +16 -0
  40. package/src/columnSchema/json.ts +64 -0
  41. package/src/columnSchema/number.ts +122 -0
  42. package/src/columnSchema/string.ts +222 -0
  43. package/src/columnSchema/utils.ts +27 -0
  44. package/src/common.ts +86 -0
  45. package/src/db.test.ts +67 -0
  46. package/src/db.ts +212 -0
  47. package/src/errors.ts +7 -0
  48. package/src/index.ts +18 -0
  49. package/src/operators.test.ts +608 -0
  50. package/src/operators.ts +177 -0
  51. package/src/query.ts +292 -0
  52. package/src/queryDataUtils.ts +50 -0
  53. package/src/queryMethods/aggregate.test.ts +583 -0
  54. package/src/queryMethods/aggregate.ts +878 -0
  55. package/src/queryMethods/callbacks.test.ts +69 -0
  56. package/src/queryMethods/callbacks.ts +55 -0
  57. package/src/queryMethods/clear.test.ts +64 -0
  58. package/src/queryMethods/clear.ts +58 -0
  59. package/src/queryMethods/columnInfo.test.ts +45 -0
  60. package/src/queryMethods/columnInfo.ts +67 -0
  61. package/src/queryMethods/delete.test.ts +135 -0
  62. package/src/queryMethods/delete.ts +50 -0
  63. package/src/queryMethods/for.test.ts +57 -0
  64. package/src/queryMethods/for.ts +99 -0
  65. package/src/queryMethods/from.test.ts +66 -0
  66. package/src/queryMethods/from.ts +58 -0
  67. package/src/queryMethods/get.test.ts +66 -0
  68. package/src/queryMethods/get.ts +88 -0
  69. package/src/queryMethods/having.test.ts +247 -0
  70. package/src/queryMethods/having.ts +99 -0
  71. package/src/queryMethods/insert.test.ts +555 -0
  72. package/src/queryMethods/insert.ts +453 -0
  73. package/src/queryMethods/join.test.ts +150 -0
  74. package/src/queryMethods/join.ts +508 -0
  75. package/src/queryMethods/json.test.ts +398 -0
  76. package/src/queryMethods/json.ts +259 -0
  77. package/src/queryMethods/log.test.ts +172 -0
  78. package/src/queryMethods/log.ts +123 -0
  79. package/src/queryMethods/queryMethods.test.ts +629 -0
  80. package/src/queryMethods/queryMethods.ts +428 -0
  81. package/src/queryMethods/select.test.ts +479 -0
  82. package/src/queryMethods/select.ts +249 -0
  83. package/src/queryMethods/then.ts +236 -0
  84. package/src/queryMethods/transaction.test.ts +66 -0
  85. package/src/queryMethods/transaction.ts +66 -0
  86. package/src/queryMethods/union.test.ts +59 -0
  87. package/src/queryMethods/union.ts +89 -0
  88. package/src/queryMethods/update.test.ts +417 -0
  89. package/src/queryMethods/update.ts +350 -0
  90. package/src/queryMethods/upsert.test.ts +56 -0
  91. package/src/queryMethods/upsert.ts +43 -0
  92. package/src/queryMethods/where.test.ts +1594 -0
  93. package/src/queryMethods/where.ts +450 -0
  94. package/src/queryMethods/window.test.ts +66 -0
  95. package/src/queryMethods/window.ts +108 -0
  96. package/src/queryMethods/with.test.ts +191 -0
  97. package/src/queryMethods/with.ts +92 -0
  98. package/src/quote.ts +36 -0
  99. package/src/relations.ts +194 -0
  100. package/src/sql/aggregate.ts +80 -0
  101. package/src/sql/columnInfo.ts +22 -0
  102. package/src/sql/common.ts +42 -0
  103. package/src/sql/delete.ts +41 -0
  104. package/src/sql/distinct.ts +19 -0
  105. package/src/sql/fromAndAs.ts +51 -0
  106. package/src/sql/having.ts +140 -0
  107. package/src/sql/index.ts +2 -0
  108. package/src/sql/insert.ts +102 -0
  109. package/src/sql/join.ts +242 -0
  110. package/src/sql/orderBy.ts +41 -0
  111. package/src/sql/select.ts +153 -0
  112. package/src/sql/toSql.ts +153 -0
  113. package/src/sql/truncate.ts +13 -0
  114. package/src/sql/types.ts +355 -0
  115. package/src/sql/update.ts +62 -0
  116. package/src/sql/where.ts +314 -0
  117. package/src/sql/window.ts +38 -0
  118. package/src/sql/with.ts +32 -0
  119. package/src/test-utils.ts +172 -0
  120. package/src/utils.ts +140 -0
  121. package/tsconfig.build.json +6 -0
  122. package/tsconfig.json +8 -0
@@ -0,0 +1,398 @@
1
+ import {
2
+ AssertEqual,
3
+ expectQueryNotMutated,
4
+ expectSql,
5
+ User,
6
+ userData,
7
+ useTestDatabase,
8
+ } from '../test-utils';
9
+ import { columnTypes } from '../columnSchema';
10
+
11
+ describe('json methods', () => {
12
+ useTestDatabase();
13
+
14
+ describe('json', () => {
15
+ it('wraps a query with json functions', () => {
16
+ const q = User.all();
17
+ expectSql(
18
+ q.where({ id: 1 }).json().toSql(),
19
+ `
20
+ SELECT COALESCE(json_agg(row_to_json("t".*)), '[]')
21
+ FROM (
22
+ SELECT * FROM "user"
23
+ WHERE "user"."id" = $1
24
+ ) AS "t"
25
+ `,
26
+ [1],
27
+ );
28
+ expectQueryNotMutated(q);
29
+ });
30
+
31
+ it('supports `take`', () => {
32
+ const q = User.all();
33
+ expectSql(
34
+ q.where({ id: 1 }).take().json().toSql(),
35
+ `
36
+ SELECT row_to_json("t".*)
37
+ FROM (
38
+ SELECT * FROM "user"
39
+ WHERE "user"."id" = $1
40
+ LIMIT $2
41
+ ) AS "t"
42
+ `,
43
+ [1, 1],
44
+ );
45
+ expectQueryNotMutated(q);
46
+ });
47
+ });
48
+
49
+ describe('processing and selecting json data', () => {
50
+ beforeEach(async () => {
51
+ await User.insert({
52
+ ...userData,
53
+ data: { name: 'value', tags: ['one'] },
54
+ });
55
+ });
56
+
57
+ describe('jsonSet', () => {
58
+ it('should select json with updated property', async () => {
59
+ const q = User.all();
60
+
61
+ const query = q.jsonSet('data', ['name'], 'new value');
62
+ expectSql(
63
+ query.toSql(),
64
+ `
65
+ SELECT jsonb_set("user"."data", '{name}', $1) AS "data"
66
+ FROM "user"
67
+ `,
68
+ ['"new value"'],
69
+ );
70
+
71
+ const result = await query.take();
72
+ expect(result.data).toEqual({ name: 'new value', tags: ['one'] });
73
+
74
+ const eq: AssertEqual<
75
+ typeof result.data,
76
+ { name: string; tags: string[] } | null
77
+ > = true;
78
+ expect(eq).toBe(true);
79
+
80
+ expectQueryNotMutated(q);
81
+ });
82
+
83
+ it('should accept optional `as`, `createIfMissing`', async () => {
84
+ const q = User.all();
85
+
86
+ const query = q.jsonSet('data', ['name'], 'new value', {
87
+ as: 'alias',
88
+ createIfMissing: true,
89
+ });
90
+ expectSql(
91
+ query.toSql(),
92
+ `
93
+ SELECT jsonb_set("user"."data", '{name}', $1, true) AS "alias"
94
+ FROM "user"
95
+ `,
96
+ ['"new value"'],
97
+ );
98
+
99
+ const result = await query.take();
100
+ expect(result.alias).toEqual({ name: 'new value', tags: ['one'] });
101
+
102
+ const eq: AssertEqual<
103
+ typeof result.alias,
104
+ { name: string; tags: string[] } | null
105
+ > = true;
106
+ expect(eq).toBe(true);
107
+
108
+ expectQueryNotMutated(q);
109
+ });
110
+
111
+ it('supports nesting', async () => {
112
+ const q = User.all();
113
+
114
+ const query = q.jsonSet(
115
+ q.jsonInsert('data', ['tags', 0], 'two'),
116
+ ['name'],
117
+ 'new value',
118
+ );
119
+ expectSql(
120
+ query.toSql(),
121
+ `
122
+ SELECT jsonb_set(
123
+ jsonb_insert("user"."data", '{tags, 0}', $1),
124
+ '{name}', $2
125
+ ) AS "data"
126
+ FROM "user"
127
+ `,
128
+ ['"two"', '"new value"'],
129
+ );
130
+
131
+ const result = await query.take();
132
+ expect(result.data).toEqual({
133
+ name: 'new value',
134
+ tags: ['two', 'one'],
135
+ });
136
+
137
+ const eq: AssertEqual<
138
+ typeof result.data,
139
+ { name: string; tags: string[] } | null
140
+ > = true;
141
+ expect(eq).toBe(true);
142
+
143
+ expectQueryNotMutated(q);
144
+ });
145
+ });
146
+
147
+ describe('jsonInsert', () => {
148
+ it('should select json with updated property', async () => {
149
+ const q = User.all();
150
+
151
+ const query = q.jsonInsert('data', ['tags', 0], 'two');
152
+ expectSql(
153
+ query.toSql(),
154
+ `
155
+ SELECT jsonb_insert("user"."data", '{tags, 0}', $1) AS "data"
156
+ FROM "user"
157
+ `,
158
+ ['"two"'],
159
+ );
160
+
161
+ const result = await query.take();
162
+ expect(result.data).toEqual({ name: 'value', tags: ['two', 'one'] });
163
+
164
+ const eq: AssertEqual<
165
+ typeof result.data,
166
+ { name: string; tags: string[] } | null
167
+ > = true;
168
+ expect(eq).toBe(true);
169
+
170
+ expectQueryNotMutated(q);
171
+ });
172
+
173
+ it('should accept optional `as`, `insertAfter`', async () => {
174
+ const q = User.all();
175
+
176
+ const query = q.jsonInsert('data', ['tags', 0], 'two', {
177
+ as: 'alias',
178
+ insertAfter: true,
179
+ });
180
+ expectSql(
181
+ query.toSql(),
182
+ `
183
+ SELECT jsonb_insert("user"."data", '{tags, 0}', $1, true) AS "alias"
184
+ FROM "user"
185
+ `,
186
+ ['"two"'],
187
+ );
188
+
189
+ const result = await query.take();
190
+ expect(result.alias).toEqual({ name: 'value', tags: ['one', 'two'] });
191
+
192
+ const eq: AssertEqual<
193
+ typeof result.alias,
194
+ { name: string; tags: string[] } | null
195
+ > = true;
196
+ expect(eq).toBe(true);
197
+
198
+ expectQueryNotMutated(q);
199
+ });
200
+
201
+ it('supports nesting', async () => {
202
+ const q = User.all();
203
+
204
+ const query = q.jsonInsert(
205
+ q.jsonSet('data', ['tags'], []),
206
+ ['tags', 0],
207
+ 'tag',
208
+ );
209
+ expectSql(
210
+ query.toSql(),
211
+ `
212
+ SELECT jsonb_insert(
213
+ jsonb_set("user"."data", '{tags}', $1),
214
+ '{tags, 0}', $2
215
+ ) AS "data"
216
+ FROM "user"
217
+ `,
218
+ ['[]', '"tag"'],
219
+ );
220
+
221
+ const result = await query.take();
222
+ expect(result.data).toEqual({ name: 'value', tags: ['tag'] });
223
+
224
+ const eq: AssertEqual<
225
+ typeof result.data,
226
+ { name: string; tags: string[] } | null
227
+ > = true;
228
+ expect(eq).toBe(true);
229
+
230
+ expectQueryNotMutated(q);
231
+ });
232
+ });
233
+
234
+ describe('jsonRemove', () => {
235
+ it('should select json with removed property', async () => {
236
+ const q = User.all();
237
+
238
+ const query = q.jsonRemove('data', ['tags', 0]);
239
+ expectSql(
240
+ query.toSql(),
241
+ `
242
+ SELECT "user"."data" #- '{tags, 0}' AS "data"
243
+ FROM "user"
244
+ `,
245
+ );
246
+
247
+ const result = await query.take();
248
+ expect(result.data).toEqual({ name: 'value', tags: [] });
249
+
250
+ const eq: AssertEqual<
251
+ typeof result.data,
252
+ { name: string; tags: string[] } | null
253
+ > = true;
254
+ expect(eq).toBe(true);
255
+
256
+ expectQueryNotMutated(q);
257
+ });
258
+
259
+ it('should accept optional `as`', async () => {
260
+ const q = User.all();
261
+
262
+ const query = q.jsonRemove('data', ['tags', 0], { as: 'alias' });
263
+ expectSql(
264
+ query.toSql(),
265
+ `
266
+ SELECT "user"."data" #- '{tags, 0}' AS "alias"
267
+ FROM "user"
268
+ `,
269
+ );
270
+
271
+ const result = await query.take();
272
+ expect(result.alias).toEqual({ name: 'value', tags: [] });
273
+
274
+ const eq: AssertEqual<
275
+ typeof result.alias,
276
+ { name: string; tags: string[] } | null
277
+ > = true;
278
+ expect(eq).toBe(true);
279
+
280
+ expectQueryNotMutated(q);
281
+ });
282
+
283
+ it('supports nesting', async () => {
284
+ const q = User.all();
285
+
286
+ const query = q.jsonRemove(q.jsonSet('data', ['tags'], ['tag']), [
287
+ 'tags',
288
+ 0,
289
+ ]);
290
+ expectSql(
291
+ query.toSql(),
292
+ `
293
+ SELECT
294
+ jsonb_set("user"."data", '{tags}', $1) #- '{tags, 0}' AS "data"
295
+ FROM "user"
296
+ `,
297
+ ['["tag"]'],
298
+ );
299
+
300
+ const result = await query.take();
301
+ expect(result.data).toEqual({ name: 'value', tags: [] });
302
+
303
+ const eq: AssertEqual<
304
+ typeof result.data,
305
+ { name: string; tags: string[] } | null
306
+ > = true;
307
+ expect(eq).toBe(true);
308
+
309
+ expectQueryNotMutated(q);
310
+ });
311
+ });
312
+
313
+ describe('jsonPathQuery', () => {
314
+ it('should select json property', async () => {
315
+ const q = User.all();
316
+
317
+ const query = q.jsonPathQuery(
318
+ columnTypes.text(),
319
+ 'data',
320
+ '$.name',
321
+ 'name',
322
+ );
323
+ expectSql(
324
+ query.toSql(),
325
+ `
326
+ SELECT jsonb_path_query("user"."data", $1) AS "name"
327
+ FROM "user"
328
+ `,
329
+ ['$.name'],
330
+ );
331
+
332
+ const result = await query.take();
333
+ expect(result.name).toBe('value');
334
+
335
+ const eq: AssertEqual<typeof result.name, string> = true;
336
+ expect(eq).toBe(true);
337
+
338
+ expectQueryNotMutated(q);
339
+ });
340
+
341
+ it('optionally supports vars and silent options', () => {
342
+ const q = User.all();
343
+
344
+ const query = q.jsonPathQuery(
345
+ columnTypes.text(),
346
+ 'data',
347
+ '$.name',
348
+ 'name',
349
+ {
350
+ vars: 'vars',
351
+ silent: true,
352
+ },
353
+ );
354
+ expectSql(
355
+ query.toSql(),
356
+ `
357
+ SELECT jsonb_path_query("user"."data", $1, $2, true) AS "name"
358
+ FROM "user"
359
+ `,
360
+ ['$.name', 'vars'],
361
+ );
362
+
363
+ expectQueryNotMutated(q);
364
+ });
365
+
366
+ it('supports nesting', async () => {
367
+ const q = User.all();
368
+
369
+ const query = q.jsonPathQuery(
370
+ columnTypes.array(columnTypes.text()),
371
+ q.jsonSet('data', ['tags'], ['tag']),
372
+ '$.tags',
373
+ 'tags',
374
+ );
375
+ expectSql(
376
+ query.toSql(),
377
+ `
378
+ SELECT
379
+ jsonb_path_query(
380
+ jsonb_set("user"."data", '{tags}', $1),
381
+ $2
382
+ ) AS "tags"
383
+ FROM "user"
384
+ `,
385
+ ['["tag"]', '$.tags'],
386
+ );
387
+
388
+ const result = await query.take();
389
+ expect(result.tags).toEqual(['tag']);
390
+
391
+ const eq: AssertEqual<typeof result.tags, string[]> = true;
392
+ expect(eq).toBe(true);
393
+
394
+ expectQueryNotMutated(q);
395
+ });
396
+ });
397
+ });
398
+ });
@@ -0,0 +1,259 @@
1
+ import { AddQuerySelect, Query, SetQueryReturnsValueOptional } from '../query';
2
+ import { pushQueryValue } from '../queryDataUtils';
3
+ import { ColumnType, StringColumn } from '../columnSchema';
4
+ import { JsonItem } from '../sql';
5
+ import { raw, StringKey } from '../common';
6
+
7
+ type JsonColumnName<T extends Pick<Query, 'selectable'>> = StringKey<
8
+ {
9
+ [K in keyof T['selectable']]: T['selectable'][K]['column']['dataType'] extends 'jsonb'
10
+ ? K
11
+ : never;
12
+ }[keyof T['selectable']]
13
+ >;
14
+
15
+ type ColumnOrJsonMethod<T extends Query> = JsonColumnName<T> | JsonItem;
16
+
17
+ type JsonSetResult<
18
+ T extends Query,
19
+ Column extends ColumnOrJsonMethod<T>,
20
+ As extends string,
21
+ Type extends ColumnType = Column extends keyof T['shape']
22
+ ? T['shape'][Column]
23
+ : Column extends JsonItem
24
+ ? Column['__json'][2]
25
+ : ColumnType,
26
+ > = JsonItem<As, Type> &
27
+ (Type extends ColumnType ? AddQuerySelect<T, Record<As, Type>> : T);
28
+
29
+ type JsonPathQueryResult<
30
+ T extends Query,
31
+ As extends string,
32
+ Type extends ColumnType,
33
+ > = JsonItem &
34
+ AddQuerySelect<
35
+ T,
36
+ {
37
+ [K in As]: Type;
38
+ }
39
+ >;
40
+
41
+ export class Json {
42
+ json<T extends Query>(
43
+ this: T,
44
+ ): SetQueryReturnsValueOptional<T, StringColumn> {
45
+ return this.clone()._json();
46
+ }
47
+
48
+ _json<T extends Query>(
49
+ this: T,
50
+ ): SetQueryReturnsValueOptional<T, StringColumn> {
51
+ const q = this._wrap(this.__model.clone()) as T;
52
+ q._getOptional(
53
+ raw<StringColumn>(
54
+ this.query.take
55
+ ? `row_to_json("t".*)`
56
+ : `COALESCE(json_agg(row_to_json("t".*)), '[]')`,
57
+ ),
58
+ );
59
+ delete q.query.take;
60
+ return q as unknown as SetQueryReturnsValueOptional<T, StringColumn>;
61
+ }
62
+
63
+ jsonSet<
64
+ T extends Query,
65
+ Column extends ColumnOrJsonMethod<T>,
66
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
67
+ >(
68
+ this: T,
69
+ column: Column,
70
+ path: Array<string | number>,
71
+ value: unknown,
72
+ options?: {
73
+ as?: As;
74
+ createIfMissing?: boolean;
75
+ },
76
+ ): JsonSetResult<T, Column, As> {
77
+ const q = this.clone() as T;
78
+ return q._jsonSet(column, path, value, options);
79
+ }
80
+
81
+ _jsonSet<
82
+ T extends Query,
83
+ Column extends ColumnOrJsonMethod<T>,
84
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
85
+ >(
86
+ this: T,
87
+ column: Column,
88
+ path: Array<string | number>,
89
+ value: unknown,
90
+ options?: {
91
+ as?: As;
92
+ createIfMissing?: boolean;
93
+ },
94
+ ): JsonSetResult<T, Column, As> {
95
+ const json: JsonItem = {
96
+ __json: [
97
+ 'set',
98
+ options?.as ??
99
+ (typeof column === 'string'
100
+ ? column
101
+ : (column as JsonItem).__json[1]),
102
+ typeof column === 'string'
103
+ ? this.shape[column]
104
+ : (column as JsonItem).__json[2],
105
+ column,
106
+ path,
107
+ value,
108
+ options,
109
+ ],
110
+ };
111
+
112
+ return Object.assign(
113
+ pushQueryValue(this, 'select', json),
114
+ json,
115
+ ) as unknown as JsonSetResult<T, Column, As>;
116
+ }
117
+
118
+ jsonInsert<
119
+ T extends Query,
120
+ Column extends ColumnOrJsonMethod<T>,
121
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
122
+ >(
123
+ this: T,
124
+ ...args: [
125
+ column: Column,
126
+ path: Array<string | number>,
127
+ value: unknown,
128
+ options?: {
129
+ as?: As;
130
+ insertAfter?: boolean;
131
+ },
132
+ ]
133
+ ): JsonSetResult<T, Column, As> {
134
+ const q = this.clone() as T;
135
+ return q._jsonInsert(...args);
136
+ }
137
+
138
+ _jsonInsert<
139
+ T extends Query,
140
+ Column extends ColumnOrJsonMethod<T>,
141
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
142
+ >(
143
+ this: T,
144
+ column: Column,
145
+ path: Array<string | number>,
146
+ value: unknown,
147
+ options?: {
148
+ as?: As;
149
+ insertAfter?: boolean;
150
+ },
151
+ ): JsonSetResult<T, Column, As> {
152
+ const json: JsonItem = {
153
+ __json: [
154
+ 'insert',
155
+ options?.as ??
156
+ (typeof column === 'string'
157
+ ? column
158
+ : (column as JsonItem).__json[1]),
159
+ typeof column === 'string'
160
+ ? this.shape[column]
161
+ : (column as JsonItem).__json[2],
162
+ column,
163
+ path,
164
+ value,
165
+ options,
166
+ ],
167
+ };
168
+
169
+ return Object.assign(
170
+ pushQueryValue(this, 'select', json),
171
+ json,
172
+ ) as unknown as JsonSetResult<T, Column, As>;
173
+ }
174
+
175
+ jsonRemove<
176
+ T extends Query,
177
+ Column extends ColumnOrJsonMethod<T>,
178
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
179
+ >(
180
+ this: T,
181
+ ...args: [
182
+ column: Column,
183
+ path: Array<string | number>,
184
+ options?: { as?: As },
185
+ ]
186
+ ): JsonSetResult<T, Column, As> {
187
+ const q = this.clone() as T;
188
+ return q._jsonRemove(...args);
189
+ }
190
+
191
+ _jsonRemove<
192
+ T extends Query,
193
+ Column extends ColumnOrJsonMethod<T>,
194
+ As extends string = Column extends JsonItem ? Column['__json'][1] : Column,
195
+ >(
196
+ this: T,
197
+ column: Column,
198
+ path: Array<string | number>,
199
+ options?: { as?: As },
200
+ ): JsonSetResult<T, Column, As> {
201
+ const json: JsonItem = {
202
+ __json: [
203
+ 'remove',
204
+ options?.as ??
205
+ (typeof column === 'string'
206
+ ? column
207
+ : (column as JsonItem).__json[1]),
208
+ typeof column === 'string'
209
+ ? this.shape[column]
210
+ : (column as JsonItem).__json[2],
211
+ column,
212
+ path,
213
+ ],
214
+ };
215
+
216
+ return Object.assign(
217
+ pushQueryValue(this, 'select', json),
218
+ json,
219
+ ) as unknown as JsonSetResult<T, Column, As>;
220
+ }
221
+
222
+ jsonPathQuery<T extends Query, As extends string, Type extends ColumnType>(
223
+ this: T,
224
+ ...args: [
225
+ type: Type,
226
+ column: ColumnOrJsonMethod<T>,
227
+ path: string,
228
+ as: As,
229
+ options?: {
230
+ vars?: string;
231
+ silent?: boolean;
232
+ },
233
+ ]
234
+ ): JsonPathQueryResult<T, As, Type> {
235
+ const q = this.clone() as T;
236
+ return q._jsonPathQuery(...args);
237
+ }
238
+
239
+ _jsonPathQuery<T extends Query, As extends string, Type extends ColumnType>(
240
+ this: T,
241
+ type: Type,
242
+ column: ColumnOrJsonMethod<T>,
243
+ path: string,
244
+ as: As,
245
+ options?: {
246
+ vars?: string;
247
+ silent?: boolean;
248
+ },
249
+ ): JsonPathQueryResult<T, As, Type> {
250
+ const json: JsonItem = {
251
+ __json: ['pathQuery', as, type, column, path, options],
252
+ };
253
+
254
+ return Object.assign(
255
+ pushQueryValue(this, 'select', json),
256
+ json,
257
+ ) as unknown as JsonPathQueryResult<T, As, Type>;
258
+ }
259
+ }