@effect-gql/core 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-gql/core",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Core GraphQL framework for Effect-TS - schema building, type mapping, and execution",
5
5
  "repository": {
6
6
  "url": "https://github.com/nrf110/effect-gql"
@@ -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
@@ -98,7 +98,7 @@ var GraphQLRouterConfigFromEnv = effect.Config.all({
98
98
  );
99
99
 
100
100
  // src/server/graphiql.ts
101
- var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
101
+ var graphiqlHtml = (endpoint, subscriptionEndpoint) => `<!DOCTYPE html>
102
102
  <html lang="en">
103
103
  <head>
104
104
  <meta charset="utf-8" />
@@ -126,6 +126,7 @@ var graphiqlHtml = (endpoint) => `<!DOCTYPE html>
126
126
  <script>
127
127
  const fetcher = GraphiQL.createFetcher({
128
128
  url: ${JSON.stringify(endpoint)},
129
+ subscriptionUrl: ${JSON.stringify(subscriptionEndpoint ?? endpoint)},
129
130
  });
130
131
  ReactDOM.createRoot(document.getElementById('graphiql')).render(
131
132
  React.createElement(GraphiQL, { fetcher })
@@ -850,19 +851,32 @@ var defaultErrorHandler = (cause) => (process.env.NODE_ENV !== "production" ? ef
850
851
  ).pipe(effect.Effect.orDie)
851
852
  )
852
853
  );
853
- var parseGraphQLQuery = (query, extensionsService) => effect.Effect.gen(function* () {
854
+ var GraphQLRequestBodySchema = effect.Schema.Struct({
855
+ query: effect.Schema.String,
856
+ variables: effect.Schema.optionalWith(effect.Schema.Record({ key: effect.Schema.String, value: effect.Schema.Unknown }), {
857
+ as: "Option"
858
+ }),
859
+ operationName: effect.Schema.optionalWith(effect.Schema.String, { as: "Option" })
860
+ });
861
+ var decodeRequestBody = platform.HttpIncomingMessage.schemaBodyJson(GraphQLRequestBodySchema);
862
+ var parseGraphQLQuery = (query, extensionsService) => {
854
863
  try {
855
864
  const document = graphql.parse(query);
856
- return { ok: true, document };
865
+ return effect.Effect.succeed({ ok: true, document });
857
866
  } catch (parseError) {
858
- const extensionData = yield* extensionsService.get();
859
- const response = yield* platform.HttpServerResponse.json({
860
- errors: [{ message: String(parseError) }],
861
- extensions: Object.keys(extensionData).length > 0 ? extensionData : void 0
862
- }).pipe(effect.Effect.orDie);
863
- return { ok: false, response };
867
+ return extensionsService.get().pipe(
868
+ effect.Effect.flatMap(
869
+ (extensionData) => platform.HttpServerResponse.json({
870
+ errors: [{ message: String(parseError) }],
871
+ extensions: Object.keys(extensionData).length > 0 ? extensionData : void 0
872
+ }).pipe(
873
+ effect.Effect.orDie,
874
+ effect.Effect.map((response) => ({ ok: false, response }))
875
+ )
876
+ )
877
+ );
864
878
  }
865
- });
879
+ };
866
880
  var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig) => {
867
881
  if (!complexityConfig) {
868
882
  return effect.Effect.void;
@@ -882,8 +896,9 @@ var runComplexityValidation = (body, schema, fieldComplexities, complexityConfig
882
896
  )
883
897
  );
884
898
  };
