import type { Run402ReleaseConfig } from "../config.js";
import { LocalError } from "../errors.js";
import type { Run402AppHttpVerifySpec } from "../app-up.js";
import type { AssetSyncPruneConfirm, ContentRef, ContentSource, DatabaseSpec, FunctionSpec, I18nSpec, LocalDirRef, ReleaseSpec, SitePublicPathsSpec, SiteEmbeddingSpec } from "../namespaces/deploy.types.js";
export type LocalFileReferenceKind = "migration_sql" | "function_source" | "site_file" | "site_dir" | "asset";
export interface LocalFileReference {
    /** Dotted/bracketed path into the ReleaseSpec, e.g. `functions.replace.api.source`. */
    field_path: string;
    /** Absolute path the reference resolved to. */
    path: string;
    kind: LocalFileReferenceKind;
    /** `site_dir` references must be directories; everything else a file. */
    expects: "file" | "directory";
}
export interface MissingLocalFileReference {
    field_path: string;
    path: string;
    kind: LocalFileReferenceKind;
}
/** Collect every local filesystem reference a normalized ReleaseSpec carries. */
export declare function collectLocalFileReferences(spec: Partial<ReleaseSpec>): LocalFileReference[];
/** `stat` every local reference; returns the ones that are absent or of the wrong kind. */
export declare function findMissingLocalFileReferences(spec: Partial<ReleaseSpec>): Promise<MissingLocalFileReference[]>;
/**
 * Build the `MANIFEST_FILE_MISSING` envelope: the message names the first
 * missing file, `details.missing[]` lists all of them, and there is one
 * `create_file` next action per missing reference.
 */
export declare function manifestFileMissingError(missing: MissingLocalFileReference[], opts?: {
    manifestPath?: string;
}): LocalError;
/**
 * The `check_manifest` next action: `run402 up --check` validates the
 * manifest and prints the preflight (file references, the site inventory by
 * content type, function and migration counts) with no gateway call, so an
 * agent can confirm a fix before spending an upload.
 */
export declare function checkManifestNextAction(manifestPath?: string): Record<string, unknown>;
/**
 * Throw `MANIFEST_FILE_MISSING` when any local filesystem reference in the
 * normalized spec is absent. Cheap (one `stat` per reference) — run it in
 * `--check` / `--print-spec` and before any plan so a typo in `source.path`
 * or a site `{ path }` never reaches the gateway.
 */
export declare function assertLocalFileReferencesExist(spec: Partial<ReleaseSpec>, opts?: {
    manifestPath?: string;
}): Promise<void>;
/**
 * Typed ENOENT for an explicitly named manifest path: `MANIFEST_NOT_FOUND`
 * with `details.path` and a `create_manifest` next action pointing at it.
 */
export declare function manifestNotFoundError(path: string, context: string): LocalError;
export interface LoadExecutableDeployConfigOptions {
    /** Test/advanced override for executable config evaluation timeout. Defaults to 5000ms. */
    timeoutMs?: number;
    /** Test/advanced override for env helper values. Defaults to process.env. */
    env?: Record<string, string | undefined>;
}
export interface ExecutableDeployConfigMetadata {
    env_accessed: string[];
}
export type DeployManifestFileEntry = ContentSource | {
    path: string;
    contentType?: string;
    content_type?: string;
    data?: never;
} | {
    data: string | ContentSource;
    encoding?: "utf-8" | "base64";
    contentType?: string;
    content_type?: string;
};
export type DeployManifestFileSet = Record<string, DeployManifestFileEntry>;
interface DeployManifestMigrationBaseSpec {
    checksum?: string;
    sql?: string;
    sql_ref?: ContentRef;
    sql_path?: string;
    sql_file?: string;
    transaction?: "required" | "none";
}
export interface DeployManifestVersionedMigrationSpec extends DeployManifestMigrationBaseSpec {
    id: string;
    name?: never;
}
export interface DeployManifestContentTrackedMigrationSpec extends DeployManifestMigrationBaseSpec {
    /** Content-tracked migration name. The SDK compiles this to
     *  `<name>_<sha256(sql)[0:16]>`; SQL MUST be idempotent because changed
     *  content applies again against a database with prior versions. */
    name: string;
    id?: never;
}
export type DeployManifestMigrationSpec = DeployManifestVersionedMigrationSpec | DeployManifestContentTrackedMigrationSpec;
export interface DeployManifestDatabaseSpec {
    migrations?: DeployManifestMigrationSpec[];
    expose?: DatabaseSpec["expose"];
    zero_downtime?: boolean;
}
export interface DeployManifestFunctionSpec extends Omit<FunctionSpec, "source" | "files"> {
    source?: DeployManifestFileEntry;
    files?: DeployManifestFileSet;
}
export interface DeployManifestFunctionsSpec {
    replace?: Record<string, DeployManifestFunctionSpec>;
    patch?: {
        set?: Record<string, DeployManifestFunctionSpec>;
        delete?: string[];
    };
}
export type DeployManifestSiteSpec = {
    replace: DeployManifestFileSet | LocalDirRef;
    patch?: never;
    public_paths?: SitePublicPathsSpec;
    embedding?: SiteEmbeddingSpec | null;
} | {
    patch: {
        put?: DeployManifestFileSet | LocalDirRef;
        delete?: string[];
    };
    replace?: never;
    public_paths?: SitePublicPathsSpec;
    embedding?: SiteEmbeddingSpec | null;
} | {
    public_paths: SitePublicPathsSpec;
    replace?: never;
    patch?: never;
    embedding?: SiteEmbeddingSpec | null;
} | {
    embedding: SiteEmbeddingSpec | null;
    replace?: never;
    patch?: never;
    public_paths?: never;
};
export interface DeployManifestAssetPutEntry {
    key: string;
    /** SDK-input form. Either:
     *  - `source` = ContentSource (string / Uint8Array / { path }) — the
     *    SDK normalizer hashes + uploads via /content/v1/plans
     *  - `sha256` + `size_bytes` = wire form (bytes already in CAS) */
    source?: DeployManifestFileEntry;
    sha256?: string;
    size_bytes?: number;
    content_type?: string;
    visibility?: "public" | "private";
    immutable?: boolean;
}
export interface DeployManifestAssetSpec {
    put?: DeployManifestAssetPutEntry[];
    delete?: string[];
    sync?: {
        prefix: string;
        prune: true;
        confirm?: AssetSyncPruneConfirm;
    };
}
/**
 * One post-apply HTTP verification check. Mirrors the app-spec
 * `Run402AppHttpVerifySpec` shape (`app-up.ts`): `id` + (`path` or `url`) +
 * `expect.status`. The deploy-manifest flavor additionally accepts the
 * snake_case `expected_status` alias for `expect.status`.
 */
