@calebmabry/postgres-mcp-server 2.0.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 (63) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +203 -0
  3. package/dist/config.d.ts +47 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +51 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/db.d.ts +46 -0
  8. package/dist/db.d.ts.map +1 -0
  9. package/dist/db.js +142 -0
  10. package/dist/db.js.map +1 -0
  11. package/dist/http-server.d.ts +3 -0
  12. package/dist/http-server.d.ts.map +1 -0
  13. package/dist/http-server.js +184 -0
  14. package/dist/http-server.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +33 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/logger.d.ts +8 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +85 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/register-tools.d.ts +6 -0
  24. package/dist/register-tools.d.ts.map +1 -0
  25. package/dist/register-tools.js +83 -0
  26. package/dist/register-tools.js.map +1 -0
  27. package/dist/tools/describe.d.ts +31 -0
  28. package/dist/tools/describe.d.ts.map +1 -0
  29. package/dist/tools/describe.js +61 -0
  30. package/dist/tools/describe.js.map +1 -0
  31. package/dist/tools/functions.d.ts +20 -0
  32. package/dist/tools/functions.d.ts.map +1 -0
  33. package/dist/tools/functions.js +65 -0
  34. package/dist/tools/functions.js.map +1 -0
  35. package/dist/tools/indexes.d.ts +17 -0
  36. package/dist/tools/indexes.d.ts.map +1 -0
  37. package/dist/tools/indexes.js +82 -0
  38. package/dist/tools/indexes.js.map +1 -0
  39. package/dist/tools/list.d.ts +22 -0
  40. package/dist/tools/list.d.ts.map +1 -0
  41. package/dist/tools/list.js +64 -0
  42. package/dist/tools/list.js.map +1 -0
  43. package/dist/tools/performance.d.ts +26 -0
  44. package/dist/tools/performance.d.ts.map +1 -0
  45. package/dist/tools/performance.js +125 -0
  46. package/dist/tools/performance.js.map +1 -0
  47. package/dist/tools/query.d.ts +6 -0
  48. package/dist/tools/query.d.ts.map +1 -0
  49. package/dist/tools/query.js +318 -0
  50. package/dist/tools/query.js.map +1 -0
  51. package/dist/tools/schemas.d.ts +10 -0
  52. package/dist/tools/schemas.d.ts.map +1 -0
  53. package/dist/tools/schemas.js +51 -0
  54. package/dist/tools/schemas.js.map +1 -0
  55. package/dist/validation.d.ts +159 -0
  56. package/dist/validation.d.ts.map +1 -0
  57. package/dist/validation.js +90 -0
  58. package/dist/validation.js.map +1 -0
  59. package/dist/version.d.ts +3 -0
  60. package/dist/version.d.ts.map +1 -0
  61. package/dist/version.js +11 -0
  62. package/dist/version.js.map +1 -0
  63. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025, abiswas97
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # Postgres MCP Server
2
+
3
+ [![npm version](https://badge.fury.io/js/@calebmabry%2Fpostgres-mcp-server.svg)](https://www.npmjs.com/package/@calebmabry/postgres-mcp-server)
4
+ [![Tests](https://github.com/caleb-mabry/postgres-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/caleb-mabry/postgres-mcp/actions/workflows/test.yml)
5
+ [![GitHub issues](https://img.shields.io/github/issues/caleb-mabry/postgres-mcp)](https://github.com/caleb-mabry/postgres-mcp/issues)
6
+ [![Documentation](https://img.shields.io/badge/docs-docusaurus-blue)](https://caleb-mabry.github.io/postgres-mcp/)
7
+
8
+ A Model Context Protocol (MCP) server that provides secure database access to PostgreSQL through Kysely ORM. This server enables Claude Desktop to interact with PostgreSQL databases using natural language.
9
+
10
+ ## 📚 Documentation
11
+
12
+ **Full documentation is available at: [caleb-mabry.github.io/postgres-mcp](https://caleb-mabry.github.io/postgres-mcp/)**
13
+
14
+ ## Features
15
+
16
+ - **MCP Tools**: Query execution, table listing, schema inspection, and constraint information
17
+ - **Type Safety**: Full TypeScript support with typed inputs/outputs
18
+ - **Connection Pooling**: Configurable connection limits with idle timeout
19
+ - **Error Handling**: Graceful error messages for connection and query issues
20
+ - **Security**: Parameterized queries to prevent SQL injection
21
+
22
+ ## Quick Start
23
+
24
+ ### For Claude Desktop Users
25
+
26
+ 👉 **See [CLAUDE_SETUP.md](./CLAUDE_SETUP.md) for complete Claude Desktop setup instructions**
27
+
28
+ ### For HTTP/API Usage
29
+
30
+ See [HTTP_SERVER.md](./HTTP_SERVER.md) for HTTP transport setup
31
+
32
+ ### Direct Installation
33
+
34
+ ```bash
35
+ npx -y @calebmabry/postgres-mcp-server
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ Create a `.env` file with your database credentials:
41
+
42
+ ```env
43
+ DB_HOST=127.0.0.1
44
+ DB_PORT=5432
45
+ DB_USER=postgres
46
+ DB_PASSWORD=your_password_here
47
+ DB_NAME=postgres
48
+ DB_SSL=true
49
+ ```
50
+
51
+ ## Available Tools
52
+
53
+ | Tool | Description | Required Parameters | Optional Parameters |
54
+ | --------------------- | ------------------------------------------- | ----------------------------------- | ----------------------------------------------------------- |
55
+ | **`query`** | Execute SQL queries with pagination support | `sql` (string) | `pageSize` (1-500), `offset` (number), `parameters` (array) |
56
+ | **`describe_table`** | Get table structure and column details | `schema` (string), `table` (string) | - |
57
+ | **`list_tables`** | List all tables in a schema | `schema` (string) | - |
58
+ | **`list_schemas`** | List all schemas in the database | - | `includeSystemSchemas` (boolean) |
59
+ | **`get_constraints`** | Get table constraints (PK, FK, etc.) | `schema` (string), `table` (string) | - |
60
+ | **`list_indexes`** | List indexes for a table or schema | `schema` (string) | `table` (string) |
61
+ | **`list_views`** | List views in a schema | `schema` (string) | - |
62
+ | **`list_functions`** | List functions and procedures | `schema` (string) | - |
63
+ | **`explain_query`** | Get query execution plan | `sql` (string) | `analyze` (boolean), `format` (text/json/xml/yaml) |
64
+ | **`get_table_stats`** | Get table size and statistics | `schema` (string) | `table` (string) |
65
+
66
+ ### Key Features
67
+
68
+ - **Pagination**: Query tool supports up to 500 rows per page with automatic LIMIT/OFFSET handling
69
+ - **Security**: Parameterized queries prevent SQL injection, READ_ONLY mode by default
70
+ - **Type Safety**: Full TypeScript support with Zod schema validation
71
+
72
+ ## Client Configuration
73
+
74
+ The postgres-mcp-server works with any MCP-compatible client. See configuration examples below:
75
+
76
+ ### Claude Desktop
77
+
78
+ Add to `claude_desktop_config.json`:
79
+
80
+ ```json
81
+ {
82
+ "mcpServers": {
83
+ "postgres-mcp-server": {
84
+ "command": "npx",
85
+ "args": ["-y", "@calebmabry/postgres-mcp-server"],
86
+ "env": {
87
+ "DB_HOST": "127.0.0.1",
88
+ "DB_PORT": "5432",
89
+ "DB_USER": "postgres",
90
+ "DB_PASSWORD": "your_password_here",
91
+ "DB_NAME": "your_database_name",
92
+ "DB_SSL": "false",
93
+ "READ_ONLY": "true"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ **Config locations:**
101
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
102
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
103
+
104
+ See [claude_config_example.json](./claude_config_example.json) for a full example.
105
+
106
+ ### Cline (VS Code)
107
+
108
+ Add to `.cline/mcp_settings.json`:
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "postgres-mcp-server": {
114
+ "command": "npx",
115
+ "args": ["-y", "@calebmabry/postgres-mcp-server"],
116
+ "env": {
117
+ "DB_HOST": "localhost",
118
+ "DB_NAME": "your_database",
119
+ "DB_USER": "postgres",
120
+ "DB_PASSWORD": "your_password"
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ See [cline_mcp_settings_example.json](./cline_mcp_settings_example.json) for a full example.
128
+
129
+ ### Zed Editor
130
+
131
+ Add to Zed settings (Settings → Context Servers):
132
+
133
+ ```json
134
+ {
135
+ "context_servers": {
136
+ "postgres-mcp-server": {
137
+ "command": {
138
+ "path": "npx",
139
+ "args": ["-y", "@calebmabry/postgres-mcp-server"]
140
+ },
141
+ "settings": {
142
+ "DB_HOST": "localhost",
143
+ "DB_NAME": "your_database",
144
+ "DB_USER": "postgres",
145
+ "DB_PASSWORD": "your_password"
146
+ }
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ See [zed_settings_example.json](./zed_settings_example.json) for a full example.
153
+
154
+ ### Docker
155
+
156
+ Use the included Dockerfile or docker-compose.yml:
157
+
158
+ ```bash
159
+ docker-compose up -d
160
+ ```
161
+
162
+ See [docker-compose.example.yml](./docker-compose.example.yml) for a full example.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ # Clone and install dependencies
168
+ git clone https://github.com/caleb-mabry/postgres-mcp.git
169
+ cd postgres-mcp-server
170
+ npm install
171
+
172
+ # Run in development mode with hot reload
173
+ npm run dev
174
+
175
+ # Build for production
176
+ npm run build
177
+
178
+ # Run tests
179
+ npm run test
180
+
181
+ # Run specific test suites
182
+ npm run test:unit
183
+ npm run test:integration
184
+ ```
185
+
186
+ ## Environment Variables
187
+
188
+ | Variable | Default | Description |
189
+ | ------------------- | ----------- | --------------------------------------- |
190
+ | `DB_HOST` | `127.0.0.1` | PostgreSQL host |
191
+ | `DB_PORT` | `5432` | PostgreSQL port |
192
+ | `DB_USER` | `postgres` | Database user |
193
+ | `DB_PASSWORD` | _required_ | Database password |
194
+ | `DB_NAME` | `postgres` | Database name |
195
+ | `DB_SSL` | `true` | Enable SSL connection |
196
+ | `READ_ONLY` | `true` | Restrict to SELECT/WITH/EXPLAIN queries |
197
+ | `QUERY_TIMEOUT` | `30000` | Query timeout in milliseconds |
198
+ | `MAX_PAGE_SIZE` | `500` | Maximum rows per page |
199
+ | `DEFAULT_PAGE_SIZE` | `100` | Default page size when not specified |
200
+
201
+ ## License
202
+
203
+ ISC
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Centralized configuration management for environment variables
3
+ */
4
+ export interface AppConfig {
5
+ db: {
6
+ host: string;
7
+ port: number;
8
+ user: string;
9
+ password: string;
10
+ database: string;
11
+ maxConnections: number;
12
+ idleTimeoutMs: number;
13
+ connectionTimeoutMs: number;
14
+ queryTimeoutMs: number;
15
+ ssl: {
16
+ enabled: boolean;
17
+ rejectUnauthorized: boolean;
18
+ caCert?: string;
19
+ allowSelfSigned: boolean;
20
+ };
21
+ };
22
+ server: {
23
+ port: number;
24
+ allowedHosts?: string;
25
+ };
26
+ query: {
27
+ maxPageSize: number;
28
+ defaultPageSize: number;
29
+ autoLimit: boolean;
30
+ maxPayloadSize: number;
31
+ };
32
+ app: {
33
+ readOnly: boolean;
34
+ logLevel: "debug" | "info" | "warn" | "error";
35
+ };
36
+ }
37
+ /**
38
+ * Load and validate configuration from environment variables
39
+ * @param forceReload - Force reloading from environment variables (useful for tests)
40
+ */
41
+ export declare function loadConfig(forceReload?: boolean): AppConfig;
42
+ /**
43
+ * Singleton configuration instance
44
+ * Can be accessed directly for most use cases
45
+ */
46
+ export declare const config: AppConfig;
47
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,SAAS;IAExB,EAAE,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,cAAc,EAAE,MAAM,CAAC;QACvB,GAAG,EAAE;YACH,OAAO,EAAE,OAAO,CAAC;YACjB,kBAAkB,EAAE,OAAO,CAAC;YAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,eAAe,EAAE,OAAO,CAAC;SAC1B,CAAC;KACH,CAAC;IAGF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAGF,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAGF,GAAG,EAAE;QACH,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;KAC/C,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,WAAW,UAAQ,GAAG,SAAS,CA+CzD;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAwB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Centralized configuration management for environment variables
3
+ */
4
+ /**
5
+ * Load and validate configuration from environment variables
6
+ * @param forceReload - Force reloading from environment variables (useful for tests)
7
+ */
8
+ export function loadConfig(forceReload = false) {
9
+ // For DB_PASSWORD, allow it to be empty in test/dev environments
10
+ // but it will still be required for actual DB connections
11
+ const dbPassword = process.env.DB_PASSWORD || "";
12
+ return {
13
+ db: {
14
+ host: process.env.DB_HOST || "127.0.0.1",
15
+ port: parseInt(process.env.DB_PORT || "5432", 10),
16
+ user: process.env.DB_USER || "postgres",
17
+ password: dbPassword,
18
+ database: process.env.DB_NAME || "postgres",
19
+ maxConnections: parseInt(process.env.DB_POOL_MAX || "5", 10),
20
+ idleTimeoutMs: parseInt(process.env.DB_IDLE_TIMEOUT || "5000", 10),
21
+ connectionTimeoutMs: parseInt(process.env.DB_CONNECTION_TIMEOUT || "10000", 10),
22
+ queryTimeoutMs: parseInt(process.env.DB_QUERY_TIMEOUT || "30000", 10),
23
+ ssl: {
24
+ enabled: process.env.DB_SSL !== "false",
25
+ rejectUnauthorized: process.env.DB_SSL_REJECT_UNAUTHORIZED !== "false",
26
+ caCert: process.env.DB_SSL_CA_CERT,
27
+ allowSelfSigned: process.env.DB_SSL_ALLOW_SELF_SIGNED === "true",
28
+ },
29
+ },
30
+ server: {
31
+ port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3000,
32
+ allowedHosts: process.env.ALLOWED_HOSTS,
33
+ },
34
+ query: {
35
+ maxPageSize: parseInt(process.env.MAX_PAGE_SIZE || "500", 10),
36
+ defaultPageSize: parseInt(process.env.DEFAULT_PAGE_SIZE || "100", 10),
37
+ autoLimit: process.env.AUTO_LIMIT !== "false",
38
+ maxPayloadSize: parseInt(process.env.MAX_PAYLOAD_SIZE || String(5 * 1024 * 1024), 10),
39
+ },
40
+ app: {
41
+ readOnly: process.env.READ_ONLY !== "false",
42
+ logLevel: process.env.LOG_LEVEL || "info",
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Singleton configuration instance
48
+ * Can be accessed directly for most use cases
49
+ */
50
+ export const config = loadConfig();
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2CH;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,WAAW,GAAG,KAAK;IAC5C,iEAAiE;IACjE,0DAA0D;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAEjD,OAAO;QACL,EAAE,EAAE;YACF,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,WAAW;YACxC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,MAAM,EAAE,EAAE,CAAC;YACjD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,UAAU;YACvC,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,UAAU;YAC3C,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,EAAE,EAAE,CAAC;YAC5D,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,MAAM,EAAE,EAAE,CAAC;YAClE,mBAAmB,EAAE,QAAQ,CAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,EAC5C,EAAE,CACH;YACD,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,EAAE,EAAE,CAAC;YACrE,GAAG,EAAE;gBACH,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,OAAO;gBACvC,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,OAAO;gBACtE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;gBAClC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,MAAM;aACjE;SACF;QAED,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9D,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;SACxC;QAED,KAAK,EAAE;YACL,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,KAAK,EAAE,EAAE,CAAC;YAC7D,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,KAAK,EAAE,EAAE,CAAC;YACrE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO;YAC7C,cAAc,EAAE,QAAQ,CACtB,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,EACvD,EAAE,CACH;SACF;QAED,GAAG,EAAE;YACH,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO;YAC3C,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,SAA0C,IAAI,MAAM;SAC5E;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAc,UAAU,EAAE,CAAC"}
package/dist/db.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { Kysely } from "kysely";
2
+ import { Pool } from "pg";
3
+ export interface Database {
4
+ [key: string]: any;
5
+ }
6
+ export interface DatabaseConfig {
7
+ host: string;
8
+ port: number;
9
+ user: string;
10
+ password: string;
11
+ database: string;
12
+ maxConnections: number;
13
+ idleTimeoutMs: number;
14
+ ssl: boolean | {
15
+ rejectUnauthorized: boolean;
16
+ ca?: string;
17
+ };
18
+ connectionTimeoutMs: number;
19
+ queryTimeoutMs: number;
20
+ }
21
+ declare class DatabaseManager {
22
+ private static instance;
23
+ private db;
24
+ private pool;
25
+ private config;
26
+ private constructor();
27
+ static getInstance(): DatabaseManager;
28
+ private loadConfig;
29
+ private buildSSLConfig;
30
+ getDatabase(): Kysely<Database>;
31
+ private connect;
32
+ close(): Promise<void>;
33
+ healthCheck(): Promise<{
34
+ healthy: boolean;
35
+ error?: string;
36
+ }>;
37
+ getConfig(): DatabaseConfig;
38
+ getPool(): Pool;
39
+ isConnected(): boolean;
40
+ }
41
+ export declare function getDb(): Kysely<Database>;
42
+ export declare function closeDb(): Promise<void>;
43
+ export declare function getPool(): Pool;
44
+ export declare function getDbManager(): DatabaseManager;
45
+ export {};
46
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmB,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAOtC,MAAM,WAAW,QAAQ;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,OAAO,GAAG;QAAE,kBAAkB,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,OAAO,CAAC,EAAE,CAAiC;IAC3C,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAiB;IAE/B,OAAO;WAIO,WAAW,IAAI,eAAe;IAO5C,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,cAAc;IAwBf,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC;IAOtC,OAAO,CAAC,OAAO;IAoCF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,WAAW,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsBlE,SAAS,IAAI,cAAc;IAI3B,OAAO,IAAI,IAAI;IAOf,WAAW,IAAI,OAAO;CAG9B;AAED,wBAAgB,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,CAExC;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7C;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B;AAED,wBAAgB,YAAY,IAAI,eAAe,CAE9C"}
package/dist/db.js ADDED
@@ -0,0 +1,142 @@
1
+ import { Kysely, PostgresDialect } from "kysely";
2
+ import { Pool } from "pg";
3
+ import * as dotenv from "dotenv";
4
+ import { config } from "./config.js";
5
+ import { log } from "./logger.js";
6
+ dotenv.config();
7
+ class DatabaseManager {
8
+ static instance = null;
9
+ db = null;
10
+ pool = null;
11
+ config;
12
+ constructor() {
13
+ this.config = this.loadConfig();
14
+ }
15
+ static getInstance() {
16
+ if (!DatabaseManager.instance) {
17
+ DatabaseManager.instance = new DatabaseManager();
18
+ }
19
+ return DatabaseManager.instance;
20
+ }
21
+ loadConfig() {
22
+ return {
23
+ host: config.db.host,
24
+ port: config.db.port,
25
+ user: config.db.user,
26
+ password: config.db.password,
27
+ database: config.db.database,
28
+ maxConnections: config.db.maxConnections,
29
+ idleTimeoutMs: config.db.idleTimeoutMs,
30
+ connectionTimeoutMs: config.db.connectionTimeoutMs,
31
+ queryTimeoutMs: config.db.queryTimeoutMs,
32
+ ssl: this.buildSSLConfig(),
33
+ };
34
+ }
35
+ buildSSLConfig() {
36
+ if (!config.db.ssl.enabled) {
37
+ return false;
38
+ }
39
+ const sslConfig = {
40
+ rejectUnauthorized: config.db.ssl.rejectUnauthorized,
41
+ };
42
+ // Add CA certificate if provided
43
+ if (config.db.ssl.caCert) {
44
+ sslConfig.ca = config.db.ssl.caCert;
45
+ }
46
+ // For when explicitly allowing self-signed certs
47
+ if (config.db.ssl.allowSelfSigned) {
48
+ sslConfig.rejectUnauthorized = false;
49
+ }
50
+ return sslConfig;
51
+ }
52
+ getDatabase() {
53
+ if (!this.db) {
54
+ this.connect();
55
+ }
56
+ return this.db;
57
+ }
58
+ connect() {
59
+ if (this.db) {
60
+ return;
61
+ }
62
+ const poolConfig = {
63
+ host: this.config.host,
64
+ port: this.config.port,
65
+ user: this.config.user,
66
+ password: this.config.password,
67
+ database: this.config.database,
68
+ max: this.config.maxConnections,
69
+ idleTimeoutMillis: this.config.idleTimeoutMs,
70
+ connectionTimeoutMillis: this.config.connectionTimeoutMs,
71
+ statement_timeout: this.config.queryTimeoutMs,
72
+ query_timeout: this.config.queryTimeoutMs,
73
+ ssl: this.config.ssl,
74
+ };
75
+ this.pool = new Pool(poolConfig);
76
+ this.pool.on("error", (err) => {
77
+ log.error(`Pool error: ${err.message}`, "db", { code: err.code });
78
+ });
79
+ this.pool.on("connect", () => {
80
+ log.debug("New pool connection established", "db");
81
+ });
82
+ this.db = new Kysely({
83
+ dialect: new PostgresDialect({
84
+ pool: this.pool,
85
+ }),
86
+ });
87
+ }
88
+ async close() {
89
+ if (this.db) {
90
+ await this.db.destroy();
91
+ this.db = null;
92
+ }
93
+ if (this.pool && !this.pool.ended) {
94
+ await this.pool.end();
95
+ this.pool = null;
96
+ }
97
+ }
98
+ async healthCheck() {
99
+ try {
100
+ if (!this.db) {
101
+ this.connect();
102
+ }
103
+ await this.db.selectFrom("information_schema.tables")
104
+ .select("table_name")
105
+ .limit(1)
106
+ .execute();
107
+ return { healthy: true };
108
+ }
109
+ catch (error) {
110
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
111
+ return {
112
+ healthy: false,
113
+ error: errorMessage,
114
+ };
115
+ }
116
+ }
117
+ getConfig() {
118
+ return { ...this.config }; // Return a copy to prevent modification
119
+ }
120
+ getPool() {
121
+ if (!this.pool) {
122
+ this.connect();
123
+ }
124
+ return this.pool;
125
+ }
126
+ isConnected() {
127
+ return this.db !== null && this.pool !== null;
128
+ }
129
+ }
130
+ export function getDb() {
131
+ return DatabaseManager.getInstance().getDatabase();
132
+ }
133
+ export async function closeDb() {
134
+ await DatabaseManager.getInstance().close();
135
+ }
136
+ export function getPool() {
137
+ return DatabaseManager.getInstance().getPool();
138
+ }
139
+ export function getDbManager() {
140
+ return DatabaseManager.getInstance();
141
+ }
142
+ //# sourceMappingURL=db.js.map
package/dist/db.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":""}