@graphysdk/data-import-utils 1.8.0 → 1.8.1-beta.1786025839240

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 (84) hide show
  1. package/LICENSE.md +17 -0
  2. package/README.md +11 -15
  3. package/dist/buffer.cjs +1 -1
  4. package/dist/buffer.mjs +4 -1
  5. package/dist/constants-BSk6SyUk.cjs +1 -0
  6. package/dist/constants-PA0Uh9bi.js +5 -0
  7. package/dist/csv.cjs +1 -1
  8. package/dist/csv.mjs +4 -1
  9. package/dist/file.cjs +1 -1
  10. package/dist/file.mjs +17 -1
  11. package/dist/format-detection-1kqWtVpP.cjs +1 -0
  12. package/dist/format-detection-MwlOpP6Y.js +18 -0
  13. package/dist/from-csv-Ccr_5k9u.cjs +1 -0
  14. package/dist/from-csv-CrQ_H-s5.js +5 -0
  15. package/dist/from-csv.d.ts +13 -0
  16. package/dist/from-json-DC712HdK.js +48 -0
  17. package/dist/from-json-lzRNXlod.cjs +1 -0
  18. package/dist/{json.d.ts → from-json.d.ts} +4 -18
  19. package/dist/from-spreadsheet-D2kWRyr3.js +79 -0
  20. package/dist/from-spreadsheet-EfBhqj2z.cjs +1 -0
  21. package/dist/from-spreadsheet.d.ts +20 -0
  22. package/dist/from-tsv-B02B59Ey.cjs +1 -0
  23. package/dist/from-tsv-CPj6UzXC.js +5 -0
  24. package/dist/from-tsv.d.ts +11 -0
  25. package/dist/index-buffer.d.ts +2 -0
  26. package/dist/index-csv.d.ts +2 -0
  27. package/dist/index-file.d.ts +2 -0
  28. package/dist/index-json.d.ts +3 -0
  29. package/dist/index-ods.d.ts +2 -0
  30. package/dist/index-text.d.ts +2 -0
  31. package/dist/index-tsv.d.ts +2 -0
  32. package/dist/index-url.d.ts +2 -0
  33. package/dist/index-xls.d.ts +2 -0
  34. package/dist/index-xlsx.d.ts +8 -0
  35. package/dist/index.cjs +0 -1
  36. package/dist/index.d.ts +8 -44
  37. package/dist/index.mjs +0 -1
  38. package/dist/json.cjs +1 -1
  39. package/dist/json.mjs +4 -1
  40. package/dist/map-rows-1hzHO_rN.cjs +1 -0
  41. package/dist/map-rows-GOmUltJ3.js +35 -0
  42. package/dist/ods.cjs +1 -1
  43. package/dist/ods.mjs +4 -1
  44. package/dist/parse-delimited-BSoFIVFq.cjs +1 -0
  45. package/dist/parse-delimited-qsjX5KAa.js +28 -0
  46. package/dist/parse-delimited.d.ts +7 -0
  47. package/dist/parse-file.d.ts +12 -0
  48. package/dist/parse-string-DpdSP3xh.cjs +1 -0
  49. package/dist/parse-string-VVlSsL2Y.js +47 -0
  50. package/dist/parse-string.d.ts +29 -0
  51. package/dist/parse-url.d.ts +14 -0
  52. package/dist/spreadsheet/cell-primitive.d.ts +7 -0
  53. package/dist/spreadsheet/load-workbook.d.ts +3 -0
  54. package/dist/spreadsheet/read-region.d.ts +39 -0
  55. package/dist/spreadsheet/workbook-index.d.ts +50 -0
  56. package/dist/text.cjs +1 -1
  57. package/dist/text.mjs +4 -1
  58. package/dist/tsv.cjs +1 -1
  59. package/dist/tsv.mjs +4 -1
  60. package/dist/{url.d.ts → types.d.ts} +18 -24
  61. package/dist/url.cjs +1 -1
  62. package/dist/url.mjs +87 -1
  63. package/dist/utils/build-columns.d.ts +10 -0
  64. package/dist/utils/column-index-to-property-key.d.ts +2 -0
  65. package/dist/utils/constants.d.ts +6 -0
  66. package/dist/utils/format-detection.d.ts +4 -0
  67. package/dist/utils/map-rows.d.ts +13 -0
  68. package/dist/utils/normalize-value.d.ts +12 -0
  69. package/dist/utils/url-validation.d.ts +2 -0
  70. package/dist/wire-data.types.d.ts +13 -0
  71. package/dist/xls.cjs +1 -1
  72. package/dist/xls.mjs +4 -1
  73. package/dist/xlsx.cjs +1 -1
  74. package/dist/xlsx.mjs +172 -1
  75. package/package.json +52 -38
  76. package/dist/README.md +0 -78
  77. package/dist/buffer.d.ts +0 -36
  78. package/dist/csv.d.ts +0 -32
  79. package/dist/file.d.ts +0 -42
  80. package/dist/ods.d.ts +0 -31
  81. package/dist/text.d.ts +0 -32
  82. package/dist/tsv.d.ts +0 -30
  83. package/dist/xls.d.ts +0 -32
  84. package/dist/xlsx.d.ts +0 -127
