UNPKG

@sheetxl/io

Version:

IO - Import/Export Libraries for SheetXL.

232 lines (231 loc) 11.7 kB
/** * @license @sheetxl/io - IO - Import/Export Libraries for SheetXL. - v0.7.27 * * (C) 2025-present SheetXL Inc. & Michael T. Ford * License: The license can be found at https://www.sheetxl.com/license. */ import { BufferUtils as e } from "@sheetxl/utils"; import { TextUtils as t } from "@sheetxl/sdk"; import r from "path"; const o = [{ key: "SheetXL", description: "SheetXL", mimeType: ".sxl", exts: ["sxl", "json"], isDefault: true, handler: async (e2, t2) => (await import("./VUIjKANo4QVIKBlI.mjs")).readBufferSXL(e2, t2) }, { key: "CSV", description: "Comma Delimited", mimeType: "text/csv", exts: ["csv"], handler: async (e2, t2) => (await import("./CxZwQdVNPX28b1YR.mjs")).readBufferCSV(e2, t2) }, { key: "Excel", description: "Excel Workbook", mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", exts: ["xlsx", "xls", "xlsm"], handler: async (e2, t2) => (await import("./Bl-w2fv5_elyht4Z.mjs").then((e3) => e3.H)).readBufferXLSX(e2, t2) }], a = [{ key: "SheetXL", mimeType: "application/vnd.sheetxl.sheet", description: "SheetXL", exts: ["sxl", "json"], isDefault: true, async handler(e2, t2) { "json" === t2?.format && (t2 = { compress: false, ...t2 }); return (await import("./VUIjKANo4QVIKBlI.mjs")).writeBufferSXL(e2, t2); } }, { key: "CSV", mimeType: "text/csv", description: "Comma Delimited", exts: ["csv"], handler: async (e2, t2) => (await import("./CxZwQdVNPX28b1YR.mjs")).writeBufferCSV(e2, t2) }, { key: "Excel", mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", description: "Excel Workbook", exts: ["xlsx"], tags: ["SheetJS Pro"], handler: async (e2, t2) => (await import("./Bl-w2fv5_elyht4Z.mjs").then((e3) => e3.H)).writeBufferXLSX(e2, t2) }]; class s { constructor(e2 = o, t2 = a) { this._readFormats = [], this._writeFormats = [], this._readFormats = Object.freeze([...e2]), this._writeFormats = Object.freeze([...t2]); } async getReadFormats(e2) { return e2 ? this._filterFormats(e2, this._readFormats) : [...this._readFormats]; } async getWriteFormats(e2) { return this._writeFormats ? e2 ? this._filterFormats(e2, this._writeFormats) : [...this._writeFormats] : []; } async writeArrayBuffer(e2, t2) { const r2 = (await this.getWriteFormats({ search: t2?.format ?? "slx" }))[0]; return this._writeArrayBuffer(e2, r2, t2); } async read(r2) { if (!r2) throw new Error("'options' must be provided for read."); let o2 = r2.source; if (!o2) throw new Error("'options.source' must be provided for read."); let a2, s2 = r2.name, i2 = r2.format; !i2 && s2 && (a2 = t.getFileNameExtension(s2)), "function" == typeof o2 && (o2 = o2()), o2 && "object" == typeof o2 && "function" == typeof o2.then && (o2 = await Promise.resolve(o2)); const n2 = this._detectImportSourceType(o2); if (!n2) throw new Error("Unable to detect source type from provided input."); const f2 = this, c2 = async (e2, t2, o3) => { if (!e2 && !t2) throw new Error("Either format or file extension must be provided to determine read type."); const a3 = (await f2.getReadFormats({ search: e2, ext: t2 }))[0]; if (!a3) throw new Error(`No read format available for '${r2.format ?? t2}' input.`); delete (r2 = { ...r2, ...r2?.typedCreateWorkbookOptions?.[a3.key] }).typedCreateWorkbookOptions; const i3 = s2 ?? o3 ?? `read-${n2}`; r2.createWorkbookOptions = { ...r2.createWorkbookOptions || {}, name: i3 }, void 0 !== r2.readonly && (r2.createWorkbookOptions = { readonly: r2.readonly, ...r2.createWorkbookOptions }, delete r2.readonly); const c3 = r2?.progress?.onStart; return c3 && await Promise.resolve(c3({ format: a3, name: i3 })), a3; }, l = async (e2, t2, r3) => { const o3 = await Promise.resolve(e2), a3 = await this._readArrayBuffer(o3, t2, r3); return r3?.progress?.onComplete?.(), a3; }; switch (n2) { case "file": { const e2 = o2, a3 = e2?.name; let s3 = ""; a3 && (s3 = `${t.getBaseName(a3)}`); const n3 = await c2(i2, t.getFileNameExtension(a3), s3); return l(e2.arrayBuffer(), n3, r2); } case "blob": { const e2 = await c2(i2, a2); return l(o2.arrayBuffer(), e2, r2); } case "base64": { const t2 = await c2(i2, a2); let s3; if (o2 && "object" == typeof o2 && "base64" in o2) s3 = o2.base64; else if ("string" == typeof o2 && o2.startsWith("data:")) { const [, e2] = o2.split(","); s3 = e2; } else s3 = o2; return l(e.base64ToArrayBuffer(s3), t2, r2); } case "fetch": { let e2, s3, n3 = null; if ("string" == typeof o2) n3 = o2; else { if (!o2 || "object" != typeof o2 || !("input" in o2)) throw new Error("Invalid fetch source provided."); { const t2 = o2; n3 = t2.input, e2 = t2.init, s3 = t2.timeout; } } const f3 = s3 || 3e4, m = new AbortController(), d = setTimeout(() => m.abort(), f3), u = "string" == typeof n3 ? n3 : n3.toString(), p = a2 || t.getFileNameExtension(u), h = await c2(i2, p, t.getBaseName(u, true)); try { const t2 = await fetch(n3, { ...e2, signal: m.signal }); if (clearTimeout(d), !t2.ok) throw new Error(`Failed to fetch: ${t2.status} ${t2.statusText}`); const o3 = await t2.arrayBuffer(); if (!o3) throw new Error(`Unable to fetched content: ${u}`); return l(o3, h, r2); } catch (e3) { if (clearTimeout(d), "AbortError" === e3.name) throw new Error(`Fetch timeout after ${f3}ms: ${u}`); throw e3; } } case "buffer": return l(o2, await c2(i2, a2), r2); case "stream": { const e2 = await c2(i2, a2), t2 = o2.getReader(), s3 = []; let n3 = 0; try { for (; ; ) { const { done: e3, value: r3 } = await t2.read(); if (e3) break; s3.push(r3), n3 += r3.length; } } finally { t2.releaseLock(); } const f3 = new ArrayBuffer(n3), m = new Uint8Array(f3); let d = 0; for (const e3 of s3) m.set(e3, d), d += e3.length; return l(f3, e2, r2); } default: throw new Error(`Unsupported source type: ${n2}`); } } async writeFile(e2, r2, o2) { if (!e2) throw new Error("File name must be provided."); if (!r2) throw new Error("Workbook must be provided."); if (!r2.isIWorkbook) throw new Error("Invalid workbook model provided. Must be an instance of IWorkbook."); const a2 = t.getFileNameExtension(e2).toLowerCase(); a2 && (e2 = e2.slice(0, e2.length - a2.length - 1)); const s2 = (await this.getWriteFormats({ search: o2?.format, ext: a2 }))[0]; if (!s2) throw new Error(`Unable to determine write type for '${e2}'.`); const i2 = e2 + "." + (a2 || s2.exts[0]); let n2 = null; try { n2 = await this._writeArrayBuffer(r2, s2, o2); } catch (e3) { throw "string" == typeof e3 ? new Error(e3) : e3; } try { await (async (e3, t2) => { const r3 = await import( /* @vite-ignore */ /* webpackIgnore: true */ "fs/promises" ), o3 = Buffer.from(t2); await r3.writeFile(e3, o3); })(i2, n2); } catch (e3) { throw new Error("Unable to write file.", { cause: e3 }); } return o2?.progress?.onComplete?.(), true; } async registerReadFormat(e2) { this._registerFormatType(e2, this._readFormats); } async registerWriteFormat(e2) { this._registerFormatType(e2, this._writeFormats); } async _registerFormatType(e2, t2) { if (!e2) throw new Error("format must be provided."); } _detectImportSourceType(e2) { return e2 && "object" == typeof e2 && "base64" in e2 ? "base64" : e2 && "object" == typeof e2 && "input" in e2 ? "fetch" : "string" == typeof e2 ? e2.startsWith("data:") ? "base64" : (e2.startsWith("http://") || e2.startsWith("https://") || e2.startsWith("/") || e2.startsWith("./") || e2.startsWith("../"), "fetch") : "undefined" != typeof File && e2 instanceof File ? "file" : "undefined" != typeof Blob && e2 instanceof Blob ? "blob" : e2 instanceof ArrayBuffer || ArrayBuffer.isView(e2) ? "buffer" : "undefined" != typeof ReadableStream && e2 instanceof ReadableStream ? "stream" : null; } _filterFormats(e2, t2, r2) { if (!e2 || 0 === Object.keys(e2).length) { if (!r2) return [...t2]; e2 = { ext: r2 }; } const o2 = e2.search?.toLocaleLowerCase(); return t2.filter((t3) => { if (o2) { const e3 = t3.key.toLocaleLowerCase().includes(o2), r3 = !!t3.exts && t3.exts.some((e4) => e4.toLocaleLowerCase().includes(o2)), a3 = !!t3.mimeType && t3.mimeType.toLocaleLowerCase().includes(o2), s2 = !!t3.tags && t3.tags.some((e4) => e4.toLocaleLowerCase().includes(o2)), i2 = !!t3.description && t3.description.toLocaleLowerCase().includes(o2); if (!(e3 || r3 || a3 || s2 || i2)) return false; } const a2 = e2.ext || r2; if (a2) { const e3 = a2.toLocaleLowerCase(); if (!t3.exts.some((t4) => t4.toLocaleLowerCase() === e3)) return false; } if (e2.mimeType && t3.mimeType !== e2.mimeType) return false; if (e2.key && t3.key.toLocaleLowerCase() !== e2.key.toLocaleLowerCase()) return false; if (void 0 !== e2.isDefault && t3.isDefault !== e2.isDefault) return false; if (e2.tags) { const r3 = t3.tags || []; if (!("string" == typeof e2.tags ? [e2.tags] : e2.tags).every((e3) => r3.includes(e3))) return false; } return true; }); } async _writeArrayBuffer(e2, t2, r2) { if (!t2) throw new Error(`Invalid write type for '${t2}'.`); try { const o2 = t2.handler; if (!o2) throw new Error(`Unable to resolve handler for type: ${t2.description ?? t2}.`); return o2(e2, r2); } catch (e3) { throw new Error(`Unable to load handler for '${t2}.'`, { cause: e3 }); } } async _readArrayBuffer(e2, t2, r2 = null) { if (!e2) throw new Error("ArrayBuffer must be specified."); if (!t2) throw new Error("format must be specified."); const o2 = t2.handler; if (!o2) throw new Error(`Unable to resolve handler for format type: ${t2?.description ?? t2}.`); let a2; try { a2 = await o2(e2, r2); } catch (e3) { throw new Error("Unable to read", { cause: e3 }); } return a2; } } const i = new s(), n = /^(con|prn|aux|nul|com\d|lpt\d)$/i, f = /[<>:"/\\|?*\u0000-\u001F]/g, c = Object.freeze(Object.defineProperty({ __proto__: null, MAX_WORKBOOK_NAME_SIZE: 96, WINDOW_FILENAME_CHAR_RESERVED_REGEX: f, WINDOW_FILENAME_RESERVED_REGEX: n, isValidWindowsFilename: (e2) => !(!e2 || e2.length > 255) && (!f.test(e2) && !n.test(e2) && ("." !== e2 && ".." !== e2)), relativePath: (e2, t2) => { try { return new URL(t2), t2; } catch { } if (t2.startsWith("/") || /^[a-zA-Z]:/.test(t2)) return t2; if ("undefined" == typeof window || void 0 === window.document) { if ("undefined" != typeof require && "undefined" != typeof process) return r.resolve(e2, t2); throw new Error("Unsupported environment"); } try { let r2 = e2.startsWith("http") ? e2 : `file:///${e2.replace(/\\/g, "/")}`; r2.endsWith("/") || (r2 += "/"); return new URL(t2, r2).href; } catch { const r2 = document.createElement("a"); let o2 = e2; return o2.endsWith("/") || (o2 += "/"), r2.href = new URL(t2, o2).href, r2.href; } } }, Symbol.toStringTag, { value: "Module" })); export { s as DefaultWorkbookIO, c as IOUtils, i as WorkbookIO };