@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.js ADDED
@@ -0,0 +1,3292 @@
1
+ import { GraphQLDirective, GraphQLEnumType, GraphQLInputObjectType, GraphQLInterfaceType, GraphQLObjectType, GraphQLUnionType, GraphQLSchema, GraphQLNonNull, GraphQLString, GraphQLFloat, GraphQLBoolean, GraphQLInt, GraphQLList, parse, GraphQLError, validate, execute as execute$1, Kind, specifiedRules, NoSchemaIntrospectionCustomRule, subscribe, GraphQLScalarType } from 'graphql';
2
+ export { DirectiveLocation, GraphQLBoolean, GraphQLEnumType, GraphQLFloat, GraphQLID, GraphQLInputObjectType, GraphQLInt, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLScalarType, GraphQLSchema, GraphQLString, GraphQLUnionType, Kind, graphql, lexicographicSortSchema, printSchema } from 'graphql';
3
+ import { Pipeable, Context, Data, Layer, Effect, Ref, HashMap, Config, Option, Schema, Runtime, Queue, Stream, Fiber, Deferred } from 'effect';
4
+ import * as S2 from 'effect/Schema';
5
+ import * as AST from 'effect/SchemaAST';
6
+ import DataLoader from 'dataloader';
7
+ import { HttpIncomingMessage, HttpServerResponse, HttpServerRequest, HttpRouter } from '@effect/platform';
8
+ import { makeServer } from 'graphql-ws';
9
+
10
+ // src/builder/index.ts
11
+ var isIntegerType = (ast) => {
12
+ if (ast._tag === "Refinement") {
13
+ const refinement = ast;
14
+ const annotations = refinement.annotations;
15
+ if (annotations) {
16
+ const identifier = AST.getIdentifierAnnotation(refinement);
17
+ if (identifier._tag === "Some" && identifier.value === "Int") {
18
+ return true;
19
+ }
20
+ }
21
+ return isIntegerType(refinement.from);
22
+ }
23
+ return false;
24
+ };
25
+ var toGraphQLType = (schema) => {
26
+ const ast = schema.ast;
27
+ if (ast._tag === "StringKeyword") return GraphQLString;
28
+ if (ast._tag === "NumberKeyword") return GraphQLFloat;
29
+ if (ast._tag === "BooleanKeyword") return GraphQLBoolean;
30
+ if (ast._tag === "Refinement") {
31
+ if (isIntegerType(ast)) {
32
+ return GraphQLInt;
33
+ }
34
+ return toGraphQLType(S2.make(ast.from));
35
+ }
36
+ if (ast._tag === "Literal") {
37
+ if (typeof ast.literal === "string") return GraphQLString;
38
+ if (typeof ast.literal === "number") {
39
+ return Number.isInteger(ast.literal) ? GraphQLInt : GraphQLFloat;
40
+ }
41
+ if (typeof ast.literal === "boolean") return GraphQLBoolean;
42
+ }
43
+ if (ast._tag === "TupleType") {
44
+ const elements = ast.elements;
45
+ if (elements.length > 0) {
46
+ const elementSchema = S2.make(elements[0].type);
47
+ return new GraphQLList(toGraphQLType(elementSchema));
48
+ }
49
+ }
50
+ if (ast._tag === "TypeLiteral") {
51
+ const fields = {};
52
+ for (const field2 of ast.propertySignatures) {
53
+ const fieldName = String(field2.name);
54
+ const fieldSchema = S2.make(field2.type);
55
+ let fieldType = toGraphQLType(fieldSchema);
56
+ if (!field2.isOptional) {
57
+ fieldType = new GraphQLNonNull(fieldType);
58
+ }
59
+ fields[fieldName] = { type: fieldType };
60
+ }
61
+ const typeName = schema.annotations?.identifier || `Object_${Math.random().toString(36).slice(2, 11)}`;
62
+ return new GraphQLObjectType({
63
+ name: typeName,
64
+ fields
65
+ });
66
+ }
67
+ if (ast._tag === "Transformation") {
68
+ return toGraphQLType(S2.make(ast.to));
69
+ }
70
+ if (ast._tag === "Union") {
71
+ const types = ast.types;
72
+ if (types.length > 0) {
73
+ return toGraphQLType(S2.make(types[0]));
74
+ }
75
+ }
76
+ if (ast._tag === "Suspend") {
77
+ const innerAst = ast.f();
78
+ return toGraphQLType(S2.make(innerAst));
79
+ }
80
+ return GraphQLString;
81
+ };
82
+ var toGraphQLInputType = (schema) => {
83
+ const ast = schema.ast;
84
+ if (ast._tag === "StringKeyword") return GraphQLString;
85
+ if (ast._tag === "NumberKeyword") return GraphQLFloat;
86
+ if (ast._tag === "BooleanKeyword") return GraphQLBoolean;
87
+ if (ast._tag === "Refinement") {
88
+ if (isIntegerType(ast)) {
89
+ return GraphQLInt;
90
+ }
91
+ return toGraphQLInputType(S2.make(ast.from));
92
+ }
93
+ if (ast._tag === "Literal") {
94
+ if (typeof ast.literal === "string") return GraphQLString;
95
+ if (typeof ast.literal === "number") {
96
+ return Number.isInteger(ast.literal) ? GraphQLInt : GraphQLFloat;
97
+ }
98
+ if (typeof ast.literal === "boolean") return GraphQLBoolean;
99
+ }
100
+ if (ast._tag === "TupleType") {
101
+ const elements = ast.elements;
102
+ if (elements.length > 0) {
103
+ const elementSchema = S2.make(elements[0].type);
104
+ return new GraphQLList(toGraphQLInputType(elementSchema));
105
+ }
106
+ }
107
+ if (ast._tag === "TypeLiteral") {
108
+ const fields = {};
109
+ for (const field2 of ast.propertySignatures) {
110
+ const fieldName = String(field2.name);
111
+ const fieldSchema = S2.make(field2.type);
112
+ let fieldType = toGraphQLInputType(fieldSchema);
113
+ if (!field2.isOptional) {
114
+ fieldType = new GraphQLNonNull(fieldType);
115
+ }
116
+ fields[fieldName] = { type: fieldType };
117
+ }
118
+ const typeName = schema.annotations?.identifier || `Input_${Math.random().toString(36).slice(2, 11)}`;
119
+ return new GraphQLInputObjectType({
120
+ name: typeName,
121
+ fields
122
+ });
123
+ }
124
+ if (ast._tag === "Transformation") {
125
+ return toGraphQLInputType(S2.make(ast.from));
126
+ }
127
+ if (ast._tag === "Union") {
128
+ const types = ast.types;
129
+ if (types.length > 0) {
130
+ return toGraphQLInputType(S2.make(types[0]));
131
+ }
132
+ }
133
+ if (ast._tag === "Suspend") {
134
+ const innerAst = ast.f();
135
+ return toGraphQLInputType(S2.make(innerAst));
136
+ }
137
+ return GraphQLString;
138
+ };
139
+ var toGraphQLObjectType = (name, schema, additionalFields) => {
140
+ const ast = schema.ast;
141
+ if (ast._tag === "TypeLiteral") {
142
+ const fields = {};
143
+ for (const field2 of ast.propertySignatures) {
144
+ const fieldName = String(field2.name);
145
+ const fieldSchema = S2.make(field2.type);
146
+ let fieldType = toGraphQLType(fieldSchema);
147
+ if (!field2.isOptional) {
148
+ fieldType = new GraphQLNonNull(fieldType);
149
+ }
150
+ fields[fieldName] = { type: fieldType };
151
+ }
152
+ if (additionalFields) {
153
+ for (const [fieldName, fieldConfig] of Object.entries(additionalFields)) {
154
+ fields[fieldName] = {
155
+ type: fieldConfig.type,
156
+ args: fieldConfig.args,
157
+ description: fieldConfig.description,
158
+ // Note: resolve will be set later when runtime is available
159
+ resolve: fieldConfig.resolve
160
+ };
161
+ }
162
+ }
163
+ return new GraphQLObjectType({
164
+ name,
165
+ fields
166
+ });
167
+ }
168
+ throw new Error(`Schema must be an object type to convert to GraphQLObjectType`);
169
+ };
170
+ var toGraphQLArgs = (schema) => {
171
+ const ast = schema.ast;
172
+ if (ast._tag === "TypeLiteral") {
173
+ const args = {};
174
+ for (const field2 of ast.propertySignatures) {
175
+ const fieldName = String(field2.name);
176
+ const fieldSchema = S2.make(field2.type);
177
+ let fieldType = toGraphQLInputType(fieldSchema);
178
+ if (!field2.isOptional) {
179
+ fieldType = new GraphQLNonNull(fieldType);
180
+ }
181
+ args[fieldName] = { type: fieldType };
182
+ }
183
+ return args;
184
+ }
185
+ throw new Error(`Schema must be an object type to convert to GraphQL arguments`);
186
+ };
187
+
188
+ // src/builder/type-registry.ts
189
+ function getSchemaName(schema) {
190
+ const ast = schema.ast;
191
+ if (ast._tag === "Transformation") {
192
+ const identifier = AST.getIdentifierAnnotation(ast.to);
193
+ if (identifier._tag === "Some") {
194
+ return identifier.value;
195
+ }
196
+ }
197
+ if (ast._tag === "TypeLiteral") {
198
+ const tagProp = ast.propertySignatures.find((p) => String(p.name) === "_tag");
199
+ if (tagProp && tagProp.type._tag === "Literal" && typeof tagProp.type.literal === "string") {
200
+ return tagProp.type.literal;
201
+ }
202
+ }
203
+ return void 0;
204
+ }
205
+ function buildReverseLookups(ctx) {
206
+ if (!ctx.schemaToTypeName) {
207
+ ctx.schemaToTypeName = /* @__PURE__ */ new Map();
208
+ ctx.astToTypeName = /* @__PURE__ */ new Map();
209
+ for (const [typeName, typeReg] of ctx.types) {
210
+ ctx.schemaToTypeName.set(typeReg.schema, typeName);
211
+ ctx.astToTypeName.set(typeReg.schema.ast, typeName);
212
+ }
213
+ }
214
+ if (!ctx.schemaToInterfaceName) {
215
+ ctx.schemaToInterfaceName = /* @__PURE__ */ new Map();
216
+ ctx.astToInterfaceName = /* @__PURE__ */ new Map();
217
+ for (const [interfaceName, interfaceReg] of ctx.interfaces) {
218
+ ctx.schemaToInterfaceName.set(interfaceReg.schema, interfaceName);
219
+ ctx.astToInterfaceName.set(interfaceReg.schema.ast, interfaceName);
220
+ }
221
+ }
222
+ if (!ctx.schemaToInputName) {
223
+ ctx.schemaToInputName = /* @__PURE__ */ new Map();
224
+ ctx.astToInputName = /* @__PURE__ */ new Map();
225
+ for (const [inputName, inputReg] of ctx.inputs) {
226
+ ctx.schemaToInputName.set(inputReg.schema, inputName);
227
+ ctx.astToInputName.set(inputReg.schema.ast, inputName);
228
+ }
229
+ }
230
+ if (!ctx.enumSortedValues) {
231
+ ctx.enumSortedValues = /* @__PURE__ */ new Map();
232
+ ctx.literalToEnumName = /* @__PURE__ */ new Map();
233
+ for (const [enumName, enumReg] of ctx.enums) {
234
+ ctx.enumSortedValues.set(enumName, [...enumReg.values].sort());
235
+ for (const value of enumReg.values) {
236
+ ctx.literalToEnumName.set(value, enumName);
237
+ }
238
+ }
239
+ }
240
+ if (!ctx.unionSortedTypes) {
241
+ ctx.unionSortedTypes = /* @__PURE__ */ new Map();
242
+ for (const [unionName, unionReg] of ctx.unions) {
243
+ ctx.unionSortedTypes.set(unionName, [...unionReg.types].sort());
244
+ }
245
+ }
246
+ }
247
+ var nonNullCache = /* @__PURE__ */ new WeakMap();
248
+ function getNonNull(type) {
249
+ let cached = nonNullCache.get(type);
250
+ if (!cached) {
251
+ cached = new GraphQLNonNull(type);
252
+ nonNullCache.set(type, cached);
253
+ }
254
+ return cached;
255
+ }
256
+ function toGraphQLTypeWithRegistry(schema, ctx) {
257
+ buildReverseLookups(ctx);
258
+ const ast = schema.ast;
259
+ const registeredType = findRegisteredType(schema, ast, ctx);
260
+ if (registeredType) return registeredType;
261
+ const registeredInterface = findRegisteredInterface(schema, ast, ctx);
262
+ if (registeredInterface) return registeredInterface;
263
+ if (ast._tag === "Transformation") {
264
+ return handleTransformationAST(ast, ctx);
265
+ }
266
+ if (ast._tag === "Union") {
267
+ return handleUnionAST(ast, ctx);
268
+ }
269
+ if (ast._tag === "Literal") {
270
+ const enumType2 = findEnumForLiteral(ast, ctx);
271
+ if (enumType2) return enumType2;
272
+ }
273
+ if (ast._tag === "TupleType") {
274
+ return handleTupleTypeAST(ast, ctx);
275
+ }
276
+ if (ast._tag === "Suspend") {
277
+ const innerAst = ast.f();
278
+ return toGraphQLTypeWithRegistry(S2.make(innerAst), ctx);
279
+ }
280
+ return toGraphQLType(schema);
281
+ }
282
+ function findRegisteredType(schema, ast, ctx) {
283
+ const typeName = ctx.schemaToTypeName?.get(schema) ?? ctx.astToTypeName?.get(ast);
284
+ if (typeName) {
285
+ return ctx.typeRegistry.get(typeName);
286
+ }
287
+ return void 0;
288
+ }
289
+ function findRegisteredInterface(schema, ast, ctx) {
290
+ const interfaceName = ctx.schemaToInterfaceName?.get(schema) ?? ctx.astToInterfaceName?.get(ast);
291
+ if (interfaceName) {
292
+ return ctx.interfaceRegistry.get(interfaceName);
293
+ }
294
+ return void 0;
295
+ }
296
+ function handleTransformationAST(ast, ctx) {
297
+ const toAst = ast.to;
298
+ if (toAst._tag === "TupleType") {
299
+ if (toAst.rest && toAst.rest.length > 0) {
300
+ const elementSchema = S2.make(toAst.rest[0].type);
301
+ const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
302
+ return new GraphQLList(elementType);
303
+ } else if (toAst.elements.length > 0) {
304
+ const elementSchema = S2.make(toAst.elements[0].type);
305
+ const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
306
+ return new GraphQLList(elementType);
307
+ }
308
+ }
309
+ return toGraphQLTypeWithRegistry(S2.make(ast.to), ctx);
310
+ }
311
+ function handleUnionAST(ast, ctx) {
312
+ const allLiterals = ast.types.every((t) => t._tag === "Literal");
313
+ if (allLiterals) {
314
+ const enumType2 = findEnumForLiteralUnion(ast.types, ctx);
315
+ if (enumType2) return enumType2;
316
+ } else {
317
+ const unionType2 = findRegisteredUnion(ast.types, ctx);
318
+ if (unionType2) return unionType2;
319
+ }
320
+ if (ast.types.length > 0) {
321
+ return toGraphQLTypeWithRegistry(S2.make(ast.types[0]), ctx);
322
+ }
323
+ return toGraphQLType(S2.make(ast));
324
+ }
325
+ function findEnumForLiteralUnion(types, ctx) {
326
+ const literalValues = types.map((t) => String(t.literal)).sort();
327
+ for (const [enumName] of ctx.enums) {
328
+ const enumValues = ctx.enumSortedValues?.get(enumName);
329
+ if (enumValues && literalValues.length === enumValues.length && literalValues.every((v, i) => v === enumValues[i])) {
330
+ return ctx.enumRegistry.get(enumName);
331
+ }
332
+ }
333
+ return void 0;
334
+ }
335
+ function findRegisteredUnion(types, ctx) {
336
+ const memberTags = [];
337
+ for (const memberAst of types) {
338
+ if (memberAst._tag === "TypeLiteral") {
339
+ const tagProp = memberAst.propertySignatures.find((p) => String(p.name) === "_tag");
340
+ if (tagProp && tagProp.type._tag === "Literal") {
341
+ memberTags.push(String(tagProp.type.literal));
342
+ }
343
+ }
344
+ }
345
+ if (memberTags.length === types.length) {
346
+ const sortedTags = memberTags.sort();
347
+ for (const [unionName] of ctx.unions) {
348
+ const unionTypes = ctx.unionSortedTypes?.get(unionName);
349
+ if (unionTypes && sortedTags.length === unionTypes.length && sortedTags.every((tag, i) => tag === unionTypes[i])) {
350
+ return ctx.unionRegistry.get(unionName);
351
+ }
352
+ }
353
+ }
354
+ return void 0;
355
+ }
356
+ function findEnumForLiteral(ast, ctx) {
357
+ const literalValue = String(ast.literal);
358
+ const enumName = ctx.literalToEnumName?.get(literalValue);
359
+ if (enumName) {
360
+ return ctx.enumRegistry.get(enumName);
361
+ }
362
+ return void 0;
363
+ }
364
+ function handleTupleTypeAST(ast, ctx) {
365
+ if (ast.rest && ast.rest.length > 0) {
366
+ const elementSchema = S2.make(ast.rest[0].type);
367
+ const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
368
+ return new GraphQLList(elementType);
369
+ } else if (ast.elements && ast.elements.length > 0) {
370
+ const elementSchema = S2.make(ast.elements[0].type);
371
+ const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
372
+ return new GraphQLList(elementType);
373
+ }
374
+ return toGraphQLType(S2.make(ast));
375
+ }
376
+ function schemaToFields(schema, ctx) {
377
+ let ast = schema.ast;
378
+ if (ast._tag === "Transformation") {
379
+ ast = ast.to;
380
+ }
381
+ if (ast._tag === "Declaration") {
382
+ const typeParams = ast.typeParameters;
383
+ if (typeParams && typeParams.length > 0 && typeParams[0]._tag === "TypeLiteral") {
384
+ ast = typeParams[0];
385
+ }
386
+ }
387
+ if (ast._tag === "TypeLiteral") {
388
+ const fields = {};
389
+ for (const field2 of ast.propertySignatures) {
390
+ const fieldName = String(field2.name);
391
+ const fieldSchema = S2.make(field2.type);
392
+ let fieldType = toGraphQLTypeWithRegistry(fieldSchema, ctx);
393
+ if (!field2.isOptional) {
394
+ fieldType = getNonNull(fieldType);
395
+ }
396
+ fields[fieldName] = { type: fieldType };
397
+ }
398
+ return fields;
399
+ }
400
+ return {};
401
+ }
402
+ function schemaToInputFields(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
403
+ const ast = schema.ast;
404
+ if (ast._tag === "TypeLiteral") {
405
+ const fields = {};
406
+ for (const field2 of ast.propertySignatures) {
407
+ const fieldName = String(field2.name);
408
+ const fieldSchema = S2.make(field2.type);
409
+ let fieldType = toGraphQLInputTypeWithRegistry(
410
+ fieldSchema,
411
+ enumRegistry,
412
+ inputRegistry,
413
+ inputs,
414
+ enums,
415
+ cache
416
+ );
417
+ if (!field2.isOptional) {
418
+ fieldType = getNonNull(fieldType);
419
+ }
420
+ fields[fieldName] = { type: fieldType };
421
+ }
422
+ return fields;
423
+ }
424
+ return {};
425
+ }
426
+ function buildInputTypeLookupCache(inputs, enums) {
427
+ const cache = {
428
+ schemaToInputName: /* @__PURE__ */ new Map(),
429
+ astToInputName: /* @__PURE__ */ new Map(),
430
+ literalToEnumName: /* @__PURE__ */ new Map(),
431
+ enumSortedValues: /* @__PURE__ */ new Map()
432
+ };
433
+ for (const [inputName, inputReg] of inputs) {
434
+ cache.schemaToInputName.set(inputReg.schema, inputName);
435
+ cache.astToInputName.set(inputReg.schema.ast, inputName);
436
+ }
437
+ for (const [enumName, enumReg] of enums) {
438
+ cache.enumSortedValues.set(enumName, [...enumReg.values].sort());
439
+ for (const value of enumReg.values) {
440
+ cache.literalToEnumName.set(value, enumName);
441
+ }
442
+ }
443
+ return cache;
444
+ }
445
+ function toGraphQLInputTypeWithRegistry(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
446
+ const ast = schema.ast;
447
+ if (ast._tag === "Transformation") {
448
+ const toAst = ast.to;
449
+ return toGraphQLInputTypeWithRegistry(
450
+ S2.make(toAst),
451
+ enumRegistry,
452
+ inputRegistry,
453
+ inputs,
454
+ enums,
455
+ cache
456
+ );
457
+ }
458
+ if (cache?.schemaToInputName || cache?.astToInputName) {
459
+ const inputName = cache.schemaToInputName?.get(schema) ?? cache.astToInputName?.get(ast);
460
+ if (inputName) {
461
+ const result = inputRegistry.get(inputName);
462
+ if (result) return result;
463
+ }
464
+ } else {
465
+ for (const [inputName, inputReg] of inputs) {
466
+ if (inputReg.schema.ast === ast || inputReg.schema === schema) {
467
+ const result = inputRegistry.get(inputName);
468
+ if (result) return result;
469
+ }
470
+ }
471
+ }
472
+ if (ast._tag === "Union") {
473
+ const unionAst = ast;
474
+ const nonUndefinedTypes = unionAst.types.filter((t) => t._tag !== "UndefinedKeyword");
475
+ if (nonUndefinedTypes.length === 1 && nonUndefinedTypes[0]._tag === "Union") {
476
+ return toGraphQLInputTypeWithRegistry(
477
+ S2.make(nonUndefinedTypes[0]),
478
+ enumRegistry,
479
+ inputRegistry,
480
+ inputs,
481
+ enums,
482
+ cache
483
+ );
484
+ }
485
+ if (nonUndefinedTypes.length === 1 && nonUndefinedTypes[0]._tag === "TypeLiteral") {
486
+ return toGraphQLInputTypeWithRegistry(
487
+ S2.make(nonUndefinedTypes[0]),
488
+ enumRegistry,
489
+ inputRegistry,
490
+ inputs,
491
+ enums,
492
+ cache
493
+ );
494
+ }
495
+ const allLiterals = unionAst.types.every((t) => t._tag === "Literal");
496
+ if (allLiterals) {
497
+ const literalValues = unionAst.types.map((t) => String(t.literal)).sort();
498
+ for (const [enumName] of enums) {
499
+ const enumValues = cache?.enumSortedValues?.get(enumName) ?? [...enums.get(enumName).values].sort();
500
+ if (literalValues.length === enumValues.length && literalValues.every((v, i) => v === enumValues[i])) {
501
+ const result = enumRegistry.get(enumName);
502
+ if (result) return result;
503
+ }
504
+ }
505
+ }
506
+ }
507
+ if (ast._tag === "Literal") {
508
+ const literalValue = String(ast.literal);
509
+ if (cache?.literalToEnumName) {
510
+ const enumName = cache.literalToEnumName.get(literalValue);
511
+ if (enumName) {
512
+ const result = enumRegistry.get(enumName);
513
+ if (result) return result;
514
+ }
515
+ } else {
516
+ for (const [enumName, enumReg] of enums) {
517
+ if (enumReg.values.includes(literalValue)) {
518
+ const result = enumRegistry.get(enumName);
519
+ if (result) return result;
520
+ }
521
+ }
522
+ }
523
+ }
524
+ if (ast._tag === "Suspend") {
525
+ const innerAst = ast.f();
526
+ return toGraphQLInputTypeWithRegistry(
527
+ S2.make(innerAst),
528
+ enumRegistry,
529
+ inputRegistry,
530
+ inputs,
531
+ enums,
532
+ cache
533
+ );
534
+ }
535
+ return toGraphQLInputType(schema);
536
+ }
537
+ function toGraphQLArgsWithRegistry(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
538
+ const ast = schema.ast;
539
+ if (ast._tag === "TypeLiteral") {
540
+ const args = {};
541
+ for (const field2 of ast.propertySignatures) {
542
+ const fieldName = String(field2.name);
543
+ const fieldSchema = S2.make(field2.type);
544
+ let fieldType = toGraphQLInputTypeWithRegistry(
545
+ fieldSchema,
546
+ enumRegistry,
547
+ inputRegistry,
548
+ inputs,
549
+ enums,
550
+ cache
551
+ );
552
+ if (!field2.isOptional) {
553
+ fieldType = getNonNull(fieldType);
554
+ }
555
+ args[fieldName] = { type: fieldType };
556
+ }
557
+ return args;
558
+ }
559
+ return toGraphQLArgs(schema);
560
+ }
561
+ function applyDirectives(effect, directives, directiveRegistrations) {
562
+ if (!directives) return effect;
563
+ let wrapped = effect;
564
+ for (const directiveApp of directives) {
565
+ const directiveReg = directiveRegistrations.get(directiveApp.name);
566
+ if (directiveReg?.apply) {
567
+ wrapped = directiveReg.apply(directiveApp.args ?? {})(wrapped);
568
+ }
569
+ }
570
+ return wrapped;
571
+ }
572
+ function applyMiddleware(effect, context, middlewares) {
573
+ if (middlewares.length === 0) return effect;
574
+ let wrapped = effect;
575
+ for (let i = middlewares.length - 1; i >= 0; i--) {
576
+ const middleware2 = middlewares[i];
577
+ if (middleware2.match && !middleware2.match(context.info)) {
578
+ continue;
579
+ }
580
+ wrapped = middleware2.apply(wrapped, context);
581
+ }
582
+ return wrapped;
583
+ }
584
+ function buildField(config, ctx) {
585
+ const fieldConfig = {
586
+ type: toGraphQLTypeWithRegistry(config.type, ctx),
587
+ resolve: async (_parent, args, context, info) => {
588
+ let effect = applyDirectives(
589
+ config.resolve(args),
590
+ config.directives,
591
+ ctx.directiveRegistrations
592
+ );
593
+ const middlewareContext = { parent: _parent, args, info };
594
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
595
+ return await Runtime.runPromise(context.runtime)(effect);
596
+ }
597
+ };
598
+ if (config.args) {
599
+ fieldConfig.args = toGraphQLArgsWithRegistry(
600
+ config.args,
601
+ ctx.enumRegistry,
602
+ ctx.inputRegistry,
603
+ ctx.inputs,
604
+ ctx.enums,
605
+ ctx.inputTypeLookupCache
606
+ );
607
+ }
608
+ if (config.description) {
609
+ fieldConfig.description = config.description;
610
+ }
611
+ return fieldConfig;
612
+ }
613
+ function buildObjectField(config, ctx) {
614
+ const fieldConfig = {
615
+ type: toGraphQLTypeWithRegistry(config.type, ctx),
616
+ resolve: async (parent, args, context, info) => {
617
+ let effect = applyDirectives(
618
+ config.resolve(parent, args),
619
+ config.directives,
620
+ ctx.directiveRegistrations
621
+ );
622
+ const middlewareContext = { parent, args, info };
623
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
624
+ return await Runtime.runPromise(context.runtime)(effect);
625
+ }
626
+ };
627
+ if (config.args) {
628
+ fieldConfig.args = toGraphQLArgsWithRegistry(
629
+ config.args,
630
+ ctx.enumRegistry,
631
+ ctx.inputRegistry,
632
+ ctx.inputs,
633
+ ctx.enums,
634
+ ctx.inputTypeLookupCache
635
+ );
636
+ }
637
+ if (config.description) {
638
+ fieldConfig.description = config.description;
639
+ }
640
+ return fieldConfig;
641
+ }
642
+ function buildSubscriptionField(config, ctx) {
643
+ const fieldConfig = {
644
+ type: toGraphQLTypeWithRegistry(config.type, ctx),
645
+ // The subscribe function returns an AsyncIterator
646
+ subscribe: async (_parent, args, context, info) => {
647
+ let subscribeEffect = config.subscribe(args);
648
+ subscribeEffect = applyDirectives(
649
+ subscribeEffect,
650
+ config.directives,
651
+ ctx.directiveRegistrations
652
+ );
653
+ const middlewareContext = { parent: _parent, args, info };
654
+ subscribeEffect = applyMiddleware(subscribeEffect, middlewareContext, ctx.middlewares);
655
+ const stream = await Runtime.runPromise(context.runtime)(subscribeEffect);
656
+ return streamToAsyncIterator(stream, context.runtime);
657
+ },
658
+ // The resolve function transforms each yielded value
659
+ // If no custom resolve is provided, return the payload directly
660
+ resolve: config.resolve ? async (value, args, context, info) => {
661
+ let effect = config.resolve(value, args);
662
+ const middlewareContext = { parent: value, args, info };
663
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
664
+ return await Runtime.runPromise(context.runtime)(effect);
665
+ } : (value) => value
666
+ };
667
+ if (config.args) {
668
+ fieldConfig.args = toGraphQLArgsWithRegistry(
669
+ config.args,
670
+ ctx.enumRegistry,
671
+ ctx.inputRegistry,
672
+ ctx.inputs,
673
+ ctx.enums,
674
+ ctx.inputTypeLookupCache
675
+ );
676
+ }
677
+ if (config.description) {
678
+ fieldConfig.description = config.description;
679
+ }
680
+ return fieldConfig;
681
+ }
682
+ function streamToAsyncIterator(stream, runtime) {
683
+ let queue;
684
+ let fiber;
685
+ let initialized = false;
686
+ let done = false;
687
+ const initialize = async () => {
688
+ if (initialized) return;
689
+ initialized = true;
690
+ queue = await Runtime.runPromise(runtime)(Queue.unbounded());
691
+ fiber = Runtime.runFork(runtime)(
692
+ Effect.ensuring(
693
+ Stream.runForEach(stream, (value) => Queue.offer(queue, Option.some(value))),
694
+ // Signal completion by pushing None
695
+ Queue.offer(queue, Option.none())
696
+ )
697
+ );
698
+ };
699
+ return {
700
+ [Symbol.asyncIterator]() {
701
+ return this;
702
+ },
703
+ async next() {
704
+ await initialize();
705
+ if (done) {
706
+ return { done: true, value: void 0 };
707
+ }
708
+ try {
709
+ const optionValue = await Runtime.runPromise(runtime)(Queue.take(queue));
710
+ if (Option.isNone(optionValue)) {
711
+ done = true;
712
+ return { done: true, value: void 0 };
713
+ }
714
+ return { done: false, value: optionValue.value };
715
+ } catch (error) {
716
+ done = true;
717
+ throw error;
718
+ }
719
+ },
720
+ async return() {
721
+ done = true;
722
+ if (initialized) {
723
+ try {
724
+ await Runtime.runPromise(runtime)(
725
+ Fiber.interrupt(fiber)
726
+ );
727
+ await Runtime.runPromise(runtime)(Queue.shutdown(queue));
728
+ } catch {
729
+ }
730
+ }
731
+ return { done: true, value: void 0 };
732
+ }
733
+ };
734
+ }
735
+
736
+ // src/builder/schema-builder.ts
737
+ function updateState(state, key, value) {
738
+ return { ...state, [key]: value };
739
+ }
740
+ var GraphQLSchemaBuilder = class _GraphQLSchemaBuilder {
741
+ constructor(state) {
742
+ this.state = state;
743
+ }
744
+ pipe() {
745
+ return Pipeable.pipeArguments(this, arguments);
746
+ }
747
+ /**
748
+ * Create an empty schema builder
749
+ */
750
+ static empty = new _GraphQLSchemaBuilder({
751
+ types: /* @__PURE__ */ new Map(),
752
+ interfaces: /* @__PURE__ */ new Map(),
753
+ enums: /* @__PURE__ */ new Map(),
754
+ unions: /* @__PURE__ */ new Map(),
755
+ inputs: /* @__PURE__ */ new Map(),
756
+ directives: /* @__PURE__ */ new Map(),
757
+ middlewares: [],
758
+ extensions: [],
759
+ queries: /* @__PURE__ */ new Map(),
760
+ mutations: /* @__PURE__ */ new Map(),
761
+ subscriptions: /* @__PURE__ */ new Map(),
762
+ objectFields: /* @__PURE__ */ new Map()
763
+ });
764
+ /**
765
+ * Create a new builder with updated state
766
+ */
767
+ with(newState) {
768
+ return new _GraphQLSchemaBuilder(newState);
769
+ }
770
+ // ============================================================================
771
+ // Registration Methods
772
+ // ============================================================================
773
+ /**
774
+ * Add a query field
775
+ */
776
+ query(name, config) {
777
+ const newQueries = new Map(this.state.queries);
778
+ newQueries.set(name, config);
779
+ return this.with(updateState(this.state, "queries", newQueries));
780
+ }
781
+ /**
782
+ * Add a mutation field
783
+ */
784
+ mutation(name, config) {
785
+ const newMutations = new Map(this.state.mutations);
786
+ newMutations.set(name, config);
787
+ return this.with(updateState(this.state, "mutations", newMutations));
788
+ }
789
+ /**
790
+ * Add a subscription field
791
+ *
792
+ * Subscriptions return a Stream that yields values over time.
793
+ * The subscribe function returns an Effect that produces a Stream.
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * builder.subscription("userCreated", {
798
+ * type: User,
799
+ * subscribe: Effect.gen(function*() {
800
+ * const pubsub = yield* PubSubService
801
+ * return pubsub.subscribe("USER_CREATED")
802
+ * }),
803
+ * })
804
+ * ```
805
+ */
806
+ subscription(name, config) {
807
+ const newSubscriptions = new Map(this.state.subscriptions);
808
+ newSubscriptions.set(name, config);
809
+ return this.with(updateState(this.state, "subscriptions", newSubscriptions));
810
+ }
811
+ /**
812
+ * Register an object type from a schema
813
+ */
814
+ objectType(config) {
815
+ const {
816
+ schema,
817
+ description,
818
+ implements: implementsInterfaces,
819
+ directives,
820
+ cacheControl,
821
+ fields
822
+ } = config;
823
+ const name = config.name ?? getSchemaName(schema);
824
+ if (!name) {
825
+ throw new Error(
826
+ "objectType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
827
+ );
828
+ }
829
+ const newTypes = new Map(this.state.types);
830
+ newTypes.set(name, {
831
+ name,
832
+ schema,
833
+ description,
834
+ implements: implementsInterfaces,
835
+ directives,
836
+ cacheControl
837
+ });
838
+ let newObjectFields = this.state.objectFields;
839
+ if (fields) {
840
+ newObjectFields = new Map(this.state.objectFields);
841
+ const typeFields = /* @__PURE__ */ new Map();
842
+ for (const [fieldName, fieldConfig] of Object.entries(fields)) {
843
+ typeFields.set(fieldName, fieldConfig);
844
+ }
845
+ newObjectFields.set(name, typeFields);
846
+ }
847
+ return this.with({
848
+ ...this.state,
849
+ types: newTypes,
850
+ objectFields: newObjectFields
851
+ });
852
+ }
853
+ /**
854
+ * Register an interface type from a schema
855
+ */
856
+ interfaceType(config) {
857
+ const { schema, resolveType, directives } = config;
858
+ const name = config.name ?? getSchemaName(schema);
859
+ if (!name) {
860
+ throw new Error(
861
+ "interfaceType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
862
+ );
863
+ }
864
+ const newInterfaces = new Map(this.state.interfaces);
865
+ newInterfaces.set(name, {
866
+ name,
867
+ schema,
868
+ resolveType: resolveType ?? ((value) => value._tag),
869
+ directives
870
+ });
871
+ return this.with(updateState(this.state, "interfaces", newInterfaces));
872
+ }
873
+ /**
874
+ * Register an enum type
875
+ */
876
+ enumType(config) {
877
+ const { name, values, description, directives } = config;
878
+ const newEnums = new Map(this.state.enums);
879
+ newEnums.set(name, { name, values, description, directives });
880
+ return this.with(updateState(this.state, "enums", newEnums));
881
+ }
882
+ /**
883
+ * Register a union type
884
+ */
885
+ unionType(config) {
886
+ const { name, types, resolveType, directives } = config;
887
+ const newUnions = new Map(this.state.unions);
888
+ newUnions.set(name, {
889
+ name,
890
+ types,
891
+ resolveType: resolveType ?? ((value) => value._tag),
892
+ directives
893
+ });
894
+ return this.with(updateState(this.state, "unions", newUnions));
895
+ }
896
+ /**
897
+ * Register an input type
898
+ */
899
+ inputType(config) {
900
+ const { schema, description, directives } = config;
901
+ const name = config.name ?? getSchemaName(schema);
902
+ if (!name) {
903
+ throw new Error(
904
+ "inputType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
905
+ );
906
+ }
907
+ const newInputs = new Map(this.state.inputs);
908
+ newInputs.set(name, { name, schema, description, directives });
909
+ return this.with(updateState(this.state, "inputs", newInputs));
910
+ }
911
+ /**
912
+ * Register a directive
913
+ */
914
+ directive(config) {
915
+ const newDirectives = new Map(this.state.directives);
916
+ newDirectives.set(config.name, config);
917
+ return this.with(updateState(this.state, "directives", newDirectives));
918
+ }
919
+ /**
920
+ * Register a middleware
921
+ *
922
+ * Middleware wraps all resolvers (or those matching a pattern) and executes
923
+ * in an "onion" model - first registered middleware is the outermost layer.
924
+ *
925
+ * @param config.name - Middleware name (for debugging/logging)
926
+ * @param config.description - Optional description
927
+ * @param config.match - Optional predicate to filter which fields this applies to
928
+ * @param config.apply - Function that transforms the resolver Effect
929
+ *
930
+ * @example
931
+ * ```typescript
932
+ * builder.middleware({
933
+ * name: "logging",
934
+ * apply: (effect, ctx) => Effect.gen(function*() {
935
+ * yield* Effect.logInfo(`Resolving ${ctx.info.fieldName}`)
936
+ * const start = Date.now()
937
+ * const result = yield* effect
938
+ * yield* Effect.logInfo(`Resolved in ${Date.now() - start}ms`)
939
+ * return result
940
+ * })
941
+ * })
942
+ * ```
943
+ */
944
+ middleware(config) {
945
+ const newMiddlewares = [...this.state.middlewares, config];
946
+ return this.with({ ...this.state, middlewares: newMiddlewares });
947
+ }
948
+ /**
949
+ * Register an extension
950
+ *
951
+ * Extensions provide lifecycle hooks that run at each phase of request processing
952
+ * (parse, validate, execute) and can contribute data to the response's extensions field.
953
+ *
954
+ * @param config.name - Extension name (for debugging/logging)
955
+ * @param config.description - Optional description
956
+ * @param config.onParse - Called after query parsing
957
+ * @param config.onValidate - Called after validation
958
+ * @param config.onExecuteStart - Called before execution begins
959
+ * @param config.onExecuteEnd - Called after execution completes
960
+ *
961
+ * @example
962
+ * ```typescript
963
+ * builder.extension({
964
+ * name: "tracing",
965
+ * onExecuteStart: () => Effect.gen(function*() {
966
+ * const ext = yield* ExtensionsService
967
+ * yield* ext.set("tracing", { startTime: Date.now() })
968
+ * }),
969
+ * onExecuteEnd: () => Effect.gen(function*() {
970
+ * const ext = yield* ExtensionsService
971
+ * yield* ext.merge("tracing", { endTime: Date.now() })
972
+ * }),
973
+ * })
974
+ * ```
975
+ */
976
+ extension(config) {
977
+ const newExtensions = [...this.state.extensions, config];
978
+ return this.with({ ...this.state, extensions: newExtensions });
979
+ }
980
+ /**
981
+ * Get the registered extensions for use by the execution layer
982
+ */
983
+ getExtensions() {
984
+ return this.state.extensions;
985
+ }
986
+ /**
987
+ * Add a computed/relational field to an object type
988
+ */
989
+ field(typeName, fieldName, config) {
990
+ const newObjectFields = new Map(this.state.objectFields);
991
+ const typeFields = newObjectFields.get(typeName) || /* @__PURE__ */ new Map();
992
+ typeFields.set(fieldName, config);
993
+ newObjectFields.set(typeName, typeFields);
994
+ return this.with(updateState(this.state, "objectFields", newObjectFields));
995
+ }
996
+ // ============================================================================
997
+ // Schema Building
998
+ // ============================================================================
999
+ /**
1000
+ * Get the field complexity map for use in complexity validation.
1001
+ * Maps "TypeName.fieldName" to the complexity value or function.
1002
+ */
1003
+ getFieldComplexities() {
1004
+ const complexities = /* @__PURE__ */ new Map();
1005
+ for (const [name, config] of this.state.queries) {
1006
+ if (config.complexity !== void 0) {
1007
+ complexities.set(`Query.${name}`, config.complexity);
1008
+ }
1009
+ }
1010
+ for (const [name, config] of this.state.mutations) {
1011
+ if (config.complexity !== void 0) {
1012
+ complexities.set(`Mutation.${name}`, config.complexity);
1013
+ }
1014
+ }
1015
+ for (const [name, config] of this.state.subscriptions) {
1016
+ if (config.complexity !== void 0) {
1017
+ complexities.set(`Subscription.${name}`, config.complexity);
1018
+ }
1019
+ }
1020
+ for (const [typeName, fields] of this.state.objectFields) {
1021
+ for (const [fieldName, config] of fields) {
1022
+ if (config.complexity !== void 0) {
1023
+ complexities.set(`${typeName}.${fieldName}`, config.complexity);
1024
+ }
1025
+ }
1026
+ }
1027
+ return complexities;
1028
+ }
1029
+ /**
1030
+ * Get the cache hint map for use in cache control calculation.
1031
+ * Maps "TypeName.fieldName" to the cache hint for field-level hints,
1032
+ * or "TypeName" to the cache hint for type-level hints.
1033
+ */
1034
+ getCacheHints() {
1035
+ const hints = /* @__PURE__ */ new Map();
1036
+ for (const [typeName, typeReg] of this.state.types) {
1037
+ if (typeReg.cacheControl !== void 0) {
1038
+ hints.set(typeName, typeReg.cacheControl);
1039
+ }
1040
+ }
1041
+ for (const [name, config] of this.state.queries) {
1042
+ if (config.cacheControl !== void 0) {
1043
+ hints.set(`Query.${name}`, config.cacheControl);
1044
+ }
1045
+ }
1046
+ for (const [name, config] of this.state.subscriptions) {
1047
+ if (config.cacheControl !== void 0) {
1048
+ hints.set(`Subscription.${name}`, config.cacheControl);
1049
+ }
1050
+ }
1051
+ for (const [typeName, fields] of this.state.objectFields) {
1052
+ for (const [fieldName, config] of fields) {
1053
+ if (config.cacheControl !== void 0) {
1054
+ hints.set(`${typeName}.${fieldName}`, config.cacheControl);
1055
+ }
1056
+ }
1057
+ }
1058
+ return hints;
1059
+ }
1060
+ /**
1061
+ * Build the GraphQL schema (no services required)
1062
+ */
1063
+ buildSchema() {
1064
+ const directiveRegistry = this.buildDirectiveRegistry();
1065
+ const enumRegistry = this.buildEnumRegistry();
1066
+ const inputRegistry = this.buildInputRegistry(enumRegistry);
1067
+ const interfaceRegistry = this.buildInterfaceRegistry(enumRegistry);
1068
+ const { typeRegistry, unionRegistry } = this.buildTypeAndUnionRegistries(
1069
+ enumRegistry,
1070
+ interfaceRegistry
1071
+ );
1072
+ const fieldCtx = this.createFieldBuilderContext(
1073
+ typeRegistry,
1074
+ interfaceRegistry,
1075
+ enumRegistry,
1076
+ unionRegistry,
1077
+ inputRegistry
1078
+ );
1079
+ const queryFields = this.buildQueryFields(fieldCtx);
1080
+ const mutationFields = this.buildMutationFields(fieldCtx);
1081
+ const subscriptionFields = this.buildSubscriptionFields(fieldCtx);
1082
+ return this.assembleSchema({
1083
+ directiveRegistry,
1084
+ enumRegistry,
1085
+ inputRegistry,
1086
+ interfaceRegistry,
1087
+ typeRegistry,
1088
+ unionRegistry,
1089
+ queryFields,
1090
+ mutationFields,
1091
+ subscriptionFields
1092
+ });
1093
+ }
1094
+ buildDirectiveRegistry() {
1095
+ const registry = /* @__PURE__ */ new Map();
1096
+ const cache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
1097
+ for (const [name, reg] of this.state.directives) {
1098
+ const graphqlDirective = new GraphQLDirective({
1099
+ name,
1100
+ description: reg.description,
1101
+ locations: [...reg.locations],
1102
+ args: reg.args ? toGraphQLArgsWithRegistry(
1103
+ reg.args,
1104
+ /* @__PURE__ */ new Map(),
1105
+ /* @__PURE__ */ new Map(),
1106
+ this.state.inputs,
1107
+ this.state.enums,
1108
+ cache
1109
+ ) : void 0
1110
+ });
1111
+ registry.set(name, graphqlDirective);
1112
+ }
1113
+ return registry;
1114
+ }
1115
+ buildEnumRegistry() {
1116
+ const registry = /* @__PURE__ */ new Map();
1117
+ for (const [name, reg] of this.state.enums) {
1118
+ const enumValues = {};
1119
+ for (const value of reg.values) {
1120
+ enumValues[value] = { value };
1121
+ }
1122
+ registry.set(
1123
+ name,
1124
+ new GraphQLEnumType({
1125
+ name,
1126
+ values: enumValues,
1127
+ description: reg.description,
1128
+ extensions: reg.directives ? { directives: reg.directives } : void 0
1129
+ })
1130
+ );
1131
+ }
1132
+ return registry;
1133
+ }
1134
+ buildInputRegistry(enumRegistry) {
1135
+ const registry = /* @__PURE__ */ new Map();
1136
+ const cache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
1137
+ for (const [name, reg] of this.state.inputs) {
1138
+ const inputType2 = new GraphQLInputObjectType({
1139
+ name,
1140
+ description: reg.description,
1141
+ fields: () => schemaToInputFields(
1142
+ reg.schema,
1143
+ enumRegistry,
1144
+ registry,
1145
+ this.state.inputs,
1146
+ this.state.enums,
1147
+ cache
1148
+ ),
1149
+ extensions: reg.directives ? { directives: reg.directives } : void 0
1150
+ });
1151
+ registry.set(name, inputType2);
1152
+ }
1153
+ return registry;
1154
+ }
1155
+ buildInterfaceRegistry(enumRegistry) {
1156
+ const registry = /* @__PURE__ */ new Map();
1157
+ const typeRegistry = /* @__PURE__ */ new Map();
1158
+ const unionRegistry = /* @__PURE__ */ new Map();
1159
+ const sharedCtx = {
1160
+ types: this.state.types,
1161
+ interfaces: this.state.interfaces,
1162
+ enums: this.state.enums,
1163
+ unions: this.state.unions,
1164
+ inputs: this.state.inputs,
1165
+ typeRegistry,
1166
+ interfaceRegistry: registry,
1167
+ enumRegistry,
1168
+ unionRegistry};
1169
+ buildReverseLookups(sharedCtx);
1170
+ for (const [name, reg] of this.state.interfaces) {
1171
+ const interfaceType2 = new GraphQLInterfaceType({
1172
+ name,
1173
+ fields: () => schemaToFields(reg.schema, sharedCtx),
1174
+ resolveType: reg.resolveType,
1175
+ extensions: reg.directives ? { directives: reg.directives } : void 0
1176
+ });
1177
+ registry.set(name, interfaceType2);
1178
+ }
1179
+ return registry;
1180
+ }
1181
+ buildTypeAndUnionRegistries(enumRegistry, interfaceRegistry) {
1182
+ const typeRegistry = /* @__PURE__ */ new Map();
1183
+ const unionRegistry = /* @__PURE__ */ new Map();
1184
+ const sharedCtx = {
1185
+ types: this.state.types,
1186
+ interfaces: this.state.interfaces,
1187
+ enums: this.state.enums,
1188
+ unions: this.state.unions,
1189
+ inputs: this.state.inputs,
1190
+ typeRegistry,
1191
+ interfaceRegistry,
1192
+ enumRegistry,
1193
+ unionRegistry};
1194
+ buildReverseLookups(sharedCtx);
1195
+ const sharedFieldCtx = this.createFieldBuilderContext(
1196
+ typeRegistry,
1197
+ interfaceRegistry,
1198
+ enumRegistry,
1199
+ unionRegistry,
1200
+ /* @__PURE__ */ new Map()
1201
+ );
1202
+ for (const [typeName, typeReg] of this.state.types) {
1203
+ const implementedInterfaces = typeReg.implements?.map((name) => interfaceRegistry.get(name)).filter(Boolean) ?? [];
1204
+ const graphqlType = new GraphQLObjectType({
1205
+ name: typeName,
1206
+ description: typeReg.description,
1207
+ fields: () => {
1208
+ const baseFields = schemaToFields(typeReg.schema, sharedCtx);
1209
+ const additionalFields = this.state.objectFields.get(typeName);
1210
+ if (additionalFields) {
1211
+ for (const [fieldName, fieldConfig] of additionalFields) {
1212
+ baseFields[fieldName] = buildObjectField(fieldConfig, sharedFieldCtx);
1213
+ }
1214
+ }
1215
+ return baseFields;
1216
+ },
1217
+ interfaces: implementedInterfaces.length > 0 ? implementedInterfaces : void 0,
1218
+ extensions: typeReg.directives ? { directives: typeReg.directives } : void 0
1219
+ });
1220
+ typeRegistry.set(typeName, graphqlType);
1221
+ }
1222
+ for (const [name, reg] of this.state.unions) {
1223
+ const unionType2 = new GraphQLUnionType({
1224
+ name,
1225
+ types: () => reg.types.map((typeName) => typeRegistry.get(typeName)).filter(Boolean),
1226
+ resolveType: reg.resolveType,
1227
+ extensions: reg.directives ? { directives: reg.directives } : void 0
1228
+ });
1229
+ unionRegistry.set(name, unionType2);
1230
+ }
1231
+ return { typeRegistry, unionRegistry };
1232
+ }
1233
+ createFieldBuilderContext(typeRegistry, interfaceRegistry, enumRegistry, unionRegistry, inputRegistry) {
1234
+ const inputTypeLookupCache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
1235
+ return {
1236
+ types: this.state.types,
1237
+ interfaces: this.state.interfaces,
1238
+ enums: this.state.enums,
1239
+ unions: this.state.unions,
1240
+ inputs: this.state.inputs,
1241
+ typeRegistry,
1242
+ interfaceRegistry,
1243
+ enumRegistry,
1244
+ unionRegistry,
1245
+ inputRegistry,
1246
+ directiveRegistrations: this.state.directives,
1247
+ middlewares: this.state.middlewares,
1248
+ inputTypeLookupCache
1249
+ };
1250
+ }
1251
+ buildQueryFields(ctx) {
1252
+ const fields = {};
1253
+ for (const [name, config] of this.state.queries) {
1254
+ fields[name] = buildField(config, ctx);
1255
+ }
1256
+ return fields;
1257
+ }
1258
+ buildMutationFields(ctx) {
1259
+ const fields = {};
1260
+ for (const [name, config] of this.state.mutations) {
1261
+ fields[name] = buildField(config, ctx);
1262
+ }
1263
+ return fields;
1264
+ }
1265
+ buildSubscriptionFields(ctx) {
1266
+ const fields = {};
1267
+ for (const [name, config] of this.state.subscriptions) {
1268
+ fields[name] = buildSubscriptionField(config, ctx);
1269
+ }
1270
+ return fields;
1271
+ }
1272
+ assembleSchema(registries) {
1273
+ const schemaConfig = {
1274
+ types: [
1275
+ ...Array.from(registries.enumRegistry.values()),
1276
+ ...Array.from(registries.inputRegistry.values()),
1277
+ ...Array.from(registries.interfaceRegistry.values()),
1278
+ ...Array.from(registries.typeRegistry.values()),
1279
+ ...Array.from(registries.unionRegistry.values())
1280
+ ],
1281
+ directives: registries.directiveRegistry.size > 0 ? [...Array.from(registries.directiveRegistry.values())] : void 0
1282
+ };
1283
+ if (Object.keys(registries.queryFields).length > 0) {
1284
+ schemaConfig.query = new GraphQLObjectType({
1285
+ name: "Query",
1286
+ fields: registries.queryFields
1287
+ });
1288
+ }
1289
+ if (Object.keys(registries.mutationFields).length > 0) {
1290
+ schemaConfig.mutation = new GraphQLObjectType({
1291
+ name: "Mutation",
1292
+ fields: registries.mutationFields
1293
+ });
1294
+ }
1295
+ if (Object.keys(registries.subscriptionFields).length > 0) {
1296
+ schemaConfig.subscription = new GraphQLObjectType({
1297
+ name: "Subscription",
1298
+ fields: registries.subscriptionFields
1299
+ });
1300
+ }
1301
+ return new GraphQLSchema(schemaConfig);
1302
+ }
1303
+ };
1304
+
1305
+ // src/builder/pipe-api.ts
1306
+ var objectType = (config) => (builder) => builder.objectType(config);
1307
+ var interfaceType = (config) => (builder) => builder.interfaceType(config);
1308
+ var enumType = (config) => (builder) => builder.enumType(config);
1309
+ var unionType = (config) => (builder) => builder.unionType(config);
1310
+ var inputType = (config) => (builder) => builder.inputType(config);
1311
+ var directive = (config) => (builder) => builder.directive(config);
1312
+ var middleware = (config) => (builder) => builder.middleware(config);
1313
+ var extension = (config) => (builder) => builder.extension(config);
1314
+ var query = (name, config) => (builder) => builder.query(name, config);
1315
+ var mutation = (name, config) => (builder) => builder.mutation(name, config);
1316
+ var subscription = (name, config) => (builder) => builder.subscription(name, config);
1317
+ var field = (typeName, fieldName, config) => (builder) => builder.field(typeName, fieldName, config);
1318
+ var compose = (...operations) => (builder) => operations.reduce((b, op) => op(b), builder);
1319
+ var ExtensionsService = Context.GenericTag(
1320
+ "@effect-gql/ExtensionsService"
1321
+ );
1322
+ function deepMerge(target, source) {
1323
+ const result = { ...target };
1324
+ for (const key of Object.keys(source)) {
1325
+ const sourceValue = source[key];
1326
+ const targetValue = result[key];
1327
+ if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
1328
+ result[key] = deepMerge(
1329
+ targetValue,
1330
+ sourceValue
1331
+ );
1332
+ } else {
1333
+ result[key] = sourceValue;
1334
+ }
1335
+ }
1336
+ return result;
1337
+ }
1338
+ var makeExtensionsService = () => Effect.gen(function* () {
1339
+ const ref = yield* Ref.make({});
1340
+ return ExtensionsService.of({
1341
+ set: (key, value) => Ref.update(ref, (current) => ({ ...current, [key]: value })),
1342
+ merge: (key, value) => Ref.update(ref, (current) => {
1343
+ const existing = current[key];
1344
+ if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
1345
+ return {
1346
+ ...current,
1347
+ [key]: deepMerge(existing, value)
1348
+ };
1349
+ }
1350
+ return { ...current, [key]: value };
1351
+ }),
1352
+ get: () => Ref.get(ref)
1353
+ });
1354
+ });
1355
+ var runExtensionHooks = (extensions, hookName, getHookEffect) => Effect.forEach(
1356
+ extensions.filter((ext) => ext[hookName] !== void 0),
1357
+ (ext) => getHookEffect(ext).pipe(
1358
+ Effect.catchAllCause(
1359
+ (cause) => Effect.logWarning(`Extension "${ext.name}" ${String(hookName)} hook failed`, cause)
1360
+ )
1361
+ ),
1362
+ { discard: true }
1363
+ );
1364
+ var runParseHooks = (extensions, source, document) => runExtensionHooks(extensions, "onParse", (ext) => ext.onParse(source, document));
1365
+ var runValidateHooks = (extensions, document, errors) => runExtensionHooks(extensions, "onValidate", (ext) => ext.onValidate(document, errors));
1366
+ var runExecuteStartHooks = (extensions, args) => runExtensionHooks(extensions, "onExecuteStart", (ext) => ext.onExecuteStart(args));
1367
+ var runExecuteEndHooks = (extensions, result) => runExtensionHooks(extensions, "onExecuteEnd", (ext) => ext.onExecuteEnd(result));
1368
+
1369
+ // src/builder/execute.ts
1370
+ var execute = (schema, layer, extensions = [], fieldComplexities = /* @__PURE__ */ new Map()) => (source, variableValues, operationName) => Effect.gen(function* () {
1371
+ const extensionsService = yield* makeExtensionsService();
1372
+ const runtime = yield* Effect.runtime();
1373
+ let document;
1374
+ try {
1375
+ document = parse(source);
1376
+ } catch (parseError) {
1377
+ const extensionData2 = yield* extensionsService.get();
1378
+ return {
1379
+ errors: [
1380
+ parseError instanceof GraphQLError ? parseError : new GraphQLError(String(parseError))
1381
+ ],
1382
+ extensions: Object.keys(extensionData2).length > 0 ? extensionData2 : void 0
1383
+ };
1384
+ }
1385
+ yield* runParseHooks(extensions, source, document).pipe(
1386
+ Effect.provideService(ExtensionsService, extensionsService)
1387
+ );
1388
+ const validationErrors = validate(schema, document);
1389
+ yield* runValidateHooks(extensions, document, validationErrors).pipe(
1390
+ Effect.provideService(ExtensionsService, extensionsService)
1391
+ );
1392
+ if (validationErrors.length > 0) {
1393
+ const extensionData2 = yield* extensionsService.get();
1394
+ return {
1395
+ errors: validationErrors,
1396
+ extensions: Object.keys(extensionData2).length > 0 ? extensionData2 : void 0
1397
+ };
1398
+ }
1399
+ const executionArgs = {
1400
+ source,
1401
+ document,
1402
+ variableValues,
1403
+ operationName,
1404
+ schema,
1405
+ fieldComplexities
1406
+ };
1407
+ yield* runExecuteStartHooks(extensions, executionArgs).pipe(
1408
+ Effect.provideService(ExtensionsService, extensionsService)
1409
+ );
1410
+ const executeResult = yield* Effect.try({
1411
+ try: () => execute$1({
1412
+ schema,
1413
+ document,
1414
+ variableValues,
1415
+ operationName,
1416
+ contextValue: { runtime }
1417
+ }),
1418
+ catch: (error) => new Error(String(error))
1419
+ });
1420
+ const resolvedResult = executeResult && typeof executeResult === "object" && "then" in executeResult ? yield* Effect.promise(() => executeResult) : executeResult;
1421
+ yield* runExecuteEndHooks(extensions, resolvedResult).pipe(
1422
+ Effect.provideService(ExtensionsService, extensionsService)
1423
+ );
1424
+ const extensionData = yield* extensionsService.get();
1425
+ if (Object.keys(extensionData).length > 0) {
1426
+ return {
1427
+ ...resolvedResult,
1428
+ extensions: {
1429
+ ...resolvedResult.extensions,
1430
+ ...extensionData
1431
+ }
1432
+ };
1433
+ }
1434
+ return resolvedResult;
1435
+ }).pipe(Effect.provide(layer));
1436
+ var GraphQLError2 = class extends Data.TaggedError("GraphQLError") {
1437
+ };
1438
+ var ValidationError = class extends Data.TaggedError("ValidationError") {
1439
+ };
1440
+ var AuthorizationError = class extends Data.TaggedError("AuthorizationError") {
1441
+ };
1442
+ var NotFoundError = class extends Data.TaggedError("NotFoundError") {
1443
+ };
1444
+ var GraphQLRequestContext = Context.GenericTag("GraphQLRequestContext");
1445
+ var makeRequestContextLayer = (context) => Layer.succeed(GraphQLRequestContext, context);
1446
+ function single(config) {
1447
+ return {
1448
+ _tag: "single",
1449
+ batch: config.batch,
1450
+ key: config.key
1451
+ };
1452
+ }
1453
+ function grouped(config) {
1454
+ return {
1455
+ _tag: "grouped",
1456
+ batch: config.batch,
1457
+ groupBy: config.groupBy
1458
+ };
1459
+ }
1460
+ var LoaderRegistry = class {
1461
+ constructor(definitions) {
1462
+ this.definitions = definitions;
1463
+ this.Service = Context.GenericTag(
1464
+ `DataLoaders(${Object.keys(definitions).join(", ")})`
1465
+ );
1466
+ }
1467
+ _tag = "LoaderRegistry";
1468
+ /**
1469
+ * The Effect service tag for this loader registry
1470
+ */
1471
+ Service;
1472
+ /**
1473
+ * Create a Layer that provides fresh DataLoader instances.
1474
+ * Call this once per request to get request-scoped loaders.
1475
+ */
1476
+ toLayer() {
1477
+ const self = this;
1478
+ return Layer.effect(
1479
+ this.Service,
1480
+ Effect.gen(function* () {
1481
+ const instances = {};
1482
+ for (const name of Object.keys(self.definitions)) {
1483
+ const def = self.definitions[name];
1484
+ instances[name] = yield* createDataLoader(def);
1485
+ }
1486
+ return instances;
1487
+ })
1488
+ );
1489
+ }
1490
+ /**
1491
+ * Helper to use loaders in a resolver with a callback.
1492
+ */
1493
+ use(fn) {
1494
+ const self = this;
1495
+ return Effect.gen(function* () {
1496
+ const loaders = yield* self.Service;
1497
+ return yield* Effect.promise(() => fn(loaders));
1498
+ });
1499
+ }
1500
+ /**
1501
+ * Load a single value by key.
1502
+ * This is the most common operation in resolvers.
1503
+ *
1504
+ * @internal The internal cast is safe because LoaderInstances<Defs> guarantees
1505
+ * that loaders[name] is a DataLoader with the correct key/value types.
1506
+ */
1507
+ load(name, key) {
1508
+ const self = this;
1509
+ return Effect.gen(function* () {
1510
+ const loaders = yield* self.Service;
1511
+ const loader = loaders[name];
1512
+ return yield* Effect.promise(() => loader.load(key));
1513
+ });
1514
+ }
1515
+ /**
1516
+ * Load multiple values by keys.
1517
+ * All keys are batched into a single request.
1518
+ *
1519
+ * @internal The internal cast is safe because LoaderInstances<Defs> guarantees
1520
+ * that loaders[name] is a DataLoader with the correct key/value types.
1521
+ */
1522
+ loadMany(name, keys) {
1523
+ const self = this;
1524
+ return Effect.gen(function* () {
1525
+ const loaders = yield* self.Service;
1526
+ const loader = loaders[name];
1527
+ const results = yield* Effect.promise(() => loader.loadMany(keys));
1528
+ for (const result of results) {
1529
+ if (result instanceof Error) {
1530
+ return yield* Effect.fail(result);
1531
+ }
1532
+ }
1533
+ return results;
1534
+ });
1535
+ }
1536
+ };
1537
+ function createSingleDataLoader(def, context) {
1538
+ return new DataLoader(async (keys) => {
1539
+ const items = await Effect.runPromise(def.batch(keys).pipe(Effect.provide(context)));
1540
+ return keys.map((key) => {
1541
+ const item = items.find((i) => def.key(i) === key);
1542
+ if (!item) return new Error(`Not found: ${key}`);
1543
+ return item;
1544
+ });
1545
+ });
1546
+ }
1547
+ function createGroupedDataLoader(def, context) {
1548
+ return new DataLoader(async (keys) => {
1549
+ const items = await Effect.runPromise(def.batch(keys).pipe(Effect.provide(context)));
1550
+ const map = /* @__PURE__ */ new Map();
1551
+ for (const item of items) {
1552
+ const key = def.groupBy(item);
1553
+ let arr = map.get(key);
1554
+ if (!arr) {
1555
+ arr = [];
1556
+ map.set(key, arr);
1557
+ }
1558
+ arr.push(item);
1559
+ }
1560
+ return keys.map((key) => map.get(key) ?? []);
1561
+ });
1562
+ }
1563
+ function createDataLoader(def) {
1564
+ return Effect.gen(function* () {
1565
+ const context = yield* Effect.context();
1566
+ if (def._tag === "single") {
1567
+ return createSingleDataLoader(def, context);
1568
+ } else {
1569
+ return createGroupedDataLoader(def, context);
1570
+ }
1571
+ });
1572
+ }
1573
+ function define(definitions) {
1574
+ return new LoaderRegistry(definitions);
1575
+ }
1576
+ function mapByKey(keys, items, keyFn) {
1577
+ const map = /* @__PURE__ */ new Map();
1578
+ for (const item of items) {
1579
+ map.set(keyFn(item), item);
1580
+ }
1581
+ return keys.map((key) => map.get(key) ?? new Error(`Not found: ${key}`));
1582
+ }
1583
+ function groupByKey(keys, items, keyFn) {
1584
+ const map = /* @__PURE__ */ new Map();
1585
+ for (const key of keys) {
1586
+ map.set(key, []);
1587
+ }
1588
+ for (const item of items) {
1589
+ const key = keyFn(item);
1590
+ const arr = map.get(key);
1591
+ if (arr) arr.push(item);
1592
+ }
1593
+ return map;
1594
+ }
1595
+ var Loader = {
1596
+ define,
1597
+ single,
1598
+ grouped,
1599
+ mapByKey,
1600
+ groupByKey
1601
+ };
1602
+ var MissingResolverContextError = class extends Error {
1603
+ constructor(contextName) {
1604
+ super(
1605
+ `Resolver context "${contextName}" was not provided. Ensure a parent resolver or directive provides this context.`
1606
+ );
1607
+ this.contextName = contextName;
1608
+ this.name = "MissingResolverContextError";
1609
+ }
1610
+ _tag = "MissingResolverContextError";
1611
+ };
1612
+ var ResolverContextStore = Context.GenericTag(
1613
+ "effect-gql/ResolverContextStore"
1614
+ );
1615
+ var makeStoreLayer = () => Effect.map(
1616
+ Ref.make(HashMap.empty()),
1617
+ (ref) => Layer.succeed(ResolverContextStore, { ref })
1618
+ );
1619
+ var storeLayer = Layer.effect(
1620
+ ResolverContextStore,
1621
+ Effect.map(Ref.make(HashMap.empty()), (ref) => ({ ref }))
1622
+ );
1623
+ var make3 = (name) => ({
1624
+ _tag: "ResolverContextSlot",
1625
+ name,
1626
+ _A: void 0
1627
+ });
1628
+ var get = (slot) => Effect.flatMap(
1629
+ ResolverContextStore,
1630
+ (store) => Effect.flatMap(Ref.get(store.ref), (map) => {
1631
+ const value = HashMap.get(map, slot.name);
1632
+ return Option.match(value, {
1633
+ onNone: () => Effect.fail(new MissingResolverContextError(slot.name)),
1634
+ onSome: (v) => Effect.succeed(v)
1635
+ });
1636
+ })
1637
+ );
1638
+ var getOption = (slot) => Effect.flatMap(
1639
+ ResolverContextStore,
1640
+ (store) => Effect.map(Ref.get(store.ref), (map) => HashMap.get(map, slot.name))
1641
+ );
1642
+ var set = (slot, value) => Effect.flatMap(
1643
+ ResolverContextStore,
1644
+ (store) => Ref.update(store.ref, (map) => HashMap.set(map, slot.name, value))
1645
+ );
1646
+ var setMany = (values) => Effect.flatMap(
1647
+ ResolverContextStore,
1648
+ (store) => Ref.update(store.ref, (map) => {
1649
+ let result = map;
1650
+ for (const [slot, value] of values) {
1651
+ result = HashMap.set(result, slot.name, value);
1652
+ }
1653
+ return result;
1654
+ })
1655
+ );
1656
+ var has = (slot) => Effect.flatMap(
1657
+ ResolverContextStore,
1658
+ (store) => Effect.map(Ref.get(store.ref), (map) => HashMap.has(map, slot.name))
1659
+ );
1660
+ var getOrElse = (slot, orElse) => Effect.flatMap(
1661
+ ResolverContextStore,
1662
+ (store) => Effect.map(
1663
+ Ref.get(store.ref),
1664
+ (map) => Option.getOrElse(HashMap.get(map, slot.name), orElse)
1665
+ )
1666
+ );
1667
+ var scoped = (slot, value) => (effect) => Effect.flatMap(
1668
+ ResolverContextStore,
1669
+ (store) => Effect.acquireUseRelease(
1670
+ // Acquire: save current value and set new one
1671
+ Effect.flatMap(Ref.get(store.ref), (map) => {
1672
+ const previous = HashMap.get(map, slot.name);
1673
+ return Effect.as(Ref.set(store.ref, HashMap.set(map, slot.name, value)), previous);
1674
+ }),
1675
+ // Use: run the effect
1676
+ () => effect,
1677
+ // Release: restore previous value
1678
+ (previous) => Ref.update(
1679
+ store.ref,
1680
+ (map) => Option.match(previous, {
1681
+ onNone: () => HashMap.remove(map, slot.name),
1682
+ onSome: (v) => HashMap.set(map, slot.name, v)
1683
+ })
1684
+ )
1685
+ )
1686
+ );
1687
+ var ResolverContext = {
1688
+ make: make3,
1689
+ get,
1690
+ getOption,
1691
+ set,
1692
+ setMany,
1693
+ has,
1694
+ getOrElse,
1695
+ scoped,
1696
+ storeLayer,
1697
+ makeStoreLayer,
1698
+ Store: ResolverContextStore,
1699
+ MissingResolverContextError
1700
+ };
1701
+ var defaultConfig = {
1702
+ path: "/graphql",
1703
+ graphiql: false,
1704
+ complexity: void 0,
1705
+ introspection: true,
1706
+ cacheControl: void 0
1707
+ };
1708
+ var normalizeConfig = (input = {}) => {
1709
+ const path = input.path ?? defaultConfig.path;
1710
+ let graphiql = false;
1711
+ if (input.graphiql === true) {
1712
+ graphiql = { path: "/graphiql", endpoint: path };
1713
+ } else if (input.graphiql && typeof input.graphiql === "object") {
1714
+ graphiql = {
1715
+ path: input.graphiql.path ?? "/graphiql",
1716
+ endpoint: input.graphiql.endpoint ?? path
1717
+ };
1718
+ }
1719
+ return {
1720
+ path,
1721
+ graphiql,
1722
+ complexity: input.complexity,
1723
+ introspection: input.introspection ?? true,
1724
+ cacheControl: input.cacheControl
1725
+ };
1726
+ };
1727
+ var GraphQLRouterConfigFromEnv = Config.all({
1728
+ path: Config.string("GRAPHQL_PATH").pipe(Config.withDefault("/graphql")),
1729
+ introspection: Config.boolean("GRAPHQL_INTROSPECTION").pipe(Config.withDefault(true)),
1730
+ graphiqlEnabled: Config.boolean("GRAPHIQL_ENABLED").pipe(Config.withDefault(false)),
1731
+ graphiqlPath: Config.string("GRAPHIQL_PATH").pipe(Config.withDefault("/graphiql")),
1732
+ graphiqlEndpoint: Config.string("GRAPHIQL_ENDPOINT").pipe(Config.option),
1733
+ maxDepth: Config.number("GRAPHQL_MAX_DEPTH").pipe(Config.option),
1734
+ maxComplexity: Config.number("GRAPHQL_MAX_COMPLEXITY").pipe(Config.option),
1735
+ maxAliases: Config.number("GRAPHQL_MAX_ALIASES").pipe(Config.option),
1736
+ maxFields: Config.number("GRAPHQL_MAX_FIELDS").pipe(Config.option),
1737
+ defaultFieldComplexity: Config.number("GRAPHQL_DEFAULT_FIELD_COMPLEXITY").pipe(
1738
+ Config.withDefault(1)
1739
+ ),
1740
+ cacheControlEnabled: Config.boolean("GRAPHQL_CACHE_CONTROL_ENABLED").pipe(
1741
+ Config.withDefault(false)
1742
+ ),
1743
+ cacheControlDefaultMaxAge: Config.number("GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE").pipe(
1744
+ Config.withDefault(0)
1745
+ ),
1746
+ cacheControlDefaultScope: Config.string("GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE").pipe(
1747
+ Config.withDefault("PUBLIC")
1748
+ )
1749
+ }).pipe(
1750
+ Config.map(
1751
+ ({
1752
+ path,
1753
+ introspection,
1754
+ graphiqlEnabled,
1755
+ graphiqlPath,
1756
+ graphiqlEndpoint,
1757
+ maxDepth,
1758
+ maxComplexity,
1759
+ maxAliases,
1760
+ maxFields,
1761
+ defaultFieldComplexity,
1762
+ cacheControlEnabled,
1763
+ cacheControlDefaultMaxAge,
1764
+ cacheControlDefaultScope
1765
+ }) => {
1766
+ const hasComplexity = Option.isSome(maxDepth) || Option.isSome(maxComplexity) || Option.isSome(maxAliases) || Option.isSome(maxFields);
1767
+ return {
1768
+ path,
1769
+ introspection,
1770
+ graphiql: graphiqlEnabled ? {
1771
+ path: graphiqlPath,
1772
+ endpoint: Option.isSome(graphiqlEndpoint) ? graphiqlEndpoint.value : path
1773
+ } : false,
1774
+ complexity: hasComplexity ? {
1775
+ maxDepth: Option.getOrUndefined(maxDepth),
1776
+ maxComplexity: Option.getOrUndefined(maxComplexity),
1777
+ maxAliases: Option.getOrUndefined(maxAliases),
1778
+ maxFields: Option.getOrUndefined(maxFields),
1779
+ defaultFieldComplexity
1780
+ } : void 0,
1781
+ cacheControl: cacheControlEnabled ? {
1782
+ enabled: true,
1783
+ defaultMaxAge: cacheControlDefaultMaxAge,
1784
+ defaultScope: cacheControlDefaultScope === "PRIVATE" ? "PRIVATE" : "PUBLIC",
1785
+ calculateHttpHeaders: true
1786
+ } : void 0
1787
+ };
1788
+ }
1789
+ )
1790
+ );
1791
+
1792
+ // src/server/graphiql.ts
1793
+ var graphiqlHtml = (endpoint, subscriptionEndpoint) => `<!DOCTYPE html>
1794
+ <html lang="en">
1795
+ <head>
1796
+ <meta charset="utf-8" />
1797
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
1798
+ <title>GraphiQL</title>
1799
+ <link
1800
+ rel="stylesheet"
1801
+ href="https://unpkg.com/graphiql@3/graphiql.min.css"
1802
+ />
1803
+ </head>
1804
+ <body style="margin: 0; overflow: hidden;">
1805
+ <div id="graphiql" style="height: 100vh;"></div>
1806
+ <script
1807
+ crossorigin
1808
+ src="https://unpkg.com/react@18/umd/react.production.min.js"
1809
+ ></script>
1810
+ <script
1811
+ crossorigin
1812
+ src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
1813
+ ></script>
1814
+ <script
1815
+ crossorigin
1816
+ src="https://unpkg.com/graphiql@3/graphiql.min.js"
1817
+ ></script>
1818
+ <script>
1819
+ const fetcher = GraphiQL.createFetcher({
1820
+ url: ${JSON.stringify(endpoint)},
1821
+ subscriptionUrl: ${JSON.stringify(subscriptionEndpoint ?? endpoint)},
1822
+ });
1823
+ ReactDOM.createRoot(document.getElementById('graphiql')).render(
1824
+ React.createElement(GraphiQL, { fetcher })
1825
+ );
1826
+ </script>
1827
+ </body>
1828
+ </html>`;
1829
+ var ComplexityLimitExceededError = class extends Data.TaggedError("ComplexityLimitExceededError") {
1830
+ };
1831
+ var ComplexityAnalysisError = class extends Data.TaggedError("ComplexityAnalysisError") {
1832
+ };
1833
+ var defaultComplexityCalculator = (defaultCost = 1) => {
1834
+ return (info) => Effect.try({
1835
+ try: () => {
1836
+ const fragments = /* @__PURE__ */ new Map();
1837
+ for (const definition of info.document.definitions) {
1838
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
1839
+ fragments.set(definition.name.value, definition);
1840
+ }
1841
+ }
1842
+ const rootType = getRootType(info.schema, info.operation.operation);
1843
+ if (!rootType) {
1844
+ throw new Error(`No root type found for operation: ${info.operation.operation}`);
1845
+ }
1846
+ const result = analyzeSelectionSet(
1847
+ info.operation.selectionSet,
1848
+ rootType,
1849
+ info.schema,
1850
+ fragments,
1851
+ info.fieldComplexities,
1852
+ info.variables ?? {},
1853
+ defaultCost,
1854
+ 1,
1855
+ // Starting depth
1856
+ /* @__PURE__ */ new Set()
1857
+ // Visited fragments to prevent infinite loops
1858
+ );
1859
+ return result;
1860
+ },
1861
+ catch: (error) => new ComplexityAnalysisError({
1862
+ message: `Failed to analyze query complexity: ${error}`,
1863
+ cause: error
1864
+ })
1865
+ });
1866
+ };
1867
+ function getRootType(schema, operation) {
1868
+ switch (operation) {
1869
+ case "query":
1870
+ return schema.getQueryType() ?? null;
1871
+ case "mutation":
1872
+ return schema.getMutationType() ?? null;
1873
+ case "subscription":
1874
+ return schema.getSubscriptionType() ?? null;
1875
+ }
1876
+ }
1877
+ function getNamedType(type) {
1878
+ if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {
1879
+ return getNamedType(type.ofType);
1880
+ }
1881
+ if (type instanceof GraphQLObjectType) {
1882
+ return type;
1883
+ }
1884
+ return null;
1885
+ }
1886
+ function accumulateResult(acc, result) {
1887
+ acc.maxDepth = Math.max(acc.maxDepth, result.depth);
1888
+ acc.complexity += result.complexity;
1889
+ acc.fieldCount += result.fieldCount;
1890
+ acc.aliasCount += result.aliasCount;
1891
+ }
1892
+ function analyzeSelectionSet(selectionSet, parentType, schema, fragments, fieldComplexities, variables, defaultCost, currentDepth, visitedFragments) {
1893
+ const ctx = { schema, fragments, fieldComplexities, variables, defaultCost };
1894
+ const acc = { maxDepth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 };
1895
+ for (const selection of selectionSet.selections) {
1896
+ const result = analyzeSelection(selection, parentType, ctx, currentDepth, visitedFragments);
1897
+ accumulateResult(acc, result);
1898
+ }
1899
+ return {
1900
+ depth: acc.maxDepth,
1901
+ complexity: acc.complexity,
1902
+ fieldCount: acc.fieldCount,
1903
+ aliasCount: acc.aliasCount
1904
+ };
1905
+ }
1906
+ function analyzeSelection(selection, parentType, ctx, currentDepth, visitedFragments) {
1907
+ switch (selection.kind) {
1908
+ case Kind.FIELD:
1909
+ return analyzeField(selection, parentType, ctx, currentDepth, visitedFragments);
1910
+ case Kind.FRAGMENT_SPREAD:
1911
+ return analyzeFragmentSpread(selection, ctx, currentDepth, visitedFragments);
1912
+ case Kind.INLINE_FRAGMENT:
1913
+ return analyzeInlineFragment(selection, parentType, ctx, currentDepth, visitedFragments);
1914
+ }
1915
+ }
1916
+ function analyzeField(field2, parentType, ctx, currentDepth, visitedFragments) {
1917
+ const fieldName = field2.name.value;
1918
+ const aliasCount = field2.alias ? 1 : 0;
1919
+ if (fieldName.startsWith("__")) {
1920
+ return { depth: currentDepth, complexity: 0, fieldCount: 1, aliasCount };
1921
+ }
1922
+ const schemaField = parentType.getFields()[fieldName];
1923
+ if (!schemaField) {
1924
+ return { depth: currentDepth, complexity: ctx.defaultCost, fieldCount: 1, aliasCount };
1925
+ }
1926
+ const args = resolveFieldArguments(field2, ctx.variables);
1927
+ const complexityKey = `${parentType.name}.${fieldName}`;
1928
+ const fieldComplexity = ctx.fieldComplexities.get(complexityKey);
1929
+ const cost = fieldComplexity !== void 0 ? typeof fieldComplexity === "function" ? fieldComplexity(args) : fieldComplexity : ctx.defaultCost;
1930
+ if (field2.selectionSet) {
1931
+ const fieldType = getNamedType(schemaField.type);
1932
+ if (fieldType) {
1933
+ const nestedResult = analyzeSelectionSet(
1934
+ field2.selectionSet,
1935
+ fieldType,
1936
+ ctx.schema,
1937
+ ctx.fragments,
1938
+ ctx.fieldComplexities,
1939
+ ctx.variables,
1940
+ ctx.defaultCost,
1941
+ currentDepth + 1,
1942
+ visitedFragments
1943
+ );
1944
+ return {
1945
+ depth: nestedResult.depth,
1946
+ complexity: cost + nestedResult.complexity,
1947
+ fieldCount: 1 + nestedResult.fieldCount,
1948
+ aliasCount: aliasCount + nestedResult.aliasCount
1949
+ };
1950
+ }
1951
+ }
1952
+ return { depth: currentDepth, complexity: cost, fieldCount: 1, aliasCount };
1953
+ }
1954
+ function analyzeFragmentSpread(spread, ctx, currentDepth, visitedFragments) {
1955
+ const fragmentName = spread.name.value;
1956
+ if (visitedFragments.has(fragmentName)) {
1957
+ return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 };
1958
+ }
1959
+ const fragment = ctx.fragments.get(fragmentName);
1960
+ if (!fragment) {
1961
+ return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 };
1962
+ }
1963
+ const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value);
1964
+ if (!(fragmentType instanceof GraphQLObjectType)) {
1965
+ return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 };
1966
+ }
1967
+ const newVisited = new Set(visitedFragments);
1968
+ newVisited.add(fragmentName);
1969
+ return analyzeSelectionSet(
1970
+ fragment.selectionSet,
1971
+ fragmentType,
1972
+ ctx.schema,
1973
+ ctx.fragments,
1974
+ ctx.fieldComplexities,
1975
+ ctx.variables,
1976
+ ctx.defaultCost,
1977
+ currentDepth,
1978
+ newVisited
1979
+ );
1980
+ }
1981
+ function analyzeInlineFragment(fragment, parentType, ctx, currentDepth, visitedFragments) {
1982
+ let targetType = parentType;
1983
+ if (fragment.typeCondition) {
1984
+ const conditionType = ctx.schema.getType(fragment.typeCondition.name.value);
1985
+ if (conditionType instanceof GraphQLObjectType) {
1986
+ targetType = conditionType;
1987
+ }
1988
+ }
1989
+ return analyzeSelectionSet(
1990
+ fragment.selectionSet,
1991
+ targetType,
1992
+ ctx.schema,
1993
+ ctx.fragments,
1994
+ ctx.fieldComplexities,
1995
+ ctx.variables,
1996
+ ctx.defaultCost,
1997
+ currentDepth,
1998
+ visitedFragments
1999
+ );
2000
+ }
2001
+ function resolveFieldArguments(field2, variables) {
2002
+ const args = {};
2003
+ if (!field2.arguments) {
2004
+ return args;
2005
+ }
2006
+ for (const arg of field2.arguments) {
2007
+ const value = arg.value;
2008
+ switch (value.kind) {
2009
+ case Kind.VARIABLE:
2010
+ args[arg.name.value] = variables[value.name.value];
2011
+ break;
2012
+ case Kind.INT:
2013
+ args[arg.name.value] = parseInt(value.value, 10);
2014
+ break;
2015
+ case Kind.FLOAT:
2016
+ args[arg.name.value] = parseFloat(value.value);
2017
+ break;
2018
+ case Kind.STRING:
2019
+ args[arg.name.value] = value.value;
2020
+ break;
2021
+ case Kind.BOOLEAN:
2022
+ args[arg.name.value] = value.value;
2023
+ break;
2024
+ case Kind.NULL:
2025
+ args[arg.name.value] = null;
2026
+ break;
2027
+ case Kind.ENUM:
2028
+ args[arg.name.value] = value.value;
2029
+ break;
2030
+ case Kind.LIST:
2031
+ args[arg.name.value] = [];
2032
+ break;
2033
+ case Kind.OBJECT:
2034
+ args[arg.name.value] = {};
2035
+ break;
2036
+ }
2037
+ }
2038
+ return args;
2039
+ }
2040
+ var validateComplexity = (query2, operationName, variables, schema, fieldComplexities, config) => Effect.gen(function* () {
2041
+ const document = yield* Effect.try({
2042
+ try: () => parse(query2),
2043
+ catch: (error) => new ComplexityAnalysisError({
2044
+ message: `Failed to parse query: ${error}`,
2045
+ cause: error
2046
+ })
2047
+ });
2048
+ const operation = yield* Effect.try({
2049
+ try: () => {
2050
+ const operations = document.definitions.filter(
2051
+ (d) => d.kind === Kind.OPERATION_DEFINITION
2052
+ );
2053
+ if (operations.length === 0) {
2054
+ throw new Error("No operation found in query");
2055
+ }
2056
+ if (operationName) {
2057
+ const op = operations.find((o) => o.name?.value === operationName);
2058
+ if (!op) {
2059
+ throw new Error(`Operation "${operationName}" not found`);
2060
+ }
2061
+ return op;
2062
+ }
2063
+ if (operations.length > 1) {
2064
+ throw new Error("Multiple operations found - operationName required");
2065
+ }
2066
+ return operations[0];
2067
+ },
2068
+ catch: (error) => new ComplexityAnalysisError({
2069
+ message: String(error),
2070
+ cause: error
2071
+ })
2072
+ });
2073
+ const calculator = config.calculator ?? defaultComplexityCalculator(config.defaultFieldComplexity ?? 1);
2074
+ const result = yield* calculator({
2075
+ document,
2076
+ operation,
2077
+ variables,
2078
+ schema,
2079
+ fieldComplexities
2080
+ });
2081
+ const checkLimit = (limitType, limit, actual) => Effect.gen(function* () {
2082
+ if (limit !== void 0 && actual > limit) {
2083
+ const exceededInfo = {
2084
+ result,
2085
+ exceededLimit: limitType,
2086
+ limit,
2087
+ actual,
2088
+ query: query2,
2089
+ operationName
2090
+ };
2091
+ if (config.onExceeded) {
2092
+ yield* config.onExceeded(exceededInfo);
2093
+ }
2094
+ yield* Effect.fail(
2095
+ new ComplexityLimitExceededError({
2096
+ message: `Query ${limitType} of ${actual} exceeds maximum allowed ${limitType} of ${limit}`,
2097
+ limit,
2098
+ actual,
2099
+ limitType
2100
+ })
2101
+ );
2102
+ }
2103
+ });
2104
+ yield* checkLimit("depth", config.maxDepth, result.depth);
2105
+ yield* checkLimit("complexity", config.maxComplexity, result.complexity);
2106
+ yield* checkLimit("aliases", config.maxAliases, result.aliasCount);
2107
+ yield* checkLimit("fields", config.maxFields, result.fieldCount);
2108
+ return result;
2109
+ });
2110
+ var ComplexityConfigFromEnv = Config.all({
2111
+ maxDepth: Config.number("GRAPHQL_MAX_DEPTH").pipe(Config.option),
2112
+ maxComplexity: Config.number("GRAPHQL_MAX_COMPLEXITY").pipe(Config.option),
2113
+ maxAliases: Config.number("GRAPHQL_MAX_ALIASES").pipe(Config.option),
2114
+ maxFields: Config.number("GRAPHQL_MAX_FIELDS").pipe(Config.option),
2115
+ defaultFieldComplexity: Config.number("GRAPHQL_DEFAULT_FIELD_COMPLEXITY").pipe(
2116
+ Config.withDefault(1)
2117
+ )
2118
+ }).pipe(
2119
+ Config.map(({ maxDepth, maxComplexity, maxAliases, maxFields, defaultFieldComplexity }) => ({
2120
+ maxDepth: Option.getOrUndefined(maxDepth),
2121
+ maxComplexity: Option.getOrUndefined(maxComplexity),
2122
+ maxAliases: Option.getOrUndefined(maxAliases),
2123
+ maxFields: Option.getOrUndefined(maxFields),
2124
+ defaultFieldComplexity
2125
+ }))
2126
+ );
2127
+ var depthOnlyCalculator = (info) => Effect.try({
2128
+ try: () => {
2129
+ const fragments = /* @__PURE__ */ new Map();
2130
+ for (const definition of info.document.definitions) {
2131
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
2132
+ fragments.set(definition.name.value, definition);
2133
+ }
2134
+ }
2135
+ const depth = calculateMaxDepth(info.operation.selectionSet, fragments, 1, /* @__PURE__ */ new Set());
2136
+ return {
2137
+ depth,
2138
+ complexity: 0,
2139
+ fieldCount: 0,
2140
+ aliasCount: 0
2141
+ };
2142
+ },
2143
+ catch: (error) => new ComplexityAnalysisError({
2144
+ message: `Failed to analyze query depth: ${error}`,
2145
+ cause: error
2146
+ })
2147
+ });
2148
+ function calculateMaxDepth(selectionSet, fragments, currentDepth, visitedFragments) {
2149
+ let maxDepth = currentDepth;
2150
+ for (const selection of selectionSet.selections) {
2151
+ switch (selection.kind) {
2152
+ case Kind.FIELD:
2153
+ if (selection.selectionSet) {
2154
+ const nestedDepth = calculateMaxDepth(
2155
+ selection.selectionSet,
2156
+ fragments,
2157
+ currentDepth + 1,
2158
+ visitedFragments
2159
+ );
2160
+ maxDepth = Math.max(maxDepth, nestedDepth);
2161
+ }
2162
+ break;
2163
+ case Kind.FRAGMENT_SPREAD: {
2164
+ const fragmentName = selection.name.value;
2165
+ if (!visitedFragments.has(fragmentName)) {
2166
+ const fragment = fragments.get(fragmentName);
2167
+ if (fragment) {
2168
+ const newVisited = new Set(visitedFragments);
2169
+ newVisited.add(fragmentName);
2170
+ const fragmentDepth = calculateMaxDepth(
2171
+ fragment.selectionSet,
2172
+ fragments,
2173
+ currentDepth,
2174
+ newVisited
2175
+ );
2176
+ maxDepth = Math.max(maxDepth, fragmentDepth);
2177
+ }
2178
+ }
2179
+ break;
2180
+ }
2181
+ case Kind.INLINE_FRAGMENT: {
2182
+ const inlineDepth = calculateMaxDepth(
2183
+ selection.selectionSet,
2184
+ fragments,
2185
+ currentDepth,
2186
+ visitedFragments
2187
+ );
2188
+ maxDepth = Math.max(maxDepth, inlineDepth);
2189
+ break;
2190
+ }
2191
+ }
2192
+ }
2193
+ return maxDepth;
2194
+ }
2195
+ var combineCalculators = (...calculators) => {
2196
+ return (info) => Effect.gen(function* () {
2197
+ let maxDepth = 0;
2198
+ let maxComplexity = 0;
2199
+ let maxFieldCount = 0;
2200
+ let maxAliasCount = 0;
2201
+ for (const calculator of calculators) {
2202
+ const result = yield* calculator(info);
2203
+ maxDepth = Math.max(maxDepth, result.depth);
2204
+ maxComplexity = Math.max(maxComplexity, result.complexity);
2205
+ maxFieldCount = Math.max(maxFieldCount, result.fieldCount);
2206
+ maxAliasCount = Math.max(maxAliasCount, result.aliasCount);
2207
+ }
2208
+ return {
2209
+ depth: maxDepth,
2210
+ complexity: maxComplexity,
2211
+ fieldCount: maxFieldCount,
2212
+ aliasCount: maxAliasCount
2213
+ };
2214
+ });
2215
+ };
2216
+ var computeCachePolicy = (info) => Effect.sync(() => {
2217
+ const fragments = /* @__PURE__ */ new Map();
2218
+ for (const definition of info.document.definitions) {
2219
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
2220
+ fragments.set(definition.name.value, definition);
2221
+ }
2222
+ }
2223
+ const rootType = getRootType2(info.schema, info.operation.operation);
2224
+ if (!rootType) {
2225
+ return { maxAge: 0, scope: "PUBLIC" };
2226
+ }
2227
+ const defaultMaxAge = info.config.defaultMaxAge ?? 0;
2228
+ const defaultScope = info.config.defaultScope ?? "PUBLIC";
2229
+ const result = analyzeSelectionSet2(
2230
+ info.operation.selectionSet,
2231
+ rootType,
2232
+ info.schema,
2233
+ fragments,
2234
+ info.cacheHints,
2235
+ defaultMaxAge,
2236
+ defaultScope,
2237
+ void 0,
2238
+ // No parent maxAge for root
2239
+ /* @__PURE__ */ new Set()
2240
+ );
2241
+ return result;
2242
+ });
2243
+ var computeCachePolicyFromQuery = (query2, operationName, schema, cacheHints, config = {}) => Effect.gen(function* () {
2244
+ const document = yield* Effect.try({
2245
+ try: () => parse(query2),
2246
+ catch: (error) => new Error(`Failed to parse query: ${error}`)
2247
+ });
2248
+ const operation = yield* Effect.try({
2249
+ try: () => {
2250
+ const operations = document.definitions.filter(
2251
+ (d) => d.kind === Kind.OPERATION_DEFINITION
2252
+ );
2253
+ if (operations.length === 0) {
2254
+ throw new Error("No operation found in query");
2255
+ }
2256
+ if (operationName) {
2257
+ const op = operations.find((o) => o.name?.value === operationName);
2258
+ if (!op) {
2259
+ throw new Error(`Operation "${operationName}" not found`);
2260
+ }
2261
+ return op;
2262
+ }
2263
+ if (operations.length > 1) {
2264
+ throw new Error("Multiple operations found - operationName required");
2265
+ }
2266
+ return operations[0];
2267
+ },
2268
+ catch: (error) => error
2269
+ });
2270
+ return yield* computeCachePolicy({
2271
+ document,
2272
+ operation,
2273
+ schema,
2274
+ cacheHints,
2275
+ config
2276
+ });
2277
+ });
2278
+ var toCacheControlHeader = (policy) => {
2279
+ if (policy.maxAge === 0) {
2280
+ return "no-store";
2281
+ }
2282
+ const directives = [];
2283
+ directives.push(policy.scope === "PRIVATE" ? "private" : "public");
2284
+ directives.push(`max-age=${policy.maxAge}`);
2285
+ return directives.join(", ");
2286
+ };
2287
+ function getRootType2(schema, operation) {
2288
+ switch (operation) {
2289
+ case "query":
2290
+ return schema.getQueryType() ?? null;
2291
+ case "mutation":
2292
+ return schema.getMutationType() ?? null;
2293
+ case "subscription":
2294
+ return schema.getSubscriptionType() ?? null;
2295
+ }
2296
+ }
2297
+ function getNamedType2(type) {
2298
+ if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {
2299
+ return getNamedType2(type.ofType);
2300
+ }
2301
+ if (type instanceof GraphQLObjectType || type instanceof GraphQLScalarType || type instanceof GraphQLEnumType) {
2302
+ return type;
2303
+ }
2304
+ return null;
2305
+ }
2306
+ function isLeafType(type) {
2307
+ const namedType = getNamedType2(type);
2308
+ return namedType instanceof GraphQLScalarType || namedType instanceof GraphQLEnumType;
2309
+ }
2310
+ function aggregatePolicy(acc, policy) {
2311
+ if (acc.minMaxAge === void 0) {
2312
+ acc.minMaxAge = policy.maxAge;
2313
+ } else {
2314
+ acc.minMaxAge = Math.min(acc.minMaxAge, policy.maxAge);
2315
+ }
2316
+ if (policy.scope === "PRIVATE") {
2317
+ acc.hasPrivate = true;
2318
+ }
2319
+ }
2320
+ function analyzeFragmentSpread2(fragmentName, ctx, parentMaxAge, visitedFragments) {
2321
+ if (visitedFragments.has(fragmentName)) {
2322
+ return void 0;
2323
+ }
2324
+ const fragment = ctx.fragments.get(fragmentName);
2325
+ if (!fragment) {
2326
+ return void 0;
2327
+ }
2328
+ const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value);
2329
+ if (!(fragmentType instanceof GraphQLObjectType)) {
2330
+ return void 0;
2331
+ }
2332
+ const newVisited = new Set(visitedFragments);
2333
+ newVisited.add(fragmentName);
2334
+ return analyzeSelectionSet2(fragment.selectionSet, fragmentType, ctx, parentMaxAge, newVisited);
2335
+ }
2336
+ function analyzeInlineFragment2(selection, parentType, ctx, parentMaxAge, visitedFragments) {
2337
+ let targetType = parentType;
2338
+ if (selection.typeCondition) {
2339
+ const conditionType = ctx.schema.getType(selection.typeCondition.name.value);
2340
+ if (conditionType instanceof GraphQLObjectType) {
2341
+ targetType = conditionType;
2342
+ }
2343
+ }
2344
+ return analyzeSelectionSet2(
2345
+ selection.selectionSet,
2346
+ targetType,
2347
+ ctx,
2348
+ parentMaxAge,
2349
+ visitedFragments
2350
+ );
2351
+ }
2352
+ function lookupEffectiveCacheHint(parentTypeName, fieldName, returnType, cacheHints) {
2353
+ const fieldKey = `${parentTypeName}.${fieldName}`;
2354
+ const fieldHint = cacheHints.get(fieldKey);
2355
+ if (fieldHint) return fieldHint;
2356
+ const namedType = getNamedType2(returnType);
2357
+ return namedType ? cacheHints.get(namedType.name) : void 0;
2358
+ }
2359
+ function computeFieldMaxAge(hint, fieldType, parentMaxAge, defaultMaxAge) {
2360
+ if (hint) {
2361
+ if (hint.inheritMaxAge && parentMaxAge !== void 0) {
2362
+ return parentMaxAge;
2363
+ }
2364
+ if (hint.maxAge !== void 0) {
2365
+ return hint.maxAge;
2366
+ }
2367
+ }
2368
+ if (isLeafType(fieldType) && parentMaxAge !== void 0) {
2369
+ return parentMaxAge;
2370
+ }
2371
+ return defaultMaxAge;
2372
+ }
2373
+ function analyzeSelectionSet2(selectionSet, parentType, schemaOrCtx, fragmentsOrParentMaxAge, cacheHintsOrVisited, defaultMaxAge, defaultScope, parentMaxAge, visitedFragments) {
2374
+ let ctx;
2375
+ let actualParentMaxAge;
2376
+ let actualVisitedFragments;
2377
+ if (schemaOrCtx instanceof GraphQLSchema) {
2378
+ ctx = {
2379
+ schema: schemaOrCtx,
2380
+ fragments: fragmentsOrParentMaxAge,
2381
+ cacheHints: cacheHintsOrVisited,
2382
+ defaultMaxAge,
2383
+ defaultScope
2384
+ };
2385
+ actualParentMaxAge = parentMaxAge;
2386
+ actualVisitedFragments = visitedFragments;
2387
+ } else {
2388
+ ctx = schemaOrCtx;
2389
+ actualParentMaxAge = fragmentsOrParentMaxAge;
2390
+ actualVisitedFragments = cacheHintsOrVisited;
2391
+ }
2392
+ const acc = { minMaxAge: void 0, hasPrivate: false };
2393
+ for (const selection of selectionSet.selections) {
2394
+ let fieldPolicy;
2395
+ switch (selection.kind) {
2396
+ case Kind.FIELD:
2397
+ fieldPolicy = analyzeField2(
2398
+ selection,
2399
+ parentType,
2400
+ ctx,
2401
+ actualParentMaxAge,
2402
+ actualVisitedFragments
2403
+ );
2404
+ break;
2405
+ case Kind.FRAGMENT_SPREAD:
2406
+ fieldPolicy = analyzeFragmentSpread2(
2407
+ selection.name.value,
2408
+ ctx,
2409
+ actualParentMaxAge,
2410
+ actualVisitedFragments
2411
+ );
2412
+ break;
2413
+ case Kind.INLINE_FRAGMENT:
2414
+ fieldPolicy = analyzeInlineFragment2(
2415
+ selection,
2416
+ parentType,
2417
+ ctx,
2418
+ actualParentMaxAge,
2419
+ actualVisitedFragments
2420
+ );
2421
+ break;
2422
+ }
2423
+ if (fieldPolicy) {
2424
+ aggregatePolicy(acc, fieldPolicy);
2425
+ }
2426
+ }
2427
+ return {
2428
+ maxAge: acc.minMaxAge ?? ctx.defaultMaxAge,
2429
+ scope: acc.hasPrivate ? "PRIVATE" : ctx.defaultScope
2430
+ };
2431
+ }
2432
+ function analyzeField2(field2, parentType, ctx, parentMaxAge, visitedFragments) {
2433
+ const fieldName = field2.name.value;
2434
+ if (fieldName.startsWith("__")) {
2435
+ return { maxAge: Infinity, scope: "PUBLIC" };
2436
+ }
2437
+ const schemaField = parentType.getFields()[fieldName];
2438
+ if (!schemaField) {
2439
+ return { maxAge: ctx.defaultMaxAge, scope: ctx.defaultScope };
2440
+ }
2441
+ const effectiveHint = lookupEffectiveCacheHint(
2442
+ parentType.name,
2443
+ fieldName,
2444
+ schemaField.type,
2445
+ ctx.cacheHints
2446
+ );
2447
+ const fieldMaxAge = computeFieldMaxAge(
2448
+ effectiveHint,
2449
+ schemaField.type,
2450
+ parentMaxAge,
2451
+ ctx.defaultMaxAge
2452
+ );
2453
+ const fieldScope = effectiveHint?.scope ?? ctx.defaultScope;
2454
+ const namedType = getNamedType2(schemaField.type);
2455
+ if (field2.selectionSet && namedType instanceof GraphQLObjectType) {
2456
+ const nestedPolicy = analyzeSelectionSet2(
2457
+ field2.selectionSet,
2458
+ namedType,
2459
+ ctx,
2460
+ fieldMaxAge,
2461
+ visitedFragments
2462
+ );
2463
+ return {
2464
+ maxAge: Math.min(fieldMaxAge, nestedPolicy.maxAge),
2465
+ scope: fieldScope === "PRIVATE" || nestedPolicy.scope === "PRIVATE" ? "PRIVATE" : "PUBLIC"
2466
+ };
2467
+ }
2468
+ return { maxAge: fieldMaxAge, scope: fieldScope };
2469
+ }
2470
+ var CacheControlConfigFromEnv = Config.all({
2471
+ enabled: Config.boolean("GRAPHQL_CACHE_CONTROL_ENABLED").pipe(Config.withDefault(true)),
2472
+ defaultMaxAge: Config.number("GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE").pipe(Config.withDefault(0)),
2473
+ defaultScope: Config.string("GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE").pipe(
2474
+ Config.withDefault("PUBLIC"),
2475
+ Config.map((s) => s === "PRIVATE" ? "PRIVATE" : "PUBLIC")
2476
+ ),
2477
+ calculateHttpHeaders: Config.boolean("GRAPHQL_CACHE_CONTROL_HTTP_HEADERS").pipe(
2478
+ Config.withDefault(true)
2479
+ )
2480
+ });
2481
+
2482
+ // src/server/router.ts
2483
+ var defaultErrorHandler = (cause) => (process.env.NODE_ENV !== "production" ? Effect.logError("GraphQL error", cause) : Effect.void).pipe(
2484
+ Effect.andThen(
2485
+ HttpServerResponse.json(
2486
+ {
2487
+ errors: [
2488
+ {
2489
+ message: "An error occurred processing your request"
2490
+ }
2491
+ ]
2492
+ },
2493
+ { status: 500 }
2494
+ ).pipe(Effect.orDie)
2495
+ )
2496
+ );
2497
+ var GraphQLRequestBodySchema = Schema.Struct({
2498
+ query: Schema.String,
2499
+ variables: Schema.optionalWith(Schema.Record({ key: Schema.String, value: Schema.Unknown }), {
2500
+ as: "Option"
2501
+ }),
2502
+ operationName: Schema.optionalWith(Schema.String, { as: "Option" })
2503
+ });
2504
+ var decodeRequestBody = HttpIncomingMessage.schemaBodyJson(GraphQLRequestBodySchema);
2505
+ var parseGraphQLQuery = (query2, extensionsService) => {
2506
+ try {
2507
+ const document = parse(query2);
2508
+ return Effect.succeed({ ok: true, document });
2509
+ } catch (parseError) {
2510
+ return extensionsService.get().pipe(
2511
+ Effect.flatMap(
2512
+ (extensionData) => HttpServerResponse.json({
2513
+ errors: [{ message: String(parseError) }],
2514
+ extensions: Object.keys(extensionData).length > 0 ? extensionData : void 0
2515
+ }).pipe(
2516
+ Effect.orDie,
2517
+ Effect.map((response) => ({ ok: false, response }))
2518
+ )
2519
+ )
2520
+ );
2521
+ }
2522
+ };
2523
+ var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig) => {
2524
+ if (!complexityConfig) {
2525
+ return Effect.void;
2526
+ }
2527
+ return validateComplexity(
2528
+ body.query,
2529
+ body.operationName,
2530
+ body.variables,
2531
+ schema,
2532
+ fieldComplexities,
2533
+ complexityConfig
2534
+ ).pipe(
2535
+ Effect.catchTag("ComplexityLimitExceededError", (error) => Effect.fail(error)),
2536
+ Effect.catchTag(
2537
+ "ComplexityAnalysisError",
2538
+ (error) => Effect.logWarning("Complexity analysis failed", error)
2539
+ )
2540
+ );
2541
+ };
2542
+ var isPromiseLike = (value) => value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
2543
+ var executeGraphQLQuery = (schema, document, variables, operationName, runtime) => {
2544
+ const tryExecute = Effect.try({
2545
+ try: () => execute$1({
2546
+ schema,
2547
+ document,
2548
+ variableValues: variables,
2549
+ operationName,
2550
+ contextValue: { runtime }
2551
+ }),
2552
+ catch: (error) => new Error(String(error))
2553
+ });
2554
+ return tryExecute.pipe(
2555
+ Effect.flatMap((executeResult) => {
2556
+ if (isPromiseLike(executeResult)) {
2557
+ return Effect.promise(() => executeResult);
2558
+ }
2559
+ return Effect.succeed(executeResult);
2560
+ })
2561
+ );
2562
+ };
2563
+ var computeCacheControlHeader = (document, operationName, schema, cacheHints, cacheControlConfig) => {
2564
+ if (cacheControlConfig?.enabled === false || cacheControlConfig?.calculateHttpHeaders === false) {
2565
+ return Effect.succeed(void 0);
2566
+ }
2567
+ const operations = document.definitions.filter(
2568
+ (d) => d.kind === Kind.OPERATION_DEFINITION
2569
+ );
2570
+ const operation = operationName ? operations.find((o) => o.name?.value === operationName) : operations[0];
2571
+ if (!operation || operation.operation === "mutation") {
2572
+ return Effect.succeed(void 0);
2573
+ }
2574
+ return computeCachePolicy({
2575
+ document,
2576
+ operation,
2577
+ schema,
2578
+ cacheHints,
2579
+ config: cacheControlConfig ?? {}
2580
+ }).pipe(Effect.map(toCacheControlHeader));
2581
+ };
2582
+ var buildGraphQLResponse = (result, extensionData, cacheControlHeader) => {
2583
+ const finalResult = Object.keys(extensionData).length > 0 ? {
2584
+ ...result,
2585
+ extensions: {
2586
+ ...result.extensions,
2587
+ ...extensionData
2588
+ }
2589
+ } : result;
2590
+ const responseHeaders = cacheControlHeader ? { "cache-control": cacheControlHeader } : void 0;
2591
+ return HttpServerResponse.json(finalResult, { headers: responseHeaders }).pipe(Effect.orDie);
2592
+ };
2593
+ var handleComplexityError = (error) => HttpServerResponse.json(
2594
+ {
2595
+ errors: [
2596
+ {
2597
+ message: error.message,
2598
+ extensions: {
2599
+ code: "COMPLEXITY_LIMIT_EXCEEDED",
2600
+ limitType: error.limitType,
2601
+ limit: error.limit,
2602
+ actual: error.actual
2603
+ }
2604
+ }
2605
+ ]
2606
+ },
2607
+ { status: 400 }
2608
+ ).pipe(Effect.orDie);
2609
+ var makeGraphQLRouter = (schema, layer, options = {}) => {
2610
+ const resolvedConfig = normalizeConfig(options);
2611
+ const fieldComplexities = options.fieldComplexities ?? /* @__PURE__ */ new Map();
2612
+ const cacheHints = options.cacheHints ?? /* @__PURE__ */ new Map();
2613
+ const extensions = options.extensions ?? [];
2614
+ const errorHandler = options.errorHandler ?? defaultErrorHandler;
2615
+ const graphqlHandler = Effect.gen(function* () {
2616
+ const extensionsService = yield* makeExtensionsService();
2617
+ const runtime = yield* Effect.runtime();
2618
+ const request = yield* HttpServerRequest.HttpServerRequest;
2619
+ const parsedBody = yield* decodeRequestBody(request);
2620
+ const body = {
2621
+ query: parsedBody.query,
2622
+ variables: parsedBody.variables._tag === "Some" ? parsedBody.variables.value : void 0,
2623
+ operationName: parsedBody.operationName._tag === "Some" ? parsedBody.operationName.value : void 0
2624
+ };
2625
+ const parseResult = yield* parseGraphQLQuery(body.query, extensionsService);
2626
+ if (!parseResult.ok) {
2627
+ return parseResult.response;
2628
+ }
2629
+ const document = parseResult.document;
2630
+ yield* runParseHooks(extensions, body.query, document).pipe(
2631
+ Effect.provideService(ExtensionsService, extensionsService)
2632
+ );
2633
+ const validationRules = resolvedConfig.introspection ? void 0 : specifiedRules.concat(NoSchemaIntrospectionCustomRule);
2634
+ const validationErrors = validate(schema, document, validationRules);
2635
+ yield* runValidateHooks(extensions, document, validationErrors).pipe(
2636
+ Effect.provideService(ExtensionsService, extensionsService)
2637
+ );
2638
+ if (validationErrors.length > 0) {
2639
+ const extensionData2 = yield* extensionsService.get();
2640
+ return yield* HttpServerResponse.json(
2641
+ {
2642
+ errors: validationErrors.map((e) => ({
2643
+ message: e.message,
2644
+ locations: e.locations,
2645
+ path: e.path
2646
+ })),
2647
+ extensions: Object.keys(extensionData2).length > 0 ? extensionData2 : void 0
2648
+ },
2649
+ { status: 400 }
2650
+ );
2651
+ }
2652
+ yield* runComplexityValidation(body, schema, fieldComplexities, resolvedConfig.complexity);
2653
+ yield* runExecuteStartHooks(extensions, {
2654
+ source: body.query,
2655
+ document,
2656
+ variableValues: body.variables,
2657
+ operationName: body.operationName,
2658
+ schema,
2659
+ fieldComplexities
2660
+ }).pipe(Effect.provideService(ExtensionsService, extensionsService));
2661
+ const result = yield* executeGraphQLQuery(
2662
+ schema,
2663
+ document,
2664
+ body.variables,
2665
+ body.operationName,
2666
+ runtime
2667
+ );
2668
+ yield* runExecuteEndHooks(extensions, result).pipe(
2669
+ Effect.provideService(ExtensionsService, extensionsService)
2670
+ );
2671
+ const extensionData = yield* extensionsService.get();
2672
+ const cacheControlHeader = yield* computeCacheControlHeader(
2673
+ document,
2674
+ body.operationName,
2675
+ schema,
2676
+ cacheHints,
2677
+ resolvedConfig.cacheControl
2678
+ );
2679
+ return yield* buildGraphQLResponse(result, extensionData, cacheControlHeader);
2680
+ }).pipe(
2681
+ Effect.provide(layer),
2682
+ Effect.catchAll((error) => {
2683
+ if (error instanceof ComplexityLimitExceededError) {
2684
+ return handleComplexityError(error);
2685
+ }
2686
+ return Effect.fail(error);
2687
+ }),
2688
+ Effect.catchAllCause(errorHandler)
2689
+ );
2690
+ let router = HttpRouter.empty.pipe(
2691
+ HttpRouter.post(resolvedConfig.path, graphqlHandler)
2692
+ );
2693
+ if (resolvedConfig.graphiql) {
2694
+ const { path, endpoint, subscriptionEndpoint } = resolvedConfig.graphiql;
2695
+ router = router.pipe(
2696
+ HttpRouter.get(
2697
+ path,
2698
+ HttpServerResponse.html(graphiqlHtml(endpoint, subscriptionEndpoint))
2699
+ )
2700
+ );
2701
+ }
2702
+ return router;
2703
+ };
2704
+
2705
+ // src/server/schema-builder-extensions.ts
2706
+ var toRouter = (builder, layer, options) => {
2707
+ const schema = builder.buildSchema();
2708
+ const fieldComplexities = builder.getFieldComplexities();
2709
+ const cacheHints = builder.getCacheHints();
2710
+ return makeGraphQLRouter(schema, layer, { ...options, fieldComplexities, cacheHints });
2711
+ };
2712
+ var WebSocketError = class extends Data.TaggedError("WebSocketError") {
2713
+ };
2714
+ var createConnectionContext = (extra) => ({
2715
+ runtime: extra.runtime,
2716
+ connectionParams: extra.connectionParams,
2717
+ socket: extra.socket
2718
+ });
2719
+ var makeOnConnectHandler = (options) => {
2720
+ if (!options?.onConnect) return void 0;
2721
+ return async (ctx) => {
2722
+ const extra = ctx.extra;
2723
+ try {
2724
+ const result = await Runtime.runPromise(extra.runtime)(
2725
+ options.onConnect(ctx.connectionParams ?? {})
2726
+ );
2727
+ if (typeof result === "object" && result !== null) {
2728
+ Object.assign(extra.connectionParams, result);
2729
+ }
2730
+ return result !== false;
2731
+ } catch {
2732
+ return false;
2733
+ }
2734
+ };
2735
+ };
2736
+ var makeOnDisconnectHandler = (options) => {
2737
+ if (!options?.onDisconnect) return void 0;
2738
+ return async (ctx) => {
2739
+ const extra = ctx.extra;
2740
+ await Runtime.runPromise(extra.runtime)(
2741
+ options.onDisconnect(createConnectionContext(extra))
2742
+ ).catch(() => {
2743
+ });
2744
+ };
2745
+ };
2746
+ var makeOnSubscribeHandler = (options, schema, complexityConfig, fieldComplexities) => {
2747
+ return async (ctx, id, payload) => {
2748
+ const extra = ctx.extra;
2749
+ const connectionCtx = createConnectionContext(extra);
2750
+ if (complexityConfig) {
2751
+ const validationEffect = validateComplexity(
2752
+ payload.query,
2753
+ payload.operationName ?? void 0,
2754
+ payload.variables ?? void 0,
2755
+ schema,
2756
+ fieldComplexities,
2757
+ complexityConfig
2758
+ ).pipe(
2759
+ Effect.catchAll((error) => {
2760
+ if (error._tag === "ComplexityLimitExceededError") {
2761
+ throw new GraphQLError(error.message, {
2762
+ extensions: {
2763
+ code: "COMPLEXITY_LIMIT_EXCEEDED",
2764
+ limitType: error.limitType,
2765
+ limit: error.limit,
2766
+ actual: error.actual
2767
+ }
2768
+ });
2769
+ }
2770
+ return Effect.logWarning("Complexity analysis failed for subscription", error);
2771
+ })
2772
+ );
2773
+ await Effect.runPromise(validationEffect);
2774
+ }
2775
+ if (options?.onSubscribe) {
2776
+ await Runtime.runPromise(extra.runtime)(
2777
+ options.onSubscribe(connectionCtx, {
2778
+ id,
2779
+ payload: {
2780
+ query: payload.query,
2781
+ variables: payload.variables ?? void 0,
2782
+ operationName: payload.operationName ?? void 0,
2783
+ extensions: payload.extensions ?? void 0
2784
+ }
2785
+ })
2786
+ );
2787
+ }
2788
+ };
2789
+ };
2790
+ var makeOnCompleteHandler = (options) => {
2791
+ if (!options?.onComplete) return void 0;
2792
+ return async (ctx, id, _payload) => {
2793
+ const extra = ctx.extra;
2794
+ await Runtime.runPromise(extra.runtime)(
2795
+ options.onComplete(createConnectionContext(extra), { id })
2796
+ ).catch(() => {
2797
+ });
2798
+ };
2799
+ };
2800
+ var makeOnErrorHandler = (options) => {
2801
+ if (!options?.onError) return void 0;
2802
+ return async (ctx, _id, _payload, errors) => {
2803
+ const extra = ctx.extra;
2804
+ await Runtime.runPromise(extra.runtime)(
2805
+ options.onError(createConnectionContext(extra), errors)
2806
+ ).catch(() => {
2807
+ });
2808
+ };
2809
+ };
2810
+ var createGraphqlWsSocketAdapter = (socket, runtime) => {
2811
+ let messageCallback = null;
2812
+ return {
2813
+ adapter: {
2814
+ protocol: socket.protocol,
2815
+ send: (data) => Runtime.runPromise(runtime)(
2816
+ socket.send(data).pipe(Effect.catchAll((error) => Effect.logError("WebSocket send error", error)))
2817
+ ),
2818
+ close: (code, reason) => {
2819
+ Runtime.runPromise(runtime)(socket.close(code, reason)).catch(() => {
2820
+ });
2821
+ },
2822
+ onMessage: (cb) => {
2823
+ messageCallback = cb;
2824
+ },
2825
+ onPong: (_payload) => {
2826
+ }
2827
+ },
2828
+ dispatchMessage: async (message) => {
2829
+ if (messageCallback) {
2830
+ await messageCallback(message);
2831
+ }
2832
+ }
2833
+ };
2834
+ };
2835
+ var runConnectionLifecycle = (socket, wsServer, extra) => Effect.gen(function* () {
2836
+ const messageQueue = yield* Queue.unbounded();
2837
+ const closedDeferred = yield* Deferred.make();
2838
+ const messageFiber = yield* Effect.fork(
2839
+ Stream.runForEach(socket.messages, (msg) => Queue.offer(messageQueue, msg)).pipe(
2840
+ Effect.catchAll((error) => Deferred.fail(closedDeferred, error))
2841
+ )
2842
+ );
2843
+ const closeFiber = yield* Effect.fork(
2844
+ socket.closed.pipe(
2845
+ Effect.tap((event) => Deferred.succeed(closedDeferred, event)),
2846
+ Effect.catchAll((error) => Deferred.fail(closedDeferred, error))
2847
+ )
2848
+ );
2849
+ const { adapter, dispatchMessage } = createGraphqlWsSocketAdapter(socket, extra.runtime);
2850
+ const closedHandler = wsServer.opened(adapter, extra);
2851
+ const processMessagesFiber = yield* Effect.fork(
2852
+ Effect.gen(function* () {
2853
+ while (true) {
2854
+ const message = yield* Queue.take(messageQueue);
2855
+ yield* Effect.tryPromise({
2856
+ try: () => dispatchMessage(message),
2857
+ catch: (error) => error
2858
+ }).pipe(Effect.catchAll(() => Effect.void));
2859
+ }
2860
+ })
2861
+ );
2862
+ yield* Deferred.await(closedDeferred).pipe(
2863
+ Effect.catchAll(() => Effect.succeed({ code: 1e3, reason: "Error" }))
2864
+ );
2865
+ closedHandler(1e3, "Connection closed");
2866
+ yield* Fiber.interrupt(messageFiber);
2867
+ yield* Fiber.interrupt(closeFiber);
2868
+ yield* Fiber.interrupt(processMessagesFiber);
2869
+ yield* Queue.shutdown(messageQueue);
2870
+ }).pipe(
2871
+ Effect.catchAllCause(() => Effect.void),
2872
+ Effect.scoped
2873
+ );
2874
+ var makeGraphQLWSHandler = (schema, layer, options) => {
2875
+ const complexityConfig = options?.complexity;
2876
+ const fieldComplexities = options?.fieldComplexities ?? /* @__PURE__ */ new Map();
2877
+ const serverOptions = {
2878
+ schema,
2879
+ context: async (ctx) => {
2880
+ const extra = ctx.extra;
2881
+ return {
2882
+ runtime: extra.runtime,
2883
+ ...extra.connectionParams
2884
+ };
2885
+ },
2886
+ subscribe: async (args) => subscribe(args),
2887
+ onConnect: makeOnConnectHandler(options),
2888
+ onDisconnect: makeOnDisconnectHandler(options),
2889
+ onSubscribe: makeOnSubscribeHandler(options, schema, complexityConfig, fieldComplexities),
2890
+ onComplete: makeOnCompleteHandler(options),
2891
+ onError: makeOnErrorHandler(options)
2892
+ };
2893
+ const wsServer = makeServer(serverOptions);
2894
+ return (socket) => Effect.gen(function* () {
2895
+ const runtime = yield* Effect.provide(Effect.runtime(), layer);
2896
+ const extra = {
2897
+ socket,
2898
+ runtime,
2899
+ connectionParams: {}
2900
+ };
2901
+ yield* runConnectionLifecycle(socket, wsServer, extra);
2902
+ }).pipe(
2903
+ Effect.catchAllCause(() => Effect.void),
2904
+ Effect.scoped
2905
+ );
2906
+ };
2907
+ var WS_CLOSED = 3;
2908
+ var toEffectWebSocketFromWs = (ws) => {
2909
+ const messagesEffect = Effect.gen(function* () {
2910
+ const queue = yield* Queue.unbounded();
2911
+ const closed = yield* Deferred.make();
2912
+ ws.on("message", (data) => {
2913
+ const message = data.toString();
2914
+ Effect.runPromise(Queue.offer(queue, message)).catch(() => {
2915
+ });
2916
+ });
2917
+ ws.on("error", (error) => {
2918
+ Effect.runPromise(Deferred.fail(closed, new WebSocketError({ cause: error }))).catch(() => {
2919
+ });
2920
+ });
2921
+ ws.on("close", (code, reason) => {
2922
+ Effect.runPromise(
2923
+ Queue.shutdown(queue).pipe(
2924
+ Effect.andThen(Deferred.succeed(closed, { code, reason: reason.toString() }))
2925
+ )
2926
+ ).catch(() => {
2927
+ });
2928
+ });
2929
+ return { queue, closed };
2930
+ });
2931
+ const messages = Stream.unwrap(
2932
+ messagesEffect.pipe(
2933
+ Effect.map(({ queue }) => Stream.fromQueue(queue).pipe(Stream.catchAll(() => Stream.empty)))
2934
+ )
2935
+ );
2936
+ return {
2937
+ protocol: ws.protocol || "graphql-transport-ws",
2938
+ send: (data) => Effect.async((resume) => {
2939
+ ws.send(data, (error) => {
2940
+ if (error) {
2941
+ resume(Effect.fail(new WebSocketError({ cause: error })));
2942
+ } else {
2943
+ resume(Effect.succeed(void 0));
2944
+ }
2945
+ });
2946
+ }),
2947
+ close: (code, reason) => Effect.sync(() => {
2948
+ ws.close(code ?? 1e3, reason ?? "");
2949
+ }),
2950
+ messages,
2951
+ closed: Effect.async((resume) => {
2952
+ if (ws.readyState === WS_CLOSED) {
2953
+ resume(Effect.succeed({ code: 1e3, reason: "" }));
2954
+ return;
2955
+ }
2956
+ const onClose = (code, reason) => {
2957
+ cleanup();
2958
+ resume(Effect.succeed({ code, reason: reason.toString() }));
2959
+ };
2960
+ const onError = (error) => {
2961
+ cleanup();
2962
+ resume(Effect.fail(new WebSocketError({ cause: error })));
2963
+ };
2964
+ const cleanup = () => {
2965
+ ws.removeListener("close", onClose);
2966
+ ws.removeListener("error", onError);
2967
+ };
2968
+ ws.on("close", onClose);
2969
+ ws.on("error", onError);
2970
+ return Effect.sync(cleanup);
2971
+ })
2972
+ };
2973
+ };
2974
+ var SSE_HEADERS = {
2975
+ "Content-Type": "text/event-stream",
2976
+ "Cache-Control": "no-cache",
2977
+ Connection: "keep-alive",
2978
+ "X-Accel-Buffering": "no"
2979
+ // Disable nginx buffering
2980
+ };
2981
+ var SSEError = class extends Data.TaggedError("SSEError") {
2982
+ };
2983
+ var formatNextEvent = (result) => ({
2984
+ event: "next",
2985
+ data: JSON.stringify(result)
2986
+ });
2987
+ var formatErrorEvent = (errors) => ({
2988
+ event: "error",
2989
+ data: JSON.stringify({ errors })
2990
+ });
2991
+ var formatCompleteEvent = () => ({
2992
+ event: "complete",
2993
+ data: ""
2994
+ });
2995
+ var formatSSEMessage = (event) => {
2996
+ const lines = [`event: ${event.event}`];
2997
+ if (event.data) {
2998
+ lines.push(`data: ${event.data}`);
2999
+ }
3000
+ lines.push("", "");
3001
+ return lines.join("\n");
3002
+ };
3003
+ var makeSSESubscriptionStream = (schema, layer, request, headers, options) => {
3004
+ const complexityConfig = options?.complexity;
3005
+ const fieldComplexities = options?.fieldComplexities ?? /* @__PURE__ */ new Map();
3006
+ return Stream.unwrap(
3007
+ Effect.gen(function* () {
3008
+ const runtime = yield* Effect.provide(Effect.runtime(), layer);
3009
+ let connectionContext = {};
3010
+ if (options?.onConnect) {
3011
+ try {
3012
+ connectionContext = yield* Effect.provide(options.onConnect(request, headers), layer);
3013
+ } catch {
3014
+ return Stream.make(
3015
+ formatErrorEvent([
3016
+ new GraphQLError("Subscription connection rejected", {
3017
+ extensions: { code: "CONNECTION_REJECTED" }
3018
+ })
3019
+ ]),
3020
+ formatCompleteEvent()
3021
+ );
3022
+ }
3023
+ }
3024
+ let document;
3025
+ try {
3026
+ document = parse(request.query);
3027
+ } catch (syntaxError) {
3028
+ return Stream.make(formatErrorEvent([syntaxError]), formatCompleteEvent());
3029
+ }
3030
+ const validationErrors = validate(schema, document);
3031
+ if (validationErrors.length > 0) {
3032
+ return Stream.make(formatErrorEvent(validationErrors), formatCompleteEvent());
3033
+ }
3034
+ const operations = document.definitions.filter(
3035
+ (d) => d.kind === Kind.OPERATION_DEFINITION
3036
+ );
3037
+ const operation = request.operationName ? operations.find((o) => o.name?.value === request.operationName) : operations[0];
3038
+ if (!operation) {
3039
+ return Stream.make(
3040
+ formatErrorEvent([new GraphQLError("No operation found in query")]),
3041
+ formatCompleteEvent()
3042
+ );
3043
+ }
3044
+ if (operation.operation !== "subscription") {
3045
+ return Stream.make(
3046
+ formatErrorEvent([
3047
+ new GraphQLError(
3048
+ `SSE endpoint only supports subscriptions, received: ${operation.operation}`,
3049
+ { extensions: { code: "OPERATION_NOT_SUPPORTED" } }
3050
+ )
3051
+ ]),
3052
+ formatCompleteEvent()
3053
+ );
3054
+ }
3055
+ if (complexityConfig) {
3056
+ const complexityResult = yield* validateComplexity(
3057
+ request.query,
3058
+ request.operationName,
3059
+ request.variables,
3060
+ schema,
3061
+ fieldComplexities,
3062
+ complexityConfig
3063
+ ).pipe(
3064
+ Effect.map(() => null),
3065
+ Effect.catchAll((error) => {
3066
+ if (error._tag === "ComplexityLimitExceededError") {
3067
+ return Effect.succeed(
3068
+ new GraphQLError(error.message, {
3069
+ extensions: {
3070
+ code: "COMPLEXITY_LIMIT_EXCEEDED",
3071
+ limitType: error.limitType,
3072
+ limit: error.limit,
3073
+ actual: error.actual
3074
+ }
3075
+ })
3076
+ );
3077
+ }
3078
+ return Effect.logWarning("Complexity analysis failed for SSE subscription", error).pipe(
3079
+ Effect.map(() => null)
3080
+ );
3081
+ })
3082
+ );
3083
+ if (complexityResult) {
3084
+ return Stream.make(formatErrorEvent([complexityResult]), formatCompleteEvent());
3085
+ }
3086
+ }
3087
+ const ctx = {
3088
+ runtime,
3089
+ request,
3090
+ connectionContext
3091
+ };
3092
+ if (options?.onSubscribe) {
3093
+ yield* Effect.provide(options.onSubscribe(ctx), layer).pipe(
3094
+ Effect.catchAll(() => Effect.void)
3095
+ );
3096
+ }
3097
+ const graphqlContext = {
3098
+ runtime,
3099
+ ...connectionContext
3100
+ };
3101
+ const subscriptionResult = yield* Effect.tryPromise({
3102
+ try: () => subscribe({
3103
+ schema,
3104
+ document,
3105
+ variableValues: request.variables,
3106
+ operationName: request.operationName ?? void 0,
3107
+ contextValue: graphqlContext
3108
+ }),
3109
+ catch: (error) => new SSEError({ cause: error })
3110
+ });
3111
+ if (!isAsyncIterable(subscriptionResult)) {
3112
+ const result = subscriptionResult;
3113
+ if (result.errors) {
3114
+ return Stream.make(formatErrorEvent(result.errors), formatCompleteEvent());
3115
+ }
3116
+ return Stream.make(formatNextEvent(result), formatCompleteEvent());
3117
+ }
3118
+ const asyncIterator = subscriptionResult[Symbol.asyncIterator]();
3119
+ const eventStream = Stream.async((emit) => {
3120
+ let done = false;
3121
+ const iterate = async () => {
3122
+ try {
3123
+ while (!done) {
3124
+ const result = await asyncIterator.next();
3125
+ if (result.done) {
3126
+ emit.end();
3127
+ break;
3128
+ }
3129
+ emit.single(formatNextEvent(result.value));
3130
+ }
3131
+ } catch (error) {
3132
+ if (!done) {
3133
+ emit.single(
3134
+ formatErrorEvent([
3135
+ error instanceof GraphQLError ? error : new GraphQLError(
3136
+ error instanceof Error ? error.message : "Subscription error",
3137
+ { extensions: { code: "SUBSCRIPTION_ERROR" } }
3138
+ )
3139
+ ])
3140
+ );
3141
+ emit.end();
3142
+ }
3143
+ }
3144
+ };
3145
+ iterate();
3146
+ return Effect.sync(() => {
3147
+ done = true;
3148
+ asyncIterator.return?.();
3149
+ });
3150
+ });
3151
+ return eventStream.pipe(
3152
+ Stream.onDone(
3153
+ () => Effect.gen(function* () {
3154
+ yield* Effect.sync(() => {
3155
+ });
3156
+ }).pipe(Effect.asVoid)
3157
+ ),
3158
+ Stream.concat(Stream.make(formatCompleteEvent())),
3159
+ Stream.onDone(() => {
3160
+ if (options?.onComplete) {
3161
+ return Effect.provide(options.onComplete(ctx), layer).pipe(
3162
+ Effect.catchAll(() => Effect.void)
3163
+ );
3164
+ }
3165
+ return Effect.void;
3166
+ })
3167
+ );
3168
+ }).pipe(
3169
+ Effect.catchAll(
3170
+ (error) => Effect.succeed(
3171
+ Stream.make(
3172
+ formatErrorEvent([
3173
+ new GraphQLError(error instanceof Error ? error.message : "Internal error", {
3174
+ extensions: { code: "INTERNAL_ERROR" }
3175
+ })
3176
+ ]),
3177
+ formatCompleteEvent()
3178
+ )
3179
+ )
3180
+ )
3181
+ )
3182
+ );
3183
+ };
3184
+ var makeGraphQLSSEHandler = (schema, layer, options) => {
3185
+ return (request, headers) => makeSSESubscriptionStream(schema, layer, request, headers, options);
3186
+ };
3187
+ function isAsyncIterable(value) {
3188
+ return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
3189
+ }
3190
+ var createAnalyzerExtension = (config = {}) => {
3191
+ const {
3192
+ includeComplexity = true,
3193
+ includeDepth = true,
3194
+ includeFieldCount = false,
3195
+ includeAliasCount = false,
3196
+ key = "analyzer",
3197
+ thresholds,
3198
+ defaultFieldComplexity = 1,
3199
+ fieldComplexities: configFieldComplexities
3200
+ } = config;
3201
+ return {
3202
+ name: "analyzer",
3203
+ description: "Reports query complexity metrics in response extensions",
3204
+ onExecuteStart: (args) => Effect.gen(function* () {
3205
+ const ext = yield* ExtensionsService;
3206
+ const operation = findOperation(args);
3207
+ if (!operation) {
3208
+ return;
3209
+ }
3210
+ const fieldComplexities = configFieldComplexities ?? args.fieldComplexities;
3211
+ const calculator = defaultComplexityCalculator(defaultFieldComplexity);
3212
+ const result = yield* calculator({
3213
+ document: args.document,
3214
+ operation,
3215
+ variables: args.variableValues,
3216
+ schema: args.schema,
3217
+ fieldComplexities
3218
+ }).pipe(
3219
+ Effect.catchAll(
3220
+ (error) => Effect.logWarning("Analyzer extension: complexity calculation failed", error).pipe(
3221
+ Effect.as(null)
3222
+ )
3223
+ )
3224
+ );
3225
+ if (!result) {
3226
+ return;
3227
+ }
3228
+ yield* checkThresholds(result, thresholds);
3229
+ const output = {};
3230
+ if (includeComplexity) {
3231
+ output.complexity = result.complexity;
3232
+ }
3233
+ if (includeDepth) {
3234
+ output.depth = result.depth;
3235
+ }
3236
+ if (includeFieldCount) {
3237
+ output.fieldCount = result.fieldCount;
3238
+ }
3239
+ if (includeAliasCount) {
3240
+ output.aliasCount = result.aliasCount;
3241
+ }
3242
+ yield* ext.set(key, output);
3243
+ })
3244
+ };
3245
+ };
3246
+ function findOperation(args) {
3247
+ const operations = args.document.definitions.filter(
3248
+ (d) => d.kind === Kind.OPERATION_DEFINITION
3249
+ );
3250
+ if (operations.length === 0) {
3251
+ return null;
3252
+ }
3253
+ if (args.operationName) {
3254
+ return operations.find((o) => o.name?.value === args.operationName) ?? null;
3255
+ }
3256
+ return operations[0];
3257
+ }
3258
+ function checkThresholds(result, thresholds) {
3259
+ if (!thresholds) {
3260
+ return Effect.void;
3261
+ }
3262
+ const warnings = [];
3263
+ if (thresholds.depth !== void 0 && result.depth > thresholds.depth) {
3264
+ warnings.push(`Query depth ${result.depth} exceeds threshold ${thresholds.depth}`);
3265
+ }
3266
+ if (thresholds.complexity !== void 0 && result.complexity > thresholds.complexity) {
3267
+ warnings.push(
3268
+ `Query complexity ${result.complexity} exceeds threshold ${thresholds.complexity}`
3269
+ );
3270
+ }
3271
+ if (thresholds.fieldCount !== void 0 && result.fieldCount > thresholds.fieldCount) {
3272
+ warnings.push(
3273
+ `Query field count ${result.fieldCount} exceeds threshold ${thresholds.fieldCount}`
3274
+ );
3275
+ }
3276
+ if (thresholds.aliasCount !== void 0 && result.aliasCount > thresholds.aliasCount) {
3277
+ warnings.push(
3278
+ `Query alias count ${result.aliasCount} exceeds threshold ${thresholds.aliasCount}`
3279
+ );
3280
+ }
3281
+ if (warnings.length > 0) {
3282
+ return Effect.logWarning("Analyzer extension: thresholds exceeded", {
3283
+ warnings,
3284
+ result
3285
+ });
3286
+ }
3287
+ return Effect.void;
3288
+ }
3289
+
3290
+ export { AuthorizationError, CacheControlConfigFromEnv, ComplexityAnalysisError, ComplexityConfigFromEnv, ComplexityLimitExceededError, ExtensionsService, GraphQLError2 as GraphQLError, GraphQLRequestContext, GraphQLRouterConfigFromEnv, GraphQLSchemaBuilder, Loader, MissingResolverContextError, NotFoundError, ResolverContext, ResolverContextStore, SSEError, SSE_HEADERS, ValidationError, WS_CLOSED, WebSocketError, combineCalculators, compose, computeCachePolicy, computeCachePolicyFromQuery, createAnalyzerExtension, defaultComplexityCalculator, defaultConfig, defaultErrorHandler, depthOnlyCalculator, directive, enumType, execute, extension, field, formatCompleteEvent, formatErrorEvent, formatNextEvent, formatSSEMessage, get, getOption, getOrElse, getSchemaName, graphiqlHtml, has, inputType, interfaceType, make3 as make, makeExtensionsService, makeGraphQLRouter, makeGraphQLSSEHandler, makeGraphQLWSHandler, makeRequestContextLayer, makeSSESubscriptionStream, makeStoreLayer, middleware, mutation, normalizeConfig, objectType, query, runExecuteEndHooks, runExecuteStartHooks, runParseHooks, runValidateHooks, scoped, set, setMany, storeLayer, subscription, toCacheControlHeader, toEffectWebSocketFromWs, toGraphQLArgs, toGraphQLInputType, toGraphQLObjectType, toGraphQLType, toRouter, unionType, validateComplexity };
3291
+ //# sourceMappingURL=index.js.map
3292
+ //# sourceMappingURL=index.js.map