Files
dify/web/plugins/vite/react-grab-open-file.ts
Stephen Zhou f05f0be55f
Some checks failed
autofix.ci / autofix (push) Has been cancelled
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/amd64, build-api-amd64) (push) Has been cancelled
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/arm64, build-api-arm64) (push) Has been cancelled
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/amd64, build-web-amd64) (push) Has been cancelled
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/arm64, build-web-arm64) (push) Has been cancelled
Build and Push API & Web / create-manifest (api, DIFY_API_IMAGE_NAME, merge-api-images) (push) Has been cancelled
Build and Push API & Web / create-manifest (web, DIFY_WEB_IMAGE_NAME, merge-web-images) (push) Has been cancelled
Main CI Pipeline / Check Changed Files (push) Has been cancelled
Main CI Pipeline / API Tests (push) Has been cancelled
Main CI Pipeline / Web Tests (push) Has been cancelled
Main CI Pipeline / Style Check (push) Has been cancelled
Main CI Pipeline / VDB Tests (push) Has been cancelled
Main CI Pipeline / DB Migration Test (push) Has been cancelled
chore: use react-grab to replace code-inspector-plugin (#33078)
2026-03-06 14:54:24 +08:00

93 lines
2.4 KiB
TypeScript

import type { Plugin } from 'vite'
import { injectClientSnippet, normalizeViteModuleId } from './utils'
type ReactGrabOpenFilePluginOptions = {
injectTarget: string
projectRoot: string
}
export const reactGrabOpenFilePlugin = ({
injectTarget,
projectRoot,
}: ReactGrabOpenFilePluginOptions): Plugin => {
const reactGrabOpenFileClientMarker = 'react-grab-open-file-client'
const reactGrabOpenFileClientSnippet = `/* ${reactGrabOpenFileClientMarker} */
if (typeof window !== 'undefined') {
const projectRoot = ${JSON.stringify(projectRoot)};
const pluginName = 'dify-vite-open-file';
const rootRelativeSourcePathPattern = /^\\/(?!@|node_modules)(?:.+)\\.(?:[cm]?[jt]sx?|mdx?)$/;
const normalizeProjectRoot = (input) => {
return input.endsWith('/') ? input.slice(0, -1) : input;
};
const resolveFilePath = (filePath) => {
if (filePath.startsWith('/@fs/')) {
return filePath.slice('/@fs'.length);
}
if (!rootRelativeSourcePathPattern.test(filePath)) {
return filePath;
}
const normalizedProjectRoot = normalizeProjectRoot(projectRoot);
if (filePath.startsWith(normalizedProjectRoot)) {
return filePath;
}
return \`\${normalizedProjectRoot}\${filePath}\`;
};
const registerPlugin = () => {
if (window.__DIFY_REACT_GRAB_OPEN_FILE_PLUGIN_REGISTERED__) {
return;
}
const reactGrab = window.__REACT_GRAB__;
if (!reactGrab) {
return;
}
reactGrab.registerPlugin({
name: pluginName,
hooks: {
onOpenFile(filePath, lineNumber) {
const params = new URLSearchParams({
file: resolveFilePath(filePath),
column: '1',
});
if (lineNumber) {
params.set('line', String(lineNumber));
}
void fetch(\`/__open-in-editor?\${params.toString()}\`);
return true;
},
},
});
window.__DIFY_REACT_GRAB_OPEN_FILE_PLUGIN_REGISTERED__ = true;
};
registerPlugin();
window.addEventListener('react-grab:init', registerPlugin);
}
`
return {
name: 'react-grab-open-file',
apply: 'serve',
transform(code, id) {
const cleanId = normalizeViteModuleId(id)
if (cleanId !== injectTarget)
return null
const nextCode = injectClientSnippet(code, reactGrabOpenFileClientMarker, reactGrabOpenFileClientSnippet)
if (nextCode === code)
return null
return { code: nextCode, map: null }
},
}
}