/** * Shared helper functions for Svelte preprocessors. * * Provides AST utilities for detecting static content, resolving imports, * managing import statements, and escaping strings for Svelte templates. * Used by `svelte_preprocess_mdz` in fuz_ui, `svelte_preprocess_fuz_code` * in fuz_code, and potentially other Svelte preprocessors. * * Uses `import type` from `svelte/compiler` for AST types only — no runtime * Svelte dependency. Consumers must have `svelte` installed for type resolution. * * @module */ import type { Expression, ImportDeclaration, ImportDefaultSpecifier, ImportSpecifier, VariableDeclaration } from 'estree'; import type { AST } from 'svelte/compiler'; /** Import metadata for a single import specifier. */ export interface PreprocessImportInfo { /** The module path to import from. */ path: string; /** Whether this is a default or named import. */ kind: 'default' | 'named'; } /** Information about a resolved component import. */ export interface ResolvedComponentImport { /** The `ImportDeclaration` AST node that provides this name. */ import_node: ImportDeclaration; /** The specific import specifier for this name. */ specifier: ImportSpecifier | ImportDefaultSpecifier; } /** * Finds an attribute by name on a component AST node. * * Iterates the node's `attributes` array and returns the first `Attribute` * node whose `name` matches. Skips `SpreadAttribute`, directive, and other node types. * * @returns the matching `Attribute` node, or `undefined` if not found */ export declare const find_attribute: (node: AST.Component, name: string) => AST.Attribute | undefined; /** * Recursively evaluates an expression AST node to a static string value. * * Handles string `Literal`, `TemplateLiteral` (including interpolations when all * expressions resolve), `BinaryExpression` with `+`, and `Identifier` lookup * via an optional bindings map built by `build_static_bindings`. * Returns `null` for dynamic expressions, non-string literals, or unsupported node types. * * @param expr - an ESTree expression AST node * @param bindings - optional map of variable names to their resolved static string values * @returns the resolved static string, or `null` if the expression is dynamic */ export declare const evaluate_static_expr: (expr: Expression, bindings?: ReadonlyMap) => string | null; /** * Extracts a static string value from a Svelte attribute value AST node. * * Handles three forms: * - Boolean `true` (bare attribute like `inline`) -- returns `null`. * - Array with a single `Text` node (quoted attribute like `content="text"`) -- * returns the text data. * - `ExpressionTag` (expression like `content={'text'}`) -- delegates to `evaluate_static_expr`. * * Returns `null` for null literals, mixed arrays, dynamic expressions, and non-string values. * * @param value - the attribute value from `AST.Attribute['value']` * @param bindings - optional map of variable names to their resolved static string values * @returns the resolved static string, or `null` if the value is dynamic */ export declare const extract_static_string: (value: AST.Attribute["value"], bindings?: ReadonlyMap) => string | null; /** A single branch in a conditional chain extracted from nested ternary expressions. */ export interface ConditionalChainBranch { /** The source text of the test expression, or `null` for the final else branch. */ test_source: string | null; /** The resolved static string value for this branch. */ value: string; } /** * Extracts a chain of conditional expressions where all leaf values are static strings. * * Handles nested ternaries like `a ? 'x' : b ? 'y' : 'z'` by iteratively walking * the right-recursive `ConditionalExpression` chain. At each level, evaluates the * consequent via `evaluate_static_expr` and continues into the alternate if it is * another `ConditionalExpression`. The final alternate is the else branch. * * Returns `null` if the attribute value is not an `ExpressionTag` containing a * `ConditionalExpression`, if any leaf fails to resolve to a static string, or * if the chain exceeds 10 branches (safety limit). * * A 2-branch result covers the simple ternary case (`a ? 'x' : 'y'`). * * @param value - the attribute value from `AST.Attribute['value']` * @param source - the full source string (needed to slice test expression source text) * @param bindings - map of variable names to their resolved static string values * @returns array of conditional chain branches, or `null` if not extractable */ export declare const try_extract_conditional_chain: (value: AST.Attribute["value"], source: string, bindings: ReadonlyMap) => Array | null; /** * Builds a map of statically resolvable `const` bindings from a Svelte AST. * * Scans top-level `const` variable declarations in both instance and module scripts. * For each declarator with a plain `Identifier` pattern and a statically evaluable * initializer, adds the binding to the map. Processes declarations in source order * so that chained references resolve: `const a = 'x'; const b = a;` maps `b` to `'x'`. * * Skips destructuring patterns, `let`/`var` declarations, and declarations * whose initializers reference dynamic values. * * @param ast - the parsed Svelte AST root node * @returns map of variable names to their resolved static string values */ export declare const build_static_bindings: (ast: AST.Root) => Map; /** * Resolves local names that import from specified source paths. * * Scans `ImportDeclaration` nodes in both the instance and module scripts. * Handles default, named, and aliased imports. Skips namespace imports * and `import type` declarations (both whole-declaration and per-specifier). * Returns import node references alongside names to support import removal. * * @param ast - the parsed Svelte AST root node * @param component_imports - array of import source paths to match against * @returns map of local names to their resolved import info */ export declare const resolve_component_names: (ast: AST.Root, component_imports: Array) => Map; /** * Finds the position to insert new import statements within a script block. * * Returns the end position of the last `ImportDeclaration`, or the start * of the script body content if no imports exist. */ export declare const find_import_insert_position: (script: AST.Script) => number; /** * Generates indented import statement lines from an import map. * * Default imports produce `import Name from 'path';` lines. * Named imports are grouped by path into `import {a, b} from 'path';` lines. * * @param imports - map of local names to their import info * @param indent - indentation prefix for each line @default '\t' * @returns a string of newline-separated import statements */ export declare const generate_import_lines: (imports: Map, indent?: string) => string; /** * Checks if an identifier with the given name appears anywhere in an AST subtree. * * Recursively walks all object and array properties of the tree, matching * ESTree `Identifier` nodes (`{type: 'Identifier', name}`). Nodes in the * `skip` set are excluded from traversal — used to skip `ImportDeclaration` * nodes so the import's own specifier identifier doesn't false-positive. * * Skips `Identifier` nodes in non-reference positions defined by * `NON_REFERENCE_FIELDS` — for example, `obj.Mdz` (non-computed member property), * `{ Mdz: value }` (non-computed object key), and statement labels. * * Safe for Svelte template ASTs: `Component.name` is a plain string property * (not an `Identifier` node), so `` tags do not produce false matches. * * @param node - the AST subtree to search * @param name - the identifier name to look for * @param skip - set of AST nodes to skip during traversal * @returns `true` if a matching `Identifier` node is found */ export declare const has_identifier_in_tree: (node: unknown, name: string, skip?: Set) => boolean; /** * Escapes text for safe embedding in Svelte template markup. * * Uses a single-pass regex replacement to avoid corruption that occurs with sequential * `.replace()` calls (where the second replace matches characters introduced by the first). * * Escapes four characters: * - `{` → `{'{'}` and `}` → `{'}'}` — prevents Svelte expression interpretation * - `<` → `<` — prevents HTML/Svelte tag interpretation * - `&` → `&` — prevents HTML entity interpretation * * The `&` escaping is necessary because runtime `MdzNodeView.svelte` renders text * with `{node.content}` (a Svelte expression), which auto-escapes `&` to `&`. * The preprocessor emits raw template text where `&` is NOT auto-escaped, so * manual escaping is required to match the runtime behavior. */ export declare const escape_svelte_text: (text: string) => string; /** * Removes a single-declarator `VariableDeclaration` from source using MagicString. * * Consumes leading whitespace (tabs/spaces) and trailing newline to avoid leaving * blank lines. Only safe for single-declarator statements (`const x = 'val';`); * callers must verify `node.declarations.length === 1` before calling. * * @param declaration_node - the `VariableDeclaration` AST node with Svelte position data * @mutates s - removes the declaration's character range */ export declare const remove_variable_declaration: (s: { remove: (start: number, end: number) => unknown; }, declaration_node: VariableDeclaration & { start: number; end: number; }, source: string) => void; /** * Removes an `ImportDeclaration` from source using MagicString. * * Consumes leading whitespace (tabs/spaces) and trailing newline to avoid leaving * blank lines. * * @param import_node - the `ImportDeclaration` AST node with Svelte position data * @mutates s - removes the declaration's character range */ export declare const remove_import_declaration: (s: { remove: (start: number, end: number) => unknown; }, import_node: ImportDeclaration & { start: number; end: number; }, source: string) => void; /** * Removes a specifier from a multi-specifier import declaration by * reconstructing the statement without the removed specifier. * * Overwrites the entire declaration range to avoid character-level comma surgery. * * Handles: * - `import Mdz, {other} from '...'` → `import {other} from '...'` * - `import {default as Mdz, other} from '...'` → `import {other} from '...'` * - `import {Mdz, other} from '...'` → `import {other} from '...'` * * @param additional_lines - extra content appended after the reconstructed import * (used to bundle new imports into the overwrite to avoid MagicString boundary conflicts). * @mutates s - overwrites the import declaration's character range */ export declare const remove_import_specifier: (s: { overwrite: (start: number, end: number, content: string) => unknown; }, node: ImportDeclaration & { start: number; end: number; }, specifier_to_remove: ImportDeclaration["specifiers"][number], source: string, additional_lines?: string) => void; /** * Handles errors during Svelte preprocessing with configurable behavior. * * @param prefix - log prefix (e.g. `'[fuz-mdz]'`, `'[fuz-code]'`) * @param on_error - `'throw'` to re-throw as a new Error, `'log'` to console.error * @throws Error wrapping `error` (with original as `cause`) when `on_error` is `'throw'` */ export declare const handle_preprocess_error: (error: unknown, prefix: string, filename: string | undefined, on_error: "throw" | "log") => void; //# sourceMappingURL=svelte_preprocess_helpers.d.ts.map