@starbemtech/star-db-query-builder 1.0.38 → 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 (85) 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 +1309 -129
  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/block-navigation.js +1 -1
  10. package/coverage/lcov-report/index.html +41 -11
  11. package/coverage/lcov-report/mysqlClient.ts.html +685 -0
  12. package/coverage/lcov-report/pgClient.ts.html +823 -0
  13. package/coverage/lcov-report/sorter.js +21 -7
  14. package/coverage/lcov.info +533 -0
  15. package/coverage/mysqlClient.ts.html +685 -0
  16. package/coverage/pgClient.ts.html +823 -0
  17. package/coverage/prettify.css +1 -0
  18. package/coverage/prettify.js +2 -0
  19. package/coverage/sort-arrow-sprite.png +0 -0
  20. package/coverage/sorter.js +210 -0
  21. package/dist/index.d.ts +5 -4
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/src/core/repository.d.ts +374 -0
  25. package/dist/src/core/repository.js +677 -0
  26. package/dist/src/core/repository.js.map +1 -0
  27. package/dist/src/{default → core}/types.d.ts +8 -0
  28. package/dist/src/{default → core}/types.js.map +1 -1
  29. package/dist/src/core/utils.d.ts +133 -0
  30. package/dist/src/{default → core}/utils.js +167 -0
  31. package/dist/src/core/utils.js.map +1 -0
  32. package/dist/src/db/IDatabaseClient.d.ts +10 -1
  33. package/dist/src/db/initDb.d.ts +120 -1
  34. package/dist/src/db/initDb.js +119 -0
  35. package/dist/src/db/initDb.js.map +1 -1
  36. package/dist/src/db/mysqlClient.d.ts +23 -1
  37. package/dist/src/db/mysqlClient.js +115 -0
  38. package/dist/src/db/mysqlClient.js.map +1 -1
  39. package/dist/src/db/pgClient.d.ts +22 -1
  40. package/dist/src/db/pgClient.js +127 -0
  41. package/dist/src/db/pgClient.js.map +1 -1
  42. package/dist/src/monitor/monitor.d.ts +6 -1
  43. package/dist/src/monitor/monitor.js +5 -0
  44. package/dist/src/monitor/monitor.js.map +1 -1
  45. package/dist/src/setupTests.d.ts +26 -0
  46. package/dist/src/setupTests.js +43 -0
  47. package/dist/src/setupTests.js.map +1 -0
  48. package/docs/INDEX.md +145 -0
  49. package/docs/methods/findFirst.md +394 -0
  50. package/docs/methods/findMany.md +587 -0
  51. package/docs/methods/insert.md +536 -0
  52. package/docs/methods/insertMany.md +627 -0
  53. package/docs/methods/joins.md +781 -0
  54. package/docs/methods/rawQuery.md +284 -0
  55. package/docs/methods/transactions.md +737 -0
  56. package/eslint.config.mjs +77 -0
  57. package/index.ts +5 -4
  58. package/jest.config.ts +23 -28
  59. package/package.json +53 -30
  60. package/scripts/release.sh +123 -0
  61. package/src/core/repository.ts +865 -0
  62. package/src/{default → core}/types.ts +10 -1
  63. package/src/{default → core}/utils.ts +168 -0
  64. package/src/db/IDatabaseClient.ts +11 -1
  65. package/src/db/__tests__/mysqlClient.test.ts +262 -0
  66. package/src/db/__tests__/pgClient.test.ts +260 -0
  67. package/src/db/initDb.ts +120 -1
  68. package/src/db/mysqlClient.ts +119 -3
  69. package/src/db/pgClient.ts +131 -3
  70. package/src/monitor/monitor.ts +5 -0
  71. package/src/setupTests.ts +45 -0
  72. package/tsconfig.test.json +21 -0
  73. package/.eslintignore +0 -4
  74. package/.eslintrc.json +0 -32
  75. package/coverage/clover.xml +0 -6
  76. package/coverage/coverage-final.json +0 -1
  77. package/dist/.eslintrc.json +0 -32
  78. package/dist/src/default/genericRepository.d.ts +0 -20
  79. package/dist/src/default/genericRepository.js +0 -192
  80. package/dist/src/default/genericRepository.js.map +0 -1
  81. package/dist/src/default/utils.d.ts +0 -9
  82. package/dist/src/default/utils.js.map +0 -1
  83. package/index.d.ts +0 -60
  84. package/src/default/genericRepository.ts +0 -320
  85. /package/dist/src/{default → core}/types.js +0 -0
