Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
258 changes: 258 additions & 0 deletions .github/workflows/rendition-dss-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
name: Rendition DSS validation

on:
pull_request:
branches: [main]
paths:
- '.github/workflows/rendition-dss-validation.yml'
- 'package.json'
- 'pnpm-lock.yaml'
- 'packages/components/*-full/package.json'
- 'packages/presets/all/**'
- 'packages/renderers/signature/**'
push:
branches: [main]
paths:
- '.github/workflows/rendition-dss-validation.yml'
- 'package.json'
- 'pnpm-lock.yaml'
- 'packages/components/*-full/package.json'
- 'packages/presets/all/**'
- 'packages/renderers/signature/**'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: rendition-dss-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
validate:
runs-on: ubuntu-24.04
timeout-minutes: 45

steps:
- name: Checkout cloneable source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with:
version: 11.0.9
run_install: false

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24.19.0'
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: '3.12.12'

- name: Set up Rust
shell: bash
run: |
rustup toolchain install 1.88.0 --profile minimal
rustup default 1.88.0
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.127 --locked

- name: Install Python fixture dependency
shell: bash
run: |
python3 -m venv /tmp/file-viewer-signature-venv
echo '/tmp/file-viewer-signature-venv/bin' >> "$GITHUB_PATH"
/tmp/file-viewer-signature-venv/bin/python -m pip install \
--disable-pip-version-check \
--only-binary=:all: \
--require-hashes \
--requirement packages/renderers/signature/test/requirements-fixtures.txt

- name: Toolchain versions
shell: bash
run: |
node --version
pnpm --version
python --version
openssl version
rustc --version
cargo --version
wasm-bindgen --version

- name: Install workspace dependencies
run: pnpm install --frozen-lockfile

- name: Build core prerequisite
id: core_build
continue-on-error: true
run: pnpm --filter @file-viewer/core build

- name: Signature renderer type-check
id: signature_typecheck
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature type-check

- name: Verify signature renderer opt-in boundary
id: optional_boundary
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:optional-boundary

- name: Issue 206 CMS and timestamp verification
id: github206
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:github-206

- name: OpenSSL / RFC fixture verification
id: fixtures
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:fixtures

- name: OpenPGP architecture verification only
id: openpgp_arch
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:openpgp-architecture

- name: OpenPGP architecture and detection verification
id: openpgp
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:openpgp

- name: Standalone rPGP Rust/WASM compile
id: rust_wasm
continue-on-error: true
shell: bash
working-directory: packages/renderers/signature/rust
run: |
test -s Cargo.lock
cargo build --release --locked --target wasm32-unknown-unknown
wasm-bindgen target/wasm32-unknown-unknown/release/file_viewer_rpgp_wrapper.wasm \
--target web \
--out-dir /tmp/rpgp-wasm \
--out-name rpgp_wrapper
test -s /tmp/rpgp-wasm/rpgp_wrapper_bg.wasm
ls -lh /tmp/rpgp-wasm/rpgp_wrapper_bg.wasm

- name: Build signature renderer including rPGP WASM
id: signature_build
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature build

- name: Install pinned Playwright browsers
run: npm exec --yes --package=playwright@1.61.1 -- playwright install --with-deps chromium firefox webkit

- name: Browser rendering, CSP, offline, and cleanup verification
id: signature_browser
continue-on-error: true
run: pnpm --filter @file-viewer/renderer-signature verify:browser

- name: Full repository type-check
id: repo_typecheck
continue-on-error: true
run: pnpm type-check

- name: GitHub governance verification
id: governance
continue-on-error: true
run: pnpm verify:github-governance

- name: Offline-assets verification when available
id: offline_assets
continue-on-error: true
shell: bash
run: |
if node -e "const p=require('./package.json'); process.exit(p.scripts?.['verify:offline-assets'] ? 0 : 1)"; then
echo 'available=true' >> "$GITHUB_OUTPUT"
pnpm verify:offline-assets
else
echo 'available=false' >> "$GITHUB_OUTPUT"
echo 'verify:offline-assets is not defined on this source commit; no result claimed.'
fi

