Modernize the API.

This commit is contained in:
Jayden Seric 2021-06-11 15:23:05 +10:00
parent 9d5dfe07d8
commit 3db018dcc4
4 changed files with 368 additions and 559 deletions

848
api/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -20,25 +20,25 @@
"npm": ">= 7"
},
"dependencies": {
"apollo-server-koa": "^2.24.1",
"apollo-server-koa": "^2.25.1",
"dotenv": "^10.0.0",
"graphql": "^15.5.0",
"graphql-upload": "^12.0.0",
"koa": "^2.13.1",
"lowdb": "^1.0.0",
"mkdirp": "^1.0.4",
"lowdb": "^2.1.0",
"make-dir": "^3.1.0",
"shortid": "^2.2.16"
},
"devDependencies": {
"eslint": "^7.27.0",
"eslint": "^7.28.0",
"eslint-config-env": "^20.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.3",
"eslint-plugin-jsdoc": "^35.0.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsdoc": "^35.1.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"nodemon": "^2.0.7",
"prettier": "^2.3.0"
"prettier": "^2.3.1"
},
"scripts": {
"test": "npm run test:eslint && npm run test:prettier",

View File

@ -7,7 +7,10 @@ export default new GraphQLObjectType({
uploads: {
description: 'All stored files.',
type: GraphQLNonNull(GraphQLList(GraphQLNonNull(FileType))),
resolve: (source, args, { db }) => db.get('uploads').value(),
async resolve(source, args, { db }) {
await db.read();
return db.data.uploads;
},
},
}),
});

View File

@ -1,21 +1,18 @@
import { createWriteStream, unlink } from 'fs';
import { fileURLToPath } from 'url';
import { ApolloServer } from 'apollo-server-koa';
import { graphqlUploadKoa } from 'graphql-upload';
import Koa from 'koa';
import lowdb from 'lowdb';
import FileSync from 'lowdb/adapters/FileSync.js';
import mkdirp from 'mkdirp';
import shortid from 'shortid';
// `eslint-plugin-node` doesnt support the package `exports` field, see:
// https://github.com/mysticatea/eslint-plugin-node/issues/255
// eslint-disable-next-line node/no-missing-import
import { JSONFile, Low } from 'lowdb';
import makeDir from 'make-dir';
import shortId from 'shortid';
import schema from './schema/index.mjs';
const UPLOAD_DIR = './uploads';
const db = lowdb(new FileSync('db.json'));
// Seed an empty DB.
db.defaults({ uploads: [] }).write();
// Ensure upload directory exists.
mkdirp.sync(UPLOAD_DIR);
const UPLOAD_DIR = new URL('uploads/', import.meta.url);
const db = new Low(new JSONFile('db.json'));
/**
* Stores a GraphQL file upload. The file is stored in the filesystem and its
@ -26,8 +23,8 @@ mkdirp.sync(UPLOAD_DIR);
async function storeUpload(upload) {
const { createReadStream, filename, mimetype } = await upload;
const stream = createReadStream();
const id = shortid.generate();
const path = `${UPLOAD_DIR}/${id}-${filename}`;
const id = shortId.generate();
const path = new URL(`${id}-${filename}`, UPLOAD_DIR);
const file = { id, filename, mimetype, path };
// Store the file in the filesystem.
@ -56,7 +53,9 @@ async function storeUpload(upload) {
});
// Record the file metadata in the DB.
db.get('uploads').push(file).write();
await db.read();
db.data.uploads.push(file);
await db.write();
return file;
}
@ -81,10 +80,29 @@ new ApolloServer({
context: { db, storeUpload },
}).applyMiddleware({ app });
app.listen(process.env.PORT, (error) => {
if (error) throw error;
/**
* Starts the API server.
*/
async function startServer() {
await db.read();
console.info(
`Serving http://localhost:${process.env.PORT} for ${process.env.NODE_ENV}.`
);
});
// Seed an empty DB.
if (!db.data) {
db.data = { uploads: [] };
await db.write();
}
// Ensure upload directory exists.
await makeDir(fileURLToPath(UPLOAD_DIR));
app.listen(process.env.PORT, (error) => {
if (error) throw error;
console.info(
`Serving http://localhost:${process.env.PORT} for ${process.env.NODE_ENV}.`
);
});
}
startServer();