Skip to content

Commit

Permalink
fix(eslint-plugin): only take return statement into account with no-m…
Browse files Browse the repository at this point in the history
…ultiple-actions-in-effects
  • Loading branch information
timdeschryver committed Jun 24, 2024
1 parent a15d53e commit 77572ff
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ export class Effects {
)
}
}`,
`
export const saveSearchCriteria$ = createEffect(
(actions$ = inject(Actions$), store = inject(Store), saveLoadService = inject(SaveLoadService)) => {
return actions$.pipe(
ofType(SearchCriteriaActions.save),
concatLatestFrom(() => store.select(inventoryFeature.selectInventoryItems)),
concatMap(([{ searchCriteriaName }, inventoryItems]) => {
const tags = Object.keys(inventoryItems)
.filter((inventoryType) => {
const [, inventorySearchType] = splitInventoryType(inventoryType as InventoryType);
return inventorySearchType === 'costCenter' || inventorySearchType === 'wbs';
})
.map((inventoryType) => splitInventoryType(inventoryType as InventoryType))
.map(([value, type]) => ({ value, type }));
return saveLoadService.saveSearch(searchCriteriaName, tags, false).pipe(
map(() => SearchCriteriaActions.saveSucceeded()),
catchError((error: Error) => {
if (error instanceof HttpErrorResponse && error.status === 409) {
return of(SearchCriteriaActions.saveAlreadyExists({ searchCriteriaName, tags }));
}
return defaultErrorHadnler(error, 'inventoryDomain.messages.saveSearchFailed', SearchCriteriaActions.saveFailed());
})
);
})
);
},
{ functional: true }
);
`,
];

const invalid: () => RunTests['invalid'] = () => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import * as path from 'path';
import { createRule } from '../../rule-creator';
import {
createEffectExpression,
mapLikeOperatorsExplicitReturn,
mapLikeOperatorsImplicitReturn,
isBlockStatement,
isReturnStatement,
mapLikeOperatorCallExpressions,
} from '../../utils';

export const messageId = 'noMultipleActionsInEffects';
Expand All @@ -18,6 +19,7 @@ type Options = readonly unknown[];
type EffectsMapLikeOperatorsReturn =
| TSESTree.ArrowFunctionExpression
| TSESTree.CallExpression
| TSESTree.FunctionExpression
| TSESTree.ReturnStatement;

export default createRule<Options, MessageIds>({
Expand All @@ -37,7 +39,7 @@ export default createRule<Options, MessageIds>({
defaultOptions: [],
create: (context) => {
return {
[`${createEffectExpression} :matches(${mapLikeOperatorsImplicitReturn}, ${mapLikeOperatorsExplicitReturn})`](
[`${createEffectExpression} ${mapLikeOperatorCallExpressions}`](
node: EffectsMapLikeOperatorsReturn
) {
const nodeToReport = getNodeToReport(node);
Expand Down Expand Up @@ -71,10 +73,20 @@ export default createRule<Options, MessageIds>({
function getNodeToReport(node: EffectsMapLikeOperatorsReturn) {
switch (node.type) {
case AST_NODE_TYPES.ArrowFunctionExpression:
return node.body;
case AST_NODE_TYPES.FunctionExpression:
return isBlockStatement(node.body)
? findReturnStatement(node.body.body)
: node.body;
case AST_NODE_TYPES.CallExpression:
return node.arguments[0];
return findReturnStatement(node.arguments) ?? node.arguments[0];
default:
return node.argument;
}
}

function findReturnStatement(nodes: TSESTree.Node[]) {
const returnNode = nodes.find((n): n is TSESTree.ReturnStatement =>
isReturnStatement(n)
);
return returnNode?.argument;
}
2 changes: 1 addition & 1 deletion modules/eslint-plugin/src/utils/helper-functions/guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const isTSInstantiationExpression = isNodeOfType(
);
export const isProperty = isNodeOfType(AST_NODE_TYPES.Property);
export const isArrayExpression = isNodeOfType(AST_NODE_TYPES.ArrayExpression);

export const isBlockStatement = isNodeOfType(AST_NODE_TYPES.BlockStatement);
export function isIdentifierOrMemberExpression(
node: TSESTree.Node
): node is TSESTree.Identifier | TSESTree.MemberExpression {
Expand Down
6 changes: 2 additions & 4 deletions modules/eslint-plugin/src/utils/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,5 @@ export const actionReducerMap = `VariableDeclarator[id.typeAnnotation.typeAnnota

const mapLikeOperators = '/^(concat|exhaust|flat|merge|switch)Map$/';
const mapLikeToOperators = '/^(concat|merge|switch)MapTo$/';
export const mapLikeOperatorsExplicitReturn =
`CallExpression[callee.name=${mapLikeOperators}] ReturnStatement` as const;
export const mapLikeOperatorsImplicitReturn =
`:matches(CallExpression[callee.name=${mapLikeToOperators}], CallExpression[callee.name=${mapLikeOperators}] > ArrowFunctionExpression)` as const;
export const mapLikeOperatorCallExpressions =
`:matches(CallExpression[callee.name=${mapLikeToOperators}], CallExpression[callee.name=${mapLikeOperators}] > :matches(ReturnStatement,ArrowFunctionExpression,FunctionExpression))` as const;

0 comments on commit 77572ff

Please sign in to comment.