effect-qb 4.0.0-beta.66 → 4.0.0-beta.98

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 (129) hide show
  1. package/README.md +5 -2
  2. package/dist/index.js +9376 -0
  3. package/dist/mysql.js +3921 -2573
  4. package/dist/postgres/metadata.js +2491 -1373
  5. package/dist/postgres.js +5453 -5155
  6. package/dist/sqlite.js +6895 -5529
  7. package/dist/standard.js +9330 -0
  8. package/package.json +9 -2
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/coercion/rules.ts +13 -1
  13. package/src/internal/column-state.ts +21 -15
  14. package/src/internal/column.ts +44 -7
  15. package/src/internal/datatypes/define.ts +7 -1
  16. package/src/internal/datatypes/enrich.ts +23 -0
  17. package/src/internal/datatypes/lookup.ts +81 -25
  18. package/src/internal/datatypes/matrix.ts +903 -0
  19. package/src/internal/datatypes/shape.ts +2 -0
  20. package/src/internal/derived-table.ts +4 -36
  21. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +552 -361
  22. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +657 -400
  23. package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +505 -347
  24. package/src/internal/dialect.ts +35 -0
  25. package/src/internal/dsl-mutation-runtime.ts +12 -162
  26. package/src/internal/dsl-plan-runtime.ts +10 -138
  27. package/src/internal/dsl-query-runtime.ts +5 -79
  28. package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
  29. package/src/internal/executor.ts +14 -16
  30. package/src/internal/grouping-key.ts +87 -20
  31. package/src/internal/implication-runtime.ts +1 -1
  32. package/src/internal/json/path-access.ts +351 -0
  33. package/src/internal/predicate/runtime.ts +3 -0
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +64 -25
  36. package/src/internal/renderer.ts +26 -14
  37. package/src/internal/runtime/normalize.ts +12 -5
  38. package/src/internal/scalar.ts +7 -1
  39. package/src/internal/schema-derivation.d.ts +7 -7
  40. package/src/internal/schema-derivation.ts +9 -9
  41. package/src/internal/schema-expression.ts +2 -2
  42. package/src/internal/sql-expression-renderer.ts +19 -0
  43. package/src/internal/standard-dsl.ts +6978 -0
  44. package/src/internal/table-options.ts +126 -66
  45. package/src/internal/table.ts +652 -219
  46. package/src/mysql/column-extension.ts +3 -0
  47. package/src/mysql/column.ts +8 -9
  48. package/src/mysql/datatypes/index.ts +4 -2
  49. package/src/mysql/datatypes/spec.ts +6 -176
  50. package/src/mysql/errors/normalize.ts +0 -1
  51. package/src/mysql/executor.ts +7 -7
  52. package/src/mysql/internal/dialect.ts +9 -4
  53. package/src/mysql/internal/dsl.ts +312 -154
  54. package/src/mysql/internal/renderer.ts +6 -2
  55. package/src/mysql/json.ts +7 -2
  56. package/src/mysql/query-extension.ts +16 -0
  57. package/src/mysql/renderer.ts +37 -3
  58. package/src/mysql/type.ts +60 -0
  59. package/src/mysql.ts +7 -13
  60. package/src/postgres/check.ts +1 -0
  61. package/src/postgres/column-extension.ts +28 -0
  62. package/src/postgres/column.ts +2 -8
  63. package/src/postgres/datatypes/index.d.ts +2 -1
  64. package/src/postgres/datatypes/index.ts +4 -2
  65. package/src/postgres/datatypes/spec.ts +6 -260
  66. package/src/postgres/errors/normalize.ts +0 -1
  67. package/src/postgres/executor.ts +7 -7
  68. package/src/postgres/foreign-key.ts +24 -0
  69. package/src/postgres/function/core.ts +1 -3
  70. package/src/postgres/function/index.ts +1 -17
  71. package/src/postgres/index.ts +1 -0
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +306 -163
  74. package/src/postgres/internal/renderer.ts +6 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -10
  76. package/src/postgres/internal/schema-model.ts +238 -7
  77. package/src/postgres/json-extension.ts +7 -0
  78. package/src/postgres/json.ts +762 -173
  79. package/src/postgres/jsonb.ts +37 -0
  80. package/src/postgres/primary-key.ts +24 -0
  81. package/src/postgres/query-extension.ts +2 -0
  82. package/src/postgres/renderer.ts +37 -3
  83. package/src/postgres/schema-management.ts +12 -11
  84. package/src/postgres/schema.ts +106 -15
  85. package/src/postgres/table.ts +205 -530
  86. package/src/postgres/type.ts +93 -10
  87. package/src/postgres/unique.ts +32 -0
  88. package/src/postgres.ts +20 -16
  89. package/src/sqlite/column-extension.ts +3 -0
  90. package/src/sqlite/column.ts +8 -9
  91. package/src/sqlite/datatypes/index.ts +4 -2
  92. package/src/sqlite/datatypes/spec.ts +6 -94
  93. package/src/sqlite/errors/normalize.ts +0 -1
  94. package/src/sqlite/executor.ts +7 -7
  95. package/src/sqlite/internal/dialect.ts +9 -4
  96. package/src/sqlite/internal/dsl.ts +301 -154
  97. package/src/sqlite/internal/renderer.ts +6 -2
  98. package/src/sqlite/json.ts +8 -2
  99. package/src/sqlite/query-extension.ts +2 -0
  100. package/src/sqlite/renderer.ts +37 -3
  101. package/src/sqlite/type.ts +40 -0
  102. package/src/sqlite.ts +7 -13
  103. package/src/standard/cast.ts +113 -0
  104. package/src/standard/check.ts +17 -0
  105. package/src/standard/column.ts +163 -0
  106. package/src/standard/datatypes/index.ts +83 -0
  107. package/src/standard/datatypes/spec.ts +12 -0
  108. package/src/standard/dialect.ts +40 -0
  109. package/src/standard/foreign-key.ts +37 -0
  110. package/src/standard/function/aggregate.ts +2 -0
  111. package/src/standard/function/core.ts +2 -0
  112. package/src/standard/function/index.ts +18 -0
  113. package/src/standard/function/string.ts +2 -0
  114. package/src/standard/function/temporal.ts +78 -0
  115. package/src/standard/function/window.ts +2 -0
  116. package/src/standard/index.ts +17 -0
  117. package/src/standard/internal/renderer.ts +45 -0
  118. package/src/standard/json.ts +883 -0
  119. package/src/standard/primary-key.ts +17 -0
  120. package/src/standard/query.ts +152 -0
  121. package/src/standard/renderer.ts +49 -0
  122. package/src/standard/table.ts +151 -0
  123. package/src/standard/unique.ts +17 -0
  124. package/src/standard.ts +32 -0
  125. package/src/internal/aggregation-validation.ts +0 -57
  126. package/src/internal/table.d.ts +0 -180
  127. package/src/mysql/table.ts +0 -186
  128. package/src/postgres/cast.ts +0 -45
  129. package/src/sqlite/table.ts +0 -175
@@ -1,5 +1,5 @@
1
1
  import * as Expression from "../internal/scalar.js"
2
- import type * as ExpressionAst from "../internal/expression-ast.js"
2
+ import * as ExpressionAst from "../internal/expression-ast.js"
3
3
  import type { JsonPathUsageError } from "../internal/json/errors.js"
4
4
  import * as JsonPath from "../internal/json/path.js"
