@abedmurrar/objection 0.0.0-stage → 4.0.0-alpha.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/LICENSE +23 -0
- package/README.md +69 -2
- package/lib/.eslintrc.json +8 -0
- package/lib/initialize.js +14 -0
- package/lib/model/AjvValidator.js +325 -0
- package/lib/model/Model.js +942 -0
- package/lib/model/ModifierNotFoundError.js +12 -0
- package/lib/model/NotFoundError.js +23 -0
- package/lib/model/RelationDoesNotExistError.js +14 -0
- package/lib/model/ValidationError.js +54 -0
- package/lib/model/Validator.js +26 -0
- package/lib/model/getModel.js +9 -0
- package/lib/model/graph/ModelGraph.js +80 -0
- package/lib/model/graph/ModelGraphBuilder.js +241 -0
- package/lib/model/graph/ModelGraphEdge.js +52 -0
- package/lib/model/graph/ModelGraphNode.js +240 -0
- package/lib/model/inheritModel.js +28 -0
- package/lib/model/modelBindKnex.js +83 -0
- package/lib/model/modelClone.js +121 -0
- package/lib/model/modelColPropMap.js +34 -0
- package/lib/model/modelId.js +62 -0
- package/lib/model/modelJsonAttributes.js +92 -0
- package/lib/model/modelParseRelations.js +82 -0
- package/lib/model/modelQueryProps.js +147 -0
- package/lib/model/modelSet.js +136 -0
- package/lib/model/modelTableMetadata.js +83 -0
- package/lib/model/modelToJson.js +187 -0
- package/lib/model/modelUtils.js +47 -0
- package/lib/model/modelValidate.js +48 -0
- package/lib/model/modelValues.js +126 -0
- package/lib/model/modelVisitor.js +41 -0
- package/lib/objection.js +114 -0
- package/lib/queryBuilder/FunctionBuilder.js +339 -0
- package/lib/queryBuilder/InternalOptions.js +29 -0
- package/lib/queryBuilder/JoinBuilder.js +157 -0
- package/lib/queryBuilder/QueryBuilder.js +1398 -0
- package/lib/queryBuilder/QueryBuilderBase.js +884 -0
- package/lib/queryBuilder/QueryBuilderContext.js +27 -0
- package/lib/queryBuilder/QueryBuilderContextBase.js +35 -0
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +558 -0
- package/lib/queryBuilder/QueryBuilderUserContext.js +31 -0
- package/lib/queryBuilder/RawBuilder.js +93 -0
- package/lib/queryBuilder/ReferenceBuilder.js +284 -0
- package/lib/queryBuilder/RelationExpression.js +431 -0
- package/lib/queryBuilder/StaticHookArguments.js +134 -0
- package/lib/queryBuilder/ValueBuilder.js +127 -0
- package/lib/queryBuilder/expressions.js +151 -0
- package/lib/queryBuilder/functions/mysql.js +817 -0
- package/lib/queryBuilder/graph/GraphAction.js +69 -0
- package/lib/queryBuilder/graph/GraphData.js +14 -0
- package/lib/queryBuilder/graph/GraphFetcher.js +191 -0
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +184 -0
- package/lib/queryBuilder/graph/GraphOperation.js +27 -0
- package/lib/queryBuilder/graph/GraphOptions.js +207 -0
- package/lib/queryBuilder/graph/GraphUpsert.js +305 -0
- package/lib/queryBuilder/graph/delete/GraphDelete.js +20 -0
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +74 -0
- package/lib/queryBuilder/graph/insert/GraphInsert.js +145 -0
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +225 -0
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +92 -0
- package/lib/queryBuilder/graph/patch/GraphPatch.js +20 -0
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +258 -0
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +31 -0
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +126 -0
- package/lib/queryBuilder/join/JoinResultColumn.js +23 -0
- package/lib/queryBuilder/join/JoinResultParser.js +119 -0
- package/lib/queryBuilder/join/RelationJoiner.js +341 -0
- package/lib/queryBuilder/join/TableNode.js +163 -0
- package/lib/queryBuilder/join/TableTree.js +85 -0
- package/lib/queryBuilder/join/utils.js +25 -0
- package/lib/queryBuilder/operations/DelegateOperation.js +141 -0
- package/lib/queryBuilder/operations/DeleteOperation.js +51 -0
- package/lib/queryBuilder/operations/FindByIdOperation.js +37 -0
- package/lib/queryBuilder/operations/FindByIdsOperation.js +29 -0
- package/lib/queryBuilder/operations/FindOperation.js +164 -0
- package/lib/queryBuilder/operations/FirstOperation.js +27 -0
- package/lib/queryBuilder/operations/FromOperation.js +110 -0
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +49 -0
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +45 -0
- package/lib/queryBuilder/operations/InsertGraphOperation.js +108 -0
- package/lib/queryBuilder/operations/InsertOperation.js +206 -0
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +46 -0
- package/lib/queryBuilder/operations/InstanceFindOperation.js +21 -0
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +24 -0
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +59 -0
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +103 -0
- package/lib/queryBuilder/operations/KnexOperation.js +14 -0
- package/lib/queryBuilder/operations/MergeOperation.js +56 -0
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +192 -0
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +29 -0
- package/lib/queryBuilder/operations/OnBuildOperation.js +29 -0
- package/lib/queryBuilder/operations/OnErrorOperation.js +29 -0
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +297 -0
- package/lib/queryBuilder/operations/RangeOperation.js +47 -0
- package/lib/queryBuilder/operations/RelateOperation.js +27 -0
- package/lib/queryBuilder/operations/ReturningOperation.js +30 -0
- package/lib/queryBuilder/operations/RunAfterOperation.js +29 -0
- package/lib/queryBuilder/operations/RunBeforeOperation.js +29 -0
- package/lib/queryBuilder/operations/UnrelateOperation.js +23 -0
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +80 -0
- package/lib/queryBuilder/operations/UpdateOperation.js +155 -0
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +45 -0
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +66 -0
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +57 -0
- package/lib/queryBuilder/operations/WhereInOperation.js +48 -0
- package/lib/queryBuilder/operations/eager/EagerOperation.js +61 -0
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +51 -0
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +13 -0
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +285 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +36 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +53 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +31 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +31 -0
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +167 -0
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +164 -0
- package/lib/queryBuilder/operations/select/SelectOperation.js +66 -0
- package/lib/queryBuilder/operations/select/Selection.js +123 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +117 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +100 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +104 -0
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +886 -0
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +97 -0
- package/lib/queryBuilder/parsers/relationExpressionParser.js +1042 -0
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +141 -0
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +22 -0
- package/lib/queryBuilder/transformations/QueryTransformation.js +11 -0
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +71 -0
- package/lib/queryBuilder/transformations/index.js +15 -0
- package/lib/queryBuilder/whereScopes.js +227 -0
- package/lib/relations/Relation.js +401 -0
- package/lib/relations/RelationDeleteOperation.js +29 -0
- package/lib/relations/RelationFindOperation.js +149 -0
- package/lib/relations/RelationInsertOperation.js +33 -0
- package/lib/relations/RelationOwner.js +236 -0
- package/lib/relations/RelationProperty.js +247 -0
- package/lib/relations/RelationUpdateOperation.js +30 -0
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +23 -0
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +44 -0
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +50 -0
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +53 -0
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +61 -0
- package/lib/relations/hasMany/HasManyInsertOperation.js +61 -0
- package/lib/relations/hasMany/HasManyRelateOperation.js +64 -0
- package/lib/relations/hasMany/HasManyRelation.js +49 -0
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +33 -0
- package/lib/relations/hasOne/HasOneRelation.js +13 -0
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +13 -0
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +105 -0
- package/lib/relations/manyToMany/ManyToManyRelation.js +507 -0
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +36 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +10 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +26 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +12 -0
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +105 -0
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +52 -0
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +81 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +14 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +34 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +16 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +10 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +82 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +12 -0
- package/lib/transaction.js +96 -0
- package/lib/utils/assert.js +25 -0
- package/lib/utils/buildUtils.js +21 -0
- package/lib/utils/classUtils.js +13 -0
- package/lib/utils/clone.js +2329 -0
- package/lib/utils/createModifier.js +42 -0
- package/lib/utils/deprecate.js +15 -0
- package/lib/utils/identifierMapping.js +227 -0
- package/lib/utils/internalPropUtils.js +11 -0
- package/lib/utils/knexUtils.js +76 -0
- package/lib/utils/mixin.js +25 -0
- package/lib/utils/mysqlJsonPath.js +55 -0
- package/lib/utils/normalizeIds.js +144 -0
- package/lib/utils/objectUtils.js +416 -0
- package/lib/utils/parseFieldExpression.js +51 -0
- package/lib/utils/postgresJsonPath.js +110 -0
- package/lib/utils/promiseUtils/after.js +17 -0
- package/lib/utils/promiseUtils/afterReturn.js +17 -0
- package/lib/utils/promiseUtils/index.js +17 -0
- package/lib/utils/promiseUtils/isPromise.js +11 -0
- package/lib/utils/promiseUtils/map.js +110 -0
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +29 -0
- package/lib/utils/promiseUtils/try.js +22 -0
- package/lib/utils/resolveModel.js +107 -0
- package/lib/utils/tmpColumnUtils.js +16 -0
- package/package.json +86 -4
- package/typings/objection/index.d.ts +4104 -0
- package/typings/objection/relation-expression.d.ts +237 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// Parses relation expressions at compile time, like objection does at runtime
|
|
2
|
+
// (lib/queryBuilder/parsers/relationExpressionParser.pegjs):
|
|
3
|
+
//
|
|
4
|
+
// '[pets(onlyDogs).toys, mom as mother.^]'
|
|
5
|
+
// { pets: { $modify: onlyDogs, toys: true }, mother: { $relation: 'mom', $recursive: true } }
|
|
6
|
+
//
|
|
7
|
+
// Both give a `GraphNode` whose children are the relations to load. Checking the
|
|
8
|
+
// relation names against the models is done in index.d.ts.
|
|
9
|
+
|
|
10
|
+
export interface GraphNode {
|
|
11
|
+
// The name of the relation. The property name (the key of the node in
|
|
12
|
+
// `children`) can be different, when an alias is used.
|
|
13
|
+
rel: string;
|
|
14
|
+
// The modifiers: names, or the values of `$modify` in object notation.
|
|
15
|
+
mods: readonly unknown[];
|
|
16
|
+
children: Graph;
|
|
17
|
+
// `^`, `^N` or `$recursive`.
|
|
18
|
+
recursive: boolean;
|
|
19
|
+
// `*` or `$allRecursive`.
|
|
20
|
+
all: boolean;
|
|
21
|
+
// Object notation with a `boolean` value, which may or may not load the relation.
|
|
22
|
+
maybe: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type Graph = { [prop: string]: GraphNode };
|
|
26
|
+
|
|
27
|
+
export interface ParseError<Message extends string = string> {
|
|
28
|
+
'~parseError': Message;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The graph of an expression that isn't known at compile time.
|
|
32
|
+
export interface UnknownGraph {
|
|
33
|
+
'~unknownGraph': true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type ParseRelationExpression<E> = string extends E
|
|
37
|
+
? UnknownGraph
|
|
38
|
+
: E extends string
|
|
39
|
+
? ParseString<E>
|
|
40
|
+
: E extends object
|
|
41
|
+
? string extends keyof E
|
|
42
|
+
? UnknownGraph
|
|
43
|
+
: RootNode<ObjectChildren<E>, E extends { $allRecursive: true } ? true : false>
|
|
44
|
+
: UnknownGraph;
|
|
45
|
+
|
|
46
|
+
type RootNode<Children extends Graph, All extends boolean = false> = {
|
|
47
|
+
rel: '';
|
|
48
|
+
mods: [];
|
|
49
|
+
children: Children;
|
|
50
|
+
recursive: false;
|
|
51
|
+
all: All;
|
|
52
|
+
maybe: false;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Strings.
|
|
56
|
+
|
|
57
|
+
type Whitespace = ' ' | '\t' | '\r' | '\n';
|
|
58
|
+
type Punctuation = '[' | ']' | '(' | ')' | ',' | '.';
|
|
59
|
+
|
|
60
|
+
// Splits an expression into names and the characters `[ ] ( ) , .`. Whitespace
|
|
61
|
+
// only separates names.
|
|
62
|
+
type Tokenize<
|
|
63
|
+
S extends string,
|
|
64
|
+
Name extends string = '',
|
|
65
|
+
Tokens extends string[] = [],
|
|
66
|
+
> = S extends `${infer C}${infer Rest}`
|
|
67
|
+
? C extends Whitespace
|
|
68
|
+
? Tokenize<Rest, '', AddName<Tokens, Name>>
|
|
69
|
+
: C extends Punctuation
|
|
70
|
+
? Tokenize<Rest, '', [...AddName<Tokens, Name>, C]>
|
|
71
|
+
: Tokenize<Rest, `${Name}${C}`, Tokens>
|
|
72
|
+
: AddName<Tokens, Name>;
|
|
73
|
+
|
|
74
|
+
type AddName<Tokens extends string[], Name extends string> = Name extends ''
|
|
75
|
+
? Tokens
|
|
76
|
+
: [...Tokens, Name];
|
|
77
|
+
|
|
78
|
+
type ParseString<E extends string> =
|
|
79
|
+
Tokenize<E> extends infer Tokens extends string[]
|
|
80
|
+
? Tokens extends []
|
|
81
|
+
? ParseError<'Empty relation expression'>
|
|
82
|
+
: Tokens extends ['*']
|
|
83
|
+
? RootNode<{}, true>
|
|
84
|
+
: Tokens extends ['[', ...infer Rest extends string[]]
|
|
85
|
+
? ParseList<Rest, {}> extends infer List
|
|
86
|
+
? List extends [infer Children extends Graph, infer After extends string[]]
|
|
87
|
+
? ExpectEnd<After, RootNode<Children>>
|
|
88
|
+
: List
|
|
89
|
+
: never
|
|
90
|
+
: ParseExpression<Tokens> extends infer Expr
|
|
91
|
+
? Expr extends [
|
|
92
|
+
infer Prop extends string,
|
|
93
|
+
infer Node extends GraphNode,
|
|
94
|
+
infer After extends string[],
|
|
95
|
+
]
|
|
96
|
+
? ExpectEnd<After, RootNode<{ [P in Prop]: Node }>>
|
|
97
|
+
: Expr
|
|
98
|
+
: never
|
|
99
|
+
: never;
|
|
100
|
+
|
|
101
|
+
type ExpectEnd<Tokens extends string[], Result> = Tokens extends []
|
|
102
|
+
? Result
|
|
103
|
+
: ParseError<`Unexpected "${Tokens[0]}" in relation expression`>;
|
|
104
|
+
|
|
105
|
+
type IsName<T> = T extends Punctuation ? false : T extends string ? true : false;
|
|
106
|
+
|
|
107
|
+
// `name(modifiers) as alias` followed by `.expression` or `.[list]`. Gives
|
|
108
|
+
// `[prop, node, rest]` or a `ParseError`.
|
|
109
|
+
type ParseExpression<Tokens extends string[]> = Tokens extends [
|
|
110
|
+
infer Name extends string,
|
|
111
|
+
...infer Rest extends string[],
|
|
112
|
+
]
|
|
113
|
+
? IsName<Name> extends true
|
|
114
|
+
? ParseModifiers<Rest> extends infer Mods
|
|
115
|
+
? Mods extends [infer Names extends string[], infer AfterMods extends string[]]
|
|
116
|
+
? AfterMods extends ['as', infer Alias extends string, ...infer AfterAlias extends string[]]
|
|
117
|
+
? IsName<Alias> extends true
|
|
118
|
+
? ParseSub<Alias, Name, Names, AfterAlias>
|
|
119
|
+
: ParseSub<Name, Name, Names, AfterMods>
|
|
120
|
+
: ParseSub<Name, Name, Names, AfterMods>
|
|
121
|
+
: Mods
|
|
122
|
+
: never
|
|
123
|
+
: ParseError<`Expected a relation name, got "${Name}"`>
|
|
124
|
+
: ParseError<'Unexpected end of relation expression'>;
|
|
125
|
+
|
|
126
|
+
type ParseModifiers<Tokens extends string[]> = Tokens extends ['(', ...infer Rest extends string[]]
|
|
127
|
+
? CollectModifiers<Rest, []>
|
|
128
|
+
: [[], Tokens];
|
|
129
|
+
|
|
130
|
+
type CollectModifiers<Tokens extends string[], Names extends string[]> = Tokens extends [
|
|
131
|
+
infer T extends string,
|
|
132
|
+
...infer Rest extends string[],
|
|
133
|
+
]
|
|
134
|
+
? T extends ')'
|
|
135
|
+
? [Names, Rest]
|
|
136
|
+
: T extends ','
|
|
137
|
+
? CollectModifiers<Rest, Names>
|
|
138
|
+
: IsName<T> extends true
|
|
139
|
+
? CollectModifiers<Rest, [...Names, T]>
|
|
140
|
+
: ParseError<`Unexpected "${T}" in modifiers`>
|
|
141
|
+
: ParseError<'Missing ")" in relation expression'>;
|
|
142
|
+
|
|
143
|
+
type Node<
|
|
144
|
+
Rel extends string,
|
|
145
|
+
Mods extends readonly unknown[],
|
|
146
|
+
Children extends Graph,
|
|
147
|
+
Recursive extends boolean = false,
|
|
148
|
+
All extends boolean = false,
|
|
149
|
+
Maybe extends boolean = false,
|
|
150
|
+
> = {
|
|
151
|
+
rel: Rel;
|
|
152
|
+
mods: Mods;
|
|
153
|
+
children: Children;
|
|
154
|
+
recursive: Recursive;
|
|
155
|
+
all: All;
|
|
156
|
+
maybe: Maybe;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
type ParseSub<
|
|
160
|
+
Prop extends string,
|
|
161
|
+
Rel extends string,
|
|
162
|
+
Mods extends string[],
|
|
163
|
+
Tokens extends string[],
|
|
164
|
+
> = Tokens extends ['.', '[', ...infer Rest extends string[]]
|
|
165
|
+
? ParseList<Rest, {}> extends infer List
|
|
166
|
+
? List extends [infer Children extends Graph, infer After extends string[]]
|
|
167
|
+
? [Prop, Node<Rel, Mods, Children>, After]
|
|
168
|
+
: List
|
|
169
|
+
: never
|
|
170
|
+
: Tokens extends ['.', infer Sub extends string, ...infer Rest extends string[]]
|
|
171
|
+
? Sub extends '^' | `^${number}`
|
|
172
|
+
? [Prop, Node<Rel, Mods, {}, true>, Rest]
|
|
173
|
+
: Sub extends '*'
|
|
174
|
+
? [Prop, Node<Rel, Mods, {}, false, true>, Rest]
|
|
175
|
+
: ParseExpression<[Sub, ...Rest]> extends infer Expr
|
|
176
|
+
? Expr extends [
|
|
177
|
+
infer SubProp extends string,
|
|
178
|
+
infer SubNode extends GraphNode,
|
|
179
|
+
infer After extends string[],
|
|
180
|
+
]
|
|
181
|
+
? [Prop, Node<Rel, Mods, { [P in SubProp]: SubNode }>, After]
|
|
182
|
+
: Expr
|
|
183
|
+
: never
|
|
184
|
+
: Tokens extends ['.']
|
|
185
|
+
? ParseError<'Unexpected end of relation expression'>
|
|
186
|
+
: [Prop, Node<Rel, Mods, {}>, Tokens];
|
|
187
|
+
|
|
188
|
+
// The items of `[a, b]`. The commas are optional. Gives `[children, rest]` or a
|
|
189
|
+
// `ParseError`.
|
|
190
|
+
type ParseList<Tokens extends string[], Children extends Graph> = Tokens extends [
|
|
191
|
+
infer T extends string,
|
|
192
|
+
...infer Rest extends string[],
|
|
193
|
+
]
|
|
194
|
+
? T extends ']'
|
|
195
|
+
? [Children, Rest]
|
|
196
|
+
: T extends ','
|
|
197
|
+
? ParseList<Rest, Children>
|
|
198
|
+
: ParseExpression<Tokens> extends infer Expr
|
|
199
|
+
? Expr extends [
|
|
200
|
+
infer Prop extends string,
|
|
201
|
+
infer Node extends GraphNode,
|
|
202
|
+
infer After extends string[],
|
|
203
|
+
]
|
|
204
|
+
? ParseList<After, AddChild<Children, Prop, Node>>
|
|
205
|
+
: Expr
|
|
206
|
+
: never
|
|
207
|
+
: ParseError<'Missing "]" in relation expression'>;
|
|
208
|
+
|
|
209
|
+
// A later relation with the same name replaces the earlier one, like at runtime.
|
|
210
|
+
type AddChild<Children extends Graph, Prop extends string, Child extends GraphNode> = {
|
|
211
|
+
[P in keyof Children | Prop]: P extends Prop ? Child : Children[P & keyof Children];
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Object notation.
|
|
215
|
+
|
|
216
|
+
type ObjectChildren<E> = {
|
|
217
|
+
[K in keyof E as K extends `$${string}`
|
|
218
|
+
? never
|
|
219
|
+
: K extends string
|
|
220
|
+
? [E[K]] extends [false]
|
|
221
|
+
? never
|
|
222
|
+
: K
|
|
223
|
+
: never]: ObjectNode<K & string, E[K]>;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
type ObjectNode<K extends string, V> = [V] extends [true]
|
|
227
|
+
? Node<K, [], {}>
|
|
228
|
+
: [V] extends [boolean]
|
|
229
|
+
? Node<K, [], {}, false, false, true>
|
|
230
|
+
: {
|
|
231
|
+
rel: V extends { $relation: infer R extends string } ? R : K;
|
|
232
|
+
mods: V extends { $modify: infer F } ? (F extends readonly unknown[] ? F : [F]) : [];
|
|
233
|
+
children: ObjectChildren<V>;
|
|
234
|
+
recursive: V extends { $recursive: true | number } ? true : false;
|
|
235
|
+
all: V extends { $allRecursive: true } ? true : false;
|
|
236
|
+
maybe: false;
|
|
237
|
+
};
|