@eamonboyle/mssql-mcp 1.5.0 → 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.
- package/README.md +379 -361
- package/dist/apps/queryResultsApp.d.ts +18 -0
- package/dist/apps/queryResultsApp.d.ts.map +1 -0
- package/dist/apps/queryResultsApp.js +272 -0
- package/dist/apps/queryResultsApp.js.map +1 -0
- package/dist/checkNodeVersion.d.ts +2 -0
- package/dist/checkNodeVersion.d.ts.map +1 -0
- package/dist/checkNodeVersion.js +9 -0
- package/dist/checkNodeVersion.js.map +1 -0
- package/dist/config.d.ts +58 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +202 -33
- package/dist/config.js.map +1 -1
- package/dist/confirmationMessage.d.ts +2 -0
- package/dist/confirmationMessage.d.ts.map +1 -0
- package/dist/confirmationMessage.js +105 -0
- package/dist/confirmationMessage.js.map +1 -0
- package/dist/db.d.ts +24 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +152 -36
- package/dist/db.js.map +1 -1
- package/dist/filteredRead.js +0 -0
- package/dist/httpServer.d.ts +25 -0
- package/dist/httpServer.d.ts.map +1 -0
- package/dist/httpServer.js +128 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -366
- package/dist/index.js.map +1 -1
- package/dist/mcpResults.d.ts +1 -1
- package/dist/mcpResults.d.ts.map +1 -1
- package/dist/mcpResults.js +2 -2
- package/dist/mcpResults.js.map +1 -1
- package/dist/nodeVersion.d.ts +14 -0
- package/dist/nodeVersion.d.ts.map +1 -0
- package/dist/nodeVersion.js +23 -0
- package/dist/nodeVersion.js.map +1 -0
- package/dist/packageInfo.d.ts +3 -0
- package/dist/packageInfo.d.ts.map +1 -0
- package/dist/packageInfo.js +5 -0
- package/dist/packageInfo.js.map +1 -0
- package/dist/promptRegistry.d.ts +1 -1
- package/dist/promptRegistry.d.ts.map +1 -1
- package/dist/promptRegistry.js +1 -1
- package/dist/promptRegistry.js.map +1 -1
- package/dist/resourceRegistry.d.ts +9 -1
- package/dist/resourceRegistry.d.ts.map +1 -1
- package/dist/resourceRegistry.js +9 -2
- package/dist/resourceRegistry.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +16 -20
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +320 -0
- package/dist/server.js.map +1 -0
- package/dist/serverState.js +2 -4
- package/dist/serverState.js.map +1 -1
- package/dist/sql.js +0 -0
- package/dist/sqlErrors.d.ts +10 -0
- package/dist/sqlErrors.d.ts.map +1 -0
- package/dist/sqlErrors.js +32 -0
- package/dist/sqlErrors.js.map +1 -0
- package/dist/toolRegistry.d.ts +1 -1
- package/dist/toolRegistry.d.ts.map +1 -1
- package/dist/toolRegistry.js +1 -1
- package/dist/toolRegistry.js.map +1 -1
- package/dist/tools/AnalyzeTableTool.js +2 -4
- package/dist/tools/AnalyzeTableTool.js.map +1 -1
- package/dist/tools/CreateIndexTool.js +2 -4
- package/dist/tools/CreateIndexTool.js.map +1 -1
- package/dist/tools/CreateTableTool.js +2 -4
- package/dist/tools/CreateTableTool.js.map +1 -1
- package/dist/tools/DeleteDataTool.js +2 -4
- package/dist/tools/DeleteDataTool.js.map +1 -1
- package/dist/tools/DescribeDependenciesTool.js +2 -4
- package/dist/tools/DescribeDependenciesTool.js.map +1 -1
- package/dist/tools/DescribeObjectTool.js +2 -4
- package/dist/tools/DescribeObjectTool.js.map +1 -1
- package/dist/tools/DescribeRelationshipsTool.js +2 -4
- package/dist/tools/DescribeRelationshipsTool.js.map +1 -1
- package/dist/tools/DescribeTableTool.js +2 -4
- package/dist/tools/DescribeTableTool.js.map +1 -1
- package/dist/tools/DropTableTool.js +2 -4
- package/dist/tools/DropTableTool.js.map +1 -1
- package/dist/tools/ExplainQueryTool.d.ts.map +1 -1
- package/dist/tools/ExplainQueryTool.js +4 -6
- package/dist/tools/ExplainQueryTool.js.map +1 -1
- package/dist/tools/InsertDataTool.js +2 -4
- package/dist/tools/InsertDataTool.js.map +1 -1
- package/dist/tools/ListDatabasesTool.d.ts.map +1 -1
- package/dist/tools/ListDatabasesTool.js +2 -4
- package/dist/tools/ListDatabasesTool.js.map +1 -1
- package/dist/tools/ListForeignKeysTool.js +2 -4
- package/dist/tools/ListForeignKeysTool.js.map +1 -1
- package/dist/tools/ListLargestTablesTool.js +2 -4
- package/dist/tools/ListLargestTablesTool.js.map +1 -1
- package/dist/tools/ListObjectsTool.js +2 -4
- package/dist/tools/ListObjectsTool.js.map +1 -1
- package/dist/tools/ListTableTool.js +2 -4
- package/dist/tools/ListTableTool.js.map +1 -1
- package/dist/tools/PreviewDeleteTool.js +2 -4
- package/dist/tools/PreviewDeleteTool.js.map +1 -1
- package/dist/tools/PreviewUpdateTool.js +2 -4
- package/dist/tools/PreviewUpdateTool.js.map +1 -1
- package/dist/tools/ReadDataTool.d.ts +15 -12
- package/dist/tools/ReadDataTool.d.ts.map +1 -1
- package/dist/tools/ReadDataTool.js +86 -64
- package/dist/tools/ReadDataTool.js.map +1 -1
- package/dist/tools/SearchDataTool.js +2 -4
- package/dist/tools/SearchDataTool.js.map +1 -1
- package/dist/tools/SummarizeSchemaTool.js +2 -4
- package/dist/tools/SummarizeSchemaTool.js.map +1 -1
- package/dist/tools/UpdateDataTool.js +2 -4
- package/dist/tools/UpdateDataTool.js.map +1 -1
- package/dist/validation.d.ts +26 -3
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +237 -85
- package/dist/validation.js.map +1 -1
- package/dist/writePreview.js +0 -0
- package/dist/writePreviewGrant.js +0 -0
- package/dist/writePreviewGrantStore.js +0 -0
- package/dist/writeSafety.js +0 -0
- package/package.json +27 -18
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC/B,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,iBAAiB,GAAG,WAAW,CAAC;AACtC,MAAM,sBAAsB,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmationMessage.d.ts","sourceRoot":"","sources":["../src/confirmationMessage.ts"],"names":[],"mappings":"AAkFA,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,GAC7B,MAAM,CAwCR"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Builds the elicitation message for write/DDL confirmations so the user sees
|
|
2
|
+
// what they are approving before they accept: target database and table,
|
|
3
|
+
// filters, and a bounded preview of inserted or updated values.
|
|
4
|
+
const MAX_VALUE_LENGTH = 40;
|
|
5
|
+
const MAX_LIST_ITEMS = 5;
|
|
6
|
+
function formatValue(value) {
|
|
7
|
+
const text = typeof value === "string" ? `'${value}'` : JSON.stringify(value);
|
|
8
|
+
const rendered = text ?? String(value);
|
|
9
|
+
return rendered.length > MAX_VALUE_LENGTH
|
|
10
|
+
? `${rendered.slice(0, MAX_VALUE_LENGTH - 1)}…`
|
|
11
|
+
: rendered;
|
|
12
|
+
}
|
|
13
|
+
function formatList(items) {
|
|
14
|
+
const shown = items.slice(0, MAX_LIST_ITEMS).join(", ");
|
|
15
|
+
const hidden = items.length - MAX_LIST_ITEMS;
|
|
16
|
+
return hidden > 0 ? `${shown} (+${hidden} more)` : shown;
|
|
17
|
+
}
|
|
18
|
+
function formatFilter(filter) {
|
|
19
|
+
if (typeof filter !== "object" || filter === null) {
|
|
20
|
+
return "?";
|
|
21
|
+
}
|
|
22
|
+
const { column, operator, value, values } = filter;
|
|
23
|
+
if (operator === "IS NULL" || operator === "IS NOT NULL") {
|
|
24
|
+
return `${String(column)} ${operator}`;
|
|
25
|
+
}
|
|
26
|
+
if (operator === "IN" && Array.isArray(values)) {
|
|
27
|
+
return `${String(column)} IN (${formatList(values.map(formatValue))})`;
|
|
28
|
+
}
|
|
29
|
+
return `${String(column)} ${String(operator)} ${formatValue(value)}`;
|
|
30
|
+
}
|
|
31
|
+
function formatTarget(args, defaultDatabase) {
|
|
32
|
+
const parts = [
|
|
33
|
+
typeof args.databaseName === "string" && args.databaseName.trim()
|
|
34
|
+
? args.databaseName.trim()
|
|
35
|
+
: defaultDatabase,
|
|
36
|
+
typeof args.schemaName === "string" && args.schemaName.trim()
|
|
37
|
+
? args.schemaName.trim()
|
|
38
|
+
: undefined,
|
|
39
|
+
String(args.tableName ?? "?"),
|
|
40
|
+
];
|
|
41
|
+
return parts.filter(Boolean).join(".");
|
|
42
|
+
}
|
|
43
|
+
function formatWhere(filters) {
|
|
44
|
+
return Array.isArray(filters) && filters.length > 0
|
|
45
|
+
? ` where ${filters.map(formatFilter).join(" AND ")}`
|
|
46
|
+
: "";
|
|
47
|
+
}
|
|
48
|
+
function isRecord(value) {
|
|
49
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
50
|
+
}
|
|
51
|
+
function formatAssignments(record) {
|
|
52
|
+
return formatList(Object.entries(record).map(([column, value]) => `${column} = ${formatValue(value)}`));
|
|
53
|
+
}
|
|
54
|
+
function formatInsertValues(data) {
|
|
55
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
56
|
+
const first = rows.find(isRecord);
|
|
57
|
+
if (!first) {
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
const assignments = formatAssignments(first);
|
|
61
|
+
if (!assignments) {
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
64
|
+
return rows.length > 1 ? `. First row: ${assignments}` : `: ${assignments}`;
|
|
65
|
+
}
|
|
66
|
+
export function describeConfirmation(toolName, args, defaultDatabase) {
|
|
67
|
+
const target = formatTarget(args, defaultDatabase);
|
|
68
|
+
let detail;
|
|
69
|
+
switch (toolName) {
|
|
70
|
+
case "insert_data": {
|
|
71
|
+
const rows = Array.isArray(args.data) ? args.data.length : 1;
|
|
72
|
+
detail = `insert ${rows} row${rows === 1 ? "" : "s"} into ${target}${formatInsertValues(args.data)}`;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "update_data": {
|
|
76
|
+
const assignments = isRecord(args.updates)
|
|
77
|
+
? formatAssignments(args.updates)
|
|
78
|
+
: "";
|
|
79
|
+
detail = `update ${target}: set ${assignments}${formatWhere(args.filters)}`;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "delete_data":
|
|
83
|
+
detail = `delete from ${target}${formatWhere(args.filters)}`;
|
|
84
|
+
break;
|
|
85
|
+
case "create_table": {
|
|
86
|
+
const columns = Array.isArray(args.columns) ? args.columns.length : 0;
|
|
87
|
+
detail = `create table ${target} with ${columns} column${columns === 1 ? "" : "s"}`;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case "create_index": {
|
|
91
|
+
const columns = Array.isArray(args.columns)
|
|
92
|
+
? args.columns.map(String)
|
|
93
|
+
: [];
|
|
94
|
+
detail = `create index ${String(args.indexName ?? "?")} on ${target} (${formatList(columns)})`;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "drop_table":
|
|
98
|
+
detail = `drop table ${target}`;
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
detail = `run ${toolName} on ${target}`;
|
|
102
|
+
}
|
|
103
|
+
return `Confirm ${toolName}: ${detail}. Review the preview and impact before accepting.`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=confirmationMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmationMessage.js","sourceRoot":"","sources":["../src/confirmationMessage.ts"],"names":[],"mappings":"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"}
|
package/dist/db.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import sql from "mssql";
|
|
2
|
+
import { type EnvironmentConfig, type SqlConnectionConfig } from "./config.js";
|
|
3
|
+
interface SqlRequestContext {
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Runs `fn` with an MCP request context so SQL requests created inside it are
|
|
8
|
+
* cancelled when the client cancels the MCP request.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runWithSqlRequestContext<T>(context: SqlRequestContext, fn: () => Promise<T>): Promise<T>;
|
|
11
|
+
/** Cancels `request` when the current MCP request is aborted. */
|
|
12
|
+
export declare function bindRequestCancellation(request: sql.Request): sql.Request;
|
|
13
|
+
export declare function configureSqlConnection(config: SqlConnectionConfig): void;
|
|
14
|
+
export declare function configureDatabase(environment: EnvironmentConfig): void;
|
|
2
15
|
export declare function getDefaultDatabaseName(): string | null;
|
|
3
16
|
/**
|
|
4
17
|
* Returns the list of allowed database names.
|
|
@@ -10,10 +23,20 @@ export declare function getAllowedDatabases(): string[];
|
|
|
10
23
|
* Returns null if invalid.
|
|
11
24
|
*/
|
|
12
25
|
export declare function resolveDatabaseName(databaseName?: string): string | null;
|
|
26
|
+
export declare function buildSqlConfig(databaseName: string, environment: SqlConnectionConfig): sql.config;
|
|
13
27
|
/**
|
|
14
28
|
* Ensures a connection pool exists for the given database.
|
|
15
29
|
*/
|
|
16
30
|
export declare function ensureSqlConnection(databaseName: string): Promise<sql.ConnectionPool>;
|
|
31
|
+
/** Closes every cached connection pool (used on shutdown). */
|
|
32
|
+
export declare function closeAllPools(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the shared connection pool for the given (or default) database.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getSqlPool(databaseName?: string): Promise<{
|
|
37
|
+
pool: sql.ConnectionPool;
|
|
38
|
+
error?: string;
|
|
39
|
+
}>;
|
|
17
40
|
/**
|
|
18
41
|
* Returns a sql.Request for the given database.
|
|
19
42
|
* Resolves database name (param or default), validates against allowed list,
|
|
@@ -27,4 +50,5 @@ export declare function getDedicatedSqlPool(databaseName?: string): Promise<{
|
|
|
27
50
|
pool: sql.ConnectionPool;
|
|
28
51
|
error?: string;
|
|
29
52
|
}>;
|
|
53
|
+
export {};
|
|
30
54
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,mBAAmB,EAEzB,MAAM,aAAa,CAAC;AAOrB,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAUD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,OAAO,EAAE,iBAAiB,EAC1B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED,iEAAiE;AACjE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAmBzE;AAMD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAExE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAItE;AASD,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAgBtD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAW9C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQxE;AAsCD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,mBAAmB,GAC/B,GAAG,CAAC,MAAM,CAoBZ;AAsBD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CA8B7B;AAED,8DAA8D;AAC9D,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAInD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAUvD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAWnD;AAED,wBAAsB,mBAAmB,CACvC,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBvD"}
|
package/dist/db.js
CHANGED
|
@@ -1,17 +1,71 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
1
2
|
import sql from "mssql";
|
|
2
|
-
import {
|
|
3
|
-
// Connection pools keyed by database name
|
|
3
|
+
import { parseDatabaseList, } from "./config.js";
|
|
4
|
+
// Connection pools keyed by database name. Pending connects are tracked so
|
|
5
|
+
// concurrent first requests share one pool instead of racing to create two.
|
|
4
6
|
const sqlPools = new Map();
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
const pendingPools = new Map();
|
|
8
|
+
const requestContext = new AsyncLocalStorage();
|
|
9
|
+
/**
|
|
10
|
+
* Runs `fn` with an MCP request context so SQL requests created inside it are
|
|
11
|
+
* cancelled when the client cancels the MCP request.
|
|
12
|
+
*/
|
|
13
|
+
export function runWithSqlRequestContext(context, fn) {
|
|
14
|
+
const store = { ...context, cleanups: new Set() };
|
|
15
|
+
return requestContext.run(store, async () => {
|
|
16
|
+
try {
|
|
17
|
+
return await fn();
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
for (const cleanup of store.cleanups) {
|
|
21
|
+
cleanup();
|
|
22
|
+
}
|
|
23
|
+
store.cleanups.clear();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Cancels `request` when the current MCP request is aborted. */
|
|
28
|
+
export function bindRequestCancellation(request) {
|
|
29
|
+
const store = requestContext.getStore();
|
|
30
|
+
const signal = store?.signal;
|
|
31
|
+
if (!store || !signal) {
|
|
32
|
+
return request;
|
|
8
33
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
34
|
+
// mssql resets its cancel flag when a query starts, so a cancel issued
|
|
35
|
+
// before then would be lost: fail fast instead.
|
|
36
|
+
signal.throwIfAborted();
|
|
37
|
+
const onAbort = () => request.cancel();
|
|
38
|
+
const cleanup = () => {
|
|
39
|
+
signal.removeEventListener("abort", onAbort);
|
|
40
|
+
store.cleanups.delete(cleanup);
|
|
41
|
+
};
|
|
42
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
43
|
+
store.cleanups.add(cleanup);
|
|
44
|
+
// Streamed requests can release the listener as soon as they finish.
|
|
45
|
+
request.once("done", cleanup);
|
|
46
|
+
return request;
|
|
47
|
+
}
|
|
48
|
+
let sqlConnectionConfig;
|
|
49
|
+
let configuredDefaultDatabase;
|
|
50
|
+
let configuredDatabases;
|
|
51
|
+
export function configureSqlConnection(config) {
|
|
52
|
+
sqlConnectionConfig = { ...config };
|
|
53
|
+
}
|
|
54
|
+
export function configureDatabase(environment) {
|
|
55
|
+
configureSqlConnection(environment);
|
|
56
|
+
configuredDefaultDatabase = environment.databaseName;
|
|
57
|
+
configuredDatabases = [...environment.databases];
|
|
58
|
+
}
|
|
59
|
+
function getSqlConnectionConfig() {
|
|
60
|
+
if (!sqlConnectionConfig) {
|
|
61
|
+
throw new Error("SQL connection configuration has not been initialized.");
|
|
62
|
+
}
|
|
63
|
+
return sqlConnectionConfig;
|
|
13
64
|
}
|
|
14
65
|
export function getDefaultDatabaseName() {
|
|
66
|
+
if (configuredDefaultDatabase) {
|
|
67
|
+
return configuredDefaultDatabase;
|
|
68
|
+
}
|
|
15
69
|
const allowedDatabases = parseDatabaseList(process.env.DATABASES);
|
|
16
70
|
const explicitDefault = process.env.DATABASE_NAME?.trim();
|
|
17
71
|
if (allowedDatabases.length === 0) {
|
|
@@ -27,6 +81,9 @@ export function getDefaultDatabaseName() {
|
|
|
27
81
|
* If DATABASES is set, returns those; otherwise returns only DATABASE_NAME.
|
|
28
82
|
*/
|
|
29
83
|
export function getAllowedDatabases() {
|
|
84
|
+
if (configuredDatabases) {
|
|
85
|
+
return [...configuredDatabases];
|
|
86
|
+
}
|
|
30
87
|
const allowedDatabases = parseDatabaseList(process.env.DATABASES);
|
|
31
88
|
if (allowedDatabases.length > 0) {
|
|
32
89
|
return allowedDatabases;
|
|
@@ -49,25 +106,57 @@ export function resolveDatabaseName(databaseName) {
|
|
|
49
106
|
return resolved;
|
|
50
107
|
return null;
|
|
51
108
|
}
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
:
|
|
57
|
-
|
|
58
|
-
|
|
109
|
+
function buildAuthentication(auth) {
|
|
110
|
+
switch (auth.type) {
|
|
111
|
+
case "sql":
|
|
112
|
+
return { user: auth.user, password: auth.password };
|
|
113
|
+
case "ntlm":
|
|
114
|
+
return { user: auth.user, password: auth.password, domain: auth.domain };
|
|
115
|
+
case "azure-default":
|
|
116
|
+
return {
|
|
117
|
+
authentication: {
|
|
118
|
+
type: "azure-active-directory-default",
|
|
119
|
+
options: auth.clientId ? { clientId: auth.clientId } : {},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
case "azure-service-principal":
|
|
123
|
+
return {
|
|
124
|
+
authentication: {
|
|
125
|
+
type: "azure-active-directory-service-principal-secret",
|
|
126
|
+
options: {
|
|
127
|
+
clientId: auth.clientId,
|
|
128
|
+
clientSecret: auth.clientSecret,
|
|
129
|
+
tenantId: auth.tenantId,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
case "azure-access-token":
|
|
134
|
+
return {
|
|
135
|
+
authentication: {
|
|
136
|
+
type: "azure-active-directory-access-token",
|
|
137
|
+
options: { token: auth.token },
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export function buildSqlConfig(databaseName, environment) {
|
|
143
|
+
const config = {
|
|
144
|
+
server: environment.serverName,
|
|
59
145
|
database: databaseName,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
requestTimeout: getQueryTimeoutMs(),
|
|
146
|
+
...buildAuthentication(environment.auth),
|
|
147
|
+
requestTimeout: environment.queryTimeoutMs,
|
|
63
148
|
options: {
|
|
64
|
-
encrypt:
|
|
65
|
-
trustServerCertificate: trustServerCertificate
|
|
149
|
+
encrypt: environment.encrypt,
|
|
150
|
+
trustServerCertificate: environment.trustServerCertificate,
|
|
66
151
|
enableArithAbort: true,
|
|
67
152
|
useUTC: false,
|
|
68
153
|
},
|
|
69
|
-
connectionTimeout:
|
|
154
|
+
connectionTimeout: environment.connectionTimeoutSeconds * 1000,
|
|
70
155
|
};
|
|
156
|
+
if (environment.serverPort !== undefined) {
|
|
157
|
+
config.port = environment.serverPort;
|
|
158
|
+
}
|
|
159
|
+
return config;
|
|
71
160
|
}
|
|
72
161
|
async function resolveConfiguredDatabase(databaseName) {
|
|
73
162
|
const resolved = resolveDatabaseName(databaseName);
|
|
@@ -91,20 +180,47 @@ export async function ensureSqlConnection(databaseName) {
|
|
|
91
180
|
if (existing && existing.connected) {
|
|
92
181
|
return existing;
|
|
93
182
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
183
|
+
const pending = pendingPools.get(databaseName);
|
|
184
|
+
if (pending) {
|
|
185
|
+
return pending;
|
|
186
|
+
}
|
|
187
|
+
const connecting = (async () => {
|
|
188
|
+
if (existing) {
|
|
189
|
+
sqlPools.delete(databaseName);
|
|
190
|
+
await existing.close().catch(() => undefined);
|
|
100
191
|
}
|
|
101
|
-
|
|
192
|
+
const config = buildSqlConfig(databaseName, getSqlConnectionConfig());
|
|
193
|
+
const pool = new sql.ConnectionPool(config);
|
|
194
|
+
await pool.connect();
|
|
195
|
+
sqlPools.set(databaseName, pool);
|
|
196
|
+
return pool;
|
|
197
|
+
})();
|
|
198
|
+
pendingPools.set(databaseName, connecting);
|
|
199
|
+
try {
|
|
200
|
+
return await connecting;
|
|
102
201
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
202
|
+
finally {
|
|
203
|
+
pendingPools.delete(databaseName);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** Closes every cached connection pool (used on shutdown). */
|
|
207
|
+
export async function closeAllPools() {
|
|
208
|
+
const pools = [...sqlPools.values()];
|
|
209
|
+
sqlPools.clear();
|
|
210
|
+
await Promise.allSettled(pools.map((pool) => pool.close()));
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Returns the shared connection pool for the given (or default) database.
|
|
214
|
+
*/
|
|
215
|
+
export async function getSqlPool(databaseName) {
|
|
216
|
+
const resolved = await resolveConfiguredDatabase(databaseName);
|
|
217
|
+
if (resolved.error) {
|
|
218
|
+
return {
|
|
219
|
+
pool: null,
|
|
220
|
+
error: resolved.error,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return { pool: await ensureSqlConnection(resolved.databaseName) };
|
|
108
224
|
}
|
|
109
225
|
/**
|
|
110
226
|
* Returns a sql.Request for the given database.
|
|
@@ -120,7 +236,7 @@ export async function getSqlRequest(databaseName) {
|
|
|
120
236
|
};
|
|
121
237
|
}
|
|
122
238
|
const pool = await ensureSqlConnection(resolved.databaseName);
|
|
123
|
-
return { request: pool.request() };
|
|
239
|
+
return { request: bindRequestCancellation(pool.request()) };
|
|
124
240
|
}
|
|
125
241
|
export async function getDedicatedSqlPool(databaseName) {
|
|
126
242
|
const resolved = await resolveConfiguredDatabase(databaseName);
|
|
@@ -131,7 +247,7 @@ export async function getDedicatedSqlPool(databaseName) {
|
|
|
131
247
|
};
|
|
132
248
|
}
|
|
133
249
|
const config = {
|
|
134
|
-
...
|
|
250
|
+
...buildSqlConfig(resolved.databaseName, getSqlConnectionConfig()),
|
|
135
251
|
pool: {
|
|
136
252
|
max: 1,
|
|
137
253
|
min: 0,
|
package/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EAIL,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,4EAA4E;AAC5E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;AACvD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAuC,CAAC;AAYpE,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAAmB,CAAC;AAEhE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA0B,EAC1B,EAAoB;IAEpB,MAAM,KAAK,GAAoB,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACnE,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACrC,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,uBAAuB,CAAC,OAAoB;IAC1D,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC;IAC7B,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,uEAAuE;IACvE,gDAAgD;IAChD,MAAM,CAAC,cAAc,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,IAAI,mBAAoD,CAAC;AACzD,IAAI,yBAA6C,CAAC;AAClD,IAAI,mBAAyC,CAAC;AAE9C,MAAM,UAAU,sBAAsB,CAAC,MAA2B;IAChE,mBAAmB,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,WAA8B;IAC9D,sBAAsB,CAAC,WAAW,CAAC,CAAC;IACpC,yBAAyB,GAAG,WAAW,CAAC,YAAY,CAAC;IACrD,mBAAmB,GAAG,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,sBAAsB;IAC7B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,IAAI,yBAAyB,EAAE,CAAC;QAC9B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IAE1D,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,eAAe,IAAI,IAAI,CAAC;IACjC,CAAC;IAED,IAAI,eAAe,IAAI,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAClE,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,gBAAgB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,mBAAmB,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IACpD,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAqB;IACvD,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,IAAI,sBAAsB,EAAE,CAAC;IAClE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAmB;IAEnB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,KAAK;YACR,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtD,KAAK,MAAM;YACT,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3E,KAAK,eAAe;YAClB,OAAO;gBACL,cAAc,EAAE;oBACd,IAAI,EAAE,gCAAgC;oBACtC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;iBAC1D;aACF,CAAC;QACJ,KAAK,yBAAyB;YAC5B,OAAO;gBACL,cAAc,EAAE;oBACd,IAAI,EAAE,iDAAiD;oBACvD,OAAO,EAAE;wBACP,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;qBACxB;iBACF;aACF,CAAC;QACJ,KAAK,oBAAoB;YACvB,OAAO;gBACL,cAAc,EAAE;oBACd,IAAI,EAAE,qCAAqC;oBAC3C,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;iBAC/B;aACF,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,YAAoB,EACpB,WAAgC;IAEhC,MAAM,MAAM,GAAe;QACzB,MAAM,EAAE,WAAW,CAAC,UAAU;QAC9B,QAAQ,EAAE,YAAY;QACtB,GAAG,mBAAmB,CAAC,WAAW,CAAC,IAAI,CAAC;QACxC,cAAc,EAAE,WAAW,CAAC,cAAc;QAC1C,OAAO,EAAE;YACP,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,sBAAsB,EAAE,WAAW,CAAC,sBAAsB;YAC1D,gBAAgB,EAAE,IAAI;YACtB,MAAM,EAAE,KAAK;SACd;QACD,iBAAiB,EAAE,WAAW,CAAC,wBAAwB,GAAG,IAAI;KAC/D,CAAC;IAEF,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,YAAqB;IAErB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;QACtC,MAAM,iBAAiB,GACrB,OAAO,CAAC,MAAM,GAAG,CAAC;YAChB,CAAC,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACnC,CAAC,CAAC,8DAA8D,CAAC;QAErE,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,KAAK,EAAE,mCAAmC,iBAAiB,2EAA2E;SACvI,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,YAAoB;IAEpB,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACnC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,KAAK,IAAI,EAAE;QAC7B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,EAAE,CAAC;IAEL,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC;IAC1B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,YAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO;YACL,IAAI,EAAE,IAAqC;YAC3C,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,YAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,IAA8B;YACvC,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC9D,OAAO,EAAE,OAAO,EAAE,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,YAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO;YACL,IAAI,EAAE,IAAqC;YAC3C,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG;QACb,GAAG,cAAc,CAAC,QAAQ,CAAC,YAAY,EAAE,sBAAsB,EAAE,CAAC;QAClE,IAAI,EAAE;YACJ,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,CAAC;YACN,iBAAiB,EAAE,KAAK;SACzB;KACY,CAAC;IAEhB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACrB,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC"}
|
package/dist/filteredRead.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type IncomingMessage, type Server, type ServerResponse } from "node:http";
|
|
2
|
+
import { type EnvironmentConfig } from "./config.js";
|
|
3
|
+
import type { ServerState } from "./serverState.js";
|
|
4
|
+
export declare function isLoopbackHost(host: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Hostnames accepted in the Host and Origin headers. Guards against DNS
|
|
7
|
+
* rebinding: a browser page on another site cannot reach the server through a
|
|
8
|
+
* hostname it controls.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveAllowedHostnames(environment: Pick<EnvironmentConfig, "mcpHttpAllowedHosts" | "mcpHttpHost" | "mcpBaseUrl">): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Refuses to expose an unauthenticated server beyond loopback unless the
|
|
13
|
+
* operator explicitly opts in.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertHttpExposureAllowed(environment: Pick<EnvironmentConfig, "mcpHttpHost" | "mcpHttpAuthToken" | "mcpHttpAllowUnauthenticated">): void;
|
|
16
|
+
/**
|
|
17
|
+
* Warns when the listener is reachable off-host over plain HTTP: the bearer
|
|
18
|
+
* token and query results would cross the network unencrypted. An https
|
|
19
|
+
* MCP_BASE_URL signals that a TLS-terminating proxy sits in front.
|
|
20
|
+
*/
|
|
21
|
+
export declare function httpExposureWarning(environment: Pick<EnvironmentConfig, "mcpHttpHost" | "mcpBaseUrl">): string | undefined;
|
|
22
|
+
export declare function isAuthorized(authorizationHeader: string | undefined, expectedToken: string): boolean;
|
|
23
|
+
export declare function createHttpRequestListener(state: ServerState, environment: EnvironmentConfig): (req: IncomingMessage, res: ServerResponse) => void;
|
|
24
|
+
export declare function startHttpServer(state: ServerState, environment: EnvironmentConfig): Promise<Server>;
|
|
25
|
+
//# sourceMappingURL=httpServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpServer.d.ts","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAOnB,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQpD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,IAAI,CACf,iBAAiB,EACjB,qBAAqB,GAAG,aAAa,GAAG,YAAY,CACrD,GACA,MAAM,EAAE,CAkBV;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,IAAI,CACf,iBAAiB,EACjB,aAAa,GAAG,kBAAkB,GAAG,6BAA6B,CACnE,GACA,IAAI,CAYN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,YAAY,CAAC,GACjE,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,YAAY,CAC1B,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,GACpB,OAAO,CAUT;AAkBD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,iBAAiB,GAC7B,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,CAmCrD;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA6BjB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { createServer, } from "node:http";
|
|
3
|
+
import { hostHeaderValidation, originValidation, toNodeHandler, } from "@modelcontextprotocol/node";
|
|
4
|
+
import { createMcpHandler } from "@modelcontextprotocol/server";
|
|
5
|
+
import { formatUrlHost, getMcpEndpointUrl, } from "./config.js";
|
|
6
|
+
import { createServerInstance } from "./server.js";
|
|
7
|
+
const LOOPBACK_HOSTNAMES = ["localhost", "127.0.0.1", "[::1]"];
|
|
8
|
+
const MCP_PATH = "/mcp";
|
|
9
|
+
export function isLoopbackHost(host) {
|
|
10
|
+
const normalized = host.trim().toLowerCase();
|
|
11
|
+
return (normalized === "localhost" ||
|
|
12
|
+
normalized === "::1" ||
|
|
13
|
+
normalized === "[::1]" ||
|
|
14
|
+
/^127(\.\d{1,3}){3}$/.test(normalized));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Hostnames accepted in the Host and Origin headers. Guards against DNS
|
|
18
|
+
* rebinding: a browser page on another site cannot reach the server through a
|
|
19
|
+
* hostname it controls.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveAllowedHostnames(environment) {
|
|
22
|
+
if (environment.mcpHttpAllowedHosts.length > 0) {
|
|
23
|
+
return [...environment.mcpHttpAllowedHosts];
|
|
24
|
+
}
|
|
25
|
+
const hostnames = new Set(LOOPBACK_HOSTNAMES);
|
|
26
|
+
const bindHost = environment.mcpHttpHost.trim().toLowerCase();
|
|
27
|
+
if (bindHost !== "0.0.0.0" &&
|
|
28
|
+
bindHost !== "::" &&
|
|
29
|
+
!isLoopbackHost(bindHost)) {
|
|
30
|
+
hostnames.add(bindHost.includes(":") ? `[${bindHost}]` : bindHost);
|
|
31
|
+
}
|
|
32
|
+
if (environment.mcpBaseUrl) {
|
|
33
|
+
hostnames.add(new URL(environment.mcpBaseUrl).hostname.toLowerCase());
|
|
34
|
+
}
|
|
35
|
+
return [...hostnames];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Refuses to expose an unauthenticated server beyond loopback unless the
|
|
39
|
+
* operator explicitly opts in.
|
|
40
|
+
*/
|
|
41
|
+
export function assertHttpExposureAllowed(environment) {
|
|
42
|
+
if (isLoopbackHost(environment.mcpHttpHost) ||
|
|
43
|
+
environment.mcpHttpAuthToken ||
|
|
44
|
+
environment.mcpHttpAllowUnauthenticated) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`MCP_HTTP_HOST=${environment.mcpHttpHost} exposes the server beyond loopback. Set MCP_HTTP_AUTH_TOKEN, or set MCP_HTTP_ALLOW_UNAUTHENTICATED=true if another layer (reverse proxy, network policy) protects it.`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Warns when the listener is reachable off-host over plain HTTP: the bearer
|
|
51
|
+
* token and query results would cross the network unencrypted. An https
|
|
52
|
+
* MCP_BASE_URL signals that a TLS-terminating proxy sits in front.
|
|
53
|
+
*/
|
|
54
|
+
export function httpExposureWarning(environment) {
|
|
55
|
+
if (isLoopbackHost(environment.mcpHttpHost) ||
|
|
56
|
+
environment.mcpBaseUrl?.startsWith("https://")) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return `Warning: MCP_HTTP_HOST=${environment.mcpHttpHost} serves plain HTTP beyond loopback, so the bearer token and query results are sent unencrypted. Put a TLS-terminating reverse proxy in front and set MCP_BASE_URL to its https:// address.`;
|
|
60
|
+
}
|
|
61
|
+
export function isAuthorized(authorizationHeader, expectedToken) {
|
|
62
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorizationHeader?.trim() ?? "");
|
|
63
|
+
if (!match) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const provided = Buffer.from(match[1].trim());
|
|
67
|
+
const expected = Buffer.from(expectedToken);
|
|
68
|
+
return (provided.length === expected.length && timingSafeEqual(provided, expected));
|
|
69
|
+
}
|
|
70
|
+
function writeJsonError(res, status, message, headers = {}) {
|
|
71
|
+
res.writeHead(status, { "content-type": "application/json", ...headers });
|
|
72
|
+
res.end(JSON.stringify({
|
|
73
|
+
jsonrpc: "2.0",
|
|
74
|
+
error: { code: -32000, message },
|
|
75
|
+
id: null,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
export function createHttpRequestListener(state, environment) {
|
|
79
|
+
const allowedHostnames = resolveAllowedHostnames(environment);
|
|
80
|
+
const validateHost = hostHeaderValidation(allowedHostnames);
|
|
81
|
+
const validateOrigin = originValidation(allowedHostnames);
|
|
82
|
+
const onerror = (error) => console.error("HTTP transport error:", error);
|
|
83
|
+
const handler = createMcpHandler(() => createServerInstance(state, environment), { onerror });
|
|
84
|
+
const nodeHandler = toNodeHandler(handler, { onerror });
|
|
85
|
+
return (req, res) => {
|
|
86
|
+
const path = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
87
|
+
if (path !== MCP_PATH) {
|
|
88
|
+
writeJsonError(res, 404, `Not found. The MCP endpoint is ${MCP_PATH}.`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!validateHost(req, res) || !validateOrigin(req, res)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (environment.mcpHttpAuthToken &&
|
|
95
|
+
!isAuthorized(req.headers.authorization, environment.mcpHttpAuthToken)) {
|
|
96
|
+
writeJsonError(res, 401, "Unauthorized.", {
|
|
97
|
+
"www-authenticate": 'Bearer realm="mssql-mcp"',
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
void nodeHandler(req, res);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export async function startHttpServer(state, environment) {
|
|
105
|
+
assertHttpExposureAllowed(environment);
|
|
106
|
+
const host = environment.mcpHttpHost;
|
|
107
|
+
const port = environment.mcpHttpPort;
|
|
108
|
+
const localEndpoint = `http://${formatUrlHost(host)}:${port}${MCP_PATH}`;
|
|
109
|
+
const publicEndpoint = getMcpEndpointUrl(environment);
|
|
110
|
+
const httpServer = createServer(createHttpRequestListener(state, environment));
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
httpServer.once("error", reject);
|
|
113
|
+
httpServer.listen(port, host, () => resolve());
|
|
114
|
+
});
|
|
115
|
+
console.error(`MCP Streamable HTTP server listening on ${localEndpoint}`);
|
|
116
|
+
if (publicEndpoint !== localEndpoint) {
|
|
117
|
+
console.error(`Public MCP endpoint: ${publicEndpoint}`);
|
|
118
|
+
}
|
|
119
|
+
if (environment.mcpHttpAuthToken) {
|
|
120
|
+
console.error("Bearer token authentication is enabled.");
|
|
121
|
+
}
|
|
122
|
+
const exposureWarning = httpExposureWarning(environment);
|
|
123
|
+
if (exposureWarning) {
|
|
124
|
+
console.error(exposureWarning);
|
|
125
|
+
}
|
|
126
|
+
return httpServer;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=httpServer.js.map
|