@atlaskit/eslint-plugin-platform 2.7.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/index.js +17 -9
  3. package/dist/cjs/rules/constants.js +1 -1
  4. package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  5. package/dist/cjs/rules/ensure-no-private-dependencies/index.js +48 -66
  6. package/dist/cjs/rules/feature-gating/inline-usage/index.js +14 -3
  7. package/dist/cjs/rules/feature-gating/no-alias/index.js +1 -1
  8. package/dist/cjs/rules/feature-gating/no-module-level-eval/index.js +1 -1
  9. package/dist/cjs/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  10. package/dist/cjs/rules/feature-gating/no-preconditioning/index.js +4 -1
  11. package/dist/cjs/rules/feature-gating/prefer-fg/index.js +1 -1
  12. package/dist/cjs/rules/feature-gating/static-feature-flags/index.js +2 -2
  13. package/dist/cjs/rules/feature-gating/use-recommended-utils/index.js +1 -1
  14. package/dist/cjs/rules/feature-gating/valid-gate-name/index.js +60 -0
  15. package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +871 -0
  16. package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +1384 -0
  17. package/dist/cjs/rules/import/no-conversation-assistant-barrel-imports/index.js +43 -0
  18. package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +1401 -0
  19. package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +777 -0
  20. package/dist/cjs/rules/import/shared/barrel-parsing.js +511 -0
  21. package/dist/cjs/rules/import/shared/file-system.js +186 -0
  22. package/dist/cjs/rules/import/shared/jest-utils.js +191 -0
  23. package/dist/cjs/rules/import/shared/package-registry.js +263 -0
  24. package/dist/cjs/rules/import/shared/package-resolution.js +185 -0
  25. package/dist/cjs/rules/import/shared/perf.js +89 -0
  26. package/dist/cjs/rules/import/shared/types.js +67 -0
  27. package/dist/cjs/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  28. package/dist/cjs/rules/no-sparse-checkout/index.js +1 -1
  29. package/dist/cjs/rules/prefer-crypto-random-uuid/index.js +87 -0
  30. package/dist/cjs/rules/use-entrypoints-in-examples/index.js +1 -1
  31. package/dist/es2019/index.js +17 -9
  32. package/dist/es2019/rules/constants.js +1 -1
  33. package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  34. package/dist/es2019/rules/ensure-no-private-dependencies/index.js +10 -9
  35. package/dist/es2019/rules/feature-gating/inline-usage/index.js +14 -3
  36. package/dist/es2019/rules/feature-gating/no-alias/index.js +1 -1
  37. package/dist/es2019/rules/feature-gating/no-module-level-eval/index.js +1 -1
  38. package/dist/es2019/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  39. package/dist/es2019/rules/feature-gating/no-preconditioning/index.js +4 -1
  40. package/dist/es2019/rules/feature-gating/prefer-fg/index.js +1 -1
  41. package/dist/es2019/rules/feature-gating/static-feature-flags/index.js +2 -2
  42. package/dist/es2019/rules/feature-gating/use-recommended-utils/index.js +1 -1
  43. package/dist/es2019/rules/feature-gating/valid-gate-name/index.js +52 -0
  44. package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +801 -0
  45. package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +1113 -0
  46. package/dist/es2019/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  47. package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +1179 -0
  48. package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +738 -0
  49. package/dist/es2019/rules/import/shared/barrel-parsing.js +433 -0
  50. package/dist/es2019/rules/import/shared/file-system.js +174 -0
  51. package/dist/es2019/rules/import/shared/jest-utils.js +159 -0
  52. package/dist/es2019/rules/import/shared/package-registry.js +240 -0
  53. package/dist/es2019/rules/import/shared/package-resolution.js +161 -0
  54. package/dist/es2019/rules/import/shared/perf.js +83 -0
  55. package/dist/es2019/rules/import/shared/types.js +57 -0
  56. package/dist/es2019/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  57. package/dist/es2019/rules/no-sparse-checkout/index.js +1 -1
  58. package/dist/es2019/rules/prefer-crypto-random-uuid/index.js +81 -0
  59. package/dist/es2019/rules/use-entrypoints-in-examples/index.js +1 -1
  60. package/dist/esm/index.js +17 -9
  61. package/dist/esm/rules/constants.js +1 -1
  62. package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  63. package/dist/esm/rules/ensure-no-private-dependencies/index.js +48 -65
  64. package/dist/esm/rules/feature-gating/inline-usage/index.js +14 -3
  65. package/dist/esm/rules/feature-gating/no-alias/index.js +1 -1
  66. package/dist/esm/rules/feature-gating/no-module-level-eval/index.js +1 -1
  67. package/dist/esm/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  68. package/dist/esm/rules/feature-gating/no-preconditioning/index.js +4 -1
  69. package/dist/esm/rules/feature-gating/prefer-fg/index.js +1 -1
  70. package/dist/esm/rules/feature-gating/static-feature-flags/index.js +2 -2
  71. package/dist/esm/rules/feature-gating/use-recommended-utils/index.js +1 -1
  72. package/dist/esm/rules/feature-gating/valid-gate-name/index.js +53 -0
  73. package/dist/esm/rules/import/no-barrel-entry-imports/index.js +864 -0
  74. package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +1375 -0
  75. package/dist/esm/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  76. package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +1391 -0
  77. package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +770 -0
  78. package/dist/esm/rules/import/shared/barrel-parsing.js +500 -0
  79. package/dist/esm/rules/import/shared/file-system.js +176 -0
  80. package/dist/esm/rules/import/shared/jest-utils.js +179 -0
  81. package/dist/esm/rules/import/shared/package-registry.js +256 -0
  82. package/dist/esm/rules/import/shared/package-resolution.js +175 -0
  83. package/dist/esm/rules/import/shared/perf.js +80 -0
  84. package/dist/esm/rules/import/shared/types.js +61 -0
  85. package/dist/esm/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  86. package/dist/esm/rules/no-sparse-checkout/index.js +1 -1
  87. package/dist/esm/rules/prefer-crypto-random-uuid/index.js +81 -0
  88. package/dist/esm/rules/use-entrypoints-in-examples/index.js +1 -1
  89. package/dist/types/index.d.ts +18 -16
  90. package/dist/types/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  91. package/dist/types/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  92. package/dist/types/rules/import/no-conversation-assistant-barrel-imports/index.d.ts +3 -0
  93. package/dist/types/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  94. package/dist/types/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  95. package/dist/types/rules/import/shared/barrel-parsing.d.ts +30 -0
  96. package/dist/types/rules/import/shared/file-system.d.ts +38 -0
  97. package/dist/types/rules/import/shared/jest-utils.d.ts +47 -0
  98. package/dist/types/rules/import/shared/package-registry.d.ts +26 -0
  99. package/dist/types/rules/import/shared/package-resolution.d.ts +38 -0
  100. package/dist/types/rules/import/shared/perf.d.ts +13 -0
  101. package/dist/types/rules/import/shared/types.d.ts +131 -0
  102. package/dist/types/rules/prefer-crypto-random-uuid/index.d.ts +3 -0
  103. package/dist/types-ts4.5/index.d.ts +18 -28
  104. package/dist/types-ts4.5/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  105. package/dist/types-ts4.5/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  106. package/dist/types-ts4.5/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  107. package/dist/types-ts4.5/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  108. package/dist/types-ts4.5/rules/import/shared/barrel-parsing.d.ts +30 -0
  109. package/dist/types-ts4.5/rules/import/shared/file-system.d.ts +38 -0
  110. package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +47 -0
  111. package/dist/types-ts4.5/rules/import/shared/package-registry.d.ts +26 -0
  112. package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +38 -0
  113. package/dist/types-ts4.5/rules/import/shared/perf.d.ts +13 -0
  114. package/dist/types-ts4.5/rules/import/shared/types.d.ts +131 -0
  115. package/package.json +4 -5
  116. package/dist/cjs/rules/ensure-feature-flag-prefix/index.js +0 -75
  117. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +0 -158
  118. package/dist/es2019/rules/ensure-feature-flag-prefix/index.js +0 -65
  119. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +0 -146
  120. package/dist/esm/rules/ensure-feature-flag-prefix/index.js +0 -69
  121. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +0 -151
  122. /package/dist/types/rules/{ensure-native-and-af-exports-synced → feature-gating/valid-gate-name}/index.d.ts +0 -0
  123. /package/dist/types-ts4.5/rules/{ensure-feature-flag-prefix → feature-gating/valid-gate-name}/index.d.ts +0 -0
  124. /package/dist/types-ts4.5/rules/{ensure-native-and-af-exports-synced → import/no-conversation-assistant-barrel-imports}/index.d.ts +0 -0
  125. /package/dist/{types/rules/ensure-feature-flag-prefix → types-ts4.5/rules/prefer-crypto-random-uuid}/index.d.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  // We will be removing sparse checkout from pipelines in CI completely due to the load it causes on BBC.
