@atlaskit/eslint-plugin-platform 0.7.3 → 0.7.5

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 (30) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/index.js +4 -3
  3. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +0 -3
  4. package/dist/cjs/rules/no-duplicate-dependencies/index.js +3 -3
  5. package/dist/cjs/rules/no-module-level-eval-nav4/index.js +56 -0
  6. package/dist/cjs/rules/utils.js +3 -3
  7. package/dist/es2019/index.js +4 -3
  8. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +0 -3
  9. package/dist/es2019/rules/no-module-level-eval-nav4/index.js +50 -0
  10. package/dist/esm/index.js +4 -3
  11. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +0 -3
  12. package/dist/esm/rules/no-duplicate-dependencies/index.js +3 -3
  13. package/dist/esm/rules/no-module-level-eval-nav4/index.js +50 -0
  14. package/dist/esm/rules/utils.js +3 -3
  15. package/dist/types/index.d.ts +2 -1
  16. package/dist/types-ts4.5/index.d.ts +2 -1
  17. package/index.js +1 -1
  18. package/package.json +6 -5
  19. package/src/index.tsx +7 -3
  20. package/src/rules/ensure-native-and-af-exports-synced/index.tsx +0 -3
  21. package/src/rules/no-module-level-eval-nav4/README.md +8 -0
  22. package/src/rules/no-module-level-eval-nav4/__tests__/test.tsx +130 -0
  23. package/src/rules/no-module-level-eval-nav4/index.tsx +72 -0
  24. package/dist/cjs/rules/ensure-valid-emotion-css-prop/index.js +0 -91
  25. package/dist/es2019/rules/ensure-valid-emotion-css-prop/index.js +0 -87
  26. package/dist/esm/rules/ensure-valid-emotion-css-prop/index.js +0 -85
  27. package/src/rules/ensure-valid-emotion-css-prop/__tests__/unit/rule.test.ts +0 -142
  28. package/src/rules/ensure-valid-emotion-css-prop/index.ts +0 -96
  29. /package/dist/types/rules/{ensure-valid-emotion-css-prop → no-module-level-eval-nav4}/index.d.ts +0 -0
  30. /package/dist/types-ts4.5/rules/{ensure-valid-emotion-css-prop → no-module-level-eval-nav4}/index.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/eslint-plugin-platform
2
2
 
3
+ ## 0.7.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#131612](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/131612)
8
+ [`898640d108441`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/898640d108441) -
9
+ Add other nav4 functions to the lint rule for no-module-level-eval-nav4
10
+
11
+ ## 0.7.4
12
+
13
+ ### Patch Changes
14
+
15
+ - [#141306](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/141306)
16
+ [`afce5e7baf293`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/afce5e7baf293) -
17
+ Addition of feature-flags/no-module-level-eval-nav4 eslint rule
18
+
3
19
  ## 0.7.3
4
20
 
5
21
  ### Patch Changes
package/dist/cjs/index.js CHANGED
@@ -15,11 +15,11 @@ var _noDuplicateDependencies = _interopRequireDefault(require("./rules/no-duplic
15
15
  var _noInvalidFeatureFlagUsage = _interopRequireDefault(require("./rules/no-invalid-feature-flag-usage"));
16
16
  var _ensureFeatureFlagPrefix = _interopRequireDefault(require("./rules/ensure-feature-flag-prefix"));
17
17
  var _ensureCriticalDependencyResolutions = _interopRequireDefault(require("./rules/ensure-critical-dependency-resolutions"));
18
- var _ensureValidEmotionCssProp = _interopRequireDefault(require("./rules/ensure-valid-emotion-css-prop"));
19
18
  var _noInvalidStorybookDecoratorUsage = _interopRequireDefault(require("./rules/no-invalid-storybook-decorator-usage"));
20
19
  var _ensurePublishValid = _interopRequireDefault(require("./rules/ensure-publish-valid"));
21
20
  var _ensureNativeAndAfExportsSynced = _interopRequireDefault(require("./rules/ensure-native-and-af-exports-synced"));
22
21
  var _noModuleLevelEval = _interopRequireDefault(require("./rules/no-module-level-eval"));
22
+ var _noModuleLevelEvalNav = _interopRequireDefault(require("./rules/no-module-level-eval-nav4"));
23
23
  var _staticFeatureFlags = _interopRequireDefault(require("./rules/static-feature-flags"));
24
24
  var _noPreconditioning = _interopRequireDefault(require("./rules/no-preconditioning"));
25
25
  var _inlineUsage = _interopRequireDefault(require("./rules/inline-usage"));
@@ -35,7 +35,6 @@ var rules = exports.rules = {
35
35
  'ensure-test-runner-nested-count': _ensureTestRunnerNestedCount.default,
36
36
  'ensure-atlassian-team': _ensureAtlassianTeam.default,
37
37
  'ensure-critical-dependency-resolutions': _ensureCriticalDependencyResolutions.default,
38
- 'ensure-valid-emotion-css-prop': _ensureValidEmotionCssProp.default,
39
38
  'no-duplicate-dependencies': _noDuplicateDependencies.default,
40
39
  'no-invalid-feature-flag-usage': _noInvalidFeatureFlagUsage.default,
41
40
  'no-pre-post-install-scripts': _noPrePostInstalls.default,
@@ -43,6 +42,7 @@ var rules = exports.rules = {
43
42
  'ensure-publish-valid': _ensurePublishValid.default,
44
43
  'ensure-native-and-af-exports-synced': _ensureNativeAndAfExportsSynced.default,
45
44
  'no-module-level-eval': _noModuleLevelEval.default,
45
+ 'no-module-level-eval-nav4': _noModuleLevelEvalNav.default,
46
46
  'static-feature-flags': _staticFeatureFlags.default,
47
47
  'no-preconditioning': _noPreconditioning.default,
48
48
  'inline-usage': _inlineUsage.default,
@@ -56,7 +56,7 @@ var configs = exports.configs = {
56
56
  rules: {
57
57
  '@atlaskit/platform/ensure-feature-flag-registration': 'error',
58
58
  '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
59
- allowedPrefixes: ['platform.']
59
+ allowedPrefixes: ['platform.', 'platform_']
60
60
  }],
61
61
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
62
62
  '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
@@ -64,6 +64,7 @@ var configs = exports.configs = {
64
64
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
65
65
  '@atlaskit/platform/ensure-atlassian-team': 'error',
66
66
  '@atlaskit/platform/no-module-level-eval': 'error',
67
+ '@atlaskit/platform/no-module-level-eval-nav4': 'error',
67
68
  '@atlaskit/platform/static-feature-flags': 'error',
68
69
  '@atlaskit/platform/no-preconditioning': 'error',
69
70
  '@atlaskit/platform/inline-usage': 'error',
@@ -13,9 +13,6 @@ var _registrationUtils = require("../util/registration-utils");
13
13
  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; }
14
14
  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; }
15
15
  var exportsValidationExceptions = {
16
- '@atlassian/sizemap': {
17
- ignoredAfExportKeys: ['.', './lmdb-cache-manager']
18
- },
19
16
  '@atlaskit/tokens': {
20
17
  ignoredAfExportKeys: ['./babel-plugin']
21
18
  },
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
10
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
11
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
+ 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; } } }; }
10
+ 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; } }
11
+ 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; }
12
12
  // eslint-disable-next-line import/no-extraneous-dependencies
13
13
 
