@salesforce/afv-skills 1.28.0 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +1 -1
- package/skills/agentforce-architecture-analyze/README.md +2 -8
- package/skills/agentforce-architecture-analyze/SKILL.md +2 -2
- package/skills/agentforce-architecture-analyze/references/contract.json +4 -4
- package/skills/agentforce-architecture-analyze/references/soql_fields.md +1 -1
- package/skills/data360-activate/README.md +0 -1
- package/skills/data360-activate/SKILL.md +0 -2
- package/skills/data360-connect/README.md +0 -2
- package/skills/data360-connect/SKILL.md +0 -2
- package/skills/data360-harmonize/SKILL.md +0 -1
- package/skills/data360-orchestrate/README.md +0 -7
- package/skills/data360-orchestrate/SKILL.md +0 -2
- package/skills/data360-prepare/README.md +0 -1
- package/skills/data360-prepare/SKILL.md +0 -1
- package/skills/data360-query/README.md +0 -1
- package/skills/data360-query/SKILL.md +0 -1
- package/skills/data360-segment/README.md +0 -1
- package/skills/data360-segment/SKILL.md +0 -2
- package/skills/dx-code-analyzer-configure/SKILL.md +31 -13
- package/skills/dx-code-analyzer-custom-rule-create/SKILL.md +484 -0
- package/skills/dx-code-analyzer-custom-rule-create/assets/pmd-ruleset-template.xml +31 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-fields-api.md +87 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-flows.md +105 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-permissions.md +95 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-examples.md +84 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/regex-examples.md +127 -0
- package/skills/dx-code-analyzer-custom-rule-create/examples/xpath-examples.md +227 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/advanced-pmd-patterns.md +288 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/apex-ast-reference.md +127 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/eslint-custom-plugins.md +247 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/eslint-rules-discovery.md +188 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier2-configurable.md +114 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier3-custom-plugins.md +113 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/metadata-xml-rules.md +285 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/regex-rule-schema.md +174 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/troubleshooting.md +141 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-governor-limits.md +83 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-method-calls.md +108 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-security.md +45 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-structure.md +127 -0
- package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns.md +131 -0
- package/skills/dx-code-analyzer-custom-rule-create/scripts/create-pmd-rule.js +209 -0
- package/skills/dx-code-analyzer-custom-rule-create/scripts/create-regex-rule.js +220 -0
- package/skills/dx-code-analyzer-run/SKILL.md +41 -8
- package/skills/experience-cms-brand-apply/SKILL.md +47 -16
- package/skills/experience-lwc-generate/README.md +3 -2
- package/skills/experience-lwc-generate/references/async-notification-patterns.md +1 -1
- package/skills/experience-lwc-generate/references/component-patterns.md +3 -3
- package/skills/experience-lwc-generate/references/flow-integration-guide.md +1 -1
- package/skills/experience-lwc-generate/references/lwc-best-practices.md +4 -4
- package/skills/experience-lwc-generate/references/scoring-and-testing.md +1 -1
- package/skills/experience-lwc-generate/references/state-management.md +2 -2
- package/skills/experience-lwc-generate/references/triangle-pattern.md +3 -3
- package/skills/experience-lwc-generate/scripts/post-tool-validate.py +2 -2
- package/skills/experience-lwc-generate/scripts/template_validator.py +1 -1
- package/skills/external-diagram-mermaid-generate/README.md +2 -2
- package/skills/external-diagram-mermaid-generate/SKILL.md +1 -3
- package/skills/external-diagram-mermaid-generate/assets/agentforce/agent-flow.md +4 -4
- package/skills/external-diagram-mermaid-generate/assets/architecture/system-landscape.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/datamodel/b2b-commerce-erd.md +3 -3
- package/skills/external-diagram-mermaid-generate/assets/datamodel/campaigns-erd.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/datamodel/consent-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/files-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/forecasting-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/fsl-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/party-model-erd.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/datamodel/quote-order-erd.md +3 -3
- package/skills/external-diagram-mermaid-generate/assets/datamodel/revenue-cloud-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/sales-cloud-erd.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/datamodel/salesforce-erd.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/datamodel/scheduler-erd.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/datamodel/service-cloud-erd.md +3 -3
- package/skills/external-diagram-mermaid-generate/assets/datamodel/territory-management-erd.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/integration/api-sequence.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/oauth/authorization-code-pkce.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/oauth/authorization-code.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/oauth/client-credentials.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/oauth/device-authorization.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/oauth/jwt-bearer.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/oauth/refresh-token.md +1 -1
- package/skills/external-diagram-mermaid-generate/assets/oauth/user-agent-social-sign-on.md +2 -2
- package/skills/external-diagram-mermaid-generate/assets/role-hierarchy/user-hierarchy.md +1 -1
- package/skills/external-diagram-mermaid-generate/references/color-palette.md +13 -13
- package/skills/external-diagram-mermaid-generate/references/diagram-conventions.md +5 -5
- package/skills/external-diagram-mermaid-generate/references/erd-conventions.md +1 -1
- package/skills/external-diagram-mermaid-generate/references/mermaid-styling.md +2 -2
- package/skills/external-diagram-mermaid-generate/references/preview-guide.md +1 -1
- package/skills/external-diagram-mermaid-generate/references/usage-examples.md +9 -9
- package/skills/external-diagram-mermaid-generate/scripts/README.md +1 -1
- package/skills/integration-connectivity-connected-app-configure/README.md +4 -5
- package/skills/integration-connectivity-connected-app-configure/SKILL.md +2 -2
- package/skills/integration-connectivity-connected-app-configure/references/example-usage.md +7 -7
- package/skills/integration-connectivity-connected-app-configure/references/migration-guide.md +1 -1
- package/skills/integration-connectivity-connected-app-configure/references/oauth-flows-reference.md +1 -1
- package/skills/integration-connectivity-connected-app-configure/references/testing-validation-guide.md +3 -3
- package/skills/integration-connectivity-generate/README.md +1 -1
- package/skills/integration-connectivity-generate/SKILL.md +6 -0
- package/skills/integration-connectivity-generate/assets/callouts/rest-queueable-callout.cls +1 -1
- package/skills/integration-connectivity-generate/assets/external-services/external-service-operations.md +1 -1
- package/skills/integration-connectivity-generate/assets/soap/wsdl2apex-guide.md +1 -1
- package/skills/integration-connectivity-generate/references/callout-patterns.md +4 -0
- package/skills/integration-connectivity-generate/references/cdc-guide.md +2 -2
- package/skills/integration-connectivity-generate/references/event-driven-architecture-guide.md +5 -5
- package/skills/integration-connectivity-generate/references/event-patterns.md +3 -2
- package/skills/integration-connectivity-generate/references/external-services-guide.md +4 -1
- package/skills/integration-connectivity-generate/references/messaging-api-v2.md +2 -2
- package/skills/integration-connectivity-generate/references/named-credentials-automation.md +1 -1
- package/skills/integration-connectivity-generate/references/named-credentials-guide.md +12 -2
- package/skills/integration-connectivity-generate/references/platform-events-guide.md +3 -3
- package/skills/integration-connectivity-generate/references/rest-callout-patterns.md +1 -1
- package/skills/integration-connectivity-generate/references/scoring-rubric.md +1 -1
- package/skills/integration-connectivity-generate/references/security-best-practices.md +5 -2
- package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +16 -5
- package/skills/integration-connectivity-generate/scripts/set-api-credential.sh +11 -2
- package/skills/integration-connectivity-generate/scripts/suggest_credential_setup.py +4 -3
- package/skills/integration-connectivity-generate/scripts/validate_integration.py +1 -1
- package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +3 -3
- package/skills/omnistudio-callable-apex-generate/README.md +1 -5
- package/skills/omnistudio-callable-apex-generate/SKILL.md +14 -4
- package/skills/omnistudio-callable-apex-generate/assets/pattern_callable_vanilla.cls +8 -1
- package/skills/omnistudio-callable-apex-generate/examples/Test_VlocityOpenInterface2Conversion/TRANSCRIPT.md +1 -1
- package/skills/omnistudio-callable-apex-generate/examples/Test_VlocityOpenInterfaceConversion/TRANSCRIPT.md +1 -1
- package/skills/omnistudio-datamapper-generate/SKILL.md +1 -1
- package/skills/omnistudio-datamapper-generate/assets/completion-summary-template.md +2 -2
- package/skills/omnistudio-datamapper-generate/references/best-practices.md +9 -9
- package/skills/omnistudio-datamapper-generate/references/naming-conventions.md +6 -6
- package/skills/omnistudio-datapacks-deploy/README.md +1 -1
- package/skills/omnistudio-datapacks-deploy/examples/business-internet-plus-bundle/deploy-business-internet-plus-bundle.yaml +1 -1
- package/skills/omnistudio-dependencies-analyze/SKILL.md +12 -5
- package/skills/omnistudio-dependencies-analyze/references/dependency-patterns.md +9 -9
- package/skills/omnistudio-dependencies-analyze/references/namespace-guide.md +1 -1
- package/skills/omnistudio-epc-catalog-generate/README.md +1 -1
- package/skills/omnistudio-flexcard-generate/SKILL.md +11 -4
- package/skills/omnistudio-flexcard-generate/references/best-practices.md +6 -6
- package/skills/omnistudio-flexcard-generate/references/data-binding-guide.md +9 -9
- package/skills/omnistudio-integration-procedure-generate/SKILL.md +9 -1
- package/skills/omnistudio-integration-procedure-generate/references/element-types.md +3 -3
- package/skills/omnistudio-omniscript-generate/SKILL.md +2 -2
- package/skills/omnistudio-omniscript-generate/references/best-practices.md +1 -1
- package/skills/omnistudio-omniscript-generate/scripts/check-duplicate-omniscript.sh +8 -0
- package/skills/omnistudio-omniscript-generate/scripts/deploy-omniscript.sh +8 -0
- package/skills/platform-apex-logs-debug/README.md +2 -2
- package/skills/platform-apex-logs-debug/references/cli-commands.md +2 -2
- package/skills/platform-apex-logs-debug/references/debug-log-reference.md +16 -16
- package/skills/platform-apex-logs-debug/references/log-analysis-tools.md +2 -2
- package/skills/platform-apex-test-run/README.md +1 -1
- package/skills/platform-apex-test-run/references/test-fix-loop.md +2 -2
- package/skills/platform-apex-test-run/references/testing-best-practices.md +3 -3
- package/skills/platform-custom-field-generate/SKILL.md +86 -126
- package/skills/platform-custom-field-generate/references/advanced-picklists.md +590 -0
- package/skills/platform-data-manage/README.md +4 -4
- package/skills/platform-data-manage/references/bulk-testing-example.md +1 -1
- package/skills/platform-data-manage/references/crud-workflow-example.md +2 -2
- package/skills/platform-data-manage/references/orchestration.md +6 -6
- package/skills/platform-flexipage-generate/SKILL.md +281 -346
- package/skills/platform-flexipage-generate/references/cli_commands.md +39 -0
- package/skills/platform-flexipage-generate/references/flexipage_fieldSection.md +162 -0
- package/skills/platform-flexipage-generate/references/flexipage_richText.md +84 -0
- package/skills/platform-flexipage-generate/references/identifiers_and_regions.md +167 -0
- package/skills/platform-flexipage-generate/references/mcp_action_examples.md +104 -0
- package/skills/platform-flexipage-generate/references/record_flexipage_dynamicHighlights.md +119 -0
- package/skills/platform-flexipage-generate/references/xml_rules.md +335 -0
- package/skills/platform-flexipage-generate/scripts/resolve-component-instructions.sh +42 -0
- package/skills/platform-flexipage-generate/scripts/scan-lwc-components.sh +113 -0
- package/skills/platform-metadata-deploy/README.md +2 -2
- package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +2 -2
- package/skills/platform-metadata-deploy/references/deployment-workflows.md +16 -16
- package/skills/platform-metadata-deploy/references/orchestration.md +3 -3
- package/skills/platform-metadata-deploy/references/trigger-deployment-safety.md +2 -2
- package/skills/platform-models-api-configure/SKILL.md +140 -0
- package/skills/platform-models-api-configure/scripts/get-orgjwt.sh +48 -0
- package/skills/platform-policy-rule-generate/SKILL.md +260 -0
- package/skills/platform-policy-rule-generate/references/deploy-errors.md +54 -0
- package/skills/platform-policy-rule-generate/references/fixtures-index.md +29 -0
- package/skills/platform-policy-rule-generate/references/policy-schema-full.md +250 -0
- package/skills/platform-policy-rule-generate/references/templates-access.md +132 -0
- package/skills/platform-policy-rule-generate/references/templates-advanced.md +58 -0
- package/skills/platform-policy-rule-generate/references/templates-record.md +75 -0
- package/skills/platform-policy-rule-generate/references/templates-transform.md +70 -0
- package/skills/platform-policy-rule-generate/references/templates.md +10 -0
- package/skills/platform-policy-rule-generate/references/ui-compatibility.md +142 -0
- package/skills/platform-soql-query/README.md +1 -1
- package/skills/platform-soql-query/SKILL.md +1 -1
- package/skills/platform-soql-query/references/anti-patterns.md +1 -1
- package/skills/platform-soql-query/references/field-coverage-rules.md +1 -1
- package/skills/platform-soql-query/references/query-optimization.md +1 -1
- package/skills/platform-soql-query/scripts/post-tool-validate.py +3 -3
- package/skills/platform-value-set-generate/SKILL.md +305 -0
- package/skills/data360-activate/CREDITS.md +0 -5
- package/skills/data360-connect/CREDITS.md +0 -5
- package/skills/data360-harmonize/CREDITS.md +0 -3
- package/skills/data360-orchestrate/CREDITS.md +0 -15
- package/skills/data360-orchestrate/UPSTREAM.md +0 -45
- package/skills/data360-prepare/CREDITS.md +0 -7
- package/skills/data360-query/CREDITS.md +0 -7
- package/skills/data360-segment/CREDITS.md +0 -3
- package/skills/experience-lwc-generate/CREDITS.md +0 -5
- package/skills/external-diagram-mermaid-generate/CREDITS.md +0 -46
- package/skills/external-diagram-visual-generate/CREDITS.md +0 -80
- package/skills/external-diagram-visual-generate/README.md +0 -83
- package/skills/external-diagram-visual-generate/SKILL.md +0 -207
- package/skills/external-diagram-visual-generate/assets/architecture/integration-flow.md +0 -55
- package/skills/external-diagram-visual-generate/assets/erd/core-objects.md +0 -131
- package/skills/external-diagram-visual-generate/assets/erd/custom-objects.md +0 -60
- package/skills/external-diagram-visual-generate/assets/lwc/dashboard-card.md +0 -45
- package/skills/external-diagram-visual-generate/assets/lwc/data-table.md +0 -57
- package/skills/external-diagram-visual-generate/assets/lwc/record-form.md +0 -60
- package/skills/external-diagram-visual-generate/assets/review/apex-review.md +0 -57
- package/skills/external-diagram-visual-generate/assets/review/lwc-review.md +0 -48
- package/skills/external-diagram-visual-generate/references/architect-aesthetic-guide.md +0 -257
- package/skills/external-diagram-visual-generate/references/examples-index.md +0 -35
- package/skills/external-diagram-visual-generate/references/gemini-cli-setup.md +0 -65
- package/skills/external-diagram-visual-generate/references/interview-questions.md +0 -529
- package/skills/external-diagram-visual-generate/references/iteration-workflow.md +0 -173
- package/skills/external-diagram-visual-generate/scripts/check-prerequisites.sh +0 -101
- package/skills/external-diagram-visual-generate/scripts/generate_image.py +0 -243
- package/skills/integration-connectivity-connected-app-configure/CREDITS.md +0 -3
- package/skills/integration-connectivity-generate/CREDITS.md +0 -5
- package/skills/omnistudio-callable-apex-generate/CREDITS.md +0 -9
- package/skills/omnistudio-datamapper-generate/CREDITS.md +0 -5
- package/skills/omnistudio-datapacks-deploy/CREDITS.md +0 -5
- package/skills/omnistudio-dependencies-analyze/CREDITS.md +0 -5
- package/skills/omnistudio-epc-catalog-generate/CREDITS.md +0 -14
- package/skills/omnistudio-flexcard-generate/CREDITS.md +0 -5
- package/skills/omnistudio-integration-procedure-generate/CREDITS.md +0 -5
- package/skills/omnistudio-omniscript-generate/CREDITS.md +0 -5
- package/skills/platform-apex-generate/CREDITS.md +0 -5
- package/skills/platform-apex-logs-debug/CREDITS.md +0 -22
- package/skills/platform-apex-test-generate/CREDITS.md +0 -5
- package/skills/platform-apex-test-run/CREDITS.md +0 -22
- package/skills/platform-data-manage/CREDITS.md +0 -5
- package/skills/platform-metadata-deploy/CREDITS.md +0 -25
- package/skills/platform-soql-query/CREDITS.md +0 -21
- /package/skills/omnistudio-callable-apex-generate/examples/Test_VlocityOpenInterfaceConversion/{MyCustomVlocityOpenInterface2.cls → MyCustomClass.cls} +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Advanced PMD Patterns
|
|
2
|
+
|
|
3
|
+
Multi-rule rulesets, overriding built-in rules, exclusion patterns, Java-based rules, and sharing rules across projects.
|
|
4
|
+
|
|
5
|
+
## Multiple Rules in One Ruleset File
|
|
6
|
+
|
|
7
|
+
A single ruleset XML can contain any number of rules. This is the recommended approach for teams maintaining a shared rule set:
|
|
8
|
+
|
|
9
|
+
```xml
|
|
10
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
11
|
+
<ruleset name="TeamStandards"
|
|
12
|
+
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
|
13
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
14
|
+
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
|
|
15
|
+
|
|
16
|
+
<description>Team coding standards</description>
|
|
17
|
+
|
|
18
|
+
<!-- Rule 1: Custom XPath rule -->
|
|
19
|
+
<rule name="NoSystemDebug" language="apex"
|
|
20
|
+
message="Remove System.debug before merging"
|
|
21
|
+
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule">
|
|
22
|
+
<priority>3</priority>
|
|
23
|
+
<properties>
|
|
24
|
+
<property name="xpath">
|
|
25
|
+
<value><![CDATA[
|
|
26
|
+
//MethodCallExpression[@FullMethodName='System.debug']
|
|
27
|
+
[not(ancestor::UserClass[ModifierNode[@Test = true()]])]
|
|
28
|
+
]]></value>
|
|
29
|
+
</property>
|
|
30
|
+
</properties>
|
|
31
|
+
</rule>
|
|
32
|
+
|
|
33
|
+
<!-- Rule 2: Another custom XPath rule -->
|
|
34
|
+
<rule name="SoqlInLoop" language="apex"
|
|
35
|
+
message="SOQL query inside a loop — move query before the loop"
|
|
36
|
+
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule">
|
|
37
|
+
<priority>2</priority>
|
|
38
|
+
<properties>
|
|
39
|
+
<property name="xpath">
|
|
40
|
+
<value><![CDATA[
|
|
41
|
+
//ForEachStatement//SoqlExpression | //ForLoopStatement//SoqlExpression | //WhileLoopStatement//SoqlExpression
|
|
42
|
+
]]></value>
|
|
43
|
+
</property>
|
|
44
|
+
</properties>
|
|
45
|
+
</rule>
|
|
46
|
+
|
|
47
|
+
<!-- Rule 3: XML metadata rule in the same file -->
|
|
48
|
+
<rule name="MinApiVersion" language="xml"
|
|
49
|
+
message="Update API version to 60.0+"
|
|
50
|
+
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule">
|
|
51
|
+
<priority>3</priority>
|
|
52
|
+
<properties>
|
|
53
|
+
<property name="xpath">
|
|
54
|
+
<value><![CDATA[
|
|
55
|
+
//*[local-name()='apiVersion'][number(substring-before(text(), '.')) < 60]
|
|
56
|
+
]]></value>
|
|
57
|
+
</property>
|
|
58
|
+
</properties>
|
|
59
|
+
</rule>
|
|
60
|
+
</ruleset>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Rules with different `language` values (apex, xml, visualforce, etc.) can coexist in one ruleset. PMD applies each rule only to files matching its language.
|
|
64
|
+
|
|
65
|
+
## Overriding Built-in PMD Rules
|
|
66
|
+
|
|
67
|
+
Override severity, priority, or configurable properties on PMD's built-in rules without writing new ones:
|
|
68
|
+
|
|
69
|
+
```xml
|
|
70
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
71
|
+
<ruleset name="CustomizedBuiltins"
|
|
72
|
+
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
|
73
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
74
|
+
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
|
|
75
|
+
|
|
76
|
+
<description>Customized built-in rule thresholds</description>
|
|
77
|
+
|
|
78
|
+
<!-- Lower the complexity threshold from default 25 to 10 -->
|
|
79
|
+
<rule ref="category/apex/design.xml/CyclomaticComplexity">
|
|
80
|
+
<priority>2</priority>
|
|
81
|
+
<properties>
|
|
82
|
+
<property name="classReportLevel" value="40" />
|
|
83
|
+
<property name="methodReportLevel" value="10" />
|
|
84
|
+
</properties>
|
|
85
|
+
</rule>
|
|
86
|
+
|
|
87
|
+
<!-- Change excessive parameter count from default 4 to 3 -->
|
|
88
|
+
<rule ref="category/apex/design.xml/ExcessiveParameterList">
|
|
89
|
+
<properties>
|
|
90
|
+
<property name="minimum" value="3" />
|
|
91
|
+
</properties>
|
|
92
|
+
</rule>
|
|
93
|
+
|
|
94
|
+
<!-- Make debug statement rule high-severity instead of moderate -->
|
|
95
|
+
<rule ref="category/apex/bestpractices.xml/DebugsShouldUseLoggingLevel">
|
|
96
|
+
<priority>2</priority>
|
|
97
|
+
<properties>
|
|
98
|
+
<property name="strictMode" value="true" />
|
|
99
|
+
</properties>
|
|
100
|
+
</rule>
|
|
101
|
+
|
|
102
|
+
<!-- Include an entire category with one exclusion -->
|
|
103
|
+
<rule ref="category/apex/security.xml">
|
|
104
|
+
<exclude name="ApexSuggestUsingNamedCred" />
|
|
105
|
+
</rule>
|
|
106
|
+
</ruleset>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Configuration:**
|
|
110
|
+
```yaml
|
|
111
|
+
# code-analyzer.yml
|
|
112
|
+
engines:
|
|
113
|
+
pmd:
|
|
114
|
+
custom_rulesets:
|
|
115
|
+
- "custom-rules/customized-builtins.xml"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### How rule ref works
|
|
119
|
+
|
|
120
|
+
| Pattern | Effect |
|
|
121
|
+
|---------|--------|
|
|
122
|
+
| `<rule ref="category/apex/design.xml/CyclomaticComplexity">` | Override one specific rule |
|
|
123
|
+
| `<rule ref="category/apex/security.xml">` | Include entire category |
|
|
124
|
+
| `<rule ref="..."><exclude name="RuleName"/></rule>` | Include category minus specific rules |
|
|
125
|
+
| Nested `<priority>` | Override severity (1=Critical, 2=High, 3=Moderate, 4=Low, 5=Info) |
|
|
126
|
+
| Nested `<properties>` | Override configurable thresholds/options |
|
|
127
|
+
|
|
128
|
+
### Common built-in rules to customize
|
|
129
|
+
|
|
130
|
+
| Rule | Useful Properties |
|
|
131
|
+
|------|-------------------|
|
|
132
|
+
| `CyclomaticComplexity` | `classReportLevel` (default: 40), `methodReportLevel` (default: 25) |
|
|
133
|
+
| `ExcessiveParameterList` | `minimum` (default: 4) |
|
|
134
|
+
| `ExcessiveClassLength` | `minimum` (default: 1000) |
|
|
135
|
+
| `TooManyFields` | `maxfields` (default: 15) |
|
|
136
|
+
| `NcssMethodCount` | `minimum` (default: 60) |
|
|
137
|
+
| `DebugsShouldUseLoggingLevel` | `strictMode` (default: false) |
|
|
138
|
+
| `ApexUnitTestClassShouldHaveAsserts` | (no properties — exclude if unwanted) |
|
|
139
|
+
|
|
140
|
+
## Exclusion Patterns
|
|
141
|
+
|
|
142
|
+
Three mechanisms for excluding files and rules:
|
|
143
|
+
|
|
144
|
+
### 1. File exclusions in `code-analyzer.yml`
|
|
145
|
+
|
|
146
|
+
Exclude entire directories or file patterns from all engines:
|
|
147
|
+
|
|
148
|
+
```yaml
|
|
149
|
+
# code-analyzer.yml
|
|
150
|
+
ignores:
|
|
151
|
+
files:
|
|
152
|
+
- "**/node_modules/**"
|
|
153
|
+
- "**/fflib_*"
|
|
154
|
+
- "**/*Test*.cls"
|
|
155
|
+
- "**/generated/**"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Supports glob patterns: `*`, `**`, `?`, `[...]`, `{...}`
|
|
159
|
+
|
|
160
|
+
### 2. Rule exclusions in PMD rulesets
|
|
161
|
+
|
|
162
|
+
Exclude specific rules when including an entire category:
|
|
163
|
+
|
|
164
|
+
```xml
|
|
165
|
+
<rule ref="category/apex/bestpractices.xml">
|
|
166
|
+
<exclude name="ApexUnitTestClassShouldHaveAsserts" />
|
|
167
|
+
<exclude name="ApexAssertionsShouldIncludeMessage" />
|
|
168
|
+
</rule>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 3. Exclude patterns in PMD rulesets
|
|
172
|
+
|
|
173
|
+
Exclude files at the PMD level (applies only to rules in that ruleset):
|
|
174
|
+
|
|
175
|
+
```xml
|
|
176
|
+
<ruleset name="MyRules" ...>
|
|
177
|
+
<exclude-pattern>.*/fflib_.*</exclude-pattern>
|
|
178
|
+
<exclude-pattern>.*/test/.*</exclude-pattern>
|
|
179
|
+
|
|
180
|
+
<rule name="..." ...>
|
|
181
|
+
...
|
|
182
|
+
</rule>
|
|
183
|
+
</ruleset>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 4. Disabling individual rules via config
|
|
187
|
+
|
|
188
|
+
Disable any rule without editing rulesets:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
# code-analyzer.yml
|
|
192
|
+
rules:
|
|
193
|
+
pmd:
|
|
194
|
+
ApexUnitTestClassShouldHaveAsserts:
|
|
195
|
+
disabled: true
|
|
196
|
+
CyclomaticComplexity:
|
|
197
|
+
severity: "Low" # Downgrade instead of disable
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Java-Based Custom Rules (Advanced)
|
|
201
|
+
|
|
202
|
+
For rules that need logic beyond XPath (complex data flow, cross-file analysis), write Java PMD rules:
|
|
203
|
+
|
|
204
|
+
1. **Create a Java class** extending `net.sourceforge.pmd.lang.apex.rule.AbstractApexRule`
|
|
205
|
+
2. **Compile into a JAR** file
|
|
206
|
+
3. **Reference in config:**
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
# code-analyzer.yml
|
|
210
|
+
engines:
|
|
211
|
+
pmd:
|
|
212
|
+
java_classpath_entries:
|
|
213
|
+
- "custom-rules/my-rules.jar" # JAR with compiled rule classes
|
|
214
|
+
- "custom-rules/lib/" # Folder of JARs (all JARs inside loaded)
|
|
215
|
+
custom_rulesets:
|
|
216
|
+
- "category/myteam/rules.xml" # Ruleset inside the JAR (classpath resource)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The JAR's ruleset XML references the Java class:
|
|
220
|
+
```xml
|
|
221
|
+
<rule name="AvoidFutureAnnotation" language="apex"
|
|
222
|
+
message="Use Queueable instead of @Future"
|
|
223
|
+
class="com.myteam.pmd.rules.AvoidFutureRule">
|
|
224
|
+
<priority>3</priority>
|
|
225
|
+
</rule>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Requirements:**
|
|
229
|
+
- Java 11+ for compilation
|
|
230
|
+
- PMD 7.x API (use `net.sourceforge.pmd.lang.rule.xpath.XPathRule` for XPath, or extend `AbstractApexRule` for visitor-pattern Java rules)
|
|
231
|
+
|
|
232
|
+
## Sharing Rules Across Projects
|
|
233
|
+
|
|
234
|
+
### Approach 1: Relative paths with shared config
|
|
235
|
+
|
|
236
|
+
If projects share a parent directory or monorepo:
|
|
237
|
+
```yaml
|
|
238
|
+
# code-analyzer.yml
|
|
239
|
+
engines:
|
|
240
|
+
pmd:
|
|
241
|
+
custom_rulesets:
|
|
242
|
+
- "../shared-rules/team-standards.xml" # Relative to config_root
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`config_root` is the directory containing `code-analyzer.yml`. All relative paths resolve from there.
|
|
246
|
+
|
|
247
|
+
### Approach 2: JAR-based distribution
|
|
248
|
+
|
|
249
|
+
Package rules into a JAR and distribute via artifact repository:
|
|
250
|
+
|
|
251
|
+
1. Build a JAR containing your ruleset XML at a classpath resource path (e.g., `category/myteam/standards.xml`)
|
|
252
|
+
2. Place the JAR in each project's `custom-rules/` directory (or download in CI)
|
|
253
|
+
3. Reference in config:
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
engines:
|
|
257
|
+
pmd:
|
|
258
|
+
java_classpath_entries:
|
|
259
|
+
- "custom-rules/myteam-rules-1.0.jar"
|
|
260
|
+
custom_rulesets:
|
|
261
|
+
- "category/myteam/standards.xml" # Resource inside the JAR
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Approach 3: Git submodule or symlink
|
|
265
|
+
|
|
266
|
+
For simpler setups, share the ruleset XML via git submodule:
|
|
267
|
+
```bash
|
|
268
|
+
git submodule add https://github.com/myteam/pmd-rules.git custom-rules/shared
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```yaml
|
|
272
|
+
engines:
|
|
273
|
+
pmd:
|
|
274
|
+
custom_rulesets:
|
|
275
|
+
- "custom-rules/shared/team-standards.xml"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### CI/CD Integration
|
|
279
|
+
|
|
280
|
+
All approaches work in CI because paths are relative to `config_root`. Example GitHub Actions step:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
- name: Run Code Analyzer
|
|
284
|
+
run: |
|
|
285
|
+
sf code-analyzer run --rule-selector "pmd:2,regex:2" --target force-app/
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
No absolute paths needed — the config file handles resolution.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Apex AST Node Reference
|
|
2
|
+
|
|
3
|
+
PMD 7.x Apex AST node types and their attributes. Use `sf code-analyzer ast-dump --file <file.cls>` to see the actual tree for your code.
|
|
4
|
+
|
|
5
|
+
## Node Hierarchy (Common Structure)
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
ApexFile
|
|
9
|
+
├── UserClass / UserInterface / UserTrigger / UserEnum
|
|
10
|
+
│ ├── FormalComment (Javadoc)
|
|
11
|
+
│ ├── ModifierNode (public, private, static, etc.)
|
|
12
|
+
│ ├── Field (class-level variables)
|
|
13
|
+
│ │ └── VariableDeclaration
|
|
14
|
+
│ └── Method
|
|
15
|
+
│ ├── ModifierNode
|
|
16
|
+
│ ├── Parameter
|
|
17
|
+
│ └── BlockStatement
|
|
18
|
+
│ ├── VariableDeclarationStatements
|
|
19
|
+
│ ├── ExpressionStatement
|
|
20
|
+
│ │ └── MethodCallExpression
|
|
21
|
+
│ ├── IfElseBlockStatement
|
|
22
|
+
│ │ └── IfBlockStatement
|
|
23
|
+
│ ├── ForEachStatement / ForLoopStatement / WhileLoopStatement
|
|
24
|
+
│ ├── TryCatchFinallyBlockStatement
|
|
25
|
+
│ │ ├── BlockStatement (try body)
|
|
26
|
+
│ │ ├── CatchBlockStatement
|
|
27
|
+
│ │ └── BlockStatement (finally body)
|
|
28
|
+
│ ├── DmlInsertStatement / DmlUpdateStatement / DmlDeleteStatement
|
|
29
|
+
│ ├── ReturnStatement
|
|
30
|
+
│ └── ThrowStatement
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ModifierNode Attributes
|
|
34
|
+
|
|
35
|
+
Every class, method, field, and parameter has a `ModifierNode` with these boolean attributes:
|
|
36
|
+
|
|
37
|
+
| Attribute | Meaning |
|
|
38
|
+
|-----------|---------|
|
|
39
|
+
| `Public` | public access |
|
|
40
|
+
| `Private` | private access |
|
|
41
|
+
| `Protected` | protected access |
|
|
42
|
+
| `Global` | global access |
|
|
43
|
+
| `Static` | static member |
|
|
44
|
+
| `Final` | final/const |
|
|
45
|
+
| `Abstract` | abstract method/class |
|
|
46
|
+
| `Virtual` | virtual method/class |
|
|
47
|
+
| `Override` | overrides parent method |
|
|
48
|
+
| `Test` | @IsTest annotated |
|
|
49
|
+
| `TestOrTestSetup` | @IsTest or @TestSetup |
|
|
50
|
+
| `WebService` | webservice method |
|
|
51
|
+
| `WithSharing` | with sharing class |
|
|
52
|
+
| `WithoutSharing` | without sharing class |
|
|
53
|
+
| `InheritedSharing` | inherited sharing class |
|
|
54
|
+
| `Transient` | transient field |
|
|
55
|
+
| `Modifiers` | Bitmask integer of all modifiers |
|
|
56
|
+
|
|
57
|
+
⚠️ **PMD 7 Boolean Attribute Comparison:**
|
|
58
|
+
|
|
59
|
+
In PMD 7, these boolean attributes are **always present** on the node — they are never absent. This means:
|
|
60
|
+
- ✅ `@WithSharing = false()` — correct (XPath boolean function)
|
|
61
|
+
- ✅ `@WithSharing = true()` — correct
|
|
62
|
+
- ❌ `@WithSharing = 'false'` — WRONG (string comparison, won't match)
|
|
63
|
+
- ❌ `not(@WithSharing)` — WRONG (attribute always exists, so this is always false)
|
|
64
|
+
- ❌ `@WithSharing` (as existence check) — WRONG (always true, attribute always present)
|
|
65
|
+
|
|
66
|
+
Use the XPath `true()`/`false()` functions for boolean comparisons:
|
|
67
|
+
```xpath
|
|
68
|
+
<!-- Classes without sharing declaration -->
|
|
69
|
+
//UserClass[ModifierNode[@WithSharing = false() and @WithoutSharing = false() and @InheritedSharing = false()]]
|
|
70
|
+
|
|
71
|
+
<!-- Abstract classes -->
|
|
72
|
+
//UserClass[ModifierNode[@Abstract = true()]]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## MethodCallExpression Attributes
|
|
76
|
+
|
|
77
|
+
| Attribute | Example | Notes |
|
|
78
|
+
|-----------|---------|-------|
|
|
79
|
+
| `FullMethodName` | `'System.debug'`, `'Database.query'` | Most reliable for matching |
|
|
80
|
+
| `MethodName` | `'debug'`, `'query'` | Just the method part |
|
|
81
|
+
| `InputParametersSize` | `'1'`, `'0'` | Number of arguments |
|
|
82
|
+
|
|
83
|
+
## LiteralExpression Attributes
|
|
84
|
+
|
|
85
|
+
| Attribute | Values | Notes |
|
|
86
|
+
|-----------|--------|-------|
|
|
87
|
+
| `LiteralType` | `STRING`, `INTEGER`, `DECIMAL`, `DOUBLE`, `LONG`, `BOOLEAN` | Type of literal |
|
|
88
|
+
| `Image` | The literal value | For strings, excludes quotes |
|
|
89
|
+
| `String` | `'true'` / `'false'` | Boolean shorthand |
|
|
90
|
+
| `Null` | `'true'` / `'false'` | Is it a null literal |
|
|
91
|
+
|
|
92
|
+
## SoqlExpression Attributes
|
|
93
|
+
|
|
94
|
+
| Attribute | Example | Notes |
|
|
95
|
+
|-----------|---------|-------|
|
|
96
|
+
| `Query` | `'SELECT Id FROM Account WHERE Name = :name'` | Original SOQL as written |
|
|
97
|
+
| `CanonicalQuery` | `'SELECT Id FROM Account WHERE Name = :tmpVar1'` | Normalized (bind vars replaced) |
|
|
98
|
+
|
|
99
|
+
## Annotation Node
|
|
100
|
+
|
|
101
|
+
```xml
|
|
102
|
+
<Annotation Image="IsTest">
|
|
103
|
+
<AnnotationParameter Name="testFor" Value="'ApexClass:MyService'" />
|
|
104
|
+
</Annotation>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use: `//Annotation[@Image='IsTest']` to find test annotations.
|
|
108
|
+
|
|
109
|
+
## DML Nodes
|
|
110
|
+
|
|
111
|
+
| Statement | Node | Notes |
|
|
112
|
+
|-----------|------|-------|
|
|
113
|
+
| `insert x;` | `DmlInsertStatement` | |
|
|
114
|
+
| `update x;` | `DmlUpdateStatement` | |
|
|
115
|
+
| `delete x;` | `DmlDeleteStatement` | |
|
|
116
|
+
| `upsert x;` | `DmlUpsertStatement` | |
|
|
117
|
+
| `undelete x;` | `DmlUndeleteStatement` | |
|
|
118
|
+
| `Database.insert(x)` | `MethodCallExpression[@FullMethodName='Database.insert']` | Method-form DML |
|
|
119
|
+
|
|
120
|
+
## Tips for Reading AST Dumps
|
|
121
|
+
|
|
122
|
+
1. **`Image` attribute** = the actual source name (variable name, class name, method name)
|
|
123
|
+
2. **`DefiningType` attribute** = which class this node belongs to (present on every node)
|
|
124
|
+
3. **`RealLoc='true'`** = this node has a real source position (not compiler-generated)
|
|
125
|
+
4. **`RealLoc='false'`** = compiler-generated node (e.g., implicit modifiers, empty references)
|
|
126
|
+
5. **`EmptyReferenceExpression`** = placeholder for unqualified variable access (ignore these)
|
|
127
|
+
6. **`Type` attribute on VariableDeclaration** = the declared type (e.g., `'Account'`, `'List<Contact>'`)
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# ESLint Custom Rules for LWC/JavaScript
|
|
2
|
+
|
|
3
|
+
Create and integrate custom ESLint rules for Lightning Web Components, JavaScript, and TypeScript through Code Analyzer.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
Code Analyzer's ESLint engine loads your project's ESLint configuration alongside its built-in rules. You can:
|
|
8
|
+
- Use your own `eslint.config.js` with custom plugins
|
|
9
|
+
- Extend or override built-in base configs (LWC, TypeScript, SLDS, React)
|
|
10
|
+
- Install any npm ESLint plugin and have Code Analyzer pick it up
|
|
11
|
+
|
|
12
|
+
## Configuration
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
# code-analyzer.yml
|
|
16
|
+
engines:
|
|
17
|
+
eslint:
|
|
18
|
+
# Point to your project's ESLint config
|
|
19
|
+
eslint_config_file: "eslint.config.js"
|
|
20
|
+
|
|
21
|
+
# Or auto-discover from workspace (searches for eslint.config.js/mjs/cjs)
|
|
22
|
+
auto_discover_eslint_config: true
|
|
23
|
+
|
|
24
|
+
# Disable base configs you don't need
|
|
25
|
+
disable_javascript_base_config: false
|
|
26
|
+
disable_lwc_base_config: false
|
|
27
|
+
disable_typescript_base_config: false
|
|
28
|
+
disable_slds_base_config: false
|
|
29
|
+
disable_react_base_config: false
|
|
30
|
+
|
|
31
|
+
# Custom file extension mapping
|
|
32
|
+
file_extensions:
|
|
33
|
+
javascript: [".js", ".cjs", ".mjs", ".jsx"]
|
|
34
|
+
typescript: [".ts", ".tsx"]
|
|
35
|
+
html: [".html", ".htm", ".cmp"]
|
|
36
|
+
css: [".css", ".scss"]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Adding Custom ESLint Plugins
|
|
40
|
+
|
|
41
|
+
### Step 1: Install the plugin
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install --save-dev eslint-plugin-my-custom
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Step 2: Create or update `eslint.config.js` (flat config)
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
const myPlugin = require('eslint-plugin-my-custom');
|
|
51
|
+
|
|
52
|
+
module.exports = [
|
|
53
|
+
{
|
|
54
|
+
plugins: {
|
|
55
|
+
'my-custom': myPlugin
|
|
56
|
+
},
|
|
57
|
+
rules: {
|
|
58
|
+
'my-custom/no-dangerous-pattern': 'error',
|
|
59
|
+
'my-custom/enforce-naming': ['warn', { pattern: '^[a-z]' }]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Step 3: Reference in `code-analyzer.yml`
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
engines:
|
|
69
|
+
eslint:
|
|
70
|
+
eslint_config_file: "eslint.config.js"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Step 4: Validate and run
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Check that custom rules appear
|
|
77
|
+
sf code-analyzer rules --rule-selector eslint
|
|
78
|
+
|
|
79
|
+
# Run against targets
|
|
80
|
+
sf code-analyzer run --rule-selector eslint --target force-app/main/default/lwc/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Common LWC Custom Rule Patterns
|
|
84
|
+
|
|
85
|
+
### Enforce component naming convention
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// eslint.config.js
|
|
89
|
+
module.exports = [
|
|
90
|
+
{
|
|
91
|
+
rules: {
|
|
92
|
+
'@lwc/lwc/no-unknown-wire-adapters': 'error',
|
|
93
|
+
'@lwc/lwc/no-api-reassignments': 'error',
|
|
94
|
+
'@lwc/lwc/no-leaky-event-listeners': 'error'
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Add SSR compatibility checks
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
module.exports = [
|
|
104
|
+
{
|
|
105
|
+
rules: {
|
|
106
|
+
'@lwc/lwc/no-restricted-browser-globals-during-ssr': 'error',
|
|
107
|
+
'@lwc/lwc/no-unsupported-ssr-properties': 'error'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
];
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### TypeScript strict rules
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
module.exports = [
|
|
117
|
+
{
|
|
118
|
+
rules: {
|
|
119
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
120
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
121
|
+
'@typescript-eslint/strict-boolean-expressions': 'warn'
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Disabling Base Configs
|
|
128
|
+
|
|
129
|
+
When you want full control over which rules run, disable the built-in base configs:
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
engines:
|
|
133
|
+
eslint:
|
|
134
|
+
eslint_config_file: "eslint.config.js"
|
|
135
|
+
disable_javascript_base_config: true
|
|
136
|
+
disable_lwc_base_config: true
|
|
137
|
+
disable_typescript_base_config: true
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This prevents Code Analyzer's bundled rules from running — only your custom config's rules apply. Parsers are still configured (so files parse correctly), but no built-in rules fire.
|
|
141
|
+
|
|
142
|
+
## Overriding Rule Severity via Config
|
|
143
|
+
|
|
144
|
+
After ESLint rules are loaded, override severity in `code-analyzer.yml`:
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
rules:
|
|
148
|
+
eslint:
|
|
149
|
+
no-unused-vars:
|
|
150
|
+
severity: "Low"
|
|
151
|
+
my-custom/dangerous-pattern:
|
|
152
|
+
severity: "Critical"
|
|
153
|
+
no-console:
|
|
154
|
+
disabled: true
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Legacy Config Support
|
|
158
|
+
|
|
159
|
+
If your project uses `.eslintrc.js` (ESLint v8 format), it still works:
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
engines:
|
|
163
|
+
eslint:
|
|
164
|
+
eslint_config_file: ".eslintrc.js"
|
|
165
|
+
eslint_ignore_file: ".eslintignore" # Only needed with legacy config
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Flat config (`eslint.config.js`) is recommended for new projects.
|
|
169
|
+
|
|
170
|
+
## Plugin Requirements
|
|
171
|
+
|
|
172
|
+
For Code Analyzer to pick up custom plugin rules, each rule must have:
|
|
173
|
+
- `meta.docs.description` — rule description
|
|
174
|
+
- `meta.docs.url` — documentation URL
|
|
175
|
+
|
|
176
|
+
Rules without these metadata fields are silently excluded. Deprecated rules are also excluded.
|
|
177
|
+
|
|
178
|
+
## Banning APIs Without a Custom Plugin
|
|
179
|
+
|
|
180
|
+
Core ESLint includes powerful "restrictor" rules that can ban specific globals, syntax patterns, or properties — no plugin installation needed. These rules are NOT active by default — you must enable them in `eslint.config.js`:
|
|
181
|
+
|
|
182
|
+
### `no-restricted-globals` — ban global functions/variables
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
module.exports = [
|
|
186
|
+
{
|
|
187
|
+
files: ["**/lwc/**/*.js"],
|
|
188
|
+
rules: {
|
|
189
|
+
"no-restricted-globals": ["error",
|
|
190
|
+
{ "name": "setTimeout", "message": "Use lifecycle hooks instead of setTimeout." },
|
|
191
|
+
{ "name": "setInterval", "message": "Use lifecycle hooks instead of setInterval." },
|
|
192
|
+
{ "name": "eval", "message": "eval is forbidden for security." }
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
];
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### `no-restricted-syntax` — ban arbitrary AST patterns
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
module.exports = [
|
|
203
|
+
{
|
|
204
|
+
files: ["**/lwc/**/*.js"],
|
|
205
|
+
rules: {
|
|
206
|
+
"no-restricted-syntax": ["error",
|
|
207
|
+
{ "selector": "CallExpression[callee.name='fetch']", "message": "Use Lightning Data Service instead of fetch." },
|
|
208
|
+
{ "selector": "NewExpression[callee.name='XMLHttpRequest']", "message": "Use fetch or LDS." }
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `no-restricted-properties` — ban specific object methods
|
|
216
|
+
|
|
217
|
+
```javascript
|
|
218
|
+
module.exports = [
|
|
219
|
+
{
|
|
220
|
+
files: ["**/lwc/**/*.js"],
|
|
221
|
+
rules: {
|
|
222
|
+
"no-restricted-properties": ["error",
|
|
223
|
+
{ "object": "window", "property": "location", "message": "Use NavigationMixin." },
|
|
224
|
+
{ "object": "document", "property": "cookie", "message": "Cookies are not available in LWC." }
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
];
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
⚠️ **These rules will NOT appear in `sf code-analyzer rules` output until you:**
|
|
232
|
+
1. Create the `eslint.config.js` file with the rule enabled
|
|
233
|
+
2. Set `engines.eslint.eslint_config_file: "eslint.config.js"` in `code-analyzer.yml`
|
|
234
|
+
3. Run `sf code-analyzer rules --rule-selector eslint:no-restricted-globals` to verify
|
|
235
|
+
|
|
236
|
+
They are core ESLint rules, not Code Analyzer built-ins — they require your config to activate.
|
|
237
|
+
|
|
238
|
+
## When to Use ESLint vs Regex vs PMD
|
|
239
|
+
|
|
240
|
+
| Need | Engine |
|
|
241
|
+
|------|--------|
|
|
242
|
+
| JavaScript/TypeScript code patterns | **ESLint** |
|
|
243
|
+
| LWC component best practices | **ESLint** (with @lwc plugin) |
|
|
244
|
+
| HTML template issues | **ESLint** (with SLDS or custom HTML plugin) |
|
|
245
|
+
| Simple string patterns in JS/TS | **ESLint** (Regex cannot distinguish code from comments/strings in JS) |
|
|
246
|
+
| Apex code structure | **PMD** (ESLint doesn't parse Apex) |
|
|
247
|
+
| Metadata XML governance | **PMD** with `language="xml"` |
|