Roo-Code/webview-ui/src/vite-plugins/sourcemapPlugin.ts
roomote[bot] 7ca4901024
fix: prevent empty mode names from being saved (fixes #5766) (#5767)
* fix: prevent empty mode names from being saved (fixes #5766)

- Add frontend validation in ModesView to prevent empty names from being saved
- Add onBlur handler to restore original name if field is left empty
- Add backend validation in CustomModesManager.updateCustomMode using modeConfigSchema
- Provide user feedback when validation fails
- Trim whitespace from mode names before validation

This prevents YAML parsing errors caused by empty mode name fields.

* fix: improve UX by allowing users to empty mode name field

- Remove restriction that prevented users from emptying the name field
- Remove onBlur handler that automatically restored original name
- Allow backend validation to handle empty names and show appropriate errors
- Users can now type freely but invalid saves are prevented by backend validation

Addresses feedback from @daniel-lxs in PR #5767

* fix: allow emptying mode name field but prevent saving when invalid

- Modified onBlur handler to check if name is empty before saving
- If empty, revert to original name instead of saving empty value
- This provides better UX as requested in PR review

* fix: add proper JSON formatting to source map writes for Windows compatibility

---------

Co-authored-by: Roo Code <roomote@roocode.com>
2025-08-04 11:03:34 -07:00

116 lines
3.5 KiB
TypeScript

import { Plugin } from "vite"
import fs from "fs"
import path from "path"
/**
* Custom Vite plugin to ensure source maps are properly included in the build
* This plugin copies source maps to the build directory and ensures they're accessible
*/
export function sourcemapPlugin(): Plugin {
return {
name: "vite-plugin-sourcemap",
apply: "build",
// After the build is complete, ensure source maps are included in the build
closeBundle: {
order: "post",
handler: async () => {
console.log("Ensuring source maps are included in build...")
// Determine the correct output directory based on the build mode
const mode = process.env.NODE_ENV
let outDir
if (mode === "nightly") {
outDir = path.resolve("../apps/vscode-nightly/build/webview-ui/build")
} else {
outDir = path.resolve("../src/webview-ui/build")
}
const assetsDir = path.join(outDir, "assets")
console.log(`Source map processing for ${mode} build in ${outDir}`)
// Check if build directory exists
if (!fs.existsSync(outDir)) {
console.warn("Build directory not found:", outDir)
return
}
// Check if assets directory exists
if (!fs.existsSync(assetsDir)) {
console.warn("Assets directory not found:", assetsDir)
return
}
// Find JS files in the assets directory
const jsFiles = fs.readdirSync(assetsDir).filter((file) => file.endsWith(".js"))
console.log(`Found ${jsFiles.length} JS files in assets directory`)
// Check for source maps
for (const jsFile of jsFiles) {
const jsPath = path.join(assetsDir, jsFile)
const mapPath = jsPath + ".map"
// If source map exists, ensure it's properly referenced in the JS file
if (fs.existsSync(mapPath)) {
console.log(`Source map found for ${jsFile}`)
// Read the JS file
let jsContent = fs.readFileSync(jsPath, "utf8")
// Check if the source map is already referenced
if (!jsContent.includes("//# sourceMappingURL=")) {
console.log(`Adding source map reference to ${jsFile}`)
// Add source map reference
jsContent += `\n//# sourceMappingURL=${jsFile}.map\n`
// Write the updated JS file
fs.writeFileSync(jsPath, jsContent)
}
// Make sure map file is in the correct format and has proper sourceRoot
try {
const mapContent = JSON.parse(fs.readFileSync(mapPath, "utf8"))
// Ensure the sourceRoot is set correctly for VSCode webview
if (!mapContent.sourceRoot) {
mapContent.sourceRoot = ""
}
// Make sure "sources" paths are relative
if (mapContent.sources) {
mapContent.sources = mapContent.sources.map((source: string) => {
// Remove absolute paths to ensure they work in VSCode webview context
return source.replace(/^\//, "")
})
}
// Write back the updated source map with proper formatting
fs.writeFileSync(mapPath, JSON.stringify(mapContent, null, 2))
console.log(`Updated source map for ${jsFile}`)
} catch (error) {
console.error(`Error processing source map for ${jsFile}:`, error)
}
} else {
console.log(`No source map found for ${jsFile}`)
}
}
// Create a special file to enable source map loading in production
fs.writeFileSync(
path.join(outDir, "sourcemap-manifest.json"),
JSON.stringify({
enabled: true,
version: process.env.PKG_VERSION || "unknown",
buildTime: new Date().toISOString(),
}),
)
console.log("Source map processing complete")
},
},
}
}