14
14
  var rule = {
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var featureLibraryFunctions = new Set([
8
+ /*
9
+ * STOP!
10
+ *
11
+ * Your code should call the API functions directly!
12
+ * But, we are temporarily adding these methods to prevent SSR builds from breaking
13
+ * while we work out a solution for the features to be evaluated inline.
14
+ * Do not add anything here without the permission of #help-jfp-squads
15
+ *
16
+ * Slack thread: https://atlassian.slack.com/archives/CFGLH1ZS8/p1726449739284819
17
+ */
18
+ 'isVisualRefreshEnabled', 'getMetaBoolean', 'getNav4Rollout', 'getWillShowNav3', 'getWillShowNav4', 'getWillShowNav4UserOptIn', 'getWillShowNav4UserOptOut']);
19
+ var isInFunctionLevel = function isInFunctionLevel(context) {
20
+ var scope = context.getScope();
21
+ while (((_scope = scope) === null || _scope === void 0 ? void 0 : _scope.type) !== 'module' && ((_scope2 = scope) === null || _scope2 === void 0 ? void 0 : _scope2.type) !== 'global') {
22
+ var _scope, _scope2;
23
+ if (scope.type === 'function') {
24
+ return true;
25
+ }
26
+ if (scope.type === 'class-field-initializer') {
27
+ return !scope.block.parent.static;
28
+ }
29
+ scope = scope.upper;
30
+ }
31
+ return false;
32
+ };
33
+ var rule = {
34
+ meta: {
35
+ docs: {
36
+ description: 'Disallow getWillShowNav4 or isVisualRefreshEnabled usage at module level',
37
+ 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'
38
+ },
39
+ messages: {
40
+ 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`.'
41
+ }
42
+ },
43
+ create: function create(context) {
44
+ return {
45
+ 'CallExpression[callee.type="Identifier"]': function CallExpressionCalleeTypeIdentifier(node) {
46
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && featureLibraryFunctions.has(node.callee.name) && !isInFunctionLevel(context)) {
47
+ context.report({
48
+ messageId: 'noModuleLevelEval',
49
+ node: node
50
+ });
51
+ }
52
+ }
53
+ };
54
+ }
55
+ };
56
+ var _default = exports.default = rule;
@@ -7,9 +7,9 @@ exports.getDef = getDef;
7
7
  exports.isAPIimport = isAPIimport;
8
8
  exports.isIdentifierImportedFrom = isIdentifierImportedFrom;
9
9
  var _constants = require("./constants");
10
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
11
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
12
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
10
+ 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; } } }; }
11
+ 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; } }
12
+ 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; }
13
13
  function isIdentifierImportedFrom(identifierName, sources, context) {
14
14
  if (sources.size > 0) {
15
15
  var _context$getScope$ref, _context$getScope$ref2;
@@ -9,11 +9,11 @@ import noDuplicateDependencies from './rules/no-duplicate-dependencies';
9
9
  import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
10
10
  import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
11
11
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
12
- import ensureValidEmotionCssProp from './rules/ensure-valid-emotion-css-prop';
13
12
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
14
13
  import ensurePublishValid from './rules/ensure-publish-valid';
15
14
  import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
16
15
  import noModuleLevelEval from './rules/no-module-level-eval';
16
+ import noModuleLevelEvalNav4 from './rules/no-module-level-eval-nav4';
17
17
  import staticFeatureFlags from './rules/static-feature-flags';
18
18
  import noPreconditioning from './rules/no-preconditioning';
19
19
  import inlineUsage from './rules/inline-usage';
@@ -27,7 +27,6 @@ export const rules = {
27
27
  'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
28
28
  'ensure-atlassian-team': ensureAtlassianTeam,
29
29
  'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
30
- 'ensure-valid-emotion-css-prop': ensureValidEmotionCssProp,
31
30
  'no-duplicate-dependencies': noDuplicateDependencies,
32
31
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
33
32
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -35,6 +34,7 @@ export const rules = {
35
34
  'ensure-publish-valid': ensurePublishValid,
36
35
  'ensure-native-and-af-exports-synced': ensureNativeAndAfExportsSynced,
37
36
  'no-module-level-eval': noModuleLevelEval,
37
+ 'no-module-level-eval-nav4': noModuleLevelEvalNav4,
38
38
  'static-feature-flags': staticFeatureFlags,
39
39
  'no-preconditioning': noPreconditioning,
40
40
  'inline-usage': inlineUsage,
@@ -48,7 +48,7 @@ export const configs = {
48
48
  rules: {
49
49
  '@atlaskit/platform/ensure-feature-flag-registration': 'error',
50
50
  '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
51
- allowedPrefixes: ['platform.']
51
+ allowedPrefixes: ['platform.', 'platform_']
52
52
  }],
53
53
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
54
54
  '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
@@ -56,6 +56,7 @@ export const configs = {
56
56
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
57
57
  '@atlaskit/platform/ensure-atlassian-team': 'error',
58
58
  '@atlaskit/platform/no-module-level-eval': 'error',
59
+ '@atlaskit/platform/no-module-level-eval-nav4': 'error',
59
60
  '@atlaskit/platform/static-feature-flags': 'error',
60
61
  '@atlaskit/platform/no-preconditioning': 'error',
61
62
  '@atlaskit/platform/inline-usage': 'error',
@@ -1,9 +1,6 @@
1
1
  import path from 'path';
2
2
  import { getMetadataForFilename } from '../util/registration-utils';
3
3
  const exportsValidationExceptions = {
4
- '@atlassian/sizemap': {
5
- ignoredAfExportKeys: ['.', './lmdb-cache-manager']
6
- },
7
4
  '@atlaskit/tokens': {
8
5
  ignoredAfExportKeys: ['./babel-plugin']
9
6
  },
@@ -0,0 +1,50 @@
1
+ const featureLibraryFunctions = new Set([
2
+ /*
3
+ * STOP!
4
+ *
5
+ * Your code should call the API functions directly!
6
+ * But, we are temporarily adding these methods to prevent SSR builds from breaking
7
+ * while we work out a solution for the features to be evaluated inline.
8
+ * Do not add anything here without the permission of #help-jfp-squads
9
+ *
10
+ * Slack thread: https://atlassian.slack.com/archives/CFGLH1ZS8/p1726449739284819
11
+ */
12
+ 'isVisualRefreshEnabled', 'getMetaBoolean', 'getNav4Rollout', 'getWillShowNav3', 'getWillShowNav4', 'getWillShowNav4UserOptIn', 'getWillShowNav4UserOptOut']);
13
+ const isInFunctionLevel = context => {
14
+ let scope = context.getScope();
15
+ while (((_scope = scope) === null || _scope === void 0 ? void 0 : _scope.type) !== 'module' && ((_scope2 = scope) === null || _scope2 === void 0 ? void 0 : _scope2.type) !== 'global') {
16
+ var _scope, _scope2;
17
+ if (scope.type === 'function') {
18
+ return true;
19
+ }
20
+ if (scope.type === 'class-field-initializer') {
21
+ return !scope.block.parent.static;
22
+ }
23
+ scope = scope.upper;
24
+ }
25
+ return false;
26
+ };
27
+ const rule = {
28
+ meta: {
29
+ docs: {
30
+ description: 'Disallow getWillShowNav4 or isVisualRefreshEnabled usage at module level',
31
+ 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
+ },
33
+ messages: {
34
+ 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`.'
35
+ }
36
+ },
37
+ create(context) {
38
+ return {
39
+ 'CallExpression[callee.type="Identifier"]': node => {
40
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && featureLibraryFunctions.has(node.callee.name) && !isInFunctionLevel(context)) {
41
+ context.report({
42
+ messageId: 'noModuleLevelEval',
43
+ node
44
+ });
45
+ }
46
+ }
47
+ };
48
+ }
49
+ };
50
+ export default rule;
package/dist/esm/index.js CHANGED
@@ -12,11 +12,11 @@ import noDuplicateDependencies from './rules/no-duplicate-dependencies';
12
12
  import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
13
13
  import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
14
14
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
15
- import ensureValidEmotionCssProp from './rules/ensure-valid-emotion-css-prop';
16
15
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
17
16
  import ensurePublishValid from './rules/ensure-publish-valid';
18
17
  import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
19
18
  import noModuleLevelEval from './rules/no-module-level-eval';
19
+ import noModuleLevelEvalNav4 from './rules/no-module-level-eval-nav4';
20
20
  import staticFeatureFlags from './rules/static-feature-flags';
21
21
  import noPreconditioning from './rules/no-preconditioning';
22
22
  import inlineUsage from './rules/inline-usage';
@@ -30,7 +30,6 @@ export var rules = {
30
30
  'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
31
31
  'ensure-atlassian-team': ensureAtlassianTeam,
32
32
  'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
33
- 'ensure-valid-emotion-css-prop': ensureValidEmotionCssProp,
34
33
  'no-duplicate-dependencies': noDuplicateDependencies,
35
34
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
36
35
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -38,6 +37,7 @@ export var rules = {
38
37
  'ensure-publish-valid': ensurePublishValid,
39
38
  'ensure-native-and-af-exports-synced': ensureNativeAndAfExportsSynced,
40
39
  'no-module-level-eval': noModuleLevelEval,
40
+ 'no-module-level-eval-nav4': noModuleLevelEvalNav4,
41
41
  'static-feature-flags': staticFeatureFlags,
42
42
  'no-preconditioning': noPreconditioning,
43
43
  'inline-usage': inlineUsage,
@@ -51,7 +51,7 @@ export var configs = {
51
51
  rules: {
52
52
  '@atlaskit/platform/ensure-feature-flag-registration': 'error',
53
53
  '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', {
54
- allowedPrefixes: ['platform.']
54
+ allowedPrefixes: ['platform.', 'platform_']
55
55
  }],
56
56
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
57
57
  '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
@@ -59,6 +59,7 @@ export var configs = {
59
59
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
60
60
  '@atlaskit/platform/ensure-atlassian-team': 'error',
61
61
  '@atlaskit/platform/no-module-level-eval': 'error',
62
+ '@atlaskit/platform/no-module-level-eval-nav4': 'error',
62
63
  '@atlaskit/platform/static-feature-flags': 'error',
63
64
  '@atlaskit/platform/no-preconditioning': 'error',
64
65
  '@atlaskit/platform/inline-usage': 'error',
@@ -6,9 +6,6 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
6
6
  import path from 'path';
7
7
  import { getMetadataForFilename } from '../util/registration-utils';
8
8
  var exportsValidationExceptions = {
9
- '@atlassian/sizemap': {
10
- ignoredAfExportKeys: ['.', './lmdb-cache-manager']
11
- },
12
9
  '@atlaskit/tokens': {
13
10
  ignoredAfExportKeys: ['./babel-plugin']
14
11
  },
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
3
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
2
+ 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; } } }; }
3
+ 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; } }
4
+ 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; }
5
5
  // eslint-disable-next-line import/no-extraneous-dependencies
6
6
 
7
7
  var rule = {
@@ -0,0 +1,50 @@
1
+ var featureLibraryFunctions = new Set([
2
+ /*
3
+ * STOP!
4
+ *
5
+ * Your code should call the API functions directly!
6
+ * But, we are temporarily adding these methods to prevent SSR builds from breaking
7
+ * while we work out a solution for the features to be evaluated inline.
8
+ * Do not add anything here without the permission of #help-jfp-squads
9
+ *
10
+ * Slack thread: https://atlassian.slack.com/archives/CFGLH1ZS8/p1726449739284819
11
+ */
12
+ 'isVisualRefreshEnabled', 'getMetaBoolean', 'getNav4Rollout', 'getWillShowNav3', 'getWillShowNav4', 'getWillShowNav4UserOptIn', 'getWillShowNav4UserOptOut']);
13
+ var isInFunctionLevel = function isInFunctionLevel(context) {
14
+ var scope = context.getScope();
15
+ while (((_scope = scope) === null || _scope === void 0 ? void 0 : _scope.type) !== 'module' && ((_scope2 = scope) === null || _scope2 === void 0 ? void 0 : _scope2.type) !== 'global') {
16
+ var _scope, _scope2;
17
+ if (scope.type === 'function') {
18
+ return true;
19
+ }
20
+ if (scope.type === 'class-field-initializer') {
21
+ return !scope.block.parent.static;
22
+ }
23
+ scope = scope.upper;
24
+ }
25
+ return false;
26
+ };
27
+ var rule = {
28
+ meta: {
29
+ docs: {
30
+ description: 'Disallow getWillShowNav4 or isVisualRefreshEnabled usage at module level',
31
+ 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
+ },
33
+ messages: {
34
+ 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`.'
35
+ }
36
+ },
37
+ create: function create(context) {
38
+ return {
39
+ 'CallExpression[callee.type="Identifier"]': function CallExpressionCalleeTypeIdentifier(node) {
40
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && featureLibraryFunctions.has(node.callee.name) && !isInFunctionLevel(context)) {
41
+ context.report({
42
+ messageId: 'noModuleLevelEval',
43
+ node: node
44
+ });
45
+ }
46
+ }
47
+ };
48
+ }
49
+ };
50
+ export default rule;
@@ -1,6 +1,6 @@
1
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
3
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
1
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
4
  import { FEATURE_API_IMPORT_SOURCES } from './constants';
5
5
  export function isIdentifierImportedFrom(identifierName, sources, context) {
6
6
  if (sources.size > 0) {
@@ -6,7 +6,6 @@ export declare const rules: {
6
6
  'ensure-test-runner-nested-count': import("eslint").Rule.RuleModule;
7
7
  'ensure-atlassian-team': import("eslint").Rule.RuleModule;
8
8
  'ensure-critical-dependency-resolutions': import("eslint").Rule.RuleModule;
9
- 'ensure-valid-emotion-css-prop': import("eslint").Rule.RuleModule;
10
9
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
11
10
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
12
11
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -14,6 +13,7 @@ export declare const rules: {
14
13
  'ensure-publish-valid': import("eslint").Rule.RuleModule;
15
14
  'ensure-native-and-af-exports-synced': import("eslint").Rule.RuleModule;
16
15
  'no-module-level-eval': import("eslint").Rule.RuleModule;
16
+ 'no-module-level-eval-nav4': import("eslint").Rule.RuleModule;
17
17
  'static-feature-flags': import("eslint").Rule.RuleModule;
18
18
  'no-preconditioning': import("eslint").Rule.RuleModule;
19
19
  'inline-usage': import("eslint").Rule.RuleModule;
@@ -35,6 +35,7 @@ export declare const configs: {
35
35
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
36
36
  '@atlaskit/platform/ensure-atlassian-team': string;
37
37
  '@atlaskit/platform/no-module-level-eval': string;
38
+ '@atlaskit/platform/no-module-level-eval-nav4': string;
38
39
  '@atlaskit/platform/static-feature-flags': string;
39
40
  '@atlaskit/platform/no-preconditioning': string;
40
41
  '@atlaskit/platform/inline-usage': string;
@@ -6,7 +6,6 @@ export declare const rules: {
6
6
  'ensure-test-runner-nested-count': import("eslint").Rule.RuleModule;
7
7
  'ensure-atlassian-team': import("eslint").Rule.RuleModule;
8
8
  'ensure-critical-dependency-resolutions': import("eslint").Rule.RuleModule;
9
- 'ensure-valid-emotion-css-prop': import("eslint").Rule.RuleModule;
10
9
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
11
10
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
12
11
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -14,6 +13,7 @@ export declare const rules: {
14
13
  'ensure-publish-valid': import("eslint").Rule.RuleModule;
15
14
  'ensure-native-and-af-exports-synced': import("eslint").Rule.RuleModule;
16
15
  'no-module-level-eval': import("eslint").Rule.RuleModule;
16
+ 'no-module-level-eval-nav4': import("eslint").Rule.RuleModule;
17
17
  'static-feature-flags': import("eslint").Rule.RuleModule;
18
18
  'no-preconditioning': import("eslint").Rule.RuleModule;
19
19
  'inline-usage': import("eslint").Rule.RuleModule;
@@ -35,6 +35,7 @@ export declare const configs: {
35
35
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': string;
36
36
  '@atlaskit/platform/ensure-atlassian-team': string;
37
37
  '@atlaskit/platform/no-module-level-eval': string;
38
+ '@atlaskit/platform/no-module-level-eval-nav4': string;
38
39
  '@atlaskit/platform/static-feature-flags': string;
39
40
  '@atlaskit/platform/no-preconditioning': string;
40
41
  '@atlaskit/platform/inline-usage': string;
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable import/no-extraneous-dependencies */
2
2
  /* eslint-disable global-require */
3
3
  // Used only for internal repo usage.
4
- require('@atlassian/ts-loader/loader');
4
+ require('@atlassian/ts-loader');
5
5
 
6
6
  module.exports = require('./src/index');
package/package.json CHANGED
@@ -1,12 +1,13 @@
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.7.3",
4
+ "version": "0.7.5",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
7
- "team": "UIP - Platform Integration Trust (PITa)",
8
- "releaseModel": "continuous",
9
- "inPublicMirror": true
7
+ "team": "UIP Dev Infra",
8
+ "toolingLabels": [
9
+ "linting"
10
+ ]
10
11
  },
11
12
  "publishConfig": {
12
13
  "registry": "https://registry.npmjs.org/"
@@ -38,7 +39,7 @@
38
39
  "devDependencies": {
39
40
  "@atlassian/ts-loader": "*",
40
41
  "@types/eslint": "^8.56.6",
41
- "eslint": "^8.49.0",
42
+ "eslint": "^8.57.0",
42
43
  "outdent": "^0.5.0"
43
44
  }
44
45
  }
package/src/index.tsx CHANGED
@@ -9,11 +9,11 @@ import noDuplicateDependencies from './rules/no-duplicate-dependencies';
9
9
  import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
10
10
  import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
11
11
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
12
- import ensureValidEmotionCssProp from './rules/ensure-valid-emotion-css-prop';
13
12
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
14
13
  import ensurePublishValid from './rules/ensure-publish-valid';
15
14
  import ensureNativeAndAfExportsSynced from './rules/ensure-native-and-af-exports-synced';
16
15
  import noModuleLevelEval from './rules/no-module-level-eval';
16
+ import noModuleLevelEvalNav4 from './rules/no-module-level-eval-nav4';
17
17
  import staticFeatureFlags from './rules/static-feature-flags';
18
18
  import noPreconditioning from './rules/no-preconditioning';
19
19
  import inlineUsage from './rules/inline-usage';
@@ -28,7 +28,6 @@ export const rules = {
28
28
  'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
29
29
  'ensure-atlassian-team': ensureAtlassianTeam,
30
30
  'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
31
- 'ensure-valid-emotion-css-prop': ensureValidEmotionCssProp,
32
31
  'no-duplicate-dependencies': noDuplicateDependencies,
33
32
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
34
33
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -36,6 +35,7 @@ export const rules = {
36
35
  'ensure-publish-valid': ensurePublishValid,
37
36
  'ensure-native-and-af-exports-synced': ensureNativeAndAfExportsSynced,
38
37
  'no-module-level-eval': noModuleLevelEval,
38
+ 'no-module-level-eval-nav4': noModuleLevelEvalNav4,
39
39
  'static-feature-flags': staticFeatureFlags,
40
40
  'no-preconditioning': noPreconditioning,
41
41
  'inline-usage': inlineUsage,
@@ -49,13 +49,17 @@ export const configs = {
49
49
  plugins: ['@atlaskit/platform'],
50
50
  rules: {
51
51
  '@atlaskit/platform/ensure-feature-flag-registration': 'error',
52
- '@atlaskit/platform/ensure-feature-flag-prefix': ['warn', { allowedPrefixes: ['platform.'] }],
52
+ '@atlaskit/platform/ensure-feature-flag-prefix': [
53
+ 'warn',
54
+ { allowedPrefixes: ['platform.', 'platform_'] },
55
+ ],
53
56
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
54
57
  '@atlaskit/platform/ensure-test-runner-nested-count': 'warn',
55
58
  '@atlaskit/platform/no-invalid-feature-flag-usage': 'error',
56
59
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
57
60
  '@atlaskit/platform/ensure-atlassian-team': 'error',
58
61
  '@atlaskit/platform/no-module-level-eval': 'error',
62
+ '@atlaskit/platform/no-module-level-eval-nav4': 'error',
59
63
  '@atlaskit/platform/static-feature-flags': 'error',
60
64
  '@atlaskit/platform/no-preconditioning': 'error',
61
65
  '@atlaskit/platform/inline-usage': 'error',
@@ -8,9 +8,6 @@ interface ExportsValidationExceptions {
8
8
  }
9
9
 
10
10
  const exportsValidationExceptions: ExportsValidationExceptions = {
11
- '@atlassian/sizemap': {
12
- ignoredAfExportKeys: ['.', './lmdb-cache-manager'],
13
- },
14
11
  '@atlaskit/tokens': {
15
12
  ignoredAfExportKeys: ['./babel-plugin'],
16
13
  },
@@ -0,0 +1,8 @@
1
+ # Avoid using navigation/visual refresh feature flag functions at module level (feature-flags/no-module-level-eval-nav4)
2
+
3
+ Disallow usage of navigation/visual refresh feature flag functions in global/module scope. Due to
4
+ JFE using SSR, feature flags should not be called/initialised before components have mounted as it
5
+ could cause errors.
6
+
7
+ This is a temporary lint rule cloned from no-module-level-nav4 while we explore pulling these
8
+ evaluations inline https://atlassian.slack.com/archives/CFGLH1ZS8/p1726449739284819