5
5
  import type {
@@ -9,11 +9,14 @@ import type {
9
9
  JsonTextResult,
10
10
  JsonValueAtPath
11
11
  } from "../internal/json/types.js"
12
+ import type { LiteralStringInput } from "../internal/table-options.js"
13
+ import type { JsonObjectKeyOf, WithJsonPathAccess } from "../internal/json/path-access.js"
14
+ import type { postgresDatatypes } from "./datatypes/index.js"
12
15
  import { json as postgresJson, jsonb as postgresJsonb } from "./internal/dsl.js"
13
16
 
14
17
  type PostgresJsonExpression<Runtime = unknown> = Expression.Scalar<
15
18
  Runtime,
16
- Expression.DbType.Json<"postgres", "json" | "jsonb">,
19
+ Expression.DbType.Json<"postgres" | "standard", "json" | "jsonb">,
17
20
  Expression.Nullability,
18
21
  string,
19
22
  Expression.ScalarKind,
@@ -29,12 +32,35 @@ type PostgresJsonbExpression<Runtime = unknown> = Expression.Scalar<
29
32
  Expression.BindingId
30
33
  >
31
34
 
35
+ type AnyJsonExpression<Runtime = unknown> = Expression.Scalar<
36
+ Runtime,
37
+ Expression.DbType.Json<any, any>,
38
+ Expression.Nullability,
39
+ string,
40
+ Expression.ScalarKind,
41
+ Expression.BindingId
42
+ >
43
+
32
44
  type ExactJsonPathInput = JsonPath.ExactSegment | JsonPath.Path<any>
33
45
 
46
+ type JsonPathPredicateExpression = Expression.Scalar<
47
+ string | null,
48
+ Expression.DbType.Any,
49
+ Expression.Nullability,
50
+ string,
51
+ Expression.ScalarKind,
52
+ Expression.BindingId
53
+ >
54
+
55
+ type JsonPathPredicateQuery = JsonPath.Path<any> | JsonPathPredicateExpression | string
56
+
57
+ type JsonPathPredicateQueryInput<Query extends JsonPathPredicateQuery> =
58
+ Query extends string ? LiteralStringInput<Query> : Query
59
+
34
60
  type ExactJsonPathUsageError<Target> = {
35
61
  readonly __effect_qb_error__: "effect-qb: postgres json helpers only accept exact key/index paths"
36
62
  readonly __effect_qb_json_path__: Target
37
- readonly __effect_qb_hint__: "Use Postgres.Json.jsonb.path(...) when you need wildcard(), slice(), or descend() segments"
63
+ readonly __effect_qb_hint__: "Use Postgres.Jsonb.key(), wildcard(), slice(), or descend() in a pipe when you need jsonb path traversal"
38
64
  }
39
65
 
40
66
  type ExactJsonPathGuard<Target> = Target extends JsonPath.Path<any>
@@ -43,9 +69,6 @@ type ExactJsonPathGuard<Target> = Target extends JsonPath.Path<any>
43
69
  ? unknown
44
70
  : ExactJsonPathUsageError<Target>
45
71
 
46
- type ExactJsonPathSegmentsGuard<Segments extends readonly JsonPath.CanonicalSegment[]> =
47
- JsonPath.IsExactPath<JsonPath.Path<Segments>> extends true ? unknown : ExactJsonPathUsageError<JsonPath.Path<Segments>>
48
-
49
72
  type JsonPathOutputOf<
50
73
  Root,
51
74
  Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment,
@@ -141,7 +164,7 @@ type JsonbOnlyUsageError<
141
164
  readonly __effect_qb_error__: "effect-qb: postgres jsonb helpers require a jsonb expression"
142
165
  readonly __effect_qb_json_operation__: Operation
143
166
  readonly __effect_qb_received_kind__: Expression.DbTypeOf<Value>["kind"]
144
- readonly __effect_qb_hint__: "Use Column.jsonb(...), Cast.to(..., Type.jsonb()), or Postgres.Json.jsonb.toJsonb(...)"
167
+ readonly __effect_qb_hint__: "Use Column.jsonb(...), Cast.to(..., Type.jsonb()), or Postgres.Jsonb.toJsonb(...)"
145
168
  }
146
169
 
147
170
  type JsonbBaseGuard<
@@ -151,11 +174,6 @@ type JsonbBaseGuard<
151
174
  ? unknown
152
175
  : JsonbOnlyUsageError<Operation, Base>
153
176
 
154
- type JsonNullabilityOf<Output> =
155
- null extends Output
156
- ? Exclude<Output, null> extends never ? "always" : "maybe"
157
- : "never"
158
-
159
177
  type JsonPathSegmentsOf<Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment> =
160
178
  Target extends JsonPath.Path<infer Segments extends readonly JsonPath.CanonicalSegment[]> ? Segments :
161
179
  Target extends JsonPath.CanonicalSegment ? readonly [Target] :
@@ -171,17 +189,27 @@ type JsonTextAccessKind<Target extends JsonPath.Path<any> | JsonPath.CanonicalSe
171
189
  ? JsonPath.IsExactPath<Target> extends true ? "jsonPathText" : "jsonTraverseText"
172
190
  : Target extends JsonPath.ExactSegment ? "jsonGetText" : "jsonAccessText"
173
191
 
192
+ type PostgresTextDb = ReturnType<typeof postgresDatatypes.text>
193
+ type PostgresBoolDb = ReturnType<typeof postgresDatatypes.boolean>
194
+
195
+ type DialectOf<Value extends Expression.Any> = Value[typeof Expression.TypeId]["dialect"]
196
+ type ScalarKindOf<Value extends Expression.Any> =
197
+ Extract<Expression.KindOf<Value>, "scalar"> extends never
198
+ ? Expression.KindOf<Value>
199
+ : Extract<Expression.KindOf<Value>, "scalar">
200
+
174
201
  type JsonResultExpression<
175
202
  Runtime,
176
203
  Db extends Expression.DbType.Json<any, any>,
177
204
  Kind extends Expression.ScalarKind = Expression.ScalarKind,
178
205
  Dependencies extends Expression.BindingId = Expression.BindingId,
179
- Ast extends ExpressionAst.Any = never
206
+ Ast extends ExpressionAst.Any = never,
207
+ Dialect extends string = string
180
208
  > = Expression.Scalar<
181
209
  Runtime,
182
210
  Db,
183
- JsonNullabilityOf<Runtime>,
184
- string,
211
+ Expression.Nullability,
212
+ Dialect,
185
213
  Kind,
186
214
  Dependencies
