@json-to-office/shared-docx 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/{chunk-PVZMPANS.js → chunk-436TK3T4.js} +622 -452
  2. package/dist/chunk-436TK3T4.js.map +1 -0
  3. package/dist/{chunk-LQGORQQI.js → chunk-CQHH44HX.js} +29 -23
  4. package/dist/chunk-CQHH44HX.js.map +1 -0
  5. package/dist/{chunk-QDBFYGOR.js → chunk-FG6SI4JG.js} +14 -3
  6. package/dist/chunk-FG6SI4JG.js.map +1 -0
  7. package/dist/{chunk-UNNSBEER.js → chunk-K7PV4XUA.js} +2 -2
  8. package/dist/chunk-K7PV4XUA.js.map +1 -0
  9. package/dist/{chunk-BDVZALLE.js → chunk-NJN6UT3A.js} +56 -3
  10. package/dist/chunk-NJN6UT3A.js.map +1 -0
  11. package/dist/{chunk-R5UGQRFE.js → chunk-PSVJL2G3.js} +2 -2
  12. package/dist/{chunk-I7HBLM3U.js → chunk-SZCMTHGI.js} +2 -2
  13. package/dist/{chunk-XDMC32YP.js → chunk-VRGM2FUX.js} +6 -6
  14. package/dist/chunk-VRGM2FUX.js.map +1 -0
  15. package/dist/{chunk-WAKSQXQA.js → chunk-Y2ME2XH6.js} +2 -2
  16. package/dist/{chunk-5QOQVYBJ.js → chunk-Z5WQPM4B.js} +3 -3
  17. package/dist/index.d.ts +173 -16
  18. package/dist/index.js +295 -16
  19. package/dist/index.js.map +1 -1
  20. package/dist/schemas/api.d.ts +6 -0
  21. package/dist/schemas/api.js +5 -5
  22. package/dist/schemas/component-defaults.d.ts +76 -29
  23. package/dist/schemas/component-defaults.js +3 -1
  24. package/dist/schemas/component-registry.js +3 -3
  25. package/dist/schemas/components.d.ts +354 -29
  26. package/dist/schemas/components.js +18 -4
  27. package/dist/schemas/document.js +6 -6
  28. package/dist/schemas/export.js +4 -4
  29. package/dist/schemas/generator.js +4 -4
  30. package/dist/schemas/theme.d.ts +298 -14
  31. package/dist/schemas/theme.js +2 -2
  32. package/dist/validation/unified/index.d.ts +192 -23
  33. package/dist/validation/unified/index.js +8 -6
  34. package/package.json +2 -2
  35. package/dist/chunk-BDVZALLE.js.map +0 -1
  36. package/dist/chunk-LQGORQQI.js.map +0 -1
  37. package/dist/chunk-PVZMPANS.js.map +0 -1
  38. package/dist/chunk-QDBFYGOR.js.map +0 -1
  39. package/dist/chunk-UNNSBEER.js.map +0 -1
  40. package/dist/chunk-XDMC32YP.js.map +0 -1
  41. /package/dist/{chunk-R5UGQRFE.js.map → chunk-PSVJL2G3.js.map} +0 -0
  42. /package/dist/{chunk-I7HBLM3U.js.map → chunk-SZCMTHGI.js.map} +0 -0
  43. /package/dist/{chunk-WAKSQXQA.js.map → chunk-Y2ME2XH6.js.map} +0 -0
  44. /package/dist/{chunk-5QOQVYBJ.js.map → chunk-Z5WQPM4B.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generateUnifiedDocumentSchema
3
- } from "./chunk-R5UGQRFE.js";
3
+ } from "./chunk-PSVJL2G3.js";
4
4
  import {
5
5
  ERROR_TEMPLATES,
6
6
  componentValidator,
@@ -31,19 +31,20 @@ import {
31
31
  validateTheme,
32
32
  validateThemeJson,
33
33
  validateThemeWithEnhancement
34
- } from "./chunk-XDMC32YP.js";
34
+ } from "./chunk-VRGM2FUX.js";
35
35
  import {
36
36
  GenerateDocumentRequestSchema,
37
37
  GenerateDocumentResponseSchema,
38
38
  ValidateDocumentRequestSchema,
39
39
  ValidateDocumentResponseSchema
40
- } from "./chunk-QDBFYGOR.js";
40
+ } from "./chunk-FG6SI4JG.js";
41
41
  import {
42
42
  JSON_SCHEMA_URLS,
43
43
  JsonComponentDefinitionSchema
44
- } from "./chunk-I7HBLM3U.js";
44
+ } from "./chunk-SZCMTHGI.js";
45
45
  import {
46
46
  collectIndentConflicts,
47
+ collectNoteRevisionConflicts,
47
48
  comprehensiveValidateDocument,
48
49
  createDocumentValidator,
49
50
  createJsonValidator,
@@ -64,11 +65,11 @@ import {
64
65
  validateJsonComponent,
65
66
  validateJsonDocument,
66
67
  validateWithEnhancement
67
- } from "./chunk-BDVZALLE.js";
68
+ } from "./chunk-NJN6UT3A.js";
68
69
  import {
69
70
  ComponentDefinitionSchema,
70
71
  StandardComponentDefinitionSchema
71
- } from "./chunk-UNNSBEER.js";
72
+ } from "./chunk-K7PV4XUA.js";
72
73
  import {
73
74
  CustomComponentDefinitionSchema,
74
75
  TextSpaceAfterComponentSchema,
@@ -82,37 +83,47 @@ import {
82
83
  createComponentSchema,
83
84
  exportSchemaToFile,
84
85
  fixSchemaReferences
85
- } from "./chunk-WAKSQXQA.js";
86
+ } from "./chunk-Y2ME2XH6.js";
86
87
  import {
87
88
  HighchartsPropsSchema,
88
89
  ReportPropsSchema,
90
+ STANDARD_COMPONENTS_REGISTRY,
89
91
  TextBoxPropsSchema,
90
92
  TocPropsSchema,
91
93
  VisualCanvasBackgroundSchema,
92
94
  VisualCanvasSchema,
93
- VisualPropsSchema
94
- } from "./chunk-5QOQVYBJ.js";
95
+ VisualPropsSchema,
96
+ getAllStandardComponentNames,
97
+ getStandardComponent
98
+ } from "./chunk-Z5WQPM4B.js";
95
99
  import {
96
100
  ThemeConfigSchema,
97
101
  createMinimalTheme,
98
102
  isValidThemeConfig
99
- } from "./chunk-LQGORQQI.js";
103
+ } from "./chunk-CQHH44HX.js";
100
104
  import {
101
105
  AlignmentSchema,
102
106
  BaseComponentPropsSchema,
103
107
  BorderSchema,
104
108
  ColumnsPropsSchema,
109
+ CommentReplySchema,
110
+ CommentSchema,
111
+ EndnotesSchema,
112
+ FootnotesSchema,
105
113
  HeadingLevelSchema,
106
114
  HeadingPropsSchema,
107
115
  ImagePropsSchema,
108
116
  IndentSchema,
109
117
  JustifiedAlignmentSchema,
110
118
  LineSpacingSchema,
119
+ ListMarkerFontSchema,
111
120
  ListPropsSchema,
112
121
  MarginsSchema,
122
+ NoteSchema,
113
123
  NumberingSchema,
114
124
  ParagraphIndentSchema,
115
125
  ParagraphPropsSchema,
126
+ RevisionMarkSchema,
116
127
  RevisionSchema,
117
128
  RevisionSegmentSchema,
118
129
  SectionPropsSchema,
@@ -123,7 +134,7 @@ import {
123
134
  TabStopTypeSchema,
124
135
  TabStopsSchema,
125
136
  TablePropsSchema
126
- } from "./chunk-PVZMPANS.js";
137
+ } from "./chunk-436TK3T4.js";
127
138
  import "./chunk-7TTAAYQ5.js";
