@json-to-office/core-docx 0.19.0 → 0.21.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/highcharts.d.ts.map +1 -1
- package/dist/components/section.d.ts.map +1 -1
- package/dist/core/cached-render.d.ts.map +1 -1
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/generator.d.ts +6 -2
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/render.d.ts +8 -6
- package/dist/core/render.d.ts.map +1 -1
- package/dist/core/structure.d.ts +2 -2
- package/dist/core/structure.d.ts.map +1 -1
- package/dist/index.js +414 -345
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts +4 -0
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +394 -287
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/types.d.ts +4 -0
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/bookmarkRegistry.d.ts +5 -2
- package/dist/utils/bookmarkRegistry.d.ts.map +1 -1
- package/dist/utils/fixFloatingImageIds.d.ts +3 -0
- package/dist/utils/fixFloatingImageIds.d.ts.map +1 -1
- package/dist/utils/generationContext.d.ts +5 -0
- package/dist/utils/generationContext.d.ts.map +1 -0
- package/dist/utils/numberingConfig.d.ts +5 -2
- package/dist/utils/numberingConfig.d.ts.map +1 -1
- package/dist/utils/packageDocument.d.ts +20 -0
- package/dist/utils/packageDocument.d.ts.map +1 -0
- package/dist/utils/placeholderProcessor.d.ts +5 -5
- package/dist/utils/placeholderProcessor.d.ts.map +1 -1
- package/dist/utils/revisionUtils.d.ts +5 -5
- package/dist/utils/revisionUtils.d.ts.map +1 -1
- package/dist/utils/textParser.d.ts +3 -3
- package/dist/utils/textParser.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1692,253 +1692,7 @@ var init_docxImagePositioning = __esm({
|
|
|
1692
1692
|
}
|
|
1693
1693
|
});
|
|
1694
1694
|
|
|
1695
|
-
// src/utils/numberingConfig.ts
|
|
1696
|
-
var numberingConfig_exports = {};
|
|
1697
|
-
__export(numberingConfig_exports, {
|
|
1698
|
-
NumberingRegistry: () => NumberingRegistry,
|
|
1699
|
-
createBulletListConfig: () => createBulletListConfig,
|
|
1700
|
-
createNumberedListConfig: () => createNumberedListConfig,
|
|
1701
|
-
createNumberingConfig: () => createNumberingConfig,
|
|
1702
|
-
globalNumberingRegistry: () => globalNumberingRegistry
|
|
1703
|
-
});
|
|
1704
|
-
import { AlignmentType as AlignmentType3, convertInchesToTwip, LevelFormat } from "docx";
|
|
1705
|
-
function getLevelFormat(format2) {
|
|
1706
|
-
if (!format2) return LevelFormat.BULLET;
|
|
1707
|
-
return LEVEL_FORMAT_MAP[format2] || LevelFormat.BULLET;
|
|
1708
|
-
}
|
|
1709
|
-
function getAlignment2(alignment) {
|
|
1710
|
-
if (!alignment) return AlignmentType3.LEFT;
|
|
1711
|
-
return ALIGNMENT_MAP[alignment] || AlignmentType3.LEFT;
|
|
1712
|
-
}
|
|
1713
|
-
function createDefaultLevel(level, format2 = LevelFormat.BULLET, text) {
|
|
1714
|
-
const baseIndent = 0.5 * (level + 1);
|
|
1715
|
-
const hangingIndent = 0.25;
|
|
1716
|
-
return {
|
|
1717
|
-
level,
|
|
1718
|
-
format: format2,
|
|
1719
|
-
text: text || (format2 === LevelFormat.BULLET ? "\u2022" : "%1."),
|
|
1720
|
-
alignment: AlignmentType3.LEFT,
|
|
1721
|
-
style: {
|
|
1722
|
-
paragraph: {
|
|
1723
|
-
indent: {
|
|
1724
|
-
left: convertInchesToTwip(baseIndent),
|
|
1725
|
-
hanging: convertInchesToTwip(hangingIndent)
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
};
|
|
1730
|
-
}
|
|
1731
|
-
function createNumberingConfig(config) {
|
|
1732
|
-
const levels = [];
|
|
1733
|
-
for (const levelConfig of config.levels) {
|
|
1734
|
-
const format2 = getLevelFormat(levelConfig.format);
|
|
1735
|
-
const alignment = getAlignment2(levelConfig.alignment);
|
|
1736
|
-
const text = levelConfig.text || (format2 === LevelFormat.BULLET ? "\u2022" : `%${levelConfig.level + 1}.`);
|
|
1737
|
-
const baseIndent = levelConfig.indent?.left !== void 0 ? levelConfig.indent.left / 72 : 0.5 * (levelConfig.level + 1);
|
|
1738
|
-
const hangingIndent = levelConfig.indent?.hanging !== void 0 ? levelConfig.indent.hanging / 72 : 0.25;
|
|
1739
|
-
const level = {
|
|
1740
|
-
level: levelConfig.level,
|
|
1741
|
-
format: format2,
|
|
1742
|
-
text,
|
|
1743
|
-
alignment,
|
|
1744
|
-
style: {
|
|
1745
|
-
paragraph: {
|
|
1746
|
-
indent: {
|
|
1747
|
-
left: convertInchesToTwip(baseIndent),
|
|
1748
|
-
hanging: convertInchesToTwip(hangingIndent)
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
},
|
|
1752
|
-
// Add start number if specified
|
|
1753
|
-
...levelConfig.start !== void 0 && { start: levelConfig.start }
|
|
1754
|
-
};
|
|
1755
|
-
levels.push(level);
|
|
1756
|
-
}
|
|
1757
|
-
return {
|
|
1758
|
-
reference: config.reference,
|
|
1759
|
-
levels
|
|
1760
|
-
};
|
|
1761
|
-
}
|
|
1762
|
-
function createBulletListConfig(reference, bullet = "\u2022") {
|
|
1763
|
-
return {
|
|
1764
|
-
reference,
|
|
1765
|
-
levels: [
|
|
1766
|
-
createDefaultLevel(0, LevelFormat.BULLET, bullet),
|
|
1767
|
-
createDefaultLevel(1, LevelFormat.BULLET, "\u25E6"),
|
|
1768
|
-
createDefaultLevel(2, LevelFormat.BULLET, "\u25AA")
|
|
1769
|
-
]
|
|
1770
|
-
};
|
|
1771
|
-
}
|
|
1772
|
-
function createNumberedListConfig(reference, start = 1) {
|
|
1773
|
-
return {
|
|
1774
|
-
reference,
|
|
1775
|
-
levels: [
|
|
1776
|
-
{ ...createDefaultLevel(0, LevelFormat.DECIMAL, "%1."), start },
|
|
1777
|
-
createDefaultLevel(1, LevelFormat.LOWER_LETTER, "%2."),
|
|
1778
|
-
createDefaultLevel(2, LevelFormat.LOWER_ROMAN, "%3.")
|
|
1779
|
-
]
|
|
1780
|
-
};
|
|
1781
|
-
}
|
|
1782
|
-
var LEVEL_FORMAT_MAP, ALIGNMENT_MAP, NumberingRegistry, globalNumberingRegistry;
|
|
1783
|
-
var init_numberingConfig = __esm({
|
|
1784
|
-
"src/utils/numberingConfig.ts"() {
|
|
1785
|
-
"use strict";
|
|
1786
|
-
LEVEL_FORMAT_MAP = {
|
|
1787
|
-
decimal: LevelFormat.DECIMAL,
|
|
1788
|
-
upperRoman: LevelFormat.UPPER_ROMAN,
|
|
1789
|
-
lowerRoman: LevelFormat.LOWER_ROMAN,
|
|
1790
|
-
upperLetter: LevelFormat.UPPER_LETTER,
|
|
1791
|
-
lowerLetter: LevelFormat.LOWER_LETTER,
|
|
1792
|
-
bullet: LevelFormat.BULLET,
|
|
1793
|
-
ordinal: LevelFormat.ORDINAL,
|
|
1794
|
-
cardinalText: LevelFormat.CARDINAL_TEXT,
|
|
1795
|
-
ordinalText: LevelFormat.ORDINAL_TEXT,
|
|
1796
|
-
hex: LevelFormat.HEX,
|
|
1797
|
-
chicago: LevelFormat.CHICAGO,
|
|
1798
|
-
ideographDigital: LevelFormat.IDEOGRAPH__DIGITAL,
|
|
1799
|
-
japaneseCounting: LevelFormat.JAPANESE_COUNTING,
|
|
1800
|
-
aiueo: LevelFormat.AIUEO,
|
|
1801
|
-
iroha: LevelFormat.IROHA,
|
|
1802
|
-
decimalFullWidth: LevelFormat.DECIMAL_FULL_WIDTH,
|
|
1803
|
-
decimalHalfWidth: LevelFormat.DECIMAL_HALF_WIDTH,
|
|
1804
|
-
japaneseLegal: LevelFormat.JAPANESE_LEGAL,
|
|
1805
|
-
japaneseDigitalTenThousand: LevelFormat.JAPANESE_DIGITAL_TEN_THOUSAND,
|
|
1806
|
-
decimalEnclosedCircle: LevelFormat.DECIMAL_ENCLOSED_CIRCLE,
|
|
1807
|
-
decimalFullWidth2: LevelFormat.DECIMAL_FULL_WIDTH2,
|
|
1808
|
-
aiueoFullWidth: LevelFormat.AIUEO_FULL_WIDTH,
|
|
1809
|
-
irohaFullWidth: LevelFormat.IROHA_FULL_WIDTH,
|
|
1810
|
-
decimalZero: LevelFormat.DECIMAL_ZERO,
|
|
1811
|
-
ganada: LevelFormat.GANADA,
|
|
1812
|
-
chosung: LevelFormat.CHOSUNG,
|
|
1813
|
-
decimalEnclosedFullstop: LevelFormat.DECIMAL_ENCLOSED_FULLSTOP,
|
|
1814
|
-
decimalEnclosedParen: LevelFormat.DECIMAL_ENCLOSED_PARENTHESES,
|
|
1815
|
-
decimalEnclosedCircleChinese: LevelFormat.DECIMAL_ENCLOSED_CIRCLE_CHINESE,
|
|
1816
|
-
ideographEnclosedCircle: LevelFormat.IDEOGRAPH_ENCLOSED_CIRCLE,
|
|
1817
|
-
ideographTraditional: LevelFormat.IDEOGRAPH_TRADITIONAL,
|
|
1818
|
-
ideographZodiac: LevelFormat.IDEOGRAPH_ZODIAC,
|
|
1819
|
-
ideographZodiacTraditional: LevelFormat.IDEOGRAPH_ZODIAC_TRADITIONAL,
|
|
1820
|
-
taiwaneseCounting: LevelFormat.TAIWANESE_COUNTING,
|
|
1821
|
-
ideographLegalTraditional: LevelFormat.IDEOGRAPH_LEGAL_TRADITIONAL,
|
|
1822
|
-
taiwaneseCountingThousand: LevelFormat.TAIWANESE_COUNTING_THOUSAND,
|
|
1823
|
-
taiwaneseDigital: LevelFormat.TAIWANESE_DIGITAL,
|
|
1824
|
-
chineseCounting: LevelFormat.CHINESE_COUNTING,
|
|
1825
|
-
chineseLegalSimplified: LevelFormat.CHINESE_LEGAL_SIMPLIFIED,
|
|
1826
|
-
chineseCountingThousand: LevelFormat.CHINESE_COUNTING_THOUSAND,
|
|
1827
|
-
koreanDigital: LevelFormat.KOREAN_DIGITAL,
|
|
1828
|
-
koreanCounting: LevelFormat.KOREAN_COUNTING,
|
|
1829
|
-
koreanLegal: LevelFormat.KOREAN_LEGAL,
|
|
1830
|
-
koreanDigital2: LevelFormat.KOREAN_DIGITAL2,
|
|
1831
|
-
vietnameseCounting: LevelFormat.VIETNAMESE_COUNTING,
|
|
1832
|
-
russianLower: LevelFormat.RUSSIAN_LOWER,
|
|
1833
|
-
russianUpper: LevelFormat.RUSSIAN_UPPER,
|
|
1834
|
-
none: LevelFormat.NONE,
|
|
1835
|
-
numberInDash: LevelFormat.NUMBER_IN_DASH,
|
|
1836
|
-
hebrew1: LevelFormat.HEBREW1,
|
|
1837
|
-
hebrew2: LevelFormat.HEBREW2,
|
|
1838
|
-
arabicAlpha: LevelFormat.ARABIC_ALPHA,
|
|
1839
|
-
arabicAbjad: LevelFormat.ARABIC_ABJAD,
|
|
1840
|
-
hindiVowels: LevelFormat.HINDI_VOWELS,
|
|
1841
|
-
hindiConsonants: LevelFormat.HINDI_CONSONANTS,
|
|
1842
|
-
hindiNumbers: LevelFormat.HINDI_NUMBERS,
|
|
1843
|
-
hindiCounting: LevelFormat.HINDI_COUNTING,
|
|
1844
|
-
thaiLetters: LevelFormat.THAI_LETTERS,
|
|
1845
|
-
thaiNumbers: LevelFormat.THAI_NUMBERS,
|
|
1846
|
-
thaiCounting: LevelFormat.THAI_COUNTING
|
|
1847
|
-
};
|
|
1848
|
-
ALIGNMENT_MAP = {
|
|
1849
|
-
start: AlignmentType3.START,
|
|
1850
|
-
end: AlignmentType3.END,
|
|
1851
|
-
left: AlignmentType3.LEFT,
|
|
1852
|
-
right: AlignmentType3.RIGHT,
|
|
1853
|
-
center: AlignmentType3.CENTER
|
|
1854
|
-
};
|
|
1855
|
-
NumberingRegistry = class {
|
|
1856
|
-
configs = /* @__PURE__ */ new Map();
|
|
1857
|
-
counter = 0;
|
|
1858
|
-
/**
|
|
1859
|
-
* Register a numbering configuration
|
|
1860
|
-
*/
|
|
1861
|
-
register(config) {
|
|
1862
|
-
const reference = config.reference;
|
|
1863
|
-
this.configs.set(reference, config);
|
|
1864
|
-
return reference;
|
|
1865
|
-
}
|
|
1866
|
-
/**
|
|
1867
|
-
* Generate a unique reference ID
|
|
1868
|
-
*/
|
|
1869
|
-
generateReference(prefix = "list") {
|
|
1870
|
-
return `${prefix}-${++this.counter}`;
|
|
1871
|
-
}
|
|
1872
|
-
/**
|
|
1873
|
-
* Get all registered configurations as an array suitable for INumberingOptions
|
|
1874
|
-
*/
|
|
1875
|
-
getAll() {
|
|
1876
|
-
return Array.from(this.configs.values());
|
|
1877
|
-
}
|
|
1878
|
-
/**
|
|
1879
|
-
* Clear all configurations
|
|
1880
|
-
*/
|
|
1881
|
-
clear() {
|
|
1882
|
-
this.configs.clear();
|
|
1883
|
-
this.counter = 0;
|
|
1884
|
-
}
|
|
1885
|
-
/**
|
|
1886
|
-
* Check if a reference exists
|
|
1887
|
-
*/
|
|
1888
|
-
has(reference) {
|
|
1889
|
-
return this.configs.has(reference);
|
|
1890
|
-
}
|
|
1891
|
-
/**
|
|
1892
|
-
* Get a configuration by reference
|
|
1893
|
-
*/
|
|
1894
|
-
get(reference) {
|
|
1895
|
-
return this.configs.get(reference);
|
|
1896
|
-
}
|
|
1897
|
-
};
|
|
1898
|
-
globalNumberingRegistry = new NumberingRegistry();
|
|
1899
|
-
}
|
|
1900
|
-
});
|
|
1901
|
-
|
|
1902
|
-
// src/utils/fixFloatingImageIds.ts
|
|
1903
|
-
var fixFloatingImageIds_exports = {};
|
|
1904
|
-
__export(fixFloatingImageIds_exports, {
|
|
1905
|
-
fixFloatingImageIds: () => fixFloatingImageIds
|
|
1906
|
-
});
|
|
1907
|
-
import AdmZip from "adm-zip";
|
|
1908
|
-
async function fixFloatingImageIds(docxPath) {
|
|
1909
|
-
try {
|
|
1910
|
-
const zip = new AdmZip(docxPath);
|
|
1911
|
-
const documentEntry = zip.getEntry("word/document.xml");
|
|
1912
|
-
if (!documentEntry) {
|
|
1913
|
-
throw new Error("document.xml not found in DOCX");
|
|
1914
|
-
}
|
|
1915
|
-
let documentXml = documentEntry.getData().toString("utf8");
|
|
1916
|
-
let idCounter = 1;
|
|
1917
|
-
documentXml = documentXml.replace(
|
|
1918
|
-
/<wp:docPr\s+id="(\d+)"/g,
|
|
1919
|
-
(_match) => {
|
|
1920
|
-
const newId = idCounter++;
|
|
1921
|
-
return `<wp:docPr id="${newId}"`;
|
|
1922
|
-
}
|
|
1923
|
-
);
|
|
1924
|
-
zip.updateFile("word/document.xml", Buffer.from(documentXml, "utf8"));
|
|
1925
|
-
zip.writeZip(docxPath);
|
|
1926
|
-
console.log(
|
|
1927
|
-
`Fixed ${idCounter - 1} duplicate floating image docPr IDs in ${docxPath}`
|
|
1928
|
-
);
|
|
1929
|
-
} catch (error) {
|
|
1930
|
-
console.error("Failed to fix floating image issues:", error);
|
|
1931
|
-
throw error;
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
var init_fixFloatingImageIds = __esm({
|
|
1935
|
-
"src/utils/fixFloatingImageIds.ts"() {
|
|
1936
|
-
"use strict";
|
|
1937
|
-
}
|
|
1938
|
-
});
|
|
1939
|
-
|
|
1940
1695
|
// src/core/generator.ts
|
|
1941
|
-
import { Packer } from "docx";
|
|
1942
1696
|
import { writeFileSync } from "fs";
|
|
1943
1697
|
|
|
1944
1698
|
// src/types/index.ts
|
|
@@ -2111,8 +1865,8 @@ function resolveComponentTree(components, theme) {
|
|
|
2111
1865
|
}
|
|
2112
1866
|
|
|
2113
1867
|
// src/core/structure.ts
|
|
2114
|
-
async function processDocument(document, theme, themeName) {
|
|
2115
|
-
const metadata = createDocumentMetadata(document.props);
|
|
1868
|
+
async function processDocument(document, theme, themeName, generationDate) {
|
|
1869
|
+
const metadata = createDocumentMetadata(document.props, generationDate);
|
|
2116
1870
|
const docDefaults = document.props.componentDefaults;
|
|
2117
1871
|
const mergedComponentDefaults = docDefaults ? mergeWithDefaults2(docDefaults, theme.componentDefaults || {}) : void 0;
|
|
2118
1872
|
const docNoProofWords = document.props.noProofWords;
|
|
@@ -2150,13 +1904,13 @@ async function processDocument(document, theme, themeName) {
|
|
|
2150
1904
|
language: document.props.language
|
|
2151
1905
|
};
|
|
2152
1906
|
}
|
|
2153
|
-
function createDocumentMetadata(props) {
|
|
1907
|
+
function createDocumentMetadata(props, generationDate = /* @__PURE__ */ new Date()) {
|
|
2154
1908
|
return {
|
|
2155
1909
|
title: props.metadata?.title,
|
|
2156
1910
|
subtitle: props.metadata?.subtitle,
|
|
2157
1911
|
author: props.metadata?.author,
|
|
2158
1912
|
company: props.metadata?.company,
|
|
2159
|
-
date: props.metadata?.date ? new Date(props.metadata.date) :
|
|
1913
|
+
date: props.metadata?.date ? new Date(props.metadata.date) : generationDate
|
|
2160
1914
|
};
|
|
2161
1915
|
}
|
|
2162
1916
|
async function extractSections(components, context) {
|
|
@@ -3819,7 +3573,39 @@ function parseTextWithHyperlinks(text, baseStyle = {}, options = {}) {
|
|
|
3819
3573
|
return runs;
|
|
3820
3574
|
}
|
|
3821
3575
|
|
|
3576
|
+
// src/utils/generationContext.ts
|
|
3577
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
3578
|
+
var generationDateStorage = new AsyncLocalStorage();
|
|
3579
|
+
function runWithGenerationDate(date, callback) {
|
|
3580
|
+
return generationDateStorage.run(date, callback);
|
|
3581
|
+
}
|
|
3582
|
+
function getGenerationDate() {
|
|
3583
|
+
return generationDateStorage.getStore() ?? /* @__PURE__ */ new Date();
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3822
3586
|
// src/utils/placeholderProcessor.ts
|
|
3587
|
+
function styledPlaceholderText(text, context) {
|
|
3588
|
+
return new TextRun2({
|
|
3589
|
+
text,
|
|
3590
|
+
font: context?.style?.font,
|
|
3591
|
+
size: context?.style?.size,
|
|
3592
|
+
color: context?.style?.color,
|
|
3593
|
+
bold: context?.style?.bold,
|
|
3594
|
+
italics: context?.style?.italics,
|
|
3595
|
+
underline: context?.style?.underline,
|
|
3596
|
+
language: context?.style?.language,
|
|
3597
|
+
noProof: context?.style?.noProof
|
|
3598
|
+
});
|
|
3599
|
+
}
|
|
3600
|
+
function placeholderDate(context) {
|
|
3601
|
+
return context?.date ?? getGenerationDate();
|
|
3602
|
+
}
|
|
3603
|
+
function isoDate(date) {
|
|
3604
|
+
return date.toISOString().slice(0, 10);
|
|
3605
|
+
}
|
|
3606
|
+
function isoDateTime(date) {
|
|
3607
|
+
return date.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
|
|
3608
|
+
}
|
|
3823
3609
|
var PlaceholderRegistry = class {
|
|
3824
3610
|
static handlers = /* @__PURE__ */ new Map();
|
|
3825
3611
|
/**
|
|
@@ -3875,8 +3661,6 @@ function processTextWithPlaceholders(text, baseStyle = {}, context = {}, noProof
|
|
|
3875
3661
|
const placeholderResult = handler({ ...context, style: baseStyle });
|
|
3876
3662
|
if (Array.isArray(placeholderResult)) {
|
|
3877
3663
|
result.push(...placeholderResult);
|
|
3878
|
-
} else if (placeholderResult instanceof TextRun2) {
|
|
3879
|
-
result.push(placeholderResult);
|
|
3880
3664
|
} else if (typeof placeholderResult === "string") {
|
|
3881
3665
|
result.push(
|
|
3882
3666
|
...createTextRunsWithNewlines2(
|
|
@@ -3885,6 +3669,8 @@ function processTextWithPlaceholders(text, baseStyle = {}, context = {}, noProof
|
|
|
3885
3669
|
noProofWords
|
|
3886
3670
|
)
|
|
3887
3671
|
);
|
|
3672
|
+
} else {
|
|
3673
|
+
result.push(placeholderResult);
|
|
3888
3674
|
}
|
|
3889
3675
|
} else {
|
|
3890
3676
|
result.push(
|
|
@@ -3999,59 +3785,51 @@ function initializeBuiltinPlaceholders() {
|
|
|
3999
3785
|
underline: context?.style?.underline
|
|
4000
3786
|
});
|
|
4001
3787
|
});
|
|
4002
|
-
PlaceholderRegistry.register(
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
const dateTimeString = now.toLocaleString();
|
|
4018
|
-
return new TextRun2({
|
|
4019
|
-
text: dateTimeString,
|
|
4020
|
-
font: context?.style?.font,
|
|
4021
|
-
size: context?.style?.size,
|
|
4022
|
-
color: context?.style?.color,
|
|
4023
|
-
bold: context?.style?.bold,
|
|
4024
|
-
italics: context?.style?.italics,
|
|
4025
|
-
underline: context?.style?.underline
|
|
4026
|
-
});
|
|
4027
|
-
});
|
|
4028
|
-
PlaceholderRegistry.register("YEAR", (context) => {
|
|
4029
|
-
const year = (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
4030
|
-
return new TextRun2({
|
|
4031
|
-
text: year,
|
|
4032
|
-
font: context?.style?.font,
|
|
4033
|
-
size: context?.style?.size,
|
|
4034
|
-
color: context?.style?.color,
|
|
4035
|
-
bold: context?.style?.bold,
|
|
4036
|
-
italics: context?.style?.italics,
|
|
4037
|
-
underline: context?.style?.underline
|
|
4038
|
-
});
|
|
4039
|
-
});
|
|
3788
|
+
PlaceholderRegistry.register(
|
|
3789
|
+
"DATE",
|
|
3790
|
+
(context) => styledPlaceholderText(isoDate(placeholderDate(context)), context)
|
|
3791
|
+
);
|
|
3792
|
+
PlaceholderRegistry.register(
|
|
3793
|
+
"DATETIME",
|
|
3794
|
+
(context) => styledPlaceholderText(isoDateTime(placeholderDate(context)), context)
|
|
3795
|
+
);
|
|
3796
|
+
PlaceholderRegistry.register(
|
|
3797
|
+
"YEAR",
|
|
3798
|
+
(context) => styledPlaceholderText(
|
|
3799
|
+
String(placeholderDate(context).getUTCFullYear()),
|
|
3800
|
+
context
|
|
3801
|
+
)
|
|
3802
|
+
);
|
|
4040
3803
|
}
|
|
4041
3804
|
initializeBuiltinPlaceholders();
|
|
4042
3805
|
|
|
4043
3806
|
// src/utils/revisionUtils.ts
|
|
3807
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
4044
3808
|
var DEFAULT_REVISION_AUTHOR = "json-to-office";
|
|
4045
3809
|
var DEFAULT_REVISION_DATE = "1970-01-01T00:00:00Z";
|
|
4046
3810
|
var RevisionIdRegistry = class {
|
|
4047
|
-
|
|
3811
|
+
fallbackCounter = 0;
|
|
3812
|
+
scopes = new AsyncLocalStorage2();
|
|
3813
|
+
runScoped(callback) {
|
|
3814
|
+
return this.scopes.run({ counter: 0 }, callback);
|
|
3815
|
+
}
|
|
4048
3816
|
next() {
|
|
4049
|
-
this.
|
|
4050
|
-
|
|
3817
|
+
const state = this.scopes.getStore();
|
|
3818
|
+
if (state) {
|
|
3819
|
+
state.counter += 1;
|
|
3820
|
+
return state.counter;
|
|
3821
|
+
}
|
|
3822
|
+
this.fallbackCounter += 1;
|
|
3823
|
+
return this.fallbackCounter;
|
|
4051
3824
|
}
|
|
4052
3825
|
/** Test-only: deterministic ids for snapshot assertions. */
|
|
4053
3826
|
clear() {
|
|
4054
|
-
|
|
3827
|
+
const state = this.scopes.getStore();
|
|
3828
|
+
if (state) {
|
|
3829
|
+
state.counter = 0;
|
|
3830
|
+
} else {
|
|
3831
|
+
this.fallbackCounter = 0;
|
|
3832
|
+
}
|
|
4055
3833
|
}
|
|
4056
3834
|
};
|
|
4057
3835
|
var globalRevisionIdRegistry = new RevisionIdRegistry();
|
|
@@ -4179,7 +3957,10 @@ async function clearComponentCache() {
|
|
|
4179
3957
|
}
|
|
4180
3958
|
}
|
|
4181
3959
|
async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
|
|
4182
|
-
const forceBypassForType = component.name === "toc" || component.name === "section" || component.name === "visual" ||
|
|
3960
|
+
const forceBypassForType = component.name === "toc" || component.name === "section" || component.name === "visual" || component.name === "heading" || // Both explicit lists and markdown-list paragraphs register numbering in
|
|
3961
|
+
// the current document scope. Cached paragraphs can otherwise reference
|
|
3962
|
+
// definitions that only existed in a previous render.
|
|
3963
|
+
component.name === "list" || component.name === "paragraph" || "id" in component || componentHasRevision(component);
|
|
4183
3964
|
if (!componentCache) {
|
|
4184
3965
|
initializeComponentCache();
|
|
4185
3966
|
}
|
|
@@ -4189,8 +3970,9 @@ async function renderComponentWithCache(component, theme, themeName, context, by
|
|
|
4189
3970
|
const componentProps = JSON.stringify(component.props || {});
|
|
4190
3971
|
const themeHash = createThemeHash(theme);
|
|
4191
3972
|
const contextKey = context?.section ? `${context.section.currentLayout}:${context.section.columnCount}` : "no-section";
|
|
3973
|
+
const generationDateKey = getGenerationDate().toISOString();
|
|
4192
3974
|
const childrenKey = "children" in component && component.children ? `:children:${JSON.stringify(component.children)}` : "";
|
|
4193
|
-
const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${componentProps}${childrenKey}`;
|
|
3975
|
+
const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${componentProps}${childrenKey}`;
|
|
4194
3976
|
const cached = await componentCache.get(cacheKey);
|
|
4195
3977
|
if (cached) {
|
|
4196
3978
|
return cached.result;
|
|
@@ -4261,19 +4043,27 @@ init_styles();
|
|
|
4261
4043
|
init_defaults();
|
|
4262
4044
|
|
|
4263
4045
|
// src/utils/bookmarkRegistry.ts
|
|
4046
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
4264
4047
|
var BookmarkRegistry = class {
|
|
4265
|
-
|
|
4266
|
-
|
|
4048
|
+
fallback = { bookmarks: /* @__PURE__ */ new Map() };
|
|
4049
|
+
scopes = new AsyncLocalStorage3();
|
|
4050
|
+
get state() {
|
|
4051
|
+
return this.scopes.getStore() ?? this.fallback;
|
|
4052
|
+
}
|
|
4053
|
+
/** Run work with an isolated registry that follows its async call chain. */
|
|
4054
|
+
runScoped(callback) {
|
|
4055
|
+
return this.scopes.run({ bookmarks: /* @__PURE__ */ new Map() }, callback);
|
|
4056
|
+
}
|
|
4267
4057
|
/**
|
|
4268
4058
|
* Register a bookmark
|
|
4269
4059
|
*/
|
|
4270
4060
|
register(id, title, type) {
|
|
4271
|
-
if (this.bookmarks.has(id)) {
|
|
4061
|
+
if (this.state.bookmarks.has(id)) {
|
|
4272
4062
|
console.warn(
|
|
4273
4063
|
`Duplicate bookmark ID: ${id}. Using the latest registration.`
|
|
4274
4064
|
);
|
|
4275
4065
|
}
|
|
4276
|
-
this.bookmarks.set(id, { id, title, type });
|
|
4066
|
+
this.state.bookmarks.set(id, { id, title, type });
|
|
4277
4067
|
}
|
|
4278
4068
|
/**
|
|
4279
4069
|
* Generate a unique bookmark ID from text
|
|
@@ -4283,7 +4073,7 @@ var BookmarkRegistry = class {
|
|
|
4283
4073
|
const baseId = text.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").substring(0, 40);
|
|
4284
4074
|
let id = baseId;
|
|
4285
4075
|
let attempt = 0;
|
|
4286
|
-
while (this.bookmarks.has(id) && attempt < 100) {
|
|
4076
|
+
while (this.state.bookmarks.has(id) && attempt < 100) {
|
|
4287
4077
|
id = `${baseId}-${++attempt}`;
|
|
4288
4078
|
}
|
|
4289
4079
|
return id;
|
|
@@ -4292,26 +4082,25 @@ var BookmarkRegistry = class {
|
|
|
4292
4082
|
* Check if a bookmark exists
|
|
4293
4083
|
*/
|
|
4294
4084
|
exists(id) {
|
|
4295
|
-
return this.bookmarks.has(id);
|
|
4085
|
+
return this.state.bookmarks.has(id);
|
|
4296
4086
|
}
|
|
4297
4087
|
/**
|
|
4298
4088
|
* Get bookmark info by ID
|
|
4299
4089
|
*/
|
|
4300
4090
|
get(id) {
|
|
4301
|
-
return this.bookmarks.get(id);
|
|
4091
|
+
return this.state.bookmarks.get(id);
|
|
4302
4092
|
}
|
|
4303
4093
|
/**
|
|
4304
4094
|
* Get all registered bookmarks
|
|
4305
4095
|
*/
|
|
4306
4096
|
getAll() {
|
|
4307
|
-
return Array.from(this.bookmarks.values());
|
|
4097
|
+
return Array.from(this.state.bookmarks.values());
|
|
4308
4098
|
}
|
|
4309
4099
|
/**
|
|
4310
4100
|
* Clear all bookmarks
|
|
4311
4101
|
*/
|
|
4312
4102
|
clear() {
|
|
4313
|
-
this.bookmarks.clear();
|
|
4314
|
-
this.counter = 0;
|
|
4103
|
+
this.state.bookmarks.clear();
|
|
4315
4104
|
}
|
|
4316
4105
|
/**
|
|
4317
4106
|
* Validate that all internal hyperlink references exist
|
|
@@ -5599,8 +5388,173 @@ function renderHeadingComponent(component, theme, themeName) {
|
|
|
5599
5388
|
return [header];
|
|
5600
5389
|
}
|
|
5601
5390
|
|
|
5391
|
+
// src/utils/numberingConfig.ts
|
|
5392
|
+
import { AlignmentType as AlignmentType3, convertInchesToTwip, LevelFormat } from "docx";
|
|
5393
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
5394
|
+
var LEVEL_FORMAT_MAP = {
|
|
5395
|
+
decimal: LevelFormat.DECIMAL,
|
|
5396
|
+
upperRoman: LevelFormat.UPPER_ROMAN,
|
|
5397
|
+
lowerRoman: LevelFormat.LOWER_ROMAN,
|
|
5398
|
+
upperLetter: LevelFormat.UPPER_LETTER,
|
|
5399
|
+
lowerLetter: LevelFormat.LOWER_LETTER,
|
|
5400
|
+
bullet: LevelFormat.BULLET,
|
|
5401
|
+
ordinal: LevelFormat.ORDINAL,
|
|
5402
|
+
cardinalText: LevelFormat.CARDINAL_TEXT,
|
|
5403
|
+
ordinalText: LevelFormat.ORDINAL_TEXT,
|
|
5404
|
+
hex: LevelFormat.HEX,
|
|
5405
|
+
chicago: LevelFormat.CHICAGO,
|
|
5406
|
+
ideographDigital: LevelFormat.IDEOGRAPH__DIGITAL,
|
|
5407
|
+
japaneseCounting: LevelFormat.JAPANESE_COUNTING,
|
|
5408
|
+
aiueo: LevelFormat.AIUEO,
|
|
5409
|
+
iroha: LevelFormat.IROHA,
|
|
5410
|
+
decimalFullWidth: LevelFormat.DECIMAL_FULL_WIDTH,
|
|
5411
|
+
decimalHalfWidth: LevelFormat.DECIMAL_HALF_WIDTH,
|
|
5412
|
+
japaneseLegal: LevelFormat.JAPANESE_LEGAL,
|
|
5413
|
+
japaneseDigitalTenThousand: LevelFormat.JAPANESE_DIGITAL_TEN_THOUSAND,
|
|
5414
|
+
decimalEnclosedCircle: LevelFormat.DECIMAL_ENCLOSED_CIRCLE,
|
|
5415
|
+
decimalFullWidth2: LevelFormat.DECIMAL_FULL_WIDTH2,
|
|
5416
|
+
aiueoFullWidth: LevelFormat.AIUEO_FULL_WIDTH,
|
|
5417
|
+
irohaFullWidth: LevelFormat.IROHA_FULL_WIDTH,
|
|
5418
|
+
decimalZero: LevelFormat.DECIMAL_ZERO,
|
|
5419
|
+
ganada: LevelFormat.GANADA,
|
|
5420
|
+
chosung: LevelFormat.CHOSUNG,
|
|
5421
|
+
decimalEnclosedFullstop: LevelFormat.DECIMAL_ENCLOSED_FULLSTOP,
|
|
5422
|
+
decimalEnclosedParen: LevelFormat.DECIMAL_ENCLOSED_PARENTHESES,
|
|
5423
|
+
decimalEnclosedCircleChinese: LevelFormat.DECIMAL_ENCLOSED_CIRCLE_CHINESE,
|
|
5424
|
+
ideographEnclosedCircle: LevelFormat.IDEOGRAPH_ENCLOSED_CIRCLE,
|
|
5425
|
+
ideographTraditional: LevelFormat.IDEOGRAPH_TRADITIONAL,
|
|
5426
|
+
ideographZodiac: LevelFormat.IDEOGRAPH_ZODIAC,
|
|
5427
|
+
ideographZodiacTraditional: LevelFormat.IDEOGRAPH_ZODIAC_TRADITIONAL,
|
|
5428
|
+
taiwaneseCounting: LevelFormat.TAIWANESE_COUNTING,
|
|
5429
|
+
ideographLegalTraditional: LevelFormat.IDEOGRAPH_LEGAL_TRADITIONAL,
|
|
5430
|
+
taiwaneseCountingThousand: LevelFormat.TAIWANESE_COUNTING_THOUSAND,
|
|
5431
|
+
taiwaneseDigital: LevelFormat.TAIWANESE_DIGITAL,
|
|
5432
|
+
chineseCounting: LevelFormat.CHINESE_COUNTING,
|
|
5433
|
+
chineseLegalSimplified: LevelFormat.CHINESE_LEGAL_SIMPLIFIED,
|
|
5434
|
+
chineseCountingThousand: LevelFormat.CHINESE_COUNTING_THOUSAND,
|
|
5435
|
+
koreanDigital: LevelFormat.KOREAN_DIGITAL,
|
|
5436
|
+
koreanCounting: LevelFormat.KOREAN_COUNTING,
|
|
5437
|
+
koreanLegal: LevelFormat.KOREAN_LEGAL,
|
|
5438
|
+
koreanDigital2: LevelFormat.KOREAN_DIGITAL2,
|
|
5439
|
+
vietnameseCounting: LevelFormat.VIETNAMESE_COUNTING,
|
|
5440
|
+
russianLower: LevelFormat.RUSSIAN_LOWER,
|
|
5441
|
+
russianUpper: LevelFormat.RUSSIAN_UPPER,
|
|
5442
|
+
none: LevelFormat.NONE,
|
|
5443
|
+
numberInDash: LevelFormat.NUMBER_IN_DASH,
|
|
5444
|
+
hebrew1: LevelFormat.HEBREW1,
|
|
5445
|
+
hebrew2: LevelFormat.HEBREW2,
|
|
5446
|
+
arabicAlpha: LevelFormat.ARABIC_ALPHA,
|
|
5447
|
+
arabicAbjad: LevelFormat.ARABIC_ABJAD,
|
|
5448
|
+
hindiVowels: LevelFormat.HINDI_VOWELS,
|
|
5449
|
+
hindiConsonants: LevelFormat.HINDI_CONSONANTS,
|
|
5450
|
+
hindiNumbers: LevelFormat.HINDI_NUMBERS,
|
|
5451
|
+
hindiCounting: LevelFormat.HINDI_COUNTING,
|
|
5452
|
+
thaiLetters: LevelFormat.THAI_LETTERS,
|
|
5453
|
+
thaiNumbers: LevelFormat.THAI_NUMBERS,
|
|
5454
|
+
thaiCounting: LevelFormat.THAI_COUNTING
|
|
5455
|
+
};
|
|
5456
|
+
var ALIGNMENT_MAP = {
|
|
5457
|
+
start: AlignmentType3.START,
|
|
5458
|
+
end: AlignmentType3.END,
|
|
5459
|
+
left: AlignmentType3.LEFT,
|
|
5460
|
+
right: AlignmentType3.RIGHT,
|
|
5461
|
+
center: AlignmentType3.CENTER
|
|
5462
|
+
};
|
|
5463
|
+
function getLevelFormat(format2) {
|
|
5464
|
+
if (!format2) return LevelFormat.BULLET;
|
|
5465
|
+
return LEVEL_FORMAT_MAP[format2] || LevelFormat.BULLET;
|
|
5466
|
+
}
|
|
5467
|
+
function getAlignment2(alignment) {
|
|
5468
|
+
if (!alignment) return AlignmentType3.LEFT;
|
|
5469
|
+
return ALIGNMENT_MAP[alignment] || AlignmentType3.LEFT;
|
|
5470
|
+
}
|
|
5471
|
+
function createNumberingConfig(config) {
|
|
5472
|
+
const levels = [];
|
|
5473
|
+
for (const levelConfig of config.levels) {
|
|
5474
|
+
const format2 = getLevelFormat(levelConfig.format);
|
|
5475
|
+
const alignment = getAlignment2(levelConfig.alignment);
|
|
5476
|
+
const text = levelConfig.text || (format2 === LevelFormat.BULLET ? "\u2022" : `%${levelConfig.level + 1}.`);
|
|
5477
|
+
const baseIndent = levelConfig.indent?.left !== void 0 ? levelConfig.indent.left / 72 : 0.5 * (levelConfig.level + 1);
|
|
5478
|
+
const hangingIndent = levelConfig.indent?.hanging !== void 0 ? levelConfig.indent.hanging / 72 : 0.25;
|
|
5479
|
+
const level = {
|
|
5480
|
+
level: levelConfig.level,
|
|
5481
|
+
format: format2,
|
|
5482
|
+
text,
|
|
5483
|
+
alignment,
|
|
5484
|
+
style: {
|
|
5485
|
+
paragraph: {
|
|
5486
|
+
indent: {
|
|
5487
|
+
left: convertInchesToTwip(baseIndent),
|
|
5488
|
+
hanging: convertInchesToTwip(hangingIndent)
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
},
|
|
5492
|
+
// Add start number if specified
|
|
5493
|
+
...levelConfig.start !== void 0 && { start: levelConfig.start }
|
|
5494
|
+
};
|
|
5495
|
+
levels.push(level);
|
|
5496
|
+
}
|
|
5497
|
+
return {
|
|
5498
|
+
reference: config.reference,
|
|
5499
|
+
levels
|
|
5500
|
+
};
|
|
5501
|
+
}
|
|
5502
|
+
var NumberingRegistry = class {
|
|
5503
|
+
fallback = {
|
|
5504
|
+
configs: /* @__PURE__ */ new Map(),
|
|
5505
|
+
counter: 0
|
|
5506
|
+
};
|
|
5507
|
+
scopes = new AsyncLocalStorage4();
|
|
5508
|
+
get state() {
|
|
5509
|
+
return this.scopes.getStore() ?? this.fallback;
|
|
5510
|
+
}
|
|
5511
|
+
/** Run work with an isolated registry that follows its async call chain. */
|
|
5512
|
+
runScoped(callback) {
|
|
5513
|
+
return this.scopes.run({ configs: /* @__PURE__ */ new Map(), counter: 0 }, callback);
|
|
5514
|
+
}
|
|
5515
|
+
/**
|
|
5516
|
+
* Register a numbering configuration
|
|
5517
|
+
*/
|
|
5518
|
+
register(config) {
|
|
5519
|
+
const reference = config.reference;
|
|
5520
|
+
this.state.configs.set(reference, config);
|
|
5521
|
+
return reference;
|
|
5522
|
+
}
|
|
5523
|
+
/**
|
|
5524
|
+
* Generate a unique reference ID
|
|
5525
|
+
*/
|
|
5526
|
+
generateReference(prefix = "list") {
|
|
5527
|
+
return `${prefix}-${++this.state.counter}`;
|
|
5528
|
+
}
|
|
5529
|
+
/**
|
|
5530
|
+
* Get all registered configurations as an array suitable for INumberingOptions
|
|
5531
|
+
*/
|
|
5532
|
+
getAll() {
|
|
5533
|
+
return Array.from(this.state.configs.values());
|
|
5534
|
+
}
|
|
5535
|
+
/**
|
|
5536
|
+
* Clear all configurations
|
|
5537
|
+
*/
|
|
5538
|
+
clear() {
|
|
5539
|
+
this.state.configs.clear();
|
|
5540
|
+
this.state.counter = 0;
|
|
5541
|
+
}
|
|
5542
|
+
/**
|
|
5543
|
+
* Check if a reference exists
|
|
5544
|
+
*/
|
|
5545
|
+
has(reference) {
|
|
5546
|
+
return this.state.configs.has(reference);
|
|
5547
|
+
}
|
|
5548
|
+
/**
|
|
5549
|
+
* Get a configuration by reference
|
|
5550
|
+
*/
|
|
5551
|
+
get(reference) {
|
|
5552
|
+
return this.state.configs.get(reference);
|
|
5553
|
+
}
|
|
5554
|
+
};
|
|
5555
|
+
var globalNumberingRegistry = new NumberingRegistry();
|
|
5556
|
+
|
|
5602
5557
|
// src/components/paragraph.ts
|
|
5603
|
-
init_numberingConfig();
|
|
5604
5558
|
function parseMarkdownList(text) {
|
|
5605
5559
|
const lines = text.split("\n");
|
|
5606
5560
|
const items = [];
|
|
@@ -5726,7 +5680,6 @@ function renderParagraphComponent(component, theme, themeName) {
|
|
|
5726
5680
|
}
|
|
5727
5681
|
|
|
5728
5682
|
// src/components/list.ts
|
|
5729
|
-
init_numberingConfig();
|
|
5730
5683
|
function createLevelsFromSimplifiedProps(props) {
|
|
5731
5684
|
const levels = [];
|
|
5732
5685
|
let format2;
|
|
@@ -6150,17 +6103,22 @@ async function renderTableComponent(component, theme, themeName) {
|
|
|
6150
6103
|
|
|
6151
6104
|
// src/components/section.ts
|
|
6152
6105
|
import { Paragraph as Paragraph4, BookmarkStart, BookmarkEnd } from "docx";
|
|
6153
|
-
function generateSectionBookmarkId() {
|
|
6154
|
-
const
|
|
6106
|
+
function generateSectionBookmarkId(context) {
|
|
6107
|
+
const custom = context.custom ??= {};
|
|
6108
|
+
const state = custom.sectionBookmarks ??= {
|
|
6109
|
+
next: 1
|
|
6110
|
+
};
|
|
6111
|
+
const ordinal = state.next++;
|
|
6112
|
+
const linkId = 1e6 + ordinal;
|
|
6155
6113
|
return {
|
|
6156
|
-
id: `
|
|
6114
|
+
id: `_NestedSection_${ordinal}`,
|
|
6157
6115
|
linkId
|
|
6158
6116
|
};
|
|
6159
6117
|
}
|
|
6160
6118
|
async function renderSectionComponent(component, theme, themeName, context) {
|
|
6161
6119
|
if (!isSectionComponent(component)) return [];
|
|
6162
6120
|
const elements = [];
|
|
6163
|
-
const { id: sectionBookmarkId, linkId: bookmarkLinkId } = generateSectionBookmarkId();
|
|
6121
|
+
const { id: sectionBookmarkId, linkId: bookmarkLinkId } = generateSectionBookmarkId(context);
|
|
6164
6122
|
elements.push(
|
|
6165
6123
|
new Paragraph4({
|
|
6166
6124
|
children: [new BookmarkStart(sectionBookmarkId, bookmarkLinkId)],
|
|
@@ -6576,9 +6534,23 @@ Cause: ${cause}`
|
|
|
6576
6534
|
height
|
|
6577
6535
|
};
|
|
6578
6536
|
}
|
|
6537
|
+
function withThemeColors(config, theme) {
|
|
6538
|
+
const options = config.options;
|
|
6539
|
+
if (!options || options.colors || !theme?.colors) return config;
|
|
6540
|
+
const palette = [
|
|
6541
|
+
theme.colors.primary,
|
|
6542
|
+
theme.colors.secondary,
|
|
6543
|
+
theme.colors.accent
|
|
6544
|
+
].filter((c) => typeof c === "string" && c.length > 0).map((c) => c.startsWith("#") ? c : `#${c}`);
|
|
6545
|
+
if (palette.length === 0) return config;
|
|
6546
|
+
return {
|
|
6547
|
+
...config,
|
|
6548
|
+
options: { ...config.options, colors: palette }
|
|
6549
|
+
};
|
|
6550
|
+
}
|
|
6579
6551
|
async function renderHighchartsComponent(component, theme, themeName, context) {
|
|
6580
6552
|
if (!isHighchartsComponent(component)) return [];
|
|
6581
|
-
const config = component.props;
|
|
6553
|
+
const config = withThemeColors(component.props, theme);
|
|
6582
6554
|
const chartResult = await generateChart(
|
|
6583
6555
|
config,
|
|
6584
6556
|
context?.services?.highcharts
|
|
@@ -6775,13 +6747,23 @@ function getAlignment3(alignment) {
|
|
|
6775
6747
|
}
|
|
6776
6748
|
}
|
|
6777
6749
|
async function renderDocument(structure, layout, options) {
|
|
6750
|
+
return runWithGenerationDate(
|
|
6751
|
+
structure.metadata.date,
|
|
6752
|
+
() => globalBookmarkRegistry.runScoped(
|
|
6753
|
+
() => globalRevisionIdRegistry.runScoped(
|
|
6754
|
+
() => globalNumberingRegistry.runScoped(
|
|
6755
|
+
() => renderDocumentScoped(structure, layout, options)
|
|
6756
|
+
)
|
|
6757
|
+
)
|
|
6758
|
+
)
|
|
6759
|
+
);
|
|
6760
|
+
}
|
|
6761
|
+
async function renderDocumentScoped(structure, layout, options) {
|
|
6778
6762
|
if (options?.cache) {
|
|
6779
6763
|
initializeComponentCache(options.cache);
|
|
6780
6764
|
} else if (!options?.bypassCache) {
|
|
6781
6765
|
initializeComponentCache();
|
|
6782
6766
|
}
|
|
6783
|
-
const { globalNumberingRegistry: globalNumberingRegistry2 } = await Promise.resolve().then(() => (init_numberingConfig(), numberingConfig_exports));
|
|
6784
|
-
globalNumberingRegistry2.clear();
|
|
6785
6767
|
const sections = [];
|
|
6786
6768
|
const context = createRenderContext(
|
|
6787
6769
|
structure,
|
|
@@ -6838,7 +6820,8 @@ async function renderDocument(structure, layout, options) {
|
|
|
6838
6820
|
structure.themeName,
|
|
6839
6821
|
context,
|
|
6840
6822
|
sectionOrdinal,
|
|
6841
|
-
closeBookmark
|
|
6823
|
+
closeBookmark,
|
|
6824
|
+
options?.bypassCache === true
|
|
6842
6825
|
);
|
|
6843
6826
|
if (layoutSection.isUserSection) {
|
|
6844
6827
|
sectionBookmarkCounter++;
|
|
@@ -6847,7 +6830,7 @@ async function renderDocument(structure, layout, options) {
|
|
|
6847
6830
|
sections.push(rendered);
|
|
6848
6831
|
}
|
|
6849
6832
|
}
|
|
6850
|
-
const numberingConfigs =
|
|
6833
|
+
const numberingConfigs = globalNumberingRegistry.getAll();
|
|
6851
6834
|
return new Document({
|
|
6852
6835
|
styles: createWordStyles(structure.theme, structure.language),
|
|
6853
6836
|
sections,
|
|
@@ -7015,7 +6998,7 @@ async function renderHeaderFooterComponents(components, theme, themeName, contex
|
|
|
7015
6998
|
}
|
|
7016
6999
|
return elements;
|
|
7017
7000
|
}
|
|
7018
|
-
async function renderSection(section, theme, themeName, context, sectionOrdinal, closeBookmark) {
|
|
7001
|
+
async function renderSection(section, theme, themeName, context, sectionOrdinal, closeBookmark, bypassCache = false) {
|
|
7019
7002
|
const elements = [];
|
|
7020
7003
|
const isFirstLayoutOfUserSection = section.isUserSection;
|
|
7021
7004
|
const sharedLinkId = section.belongsToUserSection && sectionOrdinal ? sectionOrdinal : void 0;
|
|
@@ -7053,8 +7036,7 @@ async function renderSection(section, theme, themeName, context, sectionOrdinal,
|
|
|
7053
7036
|
theme,
|
|
7054
7037
|
themeName,
|
|
7055
7038
|
sectionContext,
|
|
7056
|
-
|
|
7057
|
-
// Don't bypass cache
|
|
7039
|
+
bypassCache
|
|
7058
7040
|
);
|
|
7059
7041
|
elements.push(...rendered);
|
|
7060
7042
|
}
|
|
@@ -7204,6 +7186,75 @@ async function resolveDocumentFonts(document, theme, fonts, warnings) {
|
|
|
7204
7186
|
// src/core/generator.ts
|
|
7205
7187
|
import { applyExportMode, scopedThemeName } from "@json-to-office/shared";
|
|
7206
7188
|
|
|
7189
|
+
// src/utils/packageDocument.ts
|
|
7190
|
+
import AdmZip2 from "adm-zip";
|
|
7191
|
+
import { Packer } from "docx";
|
|
7192
|
+
|
|
7193
|
+
// src/utils/fixFloatingImageIds.ts
|
|
7194
|
+
import AdmZip from "adm-zip";
|
|
7195
|
+
function fixFloatingImageIdsInBuffer(buffer) {
|
|
7196
|
+
const zip = new AdmZip(buffer);
|
|
7197
|
+
const documentEntry = zip.getEntry("word/document.xml");
|
|
7198
|
+
if (!documentEntry) {
|
|
7199
|
+
throw new Error("document.xml not found in DOCX");
|
|
7200
|
+
}
|
|
7201
|
+
let idCounter = 1;
|
|
7202
|
+
const documentXml = documentEntry.getData().toString("utf8").replace(/<wp:docPr\s+id="(\d+)"/g, () => {
|
|
7203
|
+
const newId = idCounter++;
|
|
7204
|
+
return `<wp:docPr id="${newId}"`;
|
|
7205
|
+
});
|
|
7206
|
+
zip.updateFile(documentEntry, Buffer.from(documentXml, "utf8"));
|
|
7207
|
+
return zip.toBuffer();
|
|
7208
|
+
}
|
|
7209
|
+
|
|
7210
|
+
// src/utils/packageDocument.ts
|
|
7211
|
+
var DEFAULT_GENERATION_DATE = /* @__PURE__ */ new Date("2000-01-01T00:00:00.000Z");
|
|
7212
|
+
function resolveGenerationDate(options) {
|
|
7213
|
+
if (options?.generatedAt !== void 0) {
|
|
7214
|
+
const date = new Date(options.generatedAt);
|
|
7215
|
+
if (Number.isNaN(date.getTime())) {
|
|
7216
|
+
throw new RangeError("generatedAt must be a valid date");
|
|
7217
|
+
}
|
|
7218
|
+
if (date.getUTCFullYear() < 1980) {
|
|
7219
|
+
throw new RangeError(
|
|
7220
|
+
"generatedAt must be on or after 1980-01-01 for ZIP compatibility"
|
|
7221
|
+
);
|
|
7222
|
+
}
|
|
7223
|
+
return date;
|
|
7224
|
+
}
|
|
7225
|
+
return options?.deterministic === false ? /* @__PURE__ */ new Date() : new Date(DEFAULT_GENERATION_DATE);
|
|
7226
|
+
}
|
|
7227
|
+
function toDosTime(date) {
|
|
7228
|
+
const dosDate = (date.getUTCFullYear() - 1980 & 127) << 9 | date.getUTCMonth() + 1 << 5 | date.getUTCDate();
|
|
7229
|
+
const dosTime = date.getUTCHours() << 11 | date.getUTCMinutes() << 5 | date.getUTCSeconds() >> 1;
|
|
7230
|
+
return (dosDate << 16 | dosTime) >>> 0;
|
|
7231
|
+
}
|
|
7232
|
+
function canonicalizeDocxBuffer(buffer, generatedAt = DEFAULT_GENERATION_DATE) {
|
|
7233
|
+
const zip = new AdmZip2(buffer);
|
|
7234
|
+
const isoTimestamp = generatedAt.toISOString();
|
|
7235
|
+
const coreProperties = zip.getEntry("docProps/core.xml");
|
|
7236
|
+
if (coreProperties) {
|
|
7237
|
+
const normalized = coreProperties.getData().toString("utf8").replace(
|
|
7238
|
+
/(<dcterms:(?:created|modified)\b[^>]*>)[^<]*(<\/dcterms:(?:created|modified)>)/g,
|
|
7239
|
+
`$1${isoTimestamp}$2`
|
|
7240
|
+
);
|
|
7241
|
+
zip.updateFile(coreProperties, Buffer.from(normalized, "utf8"));
|
|
7242
|
+
}
|
|
7243
|
+
const zipTimestamp = toDosTime(generatedAt);
|
|
7244
|
+
for (const entry of zip.getEntries()) {
|
|
7245
|
+
entry.header.timeval = zipTimestamp;
|
|
7246
|
+
}
|
|
7247
|
+
return zip.toBuffer();
|
|
7248
|
+
}
|
|
7249
|
+
async function packageDocument(document, options) {
|
|
7250
|
+
const packed = await Packer.toBuffer(document);
|
|
7251
|
+
const fixed = fixFloatingImageIdsInBuffer(packed);
|
|
7252
|
+
if (options?.deterministic === false) {
|
|
7253
|
+
return fixed;
|
|
7254
|
+
}
|
|
7255
|
+
return canonicalizeDocxBuffer(fixed, resolveGenerationDate(options));
|
|
7256
|
+
}
|
|
7257
|
+
|
|
7207
7258
|
// src/json/parser.ts
|
|
7208
7259
|
import {
|
|
7209
7260
|
JsonDocumentParser,
|
|
@@ -7375,7 +7426,8 @@ async function generateDocument(document, options) {
|
|
|
7375
7426
|
options?.customThemes,
|
|
7376
7427
|
options?.services,
|
|
7377
7428
|
options?.fonts,
|
|
7378
|
-
options?.warnings
|
|
7429
|
+
options?.warnings,
|
|
7430
|
+
resolveGenerationDate(options)
|
|
7379
7431
|
);
|
|
7380
7432
|
}
|
|
7381
7433
|
async function generateFromConfig(props, components, options) {
|
|
@@ -7386,7 +7438,7 @@ async function generateFromConfig(props, components, options) {
|
|
|
7386
7438
|
};
|
|
7387
7439
|
return await generateDocument(reportComponent, options);
|
|
7388
7440
|
}
|
|
7389
|
-
async function generateDocumentWithCustomThemes(documentIn, customThemes, services, fonts, warnings) {
|
|
7441
|
+
async function generateDocumentWithCustomThemes(documentIn, customThemes, services, fonts, warnings, generationDate) {
|
|
7390
7442
|
let document = documentIn;
|
|
7391
7443
|
let themeName = document.props.theme || "minimal";
|
|
7392
7444
|
let theme;
|
|
@@ -7424,7 +7476,12 @@ async function generateDocumentWithCustomThemes(documentIn, customThemes, servic
|
|
|
7424
7476
|
}
|
|
7425
7477
|
}
|
|
7426
7478
|
await resolveDocumentFonts(document, theme, fonts, warnings);
|
|
7427
|
-
const structure = await processDocument(
|
|
7479
|
+
const structure = await processDocument(
|
|
7480
|
+
document,
|
|
7481
|
+
theme,
|
|
7482
|
+
themeName,
|
|
7483
|
+
generationDate
|
|
7484
|
+
);
|
|
7428
7485
|
const layout = applyLayout(structure.sections, theme, themeName);
|
|
7429
7486
|
const renderedDocument = await renderDocument(structure, layout, {
|
|
7430
7487
|
bypassCache: false,
|
|
@@ -7472,7 +7529,8 @@ async function generateDocumentFromJson(jsonConfig, options) {
|
|
|
7472
7529
|
options?.customThemes,
|
|
7473
7530
|
options?.services,
|
|
7474
7531
|
options?.fonts,
|
|
7475
|
-
options?.warnings
|
|
7532
|
+
options?.warnings,
|
|
7533
|
+
resolveGenerationDate(options)
|
|
7476
7534
|
);
|
|
7477
7535
|
}
|
|
7478
7536
|
function validateJsonSchema(jsonConfig) {
|
|
@@ -7480,11 +7538,11 @@ function validateJsonSchema(jsonConfig) {
|
|
|
7480
7538
|
}
|
|
7481
7539
|
async function generateBufferFromJson(jsonConfig, options) {
|
|
7482
7540
|
const document = await generateDocumentFromJson(jsonConfig, options);
|
|
7483
|
-
return
|
|
7541
|
+
return packageDocument(document, options);
|
|
7484
7542
|
}
|
|
7485
7543
|
async function generateAndSaveFromJson(jsonConfig, filename, options) {
|
|
7486
7544
|
const document = await generateDocumentFromJson(jsonConfig, options);
|
|
7487
|
-
await saveDocument(document, filename);
|
|
7545
|
+
await saveDocument(document, filename, options);
|
|
7488
7546
|
}
|
|
7489
7547
|
async function generateDocumentFromFile(filePath, options) {
|
|
7490
7548
|
const jsonDefinition = await loadJsonDefinition(filePath);
|
|
@@ -7492,25 +7550,19 @@ async function generateDocumentFromFile(filePath, options) {
|
|
|
7492
7550
|
}
|
|
7493
7551
|
async function generateBufferFromFile(filePath, options) {
|
|
7494
7552
|
const document = await generateDocumentFromFile(filePath, options);
|
|
7495
|
-
return
|
|
7553
|
+
return packageDocument(document, options);
|
|
7496
7554
|
}
|
|
7497
7555
|
async function generateAndSaveFromFile(inputFilePath, outputFilePath, options) {
|
|
7498
7556
|
const document = await generateDocumentFromFile(inputFilePath, options);
|
|
7499
|
-
await saveDocument(document, outputFilePath);
|
|
7557
|
+
await saveDocument(document, outputFilePath, options);
|
|
7500
7558
|
}
|
|
7501
|
-
async function saveDocument(document, filename) {
|
|
7502
|
-
const buffer = await
|
|
7559
|
+
async function saveDocument(document, filename, options) {
|
|
7560
|
+
const buffer = await packageDocument(document, options);
|
|
7503
7561
|
writeFileSync(filename, buffer);
|
|
7504
|
-
try {
|
|
7505
|
-
const { fixFloatingImageIds: fixFloatingImageIds2 } = await Promise.resolve().then(() => (init_fixFloatingImageIds(), fixFloatingImageIds_exports));
|
|
7506
|
-
await fixFloatingImageIds2(filename);
|
|
7507
|
-
} catch (error) {
|
|
7508
|
-
console.warn("Failed to fix floating image IDs (non-critical):", error);
|
|
7509
|
-
}
|
|
7510
7562
|
}
|
|
7511
|
-
async function generateAndSave(document, filename) {
|
|
7512
|
-
const generatedDocument = await generateDocument(document);
|
|
7513
|
-
await saveDocument(generatedDocument, filename);
|
|
7563
|
+
async function generateAndSave(document, filename, options) {
|
|
7564
|
+
const generatedDocument = await generateDocument(document, options);
|
|
7565
|
+
await saveDocument(generatedDocument, filename, options);
|
|
7514
7566
|
}
|
|
7515
7567
|
var DocumentGenerator = {
|
|
7516
7568
|
generate: generateDocument,
|
|
@@ -7840,7 +7892,6 @@ async function runExample(example, options = {}) {
|
|
|
7840
7892
|
|
|
7841
7893
|
// src/plugin/createDocumentGenerator.ts
|
|
7842
7894
|
init_styles();
|
|
7843
|
-
import { Packer as Packer2 } from "docx";
|
|
7844
7895
|
import { applyExportMode as applyExportMode2, scopedThemeName as scopedThemeName2 } from "@json-to-office/shared";
|
|
7845
7896
|
|
|
7846
7897
|
// src/plugin/version-resolver.ts
|
|
@@ -8237,7 +8288,10 @@ function createBuilderImpl(state) {
|
|
|
8237
8288
|
debug: state.debug,
|
|
8238
8289
|
enableCache: state.enableCache,
|
|
8239
8290
|
services: state.services,
|
|
8240
|
-
fonts: state.fonts
|
|
8291
|
+
fonts: state.fonts,
|
|
8292
|
+
validation: state.validation,
|
|
8293
|
+
deterministic: state.deterministic,
|
|
8294
|
+
generatedAt: state.generatedAt
|
|
8241
8295
|
};
|
|
8242
8296
|
return createBuilderImpl(
|
|
8243
8297
|
newState
|
|
@@ -8329,10 +8383,20 @@ function createBuilderImpl(state) {
|
|
|
8329
8383
|
};
|
|
8330
8384
|
const [modedDoc] = normalizeDocument(processedDocument);
|
|
8331
8385
|
await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);
|
|
8332
|
-
const
|
|
8386
|
+
const packageOptions = {
|
|
8387
|
+
deterministic: options?.deterministic ?? state.deterministic,
|
|
8388
|
+
generatedAt: options?.generatedAt ?? state.generatedAt
|
|
8389
|
+
};
|
|
8390
|
+
const structure = await processDocument(
|
|
8391
|
+
modedDoc,
|
|
8392
|
+
modedTheme,
|
|
8393
|
+
themeName,
|
|
8394
|
+
resolveGenerationDate(packageOptions)
|
|
8395
|
+
);
|
|
8333
8396
|
const layout = applyLayout(structure.sections, modedTheme, themeName);
|
|
8334
8397
|
const generatedDocument = await renderDocument(structure, layout, {
|
|
8335
|
-
services: state.services
|
|
8398
|
+
services: state.services,
|
|
8399
|
+
bypassCache: !state.enableCache
|
|
8336
8400
|
});
|
|
8337
8401
|
const preservedDefinition = preserveSet ? {
|
|
8338
8402
|
...mode.doc,
|
|
@@ -8358,7 +8422,10 @@ function createBuilderImpl(state) {
|
|
|
8358
8422
|
standardDefinition,
|
|
8359
8423
|
preservedDefinition
|
|
8360
8424
|
} = await generate(document, options);
|
|
8361
|
-
const buffer = await
|
|
8425
|
+
const buffer = await packageDocument(doc, {
|
|
8426
|
+
deterministic: options?.deterministic ?? state.deterministic,
|
|
8427
|
+
generatedAt: options?.generatedAt ?? state.generatedAt
|
|
8428
|
+
});
|
|
8362
8429
|
return { buffer, warnings, standardDefinition, preservedDefinition };
|
|
8363
8430
|
}
|
|
8364
8431
|
async function generateFile(document, outputPath, options) {
|
|
@@ -8457,7 +8524,9 @@ function createDocumentGenerator(options) {
|
|
|
8457
8524
|
enableCache: options.enableCache ?? false,
|
|
8458
8525
|
services: options.services,
|
|
8459
8526
|
fonts: options.fonts,
|
|
8460
|
-
validation: options.validation
|
|
8527
|
+
validation: options.validation,
|
|
8528
|
+
deterministic: options.deterministic ?? true,
|
|
8529
|
+
generatedAt: options.generatedAt
|
|
8461
8530
|
};
|
|
8462
8531
|
return createBuilderImpl(initialState);
|
|
8463
8532
|
}
|