Skip to content

Commit

Permalink
Update logging & lint, drop Node 12 and Mongo 4.4 in CI (#36)
Browse files Browse the repository at this point in the history
* Add option to disable colors in console

This is useful if you're logging to a text-based system like Google Stack Driver

* Use eslint fullstack

* Fix build error

* Update supported Node and Mongo
  • Loading branch information
joshgachnang authored Feb 19, 2022
1 parent f5eeb8d commit 3754162
Show file tree
Hide file tree
Showing 10 changed files with 712 additions and 1,115 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x]
mongodb-version: ["4.4"]
node-version: [14.x, 16.x]
mongodb-version: ["5.0"]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
58 changes: 12 additions & 46 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"mongoose": "^6.1.9"
},
"devDependencies": {
"mongoose": "^6.1.9",
"@types/bcrypt": "^5.0.0",
"@types/chai": "^4.2.22",
"@types/cron": "^1.7.3",
Expand All @@ -65,20 +64,21 @@
"@types/passport-local": "^1.0.34",
"@types/sinon": "^9.0.5",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"chai": "^4.3.4",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-config-developit": "^1.2.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^4.1.0",
"eslint-loader": "^3.0.0",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-config-ts-fullstack": "^0.1.1",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-lodash": "^7.1.0",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-native": "^3.7.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"jest": "^26.6.3",
"prettier": "^1.19.1",
"mongoose": "^6.1.9",
"prettier": "^2.5.1",
"sinon": "^7.5.0",
"supertest": "^6.1.6",
"ts-jest": "^26.5.1",
Expand All @@ -94,42 +94,8 @@
"useTabs": false
},
"eslintConfig": {
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"settings": {
"react": {
"version": "16.13.1"
}
},
"plugins": [
"prettier",
"lodash"
],
"extends": [
"plugin:@typescript-eslint/eslint-recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"rules": {
"prefer-const": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-require": "off",
"lodash/import-scope": [
2,
"method"
],
"prettier/prettier": "error"
}
"ts-fullstack"
]
}
}
11 changes: 6 additions & 5 deletions src/example.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import chai from "chai";
import express from "express";
import mongoose, {model, Schema} from "mongoose";
import {passportLocalMongoose} from "./passport";
import {tokenPlugin} from ".";

import {logger, tokenPlugin} from ".";
import {
baseUserPlugin,
createdDeletedPlugin,
gooseRestRouter,
Permissions,
setupAuth,
} from "./mongooseRestFramework";
import {passportLocalMongoose} from "./passport";

const assert = chai.assert;