export interface DeployManifestVerifyHttpCheck {
    id: string;
    path?: string;
    url?: string;
    expect?: {
        status: number;
    };
    /** Snake-case alias for `expect.status`. Conflicting values are rejected. */
    expected_status?: number;
    retries?: number;
}
/**
 * Authoring-only top-level `verify` block. Stripped from the wire
 * `ReleaseSpec` (like `$schema`) and returned separately from
 * `normalizeDeployManifest` / `loadDeployManifest` so the `up` runner can
 * execute the checks after a successful apply.
 */
export interface DeployManifestVerifySpec {
    http?: DeployManifestVerifyHttpCheck[];
}
/** Normalized verify metadata: checks in the canonical app-spec shape. */
export interface NormalizedDeployManifestVerify {
    http: Run402AppHttpVerifySpec[];
}
export interface DeployManifestInput extends Omit<ReleaseSpec, "project_id" | "database" | "functions" | "site" | "assets" | "i18n"> {
    /** JSON Schema metadata for editors. Stripped before deploy planning. */
    $schema?: string;
    /** App-kit evidence metadata for humans/agents. Stripped before deploy planning. */
    "x-run402-omitted_features"?: unknown;
    /** Target project id. Optional here: an override or default project may supply it. */
    project_id?: string;
    database?: DeployManifestDatabaseSpec;
    functions?: DeployManifestFunctionsSpec;
    site?: DeployManifestSiteSpec;
    assets?: DeployManifestAssetSpec;
    /** Authoring-only post-apply HTTP verification. Never sent on the wire. */
    verify?: DeployManifestVerifySpec;
    /** Routed-locale-context slice. Omit to carry forward, `null` to clear,
     *  `{ default_locale, locales, detect?, unknown_locale_policy? }` to replace. */
    i18n?: I18nSpec | (Omit<I18nSpec, "defaultLocale" | "unknownLocalePolicy"> & {
        default_locale: string;
        unknown_locale_policy?: I18nSpec["unknownLocalePolicy"];
    }) | null;
    /** CLI/MCP manifest idempotency key, returned separately for deploy options. */
    idempotency_key?: string;
}
export interface NormalizeDeployManifestOptions {
    /** Aggregate missing local inputs before eager SQL normalization. */
    validateFiles?: boolean;
    /** Diagnostic source path for authoring-file checks. */
    manifestPath?: string;
    /** Base directory for relative `{ path }`, `sql_path`, and `sql_file` entries. Defaults to `process.cwd()`. */
    baseDir?: string;
    /** Explicit project override, equivalent to CLI `--project`. Conflicts with a different manifest project. */
    project?: string;
    /** Fallback project used only when the manifest omits `project_id`. */
    defaultProject?: string;
}
export interface LoadDeployManifestOptions extends Omit<NormalizeDeployManifestOptions, "baseDir"> {
    /** Test/advanced override for executable config evaluation timeout. Defaults to 5000ms. */
    executableTimeoutMs?: number;
    /** Test/advanced override for executable config env helper values. Defaults to process.env. */
    env?: Record<string, string | undefined>;
}
export interface NormalizedDeployManifest {
    /** SDK-native deploy spec ready for `r.project(id).apply(spec, opts)`. */
    spec: ReleaseSpec;
    /** Optional idempotency key from `idempotency_key` / `idempotencyKey`. */
    idempotencyKey?: string;
    /** Authoring-only verify metadata (stripped from `spec`). Present when the
     *  manifest declared a top-level `verify` block. */
    verify?: NormalizedDeployManifestVerify;
    /** Parsed manifest object supplied by the caller or loaded from disk. */
    manifest: DeployManifestInput;
    /** Absolute path when produced by `loadDeployManifest(path)`. */
    manifestPath?: string;
    /** Metadata captured while loading an explicit executable config. */
    config?: ExecutableDeployConfigMetadata;
}
export declare function loadDeployManifest(path: string, opts?: LoadDeployManifestOptions): Promise<NormalizedDeployManifest>;
export declare function loadExecutableDeployConfig(path: string, opts?: LoadExecutableDeployConfigOptions): Promise<Run402ReleaseConfig>;
export declare function normalizeDeployManifest(input: DeployManifestInput, opts?: NormalizeDeployManifestOptions): Promise<NormalizedDeployManifest>;
/** Collect authoring paths before eager SQL reads so every missing input is reported together. */
export declare function collectAuthoringFileReferences(input: unknown, baseDir: string): LocalFileReference[];
export {};
//# sourceMappingURL=deploy-manifest.d.ts.map