@devmoods/express-extras 0.15.3 → 0.17.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 CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node --loader ts-node/esm
1
+ #!/usr/bin/env -S node --loader ts-node/esm
2
2
 
3
3
  import 'dotenv/config';
4
4
 
@@ -0,0 +1,3 @@
1
+ import { type Connection } from '../../postgres.js';
2
+ export declare function up(query: Connection['query']): Promise<void>;
3
+ export declare function down(query: Connection['query']): Promise<void>;
@@ -0,0 +1,8 @@
1
+ export async function up(query) {
2
+ await query('CREATE TABLE baz (id serial primary key)');
3
+ await query('CREATE TABLE foo (id serial primary key)');
4
+ }
5
+ export async function down(query) {
6
+ await query('DROP TABLE foo');
7
+ await query('DROP TABLE baz');
8
+ }
package/dist/email.d.ts CHANGED
@@ -12,4 +12,5 @@ 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
16
  };
package/dist/email.js CHANGED
@@ -17,5 +17,5 @@ export function createEmail({ host, port, user, pass, senderName, senderAddress,
17
17
  });
18
18
  getLogger('core').info('email-sent', { email: result });
19
19
  };
20
- return { send };
20
+ return { send, transporter };
21
21
  }
package/dist/logger.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CreateSentry } from './sentry.js';
2
- export declare type LoggerContext = Record<string, any>;
2
+ export type LoggerContext = Record<string, any>;
3
3
  export interface LoggerOptions {
4
4
  /**
5
5
  * Name of the logger
@@ -16,7 +16,7 @@ export interface LoggerOptions {
16
16
  }
17
17
  export declare function attachSentryClientToLoggers(sentryClient: CreateSentry['client']): void;
18
18
  export declare function setGlobalLoggerContext(getContext: () => LoggerContext): void;
19
- export declare type Logger = ReturnType<typeof createLogger>;
19
+ export type Logger = ReturnType<typeof createLogger>;
20
20
  export declare function createLogger({ name, getContext, silent, }: LoggerOptions): {
21
21
  debug(message: string, context?: {
22
22
  [key: string]: any;
package/dist/migrate.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { createPostgres } from './postgres.js';
1
+ import { type Connection, createPostgres } from './postgres.js';
2
2
  interface Migration {
3
3
  name: string;
4
4
  filename: string;
@@ -18,14 +18,14 @@ export declare class Migrator {
18
18
  private filenameRegExp;
19
19
  private verbose;
20
20
  constructor({ postgres, pathToMigrations, migrationTableName, verbose, }?: MigratorOptions);
21
- init(): Promise<import("pg").QueryResult<any>>;
21
+ init(): Promise<import("pg").QueryResult<import("pg").QueryResultRow>>;
22
22
  create(name: string | null | undefined): Promise<string>;
23
- runMigrations(direction: 'up' | 'down'): Promise<void>;
23
+ runMigrations(direction: 'up' | 'down'): Promise<number>;
24
24
  log(...args: any[]): void;
25
- executeMigration(migrations: Migration[], currentVersion: number, direction: 'up' | 'down'): Promise<void>;
26
- queryWithLog(sql: string): Promise<import("pg").QueryResult<any>>;
27
- migrate(migration: Migration, direction: 'up' | 'down'): Promise<any>;
28
- updateCurrentVersion(version: number): Promise<import("pg").QueryResult<any>>;
25
+ executeMigration(migrations: Migration[], currentVersion: number, direction: 'up' | 'down'): Promise<number>;
26
+ readMigrationFile(filename: string): Promise<any>;
27
+ migrate(tx: Connection, migration: Migration, direction: 'up' | 'down'): Promise<void>;
28
+ updateCurrentVersion(connection: Connection, version: number): Promise<import("pg").QueryResult<import("pg").QueryResultRow>>;
29
29
  getCurrentVersion(): Promise<number>;
30
30
  getMigrations(): Promise<{
31
31
  filename: string;
package/dist/migrate.js CHANGED
@@ -54,7 +54,7 @@ Usage
54
54
  }
55
55
  export class Migrator {
56
56
  constructor({ postgres = createPostgres(), pathToMigrations = path.resolve(process.cwd(), 'db', 'migrations'), migrationTableName = 'migrations', verbose = true, } = {}) {
57
- this.filenameRegExp = /(\d+)_(.*)\.(js|ts|mjs|mts)/;
57
+ this.filenameRegExp = /(\d+)_(.*)\.(js|ts|mjs|mts|sql)/;
58
58
  this.postgres = postgres;
59
59
  this.pathToMigrations = pathToMigrations;
60
60
  this.migrationTableName = migrationTableName;
@@ -100,46 +100,77 @@ export class Migrator {
100
100
  const pendingMigrations = this.getPendingMigrations(migrations, currentVersion);
101
101
  if (!pendingMigrations.length) {
102
102
  this.log(chalk.green('No pending migrations'));
103
- return;
103
+ return currentVersion;
104
104
  }
105
105
  for (const migration of pendingMigrations) {
106
106
  this.log('Running migration', migration.filename);
107
- await this.migrate(migration, direction);
108
- await this.updateCurrentVersion(migration.version);
107
+ await this.postgres.transaction(async (tx) => {
108
+ await this.migrate(tx, migration, direction);
109
+ await this.updateCurrentVersion(tx, migration.version);
110
+ });
109
111
  }
110
112
  this.log(chalk.green('Done!'));
113
+ return await this.getCurrentVersion();
111
114
  }
112
- else {
115
+ else if (direction === 'down') {
113
116
  const previousMigrations = this.getPreviousMigrations(migrations, currentVersion);
114
117
  const previousMigration = previousMigrations[0];
115
118
  const updatedVersion = previousMigration ? previousMigration.version : 0;
116
119
  const migrationToRollback = migrations.find((migration) => migration.version === currentVersion);
117
120
  if (!migrationToRollback) {
118
121
  this.log(chalk.green('No migrations have been run, so nothing to rollback to.'));
119
- return;
122
+ return currentVersion;
120
123
  }
121
124
  this.log('Rolling back migration', migrationToRollback.filename);
122
- await this.migrate(migrationToRollback, 'down');
123
- await this.updateCurrentVersion(updatedVersion);
125
+ await this.postgres.transaction(async (tx) => {
126
+ await this.migrate(tx, migrationToRollback, 'down');
127
+ await this.updateCurrentVersion(tx, updatedVersion);
128
+ });
129
+ return await this.getCurrentVersion();
124
130
  }
131
+ throw new Error(`Invalid direction ${direction}`);
125
132
  }
126
- queryWithLog(sql) {
127
- this.log(chalk.yellow(sql.toString()));
128
- return this.postgres.query(sql);
133
+ async readMigrationFile(filename) {
134
+ if (!filename.endsWith('.sql')) {
135
+ return import(filename);
136
+ }
137
+ const content = await fs.readFile(filename, 'utf-8');
138
+ const [up, down] = content.split('-- ROLLBACK --');
139
+ return {
140
+ up() {
141
+ return up.trim();
142
+ },
143
+ down() {
144
+ return (down || '').trim();
145
+ },
146
+ };
129
147
  }
130
- async migrate(migration, direction) {
131
- const migrator = await import(migration.filename);
148
+ async migrate(tx, migration, direction) {
149
+ const migrator = await this.readMigrationFile(migration.filename);
132
150
  if (!migrator.up || !migrator.down) {
133
151
  throw new Error('Migrations must export both an up() and a down() function.');
134
152
  }
135
- const returnValue = migrator[direction](this.queryWithLog.bind(this));
136
- if (typeof returnValue === 'string') {
137
- return this.queryWithLog(returnValue);
153
+ try {
154
+ const queryWithLog = (sql) => {
155
+ this.log(chalk.yellow(sql.toString()));
156
+ return tx.query(sql);
157
+ };
158
+ const returnValue = await migrator[direction](queryWithLog.bind(tx));
159
+ if (typeof returnValue === 'string') {
160
+ if (returnValue !== '') {
161
+ await queryWithLog(returnValue);
162
+ }
163
+ }
164
+ else {
165
+ await returnValue;
166
+ }
167
+ }
168
+ catch (error) {
169
+ throw new Error(`Migration failed: ${error.message}`);
138
170
  }
139
- return returnValue;
140
171
  }
141
- updateCurrentVersion(version) {
142
- return this.postgres.query(`INSERT INTO ${this.migrationTableName} (version, run_at) VALUES ($1, $2)`, [version, new Date()]);
172
+ updateCurrentVersion(connection, version) {
173
+ return connection.query(`INSERT INTO ${this.migrationTableName} (version, run_at) VALUES ($1, $2)`, [version, new Date()]);
143
174
  }
144
175
  async getCurrentVersion() {
145
176
  const result = await this.postgres.first(`SELECT version FROM ${this.migrationTableName} ORDER BY run_at DESC LIMIT 1`);
@@ -1,4 +1,4 @@
1
- import pg from 'pg';
1
+ import pg, { type PoolClient, type QueryResult, type QueryResultRow } from 'pg';
2
2
  import { SQL, type SQLStatement } from 'sql-template-strings';
3
3
  export interface PostgresOptions extends pg.PoolConfig {
4
4
  onError?: (error: Error, client: any) => void;
@@ -9,6 +9,18 @@ export declare class DoesNotExistError extends Error {
9
9
  export declare class MultipleRowsReturnedError extends Error {
10
10
  constructor(message: string);
11
11
  }
12
+ type Value = null | string | number | Date;
13
+ export declare class Connection {
14
+ client: PoolClient;
15
+ constructor(client: PoolClient);
16
+ query<T extends QueryResultRow>(text: string | SQLStatement, values?: Value[]): Promise<QueryResult<T>>;
17
+ all<T>(text: string | SQLStatement, values?: Value[]): Promise<T[]>;
18
+ insert<T extends QueryResultRow>(text: string | SQLStatement, values?: Value[]): Promise<QueryResult<T>>;
19
+ first<T>(text: string | SQLStatement, values?: Value[]): Promise<T | null>;
20
+ get<T>(text: string | SQLStatement, values?: Value[]): Promise<T>;
21
+ }
22
+ export declare class Transaction extends Connection {
23
+ }
12
24
  /**
13
25
  * Create a new Postgres connection pool with
14
26
  * conveience methods for executing queries using
@@ -17,171 +29,16 @@ export declare class MultipleRowsReturnedError extends Error {
17
29
  * @param config
18
30
  */
19
31
  export declare function createPostgres({ onError, ...config }?: PostgresOptions): {
20
- withConnection: (callback: (query: {
21
- query: {
22
- <T extends pg.Submittable>(queryStream: T): T;
23
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
24
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
25
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
26
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
27
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
28
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
29
- };
30
- first: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
31
- query: {
32
- <T extends pg.Submittable>(queryStream: T): T;
33
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
34
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
35
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
36
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
37
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
38
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
39
- };
40
- }) => Promise<T_1 | null>;
41
- all: <T_2>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
42
- query: {
43
- <T extends pg.Submittable>(queryStream: T): T;
44
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
45
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
46
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
47
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
48
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
49
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
50
- };
51
- }) => Promise<T_2[]>;
52
- get: <T_3>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
53
- query: {
54
- <T extends pg.Submittable>(queryStream: T): T;
55
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
56
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
57
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
58
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
59
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
60
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
61
- };
62
- }) => Promise<T_3>;
63
- insert: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
64
- query: {
65
- <T extends pg.Submittable>(queryStream: T): T;
66
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
67
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
68
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
69
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
70
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
71
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
72
- };
73
- }) => Promise<T_1 | null>;
74
- }) => Promise<void>) => Promise<void>;
75
- transaction: <T_4>(callback: (query: {
76
- query: {
77
- <T extends pg.Submittable>(queryStream: T): T;
78
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
79
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
80
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
81
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
82
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
83
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
84
- };
85
- first: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
86
- query: {
87
- <T extends pg.Submittable>(queryStream: T): T;
88
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
89
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
90
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
91
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
92
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
93
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
94
- };
95
- }) => Promise<T_1 | null>;
96
- all: <T_2>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
97
- query: {
98
- <T extends pg.Submittable>(queryStream: T): T;
99
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
100
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
101
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
102
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
103
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
104
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
105
- };
106
- }) => Promise<T_2[]>;
107
- get: <T_3>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
108
- query: {
109
- <T extends pg.Submittable>(queryStream: T): T;
110
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
111
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
112
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
113
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
114
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
115
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
116
- };
117
- }) => Promise<T_3>;
118
- insert: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
119
- query: {
120
- <T extends pg.Submittable>(queryStream: T): T;
121
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
122
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
123
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
124
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
125
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
126
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
127
- };
128
- }) => Promise<T_1 | null>;
129
- }) => T_4 | Promise<T_4>) => Promise<T_4>;
32
+ insert: <T extends pg.QueryResultRow>(text: string | SQLStatement, values?: Value[] | undefined) => Promise<pg.QueryResult<T>>;
33
+ query: <T_1 extends pg.QueryResultRow>(text: string | SQLStatement, values?: Value[] | undefined) => Promise<pg.QueryResult<T_1>>;
34
+ first: <T_2>(text: string | SQLStatement, values?: Value[] | undefined) => Promise<T_2 | null>;
35
+ all: <T_3>(text: string | SQLStatement, values?: Value[] | undefined) => Promise<T_3[]>;
36
+ get: <T_4>(text: string | SQLStatement, values?: Value[] | undefined) => Promise<T_4>;
37
+ withConnection: <T_5>(callback: (connection: Connection) => Promise<T_5>) => Promise<T_5>;
38
+ transaction: <T_6>(callback: (connection: Transaction) => T_6 | Promise<T_6>) => Promise<T_6>;
130
39
  instance: pg.Pool;
