/** * A contract declares what environment variables a service requires. * The builder validates and maps the composed variable pool against each contract, * then generates a .env file at the service's location. * * Two contract formats are supported: * * **New format (vars):** Uses `${component.KEY}` references for direct resolution. * { "vars": { "REDIS_URL": "${redis.JOB_QUEUE_URL}" }, "defaults": { ... } } * * **Legacy format (required/optional/secret):** Uses NAMESPACE-prefixed flat pool. * { "required": { "REDIS_URL": "REDIS_JOB_QUEUE_URL" }, ... } */ export interface ServiceDevConfig { command: string; cwd?: string; label?: string; } export type ContractTarget = DockerComposeTarget | Pm2Target; export interface DockerComposeTarget { type: 'docker-compose'; file: string; service: string; config?: Record; profileOverrides?: Record>; subdomain?: string; dockerfile?: string; augment?: boolean; } export interface Pm2Target { type: 'pm2'; command: string; cwd?: string; label?: string; } export interface ServiceContract { name: string; location?: string; target?: ContractTarget; outputs?: Record; onlyProfiles?: string[]; includeVars?: string[]; vars?: Record; required?: Record; optional?: Record; secret?: Record; defaults?: Record; default?: string; ignoreDefault?: boolean; dev?: ServiceDevConfig; persistent?: boolean; serve?: { build: string; config?: Record; }; } /** * Detect whether a contract uses the new `vars` format or legacy `required` format. */ export declare function isNewFormatContract(contract: ServiceContract): boolean; export declare class ContractManager { private contractsDir; private contracts; constructor(configDir: string, envDir?: string); initialize(): Promise; /** * Check if any loaded contract uses the new vars format. */ hasNewFormatContracts(): boolean; private loadContracts; /** * Load a var set from env/contracts/{name}.vars.json. * Var sets contain { vars: Record, includeVars?: string[] }. */ private loadVarSet; /** * Resolve a var set's includes recursively, returning merged vars. * Detects cycles. Includes merge left-to-right, then the set's own vars on top. */ private resolveVarSet; /** * For every loaded contract with includeVars, resolve and merge the var sets * into the contract's vars. Contract's own vars always win. */ private resolveAllIncludeVars; /** * Validate a new-format contract against the component pool. * Component pool is Map>. */ validateVarsContract(serviceName: string, componentPool: Map>): { valid: boolean; missing: string[]; warnings: string[]; }; /** * Map a new-format contract's vars to resolved values using the component pool. */ mapVarsContract(serviceName: string, componentPool: Map>): Record; /** * Resolve a ${component.KEY} reference (or template with multiple refs) * against the component pool. * * Examples: * "${redis.JOB_QUEUE_URL}" → looks up redis component, key JOB_QUEUE_URL * "${secrets.REDIS_URL}" → looks up secrets namespace * "postgresql://${database.USER}:${secrets.DB_PASSWORD}@${database.HOST}:5432/${database.NAME}" */ private resolveComponentRef; /** * Validate that all required variables for a service are present in the pool. * Legacy format only. */ validateContract(serviceName: string, systemVars: Record): { valid: boolean; missing: string[]; warnings: string[]; }; /** * Map the resolved variable pool to a service's own variable names. * Supports direct mapping and template strings: "${HOST}:${PORT}" * Legacy format only. */ mapContractVariables(serviceName: string, systemVars: Record): Record; /** * Resolve a single var name, supporting fallback chains: "VAR1 : VAR2 : VAR3" */ private resolveVariable; /** * Resolve a mapping — direct variable name or template "${HOST}:${PORT}" */ private resolveMapping; getContracts(): Map; } //# sourceMappingURL=contracts.d.ts.map