@peernova/cuneiform-sf 1.0.1 → 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.
- package/README.md +2 -2
- package/lib/commands/cuneiform/definition/export.d.ts +48 -0
- package/lib/commands/cuneiform/definition/export.js +97 -0
- package/lib/commands/cuneiform/definition/export.js.map +1 -0
- package/lib/commands/cuneiform/definition/import.d.ts +49 -0
- package/lib/commands/cuneiform/definition/import.js +107 -0
- package/lib/commands/cuneiform/definition/import.js.map +1 -0
- package/lib/models/sfdmu-types.d.ts +74 -0
- package/lib/models/sfdmu-types.js +19 -0
- package/lib/models/sfdmu-types.js.map +1 -0
- package/lib/operations/DefinitionExportOperation.d.ts +92 -0
- package/lib/operations/DefinitionExportOperation.js +197 -0
- package/lib/operations/DefinitionExportOperation.js.map +1 -0
- package/lib/operations/DefinitionImportOperation.d.ts +94 -0
- package/lib/operations/DefinitionImportOperation.js +194 -0
- package/lib/operations/DefinitionImportOperation.js.map +1 -0
- package/lib/services/SFDMUService.d.ts +119 -0
- package/lib/services/SFDMUService.js +262 -0
- package/lib/services/SFDMUService.js.map +1 -0
- package/messages/definition.export.md +41 -0
- package/messages/definition.import.md +48 -0
- package/oclif.lock +4978 -1335
- package/oclif.manifest.json +168 -1
- package/package.json +10 -6
|
@@ -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
|