// Bundles the add-on's npm dependencies into // bundled-addons/docx-editor/vendor/docx-vendor.js. // // npm run build (from addon-build/docx-editor/) // // mammoth is patched on the way through — see patches.mjs for why. The // patched copy is materialised under .patched/ so the node round-trip tests // exercise exactly the same reader the browser does. import * as esbuild from "esbuild"; import { mkdirSync, writeFileSync, readFileSync, statSync, rmSync, cpSync } from "node:fs"; import { fileURLToPath } from "node:url"; import path from "node:path"; import { applyPatches, patches } from "./patches.mjs"; const here = path.dirname(fileURLToPath(import.meta.url)); const out = path.resolve(here, "../../bundled-addons/docx-editor/vendor"); const patchedRoot = path.join(here, ".patched"); // --- 1. patched mammoth --------------------------------------------------- rmSync(patchedRoot, { recursive: true, force: true }); mkdirSync(patchedRoot, { recursive: true }); cpSync(path.join(here, "node_modules", "mammoth"), path.join(patchedRoot, "mammoth"), { recursive: true }); const touched = new Set(); for (const p of patches) { const f = path.join(patchedRoot, "mammoth", p.file); if (touched.has(f)) continue; touched.add(f); } for (const f of touched) { const rel = "mammoth/" + path.relative(path.join(patchedRoot, "mammoth"), f).split(path.sep).join("/"); const { code, hits } = applyPatches(rel, readFileSync(f, "utf8")); writeFileSync(f, code); console.log(`patched ${rel} (${hits} hunks)`); } // --- 2. bundle ------------------------------------------------------------ mkdirSync(out, { recursive: true }); const res = await esbuild.build({ entryPoints: [path.join(here, "vendor-entry.js")], bundle: true, minify: true, format: "iife", platform: "browser", target: ["chrome120"], legalComments: "none", outfile: path.join(out, "docx-vendor.js"), define: { "process.env.NODE_ENV": '"production"' }, alias: { mammoth: path.join(patchedRoot, "mammoth") }, logLevel: "info", }); if (res.errors.length) process.exit(1); // --- 3. licences ---------------------------------------------------------- // Vendored code without its licence text is the kind of thing that bites // later; this file ships next to the bundle. const pkgs = ["mammoth", "docx", "jszip", "underscore", "orderedmap", "w3c-keyname", "rope-sequence", "prosemirror-state", "prosemirror-view", "prosemirror-model", "prosemirror-schema-basic", "prosemirror-schema-list", "prosemirror-tables", "prosemirror-history", "prosemirror-commands", "prosemirror-keymap", "prosemirror-inputrules", "prosemirror-dropcursor", "prosemirror-gapcursor", "prosemirror-transform"]; let notice = "Third-party code bundled into vendor/docx-vendor.js\n" + "===================================================\n\n" + "mammoth is shipped with small local patches (colour, paragraph spacing,\n" + "numbering format); see addon-build/docx-editor/patches.mjs.\n\n"; for (const p of pkgs) { let j; try { j = JSON.parse(readFileSync(path.join(here, "node_modules", p, "package.json"), "utf8")); } catch { continue; } let text = ""; for (const f of ["LICENSE", "LICENSE.md", "LICENSE.txt", "LICENCE", "license", "LICENSE-MIT"]) { try { text = readFileSync(path.join(here, "node_modules", p, f), "utf8").trim(); break; } catch {} } notice += `--- ${p} ${j.version} — ${j.license || "see project"} ---\n` + (text || `(no licence file in the package; see ${j.homepage || j.repository?.url || "the project homepage"})`) + "\n\n"; } writeFileSync(path.join(out, "LICENSES.txt"), notice); console.log(`vendor bundle: ${(statSync(path.join(out, "docx-vendor.js")).size / 1024).toFixed(0)} KB`);