Skip to content

Commit d73d1ca

Browse files
feat: New rules for type field (#1087)
* Added type field rules and tests * Added documentation for type field rules * Correct lint errors --------- Co-authored-by: Thomas Lindner <[email protected]>
1 parent f9a64b2 commit d73d1ca

File tree

10 files changed

+394
-0
lines changed

10 files changed

+394
-0
lines changed

Diff for: src/rules/require-type.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {PackageJson} from 'type-fest';
2+
import {LintIssue} from '../lint-issue';
3+
import {RuleType} from '../types/rule-type';
4+
import {Severity} from '../types/severity';
5+
6+
const lintId = 'require-type';
7+
const nodeName = 'type';
8+
const message = 'type is required';
9+
10+
export const ruleType = RuleType.Standard;
11+
12+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
13+
export const lint = (packageJsonData: PackageJson | any, severity: Severity): LintIssue | null => {
14+
if (!packageJsonData.hasOwnProperty(nodeName)) {
15+
return new LintIssue(lintId, severity, nodeName, message);
16+
}
17+
18+
return null;
19+
};

Diff for: src/rules/type-type.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {PackageJson} from 'type-fest';
2+
import {LintIssue} from '../lint-issue';
3+
import {isString} from '../validators/type';
4+
import {RuleType} from '../types/rule-type';
5+
import {Severity} from '../types/severity';
6+
7+
const lintId = 'type-type';
8+
const nodeName = 'type';
9+
const message = 'Type should be a string';
10+
11+
export const ruleType = RuleType.Standard;
12+
13+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14+
export const lint = (packageJsonData: PackageJson | any, severity: Severity): LintIssue | null => {
15+
if (!isString(packageJsonData, nodeName)) {
16+
return new LintIssue(lintId, severity, nodeName, message);
17+
}
18+
19+
return null;
20+
};

Diff for: src/rules/valid-values-type.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {PackageJson} from 'type-fest';
2+
import {LintIssue} from '../lint-issue';
3+
import {LintResult} from '../types/lint-result';
4+
import {RuleType} from '../types/rule-type';
5+
import {Severity} from '../types/severity';
6+
import {isValidValue} from '../validators/valid-values';
7+
8+
const lintId = 'valid-values-type';
9+
const nodeName = 'type';
10+
11+
export const ruleType = RuleType.Array;
12+
13+
export const minItems = 1;
14+
15+
/**
16+
* [function description]
17+
* @param {Object} packageJsonData Valid package.json object
18+
* @param {String} severity 'error' or 'warning'
19+
* @param {Array} validValues An array of valid values
20+
* @return {Object|Boolean} LintIssue object if invalid. True if valid
21+
*/
22+
export const lint = (
23+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
24+
packageJsonData: PackageJson | any,
25+
severity: Severity,
26+
validValues: string[]
27+
): LintResult => {
28+
if (!isValidValue<string>(packageJsonData, nodeName, packageJsonData[nodeName], validValues)) {
29+
return new LintIssue(
30+
lintId,
31+
severity,
32+
nodeName,
33+
`Invalid value for type. Current value is ${packageJsonData[nodeName]}. Valid values include: ${validValues.join(
34+
', '
35+
)}.`
36+
);
37+
}
38+
39+
return null;
40+
};

Diff for: test/unit/rules/require-type.test.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {lint, ruleType} from '../../../src/rules/require-type';
2+
import {Severity} from '../../../src/types/severity';
3+
4+
describe('require-type Unit Tests', () => {
5+
describe('a rule type value should be exported', () => {
6+
test('it should equal "standard"', () => {
7+
expect(ruleType).toStrictEqual('standard');
8+
});
9+
});
10+
11+
describe('when package.json has node', () => {
12+
test('true should be returned', () => {
13+
const packageJsonData = {
14+
type: 'module',
15+
};
16+
const response = lint(packageJsonData, Severity.Error);
17+
18+
expect(response).toBeNull();
19+
});
20+
});
21+
22+
describe('when package.json does not have node', () => {
23+
test('LintIssue object should be returned', () => {
24+
const packageJsonData = {};
25+
const response = lint(packageJsonData, Severity.Error);
26+
27+
expect(response.lintId).toStrictEqual('require-type');
28+
expect(response.severity).toStrictEqual('error');
29+
expect(response.node).toStrictEqual('type');
30+
expect(response.lintMessage).toStrictEqual('type is required');
31+
});
32+
});
33+
});

Diff for: test/unit/rules/type-type.test.ts

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {lint, ruleType} from '../../../src/rules/type-type';
2+
import {Severity} from '../../../src/types/severity';
3+
4+
describe('type-type Unit Tests', () => {
5+
describe('a rule type value should be exported', () => {
6+
test('it should equal "standard"', () => {
7+
expect(ruleType).toStrictEqual('standard');
8+
});
9+
});
10+
11+
describe('when package.json has node with correct type', () => {
12+
test('true should be returned', () => {
13+
const packageJsonData = {
14+
type: 'module',
15+
};
16+
const response = lint(packageJsonData, Severity.Error);
17+
18+
expect(response).toBeNull();
19+
});
20+
});
21+
22+
describe('when package.json has node with incorrect type', () => {
23+
test('LintIssue object should be returned', () => {
24+
const packageJsonData = {
25+
type: true,
26+
};
27+
const response = lint(packageJsonData, Severity.Error);
28+
29+
expect(response.lintId).toStrictEqual('type-type');
30+
expect(response.severity).toStrictEqual('error');
31+
expect(response.node).toStrictEqual('type');
32+
expect(response.lintMessage).toStrictEqual('Type should be a string');
33+
});
34+
});
35+
36+
describe('when package.json does not have node', () => {
37+
test('true should be returned', () => {
38+
const packageJsonData = {};
39+
const response = lint(packageJsonData, Severity.Error);
40+
41+
expect(response).toBeNull();
42+
});
43+
});
44+
});

Diff for: test/unit/rules/valid-values-type.test.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {lint, ruleType, minItems} from '../../../src/rules/valid-values-type';
2+
import {Severity} from '../../../src/types/severity';
3+
4+
describe('valid-values-type Unit Tests', () => {
5+
describe('a rule type value should be exported', () => {
6+
test('it should equal "array"', () => {
7+
expect(ruleType).toStrictEqual('array');
8+
});
9+
});
10+
11+
describe('a minItems value should be exported', () => {
12+
test('it should equal 1', () => {
13+
expect(minItems).toStrictEqual(1);
14+
});
15+
});
16+
17+
describe('when package.json has node with incorrect format', () => {
18+
test('LintIssue object should be returned', () => {
19+
const packageJsonData = {
20+
type: 'type',
21+
};
22+
const validValues = ['commonjs', 'module'];
23+
const response = lint(packageJsonData, Severity.Error, validValues);
24+
25+
expect(response.lintId).toStrictEqual('valid-values-type');
26+
expect(response.severity).toStrictEqual('error');
27+
expect(response.node).toStrictEqual('type');
28+
expect(response.lintMessage).toStrictEqual(
29+
'Invalid value for type. Current value is type. Valid values include: commonjs, module.'
30+
);
31+
});
32+
});
33+
34+
describe('when package.json has node with correct format', () => {
35+
test('LintIssue object should be returned', () => {
36+
const packageJsonData = {
37+
type: 'module',
38+
};
39+
const validValues = ['commonjs', 'module'];
40+
const response = lint(packageJsonData, Severity.Error, validValues);
41+
42+
expect(response).toBeNull();
43+
});
44+
});
45+
46+
describe('when package.json does not have node', () => {
47+
test('true should be returned', () => {
48+
const packageJsonData = {};
49+
const response = lint(packageJsonData, Severity.Error, []);
50+
51+
expect(response).toBeNull();
52+
});
53+
});
54+
});

Diff for: website/docs/rules.md

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Rules allow npm-package-json-lint to be fully customizable. npm-package-json-lin
3939
* [require-repository-directory](rules/required-node/require-repository-directory.md)
4040
* [require-repository](rules/required-node/require-repository.md)
4141
* [require-scripts](rules/required-node/require-scripts.md)
42+
* [require-type](rules/required-node/require-type.md)
4243
* [require-types](rules/required-node/require-types.md)
4344
* [require-typings](rules/required-node/require-typings.md)
4445
* [require-version](rules/required-node/require-version.md)
@@ -70,6 +71,7 @@ Rules allow npm-package-json-lint to be fully customizable. npm-package-json-lin
7071
* [private-type](rules/type/private-type.md)
7172
* [repository-type](rules/type/repository-type.md)
7273
* [scripts-type](rules/type/scripts-type.md)
74+
* [type-type](rules/type/type-type.md)
7375
* [version-type](rules/type/version-type.md)
7476

7577

@@ -83,6 +85,7 @@ Rules allow npm-package-json-lint to be fully customizable. npm-package-json-lin
8385
* [valid-values-name-scope](rules/valid-values/valid-values-name-scope.md)
8486
* [valid-values-private](rules/valid-values/valid-values-private.md)
8587
* [valid-values-publishConfig](rules/valid-values/valid-values-publishConfig.md)
88+
* [valid-values-type](rules/valid-values/valid-values-type.md)
8689

8790
## Dependency rules
8891

Diff for: website/docs/rules/required-node/require-type.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
id: require-type
3+
title: require-type
4+
---
5+
6+
Enabling this rule will result in an error being generated if `type` is missing from the package.json file.
7+
8+
## Example .npmpackagejsonlintrc configuration
9+
10+
```json
11+
{
12+
"rules": {
13+
"require-type": "error"
14+
}
15+
}
16+
```
17+
18+
## Rule Details
19+
20+
### *Incorrect* example(s)
21+
22+
```json
23+
{
24+
25+
}
26+
```
27+
28+
### *Correct* example(s)
29+
30+
```json
31+
{
32+
"type": "module"
33+
}
34+
```
35+
36+
## History
37+
38+
* Introduced in version 7.0.1

Diff for: website/docs/rules/type/type-type.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
id: type-type
3+
title: type-type
4+
---
5+
6+
Enabling this rule will result in an error being generated if the value in `type` is not a string.
7+
8+
## Example .npmpackagejsonlintrc configuration
9+
10+
```json
11+
{
12+
"rules": {
13+
"type-type": "error"
14+
}
15+
}
16+
```
17+
18+
## Rule Details
19+
20+
### *Incorrect* example(s)
21+
22+
```json
23+
{
24+
"type": 1
25+
}
26+
```
27+
28+
```json
29+
{
30+
"type": ["true"]
31+
}
32+
```
33+
34+
```json
35+
{
36+
"type": true
37+
}
38+
```
39+
40+
```json
41+
{
42+
"type": {
43+
"enabled": "true"
44+
}
45+
}
46+
```
47+
48+
### *Correct* example(s)
49+
50+
```json
51+
{
52+
"type": "module"
53+
}
54+
```
55+
56+
## History
57+
58+
* Introduced in version 7.0.1

0 commit comments

Comments
 (0)