@jterrats/smart-deployment 1.0.3 → 1.0.4

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 (257) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +6 -0
  3. package/lib/ai/wave-validation-service.d.ts +21 -0
  4. package/lib/ai/wave-validation-service.js +189 -114
  5. package/lib/ai/wave-validation-service.js.map +1 -1
  6. package/lib/analysis/analysis-reporter.d.ts +12 -0
  7. package/lib/analysis/analysis-reporter.js +61 -0
  8. package/lib/analysis/analysis-reporter.js.map +1 -1
  9. package/lib/analysis/analyze-artifact-service.d.ts +25 -0
  10. package/lib/analysis/analyze-artifact-service.js +50 -0
  11. package/lib/analysis/analyze-artifact-service.js.map +1 -0
  12. package/lib/analysis/analyze-context-service.d.ts +25 -0
  13. package/lib/analysis/analyze-context-service.js +28 -0
  14. package/lib/analysis/analyze-context-service.js.map +1 -0
  15. package/lib/analysis/project-analysis-service.d.ts +48 -0
  16. package/lib/analysis/project-analysis-service.js +134 -0
  17. package/lib/analysis/project-analysis-service.js.map +1 -0
  18. package/lib/commands/analyze.d.ts +0 -2
  19. package/lib/commands/analyze.js +31 -162
  20. package/lib/commands/analyze.js.map +1 -1
  21. package/lib/commands/config.d.ts +0 -4
  22. package/lib/commands/config.js +25 -95
  23. package/lib/commands/config.js.map +1 -1
  24. package/lib/commands/resume.js +6 -16
  25. package/lib/commands/resume.js.map +1 -1
  26. package/lib/commands/start.d.ts +0 -11
  27. package/lib/commands/start.js +38 -550
  28. package/lib/commands/start.js.map +1 -1
  29. package/lib/commands/status.js +36 -12
  30. package/lib/commands/status.js.map +1 -1
  31. package/lib/commands/validate.d.ts +3 -0
  32. package/lib/commands/validate.js +5 -7
  33. package/lib/commands/validate.js.map +1 -1
  34. package/lib/config/config-mutation-service.d.ts +21 -0
  35. package/lib/config/config-mutation-service.js +61 -0
  36. package/lib/config/config-mutation-service.js.map +1 -0
  37. package/lib/dependencies/circular-dependency-detector.d.ts +5 -0
  38. package/lib/dependencies/circular-dependency-detector.js +67 -72
  39. package/lib/dependencies/circular-dependency-detector.js.map +1 -1
  40. package/lib/dependencies/dependency-depth-calculator.d.ts +28 -0
  41. package/lib/dependencies/dependency-depth-calculator.js +86 -39
  42. package/lib/dependencies/dependency-depth-calculator.js.map +1 -1
  43. package/lib/dependencies/dependency-graph-builder.d.ts +45 -13
  44. package/lib/dependencies/dependency-graph-builder.js +228 -123
  45. package/lib/dependencies/dependency-graph-builder.js.map +1 -1
  46. package/lib/dependencies/dependency-impact-analyzer.d.ts +13 -0
  47. package/lib/dependencies/dependency-impact-analyzer.js +146 -102
  48. package/lib/dependencies/dependency-impact-analyzer.js.map +1 -1
  49. package/lib/dependencies/dependency-merger.d.ts +10 -0
  50. package/lib/dependencies/dependency-merger.js +123 -61
  51. package/lib/dependencies/dependency-merger.js.map +1 -1
  52. package/lib/dependencies/dependency-resolver.d.ts +34 -9
  53. package/lib/dependencies/dependency-resolver.js +181 -112
  54. package/lib/dependencies/dependency-resolver.js.map +1 -1
  55. package/lib/dependencies/dependency-semantics.d.ts +20 -0
  56. package/lib/dependencies/dependency-semantics.js +55 -0
  57. package/lib/dependencies/dependency-semantics.js.map +1 -0
  58. package/lib/dependencies/graph-visualizer.d.ts +6 -1
  59. package/lib/dependencies/graph-visualizer.js +38 -4
  60. package/lib/dependencies/graph-visualizer.js.map +1 -1
  61. package/lib/dependencies/heuristic-inference.d.ts +2 -53
  62. package/lib/dependencies/heuristic-inference.js +8 -317
  63. package/lib/dependencies/heuristic-inference.js.map +1 -1
  64. package/lib/dependencies/heuristic-patterns.d.ts +14 -0
  65. package/lib/dependencies/heuristic-patterns.js +247 -0
  66. package/lib/dependencies/heuristic-patterns.js.map +1 -0
  67. package/lib/deployment/cycle-remediation-runner.d.ts +36 -0
  68. package/lib/deployment/cycle-remediation-runner.js +262 -0
  69. package/lib/deployment/cycle-remediation-runner.js.map +1 -0
  70. package/lib/deployment/deployment-context-service.d.ts +24 -0
  71. package/lib/deployment/deployment-context-service.js +17 -0
  72. package/lib/deployment/deployment-context-service.js.map +1 -0
  73. package/lib/deployment/deployment-runner.d.ts +37 -0
  74. package/lib/deployment/deployment-runner.js +94 -0
  75. package/lib/deployment/deployment-runner.js.map +1 -0
  76. package/lib/deployment/deployment-status-service.d.ts +5 -0
  77. package/lib/deployment/deployment-status-service.js +39 -18
  78. package/lib/deployment/deployment-status-service.js.map +1 -1
  79. package/lib/deployment/deployment-validation-service.d.ts +5 -2
  80. package/lib/deployment/deployment-validation-service.js +48 -45
  81. package/lib/deployment/deployment-validation-service.js.map +1 -1
  82. package/lib/deployment/resume-deployment-service.d.ts +14 -0
  83. package/lib/deployment/resume-deployment-service.js +25 -0
  84. package/lib/deployment/resume-deployment-service.js.map +1 -0
  85. package/lib/deployment/start-execution-service.d.ts +44 -0
  86. package/lib/deployment/start-execution-service.js +94 -0
  87. package/lib/deployment/start-execution-service.js.map +1 -0
  88. package/lib/deployment/test-executor.d.ts +60 -1
  89. package/lib/deployment/test-executor.js +180 -12
  90. package/lib/deployment/test-executor.js.map +1 -1
  91. package/lib/deployment/test-plan-service.d.ts +8 -0
  92. package/lib/deployment/test-plan-service.js +26 -0
  93. package/lib/deployment/test-plan-service.js.map +1 -0
  94. package/lib/deployment/wave-manifest-service.d.ts +11 -0
  95. package/lib/deployment/wave-manifest-service.js +41 -0
  96. package/lib/deployment/wave-manifest-service.js.map +1 -0
  97. package/lib/parsers/apex-class-parser.js +180 -98
  98. package/lib/parsers/apex-class-parser.js.map +1 -1
  99. package/lib/parsers/apex-trigger-parser.js +56 -7
  100. package/lib/parsers/apex-trigger-parser.js.map +1 -1
  101. package/lib/parsers/aura-parser.js +2 -2
  102. package/lib/parsers/aura-parser.js.map +1 -1
  103. package/lib/parsers/bot-parser.js +31 -4
  104. package/lib/parsers/bot-parser.js.map +1 -1
  105. package/lib/parsers/custom-metadata-parser.js +37 -3
  106. package/lib/parsers/custom-metadata-parser.js.map +1 -1
  107. package/lib/parsers/custom-object-parser.js +284 -150
  108. package/lib/parsers/custom-object-parser.js.map +1 -1
  109. package/lib/parsers/email-template-parser.js +115 -58
  110. package/lib/parsers/email-template-parser.js.map +1 -1
  111. package/lib/parsers/flexipage-parser.js +41 -16
  112. package/lib/parsers/flexipage-parser.js.map +1 -1
  113. package/lib/parsers/flow-parser.js +73 -63
  114. package/lib/parsers/flow-parser.js.map +1 -1
  115. package/lib/parsers/genai-prompt-parser.js +16 -4
  116. package/lib/parsers/genai-prompt-parser.js.map +1 -1
  117. package/lib/parsers/layout-parser.d.ts +11 -0
  118. package/lib/parsers/layout-parser.js +143 -68
  119. package/lib/parsers/layout-parser.js.map +1 -1
  120. package/lib/parsers/lwc-parser.d.ts +0 -9
  121. package/lib/parsers/lwc-parser.js +245 -100
  122. package/lib/parsers/lwc-parser.js.map +1 -1
  123. package/lib/parsers/parser-utils.d.ts +3 -0
  124. package/lib/parsers/parser-utils.js +16 -0
  125. package/lib/parsers/parser-utils.js.map +1 -0
  126. package/lib/parsers/permission-set-parser.d.ts +6 -0
  127. package/lib/parsers/permission-set-parser.js +31 -40
  128. package/lib/parsers/permission-set-parser.js.map +1 -1
  129. package/lib/parsers/profile-parser.d.ts +13 -0
  130. package/lib/parsers/profile-parser.js +39 -34
  131. package/lib/parsers/profile-parser.js.map +1 -1
  132. package/lib/parsers/visualforce-parser.js +2 -1
  133. package/lib/parsers/visualforce-parser.js.map +1 -1
  134. package/lib/presentation/analyze-command-presenter.d.ts +10 -0
  135. package/lib/presentation/analyze-command-presenter.js +30 -0
  136. package/lib/presentation/analyze-command-presenter.js.map +1 -0
  137. package/lib/presentation/config-command-presenter.d.ts +15 -0
  138. package/lib/presentation/config-command-presenter.js +50 -0
  139. package/lib/presentation/config-command-presenter.js.map +1 -0
  140. package/lib/presentation/project-analysis-presenter.d.ts +9 -0
  141. package/lib/presentation/project-analysis-presenter.js +9 -0
  142. package/lib/presentation/project-analysis-presenter.js.map +1 -0
  143. package/lib/presentation/resume-command-presenter.d.ts +7 -0
  144. package/lib/presentation/resume-command-presenter.js +12 -0
  145. package/lib/presentation/resume-command-presenter.js.map +1 -0
  146. package/lib/presentation/start-command-presenter.d.ts +15 -0
  147. package/lib/presentation/start-command-presenter.js +29 -0
  148. package/lib/presentation/start-command-presenter.js.map +1 -0
  149. package/lib/presentation/status-command-presenter.d.ts +7 -0
  150. package/lib/presentation/status-command-presenter.js +16 -0
  151. package/lib/presentation/status-command-presenter.js.map +1 -0
  152. package/lib/presentation/validate-command-presenter.d.ts +9 -0
  153. package/lib/presentation/validate-command-presenter.js +50 -0
  154. package/lib/presentation/validate-command-presenter.js.map +1 -0
  155. package/lib/services/metadata-scanner-service.d.ts +8 -12
  156. package/lib/services/metadata-scanner-service.js +55 -533
  157. package/lib/services/metadata-scanner-service.js.map +1 -1
  158. package/lib/services/scanners/automation-ai-metadata-scanner.d.ts +4 -0
  159. package/lib/services/scanners/automation-ai-metadata-scanner.js +61 -0
  160. package/lib/services/scanners/automation-ai-metadata-scanner.js.map +1 -0
  161. package/lib/services/scanners/code-metadata-scanner.d.ts +23 -0
  162. package/lib/services/scanners/code-metadata-scanner.js +149 -0
  163. package/lib/services/scanners/code-metadata-scanner.js.map +1 -0
  164. package/lib/services/scanners/data-metadata-scanner.d.ts +3 -0
  165. package/lib/services/scanners/data-metadata-scanner.js +82 -0
  166. package/lib/services/scanners/data-metadata-scanner.js.map +1 -0
  167. package/lib/services/scanners/experience-metadata-scanner.d.ts +5 -0
  168. package/lib/services/scanners/experience-metadata-scanner.js +123 -0
  169. package/lib/services/scanners/experience-metadata-scanner.js.map +1 -0
  170. package/lib/services/scanners/scanner-runtime.d.ts +11 -0
  171. package/lib/services/scanners/scanner-runtime.js +115 -0
  172. package/lib/services/scanners/scanner-runtime.js.map +1 -0
  173. package/lib/services/scanners/security-metadata-scanner.d.ts +3 -0
  174. package/lib/services/scanners/security-metadata-scanner.js +71 -0
  175. package/lib/services/scanners/security-metadata-scanner.js.map +1 -0
  176. package/lib/types/dependency.d.ts +11 -1
  177. package/lib/types/metadata.d.ts +17 -0
  178. package/lib/types/salesforce/flow/actions.d.ts +108 -0
  179. package/lib/types/salesforce/flow/actions.js +2 -0
  180. package/lib/types/salesforce/flow/actions.js.map +1 -0
  181. package/lib/types/salesforce/flow/common.d.ts +36 -0
  182. package/lib/types/salesforce/flow/common.js +5 -0
  183. package/lib/types/salesforce/flow/common.js.map +1 -0
  184. package/lib/types/salesforce/flow/metadata.d.ts +37 -0
  185. package/lib/types/salesforce/flow/metadata.js +2 -0
  186. package/lib/types/salesforce/flow/metadata.js.map +1 -0
  187. package/lib/types/salesforce/flow/records.d.ts +38 -0
  188. package/lib/types/salesforce/flow/records.js +2 -0
  189. package/lib/types/salesforce/flow/records.js.map +1 -0
  190. package/lib/types/salesforce/flow/resources.d.ts +44 -0
  191. package/lib/types/salesforce/flow/resources.js +2 -0
  192. package/lib/types/salesforce/flow/resources.js.map +1 -0
  193. package/lib/types/salesforce/flow/screens.d.ts +56 -0
  194. package/lib/types/salesforce/flow/screens.js +2 -0
  195. package/lib/types/salesforce/flow/screens.js.map +1 -0
  196. package/lib/types/salesforce/flow/start.d.ts +24 -0
  197. package/lib/types/salesforce/flow/start.js +2 -0
  198. package/lib/types/salesforce/flow/start.js.map +1 -0
  199. package/lib/types/salesforce/flow.d.ts +9 -514
  200. package/lib/types/salesforce/flow.js +1 -1
  201. package/lib/types/salesforce/object/core.d.ts +68 -0
  202. package/lib/types/salesforce/object/core.js +5 -0
  203. package/lib/types/salesforce/object/core.js.map +1 -0
  204. package/lib/types/salesforce/object/field.d.ts +155 -0
  205. package/lib/types/salesforce/object/field.js +5 -0
  206. package/lib/types/salesforce/object/field.js.map +1 -0
  207. package/lib/types/salesforce/object/filter.d.ts +16 -0
  208. package/lib/types/salesforce/object/filter.js +5 -0
  209. package/lib/types/salesforce/object/filter.js.map +1 -0
  210. package/lib/types/salesforce/object/policy.d.ts +27 -0
  211. package/lib/types/salesforce/object/policy.js +5 -0
  212. package/lib/types/salesforce/object/policy.js.map +1 -0
  213. package/lib/types/salesforce/object/record.d.ts +44 -0
  214. package/lib/types/salesforce/object/record.js +5 -0
  215. package/lib/types/salesforce/object/record.js.map +1 -0
  216. package/lib/types/salesforce/object/view.d.ts +71 -0
  217. package/lib/types/salesforce/object/view.js +5 -0
  218. package/lib/types/salesforce/object/view.js.map +1 -0
  219. package/lib/types/salesforce/object/weblink.d.ts +70 -0
  220. package/lib/types/salesforce/object/weblink.js +5 -0
  221. package/lib/types/salesforce/object/weblink.js.map +1 -0
  222. package/lib/types/salesforce/object.d.ts +7 -423
  223. package/lib/types/salesforce/object.js +7 -1
  224. package/lib/types/salesforce/object.js.map +1 -1
  225. package/lib/utils/cache-manager.d.ts +16 -15
  226. package/lib/utils/cache-manager.js +290 -188
  227. package/lib/utils/cache-manager.js.map +1 -1
  228. package/lib/utils/logger.d.ts +8 -0
  229. package/lib/utils/logger.js +82 -69
  230. package/lib/utils/logger.js.map +1 -1
  231. package/lib/validators/xml/xml-reference-rules.d.ts +3 -0
  232. package/lib/validators/xml/xml-reference-rules.js +173 -0
  233. package/lib/validators/xml/xml-reference-rules.js.map +1 -0
  234. package/lib/validators/xml/xml-report-formatter.d.ts +2 -0
  235. package/lib/validators/xml/xml-report-formatter.js +47 -0
  236. package/lib/validators/xml/xml-report-formatter.js.map +1 -0
  237. package/lib/validators/xml/xml-schema-rules.d.ts +3 -0
  238. package/lib/validators/xml/xml-schema-rules.js +75 -0
  239. package/lib/validators/xml/xml-schema-rules.js.map +1 -0
  240. package/lib/validators/xml/xml-validation-types.d.ts +25 -0
  241. package/lib/validators/xml/xml-validation-types.js +2 -0
  242. package/lib/validators/xml/xml-validation-types.js.map +1 -0
  243. package/lib/validators/xml-metadata-validator.d.ts +2 -63
  244. package/lib/validators/xml-metadata-validator.js +7 -338
  245. package/lib/validators/xml-metadata-validator.js.map +1 -1
  246. package/lib/waves/test-optimizer.d.ts +13 -0
  247. package/lib/waves/test-optimizer.js +124 -63
  248. package/lib/waves/test-optimizer.js.map +1 -1
  249. package/lib/waves/wave-builder.d.ts +17 -21
  250. package/lib/waves/wave-builder.js +199 -135
  251. package/lib/waves/wave-builder.js.map +1 -1
  252. package/lib/waves/wave-splitter.d.ts +12 -8
  253. package/lib/waves/wave-splitter.js +156 -115
  254. package/lib/waves/wave-splitter.js.map +1 -1
  255. package/npm-shrinkwrap.json +2 -2
  256. package/oclif.manifest.json +1 -1
  257. package/package.json +1 -1
