@atlaskit/eslint-plugin-platform 2.4.2 → 2.6.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 (49) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/afm-cc/tsconfig.json +1 -1
  3. package/dist/cjs/index.js +42 -3
  4. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  5. package/dist/cjs/rules/ensure-no-private-dependencies/index.js +101 -0
  6. package/dist/cjs/rules/ensure-valid-platform-yarn-protocol-usage/index.js +3 -15
  7. package/dist/cjs/rules/feature-gating/no-preconditioning/index.js +1 -1
  8. package/dist/cjs/rules/no-direct-document-usage/index.js +103 -0
  9. package/dist/cjs/rules/no-sparse-checkout/index.js +43 -0
  10. package/dist/cjs/rules/util/file-exclusions.js +45 -0
  11. package/dist/es2019/index.js +42 -3
  12. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  13. package/dist/es2019/rules/ensure-no-private-dependencies/index.js +63 -0
  14. package/dist/es2019/rules/ensure-valid-platform-yarn-protocol-usage/index.js +4 -16
  15. package/dist/es2019/rules/feature-gating/no-preconditioning/index.js +1 -1
  16. package/dist/es2019/rules/no-direct-document-usage/index.js +95 -0
  17. package/dist/es2019/rules/no-sparse-checkout/index.js +35 -0
  18. package/dist/es2019/rules/util/file-exclusions.js +37 -0
  19. package/dist/esm/index.js +42 -3
  20. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  21. package/dist/esm/rules/ensure-no-private-dependencies/index.js +96 -0
  22. package/dist/esm/rules/ensure-valid-platform-yarn-protocol-usage/index.js +4 -16
  23. package/dist/esm/rules/feature-gating/no-preconditioning/index.js +1 -1
  24. package/dist/esm/rules/no-direct-document-usage/index.js +97 -0
  25. package/dist/esm/rules/no-sparse-checkout/index.js +37 -0
  26. package/dist/esm/rules/util/file-exclusions.js +39 -0
  27. package/dist/types/index.d.ts +14 -0
  28. package/dist/types/rules/ensure-no-private-dependencies/index.d.ts +3 -0
  29. package/dist/types/rules/no-direct-document-usage/index.d.ts +3 -0
  30. package/dist/types/rules/no-sparse-checkout/index.d.ts +3 -0
  31. package/dist/types/rules/util/file-exclusions.d.ts +13 -0
  32. package/dist/types-ts4.5/index.d.ts +14 -0
  33. package/dist/types-ts4.5/rules/ensure-no-private-dependencies/index.d.ts +3 -0
  34. package/dist/types-ts4.5/rules/no-direct-document-usage/index.d.ts +3 -0
  35. package/dist/types-ts4.5/rules/no-sparse-checkout/index.d.ts +3 -0
  36. package/dist/types-ts4.5/rules/util/file-exclusions.d.ts +13 -0
  37. package/package.json +12 -2
  38. package/src/index.tsx +46 -2
  39. package/src/rules/ensure-native-and-af-exports-synced/index.tsx +3 -0
  40. package/src/rules/ensure-no-private-dependencies/__tests__/unit/rule.test.ts +212 -0
  41. package/src/rules/ensure-no-private-dependencies/index.ts +64 -0
  42. package/src/rules/ensure-valid-bin-values/__tests__/unit/rule.test.ts +3 -2
  43. package/src/rules/ensure-valid-platform-yarn-protocol-usage/__tests__/unit/rule.test.ts +57 -109
  44. package/src/rules/ensure-valid-platform-yarn-protocol-usage/index.ts +4 -16
  45. package/src/rules/feature-gating/no-preconditioning/index.tsx +1 -1
  46. package/src/rules/no-direct-document-usage/index.tsx +109 -0
  47. package/src/rules/no-sparse-checkout/__tests__/unit/rule.test.tsx +48 -0
  48. package/src/rules/no-sparse-checkout/index.tsx +54 -0
  49. package/src/rules/util/file-exclusions.ts +39 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/eslint-plugin-platform
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#168806](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/168806)
8
+ [`e4f94f422b9f1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e4f94f422b9f1) -
9
+ New linting rule to prevent direct "document" usage. This prevents failed tests when document is
10
+ not defined in the testing environment
11
+
12
+ ## 2.5.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#127293](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/127293)
17
+ [`3ee2e5b640591`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3ee2e5b640591) -
18
+ Created new rule `@atlaskit/platform/ensure-no-private-dependencies` which ensures that private
19
+ dependencies are not used in published packages
20
+
3
21
  ## 2.4.2
4
22
 
5
23
  ### Patch Changes
@@ -3,7 +3,7 @@
3
3
  "compilerOptions": {
4
4
  "target": "es5",
5
5
  "composite": true,
6
- "outDir": "../dist",
6
+ "outDir": "../../../../../confluence/tsDist/@atlaskit__eslint-plugin-platform",
7
7
  "rootDir": "../"
8
8
  },
9
9
  "include": [
package/dist/cjs/index.js CHANGED
@@ -18,6 +18,7 @@ var _ensureFeatureFlagPrefix = _interopRequireDefault(require("./rules/ensure-fe
18
18
  var _ensureCriticalDependencyResolutions = _interopRequireDefault(require("./rules/ensure-critical-dependency-resolutions"));
19
19
  var _ensureValidPlatformYarnProtocolUsage = _interopRequireDefault(require("./rules/ensure-valid-platform-yarn-protocol-usage"));
20
20
  var _ensureValidBinValues = _interopRequireDefault(require("./rules/ensure-valid-bin-values"));
21
+ var _ensureNoPrivateDependencies = _interopRequireDefault(require("./rules/ensure-no-private-dependencies"));
21
22
  var _expandBorderShorthand = _interopRequireDefault(require("./rules/compiled/expand-border-shorthand"));
22
23
  var _noInvalidStorybookDecoratorUsage = _interopRequireDefault(require("./rules/no-invalid-storybook-decorator-usage"));
23
24
  var _ensurePublishValid = _interopRequireDefault(require("./rules/ensure-publish-valid"));
@@ -33,8 +34,28 @@ var _useEntrypointsInExamples = _interopRequireDefault(require("./rules/use-entr
33
34
  var _useRecommendedUtils = _interopRequireDefault(require("./rules/feature-gating/use-recommended-utils"));
34
35
  var _expandBackgroundShorthand = _interopRequireDefault(require("./rules/compiled/expand-background-shorthand"));
35
36
  var _expandSpacingShorthand = _interopRequireDefault(require("./rules/compiled/expand-spacing-shorthand"));
37
+ var _noSparseCheckout = _interopRequireDefault(require("./rules/no-sparse-checkout"));
38
+ var _noDirectDocumentUsage = _interopRequireDefault(require("./rules/no-direct-document-usage"));
39
+ var _nodePath = require("node:path");
40
+ var _nodeFs = require("node:fs");
36
41
  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; }
37
42
  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; } // eslint-disable-next-line import/no-extraneous-dependencies
43
+ var jiraRoot;
44
+ try {
45
+ var findUp = require('find-up');
46
+ findUp.sync(function (dir) {
47
+ var productsJsonPath = (0, _nodePath.join)(dir, 'products.json');
48
+ if (findUp.sync.exists(productsJsonPath)) {
49
+ var productJson = JSON.parse((0, _nodeFs.readFileSync)(productsJsonPath, 'utf-8'));
50
+ if (productJson.Jira) {
51
+ jiraRoot = (0, _nodePath.normalize)((0, _nodePath.join)(dir, productJson.Jira.path));
52
+ return findUp.stop;
53
+ }
54
+ }
55
+ });
56
+ } catch (_unused) {
57
+ // we aren't running inside of AFM, so we can ignore this.
58
+ }
38
59
  var packageJson = require('@atlaskit/eslint-plugin-platform/package.json');
39
60
  var rules = exports.rules = {
40
61
  'ensure-feature-flag-registration': _ensureFeatureFlagRegistration.default,
@@ -45,6 +66,7 @@ var rules = exports.rules = {
45
66
  'ensure-critical-dependency-resolutions': _ensureCriticalDependencyResolutions.default,
46
67
  'ensure-valid-platform-yarn-protocol-usage': _ensureValidPlatformYarnProtocolUsage.default,
47
68
  'ensure-valid-bin-values': _ensureValidBinValues.default,
69
+ 'ensure-no-private-dependencies': _ensureNoPrivateDependencies.default,
48
70
  'expand-border-shorthand': _expandBorderShorthand.default,
49
71
  'expand-background-shorthand': _expandBackgroundShorthand.default,
50
72
  'expand-spacing-shorthand': _expandSpacingShorthand.default,
@@ -62,7 +84,9 @@ var rules = exports.rules = {
62
84
  'prefer-fg': _preferFg.default,
63
85
  'no-alias': _noAlias.default,
64
86
  'use-entrypoints-in-examples': _useEntrypointsInExamples.default,
65
- 'use-recommended-utils': _useRecommendedUtils.default
87
+ 'use-recommended-utils': _useRecommendedUtils.default,
88
+ 'no-sparse-checkout': _noSparseCheckout.default,
89
+ 'no-direct-document-usage': _noDirectDocumentUsage.default
66
90
  };
67
91
  var commonConfig = {
68
92
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
@@ -71,6 +95,7 @@ var commonConfig = {
71
95
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
72
96
  '@atlaskit/platform/ensure-atlassian-team': 'error',
73
97
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
98
+ '@atlaskit/platform/no-direct-document-usage': 'warn',
74
99
  // Compiled: rules that are not included via `@compiled/recommended
75
100
  '@atlaskit/platform/expand-border-shorthand': 'error',
76
101
  '@atlaskit/platform/expand-background-shorthand': 'error',
@@ -99,6 +124,7 @@ var recommendedRules = _objectSpread(_objectSpread({}, commonConfig), {}, {
99
124
  var jiraRules = commonConfig;
100
125
  var jsonPrefix = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, @typescript-eslint/semi, no-template-curly-in-string */ module.exports = ';
101
126
  var jsonPrefixForFlatConfig = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, no-template-curly-in-string */ module.exports = ';
127
+ var jsonPrefixForJira = 'module.exports = ';
102
128
  var name = packageJson.name,
103
129
  version = packageJson.version;
104
130
  var plugin = exports.plugin = {
@@ -145,7 +171,14 @@ var plugin = exports.plugin = {
145
171
  },
146
172
  processors: {
147
173
  'package-json-processor': {
148
- preprocess: function preprocess(source) {
174
+ preprocess: function preprocess(source, filename) {
175
+ // we only need to check for jiraRoot because it uses a different
176
+ // ESLint version and produces fake errors due to how this processor handles JSON
177
+ if (jiraRoot && filename.startsWith(jiraRoot)) {
178
+ // augment the json into a js file
179
+ return [jsonPrefixForJira + source.trim()];
180
+ }
181
+
149
182
  // augment the json into a js file
150
183
  return [jsonPrefix + source.trim()];
151
184
  },
@@ -168,7 +201,13 @@ var plugin = exports.plugin = {
168
201
  // This processor is used for ESLint FlatConfig,
169
202
  // once we roll out FlatConfig, we can remove the above processor
170
203
  'package-json-processor-for-flat-config': {
171
- preprocess: function preprocess(source) {
204
+ // we only need to check for jiraRoot because it uses a different
205
+ // ESLint version and produces fake errors due to how this processor handles JSON
206
+ preprocess: function preprocess(source, filename) {
207
+ if (jiraRoot && filename.startsWith(jiraRoot)) {
208
+ // augment the json into a js file
209
+ return [jsonPrefixForJira + source.trim()];
210
+ }
172
211
  // augment the json into a js file
173
212
  return [jsonPrefixForFlatConfig + source.trim()];
174
213
  },
@@ -13,6 +13,9 @@ 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
+ '@af/yarn-workspace': {
17
+ ignoredAfExportKeys: ['./lock-parser']
18
+ },
16
19
  '@atlaskit/tokens': {
17
20
  ignoredAfExportKeys: ['./babel-plugin']
18
21
  },
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _handleAstObject = require("../util/handle-ast-object");
11
+ var _getPackages = require("@manypkg/get-packages");
12
+ var _findRoot = require("@manypkg/find-root");
13
+ 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; } } }; }
14
+ 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; } }
15
+ 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; } // eslint-disable-next-line import/no-extraneous-dependencies
16
+ var root = (0, _findRoot.findRootSync)(process.cwd());
17
+ var pkgs = (0, _getPackages.getPackagesSync)(root).packages;
18
+ var pkgMap = new Map(pkgs.map(function (pkg) {
19
+ return [pkg.packageJson.name, pkg];
20
+ }));
21
+ var rule = {
22
+ meta: {
23
+ type: 'problem',
24
+ docs: {
25
+ description: "Ensures that private dependencies are not used in published packages.",
26
+ recommended: true
27
+ },
28
+ hasSuggestions: false,
29
+ messages: {
30
+ invalidPrivateDependency: "Published package has private dependency '{{ pkgName }}'. To resolve this error, remove the private dependency or set this package to private."
31
+ }
32
+ },
33
+ create: function create(context) {
34
+ return {
35
+ ObjectExpression: function () {
36
+ var _ObjectExpression = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(node) {
37
+ var isPrivatePkg, dependencies, peerDependencies, _i, _arr, obj, _iterator, _step, p, key, _pkgMap$get, isPrivateDependency;
38
+ return _regenerator.default.wrap(function _callee$(_context) {
39
+ while (1) switch (_context.prev = _context.next) {
40
+ case 0:
41
+ if (!(!context.filename.endsWith('package.json') || node.type !== 'ObjectExpression')) {
42
+ _context.next = 2;
43
+ break;
44
+ }
45
+ return _context.abrupt("return");
46
+ case 2:
47
+ // Private dependencies can be used in private packages
48
+ isPrivatePkg = (0, _handleAstObject.getObjectPropertyAsLiteral)(node, 'private') === true;
49
+ if (!(isPrivatePkg === true)) {
50
+ _context.next = 5;
51
+ break;
52
+ }
53
+ return _context.abrupt("return");
54
+ case 5:
55
+ // Check for private dependencies in dependencies and peerDependencies
56
+ // Note: devDependencies are not checked here as they don't end up in consumer lockfiles
57
+ dependencies = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'dependencies');
58
+ peerDependencies = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'peerDependencies');
59
+ for (_i = 0, _arr = [dependencies, peerDependencies]; _i < _arr.length; _i++) {
60
+ obj = _arr[_i];
61
+ _iterator = _createForOfIteratorHelper((obj === null || obj === void 0 ? void 0 : obj.properties) || []);
62
+ try {
63
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
64
+ p = _step.value;
65
+ if (p.type === 'Property' && p.key.type === 'Literal') {
66
+ key = p.key.value;
67
+ if (typeof key === 'string' && pkgMap.has(key)) {
68
+ isPrivateDependency = ((_pkgMap$get = pkgMap.get(key)) === null || _pkgMap$get === void 0 ? void 0 : _pkgMap$get.packageJson.private) === true;
69
+ if (isPrivateDependency) {
70
+ context.report({
71
+ node: node,
72
+ messageId: 'invalidPrivateDependency',
73
+ data: {
74
+ pkgName: key
75
+ }
76
+ });
77
+ }
78
+ }
79
+ }
80
+ }
81
+ } catch (err) {
82
+ _iterator.e(err);
83
+ } finally {
84
+ _iterator.f();
85
+ }
86
+ }
87
+ case 8:
88
+ case "end":
89
+ return _context.stop();
90
+ }
91
+ }, _callee);
92
+ }));
93
+ function ObjectExpression(_x) {
94
+ return _ObjectExpression.apply(this, arguments);
95
+ }
96
+ return ObjectExpression;
97
+ }()
98
+ };
99
+ }
100
+ };
101
+ var _default = exports.default = rule;
@@ -8,7 +8,6 @@ var _handleAstObject = require("../util/handle-ast-object");
8
8
  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; } } }; }
