@bernierllc/database-adapter-core 1.0.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.
Files changed (68) hide show
  1. package/README.md +467 -0
  2. package/dist/base/BaseDatabaseAdapter.d.ts +34 -0
  3. package/dist/base/BaseDatabaseAdapter.d.ts.map +1 -0
  4. package/dist/base/BaseDatabaseAdapter.js +52 -0
  5. package/dist/base/BaseMigrationManager.d.ts +41 -0
  6. package/dist/base/BaseMigrationManager.d.ts.map +1 -0
  7. package/dist/base/BaseMigrationManager.js +113 -0
  8. package/dist/base/BaseQueryBuilder.d.ts +68 -0
  9. package/dist/base/BaseQueryBuilder.d.ts.map +1 -0
  10. package/dist/base/BaseQueryBuilder.js +103 -0
  11. package/dist/base/BaseTransaction.d.ts +13 -0
  12. package/dist/base/BaseTransaction.d.ts.map +1 -0
  13. package/dist/base/BaseTransaction.js +17 -0
  14. package/dist/base/index.d.ts +5 -0
  15. package/dist/base/index.d.ts.map +1 -0
  16. package/dist/base/index.js +27 -0
  17. package/dist/errors/ConnectionError.d.ts +17 -0
  18. package/dist/errors/ConnectionError.d.ts.map +1 -0
  19. package/dist/errors/ConnectionError.js +27 -0
  20. package/dist/errors/DatabaseError.d.ts +16 -0
  21. package/dist/errors/DatabaseError.d.ts.map +1 -0
  22. package/dist/errors/DatabaseError.js +27 -0
  23. package/dist/errors/QueryError.d.ts +17 -0
  24. package/dist/errors/QueryError.d.ts.map +1 -0
  25. package/dist/errors/QueryError.js +27 -0
  26. package/dist/errors/index.d.ts +4 -0
  27. package/dist/errors/index.d.ts.map +1 -0
  28. package/dist/errors/index.js +26 -0
  29. package/dist/index.d.ts +11 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +37 -0
  32. package/dist/interfaces/IConnectionPool.d.ts +41 -0
  33. package/dist/interfaces/IConnectionPool.d.ts.map +1 -0
  34. package/dist/interfaces/IConnectionPool.js +9 -0
  35. package/dist/interfaces/IDatabaseAdapter.d.ts +45 -0
  36. package/dist/interfaces/IDatabaseAdapter.d.ts.map +1 -0
  37. package/dist/interfaces/IDatabaseAdapter.js +9 -0
  38. package/dist/interfaces/IDatabaseConfig.d.ts +40 -0
  39. package/dist/interfaces/IDatabaseConfig.d.ts.map +1 -0
  40. package/dist/interfaces/IDatabaseConfig.js +9 -0
  41. package/dist/interfaces/IDatabaseHealth.d.ts +16 -0
  42. package/dist/interfaces/IDatabaseHealth.d.ts.map +1 -0
  43. package/dist/interfaces/IDatabaseHealth.js +9 -0
  44. package/dist/interfaces/IMigration.d.ts +54 -0
  45. package/dist/interfaces/IMigration.d.ts.map +1 -0
  46. package/dist/interfaces/IMigration.js +9 -0
  47. package/dist/interfaces/IQueryBuilder.d.ts +106 -0
  48. package/dist/interfaces/IQueryBuilder.d.ts.map +1 -0
  49. package/dist/interfaces/IQueryBuilder.js +9 -0
  50. package/dist/interfaces/IQueryResult.d.ts +28 -0
  51. package/dist/interfaces/IQueryResult.d.ts.map +1 -0
  52. package/dist/interfaces/IQueryResult.js +9 -0
  53. package/dist/interfaces/IRLSContext.d.ts +15 -0
  54. package/dist/interfaces/IRLSContext.d.ts.map +1 -0
  55. package/dist/interfaces/IRLSContext.js +9 -0
  56. package/dist/interfaces/ITransaction.d.ts +32 -0
  57. package/dist/interfaces/ITransaction.d.ts.map +1 -0
  58. package/dist/interfaces/ITransaction.js +9 -0
  59. package/dist/interfaces/index.d.ts +10 -0
  60. package/dist/interfaces/index.d.ts.map +1 -0
  61. package/dist/interfaces/index.js +32 -0
  62. package/dist/rls/RLSContextManager.d.ts +45 -0
  63. package/dist/rls/RLSContextManager.d.ts.map +1 -0
  64. package/dist/rls/RLSContextManager.js +88 -0
  65. package/dist/rls/index.d.ts +2 -0
  66. package/dist/rls/index.d.ts.map +1 -0
  67. package/dist/rls/index.js +24 -0
  68. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,467 @@
