@plyaz/db 0.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 (118) hide show
  1. package/README.md +169 -0
  2. package/dist/adapters/drizzle/DrizzleAdapter.d.ts +269 -0
  3. package/dist/adapters/drizzle/DrizzleAdapter.d.ts.map +1 -0
  4. package/dist/adapters/index.d.ts +20 -0
  5. package/dist/adapters/index.d.ts.map +1 -0
  6. package/dist/adapters/sql/SQLAdapter.d.ts +282 -0
  7. package/dist/adapters/sql/SQLAdapter.d.ts.map +1 -0
  8. package/dist/adapters/supabase/SupabaseAdapter.d.ts +305 -0
  9. package/dist/adapters/supabase/SupabaseAdapter.d.ts.map +1 -0
  10. package/dist/advanced/backup/BackupService.d.ts +159 -0
  11. package/dist/advanced/backup/BackupService.d.ts.map +1 -0
  12. package/dist/advanced/backup/index.d.ts +2 -0
  13. package/dist/advanced/backup/index.d.ts.map +1 -0
  14. package/dist/advanced/caching/CacheEvict.decorator.d.ts +3 -0
  15. package/dist/advanced/caching/CacheEvict.decorator.d.ts.map +1 -0
  16. package/dist/advanced/caching/Cacheable.decorator.d.ts +99 -0
  17. package/dist/advanced/caching/Cacheable.decorator.d.ts.map +1 -0
  18. package/dist/advanced/caching/RedisCache.d.ts +417 -0
  19. package/dist/advanced/caching/RedisCache.d.ts.map +1 -0
  20. package/dist/advanced/caching/index.d.ts +4 -0
  21. package/dist/advanced/caching/index.d.ts.map +1 -0
  22. package/dist/advanced/connection-pool/DynamicPool.d.ts +234 -0
  23. package/dist/advanced/connection-pool/DynamicPool.d.ts.map +1 -0
  24. package/dist/advanced/connection-pool/index.d.ts +2 -0
  25. package/dist/advanced/connection-pool/index.d.ts.map +1 -0
  26. package/dist/advanced/index.d.ts +8 -0
  27. package/dist/advanced/index.d.ts.map +1 -0
  28. package/dist/advanced/monitoring/AlertManager.d.ts +72 -0
  29. package/dist/advanced/monitoring/AlertManager.d.ts.map +1 -0
  30. package/dist/advanced/monitoring/MetricsCollector.d.ts +81 -0
  31. package/dist/advanced/monitoring/MetricsCollector.d.ts.map +1 -0
  32. package/dist/advanced/monitoring/index.d.ts +3 -0
  33. package/dist/advanced/monitoring/index.d.ts.map +1 -0
  34. package/dist/advanced/multi-tenancy/TenantContext.d.ts +52 -0
  35. package/dist/advanced/multi-tenancy/TenantContext.d.ts.map +1 -0
  36. package/dist/advanced/multi-tenancy/TenantRepository.d.ts +292 -0
  37. package/dist/advanced/multi-tenancy/TenantRepository.d.ts.map +1 -0
  38. package/dist/advanced/multi-tenancy/index.d.ts +3 -0
  39. package/dist/advanced/multi-tenancy/index.d.ts.map +1 -0
  40. package/dist/advanced/read-replica/ReadReplicaAdapter.d.ts +516 -0
  41. package/dist/advanced/read-replica/ReadReplicaAdapter.d.ts.map +1 -0
  42. package/dist/advanced/read-replica/ReadReplicaManager.d.ts +68 -0
  43. package/dist/advanced/read-replica/ReadReplicaManager.d.ts.map +1 -0
  44. package/dist/advanced/read-replica/UseReplica.decorator.d.ts +24 -0
  45. package/dist/advanced/read-replica/UseReplica.decorator.d.ts.map +1 -0
  46. package/dist/advanced/read-replica/index.d.ts +3 -0
  47. package/dist/advanced/read-replica/index.d.ts.map +1 -0
  48. package/dist/advanced/sharding/ShardKey.d.ts +80 -0
  49. package/dist/advanced/sharding/ShardKey.d.ts.map +1 -0
  50. package/dist/advanced/sharding/ShardRouter.d.ts +66 -0
  51. package/dist/advanced/sharding/ShardRouter.d.ts.map +1 -0
  52. package/dist/advanced/sharding/index.d.ts +3 -0
  53. package/dist/advanced/sharding/index.d.ts.map +1 -0
  54. package/dist/builder/query/index.d.ts +7 -0
  55. package/dist/builder/query/index.d.ts.map +1 -0
  56. package/dist/builder/query/orm.d.ts +22 -0
  57. package/dist/builder/query/orm.d.ts.map +1 -0
  58. package/dist/builder/query/sql.d.ts +29 -0
  59. package/dist/builder/query/sql.d.ts.map +1 -0
  60. package/dist/extensions/AuditExtension.d.ts +468 -0
  61. package/dist/extensions/AuditExtension.d.ts.map +1 -0
  62. package/dist/extensions/CachingAdapter.d.ts +451 -0
  63. package/dist/extensions/CachingAdapter.d.ts.map +1 -0
  64. package/dist/extensions/EncryptionExtension.d.ts +95 -0
  65. package/dist/extensions/EncryptionExtension.d.ts.map +1 -0
  66. package/dist/extensions/ReadReplicaAdapter.d.ts +32 -0
  67. package/dist/extensions/ReadReplicaAdapter.d.ts.map +1 -0
  68. package/dist/extensions/SoftDeleteExtension.d.ts +430 -0
  69. package/dist/extensions/SoftDeleteExtension.d.ts.map +1 -0
  70. package/dist/extensions/index.d.ts +79 -0
  71. package/dist/extensions/index.d.ts.map +1 -0
  72. package/dist/factory/AdapterFactory.d.ts +111 -0
  73. package/dist/factory/AdapterFactory.d.ts.map +1 -0
  74. package/dist/factory/createDatabaseService.d.ts +121 -0
  75. package/dist/factory/createDatabaseService.d.ts.map +1 -0
  76. package/dist/index.cjs +8518 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.ts +19 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.mjs +8480 -0
  81. package/dist/index.mjs.map +1 -0
  82. package/dist/repository/BaseRepository.d.ts +209 -0
  83. package/dist/repository/BaseRepository.d.ts.map +1 -0
  84. package/dist/repository/index.d.ts +80 -0
  85. package/dist/repository/index.d.ts.map +1 -0
  86. package/dist/security/index.cjs +118 -0
  87. package/dist/security/index.cjs.map +1 -0
  88. package/dist/security/index.d.ts +3 -0
  89. package/dist/security/index.d.ts.map +1 -0
  90. package/dist/security/index.mjs +114 -0
  91. package/dist/security/index.mjs.map +1 -0
  92. package/dist/security/sanitizers/html.sanitizer.d.ts +31 -0
  93. package/dist/security/sanitizers/html.sanitizer.d.ts.map +1 -0
  94. package/dist/security/serializers/DataValidation.d.ts +34 -0
  95. package/dist/security/serializers/DataValidation.d.ts.map +1 -0
  96. package/dist/service/DatabaseService.d.ts +136 -0
  97. package/dist/service/DatabaseService.d.ts.map +1 -0
  98. package/dist/service/EventEmitter.d.ts +110 -0
  99. package/dist/service/EventEmitter.d.ts.map +1 -0
  100. package/dist/service/HealthManager.d.ts +166 -0
  101. package/dist/service/HealthManager.d.ts.map +1 -0
  102. package/dist/utils/ConfigMerger.d.ts +227 -0
  103. package/dist/utils/ConfigMerger.d.ts.map +1 -0
  104. package/dist/utils/databaseResultHelpers.d.ts +98 -0
  105. package/dist/utils/databaseResultHelpers.d.ts.map +1 -0
  106. package/dist/utils/index.d.ts +7 -0
  107. package/dist/utils/index.d.ts.map +1 -0
  108. package/dist/utils/normalizeDetails.d.ts +111 -0
  109. package/dist/utils/normalizeDetails.d.ts.map +1 -0
  110. package/dist/utils/pagination.d.ts +77 -0
  111. package/dist/utils/pagination.d.ts.map +1 -0
  112. package/dist/utils/regex.d.ts +199 -0
  113. package/dist/utils/regex.d.ts.map +1 -0
  114. package/dist/utils/typeGuards.d.ts +57 -0
  115. package/dist/utils/typeGuards.d.ts.map +1 -0
  116. package/dist/utils/validation.d.ts +146 -0
  117. package/dist/utils/validation.d.ts.map +1 -0
  118. package/package.json +156 -0
