@stll/folio-core 0.32.0 → 0.32.2
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 +95 -42
- package/dist/ai-edits/index.d.ts +2 -2
- package/dist/ai-edits/types.d.ts +25 -1
- package/dist/compat/eigenpal.d.ts +2 -2
- package/dist/document-operations.d.ts +3 -1
- package/dist/document-operations.js +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/markdown/fromMarkdown.js +13 -240
- package/dist/server.d.ts +2 -2
- package/dist/utils/urlSecurity.d.ts +1 -1
- package/dist/utils/urlSecurity.js +1 -19
- package/package.json +2 -3
package/dist/ai-edits/apply.js
CHANGED
|
@@ -143,12 +143,29 @@ const applyTrackedInlineFormatting = ({ tr, schema, doc, from, to, formatting, r
|
|
|
143
143
|
* uniqueness across overlapping calls in the same JS realm.
|
|
144
144
|
*/
|
|
145
145
|
let revisionIdCursor = Date.now() * 1e3;
|
|
146
|
-
const nextRevisionSeed = (
|
|
146
|
+
const nextRevisionSeed = (revisionIdCount) => {
|
|
147
147
|
const start = revisionIdCursor;
|
|
148
|
-
revisionIdCursor += Math.max(
|
|
148
|
+
revisionIdCursor += Math.max(revisionIdCount, 1);
|
|
149
149
|
return start;
|
|
150
150
|
};
|
|
151
151
|
/**
|
|
152
|
+
* Ids one resolved operation may allocate from the shared revision-id range
|
|
153
|
+
* reserved by `nextRevisionSeed`. Most operation types allocate at most
|
|
154
|
+
* three (delete + insert + background-format clearing); reserving four per
|
|
155
|
+
* operation is a safe cushion above that. A multi-paragraph
|
|
156
|
+
* `insertAfterBlock` / `insertBeforeBlock` (`text` split on line breaks,
|
|
157
|
+
* see `splitInsertParagraphTexts`) allocates one id per paragraph in
|
|
158
|
+
* tracked-changes mode, so it needs more than four once split into more
|
|
159
|
+
* than four paragraphs — reserving less than that would let a later
|
|
160
|
+
* `nextRevisionSeed` call reuse an id this operation already stamped on
|
|
161
|
+
* the document.
|
|
162
|
+
*/
|
|
163
|
+
const REVISION_IDS_PER_OPERATION = 4;
|
|
164
|
+
const estimateRevisionIdReservation = (item) => {
|
|
165
|
+
if (item.operation.type === "insertAfterBlock" || item.operation.type === "insertBeforeBlock") return Math.max(item.insertTexts?.length ?? 1, REVISION_IDS_PER_OPERATION);
|
|
166
|
+
return REVISION_IDS_PER_OPERATION;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
152
169
|
* Walk the live doc once and bucket every textblock by its
|
|
153
170
|
* normalised text hash. Resolution then maps each snapshot anchor
|
|
154
171
|
* to the live block at the same ordinal among same-hash siblings —
|
|
@@ -279,6 +296,22 @@ const buildSignatureTableNode = ({ schema, parties }) => {
|
|
|
279
296
|
const row = rowType.create({}, cells);
|
|
280
297
|
return tableType.create({}, row);
|
|
281
298
|
};
|
|
299
|
+
const LINE_BREAK_PATTERN = /\r\n|\r|\n/;
|
|
300
|
+
/**
|
|
301
|
+
* Split `insertAfterBlock` / `insertBeforeBlock` text on line breaks into one
|
|
302
|
+
* string per paragraph the operation should produce. A model routinely sends
|
|
303
|
+
* a whole clause — heading plus body — as one `text` with embedded newlines;
|
|
304
|
+
* Word has no such thing as a paragraph containing a line break, so each line
|
|
305
|
+
* becomes its own paragraph instead of literal newline characters inside one.
|
|
306
|
+
* Blank (whitespace-only) lines are dropped rather than becoming empty
|
|
307
|
+
* paragraphs, so a trailing/leading newline collapses away. Falls back to a
|
|
308
|
+
* single empty string when every line is blank, so callers never get zero
|
|
309
|
+
* paragraphs out of non-empty input.
|
|
310
|
+
*/
|
|
311
|
+
const splitInsertParagraphTexts = (text) => {
|
|
312
|
+
const nonBlankLines = text.split(LINE_BREAK_PATTERN).filter((line) => line.trim().length > 0);
|
|
313
|
+
return nonBlankLines.length > 0 ? nonBlankLines : [""];
|
|
314
|
+
};
|
|
282
315
|
/**
|
|
283
316
|
* Build the inline content for an inserted or replaced block, promoting the
|
|
284
317
|
* model's `**bold**` / `***bold italic***` markdown into real Word marks (the
|
|
@@ -305,6 +338,7 @@ const buildEmphasisInlineContent = (schema, text, baseMarks) => {
|
|
|
305
338
|
const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode = "tracked-changes", author = "AI", initials, createCommentId, revisionIdSeed }) => {
|
|
306
339
|
const applied = [];
|
|
307
340
|
const skipped = [];
|
|
341
|
+
const normalizations = [];
|
|
308
342
|
const resolved = [];
|
|
309
343
|
const insertionType = view.state.schema.marks["insertion"];
|
|
310
344
|
const deletionType = view.state.schema.marks["deletion"];
|
|
@@ -369,6 +403,11 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
369
403
|
}
|
|
370
404
|
claimedTableColumns.add(columnKey);
|
|
371
405
|
}
|
|
406
|
+
if ((operation.type === "insertAfterBlock" || operation.type === "insertBeforeBlock") && LINE_BREAK_PATTERN.test(operation.text)) normalizations.push({
|
|
407
|
+
id: operation.id,
|
|
408
|
+
code: "splitMultilineText",
|
|
409
|
+
paragraphCount: resolution.operation.insertTexts?.length ?? 1
|
|
410
|
+
});
|
|
372
411
|
const commentId = commentText !== void 0 ? createCommentId?.(commentText) : void 0;
|
|
373
412
|
resolved.push({
|
|
374
413
|
...resolution.operation,
|
|
@@ -385,10 +424,12 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
385
424
|
const executableResolved = tablePlan.executable;
|
|
386
425
|
if (executableResolved.length === 0) return {
|
|
387
426
|
applied,
|
|
388
|
-
skipped
|
|
427
|
+
skipped,
|
|
428
|
+
...normalizations.length > 0 && { normalizations }
|
|
389
429
|
};
|
|
390
430
|
let tr = view.state.tr;
|
|
391
|
-
|
|
431
|
+
const revisionIdReservation = executableResolved.reduce((total, item) => total + estimateRevisionIdReservation(item), 0);
|
|
432
|
+
let revisionSeed = revisionIdSeed ?? nextRevisionSeed(revisionIdReservation);
|
|
392
433
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
393
434
|
const insertedColumnCounts = /* @__PURE__ */ new Map();
|
|
394
435
|
for (const item of executableResolved.toSorted((left, right) => {
|
|
@@ -571,50 +612,59 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
571
612
|
}
|
|
572
613
|
case "insertAfterBlock":
|
|
573
614
|
case "insertBeforeBlock": {
|
|
574
|
-
|
|
615
|
+
const insertTexts = item.insertTexts ?? [""];
|
|
616
|
+
const isEmptyInsert = insertTexts.length === 1 && insertTexts[0]?.length === 0;
|
|
617
|
+
if (mode === "tracked-changes" && item.operation.pageBreakBefore === true && isEmptyInsert) {
|
|
575
618
|
skipped.push({
|
|
576
619
|
id: item.operation.id,
|
|
577
620
|
reason: "unsupportedMode"
|
|
578
621
|
});
|
|
579
622
|
continue;
|
|
580
623
|
}
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
624
|
+
const operation = item.operation;
|
|
625
|
+
const baseAttrs = operation.inheritFormatting === false ? {} : stripBlockIdentityAttrs(item.blockNode.attrs);
|
|
626
|
+
const insertedBlockRevisionIds = [];
|
|
627
|
+
const nodes = [];
|
|
628
|
+
for (const [paragraphIndex, text] of insertTexts.entries()) {
|
|
629
|
+
const isFirstParagraph = paragraphIndex === 0;
|
|
630
|
+
const marks = [];
|
|
631
|
+
let paragraphRevisionId = null;
|
|
632
|
+
if (producesTrackedChanges && insertionType) {
|
|
633
|
+
paragraphRevisionId = revisionSeed++;
|
|
634
|
+
marks.push(insertionType.create({
|
|
635
|
+
revisionId: paragraphRevisionId,
|
|
636
|
+
author,
|
|
637
|
+
date,
|
|
638
|
+
...trackedRevisionExtras
|
|
639
|
+
}));
|
|
640
|
+
insertedBlockRevisionIds.push(paragraphRevisionId);
|
|
641
|
+
}
|
|
642
|
+
if (commentMark) marks.push(commentMark);
|
|
643
|
+
const content = text.length > 0 ? buildEmphasisInlineContent(view.state.schema, text, marks) : null;
|
|
644
|
+
const attrs = isFirstParagraph ? { ...baseAttrs } : {};
|
|
645
|
+
if (isFirstParagraph && operation.pageBreakBefore === true) attrs["pageBreakBefore"] = true;
|
|
646
|
+
if (isFirstParagraph && operation.styleId !== void 0) {
|
|
647
|
+
attrs["styleId"] = operation.styleId;
|
|
648
|
+
if (operation.inheritFormatting !== false) {
|
|
649
|
+
attrs["listMarker"] = null;
|
|
650
|
+
attrs["listMarkerHidden"] = null;
|
|
651
|
+
attrs["listLevelNumFmts"] = null;
|
|
652
|
+
attrs["listLevelStarts"] = null;
|
|
653
|
+
attrs["listAbstractNumId"] = null;
|
|
654
|
+
attrs["listStartOverride"] = null;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (isSuggested && suggestionId !== null && paragraphRevisionId !== null) attrs["_suggestedInsert"] = {
|
|
658
|
+
suggestionId,
|
|
659
|
+
revisionId: paragraphRevisionId,
|
|
588
660
|
author,
|
|
589
661
|
date,
|
|
590
|
-
...
|
|
591
|
-
}
|
|
592
|
-
|
|
662
|
+
...initials ? { initials } : {}
|
|
663
|
+
};
|
|
664
|
+
nodes.push(item.blockNode.type.create(attrs, content));
|
|
593
665
|
}
|
|
594
|
-
if (
|
|
595
|
-
|
|
596
|
-
const attrs = { ...item.operation.inheritFormatting === false ? {} : stripBlockIdentityAttrs(item.blockNode.attrs) };
|
|
597
|
-
if (item.operation.pageBreakBefore === true) attrs["pageBreakBefore"] = true;
|
|
598
|
-
if (item.operation.styleId !== void 0) {
|
|
599
|
-
attrs["styleId"] = item.operation.styleId;
|
|
600
|
-
if (item.operation.inheritFormatting !== false) {
|
|
601
|
-
attrs["listMarker"] = null;
|
|
602
|
-
attrs["listMarkerHidden"] = null;
|
|
603
|
-
attrs["listLevelNumFmts"] = null;
|
|
604
|
-
attrs["listLevelStarts"] = null;
|
|
605
|
-
attrs["listAbstractNumId"] = null;
|
|
606
|
-
attrs["listStartOverride"] = null;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
if (isSuggested && suggestionId !== null && insertedBlockRevisionId !== null) attrs["_suggestedInsert"] = {
|
|
610
|
-
suggestionId,
|
|
611
|
-
revisionId: insertedBlockRevisionId,
|
|
612
|
-
author,
|
|
613
|
-
date,
|
|
614
|
-
...initials ? { initials } : {}
|
|
615
|
-
};
|
|
616
|
-
const node = item.blockNode.type.create(attrs, content);
|
|
617
|
-
tr = tr.insert(item.from, node);
|
|
666
|
+
if (insertedBlockRevisionIds.length > 0) appliedRevisionIds = insertedBlockRevisionIds;
|
|
667
|
+
tr = tr.insert(item.from, nodes);
|
|
618
668
|
break;
|
|
619
669
|
}
|
|
620
670
|
case "insertSignatureTable": {
|
|
@@ -897,7 +947,8 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
897
947
|
if (tr.docChanged) view.dispatch(tr);
|
|
898
948
|
return {
|
|
899
949
|
applied,
|
|
900
|
-
skipped
|
|
950
|
+
skipped,
|
|
951
|
+
...normalizations.length > 0 && { normalizations }
|
|
901
952
|
};
|
|
902
953
|
};
|
|
903
954
|
const applyFolioAIEditOperations = (options) => applyFolioAIEditOperationsInternal(options);
|
|
@@ -918,7 +969,8 @@ const previewFolioAIEditOperations = (options) => {
|
|
|
918
969
|
});
|
|
919
970
|
return {
|
|
920
971
|
applied: result.applied.map(({ id }) => ({ id })),
|
|
921
|
-
skipped: result.skipped
|
|
972
|
+
skipped: result.skipped,
|
|
973
|
+
...result.normalizations !== void 0 && { normalizations: result.normalizations }
|
|
922
974
|
};
|
|
923
975
|
};
|
|
924
976
|
const applyTextReplacement = ({ tr, item, mode, author, date, revisionIdDelete, revisionIdInsert, commentMark, suggestionId = null, initials }) => {
|
|
@@ -1135,6 +1187,7 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
|
|
|
1135
1187
|
let insertFrom;
|
|
1136
1188
|
if (tableBoundary) insertFrom = isInsertAfter ? tableBoundary.after : tableBoundary.before;
|
|
1137
1189
|
else insertFrom = isInsertAfter ? blockTo : blockFrom;
|
|
1190
|
+
const insertTexts = LINE_BREAK_PATTERN.test(operation.text) ? splitInsertParagraphTexts(operation.text) : [operation.text];
|
|
1138
1191
|
return {
|
|
1139
1192
|
type: "resolved",
|
|
1140
1193
|
operation: {
|
|
@@ -1144,7 +1197,7 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
|
|
|
1144
1197
|
blockFrom,
|
|
1145
1198
|
blockTo,
|
|
1146
1199
|
blockNode,
|
|
1147
|
-
|
|
1200
|
+
insertTexts
|
|
1148
1201
|
}
|
|
1149
1202
|
};
|
|
1150
1203
|
}
|
package/dist/ai-edits/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./types.js";
|
|
2
2
|
import { FolioAIEditView, applyFolioAIEditOperations } from "./apply.js";
|
|
3
3
|
import { DocPositionRange, clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "./blockRange.js";
|
|
4
4
|
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
@@ -9,4 +9,4 @@ import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlo
|
|
|
9
9
|
import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
|
|
10
10
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
11
11
|
import { WordDiffSegment, diffWordSegments } from "./word-diff.js";
|
|
12
|
-
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAIInlineFormatting, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
|
|
12
|
+
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAIInlineFormatting, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -161,6 +161,14 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
|
|
|
161
161
|
id: string;
|
|
162
162
|
type: "insertAfterBlock" | "insertBeforeBlock";
|
|
163
163
|
blockId: string;
|
|
164
|
+
/**
|
|
165
|
+
* The paragraph text to insert. A line break splits `text` into
|
|
166
|
+
* consecutive paragraphs at the same anchor instead of becoming
|
|
167
|
+
* literal newlines inside one paragraph: only the first paragraph
|
|
168
|
+
* gets `styleId` / `inheritFormatting`, later ones use body
|
|
169
|
+
* formatting. Blank lines are dropped. Reported as a
|
|
170
|
+
* `splitMultilineText` normalization when it happens.
|
|
171
|
+
*/
|
|
164
172
|
text: string;
|
|
165
173
|
inheritFormatting?: boolean;
|
|
166
174
|
/**
|
|
@@ -318,9 +326,25 @@ type FolioAIEditSkippedOperation = {
|
|
|
318
326
|
id: string;
|
|
319
327
|
reason: FolioAIEditSkipReason;
|
|
320
328
|
};
|
|
329
|
+
/** One automatic adjustment `apply.ts` made to an operation's input to keep the applied result well-formed. */
|
|
330
|
+
type FolioAIEditNormalizationCode = "splitMultilineText";
|
|
331
|
+
/**
|
|
332
|
+
* A line-break in `insertAfterBlock` / `insertBeforeBlock`'s `text` cannot become
|
|
333
|
+
* one paragraph with an embedded break (Word paragraphs are single lines); the
|
|
334
|
+
* applier splits it into one paragraph per non-blank line instead and reports it
|
|
335
|
+
* here so the caller can see what happened to the text it sent.
|
|
336
|
+
*/
|
|
337
|
+
type FolioAIEditNormalization = {
|
|
338
|
+
id: string;
|
|
339
|
+
code: FolioAIEditNormalizationCode;
|
|
340
|
+
/** Number of paragraphs the operation's `text` was split into. */
|
|
341
|
+
paragraphCount: number;
|
|
342
|
+
};
|
|
321
343
|
type FolioAIEditApplyResult = {
|
|
322
344
|
applied: FolioAIEditAppliedOperation[];
|
|
323
345
|
skipped: FolioAIEditSkippedOperation[];
|
|
346
|
+
/** Present only when at least one operation triggered a normalization. */
|
|
347
|
+
normalizations?: FolioAIEditNormalization[];
|
|
324
348
|
};
|
|
325
349
|
//#endregion
|
|
326
|
-
export { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult };
|
|
350
|
+
export { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
|
|
2
2
|
import { applyFolioAIEditOperations } from "../ai-edits/apply.js";
|
|
3
3
|
import { document_d_exports } from "../types/document.js";
|
|
4
4
|
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
@@ -34,4 +34,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
34
34
|
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
35
35
|
type Document = document_d_exports.Document;
|
|
36
36
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
37
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
37
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAITextRangeHandle } from "./ai-edits/types.js";
|
|
1
|
+
import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditNormalization, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAITextRangeHandle } from "./ai-edits/types.js";
|
|
2
2
|
import { FolioAIEditView } from "./ai-edits/apply.js";
|
|
3
3
|
//#region src/document-operations.d.ts
|
|
4
4
|
declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
|
|
@@ -206,6 +206,8 @@ type FolioDocumentOperationResultBase = {
|
|
|
206
206
|
issues: FolioDocumentOperationIssue[];
|
|
207
207
|
/** Successful effects in input-operation order; skipped operations are omitted. */
|
|
208
208
|
receipts: FolioDocumentOperationReceipt[];
|
|
209
|
+
/** Present when at least one operation triggered an automatic input normalization. */
|
|
210
|
+
normalizations?: FolioAIEditNormalization[];
|
|
209
211
|
/** Present when the execution surface can undo this committed batch. */
|
|
210
212
|
undoHandle: FolioDocumentOperationUndoHandle | null;
|
|
211
213
|
};
|
|
@@ -759,6 +759,7 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
759
759
|
skipped,
|
|
760
760
|
issues: getFolioDocumentOperationIssues(parsedBatch.operations, skipped),
|
|
761
761
|
receipts: [],
|
|
762
|
+
...previewResult.normalizations !== void 0 && { normalizations: previewResult.normalizations },
|
|
762
763
|
undoHandle: null
|
|
763
764
|
};
|
|
764
765
|
};
|
|
@@ -776,6 +777,7 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
776
777
|
applied: previewResult.applied,
|
|
777
778
|
story
|
|
778
779
|
}),
|
|
780
|
+
...previewResult.normalizations !== void 0 && { normalizations: previewResult.normalizations },
|
|
779
781
|
undoHandle: null
|
|
780
782
|
};
|
|
781
783
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./ai-edits/types.js";
|
|
2
2
|
import { applyFolioAIEditOperations } from "./ai-edits/apply.js";
|
|
3
3
|
import { document_d_exports } from "./types/document.js";
|
|
4
4
|
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
@@ -35,4 +35,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
|
|
|
35
35
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
36
36
|
type Document = document_d_exports.Document;
|
|
37
37
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
38
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
38
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -1,227 +1,24 @@
|
|
|
1
1
|
import { createEmptyDocument } from "../utils/createDocument.js";
|
|
2
|
-
import {
|
|
3
|
-
import { marked } from "marked";
|
|
2
|
+
import { compileMarkdownToContent } from "@stll/docx-core";
|
|
4
3
|
//#region src/markdown/fromMarkdown.ts
|
|
5
4
|
/**
|
|
6
5
|
* Markdown → DOCX-document import — the inverse of {@link toMarkdown} and the
|
|
7
|
-
* second half of the skills bridge.
|
|
8
|
-
* (
|
|
9
|
-
*
|
|
10
|
-
* `Document` model so a skill's markdown can be edited in the Folio editor and
|
|
11
|
-
* re-exported with {@link toMarkdown} without drift.
|
|
6
|
+
* second half of the skills bridge. The parsing lives in `@stll/docx-core`
|
|
7
|
+
* (`compileMarkdownToContent`), the same GFM reader the legal-source compiler
|
|
8
|
+
* uses; this wrapper only places the blocks into an editor-ready `Document`.
|
|
12
9
|
*
|
|
13
10
|
* Round-trip notes:
|
|
14
|
-
* - Lists
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
11
|
+
* - Lists arrive as real list paragraphs (`listRendering` plus `numPr`) with a
|
|
12
|
+
* matching `document.package.numbering`, so the editor shows a marker and
|
|
13
|
+
* {@link toMarkdown} re-derives `- ` / `1. ` rather than leaking a literal
|
|
14
|
+
* bullet glyph. Merging this content onto another document that has its own
|
|
15
|
+
* numbering (e.g. a styled preset) needs `mergeDocumentContent` to renumber
|
|
16
|
+
* the two numbering namespaces apart.
|
|
20
17
|
* - Markdown carries no page geometry, so the section is flattened to a
|
|
21
18
|
* continuous, header/footer-free band (a skill body is a document, not a
|
|
22
19
|
* Word page). Headers/footers live outside `document.content` and are never
|
|
23
20
|
* produced here.
|
|
24
|
-
* - Every markdown list also gets a matching `w:abstractNum`/`w:num` pair in
|
|
25
|
-
* `document.package.numbering` (see {@link buildNumbering}), so the result
|
|
26
|
-
* is self-consistent and `createDocx` never has to fail with a missing
|
|
27
|
-
* numbering definition. Merging this content onto another document that
|
|
28
|
-
* has its own numbering (e.g. a styled preset) needs `mergeDocumentContent`
|
|
29
|
-
* to renumber the two numbering namespaces apart — appending
|
|
30
|
-
* `document.package.document.content` directly can collide.
|
|
31
21
|
*/
|
|
32
|
-
const MONO_FONT = {
|
|
33
|
-
ascii: "Courier New",
|
|
34
|
-
hAnsi: "Courier New"
|
|
35
|
-
};
|
|
36
|
-
const isTokenType = (token, type) => token.type === type;
|
|
37
|
-
const textRun = (text, fmt = {}) => {
|
|
38
|
-
const formatting = {
|
|
39
|
-
...fmt.bold ? { bold: true } : {},
|
|
40
|
-
...fmt.italic ? { italic: true } : {},
|
|
41
|
-
...fmt.strike ? { strike: true } : {},
|
|
42
|
-
...fmt.mono ? { fontFamily: MONO_FONT } : {}
|
|
43
|
-
};
|
|
44
|
-
const segments = text.split("\n");
|
|
45
|
-
const content = [];
|
|
46
|
-
for (const [index, segment] of segments.entries()) {
|
|
47
|
-
if (index > 0) content.push({ type: "break" });
|
|
48
|
-
if (segment.length > 0) content.push({
|
|
49
|
-
type: "text",
|
|
50
|
-
text: segment
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
if (content.length === 0) content.push({
|
|
54
|
-
type: "text",
|
|
55
|
-
text: ""
|
|
56
|
-
});
|
|
57
|
-
return {
|
|
58
|
-
type: "run",
|
|
59
|
-
formatting,
|
|
60
|
-
content
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
const sanitizeMarkdownHref = (rawHref) => {
|
|
64
|
-
const trimmed = rawHref.trim();
|
|
65
|
-
if (!trimmed) return;
|
|
66
|
-
if (trimmed.startsWith("#")) {
|
|
67
|
-
const anchor = trimmed.slice(1);
|
|
68
|
-
if (!anchor || hasUnsafeAnchorCharacter(anchor)) return;
|
|
69
|
-
return `#${anchor}`;
|
|
70
|
-
}
|
|
71
|
-
return sanitizeExternalUrl(trimmed);
|
|
72
|
-
};
|
|
73
|
-
const hasUnsafeAnchorCharacter = (anchor) => {
|
|
74
|
-
for (const char of anchor) {
|
|
75
|
-
const codePoint = char.codePointAt(0) ?? 0;
|
|
76
|
-
if (codePoint <= 32 || codePoint === 127 || char.trim() === "") return true;
|
|
77
|
-
}
|
|
78
|
-
return false;
|
|
79
|
-
};
|
|
80
|
-
const inlineToRuns = (tokens, fallback, base) => {
|
|
81
|
-
if (!tokens || tokens.length === 0) return [textRun(fallback, base)];
|
|
82
|
-
const runs = [];
|
|
83
|
-
for (const token of tokens) if (isTokenType(token, "strong")) runs.push(...inlineToRuns(token.tokens, token.text, {
|
|
84
|
-
...base,
|
|
85
|
-
bold: true
|
|
86
|
-
}));
|
|
87
|
-
else if (isTokenType(token, "em")) runs.push(...inlineToRuns(token.tokens, token.text, {
|
|
88
|
-
...base,
|
|
89
|
-
italic: true
|
|
90
|
-
}));
|
|
91
|
-
else if (isTokenType(token, "del")) runs.push(...inlineToRuns(token.tokens, token.text, {
|
|
92
|
-
...base,
|
|
93
|
-
strike: true
|
|
94
|
-
}));
|
|
95
|
-
else if (isTokenType(token, "codespan")) runs.push(textRun(token.text, {
|
|
96
|
-
...base,
|
|
97
|
-
mono: true
|
|
98
|
-
}));
|
|
99
|
-
else if (isTokenType(token, "link")) {
|
|
100
|
-
const children = inlineToRuns(token.tokens, token.text, base).filter((child) => child.type === "run");
|
|
101
|
-
const href = sanitizeMarkdownHref(token.href);
|
|
102
|
-
const linkChildren = children.length > 0 ? children : [textRun(token.text, base)];
|
|
103
|
-
if (!href) {
|
|
104
|
-
runs.push(...linkChildren);
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
const anchor = href.startsWith("#") ? href.slice(1) : void 0;
|
|
108
|
-
runs.push({
|
|
109
|
-
type: "hyperlink",
|
|
110
|
-
href,
|
|
111
|
-
...anchor ? { anchor } : {},
|
|
112
|
-
children: linkChildren
|
|
113
|
-
});
|
|
114
|
-
} else if (isTokenType(token, "paragraph")) runs.push(...inlineToRuns(token.tokens, token.text, base));
|
|
115
|
-
else if (token.type === "br") runs.push({
|
|
116
|
-
type: "run",
|
|
117
|
-
content: [{ type: "break" }]
|
|
118
|
-
});
|
|
119
|
-
else if (token.type === "space") {
|
|
120
|
-
if (runs.length > 0 && token.raw.includes("\n")) runs.push(textRun("\n", base));
|
|
121
|
-
} else if (isTokenType(token, "text")) {
|
|
122
|
-
const nested = token.tokens;
|
|
123
|
-
if (nested && nested.length > 0) runs.push(...inlineToRuns(nested, token.text, base));
|
|
124
|
-
else runs.push(textRun(token.text, base));
|
|
125
|
-
} else if ("text" in token && typeof token.text === "string") runs.push(textRun(token.text, base));
|
|
126
|
-
return runs.length > 0 ? runs : [textRun(fallback, base)];
|
|
127
|
-
};
|
|
128
|
-
const para = (runs, styleId) => ({
|
|
129
|
-
type: "paragraph",
|
|
130
|
-
formatting: styleId ? { styleId } : {},
|
|
131
|
-
content: runs.length > 0 ? runs : [textRun("")]
|
|
132
|
-
});
|
|
133
|
-
const listPara = (runs, rendering) => ({
|
|
134
|
-
type: "paragraph",
|
|
135
|
-
formatting: { numPr: {
|
|
136
|
-
numId: rendering.numId,
|
|
137
|
-
ilvl: rendering.level
|
|
138
|
-
} },
|
|
139
|
-
listRendering: rendering,
|
|
140
|
-
content: runs.length > 0 ? runs : [textRun("")]
|
|
141
|
-
});
|
|
142
|
-
const cellOf = (cell) => ({
|
|
143
|
-
type: "tableCell",
|
|
144
|
-
content: [para(inlineToRuns(cell.tokens, cell.text, {}))]
|
|
145
|
-
});
|
|
146
|
-
const tableFromToken = (token) => ({
|
|
147
|
-
type: "table",
|
|
148
|
-
rows: [{
|
|
149
|
-
type: "tableRow",
|
|
150
|
-
cells: token.header.map((c) => cellOf(c))
|
|
151
|
-
}, ...token.rows.map((row) => ({
|
|
152
|
-
type: "tableRow",
|
|
153
|
-
cells: row.map((c) => cellOf(c))
|
|
154
|
-
}))]
|
|
155
|
-
});
|
|
156
|
-
const LIST_INDENT_STEP_TWIPS = 720;
|
|
157
|
-
const buildListLevel = (ilvl, isBullet, start) => ({
|
|
158
|
-
ilvl,
|
|
159
|
-
...!isBullet && { start },
|
|
160
|
-
numFmt: isBullet ? "bullet" : "decimal",
|
|
161
|
-
lvlText: isBullet ? "•" : `%${ilvl + 1}.`,
|
|
162
|
-
suffix: "tab",
|
|
163
|
-
pPr: {
|
|
164
|
-
indentLeft: LIST_INDENT_STEP_TWIPS * (ilvl + 1),
|
|
165
|
-
indentFirstLine: -360,
|
|
166
|
-
hangingIndent: true
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
const listBlocks = (list, level, numId, levels) => {
|
|
170
|
-
const out = [];
|
|
171
|
-
const start = Number(list.start) || 1;
|
|
172
|
-
const decimalLevels = Array.from({ length: level + 1 }, () => "decimal");
|
|
173
|
-
if (!levels.has(level)) levels.set(level, buildListLevel(level, !list.ordered, start));
|
|
174
|
-
for (const item of list.items) {
|
|
175
|
-
const rendering = list.ordered ? {
|
|
176
|
-
marker: `%${level + 1}.`,
|
|
177
|
-
level,
|
|
178
|
-
numId,
|
|
179
|
-
isBullet: false,
|
|
180
|
-
numFmt: "decimal",
|
|
181
|
-
levelNumFmts: decimalLevels,
|
|
182
|
-
...start !== 1 && { startOverride: start }
|
|
183
|
-
} : {
|
|
184
|
-
marker: "•",
|
|
185
|
-
level,
|
|
186
|
-
numId,
|
|
187
|
-
isBullet: true
|
|
188
|
-
};
|
|
189
|
-
const inlineTokens = [];
|
|
190
|
-
const nestedLists = [];
|
|
191
|
-
for (const child of item.tokens) if (isTokenType(child, "list")) nestedLists.push(child);
|
|
192
|
-
else inlineTokens.push(child);
|
|
193
|
-
out.push(listPara(inlineToRuns(inlineTokens, item.text, {}), rendering));
|
|
194
|
-
for (const nested of nestedLists) out.push(...listBlocks(nested, level + 1, numId, levels));
|
|
195
|
-
}
|
|
196
|
-
return out;
|
|
197
|
-
};
|
|
198
|
-
const blocksFromTokens = (tokens, numIds) => {
|
|
199
|
-
const blocks = [];
|
|
200
|
-
for (const token of tokens ?? []) if (isTokenType(token, "heading")) {
|
|
201
|
-
const level = Math.min(Math.max(token.depth, 1), 4);
|
|
202
|
-
blocks.push(para(inlineToRuns(token.tokens, token.text, {}), `Heading${level}`));
|
|
203
|
-
} else if (isTokenType(token, "paragraph")) blocks.push(para(inlineToRuns(token.tokens, token.text, {})));
|
|
204
|
-
else if (isTokenType(token, "list")) {
|
|
205
|
-
const numId = numIds.next++;
|
|
206
|
-
const levels = /* @__PURE__ */ new Map();
|
|
207
|
-
numIds.levels.set(numId, levels);
|
|
208
|
-
blocks.push(...listBlocks(token, 0, numId, levels));
|
|
209
|
-
} else if (isTokenType(token, "table")) blocks.push(tableFromToken(token));
|
|
210
|
-
else if (isTokenType(token, "code")) for (const line of token.text.split("\n")) blocks.push(para([textRun(line.length > 0 ? line : " ", { mono: true })]));
|
|
211
|
-
else if (isTokenType(token, "blockquote")) for (const inner of blocksFromTokens(token.tokens, numIds)) {
|
|
212
|
-
const styled = inner.type === "paragraph" ? {
|
|
213
|
-
...inner,
|
|
214
|
-
formatting: {
|
|
215
|
-
...inner.formatting,
|
|
216
|
-
styleId: "Quote"
|
|
217
|
-
}
|
|
218
|
-
} : inner;
|
|
219
|
-
blocks.push(styled);
|
|
220
|
-
}
|
|
221
|
-
else if (token.type === "hr") blocks.push(para([textRun("———")]));
|
|
222
|
-
else if (token.type !== "space" && "text" in token && typeof token.text === "string" && token.text.trim().length > 0) blocks.push(para([textRun(token.text)]));
|
|
223
|
-
return blocks;
|
|
224
|
-
};
|
|
225
22
|
const applyMarkdownPageGeometry = (document) => {
|
|
226
23
|
const section = document.package.document.finalSectionProperties;
|
|
227
24
|
if (!section) return;
|
|
@@ -232,26 +29,6 @@ const applyMarkdownPageGeometry = (document) => {
|
|
|
232
29
|
section.headerDistance = 0;
|
|
233
30
|
section.footerDistance = 0;
|
|
234
31
|
};
|
|
235
|
-
const buildNumbering = (numIdLevels) => {
|
|
236
|
-
const abstractNums = [];
|
|
237
|
-
const nums = [];
|
|
238
|
-
for (const [numId, levels] of numIdLevels) {
|
|
239
|
-
const sortedLevels = [...levels.entries()].sort(([a], [b]) => a - b).map(([, lvl]) => lvl);
|
|
240
|
-
abstractNums.push({
|
|
241
|
-
abstractNumId: numId,
|
|
242
|
-
multiLevelType: sortedLevels.length > 1 ? "multilevel" : "singleLevel",
|
|
243
|
-
levels: sortedLevels
|
|
244
|
-
});
|
|
245
|
-
nums.push({
|
|
246
|
-
numId,
|
|
247
|
-
abstractNumId: numId
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
abstractNums,
|
|
252
|
-
nums
|
|
253
|
-
};
|
|
254
|
-
};
|
|
255
32
|
/**
|
|
256
33
|
* Convert a markdown string to a parsed `Document`. Synchronous. The result is
|
|
257
34
|
* ready to hand to the editor (`<DocxEditor document={…} />`) and to re-export
|
|
@@ -259,13 +36,9 @@ const buildNumbering = (numIdLevels) => {
|
|
|
259
36
|
*/
|
|
260
37
|
function fromMarkdown(markdown) {
|
|
261
38
|
const document = createEmptyDocument();
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
};
|
|
266
|
-
const blocks = blocksFromTokens(marked.lexer(markdown), numIds);
|
|
267
|
-
if (blocks.length > 0) document.package.document.content = blocks;
|
|
268
|
-
if (numIds.levels.size > 0) document.package.numbering = buildNumbering(numIds.levels);
|
|
39
|
+
const { content, numbering } = compileMarkdownToContent(markdown);
|
|
40
|
+
if (content.length > 0) document.package.document.content = content;
|
|
41
|
+
if (numbering) document.package.numbering = numbering;
|
|
269
42
|
applyMarkdownPageGeometry(document);
|
|
270
43
|
return document;
|
|
271
44
|
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./ai-edits/types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAITextRangeHandle, FolioDocumentNavigationTarget, FolioDocumentOutline, FolioDocumentOutlineEntry, FolioDocumentSection, FolioDocumentSectionHandle, FolioDocumentSectionReadResult } from "./ai-edits/types.js";
|
|
2
2
|
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "./document-operations.js";
|
|
3
3
|
import { FolioReviewChange, FolioReviewChangeKind } from "./ai-edits/read.js";
|
|
4
4
|
import { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewChangeFilter, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView } from "./ai-edits/headless.js";
|
|
@@ -27,4 +27,4 @@ import { FOLIO_DOCX_PACKAGE_INSPECTION_DEFAULTS, FOLIO_DOCX_PACKAGE_INSPECTION_E
|
|
|
27
27
|
import { FOLIO_YJS_DOCX_MATERIALIZATION_ERROR_CODES, FOLIO_YJS_PROSEMIRROR_FRAGMENT_NAME, FOLIO_YJS_UPDATE_MAX_BYTES, FolioYjsDocxMaterializationError, FolioYjsDocxMaterializationErrorCode, MaterializeYjsDocxOptions, materializeYjsDocx } from "./docx/server/materializeYjsDocx.js";
|
|
28
28
|
import { GenerateRedlineDocxOptions, GenerateRedlineDocxResult, GenerateRedlineUnprocessedStory, InvalidGenerateRedlineDocxOptionsError, generateRedlineDocx } from "./redline.js";
|
|
29
29
|
import { FOLIO_VERSION_COMPARISON_PRIVACY_TRANSFORMS, FOLIO_VERSION_COMPARISON_SCOPES, FolioBlockDiff, FolioCompareDocxVersionsOptions, FolioDocumentMetadataValue, FolioFormatProperty, FolioMetadataDiff, FolioStoryDiff, FolioVersionBlockHandle, FolioVersionComparisonPrivacyTransform, FolioVersionComparisonScope, FolioVersionDiff, FolioVersionDiffPrivacyOptions, FolioVersionDiffPrivacyReport, FolioVersionDiffSegment, FolioVersionDiffSummaryCounts, InvalidFolioVersionComparisonOptionsError, applyFolioVersionDiffPrivacy, compareDocxVersions, isFolioVersionComparisonPrivacyTransform, isFolioVersionComparisonScope } from "./version-comparison.js";
|
|
30
|
-
export { type ApplyDocxXmlPatchProposalArgs, type ApplyFolioAIEditsToBufferOptions, type ApplyFolioAIEditsToBufferResult, BILINGUAL_TABLE_LAYOUTS, type BilingualBorders, type BilingualParagraphRef, type BilingualRow, type BilingualRowKind, type BilingualTableLayout, type BilingualTableParagraphRef, type CreateBilingualDocumentOptions, type CreateBilingualDocumentResult, type CreateBilingualDocxOptions, type CreateBilingualDocxResult, type CreateCommentReplyInput, type CreateEmptyDocumentOptions, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, type DeriveBlockIdInput, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, DocxArchiveError, type DocxArchiveOptions, type DocxParagraphSource, type DocxTableRowKind, type DocxTableRowPosition, EnsureParaIdsError, type EnsureParaIdsOptions, type EnsureParaIdsResult, type EvaluateDocxXmlPatchProposalArgs, type ExtractDocumentStyleSetOptions, type ExtractedDocxParagraph, type ExtractedDocxTableCell, type ExtractedDocxTableCellParagraph, type ExtractedDocxText, FOLIO_DOCUMENT_METADATA_PROPERTIES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_DOCUMENT_PRIVACY_TRANSFORMS, FOLIO_DOCX_CONFORMANCE_CHECKS, FOLIO_DOCX_CONFORMANCE_ISSUE_CODES, FOLIO_DOCX_CONFORMANCE_PROFILE, FOLIO_DOCX_CONFORMANCE_REPORT_VERSION, FOLIO_DOCX_PACKAGE_INSPECTION_DEFAULTS, FOLIO_DOCX_PACKAGE_INSPECTION_ERROR_CODES, FOLIO_DOCX_PACKAGE_INSPECTION_VERSION, FOLIO_DOCX_XML_PATCH_APPLICATION_PROFILE, FOLIO_DOCX_XML_PATCH_APPLICATION_VERSION, FOLIO_DOCX_XML_PATCH_PROPOSAL_DEFAULTS, FOLIO_DOCX_XML_PATCH_PROPOSAL_ISSUE_CODES, FOLIO_DOCX_XML_PATCH_PROPOSAL_PROFILE, FOLIO_DOCX_XML_PATCH_PROPOSAL_VERSION, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FOLIO_VERSION_COMPARISON_PRIVACY_TRANSFORMS, FOLIO_VERSION_COMPARISON_SCOPES, FOLIO_YJS_DOCX_MATERIALIZATION_ERROR_CODES, FOLIO_YJS_PROSEMIRROR_FRAGMENT_NAME, FOLIO_YJS_UPDATE_MAX_BYTES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditSnapshot, type FolioAIInlineFormatting, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsOptions, type FolioApplyDocumentOperationsToStoryOptions, type FolioApplyOperationsOptions, type FolioBlockDiff, type FolioBlockId, type FolioCompareDocxVersionsOptions, type FolioDocumentMetadataProperty, type FolioDocumentMetadataValue, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationBatchPrecondition, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationQueuedOperation, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, FolioDocumentPrivacyArchiveError, type FolioDocumentPrivacyOptions, type FolioDocumentPrivacyReport, type FolioDocumentPrivacyTransform, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioDocxConformanceCheck, type FolioDocxConformanceCheckId, type FolioDocxConformanceCheckStatus, type FolioDocxConformanceIssue, type FolioDocxConformanceIssueCode, type FolioDocxConformanceReport, type FolioDocxConformanceStatus, type FolioDocxInspectedXmlPart, type FolioDocxPackageInspection, FolioDocxPackageInspectionError, type FolioDocxPackageInspectionErrorCode, type FolioDocxPackageInspectionLimits, type FolioDocxPackagePart, type FolioDocxPackagePartKind, type FolioDocxPreparedXmlReplacement, FolioDocxReviewer, type FolioDocxReviewerOptions, type FolioDocxXmlPatchApplication, FolioDocxXmlPatchApplicationError, type FolioDocxXmlPatchApplicationReceipt, type FolioDocxXmlPatchProposal, type FolioDocxXmlPatchProposalEvaluation, type FolioDocxXmlPatchProposalIssue, type FolioDocxXmlPatchProposalIssueCode, type FolioDocxXmlPatchProposalLimits, type FolioDocxXmlReplacement, type FolioEditableDocumentStoryHandle, type FolioFormatProperty, type FolioMetadataDiff, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeFilter, type FolioReviewChangeKind, type FolioReviewComment, type FolioReviewCommentFilter, type FolioReviewCommentReply, type FolioReviewReplyInput, type FolioReviewedStory, type FolioReviewedView, type FolioStoryDiff, type FolioVersionBlockHandle, type FolioVersionComparisonPrivacyTransform, type FolioVersionComparisonScope, type FolioVersionDiff, type FolioVersionDiffPrivacyOptions, type FolioVersionDiffPrivacyReport, type FolioVersionDiffSegment, type FolioVersionDiffSummaryCounts, FolioYjsDocxMaterializationError, type FolioYjsDocxMaterializationErrorCode, type GenerateRedlineDocxOptions, type GenerateRedlineDocxResult, type GenerateRedlineUnprocessedStory, HEADING_LEVELS, type HeadingLevel, type InspectDocxPackageOptions, InvalidBilingualDocumentOptionsError, InvalidFolioDocumentOperationBatchError, InvalidFolioDocumentPrivacyOptionsError, InvalidFolioDocxXmlPatchProposalError, InvalidFolioDocxXmlPatchProposalOptionsError, InvalidFolioReportBuilderOptionsError, InvalidFolioVersionComparisonOptionsError, InvalidGenerateRedlineDocxOptionsError, type MaterializeYjsDocxOptions, type ParseOptions, type RewriteDocxMetadataPrivacyResult, STELLA_STYLE_SET_NAME, type TableCellSpec, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioDocxXmlPatchApplicationProfileError, UnsupportedFolioReviewedViewError, type ValidateDocxConformanceOptions, applyDocxXmlPatchProposal, applyFolioAIEditsToBuffer, applyFolioVersionDiffPrivacy, assertSupportedFolioDocumentOperationVersion, bookmark, compareDocxVersions, createBilingualDocument, createBilingualDocx, createDocx, createEmptyDocument, createFolioAITextRangeHandle, createStellaStyleDocumentPreset, createStellaStyleSet, createTableOfContentsField, deriveBlockId, docxToMarkdown, endnote, ensureParaIds, evaluateDocxXmlPatchProposal, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractDocxText, generateRedlineDocx, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, hashFolioAIBlockText, heading, hyperlink, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxPackage, isFolioBlockId, isFolioDocumentOperationModeSupported, isFolioDocumentPrivacyTransform, isFolioResolvedReviewedView, isFolioReviewedView, isFolioVersionComparisonPrivacyTransform, isFolioVersionComparisonScope, isSequentialFolioBlockId, isSupportedFolioDocumentOperationVersion, materializeYjsDocx, normalizeFolioAIBlockText, pageBreak, paragraph, parseDocx, parseFolioDocumentOperationBatch, parseFolioDocxXmlPatchProposal, readBilingualDocument, readBilingualDocx, readFolioDocumentSection, replyToComment, rewriteDocxMetadataPrivacy, run, table, validateDocxConformance };
|
|
30
|
+
export { type ApplyDocxXmlPatchProposalArgs, type ApplyFolioAIEditsToBufferOptions, type ApplyFolioAIEditsToBufferResult, BILINGUAL_TABLE_LAYOUTS, type BilingualBorders, type BilingualParagraphRef, type BilingualRow, type BilingualRowKind, type BilingualTableLayout, type BilingualTableParagraphRef, type CreateBilingualDocumentOptions, type CreateBilingualDocumentResult, type CreateBilingualDocxOptions, type CreateBilingualDocxResult, type CreateCommentReplyInput, type CreateEmptyDocumentOptions, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, type DeriveBlockIdInput, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, DocxArchiveError, type DocxArchiveOptions, type DocxParagraphSource, type DocxTableRowKind, type DocxTableRowPosition, EnsureParaIdsError, type EnsureParaIdsOptions, type EnsureParaIdsResult, type EvaluateDocxXmlPatchProposalArgs, type ExtractDocumentStyleSetOptions, type ExtractedDocxParagraph, type ExtractedDocxTableCell, type ExtractedDocxTableCellParagraph, type ExtractedDocxText, FOLIO_DOCUMENT_METADATA_PROPERTIES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_DOCUMENT_PRIVACY_TRANSFORMS, FOLIO_DOCX_CONFORMANCE_CHECKS, FOLIO_DOCX_CONFORMANCE_ISSUE_CODES, FOLIO_DOCX_CONFORMANCE_PROFILE, FOLIO_DOCX_CONFORMANCE_REPORT_VERSION, FOLIO_DOCX_PACKAGE_INSPECTION_DEFAULTS, FOLIO_DOCX_PACKAGE_INSPECTION_ERROR_CODES, FOLIO_DOCX_PACKAGE_INSPECTION_VERSION, FOLIO_DOCX_XML_PATCH_APPLICATION_PROFILE, FOLIO_DOCX_XML_PATCH_APPLICATION_VERSION, FOLIO_DOCX_XML_PATCH_PROPOSAL_DEFAULTS, FOLIO_DOCX_XML_PATCH_PROPOSAL_ISSUE_CODES, FOLIO_DOCX_XML_PATCH_PROPOSAL_PROFILE, FOLIO_DOCX_XML_PATCH_PROPOSAL_VERSION, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FOLIO_VERSION_COMPARISON_PRIVACY_TRANSFORMS, FOLIO_VERSION_COMPARISON_SCOPES, FOLIO_YJS_DOCX_MATERIALIZATION_ERROR_CODES, FOLIO_YJS_PROSEMIRROR_FRAGMENT_NAME, FOLIO_YJS_UPDATE_MAX_BYTES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditSnapshot, type FolioAIInlineFormatting, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsOptions, type FolioApplyDocumentOperationsToStoryOptions, type FolioApplyOperationsOptions, type FolioBlockDiff, type FolioBlockId, type FolioCompareDocxVersionsOptions, type FolioDocumentMetadataProperty, type FolioDocumentMetadataValue, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationBatchPrecondition, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationQueuedOperation, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, FolioDocumentPrivacyArchiveError, type FolioDocumentPrivacyOptions, type FolioDocumentPrivacyReport, type FolioDocumentPrivacyTransform, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioDocxConformanceCheck, type FolioDocxConformanceCheckId, type FolioDocxConformanceCheckStatus, type FolioDocxConformanceIssue, type FolioDocxConformanceIssueCode, type FolioDocxConformanceReport, type FolioDocxConformanceStatus, type FolioDocxInspectedXmlPart, type FolioDocxPackageInspection, FolioDocxPackageInspectionError, type FolioDocxPackageInspectionErrorCode, type FolioDocxPackageInspectionLimits, type FolioDocxPackagePart, type FolioDocxPackagePartKind, type FolioDocxPreparedXmlReplacement, FolioDocxReviewer, type FolioDocxReviewerOptions, type FolioDocxXmlPatchApplication, FolioDocxXmlPatchApplicationError, type FolioDocxXmlPatchApplicationReceipt, type FolioDocxXmlPatchProposal, type FolioDocxXmlPatchProposalEvaluation, type FolioDocxXmlPatchProposalIssue, type FolioDocxXmlPatchProposalIssueCode, type FolioDocxXmlPatchProposalLimits, type FolioDocxXmlReplacement, type FolioEditableDocumentStoryHandle, type FolioFormatProperty, type FolioMetadataDiff, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeFilter, type FolioReviewChangeKind, type FolioReviewComment, type FolioReviewCommentFilter, type FolioReviewCommentReply, type FolioReviewReplyInput, type FolioReviewedStory, type FolioReviewedView, type FolioStoryDiff, type FolioVersionBlockHandle, type FolioVersionComparisonPrivacyTransform, type FolioVersionComparisonScope, type FolioVersionDiff, type FolioVersionDiffPrivacyOptions, type FolioVersionDiffPrivacyReport, type FolioVersionDiffSegment, type FolioVersionDiffSummaryCounts, FolioYjsDocxMaterializationError, type FolioYjsDocxMaterializationErrorCode, type GenerateRedlineDocxOptions, type GenerateRedlineDocxResult, type GenerateRedlineUnprocessedStory, HEADING_LEVELS, type HeadingLevel, type InspectDocxPackageOptions, InvalidBilingualDocumentOptionsError, InvalidFolioDocumentOperationBatchError, InvalidFolioDocumentPrivacyOptionsError, InvalidFolioDocxXmlPatchProposalError, InvalidFolioDocxXmlPatchProposalOptionsError, InvalidFolioReportBuilderOptionsError, InvalidFolioVersionComparisonOptionsError, InvalidGenerateRedlineDocxOptionsError, type MaterializeYjsDocxOptions, type ParseOptions, type RewriteDocxMetadataPrivacyResult, STELLA_STYLE_SET_NAME, type TableCellSpec, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioDocxXmlPatchApplicationProfileError, UnsupportedFolioReviewedViewError, type ValidateDocxConformanceOptions, applyDocxXmlPatchProposal, applyFolioAIEditsToBuffer, applyFolioVersionDiffPrivacy, assertSupportedFolioDocumentOperationVersion, bookmark, compareDocxVersions, createBilingualDocument, createBilingualDocx, createDocx, createEmptyDocument, createFolioAITextRangeHandle, createStellaStyleDocumentPreset, createStellaStyleSet, createTableOfContentsField, deriveBlockId, docxToMarkdown, endnote, ensureParaIds, evaluateDocxXmlPatchProposal, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractDocxText, generateRedlineDocx, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, hashFolioAIBlockText, heading, hyperlink, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxPackage, isFolioBlockId, isFolioDocumentOperationModeSupported, isFolioDocumentPrivacyTransform, isFolioResolvedReviewedView, isFolioReviewedView, isFolioVersionComparisonPrivacyTransform, isFolioVersionComparisonScope, isSequentialFolioBlockId, isSupportedFolioDocumentOperationVersion, materializeYjsDocx, normalizeFolioAIBlockText, pageBreak, paragraph, parseDocx, parseFolioDocumentOperationBatch, parseFolioDocxXmlPatchProposal, readBilingualDocument, readBilingualDocx, readFolioDocumentSection, replyToComment, rewriteDocxMetadataPrivacy, run, table, validateDocxConformance };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { sanitizeExternalUrl } from "@stll/docx-core";
|
|
1
2
|
//#region src/utils/urlSecurity.d.ts
|
|
2
|
-
declare function sanitizeExternalUrl(rawUrl: string | undefined): string | undefined;
|
|
3
3
|
declare function normalizeUserUrl(rawUrl: string): string;
|
|
4
4
|
declare function isAllowedUserUrl(rawUrl: string): boolean;
|
|
5
5
|
declare function sanitizeLinkTarget(target: string | undefined): string;
|
|
@@ -1,29 +1,11 @@
|
|
|
1
|
+
import { sanitizeExternalUrl } from "@stll/docx-core";
|
|
1
2
|
//#region src/utils/urlSecurity.ts
|
|
2
|
-
const ALLOWED_URL_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
3
|
-
"http:",
|
|
4
|
-
"https:",
|
|
5
|
-
"mailto:",
|
|
6
|
-
"tel:"
|
|
7
|
-
]);
|
|
8
3
|
const ALLOWED_TARGETS = /* @__PURE__ */ new Set([
|
|
9
4
|
"_blank",
|
|
10
5
|
"_self",
|
|
11
6
|
"_parent",
|
|
12
7
|
"_top"
|
|
13
8
|
]);
|
|
14
|
-
function sanitizeExternalUrl(rawUrl) {
|
|
15
|
-
if (!rawUrl) return;
|
|
16
|
-
const trimmed = rawUrl.trim();
|
|
17
|
-
if (!trimmed) return;
|
|
18
|
-
try {
|
|
19
|
-
const parsed = new URL(trimmed);
|
|
20
|
-
if (!ALLOWED_URL_PROTOCOLS.has(parsed.protocol)) return;
|
|
21
|
-
if ((parsed.protocol === "mailto:" || parsed.protocol === "tel:") && parsed.pathname.trim() === "") return;
|
|
22
|
-
return parsed.href;
|
|
23
|
-
} catch {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
9
|
function normalizeUserUrl(rawUrl) {
|
|
28
10
|
const trimmed = rawUrl.trim();
|
|
29
11
|
if (!trimmed) return "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.2",
|
|
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",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"perf": "bun scripts/profile-editor.ts"
|
|
114
114
|
},
|
|
115
115
|
"dependencies": {
|
|
116
|
-
"@stll/docx-core": "^0.
|
|
116
|
+
"@stll/docx-core": "^0.18.0",
|
|
117
117
|
"@stll/docx-utils": "^0.1.0",
|
|
118
118
|
"@stll/template-conditions": "^0.1.0",
|
|
119
119
|
"better-result": "3.0.1",
|
|
@@ -122,7 +122,6 @@
|
|
|
122
122
|
"fast-xml-parser": "^5.10.1",
|
|
123
123
|
"hyphen": "1.14.1",
|
|
124
124
|
"jszip": "3.10.1",
|
|
125
|
-
"marked": "^18.0.5",
|
|
126
125
|
"prosemirror-commands": "^1.7.1",
|
|
127
126
|
"prosemirror-dropcursor": "^1.8.2",
|
|
128
127
|
"prosemirror-gapcursor": "^1.4.1",
|