@uipath/solution-packager 0.0.30 → 0.0.34

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
@@ -337,22 +337,22 @@ I18nManager.registerTranslations("zu", zu_default);
337
337
  // src/index.ts
338
338
  import { RulesConfigFileType as RulesConfigFileType2 } from "@uipath/project-packager";
339
339
  import {
340
- BuildConfiguration as BuildConfiguration3,
340
+ BuildConfiguration as BuildConfiguration2,
341
341
  LogLevel
342
342
  } from "@uipath/solutionpackager-tool-core";
343
343
 
344
344
  // src/browser-solution-packager-factory.ts
345
+ import {
346
+ BrowserContextStorage,
347
+ ConsoleTelemetryProvider,
348
+ TelemetryService
349
+ } from "@uipath/common/telemetry";
345
350
  import { BrowserFileSystem } from "@uipath/filesystem/browser";
346
351
  import {
347
352
  setGlobalLogHandler,
348
353
  ToolLogger as ToolLogger2
349
354
  } from "@uipath/project-packager";
350
- import { translate as translate3 } from "@uipath/solutionpackager-tool-core";
351
- import {
352
- BrowserContextStorage,
353
- ConsoleTelemetryProvider,
354
- TelemetryService
355
- } from "@uipath/telemetry";
355
+ import { translate as translate4 } from "@uipath/solutionpackager-tool-core";
356
356
 
357
357
  // src/services/solution-packager.ts
358
358
  import {
@@ -366,15 +366,15 @@ import {
366
366
  Path as Path4,
367
367
  TargetFramework,
368
368
  TemporaryStorageService,
369
- ToolErrorCodes as ToolErrorCodes2,
370
- ToolResult as ToolResult2,
369
+ ToolErrorCodes as ToolErrorCodes3,
370
+ ToolResult as ToolResult3,
371
371
  toolsFactoryRepository,
372
+ translate as translate3,
372
373
  ZipService
373
374
  } from "@uipath/solutionpackager-tool-core";
374
375
 
375
376
  // src/services/options-builder.ts
376
377
  import {
377
- BuildConfiguration,
378
378
  Path,
379
379
  translate
380
380
  } from "@uipath/solutionpackager-tool-core";
@@ -394,7 +394,6 @@ class OptionsBuilder {
394
394
  throw new Error(translate.t("solutionpackager.optionsBuilder.errors.outputPathRequired"));
395
395
  }
396
396
  await this.createOutputFilesDirectoryAsync(parameters.outputPath);
397
- const projectsToBuild = this.getProjectIdsToBuild(parameters, solution);
398
397
  if (!parameters.package.id || parameters.package.id.trim() === "") {
399
398
  parameters.package.id = solution.Name;
400
399
  }
@@ -405,7 +404,7 @@ class OptionsBuilder {
405
404
  configuration: parameters.configuration,
406
405
  package: parameters.package,
407
406
  publishId: parameters.publishInfo?.id,
408
- projectsToBuild
407
+ projectsToBuild: solution.Projects.map((p) => p.Id)
409
408
  };
410
409
  }
