@shbernal/ts-xlsx 3.0.0 → 3.2.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 (277) hide show
  1. package/README.md +34 -24
  2. package/dist/bytes.d.ts +10 -2
  3. package/dist/bytes.js +22 -0
  4. package/dist/core/address.d.ts +96 -2
  5. package/dist/core/address.js +87 -33
  6. package/dist/core/array-formula-ranges.d.ts +33 -0
  7. package/dist/core/array-formula-ranges.js +62 -0
  8. package/dist/core/autofilter.d.ts +4 -3
  9. package/dist/core/autofilter.js +31 -30
  10. package/dist/core/axis-handle.d.ts +2 -0
  11. package/dist/core/axis-handle.js +5 -2
  12. package/dist/core/cell.d.ts +4 -3
  13. package/dist/core/cell.js +4 -6
  14. package/dist/core/clone.d.ts +29 -0
  15. package/dist/core/clone.js +24 -0
  16. package/dist/core/color-resolution.js +4 -6
  17. package/dist/core/column.d.ts +1 -0
  18. package/dist/core/column.js +6 -2
  19. package/dist/core/comment-thread.d.ts +7 -3
  20. package/dist/core/comment-thread.js +2 -1
  21. package/dist/core/conditional-formatting-overlay.d.ts +11 -1
  22. package/dist/core/conditional-formatting-overlay.js +30 -3
  23. package/dist/core/conditional-formatting.d.ts +107 -11
  24. package/dist/core/conditional-formatting.js +76 -19
  25. package/dist/core/containers.d.ts +12 -0
  26. package/dist/core/containers.js +5 -0
  27. package/dist/core/data-validation-overlay.d.ts +7 -1
  28. package/dist/core/data-validation-overlay.js +19 -4
  29. package/dist/core/data-validation.d.ts +22 -0
  30. package/dist/core/data-validation.js +30 -4
  31. package/dist/core/date-format.d.ts +20 -0
  32. package/dist/core/date-format.js +170 -0
  33. package/dist/core/date.d.ts +43 -8
  34. package/dist/core/date.js +19 -3
  35. package/dist/core/formula-references.d.ts +26 -0
  36. package/dist/core/formula-references.js +173 -0
  37. package/dist/core/formula-scan.d.ts +2 -0
  38. package/dist/core/formula-scan.js +58 -0
  39. package/dist/core/formula.d.ts +76 -17
  40. package/dist/core/formula.js +87 -80
  41. package/dist/core/function-values.d.ts +4 -0
  42. package/dist/core/function-values.js +58 -0
  43. package/dist/core/future-functions.d.ts +3 -0
  44. package/dist/core/{modern-functions.js → future-functions.js} +119 -88
  45. package/dist/core/grid-edits.d.ts +30 -3
  46. package/dist/core/grid-edits.js +248 -81
  47. package/dist/core/grid-shift.d.ts +58 -9
  48. package/dist/core/grid-shift.js +26 -4
  49. package/dist/core/hyperlink.d.ts +39 -0
  50. package/dist/core/hyperlink.js +88 -0
  51. package/dist/core/image.d.ts +49 -14
  52. package/dist/core/image.js +16 -5
  53. package/dist/core/internal.d.ts +10 -2
  54. package/dist/core/limits.d.ts +25 -0
  55. package/dist/core/limits.js +4 -0
  56. package/dist/core/merge.d.ts +18 -4
  57. package/dist/core/merge.js +33 -20
  58. package/dist/core/page-setup.d.ts +26 -11
  59. package/dist/core/pivot-table.d.ts +49 -10
  60. package/dist/core/pivot-table.js +112 -60
  61. package/dist/core/protection.d.ts +66 -4
  62. package/dist/core/protection.js +6 -11
  63. package/dist/core/range.js +34 -30
  64. package/dist/core/row-input.js +2 -2
  65. package/dist/core/row.d.ts +1 -0
  66. package/dist/core/row.js +6 -2
  67. package/dist/core/structured-reference.d.ts +7 -0
  68. package/dist/core/structured-reference.js +7 -0
  69. package/dist/core/style.d.ts +85 -70
  70. package/dist/core/style.js +92 -28
  71. package/dist/core/table-style.d.ts +1 -1
  72. package/dist/core/table-style.js +4 -4
  73. package/dist/core/table.d.ts +64 -16
  74. package/dist/core/table.js +87 -40
  75. package/dist/core/theme.d.ts +2 -0
  76. package/dist/core/theme.js +9 -5
  77. package/dist/core/value.d.ts +60 -28
  78. package/dist/core/value.js +48 -43
  79. package/dist/core/workbook-media.d.ts +34 -0
  80. package/dist/core/workbook-media.js +44 -0
  81. package/dist/core/workbook-styles.d.ts +83 -1
  82. package/dist/core/workbook-styles.js +4 -0
  83. package/dist/core/workbook-theme.js +5 -3
  84. package/dist/core/workbook-vba.js +3 -2
  85. package/dist/core/workbook.d.ts +41 -3
  86. package/dist/core/workbook.js +46 -41
  87. package/dist/core/worksheet-comments.d.ts +2 -1
  88. package/dist/core/worksheet-comments.js +20 -13
  89. package/dist/core/worksheet-merges.d.ts +49 -0
  90. package/dist/core/worksheet-merges.js +65 -0
  91. package/dist/core/worksheet-model.d.ts +10 -2
  92. package/dist/core/worksheet-model.js +28 -9
  93. package/dist/core/worksheet-pictures.d.ts +3 -3
  94. package/dist/core/worksheet-pictures.js +7 -6
  95. package/dist/core/worksheet.d.ts +165 -27
  96. package/dist/core/worksheet.js +206 -89
  97. package/dist/customui/ribbon.js +2 -1
  98. package/dist/entries/core.d.ts +21 -14
  99. package/dist/entries/core.js +14 -7
  100. package/dist/entries/errors.d.ts +1 -0
  101. package/dist/entries/errors.js +1 -0
  102. package/dist/entries/xlsx.d.ts +1 -1
  103. package/dist/errors.d.ts +64 -0
  104. package/dist/errors.js +22 -0
  105. package/dist/hex.d.ts +8 -0
  106. package/dist/hex.js +3 -0
  107. package/dist/io/cell-metadata/metadata.d.ts +42 -0
  108. package/dist/io/cell-metadata/metadata.js +35 -0
  109. package/dist/io/cell-metadata/rich-values.d.ts +11 -0
  110. package/dist/io/cell-metadata/rich-values.js +80 -0
  111. package/dist/io/csv/delimiter.d.ts +21 -0
  112. package/dist/io/csv/delimiter.js +18 -0
  113. package/dist/io/csv/errors.d.ts +14 -0
  114. package/dist/io/csv/errors.js +5 -0
  115. package/dist/io/csv/read.d.ts +6 -1
  116. package/dist/io/csv/read.js +51 -22
  117. package/dist/io/csv/write.d.ts +19 -5
  118. package/dist/io/csv/write.js +24 -44
  119. package/dist/io/opc/inflate.js +14 -0
  120. package/dist/io/opc/namespaces.d.ts +16 -0
  121. package/dist/io/opc/namespaces.js +4 -0
  122. package/dist/io/opc/part-paths.d.ts +9 -0
  123. package/dist/io/opc/part-paths.js +5 -5
  124. package/dist/io/opc/read-opc.d.ts +58 -14
  125. package/dist/io/opc/read-opc.js +49 -21
  126. package/dist/io/opc/read-options.d.ts +5 -1
  127. package/dist/io/opc/sniff-format.d.ts +3 -3
  128. package/dist/io/opc/sniff-format.js +2 -2
  129. package/dist/io/opc/strict-relationships.d.ts +2 -0
  130. package/dist/io/opc/strict-relationships.js +12 -0
  131. package/dist/io/read-policy/column-budget.d.ts +26 -0
  132. package/dist/io/read-policy/column-budget.js +18 -0
  133. package/dist/io/read-policy/read-repair.d.ts +74 -0
  134. package/dist/io/read-policy/read-repair.js +119 -0
  135. package/dist/io/style/cell-style-resolution.d.ts +25 -0
  136. package/dist/io/style/cell-style-resolution.js +30 -0
  137. package/dist/io/style/xf-style.d.ts +23 -1
  138. package/dist/io/style/xf-style.js +8 -0
  139. package/dist/io/xlsb/formula.d.ts +2 -2
  140. package/dist/io/xlsb/formula.js +52 -35
  141. package/dist/io/xlsb/primitives.js +8 -14
  142. package/dist/io/xlsb/ptg-functions.d.ts +19 -10
  143. package/dist/io/xlsb/ptg-functions.js +495 -596
  144. package/dist/io/xlsb/read-metadata.d.ts +7 -0
  145. package/dist/io/xlsb/read-metadata.js +69 -0
  146. package/dist/io/xlsb/read-styles.js +45 -81
  147. package/dist/io/xlsb/read-worksheet.d.ts +26 -1
  148. package/dist/io/xlsb/read-worksheet.js +148 -106
  149. package/dist/io/xlsb/read.d.ts +6 -3
  150. package/dist/io/xlsb/read.js +70 -31
  151. package/dist/io/xlsb/record-stream.d.ts +30 -0
  152. package/dist/io/xlsb/record-stream.js +20 -0
  153. package/dist/io/xlsb/record-types.d.ts +14 -5
  154. package/dist/io/xlsb/record-types.js +14 -5
  155. package/dist/io/xlsb/sheet-protection.d.ts +20 -0
  156. package/dist/io/xlsb/sheet-protection.js +60 -0
  157. package/dist/io/xlsx/cell-accumulator.d.ts +24 -9
  158. package/dist/io/xlsx/cell-accumulator.js +74 -21
  159. package/dist/io/xlsx/cell-metadata.d.ts +39 -0
  160. package/dist/io/xlsx/cell-metadata.js +162 -0
  161. package/dist/io/xlsx/cell-value.d.ts +19 -5
  162. package/dist/io/xlsx/cell-value.js +45 -30
  163. package/dist/io/xlsx/color-xml.js +3 -2
  164. package/dist/io/xlsx/column-span.d.ts +11 -0
  165. package/dist/io/xlsx/column-span.js +9 -0
  166. package/dist/io/xlsx/comments.d.ts +9 -30
  167. package/dist/io/xlsx/comments.js +25 -83
  168. package/dist/io/xlsx/conditional-formatting.d.ts +43 -23
  169. package/dist/io/xlsx/conditional-formatting.js +437 -138
  170. package/dist/io/xlsx/data-validation.d.ts +12 -7
  171. package/dist/io/xlsx/data-validation.js +67 -53
  172. package/dist/io/xlsx/edit-vba.d.ts +7 -2
  173. package/dist/io/xlsx/edit-vba.js +52 -52
  174. package/dist/io/xlsx/font-xml.d.ts +7 -0
  175. package/dist/io/xlsx/font-xml.js +104 -0
  176. package/dist/io/xlsx/hyperlinks.d.ts +19 -21
  177. package/dist/io/xlsx/hyperlinks.js +12 -32
  178. package/dist/io/xlsx/images.d.ts +49 -16
  179. package/dist/io/xlsx/images.js +149 -50
  180. package/dist/io/xlsx/namespaces.d.ts +24 -0
  181. package/dist/io/xlsx/namespaces.js +11 -0
  182. package/dist/io/xlsx/package-plan.d.ts +60 -15
  183. package/dist/io/xlsx/package-plan.js +83 -18
  184. package/dist/io/xlsx/part-names.d.ts +6 -8
  185. package/dist/io/xlsx/part-names.js +3 -7
  186. package/dist/io/xlsx/pivot.d.ts +5 -5
  187. package/dist/io/xlsx/pivot.js +26 -24
  188. package/dist/io/xlsx/preserved-splices.d.ts +6 -0
  189. package/dist/io/xlsx/preserved-splices.js +74 -0
  190. package/dist/io/xlsx/read-comments.d.ts +29 -0
  191. package/dist/io/xlsx/read-comments.js +75 -0
  192. package/dist/io/xlsx/read-parts.d.ts +59 -0
  193. package/dist/io/xlsx/read-parts.js +259 -0
  194. package/dist/io/xlsx/read-pivot.js +11 -4
  195. package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +8 -5
  196. package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +24 -4
  197. package/dist/io/xlsx/read-rows.d.ts +35 -11
  198. package/dist/io/xlsx/read-rows.js +73 -49
  199. package/dist/io/xlsx/read-shared-strings.js +3 -2
  200. package/dist/io/xlsx/read-styles.d.ts +0 -30
  201. package/dist/io/xlsx/read-styles.js +45 -105
  202. package/dist/io/xlsx/read-workbook-xml.d.ts +42 -0
  203. package/dist/io/xlsx/read-workbook-xml.js +175 -0
  204. package/dist/io/xlsx/read-worksheet.d.ts +9 -3
  205. package/dist/io/xlsx/read-worksheet.js +70 -177
  206. package/dist/io/xlsx/read.d.ts +3 -14
  207. package/dist/io/xlsx/read.js +74 -411
  208. package/dist/io/xlsx/relationships.d.ts +3 -0
  209. package/dist/io/xlsx/relationships.js +4 -0
  210. package/dist/io/xlsx/rich-text.js +1 -1
  211. package/dist/io/xlsx/row-position.d.ts +20 -0
  212. package/dist/io/xlsx/row-position.js +11 -0
  213. package/dist/io/xlsx/row-xml.d.ts +139 -0
  214. package/dist/io/xlsx/row-xml.js +222 -0
  215. package/dist/io/xlsx/shared-formulas.js +2 -2
  216. package/dist/io/xlsx/sheet-properties.d.ts +10 -1
  217. package/dist/io/xlsx/sheet-properties.js +182 -20
  218. package/dist/io/xlsx/strict-parts.d.ts +7 -0
  219. package/dist/io/xlsx/strict-parts.js +171 -0
  220. package/dist/io/xlsx/style-elements.d.ts +41 -0
  221. package/dist/io/xlsx/style-elements.js +136 -0
  222. package/dist/io/xlsx/styles.d.ts +17 -3
  223. package/dist/io/xlsx/styles.js +13 -209
  224. package/dist/io/xlsx/tables.d.ts +10 -2
  225. package/dist/io/xlsx/tables.js +55 -52
  226. package/dist/io/xlsx/theme-xml.d.ts +32 -4
  227. package/dist/io/xlsx/theme-xml.js +106 -71
  228. package/dist/io/xlsx/threaded-comments.d.ts +14 -11
  229. package/dist/io/xlsx/threaded-comments.js +16 -8
  230. package/dist/io/xlsx/workbook-xml.d.ts +45 -6
  231. package/dist/io/xlsx/workbook-xml.js +62 -54
  232. package/dist/io/xlsx/worksheet-xml.d.ts +26 -70
  233. package/dist/io/xlsx/worksheet-xml.js +69 -282
  234. package/dist/io/xlsx/write-stream.d.ts +90 -19
  235. package/dist/io/xlsx/write-stream.js +80 -25
  236. package/dist/io/xlsx/write.d.ts +12 -6
  237. package/dist/io/xlsx/write.js +226 -123
  238. package/dist/rel-type.d.ts +25 -0
  239. package/dist/rel-type.js +9 -0
  240. package/dist/token-set.d.ts +13 -0
  241. package/dist/token-set.js +4 -1
  242. package/dist/vba/bytes.d.ts +16 -5
  243. package/dist/vba/bytes.js +27 -6
  244. package/dist/vba/cfb-format.d.ts +55 -0
  245. package/dist/vba/cfb-format.js +35 -0
  246. package/dist/vba/cfb-writer.d.ts +8 -0
  247. package/dist/vba/cfb-writer.js +40 -40
  248. package/dist/vba/cfb.d.ts +21 -4
  249. package/dist/vba/cfb.js +124 -90
  250. package/dist/vba/codepage.js +2 -1
  251. package/dist/vba/dir-records.d.ts +6 -0
  252. package/dist/vba/dir-records.js +10 -2
  253. package/dist/vba/errors.d.ts +11 -4
  254. package/dist/vba/index.d.ts +0 -2
  255. package/dist/vba/index.js +0 -2
  256. package/dist/vba/ms-ovba.d.ts +6 -2
  257. package/dist/vba/ms-ovba.js +66 -22
  258. package/dist/vba/project-editor.js +129 -119
  259. package/dist/vba/project.d.ts +15 -1
  260. package/dist/vba/project.js +38 -13
  261. package/dist/vba/vba-encoding.d.ts +4 -10
  262. package/dist/vba/vba-encoding.js +3 -17
  263. package/dist/xml/xml-attrs.d.ts +37 -0
  264. package/dist/xml/xml-attrs.js +30 -0
  265. package/dist/xml/xml-chars.d.ts +40 -0
  266. package/dist/xml/xml-chars.js +12 -0
  267. package/dist/xml/xml-namespaces.d.ts +31 -0
  268. package/dist/xml/xml-namespaces.js +50 -0
  269. package/dist/xml/xml-read.d.ts +101 -11
  270. package/dist/xml/xml-read.js +150 -18
  271. package/dist/xml/xml-scan.d.ts +25 -34
  272. package/dist/xml/xml-scan.js +69 -46
  273. package/dist/xml/xml.d.ts +59 -26
  274. package/dist/xml/xml.js +45 -23
  275. package/package.json +15 -9
  276. package/skills/ts-xlsx-upstream/SKILL.md +21 -13
  277. package/dist/core/modern-functions.d.ts +0 -1
