ooxml.js 6.3.7 → 7.1.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.
Files changed (52) hide show
  1. package/README.md +3 -2
  2. package/dist/{codec-D6UovAeS.d.ts → codec-BT_RdGLe.d.ts} +4 -3
  3. package/dist/{codec-BQU_AqVe.d.cts → codec-Ca78GND5.d.cts} +4 -3
  4. package/dist/codec.d.cts +1 -1
  5. package/dist/codec.d.ts +1 -1
  6. package/dist/{document-tree-CjI-Z4Tp.d.cts → document-tree-BQevawcZ.d.cts} +1 -1
  7. package/dist/{document-tree-B17XbBOR.d.ts → document-tree-ryxE_URD.d.ts} +1 -1
  8. package/dist/index.cjs +5 -1
  9. package/dist/index.d.cts +6 -5
  10. package/dist/index.d.ts +6 -5
  11. package/dist/index.js +4 -3
  12. package/dist/{metadata-C74-XCrx.d.cts → metadata-Di0PfE5h.d.cts} +9 -1
  13. package/dist/{metadata-Bjfa88HQ.d.ts → metadata-_k8PRY6p.d.ts} +9 -1
  14. package/dist/{read-6whiWc5N.cjs → read-Bu4DECZB.cjs} +54 -8
  15. package/dist/{read-BrAuHnvH.js → read-DlkyVzBP.js} +53 -7
  16. package/dist/shading-BF2-DM4L.d.ts +9 -0
  17. package/dist/shading-DB9hu40o.d.cts +9 -0
  18. package/dist/typed/document-tree.cjs +1 -1
  19. package/dist/typed/document-tree.d.cts +1 -1
  20. package/dist/typed/document-tree.d.ts +1 -1
  21. package/dist/typed/document-tree.js +1 -1
  22. package/dist/typed/docx/read.cjs +1 -1
  23. package/dist/typed/docx/read.js +1 -1
  24. package/dist/typed/docx/shading.cjs +95 -0
  25. package/dist/typed/docx/shading.d.cts +2 -0
  26. package/dist/typed/docx/shading.d.ts +2 -0
  27. package/dist/typed/docx/shading.js +93 -0
  28. package/dist/typed/docx/write.cjs +2 -5
  29. package/dist/typed/docx/write.d.cts +1 -1
  30. package/dist/typed/docx/write.d.ts +1 -1
  31. package/dist/typed/docx/write.js +2 -5
  32. package/dist/typed/embedded.cjs +1 -1
  33. package/dist/typed/embedded.js +1 -1
  34. package/dist/typed/pptx/read.cjs +1 -1
  35. package/dist/typed/pptx/read.js +1 -1
  36. package/dist/typed/shared/metadata.cjs +53 -0
  37. package/dist/typed/shared/metadata.d.cts +2 -2
  38. package/dist/typed/shared/metadata.d.ts +2 -2
  39. package/dist/typed/shared/metadata.js +52 -1
  40. package/dist/typed/xlsx/build.cjs +10 -4
  41. package/dist/typed/xlsx/build.js +10 -4
  42. package/dist/typed/xlsx/styles.cjs +70 -12
  43. package/dist/typed/xlsx/styles.d.cts +17 -8
  44. package/dist/typed/xlsx/styles.d.ts +17 -8
  45. package/dist/typed/xlsx/styles.js +71 -13
  46. package/dist/typed/xlsx/units.cjs +5 -1
  47. package/dist/typed/xlsx/units.d.cts +2 -1
  48. package/dist/typed/xlsx/units.d.ts +2 -1
  49. package/dist/typed/xlsx/units.js +5 -2
  50. package/dist/{write-BGTpp3RS.d.cts → write-C81qQcnp.d.cts} +1 -1
  51. package/dist/{write-Cnfu3zdB.d.ts → write-h7kU0YPl.d.ts} +1 -1
  52. package/package.json +10 -4
