@plyaz/db 0.4.0 → 0.5.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.
@@ -7,6 +7,7 @@
7
7
  *
8
8
  */
9
9
  import type { DatabaseResult, PaginatedResult, QueryOptions, Filter, DatabaseServiceInterface, CreateInput, OperationConfig } from "@plyaz/types/db";
10
+ import { QueryBuilder } from "../builder/query/QueryBuilder";
10
11
  /**
11
12
  * BASE REPOSITORY - Repository Layer Foundation
12
13
  *
@@ -86,6 +87,45 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
86
87
  protected readonly tableName: string;
87
88
  protected readonly defaultConfig?: OperationConfig;
88
89
  constructor(db: DatabaseServiceInterface, tableName: string, defaultConfig?: OperationConfig);
90
+ /**
91
+ * Create a fluent QueryBuilder for this repository
92
+ *
93
+ * Returns a type-safe, chainable query builder that can execute queries
94
+ * directly against this repository.
95
+ *
96
+ * @returns QueryBuilder bound to this repository
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * // Fluent query with execute
101
+ * const result = await userRepository.query()
102
+ * .where('status', 'eq', 'active')
103
+ * .orderByDesc('createdAt')
104
+ * .limit(20)
105
+ * .execute();
106
+ *
107
+ * // Get data directly
108
+ * const users = await userRepository.query()
109
+ * .where('role', 'eq', 'admin')
110
+ * .getMany();
111
+ *
112
+ * // Get single record
113
+ * const user = await userRepository.query()
114
+ * .where('email', 'eq', 'john@example.com')
115
+ * .getOne();
116
+ *
117
+ * // Complex queries
118
+ * const orders = await orderRepository.query()
119
+ * .where('status', 'eq', 'pending')
120
+ * .andWhere('totalAmount', 'gte', 100)
121
+ * .orWhere('priority', 'eq', 'high')
122
+ * .whereIn('region', ['US', 'EU'])
123
+ * .orderBy('createdAt', 'desc')
124
+ * .paginate(1, 25)
125
+ * .execute();
126
+ * ```
127
+ */
128
+ query(): QueryBuilder<T>;
89
129
  /**
90
130
  * Get the table name for this repository
91
131
  *
@@ -124,25 +164,35 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
124
164
  /**
125
165
  * Find multiple entities with optional filtering, sorting, and pagination
126
166
  *
127
- * @param {QueryOptions<T>} [options] - Optional query configuration with type-safe fields
167
+ * Accepts either QueryOptions object or a QueryBuilder instance.
168
+ *
169
+ * @param {QueryOptions<T> | QueryBuilder<T>} [options] - Query configuration or QueryBuilder
128
170
  * @param {OperationConfig} [config] - Optional per-operation configuration (adapter selection, schema override, etc.)
129
171
  * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Promise resolving to paginated results
130
172
  *
131
173
  * @example
132
174
  * ```typescript
175
+ * // Using QueryOptions (traditional)
133
176
  * const result = await userRepository.findMany({
134
177
  * filter: { field: 'status', operator: 'eq', value: 'active' },
135
178
  * sort: [{ field: 'createdAt', direction: 'desc' }],
136
179
  * pagination: { limit: 20, offset: 0 }
137
180
  * });
138
181
  *
182
+ * // Using QueryBuilder
183
+ * const query = QueryBuilder.create<User>()
184
+ * .where('status', 'eq', 'active')
185
+ * .orderByDesc('createdAt')
186
+ * .limit(20);
187
+ * const result = await userRepository.findMany(query);
188
+ *
139
189
  * // Query from analytics database
140
190
  * const analyticsResult = await userRepository.findMany({}, {
141
191
  * adapter: 'analytics'
142
192
  * });
143
193
  * ```
144
194
  */
145
- findMany(options?: QueryOptions<T>, config?: OperationConfig): Promise<DatabaseResult<PaginatedResult<T>>>;
195
+ findMany(options?: QueryOptions<T> | QueryBuilder<T>, config?: OperationConfig): Promise<DatabaseResult<PaginatedResult<T>>>;
146
196
  /**
147
197
  * Create a new entity in the database
148
198
  *
@@ -216,7 +266,9 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
216
266
  /**
217
267
  * Count entities matching optional filter criteria
218
268
  *
219
- * @param {Filter<T>} [filter] - Optional filter conditions with type-safe fields
269
+ * Accepts either a Filter object or a QueryBuilder instance.
270
+ *
271
+ * @param {Filter<T> | QueryBuilder<T>} [filter] - Filter conditions or QueryBuilder
220
272
  * @param {OperationConfig} [config] - Optional per-operation configuration (adapter selection, schema override, etc.)
221
273
  * @returns {Promise<DatabaseResult<number>>} Promise resolving to the count
222
274
  *
@@ -227,13 +279,19 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
227
279
  * field: 'status', operator: 'eq', value: 'active'
228
280
  * });
229
281
  *
282
+ * // Using QueryBuilder
283
+ * const query = QueryBuilder.create<User>()
284
+ * .where('status', 'eq', 'active')
285
+ * .andWhere('verified', 'eq', true);
286
+ * const result = await userRepository.count(query);
287
+ *
230
288
  * // Count in specific adapter
231
289
  * const archiveCount = await userRepository.count(undefined, {
232
290
  * adapter: 'archive'
233
291
  * });
234
292
  * ```
235
293
  */
