@effect-gql/core 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -0
- package/builder/index.cjs +1431 -0
- package/builder/index.cjs.map +1 -0
- package/builder/index.d.cts +259 -0
- package/{dist/builder/pipe-api.d.ts → builder/index.d.ts} +49 -21
- package/builder/index.js +1390 -0
- package/builder/index.js.map +1 -0
- package/index.cjs +3419 -0
- package/index.cjs.map +1 -0
- package/index.d.cts +523 -0
- package/index.d.ts +523 -0
- package/index.js +3242 -0
- package/index.js.map +1 -0
- package/package.json +19 -28
- package/schema-builder-Cvdq7Kz_.d.cts +963 -0
- package/schema-builder-Cvdq7Kz_.d.ts +963 -0
- package/server/index.cjs +1555 -0
- package/server/index.cjs.map +1 -0
- package/server/index.d.cts +680 -0
- package/server/index.d.ts +680 -0
- package/server/index.js +1524 -0
- package/server/index.js.map +1 -0
- package/dist/analyzer-extension.d.ts +0 -105
- package/dist/analyzer-extension.d.ts.map +0 -1
- package/dist/analyzer-extension.js +0 -137
- package/dist/analyzer-extension.js.map +0 -1
- package/dist/builder/execute.d.ts +0 -26
- package/dist/builder/execute.d.ts.map +0 -1
- package/dist/builder/execute.js +0 -104
- package/dist/builder/execute.js.map +0 -1
- package/dist/builder/field-builders.d.ts +0 -30
- package/dist/builder/field-builders.d.ts.map +0 -1
- package/dist/builder/field-builders.js +0 -200
- package/dist/builder/field-builders.js.map +0 -1
- package/dist/builder/index.d.ts +0 -7
- package/dist/builder/index.d.ts.map +0 -1
- package/dist/builder/index.js +0 -31
- package/dist/builder/index.js.map +0 -1
- package/dist/builder/pipe-api.d.ts.map +0 -1
- package/dist/builder/pipe-api.js +0 -151
- package/dist/builder/pipe-api.js.map +0 -1
- package/dist/builder/schema-builder.d.ts +0 -301
- package/dist/builder/schema-builder.d.ts.map +0 -1
- package/dist/builder/schema-builder.js +0 -566
- package/dist/builder/schema-builder.js.map +0 -1
- package/dist/builder/type-registry.d.ts +0 -80
- package/dist/builder/type-registry.d.ts.map +0 -1
- package/dist/builder/type-registry.js +0 -505
- package/dist/builder/type-registry.js.map +0 -1
- package/dist/builder/types.d.ts +0 -283
- package/dist/builder/types.d.ts.map +0 -1
- package/dist/builder/types.js +0 -3
- package/dist/builder/types.js.map +0 -1
- package/dist/cli/generate-schema.d.ts +0 -29
- package/dist/cli/generate-schema.d.ts.map +0 -1
- package/dist/cli/generate-schema.js +0 -233
- package/dist/cli/generate-schema.js.map +0 -1
- package/dist/cli/index.d.ts +0 -19
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -24
- package/dist/cli/index.js.map +0 -1
- package/dist/context.d.ts +0 -18
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -11
- package/dist/context.js.map +0 -1
- package/dist/error.d.ts +0 -45
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -29
- package/dist/error.js.map +0 -1
- package/dist/extensions.d.ts +0 -130
- package/dist/extensions.d.ts.map +0 -1
- package/dist/extensions.js +0 -78
- package/dist/extensions.js.map +0 -1
- package/dist/index.d.ts +0 -12
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -47
- package/dist/index.js.map +0 -1
- package/dist/loader.d.ts +0 -169
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -237
- package/dist/loader.js.map +0 -1
- package/dist/resolver-context.d.ts +0 -154
- package/dist/resolver-context.d.ts.map +0 -1
- package/dist/resolver-context.js +0 -184
- package/dist/resolver-context.js.map +0 -1
- package/dist/schema-mapping.d.ts +0 -30
- package/dist/schema-mapping.d.ts.map +0 -1
- package/dist/schema-mapping.js +0 -280
- package/dist/schema-mapping.js.map +0 -1
- package/dist/server/cache-control.d.ts +0 -96
- package/dist/server/cache-control.d.ts.map +0 -1
- package/dist/server/cache-control.js +0 -308
- package/dist/server/cache-control.js.map +0 -1
- package/dist/server/complexity.d.ts +0 -165
- package/dist/server/complexity.d.ts.map +0 -1
- package/dist/server/complexity.js +0 -433
- package/dist/server/complexity.js.map +0 -1
- package/dist/server/config.d.ts +0 -66
- package/dist/server/config.d.ts.map +0 -1
- package/dist/server/config.js +0 -104
- package/dist/server/config.js.map +0 -1
- package/dist/server/graphiql.d.ts +0 -5
- package/dist/server/graphiql.d.ts.map +0 -1
- package/dist/server/graphiql.js +0 -43
- package/dist/server/graphiql.js.map +0 -1
- package/dist/server/index.d.ts +0 -18
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -48
- package/dist/server/index.js.map +0 -1
- package/dist/server/router.d.ts +0 -79
- package/dist/server/router.d.ts.map +0 -1
- package/dist/server/router.js +0 -232
- package/dist/server/router.js.map +0 -1
- package/dist/server/schema-builder-extensions.d.ts +0 -42
- package/dist/server/schema-builder-extensions.d.ts.map +0 -1
- package/dist/server/schema-builder-extensions.js +0 -48
- package/dist/server/schema-builder-extensions.js.map +0 -1
- package/dist/server/sse-adapter.d.ts +0 -64
- package/dist/server/sse-adapter.d.ts.map +0 -1
- package/dist/server/sse-adapter.js +0 -227
- package/dist/server/sse-adapter.js.map +0 -1
- package/dist/server/sse-types.d.ts +0 -192
- package/dist/server/sse-types.d.ts.map +0 -1
- package/dist/server/sse-types.js +0 -63
- package/dist/server/sse-types.js.map +0 -1
- package/dist/server/ws-adapter.d.ts +0 -39
- package/dist/server/ws-adapter.d.ts.map +0 -1
- package/dist/server/ws-adapter.js +0 -247
- package/dist/server/ws-adapter.js.map +0 -1
- package/dist/server/ws-types.d.ts +0 -169
- package/dist/server/ws-types.d.ts.map +0 -1
- package/dist/server/ws-types.js +0 -11
- package/dist/server/ws-types.js.map +0 -1
- package/dist/server/ws-utils.d.ts +0 -42
- package/dist/server/ws-utils.d.ts.map +0 -1
- package/dist/server/ws-utils.js +0 -99
- package/dist/server/ws-utils.js.map +0 -1
- package/src/analyzer-extension.ts +0 -254
- package/src/builder/execute.ts +0 -153
- package/src/builder/field-builders.ts +0 -322
- package/src/builder/index.ts +0 -48
- package/src/builder/pipe-api.ts +0 -312
- package/src/builder/schema-builder.ts +0 -970
- package/src/builder/type-registry.ts +0 -670
- package/src/builder/types.ts +0 -305
- package/src/context.ts +0 -23
- package/src/error.ts +0 -32
- package/src/extensions.ts +0 -240
- package/src/index.ts +0 -32
- package/src/loader.ts +0 -363
- package/src/resolver-context.ts +0 -253
- package/src/schema-mapping.ts +0 -307
- package/src/server/cache-control.ts +0 -590
- package/src/server/complexity.ts +0 -774
- package/src/server/config.ts +0 -174
- package/src/server/graphiql.ts +0 -38
- package/src/server/index.ts +0 -96
- package/src/server/router.ts +0 -432
- package/src/server/schema-builder-extensions.ts +0 -51
- package/src/server/sse-adapter.ts +0 -327
- package/src/server/sse-types.ts +0 -234
- package/src/server/ws-adapter.ts +0 -355
- package/src/server/ws-types.ts +0 -192
- package/src/server/ws-utils.ts +0 -136
package/builder/index.js
ADDED
|
@@ -0,0 +1,1390 @@
|
|
|
1
|
+
import { GraphQLDirective, GraphQLEnumType, GraphQLInputObjectType, GraphQLInterfaceType, GraphQLObjectType, GraphQLUnionType, GraphQLSchema, GraphQLNonNull, GraphQLString, GraphQLFloat, GraphQLBoolean, GraphQLInt, GraphQLList, parse, GraphQLError, validate, execute as execute$1 } from 'graphql';
|
|
2
|
+
export { DirectiveLocation } from 'graphql';
|
|
3
|
+
import { Pipeable, Context, Runtime, Queue, Option, Effect, Stream, Fiber, Ref } from 'effect';
|
|
4
|
+
import * as S2 from 'effect/Schema';
|
|
5
|
+
import * as AST from 'effect/SchemaAST';
|
|
6
|
+
|
|
7
|
+
// src/builder/index.ts
|
|
8
|
+
var isIntegerType = (ast) => {
|
|
9
|
+
if (ast._tag === "Refinement") {
|
|
10
|
+
const refinement = ast;
|
|
11
|
+
const annotations = refinement.annotations;
|
|
12
|
+
if (annotations) {
|
|
13
|
+
const identifier = AST.getIdentifierAnnotation(refinement);
|
|
14
|
+
if (identifier._tag === "Some" && identifier.value === "Int") {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return isIntegerType(refinement.from);
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
};
|
|
22
|
+
var toGraphQLType = (schema) => {
|
|
23
|
+
const ast = schema.ast;
|
|
24
|
+
if (ast._tag === "StringKeyword") return GraphQLString;
|
|
25
|
+
if (ast._tag === "NumberKeyword") return GraphQLFloat;
|
|
26
|
+
if (ast._tag === "BooleanKeyword") return GraphQLBoolean;
|
|
27
|
+
if (ast._tag === "Refinement") {
|
|
28
|
+
if (isIntegerType(ast)) {
|
|
29
|
+
return GraphQLInt;
|
|
30
|
+
}
|
|
31
|
+
return toGraphQLType(S2.make(ast.from));
|
|
32
|
+
}
|
|
33
|
+
if (ast._tag === "Literal") {
|
|
34
|
+
if (typeof ast.literal === "string") return GraphQLString;
|
|
35
|
+
if (typeof ast.literal === "number") {
|
|
36
|
+
return Number.isInteger(ast.literal) ? GraphQLInt : GraphQLFloat;
|
|
37
|
+
}
|
|
38
|
+
if (typeof ast.literal === "boolean") return GraphQLBoolean;
|
|
39
|
+
}
|
|
40
|
+
if (ast._tag === "TupleType") {
|
|
41
|
+
const elements = ast.elements;
|
|
42
|
+
if (elements.length > 0) {
|
|
43
|
+
const elementSchema = S2.make(elements[0].type);
|
|
44
|
+
return new GraphQLList(toGraphQLType(elementSchema));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (ast._tag === "TypeLiteral") {
|
|
48
|
+
const fields = {};
|
|
49
|
+
for (const field2 of ast.propertySignatures) {
|
|
50
|
+
const fieldName = String(field2.name);
|
|
51
|
+
const fieldSchema = S2.make(field2.type);
|
|
52
|
+
let fieldType = toGraphQLType(fieldSchema);
|
|
53
|
+
if (!field2.isOptional) {
|
|
54
|
+
fieldType = new GraphQLNonNull(fieldType);
|
|
55
|
+
}
|
|
56
|
+
fields[fieldName] = { type: fieldType };
|
|
57
|
+
}
|
|
58
|
+
const typeName = schema.annotations?.identifier || `Object_${Math.random().toString(36).slice(2, 11)}`;
|
|
59
|
+
return new GraphQLObjectType({
|
|
60
|
+
name: typeName,
|
|
61
|
+
fields
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (ast._tag === "Transformation") {
|
|
65
|
+
return toGraphQLType(S2.make(ast.to));
|
|
66
|
+
}
|
|
67
|
+
if (ast._tag === "Union") {
|
|
68
|
+
const types = ast.types;
|
|
69
|
+
if (types.length > 0) {
|
|
70
|
+
return toGraphQLType(S2.make(types[0]));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (ast._tag === "Suspend") {
|
|
74
|
+
const innerAst = ast.f();
|
|
75
|
+
return toGraphQLType(S2.make(innerAst));
|
|
76
|
+
}
|
|
77
|
+
return GraphQLString;
|
|
78
|
+
};
|
|
79
|
+
var toGraphQLInputType = (schema) => {
|
|
80
|
+
const ast = schema.ast;
|
|
81
|
+
if (ast._tag === "StringKeyword") return GraphQLString;
|
|
82
|
+
if (ast._tag === "NumberKeyword") return GraphQLFloat;
|
|
83
|
+
if (ast._tag === "BooleanKeyword") return GraphQLBoolean;
|
|
84
|
+
if (ast._tag === "Refinement") {
|
|
85
|
+
if (isIntegerType(ast)) {
|
|
86
|
+
return GraphQLInt;
|
|
87
|
+
}
|
|
88
|
+
return toGraphQLInputType(S2.make(ast.from));
|
|
89
|
+
}
|
|
90
|
+
if (ast._tag === "Literal") {
|
|
91
|
+
if (typeof ast.literal === "string") return GraphQLString;
|
|
92
|
+
if (typeof ast.literal === "number") {
|
|
93
|
+
return Number.isInteger(ast.literal) ? GraphQLInt : GraphQLFloat;
|
|
94
|
+
}
|
|
95
|
+
if (typeof ast.literal === "boolean") return GraphQLBoolean;
|
|
96
|
+
}
|
|
97
|
+
if (ast._tag === "TupleType") {
|
|
98
|
+
const elements = ast.elements;
|
|
99
|
+
if (elements.length > 0) {
|
|
100
|
+
const elementSchema = S2.make(elements[0].type);
|
|
101
|
+
return new GraphQLList(toGraphQLInputType(elementSchema));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (ast._tag === "TypeLiteral") {
|
|
105
|
+
const fields = {};
|
|
106
|
+
for (const field2 of ast.propertySignatures) {
|
|
107
|
+
const fieldName = String(field2.name);
|
|
108
|
+
const fieldSchema = S2.make(field2.type);
|
|
109
|
+
let fieldType = toGraphQLInputType(fieldSchema);
|
|
110
|
+
if (!field2.isOptional) {
|
|
111
|
+
fieldType = new GraphQLNonNull(fieldType);
|
|
112
|
+
}
|
|
113
|
+
fields[fieldName] = { type: fieldType };
|
|
114
|
+
}
|
|
115
|
+
const typeName = schema.annotations?.identifier || `Input_${Math.random().toString(36).slice(2, 11)}`;
|
|
116
|
+
return new GraphQLInputObjectType({
|
|
117
|
+
name: typeName,
|
|
118
|
+
fields
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (ast._tag === "Transformation") {
|
|
122
|
+
return toGraphQLInputType(S2.make(ast.from));
|
|
123
|
+
}
|
|
124
|
+
if (ast._tag === "Union") {
|
|
125
|
+
const types = ast.types;
|
|
126
|
+
if (types.length > 0) {
|
|
127
|
+
return toGraphQLInputType(S2.make(types[0]));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (ast._tag === "Suspend") {
|
|
131
|
+
const innerAst = ast.f();
|
|
132
|
+
return toGraphQLInputType(S2.make(innerAst));
|
|
133
|
+
}
|
|
134
|
+
return GraphQLString;
|
|
135
|
+
};
|
|
136
|
+
var toGraphQLArgs = (schema) => {
|
|
137
|
+
const ast = schema.ast;
|
|
138
|
+
if (ast._tag === "TypeLiteral") {
|
|
139
|
+
const args = {};
|
|
140
|
+
for (const field2 of ast.propertySignatures) {
|
|
141
|
+
const fieldName = String(field2.name);
|
|
142
|
+
const fieldSchema = S2.make(field2.type);
|
|
143
|
+
let fieldType = toGraphQLInputType(fieldSchema);
|
|
144
|
+
if (!field2.isOptional) {
|
|
145
|
+
fieldType = new GraphQLNonNull(fieldType);
|
|
146
|
+
}
|
|
147
|
+
args[fieldName] = { type: fieldType };
|
|
148
|
+
}
|
|
149
|
+
return args;
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`Schema must be an object type to convert to GraphQL arguments`);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// src/builder/type-registry.ts
|
|
155
|
+
function getSchemaName(schema) {
|
|
156
|
+
const ast = schema.ast;
|
|
157
|
+
if (ast._tag === "Transformation") {
|
|
158
|
+
const identifier = AST.getIdentifierAnnotation(ast.to);
|
|
159
|
+
if (identifier._tag === "Some") {
|
|
160
|
+
return identifier.value;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (ast._tag === "TypeLiteral") {
|
|
164
|
+
const tagProp = ast.propertySignatures.find((p) => String(p.name) === "_tag");
|
|
165
|
+
if (tagProp && tagProp.type._tag === "Literal" && typeof tagProp.type.literal === "string") {
|
|
166
|
+
return tagProp.type.literal;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return void 0;
|
|
170
|
+
}
|
|
171
|
+
function buildReverseLookups(ctx) {
|
|
172
|
+
if (!ctx.schemaToTypeName) {
|
|
173
|
+
ctx.schemaToTypeName = /* @__PURE__ */ new Map();
|
|
174
|
+
ctx.astToTypeName = /* @__PURE__ */ new Map();
|
|
175
|
+
for (const [typeName, typeReg] of ctx.types) {
|
|
176
|
+
ctx.schemaToTypeName.set(typeReg.schema, typeName);
|
|
177
|
+
ctx.astToTypeName.set(typeReg.schema.ast, typeName);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!ctx.schemaToInterfaceName) {
|
|
181
|
+
ctx.schemaToInterfaceName = /* @__PURE__ */ new Map();
|
|
182
|
+
ctx.astToInterfaceName = /* @__PURE__ */ new Map();
|
|
183
|
+
for (const [interfaceName, interfaceReg] of ctx.interfaces) {
|
|
184
|
+
ctx.schemaToInterfaceName.set(interfaceReg.schema, interfaceName);
|
|
185
|
+
ctx.astToInterfaceName.set(interfaceReg.schema.ast, interfaceName);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!ctx.schemaToInputName) {
|
|
189
|
+
ctx.schemaToInputName = /* @__PURE__ */ new Map();
|
|
190
|
+
ctx.astToInputName = /* @__PURE__ */ new Map();
|
|
191
|
+
for (const [inputName, inputReg] of ctx.inputs) {
|
|
192
|
+
ctx.schemaToInputName.set(inputReg.schema, inputName);
|
|
193
|
+
ctx.astToInputName.set(inputReg.schema.ast, inputName);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!ctx.enumSortedValues) {
|
|
197
|
+
ctx.enumSortedValues = /* @__PURE__ */ new Map();
|
|
198
|
+
ctx.literalToEnumName = /* @__PURE__ */ new Map();
|
|
199
|
+
for (const [enumName, enumReg] of ctx.enums) {
|
|
200
|
+
ctx.enumSortedValues.set(enumName, [...enumReg.values].sort());
|
|
201
|
+
for (const value of enumReg.values) {
|
|
202
|
+
ctx.literalToEnumName.set(value, enumName);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!ctx.unionSortedTypes) {
|
|
207
|
+
ctx.unionSortedTypes = /* @__PURE__ */ new Map();
|
|
208
|
+
for (const [unionName, unionReg] of ctx.unions) {
|
|
209
|
+
ctx.unionSortedTypes.set(unionName, [...unionReg.types].sort());
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
var nonNullCache = /* @__PURE__ */ new WeakMap();
|
|
214
|
+
function getNonNull(type) {
|
|
215
|
+
let cached = nonNullCache.get(type);
|
|
216
|
+
if (!cached) {
|
|
217
|
+
cached = new GraphQLNonNull(type);
|
|
218
|
+
nonNullCache.set(type, cached);
|
|
219
|
+
}
|
|
220
|
+
return cached;
|
|
221
|
+
}
|
|
222
|
+
function toGraphQLTypeWithRegistry(schema, ctx) {
|
|
223
|
+
buildReverseLookups(ctx);
|
|
224
|
+
const ast = schema.ast;
|
|
225
|
+
const registeredType = findRegisteredType(schema, ast, ctx);
|
|
226
|
+
if (registeredType) return registeredType;
|
|
227
|
+
const registeredInterface = findRegisteredInterface(schema, ast, ctx);
|
|
228
|
+
if (registeredInterface) return registeredInterface;
|
|
229
|
+
if (ast._tag === "Transformation") {
|
|
230
|
+
return handleTransformationAST(ast, ctx);
|
|
231
|
+
}
|
|
232
|
+
if (ast._tag === "Union") {
|
|
233
|
+
return handleUnionAST(ast, ctx);
|
|
234
|
+
}
|
|
235
|
+
if (ast._tag === "Literal") {
|
|
236
|
+
const enumType2 = findEnumForLiteral(ast, ctx);
|
|
237
|
+
if (enumType2) return enumType2;
|
|
238
|
+
}
|
|
239
|
+
if (ast._tag === "TupleType") {
|
|
240
|
+
return handleTupleTypeAST(ast, ctx);
|
|
241
|
+
}
|
|
242
|
+
if (ast._tag === "Suspend") {
|
|
243
|
+
const innerAst = ast.f();
|
|
244
|
+
return toGraphQLTypeWithRegistry(S2.make(innerAst), ctx);
|
|
245
|
+
}
|
|
246
|
+
return toGraphQLType(schema);
|
|
247
|
+
}
|
|
248
|
+
function findRegisteredType(schema, ast, ctx) {
|
|
249
|
+
const typeName = ctx.schemaToTypeName?.get(schema) ?? ctx.astToTypeName?.get(ast);
|
|
250
|
+
if (typeName) {
|
|
251
|
+
return ctx.typeRegistry.get(typeName);
|
|
252
|
+
}
|
|
253
|
+
return void 0;
|
|
254
|
+
}
|
|
255
|
+
function findRegisteredInterface(schema, ast, ctx) {
|
|
256
|
+
const interfaceName = ctx.schemaToInterfaceName?.get(schema) ?? ctx.astToInterfaceName?.get(ast);
|
|
257
|
+
if (interfaceName) {
|
|
258
|
+
return ctx.interfaceRegistry.get(interfaceName);
|
|
259
|
+
}
|
|
260
|
+
return void 0;
|
|
261
|
+
}
|
|
262
|
+
function handleTransformationAST(ast, ctx) {
|
|
263
|
+
const toAst = ast.to;
|
|
264
|
+
if (toAst._tag === "TupleType") {
|
|
265
|
+
if (toAst.rest && toAst.rest.length > 0) {
|
|
266
|
+
const elementSchema = S2.make(toAst.rest[0].type);
|
|
267
|
+
const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
|
|
268
|
+
return new GraphQLList(elementType);
|
|
269
|
+
} else if (toAst.elements.length > 0) {
|
|
270
|
+
const elementSchema = S2.make(toAst.elements[0].type);
|
|
271
|
+
const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
|
|
272
|
+
return new GraphQLList(elementType);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return toGraphQLTypeWithRegistry(S2.make(ast.to), ctx);
|
|
276
|
+
}
|
|
277
|
+
function handleUnionAST(ast, ctx) {
|
|
278
|
+
const allLiterals = ast.types.every((t) => t._tag === "Literal");
|
|
279
|
+
if (allLiterals) {
|
|
280
|
+
const enumType2 = findEnumForLiteralUnion(ast.types, ctx);
|
|
281
|
+
if (enumType2) return enumType2;
|
|
282
|
+
} else {
|
|
283
|
+
const unionType2 = findRegisteredUnion(ast.types, ctx);
|
|
284
|
+
if (unionType2) return unionType2;
|
|
285
|
+
}
|
|
286
|
+
if (ast.types.length > 0) {
|
|
287
|
+
return toGraphQLTypeWithRegistry(S2.make(ast.types[0]), ctx);
|
|
288
|
+
}
|
|
289
|
+
return toGraphQLType(S2.make(ast));
|
|
290
|
+
}
|
|
291
|
+
function findEnumForLiteralUnion(types, ctx) {
|
|
292
|
+
const literalValues = types.map((t) => String(t.literal)).sort();
|
|
293
|
+
for (const [enumName] of ctx.enums) {
|
|
294
|
+
const enumValues = ctx.enumSortedValues?.get(enumName);
|
|
295
|
+
if (enumValues && literalValues.length === enumValues.length && literalValues.every((v, i) => v === enumValues[i])) {
|
|
296
|
+
return ctx.enumRegistry.get(enumName);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return void 0;
|
|
300
|
+
}
|
|
301
|
+
function findRegisteredUnion(types, ctx) {
|
|
302
|
+
const memberTags = [];
|
|
303
|
+
for (const memberAst of types) {
|
|
304
|
+
if (memberAst._tag === "TypeLiteral") {
|
|
305
|
+
const tagProp = memberAst.propertySignatures.find((p) => String(p.name) === "_tag");
|
|
306
|
+
if (tagProp && tagProp.type._tag === "Literal") {
|
|
307
|
+
memberTags.push(String(tagProp.type.literal));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (memberTags.length === types.length) {
|
|
312
|
+
const sortedTags = memberTags.sort();
|
|
313
|
+
for (const [unionName] of ctx.unions) {
|
|
314
|
+
const unionTypes = ctx.unionSortedTypes?.get(unionName);
|
|
315
|
+
if (unionTypes && sortedTags.length === unionTypes.length && sortedTags.every((tag, i) => tag === unionTypes[i])) {
|
|
316
|
+
return ctx.unionRegistry.get(unionName);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return void 0;
|
|
321
|
+
}
|
|
322
|
+
function findEnumForLiteral(ast, ctx) {
|
|
323
|
+
const literalValue = String(ast.literal);
|
|
324
|
+
const enumName = ctx.literalToEnumName?.get(literalValue);
|
|
325
|
+
if (enumName) {
|
|
326
|
+
return ctx.enumRegistry.get(enumName);
|
|
327
|
+
}
|
|
328
|
+
return void 0;
|
|
329
|
+
}
|
|
330
|
+
function handleTupleTypeAST(ast, ctx) {
|
|
331
|
+
if (ast.rest && ast.rest.length > 0) {
|
|
332
|
+
const elementSchema = S2.make(ast.rest[0].type);
|
|
333
|
+
const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
|
|
334
|
+
return new GraphQLList(elementType);
|
|
335
|
+
} else if (ast.elements && ast.elements.length > 0) {
|
|
336
|
+
const elementSchema = S2.make(ast.elements[0].type);
|
|
337
|
+
const elementType = toGraphQLTypeWithRegistry(elementSchema, ctx);
|
|
338
|
+
return new GraphQLList(elementType);
|
|
339
|
+
}
|
|
340
|
+
return toGraphQLType(S2.make(ast));
|
|
341
|
+
}
|
|
342
|
+
function schemaToFields(schema, ctx) {
|
|
343
|
+
let ast = schema.ast;
|
|
344
|
+
if (ast._tag === "Transformation") {
|
|
345
|
+
ast = ast.to;
|
|
346
|
+
}
|
|
347
|
+
if (ast._tag === "Declaration") {
|
|
348
|
+
const typeParams = ast.typeParameters;
|
|
349
|
+
if (typeParams && typeParams.length > 0 && typeParams[0]._tag === "TypeLiteral") {
|
|
350
|
+
ast = typeParams[0];
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (ast._tag === "TypeLiteral") {
|
|
354
|
+
const fields = {};
|
|
355
|
+
for (const field2 of ast.propertySignatures) {
|
|
356
|
+
const fieldName = String(field2.name);
|
|
357
|
+
const fieldSchema = S2.make(field2.type);
|
|
358
|
+
let fieldType = toGraphQLTypeWithRegistry(fieldSchema, ctx);
|
|
359
|
+
if (!field2.isOptional) {
|
|
360
|
+
fieldType = getNonNull(fieldType);
|
|
361
|
+
}
|
|
362
|
+
fields[fieldName] = { type: fieldType };
|
|
363
|
+
}
|
|
364
|
+
return fields;
|
|
365
|
+
}
|
|
366
|
+
return {};
|
|
367
|
+
}
|
|
368
|
+
function schemaToInputFields(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
|
|
369
|
+
const ast = schema.ast;
|
|
370
|
+
if (ast._tag === "TypeLiteral") {
|
|
371
|
+
const fields = {};
|
|
372
|
+
for (const field2 of ast.propertySignatures) {
|
|
373
|
+
const fieldName = String(field2.name);
|
|
374
|
+
const fieldSchema = S2.make(field2.type);
|
|
375
|
+
let fieldType = toGraphQLInputTypeWithRegistry(
|
|
376
|
+
fieldSchema,
|
|
377
|
+
enumRegistry,
|
|
378
|
+
inputRegistry,
|
|
379
|
+
inputs,
|
|
380
|
+
enums,
|
|
381
|
+
cache
|
|
382
|
+
);
|
|
383
|
+
if (!field2.isOptional) {
|
|
384
|
+
fieldType = getNonNull(fieldType);
|
|
385
|
+
}
|
|
386
|
+
fields[fieldName] = { type: fieldType };
|
|
387
|
+
}
|
|
388
|
+
return fields;
|
|
389
|
+
}
|
|
390
|
+
return {};
|
|
391
|
+
}
|
|
392
|
+
function buildInputTypeLookupCache(inputs, enums) {
|
|
393
|
+
const cache = {
|
|
394
|
+
schemaToInputName: /* @__PURE__ */ new Map(),
|
|
395
|
+
astToInputName: /* @__PURE__ */ new Map(),
|
|
396
|
+
literalToEnumName: /* @__PURE__ */ new Map(),
|
|
397
|
+
enumSortedValues: /* @__PURE__ */ new Map()
|
|
398
|
+
};
|
|
399
|
+
for (const [inputName, inputReg] of inputs) {
|
|
400
|
+
cache.schemaToInputName.set(inputReg.schema, inputName);
|
|
401
|
+
cache.astToInputName.set(inputReg.schema.ast, inputName);
|
|
402
|
+
}
|
|
403
|
+
for (const [enumName, enumReg] of enums) {
|
|
404
|
+
cache.enumSortedValues.set(enumName, [...enumReg.values].sort());
|
|
405
|
+
for (const value of enumReg.values) {
|
|
406
|
+
cache.literalToEnumName.set(value, enumName);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return cache;
|
|
410
|
+
}
|
|
411
|
+
function toGraphQLInputTypeWithRegistry(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
|
|
412
|
+
const ast = schema.ast;
|
|
413
|
+
if (ast._tag === "Transformation") {
|
|
414
|
+
const toAst = ast.to;
|
|
415
|
+
return toGraphQLInputTypeWithRegistry(
|
|
416
|
+
S2.make(toAst),
|
|
417
|
+
enumRegistry,
|
|
418
|
+
inputRegistry,
|
|
419
|
+
inputs,
|
|
420
|
+
enums,
|
|
421
|
+
cache
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
if (cache?.schemaToInputName || cache?.astToInputName) {
|
|
425
|
+
const inputName = cache.schemaToInputName?.get(schema) ?? cache.astToInputName?.get(ast);
|
|
426
|
+
if (inputName) {
|
|
427
|
+
const result = inputRegistry.get(inputName);
|
|
428
|
+
if (result) return result;
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
for (const [inputName, inputReg] of inputs) {
|
|
432
|
+
if (inputReg.schema.ast === ast || inputReg.schema === schema) {
|
|
433
|
+
const result = inputRegistry.get(inputName);
|
|
434
|
+
if (result) return result;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (ast._tag === "Union") {
|
|
439
|
+
const unionAst = ast;
|
|
440
|
+
const nonUndefinedTypes = unionAst.types.filter((t) => t._tag !== "UndefinedKeyword");
|
|
441
|
+
if (nonUndefinedTypes.length === 1 && nonUndefinedTypes[0]._tag === "Union") {
|
|
442
|
+
return toGraphQLInputTypeWithRegistry(
|
|
443
|
+
S2.make(nonUndefinedTypes[0]),
|
|
444
|
+
enumRegistry,
|
|
445
|
+
inputRegistry,
|
|
446
|
+
inputs,
|
|
447
|
+
enums,
|
|
448
|
+
cache
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
if (nonUndefinedTypes.length === 1 && nonUndefinedTypes[0]._tag === "TypeLiteral") {
|
|
452
|
+
return toGraphQLInputTypeWithRegistry(
|
|
453
|
+
S2.make(nonUndefinedTypes[0]),
|
|
454
|
+
enumRegistry,
|
|
455
|
+
inputRegistry,
|
|
456
|
+
inputs,
|
|
457
|
+
enums,
|
|
458
|
+
cache
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
const allLiterals = unionAst.types.every((t) => t._tag === "Literal");
|
|
462
|
+
if (allLiterals) {
|
|
463
|
+
const literalValues = unionAst.types.map((t) => String(t.literal)).sort();
|
|
464
|
+
for (const [enumName] of enums) {
|
|
465
|
+
const enumValues = cache?.enumSortedValues?.get(enumName) ?? [...enums.get(enumName).values].sort();
|
|
466
|
+
if (literalValues.length === enumValues.length && literalValues.every((v, i) => v === enumValues[i])) {
|
|
467
|
+
const result = enumRegistry.get(enumName);
|
|
468
|
+
if (result) return result;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (ast._tag === "Literal") {
|
|
474
|
+
const literalValue = String(ast.literal);
|
|
475
|
+
if (cache?.literalToEnumName) {
|
|
476
|
+
const enumName = cache.literalToEnumName.get(literalValue);
|
|
477
|
+
if (enumName) {
|
|
478
|
+
const result = enumRegistry.get(enumName);
|
|
479
|
+
if (result) return result;
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
for (const [enumName, enumReg] of enums) {
|
|
483
|
+
if (enumReg.values.includes(literalValue)) {
|
|
484
|
+
const result = enumRegistry.get(enumName);
|
|
485
|
+
if (result) return result;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (ast._tag === "Suspend") {
|
|
491
|
+
const innerAst = ast.f();
|
|
492
|
+
return toGraphQLInputTypeWithRegistry(
|
|
493
|
+
S2.make(innerAst),
|
|
494
|
+
enumRegistry,
|
|
495
|
+
inputRegistry,
|
|
496
|
+
inputs,
|
|
497
|
+
enums,
|
|
498
|
+
cache
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return toGraphQLInputType(schema);
|
|
502
|
+
}
|
|
503
|
+
function toGraphQLArgsWithRegistry(schema, enumRegistry, inputRegistry, inputs, enums, cache) {
|
|
504
|
+
const ast = schema.ast;
|
|
505
|
+
if (ast._tag === "TypeLiteral") {
|
|
506
|
+
const args = {};
|
|
507
|
+
for (const field2 of ast.propertySignatures) {
|
|
508
|
+
const fieldName = String(field2.name);
|
|
509
|
+
const fieldSchema = S2.make(field2.type);
|
|
510
|
+
let fieldType = toGraphQLInputTypeWithRegistry(
|
|
511
|
+
fieldSchema,
|
|
512
|
+
enumRegistry,
|
|
513
|
+
inputRegistry,
|
|
514
|
+
inputs,
|
|
515
|
+
enums,
|
|
516
|
+
cache
|
|
517
|
+
);
|
|
518
|
+
if (!field2.isOptional) {
|
|
519
|
+
fieldType = getNonNull(fieldType);
|
|
520
|
+
}
|
|
521
|
+
args[fieldName] = { type: fieldType };
|
|
522
|
+
}
|
|
523
|
+
return args;
|
|
524
|
+
}
|
|
525
|
+
return toGraphQLArgs(schema);
|
|
526
|
+
}
|
|
527
|
+
function applyDirectives(effect, directives, directiveRegistrations) {
|
|
528
|
+
if (!directives) return effect;
|
|
529
|
+
let wrapped = effect;
|
|
530
|
+
for (const directiveApp of directives) {
|
|
531
|
+
const directiveReg = directiveRegistrations.get(directiveApp.name);
|
|
532
|
+
if (directiveReg?.apply) {
|
|
533
|
+
wrapped = directiveReg.apply(directiveApp.args ?? {})(wrapped);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return wrapped;
|
|
537
|
+
}
|
|
538
|
+
function applyMiddleware(effect, context, middlewares) {
|
|
539
|
+
if (middlewares.length === 0) return effect;
|
|
540
|
+
let wrapped = effect;
|
|
541
|
+
for (let i = middlewares.length - 1; i >= 0; i--) {
|
|
542
|
+
const middleware2 = middlewares[i];
|
|
543
|
+
if (middleware2.match && !middleware2.match(context.info)) {
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
wrapped = middleware2.apply(wrapped, context);
|
|
547
|
+
}
|
|
548
|
+
return wrapped;
|
|
549
|
+
}
|
|
550
|
+
function buildField(config, ctx) {
|
|
551
|
+
const fieldConfig = {
|
|
552
|
+
type: toGraphQLTypeWithRegistry(config.type, ctx),
|
|
553
|
+
resolve: async (_parent, args, context, info) => {
|
|
554
|
+
let effect = applyDirectives(
|
|
555
|
+
config.resolve(args),
|
|
556
|
+
config.directives,
|
|
557
|
+
ctx.directiveRegistrations
|
|
558
|
+
);
|
|
559
|
+
const middlewareContext = { parent: _parent, args, info };
|
|
560
|
+
effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
|
|
561
|
+
return await Runtime.runPromise(context.runtime)(effect);
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
if (config.args) {
|
|
565
|
+
fieldConfig.args = toGraphQLArgsWithRegistry(
|
|
566
|
+
config.args,
|
|
567
|
+
ctx.enumRegistry,
|
|
568
|
+
ctx.inputRegistry,
|
|
569
|
+
ctx.inputs,
|
|
570
|
+
ctx.enums,
|
|
571
|
+
ctx.inputTypeLookupCache
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
if (config.description) {
|
|
575
|
+
fieldConfig.description = config.description;
|
|
576
|
+
}
|
|
577
|
+
return fieldConfig;
|
|
578
|
+
}
|
|
579
|
+
function buildObjectField(config, ctx) {
|
|
580
|
+
const fieldConfig = {
|
|
581
|
+
type: toGraphQLTypeWithRegistry(config.type, ctx),
|
|
582
|
+
resolve: async (parent, args, context, info) => {
|
|
583
|
+
let effect = applyDirectives(
|
|
584
|
+
config.resolve(parent, args),
|
|
585
|
+
config.directives,
|
|
586
|
+
ctx.directiveRegistrations
|
|
587
|
+
);
|
|
588
|
+
const middlewareContext = { parent, args, info };
|
|
589
|
+
effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
|
|
590
|
+
return await Runtime.runPromise(context.runtime)(effect);
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
if (config.args) {
|
|
594
|
+
fieldConfig.args = toGraphQLArgsWithRegistry(
|
|
595
|
+
config.args,
|
|
596
|
+
ctx.enumRegistry,
|
|
597
|
+
ctx.inputRegistry,
|
|
598
|
+
ctx.inputs,
|
|
599
|
+
ctx.enums,
|
|
600
|
+
ctx.inputTypeLookupCache
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
if (config.description) {
|
|
604
|
+
fieldConfig.description = config.description;
|
|
605
|
+
}
|
|
606
|
+
return fieldConfig;
|
|
607
|
+
}
|
|
608
|
+
function buildSubscriptionField(config, ctx) {
|
|
609
|
+
const fieldConfig = {
|
|
610
|
+
type: toGraphQLTypeWithRegistry(config.type, ctx),
|
|
611
|
+
// The subscribe function returns an AsyncIterator
|
|
612
|
+
subscribe: async (_parent, args, context, info) => {
|
|
613
|
+
let subscribeEffect = config.subscribe(args);
|
|
614
|
+
subscribeEffect = applyDirectives(
|
|
615
|
+
subscribeEffect,
|
|
616
|
+
config.directives,
|
|
617
|
+
ctx.directiveRegistrations
|
|
618
|
+
);
|
|
619
|
+
const middlewareContext = { parent: _parent, args, info };
|
|
620
|
+
subscribeEffect = applyMiddleware(subscribeEffect, middlewareContext, ctx.middlewares);
|
|
621
|
+
const stream = await Runtime.runPromise(context.runtime)(subscribeEffect);
|
|
622
|
+
return streamToAsyncIterator(stream, context.runtime);
|
|
623
|
+
},
|
|
624
|
+
// The resolve function transforms each yielded value
|
|
625
|
+
// If no custom resolve is provided, return the payload directly
|
|
626
|
+
resolve: config.resolve ? async (value, args, context, info) => {
|
|
627
|
+
let effect = config.resolve(value, args);
|
|
628
|
+
const middlewareContext = { parent: value, args, info };
|
|
629
|
+
effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
|
|
630
|
+
return await Runtime.runPromise(context.runtime)(effect);
|
|
631
|
+
} : (value) => value
|
|
632
|
+
};
|
|
633
|
+
if (config.args) {
|
|
634
|
+
fieldConfig.args = toGraphQLArgsWithRegistry(
|
|
635
|
+
config.args,
|
|
636
|
+
ctx.enumRegistry,
|
|
637
|
+
ctx.inputRegistry,
|
|
638
|
+
ctx.inputs,
|
|
639
|
+
ctx.enums,
|
|
640
|
+
ctx.inputTypeLookupCache
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
if (config.description) {
|
|
644
|
+
fieldConfig.description = config.description;
|
|
645
|
+
}
|
|
646
|
+
return fieldConfig;
|
|
647
|
+
}
|
|
648
|
+
function streamToAsyncIterator(stream, runtime) {
|
|
649
|
+
let queue;
|
|
650
|
+
let fiber;
|
|
651
|
+
let initialized = false;
|
|
652
|
+
let done = false;
|
|
653
|
+
const initialize = async () => {
|
|
654
|
+
if (initialized) return;
|
|
655
|
+
initialized = true;
|
|
656
|
+
queue = await Runtime.runPromise(runtime)(Queue.unbounded());
|
|
657
|
+
fiber = Runtime.runFork(runtime)(
|
|
658
|
+
Effect.ensuring(
|
|
659
|
+
Stream.runForEach(stream, (value) => Queue.offer(queue, Option.some(value))),
|
|
660
|
+
// Signal completion by pushing None
|
|
661
|
+
Queue.offer(queue, Option.none())
|
|
662
|
+
)
|
|
663
|
+
);
|
|
664
|
+
};
|
|
665
|
+
return {
|
|
666
|
+
[Symbol.asyncIterator]() {
|
|
667
|
+
return this;
|
|
668
|
+
},
|
|
669
|
+
async next() {
|
|
670
|
+
await initialize();
|
|
671
|
+
if (done) {
|
|
672
|
+
return { done: true, value: void 0 };
|
|
673
|
+
}
|
|
674
|
+
try {
|
|
675
|
+
const optionValue = await Runtime.runPromise(runtime)(Queue.take(queue));
|
|
676
|
+
if (Option.isNone(optionValue)) {
|
|
677
|
+
done = true;
|
|
678
|
+
return { done: true, value: void 0 };
|
|
679
|
+
}
|
|
680
|
+
return { done: false, value: optionValue.value };
|
|
681
|
+
} catch (error) {
|
|
682
|
+
done = true;
|
|
683
|
+
throw error;
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
async return() {
|
|
687
|
+
done = true;
|
|
688
|
+
if (initialized) {
|
|
689
|
+
try {
|
|
690
|
+
await Runtime.runPromise(runtime)(
|
|
691
|
+
Fiber.interrupt(fiber)
|
|
692
|
+
);
|
|
693
|
+
await Runtime.runPromise(runtime)(Queue.shutdown(queue));
|
|
694
|
+
} catch {
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
return { done: true, value: void 0 };
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/builder/schema-builder.ts
|
|
703
|
+
function updateState(state, key, value) {
|
|
704
|
+
return { ...state, [key]: value };
|
|
705
|
+
}
|
|
706
|
+
var GraphQLSchemaBuilder = class _GraphQLSchemaBuilder {
|
|
707
|
+
constructor(state) {
|
|
708
|
+
this.state = state;
|
|
709
|
+
}
|
|
710
|
+
pipe() {
|
|
711
|
+
return Pipeable.pipeArguments(this, arguments);
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Create an empty schema builder
|
|
715
|
+
*/
|
|
716
|
+
static empty = new _GraphQLSchemaBuilder({
|
|
717
|
+
types: /* @__PURE__ */ new Map(),
|
|
718
|
+
interfaces: /* @__PURE__ */ new Map(),
|
|
719
|
+
enums: /* @__PURE__ */ new Map(),
|
|
720
|
+
unions: /* @__PURE__ */ new Map(),
|
|
721
|
+
inputs: /* @__PURE__ */ new Map(),
|
|
722
|
+
directives: /* @__PURE__ */ new Map(),
|
|
723
|
+
middlewares: [],
|
|
724
|
+
extensions: [],
|
|
725
|
+
queries: /* @__PURE__ */ new Map(),
|
|
726
|
+
mutations: /* @__PURE__ */ new Map(),
|
|
727
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
728
|
+
objectFields: /* @__PURE__ */ new Map()
|
|
729
|
+
});
|
|
730
|
+
/**
|
|
731
|
+
* Create a new builder with updated state
|
|
732
|
+
*/
|
|
733
|
+
with(newState) {
|
|
734
|
+
return new _GraphQLSchemaBuilder(newState);
|
|
735
|
+
}
|
|
736
|
+
// ============================================================================
|
|
737
|
+
// Registration Methods
|
|
738
|
+
// ============================================================================
|
|
739
|
+
/**
|
|
740
|
+
* Add a query field
|
|
741
|
+
*/
|
|
742
|
+
query(name, config) {
|
|
743
|
+
const newQueries = new Map(this.state.queries);
|
|
744
|
+
newQueries.set(name, config);
|
|
745
|
+
return this.with(updateState(this.state, "queries", newQueries));
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Add a mutation field
|
|
749
|
+
*/
|
|
750
|
+
mutation(name, config) {
|
|
751
|
+
const newMutations = new Map(this.state.mutations);
|
|
752
|
+
newMutations.set(name, config);
|
|
753
|
+
return this.with(updateState(this.state, "mutations", newMutations));
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Add a subscription field
|
|
757
|
+
*
|
|
758
|
+
* Subscriptions return a Stream that yields values over time.
|
|
759
|
+
* The subscribe function returns an Effect that produces a Stream.
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* ```typescript
|
|
763
|
+
* builder.subscription("userCreated", {
|
|
764
|
+
* type: User,
|
|
765
|
+
* subscribe: Effect.gen(function*() {
|
|
766
|
+
* const pubsub = yield* PubSubService
|
|
767
|
+
* return pubsub.subscribe("USER_CREATED")
|
|
768
|
+
* }),
|
|
769
|
+
* })
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
subscription(name, config) {
|
|
773
|
+
const newSubscriptions = new Map(this.state.subscriptions);
|
|
774
|
+
newSubscriptions.set(name, config);
|
|
775
|
+
return this.with(updateState(this.state, "subscriptions", newSubscriptions));
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Register an object type from a schema
|
|
779
|
+
*/
|
|
780
|
+
objectType(config) {
|
|
781
|
+
const { schema, implements: implementsInterfaces, directives, cacheControl, fields } = config;
|
|
782
|
+
const name = config.name ?? getSchemaName(schema);
|
|
783
|
+
if (!name) {
|
|
784
|
+
throw new Error(
|
|
785
|
+
"objectType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
const newTypes = new Map(this.state.types);
|
|
789
|
+
newTypes.set(name, { name, schema, implements: implementsInterfaces, directives, cacheControl });
|
|
790
|
+
let newObjectFields = this.state.objectFields;
|
|
791
|
+
if (fields) {
|
|
792
|
+
newObjectFields = new Map(this.state.objectFields);
|
|
793
|
+
const typeFields = /* @__PURE__ */ new Map();
|
|
794
|
+
for (const [fieldName, fieldConfig] of Object.entries(fields)) {
|
|
795
|
+
typeFields.set(fieldName, fieldConfig);
|
|
796
|
+
}
|
|
797
|
+
newObjectFields.set(name, typeFields);
|
|
798
|
+
}
|
|
799
|
+
return this.with({
|
|
800
|
+
...this.state,
|
|
801
|
+
types: newTypes,
|
|
802
|
+
objectFields: newObjectFields
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Register an interface type from a schema
|
|
807
|
+
*/
|
|
808
|
+
interfaceType(config) {
|
|
809
|
+
const { schema, resolveType, directives } = config;
|
|
810
|
+
const name = config.name ?? getSchemaName(schema);
|
|
811
|
+
if (!name) {
|
|
812
|
+
throw new Error(
|
|
813
|
+
"interfaceType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
const newInterfaces = new Map(this.state.interfaces);
|
|
817
|
+
newInterfaces.set(name, {
|
|
818
|
+
name,
|
|
819
|
+
schema,
|
|
820
|
+
resolveType: resolveType ?? ((value) => value._tag),
|
|
821
|
+
directives
|
|
822
|
+
});
|
|
823
|
+
return this.with(updateState(this.state, "interfaces", newInterfaces));
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Register an enum type
|
|
827
|
+
*/
|
|
828
|
+
enumType(config) {
|
|
829
|
+
const { name, values, description, directives } = config;
|
|
830
|
+
const newEnums = new Map(this.state.enums);
|
|
831
|
+
newEnums.set(name, { name, values, description, directives });
|
|
832
|
+
return this.with(updateState(this.state, "enums", newEnums));
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Register a union type
|
|
836
|
+
*/
|
|
837
|
+
unionType(config) {
|
|
838
|
+
const { name, types, resolveType, directives } = config;
|
|
839
|
+
const newUnions = new Map(this.state.unions);
|
|
840
|
+
newUnions.set(name, {
|
|
841
|
+
name,
|
|
842
|
+
types,
|
|
843
|
+
resolveType: resolveType ?? ((value) => value._tag),
|
|
844
|
+
directives
|
|
845
|
+
});
|
|
846
|
+
return this.with(updateState(this.state, "unions", newUnions));
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Register an input type
|
|
850
|
+
*/
|
|
851
|
+
inputType(config) {
|
|
852
|
+
const { schema, description, directives } = config;
|
|
853
|
+
const name = config.name ?? getSchemaName(schema);
|
|
854
|
+
if (!name) {
|
|
855
|
+
throw new Error(
|
|
856
|
+
"inputType requires a name. Either provide one explicitly or use a TaggedStruct/TaggedClass/Schema.Class"
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
const newInputs = new Map(this.state.inputs);
|
|
860
|
+
newInputs.set(name, { name, schema, description, directives });
|
|
861
|
+
return this.with(updateState(this.state, "inputs", newInputs));
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Register a directive
|
|
865
|
+
*/
|
|
866
|
+
directive(config) {
|
|
867
|
+
const newDirectives = new Map(this.state.directives);
|
|
868
|
+
newDirectives.set(config.name, config);
|
|
869
|
+
return this.with(updateState(this.state, "directives", newDirectives));
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Register a middleware
|
|
873
|
+
*
|
|
874
|
+
* Middleware wraps all resolvers (or those matching a pattern) and executes
|
|
875
|
+
* in an "onion" model - first registered middleware is the outermost layer.
|
|
876
|
+
*
|
|
877
|
+
* @param config.name - Middleware name (for debugging/logging)
|
|
878
|
+
* @param config.description - Optional description
|
|
879
|
+
* @param config.match - Optional predicate to filter which fields this applies to
|
|
880
|
+
* @param config.apply - Function that transforms the resolver Effect
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```typescript
|
|
884
|
+
* builder.middleware({
|
|
885
|
+
* name: "logging",
|
|
886
|
+
* apply: (effect, ctx) => Effect.gen(function*() {
|
|
887
|
+
* yield* Effect.logInfo(`Resolving ${ctx.info.fieldName}`)
|
|
888
|
+
* const start = Date.now()
|
|
889
|
+
* const result = yield* effect
|
|
890
|
+
* yield* Effect.logInfo(`Resolved in ${Date.now() - start}ms`)
|
|
891
|
+
* return result
|
|
892
|
+
* })
|
|
893
|
+
* })
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
middleware(config) {
|
|
897
|
+
const newMiddlewares = [...this.state.middlewares, config];
|
|
898
|
+
return this.with({ ...this.state, middlewares: newMiddlewares });
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Register an extension
|
|
902
|
+
*
|
|
903
|
+
* Extensions provide lifecycle hooks that run at each phase of request processing
|
|
904
|
+
* (parse, validate, execute) and can contribute data to the response's extensions field.
|
|
905
|
+
*
|
|
906
|
+
* @param config.name - Extension name (for debugging/logging)
|
|
907
|
+
* @param config.description - Optional description
|
|
908
|
+
* @param config.onParse - Called after query parsing
|
|
909
|
+
* @param config.onValidate - Called after validation
|
|
910
|
+
* @param config.onExecuteStart - Called before execution begins
|
|
911
|
+
* @param config.onExecuteEnd - Called after execution completes
|
|
912
|
+
*
|
|
913
|
+
* @example
|
|
914
|
+
* ```typescript
|
|
915
|
+
* builder.extension({
|
|
916
|
+
* name: "tracing",
|
|
917
|
+
* onExecuteStart: () => Effect.gen(function*() {
|
|
918
|
+
* const ext = yield* ExtensionsService
|
|
919
|
+
* yield* ext.set("tracing", { startTime: Date.now() })
|
|
920
|
+
* }),
|
|
921
|
+
* onExecuteEnd: () => Effect.gen(function*() {
|
|
922
|
+
* const ext = yield* ExtensionsService
|
|
923
|
+
* yield* ext.merge("tracing", { endTime: Date.now() })
|
|
924
|
+
* }),
|
|
925
|
+
* })
|
|
926
|
+
* ```
|
|
927
|
+
*/
|
|
928
|
+
extension(config) {
|
|
929
|
+
const newExtensions = [...this.state.extensions, config];
|
|
930
|
+
return this.with({ ...this.state, extensions: newExtensions });
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Get the registered extensions for use by the execution layer
|
|
934
|
+
*/
|
|
935
|
+
getExtensions() {
|
|
936
|
+
return this.state.extensions;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Add a computed/relational field to an object type
|
|
940
|
+
*/
|
|
941
|
+
field(typeName, fieldName, config) {
|
|
942
|
+
const newObjectFields = new Map(this.state.objectFields);
|
|
943
|
+
const typeFields = newObjectFields.get(typeName) || /* @__PURE__ */ new Map();
|
|
944
|
+
typeFields.set(fieldName, config);
|
|
945
|
+
newObjectFields.set(typeName, typeFields);
|
|
946
|
+
return this.with(updateState(this.state, "objectFields", newObjectFields));
|
|
947
|
+
}
|
|
948
|
+
// ============================================================================
|
|
949
|
+
// Schema Building
|
|
950
|
+
// ============================================================================
|
|
951
|
+
/**
|
|
952
|
+
* Get the field complexity map for use in complexity validation.
|
|
953
|
+
* Maps "TypeName.fieldName" to the complexity value or function.
|
|
954
|
+
*/
|
|
955
|
+
getFieldComplexities() {
|
|
956
|
+
const complexities = /* @__PURE__ */ new Map();
|
|
957
|
+
for (const [name, config] of this.state.queries) {
|
|
958
|
+
if (config.complexity !== void 0) {
|
|
959
|
+
complexities.set(`Query.${name}`, config.complexity);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
for (const [name, config] of this.state.mutations) {
|
|
963
|
+
if (config.complexity !== void 0) {
|
|
964
|
+
complexities.set(`Mutation.${name}`, config.complexity);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
for (const [name, config] of this.state.subscriptions) {
|
|
968
|
+
if (config.complexity !== void 0) {
|
|
969
|
+
complexities.set(`Subscription.${name}`, config.complexity);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
for (const [typeName, fields] of this.state.objectFields) {
|
|
973
|
+
for (const [fieldName, config] of fields) {
|
|
974
|
+
if (config.complexity !== void 0) {
|
|
975
|
+
complexities.set(`${typeName}.${fieldName}`, config.complexity);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return complexities;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Get the cache hint map for use in cache control calculation.
|
|
983
|
+
* Maps "TypeName.fieldName" to the cache hint for field-level hints,
|
|
984
|
+
* or "TypeName" to the cache hint for type-level hints.
|
|
985
|
+
*/
|
|
986
|
+
getCacheHints() {
|
|
987
|
+
const hints = /* @__PURE__ */ new Map();
|
|
988
|
+
for (const [typeName, typeReg] of this.state.types) {
|
|
989
|
+
if (typeReg.cacheControl !== void 0) {
|
|
990
|
+
hints.set(typeName, typeReg.cacheControl);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
for (const [name, config] of this.state.queries) {
|
|
994
|
+
if (config.cacheControl !== void 0) {
|
|
995
|
+
hints.set(`Query.${name}`, config.cacheControl);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
for (const [name, config] of this.state.subscriptions) {
|
|
999
|
+
if (config.cacheControl !== void 0) {
|
|
1000
|
+
hints.set(`Subscription.${name}`, config.cacheControl);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
for (const [typeName, fields] of this.state.objectFields) {
|
|
1004
|
+
for (const [fieldName, config] of fields) {
|
|
1005
|
+
if (config.cacheControl !== void 0) {
|
|
1006
|
+
hints.set(`${typeName}.${fieldName}`, config.cacheControl);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return hints;
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Build the GraphQL schema (no services required)
|
|
1014
|
+
*/
|
|
1015
|
+
buildSchema() {
|
|
1016
|
+
const directiveRegistry = this.buildDirectiveRegistry();
|
|
1017
|
+
const enumRegistry = this.buildEnumRegistry();
|
|
1018
|
+
const inputRegistry = this.buildInputRegistry(enumRegistry);
|
|
1019
|
+
const interfaceRegistry = this.buildInterfaceRegistry(enumRegistry);
|
|
1020
|
+
const { typeRegistry, unionRegistry } = this.buildTypeAndUnionRegistries(
|
|
1021
|
+
enumRegistry,
|
|
1022
|
+
interfaceRegistry
|
|
1023
|
+
);
|
|
1024
|
+
const fieldCtx = this.createFieldBuilderContext(
|
|
1025
|
+
typeRegistry,
|
|
1026
|
+
interfaceRegistry,
|
|
1027
|
+
enumRegistry,
|
|
1028
|
+
unionRegistry,
|
|
1029
|
+
inputRegistry
|
|
1030
|
+
);
|
|
1031
|
+
const queryFields = this.buildQueryFields(fieldCtx);
|
|
1032
|
+
const mutationFields = this.buildMutationFields(fieldCtx);
|
|
1033
|
+
const subscriptionFields = this.buildSubscriptionFields(fieldCtx);
|
|
1034
|
+
return this.assembleSchema({
|
|
1035
|
+
directiveRegistry,
|
|
1036
|
+
enumRegistry,
|
|
1037
|
+
inputRegistry,
|
|
1038
|
+
interfaceRegistry,
|
|
1039
|
+
typeRegistry,
|
|
1040
|
+
unionRegistry,
|
|
1041
|
+
queryFields,
|
|
1042
|
+
mutationFields,
|
|
1043
|
+
subscriptionFields
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
buildDirectiveRegistry() {
|
|
1047
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1048
|
+
const cache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
|
|
1049
|
+
for (const [name, reg] of this.state.directives) {
|
|
1050
|
+
const graphqlDirective = new GraphQLDirective({
|
|
1051
|
+
name,
|
|
1052
|
+
description: reg.description,
|
|
1053
|
+
locations: [...reg.locations],
|
|
1054
|
+
args: reg.args ? toGraphQLArgsWithRegistry(
|
|
1055
|
+
reg.args,
|
|
1056
|
+
/* @__PURE__ */ new Map(),
|
|
1057
|
+
/* @__PURE__ */ new Map(),
|
|
1058
|
+
this.state.inputs,
|
|
1059
|
+
this.state.enums,
|
|
1060
|
+
cache
|
|
1061
|
+
) : void 0
|
|
1062
|
+
});
|
|
1063
|
+
registry.set(name, graphqlDirective);
|
|
1064
|
+
}
|
|
1065
|
+
return registry;
|
|
1066
|
+
}
|
|
1067
|
+
buildEnumRegistry() {
|
|
1068
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1069
|
+
for (const [name, reg] of this.state.enums) {
|
|
1070
|
+
const enumValues = {};
|
|
1071
|
+
for (const value of reg.values) {
|
|
1072
|
+
enumValues[value] = { value };
|
|
1073
|
+
}
|
|
1074
|
+
registry.set(
|
|
1075
|
+
name,
|
|
1076
|
+
new GraphQLEnumType({
|
|
1077
|
+
name,
|
|
1078
|
+
values: enumValues,
|
|
1079
|
+
description: reg.description,
|
|
1080
|
+
extensions: reg.directives ? { directives: reg.directives } : void 0
|
|
1081
|
+
})
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
return registry;
|
|
1085
|
+
}
|
|
1086
|
+
buildInputRegistry(enumRegistry) {
|
|
1087
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1088
|
+
const cache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
|
|
1089
|
+
for (const [name, reg] of this.state.inputs) {
|
|
1090
|
+
const inputType2 = new GraphQLInputObjectType({
|
|
1091
|
+
name,
|
|
1092
|
+
description: reg.description,
|
|
1093
|
+
fields: () => schemaToInputFields(
|
|
1094
|
+
reg.schema,
|
|
1095
|
+
enumRegistry,
|
|
1096
|
+
registry,
|
|
1097
|
+
this.state.inputs,
|
|
1098
|
+
this.state.enums,
|
|
1099
|
+
cache
|
|
1100
|
+
),
|
|
1101
|
+
extensions: reg.directives ? { directives: reg.directives } : void 0
|
|
1102
|
+
});
|
|
1103
|
+
registry.set(name, inputType2);
|
|
1104
|
+
}
|
|
1105
|
+
return registry;
|
|
1106
|
+
}
|
|
1107
|
+
buildInterfaceRegistry(enumRegistry) {
|
|
1108
|
+
const registry = /* @__PURE__ */ new Map();
|
|
1109
|
+
const typeRegistry = /* @__PURE__ */ new Map();
|
|
1110
|
+
const unionRegistry = /* @__PURE__ */ new Map();
|
|
1111
|
+
const sharedCtx = {
|
|
1112
|
+
types: this.state.types,
|
|
1113
|
+
interfaces: this.state.interfaces,
|
|
1114
|
+
enums: this.state.enums,
|
|
1115
|
+
unions: this.state.unions,
|
|
1116
|
+
inputs: this.state.inputs,
|
|
1117
|
+
typeRegistry,
|
|
1118
|
+
interfaceRegistry: registry,
|
|
1119
|
+
enumRegistry,
|
|
1120
|
+
unionRegistry};
|
|
1121
|
+
buildReverseLookups(sharedCtx);
|
|
1122
|
+
for (const [name, reg] of this.state.interfaces) {
|
|
1123
|
+
const interfaceType2 = new GraphQLInterfaceType({
|
|
1124
|
+
name,
|
|
1125
|
+
fields: () => schemaToFields(reg.schema, sharedCtx),
|
|
1126
|
+
resolveType: reg.resolveType,
|
|
1127
|
+
extensions: reg.directives ? { directives: reg.directives } : void 0
|
|
1128
|
+
});
|
|
1129
|
+
registry.set(name, interfaceType2);
|
|
1130
|
+
}
|
|
1131
|
+
return registry;
|
|
1132
|
+
}
|
|
1133
|
+
buildTypeAndUnionRegistries(enumRegistry, interfaceRegistry) {
|
|
1134
|
+
const typeRegistry = /* @__PURE__ */ new Map();
|
|
1135
|
+
const unionRegistry = /* @__PURE__ */ new Map();
|
|
1136
|
+
const sharedCtx = {
|
|
1137
|
+
types: this.state.types,
|
|
1138
|
+
interfaces: this.state.interfaces,
|
|
1139
|
+
enums: this.state.enums,
|
|
1140
|
+
unions: this.state.unions,
|
|
1141
|
+
inputs: this.state.inputs,
|
|
1142
|
+
typeRegistry,
|
|
1143
|
+
interfaceRegistry,
|
|
1144
|
+
enumRegistry,
|
|
1145
|
+
unionRegistry};
|
|
1146
|
+
buildReverseLookups(sharedCtx);
|
|
1147
|
+
const sharedFieldCtx = this.createFieldBuilderContext(
|
|
1148
|
+
typeRegistry,
|
|
1149
|
+
interfaceRegistry,
|
|
1150
|
+
enumRegistry,
|
|
1151
|
+
unionRegistry,
|
|
1152
|
+
/* @__PURE__ */ new Map()
|
|
1153
|
+
);
|
|
1154
|
+
for (const [typeName, typeReg] of this.state.types) {
|
|
1155
|
+
const implementedInterfaces = typeReg.implements?.map((name) => interfaceRegistry.get(name)).filter(Boolean) ?? [];
|
|
1156
|
+
const graphqlType = new GraphQLObjectType({
|
|
1157
|
+
name: typeName,
|
|
1158
|
+
fields: () => {
|
|
1159
|
+
const baseFields = schemaToFields(typeReg.schema, sharedCtx);
|
|
1160
|
+
const additionalFields = this.state.objectFields.get(typeName);
|
|
1161
|
+
if (additionalFields) {
|
|
1162
|
+
for (const [fieldName, fieldConfig] of additionalFields) {
|
|
1163
|
+
baseFields[fieldName] = buildObjectField(fieldConfig, sharedFieldCtx);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return baseFields;
|
|
1167
|
+
},
|
|
1168
|
+
interfaces: implementedInterfaces.length > 0 ? implementedInterfaces : void 0,
|
|
1169
|
+
extensions: typeReg.directives ? { directives: typeReg.directives } : void 0
|
|
1170
|
+
});
|
|
1171
|
+
typeRegistry.set(typeName, graphqlType);
|
|
1172
|
+
}
|
|
1173
|
+
for (const [name, reg] of this.state.unions) {
|
|
1174
|
+
const unionType2 = new GraphQLUnionType({
|
|
1175
|
+
name,
|
|
1176
|
+
types: () => reg.types.map((typeName) => typeRegistry.get(typeName)).filter(Boolean),
|
|
1177
|
+
resolveType: reg.resolveType,
|
|
1178
|
+
extensions: reg.directives ? { directives: reg.directives } : void 0
|
|
1179
|
+
});
|
|
1180
|
+
unionRegistry.set(name, unionType2);
|
|
1181
|
+
}
|
|
1182
|
+
return { typeRegistry, unionRegistry };
|
|
1183
|
+
}
|
|
1184
|
+
createFieldBuilderContext(typeRegistry, interfaceRegistry, enumRegistry, unionRegistry, inputRegistry) {
|
|
1185
|
+
const inputTypeLookupCache = buildInputTypeLookupCache(this.state.inputs, this.state.enums);
|
|
1186
|
+
return {
|
|
1187
|
+
types: this.state.types,
|
|
1188
|
+
interfaces: this.state.interfaces,
|
|
1189
|
+
enums: this.state.enums,
|
|
1190
|
+
unions: this.state.unions,
|
|
1191
|
+
inputs: this.state.inputs,
|
|
1192
|
+
typeRegistry,
|
|
1193
|
+
interfaceRegistry,
|
|
1194
|
+
enumRegistry,
|
|
1195
|
+
unionRegistry,
|
|
1196
|
+
inputRegistry,
|
|
1197
|
+
directiveRegistrations: this.state.directives,
|
|
1198
|
+
middlewares: this.state.middlewares,
|
|
1199
|
+
inputTypeLookupCache
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
buildQueryFields(ctx) {
|
|
1203
|
+
const fields = {};
|
|
1204
|
+
for (const [name, config] of this.state.queries) {
|
|
1205
|
+
fields[name] = buildField(config, ctx);
|
|
1206
|
+
}
|
|
1207
|
+
return fields;
|
|
1208
|
+
}
|
|
1209
|
+
buildMutationFields(ctx) {
|
|
1210
|
+
const fields = {};
|
|
1211
|
+
for (const [name, config] of this.state.mutations) {
|
|
1212
|
+
fields[name] = buildField(config, ctx);
|
|
1213
|
+
}
|
|
1214
|
+
return fields;
|
|
1215
|
+
}
|
|
1216
|
+
buildSubscriptionFields(ctx) {
|
|
1217
|
+
const fields = {};
|
|
1218
|
+
for (const [name, config] of this.state.subscriptions) {
|
|
1219
|
+
fields[name] = buildSubscriptionField(config, ctx);
|
|
1220
|
+
}
|
|
1221
|
+
return fields;
|
|
1222
|
+
}
|
|
1223
|
+
assembleSchema(registries) {
|
|
1224
|
+
const schemaConfig = {
|
|
1225
|
+
types: [
|
|
1226
|
+
...Array.from(registries.enumRegistry.values()),
|
|
1227
|
+
...Array.from(registries.inputRegistry.values()),
|
|
1228
|
+
...Array.from(registries.interfaceRegistry.values()),
|
|
1229
|
+
...Array.from(registries.typeRegistry.values()),
|
|
1230
|
+
...Array.from(registries.unionRegistry.values())
|
|
1231
|
+
],
|
|
1232
|
+
directives: registries.directiveRegistry.size > 0 ? [...Array.from(registries.directiveRegistry.values())] : void 0
|
|
1233
|
+
};
|
|
1234
|
+
if (Object.keys(registries.queryFields).length > 0) {
|
|
1235
|
+
schemaConfig.query = new GraphQLObjectType({
|
|
1236
|
+
name: "Query",
|
|
1237
|
+
fields: registries.queryFields
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
if (Object.keys(registries.mutationFields).length > 0) {
|
|
1241
|
+
schemaConfig.mutation = new GraphQLObjectType({
|
|
1242
|
+
name: "Mutation",
|
|
1243
|
+
fields: registries.mutationFields
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
if (Object.keys(registries.subscriptionFields).length > 0) {
|
|
1247
|
+
schemaConfig.subscription = new GraphQLObjectType({
|
|
1248
|
+
name: "Subscription",
|
|
1249
|
+
fields: registries.subscriptionFields
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
return new GraphQLSchema(schemaConfig);
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
|
|
1256
|
+
// src/builder/pipe-api.ts
|
|
1257
|
+
var objectType = (config) => (builder) => builder.objectType(config);
|
|
1258
|
+
var interfaceType = (config) => (builder) => builder.interfaceType(config);
|
|
1259
|
+
var enumType = (config) => (builder) => builder.enumType(config);
|
|
1260
|
+
var unionType = (config) => (builder) => builder.unionType(config);
|
|
1261
|
+
var inputType = (config) => (builder) => builder.inputType(config);
|
|
1262
|
+
var directive = (config) => (builder) => builder.directive(config);
|
|
1263
|
+
var middleware = (config) => (builder) => builder.middleware(config);
|
|
1264
|
+
var extension = (config) => (builder) => builder.extension(config);
|
|
1265
|
+
var query = (name, config) => (builder) => builder.query(name, config);
|
|
1266
|
+
var mutation = (name, config) => (builder) => builder.mutation(name, config);
|
|
1267
|
+
var subscription = (name, config) => (builder) => builder.subscription(name, config);
|
|
1268
|
+
var field = (typeName, fieldName, config) => (builder) => builder.field(typeName, fieldName, config);
|
|
1269
|
+
var compose = (...operations) => (builder) => operations.reduce((b, op) => op(b), builder);
|
|
1270
|
+
var ExtensionsService = Context.GenericTag(
|
|
1271
|
+
"@effect-gql/ExtensionsService"
|
|
1272
|
+
);
|
|
1273
|
+
function deepMerge(target, source) {
|
|
1274
|
+
const result = { ...target };
|
|
1275
|
+
for (const key of Object.keys(source)) {
|
|
1276
|
+
const sourceValue = source[key];
|
|
1277
|
+
const targetValue = result[key];
|
|
1278
|
+
if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
|
|
1279
|
+
result[key] = deepMerge(
|
|
1280
|
+
targetValue,
|
|
1281
|
+
sourceValue
|
|
1282
|
+
);
|
|
1283
|
+
} else {
|
|
1284
|
+
result[key] = sourceValue;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return result;
|
|
1288
|
+
}
|
|
1289
|
+
var makeExtensionsService = () => Effect.gen(function* () {
|
|
1290
|
+
const ref = yield* Ref.make({});
|
|
1291
|
+
return ExtensionsService.of({
|
|
1292
|
+
set: (key, value) => Ref.update(ref, (current) => ({ ...current, [key]: value })),
|
|
1293
|
+
merge: (key, value) => Ref.update(ref, (current) => {
|
|
1294
|
+
const existing = current[key];
|
|
1295
|
+
if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
|
|
1296
|
+
return {
|
|
1297
|
+
...current,
|
|
1298
|
+
[key]: deepMerge(existing, value)
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
return { ...current, [key]: value };
|
|
1302
|
+
}),
|
|
1303
|
+
get: () => Ref.get(ref)
|
|
1304
|
+
});
|
|
1305
|
+
});
|
|
1306
|
+
var runExtensionHooks = (extensions, hookName, getHookEffect) => Effect.forEach(
|
|
1307
|
+
extensions.filter((ext) => ext[hookName] !== void 0),
|
|
1308
|
+
(ext) => getHookEffect(ext).pipe(
|
|
1309
|
+
Effect.catchAllCause(
|
|
1310
|
+
(cause) => Effect.logWarning(`Extension "${ext.name}" ${String(hookName)} hook failed`, cause)
|
|
1311
|
+
)
|
|
1312
|
+
),
|
|
1313
|
+
{ discard: true }
|
|
1314
|
+
);
|
|
1315
|
+
var runParseHooks = (extensions, source, document) => runExtensionHooks(extensions, "onParse", (ext) => ext.onParse(source, document));
|
|
1316
|
+
var runValidateHooks = (extensions, document, errors) => runExtensionHooks(extensions, "onValidate", (ext) => ext.onValidate(document, errors));
|
|
1317
|
+
var runExecuteStartHooks = (extensions, args) => runExtensionHooks(extensions, "onExecuteStart", (ext) => ext.onExecuteStart(args));
|
|
1318
|
+
var runExecuteEndHooks = (extensions, result) => runExtensionHooks(extensions, "onExecuteEnd", (ext) => ext.onExecuteEnd(result));
|
|
1319
|
+
|
|
1320
|
+
// src/builder/execute.ts
|
|
1321
|
+
var execute = (schema, layer, extensions = [], fieldComplexities = /* @__PURE__ */ new Map()) => (source, variableValues, operationName) => Effect.gen(function* () {
|
|
1322
|
+
const extensionsService = yield* makeExtensionsService();
|
|
1323
|
+
const runtime = yield* Effect.runtime();
|
|
1324
|
+
let document;
|
|
1325
|
+
try {
|
|
1326
|
+
document = parse(source);
|
|
1327
|
+
} catch (parseError) {
|
|
1328
|
+
const extensionData2 = yield* extensionsService.get();
|
|
1329
|
+
return {
|
|
1330
|
+
errors: [
|
|
1331
|
+
parseError instanceof GraphQLError ? parseError : new GraphQLError(String(parseError))
|
|
1332
|
+
],
|
|
1333
|
+
extensions: Object.keys(extensionData2).length > 0 ? extensionData2 : void 0
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
yield* runParseHooks(extensions, source, document).pipe(
|
|
1337
|
+
Effect.provideService(ExtensionsService, extensionsService)
|
|
1338
|
+
);
|
|
1339
|
+
const validationErrors = validate(schema, document);
|
|
1340
|
+
yield* runValidateHooks(extensions, document, validationErrors).pipe(
|
|
1341
|
+
Effect.provideService(ExtensionsService, extensionsService)
|
|
1342
|
+
);
|
|
1343
|
+
if (validationErrors.length > 0) {
|
|
1344
|
+
const extensionData2 = yield* extensionsService.get();
|
|
1345
|
+
return {
|
|
1346
|
+
errors: validationErrors,
|
|
1347
|
+
extensions: Object.keys(extensionData2).length > 0 ? extensionData2 : void 0
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
const executionArgs = {
|
|
1351
|
+
source,
|
|
1352
|
+
document,
|
|
1353
|
+
variableValues,
|
|
1354
|
+
operationName,
|
|
1355
|
+
schema,
|
|
1356
|
+
fieldComplexities
|
|
1357
|
+
};
|
|
1358
|
+
yield* runExecuteStartHooks(extensions, executionArgs).pipe(
|
|
1359
|
+
Effect.provideService(ExtensionsService, extensionsService)
|
|
1360
|
+
);
|
|
1361
|
+
const executeResult = yield* Effect.try({
|
|
1362
|
+
try: () => execute$1({
|
|
1363
|
+
schema,
|
|
1364
|
+
document,
|
|
1365
|
+
variableValues,
|
|
1366
|
+
operationName,
|
|
1367
|
+
contextValue: { runtime }
|
|
1368
|
+
}),
|
|
1369
|
+
catch: (error) => new Error(String(error))
|
|
1370
|
+
});
|
|
1371
|
+
const resolvedResult = executeResult && typeof executeResult === "object" && "then" in executeResult ? yield* Effect.promise(() => executeResult) : executeResult;
|
|
1372
|
+
yield* runExecuteEndHooks(extensions, resolvedResult).pipe(
|
|
1373
|
+
Effect.provideService(ExtensionsService, extensionsService)
|
|
1374
|
+
);
|
|
1375
|
+
const extensionData = yield* extensionsService.get();
|
|
1376
|
+
if (Object.keys(extensionData).length > 0) {
|
|
1377
|
+
return {
|
|
1378
|
+
...resolvedResult,
|
|
1379
|
+
extensions: {
|
|
1380
|
+
...resolvedResult.extensions,
|
|
1381
|
+
...extensionData
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
return resolvedResult;
|
|
1386
|
+
}).pipe(Effect.provide(layer));
|
|
1387
|
+
|
|
1388
|
+
export { GraphQLSchemaBuilder, compose, directive, enumType, execute, extension, field, getSchemaName, inputType, interfaceType, middleware, mutation, objectType, query, subscription, unionType };
|
|
1389
|
+
//# sourceMappingURL=index.js.map
|
|
1390
|
+
//# sourceMappingURL=index.js.map
|