@bernierllc/database-adapter-postgresql 1.5.1 → 1.5.3
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/package.json +4 -4
- package/dist/PostgreSQLAdapter.d.ts +0 -65
- package/dist/PostgreSQLAdapter.js +0 -254
- package/dist/PostgreSQLTransaction.d.ts +0 -46
- package/dist/PostgreSQLTransaction.js +0 -203
- package/dist/errors.d.ts +0 -11
- package/dist/errors.js +0 -24
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -32
- package/dist/migrations/001_initial_schema.d.ts +0 -2
- package/dist/migrations/001_initial_schema.js +0 -91
- package/dist/realtime/RealtimeManager.d.ts +0 -76
- package/dist/realtime/RealtimeManager.js +0 -245
- package/dist/rls/ClerkIntegration.d.ts +0 -41
- package/dist/rls/ClerkIntegration.js +0 -161
- package/dist/rls/RLSPolicyGenerator.d.ts +0 -38
- package/dist/rls/RLSPolicyGenerator.js +0 -212
- package/dist/search/FullTextSearchManager.d.ts +0 -61
- package/dist/search/FullTextSearchManager.js +0 -267
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bernierllc/database-adapter-postgresql",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "PostgreSQL/Supabase Database Adapter Implementation with RLS, real-time subscriptions, and full-text search",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"@supabase/supabase-js": "^2.38.0",
|
|
21
21
|
"pg": "^8.11.0",
|
|
22
22
|
"@bernierllc/crypto-utils": "1.4.0",
|
|
23
|
-
"@bernierllc/
|
|
24
|
-
"@bernierllc/
|
|
25
|
-
"@bernierllc/
|
|
23
|
+
"@bernierllc/database-adapter-core": "3.0.2",
|
|
24
|
+
"@bernierllc/logger": "2.0.0",
|
|
25
|
+
"@bernierllc/retry-policy": "0.7.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/jest": "^29.0.0",
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import { BaseDatabaseAdapter, IDatabaseConfig, IDatabaseHealth, IQueryResult, ITransaction } from '@bernierllc/database-adapter-core';
|
|
3
|
-
/**
|
|
4
|
-
* Supabase-specific configuration
|
|
5
|
-
*/
|
|
6
|
-
export interface ISupabaseConfig {
|
|
7
|
-
supabaseUrl?: string;
|
|
8
|
-
supabaseAnonKey?: string;
|
|
9
|
-
supabaseServiceKey?: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* PostgreSQL database adapter with Supabase support
|
|
13
|
-
* Implements connection pooling, RLS, and real-time features
|
|
14
|
-
*/
|
|
15
|
-
export declare class PostgreSQLAdapter extends BaseDatabaseAdapter {
|
|
16
|
-
private pool;
|
|
17
|
-
private supabase;
|
|
18
|
-
private rlsManager;
|
|
19
|
-
private logger;
|
|
20
|
-
constructor(config: IDatabaseConfig & ISupabaseConfig);
|
|
21
|
-
/**
|
|
22
|
-
* Connect to PostgreSQL with connection pooling
|
|
23
|
-
*/
|
|
24
|
-
connect(): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Disconnect and close pool
|
|
27
|
-
*/
|
|
28
|
-
disconnect(): Promise<void>;
|
|
29
|
-
/**
|
|
30
|
-
* Execute query with RLS context
|
|
31
|
-
*/
|
|
32
|
-
query<T = unknown>(sql: string, params?: unknown[]): Promise<IQueryResult<T>>;
|
|
33
|
-
/**
|
|
34
|
-
* Begin transaction with RLS context
|
|
35
|
-
*/
|
|
36
|
-
beginTransaction(): Promise<ITransaction>;
|
|
37
|
-
/**
|
|
38
|
-
* Health check with connection pool stats
|
|
39
|
-
*/
|
|
40
|
-
healthCheck(): Promise<IDatabaseHealth>;
|
|
41
|
-
/**
|
|
42
|
-
* Get Supabase client for real-time features
|
|
43
|
-
*/
|
|
44
|
-
getSupabaseClient(): SupabaseClient | null;
|
|
45
|
-
/**
|
|
46
|
-
* Set RLS context for current operation
|
|
47
|
-
*/
|
|
48
|
-
setRLSContext(userId: string, userRole: string, tenantId?: string): void;
|
|
49
|
-
/**
|
|
50
|
-
* Clear RLS context
|
|
51
|
-
*/
|
|
52
|
-
clearRLSContext(): void;
|
|
53
|
-
/**
|
|
54
|
-
* Get current connection pool statistics
|
|
55
|
-
*/
|
|
56
|
-
getPoolStats(): {
|
|
57
|
-
total: number;
|
|
58
|
-
idle: number;
|
|
59
|
-
waiting: number;
|
|
60
|
-
} | null;
|
|
61
|
-
/**
|
|
62
|
-
* Map PostgreSQL data type OID to name
|
|
63
|
-
*/
|
|
64
|
-
private getDataTypeName;
|
|
65
|
-
}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2025 Bernier LLC
|
|
4
|
-
|
|
5
|
-
This file is licensed to the client under a limited-use license.
|
|
6
|
-
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
-
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.PostgreSQLAdapter = void 0;
|
|
11
|
-
const pg_1 = require("pg");
|
|
12
|
-
const supabase_js_1 = require("@supabase/supabase-js");
|
|
13
|
-
const database_adapter_core_1 = require("@bernierllc/database-adapter-core");
|
|
14
|
-
const retry_policy_1 = require("@bernierllc/retry-policy");
|
|
15
|
-
const logger_1 = require("@bernierllc/logger");
|
|
16
|
-
const PostgreSQLTransaction_1 = require("./PostgreSQLTransaction");
|
|
17
|
-
/**
|
|
18
|
-
* PostgreSQL database adapter with Supabase support
|
|
19
|
-
* Implements connection pooling, RLS, and real-time features
|
|
20
|
-
*/
|
|
21
|
-
class PostgreSQLAdapter extends database_adapter_core_1.BaseDatabaseAdapter {
|
|
22
|
-
pool = null;
|
|
23
|
-
supabase = null;
|
|
24
|
-
rlsManager;
|
|
25
|
-
logger;
|
|
26
|
-
constructor(config) {
|
|
27
|
-
super(config);
|
|
28
|
-
this.rlsManager = new database_adapter_core_1.RLSContextManager();
|
|
29
|
-
this.logger = (0, logger_1.createLogger)({ context: { component: 'PostgreSQLAdapter' } });
|
|
30
|
-
// Initialize Supabase client if configured
|
|
31
|
-
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
32
|
-
this.supabase = (0, supabase_js_1.createClient)(config.supabaseUrl, config.supabaseAnonKey, {
|
|
33
|
-
auth: {
|
|
34
|
-
autoRefreshToken: true,
|
|
35
|
-
persistSession: true,
|
|
36
|
-
detectSessionInUrl: false
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Connect to PostgreSQL with connection pooling
|
|
43
|
-
*/
|
|
44
|
-
async connect() {
|
|
45
|
-
if (this.connected)
|
|
46
|
-
return;
|
|
47
|
-
this.pool = new pg_1.Pool({
|
|
48
|
-
host: this.config.host,
|
|
49
|
-
port: this.config.port || 5432,
|
|
50
|
-
database: this.config.database,
|
|
51
|
-
user: this.config.username,
|
|
52
|
-
password: this.config.password,
|
|
53
|
-
ssl: this.config.ssl,
|
|
54
|
-
min: this.config.pooling?.min || 2,
|
|
55
|
-
max: this.config.pooling?.max || 10,
|
|
56
|
-
idleTimeoutMillis: this.config.pooling?.idleTimeoutMs || 30000,
|
|
57
|
-
connectionTimeoutMillis: this.config.connectionTimeoutMs || 5000
|
|
58
|
-
});
|
|
59
|
-
// Test connection with retry
|
|
60
|
-
let attempt = 0;
|
|
61
|
-
const maxRetries = 3;
|
|
62
|
-
while (attempt < maxRetries) {
|
|
63
|
-
try {
|
|
64
|
-
const client = await this.pool.connect();
|
|
65
|
-
await client.query('SELECT NOW()');
|
|
66
|
-
client.release();
|
|
67
|
-
this.connected = true;
|
|
68
|
-
this.logger.info('PostgreSQL connection established', {
|
|
69
|
-
database: this.config.database,
|
|
70
|
-
host: this.config.host,
|
|
71
|
-
poolMin: this.config.pooling?.min || 2,
|
|
72
|
-
poolMax: this.config.pooling?.max || 10
|
|
73
|
-
});
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
attempt++;
|
|
78
|
-
if ((0, retry_policy_1.shouldRetry)(attempt, error, { maxRetries })) {
|
|
79
|
-
const delay = (0, retry_policy_1.calculateRetryDelay)(attempt, {
|
|
80
|
-
initialDelayMs: 1000,
|
|
81
|
-
maxDelayMs: 5000,
|
|
82
|
-
jitter: true
|
|
83
|
-
});
|
|
84
|
-
this.logger.warn('PostgreSQL connection failed, retrying', {
|
|
85
|
-
attempt,
|
|
86
|
-
maxRetries,
|
|
87
|
-
delayMs: delay,
|
|
88
|
-
error: this.sanitizeError(error)
|
|
89
|
-
});
|
|
90
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
throw this.sanitizeError(error);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
throw new Error('Failed to connect to PostgreSQL after retries');
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Disconnect and close pool
|
|
101
|
-
*/
|
|
102
|
-
async disconnect() {
|
|
103
|
-
if (!this.pool)
|
|
104
|
-
return;
|
|
105
|
-
await this.pool.end();
|
|
106
|
-
this.pool = null;
|
|
107
|
-
this.connected = false;
|
|
108
|
-
this.logger.info('PostgreSQL connection closed');
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Execute query with RLS context
|
|
112
|
-
*/
|
|
113
|
-
async query(sql, params) {
|
|
114
|
-
this.ensureConnected();
|
|
115
|
-
const startTime = Date.now();
|
|
116
|
-
const client = await this.pool.connect();
|
|
117
|
-
try {
|
|
118
|
-
// Set RLS context if available
|
|
119
|
-
const rlsStatements = this.rlsManager.generateRLSStatements();
|
|
120
|
-
for (const stmt of rlsStatements) {
|
|
121
|
-
await client.query(stmt);
|
|
122
|
-
}
|
|
123
|
-
// Execute query
|
|
124
|
-
const result = await client.query(sql, params);
|
|
125
|
-
const duration = Date.now() - startTime;
|
|
126
|
-
this.logger.debug('Query executed', {
|
|
127
|
-
duration,
|
|
128
|
-
rowCount: result.rowCount,
|
|
129
|
-
command: result.command
|
|
130
|
-
});
|
|
131
|
-
return {
|
|
132
|
-
rows: result.rows,
|
|
133
|
-
rowCount: result.rowCount || 0,
|
|
134
|
-
fields: result.fields.map(f => ({
|
|
135
|
-
name: f.name,
|
|
136
|
-
dataTypeID: f.dataTypeID,
|
|
137
|
-
dataTypeName: this.getDataTypeName(f.dataTypeID),
|
|
138
|
-
nullable: true // PostgreSQL doesn't expose this easily
|
|
139
|
-
})),
|
|
140
|
-
command: result.command
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
const sanitized = this.sanitizeError(error);
|
|
145
|
-
this.logger.error('Query execution failed', sanitized, {
|
|
146
|
-
duration: Date.now() - startTime
|
|
147
|
-
});
|
|
148
|
-
throw sanitized;
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
client.release();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Begin transaction with RLS context
|
|
156
|
-
*/
|
|
157
|
-
async beginTransaction() {
|
|
158
|
-
this.ensureConnected();
|
|
159
|
-
const client = await this.pool.connect();
|
|
160
|
-
// Set RLS context for transaction
|
|
161
|
-
const rlsStatements = this.rlsManager.generateRLSStatements();
|
|
162
|
-
for (const stmt of rlsStatements) {
|
|
163
|
-
await client.query(stmt);
|
|
164
|
-
}
|
|
165
|
-
await client.query('BEGIN');
|
|
166
|
-
this.logger.debug('Transaction started');
|
|
167
|
-
return new PostgreSQLTransaction_1.PostgreSQLTransaction(client, this.rlsManager, this.logger);
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Health check with connection pool stats
|
|
171
|
-
*/
|
|
172
|
-
async healthCheck() {
|
|
173
|
-
if (!this.connected || !this.pool) {
|
|
174
|
-
return {
|
|
175
|
-
connected: false,
|
|
176
|
-
latencyMs: -1,
|
|
177
|
-
version: 'unknown'
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
const start = Date.now();
|
|
181
|
-
try {
|
|
182
|
-
const result = await this.pool.query('SELECT version()');
|
|
183
|
-
const latencyMs = Date.now() - start;
|
|
184
|
-
return {
|
|
185
|
-
connected: true,
|
|
186
|
-
latencyMs,
|
|
187
|
-
version: result.rows[0].version,
|
|
188
|
-
activeConnections: this.pool.totalCount,
|
|
189
|
-
maxConnections: this.pool.options.max
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
const sanitized = this.sanitizeError(error);
|
|
194
|
-
this.logger.error('Health check failed', sanitized);
|
|
195
|
-
return {
|
|
196
|
-
connected: false,
|
|
197
|
-
latencyMs: -1,
|
|
198
|
-
version: 'error'
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Get Supabase client for real-time features
|
|
204
|
-
*/
|
|
205
|
-
getSupabaseClient() {
|
|
206
|
-
return this.supabase;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Set RLS context for current operation
|
|
210
|
-
*/
|
|
211
|
-
setRLSContext(userId, userRole, tenantId) {
|
|
212
|
-
this.rlsManager.setContext({ userId, userRole, tenantId });
|
|
213
|
-
this.logger.debug('RLS context set', { userId, userRole, tenantId });
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Clear RLS context
|
|
217
|
-
*/
|
|
218
|
-
clearRLSContext() {
|
|
219
|
-
this.rlsManager.clearContext();
|
|
220
|
-
this.logger.debug('RLS context cleared');
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Get current connection pool statistics
|
|
224
|
-
*/
|
|
225
|
-
getPoolStats() {
|
|
226
|
-
if (!this.pool)
|
|
227
|
-
return null;
|
|
228
|
-
return {
|
|
229
|
-
total: this.pool.totalCount,
|
|
230
|
-
idle: this.pool.idleCount,
|
|
231
|
-
waiting: this.pool.waitingCount
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Map PostgreSQL data type OID to name
|
|
236
|
-
*/
|
|
237
|
-
getDataTypeName(oid) {
|
|
238
|
-
const typeMap = {
|
|
239
|
-
16: 'BOOL',
|
|
240
|
-
20: 'BIGINT',
|
|
241
|
-
21: 'SMALLINT',
|
|
242
|
-
23: 'INTEGER',
|
|
243
|
-
25: 'TEXT',
|
|
244
|
-
114: 'JSON',
|
|
245
|
-
1043: 'VARCHAR',
|
|
246
|
-
1082: 'DATE',
|
|
247
|
-
1114: 'TIMESTAMP',
|
|
248
|
-
1184: 'TIMESTAMPTZ',
|
|
249
|
-
3802: 'JSONB'
|
|
250
|
-
};
|
|
251
|
-
return typeMap[oid] || 'UNKNOWN';
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
exports.PostgreSQLAdapter = PostgreSQLAdapter;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { PoolClient } from 'pg';
|
|
2
|
-
import { ITransaction, IQueryResult, RLSContextManager } from '@bernierllc/database-adapter-core';
|
|
3
|
-
import { Logger } from '@bernierllc/logger';
|
|
4
|
-
/**
|
|
5
|
-
* PostgreSQL transaction implementation with RLS context support
|
|
6
|
-
*/
|
|
7
|
-
export declare class PostgreSQLTransaction implements ITransaction {
|
|
8
|
-
private client;
|
|
9
|
-
private _rlsManager;
|
|
10
|
-
id: string;
|
|
11
|
-
private active;
|
|
12
|
-
private logger?;
|
|
13
|
-
constructor(client: PoolClient, _rlsManager: RLSContextManager, logger?: Logger);
|
|
14
|
-
/**
|
|
15
|
-
* Execute query within transaction
|
|
16
|
-
*/
|
|
17
|
-
query<T = unknown>(sql: string, params?: unknown[]): Promise<IQueryResult<T>>;
|
|
18
|
-
/**
|
|
19
|
-
* Commit transaction and release client
|
|
20
|
-
*/
|
|
21
|
-
commit(): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* Rollback transaction and release client
|
|
24
|
-
*/
|
|
25
|
-
rollback(): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Create a savepoint within the transaction
|
|
28
|
-
*/
|
|
29
|
-
savepoint(name: string): Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
* Rollback to a savepoint
|
|
32
|
-
*/
|
|
33
|
-
rollbackToSavepoint(name: string): Promise<void>;
|
|
34
|
-
/**
|
|
35
|
-
* Release a savepoint
|
|
36
|
-
*/
|
|
37
|
-
releaseSavepoint(name: string): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Check if transaction is still active
|
|
40
|
-
*/
|
|
41
|
-
isActive(): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Map PostgreSQL data type OID to name
|
|
44
|
-
*/
|
|
45
|
-
private getDataTypeName;
|
|
46
|
-
}
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2025 Bernier LLC
|
|
4
|
-
|
|
5
|
-
This file is licensed to the client under a limited-use license.
|
|
6
|
-
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
-
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.PostgreSQLTransaction = void 0;
|
|
11
|
-
/**
|
|
12
|
-
* PostgreSQL transaction implementation with RLS context support
|
|
13
|
-
*/
|
|
14
|
-
class PostgreSQLTransaction {
|
|
15
|
-
client;
|
|
16
|
-
_rlsManager;
|
|
17
|
-
id;
|
|
18
|
-
active = true;
|
|
19
|
-
logger;
|
|
20
|
-
constructor(client,
|
|
21
|
-
// @ts-expect-error - Reserved for future RLS context support in transactions
|
|
22
|
-
_rlsManager, logger) {
|
|
23
|
-
this.client = client;
|
|
24
|
-
this._rlsManager = _rlsManager;
|
|
25
|
-
this.id = `txn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
26
|
-
this.logger = logger;
|
|
27
|
-
if (this.logger) {
|
|
28
|
-
this.logger.debug('Transaction created', { id: this.id });
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Execute query within transaction
|
|
33
|
-
*/
|
|
34
|
-
async query(sql, params) {
|
|
35
|
-
if (!this.active) {
|
|
36
|
-
throw new Error('Transaction is not active');
|
|
37
|
-
}
|
|
38
|
-
const startTime = Date.now();
|
|
39
|
-
try {
|
|
40
|
-
const result = await this.client.query(sql, params);
|
|
41
|
-
const duration = Date.now() - startTime;
|
|
42
|
-
if (this.logger) {
|
|
43
|
-
this.logger.debug('Transaction query executed', {
|
|
44
|
-
transactionId: this.id,
|
|
45
|
-
duration,
|
|
46
|
-
rowCount: result.rowCount,
|
|
47
|
-
command: result.command
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
rows: result.rows,
|
|
52
|
-
rowCount: result.rowCount || 0,
|
|
53
|
-
fields: result.fields.map(f => ({
|
|
54
|
-
name: f.name,
|
|
55
|
-
dataTypeID: f.dataTypeID,
|
|
56
|
-
dataTypeName: this.getDataTypeName(f.dataTypeID),
|
|
57
|
-
nullable: true
|
|
58
|
-
})),
|
|
59
|
-
command: result.command
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
if (this.logger) {
|
|
64
|
-
this.logger.error('Transaction query failed', error instanceof Error ? error : new Error(String(error)), {
|
|
65
|
-
transactionId: this.id,
|
|
66
|
-
duration: Date.now() - startTime
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Commit transaction and release client
|
|
74
|
-
*/
|
|
75
|
-
async commit() {
|
|
76
|
-
if (!this.active) {
|
|
77
|
-
throw new Error('Transaction is not active');
|
|
78
|
-
}
|
|
79
|
-
const startTime = Date.now();
|
|
80
|
-
try {
|
|
81
|
-
await this.client.query('COMMIT');
|
|
82
|
-
this.active = false;
|
|
83
|
-
if (this.logger) {
|
|
84
|
-
this.logger.debug('Transaction committed', {
|
|
85
|
-
transactionId: this.id,
|
|
86
|
-
duration: Date.now() - startTime
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
if (this.logger) {
|
|
92
|
-
this.logger.error('Transaction commit failed', error instanceof Error ? error : new Error(String(error)), {
|
|
93
|
-
transactionId: this.id
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
finally {
|
|
99
|
-
this.client.release();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Rollback transaction and release client
|
|
104
|
-
*/
|
|
105
|
-
async rollback() {
|
|
106
|
-
if (!this.active) {
|
|
107
|
-
throw new Error('Transaction is not active');
|
|
108
|
-
}
|
|
109
|
-
const startTime = Date.now();
|
|
110
|
-
try {
|
|
111
|
-
await this.client.query('ROLLBACK');
|
|
112
|
-
this.active = false;
|
|
113
|
-
if (this.logger) {
|
|
114
|
-
this.logger.debug('Transaction rolled back', {
|
|
115
|
-
transactionId: this.id,
|
|
116
|
-
duration: Date.now() - startTime
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
if (this.logger) {
|
|
122
|
-
this.logger.error('Transaction rollback failed', error instanceof Error ? error : new Error(String(error)), {
|
|
123
|
-
transactionId: this.id
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
throw error;
|
|
127
|
-
}
|
|
128
|
-
finally {
|
|
129
|
-
this.client.release();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Create a savepoint within the transaction
|
|
134
|
-
*/
|
|
135
|
-
async savepoint(name) {
|
|
136
|
-
if (!this.active) {
|
|
137
|
-
throw new Error('Transaction is not active');
|
|
138
|
-
}
|
|
139
|
-
await this.client.query(`SAVEPOINT ${name}`);
|
|
140
|
-
if (this.logger) {
|
|
141
|
-
this.logger.debug('Savepoint created', {
|
|
142
|
-
transactionId: this.id,
|
|
143
|
-
savepoint: name
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Rollback to a savepoint
|
|
149
|
-
*/
|
|
150
|
-
async rollbackToSavepoint(name) {
|
|
151
|
-
if (!this.active) {
|
|
152
|
-
throw new Error('Transaction is not active');
|
|
153
|
-
}
|
|
154
|
-
await this.client.query(`ROLLBACK TO SAVEPOINT ${name}`);
|
|
155
|
-
if (this.logger) {
|
|
156
|
-
this.logger.debug('Rolled back to savepoint', {
|
|
157
|
-
transactionId: this.id,
|
|
158
|
-
savepoint: name
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Release a savepoint
|
|
164
|
-
*/
|
|
165
|
-
async releaseSavepoint(name) {
|
|
166
|
-
if (!this.active) {
|
|
167
|
-
throw new Error('Transaction is not active');
|
|
168
|
-
}
|
|
169
|
-
await this.client.query(`RELEASE SAVEPOINT ${name}`);
|
|
170
|
-
if (this.logger) {
|
|
171
|
-
this.logger.debug('Savepoint released', {
|
|
172
|
-
transactionId: this.id,
|
|
173
|
-
savepoint: name
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Check if transaction is still active
|
|
179
|
-
*/
|
|
180
|
-
isActive() {
|
|
181
|
-
return this.active;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Map PostgreSQL data type OID to name
|
|
185
|
-
*/
|
|
186
|
-
getDataTypeName(oid) {
|
|
187
|
-
const typeMap = {
|
|
188
|
-
16: 'BOOL',
|
|
189
|
-
20: 'BIGINT',
|
|
190
|
-
21: 'SMALLINT',
|
|
191
|
-
23: 'INTEGER',
|
|
192
|
-
25: 'TEXT',
|
|
193
|
-
114: 'JSON',
|
|
194
|
-
1043: 'VARCHAR',
|
|
195
|
-
1082: 'DATE',
|
|
196
|
-
1114: 'TIMESTAMP',
|
|
197
|
-
1184: 'TIMESTAMPTZ',
|
|
198
|
-
3802: 'JSONB'
|
|
199
|
-
};
|
|
200
|
-
return typeMap[oid] || 'UNKNOWN';
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
exports.PostgreSQLTransaction = PostgreSQLTransaction;
|
package/dist/errors.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type DatabaseAdapterPostgresqlErrorCode = 'DATABASE_ADAPTER_POSTGRESQL_ERROR' | 'INVALID_INPUT' | 'OPERATION_FAILED';
|
|
2
|
-
export interface DatabaseAdapterPostgresqlErrorOptions {
|
|
3
|
-
cause?: Error;
|
|
4
|
-
code?: DatabaseAdapterPostgresqlErrorCode;
|
|
5
|
-
context?: Record<string, unknown>;
|
|
6
|
-
}
|
|
7
|
-
export declare class DatabaseAdapterPostgresqlError extends Error {
|
|
8
|
-
readonly code: DatabaseAdapterPostgresqlErrorCode;
|
|
9
|
-
readonly context?: Record<string, unknown>;
|
|
10
|
-
constructor(message: string, options?: DatabaseAdapterPostgresqlErrorOptions);
|
|
11
|
-
}
|
package/dist/errors.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2025 Bernier LLC
|
|
4
|
-
|
|
5
|
-
This file is licensed to the client under a limited-use license.
|
|
6
|
-
The client may use and modify this code only within the scope of the project it was delivered for.
|
|
7
|
-
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.DatabaseAdapterPostgresqlError = void 0;
|
|
11
|
-
class DatabaseAdapterPostgresqlError extends Error {
|
|
12
|
-
code;
|
|
13
|
-
context;
|
|
14
|
-
constructor(message, options) {
|
|
15
|
-
super(message, options?.cause ? { cause: options.cause } : undefined);
|
|
16
|
-
this.name = 'DatabaseAdapterPostgresqlError';
|
|
17
|
-
this.code = options?.code ?? 'DATABASE_ADAPTER_POSTGRESQL_ERROR';
|
|
18
|
-
if (options?.context !== undefined) {
|
|
19
|
-
this.context = options.context;
|
|
20
|
-
}
|
|
21
|
-
Error.captureStackTrace?.(this, this.constructor);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.DatabaseAdapterPostgresqlError = DatabaseAdapterPostgresqlError;
|
package/dist/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { DatabaseAdapterPostgresqlError, type DatabaseAdapterPostgresqlErrorCode, type DatabaseAdapterPostgresqlErrorOptions, } from './errors';
|
|
2
|
-
export { PostgreSQLAdapter, ISupabaseConfig } from './PostgreSQLAdapter';
|
|
3
|
-
export { PostgreSQLTransaction } from './PostgreSQLTransaction';
|
|
4
|
-
export { RLSPolicyGenerator } from './rls/RLSPolicyGenerator';
|
|
5
|
-
export { ClerkIntegration } from './rls/ClerkIntegration';
|
|
6
|
-
export { RealtimeManager, RealtimePayload, RealtimeCallbacks, PresenceData } from './realtime/RealtimeManager';
|
|
7
|
-
export { FullTextSearchManager, SearchResult, SearchOptions } from './search/FullTextSearchManager';
|
|
8
|
-
export { migration_001_initial_schema } from './migrations/001_initial_schema';
|
package/dist/index.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2025 Bernier LLC
|
|
4
|
-
|
|
5
|
-
This file is licensed to the client under a limited-use license.
|
|
6
|
-
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
-
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.migration_001_initial_schema = exports.FullTextSearchManager = exports.RealtimeManager = exports.ClerkIntegration = exports.RLSPolicyGenerator = exports.PostgreSQLTransaction = exports.PostgreSQLAdapter = exports.DatabaseAdapterPostgresqlError = void 0;
|
|
11
|
-
// Errors
|
|
12
|
-
var errors_1 = require("./errors");
|
|
13
|
-
Object.defineProperty(exports, "DatabaseAdapterPostgresqlError", { enumerable: true, get: function () { return errors_1.DatabaseAdapterPostgresqlError; } });
|
|
14
|
-
// Main adapter
|
|
15
|
-
var PostgreSQLAdapter_1 = require("./PostgreSQLAdapter");
|
|
16
|
-
Object.defineProperty(exports, "PostgreSQLAdapter", { enumerable: true, get: function () { return PostgreSQLAdapter_1.PostgreSQLAdapter; } });
|
|
17
|
-
var PostgreSQLTransaction_1 = require("./PostgreSQLTransaction");
|
|
18
|
-
Object.defineProperty(exports, "PostgreSQLTransaction", { enumerable: true, get: function () { return PostgreSQLTransaction_1.PostgreSQLTransaction; } });
|
|
19
|
-
// RLS components
|
|
20
|
-
var RLSPolicyGenerator_1 = require("./rls/RLSPolicyGenerator");
|
|
21
|
-
Object.defineProperty(exports, "RLSPolicyGenerator", { enumerable: true, get: function () { return RLSPolicyGenerator_1.RLSPolicyGenerator; } });
|
|
22
|
-
var ClerkIntegration_1 = require("./rls/ClerkIntegration");
|
|
23
|
-
Object.defineProperty(exports, "ClerkIntegration", { enumerable: true, get: function () { return ClerkIntegration_1.ClerkIntegration; } });
|
|
24
|
-
// Real-time
|
|
25
|
-
var RealtimeManager_1 = require("./realtime/RealtimeManager");
|
|
26
|
-
Object.defineProperty(exports, "RealtimeManager", { enumerable: true, get: function () { return RealtimeManager_1.RealtimeManager; } });
|
|
27
|
-
// Search
|
|
28
|
-
var FullTextSearchManager_1 = require("./search/FullTextSearchManager");
|
|
29
|
-
Object.defineProperty(exports, "FullTextSearchManager", { enumerable: true, get: function () { return FullTextSearchManager_1.FullTextSearchManager; } });
|
|
30
|
-
// Migrations
|
|
31
|
-
var _001_initial_schema_1 = require("./migrations/001_initial_schema");
|
|
32
|
-
Object.defineProperty(exports, "migration_001_initial_schema", { enumerable: true, get: function () { return _001_initial_schema_1.migration_001_initial_schema; } });
|