Skip to content

Commit

Permalink
Add abstraction over environment values
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcginnes committed Aug 29, 2024
1 parent 5e574ba commit 029f143
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 34 deletions.
44 changes: 44 additions & 0 deletions packages/graph-explorer-proxy-server/src/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import dotenv from "dotenv";
import path from "path";
import { clientRoot } from "./paths.js";
import { z } from "zod";

/** Coerces a string to a boolean value in a case insensitive way. */
const BooleanStringSchema = z
.string()
.refine(s => s.toLowerCase() === "true" || s.toLowerCase() === "false")
.transform(s => s.toLowerCase() === "true");

// Define a required schema for the values we expect along with their defaults
const EnvironmentValuesSchema = z.object({
HOST: z.string().default("localhost"),
PROXY_SERVER_HTTPS_CONNECTION: BooleanStringSchema.default("false"),
PROXY_SERVER_HTTPS_PORT: z.coerce.number().default(443),
PROXY_SERVER_HTTP_PORT: z.coerce.number().default(80),
LOG_LEVEL: z
.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"])
.default("debug"),
LOG_STYLE: z.enum(["cloudwatch", "default"]).default("default"),
});

// Load environment variables from .env file.
dotenv.config({
path: [path.join(clientRoot, ".env.local"), path.join(clientRoot, ".env")],
});

// Parse the environment values from the process
const parsedEnvironmentValues = EnvironmentValuesSchema.safeParse(process.env);

if (!parsedEnvironmentValues.success) {
console.error("Failed to parse environment values");
const flattenedErrors = parsedEnvironmentValues.error.flatten();
console.error(flattenedErrors.fieldErrors);
process.exit(1);
}

console.log("Parsed environment values:", parsedEnvironmentValues.data);

// Adds all environment values to local object
export const env = {
...parsedEnvironmentValues.data,
};
27 changes: 3 additions & 24 deletions packages/graph-explorer-proxy-server/src/logging.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,16 @@
import { NextFunction, Request, Response } from "express";
import { pino } from "pino";
import { PrettyOptions } from "pino-pretty";
import { z } from "zod";
import { env } from "./env.js";

export type LogLevel = pino.LevelWithSilent;

const LogLevelSchema = z.enum([
"fatal",
"error",
"warn",
"info",
"debug",
"trace",
"silent",
]);

export const logger = createLogger();

/** Parses the log level from a given string. If the value is unrecognized or undefined, the default is "info". */
function toLogLevel(value: string | undefined): LogLevel {
const parsed = LogLevelSchema.safeParse(value);

if (!parsed.success) {
return "info";
}

return parsed.data;
}

/** Create a logger instance with pino. */
function createLogger() {
// Check whether we are configured with CloudWatch style
const loggingInCloudWatch = process.env.LOG_STYLE === "cloudwatch";
const loggingInCloudWatch = env.LOG_STYLE === "cloudwatch";
const options: PrettyOptions = loggingInCloudWatch
? {
// Avoid colors
Expand All @@ -43,7 +22,7 @@ function createLogger() {
colorize: true,
translateTime: true,
};
const level = toLogLevel(process.env.LOG_LEVEL);
const level = env.LOG_LEVEL;

return pino({
level,
Expand Down
15 changes: 5 additions & 10 deletions packages/graph-explorer-proxy-server/src/node-server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import express, { NextFunction, Response } from "express";
import cors from "cors";
import compression from "compression";
import dotenv from "dotenv";
import fetch, { RequestInit } from "node-fetch";
import https from "https";
import bodyParser from "body-parser";
Expand All @@ -13,14 +12,10 @@ import { IncomingHttpHeaders } from "http";
import { logger as proxyLogger, requestLoggingMiddleware } from "./logging.js";
import { clientRoot, proxyServerRoot } from "./paths.js";
import { errorHandlingMiddleware, handleError } from "./error-handler.js";
import { env } from "./env.js";

const app = express();

// Load environment variables from .env file.
dotenv.config({
path: [path.join(clientRoot, ".env.local"), path.join(clientRoot, ".env")],
});

const DEFAULT_SERVICE_TYPE = "neptune-db";

interface DbQueryIncomingHttpHeaders extends IncomingHttpHeaders {
Expand Down Expand Up @@ -498,11 +493,11 @@ const certificateKeyFilePath = path.join(
const certificateFilePath = path.join(proxyServerRoot, "cert-info/server.crt");

// Get the port numbers to listen on
const host = process.env.HOST || "localhost";
const httpPort = process.env.PROXY_SERVER_HTTP_PORT || 80;
const httpsPort = process.env.PROXY_SERVER_HTTPS_PORT || 443;
const host = env.HOST;
const httpPort = env.PROXY_SERVER_HTTP_PORT;
const httpsPort = env.PROXY_SERVER_HTTPS_PORT;
const useHttps =
process.env.PROXY_SERVER_HTTPS_CONNECTION === "true" &&
env.PROXY_SERVER_HTTPS_CONNECTION &&
fs.existsSync(certificateKeyFilePath) &&
fs.existsSync(certificateFilePath);

Expand Down

0 comments on commit 029f143

Please sign in to comment.