/** * CloudFormation registry oracle — resolves the authoritative * `createOnlyProperties` / `conditionalCreateOnlyProperties` / * `primaryIdentifier` catalogue for a resource type via * `cloudformation:DescribeType`. * * The registry is the ground truth the deploy plan's replacement verdicts are * recomputed against: the CDK resource spec bundled into * `@aws-cdk/cloudformation-diff` is provably stale (e.g. a false WILL_REPLACE * on `AWS::RDS::DBInstance.Port`). Resolution order: * * in-memory (per run) → disk cache (7-day TTL, atomic writes) → live * DescribeType → stale disk cache → baked seed snapshot * * Failure at every tier degrades — the caller annotates the affected rows * `verdictSource: "cdk-spec (unverified)"` and the deploy proceeds; the oracle * never fails a deploy by being unavailable. */ import { type Result } from "@fjall/generator"; import type { AwsProvider } from "../../aws/AwsProvider.js"; /** Replacement-relevant slice of a registry resource schema. */ export interface CfnRegistrySchemaSummary { typeName: string; /** JSON pointers (`/properties/X`, possibly nested) that force replacement. */ createOnlyProperties: string[]; /** JSON pointers that MAY force replacement depending on the transition. */ conditionalCreateOnlyProperties: string[]; /** JSON pointers identifying the resource (not always the naming property). */ primaryIdentifier: string[]; } /** * The narrow read surface the plan overlay needs — CfnRegistryService * satisfies it; tests substitute a stub. */ export interface CfnRegistrySummaryReader { getSchemaSummary(typeName: string, abortSignal?: AbortSignal): Promise>; } export interface CfnRegistryServiceOptions { /** Cache root; defaults to `~/.fjall/cache/cfn-registry`. */ cacheDir?: string; /** Disk-cache freshness window; defaults to 7 days. */ cacheTtlMs?: number; /** Baked seed override (defaults to the generated snapshot). */ seed?: Readonly>; /** Injectable clock for TTL tests. */ now?: () => number; } export declare class CfnRegistryService implements CfnRegistrySummaryReader { private readonly aws; private readonly cacheDir; private readonly cacheTtlMs; private readonly seed; private readonly now; private readonly memory; constructor(aws: AwsProvider, options?: CfnRegistryServiceOptions); getSchemaSummary(typeName: string, abortSignal?: AbortSignal): Promise>; private isFresh; private cachePath; private describeType; /** A corrupt, missing, or unreadable cache file is a miss — never a crash. */ private readCache; /** * Atomic tmp + rename — the cache dir can be shared by concurrent deploys * (CLI sessions, worker containers), so a reader must never see a partial * write. Failures are best-effort: logged and discarded. */ private writeCache; }