@distilled.cloud/core 1.0.0-rc.11 → 1.0.0-rc.13

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 (149) hide show
  1. package/lib/api.d.ts +4 -4
  2. package/lib/api.d.ts.map +1 -1
  3. package/lib/api.js +1 -1
  4. package/lib/api.js.map +1 -1
  5. package/lib/category.js +1 -1
  6. package/lib/category.js.map +1 -1
  7. package/lib/codegen/boolean-string-enums.d.ts +8 -8
  8. package/lib/codegen/boolean-string-enums.d.ts.map +1 -1
  9. package/lib/codegen/boolean-string-enums.js +84 -27
  10. package/lib/codegen/boolean-string-enums.js.map +1 -1
  11. package/lib/codegen/boolean-string-enums.test.js +130 -0
  12. package/lib/codegen/boolean-string-enums.test.js.map +1 -1
  13. package/lib/codegen/cli.js +2 -2
  14. package/lib/codegen/cli.js.map +1 -1
  15. package/lib/codegen/generator.d.ts +20 -3
  16. package/lib/codegen/generator.d.ts.map +1 -1
  17. package/lib/codegen/generator.js +36 -9
  18. package/lib/codegen/generator.js.map +1 -1
  19. package/lib/codegen/generator.test.d.ts +2 -0
  20. package/lib/codegen/generator.test.d.ts.map +1 -0
  21. package/lib/codegen/generator.test.js +126 -0
  22. package/lib/codegen/generator.test.js.map +1 -0
  23. package/lib/codegen/graphql-client.d.ts +7 -1
  24. package/lib/codegen/graphql-client.d.ts.map +1 -1
  25. package/lib/codegen/graphql-client.js +262 -125
  26. package/lib/codegen/graphql-client.js.map +1 -1
  27. package/lib/codegen/graphql-client.test.js +104 -236
  28. package/lib/codegen/graphql-client.test.js.map +1 -1
  29. package/lib/codegen/openapi-binary.test.d.ts +2 -0
  30. package/lib/codegen/openapi-binary.test.d.ts.map +1 -0
  31. package/lib/codegen/openapi-binary.test.js +67 -0
  32. package/lib/codegen/openapi-binary.test.js.map +1 -0
  33. package/lib/codegen/openapi.d.ts +7 -1
  34. package/lib/codegen/openapi.d.ts.map +1 -1
  35. package/lib/codegen/openapi.js +15 -4
  36. package/lib/codegen/openapi.js.map +1 -1
  37. package/lib/codegen/patches.d.ts +16 -1
  38. package/lib/codegen/patches.d.ts.map +1 -1
  39. package/lib/codegen/patches.js +70 -4
  40. package/lib/codegen/patches.js.map +1 -1
  41. package/lib/codegen/patches.test.js +48 -2
  42. package/lib/codegen/patches.test.js.map +1 -1
  43. package/lib/codegen/untagged-unions.test.d.ts +2 -0
  44. package/lib/codegen/untagged-unions.test.d.ts.map +1 -0
  45. package/lib/codegen/untagged-unions.test.js +80 -0
  46. package/lib/codegen/untagged-unions.test.js.map +1 -0
  47. package/lib/errors.d.ts +2 -1
  48. package/lib/errors.d.ts.map +1 -1
  49. package/lib/errors.js +5 -2
  50. package/lib/errors.js.map +1 -1
  51. package/lib/fixtures/xml/upstream-validator.json +397 -0
  52. package/lib/graphql.d.ts +296 -205
  53. package/lib/graphql.d.ts.map +1 -1
  54. package/lib/graphql.js +968 -631
  55. package/lib/graphql.js.map +1 -1
  56. package/lib/graphql.test.js +134 -763
  57. package/lib/graphql.test.js.map +1 -1
  58. package/lib/graphql.types.d.ts +10 -0
  59. package/lib/graphql.types.d.ts.map +1 -1
  60. package/lib/graphql.types.js +4 -44
  61. package/lib/graphql.types.js.map +1 -1
  62. package/lib/index.d.ts +27 -0
  63. package/lib/index.d.ts.map +1 -0
  64. package/lib/index.js +27 -0
  65. package/lib/index.js.map +1 -0
  66. package/lib/pagination.d.ts +2 -1
  67. package/lib/pagination.d.ts.map +1 -1
  68. package/lib/pagination.js +24 -16
  69. package/lib/pagination.js.map +1 -1
  70. package/lib/pagination.test.d.ts +2 -0
  71. package/lib/pagination.test.d.ts.map +1 -0
  72. package/lib/pagination.test.js +134 -0
  73. package/lib/pagination.test.js.map +1 -0
  74. package/lib/protocol-http.d.ts +12 -17
  75. package/lib/protocol-http.d.ts.map +1 -1
  76. package/lib/protocol-http.js +100 -45
  77. package/lib/protocol-http.js.map +1 -1
  78. package/lib/protocol-http.test.js +130 -0
  79. package/lib/protocol-http.test.js.map +1 -1
  80. package/lib/protocol-rest.d.ts +18 -1
  81. package/lib/protocol-rest.d.ts.map +1 -1
  82. package/lib/protocol-rest.js +24 -4
  83. package/lib/protocol-rest.js.map +1 -1
  84. package/lib/query.d.ts +29 -0
  85. package/lib/query.d.ts.map +1 -0
  86. package/lib/query.js +27 -0
  87. package/lib/query.js.map +1 -0
  88. package/lib/response-validation.d.ts +67 -0
  89. package/lib/response-validation.d.ts.map +1 -0
  90. package/lib/response-validation.js +76 -0
  91. package/lib/response-validation.js.map +1 -0
  92. package/lib/response-validation.test.d.ts +2 -0
  93. package/lib/response-validation.test.d.ts.map +1 -0
  94. package/lib/response-validation.test.js +67 -0
  95. package/lib/response-validation.test.js.map +1 -0
  96. package/lib/testing.d.ts +39 -0
  97. package/lib/testing.d.ts.map +1 -0
  98. package/lib/testing.js +41 -0
  99. package/lib/testing.js.map +1 -0
  100. package/lib/trait.d.ts +29 -9
  101. package/lib/trait.d.ts.map +1 -1
  102. package/lib/trait.js +8 -0
  103. package/lib/trait.js.map +1 -1
  104. package/lib/xml.d.ts +44 -0
  105. package/lib/xml.d.ts.map +1 -0
  106. package/lib/xml.js +315 -0
  107. package/lib/xml.js.map +1 -0
  108. package/lib/xml.test.d.ts +2 -0
  109. package/lib/xml.test.d.ts.map +1 -0
  110. package/lib/xml.test.js +211 -0
  111. package/lib/xml.test.js.map +1 -0
  112. package/package.json +4 -4
  113. package/src/api.ts +4 -4
  114. package/src/category.ts +1 -1
  115. package/src/codegen/boolean-string-enums.test.ts +147 -0
  116. package/src/codegen/boolean-string-enums.ts +84 -27
  117. package/src/codegen/cli.ts +2 -2
  118. package/src/codegen/generator.test.ts +151 -0
  119. package/src/codegen/generator.ts +70 -12
  120. package/src/codegen/graphql-client.test.ts +116 -283
  121. package/src/codegen/graphql-client.ts +326 -169
  122. package/src/codegen/openapi-binary.test.ts +98 -0
  123. package/src/codegen/openapi.ts +26 -4
  124. package/src/codegen/patches.test.ts +66 -1
  125. package/src/codegen/patches.ts +84 -4
  126. package/src/codegen/untagged-unions.test.ts +89 -0
  127. package/src/errors.ts +5 -2
  128. package/src/fixtures/xml/upstream-validator.json +397 -0
  129. package/src/graphql.test.ts +174 -948
  130. package/src/graphql.ts +1592 -1167
  131. package/src/graphql.types.ts +92 -163
  132. package/src/index.ts +26 -0
  133. package/src/pagination.test.ts +191 -0
  134. package/src/pagination.ts +35 -25
  135. package/src/protocol-http.test.ts +163 -0
  136. package/src/protocol-http.ts +122 -46
  137. package/src/protocol-rest.ts +62 -13
  138. package/src/query.ts +39 -0
  139. package/src/response-validation.test.ts +95 -0
  140. package/src/response-validation.ts +116 -0
  141. package/src/testing.ts +78 -0
  142. package/src/trait.ts +39 -8
  143. package/src/xml.test.ts +269 -0
  144. package/src/xml.ts +339 -0
  145. package/lib/graphql.fixture.d.ts +0 -249
  146. package/lib/graphql.fixture.d.ts.map +0 -1
  147. package/lib/graphql.fixture.js +0 -240
  148. package/lib/graphql.fixture.js.map +0 -1
  149. package/src/graphql.fixture.ts +0 -371
