@atlaskit/eslint-plugin-platform 0.12.0 → 0.13.1

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 (91) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +3 -1
  3. package/afm-cc/tsconfig.json +1 -2
  4. package/afm-jira/tsconfig.json +19 -19
  5. package/dist/cjs/index.js +40 -22
  6. package/dist/cjs/rules/compiled/expand-border-shorthand/index.js +100 -0
  7. package/dist/cjs/rules/{no-alias → feature-gating/no-alias}/index.js +1 -1
  8. package/dist/cjs/rules/{prefer-fg → feature-gating/prefer-fg}/index.js +1 -1
  9. package/dist/cjs/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.js +1 -1
  10. package/dist/cjs/rules/{utils.js → feature-gating/utils.js} +1 -1
  11. package/dist/es2019/index.js +41 -20
  12. package/dist/es2019/rules/compiled/expand-border-shorthand/index.js +92 -0
  13. package/dist/es2019/rules/{no-alias → feature-gating/no-alias}/index.js +1 -1
  14. package/dist/es2019/rules/{prefer-fg → feature-gating/prefer-fg}/index.js +1 -1
  15. package/dist/es2019/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.js +1 -1
  16. package/dist/es2019/rules/{utils.js → feature-gating/utils.js} +1 -1
  17. package/dist/esm/index.js +40 -22
  18. package/dist/esm/rules/compiled/expand-border-shorthand/index.js +94 -0
  19. package/dist/esm/rules/{no-alias → feature-gating/no-alias}/index.js +1 -1
  20. package/dist/esm/rules/{prefer-fg → feature-gating/prefer-fg}/index.js +1 -1
  21. package/dist/esm/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.js +1 -1
  22. package/dist/esm/rules/{utils.js → feature-gating/utils.js} +1 -1
  23. package/dist/types/index.d.ts +30 -6
  24. package/dist/types/rules/compiled/expand-border-shorthand/index.d.ts +3 -0
  25. package/dist/types-ts4.5/index.d.ts +30 -6
  26. package/dist/types-ts4.5/rules/compiled/expand-border-shorthand/index.d.ts +3 -0
  27. package/package.json +6 -2
  28. package/src/index.tsx +45 -20
  29. package/src/rules/compiled/README.md +3 -0
  30. package/src/rules/compiled/expand-border-shorthand/README.md +51 -0
  31. package/src/rules/compiled/expand-border-shorthand/__tests__/rule.test.ts +186 -0
  32. package/src/rules/compiled/expand-border-shorthand/index.ts +109 -0
  33. package/src/rules/feature-gating/README.md +8 -0
  34. package/src/rules/{inline-usage → feature-gating/inline-usage}/__tests__/rule.test.tsx +1 -1
  35. package/src/rules/{no-alias → feature-gating/no-alias}/__tests__/rule.test.tsx +1 -1
  36. package/src/rules/{no-alias → feature-gating/no-alias}/index.tsx +1 -1
  37. package/src/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/__tests__/test.tsx +1 -1
  38. package/src/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/__tests__/test.tsx +1 -1
  39. package/src/rules/{no-preconditioning → feature-gating/no-preconditioning}/__tests__/rule.test.tsx +1 -1
  40. package/src/rules/{prefer-fg → feature-gating/prefer-fg}/__tests__/rule.test.tsx +1 -1
  41. package/src/rules/{prefer-fg → feature-gating/prefer-fg}/index.tsx +1 -1
  42. package/src/rules/{static-feature-flags → feature-gating/static-feature-flags}/__tests__/test.tsx +1 -1
  43. package/src/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.tsx +1 -1
  44. package/src/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/__tests__/rule.test.tsx +1 -1
  45. package/src/rules/{utils.tsx → feature-gating/utils.tsx} +1 -1
  46. /package/dist/cjs/rules/{inline-usage → feature-gating/inline-usage}/index.js +0 -0
  47. /package/dist/cjs/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.js +0 -0
  48. /package/dist/cjs/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.js +0 -0
  49. /package/dist/cjs/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.js +0 -0
  50. /package/dist/cjs/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.js +0 -0
  51. /package/dist/es2019/rules/{inline-usage → feature-gating/inline-usage}/index.js +0 -0
  52. /package/dist/es2019/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.js +0 -0
  53. /package/dist/es2019/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.js +0 -0
  54. /package/dist/es2019/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.js +0 -0
  55. /package/dist/es2019/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.js +0 -0
  56. /package/dist/esm/rules/{inline-usage → feature-gating/inline-usage}/index.js +0 -0
  57. /package/dist/esm/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.js +0 -0
  58. /package/dist/esm/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.js +0 -0
  59. /package/dist/esm/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.js +0 -0
  60. /package/dist/esm/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.js +0 -0
  61. /package/dist/types/rules/{inline-usage → feature-gating/inline-usage}/index.d.ts +0 -0
  62. /package/dist/types/rules/{no-alias → feature-gating/no-alias}/index.d.ts +0 -0
  63. /package/dist/types/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.d.ts +0 -0
  64. /package/dist/types/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.d.ts +0 -0
  65. /package/dist/types/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.d.ts +0 -0
  66. /package/dist/types/rules/{prefer-fg → feature-gating/prefer-fg}/index.d.ts +0 -0
  67. /package/dist/types/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.d.ts +0 -0
  68. /package/dist/types/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.d.ts +0 -0
  69. /package/dist/types/rules/{utils.d.ts → feature-gating/utils.d.ts} +0 -0
  70. /package/dist/types-ts4.5/rules/{inline-usage → feature-gating/inline-usage}/index.d.ts +0 -0
  71. /package/dist/types-ts4.5/rules/{no-alias → feature-gating/no-alias}/index.d.ts +0 -0
  72. /package/dist/types-ts4.5/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.d.ts +0 -0
  73. /package/dist/types-ts4.5/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.d.ts +0 -0
  74. /package/dist/types-ts4.5/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.d.ts +0 -0
  75. /package/dist/types-ts4.5/rules/{prefer-fg → feature-gating/prefer-fg}/index.d.ts +0 -0
  76. /package/dist/types-ts4.5/rules/{static-feature-flags → feature-gating/static-feature-flags}/index.d.ts +0 -0
  77. /package/dist/types-ts4.5/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.d.ts +0 -0
  78. /package/dist/types-ts4.5/rules/{utils.d.ts → feature-gating/utils.d.ts} +0 -0
  79. /package/src/rules/{inline-usage → feature-gating/inline-usage}/README.md +0 -0
  80. /package/src/rules/{inline-usage → feature-gating/inline-usage}/index.tsx +0 -0
  81. /package/src/rules/{no-alias → feature-gating/no-alias}/README.md +0 -0
  82. /package/src/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/README.md +0 -0
  83. /package/src/rules/{no-module-level-eval → feature-gating/no-module-level-eval}/index.tsx +0 -0
  84. /package/src/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/README.md +0 -0
  85. /package/src/rules/{no-module-level-eval-nav4 → feature-gating/no-module-level-eval-nav4}/index.tsx +0 -0
  86. /package/src/rules/{no-preconditioning → feature-gating/no-preconditioning}/README.md +0 -0
  87. /package/src/rules/{no-preconditioning → feature-gating/no-preconditioning}/index.tsx +0 -0
  88. /package/src/rules/{prefer-fg → feature-gating/prefer-fg}/README.md +0 -0
  89. /package/src/rules/{static-feature-flags → feature-gating/static-feature-flags}/README.md +0 -0
  90. /package/src/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/README.md +0 -0
  91. /package/src/rules/{use-recommended-utils → feature-gating/use-recommended-utils}/index.tsx +0 -0