@@ -1,12 +1,12 @@
1
1
  import { l as XmlElement } from "../../node-B6JX5CRX.cjs";
2
2
  import { r as Package } from "../../package-DMk9fuTI.cjs";
3
3
  import { CellNumberFormat } from "./number-format.cjs";
4
- import { Alignment, Color, ContentCellBorders } from "document-schema.js";
4
+ import { Alignment, Color, ContentCellBorders, ContentCellFill, ContentCellPatternType } from "document-schema.js";
5
5
  //#region src/typed/xlsx/styles.d.ts
6
6
  declare const GENERAL_NUM_FMT_ID = 0;
7
7
  interface CellStyleEntry {
8
8
  numberFormatCode?: string;
9
- background?: Color;
9
+ background?: ContentCellFill;
10
10
  borders?: ContentCellBorders;
11
11
  alignment?: Alignment;
12
12
  verticalAlignment?: "top" | "middle" | "bottom";
@@ -22,15 +22,24 @@ interface DeclaredNumberFormat {
22
22
  code: string;
23
23
  }
24
24
  interface CellFormatDecoration {
25
- background?: Color;
25
+ background?: ContentCellFill;
26
26
  borders?: ContentCellBorders;
27
27
  alignment?: Alignment;
28
28
  verticalAlignment?: "top" | "middle" | "bottom";
29
29
  }
30
- interface DeclaredFill {
31
- patternType: "none" | "gray125" | "solid";
32
- rgb?: string;
33
- }
30
+ type DeclaredFill = {
31
+ kind: "none";
32
+ } | {
33
+ kind: "gray125";
34
+ } | {
35
+ kind: "solid";
36
+ rgb: string;
37
+ } | {
38
+ kind: "pattern";
39
+ patternType: ContentCellPatternType;
40
+ fgRgb?: string;
41
+ bgRgb?: string;
42
+ };
34
43
  interface DeclaredBorder {
35
44
  edges: {
36
45
  left?: {
@@ -64,7 +73,7 @@ declare class CellFormatTable {
64
73
  private readonly indexBySignature;
65
74
  private readonly records;
66
75
  private readonly declared;
67
- private readonly fillIndexByRgb;
76
+ private readonly fillIndexBySignature;
68
77
  private readonly fills;
69
78
  private readonly borderIndexBySignature;
70
79
  private readonly borders;
@@ -1,12 +1,12 @@
1
1
  import { l as XmlElement } from "../../node-B6JX5CRX.js";
2
2
  import { r as Package } from "../../package-otZYrxiO.js";
3
3
  import { CellNumberFormat } from "./number-format.js";
4
- import { Alignment, Color, ContentCellBorders } from "document-schema.js";
4
+ import { Alignment, Color, ContentCellBorders, ContentCellFill, ContentCellPatternType } from "document-schema.js";
5
5
  //#region src/typed/xlsx/styles.d.ts
6
6
  declare const GENERAL_NUM_FMT_ID = 0;
7
7
  interface CellStyleEntry {
8
8
  numberFormatCode?: string;
9
- background?: Color;
9
+ background?: ContentCellFill;
10
10
  borders?: ContentCellBorders;
11
11
  alignment?: Alignment;
12
12
  verticalAlignment?: "top" | "middle" | "bottom";
@@ -22,15 +22,24 @@ interface DeclaredNumberFormat {
22
22
  code: string;
23
23
  }
24
24
  interface CellFormatDecoration {
25
- background?: Color;
25
+ background?: ContentCellFill;
26
26
  borders?: ContentCellBorders;
27
27
  alignment?: Alignment;
28
28
  verticalAlignment?: "top" | "middle" | "bottom";
29
29
  }
30
- interface DeclaredFill {
31
- patternType: "none" | "gray125" | "solid";
32
- rgb?: string;
33
- }
30
+ type DeclaredFill = {
31
+ kind: "none";
32
+ } | {
33
+ kind: "gray125";
34
+ } | {
35
+ kind: "solid";
36
+ rgb: string;
37
+ } | {
38
+ kind: "pattern";
39
+ patternType: ContentCellPatternType;
40
+ fgRgb?: string;
41
+ bgRgb?: string;
42
+ };
34
43
  interface DeclaredBorder {
35
44
  edges: {
36
45
  left?: {
@@ -64,7 +73,7 @@ declare class CellFormatTable {
64
73
  private readonly indexBySignature;
65
74
  private readonly records;
66
75
  private readonly declared;
67
- private readonly fillIndexByRgb;
76
+ private readonly fillIndexBySignature;
68
77
  private readonly fills;
69
78
  private readonly borderIndexBySignature;
70
79
  private readonly borders;
@@ -1,5 +1,5 @@
1
1
  import { attr, childrenWithTag, decodeEntities, rootElement } from "../util.js";
2
- import { BORDER_WIDTH_PT, borderWeightForWidthPt, colorToRgbHex, dashedBorderWeightForWidthPt, rgbHexToColor } from "document-schema.js";
2
+ import { BORDER_WIDTH_PT, borderWeightForWidthPt, colorToRgbHex, dashedBorderWeightForWidthPt, rgbHexToColor, unrecognizedFillKind } from "document-schema.js";
3
3
  import { BUILTIN_NUMBER_FORMATS } from "excel-number-format";
4
4
  //#region src/typed/xlsx/styles.ts
5
5
  const STYLES_PATH = "xl/styles.xml";
@@ -17,6 +17,29 @@ function readNumberFormatCodesById(styleSheet) {
17
17
  }
18
18
  return codes;
19
19
  }
20
+ const SPREADSHEETML_PATTERN_TYPES = /* @__PURE__ */ new Set([
21
+ "mediumGray",
22
+ "darkGray",
23
+ "lightGray",
24
+ "darkHorizontal",
25
+ "darkVertical",
26
+ "darkDown",
27
+ "darkUp",
28
+ "darkGrid",
29
+ "darkTrellis",
30
+ "lightHorizontal",
31
+ "lightVertical",
32
+ "lightDown",
33
+ "lightUp",
34
+ "lightGrid",
35
+ "lightTrellis",
36
+ "gray125",
37
+ "gray0625"
38
+ ]);
39
+ /** Whether `value` is one of ST_PatternType's own seventeen non-solid, non-none members -- the only ContentCellPatternType members a `<patternFill>` can ever name, so a value this returns true for can be used as a ContentCellPatternType directly with no further mapping. */
40
+ function isXlsxPatternType(value) {
41
+ return SPREADSHEETML_PATTERN_TYPES.has(value);
42
+ }
20
43
  const XLSX_BORDER_STYLE = {
21
44
  thin: {
22
45
  weight: "thin",
@@ -88,8 +111,24 @@ function readColorRgb(container, colorTag) {
88
111
  }
89
112
  function readFillBackground(fill) {
90
113
  const patternFill = childrenWithTag(fill, "patternFill")[0];
91
- if (patternFill === void 0 || attr(patternFill, "patternType") !== "solid") return;
92
- return readColorRgb(patternFill, "fgColor") ?? readColorRgb(patternFill, "bgColor");
114
+ if (patternFill === void 0) return;
115
+ const patternType = attr(patternFill, "patternType");
116
+ if (patternType === "solid") {
117
+ const color = readColorRgb(patternFill, "fgColor") ?? readColorRgb(patternFill, "bgColor");
118
+ return color === void 0 ? void 0 : {
119
+ kind: "solid",
120
+ color
121
+ };
122
+ }
123
+ if (patternType === void 0 || !isXlsxPatternType(patternType)) return;
124
+ const foregroundColor = readColorRgb(patternFill, "fgColor");
125
+ const backgroundColor = readColorRgb(patternFill, "bgColor");
126
+ return {
127
+ kind: "pattern",
128
+ patternType,
129
+ ...foregroundColor !== void 0 ? { foregroundColor } : {},
130
+ ...backgroundColor !== void 0 ? { backgroundColor } : {}
131
+ };
93
132
  }
94
133
  function readFills(styleSheet) {
95
134
  const fillsEl = childrenWithTag(styleSheet, "fills")[0];
@@ -198,9 +237,12 @@ function signatureOfNumberFormat(format) {
198
237
  return format.kind === "builtin" ? `builtin:${format.id}` : `custom:${format.code}`;
199
238
  }
200
239
  const EMPTY_DECORATION = {};
240
+ function fillSignature(fill) {
241
+ return fill.kind === "solid" ? `solid:${colorToRgbHex(fill.color)}` : `pattern:${fill.patternType}:${fill.foregroundColor === void 0 ? "" : colorToRgbHex(fill.foregroundColor)}:${fill.backgroundColor === void 0 ? "" : colorToRgbHex(fill.backgroundColor)}`;
242
+ }
201
243
  function signatureOfDecoration(decoration) {
202
244
  let sig = "";
203
- if (decoration.background !== void 0) sig += `|bg:${colorToRgbHex(decoration.background)}`;
245
+ if (decoration.background !== void 0) sig += `|bg:${fillSignature(decoration.background)}`;
204
246
  const borders = decoration.borders;
205
247
  if (borders !== void 0) for (const edge of [
206
248
  "left",
@@ -235,8 +277,8 @@ var CellFormatTable = class {
235
277
  borderId: EMPTY_BORDER_INDEX
236
278
  }];
237
279
  declared = [];
238
- fillIndexByRgb = /* @__PURE__ */ new Map();
239
- fills = [{ patternType: "none" }, { patternType: "gray125" }];
280
+ fillIndexBySignature = /* @__PURE__ */ new Map();
281
+ fills = [{ kind: "none" }, { kind: "gray125" }];
240
282
  borderIndexBySignature = /* @__PURE__ */ new Map();
241
283
  borders = [{ edges: {} }];
242
284
  intern(format, decoration = EMPTY_DECORATION) {
@@ -281,15 +323,31 @@ var CellFormatTable = class {
281
323
  return id;
282
324
  }
283
325
  internFill(background) {
284
- const rgb = colorToRgbHex(background);
285
- const existing = this.fillIndexByRgb.get(rgb);
326
+ const signature = fillSignature(background);
327
+ const existing = this.fillIndexBySignature.get(signature);
286
328
  if (existing !== void 0) return existing;
329
+ let declared;
330
+ switch (background.kind) {
331
+ case "solid":
332
+ declared = {
333
+ kind: "solid",
334
+ rgb: colorToRgbHex(background.color)
335
+ };
336
+ break;
337
+ case "pattern":
338
+ if (!isXlsxPatternType(background.patternType)) throw new Error(`ooxml.js cannot write a '${background.patternType}' cell fill: ECMA-376's own ST_PatternType vocabulary has no member for it, that pattern name belonging only to WordprocessingML's ST_Shd half of ContentCellPatternType's shared vocabulary`);
339
+ declared = {
340
+ kind: "pattern",
341
+ patternType: background.patternType,
342
+ ...background.foregroundColor === void 0 ? {} : { fgRgb: colorToRgbHex(background.foregroundColor) },
343
+ ...background.backgroundColor === void 0 ? {} : { bgRgb: colorToRgbHex(background.backgroundColor) }
344
+ };
345
+ break;
346
+ default: throw new Error(`ooxml.js cannot write a cell fill with kind '${unrecognizedFillKind(background)}': ContentCellFillSchema's discriminated union only defines 'solid' and 'pattern'`);
347
+ }
287
348
  const index = this.fills.length;
288
- this.fills.push({
289
- patternType: "solid",
290
- rgb
291
- });
292
- this.fillIndexByRgb.set(rgb, index);
349
+ this.fills.push(declared);
350
+ this.fillIndexBySignature.set(signature, index);
293
351
  return index;
294
352
  }
295
353
  internBorder(borders) {
@@ -5,6 +5,7 @@ const PIXELS_PER_INCH = 96;
5
5
  const MAX_DIGIT_WIDTH_PX = 7;
6
6
  const DEFAULT_ROW_HEIGHT_PT = 15;
7
7
  const DEFAULT_COLUMN_WIDTH_CHARS = 8.43;
8
+ const COLUMN_WIDTH_CHARS_DECIMAL_PLACES = 2;
8
9
  function columnWidthCharsToPt(width) {
9
10
  const digitWidthAllowance = Math.trunc(128 / 7);
10
11
  return Math.trunc((256 * width + digitWidthAllowance) / 256 * 7) / 96 * 72;
@@ -12,9 +13,12 @@ function columnWidthCharsToPt(width) {
12
13
  function ptToColumnWidthChars(widthPt) {
13
14
  const pixels = widthPt / 72 * 96;
14
15
  const digitWidthAllowance = Math.trunc(128 / 7);
15
- return pixels / 7 - digitWidthAllowance / 256;
16
+ const exact = pixels / 7 - digitWidthAllowance / 256;
17
+ const scale = 100;
18
+ return Math.max(0, Math.ceil(exact * scale) / scale);
16
19
  }
17
20
  //#endregion
21
+ exports.COLUMN_WIDTH_CHARS_DECIMAL_PLACES = COLUMN_WIDTH_CHARS_DECIMAL_PLACES;
18
22
  exports.DEFAULT_COLUMN_WIDTH_CHARS = DEFAULT_COLUMN_WIDTH_CHARS;
19
23
  exports.DEFAULT_ROW_HEIGHT_PT = DEFAULT_ROW_HEIGHT_PT;
20
24
  exports.MAX_DIGIT_WIDTH_PX = MAX_DIGIT_WIDTH_PX;
@@ -3,7 +3,8 @@ declare const PIXELS_PER_INCH = 96;
3
3
  declare const MAX_DIGIT_WIDTH_PX = 7;
4
4
  declare const DEFAULT_ROW_HEIGHT_PT = 15;
5
5
  declare const DEFAULT_COLUMN_WIDTH_CHARS = 8.43;
6
+ declare const COLUMN_WIDTH_CHARS_DECIMAL_PLACES = 2;
6
7
  declare function columnWidthCharsToPt(width: number): number;
7
8
  declare function ptToColumnWidthChars(widthPt: number): number;
8
9
  //#endregion
9
- export { DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
10
+ export { COLUMN_WIDTH_CHARS_DECIMAL_PLACES, DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
@@ -3,7 +3,8 @@ declare const PIXELS_PER_INCH = 96;
3
3
  declare const MAX_DIGIT_WIDTH_PX = 7;
4
4
  declare const DEFAULT_ROW_HEIGHT_PT = 15;
5
5
  declare const DEFAULT_COLUMN_WIDTH_CHARS = 8.43;
6
+ declare const COLUMN_WIDTH_CHARS_DECIMAL_PLACES = 2;
6
7
  declare function columnWidthCharsToPt(width: number): number;
7
8
  declare function ptToColumnWidthChars(widthPt: number): number;
8
9
  //#endregion
9
- export { DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
10
+ export { COLUMN_WIDTH_CHARS_DECIMAL_PLACES, DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
@@ -4,6 +4,7 @@ const PIXELS_PER_INCH = 96;
4
4
  const MAX_DIGIT_WIDTH_PX = 7;
5
5
  const DEFAULT_ROW_HEIGHT_PT = 15;
6
6
  const DEFAULT_COLUMN_WIDTH_CHARS = 8.43;
7
+ const COLUMN_WIDTH_CHARS_DECIMAL_PLACES = 2;
7
8
  function columnWidthCharsToPt(width) {
8
9
  const digitWidthAllowance = Math.trunc(128 / 7);
9
10
  return Math.trunc((256 * width + digitWidthAllowance) / 256 * 7) / 96 * 72;
@@ -11,7 +12,9 @@ function columnWidthCharsToPt(width) {
11
12
  function ptToColumnWidthChars(widthPt) {
12
13
  const pixels = widthPt / 72 * 96;
13
14
  const digitWidthAllowance = Math.trunc(128 / 7);
14
- return pixels / 7 - digitWidthAllowance / 256;
15
+ const exact = pixels / 7 - digitWidthAllowance / 256;
16
+ const scale = 100;
17
+ return Math.max(0, Math.ceil(exact * scale) / scale);
15
18
  }
16
19
  //#endregion
17
- export { DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
20
+ export { COLUMN_WIDTH_CHARS_DECIMAL_PLACES, DEFAULT_COLUMN_WIDTH_CHARS, DEFAULT_ROW_HEIGHT_PT, MAX_DIGIT_WIDTH_PX, PIXELS_PER_INCH, columnWidthCharsToPt, ptToColumnWidthChars };
@@ -1,5 +1,5 @@
1
1
  import { r as Package } from "./package-DMk9fuTI.cjs";
2
- import { t as DocumentMetadata } from "./metadata-C74-XCrx.cjs";
2
+ import { n as DocumentMetadata } from "./metadata-Di0PfE5h.cjs";
3
3
  import { ContentDocument, ContentSection } from "document-schema.js";
4
4
  //#region src/typed/docx/write.d.ts
5
5
  interface DocxContent {
@@ -1,5 +1,5 @@
1
1
  import { r as Package } from "./package-otZYrxiO.js";
2
- import { t as DocumentMetadata } from "./metadata-Bjfa88HQ.js";
2
+ import { n as DocumentMetadata } from "./metadata-_k8PRY6p.js";
3
3
  import { ContentDocument, ContentSection } from "document-schema.js";
4
4
  //#region src/typed/docx/write.d.ts
5
5
  interface DocxContent {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ooxml.js",
3
- "version": "6.3.7",
3
+ "version": "7.1.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": {
@@ -60,6 +60,8 @@
60
60
  "test:watch": "vitest --project unit",
61
61
  "test:coverage": "turbo run _test:coverage",
62
62
  "_test:coverage": "vitest run --project unit --coverage",
63
+ "test:mutation": "turbo run _test:mutation",
64
+ "_test:mutation": "stryker run stryker.config.mjs",
63
65
  "test:smoke": "turbo run _test:smoke",
64
66
  "_test:smoke": "vitest run --project smoke",
65
67
  "test:workers": "turbo run _test:workers",
@@ -80,9 +82,9 @@
80
82
  "license": "MIT",
81
83
  "packageManager": "pnpm@11.6.0",
82
84
  "dependencies": {
83
- "archive-codec": "^1.4.2",
84
- "document-schema.js": "^5.6.0",
85
- "excel-number-format": "^1.0.1",
85
+ "archive-codec": "^1.5.0",
86
+ "document-schema.js": "^6.1.0",
87
+ "excel-number-format": "^1.1.0",
86
88
  "fast-xml-parser": "^5.10.1",
87
89
  "fflate": "^0.8.3",
88
90
  "zod": "^4.4.3"
@@ -90,10 +92,14 @@
90
92
  "devDependencies": {
91
93
  "@arethetypeswrong/cli": "^0.18.5",
92
94
  "@cloudflare/vitest-pool-workers": "^0.21.2",
95
+ "@stryker-mutator/core": "^10.0.0",
96
+ "@stryker-mutator/typescript-checker": "^10.0.0",
97
+ "@stryker-mutator/vitest-runner": "^10.0.0",
93
98
  "@types/node": "^26.1.1",
94
99
  "@vitest/coverage-v8": "^4.1.10",
95
100
  "eslint": "^10.8.0",
96
101
  "husky": "^9.1.7",
102
+ "jiti": "2.7.0",
97
103
  "publint": "^0.3.21",
98
104
  "semantic-release": "^25.0.8",
99
105
  "tsdown": "^0.22.13",