@atlaskit/eslint-plugin-design-system 9.2.1 → 9.2.2
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 +10 -0
- package/dist/cjs/rules/utils/create-no-tagged-template-expression-rule/generate.js +2 -2
- package/dist/cjs/rules/utils/create-no-tagged-template-expression-rule/index.js +49 -19
- package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/generate.js +2 -2
- package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/index.js +30 -4
- package/dist/esm/rules/utils/create-no-tagged-template-expression-rule/generate.js +2 -2
- package/dist/esm/rules/utils/create-no-tagged-template-expression-rule/index.js +50 -20
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 9.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#86321](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/86321) [`b353b26e22b6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/b353b26e22b6) - Improvements for `no-*-tagged-template-expression` rules:
|
|
8
|
+
|
|
9
|
+
- Fixed a bug that could produce syntax errors when mixins were present in nested selectors.
|
|
10
|
+
- Disabled autofixing styled components usages with mixins in nested selectors, as there is no general equivalent.
|
|
11
|
+
- Disabled autofixing function interpolations with non-expression bodies.
|
|
12
|
+
|
|
3
13
|
## 9.2.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -83,7 +83,7 @@ var generateBlock = function generateBlock(blocks, offset, level) {
|
|
|
83
83
|
};
|
|
84
84
|
var generateArguments = function generateArguments(args, offset, level) {
|
|
85
85
|
var chars = '';
|
|
86
|
-
if (level
|
|
86
|
+
if (level >= 1 && args.length > 1) {
|
|
87
87
|
chars += '[';
|
|
88
88
|
}
|
|
89
89
|
var _iterator2 = _createForOfIteratorHelper(args.entries()),
|
|
@@ -124,7 +124,7 @@ var generateArguments = function generateArguments(args, offset, level) {
|
|
|
124
124
|
} finally {
|
|
125
125
|
_iterator2.f();
|
|
126
126
|
}
|
|
127
|
-
if (level
|
|
127
|
+
if (level >= 1 && args.length > 1) {
|
|
128
128
|
chars += '\n';
|
|
129
129
|
chars += indent(offset, level);
|
|
130
130
|
chars += ']';
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.noTaggedTemplateExpressionRuleSchema = exports.createNoTaggedTemplateExpressionRule = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _esquery = _interopRequireDefault(require("esquery"));
|
|
9
10
|
var _isSupportedImport = require("../is-supported-import");
|
|
10
11
|
var _generate = require("./generate");
|
|
11
12
|
var _getTaggedTemplateExpressionOffset = require("./get-tagged-template-expression-offset");
|
|
@@ -47,7 +48,7 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
|
|
|
47
48
|
messageId: messageId,
|
|
48
49
|
node: node,
|
|
49
50
|
fix: /*#__PURE__*/_regenerator.default.mark(function fix(fixer) {
|
|
50
|
-
var quasi, source, args, oldCode, withoutQuasi, newCode, usesEmotion;
|
|
51
|
+
var quasi, source, matches, args, oldCode, withoutQuasi, newCode, usesEmotion;
|
|
51
52
|
return _regenerator.default.wrap(function fix$(_context) {
|
|
52
53
|
while (1) switch (_context.prev = _context.next) {
|
|
53
54
|
case 0:
|
|
@@ -62,22 +63,35 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
|
|
|
62
63
|
}
|
|
63
64
|
return _context.abrupt("return");
|
|
64
65
|
case 4:
|
|
66
|
+
matches = (0, _esquery.default)(node, 'ArrowFunctionExpression > BlockStatement');
|
|
67
|
+
if (!matches.length) {
|
|
68
|
+
_context.next = 7;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
return _context.abrupt("return");
|
|
72
|
+
case 7:
|
|
65
73
|
if (!(!quasi.expressions.length && quasi.quasis.length === 1 && !quasi.quasis[0].value.raw.trim())) {
|
|
66
|
-
_context.next =
|
|
74
|
+
_context.next = 11;
|
|
67
75
|
break;
|
|
68
76
|
}
|
|
69
|
-
_context.next =
|
|
77
|
+
_context.next = 10;
|
|
70
78
|
return fixer.replaceText(quasi, '({})');
|
|
71
|
-
case
|
|
79
|
+
case 10:
|
|
72
80
|
return _context.abrupt("return");
|
|
73
|
-
case
|
|
74
|
-
args = (0, _toArguments.toArguments)(source, quasi);
|
|
81
|
+
case 11:
|
|
82
|
+
args = (0, _toArguments.toArguments)(source, quasi);
|
|
83
|
+
if (!((0, _isSupportedImport.isStyledComponents)(node.tag, references, importSources) && args.some(hasMixinInsideNestedSelector))) {
|
|
84
|
+
_context.next = 14;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
return _context.abrupt("return");
|
|
88
|
+
case 14:
|
|
75
89
|
if (!(args.length < 1)) {
|
|
76
|
-
_context.next =
|
|
90
|
+
_context.next = 16;
|
|
77
91
|
break;
|
|
78
92
|
}
|
|
79
93
|
return _context.abrupt("return");
|
|
80
|
-
case
|
|
94
|
+
case 16:
|
|
81
95
|
oldCode = source.getText(node); // Remove quasi:
|
|
82
96
|
// styled.div<Props>`
|
|
83
97
|
// color: red;
|
|
@@ -89,33 +103,33 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
|
|
|
89
103
|
// Indent the arguments after the tagged template expression range
|
|
90
104
|
(0, _generate.generate)(args, (0, _getTaggedTemplateExpressionOffset.getTaggedTemplateExpressionOffset)(node));
|
|
91
105
|
if (!(oldCode === newCode)) {
|
|
92
|
-
_context.next =
|
|
106
|
+
_context.next = 21;
|
|
93
107
|
break;
|
|
94
108
|
}
|
|
95
109
|
return _context.abrupt("return");
|
|
96
|
-
case
|
|
110
|
+
case 21:
|
|
97
111
|
// For styles like `position: initial !important`,
|
|
98
112
|
// Emotion can give typechecking errors when using object syntax
|
|
99
113
|
// due to csstype being overly strict
|
|
100
114
|
usesEmotion = (0, _isSupportedImport.isEmotion)(node.tag, references, importSources);
|
|
101
115
|
if (!(usesEmotion && !!newCode.match(/!\s*important/gm))) {
|
|
102
|
-
_context.next =
|
|
116
|
+
_context.next = 24;
|
|
103
117
|
break;
|
|
104
118
|
}
|
|
105
119
|
return _context.abrupt("return");
|
|
106
|
-
case
|
|
120
|
+
case 24:
|
|
107
121
|
if (!/\$\{.*:/.test(newCode)) {
|
|
108
|
-
_context.next =
|
|
122
|
+
_context.next = 26;
|
|
109
123
|
break;
|
|
110
124
|
}
|
|
111
125
|
return _context.abrupt("return");
|
|
112
|
-
case
|
|
113
|
-
_context.next =
|
|
126
|
+
case 26:
|
|
127
|
+
_context.next = 28;
|
|
114
128
|
return fixer.insertTextBefore(node, newCode);
|
|
115
|
-
case
|
|
116
|
-
_context.next =
|
|
129
|
+
case 28:
|
|
130
|
+
_context.next = 30;
|
|
117
131
|
return fixer.remove(node);
|
|
118
|
-
case
|
|
132
|
+
case 30:
|
|
119
133
|
case "end":
|
|
120
134
|
return _context.stop();
|
|
121
135
|
}
|
|
@@ -125,4 +139,20 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
|
|
|
125
139
|
}
|
|
126
140
|
};
|
|
127
141
|
};
|
|
128
|
-
};
|
|
142
|
+
};
|
|
143
|
+
function hasMixinInsideNestedSelector(arg) {
|
|
144
|
+
if (arg.type === 'literal' || arg.type === 'expression' || arg.type === 'declaration') {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if (arg.type === 'rule' && arg.declarations.length > 1 && arg.declarations.some(function (node) {
|
|
148
|
+
return node.type === 'expression';
|
|
149
|
+
})) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
if (arg.type === 'block') {
|
|
153
|
+
return arg.blocks.some(hasMixinInsideNestedSelector);
|
|
154
|
+
}
|
|
155
|
+
if (arg.type === 'rule') {
|
|
156
|
+
return arg.declarations.some(hasMixinInsideNestedSelector);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -61,7 +61,7 @@ const generateBlock = (blocks, offset, level) => {
|
|
|
61
61
|
};
|
|
62
62
|
const generateArguments = (args, offset, level) => {
|
|
63
63
|
let chars = '';
|
|
64
|
-
if (level
|
|
64
|
+
if (level >= 1 && args.length > 1) {
|
|
65
65
|
chars += '[';
|
|
66
66
|
}
|
|
67
67
|
for (const [i, arg] of args.entries()) {
|
|
@@ -91,7 +91,7 @@ const generateArguments = (args, offset, level) => {
|
|
|
91
91
|
chars += ',';
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
if (level
|
|
94
|
+
if (level >= 1 && args.length > 1) {
|
|
95
95
|
chars += '\n';
|
|
96
96
|
chars += indent(offset, level);
|
|
97
97
|
chars += ']';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Original source from Compiled https://github.com/atlassian-labs/compiled/blob/master/packages/eslint-plugin/src/utils/create-no-tagged-template-expression-rule/index.ts
|
|
2
2
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import esquery from 'esquery';
|
|
5
|
+
import { getImportSources, isEmotion, isStyledComponents } from '../is-supported-import';
|
|
5
6
|
import { generate } from './generate';
|
|
6
7
|
import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
|
|
7
8
|
import { toArguments } from './to-arguments';
|
|
@@ -49,13 +50,24 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
|
|
|
49
50
|
if (shouldSkipMultilineComments && quasi.quasis.map(q => q.value.raw).join('').match(/\/\*[\s\S]*\*\//g)) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
const matches = esquery(node, 'ArrowFunctionExpression > BlockStatement');
|
|
54
|
+
if (matches.length) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
54
57
|
if (!quasi.expressions.length && quasi.quasis.length === 1 && !quasi.quasis[0].value.raw.trim()) {
|
|
58
|
+
// Replace empty tagged template expression with the equivalent object call expression
|
|
55
59
|
yield fixer.replaceText(quasi, '({})');
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
58
62
|
const args = toArguments(source, quasi);
|
|
63
|
+
if (isStyledComponents(node.tag, references, importSources) && args.some(hasMixinInsideNestedSelector)) {
|
|
64
|
+
/**
|
|
65
|
+
* Styled components doesn't support arrays as style object values,
|
|
66
|
+
* so we cannot autofix mixins as we cannot combine them with the other
|
|
67
|
+
* properties in the object.
|
|
68
|
+
*/
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
59
71
|
|
|
60
72
|
// Skip invalid CSS
|
|
61
73
|
if (args.length < 1) {
|
|
@@ -123,4 +135,18 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
|
|
|
123
135
|
});
|
|
124
136
|
}
|
|
125
137
|
};
|
|
126
|
-
};
|
|
138
|
+
};
|
|
139
|
+
function hasMixinInsideNestedSelector(arg) {
|
|
140
|
+
if (arg.type === 'literal' || arg.type === 'expression' || arg.type === 'declaration') {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (arg.type === 'rule' && arg.declarations.length > 1 && arg.declarations.some(node => node.type === 'expression')) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
if (arg.type === 'block') {
|
|
147
|
+
return arg.blocks.some(hasMixinInsideNestedSelector);
|
|
148
|
+
}
|
|
149
|
+
if (arg.type === 'rule') {
|
|
150
|
+
return arg.declarations.some(hasMixinInsideNestedSelector);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -76,7 +76,7 @@ var generateBlock = function generateBlock(blocks, offset, level) {
|
|
|
76
76
|
};
|
|
77
77
|
var generateArguments = function generateArguments(args, offset, level) {
|
|
78
78
|
var chars = '';
|
|
79
|
-
if (level
|
|
79
|
+
if (level >= 1 && args.length > 1) {
|
|
80
80
|
chars += '[';
|
|
81
81
|
}
|
|
82
82
|
var _iterator2 = _createForOfIteratorHelper(args.entries()),
|
|
@@ -117,7 +117,7 @@ var generateArguments = function generateArguments(args, offset, level) {
|
|
|
117
117
|
} finally {
|
|
118
118
|
_iterator2.f();
|
|
119
119
|
}
|
|
120
|
-
if (level
|
|
120
|
+
if (level >= 1 && args.length > 1) {
|
|
121
121
|
chars += '\n';
|
|
122
122
|
chars += indent(offset, level);
|
|
123
123
|
chars += ']';
|
|
@@ -2,7 +2,8 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
2
2
|
// Original source from Compiled https://github.com/atlassian-labs/compiled/blob/master/packages/eslint-plugin/src/utils/create-no-tagged-template-expression-rule/index.ts
|
|
3
3
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import esquery from 'esquery';
|
|
6
|
+
import { getImportSources, isEmotion, isStyledComponents } from '../is-supported-import';
|
|
6
7
|
import { generate } from './generate';
|
|
7
8
|
import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
|
|
8
9
|
import { toArguments } from './to-arguments';
|
|
@@ -40,7 +41,7 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
|
|
|
40
41
|
messageId: messageId,
|
|
41
42
|
node: node,
|
|
42
43
|
fix: /*#__PURE__*/_regeneratorRuntime.mark(function fix(fixer) {
|
|
43
|
-
var quasi, source, args, oldCode, withoutQuasi, newCode, usesEmotion;
|
|
44
|
+
var quasi, source, matches, args, oldCode, withoutQuasi, newCode, usesEmotion;
|
|
44
45
|
return _regeneratorRuntime.wrap(function fix$(_context) {
|
|
45
46
|
while (1) switch (_context.prev = _context.next) {
|
|
46
47
|
case 0:
|
|
@@ -55,22 +56,35 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
|
|
|
55
56
|
}
|
|
56
57
|
return _context.abrupt("return");
|
|
57
58
|
case 4:
|
|
59
|
+
matches = esquery(node, 'ArrowFunctionExpression > BlockStatement');
|
|
60
|
+
if (!matches.length) {
|
|
61
|
+
_context.next = 7;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
return _context.abrupt("return");
|
|
65
|
+
case 7:
|
|
58
66
|
if (!(!quasi.expressions.length && quasi.quasis.length === 1 && !quasi.quasis[0].value.raw.trim())) {
|
|
59
|
-
_context.next =
|
|
67
|
+
_context.next = 11;
|
|
60
68
|
break;
|
|
61
69
|
}
|
|
62
|
-
_context.next =
|
|
70
|
+
_context.next = 10;
|
|
63
71
|
return fixer.replaceText(quasi, '({})');
|
|
64
|
-
case
|
|
72
|
+
case 10:
|
|
65
73
|
return _context.abrupt("return");
|
|
66
|
-
case
|
|
67
|
-
args = toArguments(source, quasi);
|
|
74
|
+
case 11:
|
|
75
|
+
args = toArguments(source, quasi);
|
|
76
|
+
if (!(isStyledComponents(node.tag, references, importSources) && args.some(hasMixinInsideNestedSelector))) {
|
|
77
|
+
_context.next = 14;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
return _context.abrupt("return");
|
|
81
|
+
case 14:
|
|
68
82
|
if (!(args.length < 1)) {
|
|
69
|
-
_context.next =
|
|
83
|
+
_context.next = 16;
|
|
70
84
|
break;
|
|
71
85
|
}
|
|
72
86
|
return _context.abrupt("return");
|
|
73
|
-
case
|
|
87
|
+
case 16:
|
|
74
88
|
oldCode = source.getText(node); // Remove quasi:
|
|
75
89
|
// styled.div<Props>`
|
|
76
90
|
// color: red;
|
|
@@ -82,33 +96,33 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
|
|
|
82
96
|
// Indent the arguments after the tagged template expression range
|
|
83
97
|
generate(args, getTaggedTemplateExpressionOffset(node));
|
|
84
98
|
if (!(oldCode === newCode)) {
|
|
85
|
-
_context.next =
|
|
99
|
+
_context.next = 21;
|
|
86
100
|
break;
|
|
87
101
|
}
|
|
88
102
|
return _context.abrupt("return");
|
|
89
|
-
case
|
|
103
|
+
case 21:
|
|
90
104
|
// For styles like `position: initial !important`,
|
|
91
105
|
// Emotion can give typechecking errors when using object syntax
|
|
92
106
|
// due to csstype being overly strict
|
|
93
107
|
usesEmotion = isEmotion(node.tag, references, importSources);
|
|
94
108
|
if (!(usesEmotion && !!newCode.match(/!\s*important/gm))) {
|
|
95
|
-
_context.next =
|
|
109
|
+
_context.next = 24;
|
|
96
110
|
break;
|
|
97
111
|
}
|
|
98
112
|
return _context.abrupt("return");
|
|
99
|
-
case
|
|
113
|
+
case 24:
|
|
100
114
|
if (!/\$\{.*:/.test(newCode)) {
|
|
101
|
-
_context.next =
|
|
115
|
+
_context.next = 26;
|
|
102
116
|
break;
|
|
103
117
|
}
|
|
104
118
|
return _context.abrupt("return");
|
|
105
|
-
case
|
|
106
|
-
_context.next =
|
|
119
|
+
case 26:
|
|
120
|
+
_context.next = 28;
|
|
107
121
|
return fixer.insertTextBefore(node, newCode);
|
|
108
|
-
case
|
|
109
|
-
_context.next =
|
|
122
|
+
case 28:
|
|
123
|
+
_context.next = 30;
|
|
110
124
|
return fixer.remove(node);
|
|
111
|
-
case
|
|
125
|
+
case 30:
|
|
112
126
|
case "end":
|
|
113
127
|
return _context.stop();
|
|
114
128
|
}
|
|
@@ -118,4 +132,20 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
|
|
|
118
132
|
}
|
|
119
133
|
};
|
|
120
134
|
};
|
|
121
|
-
};
|
|
135
|
+
};
|
|
136
|
+
function hasMixinInsideNestedSelector(arg) {
|
|
137
|
+
if (arg.type === 'literal' || arg.type === 'expression' || arg.type === 'declaration') {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (arg.type === 'rule' && arg.declarations.length > 1 && arg.declarations.some(function (node) {
|
|
141
|
+
return node.type === 'expression';
|
|
142
|
+
})) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
if (arg.type === 'block') {
|
|
146
|
+
return arg.blocks.some(hasMixinInsideNestedSelector);
|
|
147
|
+
}
|
|
148
|
+
if (arg.type === 'rule') {
|
|
149
|
+
return arg.declarations.some(hasMixinInsideNestedSelector);
|
|
150
|
+
}
|
|
151
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/eslint-plugin-design-system",
|
|
3
3
|
"description": "The essential plugin for use with the Atlassian Design System.",
|
|
4
|
-
"version": "9.2.
|
|
4
|
+
"version": "9.2.2",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"publishConfig": {
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@typescript-eslint/utils": "^5.48.1",
|
|
43
43
|
"ajv": "^6.12.6",
|
|
44
44
|
"eslint-codemod-utils": "^1.8.6",
|
|
45
|
+
"esquery": "^1.5.0",
|
|
45
46
|
"estraverse": "^5.3.0",
|
|
46
47
|
"lodash": "^4.17.21",
|
|
47
48
|
"semver": "^7.5.2"
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
"@emotion/react": "^11.7.1",
|
|
56
57
|
"@emotion/styled": "^11.0.0",
|
|
57
58
|
"@types/eslint": "^8.56.6",
|
|
59
|
+
"@types/esquery": "^1.5.3",
|
|
58
60
|
"@types/estraverse": "^5.1.7",
|
|
59
61
|
"eslint": "^8.49.0",
|
|
60
62
|
"jscodeshift": "^0.13.0",
|