@jterrats/smart-deployment 1.3.1 → 1.4.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 (98) hide show
  1. package/README.md +38 -0
  2. package/lib/analysis/metadata-capability-definitions.d.ts +2 -0
  3. package/lib/analysis/metadata-capability-definitions.js +260 -0
  4. package/lib/analysis/metadata-capability-definitions.js.map +1 -0
  5. package/lib/analysis/metadata-capability-registry.d.ts +11 -0
  6. package/lib/analysis/metadata-capability-registry.js +142 -0
  7. package/lib/analysis/metadata-capability-registry.js.map +1 -0
  8. package/lib/analysis/metadata-gap-analysis-service.d.ts +51 -0
  9. package/lib/analysis/metadata-gap-analysis-service.js +277 -0
  10. package/lib/analysis/metadata-gap-analysis-service.js.map +1 -0
  11. package/lib/commands/ci-publish.d.ts +6 -2
  12. package/lib/commands/ci-publish.js +23 -8
  13. package/lib/commands/ci-publish.js.map +1 -1
  14. package/lib/commands/metadata/gaps.d.ts +15 -0
  15. package/lib/commands/metadata/gaps.js +84 -0
  16. package/lib/commands/metadata/gaps.js.map +1 -0
  17. package/lib/commands/resume.js +5 -4
  18. package/lib/commands/resume.js.map +1 -1
  19. package/lib/commands/start.d.ts +6 -0
  20. package/lib/commands/start.js +43 -14
  21. package/lib/commands/start.js.map +1 -1
  22. package/lib/commands/status.js +5 -2
  23. package/lib/commands/status.js.map +1 -1
  24. package/lib/commands/validate.d.ts +7 -0
  25. package/lib/commands/validate.js +24 -2
  26. package/lib/commands/validate.js.map +1 -1
  27. package/lib/constants/deployment-order.js +1 -0
  28. package/lib/constants/deployment-order.js.map +1 -1
  29. package/lib/deployment/commit-scope-service.d.ts +7 -0
  30. package/lib/deployment/commit-scope-service.js +104 -21
  31. package/lib/deployment/commit-scope-service.js.map +1 -1
  32. package/lib/deployment/deployment-runner.d.ts +1 -1
  33. package/lib/deployment/deployment-runner.js +23 -22
  34. package/lib/deployment/deployment-runner.js.map +1 -1
  35. package/lib/deployment/deployment-status-service.d.ts +8 -7
  36. package/lib/deployment/deployment-status-service.js +45 -27
  37. package/lib/deployment/deployment-status-service.js.map +1 -1
  38. package/lib/deployment/deployment-validation-service.d.ts +2 -0
  39. package/lib/deployment/deployment-validation-service.js +2 -0
  40. package/lib/deployment/deployment-validation-service.js.map +1 -1
  41. package/lib/deployment/resume-deployment-service.d.ts +5 -4
  42. package/lib/deployment/resume-deployment-service.js +18 -21
  43. package/lib/deployment/resume-deployment-service.js.map +1 -1
  44. package/lib/deployment/sf-cli-integration.d.ts +5 -2
  45. package/lib/deployment/sf-cli-integration.js +26 -14
  46. package/lib/deployment/sf-cli-integration.js.map +1 -1
  47. package/lib/deployment/special-deployment-plan.js +36 -49
  48. package/lib/deployment/special-deployment-plan.js.map +1 -1
  49. package/lib/deployment/start-execution-service.js +1 -1
  50. package/lib/deployment/start-execution-service.js.map +1 -1
  51. package/lib/presentation/release-report-presenter.d.ts +10 -0
  52. package/lib/presentation/release-report-presenter.js +35 -0
  53. package/lib/presentation/release-report-presenter.js.map +1 -0
  54. package/lib/presentation/validate-command-presenter.js +13 -0
  55. package/lib/presentation/validate-command-presenter.js.map +1 -1
  56. package/lib/reports/release-report-builder.d.ts +6 -0
  57. package/lib/reports/release-report-builder.js +115 -0
  58. package/lib/reports/release-report-builder.js.map +1 -0
  59. package/lib/reports/release-report-command-adapter.d.ts +14 -0
  60. package/lib/reports/release-report-command-adapter.js +28 -0
  61. package/lib/reports/release-report-command-adapter.js.map +1 -0
  62. package/lib/reports/release-report-facts-factory.d.ts +14 -0
  63. package/lib/reports/release-report-facts-factory.js +140 -0
  64. package/lib/reports/release-report-facts-factory.js.map +1 -0
  65. package/lib/reports/release-report-sanitizer.d.ts +5 -0
  66. package/lib/reports/release-report-sanitizer.js +120 -0
  67. package/lib/reports/release-report-sanitizer.js.map +1 -0
  68. package/lib/reports/release-report-service.d.ts +43 -0
  69. package/lib/reports/release-report-service.js +80 -0
  70. package/lib/reports/release-report-service.js.map +1 -0
  71. package/lib/reports/release-report-store.d.ts +30 -0
  72. package/lib/reports/release-report-store.js +57 -0
  73. package/lib/reports/release-report-store.js.map +1 -0
  74. package/lib/reports/start-release-report-coordinator.d.ts +15 -0
  75. package/lib/reports/start-release-report-coordinator.js +23 -0
  76. package/lib/reports/start-release-report-coordinator.js.map +1 -0
  77. package/lib/services/metadata-scanner-service.js +12 -2
  78. package/lib/services/metadata-scanner-service.js.map +1 -1
  79. package/lib/services/scanners/automation-ai-metadata-scanner.d.ts +2 -1
  80. package/lib/services/scanners/automation-ai-metadata-scanner.js +48 -0
  81. package/lib/services/scanners/automation-ai-metadata-scanner.js.map +1 -1
  82. package/lib/types/index.d.ts +2 -0
  83. package/lib/types/index.js +2 -0
  84. package/lib/types/index.js.map +1 -1
  85. package/lib/types/metadata-capability.d.ts +39 -0
  86. package/lib/types/metadata-capability.js +2 -0
  87. package/lib/types/metadata-capability.js.map +1 -0
  88. package/lib/types/metadata.d.ts +7 -1
  89. package/lib/types/release-report.d.ts +89 -0
  90. package/lib/types/release-report.js +42 -0
  91. package/lib/types/release-report.js.map +1 -0
  92. package/messages/metadata.gaps.json +12 -0
  93. package/messages/start.json +2 -0
  94. package/messages/validate.json +3 -1
  95. package/npm-shrinkwrap.json +417 -901
  96. package/oclif.lock +415 -718
  97. package/oclif.manifest.json +93 -10
  98. package/package.json +18 -14
