@stll/folio-core 0.22.1 → 0.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/headless.d.ts +6 -6
- package/dist/ai-edits/headless.js +2 -2
- package/dist/content-controls/errors.d.ts +17 -17
- package/dist/content-controls/errors.js +3 -3
- package/dist/controller/layoutPipeline.js +28 -0
- package/dist/document-operations.d.ts +6 -6
- package/dist/document-operations.js +2 -2
- package/dist/docx/encryption/errors.d.ts +3 -3
- package/dist/docx/encryption/errors.js +1 -1
- package/dist/docx/ensureParaIds.d.ts +4 -4
- package/dist/docx/ensureParaIds.js +1 -1
- package/dist/docx/imageParser.js +6 -9
- package/dist/docx/metadataPrivacy.d.ts +6 -6
- package/dist/docx/metadataPrivacy.js +2 -2
- package/dist/docx/parser.d.ts +5 -5
- package/dist/docx/parser.js +1 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.d.ts +6 -6
- package/dist/docx/server/applyDocxXmlPatchProposal.js +2 -2
- package/dist/docx/server/boundedArchive.d.ts +4 -4
- package/dist/docx/server/boundedArchive.js +1 -1
- package/dist/docx/server/build.d.ts +5 -5
- package/dist/docx/server/build.js +1 -1
- package/dist/docx/server/createBilingualDocument.d.ts +3 -3
- package/dist/docx/server/createBilingualDocument.js +1 -1
- package/dist/docx/server/evaluateDocxXmlPatchProposal.d.ts +6 -6
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +2 -2
- package/dist/docx/server/inspectDocxPackage.d.ts +3 -3
- package/dist/docx/server/inspectDocxPackage.js +9 -8
- package/dist/docx/styleParser.js +16 -16
- package/dist/docx/xmlParser.d.ts +7 -3
- package/dist/docx/xmlParser.js +20 -7
- package/dist/docx/xmlResourceLimits.d.ts +4 -4
- package/dist/docx/xmlResourceLimits.js +1 -1
- package/dist/layout-engine/measure/font-metrics.worker.js +1 -1
- package/dist/layout-engine/measure/measureHelpers.d.ts +2 -1
- package/dist/layout-engine/measure/measureHelpers.js +5 -2
- package/dist/layout-engine/types.d.ts +6 -0
- package/dist/layout-painter/anchoredImagePosition.d.ts +2 -1
- package/dist/layout-painter/anchoredImagePosition.js +14 -6
- package/dist/layout-painter/renderPage.js +11 -1
- package/dist/layout-painter/renderParagraph.js +3 -4
- package/dist/prosemirror/attrs/index.js +6 -5
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.js +1 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +13 -3
- package/dist/prosemirror/conversion/toProseDoc.js +1 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +30 -3
- package/dist/prosemirror/extensions/marks/UnderlineExtension.js +9 -7
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +92 -16
- package/dist/prosemirror/plugins/selectionTracker.js +10 -5
- package/dist/prosemirror/schema/nodes.d.ts +1 -0
- package/dist/prosemirror/selectionMarks.d.ts +11 -0
- package/dist/prosemirror/selectionMarks.js +19 -0
- package/dist/prosemirror/selectionState.js +8 -20
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/redline.d.ts +4 -4
- package/dist/redline.js +1 -1
- package/dist/utils/formatToStyle.js +1 -1
- package/dist/version-comparison.d.ts +3 -3
- package/dist/version-comparison.js +1 -1
- package/package.json +3 -3
|
@@ -71,16 +71,16 @@ type FolioReviewedStory = {
|
|
|
71
71
|
text: string;
|
|
72
72
|
changes: FolioReviewChange[];
|
|
73
73
|
};
|
|
74
|
-
declare const UnsupportedFolioReviewedViewError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioReviewedViewError"
|
|
74
|
+
declare const UnsupportedFolioReviewedViewError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioReviewedViewError">;
|
|
75
|
+
declare class UnsupportedFolioReviewedViewError extends UnsupportedFolioReviewedViewError_base<{
|
|
75
76
|
message: string;
|
|
76
77
|
receivedView: unknown;
|
|
77
|
-
}
|
|
78
|
-
declare
|
|
79
|
-
declare
|
|
78
|
+
}> {}
|
|
79
|
+
declare const FolioDocumentStoryNotFoundError_base: import("better-result").TaggedErrorClass<"FolioDocumentStoryNotFoundError">;
|
|
80
|
+
declare class FolioDocumentStoryNotFoundError extends FolioDocumentStoryNotFoundError_base<{
|
|
80
81
|
message: string;
|
|
81
82
|
story: FolioEditableDocumentStoryHandle;
|
|
82
|
-
}
|
|
83
|
-
declare class FolioDocumentStoryNotFoundError extends FolioDocumentStoryNotFoundError_base {}
|
|
83
|
+
}> {}
|
|
84
84
|
type FolioApplyDocumentOperationsToStoryOptions = FolioApplyDocumentOperationsOptions & {
|
|
85
85
|
story: FolioEditableDocumentStoryHandle;
|
|
86
86
|
batch: FolioDocumentOperationBatch;
|
|
@@ -131,8 +131,8 @@ const FOLIO_REVIEWED_VIEWS = Object.freeze([
|
|
|
131
131
|
"final"
|
|
132
132
|
]);
|
|
133
133
|
const FOLIO_RESOLVED_REVIEWED_VIEWS = Object.freeze(["original", "final"]);
|
|
134
|
-
var UnsupportedFolioReviewedViewError = class extends TaggedError("UnsupportedFolioReviewedViewError")
|
|
135
|
-
var FolioDocumentStoryNotFoundError = class extends TaggedError("FolioDocumentStoryNotFoundError")
|
|
134
|
+
var UnsupportedFolioReviewedViewError = class extends TaggedError("UnsupportedFolioReviewedViewError") {};
|
|
135
|
+
var FolioDocumentStoryNotFoundError = class extends TaggedError("FolioDocumentStoryNotFoundError") {};
|
|
136
136
|
const MAIN_STORY = Object.freeze({ type: "main" });
|
|
137
137
|
const headerFooterStoryKey = ({ type, relationshipId }) => `${type}:${relationshipId}`;
|
|
138
138
|
const noteStoryKey = ({ type, noteId }) => `${type}:${noteId}`;
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
//#region src/content-controls/errors.d.ts
|
|
3
|
-
declare const ContentControlLockedError_base: import("better-result").TaggedErrorClass<"ContentControlLockedError"
|
|
4
|
-
message: string;
|
|
5
|
-
lock: NonNullable<document_d_exports.SdtProperties["lock"]>;
|
|
6
|
-
tag?: string;
|
|
7
|
-
alias?: string;
|
|
8
|
-
}>;
|
|
3
|
+
declare const ContentControlLockedError_base: import("better-result").TaggedErrorClass<"ContentControlLockedError">;
|
|
9
4
|
/**
|
|
10
5
|
* Refused because the target control's `w:lock` forbids the requested
|
|
11
6
|
* mutation. Caller can override with `{ force: true }` if they understand
|
|
12
7
|
* the consequences (overrides apply per call, not per document).
|
|
13
8
|
*/
|
|
14
|
-
declare class ContentControlLockedError extends ContentControlLockedError_base
|
|
15
|
-
declare const ContentControlBoundError_base: import("better-result").TaggedErrorClass<"ContentControlBoundError", {
|
|
9
|
+
declare class ContentControlLockedError extends ContentControlLockedError_base<{
|
|
16
10
|
message: string;
|
|
17
|
-
|
|
18
|
-
storeItemID?: string;
|
|
11
|
+
lock: NonNullable<document_d_exports.SdtProperties["lock"]>;
|
|
19
12
|
tag?: string;
|
|
20
13
|
alias?: string;
|
|
21
|
-
}
|
|
14
|
+
}> {}
|
|
15
|
+
declare const ContentControlBoundError_base: import("better-result").TaggedErrorClass<"ContentControlBoundError">;
|
|
22
16
|
/**
|
|
23
17
|
* Refused because the target control is bound to a `<w:dataBinding>`.
|
|
24
18
|
*
|
|
@@ -33,19 +27,25 @@ declare const ContentControlBoundError_base: import("better-result").TaggedError
|
|
|
33
27
|
* Reference: python-docx #965, Aspose forum thread on removing custom
|
|
34
28
|
* XML mapping before content updates.
|
|
35
29
|
*/
|
|
36
|
-
declare class ContentControlBoundError extends ContentControlBoundError_base
|
|
37
|
-
declare const ContentControlTypeError_base: import("better-result").TaggedErrorClass<"ContentControlTypeError", {
|
|
30
|
+
declare class ContentControlBoundError extends ContentControlBoundError_base<{
|
|
38
31
|
message: string;
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
xpath: string;
|
|
33
|
+
storeItemID?: string;
|
|
41
34
|
tag?: string;
|
|
42
35
|
alias?: string;
|
|
43
|
-
}
|
|
36
|
+
}> {}
|
|
37
|
+
declare const ContentControlTypeError_base: import("better-result").TaggedErrorClass<"ContentControlTypeError">;
|
|
44
38
|
/**
|
|
45
39
|
* Refused because the requested operation does not make sense for the
|
|
46
40
|
* control's type — e.g. setting free text on a checkbox, or unwrapping a
|
|
47
41
|
* `w15:repeatingSection` (which would orphan its row items).
|
|
48
42
|
*/
|
|
49
|
-
declare class ContentControlTypeError extends ContentControlTypeError_base
|
|
43
|
+
declare class ContentControlTypeError extends ContentControlTypeError_base<{
|
|
44
|
+
message: string;
|
|
45
|
+
sdtType: document_d_exports.SdtProperties["sdtType"];
|
|
46
|
+
reason: string;
|
|
47
|
+
tag?: string;
|
|
48
|
+
alias?: string;
|
|
49
|
+
}> {}
|
|
50
50
|
//#endregion
|
|
51
51
|
export { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError };
|
|
@@ -10,7 +10,7 @@ import { TaggedError } from "better-result";
|
|
|
10
10
|
* mutation. Caller can override with `{ force: true }` if they understand
|
|
11
11
|
* the consequences (overrides apply per call, not per document).
|
|
12
12
|
*/
|
|
13
|
-
var ContentControlLockedError = class extends TaggedError("ContentControlLockedError")
|
|
13
|
+
var ContentControlLockedError = class extends TaggedError("ContentControlLockedError") {};
|
|
14
14
|
/**
|
|
15
15
|
* Refused because the target control is bound to a `<w:dataBinding>`.
|
|
16
16
|
*
|
|
@@ -25,12 +25,12 @@ var ContentControlLockedError = class extends TaggedError("ContentControlLockedE
|
|
|
25
25
|
* Reference: python-docx #965, Aspose forum thread on removing custom
|
|
26
26
|
* XML mapping before content updates.
|
|
27
27
|
*/
|
|
28
|
-
var ContentControlBoundError = class extends TaggedError("ContentControlBoundError")
|
|
28
|
+
var ContentControlBoundError = class extends TaggedError("ContentControlBoundError") {};
|
|
29
29
|
/**
|
|
30
30
|
* Refused because the requested operation does not make sense for the
|
|
31
31
|
* control's type — e.g. setting free text on a checkbox, or unwrapping a
|
|
32
32
|
* `w15:repeatingSection` (which would orphan its row items).
|
|
33
33
|
*/
|
|
34
|
-
var ContentControlTypeError = class extends TaggedError("ContentControlTypeError")
|
|
34
|
+
var ContentControlTypeError = class extends TaggedError("ContentControlTypeError") {};
|
|
35
35
|
//#endregion
|
|
36
36
|
export { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError };
|
|
@@ -58,6 +58,29 @@ function bodyBlocksClearSectionHeaderFooter(blocks, { authoredMargins, sectionHe
|
|
|
58
58
|
});
|
|
59
59
|
return changed ? nextBlocks : blocks;
|
|
60
60
|
}
|
|
61
|
+
const arePageMarginsEqual = (left, right) => left.top === right.top && left.right === right.right && left.bottom === right.bottom && left.left === right.left && left.header === right.header && left.footer === right.footer;
|
|
62
|
+
const mirrorPageMarginsIfNeeded = (authoredMargins, pageNumber, mirrorMargins) => mirrorMargins && pageNumber % 2 === 0 ? {
|
|
63
|
+
...authoredMargins,
|
|
64
|
+
left: authoredMargins.right,
|
|
65
|
+
right: authoredMargins.left
|
|
66
|
+
} : authoredMargins;
|
|
67
|
+
function attachAuthoredMarginsToLayoutPages(layout, options) {
|
|
68
|
+
let changed = false;
|
|
69
|
+
const pages = layout.pages.map((page) => {
|
|
70
|
+
const sectionProperties = options.sectionPropertiesForMargins[page.sectionIndex ?? 0];
|
|
71
|
+
const authoredMargins = mirrorPageMarginsIfNeeded(sectionProperties ? getMargins(sectionProperties) : options.authoredMargins, page.number, options.mirrorMargins);
|
|
72
|
+
if (page.authoredMargins && arePageMarginsEqual(page.authoredMargins, authoredMargins)) return page;
|
|
73
|
+
changed = true;
|
|
74
|
+
return {
|
|
75
|
+
...page,
|
|
76
|
+
authoredMargins
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
return changed ? {
|
|
80
|
+
...layout,
|
|
81
|
+
pages
|
|
82
|
+
} : layout;
|
|
83
|
+
}
|
|
61
84
|
function runLayoutPipeline(deps, state, options = {}) {
|
|
62
85
|
const { contentWidth, columns, pageSize, margins, pageGap, showMarginGuides, marginGuideColor, syncCoordinator, headerContent, footerContent, firstPageHeaderContent, firstPageFooterContent, headerContentRId, footerContentRId, firstPageHeaderContentRId, firstPageFooterContentRId, sectionHeaderFooterRefs, theme: _theme, sectionProperties, document, defaultTabStop, mirrorMargins, styles, layout, hfPMs, painter, pagesContainer, session, renderHfFromContentOrPm, renderHeaderFooterContentByRId, documentFontsAreLoaded, buildFootnoteRenderItems, describeInvalidHighlightMarks, emptyTemplatePreviewEntries: EMPTY_TEMPLATE_PREVIEW_ENTRIES } = deps;
|
|
63
86
|
let outcome = {};
|
|
@@ -341,6 +364,11 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
341
364
|
};
|
|
342
365
|
let stabilizedFieldValues;
|
|
343
366
|
stabilizeFieldWidths();
|
|
367
|
+
newLayout = attachAuthoredMarginsToLayoutPages(newLayout, {
|
|
368
|
+
authoredMargins: margins,
|
|
369
|
+
mirrorMargins,
|
|
370
|
+
sectionPropertiesForMargins
|
|
371
|
+
});
|
|
344
372
|
const rebuildHeaderFooterForLayout = () => {
|
|
345
373
|
const seqValues = buildSeqValues(newBlocks);
|
|
346
374
|
const bookmarkTextInputs = stabilizedFieldValues === void 0 ? { seqValues } : {
|
|
@@ -42,17 +42,17 @@ type FolioDocumentOperationCapabilities = {
|
|
|
42
42
|
declare const getFolioDocumentOperationCapabilities: () => FolioDocumentOperationCapabilities;
|
|
43
43
|
declare const isFolioDocumentOperationModeSupported: (operationType: FolioDocumentOperationType, mode: FolioDocumentOperationMode) => boolean;
|
|
44
44
|
declare const isSupportedFolioDocumentOperationVersion: (value: unknown) => value is typeof FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION;
|
|
45
|
-
declare const UnsupportedFolioDocumentOperationVersionError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioDocumentOperationVersionError"
|
|
45
|
+
declare const UnsupportedFolioDocumentOperationVersionError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioDocumentOperationVersionError">;
|
|
46
|
+
declare class UnsupportedFolioDocumentOperationVersionError extends UnsupportedFolioDocumentOperationVersionError_base<{
|
|
46
47
|
message: string;
|
|
47
48
|
receivedVersion: unknown;
|
|
48
|
-
}
|
|
49
|
-
declare
|
|
50
|
-
declare
|
|
49
|
+
}> {}
|
|
50
|
+
declare const InvalidFolioDocumentOperationBatchError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocumentOperationBatchError">;
|
|
51
|
+
declare class InvalidFolioDocumentOperationBatchError extends InvalidFolioDocumentOperationBatchError_base<{
|
|
51
52
|
message: string;
|
|
52
53
|
path: string;
|
|
53
54
|
reason: string;
|
|
54
|
-
}
|
|
55
|
-
declare class InvalidFolioDocumentOperationBatchError extends InvalidFolioDocumentOperationBatchError_base {}
|
|
55
|
+
}> {}
|
|
56
56
|
declare const assertSupportedFolioDocumentOperationVersion: (value: unknown) => typeof FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION;
|
|
57
57
|
type FolioDocumentOperationBatch = {
|
|
58
58
|
readonly version: typeof FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION;
|
|
@@ -73,8 +73,8 @@ const isFolioDocumentOperationModeSupported = (operationType, mode) => {
|
|
|
73
73
|
return includesDocumentOperationMode(supportedModes, mode);
|
|
74
74
|
};
|
|
75
75
|
const isSupportedFolioDocumentOperationVersion = (value) => value === 1;
|
|
76
|
-
var UnsupportedFolioDocumentOperationVersionError = class extends TaggedError("UnsupportedFolioDocumentOperationVersionError")
|
|
77
|
-
var InvalidFolioDocumentOperationBatchError = class extends TaggedError("InvalidFolioDocumentOperationBatchError")
|
|
76
|
+
var UnsupportedFolioDocumentOperationVersionError = class extends TaggedError("UnsupportedFolioDocumentOperationVersionError") {};
|
|
77
|
+
var InvalidFolioDocumentOperationBatchError = class extends TaggedError("InvalidFolioDocumentOperationBatchError") {};
|
|
78
78
|
const assertSupportedFolioDocumentOperationVersion = (value) => {
|
|
79
79
|
if (isSupportedFolioDocumentOperationVersion(value)) return value;
|
|
80
80
|
throw new UnsupportedFolioDocumentOperationVersionError({
|
|
@@ -7,12 +7,12 @@ declare const DOCX_ENCRYPTION_ERROR_CODES: {
|
|
|
7
7
|
readonly DECRYPTION_FAILED: "DOCX_DECRYPTION_FAILED";
|
|
8
8
|
};
|
|
9
9
|
type DocxEncryptionErrorCode = (typeof DOCX_ENCRYPTION_ERROR_CODES)[keyof typeof DOCX_ENCRYPTION_ERROR_CODES];
|
|
10
|
-
declare const DocxEncryptionError_base: import("better-result").TaggedErrorClass<"DocxEncryptionError"
|
|
10
|
+
declare const DocxEncryptionError_base: import("better-result").TaggedErrorClass<"DocxEncryptionError">;
|
|
11
|
+
declare class DocxEncryptionError extends DocxEncryptionError_base<{
|
|
11
12
|
message: string;
|
|
12
13
|
code: DocxEncryptionErrorCode;
|
|
13
14
|
cause?: unknown;
|
|
14
|
-
}
|
|
15
|
-
declare class DocxEncryptionError extends DocxEncryptionError_base {}
|
|
15
|
+
}> {}
|
|
16
16
|
declare const isDocxEncryptionError: (error: unknown) => error is DocxEncryptionError;
|
|
17
17
|
//#endregion
|
|
18
18
|
export { DOCX_ENCRYPTION_ERROR_CODES, DocxEncryptionError, DocxEncryptionErrorCode, isDocxEncryptionError };
|
|
@@ -7,7 +7,7 @@ const DOCX_ENCRYPTION_ERROR_CODES = {
|
|
|
7
7
|
ENCRYPTION_UNSUPPORTED: "DOCX_ENCRYPTION_UNSUPPORTED",
|
|
8
8
|
DECRYPTION_FAILED: "DOCX_DECRYPTION_FAILED"
|
|
9
9
|
};
|
|
10
|
-
var DocxEncryptionError = class extends TaggedError("DocxEncryptionError")
|
|
10
|
+
var DocxEncryptionError = class extends TaggedError("DocxEncryptionError") {};
|
|
11
11
|
const isDocxEncryptionError = (error) => error instanceof DocxEncryptionError;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { DOCX_ENCRYPTION_ERROR_CODES, DocxEncryptionError, isDocxEncryptionError };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
//#region src/docx/ensureParaIds.d.ts
|
|
2
|
-
declare const EnsureParaIdsError_base: import("better-result").TaggedErrorClass<"EnsureParaIdsError"
|
|
2
|
+
declare const EnsureParaIdsError_base: import("better-result").TaggedErrorClass<"EnsureParaIdsError">;
|
|
3
|
+
/** A malformed or unsupported package prevented paragraph-ID normalization. */
|
|
4
|
+
declare class EnsureParaIdsError extends EnsureParaIdsError_base<{
|
|
3
5
|
message: string;
|
|
4
6
|
cause?: unknown;
|
|
5
|
-
}
|
|
6
|
-
/** A malformed or unsupported package prevented paragraph-ID normalization. */
|
|
7
|
-
declare class EnsureParaIdsError extends EnsureParaIdsError_base {}
|
|
7
|
+
}> {}
|
|
8
8
|
/** Counts and normalized bytes returned by {@link ensureParaIds}. */
|
|
9
9
|
type EnsureParaIdsResult = {
|
|
10
10
|
/** The normalized `.docx`; the input bytes verbatim when `alreadyComplete`. */
|
|
@@ -55,7 +55,7 @@ import JSZip from "jszip";
|
|
|
55
55
|
* explicitly allows signature invalidation after warning the user.
|
|
56
56
|
*/
|
|
57
57
|
/** A malformed or unsupported package prevented paragraph-ID normalization. */
|
|
58
|
-
var EnsureParaIdsError = class extends TaggedError("EnsureParaIdsError")
|
|
58
|
+
var EnsureParaIdsError = class extends TaggedError("EnsureParaIdsError") {};
|
|
59
59
|
const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
60
60
|
const MC_NAMESPACE_URI = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
61
61
|
const MC_IGNORABLE_W14 = "w14";
|
package/dist/docx/imageParser.js
CHANGED
|
@@ -4,7 +4,7 @@ import { sanitizeExternalUrl } from "../utils/urlSecurity.js";
|
|
|
4
4
|
import { WRAP_ELEMENT_NAMES, parsePositionH, parsePositionV, parseWrapElement } from "./drawingUtils.js";
|
|
5
5
|
import { resolveTarget } from "./relsParser.js";
|
|
6
6
|
import { isTextBoxDrawing } from "./textBoxParser.js";
|
|
7
|
-
import { findByFullName, findChild, getAttribute, getChildElements, parseNumericAttribute } from "./xmlParser.js";
|
|
7
|
+
import { findByFullName, findChild, getAttribute, getChildElements, parseNumericAttribute, parseOnOffValue } from "./xmlParser.js";
|
|
8
8
|
//#region src/docx/imageParser.ts
|
|
9
9
|
/**
|
|
10
10
|
* Convert rotation value (1/60000 of a degree) to degrees
|
|
@@ -74,7 +74,7 @@ function parseDocProps(docPr) {
|
|
|
74
74
|
const name = getAttribute(docPr, null, "name");
|
|
75
75
|
const descr = getAttribute(docPr, null, "descr");
|
|
76
76
|
const title = getAttribute(docPr, null, "title");
|
|
77
|
-
const decorative = getAttribute(docPr, null, "decorative") ===
|
|
77
|
+
const decorative = parseOnOffValue(getAttribute(docPr, null, "decorative")) === true;
|
|
78
78
|
const hlinkClickEl = findChild(docPr, "a", "hlinkClick");
|
|
79
79
|
const hlinkRId = hlinkClickEl ? getAttribute(hlinkClickEl, "r", "id") : null;
|
|
80
80
|
return {
|
|
@@ -92,8 +92,8 @@ function parseDocProps(docPr) {
|
|
|
92
92
|
function parseTransform(xfrm) {
|
|
93
93
|
if (!xfrm) return;
|
|
94
94
|
const rot = getAttribute(xfrm, null, "rot");
|
|
95
|
-
const flipH = getAttribute(xfrm, null, "flipH") ===
|
|
96
|
-
const flipV = getAttribute(xfrm, null, "flipV") ===
|
|
95
|
+
const flipH = parseOnOffValue(getAttribute(xfrm, null, "flipH")) === true;
|
|
96
|
+
const flipV = parseOnOffValue(getAttribute(xfrm, null, "flipV")) === true;
|
|
97
97
|
const rotation = rotToDegrees(rot);
|
|
98
98
|
if (rotation === void 0 && !flipH && !flipV) return;
|
|
99
99
|
const transform = {};
|
|
@@ -155,10 +155,7 @@ function parseImageCrop(blipFill) {
|
|
|
155
155
|
* spec-defined default.
|
|
156
156
|
*/
|
|
157
157
|
function parseOnOffAttr(element, name) {
|
|
158
|
-
|
|
159
|
-
if (raw === null) return;
|
|
160
|
-
if (raw === "1" || raw === "true" || raw === "on") return true;
|
|
161
|
-
if (raw === "0" || raw === "false" || raw === "off") return false;
|
|
158
|
+
return parseOnOffValue(getAttribute(element, null, name));
|
|
162
159
|
}
|
|
163
160
|
/**
|
|
164
161
|
* Parse `<a:alphaModFix amt="..."/>` inside the `a:blip` element. The
|
|
@@ -358,7 +355,7 @@ function parseAnchor(anchorEl, rels, media) {
|
|
|
358
355
|
const size = parseExtent(findByFullName(anchorEl, "wp:extent"));
|
|
359
356
|
const padding = parseEffectExtent(findByFullName(anchorEl, "wp:effectExtent"));
|
|
360
357
|
const props = parseDocProps(findByFullName(anchorEl, "wp:docPr"));
|
|
361
|
-
const behindDoc = getAttribute(anchorEl, null, "behindDoc") ===
|
|
358
|
+
const behindDoc = parseOnOffValue(getAttribute(anchorEl, null, "behindDoc")) === true;
|
|
362
359
|
const layoutInCell = parseOnOffAttr(anchorEl, "layoutInCell");
|
|
363
360
|
const allowOverlap = parseOnOffAttr(anchorEl, "allowOverlap");
|
|
364
361
|
const anchorDistT = parseNumericAttribute(anchorEl, null, "distT");
|
|
@@ -15,17 +15,17 @@ type RewriteDocxMetadataPrivacyResult = {
|
|
|
15
15
|
buffer: ArrayBuffer;
|
|
16
16
|
privacyReport: FolioDocumentPrivacyReport;
|
|
17
17
|
};
|
|
18
|
-
declare const InvalidFolioDocumentPrivacyOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocumentPrivacyOptionsError"
|
|
18
|
+
declare const InvalidFolioDocumentPrivacyOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocumentPrivacyOptionsError">;
|
|
19
|
+
declare class InvalidFolioDocumentPrivacyOptionsError extends InvalidFolioDocumentPrivacyOptionsError_base<{
|
|
19
20
|
message: string;
|
|
20
21
|
receivedValue: unknown;
|
|
21
|
-
}
|
|
22
|
-
declare
|
|
23
|
-
declare
|
|
22
|
+
}> {}
|
|
23
|
+
declare const FolioDocumentPrivacyArchiveError_base: import("better-result").TaggedErrorClass<"FolioDocumentPrivacyArchiveError">;
|
|
24
|
+
declare class FolioDocumentPrivacyArchiveError extends FolioDocumentPrivacyArchiveError_base<{
|
|
24
25
|
message: string;
|
|
25
26
|
reason: "input-too-large" | "load-failed" | "too-many-entries" | "core-properties-too-large";
|
|
26
27
|
cause?: unknown;
|
|
27
|
-
}
|
|
28
|
-
declare class FolioDocumentPrivacyArchiveError extends FolioDocumentPrivacyArchiveError_base {}
|
|
28
|
+
}> {}
|
|
29
29
|
declare const PRIVATE_METADATA_PROPERTIES_BY_TRANSFORM: {
|
|
30
30
|
readonly "remove-attribution": readonly ["creator", "lastModifiedBy"];
|
|
31
31
|
readonly "remove-timestamps": readonly ["created", "modified"];
|
|
@@ -20,8 +20,8 @@ const FOLIO_DOCUMENT_PRIVACY_TRANSFORMS = Object.freeze([
|
|
|
20
20
|
"remove-descriptive-metadata"
|
|
21
21
|
]);
|
|
22
22
|
const isFolioDocumentPrivacyTransform = (value) => FOLIO_DOCUMENT_PRIVACY_TRANSFORMS.some((transform) => transform === value);
|
|
23
|
-
var InvalidFolioDocumentPrivacyOptionsError = class extends TaggedError("InvalidFolioDocumentPrivacyOptionsError")
|
|
24
|
-
var FolioDocumentPrivacyArchiveError = class extends TaggedError("FolioDocumentPrivacyArchiveError")
|
|
23
|
+
var InvalidFolioDocumentPrivacyOptionsError = class extends TaggedError("InvalidFolioDocumentPrivacyOptionsError") {};
|
|
24
|
+
var FolioDocumentPrivacyArchiveError = class extends TaggedError("FolioDocumentPrivacyArchiveError") {};
|
|
25
25
|
const PRIVATE_METADATA_PROPERTIES_BY_TRANSFORM = {
|
|
26
26
|
"remove-attribution": ["creator", "lastModifiedBy"],
|
|
27
27
|
"remove-timestamps": ["created", "modified"],
|
package/dist/docx/parser.d.ts
CHANGED
|
@@ -45,13 +45,13 @@ type ParseOptions = {
|
|
|
45
45
|
* @throws {Error} if parsing fails
|
|
46
46
|
*/
|
|
47
47
|
declare function parseDocx(input: DocxInput, options?: ParseOptions): Promise<document_d_exports.Document>;
|
|
48
|
-
declare const DocxParseError_base: import("better-result").TaggedErrorClass<"DocxParseError"
|
|
49
|
-
message: string;
|
|
50
|
-
cause?: unknown;
|
|
51
|
-
}>;
|
|
48
|
+
declare const DocxParseError_base: import("better-result").TaggedErrorClass<"DocxParseError">;
|
|
52
49
|
/** DOCX parsing failure: malformed package, unsupported feature, or
|
|
53
50
|
* upstream parser exception. Wraps the original cause for diagnostics. */
|
|
54
|
-
declare class DocxParseError extends DocxParseError_base
|
|
51
|
+
declare class DocxParseError extends DocxParseError_base<{
|
|
52
|
+
message: string;
|
|
53
|
+
cause?: unknown;
|
|
54
|
+
}> {}
|
|
55
55
|
/**
|
|
56
56
|
* Quick parse - parse a DOCX without font loading
|
|
57
57
|
* Useful for quick content extraction or when fonts aren't needed
|
package/dist/docx/parser.js
CHANGED
|
@@ -228,7 +228,7 @@ async function parseDocx(input, options = {}) {
|
|
|
228
228
|
}
|
|
229
229
|
/** DOCX parsing failure: malformed package, unsupported feature, or
|
|
230
230
|
* upstream parser exception. Wraps the original cause for diagnostics. */
|
|
231
|
-
var DocxParseError = class extends TaggedError("DocxParseError")
|
|
231
|
+
var DocxParseError = class extends TaggedError("DocxParseError") {};
|
|
232
232
|
/**
|
|
233
233
|
* Build media file map from raw content and relationships
|
|
234
234
|
*/
|
|
@@ -62,18 +62,18 @@ type FolioDocxXmlPatchApplication = {
|
|
|
62
62
|
readonly receipt: FolioDocxXmlPatchApplicationReceipt;
|
|
63
63
|
readonly bytes: Uint8Array;
|
|
64
64
|
};
|
|
65
|
-
declare const UnsupportedFolioDocxXmlPatchApplicationProfileError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioDocxXmlPatchApplicationProfileError"
|
|
65
|
+
declare const UnsupportedFolioDocxXmlPatchApplicationProfileError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioDocxXmlPatchApplicationProfileError">;
|
|
66
|
+
declare class UnsupportedFolioDocxXmlPatchApplicationProfileError extends UnsupportedFolioDocxXmlPatchApplicationProfileError_base<{
|
|
66
67
|
message: string;
|
|
67
68
|
profile: unknown;
|
|
68
|
-
}
|
|
69
|
-
declare
|
|
70
|
-
declare
|
|
69
|
+
}> {}
|
|
70
|
+
declare const FolioDocxXmlPatchApplicationError_base: import("better-result").TaggedErrorClass<"FolioDocxXmlPatchApplicationError">;
|
|
71
|
+
declare class FolioDocxXmlPatchApplicationError extends FolioDocxXmlPatchApplicationError_base<{
|
|
71
72
|
message: string;
|
|
72
73
|
stage: "verify" | "load" | "replace" | "generate";
|
|
73
74
|
part?: string;
|
|
74
75
|
cause?: unknown;
|
|
75
|
-
}
|
|
76
|
-
declare class FolioDocxXmlPatchApplicationError extends FolioDocxXmlPatchApplicationError_base {}
|
|
76
|
+
}> {}
|
|
77
77
|
/** Apply a guarded XML proposal and return output only after full profile validation. */
|
|
78
78
|
declare const applyDocxXmlPatchProposal: ({ bytes, proposal: rawProposal, allowedParts, validationProfile, archive, limits }: ApplyDocxXmlPatchProposalArgs) => Promise<FolioDocxXmlPatchApplication>;
|
|
79
79
|
//#endregion
|
|
@@ -8,8 +8,8 @@ import { createHash } from "node:crypto";
|
|
|
8
8
|
const FOLIO_DOCX_XML_PATCH_APPLICATION_VERSION = 1;
|
|
9
9
|
const FOLIO_DOCX_XML_PATCH_APPLICATION_PROFILE = "folio-xml-patch-application-v1";
|
|
10
10
|
const isConformantReport = (report) => report.status === "conformant";
|
|
11
|
-
var UnsupportedFolioDocxXmlPatchApplicationProfileError = class extends TaggedError("UnsupportedFolioDocxXmlPatchApplicationProfileError")
|
|
12
|
-
var FolioDocxXmlPatchApplicationError = class extends TaggedError("FolioDocxXmlPatchApplicationError")
|
|
11
|
+
var UnsupportedFolioDocxXmlPatchApplicationProfileError = class extends TaggedError("UnsupportedFolioDocxXmlPatchApplicationProfileError") {};
|
|
12
|
+
var FolioDocxXmlPatchApplicationError = class extends TaggedError("FolioDocxXmlPatchApplicationError") {};
|
|
13
13
|
const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
14
14
|
const snapshotInput = (bytes) => Uint8Array.from(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes));
|
|
15
15
|
const snapshotArchiveOptions = (archive) => {
|
|
@@ -3,13 +3,13 @@ declare const DOCX_MAX_ENTRY_BYTES: number;
|
|
|
3
3
|
declare const DOCX_MAX_TOTAL_BYTES: number;
|
|
4
4
|
declare const DOCX_MAX_ENTRIES = 4096;
|
|
5
5
|
declare const DOCX_MAX_INPUT_BYTES: number;
|
|
6
|
-
declare const DocxArchiveError_base: import("better-result").TaggedErrorClass<"DocxArchiveError"
|
|
6
|
+
declare const DocxArchiveError_base: import("better-result").TaggedErrorClass<"DocxArchiveError">;
|
|
7
|
+
/** Error raised when a DOCX archive cannot be loaded within configured limits. */
|
|
8
|
+
declare class DocxArchiveError extends DocxArchiveError_base<{
|
|
7
9
|
message: string;
|
|
8
10
|
reason: "load-failed" | "input-too-large" | "too-many-entries" | "entry-too-large" | "total-too-large" | "invalid-options";
|
|
9
11
|
cause?: unknown;
|
|
10
|
-
}
|
|
11
|
-
/** Error raised when a DOCX archive cannot be loaded within configured limits. */
|
|
12
|
-
declare class DocxArchiveError extends DocxArchiveError_base {}
|
|
12
|
+
}> {}
|
|
13
13
|
type DocxArchiveOptions = {
|
|
14
14
|
maxInputBytes?: number;
|
|
15
15
|
maxEntryBytes?: number;
|
|
@@ -6,7 +6,7 @@ const DOCX_MAX_TOTAL_BYTES = 256 * 1024 * 1024;
|
|
|
6
6
|
const DOCX_MAX_ENTRIES = 4096;
|
|
7
7
|
const DOCX_MAX_INPUT_BYTES = 50 * 1024 * 1024;
|
|
8
8
|
/** Error raised when a DOCX archive cannot be loaded within configured limits. */
|
|
9
|
-
var DocxArchiveError = class extends TaggedError("DocxArchiveError")
|
|
9
|
+
var DocxArchiveError = class extends TaggedError("DocxArchiveError") {};
|
|
10
10
|
const collectStream = async ({ stream, maxEntryBytes, remainingBytes, maxTotalBytes, path }) => await new Promise((resolve, reject) => {
|
|
11
11
|
const chunks = [];
|
|
12
12
|
let entryBytes = 0;
|
|
@@ -5,16 +5,16 @@ import { ParagraphFormatting, TextFormatting } from "../../types/formatting.js";
|
|
|
5
5
|
//#region src/docx/server/build.d.ts
|
|
6
6
|
declare const HEADING_LEVELS: readonly [1, 2, 3, 4, 5, 6];
|
|
7
7
|
type HeadingLevel = (typeof HEADING_LEVELS)[number];
|
|
8
|
-
declare const InvalidFolioReportBuilderOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioReportBuilderOptionsError"
|
|
9
|
-
message: string;
|
|
10
|
-
path: string;
|
|
11
|
-
}>;
|
|
8
|
+
declare const InvalidFolioReportBuilderOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioReportBuilderOptionsError">;
|
|
12
9
|
/**
|
|
13
10
|
* A builder received a value outside the model's domain (a zero `gridSpan`,
|
|
14
11
|
* a negative column width, a reversed TOC range). Thrown at the boundary so
|
|
15
12
|
* the invalid value never reaches the serializer.
|
|
16
13
|
*/
|
|
17
|
-
declare class InvalidFolioReportBuilderOptionsError extends InvalidFolioReportBuilderOptionsError_base
|
|
14
|
+
declare class InvalidFolioReportBuilderOptionsError extends InvalidFolioReportBuilderOptionsError_base<{
|
|
15
|
+
message: string;
|
|
16
|
+
path: string;
|
|
17
|
+
}> {}
|
|
18
18
|
declare const run: (text: string, formatting?: TextFormatting) => Run;
|
|
19
19
|
declare const paragraph: (content: string | ParagraphContent[], formatting?: ParagraphFormatting) => Paragraph;
|
|
20
20
|
type HeadingOptions = {
|
|
@@ -34,7 +34,7 @@ const TOC_LEVEL_MAX = 9;
|
|
|
34
34
|
* a negative column width, a reversed TOC range). Thrown at the boundary so
|
|
35
35
|
* the invalid value never reaches the serializer.
|
|
36
36
|
*/
|
|
37
|
-
var InvalidFolioReportBuilderOptionsError = class extends TaggedError("InvalidFolioReportBuilderOptionsError")
|
|
37
|
+
var InvalidFolioReportBuilderOptionsError = class extends TaggedError("InvalidFolioReportBuilderOptionsError") {};
|
|
38
38
|
const assertPositiveInteger = (value, path) => {
|
|
39
39
|
if (!Number.isInteger(value) || value < 1) throw new InvalidFolioReportBuilderOptionsError({
|
|
40
40
|
message: `${path} must be a positive integer, got ${String(value)}`,
|
|
@@ -44,11 +44,11 @@ type CreateBilingualDocumentResult = {
|
|
|
44
44
|
/** Non-fatal fidelity notes (for example an unresolvable numbering style link). */
|
|
45
45
|
warnings: string[];
|
|
46
46
|
};
|
|
47
|
-
declare const InvalidBilingualDocumentOptionsError_base: import("better-result").TaggedErrorClass<"InvalidBilingualDocumentOptionsError"
|
|
47
|
+
declare const InvalidBilingualDocumentOptionsError_base: import("better-result").TaggedErrorClass<"InvalidBilingualDocumentOptionsError">;
|
|
48
|
+
declare class InvalidBilingualDocumentOptionsError extends InvalidBilingualDocumentOptionsError_base<{
|
|
48
49
|
message: string;
|
|
49
50
|
option: "targetStyleSuffix";
|
|
50
|
-
}
|
|
51
|
-
declare class InvalidBilingualDocumentOptionsError extends InvalidBilingualDocumentOptionsError_base {}
|
|
51
|
+
}> {}
|
|
52
52
|
declare function createBilingualDocument(source: document_d_exports.Document, options: CreateBilingualDocumentOptions): CreateBilingualDocumentResult;
|
|
53
53
|
/**
|
|
54
54
|
* Re-derive the row manifest from a document produced by
|
|
@@ -19,7 +19,7 @@ import { TaggedError } from "better-result";
|
|
|
19
19
|
* and read once, and its labels are translated inline rather than duplicated.
|
|
20
20
|
*/
|
|
21
21
|
const STYLE_SUFFIX_PATTERN = /^[A-Za-z0-9-]+$/u;
|
|
22
|
-
var InvalidBilingualDocumentOptionsError = class extends TaggedError("InvalidBilingualDocumentOptionsError")
|
|
22
|
+
var InvalidBilingualDocumentOptionsError = class extends TaggedError("InvalidBilingualDocumentOptionsError") {};
|
|
23
23
|
const FULL_WIDTH_PCT = 5e3;
|
|
24
24
|
const HALF_WIDTH_PCT = 2500;
|
|
25
25
|
const A4_TEXT_WIDTH_TWIPS = 9072;
|
|
@@ -62,17 +62,17 @@ type FolioDocxXmlPatchProposalEvaluation = {
|
|
|
62
62
|
readonly replacements: readonly [];
|
|
63
63
|
readonly limits: Required<FolioDocxXmlPatchProposalLimits>;
|
|
64
64
|
};
|
|
65
|
-
declare const InvalidFolioDocxXmlPatchProposalError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocxXmlPatchProposalError"
|
|
65
|
+
declare const InvalidFolioDocxXmlPatchProposalError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocxXmlPatchProposalError">;
|
|
66
|
+
declare class InvalidFolioDocxXmlPatchProposalError extends InvalidFolioDocxXmlPatchProposalError_base<{
|
|
66
67
|
message: string;
|
|
67
68
|
path: string;
|
|
68
69
|
reason: string;
|
|
69
|
-
}
|
|
70
|
-
declare
|
|
71
|
-
declare
|
|
70
|
+
}> {}
|
|
71
|
+
declare const InvalidFolioDocxXmlPatchProposalOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioDocxXmlPatchProposalOptionsError">;
|
|
72
|
+
declare class InvalidFolioDocxXmlPatchProposalOptionsError extends InvalidFolioDocxXmlPatchProposalOptionsError_base<{
|
|
72
73
|
message: string;
|
|
73
74
|
path: string;
|
|
74
|
-
}
|
|
75
|
-
declare class InvalidFolioDocxXmlPatchProposalOptionsError extends InvalidFolioDocxXmlPatchProposalOptionsError_base {}
|
|
75
|
+
}> {}
|
|
76
76
|
declare const parseFolioDocxXmlPatchProposal: (value: unknown) => FolioDocxXmlPatchProposal;
|
|
77
77
|
declare const evaluateDocxXmlPatchProposal: ({ bytes, proposal: rawProposal, allowedParts, archive, limits: rawLimits }: EvaluateDocxXmlPatchProposalArgs) => Promise<FolioDocxXmlPatchProposalEvaluation>;
|
|
78
78
|
//#endregion
|
|
@@ -29,8 +29,8 @@ const FOLIO_DOCX_XML_PATCH_PROPOSAL_ISSUE_CODES = Object.freeze([
|
|
|
29
29
|
"base-hash-mismatch",
|
|
30
30
|
"package-inspection-failed"
|
|
31
31
|
]);
|
|
32
|
-
var InvalidFolioDocxXmlPatchProposalError = class extends TaggedError("InvalidFolioDocxXmlPatchProposalError")
|
|
33
|
-
var InvalidFolioDocxXmlPatchProposalOptionsError = class extends TaggedError("InvalidFolioDocxXmlPatchProposalOptionsError")
|
|
32
|
+
var InvalidFolioDocxXmlPatchProposalError = class extends TaggedError("InvalidFolioDocxXmlPatchProposalError") {};
|
|
33
|
+
var InvalidFolioDocxXmlPatchProposalOptionsError = class extends TaggedError("InvalidFolioDocxXmlPatchProposalOptionsError") {};
|
|
34
34
|
const SHA256_PATTERN = /^[\da-f]{64}$/u;
|
|
35
35
|
const XML_DECLARED_ENCODING_PATTERN = /^\uFEFF?<\?xml[^>]*\bencoding\s*=\s*["']([^"']+)["'][^>]*\?>/iu;
|
|
36
36
|
const MAX_PACKAGE_PATH_CODE_UNITS = 1024;
|
|
@@ -8,13 +8,13 @@ declare const FOLIO_DOCX_PACKAGE_INSPECTION_DEFAULTS: Readonly<{
|
|
|
8
8
|
}>;
|
|
9
9
|
declare const FOLIO_DOCX_PACKAGE_INSPECTION_ERROR_CODES: readonly ["invalid-limits", "too-many-xml-parts", "duplicate-xml-part", "part-not-found", "part-not-xml", "xml-part-too-large", "xml-total-too-large", "xml-decode-failed"];
|
|
10
10
|
type FolioDocxPackageInspectionErrorCode = (typeof FOLIO_DOCX_PACKAGE_INSPECTION_ERROR_CODES)[number];
|
|
11
|
-
declare const FolioDocxPackageInspectionError_base: import("better-result").TaggedErrorClass<"FolioDocxPackageInspectionError"
|
|
11
|
+
declare const FolioDocxPackageInspectionError_base: import("better-result").TaggedErrorClass<"FolioDocxPackageInspectionError">;
|
|
12
|
+
declare class FolioDocxPackageInspectionError extends FolioDocxPackageInspectionError_base<{
|
|
12
13
|
message: string;
|
|
13
14
|
code: FolioDocxPackageInspectionErrorCode;
|
|
14
15
|
part?: string;
|
|
15
16
|
cause?: unknown;
|
|
16
|
-
}
|
|
17
|
-
declare class FolioDocxPackageInspectionError extends FolioDocxPackageInspectionError_base {}
|
|
17
|
+
}> {}
|
|
18
18
|
type FolioDocxPackageInspectionLimits = {
|
|
19
19
|
readonly maxXmlParts?: number;
|
|
20
20
|
readonly maxXmlPartBytes?: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAttributeAnyPrefix, getLocalName, parseXmlDocument } from "../xmlParser.js";
|
|
2
2
|
import { DocxArchiveError, loadDocxArchive } from "./boundedArchive.js";
|
|
3
|
-
import { TaggedError } from "better-result";
|
|
3
|
+
import { Result, TaggedError } from "better-result";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
//#region src/docx/server/inspectDocxPackage.ts
|
|
6
6
|
const FOLIO_DOCX_PACKAGE_INSPECTION_VERSION = 1;
|
|
@@ -19,7 +19,7 @@ const FOLIO_DOCX_PACKAGE_INSPECTION_ERROR_CODES = Object.freeze([
|
|
|
19
19
|
"xml-total-too-large",
|
|
20
20
|
"xml-decode-failed"
|
|
21
21
|
]);
|
|
22
|
-
var FolioDocxPackageInspectionError = class extends TaggedError("FolioDocxPackageInspectionError")
|
|
22
|
+
var FolioDocxPackageInspectionError = class extends TaggedError("FolioDocxPackageInspectionError") {};
|
|
23
23
|
const CONTENT_TYPES_PATH = "[Content_Types].xml";
|
|
24
24
|
const CONTENT_TYPES_READ_LIMIT = 4 * 1024 * 1024;
|
|
25
25
|
const XML_PATH_PATTERN = /(?:\.xml|\.rels)$/iu;
|
|
@@ -32,16 +32,17 @@ const decodeXml = (bytes, part) => {
|
|
|
32
32
|
let encoding = "utf-8";
|
|
33
33
|
if (bytes.length >= 2 && (bytes[0] === 255 && bytes[1] === 254 || bytes[0] === 60 && bytes[1] === 0)) encoding = "utf-16le";
|
|
34
34
|
else if (bytes.length >= 2 && (bytes[0] === 254 && bytes[1] === 255 || bytes[0] === 0 && bytes[1] === 60)) encoding = "utf-16be";
|
|
35
|
-
try
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
throw new FolioDocxPackageInspectionError({
|
|
35
|
+
const decoded = Result.try({
|
|
36
|
+
try: () => new TextDecoder(encoding, { fatal: true }).decode(bytes),
|
|
37
|
+
catch: (cause) => new FolioDocxPackageInspectionError({
|
|
39
38
|
message: `Failed to decode XML package part "${part}"`,
|
|
40
39
|
code: "xml-decode-failed",
|
|
41
40
|
part,
|
|
42
41
|
cause
|
|
43
|
-
})
|
|
44
|
-
}
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
if (decoded.isOk()) return decoded.value;
|
|
45
|
+
throw decoded.error;
|
|
45
46
|
};
|
|
46
47
|
const parseContentTypes = (xml) => {
|
|
47
48
|
const declarations = {
|