@frictionless-ts/table 1.0.1

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 (317) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/assets/geojson.json +216 -0
  4. package/build/assets/topojson.json +259 -0
  5. package/build/data/index.d.ts +2 -0
  6. package/build/data/index.js +2 -0
  7. package/build/data/record.d.ts +4 -0
  8. package/build/data/record.js +84 -0
  9. package/build/data/record.spec.d.ts +1 -0
  10. package/build/data/record.spec.js +269 -0
  11. package/build/dialect/Options.d.ts +3 -0
  12. package/build/dialect/Options.js +3 -0
  13. package/build/dialect/index.d.ts +2 -0
  14. package/build/dialect/index.js +2 -0
  15. package/build/dialect/infer.d.ts +4 -0
  16. package/build/dialect/infer.js +2 -0
  17. package/build/field/Field.d.ts +5 -0
  18. package/build/field/Field.js +2 -0
  19. package/build/field/Mapping.d.ts +11 -0
  20. package/build/field/Mapping.js +2 -0
  21. package/build/field/checks/enum.d.ts +8 -0
  22. package/build/field/checks/enum.js +71 -0
  23. package/build/field/checks/enum.spec.d.ts +1 -0
  24. package/build/field/checks/enum.spec.js +327 -0
  25. package/build/field/checks/maxLength.d.ts +7 -0
  26. package/build/field/checks/maxLength.js +17 -0
  27. package/build/field/checks/maxLength.spec.d.ts +1 -0
  28. package/build/field/checks/maxLength.spec.js +49 -0
  29. package/build/field/checks/maximum.d.ts +11 -0
  30. package/build/field/checks/maximum.js +73 -0
  31. package/build/field/checks/maximum.spec.d.ts +1 -0
  32. package/build/field/checks/maximum.spec.js +476 -0
  33. package/build/field/checks/minLength.d.ts +7 -0
  34. package/build/field/checks/minLength.js +17 -0
  35. package/build/field/checks/minLength.spec.d.ts +1 -0
  36. package/build/field/checks/minLength.spec.js +56 -0
  37. package/build/field/checks/minimum.d.ts +11 -0
  38. package/build/field/checks/minimum.js +73 -0
  39. package/build/field/checks/minimum.spec.d.ts +1 -0
  40. package/build/field/checks/minimum.spec.js +476 -0
  41. package/build/field/checks/pattern.d.ts +7 -0
  42. package/build/field/checks/pattern.js +17 -0
  43. package/build/field/checks/pattern.spec.d.ts +1 -0
  44. package/build/field/checks/pattern.spec.js +66 -0
  45. package/build/field/checks/required.d.ts +7 -0
  46. package/build/field/checks/required.js +14 -0
  47. package/build/field/checks/required.spec.d.ts +1 -0
  48. package/build/field/checks/required.spec.js +24 -0
  49. package/build/field/checks/type.d.ts +7 -0
  50. package/build/field/checks/type.js +14 -0
  51. package/build/field/checks/type.spec.d.ts +1 -0
  52. package/build/field/checks/type.spec.js +255 -0
  53. package/build/field/checks/unique.d.ts +7 -0
  54. package/build/field/checks/unique.js +17 -0
  55. package/build/field/checks/unique.spec.d.ts +1 -0
  56. package/build/field/checks/unique.spec.js +97 -0
  57. package/build/field/denormalize.d.ts +6 -0
  58. package/build/field/denormalize.js +13 -0
  59. package/build/field/desubstitute.d.ts +3 -0
  60. package/build/field/desubstitute.js +13 -0
  61. package/build/field/index.d.ts +8 -0
  62. package/build/field/index.js +6 -0
  63. package/build/field/inspect.d.ts +6 -0
  64. package/build/field/inspect.js +131 -0
  65. package/build/field/inspect.spec.d.ts +1 -0
  66. package/build/field/inspect.spec.js +385 -0
  67. package/build/field/narrow.d.ts +3 -0
  68. package/build/field/narrow.js +14 -0
  69. package/build/field/narrow.spec.d.ts +1 -0
  70. package/build/field/narrow.spec.js +52 -0
  71. package/build/field/normalize.d.ts +5 -0
  72. package/build/field/normalize.js +14 -0
  73. package/build/field/parse.d.ts +3 -0
  74. package/build/field/parse.js +47 -0
  75. package/build/field/parse.spec.d.ts +1 -0
  76. package/build/field/parse.spec.js +33 -0
  77. package/build/field/stringify.d.ts +3 -0
  78. package/build/field/stringify.js +43 -0
  79. package/build/field/stringify.spec.d.ts +1 -0
  80. package/build/field/stringify.spec.js +41 -0
  81. package/build/field/substitute.d.ts +3 -0
  82. package/build/field/substitute.js +16 -0
  83. package/build/field/types/array.d.ts +3 -0
  84. package/build/field/types/array.js +5 -0
  85. package/build/field/types/array.spec.d.ts +1 -0
  86. package/build/field/types/array.spec.js +358 -0
  87. package/build/field/types/boolean.d.ts +4 -0
  88. package/build/field/types/boolean.js +31 -0
  89. package/build/field/types/boolean.spec.d.ts +1 -0
  90. package/build/field/types/boolean.spec.js +76 -0
  91. package/build/field/types/date.d.ts +4 -0
  92. package/build/field/types/date.js +14 -0
  93. package/build/field/types/date.spec.d.ts +1 -0
  94. package/build/field/types/date.spec.js +52 -0
  95. package/build/field/types/datetime.d.ts +4 -0
  96. package/build/field/types/datetime.js +15 -0
  97. package/build/field/types/datetime.spec.d.ts +1 -0
  98. package/build/field/types/datetime.spec.js +62 -0
  99. package/build/field/types/duration.d.ts +4 -0
  100. package/build/field/types/duration.js +9 -0
  101. package/build/field/types/duration.spec.d.ts +1 -0
  102. package/build/field/types/duration.spec.js +37 -0
  103. package/build/field/types/geojson.d.ts +3 -0
  104. package/build/field/types/geojson.js +9 -0
  105. package/build/field/types/geojson.spec.d.ts +1 -0
  106. package/build/field/types/geojson.spec.js +522 -0
  107. package/build/field/types/geopoint.d.ts +4 -0
  108. package/build/field/types/geopoint.js +59 -0
  109. package/build/field/types/geopoint.spec.d.ts +1 -0
  110. package/build/field/types/geopoint.spec.js +173 -0
  111. package/build/field/types/integer.d.ts +4 -0
  112. package/build/field/types/integer.js +41 -0
  113. package/build/field/types/integer.spec.d.ts +1 -0
  114. package/build/field/types/integer.spec.js +102 -0
  115. package/build/field/types/json.d.ts +6 -0
  116. package/build/field/types/json.js +68 -0
  117. package/build/field/types/list.d.ts +4 -0
  118. package/build/field/types/list.js +30 -0
  119. package/build/field/types/list.spec.d.ts +1 -0
  120. package/build/field/types/list.spec.js +230 -0
  121. package/build/field/types/number.d.ts +4 -0
  122. package/build/field/types/number.js +50 -0
  123. package/build/field/types/number.spec.d.ts +1 -0
  124. package/build/field/types/number.spec.js +101 -0
  125. package/build/field/types/object.d.ts +3 -0
  126. package/build/field/types/object.js +5 -0
  127. package/build/field/types/object.spec.d.ts +1 -0
  128. package/build/field/types/object.spec.js +393 -0
  129. package/build/field/types/string.d.ts +4 -0
  130. package/build/field/types/string.js +32 -0
  131. package/build/field/types/string.spec.d.ts +1 -0
  132. package/build/field/types/string.spec.js +162 -0
  133. package/build/field/types/time.d.ts +4 -0
  134. package/build/field/types/time.js +18 -0
  135. package/build/field/types/time.spec.d.ts +1 -0
  136. package/build/field/types/time.spec.js +53 -0
  137. package/build/field/types/year.d.ts +4 -0
  138. package/build/field/types/year.js +16 -0
  139. package/build/field/types/year.spec.d.ts +1 -0
  140. package/build/field/types/year.spec.js +50 -0
  141. package/build/field/types/yearmonth.d.ts +4 -0
  142. package/build/field/types/yearmonth.js +14 -0
  143. package/build/field/types/yearmonth.spec.d.ts +1 -0
  144. package/build/field/types/yearmonth.spec.js +36 -0
  145. package/build/helpers.d.ts +4 -0
  146. package/build/helpers.js +12 -0
  147. package/build/index.d.ts +40 -0
  148. package/build/index.js +27 -0
  149. package/build/plugin.d.ts +27 -0
  150. package/build/plugin.js +2 -0
  151. package/build/plugins/arrow/index.d.ts +2 -0
  152. package/build/plugins/arrow/index.js +3 -0
  153. package/build/plugins/arrow/plugin.d.ts +7 -0
  154. package/build/plugins/arrow/plugin.js +22 -0
  155. package/build/plugins/arrow/plugin.spec.d.ts +1 -0
  156. package/build/plugins/arrow/plugin.spec.js +161 -0
  157. package/build/plugins/arrow/table/index.d.ts +2 -0
  158. package/build/plugins/arrow/table/index.js +3 -0
  159. package/build/plugins/arrow/table/load.d.ts +4 -0
  160. package/build/plugins/arrow/table/load.js +23 -0
  161. package/build/plugins/arrow/table/load.spec.d.ts +1 -0
  162. package/build/plugins/arrow/table/load.spec.js +56 -0
  163. package/build/plugins/arrow/table/save.d.ts +3 -0
  164. package/build/plugins/arrow/table/save.js +31 -0
  165. package/build/plugins/arrow/table/save.spec.d.ts +1 -0
  166. package/build/plugins/arrow/table/save.spec.js +81 -0
  167. package/build/plugins/csv/dialect/index.d.ts +1 -0
  168. package/build/plugins/csv/dialect/index.js +2 -0
  169. package/build/plugins/csv/dialect/infer.d.ts +4 -0
  170. package/build/plugins/csv/dialect/infer.js +44 -0
  171. package/build/plugins/csv/dialect/infer.spec.d.ts +1 -0
  172. package/build/plugins/csv/dialect/infer.spec.js +54 -0
  173. package/build/plugins/csv/index.d.ts +2 -0
  174. package/build/plugins/csv/index.js +3 -0
  175. package/build/plugins/csv/plugin.d.ts +8 -0
  176. package/build/plugins/csv/plugin.js +22 -0
  177. package/build/plugins/csv/plugin.spec.d.ts +1 -0
  178. package/build/plugins/csv/plugin.spec.js +161 -0
  179. package/build/plugins/csv/table/index.d.ts +2 -0
  180. package/build/plugins/csv/table/index.js +3 -0
  181. package/build/plugins/csv/table/load.d.ts +6 -0
  182. package/build/plugins/csv/table/load.js +86 -0
  183. package/build/plugins/csv/table/load.spec.d.ts +1 -0
  184. package/build/plugins/csv/table/load.spec.js +293 -0
  185. package/build/plugins/csv/table/save.d.ts +5 -0
  186. package/build/plugins/csv/table/save.js +29 -0
  187. package/build/plugins/csv/table/save.spec.d.ts +1 -0
  188. package/build/plugins/csv/table/save.spec.js +137 -0
  189. package/build/plugins/inline/index.d.ts +2 -0
  190. package/build/plugins/inline/index.js +3 -0
  191. package/build/plugins/inline/plugin.d.ts +7 -0
  192. package/build/plugins/inline/plugin.js +14 -0
  193. package/build/plugins/inline/table/index.d.ts +1 -0
  194. package/build/plugins/inline/table/index.js +2 -0
  195. package/build/plugins/inline/table/load.d.ts +6 -0
  196. package/build/plugins/inline/table/load.js +24 -0
  197. package/build/plugins/inline/table/load.spec.d.ts +1 -0
  198. package/build/plugins/inline/table/load.spec.js +160 -0
  199. package/build/plugins/json/buffer/decode.d.ts +4 -0
  200. package/build/plugins/json/buffer/decode.js +10 -0
  201. package/build/plugins/json/buffer/encode.d.ts +4 -0
  202. package/build/plugins/json/buffer/encode.js +8 -0
  203. package/build/plugins/json/buffer/index.d.ts +2 -0
  204. package/build/plugins/json/buffer/index.js +3 -0
  205. package/build/plugins/json/index.d.ts +2 -0
  206. package/build/plugins/json/index.js +3 -0
  207. package/build/plugins/json/plugin.d.ts +7 -0
  208. package/build/plugins/json/plugin.js +25 -0
  209. package/build/plugins/json/plugin.spec.d.ts +1 -0
  210. package/build/plugins/json/plugin.spec.js +163 -0
  211. package/build/plugins/json/table/index.d.ts +2 -0
  212. package/build/plugins/json/table/index.js +3 -0
  213. package/build/plugins/json/table/load.d.ts +6 -0
  214. package/build/plugins/json/table/load.js +55 -0
  215. package/build/plugins/json/table/load.spec.d.ts +1 -0
  216. package/build/plugins/json/table/load.spec.js +200 -0
  217. package/build/plugins/json/table/parse.d.ts +3 -0
  218. package/build/plugins/json/table/parse.js +6 -0
  219. package/build/plugins/json/table/save.d.ts +5 -0
  220. package/build/plugins/json/table/save.js +45 -0
  221. package/build/plugins/json/table/save.spec.d.ts +1 -0
  222. package/build/plugins/json/table/save.spec.js +147 -0
  223. package/build/plugins/ods/index.d.ts +2 -0
  224. package/build/plugins/ods/index.js +3 -0
  225. package/build/plugins/ods/plugin.d.ts +7 -0
  226. package/build/plugins/ods/plugin.js +23 -0
  227. package/build/plugins/ods/plugin.spec.d.ts +1 -0
  228. package/build/plugins/ods/plugin.spec.js +142 -0
  229. package/build/plugins/ods/table/index.d.ts +2 -0
  230. package/build/plugins/ods/table/index.js +3 -0
  231. package/build/plugins/ods/table/load.d.ts +4 -0
  232. package/build/plugins/ods/table/load.js +41 -0
  233. package/build/plugins/ods/table/load.spec.d.ts +1 -0
  234. package/build/plugins/ods/table/load.spec.js +167 -0
  235. package/build/plugins/ods/table/save.d.ts +3 -0
  236. package/build/plugins/ods/table/save.js +26 -0
  237. package/build/plugins/ods/table/save.spec.d.ts +1 -0
  238. package/build/plugins/ods/table/save.spec.js +75 -0
  239. package/build/plugins/ods/table/test.d.ts +5 -0
  240. package/build/plugins/ods/table/test.js +23 -0
  241. package/build/plugins/parquet/index.d.ts +2 -0
  242. package/build/plugins/parquet/index.js +3 -0
  243. package/build/plugins/parquet/plugin.d.ts +7 -0
  244. package/build/plugins/parquet/plugin.js +23 -0
  245. package/build/plugins/parquet/plugin.spec.d.ts +1 -0
  246. package/build/plugins/parquet/plugin.spec.js +142 -0
  247. package/build/plugins/parquet/table/index.d.ts +2 -0
  248. package/build/plugins/parquet/table/index.js +3 -0
  249. package/build/plugins/parquet/table/load.d.ts +4 -0
  250. package/build/plugins/parquet/table/load.js +23 -0
  251. package/build/plugins/parquet/table/load.spec.d.ts +1 -0
  252. package/build/plugins/parquet/table/load.spec.js +56 -0
  253. package/build/plugins/parquet/table/save.d.ts +3 -0
  254. package/build/plugins/parquet/table/save.js +32 -0
  255. package/build/plugins/parquet/table/save.spec.d.ts +1 -0
  256. package/build/plugins/parquet/table/save.spec.js +81 -0
  257. package/build/plugins/xlxs/index.d.ts +2 -0
  258. package/build/plugins/xlxs/index.js +3 -0
  259. package/build/plugins/xlxs/plugin.d.ts +7 -0
  260. package/build/plugins/xlxs/plugin.js +23 -0
  261. package/build/plugins/xlxs/plugin.spec.d.ts +1 -0
  262. package/build/plugins/xlxs/plugin.spec.js +142 -0
  263. package/build/plugins/xlxs/table/index.d.ts +2 -0
  264. package/build/plugins/xlxs/table/index.js +3 -0
  265. package/build/plugins/xlxs/table/load.d.ts +4 -0
  266. package/build/plugins/xlxs/table/load.js +43 -0
  267. package/build/plugins/xlxs/table/load.spec.d.ts +1 -0
  268. package/build/plugins/xlxs/table/load.spec.js +167 -0
  269. package/build/plugins/xlxs/table/save.d.ts +3 -0
  270. package/build/plugins/xlxs/table/save.js +28 -0
  271. package/build/plugins/xlxs/table/save.spec.d.ts +1 -0
  272. package/build/plugins/xlxs/table/save.spec.js +75 -0
  273. package/build/plugins/xlxs/table/test.d.ts +5 -0
  274. package/build/plugins/xlxs/table/test.js +23 -0
  275. package/build/schema/Mapping.d.ts +6 -0
  276. package/build/schema/Mapping.js +2 -0
  277. package/build/schema/Options.d.ts +22 -0
  278. package/build/schema/Options.js +2 -0
  279. package/build/schema/Schema.d.ts +4 -0
  280. package/build/schema/Schema.js +2 -0
  281. package/build/schema/helpers.d.ts +3 -0
  282. package/build/schema/helpers.js +6 -0
  283. package/build/schema/index.d.ts +8 -0
  284. package/build/schema/index.js +5 -0
  285. package/build/schema/infer.d.ts +13 -0
  286. package/build/schema/infer.js +199 -0
  287. package/build/schema/infer.spec.d.ts +1 -0
  288. package/build/schema/infer.spec.js +304 -0
  289. package/build/schema/match.d.ts +6 -0
  290. package/build/schema/match.js +8 -0
  291. package/build/table/Frame.d.ts +2 -0
  292. package/build/table/Frame.js +2 -0
  293. package/build/table/Table.d.ts +2 -0
  294. package/build/table/Table.js +2 -0
  295. package/build/table/checks/unique.d.ts +7 -0
  296. package/build/table/checks/unique.js +23 -0
  297. package/build/table/checks/unique.spec.d.ts +1 -0
  298. package/build/table/checks/unique.spec.js +187 -0
  299. package/build/table/denormalize.d.ts +6 -0
  300. package/build/table/denormalize.js +15 -0
  301. package/build/table/helpers.d.ts +19 -0
  302. package/build/table/helpers.js +62 -0
  303. package/build/table/helpers.spec.d.ts +1 -0
  304. package/build/table/helpers.spec.js +352 -0
  305. package/build/table/index.d.ts +9 -0
  306. package/build/table/index.js +8 -0
  307. package/build/table/inspect.d.ts +8 -0
  308. package/build/table/inspect.js +165 -0
  309. package/build/table/inspect.spec.d.ts +1 -0
  310. package/build/table/inspect.spec.js +335 -0
  311. package/build/table/normalize.d.ts +6 -0
  312. package/build/table/normalize.js +27 -0
  313. package/build/table/normalize.spec.d.ts +1 -0
  314. package/build/table/normalize.spec.js +222 -0
  315. package/build/table/query.d.ts +3 -0
  316. package/build/table/query.js +6 -0
  317. package/package.json +45 -0
