@crane-technologies/database 2.1.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 (34) hide show
  1. package/README.md +475 -0
  2. package/dist/components/Database.d.ts +288 -0
  3. package/dist/components/Database.d.ts.map +1 -0
  4. package/dist/components/Database.js +554 -0
  5. package/dist/components/Database.js.map +1 -0
  6. package/dist/components/Logger.d.ts +63 -0
  7. package/dist/components/Logger.d.ts.map +1 -0
  8. package/dist/components/Logger.js +147 -0
  9. package/dist/components/Logger.js.map +1 -0
  10. package/dist/index.d.ts +28 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +39 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/interfaces/BulkInsertOptions.d.ts +20 -0
  15. package/dist/interfaces/BulkInsertOptions.d.ts.map +1 -0
  16. package/dist/interfaces/BulkInsertOptions.js +3 -0
  17. package/dist/interfaces/BulkInsertOptions.js.map +1 -0
  18. package/dist/interfaces/DatabaseConfig.d.ts +52 -0
  19. package/dist/interfaces/DatabaseConfig.d.ts.map +1 -0
  20. package/dist/interfaces/DatabaseConfig.js +3 -0
  21. package/dist/interfaces/DatabaseConfig.js.map +1 -0
  22. package/dist/interfaces/Dependancy.d.ts +15 -0
  23. package/dist/interfaces/Dependancy.d.ts.map +1 -0
  24. package/dist/interfaces/Dependancy.js +3 -0
  25. package/dist/interfaces/Dependancy.js.map +1 -0
  26. package/dist/interfaces/QueryList.d.ts +4 -0
  27. package/dist/interfaces/QueryList.d.ts.map +1 -0
  28. package/dist/interfaces/QueryList.js +3 -0
  29. package/dist/interfaces/QueryList.js.map +1 -0
  30. package/dist/utils/createQueries.d.ts +65 -0
  31. package/dist/utils/createQueries.d.ts.map +1 -0
  32. package/dist/utils/createQueries.js +121 -0
  33. package/dist/utils/createQueries.js.map +1 -0
  34. package/package.json +61 -0
