@office-open/core 0.3.0 → 0.3.2

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.
@@ -64,6 +64,11 @@ declare abstract class XmlComponent extends BaseXmlComponent {
64
64
  * Prepares this component and its children for XML serialization.
65
65
  */
66
66
  prepForXml(context: IContext): IXmlableObject | undefined;
67
+ /**
68
+ * Direct XML serialization. Override in subclasses for zero-allocation output.
69
+ * Default falls back to prepForXml() + xml().
70
+ */
71
+ toXml(context: IContext): string;
67
72
  /**
68
73
  * @deprecated Internal use only.
69
74
  */
@@ -217,7 +222,10 @@ declare const convertToXmlComponent: (element: Element) => ImportedXmlComponent
217
222
  * XML component representing imported XML content.
218
223
  */
219
224
  declare class ImportedXmlComponent extends XmlComponent {
225
+ protected _sourceXml?: string;
220
226
  static fromXmlString(importedContent: string): ImportedXmlComponent;
227
+ get sourceXml(): string | undefined;
228
+ toXml(_context: IContext): string;
221
229
  constructor(rootKey: string, _attr?: any);
222
230
  push(xmlComponent: XmlComponent | string): void;
223
231
  }
@@ -1,5 +1,5 @@
1
1
  import { hpsMeasureValue } from "../values.mjs";
2
- import { xml2js } from "@office-open/xml";
2
+ import { xml, xml2js } from "@office-open/xml";
3
3
  //#region src/xml-components/base.ts
4
4
  /**
5
5
  * Abstract base class for all XML components.
@@ -50,6 +50,14 @@ var XmlComponent = class extends BaseXmlComponent {
50
50
  return { [this.rootKey]: children.length ? children.length === 1 && children[0] && typeof children[0] === "object" && "_attr" in children[0] ? children[0] : children : EMPTY_OBJECT };
51
51
  }
52
52
  /**
53
+ * Direct XML serialization. Override in subclasses for zero-allocation output.
54
+ * Default falls back to prepForXml() + xml().
55
+ */
56
+ toXml(context) {
57
+ const obj = this.prepForXml(context);
58
+ return obj ? xml(obj) : "";
59
+ }
60
+ /**
53
61
  * @deprecated Internal use only.
54
62
  */
55
63
  addChildElement(child) {
@@ -320,9 +328,18 @@ var ImportedXmlComponentAttributes = class extends XmlAttributeComponent {};
320
328
  * XML component representing imported XML content.
321
329
  */
322
330
  var ImportedXmlComponent = class extends XmlComponent {
331
+ _sourceXml;
323
332
  static fromXmlString(importedContent) {
324
333
  const xmlObj = xml2js(importedContent, { compact: false });
325
- return convertToXmlComponent(xmlObj.elements?.[0] ?? xmlObj);
334
+ const component = convertToXmlComponent(xmlObj.elements?.[0] ?? xmlObj);
335
+ component._sourceXml = importedContent;
336
+ return component;
337
+ }
338
+ get sourceXml() {
339
+ return this._sourceXml;
340
+ }
341
+ toXml(_context) {
342
+ return this._sourceXml ?? super.toXml(_context);
326
343
  }
327
344
  constructor(rootKey, _attr) {
328
345
  super(rootKey);
@@ -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 };
@@ -1,4 +1,4 @@
1
- import { O as XmlComponent } from "../_chunks/index-3uVYzs32.mjs";
1
+ import { O as XmlComponent } from "../_chunks/index-BV1I7g5r.mjs";
2
2
 
3
3
  //#region src/chart/chart-collection.d.ts
4
4
  interface IChartData {
@@ -69,7 +69,7 @@ interface IChartTypeOptions {
69
69
  readonly series: readonly IChartSeriesData[];
70
70
  readonly categories: readonly string[];
71
71
  }
72
- declare const createChartType: (options: IChartTypeOptions) => BarChart | LineChart | PieChart | AreaChart | ScatterChart;
72
+ declare const createChartType: (options: IChartTypeOptions) => ScatterChart | BarChart | LineChart | PieChart | AreaChart;
73
73
  //#endregion
74
74
  //#region src/chart/series/series-data.d.ts
75
75
  declare const createStrRef: (values: string | readonly string[]) => XmlComponent;
@@ -1,4 +1,4 @@
1
- import { T as XmlComponent, b as wrapEl, o as EmptyElement, p as chartAttr } from "../_chunks/xml-components-DazgCiyL.mjs";
1
+ import { T as XmlComponent, b as wrapEl, o as EmptyElement, p as chartAttr } from "../_chunks/xml-components-CN6syVNr.mjs";
2
2
  //#region src/chart/chart-collection.ts
3
3
  var ChartCollection = class {
4
4
  map;
@@ -1,4 +1,4 @@
1
- import { O as XmlComponent, T as XmlAttributeComponent, a as BuilderElement } from "../_chunks/index-3uVYzs32.mjs";
1
+ import { O as XmlComponent, T as XmlAttributeComponent, a as BuilderElement } from "../_chunks/index-BV1I7g5r.mjs";
2
2
 
3
3
  //#region src/drawingml/color/color-transform.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as XmlAttributeComponent, T as XmlComponent, a as BuilderElement } from "../_chunks/xml-components-DazgCiyL.mjs";
1
+ import { S as XmlAttributeComponent, T as XmlComponent, a as BuilderElement } from "../_chunks/xml-components-CN6syVNr.mjs";
2
2
  import { d as convertPixelsToEmu, t as hashedId } from "../_chunks/id-generators-Ch07cHW1.mjs";
3
3
  //#region src/drawingml/color/color-transform.ts
4
4
  /**
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";
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";
1
+ import { Relationship, elementToXml, findRel, findRelsByType, getImageType, listFiles, parseRels, readAllXmlParts, readBinaryFromZip, readTextFromZip, readXmlFromZip, uint8ToBase64, unzipToMap, zipToBuffer } from "./archive.mjs";
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-BV1I7g5r.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
  /**
@@ -107,6 +108,7 @@ declare class Relationships extends BaseXmlComponent {
107
108
  */
108
109
  declare class Formatter {
109
110
  format<T extends IContext = IContext>(input: BaseXmlComponent, context?: T): IXmlableObject;
111
+ formatToXml(input: XmlComponent, context: IContext, declaration?: boolean): string;
110
112
  }
111
113
  //#endregion
112
114
  //#region src/core-properties.d.ts
@@ -123,4 +125,57 @@ interface CoreProperties {
123
125
  }
124
126
  declare function parseCoreProperties(zip: Map<string, Uint8Array>): CoreProperties;
125
127
  //#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 };
128
+ //#region src/parser.d.ts
129
+ /**
130
+ * Wrapper for unknown/unhandled XML elements in parsed output.
131
+ * Enables lossless round-trip: unknown elements are preserved as Element trees
132
+ * and can be serialized back via js2xml() during reconstruction.
133
+ */
134
+ interface RawElement {
135
+ $raw: true;
136
+ element: Element;
137
+ }
138
+ /** Type guard for RawElement */
139
+ declare function isRaw(el: unknown): el is RawElement;
140
+ /**
141
+ * Mixed content array: typed children interleaved with unknown raw elements,
142
+ * preserving original document order for lossless round-trip.
143
+ */
144
+ type MixedChildren<T> = Array<T | RawElement>;
145
+ //#endregion
146
+ //#region src/raw-passthrough.d.ts
147
+ /**
148
+ * Thin wrapper that passes a raw Element tree through the XML serialization pipeline.
149
+ * Used to include parsed-but-unrecognized XML in generated documents.
150
+ */
151
+ declare class RawPassthrough extends BaseXmlComponent {
152
+ private readonly element;
153
+ constructor(element: Element);
154
+ prepForXml(_context: IContext): IXmlableObject;
155
+ }
156
+ //#endregion
157
+ //#region src/placeholder.d.ts
158
+ /**
159
+ * Placeholder detection utilities for compiler post-processing optimization.
160
+ *
161
+ * Both DOCX and PPTX compilers use placeholder tokens (e.g. `{chart:key}`)
162
+ * in XML strings to defer relationship ID assignment. This module provides
163
+ * fast pre-check utilities to avoid unnecessary regex scans when no placeholders exist.
164
+ */
165
+ /**
166
+ * Check if an XML string contains any placeholder tokens.
167
+ * Uses a simple `{` character check which is O(n) but much cheaper
168
+ * than running multiple regex scans.
169
+ */
170
+ declare function hasPlaceholders(xml: string): boolean;
171
+ /**
172
+ * Collect all unique placeholder keys with a given prefix from an XML string.
173
+ * Single-pass scan using indexOf, avoiding RegExp overhead.
174
+ *
175
+ * @param xml - The XML string to scan
176
+ * @param prefix - The placeholder prefix (e.g. "chart:", "smartart:", "hlink:")
177
+ * @returns Array of unique keys found after the prefix
178
+ */
179
+ declare function collectPlaceholderKeys(xml: string, prefix: string): string[];
180
+ //#endregion
181
+ 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, collectPlaceholderKeys, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, elementToXml, findRel, findRelsByType, getImageType, hasPlaceholders, 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
@@ -1,8 +1,8 @@
1
- import { C as EMPTY_OBJECT, E as BaseXmlComponent, S as XmlAttributeComponent, T as XmlComponent, _ 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, 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 IgnoreIfEmptyXmlComponent, x as NextAttributeComponent, y as stringValObj } from "./_chunks/xml-components-DazgCiyL.mjs";
1
+ import { C as EMPTY_OBJECT, E as BaseXmlComponent, S as XmlAttributeComponent, T as XmlComponent, _ 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, 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 IgnoreIfEmptyXmlComponent, x as NextAttributeComponent, y as stringValObj } from "./_chunks/xml-components-CN6syVNr.mjs";
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 {
@@ -57,6 +57,7 @@ var Relationships = class extends BaseXmlComponent {
57
57
  };
58
58
  //#endregion
59
59
  //#region src/formatter.ts
60
+ const XML_DECL = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
60
61
  /**
61
62
  * Converts an XmlComponent tree into a serializable XML object.
62
63
  */
@@ -66,6 +67,10 @@ var Formatter = class {
66
67
  if (output) return output;
67
68
  throw new Error("XMLComponent did not format correctly");
68
69
  }
70
+ formatToXml(input, context, declaration) {
71
+ const str = input.toXml(context);
72
+ return declaration ? XML_DECL + str : str;
73
+ }
69
74
  };
70
75
  //#endregion
71
76
  //#region src/core-properties.ts
@@ -115,4 +120,85 @@ function parseCoreProperties(zip) {
115
120
  return props;
116
121
  }
117
122
  //#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 };
123
+ //#region src/parser.ts
124
+ /** Type guard for RawElement */
125
+ function isRaw(el) {
126
+ return typeof el === "object" && el !== null && el.$raw === true;
127
+ }
128
+ //#endregion
129
+ //#region src/raw-passthrough.ts
130
+ /**
131
+ * Convert an Element tree to xml-js compact format (IXmlableObject).
132
+ * Always wraps in a named key so the element name is preserved even for empty elements.
133
+ */
134
+ function elementToCompact(el) {
135
+ const inner = {};
136
+ if (el.attributes && Object.keys(el.attributes).length > 0) inner._attributes = el.attributes;
137
+ if (el.cdata) inner._cdata = el.cdata;
138
+ else if (el.text != null) inner._text = el.text;
139
+ if (el.elements) for (const child of el.elements) {
140
+ const key = child.name ?? "_unknown";
141
+ const compactChild = elementToCompact(child);
142
+ if (inner[key]) {
143
+ if (!Array.isArray(inner[key])) inner[key] = [inner[key]];
144
+ inner[key].push(compactChild);
145
+ } else inner[key] = compactChild;
146
+ }
147
+ const name = el.name ?? "unknown";
148
+ if (Object.keys(inner).length === 0) return { [name]: {} };
149
+ return { [name]: inner };
150
+ }
151
+ /**
152
+ * Thin wrapper that passes a raw Element tree through the XML serialization pipeline.
153
+ * Used to include parsed-but-unrecognized XML in generated documents.
154
+ */
155
+ var RawPassthrough = class extends BaseXmlComponent {
156
+ constructor(element) {
157
+ super(element.name ?? "unknown");
158
+ this.element = element;
159
+ }
160
+ prepForXml(_context) {
161
+ return elementToCompact(this.element);
162
+ }
163
+ };
164
+ //#endregion
165
+ //#region src/placeholder.ts
166
+ /**
167
+ * Placeholder detection utilities for compiler post-processing optimization.
168
+ *
169
+ * Both DOCX and PPTX compilers use placeholder tokens (e.g. `{chart:key}`)
170
+ * in XML strings to defer relationship ID assignment. This module provides
171
+ * fast pre-check utilities to avoid unnecessary regex scans when no placeholders exist.
172
+ */
173
+ /**
174
+ * Check if an XML string contains any placeholder tokens.
175
+ * Uses a simple `{` character check which is O(n) but much cheaper
176
+ * than running multiple regex scans.
177
+ */
178
+ function hasPlaceholders(xml) {
179
+ return xml.includes("{");
180
+ }
181
+ /**
182
+ * Collect all unique placeholder keys with a given prefix from an XML string.
183
+ * Single-pass scan using indexOf, avoiding RegExp overhead.
184
+ *
185
+ * @param xml - The XML string to scan
186
+ * @param prefix - The placeholder prefix (e.g. "chart:", "smartart:", "hlink:")
187
+ * @returns Array of unique keys found after the prefix
188
+ */
189
+ function collectPlaceholderKeys(xml, prefix) {
190
+ const keys = [];
191
+ const search = `{${prefix}`;
192
+ let pos = 0;
193
+ while ((pos = xml.indexOf(search, pos)) !== -1) {
194
+ const keyStart = pos + search.length;
195
+ const keyEnd = xml.indexOf("}", keyStart);
196
+ if (keyEnd === -1) break;
197
+ const key = xml.substring(keyStart, keyEnd);
198
+ if (key.length > 0 && !keys.includes(key)) keys.push(key);
199
+ pos = keyEnd + 1;
200
+ }
201
+ return keys;
202
+ }
203
+ //#endregion
204
+ 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, collectPlaceholderKeys, convertEmuToInches, convertEmuToPixels, convertEmuToPoints, convertInchesToEmu, convertInchesToTwip, convertMillimetersToTwip, convertPixelsToEmu, convertPointsToEmu, convertToXmlComponent, createDataModel, dateTimeValue, decimalNumber, eighthPointMeasureValue, elementToXml, findRel, findRelsByType, getImageType, hasPlaceholders, 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 };
@@ -1,4 +1,4 @@
1
- import { O as XmlComponent } from "../_chunks/index-3uVYzs32.mjs";
1
+ import { O as XmlComponent } from "../_chunks/index-BV1I7g5r.mjs";
2
2
 
3
3
  //#region src/smartart/categories.d.ts
4
4
  /** Layout ID → OOXML category type */
@@ -1,4 +1,4 @@
1
- import { T as XmlComponent, p as chartAttr } from "../_chunks/xml-components-DazgCiyL.mjs";
1
+ import { T as XmlComponent, p as chartAttr } from "../_chunks/xml-components-CN6syVNr.mjs";
2
2
  //#region src/smartart/categories.ts
3
3
  /** Layout ID → OOXML category type */
4
4
  const LAYOUT_CATEGORIES = {
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.2",
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.2"
63
63
  },
64
64
  "scripts": {
65
65
  "dev": "basis build --stub",