@effect-gql/core 0.1.0 → 1.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 (164) hide show
  1. package/README.md +100 -0
  2. package/builder/index.cjs +1446 -0
  3. package/builder/index.cjs.map +1 -0
  4. package/builder/index.d.cts +260 -0
  5. package/{dist/builder/pipe-api.d.ts → builder/index.d.ts} +50 -21
  6. package/builder/index.js +1405 -0
  7. package/builder/index.js.map +1 -0
  8. package/index.cjs +3469 -0
  9. package/index.cjs.map +1 -0
  10. package/index.d.cts +529 -0
  11. package/index.d.ts +529 -0
  12. package/index.js +3292 -0
  13. package/index.js.map +1 -0
  14. package/package.json +19 -28
  15. package/schema-builder-DKvkzU_M.d.cts +965 -0
  16. package/schema-builder-DKvkzU_M.d.ts +965 -0
  17. package/server/index.cjs +1579 -0
  18. package/server/index.cjs.map +1 -0
  19. package/server/index.d.cts +682 -0
  20. package/server/index.d.ts +682 -0
  21. package/server/index.js +1548 -0
  22. package/server/index.js.map +1 -0
  23. package/dist/analyzer-extension.d.ts +0 -105
  24. package/dist/analyzer-extension.d.ts.map +0 -1
  25. package/dist/analyzer-extension.js +0 -137
  26. package/dist/analyzer-extension.js.map +0 -1
  27. package/dist/builder/execute.d.ts +0 -26
  28. package/dist/builder/execute.d.ts.map +0 -1
  29. package/dist/builder/execute.js +0 -104
  30. package/dist/builder/execute.js.map +0 -1
  31. package/dist/builder/field-builders.d.ts +0 -30
  32. package/dist/builder/field-builders.d.ts.map +0 -1
  33. package/dist/builder/field-builders.js +0 -200
  34. package/dist/builder/field-builders.js.map +0 -1
  35. package/dist/builder/index.d.ts +0 -7
  36. package/dist/builder/index.d.ts.map +0 -1
  37. package/dist/builder/index.js +0 -31
  38. package/dist/builder/index.js.map +0 -1
  39. package/dist/builder/pipe-api.d.ts.map +0 -1
  40. package/dist/builder/pipe-api.js +0 -151
  41. package/dist/builder/pipe-api.js.map +0 -1
  42. package/dist/builder/schema-builder.d.ts +0 -301
  43. package/dist/builder/schema-builder.d.ts.map +0 -1
  44. package/dist/builder/schema-builder.js +0 -566
  45. package/dist/builder/schema-builder.js.map +0 -1
  46. package/dist/builder/type-registry.d.ts +0 -80
  47. package/dist/builder/type-registry.d.ts.map +0 -1
  48. package/dist/builder/type-registry.js +0 -505
  49. package/dist/builder/type-registry.js.map +0 -1
  50. package/dist/builder/types.d.ts +0 -283
  51. package/dist/builder/types.d.ts.map +0 -1
  52. package/dist/builder/types.js +0 -3
  53. package/dist/builder/types.js.map +0 -1
  54. package/dist/cli/generate-schema.d.ts +0 -29
  55. package/dist/cli/generate-schema.d.ts.map +0 -1
  56. package/dist/cli/generate-schema.js +0 -233
  57. package/dist/cli/generate-schema.js.map +0 -1
  58. package/dist/cli/index.d.ts +0 -19
  59. package/dist/cli/index.d.ts.map +0 -1
  60. package/dist/cli/index.js +0 -24
  61. package/dist/cli/index.js.map +0 -1
  62. package/dist/context.d.ts +0 -18
  63. package/dist/context.d.ts.map +0 -1
  64. package/dist/context.js +0 -11
  65. package/dist/context.js.map +0 -1
  66. package/dist/error.d.ts +0 -45
  67. package/dist/error.d.ts.map +0 -1
  68. package/dist/error.js +0 -29
  69. package/dist/error.js.map +0 -1
  70. package/dist/extensions.d.ts +0 -130
  71. package/dist/extensions.d.ts.map +0 -1
  72. package/dist/extensions.js +0 -78
  73. package/dist/extensions.js.map +0 -1
  74. package/dist/index.d.ts +0 -12
  75. package/dist/index.d.ts.map +0 -1
  76. package/dist/index.js +0 -47
  77. package/dist/index.js.map +0 -1
  78. package/dist/loader.d.ts +0 -169
  79. package/dist/loader.d.ts.map +0 -1
  80. package/dist/loader.js +0 -237
  81. package/dist/loader.js.map +0 -1
  82. package/dist/resolver-context.d.ts +0 -154
  83. package/dist/resolver-context.d.ts.map +0 -1
  84. package/dist/resolver-context.js +0 -184
  85. package/dist/resolver-context.js.map +0 -1
  86. package/dist/schema-mapping.d.ts +0 -30
  87. package/dist/schema-mapping.d.ts.map +0 -1
  88. package/dist/schema-mapping.js +0 -280
  89. package/dist/schema-mapping.js.map +0 -1
  90. package/dist/server/cache-control.d.ts +0 -96
  91. package/dist/server/cache-control.d.ts.map +0 -1
  92. package/dist/server/cache-control.js +0 -308
  93. package/dist/server/cache-control.js.map +0 -1
  94. package/dist/server/complexity.d.ts +0 -165
  95. package/dist/server/complexity.d.ts.map +0 -1
  96. package/dist/server/complexity.js +0 -433
  97. package/dist/server/complexity.js.map +0 -1
  98. package/dist/server/config.d.ts +0 -66
  99. package/dist/server/config.d.ts.map +0 -1
  100. package/dist/server/config.js +0 -104
  101. package/dist/server/config.js.map +0 -1
  102. package/dist/server/graphiql.d.ts +0 -5
  103. package/dist/server/graphiql.d.ts.map +0 -1
  104. package/dist/server/graphiql.js +0 -43
  105. package/dist/server/graphiql.js.map +0 -1
  106. package/dist/server/index.d.ts +0 -18
  107. package/dist/server/index.d.ts.map +0 -1
  108. package/dist/server/index.js +0 -48
  109. package/dist/server/index.js.map +0 -1
  110. package/dist/server/router.d.ts +0 -79
  111. package/dist/server/router.d.ts.map +0 -1
  112. package/dist/server/router.js +0 -232
  113. package/dist/server/router.js.map +0 -1
  114. package/dist/server/schema-builder-extensions.d.ts +0 -42
  115. package/dist/server/schema-builder-extensions.d.ts.map +0 -1
  116. package/dist/server/schema-builder-extensions.js +0 -48
  117. package/dist/server/schema-builder-extensions.js.map +0 -1
  118. package/dist/server/sse-adapter.d.ts +0 -64
  119. package/dist/server/sse-adapter.d.ts.map +0 -1
  120. package/dist/server/sse-adapter.js +0 -227
  121. package/dist/server/sse-adapter.js.map +0 -1
  122. package/dist/server/sse-types.d.ts +0 -192
  123. package/dist/server/sse-types.d.ts.map +0 -1
  124. package/dist/server/sse-types.js +0 -63
  125. package/dist/server/sse-types.js.map +0 -1
  126. package/dist/server/ws-adapter.d.ts +0 -39
  127. package/dist/server/ws-adapter.d.ts.map +0 -1
  128. package/dist/server/ws-adapter.js +0 -247
  129. package/dist/server/ws-adapter.js.map +0 -1
  130. package/dist/server/ws-types.d.ts +0 -169
  131. package/dist/server/ws-types.d.ts.map +0 -1
  132. package/dist/server/ws-types.js +0 -11
  133. package/dist/server/ws-types.js.map +0 -1
  134. package/dist/server/ws-utils.d.ts +0 -42
  135. package/dist/server/ws-utils.d.ts.map +0 -1
  136. package/dist/server/ws-utils.js +0 -99
  137. package/dist/server/ws-utils.js.map +0 -1
  138. package/src/analyzer-extension.ts +0 -254
  139. package/src/builder/execute.ts +0 -153
  140. package/src/builder/field-builders.ts +0 -322
  141. package/src/builder/index.ts +0 -48
  142. package/src/builder/pipe-api.ts +0 -312
  143. package/src/builder/schema-builder.ts +0 -970
  144. package/src/builder/type-registry.ts +0 -670
  145. package/src/builder/types.ts +0 -305
  146. package/src/context.ts +0 -23
  147. package/src/error.ts +0 -32
  148. package/src/extensions.ts +0 -240
  149. package/src/index.ts +0 -32
  150. package/src/loader.ts +0 -363
  151. package/src/resolver-context.ts +0 -253
  152. package/src/schema-mapping.ts +0 -307
  153. package/src/server/cache-control.ts +0 -590
  154. package/src/server/complexity.ts +0 -774
  155. package/src/server/config.ts +0 -174
  156. package/src/server/graphiql.ts +0 -38
  157. package/src/server/index.ts +0 -96
  158. package/src/server/router.ts +0 -432
  159. package/src/server/schema-builder-extensions.ts +0 -51
  160. package/src/server/sse-adapter.ts +0 -327
  161. package/src/server/sse-types.ts +0 -234
  162. package/src/server/ws-adapter.ts +0 -355
  163. package/src/server/ws-types.ts +0 -192
  164. package/src/server/ws-utils.ts +0 -136
