eslint-plugin-perfectionist 0.1.0 → 0.3.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/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";const x=require("@typescript-eslint/types"),R=require("@typescript-eslint/utils"),j=require("natural-compare-lite"),C="eslint-plugin-perfectionist",D="azat-io/eslint-plugin-perfectionist";let E=R.ESLintUtils.RuleCreator(t=>`https://github.com/${D}/blob/main/docs/rules/${t}.md`),S=t=>{let[s,a]=t;return a-s};var d=(t=>(t.natural="natural",t["line-length"]="line-length",t))(d||{}),c=(t=>(t.asc="asc",t.desc="desc",t))(c||{});let I=(t,s,a)=>(a.order==="asc"?1:-1)*(a.type===d.natural?j(t.name,s.name):t.size-s.size)>0,O=(t,s,a,l)=>{let e=[...a].sort((r,o)=>Number(I(r,o,l))||-1),n=r=>[r.range.at(0),r.range.at(1)];return a.map(({node:r},o)=>t.replaceTextRange(n(r),s.slice(...n(e[o].node))))},N=(t={},s)=>Object.assign(s,t);const T="sort-interfaces",z=E({name:T,meta:{type:"suggestion",docs:{description:"Enforce sorted interface properties",recommended:!1},messages:{unexpectedInterfacePropertiesOrder:'Expected "{{second}}" to come before "{{first}}"'},fixable:"code",schema:[{type:"object",properties:{type:{enum:[d.natural,d["line-length"]]},order:{enum:[c.asc,c.desc]}},additionalProperties:!1}]},defaultOptions:[{type:d.natural,order:c.asc}],create:t=>({TSInterfaceBody:s=>{let a=N(t.options.at(0),{type:d.natural,order:c.asc}),l=s.body.map(e=>{let n="",r=0,o=i=>{r+=i},p=i=>{o(S(i.key.range))},g=i=>{let{length:f}="[]";o(i.parameters.reduce((h,{range:A})=>h+S(A),f))},m=i=>{if(i.optional){let{length:f}="?";o(f)}},y=i=>{var h;let f=(h=i.typeAnnotation)==null?void 0:h.range;f&&o(S(f))},u=i=>{if(i.type===x.AST_NODE_TYPES.Identifier)({name:n}=i);else if(i.type===x.AST_NODE_TYPES.TSIndexSignature){let f=i.parameters.at(0);f&&u(f)}};return e.type===x.AST_NODE_TYPES.TSPropertySignature?(u(e.key),p(e),m(e),y(e)):e.type===x.AST_NODE_TYPES.TSIndexSignature&&(u(e),g(e),y(e)),{node:e,name:n,size:r}});for(let e=1;e<l.length;e++){let n=e-1,r=e,o=l.at(n),p=l.at(r);if(I(o,p,a)){let g=s.body[r];t.report({messageId:"unexpectedInterfacePropertiesOrder",data:{first:o.name,second:p.name},node:g,fix:m=>{let y=t.getSourceCode(),{text:u}=y;return O(m,u,l,a)}})}}}})}),b="sort-jsx-props",J=E({name:b,meta:{type:"suggestion",docs:{description:"Enforce sorted interface properties",recommended:!1},messages:{unexpectedJSXPropsOrder:'Expected "{{second}}" to come before "{{first}}"'},fixable:"code",schema:[{type:"object",properties:{type:{enum:[d.natural,d["line-length"]]},order:{enum:[c.asc,c.desc]}},additionalProperties:!1}]},defaultOptions:[{type:d.natural,order:c.asc}],create:t=>({JSXElement:s=>{let a=N(t.options.at(0),{type:d.natural,order:c.asc});s.openingElement.attributes.reduce((e,n)=>(n.type==="JSXAttribute"?e.at(-1).push(n):e.push([]),e),[[]]).forEach(e=>{let n=e.map(r=>({name:r.name.type===x.AST_NODE_TYPES.JSXNamespacedName?`${r.name.namespace.name}:${r.name.name.name}`:r.name.name,size:S(r.range),node:r}));for(let r=1;r<n.length;r++){let o=r-1,p=r,g=n.at(o),m=n.at(p);I(g,m,a)&&t.report({messageId:"unexpectedJSXPropsOrder",data:{first:g.name,second:m.name},node:m.node,fix:y=>{let u=t.getSourceCode(),{text:i}=u;return O(y,i,n,a)}})}})}})}),P="sort-named-imports",$=E({name:P,meta:{type:"suggestion",docs:{description:"Enforce sorted interface properties",recommended:!1},messages:{unexpectedNamedImportsOrder:'Expected "{{second}}" to come before "{{first}}"'},fixable:"code",schema:[{type:"object",properties:{type:{enum:[d.natural,d["line-length"]]},order:{enum:[c.asc,c.desc]}},additionalProperties:!1}]},defaultOptions:[{type:d.natural,order:c.asc}],create:t=>({ImportDeclaration:s=>{let a=N(t.options.at(0),{type:d.natural,order:c.asc});if(s.specifiers.length>1){let l=s.specifiers.map(e=>{let{range:n,local:{name:r}}=e;return{size:S(n),node:e,name:r}});for(let e=1;e<l.length;e++){let n=e-1,r=e,o=l.at(n),p=l.at(r);if(I(o,p,a)){let g=s.specifiers[r];t.report({messageId:"unexpectedNamedImportsOrder",data:{first:o.name,second:p.name},node:g,fix:m=>{let y=t.getSourceCode(),{text:u}=y;return O(m,u,l,a)}})}}}}})});let _=t=>{let s={[T]:["error"],[b]:["error"],[P]:["error"]};return Object.fromEntries(Object.entries(s).map(([a,[l,e]])=>[a,[l,Object.assign(e,t)]]))};const v={name:C,rules:{[T]:z,[b]:J,[P]:$},configs:{"recommended-natural":_({type:"natural",order:"asc"}),"recommended-line-length":_({type:"line-length",order:"desc"})}};module.exports=v;
package/dist/index.mjs ADDED
@@ -0,0 +1,273 @@
1
+ import { AST_NODE_TYPES as y } from "@typescript-eslint/types";
2
+ import { ESLintUtils as C } from "@typescript-eslint/utils";
3
+ import T from "natural-compare-lite";
4
+ const z = "eslint-plugin-perfectionist", J = "azat-io/eslint-plugin-perfectionist";
5
+ let O = C.RuleCreator(
6
+ (t) => `https://github.com/${J}/blob/main/docs/rules/${t}.md`
7
+ ), h = (t) => {
8
+ let [s, a] = t;
9
+ return a - s;
10
+ };
11
+ var d = /* @__PURE__ */ ((t) => (t.natural = "natural", t["line-length"] = "line-length", t))(d || {}), c = /* @__PURE__ */ ((t) => (t.asc = "asc", t.desc = "desc", t))(c || {});
12
+ let S = (t, s, a) => (a.order === "asc" ? 1 : -1) * (a.type === d.natural ? T(t.name, s.name) : t.size - s.size) > 0, b = (t, s, a, l) => {
13
+ let e = [...a].sort((r, o) => Number(S(r, o, l)) || -1), n = (r) => [r.range.at(0), r.range.at(1)];
14
+ return a.map(
15
+ ({ node: r }, o) => t.replaceTextRange(n(r), s.slice(...n(e[o].node)))
16
+ );
17
+ }, N = (t = {}, s) => Object.assign(s, t);
18
+ const E = "sort-interfaces", $ = O({
19
+ name: E,
20
+ meta: {
21
+ type: "suggestion",
22
+ docs: {
23
+ description: "Enforce sorted interface properties",
24
+ recommended: !1
25
+ },
26
+ messages: {
27
+ unexpectedInterfacePropertiesOrder: 'Expected "{{second}}" to come before "{{first}}"'
28
+ },
29
+ fixable: "code",
30
+ schema: [
31
+ {
32
+ type: "object",
33
+ properties: {
34
+ type: {
35
+ enum: [d.natural, d["line-length"]]
36
+ },
37
+ order: {
38
+ enum: [c.asc, c.desc]
39
+ }
40
+ },
41
+ additionalProperties: !1
42
+ }
43
+ ]
44
+ },
45
+ defaultOptions: [
46
+ {
47
+ type: d.natural,
48
+ order: c.asc
49
+ }
50
+ ],
51
+ create: (t) => ({
52
+ TSInterfaceBody: (s) => {
53
+ let a = N(t.options.at(0), {
54
+ type: d.natural,
55
+ order: c.asc
56
+ }), l = s.body.map((e) => {
57
+ let n = "", r = 0, o = (i) => {
58
+ r += i;
59
+ }, p = (i) => {
60
+ o(h(i.key.range));
61
+ }, g = (i) => {
62
+ let { length: u } = "[]";
63
+ o(i.parameters.reduce((I, { range: A }) => I + h(A), u));
64
+ }, m = (i) => {
65
+ if (i.optional) {
66
+ let { length: u } = "?";
67
+ o(u);
68
+ }
69
+ }, x = (i) => {
70
+ var I;
71
+ let u = (I = i.typeAnnotation) == null ? void 0 : I.range;
72
+ u && o(h(u));
73
+ }, f = (i) => {
74
+ if (i.type === y.Identifier)
75
+ ({ name: n } = i);
76
+ else if (i.type === y.TSIndexSignature) {
77
+ let u = i.parameters.at(0);
78
+ u && f(u);
79
+ }
80
+ };
81
+ return e.type === y.TSPropertySignature ? (f(e.key), p(e), m(e), x(e)) : e.type === y.TSIndexSignature && (f(e), g(e), x(e)), {
82
+ node: e,
83
+ name: n,
84
+ size: r
85
+ };
86
+ });
87
+ for (let e = 1; e < l.length; e++) {
88
+ let n = e - 1, r = e, o = l.at(n), p = l.at(r);
89
+ if (S(o, p, a)) {
90
+ let g = s.body[r];
91
+ t.report({
92
+ messageId: "unexpectedInterfacePropertiesOrder",
93
+ data: {
94
+ first: o.name,
95
+ second: p.name
96
+ },
97
+ node: g,
98
+ fix: (m) => {
99
+ let x = t.getSourceCode(), { text: f } = x;
100
+ return b(m, f, l, a);
101
+ }
102
+ });
103
+ }
104
+ }
105
+ }
106
+ })
107
+ }), R = "sort-jsx-props", v = O({
108
+ name: R,
109
+ meta: {
110
+ type: "suggestion",
111
+ docs: {
112
+ description: "Enforce sorted interface properties",
113
+ recommended: !1
114
+ },
115
+ messages: {
116
+ unexpectedJSXPropsOrder: 'Expected "{{second}}" to come before "{{first}}"'
117
+ },
118
+ fixable: "code",
119
+ schema: [
120
+ {
121
+ type: "object",
122
+ properties: {
123
+ type: {
124
+ enum: [d.natural, d["line-length"]]
125
+ },
126
+ order: {
127
+ enum: [c.asc, c.desc]
128
+ }
129
+ },
130
+ additionalProperties: !1
131
+ }
132
+ ]
133
+ },
134
+ defaultOptions: [
135
+ {
136
+ type: d.natural,
137
+ order: c.asc
138
+ }
139
+ ],
140
+ create: (t) => ({
141
+ JSXElement: (s) => {
142
+ let a = N(t.options.at(0), {
143
+ type: d.natural,
144
+ order: c.asc
145
+ });
146
+ s.openingElement.attributes.reduce(
147
+ (e, n) => (n.type === "JSXAttribute" ? e.at(-1).push(n) : e.push([]), e),
148
+ [[]]
149
+ ).forEach((e) => {
150
+ let n = e.map((r) => ({
151
+ name: r.name.type === y.JSXNamespacedName ? `${r.name.namespace.name}:${r.name.name.name}` : r.name.name,
152
+ size: h(r.range),
153
+ node: r
154
+ }));
155
+ for (let r = 1; r < n.length; r++) {
156
+ let o = r - 1, p = r, g = n.at(o), m = n.at(p);
157
+ S(g, m, a) && t.report({
158
+ messageId: "unexpectedJSXPropsOrder",
159
+ data: {
160
+ first: g.name,
161
+ second: m.name
162
+ },
163
+ node: m.node,
164
+ fix: (x) => {
165
+ let f = t.getSourceCode(), { text: i } = f;
166
+ return b(x, i, n, a);
167
+ }
168
+ });
169
+ }
170
+ });
171
+ }
172
+ })
173
+ }), P = "sort-named-imports", X = O({
174
+ name: P,
175
+ meta: {
176
+ type: "suggestion",
177
+ docs: {
178
+ description: "Enforce sorted interface properties",
179
+ recommended: !1
180
+ },
181
+ messages: {
182
+ unexpectedNamedImportsOrder: 'Expected "{{second}}" to come before "{{first}}"'
183
+ },
184
+ fixable: "code",
185
+ schema: [
186
+ {
187
+ type: "object",
188
+ properties: {
189
+ type: {
190
+ enum: [d.natural, d["line-length"]]
191
+ },
192
+ order: {
193
+ enum: [c.asc, c.desc]
194
+ }
195
+ },
196
+ additionalProperties: !1
197
+ }
198
+ ]
199
+ },
200
+ defaultOptions: [
201
+ {
202
+ type: d.natural,
203
+ order: c.asc
204
+ }
205
+ ],
206
+ create: (t) => ({
207
+ ImportDeclaration: (s) => {
208
+ let a = N(t.options.at(0), {
209
+ type: d.natural,
210
+ order: c.asc
211
+ });
212
+ if (s.specifiers.length > 1) {
213
+ let l = s.specifiers.map((e) => {
214
+ let {
215
+ range: n,
216
+ local: { name: r }
217
+ } = e;
218
+ return {
219
+ size: h(n),
220
+ node: e,
221
+ name: r
222
+ };
223
+ });
224
+ for (let e = 1; e < l.length; e++) {
225
+ let n = e - 1, r = e, o = l.at(n), p = l.at(r);
226
+ if (S(o, p, a)) {
227
+ let g = s.specifiers[r];
228
+ t.report({
229
+ messageId: "unexpectedNamedImportsOrder",
230
+ data: {
231
+ first: o.name,
232
+ second: p.name
233
+ },
234
+ node: g,
235
+ fix: (m) => {
236
+ let x = t.getSourceCode(), { text: f } = x;
237
+ return b(m, f, l, a);
238
+ }
239
+ });
240
+ }
241
+ }
242
+ }
243
+ }
244
+ })
245
+ });
246
+ let j = (t) => {
247
+ let s = {
248
+ [E]: ["error"],
249
+ [R]: ["error"],
250
+ [P]: ["error"]
251
+ };
252
+ return Object.fromEntries(
253
+ Object.entries(s).map(([a, [l, e]]) => [
254
+ a,
255
+ [l, Object.assign(e, t)]
256
+ ])
257
+ );
258
+ };
259
+ const D = {
260
+ name: z,
261
+ rules: {
262
+ [E]: $,
263
+ [R]: v,
264
+ [P]: X
265
+ },
266
+ configs: {
267
+ "recommended-natural": j({ type: "natural", order: "asc" }),
268
+ "recommended-line-length": j({ type: "line-length", order: "desc" })
269
+ }
270
+ };
271
+ export {
272
+ D as default
273
+ };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "eslint-plugin-perfectionist",
3
3
  "description": "ESLint plugin for code formatting in perfectionist style",
