@qwickapps/server 1.1.6 → 1.1.9
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.
- package/README.md +1 -1
- package/dist/core/control-panel.d.ts.map +1 -1
- package/dist/core/control-panel.js +5 -8
- package/dist/core/control-panel.js.map +1 -1
- package/dist/core/gateway.d.ts +5 -0
- package/dist/core/gateway.d.ts.map +1 -1
- package/dist/core/gateway.js +390 -28
- package/dist/core/gateway.js.map +1 -1
- package/dist/core/health-manager.d.ts.map +1 -1
- package/dist/core/health-manager.js +3 -9
- package/dist/core/health-manager.js.map +1 -1
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/logging.js +2 -6
- package/dist/core/logging.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/cache-plugin.d.ts +219 -0
- package/dist/plugins/cache-plugin.d.ts.map +1 -0
- package/dist/plugins/cache-plugin.js +326 -0
- package/dist/plugins/cache-plugin.js.map +1 -0
- package/dist/plugins/cache-plugin.test.d.ts +8 -0
- package/dist/plugins/cache-plugin.test.d.ts.map +1 -0
- package/dist/plugins/cache-plugin.test.js +188 -0
- package/dist/plugins/cache-plugin.test.js.map +1 -0
- package/dist/plugins/config-plugin.js +1 -1
- package/dist/plugins/config-plugin.js.map +1 -1
- package/dist/plugins/diagnostics-plugin.js +1 -1
- package/dist/plugins/diagnostics-plugin.js.map +1 -1
- package/dist/plugins/health-plugin.js +1 -1
- package/dist/plugins/health-plugin.js.map +1 -1
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/logs-plugin.d.ts.map +1 -1
- package/dist/plugins/logs-plugin.js +1 -3
- package/dist/plugins/logs-plugin.js.map +1 -1
- package/dist/plugins/postgres-plugin.d.ts +155 -0
- package/dist/plugins/postgres-plugin.d.ts.map +1 -0
- package/dist/plugins/postgres-plugin.js +244 -0
- package/dist/plugins/postgres-plugin.js.map +1 -0
- package/dist/plugins/postgres-plugin.test.d.ts +8 -0
- package/dist/plugins/postgres-plugin.test.d.ts.map +1 -0
- package/dist/plugins/postgres-plugin.test.js +165 -0
- package/dist/plugins/postgres-plugin.test.js.map +1 -0
- package/dist-ui/assets/{index-Bk7ypbI4.js → index-CW1BviRn.js} +2 -2
- package/dist-ui/assets/{index-Bk7ypbI4.js.map → index-CW1BviRn.js.map} +1 -1
- package/dist-ui/index.html +1 -1
- package/package.json +13 -2
- package/src/core/control-panel.ts +5 -8
- package/src/core/gateway.ts +412 -30
- package/src/core/health-manager.ts +3 -9
- package/src/core/logging.ts +2 -6
- package/src/index.ts +22 -0
- package/src/plugins/cache-plugin.test.ts +241 -0
- package/src/plugins/cache-plugin.ts +503 -0
- package/src/plugins/config-plugin.ts +1 -1
- package/src/plugins/diagnostics-plugin.ts +1 -1
- package/src/plugins/health-plugin.ts +1 -1
- package/src/plugins/index.ts +10 -0
- package/src/plugins/logs-plugin.ts +1 -3
- package/src/plugins/postgres-plugin.test.ts +213 -0
- package/src/plugins/postgres-plugin.ts +345 -0
- package/ui/src/api/controlPanelApi.ts +1 -1
- package/ui/src/pages/LogsPage.tsx +6 -10
package/dist/plugins/index.js
CHANGED
|
@@ -8,4 +8,8 @@ export { createLogsPlugin } from './logs-plugin.js';
|
|
|
8
8
|
export { createConfigPlugin } from './config-plugin.js';
|
|
9
9
|
export { createDiagnosticsPlugin } from './diagnostics-plugin.js';
|
|
10
10
|
export { createFrontendAppPlugin } from './frontend-app-plugin.js';
|
|
11
|
+
export { createPostgresPlugin, getPostgres, hasPostgres } from './postgres-plugin.js';
|
|
12
|
+
// Backward compatibility aliases (deprecated)
|
|
13
|
+
export { createPostgresPlugin as createDatabasePlugin, getPostgres as getDatabase, hasPostgres as hasDatabase } from './postgres-plugin.js';
|
|
14
|
+
export { createCachePlugin, getCache, hasCache } from './cache-plugin.js';
|
|
11
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGtF,8CAA8C;AAC9C,OAAO,EAAE,oBAAoB,IAAI,oBAAoB,EAAE,WAAW,IAAI,WAAW,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG5I,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/logs-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAiB,MAAM,kBAAkB,CAAC;AAGrF,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAsCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,gBAAqB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"logs-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/logs-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAiB,MAAM,kBAAkB,CAAC;AAGrF,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAsCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,gBAAqB,GAAG,kBAAkB,CAkGlF"}
|
|
@@ -111,9 +111,7 @@ export function createLogsPlugin(config = {}) {
|
|
|
111
111
|
],
|
|
112
112
|
async onInit(context) {
|
|
113
113
|
const sources = getSources();
|
|
114
|
-
context.logger.
|
|
115
|
-
sources: sources.map((s) => ({ name: s.name, type: s.type, path: s.path })),
|
|
116
|
-
});
|
|
114
|
+
context.logger.debug(`Logs plugin initialized with ${sources.length} sources`);
|
|
117
115
|
},
|
|
118
116
|
};
|
|
119
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-plugin.js","sourceRoot":"","sources":["../../src/plugins/logs-plugin.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"logs-plugin.js","sourceRoot":"","sources":["../../src/plugins/logs-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides PostgreSQL database connection pooling and health checks.
|
|
5
|
+
* Wraps the 'pg' library with a simple, reusable interface.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
* - Connection pooling with configurable limits
|
|
9
|
+
* - Automatic health checks with pool stats
|
|
10
|
+
* - Transaction helpers
|
|
11
|
+
* - Multiple named instances support
|
|
12
|
+
* - Graceful shutdown
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createGateway, createPostgresPlugin, getPostgres } from '@qwickapps/server';
|
|
18
|
+
*
|
|
19
|
+
* const gateway = createGateway({
|
|
20
|
+
* // ... config
|
|
21
|
+
* plugins: [
|
|
22
|
+
* createPostgresPlugin({
|
|
23
|
+
* url: process.env.DATABASE_URL,
|
|
24
|
+
* maxConnections: 20,
|
|
25
|
+
* }),
|
|
26
|
+
* ],
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // In your service code:
|
|
30
|
+
* const db = getPostgres();
|
|
31
|
+
* const users = await db.query<User>('SELECT * FROM users WHERE active = $1', [true]);
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ## Multiple Databases
|
|
35
|
+
*
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Register multiple databases with different names
|
|
38
|
+
* createPostgresPlugin({ url: primaryUrl }, 'primary');
|
|
39
|
+
* createPostgresPlugin({ url: replicaUrl }, 'replica');
|
|
40
|
+
*
|
|
41
|
+
* // Access by name
|
|
42
|
+
* const primary = getPostgres('primary');
|
|
43
|
+
* const replica = getPostgres('replica');
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
47
|
+
*/
|
|
48
|
+
import pg from 'pg';
|
|
49
|
+
import type { ControlPanelPlugin } from '../core/types.js';
|
|
50
|
+
/**
|
|
51
|
+
* Configuration for the PostgreSQL plugin
|
|
52
|
+
*/
|
|
53
|
+
export interface PostgresPluginConfig {
|
|
54
|
+
/** Database connection URL (e.g., postgresql://user:pass@host:5432/db) */
|
|
55
|
+
url: string;
|
|
56
|
+
/** Maximum number of clients in the pool (default: 20) */
|
|
57
|
+
maxConnections?: number;
|
|
58
|
+
/** Minimum number of clients in the pool (default: 2) */
|
|
59
|
+
minConnections?: number;
|
|
60
|
+
/** Idle timeout in milliseconds - close idle clients after this time (default: 30000) */
|
|
61
|
+
idleTimeoutMs?: number;
|
|
62
|
+
/** Connection timeout in milliseconds - fail if can't connect within this time (default: 5000) */
|
|
63
|
+
connectionTimeoutMs?: number;
|
|
64
|
+
/** Statement timeout in milliseconds - cancel queries taking longer (default: none) */
|
|
65
|
+
statementTimeoutMs?: number;
|
|
66
|
+
/** Register a health check for this database (default: true) */
|
|
67
|
+
healthCheck?: boolean;
|
|
68
|
+
/** Name for the health check (default: 'postgres') */
|
|
69
|
+
healthCheckName?: string;
|
|
70
|
+
/** Health check interval in milliseconds (default: 30000) */
|
|
71
|
+
healthCheckInterval?: number;
|
|
72
|
+
/** Called when a client connects (for setup like setting search_path) */
|
|
73
|
+
onConnect?: (client: pg.PoolClient) => Promise<void>;
|
|
74
|
+
/** Called on pool errors */
|
|
75
|
+
onError?: (error: Error) => void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Transaction callback function
|
|
79
|
+
*/
|
|
80
|
+
export type TransactionCallback<T> = (client: pg.PoolClient) => Promise<T>;
|
|
81
|
+
/**
|
|
82
|
+
* PostgreSQL instance returned by the plugin
|
|
83
|
+
*/
|
|
84
|
+
export interface PostgresInstance {
|
|
85
|
+
/** Get a client from the pool (remember to release it!) */
|
|
86
|
+
getClient(): Promise<pg.PoolClient>;
|
|
87
|
+
/** Execute a query and return rows */
|
|
88
|
+
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
89
|
+
/** Execute a query and return first row or null */
|
|
90
|
+
queryOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
|
|
91
|
+
/** Execute a query and return the full result (includes rowCount, etc.) */
|
|
92
|
+
queryRaw(sql: string, params?: unknown[]): Promise<pg.QueryResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Execute multiple queries in a transaction
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const result = await db.transaction(async (client) => {
|
|
99
|
+
* await client.query('INSERT INTO users (name) VALUES ($1)', ['Alice']);
|
|
100
|
+
* await client.query('INSERT INTO audit_log (action) VALUES ($1)', ['user_created']);
|
|
101
|
+
* return { success: true };
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
transaction<T>(callback: TransactionCallback<T>): Promise<T>;
|
|
106
|
+
/** Get the underlying pool (for advanced use cases) */
|
|
107
|
+
getPool(): pg.Pool;
|
|
108
|
+
/** Get pool statistics */
|
|
109
|
+
getStats(): {
|
|
110
|
+
total: number;
|
|
111
|
+
idle: number;
|
|
112
|
+
waiting: number;
|
|
113
|
+
};
|
|
114
|
+
/** Close all connections */
|
|
115
|
+
close(): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get a PostgreSQL instance by name
|
|
119
|
+
*
|
|
120
|
+
* @param name - Instance name (default: 'default')
|
|
121
|
+
* @returns The PostgreSQL instance
|
|
122
|
+
* @throws Error if the instance is not registered
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const db = getPostgres();
|
|
127
|
+
* const users = await db.query<User>('SELECT * FROM users');
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare function getPostgres(name?: string): PostgresInstance;
|
|
131
|
+
/**
|
|
132
|
+
* Check if a PostgreSQL instance is registered
|
|
133
|
+
*
|
|
134
|
+
* @param name - Instance name (default: 'default')
|
|
135
|
+
* @returns true if the instance exists
|
|
136
|
+
*/
|
|
137
|
+
export declare function hasPostgres(name?: string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Create a PostgreSQL plugin
|
|
140
|
+
*
|
|
141
|
+
* @param config - PostgreSQL configuration
|
|
142
|
+
* @param instanceName - Name for this PostgreSQL instance (default: 'default')
|
|
143
|
+
* @returns A control panel plugin
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* createPostgresPlugin({
|
|
148
|
+
* url: process.env.DATABASE_URL,
|
|
149
|
+
* maxConnections: 20,
|
|
150
|
+
* healthCheck: true,
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare function createPostgresPlugin(config: PostgresPluginConfig, instanceName?: string): ControlPanelPlugin;
|
|
155
|
+
//# sourceMappingURL=postgres-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/postgres-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,kBAAkB,CAAC;AAI1E;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,GAAG,EAAE,MAAM,CAAC;IAEZ,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kGAAkG;IAClG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,gEAAgE;IAChE,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,yEAAyE;IACzE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAErD,4BAA4B;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,SAAS,IAAI,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAEpC,sCAAsC;IACtC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAElF,mDAAmD;IACnD,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE1F,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IAEnE;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7D,uDAAuD;IACvD,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC;IAEnB,0BAA0B;IAC1B,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7D,4BAA4B;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,IAAI,SAAY,GAAG,gBAAgB,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,SAAY,GAAG,OAAO,CAErD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,EAC5B,YAAY,SAAY,GACvB,kBAAkB,CA2JpB"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides PostgreSQL database connection pooling and health checks.
|
|
5
|
+
* Wraps the 'pg' library with a simple, reusable interface.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
* - Connection pooling with configurable limits
|
|
9
|
+
* - Automatic health checks with pool stats
|
|
10
|
+
* - Transaction helpers
|
|
11
|
+
* - Multiple named instances support
|
|
12
|
+
* - Graceful shutdown
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createGateway, createPostgresPlugin, getPostgres } from '@qwickapps/server';
|
|
18
|
+
*
|
|
19
|
+
* const gateway = createGateway({
|
|
20
|
+
* // ... config
|
|
21
|
+
* plugins: [
|
|
22
|
+
* createPostgresPlugin({
|
|
23
|
+
* url: process.env.DATABASE_URL,
|
|
24
|
+
* maxConnections: 20,
|
|
25
|
+
* }),
|
|
26
|
+
* ],
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // In your service code:
|
|
30
|
+
* const db = getPostgres();
|
|
31
|
+
* const users = await db.query<User>('SELECT * FROM users WHERE active = $1', [true]);
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ## Multiple Databases
|
|
35
|
+
*
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Register multiple databases with different names
|
|
38
|
+
* createPostgresPlugin({ url: primaryUrl }, 'primary');
|
|
39
|
+
* createPostgresPlugin({ url: replicaUrl }, 'replica');
|
|
40
|
+
*
|
|
41
|
+
* // Access by name
|
|
42
|
+
* const primary = getPostgres('primary');
|
|
43
|
+
* const replica = getPostgres('replica');
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
47
|
+
*/
|
|
48
|
+
import pg from 'pg';
|
|
49
|
+
const { Pool } = pg;
|
|
50
|
+
// Global registry of PostgreSQL instances by name
|
|
51
|
+
const instances = new Map();
|
|
52
|
+
/**
|
|
53
|
+
* Get a PostgreSQL instance by name
|
|
54
|
+
*
|
|
55
|
+
* @param name - Instance name (default: 'default')
|
|
56
|
+
* @returns The PostgreSQL instance
|
|
57
|
+
* @throws Error if the instance is not registered
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const db = getPostgres();
|
|
62
|
+
* const users = await db.query<User>('SELECT * FROM users');
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function getPostgres(name = 'default') {
|
|
66
|
+
const instance = instances.get(name);
|
|
67
|
+
if (!instance) {
|
|
68
|
+
throw new Error(`PostgreSQL instance "${name}" not found. Did you register the postgres plugin?`);
|
|
69
|
+
}
|
|
70
|
+
return instance;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if a PostgreSQL instance is registered
|
|
74
|
+
*
|
|
75
|
+
* @param name - Instance name (default: 'default')
|
|
76
|
+
* @returns true if the instance exists
|
|
77
|
+
*/
|
|
78
|
+
export function hasPostgres(name = 'default') {
|
|
79
|
+
return instances.has(name);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create a PostgreSQL plugin
|
|
83
|
+
*
|
|
84
|
+
* @param config - PostgreSQL configuration
|
|
85
|
+
* @param instanceName - Name for this PostgreSQL instance (default: 'default')
|
|
86
|
+
* @returns A control panel plugin
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* createPostgresPlugin({
|
|
91
|
+
* url: process.env.DATABASE_URL,
|
|
92
|
+
* maxConnections: 20,
|
|
93
|
+
* healthCheck: true,
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export function createPostgresPlugin(config, instanceName = 'default') {
|
|
98
|
+
let pool = null;
|
|
99
|
+
const createInstance = () => {
|
|
100
|
+
if (!pool) {
|
|
101
|
+
pool = new Pool({
|
|
102
|
+
connectionString: config.url,
|
|
103
|
+
max: config.maxConnections ?? 20,
|
|
104
|
+
min: config.minConnections ?? 2,
|
|
105
|
+
idleTimeoutMillis: config.idleTimeoutMs ?? 30000,
|
|
106
|
+
connectionTimeoutMillis: config.connectionTimeoutMs ?? 5000,
|
|
107
|
+
statement_timeout: config.statementTimeoutMs,
|
|
108
|
+
});
|
|
109
|
+
// Handle pool errors
|
|
110
|
+
pool.on('error', (err) => {
|
|
111
|
+
if (config.onError) {
|
|
112
|
+
config.onError(err);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.error(`[database:${instanceName}] Pool error:`, err.message);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
// Call onConnect for each new client
|
|
119
|
+
if (config.onConnect) {
|
|
120
|
+
pool.on('connect', (client) => {
|
|
121
|
+
config.onConnect(client).catch((err) => {
|
|
122
|
+
console.error(`[database:${instanceName}] onConnect error:`, err.message);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const instance = {
|
|
128
|
+
async getClient() {
|
|
129
|
+
if (!pool)
|
|
130
|
+
throw new Error('Database pool not initialized');
|
|
131
|
+
return pool.connect();
|
|
132
|
+
},
|
|
133
|
+
async query(sql, params) {
|
|
134
|
+
if (!pool)
|
|
135
|
+
throw new Error('Database pool not initialized');
|
|
136
|
+
const result = await pool.query(sql, params);
|
|
137
|
+
return result.rows;
|
|
138
|
+
},
|
|
139
|
+
async queryOne(sql, params) {
|
|
140
|
+
const rows = await instance.query(sql, params);
|
|
141
|
+
return rows[0] ?? null;
|
|
142
|
+
},
|
|
143
|
+
async queryRaw(sql, params) {
|
|
144
|
+
if (!pool)
|
|
145
|
+
throw new Error('Database pool not initialized');
|
|
146
|
+
return pool.query(sql, params);
|
|
147
|
+
},
|
|
148
|
+
async transaction(callback) {
|
|
149
|
+
const client = await instance.getClient();
|
|
150
|
+
try {
|
|
151
|
+
await client.query('BEGIN');
|
|
152
|
+
const result = await callback(client);
|
|
153
|
+
await client.query('COMMIT');
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
await client.query('ROLLBACK');
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
client.release();
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
getPool() {
|
|
165
|
+
if (!pool)
|
|
166
|
+
throw new Error('Database pool not initialized');
|
|
167
|
+
return pool;
|
|
168
|
+
},
|
|
169
|
+
getStats() {
|
|
170
|
+
return {
|
|
171
|
+
total: pool?.totalCount ?? 0,
|
|
172
|
+
idle: pool?.idleCount ?? 0,
|
|
173
|
+
waiting: pool?.waitingCount ?? 0,
|
|
174
|
+
};
|
|
175
|
+
},
|
|
176
|
+
async close() {
|
|
177
|
+
if (pool) {
|
|
178
|
+
await pool.end();
|
|
179
|
+
pool = null;
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
return instance;
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
name: `postgres:${instanceName}`,
|
|
187
|
+
order: 5, // Initialize early, before other plugins that may need DB
|
|
188
|
+
async onInit(context) {
|
|
189
|
+
const { registerHealthCheck, logger } = context;
|
|
190
|
+
// Create and register the instance
|
|
191
|
+
const instance = createInstance();
|
|
192
|
+
instances.set(instanceName, instance);
|
|
193
|
+
// Test connection
|
|
194
|
+
try {
|
|
195
|
+
await instance.query('SELECT 1');
|
|
196
|
+
logger.debug(`PostgreSQL "${instanceName}" connected`);
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
logger.error(`PostgreSQL "${instanceName}" connection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
200
|
+
throw err;
|
|
201
|
+
}
|
|
202
|
+
// Register health check if enabled
|
|
203
|
+
if (config.healthCheck !== false) {
|
|
204
|
+
registerHealthCheck({
|
|
205
|
+
name: config.healthCheckName ?? 'postgres',
|
|
206
|
+
type: 'custom',
|
|
207
|
+
interval: config.healthCheckInterval ?? 30000,
|
|
208
|
+
timeout: 5000,
|
|
209
|
+
check: async () => {
|
|
210
|
+
const start = Date.now();
|
|
211
|
+
try {
|
|
212
|
+
await instance.query('SELECT 1');
|
|
213
|
+
const stats = instance.getStats();
|
|
214
|
+
return {
|
|
215
|
+
healthy: true,
|
|
216
|
+
latency: Date.now() - start,
|
|
217
|
+
details: {
|
|
218
|
+
pool: stats,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
return {
|
|
224
|
+
healthy: false,
|
|
225
|
+
latency: Date.now() - start,
|
|
226
|
+
details: {
|
|
227
|
+
error: err instanceof Error ? err.message : String(err),
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
async onShutdown() {
|
|
236
|
+
const instance = instances.get(instanceName);
|
|
237
|
+
if (instance) {
|
|
238
|
+
await instance.close();
|
|
239
|
+
instances.delete(instanceName);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=postgres-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-plugin.js","sourceRoot":"","sources":["../../src/plugins/postgres-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAqFpB,kDAAkD;AAClD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,IAAI,GAAG,SAAS;IAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,oDAAoD,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAI,GAAG,SAAS;IAC1C,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAA4B,EAC5B,YAAY,GAAG,SAAS;IAExB,IAAI,IAAI,GAAmB,IAAI,CAAC;IAEhC,MAAM,cAAc,GAAG,GAAqB,EAAE;QAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,IAAI,CAAC;gBACd,gBAAgB,EAAE,MAAM,CAAC,GAAG;gBAC5B,GAAG,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE;gBAChC,GAAG,EAAE,MAAM,CAAC,cAAc,IAAI,CAAC;gBAC/B,iBAAiB,EAAE,MAAM,CAAC,aAAa,IAAI,KAAK;gBAChD,uBAAuB,EAAE,MAAM,CAAC,mBAAmB,IAAI,IAAI;gBAC3D,iBAAiB,EAAE,MAAM,CAAC,kBAAkB;aAC7C,CAAC,CAAC;YAEH,qBAAqB;YACrB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,aAAa,YAAY,eAAe,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,qCAAqC;YACrC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;oBAC5B,MAAM,CAAC,SAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;wBACtC,OAAO,CAAC,KAAK,CAAC,aAAa,YAAY,oBAAoB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;oBAC5E,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAqB;YACjC,KAAK,CAAC,SAAS;gBACb,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;YAED,KAAK,CAAC,KAAK,CAA8B,GAAW,EAAE,MAAkB;gBACtE,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC7C,OAAO,MAAM,CAAC,IAAW,CAAC;YAC5B,CAAC;YAED,KAAK,CAAC,QAAQ,CAA8B,GAAW,EAAE,MAAkB;gBACzE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAI,GAAG,EAAE,MAAM,CAAC,CAAC;gBAClD,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACzB,CAAC;YAED,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,MAAkB;gBAC5C,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACjC,CAAC;YAED,KAAK,CAAC,WAAW,CAAI,QAAgC;gBACnD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC1C,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAC5B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;oBACtC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC7B,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBAC/B,MAAM,GAAG,CAAC;gBACZ,CAAC;wBAAS,CAAC;oBACT,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;YAED,OAAO;gBACL,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,QAAQ;gBACN,OAAO;oBACL,KAAK,EAAE,IAAI,EAAE,UAAU,IAAI,CAAC;oBAC5B,IAAI,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC;oBAC1B,OAAO,EAAE,IAAI,EAAE,YAAY,IAAI,CAAC;iBACjC,CAAC;YACJ,CAAC;YAED,KAAK,CAAC,KAAK;gBACT,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;oBACjB,IAAI,GAAG,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;SACF,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,YAAY,YAAY,EAAE;QAChC,KAAK,EAAE,CAAC,EAAE,0DAA0D;QAEpE,KAAK,CAAC,MAAM,CAAC,OAAsB;YACjC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;YAEhD,mCAAmC;YACnC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;YAClC,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAEtC,kBAAkB;YAClB,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACjC,MAAM,CAAC,KAAK,CAAC,eAAe,YAAY,aAAa,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,eAAe,YAAY,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpH,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,mCAAmC;YACnC,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;gBACjC,mBAAmB,CAAC;oBAClB,IAAI,EAAE,MAAM,CAAC,eAAe,IAAI,UAAU;oBAC1C,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK;oBAC7C,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,KAAK,IAAI,EAAE;wBAChB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBACzB,IAAI,CAAC;4BACH,MAAM,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;4BACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;4BAClC,OAAO;gCACL,OAAO,EAAE,IAAI;gCACb,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gCAC3B,OAAO,EAAE;oCACP,IAAI,EAAE,KAAK;iCACZ;6BACF,CAAC;wBACJ,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC;4BACb,OAAO;gCACL,OAAO,EAAE,KAAK;gCACd,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gCAC3B,OAAO,EAAE;oCACP,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iCACxD;6BACF,CAAC;wBACJ,CAAC;oBACH,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,CAAC,UAAU;YACd,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC7C,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACvB,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Plugin Tests
|
|
3
|
+
*
|
|
4
|
+
* Note: These tests use mocks since we don't want to require a real database.
|
|
5
|
+
* Integration tests should be run separately with a real PostgreSQL instance.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=postgres-plugin.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-plugin.test.d.ts","sourceRoot":"","sources":["../../src/plugins/postgres-plugin.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Plugin Tests
|
|
3
|
+
*
|
|
4
|
+
* Note: These tests use mocks since we don't want to require a real database.
|
|
5
|
+
* Integration tests should be run separately with a real PostgreSQL instance.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
// Mock pg before importing the plugin
|
|
9
|
+
vi.mock('pg', () => {
|
|
10
|
+
const mockClient = {
|
|
11
|
+
query: vi.fn().mockResolvedValue({ rows: [] }),
|
|
12
|
+
release: vi.fn(),
|
|
13
|
+
};
|
|
14
|
+
const mockPool = {
|
|
15
|
+
connect: vi.fn().mockResolvedValue(mockClient),
|
|
16
|
+
query: vi.fn().mockResolvedValue({ rows: [] }),
|
|
17
|
+
end: vi.fn().mockResolvedValue(undefined),
|
|
18
|
+
on: vi.fn(),
|
|
19
|
+
totalCount: 5,
|
|
20
|
+
idleCount: 3,
|
|
21
|
+
waitingCount: 0,
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
default: {
|
|
25
|
+
Pool: vi.fn(() => mockPool),
|
|
26
|
+
},
|
|
27
|
+
Pool: vi.fn(() => mockPool),
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
import { createPostgresPlugin, getPostgres, hasPostgres, } from './postgres-plugin.js';
|
|
31
|
+
describe('PostgreSQL Plugin', () => {
|
|
32
|
+
const mockConfig = {
|
|
33
|
+
url: 'postgresql://test:test@localhost:5432/testdb',
|
|
34
|
+
maxConnections: 10,
|
|
35
|
+
healthCheck: false, // Disable for unit tests
|
|
36
|
+
};
|
|
37
|
+
const mockContext = {
|
|
38
|
+
config: { productName: 'Test', port: 3000 },
|
|
39
|
+
app: {},
|
|
40
|
+
router: {},
|
|
41
|
+
logger: {
|
|
42
|
+
debug: vi.fn(),
|
|
43
|
+
info: vi.fn(),
|
|
44
|
+
warn: vi.fn(),
|
|
45
|
+
error: vi.fn(),
|
|
46
|
+
},
|
|
47
|
+
registerHealthCheck: vi.fn(),
|
|
48
|
+
};
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
vi.clearAllMocks();
|
|
51
|
+
});
|
|
52
|
+
afterEach(async () => {
|
|
53
|
+
// Clean up any registered instances
|
|
54
|
+
if (hasPostgres('test')) {
|
|
55
|
+
const db = getPostgres('test');
|
|
56
|
+
await db.close();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
describe('createPostgresPlugin', () => {
|
|
60
|
+
it('should create a plugin with correct name', () => {
|
|
61
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
62
|
+
expect(plugin.name).toBe('postgres:test');
|
|
63
|
+
});
|
|
64
|
+
it('should use "default" as instance name when not specified', () => {
|
|
65
|
+
const plugin = createPostgresPlugin(mockConfig);
|
|
66
|
+
expect(plugin.name).toBe('postgres:default');
|
|
67
|
+
});
|
|
68
|
+
it('should have low order number (initialize early)', () => {
|
|
69
|
+
const plugin = createPostgresPlugin(mockConfig);
|
|
70
|
+
expect(plugin.order).toBeLessThan(10);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe('onInit', () => {
|
|
74
|
+
it('should register the postgres instance', async () => {
|
|
75
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
76
|
+
await plugin.onInit?.(mockContext);
|
|
77
|
+
expect(hasPostgres('test')).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
it('should log debug message on successful connection', async () => {
|
|
80
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
81
|
+
await plugin.onInit?.(mockContext);
|
|
82
|
+
expect(mockContext.logger.debug).toHaveBeenCalledWith(expect.stringContaining('connected'));
|
|
83
|
+
});
|
|
84
|
+
it('should register health check when enabled', async () => {
|
|
85
|
+
const configWithHealth = { ...mockConfig, healthCheck: true };
|
|
86
|
+
const plugin = createPostgresPlugin(configWithHealth, 'test');
|
|
87
|
+
await plugin.onInit?.(mockContext);
|
|
88
|
+
expect(mockContext.registerHealthCheck).toHaveBeenCalledWith(expect.objectContaining({
|
|
89
|
+
name: 'postgres',
|
|
90
|
+
type: 'custom',
|
|
91
|
+
}));
|
|
92
|
+
});
|
|
93
|
+
it('should use custom health check name when provided', async () => {
|
|
94
|
+
const configWithCustomName = {
|
|
95
|
+
...mockConfig,
|
|
96
|
+
healthCheck: true,
|
|
97
|
+
healthCheckName: 'custom-db',
|
|
98
|
+
};
|
|
99
|
+
const plugin = createPostgresPlugin(configWithCustomName, 'test');
|
|
100
|
+
await plugin.onInit?.(mockContext);
|
|
101
|
+
expect(mockContext.registerHealthCheck).toHaveBeenCalledWith(expect.objectContaining({
|
|
102
|
+
name: 'custom-db',
|
|
103
|
+
}));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('getPostgres', () => {
|
|
107
|
+
it('should return registered instance', async () => {
|
|
108
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
109
|
+
await plugin.onInit?.(mockContext);
|
|
110
|
+
const db = getPostgres('test');
|
|
111
|
+
expect(db).toBeDefined();
|
|
112
|
+
expect(db.query).toBeDefined();
|
|
113
|
+
expect(db.queryOne).toBeDefined();
|
|
114
|
+
expect(db.transaction).toBeDefined();
|
|
115
|
+
});
|
|
116
|
+
it('should throw error for unregistered instance', () => {
|
|
117
|
+
expect(() => getPostgres('nonexistent')).toThrow('PostgreSQL instance "nonexistent" not found');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe('hasPostgres', () => {
|
|
121
|
+
it('should return false for unregistered instance', () => {
|
|
122
|
+
expect(hasPostgres('nonexistent')).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
it('should return true for registered instance', async () => {
|
|
125
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
126
|
+
await plugin.onInit?.(mockContext);
|
|
127
|
+
expect(hasPostgres('test')).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('PostgresInstance', () => {
|
|
131
|
+
it('should execute query and return rows', async () => {
|
|
132
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
133
|
+
await plugin.onInit?.(mockContext);
|
|
134
|
+
const db = getPostgres('test');
|
|
135
|
+
const result = await db.query('SELECT 1');
|
|
136
|
+
expect(result).toEqual([]);
|
|
137
|
+
});
|
|
138
|
+
it('should return null from queryOne when no rows', async () => {
|
|
139
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
140
|
+
await plugin.onInit?.(mockContext);
|
|
141
|
+
const db = getPostgres('test');
|
|
142
|
+
const result = await db.queryOne('SELECT 1');
|
|
143
|
+
expect(result).toBeNull();
|
|
144
|
+
});
|
|
145
|
+
it('should return pool stats', async () => {
|
|
146
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
147
|
+
await plugin.onInit?.(mockContext);
|
|
148
|
+
const db = getPostgres('test');
|
|
149
|
+
const stats = db.getStats();
|
|
150
|
+
expect(stats).toHaveProperty('total');
|
|
151
|
+
expect(stats).toHaveProperty('idle');
|
|
152
|
+
expect(stats).toHaveProperty('waiting');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe('onShutdown', () => {
|
|
156
|
+
it('should close pool and unregister instance', async () => {
|
|
157
|
+
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
158
|
+
await plugin.onInit?.(mockContext);
|
|
159
|
+
expect(hasPostgres('test')).toBe(true);
|
|
160
|
+
await plugin.onShutdown?.();
|
|
161
|
+
expect(hasPostgres('test')).toBe(false);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=postgres-plugin.test.js.map
|