text: const path = require('path');
  
  const express = require('express');
  const bodyParser = require('body-parser');
  const mongoose = require('mongoose');
  const dotenv = require('dotenv');
  const multer = require('multer');
  const graphqlHttp = require('express-graphql');
  
  const graphqlSchema = require('./graphql/schema');
  const graphqlResolver = require('./graphql/resolvers');
  const auth = require('./middleware/auth');
  const { clearImage } = require('./util/image');
  
  dotenv.config();
  
  const app = express();
  
  const storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, 'images');
    },
    filename: (req, file, cb) => {
      cb(null, `${new Date().toISOString()}-${file.originalname}`);
    },
  });
  
  const acceptedFileTypes = ['image/png', 'image/jpg', 'image/jpeg'];
  const fileFilter = (req, file, cb) =>
    acceptedFileTypes.includes(file.mimetype) ? cb(null, true) : cb(null, false);
  
  // app.use(bodyParser.urlencoded()); // x-www-form-urlencoded <form>
  app.use(bodyParser.json()); // application/json
  app.use(multer({ storage, fileFilter }).single('image'));
  app.use('/images', express.static(path.join(__dirname, 'images')));
  
  app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader(
      'Access-Control-Allow-Methods',
      'GET, POST, PUT, PATCH, DELETE'
    );
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    if (req.method === 'OPTIONS') {
      return res.sendStatus(200);
    }
    next();
  });
  
  app.use(auth);
  
  app.put('/post-image', (req, res, next) => {
    if (!req.isAuth) {
      throw new Error('Not authenticated.');
    }
    if (!req.file) {
      return res.status(200).json({ message: 'No file provided.' });
    }
    if (req.body.oldPath) {
      clearImage(req.body.oldPath);
    }
    return res
      .status(201)
      .json({ message: 'File stored.', filePath: req.file.path });
  });
  
  app.use(
    '/graphql',
    graphqlHttp({
      schema: graphqlSchema,
      rootValue: graphqlResolver,
      graphiql: true,
      formatError(err) {
        if (!err.originalError) {
          return err;
        }
        const { data } = err.originalError;
        const message = err.message || 'An error occurred.';
        const code = err.originalError.code || 500;
        return {
          message,
          status: code,
          data,
        };
      },
    })
  );
  
  app.use((error, req, res, next) => {
    console.log(error);
    const { statusCode = 500, message, data } = error;
    res.status(statusCode).json({ message, data });
  });
  
  mongoose
    .connect(process.env.MONGODB_URI)
    .then(() => app.listen(8080))
    .catch(err => console.log(err));
  