Skip to content

Commit

Permalink
Add Postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
textbook committed Jan 30, 2024
1 parent 56f3469 commit e3d2ddf
Show file tree
Hide file tree
Showing 17 changed files with 435 additions and 14 deletions.
9 changes: 0 additions & 9 deletions .eslintrc

This file was deleted.

16 changes: 16 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": ["@codeyourfuture/standard", "prettier"],
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"plugins": ["import"],
"reportUnusedDisableDirectives": true,
"root": true,
"rules": {
"import/order": [
"error",
{ "alphabetize": { "order": "asc" }, "newlines-between": "always" }
]
}
}
14 changes: 14 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ on:
jobs:
nodejs:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: keepitsecret
POSTGRES_USER: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: textbook/take-action@nodejs
with:
Expand All @@ -15,6 +28,7 @@ jobs:
- run: npm run lint
- run: npm run test:cover
env:
DATABASE_URL: postgres://testdb:keepitsecret@localhost:5432/testdb
FORCE_COLOR: true
- run: npm run e2e
- run: npm run e2e:dev
Expand Down
5 changes: 4 additions & 1 deletion api/.eslintrc → api/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"ignorePatterns": ["/static/"],
"overrides": [
{
"files": ["*.test.js"],
"files": ["*.test.js", "setupTests.js"],
"extends": ["plugin:jest/recommended"],
"rules": {
"jest/expect-expect": [
Expand All @@ -14,6 +14,9 @@
}
}
],
"parserOptions": {
"ecmaVersion": 2022
},
"rules": {
"no-console": "warn",
"no-restricted-syntax": [
Expand Down
10 changes: 9 additions & 1 deletion api/app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import express from "express";

import db from "./db.js";
import config from "./utils/config.js";
import {
asyncHandler,
clientRouter,
configuredHelmet,
configuredMorgan,
Expand All @@ -20,7 +22,13 @@ if (config.production) {
app.use(httpsOnly());
}

app.get("/healthz", (_, res) => res.sendStatus(200));
app.get(
"/healthz",
asyncHandler(async (_, res) => {
await db.query("SELECT 1;");
res.sendStatus(200);
}),
);

app.use(clientRouter("/api"));

Expand Down
26 changes: 26 additions & 0 deletions api/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { default as pg } from "pg";

import config from "./utils/config.js";
import logger from "./utils/logger.js";

const pool = new pg.Pool({
connectionString: config.databaseUrl,
connectionTimeoutMillis: 5_000,
});

pool.on("error", (err) => logger.error("%O", err));

export const connect = async () => {
const client = await pool.connect();
logger.info("connected to %s", client.database);
client.release();
};

export const disconnect = async () => await pool.end();

export default {
query(...args) {
logger.debug("Postgres query: %O", args);
return pool.query.apply(pool, args);
},
};
1 change: 1 addition & 0 deletions api/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export default {
coverageReporters: [["json", { file: "api.json" }], "text"],
rootDir: ".",
transform: {},
setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
};
1 change: 1 addition & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"express": "^4.18.2",
"helmet": "^7.1.0",
"morgan": "^1.10.0",
"pg": "^8.11.3",
"winston": "^3.11.0"
},
"devDependencies": {
Expand Down
8 changes: 6 additions & 2 deletions api/server.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import app from "./app.js";

import { connect } from "./db.js";
import config from "./utils/config.js";
import logger from "./utils/logger.js";

const { port } = config;

app.listen(port, () => logger.info(`listening on ${port}`));
await connect();

const server = app.listen(port);

server.on("listening", () => logger.info(`listening on ${port}`));
5 changes: 5 additions & 0 deletions api/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { connect, disconnect } from "./db.js";

beforeAll(() => connect());

afterAll(() => disconnect());
14 changes: 14 additions & 0 deletions api/utils/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ const dotenvPath = resolve(

configDotenv({ path: dotenvPath });

requireArgs(["DATABASE_URL"]);

/**
* @property {string} databaseUrl
* @property {string} dotenvPath
* @property {string} logLevel
* @property {number} port
* @property {boolean} production
*/
export default {
databaseUrl: process.env.DATABASE_URL,
dotenvPath,
logLevel: process.env.LOG_LEVEL?.toLowerCase() ?? "info",
port: parseInt(process.env.PORT ?? "3000", 10),
production: process.env.NODE_ENV?.toLowerCase() === "production",
};

function requireArgs(required) {
const missing = required.filter((variable) => !process.env[variable]);
if (missing.length > 0) {
process.exitCode = 1;
throw new Error(
`missing required environment variable(s): ${missing.join(", ")}`,
);
}
}
11 changes: 11 additions & 0 deletions api/utils/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ import logger from "./logger.js";

const __dirname = dirname(fileURLToPath(import.meta.url));

export const asyncHandler = (handler) => {
/** @type {import("express").RequestHandler} */
return async (req, res, next) => {
try {
await handler(req, res, next);
} catch (err) {
next(err);
}
};
};

export const clientRouter = (apiRoot) => {
const staticDir = join(__dirname, "..", "static");
const router = Router();
Expand Down
File renamed without changes.
Loading

0 comments on commit e3d2ddf

Please sign in to comment.