@starbemtech/star-db-query-builder 1.1.0 → 1.3.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 (88) hide show
  1. package/.github/workflows/publish.yml +118 -0
  2. package/ARCHITECTURE.md +313 -0
  3. package/CHANGELOG.md +67 -0
  4. package/README.md +1275 -210
  5. package/coverage/base.css +224 -0
  6. package/coverage/block-navigation.js +87 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +131 -0
  9. package/coverage/lcov-report/base.css +224 -0
  10. package/coverage/lcov-report/block-navigation.js +87 -0
  11. package/coverage/lcov-report/favicon.png +0 -0
  12. package/coverage/lcov-report/index.html +131 -0
  13. package/coverage/lcov-report/mysqlClient.ts.html +685 -0
  14. package/coverage/lcov-report/pgClient.ts.html +823 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +210 -0
  19. package/coverage/lcov.info +533 -0
  20. package/coverage/mysqlClient.ts.html +685 -0
  21. package/coverage/pgClient.ts.html +823 -0
  22. package/coverage/prettify.css +1 -0
  23. package/coverage/prettify.js +2 -0
  24. package/coverage/sort-arrow-sprite.png +0 -0
  25. package/coverage/sorter.js +210 -0
  26. package/dist/index.d.ts +5 -4
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/src/core/repository.d.ts +374 -0
  30. package/dist/src/core/repository.js +677 -0
  31. package/dist/src/core/repository.js.map +1 -0
  32. package/dist/src/{default → core}/types.d.ts +8 -0
  33. package/dist/src/{default → core}/types.js.map +1 -1
  34. package/dist/src/core/utils.d.ts +133 -0
  35. package/dist/src/{default → core}/utils.js +167 -0
  36. package/dist/src/core/utils.js.map +1 -0
  37. package/dist/src/db/IDatabaseClient.d.ts +10 -1
  38. package/dist/src/db/initDb.d.ts +120 -1
  39. package/dist/src/db/initDb.js +119 -0
  40. package/dist/src/db/initDb.js.map +1 -1
  41. package/dist/src/db/mysqlClient.d.ts +23 -1
  42. package/dist/src/db/mysqlClient.js +115 -0
  43. package/dist/src/db/mysqlClient.js.map +1 -1
  44. package/dist/src/db/pgClient.d.ts +22 -1
  45. package/dist/src/db/pgClient.js +127 -0
  46. package/dist/src/db/pgClient.js.map +1 -1
  47. package/dist/src/monitor/monitor.d.ts +6 -1
  48. package/dist/src/monitor/monitor.js +5 -0
  49. package/dist/src/monitor/monitor.js.map +1 -1
  50. package/dist/src/setupTests.d.ts +26 -0
  51. package/dist/src/setupTests.js +43 -0
  52. package/dist/src/setupTests.js.map +1 -0
  53. package/docs/INDEX.md +145 -0
  54. package/docs/methods/findFirst.md +394 -0
  55. package/docs/methods/findMany.md +587 -0
  56. package/docs/methods/insert.md +536 -0
  57. package/docs/methods/insertMany.md +627 -0
  58. package/docs/methods/joins.md +781 -0
  59. package/docs/methods/rawQuery.md +284 -0
  60. package/docs/methods/transactions.md +737 -0
  61. package/eslint.config.mjs +77 -0
  62. package/index.ts +5 -4
  63. package/jest.config.ts +23 -28
  64. package/package.json +53 -30
  65. package/scripts/release.sh +123 -0
  66. package/src/core/repository.ts +865 -0
  67. package/src/{default → core}/types.ts +10 -1
  68. package/src/{default → core}/utils.ts +168 -0
  69. package/src/db/IDatabaseClient.ts +11 -1
  70. package/src/db/__tests__/mysqlClient.test.ts +262 -0
  71. package/src/db/__tests__/pgClient.test.ts +260 -0
  72. package/src/db/initDb.ts +120 -1
  73. package/src/db/mysqlClient.ts +119 -3
  74. package/src/db/pgClient.ts +131 -3
  75. package/src/monitor/monitor.ts +5 -0
  76. package/src/setupTests.ts +45 -0
  77. package/tsconfig.test.json +21 -0
  78. package/.eslintignore +0 -4
  79. package/.eslintrc.json +0 -32
  80. package/dist/.eslintrc.json +0 -32
  81. package/dist/src/default/genericRepository.d.ts +0 -28
  82. package/dist/src/default/genericRepository.js +0 -284
  83. package/dist/src/default/genericRepository.js.map +0 -1
  84. package/dist/src/default/utils.d.ts +0 -9
  85. package/dist/src/default/utils.js.map +0 -1
  86. package/index.d.ts +0 -60
  87. package/src/default/genericRepository.ts +0 -461
  88. /package/dist/src/{default → core}/types.js +0 -0
