File: meta-property-ordering.js

package info (click to toggle)
node-eslint-plugin-eslint-plugin 2.3.0%2B~0.3.0-6
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 652 kB
  • sloc: javascript: 5,372; makefile: 34; sh: 1
file content (88 lines) | stat: -rw-r--r-- 2,368 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
 * @fileoverview Enforces the order of meta properties
 */

'use strict';

const { getKeyName, getRuleInfo } = require('../utils');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
  meta: {
    docs: {
      description: 'enforce the order of meta properties',
      category: 'Rules',
      recommended: false,
    },
    type: 'suggestion',
    fixable: 'code',
    schema: [{
      type: 'array',
      items: { type: 'string' },
    }],
  },

  create (context) {
    const sourceCode = context.getSourceCode();
    const info = getRuleInfo(sourceCode.ast);

    const message = 'The meta properties should be placed in a consistent order: [{{order}}].';
    const order = context.options[0] || ['type', 'docs', 'fixable', 'schema', 'messages'];

    const orderMap = new Map(order.map((name, i) => [name, i]));

    return {
      Program () {
        if (
          !info ||
          !info.meta ||
          info.meta.properties.length < 2
        ) {
          return;
        }

        const props = info.meta.properties;

        let last;

        const violatingProps = props.filter(prop => {
          const curr = orderMap.has(getKeyName(prop))
            ? orderMap.get(getKeyName(prop))
            : Infinity;
          return last > (last = curr);
        });

        if (violatingProps.length === 0) {
          return;
        }

        const knownProps = props
          .filter(prop => orderMap.has(getKeyName(prop)))
          .sort((a, b) => orderMap.get(getKeyName(a)) - orderMap.get(getKeyName(b)));
        const unknownProps = props.filter(prop => !orderMap.has(getKeyName(prop)));

        for (const violatingProp of violatingProps) {
          context.report({
            node: violatingProp,
            message,
            data: {
              order: knownProps.map(getKeyName).join(', '),
            },
            fix (fixer) {
              const expectedProps = [...knownProps, ...unknownProps];
              return props.map((prop, k) => {
                return fixer.replaceText(
                  prop,
                  sourceCode.getText(expectedProps[k])
                );
              });
            },
          });
        }
      },
    };
  },
};