187
215
  > & ([Ast] extends [never] ? unknown : {
@@ -197,38 +225,390 @@ type JsonGetResultExpression<
197
225
  Base extends PostgresJsonExpression<any>,
198
226
  Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment,
199
227
  Operation extends string
200
- > = JsonResultExpression<
228
+ > = WithJsonPathAccess<JsonResultExpression<
201
229
  JsonPathOutputOf<Expression.RuntimeOf<Base>, Target, Operation>,
202
230
  JsonDbOf<Base>,
203
231
  Expression.KindOf<Base>,
204
232
  Expression.DependenciesOf<Base>,
205
- ExpressionAst.JsonAccessNode<JsonGetAccessKind<Target>, Base, JsonPathSegmentsOf<Target>>
206
- >
233
+ ExpressionAst.JsonAccessNode<JsonGetAccessKind<Target>, Base, JsonPathSegmentsOf<Target>>,
234
+ DialectOf<Base>
235
+ >>
207
236
 
208
237
  type JsonTextRuntime<
209
- Base extends PostgresJsonExpression<any>,
238
+ Base extends AnyJsonExpression<any>,
210
239
  Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment
211
240
  > =
212
241
  JsonTextResult<Exclude<JsonPathOutputOf<Expression.RuntimeOf<Base>, Target, "json.text">, JsonPathUsageError<any, any, any, any> | null>> |
213
242
  (null extends JsonPathOutputOf<Expression.RuntimeOf<Base>, Target, "json.text"> ? null : never)
214
243
 
215
244
  type JsonTextResultExpression<
216
- Base extends PostgresJsonExpression<any>,
245
+ Base extends AnyJsonExpression<any>,
217
246
  Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment
218
247
  > = Expression.Scalar<
219
248
  JsonTextRuntime<Base, Target>,
220
- Expression.DbType.Base<"postgres", "text">,
221
- JsonNullabilityOf<JsonTextRuntime<Base, Target>>,
222
- string,
249
+ PostgresTextDb,
250
+ Expression.Nullability,
251
+ DialectOf<Base>,
223
252
  Expression.KindOf<Base>,
224
253
  Expression.DependenciesOf<Base>
225
254
  > & {
226
255
  readonly [ExpressionAst.TypeId]: ExpressionAst.JsonAccessNode<JsonTextAccessKind<Target>, Base, JsonPathSegmentsOf<Target>>
227
256
  }
228
257
 
229
- const exactPath = <Segments extends readonly JsonPath.CanonicalSegment[]>(
230
- ...segments: Segments & ExactJsonPathSegmentsGuard<Segments>
231
- ): JsonPath.Path<Segments> => JsonPath.path(...segments) as unknown as JsonPath.Path<Segments>
258
+ type SegmentTuple<Segments> = Segments extends readonly JsonPath.CanonicalSegment[]
259
+ ? Segments
260
+ : readonly JsonPath.CanonicalSegment[]
261
+
262
+ type JsonAccessAst<Value> = Value extends {
263
+ readonly [ExpressionAst.TypeId]: infer Ast
264
+ } ? Ast : never
265
+
266
+ type JsonAccessExpression = {
267
+ readonly [ExpressionAst.TypeId]: ExpressionAst.JsonAccessNode<any, any, any>
268
+ }
269
+
270
+ type JsonAccessParts<
271
+ Value,
272
+ Acc extends readonly JsonPath.CanonicalSegment[] = readonly [],
273
+ Depth extends readonly unknown[] = []
274
+ > =
275
+ Depth["length"] extends 8 ? readonly [Value, readonly JsonPath.CanonicalSegment[]] :
276
+ [JsonAccessAst<Value>] extends [never]
277
+ ? Acc extends readonly [] ? never : readonly [Value, Acc]
278
+ : JsonAccessAst<Value> extends ExpressionAst.JsonAccessNode<any, infer Base extends Expression.Any, infer Segments>
279
+ ? JsonAccessParts<Base, readonly [...SegmentTuple<Segments>, ...Acc], readonly [...Depth, unknown]>
280
+ : Acc extends readonly [] ? never : readonly [Value, Acc]
281
+
282
+ type JsonAccessRoot<Value> =
283
+ JsonAccessParts<Value> extends readonly [infer Base, readonly JsonPath.CanonicalSegment[]]
284
+ ? Base
285
+ : Value
286
+
287
+ type JsonAccessSegments<Value> =
288
+ JsonAccessParts<Value> extends readonly [any, infer Segments extends readonly JsonPath.CanonicalSegment[]]
289
+ ? Segments
290
+ : never
291
+
292
+ type JsonAccessPath<Value> = JsonPath.Path<JsonAccessSegments<Value>>
293
+
294
+ type JsonAccessBase<Value extends Expression.Any> =
295
+ [JsonAccessSegments<Value>] extends [never]
296
+ ? Value
297
+ : JsonAccessRoot<Value> extends Expression.Any
298
+ ? JsonAccessRoot<Value>
299
+ : Value
300
+
301
+ type JsonTextValueRuntime<Value extends Expression.Any> =
302
+ (Exclude<Expression.RuntimeOf<Value>, JsonPathUsageError<any, any, any, any> | null> extends infer Runtime
303
+ ? Runtime extends string ? Runtime : string
304
+ : string) |
305
+ (null extends Expression.RuntimeOf<Value> ? null : never)
306
+
307
+ type JsonTextValueNullability<Value extends Expression.Any> =
308
+ null extends JsonTextValueRuntime<Value> ? "maybe" : "never"
309
+
310
+ type JsonAccessTextResultExpression<Value extends AnyJsonExpression<any>> =
311
+ Value extends JsonAccessExpression
312
+ ? Expression.Scalar<
313
+ JsonTextValueRuntime<Value>,
314
+ PostgresTextDb,
315
+ JsonTextValueNullability<Value>,
316
+ DialectOf<Value>,
317
+ ScalarKindOf<Value>,
318
+ Expression.DependenciesOf<Value>
319
+ > & {
320
+ readonly [ExpressionAst.TypeId]: ExpressionAst.JsonAccessNode<
321
+ "jsonPathText",
322
+ JsonAccessBase<Value>,
323
+ JsonAccessSegments<Value>
324
+ >
325
+ }
326
+ : JsonTextTerminalExpression<Value>
327
+
328
+ type JsonAccessDeleteResultExpression<
329
+ Value extends PostgresJsonExpression<any>,
330
+ Operation extends string
331
+ > = Value extends JsonAccessExpression
332
+ ? JsonAccessRoot<Value> extends PostgresJsonExpression<any>
333
+ ? WithJsonPathAccess<JsonResultExpression<
334
+ JsonDeleteOutputOf<Expression.RuntimeOf<JsonAccessRoot<Value>>, JsonAccessPath<Value>, Operation>,
335
+ Expression.DbTypeOf<JsonAccessRoot<Value>>,
336
+ Expression.KindOf<JsonAccessRoot<Value>>,
337
+ Expression.DependenciesOf<JsonAccessRoot<Value>>,
338
+ never,
339
+ DialectOf<JsonAccessRoot<Value>>
340
+ >>
341
+ : never
342
+ : WithJsonPathAccess<JsonResultExpression<
343
+ unknown,
344
+ Expression.DbTypeOf<Value>,
345
+ Expression.KindOf<Value>,
346
+ Expression.DependenciesOf<Value>,
347
+ never,
348
+ DialectOf<Value>
349
+ >>
350
+
351
+ type JsonAccessSetResultExpression<
352
+ Value extends PostgresJsonExpression<any>,
353
+ Next,
354
+ CreateMissing extends boolean
355
+ > = Value extends JsonAccessExpression
356
+ ? JsonAccessRoot<Value> extends PostgresJsonExpression<any>
357
+ ? WithJsonPathAccess<JsonResultExpression<
358
+ JsonSetOutputWithCreateMissing<Expression.RuntimeOf<JsonAccessRoot<Value>>, JsonAccessPath<Value>, Next, "json.set", CreateMissing>,
359
+ Expression.DbTypeOf<JsonAccessRoot<Value>>,
360
+ Expression.KindOf<JsonAccessRoot<Value>>,
361
+ Expression.DependenciesOf<JsonAccessRoot<Value>>,
362
+ never,
363
+ DialectOf<JsonAccessRoot<Value>>
364
+ >>
365
+ : never
366
+ : WithJsonPathAccess<JsonResultExpression<
367
+ unknown,
368
+ Expression.DbTypeOf<Value>,
369
+ Expression.KindOf<Value>,
370
+ Expression.DependenciesOf<Value>,
371
+ never,
372
+ DialectOf<Value>
373
+ >>
374
+
375
+ type JsonAccessInsertResultExpression<
376
+ Value extends PostgresJsonExpression<any>,
377
+ Next,
378
+ InsertAfter extends boolean
379
+ > = Value extends JsonAccessExpression
380
+ ? JsonAccessRoot<Value> extends PostgresJsonExpression<any>
381
+ ? WithJsonPathAccess<JsonResultExpression<
382
+ JsonInsertOutputOf<Expression.RuntimeOf<JsonAccessRoot<Value>>, JsonAccessPath<Value>, Next, InsertAfter, "json.insert">,
383
+ Expression.DbTypeOf<JsonAccessRoot<Value>>,
384
+ Expression.KindOf<JsonAccessRoot<Value>>,
385
+ Expression.DependenciesOf<JsonAccessRoot<Value>>,
386
+ never,
387
+ DialectOf<JsonAccessRoot<Value>>
388
+ >>
389
+ : never
390
+ : WithJsonPathAccess<JsonResultExpression<
391
+ unknown,
392
+ Expression.DbTypeOf<Value>,
393
+ Expression.KindOf<Value>,
394
+ Expression.DependenciesOf<Value>,
395
+ never,
396
+ DialectOf<Value>
397
+ >>
398
+
399
+ type JsonTextTerminalExpression<
400
+ Base extends AnyJsonExpression<any>
401
+ > = Expression.Scalar<
402
+ string | null,
403
+ PostgresTextDb,
404
+ Expression.Nullability,
405
+ DialectOf<Base>,
406
+ Expression.KindOf<Base>,
407
+ Expression.DependenciesOf<Base>
408
+ >
409
+
410
+ type JsonPredicateExpression<
411
+ Base extends PostgresJsonExpression<any>
412
+ > = Expression.Scalar<
413
+ boolean,
414
+ PostgresBoolDb,
415
+ "never",
416
+ DialectOf<Base>,
417
+ Expression.KindOf<Base>,
418
+ Expression.DependenciesOf<Base>
419
+ >
420
+
421
+ type JsonNullablePredicateExpression<
422
+ Base extends PostgresJsonExpression<any>
423
+ > = Expression.Scalar<
424
+ boolean | null,
425
+ PostgresBoolDb,
426
+ "maybe",
427
+ DialectOf<Base>,
428
+ Expression.KindOf<Base>,
429
+ Expression.DependenciesOf<Base>
430
+ >
431
+
432
+ type JsonbDeleteCallResult<
433
+ First,
434
+ Second,
435
+ Operation extends "json.delete" | "json.remove"
436
+ > =
437
+ First extends JsonPath.CanonicalSegment | JsonPath.Path<any>
438
+ ? <Base extends PostgresJsonbExpression<any>>(
439
+ base: Base
440
+ ) => WithJsonPathAccess<JsonResultExpression<
441
+ JsonDeleteOutputOf<Expression.RuntimeOf<Base>, First, Operation>,
442
+ Expression.DbTypeOf<Base>,
443
+ Expression.KindOf<Base>,
444
+ Expression.DependenciesOf<Base>,
445
+ never,
446
+ DialectOf<Base>
447
+ >>
448
+ : First extends PostgresJsonbExpression<any>
449
+ ? [Second] extends [undefined]
450
+ ? JsonAccessDeleteResultExpression<First, Operation>
451
+ : Second extends JsonPath.CanonicalSegment | JsonPath.Path<any>
452
+ ? WithJsonPathAccess<JsonResultExpression<
453
+ JsonDeleteOutputOf<Expression.RuntimeOf<First>, Second, Operation>,
454
+ Expression.DbTypeOf<First>,
455
+ Expression.KindOf<First>,
456
+ Expression.DependenciesOf<First>,
457
+ never,
458
+ DialectOf<First>
459
+ >>
460
+ : never
461
+ : never
462
+
463
+ type JsonAccessDeleteGuard<
464
+ Value,
465
+ Operation extends "json.delete" | "json.remove"
466
+ > = Value extends PostgresJsonExpression<any>
467
+ ? Value extends JsonAccessExpression
468
+ ? JsonAccessRoot<Value> extends PostgresJsonExpression<any>
469
+ ? JsonDeletePathGuard<Expression.RuntimeOf<JsonAccessRoot<Value>>, JsonAccessPath<Value>, Operation>
470
+ : unknown
471
+ : unknown
472
+ : unknown
473
+
474
+ type JsonbDeleteFirstGuard<
475
+ First,
476
+ Operation extends "json.delete" | "json.remove"
477
+ > = First extends JsonPath.CanonicalSegment | JsonPath.Path<any>
478
+ ? ExactJsonPathGuard<First>
479
+ : JsonAccessDeleteGuard<First, Operation>
480
+
481
+ type JsonbDeleteSecondGuard<
482
+ First,
483
+ Second,
484
+ Operation extends "json.delete" | "json.remove"
485
+ > = First extends PostgresJsonExpression<any>
486
+ ? Second extends JsonPath.CanonicalSegment | JsonPath.Path<any>
487
+ ? JsonDeletePathGuard<Expression.RuntimeOf<First>, Second, Operation>
488
+ : unknown
489
+ : unknown
490
+
491
+ type JsonTextCallResult<
492
+ First,
493
+ Second,
494
+ AllowedTarget extends JsonPath.CanonicalSegment | JsonPath.Path<any>
495
+ > =
496
+ First extends AllowedTarget
497
+ ? <Base extends PostgresJsonExpression<any>>(base: Base) => JsonTextResultExpression<Base, First>
498
+ : First extends PostgresJsonExpression<any>
499
+ ? [Second] extends [undefined]
500
+ ? JsonAccessTextResultExpression<First>
501
+ : Second extends AllowedTarget
502
+ ? JsonTextResultExpression<First, Second>
503
+ : never
504
+ : never
505
+
506
+ interface JsonbBaseSegmentOperation<Segment extends JsonPath.CanonicalSegment> {
507
+ <Base extends PostgresJsonbExpression<any>>(
508
+ base: Base
509
+ ): JsonGetResultExpression<Base, Segment, "json.get">
510
+ }
511
+
512
+ interface JsonbKeySegmentOperation<Key extends string>
513
+ extends JsonbBaseSegmentOperation<JsonPath.KeySegment<Key>>, JsonPath.KeySegment<Key> {}
514
+
515
+ interface JsonbIndexSegmentOperation<Index extends number>
516
+ extends JsonbBaseSegmentOperation<JsonPath.IndexSegment<Index>>, JsonPath.IndexSegment<Index> {}
517
+
518
+ interface JsonbWildcardSegmentOperation
519
+ extends JsonbBaseSegmentOperation<JsonPath.WildcardSegment>, JsonPath.WildcardSegment {}
520
+
521
+ interface JsonbSliceSegmentOperation<
522
+ Start extends number | undefined,
523
+ End extends number | undefined
524
+ > extends JsonbBaseSegmentOperation<JsonPath.SliceSegment<Start, End>>, JsonPath.SliceSegment<Start, End> {}
525
+
526
+ interface JsonbDescendSegmentOperation
527
+ extends JsonbBaseSegmentOperation<JsonPath.DescendSegment>, JsonPath.DescendSegment {}
528
+
529
+ type JsonbSegmentOperation<Segment extends JsonPath.CanonicalSegment> =
530
+ Segment extends JsonPath.KeySegment<infer Key extends string> ? JsonbKeySegmentOperation<Key> :
531
+ Segment extends JsonPath.IndexSegment<infer Index extends number> ? JsonbIndexSegmentOperation<Index> :
532
+ Segment extends JsonPath.WildcardSegment ? JsonbWildcardSegmentOperation :
533
+ Segment extends JsonPath.SliceSegment<infer Start extends number | undefined, infer End extends number | undefined> ? JsonbSliceSegmentOperation<Start, End> :
534
+ Segment extends JsonPath.DescendSegment ? JsonbDescendSegmentOperation :
535
+ never
536
+
537
+ const emptyPath = JsonPath.path()
538
+
539
+ const isObjectLike = (value: unknown): value is object =>
540
+ (typeof value === "object" || typeof value === "function") && value !== null
541
+
542
+ const isExpression = (value: unknown): value is Expression.Any =>
543
+ isObjectLike(value) && Expression.TypeId in value
544
+
545
+ const isPath = (value: unknown): value is JsonPath.Path<any> =>
546
+ isObjectLike(value) && JsonPath.TypeId in value
547
+
548
+ const isSegment = (value: unknown): value is JsonPath.CanonicalSegment =>
549
+ isObjectLike(value) && JsonPath.SegmentTypeId in value
550
+
551
+ const isTarget = (value: unknown): value is JsonPath.Path<any> | JsonPath.CanonicalSegment =>
552
+ isPath(value) || isSegment(value)
553
+
554
+ const normalizeSegment = <Segment extends JsonPath.CanonicalSegment>(
555
+ segment: Segment
556
+ ): Segment => {
557
+ switch (segment.kind) {
558
+ case "key":
559
+ return JsonPath.key(segment.key) as Segment
560
+ case "index":
561
+ return JsonPath.index(segment.index) as Segment
562
+ case "wildcard":
563
+ return JsonPath.wildcard() as Segment
564
+ case "slice":
565
+ return JsonPath.slice(segment.start, segment.end) as Segment
566
+ case "descend":
567
+ return JsonPath.descend() as Segment
568
+ }
569
+ }
570
+
571
+ const normalizeTarget = <Target extends JsonPath.Path<any> | JsonPath.CanonicalSegment>(
572
+ target: Target
573
+ ): Target =>
574
+ isPath(target)
575
+ ? JsonPath.path(...target.segments.map(normalizeSegment)) as Target
576
+ : normalizeSegment(target as JsonPath.CanonicalSegment) as unknown as Target
577
+
578
+ const accessKinds = new Set<string>([
579
+ "jsonGet",
580
+ "jsonPath",
581
+ "jsonAccess",
582
+ "jsonTraverse",
583
+ "jsonGetText",
584
+ "jsonPathText",
585
+ "jsonAccessText",
586
+ "jsonTraverseText"
587
+ ])
588
+
589
+ const accessPathOf = (value: Expression.Any): {
590
+ readonly base: Expression.Any
591
+ readonly path: JsonPath.Path<readonly JsonPath.CanonicalSegment[]>
592
+ } | undefined => {
593
+ const segments: JsonPath.CanonicalSegment[] = []
594
+ let base: Expression.Any = value
595
+ while (isExpression(base)) {
596
+ const ast = (base as Expression.Any & {
597
+ readonly [ExpressionAst.TypeId]: ExpressionAst.Any
598
+ })[ExpressionAst.TypeId] as { readonly kind?: unknown; readonly base?: unknown; readonly segments?: unknown }
599
+ if (typeof ast.kind !== "string" || !accessKinds.has(ast.kind) || !isExpression(ast.base) || !Array.isArray(ast.segments)) {
600
+ break
601
+ }
602
+ segments.unshift(...ast.segments.map(normalizeSegment))
603
+ base = ast.base
604
+ }
605
+ return segments.length === 0
606
+ ? undefined
607
+ : {
608
+ base,
609
+ path: JsonPath.path(...segments)
610
+ }
611
+ }
232
612
 
233
613
  const jsonGetDirect = <
234
614
  Base extends PostgresJsonExpression<any>,
@@ -237,7 +617,7 @@ const jsonGetDirect = <
237
617
  base: Base,
238
618
  target: Target & ExactJsonPathGuard<Target>
239
619
  ): JsonGetResultExpression<Base, Target, "json.get"> =>
240
- postgresJson.get(base as never, target as never) as unknown as JsonGetResultExpression<Base, Target, "json.get">
620
+ postgresJson.get(base as never, normalizeTarget(target) as never) as unknown as JsonGetResultExpression<Base, Target, "json.get">
241
621
 
242
622
  const jsonTextDirect = <
243
623
  Base extends PostgresJsonExpression<any>,
@@ -246,20 +626,53 @@ const jsonTextDirect = <
246
626
  base: Base,
247
627
  target: Target & ExactJsonPathGuard<Target>
248
628
  ): JsonTextResultExpression<Base, Target> =>
