@johnhenry/graceholder 0.0.0-stage → 0.1.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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +492 -2
  3. package/STABILITY.md +24 -0
  4. package/package.json +126 -4
  5. package/src/adapters/apollo.d.ts +13 -0
  6. package/src/adapters/apollo.js +48 -0
  7. package/src/adapters/fetch.d.ts +15 -0
  8. package/src/adapters/fetch.js +150 -0
  9. package/src/adapters/shared.d.ts +14 -0
  10. package/src/adapters/shared.js +65 -0
  11. package/src/adapters/urql.d.ts +8 -0
  12. package/src/adapters/urql.js +53 -0
  13. package/src/anchor.js +13 -0
  14. package/src/args.js +41 -0
  15. package/src/bulk/csv.js +118 -0
  16. package/src/bulk/ndjson.js +10 -0
  17. package/src/bulk/plan.js +195 -0
  18. package/src/bulk/shape.js +67 -0
  19. package/src/bulk/source.js +24 -0
  20. package/src/bulk/sql.js +366 -0
  21. package/src/bulk/stream.js +55 -0
  22. package/src/cursor.js +25 -0
  23. package/src/dbg.d.ts +720 -0
  24. package/src/detmath.js +74 -0
  25. package/src/directives.js +113 -0
  26. package/src/dist.js +90 -0
  27. package/src/errors.js +17 -0
  28. package/src/execute.js +577 -0
  29. package/src/explain.js +473 -0
  30. package/src/fast-check.d.ts +31 -0
  31. package/src/fast-check.js +58 -0
  32. package/src/generate.js +84 -0
  33. package/src/generator-types.d.ts +90 -0
  34. package/src/generators.js +361 -0
  35. package/src/image.js +55 -0
  36. package/src/index.d.ts +507 -0
  37. package/src/index.js +62 -0
  38. package/src/infer.js +888 -0
  39. package/src/key.js +30 -0
  40. package/src/learn.js +397 -0
  41. package/src/naming.js +74 -0
  42. package/src/pack-registry.js +59 -0
  43. package/src/packs/PROVENANCE.md +26 -0
  44. package/src/packs/commerce.d.ts +4 -0
  45. package/src/packs/commerce.js +83 -0
  46. package/src/packs/finance.d.ts +4 -0
  47. package/src/packs/finance.js +180 -0
  48. package/src/packs/geo.d.ts +4 -0
  49. package/src/packs/geo.js +227 -0
  50. package/src/packs/health.d.ts +4 -0
  51. package/src/packs/health.js +76 -0
  52. package/src/packs/index.d.ts +7 -0
  53. package/src/packs/index.js +9 -0
  54. package/src/rng.js +89 -0
  55. package/src/rules.js +228 -0
  56. package/src/scenario.js +120 -0
  57. package/src/schema.js +148 -0
  58. package/src/spec.js +235 -0
  59. package/src/suggest.js +138 -0
  60. package/src/typed.d.ts +723 -0
  61. package/src/vocab/PROVENANCE.md +12 -0
  62. package/src/vocab/en.js +106 -0
  63. package/src/world.js +461 -0
  64. package/src/xxh64.js +87 -0
