mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 16:59:43 +02:00
xlsx files were download-only. Add a read-only, virtualized preview (sheet tabs, number formats, merges, theme colours) parsed entirely in a browser Web Worker with exceljs and fflate, loaded only when a spreadsheet is opened. The workbook is checked against ZIP-bomb, entry and cell limits before exceljs loads; cell text is written with textContent, formulas are never evaluated and nothing referenced by the workbook is fetched. On the server xlsx only joins the existing allowlist and classification, with a 10 MB cap on ?preview=true. xls and ods stay download-only.
32 lines
1.5 KiB
JavaScript
32 lines
1.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Copy the XLSX preview's browser bundles (exceljs, fflate) into a public vendor
|
|
* dir. Run by postinstall for dev (src/web/public/vendor, gitignored) and by
|
|
* build.mjs for prod (dist/web/public/vendor). Both packages are pinned exactly
|
|
* in package.json, and check-public-assets.mjs hashes the output into
|
|
* SPREADSHEET_ASSET_VERSION (the worker's cache-bust token), so a version bump
|
|
* that changes the bytes fails that check until the token is refreshed.
|
|
* Source-map comments are stripped: the maps are not shipped.
|
|
*/
|
|
|
|
import { createRequire } from 'node:module';
|
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import { dirname, join, resolve } from 'node:path';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const outputDir = resolve(process.argv[2] || join(import.meta.dirname, '..', 'src', 'web', 'public', 'vendor'));
|
|
const excelSource = require.resolve('exceljs/dist/exceljs.min.js');
|
|
const fflateSource = join(dirname(require.resolve('fflate')), '..', 'umd', 'index.js');
|
|
|
|
function copyBrowserBundle(source, outputName) {
|
|
const content = readFileSync(source, 'utf8').replace(/\n?\/\/# sourceMappingURL=.*(?:\n|$)/g, '\n');
|
|
if (/sourceMappingURL/.test(content)) {
|
|
throw new Error(`Failed to strip sourceMappingURL from ${outputName}`);
|
|
}
|
|
writeFileSync(join(outputDir, outputName), content, 'utf8');
|
|
}
|
|
|
|
mkdirSync(outputDir, { recursive: true });
|
|
copyBrowserBundle(excelSource, 'exceljs.min.js');
|
|
copyBrowserBundle(fflateSource, 'fflate.min.js');
|