Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into sm/one-config-aggregator
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Apr 28, 2023
2 parents 67f06a8 + d8bc237 commit af6b338
Show file tree
Hide file tree
Showing 12 changed files with 308 additions and 637 deletions.
623 changes: 174 additions & 449 deletions CHANGELOG.md

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@salesforce/sf-plugins-core",
"version": "2.2.8",
"version": "2.2.11",
"description": "Utils for writing Salesforce CLI plugins",
"main": "lib/exported",
"types": "lib/exported.d.ts",
Expand Down Expand Up @@ -34,22 +34,22 @@
"dependencies": {
"@oclif/core": "^2.8.2",
"@salesforce/core": "^3.34.6",
"@salesforce/kit": "^1.9.0",
"@salesforce/kit": "^1.9.2",
"@salesforce/ts-types": "^1.7.3",
"chalk": "^4",
"inquirer": "^8.2.5"
},
"devDependencies": {
"@oclif/test": "^2.3.14",
"@salesforce/dev-config": "^3.0.0",
"@oclif/test": "^2.3.16",
"@salesforce/dev-config": "^3.1.0",
"@salesforce/dev-scripts": "^4.3.0",
"@salesforce/prettier-config": "^0.0.2",
"@salesforce/ts-sinon": "^1.4.6",
"@types/inquirer": "^8.2.3",
"@typescript-eslint/eslint-plugin": "^5.44.0",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"chai": "^4.3.7",
"eslint": "^8.38.0",
"eslint": "^8.39.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-salesforce": "^1.2.0",
"eslint-config-salesforce-license": "^0.2.0",
Expand Down
4 changes: 2 additions & 2 deletions src/flags/orgApiVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { Flags } from '@oclif/core';
import { Messages, sfdc, Lifecycle, OrgConfigProperties } from '@salesforce/core';
import { Messages, Lifecycle, OrgConfigProperties, validateApiVersion } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/sf-plugins-core', 'messages');
Expand Down Expand Up @@ -57,7 +57,7 @@ const getDefaultFromConfig = async (): Promise<string | undefined> => {

const validate = async (input: string): Promise<string> => {
// basic format check
if (!sfdc.validateApiVersion(input)) {
if (!validateApiVersion(input)) {
throw messages.createError('errors.InvalidApiVersion', [input]);
}
const requestedVersion = parseInt(input, 10);
Expand Down
46 changes: 41 additions & 5 deletions src/flags/orgFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { Flags } from '@oclif/core';
import { Messages, Org, ConfigAggregator, OrgConfigProperties } from '@salesforce/core';
import { ConfigAggregator, Messages, Org, OrgConfigProperties } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/sf-plugins-core', 'messages');
Expand Down Expand Up @@ -102,7 +102,16 @@ export const optionalOrgFlag = Flags.custom({
char: 'o',
parse: async (input: string | undefined) => maybeGetOrg(input),
default: async () => maybeGetOrg(),
defaultHelp: async () => (await maybeGetOrg())?.getUsername(),
defaultHelp: async (context, isWritingManifest) => {
if (isWritingManifest) {
return undefined;
}
if (context.options instanceof Org) {
const org = context.options as Org;
return org.getUsername();
}
return (await maybeGetOrg())?.getUsername();
},
});

/**
Expand Down Expand Up @@ -132,7 +141,16 @@ export const requiredOrgFlag = Flags.custom({
summary: messages.getMessage('flags.targetOrg.summary'),
parse: async (input: string | undefined) => getOrgOrThrow(input),
default: async () => getOrgOrThrow(),
defaultHelp: async () => (await getOrgOrThrow())?.getUsername(),
defaultHelp: async (context, isWritingManifest) => {
if (isWritingManifest) {
return undefined;
}
if (context.options instanceof Org) {
const org = context.options as Org;
return org.getUsername();
}
return (await maybeGetOrg())?.getUsername();
},
required: true,
});

Expand Down Expand Up @@ -163,7 +181,16 @@ export const requiredHubFlag = Flags.custom({
summary: messages.getMessage('flags.targetDevHubOrg.summary'),
parse: async (input: string | undefined) => getHubOrThrow(input),
default: async () => getHubOrThrow(),
defaultHelp: async () => (await getHubOrThrow())?.getUsername(),
defaultHelp: async (context, isWritingManifest) => {
if (isWritingManifest) {
return undefined;
}
if (context.options instanceof Org) {
const org = context.options as Org;
return org.getUsername();
}
return (await maybeGetHub())?.getUsername();
},
required: true,
});

Expand Down Expand Up @@ -193,6 +220,15 @@ export const optionalHubFlag = Flags.custom({
summary: messages.getMessage('flags.targetDevHubOrg.summary'),
parse: async (input: string | undefined) => maybeGetHub(input),
default: async () => maybeGetHub(),
defaultHelp: async () => (await maybeGetHub())?.getUsername(),
defaultHelp: async (context, isWritingManifest) => {
if (isWritingManifest) {
return undefined;
}
if (context.options instanceof Org) {
const org = context.options as Org;
return org.getUsername();
}
return (await maybeGetHub())?.getUsername();
},
required: false,
});
4 changes: 2 additions & 2 deletions src/flags/salesforceId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { Flags } from '@oclif/core';
import { Messages, sfdc } from '@salesforce/core';
import { Messages, validateSalesforceId } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/sf-plugins-core', 'messages');
Expand Down Expand Up @@ -60,7 +60,7 @@ const validate = (input: string, config?: IdFlagConfig): string => {
allowedIdLength.join(` ${messages.getMessage('errors.InvalidIdLength.or')} `),
]);
}
if (!sfdc.validateSalesforceId(input)) {
if (!validateSalesforceId(input)) {
throw messages.createError('errors.InvalidId');
}
if (startsWith && !input.startsWith(startsWith)) {
Expand Down
16 changes: 10 additions & 6 deletions src/sfCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,12 @@ export abstract class SfCommand<T> extends Command {
process.exitCode ??= codeFromError;

const sfErrorProperties = removeEmpty({
// @ts-expect-error because data is not on Error
data: (error.data as unknown) ?? null,
// @ts-expect-error because actions is not on Error
actions: (error.actions as string[]) ?? null,
code: codeFromError,
// @ts-expect-error because context is not on Error
context: (error.context as string) ?? null,
actions: 'actions' in error ? error.actions : null,
context: 'context' in error ? error.context : this.statics.name,
commandName: 'commandName' in error ? error.commandName : this.statics.name,
data: 'data' in error ? error.data : null,
result: 'result' in error ? error.result : null,
});

// Create printable error object
Expand Down Expand Up @@ -456,6 +455,10 @@ export abstract class SfCommand<T> extends Command {
// @ts-expect-error because skipOclifErrorHandling is not on SfError
err.skipOclifErrorHandling = true;

// Emit an event for plugin-telemetry prerun hook to pick up.
// @ts-expect-error because TS is strict about the events that can be emitted on process.
process.emit('sfCommandError', err);

throw err;
}

Expand Down Expand Up @@ -526,6 +529,7 @@ export namespace SfCommand {
exitCode?: number;
data?: unknown;
context?: string;
commandName?: string;
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../node_modules/@salesforce/dev-config/tsconfig",
"extends": "@salesforce/dev-config/tsconfig-test-strict",
"include": ["unit/**/*.ts", "../node_modules/@types/**/*.d.ts"],
"compilerOptions": {
"noEmit": true,
Expand Down
18 changes: 9 additions & 9 deletions test/unit/flags/duration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ describe('duration flag', () => {
};
it('passes', async () => {
const out = await Parser.parse(['--wait=10'], buildProps);
expect(out.flags.wait.quantity).to.equal(10);
expect(out.flags.wait.unit).to.equal(Duration.Unit.HOURS);
expect(out.flags.wait?.quantity).to.equal(10);
expect(out.flags.wait?.unit).to.equal(Duration.Unit.HOURS);
});
it('passes with default', async () => {
const out = await Parser.parse([], buildProps);
Expand All @@ -50,12 +50,12 @@ describe('duration flag', () => {
};
it('passes', async () => {
const out = await Parser.parse(['--wait=10'], buildProps);
expect(out.flags.wait.quantity).to.equal(10);
expect(out.flags.wait.unit).to.equal(Duration.Unit.WEEKS);
expect(out.flags.wait?.quantity).to.equal(10);
expect(out.flags.wait?.unit).to.equal(Duration.Unit.WEEKS);
});
it('passes with default', async () => {
const out = await Parser.parse([], buildProps);
expect(out.flags.wait.quantity).to.equal(33);
expect(out.flags.wait?.quantity).to.equal(33);
});
});

Expand All @@ -77,19 +77,19 @@ describe('duration flag', () => {
};
it('passes', async () => {
const out = await Parser.parse(['--wait=10'], buildProps);
expect(out.flags.wait.quantity).to.equal(10);
expect(out.flags.wait?.quantity).to.equal(10);
});
it('min passes', async () => {
const out = await Parser.parse([`--wait=${min}`], buildProps);
expect(out.flags.wait.quantity).to.equal(min);
expect(out.flags.wait?.quantity).to.equal(min);
});
it('max passes', async () => {
const out = await Parser.parse([`--wait=${max}`], buildProps);
expect(out.flags.wait.quantity).to.equal(max);
expect(out.flags.wait?.quantity).to.equal(max);
});
it('default works', async () => {
const out = await Parser.parse([], buildProps);
expect(out.flags.wait.quantity).to.equal(defaultValue);
expect(out.flags.wait?.quantity).to.equal(defaultValue);
});
describe('failures', () => {
it('below min fails', async () => {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/flags/orgFlags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ describe('org flags', () => {
it('no input, uses default', async () => {
await $$.stubConfig({ [OrgConfigProperties.TARGET_DEV_HUB]: testHub.username });
const retrieved = await maybeGetHub();
expect(retrieved).to.be.instanceOf(Org);
expect(retrieved.getOrgId()).to.equal(testHub.orgId);
assert(retrieved instanceof Org);
expect(retrieved?.getOrgId()).to.equal(testHub.orgId);
});
it('no input, uses default but is not a hub => throw', async () => {
await $$.stubConfig({ [OrgConfigProperties.TARGET_DEV_HUB]: testOrg.username });
Expand Down
8 changes: 6 additions & 2 deletions test/unit/sfCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ class TestCommand extends SfCommand<void> {
const { flags } = await this.parse(TestCommand);

if (flags.error && !flags.warn) {
const infoError = new SfError('foo bar baz', 'FooError', flags.actions ? ['this', 'is an', 'action'] : null);
const infoError = new SfError('foo bar baz', 'FooError', flags.actions ? ['this', 'is an', 'action'] : undefined);
this.info(infoError);
} else if (flags.warn) {
if (flags.error) {
const warnError = new SfError('foo bar baz', 'FooError', flags.actions ? ['this', 'is an', 'action'] : null);
const warnError = new SfError(
'foo bar baz',
'FooError',
flags.actions ? ['this', 'is an', 'action'] : undefined
);
this.warn(warnError);
} else {
this.warn('foo bar baz');
Expand Down
18 changes: 9 additions & 9 deletions test/unit/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('toHelpSection', () => {
const envVarSection = toHelpSection('ENV VAR SECTION', EnvironmentVariable.SFDX_ACCESS_TOKEN);
expect(envVarSection).to.have.property('header', 'ENV VAR SECTION');
expect(envVarSection).to.have.property('body').to.have.property('length', 1);
expect(envVarSection.body[0]).to.deep.equal({
expect(envVarSection?.body?.[0]).to.deep.equal({
name: 'SFDX_ACCESS_TOKEN',
description: SUPPORTED_ENV_VARS[EnvironmentVariable.SFDX_ACCESS_TOKEN].description,
});
Expand All @@ -36,9 +36,9 @@ describe('toHelpSection', () => {
expect(orgConfigSection).to.have.property('header', 'ORG CONFIG VAR SECTION');
expect(orgConfigSection).to.have.property('body').to.have.property('length', 1);
const orgConfig = ORG_CONFIG_ALLOWED_PROPERTIES.find(({ key }) => key === OrgConfigProperties.TARGET_ORG);
expect(orgConfigSection.body[0]).to.deep.equal({
expect(orgConfigSection?.body?.[0]).to.deep.equal({
name: 'target-org',
description: orgConfig.description,
description: orgConfig?.description,
});
});

Expand All @@ -47,9 +47,9 @@ describe('toHelpSection', () => {
expect(sfdxConfigSection).to.have.property('header', 'SFDX CONFIG VAR SECTION');
expect(sfdxConfigSection).to.have.property('body').to.have.property('length', 1);
const sfdxConfig = SFDX_ALLOWED_PROPERTIES.find(({ key }) => key === SfdxPropertyKeys.INSTANCE_URL);
expect(sfdxConfigSection.body[0]).to.deep.equal({
expect(sfdxConfigSection?.body?.[0]).to.deep.equal({
name: 'instanceUrl',
description: sfdxConfig.description,
description: sfdxConfig?.description,
});
});

Expand All @@ -64,18 +64,18 @@ describe('toHelpSection', () => {
expect(mixedSection).to.have.property('body').to.have.property('length', 3);
const sfdxConfig = SFDX_ALLOWED_PROPERTIES.find(({ key }) => key === SfdxPropertyKeys.INSTANCE_URL);
const orgConfig = ORG_CONFIG_ALLOWED_PROPERTIES.find(({ key }) => key === OrgConfigProperties.TARGET_ORG);
expect(mixedSection.body).to.deep.equal([
expect(mixedSection?.body).to.deep.equal([
{
name: 'SFDX_ACCESS_TOKEN',
description: SUPPORTED_ENV_VARS[EnvironmentVariable.SFDX_ACCESS_TOKEN].description,
},
{
name: 'target-org',
description: orgConfig.description,
description: orgConfig?.description,
},
{
name: 'instanceUrl',
description: sfdxConfig.description,
description: sfdxConfig?.description,
},
]);
});
Expand All @@ -84,7 +84,7 @@ describe('toHelpSection', () => {
const envVarSection = toHelpSection('ARBITRARY SECTION', { 'foo bar': 'hello world' });
expect(envVarSection).to.have.property('header', 'ARBITRARY SECTION');
expect(envVarSection).to.have.property('body').to.have.property('length', 1);
expect(envVarSection.body[0]).to.deep.equal({
expect(envVarSection?.body?.[0]).to.deep.equal({
name: 'foo bar',
description: 'hello world',
});
Expand Down
Loading

0 comments on commit af6b338

Please sign in to comment.