@@ -0,0 +1,282 @@
1
+ import type { SQLAdapterConfig, Transaction, DatabaseResult, PaginatedResult, QueryOptions, DatabaseHealthStatus, Filter, DatabaseAdapterType } from "@plyaz/types/db";
2
+ /**
3
+ * @class SQLAdapter
4
+ * @implements {DatabaseAdapterType}
5
+ * @classdesc
6
+ * Plain SQL adapter implementation for raw SQL queries.
7
+ *
8
+ * This adapter provides an interface to interact with SQL databases using raw SQL queries,
9
+ * supporting CRUD operations, transactions, and health checks. It uses PostgreSQL's node-pg
10
+ * driver for database connectivity and provides a simple, direct SQL interface without
11
+ * ORM abstractions. This adapter is ideal for applications that require direct control
12
+ * over SQL queries or need to leverage database-specific features.
13
+ */
14
+ export declare class SQLAdapter implements DatabaseAdapterType {
15
+ private pool;
16
+ private config;
17
+ private tableMap;
18
+ private idColumnMap;
19
+ /**
20
+ * Creates a new SQLAdapter instance.
21
+ * @param {SQLAdapterConfig} config - Configuration for the SQL adapter.
22
+ * @description
23
+ * Initializes the adapter with the provided configuration, setting up the connection pool
24
+ * for PostgreSQL database connections. The configuration should include a connection string
25
+ * and optional pool settings such as min/max connections and idle timeout. The adapter
26
+ * maintains internal maps for table names and ID columns to provide a level of abstraction
27
+ * over the raw database schema.
28
+ */
29
+ constructor(config: SQLAdapterConfig);
30
+ /**
31
+ * Initialize the adapter.
32
+ * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.
33
+ * @description
34
+ * Tests the database connection by attempting to establish a connection to the database.
35
+ * This method is typically called during application startup to verify that the adapter
36
+ * can communicate with the database before performing any operations. Returns a success
37
+ * result if the connection is established, or a failure result with an error if the
38
+ * connection cannot be established.
39
+ */
40
+ initialize(): Promise<DatabaseResult<void>>;
41
+ /**
42
+ * Connect to the database.
43
+ * @returns {Promise<void>} Promise that resolves when connected.
44
+ * @description
45
+ * Establishes a connection to the PostgreSQL database using the connection pool.
46
+ * This method is called to ensure that a connection is available before performing database operations.
47
+ * The connection pool manages the connections efficiently, reusing them when possible.
48
+ */
49
+ connect(): Promise<void>;
50
+ /**
51
+ * Disconnect from the database.
52
+ * @returns {Promise<void>} Promise that resolves when disconnected.
53
+ * @description
54
+ * Gracefully shuts down the connection pool, closing all active connections.
55
+ * This method should be called when the adapter is no longer needed, typically during
56
+ * application shutdown, to free up database resources and prevent connection leaks.
57
+ */
58
+ disconnect(): Promise<void>;
59
+ /**
60
+ * Gets the underlying PostgreSQL client instance.
61
+ * @template TClient - The type of the database client to return.
62
+ * @returns {TClient} The PostgreSQL pool instance cast to the specified client type.
63
+ * @description
64
+ * This method provides access to the underlying PostgreSQL connection pool.
65
+ * While direct access is technically possible, it is generally discouraged to
66
+ * preserve abstraction and ensure all database operations go through the adapter’s
67
+ * interface for consistent error handling, logging, and event management.
68
+ */
69
+ getClient<TClient extends object = object>(): TClient;
70
+ /**
71
+ * Execute a raw SQL query.
72
+ * @template T - The expected type of the query result rows.
73
+ * @param {string} sql - SQL query string.
74
+ * @param {T[]} [params] - Query parameters.
75
+ * @returns {Promise<T[]>} Promise resolving to query results.
76
+ * @description
77
+ * Executes a raw SQL query against the database, with optional parameterization.
78
+ * This method is useful for complex queries that cannot be easily expressed using the adapter's
79
+ * built-in methods or for database-specific operations. The method uses parameterized queries
80
+ * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.
81
+ */
82
+ query<T>(sql: string, params?: T[]): Promise<T[]>;
83
+ /**
84
+ * Register a table with the adapter.
85
+ * @template TTable - Type representing the table structure.
86
+ * @template TIdColumn - Type representing the ID column.
87
+ * @param {string} name - Logical name for the table.
88
+ * @param {TTable} [table] - Table name or object.
89
+ * @param {TIdColumn} [idColumn] - Optional ID column name.
90
+ * @description
91
+ * Registers a table with the adapter, allowing it to be referenced by a logical name
92
+ * in subsequent operations. This is necessary for the adapter to perform operations
93
+ * on the table. The ID column can also be specified if it differs from the default 'id'.
94
+ * This registration enables the adapter to map logical table names to actual table names
95
+ * and ID columns, providing a layer of abstraction between the application and the database schema.
96
+ */
97
+ registerTable<TTable, TIdColumn>(name: string, table?: TTable, idColumn?: TIdColumn): void;
98
+ /**
99
+ * Find a single record by ID.
100
+ * @template T - The expected type of the record.
101
+ * @param {string} table - Table name.
102
+ * @param {string} id - Record ID.
103
+ * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.
104
+ * @description
105
+ * Retrieves a single record from the specified table using its primary ID.
106
+ * The method constructs a SELECT query with a WHERE clause for the ID column.
107
+ * If the record is found, it is returned in a success result. If no record is found,
108
+ * null is returned in a success result. If an error occurs during the operation,
109
+ * a failure result with an error message is returned.
110
+ */
111
+ findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>>;
112
+ /**
113
+ * Find multiple records with filtering and pagination.
114
+ * @template T - The expected type of the records.
115
+ * @param {string} table - Table name.
116
+ * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.
117
+ * @returns {Promise<DatabaseResult<PaginatedResult<object>>>} Promise resolving to DatabaseResult containing paginated data.
118
+ * @description
119
+ * Retrieves multiple records from the specified table with support for filtering,
120
+ * sorting, and pagination. The method constructs a SELECT query with optional WHERE,
121
+ * ORDER BY, LIMIT, and OFFSET clauses. It first executes a COUNT query to get the
122
+ * total number of matching records, then executes the main query with the applied filters,
123
+ * sorting, and pagination. The result includes the data array, total count of matching records,
124
+ * and pagination metadata such as current page, total pages, and offset.
125
+ * If an error occurs during the operation, a failure result with an error message is returned.
126
+ */
127
+ /**
128
+ * Finds multiple records from the specified table with optional filtering, sorting, and pagination.
129
+ * @template TRecord - Type representing the shape of records returned.
130
+ * @template TOptions - Query options type.
131
+ * @template TParam - Type of query parameters (primitives).
132
+ * @param {string} table - Name of the table to query.
133
+ * @param {TOptions} [options] - Optional query options for filtering, sorting, and pagination.
134
+ * @returns {Promise<DatabaseResult<PaginatedResult<TRecord>>>} - A promise resolving to a paginated result.
135
+ * @throws {DatabaseError} - When query execution or initialization fails.
136
+ */
137
+ /**
138
+ * Finds multiple records from the specified table with optional filtering, sorting, and pagination.
139
+ * @template T - Type representing the shape of records returned.
140
+ * @param {string} table - Name of the table to query.
141
+ * @param {QueryOptions<object>} [options] - Optional query options for filtering, sorting, and pagination.
142
+ * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} - A promise resolving to a paginated result.
143
+ * @throws {DatabaseError} - When query execution or initialization fails.
144
+ */
145
+ findMany<T>(table: string, options?: QueryOptions<object>): Promise<DatabaseResult<PaginatedResult<T>>>;
146
+ /**
147
+ * Create a new record.
148
+ * @template T - The expected type of the record.
149
+ * @param {string} table - Table name.
150
+ * @param {T} data - Record data to create.
151
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.
152
+ * @description
153
+ * Inserts a new record into the specified table using the provided data.
154
+ * The method constructs an INSERT query with column names and parameter placeholders
155
+ * for the values. After insertion, it returns the inserted record with any auto-generated
156
+ * fields (like IDs) populated using the RETURNING clause. If an error occurs during the operation,
157
+ * a failure result with an error message is returned.
158
+ */
159
+ create<T>(table: string, data: T): Promise<DatabaseResult<T>>;
160
+ /**
161
+ * Update an existing record.
162
+ * @template T - The expected type of the record.
163
+ * @param {string} table - Table name.
164
+ * @param {string} id - Record ID.
165
+ * @param {Partial<T>} data - Partial record data to update.
166
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.
167
+ * @description
168
+ * Updates an existing record in the specified table using its primary ID.
169
+ * Only the fields provided in the data object are updated, allowing for partial updates.
170
+ * The method constructs an UPDATE query with a SET clause for the fields to update
171
+ * and a WHERE clause for the ID. After updating, it returns the updated record using
172
+ * the RETURNING clause. If an error occurs during the operation, a failure result with
173
+ * an error message is returned.
174
+ */
175
+ update<T>(table: string, id: string, data: Partial<T>): Promise<DatabaseResult<T>>;
176
+ /**
177
+ * Delete a record.
178
+ * @param {string} table - Table name.
179
+ * @param {string} id - Record ID.
180
+ * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.
181
+ * @description
182
+ * Deletes a record from the specified table using its primary ID.
183
+ * The method constructs a DELETE query with a WHERE clause for the ID column.
184
+ * If the operation is successful, it returns a success result with no value.
185
+ * If an error occurs during the operation, a failure result with an error message is returned.
186
+ */
187
+ delete(table: string, id: string): Promise<DatabaseResult<void>>;
188
+ /**
189
+ * Execute a transaction.
190
+ * @template T - The expected type of the transaction result.
191
+ * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.
192
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.
193
+ * @description
194
+ * Executes a callback function within a database transaction, providing atomicity.
195
+ * If the callback function executes successfully, the transaction is committed.
196
+ * If an error occurs during the execution of the callback function, the transaction
197
+ * is rolled back, ensuring that no partial changes are applied to the database.
198
+ * The method returns the result of the callback function if successful,
199
+ * or a failure result with an error message if an error occurs.
200
+ * The transaction object passed to the callback provides methods for performing
201
+ * database operations within the transaction.
202
+ */
203
+ transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<DatabaseResult<T>>;
204
+ /**
205
+ * Check if a record exists.
206
+ * @param {string} table - Table name.
207
+ * @param {string} id - Record ID.
208
+ * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.
209
+ * @description
210
+ * Checks if a record with the specified ID exists in the table.
211
+ * The method constructs a SELECT query with a WHERE clause for the ID column
212
+ * and a LIMIT of 1. It returns a success result with a boolean value indicating
213
+ * whether the record exists. If an error occurs during the operation, a failure result
214
+ * with an error message is returned.
215
+ */
216
+ exists(table: string, id: string): Promise<DatabaseResult<boolean>>;
217
+ /**
218
+ * Count records matching a filter.
219
+ * @param {string} table - Table name.
220
+ * @param {Filter} [filter] - Filter conditions.
221
+ * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.
222
+ * @description
223
+ * Counts the number of records in the specified table that match the optional filter.
224
+ * The method constructs a COUNT query with an optional WHERE clause based on the filter.
225
+ * It returns a success result with the count of matching records.
226
+ * If an error occurs during the operation, a failure result with an error message is returned.
227
+ */
228
+ count(table: string, filter?: Filter): Promise<DatabaseResult<number>>;
229
+ /**
230
+ * Perform health check.
231
+ * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.
232
+ * @description
233
+ * Checks the health of the database connection by executing a simple query.
234
+ * The method measures the response time of the query to determine the health status.
235
+ * It returns a success result with a HealthStatus object indicating whether the database is healthy,
236
+ * the response time of the health check, and any additional details.
237
+ * If an error occurs during the operation, a failure result with an error message is returned.
238
+ */
239
+ healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>>;
240
+ /**
241
+ * Get the actual table name from the mapped table name.
242
+ * @private
243
+ * @param {string} name - Logical table name.
244
+ * @returns {string} Actual table name.
245
+ * @throws {DatabaseError} If table is not registered.
246
+ * @description
247
+ * Retrieves the actual table name that has been previously registered with the adapter.
248
+ * This method is used internally by other methods to ensure that operations are performed
249
+ * on valid, registered tables. If the table is not found, it throws a DatabaseError.
250
+ */
251
+ private getTableName;
252
+ private validateBasicParams;
253
+ private validateCreateParams;
254
+ private validateUpdateParams;
255
+ /**
256
+ * Builds a SQL WHERE clause string from a provided filter definition.
257
+ *
258
+ * @private
259
+ * @template TParams - Tuple type representing the parameter array.
260
+ * @param {Filter} filter - The filter condition containing the field, operator, and value.
261
+ * @param {TParams} params - Mutable array to collect SQL parameter values.
262
+ * @param {number} startIndex - The starting index for SQL parameter placeholders (e.g., $1, $2, ...).
263
+ * @returns {string} The constructed SQL WHERE clause string.
264
+ * @throws {DatabaseError} If an unsupported operator is encountered or if the filter value type is invalid.
265
+ *
266
+ * @description
267
+ * This method dynamically builds a SQL WHERE clause based on the provided `filter` object.
268
+ * It supports operators such as:
269
+ * - `eq`, `ne` (equality and inequality)
270
+ * - `gt`, `gte`, `lt`, `lte` (comparison)
271
+ * - `in` (membership in a list)
272
+ * - `like` (pattern matching)
273
+ * - `between` (range)
274
+ * - `isNull`, `isNotNull` (null checks)
275
+ *
276
+ * The function safely constructs parameterized queries by adding each value
277
+ * into the `params` array and referencing it via `$<index>` placeholders,
278
+ * helping to prevent SQL injection attacks.
279
+ */
280
+ private buildWhereClause;
281
+ }
282
+ //# sourceMappingURL=SQLAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SQLAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/sql/SQLAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,305 @@
1
+ import type { DatabaseAdapterType, DatabaseResult, PaginatedResult, QueryOptions, Filter, DatabaseHealthStatus, Transaction, SupabaseAdapterConfig } from "@plyaz/types/db";
2
+ /**
3
+ * @class SupabaseAdapter
4
+ * @implements {DatabaseAdapterType}
5
+ * @classdesc
6
+ * Supabase adapter implementation for database operations.
7
+ *
8
+ * This adapter provides an interface to interact with Supabase databases,
9
+ * supporting CRUD operations, transactions, and health checks. It leverages
10
+ * the Supabase JavaScript client to communicate with PostgreSQL databases through
11
+ * Supabase's API. The adapter provides a consistent interface while abstracting
12
+ * away the specifics of Supabase's API calls.
13
+ */
14
+ export declare class SupabaseAdapter implements DatabaseAdapterType {
15
+ private client;
16
+ private config;
17
+ private tableMap;
18
+ private idColumnMap;
19
+ /**
20
+ * Creates a new SupabaseAdapter instance.
21
+ * @param {SupabaseAdapterConfig} config - Configuration for the Supabase adapter.
22
+ * @description
23
+ * Initializes the adapter with the provided configuration, setting up the Supabase client.
24
+ * The configuration must include a Supabase URL and either a service key or an anonymous key.
25
+ * The adapter maintains internal maps for table names and ID columns to provide a level of
26
+ * abstraction over the database schema. If required configuration values are missing,
27
+ * the constructor throws a DatabaseError.
28
+ * @throws {DatabaseError} If Supabase URL or key is not provided in the configuration.
29
+ */
30
+ constructor(config: SupabaseAdapterConfig);
31
+ /**
32
+ * Initializes the Supabase database adapter.
33
+ * @returns {Promise<DatabaseResult<void>>} A promise resolving to a DatabaseResult indicating
34
+ * whether the initialization was successful or failed.
35
+ * @description
36
+ * Validates the Supabase database connection by invoking a simple predefined RPC function (`version`).
37
+ * This method is typically executed during application startup to ensure the adapter can
38
+ * successfully communicate with the database before performing any operations.
39
+ *
40
+ * The method calls the `version` RPC to confirm connectivity. If the RPC function is not defined,
41
+ * it is treated as a non-critical error and the connection is still considered valid. Any other
42
+ * errors are reported as initialization failures.
43
+ */
44
+ initialize(): Promise<DatabaseResult<void>>;
45
+ /**
46
+ * Connect to the database.
47
+ * @returns {Promise<void>} Promise that resolves when connected.
48
+ * @description
49
+ * Supabase handles connections automatically, so this method is a no-op.
50
+ * The Supabase client manages connections internally, establishing them as needed
51
+ * and handling connection pooling. This method is included for interface compatibility
52
+ * but does not perform any connection operations.
53
+ */
54
+ connect(): Promise<void>;
55
+ /**
56
+ * Disconnect from the database.
57
+ * @returns {Promise<void>} Promise that resolves when disconnected.
58
+ * @description
59
+ * Supabase handles disconnections automatically, so this method is a no-op.
60
+ * The Supabase client manages connections internally, closing them when appropriate.
61
+ * This method is included for interface compatibility but does not perform any
62
+ * disconnection operations.
63
+ */
64
+ disconnect(): Promise<void>;
65
+ /**
66
+ * Gets the underlying Supabase client instance.
67
+ * @template TClient - The type of the Supabase client to return.
68
+ * @returns {TClient} The Supabase client instance cast to the specified client type.
69
+ * @description
70
+ * This method provides access to the underlying Supabase client.
71
+ * Although direct access is technically possible, it is discouraged to maintain
72
+ * abstraction and ensure that all database operations go through the adapter’s
73
+ * interface for consistent error handling, logging, and event management.
74
+ */
75
+ getClient<TClient extends object = object>(): TClient;
76
+ /**
77
+ * Execute a raw SQL query.
78
+ * @template T - The expected type of the query result rows.
79
+ * @param {string} sql - SQL query string.
80
+ * @param {T[]} [params] - Query parameters.
81
+ * @returns {Promise<T[]>} Promise resolving to query results.
82
+ * @description
83
+ * Executes a raw SQL query against the database using Supabase's RPC function.
84
+ * This method is useful for complex queries that cannot be easily expressed using the adapter's
85
+ * built-in methods or for database-specific operations. The method uses parameterized queries
86
+ * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.
87
+ * Note that this requires a custom RPC function named 'exec_sql' to be set up in your Supabase project.
88
+ */
89
+ query<T>(sql: string, params?: T[]): Promise<T[]>;
90
+ /**
91
+ * Register a table with the adapter.
92
+ * @template TTable - Type representing the table structure.
93
+ * @template TIdColumn - Type representing the ID column.
94
+ * @param {string} name - Logical name for the table.
95
+ * @param {TTable} [table] - Actual table name (defaults to logical name if not provided).
96
+ * @param {TIdColumn} [idColumn] - Optional ID column name.
97
+ * @description
98
+ * Registers a table with the adapter, allowing it to be referenced by a logical name
99
+ * in subsequent operations. This is necessary for the adapter to perform operations
100
+ * on the table. The ID column can also be specified if it differs from the default 'id'.
101
+ * This registration enables the adapter to map logical table names to actual table names
102
+ * and ID columns, providing a layer of abstraction between the application and the database schema.
103
+ * If no table name is provided, the logical name is used as the actual table name.
104
+ */
105
+ registerTable<TTable, TIdColumn>(name: string, table?: TTable, idColumn?: TIdColumn): void;
106
+ /**
107
+ * Find a single record by ID.
108
+ * @template T - The expected type of the record.
109
+ * @param {string} table - Table name.
110
+ * @param {string} id - Record ID.
111
+ * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.
112
+ * @description
113
+ * Retrieves a single record from the specified table using its primary ID.
114
+ * The method uses Supabase's select method with a filter for the ID column and
115
+ * the single() method to retrieve exactly one record. If the record is found,
116
+ * it is returned in a success result. If no record is found (indicated by error code PGRST116),
117
+ * null is returned in a success result. If an error occurs during the operation,
118
+ * a failure result with an error message is returned.
119
+ */
120
+ findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>>;
121
+ /**
122
+ * Find multiple records with filtering and pagination.
123
+ * @template T - The expected type of the records.
124
+ * @param {string} table - Table name.
125
+ * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.
126
+ * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Promise resolving to DatabaseResult containing paginated data.
127
+ * @description
128
+ * Retrieves multiple records from the specified table with support for filtering,
129
+ * sorting, and pagination. The method first executes a count query to get the
130
+ * total number of matching records, then executes the main query with the applied filters,
131
+ * sorting, and pagination. The result includes the data array, total count of matching records,
132
+ * and pagination metadata such as current page, total pages, and limit.
133
+ * If an error occurs during the operation, a failure result with an error message is returned.
134
+ */
135
+ findMany<T>(table: string, options?: QueryOptions): Promise<DatabaseResult<PaginatedResult<T>>>;
136
+ /**
137
+ * Create a new record.
138
+ * @template T - The expected type of the record.
139
+ * @param {string} table - Table name.
140
+ * @param {T} data - Record data to create.
141
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.
142
+ * @description
143
+ * Inserts a new record into the specified table using the provided data.
144
+ * The method uses Supabase's insert method with the data and then chains a select()
145
+ * and single() call to retrieve the inserted record with any auto-generated fields
146
+ * (like IDs) populated. If the operation is successful, it returns the created record.
147
+ * If an error occurs during the operation, a failure result with an error message is returned.
148
+ */
149
+ create<T>(table: string, data: T): Promise<DatabaseResult<T>>;
150
+ /**
151
+ * Update an existing record.
152
+ * @template T - The expected type of the record.
153
+ * @param {string} table - Table name.
154
+ * @param {string} id - Record ID.
155
+ * @param {Partial<T>} data - Partial record data to update.
156
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.
157
+ * @description
158
+ * Updates an existing record in the specified table using its primary ID.
159
+ * Only the fields provided in the data object are updated, allowing for partial updates.
160
+ * The method uses Supabase's update method with the data and a filter for the ID column,
161
+ * then chains a select() and single() call to retrieve the updated record. If the operation
162
+ * is successful, it returns the updated record. If an error occurs during the operation,
163
+ * a failure result with an error message is returned.
164
+ */
165
+ update<T>(table: string, id: string, data: Partial<T>): Promise<DatabaseResult<T>>;
166
+ /**
167
+ * Delete a record.
168
+ * @param {string} table - Table name.
169
+ * @param {string} id - Record ID.
170
+ * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.
171
+ * @description
172
+ * Deletes a record from the specified table using its primary ID.
173
+ * The method uses Supabase's delete method with a filter for the ID column.
174
+ * If the operation is successful, it returns a success result with no value.
175
+ * If an error occurs during the operation, a failure result with an error message is returned.
176
+ */
177
+ delete(table: string, id: string): Promise<DatabaseResult<void>>;
178
+ /**
179
+ * Execute a transaction.
180
+ * @template T - The expected type of the transaction result.
181
+ * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.
182
+ * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.
183
+ * @description
184
+ * Executes a callback function within a database transaction, providing atomicity.
185
+ * Note that Supabase doesn't support traditional multi-statement transactions in the same way
186
+ * as direct database connections. This adapter simulates transactional behavior by executing
187
+ * all operations through the same client, but does not provide true rollback capabilities.
188
+ * If the callback function executes successfully, the transaction is considered committed.
189
+ * If an error occurs during the execution of the callback function, a failure result with
190
+ * an error message is returned, but any successful operations within the callback will not
191
+ * be rolled back.
192
+ */
193
+ transaction<T>(callback: (trx: Transaction) => Promise<T>): Promise<DatabaseResult<T>>;
194
+ /**
195
+ * Check if a record exists.
196
+ * @param {string} table - Table name.
197
+ * @param {string} id - Record ID.
198
+ * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.
199
+ * @description
200
+ * Checks if a record with the specified ID exists in the table.
201
+ * The method constructs a SELECT query with a WHERE clause for the ID column
202
+ * and a LIMIT of 1. It returns a success result with a boolean value indicating
203
+ * whether the record exists. If an error occurs during the operation, a failure result
204
+ * with an error message is returned.
205
+ */
206
+ exists(table: string, id: string): Promise<DatabaseResult<boolean>>;
207
+ /**
208
+ * Count records matching a filter.
209
+ * @param {string} table - Table name.
210
+ * @param {Filter} [filter] - Filter conditions.
211
+ * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.
212
+ * @description
213
+ * Counts the number of records in the specified table that match the optional filter.
214
+ * The method uses Supabase's select method with the count option set to 'exact'
215
+ * and head set to true to return only the count. If a filter is provided,
216
+ * it is applied to narrow down the count to matching records. It returns a success
217
+ * result with the count of matching records. If an error occurs during the operation,
218
+ * a failure result with an error message is returned.
219
+ */
220
+ count(table: string, filter?: Filter): Promise<DatabaseResult<number>>;
221
+ /**
222
+ * Perform health check.
223
+ * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.
224
+ * @description
225
+ * Checks the health of the database connection by executing a simple RPC call.
226
+ * The method measures the response time of the query to determine the health status.
227
+ * It attempts to call a 'version' RPC function, ignoring errors related to the function
228
+ * not existing but reporting other errors. It returns a success result with a DatabaseHealthStatus
229
+ * object indicating whether the database is healthy, the response time of the health check,
230
+ * and any additional details. If an error occurs during the operation, a failure result
231
+ * with an error message is returned.
232
+ */
233
+ healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>>;
234
+ /**
235
+ * Get the actual table name from the mapped table name.
236
+ * @private
237
+ * @param {string} name - Logical table name.
238
+ * @returns {string} Actual table name.
239
+ * @throws {DatabaseError} If table is not registered.
240
+ * @description
241
+ * Retrieves the actual table name that has been previously registered with the adapter.
242
+ * This method is used internally by other methods to ensure that operations are performed
243
+ * on valid, registered tables. If the table is not found, it throws a DatabaseError.
244
+ */
245
+ private getTableName;
246
+ /**
247
+ * Applies filter conditions to a Supabase query with comprehensive operator support
248
+ *
249
+ * Transforms generic Filter objects into Supabase-specific query methods while maintaining
250
+ * type safety and preventing SQL injection through operator validation.
251
+ *
252
+ * **Supported Operators:**
253
+ * - Equality: eq, ne (not equal)
254
+ * - Comparison: gt, gte, lt, lte
255
+ * - Pattern: like (with % wildcards)
256
+ * - Membership: in, notIn (array values)
257
+ * - Range: between (two-element array)
258
+ * - Null checks: isNull, isNotNull
259
+ *
260
+ * **Security Features:**
261
+ * - Validates field names against regex: /^[a-zA-Z_][a-zA-Z0-9_]*$/
262
+ * - Validates operator against whitelist
263
+ * - Type-checks array values for 'in', 'notIn', 'between' operators
264
+ *
265
+ * @private
266
+ * @template Q - Type of the Supabase query builder
267
+ * @param {Q} query - Supabase query builder instance to apply filters to
268
+ * @param {Filter} filter - Filter conditions with field, operator, and value
269
+ * @returns {Q} Modified query builder with filter conditions applied
270
+ *
271
+ * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'in'/'notIn' value is not an array
272
+ * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'between' value is not a 2-element array
273
+ * @throws {BaseError} SUPABASE_UNSUPPORTED_OPERATOR - If operator is not in whitelist
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * // Equality filter
278
+ * const query1 = this.applyFilter(baseQuery, {
279
+ * field: 'status',
280
+ * operator: 'eq',
281
+ * value: 'active'
282
+ * });
283
+ * // Generates: query.eq('status', 'active')
284
+ *
285
+ * // Range filter
286
+ * const query2 = this.applyFilter(baseQuery, {
287
+ * field: 'age',
288
+ * operator: 'between',
289
+ * value: [18, 65]
290
+ * });
291
+ * // Generates: query.gte('age', 18).lte('age', 65)
292
+ *
293
+ * // Array membership filter
294
+ * const query3 = this.applyFilter(baseQuery, {
295
+ * field: 'category',
296
+ * operator: 'in',
297
+ * value: ['tech', 'science', 'business']
298
+ * });
299
+ * // Generates: query.in('category', ['tech', 'science', 'business'])
300
+ * ```
301
+ *
302
+ */
303
+ private applyFilter;
304
+ }
305
+ //# sourceMappingURL=SupabaseAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SupabaseAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/supabase/SupabaseAdapter.ts"],"names":[],"mappings":"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"}