jochen-schweizer / express-prom-bundle

express middleware with standard prometheus metrics in one bundle
MIT License
303 stars 67 forks source link

Typescript: normalizePath is const but needs to be set to get req.route.path #129

Closed makadev closed 2 months ago

makadev commented 2 months ago

Hi, I've set up express-prom-bundle with includePath: true and path normalization to use req.route.path instead of the real path (as documented in example 3) using the following middleware:

import type { Express, Request } from "express";
import promBundle from "express-prom-bundle";

export function applyPrometheusMiddleware(app: Express) {
    const metricsMiddleware = promBundle({
        includeStatusCode: true,
        includeMethod: true,
        includePath: true,
        // do not set normalizePath function here, it won't work with route.path
    });
    app.use(metricsMiddleware);
    promBundle.normalizePath = (req: Request) => {
        // Return the path of the express route (i.e. /v1/user/:id or /v1/timer/automated/:userid/:timerid")
        return req.route?.path ?? "NULL";
    };
}

This will throw an error when trying to transpile it with typescript compiler:

app/middleware/prometheus.middleware.ts:12:16 - error TS2540: Cannot assign to 'normalizePath' because it is a read-only property.

12     promBundle.normalizePath = (req: Request) => {
                  ~~~~~~~~~~~~~

The problem seems to be that nromalizePath is declared as const: https://github.com/jochen-schweizer/express-prom-bundle/blob/fd5ff1cfe0ac522c669cd8af92cf009d500d6caf/types/index.d.ts#L79

Expected would be let or maybe a hidden property and setter function.

For now I work around it by setting @ts-expect-error to suppress the error.

makadev commented 2 months ago

nvm, seems the example 3 is not needed and setting normalizePath in options is enough, it's not working for part of my routes for another reason (nested routing probably)