@peernova/cuneiform-sf 1.0.2 → 1.0.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,262 @@
1
+ /*
2
+ * Copyright (c) 2026, PeerNova Inc. All rights reserved.
3
+ * SPDX-License-Identifier: BSD-3-Clause
4
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ import { SfError } from '@salesforce/core';
9
+ import { SFDMUErrorCodes } from '../models/sfdmu-types.js';
10
+ /** Default promisified execFile */
11
+ const defaultExecFileAsync = promisify(execFile);
12
+ /**
13
+ * Service for executing SFDMU (Salesforce Data Move Utility) operations.
14
+ *
15
+ * This service provides:
16
+ * - Runtime verification that SFDMU is installed
17
+ * - Secure shell execution using execFile (prevents command injection)
18
+ * - Cross-platform support (Windows/Unix)
19
+ * - Configurable timeout and buffer sizes
20
+ * - Result parsing for record counts and errors
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const service = new SFDMUService();
25
+ * await service.verifyInstallation();
26
+ * const result = await service.runExport({
27
+ * configPath: './export.json',
28
+ * sourceOrg: 'myOrg'
29
+ * });
30
+ * ```
31
+ */
32
+ export class SFDMUService {
33
+ /** Default timeout for SFDMU operations (5 minutes) */
34
+ static DEFAULT_TIMEOUT = 300_000;
35
+ /** Default max buffer size for stdout/stderr (10MB) */
36
+ static DEFAULT_MAX_BUFFER = 10 * 1024 * 1024;
37
+ /** The sf CLI binary name (platform-specific) */
38
+ sfBinary;
39
+ /** Logger instance */
40
+ logger;
41
+ /** Injected execFile function */
42
+ execFileAsync;
43
+ /**
44
+ * Creates a new SFDMUService instance.
45
+ *
46
+ * @param config - Optional configuration including logger and test dependencies
47
+ */
48
+ constructor(config) {
49
+ const platform = config?.platform ?? process.platform;
50
+ this.sfBinary = platform === 'win32' ? 'sf.cmd' : 'sf';
51
+ this.logger = config?.logger;
52
+ this.execFileAsync = config?.execFileAsync ?? defaultExecFileAsync;
53
+ }
54
+ /**
55
+ * Builds command line arguments for SFDMU execution.
56
+ *
57
+ * @param options - Operation options
58
+ * @param operation - The operation type
59
+ * @returns Array of command line arguments
60
+ */
61
+ static buildArgs(options, operation) {
62
+ const args = ['sfdmu:run', '--path', options.configPath];
63
+ // For export: source=org, target=csvfile (writes CSV files)
64
+ // For import: source=csvfile, target=org (reads CSV files)
65
+ if (operation === 'export' && options.sourceOrg) {
66
+ args.push('--sourceusername', options.sourceOrg);
67
+ args.push('--targetusername', 'csvfile');
68
+ }
69
+ else if (operation === 'import' && options.targetOrg) {
70
+ args.push('--sourceusername', 'csvfile');
71
+ args.push('--targetusername', options.targetOrg);
72
+ }
73
+ // Add API preference if specified
74
+ if (options.useBulkAPI === false) {
75
+ args.push('--apiversion', 'rest');
76
+ }
77
+ return args;
78
+ }
79
+ /**
80
+ * Parses record count from SFDMU stdout output.
81
+ *
82
+ * @param stdout - Standard output from SFDMU
83
+ * @returns Parsed record count or undefined if not found
84
+ */
85
+ static parseRecordCount(stdout) {
86
+ // SFDMU outputs record counts in various formats
87
+ // Examples: "Processed 100 records", "Total: 100 records"
88
+ const patterns = [/Processed\s+(\d+)\s+records?/i, /Total[:\s]+(\d+)\s+records?/i, /(\d+)\s+records?\s+processed/i];
89
+ for (const pattern of patterns) {
90
+ const match = stdout.match(pattern);
91
+ if (match?.[1]) {
92
+ return parseInt(match[1], 10);
93
+ }
94
+ }
95
+ return undefined;
96
+ }
97
+ /**
98
+ * Parses error messages from SFDMU stderr output.
99
+ *
100
+ * @param stderr - Standard error from SFDMU
101
+ * @returns Array of error messages
102
+ */
103
+ static parseErrors(stderr) {
104
+ if (!stderr.trim()) {
105
+ return [];
106
+ }
107
+ // Split stderr into lines and filter for error messages
108
+ return stderr
109
+ .split('\n')
110
+ .map((line) => line.trim())
111
+ .filter((line) => line.length > 0 && (line.toLowerCase().includes('error') || line.startsWith('Error:')));
112
+ }
113
+ /**
114
+ * Parses warning messages from SFDMU stderr output.
115
+ *
116
+ * @param stderr - Standard error from SFDMU
117
+ * @returns Array of warning messages
118
+ */
119
+ static parseWarnings(stderr) {
120
+ if (!stderr.trim()) {
121
+ return [];
122
+ }
123
+ // Split stderr into lines and filter for warnings
124
+ return stderr
125
+ .split('\n')
126
+ .map((line) => line.trim())
127
+ .filter((line) => line.length > 0 && line.toLowerCase().includes('warning'));
128
+ }
129
+ /**
130
+ * Returns the sf binary name being used (for testing/debugging).
131
+ */
132
+ getSfBinary() {
133
+ return this.sfBinary;
134
+ }
135
+ /**
136
+ * Verifies that SFDMU is installed and available.
137
+ *
138
+ * @throws SfError if SFDMU is not installed, with installation instructions
139
+ */
140
+ async verifyInstallation() {
141
+ try {
142
+ await this.execFileAsync(this.sfBinary, ['sfdmu', '--help'], {
143
+ timeout: 30_000, // 30 second timeout for help command
144
+ maxBuffer: 1024 * 1024, // 1MB buffer for help output
145
+ });
146
+ this.logger?.log('SFDMU installation verified');
147
+ }
148
+ catch (error) {
149
+ const execError = error;
150
+ // Check if this is a "command not found" type error
151
+ if (execError.code === 'ENOENT' || execError.message?.includes('not found')) {
152
+ throw new SfError('Salesforce CLI (sf) is not installed or not in PATH.', 'SFCLINotFound', [
153
+ 'Install Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli',
154
+ 'Ensure sf is in your PATH',
155
+ ]);
156
+ }
157
+ // SFDMU plugin not installed (sf found but sfdmu command failed)
158
+ throw new SfError('SFDMU plugin is not installed.', SFDMUErrorCodes.NOT_INSTALLED, [
159
+ 'Install SFDMU: sf plugins install sfdmu',
160
+ 'Documentation: https://help.sfdmu.com',
161
+ ]);
162
+ }
163
+ }
164
+ /**
165
+ * Executes an SFDMU export operation.
166
+ *
167
+ * @param options - Export options including config path and source org
168
+ * @returns ServiceResult containing the execution result
169
+ */
170
+ async runExport(options) {
171
+ return this.executeOperation(options, 'export');
172
+ }
173
+ /**
174
+ * Executes an SFDMU import operation.
175
+ *
176
+ * @param options - Import options including config path and target org
177
+ * @returns ServiceResult containing the execution result
178
+ */
179
+ async runImport(options) {
180
+ return this.executeOperation(options, 'import');
181
+ }
182
+ /**
183
+ * Executes an SFDMU operation (export or import).
184
+ *
185
+ * @param options - Operation options
186
+ * @param operation - The operation type ('export' or 'import')
187
+ * @returns ServiceResult containing the execution result
188
+ */
189
+ async executeOperation(options, operation) {
190
+ const startTime = Date.now();
191
+ // Verify SFDMU is installed before attempting operation
192
+ await this.verifyInstallation();
193
+ // Build command arguments
194
+ const args = SFDMUService.buildArgs(options, operation);
195
+ const timeout = options.timeout ?? SFDMUService.DEFAULT_TIMEOUT;
196
+ const maxBuffer = options.maxBuffer ?? SFDMUService.DEFAULT_MAX_BUFFER;
197
+ this.logger?.log(`Executing SFDMU ${operation}: ${this.sfBinary} ${args.join(' ')}`);
198
+ try {
199
+ const { stdout, stderr } = await this.execFileAsync(this.sfBinary, args, {
200
+ timeout,
201
+ maxBuffer,
202
+ });
203
+ const duration = Date.now() - startTime;
204
+ const recordsProcessed = SFDMUService.parseRecordCount(stdout);
205
+ const warnings = SFDMUService.parseWarnings(stderr);
206
+ return {
207
+ success: true,
208
+ data: {
209
+ exitCode: 0,
210
+ stdout,
211
+ stderr,
212
+ recordsProcessed,
213
+ errors: [],
214
+ },
215
+ message: `SFDMU ${operation} completed successfully`,
216
+ warnings: warnings.length > 0 ? warnings : undefined,
217
+ metadata: {
218
+ duration,
219
+ },
220
+ };
221
+ }
222
+ catch (error) {
223
+ const duration = Date.now() - startTime;
224
+ const execError = error;
225
+ // Handle timeout
226
+ if (execError.killed && execError.signal === 'SIGTERM') {
227
+ return {
228
+ success: false,
229
+ data: {
230
+ exitCode: -1,
231
+ stdout: execError.stdout ?? '',
232
+ stderr: execError.stderr ?? '',
233
+ errors: [`Operation timed out after ${timeout}ms`],
234
+ },
235
+ errorCode: SFDMUErrorCodes.TIMEOUT,
236
+ message: `SFDMU ${operation} timed out after ${timeout}ms`,
237
+ metadata: {
238
+ duration,
239
+ },
240
+ };
241
+ }
242
+ // Handle execution failure
243
+ const exitCode = execError.code ?? 1;
244
+ const errors = SFDMUService.parseErrors(execError.stderr ?? '');
245
+ return {
246
+ success: false,
247
+ data: {
248
+ exitCode: typeof exitCode === 'number' ? exitCode : 1,
249
+ stdout: execError.stdout ?? '',
250
+ stderr: execError.stderr ?? '',
251
+ errors,
252
+ },
253
+ errorCode: SFDMUErrorCodes.EXECUTION_FAILED,
254
+ message: `SFDMU ${operation} failed with exit code ${exitCode}`,
255
+ metadata: {
256
+ duration,
257
+ },
258
+ };
259
+ }
260
+ }
261
+ }
262
+ //# sourceMappingURL=SFDMUService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SFDMUService.js","sourceRoot":"","sources":["../../src/services/SFDMUService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ # summary
2
+
3
+ Export profiling definitions from a Salesforce org to SFDMU-compatible CSV files.
4
+
5
+ # description
6
+
7
+ Exports profiling definition records to CSV files in SFDMU-compatible format for backup, version control, or cross-org migration.
8
+
9
+ The export creates a timestamped directory containing:
10
+
11
+ - export.json: SFDMU configuration file
12
+ - pnova**Profiling_Definition**c.csv: Definition records
13
+ - export-metadata.json: Export statistics and metadata
14
+
15
+ Use --exclude-ids for VCS-friendly output that excludes Salesforce IDs (Id, CreatedById, etc.), making the files suitable for version control.
16
+
17
+ # flags.target-org.summary
18
+
19
+ Salesforce org to export definitions from.
20
+
21
+ # flags.output.summary
22
+
23
+ Output directory path. Defaults to ./data/exports/definitions/{timestamp}.
24
+
25
+ # flags.exclude-ids.summary
26
+
27
+ Exclude Salesforce IDs for VCS-friendly output.
28
+
29
+ # examples
30
+
31
+ - Export all definitions to the default location:
32
+
33
+ <%= config.bin %> <%= command.id %> --target-org myOrg
34
+
35
+ - Export to a specific directory:
36
+
37
+ <%= config.bin %> <%= command.id %> --target-org myOrg --output ./backup/definitions
38
+
39
+ - Export with VCS-friendly mode (excludes IDs):
40
+
41
+ <%= config.bin %> <%= command.id %> --target-org myOrg --exclude-ids --output ./config/definitions
@@ -0,0 +1,48 @@
1
+ # summary
2
+
3
+ Import profiling definitions from SFDMU-compatible CSV files into a Salesforce org.
4
+
5
+ # description
6
+
7
+ Imports profiling definition records from CSV files exported by `sf cuneiform definition export` or manually created SFDMU-compatible files.
8
+
9
+ The source directory must contain:
10
+
11
+ - pnova**Profiling_Definition**c.csv: Definition records to import
12
+
13
+ The import operation can be configured as:
14
+
15
+ - Insert (default): Creates new records only. Fails if a record with the same Name exists.
16
+ - Upsert: Creates new records or updates existing records matched by Name (external ID).
17
+
18
+ Use --dry-run to validate the import without making changes to the org.
19
+
20
+ # flags.target-org.summary
21
+
22
+ Salesforce org to import definitions into.
23
+
24
+ # flags.source.summary
25
+
26
+ Source directory containing CSV files to import.
27
+
28
+ # flags.operation.summary
29
+
30
+ SFDMU operation type: Insert (create only) or Upsert (create/update).
31
+
32
+ # flags.dry-run.summary
33
+
34
+ Preview changes without making them (dry-run mode).
35
+
36
+ # examples
37
+
38
+ - Import definitions from a backup directory:
39
+
40
+ <%= config.bin %> <%= command.id %> --target-org myOrg --source ./backup/definitions
41
+
42
+ - Import with upsert (update existing, insert new):
43
+
44
+ <%= config.bin %> <%= command.id %> --target-org myOrg --source ./backup --operation Upsert
45
+
46
+ - Preview import without making changes:
47
+
48
+ <%= config.bin %> <%= command.id %> --target-org myOrg --source ./backup --dry-run