@graphysdk/data-import-utils 1.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # `@graphysdk/data-import-utils`
2
+
3
+ Parse CSV, TSV, and spreadsheet files into the `{ columns, rows }` data shape expected by `@graphysdk/core`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @graphysdk/data-import-utils
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ `@graphysdk/core` is required:
14
+
15
+ ```bash
16
+ pnpm add @graphysdk/core
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Parse a file from disk
22
+
23
+ ```ts
24
+ import { fromFile } from '@graphysdk/data-import-utils/file';
25
+
26
+ const data = await fromFile('sales.csv');
27
+ const data = await fromFile('report.xlsx', { sheet: 'Revenue' });
28
+ ```
29
+
30
+ ### Parse from a URL
31
+
32
+ ```ts
33
+ import { fromURL } from '@graphysdk/data-import-utils/url';
34
+
35
+ const data = await fromURL('https://example.com/sales.csv');
36
+ const data = await fromURL('https://example.com/report.xlsx', { sheet: 'Revenue' });
37
+ ```
38
+
39
+ ### Format-specific imports
40
+
41
+ Each format has a dedicated entrypoint so you only bundle what you need:
42
+
43
+ ```ts
44
+ import { fromCSV } from '@graphysdk/data-import-utils/csv';
45
+ import { fromTSV } from '@graphysdk/data-import-utils/tsv';
46
+ import { fromXLSX } from '@graphysdk/data-import-utils/xlsx';
47
+ import { fromXLS } from '@graphysdk/data-import-utils/xls';
48
+ import { fromODS } from '@graphysdk/data-import-utils/ods';
49
+ ```
50
+
51
+ ### Feeding into `generateGraph()`
52
+
53
+ ```ts
54
+ import { fromFile } from '@graphysdk/data-import-utils/file';
55
+ import { GraphyAiSdk } from '@graphysdk/agents-sdk';
56
+
57
+ const data = await fromFile('revenue.csv');
58
+
59
+ const ai = new GraphyAiSdk({ apiKey: process.env.GRAPHY_API_KEY });
60
+ const result = await ai.generateGraph({
61
+ config: { data },
62
+ userPrompt: 'bar chart of revenue by company',
63
+ });
64
+ ```
65
+
66
+ ## Supported Formats
67
+
68
+ | Format | Function | Input type |
69
+ | ------ | ------------ | ------------- |
70
+ | CSV | `fromCSV()` | `string` |
71
+ | TSV | `fromTSV()` | `string` |
72
+ | XLSX | `fromXLSX()` | `ArrayBuffer` |
73
+ | XLS | `fromXLS()` | `ArrayBuffer` |
74
+ | ODS | `fromODS()` | `ArrayBuffer` |
75
+
76
+ ## Docs
77
+
78
+ Full documentation: [https://docs.graphy.app/data-import-utils](https://docs.graphy.app/data-import-utils)
package/dist/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # `@graphysdk/data-import-utils`
2
+
3
+ Parse CSV, TSV, and spreadsheet files into the `{ columns, rows }` data shape expected by `@graphysdk/core`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @graphysdk/data-import-utils
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ `@graphysdk/core` is required:
14
+
15
+ ```bash
16
+ pnpm add @graphysdk/core
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Parse a file from disk
22
+
23
+ ```ts
24
+ import { fromFile } from '@graphysdk/data-import-utils/file';
25
+
26
+ const data = await fromFile('sales.csv');
27
+ const data = await fromFile('report.xlsx', { sheet: 'Revenue' });
28
+ ```
29
+
30
+ ### Parse from a URL
31
+
32
+ ```ts
33
+ import { fromURL } from '@graphysdk/data-import-utils/url';
34
+
35
+ const data = await fromURL('https://example.com/sales.csv');
36
+ const data = await fromURL('https://example.com/report.xlsx', { sheet: 'Revenue' });
37
+ ```
38
+
39
+ ### Format-specific imports
40
+
41
+ Each format has a dedicated entrypoint so you only bundle what you need:
42
+
43
+ ```ts
44
+ import { fromCSV } from '@graphysdk/data-import-utils/csv';
45
+ import { fromTSV } from '@graphysdk/data-import-utils/tsv';
46
+ import { fromXLSX } from '@graphysdk/data-import-utils/xlsx';
47
+ import { fromXLS } from '@graphysdk/data-import-utils/xls';
48
+ import { fromODS } from '@graphysdk/data-import-utils/ods';
49
+ ```
50
+
51
+ ### Feeding into `generateGraph()`
52
+
53
+ ```ts
54
+ import { fromFile } from '@graphysdk/data-import-utils/file';
55
+ import { GraphyAiSdk } from '@graphysdk/agents-sdk';
56
+
57
+ const data = await fromFile('revenue.csv');
58
+
59
+ const ai = new GraphyAiSdk({ apiKey: process.env.GRAPHY_API_KEY });
60
+ const result = await ai.generateGraph({
61
+ config: { data },
62
+ userPrompt: 'bar chart of revenue by company',
63
+ });
64
+ ```
65
+
66
+ ## Supported Formats
67
+
68
+ | Format | Function | Input type |
69
+ | ------ | ------------ | ------------- |
70
+ | CSV | `fromCSV()` | `string` |
71
+ | TSV | `fromTSV()` | `string` |
72
+ | XLSX | `fromXLSX()` | `ArrayBuffer` |
73
+ | XLS | `fromXLS()` | `ArrayBuffer` |
74
+ | ODS | `fromODS()` | `ArrayBuffer` |
75
+
76
+ ## Docs
77
+
78
+ Full documentation: [https://docs.graphy.app/data-import-utils](https://docs.graphy.app/data-import-utils)
@@ -0,0 +1 @@
1
+ "use strict";var e=require("tslib");require("papaparse");var t=require("@graphysdk/core/node"),r=require("exceljs");const o=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),a=(e,t="EN_US")=>{let r;if(r=o.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(u.has(t)){if(s.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},c=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},d=(o,n)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,l,i,s,u;const d=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(o.byteLength>d)throw new Error(`Input size (${o.byteLength} bytes) exceeds the maximum allowed size of ${d} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const f=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new r.Workbook;yield m.xlsx.load(o,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const 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})(m,null==n?void 0:n.sheet);if(!p||0===p.rowCount)return{columns:[],rows:[]};const h=p.columnCount;if(0===h)return{columns:[],rows:[]};const w=p.getRow(1),v=[];for(let e=1;e<=h;e++){const t=w.getCell(e).value;v.push(String(null!=t?t:""))}const x=((e,r)=>{var o;const n=[];for(let l=0;l<r;l++){const r=null===(o=null==e?void 0:e[l])||void 0===o?void 0:o.trim(),i={key:t.columnIndexToPropertyKey(l)};r&&(i.label=r),n.push(i)}return n})(v,h),g=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,b=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=p.rowCount;e++){if(S++,S>g)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${g}). Use the maxRows option to increase the limit.`);if($+=h,$>b)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${b}). Use the maxCells option to increase the limit.`);const t=p.getRow(e),r=[];for(let e=1;e<=h;e++)r.push(c(t.getCell(e)));y.push(r)}const k=((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:a(String(i),r)}return o}))(y,x,f);return{columns:x,rows:k}});exports.fromBuffer=(t,r,o)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(r){case"xlsx":case"xls":case"ods":return((e,t)=>d(e,t))(t,o);default:throw new Error(`Unsupported binary format "${r}". Supported: xlsx, xls, ods`)}});
@@ -0,0 +1,36 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Binary formats that accept ArrayBuffer input. */
6
+ type BinaryFileFormat = 'xlsx' | 'xls' | 'ods';
7
+ /** Shared base options for all parsers. */
8
+ interface BaseParseOptions {
9
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
10
+ locale?: VizLocale;
11
+ /** Maximum allowed input size in megabytes. @default 5 */
12
+ maxFileSize?: number;
13
+ }
14
+ /** Options for XLSX / XLS / ODS parsing. */
15
+ interface SpreadsheetParseOptions extends BaseParseOptions {
16
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
17
+ sheet?: string | number;
18
+ /** Maximum number of data rows to process. @default 100_000 */
19
+ maxRows?: number;
20
+ /** Maximum total cells to process. @default 5_000_000 */
21
+ maxCells?: number;
22
+ }
23
+
24
+ /**
25
+ * Parses a binary buffer (XLSX, XLS, or ODS) into the `Data` shape expected by `generateGraph()`.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const data = await fromBuffer(xlsxBuffer, 'xlsx');
30
+ * const data = await fromBuffer(odsBuffer, 'ods', { sheet: 'Revenue' });
31
+ * ```
32
+ */
33
+ declare const fromBuffer: (input: ArrayBuffer, format: BinaryFileFormat, options?: SpreadsheetParseOptions) => Promise<Data>;
34
+
35
+ export { fromBuffer };
36
+ export type { BaseParseOptions, BinaryFileFormat, Data, SpreadsheetParseOptions };
@@ -0,0 +1 @@
1
+ import{__awaiter as e}from"tslib";import"papaparse";import{columnIndexToPropertyKey as t}from"@graphysdk/core/node";import o from"exceljs";const r=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),a=(e,t="EN_US")=>{let o;if(o=r.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(u.has(t)){if(s.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},c=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},f=(r,n)=>e(void 0,void 0,void 0,function*(){var e,l,i,s,u;const f=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(r.byteLength>f)throw new Error(`Input size (${r.byteLength} bytes) exceeds the maximum allowed size of ${f} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new o.Workbook;yield m.xlsx.load(r,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const p=((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})(m,null==n?void 0:n.sheet);if(!p||0===p.rowCount)return{columns:[],rows:[]};const h=p.columnCount;if(0===h)return{columns:[],rows:[]};const w=p.getRow(1),v=[];for(let e=1;e<=h;e++){const t=w.getCell(e).value;v.push(String(null!=t?t:""))}const g=((e,o)=>{var r;const n=[];for(let l=0;l<o;l++){const o=null===(r=null==e?void 0:e[l])||void 0===r?void 0:r.trim(),i={key:t(l)};o&&(i.label=o),n.push(i)}return n})(v,h),x=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,b=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=p.rowCount;e++){if(S++,S>x)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${x}). Use the maxRows option to increase the limit.`);if($+=h,$>b)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${b}). Use the maxCells option to increase the limit.`);const t=p.getRow(e),o=[];for(let e=1;e<=h;e++)o.push(c(t.getCell(e)));y.push(o)}const k=((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:a(String(i),o)}return r}))(y,g,d);return{columns:g,rows:k}}),d=(t,o,r)=>e(void 0,void 0,void 0,function*(){switch(o){case"xlsx":case"xls":case"ods":return((e,t)=>f(e,t))(t,r);default:throw new Error(`Unsupported binary format "${o}". Supported: xlsx, xls, ods`)}});export{d as fromBuffer};
package/dist/csv.cjs ADDED
@@ -0,0 +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.fromCSV=(e,r)=>d(e,void 0,r);
package/dist/csv.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for CSV / TSV parsing. */
13
+ interface DelimitedParseOptions extends BaseParseOptions {
14
+ /** Whether the first row contains column headers. @default true */
15
+ hasHeader?: boolean;
16
+ }
17
+
18
+ /**
19
+ * Parses a CSV string into the `Data` shape expected by `generateGraph()`.
20
+ * The delimiter is auto-detected by PapaParse (comma, semicolon, pipe, tab, etc.).
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const data = fromCSV('Name,Revenue\nAcme,1000\nGlobex,2000');
25
+ * const data = fromCSV('Name;Revenue\nAcme;1000\nGlobex;2000'); // semicolon-delimited
26
+ * sdk.generateGraph({ config: { data }, userPrompt: 'bar chart' });
27
+ * ```
28
+ */
29
+ declare const fromCSV: (input: string, options?: DelimitedParseOptions) => Data;
30
+
31
+ export { fromCSV };
32
+ export type { BaseParseOptions, DelimitedParseOptions };
package/dist/csv.mjs ADDED
@@ -0,0 +1 @@
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,void 0,r);export{a as fromCSV};
package/dist/file.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=require("tslib"),t=require("node:fs/promises"),r=require("node:path"),o=require("papaparse"),n=require("@graphysdk/core/node"),s=require("exceljs");const i=new Set(["csv","tsv"]),l={".csv":"csv",".tsv":"tsv",".tab":"tsv",".xlsx":"xlsx",".xls":"xls",".ods":"ods"},u=(e,t)=>{var r;const o=[];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:n.columnIndexToPropertyKey(s)};t&&(i.label=t),o.push(i)}return o},a=/[^\p{ASCII}]/u,d=/[\u2012\u2013\u2014\u2212](?=\d)/g,f=/\u00A0/g,c=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,p=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,v=new Set(["PT_PT","AR"]),w=(e,t="EN_US")=>{let r;if(r=a.test(e)?e.replace(d,"-").replace(f," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(v.has(t)){if(p.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(c.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},m=(e,t,r)=>e.map(e=>{const o={};for(let n=0;n<t.length;n++){const s=t[n];if(!s)continue;const i=e[n];o[s.key]=null==i||""===i?null:"number"==typeof i?i:w(String(i),r)}return o}),h=(e,t,r)=>{var n,s,i,l,a;const d=1024*(null!==(n=null==r?void 0:r.maxFileSize)&&void 0!==n?n:5)*1024;if(e.length>d)throw new Error(`Input size (${e.length} bytes) exceeds the maximum allowed size of ${d} bytes (${null!==(s=null==r?void 0:r.maxFileSize)&&void 0!==s?s:5} MB).`);const f=!1!==(null==r?void 0:r.hasHeader),c=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",p=o.parse(e,{header:!1,delimiter:t,skipEmptyLines:!0}),v=p.errors.filter(e=>"Quotes"===e.type);if(v.length>0){const e=v[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 w=p.data;if(0===w.length)return{columns:[],rows:[]};const h=f?w[0]:void 0,x=f?w.slice(1):w,g=w.reduce((e,t)=>Math.max(e,t.length),0),y=u(h,g);return{columns:y,rows:m(x,y,c)}},x=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},g=(t,r)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,o,n,i,l;const a=1024*(null!==(e=null==r?void 0:r.maxFileSize)&&void 0!==e?e:5)*1024;if(t.byteLength>a)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(o=null==r?void 0:r.maxFileSize)&&void 0!==o?o:5} MB).`);const d=null!==(n=null==r?void 0:r.locale)&&void 0!==n?n:"EN_US",f=new s.Workbook;yield f.xlsx.load(t,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const c=((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})(f,null==r?void 0:r.sheet);if(!c||0===c.rowCount)return{columns:[],rows:[]};const p=c.columnCount;if(0===p)return{columns:[],rows:[]};const v=c.getRow(1),w=[];for(let e=1;e<=p;e++){const t=v.getCell(e).value;w.push(String(null!=t?t:""))}const h=u(w,p),g=null!==(i=null==r?void 0:r.maxRows)&&void 0!==i?i:1e5,y=null!==(l=null==r?void 0:r.maxCells)&&void 0!==l?l:5e6,b=[];let $=0,S=0;for(let e=2;e<=c.rowCount;e++){if($++,$>g)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${g}). Use the maxRows option to increase the limit.`);if(S+=p,S>y)throw new Error(`Cell limit exceeded: processed ${S} cells (maximum: ${y}). Use the maxCells option to increase the limit.`);const t=c.getRow(e),r=[];for(let e=1;e<=p;e++)r.push(x(t.getCell(e)));b.push(r)}return{columns:h,rows:m(b,h,d)}}),y=(e,t,r)=>{switch(t){case"csv":return((e,t)=>h(e,void 0,t))(e,r);case"tsv":return((e,t)=>h(e,"\t",t))(e,r);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv`)}},b=(t,r,o)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(r){case"xlsx":case"xls":case"ods":return((e,t)=>g(e,t))(t,o);default:throw new Error(`Unsupported binary format "${r}". Supported: xlsx, xls, ods`)}});exports.fromFile=(o,n)=>e.__awaiter(void 0,void 0,void 0,function*(){if("undefined"!=typeof window&&"undefined"==typeof process)throw new Error("fromFile is only available in Node.js environments. In the browser, read the file using the File API and pass the result to fromCSV (for text) or fromXLSX (for binary formats).");const s=r.extname(o).toLowerCase(),u=(e=>l[e.toLowerCase()])(s);if(!u){const e=Object.keys(l).join(", ");throw new Error(`Unsupported file extension "${s||"(none)"}". Supported: ${e}`)}const a=yield t.readFile(o);return((t,r,o)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(r){case"csv":case"tsv":if("string"!=typeof t)throw new TypeError(`${r.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return y(t,r,o);case"xlsx":case"xls":case"ods":if("string"==typeof t)throw new TypeError(`${r.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);return b(t,r,o);default:throw new Error(`Unsupported format "${r}". Supported formats: csv, tsv, xlsx, xls, ods`)}}))(i.has(u)?"string"==typeof a?a:a.toString("utf-8"):a instanceof Buffer?a.buffer.slice(a.byteOffset,a.byteOffset+a.byteLength):a,u,n)});
package/dist/file.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for CSV / TSV parsing. */
13
+ interface DelimitedParseOptions extends BaseParseOptions {
14
+ /** Whether the first row contains column headers. @default true */
15
+ hasHeader?: boolean;
16
+ }
17
+ /** Options for XLSX / XLS / ODS parsing. */
18
+ interface SpreadsheetParseOptions extends BaseParseOptions {
19
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
20
+ sheet?: string | number;
21
+ /** Maximum number of data rows to process. @default 100_000 */
22
+ maxRows?: number;
23
+ /** Maximum total cells to process. @default 5_000_000 */
24
+ maxCells?: number;
25
+ }
26
+ /** Options for `fromFile` — covers both delimited and spreadsheet formats. */
27
+ type FileParseOptions = SpreadsheetParseOptions & Pick<DelimitedParseOptions, 'hasHeader'>;
28
+
29
+ /**
30
+ * Reads a file from disk and parses it into the `Data` shape expected by
31
+ * `generateGraph()`. The format is auto-detected from the file extension.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const data = await fromFile('sales.csv');
36
+ * const data = await fromFile('report.xlsx', { sheet: 'Revenue' });
37
+ * ```
38
+ */
39
+ declare const fromFile: (filePath: string, options?: FileParseOptions) => Promise<Data>;
40
+
41
+ export { fromFile };
42
+ export type { BaseParseOptions, Data, FileParseOptions, SpreadsheetParseOptions };
package/dist/file.mjs ADDED
@@ -0,0 +1 @@
1
+ import{__awaiter as e}from"tslib";import{readFile as t}from"node:fs/promises";import r from"node:path";import o from"papaparse";import{columnIndexToPropertyKey as n}from"@graphysdk/core/node";import s from"exceljs";const i=new Set(["csv","tsv"]),l={".csv":"csv",".tsv":"tsv",".tab":"tsv",".xlsx":"xlsx",".xls":"xls",".ods":"ods"},u=(e,t)=>{var r;const o=[];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:n(s)};t&&(i.label=t),o.push(i)}return o},a=/[^\p{ASCII}]/u,d=/[\u2012\u2013\u2014\u2212](?=\d)/g,f=/\u00A0/g,c=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,p=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,m=new Set(["PT_PT","AR"]),v=(e,t="EN_US")=>{let r;if(r=a.test(e)?e.replace(d,"-").replace(f," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(m.has(t)){if(p.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(c.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},h=(e,t,r)=>e.map(e=>{const o={};for(let n=0;n<t.length;n++){const s=t[n];if(!s)continue;const i=e[n];o[s.key]=null==i||""===i?null:"number"==typeof i?i:v(String(i),r)}return o}),w=(e,t,r)=>{var n,s,i,l,a;const d=1024*(null!==(n=null==r?void 0:r.maxFileSize)&&void 0!==n?n:5)*1024;if(e.length>d)throw new Error(`Input size (${e.length} bytes) exceeds the maximum allowed size of ${d} bytes (${null!==(s=null==r?void 0:r.maxFileSize)&&void 0!==s?s:5} MB).`);const f=!1!==(null==r?void 0:r.hasHeader),c=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",p=o.parse(e,{header:!1,delimiter:t,skipEmptyLines:!0}),m=p.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 v=p.data;if(0===v.length)return{columns:[],rows:[]};const w=f?v[0]:void 0,x=f?v.slice(1):v,g=v.reduce((e,t)=>Math.max(e,t.length),0),y=u(w,g);return{columns:y,rows:h(x,y,c)}},x=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},g=(t,r)=>e(void 0,void 0,void 0,function*(){var e,o,n,i,l;const a=1024*(null!==(e=null==r?void 0:r.maxFileSize)&&void 0!==e?e:5)*1024;if(t.byteLength>a)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(o=null==r?void 0:r.maxFileSize)&&void 0!==o?o:5} MB).`);const d=null!==(n=null==r?void 0:r.locale)&&void 0!==n?n:"EN_US",f=new s.Workbook;yield f.xlsx.load(t,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const c=((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})(f,null==r?void 0:r.sheet);if(!c||0===c.rowCount)return{columns:[],rows:[]};const p=c.columnCount;if(0===p)return{columns:[],rows:[]};const m=c.getRow(1),v=[];for(let e=1;e<=p;e++){const t=m.getCell(e).value;v.push(String(null!=t?t:""))}const w=u(v,p),g=null!==(i=null==r?void 0:r.maxRows)&&void 0!==i?i:1e5,y=null!==(l=null==r?void 0:r.maxCells)&&void 0!==l?l:5e6,b=[];let $=0,S=0;for(let e=2;e<=c.rowCount;e++){if($++,$>g)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${g}). Use the maxRows option to increase the limit.`);if(S+=p,S>y)throw new Error(`Cell limit exceeded: processed ${S} cells (maximum: ${y}). Use the maxCells option to increase the limit.`);const t=c.getRow(e),r=[];for(let e=1;e<=p;e++)r.push(x(t.getCell(e)));b.push(r)}return{columns:w,rows:h(b,w,d)}}),y=(e,t,r)=>{switch(t){case"csv":return((e,t)=>w(e,void 0,t))(e,r);case"tsv":return((e,t)=>w(e,"\t",t))(e,r);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv`)}},b=(t,r,o)=>e(void 0,void 0,void 0,function*(){switch(r){case"xlsx":case"xls":case"ods":return((e,t)=>g(e,t))(t,o);default:throw new Error(`Unsupported binary format "${r}". Supported: xlsx, xls, ods`)}}),$=(o,n)=>e(void 0,void 0,void 0,function*(){if("undefined"!=typeof window&&"undefined"==typeof process)throw new Error("fromFile is only available in Node.js environments. In the browser, read the file using the File API and pass the result to fromCSV (for text) or fromXLSX (for binary formats).");const s=r.extname(o).toLowerCase(),u=(e=>l[e.toLowerCase()])(s);if(!u){const e=Object.keys(l).join(", ");throw new Error(`Unsupported file extension "${s||"(none)"}". Supported: ${e}`)}const a=yield t(o);return((t,r,o)=>e(void 0,void 0,void 0,function*(){switch(r){case"csv":case"tsv":if("string"!=typeof t)throw new TypeError(`${r.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return y(t,r,o);case"xlsx":case"xls":case"ods":if("string"==typeof t)throw new TypeError(`${r.toUpperCase()} parsing requires an ArrayBuffer input, but received a string.`);return b(t,r,o);default:throw new Error(`Unsupported format "${r}". Supported formats: csv, tsv, xlsx, xls, ods`)}}))(i.has(u)?"string"==typeof a?a:a.toString("utf-8"):a instanceof Buffer?a.buffer.slice(a.byteOffset,a.byteOffset+a.byteLength):a,u,n)});export{$ as fromFile};
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,44 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Supported file formats. */
6
+ type FileFormat = 'csv' | 'tsv' | 'xlsx' | 'xls' | 'ods';
7
+ /** Text-based formats that accept string input. */
8
+ type TextFileFormat = 'csv' | 'tsv';
9
+ /** Binary formats that accept ArrayBuffer input. */
10
+ type BinaryFileFormat = 'xlsx' | 'xls' | 'ods';
11
+ /** Shared base options for all parsers. */
12
+ interface BaseParseOptions {
13
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
14
+ locale?: VizLocale;
15
+ /** Maximum allowed input size in megabytes. @default 5 */
16
+ maxFileSize?: number;
17
+ }
18
+ /** Options for CSV / TSV parsing. */
19
+ interface DelimitedParseOptions extends BaseParseOptions {
20
+ /** Whether the first row contains column headers. @default true */
21
+ hasHeader?: boolean;
22
+ }
23
+ /** Options for XLSX / XLS / ODS parsing. */
24
+ interface SpreadsheetParseOptions extends BaseParseOptions {
25
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
26
+ sheet?: string | number;
27
+ /** Maximum number of data rows to process. @default 100_000 */
28
+ maxRows?: number;
29
+ /** Maximum total cells to process. @default 5_000_000 */
30
+ maxCells?: number;
31
+ }
32
+ /** Options specific to URL fetching. */
33
+ interface URLParseOptions extends SpreadsheetParseOptions {
34
+ /** Custom headers to include in the fetch request. */
35
+ headers?: Record<string, string>;
36
+ /** Whether the first row contains column headers. @default true */
37
+ hasHeader?: boolean;
38
+ /** Fetch timeout in milliseconds. @default 30_000 */
39
+ timeout?: number;
40
+ /** Optional external abort signal for cancellation. */
41
+ signal?: AbortSignal;
42
+ }
43
+
44
+ export type { BaseParseOptions, BinaryFileFormat, Data, DelimitedParseOptions, FileFormat, SpreadsheetParseOptions, TextFileFormat, URLParseOptions };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+
package/dist/ods.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=require("tslib"),t=require("exceljs"),r=require("@graphysdk/core/node");const o=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),c=(e,t="EN_US")=>{let r;if(r=o.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(u.has(t)){if(s.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},a=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},f=(o,n)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,l,i,s,u;const f=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(o.byteLength>f)throw new Error(`Input size (${o.byteLength} bytes) exceeds the maximum allowed size of ${f} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(o,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),r=[];for(let e=1;e<=p;e++)r.push(a(t.getCell(e)));y.push(r)}const k=((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:c(String(i),r)}return o}))(y,v,d);return{columns:v,rows:k}});exports.fromODS=(e,t)=>f(e,t);
package/dist/ods.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for XLSX / XLS / ODS parsing. */
13
+ interface SpreadsheetParseOptions extends BaseParseOptions {
14
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
15
+ sheet?: string | number;
16
+ /** Maximum number of data rows to process. @default 100_000 */
17
+ maxRows?: number;
18
+ /** Maximum total cells to process. @default 5_000_000 */
19
+ maxCells?: number;
20
+ }
21
+
22
+ /**
23
+ * Parses an ODS (OpenDocument Spreadsheet) file into the `Data` shape expected by `generateGraph()`.
24
+ *
25
+ * **Note:** Uses ExcelJS which natively supports XLSX format. ODS files that are
26
+ * saved in XLSX-compatible format will parse correctly. Native ODS format is not supported.
27
+ */
28
+ declare const fromODS: (input: ArrayBuffer, options?: SpreadsheetParseOptions) => Promise<Data>;
29
+
30
+ export { fromODS };
31
+ export type { BaseParseOptions, SpreadsheetParseOptions };
package/dist/ods.mjs ADDED
@@ -0,0 +1 @@
1
+ import{__awaiter as e}from"tslib";import t from"exceljs";import{columnIndexToPropertyKey as o}from"@graphysdk/core/node";const r=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),f=(e,t="EN_US")=>{let o;if(o=r.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(u.has(t)){if(s.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},c=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},a=(r,n)=>e(void 0,void 0,void 0,function*(){var e,l,i,s,u;const a=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(r.byteLength>a)throw new Error(`Input size (${r.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(r,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),o=[];for(let e=1;e<=p;e++)o.push(c(t.getCell(e)));y.push(o)}const k=((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:f(String(i),o)}return r}))(y,v,d);return{columns:v,rows:k}}),d=(e,t)=>a(e,t);export{d as fromODS};
package/dist/text.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";require("tslib");var e=require("papaparse"),r=require("@graphysdk/core/node");require("exceljs");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+)?$/,s=new Set(["PT_PT","AR"]),u=(e,r="EN_US")=>{let u;if(u=t.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===u)return null;if(u.length>100)return u;if(s.has(r)){if(i.test(u)){const e=u.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(o.test(u)){const e=u.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return u},d=(t,n,l)=>{var o,i,s,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 p=!1!==(null==l?void 0:l.hasHeader),m=null!==(s=null==l?void 0:l.locale)&&void 0!==s?s:"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=p?h[0]:void 0,w=p?h.slice(1):h,x=((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)),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:u(String(i),t)}return n}))(w,x,m);return{columns:x,rows:y}};exports.fromText=(e,r,t)=>{switch(r){case"csv":return((e,r)=>d(e,void 0,r))(e,t);case"tsv":return((e,r)=>d(e,"\t",r))(e,t);default:throw new Error(`Unsupported text format "${r}". Supported: csv, tsv`)}};
package/dist/text.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Text-based formats that accept string input. */
6
+ type TextFileFormat = 'csv' | 'tsv';
7
+ /** Shared base options for all parsers. */
8
+ interface BaseParseOptions {
9
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
10
+ locale?: VizLocale;
11
+ /** Maximum allowed input size in megabytes. @default 5 */
12
+ maxFileSize?: number;
13
+ }
14
+ /** Options for CSV / TSV parsing. */
15
+ interface DelimitedParseOptions extends BaseParseOptions {
16
+ /** Whether the first row contains column headers. @default true */
17
+ hasHeader?: boolean;
18
+ }
19
+
20
+ /**
21
+ * Parses a text string (CSV or TSV) into the `Data` shape expected by `generateGraph()`.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const data = fromText(csvContent, 'csv');
26
+ * const data = fromText(tsvContent, 'tsv', { hasHeader: false });
27
+ * ```
28
+ */
29
+ declare const fromText: (input: string, format: TextFileFormat, options?: DelimitedParseOptions) => Data;
30
+
31
+ export { fromText };
32
+ export type { BaseParseOptions, Data, DelimitedParseOptions, TextFileFormat };
package/dist/text.mjs ADDED
@@ -0,0 +1 @@
1
+ import"tslib";import e from"papaparse";import{columnIndexToPropertyKey as r}from"@graphysdk/core/node";import"exceljs";const t=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,o=/\u00A0/g,l=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,i=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,s=new Set(["PT_PT","AR"]),u=(e,r="EN_US")=>{let u;if(u=t.test(e)?e.replace(n,"-").replace(o," ").trim():e.trim(),""===u)return null;if(u.length>100)return u;if(s.has(r)){if(i.test(u)){const e=u.replace(/\./g,"").replace(",","."),r=Number(e);if(Number.isFinite(r))return r}}else if(l.test(u)){const e=u.replace(/,/g,""),r=Number(e);if(Number.isFinite(r))return r}return u},d=(t,n,o)=>{var l,i,s,d,a;const c=1024*(null!==(l=null==o?void 0:o.maxFileSize)&&void 0!==l?l: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==o?void 0:o.maxFileSize)&&void 0!==i?i:5} MB).`);const m=!1!==(null==o?void 0:o.hasHeader),p=null!==(s=null==o?void 0:o.locale)&&void 0!==s?s:"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,b=((e,t)=>{var n;const o=[];for(let l=0;l<t;l++){const t=null===(n=null==e?void 0:e[l])||void 0===n?void 0:n.trim(),i={key:r(l)};t&&(i.label=t),o.push(i)}return o})(g,h.reduce((e,r)=>Math.max(e,r.length),0)),x=((e,r,t)=>e.map(e=>{const n={};for(let o=0;o<r.length;o++){const l=r[o];if(!l)continue;const i=e[o];n[l.key]=null==i||""===i?null:"number"==typeof i?i:u(String(i),t)}return n}))(w,b,p);return{columns:b,rows:x}},a=(e,r,t)=>{switch(r){case"csv":return((e,r)=>d(e,void 0,r))(e,t);case"tsv":return((e,r)=>d(e,"\t",r))(e,t);default:throw new Error(`Unsupported text format "${r}". Supported: csv, tsv`)}};export{a as fromText};
package/dist/tsv.cjs ADDED
@@ -0,0 +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);
package/dist/tsv.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for CSV / TSV parsing. */
13
+ interface DelimitedParseOptions extends BaseParseOptions {
14
+ /** Whether the first row contains column headers. @default true */
15
+ hasHeader?: boolean;
16
+ }
17
+
18
+ /**
19
+ * Parses a TSV string into the `Data` shape expected by `generateGraph()`.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const data = fromTSV('Name\tRevenue\nAcme\t1000');
24
+ * sdk.generateGraph({ config: { data }, userPrompt: 'bar chart' });
25
+ * ```
26
+ */
27
+ declare const fromTSV: (input: string, options?: DelimitedParseOptions) => Data;
28
+
29
+ export { fromTSV };
30
+ export type { BaseParseOptions, DelimitedParseOptions };
package/dist/tsv.mjs ADDED
@@ -0,0 +1 @@
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};
package/dist/url.cjs ADDED
@@ -0,0 +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"]),s={".csv":"csv",".tsv":"tsv",".tab":"tsv",".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)},d=(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},c=/[^\p{ASCII}]/u,f=/[\u2012\u2013\u2014\u2212](?=\d)/g,h=/\u00A0/g,p=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,w=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,m=new Set(["PT_PT","AR"]),v=(e,t="EN_US")=>{let o;if(o=c.test(e)?e.replace(f,"-").replace(h," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(m.has(t)){if(w.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},x=(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}),y=(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 c=!1!==(null==r?void 0:r.hasHeader),f=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",h=t.parse(e,{header:!1,delimiter:o,skipEmptyLines:!0}),p=h.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 w=h.data;if(0===w.length)return{columns:[],rows:[]};const m=c?w[0]:void 0,v=c?w.slice(1):w,y=w.reduce((e,t)=>Math.max(e,t.length),0),g=d(m,y);return{columns:g,rows:x(v,g,f)}},g=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},b=(t,o)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,n,s,i,l;const a=1024*(null!==(e=null==o?void 0:o.maxFileSize)&&void 0!==e?e:5)*1024;if(t.byteLength>a)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(n=null==o?void 0:o.maxFileSize)&&void 0!==n?n:5} MB).`);const u=null!==(s=null==o?void 0:o.locale)&&void 0!==s?s:"EN_US",c=new r.Workbook;yield c.xlsx.load(t,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const f=((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})(c,null==o?void 0:o.sheet);if(!f||0===f.rowCount)return{columns:[],rows:[]};const h=f.columnCount;if(0===h)return{columns:[],rows:[]};const p=f.getRow(1),w=[];for(let e=1;e<=h;e++){const t=p.getCell(e).value;w.push(String(null!=t?t:""))}const m=d(w,h),v=null!==(i=null==o?void 0:o.maxRows)&&void 0!==i?i:1e5,y=null!==(l=null==o?void 0:o.maxCells)&&void 0!==l?l:5e6,b=[];let $=0,E=0;for(let e=2;e<=f.rowCount;e++){if($++,$>v)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${v}). Use the maxRows option to increase the limit.`);if(E+=h,E>y)throw new Error(`Cell limit exceeded: processed ${E} cells (maximum: ${y}). Use the maxCells option to increase the limit.`);const t=f.getRow(e),o=[];for(let e=1;e<=h;e++)o.push(g(t.getCell(e)));b.push(o)}return{columns:m,rows:x(b,m,u)}}),$=(e,t,o)=>{switch(t){case"csv":return((e,t)=>y(e,void 0,t))(e,o);case"tsv":return((e,t)=>y(e,"\t",t))(e,o);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv`)}},E=(t,o,r)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(o){case"xlsx":case"xls":case"ods":return((e,t)=>b(e,t))(t,r);default:throw new Error(`Unsupported binary format "${o}". Supported: xlsx, xls, ods`)}}),S={"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:d}=a,c=d.lastIndexOf("."),f=(e=>s[e.toLowerCase()])(-1===c?"":d.slice(c)),h=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([h,o.signal]):h};(null==o?void 0:o.headers)&&(p.headers=o.headers);const w=yield fetch(t,p);if(!w.ok)throw new Error(`Failed to fetch "${t}": ${w.status} ${w.statusText}`);const m=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?S[o]:void 0})(w.headers.get("content-type"));if(!m){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,x=w.headers.get("content-length");if(x&&Number(x)>v)throw new Error(`Response size (${x} bytes) exceeds the maximum allowed size of ${v} bytes (${null!==(l=null==o?void 0:o.maxFileSize)&&void 0!==l?l:5} MB).`);const y=n.has(m),g=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}))(w,v,y);return((t,o,r)=>e.__awaiter(void 0,void 0,void 0,function*(){switch(o){case"csv":case"tsv":if("string"!=typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return $(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 E(t,o,r);default:throw new Error(`Unsupported format "${o}". Supported formats: csv, tsv, xlsx, xls, ods`)}}))(g,m,o)});
package/dist/url.d.ts ADDED
@@ -0,0 +1,48 @@
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'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for XLSX / XLS / ODS parsing. */
13
+ interface SpreadsheetParseOptions extends BaseParseOptions {
14
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
15
+ sheet?: string | number;
16
+ /** Maximum number of data rows to process. @default 100_000 */
17
+ maxRows?: number;
18
+ /** Maximum total cells to process. @default 5_000_000 */
19
+ maxCells?: number;
20
+ }
21
+ /** Options specific to URL fetching. */
22
+ interface URLParseOptions extends SpreadsheetParseOptions {
23
+ /** Custom headers to include in the fetch request. */
24
+ headers?: Record<string, string>;
25
+ /** Whether the first row contains column headers. @default true */
26
+ hasHeader?: boolean;
27
+ /** Fetch timeout in milliseconds. @default 30_000 */
28
+ timeout?: number;
29
+ /** Optional external abort signal for cancellation. */
30
+ signal?: AbortSignal;
31
+ }
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.mjs ADDED
@@ -0,0 +1 @@
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"]),s={".csv":"csv",".tsv":"tsv",".tab":"tsv",".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$/],u=[/^::1$/,/^fc00:/i,/^fe80:/i],a=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=u.some(e=>e.test(o));if(r||n)throw new Error(`Access to private network address is not allowed: ${e}`)})(e.hostname)},d=(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},c=/[^\p{ASCII}]/u,f=/[\u2012\u2013\u2014\u2212](?=\d)/g,p=/\u00A0/g,h=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,m=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,w=new Set(["PT_PT","AR"]),v=(e,t="EN_US")=>{let o;if(o=c.test(e)?e.replace(f,"-").replace(p," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(w.has(t)){if(m.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(h.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},x=(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}),y=(e,o,r)=>{var n,s,i,l,u;const a=1024*(null!==(n=null==r?void 0:r.maxFileSize)&&void 0!==n?n:5)*1024;if(e.length>a)throw new Error(`Input size (${e.length} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(s=null==r?void 0:r.maxFileSize)&&void 0!==s?s:5} MB).`);const c=!1!==(null==r?void 0:r.hasHeader),f=null!==(i=null==r?void 0:r.locale)&&void 0!==i?i:"EN_US",p=t.parse(e,{header:!1,delimiter:o,skipEmptyLines:!0}),h=p.errors.filter(e=>"Quotes"===e.type);if(h.length>0){const e=h[0];throw new Error(`Parse error at row ${null!==(l=null==e?void 0:e.row)&&void 0!==l?l:"?"}: ${null!==(u=null==e?void 0:e.message)&&void 0!==u?u:"Unknown error"}`)}const m=p.data;if(0===m.length)return{columns:[],rows:[]};const w=c?m[0]:void 0,v=c?m.slice(1):m,y=m.reduce((e,t)=>Math.max(e,t.length),0),g=d(w,y);return{columns:g,rows:x(v,g,f)}},g=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},b=(t,o)=>e(void 0,void 0,void 0,function*(){var e,n,s,i,l;const u=1024*(null!==(e=null==o?void 0:o.maxFileSize)&&void 0!==e?e:5)*1024;if(t.byteLength>u)throw new Error(`Input size (${t.byteLength} bytes) exceeds the maximum allowed size of ${u} bytes (${null!==(n=null==o?void 0:o.maxFileSize)&&void 0!==n?n:5} MB).`);const a=null!==(s=null==o?void 0:o.locale)&&void 0!==s?s:"EN_US",c=new r.Workbook;yield c.xlsx.load(t,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const f=((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})(c,null==o?void 0:o.sheet);if(!f||0===f.rowCount)return{columns:[],rows:[]};const p=f.columnCount;if(0===p)return{columns:[],rows:[]};const h=f.getRow(1),m=[];for(let e=1;e<=p;e++){const t=h.getCell(e).value;m.push(String(null!=t?t:""))}const w=d(m,p),v=null!==(i=null==o?void 0:o.maxRows)&&void 0!==i?i:1e5,y=null!==(l=null==o?void 0:o.maxCells)&&void 0!==l?l:5e6,b=[];let $=0,E=0;for(let e=2;e<=f.rowCount;e++){if($++,$>v)throw new Error(`Row limit exceeded: processed ${$} rows (maximum: ${v}). Use the maxRows option to increase the limit.`);if(E+=p,E>y)throw new Error(`Cell limit exceeded: processed ${E} cells (maximum: ${y}). Use the maxCells option to increase the limit.`);const t=f.getRow(e),o=[];for(let e=1;e<=p;e++)o.push(g(t.getCell(e)));b.push(o)}return{columns:w,rows:x(b,w,a)}}),$=(e,t,o)=>{switch(t){case"csv":return((e,t)=>y(e,void 0,t))(e,o);case"tsv":return((e,t)=>y(e,"\t",t))(e,o);default:throw new Error(`Unsupported text format "${t}". Supported: csv, tsv`)}},E=(t,o,r)=>e(void 0,void 0,void 0,function*(){switch(o){case"xlsx":case"xls":case"ods":return((e,t)=>b(e,t))(t,r);default:throw new Error(`Unsupported binary format "${o}". Supported: xlsx, xls, ods`)}}),S={"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"},z=(t,o)=>e(void 0,void 0,void 0,function*(){var r,i,l;const u=new URL(t);a(u);const{pathname:d}=u,c=d.lastIndexOf("."),f=(e=>s[e.toLowerCase()])(-1===c?"":d.slice(c)),p=AbortSignal.timeout(null!==(r=null==o?void 0:o.timeout)&&void 0!==r?r:3e4),h={signal:(null==o?void 0:o.signal)?AbortSignal.any([p,o.signal]):p};(null==o?void 0:o.headers)&&(h.headers=o.headers);const m=yield fetch(t,h);if(!m.ok)throw new Error(`Failed to fetch "${t}": ${m.status} ${m.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?S[o]:void 0})(m.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,x=m.headers.get("content-length");if(x&&Number(x)>v)throw new Error(`Response size (${x} bytes) exceeds the maximum allowed size of ${v} bytes (${null!==(l=null==o?void 0:o.maxFileSize)&&void 0!==l?l:5} MB).`);const y=n.has(w),g=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 u=0;for(const e of s)l.set(e,u),u+=e.byteLength;return l.buffer}))(m,v,y);return((t,o,r)=>e(void 0,void 0,void 0,function*(){switch(o){case"csv":case"tsv":if("string"!=typeof t)throw new TypeError(`${o.toUpperCase()} parsing requires a string input, but received an ArrayBuffer.`);return $(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 E(t,o,r);default:throw new Error(`Unsupported format "${o}". Supported formats: csv, tsv, xlsx, xls, ods`)}}))(g,w,o)});export{z as fromURL};
package/dist/xls.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=require("tslib"),t=require("exceljs"),r=require("@graphysdk/core/node");const o=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),c=(e,t="EN_US")=>{let r;if(r=o.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(u.has(t)){if(s.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},a=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},f=(o,n)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,l,i,s,u;const f=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(o.byteLength>f)throw new Error(`Input size (${o.byteLength} bytes) exceeds the maximum allowed size of ${f} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(o,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),r=[];for(let e=1;e<=p;e++)r.push(a(t.getCell(e)));y.push(r)}const k=((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:c(String(i),r)}return o}))(y,v,d);return{columns:v,rows:k}});exports.fromXLS=(e,t)=>f(e,t);
package/dist/xls.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for XLSX / XLS / ODS parsing. */
13
+ interface SpreadsheetParseOptions extends BaseParseOptions {
14
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
15
+ sheet?: string | number;
16
+ /** Maximum number of data rows to process. @default 100_000 */
17
+ maxRows?: number;
18
+ /** Maximum total cells to process. @default 5_000_000 */
19
+ maxCells?: number;
20
+ }
21
+
22
+ /**
23
+ * Parses an XLS file into the `Data` shape expected by `generateGraph()`.
24
+ *
25
+ * **Note:** Uses ExcelJS which natively supports XLSX format. Modern `.xls` files
26
+ * (produced by Excel 2007+) that are actually XLSX will parse correctly.
27
+ * Genuine legacy binary XLS (BIFF) files are not supported.
28
+ */
29
+ declare const fromXLS: (input: ArrayBuffer, options?: SpreadsheetParseOptions) => Promise<Data>;
30
+
31
+ export { fromXLS };
32
+ export type { BaseParseOptions, SpreadsheetParseOptions };
package/dist/xls.mjs ADDED
@@ -0,0 +1 @@
1
+ import{__awaiter as e}from"tslib";import t from"exceljs";import{columnIndexToPropertyKey as o}from"@graphysdk/core/node";const r=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),f=(e,t="EN_US")=>{let o;if(o=r.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(u.has(t)){if(s.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},c=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},a=(r,n)=>e(void 0,void 0,void 0,function*(){var e,l,i,s,u;const a=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(r.byteLength>a)throw new Error(`Input size (${r.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(r,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),o=[];for(let e=1;e<=p;e++)o.push(c(t.getCell(e)));y.push(o)}const k=((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:f(String(i),o)}return r}))(y,v,d);return{columns:v,rows:k}}),d=(e,t)=>a(e,t);export{d as fromXLS};
package/dist/xlsx.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=require("tslib"),t=require("exceljs"),r=require("@graphysdk/core/node");const o=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),c=(e,t="EN_US")=>{let r;if(r=o.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===r)return null;if(r.length>100)return r;if(u.has(t)){if(s.test(r)){const e=r.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(r)){const e=r.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return r},a=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},f=(o,n)=>e.__awaiter(void 0,void 0,void 0,function*(){var e,l,i,s,u;const f=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(o.byteLength>f)throw new Error(`Input size (${o.byteLength} bytes) exceeds the maximum allowed size of ${f} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(o,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),r=[];for(let e=1;e<=p;e++)r.push(a(t.getCell(e)));y.push(r)}const k=((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:c(String(i),r)}return o}))(y,v,d);return{columns:v,rows:k}});exports.fromXLSX=(e,t)=>f(e,t);
package/dist/xlsx.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { VizLocale, GraphConfig } from '@graphysdk/core/node';
2
+
3
+ /** The `data` shape returned by all parsers — same as `GraphConfig['data']`. */
4
+ type Data = GraphConfig['data'];
5
+ /** Shared base options for all parsers. */
6
+ interface BaseParseOptions {
7
+ /** Locale for number parsing. Determines thousand/decimal separator conventions. @default 'EN_US' */
8
+ locale?: VizLocale;
9
+ /** Maximum allowed input size in megabytes. @default 5 */
10
+ maxFileSize?: number;
11
+ }
12
+ /** Options for XLSX / XLS / ODS parsing. */
13
+ interface SpreadsheetParseOptions extends BaseParseOptions {
14
+ /** Sheet to parse — name (string) or 0-based index (number). @default 0 (first sheet) */
15
+ sheet?: string | number;
16
+ /** Maximum number of data rows to process. @default 100_000 */
17
+ maxRows?: number;
18
+ /** Maximum total cells to process. @default 5_000_000 */
19
+ maxCells?: number;
20
+ }
21
+
22
+ /**
23
+ * Parses an XLSX file into the `Data` shape expected by `generateGraph()`.
24
+ */
25
+ declare const fromXLSX: (input: ArrayBuffer, options?: SpreadsheetParseOptions) => Promise<Data>;
26
+
27
+ export { fromXLSX };
28
+ export type { BaseParseOptions, SpreadsheetParseOptions };
package/dist/xlsx.mjs ADDED
@@ -0,0 +1 @@
1
+ import{__awaiter as e}from"tslib";import t from"exceljs";import{columnIndexToPropertyKey as o}from"@graphysdk/core/node";const r=/[^\p{ASCII}]/u,n=/[\u2012\u2013\u2014\u2212](?=\d)/g,l=/\u00A0/g,i=/^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/,s=/^-?(?:\d{1,3}(?:\.\d{3})*|\d+)(?:,\d+)?$/,u=new Set(["PT_PT","AR"]),f=(e,t="EN_US")=>{let o;if(o=r.test(e)?e.replace(n,"-").replace(l," ").trim():e.trim(),""===o)return null;if(o.length>100)return o;if(u.has(t)){if(s.test(o)){const e=o.replace(/\./g,"").replace(",","."),t=Number(e);if(Number.isFinite(t))return t}}else if(i.test(o)){const e=o.replace(/,/g,""),t=Number(e);if(Number.isFinite(t))return t}return o},c=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},a=(r,n)=>e(void 0,void 0,void 0,function*(){var e,l,i,s,u;const a=1024*(null!==(e=null==n?void 0:n.maxFileSize)&&void 0!==e?e:5)*1024;if(r.byteLength>a)throw new Error(`Input size (${r.byteLength} bytes) exceeds the maximum allowed size of ${a} bytes (${null!==(l=null==n?void 0:n.maxFileSize)&&void 0!==l?l:5} MB).`);const d=null!==(i=null==n?void 0:n.locale)&&void 0!==i?i:"EN_US",m=new t.Workbook;yield m.xlsx.load(r,{ignoreNodes:["dataValidations","conditionalFormatting","sheetProtection"]});const h=((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})(m,null==n?void 0:n.sheet);if(!h||0===h.rowCount)return{columns:[],rows:[]};const p=h.columnCount;if(0===p)return{columns:[],rows:[]};const w=h.getRow(1),g=[];for(let e=1;e<=p;e++){const t=w.getCell(e).value;g.push(String(null!=t?t:""))}const v=((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})(g,p),b=null!==(s=null==n?void 0:n.maxRows)&&void 0!==s?s:1e5,x=null!==(u=null==n?void 0:n.maxCells)&&void 0!==u?u:5e6,y=[];let S=0,$=0;for(let e=2;e<=h.rowCount;e++){if(S++,S>b)throw new Error(`Row limit exceeded: processed ${S} rows (maximum: ${b}). Use the maxRows option to increase the limit.`);if($+=p,$>x)throw new Error(`Cell limit exceeded: processed ${$} cells (maximum: ${x}). Use the maxCells option to increase the limit.`);const t=h.getRow(e),o=[];for(let e=1;e<=p;e++)o.push(c(t.getCell(e)));y.push(o)}const k=((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:f(String(i),o)}return r}))(y,v,d);return{columns:v,rows:k}}),d=(e,t)=>a(e,t);export{d as fromXLSX};
package/package.json ADDED
@@ -0,0 +1,128 @@
1
+ {
2
+ "name": "@graphysdk/data-import-utils",
3
+ "author": "Graphy",
4
+ "version": "1.1.0-alpha.0",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.cjs"
13
+ },
14
+ "./csv": {
15
+ "types": "./dist/csv.d.ts",
16
+ "import": "./dist/csv.mjs",
17
+ "require": "./dist/csv.cjs"
18
+ },
19
+ "./tsv": {
20
+ "types": "./dist/tsv.d.ts",
21
+ "import": "./dist/tsv.mjs",
22
+ "require": "./dist/tsv.cjs"
23
+ },
24
+ "./xlsx": {
25
+ "types": "./dist/xlsx.d.ts",
26
+ "import": "./dist/xlsx.mjs",
27
+ "require": "./dist/xlsx.cjs"
28
+ },
29
+ "./xls": {
30
+ "types": "./dist/xls.d.ts",
31
+ "import": "./dist/xls.mjs",
32
+ "require": "./dist/xls.cjs"
33
+ },
34
+ "./ods": {
35
+ "types": "./dist/ods.d.ts",
36
+ "import": "./dist/ods.mjs",
37
+ "require": "./dist/ods.cjs"
38
+ },
39
+ "./file": {
40
+ "types": "./dist/file.d.ts",
41
+ "import": "./dist/file.mjs",
42
+ "require": "./dist/file.cjs"
43
+ },
44
+ "./url": {
45
+ "types": "./dist/url.d.ts",
46
+ "import": "./dist/url.mjs",
47
+ "require": "./dist/url.cjs"
48
+ },
49
+ "./text": {
50
+ "types": "./dist/text.d.ts",
51
+ "import": "./dist/text.mjs",
52
+ "require": "./dist/text.cjs"
53
+ },
54
+ "./buffer": {
55
+ "types": "./dist/buffer.d.ts",
56
+ "import": "./dist/buffer.mjs",
57
+ "require": "./dist/buffer.cjs"
58
+ }
59
+ },
60
+ "typesVersions": {
61
+ "*": {
62
+ "csv": [
63
+ "dist/csv.d.ts"
64
+ ],
65
+ "tsv": [
66
+ "dist/tsv.d.ts"
67
+ ],
68
+ "xlsx": [
69
+ "dist/xlsx.d.ts"
70
+ ],
71
+ "xls": [
72
+ "dist/xls.d.ts"
73
+ ],
74
+ "ods": [
75
+ "dist/ods.d.ts"
76
+ ],
77
+ "file": [
78
+ "dist/file.d.ts"
79
+ ],
80
+ "url": [
81
+ "dist/url.d.ts"
82
+ ],
83
+ "text": [
84
+ "dist/text.d.ts"
85
+ ],
86
+ "buffer": [
87
+ "dist/buffer.d.ts"
88
+ ]
89
+ }
90
+ },
91
+ "dependencies": {
92
+ "exceljs": "^4.4.0",
93
+ "papaparse": "^5.5.2",
94
+ "@graphysdk/core": "1.1.0"
95
+ },
96
+ "devDependencies": {
97
+ "@rollup/plugin-commonjs": "^28.0.6",
98
+ "@rollup/plugin-node-resolve": "^16.0.1",
99
+ "@rollup/plugin-terser": "^0.4.4",
100
+ "@rollup/plugin-typescript": "^12.1.4",
101
+ "@types/papaparse": "^5.3.15",
102
+ "rollup": "^4.59.0",
103
+ "rollup-plugin-clear": "^2.0.7",
104
+ "rollup-plugin-copy": "^3.5.0",
105
+ "rollup-plugin-dts": "^6.2.3",
106
+ "rollup-plugin-node-externals": "^8.1.1",
107
+ "tslib": "^2.8.1",
108
+ "vitest": "^4.1.0",
109
+ "@graphytools/eslint-config": "0.0.1",
110
+ "@graphysdk/core": "1.1.0",
111
+ "@graphytools/vitest-config": "1.0.0",
112
+ "@graphytools/typescript-config": "0.0.1"
113
+ },
114
+ "files": [
115
+ "dist",
116
+ "README.md"
117
+ ],
118
+ "scripts": {
119
+ "build": "rollup -c --bundleConfigAsCjs",
120
+ "build:dev": "rollup -c --bundleConfigAsCjs --watch",
121
+ "test": "vitest run",
122
+ "test:watch": "TZ=utc vitest",
123
+ "lint": "eslint . --max-warnings 0",
124
+ "format": "prettier --write .",
125
+ "format:check": "prettier --check .",
126
+ "typecheck": "tsc --noEmit"
127
+ }
128
+ }