- name: Validation result summary
if: always()
shell: bash
env:
CORE_BUILD: ${{ steps.core_build.outcome }}
SIGNATURE_TYPECHECK: ${{ steps.signature_typecheck.outcome }}
OPTIONAL_BOUNDARY: ${{ steps.optional_boundary.outcome }}
GITHUB206: ${{ steps.github206.outcome }}
FIXTURES: ${{ steps.fixtures.outcome }}
OPENPGP_ARCH: ${{ steps.openpgp_arch.outcome }}
OPENPGP: ${{ steps.openpgp.outcome }}
RUST_WASM: ${{ steps.rust_wasm.outcome }}
SIGNATURE_BUILD: ${{ steps.signature_build.outcome }}
SIGNATURE_BROWSER: ${{ steps.signature_browser.outcome }}
REPO_TYPECHECK: ${{ steps.repo_typecheck.outcome }}
GOVERNANCE: ${{ steps.governance.outcome }}
OFFLINE_ASSETS: ${{ steps.offline_assets.outcome }}
OFFLINE_AVAILABLE: ${{ steps.offline_assets.outputs.available }}
VALIDATED_REPOSITORY: ${{ github.repository }}
VALIDATED_REF: ${{ github.ref_name }}
VALIDATED_SHA: ${{ github.sha }}
run: |
if [ "$OFFLINE_AVAILABLE" = 'true' ]; then
OFFLINE_DISPLAY="$OFFLINE_ASSETS"
else
OFFLINE_DISPLAY='not-defined'
fi

{
echo '## Rendition DSS validation — cloneable main'
echo
echo "- Repository: \`$VALIDATED_REPOSITORY\`"
echo "- Ref: \`$VALIDATED_REF\`"
echo "- Commit: \`$VALIDATED_SHA\`"
echo '- Validated fixes are stored directly in the source tree; no runtime patch is required.'
echo '- Runner: `ubuntu-24.04`'
echo
echo '| Check | Outcome |'
echo '| --- | --- |'
echo "| Core build | $CORE_BUILD |"
echo "| Signature type-check | $SIGNATURE_TYPECHECK |"
echo "| Opt-in dependency boundary | $OPTIONAL_BOUNDARY |"
echo "| Issue #206 verification | $GITHUB206 |"
echo "| Fixture verification | $FIXTURES |"
echo "| OpenPGP architecture | $OPENPGP_ARCH |"
echo "| OpenPGP full verification | $OPENPGP |"
echo "| Standalone Rust/WASM | $RUST_WASM |"
echo "| Signature package build | $SIGNATURE_BUILD |"
echo "| Browser rendering / CSP / offline / cleanup | $SIGNATURE_BROWSER |"
echo "| Repository type-check | $REPO_TYPECHECK |"
echo "| Governance | $GOVERNANCE |"
echo "| Offline assets | $OFFLINE_DISPLAY |"
} >> "$GITHUB_STEP_SUMMARY"

failed=0
for value in \
"$CORE_BUILD" \
"$SIGNATURE_TYPECHECK" \
"$OPTIONAL_BOUNDARY" \
"$GITHUB206" \
"$FIXTURES" \
"$OPENPGP_ARCH" \
"$OPENPGP" \
"$RUST_WASM" \
"$SIGNATURE_BUILD" \
"$SIGNATURE_BROWSER" \
"$REPO_TYPECHECK" \
"$GOVERNANCE"; do
if [ "$value" != 'success' ]; then
failed=1
fi
done
if [ "$OFFLINE_AVAILABLE" = 'true' ] && [ "$OFFLINE_ASSETS" != 'success' ]; then
failed=1
fi

if [ "$failed" -ne 0 ]; then
echo 'One or more validation checks failed.' >&2
exit 1
fi
3 changes: 3 additions & 0 deletions docs/guide/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| Presentations | binary `ppt`, `pot`; OpenXML `pptx`, `pptm`, `potx`, `potm`, `ppsx`, `ppsm`; OpenDocument `odp`; stable high-fidelity `key` |
| Apple documents | stable high-fidelity `pages`, `numbers`, and `key` with iWork '09 XML/APXL and modern Snappy/IWA parser paths |
| Layout documents | `pdf`, `ofd`, `typ`, `typst` |
| Digital signatures (explicit opt-in, experimental) | `p7m`, `p7s`, `p7b`, `p7c`, `pkcs7`, `cms`, `cmsc`, `tsq`, `tsr`, `tst`, `tsd`, `asc`, `sig`, `pgp`, `gpg` through `@file-viewer/renderer-signature`; not included in `preset-all` or `*-full` packages |
| Archives | `zip`, `7z`, `rar`, `tar`, `gz`, `tgz`, `cab`, `iso`, `apk`, `cbz`, `cbr`, and more |
| Email | `eml`, `msg`, `mbox` |
| Diagrams and mind maps | `xmind`, `drawio`, `dio`, `excalidraw`, `mermaid`, `mmd`, `plantuml`, `puml` |
Expand All @@ -40,6 +41,8 @@

