@json-to-office/core-docx 0.12.0 → 0.14.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.
@@ -1 +1 @@
1
- {"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAwB,MAAM,WAAW,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9E,OAAO,KAAK,EAEV,wBAAwB,EAKzB,MAAM,SAAS,CAAC;AAcjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,oFAAoF;IACpF,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAseD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,wBAAwB,CAAC,SAAS,EAAE,CAAC,CAavC"}
1
+ {"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAwB,MAAM,WAAW,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9E,OAAO,KAAK,EAEV,wBAAwB,EAOzB,MAAM,SAAS,CAAC;AAejB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,oFAAoF;IACpF,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAiiBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,wBAAwB,CAAC,SAAS,EAAE,CAAC,CAavC"}
@@ -225,7 +225,7 @@ var init_minimal_docx_theme = __esm({
225
225
  size: 11
226
226
  },
227
227
  mono: {
228
- family: "SF Mono",
228
+ family: "Menlo",
229
229
  size: 10
230
230
  },
231
231
  light: {
@@ -543,7 +543,7 @@ var init_modern_docx_theme = __esm({
543
543
  fonts: {
544
544
  heading: { family: "Helvetica", size: 28 },
545
545
  body: { family: "Helvetica", size: 11 },
546
- mono: { family: "SF Mono", size: 10 },
546
+ mono: { family: "Menlo", size: 10 },
547
547
  light: { family: "Helvetica", size: 28 }
548
548
  },
549
549
  page: {
@@ -1888,7 +1888,8 @@ import {
1888
1888
  } from "@json-to-office/shared-docx/validation/unified";
1889
1889
  import {
1890
1890
  DuplicateComponentError,
1891
- ComponentValidationError as ComponentValidationError2
1891
+ ComponentValidationError as ComponentValidationError2,
1892
+ UnknownPreservedComponentError
1892
1893
  } from "@json-to-office/shared/plugin";
1893
1894
  function validateComponentProps(schema, props, componentName) {
1894
1895
  return validateCustomComponentProps(schema.propsSchema, props, {
@@ -1955,6 +1956,9 @@ function getValidatedProps(schema, props) {
1955
1956
  }
1956
1957
  var cleanComponentProps = getValidatedProps;
1957
1958
 
1959
+ // src/plugin/createDocumentGenerator.ts
1960
+ import { UnknownPreservedComponentError as UnknownPreservedComponentError2 } from "@json-to-office/shared/plugin";
1961
+
1958
1962
  // src/plugin/schema.ts
1959
1963
  import { Type } from "@sinclair/typebox";
1960
1964
  import { latestVersion } from "@json-to-office/shared-docx";
@@ -2199,7 +2203,8 @@ async function processDocument(document, theme, themeName) {
2199
2203
  metadata,
2200
2204
  sections,
2201
2205
  theme: effectiveTheme,
2202
- themeName
2206
+ themeName,
2207
+ trackRevisions: document.props.trackRevisions
2203
2208
  };
2204
2209
  }
2205
2210
  function createDocumentMetadata(props) {
@@ -2658,7 +2663,7 @@ Suggestion: ${suggestion}`
2658
2663
  import {
2659
2664
  Document,
2660
2665
  Paragraph as Paragraph7,
2661
- TextRun as TextRun5,
2666
+ TextRun as TextRun6,
2662
2667
  AlignmentType as AlignmentType5,
2663
2668
  BookmarkStart as BookmarkStart2,
2664
2669
  BookmarkEnd as BookmarkEnd2
@@ -3991,6 +3996,99 @@ var CacheKeyGenerator = class {
3991
3996
  }
3992
3997
  };
3993
3998
 
3999
+ // src/utils/revisionUtils.ts
4000
+ import { TextRun as TextRun3, InsertedTextRun, DeletedTextRun } from "docx";
4001
+ var DEFAULT_REVISION_AUTHOR = "json-to-office";
4002
+ var DEFAULT_REVISION_DATE = "1970-01-01T00:00:00Z";
4003
+ var RevisionIdRegistry = class {
4004
+ counter = 0;
4005
+ next() {
4006
+ this.counter += 1;
4007
+ return this.counter;
4008
+ }
4009
+ /** Test-only: deterministic ids for snapshot assertions. */
4010
+ clear() {
4011
+ this.counter = 0;
4012
+ }
4013
+ };
4014
+ var globalRevisionIdRegistry = new RevisionIdRegistry();
4015
+ var PLACEHOLDER_PATTERN = /\{[^}]+\}/;
4016
+ function segmentRuns(text, makeRun) {
4017
+ const lines = text.split("\n");
4018
+ return lines.map(
4019
+ (line, index) => makeRun(index === 0 ? { text: line } : { text: line, break: 1 })
4020
+ );
4021
+ }
4022
+ function createRevisionRuns(revision, baseStyle) {
4023
+ const author = revision.author || DEFAULT_REVISION_AUTHOR;
4024
+ const date = revision.date || DEFAULT_REVISION_DATE;
4025
+ const runs = [];
4026
+ for (const segment of revision.segments) {
4027
+ if (!segment.text) continue;
4028
+ const text = normalizeUnicodeText(segment.text);
4029
+ if (segment.type === "insert") {
4030
+ runs.push(
4031
+ ...segmentRuns(
4032
+ text,
4033
+ (options) => new InsertedTextRun({
4034
+ ...options,
4035
+ ...baseStyle,
4036
+ id: globalRevisionIdRegistry.next(),
4037
+ author,
4038
+ date
4039
+ })
4040
+ )
4041
+ );
4042
+ } else if (segment.type === "delete") {
4043
+ runs.push(
4044
+ ...segmentRuns(
4045
+ text,
4046
+ (options) => new DeletedTextRun({
4047
+ ...options,
4048
+ ...baseStyle,
4049
+ id: globalRevisionIdRegistry.next(),
4050
+ author,
4051
+ date
4052
+ })
4053
+ )
4054
+ );
4055
+ } else if (PLACEHOLDER_PATTERN.test(text)) {
4056
+ runs.push(
4057
+ ...processTextWithPlaceholders(text, baseStyle, {})
4058
+ );
4059
+ } else {
4060
+ runs.push(
4061
+ ...segmentRuns(
4062
+ text,
4063
+ (options) => new TextRun3({ ...options, ...baseStyle })
4064
+ )
4065
+ );
4066
+ }
4067
+ }
4068
+ return runs;
4069
+ }
4070
+ function componentHasRevision(component) {
4071
+ const props = component.props;
4072
+ if (props) {
4073
+ if (props.revision) return true;
4074
+ const items = props.items;
4075
+ if (Array.isArray(items)) {
4076
+ if (items.some(
4077
+ (item) => typeof item === "object" && item !== null && "revision" in item && item.revision
4078
+ )) {
4079
+ return true;
4080
+ }
4081
+ }
4082
+ }
4083
+ const children = component.children;
4084
+ if (Array.isArray(children)) {
4085
+ return children.some(
4086
+ (child) => typeof child === "object" && child !== null && componentHasRevision(child)
4087
+ );
4088
+ }
4089
+ return false;
4090
+ }
4091
+
3994
4092
  // src/core/cached-render.ts
3995
4093
  import { createHash as createHash2 } from "crypto";
3996
4094
  var componentCache = null;
@@ -4030,7 +4128,7 @@ function initializeComponentCache(cache) {
4030
4128
  }
4031
4129
  }
4032
4130
  async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
4033
- const forceBypassForType = component.name === "toc" || component.name === "section";
4131
+ const forceBypassForType = component.name === "toc" || component.name === "section" || componentHasRevision(component);
4034
4132
  if (!componentCache) {
4035
4133
  initializeComponentCache();
4036
4134
  }
@@ -4069,7 +4167,7 @@ async function renderComponentWithCache(component, theme, themeName, context, by
4069
4167
  // src/core/content.ts
4070
4168
  import {
4071
4169
  Paragraph,
4072
- TextRun as TextRun3,
4170
+ TextRun as TextRun4,
4073
4171
  Table,
4074
4172
  TableRow,
4075
4173
  TableCell,
@@ -4219,24 +4317,43 @@ function createText(content, theme, themeName, options = {}) {
4219
4317
  underline: options.underline ? { type: "single" } : void 0
4220
4318
  }
4221
4319
  };
4222
- const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
4223
- boldColor: options.boldColor,
4224
- enableHyperlinks: true
4225
- });
4226
- if (options.bookmarkId) {
4227
- globalBookmarkRegistry.register(
4228
- options.bookmarkId,
4229
- normalizedContent,
4230
- "paragraph"
4231
- );
4232
- children.push(
4233
- new Bookmark({
4234
- id: options.bookmarkId,
4235
- children: textRuns
4236
- })
4237
- );
4320
+ if (options.revision) {
4321
+ const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);
4322
+ if (options.bookmarkId) {
4323
+ globalBookmarkRegistry.register(
4324
+ options.bookmarkId,
4325
+ normalizedContent,
4326
+ "paragraph"
4327
+ );
4328
+ children.push(
4329
+ new Bookmark({
4330
+ id: options.bookmarkId,
4331
+ children: revisionRuns
4332
+ })
4333
+ );
4334
+ } else {
4335
+ children.push(...revisionRuns);
4336
+ }
4238
4337
  } else {
4239
- children.push(...textRuns);
4338
+ const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
4339
+ boldColor: options.boldColor,
4340
+ enableHyperlinks: true
4341
+ });
4342
+ if (options.bookmarkId) {
4343
+ globalBookmarkRegistry.register(
4344
+ options.bookmarkId,
4345
+ normalizedContent,
4346
+ "paragraph"
4347
+ );
4348
+ children.push(
4349
+ new Bookmark({
4350
+ id: options.bookmarkId,
4351
+ children: textRuns
4352
+ })
4353
+ );
4354
+ } else {
4355
+ children.push(...textRuns);
4356
+ }
4240
4357
  }
4241
4358
  const isFloating = !!options.floating;
4242
4359
  const frameOptions = isFloating && options.floating ? mapFrameOptions(options.floating, theme, themeName) : void 0;
@@ -4357,7 +4474,24 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4357
4474
  underline: options.underline ? { type: "single" } : void 0
4358
4475
  }
4359
4476
  };
4360
- if (options.bookmarkId) {
4477
+ if (options.revision) {
4478
+ const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);
4479
+ if (options.bookmarkId) {
4480
+ globalBookmarkRegistry.register(
4481
+ options.bookmarkId,
4482
+ normalizedText,
4483
+ "heading"
4484
+ );
4485
+ children.push(
4486
+ new Bookmark({
4487
+ id: options.bookmarkId,
4488
+ children: revisionRuns
4489
+ })
4490
+ );
4491
+ } else {
4492
+ children.push(...revisionRuns);
4493
+ }
4494
+ } else if (options.bookmarkId) {
4361
4495
  globalBookmarkRegistry.register(
4362
4496
  options.bookmarkId,
4363
4497
  normalizedText,
@@ -4372,7 +4506,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4372
4506
  headingTextChildren.push(...textRuns);
4373
4507
  } else {
4374
4508
  headingTextChildren.push(
4375
- new TextRun3({ text: normalizedText, ...baseTextStyle })
4509
+ new TextRun4({ text: normalizedText, ...baseTextStyle })
4376
4510
  );
4377
4511
  }
4378
4512
  children.push(
@@ -4389,7 +4523,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4389
4523
  });
4390
4524
  children.push(...textRuns);
4391
4525
  } else {
4392
- children.push(new TextRun3({ text: normalizedText, ...baseTextStyle }));
4526
+ children.push(new TextRun4({ text: normalizedText, ...baseTextStyle }));
4393
4527
  }
4394
4528
  }
4395
4529
  return new Paragraph({
@@ -4529,10 +4663,11 @@ function createList(items, _theme, _themeName, options = {}) {
4529
4663
  items.forEach((item, index) => {
4530
4664
  const itemText = typeof item === "string" ? item : item.text;
4531
4665
  const itemLevel = typeof item === "object" ? item.level || 0 : 0;
4532
- if (!itemText.trim()) {
4666
+ const itemRevision = typeof item === "object" ? item.revision : void 0;
4667
+ if (!itemText.trim() && !itemRevision) {
4533
4668
  return;
4534
4669
  }
4535
- const textRuns = parseTextWithDecorators(
4670
+ const textRuns = itemRevision ? createRevisionRuns(itemRevision, {}) : parseTextWithDecorators(
4536
4671
  itemText,
4537
4672
  {},
4538
4673
  {
@@ -4945,7 +5080,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
4945
5080
  } catch (error) {
4946
5081
  const imageSource = imageComp.props.base64 || imageComp.props.path || "unknown";
4947
5082
  cellChildren = [
4948
- new TextRun3({
5083
+ new TextRun4({
4949
5084
  text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? "..." : ""}]`,
4950
5085
  font: mergedStyle.font,
4951
5086
  size: mergedStyle.size,
@@ -4955,7 +5090,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
4955
5090
  }
4956
5091
  } else {
4957
5092
  cellChildren = [
4958
- new TextRun3({
5093
+ new TextRun4({
4959
5094
  text: `[Unsupported component type: ${cell.name}]`,
4960
5095
  font: mergedStyle.font,
4961
5096
  size: mergedStyle.size,
@@ -5352,7 +5487,9 @@ function renderHeadingComponent(component, theme, themeName) {
5352
5487
  keepNext: config.keepNext,
5353
5488
  keepLines: config.keepLines,
5354
5489
  // Bookmark ID for internal linking
5355
- bookmarkId
5490
+ bookmarkId,
5491
+ // Tracked-change segments (rendered as native Word revisions)
5492
+ revision: config.revision
5356
5493
  }
5357
5494
  );
5358
5495
  return [header];
@@ -5396,7 +5533,7 @@ function parseMarkdownList(text) {
5396
5533
  function renderParagraphComponent(component, theme, themeName) {
5397
5534
  if (!isParagraphComponent(component)) return [];
5398
5535
  const resolvedConfig = component.props;
5399
- const listData = parseMarkdownList(resolvedConfig.text);
5536
+ const listData = resolvedConfig.revision ? null : parseMarkdownList(resolvedConfig.text);
5400
5537
  if (listData) {
5401
5538
  const reference = globalNumberingRegistry.generateReference("markdown-list");
5402
5539
  const levels = [];
@@ -5473,7 +5610,9 @@ function renderParagraphComponent(component, theme, themeName) {
5473
5610
  // Pass keepLines property
5474
5611
  keepLines: resolvedConfig.keepLines,
5475
5612
  // Pass bookmark ID for internal linking
5476
- bookmarkId: resolvedConfig.id
5613
+ bookmarkId: resolvedConfig.id,
5614
+ // Tracked-change segments (rendered as native Word revisions)
5615
+ revision: resolvedConfig.revision
5477
5616
  });
5478
5617
  return [text];
5479
5618
  }
@@ -6103,7 +6242,7 @@ import {
6103
6242
  Paragraph as Paragraph6,
6104
6243
  TableOfContents,
6105
6244
  AlignmentType as AlignmentType4,
6106
- TextRun as TextRun4,
6245
+ TextRun as TextRun5,
6107
6246
  StyleLevel
6108
6247
  } from "docx";
6109
6248
  function parseDepthRange(rawDepth, fieldName, defaultFrom = 1, defaultTo = 3) {
@@ -6158,7 +6297,7 @@ function renderTocComponent(component, theme, context) {
6158
6297
  paragraphs.push(
6159
6298
  new Paragraph6({
6160
6299
  children: [
6161
- new TextRun4({
6300
+ new TextRun5({
6162
6301
  text: componentProps.title,
6163
6302
  bold: true,
6164
6303
  size: 28
@@ -6456,8 +6595,10 @@ async function renderDocument(structure, layout, options) {
6456
6595
  styles: createWordStyles(structure.theme),
6457
6596
  sections,
6458
6597
  features: {
6459
- updateFields: true
6598
+ updateFields: true,
6460
6599
  // Required for TOC fields to update correctly
6600
+ // Word opens the document in review mode (further edits are tracked)
6601
+ ...structure.trackRevisions && { trackRevisions: true }
6461
6602
  },
6462
6603
  // Add numbering configurations if any lists were rendered
6463
6604
  ...numberingConfigs.length > 0 && {
@@ -6502,7 +6643,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, _conte
6502
6643
  elements.push(
6503
6644
  new Paragraph7({
6504
6645
  children: [
6505
- new TextRun5({
6646
+ new TextRun6({
6506
6647
  text: "[IMAGE: Missing path or base64 property]",
6507
6648
  font: getThemeFonts(theme).body.family,
6508
6649
  size: 20,
@@ -6584,7 +6725,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, _conte
6584
6725
  elements.push(
6585
6726
  new Paragraph7({
6586
6727
  children: [
6587
- new TextRun5({
6728
+ new TextRun6({
6588
6729
  text: `[IMAGE: ${imageComp.props.path}]`,
6589
6730
  font: getThemeFonts(theme).body.family,
6590
6731
  size: 20,
@@ -6829,17 +6970,19 @@ function createBuilderImpl(state) {
6829
6970
  }
6830
6971
  return getThemeWithFallback(themeName);
6831
6972
  }
6832
- async function processDocumentComponents(components, warningsCollector, resolvedTheme, depth = 0) {
6973
+ async function processDocumentComponents(components, preserveSet, warningsCollector, resolvedTheme, depth = 0) {
6833
6974
  if (depth > 20) {
6834
6975
  throw new Error(
6835
6976
  "Maximum component nesting depth exceeded (20). Check for circular component references."
6836
6977
  );
6837
6978
  }
6838
- const processedComponents = [];
6979
+ const standardOut = [];
6980
+ const preservedOut = [];
6839
6981
  for (const componentData of components) {
6840
6982
  const componentName = componentData?.name;
6841
6983
  if (!componentName) {
6842
- processedComponents.push(componentData);
6984
+ standardOut.push(componentData);
6985
+ preservedOut.push(componentData);
6843
6986
  continue;
6844
6987
  }
6845
6988
  const customComponent = componentMap.get(componentName);
@@ -6862,12 +7005,14 @@ function createBuilderImpl(state) {
6862
7005
  );
6863
7006
  let nestedChildren;
6864
7007
  if (componentWithName.children && Array.isArray(componentWithName.children)) {
6865
- nestedChildren = await processDocumentComponents(
7008
+ const nested = await processDocumentComponents(
6866
7009
  componentWithName.children,
7010
+ preserveSet,
6867
7011
  warningsCollector,
6868
7012
  resolvedTheme,
6869
7013
  depth + 1
6870
7014
  );
7015
+ nestedChildren = nested.standard;
6871
7016
  }
6872
7017
  const versionLabel = componentWithName.version ? `${customComponent.name}@${componentWithName.version}` : customComponent.name;
6873
7018
  const addWarning = (message, context) => {
@@ -6887,15 +7032,21 @@ function createBuilderImpl(state) {
6887
7032
  const resultComponents = Array.isArray(result) ? result : [result];
6888
7033
  const processedResult = await processDocumentComponents(
6889
7034
  resultComponents,
7035
+ preserveSet,
6890
7036
  warningsCollector,
6891
7037
  resolvedTheme,
6892
7038
  depth + 1
6893
7039
  );
6894
- processedComponents.push(...processedResult);
7040
+ standardOut.push(...processedResult.standard);
7041
+ if (preserveSet && preserveSet.has(componentName)) {
7042
+ preservedOut.push(componentData);
7043
+ } else {
7044
+ preservedOut.push(...processedResult.preserved);
7045
+ }
6895
7046
  if (state.debug) {
6896
7047
  console.log(
6897
7048
  `Processed custom component '${versionLabel}':`,
6898
- processedResult
7049
+ processedResult.standard
6899
7050
  );
6900
7051
  }
6901
7052
  } catch (error) {
@@ -6910,20 +7061,26 @@ function createBuilderImpl(state) {
6910
7061
  if ("children" in componentData && Array.isArray(componentData.children)) {
6911
7062
  const processedNested = await processDocumentComponents(
6912
7063
  componentData.children,
7064
+ preserveSet,
6913
7065
  warningsCollector,
6914
7066
  resolvedTheme,
6915
7067
  depth + 1
6916
7068
  );
6917
- processedComponents.push({
7069
+ standardOut.push({
7070
+ ...componentData,
7071
+ children: processedNested.standard
7072
+ });
7073
+ preservedOut.push({
6918
7074
  ...componentData,
6919
- children: processedNested
7075
+ children: processedNested.preserved
6920
7076
  });
6921
7077
  } else {
6922
- processedComponents.push(componentData);
7078
+ standardOut.push(componentData);
7079
+ preservedOut.push(componentData);
6923
7080
  }
6924
7081
  }
6925
7082
  }
6926
- return processedComponents;
7083
+ return { standard: standardOut, preserved: preservedOut };
6927
7084
  }
6928
7085
  function addComponent(component) {
6929
7086
  if (!component.name) {
@@ -6948,8 +7105,24 @@ function createBuilderImpl(state) {
6948
7105
  newState
6949
7106
  );
6950
7107
  }
6951
- async function generate(document) {
7108
+ function resolvePreserveSet(options) {
7109
+ const list = options?.preserveCustomComponents;
7110
+ if (!list || list.length === 0) {
7111
+ return void 0;
7112
+ }
7113
+ const registered = new Set(state.componentNames);
7114
+ const unknown = list.filter((n) => !registered.has(n));
7115
+ if (unknown.length > 0) {
7116
+ throw new UnknownPreservedComponentError2(
7117
+ unknown,
7118
+ Array.from(state.componentNames)
7119
+ );
7120
+ }
7121
+ return new Set(list);
7122
+ }
7123
+ async function generate(document, options) {
6952
7124
  try {
7125
+ const preserveSet = resolvePreserveSet(options);
6953
7126
  const internalDocument = document;
6954
7127
  validateDocument(
6955
7128
  internalDocument,
@@ -6973,14 +7146,15 @@ function createBuilderImpl(state) {
6973
7146
  context: { code: w.code }
6974
7147
  });
6975
7148
  }
6976
- const processedComponents = await processDocumentComponents(
7149
+ const processed = await processDocumentComponents(
6977
7150
  mode.doc.children || [],
7151
+ preserveSet,
6978
7152
  warnings,
6979
7153
  modedTheme
6980
7154
  );
6981
7155
  const processedDocument = {
6982
7156
  ...mode.doc,
6983
- children: processedComponents
7157
+ children: processed.standard
6984
7158
  };
6985
7159
  const [modedDoc] = normalizeDocument(processedDocument);
6986
7160
  await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);
@@ -6989,9 +7163,15 @@ function createBuilderImpl(state) {
6989
7163
  const generatedDocument = await renderDocument(structure, layout, {
6990
7164
  services: state.services
6991
7165
  });
7166
+ const preservedDefinition = preserveSet ? {
7167
+ ...mode.doc,
7168
+ children: processed.preserved
7169
+ } : void 0;
6992
7170
  return {
6993
7171
  document: generatedDocument,
6994
- warnings: warnings.length > 0 ? warnings : null
7172
+ warnings: warnings.length > 0 ? warnings : null,
7173
+ standardDefinition: modedDoc,
7174
+ preservedDefinition
6995
7175
  };
6996
7176
  } catch (error) {
6997
7177
  if (state.debug) {
@@ -7000,16 +7180,40 @@ function createBuilderImpl(state) {
7000
7180
  throw error;
7001
7181
  }
7002
7182
  }
7003
- async function generateBuffer(document) {
7004
- const { document: doc, warnings } = await generate(document);
7183
+ async function generateBuffer(document, options) {
7184
+ const {
7185
+ document: doc,
7186
+ warnings,
7187
+ standardDefinition,
7188
+ preservedDefinition
7189
+ } = await generate(document, options);
7005
7190
  const buffer = await Packer.toBuffer(doc);
7006
- return { buffer, warnings };
7191
+ return { buffer, warnings, standardDefinition, preservedDefinition };
7007
7192
  }
7008
- async function generateFile(document, outputPath) {
7009
- const { buffer, warnings } = await generateBuffer(document);
7193
+ async function generateFile(document, outputPath, options) {
7194
+ const { buffer, warnings, standardDefinition, preservedDefinition } = await generateBuffer(document, options);
7010
7195
  const fs4 = await import("fs/promises");
7011
7196
  await fs4.writeFile(outputPath, new Uint8Array(buffer));
7012
- return { warnings };
7197
+ let preservedOutputPath;
7198
+ if (preservedDefinition !== void 0) {
7199
+ const path3 = await import("path");
7200
+ preservedOutputPath = options?.preservedOutputPath ?? (() => {
7201
+ const ext = path3.extname(outputPath);
7202
+ const base = ext ? outputPath.slice(0, -ext.length) : outputPath;
7203
+ return `${base}-preserved.json`;
7204
+ })();
7205
+ await fs4.writeFile(
7206
+ preservedOutputPath,
7207
+ JSON.stringify(preservedDefinition, null, 2),
7208
+ "utf8"
7209
+ );
7210
+ }
7211
+ return {
7212
+ warnings,
7213
+ standardDefinition,
7214
+ preservedDefinition,
7215
+ preservedOutputPath
7216
+ };
7013
7217
  }
7014
7218
  function getComponentNames() {
7015
7219
  return Array.from(state.componentNames);
@@ -7043,6 +7247,10 @@ function createBuilderImpl(state) {
7043
7247
  };
7044
7248
  }
7045
7249
  }
7250
+ async function getStandardComponentsDefinition(document) {
7251
+ const { standardDefinition } = await generate(document);
7252
+ return standardDefinition;
7253
+ }
7046
7254
  function generateSchema(includeStandardComponents = true) {
7047
7255
  return generatePluginDocumentSchema(
7048
7256
  state.components,
@@ -7056,40 +7264,6 @@ function createBuilderImpl(state) {
7056
7264
  options
7057
7265
  );
7058
7266
  }
7059
- async function getStandardComponentsDefinition(document) {
7060
- try {
7061
- const internalDocument = document;
7062
- validateDocument(
7063
- internalDocument,
7064
- state.components
7065
- );
7066
- const themeName = internalDocument.props.theme || "minimal";
7067
- const docTheme = resolveDocumentTheme(themeName);
7068
- const warnings = [];
7069
- const mode = applyExportMode({
7070
- doc: internalDocument,
7071
- theme: docTheme,
7072
- fonts: state.fonts
7073
- });
7074
- const modedTheme = mode.theme;
7075
- const processedComponents = await processDocumentComponents(
7076
- mode.doc.children || [],
7077
- warnings,
7078
- modedTheme
7079
- );
7080
- const processedDocument = {
7081
- ...mode.doc,
7082
- children: processedComponents
7083
- };
7084
- const [finalReportComponent] = normalizeDocument(processedDocument);
7085
- return finalReportComponent;
7086
- } catch (error) {
7087
- if (state.debug) {
7088
- console.error("Error getting standard components definition:", error);
7089
- }
7090
- throw error;
7091
- }
7092
- }
7093
7267
  return Object.freeze({
7094
7268
  addComponent,
7095
7269
  generate,