mongodb-mcp-server 0.0.5 → 0.0.6
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/.github/CODEOWNERS +3 -0
- package/.github/dependabot.yml +10 -0
- package/.github/workflows/code_health.yaml +9 -27
- package/.github/workflows/code_health_fork.yaml +106 -0
- package/.github/workflows/codeql.yml +34 -0
- package/.github/workflows/lint.yml +37 -0
- package/.github/workflows/prepare_release.yaml +5 -3
- package/.github/workflows/publish.yaml +6 -3
- package/.prettierrc.json +1 -1
- package/README.md +16 -0
- package/dist/common/atlas/apiClient.js +1 -5
- package/dist/common/atlas/apiClient.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/logger.js +20 -1
- package/dist/logger.js.map +1 -1
- package/dist/server.js +44 -3
- package/dist/server.js.map +1 -1
- package/dist/session.js +50 -5
- package/dist/session.js.map +1 -1
- package/dist/telemetry/constants.js.map +1 -1
- package/dist/telemetry/telemetry.js +7 -6
- package/dist/telemetry/telemetry.js.map +1 -1
- package/dist/tools/atlas/{createAccessList.js → create/createAccessList.js} +1 -1
- package/dist/tools/atlas/create/createAccessList.js.map +1 -0
- package/dist/tools/atlas/{createDBUser.js → create/createDBUser.js} +1 -1
- package/dist/tools/atlas/create/createDBUser.js.map +1 -0
- package/dist/tools/atlas/{createFreeCluster.js → create/createFreeCluster.js} +5 -2
- package/dist/tools/atlas/create/createFreeCluster.js.map +1 -0
- package/dist/tools/atlas/{createProject.js → create/createProject.js} +1 -1
- package/dist/tools/atlas/create/createProject.js.map +1 -0
- package/dist/tools/atlas/metadata/connectCluster.js +97 -0
- package/dist/tools/atlas/metadata/connectCluster.js.map +1 -0
- package/dist/tools/atlas/{inspectAccessList.js → read/inspectAccessList.js} +1 -1
- package/dist/tools/atlas/read/inspectAccessList.js.map +1 -0
- package/dist/tools/atlas/{inspectCluster.js → read/inspectCluster.js} +1 -1
- package/dist/tools/atlas/read/inspectCluster.js.map +1 -0
- package/dist/tools/atlas/{listClusters.js → read/listClusters.js} +1 -1
- package/dist/tools/atlas/read/listClusters.js.map +1 -0
- package/dist/tools/atlas/{listDBUsers.js → read/listDBUsers.js} +1 -1
- package/dist/tools/atlas/read/listDBUsers.js.map +1 -0
- package/dist/tools/atlas/{listOrgs.js → read/listOrgs.js} +1 -1
- package/dist/tools/atlas/read/listOrgs.js.map +1 -0
- package/dist/tools/atlas/{listProjects.js → read/listProjects.js} +1 -1
- package/dist/tools/atlas/read/listProjects.js.map +1 -0
- package/dist/tools/atlas/tools.js +12 -10
- package/dist/tools/atlas/tools.js.map +1 -1
- package/dist/tools/mongodb/create/insertMany.js +1 -1
- package/dist/tools/mongodb/create/insertMany.js.map +1 -1
- package/dist/tools/mongodb/delete/deleteMany.js +1 -2
- package/dist/tools/mongodb/delete/deleteMany.js.map +1 -1
- package/dist/tools/mongodb/metadata/connect.js +59 -71
- package/dist/tools/mongodb/metadata/connect.js.map +1 -1
- package/dist/tools/mongodb/mongodbTool.js +37 -30
- package/dist/tools/mongodb/mongodbTool.js.map +1 -1
- package/dist/tools/mongodb/read/aggregate.js +1 -1
- package/dist/tools/mongodb/read/aggregate.js.map +1 -1
- package/dist/tools/mongodb/read/count.js +1 -2
- package/dist/tools/mongodb/read/count.js.map +1 -1
- package/dist/tools/mongodb/read/find.js +2 -4
- package/dist/tools/mongodb/read/find.js.map +1 -1
- package/dist/tools/mongodb/tools.js +4 -2
- package/dist/tools/mongodb/tools.js.map +1 -1
- package/dist/tools/mongodb/update/updateMany.js +2 -4
- package/dist/tools/mongodb/update/updateMany.js.map +1 -1
- package/dist/tools/tool.js +30 -6
- package/dist/tools/tool.js.map +1 -1
- package/package.json +2 -2
- package/src/common/atlas/apiClient.ts +3 -11
- package/src/config.ts +12 -7
- package/src/errors.ts +1 -1
- package/src/index.ts +3 -3
- package/src/logger.ts +26 -1
- package/src/server.ts +60 -5
- package/src/session.ts +69 -6
- package/src/telemetry/constants.ts +2 -2
- package/src/telemetry/telemetry.ts +9 -21
- package/src/telemetry/types.ts +28 -11
- package/src/tools/atlas/{createAccessList.ts → create/createAccessList.ts} +2 -2
- package/src/tools/atlas/{createDBUser.ts → create/createDBUser.ts} +3 -3
- package/src/tools/atlas/{createFreeCluster.ts → create/createFreeCluster.ts} +7 -4
- package/src/tools/atlas/{createProject.ts → create/createProject.ts} +3 -3
- package/src/tools/atlas/metadata/connectCluster.ts +114 -0
- package/src/tools/atlas/{inspectAccessList.ts → read/inspectAccessList.ts} +2 -2
- package/src/tools/atlas/{inspectCluster.ts → read/inspectCluster.ts} +3 -3
- package/src/tools/atlas/{listClusters.ts → read/listClusters.ts} +3 -3
- package/src/tools/atlas/{listDBUsers.ts → read/listDBUsers.ts} +3 -3
- package/src/tools/atlas/{listOrgs.ts → read/listOrgs.ts} +2 -2
- package/src/tools/atlas/{listProjects.ts → read/listProjects.ts} +3 -3
- package/src/tools/atlas/tools.ts +12 -10
- package/src/tools/mongodb/create/insertMany.ts +1 -1
- package/src/tools/mongodb/delete/deleteMany.ts +1 -2
- package/src/tools/mongodb/metadata/connect.ts +78 -75
- package/src/tools/mongodb/mongodbTool.ts +40 -30
- package/src/tools/mongodb/read/aggregate.ts +1 -1
- package/src/tools/mongodb/read/count.ts +1 -2
- package/src/tools/mongodb/read/find.ts +2 -4
- package/src/tools/mongodb/tools.ts +4 -2
- package/src/tools/mongodb/update/updateMany.ts +2 -4
- package/src/tools/tool.ts +40 -13
- package/tests/integration/helpers.ts +13 -3
- package/tests/integration/server.test.ts +46 -20
- package/tests/integration/tools/atlas/atlasHelpers.ts +7 -5
- package/tests/integration/tools/atlas/clusters.test.ts +68 -4
- package/tests/integration/tools/mongodb/metadata/connect.test.ts +85 -100
- package/tests/integration/tools/mongodb/mongodbHelpers.ts +32 -21
- package/tests/unit/telemetry.test.ts +200 -0
- package/dist/tools/atlas/createAccessList.js.map +0 -1
- package/dist/tools/atlas/createDBUser.js.map +0 -1
- package/dist/tools/atlas/createFreeCluster.js.map +0 -1
- package/dist/tools/atlas/createProject.js.map +0 -1
- package/dist/tools/atlas/inspectAccessList.js.map +0 -1
- package/dist/tools/atlas/inspectCluster.js.map +0 -1
- package/dist/tools/atlas/listClusters.js.map +0 -1
- package/dist/tools/atlas/listDBUsers.js.map +0 -1
- package/dist/tools/atlas/listOrgs.js.map +0 -1
- package/dist/tools/atlas/listProjects.js.map +0 -1
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { Session } from "../../../../src/session.js";
|
|
2
2
|
import { expectDefined } from "../../helpers.js";
|
|
3
|
-
import { describeWithAtlas, withProject,
|
|
3
|
+
import { describeWithAtlas, withProject, randomId } from "./atlasHelpers.js";
|
|
4
4
|
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
|
|
6
|
+
function sleep(ms: number) {
|
|
7
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
async function deleteAndWaitCluster(session: Session, projectId: string, clusterName: string) {
|
|
7
11
|
await session.apiClient.deleteCluster({
|
|
8
12
|
params: {
|
|
9
13
|
path: {
|
|
10
14
|
groupId: projectId,
|
|
11
|
-
clusterName
|
|
15
|
+
clusterName,
|
|
12
16
|
},
|
|
13
17
|
},
|
|
14
18
|
});
|
|
@@ -18,7 +22,7 @@ async function deleteAndWaitCluster(session: Session, projectId: string, cluster
|
|
|
18
22
|
params: {
|
|
19
23
|
path: {
|
|
20
24
|
groupId: projectId,
|
|
21
|
-
clusterName
|
|
25
|
+
clusterName,
|
|
22
26
|
},
|
|
23
27
|
},
|
|
24
28
|
});
|
|
@@ -29,6 +33,23 @@ async function deleteAndWaitCluster(session: Session, projectId: string, cluster
|
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
async function waitClusterState(session: Session, projectId: string, clusterName: string, state: string) {
|
|
37
|
+
while (true) {
|
|
38
|
+
const cluster = await session.apiClient.getCluster({
|
|
39
|
+
params: {
|
|
40
|
+
path: {
|
|
41
|
+
groupId: projectId,
|
|
42
|
+
clusterName,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (cluster?.stateName === state) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await sleep(1000);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
describeWithAtlas("clusters", (integration) => {
|
|
33
54
|
withProject(integration, ({ getProjectId }) => {
|
|
34
55
|
const clusterName = "ClusterTest-" + randomId;
|
|
@@ -66,7 +87,7 @@ describeWithAtlas("clusters", (integration) => {
|
|
|
66
87
|
},
|
|
67
88
|
})) as CallToolResult;
|
|
68
89
|
expect(response.content).toBeArray();
|
|
69
|
-
expect(response.content).toHaveLength(
|
|
90
|
+
expect(response.content).toHaveLength(2);
|
|
70
91
|
expect(response.content[0].text).toContain("has been created");
|
|
71
92
|
});
|
|
72
93
|
});
|
|
@@ -117,5 +138,48 @@ describeWithAtlas("clusters", (integration) => {
|
|
|
117
138
|
expect(response.content[1].text).toContain(`${clusterName} | `);
|
|
118
139
|
});
|
|
119
140
|
});
|
|
141
|
+
|
|
142
|
+
describe("atlas-connect-cluster", () => {
|
|
143
|
+
beforeAll(async () => {
|
|
144
|
+
const projectId = getProjectId();
|
|
145
|
+
await waitClusterState(integration.mcpServer().session, projectId, clusterName, "IDLE");
|
|
146
|
+
await integration.mcpServer().session.apiClient.createProjectIpAccessList({
|
|
147
|
+
params: {
|
|
148
|
+
path: {
|
|
149
|
+
groupId: projectId,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
body: [
|
|
153
|
+
{
|
|
154
|
+
comment: "MCP test",
|
|
155
|
+
cidrBlock: "0.0.0.0/0",
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("should have correct metadata", async () => {
|
|
162
|
+
const { tools } = await integration.mcpClient().listTools();
|
|
163
|
+
const connectCluster = tools.find((tool) => tool.name === "atlas-connect-cluster");
|
|
164
|
+
|
|
165
|
+
expectDefined(connectCluster);
|
|
166
|
+
expect(connectCluster.inputSchema.type).toBe("object");
|
|
167
|
+
expectDefined(connectCluster.inputSchema.properties);
|
|
168
|
+
expect(connectCluster.inputSchema.properties).toHaveProperty("projectId");
|
|
169
|
+
expect(connectCluster.inputSchema.properties).toHaveProperty("clusterName");
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("connects to cluster", async () => {
|
|
173
|
+
const projectId = getProjectId();
|
|
174
|
+
|
|
175
|
+
const response = (await integration.mcpClient().callTool({
|
|
176
|
+
name: "atlas-connect-cluster",
|
|
177
|
+
arguments: { projectId, clusterName },
|
|
178
|
+
})) as CallToolResult;
|
|
179
|
+
expect(response.content).toBeArray();
|
|
180
|
+
expect(response.content).toHaveLength(1);
|
|
181
|
+
expect(response.content[0].text).toContain(`Connected to cluster "${clusterName}"`);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
120
184
|
});
|
|
121
185
|
});
|
|
@@ -1,147 +1,132 @@
|
|
|
1
1
|
import { describeWithMongoDB } from "../mongodbHelpers.js";
|
|
2
|
-
|
|
3
|
-
import { getResponseContent, validateToolMetadata } from "../../../helpers.js";
|
|
4
|
-
|
|
2
|
+
import { getResponseContent, validateThrowsForInvalidArguments, validateToolMetadata } from "../../../helpers.js";
|
|
5
3
|
import { config } from "../../../../../src/config.js";
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
required: false,
|
|
15
|
-
},
|
|
16
|
-
]);
|
|
17
|
-
|
|
18
|
-
describe("without arguments", () => {
|
|
19
|
-
it("prompts for connection string if not set", async () => {
|
|
20
|
-
const response = await integration.mcpClient().callTool({ name: "connect" });
|
|
21
|
-
const content = getResponseContent(response.content);
|
|
22
|
-
expect(content).toContain("No connection details provided");
|
|
5
|
+
// These tests are temporarily skipped because the connect tool is disabled for the initial release.
|
|
6
|
+
// TODO: https://github.com/mongodb-js/mongodb-mcp-server/issues/141 - reenable when the connect tool is reenabled
|
|
7
|
+
describeWithMongoDB(
|
|
8
|
+
"switchConnection tool",
|
|
9
|
+
(integration) => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
integration.mcpServer().userConfig.connectionString = integration.connectionString();
|
|
23
12
|
});
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
validateToolMetadata(
|
|
15
|
+
integration,
|
|
16
|
+
"switch-connection",
|
|
17
|
+
"Switch to a different MongoDB connection. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new instance.",
|
|
18
|
+
[
|
|
19
|
+
{
|
|
20
|
+
name: "connectionString",
|
|
21
|
+
description: "MongoDB connection string to switch to (in the mongodb:// or mongodb+srv:// format)",
|
|
22
|
+
type: "string",
|
|
23
|
+
required: false,
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
);
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
describe("without connection string", () => {
|
|
37
|
-
it("prompts for connection string", async () => {
|
|
38
|
-
const response = await integration.mcpClient().callTool({ name: "connect", arguments: {} });
|
|
39
|
-
const content = getResponseContent(response.content);
|
|
40
|
-
expect(content).toContain("No connection details provided");
|
|
41
|
-
});
|
|
42
|
-
});
|
|
28
|
+
validateThrowsForInvalidArguments(integration, "switch-connection", [{ connectionString: 123 }]);
|
|
43
29
|
|
|
44
|
-
describe("
|
|
30
|
+
describe("without arguments", () => {
|
|
45
31
|
it("connects to the database", async () => {
|
|
46
|
-
const response = await integration.mcpClient().callTool({
|
|
47
|
-
name: "connect",
|
|
48
|
-
arguments: {
|
|
49
|
-
options: [
|
|
50
|
-
{
|
|
51
|
-
connectionString: integration.connectionString(),
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
});
|
|
32
|
+
const response = await integration.mcpClient().callTool({ name: "switch-connection" });
|
|
56
33
|
const content = getResponseContent(response.content);
|
|
57
34
|
expect(content).toContain("Successfully connected");
|
|
58
|
-
expect(content).toContain(integration.connectionString());
|
|
59
35
|
});
|
|
60
36
|
});
|
|
61
37
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
arguments: { options: [{ connectionString: "mongodb://localhost:12345" }] },
|
|
67
|
-
});
|
|
68
|
-
const content = getResponseContent(response.content);
|
|
69
|
-
expect(content).toContain("Error running connect");
|
|
70
|
-
|
|
71
|
-
// Should not suggest using the config connection string (because we don't have one)
|
|
72
|
-
expect(content).not.toContain("Your config lists a different connection string");
|
|
73
|
-
});
|
|
38
|
+
it("doesn't have the connect tool registered", async () => {
|
|
39
|
+
const { tools } = await integration.mcpClient().listTools();
|
|
40
|
+
const tool = tools.find((tool) => tool.name === "connect");
|
|
41
|
+
expect(tool).toBeUndefined();
|
|
74
42
|
});
|
|
75
|
-
});
|
|
76
43
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
config.connectionString = integration.connectionString();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("uses the connection string from config", async () => {
|
|
83
|
-
const response = await integration.mcpClient().callTool({ name: "connect", arguments: {} });
|
|
44
|
+
it("defaults to the connection string from config", async () => {
|
|
45
|
+
const response = await integration.mcpClient().callTool({ name: "switch-connection", arguments: {} });
|
|
84
46
|
const content = getResponseContent(response.content);
|
|
85
47
|
expect(content).toContain("Successfully connected");
|
|
86
|
-
expect(content).toContain(integration.connectionString());
|
|
87
48
|
});
|
|
88
49
|
|
|
89
|
-
it("
|
|
50
|
+
it("switches to the connection string from the arguments", async () => {
|
|
90
51
|
const newConnectionString = `${integration.connectionString()}?appName=foo-bar`;
|
|
91
52
|
const response = await integration.mcpClient().callTool({
|
|
92
|
-
name: "
|
|
53
|
+
name: "switch-connection",
|
|
93
54
|
arguments: {
|
|
94
|
-
|
|
95
|
-
{
|
|
96
|
-
connectionString: newConnectionString,
|
|
97
|
-
},
|
|
98
|
-
],
|
|
55
|
+
connectionString: newConnectionString,
|
|
99
56
|
},
|
|
100
57
|
});
|
|
101
58
|
const content = getResponseContent(response.content);
|
|
102
59
|
expect(content).toContain("Successfully connected");
|
|
103
|
-
expect(content).toContain(newConnectionString);
|
|
104
60
|
});
|
|
105
61
|
|
|
106
62
|
describe("when the arugment connection string is invalid", () => {
|
|
107
|
-
it("
|
|
63
|
+
it("returns error message", async () => {
|
|
108
64
|
const response = await integration.mcpClient().callTool({
|
|
109
|
-
name: "
|
|
65
|
+
name: "switch-connection",
|
|
110
66
|
arguments: {
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
connectionString: "mongodb://localhost:12345",
|
|
114
|
-
},
|
|
115
|
-
],
|
|
67
|
+
connectionString: "mongodb://localhost:12345",
|
|
116
68
|
},
|
|
117
69
|
});
|
|
70
|
+
|
|
118
71
|
const content = getResponseContent(response.content);
|
|
119
|
-
|
|
120
|
-
expect(content).toContain(
|
|
121
|
-
`Your config lists a different connection string: '${config.connectionString}' - do you want to try connecting to it instead?`
|
|
122
|
-
);
|
|
72
|
+
|
|
73
|
+
expect(content).toContain("Error running switch-connection");
|
|
123
74
|
});
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
(mdbIntegration) => ({
|
|
78
|
+
...config,
|
|
79
|
+
connectionString: mdbIntegration.connectionString(),
|
|
80
|
+
}),
|
|
81
|
+
describe.skip
|
|
82
|
+
);
|
|
83
|
+
describeWithMongoDB(
|
|
84
|
+
"Connect tool",
|
|
85
|
+
(integration) => {
|
|
86
|
+
validateToolMetadata(integration, "connect", "Connect to a MongoDB instance", [
|
|
87
|
+
{
|
|
88
|
+
name: "connectionString",
|
|
89
|
+
description: "MongoDB connection string (in the mongodb:// or mongodb+srv:// format)",
|
|
90
|
+
type: "string",
|
|
91
|
+
required: true,
|
|
92
|
+
},
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
validateThrowsForInvalidArguments(integration, "connect", [{}, { connectionString: 123 }]);
|
|
96
|
+
|
|
97
|
+
it("doesn't have the switch-connection tool registered", async () => {
|
|
98
|
+
const { tools } = await integration.mcpClient().listTools();
|
|
99
|
+
const tool = tools.find((tool) => tool.name === "switch-connection");
|
|
100
|
+
expect(tool).toBeUndefined();
|
|
101
|
+
});
|
|
124
102
|
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
describe("with connection string", () => {
|
|
104
|
+
it("connects to the database", async () => {
|
|
127
105
|
const response = await integration.mcpClient().callTool({
|
|
128
106
|
name: "connect",
|
|
129
107
|
arguments: {
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
connectionString: "mongodb://localhost:12345",
|
|
133
|
-
},
|
|
134
|
-
],
|
|
108
|
+
connectionString: integration.connectionString(),
|
|
135
109
|
},
|
|
136
110
|
});
|
|
137
|
-
|
|
138
111
|
const content = getResponseContent(response.content);
|
|
112
|
+
expect(content).toContain("Successfully connected");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
139
115
|
|
|
140
|
-
|
|
141
|
-
|
|
116
|
+
describe("with invalid connection string", () => {
|
|
117
|
+
it("returns error message", async () => {
|
|
118
|
+
const response = await integration.mcpClient().callTool({
|
|
119
|
+
name: "connect",
|
|
120
|
+
arguments: { connectionString: "mongodb://localhost:12345" },
|
|
121
|
+
});
|
|
122
|
+
const content = getResponseContent(response.content);
|
|
142
123
|
expect(content).toContain("Error running connect");
|
|
124
|
+
|
|
125
|
+
// Should not suggest using the config connection string (because we don't have one)
|
|
143
126
|
expect(content).not.toContain("Your config lists a different connection string");
|
|
144
127
|
});
|
|
145
128
|
});
|
|
146
|
-
}
|
|
147
|
-
|
|
129
|
+
},
|
|
130
|
+
() => config,
|
|
131
|
+
describe.skip
|
|
132
|
+
);
|
|
@@ -3,29 +3,47 @@ import path from "path";
|
|
|
3
3
|
import fs from "fs/promises";
|
|
4
4
|
import { MongoClient, ObjectId } from "mongodb";
|
|
5
5
|
import { getResponseContent, IntegrationTest, setupIntegrationTest } from "../../helpers.js";
|
|
6
|
-
import { config } from "../../../../src/config.js";
|
|
6
|
+
import { config, UserConfig } from "../../../../src/config.js";
|
|
7
7
|
|
|
8
8
|
interface MongoDBIntegrationTest {
|
|
9
9
|
mongoClient: () => MongoClient;
|
|
10
10
|
connectionString: () => string;
|
|
11
|
-
connectMcpClient: () => Promise<void>;
|
|
12
11
|
randomDbName: () => string;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export function describeWithMongoDB(
|
|
16
15
|
name: string,
|
|
17
|
-
fn: (integration: IntegrationTest & MongoDBIntegrationTest) => void
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
fn: (integration: IntegrationTest & MongoDBIntegrationTest & { connectMcpClient: () => Promise<void> }) => void,
|
|
17
|
+
getUserConfig: (mdbIntegration: MongoDBIntegrationTest) => UserConfig = () => config,
|
|
18
|
+
describeFn = describe
|
|
19
|
+
) {
|
|
20
|
+
describeFn(name, () => {
|
|
21
|
+
const mdbIntegration = setupMongoDBIntegrationTest();
|
|
22
|
+
const integration = setupIntegrationTest(() => ({
|
|
23
|
+
...getUserConfig(mdbIntegration),
|
|
24
|
+
connectionString: mdbIntegration.connectionString(),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
integration.mcpServer().userConfig.connectionString = mdbIntegration.connectionString();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
fn({
|
|
32
|
+
...integration,
|
|
33
|
+
...mdbIntegration,
|
|
34
|
+
connectMcpClient: async () => {
|
|
35
|
+
// TODO: https://github.com/mongodb-js/mongodb-mcp-server/issues/141 - reenable when
|
|
36
|
+
// the connect tool is reenabled
|
|
37
|
+
// await integration.mcpClient().callTool({
|
|
38
|
+
// name: "connect",
|
|
39
|
+
// arguments: { connectionString: mdbIntegration.connectionString() },
|
|
40
|
+
// });
|
|
41
|
+
},
|
|
24
42
|
});
|
|
25
43
|
});
|
|
26
44
|
}
|
|
27
45
|
|
|
28
|
-
export function setupMongoDBIntegrationTest(
|
|
46
|
+
export function setupMongoDBIntegrationTest(): MongoDBIntegrationTest {
|
|
29
47
|
let mongoCluster: // TODO: Fix this type once mongodb-runner is updated.
|
|
30
48
|
| {
|
|
31
49
|
connectionString: string;
|
|
@@ -40,9 +58,6 @@ export function setupMongoDBIntegrationTest(integration: IntegrationTest): Mongo
|
|
|
40
58
|
});
|
|
41
59
|
|
|
42
60
|
afterEach(async () => {
|
|
43
|
-
await integration.mcpServer().session.close();
|
|
44
|
-
config.connectionString = undefined;
|
|
45
|
-
|
|
46
61
|
await mongoClient?.close();
|
|
47
62
|
mongoClient = undefined;
|
|
48
63
|
});
|
|
@@ -108,12 +123,7 @@ export function setupMongoDBIntegrationTest(integration: IntegrationTest): Mongo
|
|
|
108
123
|
return mongoClient;
|
|
109
124
|
},
|
|
110
125
|
connectionString: getConnectionString,
|
|
111
|
-
|
|
112
|
-
await integration.mcpClient().callTool({
|
|
113
|
-
name: "connect",
|
|
114
|
-
arguments: { options: [{ connectionString: getConnectionString() }] },
|
|
115
|
-
});
|
|
116
|
-
},
|
|
126
|
+
|
|
117
127
|
randomDbName: () => randomDbName,
|
|
118
128
|
};
|
|
119
129
|
}
|
|
@@ -128,13 +138,14 @@ export function validateAutoConnectBehavior(
|
|
|
128
138
|
},
|
|
129
139
|
beforeEachImpl?: () => Promise<void>
|
|
130
140
|
): void {
|
|
131
|
-
|
|
141
|
+
// TODO: https://github.com/mongodb-js/mongodb-mcp-server/issues/141 - reenable when the connect tool is reenabled
|
|
142
|
+
describe.skip("when not connected", () => {
|
|
132
143
|
if (beforeEachImpl) {
|
|
133
144
|
beforeEach(() => beforeEachImpl());
|
|
134
145
|
}
|
|
135
146
|
|
|
136
147
|
it("connects automatically if connection string is configured", async () => {
|
|
137
|
-
|
|
148
|
+
integration.mcpServer().userConfig.connectionString = integration.connectionString();
|
|
138
149
|
|
|
139
150
|
const validationInfo = validation();
|
|
140
151
|
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { ApiClient } from "../../src/common/atlas/apiClient.js";
|
|
2
|
+
import { Session } from "../../src/session.js";
|
|
3
|
+
import { Telemetry } from "../../src/telemetry/telemetry.js";
|
|
4
|
+
import { BaseEvent, TelemetryResult } from "../../src/telemetry/types.js";
|
|
5
|
+
import { EventCache } from "../../src/telemetry/eventCache.js";
|
|
6
|
+
import { config } from "../../src/config.js";
|
|
7
|
+
|
|
8
|
+
// Mock the ApiClient to avoid real API calls
|
|
9
|
+
jest.mock("../../src/common/atlas/apiClient.js");
|
|
10
|
+
const MockApiClient = ApiClient as jest.MockedClass<typeof ApiClient>;
|
|
11
|
+
|
|
12
|
+
// Mock EventCache to control and verify caching behavior
|
|
13
|
+
jest.mock("../../src/telemetry/eventCache.js");
|
|
14
|
+
const MockEventCache = EventCache as jest.MockedClass<typeof EventCache>;
|
|
15
|
+
|
|
16
|
+
describe("Telemetry", () => {
|
|
17
|
+
let mockApiClient: jest.Mocked<ApiClient>;
|
|
18
|
+
let mockEventCache: jest.Mocked<EventCache>;
|
|
19
|
+
let session: Session;
|
|
20
|
+
let telemetry: Telemetry;
|
|
21
|
+
|
|
22
|
+
// Helper function to create properly typed test events
|
|
23
|
+
function createTestEvent(options?: {
|
|
24
|
+
source?: string;
|
|
25
|
+
result?: TelemetryResult;
|
|
26
|
+
component?: string;
|
|
27
|
+
category?: string;
|
|
28
|
+
command?: string;
|
|
29
|
+
duration_ms?: number;
|
|
30
|
+
}): BaseEvent {
|
|
31
|
+
return {
|
|
32
|
+
timestamp: new Date().toISOString(),
|
|
33
|
+
source: options?.source || "mdbmcp",
|
|
34
|
+
properties: {
|
|
35
|
+
component: options?.component || "test-component",
|
|
36
|
+
duration_ms: options?.duration_ms || 100,
|
|
37
|
+
result: options?.result || "success",
|
|
38
|
+
category: options?.category || "test",
|
|
39
|
+
command: options?.command || "test-command",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Helper function to verify mock calls to reduce duplication
|
|
45
|
+
function verifyMockCalls({
|
|
46
|
+
sendEventsCalls = 0,
|
|
47
|
+
clearEventsCalls = 0,
|
|
48
|
+
appendEventsCalls = 0,
|
|
49
|
+
sendEventsCalledWith = undefined,
|
|
50
|
+
appendEventsCalledWith = undefined,
|
|
51
|
+
} = {}) {
|
|
52
|
+
const { calls: sendEvents } = mockApiClient.sendEvents.mock;
|
|
53
|
+
const { calls: clearEvents } = mockEventCache.clearEvents.mock;
|
|
54
|
+
const { calls: appendEvents } = mockEventCache.appendEvents.mock;
|
|
55
|
+
|
|
56
|
+
expect(sendEvents.length).toBe(sendEventsCalls);
|
|
57
|
+
expect(clearEvents.length).toBe(clearEventsCalls);
|
|
58
|
+
expect(appendEvents.length).toBe(appendEventsCalls);
|
|
59
|
+
|
|
60
|
+
if (sendEventsCalledWith) {
|
|
61
|
+
expect(sendEvents[0]?.[0]).toEqual(sendEventsCalledWith);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (appendEventsCalledWith) {
|
|
65
|
+
expect(appendEvents[0]?.[0]).toEqual(appendEventsCalledWith);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
// Reset mocks before each test
|
|
71
|
+
jest.clearAllMocks();
|
|
72
|
+
|
|
73
|
+
// Setup mocked API client
|
|
74
|
+
mockApiClient = new MockApiClient() as jest.Mocked<ApiClient>;
|
|
75
|
+
mockApiClient.sendEvents = jest.fn().mockResolvedValue(undefined);
|
|
76
|
+
mockApiClient.hasCredentials = jest.fn().mockReturnValue(true);
|
|
77
|
+
|
|
78
|
+
// Setup mocked EventCache
|
|
79
|
+
mockEventCache = new MockEventCache() as jest.Mocked<EventCache>;
|
|
80
|
+
mockEventCache.getEvents = jest.fn().mockReturnValue([]);
|
|
81
|
+
mockEventCache.clearEvents = jest.fn().mockResolvedValue(undefined);
|
|
82
|
+
mockEventCache.appendEvents = jest.fn().mockResolvedValue(undefined);
|
|
83
|
+
MockEventCache.getInstance = jest.fn().mockReturnValue(mockEventCache);
|
|
84
|
+
|
|
85
|
+
// Create a simplified session with our mocked API client
|
|
86
|
+
session = {
|
|
87
|
+
apiClient: mockApiClient,
|
|
88
|
+
sessionId: "test-session-id",
|
|
89
|
+
agentRunner: { name: "test-agent", version: "1.0.0" } as const,
|
|
90
|
+
close: jest.fn().mockResolvedValue(undefined),
|
|
91
|
+
setAgentRunner: jest.fn().mockResolvedValue(undefined),
|
|
92
|
+
} as unknown as Session;
|
|
93
|
+
|
|
94
|
+
// Create the telemetry instance with mocked dependencies
|
|
95
|
+
telemetry = new Telemetry(session, mockEventCache);
|
|
96
|
+
|
|
97
|
+
config.telemetry = "enabled";
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("when telemetry is enabled", () => {
|
|
101
|
+
it("should send events successfully", async () => {
|
|
102
|
+
const testEvent = createTestEvent();
|
|
103
|
+
|
|
104
|
+
await telemetry.emitEvents([testEvent]);
|
|
105
|
+
|
|
106
|
+
verifyMockCalls({
|
|
107
|
+
sendEventsCalls: 1,
|
|
108
|
+
clearEventsCalls: 1,
|
|
109
|
+
sendEventsCalledWith: [testEvent],
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("should cache events when sending fails", async () => {
|
|
114
|
+
mockApiClient.sendEvents.mockRejectedValueOnce(new Error("API error"));
|
|
115
|
+
|
|
116
|
+
const testEvent = createTestEvent();
|
|
117
|
+
|
|
118
|
+
await telemetry.emitEvents([testEvent]);
|
|
119
|
+
|
|
120
|
+
verifyMockCalls({
|
|
121
|
+
sendEventsCalls: 1,
|
|
122
|
+
appendEventsCalls: 1,
|
|
123
|
+
appendEventsCalledWith: [testEvent],
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("should include cached events when sending", async () => {
|
|
128
|
+
const cachedEvent = createTestEvent({
|
|
129
|
+
command: "cached-command",
|
|
130
|
+
component: "cached-component",
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const newEvent = createTestEvent({
|
|
134
|
+
command: "new-command",
|
|
135
|
+
component: "new-component",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Set up mock to return cached events
|
|
139
|
+
mockEventCache.getEvents.mockReturnValueOnce([cachedEvent]);
|
|
140
|
+
|
|
141
|
+
await telemetry.emitEvents([newEvent]);
|
|
142
|
+
|
|
143
|
+
verifyMockCalls({
|
|
144
|
+
sendEventsCalls: 1,
|
|
145
|
+
clearEventsCalls: 1,
|
|
146
|
+
sendEventsCalledWith: [cachedEvent, newEvent],
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe("when telemetry is disabled", () => {
|
|
152
|
+
beforeEach(() => {
|
|
153
|
+
config.telemetry = "disabled";
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("should not send events", async () => {
|
|
157
|
+
const testEvent = createTestEvent();
|
|
158
|
+
|
|
159
|
+
await telemetry.emitEvents([testEvent]);
|
|
160
|
+
|
|
161
|
+
verifyMockCalls();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("should correctly add common properties to events", () => {
|
|
166
|
+
const commonProps = telemetry.getCommonProperties();
|
|
167
|
+
|
|
168
|
+
// Use explicit type assertion
|
|
169
|
+
const expectedProps: Record<string, string> = {
|
|
170
|
+
mcp_client_version: "1.0.0",
|
|
171
|
+
mcp_client_name: "test-agent",
|
|
172
|
+
session_id: "test-session-id",
|
|
173
|
+
config_atlas_auth: "true",
|
|
174
|
+
config_connection_string: expect.any(String) as unknown as string,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
expect(commonProps).toMatchObject(expectedProps);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe("when DO_NOT_TRACK environment variable is set", () => {
|
|
181
|
+
let originalEnv: string | undefined;
|
|
182
|
+
|
|
183
|
+
beforeEach(() => {
|
|
184
|
+
originalEnv = process.env.DO_NOT_TRACK;
|
|
185
|
+
process.env.DO_NOT_TRACK = "1";
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
afterEach(() => {
|
|
189
|
+
process.env.DO_NOT_TRACK = originalEnv;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("should not send events", async () => {
|
|
193
|
+
const testEvent = createTestEvent();
|
|
194
|
+
|
|
195
|
+
await telemetry.emitEvents([testEvent]);
|
|
196
|
+
|
|
197
|
+
verifyMockCalls();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createAccessList.js","sourceRoot":"","sources":["../../../src/tools/atlas/createAccessList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IAAvD;;QACc,SAAI,GAAG,0BAA0B,CAAC;QAClC,gBAAW,GAAG,6DAA6D,CAAC;QAC5E,kBAAa,GAAkB,QAAQ,CAAC;QACxC,cAAS,GAAG;YAClB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAClD,WAAW,EAAE,CAAC;iBACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC,QAAQ,CAAC,mCAAmC,CAAC;iBAC7C,QAAQ,EAAE;YACf,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,QAAQ,EAAE;YAC9F,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;YACnF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE;SAC1G,CAAC;IAuDN,CAAC;IArDa,KAAK,CAAC,OAAO,CAAC,EACpB,SAAS,EACT,WAAW,EACX,UAAU,EACV,OAAO,EACP,gBAAgB,GACc;QAC9B,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC3F,CAAC;QAED,MAAM,QAAQ,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACrD,OAAO,EAAE,SAAS;YAClB,SAAS;YACT,OAAO,EAAE,OAAO,IAAI,eAAe;SACtC,CAAC,CAAC,CAAC;QAEJ,IAAI,gBAAgB,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG;gBACV,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS,CAAC,kBAAkB;gBACvC,OAAO,EAAE,OAAO,IAAI,eAAe;aACtC,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACtD,OAAO,EAAE,SAAS;YAClB,SAAS;YACT,OAAO,EAAE,OAAO,IAAI,eAAe;SACtC,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;QAE5C,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,yBAAyB,CAAC;YACnD,MAAM,EAAE;gBACJ,IAAI,EAAE;oBACF,OAAO,EAAE,SAAS;iBACrB;aACJ;YACD,IAAI,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,OAAO;YACH,OAAO,EAAE;gBACL;oBACI,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,mDAAmD,SAAS,GAAG;iBACxE;aACJ;SACJ,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createDBUser.js","sourceRoot":"","sources":["../../../src/tools/atlas/createDBUser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IAAnD;;QACc,SAAI,GAAG,sBAAsB,CAAC;QAC9B,gBAAW,GAAG,uCAAuC,CAAC;QACtD,kBAAa,GAAkB,QAAQ,CAAC;QACxC,cAAS,GAAG;YAClB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAClD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC1D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC1D,KAAK,EAAE,CAAC;iBACH,KAAK,CACF,CAAC,CAAC,MAAM,CAAC;gBACL,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC1C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;gBACnE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;aACpE,CAAC,CACL;iBACA,QAAQ,CAAC,wBAAwB,CAAC;YACvC,QAAQ,EAAE,CAAC;iBACN,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,CAAC,wEAAwE,CAAC;iBAClF,QAAQ,EAAE;SAClB,CAAC;IAwCN,CAAC;IAtCa,KAAK,CAAC,OAAO,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,GACsB;QAC9B,MAAM,KAAK,GAAG;YACV,OAAO,EAAE,SAAS;YAClB,UAAU,EAAE,MAAM;YAClB,YAAY,EAAE,OAAO;YACrB,YAAY,EAAE,MAAM;YACpB,YAAY,EAAE,MAAM;YACpB,QAAQ,EAAE,MAAM;YAChB,QAAQ;YACR,QAAQ;YACR,KAAK,EAAE,KAAsC;YAC7C,MAAM,EAAE,QAAQ,EAAE,MAAM;gBACpB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACvB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,OAAO;iBAChB,CAAC,CAAC;gBACL,CAAC,CAAC,SAAS;SACG,CAAC;QAEvB,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC;YAC5C,MAAM,EAAE;gBACJ,IAAI,EAAE;oBACF,OAAO,EAAE,SAAS;iBACrB;aACJ;YACD,IAAI,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,OAAO;YACH,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,QAAQ,wBAAwB,EAAE,CAAC;SAC/E,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createFreeCluster.js","sourceRoot":"","sources":["../../../src/tools/atlas/createFreeCluster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IAAxD;;QACc,SAAI,GAAG,2BAA2B,CAAC;QACnC,gBAAW,GAAG,qCAAqC,CAAC;QACpD,kBAAa,GAAkB,QAAQ,CAAC;QACxC,cAAS,GAAG;YAClB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YAC3E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;SAC5E,CAAC;IAsCN,CAAC;IApCa,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAmC;QAChF,MAAM,KAAK,GAAG;YACV,OAAO,EAAE,SAAS;YAClB,IAAI;YACJ,WAAW,EAAE,YAAY;YACzB,gBAAgB,EAAE;gBACd;oBACI,QAAQ,EAAE,QAAQ;oBAClB,aAAa,EAAE;wBACX;4BACI,YAAY,EAAE,QAAQ;4BACtB,mBAAmB,EAAE,KAAK;4BAC1B,UAAU,EAAE,MAAM;4BAClB,cAAc,EAAE;gCACZ,YAAY,EAAE,IAAI;6BACrB;yBACJ;qBACJ;iBACJ;aACJ;YACD,4BAA4B,EAAE,KAAK;SACG,CAAC;QAE3C,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC;YACvC,MAAM,EAAE;gBACJ,IAAI,EAAE;oBACF,OAAO,EAAE,SAAS;iBACrB;aACJ;YACD,IAAI,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,OAAO;YACH,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,IAAI,iCAAiC,MAAM,IAAI,EAAE,CAAC;SACjG,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createProject.js","sourceRoot":"","sources":["../../../src/tools/atlas/createProject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAApD;;QACc,SAAI,GAAG,sBAAsB,CAAC;QAC9B,gBAAW,GAAG,gCAAgC,CAAC;QAC/C,kBAAa,GAAkB,QAAQ,CAAC;QACxC,cAAS,GAAG;YAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YACvE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SACxF,CAAC;IAgDN,CAAC;IA9Ca,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,cAAc,EAAmC;QACpF,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,WAAW,GAAG,eAAe,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,IAAI,CAAC;gBACD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC;gBACvE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CACX,iGAAiG,CACpG,CAAC;gBACN,CAAC;gBACD,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,UAAU,GAAG,IAAI,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACL,MAAM,IAAI,KAAK,CACX,0HAA0H,CAC7H,CAAC;YACN,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAG;YACV,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,cAAc;SACf,CAAC;QAEX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC;YACrD,IAAI,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAChD,CAAC;QAED,OAAO;YACH,OAAO,EAAE;gBACL;oBACI,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,YAAY,WAAW,yBAAyB,UAAU,CAAC,CAAC,CAAC,0BAA0B,cAAc,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG;iBAC1H;aACJ;SACJ,CAAC;IACN,CAAC;CACJ"}
|