Skip to content

Commit 8efb029

Browse files
refactor: Replace z.string with CommonArgs.string (#629)
1 parent 91c11cc commit 8efb029

File tree

4 files changed

+89
-6
lines changed

4 files changed

+89
-6
lines changed

src/tools/args.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { z, type ZodString } from "zod";
2+
import { EJSON } from "bson";
3+
4+
const NO_UNICODE_REGEX = /^[\x20-\x7E]*$/;
5+
export const NO_UNICODE_ERROR = "String cannot contain special characters or Unicode symbols";
6+
7+
const ALLOWED_USERNAME_CHARACTERS_REGEX = /^[a-zA-Z0-9._-]+$/;
8+
export const ALLOWED_USERNAME_CHARACTERS_ERROR =
9+
"Username can only contain letters, numbers, dots, hyphens, and underscores";
10+
11+
const ALLOWED_REGION_CHARACTERS_REGEX = /^[a-zA-Z0-9_-]+$/;
12+
export const ALLOWED_REGION_CHARACTERS_ERROR = "Region can only contain letters, numbers, hyphens, and underscores";
13+
14+
const ALLOWED_CLUSTER_NAME_CHARACTERS_REGEX = /^[a-zA-Z0-9_-]+$/;
15+
export const ALLOWED_CLUSTER_NAME_CHARACTERS_ERROR =
16+
"Cluster names can only contain ASCII letters, numbers, and hyphens.";
17+
18+
const ALLOWED_PROJECT_NAME_CHARACTERS_REGEX = /^[a-zA-Z0-9\s()@&+:._',-]+$/;
19+
export const ALLOWED_PROJECT_NAME_CHARACTERS_ERROR =
20+
"Project names can't be longer than 64 characters and can only contain letters, numbers, spaces, and the following symbols: ( ) @ & + : . _ - ' ,";
21+
export const CommonArgs = {
22+
string: (): ZodString => z.string().regex(NO_UNICODE_REGEX, NO_UNICODE_ERROR),
23+
24+
objectId: (fieldName: string): z.ZodString =>
25+
z
26+
.string()
27+
.min(1, `${fieldName} is required`)
28+
.length(24, `${fieldName} must be exactly 24 characters`)
29+
.regex(/^[0-9a-fA-F]+$/, `${fieldName} must contain only hexadecimal characters`),
30+
};
31+
32+
export const AtlasArgs = {
33+
projectId: (): z.ZodString => CommonArgs.objectId("projectId"),
34+
35+
organizationId: (): z.ZodString => CommonArgs.objectId("organizationId"),
36+
37+
clusterName: (): z.ZodString =>
38+
z
39+
.string()
40+
.min(1, "Cluster name is required")
41+
.max(64, "Cluster name must be 64 characters or less")
42+
.regex(ALLOWED_CLUSTER_NAME_CHARACTERS_REGEX, ALLOWED_CLUSTER_NAME_CHARACTERS_ERROR),
43+
44+
projectName: (): z.ZodString =>
45+
z
46+
.string()
47+
.min(1, "Project name is required")
48+
.max(64, "Project name must be 64 characters or less")
49+
.regex(ALLOWED_PROJECT_NAME_CHARACTERS_REGEX, ALLOWED_PROJECT_NAME_CHARACTERS_ERROR),
50+
51+
username: (): z.ZodString =>
52+
z
53+
.string()
54+
.min(1, "Username is required")
55+
.max(100, "Username must be 100 characters or less")
56+
.regex(ALLOWED_USERNAME_CHARACTERS_REGEX, ALLOWED_USERNAME_CHARACTERS_ERROR),
57+
58+
ipAddress: (): z.ZodString => z.string().ip({ version: "v4" }),
59+
60+
cidrBlock: (): z.ZodString => z.string().cidr(),
61+
62+
region: (): z.ZodString =>
63+
z
64+
.string()
65+
.min(1, "Region is required")
66+
.max(50, "Region must be 50 characters or less")
67+
.regex(ALLOWED_REGION_CHARACTERS_REGEX, ALLOWED_REGION_CHARACTERS_ERROR),
68+
69+
password: (): z.ZodString =>
70+
z.string().min(1, "Password is required").max(100, "Password must be 100 characters or less"),
71+
};
72+
73+
function toEJSON<T extends object | undefined>(value: T): T {
74+
if (!value) {
75+
return value;
76+
}
77+
78+
return EJSON.deserialize(value, { relaxed: false }) as T;
79+
}
80+
81+
export function zEJSON(): z.AnyZodObject {
82+
return z.object({}).passthrough().transform(toEJSON) as unknown as z.AnyZodObject;
83+
}

src/tools/atlasLocal/connect/connectDeployment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
22
import { AtlasLocalToolBase } from "../atlasLocalTool.js";
33
import type { OperationType, ToolArgs } from "../../tool.js";
44
import type { Client } from "@mongodb-js-preview/atlas-local";
5-
import { z } from "zod";
5+
import { CommonArgs } from "../../args.js";
66

77
export class ConnectDeploymentTool extends AtlasLocalToolBase {
88
public name = "atlas-local-connect-deployment";
99
protected description = "Connect to a MongoDB Atlas Local deployment";
1010
public operationType: OperationType = "connect";
1111
protected argsShape = {
12-
deploymentName: z.string().describe("Name of the deployment to connect to"),
12+
deploymentName: CommonArgs.string().describe("Name of the deployment to connect to"),
1313
};
1414

1515
protected async executeWithAtlasLocalClient(

src/tools/atlasLocal/create/createDeployment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
22
import { AtlasLocalToolBase } from "../atlasLocalTool.js";
33
import type { OperationType, ToolArgs } from "../../tool.js";
44
import type { Client, CreateDeploymentOptions, CreationSourceType } from "@mongodb-js-preview/atlas-local";
5-
import z from "zod";
5+
import { CommonArgs } from "../../args.js";
66

77
export class CreateDeploymentTool extends AtlasLocalToolBase {
88
public name = "atlas-local-create-deployment";
99
protected description = "Create a MongoDB Atlas local deployment";
1010
public operationType: OperationType = "create";
1111
protected argsShape = {
12-
deploymentName: z.string().describe("Name of the deployment to create").optional(),
12+
deploymentName: CommonArgs.string().describe("Name of the deployment to create").optional(),
1313
};
1414

1515
protected async executeWithAtlasLocalClient(

src/tools/atlasLocal/delete/deleteDeployment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { z } from "zod";
21
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
32
import { AtlasLocalToolBase } from "../atlasLocalTool.js";
43
import type { OperationType, ToolArgs } from "../../tool.js";
54
import type { Client } from "@mongodb-js-preview/atlas-local";
5+
import { CommonArgs } from "../../args.js";
66

77
export class DeleteDeploymentTool extends AtlasLocalToolBase {
88
public name = "atlas-local-delete-deployment";
99
protected description = "Delete a MongoDB Atlas local deployment";
1010
public operationType: OperationType = "delete";
1111
protected argsShape = {
12-
deploymentName: z.string().describe("Name of the deployment to delete"),
12+
deploymentName: CommonArgs.string().describe("Name of the deployment to delete"),
1313
};
1414

1515
protected async executeWithAtlasLocalClient(

0 commit comments

Comments
 (0)