@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.
package/dist/index.js CHANGED
@@ -231,7 +231,7 @@ var init_minimal_docx_theme = __esm({
231
231
  size: 11
232
232
  },
233
233
  mono: {
234
- family: "SF Mono",
234
+ family: "Menlo",
235
235
  size: 10
236
236
  },
237
237
  light: {
@@ -549,7 +549,7 @@ var init_modern_docx_theme = __esm({
549
549
  fonts: {
550
550
  heading: { family: "Helvetica", size: 28 },
551
551
  body: { family: "Helvetica", size: 11 },
552
- mono: { family: "SF Mono", size: 10 },
552
+ mono: { family: "Menlo", size: 10 },
553
553
  light: { family: "Helvetica", size: 28 }
554
554
  },
555
555
  page: {
@@ -2122,7 +2122,8 @@ async function processDocument(document, theme, themeName) {
2122
2122
  metadata,
2123
2123
  sections,
2124
2124
  theme: effectiveTheme,
2125
- themeName
2125
+ themeName,
2126
+ trackRevisions: document.props.trackRevisions
2126
2127
  };
2127
2128
  }
2128
2129
  function createDocumentMetadata(props) {
@@ -2581,7 +2582,7 @@ Suggestion: ${suggestion}`
2581
2582
  import {
2582
2583
  Document,
2583
2584
  Paragraph as Paragraph7,
2584
- TextRun as TextRun5,
2585
+ TextRun as TextRun6,
2585
2586
  AlignmentType as AlignmentType5,
2586
2587
  BookmarkStart as BookmarkStart2,
2587
2588
  BookmarkEnd as BookmarkEnd2
@@ -3914,6 +3915,99 @@ var CacheKeyGenerator = class {
3914
3915
  }
3915
3916
  };
3916
3917
 
3918
+ // src/utils/revisionUtils.ts
3919
+ import { TextRun as TextRun3, InsertedTextRun, DeletedTextRun } from "docx";
3920
+ var DEFAULT_REVISION_AUTHOR = "json-to-office";
3921
+ var DEFAULT_REVISION_DATE = "1970-01-01T00:00:00Z";
3922
+ var RevisionIdRegistry = class {
3923
+ counter = 0;
3924
+ next() {
3925
+ this.counter += 1;
3926
+ return this.counter;
3927
+ }
3928
+ /** Test-only: deterministic ids for snapshot assertions. */
3929
+ clear() {
3930
+ this.counter = 0;
3931
+ }
3932
+ };
3933
+ var globalRevisionIdRegistry = new RevisionIdRegistry();
3934
+ var PLACEHOLDER_PATTERN = /\{[^}]+\}/;
3935
+ function segmentRuns(text, makeRun) {
3936
+ const lines = text.split("\n");
3937
+ return lines.map(
3938
+ (line, index) => makeRun(index === 0 ? { text: line } : { text: line, break: 1 })
3939
+ );
3940
+ }
3941
+ function createRevisionRuns(revision, baseStyle) {
3942
+ const author = revision.author || DEFAULT_REVISION_AUTHOR;
3943
+ const date = revision.date || DEFAULT_REVISION_DATE;
3944
+ const runs = [];
3945
+ for (const segment of revision.segments) {
3946
+ if (!segment.text) continue;
3947
+ const text = normalizeUnicodeText(segment.text);
3948
+ if (segment.type === "insert") {
3949
+ runs.push(
3950
+ ...segmentRuns(
3951
+ text,
3952
+ (options) => new InsertedTextRun({
3953
+ ...options,
3954
+ ...baseStyle,
3955
+ id: globalRevisionIdRegistry.next(),
3956
+ author,
3957
+ date
3958
+ })
3959
+ )
3960
+ );
3961
+ } else if (segment.type === "delete") {
3962
+ runs.push(
3963
+ ...segmentRuns(
3964
+ text,
3965
+ (options) => new DeletedTextRun({
3966
+ ...options,
3967
+ ...baseStyle,
3968
+ id: globalRevisionIdRegistry.next(),
3969
+ author,
3970
+ date
3971
+ })
3972
+ )
3973
+ );
3974
+ } else if (PLACEHOLDER_PATTERN.test(text)) {
3975
+ runs.push(
3976
+ ...processTextWithPlaceholders(text, baseStyle, {})
3977
+ );
3978
+ } else {
3979
+ runs.push(
3980
+ ...segmentRuns(
3981
+ text,
3982
+ (options) => new TextRun3({ ...options, ...baseStyle })
3983
+ )
3984
+ );
3985
+ }
3986
+ }
3987
+ return runs;
3988
+ }
3989
+ function componentHasRevision(component) {
3990
+ const props = component.props;
3991
+ if (props) {
3992
+ if (props.revision) return true;
3993
+ const items = props.items;
3994
+ if (Array.isArray(items)) {
3995
+ if (items.some(
3996
+ (item) => typeof item === "object" && item !== null && "revision" in item && item.revision
3997
+ )) {
3998
+ return true;
3999
+ }
4000
+ }
4001
+ }
4002
+ const children = component.children;
4003
+ if (Array.isArray(children)) {
4004
+ return children.some(
4005
+ (child) => typeof child === "object" && child !== null && componentHasRevision(child)
4006
+ );
4007
+ }
4008
+ return false;
4009
+ }
4010
+
3917
4011
  // src/core/cached-render.ts
3918
4012
  import { createHash as createHash2 } from "crypto";
3919
4013
  var componentCache = null;
@@ -3961,7 +4055,7 @@ async function clearComponentCache() {
3961
4055
  }
3962
4056
  }
3963
4057
  async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
3964
- const forceBypassForType = component.name === "toc" || component.name === "section";
4058
+ const forceBypassForType = component.name === "toc" || component.name === "section" || componentHasRevision(component);
3965
4059
  if (!componentCache) {
3966
4060
  initializeComponentCache();
3967
4061
  }
@@ -4002,7 +4096,13 @@ async function warmComponentCache(components) {
4002
4096
  }
4003
4097
  const warmingPromises = components.map(
4004
4098
  async ({ component, theme, themeName, context }) => {
4005
- await renderComponentWithCache(component, theme, themeName, context, false);
4099
+ await renderComponentWithCache(
4100
+ component,
4101
+ theme,
4102
+ themeName,
4103
+ context,
4104
+ false
4105
+ );
4006
4106
  }
4007
4107
  );
4008
4108
  await Promise.all(warmingPromises);
@@ -4017,7 +4117,7 @@ function getComponentCacheStats() {
4017
4117
  // src/core/content.ts
4018
4118
  import {
4019
4119
  Paragraph,
4020
- TextRun as TextRun3,
4120
+ TextRun as TextRun4,
4021
4121
  Table,
4022
4122
  TableRow,
4023
4123
  TableCell,
@@ -4167,24 +4267,43 @@ function createText(content, theme, themeName, options = {}) {
4167
4267
  underline: options.underline ? { type: "single" } : void 0
4168
4268
  }
4169
4269
  };
4170
- const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
4171
- boldColor: options.boldColor,
4172
- enableHyperlinks: true
4173
- });
4174
- if (options.bookmarkId) {
4175
- globalBookmarkRegistry.register(
4176
- options.bookmarkId,
4177
- normalizedContent,
4178
- "paragraph"
4179
- );
4180
- children.push(
4181
- new Bookmark({
4182
- id: options.bookmarkId,
4183
- children: textRuns
4184
- })
4185
- );
4270
+ if (options.revision) {
4271
+ const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);
4272
+ if (options.bookmarkId) {
4273
+ globalBookmarkRegistry.register(
4274
+ options.bookmarkId,
4275
+ normalizedContent,
4276
+ "paragraph"
4277
+ );
4278
+ children.push(
4279
+ new Bookmark({
4280
+ id: options.bookmarkId,
4281
+ children: revisionRuns
4282
+ })
4283
+ );
4284
+ } else {
4285
+ children.push(...revisionRuns);
4286
+ }
4186
4287
  } else {
4187
- children.push(...textRuns);
4288
+ const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {
4289
+ boldColor: options.boldColor,
4290
+ enableHyperlinks: true
4291
+ });
4292
+ if (options.bookmarkId) {
4293
+ globalBookmarkRegistry.register(
4294
+ options.bookmarkId,
4295
+ normalizedContent,
4296
+ "paragraph"
4297
+ );
4298
+ children.push(
4299
+ new Bookmark({
4300
+ id: options.bookmarkId,
4301
+ children: textRuns
4302
+ })
4303
+ );
4304
+ } else {
4305
+ children.push(...textRuns);
4306
+ }
4188
4307
  }
4189
4308
  const isFloating = !!options.floating;
4190
4309
  const frameOptions = isFloating && options.floating ? mapFrameOptions(options.floating, theme, themeName) : void 0;
@@ -4305,7 +4424,24 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4305
4424
  underline: options.underline ? { type: "single" } : void 0
4306
4425
  }
4307
4426
  };
4308
- if (options.bookmarkId) {
4427
+ if (options.revision) {
4428
+ const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);
4429
+ if (options.bookmarkId) {
4430
+ globalBookmarkRegistry.register(
4431
+ options.bookmarkId,
4432
+ normalizedText,
4433
+ "heading"
4434
+ );
4435
+ children.push(
4436
+ new Bookmark({
4437
+ id: options.bookmarkId,
4438
+ children: revisionRuns
4439
+ })
4440
+ );
4441
+ } else {
4442
+ children.push(...revisionRuns);
4443
+ }
4444
+ } else if (options.bookmarkId) {
4309
4445
  globalBookmarkRegistry.register(
4310
4446
  options.bookmarkId,
4311
4447
  normalizedText,
@@ -4320,7 +4456,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4320
4456
  headingTextChildren.push(...textRuns);
4321
4457
  } else {
4322
4458
  headingTextChildren.push(
4323
- new TextRun3({ text: normalizedText, ...baseTextStyle })
4459
+ new TextRun4({ text: normalizedText, ...baseTextStyle })
4324
4460
  );
4325
4461
  }
4326
4462
  children.push(
@@ -4337,7 +4473,7 @@ function createHeading(text, level, theme, _themeName, options = {}) {
4337
4473
  });
4338
4474
  children.push(...textRuns);
4339
4475
  } else {
4340
- children.push(new TextRun3({ text: normalizedText, ...baseTextStyle }));
4476
+ children.push(new TextRun4({ text: normalizedText, ...baseTextStyle }));
4341
4477
  }
4342
4478
  }
4343
4479
  return new Paragraph({
@@ -4477,10 +4613,11 @@ function createList(items, _theme, _themeName, options = {}) {
4477
4613
  items.forEach((item, index) => {
4478
4614
  const itemText = typeof item === "string" ? item : item.text;
4479
4615
  const itemLevel = typeof item === "object" ? item.level || 0 : 0;
4480
- if (!itemText.trim()) {
4616
+ const itemRevision = typeof item === "object" ? item.revision : void 0;
4617
+ if (!itemText.trim() && !itemRevision) {
4481
4618
  return;
4482
4619
  }
4483
- const textRuns = parseTextWithDecorators(
4620
+ const textRuns = itemRevision ? createRevisionRuns(itemRevision, {}) : parseTextWithDecorators(
4484
4621
  itemText,
4485
4622
  {},
4486
4623
  {
@@ -4893,7 +5030,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
4893
5030
  } catch (error) {
4894
5031
  const imageSource = imageComp.props.base64 || imageComp.props.path || "unknown";
4895
5032
  cellChildren = [
4896
- new TextRun3({
5033
+ new TextRun4({
4897
5034
  text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? "..." : ""}]`,
4898
5035
  font: mergedStyle.font,
4899
5036
  size: mergedStyle.size,
@@ -4903,7 +5040,7 @@ async function createTable(columns, tableConfig, theme, themeName, _options = {}
4903
5040
  }
4904
5041
  } else {
4905
5042
  cellChildren = [
4906
- new TextRun3({
5043
+ new TextRun4({
4907
5044
  text: `[Unsupported component type: ${cell.name}]`,
4908
5045
  font: mergedStyle.font,
4909
5046
  size: mergedStyle.size,
@@ -5300,7 +5437,9 @@ function renderHeadingComponent(component, theme, themeName) {
5300
5437
  keepNext: config.keepNext,
5301
5438
  keepLines: config.keepLines,
5302
5439
  // Bookmark ID for internal linking
5303
- bookmarkId
5440
+ bookmarkId,
5441
+ // Tracked-change segments (rendered as native Word revisions)
5442
+ revision: config.revision
5304
5443
  }
5305
5444
  );
5306
5445
  return [header];
@@ -5344,7 +5483,7 @@ function parseMarkdownList(text) {
5344
5483
  function renderParagraphComponent(component, theme, themeName) {
5345
5484
  if (!isParagraphComponent(component)) return [];
5346
5485
  const resolvedConfig = component.props;
5347
- const listData = parseMarkdownList(resolvedConfig.text);
5486
+ const listData = resolvedConfig.revision ? null : parseMarkdownList(resolvedConfig.text);
5348
5487
  if (listData) {
5349
5488
  const reference = globalNumberingRegistry.generateReference("markdown-list");
5350
5489
  const levels = [];
@@ -5421,7 +5560,9 @@ function renderParagraphComponent(component, theme, themeName) {
5421
5560
  // Pass keepLines property
5422
5561
  keepLines: resolvedConfig.keepLines,
5423
5562
  // Pass bookmark ID for internal linking
5424
- bookmarkId: resolvedConfig.id
5563
+ bookmarkId: resolvedConfig.id,
5564
+ // Tracked-change segments (rendered as native Word revisions)
5565
+ revision: resolvedConfig.revision
5425
5566
  });
5426
5567
  return [text];
5427
5568
  }
@@ -6051,7 +6192,7 @@ import {
6051
6192
  Paragraph as Paragraph6,
6052
6193
  TableOfContents,
6053
6194
  AlignmentType as AlignmentType4,
6054
- TextRun as TextRun4,
6195
+ TextRun as TextRun5,
6055
6196
  StyleLevel
6056
6197
  } from "docx";
6057
6198
  function parseDepthRange(rawDepth, fieldName, defaultFrom = 1, defaultTo = 3) {
@@ -6106,7 +6247,7 @@ function renderTocComponent(component, theme, context) {
6106
6247
  paragraphs.push(
6107
6248
  new Paragraph6({
6108
6249
  children: [
6109
- new TextRun4({
6250
+ new TextRun5({
6110
6251
  text: componentProps.title,
6111
6252
  bold: true,
6112
6253
  size: 28
@@ -6411,8 +6552,10 @@ async function renderDocument(structure, layout, options) {
6411
6552
  styles: createWordStyles(structure.theme),
6412
6553
  sections,
6413
6554
  features: {
6414
- updateFields: true
6555
+ updateFields: true,
6415
6556
  // Required for TOC fields to update correctly
6557
+ // Word opens the document in review mode (further edits are tracked)
6558
+ ...structure.trackRevisions && { trackRevisions: true }
6416
6559
  },
6417
6560
  // Add numbering configurations if any lists were rendered
6418
6561
  ...numberingConfigs.length > 0 && {
@@ -6457,7 +6600,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, _conte
6457
6600
  elements.push(
6458
6601
  new Paragraph7({
6459
6602
  children: [
6460
- new TextRun5({
6603
+ new TextRun6({
6461
6604
  text: "[IMAGE: Missing path or base64 property]",
6462
6605
  font: getThemeFonts(theme).body.family,
6463
6606
  size: 20,
@@ -6539,7 +6682,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, _conte
6539
6682
  elements.push(
6540
6683
  new Paragraph7({
6541
6684
  children: [
6542
- new TextRun5({
6685
+ new TextRun6({
6543
6686
  text: `[IMAGE: ${imageComp.props.path}]`,
6544
6687
  font: getThemeFonts(theme).body.family,
6545
6688
  size: 20,
@@ -7268,7 +7411,8 @@ import {
7268
7411
  } from "@json-to-office/shared-docx/validation/unified";
7269
7412
  import {
7270
7413
  DuplicateComponentError,
7271
- ComponentValidationError as ComponentValidationError2
7414
+ ComponentValidationError as ComponentValidationError2,
7415
+ UnknownPreservedComponentError
7272
7416
  } from "@json-to-office/shared/plugin";
7273
7417
  function validateComponentProps(schema, props, componentName) {
7274
7418
  return validateCustomComponentProps(schema.propsSchema, props, {
@@ -7335,6 +7479,9 @@ function getValidatedProps(schema, props) {
7335
7479
  }
7336
7480
  var cleanComponentProps = getValidatedProps;
7337
7481
 
7482
+ // src/plugin/createDocumentGenerator.ts
7483
+ import { UnknownPreservedComponentError as UnknownPreservedComponentError2 } from "@json-to-office/shared/plugin";
7484
+
7338
7485
  // src/plugin/schema.ts
7339
7486
  import { Type as Type2 } from "@sinclair/typebox";
7340
7487
  import { latestVersion } from "@json-to-office/shared-docx";
@@ -7510,17 +7657,19 @@ function createBuilderImpl(state) {
7510
7657
  }
7511
7658
  return getThemeWithFallback(themeName);
7512
7659
  }
7513
- async function processDocumentComponents(components, warningsCollector, resolvedTheme, depth = 0) {
7660
+ async function processDocumentComponents(components, preserveSet, warningsCollector, resolvedTheme, depth = 0) {
7514
7661
  if (depth > 20) {
7515
7662
  throw new Error(
7516
7663
  "Maximum component nesting depth exceeded (20). Check for circular component references."
7517
7664
  );
7518
7665
  }
7519
- const processedComponents = [];
7666
+ const standardOut = [];
7667
+ const preservedOut = [];
7520
7668
  for (const componentData of components) {
7521
7669
  const componentName = componentData?.name;
7522
7670
  if (!componentName) {
7523
- processedComponents.push(componentData);
7671
+ standardOut.push(componentData);
7672
+ preservedOut.push(componentData);
7524
7673
  continue;
7525
7674
  }
7526
7675
  const customComponent = componentMap.get(componentName);
@@ -7543,12 +7692,14 @@ function createBuilderImpl(state) {
7543
7692
  );
7544
7693
  let nestedChildren;
7545
7694
  if (componentWithName.children && Array.isArray(componentWithName.children)) {
7546
- nestedChildren = await processDocumentComponents(
7695
+ const nested = await processDocumentComponents(
7547
7696
  componentWithName.children,
7697
+ preserveSet,
7548
7698
  warningsCollector,
7549
7699
  resolvedTheme,
7550
7700
  depth + 1
7551
7701
  );
7702
+ nestedChildren = nested.standard;
7552
7703
  }
7553
7704
  const versionLabel = componentWithName.version ? `${customComponent.name}@${componentWithName.version}` : customComponent.name;
7554
7705
  const addWarning = (message, context) => {
@@ -7568,15 +7719,21 @@ function createBuilderImpl(state) {
7568
7719
  const resultComponents = Array.isArray(result) ? result : [result];
7569
7720
  const processedResult = await processDocumentComponents(
7570
7721
  resultComponents,
7722
+ preserveSet,
7571
7723
  warningsCollector,
7572
7724
  resolvedTheme,
7573
7725
  depth + 1
7574
7726
  );
7575
- processedComponents.push(...processedResult);
7727
+ standardOut.push(...processedResult.standard);
7728
+ if (preserveSet && preserveSet.has(componentName)) {
7729
+ preservedOut.push(componentData);
7730
+ } else {
7731
+ preservedOut.push(...processedResult.preserved);
7732
+ }
7576
7733
  if (state.debug) {
7577
7734
  console.log(
7578
7735
  `Processed custom component '${versionLabel}':`,
7579
- processedResult
7736
+ processedResult.standard
7580
7737
  );
7581
7738
  }
7582
7739
  } catch (error) {
@@ -7591,20 +7748,26 @@ function createBuilderImpl(state) {
7591
7748
  if ("children" in componentData && Array.isArray(componentData.children)) {
7592
7749
  const processedNested = await processDocumentComponents(
7593
7750
  componentData.children,
7751
+ preserveSet,
7594
7752
  warningsCollector,
7595
7753
  resolvedTheme,
7596
7754
  depth + 1
7597
7755
  );
7598
- processedComponents.push({
7756
+ standardOut.push({
7757
+ ...componentData,
7758
+ children: processedNested.standard
7759
+ });
7760
+ preservedOut.push({
7599
7761
  ...componentData,
7600
- children: processedNested
7762
+ children: processedNested.preserved
7601
7763
  });
7602
7764
  } else {
7603
- processedComponents.push(componentData);
7765
+ standardOut.push(componentData);
7766
+ preservedOut.push(componentData);
7604
7767
  }
7605
7768
  }
7606
7769
  }
7607
- return processedComponents;
7770
+ return { standard: standardOut, preserved: preservedOut };
7608
7771
  }
7609
7772
  function addComponent(component) {
7610
7773
  if (!component.name) {
@@ -7629,8 +7792,24 @@ function createBuilderImpl(state) {
7629
7792
  newState
7630
7793
  );
7631
7794
  }
7632
- async function generate(document) {
7795
+ function resolvePreserveSet(options) {
7796
+ const list = options?.preserveCustomComponents;
7797
+ if (!list || list.length === 0) {
7798
+ return void 0;
7799
+ }
7800
+ const registered = new Set(state.componentNames);
7801
+ const unknown = list.filter((n) => !registered.has(n));
7802
+ if (unknown.length > 0) {
7803
+ throw new UnknownPreservedComponentError2(
7804
+ unknown,
7805
+ Array.from(state.componentNames)
7806
+ );
7807
+ }
7808
+ return new Set(list);
7809
+ }
7810
+ async function generate(document, options) {
7633
7811
  try {
7812
+ const preserveSet = resolvePreserveSet(options);
7634
7813
  const internalDocument = document;
7635
7814
  validateDocument(
7636
7815
  internalDocument,
@@ -7654,14 +7833,15 @@ function createBuilderImpl(state) {
7654
7833
  context: { code: w.code }
7655
7834
  });
7656
7835
  }
7657
- const processedComponents = await processDocumentComponents(
7836
+ const processed = await processDocumentComponents(
7658
7837
  mode.doc.children || [],
7838
+ preserveSet,
7659
7839
  warnings,
7660
7840
  modedTheme
7661
7841
  );
7662
7842
  const processedDocument = {
7663
7843
  ...mode.doc,
7664
- children: processedComponents
7844
+ children: processed.standard
7665
7845
  };
7666
7846
  const [modedDoc] = normalizeDocument(processedDocument);
7667
7847
  await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);
@@ -7670,9 +7850,15 @@ function createBuilderImpl(state) {
7670
7850
  const generatedDocument = await renderDocument(structure, layout, {
7671
7851
  services: state.services
7672
7852
  });
7853
+ const preservedDefinition = preserveSet ? {
7854
+ ...mode.doc,
7855
+ children: processed.preserved
7856
+ } : void 0;
7673
7857
  return {
7674
7858
  document: generatedDocument,
7675
- warnings: warnings.length > 0 ? warnings : null
7859
+ warnings: warnings.length > 0 ? warnings : null,
7860
+ standardDefinition: modedDoc,
7861
+ preservedDefinition
7676
7862
  };
7677
7863
  } catch (error) {
7678
7864
  if (state.debug) {
@@ -7681,16 +7867,40 @@ function createBuilderImpl(state) {
7681
7867
  throw error;
7682
7868
  }
7683
7869
  }
7684
- async function generateBuffer(document) {
7685
- const { document: doc, warnings } = await generate(document);
7870
+ async function generateBuffer(document, options) {
7871
+ const {
7872
+ document: doc,
7873
+ warnings,
7874
+ standardDefinition,
7875
+ preservedDefinition
7876
+ } = await generate(document, options);
7686
7877
  const buffer = await Packer2.toBuffer(doc);
7687
- return { buffer, warnings };
7878
+ return { buffer, warnings, standardDefinition, preservedDefinition };
7688
7879
  }
7689
- async function generateFile(document, outputPath) {
7690
- const { buffer, warnings } = await generateBuffer(document);
7880
+ async function generateFile(document, outputPath, options) {
7881
+ const { buffer, warnings, standardDefinition, preservedDefinition } = await generateBuffer(document, options);
7691
7882
  const fs6 = await import("fs/promises");
7692
7883
  await fs6.writeFile(outputPath, new Uint8Array(buffer));
7693
- return { warnings };
7884
+ let preservedOutputPath;
7885
+ if (preservedDefinition !== void 0) {
7886
+ const path4 = await import("path");
7887
+ preservedOutputPath = options?.preservedOutputPath ?? (() => {
7888
+ const ext = path4.extname(outputPath);
7889
+ const base = ext ? outputPath.slice(0, -ext.length) : outputPath;
7890
+ return `${base}-preserved.json`;
7891
+ })();
7892
+ await fs6.writeFile(
7893
+ preservedOutputPath,
7894
+ JSON.stringify(preservedDefinition, null, 2),
7895
+ "utf8"
7896
+ );
7897
+ }
7898
+ return {
7899
+ warnings,
7900
+ standardDefinition,
7901
+ preservedDefinition,
7902
+ preservedOutputPath
7903
+ };
7694
7904
  }
7695
7905
  function getComponentNames() {
7696
7906
  return Array.from(state.componentNames);
@@ -7724,6 +7934,10 @@ function createBuilderImpl(state) {
7724
7934
  };
7725
7935
  }
7726
7936
  }
7937
+ async function getStandardComponentsDefinition(document) {
7938
+ const { standardDefinition } = await generate(document);
7939
+ return standardDefinition;
7940
+ }
7727
7941
  function generateSchema(includeStandardComponents = true) {
7728
7942
  return generatePluginDocumentSchema(
7729
7943
  state.components,
@@ -7737,40 +7951,6 @@ function createBuilderImpl(state) {
7737
7951
  options
7738
7952
  );
7739
7953
  }
7740
- async function getStandardComponentsDefinition(document) {
7741
- try {
7742
- const internalDocument = document;
7743
- validateDocument(
7744
- internalDocument,
7745
- state.components
7746
- );
7747
- const themeName = internalDocument.props.theme || "minimal";
7748
- const docTheme = resolveDocumentTheme(themeName);
7749
- const warnings = [];
7750
- const mode = applyExportMode2({
7751
- doc: internalDocument,
7752
- theme: docTheme,
7753
- fonts: state.fonts
7754
- });
7755
- const modedTheme = mode.theme;
7756
- const processedComponents = await processDocumentComponents(
7757
- mode.doc.children || [],
7758
- warnings,
7759
- modedTheme
7760
- );
7761
- const processedDocument = {
7762
- ...mode.doc,
7763
- children: processedComponents
7764
- };
7765
- const [finalReportComponent] = normalizeDocument(processedDocument);
7766
- return finalReportComponent;
7767
- } catch (error) {
7768
- if (state.debug) {
7769
- console.error("Error getting standard components definition:", error);
7770
- }
7771
- throw error;
7772
- }
7773
- }
7774
7954
  return Object.freeze({
7775
7955
  addComponent,
7776
7956
  generate,
@@ -7816,6 +7996,7 @@ export {
7816
7996
  ThemeFileError,
7817
7997
  ThemeParseError,
7818
7998
  ThemeValidationError,
7999
+ UnknownPreservedComponentError,
7819
8000
  cleanComponentProps,
7820
8001
  clearComponentCache,
7821
8002
  corporateTheme,