@@ -0,0 +1,259 @@
1
+ import { INTERNAL } from '../../core/internal.js';
2
+ import { mergesOverlappingTables } from '../../core/merge.js';
3
+ import { Workbook } from '../../core/workbook.js';
4
+ import { isAnyRelType } from '../../rel-type.js';
5
+ import { localName } from '../../xml/xml-scan.js';
6
+ import { relAttr } from '../opc/namespaces.js';
7
+ import { extensionOf, resolveRelativePart } from '../opc/part-paths.js';
8
+ import { capturePartClosure, parseRelationshipRecords, readPartRelationships, } from '../opc/read-opc.js';
9
+ import { admitting } from '../read-policy/read-repair.js';
10
+ import { parseDrawing } from './images.js';
11
+ import { parseComments } from './read-comments.js';
12
+ import { parsePivotTable } from './read-pivot.js';
13
+ import { transitionalPart } from './strict-parts.js';
14
+ import { parseTable } from './tables.js';
15
+ import { parseThemeSchemes } from './theme-xml.js';
16
+ import { buildCommentThreads, parsePersons, parseThreadedComments } from './threaded-comments.js';
17
+ function capturePreservedClosure({ pkg, contentTypeOf }, entryPath) {
18
+ return capturePartClosure(entryPath, pkg.partText, pkg.partBytes, contentTypeOf)?.map((part) => {
19
+ const bytes = transitionalPart(part.bytes, part.contentType);
20
+ return bytes === part.bytes ? part : { ...part, bytes };
21
+ });
22
+ }
23
+ export function readSheetComments(sheetRels) {
24
+ const commentsXml = sheetRels.relatedText('comments');
25
+ return commentsXml === undefined ? undefined : parseComments(commentsXml);
26
+ }
27
+ export function readWorkbookPersons({ workbook }, workbookRels) {
28
+ const xml = workbookRels.relatedText('person');
29
+ if (xml !== undefined)
30
+ workbook[INTERNAL].restorePersons(parsePersons(xml));
31
+ }
32
+ export function readWorkbookTheme(context, workbookRels) {
33
+ const { pkg, workbook } = context;
34
+ const entryPath = workbookRels.targetPath('theme');
35
+ if (entryPath === undefined)
36
+ return;
37
+ const parts = capturePreservedClosure(context, entryPath);
38
+ if (parts === undefined)
39
+ return;
40
+ const xml = pkg.partText(entryPath) ?? '';
41
+ workbook[INTERNAL].restoreThemePart({ entryPath, parts }, parseThemeSchemes(xml));
42
+ }
43
+ export function readSheetCommentThreads({ workbook }, sheetRels) {
44
+ const xml = sheetRels.relatedText('threadedComment');
45
+ if (xml === undefined)
46
+ return [];
47
+ return buildCommentThreads(parseThreadedComments(xml), (id) => workbook.getPerson(id));
48
+ }
49
+ export function readSheetPrinterSettings(sheetRels) {
50
+ return sheetRels.relatedBytes('printerSettings');
51
+ }
52
+ function internImage(context, mediaPath) {
53
+ const { workbook, pkg, imageIdByMediaPath } = context;
54
+ const known = imageIdByMediaPath.get(mediaPath);
55
+ if (known !== undefined)
56
+ return known;
57
+ const bytes = pkg.partBytes(mediaPath);
58
+ if (bytes === undefined)
59
+ return undefined;
60
+ const id = workbook.addImage({ buffer: bytes, extension: extensionOf(mediaPath) });
61
+ imageIdByMediaPath.set(mediaPath, id);
62
+ return id;
63
+ }
64
+ export function readSheetImages(context, sheetRels, sheet) {
65
+ const { partText } = context.pkg;
66
+ const drawingPath = sheetRels.targetPath('drawing');
67
+ if (drawingPath === undefined)
68
+ return;
69
+ const drawingXml = partText(drawingPath);
70
+ if (drawingXml === undefined)
71
+ return;
72
+ const { anchors, fullyModeled } = parseDrawing(drawingXml);
73
+ if (!fullyModeled)
74
+ return;
75
+ const drawingRels = readPartRelationships(drawingPath, partText);
76
+ for (const anchor of anchors) {
77
+ const embedded = drawingRels.byId(anchor.embed);
78
+ if (embedded === undefined)
79
+ continue;
80
+ const mediaPath = drawingRels.pathOf(embedded.target);
81
+ const id = internImage(context, mediaPath);
82
+ if (id === undefined)
83
+ continue;
84
+ const rot = anchor.rotation !== undefined ? { rotation: anchor.rotation } : {};
85
+ const properties = pictureOf(anchor, drawingRels);
86
+ if (anchor.to !== undefined) {
87
+ const mode = anchor.editAs !== undefined ? { editAs: anchor.editAs } : {};
88
+ sheet.addImageAnchor(id, { from: anchor.from, to: anchor.to, ...mode, ...rot }, properties);
89
+ }
90
+ else if (anchor.ext !== undefined) {
91
+ sheet.addImageAnchor(id, { from: anchor.from, ext: anchor.ext, ...rot }, properties);
92
+ }
93
+ }
94
+ }
95
+ function pictureOf(anchor, drawingRels) {
96
+ const { description, title, crop, hyperlinkId, tooltip } = anchor;
97
+ const link = hyperlinkId === undefined ? undefined : drawingRels.byId(hyperlinkId);
98
+ const target = link === undefined || link.target === '' ? undefined : link.target;
99
+ return {
100
+ ...(description === undefined ? {} : { description }),
101
+ ...(title === undefined ? {} : { title }),
102
+ ...(crop === undefined ? {} : { crop }),
103
+ ...(target === undefined
104
+ ? {}
105
+ : { hyperlink: tooltip === undefined ? { target } : { target, tooltip } }),
106
+ };
107
+ }
108
+ export function readSheetBackground(context, sheetRels, sheet) {
109
+ const mediaPath = sheetRels.targetPath('image');
110
+ if (mediaPath === undefined)
111
+ return;
112
+ const id = internImage(context, mediaPath);
113
+ if (id !== undefined)
114
+ sheet.addBackgroundImage(id);
115
+ }
116
+ export function readSheetPreservedReferences(context, sheetRels, referenceRelIds, sheet) {
117
+ const capture = (element, relType, target) => {
118
+ const entryPath = sheetRels.pathOf(target);
119
+ const parts = capturePreservedClosure(context, entryPath);
120
+ if (parts !== undefined)
121
+ sheet[INTERNAL].addPreservedReference({ element, relType, entryPath, parts });
122
+ };
123
+ const referenceElements = sheet.images.length === 0 ? ['drawing', 'legacyDrawingHF'] : ['legacyDrawingHF'];
124
+ for (const element of referenceElements) {
125
+ const relId = referenceRelIds[element];
126
+ const record = relId === undefined ? undefined : sheetRels.byId(relId);
127
+ if (record !== undefined && !record.external)
128
+ capture(element, record.type, record.target);
129
+ }
130
+ for (const record of sheetRels.records) {
131
+ if (record.external)
132
+ continue;
133
+ if (isPreservedSheetRelType(record.type))
134
+ capture(undefined, record.type, record.target);
135
+ }
136
+ }
137
+ function isPreservedSheetRelType(type) {
138
+ return isAnyRelType(type, 'pivotTable', 'slicer');
139
+ }
140
+ export function readWorkbookPreservedReferences(context, workbookRels, registrations) {
141
+ const { workbook } = context;
142
+ const { cacheIdByRelId, externalIndexByRelId } = registrations;
143
+ for (const record of workbookRels.records) {
144
+ if (record.external || !isPreservedWorkbookRelType(record.type))
145
+ continue;
146
+ const entryPath = workbookRels.pathOf(record.target);
147
+ const parts = capturePreservedClosure(context, entryPath);
148
+ if (parts === undefined)
149
+ continue;
150
+ const cacheId = cacheIdByRelId.get(record.id);
151
+ const externalReferenceIndex = externalIndexByRelId.get(record.id);
152
+ workbook[INTERNAL].addPreservedReference({
153
+ relType: record.type,
154
+ entryPath,
155
+ parts,
156
+ ...(cacheId !== undefined ? { pivotCacheId: cacheId } : {}),
157
+ ...(externalReferenceIndex !== undefined ? { externalReferenceIndex } : {}),
158
+ });
159
+ }
160
+ }
161
+ export function readRootPreservedReferences(context) {
162
+ const { workbook } = context;
163
+ const relsXml = context.pkg.partText('_rels/.rels');
164
+ if (relsXml === undefined)
165
+ return;
166
+ for (const record of parseRelationshipRecords(relsXml)) {
167
+ if (record.external || isRegeneratedRootRelType(record.type))
168
+ continue;
169
+ const entryPath = resolveRelativePart('', record.target);
170
+ const parts = capturePreservedClosure(context, entryPath);
171
+ if (parts === undefined)
172
+ continue;
173
+ workbook[INTERNAL].addPreservedRootReference({ relType: record.type, entryPath, parts });
174
+ }
175
+ }
176
+ function isRegeneratedRootRelType(type) {
177
+ return isAnyRelType(type, 'officeDocument', 'core-properties', 'extended-properties');
178
+ }
179
+ function isPreservedWorkbookRelType(type) {
180
+ return isAnyRelType(type, 'pivotCacheDefinition', 'slicerCache', 'vbaProject', 'externalLink');
181
+ }
182
+ export function pivotCacheRegistrationsPass() {
183
+ const byRelId = new Map();
184
+ return {
185
+ handlers: {
186
+ onOpen(name, attrs, _selfClosing, scope) {
187
+ if (localName(name) !== 'pivotCache')
188
+ return;
189
+ const relId = relAttr(scope, attrs, 'id');
190
+ if (relId !== undefined && attrs.cacheId !== undefined)
191
+ byRelId.set(relId, attrs.cacheId);
192
+ },
193
+ },
194
+ result: () => byRelId,
195
+ };
196
+ }
197
+ export function externalReferenceRegistrationsPass() {
198
+ const byRelId = new Map();
199
+ let index = 0;
200
+ return {
201
+ handlers: {
202
+ onOpen(name, attrs, _selfClosing, scope) {
203
+ if (localName(name) !== 'externalReference')
204
+ return;
205
+ const relId = relAttr(scope, attrs, 'id');
206
+ if (relId !== undefined)
207
+ byRelId.set(relId, index++);
208
+ },
209
+ },
210
+ result: () => byRelId,
211
+ };
212
+ }
213
+ export function worksheetReferencePass() {
214
+ const relIds = {};
215
+ return {
216
+ handlers: {
217
+ onOpen(name, attrs, _selfClosing, scope) {
218
+ const local = localName(name);
219
+ if (local !== 'drawing' && local !== 'legacyDrawingHF')
220
+ return;
221
+ if (relIds[local] !== undefined)
222
+ return;
223
+ const relId = relAttr(scope, attrs, 'id');
224
+ if (relId !== undefined)
225
+ relIds[local] = relId;
226
+ },
227
+ },
228
+ result: () => relIds,
229
+ };
230
+ }
231
+ export function readSheetTables({ pkg }, sheetRels, sheet, definedNames) {
232
+ for (const tablePath of sheetRels.targetPaths('table')) {
233
+ const tableXml = pkg.partText(tablePath);
234
+ if (tableXml === undefined)
235
+ continue;
236
+ const options = parseTable(tableXml, definedNames);
237
+ if (options !== undefined) {
238
+ admitting(() => {
239
+ sheet.addTable(options);
240
+ });
241
+ }
242
+ }
243
+ dropMergesInsideTables(sheet);
244
+ }
245
+ export function readSheetPivotTables({ pkg }, sheetRels, sheet) {
246
+ const { partText } = pkg;
247
+ for (const tablePath of sheetRels.targetPaths('pivotTable')) {
248
+ const tableXml = partText(tablePath);
249
+ if (tableXml === undefined)
250
+ continue;
251
+ const cacheXml = readPartRelationships(tablePath, partText).relatedText('pivotCacheDefinition') ?? '';
252
+ sheet[INTERNAL].addLoadedPivotTable(parsePivotTable(tableXml, cacheXml));
253
+ }
254
+ }
255
+ function dropMergesInsideTables(sheet) {
256
+ for (const { merge } of mergesOverlappingTables(sheet.merges, sheet.tables)) {
257
+ sheet.unmergeCells(merge);
258
+ }
259
+ }
@@ -1,6 +1,8 @@
1
1
  import { isDeclarablePivotSourceKind, pivotMetricFromSubtotal, } from '../../core/pivot-table.js';
