Skip to content

Commit

Permalink
fix: types for the proxy option (#4173)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Jan 13, 2022
1 parent c9a3aeb commit efec2f5
Show file tree
Hide file tree
Showing 2 changed files with 311 additions and 283 deletions.
244 changes: 120 additions & 124 deletions lib/Server.js
Expand Up @@ -110,22 +110,22 @@ const schema = require("./options.json");
*/

/**
* @typedef {{ [url: string]: string | HttpProxyMiddlewareOptions }} ProxyConfigMap
* @callback ByPass
* @param {Request} req
* @param {Response} res
* @param {ProxyConfigArrayItem} proxyConfig
*/

/**
* @typedef {HttpProxyMiddlewareOptions[]} ProxyArray
* @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem
*/

/**
* @callback ByPass
* @param {Request} req
* @param {Response} res
* @param {ProxyConfigArray} proxyConfig
* @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray
*/

/**
* @typedef {{ path?: string | string[] | undefined, context?: string | string[] | HttpProxyMiddlewareOptionsFilter | undefined } & HttpProxyMiddlewareOptions & ByPass} ProxyConfigArray
* @typedef {{ [url: string]: string | ProxyConfigArrayItem }} ProxyConfigMap
*/

/**
Expand Down Expand Up @@ -194,7 +194,7 @@ const schema = require("./options.json");
* @property {boolean} [http2]
* @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server]
* @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer]
* @property {ProxyConfigMap | ProxyConfigArray | ProxyArray} [proxy]
* @property {ProxyConfigMap | ProxyConfigArrayItem | ProxyConfigArray} [proxy]
* @property {boolean | string | Open | Array<string | Open>} [open]
* @property {boolean} [setupExitSignals]
* @property {boolean | ClientConfiguration} [client]
Expand Down Expand Up @@ -1380,10 +1380,10 @@ class Server {
Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
Object.prototype.hasOwnProperty.call(options.proxy, "router")
) {
/** @type {ProxyArray} */
/** @type {ProxyConfigArray} */
(options.proxy) = [/** @type {ProxyConfigMap} */ (options.proxy)];
} else {
/** @type {ProxyArray} */
/** @type {ProxyConfigArray} */
(options.proxy) = Object.keys(options.proxy).map(
/**
* @param {string} context
Expand Down Expand Up @@ -1421,50 +1421,48 @@ class Server {
}
}

/** @type {ProxyArray} */
/** @type {ProxyConfigArray} */
(options.proxy) =
/** @type {ProxyArray} */
(options.proxy).map(
/** @type {ProxyConfigArray} */
(options.proxy).map((item) => {
if (typeof item === "function") {
return item;
}

/**
* @param {HttpProxyMiddlewareOptions} item
* @returns {HttpProxyMiddlewareOptions}
* @param {"info" | "warn" | "error" | "debug" | "silent" | undefined | "none" | "log" | "verbose"} level
* @returns {"info" | "warn" | "error" | "debug" | "silent" | undefined}
*/
(item) => {
/**
* @param {"info" | "warn" | "error" | "debug" | "silent" | undefined | "none" | "log" | "verbose"} level
* @returns {"info" | "warn" | "error" | "debug" | "silent" | undefined}
*/
const getLogLevelForProxy = (level) => {
if (level === "none") {
return "silent";
}

if (level === "log") {
return "info";
}

if (level === "verbose") {
return "debug";
}

return level;
};
const getLogLevelForProxy = (level) => {
if (level === "none") {
return "silent";
}

if (typeof item.logLevel === "undefined") {
item.logLevel = getLogLevelForProxy(
compilerOptions.infrastructureLogging
? compilerOptions.infrastructureLogging.level
: "info"
);
if (level === "log") {
return "info";
}

if (typeof item.logProvider === "undefined") {
item.logProvider = () => this.logger;
if (level === "verbose") {
return "debug";
}

return item;
return level;
};

if (typeof item.logLevel === "undefined") {
item.logLevel = getLogLevelForProxy(
compilerOptions.infrastructureLogging
? compilerOptions.infrastructureLogging.level
: "info"
);
}
);

if (typeof item.logProvider === "undefined") {
item.logProvider = () => this.logger;
}

return item;
});
}

if (typeof options.setupExitSignals === "undefined") {
Expand Down Expand Up @@ -2124,7 +2122,7 @@ class Server {
const { createProxyMiddleware } = require("http-proxy-middleware");

/**
* @param {ProxyConfigArray} proxyConfig
* @param {ProxyConfigArrayItem} proxyConfig
* @returns {RequestHandler | undefined}
*/
const getProxyMiddleware = (proxyConfig) => {
Expand Down Expand Up @@ -2160,93 +2158,91 @@ class Server {
* }
* ]
*/
/** @type {ProxyArray} */
(this.options.proxy).forEach(
/** @type {ProxyConfigArray} */
(this.options.proxy).forEach((proxyConfigOrCallback) => {
/**
* @param {any} proxyConfigOrCallback
* @type {RequestHandler}
*/
(proxyConfigOrCallback) => {
/**
* @type {RequestHandler}
*/
let proxyMiddleware;
let proxyMiddleware;

let proxyConfig =
typeof proxyConfigOrCallback === "function"
? proxyConfigOrCallback()
: proxyConfigOrCallback;
let proxyConfig =
typeof proxyConfigOrCallback === "function"
? proxyConfigOrCallback()
: proxyConfigOrCallback;

proxyMiddleware =
/** @type {RequestHandler} */
(getProxyMiddleware(proxyConfig));
proxyMiddleware =
/** @type {RequestHandler} */
(getProxyMiddleware(proxyConfig));

if (proxyConfig.ws) {
this.webSocketProxies.push(proxyMiddleware);
}
if (proxyConfig.ws) {
this.webSocketProxies.push(proxyMiddleware);
}

/**
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Promise<void>}
*/
const handler = async (req, res, next) => {
if (typeof proxyConfigOrCallback === "function") {
const newProxyConfig = proxyConfigOrCallback(req, res, next);

if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware =
/** @type {RequestHandler} */
(getProxyMiddleware(proxyConfig));
}
/**
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Promise<void>}
*/
const handler = async (req, res, next) => {
if (typeof proxyConfigOrCallback === "function") {
const newProxyConfig = proxyConfigOrCallback(req, res, next);

if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware =
/** @type {RequestHandler} */
(getProxyMiddleware(proxyConfig));
}
}

// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
// TODO remove in the next major in favor `context` and `router` options
const isByPassFuncDefined =
typeof proxyConfig.bypass === "function";
const bypassUrl = isByPassFuncDefined
? await proxyConfig.bypass(req, res, proxyConfig)
: null;

if (typeof bypassUrl === "boolean") {
// skip the proxy
// @ts-ignore
req.url = null;
next();
} else if (typeof bypassUrl === "string") {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
};
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
// TODO remove in the next major in favor `context` and `router` options
const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
const bypassUrl = isByPassFuncDefined
? await /** @type {ByPass} */ (proxyConfig.bypass)(
req,
res,
proxyConfig
)
: null;

if (typeof bypassUrl === "boolean") {
// skip the proxy
// @ts-ignore
req.url = null;
next();
} else if (typeof bypassUrl === "string") {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
};

middlewares.push({
name: "http-proxy-middleware",
middleware: handler,
});
// Also forward error requests to the proxy so it can handle them.
middlewares.push({
name: "http-proxy-middleware-error-handler",
middleware:
/**
* @param {Error} error
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {any}
*/
(error, req, res, next) => handler(req, res, next),
});
}
);
middlewares.push({
name: "http-proxy-middleware",
middleware: handler,
});
// Also forward error requests to the proxy so it can handle them.
middlewares.push({
name: "http-proxy-middleware-error-handler",
middleware:
/**
* @param {Error} error
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {any}
*/
(error, req, res, next) => handler(req, res, next),
});
});

middlewares.push({
name: "webpack-dev-middleware",
Expand Down

0 comments on commit efec2f5

Please sign in to comment.