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