@@ -0,0 +1,94 @@
1
+ var EXCLUDED_VALUES = ['0', 'none', 'unset', 'none !important'];
2
+ var findCallExpression = function findCallExpression(node) {
3
+ var parent = node.parent;
4
+ if (!parent) {
5
+ return null;
6
+ }
7
+ if (parent.type === 'CallExpression') {
8
+ return parent;
9
+ }
10
+ return findCallExpression(parent);
11
+ };
12
+ var separateBorderProperties = function separateBorderProperties(borderString, property, context) {
13
+ if (EXCLUDED_VALUES.includes(borderString)) {
14
+ return;
15
+ }
16
+ context.report({
17
+ node: property,
18
+ messageId: 'expandBorderShorthand'
19
+ });
20
+ };
21
+
22
+ // checks if the function that holds the border property is using an import package that this rule is targeting
23
+ var isCompiledAPI = function isCompiledAPI(importDeclaration, callExpression) {
24
+ var functionName;
25
+ if (callExpression.callee.type === 'Identifier') {
26
+ functionName = callExpression.callee.name;
27
+ } else if (callExpression.callee.type === 'MemberExpression') {
28
+ if (callExpression.callee.object.type === 'Identifier') {
29
+ functionName = callExpression.callee.object.name;
30
+ }
31
+ }
32
+ if (!functionName) {
33
+ return;
34
+ }
35
+ return importDeclaration.specifiers.some(function (specifier) {
36
+ return specifier.type === 'ImportSpecifier' && specifier.imported.name === functionName;
37
+ });
38
+ };
39
+ export var expandBorderShorthand = {
40
+ meta: {
41
+ docs: {
42
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/compiled/expand-border-shorthand'
43
+ },
44
+ messages: {
45
+ expandBorderShorthand: 'Use borderColor, borderStyle, and borderWidth instead of border shorthand'
46
+ },
47
+ type: 'problem'
48
+ },
49
+ create: function create(context) {
50
+ var importDeclaration;
51
+ return {
52
+ 'ImportDeclaration[source.value="@compiled/react"], ImportDeclaration[source.value="@atlaskit/css"]': function ImportDeclarationSourceValueCompiledReactImportDeclarationSourceValueAtlaskitCss(node) {
53
+ importDeclaration = node;
54
+ },
55
+ 'Property[key.name="border"]': function PropertyKeyNameBorder(node) {
56
+ var callExpression = findCallExpression(node);
57
+ if (!callExpression) {
58
+ return;
59
+ }
60
+ if (importDeclaration) {
61
+ if (isCompiledAPI(importDeclaration, callExpression)) {
62
+ if (node.value.type === 'Literal' && node.value.value !== null) {
63
+ if (typeof node.value.value === 'string') {
64
+ var borderString = node.value.value;
65
+ separateBorderProperties(borderString, node, context);
66
+ } else if (node.value.raw) {
67
+ var _borderString = node.value.raw;
68
+ separateBorderProperties(_borderString, node, context);
69
+ }
70
+ } else if (node.value.type === 'TemplateLiteral') {
71
+ if (node.value.quasis.length > 1 || node.value.expressions.length > 0) {
72
+ context.report({
73
+ node: node,
74
+ messageId: 'expandBorderShorthand'
75
+ });
76
+ return;
77
+ }
78
+ if (node.value.quasis.length === 1 && node.value.quasis[0].value.cooked) {
79
+ var borderQuasis = node.value.quasis[0].value.cooked;
80
+ separateBorderProperties(borderQuasis, node, context);
81
+ }
82
+ } else if (node.value.type === 'CallExpression') {
83
+ context.report({
84
+ node: node,
85
+ messageId: 'expandBorderShorthand'
86
+ });
87
+ }
88
+ }
89
+ }
90
+ }
91
+ };
92
+ }
93
+ };
94
+ export default expandBorderShorthand;
@@ -1,5 +1,5 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { FEATURE_API_IMPORT_SOURCES, FEATURE_MOCKS_IMPORT_SOURCES, FEATURE_UTILS_IMPORT_SOURCES } from '../constants';
2
+ import { FEATURE_API_IMPORT_SOURCES, FEATURE_MOCKS_IMPORT_SOURCES, FEATURE_UTILS_IMPORT_SOURCES } from '../../constants';
3
3
  import { isIdentifierImportedFrom } from '../utils';
