@johnhenry/graceholder 0.0.0-stage → 0.0.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 +21 -0
- package/README.md +492 -2
- package/STABILITY.md +24 -0
- package/package.json +126 -4
- package/src/adapters/apollo.d.ts +13 -0
- package/src/adapters/apollo.js +48 -0
- package/src/adapters/fetch.d.ts +15 -0
- package/src/adapters/fetch.js +150 -0
- package/src/adapters/shared.d.ts +14 -0
- package/src/adapters/shared.js +65 -0
- package/src/adapters/urql.d.ts +8 -0
- package/src/adapters/urql.js +53 -0
- package/src/anchor.js +13 -0
- package/src/args.js +41 -0
- package/src/bulk/csv.js +118 -0
- package/src/bulk/ndjson.js +10 -0
- package/src/bulk/plan.js +195 -0
- package/src/bulk/shape.js +67 -0
- package/src/bulk/source.js +24 -0
- package/src/bulk/sql.js +366 -0
- package/src/bulk/stream.js +55 -0
- package/src/cursor.js +25 -0
- package/src/dbg.d.ts +720 -0
- package/src/detmath.js +74 -0
- package/src/directives.js +113 -0
- package/src/dist.js +90 -0
- package/src/errors.js +17 -0
- package/src/execute.js +577 -0
- package/src/explain.js +473 -0
- package/src/fast-check.d.ts +31 -0
- package/src/fast-check.js +58 -0
- package/src/generate.js +84 -0
- package/src/generator-types.d.ts +90 -0
- package/src/generators.js +361 -0
- package/src/image.js +55 -0
- package/src/index.d.ts +507 -0
- package/src/index.js +62 -0
- package/src/infer.js +888 -0
- package/src/key.js +30 -0
- package/src/learn.js +397 -0
- package/src/naming.js +74 -0
- package/src/pack-registry.js +59 -0
- package/src/packs/PROVENANCE.md +26 -0
- package/src/packs/commerce.d.ts +4 -0
- package/src/packs/commerce.js +83 -0
- package/src/packs/finance.d.ts +4 -0
- package/src/packs/finance.js +180 -0
- package/src/packs/geo.d.ts +4 -0
- package/src/packs/geo.js +227 -0
- package/src/packs/health.d.ts +4 -0
- package/src/packs/health.js +76 -0
- package/src/packs/index.d.ts +7 -0
- package/src/packs/index.js +9 -0
- package/src/rng.js +89 -0
- package/src/rules.js +228 -0
- package/src/scenario.js +120 -0
- package/src/schema.js +148 -0
- package/src/spec.js +235 -0
- package/src/suggest.js +138 -0
- package/src/typed.d.ts +723 -0
- package/src/vocab/PROVENANCE.md +12 -0
- package/src/vocab/en.js +106 -0
- package/src/world.js +461 -0
- package/src/xxh64.js +87 -0
package/src/dbg.d.ts
ADDED
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
// Type-level reading of a query string (docs/design.md section 20): `ResultOf<"{ users { id name } }">`.
|
|
2
|
+
//
|
|
3
|
+
// This file mirrors the runtime rules of docs/design.md section 4 (L, N and T rules) for the
|
|
4
|
+
// default inference (no schema, no packs, `distributions: "uniform"`). It is a parser written in
|
|
5
|
+
// template literal types: a tokenizer, a stack machine for selection sets, and an evaluator.
|
|
6
|
+
// What cannot be inferred falls back to `unknown`; a query that cannot be parsed gives `Data`.
|
|
7
|
+
//
|
|
8
|
+
// The file is self-contained on purpose: `npm run typecheck` checks it with skipLibCheck off.
|
|
9
|
+
import type { GeneratorTypes } from "./generator-types.js";
|
|
10
|
+
|
|
11
|
+
// ---- tokenizer ----------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
export type WS = " " | "\n" | "\t" | "\r" | "," | "";
|
|
14
|
+
export type Lower = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
|
|
15
|
+
export type Upper = Uppercase<Lower>;
|
|
16
|
+
export type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
17
|
+
export type NameChar = Lower | Upper | Digit | "_" | "-" | "+" | ".";
|
|
18
|
+
export type Punct = "{" | "}" | "(" | ")" | "[" | "]" | ":" | "@" | "!" | "=" | "|" | "&";
|
|
19
|
+
|
|
20
|
+
export type SkipWS<S extends string> = S extends `${WS}${infer R}` ? SkipWS<R> : S;
|
|
21
|
+
export type SkipLine<S extends string> = S extends `${string}\n${infer R}` ? R : "";
|
|
22
|
+
export type ReadName<S extends string, N extends string = ""> = S extends `${infer C}${infer R}` ? (C extends NameChar ? ReadName<R, `${N}${C}`> : [N, S]) : [N, ""];
|
|
23
|
+
export type ReadStr<S extends string, Acc extends string = ""> = S extends `${infer B}"${infer R}`
|
|
24
|
+
? B extends `${string}\\`
|
|
25
|
+
? ReadStr<R, `${Acc}${B}"`>
|
|
26
|
+
: [`${Acc}${B}`, R]
|
|
27
|
+
: [Acc, ""];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The next token and the rest of the text; the token is null at the end. Punctuation is itself, names
|
|
31
|
+
* and numbers are text, strings are `"text`, variables are `$name`. The parser pulls tokens one at a
|
|
32
|
+
* time from the text (a long tuple of tokens costs quadratic memory in the compiler).
|
|
33
|
+
*/
|
|
34
|
+
export type Tok1<S extends string> = SkipWS<S> extends infer T extends string
|
|
35
|
+
? T extends ""
|
|
36
|
+
? [null, ""]
|
|
37
|
+
: T extends `#${infer C}`
|
|
38
|
+
? Tok1<SkipLine<C>>
|
|
39
|
+
: T extends `...${infer R}`
|
|
40
|
+
? ["...", R]
|
|
41
|
+
: T extends `"""${infer R}`
|
|
42
|
+
? R extends `${infer B}"""${infer R2}`
|
|
43
|
+
? [`"${B}`, R2]
|
|
44
|
+
: [null, ""]
|
|
45
|
+
: T extends `"${infer R}`
|
|
46
|
+
? ReadStr<R> extends [infer B extends string, infer R2 extends string]
|
|
47
|
+
? [`"${B}`, R2]
|
|
48
|
+
: [null, ""]
|
|
49
|
+
: T extends `$${infer R}`
|
|
50
|
+
? ReadName<R> extends [infer N extends string, infer R2 extends string]
|
|
51
|
+
? [`$${N}`, R2]
|
|
52
|
+
: [null, ""]
|
|
53
|
+
: T extends `${infer C}${infer R}`
|
|
54
|
+
? C extends Punct
|
|
55
|
+
? [C, R]
|
|
56
|
+
: C extends NameChar
|
|
57
|
+
? ReadName<T> extends [infer N extends string, infer R2 extends string]
|
|
58
|
+
? [N, R2]
|
|
59
|
+
: [null, ""]
|
|
60
|
+
: Tok1<R>
|
|
61
|
+
: [null, ""]
|
|
62
|
+
: [null, ""];
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
// ---- names: tokenize, singularize, PascalCase (src/naming.js) ---------------------------------
|
|
66
|
+
|
|
67
|
+
export type IsUpper<C extends string> = C extends Uppercase<C> ? (C extends Lowercase<C> ? false : true) : false;
|
|
68
|
+
export type IsLowerLetter<C extends string> = C extends Lower ? true : false;
|
|
69
|
+
export type Alnum = Lower | Upper | Digit;
|
|
70
|
+
export type Push<Acc extends string[], Cur extends string> = Cur extends "" ? Acc : [...Acc, Lowercase<Cur>];
|
|
71
|
+
|
|
72
|
+
/** Prev: "l" lower or digit, "u" upper, "s" start or separator. */
|
|
73
|
+
export type Words<N extends string, Cur extends string = "", Prev extends "l" | "u" | "s" = "s", Acc extends string[] = []> = N extends `${infer C}${infer R}`
|
|
74
|
+
? C extends Alnum
|
|
75
|
+
? IsUpper<C> extends true
|
|
76
|
+
? Prev extends "l"
|
|
77
|
+
? Words<R, C, "u", Push<Acc, Cur>>
|
|
78
|
+
: Prev extends "u"
|
|
79
|
+
? R extends `${infer N1}${string}`
|
|
80
|
+
? IsLowerLetter<N1> extends true
|
|
81
|
+
? Words<R, C, "u", Push<Acc, Cur>>
|
|
82
|
+
: Words<R, `${Cur}${C}`, "u", Acc>
|
|
83
|
+
: Words<R, `${Cur}${C}`, "u", Acc>
|
|
84
|
+
: Words<R, `${Cur}${C}`, "u", Acc>
|
|
85
|
+
: Words<R, `${Cur}${C}`, "l", Acc>
|
|
86
|
+
: Words<R, "", "s", Push<Acc, Cur>>
|
|
87
|
+
: Push<Acc, Cur>;
|
|
88
|
+
|
|
89
|
+
export type IrregularSingular = {
|
|
90
|
+
people: "person"; men: "man"; women: "woman"; children: "child"; mice: "mouse"; feet: "foot"; teeth: "tooth"; geese: "goose";
|
|
91
|
+
analyses: "analysis"; indices: "index"; criteria: "criterion"; knives: "knife"; wives: "wife"; leaves: "leaf"; lives: "life";
|
|
92
|
+
shelves: "shelf"; wolves: "wolf"; data: "data"; movies: "movie"; cookies: "cookie"; pies: "pie"; ties: "tie"; lies: "lie";
|
|
93
|
+
zombies: "zombie"; selfies: "selfie"; rookies: "rookie"; calories: "calorie"; species: "species"; series: "series";
|
|
94
|
+
};
|
|
95
|
+
export type Vowel = "a" | "e" | "i" | "o" | "u";
|
|
96
|
+
export type Singular<W extends string> = W extends keyof IrregularSingular
|
|
97
|
+
? IrregularSingular[W]
|
|
98
|
+
: W extends `${infer P}ies`
|
|
99
|
+
? P extends `${string}${Vowel}`
|
|
100
|
+
? SingularRest<W>
|
|
101
|
+
: P extends ""
|
|
102
|
+
? SingularRest<W>
|
|
103
|
+
: `${P}y`
|
|
104
|
+
: SingularRest<W>;
|
|
105
|
+
export type SingularRest<W extends string> = W extends `${string}${"ss" | "x" | "ch" | "sh"}es`
|
|
106
|
+
? W extends `${infer P}es`
|
|
107
|
+
? P
|
|
108
|
+
: W
|
|
109
|
+
: W extends `${string}${"ss" | "us" | "is"}`
|
|
110
|
+
? W
|
|
111
|
+
: W extends `${infer P}s`
|
|
112
|
+
? P
|
|
113
|
+
: W;
|
|
114
|
+
|
|
115
|
+
export type Last<T extends string[]> = T extends [...string[], infer L extends string] ? L : never;
|
|
116
|
+
export type Init<T extends string[]> = T extends [...infer I extends string[], string] ? I : [];
|
|
117
|
+
export type SingularLast<T extends string[]> = [...Init<T>, Singular<Last<T>>];
|
|
118
|
+
export type Pascal<T extends string[], Acc extends string = ""> = T extends [infer H extends string, ...infer R extends string[]] ? Pascal<R, `${Acc}${Capitalize<H>}`> : Acc;
|
|
119
|
+
export type Reserved = "Int" | "Float" | "String" | "Boolean" | "ID" | "DateTime" | "Query" | "Mutation" | "Subscription";
|
|
120
|
+
export type FixType<N extends string> = N extends `${Digit}${string}` ? `T${N}` : N extends Reserved ? `${N}Type` : N;
|
|
121
|
+
/** Rule N3: the type name of an object field (`blogPosts` is `BlogPost`). */
|
|
122
|
+
export type TypeNameOf<Name extends string> = Words<Name> extends infer T extends string[] ? (T extends [] ? "Object" : FixType<Pascal<SingularLast<T>>>) : never;
|
|
123
|
+
|
|
124
|
+
// ---- the L and T rules (src/rules.js) ----------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
export type IrregularPlural = "people" | "children" | "men" | "women" | "mice";
|
|
127
|
+
export type SingularPlural = "views" | "likes" | "votes" | "dislikes" | "news" | "series" | "species";
|
|
128
|
+
export type PluralLast<W extends string> = W extends SingularPlural ? false : W extends IrregularPlural ? true : W extends "data" ? false : W extends `${string}${"ss" | "us" | "is"}` ? false : W extends `${string}s` ? true : false;
|
|
129
|
+
export type PagingArg = "first" | "last" | "limit" | "offset" | "skip" | "take" | "page" | "after";
|
|
130
|
+
|
|
131
|
+
/** `<x>Count`, `total<X>s` (docs/design.md 6.2): counts of a sibling collection are numbers. */
|
|
132
|
+
export type CountOf<T extends string[], L extends string = Last<T>> = T extends [infer First, ...infer Rest extends string[]]
|
|
133
|
+
? Rest extends []
|
|
134
|
+
? false
|
|
135
|
+
: L extends "count"
|
|
136
|
+
? true
|
|
137
|
+
: First extends "total"
|
|
138
|
+
? L extends SingularPlural
|
|
139
|
+
? false
|
|
140
|
+
: L extends `${string}s`
|
|
141
|
+
? Singular<L> extends Measure
|
|
142
|
+
? false
|
|
143
|
+
: Rest extends ["count"]
|
|
144
|
+
? false
|
|
145
|
+
: true
|
|
146
|
+
: false
|
|
147
|
+
: false
|
|
148
|
+
: false;
|
|
149
|
+
export type Measure = "view" | "like" | "vote" | "dislike" | "click" | "download" | "impression" | "visit" | "reaction" | "page" | "word" | "character";
|
|
150
|
+
|
|
151
|
+
export type ListRuleOf<Name extends string, T extends string[], F extends FieldNode> = F["pg"] extends true
|
|
152
|
+
? true
|
|
153
|
+
: PluralLast<Last<T>> extends true
|
|
154
|
+
? true
|
|
155
|
+
: Lowercase<Name> extends "list"
|
|
156
|
+
? true
|
|
157
|
+
: Last<T> extends "list"
|
|
158
|
+
? true
|
|
159
|
+
: T extends ["all", string, ...string[]]
|
|
160
|
+
? true
|
|
161
|
+
: F["ids"] extends true
|
|
162
|
+
? true
|
|
163
|
+
: F["ll"];
|
|
164
|
+
|
|
165
|
+
export type ImageWord = "avatar" | "image" | "photo" | "thumbnail" | "picture" | "logo";
|
|
166
|
+
export type ImageSuffix = "url" | "uri" | "link" | "src";
|
|
167
|
+
export type UrlWord = "url" | "uri" | "link" | "website" | "homepage";
|
|
168
|
+
export type PhoneWord = "phone" | "mobile" | "tel" | "telephone";
|
|
169
|
+
export type BoolPrefix = "is" | "has" | "can" | "should" | "was" | "did" | "allow" | "allows" | "allowed";
|
|
170
|
+
export type BoolSuffix = "enabled" | "active" | "verified" | "public" | "deleted" | "archived" | "flag";
|
|
171
|
+
export type IntLast = "count" | "total" | "qty" | "quantity" | "num" | "age" | "year" | "index" | "position" | "rank" | "level" | "size" | "length" | "views" | "likes" | "votes";
|
|
172
|
+
export type FloatLast = "price" | "cost" | "amount" | "total" | "subtotal" | "tax" | "fee" | "balance" | "salary" | "revenue" | "rate" | "ratio" | "score" | "rating" | "weight" | "height" | "lat" | "lng" | "latitude" | "longitude" | "percent";
|
|
173
|
+
|
|
174
|
+
export type Has<T extends string[], W extends string> = W extends T[number] ? true : false;
|
|
175
|
+
export type AnyImage<T extends string[]> = [Extract<T[number], ImageWord>] extends [never] ? false : true;
|
|
176
|
+
|
|
177
|
+
/** T1 to T13 reduced to the JSON type: `string`, `number` or `boolean` (dates and IDs are strings). */
|
|
178
|
+
export type ScalarJs<T extends string[]> = T extends []
|
|
179
|
+
? string
|
|
180
|
+
: Last<T> extends "id"
|
|
181
|
+
? string
|
|
182
|
+
: Last<T> extends "email" | "mail"
|
|
183
|
+
? string
|
|
184
|
+
: Last<T> extends "address"
|
|
185
|
+
? Has<T, "email"> extends true
|
|
186
|
+
? string
|
|
187
|
+
: Next<T>
|
|
188
|
+
: Last<T> extends ImageWord
|
|
189
|
+
? string
|
|
190
|
+
: Last<T> extends ImageSuffix
|
|
191
|
+
? AnyImage<T> extends true
|
|
192
|
+
? string
|
|
193
|
+
: Next<T>
|
|
194
|
+
: Next<T>;
|
|
195
|
+
export type Next<T extends string[]> = Last<T> extends UrlWord
|
|
196
|
+
? string
|
|
197
|
+
: Has<T, "url"> extends true
|
|
198
|
+
? string
|
|
199
|
+
: Last<T> extends PhoneWord
|
|
200
|
+
? string
|
|
201
|
+
: T[0] extends BoolPrefix
|
|
202
|
+
? boolean
|
|
203
|
+
: Last<T> extends BoolSuffix
|
|
204
|
+
? boolean
|
|
205
|
+
: T extends ["number", "of", ...string[]]
|
|
206
|
+
? number
|
|
207
|
+
: Last<T> extends IntLast | FloatLast
|
|
208
|
+
? number
|
|
209
|
+
: string;
|
|
210
|
+
/** `deletedAt` is null by default (rule T10). */
|
|
211
|
+
export type DeletedAt<T extends string[]> = T extends ["deleted", "at"] ? true : false;
|
|
212
|
+
|
|
213
|
+
// ---- the AST ------------------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
export type Item = FieldNode | { k: "i"; on: string | null; sel: Item[] } | { k: "s"; n: string };
|
|
216
|
+
export interface FieldNode {
|
|
217
|
+
k: "f";
|
|
218
|
+
n: string;
|
|
219
|
+
a: string;
|
|
220
|
+
/** a paging argument, an `ids` argument, a list-valued argument */
|
|
221
|
+
pg: boolean;
|
|
222
|
+
ids: boolean;
|
|
223
|
+
ll: boolean;
|
|
224
|
+
ls: "list" | "one" | null;
|
|
225
|
+
ty: string | null;
|
|
226
|
+
nr: boolean;
|
|
227
|
+
/** @gen, @pattern or @pick: the generator name and, for @pick, the value tokens */
|
|
228
|
+
gn: null | { g: string; v: string[] | null };
|
|
229
|
+
dv: string | null;
|
|
230
|
+
/** @skip or @include: the key may be absent */
|
|
231
|
+
op: boolean;
|
|
232
|
+
sel: Item[] | null;
|
|
233
|
+
}
|
|
234
|
+
export interface ArgInfo {
|
|
235
|
+
n: string;
|
|
236
|
+
v: Record<string, unknown>;
|
|
237
|
+
l: boolean;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export type Pop<D extends 0[]> = D extends [0, ...infer R extends 0[]] ? R : [];
|
|
241
|
+
export type IsListVar<V extends string, VL extends string, Dflt extends boolean> = V extends `$${infer N}` ? (N extends VL ? true : Dflt) : Dflt;
|
|
242
|
+
|
|
243
|
+
/** Read a list literal `[a, b]` (the opening bracket is consumed); nested values become "{". */
|
|
244
|
+
export type ReadList<S extends string, Acc extends string[] = [], D extends 0[] = []> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
245
|
+
? D extends []
|
|
246
|
+
? H extends "]"
|
|
247
|
+
? [Acc, R]
|
|
248
|
+
: H extends "[" | "{"
|
|
249
|
+
? ReadList<R, [...Acc, "{"], [0]>
|
|
250
|
+
: ReadList<R, [...Acc, H], D>
|
|
251
|
+
: H extends "[" | "{"
|
|
252
|
+
? ReadList<R, Acc, [...D, 0]>
|
|
253
|
+
: H extends "]" | "}"
|
|
254
|
+
? ReadList<R, Acc, Pop<D>>
|
|
255
|
+
: ReadList<R, Acc, D>
|
|
256
|
+
: [Acc, ""];
|
|
257
|
+
|
|
258
|
+
/** Read the arguments of a field or directive (the opening parenthesis is consumed). */
|
|
259
|
+
export type ReadArgs<S extends string, D extends 0[], Acc extends ArgInfo, VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
260
|
+
? H extends ")"
|
|
261
|
+
? D extends [0]
|
|
262
|
+
? [Acc, R]
|
|
263
|
+
: ReadArgs<R, Pop<D>, Acc, VL>
|
|
264
|
+
: H extends "(" | "{" | "["
|
|
265
|
+
? ReadArgs<R, [...D, 0], Acc, VL>
|
|
266
|
+
: H extends "}" | "]"
|
|
267
|
+
? ReadArgs<R, Pop<D>, Acc, VL>
|
|
268
|
+
: D extends [0]
|
|
269
|
+
? Tok1<R> extends [":", infer R1 extends string]
|
|
270
|
+
? Tok1<R1> extends [infer V extends string, infer R2 extends string]
|
|
271
|
+
? V extends "["
|
|
272
|
+
? ReadList<R2> extends [infer Items extends string[], infer R3 extends string]
|
|
273
|
+
? ReadArgs<R3, D, { n: Acc["n"] | H; v: Acc["v"] & { [K in H]: Items }; l: true }, VL>
|
|
274
|
+
: Acc
|
|
275
|
+
: V extends "{"
|
|
276
|
+
? ReadArgs<R1, D, { n: Acc["n"] | H; v: Acc["v"] & { [K in H]: "{" }; l: Acc["l"] }, VL>
|
|
277
|
+
: ReadArgs<R2, D, { n: Acc["n"] | H; v: Acc["v"] & { [K in H]: V }; l: IsListVar<V, VL, Acc["l"]> }, VL>
|
|
278
|
+
: Acc
|
|
279
|
+
: ReadArgs<R, D, Acc, VL>
|
|
280
|
+
: ReadArgs<R, D, Acc, VL>
|
|
281
|
+
: [Acc, ""];
|
|
282
|
+
|
|
283
|
+
export type NoArgs = { n: never; v: {}; l: false };
|
|
284
|
+
/** Directives after a field: `@name` and `@name(args)`. */
|
|
285
|
+
export type ReadDirs<S extends string, VL extends string, Acc = {}> = Tok1<S> extends ["@", infer R extends string]
|
|
286
|
+
? Tok1<R> extends [infer N extends string, infer R2 extends string]
|
|
287
|
+
? Tok1<R2> extends ["(", infer R3 extends string]
|
|
288
|
+
? ReadArgs<R3, [0], NoArgs, VL> extends [infer A extends ArgInfo, infer R4 extends string]
|
|
289
|
+
? ReadDirs<R4, VL, Acc & { [K in N]: A["v"] }>
|
|
290
|
+
: [Acc, ""]
|
|
291
|
+
: ReadDirs<R2, VL, Acc & { [K in N]: {} }>
|
|
292
|
+
: [Acc, ""]
|
|
293
|
+
: [Acc, S];
|
|
294
|
+
|
|
295
|
+
export type Unquote<S> = S extends `"${infer B}` ? B : never;
|
|
296
|
+
export type DirType<D> = D extends { type: { name: infer V } } ? (V extends string ? (Unquote<V> extends infer U extends string ? ([U] extends [never] ? null : U) : null) : null) : null;
|
|
297
|
+
export type DirGen<D> = D extends { gen: { name: infer V } }
|
|
298
|
+
? [Unquote<V>] extends [never]
|
|
299
|
+
? { g: ""; v: null }
|
|
300
|
+
: { g: Unquote<V>; v: null }
|
|
301
|
+
: D extends { pattern: unknown }
|
|
302
|
+
? { g: "pattern"; v: null }
|
|
303
|
+
: D extends { pick: { values: infer V extends string[] } }
|
|
304
|
+
? { g: "oneOf"; v: V }
|
|
305
|
+
: D extends { pick: unknown }
|
|
306
|
+
? { g: "oneOf"; v: ["{"] }
|
|
307
|
+
: null;
|
|
308
|
+
export type DirNull<D> = D extends { nullRate: { p: infer V } } ? (V extends "0" | "0.0" | "0.00" ? false : true) : false;
|
|
309
|
+
export type DirDerive<D> = D extends { derive: { from: infer V } } ? (V extends string ? (Unquote<V> extends infer U extends string ? ([U] extends [never] ? null : U) : null) : null) : null;
|
|
310
|
+
export type DirList<D> = D extends { list: unknown } ? "list" : D extends { one: unknown } ? "one" : null;
|
|
311
|
+
export type DirOpt<D> = D extends { skip: unknown } | { include: unknown } ? true : false;
|
|
312
|
+
|
|
313
|
+
export type MakeField<Alias extends string, Name extends string, A extends ArgInfo, D, Sel extends Item[] | null> = {
|
|
314
|
+
k: "f";
|
|
315
|
+
n: Name;
|
|
316
|
+
a: Alias;
|
|
317
|
+
pg: [A["n"] & PagingArg] extends [never] ? false : true;
|
|
318
|
+
ids: "ids" extends A["n"] ? true : false;
|
|
319
|
+
ll: A["l"];
|
|
320
|
+
ls: DirList<D>;
|
|
321
|
+
ty: DirType<D>;
|
|
322
|
+
nr: DirNull<D>;
|
|
323
|
+
gn: DirGen<D>;
|
|
324
|
+
dv: DirDerive<D>;
|
|
325
|
+
op: DirOpt<D>;
|
|
326
|
+
sel: Sel;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// ---- parser: selection sets (recursive descent over the text) ---------------------------------------
|
|
330
|
+
// One selection set is a loop (the compiler allows 1000 tail steps); nested sets nest the evaluation.
|
|
331
|
+
|
|
332
|
+
export type ParseSel<S extends string, Cur extends Item[], VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
333
|
+
? H extends "}"
|
|
334
|
+
? { sel: Cur; rest: R }
|
|
335
|
+
: (H extends "..." ? ParseSpread<R, VL> : ParseField<H, R, VL>) extends [infer It extends Item, infer R2 extends string]
|
|
336
|
+
? ParseSel<R2, [...Cur, It], VL>
|
|
337
|
+
: { bad: true }
|
|
338
|
+
: { bad: true };
|
|
339
|
+
|
|
340
|
+
export type SkipDirs<S extends string, VL extends string> = ReadDirs<S, VL> extends [unknown, infer R extends string] ? R : S;
|
|
341
|
+
|
|
342
|
+
/** A nested selection set (the opening brace is consumed): `[sel, rest]`. */
|
|
343
|
+
export type Nested<S extends string, VL extends string> = ParseSel<S, [], VL> extends { sel: infer Sel extends Item[]; rest: infer R extends string } ? [Sel, R] : { bad: true };
|
|
344
|
+
|
|
345
|
+
export type ParseSpread<S extends string, VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
346
|
+
? H extends "on"
|
|
347
|
+
? Tok1<R> extends [infer C extends string, infer R1 extends string]
|
|
348
|
+
? Tok1<SkipDirs<R1, VL>> extends ["{", infer R2 extends string]
|
|
349
|
+
? Nested<R2, VL> extends [infer Sel extends Item[], infer R3 extends string]
|
|
350
|
+
? [{ k: "i"; on: C; sel: Sel }, R3]
|
|
351
|
+
: { bad: true }
|
|
352
|
+
: { bad: true }
|
|
353
|
+
: { bad: true }
|
|
354
|
+
: H extends "{"
|
|
355
|
+
? Nested<R, VL> extends [infer Sel extends Item[], infer R3 extends string]
|
|
356
|
+
? [{ k: "i"; on: null; sel: Sel }, R3]
|
|
357
|
+
: { bad: true }
|
|
358
|
+
: H extends "@"
|
|
359
|
+
? Tok1<SkipDirs<S, VL>> extends ["{", infer R2 extends string]
|
|
360
|
+
? Nested<R2, VL> extends [infer Sel extends Item[], infer R3 extends string]
|
|
361
|
+
? [{ k: "i"; on: null; sel: Sel }, R3]
|
|
362
|
+
: { bad: true }
|
|
363
|
+
: { bad: true }
|
|
364
|
+
: [{ k: "s"; n: H }, SkipDirs<R, VL>]
|
|
365
|
+
: { bad: true };
|
|
366
|
+
|
|
367
|
+
export type ParseField<H extends string, R extends string, VL extends string> = Tok1<R> extends [":", infer R1 extends string]
|
|
368
|
+
? Tok1<R1> extends [infer Real extends string, infer R2 extends string]
|
|
369
|
+
? ParseField2<H, Real, R2, VL>
|
|
370
|
+
: { bad: true }
|
|
371
|
+
: ParseField2<H, H, R, VL>;
|
|
372
|
+
|
|
373
|
+
export type ParseField2<Alias extends string, Name extends string, R extends string, VL extends string> = Tok1<R> extends ["(", infer R1 extends string]
|
|
374
|
+
? ReadArgs<R1, [0], NoArgs, VL> extends [infer A extends ArgInfo, infer R2 extends string]
|
|
375
|
+
? ParseField3<Alias, Name, A, R2, VL>
|
|
376
|
+
: { bad: true }
|
|
377
|
+
: ParseField3<Alias, Name, NoArgs, R, VL>;
|
|
378
|
+
|
|
379
|
+
export type ParseField3<Alias extends string, Name extends string, A extends ArgInfo, R extends string, VL extends string> = ReadDirs<R, VL> extends [infer D, infer R2 extends string]
|
|
380
|
+
? Tok1<R2> extends ["{", infer R3 extends string]
|
|
381
|
+
? Nested<R3, VL> extends [infer Sel extends Item[], infer R4 extends string]
|
|
382
|
+
? [MakeField<Alias, Name, A, D, Sel>, R4]
|
|
383
|
+
: { bad: true }
|
|
384
|
+
: [MakeField<Alias, Name, A, D, null>, R2]
|
|
385
|
+
: { bad: true };
|
|
386
|
+
|
|
387
|
+
/** Operation header: name, variable definitions (collect the list-typed variables), directives. */
|
|
388
|
+
export type VarDefs<S extends string, D extends 0[], VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
389
|
+
? H extends ")"
|
|
390
|
+
? D extends [0]
|
|
391
|
+
? [VL, R]
|
|
392
|
+
: VarDefs<R, Pop<D>, VL>
|
|
393
|
+
: H extends "(" | "{" | "["
|
|
394
|
+
? VarDefs<R, [...D, 0], VL>
|
|
395
|
+
: H extends "}" | "]"
|
|
396
|
+
? VarDefs<R, Pop<D>, VL>
|
|
397
|
+
: H extends `$${infer N}`
|
|
398
|
+
? Tok1<R> extends [":", infer R1 extends string]
|
|
399
|
+
? Tok1<R1> extends ["[", infer R2 extends string]
|
|
400
|
+
? VarDefs<R2, [...D, 0], VL | N>
|
|
401
|
+
: VarDefs<R1, D, VL>
|
|
402
|
+
: VarDefs<R, D, VL>
|
|
403
|
+
: VarDefs<R, D, VL>
|
|
404
|
+
: [VL, ""];
|
|
405
|
+
export type OpHead<S extends string, VL extends string = never> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
406
|
+
? H extends "{"
|
|
407
|
+
? [VL, R]
|
|
408
|
+
: H extends "("
|
|
409
|
+
? VarDefs<R, [0], VL> extends [infer V extends string, infer R2 extends string]
|
|
410
|
+
? OpHead<R2, V>
|
|
411
|
+
: never
|
|
412
|
+
: OpHead<R, VL>
|
|
413
|
+
: never;
|
|
414
|
+
|
|
415
|
+
export interface DocT {
|
|
416
|
+
ops: Item[][];
|
|
417
|
+
frags: Record<string, { on: string; sel: Item[] }>;
|
|
418
|
+
ok: boolean;
|
|
419
|
+
}
|
|
420
|
+
export type Failed<Ops extends Item[][], Frags> = { ops: Ops; frags: Frags; ok: false };
|
|
421
|
+
export type Doc<S extends string, Ops extends Item[][] = [], Frags extends DocT["frags"] = {}> = Tok1<S> extends [infer H extends string, infer R extends string]
|
|
422
|
+
? H extends "{"
|
|
423
|
+
? ParseSel<R, [], never> extends { sel: infer Sel extends Item[]; rest: infer R2 extends string }
|
|
424
|
+
? Doc<R2, [...Ops, Sel], Frags>
|
|
425
|
+
: Failed<Ops, Frags>
|
|
426
|
+
: H extends "query" | "mutation" | "subscription"
|
|
427
|
+
? OpHead<R> extends [infer VL extends string, infer R2 extends string]
|
|
428
|
+
? ParseSel<R2, [], VL> extends { sel: infer Sel extends Item[]; rest: infer R3 extends string }
|
|
429
|
+
? Doc<R3, [...Ops, Sel], Frags>
|
|
430
|
+
: Failed<Ops, Frags>
|
|
431
|
+
: Failed<Ops, Frags>
|
|
432
|
+
: H extends "fragment"
|
|
433
|
+
? Tok1<R> extends [infer N extends string, infer R1 extends string]
|
|
434
|
+
? Tok1<R1> extends ["on", infer R2 extends string]
|
|
435
|
+
? Tok1<R2> extends [infer C extends string, infer R3 extends string]
|
|
436
|
+
? Tok1<SkipDirs<R3, never>> extends ["{", infer R4 extends string]
|
|
437
|
+
? ParseSel<R4, [], never> extends { sel: infer Sel extends Item[]; rest: infer R5 extends string }
|
|
438
|
+
? Doc<R5, Ops, Frags & { [K in N]: { on: C; sel: Sel } }>
|
|
439
|
+
: Failed<Ops, Frags>
|
|
440
|
+
: Failed<Ops, Frags>
|
|
441
|
+
: Failed<Ops, Frags>
|
|
442
|
+
: Failed<Ops, Frags>
|
|
443
|
+
: Failed<Ops, Frags>
|
|
444
|
+
: Failed<Ops, Frags>
|
|
445
|
+
: { ops: Ops; frags: Frags; ok: true };
|
|
446
|
+
|
|
447
|
+
// ---- evaluation ---------------------------------------------------------------------------------
|
|
448
|
+
|
|
449
|
+
export type Simplify<T> = { [K in keyof T]: T[K] } & {};
|
|
450
|
+
|
|
451
|
+
/** Fields of a selection set, looking through every fragment (the `flattenFields` of src/infer.js). */
|
|
452
|
+
export type Flatten<Sel extends Item[], Fr, Acc extends FieldNode[] = []> = Sel extends [infer I, ...infer R extends Item[]]
|
|
453
|
+
? I extends FieldNode
|
|
454
|
+
? Flatten<R, Fr, [...Acc, I]>
|
|
455
|
+
: I extends { k: "i"; sel: infer S extends Item[] }
|
|
456
|
+
? Flatten<R, Fr, [...Acc, ...Flatten<S, Fr>]>
|
|
457
|
+
: I extends { k: "s"; n: infer N }
|
|
458
|
+
? N extends keyof Fr
|
|
459
|
+
? Fr[N] extends { sel: infer S extends Item[] }
|
|
460
|
+
? Flatten<R, Fr, [...Acc, ...Flatten<S, Fr>]>
|
|
461
|
+
: Flatten<R, Fr, Acc>
|
|
462
|
+
: Flatten<R, Fr, Acc>
|
|
463
|
+
: Flatten<R, Fr, Acc>
|
|
464
|
+
: Acc;
|
|
465
|
+
|
|
466
|
+
/** The fields of one possible type of a union or interface (`walkAbstract` in src/infer.js). */
|
|
467
|
+
export type FlattenFor<Sel extends Item[], Fr, T extends string, Acc extends FieldNode[] = []> = Sel extends [infer I, ...infer R extends Item[]]
|
|
468
|
+
? I extends FieldNode
|
|
469
|
+
? FlattenFor<R, Fr, T, [...Acc, I]>
|
|
470
|
+
: I extends { k: "i"; on: infer C; sel: infer S extends Item[] }
|
|
471
|
+
? C extends null
|
|
472
|
+
? FlattenFor<R, Fr, T, [...Acc, ...FlattenFor<S, Fr, T>]>
|
|
473
|
+
: C extends T
|
|
474
|
+
? FlattenFor<R, Fr, T, [...Acc, ...Flatten<S, Fr>]>
|
|
475
|
+
: FlattenFor<R, Fr, T, Acc>
|
|
476
|
+
: I extends { k: "s"; n: infer N }
|
|
477
|
+
? N extends keyof Fr
|
|
478
|
+
? Fr[N] extends { on: infer C; sel: infer S extends Item[] }
|
|
479
|
+
? C extends T
|
|
480
|
+
? FlattenFor<R, Fr, T, [...Acc, ...Flatten<S, Fr>]>
|
|
481
|
+
: FlattenFor<R, Fr, T, Acc>
|
|
482
|
+
: FlattenFor<R, Fr, T, Acc>
|
|
483
|
+
: FlattenFor<R, Fr, T, Acc>
|
|
484
|
+
: FlattenFor<R, Fr, T, Acc>
|
|
485
|
+
: Acc;
|
|
486
|
+
|
|
487
|
+
/** Distinct type conditions applied directly to a field's selection (rules N2 and S4). */
|
|
488
|
+
export type Explicit<Sel extends Item[], Fr, Acc extends string = never> = Sel extends [infer I, ...infer R extends Item[]]
|
|
489
|
+
? I extends { k: "i"; on: infer C; sel: infer S extends Item[] }
|
|
490
|
+
? C extends string
|
|
491
|
+
? Explicit<R, Fr, Acc | C>
|
|
492
|
+
: Explicit<R, Fr, Acc | Explicit<S, Fr>>
|
|
493
|
+
: I extends { k: "s"; n: infer N }
|
|
494
|
+
? N extends keyof Fr
|
|
495
|
+
? Fr[N] extends { on: infer C extends string }
|
|
496
|
+
? Explicit<R, Fr, Acc | C>
|
|
497
|
+
: Explicit<R, Fr, Acc>
|
|
498
|
+
: Explicit<R, Fr, Acc>
|
|
499
|
+
: Explicit<R, Fr, Acc>
|
|
500
|
+
: Acc;
|
|
501
|
+
|
|
502
|
+
export type IsUnion<T, U = T> = [T] extends [never] ? false : T extends unknown ? ([U] extends [T] ? false : true) : never;
|
|
503
|
+
|
|
504
|
+
/** Merge fields with the same response key: their selections concatenate. */
|
|
505
|
+
export type Dedupe<Fl extends FieldNode[]> = { [A in Fl[number]["a"]]: ByAlias<Fl, A> };
|
|
506
|
+
export type ByAlias<Fl extends FieldNode[], A extends string> = Extract<Fl[number], { a: A }> extends infer X ? (IsUnion<X> extends true ? FoldAlias<Fl, A> : X) : never;
|
|
507
|
+
export type FoldAlias<Fl extends FieldNode[], A extends string, Acc = never> = Fl extends [infer F extends FieldNode, ...infer R extends FieldNode[]]
|
|
508
|
+
? F["a"] extends A
|
|
509
|
+
? FoldAlias<R, A, [Acc] extends [never] ? F : MergeField<Acc, F>>
|
|
510
|
+
: FoldAlias<R, A, Acc>
|
|
511
|
+
: Acc;
|
|
512
|
+
export type MergeField<A, B extends FieldNode> = A extends FieldNode ? (A["sel"] extends Item[] ? (B["sel"] extends Item[] ? { [K in keyof A]: K extends "sel" ? [...A["sel"], ...B["sel"]] : A[K] } : A) : A) : A;
|
|
513
|
+
|
|
514
|
+
export type ReqKeys<D> = { [K in keyof D]: D[K] extends { op: true } ? never : K }[keyof D];
|
|
515
|
+
export type OptKeys<D> = { [K in keyof D]: D[K] extends { op: true } ? K : never }[keyof D];
|
|
516
|
+
|
|
517
|
+
export type Syn = "conn" | "edge" | "page" | null;
|
|
518
|
+
|
|
519
|
+
export type ObjOf<Fl extends FieldNode[], Fr, TN extends string, S extends Syn = null, Itm extends string = ""> = Dedupe<Fl> extends infer D
|
|
520
|
+
? Simplify<{ [K in ReqKeys<D> & string]: ValOf<D[K & keyof D], Fr, TN, S, Itm> } & { [K in OptKeys<D> & string]?: ValOf<D[K & keyof D], Fr, TN, S, Itm> }>
|
|
521
|
+
: never;
|
|
522
|
+
|
|
523
|
+
export type ValOf<N, Fr, TN extends string, S extends Syn, Itm extends string> = N extends FieldNode ? Val<N, Fr, TN, S, Itm> : never;
|
|
524
|
+
|
|
525
|
+
export type Val<F extends FieldNode, Fr, TN extends string, S extends Syn, Itm extends string> = S extends "conn"
|
|
526
|
+
? F["n"] extends "edges"
|
|
527
|
+
? F["sel"] extends Item[]
|
|
528
|
+
? ObjOf<Flatten<F["sel"], Fr>, Fr, `${Itm}Edge`, "edge", Itm>[]
|
|
529
|
+
: unknown
|
|
530
|
+
: F["n"] extends "nodes"
|
|
531
|
+
? F["sel"] extends Item[]
|
|
532
|
+
? ObjOf<Flatten<F["sel"], Fr>, Fr, Itm>[]
|
|
533
|
+
: unknown
|
|
534
|
+
: F["n"] extends "pageInfo"
|
|
535
|
+
? F["sel"] extends Item[]
|
|
536
|
+
? ObjOf<Flatten<F["sel"], Fr>, Fr, "PageInfo", "page">
|
|
537
|
+
: unknown
|
|
538
|
+
: F["n"] extends "totalCount"
|
|
539
|
+
? number
|
|
540
|
+
: Plain<F, Fr, TN>
|
|
541
|
+
: S extends "edge"
|
|
542
|
+
? F["n"] extends "cursor"
|
|
543
|
+
? string
|
|
544
|
+
: F["n"] extends "node"
|
|
545
|
+
? F["sel"] extends Item[]
|
|
546
|
+
? ObjOf<Flatten<F["sel"], Fr>, Fr, Itm>
|
|
547
|
+
: unknown
|
|
548
|
+
: Plain<F, Fr, TN>
|
|
549
|
+
: S extends "page"
|
|
550
|
+
? F["n"] extends "hasNextPage" | "hasPreviousPage"
|
|
551
|
+
? boolean
|
|
552
|
+
: F["n"] extends "startCursor" | "endCursor"
|
|
553
|
+
? string | null
|
|
554
|
+
: Plain<F, Fr, TN>
|
|
555
|
+
: Plain<F, Fr, TN>;
|
|
556
|
+
|
|
557
|
+
export type Plain<F extends FieldNode, Fr, TN extends string> = F["sel"] extends infer S extends Item[] ? ObjectValue<F, S, Fr> : ScalarValue<F, TN>;
|
|
558
|
+
|
|
559
|
+
export type Nullable<F extends FieldNode, T> = F["nr"] extends true ? T | null : T;
|
|
560
|
+
|
|
561
|
+
// scalars ----
|
|
562
|
+
|
|
563
|
+
export type GenJs<G extends { g: string; v: string[] | null }, Dflt> = G["g"] extends "oneOf"
|
|
564
|
+
? G["v"] extends string[]
|
|
565
|
+
? PickJs<G["v"]>
|
|
566
|
+
: unknown
|
|
567
|
+
: G["g"] extends "pattern"
|
|
568
|
+
? string
|
|
569
|
+
: G["g"] extends keyof GeneratorTypes
|
|
570
|
+
? GeneratorTypes[G["g"]]
|
|
571
|
+
: G["g"] extends ""
|
|
572
|
+
? Dflt
|
|
573
|
+
: unknown;
|
|
574
|
+
/** `@pick(values: [...])`: literal strings stay literal; numbers and booleans widen; anything else is unknown. */
|
|
575
|
+
export type PickJs<V extends string[]> = "{" extends V[number]
|
|
576
|
+
? unknown
|
|
577
|
+
: V extends []
|
|
578
|
+
? never
|
|
579
|
+
: PickOne<V[number]>;
|
|
580
|
+
export type PickOne<T extends string> = T extends `"${infer S}` ? S : T extends "true" | "false" ? boolean : T extends `${Digit}${string}` | `-${string}` ? number : unknown;
|
|
581
|
+
|
|
582
|
+
export type ScalarList<F extends FieldNode, T extends string[]> = F["ls"] extends "list" ? true : F["ls"] extends "one" ? false : F["dv"] extends string ? false : CountOf<T> extends true ? false : ListRuleOf<F["n"], T, F>;
|
|
583
|
+
|
|
584
|
+
export type ScalarValue<F extends FieldNode, TN extends string> = F["n"] extends "__typename"
|
|
585
|
+
? TN
|
|
586
|
+
: Words<F["n"]> extends infer T extends string[]
|
|
587
|
+
? ScalarList<F, T> extends infer L
|
|
588
|
+
? Nullable<F, ScalarBase<F, T, L>> extends infer V
|
|
589
|
+
? L extends true
|
|
590
|
+
? F["nr"] extends true
|
|
591
|
+
? Exclude<V, null>[] | null
|
|
592
|
+
: V[]
|
|
593
|
+
: V
|
|
594
|
+
: never
|
|
595
|
+
: never
|
|
596
|
+
: never;
|
|
597
|
+
export type ScalarBase<F extends FieldNode, T extends string[], L> = F["gn"] extends { g: string; v: string[] | null }
|
|
598
|
+
? GenJs<F["gn"], ScalarJs<L extends true ? SingularLast<T> : T>>
|
|
599
|
+
: F["dv"] extends string
|
|
600
|
+
? ScalarJs<Words<F["dv"]>>
|
|
601
|
+
: CountOf<T> extends true
|
|
602
|
+
? number
|
|
603
|
+
: L extends true
|
|
604
|
+
? ScalarJs<SingularLast<T>>
|
|
605
|
+
: DeletedAt<T> extends true
|
|
606
|
+
? string | null
|
|
607
|
+
: ScalarJs<T>;
|
|
608
|
+
|
|
609
|
+
// objects ----
|
|
610
|
+
|
|
611
|
+
export type TypeNameFor<F extends FieldNode, Ex extends string> = F["ty"] extends string ? F["ty"] : [Ex] extends [never] ? TypeNameOf<F["n"]> : IsUnion<Ex> extends true ? TypeNameOf<F["n"]> : Ex;
|
|
612
|
+
|
|
613
|
+
export type NamesWithSel<Kids extends FieldNode[]> = Kids[number] extends infer K ? (K extends { n: infer N; sel: Item[] } ? N : never) : never;
|
|
614
|
+
export type AllNames<Kids extends FieldNode[]> = Kids[number]["n"];
|
|
615
|
+
|
|
616
|
+
export type IsConnection<Kids extends FieldNode[], Ex extends string, F extends FieldNode> = F["ty"] extends string
|
|
617
|
+
? false
|
|
618
|
+
: [Ex] extends [never]
|
|
619
|
+
? ConnShape<Kids>
|
|
620
|
+
: Ex extends `${string}Connection`
|
|
621
|
+
? IsUnion<Ex> extends true
|
|
622
|
+
? ConnShape<Kids>
|
|
623
|
+
: true
|
|
624
|
+
: ConnShape<Kids>;
|
|
625
|
+
export type ConnShape<Kids extends FieldNode[]> = "edges" extends NamesWithSel<Kids>
|
|
626
|
+
? true
|
|
627
|
+
: "pageInfo" extends NamesWithSel<Kids>
|
|
628
|
+
? true
|
|
629
|
+
: "nodes" extends NamesWithSel<Kids>
|
|
630
|
+
? "totalCount" extends AllNames<Kids>
|
|
631
|
+
? true
|
|
632
|
+
: false
|
|
633
|
+
: false;
|
|
634
|
+
|
|
635
|
+
export type ConnItem<F extends FieldNode, Ex extends string> = [Ex] extends [never]
|
|
636
|
+
? ConnItemByName<F>
|
|
637
|
+
: IsUnion<Ex> extends true
|
|
638
|
+
? ConnItemByName<F>
|
|
639
|
+
: Ex extends `${infer I}Connection`
|
|
640
|
+
? I extends ""
|
|
641
|
+
? "Node"
|
|
642
|
+
: I
|
|
643
|
+
: ConnItemByName<F>;
|
|
644
|
+
export type ConnItemByName<F extends FieldNode> = Words<F["n"]> extends infer T extends string[]
|
|
645
|
+
? Last<T> extends "connection"
|
|
646
|
+
? TypeNameOf<Init<T> extends [] ? F["n"] : Join<Init<T>>>
|
|
647
|
+
: TypeNameOf<F["n"]>
|
|
648
|
+
: never;
|
|
649
|
+
export type Join<T extends string[], Acc extends string = ""> = T extends [infer H extends string, ...infer R extends string[]] ? Join<R, Acc extends "" ? H : `${Acc}_${H}`> : Acc;
|
|
650
|
+
|
|
651
|
+
export type ObjectValue<F extends FieldNode, Sel extends Item[], Fr> = Explicit<Sel, Fr> extends infer E0 extends string
|
|
652
|
+
? (F["ty"] extends string ? F["ty"] : E0) extends infer Ex extends string
|
|
653
|
+
? Flatten<Sel, Fr> extends infer Kids extends FieldNode[]
|
|
654
|
+
? IsUnion<Ex> extends true
|
|
655
|
+
? ListWrap<F, ObjList<F>, UnionObj<Sel, Fr, Ex>>
|
|
656
|
+
: IsConnection<Kids, Ex, F> extends true
|
|
657
|
+
? ListWrap<F, false, ObjOf<Kids, Fr, ConnTN<F, Ex>, "conn", ConnItem<F, Ex>>>
|
|
658
|
+
: ListWrap<F, ObjList<F>, ObjOf<Kids, Fr, TypeNameFor<F, Ex>>>
|
|
659
|
+
: never
|
|
660
|
+
: never
|
|
661
|
+
: never;
|
|
662
|
+
export type ConnTN<F extends FieldNode, Ex extends string> = `${ConnItem<F, Ex>}Connection`;
|
|
663
|
+
export type UnionObj<Sel extends Item[], Fr, Ex extends string> = Ex extends string ? ObjOf<FlattenFor<Sel, Fr, Ex>, Fr, Ex> : never;
|
|
664
|
+
|
|
665
|
+
/** Object fields: the list rule without argument-literal lists for unions (src/infer.js finalize). */
|
|
666
|
+
export type ObjList<F extends FieldNode> = F["ls"] extends "list" ? true : F["ls"] extends "one" ? false : Words<F["n"]> extends infer T extends string[] ? ListRuleOf<F["n"], T, F> : false;
|
|
667
|
+
export type ListWrap<F extends FieldNode, L, V> = L extends true ? Nullable<F, V[]> : Nullable<F, V>;
|
|
668
|
+
|
|
669
|
+
// ---- public --------------------------------------------------------------------------------------
|
|
670
|
+
|
|
671
|
+
export type AnyData = Record<string, unknown>;
|
|
672
|
+
export type Eval<D> = D extends { ok: true; ops: [infer S extends Item[]]; frags: infer Fr }
|
|
673
|
+
? ObjOf<Flatten<S, Fr>, Fr, "Query">
|
|
674
|
+
: AnyData;
|
|
675
|
+
export type ParseAll<Q extends string> = Doc<Q>;
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* The data a query returns, inferred from the query text. A query that is not a literal type
|
|
679
|
+
* (a `string` variable), has several operations or cannot be parsed gives `Record<string, unknown>`.
|
|
680
|
+
*/
|
|
681
|
+
export type ResultOf<Q> = Q extends string ? (string extends Q ? AnyData : Eval<ParseAll<Q>>) : AnyData;
|
|
682
|
+
|
|
683
|
+
export type ItemOfValue<V> = NonNullable<V> extends infer N
|
|
684
|
+
? N extends readonly (infer E)[]
|
|
685
|
+
? E
|
|
686
|
+
: N extends { nodes: readonly (infer E)[] }
|
|
687
|
+
? E
|
|
688
|
+
: N extends { edges: readonly { node: infer E }[] }
|
|
689
|
+
? E
|
|
690
|
+
: unknown
|
|
691
|
+
: never;
|
|
692
|
+
|
|
693
|
+
export type RootFields<Q extends string> = Doc<Q> extends { ok: true; ops: [infer S extends Item[]]; frags: infer Fr } ? [Flatten<S, Fr>, Fr] : never;
|
|
694
|
+
export type FirstCollection<Fl extends FieldNode[], Fr> = Fl extends [infer F extends FieldNode, ...infer R extends FieldNode[]]
|
|
695
|
+
? F["sel"] extends Item[]
|
|
696
|
+
? Val<F, Fr, "Query", null, ""> extends infer V
|
|
697
|
+
? NonNullable<V> extends readonly unknown[] | { edges: unknown } | { nodes: unknown }
|
|
698
|
+
? F
|
|
699
|
+
: FirstCollection<R, Fr>
|
|
700
|
+
: never
|
|
701
|
+
: FirstCollection<R, Fr>
|
|
702
|
+
: never;
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* The type of one item of the root collection `stream()` yields: the elements of the first root list,
|
|
706
|
+
* the nodes of a root connection, or the root field named by `Field` (a response key).
|
|
707
|
+
*/
|
|
708
|
+
export type ItemOf<Q, Field extends string | undefined = undefined> = Q extends string
|
|
709
|
+
? string extends Q
|
|
710
|
+
? Record<string, any>
|
|
711
|
+
: RootFields<Q> extends [infer Fl extends FieldNode[], infer Fr]
|
|
712
|
+
? (Field extends string ? Extract<Fl[number], { a: Field }> : FirstCollection<Fl, Fr>) extends infer F
|
|
713
|
+
? [F] extends [never]
|
|
714
|
+
? Record<string, any>
|
|
715
|
+
: F extends FieldNode
|
|
716
|
+
? ItemOfValue<Val<F, Fr, "Query", null, "">>
|
|
717
|
+
: never
|
|
718
|
+
: never
|
|
719
|
+
: Record<string, any>
|
|
720
|
+
: Record<string, any>;
|