diff --git a/.changeset/smart-pandas-leave.md b/.changeset/smart-pandas-leave.md new file mode 100644 index 00000000..11a84f47 --- /dev/null +++ b/.changeset/smart-pandas-leave.md @@ -0,0 +1,5 @@ +--- +"@ladle/react": patch +--- + +refactor: replace koa-connect with custom middleware adapter diff --git a/packages/ladle/lib/cli/vite-dev.js b/packages/ladle/lib/cli/vite-dev.js index baad1941..8380bdfa 100644 --- a/packages/ladle/lib/cli/vite-dev.js +++ b/packages/ladle/lib/cli/vite-dev.js @@ -3,7 +3,6 @@ import koa from "koa"; import http from "http"; import http2 from "http2"; import https from "https"; -import c2k from "koa-connect"; import path from "path"; import getPort from "get-port"; import { globby } from "globby"; @@ -14,6 +13,7 @@ import debug from "./debug.js"; import getBaseViteConfig from "./vite-base.js"; import { getMetaJsonObject } from "./vite-plugin/generate/get-meta-json.js"; import { getEntryData } from "./vite-plugin/parse/get-entry-data.js"; +import { connectToKoa } from "./vite-plugin/connect-to-koa.js"; /** * @param config {import("../shared/types").Config} @@ -91,7 +91,7 @@ const bundler = async (config, configFolder) => { } await next(); }); - app.use(c2k(vite.middlewares)); + app.use(connectToKoa(vite.middlewares)); // activate https if key and cert are provided const useHttps = diff --git a/packages/ladle/lib/cli/vite-plugin/connect-to-koa.js b/packages/ladle/lib/cli/vite-plugin/connect-to-koa.js new file mode 100644 index 00000000..1ece79c9 --- /dev/null +++ b/packages/ladle/lib/cli/vite-plugin/connect-to-koa.js @@ -0,0 +1,50 @@ +/** + * @typedef {import('koa').Context} KoaContext + * @typedef {import('koa').Next} KoaNext + */ + +/** + * Converts Connect/Express-style middleware to Koa middleware. + * + * This adapter bridges the gap between Vite's Connect-based middleware system + * and Ladle's Koa-based server architecture. + * + * @param {import('vite').Connect.Server} connectMiddleware - Connect/Express middleware function with signature (req, res, next) + * @returns {(ctx: KoaContext, next: KoaNext) => Promise} Koa middleware function with signature (ctx, next) + * + * @description + * Vite uses Connect middleware internally (similar to Express), which expects + * (req, res, next) function signatures. Koa uses a different pattern with a context + * object (ctx) and async/await. This adapter wraps Connect middleware to work with Koa. + * + * **Supported Vite Versions:** + * - Vite 7.x + * - Vite 6.x + * - Vite 5.x + * - Vite 4.x + * + * **How it works:** + * 1. Receives a Connect middleware that expects Node.js req/res objects + * 2. Extracts req and res from the Koa context (ctx.req, ctx.res) + * 3. Wraps the Connect middleware call in a Promise + * 4. Handles errors from the Connect middleware by rejecting the Promise + * 5. Continues the Koa middleware chain by calling next() + * + * @example + * import { connectToKoa } from './connect-to-koa.js'; + * import vite from 'vite'; + * + * const viteServer = await vite.createServer(); + * app.use(connectToKoa(viteServer.middlewares)); + */ +export const connectToKoa = (connectMiddleware) => { + return async (/** @type {KoaContext} */ ctx, /** @type {KoaNext} */ next) => { + await new Promise((resolve, reject) => { + connectMiddleware(ctx.req, ctx.res, (/** @type {any} */ err) => { + if (err) reject(err); + else resolve(undefined); + }); + }); + await next(); + }; +}; diff --git a/packages/ladle/package.json b/packages/ladle/package.json index f0312237..debd300f 100644 --- a/packages/ladle/package.json +++ b/packages/ladle/package.json @@ -59,7 +59,6 @@ "globby": "^14.0.2", "history": "^5.3.0", "koa": "^2.15.4", - "koa-connect": "^2.1.0", "lodash.merge": "^4.6.2", "msw": "^2.7.0", "open": "^10.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45e5ecaf..a2f8bdd1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -449,9 +449,6 @@ importers: koa: specifier: ^2.15.4 version: 2.15.4 - koa-connect: - specifier: ^2.1.0 - version: 2.1.0 lodash.merge: specifier: ^4.6.2 version: 4.6.2 @@ -5644,9 +5641,6 @@ packages: koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} - koa-connect@2.1.0: - resolution: {integrity: sha512-O9pcFafHk0oQsBevlbTBlB9co+2RUQJ4zCzu3qJPmGlGoeEZkne+7gWDkecqDPSbCtED6LmhlQladxs6NjOnMQ==} - koa-convert@2.0.0: resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} engines: {node: '>= 10'} @@ -15135,8 +15129,6 @@ snapshots: koa-compose@4.1.0: {} - koa-connect@2.1.0: {} - koa-convert@2.0.0: dependencies: co: 4.6.0