• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 16347477296

17 Jul 2025 02:10PM UTC coverage: 77.304% (-0.09%) from 77.39%
16347477296

Pull #378

github

web-flow
Merge 2f2bcf319 into fd3f2a4fd
Pull Request #378: chore: specify the correct minimum node requirements

496 of 685 branches covered (72.41%)

Branch coverage included in aggregate %.

2825 of 3611 relevant lines covered (78.23%)

28.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/scripts/apply.ts
1
import fs from "fs/promises";
×
2
import { OpenAPIV3_1 } from "openapi-types";
3
import argv from "yargs-parser";
×
4

5
function findObjectFromRef<T>(obj: T | OpenAPIV3_1.ReferenceObject, openapi: OpenAPIV3_1.Document): T {
×
6
    const ref = (obj as OpenAPIV3_1.ReferenceObject).$ref;
×
7
    if (ref === undefined) {
×
8
        return obj as T;
×
9
    }
×
10
    const paramParts = ref.split("/");
×
11
    paramParts.shift(); // Remove the first part which is always '#'
×
12

13
    let foundObj: Record<string, unknown> = openapi;
×
14
    while (true) {
×
15
        const part = paramParts.shift();
×
16
        if (!part) {
×
17
            break;
×
18
        }
×
19

20
        foundObj = foundObj[part] as Record<string, unknown>;
×
21
    }
×
22
    return foundObj as T;
×
23
}
×
24

25
async function main() {
×
26
    const { spec, file } = argv(process.argv.slice(2));
×
27

28
    if (!spec || !file) {
×
29
        console.error("Please provide both --spec and --file arguments.");
×
30
        process.exit(1);
×
31
    }
×
32

33
    const specFile = await fs.readFile(spec as string, "utf8");
×
34

35
    const operations: {
×
36
        path: string;
37
        method: string;
38
        operationId: string;
39
        requiredParams: boolean;
40
        tag: string;
41
        hasResponseBody: boolean;
42
    }[] = [];
×
43

44
    const openapi = JSON.parse(specFile) as OpenAPIV3_1.Document;
×
45
    for (const path in openapi.paths) {
×
46
        for (const method in openapi.paths[path]) {
×
47
            // @ts-expect-error This is a workaround for the OpenAPI types
48
            const operation = openapi.paths[path][method] as OpenAPIV3_1.OperationObject;
×
49

50
            if (!operation.operationId || !operation.tags?.length) {
×
51
                continue;
×
52
            }
×
53

54
            let requiredParams = !!operation.requestBody;
×
55
            let hasResponseBody = false;
×
56
            for (const code in operation.responses) {
×
57
                try {
×
58
                    const httpCode = parseInt(code, 10);
×
59
                    if (httpCode >= 200 && httpCode < 300) {
×
60
                        const response = operation.responses[code];
×
61
                        const responseObject = findObjectFromRef(response, openapi) as OpenAPIV3_1.ResponseObject;
×
62
                        if (responseObject && responseObject.content) {
×
63
                            for (const contentType in responseObject.content) {
×
64
                                const content = responseObject.content[contentType];
×
65
                                hasResponseBody = !!content?.schema;
×
66
                            }
×
67
                        }
×
68
                    }
×
69
                } catch {
×
70
                    continue;
×
71
                }
×
72
            }
×
73

74
            for (const param of operation.parameters || []) {
×
75
                const paramObject = findObjectFromRef(param, openapi);
×
76
                if (paramObject.in === "path") {
×
77
                    requiredParams = true;
×
78
                }
×
79
            }
×
80

81
            operations.push({
×
82
                path,
×
83
                method: method.toUpperCase(),
×
84
                operationId: operation.operationId || "",
×
85
                requiredParams,
×
86
                hasResponseBody,
×
87
                tag: operation.tags?.[0] ?? "",
×
88
            });
×
89
        }
×
90
    }
×
91

92
    const operationOutput = operations
×
93
        .map((operation) => {
×
94
            const { operationId, method, path, requiredParams, hasResponseBody } = operation;
×
95
            return `async ${operationId}(options${requiredParams ? "" : "?"}: FetchOptions<operations["${operationId}"]>) {
×
96
    const { ${hasResponseBody ? `data, ` : ``}error, response } = await this.client.${method}("${path}", options);
×
97
    if (error) {
98
        throw ApiClientError.fromError(response, error);
99
    }
100
    ${
101
        hasResponseBody
×
102
            ? `return data;
×
103
`
104
            : ``
×
105
    }}
×
106
`;
107
        })
×
108
        .join("\n");
×
109

110
    const templateFile = await fs.readFile(file as string, "utf8");
×
111
    const templateLines = templateFile.split("\n");
×
112
    const outputLines: string[] = [];
×
113
    let addLines = true;
×
114
    for (const line of templateLines) {
×
115
        if (line.includes("DO NOT EDIT. This is auto-generated code.")) {
×
116
            addLines = !addLines;
×
117
            outputLines.push(line);
×
118
            if (!addLines) {
×
119
                outputLines.push(operationOutput);
×
120
            }
×
121
            continue;
×
122
        }
×
123
        if (addLines) {
×
124
            outputLines.push(line);
×
125
        }
×
126
    }
×
127
    const output = outputLines.join("\n");
×
128

129
    await fs.writeFile(file as string, output, "utf8");
×
130
}
×
131

132
main().catch((error) => {
×
133
    console.error("Error:", error);
×
134
    process.exit(1);
×
135
});
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc