@atlaskit/eslint-plugin-platform 2.7.2 → 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 (75) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/index.js +14 -3
  3. package/dist/cjs/rules/feature-gating/valid-gate-name/index.js +60 -0
  4. package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +871 -0
  5. package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +1384 -0
  6. package/dist/cjs/rules/import/no-conversation-assistant-barrel-imports/index.js +43 -0
  7. package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +1401 -0
  8. package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +777 -0
  9. package/dist/cjs/rules/import/shared/barrel-parsing.js +511 -0
  10. package/dist/cjs/rules/import/shared/file-system.js +186 -0
  11. package/dist/cjs/rules/import/shared/jest-utils.js +191 -0
  12. package/dist/cjs/rules/import/shared/package-registry.js +263 -0
  13. package/dist/cjs/rules/import/shared/package-resolution.js +185 -0
  14. package/dist/cjs/rules/import/shared/perf.js +89 -0
  15. package/dist/cjs/rules/import/shared/types.js +67 -0
  16. package/dist/es2019/index.js +14 -3
  17. package/dist/es2019/rules/feature-gating/valid-gate-name/index.js +52 -0
  18. package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +801 -0
  19. package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +1113 -0
  20. package/dist/es2019/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  21. package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +1179 -0
  22. package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +738 -0
  23. package/dist/es2019/rules/import/shared/barrel-parsing.js +433 -0
  24. package/dist/es2019/rules/import/shared/file-system.js +174 -0
  25. package/dist/es2019/rules/import/shared/jest-utils.js +159 -0
  26. package/dist/es2019/rules/import/shared/package-registry.js +240 -0
  27. package/dist/es2019/rules/import/shared/package-resolution.js +161 -0
  28. package/dist/es2019/rules/import/shared/perf.js +83 -0
  29. package/dist/es2019/rules/import/shared/types.js +57 -0
  30. package/dist/esm/index.js +14 -3
  31. package/dist/esm/rules/feature-gating/valid-gate-name/index.js +53 -0
  32. package/dist/esm/rules/import/no-barrel-entry-imports/index.js +864 -0
  33. package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +1375 -0
  34. package/dist/esm/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  35. package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +1391 -0
  36. package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +770 -0
  37. package/dist/esm/rules/import/shared/barrel-parsing.js +500 -0
  38. package/dist/esm/rules/import/shared/file-system.js +176 -0
  39. package/dist/esm/rules/import/shared/jest-utils.js +179 -0
  40. package/dist/esm/rules/import/shared/package-registry.js +256 -0
  41. package/dist/esm/rules/import/shared/package-resolution.js +175 -0
  42. package/dist/esm/rules/import/shared/perf.js +80 -0
  43. package/dist/esm/rules/import/shared/types.js +61 -0
  44. package/dist/types/index.d.ts +16 -2
  45. package/dist/types/rules/feature-gating/valid-gate-name/index.d.ts +3 -0
  46. package/dist/types/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  47. package/dist/types/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  48. package/dist/types/rules/import/no-conversation-assistant-barrel-imports/index.d.ts +3 -0
  49. package/dist/types/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  50. package/dist/types/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  51. package/dist/types/rules/import/shared/barrel-parsing.d.ts +30 -0
  52. package/dist/types/rules/import/shared/file-system.d.ts +38 -0
  53. package/dist/types/rules/import/shared/jest-utils.d.ts +47 -0
  54. package/dist/types/rules/import/shared/package-registry.d.ts +26 -0
  55. package/dist/types/rules/import/shared/package-resolution.d.ts +38 -0
  56. package/dist/types/rules/import/shared/perf.d.ts +13 -0
  57. package/dist/types/rules/import/shared/types.d.ts +131 -0
  58. package/dist/types-ts4.5/index.d.ts +16 -2
  59. package/dist/types-ts4.5/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  60. package/dist/types-ts4.5/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  61. package/dist/types-ts4.5/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  62. package/dist/types-ts4.5/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  63. package/dist/types-ts4.5/rules/import/shared/barrel-parsing.d.ts +30 -0
  64. package/dist/types-ts4.5/rules/import/shared/file-system.d.ts +38 -0
  65. package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +47 -0
  66. package/dist/types-ts4.5/rules/import/shared/package-registry.d.ts +26 -0
  67. package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +38 -0
  68. package/dist/types-ts4.5/rules/import/shared/perf.d.ts +13 -0
  69. package/dist/types-ts4.5/rules/import/shared/types.d.ts +131 -0
  70. package/package.json +4 -2
  71. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +0 -158
  72. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +0 -146
  73. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +0 -151
  74. /package/dist/types-ts4.5/rules/{ensure-native-and-af-exports-synced → feature-gating/valid-gate-name}/index.d.ts +0 -0
  75. /package/dist/{types/rules/ensure-native-and-af-exports-synced → types-ts4.5/rules/import/no-conversation-assistant-barrel-imports}/index.d.ts +0 -0
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PERF_ENV_VAR = void 0;
7
+ exports.isPerfEnabled = isPerfEnabled;
8
+ exports.perfInc = perfInc;
9
+ exports.perfTime = perfTime;
10
+ var PERF_ENV_VAR = exports.PERF_ENV_VAR = 'INTERNAL_ESLINT_BARREL_PERF';
11
+ function nowMs() {
12
+ // eslint-disable-next-line no-restricted-globals
13
+ return typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();
14
+ }
15
+ function isPerfEnabled() {
16
+ return process.env[PERF_ENV_VAR] === '1' || process.env[PERF_ENV_VAR] === 'true';
17
+ }
18
+ function ensurePerfInitialized(_ref) {
19
+ var fs = _ref.fs;
20
+ if (!fs.cache.perf) {
21
+ fs.cache.perf = {
22
+ installedExitHook: false,
23
+ counters: {},
24
+ timers: {}
25
+ };
26
+ }
27
+ }
28
+ function ensureExitHookInstalled(_ref2) {
29
+ var fs = _ref2.fs;
30
+ if (!isPerfEnabled()) {
31
+ return;
32
+ }
33
+ ensurePerfInitialized({
34
+ fs: fs
35
+ });
36
+ if (fs.cache.perf.installedExitHook) {
37
+ return;
38
+ }
39
+ fs.cache.perf.installedExitHook = true;
40
+ // eslint-disable-next-line no-console
41
+ console.error("[eslint-plugin-internal] perf enabled via ".concat(PERF_ENV_VAR));
42
+ process.once('exit', function () {
43
+ var _fs$cache$perf$counte, _fs$cache$perf, _fs$cache$perf$timers, _fs$cache$perf2;
44
+ // eslint-disable-next-line no-console
45
+ console.error("[eslint-plugin-internal] perf exit hook fired (".concat(PERF_ENV_VAR, ")"));
46
+ // eslint-disable-next-line no-console
47
+ console.log("[eslint-plugin-internal] perf summary (".concat(PERF_ENV_VAR, ")"));
48
+ // eslint-disable-next-line no-console
49
+ console.log(JSON.stringify({
50
+ counters: (_fs$cache$perf$counte = (_fs$cache$perf = fs.cache.perf) === null || _fs$cache$perf === void 0 ? void 0 : _fs$cache$perf.counters) !== null && _fs$cache$perf$counte !== void 0 ? _fs$cache$perf$counte : {},
51
+ timers: (_fs$cache$perf$timers = (_fs$cache$perf2 = fs.cache.perf) === null || _fs$cache$perf2 === void 0 ? void 0 : _fs$cache$perf2.timers) !== null && _fs$cache$perf$timers !== void 0 ? _fs$cache$perf$timers : {}
52
+ }, null, 2));
53
+ });
54
+ }
55
+ function perfInc(_ref3) {
56
+ var _perf$counters$key;
57
+ var fs = _ref3.fs,
58
+ key = _ref3.key,
59
+ _ref3$by = _ref3.by,
60
+ by = _ref3$by === void 0 ? 1 : _ref3$by;
61
+ if (!isPerfEnabled()) {
62
+ return;
63
+ }
64
+ ensureExitHookInstalled({
65
+ fs: fs
66
+ });
67
+ var perf = fs.cache.perf;
68
+ perf.counters[key] = ((_perf$counters$key = perf.counters[key]) !== null && _perf$counters$key !== void 0 ? _perf$counters$key : 0) + by;
69
+ }
70
+ function perfTime(_ref4) {
71
+ var fs = _ref4.fs,
72
+ key = _ref4.key,
73
+ fn = _ref4.fn;
74
+ if (!isPerfEnabled()) {
75
+ return fn();
76
+ }
77
+ ensureExitHookInstalled({
78
+ fs: fs
79
+ });
80
+ var perf = fs.cache.perf;
81
+ var start = nowMs();
82
+ try {
83
+ return fn();
84
+ } finally {
85
+ var _perf$timers$key;
86
+ var duration = nowMs() - start;
87
+ perf.timers[key] = ((_perf$timers$key = perf.timers[key]) !== null && _perf$timers$key !== void 0 ? _perf$timers$key : 0) + duration;
88
+ }
89
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.realFileSystem = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _child_process = require("child_process");
10
+ var _fs = require("fs");
11
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
+ /**
14
+ * Directory entry returned by readdirSync with withFileTypes option.
15
+ */
16
+
17
+ /**
18
+ * State for the package registry cache.
19
+ * This is used to cache package name to directory mappings for efficient lookups.
20
+ */
21
+
22
+ /**
23
+ * Cache structure for file system operations.
24
+ * Contains both package registry cache and workspace root cache.
25
+ */
26
+
27
+ /**
28
+ * File system abstraction for testability.
29
+ * This interface allows the core logic to be tested with mock file systems.
30
+ * The cache property holds package resolution state and can be passed as an empty
31
+ * object for tests to ensure fresh state for each test case.
32
+ */
33
+
34
+ /**
35
+ * Real file system implementation using Node.js fs module.
36
+ */
37
+ var realFileSystem = exports.realFileSystem = {
38
+ existsSync: _fs.existsSync,
39
+ readFileSync: _fs.readFileSync,
40
+ realpathSync: _fs.realpathSync,
41
+ statSync: _fs.statSync,
42
+ readdirSync: function readdirSync(path, options) {
43
+ return (0, _fs.readdirSync)(path, options);
44
+ },
45
+ execSync: function execSync(command, options) {
46
+ try {
47
+ return (0, _child_process.execSync)(command, _objectSpread(_objectSpread({}, options), {}, {
48
+ encoding: 'utf-8'
49
+ })).trim();
50
+ } catch (_unused) {
51
+ return null;
52
+ }
53
+ },
54
+ cache: {}
55
+ };
56
+
57
+ /**
58
+ * Information about cross-package re-export origin.
59
+ */
60
+
61
+ /**
62
+ * Information about where an export originates.
63
+ */
64
+
65
+ /**
66
+ * Context for package resolution operations.
67
+ */
@@ -13,7 +13,6 @@ import ensureNoPrivateDependencies from './rules/ensure-no-private-dependencies'
13
13
  import expandBorderShorthand from './rules/compiled/expand-border-shorthand';
14
14
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
15
15
  import ensurePublishValid from './rules/ensure-publish-valid';
16
- import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
17
16
  import noModuleLevelEval from './rules/feature-gating/no-module-level-eval';
18
17
  import noModuleLevelEvalNav4 from './rules/feature-gating/no-module-level-eval-nav4';
19
18
  import staticFeatureFlags from './rules/feature-gating/static-feature-flags';
@@ -23,12 +22,18 @@ import preferFG from './rules/feature-gating/prefer-fg';
23
22
  import noAlias from './rules/feature-gating/no-alias';
24
23
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
25
24
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
25
+ import validGateName from './rules/feature-gating/valid-gate-name';
26
26
  import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
27
27
  import expandSpacingShorthand from './rules/compiled/expand-spacing-shorthand';
28
28
  import noSparseCheckout from './rules/no-sparse-checkout';
29
29
  import noDirectDocumentUsage from './rules/no-direct-document-usage';
30
30
  import noSetImmediate from './rules/no-set-immediate';
31
31
  import preferCryptoRandomUuid from './rules/prefer-crypto-random-uuid';
32
+ import noBarrelEntryImports from './rules/import/no-barrel-entry-imports';
33
+ import noBarrelEntryJestMock from './rules/import/no-barrel-entry-jest-mock';
34
+ import noJestMockBarrelFiles from './rules/import/no-jest-mock-barrel-files';
35
+ import noRelativeBarrelFileImports from './rules/import/no-relative-barrel-file-imports';
36
+ import noConversationAssistantBarrelImports from './rules/import/no-conversation-assistant-barrel-imports';
32
37
  import { join, normalize } from 'node:path';
33
38
  import { readFileSync } from 'node:fs';
34
39
  let jiraRoot;
@@ -64,7 +69,6 @@ const rules = {
64
69
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
65
70
  'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage,
66
71
  'ensure-publish-valid': ensurePublishValid,
67
- 'ensure-native-and-af-exports-synced': ensureNativeAndAfExportsSynced,
68
72
  'no-module-level-eval': noModuleLevelEval,
69
73
  'no-module-level-eval-nav4': noModuleLevelEvalNav4,
70
74
  'static-feature-flags': staticFeatureFlags,
@@ -74,10 +78,16 @@ const rules = {
74
78
  'no-alias': noAlias,
75
79
  'use-entrypoints-in-examples': useEntrypointsInExamples,
76
80
  'use-recommended-utils': useRecommendedUtils,
81
+ 'valid-gate-name': validGateName,
77
82
  'no-sparse-checkout': noSparseCheckout,
78
83
  'no-direct-document-usage': noDirectDocumentUsage,
79
84
  'no-set-immediate': noSetImmediate,
80
- 'prefer-crypto-random-uuid': preferCryptoRandomUuid
85
+ 'prefer-crypto-random-uuid': preferCryptoRandomUuid,
86
+ 'no-barrel-entry-imports': noBarrelEntryImports,
87
+ 'no-barrel-entry-jest-mock': noBarrelEntryJestMock,
88
+ 'no-jest-mock-barrel-files': noJestMockBarrelFiles,
89
+ 'no-relative-barrel-file-imports': noRelativeBarrelFileImports,
90
+ 'no-conversation-assistant-barrel-imports': noConversationAssistantBarrelImports
81
91
  };
82
92
  const commonConfig = {
83
93
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
@@ -108,6 +118,7 @@ const recommendedRules = {
108
118
  '@atlaskit/platform/inline-usage': 'error',
109
119
  '@atlaskit/platform/prefer-fg': 'error',
110
120
  '@atlaskit/platform/no-alias': 'error',
121
+ '@atlaskit/platform/valid-gate-name': 'error',
111
122
  // end: feature-gating rules
112
123
  '@atlaskit/platform/ensure-feature-flag-registration': 'error'
113
124
  };
@@ -0,0 +1,52 @@
1
+ import { FEATURE_API_IMPORT_SOURCES } from '../../constants';
2
+ import { isIdentifierImportedFrom } from '../utils';
3
+ const IMPORT_SOURCES = new Set([...FEATURE_API_IMPORT_SOURCES, '@atlassian/jira-feature-flagging-utils', '@atlassian/jira-feature-gate-component']);
4
+ const FUNCTION_NAMES = new Set(['ff', 'fg', 'getFeatureFlagValue', 'componentWithFF', 'componentWithFG', 'passGate', 'withGate', 'expVal', 'expValEquals', 'UNSAFE_noExposureExp', 'mockExp', 'withExp', 'wasExperimentManuallyExposed']);
5
+
6
+ /**
7
+ * Valid gate names must only contain lowercase letters (a-z), numbers (0-9),
8
+ * underscores (_), hyphens (-), and dots (.).
9
+ * No spaces, capital letters, or other characters are allowed.
10
+ */
11
+ const VALID_GATE_NAME_PATTERN = /^[a-z0-9_.-]+$/;
12
+ function isValidGateName(name) {
13
+ return VALID_GATE_NAME_PATTERN.test(name);
14
+ }
15
+ const rule = {
16
+ meta: {
17
+ type: 'problem',
18
+ docs: {
19
+ description: 'Ensure feature gate names contain only lowercase letters, numbers, underscores, and hyphens'
20
+ },
21
+ messages: {
22
+ invalidGateName: 'Feature gate name "{{name}}" is invalid. Gate names must contain only lowercase letters (a-z), numbers (0-9), underscores (_), hyphens (-), and dots (.).'
23
+ }
24
+ },
25
+ create(context) {
26
+ return {
27
+ 'CallExpression[callee.type="Identifier"][arguments.length>0][arguments.0.type="Literal"]': node => {
28
+ if (node.type !== 'CallExpression') {
29
+ return;
30
+ }
31
+ if (node.callee.type === 'Identifier' && (!FUNCTION_NAMES.has(node.callee.name) || !isIdentifierImportedFrom(node.callee.name, IMPORT_SOURCES, context, node))) {
32
+ return;
33
+ }
34
+ const nameArgument = node.arguments[0];
35
+ if (nameArgument.type !== 'Literal' || typeof nameArgument.value !== 'string') {
36
+ return;
37
+ }
38
+ const gateName = nameArgument.value;
39
+ if (!isValidGateName(gateName)) {
40
+ context.report({
41
+ node: nameArgument,
42
+ messageId: 'invalidGateName',
43
+ data: {
44
+ name: gateName
45
+ }
46
+ });
47
+ }
48
+ }
49
+ };
50
+ }
51
+ };
52
+ export default rule;