feat: add local OneNote and ONEPKG reader

This commit is contained in:
2026-07-22 17:06:03 +02:00
commit f581cbdced
93 changed files with 14949 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
import {
OneNoteParserError,
detectOneNoteFormat,
parseOneNoteSection,
} from '../src/onenote/index.js';
const fixture = Buffer.from(
readFileSync(
join(process.cwd(), 'tests/fixtures/onenote_desktop.one.b64'),
'utf8'
).replace(/\s/g, ''),
'base64'
);
describe('desktop OneStore section parser', () => {
it('parses the pinned Joplin golden file into serializable page text', () => {
expect(fixture).toHaveLength(34_904);
expect(createHash('sha256').update(fixture).digest('hex')).toBe(
'7c43e85e2169b4bc3236db73a24c8f20d5c284b74563c07baf1406887d20eb5e'
);
expect(detectOneNoteFormat(fixture).kind).toBe('desktop-one');
const parsed = parseOneNoteSection(fixture, {
sourceName: 'onenote_desktop.one',
});
expect(structuredClone(parsed)).toEqual(parsed);
expect(parsed.pages).toHaveLength(3);
expect(parsed.pages[0]).toMatchObject({
id: '{27CDD549-7E76-45B0-B18D-5A9BCF261CCB}',
title: 'Test',
createdAt: '2025-10-17T20:59:14.797Z',
updatedAt: '2025-10-17T21:38:35.000Z',
level: 1,
});
expect(parsed.pages[0]!.text).toContain('Test!');
expect(parsed.pages[0]!.text).toContain('3+3=6');
expect(parsed.pages[0]!.text).toContain(
'This notebook should have three pages.'
);
expect(parsed.pages[1]).toMatchObject({
id: '{A7185C1A-6895-48FA-B9DD-380B511D0F82}',
title: 'Another page',
createdAt: '2025-10-17T21:00:24.848Z',
updatedAt: '2025-10-17T21:00:57.000Z',
level: 1,
});
expect(parsed.pages[1]!.text).toContain('Testing!');
expect(parsed.pages[2]).toMatchObject({
id: '{1A5CF75B-BF4A-4F37-B48C-F5493F4ED828}',
title: 'Page 3',
createdAt: '2025-10-17T21:38:42.795Z',
updatedAt: '2025-10-17T21:38:49.000Z',
level: 1,
});
expect(parsed.pages[2]!.text).toContain(
'This page is nearly empty. It has a single text box and not much else.'
);
const codes = parsed.diagnostics.map(({ code }) => code);
expect(codes).toContain('UNSUPPORTED_IMAGE');
expect(codes).toContain('UNSUPPORTED_TABLE');
expect(codes).toContain('UNSUPPORTED_INK');
});
it('fails malformed input with a controlled parser error', () => {
expect(() => parseOneNoteSection(new Uint8Array(63))).toThrowError(
OneNoteParserError
);
});
});