typewright 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/SPEC.md +327 -0
- package/dist/chunk-CZQO7TTL.js +1533 -0
- package/dist/chunk-CZQO7TTL.js.map +1 -0
- package/dist/chunk-KNEKNZXK.js +286 -0
- package/dist/chunk-KNEKNZXK.js.map +1 -0
- package/dist/chunk-M6IVEMXO.js +1398 -0
- package/dist/chunk-M6IVEMXO.js.map +1 -0
- package/dist/chunk-NJ7PJKHN.js +652 -0
- package/dist/chunk-NJ7PJKHN.js.map +1 -0
- package/dist/commands-Z3ndUSza.d.cts +221 -0
- package/dist/commands-Z3ndUSza.d.ts +221 -0
- package/dist/core/index.cjs +2952 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +410 -0
- package/dist/core/index.d.ts +410 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/mdx/index.cjs +662 -0
- package/dist/mdx/index.cjs.map +1 -0
- package/dist/mdx/index.d.cts +252 -0
- package/dist/mdx/index.d.ts +252 -0
- package/dist/mdx/index.js +3 -0
- package/dist/mdx/index.js.map +1 -0
- package/dist/react/index.cjs +7439 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +140 -0
- package/dist/react/index.d.ts +140 -0
- package/dist/react/index.js +3644 -0
- package/dist/react/index.js.map +1 -0
- package/dist/streaming/index.cjs +1494 -0
- package/dist/streaming/index.cjs.map +1 -0
- package/dist/streaming/index.d.cts +64 -0
- package/dist/streaming/index.d.ts +64 -0
- package/dist/streaming/index.js +4 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/types-CX1GOx0Y.d.cts +319 -0
- package/dist/types-CX1GOx0Y.d.ts +319 -0
- package/package.json +128 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox/host.ts","../src/mdx/transform.ts","../src/mdx/index.ts"],"names":[],"mappings":"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","file":"chunk-NJ7PJKHN.js","sourcesContent":["/**\n * `src/sandbox/host.ts` — the opaque-origin execution sandbox (SPEC.md §7, §11).\n *\n * Anything executable (compiled MDX, Mermaid diagrams) runs here, never in the\n * host document. The sandbox is a hidden `<iframe srcdoc sandbox=\"allow-scripts\">`\n * with an **opaque origin** — `allow-same-origin` is NEVER granted, so a payload\n * cannot reach `parent.document`, storage, cookies, or the network beyond what\n * the CSP permits. This closes the XSS→RCE escalation and is Electron-safe.\n *\n * Security model (why this is safe without origin checks)\n * ------------------------------------------------------\n * - The iframe is opaque-origin, so every message it posts arrives at the host\n * with `event.origin === \"null\"`. Origin therefore cannot authenticate the\n * channel. Instead we validate:\n * 1. `event.source === iframe.contentWindow` — the message really came from\n * *our* frame (not a sibling frame or another window), and\n * 2. `message.token === <per-instance random token>` — the message carries\n * the secret channel token baked into this frame's `srcdoc`.\n * Both must hold; mismatches are silently ignored. The same token+source gate\n * is applied *inside* the frame (it only accepts messages whose source is its\n * `parent` and whose token matches).\n * - The CSP baked into the srcdoc is `default-src 'none'` with only\n * `'unsafe-inline'` scripts/styles (extendable via {@link SandboxOptions.csp}).\n * Compiled modules run as DOM-inserted **inline** `<script>` elements — which\n * `'unsafe-inline'` permits — so we never need `'unsafe-eval'`/`new Function`.\n * - Compiled output renders **inside** the iframe (the iframe *is* the widget).\n * The host never `innerHTML`s compiled output into its own tree. `evaluate`\n * resolves with the produced `html` for informational/read-mode use only; the\n * host must treat it as untrusted.\n * - A component's legitimate host/network needs are brokered: code inside the\n * frame calls `host(payload)` → `postMessage({type:'host', payload})` → the\n * host's {@link SandboxOptions.onHostMessage}, which proxies the request.\n *\n * The message-validation and dispatch logic is factored into pure functions\n * ({@link shouldAcceptMessage}, {@link dispatchInbound}, {@link buildSandboxCsp},\n * {@link buildSandboxSrcdoc}) so the protocol is unit-testable without a real\n * cross-origin frame (end-to-end iframe evaluation is covered by the e2e suite).\n */\n\nimport type { SandboxOptions } from '../types';\n\n/* ------------------------------------------------------------------ *\n * Public surface\n * ------------------------------------------------------------------ */\n\n/** Result of evaluating a compiled module inside the sandbox. */\nexport interface EvaluateResult {\n /**\n * Serialized HTML the module produced (already rendered inside the iframe).\n * Informational only — the host MUST NOT inject this into its own DOM.\n */\n html?: string;\n /** Measured content height of the iframe, for sizing the widget. */\n height?: number;\n /** Present when evaluation threw; the module never crashes the host. */\n error?: string;\n}\n\n/** Result of rendering a Mermaid diagram inside the sandbox. */\nexport interface MermaidResult {\n /** The diagram SVG (already rendered inside the iframe). */\n svg?: string;\n height?: number;\n error?: string;\n}\n\n/** Controller returned by {@link createSandbox}. */\nexport interface SandboxController {\n /**\n * Evaluate a compiled module body inside the sandbox. `code` is a statement\n * list that closes over the injected `h`, `components`, `props`, `host`, and\n * `root`, and returns the rendered result (an HTML string, a DOM node, or\n * nothing if it mounts into `root` itself). See the transform adapters in\n * `src/mdx/transform.ts` for the code shape.\n */\n evaluate(code: string, props?: Record<string, unknown>): Promise<EvaluateResult>;\n /** Render a Mermaid diagram source using the injected engine (if any). */\n renderMermaid(src: string): Promise<MermaidResult>;\n /** Tear down: remove the iframe, drop listeners, settle pending calls. */\n destroy(): void;\n}\n\n/**\n * Options for {@link createSandbox}. A superset of the public\n * {@link SandboxOptions} with host-only injection points (an existing\n * `SandboxOptions` is accepted as-is).\n */\nexport interface CreateSandboxOptions extends SandboxOptions {\n /** Element to append the hidden iframe to (defaults to `document.body`). */\n container?: HTMLElement;\n /**\n * Milliseconds before an `evaluate` / `renderMermaid` call resolves with a\n * timeout error (never rejects). `0` disables the timeout. Defaults to 8000.\n */\n timeoutMs?: number;\n /**\n * JavaScript *source* of a Mermaid-compatible engine, inlined into the sandbox\n * document (see {@link import('../types').MermaidOptions.getEngine}). Expected\n * to define `self.__twMermaidRender(src)` or `self.mermaid`.\n */\n mermaidEngine?: string;\n}\n\n/* ------------------------------------------------------------------ *\n * Pure protocol helpers (unit-tested)\n * ------------------------------------------------------------------ */\n\n/** Normalized shape of an inbound result message from the frame. */\nexport interface InboundResult {\n html?: string;\n svg?: string;\n height?: number;\n error?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Decide whether an inbound `message` event should be trusted. Replaces the\n * origin check (useless for an opaque-origin frame, where `event.origin` is\n * always `\"null\"`) with a source-identity + secret-token check.\n */\nexport function shouldAcceptMessage(\n event: { source?: unknown; data?: unknown },\n ctx: { source: unknown; token: string },\n): boolean {\n // The frame's own window must be the sender — not a sibling frame or a\n // rogue opener that happens to know the token.\n if (event.source !== ctx.source) return false;\n const data = event.data;\n if (!isRecord(data)) return false;\n return data.token === ctx.token;\n}\n\n/**\n * Route a *trusted* inbound message to the right handler. `ready` unlocks the\n * outbound queue, `host` is brokered to {@link SandboxOptions.onHostMessage},\n * anything carrying a numeric `id` settles the matching pending call.\n */\nexport function dispatchInbound(\n data: Record<string, unknown>,\n handlers: {\n onReady?: () => void;\n onHost?: (payload: unknown) => void;\n onResult?: (id: number, result: InboundResult) => void;\n },\n): void {\n const type = data.type;\n if (type === 'ready') {\n handlers.onReady?.();\n return;\n }\n if (type === 'host') {\n handlers.onHost?.(data.payload);\n return;\n }\n if (typeof data.id === 'number') {\n handlers.onResult?.(data.id, {\n html: typeof data.html === 'string' ? data.html : undefined,\n svg: typeof data.svg === 'string' ? data.svg : undefined,\n height: typeof data.height === 'number' ? data.height : undefined,\n error: typeof data.error === 'string' ? data.error : undefined,\n });\n }\n}\n\n/**\n * Build the frame-bound payload for an `evaluate` request. The host component\n * map travels under `props.components` — the single standardized field that the\n * in-frame `runModule` reads to bind the module's `components` (see\n * {@link MODULE_BINDINGS} and the dispatch in {@link SANDBOX_BOOTSTRAP}).\n * Centralizing the shape here keeps the sender and the frame in agreement and\n * makes the wiring unit-testable without a live iframe.\n */\nexport function buildEvaluateMessage(\n code: string,\n props?: Record<string, unknown>,\n): { code: string; props: Record<string, unknown> } {\n return { code, props: props ?? {} };\n}\n\n/**\n * The lexical bindings every compiled module closes over, injected verbatim as\n * the head of the in-frame module wrapper (see {@link SANDBOX_BOOTSTRAP}).\n * Notably it binds `components` ← `self.__tw.components` (the host's component\n * map), which the constrained transform relies on (`const Callout =\n * components[\"Callout\"]`). Exported so the binding contract is unit-testable\n * against the exact source the frame runs — no drift.\n */\nexport const MODULE_BINDINGS =\n 'var h=self.__tw.h,host=self.__tw.host,components=self.__tw.components,' +\n 'props=self.__tw.props,root=document.getElementById(\"tw-root\");';\n\n/** The strict base CSP for the sandbox document; `extra` is appended. */\nexport function buildSandboxCsp(extra?: string): string {\n const base =\n \"default-src 'none'; \" +\n \"script-src 'unsafe-inline'; \" +\n \"style-src 'unsafe-inline'; \" +\n 'img-src data: https:; ' +\n 'font-src data:';\n const trimmed = extra?.trim();\n return trimmed ? `${base}; ${trimmed}` : base;\n}\n\n/** A per-instance random channel token. Prefers crypto; falls back gracefully. */\nexport function createChannelToken(): string {\n const cryptoObj = (globalThis as { crypto?: Crypto }).crypto;\n if (cryptoObj && typeof cryptoObj.getRandomValues === 'function') {\n const bytes = new Uint8Array(16);\n cryptoObj.getRandomValues(bytes);\n let out = '';\n for (const b of bytes) out += b.toString(16).padStart(2, '0');\n return out;\n }\n return `${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\n/** Neutralize a premature `</script>` in inlined engine source. */\nfunction neutralizeScriptClose(source: string): string {\n return source.replace(/<\\/(script)/gi, '<\\\\/$1');\n}\n\n/**\n * Build the sandbox document. Only trusted, fixed content is inlined here (the\n * bootstrap and the optional engine source); per-evaluate module code is NEVER\n * inlined into this string — it is injected at runtime via a script element's\n * `textContent` (see the bootstrap), which is immune to `</script>` breakout.\n */\nexport function buildSandboxSrcdoc(params: {\n token: string;\n csp: string;\n engineSource?: string;\n}): string {\n const { token, csp, engineSource } = params;\n const bootstrap = SANDBOX_BOOTSTRAP.replace('__TW_TOKEN__', JSON.stringify(token));\n return (\n '<!DOCTYPE html><html><head><meta charset=\"utf-8\">' +\n `<meta http-equiv=\"Content-Security-Policy\" content=\"${csp}\">` +\n '<style>html,body{margin:0;padding:0;background:transparent;color:inherit;' +\n 'font:14px/1.5 system-ui,-apple-system,sans-serif}#tw-root{display:block}</style>' +\n '</head><body><div id=\"tw-root\"></div>' +\n (engineSource ? `<script>\\n${neutralizeScriptClose(engineSource)}\\n</script>` : '') +\n `<script>\\n${bootstrap}\\n</script>` +\n '</body></html>'\n );\n}\n\n/* ------------------------------------------------------------------ *\n * Sandbox factory\n * ------------------------------------------------------------------ */\n\n/**\n * Create a hidden opaque-origin sandbox and return a controller for evaluating\n * compiled modules and rendering Mermaid inside it. Requires a DOM (browser or\n * jsdom). Debouncing is the caller's responsibility.\n */\nexport function createSandbox(opts: CreateSandboxOptions = {}): SandboxController {\n if (typeof document === 'undefined') {\n throw new Error(\n 'typewright/mdx: createSandbox requires a DOM (browser or jsdom); none was found.',\n );\n }\n\n const token = createChannelToken();\n const csp = buildSandboxCsp(opts.csp);\n const srcdoc = buildSandboxSrcdoc({ token, csp, engineSource: opts.mermaidEngine });\n const timeoutMs = opts.timeoutMs ?? 8000;\n\n const iframe = document.createElement('iframe');\n // Opaque origin: scripts only, NEVER allow-same-origin (SPEC.md §7/§11).\n iframe.setAttribute('sandbox', 'allow-scripts');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('tabindex', '-1');\n iframe.setAttribute('title', 'typewright sandbox');\n iframe.style.cssText =\n 'position:absolute;width:0;height:0;border:0;visibility:hidden;pointer-events:none;';\n iframe.srcdoc = srcdoc;\n\n const container = opts.container ?? document.body ?? document.documentElement;\n container.appendChild(iframe);\n\n let destroyed = false;\n let ready = false;\n let nextId = 1;\n const outbox: Array<Record<string, unknown>> = [];\n const pending = new Map<\n number,\n { resolve: (r: InboundResult) => void; timer?: ReturnType<typeof setTimeout> }\n >();\n\n function flush(): void {\n if (!ready || destroyed) return;\n const win = iframe.contentWindow;\n if (!win) return;\n while (outbox.length > 0) {\n const msg = outbox.shift();\n if (!msg) continue;\n try {\n win.postMessage(msg, '*');\n } catch {\n // A non-structured-cloneable payload (e.g. a function passed in\n // MdxOptions.components — functions can't cross the postMessage\n // boundary into the opaque-origin frame) throws DataCloneError here.\n // Fail the matching request fast with a clear message instead of\n // letting it hang until the timeout.\n const id = msg.id;\n if (typeof id === 'number') {\n settle(id, {\n error:\n 'sandbox payload is not serializable — MDX components/props must be ' +\n 'structured-cloneable (functions are not supported across the sandbox)',\n });\n }\n }\n }\n }\n\n function send(msg: Record<string, unknown>): void {\n // targetOrigin '*' is required: the frame is opaque-origin (\"null\") and\n // cannot be named. The token in the payload authenticates the channel.\n outbox.push({ ...msg, token });\n flush();\n }\n\n function settle(id: number, result: InboundResult): void {\n const entry = pending.get(id);\n if (!entry) return;\n pending.delete(id);\n if (entry.timer) clearTimeout(entry.timer);\n entry.resolve(result);\n }\n\n function request(\n kind: 'evaluate' | 'mermaid',\n extra: Record<string, unknown>,\n ): Promise<InboundResult> {\n if (destroyed) return Promise.resolve({ error: 'sandbox destroyed' });\n const id = nextId++;\n return new Promise<InboundResult>((resolve) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(\n () => settle(id, { error: `sandbox ${kind} timed out after ${timeoutMs}ms` }),\n timeoutMs,\n )\n : undefined;\n pending.set(id, { resolve, timer });\n send({ type: kind, id, ...extra });\n });\n }\n\n function onMessage(event: MessageEvent): void {\n if (destroyed) return;\n // Opaque-origin frame → validate by source identity + token, not origin.\n if (!shouldAcceptMessage(event, { source: iframe.contentWindow, token })) return;\n dispatchInbound(event.data as Record<string, unknown>, {\n onReady: () => {\n ready = true;\n flush();\n },\n onHost: (payload) => {\n opts.onHostMessage?.(payload);\n },\n onResult: (id, result) => settle(id, result),\n });\n }\n\n window.addEventListener('message', onMessage);\n\n return {\n async evaluate(code, props) {\n const r = await request('evaluate', buildEvaluateMessage(code, props));\n return { html: r.html, height: r.height, error: r.error };\n },\n async renderMermaid(src) {\n const r = await request('mermaid', { src });\n return { svg: r.svg, height: r.height, error: r.error };\n },\n destroy() {\n if (destroyed) return;\n destroyed = true;\n window.removeEventListener('message', onMessage);\n for (const [, entry] of pending) {\n if (entry.timer) clearTimeout(entry.timer);\n entry.resolve({ error: 'sandbox destroyed' });\n }\n pending.clear();\n iframe.remove();\n },\n };\n}\n\n/* ------------------------------------------------------------------ *\n * The in-frame bootstrap (runs inside the opaque-origin iframe)\n * ------------------------------------------------------------------ */\n\n/**\n * Injected into the sandbox `srcdoc`. `__TW_TOKEN__` is replaced with the\n * JSON-encoded channel token. Written in ES5-ish JS (no build step runs on it)\n * and self-contained. It:\n * - only accepts messages whose `source === parent` and whose `token` matches;\n * - on `evaluate`, runs the module as a DOM-inserted inline script (CSP\n * `'unsafe-inline'` — no `eval`), mounting output into `#tw-root` and posting\n * `{ html, height }` (or `{ error }`);\n * - on `mermaid`, calls the injected engine and posts `{ svg, height }`;\n * - exposes `host(payload)` to brokered code, and `h()` to build DOM.\n */\nconst SANDBOX_BOOTSTRAP = `\n(function () {\n var TOKEN = __TW_TOKEN__;\n var root = document.getElementById('tw-root') || document.body;\n\n function post(msg) { msg.token = TOKEN; parent.postMessage(msg, '*'); }\n function measure() {\n var de = document.documentElement, b = document.body;\n return Math.max(\n de ? de.scrollHeight : 0,\n b ? b.scrollHeight : 0,\n root ? root.scrollHeight : 0\n );\n }\n function host(payload) { post({ type: 'host', payload: payload }); }\n\n function appendChildren(el, children) {\n for (var i = 0; i < children.length; i++) {\n var c = children[i];\n if (c == null || c === false || c === true) continue;\n if (Object.prototype.toString.call(c) === '[object Array]') { appendChildren(el, c); continue; }\n if (typeof Node !== 'undefined' && c instanceof Node) { el.appendChild(c); continue; }\n el.appendChild(document.createTextNode(String(c)));\n }\n }\n // Hyperscript used by compiled MDX: builds real DOM (no innerHTML string\n // concatenation), returns an element. A function tag is a component.\n function h(tag, props) {\n var children = Array.prototype.slice.call(arguments, 2);\n if (typeof tag === 'function') {\n var p = {}; for (var pk in (props || {})) p[pk] = props[pk]; p.children = children;\n return tag(p);\n }\n var el = document.createElement(String(tag));\n if (props) {\n for (var key in props) {\n var v = props[key];\n if (v == null || v === false) continue;\n if (key === 'className' || key === 'class') { el.setAttribute('class', String(v)); continue; }\n if (key === 'style' && v && typeof v === 'object') {\n for (var s in v) { try { el.style[s] = v[s]; } catch (e) {} }\n continue;\n }\n if (key.slice(0, 2) === 'on') continue; // never wire inline handlers\n if (v === true) { el.setAttribute(key, ''); continue; }\n el.setAttribute(key, String(v));\n }\n }\n appendChildren(el, children);\n return el;\n }\n\n var RT = { h: h, host: host, props: {}, components: {}, done: null, error: null };\n self.__tw = RT;\n\n RT.done = function (id, out) {\n Promise.resolve(out).then(function (value) {\n try {\n if (typeof Node !== 'undefined' && value instanceof Node) root.appendChild(value);\n else if (typeof value === 'string') root.innerHTML = value;\n // else: the module mounted itself into root\n } catch (e) {}\n post({ type: 'result', id: id, html: root.innerHTML, height: measure() });\n }, function (err) {\n post({ type: 'result', id: id, error: String((err && err.message) || err) });\n });\n };\n RT.error = function (id, err) {\n post({ type: 'result', id: id, error: String((err && err.message) || err) });\n };\n\n function runModule(id, code, props, components) {\n RT.props = props || {};\n RT.components = components || {};\n // Inline-script injection (allowed by CSP 'unsafe-inline'; no eval). Setting\n // textContent — not innerHTML — makes any '</script>' in code inert.\n var wrapped =\n '\"use strict\";(function(){' +\n '${MODULE_BINDINGS}' +\n 'try{var __out=(function(){' + code + '\\\\n})();self.__tw.done(' + id + ',__out);}' +\n 'catch(__e){self.__tw.error(' + id + ',__e);}})();';\n var s = document.createElement('script');\n s.textContent = wrapped;\n (document.body || document.documentElement).appendChild(s);\n if (s.parentNode) s.parentNode.removeChild(s);\n }\n\n function renderMermaid(id, src) {\n try {\n var engine = null;\n if (typeof self.__twMermaidRender === 'function') {\n engine = self.__twMermaidRender;\n } else if (self.mermaid && typeof self.mermaid.render === 'function') {\n engine = function (s) {\n return Promise.resolve(self.mermaid.render('tw-mmd-' + id, s)).then(function (r) {\n return typeof r === 'string' ? r : (r && r.svg) || '';\n });\n };\n }\n if (!engine) { post({ type: 'result', id: id, error: 'no mermaid engine injected in sandbox' }); return; }\n Promise.resolve(engine(src)).then(function (svg) {\n try { root.innerHTML = svg || ''; } catch (e) {}\n post({ type: 'result', id: id, svg: svg || '', height: measure() });\n }, function (err) {\n post({ type: 'result', id: id, error: String((err && err.message) || err) });\n });\n } catch (err) {\n post({ type: 'result', id: id, error: String((err && err.message) || err) });\n }\n }\n\n window.addEventListener('message', function (event) {\n if (event.source !== parent) return; // only the host frame\n var data = event.data;\n if (!data || typeof data !== 'object' || data.token !== TOKEN) return; // token gate\n // The host component map travels under props.components (see\n // buildEvaluateMessage); bind it as the module components map.\n if (data.type === 'evaluate') runModule(data.id, data.code, data.props, data.props && data.props.components);\n else if (data.type === 'mermaid') renderMermaid(data.id, data.src);\n });\n\n post({ type: 'ready' });\n})();\n`;\n","/**\n * `src/mdx/transform.ts` — MDX transform adapters (SPEC.md §7, step 2).\n *\n * Turning JSX/TS into runnable plain JS is the one conceded boundary. This\n * module resolves an {@link MdxTransform} into a uniform async compile function\n * `(code, meta?) => Promise<string>`:\n *\n * - `'wasm-esbuild'` → dynamically imports the OPTIONAL peer `esbuild-wasm`.\n * - `'wasm-swc'` → dynamically imports the OPTIONAL peer `@swc/wasm-web`.\n * Both peers are never bundled and never hard-imported; if absent, a clear\n * Error naming the missing peer is thrown. The host is responsible for\n * initializing the wasm engine (its `wasmURL` is environment-specific).\n * - `'constrained'` → a built-in, ZERO-DEPENDENCY transform for a restricted\n * MDX-JS subset (see grammar below). No external parser.\n * - a function → returned as-is (host-supplied), wrapped to a Promise.\n * - `undefined` → a transform that throws \"no MDX transform configured\"\n * (the editor treats this as \"render escaped source\").\n *\n * ── Constrained subset (exact, compiled to `h(tag, props, ...children)`) ──────\n * The constrained transform is a small hand-written recursive-descent parser for\n * a bounded surface — deliberately NOT a general JS parser. It accepts:\n *\n * Module := (Line)* lines beginning with `import`/`export`\n * (at column 0) are stripped/hoisted out\n * Body := (Text | Element | Interp)* the remaining top-level content\n * Element := '<' Name Attr* '/>'\n * | '<' Name Attr* '>' Children '</' Name '>'\n * Name := [A-Za-z][A-Za-z0-9._-]* Capitalized → component; the root\n * identifier is bound from the map\n * (`const Chart = components[\"Chart\"]`) and the\n * tag is emitted bare (`h(Chart, …)`, `h(Foo.Bar, …)`);\n * lowercase → HTML string tag. A capitalized name\n * whose segments aren't identifiers is rejected.\n * Attr := Name boolean shorthand → `true`\n * | Name '=' '\"' … '\"' string literal\n * | Name '=' \"'\" … \"'\" string literal\n * | Name '=' '{' Expr '}' restricted expression\n * Children := (Text | Element | Interp)*\n * Interp := '{' Expr '}' interpolation child\n * Expr := number | 'true' | 'false' | 'null'\n * | Identifier e.g. `name`\n * | Identifier ('.' Identifier)+ simple member, e.g. `user.name`\n * Text := run of chars that are not '<' or '{' (JSX entities untouched)\n *\n * Anything outside this subset (arrow functions, calls, operators, object/array\n * literals, template strings, JSX fragments `<>…</>`, spread `{...x}`, mismatched\n * tags, unterminated constructs) throws a clear Error — it never silently\n * miscompiles. Hosts needing the full surface use `wasm-esbuild`/`wasm-swc`.\n *\n * Output shape: the compiled module is a statement list ending in a `return`,\n * closing over the sandbox-injected `h`, `components`, and `props`. Example:\n * `<Callout type=\"info\">Hi {name}</Callout>` →\n * const Callout = components[\"Callout\"];\n * return h(Callout, {\"type\": \"info\"}, \"Hi \", name);\n */\n\nimport type { MdxTransform } from '../types';\n\nexport interface TransformMeta {\n filename?: string;\n}\n\nexport type CompileFn = (code: string, meta?: TransformMeta) => Promise<string>;\n\n/* ------------------------------------------------------------------ *\n * Resolution\n * ------------------------------------------------------------------ */\n\n/** Resolve an {@link MdxTransform} into a uniform async compile function. */\nexport function resolveTransform(t: MdxTransform | undefined): CompileFn {\n if (t === undefined) {\n return async () => {\n throw new Error('no MDX transform configured');\n };\n }\n if (typeof t === 'function') {\n return async (code, meta) => t(code, meta ?? {});\n }\n switch (t) {\n case 'constrained':\n return async (code) => compileConstrained(code);\n case 'wasm-esbuild':\n return (code, meta) => transformWithEsbuild(code, meta);\n case 'wasm-swc':\n return (code, meta) => transformWithSwc(code, meta);\n default: {\n // Exhaustiveness: a new MdxTransform string must be handled here.\n const never: never = t;\n throw new Error(`typewright/mdx: unknown MDX transform \"${String(never)}\"`);\n }\n }\n}\n\n/* ------------------------------------------------------------------ *\n * Optional-peer wasm adapters\n * ------------------------------------------------------------------ */\n\n/**\n * Dynamically import an optional peer by a NON-literal specifier so no bundler\n * tries to resolve/inline it. Throws a clear, actionable Error if it is absent.\n */\nasync function importOptionalPeer(name: string): Promise<Record<string, unknown>> {\n const specifier = name; // variable → non-analyzable → never bundled\n try {\n return (await import(/* @vite-ignore */ specifier)) as Record<string, unknown>;\n } catch (cause) {\n throw new Error(\n `typewright/mdx: this MDX transform needs the optional peer dependency \"${name}\", ` +\n `which is not installed. Install it (e.g. \\`npm i ${name}\\`) or choose a different ` +\n `MdxTransform (\"constrained\" has zero dependencies).`,\n { cause },\n );\n }\n}\n\nfunction loaderFor(meta?: TransformMeta): 'tsx' | 'jsx' {\n return /\\.tsx?$/.test(meta?.filename ?? '') ? 'tsx' : 'jsx';\n}\n\nasync function transformWithEsbuild(code: string, meta?: TransformMeta): Promise<string> {\n const esbuild = await importOptionalPeer('esbuild-wasm');\n const transform = esbuild.transform as\n | ((input: string, options: unknown) => Promise<{ code: string }>)\n | undefined;\n if (typeof transform !== 'function') {\n throw new Error('typewright/mdx: \"esbuild-wasm\" is installed but exposes no transform().');\n }\n const result = await transform(code, {\n loader: loaderFor(meta),\n jsx: 'automatic',\n format: 'esm',\n sourcefile: meta?.filename,\n });\n return result.code;\n}\n\nasync function transformWithSwc(code: string, meta?: TransformMeta): Promise<string> {\n const swc = await importOptionalPeer('@swc/wasm-web');\n const transform = swc.transform as\n | ((input: string, options: unknown) => Promise<{ code: string }>)\n | undefined;\n if (typeof transform !== 'function') {\n throw new Error('typewright/mdx: \"@swc/wasm-web\" is installed but exposes no transform().');\n }\n const tsx = loaderFor(meta) === 'tsx';\n const result = await transform(code, {\n filename: meta?.filename,\n jsc: {\n parser: tsx\n ? { syntax: 'typescript', tsx: true }\n : { syntax: 'ecmascript', jsx: true },\n transform: { react: { runtime: 'automatic' } },\n },\n });\n return result.code;\n}\n\n/* ------------------------------------------------------------------ *\n * Constrained transform — zero-dependency restricted JSX compiler\n * ------------------------------------------------------------------ */\n\ntype ConstrainedNode =\n | { kind: 'text'; value: string }\n | { kind: 'expr'; source: string }\n | { kind: 'element'; name: string; attrs: Attr[]; children: ConstrainedNode[] };\n\ninterface Attr {\n name: string;\n /** `undefined` → boolean shorthand (`true`). */\n value?: { kind: 'string'; value: string } | { kind: 'expr'; source: string };\n}\n\nclass TransformError extends Error {\n constructor(message: string, index: number) {\n super(`constrained MDX transform: ${message} (at offset ${index})`);\n this.name = 'TransformError';\n }\n}\n\nconst IDENT_START = /[A-Za-z_$]/;\nconst IDENT_PART = /[A-Za-z0-9_$]/;\nconst NAME_PART = /[A-Za-z0-9._-]/;\n\n/** Compile the restricted MDX subset to a sandbox module string. */\nexport function compileConstrained(source: string): string {\n const { body, components } = new ConstrainedParser(source).parse();\n const parts: string[] = [];\n for (const name of components) {\n parts.push(`const ${name} = components[${JSON.stringify(name)}];`);\n }\n parts.push(`return ${childrenExpr(body)};`);\n return parts.join('\\n');\n}\n\n/** Strip top-level `import`/`export` lines; return the remaining body. */\nfunction stripModuleLines(source: string): string {\n const kept: string[] = [];\n for (const line of source.split('\\n')) {\n if (/^\\s*(import|export)\\b/.test(line)) {\n // Line-based hoist: imports/exports are dropped (components come from the\n // injected `components` map, not resolved modules — documented limitation).\n kept.push('');\n } else {\n kept.push(line);\n }\n }\n return kept.join('\\n');\n}\n\nclass ConstrainedParser {\n private readonly src: string;\n private pos = 0;\n private readonly components = new Set<string>();\n\n constructor(rawSource: string) {\n this.src = stripModuleLines(rawSource);\n }\n\n parse(): { body: ConstrainedNode[]; components: string[] } {\n const body = this.parseChildren(null);\n this.skipInsignificantWhitespace();\n if (this.pos < this.src.length) {\n throw new TransformError(`unexpected \"${this.src[this.pos]}\"`, this.pos);\n }\n return { body, components: [...this.components] };\n }\n\n private parseChildren(closeTag: string | null): ConstrainedNode[] {\n const children: ConstrainedNode[] = [];\n for (;;) {\n if (this.pos >= this.src.length) {\n if (closeTag !== null) {\n throw new TransformError(`unclosed <${closeTag}>`, this.pos);\n }\n return children;\n }\n const ch = this.src[this.pos];\n if (ch === '<') {\n if (this.src[this.pos + 1] === '/') {\n // Closing tag — belongs to the caller.\n if (closeTag === null) {\n throw new TransformError('unexpected closing tag', this.pos);\n }\n return children;\n }\n children.push(this.parseElement());\n } else if (ch === '{') {\n children.push({ kind: 'expr', source: this.parseBracedExpr() });\n } else {\n const text = this.parseText();\n if (text.value.length > 0) children.push(text);\n }\n }\n }\n\n private parseText(): { kind: 'text'; value: string } {\n let out = '';\n while (this.pos < this.src.length) {\n const ch = this.src[this.pos];\n if (ch === '<' || ch === '{') break;\n out += ch;\n this.pos++;\n }\n return { kind: 'text', value: out };\n }\n\n private parseElement(): ConstrainedNode {\n const start = this.pos;\n this.expect('<');\n const name = this.parseName();\n if (isComponentName(name)) this.components.add(componentRoot(name, start));\n const attrs: Attr[] = [];\n for (;;) {\n this.skipWhitespace();\n const ch = this.src[this.pos];\n if (ch === undefined) throw new TransformError('unterminated tag', start);\n if (ch === '/') {\n this.expect('/');\n this.expect('>');\n return { kind: 'element', name, attrs, children: [] };\n }\n if (ch === '>') {\n this.pos++;\n const children = this.parseChildren(name);\n this.expect('<');\n this.expect('/');\n this.skipWhitespace();\n const closeName = this.parseName();\n if (closeName !== name) {\n throw new TransformError(`mismatched closing tag </${closeName}> for <${name}>`, this.pos);\n }\n this.skipWhitespace();\n this.expect('>');\n return { kind: 'element', name, attrs, children };\n }\n attrs.push(this.parseAttr());\n }\n }\n\n private parseAttr(): Attr {\n const name = this.parseName();\n this.skipWhitespace();\n if (this.src[this.pos] !== '=') {\n return { name }; // boolean shorthand\n }\n this.pos++; // '='\n this.skipWhitespace();\n const ch = this.src[this.pos];\n if (ch === '\"' || ch === \"'\") {\n return { name, value: { kind: 'string', value: this.parseStringLiteral(ch) } };\n }\n if (ch === '{') {\n return { name, value: { kind: 'expr', source: this.parseBracedExpr() } };\n }\n throw new TransformError(`attribute \"${name}\" must be a string literal or a {expression}`, this.pos);\n }\n\n private parseName(): string {\n const start = this.pos;\n const first = this.src[this.pos];\n if (first === undefined || !/[A-Za-z]/.test(first)) {\n throw new TransformError('expected a tag/attribute name', this.pos);\n }\n let out = first;\n this.pos++;\n while (this.pos < this.src.length && NAME_PART.test(this.src[this.pos] as string)) {\n out += this.src[this.pos];\n this.pos++;\n }\n if (out.endsWith('.') || out.endsWith('-')) {\n throw new TransformError(`invalid name \"${out}\"`, start);\n }\n return out;\n }\n\n private parseStringLiteral(quote: string): string {\n this.expect(quote);\n let out = '';\n while (this.pos < this.src.length) {\n const ch = this.src[this.pos];\n if (ch === quote) {\n this.pos++;\n return out;\n }\n if (ch === '\\\\') {\n // Keep escapes literal-safe: capture the next char verbatim.\n out += ch;\n this.pos++;\n if (this.pos < this.src.length) {\n out += this.src[this.pos];\n this.pos++;\n }\n continue;\n }\n out += ch;\n this.pos++;\n }\n throw new TransformError('unterminated string literal', this.pos);\n }\n\n /** Consume `{ … }` and return the validated restricted expression source. */\n private parseBracedExpr(): string {\n const start = this.pos;\n this.expect('{');\n let depth = 1;\n let raw = '';\n while (this.pos < this.src.length && depth > 0) {\n const ch = this.src[this.pos];\n if (ch === '{') depth++;\n else if (ch === '}') {\n depth--;\n if (depth === 0) {\n this.pos++;\n break;\n }\n }\n raw += ch;\n this.pos++;\n }\n if (depth !== 0) throw new TransformError('unterminated {expression}', start);\n return validateRestrictedExpr(raw.trim(), start);\n }\n\n private expect(ch: string): void {\n if (this.src[this.pos] !== ch) {\n throw new TransformError(`expected \"${ch}\"`, this.pos);\n }\n this.pos++;\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.src.length && /\\s/.test(this.src[this.pos] as string)) this.pos++;\n }\n\n /** Skip trailing whitespace-only content when checking for EOF. */\n private skipInsignificantWhitespace(): void {\n while (this.pos < this.src.length && /\\s/.test(this.src[this.pos] as string)) this.pos++;\n }\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name);\n}\n\nconst SIMPLE_IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * For a capitalized component tag (optionally a member expression like\n * `Foo.Bar`), validate that every segment is a plain identifier and return the\n * ROOT identifier to bind from the `components` map (`const Foo = components[\"Foo\"]`;\n * the tag itself is emitted as the bare dotted path). Throws on names that would\n * not form valid JS (e.g. a hyphenated capitalized name).\n */\nfunction componentRoot(name: string, index: number): string {\n const segments = name.split('.');\n for (const seg of segments) {\n if (!SIMPLE_IDENT.test(seg)) {\n throw new TransformError(\n `unsupported component name \"${name}\" — component tags must be dot-separated identifiers`,\n index,\n );\n }\n }\n return segments[0] as string;\n}\n\n/**\n * Validate that `expr` is a restricted expression (number/boolean/null,\n * identifier, or a simple dotted member). Returns it unchanged; throws\n * otherwise. This is the guard that keeps the subset safe and predictable — no\n * calls, operators, or function bodies slip through.\n */\nfunction validateRestrictedExpr(expr: string, index: number): string {\n if (expr.length === 0) {\n throw new TransformError('empty {expression}', index);\n }\n if (expr === 'true' || expr === 'false' || expr === 'null') return expr;\n if (/^-?\\d+(\\.\\d+)?$/.test(expr)) return expr;\n if (isSimpleMemberPath(expr)) return expr;\n throw new TransformError(\n `unsupported expression \\`${expr}\\` — only numbers, true/false/null, ` +\n `an identifier, or a simple dotted member (a.b.c) are allowed`,\n index,\n );\n}\n\n/** `foo` or `foo.bar.baz` — each segment a valid JS identifier. */\nfunction isSimpleMemberPath(expr: string): boolean {\n const segments = expr.split('.');\n for (const seg of segments) {\n if (seg.length === 0) return false;\n if (!IDENT_START.test(seg[0] as string)) return false;\n for (let i = 1; i < seg.length; i++) {\n if (!IDENT_PART.test(seg[i] as string)) return false;\n }\n }\n return true;\n}\n\n/* ------------------------------------------------------------------ *\n * Codegen\n * ------------------------------------------------------------------ */\n\nfunction childrenExpr(children: ConstrainedNode[]): string {\n const rendered = children.map(nodeExpr).filter((s) => s !== null) as string[];\n if (rendered.length === 0) return 'null';\n if (rendered.length === 1) return rendered[0] as string;\n return `[${rendered.join(', ')}]`;\n}\n\nfunction nodeExpr(node: ConstrainedNode): string | null {\n if (node.kind === 'text') {\n if (node.value.trim().length === 0 && node.value.indexOf('\\n') !== -1) {\n // Whitespace-only text spanning a line break is layout noise — drop it,\n // matching JSX's whitespace handling for readability.\n return null;\n }\n return JSON.stringify(node.value);\n }\n if (node.kind === 'expr') {\n return node.source;\n }\n const tag = isComponentName(node.name) ? node.name : JSON.stringify(node.name);\n const props = attrsExpr(node.attrs);\n const kids = node.children.map(nodeExpr).filter((s) => s !== null) as string[];\n const args = [tag, props, ...kids];\n return `h(${args.join(', ')})`;\n}\n\nfunction attrsExpr(attrs: Attr[]): string {\n if (attrs.length === 0) return 'null';\n const entries = attrs.map((attr) => {\n const key = JSON.stringify(attr.name);\n if (attr.value === undefined) return `${key}: true`;\n if (attr.value.kind === 'string') return `${key}: ${JSON.stringify(attr.value.value)}`;\n return `${key}: ${attr.value.source}`;\n });\n return `{${entries.join(', ')}}`;\n}\n","/**\n * `typewright/mdx` — the sandboxed MDX/Mermaid execution boundary.\n *\n * Two pieces, kept separate on purpose (SPEC.md §7):\n * - {@link resolveTransform} turns JSX/TS into plain JS (the one conceded\n * dependency boundary — wasm peers or a zero-dep constrained subset).\n * - {@link createSandbox} runs that plain JS inside an opaque-origin sandboxed\n * iframe that cannot reach the host DOM, storage, or session.\n *\n * {@link compileAndRun} is the convenience that wires them together for a\n * one-shot compile-and-render.\n */\n\nimport { createSandbox } from '../sandbox/host';\nimport type { CreateSandboxOptions, EvaluateResult } from '../sandbox/host';\nimport { resolveTransform } from './transform';\nimport type { TransformMeta } from './transform';\nimport type { MdxTransform } from '../types';\n\nexport { createSandbox } from '../sandbox/host';\nexport type {\n SandboxController,\n CreateSandboxOptions,\n EvaluateResult,\n MermaidResult,\n InboundResult,\n} from '../sandbox/host';\nexport {\n shouldAcceptMessage,\n dispatchInbound,\n buildSandboxCsp,\n buildSandboxSrcdoc,\n createChannelToken,\n} from '../sandbox/host';\n\nexport { resolveTransform, compileConstrained } from './transform';\nexport type { CompileFn, TransformMeta } from './transform';\n\n/* Re-export the relevant public config types for `typewright/mdx` consumers. */\nexport type {\n MdxOptions,\n MdxTransform,\n ComponentMap,\n SandboxOptions,\n MermaidOptions,\n MathOptions,\n} from '../types';\n\n/** Options for {@link compileAndRun}. */\nexport interface CompileAndRunOptions {\n /** MDX/JSX source to compile. */\n code: string;\n /** How to transform it (defaults to `undefined` → throws \"no transform\"). */\n transform?: MdxTransform;\n /** Transform metadata (e.g. a filename to pick the tsx/jsx loader). */\n meta?: TransformMeta;\n /** Props passed to the evaluated module. */\n props?: Record<string, unknown>;\n /**\n * Sandbox options for a freshly-created sandbox. Ignored when `controller`\n * is supplied.\n */\n sandbox?: CreateSandboxOptions;\n /** Reuse an existing sandbox instead of creating (and destroying) one. */\n controller?: ReturnType<typeof createSandbox>;\n}\n\n/**\n * Compile `code` with the resolved transform and evaluate it in a sandbox. When\n * no `controller` is supplied a temporary sandbox is created and destroyed\n * around the call. The compiled output renders inside the sandbox; the returned\n * `html` is informational — never inject it into the host tree (SPEC.md §11).\n */\nexport async function compileAndRun(opts: CompileAndRunOptions): Promise<EvaluateResult> {\n const compile = resolveTransform(opts.transform);\n const js = await compile(opts.code, opts.meta);\n const owned = opts.controller === undefined;\n const sandbox = opts.controller ?? createSandbox(opts.sandbox);\n try {\n return await sandbox.evaluate(js, opts.props);\n } finally {\n if (owned) sandbox.destroy();\n }\n}\n"]}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typewright AST — the offset-exact node model the parser produces and the
|
|
3
|
+
* renderer / unified-mode / fold services consume.
|
|
4
|
+
*
|
|
5
|
+
* Every node carries `from`/`to`: UTF-16 offsets into the source string. This
|
|
6
|
+
* is the contract that makes non-destructive rendering, source-revealing, and
|
|
7
|
+
* folding possible — a node always knows exactly which slice of the string it
|
|
8
|
+
* owns. Marker offsets (e.g. a heading's `### `, an emphasis delimiter) are
|
|
9
|
+
* exposed where a consumer needs to hide/reveal them.
|
|
10
|
+
*/
|
|
11
|
+
interface Pos {
|
|
12
|
+
/** Inclusive start offset into the source string. */
|
|
13
|
+
from: number;
|
|
14
|
+
/** Exclusive end offset into the source string. */
|
|
15
|
+
to: number;
|
|
16
|
+
}
|
|
17
|
+
interface TextNode extends Pos {
|
|
18
|
+
type: 'text';
|
|
19
|
+
value: string;
|
|
20
|
+
}
|
|
21
|
+
interface Emphasis extends Pos {
|
|
22
|
+
type: 'emphasis';
|
|
23
|
+
/** The delimiter used (`*` or `_`). */
|
|
24
|
+
marker: string;
|
|
25
|
+
children: Inline[];
|
|
26
|
+
}
|
|
27
|
+
interface Strong extends Pos {
|
|
28
|
+
type: 'strong';
|
|
29
|
+
marker: string;
|
|
30
|
+
children: Inline[];
|
|
31
|
+
}
|
|
32
|
+
interface Strikethrough extends Pos {
|
|
33
|
+
type: 'strikethrough';
|
|
34
|
+
children: Inline[];
|
|
35
|
+
}
|
|
36
|
+
interface InlineCode extends Pos {
|
|
37
|
+
type: 'inlineCode';
|
|
38
|
+
value: string;
|
|
39
|
+
/** Number of backticks in the fence. */
|
|
40
|
+
ticks: number;
|
|
41
|
+
}
|
|
42
|
+
interface Link extends Pos {
|
|
43
|
+
type: 'link';
|
|
44
|
+
url: string;
|
|
45
|
+
title?: string;
|
|
46
|
+
children: Inline[];
|
|
47
|
+
}
|
|
48
|
+
interface Image extends Pos {
|
|
49
|
+
type: 'image';
|
|
50
|
+
url: string;
|
|
51
|
+
alt: string;
|
|
52
|
+
title?: string;
|
|
53
|
+
}
|
|
54
|
+
interface Autolink extends Pos {
|
|
55
|
+
type: 'autolink';
|
|
56
|
+
url: string;
|
|
57
|
+
}
|
|
58
|
+
interface LineBreak extends Pos {
|
|
59
|
+
type: 'break';
|
|
60
|
+
/** A hard break (two trailing spaces or backslash) vs a soft newline. */
|
|
61
|
+
hard: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Inline math (`$…$` inline, `$$…$$` inline-display). Opt-in via {@link ParseOptions.math}. */
|
|
64
|
+
interface Math extends Pos {
|
|
65
|
+
type: 'math';
|
|
66
|
+
/** The TeX source between the delimiters (delimiters excluded). */
|
|
67
|
+
value: string;
|
|
68
|
+
/** `true` for a `$$…$$` display span, `false` for a `$…$` inline span. */
|
|
69
|
+
display: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** A footnote reference `[^id]`. Opt-in via {@link ParseOptions.footnotes}. */
|
|
72
|
+
interface FootnoteRef extends Pos {
|
|
73
|
+
type: 'footnoteRef';
|
|
74
|
+
/** The referenced footnote label (between `[^` and `]`). */
|
|
75
|
+
id: string;
|
|
76
|
+
}
|
|
77
|
+
type Inline = TextNode | Emphasis | Strong | Strikethrough | InlineCode | Link | Image | Autolink | LineBreak | Math | FootnoteRef;
|
|
78
|
+
interface Heading extends Pos {
|
|
79
|
+
type: 'heading';
|
|
80
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
81
|
+
/** Offset just past the `#`… marker + following space (start of content). */
|
|
82
|
+
contentFrom: number;
|
|
83
|
+
children: Inline[];
|
|
84
|
+
}
|
|
85
|
+
interface Paragraph extends Pos {
|
|
86
|
+
type: 'paragraph';
|
|
87
|
+
children: Inline[];
|
|
88
|
+
}
|
|
89
|
+
interface Blockquote extends Pos {
|
|
90
|
+
type: 'blockquote';
|
|
91
|
+
children: Block[];
|
|
92
|
+
}
|
|
93
|
+
type TaskState = 'checked' | 'unchecked' | null;
|
|
94
|
+
interface ListItem extends Pos {
|
|
95
|
+
type: 'listItem';
|
|
96
|
+
/** Task-list state, or null for a plain item. */
|
|
97
|
+
task: TaskState;
|
|
98
|
+
/** Offset just past the list marker (`- `, `1. `, `- [x] `). */
|
|
99
|
+
contentFrom: number;
|
|
100
|
+
children: Block[];
|
|
101
|
+
}
|
|
102
|
+
interface List extends Pos {
|
|
103
|
+
type: 'list';
|
|
104
|
+
ordered: boolean;
|
|
105
|
+
/** Start number for an ordered list. */
|
|
106
|
+
start: number;
|
|
107
|
+
/** Loose lists wrap items in paragraphs; tight lists don't. */
|
|
108
|
+
tight: boolean;
|
|
109
|
+
items: ListItem[];
|
|
110
|
+
}
|
|
111
|
+
interface CodeBlock extends Pos {
|
|
112
|
+
type: 'codeBlock';
|
|
113
|
+
/** Info string after the opening fence (may be empty). */
|
|
114
|
+
lang: string;
|
|
115
|
+
value: string;
|
|
116
|
+
fenced: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface ThematicBreak extends Pos {
|
|
119
|
+
type: 'thematicBreak';
|
|
120
|
+
}
|
|
121
|
+
type CellAlign = 'left' | 'center' | 'right' | null;
|
|
122
|
+
interface TableCell extends Pos {
|
|
123
|
+
type: 'tableCell';
|
|
124
|
+
children: Inline[];
|
|
125
|
+
}
|
|
126
|
+
interface Table extends Pos {
|
|
127
|
+
type: 'table';
|
|
128
|
+
align: CellAlign[];
|
|
129
|
+
header: TableCell[];
|
|
130
|
+
rows: TableCell[][];
|
|
131
|
+
}
|
|
132
|
+
/** Raw HTML or an MDX/JSX/ESM region — kept verbatim (markup only, not evaluated). */
|
|
133
|
+
interface HtmlBlock extends Pos {
|
|
134
|
+
type: 'htmlBlock';
|
|
135
|
+
value: string;
|
|
136
|
+
/** `html` for raw HTML, `mdxFlow` for a JSX element / ESM line at block level. */
|
|
137
|
+
variant: 'html' | 'mdxFlow';
|
|
138
|
+
}
|
|
139
|
+
/** A `$$…$$` display-math block. Opt-in via {@link ParseOptions.math}. */
|
|
140
|
+
interface MathBlock extends Pos {
|
|
141
|
+
type: 'mathBlock';
|
|
142
|
+
/** The TeX source between the `$$` fences (fences excluded). */
|
|
143
|
+
value: string;
|
|
144
|
+
}
|
|
145
|
+
/** A footnote definition `[^id]: …`. Opt-in via {@link ParseOptions.footnotes}. */
|
|
146
|
+
interface FootnoteDef extends Pos {
|
|
147
|
+
type: 'footnoteDef';
|
|
148
|
+
/** The footnote label (between `[^` and `]`). */
|
|
149
|
+
id: string;
|
|
150
|
+
children: Block[];
|
|
151
|
+
}
|
|
152
|
+
/** A single term + one-or-more definitions inside a {@link DefList}. */
|
|
153
|
+
interface DefItem extends Pos {
|
|
154
|
+
type: 'defItem';
|
|
155
|
+
term: Inline[];
|
|
156
|
+
/** Each `: …` definition, parsed as its own block sequence. */
|
|
157
|
+
definitions: Block[][];
|
|
158
|
+
}
|
|
159
|
+
/** A definition list — terms with `: …` definitions. Opt-in via {@link ParseOptions.defLists}. */
|
|
160
|
+
interface DefList extends Pos {
|
|
161
|
+
type: 'defList';
|
|
162
|
+
items: DefItem[];
|
|
163
|
+
}
|
|
164
|
+
type Block = Heading | Paragraph | Blockquote | List | CodeBlock | ThematicBreak | Table | HtmlBlock | MathBlock | FootnoteDef | DefList;
|
|
165
|
+
interface Document extends Pos {
|
|
166
|
+
type: 'document';
|
|
167
|
+
children: Block[];
|
|
168
|
+
}
|
|
169
|
+
type AstNode = Document | Block | ListItem | TableCell | DefItem | Inline;
|
|
170
|
+
/**
|
|
171
|
+
* Opt-in parser extensions. Every flag defaults to `false`, so `parse(src)`
|
|
172
|
+
* behaves exactly as it always has; enabling a flag lights up the matching
|
|
173
|
+
* construct (and nothing else). Kept semver-safe so a later wave can turn these
|
|
174
|
+
* on from configuration without a breaking parser change.
|
|
175
|
+
*/
|
|
176
|
+
interface ParseOptions {
|
|
177
|
+
/** Parse `$…$` inline and `$$…$$` block math. */
|
|
178
|
+
math?: boolean;
|
|
179
|
+
/** Parse `[^id]` footnote references and `[^id]: …` definitions. */
|
|
180
|
+
footnotes?: boolean;
|
|
181
|
+
/** Parse `term` / `: definition` definition lists. */
|
|
182
|
+
defLists?: boolean;
|
|
183
|
+
}
|
|
184
|
+
declare function isInline(node: AstNode): node is Inline;
|
|
185
|
+
/** Depth-first walk over the tree; return false from `visit` to skip children. */
|
|
186
|
+
declare function walk(node: AstNode, visit: (node: AstNode) => boolean | void): void;
|
|
187
|
+
declare function childrenOf(node: AstNode): AstNode[];
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Editing commands — pure transforms over `(text, selection)` used by the
|
|
191
|
+
* formatting toolbar and keyboard shortcuts. Each returns the new text and the
|
|
192
|
+
* new selection, so the caller (edit textarea / unified active block) can apply
|
|
193
|
+
* it and restore the caret. Pure and framework-free — fully unit-testable.
|
|
194
|
+
*/
|
|
195
|
+
type Command = 'bold' | 'italic' | 'strikethrough' | 'inlineCode' | 'link' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'bulletList' | 'orderedList' | 'taskList' | 'quote' | 'horizontalRule' | 'codeBlock' | 'table';
|
|
196
|
+
/** Metadata describing a command for enumerable surfaces (toolbar, palette, keymap). */
|
|
197
|
+
interface CommandMeta {
|
|
198
|
+
id: Command;
|
|
199
|
+
label: string;
|
|
200
|
+
/** Display shortcut (e.g. `⌘B`) when one is bound; omitted otherwise. */
|
|
201
|
+
kbd?: string;
|
|
202
|
+
group: 'inline' | 'block' | 'insert';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The single source of truth enumerating every command — consumed by the
|
|
206
|
+
* formatting toolbar, the command palette, and the keymap. Plain data, no side
|
|
207
|
+
* effects; one entry per `Command` id (kept exhaustive by the `applyCommand`
|
|
208
|
+
* `never` guard, which forces new ids to exist before they can be listed here).
|
|
209
|
+
*/
|
|
210
|
+
declare const COMMANDS: readonly CommandMeta[];
|
|
211
|
+
interface Sel {
|
|
212
|
+
from: number;
|
|
213
|
+
to: number;
|
|
214
|
+
}
|
|
215
|
+
interface CommandResult {
|
|
216
|
+
text: string;
|
|
217
|
+
selection: Sel;
|
|
218
|
+
}
|
|
219
|
+
declare function applyCommand(text: string, sel: Sel, cmd: Command): CommandResult;
|
|
220
|
+
|
|
221
|
+
export { type AstNode as A, type Block as B, type CellAlign as C, type Document as D, type Emphasis as E, type FootnoteDef as F, isInline as G, type Heading as H, type Inline as I, walk as J, type LineBreak as L, type Math as M, type ParseOptions as P, type Sel as S, type Table as T, type Pos as a, type Autolink as b, type Blockquote as c, COMMANDS as d, type CodeBlock as e, type Command as f, type CommandResult as g, type DefItem as h, type DefList as i, type FootnoteRef as j, type HtmlBlock as k, type Image as l, type InlineCode as m, type Link as n, type List as o, type ListItem as p, type MathBlock as q, type Paragraph as r, type Strikethrough as s, type Strong as t, type TableCell as u, type TaskState as v, type TextNode as w, type ThematicBreak as x, applyCommand as y, childrenOf as z };
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typewright AST — the offset-exact node model the parser produces and the
|
|
3
|
+
* renderer / unified-mode / fold services consume.
|
|
4
|
+
*
|
|
5
|
+
* Every node carries `from`/`to`: UTF-16 offsets into the source string. This
|
|
6
|
+
* is the contract that makes non-destructive rendering, source-revealing, and
|
|
7
|
+
* folding possible — a node always knows exactly which slice of the string it
|
|
8
|
+
* owns. Marker offsets (e.g. a heading's `### `, an emphasis delimiter) are
|
|
9
|
+
* exposed where a consumer needs to hide/reveal them.
|
|
10
|
+
*/
|
|
11
|
+
interface Pos {
|
|
12
|
+
/** Inclusive start offset into the source string. */
|
|
13
|
+
from: number;
|
|
14
|
+
/** Exclusive end offset into the source string. */
|
|
15
|
+
to: number;
|
|
16
|
+
}
|
|
17
|
+
interface TextNode extends Pos {
|
|
18
|
+
type: 'text';
|
|
19
|
+
value: string;
|
|
20
|
+
}
|
|
21
|
+
interface Emphasis extends Pos {
|
|
22
|
+
type: 'emphasis';
|
|
23
|
+
/** The delimiter used (`*` or `_`). */
|
|
24
|
+
marker: string;
|
|
25
|
+
children: Inline[];
|
|
26
|
+
}
|
|
27
|
+
interface Strong extends Pos {
|
|
28
|
+
type: 'strong';
|
|
29
|
+
marker: string;
|
|
30
|
+
children: Inline[];
|
|
31
|
+
}
|
|
32
|
+
interface Strikethrough extends Pos {
|
|
33
|
+
type: 'strikethrough';
|
|
34
|
+
children: Inline[];
|
|
35
|
+
}
|
|
36
|
+
interface InlineCode extends Pos {
|
|
37
|
+
type: 'inlineCode';
|
|
38
|
+
value: string;
|
|
39
|
+
/** Number of backticks in the fence. */
|
|
40
|
+
ticks: number;
|
|
41
|
+
}
|
|
42
|
+
interface Link extends Pos {
|
|
43
|
+
type: 'link';
|
|
44
|
+
url: string;
|
|
45
|
+
title?: string;
|
|
46
|
+
children: Inline[];
|
|
47
|
+
}
|
|
48
|
+
interface Image extends Pos {
|
|
49
|
+
type: 'image';
|
|
50
|
+
url: string;
|
|
51
|
+
alt: string;
|
|
52
|
+
title?: string;
|
|
53
|
+
}
|
|
54
|
+
interface Autolink extends Pos {
|
|
55
|
+
type: 'autolink';
|
|
56
|
+
url: string;
|
|
57
|
+
}
|
|
58
|
+
interface LineBreak extends Pos {
|
|
59
|
+
type: 'break';
|
|
60
|
+
/** A hard break (two trailing spaces or backslash) vs a soft newline. */
|
|
61
|
+
hard: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Inline math (`$…$` inline, `$$…$$` inline-display). Opt-in via {@link ParseOptions.math}. */
|
|
64
|
+
interface Math extends Pos {
|
|
65
|
+
type: 'math';
|
|
66
|
+
/** The TeX source between the delimiters (delimiters excluded). */
|
|
67
|
+
value: string;
|
|
68
|
+
/** `true` for a `$$…$$` display span, `false` for a `$…$` inline span. */
|
|
69
|
+
display: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** A footnote reference `[^id]`. Opt-in via {@link ParseOptions.footnotes}. */
|
|
72
|
+
interface FootnoteRef extends Pos {
|
|
73
|
+
type: 'footnoteRef';
|
|
74
|
+
/** The referenced footnote label (between `[^` and `]`). */
|
|
75
|
+
id: string;
|
|
76
|
+
}
|
|
77
|
+
type Inline = TextNode | Emphasis | Strong | Strikethrough | InlineCode | Link | Image | Autolink | LineBreak | Math | FootnoteRef;
|
|
78
|
+
interface Heading extends Pos {
|
|
79
|
+
type: 'heading';
|
|
80
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
81
|
+
/** Offset just past the `#`… marker + following space (start of content). */
|
|
82
|
+
contentFrom: number;
|
|
83
|
+
children: Inline[];
|
|
84
|
+
}
|
|
85
|
+
interface Paragraph extends Pos {
|
|
86
|
+
type: 'paragraph';
|
|
87
|
+
children: Inline[];
|
|
88
|
+
}
|
|
89
|
+
interface Blockquote extends Pos {
|
|
90
|
+
type: 'blockquote';
|
|
91
|
+
children: Block[];
|
|
92
|
+
}
|
|
93
|
+
type TaskState = 'checked' | 'unchecked' | null;
|
|
94
|
+
interface ListItem extends Pos {
|
|
95
|
+
type: 'listItem';
|
|
96
|
+
/** Task-list state, or null for a plain item. */
|
|
97
|
+
task: TaskState;
|
|
98
|
+
/** Offset just past the list marker (`- `, `1. `, `- [x] `). */
|
|
99
|
+
contentFrom: number;
|
|
100
|
+
children: Block[];
|
|
101
|
+
}
|
|
102
|
+
interface List extends Pos {
|
|
103
|
+
type: 'list';
|
|
104
|
+
ordered: boolean;
|
|
105
|
+
/** Start number for an ordered list. */
|
|
106
|
+
start: number;
|
|
107
|
+
/** Loose lists wrap items in paragraphs; tight lists don't. */
|
|
108
|
+
tight: boolean;
|
|
109
|
+
items: ListItem[];
|
|
110
|
+
}
|
|
111
|
+
interface CodeBlock extends Pos {
|
|
112
|
+
type: 'codeBlock';
|
|
113
|
+
/** Info string after the opening fence (may be empty). */
|
|
114
|
+
lang: string;
|
|
115
|
+
value: string;
|
|
116
|
+
fenced: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface ThematicBreak extends Pos {
|
|
119
|
+
type: 'thematicBreak';
|
|
120
|
+
}
|
|
121
|
+
type CellAlign = 'left' | 'center' | 'right' | null;
|
|
122
|
+
interface TableCell extends Pos {
|
|
123
|
+
type: 'tableCell';
|
|
124
|
+
children: Inline[];
|
|
125
|
+
}
|
|
126
|
+
interface Table extends Pos {
|
|
127
|
+
type: 'table';
|
|
128
|
+
align: CellAlign[];
|
|
129
|
+
header: TableCell[];
|
|
130
|
+
rows: TableCell[][];
|
|
131
|
+
}
|
|
132
|
+
/** Raw HTML or an MDX/JSX/ESM region — kept verbatim (markup only, not evaluated). */
|
|
133
|
+
interface HtmlBlock extends Pos {
|
|
134
|
+
type: 'htmlBlock';
|
|
135
|
+
value: string;
|
|
136
|
+
/** `html` for raw HTML, `mdxFlow` for a JSX element / ESM line at block level. */
|
|
137
|
+
variant: 'html' | 'mdxFlow';
|
|
138
|
+
}
|
|
139
|
+
/** A `$$…$$` display-math block. Opt-in via {@link ParseOptions.math}. */
|
|
140
|
+
interface MathBlock extends Pos {
|
|
141
|
+
type: 'mathBlock';
|
|
142
|
+
/** The TeX source between the `$$` fences (fences excluded). */
|
|
143
|
+
value: string;
|
|
144
|
+
}
|
|
145
|
+
/** A footnote definition `[^id]: …`. Opt-in via {@link ParseOptions.footnotes}. */
|
|
146
|
+
interface FootnoteDef extends Pos {
|
|
147
|
+
type: 'footnoteDef';
|
|
148
|
+
/** The footnote label (between `[^` and `]`). */
|
|
149
|
+
id: string;
|
|
150
|
+
children: Block[];
|
|
151
|
+
}
|
|
152
|
+
/** A single term + one-or-more definitions inside a {@link DefList}. */
|
|
153
|
+
interface DefItem extends Pos {
|
|
154
|
+
type: 'defItem';
|
|
155
|
+
term: Inline[];
|
|
156
|
+
/** Each `: …` definition, parsed as its own block sequence. */
|
|
157
|
+
definitions: Block[][];
|
|
158
|
+
}
|
|
159
|
+
/** A definition list — terms with `: …` definitions. Opt-in via {@link ParseOptions.defLists}. */
|
|
160
|
+
interface DefList extends Pos {
|
|
161
|
+
type: 'defList';
|
|
162
|
+
items: DefItem[];
|
|
163
|
+
}
|
|
164
|
+
type Block = Heading | Paragraph | Blockquote | List | CodeBlock | ThematicBreak | Table | HtmlBlock | MathBlock | FootnoteDef | DefList;
|
|
165
|
+
interface Document extends Pos {
|
|
166
|
+
type: 'document';
|
|
167
|
+
children: Block[];
|
|
168
|
+
}
|
|
169
|
+
type AstNode = Document | Block | ListItem | TableCell | DefItem | Inline;
|
|
170
|
+
/**
|
|
171
|
+
* Opt-in parser extensions. Every flag defaults to `false`, so `parse(src)`
|
|
172
|
+
* behaves exactly as it always has; enabling a flag lights up the matching
|
|
173
|
+
* construct (and nothing else). Kept semver-safe so a later wave can turn these
|
|
174
|
+
* on from configuration without a breaking parser change.
|
|
175
|
+
*/
|
|
176
|
+
interface ParseOptions {
|
|
177
|
+
/** Parse `$…$` inline and `$$…$$` block math. */
|
|
178
|
+
math?: boolean;
|
|
179
|
+
/** Parse `[^id]` footnote references and `[^id]: …` definitions. */
|
|
180
|
+
footnotes?: boolean;
|
|
181
|
+
/** Parse `term` / `: definition` definition lists. */
|
|
182
|
+
defLists?: boolean;
|
|
183
|
+
}
|
|
184
|
+
declare function isInline(node: AstNode): node is Inline;
|
|
185
|
+
/** Depth-first walk over the tree; return false from `visit` to skip children. */
|
|
186
|
+
declare function walk(node: AstNode, visit: (node: AstNode) => boolean | void): void;
|
|
187
|
+
declare function childrenOf(node: AstNode): AstNode[];
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Editing commands — pure transforms over `(text, selection)` used by the
|
|
191
|
+
* formatting toolbar and keyboard shortcuts. Each returns the new text and the
|
|
192
|
+
* new selection, so the caller (edit textarea / unified active block) can apply
|
|
193
|
+
* it and restore the caret. Pure and framework-free — fully unit-testable.
|
|
194
|
+
*/
|
|
195
|
+
type Command = 'bold' | 'italic' | 'strikethrough' | 'inlineCode' | 'link' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'bulletList' | 'orderedList' | 'taskList' | 'quote' | 'horizontalRule' | 'codeBlock' | 'table';
|
|
196
|
+
/** Metadata describing a command for enumerable surfaces (toolbar, palette, keymap). */
|
|
197
|
+
interface CommandMeta {
|
|
198
|
+
id: Command;
|
|
199
|
+
label: string;
|
|
200
|
+
/** Display shortcut (e.g. `⌘B`) when one is bound; omitted otherwise. */
|
|
201
|
+
kbd?: string;
|
|
202
|
+
group: 'inline' | 'block' | 'insert';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The single source of truth enumerating every command — consumed by the
|
|
206
|
+
* formatting toolbar, the command palette, and the keymap. Plain data, no side
|
|
207
|
+
* effects; one entry per `Command` id (kept exhaustive by the `applyCommand`
|
|
208
|
+
* `never` guard, which forces new ids to exist before they can be listed here).
|
|
209
|
+
*/
|
|
210
|
+
declare const COMMANDS: readonly CommandMeta[];
|
|
211
|
+
interface Sel {
|
|
212
|
+
from: number;
|
|
213
|
+
to: number;
|
|
214
|
+
}
|
|
215
|
+
interface CommandResult {
|
|
216
|
+
text: string;
|
|
217
|
+
selection: Sel;
|
|
218
|
+
}
|
|
219
|
+
declare function applyCommand(text: string, sel: Sel, cmd: Command): CommandResult;
|
|
220
|
+
|
|
221
|
+
export { type AstNode as A, type Block as B, type CellAlign as C, type Document as D, type Emphasis as E, type FootnoteDef as F, isInline as G, type Heading as H, type Inline as I, walk as J, type LineBreak as L, type Math as M, type ParseOptions as P, type Sel as S, type Table as T, type Pos as a, type Autolink as b, type Blockquote as c, COMMANDS as d, type CodeBlock as e, type Command as f, type CommandResult as g, type DefItem as h, type DefList as i, type FootnoteRef as j, type HtmlBlock as k, type Image as l, type InlineCode as m, type Link as n, type List as o, type ListItem as p, type MathBlock as q, type Paragraph as r, type Strikethrough as s, type Strong as t, type TableCell as u, type TaskState as v, type TextNode as w, type ThematicBreak as x, applyCommand as y, childrenOf as z };
|