From 3d043208d99e41bd3b0538e381a289ba4892fbf1 Mon Sep 17 00:00:00 2001 From: Tan Nguyen Date: Fri, 7 Aug 2026 09:53:02 +0700 Subject: [PATCH 1/2] chore: update package overrides in pnpm-workspace.yaml - Set happy-dom to version 20.11.1 for versions below 20.8.9 - Update tmp to version 0.2.7 for versions below 0.2.6 - Pin undici to version 7.29.0 for versions between 7.0.0 and 7.29.0 --- examples/desktop-counter/package.json | 10 +- packages/auth/package.json | 4 +- packages/core/package.json | 4 +- packages/database/package.json | 4 +- packages/deno-adapter/package.json | 4 +- packages/desktop/README.md | 6 +- packages/desktop/docs/guide.md | 6 +- packages/framework/package.json | 8 +- .../framework/tests/package-contract.test.ts | 4 +- packages/node-adapter/package.json | 4 +- packages/renderer/package.json | 1 + packages/scaffold/package.json | 8 +- packages/scaffold/src/index.js | 2 +- packages/scaffold/tests/scaffold.test.js | 2 +- packages/studio/package.json | 6 +- pnpm-lock.yaml | 451 +++++++++++------- pnpm-workspace.yaml | 3 + 17 files changed, 315 insertions(+), 212 deletions(-) diff --git a/examples/desktop-counter/package.json b/examples/desktop-counter/package.json index 785d7dca..80c5d1bd 100644 --- a/examples/desktop-counter/package.json +++ b/examples/desktop-counter/package.json @@ -5,7 +5,7 @@ "private": true, "type": "module", "engines": { - "node": ">=22 <26" + "node": ">=22" }, "main": "dist/desktop/index.js", "scripts": { @@ -25,10 +25,10 @@ "@cossackframework/renderer": "workspace:*", "@cossackframework/ui": "workspace:*", "@cossackframework/node-adapter": "workspace:*", - "@hono/node-server": "^1.13.0", - "@tailwindcss/vite": "^4.1.0", - "hono": "^4.12.31", - "tailwindcss": "^4.1.0", + "@hono/node-server": "^2.0.5", + "@tailwindcss/vite": "^4.3.3", + "hono": "^4.12.34", + "tailwindcss": "^4.3.3", "vite": "^8.1.4", "ws": "^8.18.0" }, diff --git a/packages/auth/package.json b/packages/auth/package.json index 1f4bef7b..25e0e9c0 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -20,10 +20,10 @@ "test": "vitest" }, "devDependencies": { - "hono": "^4.12.31", + "hono": "^4.12.34", "vitest": "^4.1.10" }, "peerDependencies": { - "hono": "^4.12.0" + "hono": "^4.12.34" } } diff --git a/packages/core/package.json b/packages/core/package.json index afb75613..3ae6782e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,7 +39,7 @@ "devDependencies": { "@types/jsdom": "^28.0.3", "@types/node": "^22.19.0", - "hono": "^4.12.31", + "hono": "^4.12.34", "jsdom": "^29.1.1", "reflect-metadata": "^0.2.2", "typescript": "^7.0.2", @@ -47,6 +47,6 @@ "vitest": "^4.1.10" }, "peerDependencies": { - "hono": "^4.12.0" + "hono": "^4.12.34" } } diff --git a/packages/database/package.json b/packages/database/package.json index 08dd4ffc..aa03daa7 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -88,7 +88,7 @@ "@tursodatabase/database": "^0.7.2", "@tursodatabase/serverless": "^1.4.0", "better-sqlite3": ">=11", - "hono": "^4.12.0", + "hono": "^4.12.34", "mysql2": ">=3.11", "pg": ">=8.13", "reflect-metadata": ">=0.2" @@ -115,7 +115,7 @@ }, "devDependencies": { "@types/node": "^22.19.0", - "hono": "^4.12.31", + "hono": "^4.12.34", "reflect-metadata": "^0.2.2", "typescript": "^7.0.2", "vitest": "^4.1.10" diff --git a/packages/deno-adapter/package.json b/packages/deno-adapter/package.json index 11152369..56020c23 100644 --- a/packages/deno-adapter/package.json +++ b/packages/deno-adapter/package.json @@ -20,11 +20,11 @@ }, "peerDependencies": { "@cossackframework/framework": "workspace:*", - "hono": "^4.12.0" + "hono": "^4.12.34" }, "devDependencies": { "@cossackframework/framework": "workspace:*", - "hono": "^4.12.31", + "hono": "^4.12.34", "typescript": "^7.0.2", "vite": "^8.1.4", "vitest": "^4.1.10" diff --git a/packages/desktop/README.md b/packages/desktop/README.md index 16b8a50f..e6d95e28 100644 --- a/packages/desktop/README.md +++ b/packages/desktop/README.md @@ -47,9 +47,9 @@ An unpacked Forge executable bypasses that desktop entry; launch it with both `--no-sandbox` and `--ozone-platform=x11` when testing directly from `out/`. The sandbox flag is only appropriate for that uninstalled test package. -Use Node 22 or 24 LTS for Forge packaging. The current Forge/Packager ZIP stack -can extract Electron pathologically slowly under Node 26; generated Desktop -projects declare `node: ">=22 <26"` until that upstream combination is fixed. +Node 22 or 24 LTS is recommended for Forge packaging. Node 26 is supported, but +the current Forge/Packager ZIP stack can extract Electron pathologically slowly +there; generated Desktop projects declare `node: ">=22"`. Use Electron APIs in the bootstrap or through ordinary `@Server()` methods via `this.env.COSSACK_DESKTOP`. There is deliberately no renderer client or generic diff --git a/packages/desktop/docs/guide.md b/packages/desktop/docs/guide.md index 13bec223..1fb3f84e 100644 --- a/packages/desktop/docs/guide.md +++ b/packages/desktop/docs/guide.md @@ -67,9 +67,9 @@ for an unpacked app and `desktop:make` for the current host's `.deb`, `.msi`, or `.dmg`; installers are not cross-built. Signing and notarization are optional until credentials are supplied. -Package with Node 22 or 24 LTS. Electron Packager's current ZIP extraction path -is extremely slow under Node 26, so generated Desktop manifests temporarily -declare `node: ">=22 <26"`. +Node 22 or 24 LTS is recommended for packaging. Node 26 is supported, but +Electron Packager's current ZIP extraction path is extremely slow there; +generated Desktop manifests declare `node: ">=22"`. References: [security checklist](https://www.electronjs.org/docs/latest/tutorial/security), [protocol API](https://www.electronjs.org/docs/latest/api/protocol), diff --git a/packages/framework/package.json b/packages/framework/package.json index 63b6e7c1..6dbb29c2 100644 --- a/packages/framework/package.json +++ b/packages/framework/package.json @@ -142,18 +142,18 @@ "vfile-matter": "^5.0.1", "@cloudflare/vite-plugin": "^1.47.0", "@playwright/test": "^1.61.1", - "@tailwindcss/vite": "^4.1.0", + "@tailwindcss/vite": "^4.3.3", "@types/mdast": "^4.0.4", "cossack": "workspace:*", - "hono": "^4.12.31", + "hono": "^4.12.34", "reflect-metadata": "^0.2.2", - "tailwindcss": "^4.1.0", + "tailwindcss": "^4.3.3", "vite": "^8.1.4", "vitest": "^4.1.10", "wrangler": "^4.114.0" }, "peerDependencies": { - "hono": "^4.12.0", + "hono": "^4.12.34", "vite": "^8.1.0" }, "engines": { diff --git a/packages/framework/tests/package-contract.test.ts b/packages/framework/tests/package-contract.test.ts index 17301515..31fb89e7 100644 --- a/packages/framework/tests/package-contract.test.ts +++ b/packages/framework/tests/package-contract.test.ts @@ -16,7 +16,7 @@ describe('Hono package contract', () => { 'utf8', )); - expect(packageJson.peerDependencies?.hono).toBe('^4.12.0'); + expect(packageJson.peerDependencies?.hono).toBe('^4.12.34'); expect(packageJson.dependencies?.hono).toBeUndefined(); expect(packageJson.devDependencies?.hono).toMatch(/^\^4\.12\./); }); @@ -104,7 +104,7 @@ describe('framework publication contract', () => { expect(frameworkPackage.devDependencies).toHaveProperty(name); } expect(frameworkPackage.peerDependencies).toMatchObject({ - hono: '^4.12.0', + hono: '^4.12.34', vite: '^8.1.0', }); }); diff --git a/packages/node-adapter/package.json b/packages/node-adapter/package.json index 125dfc54..29738189 100644 --- a/packages/node-adapter/package.json +++ b/packages/node-adapter/package.json @@ -36,12 +36,12 @@ "devDependencies": { "@types/nodemailer": "^8.0.1", "@types/ws": "^8.18.0", - "hono": "^4.12.31", + "hono": "^4.12.34", "typescript": "^7.0.2", "vite": "^8.1.4", "vitest": "^4.1.10" }, "peerDependencies": { - "hono": "^4.12.0" + "hono": "^4.12.34" } } diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 84928fa5..ec334584 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -38,6 +38,7 @@ "css-tree": "^3.2.1" }, "devDependencies": { + "happy-dom": "^20.11.1", "oxlint": "^1.41.0", "typescript": "^7.0.2", "vite": "^8.1.4", diff --git a/packages/scaffold/package.json b/packages/scaffold/package.json index c5aaf91d..a1979e95 100644 --- a/packages/scaffold/package.json +++ b/packages/scaffold/package.json @@ -37,13 +37,13 @@ "@tursodatabase/serverless": "^1.4.0", "@cossackframework/solar-icons": "^0.7.1", "@cossackframework/studio": "^0.8.1", - "@hono/node-server": "^1.13.0", - "@tailwindcss/vite": "^4.1.0", + "@hono/node-server": "^2.0.5", + "@tailwindcss/vite": "^4.3.3", "@types/node": "^22.0.0", "@types/mdast": "^4.0.4", "@types/pg": "^8.15.5", "@types/ws": "^8.18.0", - "hono": "^4.12.31", + "hono": "^4.12.34", "electron": "^43.3.0", "mysql2": "^3.14.3", "pg": "^8.16.3", @@ -57,7 +57,7 @@ "remark-rehype": "^11.1.2", "remark-sugar-high": "^0.6.3", "remark-toc": "^9.0.0", - "tailwindcss": "^4.1.0", + "tailwindcss": "^4.3.3", "tsx": "^4.23.0", "unified": "^11.0.5", "vite": "^8.1.4", diff --git a/packages/scaffold/src/index.js b/packages/scaffold/src/index.js index 87519ef2..5a6d1278 100644 --- a/packages/scaffold/src/index.js +++ b/packages/scaffold/src/index.js @@ -578,7 +578,7 @@ function packageJson(recipe, projectName) { name: projectName, version: '0.1.0', type: 'module', - ...(recipe.resolvedFeatures.includes('desktop') ? { engines: { node: '>=22 <26' } } : {}), + ...(recipe.resolvedFeatures.includes('desktop') ? { engines: { node: '>=22' } } : {}), description: 'The Borderless TypeScript Framework', cossack: { runtime: recipe.adapter }, scripts, diff --git a/packages/scaffold/tests/scaffold.test.js b/packages/scaffold/tests/scaffold.test.js index de24181e..9c49f48d 100644 --- a/packages/scaffold/tests/scaffold.test.js +++ b/packages/scaffold/tests/scaffold.test.js @@ -695,7 +695,7 @@ describe('composition', () => { expect(targetPackage.devDependencies.electron).toBeDefined(); expect(targetPackage.devDependencies['@electron-forge/cli']).toBeDefined(); expect(targetPackage.main).toBe('dist/desktop/index.js'); - expect(targetPackage.engines.node).toBe('>=22 <26'); + expect(targetPackage.engines.node).toBe('>=22'); expect(targetPackage.scripts['build:desktop']).toContain('src/desktop/index.ts'); expect(targetPackage.scripts['build:desktop']).toContain('--mode desktop'); expect(targetPackage.scripts['desktop:dev']).toBe('cossack-desktop'); diff --git a/packages/studio/package.json b/packages/studio/package.json index b9daac8c..4cfc9f28 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -35,7 +35,7 @@ "@cossackframework/renderer": "workspace:*", "@cossackframework/solar-icons": "^0.7.1", "@cossackframework/ui": "workspace:*", - "hono": "^4.12.31", + "hono": "^4.12.34", "prompts": "^2.4.2", "reflect-metadata": "^0.2.2" }, @@ -43,10 +43,10 @@ "@tursodatabase/database": "^0.7.2", "@tursodatabase/serverless": "^1.4.0", "@playwright/test": "^1.61.1", - "@tailwindcss/vite": "^4.1.0", + "@tailwindcss/vite": "^4.3.3", "@types/node": "^22.19.0", "monaco-editor": "^0.52.2", - "tailwindcss": "^4.1.0", + "tailwindcss": "^4.3.3", "typescript": "^7.0.2", "tsx": "^4.23.0", "vite": "^8.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1403330e..b6f5c832 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ settings: overrides: '@electron/rebuild': ^4.2.0 + happy-dom@<20.8.9: 20.11.1 + tmp@<0.2.6: 0.2.7 + undici@>=7.0.0 <7.29.0: 7.29.0 importers: @@ -36,17 +39,17 @@ importers: specifier: workspace:* version: link:../../packages/ui '@hono/node-server': - specifier: ^1.13.0 - version: 1.19.17(hono@4.12.31) + specifier: ^2.0.5 + version: 2.1.0(hono@4.13.0) '@tailwindcss/vite': - specifier: ^4.1.0 - version: 4.2.4(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + specifier: ^4.3.3 + version: 4.3.3(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 tailwindcss: - specifier: ^4.1.0 - version: 4.2.4 + specifier: ^4.3.3 + version: 4.3.3 vite: specifier: ^8.1.4 version: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) @@ -85,11 +88,11 @@ importers: packages/auth: devDependencies: hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/core: dependencies: @@ -104,8 +107,8 @@ importers: specifier: ^22.19.0 version: 22.20.1 hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 jsdom: specifier: ^29.1.1 version: 29.1.1 @@ -120,7 +123,7 @@ importers: version: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/cossack: dependencies: @@ -139,7 +142,7 @@ importers: devDependencies: vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/database: dependencies: @@ -166,8 +169,8 @@ importers: specifier: ^22.19.0 version: 22.20.1 hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 reflect-metadata: specifier: ^0.2.2 version: 0.2.2 @@ -176,7 +179,7 @@ importers: version: 7.0.2 vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/deno-adapter: dependencies: @@ -188,8 +191,8 @@ importers: specifier: workspace:* version: link:../framework hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 typescript: specifier: ^7.0.2 version: 7.0.2 @@ -198,7 +201,7 @@ importers: version: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/desktop: dependencies: @@ -220,7 +223,7 @@ importers: version: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/framework: dependencies: @@ -250,8 +253,8 @@ importers: specifier: ^1.61.1 version: 1.61.1 '@tailwindcss/vite': - specifier: ^4.1.0 - version: 4.2.4(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + specifier: ^4.3.3 + version: 4.3.3(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) '@types/mdast': specifier: ^4.0.4 version: 4.0.4 @@ -259,8 +262,8 @@ importers: specifier: workspace:* version: link:../cossack hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 reflect-metadata: specifier: ^0.2.2 version: 0.2.2 @@ -292,8 +295,8 @@ importers: specifier: ^9.0.0 version: 9.0.0 tailwindcss: - specifier: ^4.1.0 - version: 4.2.4 + specifier: ^4.3.3 + version: 4.3.3 tsx: specifier: ^4.23.0 version: 4.23.0 @@ -308,7 +311,7 @@ importers: version: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) wrangler: specifier: ^4.114.0 version: 4.114.0 @@ -332,8 +335,8 @@ importers: specifier: ^8.18.0 version: 8.18.1 hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 typescript: specifier: ^7.0.2 version: 7.0.2 @@ -342,7 +345,7 @@ importers: version: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/renderer: dependencies: @@ -350,6 +353,9 @@ importers: specifier: ^3.2.1 version: 3.2.1 devDependencies: + happy-dom: + specifier: ^20.11.1 + version: 20.11.1 oxlint: specifier: ^1.41.0 version: 1.41.0 @@ -361,7 +367,7 @@ importers: version: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/scaffold: dependencies: @@ -374,7 +380,7 @@ importers: devDependencies: vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/studio: dependencies: @@ -397,8 +403,8 @@ importers: specifier: workspace:* version: link:../ui hono: - specifier: ^4.12.31 - version: 4.12.31 + specifier: ^4.12.34 + version: 4.13.0 prompts: specifier: ^2.4.2 version: 2.4.2 @@ -410,8 +416,8 @@ importers: specifier: ^1.61.1 version: 1.61.1 '@tailwindcss/vite': - specifier: ^4.1.0 - version: 4.2.4(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + specifier: ^4.3.3 + version: 4.3.3(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) '@tursodatabase/database': specifier: ^0.7.2 version: 0.7.2 @@ -425,8 +431,8 @@ importers: specifier: ^0.52.2 version: 0.52.2 tailwindcss: - specifier: ^4.1.0 - version: 4.2.4 + specifier: ^4.3.3 + version: 4.3.3 tsx: specifier: ^4.23.0 version: 4.23.0 @@ -438,7 +444,7 @@ importers: version: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/test-utils: dependencies: @@ -451,7 +457,7 @@ importers: version: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages/ui: devDependencies: @@ -475,7 +481,7 @@ importers: version: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) packages: @@ -985,9 +991,9 @@ packages: '@noble/hashes': optional: true - '@hono/node-server@1.19.17': - resolution: {integrity: sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ==} - engines: {node: '>=18.14.1'} + '@hono/node-server@2.1.0': + resolution: {integrity: sha512-XovyyCCnBzW+zKu+z/zq8hwNs4KOR5rEMAOxo2f40Q5xoOI37IMm6MIg2COOUtUApo0i6850MTBKH2u4QLGIqg==} + engines: {node: '>=20'} peerDependencies: hono: ^4 @@ -1484,69 +1490,69 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tailwindcss/node@4.2.4': - resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} - '@tailwindcss/oxide-android-arm64@4.2.4': - resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==} + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.2.4': - resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==} + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.2.4': - resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==} + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.2.4': - resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==} + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': - resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': - resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==} + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] libc: [glibc] - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': - resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==} + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] libc: [musl] - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': - resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==} + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} engines: {node: '>= 20'} cpu: [x64] os: [linux] libc: [glibc] - '@tailwindcss/oxide-linux-x64-musl@4.2.4': - resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==} + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} engines: {node: '>= 20'} cpu: [x64] os: [linux] libc: [musl] - '@tailwindcss/oxide-wasm32-wasi@4.2.4': - resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==} + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -1557,24 +1563,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': - resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==} + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': - resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==} + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.2.4': - resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==} + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} engines: {node: '>= 20'} - '@tailwindcss/vite@4.2.4': - resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==} + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 @@ -2038,6 +2044,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer-image-size@0.6.4: + resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==} + engines: {node: '>=4.0'} + cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} @@ -2271,22 +2281,18 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.21.0: - resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.24.5: resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} engines: {node: '>=10.13.0'} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + entities@8.0.0: resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} engines: {node: '>=20.19.0'} @@ -2563,8 +2569,8 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - happy-dom@20.4.0: - resolution: {integrity: sha512-RDeQm3dT9n0A5f/TszjUmNCLEuPnMGv3Tv4BmNINebz/h17PA6LMBcxJ5FrcqltNBMh9jA/8ufgDdBYUdBt+eg==} + happy-dom@20.11.1: + resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} has-flag@4.0.0: @@ -2605,8 +2611,8 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - hono@4.12.31: - resolution: {integrity: sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==} + hono@4.13.0: + resolution: {integrity: sha512-jhunvfHWxd7J5EFfSgH4xsYJzSe/lfqbUCxiyyeaQasUsXeEHXtzVid+7EOGByc5JnFa23SSFL3Y2RV/z1T+eQ==} engines: {node: '>=16.9.0'} hosted-git-info@2.8.9: @@ -2737,6 +2743,10 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + jsdom@29.1.1: resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} @@ -3258,10 +3268,6 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - oxlint@1.41.0: resolution: {integrity: sha512-Dyaoup82uhgAgp5xLNt4dPdvl5eSJTIzqzL7DcKbkooUE4PDViWURIPlSUF8hu5a+sCnNIp/LlQMDsKoyaLTBA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3784,8 +3790,8 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - tailwindcss@4.2.4: - resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==} + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} @@ -3828,10 +3834,6 @@ packages: tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - tmp@0.2.7: resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} @@ -3914,8 +3916,8 @@ packages: resolution: {integrity: sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==} engines: {node: '>=18.17'} - undici@7.28.0: - resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + undici@7.29.0: + resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} engines: {node: '>=20.18.1'} unenv@2.0.0-rc.24: @@ -4036,7 +4038,7 @@ packages: '@vitest/coverage-istanbul': 4.1.10 '@vitest/coverage-v8': 4.1.10 '@vitest/ui': 4.1.10 - happy-dom: '*' + happy-dom: 20.11.1 jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: @@ -4835,7 +4837,7 @@ snapshots: semver: 7.8.5 sumchecker: 3.0.1(supports-color@10.2.2) optionalDependencies: - undici: 7.28.0 + undici: 7.29.0 transitivePeerDependencies: - supports-color @@ -5013,9 +5015,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@hono/node-server@1.19.17(hono@4.12.31)': + '@hono/node-server@2.1.0(hono@4.13.0)': dependencies: - hono: 4.12.31 + hono: 4.13.0 '@img/colour@1.1.0': {} @@ -5441,79 +5443,79 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/node@4.2.4': + '@tailwindcss/node@4.3.3': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.21.0 - jiti: 2.6.1 + enhanced-resolve: 5.24.5 + jiti: 2.7.0 lightningcss: 1.32.0 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.2.4 + tailwindcss: 4.3.3 - '@tailwindcss/oxide-android-arm64@4.2.4': + '@tailwindcss/oxide-android-arm64@4.3.3': optional: true - '@tailwindcss/oxide-darwin-arm64@4.2.4': + '@tailwindcss/oxide-darwin-arm64@4.3.3': optional: true - '@tailwindcss/oxide-darwin-x64@4.2.4': + '@tailwindcss/oxide-darwin-x64@4.3.3': optional: true - '@tailwindcss/oxide-freebsd-x64@4.2.4': + '@tailwindcss/oxide-freebsd-x64@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.2.4': + '@tailwindcss/oxide-linux-x64-musl@4.3.3': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.2.4': + '@tailwindcss/oxide-wasm32-wasi@4.3.3': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': optional: true - '@tailwindcss/oxide@4.2.4': + '@tailwindcss/oxide@4.3.3': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-x64': 4.2.4 - '@tailwindcss/oxide-freebsd-x64': 4.2.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-x64-musl': 4.2.4 - '@tailwindcss/oxide-wasm32-wasi': 4.2.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - - '@tailwindcss/vite@4.2.4(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': - dependencies: - '@tailwindcss/node': 4.2.4 - '@tailwindcss/oxide': 4.2.4 - tailwindcss: 4.2.4 + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 vite: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) - '@tailwindcss/vite@4.2.4(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': + '@tailwindcss/vite@4.3.3(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': dependencies: - '@tailwindcss/node': 4.2.4 - '@tailwindcss/oxide': 4.2.4 - tailwindcss: 4.2.4 + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 vite: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) '@tursodatabase/database-common@0.7.2': {} @@ -5632,8 +5634,7 @@ snapshots: '@types/unist@3.0.3': {} - '@types/whatwg-mimetype@3.0.2': - optional: true + '@types/whatwg-mimetype@3.0.2': {} '@types/wrap-ansi@3.0.0': {} @@ -5725,6 +5726,14 @@ snapshots: optionalDependencies: vite: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + '@vitest/mocker@4.1.10(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + '@vitest/mocker@4.1.10(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 @@ -5733,6 +5742,14 @@ snapshots: optionalDependencies: vite: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + '@vitest/mocker@4.1.10(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + '@vitest/pretty-format@4.1.10': dependencies: tinyrainbow: 3.1.0 @@ -5965,6 +5982,10 @@ snapshots: buffer-from@1.1.2: {} + buffer-image-size@0.6.4: + dependencies: + '@types/node': 22.20.1 + cacheable-lookup@5.0.4: {} cacheable-request@7.0.4: @@ -6228,21 +6249,15 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.21.0: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - enhanced-resolve@5.24.5: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 - entities@4.5.0: - optional: true - entities@6.0.1: {} + entities@7.0.1: {} + entities@8.0.0: {} env-paths@2.2.1: {} @@ -6348,7 +6363,7 @@ snapshots: dependencies: chardet: 0.7.0 iconv-lite: 0.4.24 - tmp: 0.0.33 + tmp: 0.2.7 extract-zip@2.0.1(supports-color@10.2.2): dependencies: @@ -6566,18 +6581,18 @@ snapshots: graceful-fs@4.2.11: {} - happy-dom@20.4.0: + happy-dom@20.11.1: dependencies: '@types/node': 22.20.1 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 - entities: 4.5.0 + buffer-image-size: 0.6.4 + entities: 7.0.1 whatwg-mimetype: 3.0.0 ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate - optional: true has-flag@4.0.0: {} @@ -6665,7 +6680,7 @@ snapshots: property-information: 7.2.0 space-separated-tokens: 2.0.2 - hono@4.12.31: {} + hono@4.13.0: {} hosted-git-info@2.8.9: {} @@ -6769,6 +6784,8 @@ snapshots: jiti@2.6.1: {} + jiti@2.7.0: {} + jsdom@29.1.1: dependencies: '@asamuzakjp/css-color': 5.1.11 @@ -6786,7 +6803,7 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.28.0 + undici: 7.29.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -7310,7 +7327,7 @@ snapshots: dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.35.2 - undici: 7.28.0 + undici: 7.29.0 workerd: 1.20260722.1 ws: 8.21.0 youch: 4.1.0-beta.10 @@ -7447,8 +7464,6 @@ snapshots: dependencies: mimic-fn: 2.1.0 - os-tmpdir@1.0.2: {} - oxlint@1.41.0: optionalDependencies: '@oxlint/darwin-arm64': 1.41.0 @@ -7999,7 +8014,7 @@ snapshots: symbol-tree@3.2.4: {} - tailwindcss@4.2.4: {} + tailwindcss@4.3.3: {} tapable@2.3.3: {} @@ -8043,12 +8058,7 @@ snapshots: tmp: 0.2.7 optional: true - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - - tmp@0.2.7: - optional: true + tmp@0.2.7: {} tn1150@0.1.0: dependencies: @@ -8131,7 +8141,7 @@ snapshots: undici@6.28.0: {} - undici@7.28.0: {} + undici@7.29.0: {} unenv@2.0.0-rc.24: dependencies: @@ -8233,6 +8243,22 @@ snapshots: tsx: 4.23.0 yaml: 2.9.0 + vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.5 + postcss: 8.5.23 + rolldown: 1.1.5 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.20.1 + esbuild: 0.28.1 + fsevents: 2.3.3 + jiti: 2.7.0 + terser: 5.49.0 + tsx: 4.23.0 + yaml: 2.9.0 + vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 @@ -8249,7 +8275,23 @@ snapshots: tsx: 4.23.0 yaml: 2.9.0 - vitest@4.1.10(@types/node@22.20.1)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): + vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.5 + postcss: 8.5.23 + rolldown: 1.1.5 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.0.0 + esbuild: 0.28.1 + fsevents: 2.3.3 + jiti: 2.7.0 + terser: 5.49.0 + tsx: 4.23.0 + yaml: 2.9.0 + + vitest@4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 '@vitest/mocker': 4.1.10(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) @@ -8273,12 +8315,41 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.20.1 - happy-dom: 20.4.0 + happy-dom: 20.11.1 + jsdom: 29.1.1 + transitivePeerDependencies: + - msw + + vitest@4.1.10(@types/node@22.20.1)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.1.4(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.20.1 + happy-dom: 20.11.1 jsdom: 29.1.1 transitivePeerDependencies: - msw - vitest@4.1.10(@types/node@26.0.0)(happy-dom@20.4.0)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): + vitest@4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 '@vitest/mocker': 4.1.10(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) @@ -8302,7 +8373,36 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 26.0.0 - happy-dom: 20.4.0 + happy-dom: 20.11.1 + jsdom: 29.1.1 + transitivePeerDependencies: + - msw + + vitest@4.1.10(@types/node@26.0.0)(happy-dom@20.11.1)(jsdom@29.1.1)(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.1.4(@types/node@26.0.0)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.49.0)(tsx@4.23.0)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 26.0.0 + happy-dom: 20.11.1 jsdom: 29.1.1 transitivePeerDependencies: - msw @@ -8359,8 +8459,7 @@ snapshots: - postcss - uglify-js - whatwg-mimetype@3.0.0: - optional: true + whatwg-mimetype@3.0.0: {} whatwg-mimetype@5.0.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index afe40a6e..7a4ad817 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -17,6 +17,9 @@ allowBuilds: overrides: '@electron/rebuild': ^4.2.0 + 'happy-dom@<20.8.9': 20.11.1 + 'tmp@<0.2.6': 0.2.7 + 'undici@>=7.0.0 <7.29.0': 7.29.0 minimumReleaseAgeExclude: - electron@43.3.0 From 4aebad80aba9e6a5c78649f3b46904e61b09f23a Mon Sep 17 00:00:00 2001 From: Tan Nguyen Date: Fri, 7 Aug 2026 10:09:23 +0700 Subject: [PATCH 2/2] feat: enhance minification to preserve sibling SVG elements and improve attribute handling --- packages/renderer/src/minify-html.test.ts | 22 ++++++++++++++++++++++ packages/renderer/src/minify-html.ts | 11 +++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/renderer/src/minify-html.test.ts b/packages/renderer/src/minify-html.test.ts index 362516b4..d7fcc860 100644 --- a/packages/renderer/src/minify-html.test.ts +++ b/packages/renderer/src/minify-html.test.ts @@ -167,6 +167,28 @@ Line 1 expect(result).toContain('
'); }); + it('preserves sibling SVG elements whose final attribute precedes a self-closing slash', () => { + const input = ` + + + `; + const result = minifyHtml(input); + + expect(result).toContain('stroke-width="1.5"/>'); + expect(result).toContain('stroke-linecap="round"/>'); + + document.body.innerHTML = result; + const svg = document.body.querySelector('svg')!; + const circle = svg.querySelector('circle')!; + const path = svg.querySelector('path')!; + + expect(svg.children).toHaveLength(2); + expect(circle.children).toHaveLength(0); + expect(circle.getAttribute('stroke-width')).toBe('1.5'); + expect(path.parentElement).toBe(svg); + expect(path.getAttribute('stroke-linecap')).toBe('round'); + }); + it('trims leading and trailing whitespace', () => { const input = '
hello
'; const result = minifyHtml(input); diff --git a/packages/renderer/src/minify-html.ts b/packages/renderer/src/minify-html.ts index bf4bacf5..db47e86a 100644 --- a/packages/renderer/src/minify-html.ts +++ b/packages/renderer/src/minify-html.ts @@ -23,7 +23,7 @@ const TYPE_JS_CSS = /\s+type\s*=\s*["']text\/(javascript|css)["']/gi; // separator. Besides matching the HTML grammar, this prevents malformed // third-party markup such as `r="6"stroke="currentColor"` from becoming the // substantially worse `r=6stroke=currentColor` during minification. -const QUOTED_ATTR = /(\w[\w-]*)\s*=\s*["']([a-zA-Z0-9_.-]+)["'](?=\s|\/?>)/g; +const QUOTED_ATTR = /(\w[\w-]*)\s*=\s*["']([a-zA-Z0-9_.-]+)["'](?=(\s|\/?>))/g; function preserveBlocks(html: string): { html: string; blocks: string[] } { const blocks: string[] = []; @@ -64,7 +64,14 @@ export function minifyHtml(html: string): string { result = result.replace(/>\s+<'); // Step 6: Remove optional quotes around simple attribute values - result = result.replace(QUOTED_ATTR, (_, name, value) => { + result = result.replace(QUOTED_ATTR, (match, name, value, separator) => { + // In a self-closing tag, `/` is not a delimiter for an unquoted HTML + // attribute value. Unquoting the final SVG attribute would turn e.g. + // `stroke-width="1.5"/>` into `stroke-width=1.5/>`; the tokenizer then + // reads the slash as part of the value and fails to self-close the SVG + // element. Keep that final value quoted so sibling SVG nodes retain + // their intended structure during the initial server render. + if (separator === '/>') return match; return `${name}=${value}`; });