128
139
 
129
140
  // src/diff/word-diff.ts
@@ -394,8 +405,8 @@ function diffTextComponent(oldNode, newNode, path, ctx) {
394
405
  const oldText = plainText(oldNode);
395
406
  const newText = plainText(newNode);
396
407
  const propsChanged = !deepEqual(
397
- propsWithout(oldNode.props, "text", "revision"),
398
- propsWithout(newNode.props, "text", "revision")
408
+ propsWithout(oldNode.props, "text", "revision", "comment"),
409
+ propsWithout(newNode.props, "text", "revision", "comment")
399
410
  );
400
411
  if (propsChanged) {
401
412
  ctx.summary.untracked.push({
@@ -432,12 +443,28 @@ function diffTextComponent(oldNode, newNode, path, ctx) {
432
443
  return {
433
444
  ...newNode,
434
445
  props: {
435
- ...newNode.props,
446
+ ...revisedTextProps(newNode, path, ctx),
436
447
  text: newText,
437
448
  revision: makeRevision(ctx, segments)
438
449
  }
439
450
  };
440
451
  }
452
+ function revisedTextProps(node, path, ctx) {
453
+ const props = { ...node.props ?? {} };
454
+ const dropped = ["footnotes", "endnotes"].filter((kind) => {
455
+ const notes = props[kind];
456
+ return Array.isArray(notes) && notes.length > 0;
457
+ });
458
+ if (dropped.length === 0) return props;
459
+ for (const kind of dropped) delete props[kind];
460
+ ctx.summary.untracked.push({
461
+ path,
462
+ kind: "modified",
463
+ component: node.name,
464
+ detail: `${dropped.join(" and ")} dropped from a tracked-change paragraph (note markers do not resolve inside revision text); the note bodies are not in the redline`
465
+ });
466
+ return props;
467
+ }
441
468
  function insertedTextComponent(node, path, ctx) {
442
469
  ctx.summary.tracked.inserted++;
443
470
  const text = plainText(node);
@@ -446,7 +473,7 @@ function insertedTextComponent(node, path, ctx) {
446
473
  return {
447
474
  ...node,
448
475
  props: {
449
- ...node.props,
476
+ ...revisedTextProps(node, path, ctx),
450
477
  text,
451
478
  revision: makeRevision(ctx, segments)
452
479
  }
@@ -460,7 +487,7 @@ function deletedTextComponent(node, path, ctx) {
460
487
  return {
461
488
  ...node,
462
489
  props: {
463
- ...node.props,
490
+ ...revisedTextProps(node, path, ctx),
464
491
  text: "",
465
492
  revision: makeRevision(ctx, segments)
466
493
  }
@@ -579,6 +606,238 @@ function listWithAllItems(node, type, ctx) {
579
606
  }));
580
607
  return { ...node, props: { ...node.props, items } };
581
608
  }
609
+ function cellText(cell) {
610
+ if (!cell) return "";
611
+ const content = cell.content;
612
+ if (typeof content === "string")
613
+ return stripMarkdown(content.normalize("NFC"));
614
+ if (content && typeof content === "object") {
615
+ const props = content.props;
616
+ const text = props?.text;
617
+ if (typeof text === "string") return stripMarkdown(text.normalize("NFC"));
618
+ }
619
+ return "";
620
+ }
621
+ function cellRawText(cell) {
622
+ if (!cell) return "";
623
+ const content = cell.content;
624
+ if (typeof content === "string") return content.normalize("NFC");
625
+ if (content && typeof content === "object") {
626
+ const text = content.props?.text;
627
+ if (typeof text === "string") return text.normalize("NFC");
628
+ }
629
+ return "";
630
+ }
631
+ function isTextCell(cell) {
632
+ if (!cell) return true;
633
+ const content = cell.content;
634
+ if (content === void 0 || typeof content === "string") return true;
635
+ return typeof content === "object" && content.name === "paragraph";
636
+ }
637
+ function toRowView(node) {
638
+ const columns = node.props?.columns ?? [];
639
+ const rowCount = columns.reduce(
640
+ (max, column) => Math.max(max, column.cells?.length ?? 0),
641
+ 0
642
+ );
643
+ const authoredRows = node.props?.rows ?? [];
644
+ return Array.from({ length: rowCount }, (_, rowIndex) => {
645
+ const cells = columns.map((column) => column.cells?.[rowIndex]);
646
+ return {
647
+ cells,
648
+ key: cells.map(cellText).join("\0"),
649
+ rawKey: cells.map(cellRawText).join("\0"),
650
+ rowProps: authoredRows[rowIndex]
651
+ };
652
+ });
653
+ }
654
+ function withRows(node, rows, rowProps) {
655
+ const columns = node.props?.columns ?? [];
656
+ const merged = rows.map((row, index) => ({
657
+ ...row.rowProps ?? {},
658
+ ...rowProps[index]
659
+ }));
660
+ return {
661
+ ...node,
662
+ props: {
663
+ ...node.props,
664
+ columns: columns.map((column, colIndex) => ({
665
+ ...column,
666
+ cells: rows.map((row) => row.cells[colIndex] ?? { content: "" })
667
+ })),
668
+ ...merged.some((props) => Object.keys(props).length > 0) && {
669
+ rows: merged
670
+ }
671
+ }
672
+ };
673
+ }
674
+ function isColumnTable(node) {
675
+ return Array.isArray(node.props?.columns) && !node.props?.headers;
676
+ }
677
+ function revisedCell(cell, oldCell, oldText, newText, path, ctx) {
678
+ const segments = diffWords(oldText, newText);
679
+ notePlaceholdersInChanges(segments, path, "table", ctx);
680
+ if (cellRawText(oldCell) !== oldText || cellRawText(cell) !== newText) {
681
+ ctx.summary.untracked.push({
682
+ path,
683
+ kind: "modified",
684
+ component: "table",
685
+ detail: "inline formatting or links flattened to plain text in a table cell (revision segments render literally)"
686
+ });
687
+ }
688
+ const base = cell ?? { content: "" };
689
+ return {
690
+ ...base,
691
+ // The revision carries the text, so `content` keeps the new version for
692
+ // readers that ignore tracked changes. A component cell keeps being a
693
+ // component — replacing it with a bare string would silently discard the
694
+ // paragraph's font, alignment and the rest.
695
+ content: revisedCellContent(base.content, newText, path, ctx),
696
+ revision: makeRevision(ctx, segments)
697
+ };
698
+ }
699
+ function revisedCellContent(content, newText, path, ctx) {
700
+ if (!content || typeof content !== "object") return newText;
701
+ const component = content;
702
+ return {
703
+ ...component,
704
+ props: {
705
+ ...revisedTextProps(component, path, ctx),
706
+ text: newText
707
+ }
708
+ };
709
+ }
710
+ function diffTableComponent(oldNode, newNode, path, ctx) {
711
+ const oldRows = toRowView(oldNode);
712
+ const newRows = toRowView(newNode);
713
+ const oldColumns = oldNode.props?.columns ?? [];
714
+ const newColumns = newNode.props?.columns ?? [];
715
+ if (oldColumns.length !== newColumns.length) {
716
+ ctx.summary.untracked.push({
717
+ path,
718
+ kind: "modified",
719
+ component: "table",
720
+ detail: "table column count changed (columns are not expressible as a tracked change); new version rendered"
721
+ });
722
+ return newNode;
723
+ }
724
+ const propsChanged = !deepEqual(
725
+ propsWithout(oldNode.props, "columns", "rows"),
726
+ propsWithout(newNode.props, "columns", "rows")
727
+ );
728
+ if (propsChanged) {
729
+ ctx.summary.untracked.push({
730
+ path,
731
+ kind: "modified",
732
+ component: "table",
733
+ detail: "table configuration changed (borders/widths/defaults); new version rendered"
734
+ });
735
+ }
736
+ const headersChanged = !deepEqual(
737
+ oldColumns.map((column) => column.header),
738
+ newColumns.map((column) => column.header)
739
+ );
740
+ if (headersChanged) {
741
+ ctx.summary.untracked.push({
742
+ path,
743
+ kind: "modified",
744
+ component: "table",
745
+ detail: "table header row changed (headers are not row content); new version rendered"
746
+ });
747
+ }
748
+ if (deepEqual(
749
+ oldRows.map((row) => row.key),
750
+ newRows.map((row) => row.key)
751
+ )) {
752
+ if (!deepEqual(
753
+ oldRows.map((row) => row.rawKey),
754
+ newRows.map((row) => row.rawKey)
755
+ )) {
756
+ ctx.summary.untracked.push({
757
+ path,
758
+ kind: "modified",
759
+ component: "table",
760
+ detail: "inline formatting or link target changed in table cells (markdown-only); new version rendered without a tracked change"
761
+ });
762
+ } else if (!propsChanged && !headersChanged && deepEqual(oldRows, newRows)) {
763
+ ctx.summary.unchangedBlocks++;
764
+ }
765
+ return newNode;
766
+ }
767
+ const ops = alignByLcs(oldRows, newRows, (row) => row.key);
768
+ const outRows = [];
769
+ const outProps = [];
770
+ let changed = false;
771
+ const push = (row, props) => {
772
+ outRows.push(row);
773
+ outProps.push(props);
774
+ };
775
+ let k = 0;
776
+ while (k < ops.length) {
777
+ const op = ops[k];
778
+ if (op.op === "equal") {
779
+ push(op.newItem, {});
780
+ k++;
781
+ continue;
782
+ }
783
+ const deleted = [];
784
+ const inserted = [];
785
+ while (k < ops.length && ops[k].op !== "equal") {
786
+ const gapOp = ops[k];
787
+ if (gapOp.op === "delete") deleted.push(gapOp.oldItem);
788
+ else if (gapOp.op === "insert") inserted.push(gapOp.newItem);
789
+ k++;
790
+ }
791
+ const { plan } = pairGap(
792
+ deleted,
793
+ inserted,
794
+ (oldRow, newRow) => oldRow.cells.length === newRow.cells.length && oldRow.cells.every(isTextCell) && newRow.cells.every(isTextCell)
795
+ );
796
+ for (const step of plan) {
797
+ changed = true;
798
+ if (step.kind === "paired") {
799
+ const cells = step.newItem.cells.map((cell, index) => {
800
+ const oldText = cellText(step.oldItem.cells[index]);
801
+ const newText = cellText(cell);
802
+ return oldText === newText ? cell ?? { content: "" } : revisedCell(
803
+ cell,
804
+ step.oldItem.cells[index],
805
+ oldText,
806
+ newText,
807
+ path,
808
+ ctx
809
+ );
810
+ });
811
+ push({ ...step.newItem, cells }, {});
812
+ } else if (step.kind === "inserted") {
813
+ ctx.summary.tracked.inserted++;
814
+ push(step.newItem, { revision: rowRevision(ctx, "insert") });
815
+ } else {
816
+ ctx.summary.tracked.deleted++;
817
+ push(step.oldItem, { revision: rowRevision(ctx, "delete") });
818
+ }
819
+ }
820
+ }
821
+ if (changed) ctx.summary.tracked.modified++;
822
+ return withRows(newNode, outRows, outProps);
823
+ }
824
+ function tableWithAllRows(node, type, ctx) {
825
+ if (type === "insert") ctx.summary.tracked.inserted++;
826
+ else ctx.summary.tracked.deleted++;
827
+ const rows = toRowView(node);
828
+ return withRows(
829
+ node,
830
+ rows,
831
+ rows.map(() => ({ revision: rowRevision(ctx, type) }))
832
+ );
833
+ }
834
+ function rowRevision(ctx, type) {
835
+ return {
836
+ type,
837
+ ...ctx.author && { author: ctx.author },
838
+ ...ctx.date && { date: ctx.date }
839
+ };
840
+ }
582
841
  function isContainer(node) {
583
842
  return Array.isArray(node.children);
584
843
  }
@@ -605,6 +864,9 @@ function diffPairedNode(oldNode, newNode, path, ctx) {
605
864
  if (newNode.name === "list") {
606
865
  return diffListComponent(oldNode, newNode, path, ctx);
607
866
  }
867
+ if (newNode.name === "table" && isColumnTable(oldNode) && isColumnTable(newNode)) {
868
+ return diffTableComponent(oldNode, newNode, path, ctx);
869
+ }
608
870
  if (isContainer(newNode) || isContainer(oldNode)) {
609
871
  const propsChanged = !deepEqual(oldNode.props, newNode.props);
610
872
  if (propsChanged) {
@@ -643,6 +905,9 @@ function emitInserted(node, path, ctx) {
643
905
  if (node.name === "list") {
644
906
  return listWithAllItems(node, "insert", ctx);
645
907
  }
908
+ if (node.name === "table" && isColumnTable(node)) {
909
+ return tableWithAllRows(node, "insert", ctx);
910
+ }
646
911
  if (isContainer(node)) {
647
912
  if (typeof node.props?.title === "string") {
648
913
  ctx.summary.untracked.push({
@@ -675,6 +940,9 @@ function emitDeleted(node, path, ctx) {
675
940
  if (node.name === "list") {
676
941
  return listWithAllItems(node, "delete", ctx);
677
942
  }
943
+ if (node.name === "table" && isColumnTable(node)) {
944
+ return tableWithAllRows(node, "delete", ctx);
945
+ }
678
946
  if (isContainer(node)) {
679
947
  if (typeof node.props?.title === "string") {
680
948
  ctx.summary.untracked.push({
@@ -1644,11 +1912,15 @@ export {
1644
1912
  BorderSchema,
1645
1913
  COMPONENT_METADATA,
1646
1914
  ColumnsPropsSchema,
1915
+ CommentReplySchema,
1916
+ CommentSchema,
1647
1917
  ComponentDefinitionSchema,
1648
1918
  CustomComponentDefinitionSchema,
1649
1919
  DEFAULT_ERROR_CONFIG,
1650
1920
  ERROR_EMOJIS,
1651
1921
  ERROR_TEMPLATES,
1922
+ EndnotesSchema,
1923
+ FootnotesSchema,
1652
1924
  GenerateDocumentRequestSchema,
1653
1925
  GenerateDocumentResponseSchema,
1654
1926
  HeadingLevelSchema,
@@ -1663,16 +1935,20 @@ export {
1663
1935
  JsonValidationError,
1664
1936
  JustifiedAlignmentSchema,
1665
1937
  LineSpacingSchema,
1938
+ ListMarkerFontSchema,
1666
1939
  ListPropsSchema,
1667
1940
  MarginsSchema,
1941
+ NoteSchema,
1668
1942
  NumberingSchema,
1669
1943
  ParagraphIndentSchema,
1670
1944
  ParagraphPropsSchema,
1671
1945
  ReportPropsSchema,
1946
+ RevisionMarkSchema,
1672
1947
  RevisionSchema,
1673
1948
  RevisionSegmentSchema,
1674
1949
  SHARED_DOCX_VERSION,
1675
1950
  STANDARD_COMPONENTS,
1951
+ STANDARD_COMPONENTS_REGISTRY,
1676
1952
  STANDARD_COMPONENTS_SET,
1677
1953
  SectionPropsSchema,
1678
1954
  SpacingSchema,
@@ -1697,6 +1973,7 @@ export {
1697
1973
  calculatePosition,
1698
1974
  clearComponentNamesCache,
1699
1975
  collectIndentConflicts,
1976
+ collectNoteRevisionConflicts,
1700
1977
  compareSemver,
1701
1978
  componentValidator,
1702
1979
  comprehensiveValidateDocument,
@@ -1729,10 +2006,12 @@ export {
1729
2006
  formatValidationErrorStrings,
1730
2007
  formatValidationErrors,
1731
2008
  generateUnifiedDocumentSchema,
2009
+ getAllStandardComponentNames,
1732
2010
  getErrorSummary,
1733
2011
  getLiteralValue,
1734
2012
  getObjectSchemaPropertyNames,
1735
2013
  getSchemaMetadata,
2014
+ getStandardComponent,
1736
2015
  getThemeName,
1737
2016
  getValidationContext,
1738
2017
  getValidationErrors,