import { writeFile } from 'node:fs/promises' import path from 'node:path' import esbuild from 'esbuild' /** * The in-WebView rich Markdown editor document, bundled from its modules. * * The document is a string the native WebView loads inside its HTML, so it cannot be an ES module * there — and it is ordinary TypeScript everywhere else, which a page imports directly. So this is * one esbuild bundle of the entry that calls `createRichMarkdownEditorDocument()` with no host, * written out as a string, exactly as the terminal's document beside it is. * * `iife`, so the bundle's module scope is its own and nothing it declares reaches the page it is * pasted into. Not minified: the document is read in the WebView's own console, and it is a few * tens of kilobytes rather than an engine. */ const mobileRoot = path.join(import.meta.dirname, '..') /** The oldest WebView Orca supports, matching the terminal document's own floor (#7030). */ const TARGET = 'chrome74' const ENTRY = path.join( mobileRoot, 'src', 'components', 'rich-markdown', 'native-document-entry.ts' ) export const RICH_MARKDOWN_EDITOR_SCRIPT_PATH = path.join( mobileRoot, 'src', 'components', 'rich-markdown-editor-document-script.generated.ts' ) const GENERATED_HEADER = `// Generated by scripts/build-rich-markdown-editor-script.mjs. Do not edit.\n` + `// The source is mobile/src/components/rich-markdown/, bundled from native-document-entry.ts.\n` + `// Target: ${TARGET}. Regenerate via pnpm postinstall.` /** * One options object, so a census of what the bundle contains measures the bundle that ships. * * `absWorkingDir` is load-bearing: esbuild writes each module's path into the bundle as a comment, * relative to the working directory, so without it the artifact's bytes depend on where the * generator was run from — three cwds gave three digests, and from outside the repo the comments * carry an absolute path with the builder's home directory in it. */ export function richMarkdownEditorBuildOptions(extra = {}) { return { absWorkingDir: mobileRoot, entryPoints: [ENTRY], bundle: true, format: 'iife', minify: false, platform: 'browser', target: TARGET, legalComments: 'none', write: false, logLevel: 'silent', ...extra } } /** * One bundle, and everything a reader asks about it. * * The text and the module list come from the same build because they are two readings of one * thing: a census that built its own would answer about a bundle nobody ships. */ export async function richMarkdownEditorBundle() { const result = await esbuild.build(richMarkdownEditorBuildOptions({ metafile: true })) const [output] = result.outputFiles if (!output) { throw new Error('[build-rich-markdown-editor-script] esbuild emitted no document bundle') } return { script: output.text.trimEnd(), inputs: Object.keys(result.metafile.inputs) } } export async function buildRichMarkdownEditorScript() { return (await richMarkdownEditorBundle()).script } async function main() { const script = await buildRichMarkdownEditorScript() await writeFile( RICH_MARKDOWN_EDITOR_SCRIPT_PATH, `${GENERATED_HEADER}\nexport const RICH_MARKDOWN_EDITOR_DOCUMENT_SCRIPT = ${JSON.stringify(script)}\n` ) } if (process.argv[1] && import.meta.url.endsWith(path.basename(process.argv[1]))) { await main() }