eslint-plugin-perfectionist 0.3.0 → 0.5.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 CHANGED
@@ -1 +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;
1
+ "use strict";const f=require("@typescript-eslint/types"),Y=require("@typescript-eslint/utils"),L=require("natural-compare-lite"),j="eslint-plugin-perfectionist",C="azat-io/eslint-plugin-perfectionist";let y=Y.ESLintUtils.RuleCreator(r=>`https://github.com/${C}/blob/main/docs/rules/${r}.md`),E=r=>{let[o,l]=r;return l-o};var n=(r=>(r.natural="natural",r["line-length"]="line-length",r))(n||{}),d=(r=>(r.asc="asc",r.desc="desc",r))(d||{});let m=(r,o,l)=>(l.order==="asc"?1:-1)*(l.type===n.natural?L(r.name,o.name):r.size-o.size)>0,S=(r,o,l,p)=>{let s=[...l].sort((t,a)=>Number(m(t,a,p))||-1);p.spreadLast&&s.forEach((t,a)=>{t.node.type===f.AST_NODE_TYPES.SpreadElement&&s.push(s.splice(a,1).at(0))});let e=t=>[t.range.at(0),t.range.at(1)];return l.map(({node:t},a)=>r.replaceTextRange(e(t),o.slice(...e(s[a].node))))},T=(r={},o)=>Object.assign(o,r);const _="sort-array-includes",M=y({name:_,meta:{type:"suggestion",docs:{description:"Enforce sorted arrays before include method",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc},spreadLast:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedArrayIncludesOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({MemberExpression:o=>{if((o.object.type===f.AST_NODE_TYPES.ArrayExpression||o.object.type===f.AST_NODE_TYPES.NewExpression)&&o.property.type===f.AST_NODE_TYPES.Identifier&&o.property.name==="includes"){let l=T(r.options.at(0),{type:n.natural,order:d.asc,spreadLast:!1}),p=o.object.type===f.AST_NODE_TYPES.ArrayExpression?o.object.elements:o.object.arguments;if(p.length>1){let s=r.getSourceCode().text,e=p.reduce((t,a)=>(a===null||t.at(0).push({name:a.type===f.AST_NODE_TYPES.Literal?a.raw:s.slice(...a.range),size:E(a.range),type:a.type,node:a}),t),[[],[]]).flat();for(let t=1;t<e.length;t++){let a=e.at(t-1),i=e.at(t),c;l.spreadLast&&a.node.type===f.AST_NODE_TYPES.Literal&&i.node.type===f.AST_NODE_TYPES.SpreadElement?c=!1:l.spreadLast&&a.node.type===f.AST_NODE_TYPES.SpreadElement&&i.node.type===f.AST_NODE_TYPES.Literal?c=!0:c=m(a,i,l),c&&r.report({messageId:"unexpectedArrayIncludesOrder",data:{first:a.name,second:i.name},node:i.node,fix:u=>{let g=r.getSourceCode(),{text:x}=g;return S(u,x,e,l)}})}}}}})}),N="sort-interfaces",R=y({name:N,meta:{type:"suggestion",docs:{description:"Enforce sorted interface properties",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedInterfacePropertiesOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({TSInterfaceBody:o=>{let l=T(r.options.at(0),{type:n.natural,order:d.asc});if(o.body.length>1){let p=r.getSourceCode().text,s=o.body.map(e=>{var a,i,c;let t;if(e.type===f.AST_NODE_TYPES.TSPropertySignature)if(e.key.type===f.AST_NODE_TYPES.Identifier)({name:t}=e.key);else if(e.key.type===f.AST_NODE_TYPES.Literal)t=`${e.key.value}`;else{let u;if((a=e.typeAnnotation)!=null&&a.range.at(0))u=e.typeAnnotation.range.at(0);else{let g=e.optional?1:0;u=e.range.at(1)-g}t=p.slice(e.range.at(0),u)}else e.type===f.AST_NODE_TYPES.TSIndexSignature?t=p.slice(e.range.at(0),((i=e.typeAnnotation)==null?void 0:i.range.at(0))??e.range.at(1)):t=p.slice(e.range.at(0),((c=e.returnType)==null?void 0:c.range.at(0))??e.range.at(1));return{size:E(e.range),node:e,name:t}});for(let e=1;e<s.length;e++){let t=s.at(e-1),a=s.at(e);if(m(t,a,l)){let i=o.body[e];r.report({messageId:"unexpectedInterfacePropertiesOrder",data:{first:t.name,second:a.name},node:i,fix:c=>S(c,p,s,l)})}}}}})}),O="sort-jsx-props",U=y({name:O,meta:{type:"suggestion",docs:{description:"Enforce sorted JSX props",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedJSXPropsOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({JSXElement:o=>{let l=T(r.options.at(0),{type:n.natural,order:d.asc});o.openingElement.attributes.reduce((s,e)=>(e.type==="JSXAttribute"?s.at(-1).push(e):s.push([]),s),[[]]).forEach(s=>{let e=s.map(t=>({name:t.name.type===f.AST_NODE_TYPES.JSXNamespacedName?`${t.name.namespace.name}:${t.name.name.name}`:t.name.name,size:E(t.range),node:t}));for(let t=1;t<e.length;t++){let a=e.at(t-1),i=e.at(t);m(a,i,l)&&r.report({messageId:"unexpectedJSXPropsOrder",data:{first:a.name,second:i.name},node:i.node,fix:c=>{let u=r.getSourceCode().text;return S(c,u,e,l)}})}})}})}),h="sort-map-elements",$=y({name:h,meta:{type:"suggestion",docs:{description:"Enforce sorted Map elements",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedMapElementsOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({NewExpression:o=>{if(o.callee.type===f.AST_NODE_TYPES.Identifier&&o.callee.name==="Map"&&o.arguments[0].type===f.AST_NODE_TYPES.ArrayExpression){let l=T(r.options.at(0),{type:n.natural,order:d.asc}),[{elements:p}]=o.arguments,s=r.getSourceCode().text;p.length>1&&p.reduce((t,a)=>(a===null||a.type===f.AST_NODE_TYPES.SpreadElement?t.push([]):t.at(-1).push(a),t),[[]]).forEach(t=>{let a=t.map(i=>{let c;if(i.type===f.AST_NODE_TYPES.ArrayExpression){let[u]=i.elements;u?u.type===f.AST_NODE_TYPES.Literal?c=u.raw:c=s.slice(...u.range):c=`${u}`}else c=s.slice(...i.range);return{size:E(i.range),node:i,name:c}});for(let i=1;i<a.length;i++){let c=a.at(i-1),u=a.at(i);m(c,u,l)&&r.report({messageId:"unexpectedMapElementsOrder",data:{first:c.name,second:u.name},node:u.node,fix:g=>{let x=r.getSourceCode(),{text:I}=x;return S(g,I,a,l)}})}})}}})}),A="sort-named-exports",v=y({name:A,meta:{type:"suggestion",docs:{description:"Enforce sorted named exports",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedNamedExportsOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({ExportNamedDeclaration:o=>{let l=T(r.options.at(0),{type:n.natural,order:d.asc});if(o.specifiers.length>1){let p=o.specifiers.map(s=>{let{range:e,local:{name:t}}=s;return{size:E(e),node:s,name:t}});for(let s=1;s<p.length;s++){let e=p.at(s-1),t=p.at(s);if(m(e,t,l)){let a=o.specifiers[s];r.report({messageId:"unexpectedNamedExportsOrder",data:{first:e.name,second:t.name},node:a,fix:i=>{let c=r.getSourceCode(),{text:u}=c;return S(i,u,p,l)}})}}}}})}),b="sort-named-imports",z=y({name:b,meta:{type:"suggestion",docs:{description:"Enforce sorted named imports",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedNamedImportsOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({ImportDeclaration:o=>{let l=T(r.options.at(0),{type:n.natural,order:d.asc});if(o.specifiers.length>1){let p=o.specifiers.map(s=>{let{range:e,local:{name:t}}=s;return{size:E(e),node:s,name:t}});for(let s=1;s<p.length;s++){let e=p.at(s-1),t=p.at(s);if(m(e,t,l)){let a=o.specifiers[s];r.report({messageId:"unexpectedNamedImportsOrder",data:{first:e.name,second:t.name},node:a,fix:i=>{let c=r.getSourceCode(),{text:u}=c;return S(i,u,p,l)}})}}}}})}),P="sort-union-types",J=y({name:P,meta:{type:"suggestion",docs:{description:"Enforce sorted union types",recommended:!1},fixable:"code",schema:[{type:"object",properties:{type:{enum:[n.natural,n["line-length"]],default:n.natural},order:{enum:[d.asc,d.desc],default:d.asc}},additionalProperties:!1}],messages:{unexpectedUnionTypesOrder:'Expected "{{second}}" to come before "{{first}}"'}},defaultOptions:[{type:n.natural,order:d.asc}],create:r=>({TSUnionType:o=>{let l=r.getSourceCode().text,p=T(r.options.at(0),{type:n.natural,order:d.asc}),s=o.types.map(e=>{let{range:t}=e,a=l.slice(...t);return{size:E(t),node:e,name:a}});for(let e=1;e<s.length;e++){let t=s.at(e-1),a=s.at(e);if(m(t,a,p)){let i=o.types[e];r.report({messageId:"unexpectedUnionTypesOrder",data:{first:t.name,second:a.name},node:i,fix:c=>{let u=r.getSourceCode(),{text:g}=u;return S(c,g,s,p)}})}}}})});let D=r=>{let o={[_]:["error",{spreadLast:!0}],[N]:["error"],[O]:["error"],[h]:["error"],[A]:["error"],[b]:["error"],[P]:["error"]};return Object.fromEntries(Object.entries(o).map(([l,[p,s={}]])=>[l,[p,Object.assign(s,r)]]))};const X={name:j,rules:{[_]:M,[N]:R,[O]:U,[h]:$,[A]:v,[b]:z,[P]:J},configs:{"recommended-natural":D({type:n.natural,order:d.asc}),"recommended-line-length":D({type:n["line-length"],order:d.desc})}};module.exports=X;
package/dist/index.mjs CHANGED
@@ -1,119 +1,193 @@
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;
1
+ import { AST_NODE_TYPES as f } from "@typescript-eslint/types";
2
+ import { ESLintUtils as M } from "@typescript-eslint/utils";
3
+ import R from "natural-compare-lite";
4
+ const T = "eslint-plugin-perfectionist", U = "azat-io/eslint-plugin-perfectionist";
5
+ let y = M.RuleCreator(
6
+ (r) => `https://github.com/${U}/blob/main/docs/rules/${r}.md`
7
+ ), E = (r) => {
8
+ let [o, l] = r;
9
+ return l - o;
10
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)))
11
+ var n = /* @__PURE__ */ ((r) => (r.natural = "natural", r["line-length"] = "line-length", r))(n || {}), d = /* @__PURE__ */ ((r) => (r.asc = "asc", r.desc = "desc", r))(d || {});
12
+ let m = (r, o, l) => (l.order === "asc" ? 1 : -1) * (l.type === n.natural ? R(r.name, o.name) : r.size - o.size) > 0, x = (r, o, l, p) => {
13
+ let s = [...l].sort((t, a) => Number(m(t, a, p)) || -1);
14
+ p.spreadLast && s.forEach((t, a) => {
15
+ t.node.type === f.SpreadElement && s.push(s.splice(a, 1).at(0));
16
+ });
17
+ let e = (t) => [t.range.at(0), t.range.at(1)];
18
+ return l.map(
19
+ ({ node: t }, a) => r.replaceTextRange(e(t), o.slice(...e(s[a].node)))
16
20
  );
17
- }, N = (t = {}, s) => Object.assign(s, t);
18
- const E = "sort-interfaces", $ = O({
19
- name: E,
21
+ }, h = (r = {}, o) => Object.assign(o, r);
22
+ const N = "sort-array-includes", $ = y({
23
+ name: N,
20
24
  meta: {
21
25
  type: "suggestion",
22
26
  docs: {
23
- description: "Enforce sorted interface properties",
27
+ description: "Enforce sorted arrays before include method",
24
28
  recommended: !1
25
29
  },
26
- messages: {
27
- unexpectedInterfacePropertiesOrder: 'Expected "{{second}}" to come before "{{first}}"'
28
- },
29
30
  fixable: "code",
30
31
  schema: [
31
32
  {
32
33
  type: "object",
33
34
  properties: {
34
35
  type: {
35
- enum: [d.natural, d["line-length"]]
36
+ enum: [n.natural, n["line-length"]],
37
+ default: n.natural
36
38
  },
37
39
  order: {
38
- enum: [c.asc, c.desc]
40
+ enum: [d.asc, d.desc],
41
+ default: d.asc
42
+ },
43
+ spreadLast: {
44
+ type: "boolean",
45
+ default: !1
39
46
  }
40
47
  },
41
48
  additionalProperties: !1
42
49
  }
43
- ]
50
+ ],
51
+ messages: {
52
+ unexpectedArrayIncludesOrder: 'Expected "{{second}}" to come before "{{first}}"'
53
+ }
44
54
  },
45
55
  defaultOptions: [
46
56
  {
47
- type: d.natural,
48
- order: c.asc
57
+ type: n.natural,
58
+ order: d.asc
49
59
  }
50
60
  ],
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);
61
+ create: (r) => ({
62
+ MemberExpression: (o) => {
63
+ if ((o.object.type === f.ArrayExpression || o.object.type === f.NewExpression) && o.property.type === f.Identifier && o.property.name === "includes") {
64
+ let l = h(r.options.at(0), {
65
+ type: n.natural,
66
+ order: d.asc,
67
+ spreadLast: !1
68
+ }), p = o.object.type === f.ArrayExpression ? o.object.elements : o.object.arguments;
69
+ if (p.length > 1) {
70
+ let s = r.getSourceCode().text, e = p.reduce(
71
+ (t, a) => (a === null || t.at(0).push({
72
+ name: a.type === f.Literal ? a.raw : s.slice(...a.range),
73
+ size: E(a.range),
74
+ type: a.type,
75
+ node: a
76
+ }), t),
77
+ [[], []]
78
+ ).flat();
79
+ for (let t = 1; t < e.length; t++) {
80
+ let a = e.at(t - 1), i = e.at(t), c;
81
+ l.spreadLast && a.node.type === f.Literal && i.node.type === f.SpreadElement ? c = !1 : l.spreadLast && a.node.type === f.SpreadElement && i.node.type === f.Literal ? c = !0 : c = m(a, i, l), c && r.report({
82
+ messageId: "unexpectedArrayIncludesOrder",
83
+ data: {
84
+ first: a.name,
85
+ second: i.name
86
+ },
87
+ node: i.node,
88
+ fix: (u) => {
89
+ let g = r.getSourceCode(), { text: b } = g;
90
+ return x(u, b, e, l);
91
+ }
92
+ });
79
93
  }
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
94
  }
104
95
  }
105
96
  }
106
97
  })
107
- }), R = "sort-jsx-props", v = O({
108
- name: R,
98
+ }), S = "sort-interfaces", v = y({
99
+ name: S,
109
100
  meta: {
110
101
  type: "suggestion",
111
102
  docs: {
112
103
  description: "Enforce sorted interface properties",
113
104
  recommended: !1
114
105
  },
106
+ fixable: "code",
107
+ schema: [
108
+ {
109
+ type: "object",
110
+ properties: {
111
+ type: {
112
+ enum: [n.natural, n["line-length"]],
113
+ default: n.natural
114
+ },
115
+ order: {
116
+ enum: [d.asc, d.desc],
117
+ default: d.asc
118
+ }
119
+ },
120
+ additionalProperties: !1
121
+ }
122
+ ],
115
123
  messages: {
116
- unexpectedJSXPropsOrder: 'Expected "{{second}}" to come before "{{first}}"'
124
+ unexpectedInterfacePropertiesOrder: 'Expected "{{second}}" to come before "{{first}}"'
125
+ }
126
+ },
127
+ defaultOptions: [
128
+ {
129
+ type: n.natural,
130
+ order: d.asc
131
+ }
132
+ ],
133
+ create: (r) => ({
134
+ TSInterfaceBody: (o) => {
135
+ let l = h(r.options.at(0), {
136
+ type: n.natural,
137
+ order: d.asc
138
+ });
139
+ if (o.body.length > 1) {
140
+ let p = r.getSourceCode().text, s = o.body.map((e) => {
141
+ var a, i, c;
142
+ let t;
143
+ if (e.type === f.TSPropertySignature)
144
+ if (e.key.type === f.Identifier)
145
+ ({ name: t } = e.key);
146
+ else if (e.key.type === f.Literal)
147
+ t = `${e.key.value}`;
148
+ else {
149
+ let u;
150
+ if ((a = e.typeAnnotation) != null && a.range.at(0))
151
+ u = e.typeAnnotation.range.at(0);
152
+ else {
153
+ let g = e.optional ? 1 : 0;
154
+ u = e.range.at(1) - g;
155
+ }
156
+ t = p.slice(e.range.at(0), u);
157
+ }
158
+ else
159
+ e.type === f.TSIndexSignature ? t = p.slice(e.range.at(0), ((i = e.typeAnnotation) == null ? void 0 : i.range.at(0)) ?? e.range.at(1)) : t = p.slice(e.range.at(0), ((c = e.returnType) == null ? void 0 : c.range.at(0)) ?? e.range.at(1));
160
+ return {
161
+ size: E(e.range),
162
+ node: e,
163
+ name: t
164
+ };
165
+ });
166
+ for (let e = 1; e < s.length; e++) {
167
+ let t = s.at(e - 1), a = s.at(e);
168
+ if (m(t, a, l)) {
169
+ let i = o.body[e];
170
+ r.report({
171
+ messageId: "unexpectedInterfacePropertiesOrder",
172
+ data: {
173
+ first: t.name,
174
+ second: a.name
175
+ },
176
+ node: i,
177
+ fix: (c) => x(c, p, s, l)
178
+ });
179
+ }
180
+ }
181
+ }
182
+ }
183
+ })
184
+ }), O = "sort-jsx-props", z = y({
185
+ name: O,
186
+ meta: {
187
+ type: "suggestion",
188
+ docs: {
189
+ description: "Enforce sorted JSX props",
190
+ recommended: !1
117
191
  },
118
192
  fixable: "code",
119
193
  schema: [
@@ -121,65 +195,145 @@ const E = "sort-interfaces", $ = O({
121
195
  type: "object",
122
196
  properties: {
123
197
  type: {
124
- enum: [d.natural, d["line-length"]]
198
+ enum: [n.natural, n["line-length"]],
199
+ default: n.natural
125
200
  },
126
201
  order: {
127
- enum: [c.asc, c.desc]
202
+ enum: [d.asc, d.desc],
203
+ default: d.asc
128
204
  }
129
205
  },
130
206
  additionalProperties: !1
131
207
  }
132
- ]
208
+ ],
209
+ messages: {
210
+ unexpectedJSXPropsOrder: 'Expected "{{second}}" to come before "{{first}}"'
211
+ }
133
212
  },
134
213
  defaultOptions: [
135
214
  {
136
- type: d.natural,
137
- order: c.asc
215
+ type: n.natural,
216
+ order: d.asc
138
217
  }
139
218
  ],
140
- create: (t) => ({
141
- JSXElement: (s) => {
142
- let a = N(t.options.at(0), {
143
- type: d.natural,
144
- order: c.asc
219
+ create: (r) => ({
220
+ JSXElement: (o) => {
221
+ let l = h(r.options.at(0), {
222
+ type: n.natural,
223
+ order: d.asc
145
224
  });
146
- s.openingElement.attributes.reduce(
147
- (e, n) => (n.type === "JSXAttribute" ? e.at(-1).push(n) : e.push([]), e),
225
+ o.openingElement.attributes.reduce(
226
+ (s, e) => (e.type === "JSXAttribute" ? s.at(-1).push(e) : s.push([]), s),
148
227
  [[]]
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
228
+ ).forEach((s) => {
229
+ let e = s.map((t) => ({
230
+ name: t.name.type === f.JSXNamespacedName ? `${t.name.namespace.name}:${t.name.name.name}` : t.name.name,
231
+ size: E(t.range),
232
+ node: t
154
233
  }));
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({
234
+ for (let t = 1; t < e.length; t++) {
235
+ let a = e.at(t - 1), i = e.at(t);
236
+ m(a, i, l) && r.report({
158
237
  messageId: "unexpectedJSXPropsOrder",
159
238
  data: {
160
- first: g.name,
161
- second: m.name
239
+ first: a.name,
240
+ second: i.name
162
241
  },
163
- node: m.node,
164
- fix: (x) => {
165
- let f = t.getSourceCode(), { text: i } = f;
166
- return b(x, i, n, a);
242
+ node: i.node,
243
+ fix: (c) => {
244
+ let u = r.getSourceCode().text;
245
+ return x(c, u, e, l);
167
246
  }
168
247
  });
169
248
  }
170
249
  });
171
250
  }
172
251
  })
173
- }), P = "sort-named-imports", X = O({
174
- name: P,
252
+ }), I = "sort-map-elements", _ = y({
253
+ name: I,
175
254
  meta: {
176
255
  type: "suggestion",
177
256
  docs: {
178
- description: "Enforce sorted interface properties",
257
+ description: "Enforce sorted Map elements",
179
258
  recommended: !1
180
259
  },
260
+ fixable: "code",
261
+ schema: [
262
+ {
263
+ type: "object",
264
+ properties: {
265
+ type: {
266
+ enum: [n.natural, n["line-length"]],
267
+ default: n.natural
268
+ },
269
+ order: {
270
+ enum: [d.asc, d.desc],
271
+ default: d.asc
272
+ }
273
+ },
274
+ additionalProperties: !1
275
+ }
276
+ ],
181
277
  messages: {
182
- unexpectedNamedImportsOrder: 'Expected "{{second}}" to come before "{{first}}"'
278
+ unexpectedMapElementsOrder: 'Expected "{{second}}" to come before "{{first}}"'
279
+ }
280
+ },
281
+ defaultOptions: [
282
+ {
283
+ type: n.natural,
284
+ order: d.asc
285
+ }
286
+ ],
287
+ create: (r) => ({
288
+ NewExpression: (o) => {
289
+ if (o.callee.type === f.Identifier && o.callee.name === "Map" && o.arguments[0].type === f.ArrayExpression) {
290
+ let l = h(r.options.at(0), {
291
+ type: n.natural,
292
+ order: d.asc
293
+ }), [{ elements: p }] = o.arguments, s = r.getSourceCode().text;
294
+ p.length > 1 && p.reduce(
295
+ (t, a) => (a === null || a.type === f.SpreadElement ? t.push([]) : t.at(-1).push(a), t),
296
+ [[]]
297
+ ).forEach((t) => {
298
+ let a = t.map((i) => {
299
+ let c;
300
+ if (i.type === f.ArrayExpression) {
301
+ let [u] = i.elements;
302
+ u ? u.type === f.Literal ? c = u.raw : c = s.slice(...u.range) : c = `${u}`;
303
+ } else
304
+ c = s.slice(...i.range);
305
+ return {
306
+ size: E(i.range),
307
+ node: i,
308
+ name: c
309
+ };
310
+ });
311
+ for (let i = 1; i < a.length; i++) {
312
+ let c = a.at(i - 1), u = a.at(i);
313
+ m(c, u, l) && r.report({
314
+ messageId: "unexpectedMapElementsOrder",
315
+ data: {
316
+ first: c.name,
317
+ second: u.name
318
+ },
319
+ node: u.node,
320
+ fix: (g) => {
321
+ let b = r.getSourceCode(), { text: P } = b;
322
+ return x(g, P, a, l);
323
+ }
324
+ });
325
+ }
326
+ });
327
+ }
328
+ }
329
+ })
330
+ }), A = "sort-named-exports", J = y({
331
+ name: A,
332
+ meta: {
333
+ type: "suggestion",
334
+ docs: {
335
+ description: "Enforce sorted named exports",
336
+ recommended: !1
183
337
  },
184
338
  fixable: "code",
185
339
  schema: [
@@ -187,54 +341,133 @@ const E = "sort-interfaces", $ = O({
187
341
  type: "object",
188
342
  properties: {
189
343
  type: {
190
- enum: [d.natural, d["line-length"]]
344
+ enum: [n.natural, n["line-length"]],
345
+ default: n.natural
191
346
  },
192
347
  order: {
193
- enum: [c.asc, c.desc]
348
+ enum: [d.asc, d.desc],
349
+ default: d.asc
194
350
  }
195
351
  },
196
352
  additionalProperties: !1
197
353
  }
198
- ]
354
+ ],
355
+ messages: {
356
+ unexpectedNamedExportsOrder: 'Expected "{{second}}" to come before "{{first}}"'
357
+ }
199
358
  },
200
359
  defaultOptions: [
201
360
  {
202
- type: d.natural,
203
- order: c.asc
361
+ type: n.natural,
362
+ order: d.asc
204
363
  }
205
364
  ],
206
- create: (t) => ({
207
- ImportDeclaration: (s) => {
208
- let a = N(t.options.at(0), {
209
- type: d.natural,
210
- order: c.asc
365
+ create: (r) => ({
366
+ ExportNamedDeclaration: (o) => {
367
+ let l = h(r.options.at(0), {
368
+ type: n.natural,
369
+ order: d.asc
211
370
  });
212
- if (s.specifiers.length > 1) {
213
- let l = s.specifiers.map((e) => {
371
+ if (o.specifiers.length > 1) {
372
+ let p = o.specifiers.map((s) => {
214
373
  let {
215
- range: n,
216
- local: { name: r }
217
- } = e;
374
+ range: e,
375
+ local: { name: t }
376
+ } = s;
218
377
  return {
219
- size: h(n),
220
- node: e,
221
- name: r
378
+ size: E(e),
379
+ node: s,
380
+ name: t
381
+ };
382
+ });
383
+ for (let s = 1; s < p.length; s++) {
384
+ let e = p.at(s - 1), t = p.at(s);
385
+ if (m(e, t, l)) {
386
+ let a = o.specifiers[s];
387
+ r.report({
388
+ messageId: "unexpectedNamedExportsOrder",
389
+ data: {
390
+ first: e.name,
391
+ second: t.name
392
+ },
393
+ node: a,
394
+ fix: (i) => {
395
+ let c = r.getSourceCode(), { text: u } = c;
396
+ return x(i, u, p, l);
397
+ }
398
+ });
399
+ }
400
+ }
401
+ }
402
+ }
403
+ })
404
+ }), L = "sort-named-imports", X = y({
405
+ name: L,
406
+ meta: {
407
+ type: "suggestion",
408
+ docs: {
409
+ description: "Enforce sorted named imports",
410
+ recommended: !1
411
+ },
412
+ fixable: "code",
413
+ schema: [
414
+ {
415
+ type: "object",
416
+ properties: {
417
+ type: {
418
+ enum: [n.natural, n["line-length"]],
419
+ default: n.natural
420
+ },
421
+ order: {
422
+ enum: [d.asc, d.desc],
423
+ default: d.asc
424
+ }
425
+ },
426
+ additionalProperties: !1
427
+ }
428
+ ],
429
+ messages: {
430
+ unexpectedNamedImportsOrder: 'Expected "{{second}}" to come before "{{first}}"'
431
+ }
432
+ },
433
+ defaultOptions: [
434
+ {
435
+ type: n.natural,
436
+ order: d.asc
437
+ }
438
+ ],
439
+ create: (r) => ({
440
+ ImportDeclaration: (o) => {
441
+ let l = h(r.options.at(0), {
442
+ type: n.natural,
443
+ order: d.asc
444
+ });
445
+ if (o.specifiers.length > 1) {
446
+ let p = o.specifiers.map((s) => {
447
+ let {
448
+ range: e,
449
+ local: { name: t }
450
+ } = s;
451
+ return {
452
+ size: E(e),
453
+ node: s,
454
+ name: t
222
455
  };
223
456
  });
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({
457
+ for (let s = 1; s < p.length; s++) {
458
+ let e = p.at(s - 1), t = p.at(s);
459
+ if (m(e, t, l)) {
460
+ let a = o.specifiers[s];
461
+ r.report({
229
462
  messageId: "unexpectedNamedImportsOrder",
230
463
  data: {
231
- first: o.name,
232
- second: p.name
464
+ first: e.name,
465
+ second: t.name
233
466
  },
234
- node: g,
235
- fix: (m) => {
236
- let x = t.getSourceCode(), { text: f } = x;
237
- return b(m, f, l, a);
467
+ node: a,
468
+ fix: (i) => {
469
+ let c = r.getSourceCode(), { text: u } = c;
470
+ return x(i, u, p, l);
238
471
  }
239
472
  });
240
473
  }
@@ -242,32 +475,114 @@ const E = "sort-interfaces", $ = O({
242
475
  }
243
476
  }
244
477
  })
478
+ }), j = "sort-union-types", k = y({
479
+ name: j,
480
+ meta: {
481
+ type: "suggestion",
482
+ docs: {
483
+ description: "Enforce sorted union types",
484
+ recommended: !1
485
+ },
486
+ fixable: "code",
487
+ schema: [
488
+ {
489
+ type: "object",
490
+ properties: {
491
+ type: {
492
+ enum: [n.natural, n["line-length"]],
493
+ default: n.natural
494
+ },
495
+ order: {
496
+ enum: [d.asc, d.desc],
497
+ default: d.asc
498
+ }
499
+ },
500
+ additionalProperties: !1
501
+ }
502
+ ],
503
+ messages: {
504
+ unexpectedUnionTypesOrder: 'Expected "{{second}}" to come before "{{first}}"'
505
+ }
506
+ },
507
+ defaultOptions: [
508
+ {
509
+ type: n.natural,
510
+ order: d.asc
511
+ }
512
+ ],
513
+ create: (r) => ({
514
+ TSUnionType: (o) => {
515
+ let l = r.getSourceCode().text, p = h(r.options.at(0), {
516
+ type: n.natural,
517
+ order: d.asc
518
+ }), s = o.types.map((e) => {
519
+ let { range: t } = e, a = l.slice(...t);
520
+ return {
521
+ size: E(t),
522
+ node: e,
523
+ name: a
524
+ };
525
+ });
526
+ for (let e = 1; e < s.length; e++) {
527
+ let t = s.at(e - 1), a = s.at(e);
528
+ if (m(t, a, p)) {
529
+ let i = o.types[e];
530
+ r.report({
531
+ messageId: "unexpectedUnionTypesOrder",
532
+ data: {
533
+ first: t.name,
534
+ second: a.name
535
+ },
536
+ node: i,
537
+ fix: (c) => {
538
+ let u = r.getSourceCode(), { text: g } = u;
539
+ return x(c, g, s, p);
540
+ }
541
+ });
542
+ }
543
+ }
544
+ }
545
+ })
245
546
  });
246
- let j = (t) => {
247
- let s = {
248
- [E]: ["error"],
249
- [R]: ["error"],
250
- [P]: ["error"]
547
+ let C = (r) => {
548
+ let o = {
549
+ [N]: ["error", { spreadLast: !0 }],
550
+ [S]: ["error"],
551
+ [O]: ["error"],
552
+ [I]: ["error"],
553
+ [A]: ["error"],
554
+ [L]: ["error"],
555
+ [j]: ["error"]
251
556
  };
252
557
  return Object.fromEntries(
253
- Object.entries(s).map(([a, [l, e]]) => [
254
- a,
255
- [l, Object.assign(e, t)]
558
+ Object.entries(o).map(([l, [p, s = {}]]) => [
559
+ l,
560
+ [p, Object.assign(s, r)]
256
561
  ])
257
562
  );
258
563
  };
259
- const D = {
260
- name: z,
564
+ const V = {
565
+ name: T,
261
566
  rules: {
262
- [E]: $,
263
- [R]: v,
264
- [P]: X
567
+ [N]: $,
568
+ [S]: v,
569
+ [O]: z,
570
+ [I]: _,
571
+ [A]: J,
572
+ [L]: X,
573
+ [j]: k
265
574
  },
266
575
  configs: {
267
- "recommended-natural": j({ type: "natural", order: "asc" }),
268
- "recommended-line-length": j({ type: "line-length", order: "desc" })
576
+ "recommended-natural": C({
577
+ type: n.natural,
578
+ order: d.asc
579
+ }),
580
+ "recommended-line-length": C({
581
+ type: n["line-length"],
582
+ order: d.desc
583
+ })
269
584
  }
270
585
  };
271
586
  export {
272
- D as default
587
+ V as default
273
588
  };
package/license ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2023 Azat S. <to@azat.io>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-perfectionist",
3
3
  "description": "ESLint plugin for code formatting in perfectionist style",
4
- "version": "0.3.0",
4
+ "version": "0.5.0",
5
5
  "homepage": "https://eslint-plugin-perfectionist.azat.io",
6
6
  "repository": "azat-io/eslint-plugin-perfectionist",
7
7
  "author": "Azat S. <to@azat.io>",
package/readme.md CHANGED
@@ -22,12 +22,15 @@ npm install --save-dev eslint-plugin-perfectionist
22
22
 
23
23
  ## Rules
24
24
 
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 | ✅ | 🔧 |
25
+ | Name | Description | 💼 | 🛠 |
26
+ | :------------------------------------------------------------------------------------------- | :------------------------------------------ | :-- | :-- |
27
+ | [sort-array-includes](https://eslint-plugin-perfectionist.azat.io/rules/sort-array-includes) | Enforce sorted arrays before include method | ✅ | 🔧 |
28
+ | [sort-interfaces](https://eslint-plugin-perfectionist.azat.io/rules/sort-interfaces) | Enforce sorted interface properties | ✅ | 🔧 |
29
+ | [sort-jsx-props](https://eslint-plugin-perfectionist.azat.io/rules/sort-jsx-props) | Enforce sorted JSX props | ✅ | 🔧 |
30
+ | [sort-map-elements](https://eslint-plugin-perfectionist.azat.io/rules/sort-map-elements) | Enforce sorted Map elements | ✅ | 🔧 |
31
+ | [sort-named-exports](https://eslint-plugin-perfectionist.azat.io/rules/sort-named-exports) | Enforce sorted named exports | ✅ | 🔧 |
32
+ | [sort-named-imports](https://eslint-plugin-perfectionist.azat.io/rules/sort-named-imports) | Enforce sorted named imports | ✅ | 🔧 |
33
+ | [sort-union-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-union-types) | Enforce sorted union types | ✅ | 🔧 |
31
34
 
32
35
  ## See also
33
36