@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.
- package/CHANGELOG.md +18 -0
- package/afm-cc/tsconfig.json +1 -1
- package/dist/cjs/index.js +42 -3
- package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +3 -0
- package/dist/cjs/rules/ensure-no-private-dependencies/index.js +101 -0
- package/dist/cjs/rules/ensure-valid-platform-yarn-protocol-usage/index.js +3 -15
- package/dist/cjs/rules/feature-gating/no-preconditioning/index.js +1 -1
- package/dist/cjs/rules/no-direct-document-usage/index.js +103 -0
- package/dist/cjs/rules/no-sparse-checkout/index.js +43 -0
- package/dist/cjs/rules/util/file-exclusions.js +45 -0
- package/dist/es2019/index.js +42 -3
- package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +3 -0
- package/dist/es2019/rules/ensure-no-private-dependencies/index.js +63 -0
- package/dist/es2019/rules/ensure-valid-platform-yarn-protocol-usage/index.js +4 -16
- package/dist/es2019/rules/feature-gating/no-preconditioning/index.js +1 -1
- package/dist/es2019/rules/no-direct-document-usage/index.js +95 -0
- package/dist/es2019/rules/no-sparse-checkout/index.js +35 -0
- package/dist/es2019/rules/util/file-exclusions.js +37 -0
- package/dist/esm/index.js +42 -3
- package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +3 -0
- package/dist/esm/rules/ensure-no-private-dependencies/index.js +96 -0
- package/dist/esm/rules/ensure-valid-platform-yarn-protocol-usage/index.js +4 -16
- package/dist/esm/rules/feature-gating/no-preconditioning/index.js +1 -1
- package/dist/esm/rules/no-direct-document-usage/index.js +97 -0
- package/dist/esm/rules/no-sparse-checkout/index.js +37 -0
- package/dist/esm/rules/util/file-exclusions.js +39 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/rules/ensure-no-private-dependencies/index.d.ts +3 -0
- package/dist/types/rules/no-direct-document-usage/index.d.ts +3 -0
- package/dist/types/rules/no-sparse-checkout/index.d.ts +3 -0
- package/dist/types/rules/util/file-exclusions.d.ts +13 -0
- package/dist/types-ts4.5/index.d.ts +14 -0
- package/dist/types-ts4.5/rules/ensure-no-private-dependencies/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-direct-document-usage/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-sparse-checkout/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/util/file-exclusions.d.ts +13 -0
- package/package.json +12 -2
- package/src/index.tsx +46 -2
- package/src/rules/ensure-native-and-af-exports-synced/index.tsx +3 -0
- package/src/rules/ensure-no-private-dependencies/__tests__/unit/rule.test.ts +212 -0
- package/src/rules/ensure-no-private-dependencies/index.ts +64 -0
- package/src/rules/ensure-valid-bin-values/__tests__/unit/rule.test.ts +3 -2
- package/src/rules/ensure-valid-platform-yarn-protocol-usage/__tests__/unit/rule.test.ts +57 -109
- package/src/rules/ensure-valid-platform-yarn-protocol-usage/index.ts +4 -16
- package/src/rules/feature-gating/no-preconditioning/index.tsx +1 -1
- package/src/rules/no-direct-document-usage/index.tsx +109 -0
- package/src/rules/no-sparse-checkout/__tests__/unit/rule.test.tsx +48 -0
- package/src/rules/no-sparse-checkout/index.tsx +54 -0
- package/src/rules/util/file-exclusions.ts +39 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { tester } from '../../../../__tests__/utils/_tester';
|
|
2
|
+
import rule from '../../index';
|
|
3
|
+
|
|
4
|
+
const cwd = process.cwd();
|
|
5
|
+
|
|
6
|
+
jest.mock('@manypkg/find-root');
|
|
7
|
+
|
|
8
|
+
jest.mock('@manypkg/get-packages', () => ({
|
|
9
|
+
getPackagesSync: () => {
|
|
10
|
+
return {
|
|
11
|
+
packages: [
|
|
12
|
+
// Private packages
|
|
13
|
+
{
|
|
14
|
+
packageJson: {
|
|
15
|
+
name: '@af/private-pkg',
|
|
16
|
+
private: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
packageJson: {
|
|
21
|
+
name: '@atlassian/private-pkg',
|
|
22
|
+
private: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
packageJson: {
|
|
27
|
+
name: '@atlassiansox/private-pkg',
|
|
28
|
+
private: true,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
// Public packages
|
|
32
|
+
{
|
|
33
|
+
packageJson: {
|
|
34
|
+
name: '@atlassian/public-pkg',
|
|
35
|
+
publishConfig: { registry: 'https://pkg-registry.com' },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
packageJson: {
|
|
40
|
+
name: '@atlassiansox/public-pkg',
|
|
41
|
+
publishConfig: { registry: 'https://pkg-registry.com' },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
packageJson: {
|
|
46
|
+
name: '@atlaskit/public-pkg',
|
|
47
|
+
publishConfig: { registry: 'https://pkg-registry.com' },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
const getErrorMessage = (pkgName: string) =>
|
|
56
|
+
`Published package has private dependency '${pkgName}'. To resolve this error, remove the private dependency or set this package to private.`;
|
|
57
|
+
|
|
58
|
+
describe('test ensure-no-private-dependencies', () => {
|
|
59
|
+
tester.run('ensure-no-private-dependencies', rule, {
|
|
60
|
+
valid: [
|
|
61
|
+
// Private and public dependencies are allowed in private '@af' scoped packages
|
|
62
|
+
{
|
|
63
|
+
code: `const foo = {
|
|
64
|
+
"name:": "@af/test",
|
|
65
|
+
"private": true,
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@af/private-pkg": "workspace:*",
|
|
68
|
+
"@af/public-pkg": "workspace:*",
|
|
69
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
70
|
+
"@atlassian/public-pkg": "workspace:*",
|
|
71
|
+
"@atlassiansox/private-pkg": "workspace:*",
|
|
72
|
+
"@atlassiansox/public-pkg": "workspace:*",
|
|
73
|
+
"react": "root:*"
|
|
74
|
+
}
|
|
75
|
+
}`,
|
|
76
|
+
filename: `${cwd}/packages/fpp/package.json`,
|
|
77
|
+
},
|
|
78
|
+
// Private and public dependencies are allowed in private '@atlassian' scoped packages
|
|
79
|
+
{
|
|
80
|
+
code: `const foo = {
|
|
81
|
+
"name:": "@atlassian/test",
|
|
82
|
+
"private": true,
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@af/private-pkg": "workspace:*",
|
|
85
|
+
"@af/public-pkg": "workspace:*",
|
|
86
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
87
|
+
"@atlassian/public-pkg": "workspace:*",
|
|
88
|
+
"@atlassiansox/private-pkg": "workspace:*",
|
|
89
|
+
"@atlassiansox/public-pkg": "workspace:*",
|
|
90
|
+
"react": "root:*"
|
|
91
|
+
}
|
|
92
|
+
}`,
|
|
93
|
+
filename: `${cwd}/packages/fpp/package.json`,
|
|
94
|
+
},
|
|
95
|
+
// Private dependencies are allowed in private '@atlassiansox' scoped packages
|
|
96
|
+
{
|
|
97
|
+
code: `const foo = {
|
|
98
|
+
"name:": "@atlassiansox/test",
|
|
99
|
+
"private": true,
|
|
100
|
+
"dependencies": {
|
|
101
|
+
"@af/private-pkg": "workspace:*",
|
|
102
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
103
|
+
"@atlassiansox/private-pkg": "workspace:*",
|
|
104
|
+
"react": "root:*"
|
|
105
|
+
}
|
|
106
|
+
}`,
|
|
107
|
+
filename: `${cwd}/packages/foo/package.json`,
|
|
108
|
+
},
|
|
109
|
+
// Private and public dependencies are allowed in private '@atlassiansox' scoped packages
|
|
110
|
+
{
|
|
111
|
+
code: `const foo = {
|
|
112
|
+
"name:": "@atlassiansox/test",
|
|
113
|
+
"private": true,
|
|
114
|
+
"dependencies": {
|
|
115
|
+
"@af/private-pkg": "workspace:*",
|
|
116
|
+
"@af/public-pkg": "workspace:*",
|
|
117
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
118
|
+
"@atlassian/public-pkg": "workspace:*",
|
|
119
|
+
"@atlassiansox/private-pkg": "workspace:*",
|
|
120
|
+
"@atlassiansox/public-pkg": "workspace:*",
|
|
121
|
+
"react": "root:*"
|
|
122
|
+
}
|
|
123
|
+
}`,
|
|
124
|
+
filename: `${cwd}/packages/fpp/package.json`,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
invalid: [
|
|
128
|
+
// Disallow private dependencies in public '@atlaskit' scoped packages
|
|
129
|
+
{
|
|
130
|
+
code: `const foo = {
|
|
131
|
+
"name": "@atlaskit/test",
|
|
132
|
+
"publishConfig": { "registry": "https://pkg-registry.com" },
|
|
133
|
+
"dependencies": {
|
|
134
|
+
"@af/private-pkg": "workspace:*",
|
|
135
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
136
|
+
"@atlassiansox/private-pkg": "workspace:*",
|
|
137
|
+
"react": "root:*"
|
|
138
|
+
}
|
|
139
|
+
}`,
|
|
140
|
+
filename: `${cwd}/packages/foo/package.json`,
|
|
141
|
+
errors: [
|
|
142
|
+
{
|
|
143
|
+
message:
|
|
144
|
+
"Published package has private dependency '@af/private-pkg'. To resolve this error, remove the private dependency or set this package to private.",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
message:
|
|
148
|
+
"Published package has private dependency '@atlassian/private-pkg'. To resolve this error, remove the private dependency or set this package to private.",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
message:
|
|
152
|
+
"Published package has private dependency '@atlassiansox/private-pkg'. To resolve this error, remove the private dependency or set this package to private.",
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
// Disallow private dependencies in public '@atlassian' scoped packages
|
|
157
|
+
{
|
|
158
|
+
code: `const foo = {
|
|
159
|
+
"name": "@atlassian/test",
|
|
160
|
+
"publishConfig": { "registry": "https://registry.npmjs.org/" },
|
|
161
|
+
"dependencies": {
|
|
162
|
+
"@af/private-pkg": "workspace:*",
|
|
163
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
164
|
+
"@atlassiansox/private-pkg": "workspace:*"
|
|
165
|
+
}
|
|
166
|
+
}`,
|
|
167
|
+
filename: `${cwd}/packages/foo/package.json`,
|
|
168
|
+
errors: [
|
|
169
|
+
{ message: getErrorMessage('@af/private-pkg') },
|
|
170
|
+
{ message: getErrorMessage('@atlassian/private-pkg') },
|
|
171
|
+
{ message: getErrorMessage('@atlassiansox/private-pkg') },
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
// Disallow private dependencies in public '@atlassiansox' scoped packages
|
|
175
|
+
{
|
|
176
|
+
code: `const foo = {
|
|
177
|
+
"name": "@atlassian/test3",
|
|
178
|
+
"publishConfig": { "registry": "https://registry.npmjs.org/" },
|
|
179
|
+
"dependencies": {
|
|
180
|
+
"@af/private-pkg": "workspace:*",
|
|
181
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
182
|
+
"@atlassiansox/private-pkg": "workspace:*"
|
|
183
|
+
}
|
|
184
|
+
}`,
|
|
185
|
+
filename: `${cwd}/packages/foo/package.json`,
|
|
186
|
+
errors: [
|
|
187
|
+
{ message: getErrorMessage('@af/private-pkg') },
|
|
188
|
+
{ message: getErrorMessage('@atlassian/private-pkg') },
|
|
189
|
+
{ message: getErrorMessage('@atlassiansox/private-pkg') },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
// Disallow private peer dependencies
|
|
193
|
+
{
|
|
194
|
+
code: `const foo = {
|
|
195
|
+
"name": "@atlaskit/test",
|
|
196
|
+
"publishConfig": { "registry": "https://registry.npmjs.org/" },
|
|
197
|
+
"peerDependencies": {
|
|
198
|
+
"@af/private-pkg": "workspace:*",
|
|
199
|
+
"@atlassian/private-pkg": "workspace:*",
|
|
200
|
+
"@atlassiansox/private-pkg": "workspace:*"
|
|
201
|
+
}
|
|
202
|
+
}`,
|
|
203
|
+
filename: `${cwd}/packages/foo/package.json`,
|
|
204
|
+
errors: [
|
|
205
|
+
{ message: getErrorMessage('@af/private-pkg') },
|
|
206
|
+
{ message: getErrorMessage('@atlassian/private-pkg') },
|
|
207
|
+
{ message: getErrorMessage('@atlassiansox/private-pkg') },
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
});
|
|
212
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import type { Rule } from 'eslint';
|
|
3
|
+
import { getObjectPropertyAsObject, getObjectPropertyAsLiteral } from '../util/handle-ast-object';
|
|
4
|
+
import { getPackagesSync } from '@manypkg/get-packages';
|
|
5
|
+
import { findRootSync } from '@manypkg/find-root';
|
|
6
|
+
|
|
7
|
+
const root = findRootSync(process.cwd());
|
|
8
|
+
const pkgs = getPackagesSync(root).packages;
|
|
9
|
+
const pkgMap = new Map(pkgs.map((pkg) => [pkg.packageJson.name, pkg]));
|
|
10
|
+
|
|
11
|
+
const rule: Rule.RuleModule = {
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'problem',
|
|
14
|
+
docs: {
|
|
15
|
+
description: `Ensures that private dependencies are not used in published packages.`,
|
|
16
|
+
recommended: true,
|
|
17
|
+
},
|
|
18
|
+
hasSuggestions: false,
|
|
19
|
+
messages: {
|
|
20
|
+
invalidPrivateDependency: `Published package has private dependency '{{ pkgName }}'. To resolve this error, remove the private dependency or set this package to private.`,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
create(context) {
|
|
24
|
+
return {
|
|
25
|
+
ObjectExpression: async (node: Rule.Node) => {
|
|
26
|
+
// Only run this rule on package.json files
|
|
27
|
+
if (!context.filename.endsWith('package.json') || node.type !== 'ObjectExpression') {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Private dependencies can be used in private packages
|
|
32
|
+
const isPrivatePkg = getObjectPropertyAsLiteral(node, 'private') === true;
|
|
33
|
+
if (isPrivatePkg === true) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check for private dependencies in dependencies and peerDependencies
|
|
38
|
+
// Note: devDependencies are not checked here as they don't end up in consumer lockfiles
|
|
39
|
+
const dependencies = getObjectPropertyAsObject(node, 'dependencies');
|
|
40
|
+
const peerDependencies = getObjectPropertyAsObject(node, 'peerDependencies');
|
|
41
|
+
|
|
42
|
+
for (const obj of [dependencies, peerDependencies]) {
|
|
43
|
+
for (const p of obj?.properties || []) {
|
|
44
|
+
if (p.type === 'Property' && p.key.type === 'Literal') {
|
|
45
|
+
const key = p.key.value;
|
|
46
|
+
if (typeof key === 'string' && pkgMap.has(key)) {
|
|
47
|
+
const isPrivateDependency = pkgMap.get(key)?.packageJson.private === true;
|
|
48
|
+
if (isPrivateDependency) {
|
|
49
|
+
context.report({
|
|
50
|
+
node,
|
|
51
|
+
messageId: 'invalidPrivateDependency',
|
|
52
|
+
data: { pkgName: key },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default rule;
|
|
@@ -16,8 +16,9 @@ jest.mock('fs', () => {
|
|
|
16
16
|
const actual = jest.requireActual('fs');
|
|
17
17
|
return {
|
|
18
18
|
...actual,
|
|
19
|
-
statSync: jest.fn((
|
|
20
|
-
isFile: jest.fn(() => mockValidBinPaths.includes(
|
|
19
|
+
statSync: jest.fn((p: string) => ({
|
|
20
|
+
isFile: jest.fn(() => mockValidBinPaths.includes(p)),
|
|
21
|
+
isDirectory: jest.fn(() => actual.statSync(p).isDirectory()),
|
|
21
22
|
})),
|
|
22
23
|
};
|
|
23
24
|
});
|
|
@@ -6,95 +6,43 @@ const cwd = process.cwd();
|
|
|
6
6
|
describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
7
7
|
tester.run('workspace protocol', rule, {
|
|
8
8
|
valid: [
|
|
9
|
-
// Workspace protocol is allowed in
|
|
9
|
+
// Workspace protocol 'workspace:*' is allowed in packages as dependencies
|
|
10
10
|
{
|
|
11
11
|
code: `const foo = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}`,
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@atlaskit/button": "workspace:*",
|
|
14
|
+
"@atlaskit/primitives": "workspace:*",
|
|
15
|
+
"@atlaskit/tokens": "workspace:*"
|
|
16
|
+
}
|
|
17
|
+
}`,
|
|
19
18
|
filename: `${cwd}/packages/foo/package.json`,
|
|
20
19
|
},
|
|
21
|
-
// Workspace protocol is allowed in
|
|
20
|
+
// Workspace protocol 'workspace:*' is allowed in packages as devDependencies
|
|
22
21
|
{
|
|
23
22
|
code: `const foo = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}`,
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@atlaskit/button": "workspace:*",
|
|
25
|
+
"@atlaskit/primitives": "workspace:*"
|
|
26
|
+
}
|
|
27
|
+
}`,
|
|
30
28
|
filename: `${cwd}/packages/foo/package.json`,
|
|
31
29
|
},
|
|
32
|
-
// Workspace protocol is allowed in
|
|
30
|
+
// Workspace protocol is allowed in packages dependencies and devDependencies
|
|
33
31
|
{
|
|
34
32
|
code: `const foo = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}`,
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@atlaskit/button": "workspace:*",
|
|
35
|
+
"@atlaskit/primitives": "workspace:*"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@atlaskit/button": "workspace:*",
|
|
39
|
+
"@atlaskit/primitives": "workspace:*"
|
|
40
|
+
}
|
|
41
|
+
}`,
|
|
45
42
|
filename: `${cwd}/packages/foo/package.json`,
|
|
46
43
|
},
|
|
47
44
|
],
|
|
48
|
-
invalid: [
|
|
49
|
-
// Workspace protocol is not allowed in public packages as dependencies
|
|
50
|
-
{
|
|
51
|
-
code: `const foo = {
|
|
52
|
-
"dependencies": {
|
|
53
|
-
"@atlaskit/button": "workspace:^",
|
|
54
|
-
"@atlaskit/primitives": "workspace:*",
|
|
55
|
-
"@atlaskit/tokens": "workspace:*"
|
|
56
|
-
}
|
|
57
|
-
}`,
|
|
58
|
-
filename: `${cwd}/packages/foo/package.json`,
|
|
59
|
-
errors: [
|
|
60
|
-
{
|
|
61
|
-
messageId: 'invalidWorkspaceProtocolUsage',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
// Workspace protocol is not allowed in public packages as devDependencies
|
|
66
|
-
{
|
|
67
|
-
code: `const foo = {
|
|
68
|
-
"devDependencies": {
|
|
69
|
-
"@atlaskit/button": "workspace:^",
|
|
70
|
-
"@atlaskit/primitives": "^1.0.0"
|
|
71
|
-
}
|
|
72
|
-
}`,
|
|
73
|
-
filename: `${cwd}/packages/foo/package.json`,
|
|
74
|
-
errors: [
|
|
75
|
-
{
|
|
76
|
-
messageId: 'invalidWorkspaceProtocolUsage',
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
// Workspace protocol is not allowed in public packages as dependencies and devDependencies
|
|
81
|
-
{
|
|
82
|
-
code: `const foo = {
|
|
83
|
-
"dependencies": {
|
|
84
|
-
"@atlaskit/button": "workspace:^"
|
|
85
|
-
},
|
|
86
|
-
"devDependencies": {
|
|
87
|
-
"@atlaskit/primitives": "workspace:^"
|
|
88
|
-
}
|
|
89
|
-
}`,
|
|
90
|
-
filename: `${cwd}/packages/foo/package.json`,
|
|
91
|
-
errors: [
|
|
92
|
-
{
|
|
93
|
-
messageId: 'invalidWorkspaceProtocolUsage',
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
],
|
|
45
|
+
invalid: [],
|
|
98
46
|
});
|
|
99
47
|
|
|
100
48
|
tester.run('root: protocol', rule, {
|
|
@@ -104,10 +52,10 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
104
52
|
// 'root:' protocol is not allowed in packages as dependencies
|
|
105
53
|
{
|
|
106
54
|
code: `const foo = {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"react": "root:*",
|
|
57
|
+
}
|
|
58
|
+
}`,
|
|
111
59
|
filename: `${cwd}/packages/foo/package.json`,
|
|
112
60
|
errors: [
|
|
113
61
|
{
|
|
@@ -118,11 +66,11 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
118
66
|
// 'root:' protocol is not allowed in private packages as dependencies
|
|
119
67
|
{
|
|
120
68
|
code: `const foo = {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
69
|
+
"private": true,
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"react": "root:*",
|
|
72
|
+
}
|
|
73
|
+
}`,
|
|
126
74
|
filename: `${cwd}/packages/foo/package.json`,
|
|
127
75
|
errors: [
|
|
128
76
|
{
|
|
@@ -133,10 +81,10 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
133
81
|
// 'root:' protocol is not allowed in public packages as devDependencies
|
|
134
82
|
{
|
|
135
83
|
code: `const foo = {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"react": "root:*",
|
|
86
|
+
}
|
|
87
|
+
}`,
|
|
140
88
|
filename: `${cwd}/packages/foo/package.json`,
|
|
141
89
|
errors: [
|
|
142
90
|
{
|
|
@@ -147,11 +95,11 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
147
95
|
// 'root:' protocol is not allowed in private packages as devDependencies
|
|
148
96
|
{
|
|
149
97
|
code: `const foo = {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
98
|
+
"private": true,
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"react": "root:*",
|
|
101
|
+
}
|
|
102
|
+
}`,
|
|
155
103
|
filename: `${cwd}/packages/foo/package.json`,
|
|
156
104
|
errors: [
|
|
157
105
|
{
|
|
@@ -162,13 +110,13 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
162
110
|
// 'root:' protocol is not allowed in public packages as dependencies and devDependencies
|
|
163
111
|
{
|
|
164
112
|
code: `const foo = {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
113
|
+
"dependencies": {
|
|
114
|
+
"lodash": "root:*"
|
|
115
|
+
},
|
|
116
|
+
"devDependencies": {
|
|
117
|
+
"react": "root:*"
|
|
118
|
+
}
|
|
119
|
+
}`,
|
|
172
120
|
filename: `${cwd}/packages/foo/package.json`,
|
|
173
121
|
errors: [
|
|
174
122
|
{
|
|
@@ -179,14 +127,14 @@ describe('test ensure-valid-platform-yarn-protocol-usage rule', () => {
|
|
|
179
127
|
// 'root:' protocol is not allowed in private packages as dependencies and devDependencies
|
|
180
128
|
{
|
|
181
129
|
code: `const foo = {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
130
|
+
"private": true,
|
|
131
|
+
"dependencies": {
|
|
132
|
+
"lodash": "root:*"
|
|
133
|
+
},
|
|
134
|
+
"devDependencies": {
|
|
135
|
+
"react": "root:*"
|
|
136
|
+
}
|
|
137
|
+
}`,
|
|
190
138
|
filename: `${cwd}/packages/foo/package.json`,
|
|
191
139
|
errors: [
|
|
192
140
|
{
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
2
|
import type { Rule } from 'eslint';
|
|
3
3
|
import type { ObjectExpression } from 'estree';
|
|
4
|
-
import { getObjectPropertyAsObject
|
|
4
|
+
import { getObjectPropertyAsObject } from '../util/handle-ast-object';
|
|
5
5
|
|
|
6
|
-
const workspaceProtocolRegex = /^workspace:[\^~\*]$/;
|
|
7
6
|
const rootProtocolRegex = /^root:[\^~\*]$/;
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -14,14 +13,12 @@ function getYarnProtocolsUsed(node: ObjectExpression) {
|
|
|
14
13
|
|
|
15
14
|
const dependencies = getObjectPropertyAsObject(node, 'dependencies');
|
|
16
15
|
const devDependencies = getObjectPropertyAsObject(node, 'devDependencies');
|
|
16
|
+
const peerDependencies = getObjectPropertyAsObject(node, 'peerDependencies');
|
|
17
17
|
|
|
18
|
-
for (const obj of [dependencies, devDependencies]) {
|
|
18
|
+
for (const obj of [dependencies, devDependencies, peerDependencies]) {
|
|
19
19
|
for (const p of obj?.properties || []) {
|
|
20
20
|
if (p.type === 'Property' && p.value.type === 'Literal') {
|
|
21
21
|
if (typeof p.value.value === 'string') {
|
|
22
|
-
if (workspaceProtocolRegex.test(p.value.value)) {
|
|
23
|
-
protocolsUsed.workspace = true;
|
|
24
|
-
}
|
|
25
22
|
if (rootProtocolRegex.test(p.value.value)) {
|
|
26
23
|
protocolsUsed.root = true;
|
|
27
24
|
}
|
|
@@ -42,7 +39,7 @@ const rule: Rule.RuleModule = {
|
|
|
42
39
|
},
|
|
43
40
|
hasSuggestions: false,
|
|
44
41
|
messages: {
|
|
45
|
-
invalidWorkspaceProtocolUsage: `The 'workspace
|
|
42
|
+
invalidWorkspaceProtocolUsage: `The 'workspace:^'protocol is Used. To resolve this error, please use the 'workspace:*' protocol instead.`,
|
|
46
43
|
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').`,
|
|
47
44
|
},
|
|
48
45
|
},
|
|
@@ -62,15 +59,6 @@ const rule: Rule.RuleModule = {
|
|
|
62
59
|
messageId: 'invalidRootProtocolUsage',
|
|
63
60
|
});
|
|
64
61
|
}
|
|
65
|
-
|
|
66
|
-
// The 'workspace:' protocol can not be used in public packages
|
|
67
|
-
const isPrivatePackage = getObjectPropertyAsLiteral(node, 'private') === true;
|
|
68
|
-
if (!isPrivatePackage && yarnProtocolsUsed.workspace) {
|
|
69
|
-
context.report({
|
|
70
|
-
node,
|
|
71
|
-
messageId: 'invalidWorkspaceProtocolUsage',
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
62
|
},
|
|
75
63
|
};
|
|
76
64
|
},
|
|
@@ -68,7 +68,7 @@ const rule: Rule.RuleModule = {
|
|
|
68
68
|
},
|
|
69
69
|
messages: {
|
|
70
70
|
useConfig:
|
|
71
|
-
'Do not precondition gates or experiments with another gate. Configure this in Statsig instead to reduce unnecessary code and
|
|
71
|
+
'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.',
|
|
72
72
|
incorrectExposure:
|
|
73
73
|
'Evaluate gates or experiments at the end of your logical expression to ensure exposure is tracked correctly.',
|
|
74
74
|
},
|