eslint-plugin-package-json 0.52.0 → 0.53.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 +14 -2
- package/lib/createRule.d.ts +28 -28
- package/lib/createRule.js +18 -12
- package/lib/index.d.ts +33 -35
- package/lib/index.js +6 -6
- package/lib/plugin.d.ts +33 -34
- package/lib/plugin.js +62 -80
- package/lib/rules/no-empty-fields.d.ts +6 -11
- package/lib/rules/no-empty-fields.js +80 -112
- package/lib/rules/no-redundant-files.d.ts +5 -10
- package/lib/rules/no-redundant-files.js +93 -136
- package/lib/rules/order-properties.d.ts +6 -11
- package/lib/rules/order-properties.js +92 -116
- package/lib/rules/repository-shorthand.d.ts +6 -11
- package/lib/rules/repository-shorthand.js +79 -112
- package/lib/rules/require-properties.d.ts +7 -12
- package/lib/rules/require-properties.js +31 -27
- package/lib/rules/restrict-dependency-ranges.d.ts +9 -14
- package/lib/rules/restrict-dependency-ranges.js +137 -189
- package/lib/rules/sort-collections.d.ts +5 -10
- package/lib/rules/sort-collections.js +71 -124
- package/lib/rules/unique-dependencies.d.ts +5 -10
- package/lib/rules/unique-dependencies.js +58 -82
- package/lib/rules/valid-bin.d.ts +6 -11
- package/lib/rules/valid-bin.js +59 -78
- package/lib/rules/valid-local-dependency.d.ts +5 -10
- package/lib/rules/valid-local-dependency.js +49 -57
- package/lib/rules/valid-name.d.ts +5 -10
- package/lib/rules/valid-name.js +41 -48
- package/lib/rules/valid-package-definition.d.ts +6 -11
- package/lib/rules/valid-package-definition.js +41 -50
- package/lib/rules/valid-properties.d.ts +7 -7
- package/lib/rules/valid-properties.js +33 -55
- package/lib/rules/valid-repository-directory.d.ts +5 -10
- package/lib/rules/valid-repository-directory.js +65 -80
- package/lib/rules/valid-version.d.ts +5 -10
- package/lib/rules/valid-version.js +35 -36
- package/lib/types/estree.d.ts +8 -0
- package/lib/utils/createSimpleRequirePropertyRule.d.ts +19 -18
- package/lib/utils/createSimpleRequirePropertyRule.js +48 -53
- package/lib/utils/createSimpleValidPropertyRule.d.ts +6 -8
- package/lib/utils/createSimpleValidPropertyRule.js +45 -39
- package/lib/utils/findPropertyWithKeyValue.d.ts +6 -5
- package/lib/utils/findPropertyWithKeyValue.js +5 -6
- package/lib/utils/formatErrors.d.ts +3 -2
- package/lib/utils/formatErrors.js +11 -7
- package/lib/utils/isPackageJson.d.ts +3 -2
- package/lib/utils/isPackageJson.js +4 -3
- package/lib/utils/predicates.d.ts +4 -3
- package/lib/utils/predicates.js +6 -6
- package/package.json +8 -8
- package/lib/tests/rules/ruleTester.d.ts +0 -15
- package/lib/tests/rules/ruleTester.js +0 -25
- package/lib/types/estree.d.d.ts +0 -7
- package/lib/types/estree.d.js +0 -0
|
@@ -1,56 +1,47 @@
|
|
|
1
|
-
import { validate } from "package-json-validator";
|
|
2
1
|
import { createRule } from "../createRule.js";
|
|
2
|
+
import { validate } from "package-json-validator";
|
|
3
|
+
|
|
4
|
+
//#region src/rules/valid-package-definition.ts
|
|
3
5
|
const ignoredErrors = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
/^Url not valid/i,
|
|
7
|
+
/^Invalid version range for .+?: file:/i,
|
|
8
|
+
/^author field should have name/i
|
|
7
9
|
];
|
|
8
10
|
const isUsableError = (errorText) => ignoredErrors.every((pattern) => !pattern.test(errorText));
|
|
9
11
|
const rule = createRule({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
items: {
|
|
43
|
-
type: "string"
|
|
44
|
-
},
|
|
45
|
-
type: "array"
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
type: "object"
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
type: "problem"
|
|
52
|
-
}
|
|
12
|
+
create(context) {
|
|
13
|
+
const ignoreProperties = context.options[0]?.ignoreProperties ?? [];
|
|
14
|
+
return { "Program:exit"() {
|
|
15
|
+
const validation = validate(context.sourceCode.text);
|
|
16
|
+
const usableErrors = validation.errors?.filter((error) => {
|
|
17
|
+
return isUsableError(error.message) && !ignoreProperties.includes(error.field);
|
|
18
|
+
}) ?? [];
|
|
19
|
+
for (const error of usableErrors) if (error.message) context.report({
|
|
20
|
+
message: error.message,
|
|
21
|
+
node: context.sourceCode.ast
|
|
22
|
+
});
|
|
23
|
+
} };
|
|
24
|
+
},
|
|
25
|
+
meta: {
|
|
26
|
+
defaultOptions: [{ ignoreProperties: [] }],
|
|
27
|
+
docs: {
|
|
28
|
+
category: "Best Practices",
|
|
29
|
+
description: "Enforce that package.json has all properties required by the npm spec",
|
|
30
|
+
recommended: true
|
|
31
|
+
},
|
|
32
|
+
schema: [{
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
properties: { ignoreProperties: {
|
|
35
|
+
description: "Array of top-level package properties to ignore.",
|
|
36
|
+
items: { type: "string" },
|
|
37
|
+
type: "array"
|
|
38
|
+
} },
|
|
39
|
+
type: "object"
|
|
40
|
+
}],
|
|
41
|
+
type: "problem"
|
|
42
|
+
},
|
|
43
|
+
name: "valid-package-definition"
|
|
53
44
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
};
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { rule };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { PackageJsonRuleModule } from
|
|
2
|
-
import 'estree';
|
|
3
|
-
import 'eslint';
|
|
4
|
-
import 'jsonc-eslint-parser';
|
|
1
|
+
import { PackageJsonRuleModule } from "../createRule.js";
|
|
5
2
|
|
|
3
|
+
//#region src/rules/valid-properties.d.ts
|
|
6
4
|
/** All basic valid- flavor rules */
|
|
7
|
-
declare const rules:
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
declare const rules: {
|
|
6
|
+
[k: string]: PackageJsonRuleModule<unknown[]>;
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { rules };
|
|
@@ -1,57 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
validateCpu,
|
|
6
|
-
validateDependencies,
|
|
7
|
-
validateDescription,
|
|
8
|
-
validateLicense,
|
|
9
|
-
validateScripts,
|
|
10
|
-
validateType
|
|
11
|
-
} from "package-json-validator";
|
|
12
|
-
import {
|
|
13
|
-
createSimpleValidPropertyRule
|
|
14
|
-
} from "../utils/createSimpleValidPropertyRule.js";
|
|
1
|
+
import { createSimpleValidPropertyRule } from "../utils/createSimpleValidPropertyRule.js";
|
|
2
|
+
import { validateAuthor, validateBundleDependencies, validateConfig, validateCpu, validateDependencies, validateDescription, validateLicense, validateScripts, validateType } from "package-json-validator";
|
|
3
|
+
|
|
4
|
+
//#region src/rules/valid-properties.ts
|
|
15
5
|
const properties = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
["peerDependencies", validateDependencies],
|
|
32
|
-
["scripts", validateScripts],
|
|
33
|
-
["type", validateType]
|
|
34
|
-
// TODO: More to come!
|
|
6
|
+
["author", validateAuthor],
|
|
7
|
+
["bundleDependencies", {
|
|
8
|
+
aliases: ["bundledDependencies"],
|
|
9
|
+
validator: validateBundleDependencies
|
|
10
|
+
}],
|
|
11
|
+
["config", validateConfig],
|
|
12
|
+
["cpu", validateCpu],
|
|
13
|
+
["dependencies", validateDependencies],
|
|
14
|
+
["description", validateDescription],
|
|
15
|
+
["devDependencies", validateDependencies],
|
|
16
|
+
["license", validateLicense],
|
|
17
|
+
["optionalDependencies", validateDependencies],
|
|
18
|
+
["peerDependencies", validateDependencies],
|
|
19
|
+
["scripts", validateScripts],
|
|
20
|
+
["type", validateType]
|
|
35
21
|
];
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
);
|
|
51
|
-
return acc;
|
|
52
|
-
},
|
|
53
|
-
{}
|
|
54
|
-
);
|
|
55
|
-
export {
|
|
56
|
-
rules
|
|
57
|
-
};
|
|
22
|
+
/** All basic valid- flavor rules */
|
|
23
|
+
const rules = Object.fromEntries(properties.map(([propertyName, validationFunctionOrOptions]) => {
|
|
24
|
+
let validationFunction;
|
|
25
|
+
let aliases = [];
|
|
26
|
+
if (typeof validationFunctionOrOptions === "object") {
|
|
27
|
+
validationFunction = validationFunctionOrOptions.validator;
|
|
28
|
+
aliases = validationFunctionOrOptions.aliases;
|
|
29
|
+
} else validationFunction = validationFunctionOrOptions;
|
|
30
|
+
const { rule, ruleName } = createSimpleValidPropertyRule(propertyName, validationFunction, aliases);
|
|
31
|
+
return [ruleName, rule];
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { rules };
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
3
|
-
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
|
-
import 'estree';
|
|
1
|
+
import { PackageJsonRuleModule } from "../createRule.js";
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export { rule };
|
|
3
|
+
//#region src/rules/valid-repository-directory.d.ts
|
|
4
|
+
declare const rule: PackageJsonRuleModule<unknown[]>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { rule };
|
|
@@ -1,86 +1,71 @@
|
|
|
1
|
-
import { findRootSync } from "@altano/repository-tools";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { sep as posixSep } from "node:path/posix";
|
|
4
1
|
import { createRule } from "../createRule.js";
|
|
5
2
|
import { findPropertyWithKeyValue } from "../utils/findPropertyWithKeyValue.js";
|
|
3
|
+
import * as path$1 from "node:path";
|
|
4
|
+
import { findRootSync } from "@altano/repository-tools";
|
|
5
|
+
import { sep } from "node:path/posix";
|
|
6
|
+
|
|
7
|
+
//#region src/rules/valid-repository-directory.ts
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the child path appears at the end of the parent path.
|
|
10
|
+
* @example '/a/b/c', 'c' => true
|
|
11
|
+
* @example '/a/b/c', 'b/c' => true
|
|
12
|
+
* @example '/a/b/c', 'b' => false
|
|
13
|
+
* @example '/a/b/c', 'd' => false
|
|
14
|
+
*/
|
|
6
15
|
function pathEndsWith(parent, child) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (pathToCheck === child) {
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
16
|
+
const segments = parent.split(path$1.sep);
|
|
17
|
+
if (parent === child) return true;
|
|
18
|
+
let pathToCheck = "";
|
|
19
|
+
return segments.reverse().some((segment) => {
|
|
20
|
+
pathToCheck = path$1.join(segment, pathToCheck);
|
|
21
|
+
if (pathToCheck === child) return true;
|
|
22
|
+
});
|
|
18
23
|
}
|
|
19
24
|
const rule = createRule({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
},
|
|
69
|
-
meta: {
|
|
70
|
-
docs: {
|
|
71
|
-
category: "Best Practices",
|
|
72
|
-
description: "Enforce that if repository directory is specified, it matches the path to the package.json file",
|
|
73
|
-
recommended: true
|
|
74
|
-
},
|
|
75
|
-
hasSuggestions: true,
|
|
76
|
-
messages: {
|
|
77
|
-
mismatched: "Directory does not match package.json directory.",
|
|
78
|
-
replace: "Replace with '{{ expected }}'."
|
|
79
|
-
},
|
|
80
|
-
schema: [],
|
|
81
|
-
type: "suggestion"
|
|
82
|
-
}
|
|
25
|
+
create(context) {
|
|
26
|
+
return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=repository][value.type=JSONObjectExpression]"(node) {
|
|
27
|
+
const directoryProperty = findPropertyWithKeyValue(node.value.properties, "directory");
|
|
28
|
+
if (directoryProperty?.value.type !== "JSONLiteral" || typeof directoryProperty.value.value !== "string") return;
|
|
29
|
+
const directoryValue = directoryProperty.value.value;
|
|
30
|
+
const fileDirectory = path$1.normalize(path$1.dirname(context.filename));
|
|
31
|
+
const repositoryRoot = findRootSync(fileDirectory);
|
|
32
|
+
if (repositoryRoot == null) {
|
|
33
|
+
if (!pathEndsWith(fileDirectory, path$1.normalize(directoryValue))) context.report({
|
|
34
|
+
messageId: "mismatched",
|
|
35
|
+
node: directoryProperty.value
|
|
36
|
+
});
|
|
37
|
+
} else {
|
|
38
|
+
const expected = path$1.relative(repositoryRoot, fileDirectory).replaceAll(path$1.sep, sep);
|
|
39
|
+
if (expected !== directoryValue) context.report({
|
|
40
|
+
messageId: "mismatched",
|
|
41
|
+
node: directoryProperty.value,
|
|
42
|
+
suggest: [{
|
|
43
|
+
data: { expected },
|
|
44
|
+
fix(fixer) {
|
|
45
|
+
return fixer.replaceText(directoryProperty.value, `"${expected}"`);
|
|
46
|
+
},
|
|
47
|
+
messageId: "replace"
|
|
48
|
+
}]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
} };
|
|
52
|
+
},
|
|
53
|
+
meta: {
|
|
54
|
+
docs: {
|
|
55
|
+
category: "Best Practices",
|
|
56
|
+
description: "Enforce that if repository directory is specified, it matches the path to the package.json file",
|
|
57
|
+
recommended: true
|
|
58
|
+
},
|
|
59
|
+
hasSuggestions: true,
|
|
60
|
+
messages: {
|
|
61
|
+
mismatched: "Directory does not match package.json directory.",
|
|
62
|
+
replace: "Replace with '{{ expected }}'."
|
|
63
|
+
},
|
|
64
|
+
schema: [],
|
|
65
|
+
type: "suggestion"
|
|
66
|
+
},
|
|
67
|
+
name: "valid-repository-directory"
|
|
83
68
|
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { rule };
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
3
|
-
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
|
-
import 'estree';
|
|
1
|
+
import { PackageJsonRuleModule } from "../createRule.js";
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export { rule };
|
|
3
|
+
//#region src/rules/valid-version.d.ts
|
|
4
|
+
declare const rule: PackageJsonRuleModule<unknown[]>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { rule };
|
|
@@ -1,39 +1,38 @@
|
|
|
1
|
-
import semver from "semver";
|
|
2
1
|
import { createRule } from "../createRule.js";
|
|
2
|
+
import semver from "semver";
|
|
3
|
+
|
|
4
|
+
//#region src/rules/valid-version.ts
|
|
3
5
|
const rule = createRule({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
schema: [],
|
|
34
|
-
type: "problem"
|
|
35
|
-
}
|
|
6
|
+
create(context) {
|
|
7
|
+
return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=version]"(node) {
|
|
8
|
+
if (node.value.type !== "JSONLiteral" || typeof node.value.value !== "string") {
|
|
9
|
+
context.report({
|
|
10
|
+
messageId: "type",
|
|
11
|
+
node: node.value
|
|
12
|
+
});
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!semver.valid(node.value.value)) context.report({
|
|
16
|
+
messageId: "invalid",
|
|
17
|
+
node: node.value
|
|
18
|
+
});
|
|
19
|
+
} };
|
|
20
|
+
},
|
|
21
|
+
meta: {
|
|
22
|
+
docs: {
|
|
23
|
+
category: "Best Practices",
|
|
24
|
+
description: "Enforce that package versions are valid semver specifiers",
|
|
25
|
+
recommended: true
|
|
26
|
+
},
|
|
27
|
+
messages: {
|
|
28
|
+
invalid: "Version is not a valid semver specifier.",
|
|
29
|
+
type: "\"version\" should be a string."
|
|
30
|
+
},
|
|
31
|
+
schema: [],
|
|
32
|
+
type: "problem"
|
|
33
|
+
},
|
|
34
|
+
name: "valid-version"
|
|
36
35
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { rule };
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
3
|
-
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
|
-
import 'estree';
|
|
1
|
+
import { PackageJsonRuleModule } from "../createRule.js";
|
|
5
2
|
|
|
3
|
+
//#region src/utils/createSimpleRequirePropertyRule.d.ts
|
|
6
4
|
interface CreateRequirePropertyRuleOptions {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The default value of `ignorePrivate` rule option.
|
|
7
|
+
*/
|
|
8
|
+
ignorePrivateDefault?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Whether the rule should be included in the recommended config.
|
|
11
|
+
*/
|
|
12
|
+
isRecommended?: boolean;
|
|
15
13
|
}
|
|
16
14
|
type Options = [{
|
|
17
|
-
|
|
15
|
+
ignorePrivate?: boolean;
|
|
18
16
|
}?];
|
|
19
17
|
/**
|
|
20
18
|
* Given a top-level property name, create a rule that requires that property to be present.
|
|
@@ -22,9 +20,12 @@ type Options = [{
|
|
|
22
20
|
* Note: this will only create a basic require rule, with no options. If you need
|
|
23
21
|
* to create a more complex rule, create it in its own file.
|
|
24
22
|
*/
|
|
25
|
-
declare const createSimpleRequirePropertyRule: (propertyName: string, {
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
declare const createSimpleRequirePropertyRule: (propertyName: string, {
|
|
24
|
+
ignorePrivateDefault,
|
|
25
|
+
isRecommended
|
|
26
|
+
}?: CreateRequirePropertyRuleOptions) => {
|
|
27
|
+
rule: PackageJsonRuleModule<Options>;
|
|
28
|
+
ruleName: string;
|
|
28
29
|
};
|
|
29
|
-
|
|
30
|
-
export {
|
|
30
|
+
//#endregion
|
|
31
|
+
export { CreateRequirePropertyRuleOptions, createSimpleRequirePropertyRule };
|
|
@@ -1,56 +1,51 @@
|
|
|
1
1
|
import { createRule } from "../createRule.js";
|
|
2
2
|
import { isJSONStringLiteral } from "./predicates.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
type: "suggestion"
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
export {
|
|
55
|
-
createSimpleRequirePropertyRule
|
|
3
|
+
|
|
4
|
+
//#region src/utils/createSimpleRequirePropertyRule.ts
|
|
5
|
+
/**
|
|
6
|
+
* Given a top-level property name, create a rule that requires that property to be present.
|
|
7
|
+
* Optionally, include it in the recommended config.
|
|
8
|
+
* Note: this will only create a basic require rule, with no options. If you need
|
|
9
|
+
* to create a more complex rule, create it in its own file.
|
|
10
|
+
*/
|
|
11
|
+
const createSimpleRequirePropertyRule = (propertyName, { ignorePrivateDefault = false, isRecommended } = {}) => {
|
|
12
|
+
const ruleName = `require-${propertyName}`;
|
|
13
|
+
const rule = createRule({
|
|
14
|
+
create(context) {
|
|
15
|
+
const enforceForPrivate = context.settings.packageJson?.enforceForPrivate;
|
|
16
|
+
const ignorePrivate = context.options[0]?.ignorePrivate ?? (typeof enforceForPrivate === "boolean" ? !enforceForPrivate : ignorePrivateDefault);
|
|
17
|
+
return { "Program > JSONExpressionStatement > JSONObjectExpression"(node) {
|
|
18
|
+
if (ignorePrivate && node.properties.some((property) => isJSONStringLiteral(property.key) && property.key.value === "private" && property.value.type === "JSONLiteral" && property.value.value === true)) return;
|
|
19
|
+
if (!node.properties.some((property) => isJSONStringLiteral(property.key) && property.key.value === propertyName)) context.report({
|
|
20
|
+
data: { property: propertyName },
|
|
21
|
+
messageId: "missing",
|
|
22
|
+
node: context.sourceCode.ast
|
|
23
|
+
});
|
|
24
|
+
} };
|
|
25
|
+
},
|
|
26
|
+
meta: {
|
|
27
|
+
docs: {
|
|
28
|
+
description: `Requires the \`${propertyName}\` property to be present.`,
|
|
29
|
+
recommended: isRecommended
|
|
30
|
+
},
|
|
31
|
+
messages: { missing: "Property '{{property}}' is required." },
|
|
32
|
+
schema: [{
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
properties: { ignorePrivate: {
|
|
35
|
+
default: ignorePrivateDefault,
|
|
36
|
+
type: "boolean"
|
|
37
|
+
} },
|
|
38
|
+
type: "object"
|
|
39
|
+
}],
|
|
40
|
+
type: "suggestion"
|
|
41
|
+
},
|
|
42
|
+
name: ruleName
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
rule,
|
|
46
|
+
ruleName
|
|
47
|
+
};
|
|
56
48
|
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { createSimpleRequirePropertyRule };
|