/** A project row, reduced to what says how it deploys (camel or snake columns). */ export interface DeployProjectRow { runtimeMode?: string; runtime_mode?: string; gitRepoUrl?: string; git_repo_url?: string; gitBranch?: string; git_branch?: string; } /** A deployment row, reduced to what says what it was built from. */ export interface DeploySourceRow { id?: string | number; status?: string; createdAt?: string | Date; created_at?: string | Date; sourceRef?: string; source_ref?: string; bundleId?: string; bundle_id?: string; } export interface BareDeployPlan { /** * Whether the project runs the platform runtime — in which case any source * build here ejects it back onto a container image. */ managed: boolean; /** * `git` — the control plane will clone the configured repository. * `snapshot` — it will rebuild the newest uploaded source archive. * `none` — it holds neither, and will refuse. */ source: "git" | "snapshot" | "none"; /** Lines describing the build, printed before it is triggered. */ lines: string[]; } /** Rough age of a timestamp, for "…uploaded 6d ago". Undefined if unreadable. */ export declare function timeAgo(value: string | Date | undefined, now: Date): string | undefined; /** * Whether this project runs on the managed runtime. * * `runtimeMode` on the project row is the authority — the control plane writes * it. The bundle-id fallback covers a control plane that does not return the * field: a successful deploy that served a bundle only happens on the managed * path. */ export declare function isManagedProject(project: DeployProjectRow | undefined, latest: DeploySourceRow | undefined): boolean; /** What a `deploy` with nothing attached will build, in the words to print. */ export declare function planBareDeploy(project: DeployProjectRow | undefined, latest: DeploySourceRow | undefined, now: Date): BareDeployPlan; /** * A warning attached to a deploy: printed for the human, carried in the JSON. * * `code` is the stable half — the message is prose and will be reworded, so it * is the code that CI or an agent branches on. */ export interface DeployWarning { code: string; message: string; hint?: string; } /** `code` of the warning below, and the field name it sets in the payload. */ export declare const EJECTS_MANAGED_RUNTIME = "ejects_managed_runtime"; /** The one sentence that says a source build undoes `runtimeMode: managed`. */ export declare function ejectWarning(projectRef: string): DeployWarning; /** How a container-image deploy was asked for — the input to both rules below. */ export interface EjectContext { /** The project currently runs on the managed runtime. */ managed: boolean; /** `--source` was passed: build this directory. */ source: boolean; /** `--force` was passed: eject on purpose. */ force: boolean; } /** * Why a container-image deploy of a managed project is refused — or `undefined` * to let it through. * * Every path below this point builds a container image, and a successful one * sets `runtimeMode: "custom"` server-side. So the question is never "which flag * was used" but "did the caller ask to leave the managed runtime", and only * `--force` answers it. * * `--source` used to be read as answering it too, on the theory that uploading a * build context is self-evidently a deliberate eject. It is not: `--source` * picks *which source* gets built — this directory, rather than the stale * archive the control plane is holding — and the eject is a side effect of the * answer. That is exactly how a live project got flipped to `custom` by someone * whose actual intent was "deploy what I have here", and it is the same * ignorance the bare form is refused for. Same ignorance, same refusal. */ export declare function ejectRefusal(opts: EjectContext, projectRef: string): { message: string; hint: string; code: string; } | undefined; /** * Which warnings a container-image deploy has earned. * * Pure, and separate from the printing, because the printing is what went * wrong: the eject warning used to be written inline behind `!isJsonMode()`, so * the fact that a deploy ejects a managed project existed only as a side effect * of a TTY being attached. Deciding here, emitting once at the call site, means * the decision cannot be output-mode-dependent again. * * The condition is just `managed`: anything reaching this point is a container * image build that `ejectRefusal` has already let through, and on a managed * project that is an eject however it was spelled. A caller who passed `--force` * knows — the warning is for the transcript and the payload, which is what * anyone reviewing the deploy afterwards actually reads. */ export declare function deployWarnings(opts: EjectContext, projectRef: string): DeployWarning[]; /** The warning half of a deploy's JSON payload — merged into whatever it emits. */ export declare function warningPayload(warnings: DeployWarning[]): Record; export declare function deployCommand(rawArgs: string[], projectRef: string): Promise; export declare function logsCommand(rawArgs: string[], projectRef: string): Promise;