@cedarjs/api-server 6.0.0-rc.221 → 6.0.0-rc.260

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/dist/bin.js CHANGED
@@ -88,7 +88,9 @@ function resolveOptions(options = {}, args) {
88
88
  bodyLimit: defaults.fastifyServerOptions.bodyLimit
89
89
  },
90
90
  discoverFunctionsGlob: options.discoverFunctionsGlob ?? defaults.discoverFunctionsGlob,
91
+ configureServer: options.configureServer ?? defaults.configureServer,
91
92
  configureApiServer: options.configureApiServer ?? defaults.configureApiServer,
93
+ configureGraphQLServer: options.configureGraphQLServer ?? defaults.configureGraphQLServer,
92
94
  apiHost: options.apiHost ?? defaults.apiHost,
93
95
  apiPort: options.apiPort ?? defaults.apiPort
94
96
  };
@@ -153,8 +155,12 @@ var init_createServerHelpers = __esm({
153
155
  // 100MB
154
156
  },
155
157
  discoverFunctionsGlob: "dist/functions/**/*.{ts,js}",
158
+ configureServer: () => {
159
+ },
156
160
  configureApiServer: () => {
157
161
  },
162
+ configureGraphQLServer: () => {
163
+ },
158
164
  parseArgs: true,
159
165
  // `createServer()`'s only callers are `cedarjs-server api` and custom
160
166
  // `api/src/server.ts` files — both only ever run with the api side
@@ -573,7 +579,8 @@ var init_api = __esm({
573
579
  // src/plugins/graphql.ts
574
580
  var graphql_exports = {};
575
581
  __export(graphql_exports, {
576
- cedarFastifyGraphQLServer: () => cedarFastifyGraphQLServer
582
+ cedarFastifyGraphQLServer: () => cedarFastifyGraphQLServer,
583
+ isClientDisconnectError: () => isClientDisconnectError
577
584
  });
578
585
  import { pathToFileURL as pathToFileURL3 } from "node:url";
579
586
  import fastifyMultiPart from "@fastify/multipart";
@@ -594,6 +601,9 @@ async function cedarFastifyGraphQLServer(fastify2, options) {
594
601
  fastify2.addHook("onRequest", (_req, _reply, done) => {
595
602
  getAsyncStoreInstance3().run(/* @__PURE__ */ new Map(), done);
596
603
  });
604
+ if (cedarOptions.configureServer) {
605
+ await cedarOptions.configureServer(fastify2);
606
+ }
597
607
  try {
598
608
  if (!cedarOptions.graphql) {
599
609
  const [graphqlFunctionPath] = await fg2("dist/functions/graphql.{ts,js}", {
@@ -631,7 +641,7 @@ async function cedarFastifyGraphQLServer(fastify2, options) {
631
641
  requestContext: void 0
632
642
  });
633
643
  } catch (e) {
634
- if (!!e && typeof e === "object" && "code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
644
+ if (isClientDisconnectError(e)) {
635
645
  return new Response(null, { status: 499 });
636
646
  }
637
647
  throw e;
@@ -658,6 +668,18 @@ async function cedarFastifyGraphQLServer(fastify2, options) {
658
668
  function trimSlashes(path6) {
659
669
  return path6.replace(/^\/|\/$/g, "");
660
670
  }
671
+ function isClientDisconnectError(e) {
672
+ if (!e || typeof e !== "object") {
673
+ return false;
674
+ }
675
+ if ("code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
676
+ return true;
677
+ }
678
+ if (e instanceof DOMException && e.name === "AbortError") {
679
+ return true;
680
+ }
681
+ return false;
682
+ }
661
683
  function createFetchRequest(req, reply) {
662
684
  const controller = new AbortController();
663
685
  reply.raw.on("close", () => {
@@ -696,7 +718,9 @@ async function createServer(options = {}) {
696
718
  apiRootPath,
697
719
  fastifyServerOptions,
698
720
  discoverFunctionsGlob,
721
+ configureServer,
699
722
  configureApiServer,
723
+ configureGraphQLServer,
700
724
  apiPort,
701
725
  apiHost
702
726
  } = resolveOptions(options);
@@ -735,6 +759,9 @@ async function createServer(options = {}) {
735
759
  server.addHook("onRequest", (_req, _reply, done) => {
736
760
  getAsyncStoreInstance4().run(/* @__PURE__ */ new Map(), done);
737
761
  });
762
+ if (configureServer) {
763
+ await configureServer(server);
764
+ }
738
765
  await server.register(cedarFastifyAPI, {
739
766
  cedar: {
740
767
  apiRootPath,
@@ -755,7 +782,8 @@ async function createServer(options = {}) {
755
782
  await server.register(cedarFastifyGraphQLServer2, {
756
783
  cedar: {
757
784
  apiRootPath,
758
- graphql: __cedar_graphqlOptions
785
+ graphql: __cedar_graphqlOptions,
786
+ configureServer: configureGraphQLServer
759
787
  }
760
788
  });
761
789
  }
@@ -11,13 +11,29 @@ import type { CreateServerOptions, Server } from './createServerHelpers.js';
11
11
  * const server = await createServer({
12
12
  * logger,
13
13
  * apiRootPath: 'api'
14
+ * configureServer: (server) => {
15
+ * // Runs before the api functions and GraphQL plugins are
16
+ * // registered, i.e. before any routes exist. This is the right
17
+ * // place for plugins with a "global" mode that hooks `onRoute`
18
+ * // (e.g. `@fastify/compress`), since those only affect routes
19
+ * // registered *after* the plugin itself — registering them here
20
+ * // applies them to *both* api functions and the GraphQL endpoint:
21
+ * server.register(compress, { global: true })
22
+ * },
14
23
  * configureApiServer: (server) => {
15
- * // Configure the API server fastify instance, e.g. add content type parsers
24
+ * // Configure just the api functions' fastify instance, e.g. add
25
+ * // content type parsers. Doesn't apply to the GraphQL endpoint.
26
+ * },
27
+ * configureGraphQLServer: (server) => {
28
+ * // Configure just the GraphQL fastify instance. Doesn't apply to
29
+ * // api function routes.
16
30
  * },
17
31
  * })
18
32
  *
19
- * // Configure the returned fastify instance:
20
- * server.register(myPlugin)
33
+ * // Plain request-lifecycle hooks (onRequest, onSend, etc.) don't depend
34
+ * // on registration order, so they can also be added to the returned
35
+ * // instance after the fact and will still apply to both:
36
+ * server.addHook('onRequest', myHook)
21
37
  *
22
38
  * // When ready, start the server:
23
39
  * await server.start()
@@ -1 +1 @@
1
- {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../src/createServer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEP,MAAM,0BAA0B,CAAA;AAsBjC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,mBAqHnE"}
1
+ {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../src/createServer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEP,MAAM,0BAA0B,CAAA;AAsBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,mBA4InE"}
@@ -22,7 +22,9 @@ async function createServer(options = {}) {
22
22
  apiRootPath,
23
23
  fastifyServerOptions,
24
24
  discoverFunctionsGlob,
25
+ configureServer,
25
26
  configureApiServer,
27
+ configureGraphQLServer,
26
28
  apiPort,
27
29
  apiHost
28
30
  } = resolveOptions(options);
@@ -61,6 +63,9 @@ async function createServer(options = {}) {
61
63
  server.addHook("onRequest", (_req, _reply, done) => {
62
64
  getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), done);
63
65
  });
66
+ if (configureServer) {
67
+ await configureServer(server);
68
+ }
64
69
  await server.register(cedarFastifyAPI, {
65
70
  cedar: {
66
71
  apiRootPath,
@@ -81,7 +86,8 @@ async function createServer(options = {}) {
81
86
  await server.register(cedarFastifyGraphQLServer, {
82
87
  cedar: {
83
88
  apiRootPath,
84
- graphql: __cedar_graphqlOptions
89
+ graphql: __cedar_graphqlOptions,
90
+ configureServer: configureGraphQLServer
85
91
  }
86
92
  });
87
93
  }
@@ -18,8 +18,21 @@ export interface CreateServerOptions {
18
18
  * Defaults to: "dist/functions/**\/*.{ts,js}"
19
19
  */
20
20
  discoverFunctionsGlob?: string | string[];
21
- /** Customise the API server fastify plugin before it is registered */
22
- configureApiServer?: (server: Server) => void | Promise<void>;
21
+ /**
22
+ * Configure the root fastify instance *before* the api functions and
23
+ * GraphQL plugins are registered. Use this to register Fastify plugins
24
+ * that need to run before any routes exist — most notably plugins with a
25
+ * "global" mode that works by hooking `onRoute` (e.g. `@fastify/compress`),
26
+ * which only affects routes registered *after* the plugin itself. Simple
27
+ * request-lifecycle hooks (`onRequest`, `onSend`, etc.) don't have this
28
+ * restriction and can also be added to the returned server after
29
+ * `createServer()` resolves.
30
+ */
31
+ configureServer?: (server: FastifyInstance) => void | Promise<void>;
32
+ /** Customise the API functions fastify plugin before it is registered */
33
+ configureApiServer?: (server: FastifyInstance) => void | Promise<void>;
34
+ /** Customise the GraphQL fastify plugin before it is registered */
35
+ configureGraphQLServer?: (server: FastifyInstance) => void | Promise<void>;
23
36
  /** Whether to parse args or not. Defaults to `true` */
24
37
  parseArgs?: boolean;
25
38
  /** The port to listen on. Defaults to what's configured in cedar.toml */
@@ -1 +1 @@
1
- {"version":3,"file":"createServerHelpers.d.ts","sourceRoot":"","sources":["../src/createServerHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AAEtE,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,iCAAiC;IACjC,MAAM,CAAC,EACH,oBAAoB,CAAC,QAAQ,CAAC,GAC9B,oBAAoB,CAAC,gBAAgB,CAAC,CAAA;IAE1C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAA;IAE3D;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAEzC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE7D,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,0BAA0B,GAAG,QAAQ,CACxC,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG;IAClD,oBAAoB,EAAE,oBAAoB,CAAA;CAC3C,CACF,CAAA;AAID,eAAO,MAAM,6BAA6B,EAAE,MAAM,0BAqB9C,CAAA;AAgBJ,wBAAgB,cAAc,CAC5B,OAAO,GAAE,mBAAwB,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE;0BAdS,oBAAoB;GA4F7C"}
1
+ {"version":3,"file":"createServerHelpers.d.ts","sourceRoot":"","sources":["../src/createServerHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AAEtE,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,iCAAiC;IACjC,MAAM,CAAC,EACH,oBAAoB,CAAC,QAAQ,CAAC,GAC9B,oBAAoB,CAAC,gBAAgB,CAAC,CAAA;IAE1C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAA;IAE3D;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAEzC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnE,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtE,mEAAmE;IACnE,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1E,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,0BAA0B,GAAG,QAAQ,CACxC,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG;IAClD,oBAAoB,EAAE,oBAAoB,CAAA;CAC3C,CACF,CAAA;AAID,eAAO,MAAM,6BAA6B,EAAE,MAAM,0BAuB9C,CAAA;AAgBJ,wBAAgB,cAAc,CAC5B,OAAO,GAAE,mBAAwB,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE;0BAdS,oBAAoB;GA+F7C"}
@@ -12,8 +12,12 @@ const getDefaultCreateServerOptions = () => ({
12
12
  // 100MB
13
13
  },
14
14
  discoverFunctionsGlob: "dist/functions/**/*.{ts,js}",
15
+ configureServer: () => {
16
+ },
15
17
  configureApiServer: () => {
16
18
  },
19
+ configureGraphQLServer: () => {
20
+ },
17
21
  parseArgs: true,
18
22
  // `createServer()`'s only callers are `cedarjs-server api` and custom
19
23
  // `api/src/server.ts` files — both only ever run with the api side
@@ -36,7 +40,9 @@ function resolveOptions(options = {}, args) {
36
40
  bodyLimit: defaults.fastifyServerOptions.bodyLimit
37
41
  },
38
42
  discoverFunctionsGlob: options.discoverFunctionsGlob ?? defaults.discoverFunctionsGlob,
43
+ configureServer: options.configureServer ?? defaults.configureServer,
39
44
  configureApiServer: options.configureApiServer ?? defaults.configureApiServer,
45
+ configureGraphQLServer: options.configureGraphQLServer ?? defaults.configureGraphQLServer,
40
46
  apiHost: options.apiHost ?? defaults.apiHost,
41
47
  apiPort: options.apiPort ?? defaults.apiPort
42
48
  };
@@ -1,13 +1,12 @@
1
1
  import type { Options as FastGlobOptions } from 'fast-glob';
2
2
  import type { FastifyInstance } from 'fastify';
3
- import type { Server } from '../createServerHelpers.js';
4
3
  export interface CedarFastifyAPIOptions {
5
4
  cedar: {
6
5
  apiRootPath?: string;
7
6
  fastGlobOptions?: FastGlobOptions;
8
7
  discoverFunctionsGlob?: string | string[];
9
8
  loadUserConfig?: boolean;
10
- configureServer?: (server: Server) => void | Promise<void>;
9
+ configureServer?: (server: FastifyInstance) => void | Promise<void>;
11
10
  };
12
11
  }
13
12
  export declare function cedarFastifyAPI(fastify: FastifyInstance, opts: CedarFastifyAPIOptions): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/plugins/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAO9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAKvD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QACzC,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAI3D,CAAA;CACF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,sBAAsB,iBA4C7B"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/plugins/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAW9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QACzC,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAIpE,CAAA;CACF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,sBAAsB,iBAgD7B"}
@@ -4,7 +4,24 @@ export interface CedarFastifyGraphQLOptions {
4
4
  cedar: {
5
5
  apiRootPath?: string;
6
6
  graphql?: GraphQLYogaOptions;
7
+ configureServer?: (server: FastifyInstance) => void | Promise<void>;
7
8
  };
8
9
  }
9
10
  export declare function cedarFastifyGraphQLServer(fastify: FastifyInstance, options: CedarFastifyGraphQLOptions): Promise<void>;
11
+ /**
12
+ * Detects errors that indicate the client disconnected before the response
13
+ * finished, rather than a genuine server-side failure.
14
+ *
15
+ * `ERR_STREAM_PREMATURE_CLOSE` can surface from the underlying Node stream
16
+ * closing early. The `DOMException` named `AbortError` is thrown by Yoga
17
+ * when the AbortSignal wired up in `createFetchRequest`'s
18
+ * `reply.raw.on('close', ...)` handler is aborted, which only happens when
19
+ * the client itself has gone away.
20
+ *
21
+ * The `DOMException` check (rather than just `name === 'AbortError'`) is
22
+ * deliberate: a resolver or hook could throw a plain `Error` renamed to
23
+ * `AbortError`, which would otherwise be misclassified as a benign
24
+ * disconnect and hide a real server-side failure behind a 499.
25
+ */
26
+ export declare function isClientDisconnectError(e: unknown): boolean;
10
27
  //# sourceMappingURL=graphql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../src/plugins/graphql.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,SAAS,CAAA;AAOhB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAC7B,CAAA;CACF;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,0BAA0B,iBA+HpC"}
1
+ {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../src/plugins/graphql.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,SAAS,CAAA;AAOhB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,kBAAkB,CAAA;QAC5B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KACpE,CAAA;CACF;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,0BAA0B,iBAmIpC;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAc3D"}
@@ -18,6 +18,9 @@ async function cedarFastifyGraphQLServer(fastify, options) {
18
18
  fastify.addHook("onRequest", (_req, _reply, done) => {
19
19
  getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), done);
20
20
  });
21
+ if (cedarOptions.configureServer) {
22
+ await cedarOptions.configureServer(fastify);
23
+ }
21
24
  try {
22
25
  if (!cedarOptions.graphql) {
23
26
  const [graphqlFunctionPath] = await fg("dist/functions/graphql.{ts,js}", {
@@ -55,7 +58,7 @@ async function cedarFastifyGraphQLServer(fastify, options) {
55
58
  requestContext: void 0
56
59
  });
57
60
  } catch (e) {
58
- if (!!e && typeof e === "object" && "code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
61
+ if (isClientDisconnectError(e)) {
59
62
  return new Response(null, { status: 499 });
60
63
  }
61
64
  throw e;
@@ -82,6 +85,18 @@ async function cedarFastifyGraphQLServer(fastify, options) {
82
85
  function trimSlashes(path) {
83
86
  return path.replace(/^\/|\/$/g, "");
84
87
  }
88
+ function isClientDisconnectError(e) {
89
+ if (!e || typeof e !== "object") {
90
+ return false;
91
+ }
92
+ if ("code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
93
+ return true;
94
+ }
95
+ if (e instanceof DOMException && e.name === "AbortError") {
96
+ return true;
97
+ }
98
+ return false;
99
+ }
85
100
  function createFetchRequest(req, reply) {
86
101
  const controller = new AbortController();
87
102
  reply.raw.on("close", () => {
@@ -99,5 +114,6 @@ function createFetchRequest(req, reply) {
99
114
  });
100
115
  }
101
116
  export {
102
- cedarFastifyGraphQLServer
117
+ cedarFastifyGraphQLServer,
118
+ isClientDisconnectError
103
119
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/api-server",
3
- "version": "6.0.0-rc.221",
3
+ "version": "6.0.0-rc.260",
4
4
  "description": "CedarJS's HTTP server for Serverless Functions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -92,13 +92,13 @@
92
92
  "test:watch": "vitest watch"
93
93
  },
94
94
  "dependencies": {
95
- "@cedarjs/api": "6.0.0-rc.221",
96
- "@cedarjs/context": "6.0.0-rc.221",
97
- "@cedarjs/fastify-web": "6.0.0-rc.221",
98
- "@cedarjs/project-config": "6.0.0-rc.221",
99
- "@cedarjs/web-server": "6.0.0-rc.221",
95
+ "@cedarjs/api": "6.0.0-rc.260",
96
+ "@cedarjs/context": "6.0.0-rc.260",
97
+ "@cedarjs/fastify-web": "6.0.0-rc.260",
98
+ "@cedarjs/project-config": "6.0.0-rc.260",
99
+ "@cedarjs/web-server": "6.0.0-rc.260",
100
100
  "@fastify/multipart": "9.4.0",
101
- "@fastify/url-data": "6.0.3",
101
+ "@fastify/url-data": "6.0.4",
102
102
  "ansis": "4.3.1",
103
103
  "dotenv-defaults": "5.0.2",
104
104
  "fast-glob": "3.3.3",
@@ -113,22 +113,23 @@
113
113
  "yargs": "17.7.3"
114
114
  },
115
115
  "devDependencies": {
116
- "@cedarjs/framework-tools": "6.0.0-rc.221",
116
+ "@cedarjs/framework-tools": "6.0.0-rc.260",
117
+ "@fastify/compress": "9.1.1",
117
118
  "@types/aws-lambda": "8.10.162",
118
119
  "@types/dotenv-defaults": "^5.0.0",
119
120
  "@types/split2": "4.2.3",
120
121
  "@types/yargs": "17.0.35",
121
122
  "concurrently": "9.2.4",
122
- "esbuild": "0.28.1",
123
+ "esbuild": "0.28.2",
123
124
  "memfs": "4.64.0",
124
125
  "pino": "9.7.0",
125
126
  "pino-abstract-transport": "1.2.0",
126
- "publint": "0.3.22",
127
+ "publint": "0.3.23",
127
128
  "typescript": "5.9.3",
128
129
  "vitest": "4.1.10"
129
130
  },
130
131
  "peerDependencies": {
131
- "@cedarjs/graphql-server": "6.0.0-rc.221"
132
+ "@cedarjs/graphql-server": "6.0.0-rc.260"
132
133
  },
133
134
  "peerDependenciesMeta": {
134
135
  "@cedarjs/graphql-server": {