The full machine-readable matrix, including containers, levels, status, and limits, is generated from `ecosystem/format-catalog.json` into [`docs/generated/format-catalog.md`](/generated/format-catalog).

The signature row is an additional experimental, package-owned definition and is not counted in the 221-extension default catalog above. It must be installed and registered explicitly. Parsing or a valid cryptographic result does not establish certificate trust, policy compliance, qualified-signature status, identity assurance, or legal validity.

## Engineering Renderer Notes

- Word preview uses `@file-viewer/renderer-word`. The package lazy-loads the self-maintained DOCX engine, `msdoc-viewer`, and RTF/OpenDocument helpers only for DOCX/DOC/RTF/ODT files, so core-only and lightweight component installs do not pull Word engines by default.
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/on-demand-renderers.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Install a single renderer when a product needs the smallest possible capability
| `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD |
| `@file-viewer/renderer-cad` | `cadRenderer` | DWG, DXF, DWF, DWFx, XPS |
| `@file-viewer/renderer-3d` | `modelRenderer` | 3D models and lightweight geometry signatures |
| `@file-viewer/renderer-signature` | `signatureRenderer` | Explicit opt-in, experimental CMS/CAdES, timestamp, and public OpenPGP inspection; excluded from `preset-all` and `*-full` packages |

Binary PowerPoint and OpenXML PowerPoint share the presentation plugin but keep separate lazy engine boundaries. The packaged `.ppt` 0.3.3 runtime is zero-config in standard layouts; for custom asset layouts, configure `presentation.pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl`. PPTX continues to use `presentation.workerUrl` / `workerType`.

Expand All @@ -88,6 +89,8 @@ Strict PPTX-only applications can import `pptxRenderer` from `@file-viewer/rende

Engine packages such as `@file-viewer/pptx`, `@file-viewer/geometry-engine`, `@file-viewer/eda-layout`, and `@file-viewer/eda-orcad` are maintained for renderer internals and advanced reuse. Normal viewer integrations should use the renderer or preset package above.

Install `@file-viewer/renderer-signature` directly and pass `signatureRenderer` in `options.renderers`. Its optional Rust/WASM toolchain and cryptographic scope are deliberately not pulled into existing Full installs.

## Automatic Preset Assembly

