Skip to content
Merged
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
2 changes: 0 additions & 2 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
"loglevel",
"sobject",
"target-org",
"verbose",
"wait"
],
"plugin": "@salesforce/plugin-data"
Expand Down Expand Up @@ -294,7 +293,6 @@
"loglevel",
"sobject",
"target-org",
"verbose",
"wait"
],
"plugin": "@salesforce/plugin-data"
Expand Down
4 changes: 0 additions & 4 deletions messages/bulkIngest.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ Number of minutes to wait for the command to complete before displaying the resu

Run the command asynchronously.

# flags.verbose.summary

Print verbose output of failed records if result is available.

# flags.jobid

ID of the job you want to resume.
Expand Down
36 changes: 2 additions & 34 deletions src/bulkIngest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import * as fs from 'node:fs';
import { platform } from 'node:os';
import { Flags, SfCommand, Ux, optionalOrgFlagWithDeprecations, loglevel } from '@salesforce/sf-plugins-core';
import { IngestJobV2, IngestJobV2FailedResults, JobInfoV2 } from '@jsforce/jsforce-node/lib/api/bulk2.js';
import { Flags, SfCommand, optionalOrgFlagWithDeprecations, loglevel } from '@salesforce/sf-plugins-core';
import { IngestJobV2, JobInfoV2 } from '@jsforce/jsforce-node/lib/api/bulk2.js';
import { Connection, Messages, SfError } from '@salesforce/core';
import { Schema } from '@jsforce/jsforce-node';
import { Duration } from '@salesforce/kit';
Expand Down Expand Up @@ -53,7 +53,6 @@ export async function bulkIngest(opts: {
wait: Duration;
file: string;
jsonEnabled: boolean;
verbose: boolean;
logFn: (message: string) => void;
warnFn: (message: SfCommand.Warning) => void;
}): Promise<BulkIngestInfo> {
Expand All @@ -64,10 +63,6 @@ export async function bulkIngest(opts: {
throw new SfError('External ID is only required for `sf data upsert bulk`.');
}

if (opts.verbose && !['delete', 'hardDelete', 'upsert'].includes(opts.operation)) {
throw new SfError('Verbose mode is limited for `sf data delete/upsert bulk` and will be removed after March 2025.');
}

const timeout = opts.async ? Duration.minutes(0) : opts.wait ?? Duration.minutes(0);
const async = timeout.milliseconds === 0;

Expand Down Expand Up @@ -155,12 +150,6 @@ export async function bulkIngest(opts: {

if (jobInfo.numberRecordsFailed) {
stages.error();
if (opts.verbose && !opts.jsonEnabled) {
const records = await job.getFailedResults();
if (records.length > 0) {
printBulkErrors(records);
}
}

if (['delete', 'hardDelete', 'upsert'].includes(opts.operation) && opts.jsonEnabled) {
opts.warnFn(
Expand Down Expand Up @@ -381,20 +370,6 @@ export const lineEndingFlag = Flags.option({
options: ['CRLF', 'LF'] as const,
})();

/**
* @deprecated
*/
export const printBulkErrors = (failedResults: IngestJobV2FailedResults<Schema>): void => {
const ux = new Ux();
ux.log();
ux.table({
// eslint-disable-next-line camelcase
data: failedResults.map((f) => ({ id: 'Id' in f ? f.Id : '', sfId: f.sf__Id, error: f.sf__Error })),
columns: ['id', { key: 'sfId', name: 'Sf_Id' }, 'error'],
title: `Bulk Failures [${failedResults.length}]`,
});
};

/**
* Use only for commands that maintain sfdx compatibility.
*
Expand Down Expand Up @@ -430,13 +405,6 @@ export const baseUpsertDeleteFlags = {
summary: messages.getMessage('flags.async.summary'),
exclusive: ['wait'],
}),
verbose: Flags.boolean({
summary: messages.getMessage('flags.verbose.summary'),
deprecated: {
message:
'The --verbose flag is deprecated and will be removed after March 2025, use "sf data bulk results" to get job results instead.',
},
}),
};

/**
Expand Down
1 change: 0 additions & 1 deletion src/commands/data/delete/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export default class Delete extends SfCommand<BulkResultV2> {
wait: flags.wait,
file: flags.file,
jsonEnabled: this.jsonEnabled(),
verbose: flags.verbose,
logFn: (arg: string) => {
this.log(arg);
},
Expand Down
1 change: 0 additions & 1 deletion src/commands/data/import/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export default class DataImportBulk extends SfCommand<DataImportBulkResult> {
wait: flags.wait,
file: flags.file,
jsonEnabled: this.jsonEnabled(),
verbose: false,
logFn: (arg: string) => {
this.log(arg);
},
Expand Down
1 change: 0 additions & 1 deletion src/commands/data/update/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export default class DataUpdateBulk extends SfCommand<DataUpdateBulkResult> {
wait: flags.wait,
file: flags.file,
jsonEnabled: this.jsonEnabled(),
verbose: false,
logFn: (arg: string) => {
this.log(arg);
},
Expand Down
1 change: 0 additions & 1 deletion src/commands/data/upsert/bulk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export default class Upsert extends SfCommand<BulkResultV2> {
wait: flags.wait,
file: flags.file,
jsonEnabled: this.jsonEnabled(),
verbose: flags.verbose,
logFn: (arg: string) => {
this.log(arg);
},
Expand Down
102 changes: 4 additions & 98 deletions test/commands/data/dataBulk.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import { expect, config as chaiConfig } from 'chai';
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
import { sleep } from '@salesforce/kit';
import { ensurePlainObject } from '@salesforce/ts-types';
import type { SaveResult } from '@jsforce/jsforce-node';
import { BulkResultV2 } from '../../../src/types.js';
import { QueryResult } from '../data/query/query.nut.js';
import type { BulkResultV2 } from '../../../src/types.js';
import type { QueryResult } from '../data/query/query.nut.js';

chaiConfig.truncateThreshold = 0;

Expand Down Expand Up @@ -98,29 +97,8 @@ describe('data:bulk commands', () => {
});
});

describe('bulk data commands with --verbose', () => {
it('should print table because of --verbose and errors', () => {
fs.writeFileSync(path.join(testSession.project.dir, 'data.csv'), `Id${os.EOL}001000000000000AAA`);

const result = execCmd('data:delete:bulk --sobject Account --file data.csv --wait 10 --verbose', {
ensureExitCode: 1,
}).shellOutput;
// Bulk Failures [1]
// ┌────────────────────┬────────────────────┬───────────────────────────────────────────────────────────┐
// │ Id │ Sf_Id │ Error │
// ├────────────────────┼────────────────────┼───────────────────────────────────────────────────────────┤
// │ 001000000000000AAA │ 001000000000000AAA │ INVALID_CROSS_REFERENCE_KEY:invalid cross reference id:-- │
// └────────────────────┴────────────────────┴───────────────────────────────────────────────────────────┘

expect(result).to.include('Bulk Failures [1]');
expect(result).to.include('Id');
expect(result).to.include('Sf_Id');
expect(result).to.include('Error');
expect(result).to.include('INVALID_CROSS_REFERENCE_KEY:invalid cross reference id');
// expect(result).to.include('MALFORMED_ID:bad id')
});

it('should not print table because of errors and missing --verbose', () => {
describe('bulk data commands', () => {
it('should not print table because of errors', () => {
fs.writeFileSync(path.join(testSession.project.dir, 'data.csv'), `Id${os.EOL}001000000000000AAA`);

const result = execCmd('data:delete:bulk --sobject Account --file data.csv --wait 10', { ensureExitCode: 1 })
Expand All @@ -129,60 +107,6 @@ describe('data:bulk commands', () => {
expect(result).to.not.include('Bulk Failures [1]');
});

it('should not print error table when there are no errors', () => {
// insert account
const accountId = execCmd<SaveResult>('data:create:record -s Account --values Name=test --json', {
ensureExitCode: 0,
}).jsonOutput?.result.id;
fs.writeFileSync(path.join(testSession.project.dir, 'account.csv'), `Id${os.EOL}${accountId}`);
const result = execCmd('data:delete:bulk --sobject Account --file account.csv --wait 10 --verbose', {
ensureExitCode: 0,
}).shellOutput.stdout;
expect(result).to.match(/Successful records: 1\s*Failed records: 0\s*Status: JobComplete/s);
expect(result).to.not.include('Bulk Failures');
});

it('bulk delete should have information in --json', () => {
fs.writeFileSync(path.join(testSession.project.dir, 'data.csv'), `Id${os.EOL}001000000000000AAA`);

const result = execCmd<BulkResultV2>(
'data:delete:bulk --sobject Account --file data.csv --wait 10 --verbose --json',
{ ensureExitCode: 1 }
).jsonOutput?.result.records;
/*
{
"status": 1,
"result": {
"jobInfo": {
"id": "<ID>",
"operation": "delete",
"object": "Account",
// ...
},
"records": {
"successfulResults": [],
"failedResults": [
{
"sf__Id": "",
"sf__Error": "MALFORMED_ID:malformed id 001000000000000AAA:--",
"Id": "001000000000000AAA"

],
"unprocessedRecords": []
}
},
"warnings": []
}
*/

expect(result?.failedResults[0]).to.have.all.keys('sf__Id', 'sf__Error', 'Id');
expect(result?.failedResults[0].sf__Id).to.equal('001000000000000AAA');
expect(result?.failedResults[0].sf__Error).to.equal('INVALID_CROSS_REFERENCE_KEY:invalid cross reference id:--');
// expect(result?.failedResults[0].sf__Error).to.equal('MALFORMED_ID:bad id 001000000000000AAA:--')
expect(result?.failedResults[0].Id).to.equal('001000000000000AAA');
expect(result?.successfulResults.length).to.equal(0);
});

it('bulk upsert should have information in --json', () => {
const result = execCmd<BulkResultV2>(
`data:upsert:bulk --sobject Account --file ${path.join(
Expand All @@ -208,24 +132,6 @@ describe('data:bulk commands', () => {
);
expect(result?.successfulResults[0].sf__Id?.length).to.equal(18);
});

it('should print verbose success with json', () => {
// insert account
const accountId = execCmd<SaveResult>('data:create:record -s Account --values Name=test --json', {
ensureExitCode: 0,
}).jsonOutput?.result.id;
fs.writeFileSync(path.join(testSession.project.dir, 'account.csv'), `Id${os.EOL}${accountId}`);

const result = execCmd<BulkResultV2>(
'data:delete:bulk --sobject Account --file account.csv --wait 10 --verbose --json',
{ ensureExitCode: 0 }
).jsonOutput?.result.records;
expect(result?.successfulResults[0]).to.have.all.keys('sf__Id', 'sf__Created', 'Id');
expect(result?.successfulResults[0].sf__Id).to.equal(accountId);
expect(result?.successfulResults[0].sf__Created).to.equal('false');
expect(result?.successfulResults[0].Id).to.equal(accountId);
expect(result?.failedResults.length).to.equal(0);
});
});
});

Expand Down