@@ -0,0 +1,35 @@
1
+ var s = (t) => `c${t + 1}`, b = (t, u) => {
2
+ const e = [];
3
+ for (let n = 0; n < u; n++) {
4
+ const r = t?.[n]?.trim(), l = { key: s(n) };
5
+ r && (l.label = r), e.push(l);
6
+ }
7
+ return e;
8
+ }, o = 100, c = /[^\p{ASCII}]/u, m = /[\u2012\u2013\u2014\u2212](?=\d)/g, d = /\u00A0/g, f = /^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/, p = /^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/, v = /* @__PURE__ */ new Set(["PT_PT", "AR"]), g = (t, u = "EN_US") => {
9
+ let e;
10
+ if (c.test(t) ? e = t.replace(m, "-").replace(d, " ").trim() : e = t.trim(), e === "") return null;
11
+ if (e.length > o) return e;
12
+ if (v.has(u)) {
13
+ if (p.test(e)) {
14
+ const n = e.replace(/\./g, "").replace(",", "."), r = Number(n);
15
+ if (Number.isFinite(r)) return r;
16
+ }
17
+ } else if (f.test(e)) {
18
+ const n = e.replace(/,/g, ""), r = Number(n);
19
+ if (Number.isFinite(r)) return r;
20
+ }
21
+ return e;
22
+ }, N = (t, u, e) => t.map((n) => {
23
+ const r = {};
24
+ for (let l = 0; l < u.length; l++) {
25
+ const a = u[l];
26
+ if (!a) continue;
27
+ const i = n[l];
28
+ i == null || i === "" ? r[a.key] = null : typeof i == "number" ? r[a.key] = i : r[a.key] = g(String(i), e);
29
+ }
30
+ return r;
31
+ });
32
+ export {
33
+ b as n,
34
+ N as t
35
+ };
package/dist/ods.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("tslib"),t=require("exceljs"),r=require("@graphysdk/core/node");const o=e=>{const{value:t}=e;if(null==t)return null;if("number"==typeof t)return t;if("string"==typeof t)return""===t?null:t;if("boolean"==typeof t)return t?1:0;if(t instanceof Date)return t.toISOString();if((e=>"object"==typeof e&&null!==e&&"formula"in e)(t)){if("number"==typeof t.result)return t.result;if("string"==typeof t.result)return""===t.result?null:t.result;if("boolean"==typeof t.result)return t.result?1:0;if(t.result instanceof Date)return t.result.toISOString()}const r=e.text;return""===r?null:r},n=["dataValidations","conditionalFormatting","sheetProtection"];const l=/[^\p{ASCII}]/u,i=/[\u2012\u2013\u2014\u2212](?=\d)/g,u=/\u00A0/g,s=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,c=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,a=new Set(["PT_PT","AR"]),f=(e,t="EN_US")=>{let r;if(r=l.test(e)?e.replace(i,"-").replace(u," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(a.has(t)){if(c.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(s.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},d=(l,i)=>e.__awaiter(void 0,void 0,void 0,function*(){var u,s,c,a,d;const m=1024*(null!==(u=null==i?void 0:i.maxFileSize)&&void 0!==u?u:5)*1024;if(l.byteLength>m)throw new Error(`Input size (${l.byteLength} bytes) exceeds the maximum allowed size of ${m} bytes (${null!==(s=null==i?void 0:i.maxFileSize)&&void 0!==s?s:5} MB).`);const h=null!==(c=null==i?void 0:i.locale)&&void 0!==c?c:"EN_US",w=yield function(r){return e.__awaiter(this,void 0,void 0,function*(){const e=new t.Workbook;return yield e.xlsx.load(r,{ignoreNodes:n}),e})}(l),p=((e,t)=>{if(void 0===t)return e.worksheets[0];if("number"==typeof t){const r=e.worksheets[t];if(!r)throw new Error(`Sheet index ${t} is out of range. Workbook has ${e.worksheets.length} sheet(s).`);return r}const r=e.getWorksheet(t);if(!r){const r=e.worksheets.map(e=>`"${e.name}"`).join(", ");throw new Error(`Sheet "${t}" not found. Available sheets: ${r}`)}return r})(w,null==i?void 0:i.sheet);if(!p||0===p.rowCount)return{columns:[],rows:[]};const v=p.columnCount;if(0===v)return{columns:[],rows:[]};const g=p.getRow(1),b=[];for(let e=1;e<=v;e++){const t=g.getCell(e).value;b.push(String(null!=t?t:""))}const y=((e,t)=>{var o;const n=[];for(let l=0;l<t;l++){const t=null===(o=null==e?void 0:e[l])||void 0===o?void 0:o.trim(),i={key:r.columnIndexToPropertyKey(l)};t&&(i.label=t),n.push(i)}return n})(b,v),x=null!==(a=null==i?void 0:i.maxRows)&&void 0!==a?a:1e5,S=null!==(d=null==i?void 0:i.maxCells)&&void 0!==d?d:5e6,$=[];let k=0,C=0;for(let e=2;e<=p.rowCount;e++){if(k++,k>x)throw new Error(`Row limit exceeded: processed ${k} rows (maximum: ${x}). Use the maxRows option to increase the limit.`);if(C+=v,C>S)throw new Error(`Cell limit exceeded: processed ${C} cells (maximum: ${S}). Use the maxCells option to increase the limit.`);const t=p.getRow(e),r=[];for(let e=1;e<=v;e++)r.push(o(t.getCell(e)));$.push(r)}const E=((e,t,r)=>e.map(e=>{const o={};for(let n=0;n<t.length;n++){const l=t[n];if(!l)continue;const i=e[n];o[l.key]=null==i||""===i?null:"number"==typeof i?i:f(String(i),r)}return o}))($,y,h);return{columns:y,rows:E}});exports.fromODS=(e,t)=>d(e,t);
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./from-spreadsheet-EfBhqj2z.cjs");exports.fromODS=e.fromODS;
package/dist/ods.mjs CHANGED
@@ -1 +1,4 @@
1
- import{__awaiter as e}from"tslib";import t from"exceljs";import{columnIndexToPropertyKey as o}from"@graphysdk/core/node";const r=e=>{const{value:t}=e;if(null==t)return null;if("number"==typeof t)return t;if("string"==typeof t)return""===t?null:t;if("boolean"==typeof t)return t?1:0;if(t instanceof Date)return t.toISOString();if((e=>"object"==typeof e&&null!==e&&"formula"in e)(t)){if("number"==typeof t.result)return t.result;if("string"==typeof t.result)return""===t.result?null:t.result;if("boolean"==typeof t.result)return t.result?1:0;if(t.result instanceof Date)return t.result.toISOString()}const o=e.text;return""===o?null:o},n=["dataValidations","conditionalFormatting","sheetProtection"];const l=/[^\p{ASCII}]/u,i=/[\u2012\u2013\u2014\u2212](?=\d)/g,s=/\u00A0/g,u=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,f=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,c=new Set(["PT_PT","AR"]),d=(e,t="EN_US")=>{let o;if(o=l.test(e)?e.replace(i,"-").replace(s," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(c.has(t)){if(f.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(u.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},a=(l,i)=>e(void 0,void 0,void 0,function*(){var s,u,f,c,a;const m=1024*(null!==(s=null==i?void 0:i.maxFileSize)&&void 0!==s?s:5)*1024;if(l.byteLength>m)throw new Error(`Input size (${l.byteLength} bytes) exceeds the maximum allowed size of ${m} bytes (${null!==(u=null==i?void 0:i.maxFileSize)&&void 0!==u?u:5} MB).`);const h=null!==(f=null==i?void 0:i.locale)&&void 0!==f?f:"EN_US",p=yield function(o){return e(this,void 0,void 0,function*(){const e=new t.Workbook;return yield e.xlsx.load(o,{ignoreNodes:n}),e})}(l),w=((e,t)=>{if(void 0===t)return e.worksheets[0];if("number"==typeof t){const o=e.worksheets[t];if(!o)throw new Error(`Sheet index ${t} is out of range. Workbook has ${e.worksheets.length} sheet(s).`);return o}const o=e.getWorksheet(t);if(!o){const o=e.worksheets.map(e=>`"${e.name}"`).join(", ");throw new Error(`Sheet "${t}" not found. Available sheets: ${o}`)}return o})(p,null==i?void 0:i.sheet);if(!w||0===w.rowCount)return{columns:[],rows:[]};const v=w.columnCount;if(0===v)return{columns:[],rows:[]};const g=w.getRow(1),b=[];for(let e=1;e<=v;e++){const t=g.getCell(e).value;b.push(String(null!=t?t:""))}const x=((e,t)=>{var r;const n=[];for(let l=0;l<t;l++){const t=null===(r=null==e?void 0:e[l])||void 0===r?void 0:r.trim(),i={key:o(l)};t&&(i.label=t),n.push(i)}return n})(b,v),y=null!==(c=null==i?void 0:i.maxRows)&&void 0!==c?c:1e5,S=null!==(a=null==i?void 0:i.maxCells)&&void 0!==a?a:5e6,$=[];let k=0,C=0;for(let e=2;e<=w.rowCount;e++){if(k++,k>y)throw new Error(`Row limit exceeded: processed ${k} rows (maximum: ${y}). Use the maxRows option to increase the limit.`);if(C+=v,C>S)throw new Error(`Cell limit exceeded: processed ${C} cells (maximum: ${S}). Use the maxCells option to increase the limit.`);const t=w.getRow(e),o=[];for(let e=1;e<=v;e++)o.push(r(t.getCell(e)));$.push(o)}const E=((e,t,o)=>e.map(e=>{const r={};for(let n=0;n<t.length;n++){const l=t[n];if(!l)continue;const i=e[n];r[l.key]=null==i||""===i?null:"number"==typeof i?i:d(String(i),o)}return r}))($,x,h);return{columns:x,rows:E}}),m=(e,t)=>a(e,t);export{m as fromODS};
1
+ import { t as r } from "./from-spreadsheet-D2kWRyr3.js";
2
+ export {
3
+ r as fromODS
4
+ };
@@ -0,0 +1 @@
1
+ const a=require("./map-rows-1hzHO_rN.cjs");let o=require("papaparse");o=a.__toESM(o,1);var p=(s,m,t)=>{const l=(t?.maxFileSize??5)*1024*1024;if(s.length>l)throw new Error(`Input size (${s.length} bytes) exceeds the maximum allowed size of ${l} bytes (${t?.maxFileSize??5} MB).`);const n=t?.hasHeader!==!1,w=t?.locale??"EN_US",i=o.default.parse(s,{header:!1,delimiter:m,skipEmptyLines:!0}),c=i.errors.filter(e=>e.type==="Quotes");if(c.length>0){const e=c[0];throw new Error(`Parse error at row ${e?.row??"?"}: ${e?.message??"Unknown error"}`)}const r=i.data;if(r.length===0)return{columns:[],rows:[]};const d=n?r[0]:void 0,h=n?r.slice(1):r,u=a.buildColumns(d,r.reduce((e,f)=>Math.max(e,f.length),0));return{columns:u,rows:a.mapRows(h,u,w)}};Object.defineProperty(exports,"parseDelimited",{enumerable:!0,get:function(){return p}});
@@ -0,0 +1,28 @@
1
+ import { n as f, t as u } from "./map-rows-GOmUltJ3.js";
2
+ import x from "papaparse";
3
+ var y = (t, i, s) => {
4
+ const a = (s?.maxFileSize ?? 5) * 1024 * 1024;
5
+ if (t.length > a) throw new Error(`Input size (${t.length} bytes) exceeds the maximum allowed size of ${a} bytes (${s?.maxFileSize ?? 5} MB).`);
6
+ const o = s?.hasHeader !== !1, m = s?.locale ?? "EN_US", l = x.parse(t, {
7
+ header: !1,
8
+ delimiter: i,
9
+ skipEmptyLines: !0
10
+ }), n = l.errors.filter((e) => e.type === "Quotes");
11
+ if (n.length > 0) {
12
+ const e = n[0];
13
+ throw new Error(`Parse error at row ${e?.row ?? "?"}: ${e?.message ?? "Unknown error"}`);
14
+ }
15
+ const r = l.data;
16
+ if (r.length === 0) return {
17
+ columns: [],
18
+ rows: []
19
+ };
20
+ const w = o ? r[0] : void 0, h = o ? r.slice(1) : r, c = f(w, r.reduce((e, d) => Math.max(e, d.length), 0));
21
+ return {
22
+ columns: c,
23
+ rows: u(h, c, m)
24
+ };
25
+ };
26
+ export {
27
+ y as t
28
+ };
@@ -0,0 +1,7 @@
1
+ import { Data, DelimitedParseOptions } from './types';
2
+ /**
3
+ * Parses a delimited string (CSV or TSV) into the `Data` shape expected by `generateGraph()`.
4
+ *
5
+ * @internal Shared implementation used by `fromCSV` and `fromTSV`.
6
+ */
7
+ export declare const parseDelimited: (input: string, delimiter: string | undefined, options?: DelimitedParseOptions) => Data;
@@ -0,0 +1,12 @@
1
+ import { Data, FileParseOptions } from './types';
2
+ /**
3
+ * Reads a file from disk and parses it into the `Data` shape expected by
4
+ * `generateGraph()`. The format is auto-detected from the file extension.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const data = await fromFile('sales.csv');
9
+ * const data = await fromFile('report.xlsx', { sheet: 'Revenue' });
10
+ * ```
11
+ */
12
+ export declare const fromFile: (filePath: string, options?: FileParseOptions) => Promise<Data>;
@@ -0,0 +1 @@
1
+ const u=require("./from-csv-Ccr_5k9u.cjs"),c=require("./from-tsv-B02B59Ey.cjs"),f=require("./from-json-lzRNXlod.cjs"),t=require("./from-spreadsheet-EfBhqj2z.cjs");var n=(r,e,s)=>{switch(e){case"csv":return u.fromCSV(r,s);case"tsv":return c.fromTSV(r,s);case"json":return f.fromJSON(r,s);default:throw new Error(`Unsupported text format "${e}". Supported: csv, tsv, json`)}},o=async(r,e,s)=>{switch(e){case"xlsx":return t.fromXLSX(r,s);case"xls":return t.fromXLS(r,s);case"ods":return t.fromODS(r,s);default:throw new Error(`Unsupported binary format "${e}". Supported: xlsx, xls, ods`)}},a=async(r,e,s)=>{switch(e){case"csv":case"tsv":case"json":if(typeof r!="string")throw new TypeError(`${e.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return n(r,e,s);case"xlsx":case"xls":case"ods":if(typeof r=="string")throw new TypeError(`${e.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);return o(r,e,s);default:throw new Error(`Unsupported format "${e}". Supported formats: csv, tsv, json, xlsx, xls, ods`)}};Object.defineProperty(exports,"fromBuffer",{enumerable:!0,get:function(){return o}});Object.defineProperty(exports,"fromString",{enumerable:!0,get:function(){return a}});Object.defineProperty(exports,"fromText",{enumerable:!0,get:function(){return n}});
@@ -0,0 +1,47 @@
1
+ import { t } from "./from-csv-CrQ_H-s5.js";
2
+ import { t as a } from "./from-tsv-CPj6UzXC.js";
3
+ import { t as o } from "./from-json-DC712HdK.js";
4
+ import { n, r as c, t as f } from "./from-spreadsheet-D2kWRyr3.js";
5
+ var u = (r, s, e) => {
6
+ switch (s) {
7
+ case "csv":
8
+ return t(r, e);
9
+ case "tsv":
10
+ return a(r, e);
11
+ case "json":
12
+ return o(r, e);
13
+ default:
14
+ throw new Error(`Unsupported text format "${s}". Supported: csv, tsv, json`);
15
+ }
16
+ }, p = async (r, s, e) => {
17
+ switch (s) {
18
+ case "xlsx":
19
+ return c(r, e);
20
+ case "xls":
21
+ return n(r, e);
22
+ case "ods":
23
+ return f(r, e);
24
+ default:
25
+ throw new Error(`Unsupported binary format "${s}". Supported: xlsx, xls, ods`);
26
+ }
27
+ }, w = async (r, s, e) => {
28
+ switch (s) {
29
+ case "csv":
30
+ case "tsv":
31
+ case "json":
32
+ if (typeof r != "string") throw new TypeError(`${s.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);
33
+ return u(r, s, e);
34
+ case "xlsx":
35
+ case "xls":
36
+ case "ods":
37
+ if (typeof r == "string") throw new TypeError(`${s.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);
38
+ return p(r, s, e);
39
+ default:
40
+ throw new Error(`Unsupported format "${s}". Supported formats: csv, tsv, json, xlsx, xls, ods`);
41
+ }
42
+ };
43
+ export {
44
+ w as n,
45
+ u as r,
46
+ p as t
47
+ };
@@ -0,0 +1,29 @@
1
+ import { BinaryFileFormat, Data, DelimitedParseOptions, FileFormat, FileParseOptions, SpreadsheetParseOptions, TextFileFormat } from './types';
2
+ /**
3
+ * Parses a text string (CSV or TSV) into the `Data` shape expected by `generateGraph()`.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * const data = fromText(csvContent, 'csv');
8
+ * const data = fromText(tsvContent, 'tsv', { hasHeader: false });
9
+ * ```
10
+ */
11
+ export declare const fromText: (input: string, format: TextFileFormat, options?: DelimitedParseOptions) => Data;
12
+ /**
13
+ * Parses a binary buffer (XLSX, XLS, or ODS) into the `Data` shape expected by `generateGraph()`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const data = await fromBuffer(xlsxBuffer, 'xlsx');
18
+ * const data = await fromBuffer(odsBuffer, 'ods', { sheet: 'Revenue' });
19
+ * ```
20
+ */
21
+ export declare const fromBuffer: (input: ArrayBuffer, format: BinaryFileFormat, options?: SpreadsheetParseOptions) => Promise<Data>;
22
+ /**
23
+ * Internal polymorphic dispatcher — used by `fromFile` and `fromURL` where the
24
+ * format is determined at runtime. Prefer `fromText` or `fromBuffer` in user code
25
+ * for compile-time type safety.
26
+ *
27
+ * @internal
28
+ */
29
+ export declare const fromString: (input: string | ArrayBuffer, format: FileFormat, options?: FileParseOptions) => Promise<Data>;
@@ -0,0 +1,14 @@
1
+ import { Data, URLParseOptions } from './types';
2
+ /**
3
+ * Fetches a remote file by URL and parses it into the `Data` shape expected by
4
+ * `generateGraph()`. The format is detected from the URL path extension, falling
5
+ * back to the response `Content-Type` header.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const data = await fromURL('https://example.com/sales.csv');
10
+ * const data = await fromURL('https://example.com/report.xlsx', { sheet: 'Revenue' });
11
+ * const data = await fromURL('https://example.com/data.csv', { headers: { Authorization: 'Bearer token' } });
12
+ * ```
13
+ */
14
+ export declare const fromURL: (url: string, options?: URLParseOptions) => Promise<Data>;
@@ -0,0 +1,7 @@
1
+ import { default as ExcelJS } from 'exceljs';
2
+ /**
3
+ * Extracts a primitive value (`string | number | null`) from an ExcelJS cell.
4
+ * Handles numbers, strings, booleans, dates, formulas, rich text, hyperlinks, and errors.
5
+ * Shared by chart-oriented parsing (`fromXLSX`) and extract-oriented region reads.
6
+ */
7
+ export declare const extractCellPrimitive: (cell: ExcelJS.Cell) => string | number | null;
@@ -0,0 +1,3 @@
1
+ import { default as ExcelJS } from 'exceljs';
2
+ /** Loads an OOXML `.xlsx` buffer into an ExcelJS workbook (single-file extract pipeline). */
3
+ export declare function loadWorkbookFromXlsxBuffer(input: ArrayBuffer): Promise<ExcelJS.Workbook>;
@@ -0,0 +1,39 @@
1
+ import { default as ExcelJS } from 'exceljs';
2
+ import { IslandEntry } from './workbook-index';
3
+ export interface ReadSheetRegionOptions {
4
+ /** Stop after this many cells (complete rows only — no partial trailing row). @default {@link DEFAULT_READ_REGION_MAX_CELLS} */
5
+ maxCells?: number;
6
+ }
7
+ export interface ReadSheetRegionResult {
8
+ sheetIndex: number;
9
+ sheetName: string;
10
+ /**
11
+ * Inclusive 1-based Excel row for the first row in {@link rows} (always the requested `rowMin`).
12
+ */
13
+ rowMin: number;
14
+ /**
15
+ * Inclusive 1-based Excel row for the last row in {@link rows} (`rowMin + rows.length - 1`).
16
+ * When {@link truncated} is false, this equals the requested `rowMax`.
17
+ */
18
+ rowMax: number;
19
+ colMin: number;
20
+ colMax: number;
21
+ /** Row-major grid aligned to Excel indices; `rows[i]` is Excel row `rowMin + i`. */
22
+ rows: Array<Array<string | number | null>>;
23
+ truncated: boolean;
24
+ returnedCellCount: number;
25
+ }
26
+ /** Default max cells returned by {@link readSheetRegion} (row-major fill). */
27
+ export declare const DEFAULT_READ_REGION_MAX_CELLS = 50000;
28
+ /**
29
+ * Reads a rectangular region (1-based inclusive Excel row/column indices) using the same cell rules as {@link extractCellPrimitive}.
30
+ * Enforces {@link ReadSheetRegionOptions.maxCells}; when exceeded, returns complete rows only and sets `truncated`.
31
+ */
32
+ export declare function readSheetRegion(workbook: ExcelJS.Workbook, sheetIndex: number, bounds: {
33
+ rowMin: number;
34
+ rowMax: number;
35
+ colMin: number;
36
+ colMax: number;
37
+ }, options?: ReadSheetRegionOptions): ReadSheetRegionResult;
38
+ /** Reads exactly the bounding box of an island entry from {@link buildWorkbookIndex}. */
39
+ export declare function readIslandRegion(workbook: ExcelJS.Workbook, island: IslandEntry, options?: ReadSheetRegionOptions): ReadSheetRegionResult;
@@ -0,0 +1,50 @@
1
+ import { default as ExcelJS } from 'exceljs';
2
+ export interface BuildWorkbookIndexOptions {
3
+ /**
4
+ * Abort if the workbook would exceed this many non-empty cells in total (memory / DoS guard).
5
+ * @default {@link DEFAULT_MAX_WORKBOOK_INDEX_NON_EMPTY_CELLS}
6
+ */
7
+ maxNonEmptyCells?: number;
8
+ }
9
+ export interface SheetIndexEntry {
10
+ sheetName: string;
11
+ /** 0-based order in the workbook. */
12
+ sheetIndex: number;
13
+ /** Inclusive 1-based Excel row/column indices; `null` when the sheet has no data cells. */
14
+ rowMin: number | null;
15
+ rowMax: number | null;
16
+ colMin: number | null;
17
+ colMax: number | null;
18
+ nonEmptyCellCount: number;
19
+ }
20
+ export interface IslandEntry {
21
+ /**
22
+ * Stable within a single file: `${sheetIndex}:${islandOrdinalOnSheet}`.
23
+ * Consumers prefix with request-level `fileIndex` for multi-file UX.
24
+ */
25
+ localId: string;
26
+ sheetIndex: number;
27
+ sheetName: string;
28
+ rowMin: number;
29
+ rowMax: number;
30
+ colMin: number;
31
+ colMax: number;
32
+ /** Number of non-empty cells in this island (4-connected region). */
33
+ cellCount: number;
34
+ }
35
+ export interface WorkbookIndex {
36
+ schemaVersion: typeof WORKBOOK_INDEX_SCHEMA_VERSION;
37
+ sheets: SheetIndexEntry[];
38
+ islands: IslandEntry[];
39
+ }
40
+ /** Bump when island rules or index shape changes (extract API stability). */
41
+ export declare const WORKBOOK_INDEX_SCHEMA_VERSION: 1;
42
+ /** Default cap on total non-empty cells indexed across the workbook (aligns with {@link DEFAULT_MAX_CELLS}). */
43
+ export declare const DEFAULT_MAX_WORKBOOK_INDEX_NON_EMPTY_CELLS = 5000000;
44
+ /**
45
+ * Deterministic structural index for one loaded workbook: per-sheet used bounds and
46
+ * 4-connected **islands** of non-empty cells (using the same empty rules as {@link extractCellPrimitive}).
47
+ */
48
+ export declare function buildWorkbookIndex(workbook: ExcelJS.Workbook, options?: BuildWorkbookIndexOptions): WorkbookIndex;
49
+ /** Loads an `.xlsx` buffer and returns its structural index (no retained workbook handle). */
50
+ export declare function buildWorkbookIndexFromXlsxBuffer(input: ArrayBuffer, options?: BuildWorkbookIndexOptions): Promise<WorkbookIndex>;
package/dist/text.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";require("tslib");var e=require("papaparse"),r=require("@graphysdk/core/node");require("exceljs");const t=/[^\p{ASCII}]/u,o=/[\u2012\u2013\u2014\u2212](?=\d)/g,n=/\u00A0/g,s=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,l=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,i=new Set(["PT_PT","AR"]),u=(e,r="EN_US")=>{let u;if(u=t.test(e)?e.replace(o,"-").replace(n," ").trim():e.trim(),""===u)return null;if(u.length>100)return u;if(i.has(r)){if(l.test(u)){const e=u.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(s.test(u)){const e=u.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return u},a=(t,o,n)=>{var s,l,i,a,c;const d=1024*(null!==(s=null==n?void 0:n.maxFileSize)&&void 0!==s?s:5)*1024;if(t.length>d)throw new Error(`Input size (${t.length} bytes) exceeds the maximum allowed size of ${d} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const m=!1!==(null==n?void 0:n.hasHeader),p=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",f=e.parse(t,{header:!1,delimiter:o,skipEmptyLines:!0}),y=f.errors.filter(e=>"Quotes"===e.type);if(y.length>0){const e=y[0];throw new Error(`Parse error at row ${null!==(a=null==e?void 0:e.row)&&void 0!==a?a:"?"}: ${null!==(c=null==e?void 0:e.message)&&void 0!==c?c:"Unknown error"}`)}const w=f.data;if(0===w.length)return{columns:[],rows:[]};const h=m?w[0]:void 0,v=m?w.slice(1):w,b=((e,t)=>{var o;const n=[];for(let s=0;s<t;s++){const t=null===(o=null==e?void 0:e[s])||void 0===o?void 0:o.trim(),l={key:r.columnIndexToPropertyKey(s)};t&&(l.label=t),n.push(l)}return n})(h,w.reduce((e,r)=>Math.max(e,r.length),0)),g=((e,r,t)=>e.map(e=>{const o={};for(let n=0;n<r.length;n++){const s=r[n];if(!s)continue;const l=e[n];o[s.key]=null==l||""===l?null:"number"==typeof l?l:u(String(l),t)}return o}))(v,b,p);return{columns:b,rows:g}},c=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),d=e=>null==e?null:"number"==typeof e?Number.isFinite(e)?e:null:"string"==typeof e?e:"boolean"==typeof e?String(e):JSON.stringify(e),m=(e,r)=>{const t="string"==typeof e?((e,r)=>{var t;const o=null!==(t=null==r?void 0:r.maxFileSize)&&void 0!==t?t:5,n=1024*o*1024,s=(new TextEncoder).encode(e).byteLength;if(s>n)throw new Error(`Input size (${s} bytes) exceeds the maximum allowed size of ${n} bytes (${o} MB).`);try{return JSON.parse(e)}catch(e){throw new Error(`Invalid JSON: ${e instanceof Error?e.message:"could not parse"}`)}})(e,r):e;if(Array.isArray(t))return(e=>{const r=[],t=new Set;for(const o of e){if(!c(o))throw new Error("Each JSON row must be an object mapping column names to values.");for(const e of Object.keys(o))t.has(e)||(t.add(e),r.push(e))}return{columns:r.map(e=>({key:e})),rows:e.map(e=>{const t={};for(const o of r)t[o]=d(e[o]);return t})}})(t);if((e=>c(e)&&Array.isArray(e.columns)&&Array.isArray(e.rows))(t))return(e=>{const r=e.columns.map(e=>{if(!c(e)||"string"!=typeof e.key||0===e.key.length)throw new Error('Each JSON column must be an object with a non-empty string "key".');return void 0!==e.label?{key:e.key,label:String(e.label)}:{key:e.key}}),t=e.rows.map(e=>{if(!c(e))throw new Error("Each JSON row must be an object mapping column keys to values.");const t={};for(const o of r)t[o.key]=d(e[o.key]);return t});return{columns:r,rows:t}})(t);throw new Error("Unsupported JSON dataset: expected an array of row objects or a { columns, rows } object.")};exports.fromText=(e,r,t)=>{switch(r){case"csv":return((e,r)=>a(e,void 0,r))(e,t);case"tsv":return((e,r)=>a(e,"\t",r))(e,t);case"json":return m(e,t);default:throw new Error(`Unsupported text format "${r}". Supported: csv, tsv, json`)}};
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./parse-string-DpdSP3xh.cjs");exports.fromText=e.fromText;
package/dist/text.mjs CHANGED
@@ -1 +1,4 @@
1
- import"tslib";import e from"papaparse";import{columnIndexToPropertyKey as r}from"@graphysdk/core/node";import"exceljs";const t=/[^\p{ASCII}]/u,o=/[\u2012\u2013\u2014\u2212](?=\d)/g,n=/\u00A0/g,s=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,l=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,i=new Set(["PT_PT","AR"]),u=(e,r="EN_US")=>{let u;if(u=t.test(e)?e.replace(o,"-").replace(n," ").trim():e.trim(),""===u)return null;if(u.length>100)return u;if(i.has(r)){if(l.test(u)){const e=u.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(s.test(u)){const e=u.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return u},a=(t,o,n)=>{var s,l,i,a,c;const m=1024*(null!==(s=null==n?void 0:n.maxFileSize)&&void 0!==s?s:5)*1024;if(t.length>m)throw new Error(`Input size (${t.length} bytes) exceeds the maximum allowed size of ${m} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=!1!==(null==n?void 0:n.hasHeader),p=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",f=e.parse(t,{header:!1,delimiter:o,skipEmptyLines:!0}),y=f.errors.filter(e=>"Quotes"===e.type);if(y.length>0){const e=y[0];throw new Error(`Parse error at row ${null!==(a=null==e?void 0:e.row)&&void 0!==a?a:"?"}: ${null!==(c=null==e?void 0:e.message)&&void 0!==c?c:"Unknown error"}`)}const w=f.data;if(0===w.length)return{columns:[],rows:[]};const h=d?w[0]:void 0,v=d?w.slice(1):w,b=((e,t)=>{var o;const n=[];for(let s=0;s<t;s++){const t=null===(o=null==e?void 0:e[s])||void 0===o?void 0:o.trim(),l={key:r(s)};t&&(l.label=t),n.push(l)}return n})(h,w.reduce((e,r)=>Math.max(e,r.length),0)),g=((e,r,t)=>e.map(e=>{const o={};for(let n=0;n<r.length;n++){const s=r[n];if(!s)continue;const l=e[n];o[s.key]=null==l||""===l?null:"number"==typeof l?l:u(String(l),t)}return o}))(v,b,p);return{columns:b,rows:g}},c=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),m=e=>null==e?null:"number"==typeof e?Number.isFinite(e)?e:null:"string"==typeof e?e:"boolean"==typeof e?String(e):JSON.stringify(e),d=(e,r)=>{const t="string"==typeof e?((e,r)=>{var t;const o=null!==(t=null==r?void 0:r.maxFileSize)&&void 0!==t?t:5,n=1024*o*1024,s=(new TextEncoder).encode(e).byteLength;if(s>n)throw new Error(`Input size (${s} bytes) exceeds the maximum allowed size of ${n} bytes (${o} MB).`);try{return JSON.parse(e)}catch(e){throw new Error(`Invalid JSON: ${e instanceof Error?e.message:"could not parse"}`)}})(e,r):e;if(Array.isArray(t))return(e=>{const r=[],t=new Set;for(const o of e){if(!c(o))throw new Error("Each JSON row must be an object mapping column names to values.");for(const e of Object.keys(o))t.has(e)||(t.add(e),r.push(e))}return{columns:r.map(e=>({key:e})),rows:e.map(e=>{const t={};for(const o of r)t[o]=m(e[o]);return t})}})(t);if((e=>c(e)&&Array.isArray(e.columns)&&Array.isArray(e.rows))(t))return(e=>{const r=e.columns.map(e=>{if(!c(e)||"string"!=typeof e.key||0===e.key.length)throw new Error('Each JSON column must be an object with a non-empty string "key".');return void 0!==e.label?{key:e.key,label:String(e.label)}:{key:e.key}}),t=e.rows.map(e=>{if(!c(e))throw new Error("Each JSON row must be an object mapping column keys to values.");const t={};for(const o of r)t[o.key]=m(e[o.key]);return t});return{columns:r,rows:t}})(t);throw new Error("Unsupported JSON dataset: expected an array of row objects or a { columns, rows } object.")},p=(e,r,t)=>{switch(r){case"csv":return((e,r)=>a(e,void 0,r))(e,t);case"tsv":return((e,r)=>a(e,"\t",r))(e,t);case"json":return d(e,t);default:throw new Error(`Unsupported text format "${r}". Supported: csv, tsv, json`)}};export{p as fromText};
1
+ import { r as o } from "./parse-string-VVlSsL2Y.js";
2
+ export {
3
+ o as fromText
4
+ };
package/dist/tsv.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("papaparse"),r=require("@graphysdk/core/node");const t=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,o=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,i=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),s=(e,r="EN_US")=>{let s;if(s=t.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===s)return null;if(s.length>100)return s;if(u.has(r)){if(i.test(s)){const e=s.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(o.test(s)){const e=s.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return s},d=(t,n,l)=>{var o,i,u,d,a;const c=1024*(null!==(o=null==l?void 0:l.maxFileSize)&&void 0!==o?o:5)*1024;if(t.length>c)throw new Error(`Input size (${t.length} bytes) exceeds the maximum allowed size of ${c} bytes (${null!==(i=null==l?void 0:l.maxFileSize)&&void 0!==i?i:5} MB).`);const m=!1!==(null==l?void 0:l.hasHeader),p=null!==(u=null==l?void 0:l.locale)&&void 0!==u?u:"EN_US",v=e.parse(t,{header:!1,delimiter:n,skipEmptyLines:!0}),f=v.errors.filter(e=>"Quotes"===e.type);if(f.length>0){const e=f[0];throw new Error(`Parse error at row ${null!==(d=null==e?void 0:e.row)&&void 0!==d?d:"?"}: ${null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"}`)}const h=v.data;if(0===h.length)return{columns:[],rows:[]};const g=m?h[0]:void 0,w=m?h.slice(1):h,y=((e,t)=>{var n;const l=[];for(let o=0;o<t;o++){const t=null===(n=null==e?void 0:e[o])||void 0===n?void 0:n.trim(),i={key:r.columnIndexToPropertyKey(o)};t&&(i.label=t),l.push(i)}return l})(g,h.reduce((e,r)=>Math.max(e,r.length),0)),b=((e,r,t)=>e.map(e=>{const n={};for(let l=0;l<r.length;l++){const o=r[l];if(!o)continue;const i=e[l];n[o.key]=null==i||""===i?null:"number"==typeof i?i:s(String(i),t)}return n}))(w,y,p);return{columns:y,rows:b}};exports.fromTSV=(e,r)=>d(e,"\t",r);
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./from-tsv-B02B59Ey.cjs");exports.fromTSV=e.fromTSV;
package/dist/tsv.mjs CHANGED
@@ -1 +1,4 @@
1
- import e from"papaparse";import{columnIndexToPropertyKey as r}from"@graphysdk/core/node";const t=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,o=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,i=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),s=(e,r="EN_US")=>{let s;if(s=t.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===s)return null;if(s.length>100)return s;if(u.has(r)){if(i.test(s)){const e=s.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(o.test(s)){const e=s.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return s},d=(t,n,l)=>{var o,i,u,d,a;const c=1024*(null!==(o=null==l?void 0:l.maxFileSize)&&void 0!==o?o:5)*1024;if(t.length>c)throw new Error(`Input size (${t.length} bytes) exceeds the maximum allowed size of ${c} bytes (${null!==(i=null==l?void 0:l.maxFileSize)&&void 0!==i?i:5} MB).`);const m=!1!==(null==l?void 0:l.hasHeader),p=null!==(u=null==l?void 0:l.locale)&&void 0!==u?u:"EN_US",f=e.parse(t,{header:!1,delimiter:n,skipEmptyLines:!0}),v=f.errors.filter(e=>"Quotes"===e.type);if(v.length>0){const e=v[0];throw new Error(`Parse error at row ${null!==(d=null==e?void 0:e.row)&&void 0!==d?d:"?"}: ${null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"}`)}const h=f.data;if(0===h.length)return{columns:[],rows:[]};const g=m?h[0]:void 0,w=m?h.slice(1):h,b=((e,t)=>{var n;const l=[];for(let o=0;o<t;o++){const t=null===(n=null==e?void 0:e[o])||void 0===n?void 0:n.trim(),i={key:r(o)};t&&(i.label=t),l.push(i)}return l})(g,h.reduce((e,r)=>Math.max(e,r.length),0)),y=((e,r,t)=>e.map(e=>{const n={};for(let l=0;l<r.length;l++){const o=r[l];if(!o)continue;const i=e[l];n[o.key]=null==i||""===i?null:"number"==typeof i?i:s(String(i),t)}return n}))(w,b,p);return{columns:b,rows:y}},a=(e,r)=>d(e,"\t",r);export{a as fromTSV};
1
+ import { t as r } from "./from-tsv-CPj6UzXC.js";
2
+ export {
3
+ r as fromTSV
4
+ };
@@ -1,16 +1,25 @@
1
- import { GraphConfig, VizLocale } from '@graphysdk/core/node';
2
-
3
- /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
- type Data = GraphConfig['data'];
1
+ import { Data, VizLocale } from './wire-data.types';
2
+ export type { Data, VizLocale };
3
+ /** Supported file formats. */
4
+ export type FileFormat = 'csv' | 'tsv' | 'json' | 'xlsx' | 'xls' | 'ods';
5
+ /** Text-based formats that accept string input. */
6
+ export type TextFileFormat = 'csv' | 'tsv' | 'json';
7
+ /** Binary formats that accept ArrayBuffer input. */
8
+ export type BinaryFileFormat = 'xlsx' | 'xls' | 'ods';
5
9
  /** Shared base options for all parsers. */
6
- interface BaseParseOptions {
10
+ export interface BaseParseOptions {
7
11
  /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
12
  locale?: VizLocale;
9
13
  /** Maximum allowed input size in megabytes. @default 5 */
10
14
  maxFileSize?: number;
11
15
  }
16
+ /** Options for CSV / TSV parsing. */
17
+ export interface DelimitedParseOptions extends BaseParseOptions {
18
+ /** Whether the first row contains column headers. @default true */
19
+ hasHeader?: boolean;
20
+ }
12
21
  /** Options for XLSX / XLS / ODS parsing. */
13
- interface SpreadsheetParseOptions extends BaseParseOptions {
22
+ export interface SpreadsheetParseOptions extends BaseParseOptions {
14
23
  /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
15
24
  sheet?: string | number;
16
25
  /** Maximum number of data rows to process. @default 100_000 */
@@ -18,8 +27,10 @@ interface SpreadsheetParseOptions extends BaseParseOptions {
18
27
  /** Maximum total cells to process. @default 5_000_000 */
19
28
  maxCells?: number;
20
29
  }
30
+ /** Options for `fromFile` — covers both delimited and spreadsheet formats. */
31
+ export type FileParseOptions = SpreadsheetParseOptions & Pick<DelimitedParseOptions, 'hasHeader'>;
21
32
  /** Options specific to URL fetching. */
22
- interface URLParseOptions extends SpreadsheetParseOptions {
33
+ export interface URLParseOptions extends SpreadsheetParseOptions {
23
34
  /** Custom headers to include in the fetch request. */
24
35
  headers?: Record<string, string>;
25
36
  /** Whether the first row contains column headers. @default true */
@@ -29,20 +40,3 @@ interface URLParseOptions extends SpreadsheetParseOptions {
29
40
  /** Optional external abort signal for cancellation. */
30
41
  signal?: AbortSignal;
31
42
  }
32
-
33
- /**
34
- * Fetches a remote file by URL and parses it into the `Data` shape expected by
35
- * `generateGraph()`. The format is detected from the URL path extension, falling
36
- * back to the response `Content-Type` header.
37
- *
38
- * @example
39
- * ```ts
40
- * const data = await fromURL('https://example.com/sales.csv');
41
- * const data = await fromURL('https://example.com/report.xlsx', { sheet: 'Revenue' });
42
- * const data = await fromURL('https://example.com/data.csv', { headers: { Authorization: 'Bearer token' } });
43
- * ```
44
- */
45
- declare const fromURL: (url: string, options?: URLParseOptions) => Promise<Data>;
46
-
47
- export { fromURL };
48
- export type { Data, URLParseOptions };
package/dist/url.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("tslib"),t=require("papaparse"),o=require("@graphysdk/core/node"),r=require("exceljs");const n=new Set(["csv","tsv","json"]),s={".csv":"csv",".tsv":"tsv",".tab":"tsv",".json":"json",".xlsx":"xlsx",".xls":"xls",".ods":"ods"},i=new Set(["http:","https:"]),l=[/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/],a=[/^::1$/,/^fc00:/i,/^fe80:/i],u=e=>{(e=>{if(!i.has(e.protocol))throw new Error(`Unsupported URL scheme: ${e.protocol}. Only http: and https: are supported.`)})(e),(e=>{const t=e.toLowerCase();if("localhost"===t)throw new Error(`Access to private network address is not allowed: ${e}`);const o=t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t,r=l.some(e=>e.test(o)),n=a.some(e=>e.test(o));if(r||n)throw new Error(`Access to private network address is not allowed: ${e}`)})(e.hostname)},c=(e,t)=>{var r;const n=[];for(let s=0;s<t;s++){const t=null===(r=null==e?void 0:e[s])||void 0===r?void 0:r.trim(),i={key:o.columnIndexToPropertyKey(s)};t&&(i.label=t),n.push(i)}return n},d=/[^\p{ASCII}]/u,f=/[\u2012\u2013\u2014\u2212](?=\d)/g,w=/\u00A0/g,m=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,p=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,h=new Set(["PT_PT","AR"]),v=(e,t="EN_US")=>{let o;if(o=d.test(e)?e.replace(f,"-").replace(w," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(h.has(t)){if(p.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(m.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},y=(e,t,o)=>e.map(e=>{const r={};for(let n=0;n<t.length;n++){const s=t[n];if(!s)continue;const i=e[n];r[s.key]=null==i||""===i?null:"number"==typeof i?i:v(String(i),o)}return r}),x=(e,o,r)=>{var n,s,i,l,a;const u=1024*(null!==(n=null==r?void 0:r.maxFileSize)&&void 0!==n?n:5)*1024;if(e.length>u)throw new Error(`Input size (${e.length} bytes) exceeds the maximum allowed size of ${u} bytes (${null!==(s=null==r?void 0:r.maxFileSize)&&void 0!==s?s:5} MB).`);const d=!1!==(null==r?void 0:r.hasHeader),f=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",w=t.parse(e,{header:!1,delimiter:o,skipEmptyLines:!0}),m=w.errors.filter(e=>"Quotes"===e.type);if(m.length>0){const e=m[0];throw new Error(`Parse error at row ${null!==(l=null==e?void 0:e.row)&&void 0!==l?l:"?"}: ${null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"}`)}const p=w.data;if(0===p.length)return{columns:[],rows:[]};const h=d?p[0]:void 0,v=d?p.slice(1):p,x=p.reduce((e,t)=>Math.max(e,t.length),0),b=c(h,x);return{columns:b,rows:y(v,b,f)}},b=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),g=e=>null==e?null:"number"==typeof e?Number.isFinite(e)?e:null:"string"==typeof e?e:"boolean"==typeof e?String(e):JSON.stringify(e),$=(e,t)=>{const o="string"==typeof e?((e,t)=>{var o;const r=null!==(o=null==t?void 0:t.maxFileSize)&&void 0!==o?o:5,n=1024*r*1024,s=(new TextEncoder).encode(e).byteLength;if(s>n)throw new Error(`Input size (${s} bytes) exceeds the maximum allowed size of ${n} bytes (${r} MB).`);try{return JSON.parse(e)}catch(e){throw new Error(`Invalid JSON: ${e instanceof Error?e.message:"could not parse"}`)}})(e,t):e;if(Array.isArray(o))return(e=>{const t=[],o=new Set;for(const r of e){if(!b(r))throw new Error("Each JSON row must be an object mapping column names to values.");for(const e of Object.keys(r))o.has(e)||(o.add(e),t.push(e))}return{columns:t.map(e=>({key:e})),rows:e.map(e=>{const o={};for(const r of t)o[r]=g(e[r]);return o})}})(o);if((e=>b(e)&&Array.isArray(e.columns)&&Array.isArray(e.rows))(o))return(e=>{const t=e.columns.map(e=>{if(!b(e)||"string"!=typeof e.key||0===e.key.length)throw new Error('Each JSON column must be an object with a non-empty string "key".');return void 0!==e.label?{key:e.key,label:String(e.label)}:{key:e.key}}),o=e.rows.map(e=>{if(!b(e))throw new Error("Each JSON row must be an object mapping column keys to values.");const o={};for(const r of t)o[r.key]=g(e[r.key]);return o});return{columns:t,rows:o}})(o);throw new Error("Unsupported JSON dataset: expected an array of row objects or a { columns, rows } object.")},E=e=>{const{value:t}=e;if(null==t)return null;if("number"==typeof t)return t;if("string"==typeof t)return""===t?null:t;if("boolean"==typeof t)return t?1:0;if(t instanceof Date)return t.toISOString();if((e=>"object"==typeof e&&null!==e&&"formula"in e)(t)){if("number"==typeof t.result)return t.result;if("string"==typeof t.result)return""===t.result?null:t.result;if("boolean"==typeof t.result)return t.result?1:0;if(t.result instanceof Date)return t.result.toISOString()}const o=e.text;return""===o?null:o},S=["dataValidations","conditionalFormatting","sheetProtection"];const k=(t,o)=>e.__awaiter(void 0,void 0,void 0,function*(){var n,s,i,l,a;const u=1024*(null!==(n=null==o?void 0:o.maxFileSize)&&void 0!==n?n:5)*1024;if(t.byteLength>u)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${u} bytes (${null!==(s=null==o?void 0:o.maxFileSize)&&void 0!==s?s:5} MB).`);const d=null!==(i=null==o?void 0:o.locale)&&void 0!==i?i:"EN_US",f=yield function(t){return e.__awaiter(this,void 0,void 0,function*(){const e=new r.Workbook;return yield e.xlsx.load(t,{ignoreNodes:S}),e})}(t),w=((e,t)=>{if(void 0===t)return e.worksheets[0];if("number"==typeof t){const o=e.worksheets[t];if(!o)throw new Error(`Sheet index ${t} is out of range. Workbook has ${e.worksheets.length} sheet(s).`);return o}const o=e.getWorksheet(t);if(!o){const o=e.worksheets.map(e=>`"${e.name}"`).join(", ");throw new Error(`Sheet "${t}" not found. Available sheets: ${o}`)}return o})(f,null==o?void 0:o.sheet);if(!w||0===w.rowCount)return{columns:[],rows:[]};const m=w.columnCount;if(0===m)return{columns:[],rows:[]};const p=w.getRow(1),h=[];for(let e=1;e<=m;e++){const t=p.getCell(e).value;h.push(String(null!=t?t:""))}const v=c(h,m),x=null!==(l=null==o?void 0:o.maxRows)&&void 0!==l?l:1e5,b=null!==(a=null==o?void 0:o.maxCells)&&void 0!==a?a:5e6,g=[];let $=0,k=0;for(let e=2;e<=w.rowCount;e++){if($++,$>x)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${x}). Use the maxRows option to increase the limit.`);if(k+=m,k>b)throw new Error(`Cell limit exceeded: processed ${k} cells (maximum: ${b}). Use the maxCells option to increase the limit.`);const t=w.getRow(e),o=[];for(let e=1;e<=m;e++)o.push(E(t.getCell(e)));g.push(o)}return{columns:v,rows:y(g,v,d)}}),z=(e,t,o)=>{switch(t){case"csv":return((e,t)=>x(e,void 0,t))(e,o);case"tsv":return((e,t)=>x(e,"\t",t))(e,o);case"json":return $(e,o);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv, json`)}},j=(t,o,r)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(o){case"xlsx":case"xls":case"ods":return((e,t)=>k(e,t))(t,r);default:throw new Error(`Unsupported binary format "${o}". Supported: xlsx, xls, ods`)}}),A={"text/csv":"csv","text/tab-separated-values":"tsv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods"};exports.fromURL=(t,o)=>e.__awaiter(void 0,void 0,void 0,function*(){var r,i,l;const a=new URL(t);u(a);const{pathname:c}=a,d=c.lastIndexOf("."),f=(e=>s[e.toLowerCase()])(-1===d?"":c.slice(d)),w=AbortSignal.timeout(null!==(r=null==o?void 0:o.timeout)&&void 0!==r?r:3e4),m={signal:(null==o?void 0:o.signal)?AbortSignal.any([w,o.signal]):w};(null==o?void 0:o.headers)&&(m.headers=o.headers);const p=yield fetch(t,m);if(!p.ok)throw new Error(`Failed to fetch "${t}": ${p.status} ${p.statusText}`);const h=null!=f?f:(e=>{var t;if(!e)return;const o=null===(t=e.split(";")[0])||void 0===t?void 0:t.trim().toLowerCase();return o?A[o]:void 0})(p.headers.get("content-type"));if(!h){const e=Object.keys(s).join(", ");throw new Error(`Could not detect format for "${t}". No recognized file extension or Content-Type. Supported extensions: ${e}`)}const v=1024*(null!==(i=null==o?void 0:o.maxFileSize)&&void 0!==i?i:5)*1024,y=p.headers.get("content-length");if(y&&Number(y)>v)throw new Error(`Response size (${y} bytes) exceeds the maximum allowed size of ${v} bytes (${null!==(l=null==o?void 0:o.maxFileSize)&&void 0!==l?l:5} MB).`);const x=n.has(h),b=yield((t,o,r)=>e.__awaiter(void 0,void 0,void 0,function*(){const e=t.body;if(!e){if(r){const e=yield t.text(),r=(new TextEncoder).encode(e).byteLength;if(r>o)throw new Error(`Response body size (${r} bytes) exceeds the maximum allowed size of ${o} bytes.`);return e}const e=yield t.arrayBuffer();if(e.byteLength>o)throw new Error(`Response body size (${e.byteLength} bytes) exceeds the maximum allowed size of ${o} bytes.`);return e}const n=e.getReader(),s=[];let i=0;try{for(;;){const{done:e,value:t}=yield n.read();if(e)break;if(i+=t.byteLength,i>o)throw yield n.cancel(),new Error(`Response body size exceeds the maximum allowed size of ${o} bytes. Download aborted.`);s.push(t)}}catch(e){if(e instanceof Error&&e.message.includes("maximum allowed size"))throw e;throw yield n.cancel().catch(()=>{}),e}if(r){const e=new TextDecoder;return s.map(t=>e.decode(t,{stream:!0})).join("")+e.decode()}const l=new Uint8Array(i);let a=0;for(const e of s)l.set(e,a),a+=e.byteLength;return l.buffer}))(p,v,x);return((t,o,r)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(o){case"csv":case"tsv":case"json":if("string"!=typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return z(t,o,r);case"xlsx":case"xls":case"ods":if("string"==typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);return j(t,o,r);default:throw new Error(`Unsupported format "${o}". Supported formats: csv, tsv, json, xlsx, xls, ods`)}}))(b,h,o)});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./format-detection-1kqWtVpP.cjs"),u=require("./parse-string-DpdSP3xh.cjs");var p=new Set(["http:","https:"]),b=[/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/],v=[/^::1$/,/^fc00:/i,/^fe80:/i],y=t=>{x(t),g(t.hostname)},x=t=>{if(!p.has(t.protocol))throw new Error(`Unsupported URL scheme: ${t.protocol}. Only http: and https: are supported.`)},g=t=>{const e=t.toLowerCase();if(e==="localhost")throw new Error(`Access to private network address is not allowed: ${t}`);const a=e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e,c=b.some(s=>s.test(a)),i=v.some(s=>s.test(a));if(c||i)throw new Error(`Access to private network address is not allowed: ${t}`)},E={"text/csv":"csv","text/tab-separated-values":"tsv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods"},$=async(t,e)=>{const a=new URL(t);y(a);const{pathname:c}=a,i=c.lastIndexOf("."),s=h.formatFromExtension(i===-1?"":c.slice(i)),d=AbortSignal.timeout(e?.timeout??3e4),f={signal:e?.signal?AbortSignal.any([d,e.signal]):d};e?.headers&&(f.headers=e.headers);const n=await fetch(t,f);if(!n.ok)throw new Error(`Failed to fetch "${t}": ${n.status} ${n.statusText}`);const o=s??T(n.headers.get("content-type"));if(!o){const w=Object.keys(h.EXTENSION_MAP).join(", ");throw new Error(`Could not detect format for "${t}". No recognized file extension or Content-Type. Supported extensions: ${w}`)}const r=(e?.maxFileSize??5)*1024*1024,l=n.headers.get("content-length");if(l&&Number(l)>r)throw new Error(`Response size (${l} bytes) exceeds the maximum allowed size of ${r} bytes (${e?.maxFileSize??5} MB).`);const m=h.TEXT_FORMATS.has(o);return u.fromString(await S(n,r,m),o,e)},S=async(t,e,a)=>{const c=t.body;if(!c){if(a){const r=await t.text(),l=new TextEncoder().encode(r).byteLength;if(l>e)throw new Error(`Response body size (${l} bytes) exceeds the maximum allowed size of ${e} bytes.`);return r}const o=await t.arrayBuffer();if(o.byteLength>e)throw new Error(`Response body size (${o.byteLength} bytes) exceeds the maximum allowed size of ${e} bytes.`);return o}const i=c.getReader(),s=[];let d=0;try{for(;;){const{done:o,value:r}=await i.read();if(o)break;if(d+=r.byteLength,d>e)throw await i.cancel(),new Error(`Response body size exceeds the maximum allowed size of ${e} bytes. Download aborted.`);s.push(r)}}catch(o){throw o instanceof Error&&o.message.includes("maximum allowed size")||await i.cancel().catch(()=>{}),o}if(a){const o=new TextDecoder;return s.map(r=>o.decode(r,{stream:!0})).join("")+o.decode()}const f=new Uint8Array(d);let n=0;for(const o of s)f.set(o,n),n+=o.byteLength;return f.buffer},T=t=>{if(!t)return;const e=t.split(";")[0]?.trim().toLowerCase();return e?E[e]:void 0};exports.fromURL=$;
package/dist/url.mjs CHANGED
@@ -1 +1,87 @@
1
- import{__awaiter as e}from"tslib";import t from"papaparse";import{columnIndexToPropertyKey as o}from"@graphysdk/core/node";import r from"exceljs";const n=new Set(["csv","tsv","json"]),s={".csv":"csv",".tsv":"tsv",".tab":"tsv",".json":"json",".xlsx":"xlsx",".xls":"xls",".ods":"ods"},i=new Set(["http:","https:"]),l=[/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\.0\.0\.0$/],a=[/^::1$/,/^fc00:/i,/^fe80:/i],u=e=>{(e=>{if(!i.has(e.protocol))throw new Error(`Unsupported URL scheme: ${e.protocol}. Only http: and https: are supported.`)})(e),(e=>{const t=e.toLowerCase();if("localhost"===t)throw new Error(`Access to private network address is not allowed: ${e}`);const o=t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t,r=l.some(e=>e.test(o)),n=a.some(e=>e.test(o));if(r||n)throw new Error(`Access to private network address is not allowed: ${e}`)})(e.hostname)},c=(e,t)=>{var r;const n=[];for(let s=0;s<t;s++){const t=null===(r=null==e?void 0:e[s])||void 0===r?void 0:r.trim(),i={key:o(s)};t&&(i.label=t),n.push(i)}return n},d=/[^\p{ASCII}]/u,f=/[\u2012\u2013\u2014\u2212](?=\d)/g,m=/\u00A0/g,p=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,h=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,w=new Set(["PT_PT","AR"]),v=(e,t="EN_US")=>{let o;if(o=d.test(e)?e.replace(f,"-").replace(m," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(w.has(t)){if(h.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(p.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},y=(e,t,o)=>e.map(e=>{const r={};for(let n=0;n<t.length;n++){const s=t[n];if(!s)continue;const i=e[n];r[s.key]=null==i||""===i?null:"number"==typeof i?i:v(String(i),o)}return r}),x=(e,o,r)=>{var n,s,i,l,a;const u=1024*(null!==(n=null==r?void 0:r.maxFileSize)&&void 0!==n?n:5)*1024;if(e.length>u)throw new Error(`Input size (${e.length} bytes) exceeds the maximum allowed size of ${u} bytes (${null!==(s=null==r?void 0:r.maxFileSize)&&void 0!==s?s:5} MB).`);const d=!1!==(null==r?void 0:r.hasHeader),f=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",m=t.parse(e,{header:!1,delimiter:o,skipEmptyLines:!0}),p=m.errors.filter(e=>"Quotes"===e.type);if(p.length>0){const e=p[0];throw new Error(`Parse error at row ${null!==(l=null==e?void 0:e.row)&&void 0!==l?l:"?"}: ${null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"}`)}const h=m.data;if(0===h.length)return{columns:[],rows:[]};const w=d?h[0]:void 0,v=d?h.slice(1):h,x=h.reduce((e,t)=>Math.max(e,t.length),0),b=c(w,x);return{columns:b,rows:y(v,b,f)}},b=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),g=e=>null==e?null:"number"==typeof e?Number.isFinite(e)?e:null:"string"==typeof e?e:"boolean"==typeof e?String(e):JSON.stringify(e),$=(e,t)=>{const o="string"==typeof e?((e,t)=>{var o;const r=null!==(o=null==t?void 0:t.maxFileSize)&&void 0!==o?o:5,n=1024*r*1024,s=(new TextEncoder).encode(e).byteLength;if(s>n)throw new Error(`Input size (${s} bytes) exceeds the maximum allowed size of ${n} bytes (${r} MB).`);try{return JSON.parse(e)}catch(e){throw new Error(`Invalid JSON: ${e instanceof Error?e.message:"could not parse"}`)}})(e,t):e;if(Array.isArray(o))return(e=>{const t=[],o=new Set;for(const r of e){if(!b(r))throw new Error("Each JSON row must be an object mapping column names to values.");for(const e of Object.keys(r))o.has(e)||(o.add(e),t.push(e))}return{columns:t.map(e=>({key:e})),rows:e.map(e=>{const o={};for(const r of t)o[r]=g(e[r]);return o})}})(o);if((e=>b(e)&&Array.isArray(e.columns)&&Array.isArray(e.rows))(o))return(e=>{const t=e.columns.map(e=>{if(!b(e)||"string"!=typeof e.key||0===e.key.length)throw new Error('Each JSON column must be an object with a non-empty string "key".');return void 0!==e.label?{key:e.key,label:String(e.label)}:{key:e.key}}),o=e.rows.map(e=>{if(!b(e))throw new Error("Each JSON row must be an object mapping column keys to values.");const o={};for(const r of t)o[r.key]=g(e[r.key]);return o});return{columns:t,rows:o}})(o);throw new Error("Unsupported JSON dataset: expected an array of row objects or a { columns, rows } object.")},E=e=>{const{value:t}=e;if(null==t)return null;if("number"==typeof t)return t;if("string"==typeof t)return""===t?null:t;if("boolean"==typeof t)return t?1:0;if(t instanceof Date)return t.toISOString();if((e=>"object"==typeof e&&null!==e&&"formula"in e)(t)){if("number"==typeof t.result)return t.result;if("string"==typeof t.result)return""===t.result?null:t.result;if("boolean"==typeof t.result)return t.result?1:0;if(t.result instanceof Date)return t.result.toISOString()}const o=e.text;return""===o?null:o},S=["dataValidations","conditionalFormatting","sheetProtection"];const k=(t,o)=>e(void 0,void 0,void 0,function*(){var n,s,i,l,a;const u=1024*(null!==(n=null==o?void 0:o.maxFileSize)&&void 0!==n?n:5)*1024;if(t.byteLength>u)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${u} bytes (${null!==(s=null==o?void 0:o.maxFileSize)&&void 0!==s?s:5} MB).`);const d=null!==(i=null==o?void 0:o.locale)&&void 0!==i?i:"EN_US",f=yield function(t){return e(this,void 0,void 0,function*(){const e=new r.Workbook;return yield e.xlsx.load(t,{ignoreNodes:S}),e})}(t),m=((e,t)=>{if(void 0===t)return e.worksheets[0];if("number"==typeof t){const o=e.worksheets[t];if(!o)throw new Error(`Sheet index ${t} is out of range. Workbook has ${e.worksheets.length} sheet(s).`);return o}const o=e.getWorksheet(t);if(!o){const o=e.worksheets.map(e=>`"${e.name}"`).join(", ");throw new Error(`Sheet "${t}" not found. Available sheets: ${o}`)}return o})(f,null==o?void 0:o.sheet);if(!m||0===m.rowCount)return{columns:[],rows:[]};const p=m.columnCount;if(0===p)return{columns:[],rows:[]};const h=m.getRow(1),w=[];for(let e=1;e<=p;e++){const t=h.getCell(e).value;w.push(String(null!=t?t:""))}const v=c(w,p),x=null!==(l=null==o?void 0:o.maxRows)&&void 0!==l?l:1e5,b=null!==(a=null==o?void 0:o.maxCells)&&void 0!==a?a:5e6,g=[];let $=0,k=0;for(let e=2;e<=m.rowCount;e++){if($++,$>x)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${x}). Use the maxRows option to increase the limit.`);if(k+=p,k>b)throw new Error(`Cell limit exceeded: processed ${k} cells (maximum: ${b}). Use the maxCells option to increase the limit.`);const t=m.getRow(e),o=[];for(let e=1;e<=p;e++)o.push(E(t.getCell(e)));g.push(o)}return{columns:v,rows:y(g,v,d)}}),z=(e,t,o)=>{switch(t){case"csv":return((e,t)=>x(e,void 0,t))(e,o);case"tsv":return((e,t)=>x(e,"\t",t))(e,o);case"json":return $(e,o);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv, json`)}},j=(t,o,r)=>e(void 0,void 0,void 0,function*(){switch(o){case"xlsx":case"xls":case"ods":return((e,t)=>k(e,t))(t,r);default:throw new Error(`Unsupported binary format "${o}". Supported: xlsx, xls, ods`)}}),A={"text/csv":"csv","text/tab-separated-values":"tsv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods"},N=(t,o)=>e(void 0,void 0,void 0,function*(){var r,i,l;const a=new URL(t);u(a);const{pathname:c}=a,d=c.lastIndexOf("."),f=(e=>s[e.toLowerCase()])(-1===d?"":c.slice(d)),m=AbortSignal.timeout(null!==(r=null==o?void 0:o.timeout)&&void 0!==r?r:3e4),p={signal:(null==o?void 0:o.signal)?AbortSignal.any([m,o.signal]):m};(null==o?void 0:o.headers)&&(p.headers=o.headers);const h=yield fetch(t,p);if(!h.ok)throw new Error(`Failed to fetch "${t}": ${h.status} ${h.statusText}`);const w=null!=f?f:(e=>{var t;if(!e)return;const o=null===(t=e.split(";")[0])||void 0===t?void 0:t.trim().toLowerCase();return o?A[o]:void 0})(h.headers.get("content-type"));if(!w){const e=Object.keys(s).join(", ");throw new Error(`Could not detect format for "${t}". No recognized file extension or Content-Type. Supported extensions: ${e}`)}const v=1024*(null!==(i=null==o?void 0:o.maxFileSize)&&void 0!==i?i:5)*1024,y=h.headers.get("content-length");if(y&&Number(y)>v)throw new Error(`Response size (${y} bytes) exceeds the maximum allowed size of ${v} bytes (${null!==(l=null==o?void 0:o.maxFileSize)&&void 0!==l?l:5} MB).`);const x=n.has(w),b=yield((t,o,r)=>e(void 0,void 0,void 0,function*(){const e=t.body;if(!e){if(r){const e=yield t.text(),r=(new TextEncoder).encode(e).byteLength;if(r>o)throw new Error(`Response body size (${r} bytes) exceeds the maximum allowed size of ${o} bytes.`);return e}const e=yield t.arrayBuffer();if(e.byteLength>o)throw new Error(`Response body size (${e.byteLength} bytes) exceeds the maximum allowed size of ${o} bytes.`);return e}const n=e.getReader(),s=[];let i=0;try{for(;;){const{done:e,value:t}=yield n.read();if(e)break;if(i+=t.byteLength,i>o)throw yield n.cancel(),new Error(`Response body size exceeds the maximum allowed size of ${o} bytes. Download aborted.`);s.push(t)}}catch(e){if(e instanceof Error&&e.message.includes("maximum allowed size"))throw e;throw yield n.cancel().catch(()=>{}),e}if(r){const e=new TextDecoder;return s.map(t=>e.decode(t,{stream:!0})).join("")+e.decode()}const l=new Uint8Array(i);let a=0;for(const e of s)l.set(e,a),a+=e.byteLength;return l.buffer}))(h,v,x);return((t,o,r)=>e(void 0,void 0,void 0,function*(){switch(o){case"csv":case"tsv":case"json":if("string"!=typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return z(t,o,r);case"xlsx":case"xls":case"ods":if("string"==typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);return j(t,o,r);default:throw new Error(`Unsupported format "${o}". Supported formats: csv, tsv, json, xlsx, xls, ods`)}}))(b,w,o)});export{N as fromURL};
1
+ import { n as w, r as p, t as u } from "./format-detection-MwlOpP6Y.js";
2
+ import { n as b } from "./parse-string-VVlSsL2Y.js";
3
+ var v = /* @__PURE__ */ new Set(["http:", "https:"]), x = [
4
+ /^127\./,
5
+ /^10\./,
6
+ /^172\.(1[6-9]|2\d|3[01])\./,
7
+ /^192\.168\./,
8
+ /^169\.254\./,
9
+ /^0\.0\.0\.0$/
10
+ ], y = [
11
+ /^::1$/,
12
+ /^fc00:/i,
13
+ /^fe80:/i
14
+ ], E = (t) => {
15
+ g(t), $(t.hostname);
16
+ }, g = (t) => {
17
+ if (!v.has(t.protocol)) throw new Error(`Unsupported URL scheme: ${t.protocol}. Only http: and https: are supported.`);
18
+ }, $ = (t) => {
19
+ const e = t.toLowerCase();
20
+ if (e === "localhost") throw new Error(`Access to private network address is not allowed: ${t}`);
21
+ const n = e.startsWith("[") && e.endsWith("]") ? e.slice(1, -1) : e, c = x.some((s) => s.test(n)), i = y.some((s) => s.test(n));
22
+ if (c || i) throw new Error(`Access to private network address is not allowed: ${t}`);
23
+ }, T = {
24
+ "text/csv": "csv",
25
+ "text/tab-separated-values": "tsv",
26
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
27
+ "application/vnd.ms-excel": "xls",
28
+ "application/vnd.oasis.opendocument.spreadsheet": "ods"
29
+ }, z = async (t, e) => {
30
+ const n = new URL(t);
31
+ E(n);
32
+ const { pathname: c } = n, i = c.lastIndexOf("."), s = p(i === -1 ? "" : c.slice(i)), d = AbortSignal.timeout(e?.timeout ?? 3e4), f = { signal: e?.signal ? AbortSignal.any([d, e.signal]) : d };
33
+ e?.headers && (f.headers = e.headers);
34
+ const a = await fetch(t, f);
35
+ if (!a.ok) throw new Error(`Failed to fetch "${t}": ${a.status} ${a.statusText}`);
36
+ const o = s ?? R(a.headers.get("content-type"));
37
+ if (!o) {
38
+ const m = Object.keys(u).join(", ");
39
+ throw new Error(`Could not detect format for "${t}". No recognized file extension or Content-Type. Supported extensions: ${m}`);
40
+ }
41
+ const r = (e?.maxFileSize ?? 5) * 1024 * 1024, l = a.headers.get("content-length");
42
+ if (l && Number(l) > r) throw new Error(`Response size (${l} bytes) exceeds the maximum allowed size of ${r} bytes (${e?.maxFileSize ?? 5} MB).`);
43
+ const h = w.has(o);
44
+ return b(await L(a, r, h), o, e);
45
+ }, L = async (t, e, n) => {
46
+ const c = t.body;
47
+ if (!c) {
48
+ if (n) {
49
+ const r = await t.text(), l = new TextEncoder().encode(r).byteLength;
50
+ if (l > e) throw new Error(`Response body size (${l} bytes) exceeds the maximum allowed size of ${e} bytes.`);
51
+ return r;
52
+ }
53
+ const o = await t.arrayBuffer();
54
+ if (o.byteLength > e) throw new Error(`Response body size (${o.byteLength} bytes) exceeds the maximum allowed size of ${e} bytes.`);
55
+ return o;
56
+ }
57
+ const i = c.getReader(), s = [];
58
+ let d = 0;
59
+ try {
60
+ for (; ; ) {
61
+ const { done: o, value: r } = await i.read();
62
+ if (o) break;
63
+ if (d += r.byteLength, d > e)
64
+ throw await i.cancel(), new Error(`Response body size exceeds the maximum allowed size of ${e} bytes. Download aborted.`);
65
+ s.push(r);
66
+ }
67
+ } catch (o) {
68
+ throw o instanceof Error && o.message.includes("maximum allowed size") || await i.cancel().catch(() => {
69
+ }), o;
70
+ }
71
+ if (n) {
72
+ const o = new TextDecoder();
73
+ return s.map((r) => o.decode(r, { stream: !0 })).join("") + o.decode();
74
+ }
75
+ const f = new Uint8Array(d);
76
+ let a = 0;
77
+ for (const o of s)
78
+ f.set(o, a), a += o.byteLength;
79
+ return f.buffer;
80
+ }, R = (t) => {
81
+ if (!t) return;
82
+ const e = t.split(";")[0]?.trim().toLowerCase();
83
+ return e ? T[e] : void 0;
84
+ };
85
+ export {
86
+ z as fromURL
87
+ };
@@ -0,0 +1,10 @@
1
+ import { Data } from '../types';
2
+ type Column = Data['columns'][number];
3
+ /**
4
+ * Builds column definitions from an optional header row.
5
+ *
6
+ * Keys are generated with `columnIndexToPropertyKey` (`c1`, `c2`, …) to stay
7
+ * consistent with the server-side parsing.
8
+ */
9
+ export declare const buildColumns: (headerRow: string[] | undefined, columnCount: number) => Column[];
10
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Column keys `c1`, `c2`, … — same convention as Classic core / agents pipeline. */
2
+ export declare const columnIndexToPropertyKey: (index: number) => string;
@@ -0,0 +1,6 @@
1
+ /** Default maximum input size in megabytes. */
2
+ export declare const DEFAULT_MAX_SIZE_MB = 5;
3
+ /** Default maximum number of data rows to process in spreadsheet parsing. */
4
+ export declare const DEFAULT_MAX_ROWS = 100000;
5
+ /** Default maximum total number of cells to process in spreadsheet parsing. */
6
+ export declare const DEFAULT_MAX_CELLS = 5000000;
@@ -0,0 +1,4 @@
1
+ import { FileFormat } from '../types';
2
+ export declare const TEXT_FORMATS: Set<FileFormat>;
3
+ export declare const EXTENSION_MAP: Record<string, FileFormat>;
4
+ export declare const formatFromExtension: (ext: string) => FileFormat | undefined;