office-open 0.12.2 → 0.13.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
@@ -9,7 +9,7 @@
9
9
  ## Features
10
10
 
11
11
  - **One Install** — Import from `office-open/docx`, `office-open/pptx`, `office-open/xlsx`; no Microsoft Office required
12
- - **AI SDK Tools** — Vercel AI SDK compatible tools for `generate-docx`, `generate-pptx`, `generate-xlsx`, ready for AI agents and chatbots
12
+ - **AI SDK Tools** — Vercel AI SDK compatible tools for `generate-docx`, `generate-pptx`, `generate-xlsx`, with schema-validated retries
13
13
  - **JSON Schemas** — Draft-07 input validation for all document types, with on-demand schema slicing for LLM context budgets
14
14
  - **CLI** — Generate files from JSON via `npx office-open`
15
15
  - **Generate Function** — Type-agnostic `generate()` for dynamic document creation
@@ -58,7 +58,7 @@ npx office-open docx document.json "output.docx"
58
58
  npx office-open pptx slides.json "output.pptx"
59
59
  npx office-open xlsx spreadsheet.json "output.xlsx"
60
60
 
61
- # Consult the JSON schemas (for AI agents and humans)
61
+ # Inspect the option schemas on demand
62
62
  npx office-open schema index docx # indexed lookup entries by domain
63
63
  npx office-open schema index docx --all # every definition name
64
64
  npx office-open schema slice docx ParagraphOptions RunOptions # sub-schema for those types
@@ -155,6 +155,21 @@ import { parse, stringify } from "office-open/xml";
155
155
  }
