@sheetxl/io
Version:
IO - Import/Export Libraries for SheetXL.
373 lines (372 loc) • 17.8 kB
JavaScript
import { BufferUtils as F } from "@sheetxl/utils";
import { TextUtils as y } from "@sheetxl/sdk";
/**
* @license @sheetxl/io - IO - Import/Export Libraries for SheetXL. - v0.4.0
*
* (C) 2025-present SheetXL Inc. & Michael T. Ford
* License: The license can be found at https://www.sheetxl.com/license.
*/
const E = [{ key: "SheetXL", description: "SheetXL", mimeType: ".sxl", exts: ["sxl"], isDefault: !0, handler: async (c, t) => (await import("./DIpq16BY3N8OQgvw.mjs")).fromBufferJSON(c, t) }, { key: "CSV", description: "Comma Delimited", mimeType: "text/csv", exts: ["csv"], handler: async (c, t) => (await import("./DktNcqC4wKbZtyog.mjs")).fromBufferCSV(c, t) }, { key: "Excel", description: "Excel Workbook", mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", exts: ["xlsx", "xls", "xlsm"], handler: async (c, t) => (await import("./DhhW7aeMKjO6KolN.mjs").then((o) => o.i)).fromBufferXLSX(c, t) }], k = [{ key: "SheetXL", mimeType: "application/vnd.sheetxl.sheet", description: "SheetXL", ext: "sxl", isDefault: !0, handler: async (c, t) => (await import("./DIpq16BY3N8OQgvw.mjs")).toBufferJSON(c, t) }, { key: "CSV", mimeType: "text/csv", description: "Comma Delimited", ext: "csv", handler: async (c, t) => (await import("./DktNcqC4wKbZtyog.mjs")).toBufferCSV(c, t) }, { key: "Excel", mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", description: "Excel Workbook", ext: "xlsx", tags: ["SheetJS Pro"], handler: async (c, t) => (await import("./DhhW7aeMKjO6KolN.mjs").then((o) => o.i)).toBufferXLSX(c, t) }], x = async (c, t) => {
let o;
t instanceof SharedArrayBuffer ? (o = new ArrayBuffer(t.byteLength), new Uint8Array(o).set(new Uint8Array(t))) : o = t, function(e, r) {
const i = URL.createObjectURL(e), n = document.createElement("a");
n.style.display = "none", n.href = i, n.download = r, document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(i);
}(new Blob([o], { type: "application/octet-stream" }), c);
};
class A {
constructor(t = E, o = k) {
this._readFormatTypes = [], this._writeFormatType = [], this._readFormatTypes = Object.freeze([...t]), this._writeFormatType = Object.freeze([...o]);
}
_detectImportSourceType(t) {
return t && typeof t == "object" && "base64" in t ? "base64" : t && typeof t == "object" && "input" in t ? "fetch" : typeof t == "string" ? t.startsWith("data:") ? "base64" : (t.startsWith("http://") || t.startsWith("https://") || t.startsWith("/") || t.startsWith("./") || t.startsWith("../"), "fetch") : typeof File < "u" && t instanceof File ? "file" : t instanceof ArrayBuffer || ArrayBuffer.isView(t) ? "buffer" : typeof ReadableStream < "u" && t instanceof ReadableStream ? "stream" : null;
}
getReadFormats() {
return this._readFormatTypes;
}
getWriteFormats() {
return this._writeFormatType;
}
getReadFormatTypeForKey(t) {
return this._readFormatTypes.find((o) => o.key.includes(t)) ?? null;
}
getReadFormatTypeForExt(t) {
return t = t.toLowerCase(), this._readFormatTypes.find((o) => o.exts.includes(t)) ?? null;
}
getReadFormatTypeForMimeType(t) {
return this._readFormatTypes.find((o) => o.mimeType === t) ?? null;
}
getWriteFormatTypeForExt(t) {
return t = t.toLowerCase(), this._writeFormatType.find((o) => o.ext === t) ?? null;
}
getWriteFormatType(t) {
t = t.toLowerCase();
let o = this._writeFormatType.find((e) => e.ext === t) ?? null;
return o || (o = this._writeFormatType.find((e) => e.key.toLowerCase() === t) ?? null, o || (this._writeFormatType.find((e) => e.mimeType.toLowerCase() === t) ?? null));
}
getAllReadFormatTypeAsString() {
const t = [];
for (let o = 0; o < this._readFormatTypes.length; o++) t.push(this._readFormatTypes[o].mimeType);
return t;
}
async toArrayBuffer(t, o, e) {
const r = this.getWriteFormatType(o);
if (!r) throw new Error(`Invalid export type for '${o}'.`);
try {
const i = r.handler;
if (!i) throw new Error(`Unable to resolve handler for type: ${r.description ?? o}.`);
return i(t, e);
} catch (i) {
throw new Error(`Unable to load handler for '${o}.'`, { cause: i });
}
}
async _fromArrayBuffer(t, o, e = null) {
let r = this.getReadFormatTypeForKey(o) ?? this.getReadFormatTypeForExt(o) ?? this.getReadFormatTypeForMimeType(o);
if (!t || !r) {
if (!t) throw new Error("ArrayBuffer must be specified.");
if (!o) throw new Error("formatKey must be specified.");
}
const i = r.handler;
if (!i) throw new Error(`Unable to resolve handler for type: ${r?.description ?? o}.`);
const n = { ...e, ...e?.typedConstructorOptions?.[o] };
let s;
delete n.typedConstructorOptions;
try {
s = await i(t, n);
} catch (a) {
throw new Error("Unable to import", { cause: a });
}
return s;
}
async read(t) {
if (!t) throw new Error("'options' must be provided for load.");
let o = t.source;
if (!o) throw new Error("'options.source' must be provided for load.");
const e = t.name, r = t.formatType;
typeof o == "function" && (o = o()), o && typeof o == "object" && typeof o.then == "function" && (o = await Promise.resolve(o));
const i = this._detectImportSourceType(o);
if (!i) throw new Error("Unable to detect source type from provided input.");
switch (i) {
case "file": {
const n = o;
return await this._fromFile(n, t);
}
case "base64": {
let n;
if (o && typeof o == "object" && "base64" in o) n = o.base64;
else if (typeof o == "string" && o.startsWith("data:")) {
const [, f] = o.split(",");
n = f;
} else n = o;
const s = F.base64ToArrayBuffer(n), a = this.getReadFormatTypeForExt(r) || this._readFormatTypes[0];
if (!a) throw new Error("No import type available for base64 input.");
return { workbook: await this._fromArrayBuffer(s, a.key, t), title: e || "imported-file", formatType: a };
}
case "fetch": {
let n, s, a = null;
if (typeof o == "string") a = o;
else {
if (!o || typeof o != "object" || !("input" in o)) throw new Error("Invalid fetch source provided.");
{
const p = o;
a = p.input, n = p.init, s = p.timeout;
}
}
const f = s || 3e4, l = new AbortController(), u = setTimeout(() => l.abort(), f), h = typeof a == "string" ? a : a.toString(), d = r || y.getFileNameExtension(h), m = this.getReadFormatTypeForExt(d) || this._readFormatTypes[0];
try {
const p = await fetch(a, { ...n, signal: l.signal });
if (clearTimeout(u), !p.ok) throw new Error(`Failed to fetch: ${p.status} ${p.statusText}`);
const v = await p.arrayBuffer();
if (!m) throw new Error(`Unable to determine import type for fetched content: ${h}`);
return { workbook: await this._fromArrayBuffer(v, m.key, t), title: e || y.getBaseName(h, !0) || "fetched-file", formatType: m };
} catch (p) {
throw clearTimeout(u), p.name === "AbortError" ? new Error(`Fetch timeout after ${f}ms: ${h}`) : p;
}
}
case "buffer": {
const n = o, s = this.getReadFormatTypeForExt(r) || this._readFormatTypes[0];
if (!s) throw new Error("No import type available for buffer input.");
return { workbook: await this._fromArrayBuffer(n, s.key, t), title: e || "buffer-file", formatType: s };
}
case "stream": {
const n = o.getReader(), s = [];
let a = 0;
try {
for (; ; ) {
const { done: d, value: m } = await n.read();
if (d) break;
s.push(m), a += m.length;
}
} finally {
n.releaseLock();
}
const f = new ArrayBuffer(a), l = new Uint8Array(f);
let u = 0;
for (const d of s) l.set(d, u), u += d.length;
const h = this.getReadFormatTypeForExt(r) || this._readFormatTypes[0];
if (!h) throw new Error("No import type available for stream input.");
return { workbook: await this._fromArrayBuffer(f, h.key, t), title: e || "stream-file", formatType: h };
}
default:
throw new Error(`Unsupported source type: ${i}`);
}
}
async _fromFile(t, o = null) {
let e = null;
try {
let r = "";
t?.name && (r = `${y.getBaseName(t.name)}`);
const i = this.getReadFormatTypeForExt(y.getFileNameExtension(t?.name));
if (!i) throw new Error(`Unknown file type: ${y.getFileNameExtension(t?.name) ?? t?.name ?? "(empty)"}.`);
const n = await t.arrayBuffer(), s = { ...o, ...o?.typedConstructorOptions?.[i.key] };
delete s.typedConstructorOptions;
const a = i.handler;
if (!a) throw new Error(`Unable to resolve handler for type: ${i?.description ?? y.getFileNameExtension(t?.name) ?? t?.name ?? "(empty)"}.`);
await s.onStart?.(r);
const f = await a(n, s);
e = new _(t, f, r, i);
} catch (r) {
throw r;
}
return e;
}
async writeFile(t, o, e) {
if (!o || !t) throw new Error("Workbook model or file name must be provided.");
if (!o.isIWorkbook) throw new Error("Invalid workbook model provided. Must be an instance of IWorkbook.");
const r = y.getFileNameExtension(t);
r && (t = t.slice(0, t.length - r.length - 1));
let i = null;
e?.formatType && (i = this.getWriteFormatType(e.formatType));
const n = this.getWriteFormats(), s = n.length;
for (let l = 0; !i && l < s; l++) (n[l].ext === r || !r && n[l].isDefault) && (i = n[l]);
if (!i) throw new Error(`Unable to determine export type for '${t}'.`);
const a = t + "." + i.ext;
let f = null;
try {
f = await this.toArrayBuffer(o, i.key);
} catch (l) {
throw typeof l == "string" ? new Error(l) : l;
}
try {
await x(a, f);
} catch (l) {
throw new Error("Unable to write file.", { cause: l });
}
return !0;
}
}
class _ {
constructor(t, o, e, r) {
this.file = t, this.workbook = o, this.title = e, this.formatType = r;
}
get [Symbol.toStringTag]() {
return "[WorkbookHandle]";
}
toString() {
return `'${this.file.name}' ${this.file.size} (${this.formatType.description})`;
}
}
const W = new A();
var w, g, C = function() {
if (g) return w;
function c(e) {
if (typeof e != "string") throw new TypeError("Path must be a string. Received " + JSON.stringify(e));
}
function t(e, r) {
for (var i, n = "", s = 0, a = -1, f = 0, l = 0; l <= e.length; ++l) {
if (l < e.length) i = e.charCodeAt(l);
else {
if (i === 47) break;
i = 47;
}
if (i === 47) {
if (!(a === l - 1 || f === 1)) if (a !== l - 1 && f === 2) {
if (n.length < 2 || s !== 2 || n.charCodeAt(n.length - 1) !== 46 || n.charCodeAt(n.length - 2) !== 46) {
if (n.length > 2) {
var u = n.lastIndexOf("/");
if (u !== n.length - 1) {
u === -1 ? (n = "", s = 0) : s = (n = n.slice(0, u)).length - 1 - n.lastIndexOf("/"), a = l, f = 0;
continue;
}
} else if (n.length === 2 || n.length === 1) {
n = "", s = 0, a = l, f = 0;
continue;
}
}
r && (n.length > 0 ? n += "/.." : n = "..", s = 2);
} else n.length > 0 ? n += "/" + e.slice(a + 1, l) : n = e.slice(a + 1, l), s = l - a - 1;
a = l, f = 0;
} else i === 46 && f !== -1 ? ++f : f = -1;
}
return n;
}
g = 1;
var o = { resolve: function() {
for (var e, r = "", i = !1, n = arguments.length - 1; n >= -1 && !i; n--) {
var s;
n >= 0 ? s = arguments[n] : (e === void 0 && (e = process.cwd()), s = e), c(s), s.length !== 0 && (r = s + "/" + r, i = s.charCodeAt(0) === 47);
}
return r = t(r, !i), i ? r.length > 0 ? "/" + r : "/" : r.length > 0 ? r : ".";
}, normalize: function(e) {
if (c(e), e.length === 0) return ".";
var r = e.charCodeAt(0) === 47, i = e.charCodeAt(e.length - 1) === 47;
return (e = t(e, !r)).length !== 0 || r || (e = "."), e.length > 0 && i && (e += "/"), r ? "/" + e : e;
}, isAbsolute: function(e) {
return c(e), e.length > 0 && e.charCodeAt(0) === 47;
}, join: function() {
if (arguments.length === 0) return ".";
for (var e, r = 0; r < arguments.length; ++r) {
var i = arguments[r];
c(i), i.length > 0 && (e === void 0 ? e = i : e += "/" + i);
}
return e === void 0 ? "." : o.normalize(e);
}, relative: function(e, r) {
if (c(e), c(r), e === r || (e = o.resolve(e)) === (r = o.resolve(r))) return "";
for (var i = 1; i < e.length && e.charCodeAt(i) === 47; ++i) ;
for (var n = e.length, s = n - i, a = 1; a < r.length && r.charCodeAt(a) === 47; ++a) ;
for (var f = r.length - a, l = s < f ? s : f, u = -1, h = 0; h <= l; ++h) {
if (h === l) {
if (f > l) {
if (r.charCodeAt(a + h) === 47) return r.slice(a + h + 1);
if (h === 0) return r.slice(a + h);
} else s > l && (e.charCodeAt(i + h) === 47 ? u = h : h === 0 && (u = 0));
break;
}
var d = e.charCodeAt(i + h);
if (d !== r.charCodeAt(a + h)) break;
d === 47 && (u = h);
}
var m = "";
for (h = i + u + 1; h <= n; ++h) h !== n && e.charCodeAt(h) !== 47 || (m.length === 0 ? m += ".." : m += "/..");
return m.length > 0 ? m + r.slice(a + u) : (a += u, r.charCodeAt(a) === 47 && ++a, r.slice(a));
}, _makeLong: function(e) {
return e;
}, dirname: function(e) {
if (c(e), e.length === 0) return ".";
for (var r = e.charCodeAt(0), i = r === 47, n = -1, s = !0, a = e.length - 1; a >= 1; --a) if ((r = e.charCodeAt(a)) === 47) {
if (!s) {
n = a;
break;
}
} else s = !1;
return n === -1 ? i ? "/" : "." : i && n === 1 ? "//" : e.slice(0, n);
}, basename: function(e, r) {
if (r !== void 0 && typeof r != "string") throw new TypeError('"ext" argument must be a string');
c(e);
var i, n = 0, s = -1, a = !0;
if (r !== void 0 && r.length > 0 && r.length <= e.length) {
if (r.length === e.length && r === e) return "";
var f = r.length - 1, l = -1;
for (i = e.length - 1; i >= 0; --i) {
var u = e.charCodeAt(i);
if (u === 47) {
if (!a) {
n = i + 1;
break;
}
} else l === -1 && (a = !1, l = i + 1), f >= 0 && (u === r.charCodeAt(f) ? --f === -1 && (s = i) : (f = -1, s = l));
}
return n === s ? s = l : s === -1 && (s = e.length), e.slice(n, s);
}
for (i = e.length - 1; i >= 0; --i) if (e.charCodeAt(i) === 47) {
if (!a) {
n = i + 1;
break;
}
} else s === -1 && (a = !1, s = i + 1);
return s === -1 ? "" : e.slice(n, s);
}, extname: function(e) {
c(e);
for (var r = -1, i = 0, n = -1, s = !0, a = 0, f = e.length - 1; f >= 0; --f) {
var l = e.charCodeAt(f);
if (l !== 47) n === -1 && (s = !1, n = f + 1), l === 46 ? r === -1 ? r = f : a !== 1 && (a = 1) : r !== -1 && (a = -1);
else if (!s) {
i = f + 1;
break;
}
}
return r === -1 || n === -1 || a === 0 || a === 1 && r === n - 1 && r === i + 1 ? "" : e.slice(r, n);
}, format: function(e) {
if (e === null || typeof e != "object") throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof e);
return function(r, i) {
var n = i.dir || i.root, s = i.base || (i.name || "") + (i.ext || "");
return n ? n === i.root ? n + s : n + r + s : s;
}("/", e);
}, parse: function(e) {
c(e);
var r = { root: "", dir: "", base: "", ext: "", name: "" };
if (e.length === 0) return r;
var i, n = e.charCodeAt(0), s = n === 47;
s ? (r.root = "/", i = 1) : i = 0;
for (var a = -1, f = 0, l = -1, u = !0, h = e.length - 1, d = 0; h >= i; --h) if ((n = e.charCodeAt(h)) !== 47) l === -1 && (u = !1, l = h + 1), n === 46 ? a === -1 ? a = h : d !== 1 && (d = 1) : a !== -1 && (d = -1);
else if (!u) {
f = h + 1;
break;
}
return a === -1 || l === -1 || d === 0 || d === 1 && a === l - 1 && a === f + 1 ? l !== -1 && (r.base = r.name = f === 0 && s ? e.slice(1, l) : e.slice(f, l)) : (f === 0 && s ? (r.name = e.slice(1, a), r.base = e.slice(1, l)) : (r.name = e.slice(f, a), r.base = e.slice(f, l)), r.ext = e.slice(a, l)), f > 0 ? r.dir = e.slice(0, f - 1) : s && (r.dir = "/"), r;
}, sep: "/", delimiter: ":", win32: null, posix: null };
return o.posix = o, w = o;
}();
const b = /^(con|prn|aux|nul|com\d|lpt\d)$/i, T = /[<>:"/\\|?*\u0000-\u001F]/g, B = Object.freeze(Object.defineProperty({ __proto__: null, MAX_WORKBOOK_NAME_SIZE: 96, WINDOW_FILENAME_CHAR_RESERVED_REGEX: T, WINDOW_FILENAME_RESERVED_REGEX: b, isValidWindowsFilename: (c) => !(!c || c.length > 255) && !T.test(c) && !b.test(c) && c !== "." && c !== "..", relativePath: (c, t) => {
try {
return new URL(t), t;
} catch {
}
if (t.startsWith("/") || /^[a-zA-Z]:/.test(t)) return t;
if (typeof window > "u" || window.document === void 0) {
if (typeof require < "u" && typeof process < "u") return C.Path.resolve(c, t);
throw new Error("Unsupported environment");
}
try {
let o = c.startsWith("http") ? c : `file:///${c.replace(/\\/g, "/")}`;
return o.endsWith("/") || (o += "/"), new URL(t, o).href;
} catch {
const o = document.createElement("a");
let e = c;
return e.endsWith("/") || (e += "/"), o.href = new URL(t, e).href, o.href;
}
} }, Symbol.toStringTag, { value: "Module" }));
export {
A as DefaultWorkbookIO,
B as IOUtils,
W as WorkbookIO
};