@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.
- package/README.md +100 -0
- package/builder/index.cjs +1446 -0
- package/builder/index.cjs.map +1 -0
- package/builder/index.d.cts +260 -0
- package/{dist/builder/pipe-api.d.ts → builder/index.d.ts} +50 -21
- package/builder/index.js +1405 -0
- package/builder/index.js.map +1 -0
- package/index.cjs +3469 -0
- package/index.cjs.map +1 -0
- package/index.d.cts +529 -0
- package/index.d.ts +529 -0
- package/index.js +3292 -0
- package/index.js.map +1 -0
- package/package.json +19 -28
- package/schema-builder-DKvkzU_M.d.cts +965 -0
- package/schema-builder-DKvkzU_M.d.ts +965 -0
- package/server/index.cjs +1579 -0
- package/server/index.cjs.map +1 -0
- package/server/index.d.cts +682 -0
- package/server/index.d.ts +682 -0
- package/server/index.js +1548 -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
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { Kind, type OperationDefinitionNode } from "graphql"
|
|
3
|
-
import type { GraphQLExtension, ExecutionArgs } from "./extensions"
|
|
4
|
-
import { ExtensionsService } from "./extensions"
|
|
5
|
-
import {
|
|
6
|
-
defaultComplexityCalculator,
|
|
7
|
-
type ComplexityResult,
|
|
8
|
-
type FieldComplexityMap,
|
|
9
|
-
} from "./server/complexity"
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Configuration for the analyzer extension
|
|
13
|
-
*/
|
|
14
|
-
export interface AnalyzerExtensionConfig {
|
|
15
|
-
/**
|
|
16
|
-
* Include the total complexity score in the response.
|
|
17
|
-
* @default true
|
|
18
|
-
*/
|
|
19
|
-
readonly includeComplexity?: boolean
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Include the maximum query depth in the response.
|
|
23
|
-
* @default true
|
|
24
|
-
*/
|
|
25
|
-
readonly includeDepth?: boolean
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Include the total field count in the response.
|
|
29
|
-
* @default false
|
|
30
|
-
*/
|
|
31
|
-
readonly includeFieldCount?: boolean
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Include the alias count in the response.
|
|
35
|
-
* @default false
|
|
36
|
-
*/
|
|
37
|
-
readonly includeAliasCount?: boolean
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The key to use in the response extensions object.
|
|
41
|
-
* @default "analyzer"
|
|
42
|
-
*/
|
|
43
|
-
readonly key?: string
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Thresholds for logging warnings when exceeded.
|
|
47
|
-
* When a metric exceeds its threshold, a warning is logged.
|
|
48
|
-
*/
|
|
49
|
-
readonly thresholds?: {
|
|
50
|
-
readonly depth?: number
|
|
51
|
-
readonly complexity?: number
|
|
52
|
-
readonly fieldCount?: number
|
|
53
|
-
readonly aliasCount?: number
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Default complexity cost for fields without explicit costs.
|
|
58
|
-
* @default 1
|
|
59
|
-
*/
|
|
60
|
-
readonly defaultFieldComplexity?: number
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Optional field complexity overrides.
|
|
64
|
-
* If not provided, uses the field complexities from the schema builder
|
|
65
|
-
* (passed via ExecutionArgs).
|
|
66
|
-
*/
|
|
67
|
-
readonly fieldComplexities?: FieldComplexityMap
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Output format for analyzer extension
|
|
72
|
-
*/
|
|
73
|
-
export interface AnalyzerOutput {
|
|
74
|
-
complexity?: number
|
|
75
|
-
depth?: number
|
|
76
|
-
fieldCount?: number
|
|
77
|
-
aliasCount?: number
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Create an analyzer extension that reports query complexity metrics
|
|
82
|
-
* in the response extensions field.
|
|
83
|
-
*
|
|
84
|
-
* Similar to async-graphql's Analyzer extension, this allows you to
|
|
85
|
-
* monitor the complexity of incoming queries without blocking execution.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* // Basic usage - reports complexity and depth
|
|
90
|
-
* const analyzer = createAnalyzerExtension()
|
|
91
|
-
*
|
|
92
|
-
* // With all metrics and warnings
|
|
93
|
-
* const analyzer = createAnalyzerExtension({
|
|
94
|
-
* includeFieldCount: true,
|
|
95
|
-
* includeAliasCount: true,
|
|
96
|
-
* thresholds: {
|
|
97
|
-
* depth: 10,
|
|
98
|
-
* complexity: 100,
|
|
99
|
-
* },
|
|
100
|
-
* })
|
|
101
|
-
*
|
|
102
|
-
* // Add to schema builder
|
|
103
|
-
* const builder = GraphQLSchemaBuilder.empty.pipe(
|
|
104
|
-
* extension(analyzer),
|
|
105
|
-
* // ...queries, mutations, etc.
|
|
106
|
-
* )
|
|
107
|
-
*
|
|
108
|
-
* // Response will include:
|
|
109
|
-
* // {
|
|
110
|
-
* // "data": { ... },
|
|
111
|
-
* // "extensions": {
|
|
112
|
-
* // "analyzer": {
|
|
113
|
-
* // "complexity": 42,
|
|
114
|
-
* // "depth": 3
|
|
115
|
-
* // }
|
|
116
|
-
* // }
|
|
117
|
-
* // }
|
|
118
|
-
* ```
|
|
119
|
-
*/
|
|
120
|
-
export const createAnalyzerExtension = (
|
|
121
|
-
config: AnalyzerExtensionConfig = {}
|
|
122
|
-
): GraphQLExtension<ExtensionsService> => {
|
|
123
|
-
const {
|
|
124
|
-
includeComplexity = true,
|
|
125
|
-
includeDepth = true,
|
|
126
|
-
includeFieldCount = false,
|
|
127
|
-
includeAliasCount = false,
|
|
128
|
-
key = "analyzer",
|
|
129
|
-
thresholds,
|
|
130
|
-
defaultFieldComplexity = 1,
|
|
131
|
-
fieldComplexities: configFieldComplexities,
|
|
132
|
-
} = config
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
name: "analyzer",
|
|
136
|
-
description: "Reports query complexity metrics in response extensions",
|
|
137
|
-
|
|
138
|
-
onExecuteStart: (args: ExecutionArgs) =>
|
|
139
|
-
Effect.gen(function* () {
|
|
140
|
-
const ext = yield* ExtensionsService
|
|
141
|
-
|
|
142
|
-
// Find the operation
|
|
143
|
-
const operation = findOperation(args)
|
|
144
|
-
if (!operation) {
|
|
145
|
-
return
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Use config field complexities if provided, otherwise use from args
|
|
149
|
-
const fieldComplexities = configFieldComplexities ?? args.fieldComplexities
|
|
150
|
-
|
|
151
|
-
// Calculate complexity
|
|
152
|
-
const calculator = defaultComplexityCalculator(defaultFieldComplexity)
|
|
153
|
-
const result = yield* calculator({
|
|
154
|
-
document: args.document,
|
|
155
|
-
operation,
|
|
156
|
-
variables: args.variableValues,
|
|
157
|
-
schema: args.schema,
|
|
158
|
-
fieldComplexities,
|
|
159
|
-
}).pipe(
|
|
160
|
-
Effect.catchAll((error) =>
|
|
161
|
-
Effect.logWarning("Analyzer extension: complexity calculation failed", error).pipe(
|
|
162
|
-
Effect.as(null)
|
|
163
|
-
)
|
|
164
|
-
)
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
if (!result) {
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Check thresholds and log warnings
|
|
172
|
-
yield* checkThresholds(result, thresholds)
|
|
173
|
-
|
|
174
|
-
// Build output
|
|
175
|
-
const output: AnalyzerOutput = {}
|
|
176
|
-
if (includeComplexity) {
|
|
177
|
-
output.complexity = result.complexity
|
|
178
|
-
}
|
|
179
|
-
if (includeDepth) {
|
|
180
|
-
output.depth = result.depth
|
|
181
|
-
}
|
|
182
|
-
if (includeFieldCount) {
|
|
183
|
-
output.fieldCount = result.fieldCount
|
|
184
|
-
}
|
|
185
|
-
if (includeAliasCount) {
|
|
186
|
-
output.aliasCount = result.aliasCount
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Add to extensions
|
|
190
|
-
yield* ext.set(key, output)
|
|
191
|
-
}),
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Find the operation to analyze from the document
|
|
197
|
-
*/
|
|
198
|
-
function findOperation(args: ExecutionArgs): OperationDefinitionNode | null {
|
|
199
|
-
const operations = args.document.definitions.filter(
|
|
200
|
-
(d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
if (operations.length === 0) {
|
|
204
|
-
return null
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (args.operationName) {
|
|
208
|
-
return operations.find((o) => o.name?.value === args.operationName) ?? null
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return operations[0]
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Check thresholds and log warnings for exceeded values
|
|
216
|
-
*/
|
|
217
|
-
function checkThresholds(
|
|
218
|
-
result: ComplexityResult,
|
|
219
|
-
thresholds?: AnalyzerExtensionConfig["thresholds"]
|
|
220
|
-
): Effect.Effect<void> {
|
|
221
|
-
if (!thresholds) {
|
|
222
|
-
return Effect.void
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const warnings: string[] = []
|
|
226
|
-
|
|
227
|
-
if (thresholds.depth !== undefined && result.depth > thresholds.depth) {
|
|
228
|
-
warnings.push(`Query depth ${result.depth} exceeds threshold ${thresholds.depth}`)
|
|
229
|
-
}
|
|
230
|
-
if (thresholds.complexity !== undefined && result.complexity > thresholds.complexity) {
|
|
231
|
-
warnings.push(
|
|
232
|
-
`Query complexity ${result.complexity} exceeds threshold ${thresholds.complexity}`
|
|
233
|
-
)
|
|
234
|
-
}
|
|
235
|
-
if (thresholds.fieldCount !== undefined && result.fieldCount > thresholds.fieldCount) {
|
|
236
|
-
warnings.push(
|
|
237
|
-
`Query field count ${result.fieldCount} exceeds threshold ${thresholds.fieldCount}`
|
|
238
|
-
)
|
|
239
|
-
}
|
|
240
|
-
if (thresholds.aliasCount !== undefined && result.aliasCount > thresholds.aliasCount) {
|
|
241
|
-
warnings.push(
|
|
242
|
-
`Query alias count ${result.aliasCount} exceeds threshold ${thresholds.aliasCount}`
|
|
243
|
-
)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (warnings.length > 0) {
|
|
247
|
-
return Effect.logWarning("Analyzer extension: thresholds exceeded", {
|
|
248
|
-
warnings,
|
|
249
|
-
result,
|
|
250
|
-
})
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return Effect.void
|
|
254
|
-
}
|
package/src/builder/execute.ts
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { Effect, Layer } from "effect"
|
|
2
|
-
import {
|
|
3
|
-
GraphQLSchema,
|
|
4
|
-
GraphQLError,
|
|
5
|
-
parse,
|
|
6
|
-
validate,
|
|
7
|
-
execute as graphqlExecute,
|
|
8
|
-
type ExecutionResult,
|
|
9
|
-
type DocumentNode,
|
|
10
|
-
} from "graphql"
|
|
11
|
-
import type { GraphQLEffectContext } from "./types"
|
|
12
|
-
import {
|
|
13
|
-
type GraphQLExtension,
|
|
14
|
-
ExtensionsService,
|
|
15
|
-
makeExtensionsService,
|
|
16
|
-
runParseHooks,
|
|
17
|
-
runValidateHooks,
|
|
18
|
-
runExecuteStartHooks,
|
|
19
|
-
runExecuteEndHooks,
|
|
20
|
-
} from "../extensions"
|
|
21
|
-
import type { FieldComplexityMap } from "../server/complexity"
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Execute a GraphQL query with a service layer
|
|
25
|
-
*
|
|
26
|
-
* This is the layer-per-request execution model. Build the schema once,
|
|
27
|
-
* then execute each request with its own layer (including request-scoped services).
|
|
28
|
-
*
|
|
29
|
-
* The execution follows these phases:
|
|
30
|
-
* 1. Parse - Convert source string to DocumentNode
|
|
31
|
-
* 2. Validate - Check document against schema
|
|
32
|
-
* 3. Execute - Run resolvers and return result
|
|
33
|
-
*
|
|
34
|
-
* Extensions can hook into each phase via onParse, onValidate, onExecuteStart, onExecuteEnd.
|
|
35
|
-
* Extension data is automatically merged into the response's extensions field.
|
|
36
|
-
*/
|
|
37
|
-
export const execute =
|
|
38
|
-
<R>(
|
|
39
|
-
schema: GraphQLSchema,
|
|
40
|
-
layer: Layer.Layer<R>,
|
|
41
|
-
extensions: readonly GraphQLExtension<any>[] = [],
|
|
42
|
-
fieldComplexities: FieldComplexityMap = new Map()
|
|
43
|
-
) =>
|
|
44
|
-
(
|
|
45
|
-
source: string,
|
|
46
|
-
variableValues?: Record<string, unknown>,
|
|
47
|
-
operationName?: string
|
|
48
|
-
): Effect.Effect<ExecutionResult, Error> =>
|
|
49
|
-
Effect.gen(function* () {
|
|
50
|
-
// Create the ExtensionsService for this request
|
|
51
|
-
const extensionsService = yield* makeExtensionsService()
|
|
52
|
-
|
|
53
|
-
// Create runtime from the provided layer
|
|
54
|
-
const runtime = yield* Effect.runtime<R>()
|
|
55
|
-
|
|
56
|
-
// Phase 1: Parse
|
|
57
|
-
let document: DocumentNode
|
|
58
|
-
try {
|
|
59
|
-
document = parse(source)
|
|
60
|
-
} catch (parseError) {
|
|
61
|
-
// Parse errors are returned as GraphQL errors, not thrown
|
|
62
|
-
const extensionData = yield* extensionsService.get()
|
|
63
|
-
return {
|
|
64
|
-
errors: [
|
|
65
|
-
parseError instanceof GraphQLError ? parseError : new GraphQLError(String(parseError)),
|
|
66
|
-
],
|
|
67
|
-
extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,
|
|
68
|
-
} as ExecutionResult
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Run onParse hooks
|
|
72
|
-
yield* runParseHooks(extensions, source, document).pipe(
|
|
73
|
-
Effect.provideService(ExtensionsService, extensionsService)
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
// Phase 2: Validate
|
|
77
|
-
const validationErrors = validate(schema, document)
|
|
78
|
-
|
|
79
|
-
// Run onValidate hooks
|
|
80
|
-
yield* runValidateHooks(extensions, document, validationErrors).pipe(
|
|
81
|
-
Effect.provideService(ExtensionsService, extensionsService)
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
// If validation failed, return errors without executing
|
|
85
|
-
if (validationErrors.length > 0) {
|
|
86
|
-
const extensionData = yield* extensionsService.get()
|
|
87
|
-
return {
|
|
88
|
-
errors: validationErrors,
|
|
89
|
-
extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,
|
|
90
|
-
} as ExecutionResult
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Phase 3: Execute
|
|
94
|
-
const executionArgs = {
|
|
95
|
-
source,
|
|
96
|
-
document,
|
|
97
|
-
variableValues,
|
|
98
|
-
operationName,
|
|
99
|
-
schema,
|
|
100
|
-
fieldComplexities,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Run onExecuteStart hooks
|
|
104
|
-
yield* runExecuteStartHooks(extensions, executionArgs).pipe(
|
|
105
|
-
Effect.provideService(ExtensionsService, extensionsService)
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
// Execute the GraphQL query
|
|
109
|
-
const executeResult = yield* Effect.try({
|
|
110
|
-
try: () =>
|
|
111
|
-
graphqlExecute({
|
|
112
|
-
schema,
|
|
113
|
-
document,
|
|
114
|
-
variableValues,
|
|
115
|
-
operationName,
|
|
116
|
-
contextValue: { runtime } satisfies GraphQLEffectContext<R>,
|
|
117
|
-
}),
|
|
118
|
-
catch: (error) => new Error(String(error)),
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
// Await result if it's a promise (for subscriptions, it might be)
|
|
122
|
-
const resolvedResult: Awaited<typeof executeResult> =
|
|
123
|
-
executeResult && typeof executeResult === "object" && "then" in executeResult
|
|
124
|
-
? yield* Effect.promise(() => executeResult)
|
|
125
|
-
: executeResult
|
|
126
|
-
|
|
127
|
-
// Run onExecuteEnd hooks
|
|
128
|
-
yield* runExecuteEndHooks(extensions, resolvedResult).pipe(
|
|
129
|
-
Effect.provideService(ExtensionsService, extensionsService)
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
// Merge extension data into result
|
|
133
|
-
const extensionData = yield* extensionsService.get()
|
|
134
|
-
if (Object.keys(extensionData).length > 0) {
|
|
135
|
-
return {
|
|
136
|
-
...resolvedResult,
|
|
137
|
-
extensions: {
|
|
138
|
-
...resolvedResult.extensions,
|
|
139
|
-
...extensionData,
|
|
140
|
-
},
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return resolvedResult
|
|
145
|
-
}).pipe(Effect.provide(layer)) as Effect.Effect<ExecutionResult, Error>
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Execute a GraphQL query with a service layer (simple version without extensions)
|
|
149
|
-
*
|
|
150
|
-
* @deprecated Use execute() instead, which now supports extensions as an optional parameter
|
|
151
|
-
*/
|
|
152
|
-
export const executeSimple = <R>(schema: GraphQLSchema, layer: Layer.Layer<R>) =>
|
|
153
|
-
execute(schema, layer, [])
|