package/lib/graphql.d.ts CHANGED
@@ -1,121 +1,68 @@
1
+ /**
2
+ * GraphQL Query algebra — the runtime generated GraphQL SDKs target.
3
+ *
4
+ * ── Why this exists ────────────────────────────────────────────────────────
5
+ * A GraphQL document is a *selection*, not an RPC. Distilled used to bake a
6
+ * max-depth selection into every operation (`Railway.me({})` downloaded the
7
+ * world). This module instead treats every field as a lazy `Query<Value>`:
8
+ * reading `user.email` records that field, and nothing is posted until
9
+ * `Query.fn` evaluates the plan you returned.
10
+ *
11
+ * ── The two phases ─────────────────────────────────────────────────────────
12
+ * 1. Build (your function). `Railway.me()` / `user.email` / `Query.map` do
13
+ * not talk to the network. They construct an expression tree:
14
+ * Of | Map | Filter | FlatMap | Prop | Root
15
+ * The inner function of `Query.fn` is therefore a *builder*, not an
16
+ * Effect generator. No `yield*` inside it.
17
+ *
18
+ * 2. Evaluate (`Query.fn`). Walk the returned plan, paint every GraphQL
19
+ * field that appears onto one selection forest, POST that document
20
+ * once through {@link GqlTransport}, then interpret Map/Filter/FlatMap
21
+ * against the JSON. Effects reached via FlatMap (e.g.
22
+ * `usernameIsAvailable(name)`) run *after* the POST, with real values.
23
+ *
24
+ * ── Combinators ────────────────────────────────────────────────────────────
25
+ * - `Query.of(x)` — a literal; never selected.
26
+ * - `Query.map` on a list — callback receives `Query<Item>` so `p.name` is
27
+ * still a Query (selected). On a scalar, callback receives the value
28
+ * after extract (`stars => stars > 5`). Relay connections (`edges { node }`)
29
+ * are lists of the node type, so `projects({ first: 20 }).pipe(Query.map)`
30
+ * maps projects, not edges.
31
+ * - `Query.filter` — predicate is `Query<Item> => Query<boolean>`; the
32
+ * boolean Query is walked for fields, then run per row after the POST.
33
+ * - `Query.flatMap` — after extract, run `(value) => Effect | Query`.
34
+ * - `Query.pages` / `Query.items` — a Stream over every page / node of a
35
+ * Relay connection, one POST per page (see "Pagination").
36
+ *
37
+ * ── Types ──────────────────────────────────────────────────────────────────
38
+ * `Query<Value>` is `QueryNode<Value>` plus the GraphQL fields of `Value`,
39
+ * so `user.name` type-checks. That copy is a circular type alias
40
+ * (`Query<User>` contains `Query<Project[]>` which contains `Query<User>`
41
+ * again). TypeScript leaves the cycle lazy; there is no depth cap.
42
+ *
43
+ * ── Transport ──────────────────────────────────────────────────────────────
44
+ * {@link GqlTransport.execute} posts `{ query, variables, operationName }`.
45
+ * The Effect it returns may require Credentials / HttpClient; those leak
46
+ * into `Query.fn`'s requirements. It returns the parsed `data` and raw
47
+ * `errors`; `Query.fn` classifies the errors (see "Errors" below). Compile
48
+ * failures are {@link GqlError} defects.
49
+ *
50
+ * Generated SDKs export *roots* (`Railway.me`, `Railway.project`).
51
+ * Combinators live in `@distilled.cloud/core/query`.
52
+ */
53
+ import * as Context from "effect/Context";
1
54
  import * as Effect from "effect/Effect";