@@ -0,0 +1,288 @@
1
+ import { QueryResult } from "pg";
2
+ import { Dependency } from "@/interfaces/Dependancy";
3
+ import { DatabaseConfig } from "@/interfaces/DatabaseConfig";
4
+ import { BulkInsertOptions } from "@/interfaces/BulkInsertOptions";
5
+ import { QueryReference } from "@/utils/createQueries";
6
+ /**
7
+ * Database class implements the Singleton pattern to manage PostgreSQL connections.
8
+ * Provides methods for executing SQL queries, transactions and dependency handling.
9
+ * Supports QueryReference objects for autocomplete.
10
+ *
11
+ * @class Database
12
+ * @example
13
+ * ```typescript
14
+ * import Database, { createQueries } from '@crane-technologies/database';
15
+ *
16
+ * const queries = createQueries({
17
+ * users: {
18
+ * getById: "SELECT * FROM users WHERE id = $1"
19
+ * }
20
+ * });
21
+ *
22
+ * const db = Database.getInstance(config, queries);
23
+ *
24
+ * // ✅ Con autocompletado
25
+ * await db.query(queries.users.getById, [123]);
26
+ * ```
27
+ */
28
+ declare class Database {
29
+ /** Unique singleton instance */
30
+ private static instance;
31
+ /** PostgreSQL connection pool */
32
+ private pool;
33
+ /** Dictionary of predefined SQL queries (flat map) */
34
+ private queries;
35
+ /** Logger instance */
36
+ private logger;
37
+ /** Database configuration */
38
+ private config;
39
+ /**
40
+ * Private constructor that implements the Singleton pattern.
41
+ * Use getInstance() to get the Database instance.
42
+ *
43
+ * @param {DatabaseConfig} config - Database configuration
44
+ * @param {Record<string, string>} flatMap - Flat map of queries
45
+ * @private
46
+ */
47
+ private constructor();
48
+ /**
49
+ * Initializes the PostgreSQL connection pool using provided configuration.
50
+ * Executed only once when creating the first singleton instance.
51
+ *
52
+ * @private
53
+ * @returns {void}
54
+ * @throws {Error} If pool initialization fails
55
+ */
56
+ private initializePool;
57
+ /**
58
+ * Static method to get the unique Database instance (Singleton pattern).
59
+ * Accepts the result of createQueries() or a plain object with queries.
60
+ *
61
+ * @param {DatabaseConfig} config - Database configuration (required on first call)
62
+ * @param {any} queries - Result from createQueries() or plain query object
63
+ * @returns {Database} The unique Database instance
64
+ * @throws {Error} If config is not provided on first initialization
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // With createQueries (recommended)
69
+ * const queries = createQueries({
70
+ * users: { getById: "SELECT * FROM users WHERE id = $1" }
71
+ * });
72
+ * const db = Database.getInstance(config, queries);
73
+ * await db.query(queries.users.getById, [123]);
74
+ *
75
+ * // With plain object (backward compatible)
76
+ * const db = Database.getInstance(config, {
77
+ * getUser: "SELECT * FROM users WHERE id = $1"
78
+ * });
79
+ * await db.query("getUser", [123]);
80
+ * ```
81
+ */
82
+ static getInstance(config: DatabaseConfig, queries?: any): Database;
83
+ /**
84
+ * Validates that the pool is active and ready to accept connections.
85
+ *
86
+ * @private
87
+ * @throws {Error} If pool is closed or not initialized
88
+ */
89
+ private ensurePoolActive;
90
+ /**
91
+ * Extracts the SQL from a QueryReference or string key.
92
+ *
93
+ * @private
94
+ * @param query - QueryReference, string key, or raw SQL
95
+ * @returns The SQL query string
96
+ * @throws {Error} If query is not found
97
+ */
98
+ private getQuery;
99
+ /**
100
+ * Gets the SQL query string.
101
+ *
102
+ * @private
103
+ * @param query - QueryReference or string
104
+ * @returns The SQL query string
105
+ */
106
+ private getQueryName;
107
+ /**
108
+ * Executes a predefined SQL query using QueryReference or string key.
109
+ * Gets a connection from the pool, executes the query and releases the connection.
110
+ *
111
+ * @param {string | QueryReference} query - QueryReference object or query key
112
+ * @param {any[]} params - Optional parameters for the SQL query
113
+ * @returns {Promise<QueryResult>} SQL query result
114
+ * @throws {Error} If the query doesn't exist or execution fails
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // With QueryReference (autocomplete!)
119
+ * const result = await db.queryList(queries.users.getById, [123]);
120
+ *
121
+ * // With string key (backward compatible)
122
+ * const result = await db.queryList("users.getById", [123]);
123
+ * ```
124
+ */
125
+ queryList(query: string | QueryReference, params?: any[]): Promise<QueryResult>;
126
+ /**
127
+ * Executes a direct SQL query (raw SQL text).
128
+ * Useful for dynamic queries that are not predefined in the dictionary.
129
+ * Gets a connection from the pool, executes the query and releases the connection.
130
+ *
131
+ * @param {string} sqlText - The complete SQL text of the query to execute
132
+ * @param {any[]} params - Optional parameters for the SQL query
133
+ * @returns {Promise<QueryResult>} SQL query result
134
+ * @throws {Error} If query execution fails
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const result = await db.rawQuery("SELECT COUNT(*) FROM users WHERE active = $1", [true]);
139
+ * const count = result.rows[0].count;
140
+ * ```
141
+ */
142
+ rawQuery(sqlText: string, params?: any[]): Promise<QueryResult>;
143
+ /**
144
+ * Performs a high-performance bulk insert using PostgreSQL's native COPY ... FROM STDIN.
145
+ * Accepts an array of rows and streams them as CSV to the database.
146
+ * This is significantly faster than multiple INSERT statements.
147
+ *
148
+ * @param {string} table - The target table name.
149
+ * @param {string[]} columns - Array of column names to insert into (order matters).
150
+ * @param {(string | number | boolean | Date | null | undefined)[][]} rows - Array of row arrays, each representing a record.
151
+ * @param {BulkInsertOptions} [options] - Optional CSV formatting options (delimiter, header).
152
+ * @returns {Promise<{ inserted: number }>} Number of rows successfully inserted.
153
+ * @throws {Error} If the operation fails or the pool is not active.
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * await db.bulkInsert(
158
+ * "users",
159
+ * ["name", "email"],
160
+ * [
161
+ * ["Alice", "alice@email.com"],
162
+ * ["Bob", "bob@email.com"]
163
+ * ],
164
+ * { header: false }
165
+ * );
166
+ * ```
167
+ */
168
+ bulkInsert(table: string, columns: string[], rows: (string | number | boolean | Date | null | undefined)[][], options?: BulkInsertOptions): Promise<{
169
+ inserted: number;
170
+ }>;
171
+ /**
172
+ * Generator that yields CSV lines for bulk insert operations.
173
+ * Optionally includes a header row with column names.
174
+ * Each yielded value is a CSV-formatted string representing a row.
175
+ *
176
+ * @private
177
+ * @param {string[]} columns - Array of column names.
178
+ * @param {(string | number | boolean | Date | null | undefined)[][]} rows - Array of row arrays.
179
+ * @param {string} delimiter - CSV delimiter character.
180
+ * @param {boolean} includeHeader - Whether to include a header row.
181
+ * @yields {string} CSV-formatted line.
182
+ */
183
+ private generateCsvLines;
184
+ /**
185
+ * Escapes a single value for safe inclusion in a CSV line.
186
+ * Handles delimiters, quotes, and line breaks according to CSV rules.
187
+ *
188
+ * @private
189
+ * @param {string | number | boolean | Date | null | undefined} value - The value to escape.
190
+ * @param {string} delimiter - The CSV delimiter character.
191
+ * @returns {string} The escaped CSV value.
192
+ */
193
+ private escapeCsvValue;
194
+ /**
195
+ * Safely quotes a SQL identifier (such as a table or column name) for use in queries.
196
+ * Escapes any double quotes within the identifier to prevent SQL injection or syntax errors.
197
+ *
198
+ * @private
199
+ * @param {string} identifier - The SQL identifier to quote (e.g., table or column name).
200
+ * @returns {string} The quoted and escaped identifier, safe for use in SQL statements.
201
+ *
202
+ * @example
203
+ * const quoted = db.quoteIdentifier('user"name');
204
+ * // quoted === '"user""name"'
205
+ */
206
+ private quoteIdentifier;
207
+ /**
208
+ * Smart method that executes queries automatically detecting the type.
209
+ * Supports QueryReference objects (from createQueries), string keys, or raw SQL.
210
+ *
211
+ * @param {string | QueryReference} query - QueryReference, query key, or raw SQL
212
+ * @param {any[]} params - Optional parameters for the SQL query
213
+ * @returns {Promise<QueryResult>} SQL query result
214
+ * @throws {Error} If query execution fails
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * // Using QueryReference (autocomplete!)
219
+ * const user = await db.query(queries.users.getById, [123]);
220
+ *
221
+ * // Using string key (backward compatible)
222
+ * const user = await db.query("users.getById", [123]);
223
+ *
224
+ * // Using raw SQL
225
+ * const products = await db.query("SELECT * FROM products WHERE price > $1", [100]);
226
+ * ```
227
+ */
228
+ query(query: string | QueryReference, params?: any[]): Promise<QueryResult>;
229
+ /**
230
+ * Executes multiple SQL queries within an atomic transaction.
231
+ * All queries execute or fail together (ACID compliance).
232
+ * Supports dependencies between queries, where the result of one query
233
+ * can be used as a parameter in subsequent queries.
234
+ * Supports QueryReference objects with autocomplete.
235
+ *
236
+ * @param {(string | QueryReference)[]} queryArray - Array of QueryReferences or query keys
237
+ * @param {any[][]} paramsArray - Array of arrays with parameters for each query
238
+ * @param {Dependency[]} dependencies - Optional array of dependencies between queries
239
+ * @returns {Promise<QueryResult[]>} Array with the results of all queries
240
+ * @throws {Error} If any query fails, the entire transaction is rolled back
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * // With QueryReference (autocomplete!)
245
+ * const results = await db.transaction(
246
+ * [queries.users.create, queries.profiles.create],
247
+ * [
248
+ * ["John", "john@email.com"],
249
+ * [null, "Profile description"]
250
+ * ],
251
+ * [{ sourceIndex: 0, targetIndex: 1, targetParamIndex: 0 }]
252
+ * );
253
+ *
254
+ * // With string keys (backward compatible)
255
+ * const results = await db.transaction(
256
+ * ["users.create", "profiles.create"],
257
+ * [["John", "john@email.com"], [null, "Profile description"]],
258
+ * [{ sourceIndex: 0, targetIndex: 1, targetParamIndex: 0 }]
259
+ * );
260
+ * ```
261
+ */
262
+ transaction(queryArray: (string | QueryReference)[], paramsArray: any[][], dependencies?: Dependency[]): Promise<QueryResult[]>;
263
+ /**
264
+ * Closes all connections in the pool and cleans up resources.
265
+ * Should be called before application shutdown or when the database is no longer needed.
266
+ * After calling this method, the singleton instance is reset and a new one can be created.
267
+ *
268
+ * @returns {Promise<void>}
269
+ * @throws {Error} If there's an error closing the pool
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * process.on('SIGTERM', async () => {
274
+ * const db = Database.getInstance();
275
+ * await db.close();
276
+ * process.exit(0);
277
+ * });
278
+ * ```
279
+ */
280
+ close(): Promise<void>;
281
+ /**
282
+ * Updates the log level dynamically
283
+ * @param level - New log level (0-3)
284
+ */
285
+ setLogLevel(level: 0 | 1 | 2 | 3): void;
286
+ }
287
+ export default Database;
288
+ //# sourceMappingURL=Database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../components/Database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,WAAW,EAAE,MAAM,IAAI,CAAC;AAMnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,cAAM,QAAQ;IACZ,gCAAgC;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAW;IAElC,iCAAiC;IACjC,OAAO,CAAC,IAAI,CAAQ;IAEpB,sDAAsD;IACtD,OAAO,CAAC,OAAO,CAAY;IAE3B,sBAAsB;IACtB,OAAO,CAAC,MAAM,CAAS;IAEvB,6BAA6B;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAE/B;;;;;;;OAOG;IACH,OAAO;IAOP;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;WACW,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,QAAQ;IA6B1E;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;IAgChB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAUpB;;;;;;;;;;;;;;;;;OAiBG;IACG,SAAS,CACb,KAAK,EAAE,MAAM,GAAG,cAAc,EAC9B,MAAM,CAAC,EAAE,GAAG,EAAE,GACb,OAAO,CAAC,WAAW,CAAC;IA6BvB;;;;;;;;;;;;;;;OAeG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IA0BrE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,EAC/D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IA6ChC;;;;;;;;;;;OAWG;IACH,OAAO,CAAE,gBAAgB;IAkBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAgBtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,KAAK,CACT,KAAK,EAAE,MAAM,GAAG,cAAc,EAC9B,MAAM,CAAC,EAAE,GAAG,EAAE,GACb,OAAO,CAAC,WAAW,CAAC;IAoBvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACG,WAAW,CACf,UAAU,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC,EAAE,EACvC,WAAW,EAAE,GAAG,EAAE,EAAE,EACpB,YAAY,GAAE,UAAU,EAAO,GAC9B,OAAO,CAAC,WAAW,EAAE,CAAC;IAwEzB;;;;;;;;;;;;;;;;OAgBG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAcnC;;;OAGG;IACI,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI;CAI/C;AAED,eAAe,QAAQ,CAAC"}