{"version":3,"file":"dev-server-middleware.mjs","names":[],"sources":["../../../src/build/rspack/dev-server-middleware.ts"],"sourcesContent":["import type { PluginInfo } from \"./utils\";\n\nconst corsHeaders = {\n  \"Access-Control-Allow-Origin\": \"*\",\n  \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",\n  \"Access-Control-Allow-Headers\": \"X-Requested-With, content-type, Authorization\",\n};\n\nconst applyCorsHeaders = (res: any) => {\n  Object.entries(corsHeaders).forEach(([key, value]) => {\n    res.setHeader(key, value);\n  });\n};\n\nconst normalizePrefix = (prefix?: string): string => {\n  if (!prefix) return \"\";\n  const cleaned = prefix.replace(/^\\/+|\\/+$/g, \"\");\n  return cleaned ? `/${cleaned}` : \"\";\n};\n\nexport function setupPluginMiddleware(\n  devServer: any,\n  pluginInfo: PluginInfo,\n  devConfig: any,\n  port: number,\n) {\n  const rpcPrefix = normalizePrefix(devConfig?.prefix);\n  const handlers: { rpc: any; api: any } = { rpc: null, api: null };\n  let cleanup: (() => Promise<void>) | null = null;\n\n  const performCleanup = async () => {\n    if (cleanup) {\n      await cleanup();\n      cleanup = null;\n    }\n  };\n\n  (async () => {\n    await performCleanup();\n\n    try {\n      const { createPluginRuntime } = await import(\"every-plugin\");\n      const { RPCHandler } = await import(\"@orpc/server/fetch\");\n      const { OpenAPIHandler } = await import(\"@orpc/openapi/fetch\");\n      const { OpenAPIReferencePlugin } = await import(\"@orpc/openapi/plugins\");\n      const { ZodToJsonSchemaConverter } = await import(\"@orpc/zod/zod4\");\n      const { onError } = await import(\"every-plugin/orpc\");\n      const { formatORPCError } = await import(\"every-plugin/errors\");\n\n      const pluginId = devConfig?.pluginId || pluginInfo.normalizedName;\n\n      const runtime = createPluginRuntime({\n        registry: {\n          [pluginId]: {\n            remote: `http://localhost:${port}/remoteEntry.js`,\n          },\n        },\n      });\n\n      const defaultConfig = { variables: {}, secrets: {} };\n\n      // @ts-expect-error we don't know the plugin id\n      const loaded = await runtime.usePlugin(pluginId, (devConfig?.config ?? defaultConfig) as any);\n\n      cleanup = async () => {\n        if (runtime) await runtime.shutdown();\n        handlers.rpc = null;\n        handlers.api = null;\n        if (devServer.app.locals.handlers) {\n          devServer.app.locals.handlers = null;\n        }\n      };\n\n      handlers.rpc = new RPCHandler(loaded.router, {\n        interceptors: [\n          onError((error: any) => {\n            formatORPCError(error);\n          }),\n        ],\n      });\n\n      handlers.api = new OpenAPIHandler(loaded.router, {\n        plugins: [\n          new OpenAPIReferencePlugin({\n            schemaConverters: [new ZodToJsonSchemaConverter()],\n          }),\n        ],\n        interceptors: [\n          onError((error: any) => {\n            formatORPCError(error);\n          }),\n        ],\n      });\n\n      console.log(`╭─────────────────────────────────────────────`);\n      console.log(`│  ✅ Plugin dev server ready: `);\n      console.log(`├─────────────────────────────────────────────`);\n      console.log(`│  📡 RPC:    http://localhost:${port}/api/rpc${rpcPrefix}`);\n      console.log(`│  📖 Docs:   http://localhost:${port}/api`);\n      console.log(`│  💚 Health: http://localhost:${port}/`);\n      console.log(`╰─────────────────────────────────────────────`);\n\n      devServer.app.locals.handlers = handlers;\n\n      if (devServer.server) {\n        devServer.server.once(\"close\", async () => {\n          await performCleanup();\n        });\n      }\n    } catch (error) {\n      console.error(\"❌ Failed to load plugin:\", error);\n      await performCleanup();\n    }\n  })().catch((err) => {\n    console.error(\"❌ Plugin dev server fatal error:\", err);\n  });\n\n  process.once(\"SIGINT\", async () => {\n    const timeout = setTimeout(() => process.exit(0), 3000);\n    await performCleanup();\n    clearTimeout(timeout);\n  });\n  process.once(\"SIGTERM\", async () => {\n    const timeout = setTimeout(() => process.exit(0), 3000);\n    await performCleanup();\n    clearTimeout(timeout);\n  });\n\n  devServer.app.options(\"*\", (_req: any, res: any) => {\n    applyCorsHeaders(res);\n    res.status(200).end();\n  });\n\n  devServer.app.get(\"/\", (_req: any, res: any) => {\n    applyCorsHeaders(res);\n    res.json({\n      ok: true,\n      plugin: pluginInfo.normalizedName,\n      version: pluginInfo.version,\n      status: devServer.app.locals.handlers?.rpc ? \"ready\" : \"loading\",\n      endpoints: {\n        health: \"/\",\n        docs: \"/api\",\n        rpc: `/api/rpc${rpcPrefix}`,\n      },\n    });\n  });\n\n  devServer.app.get(\"/health\", (_req: any, res: any) => {\n    applyCorsHeaders(res);\n    res.status(200).send(\"OK\");\n  });\n\n  const buildDevContext = (_req: any, webRequest: Request) => {\n    const rawClone =\n      webRequest.method === \"GET\" || webRequest.method === \"HEAD\" ? null : webRequest.clone();\n    let cachedRawBody: string | null = null;\n    return {\n      reqHeaders: webRequest.headers,\n      getRawBody: async (): Promise<string> => {\n        if (cachedRawBody !== null) return cachedRawBody;\n        if (!rawClone) {\n          cachedRawBody = \"\";\n          return cachedRawBody;\n        }\n        cachedRawBody = await rawClone.text();\n        return cachedRawBody;\n      },\n    };\n  };\n\n  const handleApiRequest = async (req: any, res: any) => {\n    applyCorsHeaders(res);\n    const apiHandler = devServer.app.locals.handlers?.api;\n    if (!apiHandler) {\n      return res.status(503).json({ error: \"Plugin still loading...\" });\n    }\n\n    try {\n      const url = `http://${req.headers.host}${req.url}`;\n      const webRequest = new Request(url, {\n        method: req.method,\n        headers: req.headers,\n        body: req.method !== \"GET\" && req.method !== \"HEAD\" ? req : undefined,\n        duplex: req.method !== \"GET\" && req.method !== \"HEAD\" ? \"half\" : undefined,\n      } as RequestInit);\n\n      const result = await apiHandler.handle(webRequest, {\n        prefix: \"/api\",\n        context: buildDevContext(req, webRequest),\n      });\n\n      if (result.response) {\n        res.status(result.response.status);\n        result.response.headers.forEach((value: string, key: string) => {\n          res.setHeader(key, value);\n        });\n        const text = await result.response.text();\n        res.send(text);\n      } else {\n        res.status(404).send(\"Not Found\");\n      }\n    } catch (error) {\n      console.error(\"OpenAPI error:\", error);\n      res.status(500).json({ error: (error as Error).message });\n    }\n  };\n\n  devServer.app.all(`/api/rpc${rpcPrefix}/*`, async (req: any, res: any) => {\n    applyCorsHeaders(res);\n    const rpcHandler = devServer.app.locals.handlers?.rpc;\n    if (!rpcHandler) {\n      return res.status(503).json({ error: \"Plugin still loading...\" });\n    }\n\n    try {\n      const url = `http://${req.headers.host}${req.url}`;\n      const webRequest = new Request(url, {\n        method: req.method,\n        headers: req.headers,\n        body: req.method !== \"GET\" && req.method !== \"HEAD\" ? req : undefined,\n        duplex: req.method !== \"GET\" && req.method !== \"HEAD\" ? \"half\" : undefined,\n      } as RequestInit);\n\n      const result = await rpcHandler.handle(webRequest, {\n        prefix: `/api/rpc${rpcPrefix}`,\n        context: buildDevContext(req, webRequest),\n      });\n\n      if (result.response) {\n        res.status(result.response.status);\n        result.response.headers.forEach((value: string, key: string) => {\n          res.setHeader(key, value);\n        });\n        const text = await result.response.text();\n        res.send(text);\n      } else {\n        res.status(404).send(\"Not Found\");\n      }\n    } catch (error) {\n      console.error(\"RPC error:\", error);\n      res.status(500).json({ error: (error as Error).message });\n    }\n  });\n\n  devServer.app.all(\"/api\", handleApiRequest);\n  devServer.app.all(\"/api/*\", handleApiRequest);\n}\n"],"mappings":"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"}