9
9
  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; } }
10
10
  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; } // eslint-disable-next-line import/no-extraneous-dependencies
11
- var workspaceProtocolRegex = /^workspace:[\^~\*]$/;
12
11
  var rootProtocolRegex = /^root:[\^~\*]$/;
13
12
 
14
13
  /**
@@ -21,7 +20,8 @@ function getYarnProtocolsUsed(node) {
21
20
  };
22
21
  var dependencies = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'dependencies');
23
22
  var devDependencies = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'devDependencies');
24
- for (var _i = 0, _arr = [dependencies, devDependencies]; _i < _arr.length; _i++) {
23
+ var peerDependencies = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'peerDependencies');
24
+ for (var _i = 0, _arr = [dependencies, devDependencies, peerDependencies]; _i < _arr.length; _i++) {
25
25
  var obj = _arr[_i];
26
26
  var _iterator = _createForOfIteratorHelper((obj === null || obj === void 0 ? void 0 : obj.properties) || []),
27
27
  _step;
@@ -30,9 +30,6 @@ function getYarnProtocolsUsed(node) {
30
30
  var p = _step.value;
31
31
  if (p.type === 'Property' && p.value.type === 'Literal') {
32
32
  if (typeof p.value.value === 'string') {
33
- if (workspaceProtocolRegex.test(p.value.value)) {
34
- protocolsUsed.workspace = true;
35
- }
36
33
  if (rootProtocolRegex.test(p.value.value)) {
37
34
  protocolsUsed.root = true;
38
35
  }
@@ -56,7 +53,7 @@ var rule = {
56
53
  },
57
54
  hasSuggestions: false,
58
55
  messages: {
59
- invalidWorkspaceProtocolUsage: "The 'workspace:' protocol is not allowed in public packages. To resolve this error, either set the package to private or replace the 'workspace:' protocol with specific package versions (e.g. '^1.0.0').",
56
+ invalidWorkspaceProtocolUsage: "The 'workspace:^'protocol is Used. To resolve this error, please use the 'workspace:*' protocol instead.",
60
57
  invalidRootProtocolUsage: "The 'root:' protocol is not allowed in platform packages. To resolve this error, replace the 'root:' protocol with specific package versions (e.g. '^1.0.0')."
61
58
  }
62
59
  },
@@ -75,15 +72,6 @@ var rule = {
75
72
  messageId: 'invalidRootProtocolUsage'
76
73
  });
77
74
  }
78
-
79
- // The 'workspace:' protocol can not be used in public packages
80
- var isPrivatePackage = (0, _handleAstObject.getObjectPropertyAsLiteral)(node, 'private') === true;
81
- if (!isPrivatePackage && yarnProtocolsUsed.workspace) {
82
- context.report({
83
- node: node,
84
- messageId: 'invalidWorkspaceProtocolUsage'
85
- });
86
- }
87
75
  }
88
76
  };
89
77
  }
@@ -55,7 +55,7 @@ var rule = {
55
55
  url: 'https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/browse/platform/packages/platform/eslint-plugin/src/rules/no-preconditioning/README.md'
56
56
  },
57
57
  messages: {
58
- useConfig: 'Do not precondition gates or experiments with another gate. Configure this in Statsig instead to reduce unnecessary code and simplify cleanup.',
58
+ 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.',
59
59
  incorrectExposure: 'Evaluate gates or experiments at the end of your logical expression to ensure exposure is tracked correctly.'
60
60
  }
61
61
  },
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _fileExclusions = require("../util/file-exclusions");
8
+ var rule = {
9
+ meta: {
10
+ type: 'problem',
11
+ docs: {
12
+ description: 'Enforce using getDocument from @atlaskit/browser-apis instead of direct document usage',
13
+ recommended: true
14
+ },
15
+ messages: {
16
+ useGetDocument: 'Use getDocument from @atlaskit/browser-apis instead of direct document usage'
17
+ },
18
+ schema: []
19
+ },
20
+ create: function create(context) {
21
+ var hasGetDocumentImport = false;
22
+ var filename = context.filename;
23
+
24
+ // Skip test files
25
+ var skipResult = (0, _fileExclusions.skipForTestFiles)(context);
26
+ if (skipResult) {
27
+ return skipResult;
28
+ }
29
+
30
+ // Skip example files
31
+ var skipResult2 = (0, _fileExclusions.skipForExampleFiles)(context);
32
+ if (skipResult2) {
33
+ return skipResult2;
34
+ }
35
+
36
+ // Skip the getDocument.ts file itself
37
+ if (filename.endsWith('getDocument.ts')) {
38
+ return {};
39
+ }
40
+ return {
41
+ ImportDeclaration: function ImportDeclaration(node) {
42
+ if (node.source.value === '@atlaskit/browser-apis' && node.specifiers.some(function (specifier) {
43
+ return specifier.type === 'ImportSpecifier' && specifier.imported.name === 'getDocument';
44
+ })) {
45
+ hasGetDocumentImport = true;
46
+ }
47
+ },
48
+ Identifier: function Identifier(node) {
49
+ if (node.name === 'document' && !hasGetDocumentImport) {
50
+ var parent = node.parent;
51
+
52
+ // Skip if 'document' is used as a property key in an object literal
53
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'Property' && parent.key === node) {
54
+ return;
55
+ }
56
+
57
+ // Skip if 'document' is used as a shorthand property value
58
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'Property' && parent.value === node && parent.shorthand) {
59
+ return;
60
+ }
61
+
62
+ // Skip if 'document' is used as a property being accessed in a member expression
63
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'MemberExpression' && parent.property === node && !parent.computed) {
64
+ return;
65
+ }
66
+
67
+ // Skip if 'document' is being declared as a variable
68
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'VariableDeclarator' && parent.id === node) {
69
+ return;
70
+ }
71
+
72
+ // Skip if 'document' is a function name
73
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'FunctionDeclaration' && 'id' in parent && parent.id === node) {
74
+ return;
75
+ }
76
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'FunctionExpression' && 'id' in parent && parent.id === node) {
77
+ return;
78
+ }
79
+
80
+ // Skip if 'document' is a method name in a class or object
81
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'MethodDefinition' && parent.key === node) {
82
+ return;
83
+ }
84
+
85
+ // Skip if 'document' is being assigned to (shadowing the global)
86
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'AssignmentExpression' && parent.left === node) {
87
+ return;
88
+ }
89
+
90
+ // Skip if 'document' is in a destructuring pattern (could be destructuring from an object)
91
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'ObjectPattern' || (parent === null || parent === void 0 ? void 0 : parent.type) === 'ArrayPattern') {
92
+ return;
93
+ }
94
+ context.report({
95
+ node: node,
96
+ messageId: 'useGetDocument'
97
+ });
98
+ }
99
+ }
100
+ };
101
+ }
102
+ };
103
+ var _default = exports.default = rule;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ // We will be removing sparse checkout from pipelines in CI completely due to the load it causes on BBC.
8
+ // We will be incrementally removing sparse-checkout from the files below as it is probably unnecessasry.
9
+ // If you must add an exception below, please go through the chopper process before doing so
10
+ var 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'];
11
+ var rule = {
12
+ meta: {
13
+ docs: {
14
+ recommended: false
15
+ },
16
+ type: 'problem',
17
+ messages: {
18
+ noSparseCheckout: 'Sparse checkout is not allowed in pipeline configurations. Use git-alternates instead by setting sparseCheckout to false or add this file to exceptions.'
19
+ }
20
+ },
21
+ create: function create(context) {
22
+ var fileName = context.filename;
23
+ if (sparseCheckoutExceptions.some(function (exception) {
24
+ return fileName.endsWith(exception);
25
+ })) {
26
+ return {};
27
+ }
28
+ return {
29
+ // Look for calls to afmClone or objects that match AFMCloneConfig type
30
+ 'CallExpression[callee.object.name=alias][callee.property.name=afmClone] ObjectExpression Property': function CallExpressionCalleeObjectNameAliasCalleePropertyNameAfmClone_ObjectExpression_Property(node) {
31
+ if (node.key.type === 'Identifier' && node.key.name === 'sparseCheckout') {
32
+ if (node.value.type === 'Literal' && node.value.value === true) {
33
+ context.report({
34
+ node: node,
35
+ messageId: 'noSparseCheckout'
36
+ });
37
+ }
38
+ }
39
+ }
40
+ };
41
+ }
42
+ };
43
+ var _default = exports.default = rule;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.skipForTestFiles = exports.skipForExampleFiles = void 0;
7
+ /**
8
+ * Common patterns for test files that should be excluded from rules
9
+ */
10
+ var TEST_FILE_PATTERNS = ['__tests__', 'test', 'spec'];
11
+
12
+ /**
13
+ * Checks if a file should be excluded from rules based on test file patterns
14
+ * @param filename The filename to check
15
+ * @returns true if the file should be excluded, false otherwise
16
+ */
17
+ var isTestFile = function isTestFile(filename) {
18
+ return TEST_FILE_PATTERNS.some(function (pattern) {
19
+ return filename.includes(pattern);
20
+ });
21
+ };
22
+
23
+ /**
24
+ * Helper function to skip rules for test files
25
+ * @param context The ESLint rule context
26
+ * @returns An empty RuleListener if the file is a test file, undefined otherwise
27
+ */
28
+ var skipForTestFiles = exports.skipForTestFiles = function skipForTestFiles(context) {
29
+ if (isTestFile(context.filename)) {
30
+ return {};
31
+ }
32
+ return undefined;
33
+ };
34
+
35
+ /**
36
+ * Helper function to skip rules for example files
37
+ * @param context The ESLint rule context
38
+ * @returns An empty RuleListener if the file is an example file, undefined otherwise
39
+ */
40
+ var skipForExampleFiles = exports.skipForExampleFiles = function skipForExampleFiles(context) {
41
+ if (context.filename.includes('example')) {
42
+ return {};
43
+ }
44
+ return undefined;
45
+ };
@@ -11,6 +11,7 @@ import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
11
11
  import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