@@ -0,0 +1,14 @@
1
+ import type { DeploymentValidationSummary } from '../deployment/deployment-validation-service.js';
2
+ import type { DeploymentContext } from '../deployment/deployment-context-service.js';
3
+ import type { SpecialDeploymentExecutionResult } from '../deployment/special-deployment-executor.js';
4
+ import type { SpecialDeploymentPlan } from '../deployment/special-deployment-plan.js';
5
+ import type { ReleaseReportFacts } from '../types/release-report.js';
6
+ export declare function buildCiPublishReportFacts(plan: SpecialDeploymentPlan, execution?: SpecialDeploymentExecutionResult): ReleaseReportFacts;
7
+ export declare function buildValidationReportFacts(summary: DeploymentValidationSummary, targetOrg: string | undefined, useAI: boolean): ReleaseReportFacts;
8
+ export declare function buildStartReportFacts(context: DeploymentContext, options: {
9
+ targetOrg?: string;
10
+ dryRun: boolean;
11
+ validateOnly: boolean;
12
+ failed?: boolean;
13
+ warning?: string;
14
+ }): ReleaseReportFacts;
@@ -0,0 +1,140 @@
1
+ export function buildCiPublishReportFacts(plan, execution) {
2
+ const phases = plan.phases.map((phase) => toSpecialPhaseFact(phase, plan, execution));
3
+ const statusByPhase = new Map(phases.map((phase) => [phase.id, phase.status]));
4
+ return {
5
+ command: 'smart-deployment ci-publish',
6
+ targetOrg: plan.targetOrg,
7
+ analysisMode: 'deterministic',
8
+ enrichment: { status: 'skipped' },
9
+ outcome: execution ? (execution.success ? 'succeeded' : 'failed') : plan.success ? 'skipped' : 'failed',
10
+ phases,
11
+ items: plan.phases.flatMap((phase) => phase.components.map((component) => toItem(component, phase.kind, operationForPhase(phase.kind), routeForPhase(phase.kind), statusByPhase.get(phase.kind), plan.targetOrg))),
12
+ reportWarnings: [...plan.warnings, ...plan.errors],
13
+ };
14
+ }
15
+ export function buildValidationReportFacts(summary, targetOrg, useAI) {
16
+ const status = summary.valid ? 'succeeded' : 'needs_review';
17
+ return {
18
+ command: 'smart-deployment validate',
19
+ targetOrg,
20
+ analysisMode: summary.aiAnalyzed ? 'ai_enriched' : 'deterministic',
21
+ enrichment: {
22
+ status: summary.aiAnalyzed ? 'available' : useAI ? 'unavailable' : 'skipped',
23
+ warnings: useAI && !summary.aiAnalyzed
24
+ ? ['AI validation unavailable; deterministic validation was retained.']
25
+ : undefined,
26
+ },
27
+ outcome: summary.valid ? 'succeeded' : 'failed',
28
+ phases: [
29
+ {
30
+ id: 'validation',
31
+ route: 'validation',
32
+ operation: 'validate',
33
+ status,
34
+ remediation: summary.issues.map((issue) => issue.message),
35
+ },
36
+ ],
37
+ items: summary.componentIds.map((component) => toItem(component, 'validation', 'validate', 'validation', status, targetOrg)),
38
+ reportWarnings: summary.issues.map((issue) => issue.message),
39
+ };
40
+ }
41
+ export function buildStartReportFacts(context, options) {
42
+ const operation = options.validateOnly ? 'validate' : 'deploy';
43
+ const status = options.failed ? 'failed' : options.dryRun ? 'skipped' : 'succeeded';
44
+ const phaseId = options.validateOnly ? 'validation' : 'core-metadata';
45
+ const route = options.validateOnly ? 'validation' : 'salesforce-metadata';
46
+ const aiContext = context.aiContext;
47
+ const isAIEnriched = aiContext?.enabled === true && aiContext.fallback !== true && aiContext.inferenceFallback !== true;
48
+ return {
49
+ command: 'smart-deployment start',
50
+ targetOrg: options.targetOrg,
51
+ analysisMode: isAIEnriched ? 'ai_enriched' : 'deterministic',
52
+ enrichment: {
53
+ status: isAIEnriched ? 'available' : aiContext?.enabled ? 'partial' : 'skipped',
54
+ warnings: aiContext?.enabled && !isAIEnriched
55
+ ? ['AI enrichment was partial; deterministic planning was retained.']
56
+ : undefined,
57
+ },
58
+ outcome: options.failed ? 'failed' : options.dryRun ? 'skipped' : 'succeeded',
59
+ phases: [
60
+ {
61
+ id: phaseId,
62
+ route,
63
+ operation,
64
+ status,
65
+ remediation: options.warning ? [options.warning] : undefined,
66
+ },
67
+ ],
68
+ items: context.scanResult.components.map((component) => ({
69
+ phaseId,
70
+ metadataType: component.type,
71
+ fullName: component.name,
72
+ route,
73
+ operation,
74
+ status,
75
+ targetOrg: options.targetOrg,
76
+ })),
77
+ reportWarnings: options.warning ? [options.warning] : undefined,
78
+ };
79
+ }
80
+ function toSpecialPhaseFact(phase, plan, execution) {
81
+ const status = specialPhaseStatus(phase, plan, execution);
82
+ const commandResults = execution?.commands.filter((result) => result.phaseKind === phase.kind) ?? [];
83
+ return {
84
+ id: phase.kind,
85
+ route: routeForPhase(phase.kind),
86
+ operation: operationForPhase(phase.kind),
87
+ status,
88
+ evidence: phase.commands.map((command, index) => {
89
+ const result = commandResults[index];
90
+ return {
91
+ tool: command.tool,
92
+ operationId: `${phase.kind}:${index + 1}`,
93
+ exitCode: result?.exitCode ?? (result?.success ? 0 : undefined),
94
+ };
95
+ }),
96
+ remediation: [...(phase.errors ?? []), ...(phase.warnings ?? []), ...(phase.skipReason ? [phase.skipReason] : [])],
97
+ };
98
+ }
99
+ function specialPhaseStatus(phase, plan, execution) {
100
+ if ((phase.errors?.length ?? 0) > 0 || execution?.failedPhase === phase.kind)
101
+ return 'failed';
102
+ if (phase.skipped || execution?.skippedPhases.includes(phase.kind))
103
+ return 'skipped';
104
+ if (!execution)
105
+ return plan.dryRun ? 'skipped' : 'unknown';
106
+ if (execution.completedPhases.includes(phase.kind))
107
+ return 'succeeded';
108
+ return execution.success ? 'succeeded' : 'skipped';
109
+ }
110
+ function routeForPhase(kind) {
111
+ const routes = {
112
+ 'core-metadata': 'salesforce-metadata',
113
+ 'agentforce-publish': 'agentforce',
114
+ 'agentforce-activate': 'agentforce',
115
+ 'ai-evaluations': 'ai-evaluation',
116
+ 'community-publish': 'experience-cloud',
117
+ 'omnistudio-vlocity': 'omnistudio',
118
+ };
119
+ return routes[kind];
120
+ }
121
+ function operationForPhase(kind) {
122
+ if (kind === 'agentforce-activate')
123
+ return 'activate';
124
+ if (kind === 'agentforce-publish' || kind === 'community-publish' || kind === 'omnistudio-vlocity')
125
+ return 'publish';
126
+ return 'deploy';
127
+ }
128
+ function toItem(component, phaseId, operation, route, status, targetOrg) {
129
+ const separator = component.indexOf(':');
130
+ return {
131
+ phaseId,
132
+ metadataType: separator > 0 ? component.slice(0, separator) : 'Unknown',
133
+ fullName: separator > 0 ? component.slice(separator + 1) : component,
134
+ route,
135
+ operation,
136
+ status: status ?? 'unknown',
137
+ targetOrg,
138
+ };
139
+ }
140
+ //# sourceMappingURL=release-report-facts-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-report-facts-factory.js","sourceRoot":"","sources":["../../src/reports/release-report-facts-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ReleaseReportV1 } from '../types/release-report.js';
2
+ export type ReleaseReportSanitizerOptions = {
3
+ projectRoot?: string;
4
+ };
5
+ export declare function sanitizeReleaseReport(report: ReleaseReportV1, options?: ReleaseReportSanitizerOptions): ReleaseReportV1;
@@ -0,0 +1,120 @@
1
+ import * as path from 'node:path';
2
+ const ANSI_SEQUENCE = new RegExp(`${String.fromCharCode(27)}(?:\\][^${String.fromCharCode(7)}]*(?:${String.fromCharCode(7)}|${String.fromCharCode(27)}\\\\)|\\[[0-?]*[ -/]*[@-~])`, 'gu');
3
+ const CONTROL_CHARACTER = new RegExp(`[${String.fromCharCode(0)}-${String.fromCharCode(8)}${String.fromCharCode(11)}${String.fromCharCode(12)}${String.fromCharCode(14)}-${String.fromCharCode(31)}${String.fromCharCode(127)}-${String.fromCharCode(159)}]`, 'gu');
4
+ const AUTH_URL = /\b(?:force|sfdx):\/\/[^\s]+/giu;
5
+ const BEARER_TOKEN = /\bBearer\s+[A-Za-z0-9._~+/-]+=*/giu;
6
+ const CREDENTIAL_ASSIGNMENT = /\b(access[_-]?token|auth(?:orization)?|client[_-]?secret|password|refresh[_-]?token|secret|token)\s*[:=]\s*[^\s,;]+/giu;
7
+ export function sanitizeReleaseReport(report, options = {}) {
8
+ return {
9
+ schemaVersion: report.schemaVersion,
10
+ generatedAt: report.generatedAt,
11
+ command: sanitizeText(report.command, 128),
12
+ targetOrg: optionalText(report.targetOrg, 256),
13
+ analysisMode: report.analysisMode,
14
+ enrichment: {
15
+ status: report.enrichment.status,
16
+ warnings: sanitizeList(report.enrichment.warnings, 1000),
17
+ },
18
+ outcome: report.outcome,
19
+ summary: { ...report.summary },
20
+ phases: report.phases.map((phase) => sanitizePhase(phase, options)),
21
+ items: report.items.map((item) => sanitizeItem(item, options)),
22
+ reportWarnings: sanitizeList(report.reportWarnings, 1000) ?? [],
23
+ };
24
+ }
25
+ function sanitizePhase(phase, options) {
26
+ return {
27
+ id: phase.id,
28
+ route: phase.route,
29
+ operation: phase.operation,
30
+ status: phase.status,
31
+ evidence: phase.evidence?.map((entry) => sanitizeEvidence(entry, options)),
32
+ remediation: sanitizeList(phase.remediation, 1000),
33
+ };
34
+ }
35
+ function sanitizeItem(item, options) {
36
+ return {
37
+ phaseId: item.phaseId,
38
+ metadataType: sanitizeText(item.metadataType, 256),
39
+ fullName: sanitizeText(item.fullName, 512),
40
+ route: item.route,
41
+ operation: item.operation,
42
+ status: item.status,
43
+ targetOrg: optionalText(item.targetOrg, 256),
44
+ evidenceReferences: sanitizeReferences(item.evidenceReferences, options.projectRoot),
45
+ remediation: sanitizeList(item.remediation, 1000),
46
+ };
47
+ }
48
+ function sanitizeEvidence(evidence, options) {
49
+ return {
50
+ tool: evidence.tool,
51
+ operationId: sanitizeText(evidence.operationId, 256),
52
+ exitCode: Number.isSafeInteger(evidence.exitCode) ? evidence.exitCode : undefined,
53
+ deploymentId: optionalText(evidence.deploymentId, 256),
54
+ artifact: sanitizeReference(evidence.artifact, options.projectRoot),
55
+ };
56
+ }
57
+ function sanitizeReferences(references, projectRoot) {
58
+ if (!references)
59
+ return undefined;
60
+ const safe = references
61
+ .map((reference) => sanitizeReference(reference, projectRoot))
62
+ .filter((reference) => reference !== undefined);
63
+ return safe.length > 0 ? [...new Set(safe)].sort() : undefined;
64
+ }
65
+ function sanitizeReference(reference, projectRoot) {
66
+ if (!reference)
67
+ return undefined;
68
+ const clean = sanitizeText(reference, 1024);
69
+ const pathApi = isWindowsPath(clean) || (projectRoot ? isWindowsPath(projectRoot) : false) ? path.win32 : path;
70
+ const resolvedRoot = projectRoot ? pathApi.resolve(projectRoot) : undefined;
71
+ const candidate = pathApi.isAbsolute(clean) ? pathApi.resolve(clean) : pathApi.resolve(resolvedRoot ?? '.', clean);
72
+ if (pathApi.isAbsolute(clean)) {
73
+ if (!resolvedRoot)
74
+ return undefined;
75
+ const relative = pathApi.relative(resolvedRoot, candidate);
76
+ if (!isSafeRelativePath(relative, pathApi))
77
+ return undefined;
78
+ return normalizeReference(relative);
79
+ }
80
+ if (!isSafeRelativePath(clean, pathApi))
81
+ return undefined;
82
+ return normalizeReference(clean);
83
+ }
84
+ function isSafeRelativePath(reference, pathApi) {
85
+ return (reference.length > 0 &&
86
+ !pathApi.isAbsolute(reference) &&
87
+ reference !== '..' &&
88
+ !reference.startsWith('../') &&
89
+ !reference.startsWith('..\\'));
90
+ }
91
+ function isWindowsPath(reference) {
92
+ return /^[A-Za-z]:[\\/]/u.test(reference) || reference.startsWith('\\\\');
93
+ }
94
+ function normalizeReference(reference) {
95
+ return reference.replaceAll('\\', '/').split(path.sep).join('/');
96
+ }
97
+ function sanitizeList(values, maxLength) {
98
+ if (!values)
99
+ return undefined;
100
+ const safe = values.map((value) => sanitizeText(value, maxLength)).filter((value) => value.length > 0);
101
+ return safe.length > 0 ? [...new Set(safe)].sort() : undefined;
102
+ }
103
+ function optionalText(value, maxLength) {
104
+ if (value === undefined)
105
+ return undefined;
106
+ const safe = sanitizeText(value, maxLength);
107
+ return safe.length > 0 ? safe : undefined;
108
+ }
109
+ function sanitizeText(value, maxLength) {
110
+ const redacted = value
111
+ .replace(ANSI_SEQUENCE, '')
112
+ .replace(CONTROL_CHARACTER, '')
113
+ .replace(AUTH_URL, '[REDACTED]')
114
+ .replace(BEARER_TOKEN, 'Bearer [REDACTED]')
115
+ .replace(CREDENTIAL_ASSIGNMENT, '$1=[REDACTED]')
116
+ .replace(/\s+/gu, ' ')
117
+ .trim();
118
+ return redacted.length <= maxLength ? redacted : `${redacted.slice(0, maxLength - 3)}...`;
119
+ }
120
+ //# sourceMappingURL=release-report-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-report-sanitizer.js","sourceRoot":"","sources":["../../src/reports/release-report-sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { ReleaseReportFacts, ReleaseReportV1 } from '../types/release-report.js';
2
+ import { type ReleaseReportSanitizerOptions } from './release-report-sanitizer.js';
3
+ import { type ReleaseReportStoreOptions } from './release-report-store.js';
4
+ export type UnderlyingOperationResult<T> = {
5
+ kind: 'succeeded';
6
+ value: T;
7
+ } | {
8
+ kind: 'failed';
9
+ error: unknown;
10
+ };
11
+ export type ReleaseReportFailureStage = 'build' | 'sanitize' | 'serialize' | 'persist';
12
+ export type ReleaseReportFinalization = {
13
+ kind: 'written';
14
+ report: ReleaseReportV1;
15
+ path: string;
16
+ } | {
17
+ kind: 'unavailable';
18
+ stage: ReleaseReportFailureStage;
19
+ warning: string;
20
+ report?: ReleaseReportV1;
21
+ };
22
+ export type ReleaseReportServiceResult<T> = {
23
+ underlying: UnderlyingOperationResult<T>;
24
+ report: ReleaseReportFinalization;
25
+ };
26
+ export type ReleaseReportServiceOptions = ReleaseReportStoreOptions & ReleaseReportSanitizerOptions;
27
+ export type ReleaseReportServiceDependencies = {
28
+ build: (facts: ReleaseReportFacts) => ReleaseReportV1;
29
+ sanitize: (report: ReleaseReportV1, options: ReleaseReportSanitizerOptions) => ReleaseReportV1;
30
+ serialize: (report: ReleaseReportV1) => string;
31
+ store: (serializedReport: string, options: ReleaseReportStoreOptions) => Promise<{
32
+ kind: 'written';
33
+ path: string;
34
+ } | {
35
+ kind: 'unavailable';
36
+ warning: string;
37
+ }>;
38
+ };
39
+ export declare class ReleaseReportService {
40
+ private readonly dependencies;
41
+ constructor(dependencies?: Partial<ReleaseReportServiceDependencies>);
42
+ finalize<T>(underlying: UnderlyingOperationResult<T>, facts: ReleaseReportFacts, options: ReleaseReportServiceOptions): Promise<ReleaseReportServiceResult<T>>;
43
+ }
@@ -0,0 +1,80 @@
1
+ import { ReleaseReportBuilder } from './release-report-builder.js';
2
+ import { sanitizeReleaseReport } from './release-report-sanitizer.js';
3
+ import { ReleaseReportStore } from './release-report-store.js';
4
+ export class ReleaseReportService {
5
+ dependencies;
6
+ constructor(dependencies) {
7
+ const builder = new ReleaseReportBuilder();
8
+ const store = new ReleaseReportStore();
9
+ this.dependencies = {
10
+ build: (facts) => builder.build(facts),
11
+ sanitize: sanitizeReleaseReport,
12
+ serialize: serializeReleaseReport,
13
+ store: async (serializedReport, options) => store.write(serializedReport, options),
14
+ ...dependencies,
15
+ };
16
+ }
17
+ async finalize(underlying, facts, options) {
18
+ const built = attempt('build', () => this.dependencies.build(facts));
19
+ if (built.kind === 'unavailable')
20
+ return { underlying, report: built };
21
+ const sanitized = attempt('sanitize', () => this.dependencies.sanitize(built.report, options));
22
+ if (sanitized.kind === 'unavailable')
23
+ return { underlying, report: sanitized };
24
+ const serialized = attemptSerialization(() => this.dependencies.serialize(sanitized.report), sanitized.report);
25
+ if (serialized.kind === 'unavailable')
26
+ return { underlying, report: serialized };
27
+ try {
28
+ const persistence = await this.dependencies.store(serialized.content, options);
29
+ if (persistence.kind === 'unavailable') {
30
+ return {
31
+ underlying,
32
+ report: {
33
+ kind: 'unavailable',
34
+ stage: 'persist',
35
+ warning: persistence.warning,
36
+ report: sanitized.report,
37
+ },
38
+ };
39
+ }
40
+ return {
41
+ underlying,
42
+ report: { kind: 'written', report: sanitized.report, path: persistence.path },
43
+ };
44
+ }
45
+ catch {
46
+ return {
47
+ underlying,
48
+ report: {
49
+ kind: 'unavailable',
50
+ stage: 'persist',
51
+ warning: warningFor('persist'),
52
+ report: sanitized.report,
53
+ },
54
+ };
55
+ }
56
+ }
57
+ }
58
+ function attempt(stage, operation) {
59
+ try {
60
+ return { kind: 'available', report: operation() };
61
+ }
62
+ catch {
63
+ return { kind: 'unavailable', stage, warning: warningFor(stage) };
64
+ }
65
+ }
66
+ function attemptSerialization(operation, report) {
67
+ try {
68
+ return { kind: 'serialized', content: operation() };
69
+ }
70
+ catch {
71
+ return { kind: 'unavailable', stage: 'serialize', warning: warningFor('serialize'), report };
72
+ }
73
+ }
74
+ function serializeReleaseReport(report) {
75
+ return `${JSON.stringify(report, null, 2)}\n`;
76
+ }
77
+ function warningFor(stage) {
78
+ return `Release report ${stage} is unavailable; the underlying operation result is unchanged.`;
79
+ }
80
+ //# sourceMappingURL=release-report-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-report-service.js","sourceRoot":"","sources":["../../src/reports/release-report-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export type ReleaseReportStoreResult = {
2
+ kind: 'written';
3
+ path: string;
4
+ } | {
5
+ kind: 'unavailable';
6
+ warning: string;
7
+ };
8
+ export type ReleaseReportStoreOptions = {
9
+ projectRoot: string;
10
+ reportDir?: string;
11
+ };
12
+ type AtomicFileHandle = {
13
+ writeFile: (content: string, encoding: BufferEncoding) => Promise<void>;
14
+ sync: () => Promise<void>;
15
+ close: () => Promise<void>;
16
+ };
17
+ export type ReleaseReportFileSystem = {
18
+ mkdir: (directory: string) => Promise<void>;
19
+ openExclusive: (filePath: string) => Promise<AtomicFileHandle>;
20
+ rename: (source: string, destination: string) => Promise<void>;
21
+ unlink: (filePath: string) => Promise<void>;
22
+ };
23
+ export declare class ReleaseReportStore {
24
+ private readonly fileSystem;
25
+ private readonly temporaryPathFactory;
26
+ constructor(fileSystem?: ReleaseReportFileSystem, temporaryPathFactory?: (finalPath: string) => string);
27
+ resolvePath(options: ReleaseReportStoreOptions): string;
28
+ write(serializedReport: string, options: ReleaseReportStoreOptions): Promise<ReleaseReportStoreResult>;
29
+ }
30
+ export {};
@@ -0,0 +1,57 @@
1
+ import { mkdir, open, rename, unlink } from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ const DEFAULT_REPORT_DIRECTORY = '.smart-deployment/reports';
4
+ const RELEASE_REPORT_FILE_NAME = 'release-report.json';
5
+ let temporarySequence = 0;
6
+ const NODE_FILE_SYSTEM = {
7
+ mkdir: async (directory) => mkdir(directory, { recursive: true }).then(() => undefined),
8
+ openExclusive: async (filePath) => open(filePath, 'wx'),
9
+ rename,
10
+ unlink,
11
+ };
12
+ export class ReleaseReportStore {
13
+ fileSystem;
14
+ temporaryPathFactory;
15
+ constructor(fileSystem = NODE_FILE_SYSTEM, temporaryPathFactory = defaultTemporaryPath) {
16
+ this.fileSystem = fileSystem;
17
+ this.temporaryPathFactory = temporaryPathFactory;
18
+ }
19
+ resolvePath(options) {
20
+ const directory = options.reportDir
21
+ ? path.resolve(options.projectRoot, options.reportDir)
22
+ : path.resolve(options.projectRoot, DEFAULT_REPORT_DIRECTORY);
23
+ return path.join(directory, RELEASE_REPORT_FILE_NAME);
24
+ }
25
+ async write(serializedReport, options) {
26
+ const finalPath = this.resolvePath(options);
27
+ const temporaryPath = this.temporaryPathFactory(finalPath);
28
+ let handle;
29
+ try {
30
+ await this.fileSystem.mkdir(path.dirname(finalPath));
31
+ handle = await this.fileSystem.openExclusive(temporaryPath);
32
+ await handle.writeFile(serializedReport, 'utf8');
33
+ await handle.sync();
34
+ await handle.close();
35
+ handle = undefined;
36
+ await this.fileSystem.rename(temporaryPath, finalPath);
37
+ return { kind: 'written', path: finalPath };
38
+ }
39
+ catch {
40
+ await closeBestEffort(handle);
41
+ await this.fileSystem.unlink(temporaryPath).catch(() => undefined);
42
+ return {
43
+ kind: 'unavailable',
44
+ warning: 'Release report persistence is unavailable; the underlying operation result is unchanged.',
45
+ };
46
+ }
47
+ }
48
+ }
49
+ async function closeBestEffort(handle) {
50
+ if (handle)
51
+ await handle.close().catch(() => undefined);
52
+ }
53
+ function defaultTemporaryPath(finalPath) {
54
+ temporarySequence += 1;
55
+ return `${finalPath}.${process.pid}.${temporarySequence}.tmp`;
56
+ }
57
+ //# sourceMappingURL=release-report-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-report-store.js","sourceRoot":"","sources":["../../src/reports/release-report-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { DeploymentContext } from '../deployment/deployment-context-service.js';
2
+ import type { ReleaseReportPresenterIO } from '../presentation/release-report-presenter.js';
3
+ import { ReleaseReportCommandAdapter, type ReleaseReportCommandOutput } from './release-report-command-adapter.js';
4
+ export type StartReleaseReportOptions = {
5
+ targetOrg?: string;
6
+ dryRun: boolean;
7
+ validateOnly: boolean;
8
+ reportDir?: string;
9
+ };
10
+ export declare class StartReleaseReportCoordinator {
11
+ private readonly adapter;
12
+ constructor(adapter?: ReleaseReportCommandAdapter);
13
+ finalizeSuccess<T>(io: ReleaseReportPresenterIO, result: T, context: DeploymentContext, options: StartReleaseReportOptions): Promise<T & ReleaseReportCommandOutput>;
14
+ finalizeFailure(io: ReleaseReportPresenterIO, error: unknown, context: DeploymentContext, options: StartReleaseReportOptions): Promise<void>;
15
+ }
@@ -0,0 +1,23 @@
1
+ import { ReleaseReportCommandAdapter } from './release-report-command-adapter.js';
2
+ import { buildStartReportFacts } from './release-report-facts-factory.js';
3
+ export class StartReleaseReportCoordinator {
4
+ adapter;
5
+ constructor(adapter = new ReleaseReportCommandAdapter()) {
6
+ this.adapter = adapter;
7
+ }
8
+ async finalizeSuccess(io, result, context, options) {
9
+ const releaseReport = await this.adapter.finalize(io, { kind: 'succeeded', value: result }, buildStartReportFacts(context, options), {
10
+ projectRoot: context.scanResult.projectRoot,
11
+ reportDir: options.reportDir,
12
+ });
13
+ return { ...result, ...releaseReport };
14
+ }
15
+ async finalizeFailure(io, error, context, options) {
16
+ const warning = error instanceof Error ? error.message : String(error);
17
+ await this.adapter.finalize(io, { kind: 'failed', error }, buildStartReportFacts(context, { ...options, failed: true, warning }), {
18
+ projectRoot: context.scanResult.projectRoot,
19
+ reportDir: options.reportDir,
20
+ });
21
+ }
22
+ }
23
+ //# sourceMappingURL=start-release-report-coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-release-report-coordinator.js","sourceRoot":"","sources":["../../src/reports/start-release-report-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAmC,MAAM,qCAAqC,CAAC;AACnH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAS1E,MAAM,OAAO,6BAA6B;IACJ;IAApC,YAAoC,UAAU,IAAI,2BAA2B,EAAE;QAA3C,YAAO,GAAP,OAAO,CAAoC;IAAG,CAAC;IAE5E,KAAK,CAAC,eAAe,CAC1B,EAA4B,EAC5B,MAAS,EACT,OAA0B,EAC1B,OAAkC;QAElC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAC/C,EAAE,EACF,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,EACpC,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,EACvC;YACE,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW;YAC3C,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CACF,CAAC;QACF,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,aAAa,EAAE,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,eAAe,CAC1B,EAA4B,EAC5B,KAAc,EACd,OAA0B,EAC1B,OAAkC;QAElC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CACzB,EAAE,EACF,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EACzB,qBAAqB,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EACrE;YACE,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW;YAC3C,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -13,7 +13,7 @@ import { DependencyGraphBuilder } from '../dependencies/dependency-graph-builder
13
13
  import { ForceIgnoreParser } from '../scanner/forceignore-parser.js';