package/index.d.ts ADDED
@@ -0,0 +1,529 @@
1
+ import { F as FieldComplexityMap, G as GraphQLExtension, E as ExtensionsService } from './schema-builder-DKvkzU_M.js';
2
+ export { y as CacheControlConfig, J as CacheControlConfigFromEnv, h as CacheControlScope, C as CacheHint, w as CacheHintMap, x as CachePolicy, z as CachePolicyAnalysisInfo, q as ComplexityAnalysisError, l as ComplexityAnalysisInfo, n as ComplexityCalculator, j as ComplexityConfig, u as ComplexityConfigFromEnv, m as ComplexityExceededInfo, p as ComplexityLimitExceededError, k as ComplexityResult, D as DirectiveApplication, d as DirectiveRegistration, b as EnumRegistration, K as ExecutionArgs, o as FieldComplexity, a as FieldRegistration, f as GraphQLEffectContext, i as GraphQLSchemaBuilder, c as InputTypeRegistration, I as InterfaceRegistration, M as MiddlewareContext, e as MiddlewareRegistration, O as ObjectFieldRegistration, S as SubscriptionFieldRegistration, T as TypeRegistration, g as TypeRegistries, U as UnionRegistration, t as combineCalculators, A as computeCachePolicy, B as computeCachePolicyFromQuery, r as defaultComplexityCalculator, s as depthOnlyCalculator, L as makeExtensionsService, R as runExecuteEndHooks, Q as runExecuteStartHooks, N as runParseHooks, P as runValidateHooks, H as toCacheControlHeader, v as validateComplexity } from './schema-builder-DKvkzU_M.js';
3
+ import { GraphQLOutputType, GraphQLInputType, GraphQLFieldConfigArgumentMap, GraphQLObjectType } from 'graphql';
4
+ export { DirectiveLocation, GraphQLBoolean, GraphQLEnumType, GraphQLFieldConfigMap, GraphQLFloat, GraphQLID, GraphQLInputObjectType, GraphQLInt, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLScalarType, GraphQLSchema, GraphQLString, GraphQLUnionType, Kind, ValueNode, graphql, lexicographicSortSchema, printSchema } from 'graphql';
5
+ export { compose, directive, enumType, execute, extension, field, getSchemaName, inputType, interfaceType, middleware, mutation, objectType, query, subscription, unionType } from './builder/index.js';
6
+ import { Effect, Context, Layer, Ref, HashMap, Option } from 'effect';
7
+ import * as S from 'effect/Schema';
8
+ import * as effect_Cause from 'effect/Cause';
9
+ import * as effect_Types from 'effect/Types';
10
+ import DataLoader from 'dataloader';
11
+ export { CloseEvent, CompleteMessage, ConnectionContext, EffectSSE, EffectWebSocket, ErrorHandler, GraphQLRouterConfig, GraphQLRouterConfigFromEnv, GraphQLRouterConfigInput, GraphQLSSEConfig, GraphQLSSEOptions, GraphQLWSConfig, GraphQLWSOptions, GraphiQLConfig, MakeGraphQLRouterOptions, SSEConnectionContext, SSEError, SSEEvent, SSEEventType, SSESubscriptionRequest, SSESubscriptionResult, SSE_HEADERS, SubscribeMessage, WS_CLOSED, WebSocketError, WsWebSocket, defaultConfig, defaultErrorHandler, formatCompleteEvent, formatErrorEvent, formatNextEvent, formatSSEMessage, graphiqlHtml, makeGraphQLRouter, makeGraphQLSSEHandler, makeGraphQLWSHandler, makeSSESubscriptionStream, normalizeConfig, toEffectWebSocketFromWs, toRouter } from './server/index.js';
12
+ import '@effect/platform';
13
+
14
+ /**
15
+ * Convert an Effect Schema to a GraphQL output type
16
+ */
17
+ declare const toGraphQLType: (schema: S.Schema<any, any, any>) => GraphQLOutputType;
18
+ /**
19
+ * Convert an Effect Schema to a GraphQL input type
20
+ */
21
+ declare const toGraphQLInputType: (schema: S.Schema<any, any, any>) => GraphQLInputType;
22
+ /**
23
+ * Additional field configuration for computed/relational fields
24
+ */
25
+ interface AdditionalField<Parent, Args, R, E, A> {
26
+ type: GraphQLOutputType;
27
+ args?: GraphQLFieldConfigArgumentMap;
28
+ description?: string;
29
+ resolve: (parent: Parent, args: Args) => Effect.Effect<A, E, R>;
30
+ }
31
+ /**
32
+ * Create a GraphQL Object Type from an Effect Schema with a name
33
+ * Optionally add computed/relational fields with resolvers
34
+ */
35
+ declare const toGraphQLObjectType: <T>(name: string, schema: S.Schema<any, any, any>, additionalFields?: Record<string, AdditionalField<T, any, any, any, any>>) => GraphQLObjectType;
36
+ /**
37
+ * Convert an Effect Schema to GraphQL arguments
38
+ */
39
+ declare const toGraphQLArgs: (schema: S.Schema<any, any, any>) => GraphQLFieldConfigArgumentMap;
40
+
41
+ declare const GraphQLError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
42
+ readonly _tag: "GraphQLError";
43
+ } & Readonly<A>;
44
+ /**
45
+ * Base class for GraphQL errors in Effect
46
+ */
47
+ declare class GraphQLError extends GraphQLError_base<{
48
+ message: string;
49
+ extensions?: Record<string, unknown>;
50
+ }> {
51
+ }
52
+ declare const ValidationError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
53
+ readonly _tag: "ValidationError";
54
+ } & Readonly<A>;
55
+ /**
56
+ * Validation error for input validation failures
57
+ */
58
+ declare class ValidationError extends ValidationError_base<{
59
+ message: string;
60
+ field?: string;
61
+ }> {
62
+ }
63
+ declare const AuthorizationError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
64
+ readonly _tag: "AuthorizationError";
65
+ } & Readonly<A>;
66
+ /**
67
+ * Authorization error for access control failures
68
+ */
69
+ declare class AuthorizationError extends AuthorizationError_base<{
70
+ message: string;
71
+ }> {
72
+ }
73
+ declare const NotFoundError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
74
+ readonly _tag: "NotFoundError";
75
+ } & Readonly<A>;
76
+ /**
77
+ * Not found error for missing resources
78
+ */
79
+ declare class NotFoundError extends NotFoundError_base<{
80
+ message: string;
81
+ resource?: string;
82
+ }> {
83
+ }
84
+
85
+ /**
86
+ * GraphQL request context containing request-specific data
87
+ */
88
+ interface GraphQLRequestContext {
89
+ readonly request: {
90
+ readonly headers: Record<string, string>;
91
+ readonly query: string;
92
+ readonly variables?: Record<string, unknown>;
93
+ readonly operationName?: string;
94
+ };
95
+ }
96
+ declare const GraphQLRequestContext: Context.Tag<GraphQLRequestContext, GraphQLRequestContext>;
97
+ /**
98
+ * Create a layer from request context
99
+ */
100
+ declare const makeRequestContextLayer: (context: GraphQLRequestContext) => Layer.Layer<GraphQLRequestContext>;
101
+
102
+ /**
103
+ * Ergonomic DataLoader helpers for Effect-based GraphQL
104
+ *
105
+ * This module provides a type-safe, declarative way to define DataLoaders
106
+ * that integrate seamlessly with Effect's service system.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // Define loaders
111
+ * const loaders = Loader.define({
112
+ * UserById: Loader.single<string, User>({
113
+ * batch: (ids) => db.getUsersByIds(ids),
114
+ * key: (user) => user.id,
115
+ * }),
116
+ *
117
+ * PostsByAuthorId: Loader.grouped<string, Post>({
118
+ * batch: (ids) => db.getPostsForAuthors(ids),
119
+ * groupBy: (post) => post.authorId,
120
+ * }),
121
+ * })
122
+ *
123
+ * // Use in resolvers
124
+ * resolve: (parent) => loaders.load("UserById", parent.authorId)
125
+ * ```
126
+ */
127
+ /**
128
+ * Configuration for a single-value loader (one key -> one value)
129
+ */
130
+ interface SingleLoaderDef<K, V, R> {
131
+ readonly _tag: "single";
132
+ readonly batch: (keys: readonly K[]) => Effect.Effect<readonly V[], Error, R>;
133
+ readonly key: (value: V) => K;
134
+ }
135
+ /**
136
+ * Configuration for a grouped loader (one key -> many values)
137
+ */
138
+ interface GroupedLoaderDef<K, V, R> {
139
+ readonly _tag: "grouped";
140
+ readonly batch: (keys: readonly K[]) => Effect.Effect<readonly V[], Error, R>;
141
+ readonly groupBy: (value: V) => K;
142
+ }
143
+ type LoaderDef<K, V, R> = SingleLoaderDef<K, V, R> | GroupedLoaderDef<K, V, R>;
144
+ /**
145
+ * Runtime DataLoader instances
146
+ */
147
+ type LoaderInstances<Defs extends Record<string, LoaderDef<any, any, any>>> = {
148
+ [Name in keyof Defs]: Defs[Name] extends SingleLoaderDef<infer K, infer V, any> ? DataLoader<K, V> : Defs[Name] extends GroupedLoaderDef<infer K, infer V, any> ? DataLoader<K, V[]> : never;
149
+ };
150
+ /**
151
+ * Extract the value type for a loader (accounting for grouped loaders)
152
+ */
153
+ type LoaderValue<Def> = Def extends SingleLoaderDef<any, infer V, any> ? V : Def extends GroupedLoaderDef<any, infer V, any> ? V[] : never;
154
+ /**
155
+ * Extract the key type for a loader
156
+ */
157
+ type LoaderKey<Def> = Def extends LoaderDef<infer K, any, any> ? K : never;
158
+ /**
159
+ * Extract combined requirements from all loaders
160
+ */
161
+ type LoaderRequirements<Defs extends Record<string, LoaderDef<any, any, any>>> = {
162
+ [K in keyof Defs]: Defs[K] extends LoaderDef<any, any, infer R> ? R : never;
163
+ }[keyof Defs];
164
+ /**
165
+ * Create a single-value loader definition.
166
+ * One key maps to one value.
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * Loader.single<string, User>({
171
+ * batch: (ids) => db.getUsersByIds(ids),
172
+ * key: (user) => user.id,
173
+ * })
174
+ * ```
175
+ */
176
+ declare function single<K, V, R = never>(config: {
177
+ batch: (keys: readonly K[]) => Effect.Effect<readonly V[], Error, R>;
178
+ key: (value: V) => K;
179
+ }): SingleLoaderDef<K, V, R>;
180
+ /**
181
+ * Create a grouped loader definition.
182
+ * One key maps to many values.
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * Loader.grouped<string, Post>({
187
+ * batch: (authorIds) => db.getPostsForAuthors(authorIds),
188
+ * groupBy: (post) => post.authorId,
189
+ * })
190
+ * ```
191
+ */
192
+ declare function grouped<K, V, R = never>(config: {
193
+ batch: (keys: readonly K[]) => Effect.Effect<readonly V[], Error, R>;
194
+ groupBy: (value: V) => K;
195
+ }): GroupedLoaderDef<K, V, R>;
196
+ /**
197
+ * A registry of loader definitions with methods to create instances and layers
198
+ */
199
+ declare class LoaderRegistry<Defs extends Record<string, LoaderDef<any, any, any>>> {
200
+ readonly definitions: Defs;
201
+ readonly _tag = "LoaderRegistry";
202
+ /**
203
+ * The Effect service tag for this loader registry
204
+ */
205
+ readonly Service: Context.Tag<LoaderInstances<Defs>, LoaderInstances<Defs>>;
206
+ constructor(definitions: Defs);
207
+ /**
208
+ * Create a Layer that provides fresh DataLoader instances.
209
+ * Call this once per request to get request-scoped loaders.
210
+ */
211
+ toLayer(): Layer.Layer<LoaderInstances<Defs>, never, LoaderRequirements<Defs>>;
212
+ /**
213
+ * Helper to use loaders in a resolver with a callback.
214
+ */
215
+ use<A>(fn: (loaders: LoaderInstances<Defs>) => Promise<A>): Effect.Effect<A, Error, LoaderInstances<Defs>>;
216
+ /**
217
+ * Load a single value by key.
218
+ * This is the most common operation in resolvers.
219
+ *
220
+ * @internal The internal cast is safe because LoaderInstances<Defs> guarantees
221
+ * that loaders[name] is a DataLoader with the correct key/value types.
222
+ */
223
+ load<Name extends keyof Defs & string>(name: Name, key: LoaderKey<Defs[Name]>): Effect.Effect<LoaderValue<Defs[Name]>, Error, LoaderInstances<Defs>>;
224
+ /**
225
+ * Load multiple values by keys.
226
+ * All keys are batched into a single request.
227
+ *
228
+ * @internal The internal cast is safe because LoaderInstances<Defs> guarantees
229
+ * that loaders[name] is a DataLoader with the correct key/value types.
230
+ */
231
+ loadMany<Name extends keyof Defs & string>(name: Name, keys: readonly LoaderKey<Defs[Name]>[]): Effect.Effect<readonly LoaderValue<Defs[Name]>[], Error, LoaderInstances<Defs>>;
232
+ }
233
+ /**
234
+ * Define a set of loaders.
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * const loaders = Loader.define({
239
+ * UserById: Loader.single<string, User>({
240
+ * batch: (ids) => db.getUsersByIds(ids),
241
+ * key: (user) => user.id,
242
+ * }),
243
+ * PostsByAuthorId: Loader.grouped<string, Post>({
244
+ * batch: (ids) => db.getPostsForAuthors(ids),
245
+ * groupBy: (post) => post.authorId,
246
+ * }),
247
+ * })
248
+ *
249
+ * // In resolvers:
250
+ * loaders.load("UserById", "123")
251
+ * loaders.loadMany("UserById", ["1", "2", "3"])
252
+ * ```
253
+ */
254
+ declare function define<Defs extends Record<string, LoaderDef<any, any, any>>>(definitions: Defs): LoaderRegistry<Defs>;
255
+ /**
256
+ * Map an array of items to match requested keys.
257
+ * Returns items in the same order as keys, with errors for missing items.
258
+ */
259
+ declare function mapByKey<K, V>(keys: readonly K[], items: readonly V[], keyFn: (item: V) => K): (V | Error)[];
260
+ /**
261
+ * Group an array of items by a key function.
262
+ * Returns a Map from key to array of matching items.
263
+ * Guarantees an entry (possibly empty) for each requested key.
264
+ */
265
+ declare function groupByKey<K, V>(keys: readonly K[], items: readonly V[], keyFn: (item: V) => K): Map<K, V[]>;
266
+ declare const Loader: {
267
+ readonly define: typeof define;
268
+ readonly single: typeof single;
269
+ readonly grouped: typeof grouped;
270
+ readonly mapByKey: typeof mapByKey;
271
+ readonly groupByKey: typeof groupByKey;
272
+ };
273
+
274
+ /**
275
+ * A type-safe context system for passing values through the resolver hierarchy.
276
+ *
277
+ * Unlike simple property bags, this provides:
278
+ * - Type-safe slots that know their value type
279
+ * - Clear errors when required context is missing
280
+ * - Request-scoped storage that works across nested resolvers
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * // Define a context slot
285
+ * const AuthPrincipal = ResolverContext.make<User>("AuthPrincipal")
286
+ *
287
+ * // Provide in a directive
288
+ * .directive({
289
+ * name: "auth",
290
+ * apply: () => (effect) => Effect.gen(function*() {
291
+ * const user = yield* validateJwt()
292
+ * yield* ResolverContext.set(AuthPrincipal, user)
293
+ * return yield* effect
294
+ * }),
295
+ * })
296
+ *
297
+ * // Access in any nested resolver
298
+ * .field("User", "posts", {
299
+ * resolve: (parent) => Effect.gen(function*() {
300
+ * const user = yield* ResolverContext.get(AuthPrincipal)
301
+ * // ...
302
+ * }),
303
+ * })
304
+ * ```
305
+ */
306
+ /**
307
+ * Error thrown when trying to access a context value that hasn't been set
308
+ */
309
+ declare class MissingResolverContextError extends Error {
310
+ readonly contextName: string;
311
+ readonly _tag = "MissingResolverContextError";
312
+ constructor(contextName: string);
313
+ }
314
+ /**
315
+ * A typed context slot that can hold a value of type A
316
+ */
317
+ interface ResolverContextSlot<A> {
318
+ readonly _tag: "ResolverContextSlot";
319
+ readonly name: string;
320
+ readonly _A: A;
321
+ }
322
+ /**
323
+ * Internal storage for resolver context values.
324
+ * This is a request-scoped service that holds all context values.
325
+ */
326
+ interface ResolverContextStore {
327
+ readonly ref: Ref.Ref<HashMap.HashMap<string, unknown>>;
328
+ }
329
+ declare const ResolverContextStore: Context.Tag<ResolverContextStore, ResolverContextStore>;
330
+ /**
331
+ * Create a Layer that provides the ResolverContextStore.
332
+ * This should be included in the request layer.
333
+ */
334
+ declare const makeStoreLayer: () => Effect.Effect<Layer.Layer<ResolverContextStore>>;
335
+ /**
336
+ * Create a Layer that provides an empty ResolverContextStore.
337
+ * Convenience function for creating a fresh store layer.
338
+ */
339
+ declare const storeLayer: Layer.Layer<ResolverContextStore>;
340
+ /**
341
+ * Create a new resolver context slot.
342
+ *
343
+ * The name is used for error messages when the context is accessed but not set.
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * const AuthPrincipal = ResolverContext.make<User>("AuthPrincipal")
348
+ * const TenantId = ResolverContext.make<string>("TenantId")
349
+ * ```
350
+ */
351
+ declare const make: <A>(name: string) => ResolverContextSlot<A>;
352
+ /**
353
+ * Get a value from the resolver context.
354
+ *
355
+ * Fails with MissingResolverContextError if the context was not set
356
+ * by a parent resolver or directive.
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * const effect = Effect.gen(function*() {
361
+ * const user = yield* ResolverContext.get(AuthPrincipal)
362
+ * // user is typed as User
363
+ * })
364
+ * ```
365
+ */
366
+ declare const get: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<A, MissingResolverContextError, ResolverContextStore>;
367
+ /**
368
+ * Get a value from the resolver context as an Option.
369
+ *
370
+ * Returns None if the context was not set, instead of failing.
371
+ * Useful when context is optional.
372
+ */
373
+ declare const getOption: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<Option.Option<A>, never, ResolverContextStore>;
374
+ /**
375
+ * Set a value in the resolver context.
376
+ *
377
+ * The value will be available to all subsequent resolver calls in this request.
378
+ * This mutates the request-scoped store, so nested resolvers will see the value.
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * // In a directive
383
+ * const withAuth = (effect) => Effect.gen(function*() {
384
+ * const user = yield* validateJwt()
385
+ * yield* ResolverContext.set(AuthPrincipal, user)
386
+ * return yield* effect
387
+ * })
388
+ * ```
389
+ */
390
+ declare const set: <A>(slot: ResolverContextSlot<A>, value: A) => Effect.Effect<void, never, ResolverContextStore>;
391
+ /**
392
+ * Set multiple context values at once.
393
+ */
394
+ declare const setMany: (values: ReadonlyArray<readonly [ResolverContextSlot<any>, any]>) => Effect.Effect<void, never, ResolverContextStore>;
395
+ /**
396
+ * Check if a context slot has a value set.
397
+ */
398
+ declare const has: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<boolean, never, ResolverContextStore>;
399
+ /**
400
+ * Get a value or return a default if not set.
401
+ */
402
+ declare const getOrElse: <A>(slot: ResolverContextSlot<A>, orElse: () => A) => Effect.Effect<A, never, ResolverContextStore>;
403
+ /**
404
+ * Run an effect with a temporary context value.
405
+ * The value is set before the effect runs and removed after.
406
+ * Useful for scoped context that shouldn't persist.
407
+ */
408
+ declare const scoped: <A>(slot: ResolverContextSlot<A>, value: A) => <B, E, R>(effect: Effect.Effect<B, E, R>) => Effect.Effect<B, E, R | ResolverContextStore>;
409
+ /**
410
+ * Namespace for ResolverContext functions
411
+ */
412
+ declare const ResolverContext: {
413
+ readonly make: <A>(name: string) => ResolverContextSlot<A>;
414
+ readonly get: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<A, MissingResolverContextError, ResolverContextStore>;
415
+ readonly getOption: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<Option.Option<A>, never, ResolverContextStore>;
416
+ readonly set: <A>(slot: ResolverContextSlot<A>, value: A) => Effect.Effect<void, never, ResolverContextStore>;
417
+ readonly setMany: (values: ReadonlyArray<readonly [ResolverContextSlot<any>, any]>) => Effect.Effect<void, never, ResolverContextStore>;
418
+ readonly has: <A>(slot: ResolverContextSlot<A>) => Effect.Effect<boolean, never, ResolverContextStore>;
419
+ readonly getOrElse: <A>(slot: ResolverContextSlot<A>, orElse: () => A) => Effect.Effect<A, never, ResolverContextStore>;
420
+ readonly scoped: <A>(slot: ResolverContextSlot<A>, value: A) => <B, E, R>(effect: Effect.Effect<B, E, R>) => Effect.Effect<B, E, R | ResolverContextStore>;
421
+ readonly storeLayer: Layer.Layer<ResolverContextStore, never, never>;
422
+ readonly makeStoreLayer: () => Effect.Effect<Layer.Layer<ResolverContextStore>>;
423
+ readonly Store: Context.Tag<ResolverContextStore, ResolverContextStore>;
424
+ readonly MissingResolverContextError: typeof MissingResolverContextError;
425
+ };
426
+
427
+ /**
428
+ * Configuration for the analyzer extension
429
+ */
430
+ interface AnalyzerExtensionConfig {
431
+ /**
432
+ * Include the total complexity score in the response.
433
+ * @default true
434
+ */
435
+ readonly includeComplexity?: boolean;
436
+ /**
437
+ * Include the maximum query depth in the response.
438
+ * @default true
439
+ */
440
+ readonly includeDepth?: boolean;
441
+ /**
442
+ * Include the total field count in the response.
443
+ * @default false
444
+ */
445
+ readonly includeFieldCount?: boolean;
446
+ /**
447
+ * Include the alias count in the response.
448
+ * @default false
449
+ */
450
+ readonly includeAliasCount?: boolean;
451
+ /**
452
+ * The key to use in the response extensions object.
453
+ * @default "analyzer"
454
+ */
455
+ readonly key?: string;
456
+ /**
457
+ * Thresholds for logging warnings when exceeded.
458
+ * When a metric exceeds its threshold, a warning is logged.
459
+ */
460
+ readonly thresholds?: {
461
+ readonly depth?: number;
462
+ readonly complexity?: number;
463
+ readonly fieldCount?: number;
464
+ readonly aliasCount?: number;
465
+ };
466
+ /**
467
+ * Default complexity cost for fields without explicit costs.
468
+ * @default 1
469
+ */
470
+ readonly defaultFieldComplexity?: number;
471
+ /**
472
+ * Optional field complexity overrides.
473
+ * If not provided, uses the field complexities from the schema builder
474
+ * (passed via ExecutionArgs).
475
+ */
476
+ readonly fieldComplexities?: FieldComplexityMap;
477
+ }
478
+ /**
479
+ * Output format for analyzer extension
480
+ */
481
+ interface AnalyzerOutput {
482
+ complexity?: number;
483
+ depth?: number;
484
+ fieldCount?: number;
485
+ aliasCount?: number;
486
+ }
487
+ /**
488
+ * Create an analyzer extension that reports query complexity metrics
489
+ * in the response extensions field.
490
+ *
491
+ * Similar to async-graphql's Analyzer extension, this allows you to
492
+ * monitor the complexity of incoming queries without blocking execution.
493
+ *
494
+ * @example
495
+ * ```typescript
496
+ * // Basic usage - reports complexity and depth
497
+ * const analyzer = createAnalyzerExtension()
498
+ *
499
+ * // With all metrics and warnings
500
+ * const analyzer = createAnalyzerExtension({
501
+ * includeFieldCount: true,
502
+ * includeAliasCount: true,
503
+ * thresholds: {
504
+ * depth: 10,
505
+ * complexity: 100,
506
+ * },
507
+ * })
508
+ *
509
+ * // Add to schema builder
510
+ * const builder = GraphQLSchemaBuilder.empty.pipe(
511
+ * extension(analyzer),
512
+ * // ...queries, mutations, etc.
513
+ * )
514
+ *
515
+ * // Response will include:
516
+ * // {
517
+ * // "data": { ... },
518
+ * // "extensions": {
519
+ * // "analyzer": {
520
+ * // "complexity": 42,
521
+ * // "depth": 3
522
+ * // }
523
+ * // }
524
+ * // }
525
+ * ```
526
+ */
527
+ declare const createAnalyzerExtension: (config?: AnalyzerExtensionConfig) => GraphQLExtension<ExtensionsService>;
528
+
529
+ export { type AdditionalField, type AnalyzerExtensionConfig, type AnalyzerOutput, AuthorizationError, ExtensionsService, FieldComplexityMap, GraphQLError, GraphQLExtension, GraphQLRequestContext, type GroupedLoaderDef, Loader, type LoaderDef, type LoaderInstances, LoaderRegistry, MissingResolverContextError, NotFoundError, ResolverContext, type ResolverContextSlot, ResolverContextStore, type SingleLoaderDef, ValidationError, createAnalyzerExtension, get, getOption, getOrElse, has, make, makeRequestContextLayer, makeStoreLayer, scoped, set, setMany, storeLayer, toGraphQLArgs, toGraphQLInputType, toGraphQLObjectType, toGraphQLType };