meta-inline-properties.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. "use strict";
  2. /**
  3. * @fileoverview Meta should have inline properties
  4. * @author Yann Braga
  5. */
  6. const utils_1 = require("../utils");
  7. const constants_1 = require("../utils/constants");
  8. const create_storybook_rule_1 = require("../utils/create-storybook-rule");
  9. module.exports = (0, create_storybook_rule_1.createStorybookRule)({
  10. name: 'meta-inline-properties',
  11. defaultOptions: [{ csfVersion: 3 }],
  12. meta: {
  13. type: 'problem',
  14. docs: {
  15. description: 'Meta should only have inline properties',
  16. categories: [constants_1.CategoryId.CSF, constants_1.CategoryId.RECOMMENDED],
  17. excludeFromConfig: true,
  18. recommended: 'error',
  19. },
  20. messages: {
  21. metaShouldHaveInlineProperties: 'Meta should only have inline properties: {{property}}',
  22. },
  23. schema: [
  24. {
  25. type: 'object',
  26. properties: {
  27. csfVersion: {
  28. type: 'number',
  29. },
  30. },
  31. additionalProperties: false,
  32. },
  33. ],
  34. },
  35. create(context) {
  36. // variables should be defined here
  37. // In case we need to get options defined in the rule schema
  38. // const options = context.options[0] || {}
  39. // const csfVersion = options.csfVersion
  40. //----------------------------------------------------------------------
  41. // Helpers
  42. //----------------------------------------------------------------------
  43. const isInline = (node) => {
  44. if (!(node && typeof node === 'object' && 'value' in node)) {
  45. return false;
  46. }
  47. return (node.value.type === 'ObjectExpression' ||
  48. node.value.type === 'Literal' ||
  49. node.value.type === 'ArrayExpression');
  50. };
  51. // any helper functions should go here or else delete this section
  52. //----------------------------------------------------------------------
  53. // Public
  54. //----------------------------------------------------------------------
  55. return {
  56. ExportDefaultDeclaration(node) {
  57. const meta = (0, utils_1.getMetaObjectExpression)(node, context);
  58. if (!meta) {
  59. return null;
  60. }
  61. const ruleProperties = ['title', 'args'];
  62. const dynamicProperties = [];
  63. const metaNodes = meta.properties.filter((prop) => 'key' in prop && 'name' in prop.key && ruleProperties.includes(prop.key.name));
  64. metaNodes.forEach((metaNode) => {
  65. if (!isInline(metaNode)) {
  66. dynamicProperties.push(metaNode);
  67. }
  68. });
  69. if (dynamicProperties.length > 0) {
  70. dynamicProperties.forEach((propertyNode) => {
  71. var _a;
  72. context.report({
  73. node: propertyNode,
  74. messageId: 'metaShouldHaveInlineProperties',
  75. data: {
  76. property: (_a = propertyNode.key) === null || _a === void 0 ? void 0 : _a.name,
  77. },
  78. });
  79. });
  80. }
  81. },
  82. };
  83. },
  84. });