131
40
  clear: (force?: boolean) => Promise<void>;
132
41
  end(): Promise<void>;
133
- query: {
134
- <T extends pg.Submittable>(queryStream: T): T;
135
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
136
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
137
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
138
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
139
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
140
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
141
- };
142
- first: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
143
- query: {
144
- <T extends pg.Submittable>(queryStream: T): T;
145
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
146
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
147
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
148
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
149
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
150
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
151
- };
152
- }) => Promise<T_1 | null>;
153
- all: <T_2>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
154
- query: {
155
- <T extends pg.Submittable>(queryStream: T): T;
156
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
157
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
158
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
159
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
160
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
161
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
162
- };
163
- }) => Promise<T_2[]>;
164
- get: <T_3>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
165
- query: {
166
- <T extends pg.Submittable>(queryStream: T): T;
167
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
168
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
169
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
170
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
171
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
172
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
173
- };
174
- }) => Promise<T_3>;
175
- insert: <T_1>(text: string | SQLStatement, values?: (null | string | number | Date)[], options?: {
176
- query: {
177
- <T extends pg.Submittable>(queryStream: T): T;
178
- <R extends any[] = any[], I extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I>, values?: I | undefined): Promise<pg.QueryArrayResult<R>>;
179
- <R_1 extends pg.QueryResultRow = any, I_1 extends any[] = any[]>(queryConfig: pg.QueryConfig<I_1>): Promise<pg.QueryResult<R_1>>;
180
- <R_2 extends pg.QueryResultRow = any, I_2 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_2>, values?: I_2 | undefined): Promise<pg.QueryResult<R_2>>;
181
- <R_3 extends any[] = any[], I_3 extends any[] = any[]>(queryConfig: pg.QueryArrayConfig<I_3>, callback: (err: Error, result: pg.QueryArrayResult<R_3>) => void): void;
182
- <R_4 extends pg.QueryResultRow = any, I_4 extends any[] = any[]>(queryTextOrConfig: string | pg.QueryConfig<I_4>, callback: (err: Error, result: pg.QueryResult<R_4>) => void): void;
183
- <R_5 extends pg.QueryResultRow = any, I_5 extends any[] = any[]>(queryText: string, values: I_5, callback: (err: Error, result: pg.QueryResult<R_5>) => void): void;
184
- };
185
- }) => Promise<T_1 | null>;
186
42
  };
