@effect-gql/core 1.0.0 → 1.1.1
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 +27 -1
- package/builder/index.cjs +17 -2
- package/builder/index.cjs.map +1 -1
- package/builder/index.d.cts +3 -2
- package/builder/index.d.ts +3 -2
- package/builder/index.js +17 -2
- package/builder/index.js.map +1 -1
- package/index.cjs +141 -74
- package/index.cjs.map +1 -1
- package/index.d.cts +9 -3
- package/index.d.ts +9 -3
- package/index.js +143 -76
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/{schema-builder-Cvdq7Kz_.d.cts → schema-builder-DKvkzU_M.d.cts} +2 -0
- package/{schema-builder-Cvdq7Kz_.d.ts → schema-builder-DKvkzU_M.d.ts} +2 -0
- package/server/index.cjs +88 -47
- package/server/index.cjs.map +1 -1
- package/server/index.d.cts +5 -3
- package/server/index.d.ts +5 -3
- package/server/index.js +91 -50
- package/server/index.js.map +1 -1
package/server/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Layer, Cause, Effect, Stream, Runtime } from 'effect';
|
|
2
|
-
import { j as ComplexityConfig, y as CacheControlConfig, F as FieldComplexityMap, w as CacheHintMap, G as GraphQLExtension, i as GraphQLSchemaBuilder } from '../schema-builder-
|
|
3
|
-
export { J as CacheControlConfigFromEnv, x as CachePolicy, z as CachePolicyAnalysisInfo, q as ComplexityAnalysisError, l as ComplexityAnalysisInfo, n as ComplexityCalculator, u as ComplexityConfigFromEnv, m as ComplexityExceededInfo, p as ComplexityLimitExceededError, k as ComplexityResult, o as FieldComplexity, t as combineCalculators, A as computeCachePolicy, B as computeCachePolicyFromQuery, r as defaultComplexityCalculator, s as depthOnlyCalculator, H as toCacheControlHeader, v as validateComplexity } from '../schema-builder-
|
|
2
|
+
import { j as ComplexityConfig, y as CacheControlConfig, F as FieldComplexityMap, w as CacheHintMap, G as GraphQLExtension, i as GraphQLSchemaBuilder } from '../schema-builder-DKvkzU_M.cjs';
|
|
3
|
+
export { J as CacheControlConfigFromEnv, x as CachePolicy, z as CachePolicyAnalysisInfo, q as ComplexityAnalysisError, l as ComplexityAnalysisInfo, n as ComplexityCalculator, u as ComplexityConfigFromEnv, m as ComplexityExceededInfo, p as ComplexityLimitExceededError, k as ComplexityResult, o as FieldComplexity, t as combineCalculators, A as computeCachePolicy, B as computeCachePolicyFromQuery, r as defaultComplexityCalculator, s as depthOnlyCalculator, H as toCacheControlHeader, v as validateComplexity } from '../schema-builder-DKvkzU_M.cjs';
|
|
4
4
|
import { HttpServerResponse, HttpRouter } from '@effect/platform';
|
|
5
5
|
import { GraphQLSchema, ExecutionResult } from 'graphql';
|
|
6
6
|
import * as effect_Cause from 'effect/Cause';
|
|
@@ -15,6 +15,8 @@ interface GraphiQLConfig {
|
|
|
15
15
|
readonly path: string;
|
|
16
16
|
/** URL where GraphiQL sends requests (default: same as graphql path) */
|
|
17
17
|
readonly endpoint: string;
|
|
18
|
+
/** WebSocket URL for subscriptions (default: same as endpoint) */
|
|
19
|
+
readonly subscriptionEndpoint?: string;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Configuration for the GraphQL router
|
|
@@ -73,7 +75,7 @@ declare const GraphQLRouterConfigFromEnv: Config.Config<GraphQLRouterConfig>;
|
|
|
73
75
|
/**
|
|
74
76
|
* Generate HTML for GraphiQL IDE, loading dependencies from CDN
|
|
75
77
|
*/
|
|
76
|
-
declare const graphiqlHtml: (endpoint: string) => string;
|
|
78
|
+
declare const graphiqlHtml: (endpoint: string, subscriptionEndpoint?: string) => string;
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Error handler function type for handling uncaught errors during GraphQL execution.
|
package/server/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Layer, Cause, Effect, Stream, Runtime } from 'effect';
|
|
2
|
-
import { j as ComplexityConfig, y as CacheControlConfig, F as FieldComplexityMap, w as CacheHintMap, G as GraphQLExtension, i as GraphQLSchemaBuilder } from '../schema-builder-
|
|
3
|
-
export { J as CacheControlConfigFromEnv, x as CachePolicy, z as CachePolicyAnalysisInfo, q as ComplexityAnalysisError, l as ComplexityAnalysisInfo, n as ComplexityCalculator, u as ComplexityConfigFromEnv, m as ComplexityExceededInfo, p as ComplexityLimitExceededError, k as ComplexityResult, o as FieldComplexity, t as combineCalculators, A as computeCachePolicy, B as computeCachePolicyFromQuery, r as defaultComplexityCalculator, s as depthOnlyCalculator, H as toCacheControlHeader, v as validateComplexity } from '../schema-builder-
|
|
2
|
+
import { j as ComplexityConfig, y as CacheControlConfig, F as FieldComplexityMap, w as CacheHintMap, G as GraphQLExtension, i as GraphQLSchemaBuilder } from '../schema-builder-DKvkzU_M.js';
|
|
3
|
+
export { J as CacheControlConfigFromEnv, x as CachePolicy, z as CachePolicyAnalysisInfo, q as ComplexityAnalysisError, l as ComplexityAnalysisInfo, n as ComplexityCalculator, u as ComplexityConfigFromEnv, m as ComplexityExceededInfo, p as ComplexityLimitExceededError, k as ComplexityResult, o as FieldComplexity, t as combineCalculators, A as computeCachePolicy, B as computeCachePolicyFromQuery, r as defaultComplexityCalculator, s as depthOnlyCalculator, H as toCacheControlHeader, v as validateComplexity } from '../schema-builder-DKvkzU_M.js';
|
|
4
4
|
import { HttpServerResponse, HttpRouter } from '@effect/platform';
|
|
5
5
|
import { GraphQLSchema, ExecutionResult } from 'graphql';
|
|
6
6
|
import * as effect_Cause from 'effect/Cause';
|
|
@@ -15,6 +15,8 @@ interface GraphiQLConfig {
|
|
|
15
15
|
readonly path: string;
|
|
16
16
|
/** URL where GraphiQL sends requests (default: same as graphql path) */
|
|
17
17
|
readonly endpoint: string;
|
|
18
|
+
/** WebSocket URL for subscriptions (default: same as endpoint) */
|
|
19
|
+
readonly subscriptionEndpoint?: string;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Configuration for the GraphQL router
|
|
@@ -73,7 +75,7 @@ declare const GraphQLRouterConfigFromEnv: Config.Config<GraphQLRouterConfig>;
|
|
|
73
75
|
/**
|
|
74
76
|
* Generate HTML for GraphiQL IDE, loading dependencies from CDN
|
|
75
77
|
*/
|
|
76
|
-
declare const graphiqlHtml: (endpoint: string) => string;
|
|
78
|
+
declare const graphiqlHtml: (endpoint: string, subscriptionEndpoint?: string) => string;
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Error handler function type for handling uncaught errors during GraphQL execution.
|
package/server/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Config, Option, Data, Context, Effect, Queue, Deferred, Stream, Ref,
|
|
2
|
-
import { HttpServerResponse, HttpServerRequest, HttpRouter } from '@effect/platform';
|
|
3
|
-
import { Kind, GraphQLObjectType, parse, specifiedRules, NoSchemaIntrospectionCustomRule, validate,
|
|
4
|
-
import { makeServer } from 'graphql-ws';
|
|
1
|
+
import { Config, Option, Data, Context, Schema, Effect, Queue, Deferred, Stream, Ref, Fiber, Runtime } from 'effect';
|
|
2
|
+
import { HttpIncomingMessage, HttpServerResponse, HttpServerRequest, HttpRouter } from '@effect/platform';
|
|
3
|
+
import { Kind, GraphQLObjectType, parse, specifiedRules, NoSchemaIntrospectionCustomRule, validate, GraphQLError, subscribe, GraphQLNonNull, GraphQLList, GraphQLSchema, GraphQLScalarType, GraphQLEnumType, execute } from 'graphql';
|
|
5
4
|
|
|
6
5
|
// src/server/config.ts
|
|
7
6
|
var defaultConfig = {
|
|
@@ -96,7 +95,7 @@ var GraphQLRouterConfigFromEnv = Config.all({
|
|
|
96
95
|
);
|
|
97
96
|
|
|
98
97
|
// src/server/graphiql.ts
|
|
99
|
-
var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
|
|
98
|
+
var graphiqlHtml = (endpoint, subscriptionEndpoint) => `<!DOCTYPE html>
|
|
100
99
|
<html lang="en">
|
|
101
100
|
<head>
|
|
102
101
|
<meta charset="utf-8" />
|
|
@@ -124,6 +123,7 @@ var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
|
|
|
124
123
|
<script>
|
|
125
124
|
const fetcher = GraphiQL.createFetcher({
|
|
126
125
|
url: ${JSON.stringify(endpoint)},
|
|
126
|
+
subscriptionUrl: ${JSON.stringify(subscriptionEndpoint ?? endpoint)},
|
|
127
127
|
});
|
|
128
128
|
ReactDOM.createRoot(document.getElementById('graphiql')).render(
|
|
129
129
|
React.createElement(GraphiQL, { fetcher })
|
|
@@ -848,19 +848,32 @@ var defaultErrorHandler = (cause) => (process.env.NODE_ENV !== "production" ? Ef
|
|
|
848
848
|
).pipe(Effect.orDie)
|
|
849
849
|
)
|
|
850
850
|
);
|
|
851
|
-
var
|
|
851
|
+
var GraphQLRequestBodySchema = Schema.Struct({
|
|
852
|
+
query: Schema.String,
|
|
853
|
+
variables: Schema.optionalWith(Schema.Record({ key: Schema.String, value: Schema.Unknown }), {
|
|
854
|
+
as: "Option"
|
|
855
|
+
}),
|
|
856
|
+
operationName: Schema.optionalWith(Schema.String, { as: "Option" })
|
|
857
|
+
});
|
|
858
|
+
var decodeRequestBody = HttpIncomingMessage.schemaBodyJson(GraphQLRequestBodySchema);
|
|
859
|
+
var parseGraphQLQuery = (query, extensionsService) => {
|
|
852
860
|
try {
|
|
853
861
|
const document = parse(query);
|
|
854
|
-
return { ok: true, document };
|
|
862
|
+
return Effect.succeed({ ok: true, document });
|
|
855
863
|
} catch (parseError) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
864
|
+
return extensionsService.get().pipe(
|
|
865
|
+
Effect.flatMap(
|
|
866
|
+
(extensionData) => HttpServerResponse.json({
|
|
867
|
+
errors: [{ message: String(parseError) }],
|
|
868
|
+
extensions: Object.keys(extensionData).length > 0 ? extensionData : void 0
|
|
869
|
+
}).pipe(
|
|
870
|
+
Effect.orDie,
|
|
871
|
+
Effect.map((response) => ({ ok: false, response }))
|
|
872
|
+
)
|
|
873
|
+
)
|
|
874
|
+
);
|
|
862
875
|
}
|
|
863
|
-
}
|
|
876
|
+
};
|
|
864
877
|
var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig) => {
|
|
865
878
|
if (!complexityConfig) {
|
|
866
879
|
return Effect.void;
|
|
@@ -880,8 +893,9 @@ var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig
|
|
|
880
893
|
)
|
|
881
894
|
);
|
|
882
895
|
};
|
|
883
|
-
var
|
|
884
|
-
|
|
896
|
+
var isPromiseLike = (value) => value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
897
|
+
var executeGraphQLQuery = (schema, document, variables, operationName, runtime) => {
|
|
898
|
+
const tryExecute = Effect.try({
|
|
885
899
|
try: () => execute({
|
|
886
900
|
schema,
|
|
887
901
|
document,
|
|
@@ -891,33 +905,34 @@ var executeGraphQLQuery = (schema, document, variables, operationName, runtime)
|
|
|
891
905
|
}),
|
|
892
906
|
catch: (error) => new Error(String(error))
|
|
893
907
|
});
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
()
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
})
|
|
901
|
-
|
|
908
|
+
return tryExecute.pipe(
|
|
909
|
+
Effect.flatMap((executeResult) => {
|
|
910
|
+
if (isPromiseLike(executeResult)) {
|
|
911
|
+
return Effect.promise(() => executeResult);
|
|
912
|
+
}
|
|
913
|
+
return Effect.succeed(executeResult);
|
|
914
|
+
})
|
|
915
|
+
);
|
|
916
|
+
};
|
|
917
|
+
var computeCacheControlHeader = (document, operationName, schema, cacheHints, cacheControlConfig) => {
|
|
902
918
|
if (cacheControlConfig?.enabled === false || cacheControlConfig?.calculateHttpHeaders === false) {
|
|
903
|
-
return void 0;
|
|
919
|
+
return Effect.succeed(void 0);
|
|
904
920
|
}
|
|
905
921
|
const operations = document.definitions.filter(
|
|
906
922
|
(d) => d.kind === Kind.OPERATION_DEFINITION
|
|
907
923
|
);
|
|
908
924
|
const operation = operationName ? operations.find((o) => o.name?.value === operationName) : operations[0];
|
|
909
925
|
if (!operation || operation.operation === "mutation") {
|
|
910
|
-
return void 0;
|
|
926
|
+
return Effect.succeed(void 0);
|
|
911
927
|
}
|
|
912
|
-
|
|
928
|
+
return computeCachePolicy({
|
|
913
929
|
document,
|
|
914
930
|
operation,
|
|
915
931
|
schema,
|
|
916
932
|
cacheHints,
|
|
917
933
|
config: cacheControlConfig ?? {}
|
|
918
|
-
});
|
|
919
|
-
|
|
920
|
-
});
|
|
934
|
+
}).pipe(Effect.map(toCacheControlHeader));
|
|
935
|
+
};
|
|
921
936
|
var buildGraphQLResponse = (result, extensionData, cacheControlHeader) => {
|
|
922
937
|
const finalResult = Object.keys(extensionData).length > 0 ? {
|
|
923
938
|
...result,
|
|
@@ -955,7 +970,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
955
970
|
const extensionsService = yield* makeExtensionsService();
|
|
956
971
|
const runtime = yield* Effect.runtime();
|
|
957
972
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
958
|
-
const
|
|
973
|
+
const parsedBody = yield* decodeRequestBody(request);
|
|
974
|
+
const body = {
|
|
975
|
+
query: parsedBody.query,
|
|
976
|
+
variables: parsedBody.variables._tag === "Some" ? parsedBody.variables.value : void 0,
|
|
977
|
+
operationName: parsedBody.operationName._tag === "Some" ? parsedBody.operationName.value : void 0
|
|
978
|
+
};
|
|
959
979
|
const parseResult = yield* parseGraphQLQuery(body.query, extensionsService);
|
|
960
980
|
if (!parseResult.ok) {
|
|
961
981
|
return parseResult.response;
|
|
@@ -964,7 +984,7 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
964
984
|
yield* runParseHooks(extensions, body.query, document).pipe(
|
|
965
985
|
Effect.provideService(ExtensionsService, extensionsService)
|
|
966
986
|
);
|
|
967
|
-
const validationRules = resolvedConfig.introspection ? void 0 :
|
|
987
|
+
const validationRules = resolvedConfig.introspection ? void 0 : specifiedRules.concat(NoSchemaIntrospectionCustomRule);
|
|
968
988
|
const validationErrors = validate(schema, document, validationRules);
|
|
969
989
|
yield* runValidateHooks(extensions, document, validationErrors).pipe(
|
|
970
990
|
Effect.provideService(ExtensionsService, extensionsService)
|
|
@@ -1025,9 +1045,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
1025
1045
|
HttpRouter.post(resolvedConfig.path, graphqlHandler)
|
|
1026
1046
|
);
|
|
1027
1047
|
if (resolvedConfig.graphiql) {
|
|
1028
|
-
const { path, endpoint } = resolvedConfig.graphiql;
|
|
1048
|
+
const { path, endpoint, subscriptionEndpoint } = resolvedConfig.graphiql;
|
|
1029
1049
|
router = router.pipe(
|
|
1030
|
-
HttpRouter.get(
|
|
1050
|
+
HttpRouter.get(
|
|
1051
|
+
path,
|
|
1052
|
+
HttpServerResponse.html(graphiqlHtml(endpoint, subscriptionEndpoint))
|
|
1053
|
+
)
|
|
1031
1054
|
);
|
|
1032
1055
|
}
|
|
1033
1056
|
return router;
|
|
@@ -1202,27 +1225,45 @@ var runConnectionLifecycle = (socket, wsServer, extra) => Effect.gen(function* (
|
|
|
1202
1225
|
Effect.catchAllCause(() => Effect.void),
|
|
1203
1226
|
Effect.scoped
|
|
1204
1227
|
);
|
|
1228
|
+
var importGraphqlWs = Effect.tryPromise({
|
|
1229
|
+
try: () => import('graphql-ws'),
|
|
1230
|
+
catch: () => new Error(
|
|
1231
|
+
"graphql-ws is required for WebSocket subscriptions. Install it with: npm install graphql-ws"
|
|
1232
|
+
)
|
|
1233
|
+
});
|
|
1205
1234
|
var makeGraphQLWSHandler = (schema, layer, options) => {
|
|
1206
1235
|
const complexityConfig = options?.complexity;
|
|
1207
1236
|
const fieldComplexities = options?.fieldComplexities ?? /* @__PURE__ */ new Map();
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1237
|
+
let wsServerPromise = null;
|
|
1238
|
+
const getOrCreateServer = async () => {
|
|
1239
|
+
if (!wsServerPromise) {
|
|
1240
|
+
wsServerPromise = Effect.runPromise(importGraphqlWs).then(({ makeServer }) => {
|
|
1241
|
+
const serverOptions = {
|
|
1242
|
+
schema,
|
|
1243
|
+
context: async (ctx) => {
|
|
1244
|
+
const extra = ctx.extra;
|
|
1245
|
+
return {
|
|
1246
|
+
runtime: extra.runtime,
|
|
1247
|
+
...extra.connectionParams
|
|
1248
|
+
};
|
|
1249
|
+
},
|
|
1250
|
+
subscribe: async (args) => subscribe(args),
|
|
1251
|
+
onConnect: makeOnConnectHandler(options),
|
|
1252
|
+
onDisconnect: makeOnDisconnectHandler(options),
|
|
1253
|
+
onSubscribe: makeOnSubscribeHandler(options, schema, complexityConfig, fieldComplexities),
|
|
1254
|
+
onComplete: makeOnCompleteHandler(options),
|
|
1255
|
+
onError: makeOnErrorHandler(options)
|
|
1256
|
+
};
|
|
1257
|
+
return makeServer(serverOptions);
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
return wsServerPromise;
|
|
1223
1261
|
};
|
|
1224
|
-
const wsServer = makeServer(serverOptions);
|
|
1225
1262
|
return (socket) => Effect.gen(function* () {
|
|
1263
|
+
const wsServer = yield* Effect.tryPromise({
|
|
1264
|
+
try: () => getOrCreateServer(),
|
|
1265
|
+
catch: (error) => error
|
|
1266
|
+
});
|
|
1226
1267
|
const runtime = yield* Effect.provide(Effect.runtime(), layer);
|
|
1227
1268
|
const extra = {
|
|
1228
1269
|
socket,
|