eslint-plugin-sf-plugin
Version:
Helpful eslint rules for sf plugins.
100 lines (99 loc) • 5.18 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.noThisFlags = void 0;
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils");
const utils_1 = require("@typescript-eslint/utils");
const commands_1 = require("../../shared/commands");
const expressions_1 = require("../../shared/expressions");
exports.noThisFlags = eslint_utils_1.RuleCreator.withoutDocs({
meta: {
docs: {
description: 'Fix references to this.org (property on SfdxCommand)',
recommended: 'recommended',
},
messages: {
noThisFlags: 'SfCommand does not have a this.flags property. Make sure you parse the flag.',
useFlags: 'change this.flags to flags',
instanceProp: 'create a this.flags property on SfCommand',
setThisFlags: 'flags is defined on the class, but never set. Set it equal to the parsed flags property.',
},
hasSuggestions: true,
type: 'suggestion',
schema: [],
fixable: 'code',
},
defaultOptions: [],
create(context) {
return (0, commands_1.isInCommandDirectory)(context)
? {
MemberExpression(node) {
var _a;
if ((0, expressions_1.MemberExpressionIsThisDotFoo)(node, 'flags') && (0, commands_1.ancestorsContainsSfCommand)(context)) {
// it's ok if there's a this.flags on the class...
const classAbove = (0, commands_1.getSfCommand)(context);
if (!classAbove) {
return;
}
const runMethod = (0, commands_1.getRunMethod)(classAbove);
if (!runMethod) {
return;
}
if (classAbove.body.body.find((b) => b.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
b.key.type === utils_1.AST_NODE_TYPES.Identifier &&
b.key.name === 'flags' &&
b.static === false)) {
// ...as long as it's been set in the run method
const flagsParse = (runMethod === null || runMethod === void 0 ? void 0 : runMethod.type) === utils_1.AST_NODE_TYPES.MethodDefinition
? (_a = runMethod.value.body) === null || _a === void 0 ? void 0 : _a.body.find((b) => b.type === utils_1.AST_NODE_TYPES.VariableDeclaration &&
context.sourceCode.getText(b).includes('this.parse'))
: undefined;
const source = context.sourceCode.getText();
if (!source.includes('this.flags = ') && flagsParse) {
context.report({
node,
messageId: 'instanceProp',
fix: (fixer) => fixer.insertTextAfter(flagsParse, 'this.flags = flags;'),
});
}
}
// we have no this.flags.
// in run method, convert to parsed flags value.
else if (context.getAncestors().some((b) => (0, commands_1.isRunMethod)(b))) {
context.report({
node,
messageId: 'noThisFlags',
fix: (fixer) => fixer.replaceText(node, 'flags'),
});
}
else if (runMethod) {
// otherwise, your options are: Make one, or use flags
context.report({
node,
messageId: 'noThisFlags',
suggest: [
{
messageId: 'useFlags',
fix: (fixer) => fixer.replaceText(node, 'flags'),
},
{
messageId: 'instanceProp',
fix: (fixer) => {
var _a;
return fixer.insertTextBefore(runMethod, `private flags: Interfaces.InferredFlags<typeof ${(_a = classAbove.id) === null || _a === void 0 ? void 0 : _a.name}.flags>;`);
},
},
],
});
}
}
},
}
: {};
},
});
;