ooxml.js 2.15.0 → 2.16.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 CHANGED
@@ -241,7 +241,7 @@ The package layers a lossless core outward to lossy convenience views:
241
241
 
242
242
  ## Gotchas and quirks
243
243
 
244
- - **`readDocx`/`readPptx` are not a round-trip path.** Numbering definitions, cell border styling/shading, and `w:themeColor` (without `themeShade`/`themeTint`) are read; images read into `ContentImageBlock` (floating `wp:anchor` position not recorded); `PAGE`/`NUMPAGES` fields resolve to Word's cached text. On pptx: connector shapes (`p:cxnSp`) are skipped; shape rotation composes through groups; a chart graphic frame reads its chart part's cached series/category model into a table block (header row = series names, one row per category index); a SmartArt graphic frame reads its diagram data model's node text as paragraphs in diagram order (depth-first over `parOf` connections, siblings by `srcOrd`); OLE graphic frames come through with geometry but empty content.
244
+ - **`readDocx`/`readPptx` are not a round-trip path.** Numbering definitions, cell border styling/shading, and `w:themeColor` (without `themeShade`/`themeTint`) are read; images read into `ContentImageBlock` (floating `wp:anchor` position not recorded); `PAGE`/`NUMPAGES` fields resolve to Word's cached text. On pptx: connector shapes (`p:cxnSp`) are skipped; shape rotation composes through groups; a chart graphic frame reads its chart part's cached series/category model into a table block (header row = series names, one row per category index); a SmartArt graphic frame reads its diagram data model's node text as paragraphs in diagram order (depth-first over `parOf` connections, siblings by `srcOrd`); an OLE graphic frame reads the fallback picture its `mc:Fallback` carries (or, with none reachable, a paragraph naming the `p:oleObj`'s `progId`) — the embedded payload itself is an external application's data and is not decoded.
245
245
  - **xlsx has no native percentage/currency/date/time cell type.** Both directions are closed via the number-format engine: reading classifies style → format code → kind; writing emits interned `numFmt` codes, fed back through the classifier in tests. `displayText` is the typed-value spelling, not the producer's rendered string.
246
246
  - **`test:smoke` depends on a fresh build.** It runs `tsdown && vitest run --project smoke`, always rebuilding `dist/` first. A bare `vitest` runs both projects; `smoke` fails loudly (`Cannot find module '../dist/index.js'`) if `dist/` is unbuilt.
247
247
  - **Binary-vs-XML part classification is a byte sniff, not an extension check.** `looksLikeXml` looks for a leading `<` after skipping a UTF-8 BOM and whitespace; any future binary format starting with `<` would misclassify.
@@ -20,6 +20,7 @@ const PRESENTATION_PATH = "ppt/presentation.xml";
20
20
  const TABLE_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
21
21
  const CHART_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
22
22
  const DIAGRAM_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
23
+ const OLE_GRAPHIC_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
23
24
  function readSlideSize(presentationRoot) {
24
25
  const sldSz = presentationRoot === void 0 ? void 0 : require_typed_util.childrenWithTag(presentationRoot, "p:sldSz")[0];
25
26
  const cx = sldSz === void 0 ? void 0 : require_typed_util.attr(sldSz, "cx");
@@ -195,29 +196,26 @@ function readSpShape(sp, context, slideRels, parentTransform) {
195
196
  blocks
196
197
  };
197
198
  }
