import type { CdkService } from "../infrastructure/CdkService.js"; import type { HungUpdateWatchOptions } from "../infrastructure/hungUpdateWatch.js"; import type { CloudFormationService } from "../infrastructure/CloudFormationService.js"; import type { AwsProvider } from "../../aws/AwsProvider.js"; import type { DeployCallbacks } from "../../types/callbacks.js"; import type { ResourceEvent } from "../../types/events.js"; import type { DeployParams } from "../../types/params.js"; import { type LeaseDeniedError } from "../../orchestration/application/leaseGate.js"; import type { DeploymentContext } from "../../types/deployment/DeploymentTypes.js"; import { type ApplicationStack } from "../../types/operations.js"; import type { ParallelDeploymentResult } from "../../types/deployment/parallel.js"; import { type Result } from "@fjall/generator"; import { ApplicationError, type StackDeploymentData } from "../../types/application/ApplicationServiceTypes.js"; import { type ApplicationDestroyPlan, type DestroyAllStacksCallbacks } from "./applicationStackHelpers.js"; interface StackCallbacks { onOutput?: (chunk: string) => void; onResourceProgress?: (event: ResourceEvent) => void; onLog?: DeployCallbacks["onLog"]; onStackCleanupProgress?: DeployCallbacks["onStackCleanupProgress"]; } interface DeployStackOptions { /** * CloudFormation `--parameters key=value` overrides forwarded verbatim to * `cdk deploy`. Used by the orchestrator to pin per-service ECS image * tags to the content-hash tag pushed in the preceding Docker phase. */ parameters?: Record; abortSignal?: AbortSignal; /** * Deploy only the named stack (`cdk deploy --exclusively`). Set on * parallel-phase deploys, where the orchestrator has already deployed the * shared dependency stack and sibling cdk processes must not race the * fixed-name changeset on it. */ exclusively?: boolean; /** * The deploy's ECS tail and a warning sink, so the engine can end an update * ECS rolled back and CloudFormation stopped driving (FJL-901). */ hungUpdate?: HungUpdateWatchOptions; } /** * What runs beside one stack's deploy: the deploy's ECS tail, as the events * it observes, the watch it hands the deploy, and the settling that ends it * before the stack's completion is reported. `settle` never rejects. */ export interface StackDeploySession { observe(event: ResourceEvent): void; readonly hungUpdate: HungUpdateWatchOptions; settle(outcome: { deploySucceeded: boolean; }): Promise; } interface ParallelStackCallbacks { onOutput?: (chunk: string, stackId: ApplicationStack) => void; onResourceProgress?: (event: ResourceEvent, stackId: ApplicationStack) => void; onLog?: DeployCallbacks["onLog"]; onStackCleanupProgress?: DeployCallbacks["onStackCleanupProgress"]; onStackComplete?: (stack: ApplicationStack, success: boolean, duration: number, error?: Error) => void; } /** * Service for deploying and destroying individual CloudFormation stacks. * * Handles single-stack deploy/destroy, parallel operations, and the full * destroy-all-stacks orchestration. * * Unlike the CLI version, services are constructor-injected rather than * fetched via singleton factories. */ export declare class ApplicationStackService { private cdkService; private cloudFormationService; private aws?; constructor(cdkService: CdkService, cloudFormationService: CloudFormationService, aws?: AwsProvider | undefined); /** * Delegate to CdkService.runCdkSynth — exposed for destroyAllStacks orchestration. */ runCdkSynth(context: DeploymentContext): ReturnType; /** * Deploy a specific stack type for an application */ deployStack(stackType: ApplicationStack, context: DeploymentContext, callbacks?: StackCallbacks, options?: DeployStackOptions): Promise>; /** * Deploy multiple stacks in parallel within a deployment phase. * * Uses Promise.allSettled to ensure all stacks are attempted even if some fail. * Each stack deploys beside its own session from `sessionFor`, settled * before the stack's completion is reported, as a sequential deploy's is. * Without `sessionFor`, the stacks deploy as they did before 39.0.6, with no * ECS tail and no hung-update watch; fjall's own deploy always passes it. */ deployStacksInParallel(stacks: readonly ApplicationStack[], context: DeploymentContext, callbacks?: ParallelStackCallbacks, sessionFor?: (stack: ApplicationStack) => StackDeploySession): Promise>; /** * Destroy a specific stack type */ destroyStack(stackType: ApplicationStack, context: DeploymentContext, callbacks?: StackCallbacks, useCdkOut?: boolean, abortSignal?: AbortSignal, assertLeaseForStack?: DeployParams["assertLeaseForStack"]): Promise>; /** * Destroy multiple stacks in parallel within a destroy phase. * * IMPORTANT: For parallel operations, useCdkOut must be true and CDK synth must * be run beforehand. Multiple CDK commands cannot run in parallel because they * all try to synthesise to the same cdk.out directory. */ destroyStacksInParallel(stacks: readonly ApplicationStack[], context: DeploymentContext, callbacks?: ParallelStackCallbacks, useCdkOut?: boolean, abortSignal?: AbortSignal): Promise>; /** * Get stack outputs for a deployed stack */ getStackOutputs(appName: string, stackType: ApplicationStack, abortSignal?: AbortSignal): Promise, ApplicationError>>; /** * Resolve the website URL for an application from CloudFormation stack outputs. * Checks Compute stack for LoadBalancer URL, then CDN stack for CloudFront distribution. */ resolveWebsiteUrl(appName: string): Promise; /** * Destroy all stacks for an application in reverse order. * Supports parallel destruction for OpenNext patterns (nextjs/payload). */ destroyAllStacks(context: DeploymentContext, plan: ApplicationDestroyPlan, callbacks?: DestroyAllStacksCallbacks, abortSignal?: AbortSignal, assertLeaseForStack?: DeployParams["assertLeaseForStack"]): Promise>; } export {};