@vercel/node#VercelApiHandler TypeScript Examples

The following examples show how to use @vercel/node#VercelApiHandler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: vercelApollo.ts    From apollo-server-vercel with MIT License 6 votes vote down vote up
export function graphqlVercel(options: GraphQLOptions | VercelGraphQLOptionsFunction): VercelApiHandler {
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  if (!options) throw new Error(`Apollo Server requires options.`);

  if (arguments.length > 1) {
    throw new Error(`Apollo Server expects exactly one argument, got ${arguments.length}`);
  }

  const graphqlHandler: VercelApiHandler = async (req, res) => {
    if (req.method === `POST` && !req.body) {
      res.status(500).send(`POST body missing.`);
      return;
    }

    try {
      const { graphqlResponse, responseInit } = await runHttpQuery([req, res], {
        method: req.method!,
        options,
        query: req.method === `POST` ? req.body : req.query,
        request: convertNodeHttpToRequest(req)
      });
      setHeaders(res, responseInit.headers ?? {});
      res.status(200).send(graphqlResponse);
    } catch (error: unknown) {
      const { headers, statusCode, message } = error as HttpQueryError;
      setHeaders(res, headers ?? {});
      res.status(statusCode).send(message);
    }
  };

  return graphqlHandler;
}
Example #2
Source File: wrapExpressHandler.ts    From octane with Apache License 2.0 6 votes vote down vote up
wrapExpressHandler = function (handler: RequestHandler): VercelApiHandler {
    return function (request: VercelRequest, response: VercelResponse): Promise<void> {
        return new Promise<void>(function (resolve, reject) {
            handler(request as any, response as any, function (error?: any) {
                if (error) {
                    reject(error);
                } else {
                    resolve();
                }
            });
        });
    };
}
Example #3
Source File: micro.ts    From mayoor with MIT License 5 votes vote down vote up
apolloServerHandler: VercelApiHandler
Example #4
Source File: ApolloServer.ts    From apollo-server-vercel with MIT License 4 votes vote down vote up
public createHandler({ cors, onHealthCheck }: CreateHandlerOptions = {}): VercelApiHandler {
    const corsHeaders = new Map();

    if (cors) {
      if (cors.methods) {
        if (typeof cors.methods === `string`) {
          corsHeaders.set(`access-control-allow-methods`, cors.methods);
        } else if (Array.isArray(cors.methods)) {
          corsHeaders.set(`access-control-allow-methods`, cors.methods.join(`,`));
        }
      }

      if (cors.allowedHeaders) {
        if (typeof cors.allowedHeaders === `string`) {
          corsHeaders.set(`access-control-allow-headers`, cors.allowedHeaders);
        } else if (Array.isArray(cors.allowedHeaders)) {
          corsHeaders.set(`access-control-allow-headers`, cors.allowedHeaders.join(`,`));
        }
      }

      if (cors.exposedHeaders) {
        if (typeof cors.exposedHeaders === `string`) {
          corsHeaders.set(`access-control-expose-headers`, cors.exposedHeaders);
        } else if (Array.isArray(cors.exposedHeaders)) {
          corsHeaders.set(`access-control-expose-headers`, cors.exposedHeaders.join(`,`));
        }
      }

      if (cors.credentials) {
        corsHeaders.set(`access-control-allow-credentials`, `true`);
      }
      if (typeof cors.maxAge === `number`) {
        corsHeaders.set(`access-control-max-age`, cors.maxAge.toString());
      }
    }

    return async (req: VercelRequest, res: VercelResponse): Promise<void> => {
      const willStart = this.willStart();
      const requestCorsHeaders = new Map(corsHeaders);

      if (cors?.origin) {
        const requestOrigin = req.headers.origin;
        if (typeof cors.origin === `string`) {
          requestCorsHeaders.set(`access-control-allow-origin`, cors.origin);
        } else if (
          requestOrigin &&
          (typeof cors.origin === `boolean` ||
            (Array.isArray(cors.origin) && requestOrigin && cors.origin.includes(requestOrigin)))
        ) {
          requestCorsHeaders.set(`access-control-allow-origin`, requestOrigin);
        }

        const requestAccessControlRequestHeaders = req.headers[`access-control-request-headers`];
        if (!cors.allowedHeaders && requestAccessControlRequestHeaders) {
          requestCorsHeaders.set(`access-control-allow-headers`, requestAccessControlRequestHeaders);
        }
      }

      const requestCorsHeadersObject = Array.from(requestCorsHeaders).reduce<Record<string, string>>(
        (headersObject, [key, value]) => {
          headersObject[key] = value;
          return headersObject;
        },
        {}
      );

      if (req.method === `OPTIONS`) {
        setHeaders(res, requestCorsHeadersObject);
        res.status(204).send(``);
        return;
      }

      if (req.url === `/.well-known/apollo/server-health`) {
        const successfulResponse = (): VercelResponse => {
          setHeaders(res, {
            "Content-Type": `application/json`,
            ...requestCorsHeadersObject
          });
          return res.status(200).json({ status: `pass` });
        };
        if (onHealthCheck) {
          try {
            void onHealthCheck(req);
            successfulResponse();
          } catch {
            setHeaders(res, {
              "Content-Type": `application/json`,
              ...requestCorsHeadersObject
            });
            res.status(503).json({ status: `fail` });
            return;
          }
        } else {
          successfulResponse();
          return;
        }
      }

      if (this.playgroundOptions && req.method === `GET`) {
        const acceptHeader = req.headers.Accept ?? req.headers.accept;
        if (acceptHeader?.includes(`text/html`)) {
          const path = req.url ?? `/`;
          const playgroundRenderPageOptions: PlaygroundRenderPageOptions = {
            endpoint: path,
            ...this.playgroundOptions
          };

          setHeaders(res, {
            "Content-Type": `text/html`,
            ...requestCorsHeadersObject
          });
          res.status(200).send(renderPlaygroundPage(playgroundRenderPageOptions));
          return;
        }
      }

      type NextFunction = () => Promise<void>;

      const fileUploadHandler = async (next: NextFunction): Promise<void> => {
        const contentType = req.headers[`content-type`] ?? req.headers[`Content-Type`];
        if (
          contentType &&
          (contentType as string).startsWith(`multipart/form-data`) &&
          typeof processFileUploads === `function`
        ) {
          try {
            // eslint-disable-next-line require-atomic-updates
            req.body = await processFileUploads(req, res, this.uploadsConfig ?? {});
            await next();
          } catch (error: unknown) {
            if (error instanceof Error) {
              // eslint-disable-next-line @typescript-eslint/no-throw-literal
              throw formatApolloErrors([error], {
                formatter: this.requestOptions.formatError,
                debug: this.requestOptions.debug
              });
            }
          }
        } else {
          await next();
        }
      };

      const handleGraphQLRequest = async (): Promise<void> => {
        await willStart;
        if (cors) {
          setHeaders(res, {
            ...requestCorsHeadersObject
          });
        }
        const options = await this.createGraphQLServerOptions(req, res);
        graphqlVercel(options)(req, res);
      };

      await fileUploadHandler(handleGraphQLRequest);
    };
  }