@atlaskit/eslint-plugin-design-system 8.25.2 → 8.27.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +4 -0
  3. package/constellation/index/usage.mdx +402 -6
  4. package/dist/cjs/presets/all.codegen.js +5 -1
  5. package/dist/cjs/presets/recommended.codegen.js +5 -1
  6. package/dist/cjs/rules/consistent-css-prop-usage/index.js +254 -32
  7. package/dist/cjs/rules/index.codegen.js +9 -1
  8. package/dist/cjs/rules/no-empty-styled-expression/index.js +75 -0
  9. package/dist/cjs/rules/no-exported-css/index.js +37 -0
  10. package/dist/cjs/rules/no-exported-keyframes/index.js +37 -0
  11. package/dist/cjs/rules/no-invalid-css-map/index.js +102 -0
  12. package/dist/cjs/rules/no-invalid-css-map/utils.js +193 -0
  13. package/dist/cjs/rules/utils/create-no-exported-rule/check-if-supported-export.js +158 -0
  14. package/dist/cjs/rules/utils/create-no-exported-rule/is-styled-component.js +80 -0
  15. package/dist/cjs/rules/utils/create-no-exported-rule/main.js +66 -0
  16. package/dist/cjs/rules/utils/get-first-supported-import.js +28 -0
  17. package/dist/cjs/rules/utils/is-supported-import.js +53 -16
  18. package/dist/es2019/presets/all.codegen.js +5 -1
  19. package/dist/es2019/presets/recommended.codegen.js +5 -1
  20. package/dist/es2019/rules/consistent-css-prop-usage/index.js +251 -33
  21. package/dist/es2019/rules/index.codegen.js +9 -1
  22. package/dist/es2019/rules/no-empty-styled-expression/index.js +65 -0
  23. package/dist/es2019/rules/no-exported-css/index.js +31 -0
  24. package/dist/es2019/rules/no-exported-keyframes/index.js +31 -0
  25. package/dist/es2019/rules/no-invalid-css-map/index.js +95 -0
  26. package/dist/es2019/rules/no-invalid-css-map/utils.js +134 -0
  27. package/dist/es2019/rules/utils/create-no-exported-rule/check-if-supported-export.js +142 -0
  28. package/dist/es2019/rules/utils/create-no-exported-rule/is-styled-component.js +70 -0
  29. package/dist/es2019/rules/utils/create-no-exported-rule/main.js +59 -0
  30. package/dist/es2019/rules/utils/get-first-supported-import.js +22 -0
  31. package/dist/es2019/rules/utils/is-supported-import.js +50 -15
  32. package/dist/esm/presets/all.codegen.js +5 -1
  33. package/dist/esm/presets/recommended.codegen.js +5 -1
  34. package/dist/esm/rules/consistent-css-prop-usage/index.js +255 -33
  35. package/dist/esm/rules/index.codegen.js +9 -1
  36. package/dist/esm/rules/no-empty-styled-expression/index.js +68 -0
  37. package/dist/esm/rules/no-exported-css/index.js +31 -0
  38. package/dist/esm/rules/no-exported-keyframes/index.js +31 -0
  39. package/dist/esm/rules/no-invalid-css-map/index.js +96 -0
  40. package/dist/esm/rules/no-invalid-css-map/utils.js +186 -0
  41. package/dist/esm/rules/utils/create-no-exported-rule/check-if-supported-export.js +151 -0
  42. package/dist/esm/rules/utils/create-no-exported-rule/is-styled-component.js +74 -0
  43. package/dist/esm/rules/utils/create-no-exported-rule/main.js +60 -0
  44. package/dist/esm/rules/utils/get-first-supported-import.js +22 -0
  45. package/dist/esm/rules/utils/is-supported-import.js +51 -15
  46. package/dist/types/index.codegen.d.ts +8 -0
  47. package/dist/types/presets/all.codegen.d.ts +5 -1
  48. package/dist/types/presets/recommended.codegen.d.ts +5 -1
  49. package/dist/types/rules/consistent-css-prop-usage/types.d.ts +7 -2
  50. package/dist/types/rules/index.codegen.d.ts +4 -0
  51. package/dist/types/rules/no-empty-styled-expression/index.d.ts +3 -0
  52. package/dist/types/rules/no-exported-css/index.d.ts +3 -0
  53. package/dist/types/rules/no-exported-keyframes/index.d.ts +3 -0
  54. package/dist/types/rules/no-invalid-css-map/index.d.ts +3 -0
  55. package/dist/types/rules/no-invalid-css-map/utils.d.ts +14 -0
  56. package/dist/types/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
  57. package/dist/types/rules/utils/create-no-exported-rule/check-if-supported-export.d.ts +15 -0
  58. package/dist/types/rules/utils/create-no-exported-rule/is-styled-component.d.ts +14 -0
  59. package/dist/types/rules/utils/create-no-exported-rule/main.d.ts +19 -0
  60. package/dist/types/rules/utils/create-rule.d.ts +1 -1
  61. package/dist/types/rules/utils/get-first-supported-import.d.ts +17 -0
  62. package/dist/types/rules/utils/is-supported-import.d.ts +26 -8
  63. package/dist/types-ts4.5/index.codegen.d.ts +8 -0
  64. package/dist/types-ts4.5/presets/all.codegen.d.ts +5 -1
  65. package/dist/types-ts4.5/presets/recommended.codegen.d.ts +5 -1
  66. package/dist/types-ts4.5/rules/consistent-css-prop-usage/types.d.ts +7 -2
  67. package/dist/types-ts4.5/rules/index.codegen.d.ts +4 -0
  68. package/dist/types-ts4.5/rules/no-empty-styled-expression/index.d.ts +3 -0
  69. package/dist/types-ts4.5/rules/no-exported-css/index.d.ts +3 -0
  70. package/dist/types-ts4.5/rules/no-exported-keyframes/index.d.ts +3 -0
  71. package/dist/types-ts4.5/rules/no-invalid-css-map/index.d.ts +3 -0
  72. package/dist/types-ts4.5/rules/no-invalid-css-map/utils.d.ts +14 -0
  73. package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
  74. package/dist/types-ts4.5/rules/utils/create-no-exported-rule/check-if-supported-export.d.ts +15 -0
  75. package/dist/types-ts4.5/rules/utils/create-no-exported-rule/is-styled-component.d.ts +14 -0
  76. package/dist/types-ts4.5/rules/utils/create-no-exported-rule/main.d.ts +19 -0
  77. package/dist/types-ts4.5/rules/utils/create-rule.d.ts +1 -1
  78. package/dist/types-ts4.5/rules/utils/get-first-supported-import.d.ts +17 -0
  79. package/dist/types-ts4.5/rules/utils/is-supported-import.d.ts +26 -8
  80. package/package.json +3 -1
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _checkIfSupportedExport = require("../utils/create-no-exported-rule/check-if-supported-export");
8
+ var _createRule = require("../utils/create-rule");
9
+ var _isSupportedImport = require("../utils/is-supported-import");
10
+ var _utils = require("./utils");
11
+ var IMPORT_SOURCES = [_isSupportedImport.CSS_IN_JS_IMPORTS.compiled, _isSupportedImport.CSS_IN_JS_IMPORTS.atlaskitCss];
12
+ var reportIfExported = function reportIfExported(node, context) {
13
+ var state = (0, _checkIfSupportedExport.checkIfSupportedExport)(context, node, IMPORT_SOURCES);
14
+ if (!state.isExport) {
15
+ return;
16
+ }
17
+ context.report({
18
+ messageId: 'noExportedCssMap',
19
+ node: state.node
20
+ });
21
+ };
22
+ var reportIfNotTopLevelScope = function reportIfNotTopLevelScope(node, context) {
23
+ // Treat `export` keyword as valid because the reportIfExported function already handles those
24
+ var validTypes = ['ExportDefaultDeclaration', 'ExportNamedDeclaration', 'Program', 'VariableDeclaration', 'VariableDeclarator'];
25
+ var parentNode = node.parent;
26
+ while (parentNode) {
27
+ if (!validTypes.includes(parentNode.type)) {
28
+ context.report({
29
+ node: node,
30
+ messageId: 'mustBeTopLevelScope'
31
+ });
32
+ return;
33
+ }
34
+ parentNode = parentNode.parent;
35
+ }
36
+ };
37
+ var createCssMapRule = function createCssMapRule(context) {
38
+ var _context$getSourceCod = context.getSourceCode(),
39
+ text = _context$getSourceCod.text;
40
+ if (IMPORT_SOURCES.every(function (importSource) {
41
+ return !text.includes(importSource);
42
+ })) {
43
+ return {};
44
+ }
45
+ return {
46
+ CallExpression: function CallExpression(node) {
47
+ var references = context.getScope().references;
48
+ if (!(0, _isSupportedImport.isCssMap)(node.callee, references, IMPORT_SOURCES)) {
49
+ return;
50
+ }
51
+ reportIfExported(node, context);
52
+ reportIfNotTopLevelScope(node, context);
53
+ var cssMapObject = (0, _utils.getCssMapObject)(node);
54
+ if (!cssMapObject) {
55
+ return;
56
+ }
57
+ var cssMapObjectChecker = new _utils.CssMapObjectChecker(cssMapObject, context);
58
+ cssMapObjectChecker.run();
59
+ }
60
+ };
61
+ };
62
+ var noInvalidCssMapRule = (0, _createRule.createLintRule)({
63
+ meta: {
64
+ name: 'no-invalid-css-map',
65
+ docs: {
66
+ description: "Checks the validity of a CSS map created through cssMap. This is intended to be used alongside TypeScript's type-checking.",
67
+ recommended: true,
68
+ severity: 'error'
69
+ },
70
+ messages: {
71
+ mustBeTopLevelScope: 'cssMap must only be used in the top-most scope of the module.',
72
+ noNonStaticallyEvaluable: 'Cannot statically evaluate the value of this variable. Values used in the cssMap function call should have a value evaluable at build time.',
73
+ noExportedCssMap: 'cssMap usages cannot be exported.',
74
+ noInlineFunctions: 'Cannot use functions as values in cssMap - values must only be statically evaluable values (e.g. strings, numbers).',
75
+ noFunctionCalls: 'Cannot call external functions in cssMap - values must only be statically evaluable values (e.g. strings, numbers).',
76
+ noSpreadElement: 'Cannot use the spread operator in cssMap.'
77
+ },
78
+ schema: [{
79
+ type: 'object',
80
+ properties: {
81
+ allowedFunctionCalls: {
82
+ type: 'array',
83
+ items: {
84
+ type: 'array',
85
+ minItems: 2,
86
+ maxItems: 2,
87
+ items: [{
88
+ type: 'string'
89
+ }, {
90
+ type: 'string'
91
+ }]
92
+ },
93
+ uniqueItems: true
94
+ }
95
+ },
96
+ additionalProperties: false
97
+ }],
98
+ type: 'problem'
99
+ },
100
+ create: createCssMapRule
101
+ });
102
+ var _default = exports.default = noInvalidCssMapRule;
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getCssMapObject = exports.CssMapObjectChecker = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
12
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
13
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
+ var getCssMapObject = exports.getCssMapObject = function getCssMapObject(node) {
15
+ // We assume the argument `node` is already a cssMap() call.
16
+
17
+ // Things like the number of arguments to cssMap and the type of
18
+ // cssMap's argument are handled by the TypeScript compiler, so
19
+ // we don't bother with creating eslint errors for these here
20
+
21
+ if (node.arguments.length !== 1 || node.arguments[0].type !== 'ObjectExpression') {
22
+ return;
23
+ }
24
+ return node.arguments[0];
25
+ };
26
+ var findNodeReference = function findNodeReference(references, node) {
27
+ return references.find(function (reference) {
28
+ return reference.identifier === node;
29
+ });
30
+ };
31
+ var getAllowedFunctionCalls = function getAllowedFunctionCalls(options) {
32
+ var _options$;
33
+ if (options.length === 0 || ((_options$ = options[0]) === null || _options$ === void 0 ? void 0 : _options$.allowedFunctionCalls) === undefined) {
34
+ return [];
35
+ }
36
+
37
+ // Beyond the basic check of "does allowedFunctionCalls exist?",
38
+ // we assume ESLint's rule checker type checks the contents of allowedFunctionCalls
39
+ // as it should
40
+ return options[0].allowedFunctionCalls;
41
+ };
42
+ var CssMapObjectChecker = exports.CssMapObjectChecker = /*#__PURE__*/function () {
43
+ function CssMapObjectChecker(cssMapObject, context) {
44
+ (0, _classCallCheck2.default)(this, CssMapObjectChecker);
45
+ this.allowedFunctionCalls = getAllowedFunctionCalls(context.options);
46
+ this.cssMapObject = cssMapObject;
47
+ this.report = context.report;
48
+ this.references = context.getScope().references;
49
+ }
50
+ (0, _createClass2.default)(CssMapObjectChecker, [{
51
+ key: "isNotWhitelistedFunction",
52
+ value: function isNotWhitelistedFunction(callee) {
53
+ var _reference$resolved,
54
+ _this = this;
55
+ if (callee.type !== 'Identifier' || this.allowedFunctionCalls.length === 0) {
56
+ return true;
57
+ }
58
+ var reference = findNodeReference(this.references, callee);
59
+ var definitions = reference === null || reference === void 0 || (_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs;
60
+ if (!definitions) {
61
+ return true;
62
+ }
63
+ return definitions.some(function (definition) {
64
+ // We add some restrictions to keep this simple...
65
+ // Forbid non-imported functions
66
+ if (definition.type !== 'ImportBinding') {
67
+ return true;
68
+ }
69
+ // Forbid default imports (e.g. `import React from 'react'`)
70
+ if (definition.node.type !== 'ImportSpecifier') {
71
+ return true;
72
+ }
73
+ var packageName = definition.parent.source.value;
74
+ var importedFunctionName = definition.node.imported.name;
75
+ return !_this.allowedFunctionCalls.some(function (_ref) {
76
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
77
+ allowedPackageName = _ref2[0],
78
+ allowedFunctionName = _ref2[1];
79
+ return allowedPackageName === packageName && allowedFunctionName === importedFunctionName;
80
+ });
81
+ });
82
+ }
83
+ }, {
84
+ key: "checkCssMapObjectValue",
85
+ value: function checkCssMapObjectValue(value) {
86
+ if (value.type === 'CallExpression' && this.isNotWhitelistedFunction(value.callee)) {
87
+ // object value is a function call in the style
88
+ // {
89
+ // key: functionCall(), ...
90
+ // }
91
+ this.report({
92
+ node: value,
93
+ messageId: 'noFunctionCalls'
94
+ });
95
+ } else if (value.type === 'ArrowFunctionExpression' || value.type === 'FunctionExpression') {
96
+ // object value is a function call in the style
97
+ // {
98
+ // key: (prop) => prop.color, // ArrowFunctionExpression
99
+ // get danger() { return { ... } }, // FunctionExpression
100
+ // }
101
+ this.report({
102
+ node: value,
103
+ messageId: 'noInlineFunctions'
104
+ });
105
+ } else if (value.type === 'BinaryExpression' || value.type === 'LogicalExpression') {
106
+ this.checkCssMapObjectValue(value.left);
107
+ this.checkCssMapObjectValue(value.right);
108
+ } else if (value.type === 'Identifier') {
109
+ var _reference$resolved2;
110
+ var reference = findNodeReference(this.references, value);
111
+
112
+ // Get the variable's definition when initialised. Assume that the last definition
113
+ // is the most recent one.
114
+ //
115
+ // Ideally we would try to get the variable's value at the point at which
116
+ // cssMap() is run, but ESLint doesn't seem to give us an easy way to
117
+ // do that...
118
+ var definitions = reference === null || reference === void 0 || (_reference$resolved2 = reference.resolved) === null || _reference$resolved2 === void 0 ? void 0 : _reference$resolved2.defs;
119
+ if (!definitions || definitions.length === 0) {
120
+ // Variable is not defined :thinking:
121
+ return;
122
+ }
123
+ var _iterator = _createForOfIteratorHelper(definitions),
124
+ _step;
125
+ try {
126
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
127
+ var definition = _step.value;
128
+ if (definition.type === 'Variable' && definition.node.init) {
129
+ return this.checkCssMapObjectValue(definition.node.init);
130
+ }
131
+ }
132
+ } catch (err) {
133
+ _iterator.e(err);
134
+ } finally {
135
+ _iterator.f();
136
+ }
137
+ } else if (value.type === 'ObjectExpression') {
138
+ // Object inside another object
139
+ this.checkCssMapObject(value);
140
+ } else if (value.type === 'TemplateLiteral') {
141
+ // object value is a template literal, something like
142
+ // `hello world`
143
+ // `hello ${functionCall()} world`
144
+ // `hello ${someVariable} world`
145
+ // etc.
146
+ //
147
+ // where the expressions are the parts enclosed within the
148
+ // ${ ... }
149
+ var _iterator2 = _createForOfIteratorHelper(value.expressions),
150
+ _step2;
151
+ try {
152
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
153
+ var expression = _step2.value;
154
+ this.checkCssMapObjectValue(expression);
155
+ }
156
+ } catch (err) {
157
+ _iterator2.e(err);
158
+ } finally {
159
+ _iterator2.f();
160
+ }
161
+ }
162
+ }
163
+ }, {
164
+ key: "checkCssMapObject",
165
+ value: function checkCssMapObject(cssMapObject) {
166
+ var _iterator3 = _createForOfIteratorHelper(cssMapObject.properties),
167
+ _step3;
168
+ try {
169
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
170
+ var property = _step3.value;
171
+ if (property.type === 'SpreadElement') {
172
+ this.report({
173
+ node: property,
174
+ messageId: 'noSpreadElement'
175
+ });
176
+ continue;
177
+ }
178
+ this.checkCssMapObjectValue(property.value);
179
+ }
180
+ } catch (err) {
181
+ _iterator3.e(err);
182
+ } finally {
183
+ _iterator3.f();
184
+ }
185
+ }
186
+ }, {
187
+ key: "run",
188
+ value: function run() {
189
+ this.checkCssMapObject(this.cssMapObject);
190
+ }
191
+ }]);
192
+ return CssMapObjectChecker;
193
+ }();
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.checkIfSupportedExport = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _isStyledComponent = require("./is-styled-component");
10
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
11
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
12
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
13
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
+ var getStack = function getStack(context, node) {
16
+ var _scope;
17
+ var _context$getSourceCod = context.getSourceCode(),
18
+ scopeManager = _context$getSourceCod.scopeManager;
19
+ var stack = {
20
+ nodes: [],
21
+ root: node
22
+ };
23
+ var scope;
24
+ for (var current = node; current.type !== 'Program'; current = current.parent) {
25
+ if (!scope) {
26
+ var currentScope = scopeManager.acquire(current);
27
+ if (currentScope) {
28
+ scope = currentScope;
29
+ }
30
+ }
31
+ switch (current.type) {
32
+ case 'ExportDefaultDeclaration':
33
+ case 'ExportNamedDeclaration':
34
+ stack.root = current;
35
+ break;
36
+ case 'VariableDeclarator':
37
+ stack.root = current;
38
+ break;
39
+ case 'ExportSpecifier':
40
+ case 'ObjectExpression':
41
+ case 'VariableDeclaration':
42
+ break;
43
+ default:
44
+ stack.nodes.unshift(current);
45
+ }
46
+ }
47
+ return _objectSpread(_objectSpread({}, stack), {}, {
48
+ scope: (_scope = scope) !== null && _scope !== void 0 ? _scope : context.getScope()
49
+ });
50
+ };
51
+ var matches = function matches(defs, refs) {
52
+ // When there are no defs, the definition is inlined. This must be a match as we know the refs contain the initial
53
+ // definition.
54
+ if (!defs.length) {
55
+ return true;
56
+ }
57
+
58
+ // When there are no refs, the reference refers to the entire definition and therefore must be a match.
59
+ if (!refs.length) {
60
+ return true;
61
+ }
62
+
63
+ // When both the references and definitions exist, they should match in length
64
+ if (defs.length !== refs.length) {
65
+ return false;
66
+ }
67
+ return defs.every(function (def, i) {
68
+ var ref = refs[i];
69
+ if (def.type === 'Property') {
70
+ // There is a match between the def and the ref when both names match:
71
+ //
72
+ // const fooDef = { bar: '' };
73
+ // const barRef = fooDef.bar
74
+ //
75
+ // There is no match when the ref property does not match the definition key name:
76
+ //
77
+ // const barRef = fooDef.notFound
78
+ return def.key.type === 'Identifier' && ref.type === 'MemberExpression' && ref.property.type === 'Identifier' && ref.property.name === def.key.name;
79
+ }
80
+
81
+ // Anything here is either unsupported or should not match...
82
+ return false;
83
+ });
84
+ };
85
+ var checkIfSupportedExport = exports.checkIfSupportedExport = function checkIfSupportedExport(context, node, importSources) {
86
+ var _resolved$references;
87
+ var scope = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : context.getScope();
88
+ // Ignore any expression defined outside of the global or module scope as we have no way of statically analysing them
89
+ if (scope.type !== 'global' && scope.type !== 'module') {
90
+ return {
91
+ isExport: false
92
+ };
93
+ }
94
+ var _getStack = getStack(context, node.parent),
95
+ root = _getStack.root,
96
+ nodes = _getStack.nodes;
97
+ // Exporting a component with a css reference should be allowed
98
+ if ((0, _isStyledComponent.isStyledComponent)(nodes, context, importSources)) {
99
+ return {
100
+ isExport: false
101
+ };
102
+ }
103
+ if (root.type === 'ExportDefaultDeclaration' || root.type === 'ExportNamedDeclaration') {
104
+ return {
105
+ isExport: true,
106
+ node: root
107
+ };
108
+ }
109
+ if (root.type !== 'VariableDeclarator') {
110
+ return {
111
+ isExport: false
112
+ };
113
+ }
114
+
115
+ // Find the reference to the variable declarator
116
+ var reference = scope.references.find(function (_ref) {
117
+ var identifier = _ref.identifier;
118
+ return identifier === root.id;
119
+ });
120
+ if (!reference) {
121
+ return {
122
+ isExport: false
123
+ };
124
+ }
125
+
126
+ // Iterate through all of the references to the resolved variable declarator node
127
+ var resolved = reference.resolved;
128
+ var _iterator = _createForOfIteratorHelper((_resolved$references = resolved === null || resolved === void 0 ? void 0 : resolved.references) !== null && _resolved$references !== void 0 ? _resolved$references : []),
129
+ _step;
130
+ try {
131
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
132
+ var identifier = _step.value.identifier;
133
+ // Skip references to the root, since it has already been processed above
134
+ if (identifier === root.id) {
135
+ continue;
136
+ }
137
+ var _getStack2 = getStack(context, identifier.parent),
138
+ refs = _getStack2.nodes,
139
+ nextScope = _getStack2.scope;
140
+
141
+ // Only validate the resolved reference if it accesses the definition node
142
+ if (matches(nodes, refs.reverse())) {
143
+ // Now validate the identifier reference as a definition
144
+ var validity = checkIfSupportedExport(context, identifier, importSources, nextScope);
145
+ if (validity.isExport) {
146
+ return validity;
147
+ }
148
+ }
149
+ }
150
+ } catch (err) {
151
+ _iterator.e(err);
152
+ } finally {
153
+ _iterator.f();
154
+ }
155
+ return {
156
+ isExport: false
157
+ };
158
+ };
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isStyledComponent = void 0;
7
+ var _getFirstSupportedImport = require("../get-first-supported-import");
8
+ /**
9
+ * Given a list of node, find and return the callee of the first Compiled or styled-components `styled` function call found in the list.
10
+ *
11
+ * For example, given `styled.div({ ... })`, we return the node corresponding to the
12
+ * `styled.div` part. Alternatively, given `styled(button)(style)`, we return the `styled`
13
+ * part.
14
+ *
15
+ * @param nodes
16
+ * @returns The callee of the first `styled` function call found.
17
+ */
18
+ var findNode = function findNode(nodes) {
19
+ var node = nodes.find(function (n) {
20
+ return n.type === 'TaggedTemplateExpression' || n.type === 'CallExpression';
21
+ });
22
+ if (!node) {
23
+ return;
24
+ }
25
+ if (node.type === 'CallExpression') {
26
+ // Eg. const Component = styled.button(style)
27
+ if (node.callee.type === 'MemberExpression') {
28
+ return node.callee;
29
+ }
30
+
31
+ // Eg. const Component = styled(button)(style)
32
+ if (node.callee.type === 'CallExpression' && node.callee.callee.type === 'Identifier') {
33
+ return node.callee.callee;
34
+ }
35
+ }
36
+
37
+ // Eg. const Component = styled.div`${styles}`;
38
+ if (node.type === 'TaggedTemplateExpression' && node.tag.type === 'MemberExpression') {
39
+ return node.tag;
40
+ }
41
+ return;
42
+ };
43
+
44
+ /**
45
+ * Given a rule, return the local name used to import the `styled` API. (for Compiled or styled-components).
46
+ *
47
+ * @param context Rule context.
48
+ * @returns The local name used to import the `styled` API.
49
+ */
50
+ var getStyledImportSpecifierName = function getStyledImportSpecifierName(context, importSources) {
51
+ var _supportedImport$spec;
52
+ var supportedImport = (0, _getFirstSupportedImport.getFirstSupportedImport)(context, importSources);
53
+ return supportedImport === null || supportedImport === void 0 || (_supportedImport$spec = supportedImport.specifiers.find(function (spec) {
54
+ return spec.type === 'ImportSpecifier' && spec.imported.name === 'styled' || spec.type === 'ImportDefaultSpecifier' && spec.local.name === 'styled';
55
+ })) === null || _supportedImport$spec === void 0 ? void 0 : _supportedImport$spec.local.name;
56
+ };
57
+
58
+ /**
59
+ * Returns whether the node is a usage of the `styled` API in the libraries we support.
60
+ *
61
+ * @param nodes Nodes to check.
62
+ * @param context Rule context.
63
+ * @param importSources A list of libraries we support.
64
+ * @returns Whether the node is a usage of the `styled` API.
65
+ */
66
+ var isStyledComponent = exports.isStyledComponent = function isStyledComponent(nodes, context, importSources) {
67
+ var node = findNode(nodes);
68
+ if (!node) {
69
+ return false;
70
+ }
71
+ var styledImportSpecifierName = getStyledImportSpecifierName(context, importSources);
72
+ if (styledImportSpecifierName) {
73
+ if (node.type === 'Identifier') {
74
+ return node.name === styledImportSpecifierName;
75
+ } else {
76
+ return node.object.type === 'Identifier' && node.object.name === styledImportSpecifierName;
77
+ }
78
+ }
79
+ return false;
80
+ };
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createNoExportedRule = void 0;
7
+ var _isSupportedImport = require("../is-supported-import");
8
+ var _checkIfSupportedExport = require("./check-if-supported-export");
9
+ /**
10
+ * Creates a new ESLint rule for banning exporting certain function calls, e.g.
11
+ * `css` and `keyframes`.
12
+ *
13
+ * Copied from the `utils/create-no-exported-rule/` folder in @compiled/eslint-plugin.
14
+ *
15
+ * Requires an importSources option defined on the rule, which is used to define additional
16
+ * packages which should be checked as part of this rule.
17
+ *
18
+ * @param isUsage A function that checks whether the current node matches the desired
19
+ * function call to check.
20
+ * @param messageId The ESLint error message to use for lint violations.
21
+ * @returns An eslint rule.
22
+ */
23
+ var createNoExportedRule = exports.createNoExportedRule = function createNoExportedRule(isUsage, messageId) {
24
+ return function (context) {
25
+ var importSources = (0, _isSupportedImport.getImportSources)(context);
26
+ var _context$getSourceCod = context.getSourceCode(),
27
+ text = _context$getSourceCod.text;
28
+ if (importSources.every(function (importSource) {
29
+ return !text.includes(importSource);
30
+ })) {
31
+ return {};
32
+ }
33
+ return {
34
+ CallExpression: function CallExpression(node) {
35
+ var _context$getScope = context.getScope(),
36
+ references = _context$getScope.references;
37
+ if (!isUsage(node.callee, references, importSources)) {
38
+ return;
39
+ }
40
+ var state = (0, _checkIfSupportedExport.checkIfSupportedExport)(context, node, importSources);
41
+ if (!state.isExport) {
42
+ return;
43
+ }
44
+ context.report({
45
+ messageId: messageId,
46
+ node: state.node
47
+ });
48
+ },
49
+ TaggedTemplateExpression: function TaggedTemplateExpression(node) {
50
+ var _context$getScope2 = context.getScope(),
51
+ references = _context$getScope2.references;
52
+ if (!isUsage(node.tag, references, importSources)) {
53
+ return;
54
+ }
55
+ var state = (0, _checkIfSupportedExport.checkIfSupportedExport)(context, node, importSources);
56
+ if (!state.isExport) {
57
+ return;
58
+ }
59
+ context.report({
60
+ messageId: messageId,
61
+ node: state.node
62
+ });
63
+ }
64
+ };
65
+ };
66
+ };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getFirstSupportedImport = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ /**
9
+ * Get the first import declaration in the file that matches any of the packages
10
+ * in `importSources`.
11
+ *
12
+ * @param context Rule context.
13
+ * @param importSources The packages to check import statements for. If importSources
14
+ * contains more than one package, the first import statement
15
+ * detected in the file that matches any of the packages will be
16
+ * returned.
17
+ * @returns The first import declaration found in the file.
18
+ */
19
+ var getFirstSupportedImport = exports.getFirstSupportedImport = function getFirstSupportedImport(context, importSources) {
20
+ var isSupportedImport = function isSupportedImport(node) {
21
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'ImportDeclaration') && typeof node.source.value === 'string' && importSources.includes(node.source.value);
22
+ };
23
+ var source = context.getSourceCode();
24
+ var supportedImports = source.ast.body.filter(isSupportedImport);
25
+ if (supportedImports.length) {
26
+ return supportedImports[0];
27
+ }
28
+ };