1
+ # @bernierllc/database-adapter-core
2
+
3
+ Abstract Database Interface for MECE Architecture - provides database-agnostic interfaces and base implementations for all database operations across BernierLLC tools.
4
+
5
+ ## Features
6
+
7
+ - **Abstract Database Interfaces** - Clean, database-agnostic interfaces for all database operations
8
+ - **Base Implementations** - Common functionality through abstract base classes
9
+ - **Row Level Security (RLS)** - Built-in support for multi-tenant security and user-based access control
10
+ - **Query Builder Foundation** - Type-safe SQL generation without string concatenation
11
+ - **Migration System** - Schema migration tracking and execution
12
+ - **Transaction Support** - ACID transaction interfaces
13
+ - **Connection Pooling** - Interface for connection pool management
14
+ - **Error Handling** - Structured error classes with sensitive data sanitization
15
+ - **Type-Safe** - Full TypeScript support with strict mode
16
+ - **Zero Runtime Overhead** - Pure interfaces and abstract classes
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @bernierllc/database-adapter-core
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Creating a Database Adapter
27
+
28
+ Extend `BaseDatabaseAdapter` to create a concrete database implementation:
29
+
30
+ ```typescript
31
+ import {
32
+ BaseDatabaseAdapter,
33
+ IDatabaseConfig,
34
+ IQueryResult,
35
+ ITransaction,
36
+ IDatabaseHealth,
37
+ ConnectionError
38
+ } from '@bernierllc/database-adapter-core';
39
+
40
+ class PostgreSQLAdapter extends BaseDatabaseAdapter {
41
+ private pool: pg.Pool;
42
+
43
+ async connect(): Promise<void> {
44
+ try {
45
+ this.pool = new pg.Pool({
46
+ host: this.config.host,
47
+ port: this.config.port,
48
+ database: this.config.database,
49
+ user: this.config.username,
50
+ password: this.config.password
51
+ });
52
+
53
+ await this.pool.connect();
54
+ this.connected = true;
55
+ } catch (error) {
56
+ throw new ConnectionError(
57
+ 'Failed to connect to PostgreSQL',
58
+ 'CONNECTION_FAILED',
59
+ error as Error,
60
+ this.config.host,
61
+ this.config.port
62
+ );
63
+ }
64
+ }
65
+
66
+ async disconnect(): Promise<void> {
67
+ await this.pool.end();
68
+ this.connected = false;
69
+ }
70
+
71
+ async query<T>(sql: string, params?: any[]): Promise<IQueryResult<T>> {
72
+ this.ensureConnected();
73
+
74
+ try {
75
+ const result = await this.pool.query(sql, params);
76
+ return {
77
+ rows: result.rows as T[],
78
+ rowCount: result.rowCount || 0,
79
+ fields: result.fields.map(f => ({
80
+ name: f.name,
81
+ dataTypeID: f.dataTypeID,
82
+ dataTypeName: f.dataTypeName,
83
+ nullable: true
84
+ })),
85
+ command: result.command
86
+ };
87
+ } catch (error) {
88
+ throw this.sanitizeError(error);
89
+ }
90
+ }
91
+
92
+ async beginTransaction(): Promise<ITransaction> {
93
+ this.ensureConnected();
94
+ // Implementation details...
95
+ }
96
+
97
+ async healthCheck(): Promise<IDatabaseHealth> {
98
+ const start = Date.now();
99
+ await this.query('SELECT 1');
100
+ const latencyMs = Date.now() - start;
101
+
102
+ return {
103
+ connected: this.connected,
104
+ latencyMs,
105
+ version: '15.0',
106
+ activeConnections: this.pool.totalCount,
107
+ maxConnections: this.pool.options.max
108
+ };
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### Using Row Level Security (RLS)
114
+
115
+ ```typescript
116
+ import { RLSContextManager, IRLSContext } from '@bernierllc/database-adapter-core';
117
+
118
+ const rlsManager = new RLSContextManager();
119
+
120
+ // Set RLS context for multi-tenant security
121
+ const context: IRLSContext = {
122
+ userId: 'user-123',
123
+ userRole: 'admin',
124
+ tenantId: 'tenant-456',
125
+ claims: { department: 'engineering' }
126
+ };
127
+
128
+ // Execute operations with RLS context
129
+ await rlsManager.withContext(context, async () => {
130
+ // All database operations here will have RLS context applied
131
+ const users = await adapter.query('SELECT * FROM users');
132
+ // PostgreSQL RLS policies will automatically filter based on context
133
+ });
134
+
135
+ // Generate PostgreSQL SET statements for RLS
136
+ rlsManager.setContext(context);
137
+ const statements = rlsManager.generateRLSStatements();
138
+ // [
139
+ // 'SET LOCAL "app.user_id" = \'user-123\';',
140
+ // 'SET LOCAL "app.user_role" = \'admin\';',
141
+ // 'SET LOCAL "app.tenant_id" = \'tenant-456\';',
142
+ // 'SET LOCAL "app.claims" = \'{"department":"engineering"}\';'
143
+ // ]
144
+ ```
145
+
146
+ ### Building Type-Safe Queries
147
+
148
+ ```typescript
149
+ import { BaseQueryBuilder } from '@bernierllc/database-adapter-core';
150
+
151
+ class PostgreSQLQueryBuilder extends BaseQueryBuilder<User> {
152
+ insert(data: Partial<User>): this {
153
+ // Implementation for INSERT
154
+ return this;
155
+ }
156
+
157
+ update(data: Partial<User>): this {
158
+ // Implementation for UPDATE
159
+ return this;
160
+ }
161
+
162
+ delete(): this {
163
+ // Implementation for DELETE
164
+ return this;
165
+ }
166
+
167
+ build(): { sql: string; params: any[] } {
168
+ // Build PostgreSQL-specific SQL
169
+ let sql = `SELECT ${this._select.join(', ')} FROM ${this._from}`;
170
+ if (this._where.length > 0) {
171
+ sql += ` WHERE ${this._where.join(' AND ')}`;
172
+ }
173
+ return { sql, params: this._params };
174
+ }
175
+ }
176
+
177
+ // Usage
178
+ const query = new PostgreSQLQueryBuilder()
179
+ .select('id', 'name', 'email')
180
+ .from('users')
181
+ .where('age > $1', [18])
182
+ .where('status = $2', ['active'])
183
+ .orderBy('name', 'ASC')
184
+ .limit(10)
185
+ .offset(20);
186
+
187
+ const result = await query.execute(adapter);
188
+ ```
189
+
190
+ ### Managing Migrations
191
+
192
+ ```typescript
193
+ import {
194
+ BaseMigrationManager,
195
+ IMigration,
196
+ IDatabaseAdapter
197
+ } from '@bernierllc/database-adapter-core';
198
+
199
+ const migrations: IMigration[] = [
200
+ {
201
+ id: '001',
202
+ name: 'create_users_table',
203
+ async up(adapter: IDatabaseAdapter) {
204
+ await adapter.query(`
205
+ CREATE TABLE users (
206
+ id SERIAL PRIMARY KEY,
207
+ name VARCHAR(255) NOT NULL,
208
+ email VARCHAR(255) UNIQUE NOT NULL,
209
+ created_at TIMESTAMPTZ DEFAULT NOW()
210
+ )
211
+ `);
212
+ },
213
+ async down(adapter: IDatabaseAdapter) {
214
+ await adapter.query('DROP TABLE users');
215
+ }
216
+ },
217
+ {
218
+ id: '002',
219
+ name: 'add_users_status',
220
+ async up(adapter: IDatabaseAdapter) {
221
+ await adapter.query(`
222
+ ALTER TABLE users ADD COLUMN status VARCHAR(50) DEFAULT 'active'
223
+ `);
224
+ },
225
+ async down(adapter: IDatabaseAdapter) {
226
+ await adapter.query('ALTER TABLE users DROP COLUMN status');
227
+ }
228
+ }
229
+ ];
230
+
231
+ const migrationManager = new BaseMigrationManager(adapter, migrations);
232
+
233
+ // Run pending migrations
234
+ await migrationManager.up();
235
+
236
+ // Get migration status
237
+ const status = await migrationManager.status();
238
+ console.log(status);
239
+ // [
240
+ // { id: '001', name: 'create_users_table', status: 'applied', appliedAt: Date },
241
+ // { id: '002', name: 'add_users_status', status: 'applied', appliedAt: Date }
242
+ // ]
243
+
244
+ // Rollback last migration
245
+ await migrationManager.down();
246
+ ```
247
+
248
+ ### Error Handling
249
+
250
+ ```typescript
251
+ import {
252
+ DatabaseError,
253
+ ConnectionError,
254
+ QueryError
255
+ } from '@bernierllc/database-adapter-core';
256
+
257
+ try {
258
+ await adapter.connect();
259
+ } catch (error) {
260
+ if (error instanceof ConnectionError) {
261
+ console.error(`Connection failed: ${error.host}:${error.port}`);
262
+ console.error(`Error code: ${error.code}`);
263
+ }
264
+ }
265
+
266
+ try {
267
+ await adapter.query('SELECT * FROM users WHERE id = $1', [userId]);
268
+ } catch (error) {
269
+ if (error instanceof QueryError) {
270
+ console.error(`Query failed: ${error.query}`);
271
+ console.error(`Parameters: ${error.params}`);
272
+ }
273
+ }
274
+ ```
275
+
276
+ ## API Reference
277
+
278
+ ### Interfaces
279
+
280
+ #### `IDatabaseAdapter`
281
+ Main adapter interface that all concrete adapters must implement.
282
+
283
+ **Methods:**
284
+ - `connect(): Promise<void>` - Connect to database
285
+ - `disconnect(): Promise<void>` - Disconnect from database
286
+ - `isConnected(): boolean` - Check connection status
287
+ - `query<T>(sql: string, params?: any[]): Promise<IQueryResult<T>>` - Execute query
288
+ - `beginTransaction(): Promise<ITransaction>` - Begin transaction
289
+ - `healthCheck(): Promise<IDatabaseHealth>` - Check database health
290
+
291
+ #### `ITransaction`
292
+ Transaction interface for ACID operations.
293
+
294
+ **Methods:**
295
+ - `query<T>(sql: string, params?: any[]): Promise<IQueryResult<T>>` - Execute query in transaction
296
+ - `commit(): Promise<void>` - Commit transaction
297
+ - `rollback(): Promise<void>` - Rollback transaction
298
+ - `isActive(): boolean` - Check if transaction is active
299
+
300
+ #### `IQueryResult<T>`
301
+ Query result with metadata.
302
+
303
+ **Properties:**
304
+ - `rows: T[]` - Result rows
305
+ - `rowCount: number` - Number of rows returned
306
+ - `fields: IFieldInfo[]` - Field metadata
307
+ - `command: string` - SQL command (SELECT, INSERT, UPDATE, DELETE)
308
+
309
+ #### `IDatabaseConfig`
310
+ Database connection configuration.
311
+
312
+ **Properties:**
313
+ - `type: 'postgresql' | 'mysql' | 'sqlite' | 'mssql'` - Database type
314
+ - `host?: string` - Host address
315
+ - `port?: number` - Port number
316
+ - `database: string` - Database name
317
+ - `username?: string` - Username
318
+ - `password?: string` - Password
319
+ - `ssl?: boolean | object` - SSL configuration
320
+ - `pooling?: object` - Connection pooling settings
321
+
322
+ #### `IRLSContext`
323
+ Row Level Security context.
324
+
325
+ **Properties:**
326
+ - `userId: string` - User ID
327
+ - `userRole: string` - User role
328
+ - `tenantId?: string` - Tenant ID (optional)
329
+ - `claims?: Record<string, any>` - Additional claims (optional)
330
+
331
+ ### Base Classes
332
+
333
+ #### `BaseDatabaseAdapter`
334
+ Abstract base class providing common adapter functionality.
335
+
336
+ **Methods:**
337
+ - `isConnected(): boolean` - Returns connection status
338
+ - `ensureConnected(): void` - Throws error if not connected
339
+ - `sanitizeError(error: unknown): Error` - Removes sensitive data from errors
340
+
341
+ #### `BaseQueryBuilder<T>`
342
+ Abstract query builder with fluent API.
343
+
344
+ **Methods:**
345
+ - `select(...columns: string[]): this`
346
+ - `from(table: string): this`
347
+ - `where(condition: string, params?: readonly unknown[]): this`
348
+ - `whereIn(column: string, values: readonly unknown[]): this`
349
+ - `join(table: string, condition: string): this`
350
+ - `leftJoin(table: string, condition: string): this`
351
+ - `orderBy(column: string, direction?: 'ASC' | 'DESC'): this`
352
+ - `limit(count: number): this`
353
+ - `offset(count: number): this`
354
+ - `execute(adapter: IDatabaseAdapter): Promise<IQueryResult<T>>`
355
+
356
+ #### `BaseMigrationManager`
357
+ Migration manager for schema changes.
358
+
359
+ **Methods:**
360
+ - `up(): Promise<void>` - Run pending migrations
361
+ - `down(): Promise<void>` - Rollback last migration
362
+ - `status(): Promise<IMigrationStatus[]>` - Get migration status
363
+
364
+ ### Utilities
365
+
366
+ #### `RLSContextManager`
367
+ Row Level Security context manager.
368
+
369
+ **Methods:**
370
+ - `setContext(context: IRLSContext): void` - Set RLS context
371
+ - `getContext(): IRLSContext | null` - Get current context
372
+ - `clearContext(): void` - Clear context
373
+ - `withContext<T>(context: IRLSContext, fn: () => Promise<T>): Promise<T>` - Execute with context
374
+ - `generateRLSStatements(): string[]` - Generate PostgreSQL SET statements
375
+
376
+ ### Error Classes
377
+
378
+ - `DatabaseError` - Base database error
379
+ - `ConnectionError` - Connection-specific errors
380
+ - `QueryError` - Query-specific errors
381
+
382
+ ## Integration Status
383
+
384
+ ### Logger Integration
385
+ **Status**: Optional - Can be integrated for error logging and query tracing
386
+
387
+ Adapters can optionally use `@bernierllc/logger` for:
388
+ - Connection lifecycle logging
389
+ - Query execution tracing
390
+ - Error logging with context
391
+
392
+ ### Docs-Suite Integration
393
+ **Status**: Ready
394
+
395
+ This package includes complete JSDoc/TypeDoc comments and can be integrated with documentation generators:
396
+ - All public APIs documented
397
+ - Interface documentation complete
398
+ - Examples included
399
+
400
+ ### NeverHub Integration
401
+ **Status**: Not Applicable
402
+
403
+ This is a pure interface package with no runtime behavior requiring service discovery or event communication.
404
+
405
+ ## Dependencies
406
+
407
+ - `@bernierllc/logger` - Structured logging (optional usage)
408
+ - `@bernierllc/crypto-utils` - For secure token generation in adapters
409
+
410
+ ## Testing
411
+
412
+ This package has comprehensive test coverage:
413
+ - **90.27%** statement coverage
414
+ - **90.47%** branch coverage
415
+ - **100%** function coverage
416
+ - **90%** line coverage
417
+ - **65 passing tests**
418
+
419
+ Run tests:
420
+ ```bash
421
+ npm test # Watch mode
422
+ npm run test:run # Single run
423
+ npm run test:coverage # With coverage report
424
+ ```
425
+
426
+ ## Building
427
+
428
+ ```bash
429
+ npm run build # Compile TypeScript
430
+ npm run lint # Run ESLint
431
+ npm run clean # Remove build artifacts
432
+ ```
433
+
434
+ ## Related Packages
435
+
436
+ ### Depends On
437
+ - [@bernierllc/logger](../logger) - Structured logging
438
+ - [@bernierllc/crypto-utils](../crypto-utils) - Cryptographic utilities
439
+
440
+ ### Used By
441
+ - `@bernierllc/database-adapter-postgresql` - PostgreSQL implementation (coming soon)
442
+ - `@bernierllc/content-storage-adapter` - Content CRUD operations (coming soon)
443
+ - All packages requiring database access
444
+
445
+ ### Part Of
446
+ - **content-management-suite** - Database foundation layer
447
+
448
+ ## Design Philosophy
449
+
450
+ This package follows MECE (Mutually Exclusive, Collectively Exhaustive) architecture principles:
451
+
452
+ - **Abstract Interfaces** - No concrete database implementations
453
+ - **Single Responsibility** - Pure interface definitions and base utilities
454
+ - **Zero Coupling** - Implementations are separate packages
455
+ - **Adapter Pattern** - Clean abstraction layer for all database operations
456
+
457
+ By keeping interfaces separate from implementations, we enable:
458
+ - **Pluggable Backends** - Switch databases without changing application code
459
+ - **Testability** - Mock adapters easily for testing
460
+ - **Flexibility** - Support multiple databases simultaneously
461
+ - **Maintainability** - Changes to one adapter don't affect others
462
+
463
+ ## License
464
+
465
+ Copyright (c) 2025 Bernier LLC. All rights reserved.
466
+
467
+ This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
@@ -0,0 +1,34 @@
1
+ import { IDatabaseAdapter, IDatabaseConfig, IDatabaseHealth, IQueryResult, ITransaction } from '../interfaces';
2
+ /**
3
+ * Abstract base class for database adapters
4
+ * Provides common functionality for all implementations
5
+ */
6
+ export declare abstract class BaseDatabaseAdapter implements IDatabaseAdapter {
7
+ protected config: IDatabaseConfig;
8
+ protected connected: boolean;
9
+ constructor(config: IDatabaseConfig);
10
+ /**
11
+ * Abstract methods - MUST be implemented by concrete adapters
12
+ */
13
+ abstract connect(): Promise<void>;
14
+ abstract disconnect(): Promise<void>;
15
+ abstract query<T = any>(sql: string, params?: any[]): Promise<IQueryResult<T>>;
16
+ abstract beginTransaction(): Promise<ITransaction>;
17
+ abstract healthCheck(): Promise<IDatabaseHealth>;
18
+ /**
19
+ * Check if database is connected
20
+ */
21
+ isConnected(): boolean;
22
+ /**
23
+ * Ensure database is connected before operations
24
+ * @throws ConnectionError if not connected
25
+ */
26
+ protected ensureConnected(): void;
27
+ /**
28
+ * Sanitize error messages to remove sensitive data
29
+ * @param error - Original error
30
+ * @returns Sanitized error
31
+ */
32
+ protected sanitizeError(error: unknown): Error;
33
+ }
34
+ //# sourceMappingURL=BaseDatabaseAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../src/base/BaseDatabaseAdapter.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACb,MAAM,eAAe,CAAC;AAGvB;;;GAGG;AACH,8BAAsB,mBAAoB,YAAW,gBAAgB;IACnE,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC;IAClC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;gBAEzB,MAAM,EAAE,eAAe;IAInC;;OAEG;IACH,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9E,QAAQ,CAAC,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC;IAClD,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAEhD;;OAEG;IACI,WAAW,IAAI,OAAO;IAI7B;;;OAGG;IACH,SAAS,CAAC,eAAe,IAAI,IAAI;IASjC;;;;OAIG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK;CAa/C"}
@@ -0,0 +1,52 @@
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.BaseDatabaseAdapter = void 0;
11
+ const errors_1 = require("../errors");
12
+ /**
13
+ * Abstract base class for database adapters
14
+ * Provides common functionality for all implementations
15
+ */
16
+ class BaseDatabaseAdapter {
17
+ constructor(config) {
18
+ this.connected = false;
19
+ this.config = config;
20
+ }
21
+ /**
22
+ * Check if database is connected
23
+ */
24
+ isConnected() {
25
+ return this.connected;
26
+ }
27
+ /**
28
+ * Ensure database is connected before operations
29
+ * @throws ConnectionError if not connected
30
+ */
31
+ ensureConnected() {
32
+ if (!this.connected) {
33
+ throw new errors_1.ConnectionError('Database not connected. Call connect() first.', 'NOT_CONNECTED');
34
+ }
35
+ }
36
+ /**
37
+ * Sanitize error messages to remove sensitive data
38
+ * @param error - Original error
39
+ * @returns Sanitized error
40
+ */
41
+ sanitizeError(error) {
42
+ const message = error instanceof Error ? error.message : 'Database error';
43
+ // Remove sensitive data patterns from error messages
44
+ const sanitized = message
45
+ .replace(/password[^\s]*/gi, 'password=***')
46
+ .replace(/secret[^\s]*/gi, 'secret=***')
47
+ .replace(/token[^\s]*/gi, 'token=***')
48
+ .replace(/key[^\s]*/gi, 'key=***');
49
+ return new Error(sanitized);
50
+ }
51
+ }
52
+ exports.BaseDatabaseAdapter = BaseDatabaseAdapter;
@@ -0,0 +1,41 @@
1
+ import { IDatabaseAdapter, IMigration, IMigrationManager, IMigrationStatus } from '../interfaces';
2
+ /**
3
+ * Base migration manager implementation
4
+ * Tracks and executes schema migrations
5
+ */
6
+ export declare class BaseMigrationManager implements IMigrationManager {
7
+ private adapter;
8
+ private migrations;
9
+ constructor(adapter: IDatabaseAdapter, migrations: IMigration[]);
10
+ /**
11
+ * Run all pending migrations
12
+ * @throws Error if any migration fails
13
+ */
14
+ up(): Promise<void>;
15
+ /**
16
+ * Rollback last applied migration
17
+ * @throws Error if no migrations to rollback or rollback fails
18
+ */
19
+ down(): Promise<void>;
20
+ /**
21
+ * Get status of all migrations
22
+ */
23
+ status(): Promise<IMigrationStatus[]>;
24
+ /**
25
+ * Ensure migrations table exists
26
+ */
27
+ private ensureMigrationsTable;
28
+ /**
29
+ * Get list of applied migration IDs in order
30
+ */
31
+ private getAppliedMigrations;
32
+ /**
33
+ * Record a migration as applied
34
+ */
35
+ private recordMigration;
36
+ /**
37
+ * Remove a migration record
38
+ */
39
+ private removeMigration;
40
+ }
41
+ //# sourceMappingURL=BaseMigrationManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseMigrationManager.d.ts","sourceRoot":"","sources":["../../src/base/BaseMigrationManager.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IAE1D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;gBADV,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,UAAU,EAAE;IAGlC;;;OAGG;IACU,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBhC;;;OAGG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBlC;;OAEG;IACU,MAAM,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAYlD;;OAEG;YACW,qBAAqB;IAUnC;;OAEG;YACW,oBAAoB;IAOlC;;OAEG;YACW,eAAe;IAO7B;;OAEG;YACW,eAAe;CAG9B"}