@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/components/heading.d.ts.map +1 -1
- package/dist/components/paragraph.d.ts.map +1 -1
- package/dist/core/cached-render.d.ts.map +1 -1
- package/dist/core/content.d.ts +3 -0
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/render.d.ts.map +1 -1
- package/dist/core/structure.d.ts +2 -0
- package/dist/core/structure.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +275 -94
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +267 -93
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/index.d.ts +2 -2
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/types.d.ts +59 -6
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/validation.d.ts +1 -1
- package/dist/plugin/validation.d.ts.map +1 -1
- package/dist/templates/themes/index.d.ts +32 -0
- package/dist/templates/themes/index.d.ts.map +1 -1
- package/dist/templates/themes/minimal.docx.theme.json +1 -1
- package/dist/templates/themes/modern.docx.theme.json +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/revisionUtils.d.ts +50 -0
- package/dist/utils/revisionUtils.d.ts.map +1 -0
- package/package.json +3 -3
|
@@ -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,
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
|
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
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
6979
|
+
const standardOut = [];
|
|
6980
|
+
const preservedOut = [];
|
|
6839
6981
|
for (const componentData of components) {
|
|
6840
6982
|
const componentName = componentData?.name;
|
|
6841
6983
|
if (!componentName) {
|
|
6842
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7078
|
+
standardOut.push(componentData);
|
|
7079
|
+
preservedOut.push(componentData);
|
|
6923
7080
|
}
|
|
6924
7081
|
}
|
|
6925
7082
|
}
|
|
6926
|
-
return
|
|
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
|
-
|
|
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
|
|
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:
|
|
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 {
|
|
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
|
-
|
|
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,
|