@stll/folio-core 0.56.0 → 0.57.0
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/apply.js +45 -14
- package/dist/ai-edits/batch-claims.d.ts +3 -1
- package/dist/ai-edits/batch-claims.js +25 -1
- package/dist/ai-edits/table-row-column-mutations.js +17 -3
- package/dist/ai-suggestions/apply.js +20 -1
- package/dist/compare/inline-atoms.js +40 -16
- package/dist/compare/inline-provenance.js +12 -5
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/controller/canonicalClipboard.js +7 -1
- package/dist/controller/canonicalComments.d.ts +41 -0
- package/dist/controller/canonicalComments.js +152 -0
- package/dist/controller/canonicalComposition.d.ts +4 -0
- package/dist/controller/canonicalComposition.js +43 -11
- package/dist/controller/canonicalInlineProjection.d.ts +6 -1
- package/dist/controller/canonicalInlineProjection.js +86 -3
- package/dist/controller/canonicalInput.js +10 -1
- package/dist/controller/canonicalInputTimer.d.ts +10 -1
- package/dist/controller/canonicalInputTimer.js +24 -1
- package/dist/controller/canonicalPublicOperations.d.ts +2 -2
- package/dist/controller/canonicalPublicOperations.js +107 -15
- package/dist/controller/canonicalSelection.d.ts +18 -0
- package/dist/controller/canonicalSelection.js +32 -0
- package/dist/controller/canonicalSession.d.ts +3 -0
- package/dist/controller/canonicalSession.js +58 -24
- package/dist/controller/canonicalStoryEditor.d.ts +2 -0
- package/dist/controller/canonicalStoryEditor.js +20 -0
- package/dist/controller/folioEditor.js +13 -0
- package/dist/controller/headerFooterEditorManager.d.ts +1 -1
- package/dist/controller/headerFooterEditorManager.js +25 -11
- package/dist/controller/hiddenEditorApi.d.ts +13 -2
- package/dist/controller/hiddenEditorApi.js +4 -0
- package/dist/controller/hiddenEditorManager.d.ts +3 -1
- package/dist/controller/hiddenEditorManager.js +166 -13
- package/dist/controller/noteEditorManager.d.ts +1 -1
- package/dist/controller/noteEditorManager.js +28 -13
- package/dist/docx/builtInStyles.js +13 -6
- package/dist/docx/containerChildren.gen.d.ts +3 -1
- package/dist/docx/containerChildren.gen.js +33 -1
- package/dist/docx/fieldParser.js +14 -2
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/hyperlinkParser.js +20 -1
- package/dist/docx/inlineWrapperContent.d.ts +4 -4
- package/dist/docx/inlineWrapperContent.js +4 -4
- package/dist/docx/linkedSdtPreservation.d.ts +10 -0
- package/dist/docx/linkedSdtPreservation.js +37 -0
- package/dist/docx/paragraphParser.js +88 -67
- package/dist/docx/paragraphPropertySource.d.ts +22 -1
- package/dist/docx/paragraphPropertySource.js +107 -1
- package/dist/docx/preservedRunContent.js +2 -1
- package/dist/docx/relsParser.js +26 -2
- package/dist/docx/rezip.js +9 -6
- package/dist/docx/selectiveSave.js +10 -8
- package/dist/docx/serializer/commentSerializer.d.ts +4 -1
- package/dist/docx/serializer/commentSerializer.js +7 -3
- package/dist/docx/serializer/paragraphSerializer.js +207 -94
- package/dist/docx/server/materializeYjsDocx.js +14 -6
- package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
- package/dist/i18n/messages/ar.gen.js +4 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
- package/dist/i18n/messages/catalogs.gen.js +68 -0
- package/dist/i18n/messages/cs.gen.js +4 -0
- package/dist/i18n/messages/de.gen.js +4 -0
- package/dist/i18n/messages/en.gen.js +4 -0
- package/dist/i18n/messages/es.gen.js +4 -0
- package/dist/i18n/messages/et.gen.js +4 -0
- package/dist/i18n/messages/fr.gen.js +4 -0
- package/dist/i18n/messages/he.gen.js +4 -0
- package/dist/i18n/messages/hi.gen.js +4 -0
- package/dist/i18n/messages/hu.gen.js +4 -0
- package/dist/i18n/messages/lt.gen.js +4 -0
- package/dist/i18n/messages/lv.gen.js +4 -0
- package/dist/i18n/messages/messages.gen.d.ts +4 -0
- package/dist/i18n/messages/pl.gen.js +4 -0
- package/dist/i18n/messages/pt-BR.gen.js +4 -0
- package/dist/i18n/messages/sk.gen.js +4 -0
- package/dist/i18n/messages/tr.gen.js +4 -0
- package/dist/i18n/messages/zh-CN.gen.js +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/revisionResolutionInline.js +25 -3
- package/dist/markdown/renderRuns.js +1 -11
- package/dist/panel-layout.d.ts +11 -9
- package/dist/panel-layout.js +13 -9
- package/dist/prosemirror/addTrackedDeletionMark.d.ts +18 -0
- package/dist/prosemirror/addTrackedDeletionMark.js +87 -0
- package/dist/prosemirror/attrs/index.js +5 -0
- package/dist/prosemirror/commands/comments.js +60 -35
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -6
- package/dist/prosemirror/commands/resolveParagraphProperties.js +22 -13
- package/dist/prosemirror/commentOps.js +15 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +22 -3
- package/dist/prosemirror/conversion/toProseDoc.js +119 -18
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +22 -5
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +74 -25
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +11 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +22 -14
- package/dist/prosemirror/extensions/marks/markUtils.js +8 -7
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +5 -2
- package/dist/prosemirror/fieldRepresentation.d.ts +8 -0
- package/dist/prosemirror/fieldRepresentation.js +18 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +13 -1
- package/dist/prosemirror/hyperlinkRemoval.js +28 -9
- package/dist/prosemirror/listNumbering.js +11 -5
- package/dist/prosemirror/noteReferenceOccurrenceId.d.ts +5 -0
- package/dist/prosemirror/noteReferenceOccurrenceId.js +5 -0
- package/dist/prosemirror/noteReferenceOccurrences.d.ts +21 -0
- package/dist/prosemirror/noteReferenceOccurrences.js +185 -0
- package/dist/prosemirror/noteReferenceReview.js +14 -1
- package/dist/prosemirror/plugins/documentStyles.d.ts +4 -1
- package/dist/prosemirror/plugins/documentStyles.js +17 -10
- package/dist/prosemirror/plugins/suggestionMode.js +47 -49
- package/dist/prosemirror/preservedXmlReview.d.ts +6 -0
- package/dist/prosemirror/preservedXmlReview.js +35 -0
- package/dist/prosemirror/runFormattingFromMarks.js +2 -2
- package/dist/prosemirror/runFormattingReconciliation.js +5 -4
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +8 -1
- package/dist/prosemirror/runPropertyChangeResolution.js +24 -2
- package/dist/prosemirror/runStyleFormatting.d.ts +3 -1
- package/dist/prosemirror/runStyleFormatting.js +3 -1
- package/dist/prosemirror/schema/marks.d.ts +1 -0
- package/dist/prosemirror/schema/nodes.d.ts +2 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +4 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +15 -15
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +69 -28
- package/dist/prosemirror/textInput.d.ts +5 -1
- package/dist/prosemirror/textInput.js +3 -3
- package/dist/prosemirror/trackedRevisionPath.d.ts +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +39 -1
- package/dist/prosemirror/validation.js +3 -5
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +9 -3
- package/dist/prosemirror/yjsDocumentMetadata.js +37 -8
- package/dist/types/canonicalCapabilities.d.ts +6 -20
- package/dist/types/canonicalCapabilities.js +6 -20
- package/dist/types/canonicalComments.d.ts +51 -0
- package/dist/types/canonicalComments.js +0 -0
- package/dist/types/canonicalSections.d.ts +12 -0
- package/dist/types/canonicalSections.js +0 -0
- package/dist/utils/headingCollector.js +45 -4
- package/dist/utils/outlineDepth.d.ts +9 -0
- package/dist/utils/outlineDepth.js +9 -0
- package/package.json +2 -2
|
@@ -19,7 +19,7 @@ const dispatchEditorTextInput = (view, input) => {
|
|
|
19
19
|
};
|
|
20
20
|
if (!view.someProp("handleTextInput", (handler) => handler(view, from, to, text, defaultTransaction))) view.dispatch(defaultTransaction());
|
|
21
21
|
};
|
|
22
|
-
const
|
|
22
|
+
const getEditorInputTargetRange = (view, event) => {
|
|
23
23
|
if (typeof event.getTargetRanges !== "function") return null;
|
|
24
24
|
const ranges = event.getTargetRanges();
|
|
25
25
|
if (ranges.length !== 1) return null;
|
|
@@ -39,7 +39,7 @@ const handleEditorBeforeInput = (view, event) => {
|
|
|
39
39
|
if (event.inputType !== "insertText" && event.inputType !== "insertReplacementText") return false;
|
|
40
40
|
const text = event.data ?? (event.dataTransfer?.types.includes("text/plain") ? event.dataTransfer.getData("text/plain") : null);
|
|
41
41
|
if (text === null) return false;
|
|
42
|
-
const selection = event.inputType === "insertReplacementText" ?
|
|
42
|
+
const selection = event.inputType === "insertReplacementText" ? getEditorInputTargetRange(view, event) : view.state.selection;
|
|
43
43
|
if (!selection) return false;
|
|
44
44
|
event.preventDefault();
|
|
45
45
|
dispatchEditorTextInput(view, {
|
|
@@ -78,4 +78,4 @@ const createTextInputPlugin = () => {
|
|
|
78
78
|
} } });
|
|
79
79
|
};
|
|
80
80
|
//#endregion
|
|
81
|
-
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, handleEditorBeforeInput };
|
|
81
|
+
export { afterNativeCompositionFlush, createTextInputPlugin, dispatchEditorTextInput, getEditorInputTargetRange, handleEditorBeforeInput };
|
|
@@ -13,5 +13,9 @@ type EnclosingInsertionAncestorsOptions = {
|
|
|
13
13
|
};
|
|
14
14
|
/** The deletion's ancestor path, with the insertion it sits in as the outermost layer. */
|
|
15
15
|
declare const enclosingInsertionAncestors: ({ insertionMark, ancestors, node }: EnclosingInsertionAncestorsOptions) => readonly TrackedRevisionAncestor[];
|
|
16
|
+
/** The authored revision layers already owned by a mark, outermost first. */
|
|
17
|
+
declare const trackedRevisionPathOf: (mark: Mark) => readonly TrackedRevisionAncestor[];
|
|
18
|
+
/** Promote a surviving existing layer; callers cannot supply a fresh identity. */
|
|
19
|
+
declare const retainedTrackedRevisionMark: (mark: Mark, keepLayer: (layer: TrackedRevisionAncestor) => boolean) => Mark | null;
|
|
16
20
|
//#endregion
|
|
17
|
-
export { enclosingInsertionAncestors, inlineWrapperStackOf, trackedRevisionLayerOf };
|
|
21
|
+
export { enclosingInsertionAncestors, inlineWrapperStackOf, retainedTrackedRevisionMark, trackedRevisionLayerOf, trackedRevisionPathOf };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { expectInlineWrapperMarkAttrs, expectTrackedChangeMarkAttrs } from "./attrs/index.js";
|
|
2
2
|
import { INLINE_WRAPPER_MARK_NAME } from "./extensions/marks/InlineWrapperExtension.js";
|
|
3
|
+
import { panic } from "better-result";
|
|
3
4
|
//#region src/prosemirror/trackedRevisionPath.ts
|
|
4
5
|
/** The wrappers `node` sits inside, outermost first; empty when it sits in none. */
|
|
5
6
|
const inlineWrapperStackOf = (node) => {
|
|
@@ -29,5 +30,42 @@ const enclosingInsertionAncestors = ({ insertionMark, ancestors, node }) => {
|
|
|
29
30
|
if (ancestors.some(({ revisionId }) => revisionId === attrs.revisionId)) return ancestors;
|
|
30
31
|
return [trackedRevisionLayerOf(insertionMark, node), ...ancestors];
|
|
31
32
|
};
|
|
33
|
+
const revisionLayerOf = (mark) => {
|
|
34
|
+
const attrs = expectTrackedChangeMarkAttrs(mark);
|
|
35
|
+
let type;
|
|
36
|
+
if (mark.type.name === "insertion") type = attrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
37
|
+
else type = attrs.moveKind === "moveFrom" ? "moveFrom" : "deletion";
|
|
38
|
+
return {
|
|
39
|
+
type,
|
|
40
|
+
revisionId: attrs.revisionId,
|
|
41
|
+
author: attrs.author,
|
|
42
|
+
...attrs.date ? { date: attrs.date } : {},
|
|
43
|
+
...attrs.utcDate ? { utcDate: attrs.utcDate } : {},
|
|
44
|
+
...attrs.initials ? { initials: attrs.initials } : {},
|
|
45
|
+
outerWrapperCount: attrs._docxOuterWrapperCount ?? 0
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/** The authored revision layers already owned by a mark, outermost first. */
|
|
49
|
+
const trackedRevisionPathOf = (mark) => [...expectTrackedChangeMarkAttrs(mark)._docxRevisionAncestors ?? [], revisionLayerOf(mark)];
|
|
50
|
+
/** Promote a surviving existing layer; callers cannot supply a fresh identity. */
|
|
51
|
+
const retainedTrackedRevisionMark = (mark, keepLayer) => {
|
|
52
|
+
const remaining = trackedRevisionPathOf(mark).filter(keepLayer);
|
|
53
|
+
const active = remaining.at(-1);
|
|
54
|
+
if (!active) return null;
|
|
55
|
+
const name = active.type === "insertion" || active.type === "moveTo" ? "insertion" : "deletion";
|
|
56
|
+
const type = mark.type.schema.marks[name];
|
|
57
|
+
if (!type) panic("A nested tracked revision has no editor mark type");
|
|
58
|
+
return type.create({
|
|
59
|
+
revisionId: active.revisionId,
|
|
60
|
+
author: active.author,
|
|
61
|
+
date: active.date ?? null,
|
|
62
|
+
utcDate: active.utcDate ?? null,
|
|
63
|
+
initials: active.initials ?? null,
|
|
64
|
+
moveKind: active.type === "moveTo" || active.type === "moveFrom" ? active.type : null,
|
|
65
|
+
_historicalFormatting: active.type === "deletion" || active.type === "moveFrom" ? true : null,
|
|
66
|
+
_docxOuterWrapperCount: active.outerWrapperCount,
|
|
67
|
+
_docxRevisionAncestors: remaining.length > 1 ? remaining.slice(0, -1) : null
|
|
68
|
+
});
|
|
69
|
+
};
|
|
32
70
|
//#endregion
|
|
33
|
-
export { enclosingInsertionAncestors, inlineWrapperStackOf, trackedRevisionLayerOf };
|
|
71
|
+
export { enclosingInsertionAncestors, inlineWrapperStackOf, retainedTrackedRevisionMark, trackedRevisionLayerOf, trackedRevisionPathOf };
|
|
@@ -2,7 +2,7 @@ import { readNoteMarkerAttrs } from "../internal/noteMarkerAttrs.js";
|
|
|
2
2
|
import { readBlockCustomXmlAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readInlineWrapperMarkAttrs, readLanguageMarkAttrs, readMathAttrs, readPageBreakRunAttrs, readParagraphAttrs, readPreservedBlockAttrs, readPreservedXmlAttrs, readRunFormattingOverrideMarkAttrs, readRunIdentityMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs } from "./attrs/index.js";
|
|
3
3
|
import { readBookmarkBoundaryAttrs } from "./bookmarkBoundaryAttrs.js";
|
|
4
4
|
import { readCommentReferenceAttrs } from "./commentReferenceAttrs.js";
|
|
5
|
-
import {
|
|
5
|
+
import { fieldRequiresStructuredContent } from "./fieldRepresentation.js";
|
|
6
6
|
import { readMoveRangeBoundaryAttrs } from "./moveRangeBoundaryAttrs.js";
|
|
7
7
|
import { readRangeAnchorAttrs } from "./rangeAnchorAttrs.js";
|
|
8
8
|
import { readTextBoxAnchorAttrs } from "./textBoxAnchorAttrs.js";
|
|
@@ -249,8 +249,6 @@ const validateNodeAttrs = (node, path, issues) => {
|
|
|
249
249
|
if (fieldAttrs.ok) {
|
|
250
250
|
const hasStructuredHyperlink = node.content.content.some((child) => child.marks.some((mark) => mark.type.name === "hyperlink"));
|
|
251
251
|
const hasPageBreakCarrier = node.content.content.some((child) => child.type.name === "pageBreakRun");
|
|
252
|
-
const hasPreservedCapture = node.content.content.some((child) => child.type.name === "preservedXml");
|
|
253
|
-
const hasInlineWrapper = node.content.content.some((child) => child.marks.some((mark) => mark.type.name === INLINE_WRAPPER_MARK_NAME));
|
|
254
252
|
if (fieldAttrs.value.fieldKind === "complex" && !hasPageBreakCarrier) issues.push({
|
|
255
253
|
path: `${path}.content`,
|
|
256
254
|
message: "Complex fields cannot contain structured result children."
|
|
@@ -259,9 +257,9 @@ const validateNodeAttrs = (node, path, issues) => {
|
|
|
259
257
|
path: `${path}.content`,
|
|
260
258
|
message: "Complex field results cannot contain hyperlink content."
|
|
261
259
|
});
|
|
262
|
-
else if (!
|
|
260
|
+
else if (!fieldRequiresStructuredContent(node.content.content)) issues.push({
|
|
263
261
|
path: `${path}.content`,
|
|
264
|
-
message: "Structured simple fields require
|
|
262
|
+
message: "Structured simple fields require non-text, hyperlink, wrapper or tracked content."
|
|
265
263
|
});
|
|
266
264
|
node.forEach((child, _offset, index) => {
|
|
267
265
|
const childPath = `${path}.content[${index}]`;
|
|
@@ -8,14 +8,20 @@ import * as Y from "yjs";
|
|
|
8
8
|
*/
|
|
9
9
|
type AttrSchemaMigrationStep = (fragment: Y.XmlFragment) => number;
|
|
10
10
|
/** Every attr-schema version this build reads, oldest first, with no gaps. */
|
|
11
|
-
declare const FOLIO_YJS_ATTR_SCHEMA_VERSIONS: readonly [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
11
|
+
declare const FOLIO_YJS_ATTR_SCHEMA_VERSIONS: readonly [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
12
12
|
/** An attr-schema version this build can read. */
|
|
13
13
|
type FolioYjsAttrSchemaVersion = (typeof FOLIO_YJS_ATTR_SCHEMA_VERSIONS)[number];
|
|
14
14
|
/**
|
|
15
15
|
* The attr-schema version this build writes. Derived against the migration map
|
|
16
16
|
* so the constant and the map cannot disagree.
|
|
17
17
|
*/
|
|
18
|
-
declare const FOLIO_YJS_ATTR_SCHEMA_VERSION =
|
|
18
|
+
declare const FOLIO_YJS_ATTR_SCHEMA_VERSION = 12;
|
|
19
|
+
declare const FolioYjsNoteReferenceSchemaError_base: import("better-result").TaggedErrorClass<"FolioYjsNoteReferenceSchemaError">;
|
|
20
|
+
declare class FolioYjsNoteReferenceSchemaError extends FolioYjsNoteReferenceSchemaError_base<{
|
|
21
|
+
message: string;
|
|
22
|
+
schemaVersion: FolioYjsAttrSchemaVersion;
|
|
23
|
+
requiredSchemaVersion: FolioYjsAttrSchemaVersion;
|
|
24
|
+
}> {}
|
|
19
25
|
/**
|
|
20
26
|
* The steps that carry a snapshot written under `fromVersion` up to
|
|
21
27
|
* {@link FOLIO_YJS_ATTR_SCHEMA_VERSION}, in order. Empty when the snapshot is
|
|
@@ -70,4 +76,4 @@ declare const writeYjsDocumentMetadata: (ydoc: Y.Doc, document: Node) => void;
|
|
|
70
76
|
declare const readYjsParagraphSourceContract: (ydoc: Y.Doc) => string | null;
|
|
71
77
|
declare const withParagraphSourceContract: (document: Node, contract: string) => Node;
|
|
72
78
|
//#endregion
|
|
73
|
-
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
79
|
+
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersion, FolioYjsAttrSchemaVersionError, FolioYjsNoteReferenceSchemaError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, getProseDocumentParagraphPropertySourceContract } from "../docx/paragraphPropertySource.js";
|
|
2
|
+
import { isNoteReferenceOccurrenceId } from "./noteReferenceOccurrenceId.js";
|
|
2
3
|
import { mintSectionProperties, parseSectionBreakType } from "./sectionCarrier.js";
|
|
3
4
|
import { Result, TaggedError, panic } from "better-result";
|
|
4
5
|
import { DRAWING_RAW_XML_MODES, outlineLevelFromStatedValue, paragraphNumberingFromSlots } from "@stll/docx-core/model";
|
|
@@ -473,7 +474,8 @@ const FOLIO_YJS_ATTR_SCHEMA_VERSIONS = [
|
|
|
473
474
|
8,
|
|
474
475
|
9,
|
|
475
476
|
10,
|
|
476
|
-
11
|
|
477
|
+
11,
|
|
478
|
+
12
|
|
477
479
|
];
|
|
478
480
|
/**
|
|
479
481
|
* The one place a persisted attr-shape change is decided.
|
|
@@ -497,13 +499,39 @@ const ATTR_SCHEMA_MIGRATIONS = {
|
|
|
497
499
|
8: mintSectionPropertiesFromBreakType,
|
|
498
500
|
9: dropUnstatedPlaceholderFlags,
|
|
499
501
|
10: renamePageBreakRunOwnerMarkAttr,
|
|
500
|
-
11:
|
|
502
|
+
11: stampMarkerOnly,
|
|
503
|
+
12: "current"
|
|
501
504
|
};
|
|
502
505
|
/**
|
|
503
506
|
* The attr-schema version this build writes. Derived against the migration map
|
|
504
507
|
* so the constant and the map cannot disagree.
|
|
505
508
|
*/
|
|
506
|
-
const FOLIO_YJS_ATTR_SCHEMA_VERSION =
|
|
509
|
+
const FOLIO_YJS_ATTR_SCHEMA_VERSION = 12;
|
|
510
|
+
var FolioYjsNoteReferenceSchemaError = class extends TaggedError("FolioYjsNoteReferenceSchemaError") {};
|
|
511
|
+
/** Check before any migration mutates the snapshot or any PM builder can drop text. */
|
|
512
|
+
const requireNoteOccurrenceAttribution = (fragment, schemaVersion) => {
|
|
513
|
+
const visit = (node) => {
|
|
514
|
+
for (const child of node.toArray()) {
|
|
515
|
+
if (typeof child === "string") continue;
|
|
516
|
+
if (!isXmlText(child)) {
|
|
517
|
+
if ("toArray" in child) visit(child);
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
for (const op of child.toDelta()) {
|
|
521
|
+
const attributes = op.attributes;
|
|
522
|
+
if (!isRecord(attributes) || attributes["footnoteRef"] == null) continue;
|
|
523
|
+
const reference = attributes["footnoteRef"];
|
|
524
|
+
if (isRecord(reference) && isNoteReferenceOccurrenceId(reference["occurrenceId"])) continue;
|
|
525
|
+
throw new FolioYjsNoteReferenceSchemaError({
|
|
526
|
+
schemaVersion,
|
|
527
|
+
requiredSchemaVersion: 12,
|
|
528
|
+
message: `Yjs schema ${schemaVersion} has unattributed note references; schema 12 requires occurrence identities. Rebuild the collaboration state from the saved DOCX.`
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
visit(fragment);
|
|
534
|
+
};
|
|
507
535
|
/**
|
|
508
536
|
* The steps that carry a snapshot written under `fromVersion` up to
|
|
509
537
|
* {@link FOLIO_YJS_ATTR_SCHEMA_VERSION}, in order. Empty when the snapshot is
|
|
@@ -528,7 +556,8 @@ const attrSchemaMigrationSteps = (fromVersion) => FOLIO_YJS_ATTR_SCHEMA_VERSIONS
|
|
|
528
556
|
* Returns how many elements the steps rewrote.
|
|
529
557
|
*/
|
|
530
558
|
const applyAttrSchemaMigrations = (ydoc, fragment, fromVersion) => {
|
|
531
|
-
|
|
559
|
+
requireNoteOccurrenceAttribution(fragment, fromVersion);
|
|
560
|
+
if (fromVersion === 12) return 0;
|
|
532
561
|
let rewritten = 0;
|
|
533
562
|
ydoc.transact(() => {
|
|
534
563
|
for (const step of attrSchemaMigrationSteps(fromVersion)) rewritten += step(fragment);
|
|
@@ -538,7 +567,7 @@ const applyAttrSchemaMigrations = (ydoc, fragment, fromVersion) => {
|
|
|
538
567
|
};
|
|
539
568
|
/** Raised when a snapshot's attr-schema marker is ahead of the running code. */
|
|
540
569
|
var FolioYjsAttrSchemaVersionError = class extends TaggedError("FolioYjsAttrSchemaVersionError") {};
|
|
541
|
-
const isReadableVersion = (marker) => typeof marker === "number" && Number.isInteger(marker) && marker >= 0 && marker <=
|
|
570
|
+
const isReadableVersion = (marker) => typeof marker === "number" && Number.isInteger(marker) && marker >= 0 && marker <= 12;
|
|
542
571
|
/**
|
|
543
572
|
* The attr-schema version a collaboration document was written under.
|
|
544
573
|
*
|
|
@@ -556,7 +585,7 @@ const readYjsAttrSchemaVersion = (ydoc) => {
|
|
|
556
585
|
return Result.err(new FolioYjsAttrSchemaVersionError({
|
|
557
586
|
marker,
|
|
558
587
|
message: "The collaboration snapshot was written by a newer Folio attr schema than this build reads.",
|
|
559
|
-
supportedVersion:
|
|
588
|
+
supportedVersion: 12
|
|
560
589
|
}));
|
|
561
590
|
};
|
|
562
591
|
const proseDocumentParagraphSourceContract = (document) => {
|
|
@@ -564,7 +593,7 @@ const proseDocumentParagraphSourceContract = (document) => {
|
|
|
564
593
|
};
|
|
565
594
|
/** Stamp the attr-schema version of the build that wrote the current fragment. */
|
|
566
595
|
const writeYjsAttrSchemaVersion = (ydoc) => {
|
|
567
|
-
ydoc.getMap(FOLIO_YJS_METADATA_MAP_NAME).set(ATTR_SCHEMA_VERSION_KEY,
|
|
596
|
+
ydoc.getMap(FOLIO_YJS_METADATA_MAP_NAME).set(ATTR_SCHEMA_VERSION_KEY, 12);
|
|
568
597
|
};
|
|
569
598
|
/**
|
|
570
599
|
* Write both metadata bindings for a freshly seeded collaboration document.
|
|
@@ -589,4 +618,4 @@ const withParagraphSourceContract = (document, contract) => {
|
|
|
589
618
|
}, document.content, document.marks);
|
|
590
619
|
};
|
|
591
620
|
//#endregion
|
|
592
|
-
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
621
|
+
export { FOLIO_YJS_ATTR_SCHEMA_VERSION, FolioYjsAttrSchemaVersionError, FolioYjsNoteReferenceSchemaError, applyAttrSchemaMigrations, attrSchemaMigrationSteps, proseDocumentParagraphSourceContract, readYjsAttrSchemaVersion, readYjsParagraphSourceContract, withParagraphSourceContract, writeYjsAttrSchemaVersion, writeYjsDocumentMetadata };
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
declare const CANONICAL_GAP: {
|
|
4
4
|
readonly authorityRouting: "authority-routing";
|
|
5
5
|
readonly commands: "command-descriptors";
|
|
6
|
-
readonly suggesting: "adapter-suggesting";
|
|
7
6
|
readonly trackedHyperlinkResolution: "tracked-hyperlink-resolution";
|
|
8
7
|
readonly comments: "comment-model-edits";
|
|
9
8
|
readonly modelEdits: "direct-model-edits";
|
|
10
9
|
readonly sectionProperties: "section-properties";
|
|
11
10
|
readonly watermark: "watermark-model-edits";
|
|
12
|
-
readonly secondaryStories: "secondary-story-routing";
|
|
13
11
|
readonly collaboration: "collaboration-session";
|
|
14
12
|
readonly dispatch: "unclassified-transactions";
|
|
15
13
|
readonly save: "pm-save-projection";
|
|
@@ -52,17 +50,11 @@ declare const CANONICAL_CAPABILITIES: {
|
|
|
52
50
|
readonly adapters: readonly ["react", "vue"];
|
|
53
51
|
readonly summary: "Hyperlink and TOC suggestions require serializable wrapper review provenance.";
|
|
54
52
|
};
|
|
55
|
-
readonly "adapter-suggesting": {
|
|
56
|
-
readonly owner: "adapters";
|
|
57
|
-
readonly kind: "refusal";
|
|
58
|
-
readonly adapters: readonly ["react", "vue"];
|
|
59
|
-
readonly summary: "Adapter suggesting controls and tracked secondary-story edits remain gated.";
|
|
60
|
-
};
|
|
61
53
|
readonly "comment-model-edits": {
|
|
62
54
|
readonly owner: "adapters";
|
|
63
|
-
readonly kind: "
|
|
55
|
+
readonly kind: "routing";
|
|
64
56
|
readonly adapters: readonly ["react", "vue"];
|
|
65
|
-
readonly summary: "
|
|
57
|
+
readonly summary: "Default sessions retain comment model edits; canonical comments use semantic operations.";
|
|
66
58
|
};
|
|
67
59
|
readonly "direct-model-edits": {
|
|
68
60
|
readonly owner: "adapters";
|
|
@@ -71,10 +63,10 @@ declare const CANONICAL_CAPABILITIES: {
|
|
|
71
63
|
readonly summary: "Direct model and pending-suggestion snapshots bypass the canonical journal.";
|
|
72
64
|
};
|
|
73
65
|
readonly "section-properties": {
|
|
74
|
-
readonly owner: "
|
|
66
|
+
readonly owner: "controller";
|
|
75
67
|
readonly kind: "routing";
|
|
76
68
|
readonly adapters: readonly ["react", "vue"];
|
|
77
|
-
readonly summary: "
|
|
69
|
+
readonly summary: "The shared controller journals section properties; default sessions keep model changes.";
|
|
78
70
|
};
|
|
79
71
|
readonly "watermark-model-edits": {
|
|
80
72
|
readonly owner: "adapters";
|
|
@@ -82,12 +74,6 @@ declare const CANONICAL_CAPABILITIES: {
|
|
|
82
74
|
readonly adapters: readonly ["vue"];
|
|
83
75
|
readonly summary: "Vue watermark mutations still change the model directly.";
|
|
84
76
|
};
|
|
85
|
-
readonly "secondary-story-routing": {
|
|
86
|
-
readonly owner: "controller";
|
|
87
|
-
readonly kind: "routing";
|
|
88
|
-
readonly adapters: readonly ["react", "vue"];
|
|
89
|
-
readonly summary: "Secondary-story creation, views and history still select their session authority.";
|
|
90
|
-
};
|
|
91
77
|
readonly "collaboration-session": {
|
|
92
78
|
readonly owner: "controller";
|
|
93
79
|
readonly kind: "refusal";
|
|
@@ -152,9 +138,9 @@ declare const CANONICAL_CAPABILITIES: {
|
|
|
152
138
|
readonly "publicOps.comments": {
|
|
153
139
|
readonly owner: "document-operations";
|
|
154
140
|
readonly defaultSessionMutation: "pm-public-operations";
|
|
155
|
-
readonly kind: "
|
|
141
|
+
readonly kind: "routing";
|
|
156
142
|
readonly adapters: readonly ["react", "vue"];
|
|
157
|
-
readonly summary: "
|
|
143
|
+
readonly summary: "Canonical public comments compile to semantic operations; default sessions retain PM comments.";
|
|
158
144
|
};
|
|
159
145
|
readonly "publicOps.suggestedMode": {
|
|
160
146
|
readonly owner: "document-operations";
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
const CANONICAL_GAP = {
|
|
4
4
|
authorityRouting: "authority-routing",
|
|
5
5
|
commands: "command-descriptors",
|
|
6
|
-
suggesting: "adapter-suggesting",
|
|
7
6
|
trackedHyperlinkResolution: "tracked-hyperlink-resolution",
|
|
8
7
|
comments: "comment-model-edits",
|
|
9
8
|
modelEdits: "direct-model-edits",
|
|
10
9
|
sectionProperties: "section-properties",
|
|
11
10
|
watermark: "watermark-model-edits",
|
|
12
|
-
secondaryStories: "secondary-story-routing",
|
|
13
11
|
collaboration: "collaboration-session",
|
|
14
12
|
dispatch: "unclassified-transactions",
|
|
15
13
|
save: "pm-save-projection",
|
|
@@ -49,17 +47,11 @@ const CANONICAL_CAPABILITIES = {
|
|
|
49
47
|
adapters: ["react", "vue"],
|
|
50
48
|
summary: "Hyperlink and TOC suggestions require serializable wrapper review provenance."
|
|
51
49
|
},
|
|
52
|
-
[CANONICAL_GAP.suggesting]: {
|
|
53
|
-
owner: "adapters",
|
|
54
|
-
kind: "refusal",
|
|
55
|
-
adapters: ["react", "vue"],
|
|
56
|
-
summary: "Adapter suggesting controls and tracked secondary-story edits remain gated."
|
|
57
|
-
},
|
|
58
50
|
[CANONICAL_GAP.comments]: {
|
|
59
51
|
owner: "adapters",
|
|
60
|
-
kind: "
|
|
52
|
+
kind: "routing",
|
|
61
53
|
adapters: ["react", "vue"],
|
|
62
|
-
summary: "
|
|
54
|
+
summary: "Default sessions retain comment model edits; canonical comments use semantic operations."
|
|
63
55
|
},
|
|
64
56
|
[CANONICAL_GAP.modelEdits]: {
|
|
65
57
|
owner: "adapters",
|
|
@@ -68,10 +60,10 @@ const CANONICAL_CAPABILITIES = {
|
|
|
68
60
|
summary: "Direct model and pending-suggestion snapshots bypass the canonical journal."
|
|
69
61
|
},
|
|
70
62
|
[CANONICAL_GAP.sectionProperties]: {
|
|
71
|
-
owner: "
|
|
63
|
+
owner: "controller",
|
|
72
64
|
kind: "routing",
|
|
73
65
|
adapters: ["react", "vue"],
|
|
74
|
-
summary: "
|
|
66
|
+
summary: "The shared controller journals section properties; default sessions keep model changes."
|
|
75
67
|
},
|
|
76
68
|
[CANONICAL_GAP.watermark]: {
|
|
77
69
|
owner: "adapters",
|
|
@@ -79,12 +71,6 @@ const CANONICAL_CAPABILITIES = {
|
|
|
79
71
|
adapters: ["vue"],
|
|
80
72
|
summary: "Vue watermark mutations still change the model directly."
|
|
81
73
|
},
|
|
82
|
-
[CANONICAL_GAP.secondaryStories]: {
|
|
83
|
-
owner: "controller",
|
|
84
|
-
kind: "routing",
|
|
85
|
-
adapters: ["react", "vue"],
|
|
86
|
-
summary: "Secondary-story creation, views and history still select their session authority."
|
|
87
|
-
},
|
|
88
74
|
[CANONICAL_GAP.collaboration]: {
|
|
89
75
|
owner: "controller",
|
|
90
76
|
kind: "refusal",
|
|
@@ -149,9 +135,9 @@ const CANONICAL_CAPABILITIES = {
|
|
|
149
135
|
[CANONICAL_GAP.publicComments]: {
|
|
150
136
|
owner: "document-operations",
|
|
151
137
|
defaultSessionMutation: "pm-public-operations",
|
|
152
|
-
kind: "
|
|
138
|
+
kind: "routing",
|
|
153
139
|
adapters: ["react", "vue"],
|
|
154
|
-
summary: "
|
|
140
|
+
summary: "Canonical public comments compile to semantic operations; default sessions retain PM comments."
|
|
155
141
|
},
|
|
156
142
|
[CANONICAL_GAP.publicSuggestedMode]: {
|
|
157
143
|
owner: "document-operations",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CanonicalGap } from "./canonicalCapabilities.js";
|
|
2
|
+
import { Comment } from "./content.js";
|
|
3
|
+
import { OpStory } from "@stll/docx-core/ops";
|
|
4
|
+
//#region src/types/canonicalComments.d.ts
|
|
5
|
+
/** Requests name their anchor; comment metadata never creates an unanchored root. */
|
|
6
|
+
type CanonicalCommentRequest = {
|
|
7
|
+
type: "create";
|
|
8
|
+
text: string;
|
|
9
|
+
author: string;
|
|
10
|
+
date?: string;
|
|
11
|
+
anchor: {
|
|
12
|
+
kind: "selection";
|
|
13
|
+
from: number;
|
|
14
|
+
to: number;
|
|
15
|
+
story: OpStory;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "reply";
|
|
18
|
+
parentId: number;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "revision";
|
|
21
|
+
story: OpStory;
|
|
22
|
+
revisionId: number;
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
type: "update";
|
|
26
|
+
id: number;
|
|
27
|
+
content: Comment["content"];
|
|
28
|
+
} | {
|
|
29
|
+
type: "resolve";
|
|
30
|
+
id: number;
|
|
31
|
+
status: "open" | "resolved";
|
|
32
|
+
} | {
|
|
33
|
+
type: "delete";
|
|
34
|
+
id: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: "replace";
|
|
37
|
+
comments: readonly Comment[];
|
|
38
|
+
};
|
|
39
|
+
type CanonicalCommentResult = {
|
|
40
|
+
status: "applied";
|
|
41
|
+
comments: Comment[];
|
|
42
|
+
commentId?: number;
|
|
43
|
+
} | {
|
|
44
|
+
status: "refused";
|
|
45
|
+
gap: CanonicalGap;
|
|
46
|
+
message: string;
|
|
47
|
+
/** Whether the same request can succeed once a pending composition settles. */
|
|
48
|
+
retry: "afterComposition" | "never";
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { CanonicalCommentRequest, CanonicalCommentResult };
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CANONICAL_GAP } from "./canonicalCapabilities.js";
|
|
2
|
+
//#region src/types/canonicalSections.d.ts
|
|
3
|
+
type CanonicalSectionPropertiesResult = {
|
|
4
|
+
status: "applied";
|
|
5
|
+
version: number;
|
|
6
|
+
} | {
|
|
7
|
+
status: "refused";
|
|
8
|
+
gap: typeof CANONICAL_GAP.sectionProperties;
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { CanonicalSectionPropertiesResult };
|
|
File without changes
|
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
import { resolveHeadingLevel } from "../docx/builtInStyles.js";
|
|
2
2
|
import { readOutlineLevelAttr } from "../prosemirror/outlineLevelAttr.js";
|
|
3
3
|
//#region src/utils/headingCollector.ts
|
|
4
|
+
const RUN_IN_TITLE_MARKS = /* @__PURE__ */ new Set([
|
|
5
|
+
"bold",
|
|
6
|
+
"italic",
|
|
7
|
+
"underline"
|
|
8
|
+
]);
|
|
9
|
+
const runInTitleFormat = (child) => {
|
|
10
|
+
const marks = child.marks.map(({ type }) => type.name).filter((name) => RUN_IN_TITLE_MARKS.has(name)).sort();
|
|
11
|
+
return marks.length > 0 ? marks.join("+") : void 0;
|
|
12
|
+
};
|
|
13
|
+
const headingText = (paragraph) => {
|
|
14
|
+
let text = "";
|
|
15
|
+
let capture = { status: "searching" };
|
|
16
|
+
for (let childIndex = 0; childIndex < paragraph.childCount; childIndex += 1) {
|
|
17
|
+
const child = paragraph.child(childIndex);
|
|
18
|
+
if (!child.isText) {
|
|
19
|
+
if (capture.status === "collecting") capture = {
|
|
20
|
+
status: "complete",
|
|
21
|
+
text: capture.text
|
|
22
|
+
};
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const childText = child.text || "";
|
|
26
|
+
text += childText;
|
|
27
|
+
const format = runInTitleFormat(child);
|
|
28
|
+
if (capture.status === "searching" && format !== void 0) {
|
|
29
|
+
capture = {
|
|
30
|
+
status: "collecting",
|
|
31
|
+
format,
|
|
32
|
+
text: childText
|
|
33
|
+
};
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (capture.status !== "collecting") continue;
|
|
37
|
+
capture = format === capture.format ? {
|
|
38
|
+
status: "collecting",
|
|
39
|
+
format: capture.format,
|
|
40
|
+
text: capture.text + childText
|
|
41
|
+
} : {
|
|
42
|
+
status: "complete",
|
|
43
|
+
text: capture.text
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return ((capture.status === "searching" ? "" : capture.text.trim()) || text).trim();
|
|
47
|
+
};
|
|
4
48
|
/**
|
|
5
49
|
* Collect all headings from a ProseMirror document, in document order.
|
|
6
50
|
*
|
|
@@ -19,10 +63,7 @@ function collectHeadings(doc, styles) {
|
|
|
19
63
|
styleId: typeof node.attrs["styleId"] === "string" ? node.attrs["styleId"] : null
|
|
20
64
|
}, styles);
|
|
21
65
|
if (level === void 0) return;
|
|
22
|
-
|
|
23
|
-
node.forEach((child) => {
|
|
24
|
-
if (child.isText) text += child.text || "";
|
|
25
|
-
});
|
|
66
|
+
const text = headingText(node);
|
|
26
67
|
if (text.trim()) headings.push({
|
|
27
68
|
text: text.trim(),
|
|
28
69
|
level,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HeadingInfo } from "./headingCollector.js";
|
|
2
|
+
//#region src/utils/outlineDepth.d.ts
|
|
3
|
+
/** Maximum heading depth displayed in the document outline. */
|
|
4
|
+
type OutlineDepth = 2 | 3 | "all";
|
|
5
|
+
declare const DEFAULT_OUTLINE_DEPTH = 2;
|
|
6
|
+
/** Filter headings for the outline without changing their document order. */
|
|
7
|
+
declare const filterHeadingsByDepth: (headings: readonly HeadingInfo[], depth: OutlineDepth) => HeadingInfo[];
|
|
8
|
+
//#endregion
|
|
9
|
+
export { DEFAULT_OUTLINE_DEPTH, OutlineDepth, filterHeadingsByDepth };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/utils/outlineDepth.ts
|
|
2
|
+
const DEFAULT_OUTLINE_DEPTH = 2;
|
|
3
|
+
/** Filter headings for the outline without changing their document order. */
|
|
4
|
+
const filterHeadingsByDepth = (headings, depth) => {
|
|
5
|
+
if (depth === "all") return [...headings];
|
|
6
|
+
return headings.filter((heading) => heading.level < depth);
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { DEFAULT_OUTLINE_DEPTH, filterHeadingsByDepth };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"perf": "bun scripts/profile-editor.ts"
|
|
147
147
|
},
|
|
148
148
|
"dependencies": {
|
|
149
|
-
"@stll/docx-core": "^0.
|
|
149
|
+
"@stll/docx-core": "^0.33.0",
|
|
150
150
|
"@stll/docx-utils": "^0.1.0",
|
|
151
151
|
"@stll/template-conditions": "^0.6.2",
|
|
152
152
|
"better-result": "3.0.1",
|