187
43
  export declare const sql: typeof SQL;
44
+ export {};
package/dist/postgres.js CHANGED
@@ -12,6 +12,40 @@ export class MultipleRowsReturnedError extends Error {
12
12
  this.name = 'MultipleRowsReturnedError';
13
13
  }
14
14
  }
15
+ export class Connection {
16
+ constructor(client) {
17
+ this.client = client;
18
+ }
19
+ async query(text, values) {
20
+ return this.client.query(text, values);
21
+ }
22
+ async all(text, values) {
23
+ const result = await this.client.query(text, values);
24
+ if (result.rows) {
25
+ return result.rows;
26
+ }
27
+ return [];
28
+ }
29
+ async insert(text, values) {
30
+ return await this.client.query(text, values);
31
+ }
32
+ async first(text, values) {
33
+ const result = await this.client.query(text, values);
34
+ return result.rows && result.rows.length ? result.rows[0] : null;
35
+ }
36
+ async get(text, values) {
37
+ const result = await this.client.query(text, values);
38
+ if (result.rowCount === 0) {
39
+ throw new DoesNotExistError('Row matching query not found');
40
+ }
41
+ if (result.rowCount > 1) {
42
+ throw new MultipleRowsReturnedError(`Call to postgres.get() returned ${result.rowCount} rows. Expected 1.`);
43
+ }
44
+ return result.rows[0];
45
+ }
46
+ }
47
+ export class Transaction extends Connection {
48
+ }
15
49
  /**
16
50
  * Create a new Postgres connection pool with
17
51
  * conveience methods for executing queries using
@@ -22,50 +56,25 @@ export class MultipleRowsReturnedError extends Error {
22
56
  export function createPostgres({ onError = () => { }, ...config } = {}) {
23
57
  const pool = new pg.Pool(config);
24
58
  pool.on('error', onError);
25
- const defaultQuery = pool.query.bind(pool);
26
59
  async function withConnection(callback) {
27
60
  const client = await pool.connect();
28
61
  try {
29
- const result = await callback(makeQueryFunctions(client.query.bind(client)));
62
+ const result = await callback(new Connection(client));
30
63
  return result;
31
64
  }
32
65
  finally {
33
66
  client.release();
34
67
  }
35
68
  }
36
- function makeQueryFunctions(defaultQuery) {
37
- async function all(text, values, options = { query: defaultQuery }) {
38
- const result = await options.query(text, values);
39
- if (result.rows) {
40
- return result.rows;
41
- }
42
- return [];
43
- }
44
- async function first(text, values, options = { query: defaultQuery }) {
45
- const result = await options.query(text, values);
46
- return result.rows && result.rows.length ? result.rows[0] : null;
47
- }
48
- async function get(text, values, options = { query: defaultQuery }) {
49
- const result = await options.query(text, values);
50
- if (result.rowCount === 0) {
51
- throw new DoesNotExistError('Row matching query not found');
52
- }
53
- if (result.rowCount > 1) {
54
- throw new MultipleRowsReturnedError(`Call to postgres.get() returned ${result.rowCount} rows. Expected 1.`);
55
- }
56
- return result.rows[0];
57
- }
58
- return { query: defaultQuery, first, all, get, insert: first };
59
- }
60
69
  /**
61
70
  * Wipe the database schema
62
71
  */