2
55
  import * as S from "effect/Schema";
3
56
  import * as Stream from "effect/Stream";
4
- import type { GraphQLModel } from "./codegen/graphql-client.ts";
5
- export type { GraphQLModel } from "./codegen/graphql-client.ts";
6
- /** A generated field's arguments, GraphQL output reference, and error tags. */
7
- export interface Field<Args, Ref extends string, E extends string = never> {
8
- readonly args: Args;
9
- readonly type: Ref;
10
- readonly errors: E;
11
- }
12
- export interface Schema {
13
- types: Record<string, Record<string, Field<any, string, string>>>;
14
- scalars: Record<string, unknown>;
15
- errors: Record<string, GraphQLIssue>;
16
- possibleTypes: Record<string, string>;
17
- query: string;
18
- mutation: string;
19
- subscription: string;
20
- globalErrors: string;
57
+ export declare const QuerySymbol: unique symbol;
58
+ declare const inspect: unique symbol;
59
+ /** A plan that cannot be compiled (a programming error, raised as a defect). */
60
+ export declare class GqlError {
61
+ readonly message: string;
62
+ readonly _tag: "GqlError";
63
+ constructor(message: string);
21
64
  }
22
- type Named<T extends string> = T extends `${infer R}!` ? Named<R> : T extends `[${infer R}]` ? Named<R> : T;
23
- type Fields<C extends Schema, N extends string> = N extends keyof C["types"] ? C["types"][N] : {};
24
- type TypeOf<F> = F extends Field<any, infer T, any> ? T : never;
25
- type ArgsOf<F> = F extends Field<infer A, any, any> ? A : never;
26
- type TagsOf<F> = F extends Field<any, any, infer E> ? E : never;
27
- type Where<A> = {} extends A ? {
28
- readonly where?: A;
29
- } : {
30
- readonly where: A;
31
- };
32
- type Directives = {
33
- readonly $include?: boolean;
34
- readonly $skip?: boolean;
35
- };
36
- type FieldSelection<C extends Schema, F> = Named<TypeOf<F>> extends keyof C["scalars"] ? ({} extends ArgsOf<F> ? boolean : never) | (Where<ArgsOf<F>> & Directives & {
37
- readonly select?: true;
38
- }) : (keyof ArgsOf<F> extends never ? Selection<C, Named<TypeOf<F>>> : never) | (Where<ArgsOf<F>> & Directives & {
39
- readonly select: Selection<C, Named<TypeOf<F>>>;
40
- });
41
- type Alias<C extends Schema, N extends string> = {
42
- [K in keyof Fields<C, N>]: {
43
- readonly [P in K]: FieldSelection<C, Fields<C, N>[K]>;
44
- };
45
- }[keyof Fields<C, N>];
46
- /** Mobius-style field selection. Arguments are passed in `where`. */
47
- export type Selection<C extends Schema, N extends string> = {
48
- readonly [K in keyof Fields<C, N>]?: FieldSelection<C, Fields<C, N>[K]>;
49
- } & {
50
- readonly __typename?: boolean;
51
- readonly __alias?: Readonly<Record<string, Alias<C, N>>>;
52
- readonly __on?: N extends keyof C["possibleTypes"] ? {
53
- readonly [K in C["possibleTypes"][N]]?: Selection<C, K>;
54
- } : never;
55
- };
56
- type Selected<Q> = Q extends {
57
- readonly select: infer P;
58
- } ? P : Q;
59
- type Keys<Q> = {
60
- [K in keyof Q]: Q[K] extends false | undefined ? never : K;
61
- }[keyof Q];
62
- type Simplify<A> = {
63
- [K in keyof A]: A[K];
64
- };
65
- type AliasValue<C extends Schema, N extends string, Q> = {
66
- [K in Extract<Keys<Q>, keyof Fields<C, N>>]: Result<C, TypeOf<Fields<C, N>[K]>, Selected<Q[K]>>;
67
- }[Extract<Keys<Q>, keyof Fields<C, N>>];
68
- type AliasResult<C extends Schema, N extends string, Q> = Q extends {
69
- readonly __alias: infer A;
70
- } ? Simplify<{
71
- [K in keyof A as Conditional<A[K][keyof A[K]]> extends true ? never : K]: AliasValue<C, N, A[K]>;
72
- } & {
73
- [K in keyof A as Conditional<A[K][keyof A[K]]> extends true ? K : never]?: AliasValue<C, N, A[K]>;
74
- }> : {};
75
- type Conditional<Q> = boolean extends Q ? true : Q extends {
76
- readonly $include: infer I;
77
- } ? [I] extends [true] ? Q extends {
78
- readonly $skip: infer S;
79
- } ? [S] extends [false] ? false : true : false : true : Q extends {
80
- readonly $skip: infer S;
81
- } ? [S] extends [false] ? false : true : false;
82
- type ObjectFields<C extends Schema, N extends string, Q> = {
83
- [K in Extract<Keys<Q>, keyof Fields<C, N>> as Conditional<Q[K]> extends true ? never : K]: Result<C, TypeOf<Fields<C, N>[K]>, Selected<Q[K]>>;
84
- } & {
85
- [K in Extract<Keys<Q>, keyof Fields<C, N>> as Conditional<Q[K]> extends true ? K : never]?: Result<C, TypeOf<Fields<C, N>[K]>, Selected<Q[K]>>;
86
- };
87
- type ObjectResult<C extends Schema, N extends string, Q> = Simplify<ObjectFields<C, N, Q> & (Q extends {
88
- readonly __typename: true;
89
- } ? {
90
- __typename: N;
91
- } : {}) & AliasResult<C, N, Q>>;
92
- type Branch<C extends Schema, N extends string, Q, T extends string> = T extends unknown ? Simplify<Omit<ObjectResult<C, N, Q>, "__typename"> & (Q extends {
93
- readonly __on: infer O;
94
- } ? T extends keyof O ? ObjectResult<C, T, O[T]> : {} : {}) & {
95
- __typename: T;
96
- }> : never;
97
- type Value<C extends Schema, T extends string, Q> = T extends `[${infer I}]` ? Array<Result<C, I, Q>> : T extends keyof C["scalars"] ? C["scalars"][T] : T extends keyof C["possibleTypes"] ? Branch<C, T, Q, C["possibleTypes"][T]> : ObjectResult<C, T, Q>;
98
- /** Selected output, preserving list and nullable wrappers. */
99
- export type Result<C extends Schema, Ref extends string, Q> = Ref extends `${infer T}!` ? Value<C, T, Q> : Value<C, Ref, Q> | null;
100
- type SelectionTags<C extends Schema, N extends string, Q> = string extends N ? string : Q extends object ? {
101
- [K in Extract<Keys<Q>, keyof Fields<C, N>>]: TagsOf<Fields<C, N>[K]> | SelectionTags<C, Named<TypeOf<Fields<C, N>[K]>>, Selected<Q[K]>>;
102
- }[Extract<Keys<Q>, keyof Fields<C, N>>] | (Q extends {
103
- readonly __on: infer O;
104
- } ? {
105
- [K in keyof O & string]: SelectionTags<C, K, O[K]>;
106
- }[keyof O & string] : never) | (Q extends {
107
- readonly __alias: infer A;
108
- } ? {
109
- [K in keyof A]: SelectionTags<C, N, A[K]>;
110
- }[keyof A] : never) : never;
111
- /** Known selected errors plus provider-wide errors and an honest fallback. */
112
- export type Errors<C extends Schema, N extends string, Q> = (SelectionTags<C, N, Q> extends infer Tags ? C["errors"][Extract<C["globalErrors"] | Tags, keyof C["errors"]>] : never) | UnknownGraphQLError;
113
- type Root<C extends Schema, K extends OperationKind> = K extends "query" ? C["query"] : C["mutation"];
114
- type OperationSelection<C extends Schema, N extends string, K extends keyof Fields<C, N>, Q> = {
115
- [P in K]: {
116
- select: Q;
117
- };
118
- };
65
+ /** Fields every classified GraphQL error carries. */
119
66
  export declare const errorFields: {
120
67
  message: S.String;
121
68
  code: S.optional<S.String>;
@@ -127,8 +74,10 @@ export declare const errorFields: {
127
74
  extensions: S.optional<S.Unknown>;
128
75
  traceId: S.optional<S.String>;
129
76
  status: S.optional<S.Number>;
77
+ /** Server retry hint in seconds. */
130
78
  retryAfter: S.optional<S.Number>;
131
79
  };
80
+ /** The shape shared by every classified GraphQL error. */
132
81
  export interface GraphQLIssue {
133
82
  readonly _tag: string;
134
83
  readonly message: string;
@@ -141,9 +90,9 @@ export interface GraphQLIssue {
141
90
  readonly extensions?: unknown;
142
91
  readonly traceId?: string;
143
92
  readonly status?: number;
144
- /** Server retry hint in seconds. */
145
93
  readonly retryAfter?: number;
146
94
  }
95
+ export type GraphQLIssueProps = Omit<GraphQLIssue, "_tag">;
147
96
  declare const UnknownGraphQLError_base: S.Class<UnknownGraphQLError, S.TaggedStruct<"UnknownGraphQLError", {
148
97
  readonly message: S.String;
149
98
  readonly code: S.optional<S.String>;
@@ -156,129 +105,271 @@ declare const UnknownGraphQLError_base: S.Class<UnknownGraphQLError, S.TaggedStr
156
105
  readonly traceId: S.optional<S.String>;
157
106
  readonly status: S.optional<S.Number>;
158
107
  readonly retryAfter: S.optional<S.Number>;
108
+ /** Root field the error path points at, when the path is known. */
159
109
  readonly coordinate: S.optional<S.String>;
160
110
  }>, import("effect/Cause").YieldableError>;
111
+ /** A GraphQL error no declared matcher recognizes. */
161
112
  export declare class UnknownGraphQLError extends UnknownGraphQLError_base {
162
113
  }
163
114
  declare const GraphQLFailure_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
164
115
  readonly _tag: "GraphQLFailure";
165
116
  } & Readonly<A>;
166
- /** All errors from one GraphQL execution, with the original partial response. */
117
+ /** One response carried errors with different tags; none is hidden. */
167
118
  export declare class GraphQLFailure<E extends GraphQLIssue = GraphQLIssue> extends GraphQLFailure_base<{
168
119
  readonly errors: readonly [E, ...E[]];
169
120
  readonly data: unknown;
170
- readonly status: number;
121
+ readonly status?: number;
171
122
  }> {
172
123
  get message(): string;
173
124
  }
174
125
  declare const GraphQLTransportError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
175
126
  readonly _tag: "GraphQLTransportError";
176
127
  } & Readonly<A>;
128
+ /** The request never produced a GraphQL response (network, HTTP, non-JSON). */
177
129
  export declare class GraphQLTransportError extends GraphQLTransportError_base<{
178
130
  readonly message: string;
179
- readonly cause?: unknown;
180
131
  readonly status?: number;
132
+ /** Server retry hint in seconds. */
181
133
  readonly retryAfter?: number;
182
- }> {
183
- }
184
- declare const GraphQLDecodeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
185
- readonly _tag: "GraphQLDecodeError";
186
- } & Readonly<A>;
187
- export declare class GraphQLDecodeError extends GraphQLDecodeError_base<{
188
- readonly message: string;
189
- readonly path?: ReadonlyArray<string | number>;
190
134
  readonly cause?: unknown;
191
135
  }> {
192
136
  }