Expand Down Expand Up @@ -52,10 +53,10 @@ const FoodModel = model<Food>("Food", schema);
function getBaseServer() {
const app = express();

app.all("/*", function(req, res, next) {
app.all("/*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
//intercepts OPTIONS method
// intercepts OPTIONS method
if (req.method === "OPTIONS") {
res.send(200);
} else {
Expand All @@ -77,6 +78,6 @@ function getBaseServer() {
})
);
app.listen(5004);
console.log("Running on 5004");
logger.info("Running on 5004");
}
getBaseServer();
27 changes: 12 additions & 15 deletions src/expressServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import express, {Router} from "express";
import cloneDeep from "lodash/cloneDeep";
import onFinished from "on-finished";
import passport from "passport";

import {logger, LoggingOptions, setupLogging} from "./logger";
import {Env, setupAuth, UserModel} from "./mongooseRestFramework";
import {Env, setupAuth, UserModel as UserMongooseModel} from "./mongooseRestFramework";

const SLOW_READ_MAX = 200;
const SLOW_WRITE_MAX = 500;
Expand All @@ -23,7 +24,7 @@ export function setupErrorLogging() {

export type AddRoutes = (router: Router) => void;

const logRequestsFinished = function(req: any, res: any, startTime: [number, number]) {
const logRequestsFinished = function (req: any, res: any, startTime: [number, number]) {
const diff = process.hrtime(startTime);
const diffInMs = Math.round(diff[0] * 1000 + diff[1] * 0.000001);
let pathName = "unknown";
Expand All @@ -35,17 +36,17 @@ const logRequestsFinished = function(req: any, res: any, startTime: [number, num
logger.warn(`Request without route: ${req.originalUrl}`);
}

logger.debug(`${req.method} -> ${req.originalUrl} ${res.statusCode} ${diffInMs + "ms"}`);
logger.debug(`${req.method} -> ${req.originalUrl} ${res.statusCode} ${`${diffInMs}ms`}`);
if (diffInMs > SLOW_READ_MAX && req.method === "GET") {
logger.warn("Slow GET request", {
requestTime: diffInMs,
pathName: pathName,
pathName,
url: req.originalUrl,
});
} else if (diffInMs > SLOW_WRITE_MAX) {
logger.warn("Slow write request", {
requestTime: diffInMs,
pathName: pathName,
pathName,
url: req.originalUrl,
});
}
Expand Down Expand Up @@ -105,7 +106,7 @@ export function createRouterWithAuth(
]);
}

function initializeRoutes(UserModel: UserModel, addRoutes: AddRoutes) {
function initializeRoutes(UserModel: UserMongooseModel, addRoutes: AddRoutes) {
if (!process.env.SESSION_SECRET && process.env.NODE_ENV === "production") {
throw new Error("You must provide a SESSION_SECRET in env.");
}
Expand All @@ -114,7 +115,7 @@ function initializeRoutes(UserModel: UserModel, addRoutes: AddRoutes) {

app.use(Sentry.Handlers.requestHandler());

app.all("/*", function(req, res, next) {
app.all("/*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
if (req.method === "OPTIONS") {
Expand All @@ -136,25 +137,24 @@ function initializeRoutes(UserModel: UserModel, addRoutes: AddRoutes) {
// The error handler must be before any other error middleware and after all controllers
app.use(Sentry.Handlers.errorHandler());

// eslint-disable-next-line @typescript-eslint/no-unused-vars
app.use(function onError(_err: any, _req: any, res: any, _next: any) {
logger.error("Fallthrough error", _err);
res.statusCode = 500;
res.end(res.sentry + "\n");
res.end(`${res.sentry}\n`);
});

logger.debug("Listening on routes:");
app._router.stack.forEach((r: any) => {
if (r.route && r.route.path) {
logger.debug("[Route] " + r.route.path);
logger.debug(`[Route] ${r.route.path}`);
}
});

return app;
}

export interface SetupServerOptions {
userModel: UserModel;
userModel: UserMongooseModel;
addRoutes: AddRoutes;
loggingOptions?: LoggingOptions;
skipListen?: boolean;
Expand Down Expand Up @@ -237,10 +237,7 @@ export interface WrapScriptOptions {
// Wrap up a script with some helpers, such as catching errors, reporting them to sentry, notifying
// Slack of runs, etc. Also supports timeouts.
export async function wrapScript(func: () => Promise<any>, options: WrapScriptOptions = {}) {
const name = require.main?.filename
.split("/")
.slice(-1)[0]
.replace(".ts", "");
const name = require.main?.filename.split("/").slice(-1)[0].replace(".ts", "");
logger.info(`Running script ${name}`);
sendToSlack(`Running script ${name}`, options.slackChannel);

Expand Down
7 changes: 6 additions & 1 deletion src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ export interface LoggingOptions {
transports?: winston.transport[];
disableFileLogging?: boolean;
disableConsoleLogging?: boolean;
disableConsoleColors?: boolean;
logDirectory?: string;
}

export function setupLogging(options?: LoggingOptions) {
logger.clear();
if (!options?.disableConsoleLogging) {
const formats: any[] = [winston.format.simple()];
if (!options?.disableConsoleColors) {
formats.push(winston.format.colorize());
}
logger.add(
new winston.transports.Console({
debugStdout: !options?.level || options?.level === "debug",
level: options?.level ?? "debug",
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
format: winston.format.combine(...formats),
})
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/models/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
* Contains the APIs and model plugins to send and receive messages. Currently, supports Twilio and
* Expo push notifications.
*/
import axios from "axios";
import Expo, {ExpoPushErrorTicket, ExpoPushSuccessTicket, ExpoPushTicket} from "expo-server-sdk";
import mongoose, {Document, Schema, Types} from "mongoose";

import {logger} from "../logger";
import {
ConversationDocument,
Expand All @@ -16,7 +18,6 @@ import {
MessagePushStatus,
MessageSchema,
} from "./interfaces";
import axios from "axios";

// Selectively export from interfaces
export {MessageSchema, MessageModel, MessageDocument} from "./interfaces";
Expand Down Expand Up @@ -358,7 +359,7 @@ export function conversationPlugin(conversationSchema: Schema) {

conversationSchema.statics = {
createConversationForUser(user: ConversationUser, extraData: any) {
console.log("Creating conversation for user", user._id);
logger.info("Creating conversation for user", user._id);
return this.create({
members: [{userId: user._id}],
...extraData,
Expand Down
Loading

0 comments on commit 3754162

Please sign in to comment.