@effect-gql/core 0.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 (145) hide show
  1. package/LICENSE +7 -0
  2. package/dist/analyzer-extension.d.ts +105 -0
  3. package/dist/analyzer-extension.d.ts.map +1 -0
  4. package/dist/analyzer-extension.js +137 -0
  5. package/dist/analyzer-extension.js.map +1 -0
  6. package/dist/builder/execute.d.ts +26 -0
  7. package/dist/builder/execute.d.ts.map +1 -0
  8. package/dist/builder/execute.js +104 -0
  9. package/dist/builder/execute.js.map +1 -0
  10. package/dist/builder/field-builders.d.ts +30 -0
  11. package/dist/builder/field-builders.d.ts.map +1 -0
  12. package/dist/builder/field-builders.js +200 -0
  13. package/dist/builder/field-builders.js.map +1 -0
  14. package/dist/builder/index.d.ts +7 -0
  15. package/dist/builder/index.d.ts.map +1 -0
  16. package/dist/builder/index.js +31 -0
  17. package/dist/builder/index.js.map +1 -0
  18. package/dist/builder/pipe-api.d.ts +231 -0
  19. package/dist/builder/pipe-api.d.ts.map +1 -0
  20. package/dist/builder/pipe-api.js +151 -0
  21. package/dist/builder/pipe-api.js.map +1 -0
  22. package/dist/builder/schema-builder.d.ts +301 -0
  23. package/dist/builder/schema-builder.d.ts.map +1 -0
  24. package/dist/builder/schema-builder.js +566 -0
  25. package/dist/builder/schema-builder.js.map +1 -0
  26. package/dist/builder/type-registry.d.ts +80 -0
  27. package/dist/builder/type-registry.d.ts.map +1 -0
  28. package/dist/builder/type-registry.js +505 -0
  29. package/dist/builder/type-registry.js.map +1 -0
  30. package/dist/builder/types.d.ts +283 -0
  31. package/dist/builder/types.d.ts.map +1 -0
  32. package/dist/builder/types.js +3 -0
  33. package/dist/builder/types.js.map +1 -0
  34. package/dist/cli/generate-schema.d.ts +29 -0
  35. package/dist/cli/generate-schema.d.ts.map +1 -0
  36. package/dist/cli/generate-schema.js +233 -0
  37. package/dist/cli/generate-schema.js.map +1 -0
  38. package/dist/cli/index.d.ts +19 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +24 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/context.d.ts +18 -0
  43. package/dist/context.d.ts.map +1 -0
  44. package/dist/context.js +11 -0
  45. package/dist/context.js.map +1 -0
  46. package/dist/error.d.ts +45 -0
  47. package/dist/error.d.ts.map +1 -0
  48. package/dist/error.js +29 -0
  49. package/dist/error.js.map +1 -0
  50. package/dist/extensions.d.ts +130 -0
  51. package/dist/extensions.d.ts.map +1 -0
  52. package/dist/extensions.js +78 -0
  53. package/dist/extensions.js.map +1 -0
  54. package/dist/index.d.ts +12 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +47 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/loader.d.ts +169 -0
  59. package/dist/loader.d.ts.map +1 -0
  60. package/dist/loader.js +237 -0
  61. package/dist/loader.js.map +1 -0
  62. package/dist/resolver-context.d.ts +154 -0
  63. package/dist/resolver-context.d.ts.map +1 -0
  64. package/dist/resolver-context.js +184 -0
  65. package/dist/resolver-context.js.map +1 -0
  66. package/dist/schema-mapping.d.ts +30 -0
  67. package/dist/schema-mapping.d.ts.map +1 -0
  68. package/dist/schema-mapping.js +280 -0
  69. package/dist/schema-mapping.js.map +1 -0
  70. package/dist/server/cache-control.d.ts +96 -0
  71. package/dist/server/cache-control.d.ts.map +1 -0
  72. package/dist/server/cache-control.js +308 -0
  73. package/dist/server/cache-control.js.map +1 -0
  74. package/dist/server/complexity.d.ts +165 -0
  75. package/dist/server/complexity.d.ts.map +1 -0
  76. package/dist/server/complexity.js +433 -0
  77. package/dist/server/complexity.js.map +1 -0
  78. package/dist/server/config.d.ts +66 -0
  79. package/dist/server/config.d.ts.map +1 -0
  80. package/dist/server/config.js +104 -0
  81. package/dist/server/config.js.map +1 -0
  82. package/dist/server/graphiql.d.ts +5 -0
  83. package/dist/server/graphiql.d.ts.map +1 -0
  84. package/dist/server/graphiql.js +43 -0
  85. package/dist/server/graphiql.js.map +1 -0
  86. package/dist/server/index.d.ts +18 -0
  87. package/dist/server/index.d.ts.map +1 -0
  88. package/dist/server/index.js +48 -0
  89. package/dist/server/index.js.map +1 -0
  90. package/dist/server/router.d.ts +79 -0
  91. package/dist/server/router.d.ts.map +1 -0
  92. package/dist/server/router.js +232 -0
  93. package/dist/server/router.js.map +1 -0
  94. package/dist/server/schema-builder-extensions.d.ts +42 -0
  95. package/dist/server/schema-builder-extensions.d.ts.map +1 -0
  96. package/dist/server/schema-builder-extensions.js +48 -0
  97. package/dist/server/schema-builder-extensions.js.map +1 -0
  98. package/dist/server/sse-adapter.d.ts +64 -0
  99. package/dist/server/sse-adapter.d.ts.map +1 -0
  100. package/dist/server/sse-adapter.js +227 -0
  101. package/dist/server/sse-adapter.js.map +1 -0
  102. package/dist/server/sse-types.d.ts +192 -0
  103. package/dist/server/sse-types.d.ts.map +1 -0
  104. package/dist/server/sse-types.js +63 -0
  105. package/dist/server/sse-types.js.map +1 -0
  106. package/dist/server/ws-adapter.d.ts +39 -0
  107. package/dist/server/ws-adapter.d.ts.map +1 -0
  108. package/dist/server/ws-adapter.js +247 -0
  109. package/dist/server/ws-adapter.js.map +1 -0
  110. package/dist/server/ws-types.d.ts +169 -0
  111. package/dist/server/ws-types.d.ts.map +1 -0
  112. package/dist/server/ws-types.js +11 -0
  113. package/dist/server/ws-types.js.map +1 -0
  114. package/dist/server/ws-utils.d.ts +42 -0
  115. package/dist/server/ws-utils.d.ts.map +1 -0
  116. package/dist/server/ws-utils.js +99 -0
  117. package/dist/server/ws-utils.js.map +1 -0
  118. package/package.json +61 -0
  119. package/src/analyzer-extension.ts +254 -0
  120. package/src/builder/execute.ts +153 -0
  121. package/src/builder/field-builders.ts +322 -0
  122. package/src/builder/index.ts +48 -0
  123. package/src/builder/pipe-api.ts +312 -0
  124. package/src/builder/schema-builder.ts +970 -0
  125. package/src/builder/type-registry.ts +670 -0
  126. package/src/builder/types.ts +305 -0
  127. package/src/context.ts +23 -0
  128. package/src/error.ts +32 -0
  129. package/src/extensions.ts +240 -0
  130. package/src/index.ts +32 -0
  131. package/src/loader.ts +363 -0
  132. package/src/resolver-context.ts +253 -0
  133. package/src/schema-mapping.ts +307 -0
  134. package/src/server/cache-control.ts +590 -0
  135. package/src/server/complexity.ts +774 -0
  136. package/src/server/config.ts +174 -0
  137. package/src/server/graphiql.ts +38 -0
  138. package/src/server/index.ts +96 -0
  139. package/src/server/router.ts +432 -0
  140. package/src/server/schema-builder-extensions.ts +51 -0
  141. package/src/server/sse-adapter.ts +327 -0
  142. package/src/server/sse-types.ts +234 -0
  143. package/src/server/ws-adapter.ts +355 -0
  144. package/src/server/ws-types.ts +192 -0
  145. package/src/server/ws-utils.ts +136 -0
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2025 Nick Fisher
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,105 @@
1
+ import type { GraphQLExtension } from "./extensions";
2
+ import { ExtensionsService } from "./extensions";
3
+ import { type FieldComplexityMap } from "./server/complexity";
4
+ /**
5
+ * Configuration for the analyzer extension
6
+ */
7
+ export interface AnalyzerExtensionConfig {
8
+ /**
9
+ * Include the total complexity score in the response.
10
+ * @default true
11
+ */
12
+ readonly includeComplexity?: boolean;
13
+ /**
14
+ * Include the maximum query depth in the response.
15
+ * @default true
16
+ */
17
+ readonly includeDepth?: boolean;
18
+ /**
19
+ * Include the total field count in the response.
20
+ * @default false
21
+ */
22
+ readonly includeFieldCount?: boolean;
23
+ /**
24
+ * Include the alias count in the response.
25
+ * @default false
26
+ */
27
+ readonly includeAliasCount?: boolean;
28
+ /**
29
+ * The key to use in the response extensions object.
30
+ * @default "analyzer"
31
+ */
32
+ readonly key?: string;
33
+ /**
34
+ * Thresholds for logging warnings when exceeded.
35
+ * When a metric exceeds its threshold, a warning is logged.
36
+ */
37
+ readonly thresholds?: {
38
+ readonly depth?: number;
39
+ readonly complexity?: number;
40
+ readonly fieldCount?: number;
41
+ readonly aliasCount?: number;
42
+ };
43
+ /**
44
+ * Default complexity cost for fields without explicit costs.
45
+ * @default 1
46
+ */
47
+ readonly defaultFieldComplexity?: number;
48
+ /**
49
+ * Optional field complexity overrides.
50
+ * If not provided, uses the field complexities from the schema builder
51
+ * (passed via ExecutionArgs).
52
+ */
53
+ readonly fieldComplexities?: FieldComplexityMap;
54
+ }
55
+ /**
56
+ * Output format for analyzer extension
57
+ */
58
+ export interface AnalyzerOutput {
59
+ complexity?: number;
60
+ depth?: number;
61
+ fieldCount?: number;
62
+ aliasCount?: number;
63
+ }
64
+ /**
65
+ * Create an analyzer extension that reports query complexity metrics
66
+ * in the response extensions field.
67
+ *
68
+ * Similar to async-graphql's Analyzer extension, this allows you to
69
+ * monitor the complexity of incoming queries without blocking execution.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // Basic usage - reports complexity and depth
74
+ * const analyzer = createAnalyzerExtension()
75
+ *
76
+ * // With all metrics and warnings
77
+ * const analyzer = createAnalyzerExtension({
78
+ * includeFieldCount: true,
79
+ * includeAliasCount: true,
80
+ * thresholds: {
81
+ * depth: 10,
82
+ * complexity: 100,
83
+ * },
84
+ * })
85
+ *
86
+ * // Add to schema builder
87
+ * const builder = GraphQLSchemaBuilder.empty.pipe(
88
+ * extension(analyzer),
89
+ * // ...queries, mutations, etc.
90
+ * )
91
+ *
92
+ * // Response will include:
93
+ * // {
94
+ * // "data": { ... },
95
+ * // "extensions": {
96
+ * // "analyzer": {
97
+ * // "complexity": 42,
98
+ * // "depth": 3
99
+ * // }
100
+ * // }
101
+ * // }
102
+ * ```
103
+ */
104
+ export declare const createAnalyzerExtension: (config?: AnalyzerExtensionConfig) => GraphQLExtension<ExtensionsService>;
105
+ //# sourceMappingURL=analyzer-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer-extension.d.ts","sourceRoot":"","sources":["../src/analyzer-extension.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAA;AAE5B;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAEpC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;IAE/B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAEpC;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAEpC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAC7B,CAAA;IAED;;;OAGG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAExC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,uBAAuB,GAClC,SAAQ,uBAA4B,KACnC,gBAAgB,CAAC,iBAAiB,CAuEpC,CAAA"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAnalyzerExtension = void 0;
4
+ const effect_1 = require("effect");
5
+ const graphql_1 = require("graphql");
6
+ const extensions_1 = require("./extensions");
7
+ const complexity_1 = require("./server/complexity");
8
+ /**
9
+ * Create an analyzer extension that reports query complexity metrics
10
+ * in the response extensions field.
11
+ *
12
+ * Similar to async-graphql's Analyzer extension, this allows you to
13
+ * monitor the complexity of incoming queries without blocking execution.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Basic usage - reports complexity and depth
18
+ * const analyzer = createAnalyzerExtension()
19
+ *
20
+ * // With all metrics and warnings
21
+ * const analyzer = createAnalyzerExtension({
22
+ * includeFieldCount: true,
23
+ * includeAliasCount: true,
24
+ * thresholds: {
25
+ * depth: 10,
26
+ * complexity: 100,
27
+ * },
28
+ * })
29
+ *
30
+ * // Add to schema builder
31
+ * const builder = GraphQLSchemaBuilder.empty.pipe(
32
+ * extension(analyzer),
33
+ * // ...queries, mutations, etc.
34
+ * )
35
+ *
36
+ * // Response will include:
37
+ * // {
38
+ * // "data": { ... },
39
+ * // "extensions": {
40
+ * // "analyzer": {
41
+ * // "complexity": 42,
42
+ * // "depth": 3
43
+ * // }
44
+ * // }
45
+ * // }
46
+ * ```
47
+ */
48
+ const createAnalyzerExtension = (config = {}) => {
49
+ const { includeComplexity = true, includeDepth = true, includeFieldCount = false, includeAliasCount = false, key = "analyzer", thresholds, defaultFieldComplexity = 1, fieldComplexities: configFieldComplexities, } = config;
50
+ return {
51
+ name: "analyzer",
52
+ description: "Reports query complexity metrics in response extensions",
53
+ onExecuteStart: (args) => effect_1.Effect.gen(function* () {
54
+ const ext = yield* extensions_1.ExtensionsService;
55
+ // Find the operation
56
+ const operation = findOperation(args);
57
+ if (!operation) {
58
+ return;
59
+ }
60
+ // Use config field complexities if provided, otherwise use from args
61
+ const fieldComplexities = configFieldComplexities ?? args.fieldComplexities;
62
+ // Calculate complexity
63
+ const calculator = (0, complexity_1.defaultComplexityCalculator)(defaultFieldComplexity);
64
+ const result = yield* calculator({
65
+ document: args.document,
66
+ operation,
67
+ variables: args.variableValues,
68
+ schema: args.schema,
69
+ fieldComplexities,
70
+ }).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.logWarning("Analyzer extension: complexity calculation failed", error).pipe(effect_1.Effect.as(null))));
71
+ if (!result) {
72
+ return;
73
+ }
74
+ // Check thresholds and log warnings
75
+ yield* checkThresholds(result, thresholds);
76
+ // Build output
77
+ const output = {};
78
+ if (includeComplexity) {
79
+ output.complexity = result.complexity;
80
+ }
81
+ if (includeDepth) {
82
+ output.depth = result.depth;
83
+ }
84
+ if (includeFieldCount) {
85
+ output.fieldCount = result.fieldCount;
86
+ }
87
+ if (includeAliasCount) {
88
+ output.aliasCount = result.aliasCount;
89
+ }
90
+ // Add to extensions
91
+ yield* ext.set(key, output);
92
+ }),
93
+ };
94
+ };
95
+ exports.createAnalyzerExtension = createAnalyzerExtension;
96
+ /**
97
+ * Find the operation to analyze from the document
98
+ */
99
+ function findOperation(args) {
100
+ const operations = args.document.definitions.filter((d) => d.kind === graphql_1.Kind.OPERATION_DEFINITION);
101
+ if (operations.length === 0) {
102
+ return null;
103
+ }
104
+ if (args.operationName) {
105
+ return operations.find((o) => o.name?.value === args.operationName) ?? null;
106
+ }
107
+ return operations[0];
108
+ }
109
+ /**
110
+ * Check thresholds and log warnings for exceeded values
111
+ */
112
+ function checkThresholds(result, thresholds) {
113
+ if (!thresholds) {
114
+ return effect_1.Effect.void;
115
+ }
116
+ const warnings = [];
117
+ if (thresholds.depth !== undefined && result.depth > thresholds.depth) {
118
+ warnings.push(`Query depth ${result.depth} exceeds threshold ${thresholds.depth}`);
119
+ }
120
+ if (thresholds.complexity !== undefined && result.complexity > thresholds.complexity) {
121
+ warnings.push(`Query complexity ${result.complexity} exceeds threshold ${thresholds.complexity}`);
122
+ }
123
+ if (thresholds.fieldCount !== undefined && result.fieldCount > thresholds.fieldCount) {
124
+ warnings.push(`Query field count ${result.fieldCount} exceeds threshold ${thresholds.fieldCount}`);
125
+ }
126
+ if (thresholds.aliasCount !== undefined && result.aliasCount > thresholds.aliasCount) {
127
+ warnings.push(`Query alias count ${result.aliasCount} exceeds threshold ${thresholds.aliasCount}`);
128
+ }
129
+ if (warnings.length > 0) {
130
+ return effect_1.Effect.logWarning("Analyzer extension: thresholds exceeded", {
131
+ warnings,
132
+ result,
133
+ });
134
+ }
135
+ return effect_1.Effect.void;
136
+ }
137
+ //# sourceMappingURL=analyzer-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer-extension.js","sourceRoot":"","sources":["../src/analyzer-extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { Effect, Layer } from "effect";
2
+ import { GraphQLSchema, type ExecutionResult } from "graphql";
3
+ import { type GraphQLExtension } from "../extensions";
4
+ import type { FieldComplexityMap } from "../server/complexity";
5
+ /**
6
+ * Execute a GraphQL query with a service layer
7
+ *
8
+ * This is the layer-per-request execution model. Build the schema once,
9
+ * then execute each request with its own layer (including request-scoped services).
10
+ *
11
+ * The execution follows these phases:
12
+ * 1. Parse - Convert source string to DocumentNode
13
+ * 2. Validate - Check document against schema
14
+ * 3. Execute - Run resolvers and return result
15
+ *
16
+ * Extensions can hook into each phase via onParse, onValidate, onExecuteStart, onExecuteEnd.
17
+ * Extension data is automatically merged into the response's extensions field.
18
+ */
19
+ export declare const execute: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, extensions?: readonly GraphQLExtension<any>[], fieldComplexities?: FieldComplexityMap) => (source: string, variableValues?: Record<string, unknown>, operationName?: string) => Effect.Effect<ExecutionResult, Error>;
20
+ /**
21
+ * Execute a GraphQL query with a service layer (simple version without extensions)
22
+ *
23
+ * @deprecated Use execute() instead, which now supports extensions as an optional parameter
24
+ */
25
+ export declare const executeSimple: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>) => (source: string, variableValues?: Record<string, unknown>, operationName?: string) => Effect.Effect<ExecutionResult, Error>;
26
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/builder/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EACL,aAAa,EAKb,KAAK,eAAe,EAErB,MAAM,SAAS,CAAA;AAEhB,OAAO,EACL,KAAK,gBAAgB,EAOtB,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO,GACjB,CAAC,EACA,QAAQ,aAAa,EACrB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB,aAAY,SAAS,gBAAgB,CAAC,GAAG,CAAC,EAAO,EACjD,oBAAmB,kBAA8B,MAGjD,QAAQ,MAAM,EACd,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,gBAAgB,MAAM,KACrB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAiGkC,CAAA;AAE3E;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,QAAQ,aAAa,EAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,cA3GjE,MAAM,mBACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBACxB,MAAM,KACrB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAyGb,CAAA"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeSimple = exports.execute = void 0;
4
+ const effect_1 = require("effect");
5
+ const graphql_1 = require("graphql");
6
+ const extensions_1 = require("../extensions");
7
+ /**
8
+ * Execute a GraphQL query with a service layer
9
+ *
10
+ * This is the layer-per-request execution model. Build the schema once,
11
+ * then execute each request with its own layer (including request-scoped services).
12
+ *
13
+ * The execution follows these phases:
14
+ * 1. Parse - Convert source string to DocumentNode
15
+ * 2. Validate - Check document against schema
16
+ * 3. Execute - Run resolvers and return result
17
+ *
18
+ * Extensions can hook into each phase via onParse, onValidate, onExecuteStart, onExecuteEnd.
19
+ * Extension data is automatically merged into the response's extensions field.
20
+ */
21
+ const execute = (schema, layer, extensions = [], fieldComplexities = new Map()) => (source, variableValues, operationName) => effect_1.Effect.gen(function* () {
22
+ // Create the ExtensionsService for this request
23
+ const extensionsService = yield* (0, extensions_1.makeExtensionsService)();
24
+ // Create runtime from the provided layer
25
+ const runtime = yield* effect_1.Effect.runtime();
26
+ // Phase 1: Parse
27
+ let document;
28
+ try {
29
+ document = (0, graphql_1.parse)(source);
30
+ }
31
+ catch (parseError) {
32
+ // Parse errors are returned as GraphQL errors, not thrown
33
+ const extensionData = yield* extensionsService.get();
34
+ return {
35
+ errors: [
36
+ parseError instanceof graphql_1.GraphQLError ? parseError : new graphql_1.GraphQLError(String(parseError)),
37
+ ],
38
+ extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,
39
+ };
40
+ }
41
+ // Run onParse hooks
42
+ yield* (0, extensions_1.runParseHooks)(extensions, source, document).pipe(effect_1.Effect.provideService(extensions_1.ExtensionsService, extensionsService));
43
+ // Phase 2: Validate
44
+ const validationErrors = (0, graphql_1.validate)(schema, document);
45
+ // Run onValidate hooks
46
+ yield* (0, extensions_1.runValidateHooks)(extensions, document, validationErrors).pipe(effect_1.Effect.provideService(extensions_1.ExtensionsService, extensionsService));
47
+ // If validation failed, return errors without executing
48
+ if (validationErrors.length > 0) {
49
+ const extensionData = yield* extensionsService.get();
50
+ return {
51
+ errors: validationErrors,
52
+ extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,
53
+ };
54
+ }
55
+ // Phase 3: Execute
56
+ const executionArgs = {
57
+ source,
58
+ document,
59
+ variableValues,
60
+ operationName,
61
+ schema,
62
+ fieldComplexities,
63
+ };
64
+ // Run onExecuteStart hooks
65
+ yield* (0, extensions_1.runExecuteStartHooks)(extensions, executionArgs).pipe(effect_1.Effect.provideService(extensions_1.ExtensionsService, extensionsService));
66
+ // Execute the GraphQL query
67
+ const executeResult = yield* effect_1.Effect.try({
68
+ try: () => (0, graphql_1.execute)({
69
+ schema,
70
+ document,
71
+ variableValues,
72
+ operationName,
73
+ contextValue: { runtime },
74
+ }),
75
+ catch: (error) => new Error(String(error)),
76
+ });
77
+ // Await result if it's a promise (for subscriptions, it might be)
78
+ const resolvedResult = executeResult && typeof executeResult === "object" && "then" in executeResult
79
+ ? yield* effect_1.Effect.promise(() => executeResult)
80
+ : executeResult;
81
+ // Run onExecuteEnd hooks
82
+ yield* (0, extensions_1.runExecuteEndHooks)(extensions, resolvedResult).pipe(effect_1.Effect.provideService(extensions_1.ExtensionsService, extensionsService));
83
+ // Merge extension data into result
84
+ const extensionData = yield* extensionsService.get();
85
+ if (Object.keys(extensionData).length > 0) {
86
+ return {
87
+ ...resolvedResult,
88
+ extensions: {
89
+ ...resolvedResult.extensions,
90
+ ...extensionData,
91
+ },
92
+ };
93
+ }
94
+ return resolvedResult;
95
+ }).pipe(effect_1.Effect.provide(layer));
96
+ exports.execute = execute;
97
+ /**
98
+ * Execute a GraphQL query with a service layer (simple version without extensions)
99
+ *
100
+ * @deprecated Use execute() instead, which now supports extensions as an optional parameter
101
+ */
102
+ const executeSimple = (schema, layer) => (0, exports.execute)(schema, layer, []);
103
+ exports.executeSimple = executeSimple;
104
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/builder/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { GraphQLFieldConfig } from "graphql";
2
+ import type { FieldRegistration, SubscriptionFieldRegistration, ObjectFieldRegistration, DirectiveRegistration, MiddlewareRegistration } from "./types";
3
+ import { type TypeConversionContext, type InputTypeLookupCache } from "./type-registry";
4
+ /**
5
+ * Context needed for building fields
6
+ */
7
+ export interface FieldBuilderContext extends TypeConversionContext {
8
+ directiveRegistrations: Map<string, DirectiveRegistration>;
9
+ middlewares: readonly MiddlewareRegistration[];
10
+ inputTypeLookupCache?: InputTypeLookupCache;
11
+ }
12
+ /**
13
+ * Build a GraphQL field config from a field registration (for queries/mutations)
14
+ */
15
+ export declare function buildField(config: FieldRegistration, ctx: FieldBuilderContext): GraphQLFieldConfig<any, any>;
16
+ /**
17
+ * Build a GraphQL field config for an object field (has parent param)
18
+ */
19
+ export declare function buildObjectField(config: ObjectFieldRegistration, ctx: FieldBuilderContext): GraphQLFieldConfig<any, any>;
20
+ /**
21
+ * Build a GraphQL subscription field config.
22
+ *
23
+ * Subscriptions in GraphQL have a special structure:
24
+ * - `subscribe` returns an AsyncIterator that yields the "root value" for each event
25
+ * - `resolve` transforms each yielded value into the final result
26
+ *
27
+ * We convert Effect's Stream to an AsyncIterator using a Queue-based approach.
28
+ */
29
+ export declare function buildSubscriptionField(config: SubscriptionFieldRegistration, ctx: FieldBuilderContext): GraphQLFieldConfig<any, any>;
30
+ //# sourceMappingURL=field-builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-builders.d.ts","sourceRoot":"","sources":["../../src/builder/field-builders.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAsB,MAAM,SAAS,CAAA;AAChE,OAAO,KAAK,EACV,iBAAiB,EACjB,6BAA6B,EAC7B,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EAGvB,MAAM,SAAS,CAAA;AAChB,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAA;AAExB;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAChE,sBAAsB,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;IAC1D,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC9C,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;CAC5C;AAwDD;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,mBAAmB,GACvB,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAuC9B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,uBAAuB,EAC/B,GAAG,EAAE,mBAAmB,GACvB,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAkC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,6BAA6B,EACrC,GAAG,EAAE,mBAAmB,GACvB,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CA6D9B"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildField = buildField;
4
+ exports.buildObjectField = buildObjectField;
5
+ exports.buildSubscriptionField = buildSubscriptionField;
6
+ const effect_1 = require("effect");
7
+ const type_registry_1 = require("./type-registry");
8
+ /**
9
+ * Apply directives to an Effect by wrapping it with directive transformers
10
+ */
11
+ function applyDirectives(effect, directives, directiveRegistrations) {
12
+ if (!directives)
13
+ return effect;
14
+ let wrapped = effect;
15
+ for (const directiveApp of directives) {
16
+ const directiveReg = directiveRegistrations.get(directiveApp.name);
17
+ if (directiveReg?.apply) {
18
+ wrapped = directiveReg.apply(directiveApp.args ?? {})(wrapped);
19
+ }
20
+ }
21
+ return wrapped;
22
+ }
23
+ /**
24
+ * Apply middleware to an Effect by wrapping it with middleware transformers.
25
+ *
26
+ * Middleware executes in "onion" order - first registered middleware is the
27
+ * outermost layer, meaning it runs first before and last after the resolver.
28
+ *
29
+ * Each middleware can optionally specify a `match` predicate to filter which
30
+ * fields it applies to.
31
+ */
32
+ function applyMiddleware(effect, context, middlewares) {
33
+ if (middlewares.length === 0)
34
+ return effect;
35
+ let wrapped = effect;
36
+ // Apply in reverse order so first registered is outermost
37
+ // (executes first before, last after)
38
+ for (let i = middlewares.length - 1; i >= 0; i--) {
39
+ const middleware = middlewares[i];
40
+ // Check if middleware should apply to this field
41
+ if (middleware.match && !middleware.match(context.info)) {
42
+ continue;
43
+ }
44
+ wrapped = middleware.apply(wrapped, context);
45
+ }
46
+ return wrapped;
47
+ }
48
+ /**
49
+ * Build a GraphQL field config from a field registration (for queries/mutations)
50
+ */
51
+ function buildField(config, ctx) {
52
+ const fieldConfig = {
53
+ type: (0, type_registry_1.toGraphQLTypeWithRegistry)(config.type, ctx),
54
+ resolve: async (_parent, args, context, info) => {
55
+ // Apply directives first (per-field, explicit)
56
+ let effect = applyDirectives(config.resolve(args), config.directives, ctx.directiveRegistrations);
57
+ // Apply middleware (global/pattern-matched)
58
+ const middlewareContext = { parent: _parent, args, info };
59
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
60
+ return await effect_1.Runtime.runPromise(context.runtime)(effect);
61
+ },
62
+ };
63
+ if (config.args) {
64
+ fieldConfig.args = (0, type_registry_1.toGraphQLArgsWithRegistry)(config.args, ctx.enumRegistry, ctx.inputRegistry, ctx.inputs, ctx.enums, ctx.inputTypeLookupCache);
65
+ }
66
+ if (config.description) {
67
+ fieldConfig.description = config.description;
68
+ }
69
+ return fieldConfig;
70
+ }
71
+ /**
72
+ * Build a GraphQL field config for an object field (has parent param)
73
+ */
74
+ function buildObjectField(config, ctx) {
75
+ const fieldConfig = {
76
+ type: (0, type_registry_1.toGraphQLTypeWithRegistry)(config.type, ctx),
77
+ resolve: async (parent, args, context, info) => {
78
+ // Apply directives first (per-field, explicit)
79
+ let effect = applyDirectives(config.resolve(parent, args), config.directives, ctx.directiveRegistrations);
80
+ // Apply middleware (global/pattern-matched)
81
+ const middlewareContext = { parent, args, info };
82
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
83
+ return await effect_1.Runtime.runPromise(context.runtime)(effect);
84
+ },
85
+ };
86
+ if (config.args) {
87
+ fieldConfig.args = (0, type_registry_1.toGraphQLArgsWithRegistry)(config.args, ctx.enumRegistry, ctx.inputRegistry, ctx.inputs, ctx.enums, ctx.inputTypeLookupCache);
88
+ }
89
+ if (config.description) {
90
+ fieldConfig.description = config.description;
91
+ }
92
+ return fieldConfig;
93
+ }
94
+ /**
95
+ * Build a GraphQL subscription field config.
96
+ *
97
+ * Subscriptions in GraphQL have a special structure:
98
+ * - `subscribe` returns an AsyncIterator that yields the "root value" for each event
99
+ * - `resolve` transforms each yielded value into the final result
100
+ *
101
+ * We convert Effect's Stream to an AsyncIterator using a Queue-based approach.
102
+ */
103
+ function buildSubscriptionField(config, ctx) {
104
+ const fieldConfig = {
105
+ type: (0, type_registry_1.toGraphQLTypeWithRegistry)(config.type, ctx),
106
+ // The subscribe function returns an AsyncIterator
107
+ subscribe: async (_parent, args, context, info) => {
108
+ // Get the Stream from the subscribe Effect
109
+ let subscribeEffect = config.subscribe(args);
110
+ // Apply directives to the subscribe effect
111
+ subscribeEffect = applyDirectives(subscribeEffect, config.directives, ctx.directiveRegistrations);
112
+ // Apply middleware to the subscribe effect
113
+ const middlewareContext = { parent: _parent, args, info };
114
+ subscribeEffect = applyMiddleware(subscribeEffect, middlewareContext, ctx.middlewares);
115
+ const stream = await effect_1.Runtime.runPromise(context.runtime)(subscribeEffect);
116
+ // Convert Stream to AsyncIterator using queue-based approach
117
+ return streamToAsyncIterator(stream, context.runtime);
118
+ },
119
+ // The resolve function transforms each yielded value
120
+ // If no custom resolve is provided, return the payload directly
121
+ resolve: config.resolve
122
+ ? async (value, args, context, info) => {
123
+ let effect = config.resolve(value, args);
124
+ // Apply middleware to the resolve effect
125
+ const middlewareContext = { parent: value, args, info };
126
+ effect = applyMiddleware(effect, middlewareContext, ctx.middlewares);
127
+ return await effect_1.Runtime.runPromise(context.runtime)(effect);
128
+ }
129
+ : (value) => value,
130
+ };
131
+ if (config.args) {
132
+ fieldConfig.args = (0, type_registry_1.toGraphQLArgsWithRegistry)(config.args, ctx.enumRegistry, ctx.inputRegistry, ctx.inputs, ctx.enums, ctx.inputTypeLookupCache);
133
+ }
134
+ if (config.description) {
135
+ fieldConfig.description = config.description;
136
+ }
137
+ return fieldConfig;
138
+ }
139
+ /**
140
+ * Convert an Effect Stream to an AsyncIterator using a Queue-based approach.
141
+ *
142
+ * This is needed because Stream.toAsyncIterable() requires R = never,
143
+ * but our streams may have service requirements that need to be provided
144
+ * by the runtime context.
145
+ */
146
+ function streamToAsyncIterator(stream, runtime) {
147
+ // Create the queue synchronously via runSync since unbounded queue creation is synchronous
148
+ let queue;
149
+ let fiber;
150
+ let initialized = false;
151
+ let done = false;
152
+ const initialize = async () => {
153
+ if (initialized)
154
+ return;
155
+ initialized = true;
156
+ queue = await effect_1.Runtime.runPromise(runtime)(effect_1.Queue.unbounded());
157
+ // Fork a fiber to run the stream and push values to the queue
158
+ fiber = effect_1.Runtime.runFork(runtime)(effect_1.Effect.ensuring(effect_1.Stream.runForEach(stream, (value) => effect_1.Queue.offer(queue, effect_1.Option.some(value))),
159
+ // Signal completion by pushing None
160
+ effect_1.Queue.offer(queue, effect_1.Option.none())));
161
+ };
162
+ return {
163
+ [Symbol.asyncIterator]() {
164
+ return this;
165
+ },
166
+ async next() {
167
+ await initialize();
168
+ if (done) {
169
+ return { done: true, value: undefined };
170
+ }
171
+ try {
172
+ const optionValue = await effect_1.Runtime.runPromise(runtime)(effect_1.Queue.take(queue));
173
+ if (effect_1.Option.isNone(optionValue)) {
174
+ done = true;
175
+ return { done: true, value: undefined };
176
+ }
177
+ return { done: false, value: optionValue.value };
178
+ }
179
+ catch (error) {
180
+ done = true;
181
+ throw error;
182
+ }
183
+ },
184
+ async return() {
185
+ // Cleanup - interrupt the fiber and shutdown the queue
186
+ done = true;
187
+ if (initialized) {
188
+ try {
189
+ await effect_1.Runtime.runPromise(runtime)(effect_1.Fiber.interrupt(fiber));
190
+ await effect_1.Runtime.runPromise(runtime)(effect_1.Queue.shutdown(queue));
191
+ }
192
+ catch {
193
+ // Ignore cleanup errors
194
+ }
195
+ }
196
+ return { done: true, value: undefined };
197
+ },
198
+ };
199
+ }
200
+ //# sourceMappingURL=field-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-builders.js","sourceRoot":"","sources":["../../src/builder/field-builders.ts"],"names":[],"mappings":"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"}