// Builds the installable plugin (plugin-architecture.md §Package format): // bundles src/plugin.ts (SDK + i18n inlined — the sandbox CSP forbids runtime // fetches) into plugin.js as a single ES module, then packs the ZIP for the // admin upload / dropzone watcher. import { mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { build } from 'esbuild'; import { zipSync } from 'fflate'; import { thirdPartyNotices } from '../third-party-licenses.mjs'; const root = dirname(fileURLToPath(import.meta.url)); const manifest = JSON.parse(readFileSync(join(root, 'manifest.json'), 'utf8')); mkdirSync(join(root, 'dist'), { recursive: true }); const buildResult = await build({ entryPoints: [join(root, 'src/plugin.ts')], bundle: true, format: 'esm', outfile: join(root, 'dist/plugin.js'), minify: true, metafile: true, }); const files = { 'manifest.json': readFileSync(join(root, 'manifest.json')), 'plugin.js': readFileSync(join(root, 'dist/plugin.js')), // mermaid and its transitive dependencies are bundled into plugin.js; their // license texts ship with the package they belong to (issue #345). 'licenses/THIRD-PARTY-NOTICES.txt': Buffer.from(thirdPartyNotices(buildResult.metafile)), }; for (const name of readdirSync(join(root, 'i18n'))) { files[`i18n/${name}`] = readFileSync(join(root, 'i18n', name)); } const target = join(root, 'dist', `${manifest.id}-${manifest.version}.zip`); writeFileSync(target, zipSync(files)); console.log(`wrote ${target}`);