package/src/typed.d.ts ADDED
@@ -0,0 +1,723 @@
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
+ type WS = " " | "\n" | "\t" | "\r" | "," | "";
14
+ 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
+ type Upper = Uppercase<Lower>;
16
+ type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
17
+ type NameChar = Lower | Upper | Digit | "_" | "-" | "+" | ".";
18
+ type Punct = "{" | "}" | "(" | ")" | "[" | "]" | ":" | "@" | "!" | "=" | "|" | "&";
19
+
20
+ type SkipWS<S extends string> = S extends `${WS}${infer R}` ? SkipWS<R> : S;
21
+ type SkipLine<S extends string> = S extends `${string}\n${infer R}` ? R : "";
22
+ 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
+ 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
+ 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
+ type IsUpper<C extends string> = C extends Uppercase<C> ? (C extends Lowercase<C> ? false : true) : false;
68
+ type IsLowerLetter<C extends string> = C extends Lower ? true : false;
69
+ type Alnum = Lower | Upper | Digit;
70
+ 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
+ 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
+ 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
+ type Vowel = "a" | "e" | "i" | "o" | "u";
96
+ 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
+ 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
+ type Last<T extends string[]> = T extends [...string[], infer L extends string] ? L : never;
116
+ type Init<T extends string[]> = T extends [...infer I extends string[], string] ? I : [];
117
+ type SingularLast<T extends string[]> = [...Init<T>, Singular<Last<T>>];
118
+ 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
+ type Reserved = "Int" | "Float" | "String" | "Boolean" | "ID" | "DateTime" | "Query" | "Mutation" | "Subscription";
120
+ 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
+ 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
+ type IrregularPlural = "people" | "children" | "men" | "women" | "mice";
127
+ type SingularPlural = "views" | "likes" | "votes" | "dislikes" | "news" | "series" | "species";
128
+ 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
+ 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
+ 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
+ type Measure = "view" | "like" | "vote" | "dislike" | "click" | "download" | "impression" | "visit" | "reaction" | "page" | "word" | "character";
150
+
151
+ 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
+ type ImageWord = "avatar" | "image" | "photo" | "thumbnail" | "picture" | "logo";
166
+ type ImageSuffix = "url" | "uri" | "link" | "src";
167
+ type UrlWord = "url" | "uri" | "link" | "website" | "homepage";
168
+ type PhoneWord = "phone" | "mobile" | "tel" | "telephone";
169
+ type BoolPrefix = "is" | "has" | "can" | "should" | "was" | "did" | "allow" | "allows" | "allowed";
170
+ type BoolSuffix = "enabled" | "active" | "verified" | "public" | "deleted" | "archived" | "flag";
171
+ type IntLast = "count" | "total" | "qty" | "quantity" | "num" | "age" | "year" | "index" | "position" | "rank" | "level" | "size" | "length" | "views" | "likes" | "votes";
172
+ 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
+ type Has<T extends string[], W extends string> = W extends T[number] ? true : false;
175
+ 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
+ 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
+ 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
+ type DeletedAt<T extends string[]> = T extends ["deleted", "at"] ? true : false;
212
+
213
+ // ---- the AST ------------------------------------------------------------------------------------
214
+
215
+ type Item = FieldNode | { k: "i"; on: string | null; sel: Item[] } | { k: "s"; n: string };
216
+ 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
+ interface ArgInfo {
235
+ n: string;
236
+ v: Record<string, unknown>;
237
+ l: boolean;
238
+ }
239
+
240
+ type Pop<D extends 0[]> = D extends [0, ...infer R extends 0[]] ? R : [];
241
+ 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
+ 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
+ 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
+ type NoArgs = { n: never; v: {}; l: false };
284
+ /** Directives after a field: `@name` and `@name(args)`. */
285
+ 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
+ type Unquote<S> = S extends `"${infer B}` ? B : never;
296
+ 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
+ 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
+ type DirNull<D> = D extends { nullRate: { p: infer V } } ? (V extends "0" | "0.0" | "0.00" ? false : true) : false;
309
+ 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
+ type DirList<D> = D extends { list: unknown } ? "list" : D extends { one: unknown } ? "one" : null;
311
+ type DirOpt<D> = D extends { skip: unknown } | { include: unknown } ? true : false;
312
+
313
+ 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
+ /** A selection set of more than 600 items is not parsed (the result falls back to `Record<string, unknown>`). */
333
+ type ParseSel<S extends string, Cur extends Item[], VL extends string> = Cur["length"] extends 600
334
+ ? { bad: true }
335
+ : Tok1<S> extends [infer H extends string, infer R extends string]
336
+ ? H extends "}"
337
+ ? { sel: Cur; rest: R }
338
+ : (H extends "..." ? ParseSpread<R, VL> : ParseField<H, R, VL>) extends [infer It extends Item, infer R2 extends string]
339
+ ? ParseSel<R2, [...Cur, It], VL>
340
+ : { bad: true }
341
+ : { bad: true };
342
+
343
+ type SkipDirs<S extends string, VL extends string> = ReadDirs<S, VL> extends [unknown, infer R extends string] ? R : S;
344
+
345
+ /** A nested selection set (the opening brace is consumed): `[sel, rest]`. */
346
+ 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 };
347
+
348
+ type ParseSpread<S extends string, VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
349
+ ? H extends "on"
350
+ ? Tok1<R> extends [infer C extends string, infer R1 extends string]
351
+ ? Tok1<SkipDirs<R1, VL>> extends ["{", infer R2 extends string]
352
+ ? Nested<R2, VL> extends [infer Sel extends Item[], infer R3 extends string]
353
+ ? [{ k: "i"; on: C; sel: Sel }, R3]
354
+ : { bad: true }
355
+ : { bad: true }
356
+ : { bad: true }
357
+ : H extends "{"
358
+ ? Nested<R, VL> extends [infer Sel extends Item[], infer R3 extends string]
359
+ ? [{ k: "i"; on: null; sel: Sel }, R3]
360
+ : { bad: true }
361
+ : H extends "@"
362
+ ? Tok1<SkipDirs<S, VL>> extends ["{", infer R2 extends string]
363
+ ? Nested<R2, VL> extends [infer Sel extends Item[], infer R3 extends string]
364
+ ? [{ k: "i"; on: null; sel: Sel }, R3]
365
+ : { bad: true }
366
+ : { bad: true }
367
+ : [{ k: "s"; n: H }, SkipDirs<R, VL>]
368
+ : { bad: true };
369
+
370
+ type ParseField<H extends string, R extends string, VL extends string> = Tok1<R> extends [":", infer R1 extends string]
371
+ ? Tok1<R1> extends [infer Real extends string, infer R2 extends string]
372
+ ? ParseField2<H, Real, R2, VL>
373
+ : { bad: true }
374
+ : ParseField2<H, H, R, VL>;
375
+
376
+ type ParseField2<Alias extends string, Name extends string, R extends string, VL extends string> = Tok1<R> extends ["(", infer R1 extends string]
377
+ ? ReadArgs<R1, [0], NoArgs, VL> extends [infer A extends ArgInfo, infer R2 extends string]
378
+ ? ParseField3<Alias, Name, A, R2, VL>
379
+ : { bad: true }
380
+ : ParseField3<Alias, Name, NoArgs, R, VL>;
381
+
382
+ 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]
383
+ ? Tok1<R2> extends ["{", infer R3 extends string]
384
+ ? Nested<R3, VL> extends [infer Sel extends Item[], infer R4 extends string]
385
+ ? [MakeField<Alias, Name, A, D, Sel>, R4]
386
+ : { bad: true }
387
+ : [MakeField<Alias, Name, A, D, null>, R2]
388
+ : { bad: true };
389
+
390
+ /** Operation header: name, variable definitions (collect the list-typed variables), directives. */
391
+ type VarDefs<S extends string, D extends 0[], VL extends string> = Tok1<S> extends [infer H extends string, infer R extends string]
392
+ ? H extends ")"
393
+ ? D extends [0]
394
+ ? [VL, R]
395
+ : VarDefs<R, Pop<D>, VL>
396
+ : H extends "(" | "{" | "["
397
+ ? VarDefs<R, [...D, 0], VL>
398
+ : H extends "}" | "]"
399
+ ? VarDefs<R, Pop<D>, VL>
400
+ : H extends `$${infer N}`
401
+ ? Tok1<R> extends [":", infer R1 extends string]
402
+ ? Tok1<R1> extends ["[", infer R2 extends string]
403
+ ? VarDefs<R2, [...D, 0], VL | N>
404
+ : VarDefs<R1, D, VL>
405
+ : VarDefs<R, D, VL>
406
+ : VarDefs<R, D, VL>
407
+ : [VL, ""];
408
+ type OpHead<S extends string, VL extends string = never> = Tok1<S> extends [infer H extends string, infer R extends string]
409
+ ? H extends "{"
410
+ ? [VL, R]
411
+ : H extends "("
412
+ ? VarDefs<R, [0], VL> extends [infer V extends string, infer R2 extends string]
413
+ ? OpHead<R2, V>
414
+ : never
415
+ : OpHead<R, VL>
416
+ : never;
417
+
418
+ interface DocT {
419
+ ops: Item[][];
420
+ frags: Record<string, { on: string; sel: Item[] }>;
421
+ ok: boolean;
422
+ }
423
+ type Failed<Ops extends Item[][], Frags> = { ops: Ops; frags: Frags; ok: false };
424
+ type Doc<S extends string, Ops extends Item[][] = [], Frags extends DocT["frags"] = {}> = Tok1<S> extends [infer H extends string, infer R extends string]
425
+ ? H extends "{"
426
+ ? ParseSel<R, [], never> extends { sel: infer Sel extends Item[]; rest: infer R2 extends string }
427
+ ? Doc<R2, [...Ops, Sel], Frags>
428
+ : Failed<Ops, Frags>
429
+ : H extends "query" | "mutation" | "subscription"
430
+ ? OpHead<R> extends [infer VL extends string, infer R2 extends string]
431
+ ? ParseSel<R2, [], VL> extends { sel: infer Sel extends Item[]; rest: infer R3 extends string }
432
+ ? Doc<R3, [...Ops, Sel], Frags>
433
+ : Failed<Ops, Frags>
434
+ : Failed<Ops, Frags>
435
+ : H extends "fragment"
436
+ ? Tok1<R> extends [infer N extends string, infer R1 extends string]
437
+ ? Tok1<R1> extends ["on", infer R2 extends string]
438
+ ? Tok1<R2> extends [infer C extends string, infer R3 extends string]
439
+ ? Tok1<SkipDirs<R3, never>> extends ["{", infer R4 extends string]
440
+ ? ParseSel<R4, [], never> extends { sel: infer Sel extends Item[]; rest: infer R5 extends string }
441
+ ? Doc<R5, Ops, Frags & { [K in N]: { on: C; sel: Sel } }>
442
+ : Failed<Ops, Frags>
443
+ : Failed<Ops, Frags>
444
+ : Failed<Ops, Frags>
445
+ : Failed<Ops, Frags>
446
+ : Failed<Ops, Frags>
447
+ : Failed<Ops, Frags>
448
+ : { ops: Ops; frags: Frags; ok: true };
449
+
450
+ // ---- evaluation ---------------------------------------------------------------------------------
451
+
452
+ type Simplify<T> = { [K in keyof T]: T[K] } & {};
453
+
454
+ /** Fields of a selection set, looking through every fragment (the `flattenFields` of src/infer.js). */
455
+ type Flatten<Sel extends Item[], Fr, Acc extends FieldNode[] = []> = Sel extends [infer I, ...infer R extends Item[]]
456
+ ? I extends FieldNode
457
+ ? Flatten<R, Fr, [...Acc, I]>
458
+ : I extends { k: "i"; sel: infer S extends Item[] }
459
+ ? Flatten<R, Fr, [...Acc, ...Flatten<S, Fr>]>
460
+ : I extends { k: "s"; n: infer N }
461
+ ? N extends keyof Fr
462
+ ? Fr[N] extends { sel: infer S extends Item[] }
463
+ ? Flatten<R, Fr, [...Acc, ...Flatten<S, Fr>]>
464
+ : Flatten<R, Fr, Acc>
465
+ : Flatten<R, Fr, Acc>
466
+ : Flatten<R, Fr, Acc>
467
+ : Acc;
468
+
469
+ /** The fields of one possible type of a union or interface (`walkAbstract` in src/infer.js). */
470
+ type FlattenFor<Sel extends Item[], Fr, T extends string, Acc extends FieldNode[] = []> = Sel extends [infer I, ...infer R extends Item[]]
471
+ ? I extends FieldNode
472
+ ? FlattenFor<R, Fr, T, [...Acc, I]>
473
+ : I extends { k: "i"; on: infer C; sel: infer S extends Item[] }
474
+ ? C extends null
475
+ ? FlattenFor<R, Fr, T, [...Acc, ...FlattenFor<S, Fr, T>]>
476
+ : C extends T
477
+ ? FlattenFor<R, Fr, T, [...Acc, ...Flatten<S, Fr>]>
478
+ : FlattenFor<R, Fr, T, Acc>
479
+ : I extends { k: "s"; n: infer N }
480
+ ? N extends keyof Fr
481
+ ? Fr[N] extends { on: infer C; sel: infer S extends Item[] }
482
+ ? C extends T
483
+ ? FlattenFor<R, Fr, T, [...Acc, ...Flatten<S, Fr>]>
484
+ : FlattenFor<R, Fr, T, Acc>
485
+ : FlattenFor<R, Fr, T, Acc>
486
+ : FlattenFor<R, Fr, T, Acc>
487
+ : FlattenFor<R, Fr, T, Acc>
488
+ : Acc;
489
+
490
+ /** Distinct type conditions applied directly to a field's selection (rules N2 and S4). */
491
+ type Explicit<Sel extends Item[], Fr, Acc extends string = never> = Sel extends [infer I, ...infer R extends Item[]]
492
+ ? I extends { k: "i"; on: infer C; sel: infer S extends Item[] }
493
+ ? C extends string
494
+ ? Explicit<R, Fr, Acc | C>
495
+ : Explicit<R, Fr, Acc | Explicit<S, Fr>>
496
+ : I extends { k: "s"; n: infer N }
497
+ ? N extends keyof Fr
498
+ ? Fr[N] extends { on: infer C extends string }
499
+ ? Explicit<R, Fr, Acc | C>
500
+ : Explicit<R, Fr, Acc>
501
+ : Explicit<R, Fr, Acc>
502
+ : Explicit<R, Fr, Acc>
503
+ : Acc;
504
+
505
+ type IsUnion<T, U = T> = [T] extends [never] ? false : T extends unknown ? ([U] extends [T] ? false : true) : never;
506
+
507
+ /** Merge fields with the same response key: their selections concatenate. */
508
+ type Dedupe<Fl extends FieldNode[]> = { [A in Fl[number]["a"]]: ByAlias<Fl, A> };
509
+ 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;
510
+ type FoldAlias<Fl extends FieldNode[], A extends string, Acc = never> = Fl extends [infer F extends FieldNode, ...infer R extends FieldNode[]]
511
+ ? F["a"] extends A
512
+ ? FoldAlias<R, A, [Acc] extends [never] ? F : MergeField<Acc, F>>
513
+ : FoldAlias<R, A, Acc>
514
+ : Acc;
515
+ 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;
516
+
517
+ type ReqKeys<D> = { [K in keyof D]: D[K] extends { op: true } ? never : K }[keyof D];
518
+ type OptKeys<D> = { [K in keyof D]: D[K] extends { op: true } ? K : never }[keyof D];
519
+
520
+ type Syn = "conn" | "edge" | "page" | null;
521
+
522
+ type ObjOf<Fl extends FieldNode[], Fr, TN extends string, S extends Syn = null, Itm extends string = ""> = Dedupe<Fl> extends infer D
523
+ ? 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> }>
524
+ : never;
525
+
526
+ type ValOf<N, Fr, TN extends string, S extends Syn, Itm extends string> = N extends FieldNode ? Val<N, Fr, TN, S, Itm> : never;
527
+
528
+ type Val<F extends FieldNode, Fr, TN extends string, S extends Syn, Itm extends string> = S extends "conn"
529
+ ? F["n"] extends "edges"
530
+ ? F["sel"] extends Item[]
531
+ ? ObjOf<Flatten<F["sel"], Fr>, Fr, `${Itm}Edge`, "edge", Itm>[]
532
+ : unknown
533
+ : F["n"] extends "nodes"
534
+ ? F["sel"] extends Item[]
535
+ ? ObjOf<Flatten<F["sel"], Fr>, Fr, Itm>[]
536
+ : unknown
537
+ : F["n"] extends "pageInfo"
538
+ ? F["sel"] extends Item[]
539
+ ? ObjOf<Flatten<F["sel"], Fr>, Fr, "PageInfo", "page">
540
+ : unknown
541
+ : F["n"] extends "totalCount"
542
+ ? number
543
+ : Plain<F, Fr, TN>
544
+ : S extends "edge"
545
+ ? F["n"] extends "cursor"
546
+ ? string
547
+ : F["n"] extends "node"
548
+ ? F["sel"] extends Item[]
549
+ ? ObjOf<Flatten<F["sel"], Fr>, Fr, Itm>
550
+ : unknown
551
+ : Plain<F, Fr, TN>
552
+ : S extends "page"
553
+ ? F["n"] extends "hasNextPage" | "hasPreviousPage"
554
+ ? boolean
555
+ : F["n"] extends "startCursor" | "endCursor"
556
+ ? string | null
557
+ : Plain<F, Fr, TN>
558
+ : Plain<F, Fr, TN>;
559
+
560
+ type Plain<F extends FieldNode, Fr, TN extends string> = F["sel"] extends infer S extends Item[] ? ObjectValue<F, S, Fr> : ScalarValue<F, TN>;
561
+
562
+ type Nullable<F extends FieldNode, T> = F["nr"] extends true ? T | null : T;
563
+
564
+ // scalars ----
565
+
566
+ type GenJs<G extends { g: string; v: string[] | null }, Dflt> = G["g"] extends "oneOf"
567
+ ? G["v"] extends string[]
568
+ ? PickJs<G["v"]>
569
+ : unknown
570
+ : G["g"] extends "pattern"
571
+ ? string
572
+ : G["g"] extends keyof GeneratorTypes
573
+ ? GeneratorTypes[G["g"]]
574
+ : G["g"] extends ""
575
+ ? Dflt
576
+ : unknown;
577
+ /** `@pick(values: [...])`: literal strings stay literal; numbers and booleans widen; anything else is unknown. */
578
+ type PickJs<V extends string[]> = "{" extends V[number]
579
+ ? unknown
580
+ : V extends []
581
+ ? never
582
+ : PickOne<V[number]>;
583
+ type PickOne<T extends string> = T extends `"${infer S}` ? S : T extends "true" | "false" ? boolean : T extends `${Digit}${string}` | `-${string}` ? number : unknown;
584
+
585
+ 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>;
586
+
587
+ type ScalarValue<F extends FieldNode, TN extends string> = F["n"] extends "__typename"
588
+ ? TN
589
+ : Words<F["n"]> extends infer T extends string[]
590
+ ? ScalarList<F, T> extends infer L
591
+ ? Nullable<F, ScalarBase<F, T, L>> extends infer V
592
+ ? L extends true
593
+ ? F["nr"] extends true
594
+ ? Exclude<V, null>[] | null
595
+ : V[]
596
+ : V
597
+ : never
598
+ : never
599
+ : never;
600
+ type ScalarBase<F extends FieldNode, T extends string[], L> = F["gn"] extends { g: string; v: string[] | null }
601
+ ? GenJs<F["gn"], ScalarJs<L extends true ? SingularLast<T> : T>>
602
+ : F["dv"] extends string
603
+ ? ScalarJs<Words<F["dv"]>>
604
+ : CountOf<T> extends true
605
+ ? number
606
+ : L extends true
607
+ ? ScalarJs<SingularLast<T>>
608
+ : DeletedAt<T> extends true
609
+ ? string | null
610
+ : ScalarJs<T>;
611
+
612
+ // objects ----
613
+
614
+ 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;
615
+
616
+ type NamesWithSel<Kids extends FieldNode[]> = Kids[number] extends infer K ? (K extends { n: infer N; sel: Item[] } ? N : never) : never;
617
+ type AllNames<Kids extends FieldNode[]> = Kids[number]["n"];
618
+
619
+ type IsConnection<Kids extends FieldNode[], Ex extends string, F extends FieldNode> = F["ty"] extends string
620
+ ? false
621
+ : [Ex] extends [never]
622
+ ? ConnShape<Kids>
623
+ : Ex extends `${string}Connection`
624
+ ? IsUnion<Ex> extends true
625
+ ? ConnShape<Kids>
626
+ : true
627
+ : ConnShape<Kids>;
628
+ type ConnShape<Kids extends FieldNode[]> = "edges" extends NamesWithSel<Kids>
629
+ ? true
630
+ : "pageInfo" extends NamesWithSel<Kids>
631
+ ? true
632
+ : "nodes" extends NamesWithSel<Kids>
633
+ ? "totalCount" extends AllNames<Kids>
634
+ ? true
635
+ : false
636
+ : false;
637
+
638
+ type ConnItem<F extends FieldNode, Ex extends string> = [Ex] extends [never]
639
+ ? ConnItemByName<F>
640
+ : IsUnion<Ex> extends true
641
+ ? ConnItemByName<F>
642
+ : Ex extends `${infer I}Connection`
643
+ ? I extends ""
644
+ ? "Node"
645
+ : I
646
+ : ConnItemByName<F>;
647
+ type ConnItemByName<F extends FieldNode> = Words<F["n"]> extends infer T extends string[]
648
+ ? Last<T> extends "connection"
649
+ ? TypeNameOf<Init<T> extends [] ? F["n"] : Join<Init<T>>>
650
+ : TypeNameOf<F["n"]>
651
+ : never;
652
+ 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;
653
+
654
+ type ObjectValue<F extends FieldNode, Sel extends Item[], Fr> = Explicit<Sel, Fr> extends infer E0 extends string
655
+ ? (F["ty"] extends string ? F["ty"] : E0) extends infer Ex extends string
656
+ ? Flatten<Sel, Fr> extends infer Kids extends FieldNode[]
657
+ ? IsUnion<Ex> extends true
658
+ ? ListWrap<F, ObjList<F>, UnionObj<Sel, Fr, Ex>>
659
+ : IsConnection<Kids, Ex, F> extends true
660
+ ? ListWrap<F, false, ObjOf<Kids, Fr, ConnTN<F, Ex>, "conn", ConnItem<F, Ex>>>
661
+ : ListWrap<F, ObjList<F>, ObjOf<Kids, Fr, TypeNameFor<F, Ex>>>
662
+ : never
663
+ : never
664
+ : never;
665
+ type ConnTN<F extends FieldNode, Ex extends string> = `${ConnItem<F, Ex>}Connection`;
666
+ type UnionObj<Sel extends Item[], Fr, Ex extends string> = Ex extends string ? ObjOf<FlattenFor<Sel, Fr, Ex>, Fr, Ex> : never;
667
+
668
+ /** Object fields: the list rule without argument-literal lists for unions (src/infer.js finalize). */
669
+ 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;
670
+ type ListWrap<F extends FieldNode, L, V> = L extends true ? Nullable<F, V[]> : Nullable<F, V>;
671
+
672
+ // ---- public --------------------------------------------------------------------------------------
673
+
674
+ type AnyData = Record<string, unknown>;
675
+ type Eval<D> = D extends { ok: true; ops: [infer S extends Item[]]; frags: infer Fr }
676
+ ? ObjOf<Flatten<S, Fr>, Fr, "Query">
677
+ : AnyData;
678
+ type ParseAll<Q extends string> = Doc<Q>;
679
+
680
+ /**
681
+ * The data a query returns, inferred from the query text. A query that is not a literal type
682
+ * (a `string` variable), has several operations or cannot be parsed gives `Record<string, unknown>`.
683
+ */
684
+ export type ResultOf<Q> = Q extends string ? (string extends Q ? AnyData : Eval<ParseAll<Q>>) : AnyData;
685
+
686
+ type ItemOfValue<V> = NonNullable<V> extends infer N
687
+ ? N extends readonly (infer E)[]
688
+ ? E
689
+ : N extends { nodes: readonly (infer E)[] }
690
+ ? E
691
+ : N extends { edges: readonly { node: infer E }[] }
692
+ ? E
693
+ : unknown
694
+ : never;
695
+
696
+ type RootFields<Q extends string> = Doc<Q> extends { ok: true; ops: [infer S extends Item[]]; frags: infer Fr } ? [Flatten<S, Fr>, Fr] : never;
697
+ type FirstCollection<Fl extends FieldNode[], Fr> = Fl extends [infer F extends FieldNode, ...infer R extends FieldNode[]]
698
+ ? F["sel"] extends Item[]
699
+ ? Val<F, Fr, "Query", null, ""> extends infer V
700
+ ? NonNullable<V> extends readonly unknown[] | { edges: unknown } | { nodes: unknown }
701
+ ? F
702
+ : FirstCollection<R, Fr>
703
+ : never
704
+ : FirstCollection<R, Fr>
705
+ : never;
706
+
707
+ /**
708
+ * The type of one item of the root collection `stream()` yields: the elements of the first root list,
709
+ * the nodes of a root connection, or the root field named by `Field` (a response key).
710
+ */
711
+ export type ItemOf<Q, Field extends string | undefined = undefined> = Q extends string
712
+ ? string extends Q
713
+ ? Record<string, any>
714
+ : RootFields<Q> extends [infer Fl extends FieldNode[], infer Fr]
715
+ ? (Field extends string ? Extract<Fl[number], { a: Field }> : FirstCollection<Fl, Fr>) extends infer F
716
+ ? [F] extends [never]
717
+ ? Record<string, any>
718
+ : F extends FieldNode
719
+ ? ItemOfValue<Val<F, Fr, "Query", null, "">>
720
+ : never
721
+ : never
722
+ : Record<string, any>
723
+ : Record<string, any>;