@cj-tech-master/excelts 5.0.6 → 5.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 (273) hide show
  1. package/dist/browser/index.browser.d.ts +1 -1
  2. package/dist/browser/index.d.ts +1 -1
  3. package/dist/browser/modules/archive/unzip/stream.base.js +19 -19
  4. package/dist/browser/modules/archive/unzip/stream.browser.js +3 -3
  5. package/dist/browser/modules/csv/csv-core.js +6 -3
  6. package/dist/browser/modules/csv/csv.browser.js +2 -2
  7. package/dist/browser/modules/csv/csv.js +1 -1
  8. package/dist/browser/modules/excel/anchor.js +4 -4
  9. package/dist/browser/modules/excel/cell.js +5 -5
  10. package/dist/browser/modules/excel/column.js +4 -4
  11. package/dist/browser/modules/excel/defined-names.js +1 -1
  12. package/dist/browser/modules/excel/form-control.js +1 -1
  13. package/dist/browser/modules/excel/pivot-table.d.ts +168 -17
  14. package/dist/browser/modules/excel/pivot-table.js +278 -70
  15. package/dist/browser/modules/excel/row.js +4 -4
  16. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +4 -4
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +4 -4
  18. package/dist/browser/modules/excel/stream/worksheet-reader.js +1 -1
  19. package/dist/browser/modules/excel/stream/worksheet-writer.js +4 -4
  20. package/dist/browser/modules/excel/table.js +2 -2
  21. package/dist/browser/modules/excel/types.d.ts +0 -4
  22. package/dist/browser/modules/excel/utils/cell-format.js +3 -3
  23. package/dist/browser/modules/excel/utils/shared-formula.js +1 -1
  24. package/dist/browser/modules/excel/utils/stream-buf.js +2 -2
  25. package/dist/browser/modules/excel/utils/string-buf.js +1 -1
  26. package/dist/browser/modules/excel/workbook.d.ts +0 -2
  27. package/dist/browser/modules/excel/workbook.js +4 -5
  28. package/dist/browser/modules/excel/worksheet.js +9 -9
  29. package/dist/browser/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
  30. package/dist/browser/modules/excel/xlsx/xform/base-xform.js +1 -1
  31. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  32. package/dist/browser/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  33. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  34. package/dist/browser/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
  35. package/dist/browser/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
  36. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
  37. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  38. package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  39. package/dist/browser/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
  40. package/dist/browser/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
  41. package/dist/browser/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  42. package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
  43. package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  44. package/dist/browser/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
  45. package/dist/browser/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  46. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  47. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  48. package/dist/browser/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
  49. package/dist/browser/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
  50. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
  51. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
  52. package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
  53. package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  54. package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  55. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  56. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
  57. package/dist/browser/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
  58. package/dist/browser/modules/excel/xlsx/xform/list-xform.js +3 -3
  59. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
  60. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
  61. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
  62. package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
  63. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
  64. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
  65. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
  66. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
  67. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
  68. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  69. package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
  70. package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
  71. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  72. package/dist/browser/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  73. package/dist/browser/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  74. package/dist/browser/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  75. package/dist/browser/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  76. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  77. package/dist/browser/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  78. package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  79. package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
  80. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  81. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
  82. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  83. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  84. package/dist/browser/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  85. package/dist/browser/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  86. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  87. package/dist/browser/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
  88. package/dist/browser/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
  89. package/dist/browser/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
  90. package/dist/browser/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
  91. package/dist/browser/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
  92. package/dist/browser/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
  93. package/dist/browser/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
  94. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
  95. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +88 -54
  96. package/dist/browser/utils/env.d.ts +0 -5
  97. package/dist/browser/utils/env.js +0 -7
  98. package/dist/browser/utils/utils.base.d.ts +8 -13
  99. package/dist/browser/utils/utils.base.js +40 -47
  100. package/dist/browser/utils/utils.browser.d.ts +1 -1
  101. package/dist/browser/utils/utils.browser.js +1 -1
  102. package/dist/browser/utils/utils.d.ts +1 -1
  103. package/dist/browser/utils/utils.js +1 -1
  104. package/dist/cjs/modules/archive/unzip/stream.base.js +19 -19
  105. package/dist/cjs/modules/archive/unzip/stream.browser.js +3 -3
  106. package/dist/cjs/modules/csv/csv-core.js +6 -3
  107. package/dist/cjs/modules/csv/csv.browser.js +2 -2
  108. package/dist/cjs/modules/csv/csv.js +1 -1
  109. package/dist/cjs/modules/excel/anchor.js +4 -4
  110. package/dist/cjs/modules/excel/cell.js +5 -5
  111. package/dist/cjs/modules/excel/column.js +4 -4
  112. package/dist/cjs/modules/excel/defined-names.js +1 -1
  113. package/dist/cjs/modules/excel/form-control.js +1 -1
  114. package/dist/cjs/modules/excel/pivot-table.js +280 -70
  115. package/dist/cjs/modules/excel/row.js +4 -4
  116. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +4 -4
  117. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  118. package/dist/cjs/modules/excel/stream/worksheet-reader.js +1 -1
  119. package/dist/cjs/modules/excel/stream/worksheet-writer.js +4 -4
  120. package/dist/cjs/modules/excel/table.js +2 -2
  121. package/dist/cjs/modules/excel/utils/cell-format.js +3 -3
  122. package/dist/cjs/modules/excel/utils/shared-formula.js +1 -1
  123. package/dist/cjs/modules/excel/utils/stream-buf.js +2 -2
  124. package/dist/cjs/modules/excel/utils/string-buf.js +1 -1
  125. package/dist/cjs/modules/excel/workbook.js +4 -5
  126. package/dist/cjs/modules/excel/worksheet.js +9 -9
  127. package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +1 -1
  128. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  129. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  130. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  131. package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  132. package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  133. package/dist/cjs/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  134. package/dist/cjs/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  135. package/dist/cjs/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  136. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  137. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  138. package/dist/cjs/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  139. package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  140. package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  141. package/dist/cjs/modules/excel/xlsx/xform/list-xform.js +3 -3
  142. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +133 -51
  143. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field.js +245 -71
  144. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +212 -36
  145. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +142 -40
  146. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  147. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +153 -0
  148. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  149. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  150. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  151. package/dist/cjs/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  152. package/dist/cjs/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  153. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  154. package/dist/cjs/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  155. package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  156. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  157. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  158. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  159. package/dist/cjs/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  160. package/dist/cjs/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  161. package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  162. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +88 -54
  163. package/dist/cjs/utils/env.js +0 -8
  164. package/dist/cjs/utils/utils.base.js +41 -54
  165. package/dist/cjs/utils/utils.browser.js +2 -7
  166. package/dist/cjs/utils/utils.js +2 -7
  167. package/dist/esm/modules/archive/unzip/stream.base.js +19 -19
  168. package/dist/esm/modules/archive/unzip/stream.browser.js +3 -3
  169. package/dist/esm/modules/csv/csv-core.js +6 -3
  170. package/dist/esm/modules/csv/csv.browser.js +2 -2
  171. package/dist/esm/modules/csv/csv.js +1 -1
  172. package/dist/esm/modules/excel/anchor.js +4 -4
  173. package/dist/esm/modules/excel/cell.js +5 -5
  174. package/dist/esm/modules/excel/column.js +4 -4
  175. package/dist/esm/modules/excel/defined-names.js +1 -1
  176. package/dist/esm/modules/excel/form-control.js +1 -1
  177. package/dist/esm/modules/excel/pivot-table.js +278 -70
  178. package/dist/esm/modules/excel/row.js +4 -4
  179. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +4 -4
  180. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +4 -4
  181. package/dist/esm/modules/excel/stream/worksheet-reader.js +1 -1
  182. package/dist/esm/modules/excel/stream/worksheet-writer.js +4 -4
  183. package/dist/esm/modules/excel/table.js +2 -2
  184. package/dist/esm/modules/excel/utils/cell-format.js +3 -3
  185. package/dist/esm/modules/excel/utils/shared-formula.js +1 -1
  186. package/dist/esm/modules/excel/utils/stream-buf.js +2 -2
  187. package/dist/esm/modules/excel/utils/string-buf.js +1 -1
  188. package/dist/esm/modules/excel/workbook.js +4 -5
  189. package/dist/esm/modules/excel/worksheet.js +9 -9
  190. package/dist/esm/modules/excel/xlsx/xform/base-xform.js +1 -1
  191. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
  192. package/dist/esm/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
  193. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
  194. package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
  195. package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
  196. package/dist/esm/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
  197. package/dist/esm/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
  198. package/dist/esm/modules/excel/xlsx/xform/core/app-xform.js +1 -1
  199. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
  200. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  201. package/dist/esm/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
  202. package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
  203. package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
  204. package/dist/esm/modules/excel/xlsx/xform/list-xform.js +3 -3
  205. package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
  206. package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
  207. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
  208. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
  209. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
  210. package/dist/esm/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
  211. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
  212. package/dist/esm/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
  213. package/dist/esm/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
  214. package/dist/esm/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
  215. package/dist/esm/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
  216. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
  217. package/dist/esm/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
  218. package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
  219. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
  220. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
  221. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
  222. package/dist/esm/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
  223. package/dist/esm/modules/excel/xlsx/xform/style/color-xform.js +1 -1
  224. package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +5 -5
  225. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +88 -54
  226. package/dist/esm/utils/env.js +0 -7
  227. package/dist/esm/utils/utils.base.js +40 -47
  228. package/dist/esm/utils/utils.browser.js +1 -1
  229. package/dist/esm/utils/utils.js +1 -1
  230. package/dist/iife/excelts.iife.js +1553 -718
  231. package/dist/iife/excelts.iife.js.map +1 -1
  232. package/dist/iife/excelts.iife.min.js +36 -105
  233. package/dist/types/index.browser.d.ts +1 -1
  234. package/dist/types/index.d.ts +1 -1
  235. package/dist/types/modules/excel/pivot-table.d.ts +168 -17
  236. package/dist/types/modules/excel/types.d.ts +0 -4
  237. package/dist/types/modules/excel/workbook.d.ts +0 -2
  238. package/dist/types/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
  239. package/dist/types/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
  240. package/dist/types/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
  241. package/dist/types/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
  242. package/dist/types/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
  243. package/dist/types/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
  244. package/dist/types/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
  245. package/dist/types/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
  246. package/dist/types/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
  247. package/dist/types/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
  248. package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
  249. package/dist/types/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
  250. package/dist/types/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
  251. package/dist/types/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
  252. package/dist/types/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
  253. package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
  254. package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
  255. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
  256. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
  257. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
  258. package/dist/types/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
  259. package/dist/types/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
  260. package/dist/types/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
  261. package/dist/types/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
  262. package/dist/types/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
  263. package/dist/types/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
  264. package/dist/types/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
  265. package/dist/types/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
  266. package/dist/types/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
  267. package/dist/types/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
  268. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
  269. package/dist/types/utils/env.d.ts +0 -5
  270. package/dist/types/utils/utils.base.d.ts +8 -13
  271. package/dist/types/utils/utils.browser.d.ts +1 -1
  272. package/dist/types/utils/utils.d.ts +1 -1
  273. package/package.json +1 -1
@@ -1,5 +1,9 @@
1
1
  import { BaseXform } from "../base-xform.js";
2
- import { xmlDecode } from "../../../../../utils/utils.js";
2
+ import { PivotErrorValue } from "../../../pivot-table.js";
3
+ import { parseOoxmlDate } from "../../../../../utils/utils.js";
4
+ import { RawXmlCollector } from "./raw-xml-collector.js";
5
+ /** Attribute keys on <cacheField> that are individually parsed (not collected into extraAttrs). */
6
+ const KNOWN_CACHE_FIELD_KEYS = new Set(["name", "numFmtId"]);
3
7
  /**
4
8
  * Xform for parsing individual <cacheField> elements within a pivot cache definition.
5
9
  *
@@ -22,8 +26,9 @@ import { xmlDecode } from "../../../../../utils/utils.js";
22
26
  class CacheFieldXform extends BaseXform {
23
27
  constructor() {
24
28
  super();
25
- this.model = null;
26
29
  this.inSharedItems = false;
30
+ this.fieldGroupCollector = new RawXmlCollector("fieldGroup");
31
+ this.model = null;
27
32
  }
28
33
  get tag() {
29
34
  return "cacheField";
@@ -31,89 +36,123 @@ class CacheFieldXform extends BaseXform {
31
36
  reset() {
32
37
  this.model = null;
33
38
  this.inSharedItems = false;
39
+ this.fieldGroupCollector.reset();
34
40
  }
35
41
  parseOpen(node) {
36
42
  const { name, attributes } = node;
43
+ // Collect fieldGroup XML verbatim for roundtrip preservation
44
+ if (this.fieldGroupCollector.active) {
45
+ this.fieldGroupCollector.feedOpen(name, attributes);
46
+ return true;
47
+ }
37
48
  switch (name) {
38
- case "cacheField":
49
+ case "cacheField": {
39
50
  // Initialize the model with field name
51
+ // Collect unknown attributes into extraAttrs bag for roundtrip preservation
52
+ const extraAttrs = {};
53
+ for (const [k, v] of Object.entries(attributes)) {
54
+ if (!KNOWN_CACHE_FIELD_KEYS.has(k)) {
55
+ extraAttrs[k] = String(v);
56
+ }
57
+ }
40
58
  this.model = {
41
- name: xmlDecode(attributes.name || ""),
42
- sharedItems: null
59
+ name: attributes.name ?? "",
60
+ sharedItems: null,
61
+ numFmtId: attributes.numFmtId,
62
+ isLoaded: true,
63
+ extraAttrs: Object.keys(extraAttrs).length > 0 ? extraAttrs : undefined
43
64
  };
44
65
  break;
66
+ }
67
+ case "fieldGroup":
68
+ // Start collecting fieldGroup XML for roundtrip preservation
69
+ if (this.model) {
70
+ this.fieldGroupCollector.start(attributes);
71
+ }
72
+ break;
45
73
  case "sharedItems":
46
74
  this.inSharedItems = true;
47
75
  // Store numeric field metadata
48
76
  if (this.model) {
49
- this.model.containsNumber = attributes.containsNumber === "1";
50
- this.model.containsInteger = attributes.containsInteger === "1";
77
+ // R8-B4: Store containsNumber/containsInteger as raw strings for roundtrip fidelity.
78
+ // Previously "0" was lost because it was parsed as undefined.
79
+ if (attributes.containsNumber !== undefined) {
80
+ this.model.containsNumber = attributes.containsNumber;
81
+ }
82
+ if (attributes.containsInteger !== undefined) {
83
+ this.model.containsInteger = attributes.containsInteger;
84
+ }
85
+ // R8-B7: Guard against NaN from malformed minValue/maxValue
51
86
  if (attributes.minValue !== undefined) {
52
- this.model.minValue = parseFloat(attributes.minValue);
87
+ const parsed = parseFloat(attributes.minValue);
88
+ if (Number.isFinite(parsed)) {
89
+ this.model.minValue = parsed;
90
+ }
53
91
  }
54
92
  if (attributes.maxValue !== undefined) {
55
- this.model.maxValue = parseFloat(attributes.maxValue);
93
+ const parsed = parseFloat(attributes.maxValue);
94
+ if (Number.isFinite(parsed)) {
95
+ this.model.maxValue = parsed;
96
+ }
97
+ }
98
+ // Preserve original sharedItems type attributes for roundtrip fidelity.
99
+ // These are stored as raw strings so we can re-emit them exactly as loaded.
100
+ if (attributes.containsSemiMixedTypes !== undefined) {
101
+ this.model.containsSemiMixedTypes = attributes.containsSemiMixedTypes;
102
+ }
103
+ if (attributes.containsNonDate !== undefined) {
104
+ this.model.containsNonDate = attributes.containsNonDate;
105
+ }
106
+ if (attributes.containsString !== undefined) {
107
+ this.model.containsString = attributes.containsString;
56
108
  }
57
- // Initialize sharedItems array if count > 0 (for both string and numeric fields)
58
- const count = parseInt(attributes.count || "0", 10);
59
- if (count > 0) {
60
- this.model.sharedItems = [];
109
+ if (attributes.containsBlank !== undefined) {
110
+ this.model.containsBlank = attributes.containsBlank;
61
111
  }
62
- else {
63
- // No count means no individual items (pure numeric field)
64
- this.model.sharedItems = null;
112
+ if (attributes.containsDate !== undefined) {
113
+ this.model.containsDate = attributes.containsDate;
65
114
  }
115
+ if (attributes.containsMixedTypes !== undefined) {
116
+ this.model.containsMixedTypes = attributes.containsMixedTypes;
117
+ }
118
+ // Initialize sharedItems array when sharedItems element is present.
119
+ // count="0" means an explicitly empty shared items list (not the same as absent).
120
+ // No count attribute also gets an empty array since the <sharedItems> element
121
+ // itself is present — child elements (<s>, <n>, etc.) will be pushed into it.
122
+ this.model.sharedItems = [];
66
123
  }
67
124
  break;
68
125
  case "s":
69
- // String value in sharedItems
70
- if (this.inSharedItems && this.model?.sharedItems !== null) {
71
- // Decode XML entities in the value
72
- const value = xmlDecode(attributes.v || "");
73
- this.model.sharedItems.push(value);
74
- }
75
- break;
76
126
  case "n":
77
- // Numeric value in sharedItems (less common, but possible)
78
- if (this.inSharedItems && this.model?.sharedItems !== null) {
79
- const value = parseFloat(attributes.v || "0");
80
- this.model.sharedItems.push(value);
81
- }
82
- break;
83
127
  case "b":
84
- // Boolean value in sharedItems
85
- if (this.inSharedItems && this.model?.sharedItems !== null) {
86
- const value = attributes.v === "1";
87
- this.model.sharedItems.push(value);
88
- }
89
- break;
90
128
  case "e":
91
- // Error value in sharedItems
92
- if (this.inSharedItems && this.model?.sharedItems !== null) {
93
- const value = `#${attributes.v || "ERROR!"}`;
94
- this.model.sharedItems.push(value);
95
- }
96
- break;
97
129
  case "m":
98
- // Missing/null value in sharedItems
99
- if (this.inSharedItems && this.model?.sharedItems !== null) {
100
- this.model.sharedItems.push(null);
101
- }
102
- break;
103
130
  case "d":
104
- // Date value in sharedItems
105
- if (this.inSharedItems && this.model?.sharedItems !== null) {
106
- const value = new Date(attributes.v || "");
107
- this.model.sharedItems.push(value);
131
+ // Shared item value push to sharedItems array if we're inside <sharedItems>
132
+ if (this.inSharedItems && this.model && this.model.sharedItems !== null) {
133
+ this.model.sharedItems.push(parseSharedItemValue(name, attributes));
108
134
  }
109
135
  break;
110
136
  }
111
137
  return true;
112
138
  }
113
- parseText(_text) {
114
- // No text content in cacheField elements
139
+ parseText(text) {
140
+ // Forward text to active collector (B3 fix: text nodes in fieldGroup)
141
+ if (this.fieldGroupCollector.active) {
142
+ this.fieldGroupCollector.feedText(text);
143
+ }
115
144
  }
116
145
  parseClose(name) {
146
+ // Handle fieldGroup collection — close tags
147
+ if (this.fieldGroupCollector.active) {
148
+ if (this.fieldGroupCollector.feedClose(name)) {
149
+ if (this.model) {
150
+ this.model.fieldGroupXml = this.fieldGroupCollector.result;
151
+ }
152
+ this.fieldGroupCollector.reset();
153
+ }
154
+ return true;
155
+ }
117
156
  switch (name) {
118
157
  case "cacheField":
119
158
  // End of this cacheField element
@@ -125,4 +164,47 @@ class CacheFieldXform extends BaseXform {
125
164
  return true;
126
165
  }
127
166
  }
167
+ // ---------------------------------------------------------------------------
168
+ // Helpers
169
+ // ---------------------------------------------------------------------------
170
+ /**
171
+ * Convert a SAX-parsed shared item element into its typed value.
172
+ *
173
+ * Tag mapping:
174
+ * - `s` → string
175
+ * - `n` → number
176
+ * - `b` → boolean
177
+ * - `e` → PivotErrorValue
178
+ * - `m` → null (missing)
179
+ * - `d` → Date (UTC)
180
+ */
181
+ function parseSharedItemValue(tag, attributes) {
182
+ switch (tag) {
183
+ case "s":
184
+ return attributes.v ?? "";
185
+ case "n":
186
+ // Missing v attribute → treat as null (missing) rather than fabricating 0
187
+ if (attributes.v === undefined || attributes.v === "") {
188
+ return null;
189
+ }
190
+ return parseFloat(attributes.v);
191
+ case "b":
192
+ return attributes.v === "1";
193
+ case "e":
194
+ return new PivotErrorValue(attributes.v ?? "");
195
+ case "m":
196
+ return null;
197
+ case "d": {
198
+ // Missing/empty v attribute → treat as missing value (null) to avoid Invalid Date
199
+ if (!attributes.v) {
200
+ return null;
201
+ }
202
+ // R8-B13: Guard against Invalid Date from malformed date strings
203
+ const date = parseOoxmlDate(attributes.v);
204
+ return isNaN(date.getTime()) ? null : date;
205
+ }
206
+ default:
207
+ return null;
208
+ }
209
+ }
128
210
  export { CacheFieldXform };