12
12
  import ensureValidPlatformYarnProtocolUsage from './rules/ensure-valid-platform-yarn-protocol-usage';
13
13
  import ensureValidBinValues from './rules/ensure-valid-bin-values';
14
+ import ensureNoPrivateDependencies from './rules/ensure-no-private-dependencies';
14
15
  import expandBorderShorthand from './rules/compiled/expand-border-shorthand';
15
16
  import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
16
17
  import ensurePublishValid from './rules/ensure-publish-valid';
@@ -26,6 +27,26 @@ import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
26
27
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
27
28
  import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
28
29
  import expandSpacingShorthand from './rules/compiled/expand-spacing-shorthand';
30
+ import noSparseCheckout from './rules/no-sparse-checkout';
31
+ import noDirectDocumentUsage from './rules/no-direct-document-usage';
32
+ import { join, normalize } from 'node:path';
33
+ import { readFileSync } from 'node:fs';
34
+ let jiraRoot;
35
+ try {
36
+ const findUp = require('find-up');
37
+ findUp.sync(dir => {
38
+ const productsJsonPath = join(dir, 'products.json');
39
+ if (findUp.sync.exists(productsJsonPath)) {
40
+ const productJson = JSON.parse(readFileSync(productsJsonPath, 'utf-8'));
41
+ if (productJson.Jira) {
42
+ jiraRoot = normalize(join(dir, productJson.Jira.path));
43
+ return findUp.stop;
44
+ }
45
+ }
46
+ });
47
+ } catch {
48
+ // we aren't running inside of AFM, so we can ignore this.
49
+ }
29
50
  const packageJson = require('@atlaskit/eslint-plugin-platform/package.json');
