Repository: nuxt/nuxt
File: packages/vite/src/plugins/dev-server.ts (TypeScript)

Code before:

        return _isProxyPath(url)
      }

      const viteMiddleware = defineEventHandler(async (event: H3V1Event | H3V2Event) => {
        const url = 'url' in event ? event.url.pathname + event.url.search + event.url.hash : event.path
        const isBasePath = url.startsWith(viteServer.config.base!)

        // Check if this is a vite-handled route or proxy path
        let isViteRoute = isBasePath
        let isProxyRoute = false
        if (!isViteRoute) {
          // Check vite middleware routes (must be done per-request as middleware stack can change)
          for (const viteRoute of viteServer.middlewares.stack) {
            if (viteRoute.route.length > 1 && url.startsWith(viteRoute.route)) {
              isViteRoute = true
              break
            }
          }
          // Check proxy paths
          isProxyRoute = isProxyPath(url)
          isViteRoute ||= isProxyRoute
        }

        const { req, res } = 'runtime' in event ? event.runtime!.node! : event.node
        if (isProxyRoute) {
          // @ts-expect-error _skip_transform is a private property
          req._skip_transform = true
        }

        // Workaround: vite devmiddleware modifies req.url
        const _originalPath = req.url
        await new Promise((resolve, reject) => {
          viteServer.middlewares.handle(req as IncomingMessage, res as ServerResponse, (err: Error) => {
            req.url = _originalPath
            return err ? reject(err) : resolve(null)
          })
        })

        // if vite has not handled the request, we want to send a 404 for paths which are not in any static base or dev server handlers
        if (url.startsWith(nuxt.options.app.buildAssetsDir) && !staticBases.some(baseURL => url.startsWith(baseURL)) && !devHandlerRegexes.some(regex => regex.test(url))) {
          res!.statusCode = 404
          res!.end('Not Found')
          return
        }
      })
      await nuxt.callHook('server:devHandler', viteMiddleware, {
        cors: (url) => {
          if (useViteCors) {
            return false
          }

Review comment (bug):
as I understand it, we simply need to avoid changing the url for proxy paths, which we could do with another private property on the req, and then in L78, we test for that private property.

as the PR is currently written, vite will transform paths that should instead be handled by nitro, which is why the tests are all failing

Code after:
          }
          // Check proxy paths
          isViteRoute ||= isProxyPath(url)
        }

        const { req, res } = 'runtime' in event ? event.runtime!.node! : event.node
        if (!isViteRoute) {
          // @ts-expect-error _skip_transform is a private property
          req._skip_transform = true
        }

        // Workaround: vite devmiddleware modifies req.url
        const _originalPath = req.url
        await new Promise((resolve, reject) => {
          viteServer.middlewares.handle(req as IncomingMessage, res as ServerResponse, (err: Error) => {
            req.url = _originalPath
            return err ? reject(err) : resolve(null)
          })
        })

        // if vite has not handled the request, we want to send a 404 for paths which are not in any static base or dev server handlers
        if (url.startsWith(nuxt.options.app.buildAssetsDir) && !staticBases.some(baseURL => url.startsWith(baseURL)) && !devHandlerRegexes.some(regex => regex.test(url))) {
          res!.statusCode = 404
          res!.end('Not Found')
          return
        }
      })
      await nuxt.callHook('server:devHandler', viteMiddleware, {
        cors: (url) => {
          if (useViteCors) {
            return false
          }

          if (url.startsWith(viteServer.config.base!)) {
            return true
          }

          // Check vite middleware routes (must be done per-request as middleware stack can change)
          for (const viteRoute of viteServer.middlewares.stack) {
            if (viteRoute.route.length > 1 && url.startsWith(viteRoute.route)) {
              return true
            }
          }

          // Check proxy paths
          return isProxyPath(url)
        },
      })

      // Use a post-hook so this runs after Vite registers its internal middleware.
      // This ensures the URL rewrite to /__skip_vite runs after the proxy middleware.