For an Office document platform, the bundler-neutral path is:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/zh/guide/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
| OpenDocument 演示文稿 | `odp` | OpenDocument 兼容预览 | 读取每页幻灯片的文本和页面结构 | 跨平台导出的演示文稿 |
| PDF | `pdf` | `pdfjs-dist` | 浏览器端 PDF 渲染,同源 URL 默认渐进读取,服务端支持 Range 时自动分片加载,支持缩放工具栏、页侧边栏/目录树侧边栏切换、宽度自适应、完整打印和导出 HTML | 合同、票据、版式稳定文件 |
| OFD | `ofd` | `@file-viewer/renderer-ofd` + `DLTech21/ofd.js` 源码 | 使用浏览器端 OFD 解析和页面渲染,vendor 随包离线分发,避开 npm dist 授权 wasm 分支 | 电子发票、公文、国产版式归档材料 |
| 数字签名与时间戳(显式按需、实验性) | `p7m`、`p7s`、`p7b`、`p7c`、`pkcs7`、`cms`、`cmsc`、`tsq`、`tsr`、`tst`、`tsd`、`asc`、`sig`、`pgp`、`gpg` | `@file-viewer/renderer-signature` + 浏览器 Web Crypto + 可选 rPGP Worker/WASM | 本地检查 CMS/PKCS#7、部分 CAdES、RFC 3161/5544 与公开 OpenPGP 材料;不默认进入 `preset-all` 或任何 `*-full` 包;解析或密码学结果不等于证书信任、政策合规或法律效力 | 签名附件与时间戳容器初筛 |
| Typst | `typ`、`typst` | `@myriaddreamin/typst.ts` 浏览器 WASM 编译 | 直接读取 Typst 源文档并输出按页 SVG,支持完整预览、打印和导出 HTML;compiler / renderer WASM 与默认字体仅命中 Typst 时按需加载 | 技术报告、论文草稿、工程文档模板 |
| 压缩包 | `zip`、`zipx`、`7z`、`rar`、`tar`、`gz`、`gzip`、`tgz`、`bz2`、`bzip2`、`tbz`、`tbz2`、`xz`、`txz`、`lzma`、`zst`、`cab`、`ar`、`cpio`、`iso`、`xar`、`lha`、`lzh`、`jar`、`war`、`ear`、`apk`、`cbz`、`cbr` | `@file-viewer/renderer-archive` + `libarchive.js` WASM Worker | 先读取目录,点击文件后按需解压;内部文件继续复用统一预览器,并支持 IndexedDB 缓存、GBK/GB18030 旧 ZIP 中文文件名、体积上限和 ZIP/TAR/GZIP 兼容降级 | 归档附件、批量交付包、压缩包内文档快速查看 |
| 邮件 | `eml`、`msg`、`mbox` | `@file-viewer/renderer-email` + `postal-mime` / `@kenjiuno/msgreader` | 展示头信息、HTML/文本正文、附件列表;MBOX 会解析首封邮件并标注识别数量;附件可下载,也可继续在线预览 | 邮件归档、客服工单、客户来信附件 |
Expand Down
3 changes: 3 additions & 0 deletions docs/zh/guide/on-demand-renderers.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ const options = {
| `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD |
| `@file-viewer/renderer-cad` | `cadRenderer` | DWG、DXF、DWF、DWFx、XPS |
| `@file-viewer/renderer-3d` | `modelRenderer` | 3D 模型和轻量几何签名 |
| `@file-viewer/renderer-signature` | `signatureRenderer` | 显式按需、实验性的 CMS/CAdES、时间戳与公开 OpenPGP 检查;不进入 `preset-all` 和任何 `*-full` 包 |
| `@file-viewer/renderer-drawing` | `drawingRenderer` | draw.io、Excalidraw、Mermaid、PlantUML |
| `@file-viewer/renderer-mindmap` | `mindmapRenderer` | XMind |
| `@file-viewer/renderer-geo` | `geoRenderer` | GeoJSON、KML、GPX、SHP |
Expand All @@ -253,6 +254,8 @@ const options = {

`@file-viewer/ppt`、`@file-viewer/pptx`、`@file-viewer/geometry-engine`、`@file-viewer/eda-layout` 和 `@file-viewer/eda-orcad` 是 renderer 内部引擎包;常规业务预览优先使用上表 renderer 或 preset。

需要签名容器能力时,应直接安装 `@file-viewer/renderer-signature` 并把 `signatureRenderer` 传给 `options.renderers`。它的可选 Rust/WASM 工具链和密码学边界不会被带入既有 Full 安装。

`preset: 'auto'` 会发现项目中已安装的 preset 包;当 `preset-all` 存在时会优先使用它,避免重复导入其它 preset。

## 缺失 renderer 的友好提示
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"build:pptx": "pnpm --filter @file-viewer/pptx build",
"build:doc": "pnpm --filter @file-viewer/doc build",
"build:core": "pnpm --filter @file-viewer/core build",
"build:renderers": "pnpm --filter './packages/renderers/**' build",
"build:renderers": "pnpm --filter './packages/renderers/**' --filter '!@file-viewer/renderer-signature' build",
"build:presets": "pnpm --filter './packages/presets/**' build",
"build:thumbnail": "pnpm --filter @file-viewer/thumbnail build",
"build:components": "pnpm --filter './packages/components/**' build",
Expand All @@ -30,6 +30,7 @@
"type-check:presets": "pnpm --filter './packages/presets/**' type-check",
"test:i18n": "node apps/viewer-demo/scripts/verify-japanese-i18n.mjs",
"test:spreadsheet-github-178": "pnpm --filter @file-viewer/renderer-spreadsheet verify:github-178",
"test:signature-github-206": "pnpm --filter @file-viewer/renderer-signature verify:github-206",
"test:thumbnail": "pnpm --filter @file-viewer/thumbnail test",
"test": "pnpm test:i18n && pnpm test:thumbnail",
"type-check:components": "pnpm --filter @file-viewer/web type-check && pnpm --filter @file-viewer/react type-check && pnpm --filter @file-viewer/react-legacy type-check && pnpm --filter @file-viewer/vue3 type-check && pnpm --filter @file-viewer/vue2.7 type-check && pnpm --filter @file-viewer/vue2.6 type-check && pnpm --filter @file-viewer/jquery type-check && pnpm --filter @file-viewer/svelte type-check",
Expand Down
Loading