UNPKG

firebase-functions

Version:
89 lines (87 loc) 3.13 kB
import { initV2Endpoint } from "../../../runtime/manifest.mjs"; import { convertIfPresent, convertInvoker } from "../../../common/encoding.mjs"; import { withInit } from "../../../common/onInit.mjs"; import { withErrorHandler } from "../../../common/providers/https.mjs"; import { wrapTraceContext } from "../../trace.mjs"; import { getGlobalOptions, optionsToEndpoint } from "../../options.mjs"; import express from "express"; import fs from "fs"; import { ApolloServer } from "@apollo/server"; import { expressMiddleware } from "@as-integrations/express4"; //#region src/v2/providers/dataconnect/graphql.ts const FIREBASE_AUTH_HEADER = "X-Firebase-Auth-Token"; /** @hidden */ async function initGraphqlServer(opts) { if (!opts.schema && !opts.schemaFilePath || opts.schema && opts.schemaFilePath) { throw new Error("Exactly one of 'schema' or 'schemaFilePath' must be provided."); } if (opts.schemaFilePath) { opts.schema = fs.readFileSync(opts.schemaFilePath, "utf-8"); } if (!opts.resolvers.query && !opts.resolvers.mutation) { throw new Error("At least one query or mutation resolver must be provided."); } const apolloResolvers = {}; if (opts.resolvers.query) { apolloResolvers.Query = opts.resolvers.query; } if (opts.resolvers.mutation) { apolloResolvers.Mutation = opts.resolvers.mutation; } try { const serverPromise = (async () => { const app = express(); const server = new ApolloServer({ typeDefs: opts.schema, resolvers: apolloResolvers }); await server.start(); app.use(`/${opts.path ?? "graphql"}`, express.json(), expressMiddleware(server, { context: ({ req }) => Promise.resolve({ auth: { token: req.header(FIREBASE_AUTH_HEADER) } }) })); return app; })(); return serverPromise; } catch (e) { if (e instanceof Error) { throw new Error("Error initializing GraphQL server: " + e.message); } else { throw e; } } } /** * @hidden * Handles HTTPS GraphQL requests. * @param {GraphqlServerOptions} opts - Options for configuring the GraphQL server. * @returns {HttpsFunction} A function you can export and deploy. */ function onGraphRequest(opts) { let serverPromise = null; const handler = wrapTraceContext(withInit(withErrorHandler(async (req, res) => { serverPromise = serverPromise ?? initGraphqlServer(opts); const app = await serverPromise; app(req, res); }))); const globalOpts = getGlobalOptions(); const baseOpts = optionsToEndpoint(globalOpts); const specificOpts = optionsToEndpoint(opts); const endpoint = { ...initV2Endpoint(globalOpts, opts), platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { ...baseOpts?.labels, ...specificOpts?.labels }, dataConnectGraphqlTrigger: {} }; convertIfPresent(endpoint.dataConnectGraphqlTrigger, globalOpts, "invoker", "invoker", convertInvoker); convertIfPresent(endpoint.dataConnectGraphqlTrigger, opts, "invoker", "invoker", convertInvoker); if (opts.schemaFilePath) { endpoint.dataConnectGraphqlTrigger.schemaFilePath = opts.schemaFilePath; } handler.__endpoint = endpoint; return handler; } //#endregion export { initGraphqlServer, onGraphRequest };