@starbemtech/star-db-query-builder 1.3.0 → 1.4.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 (75) hide show
  1. package/.claude/skills/star-db-query-builder/SKILL.md +104 -0
  2. package/CHANGELOG.md +81 -46
  3. package/LICENSE +21 -0
  4. package/README.md +194 -94
  5. package/bin/install-skill.js +53 -0
  6. package/dist/src/core/repository.d.ts +92 -9
  7. package/dist/src/core/repository.js +275 -27
  8. package/dist/src/core/repository.js.map +1 -1
  9. package/dist/src/core/types.d.ts +17 -2
  10. package/dist/src/core/utils.d.ts +102 -0
  11. package/dist/src/core/utils.js +287 -70
  12. package/dist/src/core/utils.js.map +1 -1
  13. package/dist/src/db/initDb.d.ts +60 -50
  14. package/dist/src/db/initDb.js +96 -64
  15. package/dist/src/db/initDb.js.map +1 -1
  16. package/dist/src/db/mysqlClient.d.ts +3 -8
  17. package/dist/src/db/mysqlClient.js +9 -11
  18. package/dist/src/db/mysqlClient.js.map +1 -1
  19. package/dist/src/db/pgClient.js +0 -2
  20. package/dist/src/db/pgClient.js.map +1 -1
  21. package/dist/src/monitor/monitor.js +7 -0
  22. package/dist/src/monitor/monitor.js.map +1 -1
  23. package/package.json +28 -20
  24. package/.github/workflows/publish.yml +0 -118
  25. package/.prettierignore +0 -3
  26. package/.prettierrc +0 -5
  27. package/ARCHITECTURE.md +0 -313
  28. package/coverage/base.css +0 -224
  29. package/coverage/block-navigation.js +0 -87
  30. package/coverage/favicon.png +0 -0
  31. package/coverage/index.html +0 -131
  32. package/coverage/lcov-report/base.css +0 -224
  33. package/coverage/lcov-report/block-navigation.js +0 -87
  34. package/coverage/lcov-report/favicon.png +0 -0
  35. package/coverage/lcov-report/index.html +0 -131
  36. package/coverage/lcov-report/mysqlClient.ts.html +0 -685
  37. package/coverage/lcov-report/pgClient.ts.html +0 -823
  38. package/coverage/lcov-report/prettify.css +0 -1
  39. package/coverage/lcov-report/prettify.js +0 -2
  40. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  41. package/coverage/lcov-report/sorter.js +0 -210
  42. package/coverage/lcov.info +0 -533
  43. package/coverage/mysqlClient.ts.html +0 -685
  44. package/coverage/pgClient.ts.html +0 -823
  45. package/coverage/prettify.css +0 -1
  46. package/coverage/prettify.js +0 -2
  47. package/coverage/sort-arrow-sprite.png +0 -0
  48. package/coverage/sorter.js +0 -210
  49. package/dist/src/setupTests.d.ts +0 -26
  50. package/dist/src/setupTests.js +0 -43
  51. package/dist/src/setupTests.js.map +0 -1
  52. package/docs/INDEX.md +0 -145
  53. package/docs/methods/findFirst.md +0 -394
  54. package/docs/methods/findMany.md +0 -587
  55. package/docs/methods/insert.md +0 -536
  56. package/docs/methods/insertMany.md +0 -627
  57. package/docs/methods/joins.md +0 -781
  58. package/docs/methods/rawQuery.md +0 -284
  59. package/docs/methods/transactions.md +0 -737
  60. package/eslint.config.mjs +0 -77
  61. package/index.ts +0 -16
  62. package/jest.config.ts +0 -194
  63. package/scripts/release.sh +0 -123
  64. package/src/core/repository.ts +0 -865
  65. package/src/core/types.ts +0 -97
  66. package/src/core/utils.ts +0 -357
  67. package/src/db/IDatabaseClient.ts +0 -16
  68. package/src/db/__tests__/mysqlClient.test.ts +0 -262
  69. package/src/db/__tests__/pgClient.test.ts +0 -260
  70. package/src/db/initDb.ts +0 -181
  71. package/src/db/mysqlClient.ts +0 -200
  72. package/src/db/pgClient.ts +0 -246
  73. package/src/monitor/monitor.ts +0 -16
  74. package/src/setupTests.ts +0 -45
  75. package/tsconfig.test.json +0 -21
