/** * Builds the mdb-reader bundle the Access Viewer (/access-viewer) loads from * /vendor/local/mdb-reader@3.2.0-jm1/mdb-reader.mjs. * * Why a local build rather than vendor.json: mdb-reader's browser build does * its AES and hashing with browserify-aes and create-hash, which carry their * own Buffer polyfill (safe-buffer over buffer 5). Mixed with the Buffer * mdb-reader is handed, decryption returned pages that were too short, so a * password-protected .accdb never opened in a browser ("offset is not uint"). * Here mdb-reader's environment module is swapped for environment.js, which * uses @noble/ciphers and @noble/hashes (MIT, synchronous, no Node streams), * and one Buffer (buffer 6) is bundled in and exported for the caller to use. * mdb-reader's own code is not changed. * * Versions are pinned by package-lock.json (integrity hashes). Run: * cd frontend/vendor-src/mdb-reader && npm ci --ignore-scripts && node build.mjs * then: node scripts/vendor-local-lock.mjs (from frontend/), since the output * folder is immutable once shipped; a changed build needs a new -jmN folder. */ import { build } from '../../node_modules/esbuild/lib/main.js'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const here = path.dirname(fileURLToPath(import.meta.url)); const version = JSON.parse(fs.readFileSync(path.join(here, 'node_modules/mdb-reader/package.json'), 'utf8')).version; if (version !== '3.2.0') throw new Error(`expected mdb-reader 3.2.0, found ${version}: check environment.js and the output folder together`); const out = path.join(here, '../../vendor/local/mdb-reader@3.2.0-jm1/mdb-reader.mjs'); const environment = path.join(here, 'environment.js'); const shims = path.join(here, 'node_modules/.shims.js'); // Buffer as a global, which mdb-reader uses without importing it. fs.writeFileSync(shims, "import { Buffer } from 'buffer';\nexport { Buffer };\n"); const entry = path.join(here, 'node_modules/.entry.js'); fs.writeFileSync(entry, "export { default } from 'mdb-reader';\nexport { Buffer } from 'buffer';\n"); await build({ entryPoints: [entry], absWorkingDir: here, bundle: true, format: 'esm', platform: 'browser', minify: true, inject: [shims], define: { global: 'globalThis' }, legalComments: 'eof', outfile: out, logLevel: 'warning', plugins: [ { name: 'environment', setup(b) { b.onResolve({ filter: /environment\/index\.js$/ }, () => ({ path: environment })); }, }, ], }); console.log(`wrote ${path.relative(process.cwd(), out)} (${fs.statSync(out).size} bytes)`);