Skip to content
This repository has been archived by the owner on Jul 10, 2023. It is now read-only.

Commit

Permalink
fix: update flag types
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Sep 28, 2022
1 parent 9208d31 commit fa0a5f1
Show file tree
Hide file tree
Showing 6 changed files with 1,205 additions and 1,148 deletions.
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@
"!lib/**/*.map"
],
"dependencies": {
"@oclif/core": "^1.14.1",
"@oclif/plugin-help": "^5.1.11",
"@oclif/test": "^2.1.0",
"@salesforce/core": "^3.30.8",
"@oclif/core": "^1.16.4",
"@oclif/test": "^2.2.0",
"@salesforce/core": "^3.30.9",
"@salesforce/kit": "^1.6.1",
"@salesforce/ts-types": "^1.5.21",
"chalk": "^2.4.2"
Expand Down Expand Up @@ -66,7 +65,7 @@
"pretty-quick": "^3.1.0",
"sinon": "10.0.0",
"ts-node": "^10.0.0",
"typescript": "^4.7.4"
"typescript": "^4.8.3"
},
"types": "lib/exported.d.ts",
"publishConfig": {
Expand Down
3 changes: 2 additions & 1 deletion src/sfdxCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export abstract class SfdxCommand extends Command {

private isJson = false;

// Overrides @oclif/command static flags property. Adds username flags
// Overrides @oclif/core static flags property. Adds username flags
// if the command supports them. Builds flags defined by the command's
// flagsConfig static property.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -482,6 +482,7 @@ export abstract class SfdxCommand extends Command {
const def = this.statics.flagsConfig[flag];
if (def?.deprecated) {
this.ux.warn(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
UX.formatDeprecationWarning({
name: flag,
type: 'flag',
Expand Down
42 changes: 31 additions & 11 deletions src/sfdxFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Logger, LoggerLevel, Messages, sfdc, SfError } from '@salesforce/core';
import { Duration, toNumber } from '@salesforce/kit';
import {
definiteEntriesOf,
Dictionary,
ensure,
has,
hasFunction,
Expand All @@ -24,6 +23,7 @@ import {
Omit,
Optional,
} from '@salesforce/ts-types';
import { CustomOptionFlag } from '@oclif/core/lib/interfaces/parser';
import { Deprecation } from './ux';

Messages.importMessagesDirectory(__dirname);
Expand Down Expand Up @@ -117,7 +117,8 @@ export namespace flags {
export type Any<T> = Partial<Interfaces.Flag<T>> & SfdxProperties;
export type Array<T = string> = Option<T[]> & { delimiter?: string };
export type BaseBoolean<T> = Partial<Interfaces.BooleanFlag<T>>;
export type Boolean<T> = BaseBoolean<T> & SfdxProperties;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Boolean<T = any> = BaseBoolean<T> & SfdxProperties;
export type Bounds<T> = { min?: T; max?: T };
export type Builtin = { type: 'builtin' } & Partial<SfdxProperties>;
export type DateTime = Option<Date>;
Expand All @@ -135,7 +136,8 @@ export namespace flags {
export type Minutes = Option<Duration> & Bounds<Duration | number>;
export type Number = Option<number> & NumericBounds;
export type NumericBounds = Bounds<number>;
export type Option<T> = Partial<Interfaces.OptionFlag<T>> & SfdxProperties & Validatable;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Option<T = any> = Partial<CustomOptionFlag<T>> & SfdxProperties & Validatable;
export type Output = Interfaces.FlagOutput;
// allow numeric bounds for back compat
export type Seconds = Option<Duration> & Bounds<Duration | number>;
Expand All @@ -145,6 +147,9 @@ export namespace flags {
export type Validatable = { validate?: string | RegExp | ((val: string) => boolean) };
}

// type Distribute<U> = U extends keyof typeof flags ? flags.Discriminated<U> & flags.SfdxProperties & flags.Validatable: never;
// export type AnyDiscriminated = Distribute<keyof typeof flags>;

// oclif

function buildBoolean<T = boolean>(options: flags.Boolean<T>): flags.Discriminated<flags.Boolean<T>> {
Expand All @@ -159,7 +164,7 @@ function buildEnum<T>(options: flags.Enum<T>): flags.Discriminated<flags.Enum<T>
options: options.options,
description: options.description,
longDescription: options.longDescription,
};
} as flags.Discriminated<flags.Enum<T>>;
}

function buildHelp(options: flags.BaseBoolean<boolean>): flags.Discriminated<flags.Boolean<void>> {
Expand Down Expand Up @@ -218,7 +223,7 @@ function buildOption<T>(
}

function buildString(options: flags.String): flags.Discriminated<flags.String> {
return merge<string>('string', OclifFlags.string(options), options);
return option('string', options, (val: string) => Promise.resolve(val));
}

function buildVersion(options?: flags.BaseBoolean<boolean>): flags.Discriminated<flags.Boolean<void>> {
Expand Down Expand Up @@ -626,7 +631,7 @@ export const optionalBuiltinFlags = {
* ```
*/
export type FlagsConfig = {
[key: string]: Optional<flags.Boolean<unknown> | flags.Option<unknown> | flags.Builtin>;
[key: string]: Optional<flags.Boolean | flags.Option | flags.Builtin>;

/**
* Adds the `apiversion` built-in flag to allow for overriding the API
Expand Down Expand Up @@ -671,7 +676,7 @@ export type FlagsConfig = {
* @param {string} key The flag name.
* @throws SfError If the criteria is not meet.
*/
function validateCustomFlag<T>(key: string, flag: flags.Any<T>): flags.Any<T> {
function validateCustomFlag<T>(key: string, flag: flags.Boolean<T> | flags.Option<T>): flags.Boolean<T> | flags.Option<T> {
if (!/^(?!(?:[-]|[0-9]*$))[a-z0-9-]+$/.test(key)) {
throw messages.createError('error.InvalidFlagName', [key]);
}
Expand All @@ -692,6 +697,17 @@ function isBuiltin(flag: object): flag is flags.Builtin {
return hasString(flag, 'type') && flag.type === 'builtin';
}

type Output = {
json: flags.Discriminated<flags.Boolean<boolean>>;
loglevel: flags.Discriminated<flags.Enum<string>>;
targetdevhubusername?: flags.Discriminated<flags.String>;
targetusername?: flags.Discriminated<flags.String>;
apiversion?: flags.Discriminated<flags.String>;
concise?: flags.Discriminated<flags.Boolean<boolean>>;
quiet?: flags.Discriminated<flags.Boolean<boolean>>;
verbose?: flags.Discriminated<flags.Boolean<boolean>>;
};

/**
* Builds flags for a command given a configuration object. Supports the following use cases:
* 1. Enabling common SFDX flags. E.g., { verbose: true }
Expand All @@ -706,26 +722,30 @@ function isBuiltin(flag: object): flag is flags.Builtin {
export function buildSfdxFlags(
flagsConfig: FlagsConfig,
options: { targetdevhubusername?: boolean; targetusername?: boolean }
// tslint:disable-next-line:no-any matches oclif
): flags.Output {
const output: Dictionary<flags.Any<unknown>> = {};

// Required flag options for all SFDX commands
output.json = requiredBuiltinFlags.json();
output.loglevel = requiredBuiltinFlags.loglevel();
const output: Output = {
json: requiredBuiltinFlags.json(),
loglevel: requiredBuiltinFlags.loglevel(),
};

if (options.targetdevhubusername) output.targetdevhubusername = optionalBuiltinFlags.targetdevhubusername();
if (options.targetusername) output.targetusername = optionalBuiltinFlags.targetusername();
if (options.targetdevhubusername || options.targetusername) output.apiversion = optionalBuiltinFlags.apiversion();

// Process configuration for custom and builtin flags
definiteEntriesOf(flagsConfig).forEach(([key, flag]) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
if (isBuiltin(flag)) {
if (!isKeyOf(optionalBuiltinFlags, key)) {
throw messages.createError('error.UnknownBuiltinFlagType', [key]);
}
// @ts-ignore
output[key] = optionalBuiltinFlags[key](flag);
} else {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
output[key] = validateCustomFlag<unknown>(key, flag);
}
});
Expand Down
4 changes: 4 additions & 0 deletions src/ux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ export class UX {
let msg: string;
if (has(def, 'version')) {
const version = isString(def.version) ? parseInt(def.version, 10) : def.version || 0;
// @ts-ignore
const type = ensure(def.type);
// @ts-ignore
const name = ensure(def.name);
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
msg = `The ${type} "${name}" has been deprecated and will be removed in v${version + 1}.0 or later.`;
} else {
msg = def.messageOverride;
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "./node_modules/@salesforce/dev-config/tsconfig-strict",
"compilerOptions": {
"outDir": "./lib"
"outDir": "./lib",
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}
Loading

0 comments on commit fa0a5f1

Please sign in to comment.