@devmoods/express-extras 0.32.0 → 0.33.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/dist/cache.d.ts +1 -1
- package/dist/cli.d.ts +13 -0
- package/dist/cli.js +45 -0
- package/dist/email.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/listen.d.ts +0 -1
- package/dist/listen.js +1 -1
- package/dist/logger.d.ts +6 -5
- package/dist/logger.js +2 -1
- package/dist/manage.d.ts +4 -1
- package/dist/manage.js +29 -1
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.js +2 -1
- package/dist/migrate.d.ts +4 -2
- package/dist/migrate.js +52 -72
- package/dist/postgres.d.ts +7 -7
- package/dist/postgres.js +3 -3
- package/dist/routes.js +1 -1
- package/dist/sentry.js +1 -0
- package/dist/utils.d.ts +0 -1
- package/package.json +33 -41
- package/bin/migrate +0 -5
- package/bin/routes +0 -5
- package/dist/cli/migrate.d.ts +0 -1
- package/dist/cli/migrate.js +0 -3
- package/dist/cli/routes.d.ts +0 -1
- package/dist/cli/routes.js +0 -10
package/dist/cache.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export declare function createMemoryCacheAdapter(): CacheAdapter;
|
|
|
12
12
|
export declare function createCache(adapter: CacheAdapter): {
|
|
13
13
|
set: (key: string, value: any, expires?: number | null | undefined) => Promise<void>;
|
|
14
14
|
get: (key: string) => Promise<any>;
|
|
15
|
-
clear: (key?: string
|
|
15
|
+
clear: (key?: string) => Promise<void>;
|
|
16
16
|
wrap: <T>(key: string, expiresMs: number | null | undefined, fn: () => Promise<T>) => Promise<T>;
|
|
17
17
|
};
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type WriteStream } from 'node:tty';
|
|
2
|
+
export interface CLIOptions {
|
|
3
|
+
printStackTraces?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class CLI {
|
|
6
|
+
private options;
|
|
7
|
+
constructor(options?: CLIOptions);
|
|
8
|
+
writeLine(message: string, output?: WriteStream): void;
|
|
9
|
+
greenLine(message: string, output?: WriteStream): void;
|
|
10
|
+
redLine(message: string, output?: WriteStream): void;
|
|
11
|
+
readInput(question: string): Promise<string>;
|
|
12
|
+
wrap(action: (...args: any[]) => void | Promise<void>): (...args: any[]) => Promise<void>;
|
|
13
|
+
}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { stdin, stdout, stderr } from 'node:process';
|
|
2
|
+
import * as readline from 'node:readline';
|
|
3
|
+
import {} from 'node:tty';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { startTimer } from './utils.js';
|
|
6
|
+
export class CLI {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
}
|
|
10
|
+
writeLine(message, output = stdout) {
|
|
11
|
+
output.write(`${message}`);
|
|
12
|
+
}
|
|
13
|
+
greenLine(message, output = stdout) {
|
|
14
|
+
output.write(`${chalk.green(message)}\n`);
|
|
15
|
+
}
|
|
16
|
+
redLine(message, output = stderr) {
|
|
17
|
+
output.write(`${chalk.red(message)}\n`);
|
|
18
|
+
}
|
|
19
|
+
/* v8 ignore next 10 */
|
|
20
|
+
readInput(question) {
|
|
21
|
+
const rl = readline.createInterface({ input: stdin, output: stderr });
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
rl.question(question, (answer) => {
|
|
24
|
+
resolve(answer);
|
|
25
|
+
rl.close();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
wrap(action) {
|
|
30
|
+
return async (...args) => {
|
|
31
|
+
const timer = startTimer();
|
|
32
|
+
try {
|
|
33
|
+
await action(...args);
|
|
34
|
+
this.greenLine(`Command succeeded in ${timer.getDuration().toFixed(4)}s`);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.redLine(error.message);
|
|
38
|
+
if (this.options.printStackTraces) {
|
|
39
|
+
this.writeLine('\nStack trace:\n', stderr);
|
|
40
|
+
this.redLine(error.stack);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
package/dist/email.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export interface SendEmailOptions extends nodemailer.SendMailOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function createEmail({ host, port, user, pass, senderName, senderAddress, }: EmailOptions): {
|
|
14
14
|
send: ({ to, subject, message, ...rest }: SendEmailOptions) => Promise<void>;
|
|
15
|
-
transporter: nodemailer.Transporter<import("nodemailer/lib/smtp-transport/index.js").SentMessageInfo>;
|
|
15
|
+
transporter: nodemailer.Transporter<import("nodemailer/lib/smtp-transport/index.js").SentMessageInfo, import("nodemailer/lib/smtp-transport/index.js").Options>;
|
|
16
16
|
readonly outbox: Record<string, any>[];
|
|
17
17
|
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/listen.d.ts
CHANGED
package/dist/listen.js
CHANGED
|
@@ -104,7 +104,7 @@ export function createExpressServer(app, options = {}) {
|
|
|
104
104
|
const meta = await options.healthCheck?.();
|
|
105
105
|
return { status: 'ok', meta, timestamp };
|
|
106
106
|
}
|
|
107
|
-
catch
|
|
107
|
+
catch {
|
|
108
108
|
return [503, { status: 'error', timestamp }];
|
|
109
109
|
}
|
|
110
110
|
}));
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import { type Duplex } from 'node:stream';
|
|
3
1
|
export type LoggerContext = Record<string, any>;
|
|
2
|
+
export interface LoggerOutputWriter {
|
|
3
|
+
write(chunk: any): boolean;
|
|
4
|
+
}
|
|
4
5
|
export interface LoggerOptions {
|
|
5
6
|
/**
|
|
6
7
|
* Name of the logger
|
|
@@ -11,7 +12,7 @@ export interface LoggerOptions {
|
|
|
11
12
|
*/
|
|
12
13
|
getContext?: () => LoggerContext;
|
|
13
14
|
level?: string;
|
|
14
|
-
output?:
|
|
15
|
+
output?: LoggerOutputWriter;
|
|
15
16
|
}
|
|
16
17
|
export declare function setGlobalLoggerContext(getContext: () => LoggerContext): void;
|
|
17
18
|
export type Logger = ReturnType<typeof createLogger>;
|
|
@@ -27,6 +28,6 @@ export declare function getLoggers(): Map<string, {
|
|
|
27
28
|
debug(message: string, context?: LoggerContext): void;
|
|
28
29
|
info(message: string, context?: LoggerContext): void;
|
|
29
30
|
warn(message: string, context?: LoggerContext): void;
|
|
30
|
-
error(error: Error | null, message?: string
|
|
31
|
-
fatal(error: Error | null, message?: string
|
|
31
|
+
error(error: Error | null, message?: string, context?: LoggerContext): void;
|
|
32
|
+
fatal(error: Error | null, message?: string, context?: LoggerContext): void;
|
|
32
33
|
}>;
|
package/dist/logger.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as os from 'node:os';
|
|
2
|
-
import {} from 'node:stream';
|
|
3
2
|
import * as Sentry from '@sentry/node';
|
|
4
3
|
import { useRequestId } from './context.js';
|
|
5
4
|
import { readEnv } from './utils.js';
|
|
@@ -18,7 +17,9 @@ export function setGlobalLoggerContext(getContext) {
|
|
|
18
17
|
_globalGetContext = getContext;
|
|
19
18
|
}
|
|
20
19
|
function defaultGetContext() {
|
|
20
|
+
const nameArgIndex = process.argv.indexOf('--name');
|
|
21
21
|
return {
|
|
22
|
+
app: nameArgIndex > -1 ? process.argv.at(nameArgIndex + 1) : undefined,
|
|
22
23
|
requestId: useRequestId(),
|
|
23
24
|
..._globalGetContext?.(),
|
|
24
25
|
};
|
package/dist/manage.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { program } from 'commander';
|
|
2
|
+
import { type Express } from 'express';
|
|
3
|
+
import { CLI } from './cli.js';
|
|
2
4
|
type Command = typeof program.command;
|
|
3
|
-
export declare function registerManagementCommand(register: (command: Command) => void): void;
|
|
5
|
+
export declare function registerManagementCommand(register: (command: Command, cli: CLI) => void): void;
|
|
4
6
|
export declare function runManagementCommands(): Promise<void>;
|
|
7
|
+
export declare function registerDefaultCommands(app: Express | null): void;
|
|
5
8
|
export {};
|
package/dist/manage.js
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
import { program } from 'commander';
|
|
2
|
+
import {} from 'express';
|
|
3
|
+
import { parseExpressApp } from 'express-route-parser';
|
|
4
|
+
import { hashPassword } from './auth.js';
|
|
5
|
+
import { CLI } from './cli.js';
|
|
6
|
+
import { asCli } from './migrate.js';
|
|
7
|
+
program.option('--verbose', 'Verbose mode');
|
|
2
8
|
export function registerManagementCommand(register) {
|
|
3
|
-
|
|
9
|
+
const cli = new CLI({ printStackTraces: process.argv.includes('--verbose') });
|
|
10
|
+
register(program.command.bind(program), cli);
|
|
4
11
|
}
|
|
5
12
|
export async function runManagementCommands() {
|
|
6
13
|
await program.parseAsync(process.argv);
|
|
7
14
|
}
|
|
15
|
+
export function registerDefaultCommands(app) {
|
|
16
|
+
registerManagementCommand((command, cli) => {
|
|
17
|
+
const migrate = command('migrate');
|
|
18
|
+
asCli(migrate, cli);
|
|
19
|
+
});
|
|
20
|
+
registerManagementCommand((command, cli) => command('routes').action(cli.wrap(async () => {
|
|
21
|
+
if (!app)
|
|
22
|
+
return;
|
|
23
|
+
const routes = parseExpressApp(app);
|
|
24
|
+
for (const route of routes) {
|
|
25
|
+
cli.writeLine(`${route.method.toLocaleUpperCase().padEnd(5)} ${route.path}\n`);
|
|
26
|
+
}
|
|
27
|
+
})));
|
|
28
|
+
registerManagementCommand((command, cli) => {
|
|
29
|
+
command('password-hash').action(cli.wrap(async () => {
|
|
30
|
+
const password = await cli.readInput('Type a password: ');
|
|
31
|
+
const hash = await hashPassword(password);
|
|
32
|
+
cli.writeLine(`${hash}\n`);
|
|
33
|
+
}));
|
|
34
|
+
});
|
|
35
|
+
}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import bodyParser from 'body-parser';
|
|
2
|
-
import { type RequestHandler } from 'express';
|
|
2
|
+
import { type NextFunction, type RequestHandler, type Request, type Response } from 'express';
|
|
3
3
|
type UrlencodedParser = typeof bodyParser.urlencoded;
|
|
4
4
|
type JsonParser = typeof bodyParser.json;
|
|
5
5
|
export declare const urlencodedParser: UrlencodedParser;
|
|
@@ -36,4 +36,4 @@ export declare function after(): RequestHandler;
|
|
|
36
36
|
/**
|
|
37
37
|
* Alias of `route()`
|
|
38
38
|
*/
|
|
39
|
-
export declare function asyncMiddleware<RequestBody, RequestQuery = object>(fn:
|
|
39
|
+
export declare function asyncMiddleware<RequestBody, RequestQuery = object, ResponseBody = any>(fn: (req: Request<Record<string, string>, ResponseBody, RequestBody, RequestQuery, object>, res: Response<ResponseBody, object>, next: NextFunction) => ResponseBody | Promise<ResponseBody>): RequestHandler<Record<string, string>, any, RequestBody, RequestQuery>;
|
package/dist/middleware.js
CHANGED
|
@@ -94,7 +94,8 @@ function analyticsProxy() {
|
|
|
94
94
|
return (req, res, next) => {
|
|
95
95
|
if (req.originalUrl === '/analytics.js') {
|
|
96
96
|
res.setHeader('Content-type', 'text/javascript');
|
|
97
|
-
|
|
97
|
+
res.status(200).end('// no-op analytics proxy');
|
|
98
|
+
return;
|
|
98
99
|
}
|
|
99
100
|
next();
|
|
100
101
|
};
|
package/dist/migrate.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type Command } from 'commander';
|
|
2
|
+
import { type CLI } from './cli.js';
|
|
1
3
|
import { type Connection, createPostgres } from './postgres.js';
|
|
2
4
|
interface Migration {
|
|
3
5
|
name: string;
|
|
@@ -9,8 +11,7 @@ interface MigrationFileAPI {
|
|
|
9
11
|
up(fn: any): Promise<void> | Promise<void> | string | undefined;
|
|
10
12
|
down(fn: any): Promise<string> | Promise<void> | string | undefined;
|
|
11
13
|
}
|
|
12
|
-
export declare
|
|
13
|
-
export declare function runCli(input: string[], flags: Record<string, any>, showHelp?: () => void): Promise<number>;
|
|
14
|
+
export declare const asCli: (command: Command, cli: CLI) => void;
|
|
14
15
|
export interface MigratorOptions {
|
|
15
16
|
postgres?: ReturnType<typeof createPostgres>;
|
|
16
17
|
migrationTableName?: string;
|
|
@@ -24,6 +25,7 @@ export declare class Migrator {
|
|
|
24
25
|
private filenameRegExp;
|
|
25
26
|
private verbose;
|
|
26
27
|
constructor({ postgres, pathToMigrations, migrationTableName, verbose, }?: MigratorOptions);
|
|
28
|
+
end(): Promise<void>;
|
|
27
29
|
init(): Promise<boolean>;
|
|
28
30
|
isInstalled(): Promise<boolean>;
|
|
29
31
|
create(name: string | null | undefined, format?: 'ts' | 'sql'): Promise<string>;
|
package/dist/migrate.js
CHANGED
|
@@ -1,84 +1,58 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import
|
|
4
|
+
import {} from 'commander';
|
|
5
|
+
import {} from './cli.js';
|
|
5
6
|
import { createPostgres } from './postgres.js';
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
$ migrate down
|
|
12
|
-
$ migrate create <name> [--typescript]
|
|
13
|
-
`, {
|
|
14
|
-
description: 'PostgreSQL migration tool',
|
|
15
|
-
importMeta: import.meta,
|
|
16
|
-
});
|
|
17
|
-
let exitCode = 0;
|
|
18
|
-
try {
|
|
19
|
-
exitCode = await runCli(app.input, app.flags,
|
|
20
|
-
/* c8 ignore next 2 */
|
|
21
|
-
() => app.showHelp());
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
if (error instanceof CliError) {
|
|
25
|
-
exitCode = error.code;
|
|
7
|
+
export const asCli = (command, cli) => {
|
|
8
|
+
command.command('up').action(cli.wrap(async () => {
|
|
9
|
+
const migrator = new Migrator();
|
|
10
|
+
try {
|
|
11
|
+
await migrator.runMigrations('up');
|
|
26
12
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export async function runCli(input, flags, showHelp) {
|
|
43
|
-
const verbose = !flags.silent;
|
|
44
|
-
const [inputAction, ...inputArgs] = input.slice();
|
|
45
|
-
const migrator = new Migrator({ verbose });
|
|
46
|
-
async function run(action, ...args) {
|
|
13
|
+
finally {
|
|
14
|
+
await migrator.end();
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
17
|
+
command.command('down').action(cli.wrap(async () => {
|
|
18
|
+
const migrator = new Migrator();
|
|
19
|
+
try {
|
|
20
|
+
await migrator.runMigrations('down');
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
await migrator.end();
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
26
|
+
command.command('init').action(cli.wrap(async () => {
|
|
27
|
+
const migrator = new Migrator();
|
|
47
28
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
29
|
+
const created = await migrator.init();
|
|
30
|
+
if (created) {
|
|
31
|
+
cli.greenLine('Migrations table was successfully setup.');
|
|
51
32
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
case 'down':
|
|
55
|
-
await migrator.runMigrations(action);
|
|
56
|
-
break;
|
|
57
|
-
case 'init': {
|
|
58
|
-
const created = await migrator.init();
|
|
59
|
-
if (created) {
|
|
60
|
-
migrator.log(chalk.green('Migrations table was successfully setup.'));
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
migrator.log(chalk.green('Migrations table already existing.'));
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
case 'create': {
|
|
68
|
-
const createdMigration = await migrator.create(args[0], flags.typescript ? 'ts' : 'sql');
|
|
69
|
-
migrator.log(chalk.green('Created migration', createdMigration));
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
33
|
+
else {
|
|
34
|
+
cli.greenLine('Migrations table already existing.');
|
|
72
35
|
}
|
|
73
|
-
return 0;
|
|
74
36
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
throw new CliError(error.message, 1);
|
|
37
|
+
finally {
|
|
38
|
+
await migrator.end();
|
|
78
39
|
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
40
|
+
}));
|
|
41
|
+
command
|
|
42
|
+
.command('create')
|
|
43
|
+
.argument('<string>', 'name of migration')
|
|
44
|
+
.option('--typescript', 'use typescript')
|
|
45
|
+
.action(cli.wrap(async (name, flags) => {
|
|
46
|
+
const migrator = new Migrator();
|
|
47
|
+
try {
|
|
48
|
+
const createdMigration = await migrator.create(name, flags.typescript ? 'ts' : 'sql');
|
|
49
|
+
migrator.log(chalk.green('Created migration', createdMigration));
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
await migrator.end();
|
|
53
|
+
}
|
|
54
|
+
}));
|
|
55
|
+
};
|
|
82
56
|
export class Migrator {
|
|
83
57
|
constructor({ postgres = createPostgres(), pathToMigrations = path.resolve(process.cwd(), 'db', 'migrations'), migrationTableName = 'migrations', verbose = true, } = {}) {
|
|
84
58
|
this.filenameRegExp = /(\d+)_(.*)\.(js|ts|mjs|mts|sql)/;
|
|
@@ -87,6 +61,9 @@ export class Migrator {
|
|
|
87
61
|
this.migrationTableName = migrationTableName;
|
|
88
62
|
this.verbose = verbose;
|
|
89
63
|
}
|
|
64
|
+
end() {
|
|
65
|
+
return this.postgres.end();
|
|
66
|
+
}
|
|
90
67
|
async init() {
|
|
91
68
|
if (await this.isInstalled()) {
|
|
92
69
|
return false;
|
|
@@ -107,7 +84,7 @@ export class Migrator {
|
|
|
107
84
|
await fs.stat(this.pathToMigrations);
|
|
108
85
|
return true;
|
|
109
86
|
}
|
|
110
|
-
catch
|
|
87
|
+
catch {
|
|
111
88
|
return false;
|
|
112
89
|
}
|
|
113
90
|
}
|
|
@@ -115,6 +92,9 @@ export class Migrator {
|
|
|
115
92
|
if (!name) {
|
|
116
93
|
throw new Error('Missing positional argument <name>');
|
|
117
94
|
}
|
|
95
|
+
if (!(await this.isInstalled())) {
|
|
96
|
+
await this.init();
|
|
97
|
+
}
|
|
118
98
|
const existingMigrations = await this.getMigrations();
|
|
119
99
|
const lastVersion = existingMigrations.length
|
|
120
100
|
? existingMigrations[existingMigrations.length - 1].version
|
package/dist/postgres.d.ts
CHANGED
|
@@ -33,13 +33,13 @@ export declare class Transaction extends Connection {
|
|
|
33
33
|
* @param config
|
|
34
34
|
*/
|
|
35
35
|
export declare function createPostgres({ onError, url, ...config }?: PostgresOptions): {
|
|
36
|
-
insert: <T extends
|
|
37
|
-
query: <
|
|
38
|
-
first: <
|
|
39
|
-
all: <
|
|
40
|
-
get: <
|
|
41
|
-
withConnection: <
|
|
42
|
-
transaction: <
|
|
36
|
+
insert: <T extends QueryResultRow>(text: string | SQLStatement, values?: Value[]) => Promise<QueryResult<T>>;
|
|
37
|
+
query: <T extends QueryResultRow>(text: string | SQLStatement, values?: Value[]) => Promise<QueryResult<T>>;
|
|
38
|
+
first: <T>(text: string | SQLStatement, values?: Value[]) => Promise<T | null>;
|
|
39
|
+
all: <T>(text: string | SQLStatement, values?: Value[]) => Promise<T[]>;
|
|
40
|
+
get: <T>(text: string | SQLStatement, values?: Value[]) => Promise<T>;
|
|
41
|
+
withConnection: <T>(callback: (connection: Connection) => Promise<T>) => Promise<T>;
|
|
42
|
+
transaction: <T>(callback: (connection: Transaction) => Promise<T> | T) => Promise<T>;
|
|
43
43
|
instance: pg.Pool;
|
|
44
44
|
clear: (force?: boolean) => Promise<void>;
|
|
45
45
|
end(): Promise<void>;
|
package/dist/postgres.js
CHANGED
|
@@ -71,9 +71,9 @@ export class Transaction extends Connection {
|
|
|
71
71
|
*/
|
|
72
72
|
export function createPostgres({ onError, url = readEnv('POSTGRES_URL'), ...config } = {}) {
|
|
73
73
|
const pool = new pg.Pool({ connectionString: url, ...config });
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
74
|
+
pool.on('error', (e, client) => {
|
|
75
|
+
onError?.(e, client);
|
|
76
|
+
});
|
|
77
77
|
async function withConnection(callback) {
|
|
78
78
|
const client = await pool.connect();
|
|
79
79
|
try {
|
package/dist/routes.js
CHANGED
|
@@ -2,7 +2,7 @@ import {} from 'express';
|
|
|
2
2
|
import { parseExpressApp } from 'express-route-parser';
|
|
3
3
|
import { route } from './middleware.js';
|
|
4
4
|
export function createDocsRouter(app, extras = {}) {
|
|
5
|
-
return route(() => {
|
|
5
|
+
return route(async () => {
|
|
6
6
|
return {
|
|
7
7
|
...extras,
|
|
8
8
|
routes: parseExpressApp(app),
|
package/dist/sentry.js
CHANGED
package/dist/utils.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devmoods/express-extras",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "Kubernetes-ready utilities for rapid Node.js application development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
-
"bin": {
|
|
9
|
-
"migrate": "bin/migrate"
|
|
10
|
-
},
|
|
11
8
|
"author": {
|
|
12
9
|
"name": "hanse",
|
|
13
10
|
"email": "hanse@koren.im"
|
|
@@ -17,64 +14,59 @@
|
|
|
17
14
|
"url": "https://github.com/devmoods/express-extras.git"
|
|
18
15
|
},
|
|
19
16
|
"files": [
|
|
20
|
-
"
|
|
21
|
-
"dist",
|
|
22
|
-
"README.md"
|
|
17
|
+
"dist"
|
|
23
18
|
],
|
|
24
19
|
"license": "ISC",
|
|
25
20
|
"devDependencies": {
|
|
26
|
-
"@devmoods/eslint-config": "^1.
|
|
21
|
+
"@devmoods/eslint-config": "^1.14.0",
|
|
27
22
|
"@types/koa-compose": "^3.2.8",
|
|
28
|
-
"@types/node": "
|
|
23
|
+
"@types/node": "22.7.5",
|
|
29
24
|
"@types/supertest": "^6.0.2",
|
|
30
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
31
|
-
"@typescript-eslint/parser": "^
|
|
32
|
-
"@vitest/coverage-v8": "^1.
|
|
25
|
+
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
|
26
|
+
"@typescript-eslint/parser": "^8.8.1",
|
|
27
|
+
"@vitest/coverage-v8": "^2.1.2",
|
|
33
28
|
"chalk": "^5.3.0",
|
|
34
29
|
"eslint": "^8.57.0",
|
|
35
|
-
"eslint-plugin-import": "^2.
|
|
36
|
-
"eslint-plugin-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"eslint-plugin-react-hooks": "^4.6.2",
|
|
40
|
-
"faktory-worker": "^4.5.1",
|
|
41
|
-
"prettier": "3.3.1",
|
|
30
|
+
"eslint-plugin-import": "^2.31.0",
|
|
31
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
32
|
+
"faktory-worker": "^4.6.0",
|
|
33
|
+
"prettier": "3.3.3",
|
|
42
34
|
"supertest": "7.0.0",
|
|
43
35
|
"ts-node": "10.9.2",
|
|
44
|
-
"typescript": "5.
|
|
45
|
-
"vitest": "^1.
|
|
36
|
+
"typescript": "5.6.3",
|
|
37
|
+
"vitest": "^2.1.2"
|
|
46
38
|
},
|
|
47
39
|
"dependencies": {
|
|
48
40
|
"@devmoods/fetch": "^4.0.1",
|
|
49
|
-
"@sentry/node": "^8.
|
|
50
|
-
"@sentry/profiling-node": "^8.
|
|
41
|
+
"@sentry/node": "^8.34.0",
|
|
42
|
+
"@sentry/profiling-node": "^8.34.0",
|
|
51
43
|
"@types/bcrypt": "^5.0.2",
|
|
52
44
|
"@types/body-parser": "^1.19.5",
|
|
53
45
|
"@types/cookie-parser": "^1.4.7",
|
|
54
|
-
"@types/express": "^
|
|
55
|
-
"@types/jsonwebtoken": "^9.0.
|
|
56
|
-
"@types/nodemailer": "^6.4.
|
|
57
|
-
"@types/pg": "^8.11.
|
|
58
|
-
"@types/superagent": "^8.1.
|
|
59
|
-
"@types/uuid": "^
|
|
60
|
-
"ajv": "^8.
|
|
46
|
+
"@types/express": "^5.0.0",
|
|
47
|
+
"@types/jsonwebtoken": "^9.0.7",
|
|
48
|
+
"@types/nodemailer": "^6.4.16",
|
|
49
|
+
"@types/pg": "^8.11.10",
|
|
50
|
+
"@types/superagent": "^8.1.9",
|
|
51
|
+
"@types/uuid": "^10.0.0",
|
|
52
|
+
"ajv": "^8.17.1",
|
|
61
53
|
"bcrypt": "^5.1.1",
|
|
62
|
-
"body-parser": "^1.20.
|
|
54
|
+
"body-parser": "^1.20.3",
|
|
63
55
|
"commander": "^12.1.0",
|
|
64
56
|
"compose-middleware": "^5.0.1",
|
|
65
|
-
"cookie-parser": "^1.4.
|
|
57
|
+
"cookie-parser": "^1.4.7",
|
|
66
58
|
"dotenv": "^16.4.5",
|
|
67
|
-
"express": "^4.
|
|
59
|
+
"express": "^4.21.1",
|
|
68
60
|
"express-route-parser": "^1.0.5",
|
|
69
|
-
"helmet": "^
|
|
61
|
+
"helmet": "^8.0.0",
|
|
70
62
|
"jsonwebtoken": "^9.0.2",
|
|
71
63
|
"meow": "^13.2.0",
|
|
72
|
-
"nodemailer": "^6.9.
|
|
73
|
-
"pg": "^8.
|
|
74
|
-
"redis": "^4.
|
|
64
|
+
"nodemailer": "^6.9.15",
|
|
65
|
+
"pg": "^8.13.0",
|
|
66
|
+
"redis": "^4.7.0",
|
|
75
67
|
"sql-template-strings": "^2.2.2",
|
|
76
|
-
"uuid": "^
|
|
77
|
-
"vitest-fail-on-console": "^0.7.
|
|
68
|
+
"uuid": "^10.0.0",
|
|
69
|
+
"vitest-fail-on-console": "^0.7.1"
|
|
78
70
|
},
|
|
79
71
|
"prettier": {
|
|
80
72
|
"singleQuote": true
|
|
@@ -89,11 +81,11 @@
|
|
|
89
81
|
"node": ">=20.3.0 <23"
|
|
90
82
|
},
|
|
91
83
|
"scripts": {
|
|
92
|
-
"start": "node --no-warnings --enable-source-maps --loader ts-node/esm example/index.ts",
|
|
84
|
+
"start": "node --no-warnings --enable-source-maps --loader ts-node/esm example/src/index.ts --name example",
|
|
93
85
|
"start:worker": "node --no-warnings --enable-source-maps --loader ts-node/esm example/worker.ts",
|
|
94
86
|
"clean": "rm -rf dist",
|
|
95
87
|
"lint": "eslint src example",
|
|
96
|
-
"test": "./test.sh
|
|
88
|
+
"test": "./test.sh",
|
|
97
89
|
"build": "pnpm run clean && tsc --project tsconfig.build.json",
|
|
98
90
|
"format": "prettier --write '**/*.{js,css,md,ts,tsx}'"
|
|
99
91
|
}
|
package/bin/migrate
DELETED
package/bin/routes
DELETED
package/dist/cli/migrate.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config';
|
package/dist/cli/migrate.js
DELETED
package/dist/cli/routes.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/cli/routes.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { createFetch } from '@devmoods/fetch';
|
|
2
|
-
const port = process.env.PORT ?? 3000;
|
|
3
|
-
const fetch = createFetch({
|
|
4
|
-
getRootUrl: () => `http://localhost:${port}`,
|
|
5
|
-
getRequestId: () => 'routes',
|
|
6
|
-
});
|
|
7
|
-
const response = await fetch('/docs');
|
|
8
|
-
for (const route of response.jsonData.routes) {
|
|
9
|
-
process.stdout.write(`${route.method.toLocaleUpperCase().padEnd(5)} ${route.path}\n`);
|
|
10
|
-
}
|