@office-open/core 0.6.3 → 0.6.5
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/chart/index.d.mts +1 -112
- package/dist/chart/index.mjs +1 -610
- package/dist/chart-Bd9E-YhB.mjs +611 -0
- package/dist/drawingml/index.d.mts +2 -3127
- package/dist/drawingml/index.mjs +1 -3893
- package/dist/drawingml-YMdpQfWs.mjs +4155 -0
- package/dist/{index-mjYQ4KiG.d.mts → index-B1wzvu1m.d.mts} +1 -1
- package/dist/{index-DVqYs1vv.d.mts → index-CZxcE4Q6.d.mts} +2 -2
- package/dist/index-CuRO3Jmz.d.mts +3127 -0
- package/dist/index-DNLRdIqy.d.mts +127 -0
- package/dist/index-DZobntUT.d.mts +113 -0
- package/dist/index.d.mts +128 -12
- package/dist/index.mjs +17 -21
- package/dist/patch/index.d.mts +2 -0
- package/dist/patch/index.mjs +2 -0
- package/dist/patch-BdMU95aX.mjs +337 -0
- package/dist/smartart/index.d.mts +1 -1
- package/dist/smartart/index.mjs +1 -1
- package/dist/{smartart-CwzSHTBd.mjs → smartart-DBQ_rRfK.mjs} +1 -1
- package/dist/values.d.mts +1 -1
- package/package.json +2 -6
- package/dist/archive.d.mts +0 -58
- package/dist/archive.mjs +0 -135
- package/dist/id-generators-CM3u923a.mjs +0 -72
- /package/dist/{values-CIh0bdS1.d.mts → values-QyWq4U4A.d.mts} +0 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { xml2js } from "@office-open/xml";
|
|
2
|
+
//#region src/patch/xml-namespace.ts
|
|
3
|
+
const DOCX_NS = {
|
|
4
|
+
paragraph: "w:p",
|
|
5
|
+
run: "w:r",
|
|
6
|
+
text: "w:t",
|
|
7
|
+
runProperties: "w:rPr"
|
|
8
|
+
};
|
|
9
|
+
const PPTX_NS = {
|
|
10
|
+
paragraph: "a:p",
|
|
11
|
+
run: "a:r",
|
|
12
|
+
text: "a:t",
|
|
13
|
+
runProperties: "a:rPr"
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/patch/xml-patch-utils.ts
|
|
17
|
+
/**
|
|
18
|
+
* XML utility functions for patch operations.
|
|
19
|
+
*/
|
|
20
|
+
const toJson = (xmlData) => {
|
|
21
|
+
return xml2js(xmlData, {
|
|
22
|
+
captureSpacesBetweenElements: true,
|
|
23
|
+
compact: false
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates the inner content of a text element (`w:t` / `a:t`).
|
|
28
|
+
*
|
|
29
|
+
* Returns `[{ type: "text", text }]` for non-empty text, `[]` for empty.
|
|
30
|
+
* The `xml:space` attribute is handled separately by `patchSpaceAttribute`.
|
|
31
|
+
*/
|
|
32
|
+
const createTextElementContents = (text) => text === "" ? [] : [{
|
|
33
|
+
text,
|
|
34
|
+
type: "text"
|
|
35
|
+
}];
|
|
36
|
+
const patchSpaceAttribute = (element) => ({
|
|
37
|
+
...element,
|
|
38
|
+
attributes: { "xml:space": "preserve" }
|
|
39
|
+
});
|
|
40
|
+
const getFirstLevelElements = (relationships, id) => relationships.elements?.filter((e) => e.name === id)[0].elements ?? [];
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/patch/paragraph-split-inject.ts
|
|
43
|
+
var TokenNotFoundError = class extends Error {
|
|
44
|
+
constructor(token) {
|
|
45
|
+
super(`Token ${token} not found`);
|
|
46
|
+
this.name = "TokenNotFoundError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function createSplitInject(ns, createTextElementContents, options) {
|
|
50
|
+
const preserveSpace = options?.preserveSpace ?? true;
|
|
51
|
+
const findRunElementIndexWithToken = (paragraphElement, token) => {
|
|
52
|
+
for (let i = 0; i < (paragraphElement.elements ?? []).length; i++) {
|
|
53
|
+
const element = paragraphElement.elements[i];
|
|
54
|
+
if (element.type === "element" && element.name === ns.run) {
|
|
55
|
+
const textElement = (element.elements ?? []).filter((e) => e.type === "element" && e.name === ns.text);
|
|
56
|
+
for (const text of textElement) {
|
|
57
|
+
if (!text.elements?.[0]) continue;
|
|
58
|
+
if (text.elements[0].text?.includes(token)) return i;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw new TokenNotFoundError(token);
|
|
63
|
+
};
|
|
64
|
+
const splitRunElement = (runElement, token) => {
|
|
65
|
+
let splitIndex = -1;
|
|
66
|
+
const splitElements = runElement.elements?.map((e, i) => {
|
|
67
|
+
if (splitIndex !== -1) return e;
|
|
68
|
+
if (e.type === "element" && e.name === ns.text) {
|
|
69
|
+
const splitText = (e.elements?.[0]?.text ?? "").split(token);
|
|
70
|
+
const newElements = splitText.map((t) => ({
|
|
71
|
+
...e,
|
|
72
|
+
...preserveSpace ? patchSpaceAttribute(e) : {},
|
|
73
|
+
elements: createTextElementContents(t)
|
|
74
|
+
}));
|
|
75
|
+
if (splitText.length > 1) splitIndex = i;
|
|
76
|
+
return newElements;
|
|
77
|
+
} else return e;
|
|
78
|
+
}).flat() ?? [];
|
|
79
|
+
return {
|
|
80
|
+
left: {
|
|
81
|
+
...JSON.parse(JSON.stringify(runElement)),
|
|
82
|
+
elements: splitElements.slice(0, splitIndex + 1)
|
|
83
|
+
},
|
|
84
|
+
right: {
|
|
85
|
+
...JSON.parse(JSON.stringify(runElement)),
|
|
86
|
+
elements: splitElements.slice(splitIndex + 1)
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
findRunElementIndexWithToken,
|
|
92
|
+
splitRunElement
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/patch/paragraph-token-replacer.ts
|
|
97
|
+
const ReplaceMode = {
|
|
98
|
+
START: 0,
|
|
99
|
+
MIDDLE: 1,
|
|
100
|
+
END: 2
|
|
101
|
+
};
|
|
102
|
+
function createTokenReplacer(createTextElementContents, options) {
|
|
103
|
+
const preserveSpace = options?.preserveSpace ?? true;
|
|
104
|
+
const patchTextElement = (element, text) => {
|
|
105
|
+
element.elements = createTextElementContents(text);
|
|
106
|
+
return element;
|
|
107
|
+
};
|
|
108
|
+
return ({ paragraphElement, renderedParagraph, originalText, replacementText }) => {
|
|
109
|
+
const startIndex = renderedParagraph.text.indexOf(originalText);
|
|
110
|
+
const endIndex = startIndex + originalText.length - 1;
|
|
111
|
+
let replaceMode = ReplaceMode.START;
|
|
112
|
+
for (const run of renderedParagraph.runs) for (const { text, index, start, end } of run.parts) switch (replaceMode) {
|
|
113
|
+
case ReplaceMode.START:
|
|
114
|
+
if (startIndex >= start && startIndex <= end) {
|
|
115
|
+
const offsetStartIndex = startIndex - start;
|
|
116
|
+
const offsetEndIndex = Math.min(endIndex, end) - start;
|
|
117
|
+
const partToReplace = text.substring(offsetStartIndex, offsetEndIndex + 1);
|
|
118
|
+
if (partToReplace === "") continue;
|
|
119
|
+
const firstPart = text.replace(partToReplace, replacementText);
|
|
120
|
+
patchTextElement(paragraphElement.elements[run.index].elements[index], firstPart);
|
|
121
|
+
replaceMode = ReplaceMode.MIDDLE;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
case ReplaceMode.MIDDLE:
|
|
126
|
+
if (endIndex <= end) {
|
|
127
|
+
const lastPart = text.substring(endIndex - start + 1);
|
|
128
|
+
patchTextElement(paragraphElement.elements[run.index].elements[index], lastPart);
|
|
129
|
+
const currentElement = paragraphElement.elements[run.index].elements[index];
|
|
130
|
+
paragraphElement.elements[run.index].elements[index] = preserveSpace ? patchSpaceAttribute(currentElement) : currentElement;
|
|
131
|
+
replaceMode = ReplaceMode.END;
|
|
132
|
+
} else patchTextElement(paragraphElement.elements[run.index].elements[index], "");
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
return paragraphElement;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/patch/run-renderer.ts
|
|
140
|
+
function createRunRenderer(ns) {
|
|
141
|
+
const renderParagraphNode = (node) => {
|
|
142
|
+
if (node.element.name !== ns.paragraph) throw new Error(`Invalid node type: ${node.element.name}`);
|
|
143
|
+
if (!node.element.elements) return {
|
|
144
|
+
index: -1,
|
|
145
|
+
pathToParagraph: [],
|
|
146
|
+
runs: [],
|
|
147
|
+
text: ""
|
|
148
|
+
};
|
|
149
|
+
let currentRunStringLength = 0;
|
|
150
|
+
const runs = node.element.elements.map((element, i) => ({
|
|
151
|
+
element,
|
|
152
|
+
i
|
|
153
|
+
})).filter(({ element }) => element.name === ns.run).map(({ element, i }) => {
|
|
154
|
+
const renderedRunNode = renderRunNode(element, i, currentRunStringLength);
|
|
155
|
+
currentRunStringLength += renderedRunNode.text.length;
|
|
156
|
+
return renderedRunNode;
|
|
157
|
+
}).filter((e) => Boolean(e));
|
|
158
|
+
const text = runs.reduce((acc, curr) => acc + curr.text, "");
|
|
159
|
+
return {
|
|
160
|
+
index: node.index,
|
|
161
|
+
pathToParagraph: buildNodePath(node),
|
|
162
|
+
runs,
|
|
163
|
+
text
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
const renderRunNode = (node, index, currentRunStringIndex) => {
|
|
167
|
+
if (!node.elements) return {
|
|
168
|
+
end: currentRunStringIndex,
|
|
169
|
+
index: -1,
|
|
170
|
+
parts: [],
|
|
171
|
+
start: currentRunStringIndex,
|
|
172
|
+
text: ""
|
|
173
|
+
};
|
|
174
|
+
let currentTextStringIndex = currentRunStringIndex;
|
|
175
|
+
const parts = node.elements.map((element, i) => element.name === ns.text && element.elements && element.elements.length > 0 ? (() => {
|
|
176
|
+
const partStart = currentTextStringIndex;
|
|
177
|
+
currentTextStringIndex += (element.elements[0].text?.toString() ?? "").length;
|
|
178
|
+
return {
|
|
179
|
+
end: currentTextStringIndex - 1,
|
|
180
|
+
index: i,
|
|
181
|
+
start: partStart,
|
|
182
|
+
text: element.elements[0].text?.toString() ?? ""
|
|
183
|
+
};
|
|
184
|
+
})() : void 0).filter((e) => Boolean(e)).map((e) => e);
|
|
185
|
+
const text = parts.reduce((acc, curr) => acc + curr.text, "");
|
|
186
|
+
return {
|
|
187
|
+
end: currentTextStringIndex - 1,
|
|
188
|
+
index,
|
|
189
|
+
parts,
|
|
190
|
+
start: currentRunStringIndex,
|
|
191
|
+
text
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
return renderParagraphNode;
|
|
195
|
+
}
|
|
196
|
+
const buildNodePath = (node) => node.parent ? [...buildNodePath(node.parent), node.index] : [node.index];
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/patch/xml-traverser.ts
|
|
199
|
+
const elementsToWrapper = (wrapper) => wrapper.element.elements?.map((e, i) => ({
|
|
200
|
+
element: e,
|
|
201
|
+
index: i,
|
|
202
|
+
parent: wrapper
|
|
203
|
+
})) ?? [];
|
|
204
|
+
function createTraverser(ns) {
|
|
205
|
+
const renderParagraphNode = createRunRenderer(ns);
|
|
206
|
+
const traverse = (node) => {
|
|
207
|
+
let renderedParagraphs = [];
|
|
208
|
+
const queue = [...elementsToWrapper({
|
|
209
|
+
element: node,
|
|
210
|
+
index: 0,
|
|
211
|
+
parent: void 0
|
|
212
|
+
})];
|
|
213
|
+
let currentNode;
|
|
214
|
+
while (queue.length > 0) {
|
|
215
|
+
currentNode = queue.shift();
|
|
216
|
+
if (currentNode.element.name === ns.paragraph) renderedParagraphs = [...renderedParagraphs, renderParagraphNode(currentNode)];
|
|
217
|
+
queue.push(...elementsToWrapper(currentNode));
|
|
218
|
+
}
|
|
219
|
+
return renderedParagraphs;
|
|
220
|
+
};
|
|
221
|
+
const findLocationOfText = (node, text) => traverse(node).filter((p) => p.text.includes(text));
|
|
222
|
+
return {
|
|
223
|
+
traverse,
|
|
224
|
+
findLocationOfText
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/patch/xml-replacer.ts
|
|
229
|
+
const SPLIT_TOKEN = "ɵ";
|
|
230
|
+
function createReplacer(config) {
|
|
231
|
+
const { ns, formatChild } = config;
|
|
232
|
+
const { findLocationOfText } = createTraverser(ns);
|
|
233
|
+
const replaceTokenInParagraphElement = createTokenReplacer(createTextElementContents, { preserveSpace: config.preserveSpace });
|
|
234
|
+
const { findRunElementIndexWithToken, splitRunElement } = createSplitInject(ns, createTextElementContents, { preserveSpace: config.preserveSpace });
|
|
235
|
+
const replacer = ({ json, patch, patchText, context, keepOriginalStyles = true }) => {
|
|
236
|
+
const renderedParagraphs = findLocationOfText(json, patchText);
|
|
237
|
+
if (renderedParagraphs.length === 0) return {
|
|
238
|
+
didFindOccurrence: false,
|
|
239
|
+
element: json
|
|
240
|
+
};
|
|
241
|
+
for (const renderedParagraph of renderedParagraphs) {
|
|
242
|
+
const textJson = patch.children.flatMap((c) => formatChild(c, context));
|
|
243
|
+
switch (patch.type) {
|
|
244
|
+
case "file": {
|
|
245
|
+
const parentElement = goToParentElementFromPath(json, renderedParagraph.pathToParagraph);
|
|
246
|
+
const elementIndex = getLastElementIndexFromPath(renderedParagraph.pathToParagraph);
|
|
247
|
+
parentElement.elements.splice(elementIndex, 1, ...textJson);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
default: {
|
|
251
|
+
const paragraphElement = goToElementFromPath(json, renderedParagraph.pathToParagraph);
|
|
252
|
+
replaceTokenInParagraphElement({
|
|
253
|
+
originalText: patchText,
|
|
254
|
+
paragraphElement,
|
|
255
|
+
renderedParagraph,
|
|
256
|
+
replacementText: SPLIT_TOKEN
|
|
257
|
+
});
|
|
258
|
+
const index = findRunElementIndexWithToken(paragraphElement, SPLIT_TOKEN);
|
|
259
|
+
const runElementToBeReplaced = paragraphElement.elements[index];
|
|
260
|
+
const { left, right } = splitRunElement(runElementToBeReplaced, SPLIT_TOKEN);
|
|
261
|
+
let newRunElements = textJson;
|
|
262
|
+
let patchedRightElement = right;
|
|
263
|
+
if (keepOriginalStyles) {
|
|
264
|
+
const runElementNonTextualElements = runElementToBeReplaced.elements.filter((e) => e.type === "element" && e.name === ns.runProperties);
|
|
265
|
+
newRunElements = textJson.map((e) => {
|
|
266
|
+
if (e.type !== "element" || e.name !== ns.run || e.elements?.some((c) => c.type === "element" && c.name === ns.runProperties)) return e;
|
|
267
|
+
return {
|
|
268
|
+
...e,
|
|
269
|
+
elements: [...runElementNonTextualElements, ...e.elements ?? []]
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
patchedRightElement = {
|
|
273
|
+
...right,
|
|
274
|
+
elements: [...runElementNonTextualElements, ...right.elements]
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
paragraphElement.elements.splice(index, 1, left, ...newRunElements, patchedRightElement);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
didFindOccurrence: true,
|
|
284
|
+
element: json
|
|
285
|
+
};
|
|
286
|
+
};
|
|
287
|
+
return replacer;
|
|
288
|
+
}
|
|
289
|
+
const goToElementFromPath = (json, path) => {
|
|
290
|
+
let element = json;
|
|
291
|
+
for (let i = 1; i < path.length; i++) {
|
|
292
|
+
const index = path[i];
|
|
293
|
+
element = element.elements[index];
|
|
294
|
+
}
|
|
295
|
+
return element;
|
|
296
|
+
};
|
|
297
|
+
const goToParentElementFromPath = (json, path) => goToElementFromPath(json, path.slice(0, -1));
|
|
298
|
+
const getLastElementIndexFromPath = (path) => path[path.length - 1];
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region src/patch/content-types-manager.ts
|
|
301
|
+
const appendContentType = (element, contentType, extension) => {
|
|
302
|
+
const relationshipElements = getFirstLevelElements(element, "Types");
|
|
303
|
+
if (relationshipElements.some((el) => el.type === "element" && el.name === "Default" && el?.attributes?.ContentType === contentType && el?.attributes?.Extension === extension)) return;
|
|
304
|
+
relationshipElements.push({
|
|
305
|
+
attributes: {
|
|
306
|
+
ContentType: contentType,
|
|
307
|
+
Extension: extension
|
|
308
|
+
},
|
|
309
|
+
name: "Default",
|
|
310
|
+
type: "element"
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region src/patch/relationship-manager.ts
|
|
315
|
+
const getIdFromRelationshipId = (relationshipId) => {
|
|
316
|
+
const output = parseInt(relationshipId.substring(3), 10);
|
|
317
|
+
return isNaN(output) ? 0 : output;
|
|
318
|
+
};
|
|
319
|
+
const getNextRelationshipIndex = (relationships) => {
|
|
320
|
+
return getFirstLevelElements(relationships, "Relationships").map((e) => getIdFromRelationshipId(e.attributes?.Id?.toString() ?? "")).reduce((acc, curr) => Math.max(acc, curr), 0) + 1;
|
|
321
|
+
};
|
|
322
|
+
const appendRelationship = (relationships, id, type, target, targetMode) => {
|
|
323
|
+
const relationshipElements = getFirstLevelElements(relationships, "Relationships");
|
|
324
|
+
relationshipElements.push({
|
|
325
|
+
attributes: {
|
|
326
|
+
Id: `rId${id}`,
|
|
327
|
+
Target: target,
|
|
328
|
+
TargetMode: targetMode,
|
|
329
|
+
Type: type
|
|
330
|
+
},
|
|
331
|
+
name: "Relationship",
|
|
332
|
+
type: "element"
|
|
333
|
+
});
|
|
334
|
+
return relationshipElements;
|
|
335
|
+
};
|
|
336
|
+
//#endregion
|
|
337
|
+
export { createTraverser as a, TokenNotFoundError as c, getFirstLevelElements as d, patchSpaceAttribute as f, PPTX_NS as h, createReplacer as i, createSplitInject as l, DOCX_NS as m, getNextRelationshipIndex as n, createRunRenderer as o, toJson as p, appendContentType as r, createTokenReplacer as s, appendRelationship as t, createTextElementContents as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Point, c as Connection, d as getLayoutXml, f as getStyleXml, h as STYLE_CATEGORIES, i as SmartArtData, l as DEFAULT_DRAWING_XML, m as LAYOUT_CATEGORIES, n as createDataModel, o as TransPoint, p as COLOR_CATEGORIES, r as SmartArtCollection, s as DataModel, t as TreeNode, u as getColorXml } from "../index-
|
|
1
|
+
import { a as Point, c as Connection, d as getLayoutXml, f as getStyleXml, h as STYLE_CATEGORIES, i as SmartArtData, l as DEFAULT_DRAWING_XML, m as LAYOUT_CATEGORIES, n as createDataModel, o as TransPoint, p as COLOR_CATEGORIES, r as SmartArtCollection, s as DataModel, t as TreeNode, u as getColorXml } from "../index-CZxcE4Q6.mjs";
|
|
2
2
|
export { COLOR_CATEGORIES, Connection, DEFAULT_DRAWING_XML, DataModel, LAYOUT_CATEGORIES, Point, STYLE_CATEGORIES, SmartArtCollection, SmartArtData, TransPoint, TreeNode, createDataModel, getColorXml, getLayoutXml, getStyleXml };
|
package/dist/smartart/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as DataModel, c as getColorXml, d as COLOR_CATEGORIES, f as LAYOUT_CATEGORIES, i as TransPoint, l as getLayoutXml, n as SmartArtCollection, o as Connection, p as STYLE_CATEGORIES, r as Point, s as DEFAULT_DRAWING_XML, t as createDataModel, u as getStyleXml } from "../smartart-
|
|
1
|
+
import { a as DataModel, c as getColorXml, d as COLOR_CATEGORIES, f as LAYOUT_CATEGORIES, i as TransPoint, l as getLayoutXml, n as SmartArtCollection, o as Connection, p as STYLE_CATEGORIES, r as Point, s as DEFAULT_DRAWING_XML, t as createDataModel, u as getStyleXml } from "../smartart-DBQ_rRfK.mjs";
|
|
2
2
|
export { COLOR_CATEGORIES, Connection, DEFAULT_DRAWING_XML, DataModel, LAYOUT_CATEGORIES, Point, STYLE_CATEGORIES, SmartArtCollection, TransPoint, createDataModel, getColorXml, getLayoutXml, getStyleXml };
|
package/dist/values.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as uCharHexNumber, S as twipsMeasureValue, T as unsignedDecimalNumber, _ as pointMeasureValue, a as ThemeColor, b as signedHpsMeasureValue, c as dateTimeValue, d as hexBinary, f as hexColorValue, g as percentageValue, h as measurementOrPercentValue, i as RelativeMeasure, l as decimalNumber, m as longHexNumber, n as PositivePercentage, o as ThemeFont, p as hpsMeasureValue, r as PositiveUniversalMeasure, s as UniversalMeasure, t as Percentage, u as eighthPointMeasureValue, v as positiveUniversalMeasureValue, w as universalMeasureValue, x as signedTwipsMeasureValue, y as shortHexNumber } from "./values-
|
|
1
|
+
import { C as uCharHexNumber, S as twipsMeasureValue, T as unsignedDecimalNumber, _ as pointMeasureValue, a as ThemeColor, b as signedHpsMeasureValue, c as dateTimeValue, d as hexBinary, f as hexColorValue, g as percentageValue, h as measurementOrPercentValue, i as RelativeMeasure, l as decimalNumber, m as longHexNumber, n as PositivePercentage, o as ThemeFont, p as hpsMeasureValue, r as PositiveUniversalMeasure, s as UniversalMeasure, t as Percentage, u as eighthPointMeasureValue, v as positiveUniversalMeasureValue, w as universalMeasureValue, x as signedTwipsMeasureValue, y as shortHexNumber } from "./values-QyWq4U4A.mjs";
|
|
2
2
|
export { Percentage, PositivePercentage, PositiveUniversalMeasure, RelativeMeasure, ThemeColor, ThemeFont, UniversalMeasure, dateTimeValue, decimalNumber, eighthPointMeasureValue, hexBinary, hexColorValue, hpsMeasureValue, longHexNumber, measurementOrPercentValue, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, twipsMeasureValue, uCharHexNumber, universalMeasureValue, unsignedDecimalNumber };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@office-open/core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Shared OOXML infrastructure: XmlComponent, value validators, unit converters",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"core",
|
|
@@ -49,17 +49,13 @@
|
|
|
49
49
|
"./drawingml": {
|
|
50
50
|
"types": "./dist/drawingml/index.d.mts",
|
|
51
51
|
"import": "./dist/drawingml/index.mjs"
|
|
52
|
-
},
|
|
53
|
-
"./archive": {
|
|
54
|
-
"types": "./dist/archive.d.mts",
|
|
55
|
-
"import": "./dist/archive.mjs"
|
|
56
52
|
}
|
|
57
53
|
},
|
|
58
54
|
"dependencies": {
|
|
59
55
|
"fflate": "0.8.3",
|
|
60
56
|
"hash.js": "1.1.7",
|
|
61
57
|
"nanoid": "5.1.11",
|
|
62
|
-
"@office-open/xml": "0.6.
|
|
58
|
+
"@office-open/xml": "0.6.5"
|
|
63
59
|
},
|
|
64
60
|
"scripts": {
|
|
65
61
|
"dev": "basis build --stub",
|
package/dist/archive.d.mts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Element } from "@office-open/xml";
|
|
2
|
-
|
|
3
|
-
//#region src/archive.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Unzip an OOXML file (.docx, .pptx) into a Map of path → Uint8Array.
|
|
6
|
-
*/
|
|
7
|
-
declare function unzipToMap(data: Uint8Array): Map<string, Uint8Array>;
|
|
8
|
-
/**
|
|
9
|
-
* Read a file from the zip as a UTF-8 string.
|
|
10
|
-
*/
|
|
11
|
-
declare function readTextFromZip(zip: Map<string, Uint8Array>, path: string): string | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* Parse an XML file from the zip into an Element tree.
|
|
14
|
-
*/
|
|
15
|
-
declare function readXmlFromZip(zip: Map<string, Uint8Array>, path: string): Element | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* Read a binary file from the zip.
|
|
18
|
-
*/
|
|
19
|
-
declare function readBinaryFromZip(zip: Map<string, Uint8Array>, path: string): Uint8Array | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* Parse all XML files in the zip into Element trees.
|
|
22
|
-
* Skips media files, binary files, and the main document/presentation file.
|
|
23
|
-
*/
|
|
24
|
-
declare function readAllXmlParts(zip: Map<string, Uint8Array>, options?: {
|
|
25
|
-
skipPaths?: string[];
|
|
26
|
-
}): Record<string, Element>;
|
|
27
|
-
/**
|
|
28
|
-
* List all files in the zip matching a prefix.
|
|
29
|
-
*/
|
|
30
|
-
declare function listFiles(zip: Map<string, Uint8Array>, prefix: string): string[];
|
|
31
|
-
/**
|
|
32
|
-
* Convert Uint8Array to base64 string.
|
|
33
|
-
*/
|
|
34
|
-
declare function uint8ToBase64(data: Uint8Array): string;
|
|
35
|
-
/**
|
|
36
|
-
* Determine image type from file extension.
|
|
37
|
-
*/
|
|
38
|
-
declare function getImageType(fileName: string): string;
|
|
39
|
-
interface Relationship {
|
|
40
|
-
id: string;
|
|
41
|
-
target: string;
|
|
42
|
-
type: string;
|
|
43
|
-
targetMode?: string;
|
|
44
|
-
}
|
|
45
|
-
declare function parseRels(zip: Map<string, Uint8Array>, path: string): Relationship[];
|
|
46
|
-
declare function findRel(rels: Relationship[], id: string): Relationship | undefined;
|
|
47
|
-
declare function findRelsByType(rels: Relationship[], typeSubstring: string): Relationship[];
|
|
48
|
-
/**
|
|
49
|
-
* Zip a map of path → Uint8Array/string into a ZIP buffer.
|
|
50
|
-
* XML strings are auto-encoded to UTF-8 bytes.
|
|
51
|
-
*/
|
|
52
|
-
declare function zipToBuffer(files: Map<string, Uint8Array | string>): Uint8Array;
|
|
53
|
-
/**
|
|
54
|
-
* Serialize an Element tree to an XML string.
|
|
55
|
-
*/
|
|
56
|
-
declare function elementToXml(el: Element): string;
|
|
57
|
-
//#endregion
|
|
58
|
-
export { Relationship, elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer };
|
package/dist/archive.mjs
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { attr, js2xml, xml2js } from "@office-open/xml";
|
|
2
|
-
import { strFromU8, strToU8, unzipSync, zipSync } from "fflate";
|
|
3
|
-
//#region src/archive.ts
|
|
4
|
-
const XML_PARSE_OPTIONS = {
|
|
5
|
-
nativeTypeAttributes: true,
|
|
6
|
-
captureSpacesBetweenElements: true
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Unzip an OOXML file (.docx, .pptx) into a Map of path → Uint8Array.
|
|
10
|
-
*/
|
|
11
|
-
function unzipToMap(data) {
|
|
12
|
-
const entries = unzipSync(data);
|
|
13
|
-
const map = /* @__PURE__ */ new Map();
|
|
14
|
-
for (const [path, bytes] of Object.entries(entries)) map.set(path, bytes);
|
|
15
|
-
return map;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Read a file from the zip as a UTF-8 string.
|
|
19
|
-
*/
|
|
20
|
-
function readTextFromZip(zip, path) {
|
|
21
|
-
const data = zip.get(path);
|
|
22
|
-
if (data === void 0) return void 0;
|
|
23
|
-
return strFromU8(data);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Parse an XML file from the zip into an Element tree.
|
|
27
|
-
*/
|
|
28
|
-
function readXmlFromZip(zip, path) {
|
|
29
|
-
const text = readTextFromZip(zip, path);
|
|
30
|
-
if (text === void 0) return void 0;
|
|
31
|
-
return xml2js(text, XML_PARSE_OPTIONS).elements?.find((e) => e.type === "element");
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Read a binary file from the zip.
|
|
35
|
-
*/
|
|
36
|
-
function readBinaryFromZip(zip, path) {
|
|
37
|
-
return zip.get(path);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Parse all XML files in the zip into Element trees.
|
|
41
|
-
* Skips media files, binary files, and the main document/presentation file.
|
|
42
|
-
*/
|
|
43
|
-
function readAllXmlParts(zip, options) {
|
|
44
|
-
const parts = {};
|
|
45
|
-
const skip = new Set(options?.skipPaths ?? []);
|
|
46
|
-
for (const path of zip.keys()) {
|
|
47
|
-
if (skip.has(path)) continue;
|
|
48
|
-
if (path.startsWith("word/media/") || path.startsWith("ppt/media/") || path.startsWith("xl/media/") || path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".gif") || path.endsWith(".bmp") || path.endsWith(".tif") || path.endsWith(".tiff") || path.endsWith(".emf") || path.endsWith(".wmf") || path.endsWith(".svg") || path.endsWith(".wav") || path.endsWith(".mp3") || path.endsWith(".mp4") || path.endsWith(".avi") || path.endsWith(".wmv") || path.endsWith(".thmx") || path.endsWith(".bin")) continue;
|
|
49
|
-
const el = readXmlFromZip(zip, path);
|
|
50
|
-
if (el) parts[path] = el;
|
|
51
|
-
}
|
|
52
|
-
return parts;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* List all files in the zip matching a prefix.
|
|
56
|
-
*/
|
|
57
|
-
function listFiles(zip, prefix) {
|
|
58
|
-
const result = [];
|
|
59
|
-
for (const path of zip.keys()) if (path.startsWith(prefix)) result.push(path);
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Convert Uint8Array to base64 string.
|
|
64
|
-
*/
|
|
65
|
-
function uint8ToBase64(data) {
|
|
66
|
-
const chunkSize = 8192;
|
|
67
|
-
let binary = "";
|
|
68
|
-
for (let i = 0; i < data.length; i += chunkSize) {
|
|
69
|
-
const chunk = data.subarray(i, Math.min(i + chunkSize, data.length));
|
|
70
|
-
binary += String.fromCharCode(...chunk);
|
|
71
|
-
}
|
|
72
|
-
return btoa(binary);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Determine image type from file extension.
|
|
76
|
-
*/
|
|
77
|
-
function getImageType(fileName) {
|
|
78
|
-
const ext = fileName.split(".").pop()?.toLowerCase() ?? "";
|
|
79
|
-
if ([
|
|
80
|
-
"png",
|
|
81
|
-
"jpg",
|
|
82
|
-
"jpeg",
|
|
83
|
-
"gif",
|
|
84
|
-
"bmp",
|
|
85
|
-
"tif",
|
|
86
|
-
"tiff",
|
|
87
|
-
"ico",
|
|
88
|
-
"emf",
|
|
89
|
-
"wmf",
|
|
90
|
-
"svg"
|
|
91
|
-
].includes(ext)) return ext === "jpeg" ? "jpg" : ext;
|
|
92
|
-
return "png";
|
|
93
|
-
}
|
|
94
|
-
function parseRels(zip, path) {
|
|
95
|
-
const xml = readXmlFromZip(zip, path);
|
|
96
|
-
if (!xml) return [];
|
|
97
|
-
const result = [];
|
|
98
|
-
for (const rel of xml.elements ?? []) {
|
|
99
|
-
if (rel.name !== "Relationship") continue;
|
|
100
|
-
const id = attr(rel, "Id");
|
|
101
|
-
const target = attr(rel, "Target");
|
|
102
|
-
const type = attr(rel, "Type");
|
|
103
|
-
const targetMode = attr(rel, "TargetMode");
|
|
104
|
-
if (id && target) result.push({
|
|
105
|
-
id,
|
|
106
|
-
target,
|
|
107
|
-
type: type ?? "",
|
|
108
|
-
...targetMode ? { targetMode } : {}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
return result;
|
|
112
|
-
}
|
|
113
|
-
function findRel(rels, id) {
|
|
114
|
-
return rels.find((r) => r.id === id);
|
|
115
|
-
}
|
|
116
|
-
function findRelsByType(rels, typeSubstring) {
|
|
117
|
-
return rels.filter((r) => r.type.includes(typeSubstring));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Zip a map of path → Uint8Array/string into a ZIP buffer.
|
|
121
|
-
* XML strings are auto-encoded to UTF-8 bytes.
|
|
122
|
-
*/
|
|
123
|
-
function zipToBuffer(files) {
|
|
124
|
-
const entries = {};
|
|
125
|
-
for (const [path, data] of files) entries[path] = typeof data === "string" ? strToU8(data) : data;
|
|
126
|
-
return zipSync(entries);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Serialize an Element tree to an XML string.
|
|
130
|
-
*/
|
|
131
|
-
function elementToXml(el) {
|
|
132
|
-
return js2xml(el);
|
|
133
|
-
}
|
|
134
|
-
//#endregion
|
|
135
|
-
export { elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer };
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import hash from "hash.js";
|
|
2
|
-
import { customAlphabet, nanoid } from "nanoid/non-secure";
|
|
3
|
-
//#region src/converters.ts
|
|
4
|
-
/**
|
|
5
|
-
* OOXML unit conversion utilities.
|
|
6
|
-
*
|
|
7
|
-
* @module
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Converts millimeters to TWIP (twentieths of a point).
|
|
11
|
-
*/
|
|
12
|
-
const convertMillimetersToTwip = (millimeters) => Math.floor(millimeters / 25.4 * 72 * 20);
|
|
13
|
-
/**
|
|
14
|
-
* Converts inches to TWIP (twentieths of a point).
|
|
15
|
-
*/
|
|
16
|
-
const convertInchesToTwip = (inches) => Math.floor(inches * 72 * 20);
|
|
17
|
-
/**
|
|
18
|
-
* Converts pixels to EMU (96 DPI).
|
|
19
|
-
*/
|
|
20
|
-
const convertPixelsToEmu = (pixels) => Math.round(pixels * 9525);
|
|
21
|
-
/**
|
|
22
|
-
* Converts EMU to pixels (96 DPI).
|
|
23
|
-
*/
|
|
24
|
-
const convertEmuToPixels = (emus) => Math.round(emus / 9525);
|
|
25
|
-
/**
|
|
26
|
-
* Converts inches to EMU.
|
|
27
|
-
*/
|
|
28
|
-
const convertInchesToEmu = (inches) => Math.round(inches * 914400);
|
|
29
|
-
/**
|
|
30
|
-
* Converts EMU to inches.
|
|
31
|
-
*/
|
|
32
|
-
const convertEmuToInches = (emus) => emus / 914400;
|
|
33
|
-
/**
|
|
34
|
-
* Converts points to EMU.
|
|
35
|
-
*/
|
|
36
|
-
const convertPointsToEmu = (points) => Math.round(points * 12700);
|
|
37
|
-
/**
|
|
38
|
-
* Converts EMU to points.
|
|
39
|
-
*/
|
|
40
|
-
const convertEmuToPoints = (emus) => emus / 12700;
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region src/id-generators.ts
|
|
43
|
-
/**
|
|
44
|
-
* Unique ID generation utilities.
|
|
45
|
-
*
|
|
46
|
-
* @module
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* Creates a unique numeric ID generator with sequential numbering.
|
|
50
|
-
*/
|
|
51
|
-
const uniqueNumericIdCreator = (initial = 0) => {
|
|
52
|
-
let currentCount = initial;
|
|
53
|
-
return () => ++currentCount;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Generates a unique lowercase alphanumeric ID using nanoid.
|
|
57
|
-
*/
|
|
58
|
-
const uniqueId = () => nanoid().toLowerCase();
|
|
59
|
-
/**
|
|
60
|
-
* Generates a SHA-1 hash of the provided data.
|
|
61
|
-
*/
|
|
62
|
-
const hashedId = (data) => hash.sha1().update(data instanceof ArrayBuffer ? new Uint8Array(data) : data).digest("hex");
|
|
63
|
-
/**
|
|
64
|
-
* Generates a random hexadecimal string of specified length.
|
|
65
|
-
*/
|
|
66
|
-
const generateUuidPart = (count) => customAlphabet("1234567890abcdef", count)();
|
|
67
|
-
/**
|
|
68
|
-
* Generates a UUID v4-style unique identifier.
|
|
69
|
-
*/
|
|
70
|
-
const uniqueUuid = () => `${generateUuidPart(8)}-${generateUuidPart(4)}-${generateUuidPart(4)}-${generateUuidPart(4)}-${generateUuidPart(12)}`;
|
|
71
|
-
//#endregion
|
|
72
|
-
export { convertEmuToInches as a, convertInchesToEmu as c, convertPixelsToEmu as d, convertPointsToEmu as f, uniqueUuid as i, convertInchesToTwip as l, uniqueId as n, convertEmuToPixels as o, uniqueNumericIdCreator as r, convertEmuToPoints as s, hashedId as t, convertMillimetersToTwip as u };
|
|
File without changes
|