package/src/core/types.ts DELETED
@@ -1,97 +0,0 @@
1
- import { IDatabaseClient } from '../db/IDatabaseClient'
2
-
3
- export interface RetryOptions {
4
- retries?: number
5
- factor?: number
6
- minTimeout?: number
7
- maxTimeout?: number
8
- randomize?: boolean
9
- }
10
-
11
- export interface QueryExec {
12
- text: string
13
- values?: any[]
14
- }
15
-
16
- type SimpleValue = string | number | boolean | Date
17
-
18
- export interface OperatorCondition {
19
- operator:
20
- | 'ILIKE'
21
- | 'LIKE'
22
- | '='
23
- | '>'
24
- | '<'
25
- | 'IN'
26
- | 'BETWEEN'
27
- | '!='
28
- | '<='
29
- | '>='
30
- | 'NOT IN'
31
- | 'LIKE'
32
- | 'NOT LIKE'
33
- | 'IS NULL'
34
- | 'IS NOT NULL'
35
- | 'NOT EXISTS'
36
- value: SimpleValue | SimpleValue[]
37
- }
38
-
39
- export type LogicalOperator = 'OR' | 'AND'
40
-
41
- export type Condition<T> = OperatorCondition | LogicalCondition<T>
42
-
43
- interface LogicalCondition<T> {
44
- OR?: Conditions<T>[]
45
- AND?: Conditions<T>[]
46
- JOINS?: Conditions<object>
47
- notExists?: OperatorCondition
48
- }
49
-
50
- export type Conditions<T> = {
51
- [P in keyof T]?: Condition<T[P]>
52
- } & LogicalCondition<T>
53
-
54
- export type DBClients = 'pg' | 'mysql'
55
-
56
- export type OrderBy = { field: string; direction: 'ASC' | 'DESC' }[]
57
-
58
- export interface QueryParams<T> {
59
- tableName: string
60
- dbClient: IDatabaseClient
61
- id?: string
62
- select?: string[]
63
- where?: Conditions<T>
64
- orderBy?: OrderBy
65
- groupBy?: string[]
66
- limit?: number
67
- offset?: number
68
- joins?: JoinClause[]
69
- unaccent?: boolean
70
- }
71
-
72
- interface JoinClause {
73
- type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL'
74
- table: string
75
- on: string
76
- }
77
-
78
- export interface QueryBuilder {
79
- select: string[]
80
- from?: string
81
- joins?: JoinClause[]
82
- where?: string
83
- groupBy?: string[]
84
- orderBy?: string
85
- limit?: string
86
- offset?: string
87
- }
88
-
89
- export interface RawQueryParams {
90
- dbClient: IDatabaseClient
91
- sql: string
92
- params?: any[]
93
- }
94
-
95
- export interface TransactionParams {
96
- dbClient: IDatabaseClient
97
- }
package/src/core/utils.ts DELETED
@@ -1,357 +0,0 @@
1
- import { Conditions, Condition, OrderBy, DBClients } from './types'
2
-
3
- /**
4
- * Converts an array of strings to a comma-separated string with quotes
5
- *
6
- * This function takes an array of strings and converts it to a comma-separated string
7
- * with quotes. It handles the differences between PostgreSQL and MySQL syntax for
8
- * string arrays.
9
- *
10
- * @param items - The array of strings to convert
11
- * @param clientType - The type of database client
12
- * @returns A comma-separated string with quotes
13
- *
14
- * @example
15
- * const items = ['item1', 'item2', 'item3']
16
- * const clientType = 'pg'
17
- * const result = arrayToStringWithQuotes(items, clientType)
18
- * // result will be: 'item1', 'item2', 'item3'
19
- */
20
- const arrayToStringWithQuotes = (
21
- items: string[],
22
- clientType: DBClients
23
- ): string => {
24
- const itemsWithQuotes = items.map((item) =>
25
- clientType === 'pg' ? `${item}` : `${item}`
26
- )
27
- return itemsWithQuotes.join(', ')
28
- }
29
-
30
- /**
31
- * Generates a PostgreSQL placeholder for a parameter
32
- *
33
- * This function generates a PostgreSQL placeholder for a parameter. It returns
34
- * a string with a dollar sign and the index of the parameter.
35
- *
36
- * @param index - The index of the parameter
37
- * @returns A PostgreSQL placeholder
38
- *
39
- * @example
40
- * const index = 1
41
- * const placeholder = pgPlaceholderGenerator(index)
42
- * // placeholder will be: $1
43
- */
44
- const pgPlaceholderGenerator = (index: number) => `$${index}`
45
-
46
- /**
47
- * Generates a MySQL placeholder for a parameter
48
- *
49
- * This function generates a MySQL placeholder for a parameter. It returns
50
- * a string with a question mark.
51
- *
52
- * @returns A MySQL placeholder
53
- *
54
- * @example
55
- * const placeholder = mysqlPlaceholderGenerator()
56
- * // placeholder will be: ?
57
- */
58
- const mysqlPlaceholderGenerator = () => `?`
59
-
60
- /**
61
- * Creates a SELECT clause for a query
62
- *
63
- * This function creates a SELECT clause for a query. It takes an array of fields
64
- * and a database client type and returns a string with the fields separated by commas.
65
- *
66
- * @param fields - The array of fields to select
67
- * @param clientType - The type of database client
68
- * @returns A string with the fields separated by commas
69
- *
70
- * @example
71
- * const fields = ['id', 'name', 'email']
72
- * const clientType = 'pg'
73
- * const result = createSelectFields(fields, clientType)
74
- * // result will be: "id, name, email"
75
- */
76
- export const createSelectFields = (
77
- fields: string[] = [],
78
- clientType: DBClients
79
- ): string => {
80
- return fields && fields.length > 0
81
- ? arrayToStringWithQuotes(fields, clientType)
82
- : '*'
83
- }
84
-
85
- /**
86
- * Generates placeholders for a query
87
- *
88
- * This function generates placeholders for a query. It takes an array of keys
89
- * and a database client type and returns a string with the placeholders separated by commas.
90
- *
91
- * @param keys - The array of keys to generate placeholders for
92
- * @param clientType - The type of database client
93
- * @returns A string with the placeholders separated by commas
94
- *
95
- * @example
96
- * const keys = ['id', 'name', 'email']
97
- * const clientType = 'pg'
98
- * const result = generatePlaceholders(keys, clientType)
99
- * // result will be: $1, $2, $3
100
- */
101
- export const generatePlaceholders = (
102
- keys: any[],
103
- clientType: DBClients
104
- ): string => {
105
- return keys
106
- .map((_, index) => (clientType === 'pg' ? `$${index + 1}` : '?'))
107
- .join(', ')
108
- }
109
-
110
- /**
111
- * Generates a SET clause for a query
112
- *
113
- * This function generates a SET clause for a query. It takes an array of keys
114
- * and a database client type and returns a string with the keys and placeholders separated by commas.
115
- *
116
- * @param keys - The array of keys to generate SET clause for
117
- * @param clientType - The type of database client
118
- * @returns A string with the keys and placeholders separated by commas
119
- *
120
- * @example
121
- * const keys = ['id', 'name', 'email']
122
- * const clientType = 'pg'
123
- * const result = generateSetClause(keys, clientType)
124
- * // result will be: "id = $1, name = $2, email = $3"
125
- */
126
- export const generateSetClause = (
127
- keys: any[],
128
- clientType: DBClients
129
- ): string => {
130
- return keys
131
- .map((key, index) =>
132
- clientType === 'pg' ? `${key} = $${index + 1}` : `${key} = ?`
133
- )
134
- .join(', ')
135
- }
136
-
137
- /**
138
- * Creates a WHERE clause for a query
139
- *
140
- * This function creates a WHERE clause for a query. It takes an array of conditions
141
- * and a database client type and returns a string with the conditions separated by AND.
142
- *
143
- * @param conditions - The array of conditions to create WHERE clause for
144
- * @param startIndex - The index of the first parameter
145
- * @param clientType - The type of database client
146
- * @param unaccent - Whether to use unaccent function
147
- * @returns A string with the conditions separated by AND
148
- *
149
- * @example
150
- * const conditions = [{ field: 'name', operator: '=', value: 'John Doe' }]
151
- * const startIndex = 1
152
- * const clientType = 'pg'
153
- * const unaccent = true
154
- * const result = createWhereClause(conditions, startIndex, clientType, unaccent)
155
- * // result will be: "name = $1"
156
- */
157
- export const createWhereClause = <T>(
158
- conditions: Conditions<T> = {},
159
- startIndex = 1,
160
- clientType: DBClients,
161
- unaccent?: boolean
162
- ): [string, any[], number] => {
163
- let index = startIndex
164
- const whereParts: string[] = []
165
- const values: any[] = []
166
-
167
- const processCondition = (key: string, condition: Condition<T>) => {
168
- if (typeof condition === 'object' && condition !== null) {
169
- if ('operator' in condition && 'value' in condition) {
170
- const { operator, value } = condition
171
-
172
- if (operator === 'NOT EXISTS' && typeof value === 'string') {
173
- whereParts.push(`NOT EXISTS (${value})`)
174
- } else if (operator.includes('NULL')) {
175
- whereParts.push(`${key} ${operator}`)
176
- } else if (Array.isArray(value)) {
177
- const placeholders = value
178
- .map(() =>
179
- clientType === 'pg'
180
- ? pgPlaceholderGenerator(index++)
181
- : mysqlPlaceholderGenerator()
182
- )
183
- .join(', ')
184
-
185
- if (operator === 'BETWEEN') {
186
- whereParts.push(
187
- `${key} ${operator} ${placeholders.replace(', ', ' AND ')}`
188
- )
189
- } else if (operator === 'IN') {
190
- whereParts.push(`${key} ${operator} (${placeholders})`)
191
- } else {
192
- whereParts.push(`${key} ${operator} (${placeholders})`)
193
- }
194
- values.push(...value)
195
- } else {
196
- if (unaccent && clientType === 'pg') {
197
- if (operator.toUpperCase() === 'ILIKE') {
198
- whereParts.push(
199
- `unaccent(${key}::text) ILIKE unaccent(${pgPlaceholderGenerator(index)})`
200
- )
201
- } else {
202
- whereParts.push(
203
- `unaccent(${key}::text) ${operator} unaccent(${pgPlaceholderGenerator(index)})`
204
- )
205
- }
206
- } else {
207
- whereParts.push(
208
- clientType === 'pg'
209
- ? `${key} ${operator} ${pgPlaceholderGenerator(index)}`
210
- : `${key} ${operator} ${mysqlPlaceholderGenerator()}`
211
- )
212
- }
213
- index++
214
- values.push(value)
215
- }
216
- }
217
- }
218
- }
219
-
220
- if ('JOINS' in conditions) {
221
- const logicalOperator = conditions.JOINS ? 'AND' : 'OR'
222
- const compositeConditions = conditions.JOINS
223
-
224
- if (Array.isArray(compositeConditions)) {
225
- const subWhereParts = compositeConditions
226
- .map((subCondition: any) => {
227
- if (
228
- typeof subCondition === 'object' &&
229
- !Array.isArray(subCondition) &&
230
- subCondition !== null
231
- ) {
232
- const key = Object.keys(subCondition)[0]
233
- const condition = subCondition[key]
234
-
235
- // Adiciona o tratamento de unaccent nas condições de JOINS
236
- processCondition(key, condition)
237
- return whereParts.pop()
238
- }
239
- return ''
240
- })
241
- .filter((part) => part)
242
-
243
- whereParts.push(`(${subWhereParts.join(` ${logicalOperator} `)})`)
244
- }
245
- } else {
246
- Object.entries(conditions).forEach(([key, value]) =>
247
- processCondition(key, value as Condition<T>)
248
- )
249
- }
250
-
251
- if ('OR' in conditions || 'AND' in conditions) {
252
- const logicalOperator = conditions.OR ? 'OR' : 'AND'
253
- const compositeConditions = conditions.OR || conditions.AND
254
-
255
- if (Array.isArray(compositeConditions)) {
256
- const subWhereParts = compositeConditions
257
- .map((subCondition: any) => {
258
- if (
259
- typeof subCondition === 'object' &&
260
- !Array.isArray(subCondition) &&
261
- subCondition !== null
262
- ) {
263
- const key = Object.keys(subCondition)[0]
264
- const condition = subCondition[key]
265
- processCondition(key, condition) // Certifica que o unaccent é processado aqui também
266
- return whereParts.pop()
267
- }
268
-
269
- return ''
270
- })
271
- .filter((part) => part)
272
-
273
- whereParts.push(`(${subWhereParts.join(` ${logicalOperator} `)})`)
274
- }
275
- }
276
-
277
- const whereClause =
278
- whereParts.length > 0 ? ` WHERE ${whereParts.join(' AND ')}` : ''
279
- return [whereClause, values, index]
280
- }
281
-
282
- /**
283
- * Creates an ORDER BY clause for a query
284
- *
285
- * This function creates an ORDER BY clause for a query. It takes an array of
286
- * order by fields and returns a string with the fields separated by commas.
287
- *
288
- * @param orderBy - The array of order by fields
289
- * @returns A string with the fields separated by commas
290
- *
291
- * @example
292
- * const orderBy = [{ field: 'created_at', direction: 'DESC' }]
293
- * const result = createOrderByClause(orderBy)
294
- * // result will be: "ORDER BY created_at DESC"
295
- */
296
- export const createOrderByClause = (orderBy?: OrderBy) => {
297
- if (!orderBy || orderBy.length === 0) return ''
298
- const clause = orderBy.map((o) => `${o.field} ${o.direction}`).join(', ')
299
- return ` ORDER BY ${clause}`
300
- }
301
-
302
- /**
303
- * Creates a GROUP BY clause for a query
304
- *
305
- * This function creates a GROUP BY clause for a query. It takes an array of
306
- * group by fields and returns a string with the fields separated by commas.
307
- *
308
- * @param groupBy - The array of group by fields
309
- * @returns A string with the fields separated by commas
310
- *
311
- * @example
312
- * const groupBy = ['status']
313
- * const result = createGroupByClause(groupBy)
314
- * // result will be: "GROUP BY status"
315
- */
316
- export const createGroupByClause = (groupBy?: string[]) => {
317
- if (!groupBy || groupBy.length === 0) return ''
318
- return ` GROUP BY ${groupBy.join(', ')}`
319
- }
320
-
321
- /**
322
- * Creates a LIMIT clause for a query
323
- *
324
- * This function creates a LIMIT clause for a query. It takes a limit number
325
- * and returns a string with the limit.
326
- *
327
- * @param limit - The limit number
328
- * @returns A string with the limit
329
- *
330
- * @example
331
- * const limit = 10
332
- * const result = createLimitClause(limit)
333
- * // result will be: "LIMIT 10"
334
- */
335
- export const createLimitClause = (limit?: number) => {
336
- if (!limit) return ''
337
- return ` LIMIT ${limit}`
338
- }
339
-
340
- /**
341
- * Creates an OFFSET clause for a query
342
- *
343
- * This function creates an OFFSET clause for a query. It takes an offset number
344
- * and returns a string with the offset.
345
- *
346
- * @param offset - The offset number
347
- * @returns A string with the offset
348
- *
349
- * @example
350
- * const offset = 10
351
- * const result = createOffsetClause(offset)
352
- * // result will be: "OFFSET 10"
353
- */
354
- export const createOffsetClause = (offset?: number) => {
355
- if (!offset) return ''
356
- return ` OFFSET ${offset}`
357
- }
@@ -1,16 +0,0 @@
1
- import { DBClients } from '../core/types'
2
-
3
- export interface ITransactionClient {
4
- query: <T>(sql: string, params?: any[]) => Promise<T>
5
- commit: () => Promise<void>
6
- rollback: () => Promise<void>
7
- }
8
-
9
- /**
10
- * Database client interface
11
- */
12
- export type IDatabaseClient = {
13
- clientType: DBClients
14
- query: <T>(sql: string, params?: any[]) => Promise<T>
15
- beginTransaction: () => Promise<ITransactionClient>
16
- }