@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.
@@ -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 = (count) => {
146
+ const nextRevisionSeed = (revisionIdCount) => {
147
147
  const start = revisionIdCursor;
148
- revisionIdCursor += Math.max(count, 1) * 4;
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
- let revisionSeed = revisionIdSeed ?? nextRevisionSeed(executableResolved.length);
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
- if (mode === "tracked-changes" && item.operation.pageBreakBefore === true && (!item.insertText || item.insertText.length === 0)) {
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 marks = [];
582
- let insertedBlockRevisionId = null;
583
- if (producesTrackedChanges && insertionType) {
584
- const revisionId = revisionSeed++;
585
- insertedBlockRevisionId = revisionId;
586
- marks.push(insertionType.create({
587
- revisionId,
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
- ...trackedRevisionExtras
591
- }));
592
- appliedRevisionIds = [revisionId];
662
+ ...initials ? { initials } : {}
663
+ };
664
+ nodes.push(item.blockNode.type.create(attrs, content));
593
665
  }
594
- if (commentMark) marks.push(commentMark);
595
- const content = item.insertText && item.insertText.length > 0 ? buildEmphasisInlineContent(view.state.schema, item.insertText, marks) : null;
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
- insertText: operation.text
1200
+ insertTexts
1148
1201
  }
1149
1202
  };
1150
1203
  }
@@ -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 };
@@ -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 { sanitizeExternalUrl } from "../utils/urlSecurity.js";
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. Parses the GFM subset skill bodies use
8
- * (headings, paragraphs, bold/italic/strike, inline code, bullet + ordered
9
- * lists incl. nesting, pipe tables, blockquotes, links) into the docx
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 are emitted as real list paragraphs (`listRendering`), so the editor
15
- * shows a marker and {@link toMarkdown} re-derives `- ` / `1. ` rather than
16
- * leaking a literal bullet glyph into the text.
17
- * - Inline code uses `Courier New` a whitelisted monospace family that
18
- * {@link toMarkdown} infers back to a backtick span (Folio renders it via its
19
- * bundled Cousine substitute).
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 numIds = {
263
- next: 1,
264
- levels: /* @__PURE__ */ new Map()
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.0",
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.17.3",
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",