@groundbrick/repository-base 0.0.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.
@@ -0,0 +1,452 @@
1
+ import { createLogger } from '@groundbrick/logger';
2
+ import { SqlAdapter } from './SqlAdapter.js';
3
+ /**
4
+ * Generic base repository providing CRUD operations for any entity type
5
+ */
6
+ export class BaseRepository {
7
+ db;
8
+ tableName;
9
+ logger;
10
+ sqlAdapter;
11
+ dbType;
12
+ constructor(db, tableName, logger) {
13
+ this.db = db;
14
+ this.tableName = tableName;
15
+ this.logger = logger?.child(`${tableName}-repository`) || createLogger({ context: `${tableName}-repository` });
16
+ // Automatically create SqlAdapter based on DatabaseClient type
17
+ this.sqlAdapter = new SqlAdapter(db);
18
+ this.dbType = db.getDatabaseType();
19
+ this.logger.debug('Repository initialized', {
20
+ table: this.tableName,
21
+ dbType: this.dbType,
22
+ supportsReturning: this.sqlAdapter.supportsReturning()
23
+ });
24
+ }
25
+ // ============================================================================
26
+ // BASIC CRUD OPERATIONS
27
+ // ============================================================================
28
+ /**
29
+ * Find a record by ID
30
+ */
31
+ async findById(id) {
32
+ const timer = this.logger.startTimer('findById');
33
+ this.logger.debug('Finding record by ID', { id, table: this.tableName });
34
+ const sql = this.sqlAdapter.adaptSql(`SELECT * FROM ${this.tableName} WHERE id = ?`);
35
+ try {
36
+ const result = await this.db.query(sql, [id]);
37
+ const record = result.rows[0] || null;
38
+ this.logger.debug('Find by ID result', {
39
+ id,
40
+ found: !!record,
41
+ table: this.tableName
42
+ });
43
+ return record;
44
+ }
45
+ catch (error) {
46
+ this.logger.error('Error finding record by ID', error, {
47
+ id,
48
+ table: this.tableName
49
+ });
50
+ throw error;
51
+ }
52
+ finally {
53
+ timer();
54
+ }
55
+ }
56
+ /**
57
+ * Find one record by condition
58
+ */
59
+ async findOne(condition, params = []) {
60
+ const timer = this.logger.startTimer('findOne');
61
+ this.logger.debug('Finding one record', {
62
+ condition,
63
+ params,
64
+ table: this.tableName
65
+ });
66
+ const sql = this.sqlAdapter.adaptSql(`SELECT * FROM ${this.tableName} WHERE ${condition} LIMIT 1`);
67
+ try {
68
+ const result = await this.db.query(sql, params);
69
+ const record = result.rows[0] || null;
70
+ this.logger.debug('Find one result', {
71
+ condition,
72
+ found: !!record,
73
+ table: this.tableName
74
+ });
75
+ return record;
76
+ }
77
+ catch (error) {
78
+ this.logger.error('Error finding one record', error, {
79
+ condition,
80
+ table: this.tableName
81
+ });
82
+ throw error;
83
+ }
84
+ finally {
85
+ timer();
86
+ }
87
+ }
88
+ /**
89
+ * Find multiple records by condition
90
+ */
91
+ async findMany(condition, params = []) {
92
+ const timer = this.logger.startTimer('findMany');
93
+ this.logger.debug('Finding multiple records', {
94
+ condition,
95
+ params,
96
+ table: this.tableName
97
+ });
98
+ let sql = `SELECT * FROM ${this.tableName}`;
99
+ if (condition) {
100
+ sql += ` WHERE ${condition}`;
101
+ }
102
+ sql = this.sqlAdapter.adaptSql(sql);
103
+ try {
104
+ const result = await this.db.query(sql, params);
105
+ this.logger.debug('Find many result', {
106
+ condition,
107
+ count: result.rows.length,
108
+ table: this.tableName
109
+ });
110
+ return result.rows;
111
+ }
112
+ catch (error) {
113
+ this.logger.error('Error finding multiple records', error, {
114
+ condition,
115
+ table: this.tableName
116
+ });
117
+ throw error;
118
+ }
119
+ finally {
120
+ timer();
121
+ }
122
+ ;
123
+ }
124
+ /**
125
+ * Find all records with optional query options
126
+ */
127
+ async findAll(options = {}) {
128
+ const timer = this.logger.startTimer('findAll');
129
+ this.logger.debug('Finding all records', { options, table: this.tableName });
130
+ let sql = `SELECT * FROM ${this.tableName}`;
131
+ const params = [];
132
+ // Add sorting
133
+ if (options.sort) {
134
+ const sorts = Array.isArray(options.sort) ? options.sort : [options.sort];
135
+ const orderClauses = sorts.map(sort => `${sort.column} ${sort.direction || 'ASC'}`);
136
+ sql += ` ORDER BY ${orderClauses.join(', ')}`;
137
+ }
138
+ // Add pagination
139
+ if (options.pagination) {
140
+ const { limit = 100, offset = 0 } = options.pagination;
141
+ sql += ` ${this.sqlAdapter.getLimitClause(limit, offset)}`;
142
+ }
143
+ try {
144
+ sql = this.sqlAdapter.adaptSql(sql);
145
+ const result = await this.db.query(sql, params);
146
+ this.logger.debug('Find all result', {
147
+ count: result.rows.length,
148
+ table: this.tableName
149
+ });
150
+ return result.rows;
151
+ }
152
+ catch (error) {
153
+ this.logger.error('Error finding all records', error, {
154
+ options,
155
+ table: this.tableName
156
+ });
157
+ throw error;
158
+ }
159
+ finally {
160
+ timer();
161
+ }
162
+ }
163
+ /**
164
+ * Create a new record
165
+ */
166
+ async create(data) {
167
+ const timer = this.logger.startTimer('create');
168
+ this.logger.debug('Creating new record', { data, table: this.tableName });
169
+ try {
170
+ const entries = Object.entries(data);
171
+ const columns = entries.map(([key]) => key);
172
+ const values = entries.map(([, value]) => value);
173
+ // SqlAdapter automatically handles database-specific SQL
174
+ const sql = this.sqlAdapter.createInsertSql(this.tableName, columns);
175
+ if (this.db.supportsReturning()) {
176
+ // PostgreSQL path - automatic RETURNING clause
177
+ const result = await this.db.query(sql, values);
178
+ const created = result.rows[0];
179
+ this.logger.info('Created record', {
180
+ id: created?.id,
181
+ table: this.tableName,
182
+ dbType: this.db.getDatabaseType()
183
+ });
184
+ return created;
185
+ }
186
+ else {
187
+ // MySQL path - separate queries
188
+ await this.db.query(sql, values);
189
+ const lastIdResult = await this.db.query('SELECT LAST_INSERT_ID() as id');
190
+ const newId = lastIdResult.rows[0].id;
191
+ const created = await this.findById(newId);
192
+ this.logger.info('Created record', {
193
+ id: newId,
194
+ table: this.tableName,
195
+ dbType: this.db.getDatabaseType()
196
+ });
197
+ return created;
198
+ }
199
+ }
200
+ catch (error) {
201
+ this.logger.error('Error creating record', error, {
202
+ data,
203
+ table: this.tableName,
204
+ dbType: this.db.getDatabaseType()
205
+ });
206
+ throw error;
207
+ }
208
+ finally {
209
+ timer();
210
+ }
211
+ }
212
+ /**
213
+ * Update a record by ID
214
+ */
215
+ async update(id, data) {
216
+ this.logger.debug('Updating record', { id, data, table: this.tableName });
217
+ const timer = this.logger.startTimer('update');
218
+ const entries = Object.entries(data).filter(([, value]) => value !== undefined);
219
+ if (entries.length === 0) {
220
+ this.logger.debug('No fields to update', { id, table: this.tableName });
221
+ return this.findById(id);
222
+ }
223
+ const columns = entries.map(([key]) => key);
224
+ const values = entries.map(([, value]) => value);
225
+ try {
226
+ const sql = this.sqlAdapter.createUpdateSql(this.tableName, columns);
227
+ if (this.db.supportsReturning()) {
228
+ // PostgreSQL path
229
+ const result = await this.db.query(sql, [...values, id]);
230
+ const updated = result.rows[0] || null;
231
+ this.logger.info('Updated record', {
232
+ id,
233
+ updated: !!updated,
234
+ table: this.tableName,
235
+ dbType: this.db.getDatabaseType()
236
+ });
237
+ return updated;
238
+ }
239
+ else {
240
+ // MySQL path
241
+ const result = await this.db.query(sql, [...values, id]);
242
+ if (result.rowCount === 0) {
243
+ return null;
244
+ }
245
+ const updated = await this.findById(id);
246
+ this.logger.info('Updated record', {
247
+ id,
248
+ updated: !!updated,
249
+ table: this.tableName,
250
+ dbType: this.db.getDatabaseType()
251
+ });
252
+ return updated;
253
+ }
254
+ }
255
+ catch (error) {
256
+ this.logger.error('Error updating record', error, {
257
+ id,
258
+ data,
259
+ table: this.tableName
260
+ });
261
+ throw error;
262
+ }
263
+ finally {
264
+ timer();
265
+ }
266
+ }
267
+ /**
268
+ * Delete a record by ID
269
+ */
270
+ async delete(id) {
271
+ const timer = this.logger.startTimer('delete');
272
+ this.logger.debug('Deleting record', { id, table: this.tableName });
273
+ try {
274
+ const sql = this.sqlAdapter.createDeleteSql(this.tableName);
275
+ const result = await this.db.query(sql, [id]);
276
+ const deleted = (result.rowCount || 0) > 0;
277
+ if (deleted) {
278
+ this.logger.info('Record deleted successfully', { id, deleted, table: this.tableName, dbType: this.db.getDatabaseType() });
279
+ }
280
+ else {
281
+ this.logger.debug('No record found to delete', { id, table: this.tableName, dbType: this.db.getDatabaseType() });
282
+ }
283
+ return deleted;
284
+ }
285
+ catch (error) {
286
+ this.logger.error('Error deleting record', error, {
287
+ id,
288
+ table: this.tableName,
289
+ dbType: this.db.getDatabaseType()
290
+ });
291
+ throw error;
292
+ }
293
+ finally {
294
+ timer();
295
+ }
296
+ }
297
+ // ============================================================================
298
+ // UTILITY METHODS
299
+ // ============================================================================
300
+ /**
301
+ * Count records with optional condition
302
+ */
303
+ async count(condition, params = []) {
304
+ const timer = this.logger.startTimer('count');
305
+ this.logger.debug('Counting records', { condition, params, table: this.tableName });
306
+ let sql = `SELECT COUNT(*) as count FROM ${this.tableName}`;
307
+ if (condition) {
308
+ sql += ` WHERE ${condition}`;
309
+ }
310
+ try {
311
+ sql = this.sqlAdapter.adaptSql(sql);
312
+ const result = await this.db.query(sql, params);
313
+ const count = Number(result.rows[0]?.count || 0);
314
+ this.logger.debug('Count result', {
315
+ condition,
316
+ count,
317
+ table: this.tableName
318
+ });
319
+ return count;
320
+ }
321
+ catch (error) {
322
+ this.logger.error('Error counting records', error, {
323
+ condition,
324
+ table: this.tableName
325
+ });
326
+ throw error;
327
+ }
328
+ finally {
329
+ timer();
330
+ }
331
+ }
332
+ /**
333
+ * Check if a record exists by ID
334
+ */
335
+ async exists(id) {
336
+ this.logger.debug('Checking if record exists', { id, table: this.tableName });
337
+ const count = await this.count('id = ?', [id]);
338
+ const exists = count > 0;
339
+ this.logger.debug('Exists result', { id, exists, table: this.tableName });
340
+ return exists;
341
+ }
342
+ /**
343
+ * Find records with pagination
344
+ */
345
+ async findPaginated(options) {
346
+ const { condition, params = [], pagination } = options;
347
+ const { limit = 10, offset = 0 } = pagination;
348
+ this.logger.debug('Finding paginated records', {
349
+ condition,
350
+ params,
351
+ pagination,
352
+ table: this.tableName
353
+ });
354
+ // Get total count
355
+ const total = await this.count(condition, params);
356
+ // Get data
357
+ const data = await this.findMany(condition, params);
358
+ const result = {
359
+ data,
360
+ total,
361
+ limit,
362
+ offset,
363
+ hasNext: offset + limit < total,
364
+ hasPrevious: offset > 0
365
+ };
366
+ this.logger.debug('Paginated result', {
367
+ condition,
368
+ total,
369
+ returned: data.length,
370
+ table: this.tableName
371
+ });
372
+ return result;
373
+ }
374
+ // ============================================================================
375
+ // RAW QUERY METHOD
376
+ // ============================================================================
377
+ /**
378
+ * Execute a raw SQL query (use with caution)
379
+ */
380
+ async rawQuery(sql, params = []) {
381
+ const timer = this.logger.startTimer('rawQuery');
382
+ this.logger.debug('Executing raw query', { sql, params, table: this.tableName });
383
+ try {
384
+ const adaptedSql = this.sqlAdapter.adaptSql(sql);
385
+ const result = await this.db.query(adaptedSql, params);
386
+ this.logger.debug('Raw query result', {
387
+ sql: adaptedSql,
388
+ rowCount: result.rows.length,
389
+ table: this.tableName
390
+ });
391
+ return result;
392
+ }
393
+ catch (error) {
394
+ this.logger.error('Error executing raw query', error, {
395
+ sql,
396
+ params,
397
+ table: this.tableName
398
+ });
399
+ throw error;
400
+ }
401
+ finally {
402
+ timer();
403
+ }
404
+ }
405
+ // ============================================================================
406
+ // TRANSACTION HELPER
407
+ // ============================================================================
408
+ /**
409
+ * Helper method for transaction-aware create operations
410
+ */
411
+ async createWithTransaction(tx, data) {
412
+ const keys = Object.keys(data);
413
+ const values = Object.values(data);
414
+ const sql = tx.createInsertSql(this.tableName, keys);
415
+ if (tx.supportsReturning()) {
416
+ const result = await tx.query(sql, values);
417
+ return result.rows[0];
418
+ }
419
+ else {
420
+ await tx.query(sql, values);
421
+ const lastIdResult = await tx.query('SELECT LAST_INSERT_ID() as id');
422
+ const newId = lastIdResult.rows[0].id;
423
+ const selectResult = await tx.query(tx.adaptSql(`SELECT * FROM ${this.tableName} WHERE id = ?`), [newId]);
424
+ return selectResult.rows[0];
425
+ }
426
+ }
427
+ /**
428
+ * Helper method for transaction-aware update operations
429
+ */
430
+ async updateWithTransaction(tx, id, data) {
431
+ const keys = Object.keys(data);
432
+ const values = Object.values(data);
433
+ if (keys.length === 0) {
434
+ const result = await tx.query(tx.adaptSql(`SELECT * FROM ${this.tableName} WHERE id = ?`), [id]);
435
+ return result.rows[0] || null;
436
+ }
437
+ const sql = tx.createUpdateSql(this.tableName, keys);
438
+ if (tx.supportsReturning()) {
439
+ const result = await tx.query(sql, [...values, id]);
440
+ return result.rows[0] || null;
441
+ }
442
+ else {
443
+ const updateResult = await tx.query(sql, [...values, id]);
444
+ if (updateResult.rowCount === 0) {
445
+ return null;
446
+ }
447
+ const selectResult = await tx.query(tx.adaptSql(`SELECT * FROM ${this.tableName} WHERE id = ?`), [id]);
448
+ return selectResult.rows[0] || null;
449
+ }
450
+ }
451
+ }
452
+ //# sourceMappingURL=BaseRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseRepository.js","sourceRoot":"","sources":["../../src/core/BaseRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { DatabaseClient } from '@groundbrick/db-core';
2
+ /**
3
+ * SQL Adapter that automatically detects database type from DatabaseClient
4
+ */
5
+ export declare class SqlAdapter {
6
+ private dbType;
7
+ constructor(db: DatabaseClient);
8
+ /**
9
+ * Get the database type
10
+ */
11
+ getDatabaseType(): 'postgresql' | 'mysql';
12
+ /**
13
+ * Check if database supports RETURNING clause
14
+ */
15
+ supportsReturning(): boolean;
16
+ /**
17
+ * Convert SQL with ? placeholders to database-specific format
18
+ */
19
+ adaptSql(sql: string): string;
20
+ /**
21
+ * Create database-specific INSERT SQL
22
+ */
23
+ createInsertSql(tableName: string, columns: string[]): string;
24
+ /**
25
+ * Create database-specific UPDATE SQL
26
+ */
27
+ createUpdateSql(tableName: string, columns: string[]): string;
28
+ /**
29
+ * Create database-specific DELETE SQL
30
+ */
31
+ createDeleteSql(tableName: string): string;
32
+ /**
33
+ * Get database-specific NOW() function
34
+ */
35
+ getNowFunction(): string;
36
+ /**
37
+ * Get database-specific LIMIT clause
38
+ */
39
+ getLimitClause(limit: number, offset?: number): string;
40
+ }
41
+ //# sourceMappingURL=SqlAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlAdapter.d.ts","sourceRoot":"","sources":["../../src/core/SqlAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,EAAE,EAAE,cAAc;IAK9B;;OAEG;IACH,eAAe,IAAI,YAAY,GAAG,OAAO;IAIzC;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAU7B;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAc7D;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAgB7D;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI1C;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM;CAM5D"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * SQL Adapter that automatically detects database type from DatabaseClient
3
+ */
4
+ export class SqlAdapter {
5
+ dbType;
6
+ constructor(db) {
7
+ // Automatically detect database type from client
8
+ this.dbType = db.getDatabaseType();
9
+ }
10
+ /**
11
+ * Get the database type
12
+ */
13
+ getDatabaseType() {
14
+ return this.dbType;
15
+ }
16
+ /**
17
+ * Check if database supports RETURNING clause
18
+ */
19
+ supportsReturning() {
20
+ return this.dbType === 'postgresql';
21
+ }
22
+ /**
23
+ * Convert SQL with ? placeholders to database-specific format
24
+ */
25
+ adaptSql(sql) {
26
+ if (this.dbType === 'postgresql') {
27
+ // Convert ? placeholders to $1, $2, etc.
28
+ let index = 1;
29
+ return sql.replace(/\?/g, () => `$${index++}`);
30
+ }
31
+ // MySQL uses ? placeholders as-is
32
+ return sql;
33
+ }
34
+ /**
35
+ * Create database-specific INSERT SQL
36
+ */
37
+ createInsertSql(tableName, columns) {
38
+ const placeholders = columns.map((_, index) => {
39
+ return this.dbType === 'postgresql' ? `$${index + 1}` : '?';
40
+ }).join(', ');
41
+ let sql = `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders})`;
42
+ if (this.supportsReturning()) {
43
+ sql += ' RETURNING *';
44
+ }
45
+ return sql;
46
+ }
47
+ /**
48
+ * Create database-specific UPDATE SQL
49
+ */
50
+ createUpdateSql(tableName, columns) {
51
+ const setParts = columns.map((col, index) => {
52
+ const placeholder = this.dbType === 'postgresql' ? `$${index + 1}` : '?';
53
+ return `${col} = ${placeholder}`;
54
+ });
55
+ const idPlaceholder = this.dbType === 'postgresql' ? `$${columns.length + 1}` : '?';
56
+ let sql = `UPDATE ${tableName} SET ${setParts.join(', ')} WHERE id = ${idPlaceholder}`;
57
+ if (this.supportsReturning()) {
58
+ sql += ' RETURNING *';
59
+ }
60
+ return sql;
61
+ }
62
+ /**
63
+ * Create database-specific DELETE SQL
64
+ */
65
+ createDeleteSql(tableName) {
66
+ return this.adaptSql(`DELETE FROM ${tableName} WHERE id = ?`);
67
+ }
68
+ /**
69
+ * Get database-specific NOW() function
70
+ */
71
+ getNowFunction() {
72
+ return 'NOW()'; // Both databases support this
73
+ }
74
+ /**
75
+ * Get database-specific LIMIT clause
76
+ */
77
+ getLimitClause(limit, offset = 0) {
78
+ if (offset > 0) {
79
+ return `LIMIT ${limit} OFFSET ${offset}`;
80
+ }
81
+ return `LIMIT ${limit}`;
82
+ }
83
+ }
84
+ //# sourceMappingURL=SqlAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlAdapter.js","sourceRoot":"","sources":["../../src/core/SqlAdapter.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,UAAU;IACX,MAAM,CAAyB;IAEvC,YAAY,EAAkB;QAC1B,iDAAiD;QACjD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,eAAe;QACX,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,iBAAiB;QACb,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,GAAW;QAChB,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YAC/B,yCAAyC;YACzC,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,kCAAkC;QAClC,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,SAAiB,EAAE,OAAiB;QAChD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAC1C,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAChE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,IAAI,GAAG,GAAG,eAAe,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,YAAY,GAAG,CAAC;QAEtF,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC3B,GAAG,IAAI,cAAc,CAAC;QAC1B,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,SAAiB,EAAE,OAAiB;QAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACxC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YACzE,OAAO,GAAG,GAAG,MAAM,WAAW,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACpF,IAAI,GAAG,GAAG,UAAU,SAAS,QAAQ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,aAAa,EAAE,CAAC;QAEvF,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC3B,GAAG,IAAI,cAAc,CAAC;QAC1B,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,SAAiB;QAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,SAAS,eAAe,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,cAAc;QACV,OAAO,OAAO,CAAC,CAAC,8BAA8B;IAClD,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,KAAa,EAAE,SAAiB,CAAC;QAC5C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACb,OAAO,SAAS,KAAK,WAAW,MAAM,EAAE,CAAC;QAC7C,CAAC;QACD,OAAO,SAAS,KAAK,EAAE,CAAC;IAC5B,CAAC;CACJ"}
@@ -0,0 +1,6 @@
1
+ export { BaseRepository } from './core/BaseRepository.js';
2
+ export type { BaseEntity, SimpleEntity, CreateEntityData, UpdateEntityData, RepositoryEntity } from './types/Entity.js';
3
+ export type { PaginationOptions, SortOptions, QueryOptions, FindManyOptions, PaginatedResult } from './types/QueryOptions.js';
4
+ export type { DatabaseClient, QueryResult } from '@groundbrick/db-core';
5
+ export type { Logger } from '@groundbrick/logger';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,YAAY,EACR,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACR,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EAClB,MAAM,yBAAyB,CAAC;AAMjC,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ // packages/repository-base/src/index.ts
2
+ // ============================================================================
3
+ // CORE CLASSES
4
+ // ============================================================================
5
+ export { BaseRepository } from './core/BaseRepository.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Base entity interface that all entities should extend.
3
+ * Provides common fields that are typically present in database tables.
4
+ */
5
+ export interface BaseEntity {
6
+ id?: number;
7
+ created_at?: Date;
8
+ updated_at?: Date;
9
+ }
10
+ /**
11
+ * Generic entity type that can be used for entities without timestamps
12
+ */
13
+ export interface SimpleEntity {
14
+ id?: number;
15
+ }
16
+ /**
17
+ * Type helper for creating new entities (excludes id and timestamps)
18
+ */
19
+ export type CreateEntityData<T extends BaseEntity> = Omit<T, 'id' | 'created_at' | 'updated_at'>;
20
+ /**
21
+ * Type helper for updating entities (excludes id and created_at)
22
+ */
23
+ export type UpdateEntityData<T extends BaseEntity> = Partial<Omit<T, 'id' | 'created_at'>>;
24
+ /**
25
+ * Type helper for entities that can be used in repositories
26
+ * Requires at least an id field
27
+ */
28
+ export type RepositoryEntity = {
29
+ id?: number;
30
+ [key: string]: any;
31
+ };
32
+ //# sourceMappingURL=Entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../src/types/Entity.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAEjG;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC;AAE3F;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAA,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC"}