2
+ import { numInteger } from '../../xml/xml-attrs.js';
2
3
  import { parseXml } from '../../xml/xml-read.js';
3
- import { localName, numInteger } from '../../xml/xml-scan.js';
4
+ import { localName } from '../../xml/xml-scan.js';
5
+ import { relAttr } from '../opc/namespaces.js';
4
6
  export function parsePivotTable(tableXml, cacheXml) {
5
7
  const { fields, source } = parsePivotCacheDefinition(cacheXml);
6
8
  const def = parsePivotTableDefinition(tableXml);
@@ -19,9 +21,9 @@ export function parsePivotTable(tableXml, cacheXml) {
19
21
  }
20
22
  function parsePivotCacheDefinition(cacheXml) {
21
23
  const fields = [];
22
- let source = { kind: 'worksheet', sheet: '', ref: '' };
24
+ let source = { kind: 'worksheet', sheet: '', ref: '', inAnotherWorkbook: false };
23
25
  parseXml(cacheXml, {
24
- onOpen(name, attrs) {
26
+ onOpen(name, attrs, _selfClosing, scope) {
25
27
  const local = localName(name);
26
28
  if (local === 'cacheField' && attrs.name !== undefined) {
27
29
  fields.push({ name: attrs.name });
@@ -30,7 +32,12 @@ function parsePivotCacheDefinition(cacheXml) {
30
32
  source = { ...source, kind: sourceKind(attrs.type) };
31
33
  }
32
34
  else if (local === 'worksheetSource') {
33
- source = { ...source, sheet: attrs.sheet ?? '', ref: attrs.ref ?? '' };
35
+ source = {
36
+ ...source,
37
+ sheet: attrs.sheet ?? '',
38
+ ref: attrs.ref ?? '',
39
+ inAnotherWorkbook: relAttr(scope, attrs, 'id') !== undefined,
40
+ };
34
41
  }
35
42
  },
36
43
  });
@@ -13,19 +13,22 @@ export declare class RunAccumulator {
13
13
  #private;
14
14
  /**
15
15
  * @param options.container the element that opens one string: `'si'` for the shared-string pool,
16
- * `'is'` for an inline string in a worksheet body.
17
- * @param options.readRuns whether `<r>`/`<rPr>` open a rich-text run. The buffered readers read
18
- * them; the row stream deliberately does not, and with runs off every `<t>` falls through to
19
- * {@link plainText}, which is exactly the documented flattening.
16
+ * `'is'` for an inline string in a worksheet body, `'text'` for a note's body.
17
+ * @param options.readRuns whether `<r>`/`<rPr>` open a rich-text run. A cell's string reads them in
18
+ * both worksheet readers, pooled or inline; a note's body does not, and with runs off every `<t>`
19
+ * falls through to {@link plainText}, which is the flattening a plain-text note wants.
20
20
  */
21
21
  constructor(options: {
22
- readonly container: 'si' | 'is';
22
+ readonly container: 'si' | 'is' | 'text';
23
23
  readonly readRuns: boolean;
24
24
  });
25
25
  /** The runs gathered so far. */
26
26
  get runs(): RichTextRun[];
27
27
  /** Whether the container held at least one `<r>`: what decides rich text from a plain string. */
28
28
  get isRich(): boolean;
29
+ /** Whether a container element opened at all since the last {@link beginContainer}. An `<is/>` is an
30
+ * empty string and a `<c t="inlineStr">` with no `<is>` is no string, and only this tells them apart. */
31
+ get opened(): boolean;
29
32
  /** The container's own text: every `<t>` no run claimed, concatenated and already unescaped. */
30
33
  get plainText(): string;
31
34
  /**
@@ -1,6 +1,7 @@
1
+ import { decodeSpreadsheetText } from '../../xml/xml-attrs.js';
1
2
  import { TextCapture } from '../../xml/xml-read.js';
2
- import { decodeSpreadsheetText } from '../../xml/xml-scan.js';
3
- import { applyFontChild } from './read-styles.js';
3
+ import {} from '../../xml/xml-scan.js';
4
+ import { applyFontChild } from './font-xml.js';
4
5
  export class RunAccumulator {
5
6
  #container;
6
7
  #readRuns;
@@ -12,7 +13,9 @@ export class RunAccumulator {
12
13
  #plain = '';
13
14
  #inRun = false;
14
15
  #isRich = false;
16
+ #opened = false;
15
17
  #inContainer = false;
18
+ #phoneticDepth = 0;
16
19
  constructor(options) {
17
20
  this.#container = options.container;
18
21
  this.#readRuns = options.readRuns;
@@ -23,6 +26,9 @@ export class RunAccumulator {
23
26
  get isRich() {
24
27
  return this.#isRich;
25
28
  }
29
+ get opened() {
30
+ return this.#opened;
31
+ }
26
32
  get plainText() {
27
33
  return this.#plain;
28
34
  }
@@ -34,12 +40,17 @@ export class RunAccumulator {
34
40
  this.#plain = '';
35
41
  this.#inRun = false;
36
42
  this.#isRich = false;
43
+ this.#opened = false;
44
+ this.#inContainer = false;
45
+ this.#phoneticDepth = 0;
46
+ this.#capture.reset();
37
47
  }
38
48
  open(local, attrs, selfClosing) {
39
49
  switch (local) {
40
50
  case this.#container:
41
- this.#inContainer = true;
42
51
  this.beginContainer();
52
+ this.#inContainer = !selfClosing;
53
+ this.#opened = true;
43
54
  return true;
44
55
  case 'r':
45
56
  if (!this.#readRuns || !this.#inContainer)
@@ -56,8 +67,13 @@ export class RunAccumulator {
56
67
  this.#font = {};
57
68
  this.#inProperties = true;
58
69
  return true;
70
+ case 'rPh':
71
+ if (!selfClosing)
72
+ this.#phoneticDepth++;
73
+ return true;
59
74
  case 't':
60
- this.#capture.open(local, selfClosing);
75
+ if (this.#phoneticDepth === 0)
76
+ this.#capture.open(local, selfClosing);
61
77
  return true;
62
78
  default:
63
79
  if (!this.#inProperties || this.#font === null)
@@ -82,6 +98,10 @@ export class RunAccumulator {
82
98
  }
83
99
  return 'claimed';
84
100
  }
101
+ case 'rPh':
102
+ if (this.#phoneticDepth > 0)
103
+ this.#phoneticDepth--;
104
+ return 'claimed';
85
105
  case 'rPr':
86
106
  if (!this.#readRuns || !this.#inProperties)
87
107
  return 'other';
@@ -1,6 +1,7 @@
1
1
  import type { CellValue } from '../../core/value.ts';
2
- import { type ReadXlsxOptions, type XfStyle } from './read.ts';
3
- export interface ReadSheetRowsOptions extends ReadXlsxOptions {
2
+ import type { ReadPackageOptions } from '../opc/read-options.ts';
3
+ import type { XfStyle } from '../style/xf-style.ts';
4
+ export interface ReadSheetRowsOptions extends ReadPackageOptions {
4
5
  /**
5
6
  * Which worksheet to stream: its name, or its 1-based position in the workbook. Defaults to the
6
7
  * first sheet.
@@ -8,12 +9,22 @@ export interface ReadSheetRowsOptions extends ReadXlsxOptions {
8
9
  readonly sheet?: string | number;
9
10
  }
10
11
  /**
11
- * The resolved style facets of a streamed cell: its own `<c s>` cell format, flattened exactly as
12
- * the buffered reader resolves it. Present only when the cell carries a format; a consumer can copy
13
- * these straight onto a writer cell to preserve its look through a streaming read→write.
12
+ * The resolved style facets of a streamed cell: its own `<c s>` format, failing that its row's (when
13
+ * the row is marked `customFormat`), failing that its column's, flattened exactly as the buffered
14
+ * reader resolves it. Present only when the cell, its row or its column declares a format; a consumer
15
+ * can copy these straight onto a writer cell to preserve its look through a streaming read→write.
16
+ *
17
+ * @unpublished A named commitment this surface is not ready to make. `entries/xlsx.ts` records the
18
+ * decision: the streaming reader's granular output shapes stay inferred structural types while the
19
+ * surface settles, so a consumer destructures them and never has to spell them.
14
20
  */
15
21
  export type StreamedCellStyle = XfStyle;
16
- /** One non-empty cell in a {@link StreamedRow}. */
22
+ /** One non-empty cell in a {@link StreamedRow}.
23
+ *
24
+ * @unpublished A named commitment this surface is not ready to make. `entries/xlsx.ts` records the
25
+ * decision: the streaming reader's granular output shapes stay inferred structural types while the
26
+ * surface settles, so a consumer destructures them and never has to spell them.
27
+ */
17
28
  export interface StreamedCell {
18
29
  /** 1-based column index. */
19
30
  readonly col: number;
@@ -21,7 +32,8 @@ export interface StreamedCell {
21
32
  readonly address: string;
22
33
  /** The decoded value, identical to what `readXlsx` would produce for the same cell. */
23
34
  readonly value: CellValue;
24
- /** The cell's resolved style facets, or absent when the cell carries no format of its own. */
35
+ /** The cell's resolved style facets, including a format it inherits from its row or column; absent
36
+ * when none of the three declares one. */
25
37
  readonly style?: StreamedCellStyle;
26
38
  }
27
39
  /** One worksheet row, as yielded by {@link readSheetRows} / {@link StreamedSheet.rows}. */
@@ -41,15 +53,27 @@ export interface StreamedRow {
41
53
  * its rows have not already been consumed, so their order relative to `rows()` never matters. (When
42
54
  * rows *are* consumed first, the streaming idiom, the accessors reuse that pass and re-scan
43
55
  * nothing.)
56
+ *
57
+ * @unpublished A named commitment this surface is not ready to make. `entries/xlsx.ts` records the
58
+ * decision: the streaming reader's granular output shapes stay inferred structural types while the
59
+ * surface settles, so a consumer destructures them and never has to spell them.
44
60
  */
45
61
  export interface StreamedSheet {
46
- /** The worksheet's declared name, joined from the workbook part. Never a positional placeholder. */
62
+ /**
63
+ * The worksheet's name, joined from the workbook part and repaired exactly as `readXlsx` repairs it
64
+ * (a duplicate becomes `S (2)`, a forbidden character is removed), so the two readers name a sheet
65
+ * the same way. Never a positional placeholder.
66
+ */
47
67
  readonly name: string;
48
68
  /** Stream this sheet's rows, one at a time, in sheet order. */
49
69
  rows(): Generator<StreamedRow, void, undefined>;
50
70
  /** 1-based indices of columns the sheet declares hidden, ascending. */
51
71
  readonly hiddenColumns: readonly number[];
52
- /** The sheet's merged ranges, as canonical A1 range strings, in declaration order. */
72
+ /**
73
+ * The sheet's merged ranges, as canonical A1 range strings, in declaration order: the ones
74
+ * `readXlsx` admits, so an unreadable range, or one overlapping a range declared before it, is
75
+ * dropped.
76
+ */
53
77
  readonly merges: readonly string[];
54
78
  }
55
79
  /**
@@ -76,10 +100,10 @@ export declare function readSheetRows(data: Uint8Array, options?: ReadSheetRowsO
76
100
  * of walking `readXlsx(data).worksheets`.
77
101
  *
78
102
  * @param data The raw `.xlsx` bytes.
79
- * @param options The inflate bound (see {@link ReadXlsxOptions}).
103
+ * @param options The inflate bound (see {@link ReadPackageOptions}).
80
104
  * @throws {UnsupportedFormatError} if the input is not a readable `.xlsx` package (a legacy `.xls`, a
81
105
  * binary `.xlsb`, or an unrecognised/non-ZIP blob; branch on `.format`).
82
106
  * @throws {PackageReadError} if the input is a ZIP that cannot be unpacked: a corrupt or
83
107
  * truncated archive, or one exceeding the inflate bound (a probable zip bomb).
84
108
  */
85
- export declare function readWorkbookStream(data: Uint8Array, options?: ReadXlsxOptions): Generator<StreamedSheet, void, undefined>;
109
+ export declare function readWorkbookStream(data: Uint8Array, options?: ReadPackageOptions): Generator<StreamedSheet, void, undefined>;