@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,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Logger = void 0;
4
+ /**
5
+ * Logger class that handles database operation logs based on configured log level.
6
+ *
7
+ * Log Levels:
8
+ * - 0 (NONE): No logging
9
+ * - 1 (ERROR): Only errors
10
+ * - 2 (DEBUG): Errors + debug information
11
+ * - 3 (ALL): Errors + debug + warnings + info
12
+ *
13
+ * @class Logger
14
+ * @example
15
+ * ```typescript
16
+ * const logger = new Logger(2); // ERROR + DEBUG
17
+ * logger.error("Connection failed", error);
18
+ * logger.debug("Query executed", { rowCount: 5 });
19
+ * ```
20
+ */
21
+ class Logger {
22
+ constructor(level = 1, prefix = "[DB]") {
23
+ this.level = level;
24
+ this.prefix = prefix;
25
+ }
26
+ /**
27
+ * Logs error messages (Level 1+)
28
+ * @param message - Error message
29
+ * @param error - Optional error object or additional data
30
+ */
31
+ error(message, error) {
32
+ if (this.level >= 1) {
33
+ if (error !== undefined && error !== null && error !== "") {
34
+ console.error(`❌ ${this.prefix} [ERROR] ${message}`, error);
35
+ }
36
+ else {
37
+ console.error(`❌ ${this.prefix} [ERROR] ${message}`);
38
+ }
39
+ }
40
+ }
41
+ /**
42
+ * Logs debug information (Level 2+)
43
+ * @param message - Debug message
44
+ * @param data - Optional additional data
45
+ */
46
+ debug(message, data) {
47
+ if (this.level >= 2) {
48
+ // Solo mostrar data si tiene contenido relevante
49
+ if (data && typeof data === "object") {
50
+ const cleanData = this.cleanObject(data);
51
+ if (Object.keys(cleanData).length > 0) {
52
+ console.log(`🐛 ${this.prefix} [DEBUG] ${message}`, cleanData);
53
+ }
54
+ else {
55
+ console.log(`🐛 ${this.prefix} [DEBUG] ${message}`);
56
+ }
57
+ }
58
+ else if (data !== undefined && data !== null && data !== "") {
59
+ console.log(`🐛 ${this.prefix} [DEBUG] ${message}`, data);
60
+ }
61
+ else {
62
+ console.log(`🐛 ${this.prefix} [DEBUG] ${message}`);
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * Logs warning messages (Level 3+)
68
+ * @param message - Warning message
69
+ * @param data - Optional additional data
70
+ */
71
+ warn(message, data) {
72
+ if (this.level >= 3) {
73
+ if (data && typeof data === "object") {
74
+ const cleanData = this.cleanObject(data);
75
+ if (Object.keys(cleanData).length > 0) {
76
+ console.warn(`⚠️ ${this.prefix} [WARN] ${message}`, cleanData);
77
+ }
78
+ else {
79
+ console.warn(`⚠️ ${this.prefix} [WARN] ${message}`);
80
+ }
81
+ }
82
+ else if (data !== undefined && data !== null && data !== "") {
83
+ console.warn(`⚠️ ${this.prefix} [WARN] ${message}`, data);
84
+ }
85
+ else {
86
+ console.warn(`⚠️ ${this.prefix} [WARN] ${message}`);
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Logs informational messages (Level 3+)
92
+ * @param message - Info message
93
+ * @param data - Optional additional data
94
+ */
95
+ info(message, data) {
96
+ if (this.level >= 3) {
97
+ if (data && typeof data === "object") {
98
+ const cleanData = this.cleanObject(data);
99
+ if (Object.keys(cleanData).length > 0) {
100
+ console.log(`ℹ️ ${this.prefix} [INFO] ${message}`, cleanData);
101
+ }
102
+ else {
103
+ console.log(`ℹ️ ${this.prefix} [INFO] ${message}`);
104
+ }
105
+ }
106
+ else if (data !== undefined && data !== null && data !== "") {
107
+ console.log(`ℹ️ ${this.prefix} [INFO] ${message}`, data);
108
+ }
109
+ else {
110
+ console.log(`ℹ️ ${this.prefix} [INFO] ${message}`);
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Limpia un objeto removiendo propiedades undefined, null o vacías
116
+ * @private
117
+ */
118
+ cleanObject(obj) {
119
+ if (typeof obj !== "object" || obj === null) {
120
+ return obj;
121
+ }
122
+ const cleaned = {};
123
+ for (const key in obj) {
124
+ const value = obj[key];
125
+ if (value !== undefined && value !== null && value !== "") {
126
+ cleaned[key] = value;
127
+ }
128
+ }
129
+ return cleaned;
130
+ }
131
+ /**
132
+ * Updates the log level dynamically
133
+ * @param level - New log level (0-3)
134
+ */
135
+ setLevel(level) {
136
+ this.level = level;
137
+ }
138
+ /**
139
+ * Gets the current log level
140
+ * @returns Current log level
141
+ */
142
+ getLevel() {
143
+ return this.level;
144
+ }
145
+ }
146
+ exports.Logger = Logger;
147
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../components/Logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module @crane-technologies/database
3
+ * PostgreSQL Database Component
4
+ *
5
+ * Main exports for the database component providing connection pooling,
6
+ * transactions, and query management.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import Database, { DatabaseConfig } from '@crane-technologies/database';
11
+ *
12
+ * const config: DatabaseConfig = {
13
+ * connectionString: process.env.DATABASE_URL,
14
+ * ssl: { rejectUnauthorized: false },
15
+ * max: 10,
16
+ * logLevel: 2
17
+ * };
18
+ *
19
+ * const db = Database.getInstance(config, queries);
20
+ * ```
21
+ */
22
+ export { default } from "./components/Database";
23
+ export { default as Database } from "./components/Database";
24
+ export { createQueries, QueryReference } from "./utils/createQueries";
25
+ export { Dependency } from "./interfaces/Dependancy";
26
+ export { DatabaseConfig, LogLevel } from "./interfaces/DatabaseConfig";
27
+ export { Logger } from "./components/Logger";
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAGvE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * @module @crane-technologies/database
4
+ * PostgreSQL Database Component
5
+ *
6
+ * Main exports for the database component providing connection pooling,
7
+ * transactions, and query management.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import Database, { DatabaseConfig } from '@crane-technologies/database';
12
+ *
13
+ * const config: DatabaseConfig = {
14
+ * connectionString: process.env.DATABASE_URL,
15
+ * ssl: { rejectUnauthorized: false },
16
+ * max: 10,
17
+ * logLevel: 2
18
+ * };
19
+ *
20
+ * const db = Database.getInstance(config, queries);
21
+ * ```
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.Logger = exports.createQueries = exports.Database = exports.default = void 0;
28
+ // Main Database class (default export)
29
+ var Database_1 = require("./components/Database");
30
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(Database_1).default; } });
31
+ var Database_2 = require("./components/Database");
32
+ Object.defineProperty(exports, "Database", { enumerable: true, get: function () { return __importDefault(Database_2).default; } });
33
+ // Utility functions
34
+ var createQueries_1 = require("./utils/createQueries");
35
+ Object.defineProperty(exports, "createQueries", { enumerable: true, get: function () { return createQueries_1.createQueries; } });
36
+ // Logger
37
+ var Logger_1 = require("./components/Logger");
38
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return Logger_1.Logger; } });
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;AAEH,uCAAuC;AACvC,kDAAgD;AAAvC,oHAAA,OAAO,OAAA;AAChB,kDAA4D;AAAnD,qHAAA,OAAO,OAAY;AAE5B,oBAAoB;AACpB,uDAAsE;AAA7D,8GAAA,aAAa,OAAA;AAMtB,SAAS;AACT,8CAA6C;AAApC,gGAAA,MAAM,OAAA"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Options for bulk insert operations, typically used for CSV imports.
3
+ *
4
+ * @interface BulkInsertOptions
5
+ * @property {string} [delimiter] - CSV delimiter character (default is ",").
6
+ * @property {boolean} [header] - Whether to include a header row with column names.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const options: BulkInsertOptions = {
11
+ * delimiter: ";",
12
+ * header: true,
13
+ * };
14
+ *```
15
+ */
16
+ export interface BulkInsertOptions {
17
+ delimiter?: string;
18
+ header?: boolean;
19
+ }
20
+ //# sourceMappingURL=BulkInsertOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BulkInsertOptions.d.ts","sourceRoot":"","sources":["../../interfaces/BulkInsertOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=BulkInsertOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BulkInsertOptions.js","sourceRoot":"","sources":["../../interfaces/BulkInsertOptions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Log levels for database operations
3
+ * 0 = NONE (no logs)
4
+ * 1 = ERROR (only errors)
5
+ * 2 = DEBUG (errors + debug info)
6
+ * 3 = ALL (errors + debug + warnings + info)
7
+ */
8
+ export type LogLevel = 0 | 1 | 2 | 3;
9
+ /**
10
+ * Database configuration interface that extends PostgreSQL PoolConfig.
11
+ * Defines all available options for configuring the database connection pool.
12
+ *
13
+ * @interface DatabaseConfig
14
+ * @property {string} [connectionString] - Database connection string
15
+ * @property {boolean | { rejectUnauthorized: boolean }} [ssl] - SSL configuration for the connection
16
+ * @property {number} [max] - Maximum number of clients in the pool
17
+ * @property {number} [idleTimeoutMillis] - Time a client must sit idle in the pool before being closed
18
+ * @property {number} [connectionTimeoutMillis] - Time to wait for a connection to be established
19
+ * @property {number} [statement_timeout] - Maximum allowed duration of any statement
20
+ * @property {number} [query_timeout] - Maximum allowed duration of any query
21
+ * @property {boolean} [keepAlive] - Whether to enable TCP keep-alive on the connection
22
+ * @property {LogLevel} [logLevel] - Logging level: 0=NONE, 1=ERROR, 2=DEBUG, 3=ALL (default: 1)
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const config: DatabaseConfig = {
27
+ * connectionString: process.env.DATABASE_URL,
28
+ * ssl: { rejectUnauthorized: false },
29
+ * max: 10,
30
+ * idleTimeoutMillis: 30000,
31
+ * connectionTimeoutMillis: 5000,
32
+ * statement_timeout: 30000,
33
+ * query_timeout: 30000,
34
+ * keepAlive: true,
35
+ * logLevel: 2, // ERROR + DEBUG
36
+ * };
37
+ * ```
38
+ */
39
+ export interface DatabaseConfig {
40
+ connectionString?: string;
41
+ ssl?: boolean | {
42
+ rejectUnauthorized: boolean;
43
+ };
44
+ max?: number;
45
+ idleTimeoutMillis?: number;
46
+ connectionTimeoutMillis?: number;
47
+ statement_timeout?: number;
48
+ query_timeout?: number;
49
+ keepAlive?: boolean;
50
+ logLevel?: LogLevel;
51
+ }
52
+ //# sourceMappingURL=DatabaseConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseConfig.d.ts","sourceRoot":"","sources":["../../interfaces/DatabaseConfig.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,kBAAkB,EAAE,OAAO,CAAA;KAAE,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=DatabaseConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseConfig.js","sourceRoot":"","sources":["../../interfaces/DatabaseConfig.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Interface that defines the structure of a dependency between queries in transactions.
3
+ * Allows the result of a query (sourceIndex) to be used as a parameter in another query (targetIndex).
4
+ *
5
+ * @interface Dependency
6
+ * @property {number} sourceIndex - Index of the source query in the queries array
7
+ * @property {number} targetIndex - Index of the target query that will receive the value
8
+ * @property {number} targetParamIndex - Index of the parameter in the target query where the value will be inserted
9
+ */
10
+ export interface Dependency {
11
+ sourceIndex: number;
12
+ targetIndex: number;
13
+ targetParamIndex: number;
14
+ }
15
+ //# sourceMappingURL=Dependancy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dependancy.d.ts","sourceRoot":"","sources":["../../interfaces/Dependancy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Dependancy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dependancy.js","sourceRoot":"","sources":["../../interfaces/Dependancy.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export interface QueryList {
2
+ [key: string]: string;
3
+ }
4
+ //# sourceMappingURL=QueryList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryList.d.ts","sourceRoot":"","sources":["../../interfaces/QueryList.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=QueryList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryList.js","sourceRoot":"","sources":["../../interfaces/QueryList.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Tipo que representa una referencia a una query con autocompletado.
3
+ * Contiene el path interno para que Database pueda encontrar el SQL.
4
+ */
5
+ export type QueryReference = {
6
+ __queryKey: string;
7
+ sql: string;
8
+ toString: () => string;
9
+ valueOf: () => string;
10
+ };
11
+ /**
12
+ * Función principal que convierte queries (planas o anidadas) en objetos con autocompletado.
13
+ * NO requiere desestructuración manual. El objeto retornado ya contiene todo.
14
+ *
15
+ * @param queries - Objeto con queries (soporta planas, anidadas o mixtas)
16
+ * @returns Objeto con queries accesibles directamente y __flatMap interno
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // ✅ Caso 1: Queries planas (SIN desestructurar)
21
+ * const queries = createQueries({
22
+ * getUser: "SELECT * FROM users WHERE id = $1",
23
+ * createUser: "INSERT INTO users (name) VALUES ($1) RETURNING *"
24
+ * });
25
+ *
26
+ * const db = Database.getInstance(config, queries);
27
+ * await db.query(queries.getUser, [123]);
28
+ * await db.query(queries.createUser, ["John"]);
29
+ *
30
+ * // ✅ Caso 2: Queries anidadas (SIN desestructurar)
31
+ * const queries = createQueries({
32
+ * users: {
33
+ * getById: "SELECT * FROM users WHERE id = $1",
34
+ * create: "INSERT INTO users..."
35
+ * },
36
+ * products: {
37
+ * getAll: "SELECT * FROM products"
38
+ * }
39
+ * });
40
+ *
41
+ * const db = Database.getInstance(config, queries);
42
+ * await db.query(queries.users.getById, [123]);
43
+ * await db.query(queries.products.getAll);
44
+ *
45
+ * // ✅ Caso 3: Queries mixtas (SIN desestructurar)
46
+ * const queries = createQueries({
47
+ * connection: "SELECT NOW()",
48
+ * users: {
49
+ * getById: "SELECT * FROM users WHERE id = $1"
50
+ * }
51
+ * });
52
+ *
53
+ * const db = Database.getInstance(config, queries);
54
+ * await db.query(queries.connection);
55
+ * await db.query(queries.users.getById, [123]);
56
+ *
57
+ * // ✅ OPCIONAL: Desestructurar solo si quieres
58
+ * const { users, products } = queries;
59
+ * await db.query(users.getById, [123]);
60
+ * ```
61
+ */
62
+ export declare function createQueries<T extends Record<string, any>>(queries: T): T & {
63
+ __flatMap: Record<string, string>;
64
+ };
65
+ //# sourceMappingURL=createQueries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createQueries.d.ts","sourceRoot":"","sources":["../../utils/createQueries.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,GA2E5C,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CACnE"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createQueries = createQueries;
4
+ /**
5
+ * Función principal que convierte queries (planas o anidadas) en objetos con autocompletado.
6
+ * NO requiere desestructuración manual. El objeto retornado ya contiene todo.
7
+ *
8
+ * @param queries - Objeto con queries (soporta planas, anidadas o mixtas)
9
+ * @returns Objeto con queries accesibles directamente y __flatMap interno
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // ✅ Caso 1: Queries planas (SIN desestructurar)
14
+ * const queries = createQueries({
15
+ * getUser: "SELECT * FROM users WHERE id = $1",
16
+ * createUser: "INSERT INTO users (name) VALUES ($1) RETURNING *"
17
+ * });
18
+ *
19
+ * const db = Database.getInstance(config, queries);
20
+ * await db.query(queries.getUser, [123]);
21
+ * await db.query(queries.createUser, ["John"]);
22
+ *
23
+ * // ✅ Caso 2: Queries anidadas (SIN desestructurar)
24
+ * const queries = createQueries({
25
+ * users: {
26
+ * getById: "SELECT * FROM users WHERE id = $1",
27
+ * create: "INSERT INTO users..."
28
+ * },
29
+ * products: {
30
+ * getAll: "SELECT * FROM products"
31
+ * }
32
+ * });
33
+ *
34
+ * const db = Database.getInstance(config, queries);
35
+ * await db.query(queries.users.getById, [123]);
36
+ * await db.query(queries.products.getAll);
37
+ *
38
+ * // ✅ Caso 3: Queries mixtas (SIN desestructurar)
39
+ * const queries = createQueries({
40
+ * connection: "SELECT NOW()",
41
+ * users: {
42
+ * getById: "SELECT * FROM users WHERE id = $1"
43
+ * }
44
+ * });
45
+ *
46
+ * const db = Database.getInstance(config, queries);
47
+ * await db.query(queries.connection);
48
+ * await db.query(queries.users.getById, [123]);
49
+ *
50
+ * // ✅ OPCIONAL: Desestructurar solo si quieres
51
+ * const { users, products } = queries;
52
+ * await db.query(users.getById, [123]);
53
+ * ```
54
+ */
55
+ function createQueries(queries) {
56
+ // flatMap: diccionario plano para Database
57
+ // "users.getById" -> "SELECT * FROM users WHERE id = $1"
58
+ // "getUser" -> "SELECT * FROM users WHERE id = $1"
59
+ const flatMap = {};
60
+ /**
61
+ * Función recursiva que aplana queries (planas o anidadas)
62
+ *
63
+ * Ejemplos:
64
+ * - getUser: "SELECT..." -> "getUser": "SELECT..."
65
+ * - users: { getById: "SELECT..." } -> "users.getById": "SELECT..."
66
+ */
67
+ function flatten(obj, prefix = "") {
68
+ for (const [key, value] of Object.entries(obj)) {
69
+ const fullKey = prefix ? `${prefix}.${key}` : key;
70
+ if (typeof value === "string") {
71
+ // Es un SQL string, guardarlo en flatMap
72
+ flatMap[fullKey] = value;
73
+ }
74
+ else if (typeof value === "object" && value !== null) {
75
+ // Es un objeto anidado, continuar recursivamente
76
+ flatten(value, fullKey);
77
+ }
78
+ }
79
+ }
80
+ // Aplanar todas las queries (planas y anidadas)
81
+ flatten(queries);
82
+ /**
83
+ * Proxy que intercepta el acceso a las propiedades
84
+ * Maneja tanto queries planas como anidadas
85
+ */
86
+ function createProxy(target, path = []) {
87
+ return new Proxy(target, {
88
+ get(obj, prop) {
89
+ // Permitir acceso a __flatMap
90
+ if (prop === "__flatMap") {
91
+ return flatMap;
92
+ }
93
+ // Ignorar símbolos internos de Node.js
94
+ if (typeof prop === "symbol") {
95
+ return undefined;
96
+ }
97
+ const value = obj[prop];
98
+ // CASO 1: Es un string (SQL) - Query plana o hoja de anidación
99
+ if (typeof value === "string") {
100
+ const fullPath = [...path, prop].join(".");
101
+ return {
102
+ __queryKey: fullPath,
103
+ sql: value,
104
+ toString: () => fullPath,
105
+ valueOf: () => fullPath,
106
+ };
107
+ }
108
+ // CASO 2: Es un objeto - Query anidada
109
+ if (typeof value === "object" && value !== null) {
110
+ return createProxy(value, [...path, prop]);
111
+ }
112
+ return value;
113
+ },
114
+ });
115
+ }
116
+ // Crear el proxy con las queries
117
+ const proxiedQueries = createProxy(queries);
118
+ // Retornar el proxy directamente con __flatMap accesible
119
+ return proxiedQueries;
120
+ }
121
+ //# sourceMappingURL=createQueries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createQueries.js","sourceRoot":"","sources":["../../utils/createQueries.ts"],"names":[],"mappings":";;AA8DA,sCA4EC;AA/HD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,SAAgB,aAAa,CAAgC,OAAU;IACrE,2CAA2C;IAC3C,yDAAyD;IACzD,mDAAmD;IACnD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C;;;;;;OAMG;IACH,SAAS,OAAO,CAAC,GAAQ,EAAE,SAAiB,EAAE;QAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAElD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,yCAAyC;gBACzC,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;YAC3B,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACvD,iDAAiD;gBACjD,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjB;;;OAGG;IACH,SAAS,WAAW,CAAC,MAAW,EAAE,OAAiB,EAAE;QACnD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YACvB,GAAG,CAAC,GAAG,EAAE,IAAY;gBACnB,8BAA8B;gBAC9B,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzB,OAAO,OAAO,CAAC;gBACjB,CAAC;gBAED,uCAAuC;gBACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC7B,OAAO,SAAS,CAAC;gBACnB,CAAC;gBAED,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;gBAExB,+DAA+D;gBAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAE3C,OAAO;wBACL,UAAU,EAAE,QAAQ;wBACpB,GAAG,EAAE,KAAK;wBACV,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ;wBACxB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ;qBACN,CAAC;gBACtB,CAAC;gBAED,uCAAuC;gBACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBAChD,OAAO,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC7C,CAAC;gBAED,OAAO,KAAK,CAAC;YACf,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,iCAAiC;IACjC,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAE5C,yDAAyD;IACzD,OAAO,cAA2D,CAAC;AACrE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@crane-technologies/database",
3
+ "version": "2.1.0",
4
+ "description": "PostgreSQL database component with connection pooling, transactions, dependency management and TypeScript autocomplete",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "build:watch": "tsc --watch",
10
+ "test": "tsx test.ts",
11
+ "dev": "tsx test.ts",
12
+ "test:watch": "tsx watch test.ts",
13
+ "clean": "rimraf dist",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "postgresql",
18
+ "postgres",
19
+ "database",
20
+ "pool",
21
+ "transaction",
22
+ "sql",
23
+ "pg",
24
+ "crane",
25
+ "typescript",
26
+ "autocomplete",
27
+ "queries",
28
+ "typesafe"
29
+ ],
30
+ "author": "Crane",
31
+ "license": "MIT",
32
+ "type": "commonjs",
33
+ "files": [
34
+ "dist",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/Crane/database.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/Crane/database/issues"
44
+ },
45
+ "homepage": "https://github.com/Crane/database#readme",
46
+ "dependencies": {
47
+ "pg": "^8.0.0",
48
+ "pg-copy-streams": "^7.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^24.9.1",
52
+ "@types/pg": "^8.15.5",
53
+ "@types/pg-copy-streams": "^1.2.5",
54
+ "rimraf": "^6.0.1",
55
+ "tsx": "^4.20.6",
56
+ "typescript": "^5.9.3"
57
+ },
58
+ "engines": {
59
+ "node": ">=18.0.0"
60
+ }
61
+ }