@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.
- package/LICENSE.md +17 -0
- package/README.md +11 -15
- package/dist/buffer.cjs +1 -1
- package/dist/buffer.mjs +4 -1
- package/dist/constants-BSk6SyUk.cjs +1 -0
- package/dist/constants-PA0Uh9bi.js +5 -0
- package/dist/csv.cjs +1 -1
- package/dist/csv.mjs +4 -1
- package/dist/file.cjs +1 -1
- package/dist/file.mjs +17 -1
- package/dist/format-detection-1kqWtVpP.cjs +1 -0
- package/dist/format-detection-MwlOpP6Y.js +18 -0
- package/dist/from-csv-Ccr_5k9u.cjs +1 -0
- package/dist/from-csv-CrQ_H-s5.js +5 -0
- package/dist/from-csv.d.ts +13 -0
- package/dist/from-json-DC712HdK.js +48 -0
- package/dist/from-json-lzRNXlod.cjs +1 -0
- package/dist/{json.d.ts → from-json.d.ts} +4 -18
- package/dist/from-spreadsheet-D2kWRyr3.js +79 -0
- package/dist/from-spreadsheet-EfBhqj2z.cjs +1 -0
- package/dist/from-spreadsheet.d.ts +20 -0
- package/dist/from-tsv-B02B59Ey.cjs +1 -0
- package/dist/from-tsv-CPj6UzXC.js +5 -0
- package/dist/from-tsv.d.ts +11 -0
- package/dist/index-buffer.d.ts +2 -0
- package/dist/index-csv.d.ts +2 -0
- package/dist/index-file.d.ts +2 -0
- package/dist/index-json.d.ts +3 -0
- package/dist/index-ods.d.ts +2 -0
- package/dist/index-text.d.ts +2 -0
- package/dist/index-tsv.d.ts +2 -0
- package/dist/index-url.d.ts +2 -0
- package/dist/index-xls.d.ts +2 -0
- package/dist/index-xlsx.d.ts +8 -0
- package/dist/index.cjs +0 -1
- package/dist/index.d.ts +8 -44
- package/dist/index.mjs +0 -1
- package/dist/json.cjs +1 -1
- package/dist/json.mjs +4 -1
- package/dist/map-rows-1hzHO_rN.cjs +1 -0
- package/dist/map-rows-GOmUltJ3.js +35 -0
- package/dist/ods.cjs +1 -1
- package/dist/ods.mjs +4 -1
- package/dist/parse-delimited-BSoFIVFq.cjs +1 -0
- package/dist/parse-delimited-qsjX5KAa.js +28 -0
- package/dist/parse-delimited.d.ts +7 -0
- package/dist/parse-file.d.ts +12 -0
- package/dist/parse-string-DpdSP3xh.cjs +1 -0
- package/dist/parse-string-VVlSsL2Y.js +47 -0
- package/dist/parse-string.d.ts +29 -0
- package/dist/parse-url.d.ts +14 -0
- package/dist/spreadsheet/cell-primitive.d.ts +7 -0
- package/dist/spreadsheet/load-workbook.d.ts +3 -0
- package/dist/spreadsheet/read-region.d.ts +39 -0
- package/dist/spreadsheet/workbook-index.d.ts +50 -0
- package/dist/text.cjs +1 -1
- package/dist/text.mjs +4 -1
- package/dist/tsv.cjs +1 -1
- package/dist/tsv.mjs +4 -1
- package/dist/{url.d.ts → types.d.ts} +18 -24
- package/dist/url.cjs +1 -1
- package/dist/url.mjs +87 -1
- package/dist/utils/build-columns.d.ts +10 -0
- package/dist/utils/column-index-to-property-key.d.ts +2 -0
- package/dist/utils/constants.d.ts +6 -0
- package/dist/utils/format-detection.d.ts +4 -0
- package/dist/utils/map-rows.d.ts +13 -0
- package/dist/utils/normalize-value.d.ts +12 -0
- package/dist/utils/url-validation.d.ts +2 -0
- package/dist/wire-data.types.d.ts +13 -0
- package/dist/xls.cjs +1 -1
- package/dist/xls.mjs +4 -1
- package/dist/xlsx.cjs +1 -1
- package/dist/xlsx.mjs +172 -1
- package/package.json +52 -38
- package/dist/README.md +0 -78
- package/dist/buffer.d.ts +0 -36
- package/dist/csv.d.ts +0 -32
- package/dist/file.d.ts +0 -42
- package/dist/ods.d.ts +0 -31
- package/dist/text.d.ts +0 -32
- package/dist/tsv.d.ts +0 -30
- package/dist/xls.d.ts +0 -32
- 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
|
-
|
|
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{
|
|
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,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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
1
|
+
import { t as r } from "./from-tsv-CPj6UzXC.js";
|
|
2
|
+
export {
|
|
3
|
+
r as fromTSV
|
|
4
|
+
};
|
|
@@ -1,16 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
type
|
|
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
|
-
|
|
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
|
|
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,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;
|