249
- postgresJson.text(base as never, target as never) as unknown as JsonTextResultExpression<Base, Target>
629
+ postgresJson.text(base as never, normalizeTarget(target) as never) as unknown as JsonTextResultExpression<Base, Target>
630
+
631
+ const jsonbGetDirect = <
632
+ Base extends PostgresJsonbExpression<any>,
633
+ Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
634
+ >(
635
+ base: Base,
636
+ target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.get">
637
+ ): JsonGetResultExpression<Base, Target, "json.get"> =>
638
+ postgresJsonb.get(base as Base, normalizeTarget(target)) as unknown as JsonGetResultExpression<Base, Target, "json.get">
639
+
640
+ const jsonbTextDirect = <
641
+ Base extends PostgresJsonbExpression<any>,
642
+ Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
643
+ >(
644
+ base: Base,
645
+ target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.text">
646
+ ): JsonTextResultExpression<Base, Target> =>
647
+ postgresJsonb.text(base as Base, normalizeTarget(target)) as unknown as JsonTextResultExpression<Base, Target>
648
+
649
+ const jsonbSegmentOperation = <Segment extends JsonPath.CanonicalSegment>(
650
+ segment: Segment
651
+ ): JsonbSegmentOperation<Segment> =>
652
+ Object.assign(
653
+ ((base: PostgresJsonbExpression<any>) => jsonbGetDirect(base as never, segment as never)) as unknown as JsonbSegmentOperation<Segment>,
654
+ segment
655
+ )
250
656
 
