import { FoldLine, FoldableRange, Indentation, LineRange, SupportedLanguage } from "@ngrok/mantle/highlight-utils"; import { createHighlighter } from "shiki"; import "oxc-parser"; /** * Shiki grammar IDs preloaded by Mantle's highlighting engine. * This list is shared by both Vite plugins and server-side highlighting routes. */ declare const mantleShikiLanguageGrammarIds: ["bash", "csharp", "css", "dotenv", "go", "html", "java", "javascript", "json", "jsx", "python", "ruby", "rust", "shell", "terraform", "tsx", "typescript", "xml", "yaml"]; /** * Shared Shiki theme name used across Mantle highlighting. */ declare const mantleShikiThemeName: "mantle-css-variables"; declare const mantleHighlightCacheMaxEntries = 1000; type ShikiHighlighter = Awaited>; type MantleHighlightInput = { /** * Raw code string to highlight. */ code: string; /** * Language hint. Accepts supported language aliases and markdown-style values. */ language: SupportedLanguage | (string & {}); /** * Optional indentation preference. Defaults to language-inferred indentation. */ indentation?: Indentation; /** * Whether to render line numbers into the returned HTML. * @default true */ showLineNumbers?: boolean; /** * Optional list of highlighted line numbers/ranges to render into the returned HTML. * @default [] */ highlightLines?: (LineRange | number)[]; /** * Start line number for rendered line numbers. * @default 1 */ lineNumberStart?: number; }; type MantleHighlightResult = { /** * Normalized source code used as the highlight input. */ code: string; /** * Highlighted HTML extracted from Shiki's `...`. */ html: string; /** * Resolved supported language used for highlighting. */ language: SupportedLanguage; /** * Whether returned HTML includes line numbers. */ showLineNumbers: boolean; /** * Highlighted line numbers/ranges applied to the returned HTML. */ highlightLines: (LineRange | number)[]; /** * Start line number used for rendered line numbers. */ lineNumberStart: number; }; type MantleServerHighlighter = { /** * Highlight a code snippet and return normalized code + highlighted HTML. */ highlight: (input: MantleHighlightInput) => Promise; }; /** * Creates (and caches) Mantle's shared Shiki highlighter instance. */ declare function getMantleShikiHighlighter(): Promise; /** * Highlights code with Mantle's shared Shiki engine and normalization defaults. */ declare function highlightWithMantleShiki(input: MantleHighlightInput): Promise; /** * Creates a reusable Mantle server highlighter facade for API routes. */ declare function createMantleServerSyntaxHighlighter(): MantleServerHighlighter; /** * Server-side folding strategy applied to a language. This is a richer * dispatch than `@ngrok/mantle/highlight-utils`'s `foldStrategyFor`: * * - `jsx-ast` parses JS / TS / JSX / TSX with `oxc-parser`. * - `html-ast` parses HTML / XML with `parse5`. * - `css-raw` runs a CSS-aware single-pass brace matcher. * - `json-raw` reuses the existing `computeJsonFoldRanges` (raw, scope-free). * - `token-bracket` / `token-indentation` are the existing token-based * strategies for languages without a heavier parser (Go, Rust, Java, C#, * Python, YAML). * - `token-keyword` matches keyword openers / closers against tokenized line * text (Bash / Shell). * - `token-bracket-and-keyword` runs the bracket pass *and* the keyword pass * and merges them — Ruby uses brace-style blocks (`{ |x| … }`) plus * keyword blocks (`def … end`). * - `none` opts out for plain text and unknown languages. * * Strategies suffixed `-ast` or `-raw` need only the raw source string; * `token-*` strategies need Shiki-tokenized lines with scope explanations. */ type ServerFoldStrategy = "jsx-ast" | "html-ast" | "css-raw" | "json-raw" | "token-bracket" | "token-indentation" | "token-keyword" | "token-bracket-and-keyword" | "none"; /** Returns the server fold strategy for the given supported language. */ declare function serverFoldStrategyFor(language: SupportedLanguage): ServerFoldStrategy; /** * Returns true when the strategy needs Shiki-tokenized lines (with scope * explanations) to run. AST and raw-source strategies operate on the source * string directly and let us skip the `includeExplanation: 'scopeName'` * Shiki option, saving meaningful work on JS/TS/HTML/CSS hot paths. */ declare function serverFoldNeedsTokens(strategy: ServerFoldStrategy): boolean; /** * Computes foldable ranges for a single highlighted code block, dispatching * to the appropriate strategy. Every supported language flows through here, * including the legacy token-based ones, so the engine has a single decision * point. * * Caller contract: * - For token-needing strategies, `tokens` must be the lines produced by * Shiki with `includeExplanation: 'scopeName'`. Pass `undefined` and the * strategy returns `[]`. * - For raw / AST strategies, `tokens` is ignored; only `code` matters. * * Errors raised by underlying parsers are caught and converted into "no * folds" — Shiki still gets to render the highlighted code, the gutter just * skips the toggle. We log nothing here because the engine is the wrong * layer to surface diagnostics. */ declare function computeServerFoldRanges({ code, language, tokens }: { /** Normalized source code (post-`normalizeIndentation`). */ code: string; /** Resolved Mantle supported language. */ language: SupportedLanguage; /** Shiki-tokenized lines, when the strategy needs them. */ tokens: FoldLine[] | undefined; }): FoldableRange[]; /** * AST-based fold computer for the JS/TS/JSX/TSX language family. * * Mirrors VS Code's TypeScript language service folder by walking the parsed * AST instead of pairing brackets in the token stream. This lets us fold * constructs that bracket-pairing can't see: * * - JSX elements (`…`, fragments, members like ``). * - Template literals that span multiple lines (including tagged templates). * * It also keeps every fold the bracket strategy used to give us — block * statements, object literals, array literals, class/interface bodies, switch * statements — without the per-character scope-walk cost. * * @see https://github.com/microsoft/vscode/blob/main/extensions/typescript-language-features/src/languageFeatures/folding.ts */ /** Subset of supported languages handled by this computer. */ type JsxFoldLanguage = "javascript" | "js" | "typescript" | "ts" | "jsx" | "tsx"; /** * Computes foldable ranges for a JS/TS/JSX/TSX source string by parsing it * with `oxc-parser` and walking the AST. Errors are tolerated — a partial AST * still produces useful folds. * * @example * computeJsxFoldRanges({ code: "\n \n", language: "tsx" }); * // => [{ id: "1", startLine: 1, endLine: 3 }] */ declare function computeJsxFoldRanges({ code, language }: { /** Raw source code to parse and fold. */ code: string; /** Resolved Mantle language; controls grammar selection (TS vs JS, JSX vs plain). */ language: JsxFoldLanguage; }): FoldableRange[]; /** * AST-based fold computer for HTML and XML. * * Uses `parse5` with `sourceCodeLocationInfo: true` so each element node carries * the line numbers of its open and close tags. Walking the tree gives us: * * - One fold per multi-line element (`
…
`). * - One fold per multi-line opening tag (`` — the * attribute list collapses). * - Correct void-element handling — parse5 already knows that `
`, ``, * etc. don't open folds. * - Template content traversal — parse5 stores `