63
72
  async function clear(force = false) {
64
73
  if (!force)
65
74
  return;
66
- return withConnection(async ({ query }) => {
67
- await query('DROP SCHEMA public CASCADE');
68
- await query(`CREATE SCHEMA public`);
75
+ return withConnection(async (connection) => {
76
+ await connection.query('DROP SCHEMA public CASCADE');
77
+ await connection.query(`CREATE SCHEMA public`);
69
78
  });
70
79
  }
71
80
  /**
@@ -75,7 +84,7 @@ export function createPostgres({ onError = () => { }, ...config } = {}) {
75
84
  const client = await pool.connect();
76
85
  try {
77
86
  await client.query('BEGIN');
78
- const result = await callback(makeQueryFunctions(client.query.bind(client)));
87
+ const result = await callback(new Transaction(client));
79
88
  await client.query('COMMIT');
80
89
  return result;
81
90
  }
@@ -87,8 +96,37 @@ export function createPostgres({ onError = () => { }, ...config } = {}) {
87
96
  client.release();
88
97
  }
89
98
  }
99
+ const query = async (...args) => {
100
+ return await withConnection(async (connection) => {
101
+ return connection.query(...args);
102
+ });
103
+ };
104
+ const insert = async (...args) => {
105
+ return await withConnection(async (connection) => {
106
+ return connection.insert(...args);
107
+ });
108
+ };
109
+ const first = async (...args) => {
110
+ return await withConnection(async (connection) => {
111
+ return connection.first(...args);
112
+ });
113
+ };
114
+ const all = async (...args) => {
115
+ return await withConnection(async (connection) => {
116
+ return connection.all(...args);
117
+ });
118
+ };
119
+ const get = async (...args) => {
120
+ return await withConnection(async (connection) => {
121
+ return connection.get(...args);
122
+ });
123
+ };
90
124
  return {
91
- ...makeQueryFunctions(defaultQuery),
125
+ insert,
126
+ query,
127
+ first,
128
+ all,
129
+ get,
92
130
  withConnection,
93
131
  transaction,
94
132
  instance: pool,
package/dist/redis.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare type RedisClient = ReturnType<typeof createRedis>;
1
+ export type RedisClient = ReturnType<typeof createRedis>;
2
2
  export interface RedisOptions {
3
3
  url?: string;
4
4
  onError: (error: Error) => void;
@@ -181,6 +181,8 @@ export declare function createRedis({ url, onError, }: RedisOptions): import("@r
181
181
  bf: {
182
182
  ADD: typeof import("@redis/bloom/dist/commands/bloom/ADD.js");
183
183
  add: typeof import("@redis/bloom/dist/commands/bloom/ADD.js");
184
+ CARD: typeof import("@redis/bloom/dist/commands/bloom/CARD.js");
185
+ card: typeof import("@redis/bloom/dist/commands/bloom/CARD.js");
184
186
  EXISTS: typeof import("@redis/bloom/dist/commands/bloom/EXISTS.js");
185
187
  exists: typeof import("@redis/bloom/dist/commands/bloom/EXISTS.js");
186
188
  INFO: typeof import("@redis/bloom/dist/commands/bloom/INFO.js");
package/dist/sentry.d.ts CHANGED
@@ -3,7 +3,7 @@ import { type Application } from 'express';
3
3
  export type { Sentry };
4
4
  export interface SentryOptions extends Sentry.NodeOptions {
5
5
  }
6
- export declare type CreateSentry = ReturnType<typeof createSentry>;
6
+ export type CreateSentry = ReturnType<typeof createSentry>;
7
7
  /**
8
8
  * Create a pre-configured Sentry client
9
9
  */
@@ -22,9 +22,9 @@ export declare function createSentryOptions(app: Application | null, options?: S
22
22
  release?: string | undefined;
23
23
  environment?: string | undefined;
24
24
  debug?: boolean | undefined;
25
- dsn: string | undefined;
26
25
  instrumenter?: import("@sentry/types").Instrumenter | undefined;
27
26
  sampleRate?: number | undefined;
27
+ dsn: string | undefined;
28
28
  enabled?: boolean | undefined;
29
29
  attachStacktrace?: boolean | undefined;
30
30
  autoSessionTracking?: boolean | undefined;
@@ -32,6 +32,7 @@ export declare function createSentryOptions(app: Application | null, options?: S
32
32
  dist?: string | undefined;
33
33
  transportOptions?: Partial<import("@sentry/node/types/transports/http.js").NodeTransportOptions> | undefined;
34
34
  tracesSampleRate: number;
35
+ enableTracing?: boolean | undefined;
35
36
  initialScope?: import("@sentry/types").CaptureContext | undefined;
36
37
  maxBreadcrumbs?: number | undefined;
37
38
  maxValueLength?: number | undefined;
@@ -39,18 +40,24 @@ export declare function createSentryOptions(app: Application | null, options?: S
39
40
  normalizeMaxBreadth?: number | undefined;
40
41
  shutdownTimeout?: number | undefined;
41
42
  ignoreErrors?: (string | RegExp)[] | undefined;
43
+ ignoreTransactions?: (string | RegExp)[] | undefined;
42
44
  tunnel?: string | undefined;
43
45
  sendDefaultPii?: boolean | undefined;
44
46
  _metadata?: import("@sentry/types").SdkMetadata | undefined;
45
47
  _experiments?: {
46
48
  [key: string]: any;
47
49
  } | undefined;
50
+ allowUrls?: (string | RegExp)[] | undefined;
51
+ denyUrls?: (string | RegExp)[] | undefined;
48
52
  tracesSampler?: ((samplingContext: import("@sentry/types").SamplingContext) => number | boolean) | undefined;
49
- beforeSend?: ((event: Sentry.Event, hint: Sentry.EventHint) => Sentry.Event | PromiseLike<Sentry.Event | null> | null) | undefined;
50
- beforeSendTransaction?: ((event: Sentry.Event, hint: Sentry.EventHint) => Sentry.Event | PromiseLike<Sentry.Event | null> | null) | undefined;
53
+ beforeSend?: ((event: import("@sentry/types").ErrorEvent, hint: Sentry.EventHint) => Sentry.Event | PromiseLike<Sentry.Event | null> | null) | undefined;
54
+ beforeSendTransaction?: ((event: import("@sentry/types").TransactionEvent, hint: Sentry.EventHint) => Sentry.Event | PromiseLike<Sentry.Event | null> | null) | undefined;
51
55
  beforeBreadcrumb?: ((breadcrumb: Sentry.Breadcrumb, hint?: Sentry.BreadcrumbHint | undefined) => Sentry.Breadcrumb | null) | undefined;
56
+ profilesSampleRate?: number | undefined;
57
+ profilesSampler?: ((samplingContext: import("@sentry/types").SamplingContext) => number | boolean) | undefined;
52
58
  serverName?: string | undefined;
59
+ includeLocalVariables?: boolean | undefined;
53
60
  tracePropagationTargets?: import("@sentry/types").TracePropagationTargets | undefined;
54
- shouldCreateSpanForRequest?(url: string): boolean;
55
- onFatalError?(error: Error): void;
61
+ shouldCreateSpanForRequest?(this: void, url: string): boolean;
62
+ onFatalError?(this: void, error: Error): void;
56
63
  };
package/dist/slack.d.ts CHANGED
@@ -2,8 +2,8 @@ export interface SlackOptions {
2
2
  webhookUrl?: string;
3
3
  dryRun?: boolean;
4
4
  }
5
- declare type Message = string;
6
- declare type Blocks = unknown[];
5
+ type Message = string;
6
+ type Blocks = unknown[];
7
7
  /**
8
8
  * Send messages to Slack using Incoming Webhooks
9
9
  *
@@ -1,6 +1,6 @@
1
1
  import { type Options } from 'ajv';
2
2
  import { type RequestHandler } from 'express';
3
- export declare type ValidationSchema = {
3
+ export type ValidationSchema = {
4
4
  type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';
5
5
  format?: string;
6
6
  minimum?: number;
@@ -30,7 +30,7 @@ export declare type ValidationSchema = {
30
30
  export declare function validateBody(schema: ValidationSchema): RequestHandler;
31
31
  export declare function validateQuery(schema: ValidationSchema): RequestHandler;
32
32
  export declare function validateParams(schema: ValidationSchema): RequestHandler;
33
- export declare type ValidationResult = {
33
+ export type ValidationResult = {
34
34
  isValid: true;
35
35
  errors: null;
36
36
  } | {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devmoods/express-extras",
3
- "version": "0.15.3",
3
+ "version": "0.17.0",
4
4
  "description": "Kubernetes-ready utilities for rapid Node.js application development",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  "start": "ts-node --esm example/index.ts",
13
13
  "clean": "rm -rf dist",
14
14
  "lint": "eslint src",
15
- "test": "NODE_ENV=test jest",
15
+ "test": "NODE_ENV=test vitest",
16
16
  "build": "npm run clean && tsc --project tsconfig.build.json",
17
17
  "prepublishOnly": "npm run clean && npm run build",
18
18
  "prettier": "prettier --write '**/*.{js,css,md,ts,tsx}'",
@@ -34,42 +34,41 @@
34
34
  ],
35
35
  "license": "ISC",
36
36
  "devDependencies": {
37
- "@devmoods/eslint-config": "^1.0.0",
38
- "@types/jest": "29.2.2",
39
- "@types/node": "18.11.9",
37
+ "@devmoods/eslint-config": "^1.1.0",
38
+ "@types/node": "20.2.5",
40
39
  "@types/supertest": "2.0.12",
41
- "@typescript-eslint/eslint-plugin": "^5.42.1",
42
- "@typescript-eslint/parser": "^5.42.1",
43
- "eslint": "^8.27.0",
44
- "eslint-plugin-jsx-a11y": "^6.6.1",
40
+ "@typescript-eslint/eslint-plugin": "^5.59.7",
41
+ "@typescript-eslint/parser": "^5.59.7",
42
+ "chalk": "^5.2.0",
43
+ "eslint": "^8.41.0",
44
+ "eslint-plugin-jsx-a11y": "^6.7.1",
45
45
  "eslint-plugin-prettier": "^4.2.1",
46
- "eslint-plugin-react": "^7.31.10",
46
+ "eslint-plugin-react": "^7.32.2",
47
47
  "eslint-plugin-react-hooks": "^4.6.0",
48
48
  "import-sort-cli": "6.0.0",
49
49
  "import-sort-style-module": "6.0.0",
50
50
  "isomorphic-fetch": "3.0.0",
51
- "jest": "29.3.1",
52
- "prettier": "2.7.1",
53
- "supertest": "6.3.1",
54
- "ts-jest": "29.0.3",
51
+ "prettier": "2.8.8",
52
+ "supertest": "6.3.3",
55
53
  "ts-node": "10.9.1",
56
- "typescript": "4.8.4"
54
+ "typescript": "5.0.4",
55
+ "vitest": "^0.31.1"
57
56
  },
58
57
  "dependencies": {
59
58
  "@devmoods/fetch": "^3.3.0",
60
- "@godaddy/terminus": "^4.11.2",
61
- "@sentry/node": "^7.19.0",
62
- "@sentry/tracing": "^7.19.0",
59
+ "@godaddy/terminus": "^4.12.0",
60
+ "@sentry/node": "^7.53.1",
61
+ "@sentry/tracing": "^7.53.1",
63
62
  "@types/bcrypt": "^5.0.0",
64
63
  "@types/bunyan": "^1.8.8",
65
64
  "@types/cls-hooked": "^4.3.3",
66
65
  "@types/cookie-parser": "^1.4.3",
67
- "@types/express": "^4.17.14",
68
- "@types/jsonwebtoken": "^8.5.9",
69
- "@types/nodemailer": "^6.4.6",
70
- "@types/pg": "^8.6.5",
71
- "@types/uuid": "^8.3.4",
72
- "ajv": "^8.11.0",
66
+ "@types/express": "^4.17.17",
67
+ "@types/jsonwebtoken": "^9.0.2",
68
+ "@types/nodemailer": "^6.4.8",
69
+ "@types/pg": "^8.10.1",
70
+ "@types/uuid": "^9.0.1",
71
+ "ajv": "^8.12.0",
73
72
  "bcrypt": "^5.1.0",
74
73
  "bunyan": "^1.8.15",
75
74
  "cls-hooked": "^4.2.2",
@@ -77,12 +76,12 @@
77
76
  "cookie-parser": "^1.4.6",
78
77
  "dotenv": "^16.0.3",
79
78
  "express": "^4.18.2",
80
- "helmet": "^6.0.0",
81
- "jsonwebtoken": "^8.5.1",
82
- "meow": "^11.0.0",
83
- "nodemailer": "^6.8.0",
84
- "pg": "^8.8.0",
85
- "redis": "^4.5.0",
79
+ "helmet": "^7.0.0",
80
+ "jsonwebtoken": "^9.0.0",
81
+ "meow": "^12.0.1",
82
+ "nodemailer": "^6.9.3",
83
+ "pg": "^8.11.0",
84
+ "redis": "^4.6.6",
86
85
  "sql-template-strings": "^2.2.2",
87
86
  "uuid": "^9.0.0"
88
87
  },
@@ -1 +0,0 @@
1
- export {};
@@ -1,8 +0,0 @@
1
- import { createAuthToken } from '../auth.js';
2
- test('createAuthToken', async () => {
3
- process.env.APP_JWT_SECRET = 'test';
4
- const first = createAuthToken({});
5
- await new Promise((resolve) => setTimeout(resolve, 1000));
6
- const second = createAuthToken({});
7
- expect(first).not.toEqual(second);
8
- });