@atlaskit/eslint-plugin-platform 0.2.4 → 0.2.6
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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +87 -0
- package/dist/cjs/rules/ensure-feature-flag-registration/index.js +2 -2
- package/dist/cjs/rules/ensure-publish-valid/index.js +76 -0
- package/dist/cjs/rules/ensure-test-runner-nested-count/index.js +2 -2
- package/dist/cjs/rules/util/handle-ast-object.js +32 -0
- package/dist/es2019/index.js +5 -1
- package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +64 -0
- package/dist/es2019/rules/ensure-publish-valid/index.js +68 -0
- package/dist/es2019/rules/util/handle-ast-object.js +20 -0
- package/dist/esm/index.js +5 -1
- package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +80 -0
- package/dist/esm/rules/ensure-feature-flag-registration/index.js +2 -2
- package/dist/esm/rules/ensure-publish-valid/index.js +69 -0
- package/dist/esm/rules/ensure-test-runner-nested-count/index.js +2 -2
- package/dist/esm/rules/util/handle-ast-object.js +24 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/rules/ensure-critical-dependency-resolutions/index.d.ts +3 -0
- package/dist/types/rules/ensure-publish-valid/index.d.ts +3 -0
- package/dist/types/rules/util/handle-ast-object.d.ts +3 -0
- package/dist/types-ts4.5/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/ensure-critical-dependency-resolutions/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/ensure-publish-valid/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/util/handle-ast-object.d.ts +3 -0
- package/package.json +2 -1
- package/report.api.md +2 -0
- package/src/index.tsx +4 -0
- package/src/rules/ensure-critical-dependency-resolutions/__test__/unit/rule.test.tsx +125 -0
- package/src/rules/ensure-critical-dependency-resolutions/index.tsx +113 -0
- package/src/rules/ensure-publish-valid/__tests__/unit/rule.test.ts +41 -0
- package/src/rules/ensure-publish-valid/index.ts +95 -0
- package/src/rules/util/handle-ast-object.ts +44 -0
- package/tmp/api-report-tmp.d.ts +2 -0
- package/tsconfig.app.json +36 -0
- package/tsconfig.dev.json +40 -0
- package/dist/cjs/version.json +0 -5
- package/dist/es2019/version.json +0 -5
- package/dist/esm/version.json +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-platform
|
|
2
2
|
|
|
3
|
+
## 0.2.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`7efeb93141c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/7efeb93141c) - Add a rule to ensure critical packages are resolved to the correct versions
|
|
8
|
+
|
|
9
|
+
## 0.2.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`e5f52093b2a`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e5f52093b2a) - Add a rule to ensure that publish config is correct for packages
|
|
14
|
+
|
|
3
15
|
## 0.2.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/cjs/index.js
CHANGED
|
@@ -12,16 +12,20 @@ var _ensureTestRunnerNestedCount = _interopRequireDefault(require("./rules/ensur
|
|
|
12
12
|
var _ensureAtlassianTeam = _interopRequireDefault(require("./rules/ensure-atlassian-team"));
|
|
13
13
|
var _noInvalidFeatureFlagUsage = _interopRequireDefault(require("./rules/no-invalid-feature-flag-usage"));
|
|
14
14
|
var _ensureFeatureFlagPrefix = _interopRequireDefault(require("./rules/ensure-feature-flag-prefix"));
|
|
15
|
+
var _ensureCriticalDependencyResolutions = _interopRequireDefault(require("./rules/ensure-critical-dependency-resolutions"));
|
|
15
16
|
var _noInvalidStorybookDecoratorUsage = _interopRequireDefault(require("./rules/no-invalid-storybook-decorator-usage"));
|
|
17
|
+
var _ensurePublishValid = _interopRequireDefault(require("./rules/ensure-publish-valid"));
|
|
16
18
|
var rules = {
|
|
17
19
|
'ensure-feature-flag-registration': _ensureFeatureFlagRegistration.default,
|
|
18
20
|
'ensure-feature-flag-prefix': _ensureFeatureFlagPrefix.default,
|
|
19
21
|
'ensure-test-runner-arguments': _ensureTestRunnerArguments.default,
|
|
20
22
|
'ensure-test-runner-nested-count': _ensureTestRunnerNestedCount.default,
|
|
21
23
|
'ensure-atlassian-team': _ensureAtlassianTeam.default,
|
|
24
|
+
'ensure-critical-dependency-resolutions': _ensureCriticalDependencyResolutions.default,
|
|
22
25
|
'no-invalid-feature-flag-usage': _noInvalidFeatureFlagUsage.default,
|
|
23
26
|
'no-pre-post-install-scripts': _noPrePostInstalls.default,
|
|
24
|
-
'no-invalid-storybook-decorator-usage': _noInvalidStorybookDecoratorUsage.default
|
|
27
|
+
'no-invalid-storybook-decorator-usage': _noInvalidStorybookDecoratorUsage.default,
|
|
28
|
+
'ensure-publish-valid': _ensurePublishValid.default
|
|
25
29
|
};
|
|
26
30
|
exports.rules = rules;
|
|
27
31
|
var configs = {
|
|
@@ -0,0 +1,87 @@
|
|
|
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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _findRoot = require("@manypkg/find-root");
|
|
10
|
+
var _handleAstObject = require("../util/handle-ast-object");
|
|
11
|
+
// Here we only need to specify the major and minor versions
|
|
12
|
+
// In matchMinorVersion, we will check if the versions in resolutions fall in the right ranges.
|
|
13
|
+
var DESIRED_PKG_VERSIONS = {
|
|
14
|
+
typescript: '4.9',
|
|
15
|
+
'@types/react': '16.14'
|
|
16
|
+
};
|
|
17
|
+
var matchMinorVersion = function matchMinorVersion(desiredVersion, versionInResolutions) {
|
|
18
|
+
var firstChar = versionInResolutions[0];
|
|
19
|
+
// The version is invalid if it doesn't start with a number or ~
|
|
20
|
+
if (!/^\d$/.test(firstChar) && firstChar !== '~') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return versionInResolutions.startsWith(desiredVersion) || versionInResolutions.startsWith('~' + desiredVersion);
|
|
24
|
+
};
|
|
25
|
+
var verifyResolutionFromObject = function verifyResolutionFromObject(node, pkg, version, optional) {
|
|
26
|
+
// For root package.json, we require the critical packages' resolutions exist and with matching version
|
|
27
|
+
// For individual package's package.json, it's ok if resolutions don't exist. But if they do, the version should match
|
|
28
|
+
var resolutionExist = node.properties.some(function (p) {
|
|
29
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg;
|
|
30
|
+
});
|
|
31
|
+
if (!resolutionExist) {
|
|
32
|
+
return optional;
|
|
33
|
+
}
|
|
34
|
+
var resolutionExistAndMatch = node.properties.some(function (p) {
|
|
35
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg && p.value.type === 'Literal' && matchMinorVersion(version, p.value.value);
|
|
36
|
+
});
|
|
37
|
+
return resolutionExistAndMatch;
|
|
38
|
+
};
|
|
39
|
+
var rule = {
|
|
40
|
+
meta: {
|
|
41
|
+
type: 'problem',
|
|
42
|
+
docs: {
|
|
43
|
+
description: 'Enforce the versions of critical packages are within desired ranges by checking resolutions section in package.json',
|
|
44
|
+
recommended: true
|
|
45
|
+
},
|
|
46
|
+
hasSuggestions: false,
|
|
47
|
+
messages: {
|
|
48
|
+
invalidPackageResolution: "Make sure the resolutions for the following packages match major and minor version ranges ".concat(JSON.stringify(DESIRED_PKG_VERSIONS))
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
create: function create(context) {
|
|
52
|
+
var fileName = context.getFilename();
|
|
53
|
+
return {
|
|
54
|
+
ObjectExpression: function (_ObjectExpression) {
|
|
55
|
+
function ObjectExpression(_x) {
|
|
56
|
+
return _ObjectExpression.apply(this, arguments);
|
|
57
|
+
}
|
|
58
|
+
ObjectExpression.toString = function () {
|
|
59
|
+
return _ObjectExpression.toString();
|
|
60
|
+
};
|
|
61
|
+
return ObjectExpression;
|
|
62
|
+
}(function (node) {
|
|
63
|
+
if (!fileName.endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
var packageResolutions = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'resolutions');
|
|
67
|
+
var rootDir = (0, _findRoot.findRootSync)(process.cwd());
|
|
68
|
+
var isRootPackageJson = fileName.endsWith("".concat(rootDir, "/package.json"));
|
|
69
|
+
if (packageResolutions !== null) {
|
|
70
|
+
for (var _i = 0, _Object$entries = Object.entries(DESIRED_PKG_VERSIONS); _i < _Object$entries.length; _i++) {
|
|
71
|
+
var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
|
|
72
|
+
key = _Object$entries$_i[0],
|
|
73
|
+
value = _Object$entries$_i[1];
|
|
74
|
+
if (!verifyResolutionFromObject(packageResolutions, key, value, !isRootPackageJson)) {
|
|
75
|
+
return context.report({
|
|
76
|
+
node: node,
|
|
77
|
+
messageId: 'invalidPackageResolution'
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var _default = rule;
|
|
87
|
+
exports.default = _default;
|
|
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _registrationUtils = require("../util/registration-utils");
|
|
10
|
-
function ownKeys(
|
|
11
|
-
function _objectSpread(
|
|
10
|
+
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; }
|
|
11
|
+
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; }
|
|
12
12
|
var rule = {
|
|
13
13
|
meta: {
|
|
14
14
|
docs: {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _handleAstObject = require("../util/handle-ast-object");
|
|
8
|
+
var rule = {
|
|
9
|
+
meta: {
|
|
10
|
+
type: 'problem',
|
|
11
|
+
docs: {
|
|
12
|
+
description: 'This rule ensures that the package.json for your packages are set up correctly for publishing depending on the package name prefix',
|
|
13
|
+
recommended: true
|
|
14
|
+
},
|
|
15
|
+
hasSuggestions: false,
|
|
16
|
+
schema: [{
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
exceptions: {
|
|
20
|
+
type: 'array',
|
|
21
|
+
items: [{
|
|
22
|
+
type: 'string'
|
|
23
|
+
}]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}],
|
|
27
|
+
messages: {
|
|
28
|
+
publishConfigRequired: '@atlaskit prefix is public! You have to specify a `publishConfig`, (package {{packageName}}) see https://go.atlassian.com/package-namespace',
|
|
29
|
+
noPrivate: 'setting private to true prevents publishing, your package prefix implies you want to publish! (package {{packageName}}) see https://go.atlassian.com/package-namespace'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
create: function create(context) {
|
|
33
|
+
var _ref2, _context$options;
|
|
34
|
+
var _ref = (_ref2 = (_context$options = context.options) === null || _context$options === void 0 ? void 0 : _context$options[0]) !== null && _ref2 !== void 0 ? _ref2 : {},
|
|
35
|
+
exceptions = _ref.exceptions;
|
|
36
|
+
return {
|
|
37
|
+
ObjectExpression: function ObjectExpression(node) {
|
|
38
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
var packageName = (0, _handleAstObject.getObjectPropertyAsLiteral)(node, 'name');
|
|
42
|
+
var packagePrivate = (0, _handleAstObject.getObjectPropertyAsLiteral)(node, 'private');
|
|
43
|
+
var packagePublishConfig = (0, _handleAstObject.getObjectPropertyAsObject)(node, 'publishConfig');
|
|
44
|
+
|
|
45
|
+
// exit if package is on known exception list
|
|
46
|
+
if (exceptions && exceptions.findIndex(function (name) {
|
|
47
|
+
return name === packageName;
|
|
48
|
+
}) !== -1) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (typeof packageName === 'string' && packageName.startsWith('@atlaskit')) {
|
|
52
|
+
if (typeof packagePrivate === 'boolean' && packagePrivate) {
|
|
53
|
+
return context.report({
|
|
54
|
+
node: node,
|
|
55
|
+
messageId: 'noPrivate',
|
|
56
|
+
data: {
|
|
57
|
+
packageName: packageName
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (packagePublishConfig === null) {
|
|
62
|
+
return context.report({
|
|
63
|
+
node: node,
|
|
64
|
+
messageId: 'publishConfigRequired',
|
|
65
|
+
data: {
|
|
66
|
+
packageName: packageName
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var _default = rule;
|
|
76
|
+
exports.default = _default;
|
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
-
function ownKeys(
|
|
10
|
-
function _objectSpread(
|
|
9
|
+
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; }
|
|
10
|
+
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; }
|
|
11
11
|
var NESTED_LIMIT = 4;
|
|
12
12
|
var TEST_RUNNER_IDENTIFIER = 'ffTest';
|
|
13
13
|
var getDepthOfNestedRunner = function getDepthOfNestedRunner(node) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getObjectPropertyAsObject = exports.getObjectPropertyAsLiteral = void 0;
|
|
7
|
+
var getObjectPropertyAsLiteral = function getObjectPropertyAsLiteral(node, property) {
|
|
8
|
+
var prop = node.properties.find(function (p) {
|
|
9
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === property;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// double check for property is to make typescript happy
|
|
13
|
+
if ((prop === null || prop === void 0 ? void 0 : prop.type) === 'Property' && (prop === null || prop === void 0 ? void 0 : prop.value.type) === 'Literal') {
|
|
14
|
+
var _prop$value$value;
|
|
15
|
+
return (_prop$value$value = prop.value.value) !== null && _prop$value$value !== void 0 ? _prop$value$value : null;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
exports.getObjectPropertyAsLiteral = getObjectPropertyAsLiteral;
|
|
20
|
+
var getObjectPropertyAsObject = function getObjectPropertyAsObject(node, property) {
|
|
21
|
+
var prop = node.properties.find(function (p) {
|
|
22
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === property;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// double check for property is to make typescript happy
|
|
26
|
+
if ((prop === null || prop === void 0 ? void 0 : prop.type) === 'Property' && (prop === null || prop === void 0 ? void 0 : prop.value.type) === 'ObjectExpression') {
|
|
27
|
+
var _prop$value;
|
|
28
|
+
return (_prop$value = prop.value) !== null && _prop$value !== void 0 ? _prop$value : null;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
exports.getObjectPropertyAsObject = getObjectPropertyAsObject;
|
package/dist/es2019/index.js
CHANGED
|
@@ -5,16 +5,20 @@ import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count
|
|
|
5
5
|
import ensureAtlassianTeam from './rules/ensure-atlassian-team';
|
|
6
6
|
import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
|
|
7
7
|
import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
|
|
8
|
+
import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
|
|
8
9
|
import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
|
|
10
|
+
import ensurePublishValid from './rules/ensure-publish-valid';
|
|
9
11
|
export const rules = {
|
|
10
12
|
'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
|
|
11
13
|
'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
|
|
12
14
|
'ensure-test-runner-arguments': ensureTestRunnerArguments,
|
|
13
15
|
'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
|
|
14
16
|
'ensure-atlassian-team': ensureAtlassianTeam,
|
|
17
|
+
'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
|
|
15
18
|
'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
|
|
16
19
|
'no-pre-post-install-scripts': noPreAndPostInstallScripts,
|
|
17
|
-
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage
|
|
20
|
+
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage,
|
|
21
|
+
'ensure-publish-valid': ensurePublishValid
|
|
18
22
|
};
|
|
19
23
|
export const configs = {
|
|
20
24
|
recommended: {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { findRootSync } from '@manypkg/find-root';
|
|
2
|
+
import { getObjectPropertyAsObject } from '../util/handle-ast-object';
|
|
3
|
+
|
|
4
|
+
// Here we only need to specify the major and minor versions
|
|
5
|
+
// In matchMinorVersion, we will check if the versions in resolutions fall in the right ranges.
|
|
6
|
+
const DESIRED_PKG_VERSIONS = {
|
|
7
|
+
typescript: '4.9',
|
|
8
|
+
'@types/react': '16.14'
|
|
9
|
+
};
|
|
10
|
+
const matchMinorVersion = (desiredVersion, versionInResolutions) => {
|
|
11
|
+
const firstChar = versionInResolutions[0];
|
|
12
|
+
// The version is invalid if it doesn't start with a number or ~
|
|
13
|
+
if (!/^\d$/.test(firstChar) && firstChar !== '~') {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return versionInResolutions.startsWith(desiredVersion) || versionInResolutions.startsWith('~' + desiredVersion);
|
|
17
|
+
};
|
|
18
|
+
const verifyResolutionFromObject = (node, pkg, version, optional) => {
|
|
19
|
+
// For root package.json, we require the critical packages' resolutions exist and with matching version
|
|
20
|
+
// For individual package's package.json, it's ok if resolutions don't exist. But if they do, the version should match
|
|
21
|
+
const resolutionExist = node.properties.some(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg);
|
|
22
|
+
if (!resolutionExist) {
|
|
23
|
+
return optional;
|
|
24
|
+
}
|
|
25
|
+
const resolutionExistAndMatch = node.properties.some(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg && p.value.type === 'Literal' && matchMinorVersion(version, p.value.value));
|
|
26
|
+
return resolutionExistAndMatch;
|
|
27
|
+
};
|
|
28
|
+
const rule = {
|
|
29
|
+
meta: {
|
|
30
|
+
type: 'problem',
|
|
31
|
+
docs: {
|
|
32
|
+
description: 'Enforce the versions of critical packages are within desired ranges by checking resolutions section in package.json',
|
|
33
|
+
recommended: true
|
|
34
|
+
},
|
|
35
|
+
hasSuggestions: false,
|
|
36
|
+
messages: {
|
|
37
|
+
invalidPackageResolution: `Make sure the resolutions for the following packages match major and minor version ranges ${JSON.stringify(DESIRED_PKG_VERSIONS)}`
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
create(context) {
|
|
41
|
+
const fileName = context.getFilename();
|
|
42
|
+
return {
|
|
43
|
+
ObjectExpression: node => {
|
|
44
|
+
if (!fileName.endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const packageResolutions = getObjectPropertyAsObject(node, 'resolutions');
|
|
48
|
+
const rootDir = findRootSync(process.cwd());
|
|
49
|
+
const isRootPackageJson = fileName.endsWith(`${rootDir}/package.json`);
|
|
50
|
+
if (packageResolutions !== null) {
|
|
51
|
+
for (const [key, value] of Object.entries(DESIRED_PKG_VERSIONS)) {
|
|
52
|
+
if (!verifyResolutionFromObject(packageResolutions, key, value, !isRootPackageJson)) {
|
|
53
|
+
return context.report({
|
|
54
|
+
node,
|
|
55
|
+
messageId: 'invalidPackageResolution'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export default rule;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getObjectPropertyAsLiteral, getObjectPropertyAsObject } from '../util/handle-ast-object';
|
|
2
|
+
const rule = {
|
|
3
|
+
meta: {
|
|
4
|
+
type: 'problem',
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'This rule ensures that the package.json for your packages are set up correctly for publishing depending on the package name prefix',
|
|
7
|
+
recommended: true
|
|
8
|
+
},
|
|
9
|
+
hasSuggestions: false,
|
|
10
|
+
schema: [{
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
exceptions: {
|
|
14
|
+
type: 'array',
|
|
15
|
+
items: [{
|
|
16
|
+
type: 'string'
|
|
17
|
+
}]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}],
|
|
21
|
+
messages: {
|
|
22
|
+
publishConfigRequired: '@atlaskit prefix is public! You have to specify a `publishConfig`, (package {{packageName}}) see https://go.atlassian.com/package-namespace',
|
|
23
|
+
noPrivate: 'setting private to true prevents publishing, your package prefix implies you want to publish! (package {{packageName}}) see https://go.atlassian.com/package-namespace'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
create(context) {
|
|
27
|
+
var _ref, _context$options;
|
|
28
|
+
const {
|
|
29
|
+
exceptions
|
|
30
|
+
} = (_ref = (_context$options = context.options) === null || _context$options === void 0 ? void 0 : _context$options[0]) !== null && _ref !== void 0 ? _ref : {};
|
|
31
|
+
return {
|
|
32
|
+
ObjectExpression: node => {
|
|
33
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const packageName = getObjectPropertyAsLiteral(node, 'name');
|
|
37
|
+
const packagePrivate = getObjectPropertyAsLiteral(node, 'private');
|
|
38
|
+
const packagePublishConfig = getObjectPropertyAsObject(node, 'publishConfig');
|
|
39
|
+
|
|
40
|
+
// exit if package is on known exception list
|
|
41
|
+
if (exceptions && exceptions.findIndex(name => name === packageName) !== -1) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (typeof packageName === 'string' && packageName.startsWith('@atlaskit')) {
|
|
45
|
+
if (typeof packagePrivate === 'boolean' && packagePrivate) {
|
|
46
|
+
return context.report({
|
|
47
|
+
node,
|
|
48
|
+
messageId: 'noPrivate',
|
|
49
|
+
data: {
|
|
50
|
+
packageName
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (packagePublishConfig === null) {
|
|
55
|
+
return context.report({
|
|
56
|
+
node,
|
|
57
|
+
messageId: 'publishConfigRequired',
|
|
58
|
+
data: {
|
|
59
|
+
packageName
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export default rule;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const getObjectPropertyAsLiteral = (node, property) => {
|
|
2
|
+
const prop = node.properties.find(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === property);
|
|
3
|
+
|
|
4
|
+
// double check for property is to make typescript happy
|
|
5
|
+
if ((prop === null || prop === void 0 ? void 0 : prop.type) === 'Property' && (prop === null || prop === void 0 ? void 0 : prop.value.type) === 'Literal') {
|
|
6
|
+
var _prop$value$value;
|
|
7
|
+
return (_prop$value$value = prop.value.value) !== null && _prop$value$value !== void 0 ? _prop$value$value : null;
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
};
|
|
11
|
+
export const getObjectPropertyAsObject = (node, property) => {
|
|
12
|
+
const prop = node.properties.find(p => p.type === 'Property' && p.key.type === 'Literal' && p.key.value === property);
|
|
13
|
+
|
|
14
|
+
// double check for property is to make typescript happy
|
|
15
|
+
if ((prop === null || prop === void 0 ? void 0 : prop.type) === 'Property' && (prop === null || prop === void 0 ? void 0 : prop.value.type) === 'ObjectExpression') {
|
|
16
|
+
var _prop$value;
|
|
17
|
+
return (_prop$value = prop.value) !== null && _prop$value !== void 0 ? _prop$value : null;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -5,16 +5,20 @@ import ensureTestRunnerNestedCount from './rules/ensure-test-runner-nested-count
|
|
|
5
5
|
import ensureAtlassianTeam from './rules/ensure-atlassian-team';
|
|
6
6
|
import noInvalidFeatureFlagUsage from './rules/no-invalid-feature-flag-usage';
|
|
7
7
|
import ensureFeatureFlagPrefix from './rules/ensure-feature-flag-prefix';
|
|
8
|
+
import ensureCriticalDependencyResolutions from './rules/ensure-critical-dependency-resolutions';
|
|
8
9
|
import noInvalidStorybookDecoratorUsage from './rules/no-invalid-storybook-decorator-usage';
|
|
10
|
+
import ensurePublishValid from './rules/ensure-publish-valid';
|
|
9
11
|
export var rules = {
|
|
10
12
|
'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
|
|
11
13
|
'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
|
|
12
14
|
'ensure-test-runner-arguments': ensureTestRunnerArguments,
|
|
13
15
|
'ensure-test-runner-nested-count': ensureTestRunnerNestedCount,
|
|
14
16
|
'ensure-atlassian-team': ensureAtlassianTeam,
|
|
17
|
+
'ensure-critical-dependency-resolutions': ensureCriticalDependencyResolutions,
|
|
15
18
|
'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
|
|
16
19
|
'no-pre-post-install-scripts': noPreAndPostInstallScripts,
|
|
17
|
-
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage
|
|
20
|
+
'no-invalid-storybook-decorator-usage': noInvalidStorybookDecoratorUsage,
|
|
21
|
+
'ensure-publish-valid': ensurePublishValid
|
|
18
22
|
};
|
|
19
23
|
export var configs = {
|
|
20
24
|
recommended: {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import { findRootSync } from '@manypkg/find-root';
|
|
3
|
+
import { getObjectPropertyAsObject } from '../util/handle-ast-object';
|
|
4
|
+
|
|
5
|
+
// Here we only need to specify the major and minor versions
|
|
6
|
+
// In matchMinorVersion, we will check if the versions in resolutions fall in the right ranges.
|
|
7
|
+
var DESIRED_PKG_VERSIONS = {
|
|
8
|
+
typescript: '4.9',
|
|
9
|
+
'@types/react': '16.14'
|
|
10
|
+
};
|
|
11
|
+
var matchMinorVersion = function matchMinorVersion(desiredVersion, versionInResolutions) {
|
|
12
|
+
var firstChar = versionInResolutions[0];
|
|
13
|
+
// The version is invalid if it doesn't start with a number or ~
|
|
14
|
+
if (!/^\d$/.test(firstChar) && firstChar !== '~') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return versionInResolutions.startsWith(desiredVersion) || versionInResolutions.startsWith('~' + desiredVersion);
|
|
18
|
+
};
|
|
19
|
+
var verifyResolutionFromObject = function verifyResolutionFromObject(node, pkg, version, optional) {
|
|
20
|
+
// For root package.json, we require the critical packages' resolutions exist and with matching version
|
|
21
|
+
// For individual package's package.json, it's ok if resolutions don't exist. But if they do, the version should match
|
|
22
|
+
var resolutionExist = node.properties.some(function (p) {
|
|
23
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg;
|
|
24
|
+
});
|
|
25
|
+
if (!resolutionExist) {
|
|
26
|
+
return optional;
|
|
27
|
+
}
|
|
28
|
+
var resolutionExistAndMatch = node.properties.some(function (p) {
|
|
29
|
+
return p.type === 'Property' && p.key.type === 'Literal' && p.key.value === pkg && p.value.type === 'Literal' && matchMinorVersion(version, p.value.value);
|
|
30
|
+
});
|
|
31
|
+
return resolutionExistAndMatch;
|
|
32
|
+
};
|
|
33
|
+
var rule = {
|
|
34
|
+
meta: {
|
|
35
|
+
type: 'problem',
|
|
36
|
+
docs: {
|
|
37
|
+
description: 'Enforce the versions of critical packages are within desired ranges by checking resolutions section in package.json',
|
|
38
|
+
recommended: true
|
|
39
|
+
},
|
|
40
|
+
hasSuggestions: false,
|
|
41
|
+
messages: {
|
|
42
|
+
invalidPackageResolution: "Make sure the resolutions for the following packages match major and minor version ranges ".concat(JSON.stringify(DESIRED_PKG_VERSIONS))
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
create: function create(context) {
|
|
46
|
+
var fileName = context.getFilename();
|
|
47
|
+
return {
|
|
48
|
+
ObjectExpression: function (_ObjectExpression) {
|
|
49
|
+
function ObjectExpression(_x) {
|
|
50
|
+
return _ObjectExpression.apply(this, arguments);
|
|
51
|
+
}
|
|
52
|
+
ObjectExpression.toString = function () {
|
|
53
|
+
return _ObjectExpression.toString();
|
|
54
|
+
};
|
|
55
|
+
return ObjectExpression;
|
|
56
|
+
}(function (node) {
|
|
57
|
+
if (!fileName.endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var packageResolutions = getObjectPropertyAsObject(node, 'resolutions');
|
|
61
|
+
var rootDir = findRootSync(process.cwd());
|
|
62
|
+
var isRootPackageJson = fileName.endsWith("".concat(rootDir, "/package.json"));
|
|
63
|
+
if (packageResolutions !== null) {
|
|
64
|
+
for (var _i = 0, _Object$entries = Object.entries(DESIRED_PKG_VERSIONS); _i < _Object$entries.length; _i++) {
|
|
65
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
66
|
+
key = _Object$entries$_i[0],
|
|
67
|
+
value = _Object$entries$_i[1];
|
|
68
|
+
if (!verifyResolutionFromObject(packageResolutions, key, value, !isRootPackageJson)) {
|
|
69
|
+
return context.report({
|
|
70
|
+
node: node,
|
|
71
|
+
messageId: 'invalidPackageResolution'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export default rule;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
function ownKeys(
|
|
3
|
-
function _objectSpread(
|
|
2
|
+
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; }
|
|
3
|
+
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) { _defineProperty(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; }
|
|
4
4
|
import { getMetadataForFilename, getterIdentifierToFlagTypeMap } from '../util/registration-utils';
|
|
5
5
|
var rule = {
|
|
6
6
|
meta: {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { getObjectPropertyAsLiteral, getObjectPropertyAsObject } from '../util/handle-ast-object';
|
|
2
|
+
var rule = {
|
|
3
|
+
meta: {
|
|
4
|
+
type: 'problem',
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'This rule ensures that the package.json for your packages are set up correctly for publishing depending on the package name prefix',
|
|
7
|
+
recommended: true
|
|
8
|
+
},
|
|
9
|
+
hasSuggestions: false,
|
|
10
|
+
schema: [{
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
exceptions: {
|
|
14
|
+
type: 'array',
|
|
15
|
+
items: [{
|
|
16
|
+
type: 'string'
|
|
17
|
+
}]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}],
|
|
21
|
+
messages: {
|
|
22
|
+
publishConfigRequired: '@atlaskit prefix is public! You have to specify a `publishConfig`, (package {{packageName}}) see https://go.atlassian.com/package-namespace',
|
|
23
|
+
noPrivate: 'setting private to true prevents publishing, your package prefix implies you want to publish! (package {{packageName}}) see https://go.atlassian.com/package-namespace'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
create: function create(context) {
|
|
27
|
+
var _ref2, _context$options;
|
|
28
|
+
var _ref = (_ref2 = (_context$options = context.options) === null || _context$options === void 0 ? void 0 : _context$options[0]) !== null && _ref2 !== void 0 ? _ref2 : {},
|
|
29
|
+
exceptions = _ref.exceptions;
|
|
30
|
+
return {
|
|
31
|
+
ObjectExpression: function ObjectExpression(node) {
|
|
32
|
+
if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
var packageName = getObjectPropertyAsLiteral(node, 'name');
|
|
36
|
+
var packagePrivate = getObjectPropertyAsLiteral(node, 'private');
|
|
37
|
+
var packagePublishConfig = getObjectPropertyAsObject(node, 'publishConfig');
|
|
38
|
+
|
|
39
|
+
// exit if package is on known exception list
|
|
40
|
+
if (exceptions && exceptions.findIndex(function (name) {
|
|
41
|
+
return name === packageName;
|
|
42
|
+
}) !== -1) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (typeof packageName === 'string' && packageName.startsWith('@atlaskit')) {
|
|
46
|
+
if (typeof packagePrivate === 'boolean' && packagePrivate) {
|
|
47
|
+
return context.report({
|
|
48
|
+
node: node,
|
|
49
|
+
messageId: 'noPrivate',
|
|
50
|
+
data: {
|
|
51
|
+
packageName: packageName
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (packagePublishConfig === null) {
|
|
56
|
+
return context.report({
|
|
57
|
+
node: node,
|
|
58
|
+
messageId: 'publishConfigRequired',
|
|
59
|
+
data: {
|
|
60
|
+
packageName: packageName
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export default rule;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
function ownKeys(
|
|
3
|
-
function _objectSpread(
|
|
2
|
+
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; }
|
|
3
|
+
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) { _defineProperty(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; }
|
|
4
4
|
var NESTED_LIMIT = 4;
|
|
5
5
|
var TEST_RUNNER_IDENTIFIER = 'ffTest';
|
|
6
6
|
var getDepthOfNestedRunner = function getDepthOfNestedRunner(node) {
|