effect-qb 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1431
- package/dist/mysql.js +61945 -3611
- package/dist/postgres/metadata.js +2818 -0
- package/dist/postgres.js +9942 -5591
- package/package.json +21 -10
- package/src/internal/aggregation-validation.ts +3 -3
- package/src/internal/case-analysis.d.ts +18 -0
- package/src/internal/case-analysis.ts +4 -4
- package/src/internal/coercion/analysis.d.ts +7 -0
- package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
- package/src/internal/coercion/errors.d.ts +17 -0
- package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
- package/src/internal/coercion/kind.d.ts +4 -0
- package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
- package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
- package/src/internal/coercion/rules.d.ts +6 -0
- package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
- package/src/internal/column-state.d.ts +190 -0
- package/src/internal/column-state.ts +119 -56
- package/src/internal/column.ts +387 -149
- package/src/internal/datatypes/define.d.ts +17 -0
- package/src/internal/datatypes/define.ts +18 -34
- package/src/internal/datatypes/lookup.d.ts +44 -0
- package/src/internal/datatypes/lookup.ts +61 -152
- package/src/internal/datatypes/shape.d.ts +16 -0
- package/src/internal/datatypes/shape.ts +1 -1
- package/src/internal/derived-table.d.ts +4 -0
- package/src/internal/derived-table.ts +21 -16
- package/src/internal/dsl-mutation-runtime.ts +378 -0
- package/src/internal/dsl-plan-runtime.ts +387 -0
- package/src/internal/dsl-query-runtime.ts +160 -0
- package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
- package/src/internal/executor.ts +173 -38
- package/src/internal/expression-ast.ts +19 -5
- package/src/internal/grouping-key.d.ts +3 -0
- package/src/internal/grouping-key.ts +1 -1
- package/src/internal/implication-runtime.d.ts +15 -0
- package/src/internal/implication-runtime.ts +171 -0
- package/src/internal/json/ast.d.ts +30 -0
- package/src/internal/json/ast.ts +1 -1
- package/src/internal/json/errors.d.ts +8 -0
- package/src/internal/json/path.d.ts +75 -0
- package/src/internal/json/path.ts +1 -1
- package/src/internal/json/types.d.ts +62 -0
- package/src/internal/predicate/analysis.d.ts +20 -0
- package/src/internal/{predicate-analysis.ts → predicate/analysis.ts} +13 -3
- package/src/internal/predicate/atom.d.ts +28 -0
- package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
- package/src/internal/predicate/context.d.ts +67 -0
- package/src/internal/{predicate-context.ts → predicate/context.ts} +111 -32
- package/src/internal/predicate/formula.d.ts +35 -0
- package/src/internal/{predicate-formula.ts → predicate/formula.ts} +32 -20
- package/src/internal/predicate/key.d.ts +11 -0
- package/src/internal/{predicate-key.ts → predicate/key.ts} +2 -2
- package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
- package/src/internal/predicate/normalize.d.ts +53 -0
- package/src/internal/predicate/normalize.ts +273 -0
- package/src/internal/predicate/runtime.d.ts +31 -0
- package/src/internal/predicate/runtime.ts +679 -0
- package/src/internal/projection-alias.d.ts +13 -0
- package/src/internal/projections.d.ts +31 -0
- package/src/internal/projections.ts +1 -1
- package/src/internal/query-ast.d.ts +217 -0
- package/src/internal/query-ast.ts +1 -1
- package/src/internal/query-requirements.d.ts +20 -0
- package/src/internal/query.d.ts +775 -0
- package/src/internal/query.ts +767 -275
- package/src/internal/renderer.ts +7 -21
- package/src/internal/row-set.d.ts +53 -0
- package/src/internal/{plan.ts → row-set.ts} +23 -11
- package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
- package/src/internal/{runtime-schema.ts → runtime/schema.ts} +84 -55
- package/src/internal/runtime/value.d.ts +22 -0
- package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
- package/src/internal/scalar.d.ts +107 -0
- package/src/internal/scalar.ts +191 -0
- package/src/internal/schema-derivation.d.ts +105 -0
- package/src/internal/schema-derivation.ts +93 -21
- package/src/internal/schema-expression.d.ts +18 -0
- package/src/internal/schema-expression.ts +75 -0
- package/src/internal/table-options.d.ts +94 -0
- package/src/internal/table-options.ts +94 -8
- package/src/internal/table.d.ts +173 -0
- package/src/internal/table.ts +135 -54
- package/src/mysql/column.ts +95 -18
- package/src/mysql/datatypes/index.ts +58 -3
- package/src/mysql/errors/generated.ts +57336 -0
- package/src/mysql/errors/index.ts +1 -0
- package/src/mysql/errors/normalize.ts +55 -53
- package/src/mysql/errors/types.ts +74 -0
- package/src/mysql/executor.ts +69 -7
- package/src/mysql/function/aggregate.ts +1 -5
- package/src/mysql/function/core.ts +1 -3
- package/src/mysql/function/index.ts +1 -1
- package/src/mysql/function/string.ts +1 -5
- package/src/mysql/function/temporal.ts +12 -15
- package/src/mysql/function/window.ts +1 -6
- package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +1 -1
- package/src/mysql/internal/dsl.ts +6115 -0
- package/src/{internal/mysql-renderer.ts → mysql/internal/renderer.ts} +6 -6
- package/src/mysql/internal/sql-expression-renderer.ts +1455 -0
- package/src/mysql/json.ts +2 -0
- package/src/mysql/query.ts +111 -86
- package/src/mysql/renderer.ts +1 -1
- package/src/mysql/table.ts +1 -1
- package/src/mysql.ts +6 -4
- package/src/postgres/cast.ts +30 -0
- package/src/postgres/column.ts +178 -20
- package/src/postgres/datatypes/index.d.ts +515 -0
- package/src/postgres/datatypes/index.ts +49 -5
- package/src/postgres/datatypes/spec.d.ts +412 -0
- package/src/postgres/errors/generated.ts +2636 -0
- package/src/postgres/errors/index.ts +1 -0
- package/src/postgres/errors/normalize.ts +47 -62
- package/src/postgres/errors/types.ts +92 -34
- package/src/postgres/executor.ts +37 -5
- package/src/postgres/function/aggregate.ts +1 -5
- package/src/postgres/function/core.ts +20 -2
- package/src/postgres/function/index.ts +1 -1
- package/src/postgres/function/string.ts +1 -5
- package/src/postgres/function/temporal.ts +12 -15
- package/src/postgres/function/window.ts +1 -6
- package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +1 -1
- package/src/{internal/query-factory.ts → postgres/internal/dsl.ts} +1568 -2120
- package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +6 -6
- package/src/postgres/internal/schema-ddl.ts +108 -0
- package/src/postgres/internal/schema-model.ts +150 -0
- package/src/{internal → postgres/internal}/sql-expression-renderer.ts +112 -46
- package/src/postgres/json.ts +493 -0
- package/src/postgres/metadata.ts +31 -0
- package/src/postgres/query.ts +113 -86
- package/src/postgres/renderer.ts +3 -13
- package/src/postgres/schema-expression.ts +17 -0
- package/src/postgres/schema-management.ts +204 -0
- package/src/postgres/schema.ts +35 -0
- package/src/postgres/table.ts +316 -42
- package/src/postgres/type.ts +31 -0
- package/src/postgres.ts +20 -4
- package/CHANGELOG.md +0 -134
- package/src/internal/expression.ts +0 -327
- package/src/internal/predicate-normalize.ts +0 -202
- package/src/mysql/function/json.ts +0 -4
- package/src/mysql/private/query.ts +0 -13
- package/src/postgres/function/json.ts +0 -4
- package/src/postgres/private/query.ts +0 -13
- /package/src/internal/{predicate-atom.ts → predicate/atom.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type * as Expression from "./
|
|
1
|
+
import type * as Expression from "./scalar.js"
|
|
2
2
|
import type * as Query from "./query.js"
|
|
3
3
|
import type * as JsonPath from "./json/path.js"
|
|
4
4
|
import type { JsonNode } from "./json/ast.js"
|
|
@@ -34,6 +34,15 @@ export interface CastNode<
|
|
|
34
34
|
readonly target: Target
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/** Explicit collation captured by the internal expression AST. */
|
|
38
|
+
export interface CollateNode<
|
|
39
|
+
Value extends Expression.Any = Expression.Any
|
|
40
|
+
> {
|
|
41
|
+
readonly kind: "collate"
|
|
42
|
+
readonly value: Value
|
|
43
|
+
readonly collation: readonly [string, ...string[]]
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
/** General SQL function call captured by the internal expression AST. */
|
|
38
47
|
export interface FunctionCallNode<
|
|
39
48
|
Name extends string = string,
|
|
@@ -82,6 +91,10 @@ export type BinaryKind =
|
|
|
82
91
|
| "gte"
|
|
83
92
|
| "like"
|
|
84
93
|
| "ilike"
|
|
94
|
+
| "regexMatch"
|
|
95
|
+
| "regexIMatch"
|
|
96
|
+
| "regexNotMatch"
|
|
97
|
+
| "regexNotIMatch"
|
|
85
98
|
| "isDistinctFrom"
|
|
86
99
|
| "isNotDistinctFrom"
|
|
87
100
|
| "contains"
|
|
@@ -132,7 +145,7 @@ export interface CaseNode<
|
|
|
132
145
|
|
|
133
146
|
/** `exists (<subquery>)` expression node. */
|
|
134
147
|
export interface ExistsNode<
|
|
135
|
-
PlanValue extends Query.
|
|
148
|
+
PlanValue extends Query.Plan.Any = Query.Plan.Any
|
|
136
149
|
> {
|
|
137
150
|
readonly kind: "exists"
|
|
138
151
|
readonly plan: PlanValue
|
|
@@ -140,7 +153,7 @@ export interface ExistsNode<
|
|
|
140
153
|
|
|
141
154
|
/** Scalar subquery expression node. */
|
|
142
155
|
export interface ScalarSubqueryNode<
|
|
143
|
-
PlanValue extends Query.
|
|
156
|
+
PlanValue extends Query.Plan.Any = Query.Plan.Any
|
|
144
157
|
> {
|
|
145
158
|
readonly kind: "scalarSubquery"
|
|
146
159
|
readonly plan: PlanValue
|
|
@@ -149,7 +162,7 @@ export interface ScalarSubqueryNode<
|
|
|
149
162
|
/** `value in (<subquery>)` expression node. */
|
|
150
163
|
export interface InSubqueryNode<
|
|
151
164
|
Left extends Expression.Any = Expression.Any,
|
|
152
|
-
PlanValue extends Query.
|
|
165
|
+
PlanValue extends Query.Plan.Any = Query.Plan.Any
|
|
153
166
|
> {
|
|
154
167
|
readonly kind: "inSubquery"
|
|
155
168
|
readonly left: Left
|
|
@@ -161,7 +174,7 @@ export interface QuantifiedComparisonNode<
|
|
|
161
174
|
Kind extends "comparisonAny" | "comparisonAll" = "comparisonAny" | "comparisonAll",
|
|
162
175
|
Operator extends "eq" | "neq" | "lt" | "lte" | "gt" | "gte" = "eq" | "neq" | "lt" | "lte" | "gt" | "gte",
|
|
163
176
|
Left extends Expression.Any = Expression.Any,
|
|
164
|
-
PlanValue extends Query.
|
|
177
|
+
PlanValue extends Query.Plan.Any = Query.Plan.Any
|
|
165
178
|
> {
|
|
166
179
|
readonly kind: Kind
|
|
167
180
|
readonly operator: Operator
|
|
@@ -335,6 +348,7 @@ export type Any =
|
|
|
335
348
|
| ColumnNode
|
|
336
349
|
| LiteralNode
|
|
337
350
|
| CastNode
|
|
351
|
+
| CollateNode
|
|
338
352
|
| FunctionCallNode
|
|
339
353
|
| ExcludedNode
|
|
340
354
|
| UnaryNode
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as Plan from "./row-set.js";
|
|
2
|
+
import type { PredicateFormula } from "./predicate/formula.js";
|
|
3
|
+
import type { SourceLike } from "./query.js";
|
|
4
|
+
export interface ImplicationScope {
|
|
5
|
+
readonly assumptions: PredicateFormula;
|
|
6
|
+
readonly nonNullKeys: ReadonlySet<string>;
|
|
7
|
+
readonly nullKeys: ReadonlySet<string>;
|
|
8
|
+
readonly requiredSourceNames: ReadonlySet<string>;
|
|
9
|
+
readonly absentSourceNames: ReadonlySet<string>;
|
|
10
|
+
readonly sourceModes: ReadonlyMap<string, Plan.SourceMode>;
|
|
11
|
+
}
|
|
12
|
+
export declare const presentFormulaOfSource: (source: Plan.Source<string, Plan.SourceMode, PredicateFormula, never>) => PredicateFormula;
|
|
13
|
+
export declare const presenceWitnessesOfSource: (source: Plan.Source<string, Plan.SourceMode, PredicateFormula, never>) => ReadonlySet<string>;
|
|
14
|
+
export declare const presenceWitnessesOfSourceLike: (source: SourceLike) => readonly string[];
|
|
15
|
+
export declare const resolveImplicationScope: (available: Readonly<Record<string, Plan.Source<string, Plan.SourceMode, PredicateFormula, never>>>, initialAssumptions: PredicateFormula) => ImplicationScope;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import * as Expression from "./scalar.js"
|
|
2
|
+
import * as ExpressionAst from "./expression-ast.js"
|
|
3
|
+
import * as Plan from "./row-set.js"
|
|
4
|
+
import * as Table from "./table.js"
|
|
5
|
+
import type { PredicateFormula } from "./predicate/formula.js"
|
|
6
|
+
import {
|
|
7
|
+
assumeFormulaTrue,
|
|
8
|
+
contradictsFormula,
|
|
9
|
+
guaranteedNonNullKeys,
|
|
10
|
+
guaranteedNullKeys,
|
|
11
|
+
guaranteedSourceNames,
|
|
12
|
+
trueFormula
|
|
13
|
+
} from "./predicate/runtime.js"
|
|
14
|
+
import type { SourceLike } from "./query.js"
|
|
15
|
+
|
|
16
|
+
export interface ImplicationScope {
|
|
17
|
+
readonly assumptions: PredicateFormula
|
|
18
|
+
readonly nonNullKeys: ReadonlySet<string>
|
|
19
|
+
readonly nullKeys: ReadonlySet<string>
|
|
20
|
+
readonly requiredSourceNames: ReadonlySet<string>
|
|
21
|
+
readonly absentSourceNames: ReadonlySet<string>
|
|
22
|
+
readonly sourceModes: ReadonlyMap<string, Plan.SourceMode>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type AstBackedExpression = Expression.Any & {
|
|
26
|
+
readonly [ExpressionAst.TypeId]: ExpressionAst.Any
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const presentFormulaOfSource = (source: Plan.Source): PredicateFormula =>
|
|
30
|
+
source._presentFormula ?? trueFormula()
|
|
31
|
+
|
|
32
|
+
export const presenceWitnessesOfSource = (source: Plan.Source): ReadonlySet<string> =>
|
|
33
|
+
new Set(source._presenceWitnesses ?? [])
|
|
34
|
+
|
|
35
|
+
const collectPresenceWitnesses = (
|
|
36
|
+
selection: unknown,
|
|
37
|
+
output: Set<string>
|
|
38
|
+
): void => {
|
|
39
|
+
if (typeof selection !== "object" || selection === null) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if (Expression.TypeId in selection && ExpressionAst.TypeId in selection) {
|
|
43
|
+
const expression = selection as unknown as AstBackedExpression
|
|
44
|
+
const ast = expression[ExpressionAst.TypeId]
|
|
45
|
+
if (ast.kind === "column" && expression[Expression.TypeId].nullability === "never") {
|
|
46
|
+
output.add(`${ast.tableName}.${ast.columnName}`)
|
|
47
|
+
}
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
for (const value of Object.values(selection as Record<string, unknown>)) {
|
|
51
|
+
collectPresenceWitnesses(value, output)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const presenceWitnessesOfSourceLike = (source: SourceLike): readonly string[] => {
|
|
56
|
+
const output = new Set<string>()
|
|
57
|
+
if (typeof source !== "object" || source === null) {
|
|
58
|
+
return []
|
|
59
|
+
}
|
|
60
|
+
if (Table.TypeId in source) {
|
|
61
|
+
collectPresenceWitnesses((source as Plan.Any)[Plan.TypeId].selection, output)
|
|
62
|
+
return [...output]
|
|
63
|
+
}
|
|
64
|
+
if ("columns" in source) {
|
|
65
|
+
collectPresenceWitnesses((source as { readonly columns: unknown }).columns, output)
|
|
66
|
+
}
|
|
67
|
+
return [...output]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const directAbsentSourceNames = (
|
|
71
|
+
available: Readonly<Record<string, Plan.Source>>,
|
|
72
|
+
assumptions: PredicateFormula
|
|
73
|
+
): Set<string> => {
|
|
74
|
+
const nullKeys = guaranteedNullKeys(assumptions)
|
|
75
|
+
const absent = new Set<string>()
|
|
76
|
+
for (const [name, source] of Object.entries(available)) {
|
|
77
|
+
if (source._presenceWitnesses?.some((key) => nullKeys.has(key))) {
|
|
78
|
+
absent.add(name)
|
|
79
|
+
continue
|
|
80
|
+
}
|
|
81
|
+
if (contradictsFormula(assumptions, presentFormulaOfSource(source))) {
|
|
82
|
+
absent.add(name)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return absent
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const propagateAbsentSourceNames = (
|
|
89
|
+
available: Readonly<Record<string, Plan.Source>>,
|
|
90
|
+
seed: ReadonlySet<string>
|
|
91
|
+
): Set<string> => {
|
|
92
|
+
const absent = new Set(seed)
|
|
93
|
+
let changed = true
|
|
94
|
+
while (changed) {
|
|
95
|
+
changed = false
|
|
96
|
+
for (const [name, source] of Object.entries(available)) {
|
|
97
|
+
if (absent.has(name)) {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
const required = guaranteedSourceNames(presentFormulaOfSource(source))
|
|
101
|
+
if (Array.from(required).some((dependency) => absent.has(dependency))) {
|
|
102
|
+
absent.add(name)
|
|
103
|
+
changed = true
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return absent
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const resolveImplicationScope = (
|
|
111
|
+
available: Readonly<Record<string, Plan.Source>>,
|
|
112
|
+
initialAssumptions: PredicateFormula
|
|
113
|
+
): ImplicationScope => {
|
|
114
|
+
let assumptions = initialAssumptions
|
|
115
|
+
const required = new Set<string>(
|
|
116
|
+
Object.entries(available)
|
|
117
|
+
.filter(([, source]) => source.mode === "required")
|
|
118
|
+
.map(([name]) => name)
|
|
119
|
+
)
|
|
120
|
+
const appliedRequired = new Set<string>()
|
|
121
|
+
let absent = new Set<string>()
|
|
122
|
+
|
|
123
|
+
let changed = true
|
|
124
|
+
while (changed) {
|
|
125
|
+
changed = false
|
|
126
|
+
|
|
127
|
+
for (const name of guaranteedSourceNames(assumptions)) {
|
|
128
|
+
if (!required.has(name)) {
|
|
129
|
+
required.add(name)
|
|
130
|
+
changed = true
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for (const name of required) {
|
|
135
|
+
if (absent.has(name) || appliedRequired.has(name)) {
|
|
136
|
+
continue
|
|
137
|
+
}
|
|
138
|
+
const source = available[name]
|
|
139
|
+
if (source === undefined) {
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
assumptions = assumeFormulaTrue(assumptions, presentFormulaOfSource(source))
|
|
143
|
+
appliedRequired.add(name)
|
|
144
|
+
changed = true
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const nextAbsent = propagateAbsentSourceNames(available, directAbsentSourceNames(available, assumptions))
|
|
148
|
+
if (nextAbsent.size !== absent.size || Array.from(nextAbsent).some((name) => !absent.has(name))) {
|
|
149
|
+
absent = nextAbsent
|
|
150
|
+
changed = true
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (const name of absent) {
|
|
155
|
+
required.delete(name)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const sourceModes = new Map<string, Plan.SourceMode>()
|
|
159
|
+
for (const [name, source] of Object.entries(available)) {
|
|
160
|
+
sourceModes.set(name, required.has(name) ? "required" : source.mode)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
assumptions,
|
|
165
|
+
nonNullKeys: guaranteedNonNullKeys(assumptions),
|
|
166
|
+
nullKeys: guaranteedNullKeys(assumptions),
|
|
167
|
+
requiredSourceNames: required,
|
|
168
|
+
absentSourceNames: absent,
|
|
169
|
+
sourceModes
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type * as Expression from "../scalar.js";
|
|
2
|
+
import type * as JsonPath from "./path.js";
|
|
3
|
+
export type JsonKind = "jsonGet" | "jsonPath" | "jsonAccess" | "jsonTraverse" | "jsonGetText" | "jsonPathText" | "jsonAccessText" | "jsonTraverseText" | "jsonHasKey" | "jsonKeyExists" | "jsonHasAnyKeys" | "jsonHasAllKeys" | "jsonConcat" | "jsonMerge" | "jsonDelete" | "jsonDeletePath" | "jsonRemove" | "jsonSet" | "jsonInsert" | "jsonPathExists" | "jsonPathMatch" | "jsonBuildObject" | "jsonBuildArray" | "jsonToJson" | "jsonToJsonb" | "jsonTypeOf" | "jsonLength" | "jsonKeys" | "jsonStripNulls";
|
|
4
|
+
/**
|
|
5
|
+
* Broad JSON AST node accepted by the renderer.
|
|
6
|
+
*
|
|
7
|
+
* The JSON subsystem is intentionally shaped as a small grammar rather than a
|
|
8
|
+
* collection of bespoke node interfaces. The renderer uses the `kind` plus the
|
|
9
|
+
* common field names below to lower the nodes into dialect SQL.
|
|
10
|
+
*/
|
|
11
|
+
export interface JsonNode<Kind extends JsonKind = JsonKind> {
|
|
12
|
+
readonly kind: Kind;
|
|
13
|
+
readonly value?: Expression.Any;
|
|
14
|
+
readonly base?: Expression.Any;
|
|
15
|
+
readonly left?: Expression.Any;
|
|
16
|
+
readonly right?: Expression.Any;
|
|
17
|
+
readonly path?: JsonPath.Path<any> | readonly any[];
|
|
18
|
+
readonly segments?: readonly any[];
|
|
19
|
+
readonly keys?: readonly string[];
|
|
20
|
+
readonly query?: string | Expression.Any;
|
|
21
|
+
readonly newValue?: Expression.Any;
|
|
22
|
+
readonly insert?: Expression.Any;
|
|
23
|
+
readonly createMissing?: boolean;
|
|
24
|
+
readonly insertAfter?: boolean;
|
|
25
|
+
readonly entries?: readonly {
|
|
26
|
+
readonly key: string;
|
|
27
|
+
readonly value: Expression.Any;
|
|
28
|
+
}[];
|
|
29
|
+
readonly values?: readonly Expression.Any[];
|
|
30
|
+
}
|
package/src/internal/json/ast.ts
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type JsonPathUsageError<Operation extends string, Root, Path, Reason extends string> = {
|
|
2
|
+
readonly __effect_qb_error__: "effect-qb: invalid json path usage";
|
|
3
|
+
readonly __effect_qb_json_operation__: Operation;
|
|
4
|
+
readonly __effect_qb_json_reason__: Reason;
|
|
5
|
+
readonly __effect_qb_json_root__: Root;
|
|
6
|
+
readonly __effect_qb_json_path__: Path;
|
|
7
|
+
readonly __effect_qb_hint__: "Use key(...) on objects, index(...) on arrays, and prefer exact key/index paths when you want precise output typing";
|
|
8
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type * as Expression from "../scalar.js";
|
|
2
|
+
import type { JsonPathUsageError } from "./errors.js";
|
|
3
|
+
import type { JsonBuildArray as JsonBuildArrayResult, JsonBuildObject as JsonBuildObjectResult, JsonConcatResult, JsonDeleteAtPath, JsonLiteralInput, JsonStripNullsResult as JsonStripNullsResultValue, JsonValueAtPath, JsonSetAtPath } from "./types.js";
|
|
4
|
+
import type { JsonKeysResult as JsonKeysResultValue, JsonLengthResult as JsonLengthResultValue, JsonTextResult as JsonTextResultValue, JsonTypeName as JsonTypeNameValue } from "./types.js";
|
|
5
|
+
export declare const SegmentTypeId: unique symbol;
|
|
6
|
+
export type SegmentTypeId = typeof SegmentTypeId;
|
|
7
|
+
export declare const TypeId: unique symbol;
|
|
8
|
+
export type TypeId = typeof TypeId;
|
|
9
|
+
type SegmentState<Kind extends string> = {
|
|
10
|
+
readonly kind: Kind;
|
|
11
|
+
};
|
|
12
|
+
export interface KeySegment<Key extends string = string> {
|
|
13
|
+
readonly [SegmentTypeId]: SegmentState<"key">;
|
|
14
|
+
readonly kind: "key";
|
|
15
|
+
readonly key: Key;
|
|
16
|
+
}
|
|
17
|
+
export interface IndexSegment<Index extends number = number> {
|
|
18
|
+
readonly [SegmentTypeId]: SegmentState<"index">;
|
|
19
|
+
readonly kind: "index";
|
|
20
|
+
readonly index: Index;
|
|
21
|
+
}
|
|
22
|
+
export interface WildcardSegment {
|
|
23
|
+
readonly [SegmentTypeId]: SegmentState<"wildcard">;
|
|
24
|
+
readonly kind: "wildcard";
|
|
25
|
+
}
|
|
26
|
+
export interface SliceSegment<Start extends number | undefined = number | undefined, End extends number | undefined = number | undefined> {
|
|
27
|
+
readonly [SegmentTypeId]: SegmentState<"slice">;
|
|
28
|
+
readonly kind: "slice";
|
|
29
|
+
readonly start: Start;
|
|
30
|
+
readonly end: End;
|
|
31
|
+
}
|
|
32
|
+
export interface DescendSegment {
|
|
33
|
+
readonly [SegmentTypeId]: SegmentState<"descend">;
|
|
34
|
+
readonly kind: "descend";
|
|
35
|
+
}
|
|
36
|
+
export type CanonicalSegment = KeySegment | IndexSegment | WildcardSegment | SliceSegment | DescendSegment;
|
|
37
|
+
export type AnySegment = any;
|
|
38
|
+
export type ExactSegment = KeySegment | IndexSegment;
|
|
39
|
+
type PathState<Segments extends readonly CanonicalSegment[]> = {
|
|
40
|
+
readonly segments: Segments;
|
|
41
|
+
};
|
|
42
|
+
export interface Path<Segments extends readonly CanonicalSegment[] = readonly CanonicalSegment[]> {
|
|
43
|
+
readonly [TypeId]: PathState<Segments>;
|
|
44
|
+
readonly segments: Segments;
|
|
45
|
+
}
|
|
46
|
+
export type JsonPath<Segments extends readonly CanonicalSegment[] = readonly CanonicalSegment[]> = Path<Segments>;
|
|
47
|
+
export type JsonPathSegments = readonly CanonicalSegment[];
|
|
48
|
+
export type JsonPrimitive = JsonLiteralInput;
|
|
49
|
+
export type JsonLiteral = JsonLiteralInput;
|
|
50
|
+
export type JsonInput = Expression.Any | JsonLiteral;
|
|
51
|
+
export declare const key: <Key extends string>(value: Key) => KeySegment<Key>;
|
|
52
|
+
export declare const index: <Index extends number>(value: Index) => IndexSegment<Index>;
|
|
53
|
+
export declare const wildcard: () => WildcardSegment;
|
|
54
|
+
export declare const slice: <Start extends number | undefined = undefined, End extends number | undefined = undefined>(start?: Start | undefined, end?: End | undefined) => SliceSegment<Start, End>;
|
|
55
|
+
export declare const descend: () => DescendSegment;
|
|
56
|
+
export declare const path: <Segments extends readonly CanonicalSegment[]>(...segments: Segments) => Path<Segments>;
|
|
57
|
+
export declare const makeJsonPath: <Segments extends readonly CanonicalSegment[]>(...segments: Segments) => Path<Segments>;
|
|
58
|
+
export type SegmentsOf<Value extends Path<any>> = Value[typeof TypeId]["segments"];
|
|
59
|
+
export type IsExactSegment<Segment extends CanonicalSegment> = Segment extends ExactSegment ? true : false;
|
|
60
|
+
export type IsExactPath<PathValue extends Path<any>> = SegmentsOf<PathValue> extends readonly [infer Head extends CanonicalSegment, ...infer Tail extends readonly CanonicalSegment[]] ? IsExactSegment<Head> extends true ? Tail extends readonly [] ? true : IsExactPath<Path<Tail>> : false : true;
|
|
61
|
+
export type JsonPathValue<Root, PathValue extends Path<any>, Operation extends string = "json.get"> = JsonValueAtPath<Root, PathValue, Operation>;
|
|
62
|
+
export type JsonPathOutput<Root, PathValue extends Path<any>, Operation extends string = "json.get"> = JsonValueAtPath<Root, PathValue, Operation>;
|
|
63
|
+
export type JsonPathCompatible<Root, PathValue extends Path<any>, Operation extends string = "json.get"> = JsonValueAtPath<Root, PathValue, Operation> extends JsonPathUsageError<any, any, any, any> ? JsonValueAtPath<Root, PathValue, Operation> : PathValue;
|
|
64
|
+
export type JsonPathUpdate<Root, PathValue extends Path<any>, Next, Operation extends string = "json.set"> = JsonSetAtPath<Root, PathValue, Next, Operation>;
|
|
65
|
+
export type JsonPathDelete<Root, PathValue extends Path<any>, Operation extends string = "json.delete"> = JsonDeleteAtPath<Root, PathValue, Operation>;
|
|
66
|
+
export type JsonConcat<Left, Right> = JsonConcatResult<Left, Right>;
|
|
67
|
+
export type JsonBuildObject<Shape extends Record<string, JsonInput>> = JsonBuildObjectResult<Shape>;
|
|
68
|
+
export type JsonBuildArray<Values extends readonly JsonInput[]> = JsonBuildArrayResult<Values>;
|
|
69
|
+
export type JsonTextResult<Value> = JsonTextResultValue<Value>;
|
|
70
|
+
export type JsonTypeName<Value> = JsonTypeNameValue<Value>;
|
|
71
|
+
export type JsonLengthResult<Value> = JsonLengthResultValue<Value>;
|
|
72
|
+
export type JsonKeysResult<Value> = JsonKeysResultValue<Value>;
|
|
73
|
+
export type JsonStripNullsResult<Value> = JsonStripNullsResultValue<Value>;
|
|
74
|
+
export type JsonValueOfInput<Input> = Input extends Expression.Any ? Expression.RuntimeOf<Input> : Input extends JsonLiteral ? Input : never;
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type * as JsonPath from "./path.js";
|
|
2
|
+
import type { JsonPathUsageError } from "./errors.js";
|
|
3
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
4
|
+
export type JsonValue = JsonPrimitive | readonly JsonValue[] | {
|
|
5
|
+
readonly [key: string]: JsonValue;
|
|
6
|
+
};
|
|
7
|
+
type OptionalKeyOf<ObjectType extends object, Key extends PropertyKey> = Key extends keyof ObjectType ? {} extends Pick<ObjectType, Key> ? true : false : true;
|
|
8
|
+
type NormalizeJsonTuple<Values extends readonly unknown[]> = Values extends readonly [] ? readonly [] : Values extends readonly [infer Head, ...infer Tail] ? readonly [NormalizeJsonLiteral<Head>, ...NormalizeJsonTuple<Tail>] : readonly NormalizeJsonLiteral<Values[number]>[];
|
|
9
|
+
type NormalizeJsonObject<ObjectType extends object> = {
|
|
10
|
+
readonly [Key in keyof ObjectType as Key extends string ? Key : never]: NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>>;
|
|
11
|
+
};
|
|
12
|
+
export type NormalizeJsonLiteral<Value> = [
|
|
13
|
+
Value
|
|
14
|
+
] extends [never] ? never : Value extends JsonPrimitive ? Value : Value extends undefined | bigint | symbol | Date | ((...args: readonly any[]) => any) ? never : Value extends readonly unknown[] ? NormalizeJsonTuple<Value> : Value extends object ? NormalizeJsonObject<Value> : never;
|
|
15
|
+
export type JsonLiteralInput = JsonPrimitive | readonly JsonLiteralInput[] | {
|
|
16
|
+
readonly [key: string]: JsonLiteralInput;
|
|
17
|
+
};
|
|
18
|
+
type StripNull<Value> = Exclude<Value, null>;
|
|
19
|
+
type KeyStep<Root, Key extends string, Operation extends string> = Root extends readonly unknown[] ? JsonPathUsageError<Operation, Root, JsonPath.KeySegment<Key>, "key segments cannot be applied to arrays"> : Root extends object ? Key extends keyof Root ? NormalizeJsonLiteral<Exclude<Root[Key], undefined>> | (OptionalKeyOf<Root, Key> extends true ? null : never) : Root extends Record<string, infer Value> ? NormalizeJsonLiteral<Value> | null : null : JsonPathUsageError<Operation, Root, JsonPath.KeySegment<Key>, "key segments require an object-like json value">;
|
|
20
|
+
type TupleIndex<Values extends readonly unknown[], Index extends number, Count extends readonly unknown[] = []> = Values extends readonly [infer Head, ...infer Tail] ? Count["length"] extends Index ? Head : TupleIndex<Tail, Index, [...Count, unknown]> : never;
|
|
21
|
+
type DropTupleIndex<Values extends readonly unknown[], Index extends number, Count extends readonly unknown[] = []> = Values extends readonly [infer Head, ...infer Tail] ? Count["length"] extends Index ? readonly [...Tail] : readonly [Head, ...DropTupleIndex<Tail, Index, [...Count, unknown]>] : readonly [];
|
|
22
|
+
type SetTupleIndex<Values extends readonly unknown[], Index extends number, Next, Count extends readonly unknown[] = []> = Values extends readonly [infer Head, ...infer Tail] ? Count["length"] extends Index ? readonly [Next, ...Tail] : readonly [Head, ...SetTupleIndex<Tail, Index, Next, [...Count, unknown]>] : readonly NormalizeJsonLiteral<Next>[];
|
|
23
|
+
type InsertTupleIndex<Values extends readonly unknown[], Index extends number, Next, After extends boolean, Count extends readonly unknown[] = []> = Values extends readonly [infer Head, ...infer Tail] ? Count["length"] extends Index ? After extends true ? readonly [Head, NormalizeJsonLiteral<Next>, ...Tail] : readonly [NormalizeJsonLiteral<Next>, Head, ...Tail] : readonly [Head, ...InsertTupleIndex<Tail, Index, Next, After, [...Count, unknown]>] : readonly NormalizeJsonLiteral<Next>[];
|
|
24
|
+
type IndexStep<Root, Index extends number, Operation extends string> = Root extends readonly unknown[] ? number extends Root["length"] ? NormalizeJsonLiteral<Root[number]> | null : NormalizeJsonLiteral<TupleIndex<Root, Index>> | (TupleIndex<Root, Index> extends never ? null : never) : JsonPathUsageError<Operation, Root, JsonPath.IndexSegment<Index>, "index segments require an array-like json value">;
|
|
25
|
+
type NonExactStep<Root, Segment extends JsonPath.CanonicalSegment> = Segment extends JsonPath.WildcardSegment ? NormalizeJsonLiteral<Root> | null : Segment extends JsonPath.SliceSegment<any, any> ? NormalizeJsonLiteral<Root> | null : Segment extends JsonPath.DescendSegment ? NormalizeJsonLiteral<Root> | null : never;
|
|
26
|
+
type StepValue<Root, Segment extends JsonPath.CanonicalSegment, Operation extends string> = Segment extends JsonPath.KeySegment<infer Key extends string> ? KeyStep<Root, Key, Operation> : Segment extends JsonPath.IndexSegment<infer Index extends number> ? IndexStep<Root, Index, Operation> : NonExactStep<Root, Segment>;
|
|
27
|
+
type StepSet<Root, Segment extends JsonPath.CanonicalSegment, Next, Operation extends string> = Segment extends JsonPath.KeySegment<infer Key extends string> ? Root extends readonly unknown[] ? JsonPathUsageError<Operation, Root, Segment, "key segments cannot update arrays"> : Root extends object ? Omit<Root, Key> & {
|
|
28
|
+
readonly [K in Key]: NormalizeJsonLiteral<Next>;
|
|
29
|
+
} : JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value"> : Segment extends JsonPath.IndexSegment<infer Index extends number> ? Root extends readonly unknown[] ? number extends Root["length"] ? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[] : SetTupleIndex<Root, Index, Next> : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value"> : NormalizeJsonLiteral<Root>;
|
|
30
|
+
type StepDelete<Root, Segment extends JsonPath.CanonicalSegment, Operation extends string> = Segment extends JsonPath.KeySegment<infer Key extends string> ? Root extends readonly unknown[] ? JsonPathUsageError<Operation, Root, Segment, "key segments cannot delete from arrays"> : Root extends object ? Omit<Root, Key> : JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value"> : Segment extends JsonPath.IndexSegment<infer Index extends number> ? Root extends readonly unknown[] ? number extends Root["length"] ? Root : DropTupleIndex<Root, Index> : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value"> : NormalizeJsonLiteral<Root>;
|
|
31
|
+
type StepInsert<Root, Segment extends JsonPath.CanonicalSegment, Next, After extends boolean, Operation extends string> = Segment extends JsonPath.IndexSegment<infer Index extends number> ? Root extends readonly unknown[] ? number extends Root["length"] ? readonly (NormalizeJsonLiteral<Root[number]> | NormalizeJsonLiteral<Next>)[] : InsertTupleIndex<Root, Index, Next, After> : JsonPathUsageError<Operation, Root, Segment, "index segments require an array-like json value"> : Segment extends JsonPath.KeySegment<infer Key extends string> ? Root extends readonly unknown[] ? JsonPathUsageError<Operation, Root, Segment, "key segments cannot insert into arrays"> : Root extends object ? Key extends keyof Root ? Root : Root & {
|
|
32
|
+
readonly [K in Key]: NormalizeJsonLiteral<Next>;
|
|
33
|
+
} : JsonPathUsageError<Operation, Root, Segment, "key segments require an object-like json value"> : NormalizeJsonLiteral<Root>;
|
|
34
|
+
type RecurseValue<Current, Segments extends readonly JsonPath.CanonicalSegment[], Operation extends string> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]] ? StepValue<Current, Head, Operation> extends infer Next ? Next extends JsonPathUsageError<any, any, any, any> ? Next : Tail extends readonly [] ? Next : null extends Next ? RecurseValue<StripNull<Next>, Tail, Operation> | null : RecurseValue<Next, Tail, Operation> : never : NormalizeJsonLiteral<Current>;
|
|
35
|
+
type RecurseSet<Current, Segments extends readonly JsonPath.CanonicalSegment[], Next, Operation extends string> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]] ? Tail extends readonly [] ? StepSet<Current, Head, Next, Operation> : StepValue<Current, Head, Operation> extends infer Child ? Child extends JsonPathUsageError<any, any, any, any> ? Child : StepSet<Current, Head, RecurseSet<StripNull<Child>, Tail, Next, Operation>, Operation> : never : NormalizeJsonLiteral<Next>;
|
|
36
|
+
type RecurseDelete<Current, Segments extends readonly JsonPath.CanonicalSegment[], Operation extends string> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]] ? Tail extends readonly [] ? StepDelete<Current, Head, Operation> : StepValue<Current, Head, Operation> extends infer Child ? Child extends JsonPathUsageError<any, any, any, any> ? Child : StepSet<Current, Head, RecurseDelete<StripNull<Child>, Tail, Operation>, Operation> : never : NormalizeJsonLiteral<Current>;
|
|
37
|
+
type RecurseInsert<Current, Segments extends readonly JsonPath.CanonicalSegment[], Next, After extends boolean, Operation extends string> = Segments extends readonly [infer Head extends JsonPath.CanonicalSegment, ...infer Tail extends readonly JsonPath.CanonicalSegment[]] ? Tail extends readonly [] ? StepInsert<Current, Head, Next, After, Operation> : StepValue<Current, Head, Operation> extends infer Child ? Child extends JsonPathUsageError<any, any, any, any> ? Child : StepSet<Current, Head, RecurseInsert<StripNull<Child>, Tail, Next, After, Operation>, Operation> : never : NormalizeJsonLiteral<Current>;
|
|
38
|
+
export type JsonValueAtPath<Root, PathValue extends JsonPath.Path<any>, Operation extends string = "json.get"> = RecurseValue<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Operation>;
|
|
39
|
+
export type JsonSetAtPath<Root, PathValue extends JsonPath.Path<any>, Next, Operation extends string = "json.set"> = RecurseSet<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Next, Operation>;
|
|
40
|
+
export type JsonInsertAtPath<Root, PathValue extends JsonPath.Path<any>, Next, After extends boolean = false, Operation extends string = "json.insert"> = RecurseInsert<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Next, After, Operation>;
|
|
41
|
+
export type JsonDeleteAtPath<Root, PathValue extends JsonPath.Path<any>, Operation extends string = "json.delete"> = RecurseDelete<NormalizeJsonLiteral<Root>, JsonPath.SegmentsOf<PathValue>, Operation>;
|
|
42
|
+
type ArrayElement<Value> = Value extends readonly (infer Element)[] ? Element : never;
|
|
43
|
+
type MergeJsonObjects<Left extends object, Right extends object> = Omit<Left, keyof Right> & Right;
|
|
44
|
+
type StripNullsTuple<Values extends readonly unknown[]> = Values extends readonly [] ? readonly [] : Values extends readonly [infer Head, ...infer Tail] ? readonly [JsonStripNullsResult<Head>, ...StripNullsTuple<Tail>] : readonly JsonStripNullsResult<Values[number]>[];
|
|
45
|
+
type StripNullsObject<ObjectType extends object> = ({
|
|
46
|
+
readonly [Key in keyof ObjectType as Key extends string ? null extends NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>> ? never : Key : never]-?: JsonStripNullsResult<Exclude<ObjectType[Key], null>>;
|
|
47
|
+
} & {
|
|
48
|
+
readonly [Key in keyof ObjectType as Key extends string ? null extends NormalizeJsonLiteral<Exclude<ObjectType[Key], undefined>> ? Key : never : never]?: JsonStripNullsResult<Exclude<ObjectType[Key], null>>;
|
|
49
|
+
});
|
|
50
|
+
export type JsonStripNullsResult<Value> = Value extends null ? null : Value extends readonly unknown[] ? StripNullsTuple<Value> : Value extends object ? StripNullsObject<Value> : Value;
|
|
51
|
+
export type JsonConcatResult<Left, Right> = NormalizeJsonLiteral<Left> extends infer NormalizedLeft ? NormalizeJsonLiteral<Right> extends infer NormalizedRight ? NormalizedLeft extends readonly unknown[] ? NormalizedRight extends readonly unknown[] ? number extends NormalizedLeft["length"] | NormalizedRight["length"] ? readonly (ArrayElement<NormalizedLeft> | ArrayElement<NormalizedRight>)[] : readonly [...NormalizedLeft, ...NormalizedRight] : unknown : NormalizedLeft extends object ? NormalizedRight extends object ? MergeJsonObjects<NormalizedLeft, NormalizedRight> : unknown : unknown : never : never;
|
|
52
|
+
export type JsonBuildObject<Shape extends Record<string, unknown>> = {
|
|
53
|
+
readonly [K in keyof Shape]: NormalizeJsonLiteral<Shape[K]>;
|
|
54
|
+
};
|
|
55
|
+
export type JsonBuildArray<Values extends readonly unknown[]> = {
|
|
56
|
+
readonly [K in keyof Values]: NormalizeJsonLiteral<Values[K]>;
|
|
57
|
+
} & readonly unknown[];
|
|
58
|
+
export type JsonTextResult<Value> = Value extends JsonPrimitive ? `${Value}` : string;
|
|
59
|
+
export type JsonTypeName<Value> = NormalizeJsonLiteral<Value> extends null ? "null" : NormalizeJsonLiteral<Value> extends string ? "string" : NormalizeJsonLiteral<Value> extends number ? "number" : NormalizeJsonLiteral<Value> extends boolean ? "boolean" : NormalizeJsonLiteral<Value> extends readonly unknown[] ? "array" : NormalizeJsonLiteral<Value> extends object ? "object" : "unknown";
|
|
60
|
+
export type JsonLengthResult<Value> = NormalizeJsonLiteral<Value> extends readonly unknown[] ? number : NormalizeJsonLiteral<Value> extends object ? number : null;
|
|
61
|
+
export type JsonKeysResult<Value> = NormalizeJsonLiteral<Value> extends object ? NormalizeJsonLiteral<Value> extends readonly unknown[] ? readonly [] : readonly Extract<keyof NormalizeJsonLiteral<Value>, string>[] : null;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AnalyzeFormula } from "./context.js";
|
|
2
|
+
import type { FormulaOfPredicate } from "./normalize.js";
|
|
3
|
+
import type { And, Not, PredicateFormula, TrueFormula } from "./formula.js";
|
|
4
|
+
type ContextOf<Formula extends PredicateFormula> = AnalyzeFormula<Formula>;
|
|
5
|
+
export type GuaranteedNonNullKeys<Assumptions extends PredicateFormula> = ContextOf<Assumptions>["nonNullKeys"];
|
|
6
|
+
export type GuaranteedNullKeys<Assumptions extends PredicateFormula> = ContextOf<Assumptions>["nullKeys"];
|
|
7
|
+
export type GuaranteedSourceNames<Assumptions extends PredicateFormula> = ContextOf<Assumptions>["sourceNames"];
|
|
8
|
+
export type GuaranteedEqLiteral<Assumptions extends PredicateFormula, Key extends string> = Key extends keyof ContextOf<Assumptions>["eqLiterals"] ? ContextOf<Assumptions>["eqLiterals"][Key] : never;
|
|
9
|
+
type IsContradiction<Formula extends PredicateFormula> = ContextOf<Formula>["contradiction"] extends true ? true : false;
|
|
10
|
+
type ContradictoryAssumption<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = IsContradiction<And<Assumptions, Formula>>;
|
|
11
|
+
type ContradictionFromNegation<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = IsContradiction<And<Assumptions, Not<Formula>>>;
|
|
12
|
+
export type ContradictsFormula<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = ContradictoryAssumption<Assumptions, Formula>;
|
|
13
|
+
export type ImpliesFormula<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = ContradictionFromNegation<Assumptions, Formula>;
|
|
14
|
+
export type AssumeFormulaTrue<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = Assumptions extends TrueFormula ? Formula : And<Assumptions, Formula>;
|
|
15
|
+
export type AssumeFormulaFalse<Assumptions extends PredicateFormula, Formula extends PredicateFormula> = Assumptions extends TrueFormula ? Not<Formula> : And<Assumptions, Not<Formula>>;
|
|
16
|
+
export type AssumeTrue<Assumptions extends PredicateFormula, Predicate> = AssumeFormulaTrue<Assumptions, FormulaOfPredicate<Predicate>>;
|
|
17
|
+
export type AssumeFalse<Assumptions extends PredicateFormula, Predicate> = AssumeFormulaFalse<Assumptions, FormulaOfPredicate<Predicate>>;
|
|
18
|
+
export type Contradicts<Assumptions extends PredicateFormula, Predicate> = ContradictoryAssumption<Assumptions, FormulaOfPredicate<Predicate>>;
|
|
19
|
+
export type Implies<Assumptions extends PredicateFormula, Predicate> = ContradictionFromNegation<Assumptions, FormulaOfPredicate<Predicate>>;
|
|
20
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AnalyzeFormula } from "./
|
|
2
|
-
import type { FormulaOfPredicate } from "./
|
|
3
|
-
import type { And, Not, PredicateFormula, TrueFormula } from "./
|
|
1
|
+
import type { AnalyzeFormula } from "./context.js"
|
|
2
|
+
import type { FormulaOfPredicate } from "./normalize.js"
|
|
3
|
+
import type { And, Not, PredicateFormula, TrueFormula } from "./formula.js"
|
|
4
4
|
|
|
5
5
|
type ContextOf<Formula extends PredicateFormula> = AnalyzeFormula<Formula>
|
|
6
6
|
|
|
@@ -36,6 +36,16 @@ type ContradictionFromNegation<
|
|
|
36
36
|
Formula extends PredicateFormula
|
|
37
37
|
> = IsContradiction<And<Assumptions, Not<Formula>>>
|
|
38
38
|
|
|
39
|
+
export type ContradictsFormula<
|
|
40
|
+
Assumptions extends PredicateFormula,
|
|
41
|
+
Formula extends PredicateFormula
|
|
42
|
+
> = ContradictoryAssumption<Assumptions, Formula>
|
|
43
|
+
|
|
44
|
+
export type ImpliesFormula<
|
|
45
|
+
Assumptions extends PredicateFormula,
|
|
46
|
+
Formula extends PredicateFormula
|
|
47
|
+
> = ContradictionFromNegation<Assumptions, Formula>
|
|
48
|
+
|
|
39
49
|
export type AssumeFormulaTrue<
|
|
40
50
|
Assumptions extends PredicateFormula,
|
|
41
51
|
Formula extends PredicateFormula
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface NullAtom<Key extends string> {
|
|
2
|
+
readonly kind: "is-null";
|
|
3
|
+
readonly key: Key;
|
|
4
|
+
}
|
|
5
|
+
export interface NonNullAtom<Key extends string> {
|
|
6
|
+
readonly kind: "is-not-null";
|
|
7
|
+
readonly key: Key;
|
|
8
|
+
}
|
|
9
|
+
export interface EqLiteralAtom<Key extends string, Value extends string> {
|
|
10
|
+
readonly kind: "eq-literal";
|
|
11
|
+
readonly key: Key;
|
|
12
|
+
readonly value: Value;
|
|
13
|
+
}
|
|
14
|
+
export interface NeqLiteralAtom<Key extends string, Value extends string> {
|
|
15
|
+
readonly kind: "neq-literal";
|
|
16
|
+
readonly key: Key;
|
|
17
|
+
readonly value: Value;
|
|
18
|
+
}
|
|
19
|
+
export interface EqColumnAtom<LeftKey extends string, RightKey extends string> {
|
|
20
|
+
readonly kind: "eq-column";
|
|
21
|
+
readonly left: LeftKey;
|
|
22
|
+
readonly right: RightKey;
|
|
23
|
+
}
|
|
24
|
+
export interface UnknownAtom<Tag extends string> {
|
|
25
|
+
readonly kind: "unknown";
|
|
26
|
+
readonly tag: Tag;
|
|
27
|
+
}
|
|
28
|
+
export type PredicateAtom = NullAtom<string> | NonNullAtom<string> | EqLiteralAtom<string, string> | NeqLiteralAtom<string, string> | EqColumnAtom<string, string> | UnknownAtom<string>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PredicateAtom } from "./
|
|
2
|
-
import type { AtomFormula, FalseFormula, PredicateFormula, TrueFormula } from "./
|
|
1
|
+
import type { PredicateAtom } from "./atom.js"
|
|
2
|
+
import type { AtomFormula, FalseFormula, PredicateFormula, TrueFormula } from "./formula.js"
|
|
3
3
|
|
|
4
4
|
export interface BranchLimitExceeded {
|
|
5
5
|
readonly kind: "branch-limit-exceeded"
|