import { type MetaObject, type MetaReferenceIdentity, type MetaData } from "@metaobjectsdev/metadata"; import type { FkAction } from "./types.js"; export declare function readIdentityFields(identity: MetaData): string[]; export declare function findField(entity: MetaObject, name: string): MetaData | undefined; export declare function isRequired(field: MetaData): boolean; /** * Resolve the referential actions for a foreign key inferred from an * identity.reference. * * Precedence (highest first): * 1. @onDelete / @onUpdate declared DIRECTLY on the identity.reference — the * reference IS the FK, so the action may be declared right where the FK is. * 2. A correlated sibling relationship on the same entity — matched * package-aware against the resolved @references target (refMatchesObject * / ADR-0042, so bare and FQN forms pair correctly); an M:N relationship * (@through) never correlates with a direct FK. Its explicit @onDelete, * else its subtype default (composition→cascade, aggregation→set-null, * association→restrict); onUpdate defaults to "cascade". * 3. A correlated REVERSE relationship on the TARGET entity — the documented * parent-side authoring shape ("Program owns weeks": composition declared * on the parent with @objectRef back at this FK-owning entity). Same * explicit-action-else-subtype-default resolution as tier 2. Guards: * an M:N relationship (@through) never correlates (it describes the * junction path, not this direct FK); when the FK-owning entity holds * MORE THAN ONE enforced reference to the same target the reverse * relationship contributes nothing (it cannot say which FK carries the * ownership edge — arming all of them could cascade through an edge the * author never designated; fail closed); and an INFERRED set-null default * (parent-side aggregation, no explicit @onDelete) on a NOT NULL FK drops * the INFERRED contributions only — an authored @onUpdate on that same * relationship still applies (see the in-body guard comment). * 4. None → undefined (no ON DELETE / ON UPDATE clause). * * - Resolved "no-action" → undefined: introspection in introspect/{postgres,sqlite}.ts * omits actions when the DB value is "no-action", so the expected side does the same * to keep round-trip diffs clean. * * If multiple relationships target the same entity (rare), the first one is used. * * The single `as FkAction` cast in normalize() is safe because REFERENTIAL_ACTIONS * (metadata package) and FkAction (migrate-ts/src/types.ts) are the same four-value * set: "cascade" | "set-null" | "restrict" | "no-action". The invariant is * documented in relationship-constants.ts and enforced by both the type system * (FkAction is the union literal) and a runtime-set-equality test in * referential-actions.test.ts. */ export declare function resolveReferentialActions(entity: MetaObject, ref: MetaReferenceIdentity): { onDelete: FkAction | undefined; onUpdate: FkAction | undefined; }; /** * Validate that a FK whose resolved ON DELETE action is "set-null" does not * contain any NOT NULL column. * * ON DELETE SET NULL requires all FK columns to be nullable. Postgres and * SQLite both reject the combination at DDL execution time. * * Call this from buildExpectedSchema AFTER resolving the referential action * (i.e. after resolveReferentialActions) so that explicit overrides such as * @onDelete: "restrict" are already applied before the check. * * @param entity The owning entity. * @param ref The identity.reference node being processed. * @param onDelete The resolved onDelete action (undefined = no-action). * @param constraintName The FK constraint name as it will appear in the DDL. */ export declare function validateSetNullNullability(entity: MetaObject, ref: MetaReferenceIdentity, onDelete: FkAction | undefined, constraintName: string): void; //# sourceMappingURL=referential-actions.d.ts.map