From caa3227bcc5cce30ec268e38f358465f0c72eb54 Mon Sep 17 00:00:00 2001 From: Edwin Hernandez Date: Tue, 26 Dec 2023 16:57:22 -0600 Subject: [PATCH] Update environment variables and add compression middleware --- .env.template | 7 ++- .husky/pre-commit | 4 ++ lint-staged.config.js | 3 -- package-lock.json | 76 ++++++++++++++++++++++++++++++ package.json | 10 ++++ src/server.ts | 7 ++- src/utils/compress-filter/index.ts | 20 ++++++++ src/utils/env/index.ts | 8 ++++ 8 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 .husky/pre-commit delete mode 100644 lint-staged.config.js create mode 100644 src/utils/compress-filter/index.ts diff --git a/.env.template b/.env.template index 2163e4c..d9cf7dd 100644 --- a/.env.template +++ b/.env.template @@ -1,8 +1,11 @@ # App's running environment -NODE_ENV= +NODE_ENV=development # App's running port -PORT= +PORT=8080 + +# Cors Origin URL +CORS_ORIGIN="" # App's public path PUBLIC_PATH="/" \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..0312b76 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx lint-staged \ No newline at end of file diff --git a/lint-staged.config.js b/lint-staged.config.js deleted file mode 100644 index 5f50ee7..0000000 --- a/lint-staged.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - "./**/*.{ts,js}": ["npm run lint"], -}; diff --git a/package-lock.json b/package-lock.json index 11efdb9..8c59221 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "compression": "^1.7.4", "cors": "^2.8.5", "crypto": "^1.0.1", "dotenv": "^16.3.1", @@ -18,6 +19,7 @@ }, "devDependencies": { "@tsconfig/node-lts-strictest-esm": "^18.12.1", + "@types/compression": "^1.7.5", "@types/cors": "^2.8.17", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.21", @@ -27,6 +29,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.2", "eslint-plugin-simple-import-sort": "^10.0.0", + "husky": "^8.0.3", "lint-staged": "^15.2.0", "nodemon": "^3.0.2", "prettier": "^3.1.1", @@ -378,6 +381,15 @@ "@types/node": "*" } }, + "node_modules/@types/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -1281,6 +1293,47 @@ "node": ">=16" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2291,6 +2344,21 @@ "node": ">=14.18.0" } }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3272,6 +3340,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/package.json b/package.json index f4f4ea0..699a5ad 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "lint:fix": "eslint --fix --ext .ts,.js src/", "format": "prettier --write 'src/**/*.{ts,js,json}'", "check-format": "prettier --check 'src/**/*.{ts,js,json}'", + "prepare": "husky install", "docker-prod": "docker-compose up --build", "docker-stop": "docker-compose down" }, @@ -18,6 +19,7 @@ "author": "", "license": "ISC", "dependencies": { + "compression": "^1.7.4", "cors": "^2.8.5", "crypto": "^1.0.1", "dotenv": "^16.3.1", @@ -27,6 +29,7 @@ }, "devDependencies": { "@tsconfig/node-lts-strictest-esm": "^18.12.1", + "@types/compression": "^1.7.5", "@types/cors": "^2.8.17", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.21", @@ -36,11 +39,18 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.2", "eslint-plugin-simple-import-sort": "^10.0.0", + "husky": "^8.0.3", "lint-staged": "^15.2.0", "nodemon": "^3.0.2", "prettier": "^3.1.1", "rimraf": "^5.0.5", "ts-node": "^10.9.2", "typescript": "^5.3.3" + }, + "lint-staged": { + "**/*.{js,jsx,ts,tsx}": [ + "npx prettier --write", + "npx eslint --fix" + ] } } diff --git a/src/server.ts b/src/server.ts index fb798fd..36f76db 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,3 +1,4 @@ +import compression from "compression"; import cors from "cors"; import express, { Express } from "express"; import helmet from "helmet"; @@ -5,14 +6,18 @@ import { pino } from "pino"; import { pinoHttp } from "pino-http"; import { middlewares } from "./middleware"; +import compressFilter from "./utils/compress-filter"; +import { getCorsOrigin } from "./utils/env"; const logger = pino({ name: "server start" }); const app: Express = express(); +const cors_origin = getCorsOrigin(); // Setup Middlewares -app.use(cors({ credentials: true })); +app.use(cors({ origin: [cors_origin], credentials: true })); app.use(pinoHttp({ logger })); app.use(helmet()); +app.use(compression({ filter: compressFilter })); app.use(middlewares()); export { app, logger }; diff --git a/src/utils/compress-filter/index.ts b/src/utils/compress-filter/index.ts new file mode 100644 index 0000000..3f58f4a --- /dev/null +++ b/src/utils/compress-filter/index.ts @@ -0,0 +1,20 @@ +import compression from "compression"; +import type { Request, Response } from "express"; + +/** + * Filter Function for the compression middleware + * @param req HTTPs Request + * @param res HTTPs Response + * @returns Returns false if request header contains x-no-compression + */ +function compressFilter(req: Request, res: Response): boolean { + if (req.headers["x-no-compression"]) { + // don't compress responses with this request header + return false; + } + + // fallback to standard filter function + return compression.filter(req, res); +} + +export default compressFilter; diff --git a/src/utils/env/index.ts b/src/utils/env/index.ts index 4b7fd68..439947d 100644 --- a/src/utils/env/index.ts +++ b/src/utils/env/index.ts @@ -1,5 +1,13 @@ +import * as dotenv from "dotenv"; +import path from "path"; + +dotenv.config({ + path: path.resolve(__dirname, "../../.env"), +}); + export const getPort = () => getEnvVar("PORT", "number"); export const getNodeEnv = () => getEnvVar("NODE_ENV", "string"); +export const getCorsOrigin = () => getEnvVar("CORS_ORIGIN", "string"); function getEnvVar(key: string, type: "string" | "number"): T { const value = process.env[key];