193
- declare const GraphQLRequestError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
194
- readonly _tag: "GraphQLRequestError";
137
+ declare const GraphQLPaginationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
138
+ readonly _tag: "GraphQLPaginationError";
195
139
  } & Readonly<A>;
196
- export declare class GraphQLRequestError extends GraphQLRequestError_base<{
140
+ /** A paginated connection reported more pages without a new cursor. */
141
+ export declare class GraphQLPaginationError extends GraphQLPaginationError_base<{
197
142
  readonly message: string;
143
+ readonly cursor: string | null;
198
144
  }> {
199
145
  }
200
- export type ClientError = GraphQLTransportError | GraphQLDecodeError | GraphQLRequestError;
201
- /** True only when every issue has an allowed tag; mixed failures are never hidden. */
202
- export declare const isErrorTag: (error: unknown, tags: string | readonly string[]) => boolean;
203
- /** Recover only an aggregate whose every issue matches. The original aggregate is also supplied. */
204
- export declare const catchTags: <const T extends readonly string[] | string, B, E2, R2>(tags: T, handler: (error: GraphQLIssue & {
205
- readonly _tag: T extends string ? T : T[number];
206
- }, failure: GraphQLFailure) => Effect.Effect<B, E2, R2>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | B, E | E2, R | R2>;
207
- export type OperationKind = "query" | "mutation";
208
- export interface GraphQLRequest {
209
- readonly query: string;
210
- readonly variables: Record<string, unknown>;
211
- readonly operationName: string;
212
- readonly kind: OperationKind;
146
+ /** Recognizes a raw GraphQL error. Every present property must match. */
147
+ export interface ErrorMatcher {
148
+ readonly code?: string;
149
+ readonly message?: string;
150
+ readonly messageIncludes?: string;
213
151
  }
214
- export interface GraphQLResponse {
215
- readonly body: unknown;
216
- readonly status: number;
217
- readonly headers: Readonly<Record<string, string | undefined>>;
152
+ /** Runtime description of one generated error class. */
153
+ export interface ErrorSpec<E extends GraphQLIssue = GraphQLIssue> {
154
+ readonly tag: E["_tag"];
155
+ readonly make: (props: GraphQLIssueProps) => E;
156
+ readonly matchers: ReadonlyArray<ErrorMatcher>;
157
+ /** Queries failing only with retryable errors are retried. */
158
+ readonly retryable: boolean;
159
+ /** Applies to every root, including errors that carry no path. */
160
+ readonly global: boolean;
218
161
  }
219
- export type Transport<R> = (request: GraphQLRequest) => Effect.Effect<GraphQLResponse, GraphQLTransportError | GraphQLDecodeError, R>;
220
- interface Position {
221
- readonly field: string;
222
- readonly key: string;
223
- readonly coordinate: string;
224
- readonly type: string;
225
- readonly errors: readonly string[];
226
- readonly children: readonly Position[];
227
- readonly branches: Readonly<Record<string, readonly Position[]>>;
228
- readonly typename?: boolean;
229
- readonly conditional: boolean;
230
- }
231
- export interface CompiledQuery extends GraphQLRequest {
232
- readonly rootType: string;
233
- readonly positions: readonly Position[];
162
+ export declare const errorSpec: <E extends GraphQLIssue>(make: new (props: GraphQLIssueProps) => E, tag: E["_tag"], matchers: ReadonlyArray<ErrorMatcher>, options?: {
163
+ readonly retryable?: boolean;
164
+ readonly global?: boolean;
165
+ }) => ErrorSpec<E>;
166
+ /** An entry of a GraphQL response's `errors` array, as sent on the wire. */
167
+ export interface RawGraphQLError {
168
+ readonly message: string;
169
+ readonly path?: ReadonlyArray<string | number>;
170
+ readonly locations?: ReadonlyArray<{
171
+ readonly line: number;
172
+ readonly column: number;
173
+ }>;
174
+ readonly extensions?: Record<string, unknown>;
175
+ readonly [key: string]: unknown;
234
176
  }
235
- /** Compile one selection to a GraphQL AST, variables, and an error/decoder path map. */
236
- export declare const compile: (model: GraphQLModel, kind: OperationKind, selection: unknown, operationName?: string) => CompiledQuery;
237
- type ErrorConstructor = new (args: any) => GraphQLIssue;
238
- export interface Report<A, E extends GraphQLIssue> {
239
- readonly data: A | null | undefined;
240
- readonly errors: ReadonlyArray<E>;
241
- readonly status: number;
242
- readonly extensions?: unknown;
177
+ /** What a transport returns once it has a GraphQL response body. */
178
+ export interface GraphQLResponse {
179
+ readonly data?: unknown;
180
+ readonly errors?: ReadonlyArray<RawGraphQLError>;
181
+ readonly status?: number;
182
+ readonly headers?: Readonly<Record<string, string | undefined>>;
243
183
  }
244
- type Failure<C extends Schema, N extends string, Q> = ClientError | GraphQLFailure<Errors<C, N, Q>>;
245
- type FieldAt<C extends Schema, N extends string, K extends string> = K extends keyof Fields<C, N> ? Fields<C, N>[K] : never;
246
- type ConnectionEdge<C extends Schema, Ref extends string> = Named<TypeOf<FieldAt<C, Named<Ref>, "edges">>>;
247
- type ConnectionNode<C extends Schema, Ref extends string> = TypeOf<FieldAt<C, ConnectionEdge<C, Ref>, "node">>;
248
- export interface ObjectOperation<C extends Schema, K extends OperationKind, N extends keyof Fields<C, Root<C, K>> & string, R> {
249
- <const Q extends Selection<C, Named<TypeOf<Fields<C, Root<C, K>>[N]>>>>(args: ArgsOf<Fields<C, Root<C, K>>[N]>, select: Q): Effect.Effect<Result<C, TypeOf<Fields<C, Root<C, K>>[N]>, Q>, Failure<C, Root<C, K>, OperationSelection<C, Root<C, K>, N, Q>>, R>;
184
+ export type ArgMeta = Record<string, string>;
185
+ export type FieldMeta = {
186
+ readonly name: string;
187
+ readonly kind: "scalar" | "object" | "list" | "connection";
188
+ readonly of?: TypeMeta;
189
+ readonly argTypes?: ArgMeta;
190
+ };
191
+ export type TypeMeta = {
192
+ readonly name: string;
193
+ readonly fields: Record<string, FieldMeta>;
194
+ };
195
+ export declare const scalarField: (name: string) => FieldMeta;
196
+ export declare const objectField: (name: string, objectType: TypeMeta) => FieldMeta;
197
+ export declare const listField: (name: string, itemType: TypeMeta, argTypes?: ArgMeta) => FieldMeta;
198
+ /** Relay connection: GraphQL `edges { node }` presented as `Query<Item[]>`. */
199
+ export declare const connectionField: (name: string, nodeType: TypeMeta, argTypes?: ArgMeta) => FieldMeta;
200
+ export type TypeRef = {
201
+ readonly tag: "scalar";
202
+ } | {
203
+ readonly tag: "object";
204
+ readonly meta: TypeMeta;
205
+ } | {
206
+ readonly tag: "list";
207
+ readonly of: TypeRef;
208
+ };
209
+ export interface SelNode {
210
+ field: string;
211
+ alias: string | undefined;
212
+ args: Record<string, string> | undefined;
213
+ children: Map<string, SelNode>;
214
+ isScalar: boolean;
215
+ isList: boolean;
250
216
  }
251
- export interface ScalarOperation<C extends Schema, K extends OperationKind, N extends keyof Fields<C, Root<C, K>> & string, R> {
252
- (args: ArgsOf<Fields<C, Root<C, K>>[N]>): Effect.Effect<Result<C, TypeOf<Fields<C, Root<C, K>>[N]>, true>, Failure<C, Root<C, K>, OperationSelection<C, Root<C, K>, N, true>>, R>;
217
+ export interface CompiledOperation {
218
+ readonly document: string;
219
+ readonly operationName: string;
220
+ readonly variables: Record<string, unknown>;
221
+ readonly kind: "query" | "mutation";
222
+ readonly tree: SelNode;
253
223
  }
254
- export interface Pagination<C extends Schema, K extends OperationKind, N extends keyof Fields<C, Root<C, K>> & string, R> {
255
- pages<const Q extends Selection<C, Named<TypeOf<Fields<C, Root<C, K>>[N]>>>>(args: ArgsOf<Fields<C, Root<C, K>>[N]>, select: Q): Stream.Stream<Result<C, TypeOf<Fields<C, Root<C, K>>[N]>, Q>, ClientError | GraphQLFailure<Errors<C, Root<C, K>, OperationSelection<C, Root<C, K>, N, Q>> | Errors<C, Named<TypeOf<Fields<C, Root<C, K>>[N]>>, {
256
- pageInfo: {
257
- endCursor: true;
258
- hasNextPage: true;
259
- };
260
- }>>, R>;
261
- items<const Q extends Selection<C, Named<ConnectionNode<C, TypeOf<Fields<C, Root<C, K>>[N]>>>>>(args: ArgsOf<Fields<C, Root<C, K>>[N]>, select: Q): Stream.Stream<Result<C, ConnectionNode<C, TypeOf<Fields<C, Root<C, K>>[N]>>, Q>, Failure<C, Root<C, K>, OperationSelection<C, Root<C, K>, N, {
262
- edges: {
263
- node: Q;
264
- };
265
- pageInfo: {
266
- endCursor: true;
267
- hasNextPage: true;
268
- };
269
- }>>, R>;
224
+ declare const GqlTransport_base: Context.ServiceClass<GqlTransport, "@distilled.cloud/graphql/Transport", {
225
+ readonly execute: (req: CompiledOperation) => Effect.Effect<GraphQLResponse, GraphQLTransportError, any>;
226
+ }>;
227
+ export declare class GqlTransport extends GqlTransport_base {
270
228
  }
271
- export type Operation<C extends Schema, K extends OperationKind, N extends keyof Fields<C, Root<C, K>> & string, R> = Named<TypeOf<Fields<C, Root<C, K>>[N]>> extends keyof C["scalars"] ? ScalarOperation<C, K, N, R> : ObjectOperation<C, K, N, R> & (K extends "query" ? "after" extends keyof ArgsOf<Fields<C, Root<C, K>>[N]> ? [ConnectionNode<C, TypeOf<Fields<C, Root<C, K>>[N]>>] extends [
272
- never
273
- ] ? {} : Pagination<C, K, N, R> : {} : {});
274
- /** Construct an Effect client; credentials and HTTP are resolved by the transport per call. */
275
- export declare const makeClient: <C extends Schema, R>(model: GraphQLModel, transport: Transport<R>, classes: Readonly<Record<string, ErrorConstructor>>) => {
276
- query: <const Q extends Selection<C, C["query"]>>(selection: Q) => Effect.Effect<Result<C, `${C["query"]}!`, Q>, Failure<C, C["query"], Q>, R>;
277
- mutation: <const Q extends Selection<C, C["mutation"]>>(selection: Q) => Effect.Effect<Result<C, `${C["mutation"]}!`, Q>, Failure<C, C["mutation"], Q>, R>;
278
- report: {
279
- query: <const Q extends Selection<C, C["query"]>>(selection: Q) => Effect.Effect<Report<Result<C, `${C["query"]}!`, Q>, Errors<C, C["query"], Q>>, ClientError, R>;
280
- mutation: <const Q extends Selection<C, C["mutation"]>>(selection: Q) => Effect.Effect<Report<Result<C, `${C["mutation"]}!`, Q>, Errors<C, C["mutation"], Q>>, ClientError, R>;
281
- };
282
- operation: <K extends OperationKind, N extends keyof Fields<C, Root<C, K>> & string>(kind: K, name: N) => Operation<C, K, N, R>;
229
+ /**
230
+ * GraphQL fields copied onto a Query so `user.name` type-checks.
231
+ * `Query<User>` contains `projects: Query<Project[]>`, which contains
232
+ * `owner: Query<User>` again — TypeScript leaves the cycle lazy. Fields
233
+ * inherit the errors of the root they were read from.
234
+ */
235
+ type QueryFields<Value, Error> = [NonNullable<Value>] extends [
236
+ ReadonlyArray<infer Item>
237
+ ] ? {
238
+ readonly [Field in keyof NonNullable<Item>]: Query<NonNullable<Item>[Field] | Nullish<Item>, Error>;
239
+ } & {
240
+ (args: Record<string, unknown>): Query<Value, Error>;
241
+ } : [NonNullable<Value>] extends [object] ? {
242
+ readonly [Field in keyof NonNullable<Value>]: Query<NonNullable<Value>[Field] | Nullish<Value>, Error>;
243
+ } : {};
244
+ /** A field read through a `null` parent is `null`. */
245
+ type Nullish<Value> = Extract<Value, null | undefined>;
246
+ /**
247
+ * A lazy GraphQL selection. `Value` is the plain data after `Query.fn` runs;
248
+ * `Error` is the union of typed errors the roots it reads can return.
249
+ */
250
+ export type Query<Value, Error = never> = QueryNode<Value, Error> & QueryFields<Value, Error>;
251
+ /** Strip Query/Effect wrappers from a returned plan down to plain data. */
252
+ export type UnwrapPlan<Plan> = Plan extends QueryNode<infer Value, any> ? Value : Plan extends Effect.Effect<infer Success, any, any> ? Success : Plan extends ReadonlyArray<infer Element> ? ReadonlyArray<UnwrapPlan<Element>> : Plan extends object ? {
253
+ readonly [Key in keyof Plan]: UnwrapPlan<Plan[Key]>;
254
+ } : Plan;
255
+ /** Typed errors of every Query and Effect in a returned plan. */
256
+ export type PlanError<Plan> = Plan extends QueryNode<any, infer Error> ? Error : Plan extends Effect.Effect<any, infer Error, any> ? Error : Plan extends ReadonlyArray<infer Element> ? PlanError<Element> : Plan extends object ? {
257
+ readonly [Key in keyof Plan]: PlanError<Plan[Key]>;
258
+ }[keyof Plan] : never;
259
+ /** Failures of evaluating a plan whose roots declare `Error`. */
260
+ export type QueryError<Error> = Error | GraphQLFailure<Extract<Error, GraphQLIssue> | UnknownGraphQLError> | UnknownGraphQLError | GraphQLTransportError;
261
+ type Expr = RootExpr | PropExpr | ItemExpr | MapValueExpr | MapItemsExpr | FilterExpr | FlatMapExpr | LiteralExpr;
262
+ type RootExpr = {
263
+ readonly _tag: "Root";
264
+ readonly op: "query" | "mutation";
265
+ readonly field: string;
266
+ readonly args: Record<string, unknown> | undefined;
267
+ readonly argTypes: ArgMeta | undefined;
268
+ readonly type: TypeRef;
269
+ /** Relay connection: paint `edges { node }`, extract an array of nodes. */
270
+ readonly connection?: boolean;
271
+ /** Errors this root field can return, including global errors. */
272
+ readonly errors: ReadonlyArray<ErrorSpec>;
273
+ };
274
+ type PropExpr = {
275
+ readonly _tag: "Prop";
276
+ readonly parent: Expr;
277
+ readonly field: FieldMeta;
278
+ readonly type: TypeRef;
279
+ readonly args?: Record<string, unknown>;
280
+ };
281
+ type ItemExpr = {
282
+ readonly _tag: "Item";
283
+ readonly list: Expr;
284
+ readonly type: TypeRef;
283
285
  };
286
+ type MapValueExpr = {
287
+ readonly _tag: "MapValue";
288
+ readonly parent: Expr;
289
+ readonly mapFn: (value: unknown) => unknown;
290
+ readonly type: TypeRef;
291
+ };
292
+ type MapItemsExpr = {
293
+ readonly _tag: "MapItems";
294
+ readonly parent: Expr;
295
+ readonly mapped: unknown;
296
+ /** Map one object (`null` stays `null`) instead of every list item. */
297
+ readonly single?: boolean;
298
+ readonly type: TypeRef;
299
+ };
300
+ type FilterExpr = {
301
+ readonly _tag: "Filter";
302
+ readonly parent: Expr;
303
+ readonly predicate: Expr;
304
+ readonly type: TypeRef;
305
+ };
306
+ type FlatMapExpr = {
307
+ readonly _tag: "FlatMap";
308
+ readonly parent: Expr;
309
+ readonly flatMapFn: (value: unknown) => unknown;
310
+ readonly type: TypeRef;
311
+ };
312
+ type LiteralExpr = {
313
+ readonly _tag: "Literal";
314
+ readonly value: unknown;
315
+ readonly type: TypeRef;
316
+ };
317
+ export declare class QueryNode<out Value = unknown, out Error = never> {
318
+ readonly expr: Expr;
319
+ readonly [QuerySymbol]: symbol;
320
+ readonly valueType: Value;
321
+ readonly errorType: Error;
322
+ constructor(expr: Expr);
323
+ pipe<Self>(this: Self): Self;
324
+ pipe<Self, Out1>(this: Self, step1: (_: Self) => Out1): Out1;
325
+ pipe<Self, Out1, Out2>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2): Out2;
326
+ pipe<Self, Out1, Out2, Out3>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3): Out3;
327
+ pipe<Self, Out1, Out2, Out3, Out4>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3, step4: (_: Out3) => Out4): Out4;
328
+ pipe<Self, Out1, Out2, Out3, Out4, Out5>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3, step4: (_: Out3) => Out4, step5: (_: Out4) => Out5): Out5;
329
+ pipe<Self, Out1, Out2, Out3, Out4, Out5, Out6>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3, step4: (_: Out3) => Out4, step5: (_: Out4) => Out5, step6: (_: Out5) => Out6): Out6;
330
+ pipe<Self, Out1, Out2, Out3, Out4, Out5, Out6, Out7>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3, step4: (_: Out3) => Out4, step5: (_: Out4) => Out5, step6: (_: Out5) => Out6, step7: (_: Out6) => Out7): Out7;
331
+ pipe<Self, Out1, Out2, Out3, Out4, Out5, Out6, Out7, Out8>(this: Self, step1: (_: Self) => Out1, step2: (_: Out1) => Out2, step3: (_: Out2) => Out3, step4: (_: Out3) => Out4, step5: (_: Out4) => Out5, step6: (_: Out5) => Out6, step7: (_: Out6) => Out7, step8: (_: Out7) => Out8): Out8;
332
+ [inspect](): string;
333
+ toString(): string;
334
+ }
335
+ export declare const isQuery: (value: unknown) => value is Query<unknown>;
336
+ export declare const root: <Value, Error = never>(op: "query" | "mutation", field: string, meta: TypeMeta, args?: Record<string, unknown>, argTypes?: ArgMeta, errors?: ReadonlyArray<ErrorSpec>) => Query<Value, Error>;
337
+ export declare const rootList: <Item, Error = never>(op: "query" | "mutation", field: string, meta: TypeMeta, args?: Record<string, unknown>, argTypes?: ArgMeta, errors?: ReadonlyArray<ErrorSpec>) => Query<ReadonlyArray<Item>, Error>;
338
+ /** Root Relay connection: typed as `Query<Item[]>`, document uses `edges { node }`. */
339
+ export declare const rootConnection: <Item, Error = never>(op: "query" | "mutation", field: string, meta: TypeMeta, args?: Record<string, unknown>, argTypes?: ArgMeta, errors?: ReadonlyArray<ErrorSpec>) => Query<ReadonlyArray<Item>, Error>;
340
+ /** Root field whose GraphQL type is a scalar, enum, or list of those. */
341
+ export declare const rootLeaf: <Value, Error = never>(op: "query" | "mutation", field: string, list: boolean, args?: Record<string, unknown>, argTypes?: ArgMeta, errors?: ReadonlyArray<ErrorSpec>) => Query<Value, Error>;
342
+ /** `Query.of` / pure. */
343
+ export declare const ofQuery: <Value>(value: Value) => Query<Value>;
344
+ export declare function filterQuery<Item, Error = never>(predicate: (item: Query<Item>) => QueryNode<boolean, any>): (source: QueryNode<readonly Item[] | null, Error>) => Query<readonly Item[], Error>;
345
+ export declare function filterQuery<Item, Error = never>(source: QueryNode<readonly Item[] | null, Error>, predicate: (item: Query<Item>) => QueryNode<boolean, any>): Query<readonly Item[], Error>;
346
+ /**
347
+ * What `Query.map`'s callback receives: a Query per item for lists, a Query
348
+ * for an object (so its fields get selected), the plain value for scalars.
349
+ */
350
+ type MapInput<Value> = [NonNullable<Value>] extends [ReadonlyArray<infer Item>] ? Query<Item> : [NonNullable<Value>] extends [object] ? Query<NonNullable<Value>> : Value;
351
+ /** An object mapped through a `null` value stays `null`. */
352
+ type MapOutput<Value, Mapped> = [NonNullable<Value>] extends [
353
+ ReadonlyArray<unknown>
354
+ ] ? ReadonlyArray<UnwrapPlan<Mapped>> : [NonNullable<Value>] extends [object] ? UnwrapPlan<Mapped> | Nullish<Value> : Mapped;
355
+ export declare function mapQuery<Value, Mapped, Error = never>(mapFn: (value: NoInfer<MapInput<Value>>) => Mapped): (source: QueryNode<Value, Error>) => Query<MapOutput<Value, Mapped>, Error>;
356
+ export declare function mapQuery<Value, Mapped, Error = never>(source: QueryNode<Value, Error>, mapFn: (value: NoInfer<MapInput<Value>>) => Mapped): Query<MapOutput<Value, Mapped>, Error>;
357
+ export declare function flatMapQuery<Value, Result, Error, Requirements, SourceError = never>(flatMapFn: (value: Value) => Effect.Effect<Result, Error, Requirements> | QueryNode<Result, Error>): (source: QueryNode<Value, SourceError>) => Query<Result, SourceError | Error>;
358
+ export declare function flatMapQuery<Value, Result, Error, Requirements, SourceError = never>(source: QueryNode<Value, SourceError>, flatMapFn: (value: Value) => Effect.Effect<Result, Error, Requirements> | QueryNode<Result, Error>): Query<Result, SourceError | Error>;
359
+ /**
360
+ * Builder → Effect. The inner function is *not* a generator; it returns a
361
+ * plan of Query/Effect values. Query.fn visits the plan, POSTs one document,
362
+ * then interprets Map/Filter/FlatMap/Of.
363
+ */
364
+ export declare const queryFn: <Arguments extends Array<unknown>, Plan>(build: (...args: Arguments) => Plan) => ((...args: Arguments) => Effect.Effect<UnwrapPlan<Plan>, QueryError<PlanError<Plan>>, GqlTransport>);
365
+ /**
366
+ * Every page of a Relay connection, one request per page. `query` is a
367
+ * connection lens (root or nested under objects), optionally mapped or
368
+ * filtered: `Query.pages(Railway.project({ id }).services({ first: 50 }))`.
369
+ * Starts from the query's own `after` argument, if any.
370
+ */
371
+ export declare const pagesQuery: <Item, Error>(query: QueryNode<ReadonlyArray<Item> | null, Error>) => Stream.Stream<ReadonlyArray<Item>, QueryError<Error> | GraphQLPaginationError, GqlTransport>;
372
+ /** Every node of a Relay connection, across all pages. */
373
+ export declare const itemsQuery: <Item, Error>(query: QueryNode<ReadonlyArray<Item> | null, Error>) => Stream.Stream<Item, QueryError<Error> | GraphQLPaginationError, GqlTransport>;
374
+ export {};
284
375
  //# sourceMappingURL=graphql.d.ts.map