@atlaskit/eslint-plugin-platform 0.2.2 → 0.2.4
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 +12 -0
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/rules/ensure-atlassian-team/index.js +50 -0
- package/dist/cjs/rules/no-invalid-feature-flag-usage/index.js +5 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/index.js +4 -1
- package/dist/es2019/rules/ensure-atlassian-team/index.js +39 -0
- package/dist/es2019/rules/no-invalid-feature-flag-usage/index.js +5 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/index.js +4 -1
- package/dist/esm/rules/ensure-atlassian-team/index.js +43 -0
- package/dist/esm/rules/no-invalid-feature-flag-usage/index.js +5 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/rules/ensure-atlassian-team/index.d.ts +3 -0
- package/dist/types-ts4.5/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/ensure-atlassian-team/index.d.ts +3 -0
- package/package.json +1 -1
- package/report.api.md +2 -0
- package/src/index.tsx +3 -0
- package/src/rules/ensure-atlassian-team/__tests__/unit/rule.test.ts +24 -0
- package/src/rules/ensure-atlassian-team/index.ts +63 -0
- package/src/rules/no-invalid-feature-flag-usage/__tests__/unit/rule.test.tsx +12 -1
- package/src/rules/no-invalid-feature-flag-usage/index.tsx +11 -9
- package/tmp/api-report-tmp.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-platform
|
|
2
2
|
|
|
3
|
+
## 0.2.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`eb64cbdd681`](https://bitbucket.org/atlassian/atlassian-frontend/commits/eb64cbdd681) - Add a new rule to verify that the atlassian team is defined if the relevant section exists in the package.json
|
|
8
|
+
|
|
9
|
+
## 0.2.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`0bf64fb3dd0`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0bf64fb3dd0) - Update to support unary expressions like negation
|
|
14
|
+
|
|
3
15
|
## 0.2.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/cjs/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var _ensureFeatureFlagRegistration = _interopRequireDefault(require("./rules/ens
|
|
|
9
9
|
var _noPrePostInstalls = _interopRequireDefault(require("./rules/no-pre-post-installs"));
|
|
10
10
|
var _ensureTestRunnerArguments = _interopRequireDefault(require("./rules/ensure-test-runner-arguments"));
|
|
11
11
|
var _ensureTestRunnerNestedCount = _interopRequireDefault(require("./rules/ensure-test-runner-nested-count"));
|
|
12
|
+
var _ensureAtlassianTeam = _interopRequireDefault(require("./rules/ensure-atlassian-team"));
|
|
12
13
|
var _noInvalidFeatureFlagUsage = _interopRequireDefault(require("./rules/no-invalid-feature-flag-usage"));
|
|
13
14
|
var _ensureFeatureFlagPrefix = _interopRequireDefault(require("./rules/ensure-feature-flag-prefix"));
|
|
14
15
|
var _noInvalidStorybookDecoratorUsage = _interopRequireDefault(require("./rules/no-invalid-storybook-decorator-usage"));
|
|
@@ -17,6 +18,7 @@ var rules = {
|
|
|
17
18
|
'ensure-feature-flag-prefix': _ensureFeatureFlagPrefix.default,
|
|
18
19
|
'ensure-test-runner-arguments': _ensureTestRunnerArguments.default,
|
|
19
20
|
'ensure-test-runner-nested-count': _ensureTestRunnerNestedCount.default,
|
|
21
|
+
'ensure-atlassian-team': _ensureAtlassianTeam.default,
|
|
20
22
|
'no-invalid-feature-flag-usage': _noInvalidFeatureFlagUsage.default,
|
|
21
23
|
'no-pre-post-install-scripts': _noPrePostInstalls.default,
|
|
22
24
|
'no-invalid-storybook-decorator-usage': _noInvalidStorybookDecoratorUsage.default
|
|
@@ -33,7 +35,8 @@ var configs = {
|
|
|
33
35
|
'@atlaskit/platform/ensure-test-runner-arguments': 'error',
|
|
34
36
|
'@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
|
|
35
37
|
'@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
|
|
36
|
-
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error'
|
|
38
|
+
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
|
|
39
|
+
'@atlaskit/platform/ensure-atlassian-team': 'error'
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var rule = {
|
|
8
|
+
meta: {
|
|
9
|
+
type: 'problem',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'This rule ensures that the internal packages have a responsible team attached.',
|
|
12
|
+
recommended: true
|
|
13
|
+
},
|
|
14
|
+
hasSuggestions: false,
|
|
15
|
+
messages: {
|
|
16
|
+
atlassianTeamRequired: 'The atlassian.team property is required'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
create: function create(context) {
|
|
20
|
+
return {
|
|
21
|
+
ObjectExpression: function ObjectExpression(node) {
|
|
22
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
var atlassianProp = node.properties.find(function (p) {
|
|
26
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'atlassian';
|
|
27
|
+
});
|
|
28
|
+
if (!atlassianProp) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (atlassianProp.type !== 'Property' || atlassianProp.value.type !== 'ObjectExpression') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
var teamProp = atlassianProp.value.properties.find(function (p) {
|
|
35
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'team';
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// this just checks for existence, we can potentially cross-reference it with teams.json to make sure its valid in the future.
|
|
39
|
+
if (!teamProp) {
|
|
40
|
+
return context.report({
|
|
41
|
+
node: node,
|
|
42
|
+
messageId: 'atlassianTeamRequired'
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var _default = rule;
|
|
50
|
+
exports.default = _default;
|
|
@@ -11,6 +11,8 @@ var __isOnlyOneFlagCheckInExpression = function __isOnlyOneFlagCheckInExpression
|
|
|
11
11
|
switch (root.type) {
|
|
12
12
|
case 'IfStatement':
|
|
13
13
|
return __isOnlyOneFlagCheckInExpression(root.test, ignoredNode);
|
|
14
|
+
case 'UnaryExpression':
|
|
15
|
+
return __isOnlyOneFlagCheckInExpression(root.argument, ignoredNode);
|
|
14
16
|
case 'CallExpression':
|
|
15
17
|
if (root === ignoredNode) {
|
|
16
18
|
return true;
|
|
@@ -30,7 +32,8 @@ var __isOnlyOneFlagCheckInExpression = function __isOnlyOneFlagCheckInExpression
|
|
|
30
32
|
var isOnlyOneFlagCheckInExpression = function isOnlyOneFlagCheckInExpression(node) {
|
|
31
33
|
var root = node.parent;
|
|
32
34
|
// find the root node of the expression
|
|
33
|
-
|
|
35
|
+
// NOTE: This is not an exhaustive check for all ESTree.Expression types but is good enough
|
|
36
|
+
while (root.type.endsWith('Expression')) {
|
|
34
37
|
root = root.parent;
|
|
35
38
|
}
|
|
36
39
|
return __isOnlyOneFlagCheckInExpression(root, node);
|
|
@@ -64,6 +67,7 @@ var rule = {
|
|
|
64
67
|
case 'IfStatement':
|
|
65
68
|
case 'ConditionalExpression':
|
|
66
69
|
break;
|
|
70
|
+
case 'UnaryExpression':
|
|
67
71
|
case 'LogicalExpression':
|
|
68
72
|
if (!isOnlyOneFlagCheckInExpression(node)) {
|
|
69
73
|
context.report({
|
package/dist/cjs/version.json
CHANGED
package/dist/es2019/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import ensureFeatureFlagRegistration from './rules/ensure-feature-flag-registrat
|
|
|
2
2
|
import noPreAndPostInstallScripts from './rules/no-pre-post-installs';
|
|
3
3
|
import ensureTestRunnerArguments from './rules/ensure-test-runner-arguments';
|
|
4
4
|
import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count';
|
|
5
|
+
import ensureAtlassianTeam from './rules/ensure-atlassian-team';
|
|
5
6
|
import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
|
|
6
7
|
import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
|
|
7
8
|
import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
|
|
@@ -10,6 +11,7 @@ export const rules = {
|
|
|
10
11
|
'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
|
|
11
12
|
'ensure-test-runner-arguments': ensureTestRunnerArguments,
|
|
12
13
|
'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
|
|
14
|
+
'ensure-atlassian-team': ensureAtlassianTeam,
|
|
13
15
|
'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
|
|
14
16
|
'no-pre-post-install-scripts': noPreAndPostInstallScripts,
|
|
15
17
|
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage
|
|
@@ -25,7 +27,8 @@ export const configs = {
|
|
|
25
27
|
'@atlaskit/platform/ensure-test-runner-arguments': 'error',
|
|
26
28
|
'@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
|
|
27
29
|
'@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
|
|
28
|
-
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error'
|
|
30
|
+
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
|
|
31
|
+
'@atlaskit/platform/ensure-atlassian-team': 'error'
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const rule = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: 'problem',
|
|
4
|
+
docs: {
|
|
5
|
+
description: 'This rule ensures that the internal packages have a responsible team attached.',
|
|
6
|
+
recommended: true
|
|
7
|
+
},
|
|
8
|
+
hasSuggestions: false,
|
|
9
|
+
messages: {
|
|
10
|
+
atlassianTeamRequired: 'The atlassian.team property is required'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create(context) {
|
|
14
|
+
return {
|
|
15
|
+
ObjectExpression: node => {
|
|
16
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const atlassianProp = node.properties.find(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'atlassian');
|
|
20
|
+
if (!atlassianProp) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (atlassianProp.type !== 'Property' || atlassianProp.value.type !== 'ObjectExpression') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const teamProp = atlassianProp.value.properties.find(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'team');
|
|
27
|
+
|
|
28
|
+
// this just checks for existence, we can potentially cross-reference it with teams.json to make sure its valid in the future.
|
|
29
|
+
if (!teamProp) {
|
|
30
|
+
return context.report({
|
|
31
|
+
node,
|
|
32
|
+
messageId: 'atlassianTeamRequired'
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export default rule;
|
|
@@ -3,6 +3,8 @@ const __isOnlyOneFlagCheckInExpression = (root, ignoredNode) => {
|
|
|
3
3
|
switch (root.type) {
|
|
4
4
|
case 'IfStatement':
|
|
5
5
|
return __isOnlyOneFlagCheckInExpression(root.test, ignoredNode);
|
|
6
|
+
case 'UnaryExpression':
|
|
7
|
+
return __isOnlyOneFlagCheckInExpression(root.argument, ignoredNode);
|
|
6
8
|
case 'CallExpression':
|
|
7
9
|
if (root === ignoredNode) {
|
|
8
10
|
return true;
|
|
@@ -22,7 +24,8 @@ const __isOnlyOneFlagCheckInExpression = (root, ignoredNode) => {
|
|
|
22
24
|
const isOnlyOneFlagCheckInExpression = node => {
|
|
23
25
|
let root = node.parent;
|
|
24
26
|
// find the root node of the expression
|
|
25
|
-
|
|
27
|
+
// NOTE: This is not an exhaustive check for all ESTree.Expression types but is good enough
|
|
28
|
+
while (root.type.endsWith('Expression')) {
|
|
26
29
|
root = root.parent;
|
|
27
30
|
}
|
|
28
31
|
return __isOnlyOneFlagCheckInExpression(root, node);
|
|
@@ -57,6 +60,7 @@ const rule = {
|
|
|
57
60
|
case 'IfStatement':
|
|
58
61
|
case 'ConditionalExpression':
|
|
59
62
|
break;
|
|
63
|
+
case 'UnaryExpression':
|
|
60
64
|
case 'LogicalExpression':
|
|
61
65
|
if (!isOnlyOneFlagCheckInExpression(node)) {
|
|
62
66
|
context.report({
|
package/dist/es2019/version.json
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import ensureFeatureFlagRegistration from './rules/ensure-feature-flag-registrat
|
|
|
2
2
|
import noPreAndPostInstallScripts from './rules/no-pre-post-installs';
|
|
3
3
|
import ensureTestRunnerArguments from './rules/ensure-test-runner-arguments';
|
|
4
4
|
import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count';
|
|
5
|
+
import ensureAtlassianTeam from './rules/ensure-atlassian-team';
|
|
5
6
|
import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
|
|
6
7
|
import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
|
|
7
8
|
import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
|
|
@@ -10,6 +11,7 @@ export var rules = {
|
|
|
10
11
|
'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
|
|
11
12
|
'ensure-test-runner-arguments': ensureTestRunnerArguments,
|
|
12
13
|
'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
|
|
14
|
+
'ensure-atlassian-team': ensureAtlassianTeam,
|
|
13
15
|
'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
|
|
14
16
|
'no-pre-post-install-scripts': noPreAndPostInstallScripts,
|
|
15
17
|
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage
|
|
@@ -25,7 +27,8 @@ export var configs = {
|
|
|
25
27
|
'@atlaskit/platform/ensure-test-runner-arguments': 'error',
|
|
26
28
|
'@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
|
|
27
29
|
'@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
|
|
28
|
-
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error'
|
|
30
|
+
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
|
|
31
|
+
'@atlaskit/platform/ensure-atlassian-team': 'error'
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var rule = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: 'problem',
|
|
4
|
+
docs: {
|
|
5
|
+
description: 'This rule ensures that the internal packages have a responsible team attached.',
|
|
6
|
+
recommended: true
|
|
7
|
+
},
|
|
8
|
+
hasSuggestions: false,
|
|
9
|
+
messages: {
|
|
10
|
+
atlassianTeamRequired: 'The atlassian.team property is required'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create: function create(context) {
|
|
14
|
+
return {
|
|
15
|
+
ObjectExpression: function ObjectExpression(node) {
|
|
16
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
var atlassianProp = node.properties.find(function (p) {
|
|
20
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'atlassian';
|
|
21
|
+
});
|
|
22
|
+
if (!atlassianProp) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (atlassianProp.type !== 'Property' || atlassianProp.value.type !== 'ObjectExpression') {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
var teamProp = atlassianProp.value.properties.find(function (p) {
|
|
29
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === 'team';
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// this just checks for existence, we can potentially cross-reference it with teams.json to make sure its valid in the future.
|
|
33
|
+
if (!teamProp) {
|
|
34
|
+
return context.report({
|
|
35
|
+
node: node,
|
|
36
|
+
messageId: 'atlassianTeamRequired'
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export default rule;
|
|
@@ -4,6 +4,8 @@ var __isOnlyOneFlagCheckInExpression = function __isOnlyOneFlagCheckInExpression
|
|
|
4
4
|
switch (root.type) {
|
|
5
5
|
case 'IfStatement':
|
|
6
6
|
return __isOnlyOneFlagCheckInExpression(root.test, ignoredNode);
|
|
7
|
+
case 'UnaryExpression':
|
|
8
|
+
return __isOnlyOneFlagCheckInExpression(root.argument, ignoredNode);
|
|
7
9
|
case 'CallExpression':
|
|
8
10
|
if (root === ignoredNode) {
|
|
9
11
|
return true;
|
|
@@ -23,7 +25,8 @@ var __isOnlyOneFlagCheckInExpression = function __isOnlyOneFlagCheckInExpression
|
|
|
23
25
|
var isOnlyOneFlagCheckInExpression = function isOnlyOneFlagCheckInExpression(node) {
|
|
24
26
|
var root = node.parent;
|
|
25
27
|
// find the root node of the expression
|
|
26
|
-
|
|
28
|
+
// NOTE: This is not an exhaustive check for all ESTree.Expression types but is good enough
|
|
29
|
+
while (root.type.endsWith('Expression')) {
|
|
27
30
|
root = root.parent;
|
|
28
31
|
}
|
|
29
32
|
return __isOnlyOneFlagCheckInExpression(root, node);
|
|
@@ -57,6 +60,7 @@ var rule = {
|
|
|
57
60
|
case 'IfStatement':
|
|
58
61
|
case 'ConditionalExpression':
|
|
59
62
|
break;
|
|
63
|
+
case 'UnaryExpression':
|
|
60
64
|
case 'LogicalExpression':
|
|
61
65
|
if (!isOnlyOneFlagCheckInExpression(node)) {
|
|
62
66
|
context.report({
|
package/dist/esm/version.json
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const rules: {
|
|
|
4
4
|
'ensure-feature-flag-prefix': import("eslint").Rule.RuleModule;
|
|
5
5
|
'ensure-test-runner-arguments': import("eslint").Rule.RuleModule;
|
|
6
6
|
'ensure-test-runner-nested-count': import("eslint").Rule.RuleModule;
|
|
7
|
+
'ensure-atlassian-team': import("eslint").Rule.RuleModule;
|
|
7
8
|
'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
|
|
8
9
|
'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
|
|
9
10
|
'no-invalid-storybook-decorator-usage': import("eslint").Rule.RuleModule;
|
|
@@ -20,6 +21,7 @@ export declare const configs: {
|
|
|
20
21
|
'@atlaskit/platform/ensure-test-runner-nested-count': string;
|
|
21
22
|
'@atlaskit/platform/no-invalid-feature-flag-usage': string;
|
|
22
23
|
'@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
|
|
24
|
+
'@atlaskit/platform/ensure-atlassian-team': string;
|
|
23
25
|
};
|
|
24
26
|
};
|
|
25
27
|
};
|
|
@@ -4,6 +4,7 @@ export declare const rules: {
|
|
|
4
4
|
'ensure-feature-flag-prefix': import("eslint").Rule.RuleModule;
|
|
5
5
|
'ensure-test-runner-arguments': import("eslint").Rule.RuleModule;
|
|
6
6
|
'ensure-test-runner-nested-count': import("eslint").Rule.RuleModule;
|
|
7
|
+
'ensure-atlassian-team': import("eslint").Rule.RuleModule;
|
|
7
8
|
'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
|
|
8
9
|
'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
|
|
9
10
|
'no-invalid-storybook-decorator-usage': import("eslint").Rule.RuleModule;
|
|
@@ -20,6 +21,7 @@ export declare const configs: {
|
|
|
20
21
|
'@atlaskit/platform/ensure-test-runner-nested-count': string;
|
|
21
22
|
'@atlaskit/platform/no-invalid-feature-flag-usage': string;
|
|
22
23
|
'@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
|
|
24
|
+
'@atlaskit/platform/ensure-atlassian-team': string;
|
|
23
25
|
};
|
|
24
26
|
};
|
|
25
27
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"atlassian": {
|
|
7
7
|
"team": "UIP - Platform Integration Trust (PITa)",
|
package/report.api.md
CHANGED
|
@@ -34,6 +34,7 @@ export const configs: {
|
|
|
34
34
|
'@atlaskit/platform/ensure-test-runner-nested-count': string;
|
|
35
35
|
'@atlaskit/platform/no-invalid-feature-flag-usage': string;
|
|
36
36
|
'@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
|
|
37
|
+
'@atlaskit/platform/ensure-atlassian-team': string;
|
|
37
38
|
};
|
|
38
39
|
};
|
|
39
40
|
};
|
|
@@ -49,6 +50,7 @@ export const rules: {
|
|
|
49
50
|
'ensure-feature-flag-prefix': Rule.RuleModule;
|
|
50
51
|
'ensure-test-runner-arguments': Rule.RuleModule;
|
|
51
52
|
'ensure-test-runner-nested-count': Rule.RuleModule;
|
|
53
|
+
'ensure-atlassian-team': Rule.RuleModule;
|
|
52
54
|
'no-invalid-feature-flag-usage': Rule.RuleModule;
|
|
53
55
|
'no-pre-post-install-scripts': Rule.RuleModule;
|
|
54
56
|
'no-invalid-storybook-decorator-usage': Rule.RuleModule;
|
package/src/index.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import ensureFeatureFlagRegistration from './rules/ensure-feature-flag-registrat
|
|
|
3
3
|
import noPreAndPostInstallScripts from './rules/no-pre-post-installs';
|
|
4
4
|
import ensureTestRunnerArguments from './rules/ensure-test-runner-arguments';
|
|
5
5
|
import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count';
|
|
6
|
+
import ensureAtlassianTeam from './rules/ensure-atlassian-team';
|
|
6
7
|
import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
|
|
7
8
|
import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
|
|
8
9
|
import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
|
|
@@ -12,6 +13,7 @@ export const rules = {
|
|
|
12
13
|
'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
|
|
13
14
|
'ensure-test-runner-arguments': ensureTestRunnerArguments,
|
|
14
15
|
'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
|
|
16
|
+
'ensure-atlassian-team': ensureAtlassianTeam,
|
|
15
17
|
'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
|
|
16
18
|
'no-pre-post-install-scripts': noPreAndPostInstallScripts,
|
|
17
19
|
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage,
|
|
@@ -30,6 +32,7 @@ export const configs = {
|
|
|
30
32
|
'@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
|
|
31
33
|
'@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
|
|
32
34
|
'@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
|
|
35
|
+
'@atlaskit/platform/ensure-atlassian-team': 'error',
|
|
33
36
|
},
|
|
34
37
|
},
|
|
35
38
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { tester } from '../../../../__tests__/utils/_tester';
|
|
2
|
+
import rule from '../../index';
|
|
3
|
+
|
|
4
|
+
describe('test no-pre-post-installs rule', () => {
|
|
5
|
+
tester.run('no-pre-post-installs', rule, {
|
|
6
|
+
valid: [
|
|
7
|
+
{
|
|
8
|
+
code: `const foo = {}`,
|
|
9
|
+
filename: 'package.json',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
code: `const foo = { "atlassian": { "team": "bar" } }`,
|
|
13
|
+
filename: 'foo/package.json',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
invalid: [
|
|
17
|
+
{
|
|
18
|
+
code: `const foo = { "atlassian": {} }`,
|
|
19
|
+
filename: 'foo/package.json',
|
|
20
|
+
errors: [{ messageId: 'atlassianTeamRequired' }],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
|
|
3
|
+
const rule: Rule.RuleModule = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'problem',
|
|
6
|
+
docs: {
|
|
7
|
+
description:
|
|
8
|
+
'This rule ensures that the internal packages have a responsible team attached.',
|
|
9
|
+
recommended: true,
|
|
10
|
+
},
|
|
11
|
+
hasSuggestions: false,
|
|
12
|
+
messages: {
|
|
13
|
+
atlassianTeamRequired: 'The atlassian.team property is required',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
return {
|
|
18
|
+
ObjectExpression: (node: Rule.Node) => {
|
|
19
|
+
if (
|
|
20
|
+
!context.getFilename().endsWith('package.json') ||
|
|
21
|
+
node.type !== 'ObjectExpression'
|
|
22
|
+
) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const atlassianProp = node.properties.find(
|
|
27
|
+
(p) =>
|
|
28
|
+
p.type === 'Property' &&
|
|
29
|
+
p.key.type === 'Literal' &&
|
|
30
|
+
p.key.value === 'atlassian',
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!atlassianProp) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (
|
|
38
|
+
atlassianProp.type !== 'Property' ||
|
|
39
|
+
atlassianProp.value.type !== 'ObjectExpression'
|
|
40
|
+
) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const teamProp = atlassianProp.value.properties.find(
|
|
45
|
+
(p) =>
|
|
46
|
+
p.type === 'Property' &&
|
|
47
|
+
p.key.type === 'Literal' &&
|
|
48
|
+
p.key.value === 'team',
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// this just checks for existence, we can potentially cross-reference it with teams.json to make sure its valid in the future.
|
|
52
|
+
if (!teamProp) {
|
|
53
|
+
return context.report({
|
|
54
|
+
node,
|
|
55
|
+
messageId: 'atlassianTeamRequired',
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default rule;
|
|
@@ -8,6 +8,10 @@ describe('enforce-feature-flag-usage-structure tests', () => {
|
|
|
8
8
|
// IfStatement
|
|
9
9
|
code: `if(getBooleanFF('test-flag')) { }`,
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
// negated IfStatement
|
|
13
|
+
code: `if(!getBooleanFF('test-flag')) { }`,
|
|
14
|
+
},
|
|
11
15
|
{
|
|
12
16
|
// ConditionalExpression
|
|
13
17
|
code: `const val = getBooleanFF('test-flag') ? 'yay' : 'no';`,
|
|
@@ -38,7 +42,14 @@ describe('enforce-feature-flag-usage-structure tests', () => {
|
|
|
38
42
|
],
|
|
39
43
|
},
|
|
40
44
|
{
|
|
41
|
-
code: `if(
|
|
45
|
+
code: `if(!getBooleanFF('test-flag') && !getBooleanFF('test-flag')) { }`,
|
|
46
|
+
errors: [
|
|
47
|
+
{ messageId: 'multipleFlagCheckInExpression' },
|
|
48
|
+
{ messageId: 'multipleFlagCheckInExpression' },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
code: `if((!getBooleanFF('test-flag') || 1 == true) && getBooleanFF('test-flag')) { }`,
|
|
42
53
|
errors: [
|
|
43
54
|
{ messageId: 'multipleFlagCheckInExpression' },
|
|
44
55
|
{ messageId: 'multipleFlagCheckInExpression' },
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
|
+
import type { Node, Expression } from 'estree';
|
|
2
3
|
|
|
3
4
|
const FF_GETTER_BOOLEAN_IDENTIFIER = 'getBooleanFF' as const;
|
|
4
5
|
|
|
5
6
|
const __isOnlyOneFlagCheckInExpression = (
|
|
6
|
-
root:
|
|
7
|
-
ignoredNode:
|
|
7
|
+
root: Node | Expression,
|
|
8
|
+
ignoredNode: Node,
|
|
8
9
|
): boolean => {
|
|
9
10
|
switch (root.type) {
|
|
10
11
|
case 'IfStatement':
|
|
11
|
-
return __isOnlyOneFlagCheckInExpression(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
12
|
+
return __isOnlyOneFlagCheckInExpression(root.test, ignoredNode);
|
|
13
|
+
case 'UnaryExpression':
|
|
14
|
+
return __isOnlyOneFlagCheckInExpression(root.argument, ignoredNode);
|
|
15
15
|
|
|
16
16
|
case 'CallExpression':
|
|
17
17
|
if (root === ignoredNode) {
|
|
@@ -29,8 +29,8 @@ const __isOnlyOneFlagCheckInExpression = (
|
|
|
29
29
|
case 'BinaryExpression':
|
|
30
30
|
case 'LogicalExpression':
|
|
31
31
|
return (
|
|
32
|
-
__isOnlyOneFlagCheckInExpression(root.left
|
|
33
|
-
__isOnlyOneFlagCheckInExpression(root.right
|
|
32
|
+
__isOnlyOneFlagCheckInExpression(root.left, ignoredNode) &&
|
|
33
|
+
__isOnlyOneFlagCheckInExpression(root.right, ignoredNode)
|
|
34
34
|
);
|
|
35
35
|
|
|
36
36
|
default:
|
|
@@ -41,7 +41,8 @@ const __isOnlyOneFlagCheckInExpression = (
|
|
|
41
41
|
const isOnlyOneFlagCheckInExpression = (node: Rule.Node): boolean => {
|
|
42
42
|
let root = node.parent;
|
|
43
43
|
// find the root node of the expression
|
|
44
|
-
|
|
44
|
+
// NOTE: This is not an exhaustive check for all ESTree.Expression types but is good enough
|
|
45
|
+
while (root.type.endsWith('Expression')) {
|
|
45
46
|
root = root.parent;
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -83,6 +84,7 @@ const rule: Rule.RuleModule = {
|
|
|
83
84
|
case 'IfStatement':
|
|
84
85
|
case 'ConditionalExpression':
|
|
85
86
|
break;
|
|
87
|
+
case 'UnaryExpression':
|
|
86
88
|
case 'LogicalExpression':
|
|
87
89
|
if (!isOnlyOneFlagCheckInExpression(node)) {
|
|
88
90
|
context.report({
|
package/tmp/api-report-tmp.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export const configs: {
|
|
|
20
20
|
'@atlaskit/platform/ensure-test-runner-nested-count': string;
|
|
21
21
|
'@atlaskit/platform/no-invalid-feature-flag-usage': string;
|
|
22
22
|
'@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
|
|
23
|
+
'@atlaskit/platform/ensure-atlassian-team': string;
|
|
23
24
|
};
|
|
24
25
|
};
|
|
25
26
|
};
|
|
@@ -35,6 +36,7 @@ export const rules: {
|
|
|
35
36
|
'ensure-feature-flag-prefix': Rule.RuleModule;
|
|
36
37
|
'ensure-test-runner-arguments': Rule.RuleModule;
|
|
37
38
|
'ensure-test-runner-nested-count': Rule.RuleModule;
|
|
39
|
+
'ensure-atlassian-team': Rule.RuleModule;
|
|
38
40
|
'no-invalid-feature-flag-usage': Rule.RuleModule;
|
|
39
41
|
'no-pre-post-install-scripts': Rule.RuleModule;
|
|
40
42
|
'no-invalid-storybook-decorator-usage': Rule.RuleModule;
|