@devmoods/express-extras 0.64.0 → 0.65.1
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/README.md +0 -111
- package/dist/auth/emailAndPassword.js +2 -1
- package/dist/auth/google.d.ts +4 -4
- package/dist/auth/google.js +14 -11
- package/dist/auth/passwordless.js +2 -1
- package/dist/auth/token.js +6 -6
- package/dist/auth/types.d.ts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +17 -10
- package/dist/cache.d.ts +3 -0
- package/dist/cache.js +3 -2
- package/dist/channels.d.ts +6 -5
- package/dist/channels.js +9 -4
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +72 -66
- package/dist/config.js +38 -36
- package/dist/context.d.ts +9 -2
- package/dist/context.js +18 -9
- package/dist/csrf.js +6 -6
- package/dist/email.d.ts +1 -1
- package/dist/email.js +3 -3
- package/dist/errors.js +1 -1
- package/dist/faktory.d.ts +1 -1
- package/dist/faktory.js +5 -15
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -3
- package/dist/listen.d.ts +4 -4
- package/dist/listen.js +41 -43
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +11 -5
- package/dist/manage.d.ts +4 -6
- package/dist/manage.js +41 -37
- package/dist/middleware.d.ts +3 -0
- package/dist/middleware.js +24 -7
- package/dist/rate-limit.d.ts +1 -0
- package/dist/rate-limit.js +25 -3
- package/dist/redis.d.ts +1 -1
- package/dist/redis.js +4 -4
- package/dist/sentry.js +11 -5
- package/dist/setupTests.global.d.ts +2 -0
- package/dist/setupTests.global.js +4 -0
- package/dist/setupTests.js +3 -0
- package/dist/slack.js +2 -2
- package/dist/utils.d.ts +0 -13
- package/dist/utils.js +0 -21
- package/dist/validate.js +7 -4
- package/dist/vite/__tests__/fixtures/src/entry-server.d.ts +5 -0
- package/dist/vite/__tests__/fixtures/src/entry-server.js +15 -0
- package/dist/vite/defineViteConfig.js +11 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +3 -0
- package/dist/vite/ssr.d.ts +1 -0
- package/dist/vite/ssr.js +9 -4
- package/dist/vitest/index.d.ts +5 -0
- package/dist/vitest/index.js +24 -0
- package/dist/vitest/matchers.d.ts +1 -1
- package/dist/vitest/matchers.js +6 -2
- package/dist/vitest/testClient.d.ts +30 -0
- package/dist/vitest/testClient.js +98 -0
- package/dist/webapi.js +4 -0
- package/package.json +31 -42
- package/dist/__tests__/__migrations__/1_a.d.ts +0 -3
- package/dist/__tests__/__migrations__/1_a.js +0 -9
- package/dist/migrate.d.ts +0 -47
- package/dist/migrate.js +0 -255
- package/dist/postgres-ts-generator.d.ts +0 -11
- package/dist/postgres-ts-generator.js +0 -114
- package/dist/postgres.d.ts +0 -71
- package/dist/postgres.js +0 -261
- package/dist/sql.d.ts +0 -33
- package/dist/sql.js +0 -135
- package/dist/vite.d.ts +0 -1
- package/dist/vite.js +0 -1
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
|
-
import { resolve, dirname } from 'node:path';
|
|
3
|
-
import {} from 'pg-structure';
|
|
4
|
-
import { pgStructure } from 'pg-structure/dist/main.js';
|
|
5
|
-
/**
|
|
6
|
-
* Converts PostgreSQL data type to TypeScript type
|
|
7
|
-
*/
|
|
8
|
-
function pgTypeToTsType(pgType, isNullable) {
|
|
9
|
-
const nullableSuffix = isNullable ? ' | null' : '';
|
|
10
|
-
switch (pgType.name.toLowerCase()) {
|
|
11
|
-
case 'uuid':
|
|
12
|
-
return `string${nullableSuffix}`;
|
|
13
|
-
case 'text':
|
|
14
|
-
case 'varchar':
|
|
15
|
-
case 'char':
|
|
16
|
-
case 'character varying':
|
|
17
|
-
return `string${nullableSuffix}`;
|
|
18
|
-
case 'integer':
|
|
19
|
-
case 'int':
|
|
20
|
-
case 'int2':
|
|
21
|
-
case 'int4':
|
|
22
|
-
case 'int8':
|
|
23
|
-
case 'serial':
|
|
24
|
-
case 'smallint':
|
|
25
|
-
return `number${nullableSuffix}`;
|
|
26
|
-
case 'bigint':
|
|
27
|
-
case 'bigserial':
|
|
28
|
-
case 'decimal':
|
|
29
|
-
case 'numeric':
|
|
30
|
-
return `string${nullableSuffix}`;
|
|
31
|
-
case 'real':
|
|
32
|
-
case 'double precision':
|
|
33
|
-
case 'float':
|
|
34
|
-
case 'float4':
|
|
35
|
-
case 'float8':
|
|
36
|
-
return `number${nullableSuffix}`;
|
|
37
|
-
case 'boolean':
|
|
38
|
-
case 'bool':
|
|
39
|
-
return `boolean${nullableSuffix}`;
|
|
40
|
-
case 'timestamp':
|
|
41
|
-
case 'timestamp with time zone':
|
|
42
|
-
case 'timestamptz':
|
|
43
|
-
return `Date${nullableSuffix}`;
|
|
44
|
-
case 'date':
|
|
45
|
-
return `Date${nullableSuffix}`;
|
|
46
|
-
case 'time':
|
|
47
|
-
case 'time with time zone':
|
|
48
|
-
return `string${nullableSuffix}`;
|
|
49
|
-
case 'json':
|
|
50
|
-
case 'jsonb':
|
|
51
|
-
return `Record<string, any>${nullableSuffix}`;
|
|
52
|
-
case 'bytea':
|
|
53
|
-
return `Buffer${nullableSuffix}`;
|
|
54
|
-
case 'inet':
|
|
55
|
-
case 'cidr':
|
|
56
|
-
return `string${nullableSuffix}`;
|
|
57
|
-
case 'array':
|
|
58
|
-
return `any[]${nullableSuffix}`;
|
|
59
|
-
default:
|
|
60
|
-
return `any${nullableSuffix}`;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Generates TypeScript interface for a table
|
|
65
|
-
*/
|
|
66
|
-
function generateTableInterface(table, tableName) {
|
|
67
|
-
const interfaceName = tableName.charAt(0).toUpperCase() + tableName.slice(1);
|
|
68
|
-
let interfaceCode = `\n/**\n * ${interfaceName} table interface\n */\nexport interface ${interfaceName} {\n`;
|
|
69
|
-
for (const column of table.columns) {
|
|
70
|
-
const tsType = pgTypeToTsType(column.type, !column.notNull);
|
|
71
|
-
const comment = column.comment ? ` /** ${column.comment} */` : '';
|
|
72
|
-
interfaceCode += ` /** ${column.name} */\n ${column.name}: ${tsType};${comment}\n`;
|
|
73
|
-
}
|
|
74
|
-
interfaceCode += '}\n';
|
|
75
|
-
return interfaceCode;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Generates complete TypeScript definitions from database schema
|
|
79
|
-
*/
|
|
80
|
-
export async function generateDatabaseTypes(options) {
|
|
81
|
-
const { outputPath, connectionString, schema = 'public', excludeTables = ['migrations', 'migration_lock'], includeTables, } = options;
|
|
82
|
-
// Connect to database and get schema
|
|
83
|
-
const db = await pgStructure(connectionString);
|
|
84
|
-
let output = `/**
|
|
85
|
-
* TypeScript definitions for database tables
|
|
86
|
-
* Auto-generated from database schema
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
`;
|
|
90
|
-
const tables = db.schemas.get(schema)?.tables || [];
|
|
91
|
-
const filteredTables = tables.filter((table) => {
|
|
92
|
-
if (includeTables && includeTables.length > 0) {
|
|
93
|
-
return includeTables.includes(table.name);
|
|
94
|
-
}
|
|
95
|
-
return !excludeTables.includes(table.name);
|
|
96
|
-
});
|
|
97
|
-
// Generate table interfaces
|
|
98
|
-
for (const table of filteredTables) {
|
|
99
|
-
output += generateTableInterface(table, table.name);
|
|
100
|
-
}
|
|
101
|
-
// Generate DB interface
|
|
102
|
-
output +=
|
|
103
|
-
'\n/**\n * Database schema interface\n * Maps table names to their respective interfaces\n */\nexport interface DB {\n';
|
|
104
|
-
for (const table of filteredTables) {
|
|
105
|
-
const interfaceName = table.name.charAt(0).toUpperCase() + table.name.slice(1);
|
|
106
|
-
output += ` ${table.name}: ${interfaceName};\n`;
|
|
107
|
-
}
|
|
108
|
-
output += '}\n';
|
|
109
|
-
// Ensure output directory exists
|
|
110
|
-
const outputDir = dirname(resolve(outputPath));
|
|
111
|
-
await fs.mkdir(outputDir, { recursive: true });
|
|
112
|
-
// Write the generated types
|
|
113
|
-
await fs.writeFile(resolve(outputPath), output, 'utf-8');
|
|
114
|
-
}
|
package/dist/postgres.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { type RequestHandler } from 'express';
|
|
3
|
-
import { type PoolClient, type PoolConfig, type QueryResult, type QueryResultRow } from 'pg';
|
|
4
|
-
import { type SqlStatement } from './sql.js';
|
|
5
|
-
export declare const escapePostgresIdentifier: typeof import("pg").escapeIdentifier;
|
|
6
|
-
export declare const escapePostgresLiteral: typeof import("pg").escapeLiteral;
|
|
7
|
-
export interface PostgresOptions extends PoolConfig, ConnectionOptions {
|
|
8
|
-
onError?: (error: Error, client: any) => void;
|
|
9
|
-
url?: PoolConfig['connectionString'];
|
|
10
|
-
}
|
|
11
|
-
export declare class DoesNotExistError extends Error {
|
|
12
|
-
constructor(message: string);
|
|
13
|
-
}
|
|
14
|
-
export declare class MultipleRowsReturnedError extends Error {
|
|
15
|
-
constructor(message: string);
|
|
16
|
-
}
|
|
17
|
-
export declare class IntegrityError extends Error {
|
|
18
|
-
constructor(message: string);
|
|
19
|
-
}
|
|
20
|
-
type Value = null | string | number | Date;
|
|
21
|
-
export interface ConnectionOptions {
|
|
22
|
-
onLogStatement?: (statement: SqlStatement | string, values: unknown[] | undefined, duration: number) => void;
|
|
23
|
-
}
|
|
24
|
-
export interface TransactionContext {
|
|
25
|
-
connection: Connection;
|
|
26
|
-
savepoints: string[];
|
|
27
|
-
isCommitted: boolean;
|
|
28
|
-
isRolledBack: boolean;
|
|
29
|
-
}
|
|
30
|
-
export declare const transactionStorage: AsyncLocalStorage<TransactionContext>;
|
|
31
|
-
export declare class Connection {
|
|
32
|
-
client: PoolClient;
|
|
33
|
-
options: ConnectionOptions;
|
|
34
|
-
constructor(client: PoolClient, options: ConnectionOptions);
|
|
35
|
-
private logStatement;
|
|
36
|
-
query<T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]): Promise<QueryResult<T>>;
|
|
37
|
-
all<T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]): Promise<T[]>;
|
|
38
|
-
insert<T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]): Promise<QueryResult<T>>;
|
|
39
|
-
first<T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]): Promise<T | null>;
|
|
40
|
-
get<T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]): Promise<T>;
|
|
41
|
-
}
|
|
42
|
-
export declare class Transaction extends Connection {
|
|
43
|
-
savepoints: string[];
|
|
44
|
-
isCommitted: boolean;
|
|
45
|
-
isRolledBack: boolean;
|
|
46
|
-
createSavepoint(): Promise<string>;
|
|
47
|
-
rollbackToSavepoint(savepointName: string): Promise<void>;
|
|
48
|
-
releaseSavepoint(savepointName: string): Promise<void>;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Create a new Postgres connection pool with
|
|
52
|
-
* conveience methods for executing queries using
|
|
53
|
-
* one of the available connections.
|
|
54
|
-
*
|
|
55
|
-
* @param config
|
|
56
|
-
*/
|
|
57
|
-
export declare function createPostgres({ onError, url, ...postgresOptions }?: PostgresOptions): {
|
|
58
|
-
insert: <T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]) => Promise<QueryResult<T>>;
|
|
59
|
-
query: <T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]) => Promise<QueryResult<T>>;
|
|
60
|
-
first: <T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]) => Promise<T | null>;
|
|
61
|
-
all: <T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]) => Promise<T[]>;
|
|
62
|
-
get: <T extends QueryResultRow>(text: string | SqlStatement, values?: Value[]) => Promise<T>;
|
|
63
|
-
withConnection: <T>(callback: (connection: Connection) => Promise<T>) => Promise<T>;
|
|
64
|
-
transaction: <T>(callback: () => Promise<T> | T) => Promise<T>;
|
|
65
|
-
getCurrentTransaction: () => Transaction | null;
|
|
66
|
-
instance: import("pg").Pool;
|
|
67
|
-
clear: (force?: boolean) => Promise<void>;
|
|
68
|
-
end(): Promise<void>;
|
|
69
|
-
};
|
|
70
|
-
export declare function withTransaction(postgres: ReturnType<typeof createPostgres>): RequestHandler;
|
|
71
|
-
export {};
|
package/dist/postgres.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import {} from 'express';
|
|
3
|
-
import pg, {} from 'pg';
|
|
4
|
-
import { config } from './config.js';
|
|
5
|
-
import { formatSql } from './sql.js';
|
|
6
|
-
import { startTimer } from './utils.js';
|
|
7
|
-
export const escapePostgresIdentifier = pg.escapeIdentifier;
|
|
8
|
-
export const escapePostgresLiteral = pg.escapeLiteral;
|
|
9
|
-
export class DoesNotExistError extends Error {
|
|
10
|
-
constructor(message) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.name = 'DoesNotExistError';
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export class MultipleRowsReturnedError extends Error {
|
|
16
|
-
constructor(message) {
|
|
17
|
-
super(message);
|
|
18
|
-
this.name = 'MultipleRowsReturnedError';
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export class IntegrityError extends Error {
|
|
22
|
-
constructor(message) {
|
|
23
|
-
super(message);
|
|
24
|
-
this.name = 'IntegrityError';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export const transactionStorage = new AsyncLocalStorage();
|
|
28
|
-
export class Connection {
|
|
29
|
-
client;
|
|
30
|
-
options;
|
|
31
|
-
constructor(client, options) {
|
|
32
|
-
this.client = client;
|
|
33
|
-
this.options = options;
|
|
34
|
-
}
|
|
35
|
-
logStatement(text, values, duration) {
|
|
36
|
-
if (this.options.onLogStatement) {
|
|
37
|
-
return this.options.onLogStatement(text, values, duration);
|
|
38
|
-
}
|
|
39
|
-
if (config.value.LOG_SQL) {
|
|
40
|
-
console.log(`\n${formatSql(text)}\n\nValues: ${JSON.stringify(values)}\nDuration: ${duration}ms\n`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
async query(text, values) {
|
|
44
|
-
const timer = startTimer();
|
|
45
|
-
try {
|
|
46
|
-
return await this.client.query(text, values);
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
if (error.code && error.code === '23505') {
|
|
50
|
-
throw new IntegrityError(`${error.message}: ${error.detail}`);
|
|
51
|
-
}
|
|
52
|
-
throw error;
|
|
53
|
-
}
|
|
54
|
-
finally {
|
|
55
|
-
this.logStatement?.(text, values, timer.getDuration());
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async all(text, values) {
|
|
59
|
-
const result = await this.query(text, values);
|
|
60
|
-
if (result.rows) {
|
|
61
|
-
return result.rows;
|
|
62
|
-
/* c8 ignore next 2*/
|
|
63
|
-
}
|
|
64
|
-
return [];
|
|
65
|
-
}
|
|
66
|
-
async insert(text, values) {
|
|
67
|
-
return await this.query(text, values);
|
|
68
|
-
}
|
|
69
|
-
async first(text, values) {
|
|
70
|
-
const result = await this.query(text, values);
|
|
71
|
-
return result.rows && result.rows.length ? result.rows[0] : null;
|
|
72
|
-
}
|
|
73
|
-
async get(text, values) {
|
|
74
|
-
const result = await this.query(text, values);
|
|
75
|
-
if (result.rowCount === 0) {
|
|
76
|
-
throw new DoesNotExistError('Row matching query not found');
|
|
77
|
-
}
|
|
78
|
-
if (result.rowCount > 1) {
|
|
79
|
-
throw new MultipleRowsReturnedError(`Call to postgres.get() returned ${result.rowCount} rows. Expected 1.`);
|
|
80
|
-
}
|
|
81
|
-
return result.rows[0];
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
export class Transaction extends Connection {
|
|
85
|
-
savepoints = [];
|
|
86
|
-
isCommitted = false;
|
|
87
|
-
isRolledBack = false;
|
|
88
|
-
async createSavepoint() {
|
|
89
|
-
const savepointName = `sp_${this.savepoints.length + 1}`;
|
|
90
|
-
await this.query(`SAVEPOINT ${savepointName}`);
|
|
91
|
-
this.savepoints.push(savepointName);
|
|
92
|
-
return savepointName;
|
|
93
|
-
}
|
|
94
|
-
async rollbackToSavepoint(savepointName) {
|
|
95
|
-
await this.query(`ROLLBACK TO SAVEPOINT ${savepointName}`);
|
|
96
|
-
}
|
|
97
|
-
async releaseSavepoint(savepointName) {
|
|
98
|
-
await this.query(`RELEASE SAVEPOINT ${savepointName}`);
|
|
99
|
-
const index = this.savepoints.indexOf(savepointName);
|
|
100
|
-
if (index !== -1) {
|
|
101
|
-
this.savepoints.splice(index, 1);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Create a new Postgres connection pool with
|
|
107
|
-
* conveience methods for executing queries using
|
|
108
|
-
* one of the available connections.
|
|
109
|
-
*
|
|
110
|
-
* @param config
|
|
111
|
-
*/
|
|
112
|
-
export function createPostgres({ onError, url = config.value.POSTGRES_URL, ...postgresOptions } = {}) {
|
|
113
|
-
const pool = new pg.Pool({ connectionString: url, ...postgresOptions });
|
|
114
|
-
pool.on('error', (e, client) => {
|
|
115
|
-
onError?.(e, client);
|
|
116
|
-
});
|
|
117
|
-
async function withConnection(callback) {
|
|
118
|
-
// Check if we're already in a transaction context
|
|
119
|
-
const txContext = transactionStorage.getStore();
|
|
120
|
-
if (txContext) {
|
|
121
|
-
return callback(txContext.connection);
|
|
122
|
-
}
|
|
123
|
-
const client = await pool.connect();
|
|
124
|
-
try {
|
|
125
|
-
const result = await callback(new Connection(client, {
|
|
126
|
-
onLogStatement: postgresOptions.onLogStatement,
|
|
127
|
-
}));
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
finally {
|
|
131
|
-
client.release();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Wipe the database schema
|
|
136
|
-
*/
|
|
137
|
-
async function clear(force = false) {
|
|
138
|
-
if (!force) {
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
return withConnection(async (connection) => {
|
|
142
|
-
await connection.query('DROP SCHEMA public CASCADE');
|
|
143
|
-
await connection.query(`CREATE SCHEMA public`);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Run queries inside a BEGIN, COMMIT / ROLLBACK transaction.
|
|
148
|
-
* Supports nested transactions using SAVEPOINT.
|
|
149
|
-
*/
|
|
150
|
-
async function transaction(callback) {
|
|
151
|
-
// Check if we're already in a transaction context
|
|
152
|
-
const existingTxContext = transactionStorage.getStore();
|
|
153
|
-
if (existingTxContext) {
|
|
154
|
-
// We're already in a transaction, create a savepoint for nested transaction
|
|
155
|
-
const txConnection = existingTxContext.connection;
|
|
156
|
-
const savepointName = await txConnection.createSavepoint();
|
|
157
|
-
try {
|
|
158
|
-
const result = await callback();
|
|
159
|
-
await txConnection.releaseSavepoint(savepointName);
|
|
160
|
-
return result;
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
await txConnection.rollbackToSavepoint(savepointName);
|
|
164
|
-
throw error;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
// Start a new top-level transaction
|
|
168
|
-
const client = await pool.connect();
|
|
169
|
-
const txConnection = new Transaction(client, {
|
|
170
|
-
onLogStatement: postgresOptions.onLogStatement,
|
|
171
|
-
});
|
|
172
|
-
try {
|
|
173
|
-
await txConnection.query('BEGIN');
|
|
174
|
-
// Create transaction context
|
|
175
|
-
const txContext = {
|
|
176
|
-
connection: txConnection,
|
|
177
|
-
savepoints: [],
|
|
178
|
-
isCommitted: false,
|
|
179
|
-
isRolledBack: false,
|
|
180
|
-
};
|
|
181
|
-
// Run the callback within the transaction context
|
|
182
|
-
const result = await transactionStorage.run(txContext, async () => {
|
|
183
|
-
return await callback();
|
|
184
|
-
});
|
|
185
|
-
await txConnection.query('COMMIT');
|
|
186
|
-
txContext.isCommitted = true;
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
await txConnection.query('ROLLBACK');
|
|
191
|
-
throw error;
|
|
192
|
-
}
|
|
193
|
-
finally {
|
|
194
|
-
client.release();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const query = async (...args) => {
|
|
198
|
-
return await withConnection(async (connection) => {
|
|
199
|
-
return connection.query(...args);
|
|
200
|
-
});
|
|
201
|
-
};
|
|
202
|
-
const insert = async (...args) => {
|
|
203
|
-
return await withConnection(async (connection) => {
|
|
204
|
-
return connection.insert(...args);
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
const first = async (...args) => {
|
|
208
|
-
return await withConnection(async (connection) => {
|
|
209
|
-
return connection.first(...args);
|
|
210
|
-
});
|
|
211
|
-
};
|
|
212
|
-
const all = async (...args) => {
|
|
213
|
-
return await withConnection(async (connection) => {
|
|
214
|
-
return connection.all(...args);
|
|
215
|
-
});
|
|
216
|
-
};
|
|
217
|
-
const get = async (...args) => {
|
|
218
|
-
return await withConnection(async (connection) => {
|
|
219
|
-
return connection.get(...args);
|
|
220
|
-
});
|
|
221
|
-
};
|
|
222
|
-
/**
|
|
223
|
-
* Get the current transaction from the AsyncLocalStorage context.
|
|
224
|
-
* Returns null if not in a transaction.
|
|
225
|
-
*/
|
|
226
|
-
function getCurrentTransaction() {
|
|
227
|
-
const txContext = transactionStorage.getStore();
|
|
228
|
-
return txContext ? txContext.connection : null;
|
|
229
|
-
}
|
|
230
|
-
return {
|
|
231
|
-
insert,
|
|
232
|
-
query,
|
|
233
|
-
first,
|
|
234
|
-
all,
|
|
235
|
-
get,
|
|
236
|
-
withConnection,
|
|
237
|
-
transaction,
|
|
238
|
-
getCurrentTransaction,
|
|
239
|
-
instance: pool,
|
|
240
|
-
clear,
|
|
241
|
-
end() {
|
|
242
|
-
return pool.end();
|
|
243
|
-
},
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
export function withTransaction(postgres) {
|
|
247
|
-
return async function withTransactionMiddleware(req, res, next) {
|
|
248
|
-
try {
|
|
249
|
-
await postgres.transaction(async () => {
|
|
250
|
-
await new Promise((resolve, reject) => {
|
|
251
|
-
res.on('finish', resolve);
|
|
252
|
-
res.on('error', reject);
|
|
253
|
-
next();
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
catch (error) {
|
|
258
|
-
next(error);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
}
|
package/dist/sql.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export declare class SqlStatement {
|
|
2
|
-
stringsAndValues: [string, unknown | undefined][];
|
|
3
|
-
constructor(strings: string[], values: unknown[]);
|
|
4
|
-
_extract(strings: string[], values: unknown[]): void;
|
|
5
|
-
append(statement: SqlStatement | string): this;
|
|
6
|
-
get values(): ({} | null)[];
|
|
7
|
-
get text(): string;
|
|
8
|
-
}
|
|
9
|
-
export declare const sql: {
|
|
10
|
-
(strings: TemplateStringsArray, ...values: unknown[]): SqlStatement;
|
|
11
|
-
identifier(name: string): {
|
|
12
|
-
name: string;
|
|
13
|
-
raw: boolean;
|
|
14
|
-
};
|
|
15
|
-
raw(name: string): {
|
|
16
|
-
name: string;
|
|
17
|
-
raw: boolean;
|
|
18
|
-
};
|
|
19
|
-
literal(name: string | null): {
|
|
20
|
-
name: string;
|
|
21
|
-
raw: boolean;
|
|
22
|
-
};
|
|
23
|
-
spreadUpdate: typeof spreadUpdate;
|
|
24
|
-
spreadInsert: typeof spreadInsert;
|
|
25
|
-
};
|
|
26
|
-
declare function spreadUpdate(data: Record<string, any>): SqlStatement;
|
|
27
|
-
declare function spreadInsert<TData extends Record<string, any>>(data: TData | TData[]): SqlStatement;
|
|
28
|
-
export declare function joinStatements(statements: SqlStatement[], separator: string): SqlStatement;
|
|
29
|
-
/**
|
|
30
|
-
* Returns a pretty-printed SQL statement.
|
|
31
|
-
*/
|
|
32
|
-
export declare const formatSql: (statement: SqlStatement | string) => string;
|
|
33
|
-
export {};
|
package/dist/sql.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { format } from 'sql-formatter';
|
|
2
|
-
import { escapePostgresIdentifier, escapePostgresLiteral } from './postgres.js';
|
|
3
|
-
const isRaw = (value) => {
|
|
4
|
-
return (typeof value === 'object' && value !== null && 'raw' in value && !!value.raw);
|
|
5
|
-
};
|
|
6
|
-
export class SqlStatement {
|
|
7
|
-
stringsAndValues;
|
|
8
|
-
constructor(strings, values) {
|
|
9
|
-
this.stringsAndValues = [];
|
|
10
|
-
this._extract(strings, values);
|
|
11
|
-
}
|
|
12
|
-
_extract(strings, values) {
|
|
13
|
-
for (let i = 0; i < strings.length; i++) {
|
|
14
|
-
const string = strings[i];
|
|
15
|
-
const value = values[i];
|
|
16
|
-
if (isRaw(value)) {
|
|
17
|
-
this.stringsAndValues.push([string + value.name, undefined]);
|
|
18
|
-
}
|
|
19
|
-
else if (value instanceof SqlStatement) {
|
|
20
|
-
this.stringsAndValues.push([string, undefined]);
|
|
21
|
-
this.stringsAndValues.push(...value.stringsAndValues);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
this.stringsAndValues.push([string, value]);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
append(statement) {
|
|
29
|
-
if (statement instanceof SqlStatement) {
|
|
30
|
-
this.stringsAndValues.push(...statement.stringsAndValues);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this.stringsAndValues.push([statement, undefined]);
|
|
34
|
-
}
|
|
35
|
-
return this;
|
|
36
|
-
}
|
|
37
|
-
get values() {
|
|
38
|
-
return this.stringsAndValues
|
|
39
|
-
.map(([, value]) => value)
|
|
40
|
-
.filter((x) => x !== undefined);
|
|
41
|
-
}
|
|
42
|
-
get text() {
|
|
43
|
-
let i = 1;
|
|
44
|
-
let result = '';
|
|
45
|
-
for (const [string, value] of this.stringsAndValues) {
|
|
46
|
-
if (value == null) {
|
|
47
|
-
result += string;
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
result += `${string}$${i}`;
|
|
51
|
-
i += 1;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
export const sql = (strings, ...values) => {
|
|
58
|
-
return new SqlStatement(Array.from(strings), values);
|
|
59
|
-
};
|
|
60
|
-
function spreadUpdate(data) {
|
|
61
|
-
const entries = Object.entries(data);
|
|
62
|
-
if (entries.length === 0) {
|
|
63
|
-
return sql ``;
|
|
64
|
-
}
|
|
65
|
-
return joinStatements(entries
|
|
66
|
-
.filter(([, value]) => typeof value !== 'undefined')
|
|
67
|
-
.map(([key, value]) => sql `${sql.identifier(key)} = ${value == null ? sql.raw('NULL') : value}`), ', ');
|
|
68
|
-
}
|
|
69
|
-
function spreadInsert(data) {
|
|
70
|
-
const rows = Array.isArray(data) ? data : [data];
|
|
71
|
-
if (rows.length === 0) {
|
|
72
|
-
return sql ``;
|
|
73
|
-
}
|
|
74
|
-
const statement = sql `(`;
|
|
75
|
-
statement.append(Object.keys(rows[0])
|
|
76
|
-
.map((k) => escapePostgresIdentifier(k))
|
|
77
|
-
.join(', '));
|
|
78
|
-
statement.append(sql `) VALUES `);
|
|
79
|
-
const toInsert = [];
|
|
80
|
-
for (const row of rows) {
|
|
81
|
-
const values = Object.values(row);
|
|
82
|
-
if (values.length === 0) {
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
toInsert.push(sql `(${joinStatements(values.map((value) => sql `${value ?? sql.raw('NULL')}`), ', ')})`);
|
|
86
|
-
}
|
|
87
|
-
statement.append(joinStatements(toInsert, ', '));
|
|
88
|
-
return statement;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Inject an identifier into the template string
|
|
92
|
-
*/
|
|
93
|
-
sql.identifier = (name) => {
|
|
94
|
-
return { name: escapePostgresIdentifier(name), raw: true };
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Inject a raw value into the template string
|
|
98
|
-
*/
|
|
99
|
-
sql.raw = (name) => {
|
|
100
|
-
return { name, raw: true };
|
|
101
|
-
};
|
|
102
|
-
/**
|
|
103
|
-
* Inject a literal value into the template string
|
|
104
|
-
*/
|
|
105
|
-
sql.literal = (name) => {
|
|
106
|
-
if (name === null) {
|
|
107
|
-
return { name: 'NULL', raw: true };
|
|
108
|
-
}
|
|
109
|
-
return { name: escapePostgresLiteral(name), raw: true };
|
|
110
|
-
};
|
|
111
|
-
sql.spreadUpdate = spreadUpdate;
|
|
112
|
-
sql.spreadInsert = spreadInsert;
|
|
113
|
-
export function joinStatements(statements, separator) {
|
|
114
|
-
let i = 0;
|
|
115
|
-
const statement = sql ``;
|
|
116
|
-
for (const o of statements) {
|
|
117
|
-
if (i++ !== 0) {
|
|
118
|
-
statement.append(separator);
|
|
119
|
-
}
|
|
120
|
-
statement.append(o);
|
|
121
|
-
}
|
|
122
|
-
return statement;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Returns a pretty-printed SQL statement.
|
|
126
|
-
*/
|
|
127
|
-
export const formatSql = (statement) => {
|
|
128
|
-
const value = statement instanceof SqlStatement ? statement.text : statement;
|
|
129
|
-
return format(value, {
|
|
130
|
-
language: 'postgresql',
|
|
131
|
-
keywordCase: 'upper',
|
|
132
|
-
tabWidth: 2,
|
|
133
|
-
useTabs: false,
|
|
134
|
-
});
|
|
135
|
-
};
|
package/dist/vite.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { defineViteConfig } from './vite/defineViteConfig.js';
|
package/dist/vite.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { defineViteConfig } from './vite/defineViteConfig.js';
|