@elysiumjs/mnemosyne 0.1.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/interfaces.ts DELETED
@@ -1,449 +0,0 @@
1
- // Copyright (c) 2026-present Workbud Technologies Inc. All rights reserved.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type { TSchema } from 'elysia';
16
-
17
- // ============================================================================
18
- // Driver
19
- // ============================================================================
20
-
21
- /**
22
- * Contract for ORM drivers.
23
- *
24
- * A database driver is responsible for creating connections, managing
25
- * transactions, and exposing the raw underlying client.
26
- *
27
- * @author Axel Nana <axel.nana@workbud.com>
28
- * @template TConnection The connection type managed by the driver.
29
- * @template TConnectionConfig The configuration used to create a connection.
30
- */
31
- export interface DatabaseDriver<TConnection = unknown, TConnectionConfig = unknown> {
32
- /**
33
- * Creates a new database connection from the given configuration.
34
- * @param config The connection configuration.
35
- * @returns A new database connection.
36
- */
37
- createConnection(config: TConnectionConfig): TConnection;
38
-
39
- /**
40
- * Executes a callback within a database transaction.
41
- * @param connection The connection to use for the transaction.
42
- * @param callback The function to execute within the transaction.
43
- * @returns The return value of the callback.
44
- */
45
- withTransaction<T>(
46
- connection: TConnection,
47
- callback: (tx: TConnection) => Promise<T>
48
- ): Promise<T>;
49
-
50
- /**
51
- * Returns the raw underlying client from a connection.
52
- * @param connection The connection to extract the raw client from.
53
- * @returns The raw client instance.
54
- */
55
- getRawClient(connection: TConnection): unknown;
56
- }
57
-
58
- // ============================================================================
59
- // Model Adapter
60
- // ============================================================================
61
-
62
- /**
63
- * Normalized column metadata for a table.
64
- *
65
- * Provides an ORM-agnostic description of a column's name, type,
66
- * nullability, default status, and primary key status.
67
- *
68
- * @author Axel Nana <axel.nana@workbud.com>
69
- */
70
- export interface ColumnMetadata {
71
- /**
72
- * The column name.
73
- */
74
- name: string;
75
-
76
- /**
77
- * The normalized data type of the column.
78
- */
79
- dataType:
80
- | 'string'
81
- | 'number'
82
- | 'boolean'
83
- | 'date'
84
- | 'datetime'
85
- | 'json'
86
- | 'array'
87
- | 'bigint'
88
- | 'buffer'
89
- | 'uuid';
90
-
91
- /**
92
- * Whether the column allows `NULL` values.
93
- */
94
- nullable: boolean;
95
-
96
- /**
97
- * Whether the column has a default value.
98
- */
99
- hasDefault: boolean;
100
-
101
- /**
102
- * Whether the column is a primary key.
103
- */
104
- isPrimaryKey: boolean;
105
- }
106
-
107
- /**
108
- * Bridges ORM-specific table schemas to framework metadata.
109
- *
110
- * A model adapter translates between the ORM's internal table
111
- * representation and the normalized metadata used by the framework.
112
- *
113
- * @author Axel Nana <axel.nana@workbud.com>
114
- * @template TTable The ORM-specific table type.
115
- */
116
- export interface ModelAdapter<TTable = unknown> {
117
- /**
118
- * Returns the name of the given table.
119
- * @param table The table to get the name of.
120
- * @returns The table name.
121
- */
122
- getTableName(table: TTable): string;
123
-
124
- /**
125
- * Returns the normalized column metadata for the given table.
126
- * @param table The table to extract columns from.
127
- * @returns An array of column metadata.
128
- */
129
- getColumns(table: TTable): ColumnMetadata[];
130
-
131
- /**
132
- * Creates a tenant-scoped copy of the given table.
133
- * @param table The original table.
134
- * @param tenant The tenant identifier.
135
- * @returns A new table scoped to the given tenant.
136
- */
137
- createTenantTable(table: TTable, tenant: string): TTable;
138
- }
139
-
140
- // ============================================================================
141
- // Tenancy
142
- // ============================================================================
143
-
144
- /**
145
- * Contract for tenancy strategies.
146
- *
147
- * A tenancy strategy determines how tables and connections are
148
- * scoped to a specific tenant.
149
- *
150
- * @author Axel Nana <axel.nana@workbud.com>
151
- * @template TTable The ORM-specific table type.
152
- * @template TConnection The connection type used by the strategy.
153
- */
154
- export interface TenancyStrategy<TTable = unknown, TConnection = unknown> {
155
- /**
156
- * The tenancy mode identifier (e.g. `'schema'`, `'rls'`).
157
- */
158
- readonly mode: string;
159
-
160
- /**
161
- * Resolves a table to its tenant-scoped equivalent.
162
- * @param table The original table.
163
- * @param tenant The tenant identifier.
164
- * @returns The tenant-scoped table.
165
- */
166
- resolveTable(table: TTable, tenant: string): TTable;
167
-
168
- /**
169
- * Executes a callback with tenant-level isolation applied to the connection.
170
- * @param connection The database connection.
171
- * @param tenant The tenant identifier.
172
- * @param callback The function to execute within the isolated context.
173
- * @returns The return value of the callback.
174
- */
175
- withIsolation<T>(connection: TConnection, tenant: string, callback: () => Promise<T>): Promise<T>;
176
- }
177
-
178
- // ============================================================================
179
- // Cache
180
- // ============================================================================
181
-
182
- /**
183
- * Contract for database query cache strategies.
184
- *
185
- * Implementations are responsible for storing, retrieving, and
186
- * invalidating cached query results.
187
- *
188
- * @author Axel Nana <axel.nana@workbud.com>
189
- */
190
- export interface DatabaseCacheStrategy {
191
- /**
192
- * Retrieves a cached query result by key.
193
- * @param key The cache key.
194
- * @returns The cached result, or `undefined` if not found.
195
- */
196
- get(key: string): Promise<unknown[] | undefined>;
197
-
198
- /**
199
- * Stores a query result in the cache.
200
- * @param key The cache key.
201
- * @param response The query result to cache.
202
- * @param tables The tables involved in the query.
203
- * @param config Optional cache configuration.
204
- */
205
- put(key: string, response: unknown[], tables: string[], config?: { ttl?: number }): Promise<void>;
206
-
207
- /**
208
- * Invalidates cached entries affected by a mutation.
209
- * @param params The tables and/or tags affected by the mutation.
210
- */
211
- onMutate(params: { tables?: string[]; tags?: string[] }): Promise<void>;
212
- }
213
-
214
- /**
215
- * Configuration for database query caching.
216
- * @author Axel Nana <axel.nana@workbud.com>
217
- */
218
- export interface DatabaseCacheConfig {
219
- /**
220
- * Whether caching is enabled.
221
- */
222
- enabled?: boolean;
223
-
224
- /**
225
- * The default TTL for cached data, in seconds.
226
- */
227
- ttl?: number;
228
-
229
- /**
230
- * The caching strategy.
231
- * - `'explicit'`: Only cache queries that explicitly opt in.
232
- * - `'all'`: Cache all queries automatically.
233
- */
234
- strategy?: 'explicit' | 'all';
235
-
236
- /**
237
- * The storage engine to use for the cache.
238
- */
239
- storage?: 'redis' | 'memory';
240
- }
241
-
242
- // ============================================================================
243
- // Repository
244
- // ============================================================================
245
-
246
- /**
247
- * Database primary column type.
248
- * @author Axel Nana <axel.nana@workbud.com>
249
- */
250
- export type IdType = number | string;
251
-
252
- /**
253
- * ORM-agnostic CRUD repository contract.
254
- *
255
- * Provides a standard interface for common database operations
256
- * regardless of the underlying ORM implementation.
257
- *
258
- * @author Axel Nana <axel.nana@workbud.com>
259
- * @template TSelect The type returned by select queries.
260
- * @template TInsert The type needed by insert queries.
261
- * @template TUpdate The type needed by update queries.
262
- * @template TId The primary key type.
263
- */
264
- export interface RepositoryInterface<TSelect, TInsert, TUpdate, TId extends IdType = string> {
265
- /**
266
- * Retrieves all the records in the database.
267
- * @returns All the records in the database.
268
- */
269
- all(): Promise<TSelect[]>;
270
-
271
- /**
272
- * Retrieves a paginated subset of the records in the database.
273
- * @param count The number of records per page.
274
- * @param page The page number to retrieve.
275
- * @returns A paginated response containing the records and the total count.
276
- */
277
- paginate(count: number, page: number): Promise<{ page: number; data: TSelect[]; total: number }>;
278
-
279
- /**
280
- * Retrieves a record by its id.
281
- * @param id The id of the record to retrieve.
282
- * @returns The record with the given id, or `null` if not found.
283
- */
284
- find(id: TId): Promise<TSelect | null>;
285
-
286
- /**
287
- * Finds the first record with a column matching the given value.
288
- * @param column The column to filter by.
289
- * @param value The value the column should match.
290
- * @returns The first record with a column matching the given value, or `null`.
291
- */
292
- findBy<TKey extends keyof TSelect>(column: TKey, value: TSelect[TKey]): Promise<TSelect | null>;
293
-
294
- /**
295
- * Inserts a new record in the database.
296
- * @param data The data to insert.
297
- * @returns The inserted record.
298
- */
299
- insert(data: TInsert): Promise<TSelect>;
300
-
301
- /**
302
- * Updates a record in the database.
303
- * @param id The id of the record to update.
304
- * @param data The data to update.
305
- * @returns The updated record.
306
- */
307
- update(id: TId, data: TUpdate): Promise<TSelect>;
308
-
309
- /**
310
- * Updates all the records in the database.
311
- * @param data The data to update.
312
- * @returns The updated records.
313
- */
314
- updateAll(data: TUpdate): Promise<TSelect[]>;
315
-
316
- /**
317
- * Deletes a record from the database.
318
- * @param id The ID of the record to delete.
319
- * @returns The deleted record.
320
- */
321
- delete(id: TId): Promise<TSelect>;
322
-
323
- /**
324
- * Deletes all the records from the database.
325
- * @returns All the deleted records.
326
- */
327
- deleteAll(): Promise<TSelect[]>;
328
-
329
- /**
330
- * Checks if a record exists in the database.
331
- * @param id The ID of the record to check.
332
- * @returns `true` if the record exists, `false` otherwise.
333
- */
334
- exists(id: TId): Promise<boolean>;
335
- }
336
-
337
- // ============================================================================
338
- // Model Class
339
- // ============================================================================
340
-
341
- /**
342
- * Shape of a model class.
343
- *
344
- * Describes the static interface that a model class must expose,
345
- * including inferred types, table metadata, and validation schemas.
346
- *
347
- * @author Axel Nana <axel.nana@workbud.com>
348
- * @template TSelect The type returned by select queries.
349
- * @template TInsert The type needed by insert queries.
350
- * @template TUpdate The type needed by update queries.
351
- * @template TTable The ORM-specific table type.
352
- */
353
- export type ModelClass<
354
- TSelect = unknown,
355
- TInsert = unknown,
356
- TUpdate = unknown,
357
- TTable = unknown
358
- > = {
359
- /**
360
- * The data type returned by select queries.
361
- */
362
- readonly $inferSelect: TSelect;
363
-
364
- /**
365
- * The data type needed by insert queries.
366
- */
367
- readonly $inferInsert: TInsert;
368
-
369
- /**
370
- * The data type needed by update queries.
371
- */
372
- readonly $inferUpdate: TUpdate;
373
-
374
- /**
375
- * The ORM-specific table schema wrapped by this model.
376
- */
377
- readonly table: TTable;
378
-
379
- /**
380
- * The name of the table wrapped by the model.
381
- */
382
- readonly tableName: string;
383
-
384
- /**
385
- * The table columns configuration.
386
- */
387
- readonly columns: Record<string, unknown>;
388
-
389
- /**
390
- * The validation schema for creating records.
391
- */
392
- readonly insertSchema: TSchema;
393
-
394
- /**
395
- * The validation schema for updating records.
396
- */
397
- readonly updateSchema: TSchema;
398
-
399
- /**
400
- * The validation schema for selecting records.
401
- */
402
- readonly selectSchema: TSchema;
403
-
404
- /**
405
- * Whether the model supports tenancy.
406
- */
407
- readonly supportTenancy: boolean;
408
-
409
- /**
410
- * Creates a new instance of the model.
411
- * @param args The arguments to pass to the constructor.
412
- * @returns A new instance of the model.
413
- */
414
- new (...args: unknown[]): unknown;
415
- };
416
-
417
- // ============================================================================
418
- // Repository Class
419
- // ============================================================================
420
-
421
- /**
422
- * Shape of a repository class.
423
- *
424
- * Describes the static interface that a repository class must expose,
425
- * including the associated model and connection name.
426
- *
427
- * @author Axel Nana <axel.nana@workbud.com>
428
- * @template TModel The model class type wrapped by the repository.
429
- */
430
- export type RepositoryClass<TModel extends ModelClass = ModelClass> = {
431
- /**
432
- * The model class wrapped by this repository.
433
- */
434
- readonly Model: TModel;
435
-
436
- /**
437
- * The database connection name to use in the repository.
438
- */
439
- readonly connection: string;
440
-
441
- /**
442
- * Creates a new instance of the repository.
443
- * @param args The arguments to pass to the constructor.
444
- * @returns A new repository instance.
445
- */
446
- new (
447
- ...args: unknown[]
448
- ): RepositoryInterface<TModel['$inferSelect'], TModel['$inferInsert'], TModel['$inferUpdate']>;
449
- };