effect-qb 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1294 -0
  2. package/dist/mysql.js +57575 -0
  3. package/dist/postgres.js +6303 -0
  4. package/package.json +42 -0
  5. package/src/internal/aggregation-validation.ts +57 -0
  6. package/src/internal/case-analysis.ts +50 -0
  7. package/src/internal/coercion-analysis.ts +30 -0
  8. package/src/internal/coercion-errors.ts +29 -0
  9. package/src/internal/coercion-kind.ts +32 -0
  10. package/src/internal/coercion-normalize.ts +7 -0
  11. package/src/internal/coercion-rules.ts +25 -0
  12. package/src/internal/column-state.ts +453 -0
  13. package/src/internal/column.ts +417 -0
  14. package/src/internal/datatypes/define.ts +44 -0
  15. package/src/internal/datatypes/lookup.ts +280 -0
  16. package/src/internal/datatypes/shape.ts +72 -0
  17. package/src/internal/derived-table.ts +149 -0
  18. package/src/internal/dialect.ts +30 -0
  19. package/src/internal/executor.ts +390 -0
  20. package/src/internal/expression-ast.ts +349 -0
  21. package/src/internal/expression.ts +325 -0
  22. package/src/internal/grouping-key.ts +82 -0
  23. package/src/internal/json/ast.ts +63 -0
  24. package/src/internal/json/errors.ts +13 -0
  25. package/src/internal/json/path.ts +227 -0
  26. package/src/internal/json/shape.ts +1 -0
  27. package/src/internal/json/types.ts +386 -0
  28. package/src/internal/mysql-dialect.ts +39 -0
  29. package/src/internal/mysql-renderer.ts +37 -0
  30. package/src/internal/plan.ts +64 -0
  31. package/src/internal/postgres-dialect.ts +34 -0
  32. package/src/internal/postgres-renderer.ts +40 -0
  33. package/src/internal/predicate-analysis.ts +71 -0
  34. package/src/internal/predicate-atom.ts +43 -0
  35. package/src/internal/predicate-branches.ts +40 -0
  36. package/src/internal/predicate-context.ts +279 -0
  37. package/src/internal/predicate-formula.ts +100 -0
  38. package/src/internal/predicate-key.ts +28 -0
  39. package/src/internal/predicate-nnf.ts +12 -0
  40. package/src/internal/predicate-normalize.ts +202 -0
  41. package/src/internal/projection-alias.ts +15 -0
  42. package/src/internal/projections.ts +101 -0
  43. package/src/internal/query-ast.ts +297 -0
  44. package/src/internal/query-factory.ts +6757 -0
  45. package/src/internal/query-requirements.ts +40 -0
  46. package/src/internal/query.ts +1590 -0
  47. package/src/internal/renderer.ts +102 -0
  48. package/src/internal/runtime-normalize.ts +344 -0
  49. package/src/internal/runtime-schema.ts +428 -0
  50. package/src/internal/runtime-value.ts +85 -0
  51. package/src/internal/schema-derivation.ts +131 -0
  52. package/src/internal/sql-expression-renderer.ts +1353 -0
  53. package/src/internal/table-options.ts +225 -0
  54. package/src/internal/table.ts +674 -0
  55. package/src/mysql/column.ts +30 -0
  56. package/src/mysql/datatypes/index.ts +6 -0
  57. package/src/mysql/datatypes/spec.ts +180 -0
  58. package/src/mysql/errors/catalog.ts +51662 -0
  59. package/src/mysql/errors/fields.ts +21 -0
  60. package/src/mysql/errors/index.ts +18 -0
  61. package/src/mysql/errors/normalize.ts +232 -0
  62. package/src/mysql/errors/requirements.ts +73 -0
  63. package/src/mysql/executor.ts +134 -0
  64. package/src/mysql/query.ts +189 -0
  65. package/src/mysql/renderer.ts +19 -0
  66. package/src/mysql/table.ts +157 -0
  67. package/src/mysql.ts +18 -0
  68. package/src/postgres/column.ts +20 -0
  69. package/src/postgres/datatypes/index.ts +8 -0
  70. package/src/postgres/datatypes/spec.ts +264 -0
  71. package/src/postgres/errors/catalog.ts +452 -0
  72. package/src/postgres/errors/fields.ts +48 -0
  73. package/src/postgres/errors/index.ts +4 -0
  74. package/src/postgres/errors/normalize.ts +209 -0
  75. package/src/postgres/errors/requirements.ts +65 -0
  76. package/src/postgres/errors/types.ts +38 -0
  77. package/src/postgres/executor.ts +131 -0
  78. package/src/postgres/query.ts +189 -0
  79. package/src/postgres/renderer.ts +29 -0
  80. package/src/postgres/table.ts +157 -0
  81. package/src/postgres.ts +18 -0
