@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/package.json
CHANGED
|
@@ -237,6 +237,7 @@ interface FieldRegistration<Args = any, A = any, E = any, R = any> {
|
|
|
237
237
|
interface TypeRegistration {
|
|
238
238
|
name: string;
|
|
239
239
|
schema: S.Schema<any, any, any>;
|
|
240
|
+
description?: string;
|
|
240
241
|
implements?: readonly string[];
|
|
241
242
|
directives?: readonly DirectiveApplication[];
|
|
242
243
|
/**
|
|
@@ -773,6 +774,7 @@ declare class GraphQLSchemaBuilder<R = never> implements Pipeable.Pipeable {
|
|
|
773
774
|
objectType<A, R2 = never>(config: {
|
|
774
775
|
name?: string;
|
|
775
776
|
schema: S.Schema<A, any, any>;
|
|
777
|
+
description?: string;
|
|
776
778
|
implements?: readonly string[];
|
|
777
779
|
directives?: readonly DirectiveApplication[];
|
|
778
780
|
/**
|
|
@@ -237,6 +237,7 @@ interface FieldRegistration<Args = any, A = any, E = any, R = any> {
|
|
|
237
237
|
interface TypeRegistration {
|
|
238
238
|
name: string;
|
|
239
239
|
schema: S.Schema<any, any, any>;
|
|
240
|
+
description?: string;
|
|
240
241
|
implements?: readonly string[];
|
|
241
242
|
directives?: readonly DirectiveApplication[];
|
|
242
243
|
/**
|
|
@@ -773,6 +774,7 @@ declare class GraphQLSchemaBuilder<R = never> implements Pipeable.Pipeable {
|
|
|
773
774
|
objectType<A, R2 = never>(config: {
|
|
774
775
|
name?: string;
|
|
775
776
|
schema: S.Schema<A, any, any>;
|
|
777
|
+
description?: string;
|
|
776
778
|
implements?: readonly string[];
|
|
777
779
|
directives?: readonly DirectiveApplication[];
|
|
778
780
|
/**
|
package/server/index.cjs
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
var effect = require('effect');
|
|
4
4
|
var platform = require('@effect/platform');
|
|
5
5
|
var graphql = require('graphql');
|
|
6
|
-
var graphqlWs = require('graphql-ws');
|
|
7
6
|
|
|
8
7
|
// src/server/config.ts
|
|
9
8
|
var defaultConfig = {
|
|
@@ -98,7 +97,7 @@ var GraphQLRouterConfigFromEnv = effect.Config.all({
|
|
|
98
97
|
);
|
|
99
98
|
|
|
100
99
|
// src/server/graphiql.ts
|
|
101
|
-
var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
|
|
100
|
+
var graphiqlHtml = (endpoint, subscriptionEndpoint) => `<!DOCTYPE html>
|
|
102
101
|
<html lang="en">
|
|
103
102
|
<head>
|
|
104
103
|
<meta charset="utf-8" />
|
|
@@ -126,6 +125,7 @@ var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
|
|
|
126
125
|
<script>
|
|
127
126
|
const fetcher = GraphiQL.createFetcher({
|
|
128
127
|
url: ${JSON.stringify(endpoint)},
|
|
128
|
+
subscriptionUrl: ${JSON.stringify(subscriptionEndpoint ?? endpoint)},
|
|
129
129
|
});
|
|
130
130
|
ReactDOM.createRoot(document.getElementById('graphiql')).render(
|
|
131
131
|
React.createElement(GraphiQL, { fetcher })
|
|
@@ -850,19 +850,32 @@ var defaultErrorHandler = (cause) => (process.env.NODE_ENV !== "production" ? ef
|
|
|
850
850
|
).pipe(effect.Effect.orDie)
|
|
851
851
|
)
|
|
852
852
|
);
|
|
853
|
-
var
|
|
853
|
+
var GraphQLRequestBodySchema = effect.Schema.Struct({
|
|
854
|
+
query: effect.Schema.String,
|
|
855
|
+
variables: effect.Schema.optionalWith(effect.Schema.Record({ key: effect.Schema.String, value: effect.Schema.Unknown }), {
|
|
856
|
+
as: "Option"
|
|
857
|
+
}),
|
|
858
|
+
operationName: effect.Schema.optionalWith(effect.Schema.String, { as: "Option" })
|
|
859
|
+
});
|
|
860
|
+
var decodeRequestBody = platform.HttpIncomingMessage.schemaBodyJson(GraphQLRequestBodySchema);
|
|
861
|
+
var parseGraphQLQuery = (query, extensionsService) => {
|
|
854
862
|
try {
|
|
855
863
|
const document = graphql.parse(query);
|
|
856
|
-
return { ok: true, document };
|
|
864
|
+
return effect.Effect.succeed({ ok: true, document });
|
|
857
865
|
} catch (parseError) {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
866
|
+
return extensionsService.get().pipe(
|
|
867
|
+
effect.Effect.flatMap(
|
|
868
|
+
(extensionData) => platform.HttpServerResponse.json({
|
|
869
|
+
errors: [{ message: String(parseError) }],
|
|
870
|
+
extensions: Object.keys(extensionData).length > 0 ? extensionData : void 0
|
|
871
|
+
}).pipe(
|
|
872
|
+
effect.Effect.orDie,
|
|
873
|
+
effect.Effect.map((response) => ({ ok: false, response }))
|
|
874
|
+
)
|
|
875
|
+
)
|
|
876
|
+
);
|
|
864
877
|
}
|
|
865
|
-
}
|
|
878
|
+
};
|
|
866
879
|
var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig) => {
|
|
867
880
|
if (!complexityConfig) {
|
|
868
881
|
return effect.Effect.void;
|
|
@@ -882,8 +895,9 @@ var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig
|
|
|
882
895
|
)
|
|
883
896
|
);
|
|
884
897
|
};
|
|
885
|
-
var
|
|
886
|
-
|
|
898
|
+
var isPromiseLike = (value) => value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
899
|
+
var executeGraphQLQuery = (schema, document, variables, operationName, runtime) => {
|
|
900
|
+
const tryExecute = effect.Effect.try({
|
|
887
901
|
try: () => graphql.execute({
|
|
888
902
|
schema,
|
|
889
903
|
document,
|
|
@@ -893,33 +907,34 @@ var executeGraphQLQuery = (schema, document, variables, operationName, runtime)
|
|
|
893
907
|
}),
|
|
894
908
|
catch: (error) => new Error(String(error))
|
|
895
909
|
});
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
()
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
})
|
|
903
|
-
|
|
910
|
+
return tryExecute.pipe(
|
|
911
|
+
effect.Effect.flatMap((executeResult) => {
|
|
912
|
+
if (isPromiseLike(executeResult)) {
|
|
913
|
+
return effect.Effect.promise(() => executeResult);
|
|
914
|
+
}
|
|
915
|
+
return effect.Effect.succeed(executeResult);
|
|
916
|
+
})
|
|
917
|
+
);
|
|
918
|
+
};
|
|
919
|
+
var computeCacheControlHeader = (document, operationName, schema, cacheHints, cacheControlConfig) => {
|
|
904
920
|
if (cacheControlConfig?.enabled === false || cacheControlConfig?.calculateHttpHeaders === false) {
|
|
905
|
-
return void 0;
|
|
921
|
+
return effect.Effect.succeed(void 0);
|
|
906
922
|
}
|
|
907
923
|
const operations = document.definitions.filter(
|
|
908
924
|
(d) => d.kind === graphql.Kind.OPERATION_DEFINITION
|
|
909
925
|
);
|
|
910
926
|
const operation = operationName ? operations.find((o) => o.name?.value === operationName) : operations[0];
|
|
911
927
|
if (!operation || operation.operation === "mutation") {
|
|
912
|
-
return void 0;
|
|
928
|
+
return effect.Effect.succeed(void 0);
|
|
913
929
|
}
|
|
914
|
-
|
|
930
|
+
return computeCachePolicy({
|
|
915
931
|
document,
|
|
916
932
|
operation,
|
|
917
933
|
schema,
|
|
918
934
|
cacheHints,
|
|
919
935
|
config: cacheControlConfig ?? {}
|
|
920
|
-
});
|
|
921
|
-
|
|
922
|
-
});
|
|
936
|
+
}).pipe(effect.Effect.map(toCacheControlHeader));
|
|
937
|
+
};
|
|
923
938
|
var buildGraphQLResponse = (result, extensionData, cacheControlHeader) => {
|
|
924
939
|
const finalResult = Object.keys(extensionData).length > 0 ? {
|
|
925
940
|
...result,
|
|
@@ -957,7 +972,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
957
972
|
const extensionsService = yield* makeExtensionsService();
|
|
958
973
|
const runtime = yield* effect.Effect.runtime();
|
|
959
974
|
const request = yield* platform.HttpServerRequest.HttpServerRequest;
|
|
960
|
-
const
|
|
975
|
+
const parsedBody = yield* decodeRequestBody(request);
|
|
976
|
+
const body = {
|
|
977
|
+
query: parsedBody.query,
|
|
978
|
+
variables: parsedBody.variables._tag === "Some" ? parsedBody.variables.value : void 0,
|
|
979
|
+
operationName: parsedBody.operationName._tag === "Some" ? parsedBody.operationName.value : void 0
|
|
980
|
+
};
|
|
961
981
|
const parseResult = yield* parseGraphQLQuery(body.query, extensionsService);
|
|
962
982
|
if (!parseResult.ok) {
|
|
963
983
|
return parseResult.response;
|
|
@@ -966,7 +986,7 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
966
986
|
yield* runParseHooks(extensions, body.query, document).pipe(
|
|
967
987
|
effect.Effect.provideService(ExtensionsService, extensionsService)
|
|
968
988
|
);
|
|
969
|
-
const validationRules = resolvedConfig.introspection ? void 0 :
|
|
989
|
+
const validationRules = resolvedConfig.introspection ? void 0 : graphql.specifiedRules.concat(graphql.NoSchemaIntrospectionCustomRule);
|
|
970
990
|
const validationErrors = graphql.validate(schema, document, validationRules);
|
|
971
991
|
yield* runValidateHooks(extensions, document, validationErrors).pipe(
|
|
972
992
|
effect.Effect.provideService(ExtensionsService, extensionsService)
|
|
@@ -1027,9 +1047,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
|
|
|
1027
1047
|
platform.HttpRouter.post(resolvedConfig.path, graphqlHandler)
|
|
1028
1048
|
);
|
|
1029
1049
|
if (resolvedConfig.graphiql) {
|
|
1030
|
-
const { path, endpoint } = resolvedConfig.graphiql;
|
|
1050
|
+
const { path, endpoint, subscriptionEndpoint } = resolvedConfig.graphiql;
|
|
1031
1051
|
router = router.pipe(
|
|
1032
|
-
platform.HttpRouter.get(
|
|
1052
|
+
platform.HttpRouter.get(
|
|
1053
|
+
path,
|
|
1054
|
+
platform.HttpServerResponse.html(graphiqlHtml(endpoint, subscriptionEndpoint))
|
|
1055
|
+
)
|
|
1033
1056
|
);
|
|
1034
1057
|
}
|
|
1035
1058
|
return router;
|
|
@@ -1204,27 +1227,45 @@ var runConnectionLifecycle = (socket, wsServer, extra) => effect.Effect.gen(func
|
|
|
1204
1227
|
effect.Effect.catchAllCause(() => effect.Effect.void),
|
|
1205
1228
|
effect.Effect.scoped
|
|
1206
1229
|
);
|
|
1230
|
+
var importGraphqlWs = effect.Effect.tryPromise({
|
|
1231
|
+
try: () => import('graphql-ws'),
|
|
1232
|
+
catch: () => new Error(
|
|
1233
|
+
"graphql-ws is required for WebSocket subscriptions. Install it with: npm install graphql-ws"
|
|
1234
|
+
)
|
|
1235
|
+
});
|
|
1207
1236
|
var makeGraphQLWSHandler = (schema, layer, options) => {
|
|
1208
1237
|
const complexityConfig = options?.complexity;
|
|
1209
1238
|
const fieldComplexities = options?.fieldComplexities ?? /* @__PURE__ */ new Map();
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1239
|
+
let wsServerPromise = null;
|
|
1240
|
+
const getOrCreateServer = async () => {
|
|
1241
|
+
if (!wsServerPromise) {
|
|
1242
|
+
wsServerPromise = effect.Effect.runPromise(importGraphqlWs).then(({ makeServer }) => {
|
|
1243
|
+
const serverOptions = {
|
|
1244
|
+
schema,
|
|
1245
|
+
context: async (ctx) => {
|
|
1246
|
+
const extra = ctx.extra;
|
|
1247
|
+
return {
|
|
1248
|
+
runtime: extra.runtime,
|
|
1249
|
+
...extra.connectionParams
|
|
1250
|
+
};
|
|
1251
|
+
},
|
|
1252
|
+
subscribe: async (args) => graphql.subscribe(args),
|
|
1253
|
+
onConnect: makeOnConnectHandler(options),
|
|
1254
|
+
onDisconnect: makeOnDisconnectHandler(options),
|
|
1255
|
+
onSubscribe: makeOnSubscribeHandler(options, schema, complexityConfig, fieldComplexities),
|
|
1256
|
+
onComplete: makeOnCompleteHandler(options),
|
|
1257
|
+
onError: makeOnErrorHandler(options)
|
|
1258
|
+
};
|
|
1259
|
+
return makeServer(serverOptions);
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
return wsServerPromise;
|
|
1225
1263
|
};
|
|
1226
|
-
const wsServer = graphqlWs.makeServer(serverOptions);
|
|
1227
1264
|
return (socket) => effect.Effect.gen(function* () {
|
|
1265
|
+
const wsServer = yield* effect.Effect.tryPromise({
|
|
1266
|
+
try: () => getOrCreateServer(),
|
|
1267
|
+
catch: (error) => error
|
|
1268
|
+
});
|
|
1228
1269
|
const runtime = yield* effect.Effect.provide(effect.Effect.runtime(), layer);
|
|
1229
1270
|
const extra = {
|
|
1230
1271
|
socket,
|