* feat(web): expand ContentViewer to render PDF, CSV, HTML, XML, JSON, CSS (closes #1329) Turn ContentViewer into a per-MIME dispatch surface for resource content. It now accepts raw TextResourceContents | BlobResourceContents (in addition to the existing ContentBlock path), so ResourcePreviewPanel.toContentBlock collapses to a passthrough and blob-typed resources render natively instead of falling back to opaque "[Binary content …]" text. New renderers (clients/web/src/components/elements/): - CodeHighlight: lazy react-syntax-highlighter prism-light element. Runtime, tomorrow theme, and each grammar dynamic-import on first use (one chunk per grammar). Module-level registeredLanguages / failedLoads / loadingPromises caches; plain Code block until a grammar resolves. - PdfFrame: iframe over a Blob URL (#view=FitH), revoked on unmount. - CsvTable: papaparse -> Mantine Table (first 100 rows), plain-Code fallback. - HtmlFrame: sandbox="" iframe over a Blob URL with an injected CSP meta (no script-src, falls through to default-src 'none'). - contentViewerUtils: getMimeKind, base64 decode helpers, formatXml, wrapHtmlWithCsp, SAFE_HREF markdown-anchor allowlist (unsafe href -> span). ResourcePreviewPanel: extend the URI-suffix MIME inference table (.csv/.json/.xml/.html/.htm/.css/.pdf alongside .md). Deps: papaparse + react-syntax-highlighter (+ @types). tsconfig paths stubs redirect the deep RSH imports for typecheck (the @types ambient declarations are shadowed by the real .js under bundler resolution) — same pattern the repo uses for react/pino. Tests cover PDF blob-URL creation + cleanup, CSV table render + fallback, HTML sandbox attributes + CSP injection, JSON/XML/CSS highlighted output, the lazy-load/alias/failed-load/shared-runtime paths, and the URI-suffix MIME-inference paths. validate, test:coverage (per-file gate), test:storybook, and integration all pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(web): harden ContentViewer blob/CSV rendering per review (#1551) Address review feedback on the ContentViewer MIME-dispatch PR: - useObjectUrl: fix a dev-only StrictMode bug where the committed object URL was revoked but never recreated (setup→cleanup→setup with no re-render), blanking PDF/HTML previews. Revocation is now deferred to a microtask and guarded by a "live URL" ref so a StrictMode re-setup cancels it, while a real unmount / blob change still releases the URL. Avoids set-state-in-effect; mirrors AppRenderer's deferred-disposal. - atob: guard base64 decoding with tryDecodeBase64ToUtf8 / tryDecodeBase64ToBytes so a malformed blob from an external server degrades to the binary-content notice instead of throwing during render and taking down the whole preview panel. - CsvTable: surface the 100-row display cap with a "Showing first N of M rows" caption (no silent truncation). - Extract BinaryNotice into its own module so PdfFrame can reuse it without an import cycle. Tests added for the StrictMode path, malformed-base64 fallbacks (PDF + textual blob), the safe-decode helpers, and the truncation caption. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
46 lines
1.7 KiB
JSON
46 lines
1.7 KiB
JSON
{
|
|
"extends": "./tsconfig.app.json",
|
|
"compilerOptions": {
|
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.test.tsbuildinfo",
|
|
"types": ["vite/client", "@testing-library/jest-dom", "node", "express"],
|
|
"paths": {
|
|
"@inspector/core/*": ["../../core/*"],
|
|
"@modelcontextprotocol/inspector-test-server": ["../../test-servers/src/index.ts"],
|
|
"react": ["./node_modules/@types/react"],
|
|
"react-dom": ["./node_modules/@types/react-dom"],
|
|
"react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime"],
|
|
"vitest": ["./node_modules/vitest"],
|
|
"pino": ["./node_modules/pino"],
|
|
"zustand": ["./node_modules/zustand"],
|
|
"zustand/*": ["./node_modules/zustand/*"],
|
|
"hono": ["./node_modules/hono"],
|
|
"hono/streaming": [
|
|
"./node_modules/hono/dist/types/helper/streaming/index"
|
|
],
|
|
"@hono/node-server": ["./node_modules/@hono/node-server"],
|
|
"atomically": ["./node_modules/atomically"],
|
|
"chokidar": ["./node_modules/chokidar"],
|
|
"express": ["./node_modules/@types/express"],
|
|
"yaml": ["./node_modules/yaml"],
|
|
"@napi-rs/keyring": ["./node_modules/@napi-rs/keyring"],
|
|
"react-syntax-highlighter/dist/esm/prism-light": [
|
|
"./src/types/react-syntax-highlighter-prism-light"
|
|
],
|
|
"react-syntax-highlighter/dist/esm/styles/prism/tomorrow": [
|
|
"./src/types/react-syntax-highlighter-style"
|
|
],
|
|
"react-syntax-highlighter/dist/esm/languages/prism/*": [
|
|
"./src/types/react-syntax-highlighter-grammar"
|
|
]
|
|
}
|
|
},
|
|
"include": [
|
|
"src/**/*.test.ts",
|
|
"src/**/*.test.tsx",
|
|
"src/test/**/*.ts",
|
|
"src/test/**/*.tsx",
|
|
"../../core/**/__tests__/**/*.ts",
|
|
"../../core/**/__tests__/**/*.tsx"
|
|
],
|
|
"exclude": []
|
|
}
|