firebase-functions
Version:
Firebase SDK for Cloud Functions
89 lines (87 loc) • 3.13 kB
JavaScript
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 };