@@ -0,0 +1,82 @@
1
+ import * as Expression from "./expression.js"
2
+ import * as ExpressionAst from "./expression-ast.js"
3
+
4
+ const literalGroupingKey = (value: unknown): string => {
5
+ if (value instanceof Date) {
6
+ return `date:${value.toISOString()}`
7
+ }
8
+ if (value === null) {
9
+ return "null"
10
+ }
11
+ switch (typeof value) {
12
+ case "string":
13
+ return `string:${JSON.stringify(value)}`
14
+ case "number":
15
+ return `number:${value}`
16
+ case "boolean":
17
+ return `boolean:${value}`
18
+ default:
19
+ return `literal:${JSON.stringify(value)}`
20
+ }
21
+ }
22
+
23
+ export const groupingKeyOfExpression = (expression: Expression.Any): string => {
24
+ const ast = (expression as Expression.Any & {
25
+ readonly [ExpressionAst.TypeId]: ExpressionAst.Any
26
+ })[ExpressionAst.TypeId]
27
+ switch (ast.kind) {
28
+ case "column":
29
+ return `column:${ast.tableName}.${ast.columnName}`
30
+ case "literal":
31
+ return `literal:${literalGroupingKey(ast.value)}`
32
+ case "cast":
33
+ return `cast(${groupingKeyOfExpression(ast.value)} as ${ast.target.dialect}:${ast.target.kind})`
34
+ case "isNull":
35
+ case "isNotNull":
36
+ case "not":
37
+ case "upper":
38
+ case "lower":
39
+ case "count":
40
+ case "max":
41
+ case "min":
42
+ return `${ast.kind}(${groupingKeyOfExpression(ast.value)})`
43
+ case "eq":
44
+ case "neq":
45
+ case "lt":
46
+ case "lte":
47
+ case "gt":
48
+ case "gte":
49
+ case "like":
50
+ case "ilike":
51
+ case "isDistinctFrom":
52
+ case "isNotDistinctFrom":
53
+ return `${ast.kind}(${groupingKeyOfExpression(ast.left)},${groupingKeyOfExpression(ast.right)})`
54
+ case "and":
55
+ case "or":
56
+ case "coalesce":
57
+ case "concat":
58
+ case "in":
59
+ case "notIn":
60
+ case "between":
61
+ return `${ast.kind}(${ast.values.map(groupingKeyOfExpression).join(",")})`
62
+ case "case":
63
+ return `case(${ast.branches.map((branch: ExpressionAst.CaseBranchNode) =>
64
+ `when:${groupingKeyOfExpression(branch.when)}=>${groupingKeyOfExpression(branch.then)}`).join("|")};else:${groupingKeyOfExpression(ast.else)})`
65
+ default:
66
+ throw new Error("Unsupported expression for grouping key generation")
67
+ }
68
+ }
69
+
70
+ export const dedupeGroupedExpressions = <Values extends readonly Expression.Any[]>(
71
+ values: Values
72
+ ): Values => {
73
+ const seen = new Set<string>()
74
+ return values.filter((value) => {
75
+ const key = groupingKeyOfExpression(value)
76
+ if (seen.has(key)) {
77
+ return false
78
+ }
79
+ seen.add(key)
80
+ return true
81
+ }) as unknown as Values
82
+ }
@@ -0,0 +1,63 @@
1
+ import type * as Expression from ".././expression.js"
2
+ import type * as JsonPath from "./path.js"
3
+
4
+ export type JsonKind =
5
+ | "jsonGet"
6
+ | "jsonPath"
7
+ | "jsonAccess"
8
+ | "jsonTraverse"
9
+ | "jsonGetText"
10
+ | "jsonPathText"
11
+ | "jsonAccessText"
12
+ | "jsonTraverseText"
13
+ | "jsonHasKey"
14
+ | "jsonKeyExists"
15
+ | "jsonHasAnyKeys"
16
+ | "jsonHasAllKeys"
17
+ | "jsonConcat"
18
+ | "jsonMerge"
19
+ | "jsonDelete"
20
+ | "jsonDeletePath"
21
+ | "jsonRemove"
22
+ | "jsonSet"
23
+ | "jsonInsert"
24
+ | "jsonPathExists"
25
+ | "jsonPathMatch"
26
+ | "jsonBuildObject"
27
+ | "jsonBuildArray"
28
+ | "jsonToJson"
29
+ | "jsonToJsonb"
30
+ | "jsonTypeOf"
31
+ | "jsonLength"
32
+ | "jsonKeys"
33
+ | "jsonStripNulls"
34
+
35
+ /**
36
+ * Broad JSON AST node accepted by the renderer.
37
+ *
38
+ * The JSON subsystem is intentionally shaped as a small grammar rather than a
39
+ * collection of bespoke node interfaces. The renderer uses the `kind` plus the
40
+ * common field names below to lower the nodes into dialect SQL.
41
+ */
42
+ export interface JsonNode<
43
+ Kind extends JsonKind = JsonKind
44
+ > {
45
+ readonly kind: Kind
46
+ readonly value?: Expression.Any
47
+ readonly base?: Expression.Any
48
+ readonly left?: Expression.Any
49
+ readonly right?: Expression.Any
50
+ readonly path?: JsonPath.Path<any> | readonly any[]
51
+ readonly segments?: readonly any[]
52
+ readonly keys?: readonly string[]
53
+ readonly query?: string | Expression.Any
54
+ readonly newValue?: Expression.Any
55
+ readonly insert?: Expression.Any
56
+ readonly createMissing?: boolean
57
+ readonly insertAfter?: boolean
58
+ readonly entries?: readonly {
59
+ readonly key: string
60
+ readonly value: Expression.Any
61
+ }[]
62
+ readonly values?: readonly Expression.Any[]
63
+ }
@@ -0,0 +1,13 @@
1
+ export type JsonPathUsageError<
2
+ Operation extends string,
3
+ Root,
4
+ Path,
5
+ Reason extends string
6
+ > = {
7
+ readonly __effect_qb_error__: "effect-qb: invalid json path usage"
8
+ readonly __effect_qb_json_operation__: Operation
9
+ readonly __effect_qb_json_reason__: Reason
10
+ readonly __effect_qb_json_root__: Root
11
+ readonly __effect_qb_json_path__: Path
12
+ readonly __effect_qb_hint__: "Use key(...) on objects, index(...) on arrays, and prefer exact key/index paths when you want precise output typing"
13
+ }
@@ -0,0 +1,227 @@
1
+ import type * as Expression from ".././expression.js"
2
+ import type { JsonPathUsageError } from "./errors.js"
3
+ import type {
4
+ JsonBuildArray as JsonBuildArrayResult,
5
+ JsonBuildObject as JsonBuildObjectResult,
6
+ JsonConcatResult,
7
+ JsonDeleteAtPath,
8
+ JsonInsertAtPath,
9
+ JsonLiteralInput,
10
+ JsonStripNullsResult as JsonStripNullsResultValue,
11
+ JsonValueAtPath,
12
+ JsonSetAtPath
13
+ } from "./types.js"
14
+ import type { JsonKeysResult as JsonKeysResultValue, JsonLengthResult as JsonLengthResultValue, JsonTextResult as JsonTextResultValue, JsonTypeName as JsonTypeNameValue } from "./types.js"
15
+
16
+ export const SegmentTypeId: unique symbol = Symbol.for("effect-qb/JsonPathSegment")
17
+
18
+ export type SegmentTypeId = typeof SegmentTypeId
19
+
20
+ export const TypeId: unique symbol = Symbol.for("effect-qb/JsonPath")
21
+
22
+ export type TypeId = typeof TypeId
23
+
24
+ type SegmentState<Kind extends string> = {
25
+ readonly kind: Kind
26
+ }
27
+
28
+ export interface KeySegment<Key extends string = string> {
29
+ readonly [SegmentTypeId]: SegmentState<"key">
30
+ readonly kind: "key"
31
+ readonly key: Key
32
+ }
33
+
34
+ export interface IndexSegment<Index extends number = number> {
35
+ readonly [SegmentTypeId]: SegmentState<"index">
36
+ readonly kind: "index"
37
+ readonly index: Index
38
+ }
39
+
40
+ export interface WildcardSegment {
41
+ readonly [SegmentTypeId]: SegmentState<"wildcard">
42
+ readonly kind: "wildcard"
43
+ }
44
+
45
+ export interface SliceSegment<
46
+ Start extends number | undefined = number | undefined,
47
+ End extends number | undefined = number | undefined
48
+ > {
49
+ readonly [SegmentTypeId]: SegmentState<"slice">
50
+ readonly kind: "slice"
51
+ readonly start: Start
52
+ readonly end: End
53
+ }
54
+
55
+ export interface DescendSegment {
56
+ readonly [SegmentTypeId]: SegmentState<"descend">
57
+ readonly kind: "descend"
58
+ }
59
+
60
+ export type CanonicalSegment =
61
+ | KeySegment
62
+ | IndexSegment
63
+ | WildcardSegment
64
+ | SliceSegment
65
+ | DescendSegment
66
+
67
+ export type AnySegment = any
68
+
69
+ export type ExactSegment = KeySegment | IndexSegment
70
+
71
+ type PathState<Segments extends readonly CanonicalSegment[]> = {
72
+ readonly segments: Segments
73
+ }
74
+
75
+ export interface Path<Segments extends readonly CanonicalSegment[] = readonly CanonicalSegment[]> {
76
+ readonly [TypeId]: PathState<Segments>
77
+ readonly segments: Segments
78
+ }
79
+
80
+ export type JsonPath<Segments extends readonly CanonicalSegment[] = readonly CanonicalSegment[]> = Path<Segments>
81
+
82
+ export type JsonPathSegments = readonly CanonicalSegment[]
83
+
84
+ export type JsonPrimitive = JsonLiteralInput
85
+
86
+ export type JsonLiteral = JsonLiteralInput
87
+
88
+ export type JsonInput = Expression.Any | JsonLiteral
89
+
90
+ const makeSegment = <Segment extends CanonicalSegment>(segment: Segment): Segment => segment
91
+
92
+ export const key = <Key extends string>(value: Key): KeySegment<Key> =>
93
+ makeSegment({
94
+ [SegmentTypeId]: {
95
+ kind: "key"
96
+ },
97
+ kind: "key",
98
+ key: value
99
+ } as KeySegment<Key>)
100
+
101
+ export const index = <Index extends number>(value: Index): IndexSegment<Index> =>
102
+ makeSegment({
103
+ [SegmentTypeId]: {
104
+ kind: "index"
105
+ },
106
+ kind: "index",
107
+ index: value
108
+ } as IndexSegment<Index>)
109
+
110
+ export const wildcard = (): WildcardSegment =>
111
+ makeSegment({
112
+ [SegmentTypeId]: {
113
+ kind: "wildcard"
114
+ },
115
+ kind: "wildcard"
116
+ })
117
+
118
+ export const slice = <
119
+ Start extends number | undefined = undefined,
120
+ End extends number | undefined = undefined
121
+ >(
122
+ start?: Start,
123
+ end?: End
124
+ ): SliceSegment<Start, End> =>
125
+ makeSegment({
126
+ [SegmentTypeId]: {
127
+ kind: "slice"
128
+ },
129
+ kind: "slice",
130
+ start: start as Start,
131
+ end: end as End
132
+ } as SliceSegment<Start, End>)
133
+
134
+ export const descend = (): DescendSegment =>
135
+ makeSegment({
136
+ [SegmentTypeId]: {
137
+ kind: "descend"
138
+ },
139
+ kind: "descend"
140
+ })
141
+
142
+ export const path = <Segments extends readonly CanonicalSegment[]>(
143
+ ...segments: Segments
144
+ ): Path<Segments> => ({
145
+ [TypeId]: {
146
+ segments
147
+ },
148
+ segments
149
+ })
150
+
151
+ export const makeJsonPath = path
152
+
153
+ export type SegmentsOf<Value extends Path<any>> = Value[typeof TypeId]["segments"]
154
+
155
+ export type IsExactSegment<Segment extends CanonicalSegment> = Segment extends ExactSegment ? true : false
156
+
157
+ export type IsExactPath<PathValue extends Path<any>> =
158
+ SegmentsOf<PathValue> extends readonly [infer Head extends CanonicalSegment, ...infer Tail extends readonly CanonicalSegment[]]
159
+ ? IsExactSegment<Head> extends true
160
+ ? Tail extends readonly []
161
+ ? true
162
+ : IsExactPath<Path<Tail>>
163
+ : false
164
+ : true
165
+
166
+ export type JsonPathValue<
167
+ Root,
168
+ PathValue extends Path<any>,
169
+ Operation extends string = "json.get"
170
+ > = JsonValueAtPath<Root, PathValue, Operation>
171
+
172
+ export type JsonPathOutput<
173
+ Root,
174
+ PathValue extends Path<any>,
175
+ Operation extends string = "json.get"
176
+ > = JsonValueAtPath<Root, PathValue, Operation>
177
+
178
+ export type JsonPathCompatible<
179
+ Root,
180
+ PathValue extends Path<any>,
181
+ Operation extends string = "json.get"
182
+ > = JsonValueAtPath<Root, PathValue, Operation> extends JsonPathUsageError<any, any, any, any>
183
+ ? JsonValueAtPath<Root, PathValue, Operation>
184
+ : PathValue
185
+
186
+ export type JsonPathUpdate<
187
+ Root,
188
+ PathValue extends Path<any>,
189
+ Next,
190
+ Operation extends string = "json.set"
191
+ > = JsonSetAtPath<Root, PathValue, Next, Operation>
192
+
193
+ export type JsonPathDelete<
194
+ Root,
195
+ PathValue extends Path<any>,
196
+ Operation extends string = "json.delete"
197
+ > = JsonDeleteAtPath<Root, PathValue, Operation>
198
+
199
+ export type JsonConcat<
200
+ Left,
201
+ Right
202
+ > = JsonConcatResult<Left, Right>
203
+
204
+ export type JsonBuildObject<
205
+ Shape extends Record<string, JsonInput>
206
+ > = JsonBuildObjectResult<Shape>
207
+
208
+ export type JsonBuildArray<
209
+ Values extends readonly JsonInput[]
210
+ > = JsonBuildArrayResult<Values>
211
+
212
+ export type JsonTextResult<Value> = JsonTextResultValue<Value>
213
+
214
+ export type JsonTypeName<Value> = JsonTypeNameValue<Value>
215
+
216
+ export type JsonLengthResult<Value> = JsonLengthResultValue<Value>
217
+
218
+ export type JsonKeysResult<Value> = JsonKeysResultValue<Value>
219
+
220
+ export type JsonStripNullsResult<Value> = JsonStripNullsResultValue<Value>
221
+
222
+ export type JsonValueOfInput<Input> =
223
+ Input extends Expression.Any
224
+ ? Expression.RuntimeOf<Input>
225
+ : Input extends JsonLiteral
226
+ ? Input
227
+ : never
@@ -0,0 +1 @@
1
+ export type JsonShape = Record<string, unknown> | readonly unknown[] | string | number | boolean | null