@atlaskit/eslint-plugin-platform 2.6.0 → 2.7.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 (119) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/index.js +4 -3
  3. package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  4. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  5. package/dist/cjs/rules/feature-gating/no-alias/index.js +1 -1
  6. package/dist/cjs/rules/no-direct-document-usage/index.js +1 -1
  7. package/dist/cjs/rules/no-set-immediate/index.js +39 -0
  8. package/dist/cjs/rules/util/context-compat.js +4 -2
  9. package/dist/es2019/index.js +4 -3
  10. package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  11. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  12. package/dist/es2019/rules/feature-gating/no-alias/index.js +1 -1
  13. package/dist/es2019/rules/no-direct-document-usage/index.js +1 -1
  14. package/dist/es2019/rules/no-set-immediate/index.js +33 -0
  15. package/dist/es2019/rules/util/context-compat.js +4 -2
  16. package/dist/esm/index.js +4 -3
  17. package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  18. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  19. package/dist/esm/rules/feature-gating/no-alias/index.js +1 -1
  20. package/dist/esm/rules/no-direct-document-usage/index.js +1 -1
  21. package/dist/esm/rules/no-set-immediate/index.js +33 -0
  22. package/dist/esm/rules/util/context-compat.js +4 -2
  23. package/dist/types/index.d.ts +14 -6
  24. package/dist/types/rules/util/handle-ast-object.d.ts +1 -1
  25. package/dist/types-ts4.5/index.d.ts +14 -6
  26. package/dist/types-ts4.5/rules/util/handle-ast-object.d.ts +1 -1
  27. package/package.json +2 -2
  28. package/afm-cc/tsconfig.json +0 -24
  29. package/afm-jira/tsconfig.json +0 -24
  30. package/build/tsconfig.json +0 -17
  31. package/dist/cjs/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -79
  32. package/dist/es2019/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -62
  33. package/dist/esm/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -75
  34. package/src/__tests__/utils/_tester.tsx +0 -26
  35. package/src/index.tsx +0 -251
  36. package/src/rules/compiled/README.md +0 -3
  37. package/src/rules/compiled/expand-background-shorthand/README.md +0 -23
  38. package/src/rules/compiled/expand-background-shorthand/__tests__/rule.test.ts +0 -160
  39. package/src/rules/compiled/expand-background-shorthand/index.tsx +0 -43
  40. package/src/rules/compiled/expand-border-shorthand/README.md +0 -51
  41. package/src/rules/compiled/expand-border-shorthand/__tests__/rule.test.ts +0 -211
  42. package/src/rules/compiled/expand-border-shorthand/index.ts +0 -103
  43. package/src/rules/compiled/expand-spacing-shorthand/README.md +0 -38
  44. package/src/rules/compiled/expand-spacing-shorthand/__tests__/rule.test.ts +0 -448
  45. package/src/rules/compiled/expand-spacing-shorthand/index.ts +0 -240
  46. package/src/rules/constants.tsx +0 -20
  47. package/src/rules/ensure-atlassian-team/__tests__/unit/rule.test.ts +0 -24
  48. package/src/rules/ensure-atlassian-team/index.ts +0 -51
  49. package/src/rules/ensure-critical-dependency-resolutions/__test__/unit/rule.test.tsx +0 -200
  50. package/src/rules/ensure-critical-dependency-resolutions/index.tsx +0 -172
  51. package/src/rules/ensure-feature-flag-prefix/__tests__/unit/rule.test.tsx +0 -65
  52. package/src/rules/ensure-feature-flag-prefix/index.tsx +0 -81
  53. package/src/rules/ensure-feature-flag-registration/__tests__/unit/rule.test.tsx +0 -115
  54. package/src/rules/ensure-feature-flag-registration/index.tsx +0 -106
  55. package/src/rules/ensure-native-and-af-exports-synced/__tests__/unit/rule.test.tsx +0 -199
  56. package/src/rules/ensure-native-and-af-exports-synced/index.tsx +0 -188
  57. package/src/rules/ensure-no-private-dependencies/__tests__/unit/rule.test.ts +0 -212
  58. package/src/rules/ensure-no-private-dependencies/index.ts +0 -64
  59. package/src/rules/ensure-publish-valid/__tests__/unit/rule.test.ts +0 -39
  60. package/src/rules/ensure-publish-valid/index.ts +0 -81
  61. package/src/rules/ensure-test-runner-arguments/__tests__/unit/rule.test.tsx +0 -298
  62. package/src/rules/ensure-test-runner-arguments/index.tsx +0 -121
  63. package/src/rules/ensure-test-runner-nested-count/__tests__/unit/rule.test.tsx +0 -308
  64. package/src/rules/ensure-test-runner-nested-count/index.tsx +0 -82
  65. package/src/rules/ensure-valid-bin-values/__tests__/unit/rule.test.ts +0 -159
  66. package/src/rules/ensure-valid-bin-values/index.ts +0 -70
  67. package/src/rules/ensure-valid-platform-yarn-protocol-usage/__tests__/unit/rule.test.ts +0 -147
  68. package/src/rules/ensure-valid-platform-yarn-protocol-usage/index.ts +0 -67
  69. package/src/rules/feature-gating/README.md +0 -8
  70. package/src/rules/feature-gating/inline-usage/README.md +0 -53
  71. package/src/rules/feature-gating/inline-usage/__tests__/rule.test.tsx +0 -106
  72. package/src/rules/feature-gating/inline-usage/index.tsx +0 -135
  73. package/src/rules/feature-gating/no-alias/README.md +0 -29
  74. package/src/rules/feature-gating/no-alias/__tests__/rule.test.tsx +0 -76
  75. package/src/rules/feature-gating/no-alias/index.tsx +0 -80
  76. package/src/rules/feature-gating/no-module-level-eval/README.md +0 -53
  77. package/src/rules/feature-gating/no-module-level-eval/__tests__/test.tsx +0 -133
  78. package/src/rules/feature-gating/no-module-level-eval/index.tsx +0 -54
  79. package/src/rules/feature-gating/no-module-level-eval-nav4/README.md +0 -8
  80. package/src/rules/feature-gating/no-module-level-eval-nav4/__tests__/test.tsx +0 -130
  81. package/src/rules/feature-gating/no-module-level-eval-nav4/index.tsx +0 -73
  82. package/src/rules/feature-gating/no-preconditioning/README.md +0 -69
  83. package/src/rules/feature-gating/no-preconditioning/__tests__/rule.test.tsx +0 -164
  84. package/src/rules/feature-gating/no-preconditioning/index.tsx +0 -138
  85. package/src/rules/feature-gating/prefer-fg/README.md +0 -3
  86. package/src/rules/feature-gating/prefer-fg/__tests__/rule.test.tsx +0 -83
  87. package/src/rules/feature-gating/prefer-fg/index.tsx +0 -110
  88. package/src/rules/feature-gating/static-feature-flags/README.md +0 -3
  89. package/src/rules/feature-gating/static-feature-flags/__tests__/test.tsx +0 -135
  90. package/src/rules/feature-gating/static-feature-flags/index.tsx +0 -103
  91. package/src/rules/feature-gating/use-recommended-utils/README.md +0 -67
  92. package/src/rules/feature-gating/use-recommended-utils/__tests__/rule.test.tsx +0 -78
  93. package/src/rules/feature-gating/use-recommended-utils/index.tsx +0 -57
  94. package/src/rules/feature-gating/utils.tsx +0 -48
  95. package/src/rules/no-direct-document-usage/index.tsx +0 -109
  96. package/src/rules/no-duplicate-dependencies/__tests__/unit/rule.test.ts +0 -116
  97. package/src/rules/no-duplicate-dependencies/index.ts +0 -79
  98. package/src/rules/no-invalid-feature-flag-usage/__tests__/unit/rule.test.tsx +0 -69
  99. package/src/rules/no-invalid-feature-flag-usage/index.tsx +0 -128
  100. package/src/rules/no-invalid-storybook-decorator-usage/__tests__/unit/rule.test.tsx +0 -18
  101. package/src/rules/no-invalid-storybook-decorator-usage/index.tsx +0 -39
  102. package/src/rules/no-pre-post-installs/__tests__/unit/rule.test.ts +0 -41
  103. package/src/rules/no-pre-post-installs/index.ts +0 -35
  104. package/src/rules/no-sparse-checkout/__tests__/unit/rule.test.tsx +0 -48
  105. package/src/rules/no-sparse-checkout/index.tsx +0 -54
  106. package/src/rules/use-entrypoints-in-examples/README.md +0 -27
  107. package/src/rules/use-entrypoints-in-examples/__tests__/rule.test.tsx +0 -34
  108. package/src/rules/use-entrypoints-in-examples/index.tsx +0 -43
  109. package/src/rules/util/__tests__/context-compat.test.ts +0 -122
  110. package/src/rules/util/compiled-utils.ts +0 -27
  111. package/src/rules/util/context-compat.ts +0 -41
  112. package/src/rules/util/file-exclusions.ts +0 -39
  113. package/src/rules/util/handle-ast-object.ts +0 -33
  114. package/src/rules/util/registration-utils.ts +0 -59
  115. package/tsconfig.app.json +0 -43
  116. package/tsconfig.dev.json +0 -40
  117. package/tsconfig.json +0 -23
  118. /package/dist/types/rules/{ensure-valid-platform-yarn-protocol-usage → no-set-immediate}/index.d.ts +0 -0
  119. /package/dist/types-ts4.5/rules/{ensure-valid-platform-yarn-protocol-usage → no-set-immediate}/index.d.ts +0 -0