198
- function readPicShape(pic, context, slideRels, pkg, parentTransform) {
199
- const resolved = resolveShapeFrame(pic, context, parentTransform);
200
- if (resolved === void 0) return;
201
- const blipFill = require_typed_util.childrenWithTag(pic, "p:blipFill")[0];
202
- const blip = blipFill === void 0 ? void 0 : require_typed_util.childrenWithTag(blipFill, "a:blip")[0];
199
+ function readBlipImage(parent, slideRels, pkg, frame) {
200
+ const blip = require_typed_util.elementsWithTag([parent], "a:blip")[0];
203
201
  const rId = blip === void 0 ? void 0 : require_typed_util.attr(blip, "r:embed");
204
202
  const rel = rId === void 0 ? void 0 : slideRels.get(rId);
205
203
  const mediaPart = rel === void 0 ? void 0 : pkg.parts[rel.target];
206
- const blocks = [];
207
- if (mediaPart?.kind === "binary") {
208
- const bytes = require_util_base64.base64ToBytes(mediaPart.base64);
209
- const format = require_image_sniff.sniffImageFormat(bytes);
210
- if (format !== void 0) {
211
- const image = {
212
- kind: "image",
213
- format,
214
- base64: mediaPart.base64,
215
- widthPt: resolved.frame.widthPt,
216
- heightPt: resolved.frame.heightPt
217
- };
218
- blocks.push(image);
219
- }
220
- }
204
+ if (mediaPart?.kind !== "binary") return;
205
+ const format = require_image_sniff.sniffImageFormat(require_util_base64.base64ToBytes(mediaPart.base64));
206
+ return format === void 0 ? void 0 : {
207
+ kind: "image",
208
+ format,
209
+ base64: mediaPart.base64,
210
+ widthPt: frame.widthPt,
211
+ heightPt: frame.heightPt
212
+ };
213
+ }
214
+ function readPicShape(pic, context, slideRels, pkg, parentTransform) {
215
+ const resolved = resolveShapeFrame(pic, context, parentTransform);
216
+ if (resolved === void 0) return;
217
+ const image = readBlipImage(pic, slideRels, pkg, resolved.frame);
218
+ const blocks = image === void 0 ? [] : [image];
221
219
  return {
222
220
  name: shapeName(pic),
223
221
  frame: resolved.frame,
@@ -290,6 +288,17 @@ function readGraphicFrameShape(gf, context, slideRels, pkg, parentTransform) {
290
288
  const relIds = require_typed_util.childrenWithTag(graphicData, "dgm:relIds")[0];
291
289
  const dataModelRoot = relatedPartRoot(relIds === void 0 ? void 0 : require_typed_util.attr(relIds, "r:dm"), slideRels, pkg);
292
290
  blocks = dataModelRoot === void 0 ? [] : require_typed_pptx_diagram.readDiagramText(dataModelRoot);
291
+ } else if (uri === OLE_GRAPHIC_URI && graphicData !== void 0) {
292
+ const image = readBlipImage(graphicData, slideRels, pkg, frame);
293
+ if (image !== void 0) blocks = [image];
294
+ else {
295
+ const oleObj = require_typed_util.elementsWithTag([graphicData], "p:oleObj")[0];
296
+ const progId = oleObj === void 0 ? void 0 : require_typed_util.attr(oleObj, "progId");
297
+ blocks = progId === void 0 ? [] : [{
298
+ kind: "paragraph",
299
+ runs: [{ text: progId }]
300
+ }];
301
+ }
293
302
  } else blocks = [];
294
303
  return {
295
304
  name: shapeName(gf),
@@ -19,6 +19,7 @@ const PRESENTATION_PATH = "ppt/presentation.xml";
19
19
  const TABLE_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/table";
20
20
  const CHART_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
21
21
  const DIAGRAM_GRAPHIC_URI = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
22
+ const OLE_GRAPHIC_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
22
23
  function readSlideSize(presentationRoot) {
23
24
  const sldSz = presentationRoot === void 0 ? void 0 : childrenWithTag(presentationRoot, "p:sldSz")[0];
24
25
  const cx = sldSz === void 0 ? void 0 : attr(sldSz, "cx");
@@ -194,29 +195,26 @@ function readSpShape(sp, context, slideRels, parentTransform) {
194
195
  blocks
195
196
  };
196
197
  }
197
- function readPicShape(pic, context, slideRels, pkg, parentTransform) {
198
- const resolved = resolveShapeFrame(pic, context, parentTransform);
199
- if (resolved === void 0) return;
200
- const blipFill = childrenWithTag(pic, "p:blipFill")[0];
201
- const blip = blipFill === void 0 ? void 0 : childrenWithTag(blipFill, "a:blip")[0];
198
+ function readBlipImage(parent, slideRels, pkg, frame) {
199
+ const blip = elementsWithTag([parent], "a:blip")[0];
202
200
  const rId = blip === void 0 ? void 0 : attr(blip, "r:embed");
203
201
  const rel = rId === void 0 ? void 0 : slideRels.get(rId);
204
202
  const mediaPart = rel === void 0 ? void 0 : pkg.parts[rel.target];
205
- const blocks = [];
206
- if (mediaPart?.kind === "binary") {
207
- const bytes = base64ToBytes(mediaPart.base64);
208
- const format = sniffImageFormat(bytes);
209
- if (format !== void 0) {
210
- const image = {
211
- kind: "image",
212
- format,
213
- base64: mediaPart.base64,
214
- widthPt: resolved.frame.widthPt,
215
- heightPt: resolved.frame.heightPt
216
- };
217
- blocks.push(image);
218
- }
219
- }
203
+ if (mediaPart?.kind !== "binary") return;
204
+ const format = sniffImageFormat(base64ToBytes(mediaPart.base64));
205
+ return format === void 0 ? void 0 : {
206
+ kind: "image",
207
+ format,
208
+ base64: mediaPart.base64,
209
+ widthPt: frame.widthPt,
210
+ heightPt: frame.heightPt
211
+ };
212
+ }
213
+ function readPicShape(pic, context, slideRels, pkg, parentTransform) {
214
+ const resolved = resolveShapeFrame(pic, context, parentTransform);
215
+ if (resolved === void 0) return;
216
+ const image = readBlipImage(pic, slideRels, pkg, resolved.frame);
217
+ const blocks = image === void 0 ? [] : [image];
220
218
  return {
221
219
  name: shapeName(pic),
222
220
  frame: resolved.frame,
@@ -289,6 +287,17 @@ function readGraphicFrameShape(gf, context, slideRels, pkg, parentTransform) {
289
287
  const relIds = childrenWithTag(graphicData, "dgm:relIds")[0];
290
288
  const dataModelRoot = relatedPartRoot(relIds === void 0 ? void 0 : attr(relIds, "r:dm"), slideRels, pkg);
291
289
  blocks = dataModelRoot === void 0 ? [] : readDiagramText(dataModelRoot);
290
+ } else if (uri === OLE_GRAPHIC_URI && graphicData !== void 0) {
291
+ const image = readBlipImage(graphicData, slideRels, pkg, frame);
292
+ if (image !== void 0) blocks = [image];
293
+ else {
294
+ const oleObj = elementsWithTag([graphicData], "p:oleObj")[0];
295
+ const progId = oleObj === void 0 ? void 0 : attr(oleObj, "progId");
296
+ blocks = progId === void 0 ? [] : [{
297
+ kind: "paragraph",
298
+ runs: [{ text: progId }]
299
+ }];
300
+ }
292
301
  } else blocks = [];
293
302
  return {
294
303
  name: shapeName(gf),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ooxml.js",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "description": "Type-safe, lossless round-trip conversion between OOXML packages (docx, pptx, xlsx) and JSON, built on Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {