@nhtio/adk 0.1.0-master-e6c58205 → 0.1.0-master-89b47bec

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 (290) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/__vite-browser-external-CU7uua8b.mjs +9 -0
  3. package/__vite-browser-external-CU7uua8b.mjs.map +1 -0
  4. package/__vite-browser-external-DAHxjh-D.js +13 -0
  5. package/__vite-browser-external-DAHxjh-D.js.map +1 -0
  6. package/batteries/embeddings/openai/adapter.cjs +1 -1
  7. package/batteries/embeddings/openai/adapter.mjs +1 -1
  8. package/batteries/embeddings/webllm/adapter.cjs +1 -1
  9. package/batteries/embeddings/webllm/adapter.mjs +1 -1
  10. package/batteries/llm/ollama/adapter.cjs +5 -5
  11. package/batteries/llm/ollama/adapter.mjs +5 -5
  12. package/batteries/llm/ollama/helpers.cjs +2 -2
  13. package/batteries/llm/ollama/helpers.mjs +2 -2
  14. package/batteries/llm/ollama/validation.cjs +1 -1
  15. package/batteries/llm/ollama/validation.mjs +1 -1
  16. package/batteries/llm/openai_chat_completions/adapter.cjs +5 -5
  17. package/batteries/llm/openai_chat_completions/adapter.mjs +5 -5
  18. package/batteries/llm/openai_chat_completions/helpers.cjs +2 -2
  19. package/batteries/llm/openai_chat_completions/helpers.mjs +2 -2
  20. package/batteries/llm/openai_chat_completions/validation.cjs +1 -1
  21. package/batteries/llm/openai_chat_completions/validation.mjs +1 -1
  22. package/batteries/llm/webllm_chat_completions/adapter.cjs +5 -5
  23. package/batteries/llm/webllm_chat_completions/adapter.mjs +5 -5
  24. package/batteries/llm/webllm_chat_completions/validation.cjs +1 -1
  25. package/batteries/llm/webllm_chat_completions/validation.mjs +1 -1
  26. package/batteries/media/contracts.cjs +38 -8
  27. package/batteries/media/contracts.cjs.map +1 -1
  28. package/batteries/media/contracts.d.ts +86 -6
  29. package/batteries/media/contracts.mjs +37 -9
  30. package/batteries/media/contracts.mjs.map +1 -1
  31. package/batteries/media/engines/audio_decode.cjs +46 -6
  32. package/batteries/media/engines/audio_decode.cjs.map +1 -1
  33. package/batteries/media/engines/audio_decode.d.ts +9 -5
  34. package/batteries/media/engines/audio_decode.mjs +47 -7
  35. package/batteries/media/engines/audio_decode.mjs.map +1 -1
  36. package/batteries/media/engines/data.cjs +159 -0
  37. package/batteries/media/engines/data.cjs.map +1 -0
  38. package/batteries/media/engines/data.d.ts +36 -0
  39. package/batteries/media/engines/data.mjs +157 -0
  40. package/batteries/media/engines/data.mjs.map +1 -0
  41. package/batteries/media/engines/exceljs.cjs +290 -0
  42. package/batteries/media/engines/exceljs.cjs.map +1 -0
  43. package/batteries/media/engines/exceljs.d.ts +41 -0
  44. package/batteries/media/engines/exceljs.mjs +288 -0
  45. package/batteries/media/engines/exceljs.mjs.map +1 -0
  46. package/batteries/media/engines/execa_executor.cjs +1 -1
  47. package/batteries/media/engines/execa_executor.mjs +1 -1
  48. package/batteries/media/engines/fs_workspace.cjs +1 -1
  49. package/batteries/media/engines/fs_workspace.mjs +1 -1
  50. package/batteries/media/engines/jimp.cjs +24 -2
  51. package/batteries/media/engines/jimp.cjs.map +1 -1
  52. package/batteries/media/engines/jimp.d.ts +3 -1
  53. package/batteries/media/engines/jimp.mjs +24 -2
  54. package/batteries/media/engines/jimp.mjs.map +1 -1
  55. package/batteries/media/engines/sharp.cjs +37 -4
  56. package/batteries/media/engines/sharp.cjs.map +1 -1
  57. package/batteries/media/engines/sharp.d.ts +5 -3
  58. package/batteries/media/engines/sharp.mjs +37 -4
  59. package/batteries/media/engines/sharp.mjs.map +1 -1
  60. package/batteries/media/engines/sheetjs.cjs +438 -0
  61. package/batteries/media/engines/sheetjs.cjs.map +1 -0
  62. package/batteries/media/engines/sheetjs.d.ts +51 -0
  63. package/batteries/media/engines/sheetjs.mjs +436 -0
  64. package/batteries/media/engines/sheetjs.mjs.map +1 -0
  65. package/batteries/media/engines/soffice.cjs +37 -3
  66. package/batteries/media/engines/soffice.cjs.map +1 -1
  67. package/batteries/media/engines/soffice.mjs +38 -4
  68. package/batteries/media/engines/soffice.mjs.map +1 -1
  69. package/batteries/media/engines/tesseract_js.cjs +1 -1
  70. package/batteries/media/engines/tesseract_js.mjs +1 -1
  71. package/batteries/media/engines/transformers_asr.cjs +1 -1
  72. package/batteries/media/engines/transformers_asr.mjs +1 -1
  73. package/batteries/media/forge.cjs +89 -20
  74. package/batteries/media/forge.cjs.map +1 -1
  75. package/batteries/media/forge.mjs +89 -20
  76. package/batteries/media/forge.mjs.map +1 -1
  77. package/batteries/media/formats.d.ts +9 -0
  78. package/batteries/media/index.d.ts +8 -6
  79. package/batteries/media/lint.cjs +270 -58
  80. package/batteries/media/lint.cjs.map +1 -1
  81. package/batteries/media/lint.d.ts +45 -0
  82. package/batteries/media/lint.mjs +267 -58
  83. package/batteries/media/lint.mjs.map +1 -1
  84. package/batteries/media/registry.d.ts +11 -2
  85. package/batteries/media/steps/data.d.ts +26 -0
  86. package/batteries/media/steps/doc.d.ts +17 -7
  87. package/batteries/media/steps/patch.d.ts +90 -0
  88. package/batteries/media/steps/sheet.d.ts +10 -6
  89. package/batteries/media/steps/text.d.ts +4 -1
  90. package/batteries/media/validate.d.ts +5 -0
  91. package/batteries/media/verbs.d.ts +12 -1
  92. package/batteries/media.cjs +869 -448
  93. package/batteries/media.cjs.map +1 -1
  94. package/batteries/media.mjs +829 -409
  95. package/batteries/media.mjs.map +1 -1
  96. package/batteries/storage/flydrive.cjs +3 -6
  97. package/batteries/storage/flydrive.cjs.map +1 -1
  98. package/batteries/storage/flydrive.mjs +3 -6
  99. package/batteries/storage/flydrive.mjs.map +1 -1
  100. package/batteries/storage/in_memory.cjs +1 -1
  101. package/batteries/storage/in_memory.mjs +1 -1
  102. package/batteries/storage/opfs.cjs +1 -1
  103. package/batteries/storage/opfs.mjs +1 -1
  104. package/batteries/tools/_shared.cjs +2 -2
  105. package/batteries/tools/_shared.mjs +2 -2
  106. package/batteries/tools/color.cjs +2 -2
  107. package/batteries/tools/color.mjs +2 -2
  108. package/batteries/tools/comparison.cjs +3 -3
  109. package/batteries/tools/comparison.mjs +3 -3
  110. package/batteries/tools/data_structure.cjs +3 -3
  111. package/batteries/tools/data_structure.mjs +3 -3
  112. package/batteries/tools/datetime_extended.cjs +3 -3
  113. package/batteries/tools/datetime_extended.mjs +3 -3
  114. package/batteries/tools/datetime_math.cjs +3 -3
  115. package/batteries/tools/datetime_math.mjs +3 -3
  116. package/batteries/tools/encoding.cjs +3 -3
  117. package/batteries/tools/encoding.mjs +3 -3
  118. package/batteries/tools/formatting.cjs +3 -3
  119. package/batteries/tools/formatting.mjs +3 -3
  120. package/batteries/tools/geo_basics.cjs +2 -2
  121. package/batteries/tools/geo_basics.mjs +2 -2
  122. package/batteries/tools/math.cjs +3 -3
  123. package/batteries/tools/math.mjs +3 -3
  124. package/batteries/tools/memory.cjs +6 -6
  125. package/batteries/tools/memory.mjs +6 -6
  126. package/batteries/tools/parsing.cjs +4 -4
  127. package/batteries/tools/parsing.mjs +4 -4
  128. package/batteries/tools/retrievables.cjs +5 -5
  129. package/batteries/tools/retrievables.mjs +5 -5
  130. package/batteries/tools/scrapper.cjs +1 -1
  131. package/batteries/tools/scrapper.mjs +1 -1
  132. package/batteries/tools/searxng.cjs +1 -1
  133. package/batteries/tools/searxng.mjs +1 -1
  134. package/batteries/tools/standing_instructions.cjs +4 -4
  135. package/batteries/tools/standing_instructions.mjs +4 -4
  136. package/batteries/tools/statistics.cjs +4 -4
  137. package/batteries/tools/statistics.mjs +4 -4
  138. package/batteries/tools/string_processing.cjs +3 -3
  139. package/batteries/tools/string_processing.mjs +3 -3
  140. package/batteries/tools/structured_data.cjs +3 -3
  141. package/batteries/tools/structured_data.mjs +3 -3
  142. package/batteries/tools/text_analysis.cjs +3 -3
  143. package/batteries/tools/text_analysis.mjs +3 -3
  144. package/batteries/tools/text_comparison.cjs +2 -2
  145. package/batteries/tools/text_comparison.mjs +2 -2
  146. package/batteries/tools/time.cjs +3 -3
  147. package/batteries/tools/time.mjs +3 -3
  148. package/batteries/tools/unit_conversion.cjs +2 -2
  149. package/batteries/tools/unit_conversion.mjs +2 -2
  150. package/batteries/tools/web_retrieval.cjs +1 -1
  151. package/batteries/tools/web_retrieval.mjs +1 -1
  152. package/batteries/tools.cjs +2 -2
  153. package/batteries/tools.mjs +2 -2
  154. package/batteries/vector/arangodb.cjs +1 -1
  155. package/batteries/vector/arangodb.mjs +1 -1
  156. package/batteries/vector/clickhouse.cjs +1 -1
  157. package/batteries/vector/clickhouse.mjs +1 -1
  158. package/batteries/vector/cloudflare.cjs +1 -1
  159. package/batteries/vector/cloudflare.mjs +1 -1
  160. package/batteries/vector/couchbase.cjs +1 -1
  161. package/batteries/vector/couchbase.mjs +1 -1
  162. package/batteries/vector/duckdb.cjs +1 -1
  163. package/batteries/vector/duckdb.mjs +1 -1
  164. package/batteries/vector/elasticsearch.cjs +1 -1
  165. package/batteries/vector/elasticsearch.mjs +1 -1
  166. package/batteries/vector/filters.cjs +1 -1
  167. package/batteries/vector/filters.mjs +1 -1
  168. package/batteries/vector/hnswlib.cjs +1 -1
  169. package/batteries/vector/hnswlib.mjs +1 -1
  170. package/batteries/vector/lancedb.cjs +1 -1
  171. package/batteries/vector/lancedb.mjs +1 -1
  172. package/batteries/vector/mariadb.cjs +1 -1
  173. package/batteries/vector/mariadb.mjs +1 -1
  174. package/batteries/vector/meilisearch.cjs +1 -1
  175. package/batteries/vector/meilisearch.mjs +1 -1
  176. package/batteries/vector/migrate.cjs +1 -1
  177. package/batteries/vector/migrate.mjs +1 -1
  178. package/batteries/vector/mongodb.cjs +1 -1
  179. package/batteries/vector/mongodb.mjs +1 -1
  180. package/batteries/vector/neo4j.cjs +1 -1
  181. package/batteries/vector/neo4j.mjs +1 -1
  182. package/batteries/vector/opensearch.cjs +1 -1
  183. package/batteries/vector/opensearch.mjs +1 -1
  184. package/batteries/vector/oracle23ai.cjs +1 -1
  185. package/batteries/vector/oracle23ai.mjs +1 -1
  186. package/batteries/vector/pinecone.cjs +1 -1
  187. package/batteries/vector/pinecone.mjs +1 -1
  188. package/batteries/vector/redis.cjs +1 -1
  189. package/batteries/vector/redis.mjs +1 -1
  190. package/batteries/vector/retrievable.cjs +1 -1
  191. package/batteries/vector/retrievable.mjs +1 -1
  192. package/batteries/vector/s3vectors.cjs +1 -1
  193. package/batteries/vector/s3vectors.mjs +1 -1
  194. package/batteries/vector/solr.cjs +1 -1
  195. package/batteries/vector/solr.mjs +1 -1
  196. package/batteries/vector/surrealdb.cjs +1 -1
  197. package/batteries/vector/surrealdb.mjs +1 -1
  198. package/batteries/vector/typesense.cjs +1 -1
  199. package/batteries/vector/typesense.mjs +1 -1
  200. package/batteries/vector/vespa.cjs +1 -1
  201. package/batteries/vector/vespa.mjs +1 -1
  202. package/batteries/vector/weaviate.cjs +1 -1
  203. package/batteries/vector/weaviate.mjs +1 -1
  204. package/batteries.cjs +2 -2
  205. package/batteries.mjs +2 -2
  206. package/bundled_xlsx.d.ts +1075 -0
  207. package/{common-BxoznqbX.mjs → common-BQoFv108.mjs} +7 -7
  208. package/{common-BxoznqbX.mjs.map → common-BQoFv108.mjs.map} +1 -1
  209. package/{common-BBK2e5ro.js → common-DmDn4Gfl.js} +7 -7
  210. package/{common-BBK2e5ro.js.map → common-DmDn4Gfl.js.map} +1 -1
  211. package/common.cjs +7 -7
  212. package/common.mjs +7 -7
  213. package/{dispatch_runner-Hn5idJYx.js → dispatch_runner-BwplbCPr.js} +3 -3
  214. package/{dispatch_runner-Hn5idJYx.js.map → dispatch_runner-BwplbCPr.js.map} +1 -1
  215. package/{dispatch_runner-DUrpj0xR.mjs → dispatch_runner-C1ar_D7W.mjs} +3 -3
  216. package/{dispatch_runner-DUrpj0xR.mjs.map → dispatch_runner-C1ar_D7W.mjs.map} +1 -1
  217. package/dispatch_runner.cjs +1 -1
  218. package/dispatch_runner.mjs +1 -1
  219. package/eslint.cjs +1 -1
  220. package/eslint.mjs +1 -1
  221. package/forge.cjs +4 -4
  222. package/forge.mjs +4 -4
  223. package/formats-CCylUHZw.mjs +161 -0
  224. package/formats-CCylUHZw.mjs.map +1 -0
  225. package/formats-DZVuqZUN.js +196 -0
  226. package/formats-DZVuqZUN.js.map +1 -0
  227. package/guards.cjs +8 -8
  228. package/guards.mjs +8 -8
  229. package/index.cjs +11 -11
  230. package/index.mjs +11 -11
  231. package/mcp/adk-docs-corpus.json +1 -1
  232. package/package.json +198 -182
  233. package/{scrapper-DLj_KkxK.mjs → scrapper-Dn2wXu0Y.mjs} +5 -5
  234. package/{scrapper-DLj_KkxK.mjs.map → scrapper-Dn2wXu0Y.mjs.map} +1 -1
  235. package/{scrapper-Cmf1CSA-.js → scrapper-mBZ0Odq7.js} +5 -5
  236. package/{scrapper-Cmf1CSA-.js.map → scrapper-mBZ0Odq7.js.map} +1 -1
  237. package/{searxng-BKs5s8Su.js → searxng-Dj-iP_Vz.js} +5 -5
  238. package/{searxng-BKs5s8Su.js.map → searxng-Dj-iP_Vz.js.map} +1 -1
  239. package/{searxng-BJ-aZcMz.mjs → searxng-DjFxtFf6.mjs} +5 -5
  240. package/{searxng-BJ-aZcMz.mjs.map → searxng-DjFxtFf6.mjs.map} +1 -1
  241. package/server.json +21 -0
  242. package/skills/adk-assembly/SKILL.md +2 -2
  243. package/{spooled_artifact-BR0IhU9y.js → spooled_artifact-BCmPrxZS.js} +3 -3
  244. package/{spooled_artifact-BR0IhU9y.js.map → spooled_artifact-BCmPrxZS.js.map} +1 -1
  245. package/{spooled_artifact-nTE6ujM8.mjs → spooled_artifact-DL36jnqA.mjs} +3 -3
  246. package/{spooled_artifact-nTE6ujM8.mjs.map → spooled_artifact-DL36jnqA.mjs.map} +1 -1
  247. package/spooled_artifact.cjs +2 -2
  248. package/spooled_artifact.mjs +2 -2
  249. package/{spooled_markdown_artifact-Dj3fNowz.js → spooled_markdown_artifact-CD4PrrpV.js} +3 -3
  250. package/{spooled_markdown_artifact-Dj3fNowz.js.map → spooled_markdown_artifact-CD4PrrpV.js.map} +1 -1
  251. package/{spooled_markdown_artifact-DIYzbQv8.mjs → spooled_markdown_artifact-Da-Xnebh.mjs} +3 -3
  252. package/{spooled_markdown_artifact-DIYzbQv8.mjs.map → spooled_markdown_artifact-Da-Xnebh.mjs.map} +1 -1
  253. package/{thought-Cde2Y_GK.mjs → thought-CtOoZUSE.mjs} +3 -3
  254. package/{thought-Cde2Y_GK.mjs.map → thought-CtOoZUSE.mjs.map} +1 -1
  255. package/{thought-BFtsnUTU.js → thought-eka4iUHa.js} +3 -3
  256. package/{thought-BFtsnUTU.js.map → thought-eka4iUHa.js.map} +1 -1
  257. package/{tool-CcxYxA5X.mjs → tool-CITF20yJ.mjs} +3 -3
  258. package/{tool-CcxYxA5X.mjs.map → tool-CITF20yJ.mjs.map} +1 -1
  259. package/{tool-B2nnkwNU.js → tool-Dhjca7rC.js} +3 -3
  260. package/{tool-B2nnkwNU.js.map → tool-Dhjca7rC.js.map} +1 -1
  261. package/{tool_call-BxL3eU1k.js → tool_call-Cyi0hUUc.js} +4 -4
  262. package/{tool_call-BxL3eU1k.js.map → tool_call-Cyi0hUUc.js.map} +1 -1
  263. package/{tool_call-B3MOog2R.mjs → tool_call-D_k36aI4.mjs} +4 -4
  264. package/{tool_call-B3MOog2R.mjs.map → tool_call-D_k36aI4.mjs.map} +1 -1
  265. package/{tool_registry-BaLUIzWz.mjs → tool_registry-CZ55mIti.mjs} +152 -143
  266. package/tool_registry-CZ55mIti.mjs.map +1 -0
  267. package/{tool_registry-BdKlPuHS.js → tool_registry-DwZ6pzN4.js} +151 -142
  268. package/tool_registry-DwZ6pzN4.js.map +1 -0
  269. package/{turn_runner-M2I8G2ok.js → turn_runner-CCZcsoDU.js} +5 -5
  270. package/{turn_runner-M2I8G2ok.js.map → turn_runner-CCZcsoDU.js.map} +1 -1
  271. package/{turn_runner-BV4BaZK9.mjs → turn_runner-DRPpVvsd.mjs} +5 -5
  272. package/{turn_runner-BV4BaZK9.mjs.map → turn_runner-DRPpVvsd.mjs.map} +1 -1
  273. package/turn_runner.cjs +1 -1
  274. package/turn_runner.mjs +1 -1
  275. package/{validate-JOHfh-BB.mjs → validate-C_hTnDBE.mjs} +95 -8
  276. package/validate-C_hTnDBE.mjs.map +1 -0
  277. package/{validate-DgDZkUKs.js → validate-gaSa9bsk.js} +95 -8
  278. package/validate-gaSa9bsk.js.map +1 -0
  279. package/xlsx-B0sTpEC2.js +30615 -0
  280. package/xlsx-B0sTpEC2.js.map +1 -0
  281. package/xlsx-DiMpn_Xv.mjs +30596 -0
  282. package/xlsx-DiMpn_Xv.mjs.map +1 -0
  283. package/xlsx.zahl-D2_Q-Xs4.mjs +6 -0
  284. package/xlsx.zahl-D2_Q-Xs4.mjs.map +1 -0
  285. package/xlsx.zahl-ZIcUQVv8.js +7 -0
  286. package/xlsx.zahl-ZIcUQVv8.js.map +1 -0
  287. package/tool_registry-BaLUIzWz.mjs.map +0 -1
  288. package/tool_registry-BdKlPuHS.js.map +0 -1
  289. package/validate-DgDZkUKs.js.map +0 -1
  290. package/validate-JOHfh-BB.mjs.map +0 -1
@@ -0,0 +1,438 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../chunk-Cek0wNdY.js");
3
+ const require_tool_registry = require("../../../tool_registry-DwZ6pzN4.js");
4
+ require("../../../guards.cjs");
5
+ const require_batteries_media_contracts = require("../contracts.cjs");
6
+ const require_exceptions = require("../../../exceptions-D79HIKeX.js");
7
+ const require_formats = require("../../../formats-DZVuqZUN.js");
8
+ //#region src/batteries/media/engines/sheetjs.ts
9
+ /**
10
+ * The SheetJS-backed spreadsheet {@link @nhtio/adk/batteries/media/contracts!MediaEngine}:
11
+ * the in-process, cross-environment spreadsheet converter, generator, and structural editor.
12
+ *
13
+ * @module @nhtio/adk/batteries/media/engines/sheetjs
14
+ *
15
+ * @remarks
16
+ * SheetJS (the `xlsx` package) reads and writes the widest spreadsheet matrix of any pure-JS
17
+ * library — XLSX/XLSM/XLSB, every XLS BIFF era, ODS/FODS, CSV, SYLK, DIF, DBF, HTML, RTF,
18
+ * Apple NUMBERS — with no binary, no native bindings, in any environment. This engine exposes
19
+ * that matrix three ways:
20
+ *
21
+ * - **convert**: any readable spreadsheet MIME → any writable format token.
22
+ * - **generate**: `EMPTY_MIME` → any writable token (a blank `Sheet1` workbook, written out).
23
+ * - **edit**: the `sheet.*` structural ops via CSF cell-object surgery. ⚠️ SheetJS Community
24
+ * Edition does NOT model cell styling — fonts, fills, and comments are STRIPPED by any edit
25
+ * or convert that round-trips a styled workbook (styling is a SheetJS Pro feature). For
26
+ * fidelity-preserving edits compose the exceljs engine FIRST in the engines array; this
27
+ * engine's edits are for unstyled/data workbooks and for breadth (it edits ODS, XLS, and
28
+ * every other readable format by normalizing through CSF).
29
+ *
30
+ * ⚠️ **Install from the SheetJS CDN, not the npm registry.** The registry copy of `xlsx` is
31
+ * frozen at 0.18.5 (2023) and carries CVE-2023-30533 and CVE-2024-22363; this engine requires
32
+ * `>=0.20.2`. Install: `pnpm add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`
33
+ * (SheetJS recommends vendoring the tarball — see docs.sheetjs.com).
34
+ *
35
+ * `xlsx` is an optional peer dependency, lazily imported on first actual use. The NUMBERS
36
+ * write target additionally loads the ZAHL payload (`xlsx/dist/xlsx.zahl.mjs`, ~110 KB) on
37
+ * first request of that specific target.
38
+ */
39
+ /** Every format token this engine can write, mapped to the SheetJS bookType that produces it. */
40
+ var BOOKTYPE_BY_TARGET = {
41
+ xlsx: "xlsx",
42
+ xlsm: "xlsm",
43
+ xlsb: "xlsb",
44
+ xls: "biff8",
45
+ ods: "ods",
46
+ fods: "fods",
47
+ csv: "csv",
48
+ txt: "txt",
49
+ html: "html",
50
+ rtf: "rtf",
51
+ sylk: "sylk",
52
+ dif: "dif",
53
+ dbf: "dbf",
54
+ numbers: "numbers"
55
+ };
56
+ /** The convert/generation target tokens, json included. */
57
+ var SHEET_WRITE_TARGETS = [...Object.keys(BOOKTYPE_BY_TARGET), "json"];
58
+ /** Output MIME per target token. */
59
+ var MIME_BY_TARGET = {
60
+ xlsx: require_formats.MIME.XLSX,
61
+ xlsm: require_formats.MIME.XLSM,
62
+ xlsb: require_formats.MIME.XLSB,
63
+ xls: require_formats.MIME.XLS,
64
+ ods: require_formats.MIME.ODS,
65
+ fods: require_formats.MIME.FODS,
66
+ csv: require_formats.MIME.CSV,
67
+ txt: require_formats.MIME.TXT,
68
+ html: require_formats.MIME.HTML,
69
+ rtf: "application/rtf",
70
+ sylk: require_formats.MIME.SYLK,
71
+ dif: require_formats.MIME.DIF,
72
+ dbf: require_formats.MIME.DBF,
73
+ numbers: require_formats.MIME.NUMBERS,
74
+ json: require_formats.MIME.JSON
75
+ };
76
+ /**
77
+ * Every spreadsheet MIME this engine reads. SheetJS sniffs the actual format from the bytes
78
+ * (zip vs CFB vs text heuristics), so one entry serves the whole read matrix. Formats SheetJS
79
+ * can parse but that have no standard MIME (Quattro Pro, Works, Lotus variants) are readable
80
+ * whenever a resolver hands us one of these MIMEs for them — the MIME is the only addressable
81
+ * contract the battery has.
82
+ */
83
+ var SHEET_READ_MIMES = [
84
+ require_formats.MIME.XLSX,
85
+ require_formats.MIME.XLSM,
86
+ require_formats.MIME.XLSB,
87
+ require_formats.MIME.XLS,
88
+ require_formats.MIME.ODS,
89
+ require_formats.MIME.FODS,
90
+ require_formats.MIME.CSV,
91
+ require_formats.MIME.NUMBERS,
92
+ require_formats.MIME.SYLK,
93
+ require_formats.MIME.DIF,
94
+ require_formats.MIME.DBF
95
+ ];
96
+ /** The structural ops this engine edits (same names the verb table uses). */
97
+ var SHEET_OPS = [
98
+ "sheet.add_rows",
99
+ "sheet.add_columns",
100
+ "sheet.update_cells",
101
+ "sheet.delete_rows",
102
+ "sheet.delete_columns",
103
+ "sheet.rename_sheet",
104
+ "sheet.add_sheet",
105
+ "sheet.remove_sheet",
106
+ "sheet.reorder_sheets",
107
+ "sheet.transform_table"
108
+ ];
109
+ /**
110
+ * Construct the SheetJS-backed spreadsheet engine.
111
+ *
112
+ * @param options - Optional module resolver overrides.
113
+ * @returns The engine.
114
+ */
115
+ var sheetjsEngine = (options = {}) => {
116
+ let modPromise;
117
+ const getXlsx = () => {
118
+ modPromise ??= Promise.resolve(options.xlsx ? options.xlsx() : Promise.resolve().then(() => require("../../../xlsx-B0sTpEC2.js"))).catch((err) => {
119
+ throw new require_exceptions.E_INVALID_MEDIA_PIPELINE_CONFIG([`the sheetjs engine could not load its peer dependency "xlsx": ${require_tool_registry.isError(err) ? err.message : String(err)} — install it FROM THE SHEETJS CDN (the npm registry copy is stale and vulnerable): pnpm add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`]);
120
+ });
121
+ return modPromise;
122
+ };
123
+ let zahlPromise;
124
+ const getZahl = () => {
125
+ zahlPromise ??= Promise.resolve(options.zahl ? options.zahl() : Promise.resolve().then(() => require("../../../xlsx.zahl-ZIcUQVv8.js"))).then((m) => m.default ?? m, (err) => {
126
+ const detail = require_tool_registry.isError(err) ? err.message : String(err);
127
+ throw new Error(`NUMBERS output needs the SheetJS ZAHL payload (xlsx/dist/xlsx.zahl.mjs) and it could not be loaded: ${detail}`);
128
+ });
129
+ return zahlPromise;
130
+ };
131
+ /** Write `wb` to the requested target token. */
132
+ const writeOut = async (X, wb, to) => {
133
+ if (to === "json") {
134
+ const ws = wb.Sheets[wb.SheetNames[0]];
135
+ const rows = ws ? X.utils.sheet_to_json(ws, { header: 1 }) : [];
136
+ return {
137
+ bytes: new TextEncoder().encode(JSON.stringify(rows)),
138
+ mimeType: require_formats.MIME.JSON
139
+ };
140
+ }
141
+ const bookType = BOOKTYPE_BY_TARGET[to];
142
+ if (!bookType) throw new Error(`sheetjs cannot write "${to}"; supported: ${SHEET_WRITE_TARGETS.join(", ")}`);
143
+ const writeOpts = {
144
+ bookType,
145
+ type: "array"
146
+ };
147
+ if (to === "numbers") writeOpts.numbers = await getZahl();
148
+ const out = X.write(wb, writeOpts);
149
+ return {
150
+ bytes: ArrayBuffer.isView(out) ? out : new Uint8Array(out),
151
+ mimeType: MIME_BY_TARGET[to] ?? "application/octet-stream"
152
+ };
153
+ };
154
+ const convert = async (request) => {
155
+ const X = await getXlsx();
156
+ const mime = request.mimeType.toLowerCase().split(";")[0].trim();
157
+ let wb;
158
+ if (mime === "application/x-adk-empty") {
159
+ wb = X.utils.book_new();
160
+ const seed = request.to === "numbers" ? [[""]] : [[]];
161
+ X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet(seed), "Sheet1");
162
+ } else {
163
+ wb = X.read(request.bytes);
164
+ if (wb.SheetNames.length === 0) throw new Error(`sheetjs parsed ${request.mimeType} but found no worksheets — the file may be corrupt or not actually a spreadsheet`);
165
+ }
166
+ const { bytes, mimeType } = await writeOut(X, wb, request.to);
167
+ return { outputs: [{
168
+ bytes,
169
+ mimeType
170
+ }] };
171
+ };
172
+ const edit = async (request) => {
173
+ const X = await getXlsx();
174
+ const wb = X.read(request.bytes);
175
+ if (wb.SheetNames.length === 0) throw new Error("sheetjs parsed the workbook but found no worksheets");
176
+ const summary = applyEdit(X, wb, request.op, request.args);
177
+ const { bytes, mimeType } = await writeOut(X, wb, "xlsx");
178
+ return {
179
+ bytes,
180
+ mimeType,
181
+ summary
182
+ };
183
+ };
184
+ return {
185
+ id: "sheetjs",
186
+ converts: [{
187
+ from: [require_batteries_media_contracts.EMPTY_MIME],
188
+ to: SHEET_WRITE_TARGETS,
189
+ convert
190
+ }, {
191
+ from: SHEET_READ_MIMES,
192
+ to: SHEET_WRITE_TARGETS,
193
+ convert
194
+ }],
195
+ edits: [{
196
+ over: SHEET_READ_MIMES,
197
+ ops: SHEET_OPS,
198
+ edit
199
+ }]
200
+ };
201
+ };
202
+ var asAoa = (X, ws) => X.utils.sheet_to_json(ws, {
203
+ header: 1,
204
+ defval: null
205
+ });
206
+ var resolveSheetName = (wb, sheetArg) => {
207
+ if (sheetArg === void 0 || sheetArg === null) {
208
+ const first = wb.SheetNames[0];
209
+ if (!first) throw new Error("the workbook has no worksheets");
210
+ return first;
211
+ }
212
+ if (typeof sheetArg === "number") {
213
+ const byIndex = wb.SheetNames[sheetArg - 1];
214
+ if (byIndex) return byIndex;
215
+ if (wb.SheetNames.includes(String(sheetArg))) throw new Error(`no sheet at index ${sheetArg}, but a sheet NAMED "${sheetArg}" exists — quote it: sheet="${sheetArg}"`);
216
+ throw new Error(`sheet index ${sheetArg} is out of range (1-based; the workbook has ${wb.SheetNames.length})`);
217
+ }
218
+ const name = String(sheetArg);
219
+ if (!wb.SheetNames.includes(name)) {
220
+ const names = wb.SheetNames.map((n) => `"${n}"`).join(", ");
221
+ throw new Error(`no sheet named "${name}" (sheets: ${names})`);
222
+ }
223
+ return name;
224
+ };
225
+ /** Column letters → 1-based number (`A` → 1, `AA` → 27). */
226
+ var columnLetterToNumber = (letters) => {
227
+ let n = 0;
228
+ for (const ch of letters.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64);
229
+ return n;
230
+ };
231
+ /** Parse an A1 address into 1-based row/col. */
232
+ var parseA1 = (address) => {
233
+ const m = /^([A-Za-z]+)(\d+)$/.exec(address.trim());
234
+ if (!m) throw new Error(`invalid cell address "${address}" (expected A1 form)`);
235
+ return {
236
+ row: Number(m[2]),
237
+ col: columnLetterToNumber(m[1])
238
+ };
239
+ };
240
+ var rebuild = (X, wb, name, aoa) => {
241
+ wb.Sheets[name] = X.utils.aoa_to_sheet(aoa.length > 0 ? aoa : [[]]);
242
+ };
243
+ /** Apply one structural op to the workbook in place; returns the change summary. */
244
+ var applyEdit = (X, wb, op, args) => {
245
+ switch (op) {
246
+ case "sheet.add_rows": {
247
+ const name = resolveSheetName(wb, args.sheet);
248
+ const rows = args.rows;
249
+ if (!Array.isArray(rows) || rows.length === 0 || !rows.every(Array.isArray)) throw new Error("rows must be a non-empty array of arrays");
250
+ const aoa = asAoa(X, wb.Sheets[name]);
251
+ const before = args.before;
252
+ const after = args.after;
253
+ const insertAt = before !== void 0 ? before - 1 : after !== void 0 ? after : aoa.length;
254
+ aoa.splice(insertAt, 0, ...rows);
255
+ rebuild(X, wb, name, aoa);
256
+ return { added: rows.length };
257
+ }
258
+ case "sheet.add_columns": {
259
+ const name = resolveSheetName(wb, args.sheet);
260
+ const headers = args.headers;
261
+ const descriptors = args.columns ?? headers?.map((header) => ({ header }));
262
+ if (!Array.isArray(descriptors) || descriptors.length === 0) throw new Error(`provide headers=a,b or columns='[{"header":"X","values":[1]}]'`);
263
+ const aoa = asAoa(X, wb.Sheets[name]);
264
+ const before = args.before;
265
+ const after = args.after;
266
+ const width = aoa.reduce((w, r) => Math.max(w, r.length), 0);
267
+ const insertAt = before !== void 0 ? before - 1 : after !== void 0 ? after : width;
268
+ for (const [i, col] of descriptors.entries()) {
269
+ if (typeof col?.header !== "string") throw new Error("every column needs a string header");
270
+ const columnCells = [col.header, ...col.values ?? []];
271
+ const rowsNeeded = Math.max(aoa.length, columnCells.length);
272
+ for (let r = 0; r < rowsNeeded; r++) {
273
+ aoa[r] ??= [];
274
+ while (aoa[r].length < insertAt + i) aoa[r].push(null);
275
+ aoa[r].splice(insertAt + i, 0, columnCells[r] ?? null);
276
+ }
277
+ }
278
+ rebuild(X, wb, name, aoa);
279
+ return { added: descriptors.length };
280
+ }
281
+ case "sheet.update_cells": {
282
+ const name = resolveSheetName(wb, args.sheet);
283
+ const updates = args.updates;
284
+ if (!Array.isArray(updates) || updates.length === 0) throw new Error("updates must be a non-empty array");
285
+ const ws = wb.Sheets[name];
286
+ for (const update of updates) {
287
+ let row;
288
+ let col;
289
+ if (typeof update.address === "string") ({row, col} = parseA1(update.address));
290
+ else {
291
+ row = Number(update.row);
292
+ col = typeof update.col === "string" ? columnLetterToNumber(update.col) : Number(update.col);
293
+ if (!Number.isFinite(row) || !Number.isFinite(col)) throw new Error("each update needs an address (A1) or row+col");
294
+ }
295
+ const addr = X.utils.encode_cell({
296
+ r: row - 1,
297
+ c: col - 1
298
+ });
299
+ const value = update.value;
300
+ if (typeof value === "string" && value.startsWith("=")) ws[addr] = {
301
+ t: "n",
302
+ f: value.slice(1)
303
+ };
304
+ else if (value === null || value === void 0) delete ws[addr];
305
+ else if (typeof value === "number") ws[addr] = {
306
+ t: "n",
307
+ v: value
308
+ };
309
+ else if (typeof value === "boolean") ws[addr] = {
310
+ t: "b",
311
+ v: value
312
+ };
313
+ else ws[addr] = {
314
+ t: "s",
315
+ v: String(value)
316
+ };
317
+ const range = ws["!ref"] ? X.utils.decode_range(ws["!ref"]) : {
318
+ s: {
319
+ r: row - 1,
320
+ c: col - 1
321
+ },
322
+ e: {
323
+ r: row - 1,
324
+ c: col - 1
325
+ }
326
+ };
327
+ range.s.r = Math.min(range.s.r, row - 1);
328
+ range.s.c = Math.min(range.s.c, col - 1);
329
+ range.e.r = Math.max(range.e.r, row - 1);
330
+ range.e.c = Math.max(range.e.c, col - 1);
331
+ ws["!ref"] = X.utils.encode_range(range);
332
+ }
333
+ return { modified: updates.length };
334
+ }
335
+ case "sheet.delete_rows": {
336
+ const name = resolveSheetName(wb, args.sheet);
337
+ const rows = args.rows;
338
+ if (!Array.isArray(rows) || rows.length === 0) throw new Error("rows must be a non-empty array");
339
+ const aoa = asAoa(X, wb.Sheets[name]);
340
+ for (const r of [...rows].sort((a, b) => b - a)) aoa.splice(r - 1, 1);
341
+ rebuild(X, wb, name, aoa);
342
+ return { removed: rows.length };
343
+ }
344
+ case "sheet.delete_columns": {
345
+ const name = resolveSheetName(wb, args.sheet);
346
+ const columns = args.columns;
347
+ if (!Array.isArray(columns) || columns.length === 0) throw new Error("columns must be a non-empty array");
348
+ const aoa = asAoa(X, wb.Sheets[name]);
349
+ for (const c of [...columns].sort((a, b) => b - a)) for (const row of aoa) if (row.length >= c) row.splice(c - 1, 1);
350
+ rebuild(X, wb, name, aoa);
351
+ return { removed: columns.length };
352
+ }
353
+ case "sheet.rename_sheet": {
354
+ const from = String(args.sheet ?? "");
355
+ const to = String(args.to ?? "");
356
+ if (!wb.SheetNames.includes(from)) {
357
+ const names = wb.SheetNames.map((n) => `"${n}"`).join(", ");
358
+ throw new Error(`rename targets a sheet NAME; no sheet named "${from}". Sheets: ${names}`);
359
+ }
360
+ if (wb.SheetNames.includes(to)) throw new Error(`a sheet named "${to}" already exists`);
361
+ wb.SheetNames[wb.SheetNames.indexOf(from)] = to;
362
+ wb.Sheets[to] = wb.Sheets[from];
363
+ delete wb.Sheets[from];
364
+ return { modified: 1 };
365
+ }
366
+ case "sheet.add_sheet": {
367
+ const name = String(args.name ?? "");
368
+ if (!name) throw new Error("add_sheet requires a name");
369
+ if (wb.SheetNames.includes(name)) throw new Error(`a sheet named "${name}" already exists`);
370
+ const at = args.at;
371
+ X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[]]), name);
372
+ if (at !== void 0) {
373
+ const idx = wb.SheetNames.indexOf(name);
374
+ wb.SheetNames.splice(idx, 1);
375
+ wb.SheetNames.splice(Math.max(0, at - 1), 0, name);
376
+ }
377
+ return { added: 1 };
378
+ }
379
+ case "sheet.remove_sheet": {
380
+ const name = String(args.sheet ?? "");
381
+ if (!wb.SheetNames.includes(name)) {
382
+ const names = wb.SheetNames.map((n) => `"${n}"`).join(", ");
383
+ throw new Error(`no sheet named "${name}" (sheets: ${names})`);
384
+ }
385
+ if (wb.SheetNames.length === 1) throw new Error("cannot remove the only worksheet");
386
+ wb.SheetNames.splice(wb.SheetNames.indexOf(name), 1);
387
+ delete wb.Sheets[name];
388
+ return { removed: 1 };
389
+ }
390
+ case "sheet.reorder_sheets": {
391
+ const order = args.order;
392
+ if (!Array.isArray(order) || order.length !== wb.SheetNames.length) throw new Error(`order must include every worksheet exactly once (the workbook has ${wb.SheetNames.length})`);
393
+ const resolved = order.map((ref) => typeof ref === "number" ? wb.SheetNames[ref - 1] : String(ref));
394
+ if (new Set(resolved).size !== resolved.length || resolved.some((n) => !n || !wb.SheetNames.includes(n))) throw new Error("order must reference every existing worksheet exactly once");
395
+ wb.SheetNames.length = 0;
396
+ wb.SheetNames.push(...resolved);
397
+ return { modified: resolved.length };
398
+ }
399
+ case "sheet.transform_table": {
400
+ const name = resolveSheetName(wb, args.sheet);
401
+ const headerRow = Number(args.header_row ?? 1);
402
+ const aoa = asAoa(X, wb.Sheets[name]);
403
+ const header = (aoa[headerRow - 1] ?? []).map((h) => h === null ? "" : String(h));
404
+ let modified = 0;
405
+ const rename = args.rename;
406
+ if (rename) for (const { from, to } of rename) {
407
+ const idx = header.indexOf(from);
408
+ if (idx !== -1) {
409
+ aoa[headerRow - 1][idx] = to;
410
+ header[idx] = to;
411
+ modified++;
412
+ }
413
+ }
414
+ const drop = args.drop;
415
+ const select = args.select;
416
+ const toRemove = /* @__PURE__ */ new Set();
417
+ if (drop) for (const h of drop) {
418
+ const idx = header.indexOf(h);
419
+ if (idx !== -1) toRemove.add(idx);
420
+ }
421
+ if (select) {
422
+ for (const [i, element] of header.entries()) if (!select.includes(element)) toRemove.add(i);
423
+ }
424
+ if (toRemove.size > 0) {
425
+ const sorted = [...toRemove].sort((a, b) => b - a);
426
+ for (const row of aoa) for (const idx of sorted) if (row.length > idx) row.splice(idx, 1);
427
+ modified += toRemove.size;
428
+ }
429
+ rebuild(X, wb, name, aoa);
430
+ return { modified };
431
+ }
432
+ default: throw new Error(`sheetjs does not implement edit op "${op}"`);
433
+ }
434
+ };
435
+ //#endregion
436
+ exports.sheetjsEngine = sheetjsEngine;
437
+
438
+ //# sourceMappingURL=sheetjs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheetjs.cjs","names":[],"sources":["../../../../src/batteries/media/engines/sheetjs.ts"],"sourcesContent":["/**\n * The SheetJS-backed spreadsheet {@link @nhtio/adk/batteries/media/contracts!MediaEngine}:\n * the in-process, cross-environment spreadsheet converter, generator, and structural editor.\n *\n * @module @nhtio/adk/batteries/media/engines/sheetjs\n *\n * @remarks\n * SheetJS (the `xlsx` package) reads and writes the widest spreadsheet matrix of any pure-JS\n * library — XLSX/XLSM/XLSB, every XLS BIFF era, ODS/FODS, CSV, SYLK, DIF, DBF, HTML, RTF,\n * Apple NUMBERS — with no binary, no native bindings, in any environment. This engine exposes\n * that matrix three ways:\n *\n * - **convert**: any readable spreadsheet MIME → any writable format token.\n * - **generate**: `EMPTY_MIME` → any writable token (a blank `Sheet1` workbook, written out).\n * - **edit**: the `sheet.*` structural ops via CSF cell-object surgery. ⚠️ SheetJS Community\n * Edition does NOT model cell styling — fonts, fills, and comments are STRIPPED by any edit\n * or convert that round-trips a styled workbook (styling is a SheetJS Pro feature). For\n * fidelity-preserving edits compose the exceljs engine FIRST in the engines array; this\n * engine's edits are for unstyled/data workbooks and for breadth (it edits ODS, XLS, and\n * every other readable format by normalizing through CSF).\n *\n * ⚠️ **Install from the SheetJS CDN, not the npm registry.** The registry copy of `xlsx` is\n * frozen at 0.18.5 (2023) and carries CVE-2023-30533 and CVE-2024-22363; this engine requires\n * `>=0.20.2`. Install: `pnpm add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`\n * (SheetJS recommends vendoring the tarball — see docs.sheetjs.com).\n *\n * `xlsx` is an optional peer dependency, lazily imported on first actual use. The NUMBERS\n * write target additionally loads the ZAHL payload (`xlsx/dist/xlsx.zahl.mjs`, ~110 KB) on\n * first request of that specific target.\n */\n\nimport { MIME } from '../formats'\nimport { EMPTY_MIME } from '../contracts'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type * as XlsxNS from 'xlsx'\nimport type {\n MediaEngine,\n ConvertRequest,\n ConvertResult,\n EditRequest,\n EditResult,\n} from '../contracts'\n\ntype XlsxModule = typeof XlsxNS\n\n/** Options for {@link sheetjsEngine}. */\nexport interface SheetjsEngineOptions {\n /** Override the module resolution (tests / custom builds). Default: `import('xlsx')`. */\n xlsx?: () => XlsxModule | Promise<XlsxModule>\n /**\n * Override the ZAHL payload resolution for NUMBERS output (tests / custom builds).\n * Default: `import('xlsx/dist/xlsx.zahl.mjs')`.\n */\n zahl?: () => unknown | Promise<unknown>\n}\n\n/** Every format token this engine can write, mapped to the SheetJS bookType that produces it. */\nconst BOOKTYPE_BY_TARGET: Record<string, string> = {\n xlsx: 'xlsx',\n xlsm: 'xlsm',\n xlsb: 'xlsb',\n xls: 'biff8',\n ods: 'ods',\n fods: 'fods',\n csv: 'csv',\n txt: 'txt',\n html: 'html',\n rtf: 'rtf',\n sylk: 'sylk',\n dif: 'dif',\n dbf: 'dbf',\n numbers: 'numbers',\n // json is synthesized via sheet_to_json, not a bookType — handled separately.\n}\n\n/** The convert/generation target tokens, json included. */\nconst SHEET_WRITE_TARGETS: readonly string[] = [...Object.keys(BOOKTYPE_BY_TARGET), 'json']\n\n/** Output MIME per target token. */\nconst MIME_BY_TARGET: Record<string, string> = {\n xlsx: MIME.XLSX,\n xlsm: MIME.XLSM,\n xlsb: MIME.XLSB,\n xls: MIME.XLS,\n ods: MIME.ODS,\n fods: MIME.FODS,\n csv: MIME.CSV,\n txt: MIME.TXT,\n html: MIME.HTML,\n rtf: 'application/rtf',\n sylk: MIME.SYLK,\n dif: MIME.DIF,\n dbf: MIME.DBF,\n numbers: MIME.NUMBERS,\n json: MIME.JSON,\n}\n\n/**\n * Every spreadsheet MIME this engine reads. SheetJS sniffs the actual format from the bytes\n * (zip vs CFB vs text heuristics), so one entry serves the whole read matrix. Formats SheetJS\n * can parse but that have no standard MIME (Quattro Pro, Works, Lotus variants) are readable\n * whenever a resolver hands us one of these MIMEs for them — the MIME is the only addressable\n * contract the battery has.\n */\nconst SHEET_READ_MIMES: readonly string[] = [\n MIME.XLSX,\n MIME.XLSM,\n MIME.XLSB,\n MIME.XLS,\n MIME.ODS,\n MIME.FODS,\n MIME.CSV,\n MIME.NUMBERS,\n MIME.SYLK,\n MIME.DIF,\n MIME.DBF,\n]\n\n/** The structural ops this engine edits (same names the verb table uses). */\nconst SHEET_OPS: readonly string[] = [\n 'sheet.add_rows',\n 'sheet.add_columns',\n 'sheet.update_cells',\n 'sheet.delete_rows',\n 'sheet.delete_columns',\n 'sheet.rename_sheet',\n 'sheet.add_sheet',\n 'sheet.remove_sheet',\n 'sheet.reorder_sheets',\n 'sheet.transform_table',\n]\n\n/**\n * Construct the SheetJS-backed spreadsheet engine.\n *\n * @param options - Optional module resolver overrides.\n * @returns The engine.\n */\nexport const sheetjsEngine = (options: SheetjsEngineOptions = {}): MediaEngine => {\n let modPromise: Promise<XlsxModule> | undefined\n const getXlsx = (): Promise<XlsxModule> => {\n modPromise ??= Promise.resolve(options.xlsx ? options.xlsx() : import('xlsx')).catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the sheetjs engine could not load its peer dependency \"xlsx\": ${detail} — install it FROM THE SHEETJS CDN (the npm registry copy is stale and vulnerable): pnpm add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`,\n ])\n })\n return modPromise\n }\n\n let zahlPromise: Promise<unknown> | undefined\n const getZahl = (): Promise<unknown> => {\n zahlPromise ??= Promise.resolve(\n options.zahl ? options.zahl() : import('xlsx/dist/xlsx.zahl.mjs' as string)\n ).then(\n (m) => (m as { default?: unknown }).default ?? m,\n (err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new Error(\n `NUMBERS output needs the SheetJS ZAHL payload (xlsx/dist/xlsx.zahl.mjs) and it could not be loaded: ${detail}`\n )\n }\n )\n return zahlPromise\n }\n\n /** Write `wb` to the requested target token. */\n const writeOut = async (\n X: XlsxModule,\n wb: XlsxNS.WorkBook,\n to: string\n ): Promise<{ bytes: Uint8Array; mimeType: string }> => {\n if (to === 'json') {\n const ws = wb.Sheets[wb.SheetNames[0]]\n const rows = ws ? X.utils.sheet_to_json(ws, { header: 1 }) : []\n return {\n bytes: new TextEncoder().encode(JSON.stringify(rows)),\n mimeType: MIME.JSON,\n }\n }\n const bookType = BOOKTYPE_BY_TARGET[to]\n if (!bookType) {\n throw new Error(`sheetjs cannot write \"${to}\"; supported: ${SHEET_WRITE_TARGETS.join(', ')}`)\n }\n const writeOpts: XlsxNS.WritingOptions = {\n bookType: bookType as XlsxNS.BookType,\n type: 'array',\n }\n if (to === 'numbers') {\n ;(writeOpts as { numbers?: unknown }).numbers = await getZahl()\n }\n const out = X.write(wb, writeOpts) as ArrayBuffer | Uint8Array\n const bytes = ArrayBuffer.isView(out) ? out : new Uint8Array(out)\n return { bytes, mimeType: MIME_BY_TARGET[to] ?? 'application/octet-stream' }\n }\n\n const convert = async (request: ConvertRequest): Promise<ConvertResult> => {\n const X = await getXlsx()\n const mime = request.mimeType.toLowerCase().split(';')[0].trim()\n let wb: XlsxNS.WorkBook\n if (mime === EMPTY_MIME) {\n // Generation: a blank workbook with one empty Sheet1 (steps expect ≥1 worksheet).\n // NUMBERS refuses a zero-cell sheet, so that target seeds one blank cell.\n wb = X.utils.book_new()\n const seed = request.to === 'numbers' ? [['']] : [[]]\n X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet(seed), 'Sheet1')\n } else {\n wb = X.read(request.bytes)\n if (wb.SheetNames.length === 0) {\n throw new Error(\n `sheetjs parsed ${request.mimeType} but found no worksheets — the file may be corrupt or not actually a spreadsheet`\n )\n }\n }\n const { bytes, mimeType } = await writeOut(X, wb, request.to)\n return { outputs: [{ bytes, mimeType }] }\n }\n\n const edit = async (request: EditRequest): Promise<EditResult> => {\n const X = await getXlsx()\n const wb = X.read(request.bytes)\n if (wb.SheetNames.length === 0) {\n throw new Error('sheetjs parsed the workbook but found no worksheets')\n }\n const summary = applyEdit(X, wb, request.op, request.args)\n const { bytes, mimeType } = await writeOut(X, wb, 'xlsx')\n return { bytes, mimeType, summary }\n }\n\n return {\n id: 'sheetjs',\n converts: [\n // Generation: blank Sheet1 workbook, written to any target.\n { from: [EMPTY_MIME], to: SHEET_WRITE_TARGETS, convert },\n // The read matrix: format is sniffed from bytes, so one entry serves every MIME.\n { from: SHEET_READ_MIMES, to: SHEET_WRITE_TARGETS, convert },\n ],\n edits: [\n // ⚠️ CE strips styling (fonts/fills/comments) — compose exceljs first for fidelity.\n { over: SHEET_READ_MIMES, ops: SHEET_OPS, edit },\n ],\n }\n}\n\n// ── CSF structural edits ──────────────────────────────────────────────────────\n// SheetJS CE models a worksheet as a cell map; these ops normalize to array-of-arrays,\n// operate, and rebuild. Styling does not survive this (CE has none to carry).\n\nconst asAoa = (X: XlsxModule, ws: XlsxNS.WorkSheet): unknown[][] =>\n X.utils.sheet_to_json(ws, { header: 1, defval: null }) as unknown[][]\n\nconst resolveSheetName = (wb: XlsxNS.WorkBook, sheetArg: unknown): string => {\n if (sheetArg === undefined || sheetArg === null) {\n const first = wb.SheetNames[0]\n if (!first) throw new Error('the workbook has no worksheets')\n return first\n }\n if (typeof sheetArg === 'number') {\n const byIndex = wb.SheetNames[sheetArg - 1]\n if (byIndex) return byIndex\n if (wb.SheetNames.includes(String(sheetArg))) {\n throw new Error(\n `no sheet at index ${sheetArg}, but a sheet NAMED \"${sheetArg}\" exists — quote it: sheet=\"${sheetArg}\"`\n )\n }\n throw new Error(\n `sheet index ${sheetArg} is out of range (1-based; the workbook has ${wb.SheetNames.length})`\n )\n }\n const name = String(sheetArg)\n if (!wb.SheetNames.includes(name)) {\n const names = wb.SheetNames.map((n) => `\"${n}\"`).join(', ')\n throw new Error(`no sheet named \"${name}\" (sheets: ${names})`)\n }\n return name\n}\n\n/** Column letters → 1-based number (`A` → 1, `AA` → 27). */\nconst columnLetterToNumber = (letters: string): number => {\n let n = 0\n for (const ch of letters.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64)\n return n\n}\n\n/** Parse an A1 address into 1-based row/col. */\nconst parseA1 = (address: string): { row: number; col: number } => {\n const m = /^([A-Za-z]+)(\\d+)$/.exec(address.trim())\n if (!m) throw new Error(`invalid cell address \"${address}\" (expected A1 form)`)\n return { row: Number(m[2]), col: columnLetterToNumber(m[1]) }\n}\n\nconst rebuild = (X: XlsxModule, wb: XlsxNS.WorkBook, name: string, aoa: unknown[][]): void => {\n wb.Sheets[name] = X.utils.aoa_to_sheet(aoa.length > 0 ? aoa : [[]])\n}\n\n/** Apply one structural op to the workbook in place; returns the change summary. */\nconst applyEdit = (\n X: XlsxModule,\n wb: XlsxNS.WorkBook,\n op: string,\n args: Record<string, unknown>\n): { added?: number; removed?: number; modified?: number; warnings?: string[] } => {\n switch (op) {\n case 'sheet.add_rows': {\n const name = resolveSheetName(wb, args.sheet)\n const rows = args.rows as unknown[][]\n if (!Array.isArray(rows) || rows.length === 0 || !rows.every(Array.isArray)) {\n throw new Error('rows must be a non-empty array of arrays')\n }\n const aoa = asAoa(X, wb.Sheets[name])\n const before = args.before as number | undefined\n const after = args.after as number | undefined\n const insertAt = before !== undefined ? before - 1 : after !== undefined ? after : aoa.length\n aoa.splice(insertAt, 0, ...rows)\n rebuild(X, wb, name, aoa)\n return { added: rows.length }\n }\n case 'sheet.add_columns': {\n const name = resolveSheetName(wb, args.sheet)\n const headers = args.headers as string[] | undefined\n const descriptors: Array<{ header: string; values?: unknown[] }> | undefined =\n (args.columns as Array<{ header: string; values?: unknown[] }> | undefined) ??\n headers?.map((header) => ({ header }))\n if (!Array.isArray(descriptors) || descriptors.length === 0) {\n throw new Error(`provide headers=a,b or columns='[{\"header\":\"X\",\"values\":[1]}]'`)\n }\n const aoa = asAoa(X, wb.Sheets[name])\n const before = args.before as number | undefined\n const after = args.after as number | undefined\n const width = aoa.reduce((w, r) => Math.max(w, r.length), 0)\n const insertAt = before !== undefined ? before - 1 : after !== undefined ? after : width\n for (const [i, col] of descriptors.entries()) {\n if (typeof col?.header !== 'string') throw new Error('every column needs a string header')\n const columnCells = [col.header, ...(col.values ?? [])]\n const rowsNeeded = Math.max(aoa.length, columnCells.length)\n for (let r = 0; r < rowsNeeded; r++) {\n aoa[r] ??= []\n while (aoa[r].length < insertAt + i) aoa[r].push(null)\n aoa[r].splice(insertAt + i, 0, columnCells[r] ?? null)\n }\n }\n rebuild(X, wb, name, aoa)\n return { added: descriptors.length }\n }\n case 'sheet.update_cells': {\n const name = resolveSheetName(wb, args.sheet)\n const updates = args.updates as Array<Record<string, unknown>>\n if (!Array.isArray(updates) || updates.length === 0) {\n throw new Error('updates must be a non-empty array')\n }\n const ws = wb.Sheets[name]\n for (const update of updates) {\n let row: number\n let col: number\n if (typeof update.address === 'string') {\n ;({ row, col } = parseA1(update.address))\n } else {\n row = Number(update.row)\n col =\n typeof update.col === 'string' ? columnLetterToNumber(update.col) : Number(update.col)\n if (!Number.isFinite(row) || !Number.isFinite(col)) {\n throw new Error('each update needs an address (A1) or row+col')\n }\n }\n const addr = X.utils.encode_cell({ r: row - 1, c: col - 1 })\n const value = update.value\n if (typeof value === 'string' && value.startsWith('=')) {\n ws[addr] = { t: 'n', f: value.slice(1) }\n } else if (value === null || value === undefined) {\n delete ws[addr]\n } else if (typeof value === 'number') {\n ws[addr] = { t: 'n', v: value }\n } else if (typeof value === 'boolean') {\n ws[addr] = { t: 'b', v: value }\n } else {\n ws[addr] = { t: 's', v: String(value) }\n }\n const range = ws['!ref']\n ? X.utils.decode_range(ws['!ref'] as string)\n : { s: { r: row - 1, c: col - 1 }, e: { r: row - 1, c: col - 1 } }\n range.s.r = Math.min(range.s.r, row - 1)\n range.s.c = Math.min(range.s.c, col - 1)\n range.e.r = Math.max(range.e.r, row - 1)\n range.e.c = Math.max(range.e.c, col - 1)\n ws['!ref'] = X.utils.encode_range(range)\n }\n return { modified: updates.length }\n }\n case 'sheet.delete_rows': {\n const name = resolveSheetName(wb, args.sheet)\n const rows = args.rows as number[]\n if (!Array.isArray(rows) || rows.length === 0)\n throw new Error('rows must be a non-empty array')\n const aoa = asAoa(X, wb.Sheets[name])\n for (const r of [...rows].sort((a, b) => b - a)) aoa.splice(r - 1, 1)\n rebuild(X, wb, name, aoa)\n return { removed: rows.length }\n }\n case 'sheet.delete_columns': {\n const name = resolveSheetName(wb, args.sheet)\n const columns = args.columns as number[]\n if (!Array.isArray(columns) || columns.length === 0) {\n throw new Error('columns must be a non-empty array')\n }\n const aoa = asAoa(X, wb.Sheets[name])\n for (const c of [...columns].sort((a, b) => b - a)) {\n for (const row of aoa) if (row.length >= c) row.splice(c - 1, 1)\n }\n rebuild(X, wb, name, aoa)\n return { removed: columns.length }\n }\n case 'sheet.rename_sheet': {\n const from = String(args.sheet ?? '')\n const to = String(args.to ?? '')\n if (!wb.SheetNames.includes(from)) {\n const names = wb.SheetNames.map((n) => `\"${n}\"`).join(', ')\n throw new Error(`rename targets a sheet NAME; no sheet named \"${from}\". Sheets: ${names}`)\n }\n if (wb.SheetNames.includes(to)) throw new Error(`a sheet named \"${to}\" already exists`)\n wb.SheetNames[wb.SheetNames.indexOf(from)] = to\n wb.Sheets[to] = wb.Sheets[from]\n delete wb.Sheets[from]\n return { modified: 1 }\n }\n case 'sheet.add_sheet': {\n const name = String(args.name ?? '')\n if (!name) throw new Error('add_sheet requires a name')\n if (wb.SheetNames.includes(name)) throw new Error(`a sheet named \"${name}\" already exists`)\n const at = args.at as number | undefined\n X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[]]), name)\n if (at !== undefined) {\n const idx = wb.SheetNames.indexOf(name)\n wb.SheetNames.splice(idx, 1)\n wb.SheetNames.splice(Math.max(0, at - 1), 0, name)\n }\n return { added: 1 }\n }\n case 'sheet.remove_sheet': {\n const name = String(args.sheet ?? '')\n if (!wb.SheetNames.includes(name)) {\n const names = wb.SheetNames.map((n) => `\"${n}\"`).join(', ')\n throw new Error(`no sheet named \"${name}\" (sheets: ${names})`)\n }\n if (wb.SheetNames.length === 1) throw new Error('cannot remove the only worksheet')\n wb.SheetNames.splice(wb.SheetNames.indexOf(name), 1)\n delete wb.Sheets[name]\n return { removed: 1 }\n }\n case 'sheet.reorder_sheets': {\n const order = args.order as Array<string | number>\n if (!Array.isArray(order) || order.length !== wb.SheetNames.length) {\n throw new Error(\n `order must include every worksheet exactly once (the workbook has ${wb.SheetNames.length})`\n )\n }\n const resolved = order.map((ref) =>\n typeof ref === 'number' ? wb.SheetNames[ref - 1] : String(ref)\n )\n if (\n new Set(resolved).size !== resolved.length ||\n resolved.some((n) => !n || !wb.SheetNames.includes(n))\n ) {\n throw new Error('order must reference every existing worksheet exactly once')\n }\n wb.SheetNames.length = 0\n wb.SheetNames.push(...resolved)\n return { modified: resolved.length }\n }\n case 'sheet.transform_table': {\n const name = resolveSheetName(wb, args.sheet)\n const headerRow = Number(args.header_row ?? 1)\n const aoa = asAoa(X, wb.Sheets[name])\n const header = (aoa[headerRow - 1] ?? []).map((h) => (h === null ? '' : String(h)))\n let modified = 0\n const rename = args.rename as Array<{ from: string; to: string }> | undefined\n if (rename) {\n for (const { from, to } of rename) {\n const idx = header.indexOf(from)\n if (idx !== -1) {\n aoa[headerRow - 1][idx] = to\n header[idx] = to\n modified++\n }\n }\n }\n const drop = args.drop as string[] | undefined\n const select = args.select as string[] | undefined\n const toRemove = new Set<number>()\n if (drop)\n for (const h of drop) {\n const idx = header.indexOf(h)\n if (idx !== -1) toRemove.add(idx)\n }\n if (select) {\n for (const [i, element] of header.entries()) {\n if (!select.includes(element)) toRemove.add(i)\n }\n }\n if (toRemove.size > 0) {\n const sorted = [...toRemove].sort((a, b) => b - a)\n for (const row of aoa) for (const idx of sorted) if (row.length > idx) row.splice(idx, 1)\n modified += toRemove.size\n }\n rebuild(X, wb, name, aoa)\n return { modified }\n }\n default:\n throw new Error(`sheetjs does not implement edit op \"${op}\"`)\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The SheetJS-backed spreadsheet {@link @nhtio/adk/batteries/media/contracts!MediaEngine}:
3
+ * the in-process, cross-environment spreadsheet converter, generator, and structural editor.
4
+ *
5
+ * @module @nhtio/adk/batteries/media/engines/sheetjs
6
+ *
7
+ * @remarks
8
+ * SheetJS (the `xlsx` package) reads and writes the widest spreadsheet matrix of any pure-JS
9
+ * library — XLSX/XLSM/XLSB, every XLS BIFF era, ODS/FODS, CSV, SYLK, DIF, DBF, HTML, RTF,
10
+ * Apple NUMBERS — with no binary, no native bindings, in any environment. This engine exposes
11
+ * that matrix three ways:
12
+ *
13
+ * - **convert**: any readable spreadsheet MIME → any writable format token.
14
+ * - **generate**: `EMPTY_MIME` → any writable token (a blank `Sheet1` workbook, written out).
15
+ * - **edit**: the `sheet.*` structural ops via CSF cell-object surgery. ⚠️ SheetJS Community
16
+ * Edition does NOT model cell styling — fonts, fills, and comments are STRIPPED by any edit
17
+ * or convert that round-trips a styled workbook (styling is a SheetJS Pro feature). For
18
+ * fidelity-preserving edits compose the exceljs engine FIRST in the engines array; this
19
+ * engine's edits are for unstyled/data workbooks and for breadth (it edits ODS, XLS, and
20
+ * every other readable format by normalizing through CSF).
21
+ *
22
+ * ⚠️ **Install from the SheetJS CDN, not the npm registry.** The registry copy of `xlsx` is
23
+ * frozen at 0.18.5 (2023) and carries CVE-2023-30533 and CVE-2024-22363; this engine requires
24
+ * `>=0.20.2`. Install: `pnpm add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`
25
+ * (SheetJS recommends vendoring the tarball — see docs.sheetjs.com).
26
+ *
27
+ * `xlsx` is an optional peer dependency, lazily imported on first actual use. The NUMBERS
28
+ * write target additionally loads the ZAHL payload (`xlsx/dist/xlsx.zahl.mjs`, ~110 KB) on
29
+ * first request of that specific target.
30
+ */
31
+ import type * as XlsxNS from "../../../bundled_xlsx";
32
+ import type { MediaEngine } from "../contracts";
33
+ type XlsxModule = typeof XlsxNS;
34
+ /** Options for {@link sheetjsEngine}. */
35
+ export interface SheetjsEngineOptions {
36
+ /** Override the module resolution (tests / custom builds). Default: `import('xlsx')`. */
37
+ xlsx?: () => XlsxModule | Promise<XlsxModule>;
38
+ /**
39
+ * Override the ZAHL payload resolution for NUMBERS output (tests / custom builds).
40
+ * Default: `import('xlsx/dist/xlsx.zahl.mjs')`.
41
+ */
42
+ zahl?: () => unknown | Promise<unknown>;
43
+ }
44
+ /**
45
+ * Construct the SheetJS-backed spreadsheet engine.
46
+ *
47
+ * @param options - Optional module resolver overrides.
48
+ * @returns The engine.
49
+ */
50
+ export declare const sheetjsEngine: (options?: SheetjsEngineOptions) => MediaEngine;
51
+ export {};