aboutsummaryrefslogtreecommitdiff
path: root/src/util/config.ts
diff options
context:
space:
mode:
authorKevin J Hoerr <kjhoerr@protonmail.com>2020-04-26 21:53:26 -0400
committerKevin J Hoerr <kjhoerr@protonmail.com>2020-04-26 21:53:26 -0400
commitddecabba54eb24ab4ac07a67621f805d3ad9e2ce (patch)
tree7422ecca20f3a66ce1e6bc2839db454eacc1fbd2 /src/util/config.ts
parentee068fcbf0f409ac91d6559438e84fb89e654a15 (diff)
downloadao-coverage-ddecabba54eb24ab4ac07a67621f805d3ad9e2ce.tar.gz
ao-coverage-ddecabba54eb24ab4ac07a67621f805d3ad9e2ce.tar.bz2
ao-coverage-ddecabba54eb24ab4ac07a67621f805d3ad9e2ce.zip
These changes moved a lot of the startup async to run in a streamlined
async init function. This brings more logic "to light", so it should probably have unit tests added to check the edge cases. As a bonus, no async runs as a result of route initialization. Speaking of routes, it might be nice to trim down the route calls themselves with async functions, if possible. The upload routes in particular use a lot of async. Just a note for the future.
Diffstat (limited to 'src/util/config.ts')
-rw-r--r--src/util/config.ts75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/util/config.ts b/src/util/config.ts
index 1eddda3..b3a1ead 100644
--- a/src/util/config.ts
+++ b/src/util/config.ts
@@ -1,8 +1,11 @@
import winston from "winston";
-import { MongoClient } from "mongodb";
+import { MongoClient, MongoError } from "mongodb";
import { Server } from "http";
+import path from "path";
+import fs from "fs";
import loggerConfig from "./logger";
+import processTemplate, { Template } from "../templates";
const logger = winston.createLogger(loggerConfig("ROOT"));
@@ -16,6 +19,76 @@ export const configOrError = (varName: string): string => {
}
};
+export const persistTemplate = async (input: Template): Promise<void> => {
+ try {
+ const template = await processTemplate(input);
+ logger.debug("Generated '%s' from template file", template.outputFile);
+ } catch (err1) {
+ try {
+ await fs.promises.access(input.outputFile, fs.constants.R_OK);
+ } catch (err2) {
+ logger.error(
+ "Error while generating '%s' from template file: %s",
+ input.outputFile,
+ err1
+ );
+ logger.error("Cannot proceed due to error: %s", err2);
+
+ process.exit(1);
+ }
+ // if the output file exists, then we are fine with continuing without
+ logger.warning(
+ "Could not generate '%s' from template file, but file already exists: %s",
+ input.outputFile,
+ err1
+ );
+ }
+};
+
+const MONGO_URI = configOrError("MONGO_URI");
+const TARGET_URL = process.env.TARGET_URL ?? "http://localhost:3000";
+const HOST_DIR = configOrError("HOST_DIR");
+
+export const handleStartup = async (): Promise<MongoClient> => {
+ await fs.promises.access(HOST_DIR, fs.constants.R_OK | fs.constants.W_OK);
+ if (!path.isAbsolute(HOST_DIR)) {
+ logger.error("HOST_DIR must be an absolute path");
+ process.exit(1);
+ }
+
+ const mongo = await new MongoClient(MONGO_URI, { useUnifiedTopology: true })
+ .connect()
+ .catch((err: MongoError) => {
+ logger.error(err.message ?? "Unable to connect to database");
+ process.exit(1);
+ });
+
+ await persistTemplate({
+ inputFile: path.join(
+ __dirname,
+ "..",
+ "public",
+ "templates",
+ "bash.template"
+ ),
+ outputFile: path.join(HOST_DIR, "bash"),
+ context: { TARGET_URL }
+ } as Template);
+ await persistTemplate({
+ inputFile: path.join(
+ __dirname,
+ "..",
+ "public",
+ "templates",
+ "index.html.template"
+ ),
+ outputFile: path.join(HOST_DIR, "index.html"),
+ context: { TARGET_URL }
+ } as Template);
+
+ return mongo;
+};
+
export const handleShutdown = (mongo: MongoClient, server: Server) => (
signal: NodeJS.Signals
): Promise<void> => {