30
51
  const rules = {
31
52
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
@@ -36,6 +57,7 @@ const rules = {
36
57
  'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
37
58
  'ensure-valid-platform-yarn-protocol-usage': ensureValidPlatformYarnProtocolUsage,
38
59
  'ensure-valid-bin-values': ensureValidBinValues,
60
+ 'ensure-no-private-dependencies': ensureNoPrivateDependencies,
39
61
  'expand-border-shorthand': expandBorderShorthand,
40
62
  'expand-background-shorthand': expandBackgroundShorthand,
41
63
  'expand-spacing-shorthand': expandSpacingShorthand,
@@ -53,7 +75,9 @@ const rules = {
53
75
  'prefer-fg': preferFG,
54
76
  'no-alias': noAlias,
55
77
  'use-entrypoints-in-examples': useEntrypointsInExamples,
56
- 'use-recommended-utils': useRecommendedUtils
78
+ 'use-recommended-utils': useRecommendedUtils,
79
+ 'no-sparse-checkout': noSparseCheckout,
80
+ 'no-direct-document-usage': noDirectDocumentUsage
57
81
  };
58
82
  const commonConfig = {
59
83
  '@atlaskit/platform/ensure-test-runner-arguments': 'error',
@@ -62,6 +86,7 @@ const commonConfig = {
62
86
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': 'error',
63
87
  '@atlaskit/platform/ensure-atlassian-team': 'error',
64
88
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
89
+ '@atlaskit/platform/no-direct-document-usage': 'warn',
65
90
  // Compiled: rules that are not included via `@compiled/recommended
66
91
  '@atlaskit/platform/expand-border-shorthand': 'error',
67
92
  '@atlaskit/platform/expand-background-shorthand': 'error',
@@ -91,6 +116,7 @@ const recommendedRules = {
91
116
  const jiraRules = commonConfig;
92
117
  const jsonPrefix = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, @typescript-eslint/semi, no-template-curly-in-string */ module.exports = ';
93
118
  const jsonPrefixForFlatConfig = '/* eslint-disable quote-props, comma-dangle, quotes, semi, eol-last, no-template-curly-in-string */ module.exports = ';
119
+ const jsonPrefixForJira = 'module.exports = ';
94
120
  const {
95
121
  name,
96
122
  version
@@ -139,7 +165,14 @@ const plugin = {
139
165
  },
140
166
  processors: {
141
167
  'package-json-processor': {
142
- preprocess: source => {
168
+ preprocess: (source, filename) => {
169
+ // we only need to check for jiraRoot because it uses a different
170
+ // ESLint version and produces fake errors due to how this processor handles JSON
171
+ if (jiraRoot && filename.startsWith(jiraRoot)) {
172
+ // augment the json into a js file
173
+ return [jsonPrefixForJira + source.trim()];
174
+ }
175
+
143
176
  // augment the json into a js file
144
177
  return [jsonPrefix + source.trim()];
145
178
  },
@@ -166,7 +199,13 @@ const plugin = {
166
199
  // This processor is used for ESLint FlatConfig,
167
200
  // once we roll out FlatConfig, we can remove the above processor
168
201
  'package-json-processor-for-flat-config': {
169
- preprocess: source => {
202
+ // we only need to check for jiraRoot because it uses a different
203
+ // ESLint version and produces fake errors due to how this processor handles JSON
204
+ preprocess: (source, filename) => {
205
+ if (jiraRoot && filename.startsWith(jiraRoot)) {
206
+ // augment the json into a js file
207
+ return [jsonPrefixForJira + source.trim()];
208
+ }
170
209
  // augment the json into a js file
171
210
  return [jsonPrefixForFlatConfig + source.trim()];
172
211
  },
@@ -1,6 +1,9 @@
1
1
  import path from 'path';
2
2
  import { getMetadataForFilename } from '../util/registration-utils';
3
3
  const exportsValidationExceptions = {
4
+ '@af/yarn-workspace': {
5
+ ignoredAfExportKeys: ['./lock-parser']
6
+ },
4
7
  '@atlaskit/tokens': {
5
8
  ignoredAfExportKeys: ['./babel-plugin']
6
9
  },