@@ -1,320 +0,0 @@
1
- import { v4 as uuid } from 'uuid'
2
- import { QueryParams, QueryBuilder } from './types'
3
- import {
4
- createGroupByClause,
5
- createLimitClause,
6
- createOrderByClause,
7
- generatePlaceholders,
8
- createSelectFields,
9
- createWhereClause,
10
- generateSetClause,
11
- createOffsetClause,
12
- } from './utils'
13
-
14
- export const findFirst = async <T>({
15
- tableName,
16
- dbClient,
17
- select,
18
- where,
19
- groupBy,
20
- orderBy,
21
- }: QueryParams<T>): Promise<T | null> => {
22
- if (!tableName) throw new Error('Table name is required')
23
- if (!dbClient) throw new Error('DB client is required')
24
-
25
- const fields = createSelectFields(select, dbClient.clientType)
26
- const [whereClause, params] = createWhereClause<T>(
27
- where,
28
- 1,
29
- dbClient.clientType
30
- )
31
-
32
- const orderByClause = createOrderByClause(orderBy)
33
- const groupByClause = createGroupByClause(groupBy)
34
-
35
- const rows = await dbClient.query<T[]>(
36
- `SELECT ${fields} FROM ${tableName}
37
- ${whereClause.length > 7 ? whereClause : ''}
38
- ${groupByClause}
39
- ${orderByClause}
40
- `,
41
- params
42
- )
43
-
44
- return rows[0] || null
45
- }
46
-
47
- export const findMany = async <T>({
48
- tableName,
49
- dbClient,
50
- select,
51
- where,
52
- groupBy,
53
- orderBy,
54
- limit,
55
- offset,
56
- unaccent,
57
- }: QueryParams<T>): Promise<T[]> => {
58
- if (!tableName) throw new Error('Table name is required')
59
- if (!dbClient) throw new Error('DB client is required')
60
-
61
- const fields = createSelectFields(select, dbClient.clientType)
62
- const [whereClause, params] = createWhereClause(
63
- where,
64
- 1,
65
- dbClient.clientType,
66
- unaccent
67
- )
68
-
69
- const orderByClause = createOrderByClause(orderBy)
70
- const groupByClause = createGroupByClause(groupBy)
71
- const limitClause = createLimitClause(limit)
72
- const offsetClause = createOffsetClause(offset)
73
-
74
- const rows = await dbClient.query<T[]>(
75
- `SELECT ${fields} FROM ${tableName}
76
- ${whereClause.length > 7 ? whereClause : ''}
77
- ${groupByClause}
78
- ${orderByClause}
79
- ${limitClause}
80
- ${offsetClause}
81
- `,
82
- params
83
- )
84
-
85
- return rows || []
86
- }
87
-
88
- export const insert = async <P, R>({
89
- tableName,
90
- dbClient,
91
- data,
92
- returning,
93
- }: QueryParams<R> & { data: P; returning?: string[] }): Promise<R> => {
94
- if (!tableName) throw new Error('Table name is required')
95
- if (!dbClient) throw new Error('DB client is required')
96
- if (!data) throw new Error('Data object is required')
97
-
98
- const keys =
99
- dbClient.clientType === 'pg'
100
- ? Object.keys(data).map((key) =>
101
- key === 'authorization' ? `"${key}"` : key
102
- )
103
- : Object.keys(data)
104
- const values = Object.values(data)
105
-
106
- keys.unshift('id')
107
- const generatedUUID: string = uuid()
108
- values.unshift(generatedUUID)
109
-
110
- keys.push('updated_at')
111
- values.push(new Date())
112
-
113
- const placeholders = generatePlaceholders(keys, dbClient.clientType)
114
- let query = `INSERT INTO ${tableName} (${keys.join(
115
- ', '
116
- )}) VALUES (${placeholders})`
117
-
118
- if (dbClient.clientType === 'pg') {
119
- if (returning && returning.length > 0) {
120
- query += ` RETURNING ${createSelectFields(
121
- returning,
122
- dbClient.clientType
123
- )}`
124
- }
125
- }
126
-
127
- const inserted = await dbClient.query<R[]>(query, values)
128
-
129
- if (dbClient.clientType === 'mysql') {
130
- const rows = await dbClient.query<R[]>(
131
- `SELECT ${
132
- returning && returning.length > 0
133
- ? createSelectFields(returning, dbClient.clientType)
134
- : '*'
135
- } FROM ${tableName}
136
- WHERE
137
- id = ?
138
- `,
139
- [generatedUUID]
140
- )
141
-
142
- return rows[0]
143
- }
144
-
145
- return inserted[0]
146
- }
147
-
148
- export const update = async <P, R>({
149
- tableName,
150
- dbClient,
151
- id,
152
- data,
153
- returning,
154
- }: QueryParams<R> & { data: P; returning?: string[] }): Promise<R | void> => {
155
- if (!tableName) throw new Error('Table name is required')
156
- if (!dbClient) throw new Error('DB client is required')
157
- if (!id) throw new Error('ID is required')
158
- if (!data) throw new Error('Data object is required')
159
-
160
- const keys = Object.keys(data)
161
- const values: any[] = Object.values(data)
162
-
163
- const setClause = generateSetClause(keys, dbClient.clientType)
164
- let query = `UPDATE ${tableName} SET ${setClause} WHERE id = '${id}'`
165
-
166
- if (dbClient.clientType === 'pg') {
167
- if (returning && returning.length > 0) {
168
- query += ` RETURNING ${createSelectFields(returning, dbClient.clientType)}`
169
- }
170
- }
171
-
172
- const updated = await dbClient.query<R[]>(query, values)
173
-
174
- if (dbClient.clientType === 'mysql') {
175
- const rows = await dbClient.query<R[]>(
176
- `SELECT ${
177
- returning && returning.length > 0
178
- ? createSelectFields(returning, dbClient.clientType)
179
- : '*'
180
- } FROM ${tableName}
181
- WHERE
182
- id = ?
183
- `,
184
- [id]
185
- )
186
-
187
- return rows[0]
188
- }
189
-
190
- return updated[0]
191
- }
192
-
193
- export const deleteOne = async <T>({
194
- tableName,
195
- dbClient,
196
- id,
197
- permanently = false,
198
- }: QueryParams<T> & { permanently?: boolean }): Promise<void> => {
199
- if (!tableName) throw new Error('Table name is required')
200
- if (!dbClient) throw new Error('DB client is required')
201
- if (!id) throw new Error('ID is required')
202
-
203
- await dbClient.query(
204
- permanently
205
- ? `DELETE FROM ${tableName} WHERE id = ${
206
- dbClient.clientType === 'pg' ? '$1' : '?'
207
- }`
208
- : `UPDATE ${tableName} SET status = 'deleted' WHERE id = ${
209
- dbClient.clientType === 'pg' ? '$1' : '?'
210
- }`,
211
- [id]
212
- )
213
- }
214
-
215
- export const deleteMany = async <T>({
216
- tableName,
217
- dbClient,
218
- ids,
219
- field = 'id',
220
- permanently = false,
221
- }: QueryParams<T> & {
222
- ids: string[] | number[]
223
- field?: string
224
- permanently?: boolean
225
- }): Promise<void> => {
226
- if (!tableName) throw new Error('Table name is required')
227
- if (!dbClient) throw new Error('DB client is required')
228
- if (!ids || ids.length === 0)
229
- throw new Error('IDs are required and cannot be empty')
230
- if (!field) throw new Error('Field is required')
231
-
232
- const placeholders =
233
- dbClient.clientType === 'pg'
234
- ? ids.map((_, index) => `$${index + 1}`).join(', ')
235
- : ids.map(() => '?').join(', ')
236
-
237
- const query = permanently
238
- ? `DELETE FROM ${tableName} WHERE ${field} IN (${placeholders})`
239
- : `UPDATE ${tableName} SET status = 'deleted' WHERE ${field} IN (${placeholders})`
240
-
241
- await dbClient.query(query, ids)
242
- }
243
-
244
- export const joins = async <T>({
245
- tableName,
246
- dbClient,
247
- select,
248
- joins,
249
- where,
250
- groupBy,
251
- orderBy,
252
- limit,
253
- offset,
254
- unaccent,
255
- }: QueryParams<T>): Promise<T[]> => {
256
- if (!tableName) throw new Error('Table name is required')
257
- if (!dbClient) throw new Error('DB client is required')
258
-
259
- const fields = Array.isArray(select) ? select : []
260
- const selectFields = createSelectFields(fields, dbClient.clientType)
261
- const [whereClause, params] = createWhereClause(
262
- where,
263
- 1,
264
- dbClient.clientType,
265
- unaccent
266
- )
267
- const groupByClause = createGroupByClause(groupBy)
268
- const orderByClause = createOrderByClause(orderBy)
269
- const limitClause = createLimitClause(limit)
270
- const offsetClause = createOffsetClause(offset)
271
-
272
- const queryBuilder: QueryBuilder = {
273
- select: [selectFields],
274
- from: tableName,
275
- joins: joins,
276
- where: whereClause,
277
- groupBy: [groupByClause],
278
- orderBy: orderByClause,
279
- limit: limitClause,
280
- offset: offsetClause,
281
- }
282
-
283
- const queryString = await buildQuery(queryBuilder)
284
-
285
- const rows = await dbClient.query<T[]>(queryString, params)
286
-
287
- return rows
288
- }
289
-
290
- async function buildQuery(params: QueryBuilder): Promise<string> {
291
- let queryString = `SELECT ${params.select.join(', ')} FROM ${params.from}`
292
-
293
- if (params.joins) {
294
- for (const join of params.joins) {
295
- queryString += ` ${join.type} JOIN ${join.table} ON ${join.on}`
296
- }
297
- }
298
-
299
- if (params.where) {
300
- queryString += `${params.where}`
301
- }
302
-
303
- if (params.groupBy) {
304
- queryString += `${params.groupBy}`
305
- }
306
-
307
- if (params.orderBy) {
308
- queryString += `${params.orderBy}`
309
- }
310
-
311
- if (params.limit) {
312
- queryString += `${params.limit}`
313
- }
314
-
315
- if (params.offset) {
316
- queryString += `${params.offset}`
317
- }
318
-
319
- return queryString
320
- }
File without changes