4
- "version": "0.1.0",
5
- "type": "module",
4
+ "version": "0.3.0",
5
+ "homepage": "https://eslint-plugin-perfectionist.azat.io",
6
6
  "repository": "azat-io/eslint-plugin-perfectionist",
7
7
  "author": "Azat S. <to@azat.io>",
8
8
  "license": "MIT",
@@ -19,8 +19,8 @@
19
19
  ],
20
20
  "exports": {
21
21
  ".": {
22
- "require": "./dist/index.cjs.js",
23
- "import": "./dist/index.es.js"
22
+ "require": "./dist/index.js",
23
+ "import": "./dist/index.mjs"
24
24
  },
25
25
  "./package.json": "./package.json"
26
26
  },
@@ -28,7 +28,8 @@
28
28
  "eslint": "^8.39.0"
29
29
  },
30
30
  "dependencies": {
31
- "@typescript-eslint/types": "^5.59.2",
32
- "@typescript-eslint/utils": "^5.59.2"
31
+ "@typescript-eslint/types": "^5.59.6",
32
+ "@typescript-eslint/utils": "^5.59.6",
33
+ "natural-compare-lite": "^1.4.0"
33
34
  }
34
35
  }
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ESLint Plugin Perfectionist
2
2
 
3
- <img src="https://user-images.githubusercontent.com/5698350/234571772-9e0cf164-d6bd-46fa-91d3-9c6f2a83932c.svg" alt="ESLint" align="right" width="120" height="120" />
3
+ <img src="https://raw.githubusercontent.com/azat-io/eslint-plugin-perfectionist/main/docs/public/logo.svg" alt="ESLint" align="right" width="120" height="120" />
4
4
 