885
- var executeGraphQLQuery = (schema, document, variables, operationName, runtime) => effect.Effect.gen(function* () {
886
- const executeResult = yield* effect.Effect.try({
899
+ var isPromiseLike = (value) => value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
900
+ var executeGraphQLQuery = (schema, document, variables, operationName, runtime) => {
901
+ const tryExecute = effect.Effect.try({
887
902
  try: () => graphql.execute({
888
903
  schema,
889
904
  document,
@@ -893,33 +908,34 @@ var executeGraphQLQuery = (schema, document, variables, operationName, runtime)
893
908
  }),
894
909
  catch: (error) => new Error(String(error))
895
910
  });
896
- if (executeResult && typeof executeResult === "object" && "then" in executeResult) {
897
- return yield* effect.Effect.promise(
898
- () => executeResult
899
- );
900
- }
901
- return executeResult;
902
- });
903
- var computeCacheControlHeader = (document, operationName, schema, cacheHints, cacheControlConfig) => effect.Effect.gen(function* () {
911
+ return tryExecute.pipe(
912
+ effect.Effect.flatMap((executeResult) => {
913
+ if (isPromiseLike(executeResult)) {
914
+ return effect.Effect.promise(() => executeResult);
915
+ }
916
+ return effect.Effect.succeed(executeResult);
917
+ })
918
+ );
919
+ };
920
+ var computeCacheControlHeader = (document, operationName, schema, cacheHints, cacheControlConfig) => {
904
921
  if (cacheControlConfig?.enabled === false || cacheControlConfig?.calculateHttpHeaders === false) {
905
- return void 0;
922
+ return effect.Effect.succeed(void 0);
906
923
  }
907
924
  const operations = document.definitions.filter(
908
925
  (d) => d.kind === graphql.Kind.OPERATION_DEFINITION
909
926
  );
910
927
  const operation = operationName ? operations.find((o) => o.name?.value === operationName) : operations[0];
911
928
  if (!operation || operation.operation === "mutation") {
912
- return void 0;
929
+ return effect.Effect.succeed(void 0);
913
930
  }
914
- const cachePolicy = yield* computeCachePolicy({
931
+ return computeCachePolicy({
915
932
  document,
916
933
  operation,
917
934
  schema,
918
935
  cacheHints,
919
936
  config: cacheControlConfig ?? {}
920
- });
921
- return toCacheControlHeader(cachePolicy);
922
- });
937
+ }).pipe(effect.Effect.map(toCacheControlHeader));
938
+ };
923
939
  var buildGraphQLResponse = (result, extensionData, cacheControlHeader) => {
924
940
  const finalResult = Object.keys(extensionData).length > 0 ? {
925
941
  ...result,
@@ -957,7 +973,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
957
973
  const extensionsService = yield* makeExtensionsService();
958
974
  const runtime = yield* effect.Effect.runtime();
959
975
  const request = yield* platform.HttpServerRequest.HttpServerRequest;
960
- const body = yield* request.json;
976
+ const parsedBody = yield* decodeRequestBody(request);
977
+ const body = {
978
+ query: parsedBody.query,
979
+ variables: parsedBody.variables._tag === "Some" ? parsedBody.variables.value : void 0,
980
+ operationName: parsedBody.operationName._tag === "Some" ? parsedBody.operationName.value : void 0
981
+ };
961
982
  const parseResult = yield* parseGraphQLQuery(body.query, extensionsService);
962
983
  if (!parseResult.ok) {
963
984
  return parseResult.response;
@@ -966,7 +987,7 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
966
987
  yield* runParseHooks(extensions, body.query, document).pipe(
967
988
  effect.Effect.provideService(ExtensionsService, extensionsService)
968
989
  );
969
- const validationRules = resolvedConfig.introspection ? void 0 : [...graphql.specifiedRules, graphql.NoSchemaIntrospectionCustomRule];
990
+ const validationRules = resolvedConfig.introspection ? void 0 : graphql.specifiedRules.concat(graphql.NoSchemaIntrospectionCustomRule);
970
991
  const validationErrors = graphql.validate(schema, document, validationRules);
971
992
  yield* runValidateHooks(extensions, document, validationErrors).pipe(
972
993
  effect.Effect.provideService(ExtensionsService, extensionsService)
@@ -1027,9 +1048,12 @@ var makeGraphQLRouter = (schema, layer, options = {}) => {
1027
1048
  platform.HttpRouter.post(resolvedConfig.path, graphqlHandler)
1028
1049
  );
1029
1050
  if (resolvedConfig.graphiql) {
1030
- const { path, endpoint } = resolvedConfig.graphiql;
1051
+ const { path, endpoint, subscriptionEndpoint } = resolvedConfig.graphiql;
1031
1052
  router = router.pipe(
1032
- platform.HttpRouter.get(path, platform.HttpServerResponse.html(graphiqlHtml(endpoint)))
1053
+ platform.HttpRouter.get(
1054
+ path,
1055
+ platform.HttpServerResponse.html(graphiqlHtml(endpoint, subscriptionEndpoint))
1056
+ )
1033
1057
  );
1034
1058
  }
1035
1059
  return router;