@@ -0,0 +1,142 @@
1
+ import * as pl from "nodejs-polars";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { XlsxPlugin } from "./plugin.js";
4
+ import * as loadModule from "./table/load.js";
5
+ import * as saveModule from "./table/save.js";
6
+ vi.mock("./table/load.ts", () => ({
7
+ loadXlsxTable: vi.fn(),
8
+ }));
9
+ vi.mock("./table/save.ts", () => ({
10
+ saveXlsxTable: vi.fn(),
11
+ }));
12
+ describe("XlsxPlugin", () => {
13
+ let plugin;
14
+ let mockLoadXlsxTable;
15
+ let mockSaveXlsxTable;
16
+ beforeEach(() => {
17
+ plugin = new XlsxPlugin();
18
+ mockLoadXlsxTable = vi.mocked(loadModule.loadXlsxTable);
19
+ mockSaveXlsxTable = vi.mocked(saveModule.saveXlsxTable);
20
+ vi.clearAllMocks();
21
+ });
22
+ describe("loadTable", () => {
23
+ it("should load table from xlsx file", async () => {
24
+ const resource = {
25
+ path: "test.xlsx",
26
+ };
27
+ const mockTable = pl.DataFrame().lazy();
28
+ mockLoadXlsxTable.mockResolvedValue(mockTable);
29
+ const result = await plugin.loadTable(resource);
30
+ expect(mockLoadXlsxTable).toHaveBeenCalledWith(resource, undefined);
31
+ expect(result).toEqual(mockTable);
32
+ });
33
+ it("should return undefined for non-xlsx files", async () => {
34
+ const resource = {
35
+ path: "test.csv",
36
+ };
37
+ const result = await plugin.loadTable(resource);
38
+ expect(mockLoadXlsxTable).not.toHaveBeenCalled();
39
+ expect(result).toBeUndefined();
40
+ });
41
+ it("should handle explicit format specification", async () => {
42
+ const resource = {
43
+ path: "test.txt",
44
+ format: "xlsx",
45
+ };
46
+ const mockTable = pl.DataFrame().lazy();
47
+ mockLoadXlsxTable.mockResolvedValue(mockTable);
48
+ const result = await plugin.loadTable(resource);
49
+ expect(mockLoadXlsxTable).toHaveBeenCalledWith(resource, undefined);
50
+ expect(result).toEqual(mockTable);
51
+ });
52
+ it("should pass through load options", async () => {
53
+ const resource = {
54
+ path: "test.xlsx",
55
+ };
56
+ const options = { denormalized: true };
57
+ const mockTable = pl.DataFrame().lazy();
58
+ mockLoadXlsxTable.mockResolvedValue(mockTable);
59
+ await plugin.loadTable(resource, options);
60
+ expect(mockLoadXlsxTable).toHaveBeenCalledWith(resource, options);
61
+ });
62
+ it("should handle paths with directories", async () => {
63
+ const resource = {
64
+ path: "/path/to/data.xlsx",
65
+ };
66
+ const mockTable = pl.DataFrame().lazy();
67
+ mockLoadXlsxTable.mockResolvedValue(mockTable);
68
+ await plugin.loadTable(resource);
69
+ expect(mockLoadXlsxTable).toHaveBeenCalledWith(resource, undefined);
70
+ });
71
+ it("should return undefined for ods files", async () => {
72
+ const resource = {
73
+ path: "test.ods",
74
+ };
75
+ const result = await plugin.loadTable(resource);
76
+ expect(mockLoadXlsxTable).not.toHaveBeenCalled();
77
+ expect(result).toBeUndefined();
78
+ });
79
+ it("should return undefined for json files", async () => {
80
+ const resource = {
81
+ path: "test.json",
82
+ };
83
+ const result = await plugin.loadTable(resource);
84
+ expect(mockLoadXlsxTable).not.toHaveBeenCalled();
85
+ expect(result).toBeUndefined();
86
+ });
87
+ });
88
+ describe("saveTable", () => {
89
+ it("should save table to xlsx file", async () => {
90
+ const table = pl.DataFrame().lazy();
91
+ const options = { path: "output.xlsx" };
92
+ mockSaveXlsxTable.mockResolvedValue("output.xlsx");
93
+ const result = await plugin.saveTable(table, options);
94
+ expect(mockSaveXlsxTable).toHaveBeenCalledWith(table, options);
95
+ expect(result).toBe("output.xlsx");
96
+ });
97
+ it("should return undefined for non-xlsx files", async () => {
98
+ const table = pl.DataFrame().lazy();
99
+ const options = { path: "output.csv" };
100
+ const result = await plugin.saveTable(table, options);
101
+ expect(mockSaveXlsxTable).not.toHaveBeenCalled();
102
+ expect(result).toBeUndefined();
103
+ });
104
+ it("should handle explicit format specification", async () => {
105
+ const table = pl.DataFrame().lazy();
106
+ const options = { path: "output.txt", format: "xlsx" };
107
+ mockSaveXlsxTable.mockResolvedValue("output.txt");
108
+ const result = await plugin.saveTable(table, options);
109
+ expect(mockSaveXlsxTable).toHaveBeenCalledWith(table, options);
110
+ expect(result).toBe("output.txt");
111
+ });
112
+ it("should handle paths with directories", async () => {
113
+ const table = pl.DataFrame().lazy();
114
+ const options = { path: "/path/to/output.xlsx" };
115
+ mockSaveXlsxTable.mockResolvedValue("/path/to/output.xlsx");
116
+ await plugin.saveTable(table, options);
117
+ expect(mockSaveXlsxTable).toHaveBeenCalledWith(table, options);
118
+ });
119
+ it("should return undefined for files without extension", async () => {
120
+ const table = pl.DataFrame().lazy();
121
+ const options = { path: "output" };
122
+ const result = await plugin.saveTable(table, options);
123
+ expect(mockSaveXlsxTable).not.toHaveBeenCalled();
124
+ expect(result).toBeUndefined();
125
+ });
126
+ it("should return undefined for ods files", async () => {
127
+ const table = pl.DataFrame().lazy();
128
+ const options = { path: "output.ods" };
129
+ const result = await plugin.saveTable(table, options);
130
+ expect(mockSaveXlsxTable).not.toHaveBeenCalled();
131
+ expect(result).toBeUndefined();
132
+ });
133
+ it("should return undefined for json files", async () => {
134
+ const table = pl.DataFrame().lazy();
135
+ const options = { path: "output.json" };
136
+ const result = await plugin.saveTable(table, options);
137
+ expect(mockSaveXlsxTable).not.toHaveBeenCalled();
138
+ expect(result).toBeUndefined();
139
+ });
140
+ });
141
+ });
142
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW5zL3hseHMvcGx1Z2luLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLGlCQUFpQixDQUFBO0FBQzdDLE9BQU8sS0FBSyxVQUFVLE1BQU0saUJBQWlCLENBQUE7QUFFN0MsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ2hDLGFBQWEsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFO0NBQ3ZCLENBQUMsQ0FBQyxDQUFBO0FBRUgsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ2hDLGFBQWEsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFO0NBQ3ZCLENBQUMsQ0FBQyxDQUFBO0FBRUgsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7SUFDMUIsSUFBSSxNQUFrQixDQUFBO0lBQ3RCLElBQUksaUJBQTJDLENBQUE7SUFDL0MsSUFBSSxpQkFBMkMsQ0FBQTtJQUUvQyxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsTUFBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUE7UUFDekIsaUJBQWlCLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDdkQsaUJBQWlCLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDdkQsRUFBRSxDQUFDLGFBQWEs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SSxFQUFFO1lBQ3JELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUNuQyxNQUFNLE9BQU8sR0FBRyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQTtZQUV0QyxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBRXJELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1lBQ2hELE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNoQyxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN0RCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDbkMsTUFBTSxPQUFPLEdBQUcsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUE7WUFFdkMsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUVyRCxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtZQUNoRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUE7UUFDaEMsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSZXNvdXJjZSB9IGZyb20gXCJAZnJpY3Rpb25sZXNzLXRzL21ldGFkYXRhXCJcbmltcG9ydCAqIGFzIHBsIGZyb20gXCJub2RlanMtcG9sYXJzXCJcbmltcG9ydCB7IGJlZm9yZUVhY2gsIGRlc2NyaWJlLCBleHBlY3QsIGl0LCB2aSB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgWGxzeFBsdWdpbiB9IGZyb20gXCIuL3BsdWdpbi50c1wiXG5pbXBvcnQgKiBhcyBsb2FkTW9kdWxlIGZyb20gXCIuL3RhYmxlL2xvYWQudHNcIlxuaW1wb3J0ICogYXMgc2F2ZU1vZHVsZSBmcm9tIFwiLi90YWJsZS9zYXZlLnRzXCJcblxudmkubW9jayhcIi4vdGFibGUvbG9hZC50c1wiLCAoKSA9PiAoe1xuICBsb2FkWGxzeFRhYmxlOiB2aS5mbigpLFxufSkpXG5cbnZpLm1vY2soXCIuL3RhYmxlL3NhdmUudHNcIiwgKCkgPT4gKHtcbiAgc2F2ZVhsc3hUYWJsZTogdmkuZm4oKSxcbn0pKVxuXG5kZXNjcmliZShcIlhsc3hQbHVnaW5cIiwgKCkgPT4ge1xuICBsZXQgcGx1Z2luOiBYbHN4UGx1Z2luXG4gIGxldCBtb2NrTG9hZFhsc3hUYWJsZTogUmV0dXJuVHlwZTx0eXBlb2YgdmkuZm4+XG4gIGxldCBtb2NrU2F2ZVhsc3hUYWJsZTogUmV0dXJuVHlwZTx0eXBlb2YgdmkuZm4+XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgcGx1Z2luID0gbmV3IFhsc3hQbHVnaW4oKVxuICAgIG1vY2tMb2FkWGxzeFRhYmxlID0gdmkubW9ja2VkKGxvYWRNb2R1bGUubG9hZFhsc3hUYWJsZSlcbiAgICBtb2NrU2F2ZVhsc3hUYWJsZSA9IHZpLm1vY2tlZChzYXZlTW9kdWxlLnNhdmVYbHN4VGFibGUpXG4gICAgdmkuY2xlYXJBbGxNb2NrcygpXG4gIH0pXG5cbiAgZGVzY3JpYmUoXCJsb2FkVGFibGVcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGxvYWQgdGFibGUgZnJvbSB4bHN4IGZpbGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzb3VyY2U6IFBhcnRpYWw8UmVzb3VyY2U+ID0ge1xuICAgICAgICBwYXRoOiBcInRlc3QueGxzeFwiLFxuICAgICAgfVxuICAgICAgY29uc3QgbW9ja1RhYmxlID0gcGwuRGF0YUZyYW1lKCkubGF6eSgpXG4gICAgICBtb2NrTG9hZFhsc3hUYWJsZS5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrVGFibGUpXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5sb2FkVGFibGUocmVzb3VyY2UpXG5cbiAgICAgIGV4cGVjdChtb2NrTG9hZFhsc3hUYWJsZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgocmVzb3VyY2UsIHVuZGVmaW5lZClcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwobW9ja1RhYmxlKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gdW5kZWZpbmVkIGZvciBub24teGxzeCBmaWxlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXNvdXJjZTogUGFydGlhbDxSZXNvdXJjZT4gPSB7XG4gICAgICAgIHBhdGg6IFwidGVzdC5jc3ZcIixcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGx1Z2luLmxvYWRUYWJsZShyZXNvdXJjZSlcblxuICAgICAgZXhwZWN0KG1vY2tMb2FkWGxzeFRhYmxlKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlVW5kZWZpbmVkKClcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGV4cGxpY2l0IGZvcm1hdCBzcGVjaWZpY2F0aW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc291cmNlOiBQYXJ0aWFsPFJlc291cmNlPiA9IHtcbiAgICAgICAgcGF0aDogXCJ0ZXN0LnR4dFwiLFxuICAgICAgICBmb3JtYXQ6IFwieGxzeFwiLFxuICAgICAgfVxuICAgICAgY29uc3QgbW9ja1RhYmxlID0gcGwuRGF0YUZyYW1lKCkubGF6eSgpXG4gICAgICBtb2NrTG9hZFhsc3hUYWJsZS5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrVGFibGUpXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5sb2FkVGFibGUocmVzb3VyY2UpXG5cbiAgICAgIGV4cGVjdChtb2NrTG9hZFhsc3hUYWJsZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgocmVzb3VyY2UsIHVuZGVmaW5lZClcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwobW9ja1RhYmxlKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBwYXNzIHRocm91Z2ggbG9hZCBvcHRpb25zXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc291cmNlOiBQYXJ0aWFsPFJlc291cmNlPiA9IHtcbiAgICAgICAgcGF0aDogXCJ0ZXN0Lnhsc3hcIixcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IGRlbm9ybWFsaXplZDogdHJ1ZSB9XG4gICAgICBjb25zdCBtb2NrVGFibGUgPSBwbC5EYXRhRnJhbWUoKS5sYXp5KClcbiAgICAgIG1vY2tMb2FkWGxzeFRhYmxlLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tUYWJsZSlcblxuICAgICAgYXdhaXQgcGx1Z2luLmxvYWRUYWJsZShyZXNvdXJjZSwgb3B0aW9ucylcblxuICAgICAgZXhwZWN0KG1vY2tMb2FkWGxzeFRhYmxlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChyZXNvdXJjZSwgb3B0aW9ucylcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIHBhdGhzIHdpdGggZGlyZWN0b3JpZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzb3VyY2U6IFBhcnRpYWw8UmVzb3VyY2U+ID0ge1xuICAgICAgICBwYXRoOiBcIi9wYXRoL3RvL2RhdGEueGxzeFwiLFxuICAgICAgfVxuICAgICAgY29uc3QgbW9ja1RhYmxlID0gcGwuRGF0YUZyYW1lKCkubGF6eSgpXG4gICAgICBtb2NrTG9hZFhsc3hUYWJsZS5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrVGFibGUpXG5cbiAgICAgIGF3YWl0IHBsdWdpbi5sb2FkVGFibGUocmVzb3VyY2UpXG5cbiAgICAgIGV4cGVjdChtb2NrTG9hZFhsc3hUYWJsZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgocmVzb3VyY2UsIHVuZGVmaW5lZClcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBmb3Igb2RzIGZpbGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc291cmNlOiBQYXJ0aWFsPFJlc291cmNlPiA9IHtcbiAgICAgICAgcGF0aDogXCJ0ZXN0Lm9kc1wiLFxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwbHVnaW4ubG9hZFRhYmxlKHJlc291cmNlKVxuXG4gICAgICBleHBlY3QobW9ja0xvYWRYbHN4VGFibGUpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVVbmRlZmluZWQoKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gdW5kZWZpbmVkIGZvciBqc29uIGZpbGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc291cmNlOiBQYXJ0aWFsPFJlc291cmNlPiA9IHtcbiAgICAgICAgcGF0aDogXCJ0ZXN0Lmpzb25cIixcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGx1Z2luLmxvYWRUYWJsZShyZXNvdXJjZSlcblxuICAgICAgZXhwZWN0KG1vY2tMb2FkWGxzeFRhYmxlKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlVW5kZWZpbmVkKClcbiAgICB9KVxuICB9KVxuXG4gIGRlc2NyaWJlKFwic2F2ZVRhYmxlXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzYXZlIHRhYmxlIHRvIHhsc3ggZmlsZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0YWJsZSA9IHBsLkRhdGFGcmFtZSgpLmxhenkoKVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHsgcGF0aDogXCJvdXRwdXQueGxzeFwiIH1cbiAgICAgIG1vY2tTYXZlWGxzeFRhYmxlLm1vY2tSZXNvbHZlZFZhbHVlKFwib3V0cHV0Lnhsc3hcIilcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGx1Z2luLnNhdmVUYWJsZSh0YWJsZSwgb3B0aW9ucylcblxuICAgICAgZXhwZWN0KG1vY2tTYXZlWGxzeFRhYmxlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh0YWJsZSwgb3B0aW9ucylcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJvdXRwdXQueGxzeFwiKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gdW5kZWZpbmVkIGZvciBub24teGxzeCBmaWxlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0YWJsZSA9IHBsLkRhdGFGcmFtZSgpLmxhenkoKVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHsgcGF0aDogXCJvdXRwdXQuY3N2XCIgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwbHVnaW4uc2F2ZVRhYmxlKHRhYmxlLCBvcHRpb25zKVxuXG4gICAgICBleHBlY3QobW9ja1NhdmVYbHN4VGFibGUpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKClcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVVbmRlZmluZWQoKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgZXhwbGljaXQgZm9ybWF0IHNwZWNpZmljYXRpb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGFibGUgPSBwbC5EYXRhRnJhbWUoKS5sYXp5KClcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IHBhdGg6IFwib3V0cHV0LnR4dFwiLCBmb3JtYXQ6IFwieGxzeFwiIGFzIGNvbnN0IH1cbiAgICAgIG1vY2tTYXZlWGxzeFRhYmxlLm1vY2tSZXNvbHZlZFZhbHVlKFwib3V0cHV0LnR4dFwiKVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwbHVnaW4uc2F2ZVRhYmxlKHRhYmxlLCBvcHRpb25zKVxuXG4gICAgICBleHBlY3QobW9ja1NhdmVYbHN4VGFibGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHRhYmxlLCBvcHRpb25zKVxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZShcIm91dHB1dC50eHRcIilcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIHBhdGhzIHdpdGggZGlyZWN0b3JpZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGFibGUgPSBwbC5EYXRhRnJhbWUoKS5sYXp5KClcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IHBhdGg6IFwiL3BhdGgvdG8vb3V0cHV0Lnhsc3hcIiB9XG4gICAgICBtb2NrU2F2ZVhsc3hUYWJsZS5tb2NrUmVzb2x2ZWRWYWx1ZShcIi9wYXRoL3RvL291dHB1dC54bHN4XCIpXG5cbiAgICAgIGF3YWl0IHBsdWdpbi5zYXZlVGFibGUodGFibGUsIG9wdGlvbnMpXG5cbiAgICAgIGV4cGVjdChtb2NrU2F2ZVhsc3hUYWJsZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgodGFibGUsIG9wdGlvbnMpXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIHJldHVybiB1bmRlZmluZWQgZm9yIGZpbGVzIHdpdGhvdXQgZXh0ZW5zaW9uXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRhYmxlID0gcGwuRGF0YUZyYW1lKCkubGF6eSgpXG4gICAgICBjb25zdCBvcHRpb25zID0geyBwYXRoOiBcIm91dHB1dFwiIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGx1Z2luLnNhdmVUYWJsZSh0YWJsZSwgb3B0aW9ucylcblxuICAgICAgZXhwZWN0KG1vY2tTYXZlWGxzeFRhYmxlKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlVW5kZWZpbmVkKClcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBmb3Igb2RzIGZpbGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRhYmxlID0gcGwuRGF0YUZyYW1lKCkubGF6eSgpXG4gICAgICBjb25zdCBvcHRpb25zID0geyBwYXRoOiBcIm91dHB1dC5vZHNcIiB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5zYXZlVGFibGUodGFibGUsIG9wdGlvbnMpXG5cbiAgICAgIGV4cGVjdChtb2NrU2F2ZVhsc3hUYWJsZSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKVxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZVVuZGVmaW5lZCgpXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIHJldHVybiB1bmRlZmluZWQgZm9yIGpzb24gZmlsZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGFibGUgPSBwbC5EYXRhRnJhbWUoKS5sYXp5KClcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IHBhdGg6IFwib3V0cHV0Lmpzb25cIiB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBsdWdpbi5zYXZlVGFibGUodGFibGUsIG9wdGlvbnMpXG5cbiAgICAgIGV4cGVjdChtb2NrU2F2ZVhsc3hUYWJsZSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKVxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZVVuZGVmaW5lZCgpXG4gICAgfSlcbiAgfSlcbn0pXG4iXX0=
@@ -0,0 +1,2 @@
1
+ export { loadXlsxTable } from "./load.ts";
2
+ export { saveXlsxTable } from "./save.ts";
@@ -0,0 +1,3 @@
1
+ export { loadXlsxTable } from "./load.js";
2
+ export { saveXlsxTable } from "./save.js";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wbHVnaW5zL3hseHMvdGFibGUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgbG9hZFhsc3hUYWJsZSB9IGZyb20gXCIuL2xvYWQudHNcIlxuZXhwb3J0IHsgc2F2ZVhsc3hUYWJsZSB9IGZyb20gXCIuL3NhdmUudHNcIlxuIl19
@@ -0,0 +1,4 @@
1
+ import type { Resource } from "@frictionless-ts/metadata";
2
+ import type { LoadTableOptions } from "../../../plugin.ts";
3
+ import * as pl from "nodejs-polars";
4
+ export declare function loadXlsxTable(resource: Partial<Resource>, options?: LoadTableOptions): Promise<pl.LazyDataFrame<any>>;
@@ -0,0 +1,43 @@
1
+ import { resolveDialect } from "@frictionless-ts/metadata";
2
+ import { resolveSchema } from "@frictionless-ts/metadata";
3
+ import { loadFile, prefetchFiles } from "@frictionless-ts/dataset";
4
+ import { getRecordsFromRows } from "../../../data/index.js";
5
+ import { inferSchemaFromTable } from "../../../schema/index.js";
6
+ import { normalizeTable } from "../../../table/index.js";
7
+ import * as pl from "nodejs-polars";
8
+ import { read, utils } from "xlsx";
9
+ // Currently, we use slow non-rust implementation as in the future
10
+ // polars-rust might be able to provide a faster native implementation
11
+ export async function loadXlsxTable(resource, options) {
12
+ const paths = await prefetchFiles(resource.path);
13
+ if (!paths.length) {
14
+ throw new Error("Resource path is not defined");
15
+ }
16
+ const dialect = await resolveDialect(resource.dialect);
17
+ const tables = [];
18
+ for (const path of paths) {
19
+ const buffer = await loadFile(path);
20
+ const book = read(buffer, { type: "buffer" });
21
+ const sheetIndex = dialect?.sheetNumber ? dialect.sheetNumber - 1 : 0;
22
+ const sheetName = dialect?.sheetName ?? book.SheetNames[sheetIndex];
23
+ const sheet = sheetName ? book.Sheets[sheetName] : undefined;
24
+ if (sheet) {
25
+ const rows = utils.sheet_to_json(sheet, {
26
+ header: 1,
27
+ raw: true,
28
+ });
29
+ const records = getRecordsFromRows(rows, dialect);
30
+ const table = pl.DataFrame(records).lazy();
31
+ tables.push(table);
32
+ }
33
+ }
34
+ let table = pl.concat(tables);
35
+ if (!options?.denormalized) {
36
+ let schema = await resolveSchema(resource.schema);
37
+ if (!schema)
38
+ schema = await inferSchemaFromTable(table, options);
39
+ table = await normalizeTable(table, schema);
40
+ }
41
+ return table;
42
+ }
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BsdWdpbnMveGx4cy90YWJsZS9sb2FkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUUxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUVsRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUUzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFFeEQsT0FBTyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDbkMsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFFbEMsa0VBQWtFO0FBQ2xFLHNFQUFzRTtBQUV0RSxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FDakMsUUFBMkIsRUFDM0IsT0FBMEI7SUFFMUIsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQ2pELENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFdEQsTUFBTSxNQUFNLEdBQVksRUFBRSxDQUFBO0lBQzFCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFbkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFBO1FBQzdDLE1BQU0sVUFBVSxHQUFHLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDckUsTUFBTSxTQUFTLEdBQUcsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ25FLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO1FBRTVELElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRTtnQkFDdEMsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsR0FBRyxFQUFFLElBQUk7YUFDVixDQUFjLENBQUE7WUFFZixNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDakQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUUxQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUU3QixJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDO1FBQzNCLElBQUksTUFBTSxHQUFHLE1BQU0sYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNqRCxJQUFJLENBQUMsTUFBTTtZQUFFLE1BQU0sR0FBRyxNQUFNLG9CQUFvQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUNoRSxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzdDLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZXNvbHZlRGlhbGVjdCB9IGZyb20gXCJAZnJpY3Rpb25sZXNzLXRzL21ldGFkYXRhXCJcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2UgfSBmcm9tIFwiQGZyaWN0aW9ubGVzcy10cy9tZXRhZGF0YVwiXG5pbXBvcnQgeyByZXNvbHZlU2NoZW1hIH0gZnJvbSBcIkBmcmljdGlvbmxlc3MtdHMvbWV0YWRhdGFcIlxuaW1wb3J0IHsgbG9hZEZpbGUsIHByZWZldGNoRmlsZXMgfSBmcm9tIFwiQGZyaWN0aW9ubGVzcy10cy9kYXRhc2V0XCJcbmltcG9ydCB0eXBlIHsgRGF0YVJvdyB9IGZyb20gXCIuLi8uLi8uLi9kYXRhL2luZGV4LnRzXCJcbmltcG9ydCB7IGdldFJlY29yZHNGcm9tUm93cyB9IGZyb20gXCIuLi8uLi8uLi9kYXRhL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgTG9hZFRhYmxlT3B0aW9ucyB9IGZyb20gXCIuLi8uLi8uLi9wbHVnaW4udHNcIlxuaW1wb3J0IHsgaW5mZXJTY2hlbWFGcm9tVGFibGUgfSBmcm9tIFwiLi4vLi4vLi4vc2NoZW1hL2luZGV4LnRzXCJcbmltcG9ydCB7IG5vcm1hbGl6ZVRhYmxlIH0gZnJvbSBcIi4uLy4uLy4uL3RhYmxlL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgVGFibGUgfSBmcm9tIFwiLi4vLi4vLi4vdGFibGUvaW5kZXgudHNcIlxuaW1wb3J0ICogYXMgcGwgZnJvbSBcIm5vZGVqcy1wb2xhcnNcIlxuaW1wb3J0IHsgcmVhZCwgdXRpbHMgfSBmcm9tIFwieGxzeFwiXG5cbi8vIEN1cnJlbnRseSwgd2UgdXNlIHNsb3cgbm9uLXJ1c3QgaW1wbGVtZW50YXRpb24gYXMgaW4gdGhlIGZ1dHVyZVxuLy8gcG9sYXJzLXJ1c3QgbWlnaHQgYmUgYWJsZSB0byBwcm92aWRlIGEgZmFzdGVyIG5hdGl2ZSBpbXBsZW1lbnRhdGlvblxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFhsc3hUYWJsZShcbiAgcmVzb3VyY2U6IFBhcnRpYWw8UmVzb3VyY2U+LFxuICBvcHRpb25zPzogTG9hZFRhYmxlT3B0aW9ucyxcbikge1xuICBjb25zdCBwYXRocyA9IGF3YWl0IHByZWZldGNoRmlsZXMocmVzb3VyY2UucGF0aClcbiAgaWYgKCFwYXRocy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZXNvdXJjZSBwYXRoIGlzIG5vdCBkZWZpbmVkXCIpXG4gIH1cblxuICBjb25zdCBkaWFsZWN0ID0gYXdhaXQgcmVzb2x2ZURpYWxlY3QocmVzb3VyY2UuZGlhbGVjdClcblxuICBjb25zdCB0YWJsZXM6IFRhYmxlW10gPSBbXVxuICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICBjb25zdCBidWZmZXIgPSBhd2FpdCBsb2FkRmlsZShwYXRoKVxuXG4gICAgY29uc3QgYm9vayA9IHJlYWQoYnVmZmVyLCB7IHR5cGU6IFwiYnVmZmVyXCIgfSlcbiAgICBjb25zdCBzaGVldEluZGV4ID0gZGlhbGVjdD8uc2hlZXROdW1iZXIgPyBkaWFsZWN0LnNoZWV0TnVtYmVyIC0gMSA6IDBcbiAgICBjb25zdCBzaGVldE5hbWUgPSBkaWFsZWN0Py5zaGVldE5hbWUgPz8gYm9vay5TaGVldE5hbWVzW3NoZWV0SW5kZXhdXG4gICAgY29uc3Qgc2hlZXQgPSBzaGVldE5hbWUgPyBib29rLlNoZWV0c1tzaGVldE5hbWVdIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoc2hlZXQpIHtcbiAgICAgIGNvbnN0IHJvd3MgPSB1dGlscy5zaGVldF90b19qc29uKHNoZWV0LCB7XG4gICAgICAgIGhlYWRlcjogMSxcbiAgICAgICAgcmF3OiB0cnVlLFxuICAgICAgfSkgYXMgRGF0YVJvd1tdXG5cbiAgICAgIGNvbnN0IHJlY29yZHMgPSBnZXRSZWNvcmRzRnJvbVJvd3Mocm93cywgZGlhbGVjdClcbiAgICAgIGNvbnN0IHRhYmxlID0gcGwuRGF0YUZyYW1lKHJlY29yZHMpLmxhenkoKVxuXG4gICAgICB0YWJsZXMucHVzaCh0YWJsZSlcbiAgICB9XG4gIH1cblxuICBsZXQgdGFibGUgPSBwbC5jb25jYXQodGFibGVzKVxuXG4gIGlmICghb3B0aW9ucz8uZGVub3JtYWxpemVkKSB7XG4gICAgbGV0IHNjaGVtYSA9IGF3YWl0IHJlc29sdmVTY2hlbWEocmVzb3VyY2Uuc2NoZW1hKVxuICAgIGlmICghc2NoZW1hKSBzY2hlbWEgPSBhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSwgb3B0aW9ucylcbiAgICB0YWJsZSA9IGF3YWl0IG5vcm1hbGl6ZVRhYmxlKHRhYmxlLCBzY2hlbWEpXG4gIH1cblxuICByZXR1cm4gdGFibGVcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,167 @@
1
+ import { getTempFilePath } from "@frictionless-ts/dataset";
2
+ import { describe, expect, it } from "vitest";
3
+ import { useRecording } from "vitest-polly";
4
+ import { loadXlsxTable } from "./load.js";
5
+ import { writeTestData } from "./test.js";
6
+ useRecording();
7
+ const row1 = ["id", "name"];
8
+ const row2 = [1, "english"];
9
+ const row3 = [2, "中文"];
10
+ const record1 = { id: 1, name: "english" };
11
+ const record2 = { id: 2, name: "中文" };
12
+ describe("loadXlsxTable", () => {
13
+ describe("file variations", () => {
14
+ it("should load local file", async () => {
15
+ const path = getTempFilePath();
16
+ await writeTestData(path, [row1, row2, row3]);
17
+ const table = await loadXlsxTable({ path });
18
+ expect((await table.collect()).toRecords()).toEqual([record1, record2]);
19
+ });
20
+ it("should load local file (multipart)", async () => {
21
+ const path1 = getTempFilePath();
22
+ const path2 = getTempFilePath();
23
+ await writeTestData(path1, [row1, row2, row3]);
24
+ await writeTestData(path2, [row1, row2, row3]);
25
+ const table = await loadXlsxTable({ path: [path1, path2] });
26
+ expect((await table.collect()).toRecords()).toEqual([
27
+ record1,
28
+ record2,
29
+ record1,
30
+ record2,
31
+ ]);
32
+ });
33
+ it("should load remote file", async () => {
34
+ const table = await loadXlsxTable({
35
+ path: "https://raw.githubusercontent.com/datisthq/dpkit/refs/heads/main/xlsx/table/fixtures/table.xlsx",
36
+ });
37
+ expect((await table.collect()).toRecords()).toEqual([
38
+ { id: 1, name: "english" },
39
+ { id: 2, name: "中文" },
40
+ ]);
41
+ });
42
+ it("should load multipart remote file", async () => {
43
+ const table = await loadXlsxTable({
44
+ path: [
45
+ "https://raw.githubusercontent.com/datisthq/dpkit/refs/heads/main/xlsx/table/fixtures/table.xlsx",
46
+ "https://raw.githubusercontent.com/datisthq/dpkit/refs/heads/main/xlsx/table/fixtures/table.xlsx",
47
+ ],
48
+ });
49
+ expect((await table.collect()).toRecords()).toEqual([
50
+ { id: 1, name: "english" },
51
+ { id: 2, name: "中文" },
52
+ { id: 1, name: "english" },
53
+ { id: 2, name: "中文" },
54
+ ]);
55
+ });
56
+ });
57
+ describe("dialect variations", () => {
58
+ it("should support sheetNumber", async () => {
59
+ const path = getTempFilePath();
60
+ await writeTestData(path, [row1, row2, row3], { sheetNumber: 2 });
61
+ const table = await loadXlsxTable({
62
+ path,
63
+ dialect: { sheetNumber: 2 },
64
+ });
65
+ expect((await table.collect()).toRecords()).toEqual([record1, record2]);
66
+ });
67
+ it("should support sheetName", async () => {
68
+ const path = getTempFilePath();
69
+ await writeTestData(path, [row1, row2, row3], { sheetName: "Sheet2" });
70
+ const table = await loadXlsxTable({
71
+ path,
72
+ dialect: { sheetName: "Sheet2" },
73
+ });
74
+ expect((await table.collect()).toRecords()).toEqual([record1, record2]);
75
+ });
76
+ it("should support no header", async () => {
77
+ const path = getTempFilePath();
78
+ await writeTestData(path, [row2, row3]);
79
+ const table = await loadXlsxTable({
80
+ path,
81
+ dialect: { header: false },
82
+ });
83
+ expect((await table.collect()).toRecords()).toEqual([
84
+ { field1: 1, field2: "english" },
85
+ { field1: 2, field2: "中文" },
86
+ ]);
87
+ });
88
+ it("should support headerRows offset", async () => {
89
+ const path = getTempFilePath();
90
+ await writeTestData(path, [row1, row2, row3]);
91
+ const table = await loadXlsxTable({
92
+ path,
93
+ dialect: { headerRows: [2] },
94
+ });
95
+ expect((await table.collect()).toRecords()).toEqual([
96
+ { 1: 2, english: "中文" },
97
+ ]);
98
+ });
99
+ it("should support multiline headerRows", async () => {
100
+ const path = getTempFilePath();
101
+ await writeTestData(path, [row1, row2, row3]);
102
+ const table = await loadXlsxTable({
103
+ path,
104
+ dialect: { headerRows: [1, 2] },
105
+ });
106
+ expect((await table.collect()).toRecords()).toEqual([
107
+ { "id 1": 2, "name english": "中文" },
108
+ ]);
109
+ });
110
+ it("should support headerJoin", async () => {
111
+ const path = getTempFilePath();
112
+ await writeTestData(path, [row1, row2, row3]);
113
+ const table = await loadXlsxTable({
114
+ path,
115
+ dialect: { headerRows: [1, 2], headerJoin: "-" },
116
+ });
117
+ expect((await table.collect()).toRecords()).toEqual([
118
+ { "id-1": 2, "name-english": "中文" },
119
+ ]);
120
+ });
121
+ it("should support commentRows", async () => {
122
+ const path = getTempFilePath();
123
+ await writeTestData(path, [row1, row2, row3]);
124
+ const table = await loadXlsxTable({
125
+ path,
126
+ dialect: { commentRows: [2] },
127
+ });
128
+ expect((await table.collect()).toRecords()).toEqual([record2]);
129
+ });
130
+ it("should support commentChar", async () => {
131
+ const path = getTempFilePath();
132
+ await writeTestData(path, [row1, row2, row3, ["#comment"]]);
133
+ const table = await loadXlsxTable({
134
+ path,
135
+ dialect: { commentChar: "#" },
136
+ });
137
+ expect((await table.collect()).toRecords()).toEqual([record1, record2]);
138
+ });
139
+ it("should handle longer rows", async () => {
140
+ const path = getTempFilePath();
141
+ await writeTestData(path, [row1, row2, row3, [3, "german", "bad"]]);
142
+ const table = await loadXlsxTable({
143
+ path,
144
+ dialect: { commentChar: "#" },
145
+ });
146
+ expect((await table.collect()).toRecords()).toEqual([
147
+ record1,
148
+ record2,
149
+ { id: 3, name: "german" },
150
+ ]);
151
+ });
152
+ it("should handle shorter rows", async () => {
153
+ const path = getTempFilePath();
154
+ await writeTestData(path, [row1, row2, row3, [3]]);
155
+ const table = await loadXlsxTable({
156
+ path,
157
+ dialect: { commentChar: "#" },
158
+ });
159
+ expect((await table.collect()).toRecords()).toEqual([
160
+ record1,
161
+ record2,
162
+ { id: 3, name: null },
163
+ ]);
164
+ });
165
+ });
166
+ });
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGx1Z2lucy94bHhzL3RhYmxlL2xvYWQuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDMUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFDM0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXpDLFlBQVksRUFBRSxDQUFBO0FBRWQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7QUFDM0IsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFDM0IsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7QUFFdEIsTUFBTSxPQUFPLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQTtBQUMxQyxNQUFNLE9BQU8sR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFBO0FBRXJDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO0lBQzdCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUU7UUFDL0IsRUFBRSxDQUFDLHdCQUF3QixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3RDLE1BQU0sSUFBSSxHQUFHLGVBQWUsRUFBRSxDQUFBO1lBQzlCLE1BQU0sYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FB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RUFBRTthQUM5QixDQUFDLENBQUE7WUFFRixNQUFNLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNsRCxPQUFPO2dCQUNQLE9BQU87Z0JBQ1AsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7YUFDMUIsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7UUFFRixFQUFFLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDMUMsTUFBTSxJQUFJLEdBQUcsZUFBZSxFQUFFLENBQUE7WUFDOUIsTUFBTSxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFFbEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUM7Z0JBQ2hDLElBQUk7Z0JBQ0osT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTthQUM5QixDQUFDLENBQUE7WUFFRixNQUFNLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNsRCxPQUFPO2dCQUNQLE9BQU87Z0JBQ1AsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUU7YUFDdEIsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0VGVtcEZpbGVQYXRoIH0gZnJvbSBcIkBmcmljdGlvbmxlc3MtdHMvZGF0YXNldFwiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlc3RcIlxuaW1wb3J0IHsgdXNlUmVjb3JkaW5nIH0gZnJvbSBcInZpdGVzdC1wb2xseVwiXG5pbXBvcnQgeyBsb2FkWGxzeFRhYmxlIH0gZnJvbSBcIi4vbG9hZC50c1wiXG5pbXBvcnQgeyB3cml0ZVRlc3REYXRhIH0gZnJvbSBcIi4vdGVzdC50c1wiXG5cbnVzZVJlY29yZGluZygpXG5cbmNvbnN0IHJvdzEgPSBbXCJpZFwiLCBcIm5hbWVcIl1cbmNvbnN0IHJvdzIgPSBbMSwgXCJlbmdsaXNoXCJdXG5jb25zdCByb3czID0gWzIsIFwi5Lit5paHXCJdXG5cbmNvbnN0IHJlY29yZDEgPSB7IGlkOiAxLCBuYW1lOiBcImVuZ2xpc2hcIiB9XG5jb25zdCByZWNvcmQyID0geyBpZDogMiwgbmFtZTogXCLkuK3mlodcIiB9XG5cbmRlc2NyaWJlKFwibG9hZFhsc3hUYWJsZVwiLCAoKSA9PiB7XG4gIGRlc2NyaWJlKFwiZmlsZSB2YXJpYXRpb25zXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBsb2FkIGxvY2FsIGZpbGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cxLCByb3cyLCByb3czXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHsgcGF0aCB9KVxuICAgICAgZXhwZWN0KChhd2FpdCB0YWJsZS5jb2xsZWN0KCkpLnRvUmVjb3JkcygpKS50b0VxdWFsKFtyZWNvcmQxLCByZWNvcmQyXSlcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgbG9hZCBsb2NhbCBmaWxlIChtdWx0aXBhcnQpXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhdGgxID0gZ2V0VGVtcEZpbGVQYXRoKClcbiAgICAgIGNvbnN0IHBhdGgyID0gZ2V0VGVtcEZpbGVQYXRoKClcbiAgICAgIGF3YWl0IHdyaXRlVGVzdERhdGEocGF0aDEsIFtyb3cxLCByb3cyLCByb3czXSlcbiAgICAgIGF3YWl0IHdyaXRlVGVzdERhdGEocGF0aDIsIFtyb3cxLCByb3cyLCByb3czXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHsgcGF0aDogW3BhdGgxLCBwYXRoMl0gfSlcbiAgICAgIGV4cGVjdCgoYXdhaXQgdGFibGUuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICAgIHJlY29yZDEsXG4gICAgICAgIHJlY29yZDIsXG4gICAgICAgIHJlY29yZDEsXG4gICAgICAgIHJlY29yZDIsXG4gICAgICBdKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBsb2FkIHJlbW90ZSBmaWxlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRhYmxlID0gYXdhaXQgbG9hZFhsc3hUYWJsZSh7XG4gICAgICAgIHBhdGg6IFwiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGlzdGhxL2Rwa2l0L3JlZnMvaGVhZHMvbWFpbi94bHN4L3RhYmxlL2ZpeHR1cmVzL3RhYmxlLnhsc3hcIixcbiAgICAgIH0pXG5cbiAgICAgIGV4cGVjdCgoYXdhaXQgdGFibGUuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICAgIHsgaWQ6IDEsIG5hbWU6IFwiZW5nbGlzaFwiIH0sXG4gICAgICAgIHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfSxcbiAgICAgIF0pXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIGxvYWQgbXVsdGlwYXJ0IHJlbW90ZSBmaWxlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRhYmxlID0gYXdhaXQgbG9hZFhsc3hUYWJsZSh7XG4gICAgICAgIHBhdGg6IFtcbiAgICAgICAgICBcImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kYXRpc3RocS9kcGtpdC9yZWZzL2hlYWRzL21haW4veGxzeC90YWJsZS9maXh0dXJlcy90YWJsZS54bHN4XCIsXG4gICAgICAgICAgXCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vZGF0aXN0aHEvZHBraXQvcmVmcy9oZWFkcy9tYWluL3hsc3gvdGFibGUvZml4dHVyZXMvdGFibGUueGxzeFwiLFxuICAgICAgICBdLFxuICAgICAgfSlcblxuICAgICAgZXhwZWN0KChhd2FpdCB0YWJsZS5jb2xsZWN0KCkpLnRvUmVjb3JkcygpKS50b0VxdWFsKFtcbiAgICAgICAgeyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfSxcbiAgICAgICAgeyBpZDogMiwgbmFtZTogXCLkuK3mlodcIiB9LFxuICAgICAgICB7IGlkOiAxLCBuYW1lOiBcImVuZ2xpc2hcIiB9LFxuICAgICAgICB7IGlkOiAyLCBuYW1lOiBcIuS4reaWh1wiIH0sXG4gICAgICBdKVxuICAgIH0pXG4gIH0pXG5cbiAgZGVzY3JpYmUoXCJkaWFsZWN0IHZhcmlhdGlvbnNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgc2hlZXROdW1iZXJcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cxLCByb3cyLCByb3czXSwgeyBzaGVldE51bWJlcjogMiB9KVxuXG4gICAgICBjb25zdCB0YWJsZSA9IGF3YWl0IGxvYWRYbHN4VGFibGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBkaWFsZWN0OiB7IHNoZWV0TnVtYmVyOiAyIH0sXG4gICAgICB9KVxuXG4gICAgICBleHBlY3QoKGF3YWl0IHRhYmxlLmNvbGxlY3QoKSkudG9SZWNvcmRzKCkpLnRvRXF1YWwoW3JlY29yZDEsIHJlY29yZDJdKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IHNoZWV0TmFtZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gZ2V0VGVtcEZpbGVQYXRoKClcbiAgICAgIGF3YWl0IHdyaXRlVGVzdERhdGEocGF0aCwgW3JvdzEsIHJvdzIsIHJvdzNdLCB7IHNoZWV0TmFtZTogXCJTaGVldDJcIiB9KVxuXG4gICAgICBjb25zdCB0YWJsZSA9IGF3YWl0IGxvYWRYbHN4VGFibGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBkaWFsZWN0OiB7IHNoZWV0TmFtZTogXCJTaGVldDJcIiB9LFxuICAgICAgfSlcblxuICAgICAgZXhwZWN0KChhd2FpdCB0YWJsZS5jb2xsZWN0KCkpLnRvUmVjb3JkcygpKS50b0VxdWFsKFtyZWNvcmQxLCByZWNvcmQyXSlcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBubyBoZWFkZXJcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cyLCByb3czXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgZGlhbGVjdDogeyBoZWFkZXI6IGZhbHNlIH0sXG4gICAgICB9KVxuXG4gICAgICBleHBlY3QoKGF3YWl0IHRhYmxlLmNvbGxlY3QoKSkudG9SZWNvcmRzKCkpLnRvRXF1YWwoW1xuICAgICAgICB7IGZpZWxkMTogMSwgZmllbGQyOiBcImVuZ2xpc2hcIiB9LFxuICAgICAgICB7IGZpZWxkMTogMiwgZmllbGQyOiBcIuS4reaWh1wiIH0sXG4gICAgICBdKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGhlYWRlclJvd3Mgb2Zmc2V0XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBnZXRUZW1wRmlsZVBhdGgoKVxuICAgICAgYXdhaXQgd3JpdGVUZXN0RGF0YShwYXRoLCBbcm93MSwgcm93Miwgcm93M10pXG5cbiAgICAgIGNvbnN0IHRhYmxlID0gYXdhaXQgbG9hZFhsc3hUYWJsZSh7XG4gICAgICAgIHBhdGgsXG4gICAgICAgIGRpYWxlY3Q6IHsgaGVhZGVyUm93czogWzJdIH0sXG4gICAgICB9KVxuXG4gICAgICBleHBlY3QoKGF3YWl0IHRhYmxlLmNvbGxlY3QoKSkudG9SZWNvcmRzKCkpLnRvRXF1YWwoW1xuICAgICAgICB7IDE6IDIsIGVuZ2xpc2g6IFwi5Lit5paHXCIgfSxcbiAgICAgIF0pXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgbXVsdGlsaW5lIGhlYWRlclJvd3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cxLCByb3cyLCByb3czXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgZGlhbGVjdDogeyBoZWFkZXJSb3dzOiBbMSwgMl0gfSxcbiAgICAgIH0pXG5cbiAgICAgIGV4cGVjdCgoYXdhaXQgdGFibGUuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICAgIHsgXCJpZCAxXCI6IDIsIFwibmFtZSBlbmdsaXNoXCI6IFwi5Lit5paHXCIgfSxcbiAgICAgIF0pXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgaGVhZGVySm9pblwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gZ2V0VGVtcEZpbGVQYXRoKClcbiAgICAgIGF3YWl0IHdyaXRlVGVzdERhdGEocGF0aCwgW3JvdzEsIHJvdzIsIHJvdzNdKVxuXG4gICAgICBjb25zdCB0YWJsZSA9IGF3YWl0IGxvYWRYbHN4VGFibGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBkaWFsZWN0OiB7IGhlYWRlclJvd3M6IFsxLCAyXSwgaGVhZGVySm9pbjogXCItXCIgfSxcbiAgICAgIH0pXG5cbiAgICAgIGV4cGVjdCgoYXdhaXQgdGFibGUuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICAgIHsgXCJpZC0xXCI6IDIsIFwibmFtZS1lbmdsaXNoXCI6IFwi5Lit5paHXCIgfSxcbiAgICAgIF0pXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgY29tbWVudFJvd3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cxLCByb3cyLCByb3czXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgZGlhbGVjdDogeyBjb21tZW50Um93czogWzJdIH0sXG4gICAgICB9KVxuXG4gICAgICBleHBlY3QoKGF3YWl0IHRhYmxlLmNvbGxlY3QoKSkudG9SZWNvcmRzKCkpLnRvRXF1YWwoW3JlY29yZDJdKVxuICAgIH0pXG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGNvbW1lbnRDaGFyXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBnZXRUZW1wRmlsZVBhdGgoKVxuICAgICAgYXdhaXQgd3JpdGVUZXN0RGF0YShwYXRoLCBbcm93MSwgcm93Miwgcm93MywgW1wiI2NvbW1lbnRcIl1dKVxuXG4gICAgICBjb25zdCB0YWJsZSA9IGF3YWl0IGxvYWRYbHN4VGFibGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBkaWFsZWN0OiB7IGNvbW1lbnRDaGFyOiBcIiNcIiB9LFxuICAgICAgfSlcblxuICAgICAgZXhwZWN0KChhd2FpdCB0YWJsZS5jb2xsZWN0KCkpLnRvUmVjb3JkcygpKS50b0VxdWFsKFtyZWNvcmQxLCByZWNvcmQyXSlcbiAgICB9KVxuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGxvbmdlciByb3dzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBnZXRUZW1wRmlsZVBhdGgoKVxuICAgICAgYXdhaXQgd3JpdGVUZXN0RGF0YShwYXRoLCBbcm93MSwgcm93Miwgcm93MywgWzMsIFwiZ2VybWFuXCIsIFwiYmFkXCJdXSlcblxuICAgICAgY29uc3QgdGFibGUgPSBhd2FpdCBsb2FkWGxzeFRhYmxlKHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgZGlhbGVjdDogeyBjb21tZW50Q2hhcjogXCIjXCIgfSxcbiAgICAgIH0pXG5cbiAgICAgIGV4cGVjdCgoYXdhaXQgdGFibGUuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICAgIHJlY29yZDEsXG4gICAgICAgIHJlY29yZDIsXG4gICAgICAgIHsgaWQ6IDMsIG5hbWU6IFwiZ2VybWFuXCIgfSxcbiAgICAgIF0pXG4gICAgfSlcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBzaG9ydGVyIHJvd3NcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG4gICAgICBhd2FpdCB3cml0ZVRlc3REYXRhKHBhdGgsIFtyb3cxLCByb3cyLCByb3czLCBbM11dKVxuXG4gICAgICBjb25zdCB0YWJsZSA9IGF3YWl0IGxvYWRYbHN4VGFibGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBkaWFsZWN0OiB7IGNvbW1lbnRDaGFyOiBcIiNcIiB9LFxuICAgICAgfSlcblxuICAgICAgZXhwZWN0KChhd2FpdCB0YWJsZS5jb2xsZWN0KCkpLnRvUmVjb3JkcygpKS50b0VxdWFsKFtcbiAgICAgICAgcmVjb3JkMSxcbiAgICAgICAgcmVjb3JkMixcbiAgICAgICAgeyBpZDogMywgbmFtZTogbnVsbCB9LFxuICAgICAgXSlcbiAgICB9KVxuICB9KVxufSlcbiJdfQ==
@@ -0,0 +1,3 @@
1
+ import type { SaveTableOptions } from "../../../plugin.ts";
2
+ import type { Table } from "../../../table/index.ts";
3
+ export declare function saveXlsxTable(table: Table, options: SaveTableOptions): Promise<string>;
@@ -0,0 +1,28 @@
1
+ import { saveFile } from "@frictionless-ts/dataset";
2
+ import { resolveDialect } from "@frictionless-ts/metadata";
3
+ import { utils, write } from "xlsx";
4
+ import { inferSchemaFromTable } from "../../../schema/index.js";
5
+ import { denormalizeTable } from "../../../table/index.js";
6
+ // Currently, we use slow non-rust implementation as in the future
7
+ // polars-rust might be able to provide a faster native implementation
8
+ export async function saveXlsxTable(table, options) {
9
+ const { path, overwrite } = options;
10
+ const schema = options.schema ??
11
+ (await inferSchemaFromTable(table, {
12
+ ...options,
13
+ keepStrings: true,
14
+ }));
15
+ table = await denormalizeTable(table, schema, {
16
+ nativeTypes: ["boolean", "integer", "number", "string", "year"],
17
+ });
18
+ const frame = await table.collect();
19
+ const dialect = await resolveDialect(options.dialect);
20
+ const sheetName = dialect?.sheetName ?? "Sheet1";
21
+ const sheet = utils.json_to_sheet(frame.toRecords());
22
+ const book = utils.book_new();
23
+ utils.book_append_sheet(book, sheet, sheetName);
24
+ const buffer = write(book, { type: "buffer", bookType: "xlsx" });
25
+ await saveFile(path, buffer, { overwrite });
26
+ return path;
27
+ }
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BsdWdpbnMveGx4cy90YWJsZS9zYXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUNuRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFFbkMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFHMUQsa0VBQWtFO0FBQ2xFLHNFQUFzRTtBQUV0RSxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FBQyxLQUFZLEVBQUUsT0FBeUI7SUFDekUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxPQUFPLENBQUE7SUFFbkMsTUFBTSxNQUFNLEdBQ1YsT0FBTyxDQUFDLE1BQU07UUFDZCxDQUFDLE1BQU0sb0JBQW9CLENBQUMsS0FBSyxFQUFFO1lBQ2pDLEdBQUcsT0FBTztZQUNWLFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUMsQ0FBQyxDQUFBO0lBRUwsS0FBSyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRTtRQUM1QyxXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO0tBQ2hFLENBQUMsQ0FBQTtJQUVGLE1BQU0sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ25DLE1BQU0sT0FBTyxHQUFHLE1BQU0sY0FBYyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUNyRCxNQUFNLFNBQVMsR0FBRyxPQUFPLEVBQUUsU0FBUyxJQUFJLFFBQVEsQ0FBQTtJQUVoRCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFBO0lBQ3BELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQTtJQUM3QixLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUUvQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtJQUNoRSxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQTtJQUUzQyxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzYXZlRmlsZSB9IGZyb20gXCJAZnJpY3Rpb25sZXNzLXRzL2RhdGFzZXRcIlxuaW1wb3J0IHsgcmVzb2x2ZURpYWxlY3QgfSBmcm9tIFwiQGZyaWN0aW9ubGVzcy10cy9tZXRhZGF0YVwiXG5pbXBvcnQgeyB1dGlscywgd3JpdGUgfSBmcm9tIFwieGxzeFwiXG5pbXBvcnQgdHlwZSB7IFNhdmVUYWJsZU9wdGlvbnMgfSBmcm9tIFwiLi4vLi4vLi4vcGx1Z2luLnRzXCJcbmltcG9ydCB7IGluZmVyU2NoZW1hRnJvbVRhYmxlIH0gZnJvbSBcIi4uLy4uLy4uL3NjaGVtYS9pbmRleC50c1wiXG5pbXBvcnQgeyBkZW5vcm1hbGl6ZVRhYmxlIH0gZnJvbSBcIi4uLy4uLy4uL3RhYmxlL2luZGV4LnRzXCJcbmltcG9ydCB0eXBlIHsgVGFibGUgfSBmcm9tIFwiLi4vLi4vLi4vdGFibGUvaW5kZXgudHNcIlxuXG4vLyBDdXJyZW50bHksIHdlIHVzZSBzbG93IG5vbi1ydXN0IGltcGxlbWVudGF0aW9uIGFzIGluIHRoZSBmdXR1cmVcbi8vIHBvbGFycy1ydXN0IG1pZ2h0IGJlIGFibGUgdG8gcHJvdmlkZSBhIGZhc3RlciBuYXRpdmUgaW1wbGVtZW50YXRpb25cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhdmVYbHN4VGFibGUodGFibGU6IFRhYmxlLCBvcHRpb25zOiBTYXZlVGFibGVPcHRpb25zKSB7XG4gIGNvbnN0IHsgcGF0aCwgb3ZlcndyaXRlIH0gPSBvcHRpb25zXG5cbiAgY29uc3Qgc2NoZW1hID1cbiAgICBvcHRpb25zLnNjaGVtYSA/P1xuICAgIChhd2FpdCBpbmZlclNjaGVtYUZyb21UYWJsZSh0YWJsZSwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGtlZXBTdHJpbmdzOiB0cnVlLFxuICAgIH0pKVxuXG4gIHRhYmxlID0gYXdhaXQgZGVub3JtYWxpemVUYWJsZSh0YWJsZSwgc2NoZW1hLCB7XG4gICAgbmF0aXZlVHlwZXM6IFtcImJvb2xlYW5cIiwgXCJpbnRlZ2VyXCIsIFwibnVtYmVyXCIsIFwic3RyaW5nXCIsIFwieWVhclwiXSxcbiAgfSlcblxuICBjb25zdCBmcmFtZSA9IGF3YWl0IHRhYmxlLmNvbGxlY3QoKVxuICBjb25zdCBkaWFsZWN0ID0gYXdhaXQgcmVzb2x2ZURpYWxlY3Qob3B0aW9ucy5kaWFsZWN0KVxuICBjb25zdCBzaGVldE5hbWUgPSBkaWFsZWN0Py5zaGVldE5hbWUgPz8gXCJTaGVldDFcIlxuXG4gIGNvbnN0IHNoZWV0ID0gdXRpbHMuanNvbl90b19zaGVldChmcmFtZS50b1JlY29yZHMoKSlcbiAgY29uc3QgYm9vayA9IHV0aWxzLmJvb2tfbmV3KClcbiAgdXRpbHMuYm9va19hcHBlbmRfc2hlZXQoYm9vaywgc2hlZXQsIHNoZWV0TmFtZSlcblxuICBjb25zdCBidWZmZXIgPSB3cml0ZShib29rLCB7IHR5cGU6IFwiYnVmZmVyXCIsIGJvb2tUeXBlOiBcInhsc3hcIiB9KVxuICBhd2FpdCBzYXZlRmlsZShwYXRoLCBidWZmZXIsIHsgb3ZlcndyaXRlIH0pXG5cbiAgcmV0dXJuIHBhdGhcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,75 @@
1
+ import { getTempFilePath } from "@frictionless-ts/dataset";
2
+ import * as pl from "nodejs-polars";
3
+ import { describe, expect, it } from "vitest";
4
+ import { loadXlsxTable } from "./load.js";
5
+ import { saveXlsxTable } from "./save.js";
6
+ import { readTestData } from "./test.js";
7
+ const row1 = { id: 1, name: "english" };
8
+ const row2 = { id: 2, name: "中文" };
9
+ const table = pl.readRecords([row1, row2]).lazy();
10
+ describe("saveXlsxTable", () => {
11
+ it("should save table to file", async () => {
12
+ const path = getTempFilePath();
13
+ await saveXlsxTable(table, { path });
14
+ const data = await readTestData(path);
15
+ expect(data).toEqual([row1, row2]);
16
+ });
17
+ it("should save and load various data types", async () => {
18
+ const path = getTempFilePath();
19
+ const source = pl
20
+ .DataFrame([
21
+ pl.Series("array", ["[1, 2, 3]"], pl.String),
22
+ pl.Series("boolean", [true], pl.Bool),
23
+ pl.Series("date", [new Date(Date.UTC(2025, 0, 1))], pl.Date),
24
+ pl.Series("datetime", [new Date(Date.UTC(2025, 0, 1))], pl.Datetime),
25
+ pl.Series("duration", ["P23DT23H"], pl.String),
26
+ pl.Series("geojson", ['{"value": 1}'], pl.String),
27
+ pl.Series("geopoint", [[40.0, 50.0]], pl.List(pl.Float32)),
28
+ pl.Series("integer", [1], pl.Int32),
29
+ pl.Series("list", [[1.0, 2.0, 3.0]], pl.List(pl.Float32)),
30
+ pl.Series("number", [1.1], pl.Float64),
31
+ pl.Series("object", ['{"value": 1}']),
32
+ pl.Series("string", ["string"], pl.String),
33
+ pl.Series("time", [new Date(Date.UTC(2025, 0, 1))], pl.Time),
34
+ pl.Series("year", [2025], pl.Int32),
35
+ pl.Series("yearmonth", [[2025, 1]], pl.List(pl.Int16)),
36
+ ])
37
+ .lazy();
38
+ await saveXlsxTable(source, {
39
+ path,
40
+ fieldTypes: {
41
+ array: "array",
42
+ geojson: "geojson",
43
+ geopoint: "geopoint",
44
+ list: "list",
45
+ object: "object",
46
+ // TODO: Remove time after:
47
+ // https://github.com/pola-rs/nodejs-polars/issues/364
48
+ time: "time",
49
+ year: "year",
50
+ yearmonth: "yearmonth",
51
+ },
52
+ });
53
+ const target = await loadXlsxTable({ path }, { denormalized: true });
54
+ expect((await target.collect()).toRecords()).toEqual([
55
+ {
56
+ array: "[1, 2, 3]",
57
+ boolean: true,
58
+ date: "2025-01-01",
59
+ datetime: "2025-01-01T00:00:00",
60
+ duration: "P23DT23H",
61
+ geojson: '{"value": 1}',
62
+ geopoint: "40.0,50.0",
63
+ integer: 1,
64
+ list: "1.0,2.0,3.0",
65
+ number: 1.1,
66
+ object: '{"value": 1}',
67
+ string: "string",
68
+ time: "00:00:00",
69
+ year: 2025,
70
+ yearmonth: "2025-01",
71
+ },
72
+ ]);
73
+ });
74
+ });
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGx1Z2lucy94bHhzL3RhYmxlL3NhdmUuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDMUQsT0FBTyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDbkMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDekMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXhDLE1BQU0sSUFBSSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUE7QUFDdkMsTUFBTSxJQUFJLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQTtBQUNsQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7QUFFakQsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7SUFDN0IsRUFBRSxDQUFDLDJCQUEyQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3pDLE1BQU0sSUFBSSxHQUFHLGVBQWUsRUFBRSxDQUFBO1FBQzlCLE1BQU0sYUFBYSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFFcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQ3BDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZELE1BQU0sSUFBSSxHQUFHLGVBQWUsRUFBRSxDQUFBO1FBRTlCLE1BQU0sTUFBTSxHQUFHLEVBQUU7YUFDZCxTQUFTLENBQUM7WUFDVCxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDNUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3JDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQzVELEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDO1lBQ3BFLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUM5QyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDakQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFELEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNuQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pELEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQztZQUN0QyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JDLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUMxQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQztZQUM1RCxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDbkMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3ZELENBQUM7YUFDRCxJQUFJLEVBQUUsQ0FBQTtRQUVULE1BQU0sYUFBYSxDQUFDLE1BQU0sRUFBRTtZQUMxQixJQUFJO1lBQ0osVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRSxPQUFPO2dCQUNkLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixRQUFRLEVBQUUsVUFBVTtnQkFDcEIsSUFBSSxFQUFFLE1BQU07Z0JBQ1osTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLDJCQUEyQjtnQkFDM0Isc0RBQXNEO2dCQUN0RCxJQUFJLEVBQUUsTUFBTTtnQkFDWixJQUFJLEVBQUUsTUFBTTtnQkFDWixTQUFTLEVBQUUsV0FBVzthQUN2QjtTQUNGLENBQUMsQ0FBQTtRQUVGLE1BQU0sTUFBTSxHQUFHLE1BQU0sYUFBYSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUNwRSxNQUFNLENBQUMsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ25EO2dCQUNFLEtBQUssRUFBRSxXQUFXO2dCQUNsQixPQUFPLEVBQUUsSUFBSTtnQkFDYixJQUFJLEVBQUUsWUFBWTtnQkFDbEIsUUFBUSxFQUFFLHFCQUFxQjtnQkFDL0IsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixRQUFRLEVBQUUsV0FBVztnQkFDckIsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLE1BQU0sRUFBRSxHQUFHO2dCQUNYLE1BQU0sRUFBRSxjQUFjO2dCQUN0QixNQUFNLEVBQUUsUUFBUTtnQkFDaEIsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLElBQUksRUFBRSxJQUFJO2dCQUNWLFNBQVMsRUFBRSxTQUFTO2FBQ3JCO1NBQ0YsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFRlbXBGaWxlUGF0aCB9IGZyb20gXCJAZnJpY3Rpb25sZXNzLXRzL2RhdGFzZXRcIlxuaW1wb3J0ICogYXMgcGwgZnJvbSBcIm5vZGVqcy1wb2xhcnNcIlxuaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB7IGxvYWRYbHN4VGFibGUgfSBmcm9tIFwiLi9sb2FkLnRzXCJcbmltcG9ydCB7IHNhdmVYbHN4VGFibGUgfSBmcm9tIFwiLi9zYXZlLnRzXCJcbmltcG9ydCB7IHJlYWRUZXN0RGF0YSB9IGZyb20gXCIuL3Rlc3QudHNcIlxuXG5jb25zdCByb3cxID0geyBpZDogMSwgbmFtZTogXCJlbmdsaXNoXCIgfVxuY29uc3Qgcm93MiA9IHsgaWQ6IDIsIG5hbWU6IFwi5Lit5paHXCIgfVxuY29uc3QgdGFibGUgPSBwbC5yZWFkUmVjb3Jkcyhbcm93MSwgcm93Ml0pLmxhenkoKVxuXG5kZXNjcmliZShcInNhdmVYbHN4VGFibGVcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCBzYXZlIHRhYmxlIHRvIGZpbGVcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBhdGggPSBnZXRUZW1wRmlsZVBhdGgoKVxuICAgIGF3YWl0IHNhdmVYbHN4VGFibGUodGFibGUsIHsgcGF0aCB9KVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlYWRUZXN0RGF0YShwYXRoKVxuICAgIGV4cGVjdChkYXRhKS50b0VxdWFsKFtyb3cxLCByb3cyXSlcbiAgfSlcblxuICBpdChcInNob3VsZCBzYXZlIGFuZCBsb2FkIHZhcmlvdXMgZGF0YSB0eXBlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGF0aCA9IGdldFRlbXBGaWxlUGF0aCgpXG5cbiAgICBjb25zdCBzb3VyY2UgPSBwbFxuICAgICAgLkRhdGFGcmFtZShbXG4gICAgICAgIHBsLlNlcmllcyhcImFycmF5XCIsIFtcIlsxLCAyLCAzXVwiXSwgcGwuU3RyaW5nKSxcbiAgICAgICAgcGwuU2VyaWVzKFwiYm9vbGVhblwiLCBbdHJ1ZV0sIHBsLkJvb2wpLFxuICAgICAgICBwbC5TZXJpZXMoXCJkYXRlXCIsIFtuZXcgRGF0ZShEYXRlLlVUQygyMDI1LCAwLCAxKSldLCBwbC5EYXRlKSxcbiAgICAgICAgcGwuU2VyaWVzKFwiZGF0ZXRpbWVcIiwgW25ldyBEYXRlKERhdGUuVVRDKDIwMjUsIDAsIDEpKV0sIHBsLkRhdGV0aW1lKSxcbiAgICAgICAgcGwuU2VyaWVzKFwiZHVyYXRpb25cIiwgW1wiUDIzRFQyM0hcIl0sIHBsLlN0cmluZyksXG4gICAgICAgIHBsLlNlcmllcyhcImdlb2pzb25cIiwgWyd7XCJ2YWx1ZVwiOiAxfSddLCBwbC5TdHJpbmcpLFxuICAgICAgICBwbC5TZXJpZXMoXCJnZW9wb2ludFwiLCBbWzQwLjAsIDUwLjBdXSwgcGwuTGlzdChwbC5GbG9hdDMyKSksXG4gICAgICAgIHBsLlNlcmllcyhcImludGVnZXJcIiwgWzFdLCBwbC5JbnQzMiksXG4gICAgICAgIHBsLlNlcmllcyhcImxpc3RcIiwgW1sxLjAsIDIuMCwgMy4wXV0sIHBsLkxpc3QocGwuRmxvYXQzMikpLFxuICAgICAgICBwbC5TZXJpZXMoXCJudW1iZXJcIiwgWzEuMV0sIHBsLkZsb2F0NjQpLFxuICAgICAgICBwbC5TZXJpZXMoXCJvYmplY3RcIiwgWyd7XCJ2YWx1ZVwiOiAxfSddKSxcbiAgICAgICAgcGwuU2VyaWVzKFwic3RyaW5nXCIsIFtcInN0cmluZ1wiXSwgcGwuU3RyaW5nKSxcbiAgICAgICAgcGwuU2VyaWVzKFwidGltZVwiLCBbbmV3IERhdGUoRGF0ZS5VVEMoMjAyNSwgMCwgMSkpXSwgcGwuVGltZSksXG4gICAgICAgIHBsLlNlcmllcyhcInllYXJcIiwgWzIwMjVdLCBwbC5JbnQzMiksXG4gICAgICAgIHBsLlNlcmllcyhcInllYXJtb250aFwiLCBbWzIwMjUsIDFdXSwgcGwuTGlzdChwbC5JbnQxNikpLFxuICAgICAgXSlcbiAgICAgIC5sYXp5KClcblxuICAgIGF3YWl0IHNhdmVYbHN4VGFibGUoc291cmNlLCB7XG4gICAgICBwYXRoLFxuICAgICAgZmllbGRUeXBlczoge1xuICAgICAgICBhcnJheTogXCJhcnJheVwiLFxuICAgICAgICBnZW9qc29uOiBcImdlb2pzb25cIixcbiAgICAgICAgZ2VvcG9pbnQ6IFwiZ2VvcG9pbnRcIixcbiAgICAgICAgbGlzdDogXCJsaXN0XCIsXG4gICAgICAgIG9iamVjdDogXCJvYmplY3RcIixcbiAgICAgICAgLy8gVE9ETzogUmVtb3ZlIHRpbWUgYWZ0ZXI6XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wb2xhLXJzL25vZGVqcy1wb2xhcnMvaXNzdWVzLzM2NFxuICAgICAgICB0aW1lOiBcInRpbWVcIixcbiAgICAgICAgeWVhcjogXCJ5ZWFyXCIsXG4gICAgICAgIHllYXJtb250aDogXCJ5ZWFybW9udGhcIixcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IHRhcmdldCA9IGF3YWl0IGxvYWRYbHN4VGFibGUoeyBwYXRoIH0sIHsgZGVub3JtYWxpemVkOiB0cnVlIH0pXG4gICAgZXhwZWN0KChhd2FpdCB0YXJnZXQuY29sbGVjdCgpKS50b1JlY29yZHMoKSkudG9FcXVhbChbXG4gICAgICB7XG4gICAgICAgIGFycmF5OiBcIlsxLCAyLCAzXVwiLFxuICAgICAgICBib29sZWFuOiB0cnVlLFxuICAgICAgICBkYXRlOiBcIjIwMjUtMDEtMDFcIixcbiAgICAgICAgZGF0ZXRpbWU6IFwiMjAyNS0wMS0wMVQwMDowMDowMFwiLFxuICAgICAgICBkdXJhdGlvbjogXCJQMjNEVDIzSFwiLFxuICAgICAgICBnZW9qc29uOiAne1widmFsdWVcIjogMX0nLFxuICAgICAgICBnZW9wb2ludDogXCI0MC4wLDUwLjBcIixcbiAgICAgICAgaW50ZWdlcjogMSxcbiAgICAgICAgbGlzdDogXCIxLjAsMi4wLDMuMFwiLFxuICAgICAgICBudW1iZXI6IDEuMSxcbiAgICAgICAgb2JqZWN0OiAne1widmFsdWVcIjogMX0nLFxuICAgICAgICBzdHJpbmc6IFwic3RyaW5nXCIsXG4gICAgICAgIHRpbWU6IFwiMDA6MDA6MDBcIixcbiAgICAgICAgeWVhcjogMjAyNSxcbiAgICAgICAgeWVhcm1vbnRoOiBcIjIwMjUtMDFcIixcbiAgICAgIH0sXG4gICAgXSlcbiAgfSlcbn0pXG4iXX0=
@@ -0,0 +1,5 @@
1
+ export declare function readTestData(path: string): Promise<unknown[]>;
2
+ export declare function writeTestData(path: string, rows: unknown[][], options?: {
3
+ sheetNumber?: number;
4
+ sheetName?: string;
5
+ }): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { read, utils, write } from "xlsx";
4
+ // We intentionally don't use dpkit's function here to isolate the tests
5
+ export async function readTestData(path) {
6
+ const buffer = await readFile(path);
7
+ const book = read(buffer, { type: "buffer" });
8
+ const sheetName = book.SheetNames[0];
9
+ const sheet = sheetName ? book.Sheets[sheetName] : undefined;
10
+ return sheet ? utils.sheet_to_json(sheet) : [];
11
+ }
12
+ export async function writeTestData(path, rows, options) {
13
+ const book = utils.book_new();
14
+ const sheet = utils.aoa_to_sheet(rows);
15
+ const sheetNumber = options?.sheetNumber ?? 1;
16
+ for (let i = 0; i < sheetNumber; i++) {
17
+ const sheetName = options?.sheetName ?? `Sheet${i + 1}`;
18
+ utils.book_append_sheet(book, sheet, sheetName);
19
+ }
20
+ const buffer = write(book, { type: "buffer", bookType: "xlsx" });
21
+ await writeFile(path, buffer);
22
+ }
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BsdWdpbnMveGx4cy90YWJsZS90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDNUMsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBRXpDLHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FBQyxJQUFZO0lBQzdDLE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ25DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUM3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3BDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO0lBQzVELE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7QUFDaEQsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUNqQyxJQUFZLEVBQ1osSUFBaUIsRUFDakIsT0FBc0Q7SUFFdEQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBQzdCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDdEMsTUFBTSxXQUFXLEdBQUcsT0FBTyxFQUFFLFdBQVcsSUFBSSxDQUFDLENBQUE7SUFFN0MsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sU0FBUyxHQUFHLE9BQU8sRUFBRSxTQUFTLElBQUksUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUE7UUFDdkQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFDakQsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sU0FBUyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQTtBQUMvQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgeyB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgeyByZWFkLCB1dGlscywgd3JpdGUgfSBmcm9tIFwieGxzeFwiXG5cbi8vIFdlIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGRwa2l0J3MgZnVuY3Rpb24gaGVyZSB0byBpc29sYXRlIHRoZSB0ZXN0c1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZFRlc3REYXRhKHBhdGg6IHN0cmluZykge1xuICBjb25zdCBidWZmZXIgPSBhd2FpdCByZWFkRmlsZShwYXRoKVxuICBjb25zdCBib29rID0gcmVhZChidWZmZXIsIHsgdHlwZTogXCJidWZmZXJcIiB9KVxuICBjb25zdCBzaGVldE5hbWUgPSBib29rLlNoZWV0TmFtZXNbMF1cbiAgY29uc3Qgc2hlZXQgPSBzaGVldE5hbWUgPyBib29rLlNoZWV0c1tzaGVldE5hbWVdIDogdW5kZWZpbmVkXG4gIHJldHVybiBzaGVldCA/IHV0aWxzLnNoZWV0X3RvX2pzb24oc2hlZXQpIDogW11cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlVGVzdERhdGEoXG4gIHBhdGg6IHN0cmluZyxcbiAgcm93czogdW5rbm93bltdW10sXG4gIG9wdGlvbnM/OiB7IHNoZWV0TnVtYmVyPzogbnVtYmVyOyBzaGVldE5hbWU/OiBzdHJpbmcgfSxcbikge1xuICBjb25zdCBib29rID0gdXRpbHMuYm9va19uZXcoKVxuICBjb25zdCBzaGVldCA9IHV0aWxzLmFvYV90b19zaGVldChyb3dzKVxuICBjb25zdCBzaGVldE51bWJlciA9IG9wdGlvbnM/LnNoZWV0TnVtYmVyID8/IDFcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoZWV0TnVtYmVyOyBpKyspIHtcbiAgICBjb25zdCBzaGVldE5hbWUgPSBvcHRpb25zPy5zaGVldE5hbWUgPz8gYFNoZWV0JHtpICsgMX1gXG4gICAgdXRpbHMuYm9va19hcHBlbmRfc2hlZXQoYm9vaywgc2hlZXQsIHNoZWV0TmFtZSlcbiAgfVxuXG4gIGNvbnN0IGJ1ZmZlciA9IHdyaXRlKGJvb2ssIHsgdHlwZTogXCJidWZmZXJcIiwgYm9va1R5cGU6IFwieGxzeFwiIH0pXG4gIGF3YWl0IHdyaXRlRmlsZShwYXRoLCBidWZmZXIpXG59XG4iXX0=
@@ -0,0 +1,6 @@
1
+ import type { Schema } from "@frictionless-ts/metadata";
2
+ import type { PolarsSchema } from "./Schema.ts";
3
+ export interface SchemaMapping {
4
+ source: PolarsSchema;
5
+ target: Schema;
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFwcGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NjaGVtYS9NYXBwaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gXCJAZnJpY3Rpb25sZXNzLXRzL21ldGFkYXRhXCJcbmltcG9ydCB0eXBlIHsgUG9sYXJzU2NoZW1hIH0gZnJvbSBcIi4vU2NoZW1hLnRzXCJcblxuZXhwb3J0IGludGVyZmFjZSBTY2hlbWFNYXBwaW5nIHtcbiAgc291cmNlOiBQb2xhcnNTY2hlbWFcbiAgdGFyZ2V0OiBTY2hlbWFcbn1cbiJdfQ==