import { type ServiceResult } from '../models/sfdmu-types.js'; import { SFDMUService } from '../services/SFDMUService.js'; /** * Options for the definition export operation. */ export type ExportOptions = { /** Target org username or alias to export from */ targetOrg: string; /** Output directory path (defaults to ./data/exports/definitions/{timestamp}) */ outputDir?: string; /** Exclude Salesforce IDs for VCS-friendly output */ excludeIds?: boolean; /** Optional logger for debug output */ logger?: Console; }; /** * Result of a definition export operation. */ export type ExportResult = { /** Number of definitions exported */ definitionsExported: number; /** Path to the output directory */ outputPath: string; /** List of files created */ files: string[]; /** Raw SFDMU output for debugging */ sfdmuOutput?: string; }; /** * Error codes specific to export operations. */ export declare const ExportErrorCodes: { /** Output directory already exists */ readonly OUTPUT_DIR_EXISTS: "EXPORT_OUTPUT_DIR_EXISTS"; /** No definitions found in org */ readonly NO_DEFINITIONS_FOUND: "EXPORT_NO_DEFINITIONS_FOUND"; /** Failed to create output directory */ readonly DIR_CREATION_FAILED: "EXPORT_DIR_CREATION_FAILED"; /** Failed to write config file */ readonly CONFIG_WRITE_FAILED: "EXPORT_CONFIG_WRITE_FAILED"; }; /** * Orchestrates the export of profiling definitions using SFDMU. * * Follows the 4-layer architecture: Command → Operation → Service → API * This operation layer handles business logic orchestration while delegating * the actual SFDMU execution to SFDMUService. * * @example * ```typescript * const operation = new DefinitionExportOperation(sfdmuService); * const result = await operation.execute({ * targetOrg: 'myOrg', * outputDir: './exports', * excludeIds: true * }); * ``` */ export declare class DefinitionExportOperation { /** Default base path for exports */ private static readonly DEFAULT_EXPORT_BASE; /** Expected CSV file name — written by SFDMU on successful export */ private static readonly DEFINITION_CSV; /** * SOQL query for exporting all profiling definition fields. * * Selects all configurable fields from pnova__Profiling_Definition__c: * - Identity: Id, Name, RecordTypeId * - Aggregation status: pnova__Agg_Status__c, pnova__Agg_StatusStatistical__c * - Version tracking: pnova__Aud_Version* fields for CRM/DC compatibility * - Profiling config: pnova__Profiling_IsProfileForAll* fields * - Properties: pnova__Prop_* fields (category, description, filters, KPIs, etc.) * - Formula fields: pnova__PropFx_* fields for type derivation (read-only, computed by Salesforce) */ private static readonly DEFINITION_QUERY; /** * VCS-friendly SOQL query — same as DEFINITION_QUERY without the three org-specific ID fields: * Id, RecordTypeId, and pnova__Prop_SObjectRecordTypeId__c. * * Used when --exclude-ids is set. SFDMU's excludeIdsFromCSVFiles flag is documented to strip * ID columns from export CSVs (https://help.sfdmu.com/full-documentation/export-json-file-objects-specification/script-object) * but does not honor this for Readonly (org→csvfile) exports in tested versions. * Workaround: exclude the fields from the SOQL query so they are never fetched. * * Future hardening (CLI-1793): once SFDMU fixes excludeIdsFromCSVFiles for Readonly exports, * remove this constant and the ternary in buildSFDMUConfig — the flag alone will suffice. */ private static readonly DEFINITION_QUERY_EXCLUDE_IDS; private readonly sfdmuService; private readonly logger?; /** * Creates a new DefinitionExportOperation. * * @param sfdmuService - The SFDMU service instance for executing operations * @param logger - Optional logger for debug output */ constructor(sfdmuService: SFDMUService, logger?: Console); /** * Resolves the output path, generating a timestamped directory if needed. * * @param outputDir - Optional output directory path. If not provided, generates a timestamped directory. * @returns Absolute path to the resolved output directory */ private static resolveOutputPath; /** * Builds the SFDMU export configuration. * * Creates an export.json config file structure that SFDMU reads to execute the export. * The config specifies: query (SOQL), operation (Readonly for export), externalId (Name * for matching), and optionally excludeIdsFromCSVFiles to omit Salesforce IDs. * * When excludeIds is true, uses DEFINITION_QUERY_EXCLUDE_IDS which omits Id, RecordTypeId, * and pnova__Prop_SObjectRecordTypeId__c from the SOQL. This is a CLI-1793 workaround — * see DEFINITION_QUERY_EXCLUDE_IDS for the full explanation and hardening path. * * @param excludeIds - Whether to exclude Id fields from the export (for VCS-friendly output) * @returns Config object with objects array and optional excludeIdsFromCSVFiles flag */ private static buildSFDMUConfig; /** * Counts data rows in the exported definition CSV. * * SFDMU exports RecordType as a parent-lookup sidecar alongside the definition object, * so its "Processed N records" log lines cover both objects. Reading the CSV directly * gives the exact definition count without summing across unrelated objects. * * Returns 0 if the file is absent or unreadable (SFDMU may not write it when the * org has zero definitions). */ private static countCsvDataRows; /** * Collects non-hidden files from the export directory. * * Reads the output directory and filters out hidden files (those starting with '.'). * Returns an empty array if the directory cannot be read. * * @param outputPath - The export directory path to scan * @returns Array of visible file names in the directory */ private static collectExportedFiles; /** * Executes the export operation. * * Returns a ServiceResult with success=false and one of the following error codes on failure: * - OUTPUT_DIR_EXISTS: Output directory already exists (prevent accidental overwrite) * - SFDMU error codes: When the underlying SFDMU operation fails * * The operation creates the output directory, writes export.json config, runs SFDMU, * and writes export-metadata.json on success. * * @param options - Export options * @returns ServiceResult containing export results or error details */ execute(options: ExportOptions): Promise>; }