import ts from "typescript"; import { type ValModules } from "@valbuild/core"; /** * The filesystem seam `loadValModules` reads through. * * Defaults to `ts.sys`, i.e. the real filesystem. An editor integration (see * `@valbuild/language-server`) passes a host that overlays unsaved buffers, so * that evaluation sees what the user is looking at rather than what was last * saved. */ export type ValModulesHost = ts.ParseConfigHost & ts.ModuleResolutionHost; /** * Loads the project's root `val.modules.ts` (or `.js`) using Node's `vm` * module and returns its default export (a `ValModules` registry). * * This is a recursive CommonJS loader: the root modules file and every * relative `*.val.ts` / `val.config.ts` it (dynamically) imports are * transpiled to CommonJS and evaluated in a `vm` sandbox. Bare specifiers * (e.g. `@valbuild/core`) are resolved with the real Node `require` so the * user modules share the exact same `@valbuild/core` instance that * `extractValModules` uses. * * Mirrors the pattern already used by the CLI's `evalValConfigFile`. * * SECURITY: The `vm` context is NOT a security sandbox. It deliberately exposes * `process` and a `require` that falls back to the real Node resolver (so user * modules share the same `@valbuild/core` instance). This loader must therefore * only ever be used to evaluate the project's own first-party, trusted files * (`val.modules` and the local `*.val.ts`/`val.config.ts` it imports) — i.e. the * same trust level as running the project's build. It must never be used to * evaluate untrusted or third-party modules. */ export declare function loadValModules(projectRoot: string, host?: ValModulesHost): ValModules; /** * What a `*.val.ts` file that is NOT registered in `val.modules` turns out to * be. * * A file matching `*.val.ts` is not necessarily a Val module: the same * convention is used for shared schemas and other content-adjacent helpers, and * those are not meant to be registered. Only a file that actually default * exports a module is worth warning about; one that default exports something * else is a mistake, because nothing will ever load it. * * See {@link createValModuleFileInspector}. */ export type ValModuleFileInspection = /** No default export at all: not a Val module, and not trying to be one. */ { status: "no-default-export"; } /** A real Val module — `export default c.define(...)`. */ | { status: "val-module"; } /** A default export that is not a Val module, or that would not evaluate. */ | { status: "invalid"; message: string; }; /** * Inspects individual `*.val.{ts,js}` files, sharing one module cache and one * parsed tsconfig across every call. * * The default export is checked SYNTACTICALLY first and only evaluated if it is * there. That ordering is the point: a `.val.ts` with no default export is a * helper file, and evaluating it to learn that would be both wasted work and a * way to turn an unrelated top-level throw into a reported error. * * SECURITY: evaluation goes through the same `vm` loader as * {@link loadValModules} — see the warning there. Only ever point this at the * project's own first-party files. */ export declare function createValModuleFileInspector(projectRoot: string, host?: ValModulesHost): (absPath: string) => ValModuleFileInspection;