@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.
- package/CHANGELOG.md +42 -0
- package/README.md +4 -0
- package/constellation/index/usage.mdx +402 -6
- package/dist/cjs/presets/all.codegen.js +5 -1
- package/dist/cjs/presets/recommended.codegen.js +5 -1
- package/dist/cjs/rules/consistent-css-prop-usage/index.js +254 -32
- package/dist/cjs/rules/index.codegen.js +9 -1
- package/dist/cjs/rules/no-empty-styled-expression/index.js +75 -0
- package/dist/cjs/rules/no-exported-css/index.js +37 -0
- package/dist/cjs/rules/no-exported-keyframes/index.js +37 -0
- package/dist/cjs/rules/no-invalid-css-map/index.js +102 -0
- package/dist/cjs/rules/no-invalid-css-map/utils.js +193 -0
- package/dist/cjs/rules/utils/create-no-exported-rule/check-if-supported-export.js +158 -0
- package/dist/cjs/rules/utils/create-no-exported-rule/is-styled-component.js +80 -0
- package/dist/cjs/rules/utils/create-no-exported-rule/main.js +66 -0
- package/dist/cjs/rules/utils/get-first-supported-import.js +28 -0
- package/dist/cjs/rules/utils/is-supported-import.js +53 -16
- package/dist/es2019/presets/all.codegen.js +5 -1
- package/dist/es2019/presets/recommended.codegen.js +5 -1
- package/dist/es2019/rules/consistent-css-prop-usage/index.js +251 -33
- package/dist/es2019/rules/index.codegen.js +9 -1
- package/dist/es2019/rules/no-empty-styled-expression/index.js +65 -0
- package/dist/es2019/rules/no-exported-css/index.js +31 -0
- package/dist/es2019/rules/no-exported-keyframes/index.js +31 -0
- package/dist/es2019/rules/no-invalid-css-map/index.js +95 -0
- package/dist/es2019/rules/no-invalid-css-map/utils.js +134 -0
- package/dist/es2019/rules/utils/create-no-exported-rule/check-if-supported-export.js +142 -0
- package/dist/es2019/rules/utils/create-no-exported-rule/is-styled-component.js +70 -0
- package/dist/es2019/rules/utils/create-no-exported-rule/main.js +59 -0
- package/dist/es2019/rules/utils/get-first-supported-import.js +22 -0
- package/dist/es2019/rules/utils/is-supported-import.js +50 -15
- package/dist/esm/presets/all.codegen.js +5 -1
- package/dist/esm/presets/recommended.codegen.js +5 -1
- package/dist/esm/rules/consistent-css-prop-usage/index.js +255 -33
- package/dist/esm/rules/index.codegen.js +9 -1
- package/dist/esm/rules/no-empty-styled-expression/index.js +68 -0
- package/dist/esm/rules/no-exported-css/index.js +31 -0
- package/dist/esm/rules/no-exported-keyframes/index.js +31 -0
- package/dist/esm/rules/no-invalid-css-map/index.js +96 -0
- package/dist/esm/rules/no-invalid-css-map/utils.js +186 -0
- package/dist/esm/rules/utils/create-no-exported-rule/check-if-supported-export.js +151 -0
- package/dist/esm/rules/utils/create-no-exported-rule/is-styled-component.js +74 -0
- package/dist/esm/rules/utils/create-no-exported-rule/main.js +60 -0
- package/dist/esm/rules/utils/get-first-supported-import.js +22 -0
- package/dist/esm/rules/utils/is-supported-import.js +51 -15
- package/dist/types/index.codegen.d.ts +8 -0
- package/dist/types/presets/all.codegen.d.ts +5 -1
- package/dist/types/presets/recommended.codegen.d.ts +5 -1
- package/dist/types/rules/consistent-css-prop-usage/types.d.ts +7 -2
- package/dist/types/rules/index.codegen.d.ts +4 -0
- package/dist/types/rules/no-empty-styled-expression/index.d.ts +3 -0
- package/dist/types/rules/no-exported-css/index.d.ts +3 -0
- package/dist/types/rules/no-exported-keyframes/index.d.ts +3 -0
- package/dist/types/rules/no-invalid-css-map/index.d.ts +3 -0
- package/dist/types/rules/no-invalid-css-map/utils.d.ts +14 -0
- package/dist/types/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
- package/dist/types/rules/utils/create-no-exported-rule/check-if-supported-export.d.ts +15 -0
- package/dist/types/rules/utils/create-no-exported-rule/is-styled-component.d.ts +14 -0
- package/dist/types/rules/utils/create-no-exported-rule/main.d.ts +19 -0
- package/dist/types/rules/utils/create-rule.d.ts +1 -1
- package/dist/types/rules/utils/get-first-supported-import.d.ts +17 -0
- package/dist/types/rules/utils/is-supported-import.d.ts +26 -8
- package/dist/types-ts4.5/index.codegen.d.ts +8 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +5 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +5 -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 +4 -0
- package/dist/types-ts4.5/rules/no-empty-styled-expression/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-exported-css/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-exported-keyframes/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-invalid-css-map/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-invalid-css-map/utils.d.ts +14 -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/utils/create-no-exported-rule/check-if-supported-export.d.ts +15 -0
- package/dist/types-ts4.5/rules/utils/create-no-exported-rule/is-styled-component.d.ts +14 -0
- package/dist/types-ts4.5/rules/utils/create-no-exported-rule/main.d.ts +19 -0
- package/dist/types-ts4.5/rules/utils/create-rule.d.ts +1 -1
- 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 +26 -8
- 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
|
+
};
|