156
156
  ```
157
157
 
158
+ ## Documentation
159
+
160
+ - [Documentation](https://www.office-open.com) — getting started, per-format guides, and AI integration
161
+ - [AI Integration Guide](https://www.office-open.com/en/getting-started/ai-integration) — MCP server, Agent Skill, and schema slicing
162
+ - [Changelog](https://github.com/DemoMacro/office-open/releases) — release notes
163
+ - [Report Issues](https://github.com/DemoMacro/office-open/issues) — bug reports and feature requests
164
+
165
+ ## Related Packages
166
+
167
+ - [@office-open/docx](https://www.npmjs.com/package/@office-open/docx) — Word (.docx)
168
+ - [@office-open/pptx](https://www.npmjs.com/package/@office-open/pptx) — PowerPoint (.pptx)
169
+ - [@office-open/xlsx](https://www.npmjs.com/package/@office-open/xlsx) — Excel (.xlsx)
170
+ - [@office-open/core](https://www.npmjs.com/package/@office-open/core) — shared OOXML infrastructure
171
+ - [@office-open/xml](https://www.npmjs.com/package/@office-open/xml) — XML parsing and serialization
172
+
158
173
  ## License
159
174
 
160
- MIT
175
+ - [MIT](https://github.com/DemoMacro/office-open/blob/main/LICENSE) © [Demo Macro](https://www.demomacro.com/)
package/dist/ai/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { generate } from "../generate.mjs";
2
- import { a as sliceDocumentSchema, g as validateDocumentInput, n as getSkeletonSchema, r as UnknownDefinitionError, t as renderSliceTypeText } from "../schemas-B400scMm.mjs";
2
+ import { a as sliceDocumentSchema, g as validateDocumentInput, n as getSkeletonSchema, r as UnknownDefinitionError, t as renderSliceTypeText } from "../schemas-LxuRToZl.mjs";
3
3
  import { lintWorkbookFormulas } from "@office-open/xlsx";
4
4
  import { PART_REGISTRIES, encodeBase64, unzipSync, validateOpcConsistency } from "@office-open/core";
5
5
  import { jsonSchema, tool } from "ai";
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { generateToFile, parseInput } from "./generate.mjs";
2
- import { a as sliceDocumentSchema, g as validateDocumentInput, p as SCHEMAS, r as UnknownDefinitionError, t as renderSliceTypeText, u as SCHEMA_ENTRIES } from "./schemas-B400scMm.mjs";
2
+ import { a as sliceDocumentSchema, g as validateDocumentInput, p as SCHEMAS, r as UnknownDefinitionError, t as renderSliceTypeText, u as SCHEMA_ENTRIES } from "./schemas-LxuRToZl.mjs";
3
3
  import { defineCommand, runMain } from "citty";
4
4
  //#region src/cli.ts
5
5
  const FORMATS = [
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/convert/picture.ts","../../src/convert/shape.ts","../../src/convert/position.ts","../../src/convert/connector.ts","../../src/convert/group.ts","../../src/convert/table.ts","../../src/convert/smartart.ts","../../src/convert/text.ts"],"mappings":";;;;;;iBAuHgB,cAAc,QAAQ,mBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;iBAuC3C,cAAc,QAAQ,iBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;iBAmC3C,cAAc,QAAQ,iBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;;;KClJ/C,mBAAmB;UAGd;EAEf,OAAO;EACP,UAAU;EACV,UAAU;EACV,YAAY;EACZ,UAAU;EACV,UAAU;;KAIP,gBAAgB,KAAK;EAA0B,OAAO;;iBAG3C,YAAY,UAAU,cAAc,QAAQ,IAAI;iBAehD,iBACd,GAAG,YAAY,oCACd;iBAQa,uBAAuB,UAAU,kBAAkB;iBAWnD,eACd,UAAU,iCACV,gBAAgB,oCACf;UAoCc;EACf,MAAM;EACN,gBAAgB;;iBA8BF,iBAAiB,QAAQ,iBAAmB,iBAAmB;iBA+C/D,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBASvC,YAAY,QAAQ,mBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBA2CvC,YAAY,QAAQ,mBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;UCvPtC;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;iBCdc,eACd,aAAa,8BACb,aAAa,8BACb,aAAa,8BACb,aAAa,+BACZ;iBAgBa,eAAe,KAAK;EAClC;EACA;EACA;EACA;;iBAiBc,gBAAgB,SAAS,mBAAuB;iBAQhD,gBAAgB,QAAQ,qBAAuB;iBA0B/C,gBAAgB,QAAQ,mBAAuB;;;iBCwG/C,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBAsEvC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBAgEvC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;UCzRtC;EACf,MAAM;EACN,aAAa;EACb,UAAU;;iBAyMI,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,kBAAkB;iBA+EtC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,kBAAkB;iBA6DtC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;iBClWvC,eAAe,QAAQ,oBAAe;iBAqBtC,eAAe,QAAQ,kBAAe;;;iBC2BtC,qBAAqB,SAAS,6BAA6B;iBA2H3D,mBAAmB,MAAM,mBAAmB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/convert/picture.ts","../../src/convert/shape.ts","../../src/convert/position.ts","../../src/convert/connector.ts","../../src/convert/group.ts","../../src/convert/table.ts","../../src/convert/smartart.ts","../../src/convert/text.ts"],"mappings":";;;;;;iBAuHgB,cAAc,QAAQ,mBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;iBAuC3C,cAAc,QAAQ,iBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;iBAmC3C,cAAc,QAAQ,iBAAqB;iBAE3C,cAAc,QAAQ,mBAAqB;;;KClJ/C,mBAAmB;UAGd;EAEf,OAAO;EACP,UAAU;EACV,UAAU;EACV,YAAY;EACZ,UAAU;EACV,UAAU;;KAIP,gBAAgB,KAAK;EAA0B,OAAO;;iBAG3C,YAAY,UAAU,cAAc,QAAQ,IAAI;iBAehD,iBACd,GAAG,YAAY,oCACd;iBAQa,uBAAuB,UAAU,kBAAkB;iBAWnD,eACd,UAAU,iCACV,gBAAgB,oCACf;UAoCc;EACf,MAAM;EACN,gBAAgB;;iBA8BF,iBAAiB,QAAQ,iBAAmB,iBAAmB;iBAgD/D,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBASvC,YAAY,QAAQ,mBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBA+CvC,YAAY,QAAQ,mBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;UC5PtC;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;iBCdc,eACd,aAAa,8BACb,aAAa,8BACb,aAAa,8BACb,aAAa,+BACZ;iBAgBa,eAAe,KAAK;EAClC;EACA;EACA;EACA;;iBAiBc,gBAAgB,SAAS,mBAAuB;iBAQhD,gBAAgB,QAAQ,qBAAuB;iBAyB/C,gBAAgB,QAAQ,mBAAuB;;;iBC6G/C,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBAsEvC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;iBAgEvC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;UC7RtC;EACf,MAAM;EACN,aAAa;EACb,UAAU;;iBAyMI,YAAY,QAAQ,iBAAmB;iBAEvC,YAAY,QAAQ,kBAAkB;iBA+EtC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,kBAAkB;iBA6DtC,YAAY,QAAQ,eAAmB;iBAEvC,YAAY,QAAQ,iBAAmB;;;iBClWvC,eAAe,QAAQ,oBAAe;iBAqBtC,eAAe,QAAQ,kBAAe;;;iBC2BtC,qBAAqB,SAAS,6BAA6B;iBA2H3D,mBAAmB,MAAM,mBAAmB"}
@@ -77,8 +77,8 @@ function boxFromDocx(transformation) {
77
77
  width: toEmu(transformation.width),
78
78
  height: toEmu(transformation.height),
79
79
  ...transformation.rotation !== void 0 ? { rotation: transformation.rotation } : {},
80
- ...transformation.flip?.horizontal ? { flipHorizontal: true } : {},
81
- ...transformation.flip?.vertical ? { flipVertical: true } : {}
80
+ ...transformation.flipHorizontal ? { flipHorizontal: true } : {},
81
+ ...transformation.flipVertical ? { flipVertical: true } : {}
82
82
  };
83
83
  }
84
84
  /** Emit pptx top-level position fields from a box. */
@@ -125,10 +125,8 @@ function boxToDocx(box) {
125
125
  width: box.width,
126
126
  height: box.height,
127
127
  ...box.rotation !== void 0 ? { rotation: box.rotation } : {},
128
- ...box.flipHorizontal || box.flipVertical ? { flip: {
129
- ...box.flipHorizontal ? { horizontal: true } : {},
130
- ...box.flipVertical ? { vertical: true } : {}
131
- } } : {}
128
+ ...box.flipHorizontal ? { flipHorizontal: true } : {},
129
+ ...box.flipVertical ? { flipVertical: true } : {}
132
130
  };
133
131
  }
134
132
  //#endregion
@@ -766,7 +764,7 @@ function isRunChild(child) {
766
764
  *
767
765
  * docx shapes carry text as w:p paragraphs; pptx/xlsx carry it as a core
768
766
  * TextBody (a:p). bodyProperties (a:bodyPr) round-trips verbatim. Geometry
769
- * adapts to docx's stricter API (presetGeometry rejects the bare-string
767
+ * adapts to docx's stricter API (geometry rejects the bare-string
770
768
  * shorthand pptx/xlsx accept).
771
769
  *
772
770
  * @module
@@ -829,8 +827,8 @@ const hasCnvPr$1 = (source) => {
829
827
  * full MediaDataTransformation; the caller runs it through createTransformation).
830
828
  */
831
829
  function toDocxShapeParts(source) {
832
- if ("spPr" in source) {
833
- const spPr = source.spPr;
830
+ if ("col" in source) {
831
+ const spPr = source.properties;
834
832
  const box = boxFromXlsxAnchor(source, spPr.width, spPr.height, spPr.rotation, spPr.flipHorizontal, spPr.flipVertical);
835
833
  const preset = toPresetGeometry(spPr.geometry);
836
834
  return {
@@ -838,20 +836,21 @@ function toDocxShapeParts(source) {
838
836
  children: source.textBody ? textBodyToDocxChildren(source.textBody) : [],
839
837
  ...pickContent(spPr),
840
838
  ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {},
841
- ...preset !== void 0 ? { presetGeometry: preset } : {},
839
+ ...preset !== void 0 ? { geometry: preset } : {},
842
840
  ...hasCnvPr$1(source) ? docxNonVisual(source) : {}
843
841
  },
844
842
  transformation: boxToDocx(box)
845
843
  };
846
844
  }
845
+ const spPr = source.properties ?? {};
847
846
  const box = boxFromPptx(source.x, source.y, source.width, source.height, source.rotation, source.flipHorizontal);
848
- const preset = toPresetGeometry(source.geometry);
847
+ const preset = toPresetGeometry(spPr.geometry);
849
848
  return {
850
849
  data: {
851
850
  children: source.textBody ? textBodyToDocxChildren(source.textBody) : [],
852
- ...pickContent(source),
853
- ...source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {},
854
- ...preset !== void 0 ? { presetGeometry: preset } : {},
851
+ ...pickContent(spPr),
852
+ ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {},
853
+ ...preset !== void 0 ? { geometry: preset } : {},
855
854
  ...hasCnvPr$1(source) ? docxNonVisual(source) : {}
856
855
  },
857
856
  transformation: boxToDocx(box)
@@ -865,13 +864,15 @@ function toDocxShape(source) {
865
864
  };
866
865
  }
867
866
  function toPptxShape(source) {
868
- if ("spPr" in source) {
869
- const spPr = source.spPr;
867
+ if ("col" in source) {
868
+ const spPr = source.properties;
870
869
  return {
871
870
  ...boxToPptx(boxFromXlsxAnchor(source, spPr.width, spPr.height, spPr.rotation, spPr.flipHorizontal, spPr.flipVertical)),
872
- ...pickContent(spPr),
873
- ...spPr.geometry !== void 0 ? { geometry: spPr.geometry } : {},
874
- ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {},
871
+ properties: {
872
+ ...pickContent(spPr),
873
+ ...spPr.geometry !== void 0 ? { geometry: spPr.geometry } : {},
874
+ ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {}
875
+ },
875
876
  ...source.textBody ? { textBody: source.textBody } : {},
876
877
  ...pickNonVisualDrawingProperties(source)
877
878
  };
@@ -880,8 +881,10 @@ function toPptxShape(source) {
880
881
  const textBody = docxToTextBody(source.children, source.bodyProperties);
881
882
  return {
882
883
  ...boxToPptx(box),
883
- ...pickContent(source),
884
- ...source.presetGeometry !== void 0 ? { geometry: source.presetGeometry } : source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {},
884
+ properties: {
885
+ ...pickContent(source),
886
+ ...source.geometry !== void 0 ? { geometry: source.geometry } : source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {}
887
+ },
885
888
  ...textBody ? { textBody } : {},
886
889
  ...pickNonVisualDrawingProperties(source.nonVisualProperties)
887
890
  };
@@ -897,18 +900,19 @@ function toXlsxShape(source) {
897
900
  width: box.width,
898
901
  height: box.height,
899
902
  ...pickContent(source),
900
- ...source.presetGeometry !== void 0 ? { geometry: source.presetGeometry } : source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {},
903
+ ...source.geometry !== void 0 ? { geometry: source.geometry } : source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {},
901
904
  ...box.rotation !== void 0 ? { rotation: box.rotation } : {},
902
905
  ...box.flipHorizontal ? { flipHorizontal: true } : {},
903
906
  ...box.flipVertical ? { flipVertical: true } : {}
904
907
  };
905
908
  return {
906
909
  ...pos.anchor,
907
- spPr,
910
+ properties: spPr,
908
911
  ...textBody ? { textBody } : {},
909
912
  ...pickNonVisualDrawingProperties(source.nonVisualProperties)
910
913
  };
911
914
  }
915
+ const paint = source.properties ?? {};
912
916
  const box = boxFromPptx(source.x, source.y, source.width, source.height, source.rotation, source.flipHorizontal);
913
917
  const pos = boxToXlsx(box);
914
918
  const spPr = {
@@ -916,15 +920,15 @@ function toXlsxShape(source) {
916
920
  y: pos.xfrmY,
917
921
  width: box.width,
918
922
  height: box.height,
919
- ...pickContent(source),
920
- ...source.geometry !== void 0 ? { geometry: source.geometry } : {},
921
- ...source.customGeometry !== void 0 ? { customGeometry: source.customGeometry } : {},
923
+ ...pickContent(paint),
924
+ ...paint.geometry !== void 0 ? { geometry: paint.geometry } : {},
925
+ ...paint.customGeometry !== void 0 ? { customGeometry: paint.customGeometry } : {},
922
926
  ...box.rotation !== void 0 ? { rotation: box.rotation } : {},
923
927
  ...box.flipHorizontal ? { flipHorizontal: true } : {}
924
928
  };
925
929
  return {
926
930
  ...pos.anchor,
927
- spPr,
931
+ properties: spPr,
928
932
  ...source.textBody ? { textBody: source.textBody } : {},
929
933
  ...pickNonVisualDrawingProperties(source)
930
934
  };
@@ -940,8 +944,7 @@ function toXlsxShape(source) {
940
944
  * fields (cNvPr name/description/title/hidden + locking + endpoint connections)
941
945
  * pass straight through via pickConnectorBase; only positioning (pptx two
942
946
  * endpoints ↔ xlsx cell-anchor bounding box, with flip flags encoding draw
943
- * direction) and the line fill/outline (pptx top-level convenience xlsx
944
- * nested in spPr) are adapted per leg.
947
+ * direction) is adapted per leg paint travels in `properties` on both sides.
945
948
  *
946
949
  * docx has no standalone connector element (Word embeds connectors as wps
947
950
  * shapes flagged with a connector marker), so converting a connector to docx
@@ -983,15 +986,14 @@ function toDocxConnector(_source) {
983
986
  }
984
987
  /** Convert an xlsx connector to a pptx connector. */
985
988
  function toPptxConnector(source) {
986
- const spPr = source.spPr;
989
+ const spPr = source.properties;
987
990
  const { x1, y1, x2, y2 } = boxToEndpoints(boxFromXlsxAnchor(source, spPr.width, spPr.height, spPr.rotation, spPr.flipHorizontal, spPr.flipVertical));
988
991
  return {
989
992
  x1,
990
993
  y1,
991
994
  x2,
992
995
  y2,
993
- ...spPr.outline !== void 0 ? { outline: spPr.outline } : {},
994
- ...spPr.fill !== void 0 ? { fill: spPr.fill } : {},
996
+ properties: pickContent(spPr),
995
997
  ...pickConnectorBase(source)
996
998
  };
997
999
  }
@@ -1005,14 +1007,13 @@ function toXlsxConnector(source) {
1005
1007
  width: box.width,
1006
1008
  height: box.height,
1007
1009
  geometry: "line",
1008
- ...source.outline !== void 0 ? { outline: source.outline } : {},
1009
- ...source.fill !== void 0 ? { fill: source.fill } : {},
1010
+ ...pickContent(source.properties ?? {}),
1010
1011
  ...box.flipHorizontal ? { flipHorizontal: true } : {},
1011
1012
  ...box.flipVertical ? { flipVertical: true } : {}
1012
1013
  };
1013
1014
  return {
1014
1015
  ...pos.anchor,
1015
- spPr,
1016
+ properties: spPr,
1016
1017
  ...pickConnectorBase(source)
1017
1018
  };
1018
1019
  }
@@ -1071,12 +1072,13 @@ function docxChildMediaToBox(t) {
1071
1072
  width: t.emus.x,
1072
1073
  height: t.emus.y,
1073
1074
  ...t.rotation !== void 0 ? { rotation: parseAngle(t.rotation) } : {},
1074
- ...t.flip?.horizontal ? { flipHorizontal: true } : {},
1075
- ...t.flip?.vertical ? { flipVertical: true } : {}
1075
+ ...t.flipHorizontal ? { flipHorizontal: true } : {},
1076
+ ...t.flipVertical ? { flipVertical: true } : {}
1076
1077
  };
1077
1078
  }
1078
- /** pptx shape top-level → core spPr (group-child position is absolute). */
1079
+ /** pptx shape → core spPr (group-child position is absolute). */
1079
1080
  function pptxShapeToSpPr(shape) {
1081
+ const paint = shape.properties ?? {};
1080
1082
  return {
1081
1083
  x: shape.x,
1082
1084
  y: shape.y,
@@ -1084,12 +1086,12 @@ function pptxShapeToSpPr(shape) {
1084
1086
  height: shape.height,
1085
1087
  ...shape.rotation !== void 0 ? { rotation: shape.rotation } : {},
1086
1088
  ...shape.flipHorizontal ? { flipHorizontal: true } : {},
1087
- ...shape.geometry !== void 0 ? { geometry: shape.geometry } : {},
1088
- ...shape.customGeometry !== void 0 ? { customGeometry: shape.customGeometry } : {},
1089
- ...pickContent(shape)
1089
+ ...paint.geometry !== void 0 ? { geometry: paint.geometry } : {},
1090
+ ...paint.customGeometry !== void 0 ? { customGeometry: paint.customGeometry } : {},
1091
+ ...pickContent(paint)
1090
1092
  };
1091
1093
  }
1092
- /** core spPr → pptx shape top-level fields. */
1094
+ /** core spPr → pptx shape (transform top-level, paint nested in `properties`). */
1093
1095
  function spPrToPptxShape(spPr) {
1094
1096
  return {
1095
1097
  x: spPr.x,
@@ -1099,20 +1101,22 @@ function spPrToPptxShape(spPr) {
1099
1101
  ...spPr.rotation !== void 0 ? { rotation: spPr.rotation } : {},
1100
1102
  ...spPr.flipHorizontal ? { flipHorizontal: true } : {},
1101
1103
  ...spPr.flipVertical ? { flipVertical: true } : {},
1102
- ...spPr.geometry !== void 0 ? { geometry: spPr.geometry } : {},
1103
- ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {},
1104
- ...pickContent(spPr)
1104
+ properties: {
1105
+ ...spPr.geometry !== void 0 ? { geometry: spPr.geometry } : {},
1106
+ ...spPr.customGeometry !== void 0 ? { customGeometry: spPr.customGeometry } : {},
1107
+ ...pickContent(spPr)
1108
+ }
1105
1109
  };
1106
1110
  }
1107
1111
  /** xlsx group child shape → docx wps core (position lives on the wpg child wrapper). */
1108
1112
  function xlsxShapeChildToDocxData(s) {
1109
- const preset = toPresetGeometry(s.spPr.geometry);
1113
+ const preset = toPresetGeometry(s.properties.geometry);
1110
1114
  const cnvPr = pickNonVisualDrawingProperties(s);
1111
1115
  return {
1112
1116
  children: s.textBody ? textBodyToDocxChildren(s.textBody) : [],
1113
- ...pickContent(s.spPr),
1114
- ...s.spPr.customGeometry !== void 0 ? { customGeometry: s.spPr.customGeometry } : {},
1115
- ...preset !== void 0 ? { presetGeometry: preset } : {},
1117
+ ...pickContent(s.properties),
1118
+ ...s.properties.customGeometry !== void 0 ? { customGeometry: s.properties.customGeometry } : {},
1119
+ ...preset !== void 0 ? { geometry: preset } : {},
1116
1120
  ...hasCnvPr(cnvPr) ? docxNonVisualFromCnvPr(cnvPr, "Shape") : {}
1117
1121
  };
1118
1122
  }
@@ -1128,20 +1132,19 @@ function docxChildToSpPr(data, box) {
1128
1132
  ...box.flipVertical ? { flipVertical: true } : {},
1129
1133
  ...pickContent(data)
1130
1134
  };
1131
- if (data.presetGeometry !== void 0) out.geometry = data.presetGeometry;
1135
+ if (data.geometry !== void 0) out.geometry = data.geometry;
1132
1136
  else if (data.customGeometry !== void 0) out.customGeometry = data.customGeometry;
1133
1137
  return out;
1134
1138
  }
1135
1139
  /** xlsx group connector child → pptx connector. */
1136
1140
  function xlsxConnectorChildToPptx(c) {
1137
- const { x1, y1, x2, y2 } = boxToEndpoints(boxFromSpPr(c.spPr));
1141
+ const { x1, y1, x2, y2 } = boxToEndpoints(boxFromSpPr(c.properties));
1138
1142
  return {
1139
1143
  x1,
1140
1144
  y1,
1141
1145
  x2,
1142
1146
  y2,
1143
- ...c.spPr.outline !== void 0 ? { outline: c.spPr.outline } : {},
1144
- ...c.spPr.fill !== void 0 ? { fill: c.spPr.fill } : {},
1147
+ properties: pickContent(c.properties),
1145
1148
  ...c.locking ? { locking: c.locking } : {},
1146
1149
  ...c.startConnection ? { startConnection: c.startConnection } : {},
1147
1150
  ...c.endConnection ? { endConnection: c.endConnection } : {},
@@ -1151,8 +1154,8 @@ function xlsxConnectorChildToPptx(c) {
1151
1154
  function toDocxGroup(source) {
1152
1155
  let box;
1153
1156
  let children;
1154
- if ("grpSpPr" in source) {
1155
- const g = source.grpSpPr;
1157
+ if ("properties" in source) {
1158
+ const g = source.properties;
1156
1159
  box = boxFromXlsxAnchor(source, g.width, g.height, g.rotation, g.flipHorizontal, g.flipVertical);
1157
1160
  children = xlsxGroupChildrenToDocx(source.shapes, source.connectors);
1158
1161
  } else {
@@ -1182,7 +1185,7 @@ function xlsxGroupChildrenToDocx(shapes, connectors) {
1182
1185
  const out = [];
1183
1186
  for (const s of shapes ?? []) out.push({
1184
1187
  type: "wps",
1185
- transformation: createTransformation(boxToDocx(boxFromSpPr(s.spPr))),
1188
+ transformation: createTransformation(boxToDocx(boxFromSpPr(s.properties))),
1186
1189
  data: xlsxShapeChildToDocxData(s)
1187
1190
  });
1188
1191
  if (connectors?.length) console.warn("Connector in group → docx is unsupported; skipped.");
@@ -1192,8 +1195,8 @@ function toPptxGroup(source) {
1192
1195
  let box;
1193
1196
  let children;
1194
1197
  const cnvPr = "transformation" in source ? pickNonVisualDrawingProperties(source.altText) : pickGroupBase(source);
1195
- if ("grpSpPr" in source) {
1196
- const g = source.grpSpPr;
1198
+ if ("properties" in source) {
1199
+ const g = source.properties;
1197
1200
  box = boxFromXlsxAnchor(source, g.width, g.height, g.rotation, g.flipHorizontal, g.flipVertical);
1198
1201
  children = xlsxGroupChildrenToPptx(source.shapes, source.connectors);
1199
1202
  } else {
@@ -1209,7 +1212,7 @@ function toPptxGroup(source) {
1209
1212
  function xlsxGroupChildrenToPptx(shapes, connectors) {
1210
1213
  const out = [];
1211
1214
  for (const s of shapes ?? []) {
1212
- const shape = spPrToPptxShape(s.spPr);
1215
+ const shape = spPrToPptxShape(s.properties);
1213
1216
  if (s.textBody) shape.textBody = s.textBody;
1214
1217
  Object.assign(shape, pickNonVisualDrawingProperties(s));
1215
1218
  out.push({ shape });
@@ -1257,7 +1260,7 @@ function toXlsxGroup(source) {
1257
1260
  };
1258
1261
  return {
1259
1262
  ...pos.anchor,
1260
- grpSpPr,
1263
+ properties: grpSpPr,
1261
1264
  ...shapes.length ? { shapes } : {},
1262
1265
  ...connectors.length ? { connectors } : {},
1263
1266
  ...cnvPr
@@ -1268,7 +1271,7 @@ function pptxGroupChildrenToXlsx(children) {
1268
1271
  const connectors = [];
1269
1272
  for (const child of children ?? []) if ("shape" in child) {
1270
1273
  const s = {
1271
- spPr: pptxShapeToSpPr(child.shape),
1274
+ properties: pptxShapeToSpPr(child.shape),
1272
1275
  ...child.shape.textBody ? { textBody: child.shape.textBody } : {},
1273
1276
  ...pickNonVisualDrawingProperties(child.shape)
1274
1277
  };
@@ -1283,14 +1286,13 @@ function pptxGroupChildrenToXlsx(children) {
1283
1286
  function pptxConnectorToXlsxChild(c) {
1284
1287
  const box = endpointsToBox(c.x1, c.y1, c.x2, c.y2);
1285
1288
  return {
1286
- spPr: {
1289
+ properties: {
1287
1290
  x: box.x,
1288
1291
  y: box.y,
1289
1292
  width: box.width,
1290
1293
  height: box.height,
1291
1294
  geometry: "line",
1292
- ...c.outline !== void 0 ? { outline: c.outline } : {},
1293
- ...c.fill !== void 0 ? { fill: c.fill } : {},
1295
+ ...pickContent(c.properties ?? {}),
1294
1296
  ...box.flipHorizontal ? { flipHorizontal: true } : {},
1295
1297
  ...box.flipVertical ? { flipVertical: true } : {}
1296
1298
  },
@@ -1308,7 +1310,7 @@ function docxGroupChildrenToXlsx(children) {
1308
1310
  const spPr = docxChildToSpPr(child.data, box);
1309
1311
  const textBody = docxToTextBody(child.data.children, child.data.bodyProperties);
1310
1312
  shapes.push({
1311
- spPr,
1313
+ properties: spPr,
1312
1314
  ...textBody ? { textBody } : {},
1313
1315
  ...pickNonVisualDrawingProperties(child.data.nonVisualProperties)
1314
1316
  });