@arcgis/eslint-config 4.32.0-next.73 → 4.32.0-next.75
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/{chunk-ANTZSLIJ.js → chunk-2NFXJSOF.js} +508 -78
- package/dist/{chunk-2QEPVXNZ.js → chunk-7G6OXZK7.js} +4 -2
- package/dist/{chunk-ZEQDQQHF.js → chunk-LVYAWX7T.js} +5 -3
- package/dist/config/index.js +2 -2
- package/dist/config/lumina.js +2 -2
- package/dist/plugins/lumina/index.js +2 -2
- package/dist/plugins/lumina/rules/add-missing-jsx-import.d.ts +1 -3
- package/dist/plugins/lumina/rules/auto-add-type.d.ts +1 -3
- package/dist/plugins/lumina/rules/component-placement-rules.d.ts +1 -3
- package/dist/plugins/lumina/rules/consistent-event-naming.d.ts +1 -3
- package/dist/plugins/lumina/rules/decorators-context.d.ts +1 -3
- package/dist/plugins/lumina/rules/member-ordering/build.d.ts +4 -0
- package/dist/plugins/lumina/rules/member-ordering/comments.d.ts +19 -0
- package/dist/plugins/lumina/rules/member-ordering/config.d.ts +36 -0
- package/dist/plugins/lumina/rules/member-ordering/normalize.d.ts +10 -0
- package/dist/plugins/lumina/rules/member-ordering.d.ts +1 -0
- package/dist/plugins/lumina/rules/member-ordering.test.d.ts +1 -0
- package/dist/plugins/lumina/rules/no-ignore-jsdoc-tag.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-incorrect-dynamic-tag-name.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-inline-arrow-in-ref.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-invalid-directives-prop.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-jsx-spread.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-listen-in-connected-callback.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-non-component-exports.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-property-name-start-with-on.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-render-false.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-unnecessary-attribute-name.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-unnecessary-bind-this.d.ts +1 -3
- package/dist/plugins/lumina/rules/no-unnecessary-key.d.ts +1 -3
- package/dist/plugins/lumina/rules/tag-name-rules.d.ts +1 -3
- package/dist/plugins/lumina/utils/creator.d.ts +1 -4
- package/dist/plugins/utils/makePlugin.d.ts +6 -2
- package/dist/plugins/webgis/index.js +2 -2
- package/dist/plugins/webgis/rules/no-import-outside-src.d.ts +1 -3
- package/dist/plugins/webgis/rules/no-touching-jsdoc.d.ts +1 -3
- package/dist/plugins/webgis/utils/creator.d.ts +1 -4
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeEslintPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7G6OXZK7.js";
|
|
4
4
|
|
|
5
5
|
// src/plugins/lumina/rules/add-missing-jsx-import.ts
|
|
6
6
|
import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/utils";
|
|
@@ -100,7 +100,8 @@ var addMissingJsxImport = createRule({
|
|
|
100
100
|
name: "add-missing-jsx-import",
|
|
101
101
|
meta: {
|
|
102
102
|
docs: {
|
|
103
|
-
description
|
|
103
|
+
description,
|
|
104
|
+
defaultLevel: "error"
|
|
104
105
|
},
|
|
105
106
|
messages: {
|
|
106
107
|
addMissingJsxImport: description
|
|
@@ -165,7 +166,8 @@ var autoAddType = createRule({
|
|
|
165
166
|
name: "auto-add-type",
|
|
166
167
|
meta: {
|
|
167
168
|
docs: {
|
|
168
|
-
description: description2
|
|
169
|
+
description: description2,
|
|
170
|
+
defaultLevel: "warn"
|
|
169
171
|
},
|
|
170
172
|
messages: {
|
|
171
173
|
addType: `This property is of {{ type }} type, yet the type is not trivially inferrable from the AST without type-checking. Such properties require a { type: {{ type }} } annotation.
|
|
@@ -368,7 +370,8 @@ var componentPlacementRules = createRule({
|
|
|
368
370
|
name: "component-placement-rules",
|
|
369
371
|
meta: {
|
|
370
372
|
docs: {
|
|
371
|
-
description: description3
|
|
373
|
+
description: description3,
|
|
374
|
+
defaultLevel: "error"
|
|
372
375
|
},
|
|
373
376
|
messages: {
|
|
374
377
|
fileFolderNameMismatch: "Lumina component must be declared in a file whose name (without extension) matches the parent folder name.\n\nCreating components in nested folders is supported as long as the file name matches the immediate parent folder name.",
|
|
@@ -421,7 +424,8 @@ var consistentEventNaming = createRule({
|
|
|
421
424
|
name: "consistent-event-naming",
|
|
422
425
|
meta: {
|
|
423
426
|
docs: {
|
|
424
|
-
description: description4
|
|
427
|
+
description: description4,
|
|
428
|
+
defaultLevel: "warn"
|
|
425
429
|
},
|
|
426
430
|
messages: {
|
|
427
431
|
eventNamespaceError: `Custom event name must start with one of the following prefixes: {{ prefixes }}.
|
|
@@ -528,7 +532,8 @@ var decoratorsContext = createRule({
|
|
|
528
532
|
name: "decorators-context",
|
|
529
533
|
meta: {
|
|
530
534
|
docs: {
|
|
531
|
-
description: description5
|
|
535
|
+
description: description5,
|
|
536
|
+
defaultLevel: "error"
|
|
532
537
|
},
|
|
533
538
|
messages: {
|
|
534
539
|
publicApiMustBePublic: `@property(), @method() and createEvent() members must not have private or protected modifier.
|
|
@@ -594,13 +599,425 @@ If you wish to hide this member from public documentation, use @private or @prot
|
|
|
594
599
|
}
|
|
595
600
|
});
|
|
596
601
|
|
|
602
|
+
// src/plugins/lumina/rules/member-ordering.ts
|
|
603
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES7 } from "@typescript-eslint/utils";
|
|
604
|
+
|
|
605
|
+
// src/plugins/lumina/rules/member-ordering/config.ts
|
|
606
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES5 } from "@typescript-eslint/utils";
|
|
607
|
+
var ordering = [
|
|
608
|
+
/*
|
|
609
|
+
* Putting static before instance members is a common OOP convention.
|
|
610
|
+
* Static members are always evaluated before instance members.
|
|
611
|
+
*/
|
|
612
|
+
"Static Members",
|
|
613
|
+
/**
|
|
614
|
+
* Put private properties before public, because private properties are
|
|
615
|
+
* often used as a default value for public properties.
|
|
616
|
+
*/
|
|
617
|
+
"Private Properties",
|
|
618
|
+
/**
|
|
619
|
+
* Put private properties before public, because private properties are often
|
|
620
|
+
* used as a default value for public properties.
|
|
621
|
+
*/
|
|
622
|
+
"State Properties",
|
|
623
|
+
/*
|
|
624
|
+
* Properties are the key component API. Also, since default values of
|
|
625
|
+
* properties evaluate before the constructor, they should logically be before
|
|
626
|
+
* the constructor.
|
|
627
|
+
*/
|
|
628
|
+
"Public Properties",
|
|
629
|
+
/*
|
|
630
|
+
* Methods should be a supplementary component API, not primary, so are listed
|
|
631
|
+
* after properties. At the same time, it is nice to keep public component API
|
|
632
|
+
* all in one place.
|
|
633
|
+
*/
|
|
634
|
+
"Public Methods",
|
|
635
|
+
/*
|
|
636
|
+
* Put events near properties and methods to keep all public component API in
|
|
637
|
+
* one place.
|
|
638
|
+
*/
|
|
639
|
+
"Events",
|
|
640
|
+
/*
|
|
641
|
+
* Lifecycle methods like constructor and connectedCallback are executed
|
|
642
|
+
* after all properties have default values, but before any render functions.
|
|
643
|
+
*/
|
|
644
|
+
"Lifecycle",
|
|
645
|
+
/*
|
|
646
|
+
* Private methods in between lifecycles and rendering as they are often
|
|
647
|
+
* called by either of them.
|
|
648
|
+
*/
|
|
649
|
+
"Private Methods",
|
|
650
|
+
/*
|
|
651
|
+
* Fred:
|
|
652
|
+
* The reason rendering methods are at the bottom of my modules because I can
|
|
653
|
+
* quickly jump to the bottom find the rendering method and work on it. Less
|
|
654
|
+
* scrolling.
|
|
655
|
+
* Once a module has been implemented, most of the bugs/enhancements occur in
|
|
656
|
+
* the rendering methods.
|
|
657
|
+
*/
|
|
658
|
+
"Rendering"
|
|
659
|
+
];
|
|
660
|
+
var getWireframe = () => new Map(ordering.map((region) => [region, []]));
|
|
661
|
+
var entries = Object.entries;
|
|
662
|
+
var regionMatchers = entries({
|
|
663
|
+
"Static Members": (node) => node.type === AST_NODE_TYPES5.StaticBlock || "static" in node && node.static,
|
|
664
|
+
"Lifecycle": (_node, name) => lifecyclesSet.has(name),
|
|
665
|
+
"Public Methods": (node) => "decorators" in node && hasDecorator(node, "method"),
|
|
666
|
+
"Public Properties": (node) => "decorators" in node && hasDecorator(node, "property"),
|
|
667
|
+
"State Properties": (node) => "decorators" in node && hasDecorator(node, "state"),
|
|
668
|
+
"Events": isEvent,
|
|
669
|
+
"Rendering": (_node, name) => name.startsWith("render") || name.startsWith("_render"),
|
|
670
|
+
"Private Properties": (node) => (
|
|
671
|
+
// We don't yet support public accessor properties
|
|
672
|
+
node.type === AST_NODE_TYPES5.PropertyDefinition || node.type === AST_NODE_TYPES5.AccessorProperty
|
|
673
|
+
),
|
|
674
|
+
"Private Methods": () => true
|
|
675
|
+
});
|
|
676
|
+
var definitelyComponentRegions = /* @__PURE__ */ new Set([
|
|
677
|
+
"Rendering",
|
|
678
|
+
"State Properties",
|
|
679
|
+
"Public Methods",
|
|
680
|
+
"Events"
|
|
681
|
+
]);
|
|
682
|
+
var regionsArray = regionMatchers.map(([key]) => key);
|
|
683
|
+
function isEvent(node, name) {
|
|
684
|
+
if (node.type !== AST_NODE_TYPES5.PropertyDefinition) {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
if (name === "arcgisPropertyChange") {
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
const initializer = node.value;
|
|
691
|
+
if (initializer?.type !== AST_NODE_TYPES5.CallExpression) {
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
const callExpression = initializer.callee;
|
|
695
|
+
const functionName = callExpression.type === AST_NODE_TYPES5.Identifier ? callExpression.name : callExpression.type === AST_NODE_TYPES5.CallExpression && callExpression.callee.type === AST_NODE_TYPES5.Identifier ? callExpression.callee.name : void 0;
|
|
696
|
+
return functionName === "createEvent" || functionName === "reEmitEvent" || functionName === "usePropertyChange";
|
|
697
|
+
}
|
|
698
|
+
var lifecycles = [
|
|
699
|
+
"constructor",
|
|
700
|
+
"connectedCallback",
|
|
701
|
+
"load",
|
|
702
|
+
"shouldUpdate",
|
|
703
|
+
// Not an actual lifecycle method, but can be temporary inserted by the codemod
|
|
704
|
+
"_shouldUpdate",
|
|
705
|
+
"willUpdate",
|
|
706
|
+
"update",
|
|
707
|
+
"firstUpdated",
|
|
708
|
+
"updated",
|
|
709
|
+
"loaded",
|
|
710
|
+
"disconnectedCallback"
|
|
711
|
+
];
|
|
712
|
+
var lifecyclesSet = new Set(lifecycles);
|
|
713
|
+
var supportedNodeTypes = {
|
|
714
|
+
MethodDefinition: true,
|
|
715
|
+
PropertyDefinition: true,
|
|
716
|
+
AccessorProperty: true,
|
|
717
|
+
StaticBlock: true,
|
|
718
|
+
// These should not be present in non-abstract Lumina component classes
|
|
719
|
+
TSAbstractAccessorProperty: false,
|
|
720
|
+
TSAbstractMethodDefinition: false,
|
|
721
|
+
TSAbstractPropertyDefinition: false,
|
|
722
|
+
TSIndexSignature: false
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/plugins/lumina/rules/member-ordering/comments.ts
|
|
726
|
+
import { AST_TOKEN_TYPES } from "@typescript-eslint/utils";
|
|
727
|
+
function categorizeComments(membersData, sourceCode) {
|
|
728
|
+
const categorized = {
|
|
729
|
+
header: [],
|
|
730
|
+
regionFooter: /* @__PURE__ */ new Map(),
|
|
731
|
+
memberLineEnd: /* @__PURE__ */ new Map(),
|
|
732
|
+
footer: [],
|
|
733
|
+
membersByName: /* @__PURE__ */ new Map()
|
|
734
|
+
};
|
|
735
|
+
let regionName;
|
|
736
|
+
membersData.forEach((memberData, index) => {
|
|
737
|
+
const nameNodes = categorized.membersByName.get(memberData.name);
|
|
738
|
+
if (nameNodes !== void 0) {
|
|
739
|
+
nameNodes.push(memberData);
|
|
740
|
+
} else {
|
|
741
|
+
categorized.membersByName.set(memberData.name, [memberData]);
|
|
742
|
+
}
|
|
743
|
+
memberData.comments = handleLineEndComment(memberData.comments, membersData.at(index - 1), categorized);
|
|
744
|
+
let newRegionName;
|
|
745
|
+
const lastRegionStart = memberData.comments.findLastIndex((comment) => {
|
|
746
|
+
const match = parseRegionComment(comment);
|
|
747
|
+
const isRegionStart = match !== void 0 && match.end === void 0;
|
|
748
|
+
newRegionName = match?.name;
|
|
749
|
+
return isRegionStart;
|
|
750
|
+
});
|
|
751
|
+
if (lastRegionStart !== -1) {
|
|
752
|
+
const commentsBeforeNewRegionStart = memberData.comments.slice(0, lastRegionStart);
|
|
753
|
+
const previousMember = membersData.at(index - 1);
|
|
754
|
+
handleCommentsAroundEndRegion(
|
|
755
|
+
commentsBeforeNewRegionStart,
|
|
756
|
+
false,
|
|
757
|
+
previousMember ?? memberData,
|
|
758
|
+
categorized,
|
|
759
|
+
regionName
|
|
760
|
+
);
|
|
761
|
+
memberData.comments = memberData.comments.slice(lastRegionStart + 1);
|
|
762
|
+
regionName = newRegionName;
|
|
763
|
+
}
|
|
764
|
+
const isLastNode = index === membersData.length - 1;
|
|
765
|
+
if (isLastNode) {
|
|
766
|
+
const trailingComments = sourceCode.getCommentsAfter(memberData.member);
|
|
767
|
+
const remainingTrailingComments = handleLineEndComment(trailingComments, memberData, categorized);
|
|
768
|
+
const previousMember = membersData.at(index - 1);
|
|
769
|
+
handleCommentsAroundEndRegion(
|
|
770
|
+
remainingTrailingComments,
|
|
771
|
+
true,
|
|
772
|
+
previousMember ?? memberData,
|
|
773
|
+
categorized,
|
|
774
|
+
regionName
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
return categorized;
|
|
779
|
+
}
|
|
780
|
+
function handleLineEndComment(comments, previousNode, categorized) {
|
|
781
|
+
if (comments.at(0)?.loc.start.line === previousNode?.member.loc.end.line) {
|
|
782
|
+
categorized.memberLineEnd.set(previousNode, comments.slice(0, 1));
|
|
783
|
+
return comments.slice(1);
|
|
784
|
+
}
|
|
785
|
+
return comments;
|
|
786
|
+
}
|
|
787
|
+
function handleCommentsAroundEndRegion(commentsBeforeNewRegionStart, isFooter, lastMember, categorized, regionName) {
|
|
788
|
+
if (regionName === void 0) {
|
|
789
|
+
const destination = isFooter ? categorized.footer : categorized.header;
|
|
790
|
+
destination.push(...commentsBeforeNewRegionStart);
|
|
791
|
+
} else {
|
|
792
|
+
const firstEndRegion = commentsBeforeNewRegionStart.findIndex(
|
|
793
|
+
(comment) => parseRegionComment(comment)?.end !== void 0
|
|
794
|
+
);
|
|
795
|
+
let previousRegionComments = commentsBeforeNewRegionStart;
|
|
796
|
+
if (firstEndRegion !== -1) {
|
|
797
|
+
categorized.footer.push(...commentsBeforeNewRegionStart.slice(firstEndRegion + 1));
|
|
798
|
+
previousRegionComments = commentsBeforeNewRegionStart.slice(0, firstEndRegion);
|
|
799
|
+
}
|
|
800
|
+
const existingFooter = categorized.regionFooter.get(regionName);
|
|
801
|
+
if (existingFooter === void 0) {
|
|
802
|
+
categorized.regionFooter.set(regionName, { comments: Array.from(previousRegionComments), lastMember });
|
|
803
|
+
} else {
|
|
804
|
+
existingFooter.comments.push(...previousRegionComments);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
var normalizeComments = (comments = [], sourceCode, indent = " ") => comments.filter((comment) => parseRegionComment(comment) === void 0).map((comment) => `${indent}${sourceCode.getText(comment)}`).join("\n").replaceAll(reJsApiSectionComment, "");
|
|
809
|
+
var join = (left, right, joiner = "\n\n") => left === "" || right === "" ? right || left : `${left}${joiner}${right}`;
|
|
810
|
+
var reRegionComment = /^ ?#(?<end>end)?region ?(?<name>[^\n]*)$/u;
|
|
811
|
+
var parseRegionComment = (comment) => comment.type === AST_TOKEN_TYPES.Line ? reRegionComment.exec(comment.value)?.groups : void 0;
|
|
812
|
+
var reJsApiSectionComment = /^ \/\/ ?-{4,}\n(?: \/\/\s*\n)? \/\/\s+[^\s][^\n]+\n(?: \/\/\s*\n)? \/\/ ?-{4,}/gmu;
|
|
813
|
+
|
|
814
|
+
// src/plugins/lumina/rules/member-ordering/normalize.ts
|
|
815
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES6 } from "@typescript-eslint/utils";
|
|
816
|
+
function getNormalizedRegions(membersByName) {
|
|
817
|
+
const regions = getWireframe();
|
|
818
|
+
membersByName.values().forEach((members) => {
|
|
819
|
+
const lowestRegionIndex = members.reduce(
|
|
820
|
+
(min, { region }) => Math.min(min, regionsArray.indexOf(region)),
|
|
821
|
+
Number.POSITIVE_INFINITY
|
|
822
|
+
);
|
|
823
|
+
if (members.length === 2 && members[0].member.type === AST_NODE_TYPES6.MethodDefinition && members[0].member.kind === "set") {
|
|
824
|
+
members.reverse();
|
|
825
|
+
}
|
|
826
|
+
const regionName = regionsArray[lowestRegionIndex];
|
|
827
|
+
regions.get(regionName).push(...members);
|
|
828
|
+
});
|
|
829
|
+
const normalizedRegions = Array.from(regions).filter(([_region, members]) => members.length > 0).map(
|
|
830
|
+
([region, members]) => [region, sortableRegions.has(region) ? members.sort(sortFunction.bind(void 0, region)) : members]
|
|
831
|
+
);
|
|
832
|
+
return normalizedRegions;
|
|
833
|
+
}
|
|
834
|
+
var sortableRegions = /* @__PURE__ */ new Set(["Public Methods", "Events", "Lifecycle"]);
|
|
835
|
+
function sortFunction(region, leftMember, rightMember) {
|
|
836
|
+
let leftName = leftMember.name;
|
|
837
|
+
let rightName = rightMember.name;
|
|
838
|
+
if (region === "Lifecycle") {
|
|
839
|
+
const compare = lifecycles.indexOf(leftName) - lifecycles.indexOf(rightName);
|
|
840
|
+
return compare < 0 ? -1 : 1;
|
|
841
|
+
}
|
|
842
|
+
if (leftName.startsWith("_")) {
|
|
843
|
+
leftName = leftName.slice(1);
|
|
844
|
+
}
|
|
845
|
+
if (rightName.startsWith("_")) {
|
|
846
|
+
rightName = rightName.slice(1);
|
|
847
|
+
}
|
|
848
|
+
if (leftName < rightName) {
|
|
849
|
+
return -1;
|
|
850
|
+
} else if (leftName > rightName) {
|
|
851
|
+
return 1;
|
|
852
|
+
} else {
|
|
853
|
+
return 0;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function reParentOrphanFooterComments(normalizedRegions, regionFooter) {
|
|
857
|
+
const finalRegions = new Set(normalizedRegions.map(([region]) => region));
|
|
858
|
+
regionFooter.forEach(({ comments, lastMember }, originalRegionName) => {
|
|
859
|
+
const regionStillExists = finalRegions.has(originalRegionName);
|
|
860
|
+
if (regionStillExists) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const newFooterCommentsParent = lastMember.region;
|
|
864
|
+
const existingParentFooter = regionFooter.get(newFooterCommentsParent);
|
|
865
|
+
if (existingParentFooter === void 0) {
|
|
866
|
+
regionFooter.set(newFooterCommentsParent, { comments, lastMember });
|
|
867
|
+
} else {
|
|
868
|
+
existingParentFooter.comments.push(...comments);
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// src/plugins/lumina/rules/member-ordering/build.ts
|
|
874
|
+
function buildNewBody(normalizedRegions, strayComments, sourceCode) {
|
|
875
|
+
const newRegions = normalizedRegions.map(([region, members]) => {
|
|
876
|
+
const memberLines = members.map((memberData, index) => {
|
|
877
|
+
const { member, comments, name } = memberData;
|
|
878
|
+
const commentsString = normalizeComments(comments, sourceCode);
|
|
879
|
+
const code = sourceCode.getText(member);
|
|
880
|
+
const lineEndComment = normalizeComments(strayComments.memberLineEnd.get(memberData), sourceCode, " ");
|
|
881
|
+
const memberString = ` ${code}${lineEndComment}`;
|
|
882
|
+
const fullMemberString = join(commentsString, memberString, "\n");
|
|
883
|
+
const nextMember = members.at(index + 1);
|
|
884
|
+
const isLast = nextMember === void 0;
|
|
885
|
+
const isNextSameName = name.length > 0 && name === nextMember?.name;
|
|
886
|
+
const separator = isLast ? "" : isNextSameName ? "\n" : "\n\n";
|
|
887
|
+
return `${fullMemberString}${separator}`;
|
|
888
|
+
});
|
|
889
|
+
const footerComments = normalizeComments(strayComments.regionFooter.get(region)?.comments, sourceCode);
|
|
890
|
+
const footer2 = join(footerComments, " //#endregion", "\n\n");
|
|
891
|
+
return [` //#region ${region}`, memberLines.join(""), footer2].join("\n\n");
|
|
892
|
+
});
|
|
893
|
+
const header = normalizeComments(strayComments.header, sourceCode);
|
|
894
|
+
const footer = normalizeComments(strayComments.footer, sourceCode);
|
|
895
|
+
const newBodyContent = join(join(header, newRegions.join("\n\n")), footer);
|
|
896
|
+
const newBody = `{
|
|
897
|
+
${newBodyContent}
|
|
898
|
+
}`;
|
|
899
|
+
return newBody;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/plugins/lumina/rules/member-ordering.ts
|
|
903
|
+
var baseDescription = `Consistently sort component members`;
|
|
904
|
+
var memberOrdering = createRule({
|
|
905
|
+
name: "member-ordering",
|
|
906
|
+
meta: {
|
|
907
|
+
docs: {
|
|
908
|
+
description: baseDescription,
|
|
909
|
+
defaultLevel: "warn"
|
|
910
|
+
},
|
|
911
|
+
messages: {
|
|
912
|
+
memberOrdering: "Component member ordering is not consistent. Run ESLint autofix to sort members.",
|
|
913
|
+
unsupportedElementType: "Unsupported class element type: {{ type }}"
|
|
914
|
+
},
|
|
915
|
+
type: "layout",
|
|
916
|
+
schema: [],
|
|
917
|
+
fixable: "whitespace"
|
|
918
|
+
},
|
|
919
|
+
defaultOptions: [],
|
|
920
|
+
create: (context) => ({
|
|
921
|
+
ClassDeclaration(component) {
|
|
922
|
+
const isNamedExport = component.parent?.type === AST_NODE_TYPES7.ExportNamedDeclaration;
|
|
923
|
+
if (!isNamedExport || component.abstract) {
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
const hasExtends = component.superClass !== null;
|
|
927
|
+
if (!hasExtends) {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
const sourceCode = context.sourceCode;
|
|
931
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
932
|
+
let currentRegion = "";
|
|
933
|
+
let hasWrongOrdering = false;
|
|
934
|
+
let isDefinitelyComponent = false;
|
|
935
|
+
let hadError = false;
|
|
936
|
+
const membersData = component.body.body.map((member) => {
|
|
937
|
+
const isSupportedType = supportedNodeTypes[member.type];
|
|
938
|
+
if (!isSupportedType) {
|
|
939
|
+
hadError = true;
|
|
940
|
+
context.report({ node: member, messageId: "unsupportedElementType", data: { type: member.type } });
|
|
941
|
+
}
|
|
942
|
+
const name = "key" in member ? getName(member) ?? "" : "";
|
|
943
|
+
const newRegion = regionMatchers.find(([, rules]) => rules(member, name))[0];
|
|
944
|
+
const comments = sourceCode.getCommentsBefore(member);
|
|
945
|
+
if (!hasWrongOrdering) {
|
|
946
|
+
let wrongOrdering = false;
|
|
947
|
+
const previousRegion = currentRegion;
|
|
948
|
+
for (const comment of comments) {
|
|
949
|
+
const region = parseRegionComment(comment);
|
|
950
|
+
if (region === void 0 || region.end !== void 0) {
|
|
951
|
+
continue;
|
|
952
|
+
}
|
|
953
|
+
currentRegion = region.name;
|
|
954
|
+
wrongOrdering ||= currentRegion !== newRegion;
|
|
955
|
+
}
|
|
956
|
+
if (
|
|
957
|
+
/*
|
|
958
|
+
* The @property()/@method() decorator might be missing from this
|
|
959
|
+
* node in case of getter/setter or method overload, while still
|
|
960
|
+
* being in correct ordering.
|
|
961
|
+
* The logic in rule body is lightweight compared to more
|
|
962
|
+
* comprehensive in the autofix to keep common case fast, so we
|
|
963
|
+
* ignore possible errors in getter/setters (but those errors would
|
|
964
|
+
* still be fixed as long as there is any other error in the file).
|
|
965
|
+
*/
|
|
966
|
+
!seenNames.has(name) && (member.type !== AST_NODE_TYPES7.MethodDefinition || member.kind !== "get" && member.kind !== "set")
|
|
967
|
+
) {
|
|
968
|
+
wrongOrdering ||= currentRegion !== newRegion;
|
|
969
|
+
wrongOrdering ||= previousRegion !== currentRegion && ordering.indexOf(previousRegion) > ordering.indexOf(currentRegion);
|
|
970
|
+
hasWrongOrdering = wrongOrdering;
|
|
971
|
+
}
|
|
972
|
+
seenNames.add(name);
|
|
973
|
+
}
|
|
974
|
+
isDefinitelyComponent ||= definitelyComponentRegions.has(newRegion);
|
|
975
|
+
return { member, name, comments, region: newRegion };
|
|
976
|
+
});
|
|
977
|
+
if (!isDefinitelyComponent) {
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (hadError) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
if (!hasWrongOrdering) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
context.report({
|
|
987
|
+
/**
|
|
988
|
+
* Since this rule is autofixable and stylistic, to be less obtrusive,
|
|
989
|
+
* report the error for a single character only, rather than entire
|
|
990
|
+
* component
|
|
991
|
+
*/
|
|
992
|
+
loc: {
|
|
993
|
+
start: component.loc.end,
|
|
994
|
+
end: component.loc.end
|
|
995
|
+
},
|
|
996
|
+
messageId: "memberOrdering",
|
|
997
|
+
/*
|
|
998
|
+
* We delay as much work as possible till the autofixer is run because
|
|
999
|
+
* most of the time the rule will be run without need for autofixing.
|
|
1000
|
+
*/
|
|
1001
|
+
fix(fixer) {
|
|
1002
|
+
const { membersByName, ...strayComments } = categorizeComments(membersData, sourceCode);
|
|
1003
|
+
const normalizedRegions = getNormalizedRegions(membersByName);
|
|
1004
|
+
reParentOrphanFooterComments(normalizedRegions, strayComments.regionFooter);
|
|
1005
|
+
const newBody = buildNewBody(normalizedRegions, strayComments, sourceCode);
|
|
1006
|
+
return fixer.replaceText(component.body, newBody);
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
})
|
|
1011
|
+
});
|
|
1012
|
+
|
|
597
1013
|
// src/plugins/lumina/rules/no-ignore-jsdoc-tag.ts
|
|
598
1014
|
var description6 = `Use @internal or @private JSDoc tag over @ignore. See https://qawebgis.esri.com/components/lumina/documenting-components#excluding-api-from-public-documentation`;
|
|
599
1015
|
var noIgnoreJsDocTag = createRule({
|
|
600
1016
|
name: "no-ignore-jsdoc-tag",
|
|
601
1017
|
meta: {
|
|
602
1018
|
docs: {
|
|
603
|
-
description: description6
|
|
1019
|
+
description: description6,
|
|
1020
|
+
defaultLevel: "error"
|
|
604
1021
|
},
|
|
605
1022
|
messages: {
|
|
606
1023
|
noIgnoreJsDocTag: description6
|
|
@@ -633,14 +1050,15 @@ var noIgnoreJsDocTag = createRule({
|
|
|
633
1050
|
var reIgnore = /\* @ignore/gu;
|
|
634
1051
|
|
|
635
1052
|
// src/plugins/lumina/rules/no-incorrect-dynamic-tag-name.ts
|
|
636
|
-
import { AST_NODE_TYPES as
|
|
1053
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES8, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
|
|
637
1054
|
import ts2 from "typescript";
|
|
638
1055
|
var description7 = `Detect incorrect usage of dynamic JSX tag name`;
|
|
639
1056
|
var noIncorrectDynamicTagName = createRule({
|
|
640
1057
|
name: "no-incorrect-dynamic-tag-name",
|
|
641
1058
|
meta: {
|
|
642
1059
|
docs: {
|
|
643
|
-
description: description7
|
|
1060
|
+
description: description7,
|
|
1061
|
+
defaultLevel: "error"
|
|
644
1062
|
},
|
|
645
1063
|
messages: {
|
|
646
1064
|
incorrectDynamicTagName: `This is using incorrect dynamic tag name syntax. See documentation on how to use dynamic tag in Lumina's JSX: https://qawebgis.esri.com/components/lumina/jsx#dynamic-tag-name`
|
|
@@ -658,7 +1076,7 @@ var noIncorrectDynamicTagName = createRule({
|
|
|
658
1076
|
if (!luminaJsxCheck.isLuminaJsx) {
|
|
659
1077
|
return;
|
|
660
1078
|
}
|
|
661
|
-
const isInTagName = node.parent?.type !==
|
|
1079
|
+
const isInTagName = node.parent?.type !== AST_NODE_TYPES8.JSXAttribute;
|
|
662
1080
|
if (!isInTagName) {
|
|
663
1081
|
return;
|
|
664
1082
|
}
|
|
@@ -684,16 +1102,17 @@ var noIncorrectDynamicTagName = createRule({
|
|
|
684
1102
|
});
|
|
685
1103
|
|
|
686
1104
|
// src/plugins/lumina/rules/no-inline-arrow-in-ref.ts
|
|
687
|
-
import { AST_NODE_TYPES as
|
|
688
|
-
var
|
|
689
|
-
var description8 = `${
|
|
1105
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES9 } from "@typescript-eslint/utils";
|
|
1106
|
+
var baseDescription2 = `Do not pass an inline arrow function to a ref prop - such syntax creates a new function on each render, which makes Lit call ref callback again on each render.`;
|
|
1107
|
+
var description8 = `${baseDescription2}
|
|
690
1108
|
|
|
691
1109
|
Alternatives: https://qawebgis.esri.com/components/lumina/jsx#refs`;
|
|
692
1110
|
var noInlineArrowInRef = createRule({
|
|
693
1111
|
name: "no-inline-arrow-in-ref",
|
|
694
1112
|
meta: {
|
|
695
1113
|
docs: {
|
|
696
|
-
description:
|
|
1114
|
+
description: baseDescription2,
|
|
1115
|
+
defaultLevel: "error"
|
|
697
1116
|
},
|
|
698
1117
|
messages: {
|
|
699
1118
|
errorInlineArrow: description8
|
|
@@ -707,11 +1126,11 @@ var noInlineArrowInRef = createRule({
|
|
|
707
1126
|
return {
|
|
708
1127
|
ImportDeclaration: luminaJsxCheck,
|
|
709
1128
|
JSXAttribute(node) {
|
|
710
|
-
if (!luminaJsxCheck.isLuminaJsx || node.name.name !== "ref" || node.value?.type !==
|
|
1129
|
+
if (!luminaJsxCheck.isLuminaJsx || node.name.name !== "ref" || node.value?.type !== AST_NODE_TYPES9.JSXExpressionContainer) {
|
|
711
1130
|
return;
|
|
712
1131
|
}
|
|
713
1132
|
const initializer = node.value.expression;
|
|
714
|
-
if (initializer.type !==
|
|
1133
|
+
if (initializer.type !== AST_NODE_TYPES9.ArrowFunctionExpression && initializer.type !== AST_NODE_TYPES9.FunctionExpression) {
|
|
715
1134
|
return;
|
|
716
1135
|
}
|
|
717
1136
|
context.report({
|
|
@@ -724,13 +1143,14 @@ var noInlineArrowInRef = createRule({
|
|
|
724
1143
|
});
|
|
725
1144
|
|
|
726
1145
|
// src/plugins/lumina/rules/no-invalid-directives-prop.ts
|
|
727
|
-
import { AST_NODE_TYPES as
|
|
1146
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES10 } from "@typescript-eslint/utils";
|
|
728
1147
|
var description9 = `directives={} prop value must be an array literal. Documentation: https://qawebgis.esri.com/components/lumina/jsx#lit-directives`;
|
|
729
1148
|
var noInvalidDirectivesProp = createRule({
|
|
730
1149
|
name: "no-invalid-directives-prop",
|
|
731
1150
|
meta: {
|
|
732
1151
|
docs: {
|
|
733
|
-
description: description9
|
|
1152
|
+
description: description9,
|
|
1153
|
+
defaultLevel: "error"
|
|
734
1154
|
},
|
|
735
1155
|
messages: {
|
|
736
1156
|
noInvalidDirectivesProp: description9
|
|
@@ -750,7 +1170,7 @@ var noInvalidDirectivesProp = createRule({
|
|
|
750
1170
|
if (node.name.name !== "directives") {
|
|
751
1171
|
return;
|
|
752
1172
|
}
|
|
753
|
-
const array = node.value?.type ===
|
|
1173
|
+
const array = node.value?.type === AST_NODE_TYPES10.JSXExpressionContainer && node.value.expression.type === AST_NODE_TYPES10.ArrayExpression ? node.value.expression : void 0;
|
|
754
1174
|
if (array === void 0 || array.elements.includes(null)) {
|
|
755
1175
|
context.report({
|
|
756
1176
|
messageId: "noInvalidDirectivesProp",
|
|
@@ -759,7 +1179,7 @@ var noInvalidDirectivesProp = createRule({
|
|
|
759
1179
|
return;
|
|
760
1180
|
}
|
|
761
1181
|
array.elements.forEach((element) => {
|
|
762
|
-
if (element?.type ===
|
|
1182
|
+
if (element?.type === AST_NODE_TYPES10.SpreadElement) {
|
|
763
1183
|
context.report({
|
|
764
1184
|
messageId: "noInvalidDirectivesProp",
|
|
765
1185
|
node: element
|
|
@@ -772,13 +1192,14 @@ var noInvalidDirectivesProp = createRule({
|
|
|
772
1192
|
});
|
|
773
1193
|
|
|
774
1194
|
// src/plugins/lumina/rules/no-jsx-spread.ts
|
|
775
|
-
import { AST_NODE_TYPES as
|
|
1195
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES11 } from "@typescript-eslint/utils";
|
|
776
1196
|
var description10 = `This spread syntax is not supported. Alternatives: https://qawebgis.esri.com/components/lumina/jsx#spread-attributes`;
|
|
777
1197
|
var noJsxSpread = createRule({
|
|
778
1198
|
name: "no-jsx-spread",
|
|
779
1199
|
meta: {
|
|
780
1200
|
docs: {
|
|
781
|
-
description: description10
|
|
1201
|
+
description: description10,
|
|
1202
|
+
defaultLevel: "error"
|
|
782
1203
|
},
|
|
783
1204
|
messages: {
|
|
784
1205
|
noJsxSpread: description10
|
|
@@ -798,7 +1219,7 @@ var noJsxSpread = createRule({
|
|
|
798
1219
|
const name = node.parent.name;
|
|
799
1220
|
if (
|
|
800
1221
|
// Spread syntax is allowed in function calls like <this.render {...props} />
|
|
801
|
-
name.type ===
|
|
1222
|
+
name.type === AST_NODE_TYPES11.JSXIdentifier && // Spread syntax is allowed in functions
|
|
802
1223
|
(name.name.toLowerCase() === name.name || name.name === "DynamicHtmlTag" || name.name === "DynamicSvgTag")
|
|
803
1224
|
) {
|
|
804
1225
|
context.report({
|
|
@@ -812,9 +1233,9 @@ var noJsxSpread = createRule({
|
|
|
812
1233
|
});
|
|
813
1234
|
|
|
814
1235
|
// src/plugins/lumina/rules/no-listen-in-connected-callback.ts
|
|
815
|
-
import { AST_NODE_TYPES as
|
|
816
|
-
var
|
|
817
|
-
var description11 = `${
|
|
1236
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
1237
|
+
var baseDescription3 = `Do not call this.listen()/this.listenOn() in connectedCallback.`;
|
|
1238
|
+
var description11 = `${baseDescription3}
|
|
818
1239
|
|
|
819
1240
|
Instead, call this.listen()/this.listenOn() in constructor(), load() or loaded().
|
|
820
1241
|
|
|
@@ -825,7 +1246,8 @@ var noListenInConnectedCallback = createRule({
|
|
|
825
1246
|
name: "no-listen-in-connected-callback",
|
|
826
1247
|
meta: {
|
|
827
1248
|
docs: {
|
|
828
|
-
description:
|
|
1249
|
+
description: baseDescription3,
|
|
1250
|
+
defaultLevel: "error"
|
|
829
1251
|
},
|
|
830
1252
|
messages: {
|
|
831
1253
|
errorListenInConnectedCallback: description11
|
|
@@ -837,15 +1259,15 @@ var noListenInConnectedCallback = createRule({
|
|
|
837
1259
|
create(context) {
|
|
838
1260
|
return {
|
|
839
1261
|
CallExpression(node) {
|
|
840
|
-
const isListenCall = node.callee.type ===
|
|
1262
|
+
const isListenCall = node.callee.type === AST_NODE_TYPES12.MemberExpression && node.callee.object.type === AST_NODE_TYPES12.ThisExpression && node.callee.property.type === AST_NODE_TYPES12.Identifier && (node.callee.property.name === "listen" || node.callee.property.name === "listenOn");
|
|
841
1263
|
if (!isListenCall) {
|
|
842
1264
|
return;
|
|
843
1265
|
}
|
|
844
1266
|
let hasConnectedCallbackParent = false;
|
|
845
1267
|
let currentParent = node.parent;
|
|
846
1268
|
while (currentParent) {
|
|
847
|
-
if (currentParent.type ===
|
|
848
|
-
if (currentParent.key.type ===
|
|
1269
|
+
if (currentParent.type === AST_NODE_TYPES12.MethodDefinition) {
|
|
1270
|
+
if (currentParent.key.type === AST_NODE_TYPES12.Identifier && currentParent.key.name === "connectedCallback") {
|
|
849
1271
|
hasConnectedCallbackParent = true;
|
|
850
1272
|
}
|
|
851
1273
|
break;
|
|
@@ -865,13 +1287,14 @@ var noListenInConnectedCallback = createRule({
|
|
|
865
1287
|
});
|
|
866
1288
|
|
|
867
1289
|
// src/plugins/lumina/rules/no-non-component-exports.ts
|
|
868
|
-
import { AST_NODE_TYPES as
|
|
1290
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
869
1291
|
var description12 = `To ensure Hot Module Replacement (HMR) works correctly, the file that defines the Lumina component must not export anything other than the component. Exceptions: type-only exports, and the \`exportsForTests\` object for exposing additional things for usages in tests only`;
|
|
870
1292
|
var noNonComponentExports = createRule({
|
|
871
1293
|
name: "no-non-component-exports",
|
|
872
1294
|
meta: {
|
|
873
1295
|
docs: {
|
|
874
|
-
description: description12
|
|
1296
|
+
description: description12,
|
|
1297
|
+
defaultLevel: "warn"
|
|
875
1298
|
},
|
|
876
1299
|
messages: {
|
|
877
1300
|
noNonComponentExports: description12,
|
|
@@ -892,11 +1315,11 @@ var noNonComponentExports = createRule({
|
|
|
892
1315
|
return;
|
|
893
1316
|
}
|
|
894
1317
|
luminaDeclarationInterface.body.body.forEach((member) => {
|
|
895
|
-
if (member.type !==
|
|
1318
|
+
if (member.type !== AST_NODE_TYPES13.TSPropertySignature || member.computed) {
|
|
896
1319
|
return;
|
|
897
1320
|
}
|
|
898
1321
|
const type = member.typeAnnotation?.typeAnnotation;
|
|
899
|
-
if (type?.type !==
|
|
1322
|
+
if (type?.type !== AST_NODE_TYPES13.TSTypeReference || type.typeName.type !== AST_NODE_TYPES13.Identifier) {
|
|
900
1323
|
return;
|
|
901
1324
|
}
|
|
902
1325
|
const className = type.typeName.name;
|
|
@@ -910,24 +1333,24 @@ var noNonComponentExports = createRule({
|
|
|
910
1333
|
if (node.exportKind === "type") {
|
|
911
1334
|
return;
|
|
912
1335
|
}
|
|
913
|
-
if (node.declaration?.type ===
|
|
1336
|
+
if (node.declaration?.type === AST_NODE_TYPES13.VariableDeclaration) {
|
|
914
1337
|
const isExportsForTests = node.declaration.declarations.every(
|
|
915
|
-
(declaration) => declaration.id.type ===
|
|
1338
|
+
(declaration) => declaration.id.type === AST_NODE_TYPES13.Identifier && declaration.id.name === "exportsForTests"
|
|
916
1339
|
);
|
|
917
1340
|
if (isExportsForTests) {
|
|
918
1341
|
return;
|
|
919
1342
|
}
|
|
920
|
-
} else if (node.declaration?.type ===
|
|
1343
|
+
} else if (node.declaration?.type === AST_NODE_TYPES13.FunctionDeclaration) {
|
|
921
1344
|
const isExportsForTests = node.declaration.id?.name === "exportsForTests";
|
|
922
1345
|
if (isExportsForTests) {
|
|
923
1346
|
return;
|
|
924
1347
|
}
|
|
925
1348
|
} else if (
|
|
926
1349
|
// Type-only constructs
|
|
927
|
-
node.declaration?.type ===
|
|
1350
|
+
node.declaration?.type === AST_NODE_TYPES13.TSDeclareFunction || node.declaration?.type === AST_NODE_TYPES13.TSInterfaceDeclaration || node.declaration?.type === AST_NODE_TYPES13.TSTypeAliasDeclaration
|
|
928
1351
|
) {
|
|
929
1352
|
return;
|
|
930
|
-
} else if (node.declaration?.type ===
|
|
1353
|
+
} else if (node.declaration?.type === AST_NODE_TYPES13.ClassDeclaration) {
|
|
931
1354
|
const isComponent = declaredComponents.has(node.declaration.id?.name ?? "");
|
|
932
1355
|
if (isComponent) {
|
|
933
1356
|
return;
|
|
@@ -964,13 +1387,14 @@ var noNonComponentExports = createRule({
|
|
|
964
1387
|
});
|
|
965
1388
|
|
|
966
1389
|
// src/plugins/lumina/rules/no-property-name-start-with-on.ts
|
|
967
|
-
import { AST_NODE_TYPES as
|
|
1390
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES14 } from "@typescript-eslint/utils";
|
|
968
1391
|
var description13 = `Do not start public property names with "on" as that can confuse frameworks into thinking this property is an event`;
|
|
969
1392
|
var noPropertyNameStartWithOn = createRule({
|
|
970
1393
|
name: "no-property-name-start-with-on",
|
|
971
1394
|
meta: {
|
|
972
1395
|
docs: {
|
|
973
|
-
description: description13
|
|
1396
|
+
description: description13,
|
|
1397
|
+
defaultLevel: "error"
|
|
974
1398
|
},
|
|
975
1399
|
messages: {
|
|
976
1400
|
noPropertyNameStartWithOn: description13
|
|
@@ -986,7 +1410,7 @@ var noPropertyNameStartWithOn = createRule({
|
|
|
986
1410
|
if (!isPublicProperty) {
|
|
987
1411
|
return;
|
|
988
1412
|
}
|
|
989
|
-
const propertyName = node.key.type ===
|
|
1413
|
+
const propertyName = node.key.type === AST_NODE_TYPES14.Identifier ? node.key.name : node.key.type === AST_NODE_TYPES14.Literal ? node.key.value : void 0;
|
|
990
1414
|
if (typeof propertyName !== "string") {
|
|
991
1415
|
return;
|
|
992
1416
|
}
|
|
@@ -1008,7 +1432,7 @@ var noPropertyNameStartWithOn = createRule({
|
|
|
1008
1432
|
});
|
|
1009
1433
|
|
|
1010
1434
|
// src/plugins/lumina/rules/no-render-false.ts
|
|
1011
|
-
import { AST_NODE_TYPES as
|
|
1435
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES15, ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
1012
1436
|
|
|
1013
1437
|
// src/plugins/lumina/utils/checker.ts
|
|
1014
1438
|
import ts3 from "typescript";
|
|
@@ -1041,15 +1465,16 @@ function isLuminaJsxType(type) {
|
|
|
1041
1465
|
}
|
|
1042
1466
|
|
|
1043
1467
|
// src/plugins/lumina/rules/no-render-false.ts
|
|
1044
|
-
var
|
|
1045
|
-
var description14 = `${
|
|
1468
|
+
var baseDescription4 = `Avoid accidentally rendering "false" to the screen (Lit stringifies booleans, rather than drop them like React/Stencil).`;
|
|
1469
|
+
var description14 = `${baseDescription4}
|
|
1046
1470
|
|
|
1047
1471
|
Lumina automatically handles some cases where "false" may get rendered to the screen, but the pattern this code is using is not handled.`;
|
|
1048
1472
|
var noRenderFalse = createRule({
|
|
1049
1473
|
name: "no-render-false",
|
|
1050
1474
|
meta: {
|
|
1051
1475
|
docs: {
|
|
1052
|
-
description:
|
|
1476
|
+
description: baseDescription4,
|
|
1477
|
+
defaultLevel: "warn"
|
|
1053
1478
|
},
|
|
1054
1479
|
messages: {
|
|
1055
1480
|
errorFalseRendered: description14
|
|
@@ -1070,14 +1495,14 @@ var noRenderFalse = createRule({
|
|
|
1070
1495
|
if (!isLuminaJsxType(type)) {
|
|
1071
1496
|
return;
|
|
1072
1497
|
}
|
|
1073
|
-
if (node.parent.type ===
|
|
1498
|
+
if (node.parent.type === AST_NODE_TYPES15.JSXExpressionContainer) {
|
|
1074
1499
|
return;
|
|
1075
1500
|
}
|
|
1076
1501
|
const right = unwrapExpression(node.right);
|
|
1077
|
-
if (right.type ===
|
|
1502
|
+
if (right.type === AST_NODE_TYPES15.JSXElement) {
|
|
1078
1503
|
return;
|
|
1079
1504
|
}
|
|
1080
|
-
if (node.parent.type ===
|
|
1505
|
+
if (node.parent.type === AST_NODE_TYPES15.LogicalExpression) {
|
|
1081
1506
|
return;
|
|
1082
1507
|
}
|
|
1083
1508
|
context.report({
|
|
@@ -1096,14 +1521,15 @@ var noRenderFalse = createRule({
|
|
|
1096
1521
|
});
|
|
1097
1522
|
|
|
1098
1523
|
// src/plugins/lumina/rules/no-unnecessary-attribute-name.ts
|
|
1099
|
-
import { AST_NODE_TYPES as
|
|
1524
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES16 } from "@typescript-eslint/utils";
|
|
1100
1525
|
import { camelToKebab } from "@arcgis/components-utils";
|
|
1101
1526
|
var description15 = 'There is no need for { attribute: "name" } in @property() when attribute name is trivially inferrable from the property name';
|
|
1102
1527
|
var noUnnecessaryAttributeName = createRule({
|
|
1103
1528
|
name: "no-unnecessary-attribute-name",
|
|
1104
1529
|
meta: {
|
|
1105
1530
|
docs: {
|
|
1106
|
-
description: description15
|
|
1531
|
+
description: description15,
|
|
1532
|
+
defaultLevel: "warn"
|
|
1107
1533
|
},
|
|
1108
1534
|
messages: {
|
|
1109
1535
|
noUnnecessaryAttributeName: description15
|
|
@@ -1122,11 +1548,11 @@ var noUnnecessaryAttributeName = createRule({
|
|
|
1122
1548
|
}
|
|
1123
1549
|
const { properties } = part;
|
|
1124
1550
|
const property = decorator.parent;
|
|
1125
|
-
if (property?.type !==
|
|
1551
|
+
if (property?.type !== AST_NODE_TYPES16.MethodDefinition && property?.type !== AST_NODE_TYPES16.PropertyDefinition) {
|
|
1126
1552
|
return;
|
|
1127
1553
|
}
|
|
1128
1554
|
const attributeOption = getProperty(properties, "attribute");
|
|
1129
|
-
const attributeValue = attributeOption?.type ===
|
|
1555
|
+
const attributeValue = attributeOption?.type === AST_NODE_TYPES16.Literal && typeof attributeOption.value === "string" ? attributeOption.value : void 0;
|
|
1130
1556
|
if (attributeOption === void 0 || attributeValue === void 0) {
|
|
1131
1557
|
return;
|
|
1132
1558
|
}
|
|
@@ -1152,13 +1578,14 @@ var noUnnecessaryAttributeName = createRule({
|
|
|
1152
1578
|
});
|
|
1153
1579
|
|
|
1154
1580
|
// src/plugins/lumina/rules/no-unnecessary-bind-this.ts
|
|
1155
|
-
import { AST_NODE_TYPES as
|
|
1581
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17 } from "@typescript-eslint/utils";
|
|
1156
1582
|
var description16 = `.bind(this) is not necessary in Lit's event listener callbacks and ref callbacks as it is handled automatically.`;
|
|
1157
1583
|
var noUnnecessaryBindThis = createRule({
|
|
1158
1584
|
name: "no-unnecessary-bind-this",
|
|
1159
1585
|
meta: {
|
|
1160
1586
|
docs: {
|
|
1161
|
-
description: description16
|
|
1587
|
+
description: description16,
|
|
1588
|
+
defaultLevel: "warn"
|
|
1162
1589
|
},
|
|
1163
1590
|
messages: {
|
|
1164
1591
|
noUnnecessaryBindThis: description16
|
|
@@ -1173,7 +1600,7 @@ var noUnnecessaryBindThis = createRule({
|
|
|
1173
1600
|
return {
|
|
1174
1601
|
ImportDeclaration: luminaJsxCheck,
|
|
1175
1602
|
JSXExpressionContainer(node) {
|
|
1176
|
-
if (!luminaJsxCheck.isLuminaJsx || node.parent.type !==
|
|
1603
|
+
if (!luminaJsxCheck.isLuminaJsx || node.parent.type !== AST_NODE_TYPES17.JSXAttribute || node.parent.name.type !== AST_NODE_TYPES17.JSXIdentifier) {
|
|
1177
1604
|
return;
|
|
1178
1605
|
}
|
|
1179
1606
|
const name = node.parent.name.name;
|
|
@@ -1181,12 +1608,12 @@ var noUnnecessaryBindThis = createRule({
|
|
|
1181
1608
|
if (!isAutoBindable) {
|
|
1182
1609
|
return;
|
|
1183
1610
|
}
|
|
1184
|
-
const expression = node.expression.type ===
|
|
1611
|
+
const expression = node.expression.type === AST_NODE_TYPES17.ChainExpression ? node.expression.expression : node.expression;
|
|
1185
1612
|
const isCallWithThis = (
|
|
1186
1613
|
// expression(...)
|
|
1187
|
-
expression.type ===
|
|
1614
|
+
expression.type === AST_NODE_TYPES17.CallExpression && // expression(expression)
|
|
1188
1615
|
expression.arguments.length === 1 && // expression(this)
|
|
1189
|
-
expression.arguments[0].type ===
|
|
1616
|
+
expression.arguments[0].type === AST_NODE_TYPES17.ThisExpression
|
|
1190
1617
|
);
|
|
1191
1618
|
if (!isCallWithThis) {
|
|
1192
1619
|
return;
|
|
@@ -1194,18 +1621,18 @@ var noUnnecessaryBindThis = createRule({
|
|
|
1194
1621
|
const callee = expression.callee;
|
|
1195
1622
|
const isBindThisCall = (
|
|
1196
1623
|
// expression.expression(this)
|
|
1197
|
-
callee.type ===
|
|
1198
|
-
callee.property.type ===
|
|
1624
|
+
callee.type === AST_NODE_TYPES17.MemberExpression && // expression.identifier(this)
|
|
1625
|
+
callee.property.type === AST_NODE_TYPES17.Identifier && // expression.bind(this)
|
|
1199
1626
|
callee.property.name === "bind" && // expression.expression.bind(this)
|
|
1200
|
-
callee.object.type ===
|
|
1201
|
-
callee.object.property.type ===
|
|
1202
|
-
callee.object.object.type ===
|
|
1627
|
+
callee.object.type === AST_NODE_TYPES17.MemberExpression && // expression.identifier.bind(this)
|
|
1628
|
+
callee.object.property.type === AST_NODE_TYPES17.Identifier && // this.identifier.bind(this)
|
|
1629
|
+
callee.object.object.type === AST_NODE_TYPES17.ThisExpression
|
|
1203
1630
|
);
|
|
1204
1631
|
if (!isBindThisCall) {
|
|
1205
1632
|
return;
|
|
1206
1633
|
}
|
|
1207
|
-
const tagName = context.sourceCode.getAncestors(node.parent).find((ancestor) => ancestor.type ===
|
|
1208
|
-
const tagNameString = tagName?.type ===
|
|
1634
|
+
const tagName = context.sourceCode.getAncestors(node.parent).find((ancestor) => ancestor.type === AST_NODE_TYPES17.JSXOpeningElement)?.name;
|
|
1635
|
+
const tagNameString = tagName?.type === AST_NODE_TYPES17.JSXIdentifier ? tagName.name : void 0;
|
|
1209
1636
|
if (tagNameString === void 0) {
|
|
1210
1637
|
return;
|
|
1211
1638
|
}
|
|
@@ -1226,13 +1653,14 @@ var noUnnecessaryBindThis = createRule({
|
|
|
1226
1653
|
});
|
|
1227
1654
|
|
|
1228
1655
|
// src/plugins/lumina/rules/no-unnecessary-key.ts
|
|
1229
|
-
import { AST_NODE_TYPES as
|
|
1656
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES18 } from "@typescript-eslint/utils";
|
|
1230
1657
|
var description17 = `In most cases, key={index} is not necessary in Lumina in .map(). Details: https://qawebgis.esri.com/components/lumina/jsx#key-prop`;
|
|
1231
1658
|
var noUnnecessaryKey = createRule({
|
|
1232
1659
|
name: "no-unnecessary-key",
|
|
1233
1660
|
meta: {
|
|
1234
1661
|
docs: {
|
|
1235
|
-
description: description17
|
|
1662
|
+
description: description17,
|
|
1663
|
+
defaultLevel: "warn"
|
|
1236
1664
|
},
|
|
1237
1665
|
messages: {
|
|
1238
1666
|
noUnnecessaryKey: description17
|
|
@@ -1251,21 +1679,21 @@ var noUnnecessaryKey = createRule({
|
|
|
1251
1679
|
return;
|
|
1252
1680
|
}
|
|
1253
1681
|
const keyValue = node.expression;
|
|
1254
|
-
if (keyValue.type !==
|
|
1682
|
+
if (keyValue.type !== AST_NODE_TYPES18.Identifier) {
|
|
1255
1683
|
return;
|
|
1256
1684
|
}
|
|
1257
1685
|
const keyAttribute = node.parent;
|
|
1258
|
-
if (keyAttribute?.type !==
|
|
1686
|
+
if (keyAttribute?.type !== AST_NODE_TYPES18.JSXAttribute || keyAttribute.name.type !== AST_NODE_TYPES18.JSXIdentifier || keyAttribute.name.name !== "key") {
|
|
1259
1687
|
return;
|
|
1260
1688
|
}
|
|
1261
1689
|
const mapArrowFunction = context.sourceCode.getAncestors(keyAttribute).find(
|
|
1262
|
-
(ancestor) => ancestor.type ===
|
|
1690
|
+
(ancestor) => ancestor.type === AST_NODE_TYPES18.ArrowFunctionExpression && ancestor.parent?.type === AST_NODE_TYPES18.CallExpression && ancestor.parent?.callee.type === AST_NODE_TYPES18.MemberExpression && ancestor.parent?.callee.property.type === AST_NODE_TYPES18.Identifier && ancestor.parent?.callee.property.name === "map"
|
|
1263
1691
|
);
|
|
1264
1692
|
if (mapArrowFunction === void 0) {
|
|
1265
1693
|
return;
|
|
1266
1694
|
}
|
|
1267
1695
|
const keyParameter = mapArrowFunction.params.at(1);
|
|
1268
|
-
if (keyParameter?.type !==
|
|
1696
|
+
if (keyParameter?.type !== AST_NODE_TYPES18.Identifier || keyParameter.name !== keyValue.name) {
|
|
1269
1697
|
return;
|
|
1270
1698
|
}
|
|
1271
1699
|
context.report({
|
|
@@ -1289,7 +1717,7 @@ var noUnnecessaryKey = createRule({
|
|
|
1289
1717
|
});
|
|
1290
1718
|
|
|
1291
1719
|
// src/plugins/lumina/rules/tag-name-rules.ts
|
|
1292
|
-
import { AST_NODE_TYPES as
|
|
1720
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19 } from "@typescript-eslint/utils";
|
|
1293
1721
|
var description18 = `Validate component tag name`;
|
|
1294
1722
|
var defaultOptions2 = [
|
|
1295
1723
|
{
|
|
@@ -1300,7 +1728,8 @@ var tagNameRules = createRule({
|
|
|
1300
1728
|
name: "tag-name-rules",
|
|
1301
1729
|
meta: {
|
|
1302
1730
|
docs: {
|
|
1303
|
-
description: description18
|
|
1731
|
+
description: description18,
|
|
1732
|
+
defaultLevel: "error"
|
|
1304
1733
|
},
|
|
1305
1734
|
messages: {
|
|
1306
1735
|
requireNamespace: "Custom element tag names in this project must start with one of the following namespaces: {{namespaces}}",
|
|
@@ -1363,7 +1792,7 @@ declare global {
|
|
|
1363
1792
|
}
|
|
1364
1793
|
seenDeclareGlobal = true;
|
|
1365
1794
|
luminaDeclarationInterface.body.body.forEach((member) => {
|
|
1366
|
-
if (member.type !==
|
|
1795
|
+
if (member.type !== AST_NODE_TYPES19.TSPropertySignature) {
|
|
1367
1796
|
context.report({
|
|
1368
1797
|
messageId: "unexpectedDeclareElementsEntry",
|
|
1369
1798
|
node: member
|
|
@@ -1377,7 +1806,7 @@ declare global {
|
|
|
1377
1806
|
});
|
|
1378
1807
|
return;
|
|
1379
1808
|
}
|
|
1380
|
-
if (member.key.type ===
|
|
1809
|
+
if (member.key.type === AST_NODE_TYPES19.Identifier) {
|
|
1381
1810
|
context.report({
|
|
1382
1811
|
messageId: "noTagNameIdentifier",
|
|
1383
1812
|
node: member.key
|
|
@@ -1441,7 +1870,7 @@ declare global {
|
|
|
1441
1870
|
return;
|
|
1442
1871
|
}
|
|
1443
1872
|
const type = member.typeAnnotation?.typeAnnotation;
|
|
1444
|
-
if (type?.type !==
|
|
1873
|
+
if (type?.type !== AST_NODE_TYPES19.TSTypeReference || type.typeName.type !== AST_NODE_TYPES19.Identifier) {
|
|
1445
1874
|
context.report({
|
|
1446
1875
|
messageId: "unexpectedDeclarationType",
|
|
1447
1876
|
node: type ?? member
|
|
@@ -1488,7 +1917,7 @@ declare global {
|
|
|
1488
1917
|
messageId: "mustSubclass",
|
|
1489
1918
|
node
|
|
1490
1919
|
});
|
|
1491
|
-
} else if (node.superClass.type ===
|
|
1920
|
+
} else if (node.superClass.type === AST_NODE_TYPES19.Identifier && node.superClass.name.startsWith("HTML") && node.superClass.name.endsWith("Element")) {
|
|
1492
1921
|
context.report({
|
|
1493
1922
|
messageId: "mustNotSubclassHtmlElement",
|
|
1494
1923
|
node
|
|
@@ -1527,6 +1956,7 @@ var lumina_default = makeEslintPlugin("lumina", {
|
|
|
1527
1956
|
"component-placement-rules": componentPlacementRules,
|
|
1528
1957
|
"consistent-event-naming": consistentEventNaming,
|
|
1529
1958
|
"decorators-context": decoratorsContext,
|
|
1959
|
+
"member-ordering": memberOrdering,
|
|
1530
1960
|
"no-ignore-jsdoc-tag": noIgnoreJsDocTag,
|
|
1531
1961
|
"no-incorrect-dynamic-tag-name": noIncorrectDynamicTagName,
|
|
1532
1962
|
"no-inline-arrow-in-ref": noInlineArrowInRef,
|