@office-open/core 0.3.0 → 0.3.1

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.
@@ -17,6 +17,13 @@ declare function readXmlFromZip(zip: Map<string, Uint8Array>, path: string): Ele
17
17
  * Read a binary file from the zip.
18
18
  */
19
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>;
20
27
  /**
21
28
  * List all files in the zip matching a prefix.
22
29
  */
@@ -38,5 +45,14 @@ interface Relationship {
38
45
  declare function parseRels(zip: Map<string, Uint8Array>, path: string): Relationship[];
39
46
  declare function findRel(rels: Relationship[], id: string): Relationship | undefined;
40
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;
41
57
  //#endregion
42
- export { Relationship, findRel, findRelsByType, getImageType, listFiles, parseRels, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap };
58
+ export { Relationship, elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer };
package/dist/archive.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { attr, xml2js } from "@office-open/xml";
2
- import { strFromU8, unzipSync } from "fflate";
1
+ import { attr, js2xml, xml2js } from "@office-open/xml";
2
+ import { strFromU8, strToU8, unzipSync, zipSync } from "fflate";
3
3
  //#region src/archive.ts
4
4
  const XML_PARSE_OPTIONS = {
5
5
  nativeTypeAttributes: true,
@@ -37,6 +37,21 @@ function readBinaryFromZip(zip, path) {
37
37
  return zip.get(path);
38
38
  }
39
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
+ /**
40
55
  * List all files in the zip matching a prefix.
41
56
  */
42
57
  function listFiles(zip, prefix) {
@@ -48,8 +63,12 @@ function listFiles(zip, prefix) {
48
63
  * Convert Uint8Array to base64 string.
49
64
  */
50
65
  function uint8ToBase64(data) {
66
+ const chunkSize = 8192;
51
67
  let binary = "";
52
- for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]);
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
+ }
53
72
  return btoa(binary);
54
73
  }
55
74
  /**
@@ -97,5 +116,20 @@ function findRel(rels, id) {
97
116
  function findRelsByType(rels, typeSubstring) {
98
117
  return rels.filter((r) => r.type.includes(typeSubstring));
99
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
+ }
100
134
  //#endregion
101
- export { findRel, findRelsByType, getImageType, listFiles, parseRels, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap };
135
+ export { elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,8 @@
1
- import { Relationship, findRel, findRelsByType, getImageType, listFiles, parseRels, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap } from "./archive.mjs";
1
+ import { Relationship, elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer } from "./archive.mjs";
2
2
  import { A as IContext, C as AttributePayload, D as IgnoreIfEmptyXmlComponent, E as EMPTY_OBJECT, M as IXmlableObject, O as XmlComponent, S as AttributeMap, T as XmlAttributeComponent, _ as stringContainerObj, a as BuilderElement, b as wrapEl, c as NumberValueElement, d as StringEnumValueElement, f as StringValueElement, g as onOffObj, h as numberValObj, i as convertToXmlComponent, j as IXmlAttribute, k as BaseXmlComponent, l as OnOffElement, m as hpsMeasureObj, n as ImportedRootElementAttributes, o as EmptyElement, p as chartAttr, r as ImportedXmlComponent, s as HpsMeasureElement, t as InitializableXmlComponent, u as StringContainer, v as stringEnumValObj, w as NextAttributeComponent, x as AttributeData, y as stringValObj } from "./_chunks/index-3uVYzs32.mjs";
3
3
  import { C as universalMeasureValue, S as uCharHexNumber, _ as positiveUniversalMeasureValue, a as ThemeColor, b as signedTwipsMeasureValue, c as dateTimeValue, d as hexColorValue, f as hpsMeasureValue, g as pointMeasureValue, h as percentageValue, i as RelativeMeasure, l as decimalNumber, m as measurementOrPercentValue, n as PositivePercentage, o as ThemeFont, p as longHexNumber, r as PositiveUniversalMeasure, s as UniversalMeasure, t as Percentage, u as eighthPointMeasureValue, v as shortHexNumber, w as unsignedDecimalNumber, x as twipsMeasureValue, y as signedHpsMeasureValue } from "./_chunks/values-BrGywpRh.mjs";
4
4
  import { COLOR_CATEGORIES, Connection, DataModel, ISmartArtData, ITreeNode, LAYOUT_CATEGORIES, Point, STYLE_CATEGORIES, SmartArtCollection, TransPoint, createDataModel } from "./smartart/index.mjs";
5
+ import { Element } from "@office-open/xml";
5
6
 
6
7
  //#region src/converters.d.ts
7
8
  /**
@@ -123,4 +124,33 @@ interface CoreProperties {
123
124
  }
124
125
  declare function parseCoreProperties(zip: Map<string, Uint8Array>): CoreProperties;
125
126
  //#endregion
126
- export { AppProperties, AttributeData, AttributeMap, AttributePayload, BaseXmlComponent, BuilderElement, COLOR_CATEGORIES, Connection, CoreProperties, DataModel, EMPTY_OBJECT, EmptyElement, Formatter, HpsMeasureElement, IContext, ISmartArtData, ITreeNode, IXmlAttribute, IXmlableObject, IgnoreIfEmptyXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, LAYOUT_CATEGORIES, NextAttributeComponent, NumberValueElement, OnOffElement, OutputByType, OutputType, Percentage, Point, PositivePercentage, PositiveUniversalMeasure, Relationship, type RelationshipType, Relationships, RelativeMeasure, STYLE_CATEGORIES, SmartArtCollection, StringContainer, StringEnumValueElement, StringValueElement, TargetModeType, ThemeColor, ThemeFont, TransPoint, UniqueNumericIdCreator, UniversalMeasure, XmlAttributeComponent, XmlComponent, chartAttr, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, findRel, findRelsByType, getImageType, hashedId, hexColorValue, hpsMeasureObj, hpsMeasureValue, listFiles, longHexNumber, measurementOrPercentValue, numberValObj, onOffObj, parseCoreProperties, parseRels, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, readBinaryFromZip, readTextFromZip, readXmlFromZip, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, stringContainerObj, stringEnumValObj, stringValObj, twipsMeasureValue, uCharHexNumber, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureValue, unsignedDecimalNumber, unzipToMap, wrapEl };
127
+ //#region src/parser.d.ts
128
+ /**
129
+ * Wrapper for unknown/unhandled XML elements in parsed output.
130
+ * Enables lossless round-trip: unknown elements are preserved as Element trees
131
+ * and can be serialized back via js2xml() during reconstruction.
132
+ */
133
+ interface RawElement {
134
+ $raw: true;
135
+ element: Element;
136
+ }
137
+ /** Type guard for RawElement */
138
+ declare function isRaw(el: unknown): el is RawElement;
139
+ /**
140
+ * Mixed content array: typed children interleaved with unknown raw elements,
141
+ * preserving original document order for lossless round-trip.
142
+ */
143
+ type MixedChildren<T> = Array<T | RawElement>;
144
+ //#endregion
145
+ //#region src/raw-passthrough.d.ts
146
+ /**
147
+ * Thin wrapper that passes a raw Element tree through the XML serialization pipeline.
148
+ * Used to include parsed-but-unrecognized XML in generated documents.
149
+ */
150
+ declare class RawPassthrough extends BaseXmlComponent {
151
+ private readonly element;
152
+ constructor(element: Element);
153
+ prepForXml(_context: IContext): IXmlableObject;
154
+ }
155
+ //#endregion
156
+ export { AppProperties, AttributeData, AttributeMap, AttributePayload, BaseXmlComponent, BuilderElement, COLOR_CATEGORIES, Connection, CoreProperties, DataModel, EMPTY_OBJECT, EmptyElement, Formatter, HpsMeasureElement, IContext, ISmartArtData, ITreeNode, IXmlAttribute, IXmlableObject, IgnoreIfEmptyXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, LAYOUT_CATEGORIES, MixedChildren, NextAttributeComponent, NumberValueElement, OnOffElement, OutputByType, OutputType, Percentage, Point, PositivePercentage, PositiveUniversalMeasure, RawElement, RawPassthrough, Relationship, type RelationshipType, Relationships, RelativeMeasure, STYLE_CATEGORIES, SmartArtCollection, StringContainer, StringEnumValueElement, StringValueElement, TargetModeType, ThemeColor, ThemeFont, TransPoint, UniqueNumericIdCreator, UniversalMeasure, XmlAttributeComponent, XmlComponent, chartAttr, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, elementToXml, findRel, findRelsByType, getImageType, hashedId, hexColorValue, hpsMeasureObj, hpsMeasureValue, isRaw, listFiles, longHexNumber, measurementOrPercentValue, numberValObj, onOffObj, parseCoreProperties, parseRels, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, stringContainerObj, stringEnumValObj, stringValObj, twipsMeasureValue, uCharHexNumber, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureValue, unsignedDecimalNumber, unzipToMap, wrapEl, zipToBuffer };
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { C as EMPTY_OBJECT, E as BaseXmlComponent, S as XmlAttributeComponent, T
2
2
  import { ThemeColor, ThemeFont, dateTimeValue, decimalNumber, eighthPointMeasureValue, hexColorValue, hpsMeasureValue, longHexNumber, measurementOrPercentValue, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, twipsMeasureValue, uCharHexNumber, universalMeasureValue, unsignedDecimalNumber } from "./values.mjs";
3
3
  import { a as convertEmuToInches, c as convertInchesToEmu, d as convertPixelsToEmu, f as convertPointsToEmu, i as uniqueUuid, l as convertInchesToTwip, n as uniqueId, o as convertEmuToPixels, r as uniqueNumericIdCreator, s as convertEmuToPoints, t as hashedId, u as convertMillimetersToTwip } from "./_chunks/id-generators-Ch07cHW1.mjs";
4
4
  import { COLOR_CATEGORIES, Connection, DataModel, LAYOUT_CATEGORIES, Point, STYLE_CATEGORIES, SmartArtCollection, TransPoint, createDataModel } from "./smartart/index.mjs";
5
- import { findRel, findRelsByType, getImageType, listFiles, parseRels, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap } from "./archive.mjs";
5
+ import { elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer } from "./archive.mjs";
6
6
  import { textOf } from "@office-open/xml";
7
7
  //#region src/opc/app-properties.ts
8
8
  var AppPropertiesAttributes = class extends XmlAttributeComponent {
@@ -115,4 +115,46 @@ function parseCoreProperties(zip) {
115
115
  return props;
116
116
  }
117
117
  //#endregion
118
- export { AppProperties, BaseXmlComponent, BuilderElement, COLOR_CATEGORIES, Connection, DataModel, EMPTY_OBJECT, EmptyElement, Formatter, HpsMeasureElement, IgnoreIfEmptyXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, LAYOUT_CATEGORIES, NextAttributeComponent, NumberValueElement, OnOffElement, Point, Relationships, STYLE_CATEGORIES, SmartArtCollection, StringContainer, StringEnumValueElement, StringValueElement, TargetModeType, ThemeColor, ThemeFont, TransPoint, XmlAttributeComponent, XmlComponent, chartAttr, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, findRel, findRelsByType, getImageType, hashedId, hexColorValue, hpsMeasureObj, hpsMeasureValue, listFiles, longHexNumber, measurementOrPercentValue, numberValObj, onOffObj, parseCoreProperties, parseRels, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, readBinaryFromZip, readTextFromZip, readXmlFromZip, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, stringContainerObj, stringEnumValObj, stringValObj, twipsMeasureValue, uCharHexNumber, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureValue, unsignedDecimalNumber, unzipToMap, wrapEl };
118
+ //#region src/parser.ts
119
+ /** Type guard for RawElement */
120
+ function isRaw(el) {
121
+ return typeof el === "object" && el !== null && el.$raw === true;
122
+ }
123
+ //#endregion
124
+ //#region src/raw-passthrough.ts
125
+ /**
126
+ * Convert an Element tree to xml-js compact format (IXmlableObject).
127
+ * Always wraps in a named key so the element name is preserved even for empty elements.
128
+ */
129
+ function elementToCompact(el) {
130
+ const inner = {};
131
+ if (el.attributes && Object.keys(el.attributes).length > 0) inner._attributes = el.attributes;
132
+ if (el.cdata) inner._cdata = el.cdata;
133
+ else if (el.text != null) inner._text = el.text;
134
+ if (el.elements) for (const child of el.elements) {
135
+ const key = child.name ?? "_unknown";
136
+ const compactChild = elementToCompact(child);
137
+ if (inner[key]) {
138
+ if (!Array.isArray(inner[key])) inner[key] = [inner[key]];
139
+ inner[key].push(compactChild);
140
+ } else inner[key] = compactChild;
141
+ }
142
+ const name = el.name ?? "unknown";
143
+ if (Object.keys(inner).length === 0) return { [name]: {} };
144
+ return { [name]: inner };
145
+ }
146
+ /**
147
+ * Thin wrapper that passes a raw Element tree through the XML serialization pipeline.
148
+ * Used to include parsed-but-unrecognized XML in generated documents.
149
+ */
150
+ var RawPassthrough = class extends BaseXmlComponent {
151
+ constructor(element) {
152
+ super(element.name ?? "unknown");
153
+ this.element = element;
154
+ }
155
+ prepForXml(_context) {
156
+ return elementToCompact(this.element);
157
+ }
158
+ };
159
+ //#endregion
160
+ export { AppProperties, BaseXmlComponent, BuilderElement, COLOR_CATEGORIES, Connection, DataModel, EMPTY_OBJECT, EmptyElement, Formatter, HpsMeasureElement, IgnoreIfEmptyXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent, InitializableXmlComponent, LAYOUT_CATEGORIES, NextAttributeComponent, NumberValueElement, OnOffElement, Point, RawPassthrough, Relationships, STYLE_CATEGORIES, SmartArtCollection, StringContainer, StringEnumValueElement, StringValueElement, TargetModeType, ThemeColor, ThemeFont, TransPoint, XmlAttributeComponent, XmlComponent, chartAttr, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, elementToXml, findRel, findRelsByType, getImageType, hashedId, hexColorValue, hpsMeasureObj, hpsMeasureValue, isRaw, listFiles, longHexNumber, measurementOrPercentValue, numberValObj, onOffObj, parseCoreProperties, parseRels, percentageValue, pointMeasureValue, positiveUniversalMeasureValue, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, shortHexNumber, signedHpsMeasureValue, signedTwipsMeasureValue, stringContainerObj, stringEnumValObj, stringValObj, twipsMeasureValue, uCharHexNumber, uint8ToBase64, uniqueId, uniqueNumericIdCreator, uniqueUuid, universalMeasureValue, unsignedDecimalNumber, unzipToMap, wrapEl, zipToBuffer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@office-open/core",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Shared OOXML infrastructure: XmlComponent, value validators, unit converters",
5
5
  "keywords": [
6
6
  "core",
@@ -59,7 +59,7 @@
59
59
  "fflate": "0.8.2",
60
60
  "hash.js": "1.1.7",
61
61
  "nanoid": "5.1.9",
62
- "@office-open/xml": "0.3.0"
62
+ "@office-open/xml": "0.3.1"
63
63
  },
64
64
  "scripts": {
65
65
  "dev": "basis build --stub",