251
657
  const json = {
252
- key: postgresJson.key,
253
- index: postgresJson.index,
254
- path: exactPath,
255
- get: ((...args: [PostgresJsonExpression<any>, ExactJsonPathInput] | [ExactJsonPathInput]) =>
256
- args.length === 1
257
- ? ((base: PostgresJsonExpression<any>) => jsonGetDirect(base as never, args[0] as never))
258
- : jsonGetDirect(args[0] as never, args[1] as never)) as unknown as
259
- typeof jsonGetDirect & {
658
+ get: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
659
+ if (args.length === 1) {
660
+ const [first] = args
661
+ if (isTarget(first)) {
662
+ return (base: PostgresJsonExpression<any>) => jsonGetDirect(base as never, first as never)
663
+ }
664
+ return first
665
+ }
666
+ return jsonGetDirect(args[0] as never, args[1] as never)
667
+ }) as unknown as {
668
+ <Base extends PostgresJsonExpression<any>, Target extends ExactJsonPathInput>(
669
+ base: Base,
670
+ target: Target & ExactJsonPathGuard<Target>
671
+ ): JsonGetResultExpression<Base, Target, "json.get">
260
672
  <Target extends ExactJsonPathInput>(
261
673
  target: Target & ExactJsonPathGuard<Target>
262
674
  ): <Base extends PostgresJsonExpression<any>>(base: Base) => JsonGetResultExpression<Base, Target, "json.get">
675
+ <Base>(base: Base & PostgresJsonExpression<any>): Base & PostgresJsonExpression<any>
263
676
  },
264
677
  access: <
265
678
  Base extends PostgresJsonExpression<any>,
@@ -267,37 +680,41 @@ const json = {
267
680
  >(
268
681
  base: Base,
269
682
  target: Target & ExactJsonPathGuard<Target> & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.access">
270
- ) => postgresJson.access(base, target),
683
+ ) => postgresJson.access(base, normalizeTarget(target)),
271
684
  traverse: <
272
685
  Base extends PostgresJsonExpression<any>,
273
686
  Target extends ExactJsonPathInput
274
687
  >(
275
688
  base: Base,
276
689
  target: Target & ExactJsonPathGuard<Target> & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.traverse">
277
- ) => postgresJson.traverse(base, target),
278
- text: ((...args: [PostgresJsonExpression<any>, ExactJsonPathInput] | [ExactJsonPathInput]) =>
279
- args.length === 1
280
- ? ((base: PostgresJsonExpression<any>) => jsonTextDirect(base as never, args[0] as never))
281
- : jsonTextDirect(args[0] as never, args[1] as never)) as unknown as
282
- typeof jsonTextDirect & {
283
- <Target extends ExactJsonPathInput>(
284
- target: Target & ExactJsonPathGuard<Target>
285
- ): <Base extends PostgresJsonExpression<any>>(base: Base) => JsonTextResultExpression<Base, Target>
286
- },
690
+ ) => postgresJson.traverse(base, normalizeTarget(target)),
691
+ text: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
692
+ if (args.length === 1) {
693
+ const [first] = args
694
+ if (isTarget(first)) {
695
+ return (base: PostgresJsonExpression<any>) => jsonTextDirect(base as never, first as never)
696
+ }
697
+ const access = isExpression(first) ? accessPathOf(first) : undefined
698
+ return access === undefined
699
+ ? postgresJson.text(first as never, emptyPath as never)
700
+ : jsonTextDirect(access.base as never, access.path as never)
701
+ }
702
+ return jsonTextDirect(args[0] as never, args[1] as never)
703
+ }) as unknown as <Base extends PostgresJsonExpression<any>>(base: Base) => JsonAccessTextResultExpression<Base>,
287
704
  accessText: <
288
705
  Base extends PostgresJsonExpression<any>,
289
706
  Target extends ExactJsonPathInput
290
707
  >(
291
708
  base: Base,
292
709
  target: Target & ExactJsonPathGuard<Target> & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.accessText">
293
- ) => postgresJson.accessText(base, target),
710
+ ) => postgresJson.accessText(base, normalizeTarget(target)),
294
711
  traverseText: <
295
712
  Base extends PostgresJsonExpression<any>,
296
713
  Target extends ExactJsonPathInput
297
714
  >(
298
715
  base: Base,
299
716
  target: Target & ExactJsonPathGuard<Target> & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.traverseText">
300
- ) => postgresJson.traverseText(base, target),
717
+ ) => postgresJson.traverseText(base, normalizeTarget(target)),
301
718
  buildObject: postgresJson.buildObject,
302
719
  buildArray: postgresJson.buildArray,
303
720
  toJson: postgresJson.toJson,
@@ -305,6 +722,13 @@ const json = {
305
722
  length: postgresJson.length,
306
723
  keys: postgresJson.keys,
307
724
  stripNulls: postgresJson.stripNulls,
725
+ pathMatch: <
726
+ Base extends PostgresJsonExpression<any>,
727
+ Query extends JsonPathPredicateQuery
728
+ >(
729
+ base: Base,
730
+ query: JsonPathPredicateQueryInput<Query>
731
+ ) => postgresJson.pathMatch(base, query) as unknown as JsonNullablePredicateExpression<Base>,
308
732
  delete: <
309
733
  Base extends PostgresJsonExpression<any>,
310
734
  Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
@@ -314,7 +738,7 @@ const json = {
314
738
  ): JsonResultExpression<
315
739
  JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.delete">,
316
740
  Expression.DbTypeOf<Base>
317
- > => postgresJson.delete(base as any, target as any) as unknown as JsonResultExpression<
741
+ > => postgresJson.delete(base as any, normalizeTarget(target) as any) as unknown as JsonResultExpression<
318
742
  JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.delete">,
319
743
  Expression.DbTypeOf<Base>
320
744
  >,
@@ -327,61 +751,96 @@ const json = {
327
751
  ): JsonResultExpression<
328
752
  JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.remove">,
329
753
  Expression.DbTypeOf<Base>
330
- > => postgresJson.remove(base as any, target as any) as unknown as JsonResultExpression<
754
+ > => postgresJson.remove(base as any, normalizeTarget(target) as any) as unknown as JsonResultExpression<
331
755
  JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.remove">,
332
756
  Expression.DbTypeOf<Base>
333
757
  >
334
758
  }
335
759
 