5
5
  ![Version](https://img.shields.io/npm/v/eslint-plugin-perfectionist.svg?color=brightgreen)
6
6
 
@@ -22,9 +22,12 @@ npm install --save-dev eslint-plugin-perfectionist
22
22
 
23
23
  ## Rules
24
24
 
25
- | Name | Description | 💼 | 🔧 |
26
- | :-------------- | :---------------------------------- | :-- | :-- |
27
- | sort-interfaces | Enforce sorted interface properties | 💼 | 🔧 |
25
+ | Name | Description | 💼 | 🛠 |
26
+ | :----------------------------------------------------------------------------------------- | :---------------------------------- | :-- | :-- |
27
+ | [sort-interfaces](https://eslint-plugin-perfectionist.azat.io/rules/sort-interfaces) | Enforce sorted interface properties | ✅ | 🔧 |
28
+ | [sort-jsx-props](https://eslint-plugin-perfectionist.azat.io/rules/sort-jsx-props) | Enforce sorted JSX props | ✅ | 🔧 |
29
+ | [sort-named-imports](https://eslint-plugin-perfectionist.azat.io/rules/sort-named-imports) | Enforce sorted named imports | ✅ | 🔧 |
30
+ | [sort-union-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-union-types) | Enforce sorted union types | ✅ | 🔧 |
28
31
 
29
32
  ## See also
30
33
 
package/dist/index.cjs.js DELETED
@@ -1 +0,0 @@
1
- "use strict";const g=require("@typescript-eslint/types"),y=require("@typescript-eslint/utils"),I="eslint-plugin-perfectionist",_="azat-io/eslint-plugin-perfectionist";let b=y.ESLintUtils.RuleCreator(f=>`https://github.com/${_}/blob/main/docs/rules/${f}.md`);const T="sort-interfaces",A=b({name:T,meta:{type:"suggestion",docs:{description:"Enforce sorted interface properties",recommended:!1},messages:{unexpectedInterfacePropertiesOrder:'Expected "{{second}}" to come before "{{first}}"'},fixable:"code",schema:[]},defaultOptions:[],create:f=>({TSInterfaceBody:S=>{let x=S.body.map(t=>{let a="",l=0,n=e=>{l+=e},i=e=>{let[r,o]=e;return o-r},u=e=>{n(i(e.key.range))},p=e=>{let{length:r}="[]";n(e.parameters.reduce((o,{range:m})=>o+i(m),r))},c=e=>{if(e.optional){let{length:r}="?";n(r)}},d=e=>{var o;let r=(o=e.typeAnnotation)==null?void 0:o.range;r&&n(i(r))},s=e=>{if(e.type===g.AST_NODE_TYPES.Identifier)({name:a}=e);else if(e.type===g.AST_NODE_TYPES.TSIndexSignature){let r=e.parameters.at(0);r&&s(r)}};return t.type===g.AST_NODE_TYPES.TSPropertySignature?(s(t.key),u(t),c(t),d(t)):t.type===g.AST_NODE_TYPES.TSIndexSignature&&(s(t),p(t),d(t)),{name:a,size:l}});for(let t=1;t<x.length;t++){let a=t-1,l=t,n=x.at(a),i=x.at(l);if(n.size<i.size){let u=f.getSourceCode(),p=S.body[a],c=S.body[l];f.report({messageId:"unexpectedInterfacePropertiesOrder",data:{first:n.name,second:i.name},node:c,fix:d=>{let s=r=>[r.range.at(0),r.range.at(1)];return[d.replaceTextRange(s(p),u.text.slice(...s(c))),d.replaceTextRange(s(c),u.text.slice(...s(p)))]}})}}}})}),O={name:I,rules:{[T]:A}};module.exports=O;
package/dist/index.es.js DELETED
@@ -1,102 +0,0 @@
1
- import { AST_NODE_TYPES as u } from "@typescript-eslint/types";
2
- import { ESLintUtils as y } from "@typescript-eslint/utils";
3
- const T = "eslint-plugin-perfectionist", b = "azat-io/eslint-plugin-perfectionist";
4
- let R = y.RuleCreator(
5
- (f) => `https://github.com/${b}/blob/main/docs/rules/${f}.md`
6
- );
7
- const S = "sort-interfaces", h = R({
8
- name: S,
9
- meta: {
10
- type: "suggestion",
11
- docs: {
12
- description: "Enforce sorted interface properties",
13
- recommended: !1
14
- },
15
- messages: {
16
- unexpectedInterfacePropertiesOrder: 'Expected "{{second}}" to come before "{{first}}"'
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- defaultOptions: [],
22
- create: (f) => ({
23
- TSInterfaceBody: (m) => {
24
- let x = m.body.map((t) => {
25
- let i = "", l = 0, n = (e) => {
26
- l += e;
27
- }, o = (e) => {
28
- let [r, a] = e;
29
- return a - r;
30
- }, p = (e) => {
31
- n(o(e.key.range));
32
- }, g = (e) => {
33
- let { length: r } = "[]";
34
- n(
35
- e.parameters.reduce(
36
- (a, { range: I }) => a + o(I),
37
- r
38
- )
39
- );
40
- }, c = (e) => {
41
- if (e.optional) {
42
- let { length: r } = "?";
43
- n(r);
44
- }
45
- }, d = (e) => {
46
- var a;
47
- let r = (a = e.typeAnnotation) == null ? void 0 : a.range;
48
- r && n(o(r));
49
- }, s = (e) => {
50
- if (e.type === u.Identifier)
51
- ({ name: i } = e);
52
- else if (e.type === u.TSIndexSignature) {
53
- let r = e.parameters.at(0);
54
- r && s(r);
55
- }
56
- };
57
- return t.type === u.TSPropertySignature ? (s(t.key), p(t), c(t), d(t)) : t.type === u.TSIndexSignature && (s(t), g(t), d(t)), {
58
- name: i,
59
- size: l
60
- };
61
- });
62
- for (let t = 1; t < x.length; t++) {
63
- let i = t - 1, l = t, n = x.at(i), o = x.at(l);
64
- if (n.size < o.size) {
65
- let p = f.getSourceCode(), g = m.body[i], c = m.body[l];
66
- f.report({
67
- messageId: "unexpectedInterfacePropertiesOrder",
68
- data: {
69
- first: n.name,
70
- second: o.name
71
- },
72
- node: c,
73
- fix: (d) => {
74
- let s = (r) => [
75
- r.range.at(0),
76
- r.range.at(1)
77
- ];
78
- return [
79
- d.replaceTextRange(
80
- s(g),
81
- p.text.slice(...s(c))
82
- ),
83
- d.replaceTextRange(
84
- s(c),
85
- p.text.slice(...s(g))
86
- )
87
- ];
88
- }
89
- });
90
- }
91
- }
92
- }
93
- })
94
- }), z = {
95
- name: T,
96
- rules: {
97
- [S]: h
98
- }
99
- };
100
- export {
101
- z as default
102
- };