@atlaskit/eslint-plugin-platform 2.1.2 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ const parseTemplateLiteral = (templateLiteral, context) => {
21
21
  if (cookedQuasi) {
22
22
  const splitQuasis = cookedQuasi.split(' ');
23
23
  splitQuasis.forEach(str => {
24
- str = str.trim().replace("\'", "");
24
+ str = str.trim().replace("'", '');
25
25
  if (str.length > 0) {
26
26
  propertyValues.push(isNaN(Number(str)) ? `'${str}'` : str);
27
27
  }
@@ -35,25 +35,59 @@ const parseTemplateLiteral = (templateLiteral, context) => {
35
35
  }
36
36
  return propertyValues;
37
37
  };
38
- const checkValidPropertyValues = propertyValues => {
38
+
39
+ /**
40
+ * Checks if the parsed property values are valid (i.e. no rule violation will be thrown). Cases are, the property values:
41
+ * 1. Do not contain a token
42
+ * 2. Have length that are not in the range [1, 4]
43
+ * 3. Includes `calc(...)`
44
+ * Then, the rule will return with no error
45
+ * @param propertyValues property values parsed as list of strings
46
+ * @returns boolean
47
+ */
48
+ const isPropertyValueExempted = propertyValues => {
39
49
  if (!propertyValues.some(str => str.includes('token('))) {
40
- return false;
50
+ return true;
41
51
  }
42
52
  if (propertyValues.length < 1 || propertyValues.length > 4) {
43
- return false;
53
+ return true;
44
54
  }
45
55
  if (propertyValues.some(str => str.includes('calc('))) {
46
- return false;
56
+ return true;
47
57
  }
48
- return true;
58
+ return false;
49
59
  };
50
60
 
51
- // Check that all expressions in TemplateLiteral are token expressions
52
- // If true: create an autofix
53
- // If false: report violation without autofix
54
- const hasOnlyTokens = templateLiteral => {
61
+ /**
62
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when:
63
+ * 1. All expressions in TemplateLiteral are token expressions
64
+ * 2. Property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
65
+ * The rule will return with error and provide a fix
66
+ * @param templateLiteral TemplateLiteral AST Node
67
+ * @param propertyValues property values parsed as list of strings
68
+ * @returns boolean
69
+ */
70
+ const isPropertyValuesInvalidFix = (templateLiteral, propertyValues) => {
55
71
  const expressions = templateLiteral.expressions;
56
- return expressions.every(expr => expr.type === 'CallExpression' && isTokenCallExpression(expr));
72
+ if (!expressions.every(expr => expr.type === 'CallExpression' && isTokenCallExpression(expr))) {
73
+ return false;
74
+ }
75
+ for (const propValue of propertyValues) {
76
+ if (propValue === '0') {
77
+ continue;
78
+ }
79
+ if (['auto', 'initial', 'inherit'].includes(propValue.slice(1, -1))) {
80
+ continue;
81
+ }
82
+ if (/^token\(.*\)$/.test(propValue)) {
83
+ continue;
84
+ }
85
+ if (/^['"]\d+(\.\d+)?((rem)|(em)|(px))['"]$/.test(propValue)) {
86
+ continue;
87
+ }
88
+ return false;
89
+ }
90
+ return true;
57
91
  };
58
92
 
59
93
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -104,8 +138,30 @@ const executeExpandSpacingRule = (context, node, propertyShorthand) => {
104
138
  return;
105
139
  }
106
140
  if (node.value.type === 'TemplateLiteral') {
107
- // Value of spacing property is a TemplateLiteral type that contains a token, e.g. padding: `0 token('a')`
108
- if (!hasOnlyTokens(node.value)) {
141
+ const propertyValues = parseTemplateLiteral(node.value, context);
142
+ if (isPropertyValueExempted(propertyValues)) {
143
+ // Valid, so no error should be thrown
144
+ return;
145
+ }
146
+ if (isPropertyValuesInvalidFix(node.value, propertyValues)) {
147
+ // Invalid, so error should be thrown and fix provided
148
+ context.report({
149
+ node,
150
+ messageId: 'expandSpacingShorthand',
151
+ data: {
152
+ property: propertyShorthand
153
+ },
154
+ fix(fixer) {
155
+ return expandSpacingProperties({
156
+ context,
157
+ node,
158
+ propertyValues,
159
+ fixer,
160
+ propertyShorthand
161
+ });
162
+ }
163
+ });
164
+ } else {
109
165
  context.report({
110
166
  node,
111
167
  messageId: 'expandSpacingShorthand',
@@ -115,26 +171,6 @@ const executeExpandSpacingRule = (context, node, propertyShorthand) => {
115
171
  });
116
172
  return;
117
173
  }
118
- const propertyValues = parseTemplateLiteral(node.value, context);
119
- if (!checkValidPropertyValues(propertyValues)) {
120
- return;
121
- }
122
- context.report({
123
- node,
124
- messageId: 'expandSpacingShorthand',
125
- data: {
126
- property: propertyShorthand
127
- },
128
- fix(fixer) {
129
- return expandSpacingProperties({
130
- context,
131
- node,
132
- propertyValues,
133
- fixer,
134
- propertyShorthand
135
- });
136
- }
137
- });
138
174
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
139
175
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
140
176
  const propertyValues = [getSourceCode(context).getText(node.value)];
package/dist/esm/index.js CHANGED
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  // eslint-disable-next-line import/no-extraneous-dependencies
5
-
5
+ import compiledPlugin from '@compiled/eslint-plugin';
6
6
  import ensureFeatureFlagRegistration from './rules/ensure-feature-flag-registration';
7
7
  import noPreAndPostInstallScripts from './rules/no-pre-post-installs';
8
8
  import ensureTestRunnerArguments from './rules/ensure-test-runner-arguments';
@@ -29,7 +29,8 @@ import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
29
29
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
30
30
  import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
31
31
  import expandSpacingShorthand from './rules/compiled/expand-spacing-shorthand';
32
- export var rules = {
32
+ var packageJson = require('@atlaskit/eslint-plugin-platform/package.json');
33
+ var rules = {
33
34
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
34
35
  'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
35
36
  'ensure-test-runner-arguments': ensureTestRunnerArguments,
@@ -74,75 +75,116 @@ var commonConfig = {
74
75
  runtime: 'classic'
75
76
  }]
76
77
  };
77
- export var configs = {
78
- recommended: {
79
- plugins: ['@atlaskit/platform', '@compiled'],
80
- rules: _objectSpread(_objectSpread({}, commonConfig), {}, {
81
- // See platform/packages/platform/eslint-plugin/src/rules/feature-gating/README.md
82
- // These rules are specific to `platform` and seem a WIP; jira and confluence currently have their own rules
83
- '@atlaskit/platform/no-module-level-eval': 'error',
84
- '@atlaskit/platform/static-feature-flags': 'error',
85
- '@atlaskit/platform/no-preconditioning': 'error',
86
- '@atlaskit/platform/inline-usage': 'error',
87
- '@atlaskit/platform/prefer-fg': 'error',
88
- '@atlaskit/platform/no-alias': 'error',
89
- // end: feature-gating rules
90
- '@atlaskit/platform/ensure-feature-flag-registration': 'error',
91
- '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
92
- allowedPrefixes: ['platform.', 'platform_']
93
- }]
94
- })
95
- },
96
- jira: {
97
- plugins: ['@atlaskit/platform', '@compiled'],
98
- rules: _objectSpread({}, commonConfig)
99
- }
100
- };
78
+ var recommendedRules = _objectSpread(_objectSpread({}, commonConfig), {}, {
79
+ // See platform/packages/platform/eslint-plugin/src/rules/feature-gating/README.md
80
+ // These rules are specific to `platform` and seem a WIP; jira and confluence currently have their own rules
81
+ '@atlaskit/platform/no-module-level-eval': 'error',
82
+ '@atlaskit/platform/static-feature-flags': 'error',
83
+ '@atlaskit/platform/no-preconditioning': 'error',
84
+ '@atlaskit/platform/inline-usage': 'error',
85
+ '@atlaskit/platform/prefer-fg': 'error',
86
+ '@atlaskit/platform/no-alias': 'error',
87
+ // end: feature-gating rules
88
+ '@atlaskit/platform/ensure-feature-flag-registration': 'error',
89
+ '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
90
+ allowedPrefixes: ['platform.', 'platform_']
91
+ }]
92
+ });
93
+ var jiraRules = commonConfig;
101
94
  var jsonPrefix = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, @typescript-eslint/semi, no-template-curly-in-string */ module.exports = ';
102
95
  var jsonPrefixForFlatConfig = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, no-template-curly-in-string */ module.exports = ';
103
- export var processors = {
104
- 'package-json-processor': {
105
- preprocess: function preprocess(source) {
106
- // augment the json into a js file
107
- return [jsonPrefix + source.trim()];
96
+ var name = packageJson.name,
97
+ version = packageJson.version;
98
+ var plugin = {
99
+ meta: {
100
+ name: name,
101
+ version: version
102
+ },
103
+ rules: rules,
104
+ configs: {
105
+ recommended: {
106
+ plugins: ['@atlaskit/platform', '@compiled'],
107
+ rules: recommendedRules
108
108
  },
109
- postprocess: function postprocess(messages) {
110
- return messages[0].map(function (message) {
111
- var fix = message.fix;
112
- if (!fix) {
113
- return message;
109
+ 'recommended/flat': {
110
+ plugins: {
111
+ get '@atlaskit/platform'() {
112
+ return plugin;
113
+ },
114
+ // @ts-expect-error there's an issue with the types for @compiled/eslint-plugin ('no-css-prop-without-css-function' specifically)
115
+ '@compiled': {
116
+ meta: compiledPlugin.meta,
117
+ rules: compiledPlugin.rules
114
118
  }
115
- var offset = jsonPrefix.length;
116
- return _objectSpread(_objectSpread({}, message), {}, {
117
- fix: _objectSpread(_objectSpread({}, fix), {}, {
118
- range: [fix.range[0] - offset, fix.range[1] - offset]
119
- })
120
- });
121
- });
119
+ },
120
+ rules: recommendedRules
122
121
  },
123
- supportsAutofix: true
124
- },
125
- // This processor is used for ESLint FlatConfig,
126
- // once we roll out FlatConfig, we can remove the above processor
127
- 'package-json-processor-for-flat-config': {
128
- preprocess: function preprocess(source) {
129
- // augment the json into a js file
130
- return [jsonPrefixForFlatConfig + source.trim()];
122
+ jira: {
123
+ plugins: ['@atlaskit/platform', '@compiled'],
124
+ rules: jiraRules
131
125
  },
132
- postprocess: function postprocess(messages) {
133
- return messages[0].map(function (message) {
134
- var fix = message.fix;
135
- if (!fix) {
136
- return message;
126
+ 'jira/flat': {
127
+ plugins: {
128
+ get '@atlaskit/platform'() {
129
+ return plugin;
130
+ },
131
+ // @ts-expect-error there's an issue with the types for @compiled/eslint-plugin ('no-css-prop-without-css-function' specifically)
132
+ '@compiled': {
133
+ meta: compiledPlugin.meta,
134
+ rules: compiledPlugin.rules
137
135
  }
138
- var offset = jsonPrefixForFlatConfig.length;
139
- return _objectSpread(_objectSpread({}, message), {}, {
140
- fix: _objectSpread(_objectSpread({}, fix), {}, {
141
- range: [fix.range[0] - offset, fix.range[1] - offset]
142
- })
136
+ },
137
+ rules: jiraRules
138
+ }
139
+ },
140
+ processors: {
141
+ 'package-json-processor': {
142
+ preprocess: function preprocess(source) {
143
+ // augment the json into a js file
144
+ return [jsonPrefix + source.trim()];
145
+ },
146
+ postprocess: function postprocess(messages) {
147
+ return messages[0].map(function (message) {
148
+ var fix = message.fix;
149
+ if (!fix) {
150
+ return message;
151
+ }
152
+ var offset = jsonPrefix.length;
153
+ return _objectSpread(_objectSpread({}, message), {}, {
154
+ fix: _objectSpread(_objectSpread({}, fix), {}, {
155
+ range: [fix.range[0] - offset, fix.range[1] - offset]
156
+ })
157
+ });
143
158
  });
144
- });
159
+ },
160
+ supportsAutofix: true
145
161
  },
146
- supportsAutofix: true
162
+ // This processor is used for ESLint FlatConfig,
163
+ // once we roll out FlatConfig, we can remove the above processor
164
+ 'package-json-processor-for-flat-config': {
165
+ preprocess: function preprocess(source) {
166
+ // augment the json into a js file
167
+ return [jsonPrefixForFlatConfig + source.trim()];
168
+ },
169
+ postprocess: function postprocess(messages) {
170
+ return messages[0].map(function (message) {
171
+ var fix = message.fix;
172
+ if (!fix) {
173
+ return message;
174
+ }
175
+ var offset = jsonPrefixForFlatConfig.length;
176
+ return _objectSpread(_objectSpread({}, message), {}, {
177
+ fix: _objectSpread(_objectSpread({}, fix), {}, {
178
+ range: [fix.range[0] - offset, fix.range[1] - offset]
179
+ })
180
+ });
181
+ });
182
+ },
183
+ supportsAutofix: true
184
+ }
147
185
  }
148
- };
186
+ };
187
+ var configs = plugin.configs;
188
+ var processors = plugin.processors;
189
+ export { configs, plugin, processors, rules };
190
+ export default plugin;
@@ -25,7 +25,7 @@ var parseTemplateLiteral = function parseTemplateLiteral(templateLiteral, contex
25
25
  if (cookedQuasi) {
26
26
  var splitQuasis = cookedQuasi.split(' ');
27
27
  splitQuasis.forEach(function (str) {
28
- str = str.trim().replace("\'", "");
28
+ str = str.trim().replace("'", '');
29
29
  if (str.length > 0) {
30
30
  propertyValues.push(isNaN(Number(str)) ? "'".concat(str, "'") : str);
31
31
  }
@@ -39,31 +39,74 @@ var parseTemplateLiteral = function parseTemplateLiteral(templateLiteral, contex
39
39
  }
40
40
  return propertyValues;
41
41
  };
42
- var checkValidPropertyValues = function checkValidPropertyValues(propertyValues) {
42
+
43
+ /**
44
+ * Checks if the parsed property values are valid (i.e. no rule violation will be thrown). Cases are, the property values:
45
+ * 1. Do not contain a token
46
+ * 2. Have length that are not in the range [1, 4]
47
+ * 3. Includes `calc(...)`
48
+ * Then, the rule will return with no error
49
+ * @param propertyValues property values parsed as list of strings
50
+ * @returns boolean
51
+ */
52
+ var isPropertyValueExempted = function isPropertyValueExempted(propertyValues) {
43
53
  if (!propertyValues.some(function (str) {
44
54
  return str.includes('token(');
45
55
  })) {
46
- return false;
56
+ return true;
47
57
  }
48
58
  if (propertyValues.length < 1 || propertyValues.length > 4) {
49
- return false;
59
+ return true;
50
60
  }
51
61
  if (propertyValues.some(function (str) {
52
62
  return str.includes('calc(');
53
63
  })) {
54
- return false;
64
+ return true;
55
65
  }
56
- return true;
66
+ return false;
57
67
  };
58
68
 
59
- // Check that all expressions in TemplateLiteral are token expressions
60
- // If true: create an autofix
61
- // If false: report violation without autofix
62
- var hasOnlyTokens = function hasOnlyTokens(templateLiteral) {
69
+ /**
70
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when:
71
+ * 1. All expressions in TemplateLiteral are token expressions
72
+ * 2. Property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
73
+ * The rule will return with error and provide a fix
74
+ * @param templateLiteral TemplateLiteral AST Node
75
+ * @param propertyValues property values parsed as list of strings
76
+ * @returns boolean
77
+ */
78
+ var isPropertyValuesInvalidFix = function isPropertyValuesInvalidFix(templateLiteral, propertyValues) {
63
79
  var expressions = templateLiteral.expressions;
64
- return expressions.every(function (expr) {
80
+ if (!expressions.every(function (expr) {
65
81
  return expr.type === 'CallExpression' && isTokenCallExpression(expr);
66
- });
82
+ })) {
83
+ return false;
84
+ }
85
+ var _iterator = _createForOfIteratorHelper(propertyValues),
86
+ _step;
87
+ try {
88
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
89
+ var propValue = _step.value;
90
+ if (propValue === '0') {
91
+ continue;
92
+ }
93
+ if (['auto', 'initial', 'inherit'].includes(propValue.slice(1, -1))) {
94
+ continue;
95
+ }
96
+ if (/^token\(.*\)$/.test(propValue)) {
97
+ continue;
98
+ }
99
+ if (/^['"]\d+(\.\d+)?((rem)|(em)|(px))['"]$/.test(propValue)) {
100
+ continue;
101
+ }
102
+ return false;
103
+ }
104
+ } catch (err) {
105
+ _iterator.e(err);
106
+ } finally {
107
+ _iterator.f();
108
+ }
109
+ return true;
67
110
  };
68
111
 
69
112
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -85,11 +128,11 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
85
128
  var fixes = [];
86
129
  var parentNode = node.parent;
87
130
  if (parentNode && parentNode.type === 'ObjectExpression') {
88
- var _iterator = _createForOfIteratorHelper(parentNode.properties),
89
- _step;
131
+ var _iterator2 = _createForOfIteratorHelper(parentNode.properties),
132
+ _step2;
90
133
  try {
91
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
92
- var prop = _step.value;
134
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
135
+ var prop = _step2.value;
93
136
  if (prop.type !== 'Property') {
94
137
  continue;
95
138
  }
@@ -114,9 +157,9 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
114
157
  }
115
158
  }
116
159
  } catch (err) {
117
- _iterator.e(err);
160
+ _iterator2.e(err);
118
161
  } finally {
119
- _iterator.f();
162
+ _iterator2.f();
120
163
  }
121
164
  }
122
165
  fixes.push(fixer.insertTextAfter(node, "".concat(propertyShorthand, "Top: ").concat(spacing[0], ",\n")));
@@ -131,8 +174,30 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
131
174
  return;
132
175
  }
133
176
  if (node.value.type === 'TemplateLiteral') {
134
- // Value of spacing property is a TemplateLiteral type that contains a token, e.g. padding: `0 token('a')`
135
- if (!hasOnlyTokens(node.value)) {
177
+ var propertyValues = parseTemplateLiteral(node.value, context);
178
+ if (isPropertyValueExempted(propertyValues)) {
179
+ // Valid, so no error should be thrown
180
+ return;
181
+ }
182
+ if (isPropertyValuesInvalidFix(node.value, propertyValues)) {
183
+ // Invalid, so error should be thrown and fix provided
184
+ context.report({
185
+ node: node,
186
+ messageId: 'expandSpacingShorthand',
187
+ data: {
188
+ property: propertyShorthand
189
+ },
190
+ fix: function fix(fixer) {
191
+ return expandSpacingProperties({
192
+ context: context,
193
+ node: node,
194
+ propertyValues: propertyValues,
195
+ fixer: fixer,
196
+ propertyShorthand: propertyShorthand
197
+ });
198
+ }
199
+ });
200
+ } else {
136
201
  context.report({
137
202
  node: node,
138
203
  messageId: 'expandSpacingShorthand',
@@ -142,26 +207,6 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
142
207
  });
143
208
  return;
144
209
  }
145
- var propertyValues = parseTemplateLiteral(node.value, context);
146
- if (!checkValidPropertyValues(propertyValues)) {
147
- return;
148
- }
149
- context.report({
150
- node: node,
151
- messageId: 'expandSpacingShorthand',
152
- data: {
153
- property: propertyShorthand
154
- },
155
- fix: function fix(fixer) {
156
- return expandSpacingProperties({
157
- context: context,
158
- node: node,
159
- propertyValues: propertyValues,
160
- fixer: fixer,
161
- propertyShorthand: propertyShorthand
162
- });
163
- }
164
- });
165
210
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
166
211
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
167
212
  var _propertyValues2 = [getSourceCode(context).getText(node.value)];