@plyaz/db 0.1.0 → 0.2.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 (62) hide show
  1. package/README.md +98 -134
  2. package/dist/adapters/drizzle/DrizzleAdapter.d.ts +109 -9
  3. package/dist/adapters/drizzle/DrizzleAdapter.d.ts.map +1 -1
  4. package/dist/adapters/index.d.ts +5 -0
  5. package/dist/adapters/index.d.ts.map +1 -1
  6. package/dist/adapters/mock/MockAdapter.d.ts +88 -0
  7. package/dist/adapters/mock/MockAdapter.d.ts.map +1 -0
  8. package/dist/adapters/sql/SQLAdapter.d.ts +29 -6
  9. package/dist/adapters/sql/SQLAdapter.d.ts.map +1 -1
  10. package/dist/adapters/supabase/SupabaseAdapter.d.ts +9 -2
  11. package/dist/adapters/supabase/SupabaseAdapter.d.ts.map +1 -1
  12. package/dist/advanced/multi-tenancy/TenantRepository.d.ts +1 -7
  13. package/dist/advanced/multi-tenancy/TenantRepository.d.ts.map +1 -1
  14. package/dist/advanced/read-replica/ReadReplicaAdapter.d.ts +3 -2
  15. package/dist/advanced/read-replica/ReadReplicaAdapter.d.ts.map +1 -1
  16. package/dist/cli/index.d.ts +27 -0
  17. package/dist/cli/index.d.ts.map +1 -0
  18. package/dist/cli/index.js +9201 -0
  19. package/dist/cli/index.js.map +1 -0
  20. package/dist/extensions/AuditExtension.d.ts +56 -9
  21. package/dist/extensions/AuditExtension.d.ts.map +1 -1
  22. package/dist/extensions/CachingAdapter.d.ts +5 -4
  23. package/dist/extensions/CachingAdapter.d.ts.map +1 -1
  24. package/dist/extensions/EncryptionExtension.d.ts +5 -4
  25. package/dist/extensions/EncryptionExtension.d.ts.map +1 -1
  26. package/dist/extensions/MultiReadExtension.d.ts +95 -0
  27. package/dist/extensions/MultiReadExtension.d.ts.map +1 -0
  28. package/dist/extensions/MultiWriteExtension.d.ts +67 -0
  29. package/dist/extensions/MultiWriteExtension.d.ts.map +1 -0
  30. package/dist/extensions/ReadReplicaAdapter.d.ts +4 -3
  31. package/dist/extensions/ReadReplicaAdapter.d.ts.map +1 -1
  32. package/dist/extensions/SoftDeleteExtension.d.ts +5 -4
  33. package/dist/extensions/SoftDeleteExtension.d.ts.map +1 -1
  34. package/dist/extensions/index.d.ts +4 -0
  35. package/dist/extensions/index.d.ts.map +1 -1
  36. package/dist/factory/AdapterFactory.d.ts.map +1 -1
  37. package/dist/factory/createDatabaseService.d.ts.map +1 -1
  38. package/dist/index.cjs +3298 -396
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.ts +6 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.mjs +4441 -1562
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/migrations/MigrationManager.d.ts +128 -0
  45. package/dist/migrations/MigrationManager.d.ts.map +1 -0
  46. package/dist/migrations/generateDownMigration.d.ts +25 -0
  47. package/dist/migrations/generateDownMigration.d.ts.map +1 -0
  48. package/dist/migrations/index.d.ts +10 -0
  49. package/dist/migrations/index.d.ts.map +1 -0
  50. package/dist/repository/BaseRepository.d.ts +109 -23
  51. package/dist/repository/BaseRepository.d.ts.map +1 -1
  52. package/dist/seeds/SeedManager.d.ts +120 -0
  53. package/dist/seeds/SeedManager.d.ts.map +1 -0
  54. package/dist/seeds/index.d.ts +10 -0
  55. package/dist/seeds/index.d.ts.map +1 -0
  56. package/dist/service/DatabaseService.d.ts +89 -13
  57. package/dist/service/DatabaseService.d.ts.map +1 -1
  58. package/dist/service/EventEmitter.d.ts +3 -14
  59. package/dist/service/EventEmitter.d.ts.map +1 -1
  60. package/dist/service/HealthManager.d.ts +42 -3
  61. package/dist/service/HealthManager.d.ts.map +1 -1
  62. package/package.json +9 -5
