@atlaskit/eslint-plugin-design-system 8.26.0 → 8.28.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 +31 -0
- package/README.md +31 -29
- package/constellation/consistent-css-prop-usage/usage.mdx +193 -0
- package/constellation/ensure-design-token-usage/usage.mdx +72 -0
- package/constellation/ensure-design-token-usage-preview/usage.mdx +5 -0
- package/constellation/icon-label/usage.mdx +39 -0
- package/constellation/index/usage.mdx +31 -1474
- package/constellation/local-cx-xcss/usage.mdx +37 -0
- package/constellation/no-banned-imports/usage.mdx +17 -0
- package/constellation/no-css-tagged-template-expression/usage.mdx +66 -0
- package/constellation/no-deprecated-apis/usage.mdx +76 -0
- package/constellation/no-deprecated-design-token-usage/usage.mdx +27 -0
- package/constellation/no-deprecated-imports/usage.mdx +62 -0
- package/constellation/no-empty-styled-expression/usage.mdx +77 -0
- package/constellation/no-exported-css/usage.mdx +50 -0
- package/constellation/no-exported-keyframes/usage.mdx +50 -0
- package/constellation/no-invalid-css-map/usage.mdx +199 -0
- package/constellation/no-keyframes-tagged-template-expression/usage.mdx +76 -0
- package/constellation/no-margin/usage.mdx +20 -0
- package/constellation/no-nested-styles/usage.mdx +47 -0
- package/constellation/no-physical-properties/usage.mdx +53 -0
- package/constellation/no-styled-tagged-template-expression/usage.mdx +90 -0
- package/constellation/no-unsafe-design-token-usage/usage.mdx +49 -0
- package/constellation/no-unsafe-style-overrides/usage.mdx +49 -0
- package/constellation/no-unsupported-drag-and-drop-libraries/usage.mdx +17 -0
- package/constellation/prefer-primitives/usage.mdx +31 -0
- package/constellation/use-button-group-label/usage.mdx +58 -0
- package/constellation/use-drawer-label/usage.mdx +53 -0
- package/constellation/use-heading-level-in-spotlight-card/usage.mdx +20 -0
- package/constellation/use-href-in-link-item/usage.mdx +18 -0
- package/constellation/use-primitives/usage.mdx +77 -0
- package/constellation/use-visually-hidden/usage.mdx +34 -0
- package/dist/cjs/presets/all.codegen.js +3 -1
- package/dist/cjs/rules/consistent-css-prop-usage/index.js +254 -32
- package/dist/cjs/rules/index.codegen.js +5 -1
- package/dist/cjs/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/cjs/rules/no-keyframes-tagged-template-expression/index.js +27 -0
- package/dist/cjs/rules/no-styled-tagged-template-expression/index.js +27 -0
- package/dist/cjs/rules/no-styled-tagged-template-expression/is-styled.js +53 -0
- package/dist/cjs/rules/utils/create-no-exported-rule/is-styled-component.js +6 -10
- package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.js +26 -6
- package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/cjs/rules/utils/create-rule.js +7 -5
- package/dist/cjs/rules/utils/get-first-supported-import.js +28 -0
- package/dist/cjs/rules/utils/is-supported-import.js +9 -11
- package/dist/es2019/presets/all.codegen.js +3 -1
- package/dist/es2019/rules/consistent-css-prop-usage/index.js +251 -33
- package/dist/es2019/rules/index.codegen.js +5 -1
- package/dist/es2019/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/es2019/rules/no-keyframes-tagged-template-expression/index.js +21 -0
- package/dist/es2019/rules/no-styled-tagged-template-expression/index.js +21 -0
- package/dist/es2019/rules/no-styled-tagged-template-expression/is-styled.js +45 -0
- package/dist/es2019/rules/utils/create-no-exported-rule/is-styled-component.js +4 -8
- package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/index.js +84 -0
- package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/es2019/rules/utils/create-rule.js +7 -5
- package/dist/es2019/rules/utils/get-first-supported-import.js +22 -0
- package/dist/es2019/rules/utils/is-supported-import.js +9 -9
- package/dist/esm/presets/all.codegen.js +3 -1
- package/dist/esm/rules/consistent-css-prop-usage/index.js +255 -33
- package/dist/esm/rules/index.codegen.js +5 -1
- package/dist/esm/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/esm/rules/no-keyframes-tagged-template-expression/index.js +21 -0
- package/dist/esm/rules/no-styled-tagged-template-expression/index.js +21 -0
- package/dist/esm/rules/no-styled-tagged-template-expression/is-styled.js +47 -0
- package/dist/esm/rules/utils/create-no-exported-rule/is-styled-component.js +6 -10
- package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.js +25 -5
- package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/esm/rules/utils/create-rule.js +7 -5
- package/dist/esm/rules/utils/get-first-supported-import.js +22 -0
- package/dist/esm/rules/utils/is-supported-import.js +9 -10
- package/dist/types/index.codegen.d.ts +2 -0
- package/dist/types/presets/all.codegen.d.ts +3 -1
- package/dist/types/rules/consistent-css-prop-usage/types.d.ts +7 -2
- package/dist/types/rules/index.codegen.d.ts +2 -0
- package/dist/types/rules/no-keyframes-tagged-template-expression/index.d.ts +2 -0
- package/dist/types/rules/no-styled-tagged-template-expression/index.d.ts +2 -0
- package/dist/types/rules/no-styled-tagged-template-expression/is-styled.d.ts +7 -0
- package/dist/types/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
- package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.d.ts +3 -1
- package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.d.ts +3 -0
- package/dist/types/rules/utils/get-first-supported-import.d.ts +17 -0
- package/dist/types/rules/utils/is-supported-import.d.ts +6 -5
- package/dist/types-ts4.5/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +3 -1
- package/dist/types-ts4.5/rules/consistent-css-prop-usage/types.d.ts +7 -2
- package/dist/types-ts4.5/rules/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-keyframes-tagged-template-expression/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-styled-tagged-template-expression/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-styled-tagged-template-expression/is-styled.d.ts +7 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
- package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.d.ts +3 -1
- package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.d.ts +3 -0
- package/dist/types-ts4.5/rules/utils/get-first-supported-import.d.ts +17 -0
- package/dist/types-ts4.5/rules/utils/is-supported-import.d.ts +6 -5
- package/package.json +3 -1
- package/dist/es2019/rules/no-css-tagged-template-expression/create-no-tagged-template-expression-rule/index.js +0 -62
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.d.ts +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.d.ts +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.d.ts +0 -0
|
@@ -3,20 +3,27 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
3
3
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
4
4
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
5
5
|
|
|
6
|
-
import { getIdentifierInParentScope, isNodeOfType } from 'eslint-codemod-utils';
|
|
6
|
+
import { getIdentifierInParentScope, insertAtStartOfFile, insertImportDeclaration, isNodeOfType } from 'eslint-codemod-utils';
|
|
7
|
+
import estraverse from 'estraverse';
|
|
7
8
|
import assign from 'lodash/assign';
|
|
9
|
+
import { Import } from '../../ast-nodes';
|
|
8
10
|
import { createLintRule } from '../utils/create-rule';
|
|
9
|
-
|
|
11
|
+
import { getFirstSupportedImport } from '../utils/get-first-supported-import';
|
|
12
|
+
import { getModuleOfIdentifier } from '../utils/get-import-node-by-source';
|
|
13
|
+
import { CSS_IN_JS_IMPORTS } from '../utils/is-supported-import';
|
|
14
|
+
// File-level tracking of styles hoisted from the cssAtTopOfModule/cssAtBottomOfModule fixers
|
|
10
15
|
var hoistedCss = [];
|
|
16
|
+
var isDOMElementName = function isDOMElementName(elementName) {
|
|
17
|
+
return elementName.charAt(0) !== elementName.charAt(0).toUpperCase() && elementName.charAt(0) === elementName.charAt(0).toLowerCase();
|
|
18
|
+
};
|
|
11
19
|
function isCssCallExpression(node, cssFunctions) {
|
|
12
20
|
cssFunctions = [].concat(_toConsumableArray(cssFunctions), ['cssMap']);
|
|
13
21
|
return !!(isNodeOfType(node, 'CallExpression') && node.callee && node.callee.type === 'Identifier' && cssFunctions.includes(node.callee.name) && node.arguments.length && node.arguments[0].type === 'ObjectExpression');
|
|
14
22
|
}
|
|
15
23
|
function findSpreadProperties(node) {
|
|
16
|
-
// @ts-ignore
|
|
17
24
|
return node.properties.filter(function (property) {
|
|
18
25
|
return property.type === 'SpreadElement' ||
|
|
19
|
-
// @ts-
|
|
26
|
+
// @ts-expect-error
|
|
20
27
|
property.type === 'ExperimentalSpreadProperty';
|
|
21
28
|
});
|
|
22
29
|
}
|
|
@@ -27,9 +34,8 @@ var getProgramNode = function getProgramNode(expression) {
|
|
|
27
34
|
return expression.parent;
|
|
28
35
|
};
|
|
29
36
|
|
|
30
|
-
// TODO: This can be optimised by implementing a fixer at the very end (Program:exit) and handling all validations at once
|
|
31
37
|
/**
|
|
32
|
-
* Generates the declarator string when fixing the
|
|
38
|
+
* Generates the declarator string when fixing the cssAtTopOfModule/cssAtBottomOfModule cases.
|
|
33
39
|
* When `styles` already exists, `styles_1, styles_2, ..., styles_X` are incrementally created for each unhoisted style.
|
|
34
40
|
* The generated `styles` varibale declaration names must be manually modified to be more informative at the discretion of owning teams.
|
|
35
41
|
*/
|
|
@@ -61,7 +67,7 @@ var getDeclaratorString = function getDeclaratorString(context) {
|
|
|
61
67
|
hoistedCss = [].concat(_toConsumableArray(hoistedCss), ["".concat(declaratorName).concat(count)]);
|
|
62
68
|
return "".concat(declaratorName).concat(count);
|
|
63
69
|
};
|
|
64
|
-
function analyzeIdentifier(context, sourceIdentifier, configuration) {
|
|
70
|
+
function analyzeIdentifier(context, sourceIdentifier, configuration, cssAttributeName) {
|
|
65
71
|
var _getIdentifierInParen, _getIdentifierInParen2;
|
|
66
72
|
var scope = context.getScope();
|
|
67
73
|
var _ref = (_getIdentifierInParen = (_getIdentifierInParen2 = getIdentifierInParentScope(scope, sourceIdentifier.name)) === null || _getIdentifierInParen2 === void 0 ? void 0 : _getIdentifierInParen2.identifiers) !== null && _getIdentifierInParen !== void 0 ? _getIdentifierInParen : [],
|
|
@@ -83,8 +89,11 @@ function analyzeIdentifier(context, sourceIdentifier, configuration) {
|
|
|
83
89
|
// When variable is declared inside the component
|
|
84
90
|
context.report({
|
|
85
91
|
node: sourceIdentifier,
|
|
86
|
-
messageId: configuration.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : '
|
|
92
|
+
messageId: configuration.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : 'cssAtTopOfModule',
|
|
87
93
|
fix: function fix(fixer) {
|
|
94
|
+
if (configuration.fixNamesOnly) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
88
97
|
return fixCssNotInModuleScope(fixer, context, configuration, identifier);
|
|
89
98
|
}
|
|
90
99
|
});
|
|
@@ -92,10 +101,30 @@ function analyzeIdentifier(context, sourceIdentifier, configuration) {
|
|
|
92
101
|
}
|
|
93
102
|
if (identifier.parent && identifier.parent.init && !isCssCallExpression(identifier.parent.init, configuration.cssFunctions)) {
|
|
94
103
|
// When variable value is not of type css({})
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
104
|
+
var value = identifier.parent.init;
|
|
105
|
+
if (!value) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
var valueExpression =
|
|
109
|
+
// @ts-expect-error remove once eslint types are switched to @typescript-eslint
|
|
110
|
+
value.type === 'TSAsExpression' ? value.expression : value;
|
|
111
|
+
if (['ObjectExpression', 'TemplateLiteral'].includes(valueExpression.type)) {
|
|
112
|
+
context.report({
|
|
113
|
+
node: identifier,
|
|
114
|
+
messageId: 'cssObjectTypeOnly',
|
|
115
|
+
fix: function fix(fixer) {
|
|
116
|
+
if (configuration.fixNamesOnly) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
return addCssFunctionCall(fixer, context, identifier.parent, configuration, cssAttributeName);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
context.report({
|
|
124
|
+
node: identifier,
|
|
125
|
+
messageId: 'cssObjectTypeOnly'
|
|
126
|
+
});
|
|
127
|
+
}
|
|
99
128
|
return;
|
|
100
129
|
}
|
|
101
130
|
var spreadProperties = isNodeOfType(identifier.parent.init, 'CallExpression') && findSpreadProperties(identifier.parent.init.arguments[0]);
|
|
@@ -111,12 +140,133 @@ function analyzeIdentifier(context, sourceIdentifier, configuration) {
|
|
|
111
140
|
}
|
|
112
141
|
|
|
113
142
|
/**
|
|
114
|
-
*
|
|
143
|
+
* Returns a fixer that adds `import { css } from 'import-source'` or
|
|
144
|
+
* `import { xcss } from 'import-source'` to the start of the file, depending
|
|
145
|
+
* on the value of cssAttributeName and importSource.
|
|
146
|
+
*/
|
|
147
|
+
var addImportSource = function addImportSource(context, fixer, configuration, cssAttributeName) {
|
|
148
|
+
var importSource = cssAttributeName === 'xcss' ? configuration.xcssImportSource : configuration.cssImportSource;
|
|
149
|
+
|
|
150
|
+
// Add the `import { css } from 'my-css-in-js-library';` statement
|
|
151
|
+
var packageImport = getFirstSupportedImport(context, [importSource]);
|
|
152
|
+
if (packageImport) {
|
|
153
|
+
var addCssImport = Import.insertNamedSpecifiers(packageImport, [cssAttributeName], fixer);
|
|
154
|
+
if (addCssImport) {
|
|
155
|
+
return addCssImport;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
return insertAtStartOfFile(fixer, "".concat(insertImportDeclaration(importSource, [cssAttributeName]), ";\n"));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Returns a list of fixes that:
|
|
164
|
+
* - add the `css` or `xcss` function call around the current node.
|
|
165
|
+
* - add an import statement for the package from which `css` is imported
|
|
166
|
+
*/
|
|
167
|
+
var addCssFunctionCall = function addCssFunctionCall(fixer, context, node, configuration, cssAttributeName) {
|
|
168
|
+
var fixes = [];
|
|
169
|
+
var sourceCode = context.getSourceCode();
|
|
170
|
+
if (node.type !== 'VariableDeclarator' || !node.init || !cssAttributeName) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
var compiledImportFix = addImportSource(context, fixer, configuration, cssAttributeName);
|
|
174
|
+
if (compiledImportFix) {
|
|
175
|
+
fixes.push(compiledImportFix);
|
|
176
|
+
}
|
|
177
|
+
var init = node.init;
|
|
178
|
+
var initString = sourceCode.getText(init);
|
|
179
|
+
if (node.init.type === 'TemplateLiteral') {
|
|
180
|
+
fixes.push(fixer.replaceText(init, "".concat(cssAttributeName).concat(initString)));
|
|
181
|
+
} else {
|
|
182
|
+
fixes.push(fixer.replaceText(init, "".concat(cssAttributeName, "(").concat(initString, ")")));
|
|
183
|
+
}
|
|
184
|
+
return fixes;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Check if the expression has or potentially has a local variable
|
|
189
|
+
* (as opposed to an imported one), erring on the side ot "yes"
|
|
190
|
+
* when an expression is too complicated to analyse.
|
|
191
|
+
*
|
|
192
|
+
* This is useful because expressions containing local variables
|
|
193
|
+
* cannot be easily hoisted, whereas this is not a problem with imported
|
|
194
|
+
* variables.
|
|
195
|
+
*
|
|
196
|
+
* @param context Context of the rule.
|
|
197
|
+
* @param node Any node that is potentially hoistable.
|
|
198
|
+
* @returns Whether the node potentially has a local variable (and thus is not safe to hoist).
|
|
199
|
+
*/
|
|
200
|
+
var potentiallyHasLocalVariable = function potentiallyHasLocalVariable(context, node) {
|
|
201
|
+
var hasPotentiallyLocalVariable = false;
|
|
202
|
+
var isImportedVariable = function isImportedVariable(identifier) {
|
|
203
|
+
return !!getModuleOfIdentifier(context.getSourceCode(), identifier);
|
|
204
|
+
};
|
|
205
|
+
estraverse.traverse(node, {
|
|
206
|
+
enter: function enter(node, _parent) {
|
|
207
|
+
if (isNodeOfType(node, 'SpreadElement') ||
|
|
208
|
+
// @ts-expect-error remove once we can be sure that no parser interprets
|
|
209
|
+
// the spread operator as ExperimentalSpreadProperty anymore
|
|
210
|
+
isNodeOfType(node, 'ExperimentalSpreadProperty')) {
|
|
211
|
+
// Spread elements could contain anything... so we don't bother.
|
|
212
|
+
//
|
|
213
|
+
// e.g. <div css={css({ ...(!height && { visibility: 'hidden' })} />
|
|
214
|
+
hasPotentiallyLocalVariable = true;
|
|
215
|
+
this.break();
|
|
216
|
+
}
|
|
217
|
+
if (!isNodeOfType(node, 'Property')) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
switch (node.value.type) {
|
|
221
|
+
case 'Literal':
|
|
222
|
+
break;
|
|
223
|
+
case 'Identifier':
|
|
224
|
+
// e.g. css({ margin: myVariable })
|
|
225
|
+
if (!isImportedVariable(node.value.name)) {
|
|
226
|
+
hasPotentiallyLocalVariable = true;
|
|
227
|
+
}
|
|
228
|
+
this.break();
|
|
229
|
+
break;
|
|
230
|
+
case 'MemberExpression':
|
|
231
|
+
// e.g. css({ margin: props.color })
|
|
232
|
+
// css({ margin: props.media.color })
|
|
233
|
+
if (node.value.object.type === 'Identifier' && isImportedVariable(node.value.object.name)) {
|
|
234
|
+
// We found an imported variable, don't do anything.
|
|
235
|
+
} else {
|
|
236
|
+
// e.g. css({ margin: [some complicated expression].media.color })
|
|
237
|
+
// This can potentially get too complex, so we assume there's a local
|
|
238
|
+
// variable in there somewhere.
|
|
239
|
+
hasPotentiallyLocalVariable = true;
|
|
240
|
+
}
|
|
241
|
+
this.break();
|
|
242
|
+
break;
|
|
243
|
+
case 'TemplateLiteral':
|
|
244
|
+
if (!!node.value.expressions.length) {
|
|
245
|
+
// Too many edge cases here, don't bother...
|
|
246
|
+
// e.g. css({ animation: `${expandStyles(right, rightExpanded, isExpanded)} 0.2s ease-in-out` });
|
|
247
|
+
hasPotentiallyLocalVariable = true;
|
|
248
|
+
this.break();
|
|
249
|
+
}
|
|
250
|
+
break;
|
|
251
|
+
default:
|
|
252
|
+
// Catch-all for values such as "A && B", "A ? B : C"
|
|
253
|
+
hasPotentiallyLocalVariable = true;
|
|
254
|
+
this.break();
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return hasPotentiallyLocalVariable;
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Fixer for the cssAtTopOfModule/cssAtBottomOfModule violation cases.
|
|
115
264
|
* This deals with Identifiers and Expressions passed from the traverseExpressionWithConfig() function.
|
|
265
|
+
*
|
|
116
266
|
* @param fixer The ESLint RuleFixer object
|
|
117
|
-
* @param context The context of the
|
|
267
|
+
* @param context The context of the rule
|
|
118
268
|
* @param configuration The configuration of the rule, determining whether the fix is implmeneted at the top or bottom of the module
|
|
119
|
-
* @param node
|
|
269
|
+
* @param node Any potentially hoistable node, or an identifier.
|
|
120
270
|
* @param cssAttributeName An optional parameter only added when we fix an ObjectExpression
|
|
121
271
|
*/
|
|
122
272
|
var fixCssNotInModuleScope = function fixCssNotInModuleScope(fixer, context, configuration, node, cssAttributeName) {
|
|
@@ -135,35 +285,42 @@ var fixCssNotInModuleScope = function fixCssNotInModuleScope(fixer, context, con
|
|
|
135
285
|
});
|
|
136
286
|
}
|
|
137
287
|
var moduleString;
|
|
138
|
-
var
|
|
288
|
+
var fixes = [];
|
|
139
289
|
if (node.type === 'Identifier') {
|
|
140
290
|
var identifier = node;
|
|
141
291
|
var declarator = identifier.parent.parent;
|
|
142
292
|
moduleString = sourceCode.getText(declarator);
|
|
143
|
-
|
|
293
|
+
fixes.push(fixer.remove(declarator));
|
|
144
294
|
} else {
|
|
295
|
+
if (potentiallyHasLocalVariable(context, node)) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
145
298
|
var _declarator = getDeclaratorString(context);
|
|
146
299
|
var text = sourceCode.getText(node);
|
|
147
300
|
|
|
148
301
|
// If this has been passed, then we know it's an ObjectExpression
|
|
149
302
|
if (cssAttributeName) {
|
|
150
303
|
moduleString = "const ".concat(_declarator, " = ").concat(cssAttributeName, "(").concat(text, ");");
|
|
304
|
+
var compiledImportFix = addImportSource(context, fixer, configuration, cssAttributeName);
|
|
305
|
+
if (compiledImportFix) {
|
|
306
|
+
fixes.push(compiledImportFix);
|
|
307
|
+
}
|
|
151
308
|
} else {
|
|
152
|
-
moduleString =
|
|
309
|
+
moduleString = "const ".concat(_declarator, " = ").concat(text, ";");
|
|
153
310
|
}
|
|
154
|
-
|
|
311
|
+
fixes.push(fixer.replaceText(node, _declarator));
|
|
155
312
|
}
|
|
156
|
-
return [].concat(
|
|
157
|
-
// Insert the node either before or after
|
|
313
|
+
return [].concat(fixes, [
|
|
314
|
+
// Insert the node either before or after, depending on the rule configuration
|
|
158
315
|
configuration.stylesPlacement === 'bottom' ? fixer.insertTextAfter(fixerNodePlacement, '\n' + moduleString) : fixer.insertTextBefore(fixerNodePlacement, moduleString + '\n')]);
|
|
159
316
|
};
|
|
160
317
|
|
|
161
318
|
/**
|
|
162
319
|
* Handle different cases based on what's been passed in the css-related JSXAttribute
|
|
163
|
-
* @param context the context of the
|
|
320
|
+
* @param context the context of the rule
|
|
164
321
|
* @param expression the expression of the JSXAttribute value
|
|
165
322
|
* @param configuration what css-related functions to account for (eg. css, xcss, cssMap), and whether to detect bottom vs top expressions
|
|
166
|
-
* @param cssAttributeName used to encapsulate ObjectExpressions when
|
|
323
|
+
* @param cssAttributeName used to encapsulate ObjectExpressions when cssAtTopOfModule/cssAtBottomOfModule violations are triggered
|
|
167
324
|
*/
|
|
168
325
|
var traverseExpressionWithConfig = function traverseExpressionWithConfig(context, expression, configuration, cssAttributeName) {
|
|
169
326
|
function traverseExpression(expression) {
|
|
@@ -171,7 +328,7 @@ var traverseExpressionWithConfig = function traverseExpressionWithConfig(context
|
|
|
171
328
|
case 'Identifier':
|
|
172
329
|
// {styles}
|
|
173
330
|
// We've found an identifier - time to analyze it!
|
|
174
|
-
analyzeIdentifier(context, expression, configuration);
|
|
331
|
+
analyzeIdentifier(context, expression, configuration, cssAttributeName);
|
|
175
332
|
break;
|
|
176
333
|
case 'ArrayExpression':
|
|
177
334
|
// {[styles, moreStyles]}
|
|
@@ -200,8 +357,12 @@ var traverseExpressionWithConfig = function traverseExpressionWithConfig(context
|
|
|
200
357
|
// We've found elements that shouldn't be here! Report an error.
|
|
201
358
|
context.report({
|
|
202
359
|
node: expression,
|
|
203
|
-
messageId: configuration.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : '
|
|
360
|
+
messageId: configuration.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : 'cssAtTopOfModule',
|
|
204
361
|
fix: function fix(fixer) {
|
|
362
|
+
if (configuration.fixNamesOnly) {
|
|
363
|
+
return [];
|
|
364
|
+
}
|
|
365
|
+
|
|
205
366
|
// Don't fix CallExpressions unless they're from cssFunctions or cssMap
|
|
206
367
|
if (expression.type === 'CallExpression' && !isCssCallExpression(expression, configuration.cssFunctions)) {
|
|
207
368
|
return [];
|
|
@@ -213,6 +374,17 @@ var traverseExpressionWithConfig = function traverseExpressionWithConfig(context
|
|
|
213
374
|
}
|
|
214
375
|
});
|
|
215
376
|
break;
|
|
377
|
+
|
|
378
|
+
// @ts-expect-error - our ESLint-related types assume vanilla JS, when in fact
|
|
379
|
+
// it is running @typescript-eslint
|
|
380
|
+
//
|
|
381
|
+
// Switching to the more accurate @typescript-eslint types would break
|
|
382
|
+
// eslint-codemod-utils and all ESLint rules in packages/design-system,
|
|
383
|
+
// so we just leave this as-is.
|
|
384
|
+
case 'TSAsExpression':
|
|
385
|
+
// @ts-expect-error
|
|
386
|
+
traverseExpression(expression.expression);
|
|
387
|
+
break;
|
|
216
388
|
default:
|
|
217
389
|
// Do nothing!
|
|
218
390
|
break;
|
|
@@ -222,10 +394,15 @@ var traverseExpressionWithConfig = function traverseExpressionWithConfig(context
|
|
|
222
394
|
};
|
|
223
395
|
var defaultConfig = {
|
|
224
396
|
cssFunctions: ['css', 'xcss'],
|
|
225
|
-
stylesPlacement: 'top'
|
|
397
|
+
stylesPlacement: 'top',
|
|
398
|
+
cssImportSource: CSS_IN_JS_IMPORTS.compiled,
|
|
399
|
+
xcssImportSource: CSS_IN_JS_IMPORTS.atlaskitPrimitives,
|
|
400
|
+
excludeReactComponents: false,
|
|
401
|
+
fixNamesOnly: false
|
|
226
402
|
};
|
|
227
403
|
var rule = createLintRule({
|
|
228
404
|
meta: {
|
|
405
|
+
type: 'problem',
|
|
229
406
|
name: 'consistent-css-prop-usage',
|
|
230
407
|
docs: {
|
|
231
408
|
description: 'Ensures consistency with `css` and `xcss` prop usages',
|
|
@@ -235,13 +412,42 @@ var rule = createLintRule({
|
|
|
235
412
|
},
|
|
236
413
|
fixable: 'code',
|
|
237
414
|
messages: {
|
|
238
|
-
|
|
415
|
+
cssAtTopOfModule: "Create styles at the top of the module scope using the respective css function.",
|
|
239
416
|
cssAtBottomOfModule: "Create styles at the bottom of the module scope using the respective css function.",
|
|
240
|
-
cssObjectTypeOnly: "Create styles using objects passed to
|
|
241
|
-
cssInModule: "Imported styles should not be used
|
|
417
|
+
cssObjectTypeOnly: "Create styles using objects passed to a css function call, e.g. `css({ textAlign: 'center'; })`.",
|
|
418
|
+
cssInModule: "Imported styles should not be used; instead define in the module, import a component, or use a design token.",
|
|
242
419
|
cssArrayStylesOnly: "Compose styles with an array on the css prop instead of using object spread.",
|
|
420
|
+
noMemberExpressions: "Styles should be a regular variable (e.g. 'buttonStyles'), not a member of an object (e.g. 'myObject.styles').",
|
|
243
421
|
shouldEndInStyles: 'Declared styles should end in "styles".'
|
|
244
|
-
}
|
|
422
|
+
},
|
|
423
|
+
schema: [{
|
|
424
|
+
type: 'object',
|
|
425
|
+
properties: {
|
|
426
|
+
cssFunctions: {
|
|
427
|
+
type: 'array',
|
|
428
|
+
items: [{
|
|
429
|
+
type: 'string'
|
|
430
|
+
}]
|
|
431
|
+
},
|
|
432
|
+
stylesPlacement: {
|
|
433
|
+
type: 'string',
|
|
434
|
+
enum: ['top', 'bottom']
|
|
435
|
+
},
|
|
436
|
+
cssImportSource: {
|
|
437
|
+
type: 'string'
|
|
438
|
+
},
|
|
439
|
+
xcssImportSource: {
|
|
440
|
+
type: 'string'
|
|
441
|
+
},
|
|
442
|
+
excludeReactComponents: {
|
|
443
|
+
type: 'boolean'
|
|
444
|
+
},
|
|
445
|
+
fixNamesOnly: {
|
|
446
|
+
type: 'boolean'
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
additionalProperties: false
|
|
450
|
+
}]
|
|
245
451
|
},
|
|
246
452
|
create: function create(context) {
|
|
247
453
|
var _ref3;
|
|
@@ -283,9 +489,20 @@ var rule = createLintRule({
|
|
|
283
489
|
});
|
|
284
490
|
}
|
|
285
491
|
});
|
|
286
|
-
}), _defineProperty(_ref3, "JSXAttribute", function JSXAttribute(
|
|
492
|
+
}), _defineProperty(_ref3, "JSXAttribute", function JSXAttribute(nodeOriginal) {
|
|
493
|
+
var node = nodeOriginal;
|
|
287
494
|
var name = node.name,
|
|
288
495
|
value = node.value;
|
|
496
|
+
if (mergedConfig.excludeReactComponents && node.parent.type === 'JSXOpeningElement') {
|
|
497
|
+
// e.g. <item.before />
|
|
498
|
+
if (node.parent.name.type === 'JSXMemberExpression') {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
// e.g. <div />, <MenuItem />
|
|
502
|
+
if (node.parent.name.type === 'JSXIdentifier' && !isDOMElementName(node.parent.name.name)) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
289
506
|
|
|
290
507
|
// Always reset to empty array
|
|
291
508
|
hoistedCss = [];
|
|
@@ -293,11 +510,16 @@ var rule = createLintRule({
|
|
|
293
510
|
// When not a jsx expression. For eg. css=""
|
|
294
511
|
if ((value === null || value === void 0 ? void 0 : value.type) !== 'JSXExpressionContainer') {
|
|
295
512
|
context.report({
|
|
296
|
-
node:
|
|
297
|
-
messageId: mergedConfig.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : '
|
|
513
|
+
node: node,
|
|
514
|
+
messageId: mergedConfig.stylesPlacement === 'bottom' ? 'cssAtBottomOfModule' : 'cssAtTopOfModule'
|
|
298
515
|
});
|
|
299
516
|
return;
|
|
300
517
|
}
|
|
518
|
+
if (value.expression.type === 'JSXEmptyExpression') {
|
|
519
|
+
// e.g. the comment in
|
|
520
|
+
// <div css={/* Hello there */} />
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
301
523
|
traverseExpressionWithConfig(context, value.expression, mergedConfig, name.name);
|
|
302
524
|
}
|
|
303
525
|
}), _ref3;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::0a2813f0b87e94d23e1f6fc388539c70>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -17,9 +17,11 @@ import noEmptyStyledExpression from './no-empty-styled-expression';
|
|
|
17
17
|
import noExportedCss from './no-exported-css';
|
|
18
18
|
import noExportedKeyframes from './no-exported-keyframes';
|
|
19
19
|
import noInvalidCssMap from './no-invalid-css-map';
|
|
20
|
+
import noKeyframesTaggedTemplateExpression from './no-keyframes-tagged-template-expression';
|
|
20
21
|
import noMargin from './no-margin';
|
|
21
22
|
import noNestedStyles from './no-nested-styles';
|
|
22
23
|
import noPhysicalProperties from './no-physical-properties';
|
|
24
|
+
import noStyledTaggedTemplateExpression from './no-styled-tagged-template-expression';
|
|
23
25
|
import noUnsafeDesignTokenUsage from './no-unsafe-design-token-usage';
|
|
24
26
|
import noUnsafeStyleOverrides from './no-unsafe-style-overrides';
|
|
25
27
|
import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-libraries';
|
|
@@ -45,9 +47,11 @@ export default {
|
|
|
45
47
|
'no-exported-css': noExportedCss,
|
|
46
48
|
'no-exported-keyframes': noExportedKeyframes,
|
|
47
49
|
'no-invalid-css-map': noInvalidCssMap,
|
|
50
|
+
'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpression,
|
|
48
51
|
'no-margin': noMargin,
|
|
49
52
|
'no-nested-styles': noNestedStyles,
|
|
50
53
|
'no-physical-properties': noPhysicalProperties,
|
|
54
|
+
'no-styled-tagged-template-expression': noStyledTaggedTemplateExpression,
|
|
51
55
|
'no-unsafe-design-token-usage': noUnsafeDesignTokenUsage,
|
|
52
56
|
'no-unsafe-style-overrides': noUnsafeStyleOverrides,
|
|
53
57
|
'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
1
2
|
import { createLintRule } from '../utils/create-rule';
|
|
2
3
|
import { isCss } from '../utils/is-supported-import';
|
|
3
|
-
import { createNoTaggedTemplateExpressionRule } from './create-no-tagged-template-expression-rule';
|
|
4
4
|
var rule = createLintRule({
|
|
5
5
|
meta: {
|
|
6
6
|
name: 'no-css-tagged-template-expression',
|
|
@@ -13,7 +13,8 @@ var rule = createLintRule({
|
|
|
13
13
|
},
|
|
14
14
|
messages: {
|
|
15
15
|
unexpectedTaggedTemplate: 'Unexpected `css` tagged template expression'
|
|
16
|
-
}
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
17
18
|
},
|
|
18
19
|
create: createNoTaggedTemplateExpressionRule(isCss, 'unexpectedTaggedTemplate')
|
|
19
20
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isKeyframes } from '../utils/is-supported-import';
|
|
4
|
+
var rule = createLintRule({
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'no-keyframes-tagged-template-expression',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Disallows any `keyframe` tagged template expressions that originate from Emotion, Styled Components or Compiled',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
unexpectedTaggedTemplate: 'Unexpected `keyframes` tagged template expression'
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
18
|
+
},
|
|
19
|
+
create: createNoTaggedTemplateExpressionRule(isKeyframes, 'unexpectedTaggedTemplate')
|
|
20
|
+
});
|
|
21
|
+
export default rule;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isStyled } from './is-styled';
|
|
4
|
+
var rule = createLintRule({
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'no-styled-tagged-template-expression',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Disallows any `styled` tagged template expressions that originate from Emotion, Styled Components or Compiled',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
unexpectedTaggedTemplate: 'Unexpected `styled` tagged template expression'
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
18
|
+
},
|
|
19
|
+
create: createNoTaggedTemplateExpressionRule(isStyled, 'unexpectedTaggedTemplate')
|
|
20
|
+
});
|
|
21
|
+
export default rule;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { CSS_IN_JS_IMPORTS } from '../utils/is-supported-import';
|
|
4
|
+
var functionName = 'styled';
|
|
5
|
+
var checkDefinitionHasImport = function checkDefinitionHasImport(def, importSources) {
|
|
6
|
+
if (def.type !== 'ImportBinding') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (!def.parent || !importSources.includes(def.parent.source.value)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// `@compiled/react` only exposes styled as a named export
|
|
14
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.compiled) && def.parent.source.value === CSS_IN_JS_IMPORTS.compiled) {
|
|
15
|
+
return def.node.type === 'ImportSpecifier' && def.node.imported.name === functionName;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// `@emotion/styled` only exposes styled as a default export
|
|
19
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.emotionStyled) && def.parent.source.value === CSS_IN_JS_IMPORTS.emotionStyled) {
|
|
20
|
+
return def.node.type === 'ImportDefaultSpecifier';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// `styled-components` only exposes styled as a default export
|
|
24
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.styledComponents) && def.parent.source.value === CSS_IN_JS_IMPORTS.styledComponents) {
|
|
25
|
+
return def.node.type === 'ImportDefaultSpecifier';
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
29
|
+
export var isStyled = function isStyled(nodeToCheck, referencesInScope, importSources) {
|
|
30
|
+
var nodeIdentifier = null;
|
|
31
|
+
|
|
32
|
+
// Handles styled.div`` case
|
|
33
|
+
if (nodeToCheck.type === 'MemberExpression' && nodeToCheck.object.type === 'Identifier') {
|
|
34
|
+
nodeIdentifier = nodeToCheck.object;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Handles styled(Base)`` case
|
|
38
|
+
if (nodeToCheck.type === 'CallExpression' && nodeToCheck.callee.type === 'Identifier') {
|
|
39
|
+
nodeIdentifier = nodeToCheck.callee;
|
|
40
|
+
}
|
|
41
|
+
return referencesInScope.some(function (reference) {
|
|
42
|
+
var _reference$resolved;
|
|
43
|
+
return reference.identifier === nodeIdentifier && ((_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs.some(function (def) {
|
|
44
|
+
return checkDefinitionHasImport(def, importSources);
|
|
45
|
+
}));
|
|
46
|
+
});
|
|
47
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getFirstSupportedImport } from '../get-first-supported-import';
|
|
2
2
|
/**
|
|
3
3
|
* Given a list of node, find and return the callee of the first Compiled or styled-components `styled` function call found in the list.
|
|
4
4
|
*
|
|
@@ -42,15 +42,11 @@ var findNode = function findNode(nodes) {
|
|
|
42
42
|
* @returns The local name used to import the `styled` API.
|
|
43
43
|
*/
|
|
44
44
|
var getStyledImportSpecifierName = function getStyledImportSpecifierName(context, importSources) {
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
var supportedImports = source.ast.body.filter(isSupportedImport);
|
|
51
|
-
return (_supportedImports$0$s = supportedImports[0].specifiers.find(function (spec) {
|
|
52
|
-
return spec.type === 'ImportSpecifier' && spec.imported.name === 'styled';
|
|
53
|
-
})) === null || _supportedImports$0$s === void 0 ? void 0 : _supportedImports$0$s.local.name;
|
|
45
|
+
var _supportedImport$spec;
|
|
46
|
+
var supportedImport = getFirstSupportedImport(context, importSources);
|
|
47
|
+
return supportedImport === null || supportedImport === void 0 || (_supportedImport$spec = supportedImport.specifiers.find(function (spec) {
|
|
48
|
+
return spec.type === 'ImportSpecifier' && spec.imported.name === 'styled' || spec.type === 'ImportDefaultSpecifier' && spec.local.name === 'styled';
|
|
49
|
+
})) === null || _supportedImport$spec === void 0 ? void 0 : _supportedImport$spec.local.name;
|
|
54
50
|
};
|
|
55
51
|
|
|
56
52
|
/**
|
|
@@ -2,18 +2,38 @@ 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 { getImportSources } from '../is-supported-import';
|
|
6
6
|
import { generate } from './generate';
|
|
7
7
|
import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
|
|
8
8
|
import { toArguments } from './to-arguments';
|
|
9
|
-
var
|
|
9
|
+
export var noTaggedTemplateExpressionRuleSchema = [{
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
importSources: {
|
|
13
|
+
type: 'array',
|
|
14
|
+
items: {
|
|
15
|
+
type: 'string'
|
|
16
|
+
},
|
|
17
|
+
uniqueItems: true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* When true, template strings containing multiline comments are completely skipped over.
|
|
24
|
+
*
|
|
25
|
+
* When false, multiline comments are stripped out. Ideally we would preserve them,
|
|
26
|
+
* but it would add a lot of complexity.
|
|
27
|
+
*/
|
|
28
|
+
var shouldSkipMultilineComments = false;
|
|
10
29
|
export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplateExpressionRule(isUsage, messageId) {
|
|
11
30
|
return function (context) {
|
|
31
|
+
var importSources = getImportSources(context);
|
|
12
32
|
return {
|
|
13
33
|
TaggedTemplateExpression: function TaggedTemplateExpression(node) {
|
|
14
34
|
var _context$getScope = context.getScope(),
|
|
15
35
|
references = _context$getScope.references;
|
|
16
|
-
if (!isUsage(node.tag, references,
|
|
36
|
+
if (!isUsage(node.tag, references, importSources)) {
|
|
17
37
|
return;
|
|
18
38
|
}
|
|
19
39
|
context.report({
|
|
@@ -27,9 +47,9 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
|
|
|
27
47
|
quasi = node.quasi;
|
|
28
48
|
source = context.getSourceCode(); // TODO Eventually handle comments instead of skipping them
|
|
29
49
|
// Skip auto-fixing comments
|
|
30
|
-
if (!quasi.quasis.map(function (q) {
|
|
50
|
+
if (!(shouldSkipMultilineComments && quasi.quasis.map(function (q) {
|
|
31
51
|
return q.value.raw;
|
|
32
|
-
}).join('').match(/\/\*[\s\S]*\*\//g)) {
|
|
52
|
+
}).join('').match(/\/\*[\s\S]*\*\//g))) {
|
|
33
53
|
_context.next = 4;
|
|
34
54
|
break;
|
|
35
55
|
}
|