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

SAP / ui5-tooling-extensions / 16248276690

13 Jul 2025 10:44AM CUT coverage: 100.0%. First build
16248276690

Pull #418

github

web-flow
Merge ecdeccafd into 8452b94f8
Pull Request #418: build(deps-dev): Bump sinon from 20.0.0 to 21.0.0

51 of 51 branches covered (100.0%)

Branch coverage included in aggregate %.

106 of 106 relevant lines covered (100.0%)

6.32 hits per line

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

100.0
/packages/middleware-code-coverage/lib/middleware.js
1
// @ts-nocheck
2
import {
3
        createInstrumentationConfig,
4
        shouldInstrumentResource,
5
        getLatestSourceMap,
6
        readJsonFile} from "./util.js";
7
import {createInstrumenter} from "istanbul-lib-instrument";
8
import reportCoverage from "./coverage-reporter.js";
9
import bodyParser from "body-parser";
10
import Router from "router";
11
import path from "node:path";
12
import serveStatic from "serve-static";
13
import {promisify} from "node:util";
14

15
/**
16
 * Custom middleware to instrument JS files with Istanbul.
17
 *
18
 * @param {object} parameters Parameters
19
 * @param {@ui5/logger/Logger} parameters.log
20
 *      Logger instance for use in the custom middleware.
21
 *      This parameter is only provided to custom middleware
22
 * @param {object} parameters.middlewareUtil Specification version dependent interface to a
23
 *                                                                                 [MiddlewareUtil]{https://sap.github.io/ui5-tooling/v3/api/@ui5_server_middleware_MiddlewareUtil.html} instance
24
 * @param {object} parameters.options Options
25
 * @param {string} [parameters.options.configuration] Custom server middleware configuration if given in ui5.yaml
26
 * @param {object} parameters.resources Resource collections
27
 * @param {module:@ui5/fs.AbstractReader} parameters.resources.all Reader or Collection to read resources of the
28
 *                                                                                 root project and its dependencies
29
 * @param {module:@ui5/fs.AbstractReader} parameters.resources.rootProject Reader or Collection to read resources of
30
 *                                                                                 the project the server is started in
31
 * @param {module:@ui5/fs.AbstractReader} parameters.resources.dependencies Reader or Collection to read resources of
32
 *                                                                                 the projects dependencies
33
 * @returns {Function} Middleware function to use
34
 */
35
export default async function({log, middlewareUtil, options={}, resources}) {
7✔
36
        const config = await createInstrumentationConfig(
9✔
37
                options.configuration,
38
                resources.all
39
        );
40
        const {
41
                report: reporterConfig,
42
                instrument: instrumenterConfig,
43
                ...generalConfig
44
        } = config;
9✔
45

46
        const {version: middlewareVersion} = await readJsonFile(new URL("../package.json", import.meta.url));
9✔
47

48
        // Instrumenter instance
49
        const instrumenter = createInstrumenter(instrumenterConfig);
9✔
50
        const instrument = promisify(instrumenter.instrument.bind(instrumenter));
9✔
51

52
        const router = new Router();
9✔
53

54
        /**
55
         * Handles Reporting requests
56
         *
57
         * Example:
58
         *   fetch("/.ui5/coverage/report", {
59
         *       method: "POST",
60
         *       body: JSON.stringify(window.__coverage__),
61
         *       headers: {
62
         *           'Content-Type': 'application/json'
63
         *       },
64
         *   });
65
         *
66
         */
67
        router.post(
9✔
68
                "/.ui5/coverage/report",
69
                bodyParser.json({type: "application/json", limit: "50mb"}),
70
                async (req, res) => {
71
                        const reportData = await reportCoverage(
2✔
72
                                req.body,
73
                                config,
74
                                resources,
75
                                log
76
                        );
77

78
                        if (reportData) {
2✔
79
                                res.json(reportData);
1✔
80
                        } else {
81
                                res.err("No report data provided");
1✔
82
                        }
83
                }
84
        );
85

86
        /**
87
         * Endpoint to check for middleware existence
88
         */
89
        router.get("/.ui5/coverage/ping", async (req, res) => {
9✔
90
                res.json({
1✔
91
                        version: middlewareVersion
92
                });
93
        });
94

95
        /**
96
         * Serves generated reports as static assets
97
         */
98
        reporterConfig.reporter.forEach((reportType) =>
9✔
99
                router.use(
9✔
100
                        `/.ui5/coverage/report/${reportType}`,
101
                        serveStatic(
102
                                path.join(config.cwd, reporterConfig["report-dir"], reportType)
103
                        )
104
                )
105
        );
106

107
        router.use(async (req, res, next) => {
9✔
108
                // Skip files which should not be instrumented
109
                if (!shouldInstrumentResource(req, generalConfig)) {
5✔
110
                        next();
1✔
111
                        return;
1✔
112
                }
113

114
                log.verbose(`handling ${req.path}...`);
4✔
115

116
                const pathname = middlewareUtil.getPathname(req);
4✔
117
                const matchedResource = await resources.all.byPath(pathname);
4✔
118

119
                if (!matchedResource) {
4✔
120
                        log.warn(`${pathname} not found`);
1✔
121
                        next();
1✔
122
                        return;
1✔
123
                }
124

125
                const source = await matchedResource.getString();
3✔
126
                let instrumentedSource = await instrument(source, pathname);
3✔
127

128
                log.verbose(`...${pathname} instrumented!`);
3✔
129

130
                // Append sourceMap
131
                if (instrumenterConfig.produceSourceMap) {
3✔
132
                        instrumentedSource += getLatestSourceMap(instrumenter);
2✔
133

134
                        log.verbose(`...${pathname} sourceMap embedded!`);
2✔
135
                }
136

137
                // send out instrumented source + source map
138
                res.type(".js");
3✔
139
                res.end(instrumentedSource);
3✔
140
        });
141

142
        return router;
9✔
143
}
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