336
760
  const jsonb = {
337
- key: postgresJsonb.key,
338
- index: postgresJsonb.index,
339
- wildcard: postgresJsonb.wildcard,
340
- slice: postgresJsonb.slice,
341
- descend: postgresJsonb.descend,
342
- path: postgresJsonb.path,
343
- get: <
344
- Base extends PostgresJsonExpression<any>,
345
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
761
+ key: <const Key extends string>(value: Key): JsonbSegmentOperation<JsonPath.KeySegment<Key>> =>
762
+ jsonbSegmentOperation(JsonPath.key(value)),
763
+ index: <const Index extends number>(value: Index): JsonbSegmentOperation<JsonPath.IndexSegment<Index>> =>
764
+ jsonbSegmentOperation(JsonPath.index(value)),
765
+ wildcard: (): JsonbSegmentOperation<JsonPath.WildcardSegment> =>
766
+ jsonbSegmentOperation(JsonPath.wildcard()),
767
+ slice: <
768
+ const Start extends number | undefined = undefined,
769
+ const End extends number | undefined = undefined
346
770
  >(
347
- base: Base & JsonbBaseGuard<Base, "jsonb.get">,
348
- target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.get">
349
- ) => postgresJsonb.get(base as Base, target),
771
+ start?: Start,
772
+ end?: End
773
+ ): JsonbSegmentOperation<JsonPath.SliceSegment<Start, End>> =>
774
+ jsonbSegmentOperation(JsonPath.slice(start, end)),
775
+ descend: (): JsonbSegmentOperation<JsonPath.DescendSegment> =>
776
+ jsonbSegmentOperation(JsonPath.descend()),
777
+ get: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
778
+ if (args.length === 1) {
779
+ const [first] = args
780
+ if (isTarget(first)) {
781
+ return (base: PostgresJsonbExpression<any>) => jsonbGetDirect(base as never, first as never)
782
+ }
783
+ const access = isExpression(first) ? accessPathOf(first) : undefined
784
+ return access === undefined
785
+ ? first
786
+ : jsonbGetDirect(access.base as never, access.path as never)
787
+ }
788
+ return jsonbGetDirect(args[0] as never, args[1] as never)
789
+ }) as unknown as {
790
+ <Base>(
791
+ base: Base & PostgresJsonbExpression<any>
792
+ ): Base & PostgresJsonbExpression<any>
793
+ <Base extends PostgresJsonbExpression<any>, Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>>(
794
+ base: Base,
795
+ target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.get">
796
+ ): JsonGetResultExpression<Base, Target, "json.get">
797
+ <Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>>(
798
+ target: Target & JsonValuePathGuard<any, Target, "json.get">
799
+ ): <Base extends PostgresJsonbExpression<any>>(
800
+ base: Base
801
+ ) => JsonGetResultExpression<Base, Target, "json.get">
802
+ },
350
803
  access: <
351
804
  Base extends PostgresJsonExpression<any>,
352
805
  Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
353
806
  >(
354
807
  base: Base & JsonbBaseGuard<Base, "jsonb.access">,
355
808
  target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.access">
356
- ) => postgresJsonb.access(base as Base, target),
809
+ ) => postgresJsonb.access(base as Base, normalizeTarget(target)),
357
810
  traverse: <
358
811
  Base extends PostgresJsonExpression<any>,
359
812
  Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
360
813
  >(
361
814
  base: Base & JsonbBaseGuard<Base, "jsonb.traverse">,
362
815
  target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.traverse">
363
- ) => postgresJsonb.traverse(base as Base, target),
364
- text: <
365
- Base extends PostgresJsonExpression<any>,
366
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
367
- >(
368
- base: Base & JsonbBaseGuard<Base, "jsonb.text">,
369
- target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.text">
370
- ) => postgresJsonb.text(base as Base, target),
816
+ ) => postgresJsonb.traverse(base as Base, normalizeTarget(target)),
817
+ text: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
818
+ if (args.length === 1) {
819
+ const [first] = args
820
+ if (isTarget(first)) {
821
+ return (base: PostgresJsonbExpression<any>) => jsonbTextDirect(base as never, first as never)
822
+ }
823
+ const access = isExpression(first) ? accessPathOf(first) : undefined
824
+ return access === undefined
825
+ ? postgresJsonb.text(first as never, emptyPath as never)
826
+ : jsonbTextDirect(access.base as never, access.path as never)
827
+ }
828
+ return jsonbTextDirect(args[0] as never, args[1] as never)
829
+ }) as unknown as <Base extends PostgresJsonbExpression<any>>(base: Base) => JsonAccessTextResultExpression<Base>,
371
830
  accessText: <
372
831
  Base extends PostgresJsonExpression<any>,
373
832
  Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
374
833
  >(
375
834
  base: Base & JsonbBaseGuard<Base, "jsonb.accessText">,
376
835
  target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.accessText">
377
- ) => postgresJsonb.accessText(base as Base, target),
836
+ ) => postgresJsonb.accessText(base as Base, normalizeTarget(target)),
378
837
  traverseText: <
379
838
  Base extends PostgresJsonExpression<any>,
380
839
  Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
381
840
  >(
382
841
  base: Base & JsonbBaseGuard<Base, "jsonb.traverseText">,
383
842
  target: Target & JsonValuePathGuard<Expression.RuntimeOf<Base>, Target, "json.traverseText">
384
- ) => postgresJsonb.traverseText(base as Base, target),
843
+ ) => postgresJsonb.traverseText(base as Base, normalizeTarget(target)),
385
844
  contains: <
386
845
  Left extends PostgresJsonExpression<any>,
387
846
  Right extends Parameters<typeof postgresJsonb.contains>[1]
@@ -396,98 +855,192 @@ const jsonb = {
396
855
  left: Left & JsonbBaseGuard<Left, "jsonb.containedBy">,
397
856
  right: Right
398
857
  ) => postgresJsonb.containedBy(left as Left, right),
