@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.
- package/dist/builder/query/QueryBuilder.d.ts +850 -0
- package/dist/builder/query/QueryBuilder.d.ts.map +1 -0
- package/dist/builder/query/index.d.ts +2 -1
- package/dist/builder/query/index.d.ts.map +1 -1
- package/dist/cli/index.js +202 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +1291 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1291 -7
- package/dist/index.mjs.map +1 -1
- package/dist/repository/BaseRepository.d.ts +72 -6
- package/dist/repository/BaseRepository.d.ts.map +1 -1
- package/package.json +3 -3
- package/template/config/db.config.mjs.template +33 -0
|
@@ -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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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;
|
|
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
|
-
"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.
|
|
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
|
+
};
|