14
14
  import { SfdxProjectDetector } from '../scanner/sfdx-project-detector.js';
15
15
  import { getLogger } from '../utils/logger.js';
16
- import { parseAiAuthoringBundleComponent, parseBotComponent, parseFlowComponent, parseGenAiPlannerBundleComponent, parseGenAiPromptComponent, } from './scanners/automation-ai-metadata-scanner.js';
16
+ import { parseAiEvaluationDefinitionComponent, parseAiAuthoringBundleComponent, parseBotComponent, parseFlowComponent, parseGenAiPlannerBundleComponent, parseGenAiPromptComponent, } from './scanners/automation-ai-metadata-scanner.js';
17
17
  import { CODE_DIRECTORY_SCANNERS, CODE_FILE_SCANNERS } from './scanners/code-metadata-scanner.js';
18
18
  import { parseCustomMetadataComponents, parseCustomObjectComponent } from './scanners/data-metadata-scanner.js';
19
19
  import { parseEmailTemplateComponent, parseFlexiPageComponent, parseLayoutComponent, parseVisualforceComponent, } from './scanners/experience-metadata-scanner.js';
@@ -156,9 +156,16 @@ export class MetadataScannerService {
156
156
  const botComponents = await scanMetadataFiles(packagePath, '**/bots/**/*.bot-meta.xml', errors, 'Bot', this.shouldIgnorePath, parseBotComponent);
157
157
  const genAiPromptComponents = await scanMetadataFiles(packagePath, '**/genaiPromptTemplates/**/*.genAiPromptTemplate-meta.xml', errors, 'GenAI Prompt', this.shouldIgnorePath, parseGenAiPromptComponent);
158
158
  const aiAuthoringBundleComponents = await scanMetadataFiles(packagePath, '**/aiAuthoringBundles/**/*.agent', errors, 'AiAuthoringBundle', this.shouldIgnorePath, (filePath) => Promise.resolve(parseAiAuthoringBundleComponent(filePath)));
159
+ const aiEvaluationDefinitionComponents = (await scanMetadataFiles(packagePath, '**/aiEvaluationDefinitions/**/*.aiEvaluationDefinition-meta.xml', errors, 'AiEvaluationDefinition', this.shouldIgnorePath, parseAiEvaluationDefinitionComponent)).sort((left, right) => normalizePath(left.filePath).localeCompare(normalizePath(right.filePath)));
159
160
  const authoringBundleNames = new Set(aiAuthoringBundleComponents.map((component) => component.name));
160
161
  const genAiPlannerBundleComponents = (await scanMetadataDirectories(packagePath, '**/genAiPlannerBundles/*', errors, 'GenAiPlannerBundle', this.shouldIgnorePath, parseGenAiPlannerBundleComponent)).filter((component) => !authoringBundleNames.has(component.name));
161
- return [...botComponents, ...genAiPromptComponents, ...aiAuthoringBundleComponents, ...genAiPlannerBundleComponents];
162
+ return [
163
+ ...botComponents,
164
+ ...genAiPromptComponents,
165
+ ...aiAuthoringBundleComponents,
166
+ ...aiEvaluationDefinitionComponents,
167
+ ...genAiPlannerBundleComponents,
168
+ ];
162
169
  }
163
170
  async scanAdditionalMetadata(packagePath, errors) {
164
171
  return scanAdditionalMetadata(packagePath, errors, this.shouldIgnorePath);
@@ -179,4 +186,7 @@ export class MetadataScannerService {
179
186
  return this.forceIgnoreParser.isIgnored(filePath);
180
187
  }
181
188
  }
189
+ function normalizePath(filePath) {
190
+ return filePath.split(path.sep).join('/');
191
+ }
182
192
  //# sourceMappingURL=metadata-scanner-service.js.map