399
- hasKey: <
400
- Base extends PostgresJsonExpression<any>,
401
- Key extends string
402
- >(
403
- base: Base & JsonbBaseGuard<Base, "jsonb.hasKey">,
404
- key: Key
405
- ) => postgresJsonb.hasKey(base as Base, key),
406
- keyExists: <
407
- Base extends PostgresJsonExpression<any>,
408
- Key extends string
409
- >(
410
- base: Base & JsonbBaseGuard<Base, "jsonb.keyExists">,
411
- key: Key
412
- ) => postgresJsonb.keyExists(base as Base, key),
413
- hasAnyKeys: <
414
- Base extends PostgresJsonExpression<any>,
415
- Keys extends readonly [string, ...string[]]
416
- >(
417
- base: Base & JsonbBaseGuard<Base, "jsonb.hasAnyKeys">,
418
- ...keys: Keys
419
- ) => postgresJsonb.hasAnyKeys(base as Base, ...keys),
420
- hasAllKeys: <
421
- Base extends PostgresJsonExpression<any>,
422
- Keys extends readonly [string, ...string[]]
423
- >(
424
- base: Base & JsonbBaseGuard<Base, "jsonb.hasAllKeys">,
425
- ...keys: Keys
426
- ) => postgresJsonb.hasAllKeys(base as Base, ...keys),
427
- delete: <
428
- Base extends PostgresJsonExpression<any>,
429
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
430
- >(
431
- base: Base & JsonbBaseGuard<Base, "jsonb.delete">,
432
- target: Target & JsonDeletePathGuard<Expression.RuntimeOf<Base>, Target, "json.delete">
433
- ): JsonResultExpression<
434
- JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.delete">,
435
- Expression.DbTypeOf<Base>
436
- > => postgresJsonb.delete(base as any, target as any) as unknown as JsonResultExpression<
437
- JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.delete">,
438
- Expression.DbTypeOf<Base>
439
- >,
440
- remove: <
441
- Base extends PostgresJsonExpression<any>,
442
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>
443
- >(
444
- base: Base & JsonbBaseGuard<Base, "jsonb.remove">,
445
- target: Target & JsonDeletePathGuard<Expression.RuntimeOf<Base>, Target, "json.remove">
446
- ): JsonResultExpression<
447
- JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.remove">,
448
- Expression.DbTypeOf<Base>
449
- > => postgresJsonb.remove(base as any, target as any) as unknown as JsonResultExpression<
450
- JsonDeleteOutputOf<Expression.RuntimeOf<Base>, Target, "json.remove">,
451
- Expression.DbTypeOf<Base>
452
- >,
453
- set: <
454
- Base extends PostgresJsonExpression<any>,
455
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>,
456
- Next extends Parameters<typeof postgresJsonb.set>[2],
457
- CreateMissing extends boolean = true
458
- >(
459
- base: Base & JsonbBaseGuard<Base, "jsonb.set">,
460
- target: Target & JsonSetPathGuard<Expression.RuntimeOf<Base>, Target, NoInfer<Next>, "json.set">,
461
- next: Next,
462
- options?: {
463
- readonly createMissing?: CreateMissing
858
+ hasKey: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
859
+ if (args.length === 1) {
860
+ const [key] = args
861
+ return (base: PostgresJsonExpression<any>) => postgresJsonb.hasKey(base as never, key as never)
464
862
  }
465
- ): JsonResultExpression<
466
- JsonSetOutputWithCreateMissing<Expression.RuntimeOf<Base>, Target, Next, "json.set", CreateMissing>,
467
- Expression.DbTypeOf<Base>
468
- > => postgresJsonb.set(base as any, target as any, next, options) as unknown as JsonResultExpression<
469
- JsonSetOutputWithCreateMissing<Expression.RuntimeOf<Base>, Target, Next, "json.set", CreateMissing>,
470
- Expression.DbTypeOf<Base>
471
- >,
472
- insert: <
473
- Base extends PostgresJsonExpression<any>,
474
- Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>,
475
- Next extends Parameters<typeof postgresJsonb.insert>[2],
476
- InsertAfter extends boolean = false
477
- >(
478
- base: Base & JsonbBaseGuard<Base, "jsonb.insert">,
479
- target: Target & JsonInsertPathGuard<Expression.RuntimeOf<Base>, Target, NoInfer<Next>, NoInfer<InsertAfter>, "json.insert">,
480
- next: Next,
481
- options?: {
482
- readonly insertAfter?: InsertAfter
863
+ const [base, key] = args
864
+ return postgresJsonb.hasKey(base as never, key as never)
865
+ }) as {
866
+ <Base extends PostgresJsonExpression<any>, Key extends JsonObjectKeyOf<Base>>(
867
+ base: Base & JsonbBaseGuard<Base, "jsonb.hasKey">,
868
+ key: Key
869
+ ): JsonPredicateExpression<Base>
870
+ <Key extends string>(
871
+ key: Key
872
+ ): <Base extends PostgresJsonExpression<any>>(
873
+ base: Base & JsonbBaseGuard<Base, "jsonb.hasKey"> & (Key extends JsonObjectKeyOf<Base> ? unknown : never)
874
+ ) => JsonPredicateExpression<Base>
875
+ },
876
+ keyExists: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
877
+ if (args.length === 1) {
878
+ const [key] = args
879
+ return (base: PostgresJsonExpression<any>) => postgresJsonb.keyExists(base as never, key as never)
483
880
  }
484
- ): JsonResultExpression<
485
- JsonInsertOutputOf<Expression.RuntimeOf<Base>, Target, Next, InsertAfter, "json.insert">,
486
- Expression.DbTypeOf<Base>
487
- > => postgresJsonb.insert(base as any, target as any, next, options) as unknown as JsonResultExpression<
488
- JsonInsertOutputOf<Expression.RuntimeOf<Base>, Target, Next, InsertAfter, "json.insert">,
489
- Expression.DbTypeOf<Base>
490
- >,
881
+ const [base, key] = args
882
+ return postgresJsonb.keyExists(base as never, key as never)
883
+ }) as {
884
+ <Base extends PostgresJsonExpression<any>, Key extends JsonObjectKeyOf<Base>>(
885
+ base: Base & JsonbBaseGuard<Base, "jsonb.keyExists">,
886
+ key: Key
887
+ ): JsonPredicateExpression<Base>
888
+ <Key extends string>(
889
+ key: Key
890
+ ): <Base extends PostgresJsonExpression<any>>(
891
+ base: Base & JsonbBaseGuard<Base, "jsonb.keyExists"> & (Key extends JsonObjectKeyOf<Base> ? unknown : never)
892
+ ) => JsonPredicateExpression<Base>
893
+ },
894
+ hasAnyKeys: ((base: PostgresJsonExpression<any>, ...keys: readonly string[]) =>
895
+ postgresJsonb.hasAnyKeys(base as never, ...(keys as [string, ...string[]]))) as {
896
+ <Base extends PostgresJsonExpression<any>, Keys extends readonly [JsonObjectKeyOf<Base>, ...JsonObjectKeyOf<Base>[]]>(
897
+ base: Base & JsonbBaseGuard<Base, "jsonb.hasAnyKeys">,
898
+ ...keys: Keys
899
+ ): JsonPredicateExpression<Base>
900
+ },
901
+ hasAllKeys: ((base: PostgresJsonExpression<any>, ...keys: readonly string[]) =>
902
+ postgresJsonb.hasAllKeys(base as never, ...(keys as [string, ...string[]]))) as {
903
+ <Base extends PostgresJsonExpression<any>, Keys extends readonly [JsonObjectKeyOf<Base>, ...JsonObjectKeyOf<Base>[]]>(
904
+ base: Base & JsonbBaseGuard<Base, "jsonb.hasAllKeys">,
905
+ ...keys: Keys
906
+ ): JsonPredicateExpression<Base>
907
+ },
908
+ delete: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
909
+ if (args.length === 1) {
910
+ const [first] = args
911
+ if (isTarget(first)) {
912
+ return (base: PostgresJsonbExpression<any>) => postgresJsonb.delete(base as any, normalizeTarget(first) as any)
913
+ }
914
+ const access = isExpression(first) ? accessPathOf(first) : undefined
915
+ if (access === undefined) {
916
+ throw new Error("Jsonb.delete requires a piped JSON path or an explicit target")
917
+ }
918
+ return postgresJsonb.delete(access.base as any, access.path as any)
919
+ }
920
+ return postgresJsonb.delete(args[0] as any, normalizeTarget(args[1] as JsonPath.CanonicalSegment | JsonPath.Path<any>) as any)
921
+ }) as unknown as <First extends PostgresJsonbExpression<any> | JsonPath.CanonicalSegment | JsonPath.Path<any>, Second extends JsonPath.CanonicalSegment | JsonPath.Path<any> | undefined = undefined>(
922
+ first: First & JsonbDeleteFirstGuard<First, "json.delete">,
923
+ second?: Second & JsonbDeleteSecondGuard<First, Second, "json.delete">
924
+ ) => JsonbDeleteCallResult<First, Second, "json.delete">,
925
+ remove: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
926
+ if (args.length === 1) {
927
+ const [first] = args
928
+ if (isTarget(first)) {
929
+ return (base: PostgresJsonbExpression<any>) => postgresJsonb.remove(base as any, normalizeTarget(first) as any)
930
+ }
931
+ const access = isExpression(first) ? accessPathOf(first) : undefined
932
+ if (access === undefined) {
933
+ throw new Error("Jsonb.remove requires a piped JSON path or an explicit target")
934
+ }
935
+ return postgresJsonb.remove(access.base as any, access.path as any)
936
+ }
937
+ return postgresJsonb.remove(args[0] as any, normalizeTarget(args[1] as JsonPath.CanonicalSegment | JsonPath.Path<any>) as any)
938
+ }) as unknown as <First extends PostgresJsonbExpression<any> | JsonPath.CanonicalSegment | JsonPath.Path<any>, Second extends JsonPath.CanonicalSegment | JsonPath.Path<any> | undefined = undefined>(
939
+ first: First & JsonbDeleteFirstGuard<First, "json.remove">,
940
+ second?: Second & JsonbDeleteSecondGuard<First, Second, "json.remove">
941
+ ) => JsonbDeleteCallResult<First, Second, "json.remove">,
942
+ set: ((...args: readonly unknown[]) => {
943
+ if (args.length === 1 || (args.length === 2 && !isExpression(args[0]))) {
944
+ const [next, options] = args
945
+ return (base: PostgresJsonbExpression<any>) => {
946
+ const access = accessPathOf(base)
947
+ if (access === undefined) {
948
+ throw new Error("Jsonb.set requires a piped JSON path or an explicit target")
949
+ }
950
+ return postgresJsonb.set(access.base as any, access.path as any, next as any, options as any)
951
+ }
952
+ }
953
+ if ((args.length === 2 || args.length === 3) && isExpression(args[0]) && !isTarget(args[1])) {
954
+ const [base, next, options] = args
955
+ const access = accessPathOf(base)
956
+ if (access === undefined) {
957
+ throw new Error("Jsonb.set requires a piped JSON path or an explicit target")
958
+ }
959
+ return postgresJsonb.set(access.base as any, access.path as any, next as any, options as any)
960
+ }
961
+ const [base, target, next, options] = args
962
+ return postgresJsonb.set(base as any, normalizeTarget(target as JsonPath.CanonicalSegment | JsonPath.Path<any>) as any, next as any, options as any)
963
+ }) as unknown as {
964
+ <Next extends Parameters<typeof postgresJsonb.set>[2], CreateMissing extends boolean = true>(
965
+ next: Next,
966
+ options?: {
967
+ readonly createMissing?: CreateMissing
968
+ }
969
+ ): <Base extends PostgresJsonbExpression<any>>(base: Base) => JsonAccessSetResultExpression<Base, Next, CreateMissing>
970
+ <Base extends PostgresJsonbExpression<any>, Next extends Parameters<typeof postgresJsonb.set>[2], CreateMissing extends boolean = true>(
971
+ base: Base,
972
+ next: Next,
973
+ options?: {
974
+ readonly createMissing?: CreateMissing
975
+ }
976
+ ): JsonAccessSetResultExpression<Base, Next, CreateMissing>
977
+ <Base extends PostgresJsonbExpression<any>, Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>, Next extends Parameters<typeof postgresJsonb.set>[2], CreateMissing extends boolean = true>(
978
+ base: Base,
979
+ target: Target & JsonSetPathGuard<Expression.RuntimeOf<Base>, Target, NoInfer<Next>, "json.set">,
980
+ next: Next,
981
+ options?: {
982
+ readonly createMissing?: CreateMissing
983
+ }
984
+ ): JsonResultExpression<
985
+ JsonSetOutputWithCreateMissing<Expression.RuntimeOf<Base>, Target, Next, "json.set", CreateMissing>,
986
+ Expression.DbTypeOf<Base>,
987
+ Expression.KindOf<Base>,
988
+ Expression.DependenciesOf<Base>,
989
+ never,
990
+ DialectOf<Base>
991
+ >
992
+ },
993
+ insert: ((...args: readonly unknown[]) => {
994
+ if (args.length === 1 || (args.length === 2 && !isExpression(args[0]))) {
995
+ const [next, options] = args
996
+ return (base: PostgresJsonbExpression<any>) => {
997
+ const access = accessPathOf(base)
998
+ if (access === undefined) {
999
+ throw new Error("Jsonb.insert requires a piped JSON path or an explicit target")
1000
+ }
1001
+ return postgresJsonb.insert(access.base as any, access.path as any, next as any, options as any)
1002
+ }
1003
+ }
1004
+ if ((args.length === 2 || args.length === 3) && isExpression(args[0]) && !isTarget(args[1])) {
1005
+ const [base, next, options] = args
1006
+ const access = accessPathOf(base)
1007
+ if (access === undefined) {
1008
+ throw new Error("Jsonb.insert requires a piped JSON path or an explicit target")
1009
+ }
1010
+ return postgresJsonb.insert(access.base as any, access.path as any, next as any, options as any)
1011
+ }
1012
+ const [base, target, next, options] = args
1013
+ return postgresJsonb.insert(base as any, normalizeTarget(target as JsonPath.CanonicalSegment | JsonPath.Path<any>) as any, next as any, options as any)
1014
+ }) as unknown as {
1015
+ <Next extends Parameters<typeof postgresJsonb.insert>[2], InsertAfter extends boolean = false>(
1016
+ next: Next,
1017
+ options?: {
1018
+ readonly insertAfter?: InsertAfter
1019
+ }
1020
+ ): <Base extends PostgresJsonbExpression<any>>(base: Base) => JsonAccessInsertResultExpression<Base, Next, InsertAfter>
1021
+ <Base extends PostgresJsonbExpression<any>, Next extends Parameters<typeof postgresJsonb.insert>[2], InsertAfter extends boolean = false>(
1022
+ base: Base,
1023
+ next: Next,
1024
+ options?: {
1025
+ readonly insertAfter?: InsertAfter
1026
+ }
1027
+ ): JsonAccessInsertResultExpression<Base, Next, InsertAfter>
1028
+ <Base extends PostgresJsonbExpression<any>, Target extends JsonPath.CanonicalSegment | JsonPath.Path<any>, Next extends Parameters<typeof postgresJsonb.insert>[2], InsertAfter extends boolean = false>(
1029
+ base: Base,
1030
+ target: Target & JsonInsertPathGuard<Expression.RuntimeOf<Base>, Target, NoInfer<Next>, NoInfer<InsertAfter>, "json.insert">,
1031
+ next: Next,
1032
+ options?: {
1033
+ readonly insertAfter?: InsertAfter
1034
+ }
1035
+ ): JsonResultExpression<
1036
+ JsonInsertOutputOf<Expression.RuntimeOf<Base>, Target, Next, InsertAfter, "json.insert">,
1037
+ Expression.DbTypeOf<Base>,
1038
+ Expression.KindOf<Base>,
1039
+ Expression.DependenciesOf<Base>,
1040
+ never,
1041
+ DialectOf<Base>
1042
+ >
1043
+ },
491
1044
  concat: postgresJsonb.concat,