@@ -10,6 +10,7 @@
10
10
  * @ac US-087-AC-6: Report coverage
11
11
  * @issue #87
12
12
  */
13
+ import type { MetadataComponent } from '../types/metadata.js';
13
14
  import type { Wave } from '../waves/wave-builder.js';
14
15
  import type { TestLevel } from './sf-cli-integration.js';
15
16
  export type TestExecutionPlan = {
@@ -23,6 +24,52 @@ export type TestResults = {
23
24
  coverage?: number;
24
25
  failedTests: string[];
25
26
  };
27
+ export type TestExecutorOptions = {
28
+ availableTestClasses?: string[];
29
+ availableTestComponents?: MetadataComponent[];
30
+ availableComponents?: MetadataComponent[];
31
+ };
32
+ type SfTestFailure = {
33
+ name?: string;
34
+ methodName?: string;
35
+ };
36
+ type SfCodeCoverage = {
37
+ percentage?: number;
38
+ numLinesCovered?: number;
39
+ numLinesUncovered?: number;
40
+ };
41
+ type SfRunTestResult = {
42
+ numTestsRun?: number;
43
+ numFailures?: number;
44
+ failures?: SfTestFailure[];
45
+ codeCoverage?: SfCodeCoverage[];
46
+ codeCoverageWarnings?: Array<{
47
+ message?: string;
48
+ }>;
49
+ summary?: {
50
+ testsRan?: number;
51
+ failRate?: string | number;
52
+ passing?: number;
53
+ failing?: number;
54
+ orgWideCoverage?: string | number;
55
+ testRunCoverage?: string | number;
56
+ };
57
+ };
58
+ type SfDeployResultLike = {
59
+ testsRun?: number;
60
+ testFailures?: number;
61
+ coverage?: number;
62
+ result?: {
63
+ numberTestsTotal?: number;
64
+ numberTestErrors?: number;
65
+ details?: {
66
+ runTestResult?: SfRunTestResult;
67
+ };
68
+ };
69
+ details?: {
70
+ runTestResult?: SfRunTestResult;
71
+ };
72
+ };
26
73
  /**
27
74
  * @ac US-087-AC-1: Run tests only in Apex waves
28
75
  * @ac US-087-AC-2: Support RunLocalTests
@@ -30,12 +77,24 @@ export type TestResults = {
30
77
  * @ac US-087-AC-4: Support NoTestRun (sandbox)
31
78
  */
32
79
  export declare class TestExecutor {
80
+ private readonly availableTestClasses;
81
+ private readonly availableTestCatalog;
82
+ private readonly componentDependencies;
83
+ constructor(options?: TestExecutorOptions);
33
84
  determineTestLevel(wave: Wave, isSandbox: boolean): TestExecutionPlan;
34
85
  private findRelatedTests;
86
+ private getTriggerRelatedDependencies;
87
+ private isTestClass;
88
+ private isKnownOrNamedTestClass;
89
+ private isTestComponent;
90
+ private matchesTestToClass;
91
+ private matchesTestToTrigger;
35
92
  /**
36
93
  * @ac US-087-AC-5: Track test results
37
94
  * @ac US-087-AC-6: Report coverage
38
95
  */
39
- analyzeTestResults(testsRun: number, testFailures: number, coverage?: number): TestResults;
96
+ analyzeTestResults(input: number | SfDeployResultLike, testFailures?: number, coverage?: number): TestResults;
97
+ private resolveCoverage;
40
98
  formatTestResults(results: TestResults): string;
41
99
  }
100
+ export {};
@@ -19,6 +19,26 @@ const logger = getLogger('TestExecutor');
19
19
  * @ac US-087-AC-4: Support NoTestRun (sandbox)
20
20
  */
21
21
  export class TestExecutor {
22
+ availableTestClasses;
23
+ availableTestCatalog;
24
+ componentDependencies;
25
+ constructor(options = {}) {
26
+ this.componentDependencies = new Map((options.availableComponents ?? []).map((component) => [
27
+ `${component.type}:${component.name}`,
28
+ new Set(component.dependencies),
29
+ ]));
30
+ this.availableTestCatalog = (options.availableTestComponents ?? [])
31
+ .filter((component) => component.type === 'ApexClass')
32
+ .filter((component) => this.isTestComponent(component))
33
+ .map((component) => ({
34
+ name: component.name,
35
+ dependencies: new Set(component.dependencies),
36
+ }));
37
+ this.availableTestClasses = Array.from(new Set([
38
+ ...this.availableTestCatalog.map((component) => component.name),
39
+ ...(options.availableTestClasses ?? []),
40
+ ]));
41
+ }
22
42
  determineTestLevel(wave, isSandbox) {
23
43
  // AC-1: Only run tests in Apex waves
24
44
  const hasApex = wave.metadata.types.some((type) => type === 'ApexClass' || type === 'ApexTrigger');
@@ -39,8 +59,19 @@ export class TestExecutor {
39
59
  }
40
60
  // AC-3: Run specified tests if available
41
61
  const apexComponents = wave.components.filter((component) => component.startsWith('ApexClass:') || component.startsWith('ApexTrigger:'));
62
+ const explicitTests = apexComponents
63
+ .filter((component) => component.startsWith('ApexClass:'))
64
+ .map((component) => component.replace('ApexClass:', ''))
65
+ .filter((className) => this.isKnownOrNamedTestClass(className));
66
+ const codeClasses = apexComponents
67
+ .filter((component) => component.startsWith('ApexClass:'))
68
+ .map((component) => component.replace('ApexClass:', ''))
69
+ .filter((className) => !this.isTestClass(className));
70
+ const triggers = apexComponents
71
+ .filter((component) => component.startsWith('ApexTrigger:'))
72
+ .map((component) => component.replace('ApexTrigger:', ''));
42
73
  if (apexComponents.length > 0 && apexComponents.length <= 10) {
43
- const tests = this.findRelatedTests(apexComponents);
74
+ const tests = this.findRelatedTests(codeClasses, triggers, explicitTests);
44
75
  if (tests.length > 0) {
45
76
  return {
46
77
  testLevel: 'RunSpecifiedTests',
@@ -56,26 +87,163 @@ export class TestExecutor {
56
87
  reason: 'Running all local tests',
57
88
  };
58
89
  }
59
- findRelatedTests(apexComponents) {
60
- // Placeholder: In real implementation, this would analyze test classes
61
- // and match them to the components being deployed
62
- return apexComponents
63
- .filter((component) => component.startsWith('ApexClass:'))
64
- .map((component) => component.replace('ApexClass:', '') + 'Test');
90
+ findRelatedTests(codeClasses, triggers, explicitTests) {
91
+ const relatedTests = new Set();
92
+ const candidateTests = new Set([...explicitTests, ...this.availableTestClasses]);
93
+ for (const explicitTest of explicitTests) {
94
+ relatedTests.add(explicitTest);
95
+ }
96
+ for (const codeClass of codeClasses) {
97
+ for (const candidateTest of this.availableTestCatalog) {
98
+ if (candidateTest.dependencies.has(`ApexClass:${codeClass}`)) {
99
+ relatedTests.add(candidateTest.name);
100
+ }
101
+ }
102
+ for (const candidateTest of candidateTests) {
103
+ if (this.matchesTestToClass(codeClass, candidateTest)) {
104
+ relatedTests.add(candidateTest);
105
+ }
106
+ }
107
+ }
108
+ for (const trigger of triggers) {
109
+ const triggerDependencies = this.getTriggerRelatedDependencies(trigger);
110
+ for (const candidateTest of this.availableTestCatalog) {
111
+ if (candidateTest.dependencies.has(`ApexTrigger:${trigger}`)) {
112
+ relatedTests.add(candidateTest.name);
113
+ continue;
114
+ }
115
+ if (triggerDependencies.some((dependency) => candidateTest.dependencies.has(dependency))) {
116
+ relatedTests.add(candidateTest.name);
117
+ }
118
+ }
119
+ for (const candidateTest of candidateTests) {
120
+ if (this.matchesTestToTrigger(trigger, candidateTest)) {
121
+ relatedTests.add(candidateTest);
122
+ }
123
+ }
124
+ }
125
+ if (relatedTests.size === 0) {
126
+ for (const codeClass of codeClasses) {
127
+ relatedTests.add(`${codeClass}Test`);
128
+ relatedTests.add(`${codeClass}Tests`);
129
+ }
130
+ }
131
+ return Array.from(relatedTests);
132
+ }
133
+ getTriggerRelatedDependencies(triggerName) {
134
+ const triggerNodeId = `ApexTrigger:${triggerName}`;
135
+ const dependencies = this.componentDependencies.get(triggerNodeId);
136
+ if (dependencies === undefined) {
137
+ return [];
138
+ }
139
+ return [...dependencies].filter((dependency) => dependency.startsWith('ApexClass:'));
140
+ }
141
+ isTestClass(className) {
142
+ const normalizedName = className.toLowerCase();
143
+ return normalizedName.includes('test') || normalizedName.endsWith('_test');
144
+ }
145
+ isKnownOrNamedTestClass(className) {
146
+ return this.availableTestCatalog.some((component) => component.name === className) || this.isTestClass(className);
147
+ }
148
+ isTestComponent(component) {
149
+ const apexComponent = component;
150
+ return apexComponent.isTest === true || this.isTestClass(component.name);
151
+ }
152
+ matchesTestToClass(className, testClassName) {
153
+ const normalizedClassName = className.toLowerCase();
154
+ const normalizedTestName = testClassName.toLowerCase();
155
+ const strippedTestName = normalizedTestName.replace(/tests?/g, '').replace(/_/g, '');
156
+ const strippedClassName = normalizedClassName.replace(/_/g, '');
157
+ return (normalizedTestName.includes(normalizedClassName) ||
158
+ normalizedTestName.includes(strippedClassName) ||
159
+ strippedTestName.includes(strippedClassName) ||
160
+ strippedClassName.includes(strippedTestName));
161
+ }
162
+ matchesTestToTrigger(triggerName, testClassName) {
163
+ const normalizedTriggerName = triggerName.toLowerCase();
164
+ const normalizedTestName = testClassName.toLowerCase();
165
+ return normalizedTestName.includes(normalizedTriggerName) || normalizedTestName.includes('trigger');
65
166
  }
66
167
  /**
67
168
  * @ac US-087-AC-5: Track test results
68
169
  * @ac US-087-AC-6: Report coverage
69
170
  */
70
- analyzeTestResults(testsRun, testFailures, coverage) {
71
- logger.info('Analyzing test results', { testsRun, testFailures, coverage });
171
+ analyzeTestResults(input, testFailures = 0, coverage) {
172
+ if (typeof input === 'number') {
173
+ logger.info('Analyzing numeric test results', { testsRun: input, testFailures, coverage });
174
+ return {
175
+ testsRun: input,
176
+ testFailures,
177
+ coverage,
178
+ failedTests: [],
179
+ };
180
+ }
181
+ const runTestResult = input.result?.details?.runTestResult ?? input.details?.runTestResult;
182
+ const testsRun = runTestResult?.numTestsRun ??
183
+ runTestResult?.summary?.testsRan ??
184
+ input.result?.numberTestsTotal ??
185
+ input.testsRun ??
186
+ 0;
187
+ const failures = runTestResult?.numFailures ??
188
+ runTestResult?.summary?.failing ??
189
+ input.result?.numberTestErrors ??
190
+ input.testFailures ??
191
+ 0;
192
+ const failedTests = runTestResult?.failures
193
+ ?.map((failure) => failure.name && failure.methodName
194
+ ? `${failure.name}.${failure.methodName}`
195
+ : failure.name ?? failure.methodName)
196
+ .filter((failureName) => failureName !== undefined && failureName !== '') ?? [];
197
+ const resolvedCoverage = this.resolveCoverage(runTestResult) ?? input.coverage ?? coverage;
198
+ logger.info('Analyzing structured test results', {
199
+ testsRun,
200
+ testFailures: failures,
201
+ coverage: resolvedCoverage,
202
+ failedTests: failedTests.length,
203
+ });
72
204
  return {
73
205
  testsRun,
74
- testFailures,
75
- coverage,
76
- failedTests: [], // Would be populated from actual results
206
+ testFailures: failures,
207
+ coverage: resolvedCoverage,
208
+ failedTests,
77
209
  };
78
210
  }
211
+ resolveCoverage(runTestResult) {
212
+ const summaryCoverage = runTestResult?.summary?.orgWideCoverage ?? runTestResult?.summary?.testRunCoverage;
213
+ if (typeof summaryCoverage === 'number') {
214
+ return summaryCoverage;
215
+ }
216
+ if (typeof summaryCoverage === 'string' && summaryCoverage.trim() !== '') {
217
+ const parsedSummaryCoverage = Number(summaryCoverage);
218
+ if (!Number.isNaN(parsedSummaryCoverage)) {
219
+ return parsedSummaryCoverage;
220
+ }
221
+ }
222
+ const coverageEntries = runTestResult?.codeCoverage ?? [];
223
+ if (coverageEntries.length === 0) {
224
+ return undefined;
225
+ }
226
+ let coveredLines = 0;
227
+ let uncoveredLines = 0;
228
+ let percentageEntries = 0;
229
+ let percentageTotal = 0;
230
+ for (const entry of coverageEntries) {
231
+ if (typeof entry.percentage === 'number') {
232
+ percentageEntries++;
233
+ percentageTotal += entry.percentage;
234
+ }
235
+ coveredLines += entry.numLinesCovered ?? 0;
236
+ uncoveredLines += entry.numLinesUncovered ?? 0;
237
+ }
238
+ const totalLines = coveredLines + uncoveredLines;
239
+ if (totalLines > 0) {
240
+ return Math.round((coveredLines / totalLines) * 100);
241
+ }
242
+ if (percentageEntries > 0) {
243
+ return Math.round(percentageTotal / percentageEntries);
244
+ }
245
+ return undefined;
246
+ }
79
247
  formatTestResults(results) {
80
248
  const lines = [`Tests Run: ${results.testsRun}`, `Failures: ${results.testFailures}`];
81
249
  if (results.coverage !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"test-executor.js","sourceRoot":"","sources":["../../src/deployment/test-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;AAezC;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IAChB,kBAAkB,CAAC,IAAU,EAAE,SAAkB;QACtD,qCAAqC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,aAAa,CAAC,CAAC;QAEnG,4BAA4B;QAC5B,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;gBACL,SAAS,EAAE,WAAW;gBACtB,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE,yCAAyC;aAClD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,SAAS,EAAE,WAAW;gBACtB,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE,sBAAsB;aAC/B,CAAC;QACJ,CAAC;QAED,yCAAyC;QACzC,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAC3C,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,cAAc,CAAC,CAC1F,CAAC;QAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;YACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO;oBACL,SAAS,EAAE,mBAAmB;oBAC9B,KAAK;oBACL,MAAM,EAAE,WAAW,KAAK,CAAC,MAAM,gBAAgB;iBAChD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,OAAO;YACL,SAAS,EAAE,eAAe;YAC1B,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,yBAAyB;SAClC,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,cAAwB;QAC/C,uEAAuE;QACvE,kDAAkD;QAClD,OAAO,cAAc;aAClB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;aACzD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,QAAgB,EAAE,YAAoB,EAAE,QAAiB;QACjF,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE5E,OAAO;YACL,QAAQ;YACR,YAAY;YACZ,QAAQ;YACR,WAAW,EAAE,EAAE,EAAE,yCAAyC;SAC3D,CAAC;IACJ,CAAC;IAEM,iBAAiB,CAAC,OAAoB;QAC3C,MAAM,KAAK,GAAG,CAAC,cAAc,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAEtF,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"test-executor.js","sourceRoot":"","sources":["../../src/deployment/test-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { MetadataComponent } from '../types/metadata.js';
2
+ import type { Wave } from '../waves/wave-builder.js';
3
+ import { TestExecutor, type TestExecutionPlan } from './test-executor.js';
4
+ export declare class TestPlanService {
5
+ createExecutor(components: MetadataComponent[]): TestExecutor;
6
+ resolveTestPlan(wave: Wave, skipTests: boolean, testExecutor: TestExecutor): TestExecutionPlan;
7
+ private isTestClassName;
8
+ }
@@ -0,0 +1,26 @@
1
+ import { TestExecutor } from './test-executor.js';
2
+ export class TestPlanService {
3
+ createExecutor(components) {
4
+ const availableTestClasses = components
5
+ .filter((component) => component.type === 'ApexClass')
6
+ .map((component) => component.name)
7
+ .filter((className) => this.isTestClassName(className));
8
+ const availableTestComponents = components.filter((component) => component.type === 'ApexClass');
9
+ return new TestExecutor({ availableTestClasses, availableTestComponents, availableComponents: components });
10
+ }
11
+ resolveTestPlan(wave, skipTests, testExecutor) {
12
+ if (skipTests) {
13
+ return {
14
+ testLevel: 'NoTestRun',
15
+ tests: [],
16
+ reason: 'Tests skipped via --skip-tests',
17
+ };
18
+ }
19
+ return testExecutor.determineTestLevel(wave, false);
20
+ }
21
+ isTestClassName(className) {
22
+ const normalizedName = className.toLowerCase();
23
+ return normalizedName.includes('test') || normalizedName.endsWith('_test');
24
+ }
25
+ }
26
+ //# sourceMappingURL=test-plan-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-plan-service.js","sourceRoot":"","sources":["../../src/deployment/test-plan-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAE1E,MAAM,OAAO,eAAe;IACnB,cAAc,CAAC,UAA+B;QACnD,MAAM,oBAAoB,GAAG,UAAU;aACpC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC;aACrD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;aAClC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,MAAM,uBAAuB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QAEjG,OAAO,IAAI,YAAY,CAAC,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9G,CAAC;IAEM,eAAe,CAAC,IAAU,EAAE,SAAkB,EAAE,YAA0B;QAC/E,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;gBACL,SAAS,EAAE,WAAW;gBACtB,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE,gCAAgC;aACzC,CAAC;QACJ,CAAC;QAED,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;IAEO,eAAe,CAAC,SAAiB;QACvC,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { NodeId } from '../types/dependency.js';
2
+ import type { MetadataComponent } from '../types/metadata.js';
3
+ export type WaveManifestParams = {
4
+ baseDir: string;
5
+ waveNumber: number;
6
+ components: NodeId[];
7
+ componentMap: ReadonlyMap<NodeId, MetadataComponent>;
8
+ };
9
+ export declare class WaveManifestService {
10
+ generateManifest(params: WaveManifestParams): Promise<string>;
11
+ }
@@ -0,0 +1,41 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ export class WaveManifestService {
4
+ async generateManifest(params) {
5
+ const manifestDir = path.join(params.baseDir, '.smart-deployment', 'manifests');
6
+ await mkdir(manifestDir, { recursive: true });
7
+ const grouped = new Map();
8
+ for (const nodeId of params.components) {
9
+ const component = params.componentMap.get(nodeId);
10
+ if (!component) {
11
+ continue;
12
+ }
13
+ if (!grouped.has(component.type)) {
14
+ grouped.set(component.type, new Set());
15
+ }
16
+ grouped.get(component.type).add(component.name);
17
+ }
18
+ const typeBlocks = [...grouped.entries()]
19
+ .sort((a, b) => a[0].localeCompare(b[0]))
20
+ .map(([type, members]) => {
21
+ const memberLines = [...members]
22
+ .sort((left, right) => left.localeCompare(right))
23
+ .map((member) => ` <members>${member}</members>`)
24
+ .join('\n');
25
+ return [' <types>', memberLines, ` <name>${type}</name>`, ' </types>'].join('\n');
26
+ })
27
+ .join('\n');
28
+ const content = [
29
+ '<?xml version="1.0" encoding="UTF-8"?>',
30
+ '<Package xmlns="http://soap.sforce.com/2006/04/metadata">',
31
+ typeBlocks,
32
+ ' <version>61.0</version>',
33
+ '</Package>',
34
+ '',
35
+ ].join('\n');
36
+ const manifestPath = path.join(manifestDir, `wave-${String(params.waveNumber).padStart(3, '0')}.xml`);
37
+ await writeFile(manifestPath, content, 'utf8');
38
+ return manifestPath;
39
+ }
40
+ }
41
+ //# sourceMappingURL=wave-manifest-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wave-manifest-service.js","sourceRoot":"","sources":["../../src/deployment/wave-manifest-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAWlC,MAAM,OAAO,mBAAmB;IACvB,KAAK,CAAC,gBAAgB,CAAC,MAA0B;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,EAAE,WAAW,CAAC,CAAC;QAChF,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAC;QACrD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;YACzC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;aACtC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE;YACvB,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC;iBAC7B,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;iBAChD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,MAAM,YAAY,CAAC;iBACvD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,OAAO,CAAC,aAAa,EAAE,WAAW,EAAE,iBAAiB,IAAI,SAAS,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjG,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG;YACd,wCAAwC;YACxC,2DAA2D;YAC3D,UAAU;YACV,6BAA6B;YAC7B,YAAY;YACZ,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACtG,MAAM,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,YAAY,CAAC;IACtB,CAAC;CACF"}