2
2
  // We will be incrementally removing sparse-checkout from the files below as it is probably unnecessasry.
3
3
  // If you must add an exception below, please go through the chopper process before doing so
4
- const sparseCheckoutExceptions = ['bitbucket-pipelines/pipelines/custom/run-issue-automat.ts', 'bitbucket-pipelines/pipelines/custom/marketplace/utils.ts', 'bitbucket-pipelines/pipelines/custom/confluence/utils/index.ts', 'bitbucket-pipelines/pipelines/custom/afm-tools/upload-afm-dependency-graph-cache.ts', 'bitbucket-pipelines/pipelines/custom/afm-tools/default-afm-tools.ts', 'bitbucket-pipelines/pipelines/custom/marketplace/utils.ts', 'bitbucket-pipelines/pipelines/custom/afm-git-hooks.ts', 'bitbucket-pipelines/pipelines/custom/update-codeowners-and-teams-gen.ts', 'bitbucket-pipelines/pipelines/custom/run-issue-automat.ts'];
4
+ const sparseCheckoutExceptions = ['pipeline-definitions/pipelines/custom/run-issue-automat.ts', 'pipeline-definitions/pipelines/custom/marketplace/utils.ts', 'pipeline-definitions/pipelines/custom/confluence/utils/index.ts', 'pipeline-definitions/pipelines/custom/afm-tools/upload-afm-dependency-graph-cache.ts', 'pipeline-definitions/pipelines/custom/afm-tools/default-afm-tools.ts', 'pipeline-definitions/pipelines/custom/marketplace/utils.ts', 'pipeline-definitions/pipelines/custom/afm-git-hooks.ts', 'pipeline-definitions/pipelines/custom/update-codeowners-and-teams-gen.ts', 'pipeline-definitions/pipelines/custom/run-issue-automat.ts'];
5
5
  const rule = {
6
6
  meta: {
7
7
  docs: {
@@ -0,0 +1,81 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+
3
+ const rule = {
4
+ meta: {
5
+ type: 'problem',
6
+ // Problem type = can be error
7
+ docs: {
8
+ description: 'Prefer crypto.randomUUID() over uuid library. The uuid package causes Jest mocking issues.',
9
+ recommended: true
10
+ },
11
+ fixable: 'code',
12
+ // Enables --fix
13
+ messages: {
14
+ preferCryptoRandomUUID: 'Use crypto.randomUUID() instead of the uuid library. Run `eslint --fix` to auto-migrate.'
15
+ }
16
+ },
17
+ create(context) {
18
+ const uuidImports = new Map(); // Track imported names
19
+
20
+ return {
21
+ ImportDeclaration(node) {
22
+ if (node.type !== 'ImportDeclaration') {
23
+ return;
24
+ }
25
+ const source = node.source.value;
26
+ if (typeof source === 'string' && (source === 'uuid' || /^uuid\/v[14]$/.test(source))) {
27
+ // Track imported name (e.g., uuid, v4, etc.)
28
+ const specifier = node.specifiers[0];
29
+ if (specifier) {
30
+ uuidImports.set(specifier.local.name, node);
31
+ }
32
+ context.report({
33
+ node,
34
+ messageId: 'preferCryptoRandomUUID',
35
+ fix(fixer) {
36
+ // Remove the import - usages will be fixed separately
37
+ return fixer.remove(node);
38
+ }
39
+ });
40
+ }
41
+ },
42
+ CallExpression(node) {
43
+ var _node$arguments$;
44
+ if (node.type !== 'CallExpression') {
45
+ return;
46
+ }
47
+
48
+ // Handle direct uuid() or v4() calls
49
+ if (node.callee.type === 'Identifier') {
50
+ const calleeName = node.callee.name;
51
+ if (uuidImports.has(calleeName)) {
52
+ context.report({
53
+ node,
54
+ messageId: 'preferCryptoRandomUUID',
55
+ fix(fixer) {
56
+ // Replace uuid() with crypto.randomUUID()
57
+ return fixer.replaceText(node.callee, 'crypto.randomUUID');
58
+ }
59
+ });
60
+ }
61
+ }
62
+
63
+ // Handle require('uuid')
64
+ if (node.callee.type === 'Identifier' && node.callee.name === 'require' && ((_node$arguments$ = node.arguments[0]) === null || _node$arguments$ === void 0 ? void 0 : _node$arguments$.type) === 'Literal') {
65
+ const arg = node.arguments[0].value;
66
+ if (typeof arg === 'string' && (arg === 'uuid' || /^uuid\/v[14]$/.test(arg))) {
67
+ context.report({
68
+ node,
69
+ messageId: 'preferCryptoRandomUUID'
70
+ // require() needs manual refactoring
71
+ });
72
+ }
73
+ }
74
+ },
75
+ 'Program:exit'() {
76
+ uuidImports.clear();
77
+ }
78
+ };
79
+ }
80
+ };
81
+ export default rule;
@@ -1,7 +1,7 @@
1
1
  const rule = {
2
2
  meta: {
3
3
  docs: {
4
- 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',
4
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/use-entrypoints-in-examples/README.md',
5
5
  description: 'Encourage usage of package entrypoints in examples.'
6
6
  },
7
7
  messages: {
package/dist/esm/index.js CHANGED
@@ -10,14 +10,12 @@ import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count
10
10
  import ensureAtlassianTeam from './rules/ensure-atlassian-team';
11
11
  import noDuplicateDependencies from './rules/no-duplicate-dependencies';
12
12
  import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
13
- import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
14
13
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
15
14
  import ensureValidBinValues from './rules/ensure-valid-bin-values';
16
15
  import ensureNoPrivateDependencies from './rules/ensure-no-private-dependencies';
17
16
  import expandBorderShorthand from './rules/compiled/expand-border-shorthand';
18
17
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
19
18
  import ensurePublishValid from './rules/ensure-publish-valid';
20
- import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
21
19
  import noModuleLevelEval from './rules/feature-gating/no-module-level-eval';
22
20
  import noModuleLevelEvalNav4 from './rules/feature-gating/no-module-level-eval-nav4';
23
21
  import staticFeatureFlags from './rules/feature-gating/static-feature-flags';
@@ -27,11 +25,18 @@ import preferFG from './rules/feature-gating/prefer-fg';
27
25
  import noAlias from './rules/feature-gating/no-alias';
28
26
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
29
27
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
28
+ import validGateName from './rules/feature-gating/valid-gate-name';
30
29
  import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
31
30
  import expandSpacingShorthand from './rules/compiled/expand-spacing-shorthand';
32
31
  import noSparseCheckout from './rules/no-sparse-checkout';
33
32
  import noDirectDocumentUsage from './rules/no-direct-document-usage';
34
33
  import noSetImmediate from './rules/no-set-immediate';
34
+ import preferCryptoRandomUuid from './rules/prefer-crypto-random-uuid';
35
+ import noBarrelEntryImports from './rules/import/no-barrel-entry-imports';
36
+ import noBarrelEntryJestMock from './rules/import/no-barrel-entry-jest-mock';
37
+ import noJestMockBarrelFiles from './rules/import/no-jest-mock-barrel-files';
38
+ import noRelativeBarrelFileImports from './rules/import/no-relative-barrel-file-imports';
39
+ import noConversationAssistantBarrelImports from './rules/import/no-conversation-assistant-barrel-imports';
35
40
  import { join, normalize } from 'node:path';
36
41
  import { readFileSync } from 'node:fs';
37
42
  var jiraRoot;
@@ -53,7 +58,6 @@ try {
53
58
  var packageJson = require('@atlaskit/eslint-plugin-platform/package.json');
54
59
  var rules = {
55
60
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
56
- 'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
57
61
  'ensure-test-runner-arguments': ensureTestRunnerArguments,
58
62
  'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
59
63
  'ensure-atlassian-team': ensureAtlassianTeam,
@@ -68,7 +72,6 @@ var rules = {
68
72
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
69
73
  'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage,
70
74
  'ensure-publish-valid': ensurePublishValid,
71
- 'ensure-native-and-af-exports-synced': ensureNativeAndAfExportsSynced,
72
75
  'no-module-level-eval': noModuleLevelEval,
73
76
  'no-module-level-eval-nav4': noModuleLevelEvalNav4,
74
77
  'static-feature-flags': staticFeatureFlags,
@@ -78,9 +81,16 @@ var rules = {
78
81
  'no-alias': noAlias,
79
82
  'use-entrypoints-in-examples': useEntrypointsInExamples,
80
83
  'use-recommended-utils': useRecommendedUtils,
84
+ 'valid-gate-name': validGateName,
81
85
  'no-sparse-checkout': noSparseCheckout,
82
86
  'no-direct-document-usage': noDirectDocumentUsage,
83
- 'no-set-immediate': noSetImmediate
87
+ 'no-set-immediate': noSetImmediate,
88
+ 'prefer-crypto-random-uuid': preferCryptoRandomUuid,
89
+ 'no-barrel-entry-imports': noBarrelEntryImports,
90
+ 'no-barrel-entry-jest-mock': noBarrelEntryJestMock,
91
+ 'no-jest-mock-barrel-files': noJestMockBarrelFiles,
92
+ 'no-relative-barrel-file-imports': noRelativeBarrelFileImports,
93
+ 'no-conversation-assistant-barrel-imports': noConversationAssistantBarrelImports
84
94
  };
85
95
  var commonConfig = {
86
96
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
@@ -110,11 +120,9 @@ var recommendedRules = _objectSpread(_objectSpread({}, commonConfig), {}, {
110
120
  '@atlaskit/platform/inline-usage': 'error',
111
121
  '@atlaskit/platform/prefer-fg': 'error',
112
122
  '@atlaskit/platform/no-alias': 'error',
123
+ '@atlaskit/platform/valid-gate-name': 'error',
113
124
  // end: feature-gating rules
114
- '@atlaskit/platform/ensure-feature-flag-registration': 'error',
115
- '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
116
- allowedPrefixes: ['platform.', 'platform_']
117
- }]
125
+ '@atlaskit/platform/ensure-feature-flag-registration': 'error'
118
126
  });
119
127
  var jiraRules = commonConfig;
120
128
  var jsonPrefix = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, @typescript-eslint/semi, no-template-curly-in-string */ module.exports = ';
@@ -1,5 +1,5 @@
1
1
  // List of libraries that we maintain or have worked on
2
2
  // - eg `@atlaskit/feature-gate-js-client` shouldn't be included in here
3
- export var FEATURE_API_IMPORT_SOURCES = new Set(['@atlassian/jira-feature-flagging', '@atlassian/jira-feature-flagging-using-meta', '@atlassian/jira-feature-gating', '@atlassian/jira-feature-experiments', '@atlaskit/platform-feature-flags']);
3
+ export var FEATURE_API_IMPORT_SOURCES = new Set(['@atlassian/jira-feature-flagging', '@atlassian/jira-feature-flagging-using-meta', '@atlassian/jira-feature-gating', '@atlassian/jira-feature-experiments', '@atlaskit/platform-feature-flags', '@atlassian/repo-feature-flags-statsig']);
4
4
  export var FEATURE_MOCKS_IMPORT_SOURCES = new Set(['@atlassian/jira-feature-flagging-mocks', '@atlassian/jira-feature-gates-test-mocks', '@atlassian/jira-feature-gates-storybook-mocks']);
5
5
  export var FEATURE_UTILS_IMPORT_SOURCES = new Set(['@atlassian/jira-feature-flagging-utils', '@atlassian/jira-feature-gate-component']);
@@ -10,11 +10,11 @@ import { getObjectPropertyAsObject } from '../util/handle-ast-object';
10
10
  var DESIRED_PKG_VERSIONS = {
11
11
  typescript: ['5.4', '5.9'],
12
12
  tslib: ['2.6', '2.8'],
13
- '@types/react': ['16.14', '18.2'],
14
- 'react-relay': ['npm:atl-react-relay@0.0.0-main-5980a913'],
15
- 'relay-compiler': ['npm:atl-relay-compiler@0.0.0-main-5980a913'],
16
- 'relay-runtime': ['npm:atl-relay-runtime@0.0.0-main-5980a913'],
17
- 'relay-test-utils': ['npm:atl-relay-test-utils@0.0.0-main-5980a913']
13
+ '@types/react': ['16.14', '18.2', '18.3'],
14
+ 'react-relay': ['npm:atl-react-relay@0.0.0-main-39e79f66'],
15
+ 'relay-compiler': ['npm:atl-relay-compiler@0.0.0-main-39e79f66'],
16
+ 'relay-runtime': ['npm:atl-relay-runtime@0.0.0-main-39e79f66'],
17
+ 'relay-test-utils': ['npm:atl-relay-test-utils@0.0.0-main-39e79f66']
18
18
  };
19
19
  var matchMinorVersion = function matchMinorVersion(desiredVersion, versionInResolutions) {
20
20
  var firstChar = versionInResolutions[0];
@@ -1,5 +1,3 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _regeneratorRuntime from "@babel/runtime/regenerator";
3
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; } } }; }
4
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; } }
5
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; }
@@ -8,11 +6,9 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
8
6
  import { getObjectPropertyAsObject, getObjectPropertyAsLiteral } from '../util/handle-ast-object';
9
7
  import { getPackagesSync } from '@manypkg/get-packages';
10
8
  import { findRootSync } from '@manypkg/find-root';
11
- var root = findRootSync(process.cwd());
12
- var pkgs = getPackagesSync(root).packages;
13
- var pkgMap = new Map(pkgs.map(function (pkg) {
14
- return [pkg.packageJson.name, pkg];
15
- }));
9
+ var root;
10
+ var pkgs;
11
+ var pkgMap;
16
12
  var rule = {
17
13
  meta: {
18
14
  type: 'problem',
@@ -26,70 +22,57 @@ var rule = {
26
22
  }
27
23
  },
28
24
  create: function create(context) {
25
+ if (!context.filename.endsWith('package.json')) {
26
+ return {};
27
+ }
28
+ root !== null && root !== void 0 ? root : root = findRootSync(process.cwd());
29
+ pkgs !== null && pkgs !== void 0 ? pkgs : pkgs = getPackagesSync(root).packages;
30
+ pkgMap !== null && pkgMap !== void 0 ? pkgMap : pkgMap = new Map(pkgs.map(function (pkg) {
31
+ return [pkg.packageJson.name, pkg];
32
+ }));
29
33
  return {
30
- ObjectExpression: function () {
31
- var _ObjectExpression = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(node) {
32
- var isPrivatePkg, dependencies, peerDependencies, _i, _arr, obj, _iterator, _step, p, key, _pkgMap$get, isPrivateDependency;
33
- return _regeneratorRuntime.wrap(function _callee$(_context) {
34
- while (1) switch (_context.prev = _context.next) {
35
- case 0:
36
- if (!(!context.filename.endsWith('package.json') || node.type !== 'ObjectExpression')) {
37
- _context.next = 2;
38
- break;
39
- }
40
- return _context.abrupt("return");
41
- case 2:
42
- // Private dependencies can be used in private packages
43
- isPrivatePkg = getObjectPropertyAsLiteral(node, 'private') === true;
44
- if (!(isPrivatePkg === true)) {
45
- _context.next = 5;
46
- break;
47
- }
48
- return _context.abrupt("return");
49
- case 5:
50
- // Check for private dependencies in dependencies and peerDependencies
51
- // Note: devDependencies are not checked here as they don't end up in consumer lockfiles
52
- dependencies = getObjectPropertyAsObject(node, 'dependencies');
53
- peerDependencies = getObjectPropertyAsObject(node, 'peerDependencies');
54
- for (_i = 0, _arr = [dependencies, peerDependencies]; _i < _arr.length; _i++) {
55
- obj = _arr[_i];
56
- _iterator = _createForOfIteratorHelper((obj === null || obj === void 0 ? void 0 : obj.properties) || []);
57
- try {
58
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
59
- p = _step.value;
60
- if (p.type === 'Property' && p.key.type === 'Literal') {
61
- key = p.key.value;
62
- if (typeof key === 'string' && pkgMap.has(key)) {
63
- isPrivateDependency = ((_pkgMap$get = pkgMap.get(key)) === null || _pkgMap$get === void 0 ? void 0 : _pkgMap$get.packageJson.private) === true;
64
- if (isPrivateDependency) {
65
- context.report({
66
- node: node,
67
- messageId: 'invalidPrivateDependency',
68
- data: {
69
- pkgName: key
70
- }
71
- });
72
- }
73
- }
34
+ ObjectExpression: function ObjectExpression(node) {
35
+ // Private dependencies can be used in private packages
36
+ var isPrivatePkg = getObjectPropertyAsLiteral(node, 'private') === true;
37
+ if (isPrivatePkg === true) {
38
+ return;
39
+ }
40
+
41
+ // Check for private dependencies in dependencies and peerDependencies
42
+ // Note: devDependencies are not checked here as they don't end up in consumer lockfiles
43
+ var dependencies = getObjectPropertyAsObject(node, 'dependencies');
44
+ var peerDependencies = getObjectPropertyAsObject(node, 'peerDependencies');
45
+ for (var _i = 0, _arr = [dependencies, peerDependencies]; _i < _arr.length; _i++) {
46
+ var obj = _arr[_i];
47
+ var _iterator = _createForOfIteratorHelper((obj === null || obj === void 0 ? void 0 : obj.properties) || []),
48
+ _step;
49
+ try {
50
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
51
+ var p = _step.value;
52
+ if (p.type === 'Property' && p.key.type === 'Literal') {
53
+ var key = p.key.value;
54
+ if (typeof key === 'string' && pkgMap.has(key)) {
55
+ var _pkgMap$get;
56
+ var isPrivateDependency = ((_pkgMap$get = pkgMap.get(key)) === null || _pkgMap$get === void 0 ? void 0 : _pkgMap$get.packageJson.private) === true;
57
+ if (isPrivateDependency) {
58
+ context.report({
59
+ node: node,
60
+ messageId: 'invalidPrivateDependency',
61
+ data: {
62
+ pkgName: key
74
63
  }
75
- }
76
- } catch (err) {
77
- _iterator.e(err);
78
- } finally {
79
- _iterator.f();
64
+ });
80
65
  }
81
66
  }
82
- case 8:
83
- case "end":
84
- return _context.stop();
67
+ }
85
68
  }
86
- }, _callee);
87
- }));
88
- function ObjectExpression(_x) {
89
- return _ObjectExpression.apply(this, arguments);
69
+ } catch (err) {
70
+ _iterator.e(err);
71
+ } finally {
72
+ _iterator.f();
73
+ }
90
74
  }
91
- return ObjectExpression;
92
- }()
75
+ }
93
76
  };
94
77
  }
95
78
  };
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import { isAPIimport } from '../utils';
3
- var FUNCTION_NAMES = new Set(['ff', 'fg', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp']);
4
- var STATSIG_ONLY_FUNCTION_NAMES = new Set(['fg', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp']);
3
+ var FUNCTION_NAMES = new Set(['checkGate', 'ff', 'fg', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp']);
4
+ var STATSIG_ONLY_FUNCTION_NAMES = new Set(['checkGate', 'fg', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp']);
5
5
  var _findDefinitionDeclaration = function findDefinitionDeclaration(node) {
6
6
  return node.type === 'VariableDeclaration' || node.type === 'FunctionDeclaration' ? node : _findDefinitionDeclaration(node.parent);
7
7
  };
@@ -30,6 +30,12 @@ var validateBinaryExpression = function validateBinaryExpression(node, context)
30
30
  }
31
31
  }
32
32
  };
33
+ var validateAwaitExpression = function validateAwaitExpression(node, context) {
34
+ if (node.argument.type === 'CallExpression') {
35
+ return validateCallExpression(node.argument, context);
36
+ }
37
+ return false;
38
+ };
33
39
  var validateReturnExpression = function validateReturnExpression(_ref, context) {
34
40
  var body = _ref.body;
35
41
  if (body.length !== 1) {
@@ -41,6 +47,8 @@ var validateReturnExpression = function validateReturnExpression(_ref, context)
41
47
  var argument = statement.argument;
42
48
  if (argument && argument.type === 'CallExpression') {
43
49
  validateCallExpression(argument, context);
50
+ } else if (argument && argument.type === 'AwaitExpression') {
51
+ validateAwaitExpression(argument, context);
44
52
  } else if (argument && argument.type === 'BinaryExpression') {
45
53
  validateBinaryExpression(argument, context);
46
54
  }
@@ -51,6 +59,9 @@ var validateFunctionBody = function validateFunctionBody(body, context) {
51
59
  case 'CallExpression':
52
60
  validateCallExpression(body, context);
53
61
  break;
62
+ case 'AwaitExpression':
63
+ validateAwaitExpression(body, context);
64
+ break;
54
65
  case 'BinaryExpression':
55
66
  validateBinaryExpression(body, context);
56
67
  break;
@@ -65,7 +76,7 @@ var rule = {
65
76
  type: 'problem',
66
77
  docs: {
67
78
  description: 'Ensure feature flags/gates and experiments are inlined so that they can be statically analyzable.',
68
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/inline-usage/README.md'
79
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/inline-usage/README.md'
69
80
  },
70
81
  schema: [{
71
82
  enum: ['ssOnly']
@@ -5,7 +5,7 @@ var IMPORT_SOURCES = new Set([].concat(_toConsumableArray(FEATURE_API_IMPORT_SOU
5
5
  var rule = {
6
6
  meta: {
7
7
  docs: {
8
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/no-alias/README.md',
8
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/no-alias/README.md',
9
9
  description: 'Disallow aliasing of feature flag utils to ensure feature flag usage is statically analyzable'
10
10
  },
11
11
  messages: {
@@ -18,7 +18,7 @@ var rule = {
18
18
  meta: {
19
19
  docs: {
20
20
  description: 'Disallow feature flag usage at module level',
21
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/no-module-level-eval/README.md'
21
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/no-module-level-eval/README.md'
22
22
  },
23
23
  messages: {
24
24
  noModuleLevelEval: 'Do not evaluate feature flags in the module level, it will always resolve to false when server side rendered or when flags are loaded async.'
@@ -29,7 +29,7 @@ var rule = {
29
29
  meta: {
30
30
  docs: {
31
31
  description: 'Disallow getWillShowNav4 or isVisualRefreshEnabled usage at module level',
32
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/no-module-level-eval-nav4/README.md'
32
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/no-module-level-eval-nav4/README.md'
33
33
  },
34
34
  messages: {
35
35
  noModuleLevelEval: 'Do not evaluate getWillShowNav4 or isVisualRefreshEnabled at module level. This causes complications with SSR. If feature flagging components in `jira` use `componentWithCondition` from `@atlassian/jira-feature-flagging-utils`.'
@@ -10,6 +10,9 @@ var _getGateType = function getGateType(node, context) {
10
10
  if (type === 'BinaryExpression') {
11
11
  return _getGateType(node.left, context) || _getGateType(node.right, context);
12
12
  }
13
+ if (type === 'AwaitExpression') {
14
+ return _getGateType(node.argument, context);
15
+ }
13
16
  if (node.type === 'CallExpression') {
14
17
  var callee = node.callee;
15
18
  var isFeatureGate = type === 'CallExpression' && callee.type === 'Identifier' && (
@@ -46,7 +49,7 @@ var rule = {
46
49
  meta: {
47
50
  docs: {
48
51
  description: 'Inform on how to use gates and experiments in logical expressions',
49
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/no-preconditioning/README.md'
52
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/no-preconditioning/README.md'
50
53
  },
51
54
  messages: {
52
55
  useConfig: 'Do not precondition gates or experiments with another gate. Configure this in Statsig instead to reduce unnecessary code, simplify cleanup and to ensure accurate exposures in Statsig.',
@@ -47,7 +47,7 @@ var validateUsage = function validateUsage(node, utilName, context, changeMap) {
47
47
  var rule = {
48
48
  meta: {
49
49
  docs: {
50
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/prefer-fg/README.md',
50
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/prefer-fg/README.md',
51
51
  description: 'Keep usages of boolean feature flags consistent'
52
52
  },
53
53
  fixable: 'code',
@@ -4,13 +4,13 @@ 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
 
6
6
  // Any functions not in this list should be skipped for performance.
7
- var FUNCTION_NAMES = new Set(['ff', 'fg', 'getFeatureFlagValue', 'getMultivariateFeatureFlag', 'componentWithFF', 'componentWithFG', 'passGate', 'withGate', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp', 'mockExp', 'withExp', 'wasExperimentManuallyExposed']);
7
+ var FUNCTION_NAMES = new Set(['ff', 'fg', 'getFeatureFlagValue', 'componentWithFF', 'componentWithFG', 'passGate', 'withGate', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp', 'mockExp', 'withExp', 'wasExperimentManuallyExposed']);
8
8
  var STATSIG_ONLY_FUNCTION_NAMES = new Set(['fg', 'componentWithFG', 'passGate', 'withGate', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp', 'mockExp', 'withExp', 'wasExperimentManuallyExposed']);
9
9
  var rule = {
10
10
  meta: {
11
11
  type: 'problem',
12
12
  docs: {
13
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/static-feature-flags/README.md',
13
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/static-feature-flags/README.md',
14
14
  description: 'Ensure feature flags or gates are static string literals'
15
15
  },
16
16
  fixable: 'code',
@@ -3,7 +3,7 @@ var BANNED_IMPORTS_SET = new Set(['@atlaskit/feature-gate-js-client']);
3
3
  var rule = {
4
4
  meta: {
5
5
  docs: {
6
- url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/use-recommended-utils/README.md',
6
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/use-recommended-utils/README.md',
7
7
  description: 'Prefer using the feature flag abstraction over direct statsig library.'
8
8
  },
9
9
  messages: {
@@ -0,0 +1,53 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { FEATURE_API_IMPORT_SOURCES } from '../../constants';
3
+ import { isIdentifierImportedFrom } from '../utils';
4
+ var IMPORT_SOURCES = new Set([].concat(_toConsumableArray(FEATURE_API_IMPORT_SOURCES), ['@atlassian/jira-feature-flagging-utils', '@atlassian/jira-feature-gate-component']));
5
+ var FUNCTION_NAMES = new Set(['ff', 'fg', 'getFeatureFlagValue', 'componentWithFF', 'componentWithFG', 'passGate', 'withGate', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp', 'mockExp', 'withExp', 'wasExperimentManuallyExposed']);
6
+
7
+ /**
8
+ * Valid gate names must only contain lowercase letters (a-z), numbers (0-9),
9
+ * underscores (_), hyphens (-), and dots (.).
10
+ * No spaces, capital letters, or other characters are allowed.
11
+ */
12
+ var VALID_GATE_NAME_PATTERN = /^[a-z0-9_.-]+$/;
13
+ function isValidGateName(name) {
14
+ return VALID_GATE_NAME_PATTERN.test(name);
15
+ }
16
+ var rule = {
17
+ meta: {
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'Ensure feature gate names contain only lowercase letters, numbers, underscores, and hyphens'
21
+ },
22
+ messages: {
23
+ invalidGateName: 'Feature gate name "{{name}}" is invalid. Gate names must contain only lowercase letters (a-z), numbers (0-9), underscores (_), hyphens (-), and dots (.).'
24
+ }
25
+ },
26
+ create: function create(context) {
27
+ return {
28
+ 'CallExpression[callee.type="Identifier"][arguments.length>0][arguments.0.type="Literal"]': function CallExpressionCalleeTypeIdentifierArgumentsLength0Arguments0TypeLiteral(node) {
29
+ if (node.type !== 'CallExpression') {
30
+ return;
31
+ }
32
+ if (node.callee.type === 'Identifier' && (!FUNCTION_NAMES.has(node.callee.name) || !isIdentifierImportedFrom(node.callee.name, IMPORT_SOURCES, context, node))) {
33
+ return;
34
+ }
35
+ var nameArgument = node.arguments[0];
36
+ if (nameArgument.type !== 'Literal' || typeof nameArgument.value !== 'string') {
37
+ return;
38
+ }
39
+ var gateName = nameArgument.value;
40
+ if (!isValidGateName(gateName)) {
41
+ context.report({
42
+ node: nameArgument,
43
+ messageId: 'invalidGateName',
44
+ data: {
45
+ name: gateName
46
+ }
47
+ });
48
+ }
49
+ }
50
+ };
51
+ }
52
+ };
53
+ export default rule;