1import type { IncomingMessage, ServerResponse } from 'http';
2import { parse as parseUrl } from 'url';
3
4// Middleware that accepts multiple Access-Control-Allow-Origin for processing *.map.
5// This is a hook middleware before metro processing *.map,
6// which originally allow only devtools://devtools
7export function remoteDevtoolsCorsMiddleware(
8  req: IncomingMessage,
9  res: ServerResponse,
10  next: (err?: Error) => void
11) {
12  if (req.url) {
13    const url = parseUrl(req.url);
14    const origin = req.headers.origin;
15    const isValidOrigin =
16      origin &&
17      ['devtools://devtools', 'https://chrome-devtools-frontend.appspot.com'].includes(origin);
18    if (url.pathname?.endsWith('.map') && origin && isValidOrigin) {
19      res.setHeader('Access-Control-Allow-Origin', origin);
20
21      // Prevent metro overwrite Access-Control-Allow-Origin header
22      const setHeader = res.setHeader.bind(res);
23      res.setHeader = (key, ...args) => {
24        if (key !== 'Access-Control-Allow-Origin') {
25          setHeader(key, ...args);
26        }
27        return res;
28      };
29    }
30  }
31  next();
32}
33