492
1045
  merge: postgresJsonb.merge,
493
1046
  buildObject: postgresJsonb.buildObject,
@@ -513,21 +1066,57 @@ const jsonb = {
513
1066
  >(
514
1067
  base: Base & JsonbBaseGuard<Base, "jsonb.stripNulls">
515
1068
  ) => postgresJsonb.stripNulls(base as Base),
516
- pathExists: <
517
- Base extends PostgresJsonExpression<any>
518
- >(
519
- base: Base & JsonbBaseGuard<Base, "jsonb.pathExists">,
520
- query: Parameters<typeof postgresJsonb.pathExists>[1]
521
- ) => postgresJsonb.pathExists(base as Base, query),
1069
+ pathExists: ((...args: readonly [unknown] | readonly [unknown, unknown]) => {
1070
+ if (args.length === 1) {
1071
+ const [first] = args
1072
+ if (isTarget(first) || typeof first === "string") {
1073
+ return (base: PostgresJsonbExpression<any>) => postgresJsonb.pathExists(base as any, isTarget(first) ? normalizeTarget(first) as any : first as any)
1074
+ }
1075
+ const access = isExpression(first) ? accessPathOf(first) : undefined
1076
+ if (access === undefined) {
1077
+ throw new Error("Jsonb.pathExists requires a piped JSON path or an explicit query")
1078
+ }
1079
+ return postgresJsonb.pathExists(access.base as any, access.path as any)
1080
+ }
1081
+ const [base, query] = args
1082
+ return postgresJsonb.pathExists(base as any, isTarget(query) ? normalizeTarget(query) as any : query as any)
1083
+ }) as unknown as {
1084
+ <Base extends PostgresJsonbExpression<any>, Query extends JsonPathPredicateQuery>(
1085
+ base: Base,
1086
+ query: JsonPathPredicateQueryInput<Query>
1087
+ ): ReturnType<typeof postgresJsonb.pathExists<Base, Query>>
1088
+ <Query extends JsonPathPredicateQuery>(
1089
+ query: JsonPathPredicateQueryInput<Query>
1090
+ ): <Base extends PostgresJsonbExpression<any>>(base: Base) => ReturnType<typeof postgresJsonb.pathExists<Base, Query>>
1091
+ <Base extends PostgresJsonbExpression<any>>(base: Base): JsonPredicateExpression<Base>
1092
+ },
522
1093
  pathMatch: <
523
- Base extends PostgresJsonExpression<any>
1094
+ Base extends PostgresJsonExpression<any>,
1095
+ Query extends JsonPathPredicateQuery
524
1096
  >(
525
1097
  base: Base & JsonbBaseGuard<Base, "jsonb.pathMatch">,
526
- query: Parameters<typeof postgresJsonb.pathMatch>[1]
527
- ) => postgresJsonb.pathMatch(base as Base, query)
1098
+ query: JsonPathPredicateQueryInput<Query>
1099
+ ) => postgresJsonb.pathMatch(base as Base, query) as unknown as JsonNullablePredicateExpression<Base>
528
1100
  }
529
1101
 
530
1102
  /** Postgres shared JSON helpers for exact paths and functions that work on both json and jsonb. */
531
1103
  export { json }
1104
+ export const get = json.get
1105
+ export const access = json.access
1106
+ export const traverse = json.traverse
1107
+ export const text = json.text
1108
+ export const accessText = json.accessText
1109
+ export const traverseText = json.traverseText
1110
+ export const buildObject = json.buildObject
1111
+ export const buildArray = json.buildArray
1112
+ export const toJson = json.toJson
1113
+ export const typeOf = json.typeOf
1114
+ export const length = json.length
1115
+ export const keys = json.keys
1116
+ export const stripNulls = json.stripNulls
1117
+ export const pathMatch = json.pathMatch
1118
+ export const delete_ = json.delete
1119
+ export { delete_ as delete }
1120
+ export const remove = json.remove
532
1121
  /** Postgres jsonb-only helpers for containment, mutation, wildcard paths, and SQL/JSON path predicates. */
533
1122
  export { jsonb }