release: prepare OneNote Tools 0.2.0
This commit is contained in:
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,5 +1,34 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.2.0 - 2026-07-22
|
||||||
|
|
||||||
|
- Open unfragmented FSSHTTPB package-store `.one` sections through the same
|
||||||
|
bounded page/content model as desktop revision stores.
|
||||||
|
- Interpret desktop and FSSHTTPB `.onetoc2` stores into authored section-group,
|
||||||
|
section, page, and subpage trees, with identity fallback and deterministic
|
||||||
|
handling of missing, duplicate, cyclic, and unlisted entries.
|
||||||
|
- Add complete-set CAB extraction for multi-cabinet packages, including split
|
||||||
|
CFDATA blocks, spanning files, codec continuity, link validation, aggregate
|
||||||
|
limits, and browser selection of one `.onepkg` plus its `.cab` companions.
|
||||||
|
- Add native MSZIP and Quantum decoding alongside uncompressed and LZX CAB
|
||||||
|
support.
|
||||||
|
- Parse and render structured outlines, rich-text formatting and safe links,
|
||||||
|
tables, signature/header-validated PNG/JPEG images, decoded ink, layout hints,
|
||||||
|
and declared embedded attachments.
|
||||||
|
- Add local structured JSON, text, Markdown, inert HTML, and deterministic
|
||||||
|
static notebook ZIP exports with diagnostics, unsupported-content summaries,
|
||||||
|
normalized resource names, and bounded output.
|
||||||
|
- Add independent parser, image-preview, display, TOC, cabinet-set, and export
|
||||||
|
resource budgets. Oversized images remain explicitly downloadable but are
|
||||||
|
not copied or decoded for automatic preview.
|
||||||
|
- Verify the implementation against the redistributable OneNote golden corpus,
|
||||||
|
a licensed five-part libmspack fixture, adversarial malformed inputs, and two
|
||||||
|
private `.onepkg` files without committing their bytes.
|
||||||
|
|
||||||
|
Known unsupported areas remain fragmented FSSHTTPB data-element reconstruction,
|
||||||
|
equations, audio/video, pixel-perfect page placement, and untested OneNote
|
||||||
|
producer variants.
|
||||||
|
|
||||||
## 0.1.0 - 2026-07-22
|
## 0.1.0 - 2026-07-22
|
||||||
|
|
||||||
- Add a standalone React/Vite reader integrated with Toolbox SDK 0.1.1,
|
- Add a standalone React/Vite reader integrated with Toolbox SDK 0.1.1,
|
||||||
@@ -8,21 +37,17 @@
|
|||||||
- Add a worker-hosted native TypeScript parser for a desktop OneNote
|
- Add a worker-hosted native TypeScript parser for a desktop OneNote
|
||||||
revision-store subset: bounded file-node and object-space traversal,
|
revision-store subset: bounded file-node and object-space traversal,
|
||||||
property sets, page metadata, titles, timestamps, levels, and plain text.
|
property sets, page metadata, titles, timestamps, levels, and plain text.
|
||||||
- Add bounded FSSHTTPB packaging, storage-index/cell/revision/object-group
|
- Add in-memory CAB enumeration and extraction for uncompressed and LZX
|
||||||
parsing and open unfragmented package-store `.one` sections through the same
|
folders, including checksums, strict paths, explicit resource limits, and
|
||||||
content model.
|
cooperative cancellation between data blocks.
|
||||||
- Add in-memory CAB enumeration and extraction for uncompressed, MSZIP,
|
|
||||||
Quantum, and LZX folders, including checksums, strict paths, explicit
|
|
||||||
resource limits, and cooperative cancellation between data blocks.
|
|
||||||
- Open contained `.one` sections independently and expose package entries,
|
- Open contained `.one` sections independently and expose package entries,
|
||||||
section/page navigation, partial failures, and structured diagnostics.
|
section/page navigation, partial failures, and structured diagnostics.
|
||||||
- Verify a Joplin `.one` golden with three pages and a Joplin LZX `0x1203`
|
- Verify a Joplin `.one` golden with three pages and a Joplin LZX `0x1203`
|
||||||
`.onepkg` golden with seven entries, five sections, and seven pages. Also
|
`.onepkg` golden with seven entries, five sections, and seven pages. Also
|
||||||
verify rust-cab uncompressed, MSZIP, and LZX `0x1303` fixtures plus a
|
verify rust-cab uncompressed and LZX `0x1303` fixtures.
|
||||||
generated two-block MSZIP dictionary-chain fixture and pinned Quantum
|
|
||||||
single-/multi-frame payloads.
|
|
||||||
- Add deterministic static release packaging, SHA-256 sidecars, pinned-source
|
- Add deterministic static release packaging, SHA-256 sidecars, pinned-source
|
||||||
provenance, fixture licensing, and security/support documentation.
|
provenance, fixture licensing, and security/support documentation.
|
||||||
|
|
||||||
Known unsupported areas include fragmented FSSHTTPB data-element
|
Known unsupported areas are FSSHTTP-packaged `.one`, MSZIP and Quantum CAB
|
||||||
reconstruction and untested OneNote producer variants.
|
extraction, multi-cabinet archives, `.onetoc2` hierarchy/order interpretation,
|
||||||
|
visual content, attachments, layout/format fidelity, links, and exports.
|
||||||
|
|||||||
10
LICENSE
10
LICENSE
@@ -1,4 +1,8 @@
|
|||||||
SPDX-License-Identifier: MPL-2.0
|
SPDX-License-Identifier: MPL-2.0 AND LGPL-2.1-only
|
||||||
|
|
||||||
OneNote Tools is licensed under the Mozilla Public License, version 2.0.
|
OneNote Tools is primarily licensed under the Mozilla Public License, version
|
||||||
The complete, unmodified licence text is provided in LICENSES/MPL-2.0.txt.
|
2.0. The adapted multi-cabinet implementation in
|
||||||
|
src/onenote/onepkg/cabinet-set.ts is LGPL-2.1-only. Complete, unmodified licence
|
||||||
|
texts are provided in LICENSES/MPL-2.0.txt and
|
||||||
|
LICENSES/libmspack-LGPL-2.1.txt. Other adapted and third-party material remains
|
||||||
|
under the terms recorded in THIRD_PARTY_NOTICES.md.
|
||||||
|
|||||||
92
README.md
92
README.md
@@ -1,53 +1,61 @@
|
|||||||
# OneNote Tools
|
# OneNote Tools
|
||||||
|
|
||||||
OneNote Tools is a standalone, local-first browser reader for a tested subset
|
OneNote Tools is a standalone, local-first browser reader and exporter for a
|
||||||
of Microsoft OneNote `.one` sections and CAB-based `.onepkg` packages. The
|
tested subset of Microsoft OneNote `.one` sections and CAB-based `.onepkg`
|
||||||
parser is native TypeScript, runs in a dedicated module worker, and never
|
packages. Its native TypeScript parser runs in a dedicated module worker; the
|
||||||
uploads or persists the selected notebook.
|
selected notebook is neither uploaded nor persisted.
|
||||||
|
|
||||||
It is also an independent application in the add·ideas Toolbox contract: the
|
It is also an independent application in the add·ideas Toolbox contract. The
|
||||||
source uses the Toolbox SDK shell and manifest, builds with Vite `base: './'`,
|
source uses the Toolbox SDK shell and manifest, builds with Vite `base: './'`,
|
||||||
and is delivered to Toolbox Portal as an already-built, checksummed static ZIP.
|
and is delivered to Toolbox Portal as a checksummed static ZIP.
|
||||||
|
|
||||||
## What version 0.1.0 can open
|
## What version 0.2.0 supports
|
||||||
|
|
||||||
- Desktop revision-store `.one` sections from the tested OneNote family. The
|
- Desktop revision-store and unfragmented FSSHTTPB package-store `.one`
|
||||||
reader exposes section/page names, stable page IDs, created and updated
|
sections from the tested producer families.
|
||||||
timestamps when present, page level, and readable plain text.
|
- Complete single- or multi-cabinet `.onepkg` sets using uncompressed, MSZIP,
|
||||||
- Unfragmented FSSHTTPB-packaged `.one` sections matching the tested Joplin
|
Quantum, or LZX CAB folders. Split packages can be selected as one `.onepkg`
|
||||||
family. Package cells, revision chains, object groups, and resolved object
|
file together with all of its `.cab` companions, in any selection order.
|
||||||
and page-space references feed the same bounded content reader.
|
- Desktop and FSSHTTPB `.onetoc2` stores inside packages. Section groups,
|
||||||
- Single-cabinet `.onepkg` files whose CAB folders are uncompressed, MSZIP,
|
authored section order, recycle-bin filtering, pages, and subpages are
|
||||||
Quantum, or LZX compressed. Each contained supported `.one` section is
|
presented as a notebook tree; unresolved entries retain a deterministic
|
||||||
parsed independently, so one unsupported section does not hide sections that
|
fallback rather than hiding readable sections.
|
||||||
did parse.
|
- Structured page content: outlines and layout hints, rich-text runs, safe
|
||||||
- Package entries, safe normalized paths, uncompressed sizes, compression
|
links, tables, PNG/JPEG images, decoded ink strokes, and declared embedded
|
||||||
metadata, section/page navigation, and structured diagnostics.
|
attachments. Resource bytes remain lazy until previewed, explicitly
|
||||||
|
downloaded, or included in an explicit export.
|
||||||
|
- Local exports as structured JSON, plain text, Markdown, inert semantic HTML,
|
||||||
|
or a deterministic static notebook ZIP. Exports retain parser diagnostics
|
||||||
|
and unsupported-content summaries; they do not create or modify OneNote
|
||||||
|
files.
|
||||||
|
|
||||||
The golden tests parse a real Joplin desktop `.one` file with three pages, an
|
The redistributable golden corpus covers desktop and unfragmented FSSHTTPB
|
||||||
unfragmented 17,197-byte Joplin FSSHTTPB `.one` file with one page, and a real
|
sections, a real LZX `.onepkg`, all four CAB compression modes, a five-part
|
||||||
Joplin `.onepkg` with seven entries, five sections, and seven pages. LZX
|
spanning CAB set, TOC hierarchy behavior, rich content, resources, and every
|
||||||
`0x1203` and `0x1303`, uncompressed CAB, one- and two-block MSZIP data, and
|
export format. The generic MSZIP, Quantum, and multi-cabinet fixtures establish
|
||||||
single- and multi-frame Quantum data are covered by fixtures. The MSZIP and
|
CAB behavior; they are not claims about every OneNote producer.
|
||||||
Quantum fixtures are CAB-level evidence, not a claim about a particular
|
|
||||||
OneNote `.onepkg` producer.
|
|
||||||
|
|
||||||
This is a structural reader, not a full-fidelity OneNote renderer. Images,
|
This remains a deliberately bounded compatibility subset. Fragmented FSSHTTPB
|
||||||
tables, ink, embedded files, layout, formatting, links, and exports are not
|
data-element reconstruction, equations, audio/video, and untested producer
|
||||||
rendered. Fragmented FSSHTTPB data elements and some producer variants remain
|
variants are not supported. Visual placement is approximate rather than a
|
||||||
unsupported. See
|
pixel-perfect OneNote layout. See [format support](docs/FORMAT_SUPPORT.md) for
|
||||||
[format support](docs/FORMAT_SUPPORT.md) for the precise matrix.
|
the precise matrix.
|
||||||
|
|
||||||
There is no Rust/Wasm runtime, server, proxy, upload, telemetry, or notebook
|
There is no Rust/Wasm runtime, notebook-processing application backend, upload
|
||||||
storage. All parsing and CAB/LZX/MSZIP/Quantum decompression is ordinary
|
proxy, telemetry, or notebook storage. All parsing and CAB decompression is
|
||||||
browser JavaScript produced from the TypeScript source.
|
ordinary browser JavaScript produced from the TypeScript source.
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
Run the static build or open it through Toolbox Portal, then drop or choose one
|
Run the static build or open it through Toolbox Portal, then:
|
||||||
local `.one` or `.onepkg` file. Use **Clear file** to terminate the current
|
|
||||||
worker and release application references. Browser garbage collection does not
|
- choose one local `.one` file; or
|
||||||
provide a secure-erasure guarantee.
|
- choose one `.onepkg` file and, for a split package, all linked `.cab` parts
|
||||||
|
in the same file-picker action.
|
||||||
|
|
||||||
|
Use **Clear file** to terminate the current worker and release application
|
||||||
|
references. Browser garbage collection does not provide a secure-erasure
|
||||||
|
guarantee.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
@@ -72,7 +80,7 @@ supplied through the SDK's `?toolbox=` context mechanism. The app uses the SDK
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run release:artifact
|
npm run release:artifact
|
||||||
(cd release && sha256sum -c onenote-tools-0.1.0.sha256)
|
(cd release && sha256sum -c onenote-tools-0.2.0.sha256)
|
||||||
```
|
```
|
||||||
|
|
||||||
The ZIP root contains the built static app and manifest plus the changelog,
|
The ZIP root contains the built static app and manifest plus the changelog,
|
||||||
@@ -95,7 +103,7 @@ into the portal React tree.
|
|||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
OneNote Tools is licensed under MPL-2.0. The complete licence is in
|
OneNote Tools is primarily MPL-2.0; the adapted multi-cabinet module is
|
||||||
[`LICENSES/MPL-2.0.txt`](LICENSES/MPL-2.0.txt). Adapted and third-party material
|
LGPL-2.1-only. The complete licence texts are in [`LICENSES/`](LICENSES/), and
|
||||||
remains under the terms recorded in
|
adapted/third-party material remains under the terms recorded in
|
||||||
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
|
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Corresponding source
|
# Corresponding source
|
||||||
|
|
||||||
The corresponding source for OneNote Tools 0.1.0 is the `v0.1.0` tag:
|
The corresponding source for OneNote Tools 0.2.0 is the `v0.2.0` tag:
|
||||||
|
|
||||||
https://git.add-ideas.de/zemion/onenote-tools/src/tag/v0.1.0
|
https://git.add-ideas.de/zemion/onenote-tools/src/tag/v0.2.0
|
||||||
|
|
||||||
Build the release from that tag with Node.js 22 or newer:
|
Build the release from that tag with Node.js 22 or newer:
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,17 @@ modules, pinned at `04a6db2aa7bd487a89c559631d79d1b384139f50`. Its adapted
|
|||||||
modules carry provenance headers and its licence is in
|
modules carry provenance headers and its licence is in
|
||||||
`LICENSES/compcol-MIT.txt`.
|
`LICENSES/compcol-MIT.txt`.
|
||||||
|
|
||||||
|
Multi-cabinet chain construction, split CFDATA handling, and spanning-file
|
||||||
|
semantics adapt libmspack's LGPL-2.1-only CAB decompressor, pinned at
|
||||||
|
`55d501976171397ccd5d5a7a1ca7da065b1d9a06`. The adapted module carries its
|
||||||
|
copyright/provenance header and the complete licence is in
|
||||||
|
`LICENSES/libmspack-LGPL-2.1.txt`.
|
||||||
|
|
||||||
|
`one2html` (MIT), pinned at
|
||||||
|
`59930ad309004030f812790c6749efe4265bb6bd`, was inspected as a behavioral
|
||||||
|
reference for rich-content rendering. No one2html source, template, stylesheet,
|
||||||
|
binary, or runtime dependency is shipped in this application.
|
||||||
|
|
||||||
MSZIP raw DEFLATE decoding uses fflate 0.8.3 (MIT). Its complete installed
|
MSZIP raw DEFLATE decoding uses fflate 0.8.3 (MIT). Its complete installed
|
||||||
licence text is included in the generated runtime licence bundle.
|
licence text is included in the generated runtime licence bundle.
|
||||||
|
|
||||||
@@ -49,5 +60,6 @@ The encoded fixture bytes are excluded from `dist` and the release ZIP. The
|
|||||||
release retains the fixture provenance document and AGPL text so these notices
|
release retains the fixture provenance document and AGPL text so these notices
|
||||||
remain complete.
|
remain complete.
|
||||||
|
|
||||||
The remaining npm packages are build and test tooling and are not shipped as
|
Vite and the remaining npm packages are build/test tooling rather than runtime
|
||||||
runtime modules in the static application.
|
modules. Vite's optional modulepreload runtime polyfill is explicitly disabled
|
||||||
|
for this baseline-browser build.
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
# Format support
|
# Format support
|
||||||
|
|
||||||
## Version 0.1.0 support matrix
|
## Version 0.2.0 support matrix
|
||||||
|
|
||||||
| Input or feature | Status | Tested evidence and boundary |
|
| Input or feature | Status | Tested evidence and boundary |
|
||||||
| ---------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------- |
|
| -------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||||
| Desktop revision-store `.one` | Supported subset | Real 34,904-byte Joplin golden; three pages |
|
| Desktop revision-store `.one` | Supported subset | Real 34,904-byte Joplin golden; three pages and rich content |
|
||||||
| FSSHTTPB-packaged `.one` | Supported subset | Licensed 17,197-byte Joplin golden; one page; unfragmented data elements |
|
| FSSHTTPB package-store `.one` | Supported subset | Licensed 17,197-byte Joplin golden; one page; unfragmented data elements |
|
||||||
| Unknown/legacy `.one` variants | Unsupported | File type and format GUIDs are validated before traversal |
|
| Unknown/legacy `.one` variants | Unsupported | File type and format GUIDs are validated before traversal |
|
||||||
| `.onepkg`, single CAB, LZX | Supported subset | Real Joplin package: LZX `0x1203`, three CFDATA blocks, seven entries, five sections, seven pages |
|
| `.onepkg`, one CAB | Supported subset | Real Joplin LZX package; generated/pinned none, MSZIP, Quantum, and LZX codec fixtures |
|
||||||
| CAB LZX `0x1303` | Supported extraction | Byte-for-byte rust-cab MIT unit fixture, two text entries |
|
| `.onepkg`, complete CAB set | Supported extraction | Licensed five-part libmspack set plus split-block, spanning-file, ordering, and malformed-set tests |
|
||||||
| CAB without compression | Supported extraction | Byte-for-byte rust-cab MIT unit fixture |
|
| Missing/inconsistent CAB parts | Rejected | Set ID, indexes, previous/next names, compression, split blocks, and spanning records must agree |
|
||||||
| CAB MSZIP | Supported extraction | rust-cab single-block fixture plus a generated two-block dictionary-chain fixture |
|
| CAB without compression | Supported extraction | Byte-for-byte rust-cab fixture |
|
||||||
| CAB Quantum | Supported extraction | Pinned compcol qtm.txt payload, generated one-folder CAB, and two-frame state/sentinel tests |
|
| CAB MSZIP | Supported extraction | rust-cab single block plus generated two-block dictionary-chain fixture |
|
||||||
| Multi-cabinet CAB / spanning files | Unsupported | Header flags and spanning folder indexes are rejected |
|
| CAB Quantum | Supported extraction | Pinned compcol payloads and generated CAB integration fixture |
|
||||||
| `.onetoc2` package entries | Listed only | Files are identified, but notebook hierarchy and section order are not interpreted |
|
| CAB LZX | Supported extraction | Real OneNote `0x1203` package and rust-cab `0x1303` fixture |
|
||||||
| Standalone `.onetoc2` | Unsupported in the app | The picker accepts only `.one` and `.onepkg` |
|
| `.onetoc2` inside a package | Supported subset | Desktop golden/hierarchy tests; FSSHTTPB dispatch uses a mocked shared-store seam, not a real golden |
|
||||||
|
| Standalone `.onetoc2` in the app | Not selectable | The picker accepts `.one`, or `.onepkg` together with `.cab` companions |
|
||||||
|
| Rich text and layout hints | Supported subset | Run formatting, paragraph properties, safe links, and bounded layout metadata |
|
||||||
|
| Tables | Supported subset | Rows, cells, nested blocks, column widths, locks, borders, and cell backgrounds |
|
||||||
|
| Images | Supported subset | Lazy, signature/header-validated PNG and JPEG resources; unsafe images stay downloadable only |
|
||||||
|
| Ink | Supported subset | Bounded delta decoding, strokes, colors, width/height, transparency, and SVG display/export |
|
||||||
|
| Embedded attachments | Supported subset | `ATTACHMENT_DECLARATION`/file-data resources remain inert until explicit download |
|
||||||
|
| Export | Supported subset | JSON, text, Markdown, inert HTML, and deterministic static notebook ZIP |
|
||||||
|
|
||||||
“Supported subset” is intentionally narrower than “all files with this
|
“Supported subset” is intentionally narrower than “all files with this
|
||||||
extension.” A successful open requires the tested desktop or FSSHTTPB OneStore
|
extension.” A successful open requires the tested desktop or FSSHTTPB OneStore
|
||||||
@@ -22,6 +29,8 @@ structures and content graph nodes. Malformed offsets, counts, references, CAB
|
|||||||
checksums, paths, compressed data, and unsupported variants produce bounded
|
checksums, paths, compressed data, and unsupported variants produce bounded
|
||||||
diagnostics or a controlled failure.
|
diagnostics or a controlled failure.
|
||||||
|
|
||||||
|
## OneStore and package boundaries
|
||||||
|
|
||||||
FSSHTTPB support covers the OneStore packaging envelope, Storage Index and
|
FSSHTTPB support covers the OneStore packaging envelope, Storage Index and
|
||||||
Storage Manifest, header/data-root cells, bounded revision chains, Object Group
|
Storage Manifest, header/data-root cells, bounded revision chains, Object Group
|
||||||
partitions, resolved object/page-space references, and available Object Data
|
partitions, resolved object/page-space references, and available Object Data
|
||||||
@@ -31,49 +40,68 @@ the store adapter rejects packages containing fragment records with a
|
|||||||
controlled `UNSUPPORTED_FORMAT` error. Excluded object data cannot be
|
controlled `UNSUPPORTED_FORMAT` error. Excluded object data cannot be
|
||||||
reconstructed from a standalone file and is likewise unsupported.
|
reconstructed from a standalone file and is likewise unsupported.
|
||||||
|
|
||||||
|
For a split package, the browser must receive the `.onepkg` and every linked
|
||||||
|
`.cab` companion in one selection. The extractor validates a complete,
|
||||||
|
uniquely indexed cabinet chain before decoding. It reassembles split CFDATA
|
||||||
|
blocks, preserves codec state across cabinets, and reconciles the CAB
|
||||||
|
`continued from previous`, `continued to next`, and `continued both` file
|
||||||
|
records. Partial sets are not opened heuristically.
|
||||||
|
|
||||||
The default LZX limit accepts CAB window sizes through 8 MiB, but compatibility
|
The default LZX limit accepts CAB window sizes through 8 MiB, but compatibility
|
||||||
claims are fixture-backed only for window bits 18 (`0x1203`) and 19 (`0x1303`).
|
claims are fixture-backed only for window bits 18 (`0x1203`) and 19 (`0x1303`).
|
||||||
MSZIP validates the `CK` prefix, limits each compressed block to 32 KiB + 12,
|
MSZIP validates the `CK` prefix, limits each compressed block to 32 KiB + 12,
|
||||||
decodes into a fixed-size output buffer, requires the declared output length,
|
decodes into a fixed-size output buffer, requires the declared output length,
|
||||||
and carries at most 32 KiB of history between blocks in one folder. The MSZIP
|
and carries at most 32 KiB of history between blocks in one logical folder.
|
||||||
tests establish CAB extraction behavior; no redistributable MSZIP-compressed
|
|
||||||
OneNote export is currently present, so they do not establish producer-specific
|
|
||||||
`.onepkg` compatibility.
|
|
||||||
Quantum validates level/window metadata, bounds its window to 2 MiB by default,
|
Quantum validates level/window metadata, bounds its window to 2 MiB by default,
|
||||||
requires full 32 KiB intermediate frames, preserves its arithmetic models and
|
requires full 32 KiB intermediate frames, preserves its arithmetic models and
|
||||||
LZ window across frames, and injects exactly one `0xFF` CAB block sentinel.
|
LZ window across frames/cabinets, and injects exactly one `0xFF` CAB block
|
||||||
Trailer padding is limited to the documented 0..4 zero bytes; match, frame,
|
sentinel. Trailer, match, frame, output, operation, and cancellation bounds are
|
||||||
output, operation, and cancellation bounds are enforced. Its tests likewise
|
enforced.
|
||||||
establish CAB extraction behavior only: no redistributable Quantum-compressed
|
|
||||||
OneNote export is currently present.
|
|
||||||
|
|
||||||
Trailing CAB data is ignored with a warning. Reserved CAB areas are bounded and
|
Trailing CAB data is ignored with a warning. Reserved CAB areas are bounded and
|
||||||
skipped. CAB names are decoded as strict UTF-8; unmarked valid UTF-8 receives a
|
skipped. CAB names are decoded as strict UTF-8; unmarked valid UTF-8 receives a
|
||||||
warning, while invalid non-ASCII legacy-code-page names are rejected rather
|
warning, while invalid non-ASCII legacy-code-page names are rejected rather
|
||||||
than guessed.
|
than guessed.
|
||||||
|
|
||||||
## Extracted OneNote data
|
## Notebook and page model
|
||||||
|
|
||||||
The supported section paths currently return:
|
Supported `.onetoc2` stores provide authored section order, nested section
|
||||||
|
groups, display names, identities, and colors. Exact normalized paths take
|
||||||
|
precedence; same-directory file identity is a guarded fallback. Recycle-bin
|
||||||
|
entries are omitted, duplicate/cyclic references are diagnosed, and readable
|
||||||
|
sections not reachable from a TOC are appended deterministically. Page levels
|
||||||
|
are interpreted as a page/subpage tree.
|
||||||
|
|
||||||
- section display name;
|
The supported section path returns:
|
||||||
- page ID, title, created/updated timestamp when available, and page level;
|
|
||||||
- visible Unicode/extended-ASCII rich text as plain text and a text preview;
|
|
||||||
- diagnostics tied to an offset, structure, or page where available.
|
|
||||||
|
|
||||||
It does not preserve visual position, rich-text formatting, list formatting,
|
- section/page identities, names, timestamps, page levels, and diagnostics;
|
||||||
tables, images, ink, equations, embedded files, audio/video, active links,
|
- outlines and recursively nested content blocks;
|
||||||
page versions/conflicts, or exports. Unsupported content objects remain visible
|
- rich-text runs with bold, italic, underline, strikeout, super/subscript,
|
||||||
as diagnostics instead of being silently presented as parsed.
|
font, size, foreground/highlight color, paragraph alignment/spacing, and
|
||||||
|
allow-listed `http`, `https`, and `mailto` links;
|
||||||
|
- tables, lazy PNG/JPEG images, embedded-file declarations, and decoded ink;
|
||||||
|
- bounded layout hints such as offsets, maximum dimensions, and alignment.
|
||||||
|
|
||||||
Within a supported `.onepkg`, each `.one` entry is parsed independently.
|
This is not a pixel-perfect OneNote renderer. Equations, audio/video, page
|
||||||
Malformed or unsupported sections are marked failed/unsupported while other
|
versions/conflicts, and producer-specific structures outside the golden corpus
|
||||||
sections remain available. Package navigation is temporary normalized-path
|
are not represented. Encountered unsupported object kinds remain visible as
|
||||||
order until `.onetoc2` interpretation is implemented.
|
diagnostics. Active notebook HTML/SVG is never injected.
|
||||||
|
|
||||||
|
## Export
|
||||||
|
|
||||||
|
All exports are created inside the existing local parser worker. They include a
|
||||||
|
versioned parser/support manifest, the readable page hierarchy, diagnostics,
|
||||||
|
and unsupported-content summaries. The static ZIP contains inert semantic HTML
|
||||||
|
plus JSON, text, Markdown, warnings, and bounded resources. Resource names are
|
||||||
|
normalized, potentially active attachment suffixes are neutralized, and only
|
||||||
|
validated image types may be embedded for automatic display.
|
||||||
|
|
||||||
|
Export is a representation of the parser-supported subset, not a round trip:
|
||||||
|
it neither emits `.one`/`.onepkg` nor promises full OneNote visual fidelity.
|
||||||
|
|
||||||
## Test fixtures
|
## Test fixtures
|
||||||
|
|
||||||
The exact hashes, source revisions, licences, expected page names, and CAB
|
The exact hashes, source revisions, licences, expected content, and CAB
|
||||||
structures are recorded in
|
structures are recorded in
|
||||||
[`tests/fixtures/README.md`](../tests/fixtures/README.md). Tests use no private
|
[`tests/fixtures/README.md`](../tests/fixtures/README.md). Tests use no private
|
||||||
notebooks and do not treat a synthetic archive as proof of Microsoft OneNote
|
notebooks and do not treat a synthetic archive as proof of Microsoft OneNote
|
||||||
|
|||||||
@@ -4,31 +4,41 @@ The desktop `.one` reader adapts selected structures from the pinned
|
|||||||
`onenote.rs` implementation. It is not a line-for-line or complete port.
|
`onenote.rs` implementation. It is not a line-for-line or complete port.
|
||||||
|
|
||||||
| TypeScript module | Upstream path(s) | Revision | Port scope and deviations |
|
| TypeScript module | Upstream path(s) | Revision | Port scope and deviations |
|
||||||
| ---------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `src/onenote/onestore/file-node.ts` | `onestore/desktop/file_structure/file_node_list_fragment.rs`, `file_node/*`, chunk references | `onenote.rs@5138a39a3f4e72b840932f9872fecde52fa9da60` | Selected; immutable byte input, strict range checks, fragment/child cycle detection, and depth/count limits |
|
| `src/onenote/onestore/file-node.ts` | `onestore/desktop/file_structure/file_node_list_fragment.rs`, `file_node/*`, chunk references | `onenote.rs@5138a39a3f4e72b840932f9872fecde52fa9da60` | Selected; immutable byte input, strict range checks, fragment/child cycle detection, and depth/count limits |
|
||||||
| `src/onenote/onestore/property-set.ts` | `onestore/shared/{object_prop_set,prop_set,property,object_stream_header}.rs` | same | Substantial; bounded vectors/counts/nesting and serializable discriminated unions |
|
| `src/onenote/onestore/property-set.ts` | `onestore/shared/{object_prop_set,prop_set,property,object_stream_header}.rs` | same | Substantial; bounded vectors/counts/nesting and serializable discriminated unions |
|
||||||
| `src/onenote/onestore/desktop-store.ts` | `onestore/desktop/{file_node,file_structure,objects}/*` | same | Selected desktop section path; explicit missing-reference errors; file-data/attachment payloads skipped with diagnostics |
|
| `src/onenote/onestore/desktop-store.ts` | `onestore/desktop/{file_node,file_structure,objects}/*` | same | Selected desktop section/TOC paths; explicit missing-reference errors; bounded file-data references |
|
||||||
|
| `src/onenote/onestore/file-data.ts` | `onestore/desktop/{file_node/shared,objects/file_data_store}.rs` | same | Bounded zero-copy file-data payload ranges, checked declarations, and explicit external/invalid availability |
|
||||||
|
| `src/onenote/onestore/types.ts` | `onestore/desktop/common/*`, `onestore/shared/*`, and desktop object modules | same | Serializable structural records used across desktop and FSSHTTPB adapters |
|
||||||
| `src/onenote/fsshttpb/*` | `fsshttpb/{data,data_element,packaging}.rs` | same | Native bounded package/header/data-element records, checked compact integers, zero-copy BLOB ranges; fragment records parsed but not assembled |
|
| `src/onenote/fsshttpb/*` | `fsshttpb/{data,data_element,packaging}.rs` | same | Native bounded package/header/data-element records, checked compact integers, zero-copy BLOB ranges; fragment records parsed but not assembled |
|
||||||
| `src/onenote/onestore/fsshttp-store.ts` | `onestore/fsshttpb/{header,mapping_table,object,object_space,revision,revision_role}.rs` | same | Unfragmented package-store adapter; bounded/cycle-checked revision chains, newest-revision precedence, resolved positional reference arrays |
|
| `src/onenote/onestore/fsshttp-store.ts` | `onestore/fsshttpb/{header,mapping_table,object,object_space,revision,revision_role}.rs` | same | Unfragmented package-store adapter; bounded/cycle-checked revision chains, newest-revision precedence, resolved positional reference arrays |
|
||||||
| `src/onenote/one/{constants,section}.ts` | `one/property*`, `one/property_set/*`, `onenote/{section,page,page_series,outline,rich_text}.rs` | same | Page metadata, titles, and plain text only; bounded graph traversal; visual/embedded content diagnosed |
|
| `src/onenote/one/{constants,section,content}.ts` | `one/property*`, `one/property_set/*`, `onenote/{section,page,page_series,outline,rich_text,table,image,embedded_file,ink}.rs` | same | Page metadata plus bounded recursive rich text, tables, resources, layout hints, and decoded ink in an inert browser DTO |
|
||||||
|
| `src/onenote/one/property-access.ts` | `one/property/{simple,object_reference}.rs` | same | Typed property access and resolved/compact reference validation without coercion |
|
||||||
|
| `src/onenote/one/section-content.ts` | `onenote/{section,page_series,page}.rs` | same | Worker-retained page/content/resource model with bounded diagnostics and timestamps |
|
||||||
|
| `src/onenote/parser/parse-toc.ts` | `one/property_set/toc_container.rs` and desktop/FSSHTTP OneStore readers | same | Desktop/FSSHTTP TOC content, names, identities, ordering, colors, nesting, and bounded diagnostics |
|
||||||
|
|
||||||
The browser-native package path has separate MIT provenance:
|
The browser-native package path has separate upstream provenance:
|
||||||
|
|
||||||
| TypeScript module | Upstream path(s) | Revision and selected licence | Port scope and deviations |
|
| TypeScript module | Upstream path(s) | Revision and selected licence | Port scope and deviations |
|
||||||
| ------------------------------------------------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `src/onenote/onepkg/{cabinet,checksum}.ts` | rust-cab `src/{cabinet,folder,file,ctype,checksum}.rs` | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2`, MIT | CAB reading/checksum adapted for immutable browser bytes, strict normalized paths, checked ranges/checksums, whole-folder extraction, explicit limits, and cancellation/yield hooks; writers are not ported |
|
| `src/onenote/onepkg/{cabinet,checksum}.ts` | rust-cab `src/{cabinet,folder,file,ctype,checksum}.rs` | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2`, MIT | CAB reading/checksum adapted for immutable browser bytes, strict normalized paths, checked ranges/checksums, whole-folder extraction, explicit limits, and cancellation/yield hooks; writers are not ported |
|
||||||
|
| `src/onenote/onepkg/cabinet-set.ts` | libmspack `mspack/cabd.c` | `55d501976171397ccd5d5a7a1ca7da065b1d9a06`, LGPL-2.1-only | Complete named-set validation, split CFDATA reassembly, codec continuity, spanning-file reconciliation, aggregate limits, and immutable browser inputs |
|
||||||
| `src/onenote/onepkg/mszip/decoder.ts` | rust-cab `src/mszip.rs`; fflate raw DEFLATE | rust-cab revision above; fflate 0.8.3, MIT | `CK` framing and persistent 32 KiB folder history follow rust-cab; raw DEFLATE uses fflate with a caller-owned bounded buffer and strict declared-size checks |
|
| `src/onenote/onepkg/mszip/decoder.ts` | rust-cab `src/mszip.rs`; fflate raw DEFLATE | rust-cab revision above; fflate 0.8.3, MIT | `CK` framing and persistent 32 KiB folder history follow rust-cab; raw DEFLATE uses fflate with a caller-owned bounded buffer and strict declared-size checks |
|
||||||
| `src/onenote/onepkg/quantum/{bit-reader,budget,decoder,model,tables}.ts` | compcol `src/quantum/{bits,decoder,model,tables}.rs` | `04a6db2aa7bd487a89c559631d79d1b384139f50`, MIT | Native TypeScript arithmetic/model/LZ decoder; fixed CAB output, 2 MiB maximum window, strict match/frame/trailer checks, two-block lookahead, operation budget, and cancellation checkpoints |
|
| `src/onenote/onepkg/quantum/{bit-reader,budget,decoder,model,tables}.ts` | compcol `src/quantum/{bits,decoder,model,tables}.rs` | `04a6db2aa7bd487a89c559631d79d1b384139f50`, MIT | Native TypeScript arithmetic/model/LZ decoder; fixed CAB output, 2 MiB maximum window, strict match/frame/trailer checks, two-block lookahead, operation budget, and cancellation checkpoints |
|
||||||
| `src/onenote/onepkg/lzx/{bit-reader,huffman,decoder}.ts` | lzxd 0.2.5 `src/{bitstream,tree,block,window,lib}.rs` | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd`, MIT option of MIT OR Apache-2.0 | Directly translated core with typed arrays, CAB CFDATA boundaries, persistent folder state, strict malformed-stream errors, and operation/window/cancellation limits; delta reference data is omitted |
|
| `src/onenote/onepkg/lzx/{bit-reader,huffman,decoder}.ts` | lzxd 0.2.5 `src/{bitstream,tree,block,window,lib}.rs` | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd`, MIT option of MIT OR Apache-2.0 | Directly translated core with typed arrays, CAB CFDATA boundaries, persistent folder state, strict malformed-stream errors, and operation/window/cancellation limits; delta reference data is omitted |
|
||||||
|
|
||||||
The bounded binary readers, format detection, parser limits/error model, path
|
The bounded binary readers, format detection, parser limits/error model, path
|
||||||
policy, worker protocol/DTOs, package-to-section boundary, and application UI
|
policy, package TOC-to-section hierarchy, worker protocol/DTOs, safe image
|
||||||
are original TypeScript implementations guided by the normative specifications
|
inspection, export serializers/ZIP writer, and React application UI are original
|
||||||
and project requirements.
|
TypeScript implementations guided by the normative specifications and project
|
||||||
|
requirements. The pinned `one2html` renderer informed expected visual semantics
|
||||||
|
for rich text, tables, images, attachments, and ink; its Rust/templates/CSS were
|
||||||
|
not copied or shipped.
|
||||||
|
|
||||||
Files adapted from `onenote.rs` carry an MPL-2.0 notice, SPDX identifier,
|
Files adapted from `onenote.rs` carry an MPL-2.0 notice, SPDX identifier,
|
||||||
upstream path/revision, and deviations. Files adapted from rust-cab, compcol,
|
upstream path/revision, and deviations. Files adapted from rust-cab, compcol,
|
||||||
or lzxd carry their MIT provenance, copyright notice, exact revision, and deviations.
|
or lzxd carry their MIT provenance, copyright notice, exact revision, and
|
||||||
|
deviations. The multi-cabinet module carries libmspack's LGPL-2.1-only notice.
|
||||||
Licence texts are reproduced in `LICENSES/` and included in the release ZIP.
|
Licence texts are reproduced in `LICENSES/` and included in the release ZIP.
|
||||||
|
|
||||||
Focused tests cover successful pinned fixtures plus malformed bounds,
|
Focused tests cover successful pinned fixtures plus malformed bounds,
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
# Specifications and pinned references
|
# Specifications and pinned references
|
||||||
|
|
||||||
Version 0.1.0 records these immutable implementation revisions:
|
Version 0.2.0 records these immutable implementation revisions:
|
||||||
|
|
||||||
| Repository | Exact revision | Use |
|
| Repository | Exact revision | Use |
|
||||||
| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------- |
|
| ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------- |
|
||||||
| [`toolbox-sdk`](https://git.add-ideas.de/zemion/toolbox-sdk/src/commit/5e206baf42dfae5a00f2743fb2cc501bb12d9b7a) | `5e206baf42dfae5a00f2743fb2cc501bb12d9b7a` | App contract, React shell, manifest schema/testkit, and nested-path behavior |
|
| [`toolbox-sdk`](https://git.add-ideas.de/zemion/toolbox-sdk/src/commit/5e206baf42dfae5a00f2743fb2cc501bb12d9b7a) | `5e206baf42dfae5a00f2743fb2cc501bb12d9b7a` | App contract, React shell, manifest schema/testkit, and nested-path behavior |
|
||||||
| [`toolbox-portal`](https://git.add-ideas.de/zemion/toolbox-portal/src/commit/5d2e466ad61e36a0e2be2a2d8459b1a127f53f11) | `5d2e466ad61e36a0e2be2a2d8459b1a127f53f11` | Reviewed ZIP shape, exact checksum lock, and independent-app assembly model |
|
| [`toolbox-portal`](https://git.add-ideas.de/zemion/toolbox-portal/src/commit/d46f1b61fb85a18299b6b8af2148dcd991ef6b05) | `d46f1b61fb85a18299b6b8af2148dcd991ef6b05` | Reviewed ZIP shape, exact checksum lock, independent-app assembly, and nginx deployment model |
|
||||||
| [`onenote.rs`](https://github.com/msiemens/onenote.rs/tree/5138a39a3f4e72b840932f9872fecde52fa9da60) | `5138a39a3f4e72b840932f9872fecde52fa9da60` | Selected desktop/FSSHTTPB OneStore and MS-ONE structures adapted into TypeScript |
|
| [`onenote.rs`](https://github.com/msiemens/onenote.rs/tree/5138a39a3f4e72b840932f9872fecde52fa9da60) | `5138a39a3f4e72b840932f9872fecde52fa9da60` | Selected desktop/FSSHTTPB OneStore and MS-ONE structures adapted into TypeScript |
|
||||||
| [`rust-cab`](https://github.com/mdsteele/rust-cab/tree/c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2) | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2` | CAB structures, checksum, enumeration/extraction, MSZIP history, and unit fixtures |
|
| [`rust-cab`](https://github.com/mdsteele/rust-cab/tree/c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2) | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2` | CAB structures, checksum, enumeration/extraction, MSZIP history, and unit fixtures |
|
||||||
| [`compcol`](https://github.com/KarpelesLab/compcol/tree/04a6db2aa7bd487a89c559631d79d1b384139f50) | `04a6db2aa7bd487a89c559631d79d1b384139f50` | Quantum bit reader, arithmetic models, LZ window, CAB sentinel behavior, and tests |
|
| [`compcol`](https://github.com/KarpelesLab/compcol/tree/04a6db2aa7bd487a89c559631d79d1b384139f50) | `04a6db2aa7bd487a89c559631d79d1b384139f50` | Quantum bit reader, arithmetic models, LZ window, CAB sentinel behavior, and tests |
|
||||||
| [`lzxd` 0.2.5](https://github.com/Lonami/lzxd/tree/4748e43594e3e30cff2ace3a6ad7a376c9816fdd) | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd` | LZX bitstream, Huffman, block/window, match, and E8 logic adapted into TypeScript |
|
| [`lzxd` 0.2.5](https://github.com/Lonami/lzxd/tree/4748e43594e3e30cff2ace3a6ad7a376c9816fdd) | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd` | LZX bitstream, Huffman, block/window, match, and E8 logic adapted into TypeScript |
|
||||||
|
| [`libmspack`](https://github.com/kyz/libmspack/tree/55d501976171397ccd5d5a7a1ca7da065b1d9a06) | `55d501976171397ccd5d5a7a1ca7da065b1d9a06` | Multi-cabinet chain, split CFDATA, spanning-file semantics, and licensed fixtures |
|
||||||
|
| [`one2html`](https://github.com/msiemens/one2html/tree/59930ad309004030f812790c6749efe4265bb6bd) | `59930ad309004030f812790c6749efe4265bb6bd` | Behavioral reference for rich text, tables, images, attachments, ink, and HTML rendering |
|
||||||
|
|
||||||
The SDK and Portal revisions were inspected from the local repositories. The
|
The SDK and Portal revisions were inspected from the local repositories. Every
|
||||||
four parser references were cloned and reviewed at the hashes above; a branch
|
parser/renderer reference was cloned and reviewed at the hash above; a branch
|
||||||
name or package version alone is not used as provenance. Source-level mappings
|
name or package version alone is not used as provenance. Source-level mappings
|
||||||
and behavioural deviations are in [PORTING.md](PORTING.md).
|
and behavioural deviations are in [PORTING.md](PORTING.md).
|
||||||
|
|
||||||
@@ -50,5 +52,6 @@ The Microsoft documents are linked rather than copied. Their published pages
|
|||||||
can change independently; the source references and golden bytes remain pinned
|
can change independently; the source references and golden bytes remain pinned
|
||||||
for reproducibility.
|
for reproducibility.
|
||||||
|
|
||||||
`one2html` is deliberately not pinned or inspected because visual HTML
|
The `one2html` renderer is a behavioral reference only: no Rust, Askama
|
||||||
rendering is outside this release.
|
template, stylesheet, or generated HTML is shipped or executed by this
|
||||||
|
application.
|
||||||
|
|||||||
183
docs/SECURITY.md
183
docs/SECURITY.md
@@ -2,35 +2,42 @@
|
|||||||
|
|
||||||
## Trust boundary and local processing
|
## Trust boundary and local processing
|
||||||
|
|
||||||
Selected `.one` and `.onepkg` files are untrusted. The main thread checks the
|
Selected `.one`, `.onepkg`, and companion `.cab` files are untrusted. The main
|
||||||
source size, reads one file into an `ArrayBuffer`, transfers it to a dedicated
|
thread validates the selection and combined size, reads the files into
|
||||||
module worker, and receives serializable data-transfer objects. CAB entries are
|
`ArrayBuffer`s, and transfers them to a dedicated module worker. CAB entries
|
||||||
extracted only into memory; archive paths are never written to the filesystem.
|
are extracted only into memory; archive paths are never written to the
|
||||||
|
filesystem.
|
||||||
|
|
||||||
The worker is a fault-containment and responsiveness boundary, not a security
|
The worker is a fault-containment and responsiveness boundary, not a security
|
||||||
sandbox. A successful open keeps its worker session alive for page requests.
|
sandbox. A successful open keeps its session alive for page/resource/export
|
||||||
Clearing the file, choosing another file, or unmounting the app terminates that
|
requests. Clearing the file, choosing another file, or unmounting the app
|
||||||
worker; a failed open also terminates it. JavaScript garbage collection does
|
terminates that worker; a failed open also terminates it. JavaScript garbage
|
||||||
not promise immediate release or secure erasure.
|
collection does not promise immediate release or secure erasure.
|
||||||
|
|
||||||
The application does not:
|
The application does not:
|
||||||
|
|
||||||
- upload or transmit notebook bytes;
|
- upload or transmit notebook bytes;
|
||||||
- use a backend, proxy, telemetry, analytics, remote fonts, or external content
|
- use a notebook-processing application backend, upload proxy, telemetry,
|
||||||
fetching;
|
analytics, remote fonts, or notebook-referenced external content fetching;
|
||||||
|
the optional same-origin Toolbox catalogue/manifest is application chrome
|
||||||
|
and receives no notebook data;
|
||||||
- persist source or derived content in LocalStorage, IndexedDB, Cache Storage,
|
- persist source or derived content in LocalStorage, IndexedDB, Cache Storage,
|
||||||
cookies, or a service worker;
|
cookies, or a service worker;
|
||||||
- execute notebook content or inject notebook HTML/SVG;
|
- execute notebook content or inject notebook HTML/SVG;
|
||||||
- use WebAssembly, a Rust runtime, or a native helper.
|
- use WebAssembly, a Rust runtime, or a native helper.
|
||||||
|
|
||||||
## Active default limits
|
## Active parser defaults
|
||||||
|
|
||||||
The main thread rejects a source larger than 512 MiB before reading it. The
|
The main thread accepts one `.one`, or one `.onepkg` plus its `.cab`
|
||||||
OneStore section parsers then apply these independent defaults:
|
companions. It permits at most 256 selected parts, 512 MiB per file, and 512 MiB
|
||||||
|
combined before reading.
|
||||||
|
|
||||||
|
The OneStore parser applies these independent defaults per section/store:
|
||||||
|
|
||||||
| Resource | Default limit |
|
| Resource | Default limit |
|
||||||
| ------------------------------------- | -------------------: |
|
| ------------------------------------------------ | -------------------------: |
|
||||||
| Section bytes | 512 MiB |
|
| Section bytes | 512 MiB |
|
||||||
|
| Transaction fragments / entries | 16,384 / 1,000,000 |
|
||||||
| File-node list fragments / nesting | 16,384 / 64 |
|
| File-node list fragments / nesting | 16,384 / 64 |
|
||||||
| File nodes | 1,000,000 |
|
| File nodes | 1,000,000 |
|
||||||
| Objects | 500,000 |
|
| Objects | 500,000 |
|
||||||
@@ -38,26 +45,39 @@ OneStore section parsers then apply these independent defaults:
|
|||||||
| Stream IDs | 1,000,000 |
|
| Stream IDs | 1,000,000 |
|
||||||
| FSSHTTPB revision-chain entries | 16,384 |
|
| FSSHTTPB revision-chain entries | 16,384 |
|
||||||
| One property vector | 64 MiB |
|
| One property vector | 64 MiB |
|
||||||
| Object references | 1,000,000 |
|
| Desktop object-reference vector | 1,000,000 per vector |
|
||||||
|
| FSSHTTPB ExGUID/CellID references | 1,000,000 aggregate |
|
||||||
|
| Nested PropertySets per ObjectPropSet | 1,000,000 aggregate |
|
||||||
|
| File-data objects / one payload / total payloads | 10,000 / 256 MiB / 512 MiB |
|
||||||
| Content-graph depth | 256 |
|
| Content-graph depth | 256 |
|
||||||
| Pages per section | 100,000 |
|
| Content blocks / text runs / table cells | 100,000 each |
|
||||||
| Diagnostics per section | 10,000 |
|
| Decoded ink points | 100,000 |
|
||||||
| Extracted text per section | 2,000,000 characters |
|
| Pages | 10,000 |
|
||||||
|
| Diagnostics | 10,000 |
|
||||||
|
| Retained rich/extracted text | 2,000,000 UTF-16 units |
|
||||||
|
|
||||||
The CAB/package path applies these defaults:
|
Images are automatically previewable only when a bounded PNG IHDR or JPEG
|
||||||
|
marker/SOF inspection succeeds. The compressed payload must be at most 32 MiB,
|
||||||
|
each dimension at most 16,384 pixels, and the image at most 67,108,864 pixels.
|
||||||
|
JPEG inspection reads at most 1 MiB of markers and 4,096 marker records. Images
|
||||||
|
outside those limits stay inert and are available only through an explicit
|
||||||
|
download action.
|
||||||
|
|
||||||
|
The CAB/package path applies these defaults across a complete cabinet set:
|
||||||
|
|
||||||
| Resource | Default limit |
|
| Resource | Default limit |
|
||||||
| ------------------------------- | -------------: |
|
| ------------------------------------------- | -----------------: |
|
||||||
| Cabinet input | 512 MiB |
|
| One cabinet / complete set input | 512 MiB / 512 MiB |
|
||||||
| Folders / files | 1,024 / 10,000 |
|
| Cabinet parts | 256 |
|
||||||
| CFDATA blocks | 131,072 |
|
| Folder segments / files | 1,024 / 10,000 |
|
||||||
|
| CFDATA fragments | 131,072 |
|
||||||
| CAB name bytes | 255 |
|
| CAB name bytes | 255 |
|
||||||
| Path characters / path segments | 4,096 / 64 |
|
| Path characters / path segments | 4,096 / 64 |
|
||||||
|
| TOC construction operations / diagnostics | 1,000,000 / 10,000 |
|
||||||
| One extracted file | 256 MiB |
|
| One extracted file | 256 MiB |
|
||||||
| One folder output | 512 MiB |
|
| One logical folder output | 512 MiB |
|
||||||
| Total folder output | 512 MiB |
|
| Total folder output / extracted entry bytes | 512 MiB / 512 MiB |
|
||||||
| Total extracted entry bytes | 512 MiB |
|
| Logical-folder compression ratio | 200:1 |
|
||||||
| Folder compression ratio | 200:1 |
|
|
||||||
| One MSZIP compressed block | 32 KiB + 12 B |
|
| One MSZIP compressed block | 32 KiB + 12 B |
|
||||||
| Quantum window | 2 MiB |
|
| Quantum window | 2 MiB |
|
||||||
| LZX window | 8 MiB |
|
| LZX window | 8 MiB |
|
||||||
@@ -65,56 +85,89 @@ The CAB/package path applies these defaults:
|
|||||||
|
|
||||||
A CFDATA block may declare at most 32 KiB of output. Counts and offsets use
|
A CFDATA block may declare at most 32 KiB of output. Counts and offsets use
|
||||||
checked arithmetic and bounded readers. The CAB parser verifies supplied block
|
checked arithmetic and bounded readers. The CAB parser verifies supplied block
|
||||||
checksums, rejects overlapping/out-of-range data, rejects absolute/traversal,
|
checksums; rejects overlapping/out-of-range data, traversal/absolute/control or
|
||||||
empty, control-character, and case-insensitive duplicate paths, and refuses
|
case-insensitive duplicate paths; and validates a complete cabinet set before
|
||||||
multi-cabinet/spanning entries.
|
decoding. Set IDs, indexes, links, compression, split blocks, and spanning-file
|
||||||
|
records must agree. Reserve areas are private to each cabinet/folder and are
|
||||||
|
validated locally rather than compared across parts.
|
||||||
|
|
||||||
MSZIP checks its `CK` framing and raw DEFLATE data, writes into a fixed caller
|
MSZIP checks `CK` framing and raw DEFLATE data, writes into a fixed caller
|
||||||
buffer with one overflow-detection byte, requires the exact declared output
|
buffer with overflow detection, requires the declared output size, and keeps at
|
||||||
size, and retains no more than 32 KiB of history. LZX checks its window, Huffman
|
most 32 KiB of logical-folder history. LZX and Quantum validate their windows,
|
||||||
trees, block sizes, match ranges, output size, and operation budget. CAB
|
trees/models, blocks/frames, matches, output, trailer, and operation budgets.
|
||||||
Quantum limits its window, model scans, arithmetic renormalisation, matches,
|
Codec state is preserved across continued cabinet segments. Extraction checks
|
||||||
frame/output boundaries, operation count, and trailer padding. It queues at
|
cancellation between data blocks and periodically yields to the worker loop.
|
||||||
most the current and next compressed block so a synthetic `0xFF` sentinel can
|
|
||||||
be consumed without buffering a complete folder. CAB extraction checks
|
Desktop OneStore traversal checks fragment/reference cycles, nesting,
|
||||||
cancellation during Quantum work and yields between data blocks so the worker
|
object/property/reference counts, and byte ranges. FSSHTTPB parsing bounds every
|
||||||
can process termination. Desktop OneStore traversal checks fragment/reference
|
declared stream body and compact integer, rejects invalid end markers and
|
||||||
cycles, nesting, object/property/reference counts, and byte ranges. FSSHTTPB
|
non-zero package tails, checks aggregate reference/mapping counts and revision
|
||||||
parsing bounds every declared stream body and compact integer, rejects invalid
|
cycles, and retains BLOB payloads as bounded source ranges. Fragment records
|
||||||
end markers and non-zero package tails, checks mapping/reference counts and
|
are range-checked, but packages containing them are rejected because
|
||||||
revision cycles, and retains BLOB payloads as bounded source ranges. Fragment
|
|
||||||
records are range-checked, but packages containing them are rejected because
|
|
||||||
fragmented-element reconstruction is not implemented.
|
fragmented-element reconstruction is not implemented.
|
||||||
|
|
||||||
## Rendering and links
|
## Display and export budgets
|
||||||
|
|
||||||
DTO strings are rendered as React text nodes. Notebook HTML, active SVG,
|
Parser DTOs are projected through a smaller page-display budget before React
|
||||||
scripts, attachment payloads, and automatic external navigation are not
|
creates nodes: 5,000 blocks, depth 64, 10,000 text runs, 500,000 displayed text
|
||||||
rendered. Link activation is not implemented. If links are added, they require
|
units, 2,000 table rows, 5,000 table cells, 256 columns, 10,000 ink strokes,
|
||||||
explicit user action, scheme validation, and safe navigation attributes.
|
50,000 ink points, and 4,096 characters per metadata label. Exceeding a display
|
||||||
|
budget produces an explicit truncation notice. Newlines remain inside text
|
||||||
|
nodes instead of multiplying DOM elements.
|
||||||
|
|
||||||
## Known gaps and roadmap
|
Navigation and inspectors separately expose at most 250 page links, 500
|
||||||
|
notebook nodes at depth 16, 200 package entries per page, and 100 diagnostics
|
||||||
|
per page. Titles, previews, package paths, diagnostic fields, and panel labels
|
||||||
|
are length-bounded; pagination/truncation remains explicit in the UI.
|
||||||
|
|
||||||
- There is no wall-clock deadline. Synchronous OneStore `.one` parsing cannot
|
Export planning independently permits at most 10,000 sections, 100,000 pages,
|
||||||
observe cooperative cancellation until control returns; terminating the
|
1,000,000 blocks, depth 256, 100,000 diagnostics, 8,000,000 text units, and
|
||||||
worker is the current hard stop.
|
500,000 ink points. One resource and all resources are capped at 64 MiB; one
|
||||||
- The package flow holds the source, decompressed folder buffers, extracted
|
standalone output or all uncompressed static-ZIP members are capped at 128 MiB.
|
||||||
entry slices, and parsed DTOs in memory at overlapping times. The byte/count
|
Planning accounts for metadata and projected UTF-8 output before serialization,
|
||||||
limits bound these individually but do not guarantee a low peak heap.
|
then verifies actual encoded/member sizes. Resource views remain zero-copy until
|
||||||
- Section text/page/diagnostic limits apply per contained section rather than
|
the bounded serializer needs bytes.
|
||||||
once to the complete package.
|
|
||||||
|
## Rendering, links, and downloads
|
||||||
|
|
||||||
|
DTO strings are rendered as React text nodes. Notebook HTML, scripts, active
|
||||||
|
SVG, and attachment payloads are never injected. Only parsed ink coordinates
|
||||||
|
generate application-owned SVG path attributes. Hyperlinks require an explicit
|
||||||
|
click, are limited to `http`, `https`, or `mailto`, and use
|
||||||
|
`rel="noopener noreferrer"`.
|
||||||
|
|
||||||
|
Automatic image requests carry a distinct preview intent. The worker rejects a
|
||||||
|
non-image, unapproved media type, unsafe dimensions, or oversized payload before
|
||||||
|
allocating/copying its bytes to the main thread. Approved image bytes may cross
|
||||||
|
for automatic preview; attachment bytes and rejected image bytes cross only
|
||||||
|
after the user presses a download button.
|
||||||
|
|
||||||
|
Static export HTML is inert, contains no script or external fetch, escapes all
|
||||||
|
text/attributes, embeds only images that pass the same inspector, and
|
||||||
|
neutralizes potentially active attachment suffixes. Exports represent the
|
||||||
|
supported reader model; they do not write OneNote files.
|
||||||
|
|
||||||
|
## Known gaps
|
||||||
|
|
||||||
|
- There is no wall-clock deadline. Synchronous OneStore graph parsing cannot
|
||||||
|
observe cancellation until control returns; terminating the worker is the
|
||||||
|
current hard stop.
|
||||||
|
- Package opening can hold source cabinets, decompressed logical folders,
|
||||||
|
extracted entry views, and parsed DTOs at overlapping times. Byte/count limits
|
||||||
|
bound them, but do not guarantee a low peak heap.
|
||||||
|
- Section content limits apply per contained section rather than once to the
|
||||||
|
complete `.onepkg`; cabinet/TOC limits are aggregate for the package set.
|
||||||
- CAB checksums detect accidental corruption but do not authenticate a package.
|
- CAB checksums detect accidental corruption but do not authenticate a package.
|
||||||
- Format coverage is narrow and has only the documented golden files. New
|
- Format coverage is limited to the documented golden files and structures.
|
||||||
producer/version claims require licensed regression fixtures and malformed
|
New producer/version claims require licensed regression fixtures and malformed
|
||||||
variants.
|
variants.
|
||||||
- The worker boundary reduces UI impact but is not a substitute for browser and
|
- The worker boundary reduces UI impact but is not a substitute for browser and
|
||||||
operating-system isolation. Open especially sensitive files in a dedicated
|
operating-system isolation. Open especially sensitive files in a dedicated
|
||||||
browser profile if that risk matters.
|
browser profile if that risk matters.
|
||||||
|
|
||||||
Planned hardening includes an elapsed-time budget, cancellation checkpoints in
|
Planned hardening includes elapsed-time budgets, more cancellation checkpoints,
|
||||||
desktop OneStore graph traversal, aggregate package DTO/text budgets, lower
|
lower-peak-memory extraction, expanded malformed-input/fuzz corpora, fragmented
|
||||||
peak-memory extraction, expanded malformed-input/fuzz corpora, and additional
|
FSSHTTP reconstruction, and additional licensed OneNote producer fixtures.
|
||||||
licensed OneNote export fixtures.
|
|
||||||
|
|
||||||
## Fixtures and vulnerability reporting
|
## Fixtures and vulnerability reporting
|
||||||
|
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "onenote-tools",
|
"name": "onenote-tools",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "onenote-tools",
|
"name": "onenote-tools",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0 AND LGPL-2.1-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@add-ideas/toolbox-contract": "0.1.1",
|
"@add-ideas/toolbox-contract": "0.1.1",
|
||||||
"@add-ideas/toolbox-shell-react": "0.1.1",
|
"@add-ideas/toolbox-shell-react": "0.1.1",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "onenote-tools",
|
"name": "onenote-tools",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"description": "A local-first browser workspace for native OneNote parsing.",
|
"description": "A local-first browser reader and exporter for OneNote files.",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0 AND LGPL-2.1-only",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -3,11 +3,22 @@
|
|||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "de.add-ideas.onenote-tools",
|
"id": "de.add-ideas.onenote-tools",
|
||||||
"name": "OneNote Tools",
|
"name": "OneNote Tools",
|
||||||
"description": "Local-first reader for tested desktop revision-store .one sections and LZX .onepkg packages; other OneNote formats are not implemented.",
|
"description": "Local-first reader and exporter for tested .one and .onepkg variants, with notebook trees, rich content, and split CAB package support.",
|
||||||
"entry": "./",
|
"entry": "./",
|
||||||
"icon": "./favicon.svg",
|
"icon": "./favicon.svg",
|
||||||
"categories": ["documents", "onenote"],
|
"categories": ["documents", "onenote"],
|
||||||
"tags": ["local", "read-only", "one", "onepkg", "cab", "lzx"],
|
"tags": [
|
||||||
|
"local",
|
||||||
|
"read-only",
|
||||||
|
"one",
|
||||||
|
"onepkg",
|
||||||
|
"cab",
|
||||||
|
"lzx",
|
||||||
|
"mszip",
|
||||||
|
"quantum",
|
||||||
|
"fsshttp",
|
||||||
|
"export"
|
||||||
|
],
|
||||||
"integration": {
|
"integration": {
|
||||||
"contextVersion": 1,
|
"contextVersion": 1,
|
||||||
"launchModes": ["navigate", "new-tab"],
|
"launchModes": ["navigate", "new-tab"],
|
||||||
@@ -27,7 +38,7 @@
|
|||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"repository": "https://git.add-ideas.de/zemion/onenote-tools",
|
"repository": "https://git.add-ideas.de/zemion/onenote-tools",
|
||||||
"license": "MPL-2.0"
|
"license": "MPL-2.0 AND LGPL-2.1-only"
|
||||||
},
|
},
|
||||||
"version": "0.1.0"
|
"version": "0.2.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,20 +13,27 @@ export function HelpDialog({ onClose }: HelpDialogProps) {
|
|||||||
>
|
>
|
||||||
<h2 id="help-title">About OneNote Tools</h2>
|
<h2 id="help-title">About OneNote Tools</h2>
|
||||||
<p>
|
<p>
|
||||||
Read the tested desktop revision-store .one subset and single-cabinet
|
Open tested desktop and unfragmented FSSHTTPB OneNote sections or
|
||||||
LZX or uncompressed .onepkg packages with a native TypeScript parser.
|
complete single- and multi-cabinet .onepkg sets with a native
|
||||||
Unsupported content remains visible as diagnostics instead of being
|
TypeScript parser. For a split package, select its .onepkg and all
|
||||||
silently discarded.
|
linked .cab files together.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
FSSHTTP sections, MSZIP and Quantum packages, multi-cabinet archives,
|
Notebook trees, rich text, safe links, tables, PNG/JPEG images, ink,
|
||||||
notebook TOC ordering, visual fidelity, attachments, and export are
|
attachments, and local JSON, text, Markdown, HTML, or static ZIP
|
||||||
not supported in this release.
|
exports are supported within documented safety and format limits.
|
||||||
|
Encountered unsupported object kinds remain visible as diagnostics.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Nothing is uploaded, persisted, or sent to telemetry. Closing or
|
Fragmented FSSHTTPB data, equations, audio/video, exact OneNote page
|
||||||
clearing releases application references and terminates the worker;
|
placement, and untested producer variants remain unsupported. Exports
|
||||||
this is not a secure-erasure guarantee.
|
preserve readable content but do not create OneNote files.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nothing is uploaded or sent to telemetry, and the app stores no
|
||||||
|
notebook data unless you explicitly download a resource or create an
|
||||||
|
export. Closing or clearing releases application references and
|
||||||
|
terminates the worker; this is not a secure-erasure guarantee.
|
||||||
</p>
|
</p>
|
||||||
<button type="button" onClick={onClose}>
|
<button type="button" onClick={onClose}>
|
||||||
Close
|
Close
|
||||||
|
|||||||
@@ -529,6 +529,15 @@ p {
|
|||||||
background: #f5eff8;
|
background: #f5eff8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.render-limit-notice {
|
||||||
|
margin: 1rem 0 0;
|
||||||
|
border-left: 0.2rem solid #b18124;
|
||||||
|
padding: 0.7rem 0.85rem;
|
||||||
|
color: #66552f;
|
||||||
|
background: #fbf4e6;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
.package-inspector,
|
.package-inspector,
|
||||||
.diagnostics {
|
.diagnostics {
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
|
|||||||
@@ -1,11 +1,22 @@
|
|||||||
{
|
{
|
||||||
"id": "de.add-ideas.onenote-tools",
|
"id": "de.add-ideas.onenote-tools",
|
||||||
"name": "OneNote Tools",
|
"name": "OneNote Tools",
|
||||||
"description": "Local-first reader for tested desktop revision-store .one sections and LZX .onepkg packages; other OneNote formats are not implemented.",
|
"description": "Local-first reader and exporter for tested .one and .onepkg variants, with notebook trees, rich content, and split CAB package support.",
|
||||||
"entry": "./",
|
"entry": "./",
|
||||||
"icon": "./favicon.svg",
|
"icon": "./favicon.svg",
|
||||||
"categories": ["documents", "onenote"],
|
"categories": ["documents", "onenote"],
|
||||||
"tags": ["local", "read-only", "one", "onepkg", "cab", "lzx"],
|
"tags": [
|
||||||
|
"local",
|
||||||
|
"read-only",
|
||||||
|
"one",
|
||||||
|
"onepkg",
|
||||||
|
"cab",
|
||||||
|
"lzx",
|
||||||
|
"mszip",
|
||||||
|
"quantum",
|
||||||
|
"fsshttp",
|
||||||
|
"export"
|
||||||
|
],
|
||||||
"integration": {
|
"integration": {
|
||||||
"contextVersion": 1,
|
"contextVersion": 1,
|
||||||
"launchModes": ["navigate", "new-tab"],
|
"launchModes": ["navigate", "new-tab"],
|
||||||
@@ -25,6 +36,6 @@
|
|||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"repository": "https://git.add-ideas.de/zemion/onenote-tools",
|
"repository": "https://git.add-ideas.de/zemion/onenote-tools",
|
||||||
"license": "MPL-2.0"
|
"license": "MPL-2.0 AND LGPL-2.1-only"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ describe('toolbox manifest', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not advertise unimplemented format support', () => {
|
it('does not advertise unimplemented format support', () => {
|
||||||
expect(toolboxApp.description).toContain('not implemented');
|
expect(toolboxApp.description).toContain('tested');
|
||||||
|
expect(toolboxApp.description).not.toContain('all OneNote');
|
||||||
expect(toolboxApp.privacy).toEqual(
|
expect(toolboxApp.privacy).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
processing: 'local',
|
processing: 'local',
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export const APP_VERSION = '0.1.0';
|
export const APP_VERSION = '0.2.0';
|
||||||
|
|||||||
6
tests/fixtures/README.md
vendored
6
tests/fixtures/README.md
vendored
@@ -17,7 +17,8 @@ and does not change the underlying file's licence.
|
|||||||
`7c43e85e2169b4bc3236db73a24c8f20d5c284b74563c07baf1406887d20eb5e`.
|
`7c43e85e2169b4bc3236db73a24c8f20d5c284b74563c07baf1406887d20eb5e`.
|
||||||
- Golden expectation: desktop OneStore section with three pages — `Test`,
|
- Golden expectation: desktop OneStore section with three pages — `Test`,
|
||||||
`Another page`, and `Page 3` — plus readable text/timestamps and diagnostics
|
`Another page`, and `Page 3` — plus readable text/timestamps and diagnostics
|
||||||
for image, table, and ink content.
|
plus structured rich text, a PNG resource, a table, and 1,316 decoded ink
|
||||||
|
points across 11 ink blocks.
|
||||||
|
|
||||||
## `joplin-test.onepkg.base64`
|
## `joplin-test.onepkg.base64`
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ and does not change the underlying file's licence.
|
|||||||
and nested paths, five `.one` sections, and two `.onetoc2` entries.
|
and nested paths, five `.one` sections, and two `.onetoc2` entries.
|
||||||
- Parser expectation: all five sections parse, producing seven pages in total:
|
- Parser expectation: all five sections parse, producing seven pages in total:
|
||||||
`Page 1`, `Page 2`, `Test`, `Test page`, `Testing…`, `A test`, and
|
`Page 1`, `Page 2`, `Test`, `Test page`, `Testing…`, `A test`, and
|
||||||
`Tuesday, January 13, 2026`.
|
`Tuesday, January 13, 2026`; the contained TOCs provide interpreted notebook
|
||||||
|
ordering rather than normalized-path-only navigation.
|
||||||
|
|
||||||
Tests verify the package hash, all seven paths, the native `.one` magic for
|
Tests verify the package hash, all seven paths, the native `.one` magic for
|
||||||
every section, section parse statuses, and representative title/text output.
|
every section, section parse statuses, and representative title/text output.
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import { defineConfig } from 'vite';
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: './',
|
base: './',
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
build: {
|
||||||
|
// Baseline browsers support modulepreload natively. Avoid shipping Vite's
|
||||||
|
// injected runtime polyfill (and an otherwise unnecessary runtime notice).
|
||||||
|
modulePreload: { polyfill: false },
|
||||||
|
},
|
||||||
test: {
|
test: {
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
setupFiles: './src/test/setup.ts',
|
setupFiles: './src/test/setup.ts',
|
||||||
|
|||||||
Reference in New Issue
Block a user