import type { CloudConfig, SiteConfig, SiteDeployTarget } from '@ts-cloud/core';
/**
 * The three resolved deployment kinds for a site:
 *  - `'bucket'`        — upload built `root` to object storage + CDN.
 *  - `'server-app'`    — `server` + `start`: dynamic app as a systemd service.
 *  - `'server-static'` — `server` + no `start` (has static `root`): a static
 *                        site built and shipped to `/var/www/<site>` on the box
 *                        (served by the operator's own proxy, e.g. rpx + tlsx).
 *  - `'redirect'`      — gateway-only: `redirect` is set. Nothing is shipped;
 *                        the gateway answers `domain` with an HTTP redirect.
 */
export type SiteDeployKind = 'bucket' | 'server-app' | 'server-static' | 'server-php' | 'redirect';
/**
 * On-disk base directory for a site's atomic release tree
 * (`<base>/releases/<sha>` + `<base>/current`).
 *
 * Namespaced by the project **slug** so that on a shared / multi-tenant box
 * (`cloud.attachTo`) two projects — or a tenant and the box owner — can never
 * collide on the same `/var/www/<name>` path. A bare `/var/www/<siteName>`
 * meant that e.g. every project with a `main` site fought over `/var/www/main`,
 * silently overwriting each other's releases and round-robining stale responses
 * on the shared port. This mirrors the systemd unit naming (`<slug>-<siteName>`)
 * so a release directory and the service that runs it share one identity.
 *
 * MUST be the single source of truth for the install path — deploy, rpx routing
 * (server-static), rollback/ops, and dashboard data all derive from it, so they
 * can never diverge.
 */
export declare function siteInstallBase(slug: string, siteName: string): string;
/**
 * A PHP/Laravel site: deployed to the compute box via git clone into atomic
 * release directories and served by nginx + php-fpm. Identified by a PHP
 * `type` (laravel/php/statamic/wordpress).
 */
export declare function isPhpSite(site: SiteConfig): boolean;
/**
 * Resolve the explicit-or-inferred {@link SiteDeployTarget} for a site.
 *
 * Inference (backward compatible):
 *  1. an explicit `site.deploy` always wins;
 *  2. else if `start` is present → `'server'`;
 *  3. else → `'bucket'`.
 */
export declare function resolveSiteDeployTarget(site: SiteConfig): SiteDeployTarget;
/**
 * Resolve the fine-grained {@link SiteDeployKind} for a site, combining the
 * {@link resolveSiteDeployTarget} target with the presence of `start`.
 *
 * - `bucket`                       → `'bucket'`
 * - `server` + `start`            → `'server-app'`
 * - `server` + no `start`         → `'server-static'`
 */
export declare function resolveSiteKind(site: SiteConfig): SiteDeployKind;
export interface DeploymentValidationResult {
    errors: string[];
    warnings: string[];
}
/**
 * Validate the per-site deployment configuration up front, turning what used to
 * be silent runtime failures (e.g. a `start` site with no compute server) into
 * an explicit, actionable contract.
 *
 * Never throws — returns structured `{ errors, warnings }`. Callers should abort
 * on any error and print warnings while continuing.
 */
export declare function validateDeploymentConfig(config: CloudConfig): DeploymentValidationResult;
/**
 * Does this site produce a release the compute deploy has to build, package and
 * ship?
 *
 * `false` for the two kinds that ship nothing:
 *  - `bucket`   — handled by the S3/CloudFront static-site path instead;
 *  - `redirect` — the gateway answers the domain with a Location header, so
 *    there is no `root` to package. Filtering these BEFORE the packaging loop
 *    matters: that loop reads `site.root` to build a tarball, and a redirect
 *    site has none, which failed the whole deploy with
 *    "Build output not found at undefined".
 *
 * Excluding a site here never drops its routes — the rpx gateway is
 * regenerated from the full `sites` model, not from this list.
 */
export declare function shipsARelease(site: SiteConfig): boolean;