@@ -1,69 +0,0 @@
1
- import { tester } from '../../../../__tests__/utils/_tester';
2
- import rule from '../../index';
3
-
4
- describe('enforce-feature-flag-usage-structure tests', () => {
5
- tester.run('ensure-feature-flag-registration', rule, {
6
- valid: [
7
- {
8
- // IfStatement
9
- code: `if(getBooleanFF('test-flag')) { }`,
10
- },
11
- {
12
- // negated IfStatement
13
- code: `if(!getBooleanFF('test-flag')) { }`,
14
- },
15
- {
16
- // ConditionalExpression
17
- code: `const val = getBooleanFF('test-flag') ? 'yay' : 'no';`,
18
- },
19
- {
20
- // LogicalExpression
21
- code: `const val = 100 + (getBooleanFF('test-flag') && 50 || 10);`,
22
- },
23
- ],
24
- invalid: [
25
- {
26
- code: `getBooleanFF('test-flag')`,
27
- errors: [{ messageId: 'onlyInlineIf' }],
28
- },
29
- {
30
- code: `const val = getBooleanFF('test-flag')`,
31
- errors: [{ messageId: 'onlyInlineIf' }],
32
- },
33
- {
34
- code: `const ff = "test-flag"; if(getBooleanFF(ff)) { }`,
35
- errors: [{ messageId: 'onlyStringLiteral' }],
36
- },
37
- {
38
- code: `if(getBooleanFF('test-flag') && getBooleanFF('test-flag')) { }`,
39
- errors: [
40
- { messageId: 'multipleFlagCheckInExpression' },
41
- { messageId: 'multipleFlagCheckInExpression' },
42
- ],
43
- },
44
- {
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')) { }`,
53
- errors: [
54
- { messageId: 'multipleFlagCheckInExpression' },
55
- { messageId: 'multipleFlagCheckInExpression' },
56
- ],
57
- },
58
- {
59
- code: `export default getBooleanFF('test-flag') ? "this is" : "not good";`,
60
- errors: [{ messageId: 'noModuleScope' }],
61
- },
62
- {
63
- only: true,
64
- code: `export const foo = getBooleanFF('test-flag') ? "this is" : "not good";`,
65
- errors: [{ messageId: 'noModuleScope' }],
66
- },
67
- ],
68
- });
69
- });
@@ -1,128 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
- import type { Node, Expression } from 'estree';
4
-
5
- const FF_GETTER_BOOLEAN_IDENTIFIER = 'getBooleanFF' as const;
6
-
7
- const __isOnlyOneFlagCheckInExpression = (root: Node | Expression, ignoredNode: Node): boolean => {
8
- switch (root.type) {
9
- case 'IfStatement':
10
- return __isOnlyOneFlagCheckInExpression(root.test, ignoredNode);
11
- case 'UnaryExpression':
12
- return __isOnlyOneFlagCheckInExpression(root.argument, ignoredNode);
13
-
14
- case 'CallExpression':
15
- if (root === ignoredNode) {
16
- return true;
17
- }
18
- return !(
19
- root.callee.type === 'Identifier' && root.callee.name === FF_GETTER_BOOLEAN_IDENTIFIER
20
- );
21
-
22
- // shouldn't ever get here but just in case
23
- case 'Identifier':
24
- return root.name !== FF_GETTER_BOOLEAN_IDENTIFIER;
25
-
26
- case 'BinaryExpression':
27
- case 'LogicalExpression':
28
- return (
29
- __isOnlyOneFlagCheckInExpression(root.left, ignoredNode) &&
30
- __isOnlyOneFlagCheckInExpression(root.right, ignoredNode)
31
- );
32
-
33
- default:
34
- return true;
35
- }
36
- };
37
-
38
- const isOnlyOneFlagCheckInExpression = (node: Rule.Node): boolean => {
39
- let root = node.parent;
40
- // find the root node of the expression
41
- // NOTE: This is not an exhaustive check for all ESTree.Expression types but is good enough
42
- while (root.type.endsWith('Expression')) {
43
- root = root.parent;
44
- }
45
-
46
- return __isOnlyOneFlagCheckInExpression(root, node);
47
- };
48
-
49
- const rule: Rule.RuleModule = {
50
- meta: {
51
- hasSuggestions: false,
52
- docs: {
53
- recommended: false,
54
- },
55
- type: 'problem',
56
- messages: {
57
- onlyInlineIf:
58
- "Only call feature flags as part of an expression, don't assign to a variable! See http://go/pff-eslint for more details",
59
- onlyStringLiteral:
60
- "Only get feature flags by string literal, don't use variables! See http://go/pff-eslint for more details",
61
- multipleFlagCheckInExpression: `Only check one flag per expression! See http://go/pff-eslint for more details`,
62
- noModuleScope: `Don't use platform feature flags in module scope! See http://go/pff-eslint for more details`,
63
- },
64
- },
65
- create(context) {
66
- return {
67
- [`CallExpression[callee.name=/${FF_GETTER_BOOLEAN_IDENTIFIER}/]`]: (node: Rule.Node) => {
68
- // to make typescript happy
69
- if (node.type === 'CallExpression') {
70
- const args = node.arguments;
71
-
72
- if (args.length === 1 && args[0].type !== 'Literal') {
73
- return context.report({
74
- node,
75
- messageId: 'onlyStringLiteral',
76
- });
77
- }
78
-
79
- switch (node.parent?.type) {
80
- case 'IfStatement':
81
- break;
82
- case 'ConditionalExpression':
83
- switch (node.parent?.parent.type) {
84
- case 'ExportDefaultDeclaration':
85
- // handles "export default getBooleanFF('test-flag') ? "this is" : "not good";"
86
- context.report({
87
- node,
88
- messageId: 'noModuleScope',
89
- });
90
- break;
91
- case 'VariableDeclarator':
92
- // handles "export const foo = getBooleanFF('test-flag') ? 'this is' : 'not good';"
93
- if (
94
- node.parent.parent.parent.type === 'VariableDeclaration' &&
95
- node.parent.parent.parent.parent.type === 'ExportNamedDeclaration'
96
- ) {
97
- context.report({
98
- node,
99
- messageId: 'noModuleScope',
100
- });
101
- }
102
- break;
103
- }
104
- break;
105
- case 'UnaryExpression':
106
- case 'LogicalExpression':
107
- if (!isOnlyOneFlagCheckInExpression(node)) {
108
- context.report({
109
- node,
110
- messageId: 'multipleFlagCheckInExpression',
111
- });
112
- }
113
- break;
114
- default:
115
- return context.report({
116
- node,
117
- messageId: 'onlyInlineIf',
118
- });
119
- }
120
- }
121
-
122
- return {};
123
- },
124
- };
125
- },
126
- };
127
-
128
- export default rule;
@@ -1,18 +0,0 @@
1
- import { tester } from '../../../../__tests__/utils/_tester';
2
- import rule from '../../index';
3
-
4
- describe('no-invalid-storybook-decorator-usage tests', () => {
5
- tester.run('no-invalid-storybook-decorator-usage', rule, {
6
- valid: [
7
- {
8
- code: `withPlatformFeatureFlags({})(<SampleComponent/>)`,
9
- },
10
- ],
11
- invalid: [
12
- {
13
- code: `const flags = {'uip.sample.color': true}; withPlatformFeatureFlags(flags)(<SampleComponent/>)`,
14
- errors: [{ messageId: 'onlyObjectExpression' }],
15
- },
16
- ],
17
- });
18
- });
@@ -1,39 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
-
4
- const STORYBOOK_DECORATOR_IDENTIFIER = 'withPlatformFeatureFlags' as const;
5
-
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- hasSuggestions: false,
9
- docs: {
10
- recommended: false,
11
- },
12
- type: 'problem',
13
- messages: {
14
- onlyObjectExpression:
15
- 'Only object literals allowed in the storybook decorator! See http://go/pff-eslint for more details',
16
- },
17
- },
18
- create(context) {
19
- return {
20
- [`CallExpression[callee.name=/${STORYBOOK_DECORATOR_IDENTIFIER}/]`]: (node: Rule.Node) => {
21
- // to make typescript happy
22
- if (node.type === 'CallExpression') {
23
- const args = node.arguments;
24
-
25
- if (args.length === 1 && args[0].type !== 'ObjectExpression') {
26
- return context.report({
27
- node,
28
- messageId: 'onlyObjectExpression',
29
- });
30
- }
31
- }
32
-
33
- return {};
34
- },
35
- };
36
- },
37
- };
38
-
39
- export default rule;
@@ -1,41 +0,0 @@
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 = { "scripts": { "preinstall": 1, "postinstall": 2 }}`,
9
- filename: 'hello/foo.ts',
10
- },
11
- {
12
- code: `const foo = { "scripts": { "preinstall": 1, "postinstall": 2 }}`,
13
- filename: 'foo/dummy.json',
14
- },
15
- {
16
- code: `const foo = { "scripts": { "bar": 1, "dummy": 'echo 1' }}`,
17
- filename: 'foo/package.json',
18
- },
19
- {
20
- code: `module.exports = { "scripts": { "fakePreinstall": 1 }};`,
21
- filename: 'bar/package.json',
22
- },
23
- {
24
- code: `module.exports = { "scripts": { "fakePostinstall": 1 }};`,
25
- filename: 'bar/package.json',
26
- },
27
- ],
28
- invalid: [
29
- {
30
- code: `module.exports = { "scripts": { "preinstall": 1 }};`,
31
- filename: 'bar/package.json',
32
- errors: [{ messageId: 'prePostInstallScriptsNotAllowed' }],
33
- },
34
- {
35
- code: `const foo = { "scripts": { "postinstall": 1 }}`,
36
- filename: 'baz/package.json',
37
- errors: [{ messageId: 'prePostInstallScriptsNotAllowed' }],
38
- },
39
- ],
40
- });
41
- });
@@ -1,35 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
-
4
- const rule: Rule.RuleModule = {
5
- meta: {
6
- type: 'problem',
7
- docs: {
8
- description:
9
- 'This rule disallows public packages to have pre/post install scripts as installations can happen on different environments',
10
- recommended: false,
11
- },
12
- hasSuggestions: false,
13
- messages: {
14
- prePostInstallScriptsNotAllowed: 'pre/post install scripts not allowed in package.json',
15
- },
16
- },
17
- create(context) {
18
- return {
19
- 'ObjectExpression Property[key.value=scripts] Property[key.value=/^(pre|post)install$/]': (
20
- node: Rule.Node,
21
- ) => {
22
- if (!context.getFilename().endsWith('/package.json')) {
23
- return;
24
- }
25
-
26
- return context.report({
27
- node,
28
- messageId: 'prePostInstallScriptsNotAllowed',
29
- });
30
- },
31
- };
32
- },
33
- };
34
-
35
- export default rule;
@@ -1,48 +0,0 @@
1
- import { tester } from '../../../../__tests__/utils/_tester';
2
- import rule from '../../index';
3
-
4
- describe('test no-sparse-checkout rule', () => {
5
- tester.run('no-sparse-checkout', rule, {
6
- valid: [
7
- {
8
- code: `
9
- const config = {
10
- clone: alias.afmClone({ sparseCheckout: false })
11
- };
12
- `,
13
- filename: 'hello/foo.ts',
14
- },
15
- {
16
- code: `
17
- const config = {
18
- clone: alias.afmClone({ cloneDepth: 1})
19
- };
20
- `,
21
- filename: 'hello/foo.ts',
22
- },
23
- ],
24
- invalid: [
25
- {
26
- code: `
27
- const config = {
28
- clone: alias.afmClone({ sparseCheckout: true })
29
- };
30
- `,
31
- filename: 'hello/foo.ts',
32
- errors: [{ messageId: 'noSparseCheckout' }],
33
- },
34
- {
35
- code: `
36
- const config = {
37
- clone: alias.afmClone({
38
- cloneDepth: 'full',
39
- sparseCheckout: true
40
- })
41
- };
42
- `,
43
- filename: 'hello/foo.ts',
44
- errors: [{ messageId: 'noSparseCheckout' }],
45
- },
46
- ],
47
- });
48
- });
@@ -1,54 +0,0 @@
1
- import type { Rule } from 'eslint';
2
- import type { Property } from 'estree';
3
-
4
- // We will be removing sparse checkout from pipelines in CI completely due to the load it causes on BBC.
5
- // We will be incrementally removing sparse-checkout from the files below as it is probably unnecessasry.
6
- // If you must add an exception below, please go through the chopper process before doing so
7
- const sparseCheckoutExceptions = [
8
- 'bitbucket-pipelines/pipelines/custom/run-issue-automat.ts',
9
- 'bitbucket-pipelines/pipelines/custom/marketplace/utils.ts',
10
- 'bitbucket-pipelines/pipelines/custom/confluence/utils/index.ts',
11
- 'bitbucket-pipelines/pipelines/custom/afm-tools/upload-afm-dependency-graph-cache.ts',
12
- 'bitbucket-pipelines/pipelines/custom/afm-tools/default-afm-tools.ts',
13
- 'bitbucket-pipelines/pipelines/custom/marketplace/utils.ts',
14
- 'bitbucket-pipelines/pipelines/custom/afm-git-hooks.ts',
15
- 'bitbucket-pipelines/pipelines/custom/update-codeowners-and-teams-gen.ts',
16
- 'bitbucket-pipelines/pipelines/custom/run-issue-automat.ts',
17
- ];
18
-
19
- const rule: Rule.RuleModule = {
20
- meta: {
21
- docs: {
22
- recommended: false,
23
- },
24
- type: 'problem',
25
- messages: {
26
- noSparseCheckout:
27
- 'Sparse checkout is not allowed in pipeline configurations. Use git-alternates instead by setting sparseCheckout to false or add this file to exceptions.',
28
- },
29
- },
30
-
31
- create(context) {
32
- const fileName = context.filename;
33
- if (sparseCheckoutExceptions.some((exception) => fileName.endsWith(exception))) {
34
- return {};
35
- }
36
-
37
- return {
38
- // Look for calls to afmClone or objects that match AFMCloneConfig type
39
- 'CallExpression[callee.object.name=alias][callee.property.name=afmClone] ObjectExpression Property':
40
- (node: Property) => {
41
- if (node.key.type === 'Identifier' && node.key.name === 'sparseCheckout') {
42
- if (node.value.type === 'Literal' && node.value.value === true) {
43
- context.report({
44
- node,
45
- messageId: 'noSparseCheckout',
46
- });
47
- }
48
- }
49
- },
50
- };
51
- },
52
- };
53
-
54
- export default rule;
@@ -1,27 +0,0 @@
1
- Using public entrypoints in our examples ensures that they reflect public API.
2
-
3
- It also has benefits for:
4
-
5
- - readability
6
- - bundle and code analysis
7
-
8
- ## Examples
9
-
10
- This rule marks imports as violations when they reach into the `src` folder through relative file
11
- paths.
12
-
13
- ### Incorrect
14
-
15
- ```js
16
- import Button from '../../../src';
17
-
18
- import { IconButton } from '../../../src/new';
19
- ```
20
-
21
- ### Correct
22
-
23
- ```js
24
- import Button from '@atlaskit/button';
25
-
26
- import { ExampleHelper } from '../not-src';
27
- ```
@@ -1,34 +0,0 @@
1
- import { tester } from '../../../__tests__/utils/_tester';
2
- import rule from '../index';
3
-
4
- const exampleFilename = 'packages/design-system/button/examples/0-basic.tsx';
5
- const nonExampleFilename = 'packages/design-system/button/scripts/my-script.tsx';
6
-
7
- tester.run('use-entrypoints-in-examples', rule, {
8
- valid: [
9
- {
10
- code: `import Button from '@atlaskit/button';`,
11
- filename: exampleFilename,
12
- },
13
- {
14
- code: `import { ExampleHelper } from '../not-src';`,
15
- filename: exampleFilename,
16
- },
17
- {
18
- code: `import Button from '../src';`,
19
- filename: nonExampleFilename,
20
- },
21
- ],
22
- invalid: [
23
- {
24
- code: `import Button from '../../../src';`,
25
- filename: exampleFilename,
26
- errors: [{ messageId: 'useEntrypointsInExamples' }],
27
- },
28
- {
29
- code: `import { IconButton } from '../../../src/new';`,
30
- filename: exampleFilename,
31
- errors: [{ messageId: 'useEntrypointsInExamples' }],
32
- },
33
- ],
34
- });
@@ -1,43 +0,0 @@
1
- import type { Rule } from 'eslint';
2
-
3
- const rule: Rule.RuleModule = {
4
- meta: {
5
- docs: {
6
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/use-entrypoints-in-examples/README.md',
7
- description: 'Encourage usage of package entrypoints in examples.',
8
- },
9
- messages: {
10
- useEntrypointsInExamples:
11
- 'Use the package entrypoints instead of importing from src. This ensures examples reflect public API.\n\nFor example, use `@atlaskit/button/new` instead of `../../src/new`',
12
- },
13
- type: 'problem',
14
- },
15
- create(context) {
16
- /**
17
- * Even if it's enabled on non-example files it will ignore them.
18
- *
19
- * This is a defensive check, the rule should be configured to only run on examples.
20
- */
21
- if (!context.filename.includes('/examples/')) {
22
- return {};
23
- }
24
-
25
- return {
26
- ImportDeclaration(node) {
27
- const moduleName = node.source.value;
28
- if (typeof moduleName !== 'string') {
29
- return;
30
- }
31
-
32
- if (/^(\.\.\/)+src(\/|$)/.test(moduleName)) {
33
- context.report({
34
- node: node.source,
35
- messageId: 'useEntrypointsInExamples',
36
- });
37
- }
38
- },
39
- };
40
- },
41
- };
42
-
43
- export default rule;
@@ -1,122 +0,0 @@
1
- import type { Rule, Scope, SourceCode } from 'eslint';
2
- import type { Node } from 'estree';
3
-
4
- import { getAncestors, getScope } from '../context-compat';
5
-
6
- describe('context-compat', () => {
7
- describe('getAncestors', () => {
8
- let context: Rule.RuleContext;
9
- let node: Node;
10
- let sourceCode: SourceCode;
11
- let ancestors: Node[];
12
-
13
- beforeEach(() => {
14
- node = {} as Node;
15
- ancestors = [];
16
- sourceCode = {
17
- getAncestors: jest.fn().mockReturnValue(ancestors),
18
- } as unknown as SourceCode;
19
- });
20
-
21
- it('should return ancestor nodes from context.sourceCode.getAncestors if available', () => {
22
- context = {
23
- sourceCode,
24
- } as unknown as Rule.RuleContext;
25
-
26
- const result = getAncestors(context, node);
27
- expect(result).toBe(ancestors);
28
- expect(sourceCode.getAncestors).toHaveBeenCalledWith(node);
29
- });
30
-
31
- it('should return ancestors from context.getSourceCode().getAncestors if context.sourceCode is not available', () => {
32
- context = {
33
- getSourceCode: jest.fn().mockReturnValue(sourceCode),
34
- } as unknown as Rule.RuleContext;
35
-
36
- const result = getAncestors(context, node);
37
- expect(result).toBe(ancestors);
38
- expect(context.getSourceCode).toHaveBeenCalled();
39
- expect(sourceCode.getAncestors).toHaveBeenCalledWith(node);
40
- });
41
-
42
- it('should return scope from context.getAncestors if neither context.sourceCode nor context.getSourceCode().getAncestors is available', () => {
43
- context = {
44
- getSourceCode: jest.fn().mockReturnValue({}),
45
- getAncestors: jest.fn().mockReturnValue(ancestors),
46
- } as unknown as Rule.RuleContext;
47
-
48
- const result = getAncestors(context, node);
49
- expect(result).toBe(ancestors);
50
- expect(context.getAncestors).toHaveBeenCalled();
51
- });
52
-
53
- it('should return scope from context.getAncestors if context.sourceCode does not have getAncestors', () => {
54
- context = {
55
- sourceCode: {},
56
- getAncestors: jest.fn().mockReturnValue(ancestors),
57
- } as unknown as Rule.RuleContext;
58
-
59
- const result = getAncestors(context, node);
60
- expect(result).toBe(ancestors);
61
- expect(context.getAncestors).toHaveBeenCalled();
62
- });
63
- });
64
-
65
- describe('getScope', () => {
66
- let context: Rule.RuleContext;
67
- let node: Node;
68
- let sourceCode: SourceCode;
69
- let scope: Scope.Scope;
70
-
71
- beforeEach(() => {
72
- node = {} as Node;
73
- scope = {} as Scope.Scope;
74
- sourceCode = {
75
- getScope: jest.fn().mockReturnValue(scope),
76
- } as unknown as SourceCode;
77
- });
78
-
79
- it('should return scope from context.sourceCode.getScope if available', () => {
80
- context = {
81
- sourceCode,
82
- } as unknown as Rule.RuleContext;
83
-
84
- const result = getScope(context, node);
85
- expect(result).toBe(scope);
86
- expect(sourceCode.getScope).toHaveBeenCalledWith(node);
87
- });
88
-
89
- it('should return scope from context.getSourceCode().getScope if context.sourceCode is not available', () => {
90
- context = {
91
- getSourceCode: jest.fn().mockReturnValue(sourceCode),
92
- } as unknown as Rule.RuleContext;
93
-
94
- const result = getScope(context, node);
95
- expect(result).toBe(scope);
96
- expect(context.getSourceCode).toHaveBeenCalled();
97
- expect(sourceCode.getScope).toHaveBeenCalledWith(node);
98
- });
99
-
100
- it('should return scope from context.getScope if neither context.sourceCode nor context.getSourceCode().getScope is available', () => {
101
- context = {
102
- getSourceCode: jest.fn().mockReturnValue({}),
103
- getScope: jest.fn().mockReturnValue(scope),
104
- } as unknown as Rule.RuleContext;
105
-
106
- const result = getScope(context, node);
107
- expect(result).toBe(scope);
108
- expect(context.getScope).toHaveBeenCalled();
109
- });
110
-
111
- it('should return scope from context.getScope if context.sourceCode does not have getScope', () => {
112
- context = {
113
- sourceCode: {},
114
- getScope: jest.fn().mockReturnValue(scope),
115
- } as unknown as Rule.RuleContext;
116
-
117
- const result = getScope(context, node);
118
- expect(result).toBe(scope);
119
- expect(context.getScope).toHaveBeenCalled();
120
- });
121
- });
122
- });
@@ -1,27 +0,0 @@
1
- import type { Node } from 'estree';
2
- import { getAncestors, getScope } from './context-compat';
3
- import type { Rule } from 'eslint';
4
- import {
5
- getImportSources,
6
- isCompiled,
7
- isAtlasKitCSS,
8
- } from '@atlaskit/eslint-utils/is-supported-import';
9
-
10
- // Checks if the function that holds the property is using a Compiled import package that this rule is targeting
11
- export const isCompiledAPI = (context: Rule.RuleContext, node: Node): boolean => {
12
- const importSources = getImportSources(context);
13
- const { references } = getScope(context, node);
14
- const ancestors = getAncestors(context, node);
15
- if (
16
- ancestors.some(
17
- (ancestor) =>
18
- ancestor.type === 'CallExpression' &&
19
- ancestor.callee &&
20
- (isCompiled(ancestor.callee, references, importSources) ||
21
- isAtlasKitCSS(ancestor.callee, references, importSources)),
22
- )
23
- ) {
24
- return true;
25
- }
26
- return false;
27
- };