411
410
  async createOutputFilesDirectoryAsync(outputPath) {
@@ -413,9 +412,7 @@ class OptionsBuilder {
413
412
  await this.fileSystem.mkdir(filesDir);
414
413
  }
415
414
  async buildProjectPackOptions(solutionOptions, project) {
416
- const solutionFolderPath = solutionOptions.inputPath;
417
- const projectRelativePath = Path.dirname(project.ProjectRelativePath);
418
- const projectPath = Path.join(solutionFolderPath, projectRelativePath);
415
+ const projectPath = this.resolveProjectPath(solutionOptions, project);
419
416
  const solutionName = solutionOptions.package.id || undefined;
420
417
  const packageInfo = {
421
418
  ...solutionOptions.package,
@@ -432,7 +429,7 @@ class OptionsBuilder {
432
429
  nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
433
430
  logLevel: solutionOptions.logLevel,
434
431
  skipAnalyze: solutionOptions.validateOptions.skipAnalyze,
435
- skipValidate: false,
432
+ skipValidate: solutionOptions.validateOptions.skipValidate,
436
433
  projectStorageId: project.StorageId,
437
434
  detailedLogPath: solutionOptions.detailedLogPath,
438
435
  policyFilePath: solutionOptions.validateOptions.governanceFilePath,
@@ -446,26 +443,29 @@ class OptionsBuilder {
446
443
  splitPackages: solutionOptions.packOptions?.splitPackages ?? false
447
444
  };
448
445
  }
446
+ buildProjectValidateOptions(solutionOptions, project) {
447
+ return {
448
+ projectPath: this.resolveProjectPath(solutionOptions, project),
449
+ excludeConfiguredSources: solutionOptions.excludeConfiguredSources ?? false,
450
+ nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
451
+ logLevel: solutionOptions.logLevel,
452
+ skipAnalyze: solutionOptions.validateOptions.skipAnalyze,
453
+ skipValidate: solutionOptions.validateOptions.skipValidate,
454
+ defaultSeverity: solutionOptions.validateOptions.defaultSeverity,
455
+ detailedLogPath: solutionOptions.detailedLogPath,
456
+ policyFilePath: solutionOptions.validateOptions.governanceFilePath,
457
+ policyFileType: solutionOptions.validateOptions.governanceFileType
458
+ };
459
+ }
460
+ resolveProjectPath(solutionOptions, project) {
461
+ return Path.join(solutionOptions.inputPath, Path.dirname(project.ProjectRelativePath));
462
+ }
449
463
  async buildProjectOutputPath(solutionOutputPath, project) {
450
464
  const filesDir = Path.join(solutionOutputPath, OptionsBuilder.FILES_DIRECTORY_NAME);
451
465
  const projectOutputPath = Path.join(filesDir, project.Id);
452
466
  await this.fileSystem.mkdir(projectOutputPath);
453
467
  return projectOutputPath;
454
468
  }
455
- getProjectIdsToBuild(parameters, solution) {
456
- const solutionProjectIds = solution.Projects.map((p) => p.Id);
457
- if (parameters.projectsToBuild === null || parameters.projectsToBuild === undefined || parameters.projectsToBuild.length === 0) {
458
- return parameters.configuration === BuildConfiguration.Release ? solutionProjectIds : [];
459
- }
460
- const invalidProjectIds = parameters.projectsToBuild.filter((id) => !solutionProjectIds.includes(id));
461
- if (invalidProjectIds.length > 0) {
462
- console.warn(translate.t("solutionpackager.optionsBuilder.errors.invalidProjectIds", {
463
- ids: invalidProjectIds.join(",")
464
- }));
465
- return solutionProjectIds.filter((id) => parameters.projectsToBuild?.includes(id));
466
- }
467
- return parameters.projectsToBuild;
468
- }
469
469
  }
470
470
 
471
471
  // src/services/package-id-reader.ts
@@ -481,7 +481,8 @@ class PackageIdReader {
481
481
  agent: "agent",
482
482
  api: "api",
483
483
  webapp: "webApp",
484
- process: "process"
484
+ process: "process",
485
+ flow: "flow"
485
486
  };
486
487
  static projectTypeMap = {
487
488
  process: "Rpa",
@@ -491,7 +492,8 @@ class PackageIdReader {
491
492
  processorchestration: "Agentic",
492
493
  casemanagement: "Case",
493
494
  api: "Api",
494
- agent: "Agent"
495
+ agent: "Agent",
496
+ flow: "Flow"
495
497
  };
496
498
  constructor(fileSystem, packService) {
497
499
  this.fileSystem = fileSystem;
@@ -805,6 +807,45 @@ class SolutionPackService {
805
807
  }
806
808
  }
807
809
 
810
+ // src/services/solution-validate-options-validator.ts
811
+ import {
812
+ PackagerParametersValidator as PackagerParametersValidator2
813
+ } from "@uipath/project-packager";
814
+
815
+ class SolutionValidateOptionsValidator extends PackagerParametersValidator2 {
816
+ async validateAsync(options, _cancellationToken) {
817
+ return await this.validateGovernanceOptions(options.validateOptions);
818
+ }
819
+ }
820
+
821
+ // src/services/solution-validate-service.ts
822
+ import {
823
+ ToolErrorCodes as ToolErrorCodes2,
824
+ ToolResult as ToolResult2
825
+ } from "@uipath/solutionpackager-tool-core";
826
+ class SolutionValidateService {
827
+ optionsBuilder;
828
+ projectExecutor;
829
+ telemetry;
830
+ constructor(optionsBuilder, projectExecutor, telemetry) {
831
+ this.optionsBuilder = optionsBuilder;
832
+ this.projectExecutor = projectExecutor;
833
+ this.telemetry = telemetry;
834
+ }
835
+ async validateAsync(parameters, solution, context, cancellationToken) {
836
+ return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Validate" /* SolutionValidate */, "validate", async () => {
837
+ const projectResults = await Promise.all(solution.Projects.map((project) => {
838
+ if (project.ProjectPath == null) {
839
+ return Promise.resolve(ToolResult2.error(ToolErrorCodes2.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
840
+ }
841
+ return this.projectExecutor.validateAsync(this.optionsBuilder.buildProjectValidateOptions(parameters, project), project, context, cancellationToken);
842
+ }));
843
+ const failed = projectResults.find((r) => !r.isSuccess);
844
+ return failed ?? ToolResult2.success();
845
+ }, { solutionId: solution.SolutionId });
846
+ }
847
+ }
848
+
808
849
  // src/services/solution-packager.ts
809
850
  class SolutionPackager {
810
851
  fileSystem;
@@ -819,7 +860,9 @@ class SolutionPackager {
819
860
  projectExecutor;
820
861
  solutionLoader;
821
862
  solutionPackService;
822
- optionsValidator;
863
+ solutionValidateService;
864
+ packOptionsValidator;
865
+ validateOptionsValidator;
823
866
  governancePolicyService;
824
867
  constructor(fileSystem, telemetryService, packageSignService) {
825
868
  this.fileSystem = fileSystem;
@@ -829,7 +872,8 @@ class SolutionPackager {
829
872
  this.temporaryStorage = new TemporaryStorageService(this.fileSystem);
830
873
  this.zipService = new ZipService(this.fileSystem);
831
874
  this.logger = new ToolLogger("SolutionPackager", "PackSolution");
832
- this.optionsValidator = new SolutionPackOptionsValidator(this.logger, this.fileSystem);
875
+ this.packOptionsValidator = new SolutionPackOptionsValidator(this.logger, this.fileSystem);
876
+ this.validateOptionsValidator = new SolutionValidateOptionsValidator(this.logger, this.fileSystem);
833
877
  const packService = new PackService;
834
878
  const packageIdReader = new PackageIdReader(this.fileSystem, packService);
835
879
  this.optionsBuilder = new OptionsBuilder(packageIdReader, packService, this.fileSystem);
@@ -838,6 +882,7 @@ class SolutionPackager {
838
882
  this.solutionLoader = new SolutionLoader(this.fileSystem);
839
883
  this.governancePolicyService = new GovernancePolicyService(this.fileSystem, this.temporaryStorage);
840
884
  this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService);
885
+ this.solutionValidateService = new SolutionValidateService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
841
886
  }
842
887
  async canPackSolutionAsync(solutionPath) {
843
888
  const solution = await this.solutionLoader.loadSolution(solutionPath);
@@ -887,14 +932,15 @@ class SolutionPackager {
887
932
  return await this.telemetryService.trackRequest("SolutionPackager.PackSolution" /* SolutionPackagerPackSolution */, async () => {
888
933
  try {
889
934
  await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
890
- let result = await this.optionsValidator.validateAsync(options, cancellationToken);
935
+ let result = await this.packOptionsValidator.validateAsync(options, cancellationToken);
891
936
  if (!result.isSuccess) {
892
937
  return result;
893
938
  }
894
939
  if (!options.outputPath) {
895
940
  options.outputPath = await this.temporaryStorage.getTempSubfolderPathAsync("output");
896
941
  }
897
- const solution = await this.solutionLoader.loadSolution(options.inputPath);
942
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
943
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
898
944
  const context = this.createOperationContext(options, solution);
899
945
  result = await this.solutionPackService.packAsync(options, solution, context, cancellationToken);
900
946
  if (result.isSuccess) {
@@ -906,16 +952,57 @@ class SolutionPackager {
906
952
  } catch (error) {
907
953
  const errorMessage = error instanceof Error ? error.message : String(error);
908
954
  this.logger.error(`Processing error: ${errorMessage}`);
909
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${errorMessage}`);
955
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution pack failed: ${errorMessage}`);
910
956
  } finally {
911
957
  await this.temporaryStorage.cleanup();
912
958
  }
913
959
  });
914
960
  }
961
+ async validateSolutionAsync(options, cancellationToken) {
962
+ return await this.telemetryService.trackRequest("SolutionPackager.ValidateSolution" /* SolutionPackagerValidateSolution */, async () => {
963
+ try {
964
+ await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
965
+ const validationResult = await this.validateOptionsValidator.validateAsync(options, cancellationToken);
966
+ if (!validationResult.isSuccess) {
967
+ return validationResult;
968
+ }
969
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
970
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
971
+ const context = this.createOperationContext(options, solution);
972
+ const result = await this.solutionValidateService.validateAsync(options, solution, context, cancellationToken);
973
+ if (result.isSuccess) {
974
+ this.logger.info("Solution validate completed successfully.");
975
+ } else {
976
+ this.logger.error(`Solution validate failed with error code ${result.errorCode}: ${result.message}`);
977
+ }
978
+ return result;
979
+ } catch (error) {
980
+ const errorMessage = error instanceof Error ? error.message : String(error);
981
+ this.logger.error(`Processing error: ${errorMessage}`);
982
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution validate failed: ${errorMessage}`);
983
+ } finally {
984
+ await this.temporaryStorage.cleanup();
985
+ }
986
+ });
987
+ }
988
+ filterSolutionProjects(solution, projectDesignIds) {
989
+ if (!projectDesignIds?.length)
990
+ return solution;
991
+ const solutionProjectIds = new Set(solution.Projects.map((p) => p.Id));
992
+ const unknownIds = projectDesignIds.filter((id) => !solutionProjectIds.has(id));
993
+ if (unknownIds.length > 0) {
994
+ this.logger.warn(translate3.t("solutionpackager.optionsBuilder.errors.invalidProjectIds", { ids: unknownIds.join(",") }));
995
+ }
996
+ const requested = new Set(projectDesignIds);
997
+ return {
998
+ ...solution,
999
+ Projects: solution.Projects.filter((p) => requested.has(p.Id))
1000
+ };
1001
+ }
915
1002
  createOperationContext(options, solution) {
916
1003
  return {
917
1004
  id: crypto.randomUUID(),
918
- solution,
1005
+ projects: solution.Projects,
919
1006
  downloadUrl: options.downloadUrl,
920
1007
  configuration: options.configuration,
921
1008
  targetFramework: options.targetFramework ?? TargetFramework.Portable,
@@ -998,7 +1085,7 @@ class BrowserSolutionPackagerFactory {
998
1085
  }
999
1086
  configureLanguage(config) {
1000
1087
  const language = config?.language ?? "en";
1001
- translate3.setLocale(language);
1088
+ translate4.setLocale(language);
1002
1089
  }
1003
1090
  }
1004
1091
  async function createBrowserSolutionPackager(options) {
@@ -1011,19 +1098,19 @@ import {
1011
1098
  RulesConfigFileType
1012
1099
  } from "@uipath/project-packager";
1013
1100
  import {
1014
- BuildConfiguration as BuildConfiguration2
1101
+ BuildConfiguration
1015
1102
  } from "@uipath/solutionpackager-tool-core";
1016
1103
 
1017
1104
  class SolutionPackOptions extends PackagerParameters {
1018
- downloadUrl;
1019
1105
  destinationPath;
1020
- projectsToBuild;
1106
+ projectDesignIds;
1021
1107
  validateOptions = {
1022
1108
  skipAnalyze: false,
1109
+ skipValidate: false,
1023
1110
  governanceFileType: RulesConfigFileType.Default
1024
1111
  };
1025
1112
  package;
1026
- configuration = BuildConfiguration2.Release;
1113
+ configuration = BuildConfiguration.Release;
1027
1114
  signingInfo;
1028
1115
  packOptions;
1029
1116
  publishInfo;
@@ -1034,5 +1121,5 @@ export {
1034
1121
  SolutionPackOptions,
1035
1122
  RulesConfigFileType2 as RulesConfigFileType,
1036
1123
  LogLevel,
1037
- BuildConfiguration3 as BuildConfiguration
1124
+ BuildConfiguration2 as BuildConfiguration
1038
1125
  };
package/dist/node.js CHANGED
@@ -344,11 +344,11 @@ import {
344
344
  } from "@uipath/solutionpackager-tool-core";
345
345
 
346
346
  class SolutionPackOptions extends PackagerParameters {
347
- downloadUrl;
348
347
  destinationPath;
349
- projectsToBuild;
348
+ projectDesignIds;
350
349
  validateOptions = {
351
350
  skipAnalyze: false,
351
+ skipValidate: false,
352
352
  governanceFileType: RulesConfigFileType.Default
353
353
  };
354
354
  package;
@@ -376,15 +376,15 @@ import {
376
376
  Path as Path4,
377
377
  TargetFramework,
378
378
  TemporaryStorageService,
379
- ToolErrorCodes as ToolErrorCodes2,
380
- ToolResult as ToolResult2,
379
+ ToolErrorCodes as ToolErrorCodes3,
380
+ ToolResult as ToolResult3,
381
381
  toolsFactoryRepository,
382
+ translate as translate3,
382
383
  ZipService
383
384
  } from "@uipath/solutionpackager-tool-core";
384
385
 
385
386
  // src/services/options-builder.ts
386
387
  import {
387
- BuildConfiguration as BuildConfiguration2,
388
388
  Path,
389
389
  translate
390
390
  } from "@uipath/solutionpackager-tool-core";
@@ -404,7 +404,6 @@ class OptionsBuilder {
404
404
  throw new Error(translate.t("solutionpackager.optionsBuilder.errors.outputPathRequired"));
405
405
  }
406
406
  await this.createOutputFilesDirectoryAsync(parameters.outputPath);
407
- const projectsToBuild = this.getProjectIdsToBuild(parameters, solution);
408
407
  if (!parameters.package.id || parameters.package.id.trim() === "") {
409
408
  parameters.package.id = solution.Name;
410
409
  }
@@ -415,7 +414,7 @@ class OptionsBuilder {
415
414
  configuration: parameters.configuration,
416
415
  package: parameters.package,
417
416
  publishId: parameters.publishInfo?.id,
418
- projectsToBuild
417
+ projectsToBuild: solution.Projects.map((p) => p.Id)
419
418
  };
420
419
  }
421
420
  async createOutputFilesDirectoryAsync(outputPath) {
@@ -423,9 +422,7 @@ class OptionsBuilder {
423
422
  await this.fileSystem.mkdir(filesDir);
424
423
  }
425
424
  async buildProjectPackOptions(solutionOptions, project) {
426
- const solutionFolderPath = solutionOptions.inputPath;
427
- const projectRelativePath = Path.dirname(project.ProjectRelativePath);
428
- const projectPath = Path.join(solutionFolderPath, projectRelativePath);
425
+ const projectPath = this.resolveProjectPath(solutionOptions, project);
429
426
  const solutionName = solutionOptions.package.id || undefined;
430
427
  const packageInfo = {
431
428
  ...solutionOptions.package,
@@ -442,7 +439,7 @@ class OptionsBuilder {
442
439
  nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
443
440
  logLevel: solutionOptions.logLevel,
444
441
  skipAnalyze: solutionOptions.validateOptions.skipAnalyze,
445
- skipValidate: false,
442
+ skipValidate: solutionOptions.validateOptions.skipValidate,
446
443
  projectStorageId: project.StorageId,
447
444
  detailedLogPath: solutionOptions.detailedLogPath,
448
445
  policyFilePath: solutionOptions.validateOptions.governanceFilePath,
@@ -456,26 +453,29 @@ class OptionsBuilder {
456
453
  splitPackages: solutionOptions.packOptions?.splitPackages ?? false
457
454
  };
458
455
  }
456
+ buildProjectValidateOptions(solutionOptions, project) {
457
+ return {
458
+ projectPath: this.resolveProjectPath(solutionOptions, project),
459
+ excludeConfiguredSources: solutionOptions.excludeConfiguredSources ?? false,
460
+ nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
461
+ logLevel: solutionOptions.logLevel,
462
+ skipAnalyze: solutionOptions.validateOptions.skipAnalyze,
463
+ skipValidate: solutionOptions.validateOptions.skipValidate,
464
+ defaultSeverity: solutionOptions.validateOptions.defaultSeverity,
465
+ detailedLogPath: solutionOptions.detailedLogPath,
466
+ policyFilePath: solutionOptions.validateOptions.governanceFilePath,
467
+ policyFileType: solutionOptions.validateOptions.governanceFileType
468
+ };
469
+ }
470
+ resolveProjectPath(solutionOptions, project) {
471
+ return Path.join(solutionOptions.inputPath, Path.dirname(project.ProjectRelativePath));
472
+ }
459
473
  async buildProjectOutputPath(solutionOutputPath, project) {
460
474
  const filesDir = Path.join(solutionOutputPath, OptionsBuilder.FILES_DIRECTORY_NAME);
461
475
  const projectOutputPath = Path.join(filesDir, project.Id);
462
476
  await this.fileSystem.mkdir(projectOutputPath);
463
477
  return projectOutputPath;
464
478
  }
465
- getProjectIdsToBuild(parameters, solution) {
466
- const solutionProjectIds = solution.Projects.map((p) => p.Id);
467
- if (parameters.projectsToBuild === null || parameters.projectsToBuild === undefined || parameters.projectsToBuild.length === 0) {
468
- return parameters.configuration === BuildConfiguration2.Release ? solutionProjectIds : [];
469
- }
470
- const invalidProjectIds = parameters.projectsToBuild.filter((id) => !solutionProjectIds.includes(id));
471
- if (invalidProjectIds.length > 0) {
472
- console.warn(translate.t("solutionpackager.optionsBuilder.errors.invalidProjectIds", {
473
- ids: invalidProjectIds.join(",")
474
- }));
475
- return solutionProjectIds.filter((id) => parameters.projectsToBuild?.includes(id));
476
- }
477
- return parameters.projectsToBuild;
478
- }
479
479
  }
480
480
 
481
481
  // src/services/package-id-reader.ts
@@ -491,7 +491,8 @@ class PackageIdReader {
491
491
  agent: "agent",
492
492
  api: "api",
493
493
  webapp: "webApp",
494
- process: "process"
494
+ process: "process",
495
+ flow: "flow"
495
496
  };
496
497
  static projectTypeMap = {
497
498
  process: "Rpa",
@@ -501,7 +502,8 @@ class PackageIdReader {
501
502
  processorchestration: "Agentic",
502
503
  casemanagement: "Case",
503
504
  api: "Api",
504
- agent: "Agent"
505
+ agent: "Agent",
506
+ flow: "Flow"
505
507
  };
506
508
  constructor(fileSystem, packService) {
507
509
  this.fileSystem = fileSystem;
@@ -815,6 +817,45 @@ class SolutionPackService {
815
817
  }
816
818
  }
817
819
 
820
+ // src/services/solution-validate-options-validator.ts
821
+ import {
822
+ PackagerParametersValidator as PackagerParametersValidator2
823
+ } from "@uipath/project-packager";
824
+
825
+ class SolutionValidateOptionsValidator extends PackagerParametersValidator2 {
826
+ async validateAsync(options, _cancellationToken) {
827
+ return await this.validateGovernanceOptions(options.validateOptions);
828
+ }
829
+ }
830
+
831
+ // src/services/solution-validate-service.ts
832
+ import {
833
+ ToolErrorCodes as ToolErrorCodes2,
834
+ ToolResult as ToolResult2
835
+ } from "@uipath/solutionpackager-tool-core";
836
+ class SolutionValidateService {
837
+ optionsBuilder;
838
+ projectExecutor;
839
+ telemetry;
840
+ constructor(optionsBuilder, projectExecutor, telemetry) {
841
+ this.optionsBuilder = optionsBuilder;
842
+ this.projectExecutor = projectExecutor;
843
+ this.telemetry = telemetry;
844
+ }
845
+ async validateAsync(parameters, solution, context, cancellationToken) {
846
+ return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Validate" /* SolutionValidate */, "validate", async () => {
847
+ const projectResults = await Promise.all(solution.Projects.map((project) => {
848
+ if (project.ProjectPath == null) {
849
+ return Promise.resolve(ToolResult2.error(ToolErrorCodes2.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
850
+ }
851
+ return this.projectExecutor.validateAsync(this.optionsBuilder.buildProjectValidateOptions(parameters, project), project, context, cancellationToken);
852
+ }));
853
+ const failed = projectResults.find((r) => !r.isSuccess);
854
+ return failed ?? ToolResult2.success();
855
+ }, { solutionId: solution.SolutionId });
856
+ }
857
+ }
858
+
818
859
  // src/services/solution-packager.ts
819
860
  class SolutionPackager {
820
861
  fileSystem;
@@ -829,7 +870,9 @@ class SolutionPackager {
829
870
  projectExecutor;
830
871
  solutionLoader;
831
872
  solutionPackService;
832
- optionsValidator;
873
+ solutionValidateService;
874
+ packOptionsValidator;
875
+ validateOptionsValidator;
833
876
  governancePolicyService;
834
877
  constructor(fileSystem, telemetryService, packageSignService) {
835
878
  this.fileSystem = fileSystem;
@@ -839,7 +882,8 @@ class SolutionPackager {
839
882
  this.temporaryStorage = new TemporaryStorageService(this.fileSystem);
840
883
  this.zipService = new ZipService(this.fileSystem);
841
884
  this.logger = new ToolLogger("SolutionPackager", "PackSolution");
842
- this.optionsValidator = new SolutionPackOptionsValidator(this.logger, this.fileSystem);
885
+ this.packOptionsValidator = new SolutionPackOptionsValidator(this.logger, this.fileSystem);
886
+ this.validateOptionsValidator = new SolutionValidateOptionsValidator(this.logger, this.fileSystem);
843
887
  const packService = new PackService;
844
888
  const packageIdReader = new PackageIdReader(this.fileSystem, packService);
845
889
  this.optionsBuilder = new OptionsBuilder(packageIdReader, packService, this.fileSystem);
@@ -848,6 +892,7 @@ class SolutionPackager {
848
892
  this.solutionLoader = new SolutionLoader(this.fileSystem);
849
893
  this.governancePolicyService = new GovernancePolicyService(this.fileSystem, this.temporaryStorage);
850
894
  this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService);
895
+ this.solutionValidateService = new SolutionValidateService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
851
896
  }
852
897
  async canPackSolutionAsync(solutionPath) {
853
898
  const solution = await this.solutionLoader.loadSolution(solutionPath);
@@ -897,14 +942,15 @@ class SolutionPackager {
897
942
  return await this.telemetryService.trackRequest("SolutionPackager.PackSolution" /* SolutionPackagerPackSolution */, async () => {
898
943
  try {
899
944
  await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
900
- let result = await this.optionsValidator.validateAsync(options, cancellationToken);
945
+ let result = await this.packOptionsValidator.validateAsync(options, cancellationToken);
901
946
  if (!result.isSuccess) {
902
947
  return result;
903
948
  }
904
949
  if (!options.outputPath) {
905
950
  options.outputPath = await this.temporaryStorage.getTempSubfolderPathAsync("output");
906
951
  }
907
- const solution = await this.solutionLoader.loadSolution(options.inputPath);
952
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
953
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
908
954
  const context = this.createOperationContext(options, solution);
909
955
  result = await this.solutionPackService.packAsync(options, solution, context, cancellationToken);
910
956
  if (result.isSuccess) {
@@ -916,16 +962,57 @@ class SolutionPackager {
916
962
  } catch (error) {
917
963
  const errorMessage = error instanceof Error ? error.message : String(error);
918
964
  this.logger.error(`Processing error: ${errorMessage}`);
919
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${errorMessage}`);
965
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution pack failed: ${errorMessage}`);
920
966
  } finally {
921
967
  await this.temporaryStorage.cleanup();
922
968
  }
923
969
  });
924
970
  }
971
+ async validateSolutionAsync(options, cancellationToken) {
972
+ return await this.telemetryService.trackRequest("SolutionPackager.ValidateSolution" /* SolutionPackagerValidateSolution */, async () => {
973
+ try {
974
+ await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
975
+ const validationResult = await this.validateOptionsValidator.validateAsync(options, cancellationToken);
976
+ if (!validationResult.isSuccess) {
977
+ return validationResult;
978
+ }
979
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
980
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
981
+ const context = this.createOperationContext(options, solution);
982
+ const result = await this.solutionValidateService.validateAsync(options, solution, context, cancellationToken);
983
+ if (result.isSuccess) {
984
+ this.logger.info("Solution validate completed successfully.");
985
+ } else {
986
+ this.logger.error(`Solution validate failed with error code ${result.errorCode}: ${result.message}`);
987
+ }
988
+ return result;
989
+ } catch (error) {
990
+ const errorMessage = error instanceof Error ? error.message : String(error);
991
+ this.logger.error(`Processing error: ${errorMessage}`);
992
+ return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution validate failed: ${errorMessage}`);
993
+ } finally {
994
+ await this.temporaryStorage.cleanup();
995
+ }
996
+ });
997
+ }
998
+ filterSolutionProjects(solution, projectDesignIds) {
999
+ if (!projectDesignIds?.length)
1000
+ return solution;
1001
+ const solutionProjectIds = new Set(solution.Projects.map((p) => p.Id));
1002
+ const unknownIds = projectDesignIds.filter((id) => !solutionProjectIds.has(id));
1003
+ if (unknownIds.length > 0) {
1004
+ this.logger.warn(translate3.t("solutionpackager.optionsBuilder.errors.invalidProjectIds", { ids: unknownIds.join(",") }));
1005
+ }
1006
+ const requested = new Set(projectDesignIds);
1007
+ return {
1008
+ ...solution,
1009
+ Projects: solution.Projects.filter((p) => requested.has(p.Id))
1010
+ };
1011
+ }
925
1012
  createOperationContext(options, solution) {
926
1013
  return {
927
1014
  id: crypto.randomUUID(),
928
- solution,
1015
+ projects: solution.Projects,
929
1016
  downloadUrl: options.downloadUrl,
930
1017
  configuration: options.configuration,
931
1018
  targetFramework: options.targetFramework ?? TargetFramework.Portable,
@@ -5,18 +5,16 @@ import { BuildConfiguration, type NugetPackageInfo } from "@uipath/solutionpacka
5
5
  * Solution-specific parameters extending base packager parameters
6
6
  */
7
7
  export declare class SolutionPackOptions extends PackagerParameters {
8
- /**
9
- * URL to download the solution snapshot for remote packing
10
- */
11
- downloadUrl?: string;
12
8
  /**
13
9
  * Path to the folder where the packed output will be stored.
14
10
  */
15
11
  destinationPath: string;
16
12
  /**
17
- * Array of project names/paths to build
13
+ * Subset of solution project design IDs (the `Id` field of each
14
+ * `UiPathProject` in the solution model) to process. Empty or undefined
15
+ * means "all projects". Unknown IDs are logged and silently dropped.
18
16
  */
19
- projectsToBuild?: string[];
17
+ projectDesignIds?: string[];
20
18
  /**
21
19
  * Validate options
22
20
  */
@@ -1,5 +1,5 @@
1
1
  import type { IPackService, UiPathProject } from "@uipath/project-packager";
2
- import { type IFileSystem, type IProjectPackOptions, type ISolutionPackOptions } from "@uipath/solutionpackager-tool-core";
2
+ import { type IFileSystem, type IProjectPackOptions, 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";
@@ -15,6 +15,10 @@ export interface IOptionsBuilder {
15
15
  * Build project pack options from solution parameters, for a specific project
16
16
  */
17
17
  buildProjectPackOptions(options: SolutionPackOptions, project: UiPathProject): Promise<IProjectPackOptions>;
18
+ /**
19
+ * Build project validate options from solution parameters, for a specific project
20
+ */
21
+ buildProjectValidateOptions(options: SolutionPackOptions, project: UiPathProject): IProjectValidateOptions;
18
22
  }
19
23
  export declare class OptionsBuilder implements IOptionsBuilder {
20
24
  private readonly packageIdReader;
@@ -28,6 +32,8 @@ export declare class OptionsBuilder implements IOptionsBuilder {
28
32
  * Build project pack options from solution parameters for a specific project
29
33
  */
30
34
  buildProjectPackOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): Promise<IProjectPackOptions>;
35
+ buildProjectValidateOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): IProjectValidateOptions;
36
+ private resolveProjectPath;
31
37
  /**
32
38
  * Build the output path for a project
33
39
  * Path structure: {solutionOutputFolder}/files/{projectId}
@@ -35,8 +41,4 @@ export declare class OptionsBuilder implements IOptionsBuilder {
35
41
  * @returns The output path for the project
36
42
  */
37
43
  private buildProjectOutputPath;
38
- /**
39
- * Get the list of project IDs to build based on parameters and solution
40
- */
41
- private getProjectIdsToBuild;
42
44
  }
@@ -38,6 +38,13 @@ export interface ISolutionPackager {
38
38
  * @returns ToolResult with the path to the created solution package
39
39
  */
40
40
  packSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
41
+ /**
42
+ * Validate all projects in a solution using the provided options.
43
+ * @param options Solution pack options containing all parameters
44
+ * @param cancellationToken Optional cancellation token
45
+ * @returns ToolResult indicating success if every project passed validation
46
+ */
47
+ validateSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
41
48
  /**
42
49
  * Convert a successful ToolResult to a list of package streams.
43
50
  * @param result The ToolResult to convert
@@ -59,7 +66,9 @@ export declare class SolutionPackager implements ISolutionPackager {
59
66
  private readonly projectExecutor;
60
67
  private readonly solutionLoader;
61
68
  private readonly solutionPackService;
62
- private readonly optionsValidator;
69
+ private readonly solutionValidateService;
70
+ private readonly packOptionsValidator;
71
+ private readonly validateOptionsValidator;
63
72
  private readonly governancePolicyService;
64
73
  constructor(fileSystem: IFileSystem, telemetryService: ITelemetryService, packageSignService?: IPackageSignService | undefined);
65
74
  /**
@@ -90,6 +99,21 @@ export declare class SolutionPackager implements ISolutionPackager {
90
99
  * @returns ToolResult with the path to the created solution package
91
100
  */
92
101
  packSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
102
+ /**
103
+ * Validate all projects in a solution using the provided options.
104
+ */
105
+ validateSolutionAsync(options: SolutionPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
106
+ /**
107
+ * Narrow the solution's project list to the subset the caller asked for.
108
+ * An empty or absent `projectDesignIds` is a no-op (the whole solution is
109
+ * processed). Unknown IDs are warned about and silently dropped.
110
+ *
111
+ * The filter must be applied before `createOperationContext` so that
112
+ * `ProjectOperationContext.projects` — which the remote-agent bundle
113
+ * executor uses to count compatible projects up front — stays in sync
114
+ * with what the pack/validate fan-out actually enqueues.
115
+ */
116
+ private filterSolutionProjects;
93
117
  private createOperationContext;
94
118
  /**
95
119
  * Convert a successful ToolResult to a list of package streams.
@@ -0,0 +1,7 @@
1
+ import { type IPackagerParametersValidator, PackagerParametersValidator } from "@uipath/project-packager";
2
+ import type { ToolResult } from "@uipath/solutionpackager-tool-core";
3
+ import type { SolutionPackOptions } from "../models/solution-pack-options.js";
4
+ export type ISolutionValidateOptionsValidator = IPackagerParametersValidator<SolutionPackOptions>;
5
+ export declare class SolutionValidateOptionsValidator extends PackagerParametersValidator<SolutionPackOptions> implements ISolutionValidateOptionsValidator {
6
+ validateAsync(options: SolutionPackOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
7
+ }
@@ -0,0 +1,15 @@
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 ISolutionValidateService {
7
+ validateAsync(parameters: SolutionPackOptions, solution: LoadedUiPathSolution, context: ProjectOperationContext, cancellationToken?: AbortSignal): Promise<ToolResult>;
8
+ }
9
+ export declare class SolutionValidateService implements ISolutionValidateService {
10
+ private readonly optionsBuilder;
11
+ private readonly projectExecutor;
12
+ private readonly telemetry;
13
+ constructor(optionsBuilder: IOptionsBuilder, projectExecutor: IProjectToolExecutor, telemetry: ITelemetryService);
14
+ validateAsync(parameters: SolutionPackOptions, solution: LoadedUiPathSolution, context: ProjectOperationContext, cancellationToken?: AbortSignal): Promise<ToolResult>;
15
+ }
@@ -1,5 +1,7 @@
1
1
  export declare enum TelemetryNames {
2
2
  SolutionPackagerPackSolution = "SolutionPackager.PackSolution",
3
+ SolutionPackagerValidateSolution = "SolutionPackager.ValidateSolution",
3
4
  SolutionPack = "SolutionPackager.Solution.Pack",
5
+ SolutionValidate = "SolutionPackager.Solution.Validate",
4
6
  SolutionCompress = "SolutionPackager.Solution.Compress"
5
7
  }
@@ -1 +1 @@
1
- export {};
1
+ import "../src/i18n/index.js";
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/solution-packager",
3
- "version": "0.0.30",
3
+ "version": "0.0.34",
4
4
  "description": "UiPath Solution Packager - core library for packing UiPath solutions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "!dist/**/*.map"
29
29
  ],
30
30
  "scripts": {
31
- "build": "bun build ./src/index.ts --outdir dist --format esm --target browser --external @uipath/solutionpackager-tool-core --external '@uipath/project-packager/*' --external @uipath/project-packager --external '@uipath/filesystem/*' --external @uipath/filesystem --external '@uipath/telemetry/*' --external @uipath/telemetry && bun build ./src/node.ts --outdir dist --format esm --target node --external @uipath/solutionpackager-tool-core --external '@uipath/project-packager/*' --external @uipath/project-packager --external '@uipath/telemetry/*' --external @uipath/telemetry --external '@uipath/filesystem/*' --external @uipath/filesystem && tsc --emitDeclarationOnly --outDir dist",
31
+ "build": "bun build ./src/index.ts --outdir dist --format esm --target browser --external @uipath/solutionpackager-tool-core --external '@uipath/project-packager/*' --external @uipath/project-packager --external '@uipath/filesystem/*' --external @uipath/filesystem --external '@uipath/common/*' --external @uipath/common && bun build ./src/node.ts --outdir dist --format esm --target node --external @uipath/solutionpackager-tool-core --external '@uipath/project-packager/*' --external @uipath/project-packager --external '@uipath/common/*' --external @uipath/common --external '@uipath/filesystem/*' --external @uipath/filesystem && tsc --emitDeclarationOnly --outDir dist",
32
32
  "clean": "rimraf dist",
33
33
  "test": "vitest run",
34
34
  "e2e": "vitest run --config vitest.e2e.config.ts",
@@ -46,10 +46,10 @@
46
46
  "lint": "biome check ."
47
47
  },
48
48
  "dependencies": {
49
- "@uipath/project-packager": "1.1.10",
50
- "@uipath/telemetry": "0.0.6",
51
- "@uipath/filesystem": "0.1.7",
52
- "@uipath/solutionpackager-tool-core": "0.0.31"
49
+ "@uipath/project-packager": "1.1.15",
50
+ "@uipath/common": "0.9.0",
51
+ "@uipath/filesystem": "0.9.0",
52
+ "@uipath/solutionpackager-tool-core": "0.0.33"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "fflate": "^0.8.2"
@@ -58,13 +58,13 @@
58
58
  "@types/node": "^25.5.0",
59
59
  "@uipath/resource-builder-tool": "^2025.11.0-alpha2430-2948",
60
60
  "@uipath/tool-agent": "^1.0.1",
61
- "@uipath/packager-tool-apiworkflow": "0.0.17",
62
- "@uipath/packager-tool-bpmn": "0.0.7",
63
- "@uipath/packager-tool-case": "0.0.7",
64
- "@uipath/packager-tool-connector": "0.0.17",
65
- "@uipath/packager-tool-flow": "0.0.17",
66
- "@uipath/packager-tool-webapp": "1.0.4",
67
- "@uipath/packager-tool-workflowcompiler": "0.0.14",
61
+ "@uipath/packager-tool-apiworkflow": "0.0.18",
62
+ "@uipath/packager-tool-bpmn": "0.0.8",
63
+ "@uipath/packager-tool-case": "0.0.8",
64
+ "@uipath/packager-tool-connector": "0.0.18",
65
+ "@uipath/packager-tool-flow": "0.0.18",
66
+ "@uipath/packager-tool-webapp": "1.0.5",
67
+ "@uipath/packager-tool-workflowcompiler": "0.0.15",
68
68
  "@vitest/browser": "^4.0.14",
69
69
  "@vitest/browser-playwright": "^4.0.14",
70
70
  "@vitest/coverage-v8": "^4.0.14",
@@ -72,5 +72,6 @@
72
72
  "typescript": "^5.9.3",
73
73
  "vite-tsconfig-paths": "^6.1.1",
74
74
  "vitest": "^4.0.14"
75
- }
75
+ },
76
+ "gitHead": "3f1b4d8e9f910be81e4cab956537f21dbd5d63ac"
76
77
  }