@uipath/solution-packager 1.197.0 → 1.198.0-preview.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -402,8 +402,8 @@ import {
402
402
  Path as Path4,
403
403
  TargetFramework,
404
404
  TemporaryStorageService,
405
- ToolErrorCodes as ToolErrorCodes4,
406
- ToolResult as ToolResult4,
405
+ ToolErrorCodes as ToolErrorCodes5,
406
+ ToolResult as ToolResult5,
407
407
  toolsFactoryRepository,
408
408
  translate as translate3,
409
409
  ZipService
@@ -505,6 +505,16 @@ class OptionsBuilder {
505
505
  outputPath: await this.buildProjectOutputPath(solutionOptions.outputPath, project)
506
506
  };
507
507
  }
508
+ buildProjectCleanupOptions(solutionOptions, project) {
509
+ return {
510
+ projectPath: this.resolveProjectPath(solutionOptions, project),
511
+ excludeConfiguredSources: solutionOptions.excludeConfiguredSources ?? false,
512
+ nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
513
+ logLevel: solutionOptions.logLevel,
514
+ dryRun: solutionOptions.cleanupOptions.dryRun,
515
+ skipImports: solutionOptions.cleanupOptions.skipImports
516
+ };
517
+ }
508
518
  resolveProjectPath(solutionOptions, project) {
509
519
  return Path.join(solutionOptions.inputPath, Path.dirname(project.ProjectRelativePath));
510
520
  }
