@atlaskit/eslint-plugin-design-system 8.32.0 → 8.32.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.
Files changed (22) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/constellation/no-styled-tagged-template-expression/usage.mdx +42 -0
  3. package/dist/cjs/rules/consistent-css-prop-usage/index.js +375 -334
  4. package/dist/cjs/rules/no-styled-tagged-template-expression/index.js +2 -2
  5. package/dist/cjs/rules/utils/create-no-tagged-template-expression-rule/index.js +10 -3
  6. package/dist/cjs/rules/utils/is-supported-import.js +64 -10
  7. package/dist/es2019/rules/consistent-css-prop-usage/index.js +283 -267
  8. package/dist/es2019/rules/no-styled-tagged-template-expression/index.js +1 -1
  9. package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/index.js +26 -1
  10. package/dist/es2019/rules/utils/is-supported-import.js +60 -10
  11. package/dist/esm/rules/consistent-css-prop-usage/index.js +375 -334
  12. package/dist/esm/rules/no-styled-tagged-template-expression/index.js +1 -1
  13. package/dist/esm/rules/utils/create-no-tagged-template-expression-rule/index.js +11 -4
  14. package/dist/esm/rules/utils/is-supported-import.js +63 -9
  15. package/dist/types/rules/utils/is-supported-import.d.ts +11 -0
  16. package/dist/types-ts4.5/rules/utils/is-supported-import.d.ts +11 -0
  17. package/package.json +1 -1
  18. package/dist/cjs/rules/no-styled-tagged-template-expression/is-styled.js +0 -53
  19. package/dist/es2019/rules/no-styled-tagged-template-expression/is-styled.js +0 -45
  20. package/dist/esm/rules/no-styled-tagged-template-expression/is-styled.js +0 -47
  21. package/dist/types/rules/no-styled-tagged-template-expression/is-styled.d.ts +0 -7
  22. package/dist/types-ts4.5/rules/no-styled-tagged-template-expression/is-styled.d.ts +0 -7
@@ -1,6 +1,6 @@
1
1
  import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
2
2
  import { createLintRule } from '../utils/create-rule';
