123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- "use strict";
- /**
- * @fileoverview Pass a context object when invoking a play function
- * @author Yann Braga
- */
- const create_storybook_rule_1 = require("../utils/create-storybook-rule");
- const constants_1 = require("../utils/constants");
- const ast_1 = require("../utils/ast");
- module.exports = (0, create_storybook_rule_1.createStorybookRule)({
- name: 'context-in-play-function',
- defaultOptions: [],
- meta: {
- type: 'problem',
- docs: {
- description: 'Pass a context when invoking play function of another story',
- categories: [constants_1.CategoryId.RECOMMENDED, constants_1.CategoryId.ADDON_INTERACTIONS],
- recommended: 'error',
- },
- messages: {
- passContextToPlayFunction: 'Pass a context when invoking play function of another story',
- },
- fixable: undefined,
- schema: [],
- },
- create(context) {
- // variables should be defined here
- //----------------------------------------------------------------------
- // Helpers
- //----------------------------------------------------------------------
- // any helper functions should go here or else delete this section
- const isPlayFunctionFromAnotherStory = (expr) => {
- if ((0, ast_1.isTSNonNullExpression)(expr.callee) &&
- (0, ast_1.isMemberExpression)(expr.callee.expression) &&
- (0, ast_1.isIdentifier)(expr.callee.expression.property) &&
- expr.callee.expression.property.name === 'play') {
- return true;
- }
- if ((0, ast_1.isMemberExpression)(expr.callee) &&
- (0, ast_1.isIdentifier)(expr.callee.property) &&
- expr.callee.property.name === 'play') {
- return true;
- }
- return false;
- };
- const getParentParameterName = (node) => {
- if (!(0, ast_1.isArrowFunctionExpression)(node)) {
- if (!node.parent) {
- return undefined;
- }
- return getParentParameterName(node.parent);
- }
- // No parameter found
- if (node.params.length === 0) {
- return undefined;
- }
- if (node.params.length >= 1) {
- const param = node.params[0];
- if ((0, ast_1.isIdentifier)(param)) {
- return param.name;
- }
- if ((0, ast_1.isObjectPattern)(param)) {
- const restElement = param.properties.find(ast_1.isRestElement);
- if (!restElement || !(0, ast_1.isIdentifier)(restElement.argument)) {
- // No rest element found
- return undefined;
- }
- return restElement.argument.name;
- }
- }
- return undefined;
- };
- // Expression passing an argument called context OR spreading a variable called context
- const isNotPassingContextCorrectly = (expr) => {
- const firstExpressionArgument = expr.arguments[0];
- if (!firstExpressionArgument) {
- return true;
- }
- const contextVariableName = getParentParameterName(expr);
- if (!contextVariableName) {
- return true;
- }
- if (expr.arguments.length === 1 &&
- (0, ast_1.isIdentifier)(firstExpressionArgument) &&
- firstExpressionArgument.name === contextVariableName) {
- return false;
- }
- if ((0, ast_1.isObjectExpression)(firstExpressionArgument) &&
- firstExpressionArgument.properties.some((prop) => {
- return ((0, ast_1.isSpreadElement)(prop) &&
- (0, ast_1.isIdentifier)(prop.argument) &&
- prop.argument.name === contextVariableName);
- })) {
- return false;
- }
- return true;
- };
- //----------------------------------------------------------------------
- // Public
- //----------------------------------------------------------------------
- const invocationsWithoutProperContext = [];
- return {
- CallExpression(node) {
- if (isPlayFunctionFromAnotherStory(node) && isNotPassingContextCorrectly(node)) {
- invocationsWithoutProperContext.push(node);
- }
- },
- 'Program:exit': function () {
- invocationsWithoutProperContext.forEach((node) => {
- context.report({
- node,
- messageId: 'passContextToPlayFunction',
- });
- });
- },
- };
- },
- });
|