@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.
Files changed (235) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/skills/agentforce-architecture-analyze/README.md +2 -8
  4. package/skills/agentforce-architecture-analyze/SKILL.md +2 -2
  5. package/skills/agentforce-architecture-analyze/references/contract.json +4 -4
  6. package/skills/agentforce-architecture-analyze/references/soql_fields.md +1 -1
  7. package/skills/data360-activate/README.md +0 -1
  8. package/skills/data360-activate/SKILL.md +0 -2
  9. package/skills/data360-connect/README.md +0 -2
  10. package/skills/data360-connect/SKILL.md +0 -2
  11. package/skills/data360-harmonize/SKILL.md +0 -1
  12. package/skills/data360-orchestrate/README.md +0 -7
  13. package/skills/data360-orchestrate/SKILL.md +0 -2
  14. package/skills/data360-prepare/README.md +0 -1
  15. package/skills/data360-prepare/SKILL.md +0 -1
  16. package/skills/data360-query/README.md +0 -1
  17. package/skills/data360-query/SKILL.md +0 -1
  18. package/skills/data360-segment/README.md +0 -1
  19. package/skills/data360-segment/SKILL.md +0 -2
  20. package/skills/dx-code-analyzer-configure/SKILL.md +31 -13
  21. package/skills/dx-code-analyzer-custom-rule-create/SKILL.md +484 -0
  22. package/skills/dx-code-analyzer-custom-rule-create/assets/pmd-ruleset-template.xml +31 -0
  23. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-fields-api.md +87 -0
  24. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-flows.md +105 -0
  25. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-permissions.md +95 -0
  26. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-examples.md +84 -0
  27. package/skills/dx-code-analyzer-custom-rule-create/examples/regex-examples.md +127 -0
  28. package/skills/dx-code-analyzer-custom-rule-create/examples/xpath-examples.md +227 -0
  29. package/skills/dx-code-analyzer-custom-rule-create/references/advanced-pmd-patterns.md +288 -0
  30. package/skills/dx-code-analyzer-custom-rule-create/references/apex-ast-reference.md +127 -0
  31. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-custom-plugins.md +247 -0
  32. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-rules-discovery.md +188 -0
  33. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier2-configurable.md +114 -0
  34. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier3-custom-plugins.md +113 -0
  35. package/skills/dx-code-analyzer-custom-rule-create/references/metadata-xml-rules.md +285 -0
  36. package/skills/dx-code-analyzer-custom-rule-create/references/regex-rule-schema.md +174 -0
  37. package/skills/dx-code-analyzer-custom-rule-create/references/troubleshooting.md +141 -0
  38. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-governor-limits.md +83 -0
  39. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-method-calls.md +108 -0
  40. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-security.md +45 -0
  41. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-structure.md +127 -0
  42. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns.md +131 -0
  43. package/skills/dx-code-analyzer-custom-rule-create/scripts/create-pmd-rule.js +209 -0
  44. package/skills/dx-code-analyzer-custom-rule-create/scripts/create-regex-rule.js +220 -0
  45. package/skills/dx-code-analyzer-run/SKILL.md +41 -8
  46. package/skills/experience-cms-brand-apply/SKILL.md +47 -16
  47. package/skills/experience-lwc-generate/README.md +3 -2
  48. package/skills/experience-lwc-generate/references/async-notification-patterns.md +1 -1
  49. package/skills/experience-lwc-generate/references/component-patterns.md +3 -3
  50. package/skills/experience-lwc-generate/references/flow-integration-guide.md +1 -1
  51. package/skills/experience-lwc-generate/references/lwc-best-practices.md +4 -4
  52. package/skills/experience-lwc-generate/references/scoring-and-testing.md +1 -1
  53. package/skills/experience-lwc-generate/references/state-management.md +2 -2
  54. package/skills/experience-lwc-generate/references/triangle-pattern.md +3 -3
  55. package/skills/experience-lwc-generate/scripts/post-tool-validate.py +2 -2
  56. package/skills/experience-lwc-generate/scripts/template_validator.py +1 -1
  57. package/skills/external-diagram-mermaid-generate/README.md +2 -2
  58. package/skills/external-diagram-mermaid-generate/SKILL.md +1 -3
  59. package/skills/external-diagram-mermaid-generate/assets/agentforce/agent-flow.md +4 -4
  60. package/skills/external-diagram-mermaid-generate/assets/architecture/system-landscape.md +1 -1
  61. package/skills/external-diagram-mermaid-generate/assets/datamodel/b2b-commerce-erd.md +3 -3
  62. package/skills/external-diagram-mermaid-generate/assets/datamodel/campaigns-erd.md +1 -1
  63. package/skills/external-diagram-mermaid-generate/assets/datamodel/consent-erd.md +2 -2
  64. package/skills/external-diagram-mermaid-generate/assets/datamodel/files-erd.md +2 -2
  65. package/skills/external-diagram-mermaid-generate/assets/datamodel/forecasting-erd.md +2 -2
  66. package/skills/external-diagram-mermaid-generate/assets/datamodel/fsl-erd.md +2 -2
  67. package/skills/external-diagram-mermaid-generate/assets/datamodel/party-model-erd.md +1 -1
  68. package/skills/external-diagram-mermaid-generate/assets/datamodel/quote-order-erd.md +3 -3
  69. package/skills/external-diagram-mermaid-generate/assets/datamodel/revenue-cloud-erd.md +2 -2
  70. package/skills/external-diagram-mermaid-generate/assets/datamodel/sales-cloud-erd.md +1 -1
  71. package/skills/external-diagram-mermaid-generate/assets/datamodel/salesforce-erd.md +1 -1
  72. package/skills/external-diagram-mermaid-generate/assets/datamodel/scheduler-erd.md +2 -2
  73. package/skills/external-diagram-mermaid-generate/assets/datamodel/service-cloud-erd.md +3 -3
  74. package/skills/external-diagram-mermaid-generate/assets/datamodel/territory-management-erd.md +1 -1
  75. package/skills/external-diagram-mermaid-generate/assets/integration/api-sequence.md +1 -1
  76. package/skills/external-diagram-mermaid-generate/assets/oauth/authorization-code-pkce.md +1 -1
  77. package/skills/external-diagram-mermaid-generate/assets/oauth/authorization-code.md +1 -1
  78. package/skills/external-diagram-mermaid-generate/assets/oauth/client-credentials.md +1 -1
  79. package/skills/external-diagram-mermaid-generate/assets/oauth/device-authorization.md +2 -2
  80. package/skills/external-diagram-mermaid-generate/assets/oauth/jwt-bearer.md +2 -2
  81. package/skills/external-diagram-mermaid-generate/assets/oauth/refresh-token.md +1 -1
  82. package/skills/external-diagram-mermaid-generate/assets/oauth/user-agent-social-sign-on.md +2 -2
  83. package/skills/external-diagram-mermaid-generate/assets/role-hierarchy/user-hierarchy.md +1 -1
  84. package/skills/external-diagram-mermaid-generate/references/color-palette.md +13 -13
  85. package/skills/external-diagram-mermaid-generate/references/diagram-conventions.md +5 -5
  86. package/skills/external-diagram-mermaid-generate/references/erd-conventions.md +1 -1
  87. package/skills/external-diagram-mermaid-generate/references/mermaid-styling.md +2 -2
  88. package/skills/external-diagram-mermaid-generate/references/preview-guide.md +1 -1
  89. package/skills/external-diagram-mermaid-generate/references/usage-examples.md +9 -9
  90. package/skills/external-diagram-mermaid-generate/scripts/README.md +1 -1
  91. package/skills/integration-connectivity-connected-app-configure/README.md +4 -5
  92. package/skills/integration-connectivity-connected-app-configure/SKILL.md +2 -2
  93. package/skills/integration-connectivity-connected-app-configure/references/example-usage.md +7 -7
  94. package/skills/integration-connectivity-connected-app-configure/references/migration-guide.md +1 -1
  95. package/skills/integration-connectivity-connected-app-configure/references/oauth-flows-reference.md +1 -1
  96. package/skills/integration-connectivity-connected-app-configure/references/testing-validation-guide.md +3 -3
  97. package/skills/integration-connectivity-generate/README.md +1 -1
  98. package/skills/integration-connectivity-generate/SKILL.md +6 -0
  99. package/skills/integration-connectivity-generate/assets/callouts/rest-queueable-callout.cls +1 -1
  100. package/skills/integration-connectivity-generate/assets/external-services/external-service-operations.md +1 -1
  101. package/skills/integration-connectivity-generate/assets/soap/wsdl2apex-guide.md +1 -1
  102. package/skills/integration-connectivity-generate/references/callout-patterns.md +4 -0
  103. package/skills/integration-connectivity-generate/references/cdc-guide.md +2 -2
  104. package/skills/integration-connectivity-generate/references/event-driven-architecture-guide.md +5 -5
  105. package/skills/integration-connectivity-generate/references/event-patterns.md +3 -2
  106. package/skills/integration-connectivity-generate/references/external-services-guide.md +4 -1
  107. package/skills/integration-connectivity-generate/references/messaging-api-v2.md +2 -2
  108. package/skills/integration-connectivity-generate/references/named-credentials-automation.md +1 -1
  109. package/skills/integration-connectivity-generate/references/named-credentials-guide.md +12 -2
  110. package/skills/integration-connectivity-generate/references/platform-events-guide.md +3 -3
  111. package/skills/integration-connectivity-generate/references/rest-callout-patterns.md +1 -1
  112. package/skills/integration-connectivity-generate/references/scoring-rubric.md +1 -1
  113. package/skills/integration-connectivity-generate/references/security-best-practices.md +5 -2
  114. package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +16 -5
  115. package/skills/integration-connectivity-generate/scripts/set-api-credential.sh +11 -2
  116. package/skills/integration-connectivity-generate/scripts/suggest_credential_setup.py +4 -3
  117. package/skills/integration-connectivity-generate/scripts/validate_integration.py +1 -1
  118. package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +3 -3
  119. package/skills/omnistudio-callable-apex-generate/README.md +1 -5
  120. package/skills/omnistudio-callable-apex-generate/SKILL.md +14 -4
  121. package/skills/omnistudio-callable-apex-generate/assets/pattern_callable_vanilla.cls +8 -1
  122. package/skills/omnistudio-callable-apex-generate/examples/Test_VlocityOpenInterface2Conversion/TRANSCRIPT.md +1 -1
  123. package/skills/omnistudio-callable-apex-generate/examples/Test_VlocityOpenInterfaceConversion/TRANSCRIPT.md +1 -1
  124. package/skills/omnistudio-datamapper-generate/SKILL.md +1 -1
  125. package/skills/omnistudio-datamapper-generate/assets/completion-summary-template.md +2 -2
  126. package/skills/omnistudio-datamapper-generate/references/best-practices.md +9 -9
  127. package/skills/omnistudio-datamapper-generate/references/naming-conventions.md +6 -6
  128. package/skills/omnistudio-datapacks-deploy/README.md +1 -1
  129. package/skills/omnistudio-datapacks-deploy/examples/business-internet-plus-bundle/deploy-business-internet-plus-bundle.yaml +1 -1
  130. package/skills/omnistudio-dependencies-analyze/SKILL.md +12 -5
  131. package/skills/omnistudio-dependencies-analyze/references/dependency-patterns.md +9 -9
  132. package/skills/omnistudio-dependencies-analyze/references/namespace-guide.md +1 -1
  133. package/skills/omnistudio-epc-catalog-generate/README.md +1 -1
  134. package/skills/omnistudio-flexcard-generate/SKILL.md +11 -4
  135. package/skills/omnistudio-flexcard-generate/references/best-practices.md +6 -6
  136. package/skills/omnistudio-flexcard-generate/references/data-binding-guide.md +9 -9
  137. package/skills/omnistudio-integration-procedure-generate/SKILL.md +9 -1
  138. package/skills/omnistudio-integration-procedure-generate/references/element-types.md +3 -3
  139. package/skills/omnistudio-omniscript-generate/SKILL.md +2 -2
  140. package/skills/omnistudio-omniscript-generate/references/best-practices.md +1 -1
  141. package/skills/omnistudio-omniscript-generate/scripts/check-duplicate-omniscript.sh +8 -0
  142. package/skills/omnistudio-omniscript-generate/scripts/deploy-omniscript.sh +8 -0
  143. package/skills/platform-apex-logs-debug/README.md +2 -2
  144. package/skills/platform-apex-logs-debug/references/cli-commands.md +2 -2
  145. package/skills/platform-apex-logs-debug/references/debug-log-reference.md +16 -16
  146. package/skills/platform-apex-logs-debug/references/log-analysis-tools.md +2 -2
  147. package/skills/platform-apex-test-run/README.md +1 -1
  148. package/skills/platform-apex-test-run/references/test-fix-loop.md +2 -2
  149. package/skills/platform-apex-test-run/references/testing-best-practices.md +3 -3
  150. package/skills/platform-custom-field-generate/SKILL.md +86 -126
  151. package/skills/platform-custom-field-generate/references/advanced-picklists.md +590 -0
  152. package/skills/platform-data-manage/README.md +4 -4
  153. package/skills/platform-data-manage/references/bulk-testing-example.md +1 -1
  154. package/skills/platform-data-manage/references/crud-workflow-example.md +2 -2
  155. package/skills/platform-data-manage/references/orchestration.md +6 -6
  156. package/skills/platform-flexipage-generate/SKILL.md +281 -346
  157. package/skills/platform-flexipage-generate/references/cli_commands.md +39 -0
  158. package/skills/platform-flexipage-generate/references/flexipage_fieldSection.md +162 -0
  159. package/skills/platform-flexipage-generate/references/flexipage_richText.md +84 -0
  160. package/skills/platform-flexipage-generate/references/identifiers_and_regions.md +167 -0
  161. package/skills/platform-flexipage-generate/references/mcp_action_examples.md +104 -0
  162. package/skills/platform-flexipage-generate/references/record_flexipage_dynamicHighlights.md +119 -0
  163. package/skills/platform-flexipage-generate/references/xml_rules.md +335 -0
  164. package/skills/platform-flexipage-generate/scripts/resolve-component-instructions.sh +42 -0
  165. package/skills/platform-flexipage-generate/scripts/scan-lwc-components.sh +113 -0
  166. package/skills/platform-metadata-deploy/README.md +2 -2
  167. package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +2 -2
  168. package/skills/platform-metadata-deploy/references/deployment-workflows.md +16 -16
  169. package/skills/platform-metadata-deploy/references/orchestration.md +3 -3
  170. package/skills/platform-metadata-deploy/references/trigger-deployment-safety.md +2 -2
  171. package/skills/platform-models-api-configure/SKILL.md +140 -0
  172. package/skills/platform-models-api-configure/scripts/get-orgjwt.sh +48 -0
  173. package/skills/platform-policy-rule-generate/SKILL.md +260 -0
  174. package/skills/platform-policy-rule-generate/references/deploy-errors.md +54 -0
  175. package/skills/platform-policy-rule-generate/references/fixtures-index.md +29 -0
  176. package/skills/platform-policy-rule-generate/references/policy-schema-full.md +250 -0
  177. package/skills/platform-policy-rule-generate/references/templates-access.md +132 -0
  178. package/skills/platform-policy-rule-generate/references/templates-advanced.md +58 -0
  179. package/skills/platform-policy-rule-generate/references/templates-record.md +75 -0
  180. package/skills/platform-policy-rule-generate/references/templates-transform.md +70 -0
  181. package/skills/platform-policy-rule-generate/references/templates.md +10 -0
  182. package/skills/platform-policy-rule-generate/references/ui-compatibility.md +142 -0
  183. package/skills/platform-soql-query/README.md +1 -1
  184. package/skills/platform-soql-query/SKILL.md +1 -1
  185. package/skills/platform-soql-query/references/anti-patterns.md +1 -1
  186. package/skills/platform-soql-query/references/field-coverage-rules.md +1 -1
  187. package/skills/platform-soql-query/references/query-optimization.md +1 -1
  188. package/skills/platform-soql-query/scripts/post-tool-validate.py +3 -3
  189. package/skills/platform-value-set-generate/SKILL.md +305 -0
  190. package/skills/data360-activate/CREDITS.md +0 -5
  191. package/skills/data360-connect/CREDITS.md +0 -5
  192. package/skills/data360-harmonize/CREDITS.md +0 -3
  193. package/skills/data360-orchestrate/CREDITS.md +0 -15
  194. package/skills/data360-orchestrate/UPSTREAM.md +0 -45
  195. package/skills/data360-prepare/CREDITS.md +0 -7
  196. package/skills/data360-query/CREDITS.md +0 -7
  197. package/skills/data360-segment/CREDITS.md +0 -3
  198. package/skills/experience-lwc-generate/CREDITS.md +0 -5
  199. package/skills/external-diagram-mermaid-generate/CREDITS.md +0 -46
  200. package/skills/external-diagram-visual-generate/CREDITS.md +0 -80
  201. package/skills/external-diagram-visual-generate/README.md +0 -83
  202. package/skills/external-diagram-visual-generate/SKILL.md +0 -207
  203. package/skills/external-diagram-visual-generate/assets/architecture/integration-flow.md +0 -55
  204. package/skills/external-diagram-visual-generate/assets/erd/core-objects.md +0 -131
  205. package/skills/external-diagram-visual-generate/assets/erd/custom-objects.md +0 -60
  206. package/skills/external-diagram-visual-generate/assets/lwc/dashboard-card.md +0 -45
  207. package/skills/external-diagram-visual-generate/assets/lwc/data-table.md +0 -57
  208. package/skills/external-diagram-visual-generate/assets/lwc/record-form.md +0 -60
  209. package/skills/external-diagram-visual-generate/assets/review/apex-review.md +0 -57
  210. package/skills/external-diagram-visual-generate/assets/review/lwc-review.md +0 -48
  211. package/skills/external-diagram-visual-generate/references/architect-aesthetic-guide.md +0 -257
  212. package/skills/external-diagram-visual-generate/references/examples-index.md +0 -35
  213. package/skills/external-diagram-visual-generate/references/gemini-cli-setup.md +0 -65
  214. package/skills/external-diagram-visual-generate/references/interview-questions.md +0 -529
  215. package/skills/external-diagram-visual-generate/references/iteration-workflow.md +0 -173
  216. package/skills/external-diagram-visual-generate/scripts/check-prerequisites.sh +0 -101
  217. package/skills/external-diagram-visual-generate/scripts/generate_image.py +0 -243
  218. package/skills/integration-connectivity-connected-app-configure/CREDITS.md +0 -3
  219. package/skills/integration-connectivity-generate/CREDITS.md +0 -5
  220. package/skills/omnistudio-callable-apex-generate/CREDITS.md +0 -9
  221. package/skills/omnistudio-datamapper-generate/CREDITS.md +0 -5
  222. package/skills/omnistudio-datapacks-deploy/CREDITS.md +0 -5
  223. package/skills/omnistudio-dependencies-analyze/CREDITS.md +0 -5
  224. package/skills/omnistudio-epc-catalog-generate/CREDITS.md +0 -14
  225. package/skills/omnistudio-flexcard-generate/CREDITS.md +0 -5
  226. package/skills/omnistudio-integration-procedure-generate/CREDITS.md +0 -5
  227. package/skills/omnistudio-omniscript-generate/CREDITS.md +0 -5
  228. package/skills/platform-apex-generate/CREDITS.md +0 -5
  229. package/skills/platform-apex-logs-debug/CREDITS.md +0 -22
  230. package/skills/platform-apex-test-generate/CREDITS.md +0 -5
  231. package/skills/platform-apex-test-run/CREDITS.md +0 -22
  232. package/skills/platform-data-manage/CREDITS.md +0 -5
  233. package/skills/platform-metadata-deploy/CREDITS.md +0 -25
  234. package/skills/platform-soql-query/CREDITS.md +0 -21
  235. /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"` |