api.ts

// Firebase Functions
import * as functions from 'firebase-functions';

// Express & Middleware
import * as express from 'express';
import * as cors from 'cors';
import * as morgan from 'morgan';
import { ApolloServer } from 'apollo-server-express';
import { mergedSchema, mergedResolvers } from './graphql/merge';
import { getContextObject } from './graphql/context';
import { initEndpoints } from './endpoints';
import { allowOrigins } from './utility/middlewares/allow-origins';
import { FIREBASE_FN_REGION } from './config/constants';

// API
const app = express();

app.use(cors({ origin: true }));
// TODO MUST: set this based on environment
app.use(morgan('dev'));
app.use(allowOrigins);
// Parse body from request
app.use(
  express.urlencoded({
    extended: true
  })
);
app.use(express.json());

const server = new ApolloServer({
  typeDefs: mergedSchema,
  resolvers: mergedResolvers,
  // TODO: set true only on localhost
  // Enable graphiql gui
  introspection: false,
  playground: {
    settings: {
      'editor.theme': 'dark'
    }
  },
  // NOTE: Called on every request
  context: ({ req }) => getContextObject(req)
});
server.applyMiddleware({ app, path: '/private' });

// Init this after defining graphql route,
// to prevent override from url rewrite '/**'
initEndpoints(app);

export const api = functions.region(FIREBASE_FN_REGION).https.onRequest(app);