Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
"@oclif/errors": "^1",
"@salesforce/command": "^4.2.1",
"@salesforce/core": "^2.37.1",
"@types/jsdom": "^21.1.7",
"@salesforce/sf-plugins-core": "^11.3.6",
"@salesforce/source-deploy-retrieve": "^12.6.0",
"@types/lodash.chunk": "^4.2.9",
"cheerio": "^1.0.0",
"jsdom": "^25.0.0",
"@types/shelljs": "^0.8.15",
"lodash.chunk": "^4.2.0",
"open": "^8.4.2",
"tslib": "^2",
"xmldom": "^0.6.0"
"shelljs": "^0.8.5",
"tslib": "^2"
},
"devDependencies": {
"@babel/parser": "^7.25.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as os from 'os';
import { Messages } from '@salesforce/core';
import { Messages, Org } from '@salesforce/core';
import '../../../utils/prototypes';
import { IConfig } from '@oclif/config';
import OmniStudioBaseCommand from '../../basecommand';
import { DebugTimer, MigratedObject, MigratedRecordInfo } from '../../../utils';
import { MigrationResult, MigrationTool } from '../../../migration/interfaces';
import { ResultsBuilder } from '../../../utils/resultsbuilder';
import {
LWCComponentMigrationTool,
CustomLabelMigrationTool,
ApexClassMigrationTool,
} from '../../../migration/interfaces';
import { DebugTimer } from '../../../utils';
import { MigrationResult, RelatedObjectsMigrate } from '../../../migration/interfaces';
import { sfProject } from '../../../utils/sfcli/project/sfProject';
import { Logger } from '../../../utils/logger';
import { ApexMigration } from '../../../migration/related/ApexMigration';

// Initialize Messages with the current plugin directory
Messages.importMessagesDirectory(__dirname);
Expand All @@ -22,152 +17,90 @@ Messages.importMessagesDirectory(__dirname);
// or any library that is using the messages framework can also be loaded this way.
const messages = Messages.loadMessages('@salesforce/plugin-omnistudio-related-object-migration-tool', 'migrate');

export default class OmnistudioRelatedObjectMigrationFacade extends OmniStudioBaseCommand {
const defaultProjectName = 'omnistudio_migration';
export default class OmnistudioRelatedObjectMigrationFacade {
public static description = messages.getMessage('commandDescription');
public static examples = messages.getMessage('examples').split(os.EOL);
public static args = [{ name: 'file' }];

protected readonly namespace: string;
protected readonly only: string;
protected readonly allversions: boolean;
protected readonly org: Org;

public constructor(argv: string[], config: IConfig) {
super(argv, config);
const { flags } = this.parse(OmnistudioRelatedObjectMigrationFacade);
this.namespace = flags.namespace;
this.only = flags.only;
this.allversions = flags.allversions;
public constructor(namespace: string, only: string, allversions: boolean, org: Org) {
this.namespace = namespace;
this.only = only;
this.allversions = allversions;
this.org = org;
}
public async migrateAll(migrationResult: MigrationResult, namespace: string, relatedObjects: string[]): Promise<any> {
const apiVersion = '55.0'; // Define the API version or make it configurable
const conn = this.org.getConnection();
conn.setApiVersion(apiVersion);

public migrateAll(migrationResult: MigrationResult, namespace: string, relatedObjects: string[]): any {
// Start the debug timer
DebugTimer.getInstance().start();

// Declare an array of MigrationTool
const migrationTools: MigrationTool[] = [];

const migrationTools: RelatedObjectsMigrate[] = [];
const projectDirectory: string = this.intializeProject();
const debugTimer = DebugTimer.getInstance();
debugTimer.start();
// Initialize migration tools based on the relatedObjects parameter
if (relatedObjects.includes('lwc')) {
migrationTools.push(this.createLWCComponentMigrationTool(namespace, conn));
migrationTools.push(this.createLWCComponentMigrationTool(namespace, this.org));
}
if (relatedObjects.includes('labels')) {
migrationTools.push(this.createCustomLabelMigrationTool(namespace, conn));
migrationTools.push(this.createCustomLabelMigrationTool(namespace, this.org));
}
if (relatedObjects.includes('apex')) {
migrationTools.push(this.createApexClassMigrationTool(namespace, conn));
migrationTools.push(this.createApexClassMigrationTool(projectDirectory));
}

if (migrationTools.length === 0) {
throw new Error(messages.getMessage('noMigrationToolsSelected'));
}

// Proceed with migration logic
const debugTimer = DebugTimer.getInstance();
let objectMigrationResults: MigratedObject[] = [];

// Truncate existing objects if necessary
let allTruncateComplete = true;
for (const tool of migrationTools.reverse()) {
for (const migrationTool of migrationTools.reverse()) {
try {
this.ux.log('Cleaning: ' + tool.getName());
debugTimer.lap('Cleaning: ' + tool.getName());
await tool.truncate();
} catch (ex: any) {
allTruncateComplete = false;
objectMigrationResults.push({
name: tool.getName(),
errors: [ex.message],
});
migrationTool.migrateRelatedObjects(null, null);
} catch (Error) {
// Log the error
Logger.logger.error(Error.message);
return { migrationResult };
}
}

if (allTruncateComplete) {
for (const tool of migrationTools.reverse()) {
try {
this.ux.log('Migrating: ' + tool.getName());
debugTimer.lap('Migrating: ' + tool.getName());
const results = await tool.migrate();

objectMigrationResults = objectMigrationResults.concat(
results.map((r) => ({
name: r.name,
data: this.mergeRecordAndUploadResults(r, tool),
}))
);
} catch (ex: any) {
this.logger.error(JSON.stringify(ex));
objectMigrationResults.push({
name: tool.getName(),
errors: [ex.message],
});
}
}
}

// Truncate existing objects if necessary
// Stop the debug timer
const timer = DebugTimer.getInstance().stop();

await ResultsBuilder.generate(objectMigrationResults, conn.instanceUrl);
const timer = debugTimer.stop();

// Save timer to debug logger
this.logger.debug(timer);
Logger.logger.debug(timer);

// Return results needed for --json flag
return { objectMigrationResults };
return { migrationResult };
}

// Factory methods to create instances of specific tools
private createLWCComponentMigrationTool(namespace: string, conn: any): LWCComponentMigrationTool {
private createLWCComponentMigrationTool(namespace: string, org: Org): RelatedObjectsMigrate {
// Return an instance of LWCComponentMigrationTool when implemented
throw new Error('LWCComponentMigrationTool implementation is not provided yet.');
}

private createCustomLabelMigrationTool(namespace: string, conn: any): CustomLabelMigrationTool {
private createCustomLabelMigrationTool(namespace: string, org: Org): RelatedObjectsMigrate {
// Return an instance of CustomLabelMigrationTool when implemented
throw new Error('CustomLabelMigrationTool implementation is not provided yet.');
}

private createApexClassMigrationTool(namespace: string, conn: any): ApexClassMigrationTool {
private createApexClassMigrationTool(projectPath: string): ApexMigration {
// Return an instance of ApexClassMigrationTool when implemented
throw new Error('ApexClassMigrationTool implementation is not provided yet.');
return new ApexMigration(projectPath, this.namespace, this.org);
}

private mergeRecordAndUploadResults(
migrationResults: MigrationResult,
migrationTool: MigrationTool
): MigratedRecordInfo[] {
const mergedResults: MigratedRecordInfo[] = [];

for (const record of Array.from(migrationResults.records.values())) {
const obj = {
id: record['Id'],
name: migrationTool.getRecordName(record),
status: 'Skipped',
errors: record['errors'],
migratedId: undefined,
warnings: [],
migratedName: '',
};

if (migrationResults.results.has(record['Id'])) {
const recordResults = migrationResults.results.get(record['Id']);

let errors: any[] = obj.errors || [];
errors = errors.concat(recordResults.errors || []);

obj.status = !recordResults || recordResults.hasErrors ? 'Error' : 'Complete';
obj.errors = errors;
obj.migratedId = recordResults.id;
obj.warnings = recordResults.warnings;
obj.migratedName = recordResults.newName;
}

mergedResults.push(obj);
private intializeProject(projectPath?: string): string {
if (projectPath) {
sfProject.create(defaultProjectName, projectPath);
return projectPath + '/' + defaultProjectName;
} else {
sfProject.create(defaultProjectName);
return process.cwd() + '/' + defaultProjectName;
}

return mergedResults;
}
}
14 changes: 14 additions & 0 deletions src/commands/omnistudio/migration/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import * as os from 'os';
import { flags } from '@salesforce/command';
import { Messages } from '@salesforce/core';
import '../../../utils/prototypes';
import * as shell from 'shelljs';
import OmniStudioBaseCommand from '../../basecommand';
import { DataRaptorMigrationTool } from '../../../migration/dataraptor';
import { DebugTimer, MigratedObject, MigratedRecordInfo } from '../../../utils';
import { MigrationResult, MigrationTool } from '../../../migration/interfaces';
import { ResultsBuilder } from '../../../utils/resultsbuilder';
import { CardMigrationTool } from '../../../migration/flexcard';
import { OmniScriptExportType, OmniScriptMigrationTool } from '../../../migration/omniscript';
import { cli } from '../../../utils/shell/cli';
import { Logger } from '../../../utils/logger';
import { sfProject } from '../../../utils/sfcli/project/sfProject';

// Initialize Messages with the current plugin directory
Messages.importMessagesDirectory(__dirname);
Expand Down Expand Up @@ -56,6 +59,17 @@ export default class Migrate extends OmniStudioBaseCommand {
const apiVersion = (this.flags.apiversion || '55.0') as string;
const migrateOnly = (this.flags.only || '') as string;
const allVersions = this.flags.allversions || false;
// await sfcclicommand.fetchApexClasses(this.org, '/Users/abhinavkumar2/company/mywork');
// await sfcclicommand.deployApexClasses(this.org, '/Users/abhinavkumar2/company/mywork/main/default/classes');
sfProject.create('omnistudio_migration', '/Users/abhinavkumar2/company/new');
this.ux.log('creating project');
const pwd = shell.pwd();
shell.cd('/Users/abhinavkumar2/company/new/omnistudio_migration');
cli.exec(`sf project retrieve start --metadata Apexclass --target-org ${this.org.getUsername()}`);
this.ux.log('retrieving apex classes');
cli.exec(`sf project deploy start --metadata Apexclass --target-org ${this.org.getUsername()}`);
shell.cd(pwd);

Logger.initialiseLogger(this.ux, this.logger);
this.logger = Logger.logger;
// this.org is guaranteed because requiresUsername=true, as opposed to supportsUsername
Expand Down
Loading