@atlaskit/eslint-plugin-platform 2.2.0 → 2.3.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/eslint-plugin-platform
2
2
 
3
+ ## 2.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#108485](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108485)
8
+ [`0c642edaebbbb`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0c642edaebbbb) -
9
+ AFB-822 Modifying expand-spacing-shorthand ESLint rule to not throw error for non-token
10
+ expressions in template strings
11
+
12
+ ## 2.2.1
13
+
14
+ ### Patch Changes
15
+
16
+ - [#103444](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/103444)
17
+ [`5d5006fe81146`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/5d5006fe81146) -
18
+ AFB-822 Refactor ESLint rule and added an extra case for when ESLint rule should throw error but
19
+ not provide a fix
20
+
3
21
  ## 2.2.0
4
22
 
5
23
  ### Minor Changes
package/dist/cjs/index.js CHANGED
@@ -74,7 +74,7 @@ var commonConfig = {
74
74
  // Compiled: rules that are not included via `@compiled/recommended
75
75
  '@atlaskit/platform/expand-border-shorthand': 'error',
76
76
  '@atlaskit/platform/expand-background-shorthand': 'error',
77
- '@atlaskit/platform/expand-spacing-shorthand': 'off',
77
+ '@atlaskit/platform/expand-spacing-shorthand': 'error',
78
78
  '@compiled/jsx-pragma': ['error', {
79
79
  importSources: ['@atlaskit/css'],
80
80
  onlyRunIfImportingCompiled: true,
@@ -46,31 +46,75 @@ var parseTemplateLiteral = function parseTemplateLiteral(templateLiteral, contex
46
46
  }
47
47
  return propertyValues;
48
48
  };
49
- var checkValidPropertyValues = function checkValidPropertyValues(propertyValues) {
49
+
50
+ /**
51
+ * Checks if the parsed property values are valid; values that we shouldn't handle with the fixer:
52
+ * 1. At least one expression in TemplateLiteral is not a token expression
53
+ * 2. Do not contain a token
54
+ * 3. Have length that are not in the range [1, 4] for different spacing directions
55
+ * - No more than 4 to exclude additional values such as `!important`
56
+ * 4. Includes `calc(...)`
57
+ * Then, the rule will return with no error
58
+ * @param propertyValues property values parsed as list of strings
59
+ * @returns boolean
60
+ */
61
+ var isPropertyValueExempted = function isPropertyValueExempted(templateLiteral, propertyValues) {
62
+ var expressions = templateLiteral.expressions;
63
+ if (!expressions.every(function (expr) {
64
+ return expr.type === 'CallExpression' && isTokenCallExpression(expr);
65
+ })) {
66
+ return true;
67
+ }
50
68
  if (!propertyValues.some(function (str) {
51
69
  return str.includes('token(');
52
70
  })) {
53
- return false;
71
+ return true;
54
72
  }
55
73
  if (propertyValues.length < 1 || propertyValues.length > 4) {
56
- return false;
74
+ return true;
57
75
  }
58
76
  if (propertyValues.some(function (str) {
59
77
  return str.includes('calc(');
60
78
  })) {
61
- return false;
79
+ return true;
62
80
  }
63
- return true;
81
+ return false;
64
82
  };
65
83
 
66
- // Check that all expressions in TemplateLiteral are token expressions
67
- // If true: create an autofix
68
- // If false: report violation without autofix
69
- var hasOnlyTokens = function hasOnlyTokens(templateLiteral) {
70
- var expressions = templateLiteral.expressions;
71
- return expressions.every(function (expr) {
72
- return expr.type === 'CallExpression' && isTokenCallExpression(expr);
73
- });
84
+ /**
85
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when
86
+ * property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
87
+ * The rule will return with error and provide a fix
88
+ * @param templateLiteral TemplateLiteral AST Node
89
+ * @param propertyValues property values parsed as list of strings
90
+ * @returns boolean
91
+ */
92
+ var isPropertyValuesInvalidFix = function isPropertyValuesInvalidFix(propertyValues) {
93
+ var _iterator = _createForOfIteratorHelper(propertyValues),
94
+ _step;
95
+ try {
96
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
97
+ var propValue = _step.value;
98
+ if (propValue === '0') {
99
+ continue;
100
+ }
101
+ if (['auto', 'initial', 'inherit'].includes(propValue.slice(1, -1))) {
102
+ continue;
103
+ }
104
+ if (/^token\(.*\)$/.test(propValue)) {
105
+ continue;
106
+ }
107
+ if (/^['"]\d+(\.\d+)?((rem)|(em)|(px))['"]$/.test(propValue)) {
108
+ continue;
109
+ }
110
+ return false;
111
+ }
112
+ } catch (err) {
113
+ _iterator.e(err);
114
+ } finally {
115
+ _iterator.f();
116
+ }
117
+ return true;
74
118
  };
75
119
 
76
120
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -92,11 +136,11 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
92
136
  var fixes = [];
93
137
  var parentNode = node.parent;
94
138
  if (parentNode && parentNode.type === 'ObjectExpression') {
95
- var _iterator = _createForOfIteratorHelper(parentNode.properties),
96
- _step;
139
+ var _iterator2 = _createForOfIteratorHelper(parentNode.properties),
140
+ _step2;
97
141
  try {
98
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
99
- var prop = _step.value;
142
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
143
+ var prop = _step2.value;
100
144
  if (prop.type !== 'Property') {
101
145
  continue;
102
146
  }
@@ -121,9 +165,9 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
121
165
  }
122
166
  }
123
167
  } catch (err) {
124
- _iterator.e(err);
168
+ _iterator2.e(err);
125
169
  } finally {
126
- _iterator.f();
170
+ _iterator2.f();
127
171
  }
128
172
  }
129
173
  fixes.push(fixer.insertTextAfter(node, "".concat(propertyShorthand, "Top: ").concat(spacing[0], ",\n")));
@@ -138,8 +182,30 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
138
182
  return;
139
183
  }
140
184
  if (node.value.type === 'TemplateLiteral') {
141
- // Value of spacing property is a TemplateLiteral type that contains a token, e.g. padding: `0 token('a')`
142
- if (!hasOnlyTokens(node.value)) {
185
+ var propertyValues = parseTemplateLiteral(node.value, context);
186
+ if (isPropertyValueExempted(node.value, propertyValues)) {
187
+ // Valid, so no error should be thrown
188
+ return;
189
+ }
190
+ if (isPropertyValuesInvalidFix(propertyValues)) {
191
+ // Invalid, so error should be thrown and fix provided
192
+ context.report({
193
+ node: node,
194
+ messageId: 'expandSpacingShorthand',
195
+ data: {
196
+ property: propertyShorthand
197
+ },
198
+ fix: function fix(fixer) {
199
+ return expandSpacingProperties({
200
+ context: context,
201
+ node: node,
202
+ propertyValues: propertyValues,
203
+ fixer: fixer,
204
+ propertyShorthand: propertyShorthand
205
+ });
206
+ }
207
+ });
208
+ } else {
143
209
  context.report({
144
210
  node: node,
145
211
  messageId: 'expandSpacingShorthand',
@@ -149,26 +215,6 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
149
215
  });
150
216
  return;
151
217
  }
152
- var propertyValues = parseTemplateLiteral(node.value, context);
153
- if (!checkValidPropertyValues(propertyValues)) {
154
- return;
155
- }
156
- context.report({
157
- node: node,
158
- messageId: 'expandSpacingShorthand',
159
- data: {
160
- property: propertyShorthand
161
- },
162
- fix: function fix(fixer) {
163
- return expandSpacingProperties({
164
- context: context,
165
- node: node,
166
- propertyValues: propertyValues,
167
- fixer: fixer,
168
- propertyShorthand: propertyShorthand
169
- });
170
- }
171
- });
172
218
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
173
219
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
174
220
  var _propertyValues2 = [(0, _contextCompat.getSourceCode)(context).getText(node.value)];
@@ -65,7 +65,7 @@ const commonConfig = {
65
65
  // Compiled: rules that are not included via `@compiled/recommended
66
66
  '@atlaskit/platform/expand-border-shorthand': 'error',
67
67
  '@atlaskit/platform/expand-background-shorthand': 'error',
68
- '@atlaskit/platform/expand-spacing-shorthand': 'off',
68
+ '@atlaskit/platform/expand-spacing-shorthand': 'error',
69
69
  '@compiled/jsx-pragma': ['error', {
70
70
  importSources: ['@atlaskit/css'],
71
71
  onlyRunIfImportingCompiled: true,
@@ -35,25 +35,60 @@ 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; values that we shouldn't handle with the fixer:
41
+ * 1. At least one expression in TemplateLiteral is not a token expression
42
+ * 2. Do not contain a token
43
+ * 3. Have length that are not in the range [1, 4] for different spacing directions
44
+ * - No more than 4 to exclude additional values such as `!important`
45
+ * 4. Includes `calc(...)`
46
+ * Then, the rule will return with no error
47
+ * @param propertyValues property values parsed as list of strings
48
+ * @returns boolean
49
+ */
50
+ const isPropertyValueExempted = (templateLiteral, propertyValues) => {
51
+ const expressions = templateLiteral.expressions;
52
+ if (!expressions.every(expr => expr.type === 'CallExpression' && isTokenCallExpression(expr))) {
53
+ return true;
54
+ }
39
55
  if (!propertyValues.some(str => str.includes('token('))) {
40
- return false;
56
+ return true;
41
57
  }
42
58
  if (propertyValues.length < 1 || propertyValues.length > 4) {
43
- return false;
59
+ return true;
44
60
  }
45
61
  if (propertyValues.some(str => str.includes('calc('))) {
46
- return false;
62
+ return true;
47
63
  }
48
- return true;
64
+ return false;
49
65
  };
50
66
 
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 => {
55
- const expressions = templateLiteral.expressions;
56
- return expressions.every(expr => expr.type === 'CallExpression' && isTokenCallExpression(expr));
67
+ /**
68
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when
69
+ * property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
70
+ * The rule will return with error and provide a fix
71
+ * @param templateLiteral TemplateLiteral AST Node
72
+ * @param propertyValues property values parsed as list of strings
73
+ * @returns boolean
74
+ */
75
+ const isPropertyValuesInvalidFix = propertyValues => {
76
+ for (const propValue of propertyValues) {
77
+ if (propValue === '0') {
78
+ continue;
79
+ }
80
+ if (['auto', 'initial', 'inherit'].includes(propValue.slice(1, -1))) {
81
+ continue;
82
+ }
83
+ if (/^token\(.*\)$/.test(propValue)) {
84
+ continue;
85
+ }
86
+ if (/^['"]\d+(\.\d+)?((rem)|(em)|(px))['"]$/.test(propValue)) {
87
+ continue;
88
+ }
89
+ return false;
90
+ }
91
+ return true;
57
92
  };
58
93
 
59
94
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -104,8 +139,30 @@ const executeExpandSpacingRule = (context, node, propertyShorthand) => {
104
139
  return;
105
140
  }
106
141
  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)) {
142
+ const propertyValues = parseTemplateLiteral(node.value, context);
143
+ if (isPropertyValueExempted(node.value, propertyValues)) {
144
+ // Valid, so no error should be thrown
145
+ return;
146
+ }
147
+ if (isPropertyValuesInvalidFix(propertyValues)) {
148
+ // Invalid, so error should be thrown and fix provided
149
+ context.report({
150
+ node,
151
+ messageId: 'expandSpacingShorthand',
152
+ data: {
153
+ property: propertyShorthand
154
+ },
155
+ fix(fixer) {
156
+ return expandSpacingProperties({
157
+ context,
158
+ node,
159
+ propertyValues,
160
+ fixer,
161
+ propertyShorthand
162
+ });
163
+ }
164
+ });
165
+ } else {
109
166
  context.report({
110
167
  node,
111
168
  messageId: 'expandSpacingShorthand',
@@ -115,26 +172,6 @@ const executeExpandSpacingRule = (context, node, propertyShorthand) => {
115
172
  });
116
173
  return;
117
174
  }
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
175
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
139
176
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
140
177
  const propertyValues = [getSourceCode(context).getText(node.value)];
package/dist/esm/index.js CHANGED
@@ -68,7 +68,7 @@ var commonConfig = {
68
68
  // Compiled: rules that are not included via `@compiled/recommended
69
69
  '@atlaskit/platform/expand-border-shorthand': 'error',
70
70
  '@atlaskit/platform/expand-background-shorthand': 'error',
71
- '@atlaskit/platform/expand-spacing-shorthand': 'off',
71
+ '@atlaskit/platform/expand-spacing-shorthand': 'error',
72
72
  '@compiled/jsx-pragma': ['error', {
73
73
  importSources: ['@atlaskit/css'],
74
74
  onlyRunIfImportingCompiled: true,
@@ -39,31 +39,75 @@ 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; values that we shouldn't handle with the fixer:
45
+ * 1. At least one expression in TemplateLiteral is not a token expression
46
+ * 2. Do not contain a token
47
+ * 3. Have length that are not in the range [1, 4] for different spacing directions
48
+ * - No more than 4 to exclude additional values such as `!important`
49
+ * 4. Includes `calc(...)`
50
+ * Then, the rule will return with no error
51
+ * @param propertyValues property values parsed as list of strings
52
+ * @returns boolean
53
+ */
54
+ var isPropertyValueExempted = function isPropertyValueExempted(templateLiteral, propertyValues) {
55
+ var expressions = templateLiteral.expressions;
56
+ if (!expressions.every(function (expr) {
57
+ return expr.type === 'CallExpression' && isTokenCallExpression(expr);
58
+ })) {
59
+ return true;
60
+ }
43
61
  if (!propertyValues.some(function (str) {
44
62
  return str.includes('token(');
45
63
  })) {
46
- return false;
64
+ return true;
47
65
  }
48
66
  if (propertyValues.length < 1 || propertyValues.length > 4) {
49
- return false;
67
+ return true;
50
68
  }
51
69
  if (propertyValues.some(function (str) {
52
70
  return str.includes('calc(');
53
71
  })) {
54
- return false;
72
+ return true;
55
73
  }
56
- return true;
74
+ return false;
57
75
  };
58
76
 
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) {
63
- var expressions = templateLiteral.expressions;
64
- return expressions.every(function (expr) {
65
- return expr.type === 'CallExpression' && isTokenCallExpression(expr);
66
- });
77
+ /**
78
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when
79
+ * property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
80
+ * The rule will return with error and provide a fix
81
+ * @param templateLiteral TemplateLiteral AST Node
82
+ * @param propertyValues property values parsed as list of strings
83
+ * @returns boolean
84
+ */
85
+ var isPropertyValuesInvalidFix = function isPropertyValuesInvalidFix(propertyValues) {
86
+ var _iterator = _createForOfIteratorHelper(propertyValues),
87
+ _step;
88
+ try {
89
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
90
+ var propValue = _step.value;
91
+ if (propValue === '0') {
92
+ continue;
93
+ }
94
+ if (['auto', 'initial', 'inherit'].includes(propValue.slice(1, -1))) {
95
+ continue;
96
+ }
97
+ if (/^token\(.*\)$/.test(propValue)) {
98
+ continue;
99
+ }
100
+ if (/^['"]\d+(\.\d+)?((rem)|(em)|(px))['"]$/.test(propValue)) {
101
+ continue;
102
+ }
103
+ return false;
104
+ }
105
+ } catch (err) {
106
+ _iterator.e(err);
107
+ } finally {
108
+ _iterator.f();
109
+ }
110
+ return true;
67
111
  };
68
112
 
69
113
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -85,11 +129,11 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
85
129
  var fixes = [];
86
130
  var parentNode = node.parent;
87
131
  if (parentNode && parentNode.type === 'ObjectExpression') {
88
- var _iterator = _createForOfIteratorHelper(parentNode.properties),
89
- _step;
132
+ var _iterator2 = _createForOfIteratorHelper(parentNode.properties),
133
+ _step2;
90
134
  try {
91
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
92
- var prop = _step.value;
135
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
136
+ var prop = _step2.value;
93
137
  if (prop.type !== 'Property') {
94
138
  continue;
95
139
  }
@@ -114,9 +158,9 @@ var expandSpacingProperties = function expandSpacingProperties(_ref) {
114
158
  }
115
159
  }
116
160
  } catch (err) {
117
- _iterator.e(err);
161
+ _iterator2.e(err);
118
162
  } finally {
119
- _iterator.f();
163
+ _iterator2.f();
120
164
  }
121
165
  }
122
166
  fixes.push(fixer.insertTextAfter(node, "".concat(propertyShorthand, "Top: ").concat(spacing[0], ",\n")));
@@ -131,8 +175,30 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
131
175
  return;
132
176
  }
133
177
  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)) {
178
+ var propertyValues = parseTemplateLiteral(node.value, context);
179
+ if (isPropertyValueExempted(node.value, propertyValues)) {
180
+ // Valid, so no error should be thrown
181
+ return;
182
+ }
183
+ if (isPropertyValuesInvalidFix(propertyValues)) {
184
+ // Invalid, so error should be thrown and fix provided
185
+ context.report({
186
+ node: node,
187
+ messageId: 'expandSpacingShorthand',
188
+ data: {
189
+ property: propertyShorthand
190
+ },
191
+ fix: function fix(fixer) {
192
+ return expandSpacingProperties({
193
+ context: context,
194
+ node: node,
195
+ propertyValues: propertyValues,
196
+ fixer: fixer,
197
+ propertyShorthand: propertyShorthand
198
+ });
199
+ }
200
+ });
201
+ } else {
136
202
  context.report({
137
203
  node: node,
138
204
  messageId: 'expandSpacingShorthand',
@@ -142,26 +208,6 @@ var executeExpandSpacingRule = function executeExpandSpacingRule(context, node,
142
208
  });
143
209
  return;
144
210
  }
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
211
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
166
212
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
167
213
  var _propertyValues2 = [getSourceCode(context).getText(node.value)];
@@ -82,7 +82,7 @@ declare const plugin: {
82
82
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
83
83
  '@atlaskit/platform/expand-border-shorthand': "error";
84
84
  '@atlaskit/platform/expand-background-shorthand': "error";
85
- '@atlaskit/platform/expand-spacing-shorthand': "off";
85
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
86
86
  '@compiled/jsx-pragma': ["error", {
87
87
  importSources: string[];
88
88
  onlyRunIfImportingCompiled: boolean;
@@ -114,7 +114,7 @@ declare const plugin: {
114
114
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
115
115
  '@atlaskit/platform/expand-border-shorthand': "error";
116
116
  '@atlaskit/platform/expand-background-shorthand': "error";
117
- '@atlaskit/platform/expand-spacing-shorthand': "off";
117
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
118
118
  '@compiled/jsx-pragma': ["error", {
119
119
  importSources: string[];
120
120
  onlyRunIfImportingCompiled: boolean;
@@ -133,7 +133,7 @@ declare const plugin: {
133
133
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
134
134
  '@atlaskit/platform/expand-border-shorthand': "error";
135
135
  '@atlaskit/platform/expand-background-shorthand': "error";
136
- '@atlaskit/platform/expand-spacing-shorthand': "off";
136
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
137
137
  '@compiled/jsx-pragma': ["error", {
138
138
  importSources: string[];
139
139
  onlyRunIfImportingCompiled: boolean;
@@ -155,7 +155,7 @@ declare const plugin: {
155
155
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
156
156
  '@atlaskit/platform/expand-border-shorthand': "error";
157
157
  '@atlaskit/platform/expand-background-shorthand': "error";
158
- '@atlaskit/platform/expand-spacing-shorthand': "off";
158
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
159
159
  '@compiled/jsx-pragma': ["error", {
160
160
  importSources: string[];
161
161
  onlyRunIfImportingCompiled: boolean;
@@ -191,7 +191,7 @@ declare const configs: {
191
191
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
192
192
  '@atlaskit/platform/expand-border-shorthand': "error";
193
193
  '@atlaskit/platform/expand-background-shorthand': "error";
194
- '@atlaskit/platform/expand-spacing-shorthand': "off";
194
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
195
195
  '@compiled/jsx-pragma': ["error", {
196
196
  importSources: string[];
197
197
  onlyRunIfImportingCompiled: boolean;
@@ -223,7 +223,7 @@ declare const configs: {
223
223
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
224
224
  '@atlaskit/platform/expand-border-shorthand': "error";
225
225
  '@atlaskit/platform/expand-background-shorthand': "error";
226
- '@atlaskit/platform/expand-spacing-shorthand': "off";
226
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
227
227
  '@compiled/jsx-pragma': ["error", {
228
228
  importSources: string[];
229
229
  onlyRunIfImportingCompiled: boolean;
@@ -242,7 +242,7 @@ declare const configs: {
242
242
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
243
243
  '@atlaskit/platform/expand-border-shorthand': "error";
244
244
  '@atlaskit/platform/expand-background-shorthand': "error";
245
- '@atlaskit/platform/expand-spacing-shorthand': "off";
245
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
246
246
  '@compiled/jsx-pragma': ["error", {
247
247
  importSources: string[];
248
248
  onlyRunIfImportingCompiled: boolean;
@@ -264,7 +264,7 @@ declare const configs: {
264
264
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
265
265
  '@atlaskit/platform/expand-border-shorthand': "error";
266
266
  '@atlaskit/platform/expand-background-shorthand': "error";
267
- '@atlaskit/platform/expand-spacing-shorthand': "off";
267
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
268
268
  '@compiled/jsx-pragma': ["error", {
269
269
  importSources: string[];
270
270
  onlyRunIfImportingCompiled: boolean;
@@ -85,7 +85,7 @@ declare const plugin: {
85
85
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
86
86
  '@atlaskit/platform/expand-border-shorthand': "error";
87
87
  '@atlaskit/platform/expand-background-shorthand': "error";
88
- '@atlaskit/platform/expand-spacing-shorthand': "off";
88
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
89
89
  '@compiled/jsx-pragma': [
90
90
  "error",
91
91
  {
@@ -123,7 +123,7 @@ declare const plugin: {
123
123
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
124
124
  '@atlaskit/platform/expand-border-shorthand': "error";
125
125
  '@atlaskit/platform/expand-background-shorthand': "error";
126
- '@atlaskit/platform/expand-spacing-shorthand': "off";
126
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
127
127
  '@compiled/jsx-pragma': [
128
128
  "error",
129
129
  {
@@ -145,7 +145,7 @@ declare const plugin: {
145
145
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
146
146
  '@atlaskit/platform/expand-border-shorthand': "error";
147
147
  '@atlaskit/platform/expand-background-shorthand': "error";
148
- '@atlaskit/platform/expand-spacing-shorthand': "off";
148
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
149
149
  '@compiled/jsx-pragma': [
150
150
  "error",
151
151
  {
@@ -170,7 +170,7 @@ declare const plugin: {
170
170
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
171
171
  '@atlaskit/platform/expand-border-shorthand': "error";
172
172
  '@atlaskit/platform/expand-background-shorthand': "error";
173
- '@atlaskit/platform/expand-spacing-shorthand': "off";
173
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
174
174
  '@compiled/jsx-pragma': [
175
175
  "error",
176
176
  {
@@ -212,7 +212,7 @@ declare const configs: {
212
212
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
213
213
  '@atlaskit/platform/expand-border-shorthand': "error";
214
214
  '@atlaskit/platform/expand-background-shorthand': "error";
215
- '@atlaskit/platform/expand-spacing-shorthand': "off";
215
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
216
216
  '@compiled/jsx-pragma': [
217
217
  "error",
218
218
  {
@@ -250,7 +250,7 @@ declare const configs: {
250
250
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
251
251
  '@atlaskit/platform/expand-border-shorthand': "error";
252
252
  '@atlaskit/platform/expand-background-shorthand': "error";
253
- '@atlaskit/platform/expand-spacing-shorthand': "off";
253
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
254
254
  '@compiled/jsx-pragma': [
255
255
  "error",
256
256
  {
@@ -272,7 +272,7 @@ declare const configs: {
272
272
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
273
273
  '@atlaskit/platform/expand-border-shorthand': "error";
274
274
  '@atlaskit/platform/expand-background-shorthand': "error";
275
- '@atlaskit/platform/expand-spacing-shorthand': "off";
275
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
276
276
  '@compiled/jsx-pragma': [
277
277
  "error",
278
278
  {
@@ -297,7 +297,7 @@ declare const configs: {
297
297
  '@atlaskit/platform/no-module-level-eval-nav4': "error";
298
298
  '@atlaskit/platform/expand-border-shorthand': "error";
299
299
  '@atlaskit/platform/expand-background-shorthand': "error";
300
- '@atlaskit/platform/expand-spacing-shorthand': "off";
300
+ '@atlaskit/platform/expand-spacing-shorthand': "error";
301
301
  '@compiled/jsx-pragma': [
302
302
  "error",
303
303
  {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-platform",
3
3
  "description": "The essential plugin for use with Atlassian frontend platform tools",
4
- "version": "2.2.0",
4
+ "version": "2.3.0",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
7
7
  "team": "Build Infra",
@@ -31,7 +31,7 @@
31
31
  ".": "./src/index.tsx"
32
32
  },
33
33
  "dependencies": {
34
- "@atlaskit/eslint-utils": "^1.8.0",
34
+ "@atlaskit/eslint-utils": "^1.9.0",
35
35
  "@babel/runtime": "^7.0.0",
36
36
  "@compiled/eslint-plugin": "^0.18.2",
37
37
  "@manypkg/find-root": "^1.1.0",
package/src/index.tsx CHANGED
@@ -73,7 +73,7 @@ const commonConfig = {
73
73
  // Compiled: rules that are not included via `@compiled/recommended
74
74
  '@atlaskit/platform/expand-border-shorthand': 'error',
75
75
  '@atlaskit/platform/expand-background-shorthand': 'error',
76
- '@atlaskit/platform/expand-spacing-shorthand': 'off',
76
+ '@atlaskit/platform/expand-spacing-shorthand': 'error',
77
77
  '@compiled/jsx-pragma': [
78
78
  'error',
79
79
  {
@@ -79,6 +79,28 @@ const validTestCases = (property: string) => {
79
79
  });
80
80
  `,
81
81
  },
82
+ // Template literal containing expressions that is not token should only throw error with no autofix
83
+ {
84
+ name: `${property}: property value template string where it contains an expression that is not a token`,
85
+ code: outdent`
86
+ import {css} from '@compiled/react';
87
+ const styles = css({
88
+ ${property}: \`\${token('space.100', '8px')} \${gridSize * 2}px\`,
89
+ });
90
+ const styles2 = css({
91
+ padding: \`\${DROPDOWN_HEADER_VERTICAL_PADDING} \${token('space.075','6px')}
92
+ \${DROPDOWN_HEADER_VERTICAL_PADDING} \${token('space.200', '16px')}\`,
93
+ });
94
+ const styles3 = css({
95
+ ${property}: \`\${token('space.050', '4px')} \${token('space.150', '12px')} \${token('space.150', '12px')}
96
+ \${({ isSummaryView }: EditFormContentWrapperProps) =>
97
+ isSummaryView ? token('space.0', '0') : token('space.150', '12px')}\`,
98
+ });
99
+ const styles4 = css({
100
+ ${property}: \`\${token('space.100', '8px')} -\${gridSize}px 0\`,
101
+ });
102
+ `,
103
+ },
82
104
  ];
83
105
  };
84
106
 
@@ -252,25 +274,35 @@ const invalidTestCases = (property: string) => {
252
274
  `,
253
275
  errors: [{ messageId: 'expandSpacingShorthand' }],
254
276
  },
255
- // Template literal containing expressions that is not token should only throw error with no autofix
277
+ // Strings that are not valid property values should not be autofixed (e.g. !important)
256
278
  {
257
- name: `${property}: property value template string where it contains an expression that is not a token`,
279
+ name: `${property}: Don't autofix if not able to handle all the string values, e.g !important`,
258
280
  code: outdent`
259
281
  import {css} from '@compiled/react';
260
282
  const styles = css({
261
- ${property}: \`\${token('space.100', '8px')} \${gridSize * 2}px\`,
283
+ ${property}: \`0 \${token('space.200', '16px')} !important\`,
262
284
  });
263
- const styles2 = css({
264
- padding: \`\${DROPDOWN_HEADER_VERTICAL_PADDING} \${token('space.075','6px')}
265
- \${DROPDOWN_HEADER_VERTICAL_PADDING} \${token('space.200', '16px')}\`,
285
+ `,
286
+ errors: [{ messageId: 'expandSpacingShorthand' }],
287
+ },
288
+ {
289
+ name: `${property}: Autofix if able to handle all string values`,
290
+ code: outdent`
291
+ import {css} from '@compiled/react';
292
+ const styles = css({
293
+ ${property}: \`0 auto \${token('space.300', '24px')}\`,
266
294
  });
267
- const styles3 = css({
268
- ${property}: \`\${token('space.050', '4px')} \${token('space.150', '12px')} \${token('space.150', '12px')}
269
- \${({ isSummaryView }: EditFormContentWrapperProps) =>
270
- isSummaryView ? token('space.0', '0') : token('space.150', '12px')}\`,
295
+ `,
296
+ output: outdent`
297
+ import {css} from '@compiled/react';
298
+ const styles = css({
299
+ ${property}Top: 0,
300
+ ${property}Right: 'auto',
301
+ ${property}Bottom: token('space.300', '24px'),
302
+ ${property}Left: 'auto',
271
303
  });
272
304
  `,
273
- errors: Array.from(Array(3), () => ({ messageId: 'expandSpacingShorthand' })),
305
+ errors: [{ messageId: 'expandSpacingShorthand' }],
274
306
  },
275
307
  // Miscellaneous
276
308
  {
@@ -383,7 +415,7 @@ const invalidTestCases = (property: string) => {
383
415
  `,
384
416
  errors: Array.from(Array(2), () => ({ messageId: 'expandSpacingShorthand' })),
385
417
  },
386
- // TODO (AFB-1022): Resolve this failing test
418
+ // // TODO (AFB-1022): Resolve this failing test
387
419
  // {
388
420
  // name: `${property}: styled components with prop input`,
389
421
  // code: outdent`
@@ -49,25 +49,59 @@ const parseTemplateLiteral = (templateLiteral: TemplateLiteral, context: Rule.Ru
49
49
  return propertyValues;
50
50
  };
51
51
 
52
- const checkValidPropertyValues = (propertyValues: string[]) => {
52
+ /**
53
+ * Checks if the parsed property values are valid; values that we shouldn't handle with the fixer:
54
+ * 1. At least one expression in TemplateLiteral is not a token expression
55
+ * 2. Do not contain a token
56
+ * 3. Have length that are not in the range [1, 4] for different spacing directions
57
+ * - No more than 4 to exclude additional values such as `!important`
58
+ * 4. Includes `calc(...)`
59
+ * Then, the rule will return with no error
60
+ * @param propertyValues property values parsed as list of strings
61
+ * @returns boolean
62
+ */
63
+ const isPropertyValueExempted = (templateLiteral: TemplateLiteral, propertyValues: string[]) => {
64
+ const expressions = templateLiteral.expressions;
65
+ if (!expressions.every((expr) => expr.type === 'CallExpression' && isTokenCallExpression(expr))) {
66
+ return true;
67
+ }
53
68
  if (!propertyValues.some((str) => str.includes('token('))) {
54
- return false;
69
+ return true;
55
70
  }
56
71
  if (propertyValues.length < 1 || propertyValues.length > 4) {
57
- return false;
72
+ return true;
58
73
  }
59
74
  if (propertyValues.some((str) => str.includes('calc('))) {
60
- return false;
75
+ return true;
61
76
  }
62
- return true;
77
+ return false;
63
78
  };
64
79
 
65
- // Check that all expressions in TemplateLiteral are token expressions
66
- // If true: create an autofix
67
- // If false: report violation without autofix
68
- const hasOnlyTokens = (templateLiteral: TemplateLiteral) => {
69
- const expressions = templateLiteral.expressions;
70
- return expressions.every((expr) => expr.type === 'CallExpression' && isTokenCallExpression(expr));
80
+ /**
81
+ * Checks if the parsed property values are invalid (i.e. rule violation thrown) and autofix required. Cases are when
82
+ * property values must have a format which includes -> e.g. 2, '2(rem|em|px)', auto, initial, inherit, token(...)
83
+ * The rule will return with error and provide a fix
84
+ * @param templateLiteral TemplateLiteral AST Node
85
+ * @param propertyValues property values parsed as list of strings
86
+ * @returns boolean
87
+ */
88
+ const isPropertyValuesInvalidFix = (propertyValues: string[]) => {
89
+ for (const propValue of propertyValues) {
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
+ return true;
71
105
  };
72
106
 
73
107
  // To fix spacing shorthands, given a list of spacing property values, expands the spacing property and adds autofix fixes
@@ -130,8 +164,30 @@ const executeExpandSpacingRule = (
130
164
  return;
131
165
  }
132
166
  if (node.value.type === 'TemplateLiteral') {
133
- // Value of spacing property is a TemplateLiteral type that contains a token, e.g. padding: `0 token('a')`
134
- if (!hasOnlyTokens(node.value)) {
167
+ const propertyValues = parseTemplateLiteral(node.value, context);
168
+ if (isPropertyValueExempted(node.value, propertyValues)) {
169
+ // Valid, so no error should be thrown
170
+ return;
171
+ }
172
+ if (isPropertyValuesInvalidFix(propertyValues)) {
173
+ // Invalid, so error should be thrown and fix provided
174
+ context.report({
175
+ node,
176
+ messageId: 'expandSpacingShorthand',
177
+ data: {
178
+ property: propertyShorthand,
179
+ },
180
+ fix(fixer) {
181
+ return expandSpacingProperties({
182
+ context,
183
+ node,
184
+ propertyValues,
185
+ fixer,
186
+ propertyShorthand,
187
+ });
188
+ },
189
+ });
190
+ } else {
135
191
  context.report({
136
192
  node,
137
193
  messageId: 'expandSpacingShorthand',
@@ -141,20 +197,6 @@ const executeExpandSpacingRule = (
141
197
  });
142
198
  return;
143
199
  }
144
- const propertyValues = parseTemplateLiteral(node.value, context);
145
- if (!checkValidPropertyValues(propertyValues)) {
146
- return;
147
- }
148
- context.report({
149
- node,
150
- messageId: 'expandSpacingShorthand',
151
- data: {
152
- property: propertyShorthand,
153
- },
154
- fix(fixer) {
155
- return expandSpacingProperties({ context, node, propertyValues, fixer, propertyShorthand });
156
- },
157
- });
158
200
  } else if (node.value.type === 'CallExpression' && isTokenCallExpression(node.value)) {
159
201
  // Value of spacing property is a token CallExpression type, e.g. margin: token('space.100', '8px')
160
202
  const propertyValues = [getSourceCode(context).getText(node.value)];
@@ -1,7 +1,7 @@
1
1
  ### Notes
2
2
 
3
3
  - feature-gating/\* rules are copied from
4
- [eslint-plugin-jira/rules/ff](https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/jira/build-tools/eslint-plugin-jira/rules/ff)
4
+ [eslint-plugin-jira/rules/ff](https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/jira/dev-tooling/packages/eslint-plugin-jira/rules/ff)
5
5
  with small variations as mentioned in this
6
6
  [PR](https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/115546/overview)
7
7
  - these rules could be a WIP since they are still targeting JFE libraries- see