@devmoods/express-extras 0.13.8 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/migrate.js +10 -0
- package/dist/__tests__/auth.spec.jsx +3 -5
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +33 -45
- package/dist/context.d.ts +1 -1
- package/dist/context.js +10 -17
- package/dist/email.js +4 -31
- package/dist/errors.js +16 -51
- package/dist/index.d.ts +13 -13
- package/dist/index.js +14 -32
- package/dist/listen.d.ts +4 -4
- package/dist/listen.js +11 -11
- package/dist/logger.d.ts +3 -2
- package/dist/logger.js +29 -22
- package/dist/middleware.d.ts +5 -3
- package/dist/middleware.js +20 -54
- package/dist/migrate.d.ts +1 -1
- package/dist/migrate.js +25 -31
- package/dist/postgres.d.ts +109 -109
- package/dist/postgres.js +7 -16
- package/dist/redis.d.ts +264 -234
- package/dist/redis.js +3 -7
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +3 -7
- package/dist/sentry.d.ts +4 -3
- package/dist/sentry.js +4 -32
- package/dist/slack.js +5 -9
- package/dist/validate.d.ts +2 -2
- package/dist/validate.js +13 -23
- package/package.json +29 -12
- package/bin/migrate +0 -9
package/dist/logger.js
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getLoggers = exports.getLogger = exports.createLogger = void 0;
|
|
7
|
-
const bunyan_1 = __importDefault(require("bunyan"));
|
|
8
|
-
const context_1 = require("./context");
|
|
1
|
+
import bunyan from 'bunyan';
|
|
2
|
+
import { useRequestId } from './context.js';
|
|
9
3
|
function defaultGetContext() {
|
|
10
4
|
return {
|
|
11
|
-
requestId:
|
|
5
|
+
requestId: useRequestId(),
|
|
12
6
|
};
|
|
13
7
|
}
|
|
14
8
|
const _loggers = new Map();
|
|
15
|
-
|
|
9
|
+
let _sentryClient;
|
|
10
|
+
export function attachSentryClientToLoggers(sentryClient) {
|
|
11
|
+
_sentryClient = sentryClient;
|
|
12
|
+
}
|
|
13
|
+
export function createLogger({ name, getContext, silent = () => process.env.NODE_ENV === 'test', }) {
|
|
16
14
|
if (_loggers.has(name)) {
|
|
17
15
|
throw new Error(`A logger named ${name} already exists`);
|
|
18
16
|
}
|
|
19
|
-
const logger =
|
|
17
|
+
const logger = bunyan.createLogger({
|
|
20
18
|
name,
|
|
21
|
-
serializers:
|
|
19
|
+
serializers: bunyan.stdSerializers,
|
|
22
20
|
});
|
|
23
21
|
_loggers.set(name, logger);
|
|
24
22
|
if (silent()) {
|
|
25
|
-
logger.level(
|
|
23
|
+
logger.level(bunyan.FATAL + 1);
|
|
26
24
|
}
|
|
27
25
|
function getFinalContext() {
|
|
28
26
|
return {
|
|
29
27
|
...defaultGetContext(),
|
|
30
|
-
...getContext
|
|
28
|
+
...getContext?.(),
|
|
31
29
|
};
|
|
32
30
|
}
|
|
33
31
|
return {
|
|
@@ -41,25 +39,34 @@ function createLogger({ name, getContext, silent = () => process.env.NODE_ENV ==
|
|
|
41
39
|
return logger.child(getFinalContext(), true).warn(context, message);
|
|
42
40
|
},
|
|
43
41
|
error(error, message) {
|
|
42
|
+
const context = getFinalContext();
|
|
43
|
+
if (_sentryClient != null) {
|
|
44
|
+
_sentryClient.captureException(error, {
|
|
45
|
+
tags: context,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
44
48
|
return logger
|
|
45
|
-
.child(
|
|
46
|
-
.error(error, message ||
|
|
49
|
+
.child(context, true)
|
|
50
|
+
.error(error, message || error?.message);
|
|
47
51
|
},
|
|
48
52
|
fatal(error, message) {
|
|
49
|
-
|
|
53
|
+
const context = getFinalContext();
|
|
54
|
+
if (_sentryClient != null) {
|
|
55
|
+
_sentryClient.captureException(error, {
|
|
56
|
+
tags: context,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return logger.child(context, true).fatal(error, message);
|
|
50
60
|
},
|
|
51
61
|
};
|
|
52
62
|
}
|
|
53
|
-
|
|
54
|
-
function getLogger(name) {
|
|
63
|
+
export function getLogger(name) {
|
|
55
64
|
const logger = _loggers.get(name);
|
|
56
65
|
if (!logger) {
|
|
57
66
|
return createLogger({ name });
|
|
58
67
|
}
|
|
59
68
|
return logger;
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
function getLoggers() {
|
|
70
|
+
export function getLoggers() {
|
|
63
71
|
return _loggers;
|
|
64
72
|
}
|
|
65
|
-
exports.getLoggers = getLoggers;
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
/// <reference types="connect" />
|
|
1
2
|
/// <reference types="qs" />
|
|
2
|
-
import
|
|
3
|
-
import { RequestHandler } from 'express';
|
|
4
|
-
import { ErrorHandlerOptions } from './errors';
|
|
3
|
+
import bodyParser from 'body-parser';
|
|
4
|
+
import type { RequestHandler } from 'express';
|
|
5
|
+
import { type ErrorHandlerOptions } from './errors.js';
|
|
6
|
+
declare const urlencodedParser: (options?: bodyParser.OptionsUrlencoded | undefined) => import("connect").NextHandleFunction, jsonParser: (options?: bodyParser.OptionsJson | undefined) => import("connect").NextHandleFunction;
|
|
5
7
|
export { urlencodedParser, jsonParser, asyncMiddleware as route };
|
|
6
8
|
export interface BeforeMiddlewareOptions {
|
|
7
9
|
cookies?: boolean;
|
package/dist/middleware.js
CHANGED
|
@@ -1,50 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.asyncMiddleware = exports.after = exports.notFound = exports.before = exports.route = exports.jsonParser = exports.urlencodedParser = void 0;
|
|
30
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
31
|
-
const body_parser_1 = require("body-parser");
|
|
32
|
-
Object.defineProperty(exports, "jsonParser", { enumerable: true, get: function () { return body_parser_1.json; } });
|
|
33
|
-
Object.defineProperty(exports, "urlencodedParser", { enumerable: true, get: function () { return body_parser_1.urlencoded; } });
|
|
34
|
-
const compose_middleware_1 = require("compose-middleware");
|
|
35
|
-
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
36
|
-
const helmet_1 = __importDefault(require("helmet"));
|
|
37
|
-
const context_1 = require("./context");
|
|
38
|
-
const errors_1 = require("./errors");
|
|
1
|
+
import * as Sentry from '@sentry/node';
|
|
2
|
+
import bodyParser from 'body-parser';
|
|
3
|
+
import { compose } from 'compose-middleware';
|
|
4
|
+
import cookieParser from 'cookie-parser';
|
|
5
|
+
import helmet from 'helmet';
|
|
6
|
+
import { withRequestContext } from './context.js';
|
|
7
|
+
import { NotFound } from './errors.js';
|
|
8
|
+
const { urlencoded: urlencodedParser, json: jsonParser } = bodyParser;
|
|
9
|
+
export { urlencodedParser, jsonParser, asyncMiddleware as route };
|
|
39
10
|
/**
|
|
40
11
|
* Register middleware that must come before the app routes.
|
|
41
12
|
*/
|
|
42
|
-
function before({ cookies = false, helmet: useHelmet = true, json: useJson = true, allowUnsafeInlineScripts = false, } = {}) {
|
|
43
|
-
return
|
|
13
|
+
export function before({ cookies = false, helmet: useHelmet = true, json: useJson = true, allowUnsafeInlineScripts = false, } = {}) {
|
|
14
|
+
return compose([
|
|
44
15
|
Sentry.Handlers.requestHandler(),
|
|
45
16
|
Sentry.Handlers.tracingHandler(),
|
|
46
17
|
useHelmet &&
|
|
47
|
-
(
|
|
18
|
+
helmet({
|
|
48
19
|
contentSecurityPolicy: {
|
|
49
20
|
directives: {
|
|
50
21
|
'default-src': ["'self'"],
|
|
@@ -65,38 +36,35 @@ function before({ cookies = false, helmet: useHelmet = true, json: useJson = tru
|
|
|
65
36
|
},
|
|
66
37
|
},
|
|
67
38
|
}),
|
|
68
|
-
useJson && (
|
|
69
|
-
cookies && (
|
|
70
|
-
|
|
39
|
+
useJson && jsonParser(),
|
|
40
|
+
cookies && cookieParser(),
|
|
41
|
+
withRequestContext(),
|
|
71
42
|
].filter(Boolean));
|
|
72
43
|
}
|
|
73
|
-
exports.before = before;
|
|
74
44
|
/**
|
|
75
45
|
* Middleware that sends a 404
|
|
76
46
|
*
|
|
77
47
|
* Add this after your routes to send a 404 for all
|
|
78
48
|
* unknown routes.
|
|
79
49
|
*/
|
|
80
|
-
function notFound() {
|
|
50
|
+
export function notFound() {
|
|
81
51
|
return (req, res, next) => {
|
|
82
|
-
next(
|
|
52
|
+
next(NotFound(`Could not ${req.method} ${req.path}`));
|
|
83
53
|
};
|
|
84
54
|
}
|
|
85
|
-
exports.notFound = notFound;
|
|
86
55
|
/**
|
|
87
56
|
* Register middlewares that must come after the app routes.
|
|
88
57
|
*
|
|
89
58
|
* Currently attaches:
|
|
90
59
|
* - notFound()
|
|
91
60
|
*/
|
|
92
|
-
function after() {
|
|
61
|
+
export function after() {
|
|
93
62
|
return notFound();
|
|
94
63
|
}
|
|
95
|
-
exports.after = after;
|
|
96
64
|
/**
|
|
97
65
|
* Alias of `route()`
|
|
98
66
|
*/
|
|
99
|
-
function asyncMiddleware(fn) {
|
|
67
|
+
export function asyncMiddleware(fn) {
|
|
100
68
|
return (req, res, next) => {
|
|
101
69
|
return Promise.resolve(fn(req, res, next))
|
|
102
70
|
.then((result) => {
|
|
@@ -104,7 +72,7 @@ function asyncMiddleware(fn) {
|
|
|
104
72
|
(result.length === 2 || result.length === 3) &&
|
|
105
73
|
typeof result[0] === 'number') {
|
|
106
74
|
const [status, body, headers = {}] = result;
|
|
107
|
-
for (const header
|
|
75
|
+
for (const header of Object.keys(headers)) {
|
|
108
76
|
res.setHeader(header, headers[header]);
|
|
109
77
|
}
|
|
110
78
|
res.status(status).send(body);
|
|
@@ -119,5 +87,3 @@ function asyncMiddleware(fn) {
|
|
|
119
87
|
.catch(next);
|
|
120
88
|
};
|
|
121
89
|
}
|
|
122
|
-
exports.asyncMiddleware = asyncMiddleware;
|
|
123
|
-
exports.route = asyncMiddleware;
|
package/dist/migrate.d.ts
CHANGED
package/dist/migrate.js
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const meow_1 = __importDefault(require("meow"));
|
|
11
|
-
const postgres_1 = require("./postgres");
|
|
12
|
-
async function cli() {
|
|
13
|
-
const cli = (0, meow_1.default)(`
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import meow from 'meow';
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { createPostgres } from './postgres.js';
|
|
6
|
+
export async function cli() {
|
|
7
|
+
const cli = meow(`
|
|
14
8
|
Usage
|
|
15
9
|
$ migrate init
|
|
16
10
|
$ migrate up
|
|
@@ -18,8 +12,9 @@ Usage
|
|
|
18
12
|
$ migrate create <name>
|
|
19
13
|
`, {
|
|
20
14
|
description: 'PostgreSQL migration tool',
|
|
15
|
+
importMeta: import.meta,
|
|
21
16
|
});
|
|
22
|
-
|
|
17
|
+
const verbose = !cli.flags.silent;
|
|
23
18
|
const args = cli.input.slice();
|
|
24
19
|
const action = args.shift();
|
|
25
20
|
function isValidAction(action) {
|
|
@@ -39,16 +34,17 @@ Usage
|
|
|
39
34
|
break;
|
|
40
35
|
case 'init':
|
|
41
36
|
await migrator.init();
|
|
42
|
-
migrator.log(
|
|
37
|
+
migrator.log(chalk.green('Migrations table was successfully setup.'));
|
|
43
38
|
break;
|
|
44
|
-
case 'create':
|
|
39
|
+
case 'create': {
|
|
45
40
|
const createdMigration = await migrator.create(args[0]);
|
|
46
|
-
migrator.log(
|
|
41
|
+
migrator.log(chalk.green('Created migration', createdMigration));
|
|
47
42
|
break;
|
|
43
|
+
}
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
catch (error) {
|
|
51
|
-
console.error(
|
|
47
|
+
console.error(chalk.red(error.message));
|
|
52
48
|
}
|
|
53
49
|
finally {
|
|
54
50
|
process.exit(0);
|
|
@@ -56,9 +52,8 @@ Usage
|
|
|
56
52
|
}
|
|
57
53
|
run(action, ...args);
|
|
58
54
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
constructor({ postgres = (0, postgres_1.createPostgres)(), pathToMigrations = path_1.default.resolve(process.cwd(), 'db', 'migrations'), migrationTableName = 'migrations', verbose = true, } = {}) {
|
|
55
|
+
export class Migrator {
|
|
56
|
+
constructor({ postgres = createPostgres(), pathToMigrations = path.resolve(process.cwd(), 'db', 'migrations'), migrationTableName = 'migrations', verbose = true, } = {}) {
|
|
62
57
|
this.filenameRegExp = /(\d+)_(.*)\.(js|ts|mjs|mts)/;
|
|
63
58
|
this.postgres = postgres;
|
|
64
59
|
this.pathToMigrations = pathToMigrations;
|
|
@@ -82,9 +77,9 @@ class Migrator {
|
|
|
82
77
|
const lastVersion = existingMigrations.length
|
|
83
78
|
? existingMigrations[existingMigrations.length - 1].version
|
|
84
79
|
: 0;
|
|
85
|
-
const filename =
|
|
80
|
+
const filename = path.join(this.pathToMigrations, `${lastVersion + 1}_${name}.ts`);
|
|
86
81
|
const template = `// Generated ${new Date()}\n\nexport function up(query: any) {\n\n}\n\nexport function down(query: any) {\n\n}\n`;
|
|
87
|
-
await
|
|
82
|
+
await fs.writeFile(filename, template);
|
|
88
83
|
return filename;
|
|
89
84
|
}
|
|
90
85
|
async runMigrations(direction) {
|
|
@@ -104,7 +99,7 @@ class Migrator {
|
|
|
104
99
|
if (direction === 'up') {
|
|
105
100
|
const pendingMigrations = this.getPendingMigrations(migrations, currentVersion);
|
|
106
101
|
if (!pendingMigrations.length) {
|
|
107
|
-
this.log(
|
|
102
|
+
this.log(chalk.green('No pending migrations'));
|
|
108
103
|
return;
|
|
109
104
|
}
|
|
110
105
|
for (const migration of pendingMigrations) {
|
|
@@ -112,7 +107,7 @@ class Migrator {
|
|
|
112
107
|
await this.migrate(migration, direction);
|
|
113
108
|
await this.updateCurrentVersion(migration.version);
|
|
114
109
|
}
|
|
115
|
-
this.log(
|
|
110
|
+
this.log(chalk.green('Done!'));
|
|
116
111
|
}
|
|
117
112
|
else {
|
|
118
113
|
const previousMigrations = this.getPreviousMigrations(migrations, currentVersion);
|
|
@@ -120,7 +115,7 @@ class Migrator {
|
|
|
120
115
|
const updatedVersion = previousMigration ? previousMigration.version : 0;
|
|
121
116
|
const migrationToRollback = migrations.find((migration) => migration.version === currentVersion);
|
|
122
117
|
if (!migrationToRollback) {
|
|
123
|
-
this.log(
|
|
118
|
+
this.log(chalk.green('No migrations have been run, so nothing to rollback to.'));
|
|
124
119
|
return;
|
|
125
120
|
}
|
|
126
121
|
this.log('Rolling back migration', migrationToRollback.filename);
|
|
@@ -129,11 +124,11 @@ class Migrator {
|
|
|
129
124
|
}
|
|
130
125
|
}
|
|
131
126
|
queryWithLog(sql) {
|
|
132
|
-
this.log(
|
|
127
|
+
this.log(chalk.yellow(sql.toString()));
|
|
133
128
|
return this.postgres.query(sql);
|
|
134
129
|
}
|
|
135
130
|
async migrate(migration, direction) {
|
|
136
|
-
const migrator =
|
|
131
|
+
const migrator = await import(migration.filename);
|
|
137
132
|
if (!migrator.up || !migrator.down) {
|
|
138
133
|
throw new Error('Migrations must export both an up() and a down() function.');
|
|
139
134
|
}
|
|
@@ -151,12 +146,12 @@ class Migrator {
|
|
|
151
146
|
return result ? result.version : 0;
|
|
152
147
|
}
|
|
153
148
|
async getMigrations() {
|
|
154
|
-
const files = await
|
|
149
|
+
const files = await fs.readdir(this.pathToMigrations);
|
|
155
150
|
return (files || [])
|
|
156
151
|
.map((filename) => filename.match(this.filenameRegExp))
|
|
157
152
|
.filter(notNullOrUndefined)
|
|
158
153
|
.map(([filename, version, name]) => ({
|
|
159
|
-
filename:
|
|
154
|
+
filename: path.join(this.pathToMigrations, filename),
|
|
160
155
|
version: parseInt(version, 10),
|
|
161
156
|
name,
|
|
162
157
|
}))
|
|
@@ -170,7 +165,6 @@ class Migrator {
|
|
|
170
165
|
return migrations.filter((migration) => migration.version > currentVersion);
|
|
171
166
|
}
|
|
172
167
|
}
|
|
173
|
-
exports.Migrator = Migrator;
|
|
174
168
|
function notNullOrUndefined(x) {
|
|
175
169
|
return x != null;
|
|
176
170
|
}
|