feat: open FSSHTTP OneNote sections

This commit is contained in:
2026-07-22 19:26:08 +02:00
parent a7b1cd7d16
commit eb15fecb3f
12 changed files with 877 additions and 21 deletions

View File

@@ -26,6 +26,7 @@ import type {
ObjectSpace,
PropertyEntry,
StoreObject,
StoreObjectSpaceReference,
} from '../onestore/types.js';
import { exGuidKey } from '../onestore/types.js';
import { JCID, PROPERTY } from './constants.js';
@@ -55,7 +56,9 @@ export function buildSectionDto(
const root = store.rootObjectSpace;
const metadata = rootObject(root, 2, 'section metadata root');
assertJcid(metadata, JCID.SectionMetadata, 'SectionMetadata');
const displayName = optionalString(metadata, PROPERTY.SectionDisplayName);
const displayName = cleanMetadataString(
optionalString(metadata, PROPERTY.SectionDisplayName)
);
const section = rootObject(root, 1, 'section content root');
assertJcid(section, JCID.SectionNode, 'SectionNode');
@@ -69,14 +72,14 @@ export function buildSectionDto(
series,
PROPERTY.ChildGraphSpaceElementNodes
);
for (const pageSpaceId of pageSpaceIds) {
for (const pageSpaceReference of pageSpaceIds) {
context.currentPage = undefined;
const pageSpace = store.objectSpaces.get(exGuidKey(pageSpaceId));
const pageSpace = store.objectSpaces.get(pageSpaceReference.key);
if (!pageSpace) {
addDiagnostic(
context,
'MISSING_PAGE_SPACE',
`Page object space ${exGuidKey(pageSpaceId)} is missing`,
`Page object space ${pageSpaceReference.key} is missing`,
'PageSeriesNode'
);
continue;
@@ -99,7 +102,7 @@ export function buildSectionDto(
addDiagnostic(
context,
'PAGE_PARSE_FAILED',
`Could not parse page ${exGuidKey(pageSpaceId)}: ${message}`,
`Could not parse page ${pageSpaceReference.key}: ${message}`,
'Page',
'error'
);
@@ -116,7 +119,7 @@ export function buildSectionDto(
diagnostics,
parserInfo: {
implementation: 'typescript',
supportedVariant: 'desktop-revision-store',
supportedVariant: store.variant,
referenceRevision: 'onenote.rs@5138a39a3f4e72b840932f9872fecde52fa9da60',
},
};
@@ -398,13 +401,16 @@ function objectReferences(object: StoreObject, propertyId: number): ExGuid[] {
propertyId,
countObjectReferences
);
if (object.resolvedObjectIds) {
return resolvedReferenceSlice(object.resolvedObjectIds, offset, count);
}
return resolveReferenceSlice(object, object.props.objectIds, offset, count);
}
function objectSpaceReferences(
object: StoreObject,
propertyId: number
): ExGuid[] {
): StoreObjectSpaceReference[] {
const property = findProperty(object.props, propertyId);
if (!property) return [];
let count: number;
@@ -421,12 +427,15 @@ function objectSpaceReferences(
propertyId,
countObjectSpaceReferences
);
if (object.resolvedObjectSpaceIds) {
return resolvedReferenceSlice(object.resolvedObjectSpaceIds, offset, count);
}
return resolveReferenceSlice(
object,
object.props.objectSpaceIds,
offset,
count
);
).map((id) => ({ id, key: exGuidKey(id) }));
}
function resolveReferenceSlice(
@@ -447,6 +456,19 @@ function resolveReferenceSlice(
});
}
function resolvedReferenceSlice<T>(
ids: readonly T[],
offset: number,
count: number
): T[] {
if (offset + count > ids.length) {
throw new Error(
`Reference range ${offset}+${count} exceeds resolved stream length ${ids.length}`
);
}
return ids.slice(offset, offset + count);
}
function rootObject(
space: ObjectSpace,
role: number,
@@ -659,3 +681,8 @@ function addDiagnostic(
function stripOneExtension(filename: string): string {
return (filename.split(/[\\/]/).at(-1) ?? filename).replace(/\.one$/i, '');
}
function cleanMetadataString(value: string | undefined): string | undefined {
const result = value?.split('\0').join('').trim();
return result || undefined;
}