@@ -611,7 +621,7 @@ class PackageIdReader {
611
621
  const resource = resources.find((r) => {
612
622
  const projectKey = this.getProperty(r, "projectKey");
613
623
  const kind = this.getProperty(r, "kind");
614
- return projectKey === project.Id && kind?.toLowerCase() === "process";
624
+ return projectKey === project.Id && typeof kind === "string" && kind.toLowerCase() === "process";
615
625
  });
616
626
  if (!resource) {
617
627
  return null;
@@ -652,9 +662,9 @@ class PackageIdReader {
652
662
  const projectKey = this.getProperty(resource, "projectKey");
653
663
  if (projectKey === project.Id) {
654
664
  const spec = this.getProperty(resource, "spec");
655
- let packageName = this.getProperty(spec, "packageName");
656
- if (!packageName || typeof packageName !== "string" || packageName.trim() === "") {
657
- packageName = null;
665
+ const packageName = this.getProperty(spec, "packageName");
666
+ if (typeof packageName !== "string" || packageName.trim() === "") {
667
+ return null;
658
668
  }
659
669
  return packageName;
660
670
  }
@@ -674,6 +684,77 @@ class PackageIdReader {
674
684
  }
675
685
  }
676
686
 
687
+ // src/services/solution-cleanup-service.ts
688
+ import {
689
+ ToolErrorCodes,
690
+ ToolResult
691
+ } from "@uipath/solutionpackager-tool-core";
692
+ class SolutionCleanupService {
693
+ optionsBuilder;
694
+ projectExecutor;
695
+ telemetry;
696
+ constructor(optionsBuilder, projectExecutor, telemetry) {
697
+ this.optionsBuilder = optionsBuilder;
698
+ this.projectExecutor = projectExecutor;
699
+ this.telemetry = telemetry;
700
+ }
701
+ async cleanupAsync(parameters, solution, context, cancellationToken) {
702
+ return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Cleanup" /* SolutionCleanup */, "cleanup", async () => {
703
+ const projectResults = await Promise.all(solution.Projects.map(async (project) => {
704
+ if (project.ProjectPath == null) {
705
+ return {
706
+ project,
707
+ result: ToolResult.error(ToolErrorCodes.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before cleanup.`)
708
+ };
709
+ }
710
+ const result2 = await this.projectExecutor.cleanupAsync(this.optionsBuilder.buildProjectCleanupOptions(parameters, project), project, context, cancellationToken);
711
+ return { project, result: result2 };
712
+ }));
713
+ const failed = projectResults.find((r) => !r.result.isSuccess);
714
+ if (failed) {
715
+ return failed.result;
716
+ }
717
+ const result = ToolResult.success();
718
+ const details = {};
719
+ const changedFilesByProject = this.mergeChangedFiles(projectResults.map((r) => r.result));
720
+ if (Object.keys(changedFilesByProject).length > 0) {
721
+ details.changedFilesByProject = changedFilesByProject;
722
+ }
723
+ const cleanupByProject = this.collectProjectCleanups(projectResults);
724
+ if (Object.keys(cleanupByProject).length > 0) {
725
+ details.cleanupByProject = cleanupByProject;
726
+ }
727
+ if (Object.keys(details).length > 0) {
728
+ result.details = details;
729
+ }
730
+ return result;
731
+ }, { solutionId: solution.SolutionId });
732
+ }
733
+ mergeChangedFiles(results) {
734
+ const merged = {};
735
+ for (const result of results) {
736
+ const changed = result.details?.changedFilesByProject;
737
+ if (!changed) {
738
+ continue;
739
+ }
740
+ for (const [projectId, files] of Object.entries(changed)) {
741
+ merged[projectId] = files;
742
+ }
743
+ }
744
+ return merged;
745
+ }
746
+ collectProjectCleanups(results) {
747
+ const byProject = {};
748
+ for (const { project, result } of results) {
749
+ const info = result.details?.projectCleanup;
750
+ if (info) {
751
+ byProject[project.Id] = info;
752
+ }
753
+ }
754
+ return byProject;
755
+ }
756
+ }
757
+
677
758
  // src/services/solution-loader.ts
678
759
  import { Path as Path3, translate as translate2 } from "@uipath/solutionpackager-tool-core";
679
760
 
@@ -802,8 +883,8 @@ import {
802
883
  signNupkgsAsync
803
884
  } from "@uipath/project-packager";
804
885
  import {
805
- ToolErrorCodes,
806
- ToolResult
886
+ ToolErrorCodes as ToolErrorCodes2,
887
+ ToolResult as ToolResult2
807
888
  } from "@uipath/solutionpackager-tool-core";
808
889
 
809
890
  // src/services/tool-result-helpers.ts
@@ -846,21 +927,21 @@ class SolutionPackService {
846
927
  ...projectResults
847
928
  ];
848
929
  if (hasFailedResults(restoreAndPackResults)) {
849
- return ToolResult.error(ToolErrorCodes.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
930
+ return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
850
931
  }
851
932
  const buildResult = await solutionTool.buildAsync(solutionOptions, cancellationToken);
852
933
  if (!buildResult.isSuccess) {
853
- return ToolResult.error(buildResult.errorCode, `Solution build failed: ${buildResult.message || "Unknown error"}`);
934
+ return ToolResult2.error(buildResult.errorCode, `Solution build failed: ${buildResult.message || "Unknown error"}`);
854
935
  }
855
936
  if (!solutionOptions.outputPath) {
856
- return ToolResult.error(ToolErrorCodes.InternalError, "Solution output path is not defined");
937
+ return ToolResult2.error(ToolErrorCodes2.InternalError, "Solution output path is not defined");
857
938
  }
858
939
  const signResult = await this.signProjectPackagesAsync(projectResults, parameters.signingInfo);
859
940
  if (!signResult.isSuccess) {
860
941
  return signResult;
861
942
  }
862
943
  const archivePath = await this.compressSolutionAsync(parameters, solutionOptions.outputPath);
863
- return new ToolResult(ToolErrorCodes.Success, undefined, [
944
+ return new ToolResult2(ToolErrorCodes2.Success, undefined, [
864
945
  archivePath
865
946
  ]);
866
947
  }, { solutionId: solution.SolutionId });
@@ -880,12 +961,12 @@ class SolutionPackService {
880
961
  return await this.projectExecutor.packAsync(projectOptions, project, context, cancellationToken);
881
962
  } catch (error) {
882
963
  const errorMessage = error instanceof Error ? error.message : String(error);
883
- return ToolResult.error(ToolErrorCodes.InternalError, errorMessage);
964
+ return ToolResult2.error(ToolErrorCodes2.InternalError, errorMessage);
884
965
  }
885
966
  }
886
967
  async signProjectPackagesAsync(projectResults, signingInfo) {
887
968
  if (!signingInfo?.certificatePath) {
888
- return ToolResult.success();
969
+ return ToolResult2.success();
889
970
  }
890
971
  const producedPaths = projectResults.flatMap((result) => result.packages);
891
972
  const resolved = await Promise.all(producedPaths.map(async (producedPath) => ({
@@ -894,7 +975,7 @@ class SolutionPackService {
894
975
  })));
895
976
  const unresolved = resolved.filter((entry) => entry.nupkgs.length === 0).map((entry) => entry.producedPath);
896
977
  if (unresolved.length > 0) {
897
- return ToolResult.error(ToolErrorCodes.InternalError, `Package signing was required but no .nupkg was found to sign for: ${unresolved.join(", ")}.`);
978
+ return ToolResult2.error(ToolErrorCodes2.InternalError, `Package signing was required but no .nupkg was found to sign for: ${unresolved.join(", ")}.`);
898
979
  }
899
980
  const nupkgsToSign = resolved.flatMap((entry) => entry.nupkgs);
900
981
  return signNupkgsAsync(this.packageSignService, nupkgsToSign, signingInfo);
@@ -938,8 +1019,8 @@ class SolutionPackService {
938
1019
 
939
1020
  // src/services/solution-restore-service.ts
940
1021
  import {
941
- ToolErrorCodes as ToolErrorCodes2,
942
- ToolResult as ToolResult2
1022
+ ToolErrorCodes as ToolErrorCodes3,
1023
+ ToolResult as ToolResult3
943
1024
  } from "@uipath/solutionpackager-tool-core";
944
1025
  class SolutionRestoreService {
945
1026
  optionsBuilder;
@@ -965,9 +1046,9 @@ class SolutionRestoreService {
965
1046
  })
966
1047
  ]);
967
1048
  if (hasFailedResults(restoreResults)) {
968
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution restore failed: ${getFailedResultsMessage(restoreResults)}`);
1049
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution restore failed: ${getFailedResultsMessage(restoreResults)}`);
969
1050
  }
970
- return ToolResult2.success();
1051
+ return ToolResult3.success();
971
1052
  }, { solutionId: solution.SolutionId });
972
1053
  } finally {
973
1054
  const disposeResult = solutionTool.dispose();
@@ -991,8 +1072,8 @@ class SolutionValidateOptionsValidator extends PackagerParametersValidator2 {
991
1072
 
992
1073
  // src/services/solution-validate-service.ts
993
1074
  import {
994
- ToolErrorCodes as ToolErrorCodes3,
995
- ToolResult as ToolResult3
1075
+ ToolErrorCodes as ToolErrorCodes4,
1076
+ ToolResult as ToolResult4
996
1077
  } from "@uipath/solutionpackager-tool-core";
997
1078
  class SolutionValidateService {
998
1079
  optionsBuilder;
@@ -1007,12 +1088,12 @@ class SolutionValidateService {
1007
1088
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Validate" /* SolutionValidate */, "validate", async () => {
1008
1089
  const projectResults = await Promise.all(solution.Projects.map((project) => {
1009
1090
  if (project.ProjectPath == null) {
1010
- return Promise.resolve(ToolResult3.error(ToolErrorCodes3.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
1091
+ return Promise.resolve(ToolResult4.error(ToolErrorCodes4.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
1011
1092
  }
1012
1093
  return this.projectExecutor.validateAsync(this.optionsBuilder.buildProjectValidateOptions(parameters, project), project, context, cancellationToken);
1013
1094
  }));
1014
1095
  const failed = projectResults.find((r) => !r.isSuccess);
1015
- return failed ?? ToolResult3.success();
1096
+ return failed ?? ToolResult4.success();
1016
1097
  }, { solutionId: solution.SolutionId });
1017
1098
  }
1018
1099
  }
@@ -1033,6 +1114,7 @@ class SolutionPackager {
1033
1114
  solutionPackService;
1034
1115
  solutionRestoreService;
1035
1116
  solutionValidateService;
1117
+ solutionCleanupService;
1036
1118
  packOptionsValidator;
1037
1119
  validateOptionsValidator;
1038
1120
  governancePolicyService;
@@ -1056,6 +1138,7 @@ class SolutionPackager {
1056
1138
  this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService, this.packageSignService);
1057
1139
  this.solutionRestoreService = new SolutionRestoreService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.telemetryService);
1058
1140
  this.solutionValidateService = new SolutionValidateService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
1141
+ this.solutionCleanupService = new SolutionCleanupService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
1059
1142
  }
1060
1143
  async setupAsync(input, operationId) {
1061
1144
  this.telemetryService.setOperationId(operationId);
@@ -1112,7 +1195,7 @@ class SolutionPackager {
1112
1195
  } catch (error) {
1113
1196
  const errorMessage = error instanceof Error ? error.message : String(error);
1114
1197
  this.logger.error(`Processing error: ${errorMessage}`);
1115
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution pack failed: ${errorMessage}`);
1198
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`);
1116
1199
  } finally {
1117
1200
  await this.temporaryStorage.cleanup();
1118
1201
  }
@@ -1139,7 +1222,7 @@ class SolutionPackager {
1139
1222
  } catch (error) {
1140
1223
  const errorMessage = error instanceof Error ? error.message : String(error);
1141
1224
  this.logger.error(`Processing error: ${errorMessage}`);
1142
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution validate failed: ${errorMessage}`);
1225
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`);
1143
1226
  } finally {
1144
1227
  await this.temporaryStorage.cleanup();
1145
1228
  }
@@ -1164,7 +1247,29 @@ class SolutionPackager {
1164
1247
  } catch (error) {
1165
1248
  const errorMessage = error instanceof Error ? error.message : String(error);
1166
1249
  this.logger.error(`Processing error: ${errorMessage}`);
1167
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution restore failed: ${errorMessage}`);
1250
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution restore failed: ${errorMessage}`);
1251
+ } finally {
1252
+ await this.temporaryStorage.cleanup();
1253
+ }
1254
+ });
1255
+ }
1256
+ async cleanupSolutionAsync(options, cancellationToken) {
1257
+ return await this.telemetryService.trackRequest("SolutionPackager.CleanupSolution" /* SolutionPackagerCleanupSolution */, async () => {
1258
+ try {
1259
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
1260
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
1261
+ const context = this.createOperationContext(options, solution);
1262
+ const result = await this.solutionCleanupService.cleanupAsync(options, solution, context, cancellationToken);
1263
+ if (result.isSuccess) {
1264
+ this.logger.info("Solution cleanup completed successfully.");
1265
+ } else {
1266
+ this.logger.error(`Solution cleanup failed with error code ${result.errorCode}: ${result.message}`);
1267
+ }
1268
+ return result;
1269
+ } catch (error) {
1270
+ const errorMessage = error instanceof Error ? error.message : String(error);
1271
+ this.logger.error(`Processing error: ${errorMessage}`);
1272
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution cleanup failed: ${errorMessage}`);
1168
1273
  } finally {
1169
1274
  await this.temporaryStorage.cleanup();
1170
1275
  }
@@ -1189,11 +1294,13 @@ class SolutionPackager {
1189
1294
  id: crypto.randomUUID(),
1190
1295
  projects: solution.Projects,
1191
1296
  downloadUrl: options.downloadUrl,
1297
+ solutionId: solution.SolutionId,
1192
1298
  configuration: options.configuration,
1193
1299
  targetFramework: options.targetFramework ?? TargetFramework.Portable,
1194
1300
  connection: options.connection,
1195
1301
  logger: this.logger,
1196
- workflowCompilerVersion: options.workflowCompilerVersion
1302
+ workflowCompilerVersion: options.workflowCompilerVersion,
1303
+ lockKey: options.lockKey
1197
1304
  };
1198
1305
  }
1199
1306
  async getPackageStreamsAsync(result) {
@@ -1256,6 +1363,11 @@ class SolutionPackOptions extends PackagerParameters {
1256
1363
  signingInfo;
1257
1364
  packOptions;
1258
1365
  publishInfo;
1366
+ cleanupOptions = {
1367
+ dryRun: false,
1368
+ skipImports: false
1369
+ };
1370
+ lockKey;
1259
1371
  }
1260
1372
  export {
1261
1373
  createBrowserSolutionPackager,
@@ -1266,4 +1378,4 @@ export {
1266
1378
  BuildConfiguration2 as BuildConfiguration
1267
1379
  };
1268
1380
 
1269
- //# debugId=00A5AFB7E48A8EC764756E2164756E21
1381
+ //# debugId=AED86F1027DF443564756E2164756E21
package/dist/node.js CHANGED
@@ -401,6 +401,11 @@ class SolutionPackOptions extends PackagerParameters {
401
401
  signingInfo;
402
402
  packOptions;
403
403
  publishInfo;
404
+ cleanupOptions = {
405
+ dryRun: false,
406
+ skipImports: false
407
+ };
408
+ lockKey;
404
409
  }
405
410
  // src/node-solution-packager-factory.ts
406
411
  import {
@@ -422,8 +427,8 @@ import {
422
427
  Path as Path4,
423
428
  TargetFramework,
424
429
  TemporaryStorageService,
425
- ToolErrorCodes as ToolErrorCodes4,
426
- ToolResult as ToolResult4,
430
+ ToolErrorCodes as ToolErrorCodes5,
431
+ ToolResult as ToolResult5,
427
432
  toolsFactoryRepository,
428
433
  translate as translate3,
429
434
  ZipService
@@ -525,6 +530,16 @@ class OptionsBuilder {
525
530
  outputPath: await this.buildProjectOutputPath(solutionOptions.outputPath, project)
526
531
  };
527
532
  }
533
+ buildProjectCleanupOptions(solutionOptions, project) {
534
+ return {
535
+ projectPath: this.resolveProjectPath(solutionOptions, project),
536
+ excludeConfiguredSources: solutionOptions.excludeConfiguredSources ?? false,
537
+ nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
538
+ logLevel: solutionOptions.logLevel,
539
+ dryRun: solutionOptions.cleanupOptions.dryRun,
540
+ skipImports: solutionOptions.cleanupOptions.skipImports
541
+ };
542
+ }
528
543
  resolveProjectPath(solutionOptions, project) {
529
544
  return Path.join(solutionOptions.inputPath, Path.dirname(project.ProjectRelativePath));
530
545
  }
@@ -631,7 +646,7 @@ class PackageIdReader {
631
646
  const resource = resources.find((r) => {
632
647
  const projectKey = this.getProperty(r, "projectKey");
633
648
  const kind = this.getProperty(r, "kind");
634
- return projectKey === project.Id && kind?.toLowerCase() === "process";
649
+ return projectKey === project.Id && typeof kind === "string" && kind.toLowerCase() === "process";
635
650
  });
636
651
  if (!resource) {
637
652
  return null;
@@ -672,9 +687,9 @@ class PackageIdReader {
672
687
  const projectKey = this.getProperty(resource, "projectKey");
673
688
  if (projectKey === project.Id) {
674
689
  const spec = this.getProperty(resource, "spec");
675
- let packageName = this.getProperty(spec, "packageName");
676
- if (!packageName || typeof packageName !== "string" || packageName.trim() === "") {
677
- packageName = null;
690
+ const packageName = this.getProperty(spec, "packageName");
691
+ if (typeof packageName !== "string" || packageName.trim() === "") {
692
+ return null;
678
693
  }
679
694
  return packageName;
680
695
  }
@@ -694,6 +709,77 @@ class PackageIdReader {
694
709
  }
695
710
  }
696
711
 
712
+ // src/services/solution-cleanup-service.ts
713
+ import {
714
+ ToolErrorCodes,
715
+ ToolResult
716
+ } from "@uipath/solutionpackager-tool-core";
717
+ class SolutionCleanupService {
718
+ optionsBuilder;
719
+ projectExecutor;
720
+ telemetry;
721
+ constructor(optionsBuilder, projectExecutor, telemetry) {
722
+ this.optionsBuilder = optionsBuilder;
723
+ this.projectExecutor = projectExecutor;
724
+ this.telemetry = telemetry;
725
+ }
726
+ async cleanupAsync(parameters, solution, context, cancellationToken) {
727
+ return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Cleanup" /* SolutionCleanup */, "cleanup", async () => {
728
+ const projectResults = await Promise.all(solution.Projects.map(async (project) => {
729
+ if (project.ProjectPath == null) {
730
+ return {
731
+ project,
732
+ result: ToolResult.error(ToolErrorCodes.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before cleanup.`)
733
+ };
734
+ }
735
+ const result2 = await this.projectExecutor.cleanupAsync(this.optionsBuilder.buildProjectCleanupOptions(parameters, project), project, context, cancellationToken);
736
+ return { project, result: result2 };
737
+ }));
738
+ const failed = projectResults.find((r) => !r.result.isSuccess);
739
+ if (failed) {
740
+ return failed.result;
741
+ }
742
+ const result = ToolResult.success();
743
+ const details = {};
744
+ const changedFilesByProject = this.mergeChangedFiles(projectResults.map((r) => r.result));
745
+ if (Object.keys(changedFilesByProject).length > 0) {
746
+ details.changedFilesByProject = changedFilesByProject;
747
+ }
748
+ const cleanupByProject = this.collectProjectCleanups(projectResults);
749
+ if (Object.keys(cleanupByProject).length > 0) {
750
+ details.cleanupByProject = cleanupByProject;
751
+ }
752
+ if (Object.keys(details).length > 0) {
753
+ result.details = details;
754
+ }
755
+ return result;
756
+ }, { solutionId: solution.SolutionId });
757
+ }
758
+ mergeChangedFiles(results) {
759
+ const merged = {};
760
+ for (const result of results) {
761
+ const changed = result.details?.changedFilesByProject;
762
+ if (!changed) {
763
+ continue;
764
+ }
765
+ for (const [projectId, files] of Object.entries(changed)) {
766
+ merged[projectId] = files;
767
+ }
768
+ }
769
+ return merged;
770
+ }
771
+ collectProjectCleanups(results) {
772
+ const byProject = {};
773
+ for (const { project, result } of results) {
774
+ const info = result.details?.projectCleanup;
775
+ if (info) {
776
+ byProject[project.Id] = info;
777
+ }
778
+ }
779
+ return byProject;
780
+ }
781
+ }
782
+
697
783
  // src/services/solution-loader.ts
698
784
  import { Path as Path3, translate as translate2 } from "@uipath/solutionpackager-tool-core";
699
785
 
@@ -822,8 +908,8 @@ import {
822
908
  signNupkgsAsync
823
909
  } from "@uipath/project-packager";
824
910
  import {
825
- ToolErrorCodes,
826
- ToolResult
911
+ ToolErrorCodes as ToolErrorCodes2,
912
+ ToolResult as ToolResult2
827
913
  } from "@uipath/solutionpackager-tool-core";
828
914
 
829
915
  // src/services/tool-result-helpers.ts
@@ -866,21 +952,21 @@ class SolutionPackService {
866
952
  ...projectResults
867
953
  ];
868
954
  if (hasFailedResults(restoreAndPackResults)) {
869
- return ToolResult.error(ToolErrorCodes.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
955
+ return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
870
956
  }
871
957
  const buildResult = await solutionTool.buildAsync(solutionOptions, cancellationToken);
872
958
  if (!buildResult.isSuccess) {
873
- return ToolResult.error(buildResult.errorCode, `Solution build failed: ${buildResult.message || "Unknown error"}`);
959
+ return ToolResult2.error(buildResult.errorCode, `Solution build failed: ${buildResult.message || "Unknown error"}`);
874
960
  }
875
961
  if (!solutionOptions.outputPath) {
876
- return ToolResult.error(ToolErrorCodes.InternalError, "Solution output path is not defined");
962
+ return ToolResult2.error(ToolErrorCodes2.InternalError, "Solution output path is not defined");
877
963
  }
878
964
  const signResult = await this.signProjectPackagesAsync(projectResults, parameters.signingInfo);
879
965
  if (!signResult.isSuccess) {
880
966
  return signResult;
881
967
  }
882
968
  const archivePath = await this.compressSolutionAsync(parameters, solutionOptions.outputPath);
883
- return new ToolResult(ToolErrorCodes.Success, undefined, [
969
+ return new ToolResult2(ToolErrorCodes2.Success, undefined, [
884
970
  archivePath
885
971
  ]);
886
972
  }, { solutionId: solution.SolutionId });
@@ -900,12 +986,12 @@ class SolutionPackService {
900
986
  return await this.projectExecutor.packAsync(projectOptions, project, context, cancellationToken);
901
987
  } catch (error) {
902
988
  const errorMessage = error instanceof Error ? error.message : String(error);
903
- return ToolResult.error(ToolErrorCodes.InternalError, errorMessage);
989
+ return ToolResult2.error(ToolErrorCodes2.InternalError, errorMessage);
904
990
  }
905
991
  }
906
992
  async signProjectPackagesAsync(projectResults, signingInfo) {
907
993
  if (!signingInfo?.certificatePath) {
908
- return ToolResult.success();
994
+ return ToolResult2.success();
909
995
  }
910
996
  const producedPaths = projectResults.flatMap((result) => result.packages);
911
997
  const resolved = await Promise.all(producedPaths.map(async (producedPath) => ({
@@ -914,7 +1000,7 @@ class SolutionPackService {
914
1000
  })));
915
1001
  const unresolved = resolved.filter((entry) => entry.nupkgs.length === 0).map((entry) => entry.producedPath);
916
1002
  if (unresolved.length > 0) {
917
- return ToolResult.error(ToolErrorCodes.InternalError, `Package signing was required but no .nupkg was found to sign for: ${unresolved.join(", ")}.`);
1003
+ return ToolResult2.error(ToolErrorCodes2.InternalError, `Package signing was required but no .nupkg was found to sign for: ${unresolved.join(", ")}.`);
918
1004
  }
919
1005
  const nupkgsToSign = resolved.flatMap((entry) => entry.nupkgs);
920
1006
  return signNupkgsAsync(this.packageSignService, nupkgsToSign, signingInfo);
@@ -958,8 +1044,8 @@ class SolutionPackService {
958
1044
 
959
1045
  // src/services/solution-restore-service.ts
960
1046
  import {
961
- ToolErrorCodes as ToolErrorCodes2,
962
- ToolResult as ToolResult2
1047
+ ToolErrorCodes as ToolErrorCodes3,
1048
+ ToolResult as ToolResult3
963
1049
  } from "@uipath/solutionpackager-tool-core";
964
1050
  class SolutionRestoreService {
965
1051
  optionsBuilder;
@@ -985,9 +1071,9 @@ class SolutionRestoreService {
985
1071
  })
986
1072
  ]);
987
1073
  if (hasFailedResults(restoreResults)) {
988
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution restore failed: ${getFailedResultsMessage(restoreResults)}`);
1074
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution restore failed: ${getFailedResultsMessage(restoreResults)}`);
989
1075
  }
990
- return ToolResult2.success();
1076
+ return ToolResult3.success();
991
1077
  }, { solutionId: solution.SolutionId });
992
1078
  } finally {
993
1079
  const disposeResult = solutionTool.dispose();
@@ -1011,8 +1097,8 @@ class SolutionValidateOptionsValidator extends PackagerParametersValidator2 {
1011
1097
 
1012
1098
  // src/services/solution-validate-service.ts
1013
1099
  import {
1014
- ToolErrorCodes as ToolErrorCodes3,
1015
- ToolResult as ToolResult3
1100
+ ToolErrorCodes as ToolErrorCodes4,
1101
+ ToolResult as ToolResult4
1016
1102
  } from "@uipath/solutionpackager-tool-core";
1017
1103
  class SolutionValidateService {
1018
1104
  optionsBuilder;
@@ -1027,12 +1113,12 @@ class SolutionValidateService {
1027
1113
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Validate" /* SolutionValidate */, "validate", async () => {
1028
1114
  const projectResults = await Promise.all(solution.Projects.map((project) => {
1029
1115
  if (project.ProjectPath == null) {
1030
- return Promise.resolve(ToolResult3.error(ToolErrorCodes3.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
1116
+ return Promise.resolve(ToolResult4.error(ToolErrorCodes4.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
1031
1117
  }
1032
1118
  return this.projectExecutor.validateAsync(this.optionsBuilder.buildProjectValidateOptions(parameters, project), project, context, cancellationToken);
1033
1119
  }));
1034
1120
  const failed = projectResults.find((r) => !r.isSuccess);
1035
- return failed ?? ToolResult3.success();
1121
+ return failed ?? ToolResult4.success();
1036
1122
  }, { solutionId: solution.SolutionId });
1037
1123
  }
1038
1124
  }
@@ -1053,6 +1139,7 @@ class SolutionPackager {
1053
1139
  solutionPackService;
1054
1140
  solutionRestoreService;
1055
1141
  solutionValidateService;
1142
+ solutionCleanupService;
1056
1143
  packOptionsValidator;
1057
1144
  validateOptionsValidator;
1058
1145
  governancePolicyService;
@@ -1076,6 +1163,7 @@ class SolutionPackager {
1076
1163
  this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService, this.packageSignService);
1077
1164
  this.solutionRestoreService = new SolutionRestoreService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.telemetryService);
1078
1165
  this.solutionValidateService = new SolutionValidateService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
1166
+ this.solutionCleanupService = new SolutionCleanupService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
1079
1167
  }
1080
1168
  async setupAsync(input, operationId) {
1081
1169
  this.telemetryService.setOperationId(operationId);
@@ -1132,7 +1220,7 @@ class SolutionPackager {
1132
1220
  } catch (error) {
1133
1221
  const errorMessage = error instanceof Error ? error.message : String(error);
1134
1222
  this.logger.error(`Processing error: ${errorMessage}`);
1135
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution pack failed: ${errorMessage}`);
1223
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`);
1136
1224
  } finally {
1137
1225
  await this.temporaryStorage.cleanup();
1138
1226
  }
@@ -1159,7 +1247,7 @@ class SolutionPackager {
1159
1247
  } catch (error) {
1160
1248
  const errorMessage = error instanceof Error ? error.message : String(error);
1161
1249
  this.logger.error(`Processing error: ${errorMessage}`);
1162
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution validate failed: ${errorMessage}`);
1250
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`);
1163
1251
  } finally {
1164
1252
  await this.temporaryStorage.cleanup();
1165
1253
  }
@@ -1184,7 +1272,29 @@ class SolutionPackager {
1184
1272
  } catch (error) {
1185
1273
  const errorMessage = error instanceof Error ? error.message : String(error);
1186
1274
  this.logger.error(`Processing error: ${errorMessage}`);
1187
- return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution restore failed: ${errorMessage}`);
1275
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution restore failed: ${errorMessage}`);
1276
+ } finally {
1277
+ await this.temporaryStorage.cleanup();
1278
+ }
1279
+ });
1280
+ }
1281
+ async cleanupSolutionAsync(options, cancellationToken) {
1282
+ return await this.telemetryService.trackRequest("SolutionPackager.CleanupSolution" /* SolutionPackagerCleanupSolution */, async () => {
1283
+ try {
1284
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
1285
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
1286
+ const context = this.createOperationContext(options, solution);
1287
+ const result = await this.solutionCleanupService.cleanupAsync(options, solution, context, cancellationToken);
1288
+ if (result.isSuccess) {
1289
+ this.logger.info("Solution cleanup completed successfully.");
1290
+ } else {
1291
+ this.logger.error(`Solution cleanup failed with error code ${result.errorCode}: ${result.message}`);
1292
+ }
1293
+ return result;
1294
+ } catch (error) {
1295
+ const errorMessage = error instanceof Error ? error.message : String(error);
1296
+ this.logger.error(`Processing error: ${errorMessage}`);
1297
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution cleanup failed: ${errorMessage}`);
1188
1298
  } finally {
1189
1299
  await this.temporaryStorage.cleanup();
1190
1300
  }
@@ -1209,11 +1319,13 @@ class SolutionPackager {
1209
1319
  id: crypto.randomUUID(),
1210
1320
  projects: solution.Projects,
1211
1321
  downloadUrl: options.downloadUrl,
1322
+ solutionId: solution.SolutionId,
1212
1323
  configuration: options.configuration,
1213
1324
  targetFramework: options.targetFramework ?? TargetFramework.Portable,
1214
1325
  connection: options.connection,
1215
1326
  logger: this.logger,
1216
- workflowCompilerVersion: options.workflowCompilerVersion
1327
+ workflowCompilerVersion: options.workflowCompilerVersion,
1328
+ lockKey: options.lockKey
1217
1329
  };
1218
1330
  }
1219
1331
  async getPackageStreamsAsync(result) {
@@ -1263,4 +1375,4 @@ export {
1263
1375
  SolutionPackOptions
1264
1376
  };
1265
1377
 
1266
- //# debugId=374EFD55C7484FC664756E2164756E21
1378
+ //# debugId=6638B6BAF951D31364756E2164756E21
@@ -39,4 +39,24 @@ export declare class SolutionPackOptions extends PackagerParameters {
39
39
  * Publish information
40
40
  */
41
41
  publishInfo?: PublishInfo;
42
+ /**
43
+ * Cleanup options. Defaults to removing unused items and cleaning up
44
+ * now-unused references to them in the project's files.
45
+ */
46
+ cleanupOptions: CleanupOptions;
47
+ /**
48
+ * Lock key of the current editing session. Forwarded to the remote agent for
49
+ * Cleanup so its save-back overwrite is accepted while the solution is locked
50
+ * by that session. Set by the caller that holds the lock.
51
+ */
52
+ lockKey?: string;
53
+ }
54
+ /**
55
+ * Options controlling the cleanup operation.
56
+ */
57
+ export interface CleanupOptions {
58
+ /** Detect unused items without modifying the project. */
59
+ dryRun: boolean;
60
+ /** Do not clean up now-unused references to removed items in the project's files. */
61
+ skipImports: boolean;
42
62
  }
@@ -1,5 +1,5 @@
1
1
  import type { IPackService, UiPathProject } from "@uipath/project-packager";
2
- import { type IFileSystem, type IProjectPackOptions, type IProjectRestoreOptions, type IProjectValidateOptions, type ISolutionPackOptions } from "@uipath/solutionpackager-tool-core";
2
+ import { type IFileSystem, type IProjectCleanupOptions, type IProjectPackOptions, type IProjectRestoreOptions, type IProjectValidateOptions, type ISolutionPackOptions } from "@uipath/solutionpackager-tool-core";
3
3
  import type { LoadedUiPathSolution } from "../models/loaded-uipath-solution.js";
4
4
  import type { SolutionPackOptions } from "../models/solution-pack-options.js";
5
5
  import type { IPackageIdReader } from "./package-id-reader.js";
@@ -23,6 +23,10 @@ export interface IOptionsBuilder {
23
23
  * Build project restore options from solution parameters, for a specific project
24
24
  */
25
25
  buildProjectRestoreOptions(options: SolutionPackOptions, project: UiPathProject): Promise<IProjectRestoreOptions>;
26
+ /**
27
+ * Build project cleanup options from solution parameters, for a specific project
28
+ */
29
+ buildProjectCleanupOptions(options: SolutionPackOptions, project: UiPathProject): IProjectCleanupOptions;
26
30
  }
27
31
  export declare class OptionsBuilder implements IOptionsBuilder {
28
32
  private readonly packageIdReader;
@@ -38,6 +42,7 @@ export declare class OptionsBuilder implements IOptionsBuilder {
38
42
  buildProjectPackOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): Promise<IProjectPackOptions>;
39
43
  buildProjectValidateOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): IProjectValidateOptions;
40
44
  buildProjectRestoreOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): Promise<IProjectRestoreOptions>;
45
+ buildProjectCleanupOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): IProjectCleanupOptions;
41
46
  private resolveProjectPath;
42
47
  /**
43
48
  * Build the output path for a project
@@ -0,0 +1,20 @@
1
+ import type { IProjectToolExecutor, ITelemetryService } from "@uipath/project-packager";
2
+ import { type ProjectOperationContext, ToolResult } from "@uipath/solutionpackager-tool-core";
3
+ import type { LoadedUiPathSolution } from "../models/loaded-uipath-solution.js";
4
+ import type { SolutionPackOptions } from "../models/solution-pack-options.js";
5
+ import type { IOptionsBuilder } from "./options-builder.js";
6
+ export interface ISolutionCleanupService {
7
+ /**
8
+ * Clean up every project in the solution by removing unused items.
9
+ */
10
+ cleanupAsync(parameters: SolutionPackOptions, solution: LoadedUiPathSolution, context: ProjectOperationContext, cancellationToken?: AbortSignal): Promise<ToolResult>;
11
+ }
12
+ export declare class SolutionCleanupService implements ISolutionCleanupService {
13
+ private readonly optionsBuilder;
14
+ private readonly projectExecutor;
15
+ private readonly telemetry;
16
+ constructor(optionsBuilder: IOptionsBuilder, projectExecutor: IProjectToolExecutor, telemetry: ITelemetryService);
17
+ cleanupAsync(parameters: SolutionPackOptions, solution: LoadedUiPathSolution, context: ProjectOperationContext, cancellationToken?: AbortSignal): Promise<ToolResult>;
18
+ private mergeChangedFiles;
19
+ private collectProjectCleanups;
20
+ }
@@ -48,6 +48,15 @@ export interface ISolutionPackager {
48
48
  * @returns ToolResult indicating success if every project restored
49
49
  */
50
50
  restoreSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
51
+ /**
52
+ * Clean up every project in a solution by removing unused items. Modifies the
53
+ * project sources in place. When run via the remote agent against a cloud
54
+ * solution, the agent also saves the modified solution back to StudioWeb.
55
+ * @param options Solution pack options containing all parameters
56
+ * @param cancellationToken Optional cancellation token
57
+ * @returns ToolResult; `details.changedFilesByProject` lists the changed files per project
58
+ */
59
+ cleanupSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
51
60
  /**
52
61
  * Convert a successful ToolResult to a list of package streams.
53
62
  * @param result The ToolResult to convert
@@ -71,6 +80,7 @@ export declare class SolutionPackager implements ISolutionPackager {
71
80
  private readonly solutionPackService;
72
81
  private readonly solutionRestoreService;
73
82
  private readonly solutionValidateService;
83
+ private readonly solutionCleanupService;
74
84
  private readonly packOptionsValidator;
75
85
  private readonly validateOptionsValidator;
76
86
  private readonly governancePolicyService;
@@ -106,6 +116,10 @@ export declare class SolutionPackager implements ISolutionPackager {
106
116
  * or building.
107
117
  */
108
118
  restoreSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
119
+ /**
120
+ * Clean up every project in a solution by removing unused items.
121
+ */
122
+ cleanupSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
109
123
  /**
110
124
  * Narrow the solution's project list to the subset the caller asked for.
111
125
  * An empty or absent `projectDesignIds` is a no-op (the whole solution is
@@ -2,8 +2,10 @@ export declare enum TelemetryNames {
2
2
  SolutionPackagerPackSolution = "SolutionPackager.PackSolution",
3
3
  SolutionPackagerValidateSolution = "SolutionPackager.ValidateSolution",
4
4
  SolutionPackagerRestoreSolution = "SolutionPackager.RestoreSolution",
5
+ SolutionPackagerCleanupSolution = "SolutionPackager.CleanupSolution",
5
6
  SolutionPack = "SolutionPackager.Solution.Pack",
6
7
  SolutionValidate = "SolutionPackager.Solution.Validate",
7
8
  SolutionRestore = "SolutionPackager.Solution.Restore",
9
+ SolutionCleanup = "SolutionPackager.Solution.Cleanup",
8
10
  SolutionCompress = "SolutionPackager.Solution.Compress"
9
11
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uipath/solution-packager",
3
3
  "license": "MIT",
4
- "version": "1.197.0",
4
+ "version": "1.198.0-preview.80",
5
5
  "description": "UiPath Solution Packager - core library for packing UiPath solutions",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -28,11 +28,11 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@uipath/project-packager": "1.197.0",
32
- "@uipath/solutionpackager-tool-core": "1.197.0"
31
+ "@uipath/project-packager": "1.198.0",
32
+ "@uipath/solutionpackager-tool-core": "1.198.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "fflate": "^0.8.2"
36
36
  },
37
- "gitHead": "56f68b263cec4ea1f2a39d738bd99ecf52f88fea"
37
+ "gitHead": "9b2c3c0f21a256d2f38dd28bc97e72e6f7b10a9c"
38
38
  }