/** * A bundler-neutral view of a client build, for the guards that must run on every pipeline. * * nifra's two client-leak guards - server-only code reaching the browser, and `node:` builtins in * client code - are the reason a pipeline choice is safe. They are security guards, not lints: one * stops secrets and database access shipping to a browser. Today both read Bun's metafile directly, * so a second production pipeline would either arrive without them or need them hastily ported, and * "mostly ported" is the wrong outcome for a guard of that kind. * * This is the seam that prevents that. It is introduced while Bun is still the ONLY producer, so the * adapter can be verified against the existing behaviour rather than written under pressure beside a * new bundler. Adding Rollup later becomes one more `from…` function rather than a second copy of the * detection logic. * * Deliberately minimal - exactly what the guards read, nothing more: * - which modules exist and what each imports (to walk the import chain to a sink) * - which output chunk each module landed in (to name the chunk a leak reached) */ /** One import edge, as the bundler recorded it. */ export interface GraphImport { /** The resolved path, when the bundler resolved it. */ readonly path?: string; /** The specifier as written in source - the only form that survives an unresolved import. */ readonly original?: string; } export interface GraphModule { readonly imports: readonly GraphImport[]; } export interface GraphChunk { /** Source module this chunk is the entry for, if it is one. */ readonly entryPoint?: string; /** Module ids that landed in this chunk. */ readonly modules: readonly string[]; } /** What a client build looks like to the guards, whichever bundler produced it. */ export interface ClientModuleGraph { /** Module id → its imports. Ids are bundler-native (Bun graph keys, Rollup module ids). */ readonly modules: Readonly>; /** Output path → what it contains. */ readonly chunks: Readonly>; } /** The slice of Bun's metafile this seam consumes. Not yet in `@types/bun`; shape per the docs. */ export interface BunMetafileLike { readonly inputs?: Readonly; }>>; readonly outputs?: Readonly>; }>>; } /** * Adapt a `Bun.build` metafile to the neutral graph. * * A total function: an absent or partial metafile yields an empty graph rather than throwing, because * a guard that crashes on an unexpected build shape fails the build for the wrong reason. An empty * graph reports no findings, which matches the existing behaviour when the metafile is missing. */ export declare function fromBunMetafile(meta: BunMetafileLike | undefined): ClientModuleGraph; /** * The slice of a Rollup/Vite output bundle this seam consumes. `OutputBundle` is * `Record`; only chunks carry a module graph. Typed structurally * (no `rollup`/`vite` type dependency) - the fields are stable Rollup output API. */ export interface RollupChunkLike { /** `"chunk"` for JS output, `"asset"` for CSS/static - assets have no module graph. */ readonly type?: string; /** The entry module id this chunk was built for, if it is an entry. Rollup's `facadeModuleId`. */ readonly facadeModuleId?: string | null; /** Every module id that landed in this chunk. Rollup's `moduleIds`. */ readonly moduleIds?: readonly string[]; } export type RollupBundleLike = Readonly>; /** * Adapt a Rollup/Vite output bundle to the neutral graph - the second producer the seam was built for. * * The bundle records which modules landed in which chunk (`moduleIds`) but NOT each module's import * edges, so those come from `importsOf`, which the caller backs with `this.getModuleInfo(id).importedIds` * inside a plugin hook (a test backs it with a plain map). Edges carry only the RESOLVED id - Rollup does * not keep the as-written specifier per edge - so `path` is set and `original` is left undefined. Both * guards read the resolved `path` as their fallback (a `node:` prefix, the `server-only` basename), so * detection is unaffected; only the human-readable chain shows resolved paths instead of as-written ones. * * Total, like {@link fromBunMetafile}: an empty bundle yields an empty graph (no findings), never a throw * that would fail a build for the wrong reason. */ export declare function fromRollupBundle(bundle: RollupBundleLike, importsOf: (moduleId: string) => readonly string[]): ClientModuleGraph; //# sourceMappingURL=module-graph.d.ts.map