@connorbritain/mssql-mcp-server 0.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.
- package/README.md +61 -0
- package/dist/audit/AuditLogger.d.ts +25 -0
- package/dist/audit/AuditLogger.d.ts.map +1 -0
- package/dist/audit/AuditLogger.js +91 -0
- package/dist/audit/AuditLogger.js.map +1 -0
- package/dist/config/EnvironmentManager.d.ts +36 -0
- package/dist/config/EnvironmentManager.d.ts.map +1 -0
- package/dist/config/EnvironmentManager.js +185 -0
- package/dist/config/EnvironmentManager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +615 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/CreateIndexTool.d.ts +24 -0
- package/dist/tools/CreateIndexTool.d.ts.map +1 -0
- package/dist/tools/CreateIndexTool.js +64 -0
- package/dist/tools/CreateIndexTool.js.map +1 -0
- package/dist/tools/CreateTableTool.d.ts +12 -0
- package/dist/tools/CreateTableTool.d.ts.map +1 -0
- package/dist/tools/CreateTableTool.js +49 -0
- package/dist/tools/CreateTableTool.js.map +1 -0
- package/dist/tools/DeleteDataTool.d.ts +56 -0
- package/dist/tools/DeleteDataTool.d.ts.map +1 -0
- package/dist/tools/DeleteDataTool.js +103 -0
- package/dist/tools/DeleteDataTool.js.map +1 -0
- package/dist/tools/DescribeTableTool.d.ts +20 -0
- package/dist/tools/DescribeTableTool.d.ts.map +1 -0
- package/dist/tools/DescribeTableTool.js +34 -0
- package/dist/tools/DescribeTableTool.js.map +1 -0
- package/dist/tools/DropTableTool.d.ts +12 -0
- package/dist/tools/DropTableTool.d.ts.map +1 -0
- package/dist/tools/DropTableTool.js +37 -0
- package/dist/tools/DropTableTool.js.map +1 -0
- package/dist/tools/ExplainQueryTool.d.ts +24 -0
- package/dist/tools/ExplainQueryTool.d.ts.map +1 -0
- package/dist/tools/ExplainQueryTool.js +98 -0
- package/dist/tools/ExplainQueryTool.js.map +1 -0
- package/dist/tools/InsertDataTool.d.ts +17 -0
- package/dist/tools/InsertDataTool.d.ts.map +1 -0
- package/dist/tools/InsertDataTool.js +144 -0
- package/dist/tools/InsertDataTool.js.map +1 -0
- package/dist/tools/ListTableTool.d.ts +18 -0
- package/dist/tools/ListTableTool.d.ts.map +1 -0
- package/dist/tools/ListTableTool.js +43 -0
- package/dist/tools/ListTableTool.js.map +1 -0
- package/dist/tools/ProfileTableTool.d.ts +78 -0
- package/dist/tools/ProfileTableTool.d.ts.map +1 -0
- package/dist/tools/ProfileTableTool.js +372 -0
- package/dist/tools/ProfileTableTool.js.map +1 -0
- package/dist/tools/ReadDataTool.d.ts +58 -0
- package/dist/tools/ReadDataTool.d.ts.map +1 -0
- package/dist/tools/ReadDataTool.js +265 -0
- package/dist/tools/ReadDataTool.js.map +1 -0
- package/dist/tools/RelationshipInspectorTool.d.ts +46 -0
- package/dist/tools/RelationshipInspectorTool.d.ts.map +1 -0
- package/dist/tools/RelationshipInspectorTool.js +155 -0
- package/dist/tools/RelationshipInspectorTool.js.map +1 -0
- package/dist/tools/SearchSchemaTool.d.ts +88 -0
- package/dist/tools/SearchSchemaTool.d.ts.map +1 -0
- package/dist/tools/SearchSchemaTool.js +236 -0
- package/dist/tools/SearchSchemaTool.js.map +1 -0
- package/dist/tools/TestConnectionTool.d.ts +36 -0
- package/dist/tools/TestConnectionTool.d.ts.map +1 -0
- package/dist/tools/TestConnectionTool.js +155 -0
- package/dist/tools/TestConnectionTool.js.map +1 -0
- package/dist/tools/UpdateDataTool.d.ts +61 -0
- package/dist/tools/UpdateDataTool.d.ts.map +1 -0
- package/dist/tools/UpdateDataTool.js +117 -0
- package/dist/tools/UpdateDataTool.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @connorbritain/mssql-mcp-server
|
|
2
|
+
|
|
3
|
+
Model Context Protocol server for SQL Server. This is the Node.js implementation.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @connorbritain/mssql-mcp-server@latest
|
|
9
|
+
# or run ad-hoc
|
|
10
|
+
npx @connorbritain/mssql-mcp-server@latest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## CLI
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
mssql-mcp-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The entrypoint expects env vars:
|
|
20
|
+
|
|
21
|
+
| Variable | Required | Notes |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `SERVER_NAME` | ✅ | SQL Server hostname/IP |
|
|
24
|
+
| `DATABASE_NAME` | ✅ | Database to target |
|
|
25
|
+
| `SQL_AUTH_MODE` | | `sql`, `windows`, or `aad` (default `aad`) |
|
|
26
|
+
| `SQL_USERNAME`/`SQL_PASSWORD` | | Required for `sql`/`windows` modes |
|
|
27
|
+
| `SQL_DOMAIN` | | Optional for NTLM |
|
|
28
|
+
| `SQL_PORT` | | Defaults to `1433` |
|
|
29
|
+
| `TRUST_SERVER_CERTIFICATE` | | Set `true` for dev/self-signed |
|
|
30
|
+
| `CONNECTION_TIMEOUT` | | Seconds, default `30` |
|
|
31
|
+
| `READONLY` | | `true` disables write tools |
|
|
32
|
+
| `PROFILE_SAMPLE_SIZE_DEFAULT` | | Default profiling sample size (default `50`) |
|
|
33
|
+
| `PROFILE_SAMPLE_RETURN_LIMIT` | | Max sample rows returned (default `10`) |
|
|
34
|
+
| `SEARCH_SCHEMA_DEFAULT_LIMIT` | | Default pagination size for `search_schema` (default `50`) |
|
|
35
|
+
|
|
36
|
+
## Example MCP config
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"mssql": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["@connorbritain/mssql-mcp-server@latest"],
|
|
44
|
+
"env": {
|
|
45
|
+
"SERVER_NAME": "127.0.0.1",
|
|
46
|
+
"DATABASE_NAME": "sampledb",
|
|
47
|
+
"SQL_AUTH_MODE": "sql",
|
|
48
|
+
"SQL_USERNAME": "sa",
|
|
49
|
+
"SQL_PASSWORD": "YourPassword123",
|
|
50
|
+
"READONLY": "false"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This package ships precompiled JS under `dist/`.
|
|
58
|
+
|
|
59
|
+
**Full documentation:** See the [main README](../../README.md) for complete feature list, configuration options, and safety guidance.
|
|
60
|
+
|
|
61
|
+
**Repository:** https://github.com/ConnorBritain/mssql-mcp-server
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface AuditLogEntry {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
toolName: string;
|
|
4
|
+
arguments?: Record<string, any>;
|
|
5
|
+
result?: {
|
|
6
|
+
success: boolean;
|
|
7
|
+
recordCount?: number;
|
|
8
|
+
error?: string;
|
|
9
|
+
};
|
|
10
|
+
durationMs?: number;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
userId?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class AuditLogger {
|
|
15
|
+
private readonly logFilePath;
|
|
16
|
+
private readonly enabled;
|
|
17
|
+
private readonly redactSensitiveData;
|
|
18
|
+
constructor();
|
|
19
|
+
private ensureLogDirectory;
|
|
20
|
+
private redactArguments;
|
|
21
|
+
log(entry: AuditLogEntry): void;
|
|
22
|
+
logToolInvocation(toolName: string, args: any, result: any, durationMs: number, sessionId?: string, userId?: string): void;
|
|
23
|
+
}
|
|
24
|
+
export declare const auditLogger: AuditLogger;
|
|
25
|
+
//# sourceMappingURL=AuditLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLogger.d.ts","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;;IAoB9C,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,eAAe;IA6BvB,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAkB/B,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,GAAG,EACX,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;CAiBR;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
export class AuditLogger {
|
|
4
|
+
constructor() {
|
|
5
|
+
// Read config from env vars
|
|
6
|
+
const logPath = process.env.AUDIT_LOG_PATH;
|
|
7
|
+
this.enabled = process.env.AUDIT_LOGGING !== "false"; // Enabled by default
|
|
8
|
+
this.redactSensitiveData = process.env.AUDIT_REDACT_SENSITIVE !== "false"; // Redact by default
|
|
9
|
+
if (this.enabled && logPath) {
|
|
10
|
+
this.logFilePath = path.resolve(logPath);
|
|
11
|
+
this.ensureLogDirectory();
|
|
12
|
+
}
|
|
13
|
+
else if (this.enabled) {
|
|
14
|
+
// Default to logs/audit.jsonl in the project root
|
|
15
|
+
this.logFilePath = path.resolve(process.cwd(), "logs", "audit.jsonl");
|
|
16
|
+
this.ensureLogDirectory();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
this.logFilePath = "";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
ensureLogDirectory() {
|
|
23
|
+
if (!this.logFilePath)
|
|
24
|
+
return;
|
|
25
|
+
const dir = path.dirname(this.logFilePath);
|
|
26
|
+
if (!fs.existsSync(dir)) {
|
|
27
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
redactArguments(args) {
|
|
31
|
+
if (!this.redactSensitiveData) {
|
|
32
|
+
return args;
|
|
33
|
+
}
|
|
34
|
+
const redacted = { ...args };
|
|
35
|
+
const sensitiveKeys = [
|
|
36
|
+
"password",
|
|
37
|
+
"secret",
|
|
38
|
+
"token",
|
|
39
|
+
"key",
|
|
40
|
+
"authorization",
|
|
41
|
+
"auth",
|
|
42
|
+
"credential",
|
|
43
|
+
];
|
|
44
|
+
for (const [key, value] of Object.entries(redacted)) {
|
|
45
|
+
const lowerKey = key.toLowerCase();
|
|
46
|
+
if (sensitiveKeys.some((sensitive) => lowerKey.includes(sensitive))) {
|
|
47
|
+
redacted[key] = "[REDACTED]";
|
|
48
|
+
}
|
|
49
|
+
else if (typeof value === "string" && value.length > 500) {
|
|
50
|
+
// Truncate very long strings (likely large query results)
|
|
51
|
+
redacted[key] = value.substring(0, 500) + "... [TRUNCATED]";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return redacted;
|
|
55
|
+
}
|
|
56
|
+
log(entry) {
|
|
57
|
+
if (!this.enabled || !this.logFilePath) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const logEntry = {
|
|
62
|
+
...entry,
|
|
63
|
+
arguments: entry.arguments ? this.redactArguments(entry.arguments) : undefined,
|
|
64
|
+
};
|
|
65
|
+
const logLine = JSON.stringify(logEntry) + "\n";
|
|
66
|
+
fs.appendFileSync(this.logFilePath, logLine, { encoding: "utf-8" });
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error("Failed to write audit log:", error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
logToolInvocation(toolName, args, result, durationMs, sessionId, userId) {
|
|
73
|
+
const entry = {
|
|
74
|
+
timestamp: new Date().toISOString(),
|
|
75
|
+
toolName,
|
|
76
|
+
arguments: args || {},
|
|
77
|
+
result: {
|
|
78
|
+
success: result?.success ?? false,
|
|
79
|
+
recordCount: result?.recordCount ?? result?.rowsAffected,
|
|
80
|
+
error: result?.error,
|
|
81
|
+
},
|
|
82
|
+
durationMs: Math.round(durationMs),
|
|
83
|
+
sessionId,
|
|
84
|
+
userId,
|
|
85
|
+
};
|
|
86
|
+
this.log(entry);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Singleton instance
|
|
90
|
+
export const auditLogger = new AuditLogger();
|
|
91
|
+
//# sourceMappingURL=AuditLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLogger.js","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import sql from "mssql";
|
|
2
|
+
export interface EnvironmentConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
server: string;
|
|
5
|
+
database: string;
|
|
6
|
+
port?: number;
|
|
7
|
+
authMode: "sql" | "windows" | "aad";
|
|
8
|
+
username?: string;
|
|
9
|
+
password?: string;
|
|
10
|
+
domain?: string;
|
|
11
|
+
trustServerCertificate?: boolean;
|
|
12
|
+
connectionTimeout?: number;
|
|
13
|
+
readonly?: boolean;
|
|
14
|
+
allowedTools?: string[];
|
|
15
|
+
maxRowsDefault?: number;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface EnvironmentsConfig {
|
|
19
|
+
defaultEnvironment?: string;
|
|
20
|
+
environments: EnvironmentConfig[];
|
|
21
|
+
}
|
|
22
|
+
export declare class EnvironmentManager {
|
|
23
|
+
private readonly environments;
|
|
24
|
+
private defaultEnvironment?;
|
|
25
|
+
private readonly connections;
|
|
26
|
+
constructor(configPath?: string);
|
|
27
|
+
private loadFromFile;
|
|
28
|
+
private loadFromEnvVars;
|
|
29
|
+
getEnvironment(name?: string): EnvironmentConfig;
|
|
30
|
+
listEnvironments(): EnvironmentConfig[];
|
|
31
|
+
getConnection(environmentName?: string): Promise<sql.ConnectionPool>;
|
|
32
|
+
private createSqlConfig;
|
|
33
|
+
closeAll(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare function getEnvironmentManager(): EnvironmentManager;
|
|
36
|
+
//# sourceMappingURL=EnvironmentManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentManager.d.ts","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,iBAAiB,EAAE,CAAC;CACnC;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,kBAAkB,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8D;gBAE9E,UAAU,CAAC,EAAE,MAAM;IAa/B,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,eAAe;IA+BvB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAahD,gBAAgB,IAAI,iBAAiB,EAAE;IAIjC,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YA2B5D,eAAe;IAoFvB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC;AAKD,wBAAgB,qBAAqB,IAAI,kBAAkB,CAM1D"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { InteractiveBrowserCredential } from "@azure/identity";
|
|
4
|
+
import sql from "mssql";
|
|
5
|
+
export class EnvironmentManager {
|
|
6
|
+
constructor(configPath) {
|
|
7
|
+
this.environments = new Map();
|
|
8
|
+
this.connections = new Map();
|
|
9
|
+
// Try to load from config file first
|
|
10
|
+
if (configPath) {
|
|
11
|
+
this.loadFromFile(configPath);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
// Fall back to environment variables for single environment
|
|
15
|
+
this.loadFromEnvVars();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
loadFromFile(configPath) {
|
|
19
|
+
try {
|
|
20
|
+
const resolvedPath = path.resolve(configPath);
|
|
21
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
22
|
+
console.warn(`Environment config file not found at ${resolvedPath}, falling back to env vars`);
|
|
23
|
+
this.loadFromEnvVars();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const configContent = fs.readFileSync(resolvedPath, "utf-8");
|
|
27
|
+
const config = JSON.parse(configContent);
|
|
28
|
+
this.defaultEnvironment = config.defaultEnvironment;
|
|
29
|
+
for (const env of config.environments) {
|
|
30
|
+
this.environments.set(env.name, env);
|
|
31
|
+
}
|
|
32
|
+
console.log(`Loaded ${this.environments.size} environment(s) from ${resolvedPath}`);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error(`Failed to load environment config: ${error}`);
|
|
36
|
+
this.loadFromEnvVars();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
loadFromEnvVars() {
|
|
40
|
+
const server = process.env.SERVER_NAME;
|
|
41
|
+
const database = process.env.DATABASE_NAME;
|
|
42
|
+
if (!server || !database) {
|
|
43
|
+
throw new Error("No environment config file provided and SERVER_NAME/DATABASE_NAME env vars not set");
|
|
44
|
+
}
|
|
45
|
+
const defaultEnv = {
|
|
46
|
+
name: "default",
|
|
47
|
+
server,
|
|
48
|
+
database,
|
|
49
|
+
port: process.env.SQL_PORT ? parseInt(process.env.SQL_PORT, 10) : undefined,
|
|
50
|
+
authMode: process.env.SQL_AUTH_MODE?.toLowerCase() ?? "aad",
|
|
51
|
+
username: process.env.SQL_USERNAME,
|
|
52
|
+
password: process.env.SQL_PASSWORD,
|
|
53
|
+
domain: process.env.SQL_DOMAIN,
|
|
54
|
+
trustServerCertificate: process.env.TRUST_SERVER_CERTIFICATE?.toLowerCase() === "true",
|
|
55
|
+
connectionTimeout: process.env.CONNECTION_TIMEOUT
|
|
56
|
+
? parseInt(process.env.CONNECTION_TIMEOUT, 10)
|
|
57
|
+
: 30,
|
|
58
|
+
readonly: process.env.READONLY === "true",
|
|
59
|
+
};
|
|
60
|
+
this.environments.set("default", defaultEnv);
|
|
61
|
+
this.defaultEnvironment = "default";
|
|
62
|
+
console.log("Loaded default environment from environment variables");
|
|
63
|
+
}
|
|
64
|
+
getEnvironment(name) {
|
|
65
|
+
const targetName = name || this.defaultEnvironment || "default";
|
|
66
|
+
const env = this.environments.get(targetName);
|
|
67
|
+
if (!env) {
|
|
68
|
+
throw new Error(`Environment '${targetName}' not found. Available: ${Array.from(this.environments.keys()).join(", ")}`);
|
|
69
|
+
}
|
|
70
|
+
return env;
|
|
71
|
+
}
|
|
72
|
+
listEnvironments() {
|
|
73
|
+
return Array.from(this.environments.values());
|
|
74
|
+
}
|
|
75
|
+
async getConnection(environmentName) {
|
|
76
|
+
const env = this.getEnvironment(environmentName);
|
|
77
|
+
const cached = this.connections.get(env.name);
|
|
78
|
+
// Check if we have a valid cached connection
|
|
79
|
+
if (cached &&
|
|
80
|
+
cached.pool.connected &&
|
|
81
|
+
(!cached.expiresOn || cached.expiresOn > new Date(Date.now() + 2 * 60 * 1000))) {
|
|
82
|
+
return cached.pool;
|
|
83
|
+
}
|
|
84
|
+
// Create new connection
|
|
85
|
+
const { config, expiresOn } = await this.createSqlConfig(env);
|
|
86
|
+
// Close old connection if exists
|
|
87
|
+
if (cached?.pool && cached.pool.connected) {
|
|
88
|
+
await cached.pool.close();
|
|
89
|
+
}
|
|
90
|
+
const pool = await sql.connect(config);
|
|
91
|
+
this.connections.set(env.name, { pool, expiresOn });
|
|
92
|
+
return pool;
|
|
93
|
+
}
|
|
94
|
+
async createSqlConfig(env) {
|
|
95
|
+
const baseConfig = {
|
|
96
|
+
server: env.server,
|
|
97
|
+
database: env.database,
|
|
98
|
+
port: env.port,
|
|
99
|
+
connectionTimeout: (env.connectionTimeout || 30) * 1000,
|
|
100
|
+
};
|
|
101
|
+
if (env.authMode === "sql") {
|
|
102
|
+
if (!env.username || !env.password) {
|
|
103
|
+
throw new Error(`Environment '${env.name}' requires username and password for SQL auth`);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
config: {
|
|
107
|
+
...baseConfig,
|
|
108
|
+
user: env.username,
|
|
109
|
+
password: env.password,
|
|
110
|
+
options: {
|
|
111
|
+
encrypt: false,
|
|
112
|
+
trustServerCertificate: env.trustServerCertificate ?? false,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (env.authMode === "windows") {
|
|
118
|
+
if (!env.username || !env.password) {
|
|
119
|
+
throw new Error(`Environment '${env.name}' requires username and password for Windows auth`);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
config: {
|
|
123
|
+
...baseConfig,
|
|
124
|
+
options: {
|
|
125
|
+
encrypt: false,
|
|
126
|
+
trustServerCertificate: env.trustServerCertificate ?? false,
|
|
127
|
+
},
|
|
128
|
+
authentication: {
|
|
129
|
+
type: "ntlm",
|
|
130
|
+
options: {
|
|
131
|
+
userName: env.username,
|
|
132
|
+
password: env.password,
|
|
133
|
+
domain: env.domain || "",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Azure AD auth
|
|
140
|
+
const credential = new InteractiveBrowserCredential({
|
|
141
|
+
redirectUri: "http://localhost",
|
|
142
|
+
});
|
|
143
|
+
const accessToken = await credential.getToken("https://database.windows.net/.default");
|
|
144
|
+
if (!accessToken?.token) {
|
|
145
|
+
throw new Error(`Failed to acquire Azure AD token for environment '${env.name}'`);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
config: {
|
|
149
|
+
...baseConfig,
|
|
150
|
+
options: {
|
|
151
|
+
encrypt: true,
|
|
152
|
+
trustServerCertificate: env.trustServerCertificate ?? false,
|
|
153
|
+
},
|
|
154
|
+
authentication: {
|
|
155
|
+
type: "azure-active-directory-access-token",
|
|
156
|
+
options: {
|
|
157
|
+
token: accessToken.token,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
expiresOn: accessToken?.expiresOnTimestamp
|
|
162
|
+
? new Date(accessToken.expiresOnTimestamp)
|
|
163
|
+
: new Date(Date.now() + 30 * 60 * 1000),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async closeAll() {
|
|
167
|
+
for (const [name, { pool }] of this.connections.entries()) {
|
|
168
|
+
if (pool.connected) {
|
|
169
|
+
await pool.close();
|
|
170
|
+
console.log(`Closed connection for environment '${name}'`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this.connections.clear();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Singleton instance
|
|
177
|
+
let environmentManager;
|
|
178
|
+
export function getEnvironmentManager() {
|
|
179
|
+
if (!environmentManager) {
|
|
180
|
+
const configPath = process.env.ENVIRONMENTS_CONFIG_PATH;
|
|
181
|
+
environmentManager = new EnvironmentManager(configPath);
|
|
182
|
+
}
|
|
183
|
+
return environmentManager;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=EnvironmentManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentManager.js","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,GAAG,MAAM,OAAO,CAAC;AAwBxB,MAAM,OAAO,kBAAkB;IAK7B,YAAY,UAAmB;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;QAE7B,qCAAqC;QACrC,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,4DAA4D;YAC5D,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,UAAkB;QACrC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,wCAAwC,YAAY,4BAA4B,CAAC,CAAC;gBAC/F,IAAI,CAAC,eAAe,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;YAED,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAuB,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAE7D,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;YAEpD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACtC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,IAAI,wBAAwB,YAAY,EAAE,CAAC,CAAC;QACtF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QAE3C,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAsB;YACpC,IAAI,EAAE,SAAS;YACf,MAAM;YACN,QAAQ;YACR,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;YAC3E,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,EAAU,IAAI,KAAK;YACpE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YAClC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YAClC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;YAC9B,sBAAsB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,EAAE,KAAK,MAAM;YACtF,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;gBAC/C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAC9C,CAAC,CAAC,EAAE;YACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;SAC1C,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACvE,CAAC;IAED,cAAc,CAAC,IAAa;QAC1B,MAAM,UAAU,GAAG,IAAI,IAAI,IAAI,CAAC,kBAAkB,IAAI,SAAS,CAAC;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE9C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,gBAAgB,UAAU,2BAA2B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvG,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAED,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,eAAwB;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE9C,6CAA6C;QAC7C,IACE,MAAM;YACN,MAAM,CAAC,IAAI,CAAC,SAAS;YACrB,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,EAC9E,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,wBAAwB;QACxB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAE9D,iCAAiC;QACjC,IAAI,MAAM,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAEpD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,GAAsB;QAEtB,MAAM,UAAU,GAAG;YACjB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,iBAAiB,EAAE,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,GAAG,IAAI;SACxD,CAAC;QAEF,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,IAAI,+CAA+C,CAAC,CAAC;YAC3F,CAAC;YAED,OAAO;gBACL,MAAM,EAAE;oBACN,GAAG,UAAU;oBACb,IAAI,EAAE,GAAG,CAAC,QAAQ;oBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE;wBACP,OAAO,EAAE,KAAK;wBACd,sBAAsB,EAAE,GAAG,CAAC,sBAAsB,IAAI,KAAK;qBAC5D;iBACF;aACF,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,gBAAgB,GAAG,CAAC,IAAI,mDAAmD,CAC5E,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,MAAM,EAAE;oBACN,GAAG,UAAU;oBACb,OAAO,EAAE;wBACP,OAAO,EAAE,KAAK;wBACd,sBAAsB,EAAE,GAAG,CAAC,sBAAsB,IAAI,KAAK;qBAC5D;oBACD,cAAc,EAAE;wBACd,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,QAAQ,EAAE,GAAG,CAAC,QAAQ;4BACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;4BACtB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;yBACzB;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,gBAAgB;QAChB,MAAM,UAAU,GAAG,IAAI,4BAA4B,CAAC;YAClD,WAAW,EAAE,kBAAkB;SAChC,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC;QAEvF,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,qDAAqD,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QACpF,CAAC;QAED,OAAO;YACL,MAAM,EAAE;gBACN,GAAG,UAAU;gBACb,OAAO,EAAE;oBACP,OAAO,EAAE,IAAI;oBACb,sBAAsB,EAAE,GAAG,CAAC,sBAAsB,IAAI,KAAK;iBAC5D;gBACD,cAAc,EAAE;oBACd,IAAI,EAAE,qCAAqC;oBAC3C,OAAO,EAAE;wBACP,KAAK,EAAE,WAAW,CAAC,KAAK;qBACzB;iBACF;aACF;YACD,SAAS,EAAE,WAAW,EAAE,kBAAkB;gBACxC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;gBAC1C,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,sCAAsC,IAAI,GAAG,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,qBAAqB;AACrB,IAAI,kBAAsC,CAAC;AAE3C,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACxD,kBAAkB,GAAG,IAAI,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|