package/README.md CHANGED
@@ -1,169 +1,133 @@
1
- # 📦 Plyaz Package Template
1
+ # @plyaz/db
2
2
 
3
- This is the official Plyaz internal **package template** used to create and maintain shared libraries across all apps and services. It provides a consistent setup for TypeScript packages, full integration with `@plyaz/devtools`.
3
+ Database abstraction layer with support for multiple adapters, migrations, seeds, and enterprise features.
4
4
 
5
- Use this when creating packages like:
5
+ ## Installation
6
6
 
7
- - `@plyaz/types`
8
- - `@plyaz/api`
9
- - `@plyaz/errors`
10
- - `@plyaz/web3`
11
- - `@plyaz/config`
12
-
13
- ---
14
-
15
- ## 🚀 Getting Started
7
+ ```bash
8
+ pnpm add @plyaz/db
9
+ ```
16
10
 
17
- ### 🌀 Option 1: Use GitHub Template
11
+ ## Quick Start
18
12
 
19
- 1. Go to [@plyaz/package-template](https://github.com/Plyaz-Official/package-template).
20
- 2. Click **"Use this template"**.
21
- 3. Name your new repo (e.g. `@plyaz/errors`, `@plyaz/types`).
22
- 4. Clone the repo:
23
- ```bash
24
- git clone https://github.com/Plyaz-Official/package-template.git @plyaz/types
25
- cd @plyaz/types
26
- pnpm install
27
- ````
13
+ ### Configuration
28
14
 
29
- ### 🗂 Option 2: Manual Clone
15
+ Create a `db.config.mjs` in your project root:
30
16
 
31
- ```bash
32
- git clone https://github.com/Plyaz-Official/package-template.git @plyaz/my-package
33
- cd @plyaz/my-package
34
- pnpm install
17
+ ```javascript
18
+ /** @type {import('@plyaz/db').DatabaseServiceConfig} */
19
+ export default {
20
+ adapter: 'drizzle', // 'drizzle' | 'supabase' | 'sql' | 'mock'
21
+ config: {
22
+ connectionString: process.env.DATABASE_URL,
23
+ },
24
+ // Optional features
25
+ softDelete: { enabled: true },
26
+ audit: { enabled: true },
27
+ timestamps: { enabled: true },
28
+ };
35
29
  ```
36
30
 
37
- Then update:
31
+ ### Basic Usage
38
32
 
39
- * `package.json > name` → `@plyaz/my-package`
40
- * `package.json > disable-publish` Remove it
41
- * `README.md`, GitHub metadata, CI/CD labels
33
+ ```typescript
34
+ import { createDatabaseService } from '@plyaz/db';
35
+ import config from './db.config.mjs';
42
36
 
43
- ---
37
+ const db = await createDatabaseService(config);
44
38
 
45
- ## 📦 Project Structure
39
+ // Find records
40
+ const users = await db.findMany('users', {
41
+ filters: [{ field: 'status', operator: 'eq', value: 'active' }],
42
+ pagination: { limit: 10, offset: 0 },
43
+ });
46
44
 
47
- ```
48
- ├── src/
49
- │ └── index.ts # Main entry point (exports)
50
- ├──── test/
51
- │ └── index.test.ts # Unit tests using Vitest
52
- ├── package.json # Package metadata
53
- ├── tsconfig.json # Uses @plyaz/devtools base
54
- ├── eslint.config.mjs # Uses @plyaz/devtools eslint rules
55
- ├── .prettier.mjs # Uses @plyaz/devtools formatting rules
56
- ├── .vitest.config.mjs # Uses @plyaz/devtools vitest config
57
- ├── .vitest.setup.mjs # Uses @plyaz/devtools vitest setup
58
- ```
45
+ // Find by ID
46
+ const user = await db.findById('users', 'user-123');
59
47
 
60
- ---
48
+ // Create
49
+ const newUser = await db.create('users', { name: 'John', email: 'john@example.com' });
61
50
 
62
- ## 📜 Scripts & Commands
51
+ // Update
52
+ const updated = await db.update('users', 'user-123', { name: 'Jane' });
63
53
 
64
- ```json
65
- {
66
- "build": "tsc --build",
67
- "test": "vitest run",
68
- "lint": "eslint .",
69
- "lint:fix": "eslint . --fix",
70
- "format": "prettier --write './**/*.{ts,js,json}'",
71
- "format:check": "prettier --check './**/*.{ts,js,json}'",
72
- "type:check": "tsc --noEmit"
73
- }
54
+ // Delete
55
+ const deleted = await db.delete('users', 'user-123');
74
56
  ```
75
57
 
76
- ---
58
+ ## Adapters
77
59
 
78
- ## 🔁 Dev Workflow
60
+ | Adapter | Description |
61
+ |---------|-------------|
62
+ | `drizzle` | PostgreSQL via Drizzle ORM (recommended) |
63
+ | `supabase` | Supabase client |
64
+ | `sql` | Raw PostgreSQL |
65
+ | `mock` | In-memory for testing |
79
66
 
80
- ### Local Linking (for active development)
67
+ ## CLI
81
68
 
82
- In the **package repo**:
69
+ The package includes a CLI for database management:
83
70
 
84
71
  ```bash
85
- pnpm build
86
- pnpm link --global
87
- ```
88
-
89
- In a **consumer repo** (e.g. frontend app):
90
-
91
- ```bash
92
- pnpm link --global @plyaz/my-package
93
- ```
94
-
95
- ### Publishing to GitHub Packages
72
+ # Run migrations
73
+ npx plyaz-db migrate up
74
+ npx plyaz-db migrate down
75
+ npx plyaz-db migrate status
96
76
 
97
- Ensure `.npmrc` in your user root exists:
77
+ # Run seeds
78
+ npx plyaz-db seed run
79
+ npx plyaz-db seed status
98
80
 
99
- ```npmrc
100
- @plyaz:registry=https://npm.pkg.github.com/
101
- //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
81
+ # Health check
82
+ npx plyaz-db health
102
83
  ```
103
84
 
104
- Then publish:
85
+ ### CLI Options
105
86
 
106
87
  ```bash
107
- pnpm publish --access=restricted
88
+ npx plyaz-db --config ./path/to/db.config.mjs migrate up
89
+ npx plyaz-db --env ./path/to/.env migrate up
108
90
  ```
109
91
 
110
- ---
111
-
112
- ## Best Practices
113
-
114
- * Always export from `src/index.ts`
115
- * Use semver (`1.2.0`) and follow changelog conventions
116
- * Keep isolated logic: packages should not import from app-specific code
117
- * Use `@plyaz/devtools` for all configs: ESLint, Prettier, TS, Vitest, CI and other configs
118
- * Include unit tests via `vitest`
119
- * Enable CI/CD via GitHub Actions template (see `.github/workflows/publish.yml`, `.github/workflows/security.yml`, `.github/workflows/deploy.yml`)
120
-
121
- ---
122
-
123
- ## 🧰 Shared Tooling
124
-
125
- This template is pre-integrated with:
126
-
127
- * TypeScript (strict mode)
128
- * ESLint & Prettier via `@plyaz/devtools`
129
- * ✅ Unit testing (Vitest)
130
- * ✅ CI-ready for GitHub Actions
131
- * ✅ `.npmrc` for GitHub Package Registry
132
-
133
- For full integration, ensure you're using the latest `@plyaz/devtools` and follow the [Plyaz Confluence Documentation](https://plyaz.atlassian.net/wiki/spaces/SD/overview).
134
-
135
- ---
136
-
137
- ## 🔐 GitHub Secrets (Required)
138
-
139
- To enable private publishing via CI/CD, set the following in your GitHub repo secrets:
140
-
141
- ```env
142
- GITHUB_TOKEN=<automatically available>
92
+ ## Features
93
+
94
+ - **Multiple Adapters** - Drizzle, Supabase, raw SQL, or mock
95
+ - **Soft Delete** - Mark records as deleted without removing
96
+ - **Audit Logging** - Track all database changes
97
+ - **Encryption** - Field-level encryption
98
+ - **Caching** - Query result caching with Redis
99
+ - **Read Replicas** - Automatic read/write splitting
100
+ - **Migrations** - SQL-based schema migrations
101
+ - **Seeds** - Database seeding with rollback support
102
+ - **Health Checks** - Connection monitoring
103
+
104
+ ## Repository Pattern
105
+
106
+ ```typescript
107
+ import { BaseRepository } from '@plyaz/db';
108
+
109
+ class UserRepository extends BaseRepository<User> {
110
+ constructor(db: DatabaseService) {
111
+ super(db, 'users');
112
+ }
113
+
114
+ async findByEmail(email: string) {
115
+ return this.findMany({
116
+ filters: [{ field: 'email', operator: 'eq', value: email }],
117
+ });
118
+ }
119
+ }
143
120
  ```
144
121
 
145
- ---
146
-
147
- ## 📄 When to Use a Shared Package
148
-
149
- Use this template if your logic or types:
150
-
151
- * Are used by 2+ apps/services
152
- * Need semantic versioning and reuse
153
- * Should remain independently tested and documented
122
+ ## Types
154
123
 
155
- For example:
124
+ All types are available from `@plyaz/types/db`:
156
125
 
157
- | Package | Description |
158
- | --------------- | ------------------------------------------- |
159
- | `@plyaz/types` | Global TypeScript types and interfaces |
160
- | `@plyaz/api` | Shared API SDK and HTTP clients |
161
- | `@plyaz/errors` | Standardized error shapes and handlers |
162
- | `@plyaz/web3` | Web3 interaction layer (wallets, contracts) |
163
- | `@plyaz/config` | Shared config/env/constants (no logic) |
164
-
165
- ---
166
-
167
- ## 🧠 Ownership
168
-
169
- This repo is managed by the Plyaz engineering team. Please follow versioning, changelog, and testing requirements when contributing.
126
+ ```typescript
127
+ import type {
128
+ DatabaseServiceConfig,
129
+ DatabaseAdapterType,
130
+ QueryOptions,
131
+ PaginatedResult,
132
+ } from '@plyaz/types/db';
133
+ ```
@@ -13,6 +13,9 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
13
13
  private config;
14
14
  private tableMap;
15
15
  private idColumnMap;
16
+ private stringTableMap;
17
+ private stringIdColumnMap;
18
+ private configIdColumns;
16
19
  /**
17
20
  * Creates a new DrizzleAdapter instance.
18
21
  * @param {DrizzleAdapterConfig} config - Configuration object for Drizzle and PostgreSQL connection.
@@ -51,6 +54,11 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
51
54
  * application shutdown, to free up database resources and prevent connection leaks.
52
55
  */
53
56
  disconnect(): Promise<void>;
57
+ /**
58
+ * Closes the database connection and cleanup resources.
59
+ * @returns Promise resolving to DatabaseResult indicating success or failure.
60
+ */
61
+ close(): Promise<DatabaseResult<void>>;
54
62
  /**
55
63
  * Gets the underlying Drizzle client instance.
56
64
  * @returns {TClient} The internal Drizzle client.
@@ -76,19 +84,28 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
76
84
  query<T>(sql: string, params?: T[]): Promise<T[]>;
77
85
  /**
78
86
  * Registers a table and optional ID column for ORM operations.
79
- * @template TTable - Type representing the table structure.
80
- * @template TIdColumn - Type representing the ID column.
87
+ * @template TTable - Type representing the table structure (PgTable or string).
88
+ * @template TIdColumn - Type representing the ID column (PgColumn or string).
81
89
  * @param {string} name - Logical name of the table.
82
- * @param {TTable} table - Drizzle table object.
83
- * @param {TIdColumn} [idColumn] - Optional primary key column.
90
+ * @param {TTable} table - Drizzle table object (PgTable) or string table name.
91
+ * @param {TIdColumn} [idColumn] - Optional primary key column (PgColumn or string).
84
92
  * @description
85
93
  * Registers a table with the adapter, allowing it to be referenced by a logical name
86
94
  * in subsequent operations. This is necessary for the adapter to perform ORM operations
87
95
  * on the table. The ID column can also be specified if it differs from the default 'id'.
96
+ *
97
+ * **Supports two modes:**
98
+ * 1. **PgTable mode**: Pass Drizzle schema objects for type-safe ORM operations
99
+ * 2. **String mode**: Pass string table names for raw SQL fallback (auto-registration)
100
+ *
88
101
  * This registration enables the adapter to map logical table names to actual table objects
89
102
  * and ID columns, providing a layer of abstraction between the application and the database schema.
90
103
  */
91
104
  registerTable<TTable, TIdColumn>(name: string, table: TTable, idColumn?: TIdColumn): void;
105
+ /**
106
+ * Execute raw SQL findById query
107
+ */
108
+ private rawSqlFindById;
92
109
  /**
93
110
  * Finds a record by its primary ID.
94
111
  * @template T - The expected type of the record.
@@ -101,8 +118,15 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
101
118
  * If the record is found, it is returned in a success result. If no record is found,
102
119
  * null is returned in a success result. If an error occurs during the operation,
103
120
  * a failure result with an error message is returned.
121
+ *
122
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
123
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
104
124
  */
105
125
  findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>>;
126
+ /**
127
+ * Handle USE_STRING_MODE fallback with error wrapping
128
+ */
129
+ private handleStringModeFallback;
106
130
  /**
107
131
  * Retrieves multiple records with optional filtering, sorting, and pagination.
108
132
  * @template T - The expected type of the records.
@@ -116,8 +140,21 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
116
140
  * of records returned. The result includes the data array, total count of matching records,
117
141
  * and pagination metadata such as current page, total pages, and next/previous cursors.
118
142
  * If an error occurs during the operation, a failure result with an error message is returned.
143
+ *
144
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
145
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
146
+ */
147
+ findMany<T extends Record<string, unknown>>(table: string, options?: QueryOptions<T>): Promise<DatabaseResult<PaginatedResult<T>>>;
148
+ /**
149
+ * Raw SQL fallback for findMany when no PgTable schema is registered.
150
+ * @private
119
151
  */
120
- findMany<T>(table: string, options?: QueryOptions): Promise<DatabaseResult<PaginatedResult<T>>>;
152
+ private findManyRawSql;
153
+ /**
154
+ * Builds a SQL WHERE clause string for raw SQL queries.
155
+ * @private
156
+ */
157
+ private buildSqlWhereClause;
121
158
  /**
122
159
  * Inserts a new record into the specified table.
123
160
  * @template T - The expected type of the record.
@@ -130,8 +167,16 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
130
167
  * After insertion, it returns the inserted record with any auto-generated fields
131
168
  * (like IDs) populated. If an error occurs during the operation,
132
169
  * a failure result with an error message is returned.
170
+ *
171
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
172
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
133
173
  */
134
174
  create<T>(table: string, data: T): Promise<DatabaseResult<T>>;
175
+ /**
176
+ * Raw SQL fallback for create when no PgTable schema is registered.
177
+ * @private
178
+ */
179
+ private createRawSql;
135
180
  /**
136
181
  * Updates an existing record by ID.
137
182
  * @template T - The expected type of the record.
@@ -145,8 +190,16 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
145
190
  * The method uses the registered table and ID column to construct the update query.
146
191
  * After updating, it returns the updated record. If an error occurs during the operation,
147
192
  * a failure result with an error message is returned.
193
+ *
194
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
195
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
148
196
  */
149
197
  update<T>(table: string, id: string, data: Partial<T>): Promise<DatabaseResult<T>>;
198
+ /**
199
+ * Raw SQL fallback for update when no PgTable schema is registered.
200
+ * @private
201
+ */
202
+ private updateRawSql;
150
203
  /**
151
204
  * Deletes a record by ID.
152
205
  * @param {string} table - Table name.
@@ -157,8 +210,16 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
157
210
  * The method uses the registered table and ID column to construct the delete query.
158
211
  * If the operation is successful, it returns a success result with no value.
159
212
  * If an error occurs during the operation, a failure result with an error message is returned.
213
+ *
214
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
215
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
160
216
  */
161
217
  delete(table: string, id: string): Promise<DatabaseResult<void>>;
218
+ /**
219
+ * Raw SQL fallback for delete when no PgTable schema is registered.
220
+ * @private
221
+ */
222
+ private deleteRawSql;
162
223
  /**
163
224
  * Executes a transactional operation with rollback on failure.
164
225
  * @template T - The expected type of the transaction result.
@@ -171,6 +232,8 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
171
232
  * is rolled back, ensuring that no partial changes are applied to the database.
172
233
  * The method returns the result of the callback function if successful,
173
234
  * or a failure result with an error message if an error occurs.
235
+ *
236
+ * **Auto-registers tables**: Transaction operations use raw SQL mode for unregistered tables.
174
237
  */
175
238
  transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<DatabaseResult<T>>;
176
239
  /**
@@ -183,6 +246,9 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
183
246
  * The method uses the registered table and ID column to construct the query.
184
247
  * It returns a success result with a boolean value indicating whether the record exists.
185
248
  * If an error occurs during the operation, a failure result with an error message is returned.
249
+ *
250
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
251
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
186
252
  */
187
253
  exists(table: string, id: string): Promise<DatabaseResult<boolean>>;
188
254
  /**
@@ -196,8 +262,16 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
196
262
  * If a filter is provided, it is applied to narrow down the count to matching records.
197
263
  * It returns a success result with the count of matching records.
198
264
  * If an error occurs during the operation, a failure result with an error message is returned.
265
+ *
266
+ * **Auto-registers tables**: If table is not registered with PgTable schema,
267
+ * falls back to raw SQL mode (same behavior as SQLAdapter).
199
268
  */
200
- count(table: string, filter?: Filter): Promise<DatabaseResult<number>>;
269
+ count<T extends Record<string, unknown> = Record<string, unknown>>(table: string, filter?: Filter<T>): Promise<DatabaseResult<number>>;
270
+ /**
271
+ * Raw SQL fallback for count when no PgTable schema is registered.
272
+ * @private
273
+ */
274
+ private countRawSql;
201
275
  /**
202
276
  * Performs a health check on the database connection.
203
277
  * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Health status with response time.
@@ -209,18 +283,44 @@ export declare class DrizzleAdapter implements DatabaseAdapterType {
209
283
  * If an error occurs during the operation, a failure result with an error message is returned.
210
284
  */
211
285
  healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>>;
286
+ /**
287
+ * Checks if a table is registered in string mode (raw SQL fallback).
288
+ * @private
289
+ * @param {string} name - Table name.
290
+ * @returns {boolean} True if table is registered in string mode.
291
+ */
292
+ private isStringMode;
212
293
  /**
213
294
  * Retrieves a registered table by name.
214
295
  * @private
215
296
  * @param {string} name - Table name.
216
297
  * @returns {PgTable} Table object.
217
- * @throws {DatabaseError} If table is not registered.
298
+ * @throws {DatabaseError} If table is not registered and cannot be auto-registered.
218
299
  * @description
219
300
  * Retrieves a table object that has been previously registered with the adapter.
220
- * This method is used internally by other methods to ensure that operations are performed
221
- * on valid, registered tables. If the table is not found, it throws a DatabaseError.
301
+ * If the table is not found in PgTable mode, it auto-registers in string mode
302
+ * for raw SQL operations (same behavior as SQLAdapter).
222
303
  */
223
304
  private getTable;
305
+ /**
306
+ * Gets the string table name for raw SQL operations.
307
+ * @private
308
+ * @param {string} name - Logical table name.
309
+ * @returns {string} Physical table name.
310
+ */
311
+ private getStringTableName;
312
+ /**
313
+ * Gets the string ID column for raw SQL operations.
314
+ * @private
315
+ * @param {string} name - Logical table name.
316
+ * @returns {string} ID column name (defaults to 'id').
317
+ * @description
318
+ * Retrieves the ID column for a table. Checks in this order:
319
+ * 1. Runtime registered ID column (from registerTable calls)
320
+ * 2. Config-provided ID column (from tableIdColumns in config)
321
+ * 3. Default 'id' column
322
+ */
323
+ private getStringIdColumn;
224
324
  /**
225
325
  * Retrieves the registered ID column for a table.
226
326
  * @private
@@ -1 +1 @@
1
- {"version":3,"file":"DrizzleAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/drizzle/DrizzleAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DrizzleAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/drizzle/DrizzleAdapter.ts"],"names":[],"mappings":"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"}
@@ -17,4 +17,9 @@ export { SupabaseAdapter } from "./supabase/SupabaseAdapter";
17
17
  * @exports SQLAdapter
18
18
  */
19
19
  export { SQLAdapter } from "./sql/SQLAdapter";
20
+ /**
21
+ * Mock adapter for testing
22
+ * @exports MockAdapter
23
+ */
24
+ export { MockAdapter } from "./mock/MockAdapter";
20
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * MockAdapter - In-Memory Database Adapter for Testing
3
+ *
4
+ * Provides a lightweight, in-memory database adapter that mimics
5
+ * the behavior of real database adapters without requiring an actual
6
+ * database connection. Perfect for unit tests and integration tests.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const db = await createDatabaseService({
11
+ * adapter: 'mock',
12
+ * config: {
13
+ * initialData: {
14
+ * users: [{ id: '1', name: 'Test User', email: 'test@example.com' }],
15
+ * campaigns: [{ id: '1', title: 'Test Campaign', creator_id: '1' }]
16
+ * },
17
+ * autoGenerateIds: true
18
+ * }
19
+ * });
20
+ * ```
21
+ */
22
+ import type { DatabaseAdapterType, DatabaseResult, PaginatedResult, QueryOptions, Transaction, DatabaseHealthStatus, Filter, DbMockAdapterConfig } from "@plyaz/types/db";
23
+ /**
24
+ * MockAdapter - In-memory database adapter for testing
25
+ */
26
+ export declare class MockAdapter implements DatabaseAdapterType {
27
+ private data;
28
+ private config;
29
+ private tableIdColumns;
30
+ private defaultSchema;
31
+ private isInitialized;
32
+ private transactionDepth;
33
+ private transactionData;
34
+ constructor(config?: Partial<DbMockAdapterConfig>);
35
+ initialize(): Promise<DatabaseResult<void>>;
36
+ close(): Promise<DatabaseResult<void>>;
37
+ registerTable<TTable = string, TIdColumn = string>(name: string, table?: TTable, idColumn?: TIdColumn): void;
38
+ findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>>;
39
+ /**
40
+ * Apply query options (filter, sort) to records
41
+ */
42
+ private applyQueryOptions;
43
+ /**
44
+ * Get pagination params with defaults
45
+ */
46
+ private getPaginationParams;
47
+ /**
48
+ * Apply pagination to records
49
+ */
50
+ private applyPagination;
51
+ findMany<T extends Record<string, unknown>>(table: string, options?: QueryOptions<T>): Promise<DatabaseResult<PaginatedResult<T>>>;
52
+ create<T>(table: string, data: T): Promise<DatabaseResult<T>>;
53
+ update<T>(table: string, id: string, data: Partial<T>): Promise<DatabaseResult<T>>;
54
+ delete(table: string, id: string): Promise<DatabaseResult<void>>;
55
+ transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<DatabaseResult<T>>;
56
+ exists(table: string, id: string): Promise<DatabaseResult<boolean>>;
57
+ count<T extends Record<string, unknown> = Record<string, unknown>>(table: string, filter?: Filter<T>): Promise<DatabaseResult<number>>;
58
+ healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>>;
59
+ connect(): Promise<void>;
60
+ disconnect(): Promise<void>;
61
+ getClient(): object;
62
+ query<T>(): Promise<T[]>;
63
+ /**
64
+ * Get fully-qualified table name with schema
65
+ */
66
+ private getQualifiedTableName;
67
+ private initializeTableData;
68
+ private getTableData;
69
+ private getIdColumn;
70
+ private generateId;
71
+ private simulateLatency;
72
+ private shouldFail;
73
+ private applyFilter;
74
+ private applySort;
75
+ /**
76
+ * Test utility: Clear all data
77
+ */
78
+ clearAll(): void;
79
+ /**
80
+ * Test utility: Get current data for inspection
81
+ */
82
+ getData(table?: string): Record<string, unknown>[] | Record<string, Record<string, unknown>[]>;
83
+ /**
84
+ * Test utility: Set data directly
85
+ */
86
+ setData(table: string, records: Record<string, unknown>[]): void;
87
+ }
88
+ //# sourceMappingURL=MockAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAdapter.ts"],"names":[],"mappings":"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"}