import { PgpmScriptKind } from '@pgpmjs/ast/module/types'; import { CreateBundleOptions } from './create'; import { MigrationBundle } from './types'; /** Identifies a script while it is being transformed. */ export interface TranspileScriptContext { /** Change name in the *source* bundle. */ change: string; kind: PgpmScriptKind; } export interface TranspileBundleOptions extends CreateBundleOptions { /** * Rewrite a change's name (its plan identity / path). Return the same name to * leave it unchanged. Used to move changes into a new namespace, e.g. * `schemas/app/tables/users` -> `schemas/tenant/tables/users`. * * The mechanical consequences — plan change lines + dependency refs, and each * script's `-- Deploy`/`-- requires:` header — are rewritten for you; only the * SQL statement bodies are the caller's concern via {@link transformScript}. */ renameChange?: (name: string) => string; /** * Rewrite a script's SQL body. This is where the AST-level namespace remap * lives (schema names, fully-qualified references, RLS/FK targets, function * bodies) — core stays parser-agnostic and defers the actual transform to the * caller, exactly like `rebundle`'s `categoryOf`. The passed SQL already has * its header rewritten for any change rename. */ transformScript?: (sql: string, ctx: TranspileScriptContext) => string; /** * Rewrite the `.control` file content (default: unchanged). Control `requires` * are extension deps, not change names, so they are left alone unless a caller * opts in here. */ transformControl?: (content: string, fileName: string) => string; /** * Give the transpiled bundle a new module identity: rewrites the manifest * name, the plan `%project=`/`%uri=` headers, and the `.control` file name. * Used to instance a source module under a consumer-chosen name (e.g. * `users-module` applied as `tenant-users`), so registry attribution and * dependency references land on the instance instead of the source. */ renameModule?: string; /** * Select changes to drop from the transpiled bundle entirely (return `true` * to exclude). Excluded changes are removed from the change list, deploy * order, and plan, and their name is pruned from every surviving change's * dependencies (plan brackets included). * * This is the mechanism behind subsystem exclusion in apply: an excluded * subsystem is genuinely absent from the artifact rather than emitted as an * empty script. Empty tombstones are indistinguishable by content, so they * collide on the deploy ledger's `(package, script_hash)` uniqueness — a * dropped change has no script to hash. Cascade safety (no survivor still * references a dropped object) is the caller's responsibility. */ excludeChange?: (name: string) => boolean; } /** * Transpile a {@link MigrationBundle} into a new namespace, producing a fresh * content-addressed bundle. * * Pure and deterministic (no I/O). Composes the existing rename primitives * (`renameInHeader`, `renameInPlanContent`) for the mechanical change-name/plan * rewrite and defers SQL-body rewriting to the caller-supplied * {@link TranspileBundleOptions.transformScript}. Digests are recomputed from * the transformed SQL so the result is independently verifiable, and the source * bundle's digest is recorded in `provenance.sourceBundleDigest` for lineage. */ export declare function transpileBundle(bundle: MigrationBundle, options?: TranspileBundleOptions): MigrationBundle;