@office-open/core 0.10.15 → 0.12.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/README.md +2 -1
- package/dist/chart/index.d.mts +2 -2
- package/dist/chart/index.mjs +2 -2
- package/dist/chart-DED4tXC9.mjs +2325 -0
- package/dist/chart-DED4tXC9.mjs.map +1 -0
- package/dist/color-mapping-CFF0vRSe.mjs +117 -0
- package/dist/color-mapping-CFF0vRSe.mjs.map +1 -0
- package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
- package/dist/descriptor/index.d.mts +2 -2
- package/dist/descriptor/index.mjs +1 -1
- package/dist/{descriptor-BjNkn5jo.mjs → descriptor-BqaNZrrZ.mjs} +43 -11
- package/dist/{descriptor-BjNkn5jo.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
- package/dist/drawing/index.d.mts +2 -0
- package/dist/drawing/index.mjs +2 -0
- package/dist/{drawingml-sj1J3lb0.mjs → drawing-BCAyrCCw.mjs} +4456 -3452
- package/dist/drawing-BCAyrCCw.mjs.map +1 -0
- package/dist/{converters-C_Y2QX1w.mjs → ext-uri-BHBcIrW7.mjs} +742 -45
- package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
- package/dist/index-BAxlDUQ1.d.mts +590 -0
- package/dist/index-BAxlDUQ1.d.mts.map +1 -0
- package/dist/index-BP541uS-.d.mts +489 -0
- package/dist/index-BP541uS-.d.mts.map +1 -0
- package/dist/{index-BVK2dv6C.d.mts → index-BQLIofaF.d.mts} +10 -4
- package/dist/index-BQLIofaF.d.mts.map +1 -0
- package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
- package/dist/index-CaNwM5_e.d.mts.map +1 -0
- package/dist/index-DPkf_CtG.d.mts +1578 -0
- package/dist/index-DPkf_CtG.d.mts.map +1 -0
- package/dist/index-DcukVskh.d.mts +31 -0
- package/dist/index-DcukVskh.d.mts.map +1 -0
- package/dist/index-Di6XPdGl.d.mts +322 -0
- package/dist/index-Di6XPdGl.d.mts.map +1 -0
- package/dist/index-L6AXewfV.d.mts +872 -0
- package/dist/index-L6AXewfV.d.mts.map +1 -0
- package/dist/index.d.mts +294 -30
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1327 -112
- package/dist/index.mjs.map +1 -1
- package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
- package/dist/output-yyxdkG0C.d.mts.map +1 -0
- package/dist/patch/index.d.mts +2 -2
- package/dist/patch/index.mjs +2 -2
- package/dist/{patch-BmRfghOo.mjs → patch-AkQY17CD.mjs} +73 -28
- package/dist/patch-AkQY17CD.mjs.map +1 -0
- package/dist/smartart/index.d.mts +2 -2
- package/dist/smartart/index.mjs +2 -2
- package/dist/smartart-n1kYJ6Jg.mjs +1650 -0
- package/dist/smartart-n1kYJ6Jg.mjs.map +1 -0
- package/dist/style-matrix-B6jhPAT3.mjs +123 -0
- package/dist/style-matrix-B6jhPAT3.mjs.map +1 -0
- package/dist/theme/index.d.mts +4 -2
- package/dist/theme/index.mjs +4 -2
- package/dist/theme-BKnXRmvn.mjs +426 -0
- package/dist/theme-BKnXRmvn.mjs.map +1 -0
- package/dist/theme-options-kO89NUEX.d.mts +109 -0
- package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
- package/dist/util/index.d.mts +3 -3
- package/dist/util/index.mjs +3 -3
- package/dist/{util-Tq9PSjK0.mjs → util-ptE16MEk.mjs} +237 -459
- package/dist/util-ptE16MEk.mjs.map +1 -0
- package/dist/{values-8di32lIe.d.mts → values-BECDm4zr.d.mts} +17 -31
- package/dist/values-BECDm4zr.d.mts.map +1 -0
- package/dist/vector/index.d.mts +2 -0
- package/dist/vector/index.mjs +2 -0
- package/dist/vector-DhLGZjP5.mjs +3049 -0
- package/dist/vector-DhLGZjP5.mjs.map +1 -0
- package/package.json +16 -8
- package/dist/chart-DIGJna_6.mjs +0 -582
- package/dist/chart-DIGJna_6.mjs.map +0 -1
- package/dist/converters-C_Y2QX1w.mjs.map +0 -1
- package/dist/drawingml/index.d.mts +0 -2
- package/dist/drawingml/index.mjs +0 -2
- package/dist/drawingml-sj1J3lb0.mjs.map +0 -1
- package/dist/index-BVK2dv6C.d.mts.map +0 -1
- package/dist/index-BfHfKuKy.d.mts +0 -275
- package/dist/index-BfHfKuKy.d.mts.map +0 -1
- package/dist/index-CE53SwpZ.d.mts +0 -1463
- package/dist/index-CE53SwpZ.d.mts.map +0 -1
- package/dist/index-D6VE-MnJ.d.mts +0 -43
- package/dist/index-D6VE-MnJ.d.mts.map +0 -1
- package/dist/index-DE4CLElr.d.mts +0 -145
- package/dist/index-DE4CLElr.d.mts.map +0 -1
- package/dist/index-DlPA26cw.d.mts +0 -91
- package/dist/index-DlPA26cw.d.mts.map +0 -1
- package/dist/index-k8WKLXnA.d.mts.map +0 -1
- package/dist/output-D_G_JR_8.d.mts.map +0 -1
- package/dist/patch-BmRfghOo.mjs.map +0 -1
- package/dist/smartart-B7ukZ-Tw.mjs +0 -305
- package/dist/smartart-B7ukZ-Tw.mjs.map +0 -1
- package/dist/theme-CiNzdl-9.mjs +0 -177
- package/dist/theme-CiNzdl-9.mjs.map +0 -1
- package/dist/util-Tq9PSjK0.mjs.map +0 -1
- package/dist/values-8di32lIe.d.mts.map +0 -1
|
@@ -1,34 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AsyncZipDeflate, Zip, ZipPassThrough, strFromU8, strFromU8 as strFromU8$1, unzipSync as unzipSync$1, zip, zipSync } from "fflate";
|
|
1
|
+
import { Ht as Buffer, Vt as encodeBase64 } from "./ext-uri-BHBcIrW7.mjs";
|
|
2
|
+
import { AsyncZipDeflate, Zip, ZipDeflate, ZipPassThrough, strFromU8, strFromU8 as strFromU8$1, unzipSync as unzipSync$1, zip, zipSync, zipSync as zipSync$1 } from "fflate";
|
|
3
3
|
import { sha512 } from "@noble/hashes/sha2.js";
|
|
4
|
-
//#region src/opc/output.ts
|
|
5
|
-
/**
|
|
6
|
-
* Output type definitions for OOXML document export.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
|
-
const OoxmlMimeType = {
|
|
11
|
-
DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
12
|
-
PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
13
|
-
XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
14
|
-
};
|
|
15
|
-
const convertOutput = (data, type, mimeType = OoxmlMimeType.DOCX) => {
|
|
16
|
-
switch (type) {
|
|
17
|
-
case "nodebuffer": return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
18
|
-
case "blob": return new Blob([data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)], { type: mimeType });
|
|
19
|
-
case "arraybuffer": return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
20
|
-
case "uint8array": return data;
|
|
21
|
-
case "base64": return encodeBase64(data);
|
|
22
|
-
case "string":
|
|
23
|
-
case "text":
|
|
24
|
-
case "binarystring": return strFromU8(data, true);
|
|
25
|
-
case "array": return [...data];
|
|
26
|
-
default: return data;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
//#endregion
|
|
30
4
|
//#region src/opc/zip-native.ts
|
|
31
|
-
const CRC_TABLE = new Int32Array(256);
|
|
5
|
+
const CRC_TABLE = /* @__PURE__ */ new Int32Array(256);
|
|
32
6
|
for (let i = 0; i < 256; i++) {
|
|
33
7
|
let c = i;
|
|
34
8
|
for (let k = 0; k < 8; k++) c = c & 1 ? c >>> 1 ^ -306674912 : c >>> 1;
|
|
@@ -43,19 +17,39 @@ let _nativeDeflate;
|
|
|
43
17
|
let _nativeDeflateAsync;
|
|
44
18
|
let _nativeInflate;
|
|
45
19
|
let _nativeCrc32;
|
|
20
|
+
const bunApi = globalThis.Bun;
|
|
21
|
+
if (typeof bunApi?.deflateSync === "function") {
|
|
22
|
+
_nativeDeflate = (data, level) => bunApi.deflateSync(data, { level });
|
|
23
|
+
if (typeof bunApi.inflateSync === "function") _nativeInflate = (data) => bunApi.inflateSync(data);
|
|
24
|
+
}
|
|
46
25
|
try {
|
|
47
26
|
const zlib = await import("node:zlib");
|
|
48
27
|
if (typeof zlib.deflateRawSync !== "function") throw new Error("no native deflate");
|
|
49
|
-
_nativeDeflate = (data, level) => zlib.deflateRawSync(data, { level });
|
|
28
|
+
if (_nativeDeflate === void 0) _nativeDeflate = (data, level) => zlib.deflateRawSync(data, { level });
|
|
50
29
|
_nativeDeflateAsync = (data, level) => new Promise((resolve, reject) => zlib.deflateRaw(data, { level }, (err, result) => {
|
|
51
30
|
if (err) reject(err);
|
|
52
31
|
else resolve(result);
|
|
53
32
|
}));
|
|
54
33
|
_nativeCrc32 = typeof zlib.crc32 === "function" ? (data) => zlib.crc32(data) : computeCrc32;
|
|
55
|
-
if (typeof zlib.inflateRawSync === "function") _nativeInflate = (data) => zlib.inflateRawSync(data);
|
|
34
|
+
if (typeof zlib.inflateRawSync === "function" && _nativeInflate === void 0) _nativeInflate = (data) => zlib.inflateRawSync(data);
|
|
56
35
|
} catch {}
|
|
57
36
|
const hasNativeDeflate = () => _nativeDeflate !== void 0;
|
|
58
37
|
const hasNativeInflate = () => _nativeInflate !== void 0;
|
|
38
|
+
const _prefersMainThreadDeflate = typeof bunApi?.deflateSync === "function";
|
|
39
|
+
/**
|
|
40
|
+
* True when DEFLATE work should run on the main thread instead of fflate's
|
|
41
|
+
* per-entry workers (Bun). See {@link createZipStream} in packer.ts.
|
|
42
|
+
*/
|
|
43
|
+
const prefersMainThreadDeflate = () => _prefersMainThreadDeflate;
|
|
44
|
+
/**
|
|
45
|
+
* Synchronous native CRC-32 (`zlib.crc32`, Node/Bun only) — undefined where no
|
|
46
|
+
* native zlib resolved (browsers/Deno). Used by media dedup as a fast content
|
|
47
|
+
* key; callers keep their own JS fallback. ~59× faster than a JS hash on
|
|
48
|
+
* 100 MB inputs.
|
|
49
|
+
*/
|
|
50
|
+
function nativeCrc32(data) {
|
|
51
|
+
return _nativeCrc32?.(data);
|
|
52
|
+
}
|
|
59
53
|
function wU16(b, o, v) {
|
|
60
54
|
b[o] = v & 255;
|
|
61
55
|
b[o + 1] = v >> 8 & 255;
|
|
@@ -190,25 +184,24 @@ function nativeZip(files, level = 6) {
|
|
|
190
184
|
return writeZipBuffer(entries);
|
|
191
185
|
}
|
|
192
186
|
async function nativeZipAsync(files, level = 6) {
|
|
193
|
-
|
|
187
|
+
const deflateAsync = _nativeDeflateAsync;
|
|
188
|
+
if (!deflateAsync) throw new Error("Native async deflate not available");
|
|
194
189
|
const crc = _nativeCrc32 ?? computeCrc32;
|
|
195
|
-
|
|
196
|
-
for (const key of Object.keys(files)) {
|
|
190
|
+
return writeZipBuffer((await Promise.all(Object.keys(files).map(async (key) => {
|
|
197
191
|
const raw = files[key];
|
|
198
|
-
if (raw === void 0)
|
|
192
|
+
if (raw === void 0) return null;
|
|
199
193
|
const { data, level: entryLevel } = resolveEntryData(raw, level);
|
|
200
194
|
const c = crc(data);
|
|
201
|
-
const { compressed, method } = await compressOneAsync(data, entryLevel,
|
|
202
|
-
|
|
195
|
+
const { compressed, method } = await compressOneAsync(data, entryLevel, deflateAsync);
|
|
196
|
+
return {
|
|
203
197
|
filename: textEncoder.encode(key),
|
|
204
198
|
data: compressed,
|
|
205
199
|
uncompressedSize: data.length,
|
|
206
200
|
crc: c,
|
|
207
201
|
method,
|
|
208
202
|
localOffset: 0
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return writeZipBuffer(entries);
|
|
203
|
+
};
|
|
204
|
+
}))).filter((e) => e !== null));
|
|
212
205
|
}
|
|
213
206
|
function rU16(b, o) {
|
|
214
207
|
return b[o] | b[o + 1] << 8;
|
|
@@ -274,6 +267,32 @@ function nativeUnzip(buf) {
|
|
|
274
267
|
return out;
|
|
275
268
|
}
|
|
276
269
|
//#endregion
|
|
270
|
+
//#region src/opc/output.ts
|
|
271
|
+
/**
|
|
272
|
+
* Output type definitions for OOXML document export.
|
|
273
|
+
*
|
|
274
|
+
* @module
|
|
275
|
+
*/
|
|
276
|
+
const OoxmlMimeType = {
|
|
277
|
+
DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
278
|
+
PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
279
|
+
XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
280
|
+
};
|
|
281
|
+
const convertOutput = (data, type, mimeType = OoxmlMimeType.DOCX) => {
|
|
282
|
+
switch (type) {
|
|
283
|
+
case "nodebuffer": return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
284
|
+
case "blob": return new Blob([data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)], { type: mimeType });
|
|
285
|
+
case "arraybuffer": return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
286
|
+
case "uint8array": return data;
|
|
287
|
+
case "base64": return encodeBase64(data);
|
|
288
|
+
case "string":
|
|
289
|
+
case "text":
|
|
290
|
+
case "binarystring": return strFromU8(data, true);
|
|
291
|
+
case "array": return [...data];
|
|
292
|
+
default: return data;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
//#endregion
|
|
277
296
|
//#region src/opc/packer.ts
|
|
278
297
|
/**
|
|
279
298
|
* Shared packer utilities for OOXML document generation.
|
|
@@ -286,15 +305,26 @@ const ZIP_DEFLATE_LEVEL = 1;
|
|
|
286
305
|
const ZIP_STORED_LEVEL = 0;
|
|
287
306
|
/**
|
|
288
307
|
* Media formats already compressed internally (DEFLATE for PNG, DCT for JPEG,
|
|
289
|
-
* LZW for GIF
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
|
|
293
|
-
|
|
308
|
+
* LZW for GIF; video/audio containers carry their own codec streams).
|
|
309
|
+
* Re-compressing via zip DEFLATE wastes CPU and often inflates the data, so
|
|
310
|
+
* MS Office STORE-s these (CompressionOption.NotCompressed → zip method 0).
|
|
311
|
+
* Everything else (EMF/WMF/BMP/TIFF/SVG/WAV…) is compressible → DEFLATE —
|
|
312
|
+
* measured on a real Office package, EMF at zlib level 6 matches Office
|
|
313
|
+
* output where SuperFast inflates ~15%.
|
|
314
|
+
*/
|
|
315
|
+
const PRECOMPRESSED_MEDIA_EXT = /* @__PURE__ */ new Set([
|
|
294
316
|
"jpg",
|
|
295
317
|
"jpeg",
|
|
296
318
|
"png",
|
|
297
|
-
"gif"
|
|
319
|
+
"gif",
|
|
320
|
+
"mp4",
|
|
321
|
+
"mov",
|
|
322
|
+
"wmv",
|
|
323
|
+
"mpg",
|
|
324
|
+
"mpeg",
|
|
325
|
+
"mp3",
|
|
326
|
+
"wma",
|
|
327
|
+
"aac"
|
|
298
328
|
]);
|
|
299
329
|
/**
|
|
300
330
|
* Resolve the ZIP level for a media entry by file-name extension, matching MS
|
|
@@ -311,14 +341,15 @@ const levelForMediaName = (fileName, mediaLevel) => {
|
|
|
311
341
|
/**
|
|
312
342
|
* Asynchronously compress files and convert to the requested output format.
|
|
313
343
|
*
|
|
314
|
-
*
|
|
344
|
+
* Where a native zlib resolved (Node/Bun), entries deflate in parallel on the
|
|
345
|
+
* libuv thread pool; elsewhere fflate compresses off the main thread.
|
|
315
346
|
* XML entries use DEFLATE level 1 (SuperFast) by default. Media entries are
|
|
316
347
|
* split by type, matching MS Office: already-compressed formats (PNG/JPEG/GIF)
|
|
317
348
|
* are STOREd, everything else uses the `media` level (default Normal).
|
|
318
349
|
* Set `{ media: ZIP_STORED_LEVEL }` to STORE all compressible media too.
|
|
319
350
|
*/
|
|
320
351
|
const zipAndConvert = async (files, type, mimeType, level = 1) => {
|
|
321
|
-
|
|
352
|
+
const zipped = hasNativeDeflate() ? await nativeZipAsync(files, level) : await new Promise((resolve, reject) => {
|
|
322
353
|
zip(files, {
|
|
323
354
|
level,
|
|
324
355
|
consume: true
|
|
@@ -326,7 +357,8 @@ const zipAndConvert = async (files, type, mimeType, level = 1) => {
|
|
|
326
357
|
if (err) reject(err);
|
|
327
358
|
else resolve(data);
|
|
328
359
|
});
|
|
329
|
-
})
|
|
360
|
+
});
|
|
361
|
+
return convertOutput(zipped, type, mimeType);
|
|
330
362
|
};
|
|
331
363
|
/**
|
|
332
364
|
* Synchronously compress files and convert to the requested output format.
|
|
@@ -335,7 +367,8 @@ const zipAndConvert = async (files, type, mimeType, level = 1) => {
|
|
|
335
367
|
* Blocks the event loop — prefer {@link zipAndConvert} in server contexts.
|
|
336
368
|
*/
|
|
337
369
|
const zipSyncAndConvert = (files, type, mimeType, level = 1) => {
|
|
338
|
-
|
|
370
|
+
const zipped = hasNativeDeflate() ? nativeZip(files, level) : zipSync(files, { level });
|
|
371
|
+
return convertOutput(zipped, type, mimeType);
|
|
339
372
|
};
|
|
340
373
|
/**
|
|
341
374
|
* Create a `ReadableStream<Uint8Array>` from compressed file entries.
|
|
@@ -345,6 +378,7 @@ const zipSyncAndConvert = (files, type, mimeType, level = 1) => {
|
|
|
345
378
|
* Works in both Node.js and browsers (Web Streams API).
|
|
346
379
|
*/
|
|
347
380
|
const createZipStream = (files, defaultLevel = 1) => {
|
|
381
|
+
const mainThread = prefersMainThreadDeflate();
|
|
348
382
|
return new ReadableStream({ start(controller) {
|
|
349
383
|
try {
|
|
350
384
|
const zip = new Zip((err, chunk, _final) => {
|
|
@@ -358,9 +392,10 @@ const createZipStream = (files, defaultLevel = 1) => {
|
|
|
358
392
|
for (const [name, data] of Object.entries(files)) {
|
|
359
393
|
const raw = Array.isArray(data) ? data[0] : data;
|
|
360
394
|
const level = Array.isArray(data) ? data[1].level ?? defaultLevel : defaultLevel;
|
|
361
|
-
const
|
|
395
|
+
const workerPath = level !== 0 && !mainThread;
|
|
396
|
+
const entry = level === 0 ? new ZipPassThrough(name) : workerPath ? new AsyncZipDeflate(name, { level }) : new ZipDeflate(name, { level });
|
|
362
397
|
zip.add(entry);
|
|
363
|
-
entry.push(raw, true);
|
|
398
|
+
entry.push(workerPath ? raw.slice() : raw, true);
|
|
364
399
|
}
|
|
365
400
|
zip.end();
|
|
366
401
|
} catch (err) {
|
|
@@ -369,6 +404,47 @@ const createZipStream = (files, defaultLevel = 1) => {
|
|
|
369
404
|
} });
|
|
370
405
|
};
|
|
371
406
|
/**
|
|
407
|
+
* Incremental ZIP archive writer over fflate's streaming `Zip` — parts are
|
|
408
|
+
* added and completed one at a time; compressed output flows to `ondata` as
|
|
409
|
+
* it is produced. This is the constant-memory counterpart to
|
|
410
|
+
* {@link createZipStream} (which requires the complete `Zippable` up front):
|
|
411
|
+
* serialize each part chunk-wise into the returned sink instead of building
|
|
412
|
+
* the full part string.
|
|
413
|
+
*
|
|
414
|
+
* Parts must be added in order — `[Content_Types].xml` first per OPC. The
|
|
415
|
+
* whole archive finishes when {@link ZipStreamWriter.end} is called.
|
|
416
|
+
*/
|
|
417
|
+
var ZipStreamWriter = class {
|
|
418
|
+
defaultLevel;
|
|
419
|
+
zip;
|
|
420
|
+
current;
|
|
421
|
+
mainThread = prefersMainThreadDeflate();
|
|
422
|
+
constructor(ondata, defaultLevel = 1) {
|
|
423
|
+
this.defaultLevel = defaultLevel;
|
|
424
|
+
this.zip = new Zip(ondata);
|
|
425
|
+
}
|
|
426
|
+
/** Add a part and return its incremental sink. `end()` the previous first. */
|
|
427
|
+
addPart(name, level = this.defaultLevel) {
|
|
428
|
+
if (this.current) throw new Error(`ZipStreamWriter: previous part not finalized`);
|
|
429
|
+
const workerPath = level !== 0 && !this.mainThread;
|
|
430
|
+
const entry = level === 0 ? new ZipPassThrough(name) : workerPath ? new AsyncZipDeflate(name, { level }) : new ZipDeflate(name, { level });
|
|
431
|
+
this.zip.add(entry);
|
|
432
|
+
this.current = entry;
|
|
433
|
+
return {
|
|
434
|
+
push: (chunk) => entry.push(workerPath ? chunk.slice() : chunk, false),
|
|
435
|
+
end: (lastChunk) => {
|
|
436
|
+
entry.push((workerPath ? lastChunk?.slice() : lastChunk) ?? /* @__PURE__ */ new Uint8Array(0), true);
|
|
437
|
+
this.current = void 0;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
/** Finish the archive (central directory + EOCD). */
|
|
442
|
+
end() {
|
|
443
|
+
if (this.current) throw new Error(`ZipStreamWriter: unclosed part at end()`);
|
|
444
|
+
this.zip.end();
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
372
448
|
* Create a Packer object with all output format methods.
|
|
373
449
|
*
|
|
374
450
|
* Centralises the ZIP → convert pipeline and the streaming implementation
|
|
@@ -379,7 +455,8 @@ const createPacker = (options) => {
|
|
|
379
455
|
const { compile, mimeType } = options;
|
|
380
456
|
const pack = async (file, opts) => {
|
|
381
457
|
const type = opts?.type ?? "nodebuffer";
|
|
382
|
-
|
|
458
|
+
const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6);
|
|
459
|
+
return zipAndConvert(files, type, mimeType, opts?.compression?.xml ?? 1);
|
|
383
460
|
};
|
|
384
461
|
const toBytes = (file, opts) => pack(file, {
|
|
385
462
|
...opts,
|
|
@@ -407,7 +484,8 @@ const createPacker = (options) => {
|
|
|
407
484
|
});
|
|
408
485
|
const packSync = (file, opts) => {
|
|
409
486
|
const type = opts?.type ?? "nodebuffer";
|
|
410
|
-
|
|
487
|
+
const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6);
|
|
488
|
+
return zipSyncAndConvert(files, type, mimeType, opts?.compression?.xml ?? 1);
|
|
411
489
|
};
|
|
412
490
|
const toBytesSync = (file, opts) => packSync(file, {
|
|
413
491
|
...opts,
|
|
@@ -473,16 +551,25 @@ const createPacker = (options) => {
|
|
|
473
551
|
*/
|
|
474
552
|
/** Reusable TextEncoder instance (stateless, safe to share). */
|
|
475
553
|
const encoder = new TextEncoder();
|
|
554
|
+
/** Add one binary ZIP entry using the shared media compression policy. */
|
|
555
|
+
function addBinaryFile(files, path, data, mediaLevel) {
|
|
556
|
+
files[path] = [data, { level: levelForMediaName(path, mediaLevel) }];
|
|
557
|
+
}
|
|
476
558
|
/**
|
|
477
|
-
* Convert
|
|
559
|
+
* Convert XML files, overrides, and media into a Zippable structure.
|
|
478
560
|
*
|
|
479
|
-
*
|
|
561
|
+
* Mapping values may be optional arrays so package compilers can pass their
|
|
562
|
+
* natural part mappings without reimplementing flattening and byte encoding.
|
|
480
563
|
*/
|
|
481
564
|
function compileMapping(mapping, overrides, media, mediaLevel = 0) {
|
|
482
565
|
const files = {};
|
|
483
|
-
for (const entry of Object.values(mapping))
|
|
484
|
-
|
|
485
|
-
|
|
566
|
+
for (const entry of Object.values(mapping)) {
|
|
567
|
+
if (entry === void 0) continue;
|
|
568
|
+
const entries = Array.isArray(entry) ? entry : [entry];
|
|
569
|
+
for (const file of entries) files[file.path] = typeof file.data === "string" ? encoder.encode(file.data) : file.data;
|
|
570
|
+
}
|
|
571
|
+
for (const override of overrides ?? []) files[override.path] = typeof override.data === "string" ? encoder.encode(override.data) : override.data;
|
|
572
|
+
for (const file of media ?? []) addBinaryFile(files, file.path, file.data, mediaLevel);
|
|
486
573
|
return files;
|
|
487
574
|
}
|
|
488
575
|
//#endregion
|
|
@@ -493,7 +580,7 @@ function compileMapping(mapping, overrides, media, mediaLevel = 0) {
|
|
|
493
580
|
* Implements ECMA-376 Agile Encryption password derivation.
|
|
494
581
|
* Passwords are encoded as UTF-16LE per the OOXML specification.
|
|
495
582
|
*
|
|
496
|
-
* Uses
|
|
583
|
+
* Uses `@noble`/hashes for SHA-512 — audited, cross-platform,
|
|
497
584
|
* and comparable in speed to node:crypto for this workload.
|
|
498
585
|
*
|
|
499
586
|
* @module
|
|
@@ -554,19 +641,46 @@ function derivePasswordHash(password, spinCount = 1e5) {
|
|
|
554
641
|
//#endregion
|
|
555
642
|
//#region src/util/placeholder.ts
|
|
556
643
|
const formatId = (offset, index, style) => style === "rId" ? `rId${offset + index}` : `${offset + index}`;
|
|
557
|
-
/**
|
|
558
|
-
|
|
644
|
+
/**
|
|
645
|
+
* Find the next `{key}` placeholder at/after `from`. Returns `[open, close]`
|
|
646
|
+
* brace indices, or undefined when none remain. Mirrors the semantics of
|
|
647
|
+
* `/\{([^{}]+)\}/g`: empty keys and keys containing `{` are skipped (the scan
|
|
648
|
+
* restarts after the nested brace), matching what the regex would accept.
|
|
649
|
+
*/
|
|
650
|
+
function nextPlaceholder(xml, from) {
|
|
651
|
+
let pos = from;
|
|
652
|
+
for (;;) {
|
|
653
|
+
const open = xml.indexOf("{", pos);
|
|
654
|
+
if (open === -1) return void 0;
|
|
655
|
+
const close = xml.indexOf("}", open + 1);
|
|
656
|
+
if (close === -1) return void 0;
|
|
657
|
+
if (close - open - 1 === 0) {
|
|
658
|
+
pos = open + 1;
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
const nextOpen = xml.indexOf("{", open + 1);
|
|
662
|
+
if (nextOpen !== -1 && nextOpen < close) {
|
|
663
|
+
pos = open + 1;
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
return [open, close];
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
/** Replace `{name}` placeholders with the given values (missing keys stay). */
|
|
559
670
|
function replacePlaceholders(xml, map) {
|
|
560
671
|
const parts = [];
|
|
561
672
|
let last = 0;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
673
|
+
let pos = 0;
|
|
674
|
+
for (;;) {
|
|
675
|
+
const found = nextPlaceholder(xml, pos);
|
|
676
|
+
if (found === void 0) break;
|
|
677
|
+
const [open, close] = found;
|
|
678
|
+
const replacement = map.get(xml.substring(open + 1, close));
|
|
566
679
|
if (replacement !== void 0) {
|
|
567
|
-
parts.push(xml.substring(last,
|
|
568
|
-
last =
|
|
680
|
+
parts.push(xml.substring(last, open), replacement);
|
|
681
|
+
last = close + 1;
|
|
569
682
|
}
|
|
683
|
+
pos = close + 1;
|
|
570
684
|
}
|
|
571
685
|
if (last === 0) return xml;
|
|
572
686
|
parts.push(xml.substring(last));
|
|
@@ -605,7 +719,7 @@ function getReferencedMedia(xml, mediaArray) {
|
|
|
605
719
|
* and returns the list of referenced media items for relationship registration.
|
|
606
720
|
* More efficient than calling getReferencedMedia() + replaceImagePlaceholders() separately.
|
|
607
721
|
*/
|
|
608
|
-
function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rId") {
|
|
722
|
+
function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rId", sourceRids) {
|
|
609
723
|
if (mediaArray.length === 0 || !hasPlaceholders(xml)) return {
|
|
610
724
|
xml,
|
|
611
725
|
referenced: []
|
|
@@ -616,18 +730,24 @@ function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rI
|
|
|
616
730
|
const replaceMap = /* @__PURE__ */ new Map();
|
|
617
731
|
const parts = [];
|
|
618
732
|
let last = 0;
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
733
|
+
let pos = 0;
|
|
734
|
+
for (;;) {
|
|
735
|
+
const found = nextPlaceholder(xml, pos);
|
|
736
|
+
if (found === void 0) break;
|
|
737
|
+
const [open, close] = found;
|
|
738
|
+
const key = xml.substring(open + 1, close);
|
|
622
739
|
const item = itemMap.get(key);
|
|
623
740
|
if (item !== void 0) {
|
|
624
|
-
|
|
625
|
-
|
|
741
|
+
let id = replaceMap.get(key);
|
|
742
|
+
if (id === void 0) {
|
|
743
|
+
id = sourceRids?.get(key) ?? formatId(offset, referenced.length, idFormat);
|
|
744
|
+
replaceMap.set(key, id);
|
|
626
745
|
referenced.push(item);
|
|
627
746
|
}
|
|
628
|
-
parts.push(xml.substring(last,
|
|
629
|
-
last =
|
|
747
|
+
parts.push(xml.substring(last, open), id);
|
|
748
|
+
last = close + 1;
|
|
630
749
|
}
|
|
750
|
+
pos = close + 1;
|
|
631
751
|
}
|
|
632
752
|
if (last === 0) return {
|
|
633
753
|
xml,
|
|
@@ -674,7 +794,7 @@ function replaceSmartArtPlaceholders(xml, keys, dataOffset, idFormat = "rId") {
|
|
|
674
794
|
return replacePlaceholders(xml, map);
|
|
675
795
|
}
|
|
676
796
|
function addSmartArtRelationships(keys, addRel, baseOffset, globalStartIndex, options) {
|
|
677
|
-
const { pathPrefix, styleRelType } = options;
|
|
797
|
+
const { pathPrefix, styleRelType, hasDrawing } = options;
|
|
678
798
|
const count = keys.length;
|
|
679
799
|
const loOffset = baseOffset + count;
|
|
680
800
|
const qsOffset = loOffset + count;
|
|
@@ -685,7 +805,7 @@ function addSmartArtRelationships(keys, addRel, baseOffset, globalStartIndex, op
|
|
|
685
805
|
addRel(loOffset + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout", `${pathPrefix}diagrams/layout${gi + 1}.xml`);
|
|
686
806
|
addRel(qsOffset + i, styleRelType, `${pathPrefix}diagrams/quickStyle${gi + 1}.xml`);
|
|
687
807
|
addRel(csOffset + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors", `${pathPrefix}diagrams/colors${gi + 1}.xml`);
|
|
688
|
-
addRel(csOffset + count + i, "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing", `${pathPrefix}diagrams/drawing${gi + 1}.xml`);
|
|
808
|
+
if (hasDrawing === void 0 || hasDrawing(keys[i])) addRel(csOffset + count + i, "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing", `${pathPrefix}diagrams/drawing${gi + 1}.xml`);
|
|
689
809
|
}
|
|
690
810
|
}
|
|
691
811
|
/** Replace `{reference-instance}` placeholders with numId values. */
|
|
@@ -697,16 +817,24 @@ function replaceNumberingPlaceholders(xml, concreteNumberings) {
|
|
|
697
817
|
}
|
|
698
818
|
/** Replace `{media:fileName}` placeholders with relationship IDs. */
|
|
699
819
|
function replaceMediaPlaceholders(xml, mediaData, offset) {
|
|
700
|
-
|
|
701
|
-
const map = /* @__PURE__ */ new Map();
|
|
702
|
-
for (const [i, item] of mediaData.entries()) map.set(`media:${item.fileName}`, formatId(offset, i, "rId"));
|
|
703
|
-
return replacePlaceholders(xml, map);
|
|
820
|
+
return replacePrefixedPlaceholders(xml, mediaData, offset, "media:");
|
|
704
821
|
}
|
|
705
822
|
/** Replace `{video:fileName}` placeholders with relationship IDs. */
|
|
706
823
|
function replaceVideoPlaceholders(xml, mediaData, offset) {
|
|
824
|
+
return replacePrefixedPlaceholders(xml, mediaData, offset, "video:");
|
|
825
|
+
}
|
|
826
|
+
/** Replace `{audio:fileName}` placeholders with relationship IDs. */
|
|
827
|
+
function replaceAudioPlaceholders(xml, mediaData, offset) {
|
|
828
|
+
return replacePrefixedPlaceholders(xml, mediaData, offset, "audio:");
|
|
829
|
+
}
|
|
830
|
+
/** Replace `{ole:fileName}` placeholders with relationship IDs. */
|
|
831
|
+
function replaceOlePlaceholders(xml, embeddings, offset) {
|
|
832
|
+
return replacePrefixedPlaceholders(xml, embeddings, offset, "ole:");
|
|
833
|
+
}
|
|
834
|
+
function replacePrefixedPlaceholders(xml, mediaData, offset, prefix) {
|
|
707
835
|
if (mediaData.length === 0) return xml;
|
|
708
836
|
const map = /* @__PURE__ */ new Map();
|
|
709
|
-
for (const [i, item] of mediaData.entries()) map.set(
|
|
837
|
+
for (const [i, item] of mediaData.entries()) map.set(`${prefix}${item.fileName}`, formatId(offset, i, "rId"));
|
|
710
838
|
return replacePlaceholders(xml, map);
|
|
711
839
|
}
|
|
712
840
|
/** Collect media items referenced by `{media:...}` placeholders in XML. */
|
|
@@ -717,6 +845,14 @@ function getMediaRefs(xml, mediaArray) {
|
|
|
717
845
|
function getVideoRefs(xml, mediaArray) {
|
|
718
846
|
return collectPrefixedRefs(xml, "video:", mediaArray);
|
|
719
847
|
}
|
|
848
|
+
/** Collect media items referenced by `{audio:...}` placeholders in XML. */
|
|
849
|
+
function getAudioRefs(xml, mediaArray) {
|
|
850
|
+
return collectPrefixedRefs(xml, "audio:", mediaArray);
|
|
851
|
+
}
|
|
852
|
+
/** Collect OLE embeddings referenced by `{ole:...}` placeholders in XML. */
|
|
853
|
+
function getOleRefs(xml, embeddings) {
|
|
854
|
+
return collectPrefixedRefs(xml, "ole:", embeddings);
|
|
855
|
+
}
|
|
720
856
|
function collectPrefixedRefs(xml, prefix, mediaArray) {
|
|
721
857
|
const keys = /* @__PURE__ */ new Set();
|
|
722
858
|
const search = `{${prefix}`;
|
|
@@ -730,384 +866,26 @@ function collectPrefixedRefs(xml, prefix, mediaArray) {
|
|
|
730
866
|
}
|
|
731
867
|
return mediaArray.filter((m) => keys.has(m.fileName));
|
|
732
868
|
}
|
|
733
|
-
/** Replace `{
|
|
734
|
-
function
|
|
735
|
-
if (
|
|
869
|
+
/** Replace `{prefix:key}` placeholders with relationship IDs. */
|
|
870
|
+
function replaceKeyedPlaceholders(xml, items, offset, prefix) {
|
|
871
|
+
if (items.length === 0) return xml;
|
|
736
872
|
const map = /* @__PURE__ */ new Map();
|
|
737
|
-
for (const [i,
|
|
873
|
+
for (const [i, item] of items.entries()) map.set(`${prefix}${item.key}`, formatId(offset, i, "rId"));
|
|
738
874
|
return replacePlaceholders(xml, map);
|
|
739
875
|
}
|
|
876
|
+
/** Replace `{hlink:key}` placeholders with relationship IDs. */
|
|
877
|
+
function replaceHyperlinkPlaceholders(xml, hyperlinks, offset) {
|
|
878
|
+
return replaceKeyedPlaceholders(xml, hyperlinks, offset, "hlink:");
|
|
879
|
+
}
|
|
880
|
+
/** Replace `{img-link:key}` placeholders with relationship IDs. */
|
|
881
|
+
function replaceImageLinkPlaceholders(xml, links, offset) {
|
|
882
|
+
return replaceKeyedPlaceholders(xml, links, offset, "img-link:");
|
|
883
|
+
}
|
|
884
|
+
/** Replace `{ole-link:key}` placeholders with relationship IDs. */
|
|
885
|
+
function replaceOleLinkPlaceholders(xml, links, offset) {
|
|
886
|
+
return replaceKeyedPlaceholders(xml, links, offset, "ole-link:");
|
|
887
|
+
}
|
|
740
888
|
//#endregion
|
|
741
|
-
|
|
742
|
-
/**
|
|
743
|
-
* Validates and converts a number to an integer (decimal number).
|
|
744
|
-
*
|
|
745
|
-
* Reference: ST_DecimalNumber in OOXML specification
|
|
746
|
-
*
|
|
747
|
-
* @param val - The number to validate and convert
|
|
748
|
-
* @returns The floored integer value
|
|
749
|
-
* @throws Error if the value is NaN
|
|
750
|
-
*
|
|
751
|
-
* @example
|
|
752
|
-
* ```typescript
|
|
753
|
-
* const num = decimalNumber(10.7); // Returns 10
|
|
754
|
-
* const negative = decimalNumber(-5.3); // Returns -5
|
|
755
|
-
* ```
|
|
756
|
-
*/
|
|
757
|
-
const decimalNumber = (val) => {
|
|
758
|
-
if (!Number.isFinite(val)) throw new Error(`Invalid value '${val}' specified. Must be a finite number.`);
|
|
759
|
-
return Math.floor(val);
|
|
760
|
-
};
|
|
761
|
-
/**
|
|
762
|
-
* Validates and converts a number to a positive integer (unsigned decimal number).
|
|
763
|
-
*
|
|
764
|
-
* Reference: ST_UnsignedDecimalNumber in OOXML specification
|
|
765
|
-
*
|
|
766
|
-
* @param val - The number to validate and convert
|
|
767
|
-
* @returns The floored positive integer value
|
|
768
|
-
* @throws Error if the value is NaN or negative
|
|
769
|
-
*
|
|
770
|
-
* @example
|
|
771
|
-
* ```typescript
|
|
772
|
-
* const num = unsignedDecimalNumber(10.7); // Returns 10
|
|
773
|
-
* const invalid = unsignedDecimalNumber(-5); // Throws Error
|
|
774
|
-
* ```
|
|
775
|
-
*/
|
|
776
|
-
const unsignedDecimalNumber = (val) => {
|
|
777
|
-
const value = decimalNumber(val);
|
|
778
|
-
if (value < 0) throw new Error(`Invalid value '${val}' specified. Must be a positive integer.`);
|
|
779
|
-
return value;
|
|
780
|
-
};
|
|
781
|
-
/**
|
|
782
|
-
* Validates and normalizes a hexadecimal binary value.
|
|
783
|
-
*
|
|
784
|
-
* The xsd:hexBinary type represents binary data as a sequence of binary octets
|
|
785
|
-
* using hexadecimal encoding, where each binary octet is a two-character
|
|
786
|
-
* hexadecimal number. Both lowercase and uppercase letters A-F are permitted.
|
|
787
|
-
*
|
|
788
|
-
* @param val - The hexadecimal string to validate
|
|
789
|
-
* @param length - The expected length in bytes (not characters)
|
|
790
|
-
* @returns The validated hexadecimal string
|
|
791
|
-
* @throws Error if the value is not a valid hex string of the expected length
|
|
792
|
-
*
|
|
793
|
-
* @example
|
|
794
|
-
* ```typescript
|
|
795
|
-
* hexBinary("0FB8", 2); // Valid: 2 bytes = 4 characters
|
|
796
|
-
* hexBinary("ABC", 2); // Invalid: wrong length
|
|
797
|
-
* ```
|
|
798
|
-
*/
|
|
799
|
-
const hexBinary = (val, length) => {
|
|
800
|
-
const expectedLength = length * 2;
|
|
801
|
-
if (val.length !== expectedLength || isNaN(Number(`0x${val}`))) throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);
|
|
802
|
-
return val;
|
|
803
|
-
};
|
|
804
|
-
/**
|
|
805
|
-
* Validates a long hexadecimal number (4 bytes / 8 characters).
|
|
806
|
-
*
|
|
807
|
-
* Reference: ST_LongHexNumber in OOXML specification
|
|
808
|
-
*
|
|
809
|
-
* @param val - The hexadecimal string to validate
|
|
810
|
-
* @returns The validated hexadecimal string
|
|
811
|
-
* @throws Error if the value is not a valid 8-character hex string
|
|
812
|
-
*
|
|
813
|
-
* @example
|
|
814
|
-
* ```typescript
|
|
815
|
-
* const hex = longHexNumber("ABCD1234"); // Valid
|
|
816
|
-
* ```
|
|
817
|
-
*/
|
|
818
|
-
const longHexNumber = (val) => hexBinary(val, 4);
|
|
819
|
-
/**
|
|
820
|
-
* Validates a short hexadecimal number (2 bytes / 4 characters).
|
|
821
|
-
*
|
|
822
|
-
* Reference: ST_ShortHexNumber in OOXML specification
|
|
823
|
-
*
|
|
824
|
-
* @param val - The hexadecimal string to validate
|
|
825
|
-
* @returns The validated hexadecimal string
|
|
826
|
-
* @throws Error if the value is not a valid 4-character hex string
|
|
827
|
-
*
|
|
828
|
-
* @example
|
|
829
|
-
* ```typescript
|
|
830
|
-
* const hex = shortHexNumber("AB12"); // Valid
|
|
831
|
-
* ```
|
|
832
|
-
*/
|
|
833
|
-
const shortHexNumber = (val) => hexBinary(val, 2);
|
|
834
|
-
/**
|
|
835
|
-
* Validates a single-byte hexadecimal number (1 byte / 2 characters).
|
|
836
|
-
*
|
|
837
|
-
* Reference: ST_UcharHexNumber in OOXML specification
|
|
838
|
-
*
|
|
839
|
-
* @param val - The hexadecimal string to validate
|
|
840
|
-
* @returns The validated hexadecimal string
|
|
841
|
-
* @throws Error if the value is not a valid 2-character hex string
|
|
842
|
-
*
|
|
843
|
-
* @example
|
|
844
|
-
* ```typescript
|
|
845
|
-
* const hex = uCharHexNumber("FF"); // Valid
|
|
846
|
-
* ```
|
|
847
|
-
*/
|
|
848
|
-
const uCharHexNumber = (val) => hexBinary(val, 1);
|
|
849
|
-
/**
|
|
850
|
-
* Normalizes a universal measure value by parsing and reformatting.
|
|
851
|
-
*
|
|
852
|
-
* Ensures the numeric portion is properly formatted while preserving the unit.
|
|
853
|
-
*
|
|
854
|
-
* Reference: ST_UniversalMeasure in OOXML specification
|
|
855
|
-
*
|
|
856
|
-
* @param val - The universal measure string to normalize
|
|
857
|
-
* @returns The normalized universal measure
|
|
858
|
-
*
|
|
859
|
-
* @example
|
|
860
|
-
* ```typescript
|
|
861
|
-
* const measure = universalMeasureValue("10.500mm"); // Returns "10.5mm"
|
|
862
|
-
* ```
|
|
863
|
-
*/
|
|
864
|
-
const universalMeasureValue = (val) => {
|
|
865
|
-
const unit = val.slice(-2);
|
|
866
|
-
const amount = val.substring(0, val.length - 2);
|
|
867
|
-
return `${Number(amount)}${unit}`;
|
|
868
|
-
};
|
|
869
|
-
/**
|
|
870
|
-
* Validates and normalizes a positive universal measure value.
|
|
871
|
-
*
|
|
872
|
-
* Reference: ST_PositiveUniversalMeasure in OOXML specification
|
|
873
|
-
*
|
|
874
|
-
* @param val - The positive universal measure string to validate
|
|
875
|
-
* @returns The normalized positive universal measure
|
|
876
|
-
* @throws Error if the value is negative
|
|
877
|
-
*
|
|
878
|
-
* @example
|
|
879
|
-
* ```typescript
|
|
880
|
-
* const measure = positiveUniversalMeasureValue("10.5mm"); // Valid
|
|
881
|
-
* const invalid = positiveUniversalMeasureValue("-5mm"); // Throws Error
|
|
882
|
-
* ```
|
|
883
|
-
*/
|
|
884
|
-
const positiveUniversalMeasureValue = (val) => {
|
|
885
|
-
const value = universalMeasureValue(val);
|
|
886
|
-
if (parseFloat(value) < 0) throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);
|
|
887
|
-
return value;
|
|
888
|
-
};
|
|
889
|
-
/**
|
|
890
|
-
* Validates and normalizes a hexadecimal color value.
|
|
891
|
-
*
|
|
892
|
-
* Accepts either "auto" or a 6-character RGB hex value (with or without # prefix).
|
|
893
|
-
* The # prefix is commonly used but technically invalid in OOXML, so it is stripped
|
|
894
|
-
* for strict compliance.
|
|
895
|
-
*
|
|
896
|
-
* Reference: ST_HexColor in OOXML specification
|
|
897
|
-
*
|
|
898
|
-
* @param val - The color value to validate ("auto" or hex color)
|
|
899
|
-
* @returns The normalized color value
|
|
900
|
-
* @throws Error if the hex color is invalid
|
|
901
|
-
*
|
|
902
|
-
* @example
|
|
903
|
-
* ```typescript
|
|
904
|
-
* const color1 = hexColorValue("auto"); // Returns "auto"
|
|
905
|
-
* const color2 = hexColorValue("FF0000"); // Returns "FF0000"
|
|
906
|
-
* const color3 = hexColorValue("#00FF00"); // Returns "00FF00" (# stripped)
|
|
907
|
-
* ```
|
|
908
|
-
*/
|
|
909
|
-
const hexColorValue = (val) => {
|
|
910
|
-
if (val === "auto") return val;
|
|
911
|
-
return hexBinary(val.charAt(0) === "#" ? val.substring(1) : val, 3);
|
|
912
|
-
};
|
|
913
|
-
/**
|
|
914
|
-
* Validates a signed TWIP measurement value.
|
|
915
|
-
*
|
|
916
|
-
* Accepts either a universal measure string or a numeric TWIP value.
|
|
917
|
-
*
|
|
918
|
-
* Reference: ST_SignedTwipsMeasure in OOXML specification
|
|
919
|
-
*
|
|
920
|
-
* @param val - The measurement value (universal measure or number)
|
|
921
|
-
* @returns The normalized measurement value
|
|
922
|
-
*
|
|
923
|
-
* @example
|
|
924
|
-
* ```typescript
|
|
925
|
-
* const measure1 = signedTwipsMeasureValue("10mm");
|
|
926
|
-
* const measure2 = signedTwipsMeasureValue(1440); // 1 inch in TWIP
|
|
927
|
-
* ```
|
|
928
|
-
*/
|
|
929
|
-
const signedTwipsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
|
930
|
-
/**
|
|
931
|
-
* Validates a half-point (HPS) measurement value.
|
|
932
|
-
*
|
|
933
|
-
* Accepts either a positive universal measure string or a positive number.
|
|
934
|
-
* HPS (half-points) are commonly used for font sizes.
|
|
935
|
-
*
|
|
936
|
-
* Reference: ST_HpsMeasure in OOXML specification
|
|
937
|
-
*
|
|
938
|
-
* @param val - The measurement value (positive universal measure or number)
|
|
939
|
-
* @returns The normalized measurement value
|
|
940
|
-
*
|
|
941
|
-
* @example
|
|
942
|
-
* ```typescript
|
|
943
|
-
* const fontSize1 = hpsMeasureValue("12pt");
|
|
944
|
-
* const fontSize2 = hpsMeasureValue(24); // 12pt in half-points
|
|
945
|
-
* ```
|
|
946
|
-
*/
|
|
947
|
-
const hpsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
|
948
|
-
/**
|
|
949
|
-
* Validates a signed half-point (HPS) measurement value.
|
|
950
|
-
*
|
|
951
|
-
* Accepts either a universal measure string or a numeric value.
|
|
952
|
-
*
|
|
953
|
-
* Reference: ST_SignedHpsMeasure in OOXML specification
|
|
954
|
-
*
|
|
955
|
-
* @param val - The measurement value (universal measure or number)
|
|
956
|
-
* @returns The normalized measurement value
|
|
957
|
-
*
|
|
958
|
-
* @example
|
|
959
|
-
* ```typescript
|
|
960
|
-
* const spacing1 = signedHpsMeasureValue("6pt");
|
|
961
|
-
* const spacing2 = signedHpsMeasureValue(-12); // Negative spacing
|
|
962
|
-
* ```
|
|
963
|
-
*/
|
|
964
|
-
const signedHpsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
|
965
|
-
/**
|
|
966
|
-
* Validates a positive TWIP measurement value.
|
|
967
|
-
*
|
|
968
|
-
* Accepts either a positive universal measure string or a positive number.
|
|
969
|
-
*
|
|
970
|
-
* Reference: ST_TwipsMeasure in OOXML specification
|
|
971
|
-
*
|
|
972
|
-
* @param val - The measurement value (positive universal measure or number)
|
|
973
|
-
* @returns The normalized measurement value
|
|
974
|
-
*
|
|
975
|
-
* @example
|
|
976
|
-
* ```typescript
|
|
977
|
-
* const width1 = twipsMeasureValue("25.4mm");
|
|
978
|
-
* const width2 = twipsMeasureValue(1440); // 1 inch in TWIP
|
|
979
|
-
* ```
|
|
980
|
-
*/
|
|
981
|
-
const twipsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
|
982
|
-
/**
|
|
983
|
-
* Normalizes a percentage value by parsing and reformatting.
|
|
984
|
-
*
|
|
985
|
-
* Reference: ST_Percentage in OOXML specification
|
|
986
|
-
*
|
|
987
|
-
* @param val - The percentage string to normalize
|
|
988
|
-
* @returns The normalized percentage
|
|
989
|
-
*
|
|
990
|
-
* @example
|
|
991
|
-
* ```typescript
|
|
992
|
-
* const percent = percentageValue("50.000%"); // Returns "50%"
|
|
993
|
-
* ```
|
|
994
|
-
*/
|
|
995
|
-
const percentageValue = (val) => {
|
|
996
|
-
const percent = val.substring(0, val.length - 1);
|
|
997
|
-
return `${Number(percent)}%`;
|
|
998
|
-
};
|
|
999
|
-
/**
|
|
1000
|
-
* Validates a measurement value that can be expressed as a number, percentage, or universal measure.
|
|
1001
|
-
*
|
|
1002
|
-
* Reference: ST_MeasurementOrPercent in OOXML specification
|
|
1003
|
-
*
|
|
1004
|
-
* @param val - The measurement value (number, percentage, or universal measure)
|
|
1005
|
-
* @returns The normalized measurement value
|
|
1006
|
-
*
|
|
1007
|
-
* @example
|
|
1008
|
-
* ```typescript
|
|
1009
|
-
* const measure1 = measurementOrPercentValue(100); // Unqualified number
|
|
1010
|
-
* const measure2 = measurementOrPercentValue("50%"); // Percentage
|
|
1011
|
-
* const measure3 = measurementOrPercentValue("10mm"); // Universal measure
|
|
1012
|
-
* ```
|
|
1013
|
-
*/
|
|
1014
|
-
const measurementOrPercentValue = (val) => {
|
|
1015
|
-
if (typeof val === "number") return decimalNumber(val);
|
|
1016
|
-
if (val.slice(-1) === "%") return percentageValue(val);
|
|
1017
|
-
return universalMeasureValue(val);
|
|
1018
|
-
};
|
|
1019
|
-
/**
|
|
1020
|
-
* Validates an eighth-point measurement value.
|
|
1021
|
-
*
|
|
1022
|
-
* Eighth-points are used for fine-grained measurements in text formatting.
|
|
1023
|
-
*
|
|
1024
|
-
* Reference: ST_EighthPointMeasure in OOXML specification
|
|
1025
|
-
*
|
|
1026
|
-
* @param val - The measurement value in eighth-points
|
|
1027
|
-
* @returns The validated positive integer value
|
|
1028
|
-
*
|
|
1029
|
-
* @example
|
|
1030
|
-
* ```typescript
|
|
1031
|
-
* const measure = eighthPointMeasureValue(16); // 2 points
|
|
1032
|
-
* ```
|
|
1033
|
-
*/
|
|
1034
|
-
const eighthPointMeasureValue = unsignedDecimalNumber;
|
|
1035
|
-
/**
|
|
1036
|
-
* Validates a point measurement value.
|
|
1037
|
-
*
|
|
1038
|
-
* Reference: ST_PointMeasure in OOXML specification
|
|
1039
|
-
*
|
|
1040
|
-
* @param val - The measurement value in points
|
|
1041
|
-
* @returns The validated positive integer value
|
|
1042
|
-
*
|
|
1043
|
-
* @example
|
|
1044
|
-
* ```typescript
|
|
1045
|
-
* const fontSize = pointMeasureValue(12); // 12pt
|
|
1046
|
-
* ```
|
|
1047
|
-
*/
|
|
1048
|
-
const pointMeasureValue = unsignedDecimalNumber;
|
|
1049
|
-
/**
|
|
1050
|
-
* Converts a JavaScript Date object to an ISO 8601 date-time string.
|
|
1051
|
-
*
|
|
1052
|
-
* The format is CCYY-MM-DDThh:mm:ss.sssZ where T is a literal and Z indicates UTC.
|
|
1053
|
-
* This matches the xsd:dateTime format required by OOXML.
|
|
1054
|
-
*
|
|
1055
|
-
* Reference: ST_DateTime in OOXML specification
|
|
1056
|
-
*
|
|
1057
|
-
* @param val - The Date object to convert
|
|
1058
|
-
* @returns An ISO 8601 formatted date-time string
|
|
1059
|
-
*
|
|
1060
|
-
* @example
|
|
1061
|
-
* ```typescript
|
|
1062
|
-
* const now = new Date();
|
|
1063
|
-
* const timestamp = dateTimeValue(now); // Returns "2024-01-15T10:30:00.000Z"
|
|
1064
|
-
* ```
|
|
1065
|
-
*/
|
|
1066
|
-
const dateTimeValue = (val) => val.toISOString();
|
|
1067
|
-
/**
|
|
1068
|
-
* Theme color values used throughout OOXML for referencing document theme colors.
|
|
1069
|
-
*
|
|
1070
|
-
* Reference: ST_ThemeColor in OOXML specification
|
|
1071
|
-
*
|
|
1072
|
-
* @publicApi
|
|
1073
|
-
*/
|
|
1074
|
-
const ThemeColor = {
|
|
1075
|
-
DARK1: "dark1",
|
|
1076
|
-
LIGHT1: "light1",
|
|
1077
|
-
DARK2: "dark2",
|
|
1078
|
-
LIGHT2: "light2",
|
|
1079
|
-
ACCENT1: "accent1",
|
|
1080
|
-
ACCENT2: "accent2",
|
|
1081
|
-
ACCENT3: "accent3",
|
|
1082
|
-
ACCENT4: "accent4",
|
|
1083
|
-
ACCENT5: "accent5",
|
|
1084
|
-
ACCENT6: "accent6",
|
|
1085
|
-
HYPERLINK: "hyperlink",
|
|
1086
|
-
FOLLOWED_HYPERLINK: "followedHyperlink",
|
|
1087
|
-
NONE: "none",
|
|
1088
|
-
BACKGROUND1: "background1",
|
|
1089
|
-
TEXT1: "text1",
|
|
1090
|
-
BACKGROUND2: "background2",
|
|
1091
|
-
TEXT2: "text2"
|
|
1092
|
-
};
|
|
1093
|
-
/**
|
|
1094
|
-
* Theme font values used for referencing document theme fonts.
|
|
1095
|
-
*
|
|
1096
|
-
* Reference: ST_Theme in OOXML specification
|
|
1097
|
-
*
|
|
1098
|
-
* @publicApi
|
|
1099
|
-
*/
|
|
1100
|
-
const ThemeFont = {
|
|
1101
|
-
MAJOR_EAST_ASIA: "majorEastAsia",
|
|
1102
|
-
MAJOR_BIDI: "majorBidi",
|
|
1103
|
-
MAJOR_ASCII: "majorAscii",
|
|
1104
|
-
MAJOR_H_ANSI: "majorHAnsi",
|
|
1105
|
-
MINOR_EAST_ASIA: "minorEastAsia",
|
|
1106
|
-
MINOR_BIDI: "minorBidi",
|
|
1107
|
-
MINOR_ASCII: "minorAscii",
|
|
1108
|
-
MINOR_H_ANSI: "minorHAnsi"
|
|
1109
|
-
};
|
|
1110
|
-
//#endregion
|
|
1111
|
-
export { convertOutput as $, replaceChartPlaceholders as A, compileMapping as B, findAndReplaceImagePlaceholders as C, getVideoRefs as D, getReferencedMedia as E, replaceSmartArtPlaceholders as F, levelForMediaName as G, ZIP_STORED_LEVEL as H, replaceVideoPlaceholders as I, zipAndConvert as J, strFromU8$1 as K, derivePasswordHash as L, replaceImagePlaceholders as M, replaceMediaPlaceholders as N, hasPlaceholders as O, replaceNumberingPlaceholders as P, OoxmlMimeType as Q, hashPasswordAgile as R, collectPlaceholderKeys as S, getMediaRefs as T, createPacker as U, ZIP_DEFLATE_LEVEL as V, createZipStream as W, hasNativeInflate as X, zipSyncAndConvert as Y, nativeUnzip as Z, twipsMeasureValue as _, eighthPointMeasureValue as a, unsignedDecimalNumber as b, hpsMeasureValue as c, percentageValue as d, pointMeasureValue as f, signedTwipsMeasureValue as g, signedHpsMeasureValue as h, decimalNumber as i, replaceHyperlinkPlaceholders as j, replaceAllPlaceholders as k, longHexNumber as l, shortHexNumber as m, ThemeFont as n, hexBinary as o, positiveUniversalMeasureValue as p, unzipSync$1 as q, dateTimeValue as r, hexColorValue as s, ThemeColor as t, measurementOrPercentValue as u, uCharHexNumber as v, formatId as w, addSmartArtRelationships as x, universalMeasureValue as y, randomBytes as z };
|
|
889
|
+
export { ZIP_STORED_LEVEL as A, OoxmlMimeType as B, replaceVideoPlaceholders as C, addBinaryFile as D, randomBytes as E, strFromU8$1 as F, hasNativeInflate as H, unzipSync$1 as I, zipAndConvert as L, createPacker as M, createZipStream as N, compileMapping as O, levelForMediaName as P, zipSync$1 as R, replaceSmartArtPlaceholders as S, hashPasswordAgile as T, nativeCrc32 as U, convertOutput as V, nativeUnzip as W, replaceMediaPlaceholders as _, getAudioRefs as a, replaceOlePlaceholders as b, getReferencedMedia as c, replaceAllPlaceholders as d, replaceAudioPlaceholders as f, replaceImagePlaceholders as g, replaceImageLinkPlaceholders as h, formatId as i, ZipStreamWriter as j, ZIP_DEFLATE_LEVEL as k, getVideoRefs as l, replaceHyperlinkPlaceholders as m, collectPlaceholderKeys as n, getMediaRefs as o, replaceChartPlaceholders as p, findAndReplaceImagePlaceholders as r, getOleRefs as s, addSmartArtRelationships as t, hasPlaceholders as u, replaceNumberingPlaceholders as v, derivePasswordHash as w, replacePlaceholders as x, replaceOleLinkPlaceholders as y, zipSyncAndConvert as z };
|
|
1112
890
|
|
|
1113
|
-
//# sourceMappingURL=util-
|
|
891
|
+
//# sourceMappingURL=util-ptE16MEk.mjs.map
|