4
4
  var IMPORT_SOURCES = new Set([].concat(_toConsumableArray(FEATURE_API_IMPORT_SOURCES), _toConsumableArray(FEATURE_MOCKS_IMPORT_SOURCES), _toConsumableArray(FEATURE_UTILS_IMPORT_SOURCES)));
5
5
  var rule = {
@@ -3,7 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  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; }
5
5
  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) { _defineProperty(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; }
6
- import { FEATURE_API_IMPORT_SOURCES } from '../constants';
6
+ import { FEATURE_API_IMPORT_SOURCES } from '../../constants';
7
7
  var validateUsage = function validateUsage(node, utilName, context, changeMap) {
8
8
  var _context$getScope$ref;
9
9
  var resolved = (_context$getScope$ref = context.getScope().references.find(function (ref) {
@@ -1,5 +1,5 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { FEATURE_API_IMPORT_SOURCES } from '../constants';
2
+ import { FEATURE_API_IMPORT_SOURCES } from '../../constants';
3
3
  import { getDef, isIdentifierImportedFrom } from '../utils';
4
4
  var IMPORT_SOURCES = new Set([].concat(_toConsumableArray(FEATURE_API_IMPORT_SOURCES), ['@atlassian/jira-feature-flagging-utils', '@atlassian/jira-feature-gate-component', '@atlassian/jira-feature-gates-test-mocks', '@atlassian/jira-feature-gates-storybook-mocks']));
5
5
 
@@ -1,7 +1,7 @@
1
1
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
2
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
3
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
- import { FEATURE_API_IMPORT_SOURCES } from './constants';
4
+ import { FEATURE_API_IMPORT_SOURCES } from '../constants';
5
5
  export function isIdentifierImportedFrom(identifierName, sources, context) {
6
6
  if (sources.size > 0) {
7
7
  var _context$getScope$ref, _context$getScope$ref2;
@@ -8,6 +8,7 @@ export declare const rules: {
8
8
  'ensure-critical-dependency-resolutions': import("eslint").Rule.RuleModule;
9
9
  'ensure-valid-platform-yarn-protocol-usage': import("eslint").Rule.RuleModule;
10
10
  'ensure-valid-bin-values': import("eslint").Rule.RuleModule;
11
+ 'expand-border-shorthand': import("eslint").Rule.RuleModule;
11
12
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
12
13
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
13
14
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -28,6 +29,12 @@ export declare const configs: {
28
29
  recommended: {
29
30
  plugins: string[];
30
31
  rules: {
32
+ '@atlaskit/platform/no-module-level-eval': string;
33
+ '@atlaskit/platform/static-feature-flags': string;
34
+ '@atlaskit/platform/no-preconditioning': string;
35
+ '@atlaskit/platform/inline-usage': string;
36
+ '@atlaskit/platform/prefer-fg': string;
37
+ '@atlaskit/platform/no-alias': string;
31
38
  '@atlaskit/platform/ensure-feature-flag-registration': string;
32
39
  '@atlaskit/platform/ensure-feature-flag-prefix': (string | {
33
40
  allowedPrefixes: string[];
@@ -37,13 +44,30 @@ export declare const configs: {
37
44
  '@atlaskit/platform/no-invalid-feature-flag-usage': string;
38
45
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
39
46
  '@atlaskit/platform/ensure-atlassian-team': string;
40
- '@atlaskit/platform/no-module-level-eval': string;
41
47
  '@atlaskit/platform/no-module-level-eval-nav4': string;
42
- '@atlaskit/platform/static-feature-flags': string;
43
- '@atlaskit/platform/no-preconditioning': string;
44
- '@atlaskit/platform/inline-usage': string;
45
- '@atlaskit/platform/prefer-fg': string;
46
- '@atlaskit/platform/no-alias': string;
48
+ '@atlaskit/platform/expand-border-shorthand': string;
49
+ '@compiled/jsx-pragma': (string | {
50
+ importSources: string[];
51
+ onlyRunIfImportingCompiled: boolean;
52
+ runtime: string;
53
+ })[];
54
+ };
55
+ };
56
+ jira: {
57
+ plugins: string[];
58
+ rules: {
59
+ '@atlaskit/platform/ensure-test-runner-arguments': string;
60
+ '@atlaskit/platform/ensure-test-runner-nested-count': string;
61
+ '@atlaskit/platform/no-invalid-feature-flag-usage': string;
62
+ '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
63
+ '@atlaskit/platform/ensure-atlassian-team': string;
64
+ '@atlaskit/platform/no-module-level-eval-nav4': string;
65
+ '@atlaskit/platform/expand-border-shorthand': string;
66
+ '@compiled/jsx-pragma': (string | {
67
+ importSources: string[];
68
+ onlyRunIfImportingCompiled: boolean;
69
+ runtime: string;
70
+ })[];
47
71
  };
48
72
  };
49
73
  };
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const expandBorderShorthand: Rule.RuleModule;
3
+ export default expandBorderShorthand;
@@ -8,6 +8,7 @@ export declare const rules: {
8
8
  'ensure-critical-dependency-resolutions': import("eslint").Rule.RuleModule;
9
9
  'ensure-valid-platform-yarn-protocol-usage': import("eslint").Rule.RuleModule;
10
10
  'ensure-valid-bin-values': import("eslint").Rule.RuleModule;
11
+ 'expand-border-shorthand': import("eslint").Rule.RuleModule;
11
12
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
12
13
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
13
14
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -28,6 +29,12 @@ export declare const configs: {
28
29
  recommended: {
29
30
  plugins: string[];
30
31
  rules: {
32
+ '@atlaskit/platform/no-module-level-eval': string;
33
+ '@atlaskit/platform/static-feature-flags': string;
34
+ '@atlaskit/platform/no-preconditioning': string;
35
+ '@atlaskit/platform/inline-usage': string;
36
+ '@atlaskit/platform/prefer-fg': string;
37
+ '@atlaskit/platform/no-alias': string;
31
38
  '@atlaskit/platform/ensure-feature-flag-registration': string;
32
39
  '@atlaskit/platform/ensure-feature-flag-prefix': (string | {
33
40
  allowedPrefixes: string[];
@@ -37,13 +44,30 @@ export declare const configs: {
37
44
  '@atlaskit/platform/no-invalid-feature-flag-usage': string;
38
45
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
39
46
  '@atlaskit/platform/ensure-atlassian-team': string;
40
- '@atlaskit/platform/no-module-level-eval': string;
41
47
  '@atlaskit/platform/no-module-level-eval-nav4': string;
42
- '@atlaskit/platform/static-feature-flags': string;
43
- '@atlaskit/platform/no-preconditioning': string;
44
- '@atlaskit/platform/inline-usage': string;
45
- '@atlaskit/platform/prefer-fg': string;
46
- '@atlaskit/platform/no-alias': string;
48
+ '@atlaskit/platform/expand-border-shorthand': string;
49
+ '@compiled/jsx-pragma': (string | {
50
+ importSources: string[];
51
+ onlyRunIfImportingCompiled: boolean;
52
+ runtime: string;
53
+ })[];
54
+ };
55
+ };
56
+ jira: {
57
+ plugins: string[];
58
+ rules: {
59
+ '@atlaskit/platform/ensure-test-runner-arguments': string;
60
+ '@atlaskit/platform/ensure-test-runner-nested-count': string;
61
+ '@atlaskit/platform/no-invalid-feature-flag-usage': string;
62
+ '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
63
+ '@atlaskit/platform/ensure-atlassian-team': string;
64
+ '@atlaskit/platform/no-module-level-eval-nav4': string;
65
+ '@atlaskit/platform/expand-border-shorthand': string;
66
+ '@compiled/jsx-pragma': (string | {
67
+ importSources: string[];
68
+ onlyRunIfImportingCompiled: boolean;
69
+ runtime: string;
70
+ })[];
47
71
  };
48
72
  };
49
73
  };
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const expandBorderShorthand: Rule.RuleModule;
3
+ export default expandBorderShorthand;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-platform",
3
3
  "description": "The essential plugin for use with Atlassian frontend platform tools",
4
- "version": "0.12.0",
4
+ "version": "0.13.1",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
7
- "team": "UIP Dev Infra",
7
+ "team": "Build Infra",
8
8
  "toolingLabels": [
9
9
  "linting"
10
10
  ]
@@ -38,8 +38,12 @@
38
38
  },
39
39
  "devDependencies": {
40
40
  "@atlassian/ts-loader": "*",
41
+ "@compiled/eslint-plugin": "^0.17.0",
41
42
  "@types/eslint": "^8.56.6",
42
43
  "eslint": "^8.57.0",
43
44
  "outdent": "^0.5.0"
45
+ },
46
+ "peerDependencies": {
47
+ "@compiled/eslint-plugin": "^0.17.0"
44
48
  }
45
49
  }
package/src/index.tsx CHANGED
@@ -11,18 +11,19 @@ import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
11
11
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
12
12
  import ensureValidPlatformYarnProtocolUsage from './rules/ensure-valid-platform-yarn-protocol-usage';
13
13
  import ensureValidBinValues from './rules/ensure-valid-bin-values';
14
+ import expandBorderShorthand from './rules/compiled/expand-border-shorthand';
14
15
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
15
16
  import ensurePublishValid from './rules/ensure-publish-valid';
16
17
  import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
17
- import noModuleLevelEval from './rules/no-module-level-eval';
18
- import noModuleLevelEvalNav4 from './rules/no-module-level-eval-nav4';
19
- import staticFeatureFlags from './rules/static-feature-flags';
20
- import noPreconditioning from './rules/no-preconditioning';
21
- import inlineUsage from './rules/inline-usage';
22
- import preferFG from './rules/prefer-fg';
23
- import noAlias from './rules/no-alias';
18
+ import noModuleLevelEval from './rules/feature-gating/no-module-level-eval';
19
+ import noModuleLevelEvalNav4 from './rules/feature-gating/no-module-level-eval-nav4';
20
+ import staticFeatureFlags from './rules/feature-gating/static-feature-flags';
21
+ import noPreconditioning from './rules/feature-gating/no-preconditioning';
22
+ import inlineUsage from './rules/feature-gating/inline-usage';
23
+ import preferFG from './rules/feature-gating/prefer-fg';
24
+ import noAlias from './rules/feature-gating/no-alias';
24
25
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
25
- import useRecommendedUtils from './rules/use-recommended-utils';
26
+ import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
26
27
 
27
28
  export const rules = {
28
29
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
@@ -33,6 +34,7 @@ export const rules = {
33
34
  'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
34
35
  'ensure-valid-platform-yarn-protocol-usage': ensureValidPlatformYarnProtocolUsage,
35
36
  'ensure-valid-bin-values': ensureValidBinValues,
37
+ 'expand-border-shorthand': expandBorderShorthand,
36
38
  'no-duplicate-dependencies': noDuplicateDependencies,
37
39
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
38
40
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -50,27 +52,50 @@ export const rules = {
50
52
  'use-recommended-utils': useRecommendedUtils,
51
53
  };
52
54
 
55
+ const commonConfig = {
56
+ '@atlaskit/platform/ensure-test-runner-arguments': 'error',
57
+ '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
58
+ '@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
59
+ '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
60
+ '@atlaskit/platform/ensure-atlassian-team': 'error',
61
+ '@atlaskit/platform/no-module-level-eval-nav4': 'error',
62
+ // Compiled: rules that are not included via `@compiled/recommended
63
+ '@atlaskit/platform/expand-border-shorthand': 'warn',
64
+ '@compiled/jsx-pragma': [
65
+ 'error',
66
+ {
67
+ importSources: ['@atlaskit/css'],
68
+ onlyRunIfImportingCompiled: true,
69
+ runtime: 'classic',
70
+ },
71
+ ],
72
+ };
73
+
53
74
  export const configs = {
54
75
  recommended: {
55
- plugins: ['@atlaskit/platform'],
76
+ plugins: ['@atlaskit/platform', '@compiled'],
56
77
  rules: {
57
- '@atlaskit/platform/ensure-feature-flag-registration': 'error',
58
- '@atlaskit/platform/ensure-feature-flag-prefix': [
59
- 'warn',
60
- { allowedPrefixes: ['platform.', 'platform_'] },
61
- ],
62
- '@atlaskit/platform/ensure-test-runner-arguments': 'error',
63
- '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
64
- '@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
65
- '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
66
- '@atlaskit/platform/ensure-atlassian-team': 'error',
78
+ ...commonConfig,
79
+ // See platform/packages/platform/eslint-plugin/src/rules/feature-gating/README.md
80
+ // These rules are specific to `platform` and seem a WIP; jira and confluence currently have their own rules
67
81
  '@atlaskit/platform/no-module-level-eval': 'error',
68
- '@atlaskit/platform/no-module-level-eval-nav4': 'error',
69
82
  '@atlaskit/platform/static-feature-flags': 'error',
70
83
  '@atlaskit/platform/no-preconditioning': 'error',
71
84
  '@atlaskit/platform/inline-usage': 'error',
72
85
  '@atlaskit/platform/prefer-fg': 'error',
73
86
  '@atlaskit/platform/no-alias': 'error',
87
+ // end: feature-gating rules
88
+ '@atlaskit/platform/ensure-feature-flag-registration': 'error',
89
+ '@atlaskit/platform/ensure-feature-flag-prefix': [
90
+ 'warn',
91
+ { allowedPrefixes: ['platform.', 'platform_'] },
92
+ ],
93
+ },
94
+ },
95
+ jira: {
96
+ plugins: ['@atlaskit/platform', '@compiled'],
97
+ rules: {
98
+ ...commonConfig,
74
99
  },
75
100
  },
76
101
  };
@@ -0,0 +1,3 @@
1
+ # Atlassian platform ESLint Plugin > Compiled rules
2
+
3
+ TODO
@@ -0,0 +1,51 @@
1
+ # `shorthand-property-sorting`
2
+
3
+ This ESLint rule enforces the expansion of CSS `border` shorthand property, into it's longhand
4
+ equivalents `borderStyle`, `borderWidth`, `borderColor`, for packages that originates from
5
+ `@compiled/react`, and `@atlaskit/css`.
6
+
7
+ ## Rule details
8
+
9
+ 👎 Examples of **incorrect** code for this rule:
10
+
11
+ ```js
12
+ const styles = css({
13
+ border: '1px solid black',
14
+ });
15
+
16
+ const styles = css({
17
+ border: '1px solid',
18
+ });
19
+
20
+ const styles = css({
21
+ border: '1px',
22
+ });
23
+ ```
24
+
25
+ 👍 Examples of **correct** code for this rule:
26
+
27
+ ```js
28
+ const styles = css({
29
+ borderWidth: '1px',
30
+ borderStyle: 'solid',
31
+ borderColor: 'black',
32
+ });
33
+ ```
34
+
35
+ ```js
36
+ const styles = css({
37
+ border: '0', // exempted from our ESLint rule
38
+ });
39
+
40
+ const styles = css({
41
+ border: 'none', // exempted from our ESLint rule
42
+ });
43
+
44
+ const styles = css({
45
+ border: 'unset', // exempted from our ESLint rule
46
+ });
47
+
48
+ const styles = css({
49
+ border: 'none !important', // exempted from our ESLint rule
50
+ });
51
+ ```
@@ -0,0 +1,186 @@
1
+ import { outdent } from 'outdent';
2
+
3
+ import { tester } from '../../../../__tests__/utils/_tester';
4
+ import { expandBorderShorthand } from '../index';
5
+
6
+ const valid_packages_calls_and_imports = [
7
+ ['css', 'css', '@atlaskit/css'],
8
+ ['css', 'css', '@compiled/react'],
9
+ ['styled', 'styled.div', '@compiled/react'],
10
+ ['cssMap', 'cssMap', '@atlaskit/css'],
11
+ ['cssMap', 'cssMap', '@compiled/react'],
12
+ ];
13
+
14
+ const invalid_packages_calls_and_imports = [
15
+ ['css', '@atlaskit/primitives'],
16
+ ['css', '@emotion'],
17
+ ['css', 'styled-components'],
18
+ ];
19
+
20
+ tester.run('expand-border-shorthand', expandBorderShorthand, {
21
+ valid: [
22
+ ...invalid_packages_calls_and_imports.map(([pkg, imp]) => ({
23
+ name: `incorrect packages (${pkg}, ${imp})`,
24
+ code: outdent`
25
+ import {${pkg}} from '${imp}';
26
+
27
+ const styles = ${pkg}({
28
+ border: '1px solid red',
29
+ });
30
+ `,
31
+ })),
32
+ {
33
+ name: 'references correct package',
34
+ code: outdent`
35
+ import {css} from '@compiled/react';
36
+
37
+ const styles = xcss({
38
+ border: '1px solid red',
39
+ });
40
+ `,
41
+ },
42
+ {
43
+ name: 'excluded values',
44
+ code: outdent`
45
+ import {css} from '@compiled/react';
46
+
47
+ const styles = css({
48
+ border: 'none',
49
+ });
50
+ const styles2 = css({
51
+ border: '0',
52
+ });
53
+ const styles3 = css({
54
+ border: 'unset',
55
+ });
56
+ const styles4 = css({
57
+ border: 'none !important',
58
+ });
59
+ const styles5 = css({
60
+ border: \`none\`,
61
+ });
62
+ const styles6 = css({
63
+ border: \`0\`,
64
+ });
65
+ const styles7 = css({
66
+ border: \`unset\`,
67
+ });
68
+ const styles8 = css({
69
+ border: \`none !important\`,
70
+ });
71
+ const styles9 = css({
72
+ border: 0,
73
+ });
74
+ `,
75
+ },
76
+ {
77
+ name: 'not using border shorthand',
78
+ code: outdent`
79
+ import {css} from '@compiled/react';
80
+
81
+ const styles = css({
82
+ borderTop: '2px solid green',
83
+ borderRight: '3px dashed orange',
84
+ borderBottom: '4px double purple',
85
+ borderLeft: '5px groove teal',
86
+ });
87
+ const styles2 = css({
88
+ borderWidth: '1px',
89
+ borderStyle: 'solid',
90
+ borderColor: 'black',
91
+ });
92
+ `,
93
+ },
94
+ ],
95
+ invalid: [
96
+ ...valid_packages_calls_and_imports.map(([pkg, call, imp]) => ({
97
+ name: `simple case (${call}, ${imp})`,
98
+ code: outdent`
99
+ import {${pkg}} from '${imp}';
100
+
101
+ const styles = ${call}({
102
+ border: '1px solid red',
103
+ });
104
+ const styles2 = ${call}({
105
+ border: '1px solid',
106
+ });
107
+ const styles3 = ${call}({
108
+ border: '1px',
109
+ });
110
+ `,
111
+ errors: Array.from(Array(3), () => ({ messageId: 'expandBorderShorthand' })),
112
+ })),
113
+ {
114
+ name: 'nested ObjectExpression',
115
+ code: outdent`
116
+ import {css} from '@compiled/react';
117
+ const styles = {
118
+ inverse: css({
119
+ border: '1px solid red',
120
+ }),
121
+ };
122
+ `,
123
+ errors: [{ messageId: 'expandBorderShorthand' }],
124
+ },
125
+ {
126
+ name: 'pseudo selector',
127
+ code: outdent`
128
+ import {css} from '@compiled/react';
129
+ const styles = css({
130
+ '&:hover': {
131
+ border: '1px solid red',
132
+ '&:hover': {
133
+ border: '1px solid red',
134
+ },
135
+ },
136
+ border: '1px solid red',
137
+ })
138
+ `,
139
+ errors: Array.from(Array(3), () => ({ messageId: 'expandBorderShorthand' })),
140
+ },
141
+ {
142
+ name: 'template string',
143
+ code: outdent`
144
+ import {css} from '@compiled/react';
145
+
146
+ const styles = css({
147
+ border: \`1px solid red\`,
148
+ })
149
+
150
+ const styles2 = css({
151
+ border: \`1px solid \${token('red')}\`,
152
+ })
153
+
154
+ const styles3 = css({
155
+ border: \`1px \${solid} red\`,
156
+ })
157
+
158
+ const styles4 = css({
159
+ border: \`1px red\`,
160
+ })
161
+
162
+ const styles5 = css({
163
+ border: \`1px\`,
164
+ })
165
+
166
+ const styles6 = css({
167
+ border: \` \${token('red')}\`,
168
+ })
169
+ `,
170
+ errors: Array.from(Array(6), () => ({ messageId: 'expandBorderShorthand' })),
171
+ },
172
+ {
173
+ name: 'tokens',
174
+ code: outdent`
175
+ import {css} from '@compiled/react';
176
+ const styles = css({
177
+ border: token('color.border'),
178
+ })
179
+ const styles2 = css({
180
+ border: token('space.025', '2px'),
181
+ })
182
+ `,
183
+ errors: Array.from(Array(2), () => ({ messageId: 'expandBorderShorthand' })),
184
+ },
185
+ ],
186
+ });