Skip to content

Commit

Permalink
security updates, refactoring, unit tests created, json messages enha…
Browse files Browse the repository at this point in the history
…nced
  • Loading branch information
osieckiAdam committed Dec 27, 2019
1 parent d2e8d5f commit 93c9d49
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 90 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,15 @@ sfdx plugins:link
## Commands

<!-- commands -->

- [`sfdx oa:apex:log:delete [-c] [-a] [-u <string>] [--apiversion <string>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sfdx-oaapexlogdelete--c--a--u-string---apiversion-string---json---loglevel-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal)
* [`sfdx oa:apex:log:delete [-c] [-a] [-u <string>] [--apiversion <string>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sfdx-oaapexlogdelete--c--a--u-string---apiversion-string---json---loglevel-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal)

## `sfdx oa:apex:log:delete [-c] [-a] [-u <string>] [--apiversion <string>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`

delete ApexLog entries from Your org

```
USAGE
$ sfdx oa:apex:log:delete [-c] [-a] [-u <string>] [--apiversion <string>] [--json] [--loglevel
$ sfdx oa:apex:log:delete [-c] [-a] [-u <string>] [--apiversion <string>] [--json] [--loglevel
trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]
OPTIONS
Expand Down Expand Up @@ -103,8 +102,16 @@ EXAMPLES
Number of ApexLog records to be deleted: 7
Delete job is started. Id of the job: 7501w000002WEuKAAW
To poll status of the job, run command 'sfdx force:data:bulk:status -i 7501w000002WEsi'
sfdx oa:apex:log:delete --json'
{
"status": 0,
"result": {
"numberOfQueriedLogs": 3,
"jobID": "7501w000002WnWcAAK"
}
}
```

_See code: [lib\commands\oa\apex\log\delete.js](https://github.com/osieckiAdam/osiecki-sfdx-plugins/blob/v0.1.1/lib\commands\oa\apex\log\delete.js)_

<!-- commandsstop -->
2 changes: 1 addition & 1 deletion messages/delete.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"recordsLenghtMessage": "Number of ApexLog records to be deleted: %i",
"jobStartedMessage": "Delete job is started. Id of the job: %s",
"jobStartedMessageAsync": "To poll status of the job, run command 'sfdx force:data:bulk:status -i %s -u %s",
"jobFinishedMessage": "\nJob is finished, status of the job is: %s\nTotal processing time was %i ms",
"jobFinishedMessage": "\nJob is finished",
"failedRecordsMessage": "Number of failed records: %i",
"successMessage": "All records were deleted sucessfully",
"noLogsMessage": "There are no Apex logs on Your org!",
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,25 @@
"@oclif/command": "^1",
"@oclif/config": "^1",
"@oclif/errors": "^1",
"@salesforce/command": "^1.4.1",
"@salesforce/core": "^1.3.2",
"@salesforce/command": "^2",
"@salesforce/core": "^2",
"@types/jsforce": "^1.9.13",
"tslib": "^1"
},
"devDependencies": {
"@oclif/dev-cli": "^1",
"@oclif/plugin-help": "^2",
"@oclif/plugin-help": "^2.2.3",
"@oclif/test": "^1",
"@salesforce/dev-config": "1.4.1",
"@types/chai": "^4",
"@types/chai": "^4.2.7",
"@types/mocha": "^5",
"@types/node": "^10",
"chai": "^4",
"@types/node": "^10.17.13",
"chai": "^4.2.0",
"globby": "^8",
"mocha": "^5",
"mocha": "^5.2.0",
"nyc": "^14",
"rimraf": "^3.0.0",
"testdouble": "^3.12.4",
"ts-node": "^8",
"tslint": "^5"
},
Expand Down
193 changes: 115 additions & 78 deletions src/commands/oa/apex/log/delete.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1,137 @@
import { SfdxCommand, flags, core } from '@salesforce/command';
import { core, flags, SfdxCommand } from '@salesforce/command';
import { AnyJson } from '@salesforce/ts-types';
import { Batch } from 'jsforce';

core.Messages.importMessagesDirectory(__dirname);
const messages = core.Messages.loadMessages('osiecki-sfdx-plugins', 'delete');

export default class Delete extends SfdxCommand {

public static description = messages.getMessage('deleteCommandDescription');
protected static requiresUsername = true;
protected static flagsConfig = {
checkonly: flags.boolean({ char: 'c', description: messages.getMessage('checkOnlyFlagDescription') }),
async: flags.boolean({ char: 'a', description: messages.getMessage('asyncFlagDescription') })
};
public static examples = [
`
sfdx oa:apex:log:delete
public static description = messages.getMessage('deleteCommandDescription');
public static examples = [
`
sfdx oa:apex:log:delete
Number of ApexLog records to be deleted: 100
Delete job is started. Id of the job: 7501w000002WA2EAAW
Processed records: 100 / 100
Job is finished, status of the job is: Completed
Total processing time was 2154 ms
All records were deleted sucessfully`,
`
`
sfdx oa:apex:log:delete -c -u [email protected]
Number of ApexLog records to be deleted: 10`,
`
`
sfdx oa:apex:log:delete --async
Number of ApexLog records to be deleted: 7
Delete job is started. Id of the job: 7501w000002WEuKAAW
To poll status of the job, run command 'sfdx force:data:bulk:status -i 7501w000002WEsi'`
];
To poll status of the job, run command 'sfdx force:data:bulk:status -i 7501w000002WEsi'`,
`
sfdx oa:apex:log:delete --json'
{
"status": 0,
"result": {
"numberOfQueriedLogs": 3,
"jobID": "7501w000002WnWcAAK"
}
}
`
];

public async run(): Promise<AnyJson> {
let resultsLength = 0;
const that = this;
const conn = this.org.getConnection();
protected static requiresUsername = true;
protected static flagsConfig = {
checkonly: flags.boolean({ char: 'c', description: messages.getMessage('checkOnlyFlagDescription') }),
async: flags.boolean({ char: 'a', description: messages.getMessage('asyncFlagDescription') })
};

conn
.sobject("ApexLog")
.find({}, ["Id"])
.sort({ LogLength: -1 })
.execute({ autoFetch: true, maxFetch: 10000 }, function (err, records) {
if (err) {
return console.error(err);
}
resultsLength = records.length;
public async run(): Promise<AnyJson> {

let job = conn.bulk.createJob("ApexLog", "delete");
if (records.length > 0) {
that.ux.log(messages.getMessage('recordsLenghtMessage', [records.length]));
if (!that.flags.checkonly) {
let batch = job.createBatch();
batch.execute(records);
batch.on("queue", batchInfo => {
that.ux.log(messages.getMessage("jobStartedMessage", [batchInfo.jobId]));
if (that.flags.async) {
return that.ux.log(messages.getMessage("jobStartedMessageAsync", [batchInfo.jobId, that.flags.targetusername]));
}
batch.poll(2000, 10000000);
});
batch.on("progress", response => {
batch.check().then(batchInfo => {
process.stdout.write(
"\x1Bc\rProcessed records: " +
//@ts-ignore
batchInfo.numberRecordsProcessed +
" / " +
records.length
);
});
});
batch.on("response", response => {
batch.check().then(batchDetails => {
that.ux.log(
//@ts-ignore
messages.getMessage("jobFinishedMessage", [batchDetails.state, batchDetails.totalProcessingTime])
);
//@ts-ignore
if (batchDetails.numberRecordsFailed !== "0") {
that.ux.log(
//@ts-ignore
messages.getMessage("failedRecordsMessage", [batchDetails.numberRecordsFailed])
);
} else {
that.ux.log(messages.getMessage("successMessage"));
}
});
});
batch.on("error", response => {
return console.error(response);
});
}
} else {
that.ux.log(messages.getMessage('noLogsMessage'));
}
});
return { numberOfQueriedLogs: resultsLength };
let response: AnyJson = ({ numberOfQueriedLogs: 0 });
const conn = this.org.getConnection();
const apexLogRecords = await this.getAllApexLogs();

if (apexLogRecords.length > 0) {
this.ux.log(messages.getMessage('recordsLenghtMessage', [apexLogRecords.length]));
if (this.flags.checkonly) {
response = ({ numberOfQueriedLogs: apexLogRecords.length });
} else {
const batch = this.createBatch(conn, apexLogRecords);
response = await this.trackBatchProgress(batch, apexLogRecords.length);
}
} else {
this.ux.log(messages.getMessage('noLogsMessage'));
response = ({ numberOfQueriedLogs: 0 });
}
return response;
}

public async getAllApexLogs() {
const response = this.org.getConnection()
.sobject('ApexLog')
.find({}, ['Id'])
.execute({ autoFetch: true, maxFetch: 10000 }, async (err, records) => {
if (err) {
return console.error(err);
}
return records;
});
return response;
}

public createBatch(conn: core.Connection, records: Array<{ Id?: string; }>): Batch {
return conn.bulk.createJob('ApexLog', 'delete').createBatch().execute(records);
}

private async trackBatchProgress(batch: Batch, totalNumberOfRecords: number) {
let jobId: string;
interface JobResultItem {
id: string;
success: boolean;
errors: AnyJson[];
}

const failedRecords: JobResultItem[] = new Array();
const response = await new Promise<AnyJson>((resolve, reject) => {
batch.on('queue', batchDetails => {

jobId = batchDetails.jobId;
this.ux.log(messages.getMessage('jobStartedMessage', [jobId]));
if (this.flags.async) {
this.ux.log(messages.getMessage('jobStartedMessageAsync', [jobId, this.flags.targetusername]));
resolve({ numberOfQueriedLogs: totalNumberOfRecords, jobID: jobId });
} else {
batch.poll(2000, 10000000);
if (!this.flags.json) {
batch.on('progress', batchInfo => {
this.logProgress(batchInfo.numberRecordsProcessed, totalNumberOfRecords);
});
}
batch.on('response', records => {
records.forEach((element: JobResultItem) => {
if (!element.success) {
failedRecords.push(element);
}
});
if (!this.flags.json) {
this.logProgress(records.length, totalNumberOfRecords);
}
this.ux.log(messages.getMessage('jobFinishedMessage'));
if (failedRecords.length > 0) {
this.ux.log(messages.getMessage('failedRecordsMessage', [failedRecords.length]));
} else {
this.ux.log(messages.getMessage('successMessage'));
}
resolve({ numberOfQueriedLogs: totalNumberOfRecords, jobID: jobId, numberOfFailedRecords: failedRecords.length });
});
batch.on('error', res => {
console.log(res);
reject(res);
});
}
});
});
return response;
}

private logProgress(processedItems: string, totalItems: number): void {
process.stdout.write('\x1Bc\rProcessed records: ' + processedItems + ' / ' + totalItems);
}
}
Loading

0 comments on commit 93c9d49

Please sign in to comment.