package/docs/INDEX.md ADDED
@@ -0,0 +1,145 @@
1
+ # Star DB Query Builder - Documentation Index
2
+
3
+ Welcome to the comprehensive documentation for the Star DB Query Builder library. This index provides quick access to all available documentation.
4
+
5
+ ## 📚 Main Documentation
6
+
7
+ - **[README.md](./README.md)** - Complete library overview, installation, and quick start guide
8
+ - **[Raw Query Examples](./raw-query-examples.md)** - Detailed examples for raw SQL queries
9
+
10
+ ## 🔧 Method Documentation
11
+
12
+ ### Query Methods
13
+
14
+ - **[findFirst](./methods/findFirst.md)** - Find a single record with conditions
15
+ - **[findMany](./methods/findMany.md)** - Find multiple records with pagination and filtering
16
+
17
+ ### Insert Methods
18
+
19
+ - **[insert](./methods/insert.md)** - Insert a single record
20
+ - **[insertMany](./methods/insertMany.md)** - Insert multiple records in batch
21
+
22
+ ### Update Methods
23
+
24
+ - **[update](./methods/update.md)** - Update a single record by ID
25
+ - **[updateMany](./methods/updateMany.md)** - Update multiple records with conditions
26
+
27
+ ### Delete Methods
28
+
29
+ - **[deleteOne](./methods/deleteOne.md)** - Delete a single record by ID
30
+ - **[deleteMany](./methods/deleteMany.md)** - Delete multiple records by IDs
31
+
32
+ ### Advanced Methods
33
+
34
+ - **[joins](./methods/joins.md)** - Execute queries with JOIN operations
35
+ - **[rawQuery](./methods/rawQuery.md)** - Execute raw SQL queries
36
+
37
+ ### Database Initialization
38
+
39
+ - **[initDb](./methods/initDb.md)** - Initialize database connections
40
+ - **[getDbClient](./methods/getDbClient.md)** - Retrieve database client instances
41
+
42
+ ## 🏗️ Architecture Documentation
43
+
44
+ ### Core Components
45
+
46
+ - **[Types and Interfaces](./architecture/types.md)** - TypeScript type definitions
47
+ - **[Database Clients](./architecture/database-clients.md)** - PostgreSQL and MySQL client implementations
48
+ - **[Query Builder](./architecture/query-builder.md)** - Internal query building logic
49
+
50
+ ### Utilities
51
+
52
+ - **[Utils](./architecture/utils.md)** - Helper functions for query construction
53
+ - **[Error Handling](./architecture/error-handling.md)** - Error handling patterns and best practices
54
+
55
+ ## 📖 Guides and Tutorials
56
+
57
+ ### Getting Started
58
+
59
+ - **[Installation Guide](./guides/installation.md)** - Step-by-step installation instructions
60
+ - **[First Steps](./guides/first-steps.md)** - Your first database operations
61
+ - **[TypeScript Setup](./guides/typescript-setup.md)** - TypeScript configuration and usage
62
+
63
+ ### Advanced Topics
64
+
65
+ - **[Performance Optimization](./guides/performance.md)** - Tips for optimizing database performance
66
+ - **[Security Best Practices](./guides/security.md)** - Security considerations and best practices
67
+ - **[Testing](./guides/testing.md)** - How to test your database operations
68
+ - **[Migration Guide](./guides/migration.md)** - Migrating from other ORMs
69
+
70
+ ### Database-Specific Guides
71
+
72
+ - **[PostgreSQL Guide](./guides/postgresql.md)** - PostgreSQL-specific features and optimizations
73
+ - **[MySQL Guide](./guides/mysql.md)** - MySQL-specific features and optimizations
74
+
75
+ ## 🎯 Use Cases and Examples
76
+
77
+ ### Common Patterns
78
+
79
+ - **[User Management](./examples/user-management.md)** - Complete user CRUD operations
80
+ - **[E-commerce](./examples/ecommerce.md)** - Product catalog and order management
81
+ - **[Content Management](./examples/cms.md)** - Blog posts and content management
82
+ - **[Analytics](./examples/analytics.md)** - Data aggregation and reporting
83
+
84
+ ### Real-World Scenarios
85
+
86
+ - **[API Development](./examples/api-development.md)** - Building REST APIs with the library
87
+ - **[Data Import/Export](./examples/data-import-export.md)** - Bulk data operations
88
+ - **[Audit Logging](./examples/audit-logging.md)** - Implementing audit trails
89
+ - **[Multi-tenant Applications](./examples/multi-tenant.md)** - Multi-tenant database patterns
90
+
91
+ ## 🔍 Reference
92
+
93
+ ### API Reference
94
+
95
+ - **[Method Signatures](./reference/method-signatures.md)** - Complete method signatures and parameters
96
+ - **[Type Definitions](./reference/type-definitions.md)** - All TypeScript interfaces and types
97
+ - **[Error Codes](./reference/error-codes.md)** - Complete list of error codes and messages
98
+
99
+ ### Database Compatibility
100
+
101
+ - **[PostgreSQL Features](./reference/postgresql-features.md)** - PostgreSQL-specific features
102
+ - **[MySQL Features](./reference/mysql-features.md)** - MySQL-specific features
103
+ - **[SQL Generation](./reference/sql-generation.md)** - Examples of generated SQL queries
104
+
105
+ ## 🚀 Quick Navigation
106
+
107
+ ### By Task
108
+
109
+ - **Need to find data?** → [findFirst](./methods/findFirst.md) | [findMany](./methods/findMany.md)
110
+ - **Need to insert data?** → [insert](./methods/insert.md) | [insertMany](./methods/insertMany.md)
111
+ - **Need to update data?** → [update](./methods/update.md) | [updateMany](./methods/updateMany.md)
112
+ - **Need to delete data?** → [deleteOne](./methods/deleteOne.md) | [deleteMany](./methods/deleteMany.md)
113
+ - **Need complex queries?** → [joins](./methods/joins.md) | [rawQuery](./methods/rawQuery.md)
114
+
115
+ ### By Experience Level
116
+
117
+ - **New to the library?** → [README.md](./README.md) → [First Steps](./guides/first-steps.md)
118
+ - **Familiar with basics?** → [Method Documentation](./methods/) → [Examples](./examples/)
119
+ - **Advanced user?** → [Architecture](./architecture/) → [Performance Guide](./guides/performance.md)
120
+
121
+ ### By Database
122
+
123
+ - **Using PostgreSQL?** → [PostgreSQL Guide](./guides/postgresql.md) → [PostgreSQL Features](./reference/postgresql-features.md)
124
+ - **Using MySQL?** → [MySQL Guide](./guides/mysql.md) → [MySQL Features](./reference/mysql-features.md)
125
+
126
+ ## 📝 Contributing to Documentation
127
+
128
+ If you find any issues with the documentation or want to contribute improvements:
129
+
130
+ 1. Check the [Contributing Guidelines](../CONTRIBUTING.md)
131
+ 2. Follow the [Documentation Style Guide](./style-guide.md)
132
+ 3. Submit a pull request with your changes
133
+
134
+ ## 🆘 Getting Help
135
+
136
+ - **Issues**: Check the [GitHub Issues](https://github.com/starbemtech/star-db-query-builder/issues)
137
+ - **Discussions**: Join the [GitHub Discussions](https://github.com/starbemtech/star-db-query-builder/discussions)
138
+ - **Examples**: Browse the [Examples](./examples/) directory
139
+ - **API Reference**: Check the [Reference](./reference/) section
140
+
141
+ ---
142
+
143
+ **Last Updated**: September 2025
144
+ **Version**: 1.2.0
145
+ **Maintainer**: Starbem Tech Team
@@ -0,0 +1,394 @@
1
+ # findFirst
2
+
3
+ Finds the first record that matches the specified conditions from a database table.
4
+
5
+ ## Signature
6
+
7
+ ```typescript
8
+ findFirst<T>({
9
+ tableName: string,
10
+ dbClient: IDatabaseClient,
11
+ select?: string[],
12
+ where?: Conditions<T>,
13
+ groupBy?: string[],
14
+ orderBy?: OrderBy
15
+ }): Promise<T | null>
16
+ ```
17
+
18
+ ## Parameters
19
+
20
+ | Parameter | Type | Required | Description |
21
+ | ----------- | ----------------- | -------- | ---------------------------------------------------- |
22
+ | `tableName` | `string` | ✅ | Name of the database table |
23
+ | `dbClient` | `IDatabaseClient` | ✅ | Database client instance |
24
+ | `select` | `string[]` | ❌ | Array of field names to select (default: all fields) |
25
+ | `where` | `Conditions<T>` | ❌ | Conditions to filter records |
26
+ | `groupBy` | `string[]` | ❌ | Fields to group by |
27
+ | `orderBy` | `OrderBy` | ❌ | Sort order specification |
28
+
29
+ ## Return Value
30
+
31
+ - **Type**: `Promise<T | null>`
32
+ - **Description**: Returns the first matching record or `null` if no record is found
33
+
34
+ ## Examples
35
+
36
+ ### Basic Usage
37
+
38
+ ```typescript
39
+ import { findFirst } from '@starbemtech/star-db-query-builder'
40
+
41
+ // Find user by email
42
+ const user = await findFirst({
43
+ tableName: 'users',
44
+ dbClient,
45
+ where: {
46
+ email: { operator: '=', value: 'user@example.com' },
47
+ },
48
+ })
49
+
50
+ console.log(user) // { id: 'user-123', name: 'John Doe', email: 'user@example.com', ... }
51
+ ```
52
+
53
+ ### With Specific Fields
54
+
55
+ ```typescript
56
+ // Select only specific fields
57
+ const user = await findFirst({
58
+ tableName: 'users',
59
+ dbClient,
60
+ select: ['id', 'name', 'email'],
61
+ where: {
62
+ status: { operator: '=', value: 'active' },
63
+ },
64
+ })
65
+
66
+ console.log(user) // { id: 'user-123', name: 'John Doe', email: 'user@example.com' }
67
+ ```
68
+
69
+ ### With Complex Conditions
70
+
71
+ ```typescript
72
+ // Multiple conditions with AND
73
+ const user = await findFirst({
74
+ tableName: 'users',
75
+ dbClient,
76
+ where: {
77
+ AND: [
78
+ { email: { operator: '=', value: 'user@example.com' } },
79
+ { status: { operator: '=', value: 'active' } },
80
+ { verified: { operator: '=', value: true } },
81
+ ],
82
+ },
83
+ })
84
+
85
+ // Multiple conditions with OR
86
+ const user = await findFirst({
87
+ tableName: 'users',
88
+ dbClient,
89
+ where: {
90
+ OR: [
91
+ { email: { operator: '=', value: 'user@example.com' } },
92
+ { phone: { operator: '=', value: '+1234567890' } },
93
+ ],
94
+ },
95
+ })
96
+ ```
97
+
98
+ ### With Ordering
99
+
100
+ ```typescript
101
+ // Find the most recent user
102
+ const latestUser = await findFirst({
103
+ tableName: 'users',
104
+ dbClient,
105
+ orderBy: [{ field: 'created_at', direction: 'DESC' }],
106
+ })
107
+
108
+ // Find the oldest active user
109
+ const oldestUser = await findFirst({
110
+ tableName: 'users',
111
+ dbClient,
112
+ where: { status: { operator: '=', value: 'active' } },
113
+ orderBy: [{ field: 'created_at', direction: 'ASC' }],
114
+ })
115
+ ```
116
+
117
+ ### With Grouping
118
+
119
+ ```typescript
120
+ // Find the first user in each status group
121
+ const userByStatus = await findFirst({
122
+ tableName: 'users',
123
+ dbClient,
124
+ select: ['status', 'name', 'created_at'],
125
+ groupBy: ['status'],
126
+ orderBy: [{ field: 'created_at', direction: 'ASC' }],
127
+ })
128
+ ```
129
+
130
+ ### Advanced Conditions
131
+
132
+ ```typescript
133
+ // Using different operators
134
+ const user = await findFirst({
135
+ tableName: 'users',
136
+ dbClient,
137
+ where: {
138
+ age: { operator: '>=', value: 18 },
139
+ name: { operator: 'LIKE', value: '%John%' },
140
+ email: { operator: 'IS NOT NULL', value: null },
141
+ status: { operator: 'IN', value: ['active', 'pending'] },
142
+ },
143
+ })
144
+
145
+ // Using BETWEEN
146
+ const user = await findFirst({
147
+ tableName: 'users',
148
+ dbClient,
149
+ where: {
150
+ created_at: {
151
+ operator: 'BETWEEN',
152
+ value: [new Date('2023-01-01'), new Date('2023-12-31')],
153
+ },
154
+ },
155
+ })
156
+ ```
157
+
158
+ ### TypeScript Usage
159
+
160
+ ```typescript
161
+ interface User {
162
+ id: string
163
+ name: string
164
+ email: string
165
+ age: number
166
+ status: 'active' | 'inactive' | 'pending'
167
+ created_at: Date
168
+ updated_at: Date
169
+ }
170
+
171
+ // Typed usage
172
+ const user: User | null = await findFirst<User>({
173
+ tableName: 'users',
174
+ dbClient,
175
+ where: {
176
+ email: { operator: '=', value: 'user@example.com' },
177
+ },
178
+ })
179
+
180
+ if (user) {
181
+ console.log(`Found user: ${user.name}`)
182
+ } else {
183
+ console.log('User not found')
184
+ }
185
+ ```
186
+
187
+ ### Error Handling
188
+
189
+ ```typescript
190
+ try {
191
+ const user = await findFirst({
192
+ tableName: 'users',
193
+ dbClient,
194
+ where: { email: { operator: '=', value: 'user@example.com' } },
195
+ })
196
+
197
+ if (user) {
198
+ console.log('User found:', user.name)
199
+ } else {
200
+ console.log('No user found with this email')
201
+ }
202
+ } catch (error) {
203
+ console.error('Database error:', error.message)
204
+ // Handle error appropriately
205
+ }
206
+ ```
207
+
208
+ ## Generated SQL Examples
209
+
210
+ ### Simple Query
211
+
212
+ ```sql
213
+ SELECT * FROM users WHERE email = $1 LIMIT 1
214
+ ```
215
+
216
+ ### With Specific Fields
217
+
218
+ ```sql
219
+ SELECT id, name, email FROM users WHERE status = $1 LIMIT 1
220
+ ```
221
+
222
+ ### With Complex Conditions
223
+
224
+ ```sql
225
+ SELECT * FROM users
226
+ WHERE (email = $1 AND status = $2 AND verified = $3)
227
+ LIMIT 1
228
+ ```
229
+
230
+ ### With Ordering
231
+
232
+ ```sql
233
+ SELECT * FROM users
234
+ ORDER BY created_at DESC
235
+ LIMIT 1
236
+ ```
237
+
238
+ ### With Grouping
239
+
240
+ ```sql
241
+ SELECT status, name, created_at
242
+ FROM users
243
+ GROUP BY status
244
+ ORDER BY created_at ASC
245
+ LIMIT 1
246
+ ```
247
+
248
+ ## Best Practices
249
+
250
+ ### 1. Use Specific Field Selection
251
+
252
+ ```typescript
253
+ // Good: Select only needed fields
254
+ const user = await findFirst({
255
+ tableName: 'users',
256
+ dbClient,
257
+ select: ['id', 'name', 'email'],
258
+ where: { id: { operator: '=', value: 'user-123' } },
259
+ })
260
+
261
+ // Avoid: Selecting all fields when not needed
262
+ const user = await findFirst({
263
+ tableName: 'users',
264
+ dbClient,
265
+ where: { id: { operator: '=', value: 'user-123' } },
266
+ })
267
+ ```
268
+
269
+ ### 2. Use Appropriate Indexes
270
+
271
+ Ensure your database has indexes on fields used in WHERE clauses for better performance:
272
+
273
+ ```sql
274
+ -- Example indexes for common queries
275
+ CREATE INDEX idx_users_email ON users(email);
276
+ CREATE INDEX idx_users_status ON users(status);
277
+ CREATE INDEX idx_users_created_at ON users(created_at);
278
+ ```
279
+
280
+ ### 3. Handle Null Results
281
+
282
+ ```typescript
283
+ const user = await findFirst({
284
+ tableName: 'users',
285
+ dbClient,
286
+ where: { email: { operator: '=', value: 'nonexistent@example.com' } },
287
+ })
288
+
289
+ if (!user) {
290
+ // Handle case when no user is found
291
+ throw new Error('User not found')
292
+ }
293
+ ```
294
+
295
+ ### 4. Use TypeScript for Type Safety
296
+
297
+ ```typescript
298
+ interface UserSearchParams {
299
+ email?: string
300
+ status?: string
301
+ age?: number
302
+ }
303
+
304
+ const findUserByParams = async (
305
+ params: UserSearchParams
306
+ ): Promise<User | null> => {
307
+ const where: Conditions<User> = {}
308
+
309
+ if (params.email) {
310
+ where.email = { operator: '=', value: params.email }
311
+ }
312
+
313
+ if (params.status) {
314
+ where.status = { operator: '=', value: params.status }
315
+ }
316
+
317
+ if (params.age) {
318
+ where.age = { operator: '>=', value: params.age }
319
+ }
320
+
321
+ return findFirst<User>({
322
+ tableName: 'users',
323
+ dbClient,
324
+ where,
325
+ })
326
+ }
327
+ ```
328
+
329
+ ## Common Use Cases
330
+
331
+ ### 1. User Authentication
332
+
333
+ ```typescript
334
+ const authenticateUser = async (email: string, password: string) => {
335
+ const user = await findFirst({
336
+ tableName: 'users',
337
+ dbClient,
338
+ where: {
339
+ AND: [
340
+ { email: { operator: '=', value: email } },
341
+ { password: { operator: '=', value: password } },
342
+ { status: { operator: '=', value: 'active' } },
343
+ ],
344
+ },
345
+ })
346
+
347
+ return user
348
+ }
349
+ ```
350
+
351
+ ### 2. Finding Latest Record
352
+
353
+ ```typescript
354
+ const getLatestOrder = async (userId: string) => {
355
+ const order = await findFirst({
356
+ tableName: 'orders',
357
+ dbClient,
358
+ where: { user_id: { operator: '=', value: userId } },
359
+ orderBy: [{ field: 'created_at', direction: 'DESC' }],
360
+ })
361
+
362
+ return order
363
+ }
364
+ ```
365
+
366
+ ### 3. Checking Existence
367
+
368
+ ```typescript
369
+ const userExists = async (email: string): Promise<boolean> => {
370
+ const user = await findFirst({
371
+ tableName: 'users',
372
+ dbClient,
373
+ select: ['id'],
374
+ where: { email: { operator: '=', value: email } },
375
+ })
376
+
377
+ return user !== null
378
+ }
379
+ ```
380
+
381
+ ## Performance Considerations
382
+
383
+ - **Indexes**: Ensure proper indexes exist on fields used in WHERE clauses
384
+ - **Field Selection**: Use `select` to limit returned fields when possible
385
+ - **Limit Results**: `findFirst` automatically limits to 1 result, which is optimal
386
+ - **Connection Pooling**: Use connection pooling for better performance in high-traffic applications
387
+
388
+ ## Error Messages
389
+
390
+ Common error messages you might encounter:
391
+
392
+ - `Table name is required` - The `tableName` parameter is missing
393
+ - `DB client is required` - The `dbClient` parameter is missing
394
+ - Database-specific errors from the underlying database driver