eslint-plugin-package-json 0.12.2 → 0.13.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/README.md +1 -1
- package/lib/configs/recommended.d.mts +1 -1
- package/lib/configs/recommended.d.ts +1 -1
- package/lib/index.d.mts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/plugin.d.mts +1 -1
- package/lib/plugin.d.ts +1 -1
- package/lib/rules/order-properties.d.mts +1 -1
- package/lib/rules/order-properties.d.ts +1 -1
- package/lib/rules/order-properties.js +22 -10
- package/lib/rules/order-properties.js.map +1 -1
- package/lib/rules/order-properties.mjs +22 -10
- package/lib/rules/order-properties.mjs.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ They can lint `package.json` files at project root and in any subfolder of the p
|
|
|
154
154
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KristjanESPERANTO"><img src="https://avatars.githubusercontent.com/u/35647502?v=4?s=100" width="100px;" alt="Kristjan ESPERANTO"/><br /><sub><b>Kristjan ESPERANTO</b></sub></a><br /><a href="#ideas-kristjanesperanto" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Akristjanesperanto" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=kristjanesperanto" title="Code">💻</a></td>
|
|
155
155
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nschonni"><img src="https://avatars.githubusercontent.com/u/1297909?v=4?s=100" width="100px;" alt="Nick Schonning"/><br /><sub><b>Nick Schonning</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=nschonni" title="Code">💻</a></td>
|
|
156
156
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sirugh"><img src="https://avatars.githubusercontent.com/u/1278869?v=4?s=100" width="100px;" alt="Stephen"/><br /><sub><b>Stephen</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sirugh" title="Code">💻</a></td>
|
|
157
|
-
<td align="center" valign="top" width="14.28%"><a href="https://hyoban.cc"><img src="https://avatars.githubusercontent.com/u/38493346?v=4?s=100" width="100px;" alt="Stephen Zhou"/><br /><sub><b>Stephen Zhou</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ahyoban" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Code">💻</a> <a href="#ideas-hyoban" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
157
|
+
<td align="center" valign="top" width="14.28%"><a href="https://hyoban.cc"><img src="https://avatars.githubusercontent.com/u/38493346?v=4?s=100" width="100px;" alt="Stephen Zhou"/><br /><sub><b>Stephen Zhou</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ahyoban" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Code">💻</a> <a href="#ideas-hyoban" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Documentation">📖</a></td>
|
|
158
158
|
<td align="center" valign="top" width="14.28%"><a href="https://ota-meshi.github.io/"><img src="https://avatars.githubusercontent.com/u/16508807?v=4?s=100" width="100px;" alt="Yosuke Ota"/><br /><sub><b>Yosuke Ota</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Aota-meshi" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=ota-meshi" title="Code">💻</a></td>
|
|
159
159
|
</tr>
|
|
160
160
|
<tr>
|
|
@@ -17,7 +17,7 @@ declare const recommended: {
|
|
|
17
17
|
rules: {
|
|
18
18
|
"order-properties": {
|
|
19
19
|
create(context: PackageJsonRuleContext<[({
|
|
20
|
-
order: "legacy" | "sort-package-json";
|
|
20
|
+
order: string[] | "legacy" | "sort-package-json";
|
|
21
21
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
22
22
|
meta: eslint.Rule.RuleMetaData;
|
|
23
23
|
};
|
|
@@ -17,7 +17,7 @@ declare const recommended: {
|
|
|
17
17
|
rules: {
|
|
18
18
|
"order-properties": {
|
|
19
19
|
create(context: PackageJsonRuleContext<[({
|
|
20
|
-
order: "legacy" | "sort-package-json";
|
|
20
|
+
order: string[] | "legacy" | "sort-package-json";
|
|
21
21
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
22
22
|
meta: eslint.Rule.RuleMetaData;
|
|
23
23
|
};
|
package/lib/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ import 'estree';
|
|
|
6
6
|
declare const rules: {
|
|
7
7
|
"order-properties": {
|
|
8
8
|
create(context: PackageJsonRuleContext<[({
|
|
9
|
-
order: "legacy" | "sort-package-json";
|
|
9
|
+
order: "legacy" | "sort-package-json" | string[];
|
|
10
10
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
11
11
|
meta: eslint.Rule.RuleMetaData;
|
|
12
12
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import 'estree';
|
|
|
6
6
|
declare const rules: {
|
|
7
7
|
"order-properties": {
|
|
8
8
|
create(context: PackageJsonRuleContext<[({
|
|
9
|
-
order: "legacy" | "sort-package-json";
|
|
9
|
+
order: "legacy" | "sort-package-json" | string[];
|
|
10
10
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
11
11
|
meta: eslint.Rule.RuleMetaData;
|
|
12
12
|
};
|
package/lib/plugin.d.mts
CHANGED
|
@@ -11,7 +11,7 @@ declare const plugin: {
|
|
|
11
11
|
rules: {
|
|
12
12
|
"order-properties": {
|
|
13
13
|
create(context: PackageJsonRuleContext<[({
|
|
14
|
-
order: "legacy" | "sort-package-json";
|
|
14
|
+
order: "legacy" | "sort-package-json" | string[];
|
|
15
15
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
16
16
|
meta: eslint.Rule.RuleMetaData;
|
|
17
17
|
};
|
package/lib/plugin.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare const plugin: {
|
|
|
11
11
|
rules: {
|
|
12
12
|
"order-properties": {
|
|
13
13
|
create(context: PackageJsonRuleContext<[({
|
|
14
|
-
order: "legacy" | "sort-package-json";
|
|
14
|
+
order: "legacy" | "sort-package-json" | string[];
|
|
15
15
|
} | undefined)?]>): jsonc_eslint_parser.RuleListener;
|
|
16
16
|
meta: eslint.Rule.RuleMetaData;
|
|
17
17
|
};
|
|
@@ -3,7 +3,7 @@ import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
|
3
3
|
import { PackageJsonRuleContext } from '../createRule.mjs';
|
|
4
4
|
import 'estree';
|
|
5
5
|
|
|
6
|
-
type Order = "legacy" | "sort-package-json";
|
|
6
|
+
type Order = "legacy" | "sort-package-json" | string[];
|
|
7
7
|
type Options = [{
|
|
8
8
|
order: Order;
|
|
9
9
|
}?];
|
|
@@ -3,7 +3,7 @@ import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
|
3
3
|
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
4
|
import 'estree';
|
|
5
5
|
|
|
6
|
-
type Order = "legacy" | "sort-package-json";
|
|
6
|
+
type Order = "legacy" | "sort-package-json" | string[];
|
|
7
7
|
type Options = [{
|
|
8
8
|
order: Order;
|
|
9
9
|
}?];
|
|
@@ -31,7 +31,10 @@ __export(order_properties_exports, {
|
|
|
31
31
|
rule: () => rule
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(order_properties_exports);
|
|
34
|
-
var
|
|
34
|
+
var import_detect_indent = __toESM(require("detect-indent"));
|
|
35
|
+
var import_detect_newline = __toESM(require("detect-newline"));
|
|
36
|
+
var import_sort_object_keys = __toESM(require("sort-object-keys"));
|
|
37
|
+
var import_sort_package_json = require("sort-package-json");
|
|
35
38
|
var import_createRule = require("../createRule.js");
|
|
36
39
|
const standardOrderLegacy = [
|
|
37
40
|
"name",
|
|
@@ -72,23 +75,32 @@ const rule = (0, import_createRule.createRule)({
|
|
|
72
75
|
order: "sort-package-json",
|
|
73
76
|
...context.options[0]
|
|
74
77
|
};
|
|
75
|
-
const requiredOrder = options.order === "legacy" ? standardOrderLegacy : options.order;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
requiredOrder
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
);
|
|
78
|
+
const requiredOrder = options.order === "legacy" ? standardOrderLegacy : options.order === "sort-package-json" ? import_sort_package_json.sortOrder : options.order;
|
|
79
|
+
const json = JSON.parse(text);
|
|
80
|
+
const orderedSource = (0, import_sort_object_keys.default)(json, [
|
|
81
|
+
...requiredOrder,
|
|
82
|
+
...Object.keys(json)
|
|
83
|
+
]);
|
|
82
84
|
const orderedKeys = Object.keys(orderedSource);
|
|
83
85
|
const { properties } = ast.body[0].expression;
|
|
84
86
|
for (let i = 0; i < properties.length; i += 1) {
|
|
85
87
|
if (properties[i].key.value !== orderedKeys[i]) {
|
|
86
88
|
context.report({
|
|
87
89
|
fix(fixer) {
|
|
90
|
+
const { indent, type } = (0, import_detect_indent.default)(text);
|
|
91
|
+
const endCharacters = text.endsWith("\n") ? "\n" : "";
|
|
92
|
+
const newline = import_detect_newline.default.graceful(text);
|
|
93
|
+
let result = JSON.stringify(
|
|
94
|
+
orderedSource,
|
|
95
|
+
null,
|
|
96
|
+
type === "tab" ? " " : indent
|
|
97
|
+
) + endCharacters;
|
|
98
|
+
if (newline === "\r\n") {
|
|
99
|
+
result = result.replace(/\n/g, newline);
|
|
100
|
+
}
|
|
88
101
|
return fixer.replaceText(
|
|
89
102
|
context.sourceCode.ast,
|
|
90
|
-
|
|
91
|
-
`
|
|
103
|
+
result
|
|
92
104
|
);
|
|
93
105
|
},
|
|
94
106
|
message: "Package top-level properties are not ordered in the npm standard way. Run the ESLint auto-fixer to correct.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/rules/order-properties.ts"],"sourcesContent":["import type { AST as JsonAST } from \"jsonc-eslint-parser\";\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/rules/order-properties.ts"],"sourcesContent":["import type { AST as JsonAST } from \"jsonc-eslint-parser\";\n\nimport detectIndent from \"detect-indent\";\nimport detectNewline from \"detect-newline\";\nimport sortObjectKeys from \"sort-object-keys\";\nimport { sortOrder } from \"sort-package-json\";\n\nimport { createRule } from \"../createRule.js\";\n\nconst standardOrderLegacy = [\n\t\"name\",\n\t\"version\",\n\t\"private\",\n\t\"publishConfig\",\n\t\"description\",\n\t\"main\",\n\t\"exports\",\n\t\"browser\",\n\t\"files\",\n\t\"bin\",\n\t\"directories\",\n\t\"man\",\n\t\"scripts\",\n\t\"repository\",\n\t\"keywords\",\n\t\"author\",\n\t\"license\",\n\t\"bugs\",\n\t\"homepage\",\n\t\"config\",\n\t\"dependencies\",\n\t\"devDependencies\",\n\t\"peerDependencies\",\n\t\"optionalDependencies\",\n\t\"bundledDependencies\",\n\t\"engines\",\n\t\"os\",\n\t\"cpu\",\n];\n\ntype Order = \"legacy\" | \"sort-package-json\" | string[];\n\ntype Options = [{ order: Order }?];\n\nexport const rule = createRule<Options>({\n\tcreate(context) {\n\t\treturn {\n\t\t\t\"Program:exit\"() {\n\t\t\t\tconst { ast, text } = context.sourceCode;\n\n\t\t\t\tconst options = {\n\t\t\t\t\torder: \"sort-package-json\",\n\t\t\t\t\t...context.options[0],\n\t\t\t\t} satisfies Options[0];\n\n\t\t\t\tconst requiredOrder =\n\t\t\t\t\toptions.order === \"legacy\"\n\t\t\t\t\t\t? standardOrderLegacy\n\t\t\t\t\t\t: options.order === \"sort-package-json\"\n\t\t\t\t\t\t\t? sortOrder\n\t\t\t\t\t\t\t: options.order;\n\n\t\t\t\tconst json = JSON.parse(text) as Record<string, unknown>;\n\t\t\t\tconst orderedSource = sortObjectKeys(json, [\n\t\t\t\t\t...requiredOrder,\n\t\t\t\t\t...Object.keys(json),\n\t\t\t\t]);\n\t\t\t\tconst orderedKeys = Object.keys(orderedSource);\n\n\t\t\t\tconst { properties } = ast.body[0].expression;\n\n\t\t\t\tfor (let i = 0; i < properties.length; i += 1) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t(properties[i].key as JsonAST.JSONStringLiteral)\n\t\t\t\t\t\t\t.value !== orderedKeys[i]\n\t\t\t\t\t) {\n\t\t\t\t\t\tcontext.report({\n\t\t\t\t\t\t\tfix(fixer) {\n\t\t\t\t\t\t\t\tconst { indent, type } = detectIndent(text);\n\t\t\t\t\t\t\t\tconst endCharacters = text.endsWith(\"\\n\")\n\t\t\t\t\t\t\t\t\t? \"\\n\"\n\t\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\t\tconst newline = detectNewline.graceful(text);\n\t\t\t\t\t\t\t\tlet result =\n\t\t\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t\t\torderedSource,\n\t\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t\t\ttype === \"tab\" ? \"\\t\" : indent,\n\t\t\t\t\t\t\t\t\t) + endCharacters;\n\t\t\t\t\t\t\t\tif (newline === \"\\r\\n\") {\n\t\t\t\t\t\t\t\t\tresult = result.replace(/\\n/g, newline);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn fixer.replaceText(\n\t\t\t\t\t\t\t\t\tcontext.sourceCode.ast,\n\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"Package top-level properties are not ordered in the npm standard way. Run the ESLint auto-fixer to correct.\",\n\t\t\t\t\t\t\tnode: context.sourceCode.ast,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t},\n\n\tmeta: {\n\t\tdocs: {\n\t\t\tcategory: \"Best Practices\",\n\t\t\tdescription:\n\t\t\t\t\"Package properties must be declared in standard order\",\n\t\t\trecommended: true,\n\t\t},\n\t\tfixable: \"code\",\n\t\tschema: [\n\t\t\t{\n\t\t\t\tproperties: {\n\t\t\t\t\torder: {\n\t\t\t\t\t\tanyOf: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenum: [\"legacy\", \"sort-package-json\"],\n\t\t\t\t\t\t\t\ttype: [\"string\"],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\ttype: [\"string\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttype: [\"array\"],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttype: \"object\",\n\t\t\t},\n\t\t],\n\t},\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,2BAAyB;AACzB,4BAA0B;AAC1B,8BAA2B;AAC3B,+BAA0B;AAE1B,wBAA2B;AAE3B,MAAM,sBAAsB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAMO,MAAM,WAAO,8BAAoB;AAAA,EACvC,OAAO,SAAS;AACf,WAAO;AAAA,MACN,iBAAiB;AAChB,cAAM,EAAE,KAAK,KAAK,IAAI,QAAQ;AAE9B,cAAM,UAAU;AAAA,UACf,OAAO;AAAA,UACP,GAAG,QAAQ,QAAQ,CAAC;AAAA,QACrB;AAEA,cAAM,gBACL,QAAQ,UAAU,WACf,sBACA,QAAQ,UAAU,sBACjB,qCACA,QAAQ;AAEb,cAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,cAAM,oBAAgB,wBAAAA,SAAe,MAAM;AAAA,UAC1C,GAAG;AAAA,UACH,GAAG,OAAO,KAAK,IAAI;AAAA,QACpB,CAAC;AACD,cAAM,cAAc,OAAO,KAAK,aAAa;AAE7C,cAAM,EAAE,WAAW,IAAI,IAAI,KAAK,CAAC,EAAE;AAEnC,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC9C,cACE,WAAW,CAAC,EAAE,IACb,UAAU,YAAY,CAAC,GACxB;AACD,oBAAQ,OAAO;AAAA,cACd,IAAI,OAAO;AACV,sBAAM,EAAE,QAAQ,KAAK,QAAI,qBAAAC,SAAa,IAAI;AAC1C,sBAAM,gBAAgB,KAAK,SAAS,IAAI,IACrC,OACA;AACH,sBAAM,UAAU,sBAAAC,QAAc,SAAS,IAAI;AAC3C,oBAAI,SACH,KAAK;AAAA,kBACJ;AAAA,kBACA;AAAA,kBACA,SAAS,QAAQ,MAAO;AAAA,gBACzB,IAAI;AACL,oBAAI,YAAY,QAAQ;AACvB,2BAAS,OAAO,QAAQ,OAAO,OAAO;AAAA,gBACvC;AAEA,uBAAO,MAAM;AAAA,kBACZ,QAAQ,WAAW;AAAA,kBACnB;AAAA,gBACD;AAAA,cACD;AAAA,cACA,SACC;AAAA,cACD,MAAM,QAAQ,WAAW;AAAA,YAC1B,CAAC;AAAA,UACF;AAEA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM;AAAA,IACL,MAAM;AAAA,MACL,UAAU;AAAA,MACV,aACC;AAAA,MACD,aAAa;AAAA,IACd;AAAA,IACA,SAAS;AAAA,IACT,QAAQ;AAAA,MACP;AAAA,QACC,YAAY;AAAA,UACX,OAAO;AAAA,YACN,OAAO;AAAA,cACN;AAAA,gBACC,MAAM,CAAC,UAAU,mBAAmB;AAAA,gBACpC,MAAM,CAAC,QAAQ;AAAA,cAChB;AAAA,cACA;AAAA,gBACC,OAAO;AAAA,kBACN,MAAM,CAAC,QAAQ;AAAA,gBAChB;AAAA,gBACA,MAAM,CAAC,OAAO;AAAA,cACf;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,QACA,MAAM;AAAA,MACP;AAAA,IACD;AAAA,EACD;AACD,CAAC;","names":["sortObjectKeys","detectIndent","detectNewline"]}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import detectIndent from "detect-indent";
|
|
2
|
+
import detectNewline from "detect-newline";
|
|
3
|
+
import sortObjectKeys from "sort-object-keys";
|
|
4
|
+
import { sortOrder } from "sort-package-json";
|
|
2
5
|
import { createRule } from "../createRule.js";
|
|
3
6
|
const standardOrderLegacy = [
|
|
4
7
|
"name",
|
|
@@ -39,23 +42,32 @@ const rule = createRule({
|
|
|
39
42
|
order: "sort-package-json",
|
|
40
43
|
...context.options[0]
|
|
41
44
|
};
|
|
42
|
-
const requiredOrder = options.order === "legacy" ? standardOrderLegacy : options.order;
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
requiredOrder
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
);
|
|
45
|
+
const requiredOrder = options.order === "legacy" ? standardOrderLegacy : options.order === "sort-package-json" ? sortOrder : options.order;
|
|
46
|
+
const json = JSON.parse(text);
|
|
47
|
+
const orderedSource = sortObjectKeys(json, [
|
|
48
|
+
...requiredOrder,
|
|
49
|
+
...Object.keys(json)
|
|
50
|
+
]);
|
|
49
51
|
const orderedKeys = Object.keys(orderedSource);
|
|
50
52
|
const { properties } = ast.body[0].expression;
|
|
51
53
|
for (let i = 0; i < properties.length; i += 1) {
|
|
52
54
|
if (properties[i].key.value !== orderedKeys[i]) {
|
|
53
55
|
context.report({
|
|
54
56
|
fix(fixer) {
|
|
57
|
+
const { indent, type } = detectIndent(text);
|
|
58
|
+
const endCharacters = text.endsWith("\n") ? "\n" : "";
|
|
59
|
+
const newline = detectNewline.graceful(text);
|
|
60
|
+
let result = JSON.stringify(
|
|
61
|
+
orderedSource,
|
|
62
|
+
null,
|
|
63
|
+
type === "tab" ? " " : indent
|
|
64
|
+
) + endCharacters;
|
|
65
|
+
if (newline === "\r\n") {
|
|
66
|
+
result = result.replace(/\n/g, newline);
|
|
67
|
+
}
|
|
55
68
|
return fixer.replaceText(
|
|
56
69
|
context.sourceCode.ast,
|
|
57
|
-
|
|
58
|
-
`
|
|
70
|
+
result
|
|
59
71
|
);
|
|
60
72
|
},
|
|
61
73
|
message: "Package top-level properties are not ordered in the npm standard way. Run the ESLint auto-fixer to correct.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/rules/order-properties.ts"],"sourcesContent":["import type { AST as JsonAST } from \"jsonc-eslint-parser\";\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/rules/order-properties.ts"],"sourcesContent":["import type { AST as JsonAST } from \"jsonc-eslint-parser\";\n\nimport detectIndent from \"detect-indent\";\nimport detectNewline from \"detect-newline\";\nimport sortObjectKeys from \"sort-object-keys\";\nimport { sortOrder } from \"sort-package-json\";\n\nimport { createRule } from \"../createRule.js\";\n\nconst standardOrderLegacy = [\n\t\"name\",\n\t\"version\",\n\t\"private\",\n\t\"publishConfig\",\n\t\"description\",\n\t\"main\",\n\t\"exports\",\n\t\"browser\",\n\t\"files\",\n\t\"bin\",\n\t\"directories\",\n\t\"man\",\n\t\"scripts\",\n\t\"repository\",\n\t\"keywords\",\n\t\"author\",\n\t\"license\",\n\t\"bugs\",\n\t\"homepage\",\n\t\"config\",\n\t\"dependencies\",\n\t\"devDependencies\",\n\t\"peerDependencies\",\n\t\"optionalDependencies\",\n\t\"bundledDependencies\",\n\t\"engines\",\n\t\"os\",\n\t\"cpu\",\n];\n\ntype Order = \"legacy\" | \"sort-package-json\" | string[];\n\ntype Options = [{ order: Order }?];\n\nexport const rule = createRule<Options>({\n\tcreate(context) {\n\t\treturn {\n\t\t\t\"Program:exit\"() {\n\t\t\t\tconst { ast, text } = context.sourceCode;\n\n\t\t\t\tconst options = {\n\t\t\t\t\torder: \"sort-package-json\",\n\t\t\t\t\t...context.options[0],\n\t\t\t\t} satisfies Options[0];\n\n\t\t\t\tconst requiredOrder =\n\t\t\t\t\toptions.order === \"legacy\"\n\t\t\t\t\t\t? standardOrderLegacy\n\t\t\t\t\t\t: options.order === \"sort-package-json\"\n\t\t\t\t\t\t\t? sortOrder\n\t\t\t\t\t\t\t: options.order;\n\n\t\t\t\tconst json = JSON.parse(text) as Record<string, unknown>;\n\t\t\t\tconst orderedSource = sortObjectKeys(json, [\n\t\t\t\t\t...requiredOrder,\n\t\t\t\t\t...Object.keys(json),\n\t\t\t\t]);\n\t\t\t\tconst orderedKeys = Object.keys(orderedSource);\n\n\t\t\t\tconst { properties } = ast.body[0].expression;\n\n\t\t\t\tfor (let i = 0; i < properties.length; i += 1) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t(properties[i].key as JsonAST.JSONStringLiteral)\n\t\t\t\t\t\t\t.value !== orderedKeys[i]\n\t\t\t\t\t) {\n\t\t\t\t\t\tcontext.report({\n\t\t\t\t\t\t\tfix(fixer) {\n\t\t\t\t\t\t\t\tconst { indent, type } = detectIndent(text);\n\t\t\t\t\t\t\t\tconst endCharacters = text.endsWith(\"\\n\")\n\t\t\t\t\t\t\t\t\t? \"\\n\"\n\t\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\t\tconst newline = detectNewline.graceful(text);\n\t\t\t\t\t\t\t\tlet result =\n\t\t\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t\t\torderedSource,\n\t\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t\t\ttype === \"tab\" ? \"\\t\" : indent,\n\t\t\t\t\t\t\t\t\t) + endCharacters;\n\t\t\t\t\t\t\t\tif (newline === \"\\r\\n\") {\n\t\t\t\t\t\t\t\t\tresult = result.replace(/\\n/g, newline);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn fixer.replaceText(\n\t\t\t\t\t\t\t\t\tcontext.sourceCode.ast,\n\t\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"Package top-level properties are not ordered in the npm standard way. Run the ESLint auto-fixer to correct.\",\n\t\t\t\t\t\t\tnode: context.sourceCode.ast,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t},\n\n\tmeta: {\n\t\tdocs: {\n\t\t\tcategory: \"Best Practices\",\n\t\t\tdescription:\n\t\t\t\t\"Package properties must be declared in standard order\",\n\t\t\trecommended: true,\n\t\t},\n\t\tfixable: \"code\",\n\t\tschema: [\n\t\t\t{\n\t\t\t\tproperties: {\n\t\t\t\t\torder: {\n\t\t\t\t\t\tanyOf: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenum: [\"legacy\", \"sort-package-json\"],\n\t\t\t\t\t\t\t\ttype: [\"string\"],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\ttype: [\"string\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttype: [\"array\"],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttype: \"object\",\n\t\t\t},\n\t\t],\n\t},\n});\n"],"mappings":"AAEA,OAAO,kBAAkB;AACzB,OAAO,mBAAmB;AAC1B,OAAO,oBAAoB;AAC3B,SAAS,iBAAiB;AAE1B,SAAS,kBAAkB;AAE3B,MAAM,sBAAsB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAMO,MAAM,OAAO,WAAoB;AAAA,EACvC,OAAO,SAAS;AACf,WAAO;AAAA,MACN,iBAAiB;AAChB,cAAM,EAAE,KAAK,KAAK,IAAI,QAAQ;AAE9B,cAAM,UAAU;AAAA,UACf,OAAO;AAAA,UACP,GAAG,QAAQ,QAAQ,CAAC;AAAA,QACrB;AAEA,cAAM,gBACL,QAAQ,UAAU,WACf,sBACA,QAAQ,UAAU,sBACjB,YACA,QAAQ;AAEb,cAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,cAAM,gBAAgB,eAAe,MAAM;AAAA,UAC1C,GAAG;AAAA,UACH,GAAG,OAAO,KAAK,IAAI;AAAA,QACpB,CAAC;AACD,cAAM,cAAc,OAAO,KAAK,aAAa;AAE7C,cAAM,EAAE,WAAW,IAAI,IAAI,KAAK,CAAC,EAAE;AAEnC,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC9C,cACE,WAAW,CAAC,EAAE,IACb,UAAU,YAAY,CAAC,GACxB;AACD,oBAAQ,OAAO;AAAA,cACd,IAAI,OAAO;AACV,sBAAM,EAAE,QAAQ,KAAK,IAAI,aAAa,IAAI;AAC1C,sBAAM,gBAAgB,KAAK,SAAS,IAAI,IACrC,OACA;AACH,sBAAM,UAAU,cAAc,SAAS,IAAI;AAC3C,oBAAI,SACH,KAAK;AAAA,kBACJ;AAAA,kBACA;AAAA,kBACA,SAAS,QAAQ,MAAO;AAAA,gBACzB,IAAI;AACL,oBAAI,YAAY,QAAQ;AACvB,2BAAS,OAAO,QAAQ,OAAO,OAAO;AAAA,gBACvC;AAEA,uBAAO,MAAM;AAAA,kBACZ,QAAQ,WAAW;AAAA,kBACnB;AAAA,gBACD;AAAA,cACD;AAAA,cACA,SACC;AAAA,cACD,MAAM,QAAQ,WAAW;AAAA,YAC1B,CAAC;AAAA,UACF;AAEA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM;AAAA,IACL,MAAM;AAAA,MACL,UAAU;AAAA,MACV,aACC;AAAA,MACD,aAAa;AAAA,IACd;AAAA,IACA,SAAS;AAAA,IACT,QAAQ;AAAA,MACP;AAAA,QACC,YAAY;AAAA,UACX,OAAO;AAAA,YACN,OAAO;AAAA,cACN;AAAA,gBACC,MAAM,CAAC,UAAU,mBAAmB;AAAA,gBACpC,MAAM,CAAC,QAAQ;AAAA,cAChB;AAAA,cACA;AAAA,gBACC,OAAO;AAAA,kBACN,MAAM,CAAC,QAAQ;AAAA,gBAChB;AAAA,gBACA,MAAM,CAAC,OAAO;AAAA,cACf;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,QACA,MAAM;AAAA,MACP;AAAA,IACD;AAAA,EACD;AACD,CAAC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-package-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Rules for consistent, readable, and valid package.json files. 🗂️",
|
|
5
5
|
"homepage": "https://github.com/JoshuaKGoldberg/eslint-plugin-package-json#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -52,14 +52,17 @@
|
|
|
52
52
|
"should-semantic-release": "should-semantic-release --verbose",
|
|
53
53
|
"test": "vitest",
|
|
54
54
|
"tsc": "tsc",
|
|
55
|
-
"update:eslint-docs": "eslint-doc-generator"
|
|
55
|
+
"update:eslint-docs": "eslint-doc-generator --rule-doc-title-format name"
|
|
56
56
|
},
|
|
57
57
|
"lint-staged": {
|
|
58
58
|
"*": "prettier --ignore-unknown --write"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"detect-indent": "6.1.0",
|
|
62
|
+
"detect-newline": "3.1.0",
|
|
61
63
|
"package-json-validator": "^0.6.3",
|
|
62
64
|
"semver": "^7.5.4",
|
|
65
|
+
"sort-object-keys": "^1.1.3",
|
|
63
66
|
"sort-package-json": "^1.57.0",
|
|
64
67
|
"validate-npm-package-name": "^5.0.0"
|
|
65
68
|
},
|
|
@@ -70,6 +73,7 @@
|
|
|
70
73
|
"@types/node": "^20.11.5",
|
|
71
74
|
"@types/package-json-validator": "^0.6.1",
|
|
72
75
|
"@types/semver": "^7.5.6",
|
|
76
|
+
"@types/sort-object-keys": "^1.1.3",
|
|
73
77
|
"@types/validate-npm-package-name": "^4.0.2",
|
|
74
78
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
75
79
|
"@typescript-eslint/parser": "^7.0.0",
|