3
- import { isStyled } from './is-styled';
3
+ import { isStyled } from '../utils/is-supported-import';
4
4
  var rule = createLintRule({
5
5
  meta: {
6
6
  name: 'no-styled-tagged-template-expression',
@@ -2,7 +2,7 @@ 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 { getImportSources } from '../is-supported-import';
5
+ import { getImportSources, isStyledComponents } 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';
@@ -36,6 +36,7 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
36
36
  if (!isUsage(node.tag, references, importSources)) {
37
37
  return;
38
38
  }
39
+ var isSC = isStyledComponents(node.tag, references, importSources);
39
40
  context.report({
40
41
  messageId: messageId,
41
42
  node: node,
@@ -87,12 +88,18 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
87
88
  }
88
89
  return _context.abrupt("return");
89
90
  case 16:
90
- _context.next = 18;
91
- return fixer.insertTextBefore(node, newCode);
91
+ if (!(isSC && /\$\{.*:[\s]*\{/.test(newCode))) {
92
+ _context.next = 18;
93
+ break;
94
+ }
95
+ return _context.abrupt("return");
92
96
  case 18:
93
97
  _context.next = 20;
94
- return fixer.remove(node);
98
+ return fixer.insertTextBefore(node, newCode);
95
99
  case 20:
100
+ _context.next = 22;
101
+ return fixer.remove(node);
102
+ case 22:
96
103
  case "end":
97
104
  return _context.stop();
98
105
  }
@@ -16,6 +16,21 @@ export var CSS_IN_JS_IMPORTS = {
16
16
  * By default all known import sources are checked against.
17
17
  */
18
18
  export var DEFAULT_IMPORT_SOURCES = Object.values(CSS_IN_JS_IMPORTS);
19
+ var getIdentifierNode = function getIdentifierNode(node) {
20
+ var identifierNode = node.type === 'Identifier' ? node : undefined;
21
+ if (!identifierNode) {
22
+ // Handles styled.div`` case
23
+ if (node.type === 'MemberExpression' && node.object.type === 'Identifier') {
24
+ identifierNode = node.object;
25
+ }
26
+
27
+ // Handles styled(Component)`` case
28
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier') {
29
+ identifierNode = node.callee;
30
+ }
31
+ }
32
+ return identifierNode;
33
+ };
19
34
 
20
35
  /**
21
36
  * Given the ESLint rule context, extract and parse the value of the importSources rule option.
@@ -36,6 +51,7 @@ export var getImportSources = function getImportSources(context) {
36
51
  return DEFAULT_IMPORT_SOURCES;
37
52
  };
38
53
  var isSupportedImportWrapper = function isSupportedImportWrapper(functionName) {
54
+ var defaultFromImportSources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
39
55
  var checkDefinitionHasImport = function checkDefinitionHasImport(def, importSources) {
40
56
  if (def.type !== 'ImportBinding') {
41
57
  return false;
@@ -43,12 +59,19 @@ var isSupportedImportWrapper = function isSupportedImportWrapper(functionName) {
43
59
  if (!def.parent || !importSources.includes(def.parent.source.value)) {
44
60
  return false;
45
61
  }
46
- return (
47
- // import { functionName } from 'import-source';
48
- def.node.type === 'ImportSpecifier' && def.node.imported.name === functionName ||
49
- // import functionName from 'import-source';
50
- def.node.type === 'ImportDefaultSpecifier' && def.node.local.name === functionName
51
- );
62
+
63
+ // Matches the imported name from a named import
64
+ // import { functionName, functioName as otherName } from 'import-source';
65
+ var isNamedImport = def.node.type === 'ImportSpecifier' && def.node.imported.name === functionName;
66
+
67
+ // Must explicitly match the local name from a default import
68
+ // import functionName from 'import-source';
69
+ var isDefaultImportMatchingLocal = def.node.type === 'ImportDefaultSpecifier' && def.node.local.name === functionName;
70
+
71
+ // Can match any local name from a default import
72
+ // import anything from 'import-source'
73
+ var isKnownDefaultImport = def.node.type === 'ImportDefaultSpecifier' && defaultFromImportSources.includes(def.parent.source.value);
74
+ return isNamedImport || isDefaultImportMatchingLocal || isKnownDefaultImport;
52
75
  };
53
76
 
54
77
  /**
@@ -68,9 +91,10 @@ var isSupportedImportWrapper = function isSupportedImportWrapper(functionName) {
68
91
  * @returns Whether the above conditions are true.
69
92
  */
70
93
  var isSupportedImport = function isSupportedImport(nodeToCheck, referencesInScope, importSources) {
71
- return nodeToCheck.type === 'Identifier' && referencesInScope.some(function (reference) {
94
+ var identifierNode = getIdentifierNode(nodeToCheck);
95
+ return (identifierNode === null || identifierNode === void 0 ? void 0 : identifierNode.type) === 'Identifier' && referencesInScope.some(function (reference) {
72
96
  var _reference$resolved;
73
- return reference.identifier === nodeToCheck && ((_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs.some(function (def) {
97
+ return reference.identifier === identifierNode && ((_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs.some(function (def) {
74
98
  return checkDefinitionHasImport(def, importSources);
75
99
  }));
76
100
  });
@@ -85,4 +109,34 @@ export var isCss = isSupportedImportWrapper('css');
85
109
  export var isCxFunction = isSupportedImportWrapper('cx');
86
110
  export var isCssMap = isSupportedImportWrapper('cssMap');
87
111
  export var isKeyframes = isSupportedImportWrapper('keyframes');
88
- export var isStyled = isSupportedImportWrapper('styled');
112
+ // `styled` is also the explicit default of `styled-components` and `@emotion/styled`, so we also match on default imports generally
113
+ export var isStyled = isSupportedImportWrapper('styled', ['styled-components', '@emotion/styled']);
114
+ export var isImportedFrom = function isImportedFrom(moduleName) {
115
+ var exactMatch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
116
+ return function (nodeToCheck, referencesInScope, importSources) {
117
+ if (!importSources.includes(moduleName)) {
118
+ // Don't go through the trouble of checking the import sources does not include this
119
+ // We'll assume this is skipped elsewhere.
120
+ return false;
121
+ }
122
+ var identifierNode = getIdentifierNode(nodeToCheck);
123
+ return (identifierNode === null || identifierNode === void 0 ? void 0 : identifierNode.type) === 'Identifier' && referencesInScope.some(function (reference) {
124
+ var _reference$resolved2;
125
+ return reference.identifier === identifierNode && ((_reference$resolved2 = reference.resolved) === null || _reference$resolved2 === void 0 ? void 0 : _reference$resolved2.defs.some(function (def) {
126
+ var _def$parent, _String, _def$parent2;
127
+ return def.type === 'ImportBinding' && (((_def$parent = def.parent) === null || _def$parent === void 0 ? void 0 : _def$parent.source.value) === moduleName || !exactMatch && ((_String = String((_def$parent2 = def.parent) === null || _def$parent2 === void 0 ? void 0 : _def$parent2.source.value)) === null || _String === void 0 ? void 0 : _String.startsWith(moduleName)));
128
+ }));
129
+ });
130
+ };
131
+ };
132
+
133
+ /**
134
+ * Determine if this node is specifically from a `'styled-components'` import.
135
+ * This is because `styled-components@3.4` APIs are not consistent with Emotion and Compiled,
136
+ * we need to handle them differently in a few scenarios.
137
+ *
138
+ * This can be cleaned up when `'styled-components'` is no longer a valid ImportSource.
139
+ */
140
+ export var isStyledComponents = isImportedFrom('styled-components');
141
+ export var isCompiled = isImportedFrom('@compiled/', false);
142
+ export var isEmotion = isImportedFrom('@emotion/', false);
@@ -31,4 +31,15 @@ export declare const isCxFunction: SupportedNameChecker;
31
31
  export declare const isCssMap: SupportedNameChecker;
32
32
  export declare const isKeyframes: SupportedNameChecker;
33
33
  export declare const isStyled: SupportedNameChecker;
34
+ export declare const isImportedFrom: (moduleName: string, exactMatch?: boolean) => (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
35
+ /**
36
+ * Determine if this node is specifically from a `'styled-components'` import.
37
+ * This is because `styled-components@3.4` APIs are not consistent with Emotion and Compiled,
38
+ * we need to handle them differently in a few scenarios.
39
+ *
40
+ * This can be cleaned up when `'styled-components'` is no longer a valid ImportSource.
41
+ */
42
+ export declare const isStyledComponents: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
43
+ export declare const isCompiled: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
44
+ export declare const isEmotion: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
34
45
  export {};
@@ -31,4 +31,15 @@ export declare const isCxFunction: SupportedNameChecker;
31
31
  export declare const isCssMap: SupportedNameChecker;
32
32
  export declare const isKeyframes: SupportedNameChecker;
33
33
  export declare const isStyled: SupportedNameChecker;
34
+ export declare const isImportedFrom: (moduleName: string, exactMatch?: boolean) => (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
35
+ /**
36
+ * Determine if this node is specifically from a `'styled-components'` import.
37
+ * This is because `styled-components@3.4` APIs are not consistent with Emotion and Compiled,
38
+ * we need to handle them differently in a few scenarios.
39
+ *
40
+ * This can be cleaned up when `'styled-components'` is no longer a valid ImportSource.
41
+ */
42
+ export declare const isStyledComponents: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
43
+ export declare const isCompiled: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
44
+ export declare const isEmotion: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
34
45
  export {};
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": "8.32.0",
4
+ "version": "8.32.2",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "publishConfig": {
7
7
  "registry": "https://registry.npmjs.org/"
@@ -1,53 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.isStyled = void 0;
7
- var _isSupportedImport = require("../utils/is-supported-import");
8
- // eslint-disable-next-line import/no-extraneous-dependencies
9
-
10
- var functionName = 'styled';
11
- var checkDefinitionHasImport = function checkDefinitionHasImport(def, importSources) {
12
- if (def.type !== 'ImportBinding') {
13
- return false;
14
- }
15
- if (!def.parent || !importSources.includes(def.parent.source.value)) {
16
- return false;
17
- }
18
-
19
- // `@compiled/react` only exposes styled as a named export
20
- if (importSources.includes(_isSupportedImport.CSS_IN_JS_IMPORTS.compiled) && def.parent.source.value === _isSupportedImport.CSS_IN_JS_IMPORTS.compiled) {
21
- return def.node.type === 'ImportSpecifier' && def.node.imported.name === functionName;
22
- }
23
-
24
- // `@emotion/styled` only exposes styled as a default export
25
- if (importSources.includes(_isSupportedImport.CSS_IN_JS_IMPORTS.emotionStyled) && def.parent.source.value === _isSupportedImport.CSS_IN_JS_IMPORTS.emotionStyled) {
26
- return def.node.type === 'ImportDefaultSpecifier';
27
- }
28
-
29
- // `styled-components` only exposes styled as a default export
30
- if (importSources.includes(_isSupportedImport.CSS_IN_JS_IMPORTS.styledComponents) && def.parent.source.value === _isSupportedImport.CSS_IN_JS_IMPORTS.styledComponents) {
31
- return def.node.type === 'ImportDefaultSpecifier';
32
- }
33
- return false;
34
- };
35
- var isStyled = exports.isStyled = function isStyled(nodeToCheck, referencesInScope, importSources) {
36
- var nodeIdentifier = null;
37
-
38
- // Handles styled.div`` case
39
- if (nodeToCheck.type === 'MemberExpression' && nodeToCheck.object.type === 'Identifier') {
40
- nodeIdentifier = nodeToCheck.object;
41
- }
42
-
43
- // Handles styled(Base)`` case
44
- if (nodeToCheck.type === 'CallExpression' && nodeToCheck.callee.type === 'Identifier') {
45
- nodeIdentifier = nodeToCheck.callee;
46
- }
47
- return referencesInScope.some(function (reference) {
48
- var _reference$resolved;
49
- return reference.identifier === nodeIdentifier && ((_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs.some(function (def) {
50
- return checkDefinitionHasImport(def, importSources);
51
- }));
52
- });
53
- };
@@ -1,45 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
-
3
- import { CSS_IN_JS_IMPORTS } from '../utils/is-supported-import';
4
- const functionName = 'styled';
5
- const 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 const isStyled = (nodeToCheck, referencesInScope, importSources) => {
30
- let 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(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(def => checkDefinitionHasImport(def, importSources)));
44
- });
45
- };
@@ -1,47 +0,0 @@
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,7 +0,0 @@
1
- import type { Scope } from 'eslint';
2
- import type { CallExpression } from 'estree';
3
- import { ImportSource } from '../utils/is-supported-import';
4
- type Callee = CallExpression['callee'];
5
- type Reference = Scope.Reference;
6
- export declare const isStyled: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
7
- export {};
@@ -1,7 +0,0 @@
1
- import type { Scope } from 'eslint';
2
- import type { CallExpression } from 'estree';
3
- import { ImportSource } from '../utils/is-supported-import';
4
- type Callee = CallExpression['callee'];
5
- type Reference = Scope.Reference;
6
- export declare const isStyled: (nodeToCheck: Callee, referencesInScope: Reference[], importSources: ImportSource[]) => boolean;
7
- export {};