236
- count(filter?: Filter<T>, config?: OperationConfig): Promise<DatabaseResult<number>>;
294
+ count(filter?: Filter<T> | QueryBuilder<T>, config?: OperationConfig): Promise<DatabaseResult<number>>;
237
295
  /**
238
296
  * Check if an entity exists by ID
239
297
  *
@@ -258,7 +316,9 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
258
316
  /**
259
317
  * Find the first entity matching filter criteria
260
318
  *
261
- * @param {Filter<T>} filter - Filter conditions with type-safe fields
319
+ * Accepts either a Filter object or a QueryBuilder instance.
320
+ *
321
+ * @param {Filter<T> | QueryBuilder<T>} filter - Filter conditions or QueryBuilder
262
322
  * @param {OperationConfig} [config] - Optional per-operation configuration (adapter selection, schema override, etc.)
263
323
  * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to first match or null
264
324
  *
@@ -268,6 +328,12 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
268
328
  * field: 'email', operator: 'eq', value: 'john@example.com'
269
329
  * });
270
330
  *
331
+ * // Using QueryBuilder
332
+ * const query = QueryBuilder.create<User>()
333
+ * .where('email', 'eq', 'john@example.com')
334
+ * .andWhere('status', 'eq', 'active');
335
+ * const result = await userRepository.findOne(query);
336
+ *
271
337
  * // Find in specific adapter
272
338
  * const archivedUser = await userRepository.findOne({
273
339
  * field: 'email', operator: 'eq', value: 'john@example.com'
@@ -277,7 +343,7 @@ export declare abstract class BaseRepository<T extends Record<string, unknown>>
277
343
  * });
278
344
  * ```
279
345
  */
280
- findOne(filter: Filter<T>, config?: OperationConfig): Promise<DatabaseResult<T | null>>;
346
+ findOne(filter: Filter<T> | QueryBuilder<T>, config?: OperationConfig): Promise<DatabaseResult<T | null>>;
281
347
  /**
282
348
  * Soft delete an entity by ID (recoverable deletion)
283
349
  *
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRepository.d.ts","sourceRoot":"","sources":["../../src/repository/BaseRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,YAAY,EACZ,MAAM,EACN,wBAAwB,EACxB,WAAW,EACX,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,8BAAsB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIlE,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,wBAAwB;IAC/C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAJtC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;gBAG9B,EAAE,EAAE,wBAAwB,EAC5B,SAAS,EAAE,MAAM,EACpC,aAAa,CAAC,EAAE,eAAe;IAKjC;;;;;;;OAOG;IACH,YAAY,IAAI,MAAM;IAItB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,QAAQ,CACZ,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAIpC;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,QAAQ,CACZ,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EACzB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAI9C;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,MAAM,CACV,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EACpB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAI7B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,MAAM,CACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAS7B;;;;;;;;;;;;;;;;;;;OAmBG;IACG,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAIhC;;;;;;;;;;;;;;;;;;;OAmBG;IACG,KAAK,CACT,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAClB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAIlC;;;;;;;;;;;;;;;;;;;OAmBG;IACG,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAanC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,OAAO,CACX,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAIpC;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,UAAU,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;CAGjC"}
1
+ {"version":3,"file":"BaseRepository.d.ts","sourceRoot":"","sources":["../../src/repository/BaseRepository.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@plyaz/db",
3
- "version": "0.4.0",
4
- "description": "Package description",
3
+ "version": "0.5.0",
4
+ "description": "Unified database abstraction layer with CLI for migrations and seeds",
5
5
  "type": "module",
6
6
  "keywords": [],
7
7
  "packageManager": "pnpm@10.11.0",
@@ -42,7 +42,7 @@
42
42
  "@plyaz/errors": "^1.5.0",
43
43
  "@plyaz/logger": "^1.4.1",
44
44
  "@plyaz/testing": "^1.5.1",
45
- "@plyaz/types": "^1.22.9",
45
+ "@plyaz/types": "^1.25.0",
46
46
  "@supabase/supabase-js": "^2.75.0",
47
47
  "commander": "^12.1.0",
48
48
  "drizzle-orm": "^0.44.6",
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Database Configuration
3
+ *
4
+ * Used by the @plyaz/db CLI for migrations and seeds
5
+ *
6
+ * @type {import('@plyaz/db').DatabaseServiceConfig}
7
+ */
8
+ export default {
9
+ // ============================================================================
10
+ // ADAPTER CONFIGURATION
11
+ // ============================================================================
12
+
13
+ adapter: globalThis.process.env.DB_ADAPTER ?? '{{ADAPTER}}',
14
+
15
+ config: {
16
+ connectionString: globalThis.process.env.DATABASE_URL ?? '{{CONNECTION_STRING}}',
17
+ poolSize: 20,
18
+
19
+ // Custom ID columns (optional)
20
+ // tableIdColumns: {
21
+ // 'feature_flags': 'key',
22
+ // },
23
+ },
24
+
25
+ // ============================================================================
26
+ // MIGRATIONS & SEEDS PATHS
27
+ // ============================================================================
28
+
29
+ migrationsPath: '{{MIGRATIONS_PATH}}',
30
+ seedsPath: '{{SEEDS_PATH}}',
31
+ migrationsTable: '{{MIGRATIONS_TABLE}}',
32
+ seedsTable: '{{SEEDS_TABLE}}',
33
+ };