import type { OrgAuth } from "../auth/sf-auth.ts"; import type { DescribeClient } from "../describe/client.ts"; import type { SObjectDescribe } from "../describe/types.ts"; import type { DependencyGraph } from "../graph/build.ts"; import type { LoadPlan } from "../graph/order.ts"; import { chunkIds, soqlIdList } from "./extract.ts"; import { type TargetIdentity } from "./project-id-map.ts"; import type { DryRunSummary, UpsertDecisionSummary } from "./session.ts"; /** * Dry-run: for each object in the final load order, determine how many * source records are in scope and whether the target org can accept them. * * Produces: * - Summary (returned to caller, LLM-safe) — counts, issue names, paths. * - Report file on disk (for user consumption) — counts, scope SOQL, and * schema-diff details. May contain record IDs of the root scope; stays * local to `~/.sandbox-seed/sessions//dry-run.md`. * * Mandatory before `run`: the session stores `dryRun.completedAt` and * `run` refuses unless it's within 24h. */ export type DryRunOptions = { sourceAuth: OrgAuth; targetAuth: OrgAuth; sourceDescribe: DescribeClient; targetDescribe: DescribeClient; graph: DependencyGraph; rootObject: string; whereClause: string; finalObjectList: string[]; /** * Restricted load order — same object the run will execute against. * Required: the plan hash is computed over this shape, so the caller * MUST pass the same load plan it will feed to `runExecute` (otherwise * the run-time hash check fires a false positive). */ loadPlan: LoadPlan; sessionDir: string; fetchFn?: typeof fetch; /** See src/seed/extract.ts ScopePath kind="child-lookup". */ childLookups?: Record; /** * When provided (and `isolateIdMap` is not set), dry-run consults the * persistent project-level id-map so "already seeded on prior run" * counts appear in the summary. Pure read-only — the map is never * written from dry-run. */ sourceAlias?: string; /** See `sourceAlias`. */ targetAliasForIdMap?: string; targetIdentity?: TargetIdentity; isolateIdMap?: boolean; /** * Per-object upsert-key overrides set at session start. When present, * resolveUpsertKey uses the named field verbatim instead of running * auto-pick by population — provided the field is still in the * source's candidate set. Invalid overrides surface as * `ambiguous: "override-invalid"` so the user sees the typo or stale * field name and can fix it before `run`. */ upsertKeyOverrides?: Record; /** * Pre-materialized root scope when `sampleSize` was applied at start. * See `ExecuteOptions.sampledRootIds`. dry_run honors this so the * scope it reports MATCHES what the run will process. */ sampledRootIds?: string[]; /** * Per-object field NAMES the run will mask (resolved by the caller via * resolveMaskSelection + maskedFieldNames). Rendered into the report's * "Masking" section and echoed in the summary. Names only — no values. * Absent ⇒ masking is off for the session. */ maskedFieldsByObject?: Record; }; export declare function runDryRun(opts: DryRunOptions): Promise; /** * Warn when a MASKED field is shorter on the target than on the source. * The run clamps mask generation to min(source, target) length (see * intersectWithTargetFields), so nothing breaks — but the user should * know the masked values will be shorter than the source shape suggests. * Names and lengths only; no values. */ declare function maskedLengthWarnings(object: string, srcDesc: SObjectDescribe, tgtDesc: SObjectDescribe, maskedFieldNames: string[] | undefined): string[]; /** * For each object, query the source for rows where any User/Group/Queue * reference field is populated. Those references will NOT be remapped at * run time (only RecordType is remapped), so the run silently defaults * them to the running user. This preview lets users see the blast radius * before executing. * * Best-effort: skips objects whose describe or count query fails, and * returns a partial map. A missing entry means "couldn't measure", not * "no references." */ declare function countDefaultedOwnerRefs(args: { objects: string[]; sourceAuth: OrgAuth; sourceDescribe: DescribeClient; /** The exact in-scope IDs per object, as materialized by the dry-run. */ materializedIds: Map; fetchFn?: typeof fetch; }): Promise>; declare function renderReport(args: { rootObject: string; whereClause: string; rootIds: string[]; finalObjectList: string[]; perObjectCounts: Record; perObjectSoql: Record; perObjectKind: Record; schemaIssues: string[]; upsertDecisions: Record; completedAt: string; sourceAlias: string; targetAlias: string; planHash: string; defaultedOwnerRefByObject: Record; totalDefaultedOwnerRefs: number; maskedFieldsByObject?: Record; }): string; export { chunkIds as _chunkIds, countDefaultedOwnerRefs as _countDefaultedOwnerRefs, maskedLengthWarnings as _maskedLengthWarnings, renderReport as _renderReport, soqlIdList as _soqlIdList, };