@@ -1,78 +1,252 @@
1
1
  import { xmlEncode } from "../../../../../utils/utils.js";
2
- class CacheField {
3
- constructor({ name, sharedItems, minValue, maxValue }) {
4
- // string type
5
- //
6
- // {
7
- // 'name': 'A',
8
- // 'sharedItems': ['a1', 'a2', 'a3']
9
- // }
10
- //
11
- // or
12
- //
13
- // integer type (no sharedItems)
14
- //
15
- // {
16
- // 'name': 'D',
17
- // 'sharedItems': null,
18
- // 'minValue': 5,
19
- // 'maxValue': 45
20
- // }
21
- //
22
- // or
23
- //
24
- // numeric type with shared items (used as both row/column and value field)
25
- //
26
- // {
27
- // 'name': 'C',
28
- // 'sharedItems': [5, 24, 35, 45]
29
- // }
30
- this.name = name;
31
- this.sharedItems = sharedItems;
32
- this.minValue = minValue;
33
- this.maxValue = maxValue;
34
- }
35
- render() {
36
- // PivotCache Field: http://www.datypic.com/sc/ooxml/e-ssml_cacheField-1.html
37
- // Shared Items: http://www.datypic.com/sc/ooxml/e-ssml_sharedItems-1.html
38
- // Escape XML special characters in name attribute
39
- const escapedName = xmlEncode(this.name);
40
- // No shared items - field not used for rows/columns
41
- if (this.sharedItems === null) {
42
- // If no minValue/maxValue, this is an unused field - use empty sharedItems like Excel does
43
- if (this.minValue === undefined || this.maxValue === undefined) {
44
- return `<cacheField name="${escapedName}" numFmtId="0">
45
- <sharedItems />
46
- </cacheField>`;
2
+ import { PivotErrorValue } from "../../../pivot-table.js";
3
+ /**
4
+ * Format a Date for OOXML pivot cache output.
5
+ * Excel expects `"2024-01-15T00:00:00"` — no milliseconds, no trailing "Z".
6
+ */
7
+ function formatDateForExcel(date) {
8
+ // Guard against Invalid Date — toISOString() throws RangeError for invalid dates
9
+ if (isNaN(date.getTime())) {
10
+ return "";
11
+ }
12
+ return date.toISOString().replace(/\.\d{3}Z$/, "");
13
+ }
14
+ /**
15
+ * Render a single `<cacheField>` element as an XML string.
16
+ *
17
+ * This is a pure data-in → string-out transformation with no state or lifecycle,
18
+ * so it is a plain function rather than a class.
19
+ */
20
+ function renderCacheField(cf) {
21
+ // PivotCache Field: http://www.datypic.com/sc/ooxml/e-ssml_cacheField-1.html
22
+ // Shared Items: http://www.datypic.com/sc/ooxml/e-ssml_sharedItems-1.html
23
+ // Escape XML special characters in name attribute
24
+ const escapedName = xmlEncode(cf.name);
25
+ const fmtId = cf.numFmtId ?? "0";
26
+ // Extra unknown attributes for roundtrip preservation (e.g. caption, formula)
27
+ const extraStr = buildExtraAttrsStr(cf.extraAttrs);
28
+ // fieldGroup raw XML for roundtrip (rendered after sharedItems per OOXML schema)
29
+ const fgXml = cf.fieldGroupXml ? `\n ${cf.fieldGroupXml}` : "";
30
+ // --- Branch A: no shared-item children ---
31
+ // For loaded fields, only render <sharedItems> if it was present in the original (sharedItems !== null).
32
+ // For new fields, sharedItems === null means a value-only field that still needs <sharedItems />.
33
+ if (cf.sharedItems === null) {
34
+ if (cf.isLoaded) {
35
+ // Loaded field with no <sharedItems> element — don't add one on roundtrip
36
+ if (fgXml) {
37
+ // Has fieldGroup — need open/close tags to wrap it
38
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr}>${fgXml}\n </cacheField>`;
47
39
  }
48
- // Numeric field used only for values (not rows/columns) - include min/max
49
- return `<cacheField name="${escapedName}" numFmtId="0">
50
- <sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1" containsInteger="1" minValue="${this.minValue}" maxValue="${this.maxValue}" />
51
- </cacheField>`;
40
+ // R8-B6: No children at all use self-closing tag to avoid whitespace content
41
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr} />`;
42
+ }
43
+ // New field — render bare empty <sharedItems />
44
+ let attrStr;
45
+ if (cf.minValue !== undefined && cf.maxValue !== undefined) {
46
+ // New numeric-only field (no row/column usage) – compute type attributes
47
+ const integerAttr = cf.containsInteger ? ' containsInteger="1"' : "";
48
+ attrStr = ` containsSemiMixedTypes="0" containsString="0" containsNumber="1"${integerAttr} minValue="${cf.minValue}" maxValue="${cf.maxValue}"`;
49
+ }
50
+ else {
51
+ attrStr = "";
52
52
  }
53
- // Shared items exist - check if all values are numeric
54
- // Note: empty array returns true for every(), so check length first
55
- const allNumeric = this.sharedItems.length > 0 &&
56
- this.sharedItems.every(item => typeof item === "number" && Number.isFinite(item));
57
- const allInteger = allNumeric && this.sharedItems.every(item => Number.isInteger(item));
58
- if (allNumeric) {
59
- // Numeric shared items - used when field is both a row/column field AND a value field
60
- // This allows Excel to both group by unique values AND perform aggregation
61
- const minValue = Math.min(...this.sharedItems);
62
- const maxValue = Math.max(...this.sharedItems);
63
- const integerAttr = allInteger ? ' containsInteger="1"' : "";
64
- return `<cacheField name="${escapedName}" numFmtId="0">
65
- <sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1"${integerAttr} minValue="${minValue}" maxValue="${maxValue}" count="${this.sharedItems.length}">
66
- ${this.sharedItems.map(item => `<n v="${item}" />`).join("")}
67
- </sharedItems>
53
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr}>
54
+ <sharedItems${attrStr} />${fgXml}
68
55
  </cacheField>`;
56
+ }
57
+ if (cf.isLoaded && cf.sharedItems.length === 0) {
58
+ // Roundtrip: use preserved attributes exactly as parsed
59
+ const attrStr = buildLoadedSharedItemsAttrs(cf);
60
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr}>
61
+ <sharedItems${attrStr} />${fgXml}
62
+ </cacheField>`;
63
+ }
64
+ // --- Branch B: shared items present – render each child element ---
65
+ // For loaded fields, skip recomputation – use preserved attributes directly
66
+ if (cf.isLoaded) {
67
+ const itemXmls = renderSharedItemElements(cf.sharedItems);
68
+ const finalAttrStr = buildLoadedSharedItemsAttrs(cf);
69
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr}>
70
+ <sharedItems${finalAttrStr} count="${cf.sharedItems.length}">
71
+ ${itemXmls}
72
+ </sharedItems>${fgXml}
73
+ </cacheField>`;
74
+ }
75
+ // New field – analyze content types in a single pass (avoids stack overflow from spread on large arrays)
76
+ let hasString = false;
77
+ let hasNumber = false;
78
+ let hasBoolean = false;
79
+ let hasDate = false;
80
+ let hasNull = false;
81
+ let hasError = false;
82
+ let allInteger = true;
83
+ let minValue = Infinity;
84
+ let maxValue = -Infinity;
85
+ for (const item of cf.sharedItems) {
86
+ if (item === null) {
87
+ hasNull = true;
88
+ }
89
+ else if (item instanceof PivotErrorValue) {
90
+ hasError = true;
69
91
  }
70
- // String shared items - escape XML special characters in each value
71
- return `<cacheField name="${escapedName}" numFmtId="0">
72
- <sharedItems count="${this.sharedItems.length}">
73
- ${this.sharedItems.map(item => `<s v="${xmlEncode(String(item))}" />`).join("")}
74
- </sharedItems>
92
+ else if (typeof item === "string") {
93
+ hasString = true;
94
+ }
95
+ else if (typeof item === "number") {
96
+ if (Number.isFinite(item)) {
97
+ hasNumber = true;
98
+ if (item < minValue) {
99
+ minValue = item;
100
+ }
101
+ if (item > maxValue) {
102
+ maxValue = item;
103
+ }
104
+ if (!Number.isInteger(item)) {
105
+ allInteger = false;
106
+ }
107
+ }
108
+ else {
109
+ // NaN, Infinity, -Infinity are not valid OOXML numeric values — treat as missing
110
+ hasNull = true;
111
+ }
112
+ }
113
+ else if (typeof item === "boolean") {
114
+ hasBoolean = true;
115
+ }
116
+ else if (item instanceof Date) {
117
+ hasDate = true;
118
+ }
119
+ }
120
+ // Build sharedItems attributes per OOXML spec:
121
+ // - containsSemiMixedTypes: "0" if no strings at all (default "1")
122
+ // - containsString: "0" if no string items (default "1")
123
+ // - containsNumber: "1" if any numeric items (default "0")
124
+ // - containsInteger: "1" if all numbers are integers (only when containsNumber="1")
125
+ // - containsBlank: "1" if any null/missing items
126
+ // - containsMixedTypes: "1" if multiple non-string types present
127
+ // - containsDate: "1" if any date items (default "0")
128
+ const attrs = [];
129
+ if (!hasString) {
130
+ // No string items at all (errors, numbers, booleans, dates, nulls are all non-string)
131
+ attrs.push('containsSemiMixedTypes="0"');
132
+ attrs.push('containsString="0"');
133
+ }
134
+ // containsMixedTypes: set when multiple distinct non-string type families are present
135
+ // e.g., number+date, string+number, error+number, etc.
136
+ const typeCount = (hasString ? 1 : 0) +
137
+ (hasNumber ? 1 : 0) +
138
+ (hasBoolean ? 1 : 0) +
139
+ (hasDate ? 1 : 0) +
140
+ (hasError ? 1 : 0);
141
+ if (typeCount > 1) {
142
+ attrs.push('containsMixedTypes="1"');
143
+ }
144
+ if (hasNumber) {
145
+ attrs.push('containsNumber="1"');
146
+ if (allInteger) {
147
+ attrs.push('containsInteger="1"');
148
+ }
149
+ attrs.push(`minValue="${minValue}"`);
150
+ attrs.push(`maxValue="${maxValue}"`);
151
+ }
152
+ if (hasDate) {
153
+ attrs.push('containsDate="1"');
154
+ }
155
+ if (hasNull) {
156
+ attrs.push('containsBlank="1"');
157
+ }
158
+ const itemXmls = renderSharedItemElements(cf.sharedItems);
159
+ const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
160
+ return `<cacheField name="${escapedName}" numFmtId="${fmtId}"${extraStr}>
161
+ <sharedItems${attrStr} count="${cf.sharedItems.length}">
162
+ ${itemXmls}
163
+ </sharedItems>${fgXml}
75
164
  </cacheField>`;
165
+ }
166
+ /**
167
+ * Render shared item elements as an XML string.
168
+ */
169
+ function renderSharedItemElements(sharedItems) {
170
+ const itemXmls = [];
171
+ for (const item of sharedItems) {
172
+ if (item === null) {
173
+ itemXmls.push("<m />");
174
+ }
175
+ else if (item instanceof PivotErrorValue) {
176
+ itemXmls.push(`<e v="${xmlEncode(item.code)}" />`);
177
+ }
178
+ else if (typeof item === "number") {
179
+ if (Number.isFinite(item)) {
180
+ itemXmls.push(`<n v="${item}" />`);
181
+ }
182
+ else {
183
+ // NaN, Infinity, -Infinity — not valid in OOXML, render as missing
184
+ itemXmls.push("<m />");
185
+ }
186
+ }
187
+ else if (typeof item === "boolean") {
188
+ itemXmls.push(`<b v="${item ? "1" : "0"}" />`);
189
+ }
190
+ else if (item instanceof Date) {
191
+ itemXmls.push(`<d v="${formatDateForExcel(item)}" />`);
192
+ }
193
+ else {
194
+ // string
195
+ itemXmls.push(`<s v="${xmlEncode(item)}" />`);
196
+ }
197
+ }
198
+ return itemXmls.join("");
199
+ }
200
+ /**
201
+ * Build extra attributes string for cacheField element (roundtrip preservation).
202
+ */
203
+ function buildExtraAttrsStr(extraAttrs) {
204
+ if (!extraAttrs) {
205
+ return "";
206
+ }
207
+ return Object.entries(extraAttrs)
208
+ .map(([k, v]) => ` ${k}="${xmlEncode(v)}"`)
209
+ .join("");
210
+ }
211
+ /**
212
+ * Build sharedItems attribute string from preserved loaded attributes.
213
+ * Reconstructs the original attribute order for roundtrip fidelity.
214
+ */
215
+ function buildLoadedSharedItemsAttrs(cf) {
216
+ const parts = [];
217
+ if (cf.containsSemiMixedTypes !== undefined) {
218
+ parts.push(`containsSemiMixedTypes="${cf.containsSemiMixedTypes}"`);
219
+ }
220
+ if (cf.containsNonDate !== undefined) {
221
+ parts.push(`containsNonDate="${cf.containsNonDate}"`);
222
+ }
223
+ if (cf.containsString !== undefined) {
224
+ parts.push(`containsString="${cf.containsString}"`);
225
+ }
226
+ if (cf.containsBlank !== undefined) {
227
+ parts.push(`containsBlank="${cf.containsBlank}"`);
228
+ }
229
+ if (cf.containsMixedTypes !== undefined) {
230
+ parts.push(`containsMixedTypes="${cf.containsMixedTypes}"`);
231
+ }
232
+ // R8-B4: containsNumber/containsInteger are now raw strings ("0"/"1") for roundtrip fidelity
233
+ if (cf.containsNumber !== undefined) {
234
+ parts.push(`containsNumber="${cf.containsNumber}"`);
235
+ }
236
+ if (cf.containsInteger !== undefined) {
237
+ parts.push(`containsInteger="${cf.containsInteger}"`);
238
+ }
239
+ // R8-B5: Emit minValue/maxValue independently of containsNumber — the original XML
240
+ // may have these attributes even without containsNumber="1"
241
+ if (cf.minValue !== undefined) {
242
+ parts.push(`minValue="${cf.minValue}"`);
243
+ }
244
+ if (cf.maxValue !== undefined) {
245
+ parts.push(`maxValue="${cf.maxValue}"`);
246
+ }
247
+ if (cf.containsDate !== undefined) {
248
+ parts.push(`containsDate="${cf.containsDate}"`);
76
249
  }
250
+ return parts.length > 0 ? ` ${parts.join(" ")}` : "";
77
251
  }
78
- export { CacheField };
252
+ export { renderCacheField, formatDateForExcel };