@uipath/solution-packager 0.0.34 → 1.197.0-preview.64

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 (26) hide show
  1. package/dist/index.js +239 -95
  2. package/dist/node.js +239 -41
  3. package/dist/src/browser-solution-packager-factory.d.ts +11 -4
  4. package/dist/src/i18n/locales/en.d.ts +3 -0
  5. package/dist/src/node-solution-packager-factory.d.ts +0 -1
  6. package/dist/src/services/options-builder.d.ts +6 -1
  7. package/dist/src/services/solution-loader.d.ts +1 -1
  8. package/dist/src/services/solution-pack-service.d.ts +24 -12
  9. package/dist/src/services/solution-packager.d.ts +15 -12
  10. package/dist/src/services/solution-restore-service.d.ts +23 -0
  11. package/dist/src/services/tool-result-helpers.d.ts +10 -0
  12. package/dist/src/telemetry-names.d.ts +2 -0
  13. package/dist/tests/solution-validate-options-validator.spec.d.ts +1 -0
  14. package/dist/tests/solution-validate-service.spec.d.ts +1 -0
  15. package/dist/tests/zip-temp-storage.integration.test.d.ts +1 -0
  16. package/package.json +35 -74
  17. package/dist/tests/solution-packager-e2e.test.d.ts +0 -9
  18. /package/dist/tests/{browser.test.d.ts → browser.spec.d.ts} +0 -0
  19. /package/dist/tests/{common.test.d.ts → common.spec.d.ts} +0 -0
  20. /package/dist/tests/{node.test.d.ts → node.spec.d.ts} +0 -0
  21. /package/dist/tests/{solution-pack-service.test.d.ts → options-builder.spec.d.ts} +0 -0
  22. /package/dist/tests/{solution-loader.test.d.ts → solution-loader.spec.d.ts} +0 -0
  23. /package/dist/tests/{solution-validate-options-validator.test.d.ts → solution-pack-service.spec.d.ts} +0 -0
  24. /package/dist/tests/{solution-validate-service.test.d.ts → solution-packager.e2e.test.d.ts} +0 -0
  25. /package/dist/tests/{solution-packager.test.d.ts → solution-packager.spec.d.ts} +0 -0
  26. /package/dist/tests/{zip-temp-storage-integration.test.d.ts → solution-restore-service.spec.d.ts} +0 -0
package/dist/node.js CHANGED
@@ -8,6 +8,9 @@ var de_default = {
8
8
  pathRequired: "Solution directory path is required",
9
9
  fileNotFound: "Solution file not found: {path}",
10
10
  invalidSolution: "Invalid solution file: {path}",
11
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
12
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
13
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
11
14
  noSolutionFile: "No .uipx solution file found in directory: {path}",
12
15
  invalidStorageFile: "Invalid {fileName} file"
13
16
  }
@@ -30,6 +33,9 @@ var en = {
30
33
  pathRequired: "Solution directory path is required",
31
34
  fileNotFound: "Solution file not found: {path}",
32
35
  invalidSolution: "Invalid solution file: {path}",
36
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
37
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
38
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
33
39
  noSolutionFile: "No .uipx solution file found in directory: {path}",
34
40
  invalidStorageFile: "Invalid {fileName} file"
35
41
  }
@@ -51,6 +57,9 @@ var es_default = {
51
57
  pathRequired: "Solution directory path is required",
52
58
  fileNotFound: "Solution file not found: {path}",
53
59
  invalidSolution: "Invalid solution file: {path}",
60
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
61
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
62
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
54
63
  noSolutionFile: "No .uipx solution file found in directory: {path}",
55
64
  invalidStorageFile: "Invalid {fileName} file"
56
65
  }
@@ -72,6 +81,9 @@ var es_MX_default = {
72
81
  pathRequired: "Solution directory path is required",
73
82
  fileNotFound: "Solution file not found: {path}",
74
83
  invalidSolution: "Invalid solution file: {path}",
84
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
85
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
86
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
75
87
  noSolutionFile: "No .uipx solution file found in directory: {path}",
76
88
  invalidStorageFile: "Invalid {fileName} file"
77
89
  }
@@ -93,6 +105,9 @@ var fr_default = {
93
105
  pathRequired: "Solution directory path is required",
94
106
  fileNotFound: "Solution file not found: {path}",
95
107
  invalidSolution: "Invalid solution file: {path}",
108
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
109
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
110
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
96
111
  noSolutionFile: "No .uipx solution file found in directory: {path}",
97
112
  invalidStorageFile: "Invalid {fileName} file"
98
113
  }
@@ -114,6 +129,9 @@ var ja_default = {
114
129
  pathRequired: "Solution directory path is required",
115
130
  fileNotFound: "Solution file not found: {path}",
116
131
  invalidSolution: "Invalid solution file: {path}",
132
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
133
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
134
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
117
135
  noSolutionFile: "No .uipx solution file found in directory: {path}",
118
136
  invalidStorageFile: "Invalid {fileName} file"
119
137
  }
@@ -135,6 +153,9 @@ var ko_default = {
135
153
  pathRequired: "Solution directory path is required",
136
154
  fileNotFound: "Solution file not found: {path}",
137
155
  invalidSolution: "Invalid solution file: {path}",
156
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
157
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
158
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
138
159
  noSolutionFile: "No .uipx solution file found in directory: {path}",
139
160
  invalidStorageFile: "Invalid {fileName} file"
140
161
  }
@@ -156,6 +177,9 @@ var pt_default = {
156
177
  pathRequired: "Solution directory path is required",
157
178
  fileNotFound: "Solution file not found: {path}",
158
179
  invalidSolution: "Invalid solution file: {path}",
180
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
181
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
182
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
159
183
  noSolutionFile: "No .uipx solution file found in directory: {path}",
160
184
  invalidStorageFile: "Invalid {fileName} file"
161
185
  }
@@ -177,6 +201,9 @@ var pt_BR_default = {
177
201
  pathRequired: "Solution directory path is required",
178
202
  fileNotFound: "Solution file not found: {path}",
179
203
  invalidSolution: "Invalid solution file: {path}",
204
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
205
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
206
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
180
207
  noSolutionFile: "No .uipx solution file found in directory: {path}",
181
208
  invalidStorageFile: "Invalid {fileName} file"
182
209
  }
@@ -198,6 +225,9 @@ var ro_default = {
198
225
  pathRequired: "Solution directory path is required",
199
226
  fileNotFound: "Solution file not found: {path}",
200
227
  invalidSolution: "Invalid solution file: {path}",
228
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
229
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
230
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
201
231
  noSolutionFile: "No .uipx solution file found in directory: {path}",
202
232
  invalidStorageFile: "Invalid {fileName} file"
203
233
  }
@@ -219,6 +249,9 @@ var ru_default = {
219
249
  pathRequired: "Solution directory path is required",
220
250
  fileNotFound: "Solution file not found: {path}",
221
251
  invalidSolution: "Invalid solution file: {path}",
252
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
253
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
254
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
222
255
  noSolutionFile: "No .uipx solution file found in directory: {path}",
223
256
  invalidStorageFile: "Invalid {fileName} file"
224
257
  }
@@ -240,6 +273,9 @@ var tr_default = {
240
273
  pathRequired: "Solution directory path is required",
241
274
  fileNotFound: "Solution file not found: {path}",
242
275
  invalidSolution: "Invalid solution file: {path}",
276
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
277
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
278
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
243
279
  noSolutionFile: "No .uipx solution file found in directory: {path}",
244
280
  invalidStorageFile: "Invalid {fileName} file"
245
281
  }
@@ -261,6 +297,9 @@ var zh_CN_default = {
261
297
  pathRequired: "Solution directory path is required",
262
298
  fileNotFound: "Solution file not found: {path}",
263
299
  invalidSolution: "Invalid solution file: {path}",
300
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
301
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
302
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
264
303
  noSolutionFile: "No .uipx solution file found in directory: {path}",
265
304
  invalidStorageFile: "Invalid {fileName} file"
266
305
  }
@@ -282,6 +321,9 @@ var zh_TW_default = {
282
321
  pathRequired: "Solution directory path is required",
283
322
  fileNotFound: "Solution file not found: {path}",
284
323
  invalidSolution: "Invalid solution file: {path}",
324
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
325
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
326
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
285
327
  noSolutionFile: "No .uipx solution file found in directory: {path}",
286
328
  invalidStorageFile: "Invalid {fileName} file"
287
329
  }
@@ -303,6 +345,9 @@ var zu_default = {
303
345
  pathRequired: "Solution directory path is required",
304
346
  fileNotFound: "Solution file not found: {path}",
305
347
  invalidSolution: "Invalid solution file: {path}",
348
+ projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.",
349
+ projectMissingProjectRelativePath: `Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example "Foo/project.uiproj".`,
350
+ projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.",
306
351
  noSolutionFile: "No .uipx solution file found in directory: {path}",
307
352
  invalidStorageFile: "Invalid {fileName} file"
308
353
  }
@@ -360,6 +405,7 @@ class SolutionPackOptions extends PackagerParameters {
360
405
  // src/node-solution-packager-factory.ts
361
406
  import {
362
407
  BaseNodePackagerFactory,
408
+ DotnetDiscoveryService,
363
409
  NodePackageSignService,
364
410
  ToolLogger as ToolLogger2
365
411
  } from "@uipath/project-packager/node";
@@ -376,8 +422,8 @@ import {
376
422
  Path as Path4,
377
423
  TargetFramework,
378
424
  TemporaryStorageService,
379
- ToolErrorCodes as ToolErrorCodes3,
380
- ToolResult as ToolResult3,
425
+ ToolErrorCodes as ToolErrorCodes4,
426
+ ToolResult as ToolResult4,
381
427
  toolsFactoryRepository,
382
428
  translate as translate3,
383
429
  ZipService
@@ -467,6 +513,18 @@ class OptionsBuilder {
467
513
  policyFileType: solutionOptions.validateOptions.governanceFileType
468
514
  };
469
515
  }
516
+ async buildProjectRestoreOptions(solutionOptions, project) {
517
+ if (!solutionOptions.outputPath) {
518
+ throw new Error(translate.t("solutionpackager.optionsBuilder.errors.outputPathRequired"));
519
+ }
520
+ return {
521
+ projectPath: this.resolveProjectPath(solutionOptions, project),
522
+ excludeConfiguredSources: solutionOptions.excludeConfiguredSources ?? false,
523
+ nuGetSourcesConfigPath: solutionOptions.nuGetSourcesConfigPath,
524
+ logLevel: solutionOptions.logLevel,
525
+ outputPath: await this.buildProjectOutputPath(solutionOptions.outputPath, project)
526
+ };
527
+ }
470
528
  resolveProjectPath(solutionOptions, project) {
471
529
  return Path.join(solutionOptions.inputPath, Path.dirname(project.ProjectRelativePath));
472
530
  }
@@ -641,7 +699,7 @@ import { Path as Path3, translate as translate2 } from "@uipath/solutionpackager
641
699
 
642
700
  class SolutionLoader {
643
701
  fileSystem;
644
- static SolutionStorageFileName = ".storage";
702
+ static SolutionStorageFileName = "SolutionStorage.json";
645
703
  constructor(fileSystem) {
646
704
  this.fileSystem = fileSystem;
647
705
  }
@@ -657,12 +715,8 @@ class SolutionLoader {
657
715
  }));
658
716
  }
659
717
  const json = typeof fileContent === "string" ? fileContent : new TextDecoder("utf-8").decode(fileContent);
660
- const solution = JSON.parse(json);
661
- if (!solution?.Projects) {
662
- throw new Error(translate2.t("solutionpackager.solutionLoader.errors.invalidSolution", {
663
- path: solutionFilePath
664
- }));
665
- }
718
+ const parsed = JSON.parse(json);
719
+ const solution = validateSolutionFile(parsed, solutionFilePath);
666
720
  const loadedSolution = {
667
721
  ...solution,
668
722
  Name: GetSolutionName(),
@@ -714,6 +768,38 @@ class SolutionLoader {
714
768
  }
715
769
  }
716
770
  }
771
+ function validateSolutionFile(parsed, solutionFilePath) {
772
+ if (!isRecord(parsed)) {
773
+ throw new Error(translate2.t("solutionpackager.solutionLoader.errors.invalidSolution", {
774
+ path: solutionFilePath
775
+ }));
776
+ }
777
+ if (!Array.isArray(parsed.Projects)) {
778
+ throw new Error(translate2.t("solutionpackager.solutionLoader.errors.invalidSolution", {
779
+ path: solutionFilePath
780
+ }));
781
+ }
782
+ for (const [index, project] of parsed.Projects.entries()) {
783
+ if (!isRecord(project)) {
784
+ throw new Error(translate2.t("solutionpackager.solutionLoader.errors.projectMustBeObject", {
785
+ path: solutionFilePath,
786
+ index
787
+ }));
788
+ }
789
+ if (typeof project.ProjectRelativePath !== "string" || !project.ProjectRelativePath.trim()) {
790
+ const pathHint = typeof project.Path === "string" ? translate2.t("solutionpackager.solutionLoader.errors.projectRelativePathPathHint") : "";
791
+ throw new Error(translate2.t("solutionpackager.solutionLoader.errors.projectMissingProjectRelativePath", {
792
+ path: solutionFilePath,
793
+ index,
794
+ pathHint
795
+ }));
796
+ }
797
+ }
798
+ return parsed;
799
+ }
800
+ function isRecord(value) {
801
+ return typeof value === "object" && value !== null && !Array.isArray(value);
802
+ }
717
803
 
718
804
  // src/services/solution-pack-options-validator.ts
719
805
  import {
@@ -731,10 +817,24 @@ class SolutionPackOptionsValidator extends PackagerParametersValidator {
731
817
  }
732
818
 
733
819
  // src/services/solution-pack-service.ts
820
+ import {
821
+ resolveProducedNupkgsAsync,
822
+ signNupkgsAsync
823
+ } from "@uipath/project-packager";
734
824
  import {
735
825
  ToolErrorCodes,
736
826
  ToolResult
737
827
  } from "@uipath/solutionpackager-tool-core";
828
+
829
+ // src/services/tool-result-helpers.ts
830
+ function hasFailedResults(results) {
831
+ return results.some((result) => !result.isSuccess);
832
+ }
833
+ function getFailedResultsMessage(results) {
834
+ return results.filter((result) => !result.isSuccess).map((r) => r.message || "Unknown error").join(", ");
835
+ }
836
+
837
+ // src/services/solution-pack-service.ts
738
838
  class SolutionPackService {
739
839
  optionsBuilder;
740
840
  toolsFactory;
@@ -742,13 +842,15 @@ class SolutionPackService {
742
842
  zipService;
743
843
  fileSystem;
744
844
  telemetry;
745
- constructor(optionsBuilder, toolsFactory, projectExecutor, zipService, fileSystem, telemetry) {
845
+ packageSignService;
846
+ constructor(optionsBuilder, toolsFactory, projectExecutor, zipService, fileSystem, telemetry, packageSignService) {
746
847
  this.optionsBuilder = optionsBuilder;
747
848
  this.toolsFactory = toolsFactory;
748
849
  this.projectExecutor = projectExecutor;
749
850
  this.zipService = zipService;
750
851
  this.fileSystem = fileSystem;
751
852
  this.telemetry = telemetry;
853
+ this.packageSignService = packageSignService;
752
854
  }
753
855
  async packAsync(parameters, solution, context, cancellationToken) {
754
856
  const solutionOptions = await this.optionsBuilder.buildSolutionPackOptions(parameters, solution);
@@ -763,8 +865,8 @@ class SolutionPackService {
763
865
  restoreResult,
764
866
  ...projectResults
765
867
  ];
766
- if (this.hasFailedResults(restoreAndPackResults)) {
767
- return ToolResult.error(ToolErrorCodes.InternalError, `Solution pack failed: ${this.getFailedResultsMessage(restoreAndPackResults)}`);
868
+ if (hasFailedResults(restoreAndPackResults)) {
869
+ return ToolResult.error(ToolErrorCodes.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
768
870
  }
769
871
  const buildResult = await solutionTool.buildAsync(solutionOptions, cancellationToken);
770
872
  if (!buildResult.isSuccess) {
@@ -773,6 +875,10 @@ class SolutionPackService {
773
875
  if (!solutionOptions.outputPath) {
774
876
  return ToolResult.error(ToolErrorCodes.InternalError, "Solution output path is not defined");
775
877
  }
878
+ const signResult = await this.signProjectPackagesAsync(projectResults, parameters.signingInfo);
879
+ if (!signResult.isSuccess) {
880
+ return signResult;
881
+ }
776
882
  const archivePath = await this.compressSolutionAsync(parameters, solutionOptions.outputPath);
777
883
  return new ToolResult(ToolErrorCodes.Success, undefined, [
778
884
  archivePath
@@ -791,23 +897,33 @@ class SolutionPackService {
791
897
  async packSingleProjectAsync(parameters, project, context, cancellationToken) {
792
898
  try {
793
899
  const projectOptions = await this.optionsBuilder.buildProjectPackOptions(parameters, project);
794
- return await this.projectExecutor.packAsync(projectOptions, project, context, parameters.signingInfo, cancellationToken);
900
+ return await this.projectExecutor.packAsync(projectOptions, project, context, cancellationToken);
795
901
  } catch (error) {
796
902
  const errorMessage = error instanceof Error ? error.message : String(error);
797
903
  return ToolResult.error(ToolErrorCodes.InternalError, errorMessage);
798
904
  }
799
905
  }
800
- hasFailedResults(results) {
801
- return results.some((result) => !result.isSuccess);
802
- }
803
- getFailedResultsMessage(results) {
804
- const failedResults = results.filter((result) => !result.isSuccess);
805
- return failedResults.map((r) => r.message || "Unknown error").join(", ");
906
+ async signProjectPackagesAsync(projectResults, signingInfo) {
907
+ if (!signingInfo?.certificatePath) {
908
+ return ToolResult.success();
909
+ }
910
+ const producedPaths = projectResults.flatMap((result) => result.packages);
911
+ const resolved = await Promise.all(producedPaths.map(async (producedPath) => ({
912
+ producedPath,
913
+ nupkgs: await resolveProducedNupkgsAsync(this.fileSystem, producedPath)
914
+ })));
915
+ const unresolved = resolved.filter((entry) => entry.nupkgs.length === 0).map((entry) => entry.producedPath);
916
+ if (unresolved.length > 0) {
917
+ return ToolResult.error(ToolErrorCodes.InternalError, `Package signing was required but no .nupkg was found to sign for: ${unresolved.join(", ")}.`);
918
+ }
919
+ const nupkgsToSign = resolved.flatMap((entry) => entry.nupkgs);
920
+ return signNupkgsAsync(this.packageSignService, nupkgsToSign, signingInfo);
806
921
  }
807
922
  async compressSolutionAsync(parameters, outputPath) {
808
923
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Compress" /* SolutionCompress */, "compress", async () => {
809
924
  const packageName = parameters.package.id || "solution";
810
925
  const version = parameters.package.version || "1.0.0";
926
+ await this.writePackageMetadataAsync(parameters, outputPath);
811
927
  const archiveFileName = `${packageName}_${version}.zip`;
812
928
  const archivePath = `${parameters.destinationPath}/${archiveFileName}`;
813
929
  const zipData = await this.zipService.compressAsync(outputPath);
@@ -815,6 +931,71 @@ class SolutionPackService {
815
931
  return archivePath;
816
932
  });
817
933
  }
934
+ async writePackageMetadataAsync(parameters, outputPath) {
935
+ const pkg = parameters.package;
936
+ const metadata = {
937
+ name: pkg.id || "solution",
938
+ version: pkg.version || "1.0.0"
939
+ };
940
+ const optional = {
941
+ releaseNotes: pkg.releaseNotes,
942
+ projectUrl: pkg.projectUrl,
943
+ repositoryType: pkg.repositoryType,
944
+ repositoryUrl: pkg.repositoryUrl,
945
+ repositoryBranch: pkg.repositoryBranch,
946
+ repositoryCommit: pkg.repositoryCommit
947
+ };
948
+ for (const [key, value] of Object.entries(optional)) {
949
+ if (value !== undefined && value !== "") {
950
+ metadata[key] = value;
951
+ }
952
+ }
953
+ const metadataPath = `${outputPath}/package.metadata.json`;
954
+ await this.fileSystem.writeFile(metadataPath, `${JSON.stringify(metadata, null, 2)}
955
+ `);
956
+ }
957
+ }
958
+
959
+ // src/services/solution-restore-service.ts
960
+ import {
961
+ ToolErrorCodes as ToolErrorCodes2,
962
+ ToolResult as ToolResult2
963
+ } from "@uipath/solutionpackager-tool-core";
964
+ class SolutionRestoreService {
965
+ optionsBuilder;
966
+ toolsFactory;
967
+ projectExecutor;
968
+ telemetry;
969
+ constructor(optionsBuilder, toolsFactory, projectExecutor, telemetry) {
970
+ this.optionsBuilder = optionsBuilder;
971
+ this.toolsFactory = toolsFactory;
972
+ this.projectExecutor = projectExecutor;
973
+ this.telemetry = telemetry;
974
+ }
975
+ async restoreAsync(parameters, solution, context, cancellationToken) {
976
+ const solutionOptions = await this.optionsBuilder.buildSolutionPackOptions(parameters, solution);
977
+ const solutionTool = await this.toolsFactory.createSolutionToolAsync(solution.SolutionId);
978
+ try {
979
+ return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Restore" /* SolutionRestore */, "restore", async () => {
980
+ const restoreResults = await Promise.all([
981
+ solutionTool.restoreAsync(solutionOptions, cancellationToken),
982
+ ...solution.Projects.map(async (project) => {
983
+ const projectRestoreOptions = await this.optionsBuilder.buildProjectRestoreOptions(parameters, project);
984
+ return this.projectExecutor.restoreAsync(projectRestoreOptions, project, context, cancellationToken);
985
+ })
986
+ ]);
987
+ if (hasFailedResults(restoreResults)) {
988
+ return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution restore failed: ${getFailedResultsMessage(restoreResults)}`);
989
+ }
990
+ return ToolResult2.success();
991
+ }, { solutionId: solution.SolutionId });
992
+ } finally {
993
+ const disposeResult = solutionTool.dispose();
994
+ if (disposeResult instanceof Promise) {
995
+ await disposeResult;
996
+ }
997
+ }
998
+ }
818
999
  }
819
1000
 
820
1001
  // src/services/solution-validate-options-validator.ts
@@ -830,8 +1011,8 @@ class SolutionValidateOptionsValidator extends PackagerParametersValidator2 {
830
1011
 
831
1012
  // src/services/solution-validate-service.ts
832
1013
  import {
833
- ToolErrorCodes as ToolErrorCodes2,
834
- ToolResult as ToolResult2
1014
+ ToolErrorCodes as ToolErrorCodes3,
1015
+ ToolResult as ToolResult3
835
1016
  } from "@uipath/solutionpackager-tool-core";
836
1017
  class SolutionValidateService {
837
1018
  optionsBuilder;
@@ -846,12 +1027,12 @@ class SolutionValidateService {
846
1027
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Validate" /* SolutionValidate */, "validate", async () => {
847
1028
  const projectResults = await Promise.all(solution.Projects.map((project) => {
848
1029
  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.`));
1030
+ return Promise.resolve(ToolResult3.error(ToolErrorCodes3.InternalError, `Project '${project.Id}' has no ProjectPath; the solution loader must populate it before validation.`));
850
1031
  }
851
1032
  return this.projectExecutor.validateAsync(this.optionsBuilder.buildProjectValidateOptions(parameters, project), project, context, cancellationToken);
852
1033
  }));
853
1034
  const failed = projectResults.find((r) => !r.isSuccess);
854
- return failed ?? ToolResult2.success();
1035
+ return failed ?? ToolResult3.success();
855
1036
  }, { solutionId: solution.SolutionId });
856
1037
  }
857
1038
  }
@@ -870,6 +1051,7 @@ class SolutionPackager {
870
1051
  projectExecutor;
871
1052
  solutionLoader;
872
1053
  solutionPackService;
1054
+ solutionRestoreService;
873
1055
  solutionValidateService;
874
1056
  packOptionsValidator;
875
1057
  validateOptionsValidator;
@@ -888,25 +1070,13 @@ class SolutionPackager {
888
1070
  const packageIdReader = new PackageIdReader(this.fileSystem, packService);
889
1071
  this.optionsBuilder = new OptionsBuilder(packageIdReader, packService, this.fileSystem);
890
1072
  this.toolsFactory = new ToolsFactory(this.repository, this.fileSystem);
891
- this.projectExecutor = new ProjectToolExecutor(this.toolsFactory, this.telemetryService, this.packageSignService);
1073
+ this.projectExecutor = new ProjectToolExecutor(this.toolsFactory, this.telemetryService);
892
1074
  this.solutionLoader = new SolutionLoader(this.fileSystem);
893
1075
  this.governancePolicyService = new GovernancePolicyService(this.fileSystem, this.temporaryStorage);
894
- this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService);
1076
+ this.solutionPackService = new SolutionPackService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.zipService, this.fileSystem, this.telemetryService, this.packageSignService);
1077
+ this.solutionRestoreService = new SolutionRestoreService(this.optionsBuilder, this.toolsFactory, this.projectExecutor, this.telemetryService);
895
1078
  this.solutionValidateService = new SolutionValidateService(this.optionsBuilder, this.projectExecutor, this.telemetryService);
896
1079
  }
897
- async canPackSolutionAsync(solutionPath) {
898
- const solution = await this.solutionLoader.loadSolution(solutionPath);
899
- for (const project of solution.Projects) {
900
- if (!project.ProjectPath) {
901
- return false;
902
- }
903
- const canHandle = this.repository.canHandleProject(project.Type);
904
- if (!canHandle) {
905
- return false;
906
- }
907
- }
908
- return true;
909
- }
910
1080
  async setupAsync(input, operationId) {
911
1081
  this.telemetryService.setOperationId(operationId);
912
1082
  await this.temporaryStorage.cleanup();
@@ -962,7 +1132,7 @@ class SolutionPackager {
962
1132
  } catch (error) {
963
1133
  const errorMessage = error instanceof Error ? error.message : String(error);
964
1134
  this.logger.error(`Processing error: ${errorMessage}`);
965
- return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution pack failed: ${errorMessage}`);
1135
+ return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution pack failed: ${errorMessage}`);
966
1136
  } finally {
967
1137
  await this.temporaryStorage.cleanup();
968
1138
  }
@@ -989,7 +1159,32 @@ class SolutionPackager {
989
1159
  } catch (error) {
990
1160
  const errorMessage = error instanceof Error ? error.message : String(error);
991
1161
  this.logger.error(`Processing error: ${errorMessage}`);
992
- return ToolResult3.error(ToolErrorCodes3.InternalError, `Solution validate failed: ${errorMessage}`);
1162
+ return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution validate failed: ${errorMessage}`);
1163
+ } finally {
1164
+ await this.temporaryStorage.cleanup();
1165
+ }
1166
+ });
1167
+ }
1168
+ async restoreSolutionAsync(options, cancellationToken) {
1169
+ return await this.telemetryService.trackRequest("SolutionPackager.RestoreSolution" /* SolutionPackagerRestoreSolution */, async () => {
1170
+ try {
1171
+ if (!options.outputPath) {
1172
+ options.outputPath = await this.temporaryStorage.getTempSubfolderPathAsync("restore");
1173
+ }
1174
+ const loadedSolution = await this.solutionLoader.loadSolution(options.inputPath);
1175
+ const solution = this.filterSolutionProjects(loadedSolution, options.projectDesignIds);
1176
+ const context = this.createOperationContext(options, solution);
1177
+ const result = await this.solutionRestoreService.restoreAsync(options, solution, context, cancellationToken);
1178
+ if (result.isSuccess) {
1179
+ this.logger.info("Solution restore completed successfully.");
1180
+ } else {
1181
+ this.logger.error(`Solution restore failed with error code ${result.errorCode}: ${result.message}`);
1182
+ }
1183
+ return result;
1184
+ } catch (error) {
1185
+ const errorMessage = error instanceof Error ? error.message : String(error);
1186
+ this.logger.error(`Processing error: ${errorMessage}`);
1187
+ return ToolResult4.error(ToolErrorCodes4.InternalError, `Solution restore failed: ${errorMessage}`);
993
1188
  } finally {
994
1189
  await this.temporaryStorage.cleanup();
995
1190
  }
@@ -1050,7 +1245,8 @@ class NodeSolutionPackagerFactory extends BaseNodePackagerFactory {
1050
1245
  logger.info("Creating SolutionPackager instance...");
1051
1246
  const fileSystem = this.getOrCreateFileSystem(config);
1052
1247
  const telemetryService = this.getOrCreateTelemetryService(config);
1053
- const packageSignService = new NodePackageSignService(logger);
1248
+ this.dotnetDiscovery = new DotnetDiscoveryService;
1249
+ const packageSignService = new NodePackageSignService(this.dotnetDiscovery, logger);
1054
1250
  const solutionPackager = new SolutionPackager(fileSystem, telemetryService, packageSignService);
1055
1251
  this.checkDotnetAvailability(logger);
1056
1252
  logger.info("SolutionPackager created successfully.");
@@ -1066,3 +1262,5 @@ export {
1066
1262
  SolutionPackager,
1067
1263
  SolutionPackOptions
1068
1264
  };
1265
+
1266
+ //# debugId=374EFD55C7484FC664756E2164756E21
@@ -4,16 +4,23 @@ import { type ISolutionPackager } from "./services/solution-packager.js";
4
4
  * Creates a SolutionPackager instance configured for browser usage.
5
5
  *
6
6
  * This is a convenience function that creates a BrowserSolutionPackagerFactory and calls createAsync.
7
- * For more control, use the BrowserSolutionPackagerFactory class directly.
8
7
  *
9
8
  * @param options - Configuration options for the SolutionPackager
10
9
  * @returns Promise<ISolutionPackager> - A fully configured SolutionPackager instance ready for use in the browser.
11
10
  *
12
11
  * @example
13
12
  * ```typescript
14
- * // Import tools (triggers self-registration)
15
- * import '@uipath/packager-tool-connector';
16
- * import '@uipath/packager-tool-flow';
13
+ * // Register the tools you need explicitly
14
+ * import { ResourceBuilderToolFactory } from '@uipath/resource-builder-tool';
15
+ * import { ConnectorToolFactory } from '@uipath/packager-tool-connector';
16
+ * import { FlowToolFactory } from '@uipath/packager-tool-flow';
17
+ * import { toolsFactoryRepository } from '@uipath/solutionpackager-tool-core';
18
+ *
19
+ * // ResourceBuilder is essential to solution packing — register it (consumer
20
+ * // controls the @uipath/resource-builder-tool version).
21
+ * toolsFactoryRepository.registerSolutionToolFactory(new ResourceBuilderToolFactory());
22
+ * toolsFactoryRepository.registerProjectToolFactory(new ConnectorToolFactory());
23
+ * toolsFactoryRepository.registerProjectToolFactory(new FlowToolFactory());
17
24
  *
18
25
  * // Create SolutionPackager
19
26
  * const packager = await createBrowserSolutionPackager({
@@ -9,6 +9,9 @@ export declare const en: {
9
9
  readonly pathRequired: "Solution directory path is required";
10
10
  readonly fileNotFound: "Solution file not found: {path}";
11
11
  readonly invalidSolution: "Invalid solution file: {path}";
12
+ readonly projectMustBeObject: "Invalid solution file: {path}. Projects[{index}] must be an object.";
13
+ readonly projectMissingProjectRelativePath: "Invalid solution file: {path}. Projects[{index}] is missing ProjectRelativePath.{pathHint} Use 'uip solution project add' to add projects, or set ProjectRelativePath to the project file path, for example \"Foo/project.uiproj\".";
14
+ readonly projectRelativePathPathHint: " Found Path, but .uipx uses ProjectRelativePath.";
12
15
  readonly noSolutionFile: "No .uipx solution file found in directory: {path}";
13
16
  readonly invalidStorageFile: "Invalid {fileName} file";
14
17
  };
@@ -4,7 +4,6 @@ import { type ISolutionPackager } from "./services/solution-packager.js";
4
4
  * Creates a SolutionPackager instance configured for Node.js usage.
5
5
  *
6
6
  * This is a convenience function that creates a NodeSolutionPackagerFactory and calls createAsync.
7
- * For more control, use the NodeSolutionPackagerFactory class directly.
8
7
  *
9
8
  * @param options - Configuration options for the SolutionPackager
10
9
  * @returns Promise<ISolutionPackager> - A fully configured SolutionPackager instance ready for use in Node.js.
@@ -1,5 +1,5 @@
1
1
  import type { IPackService, UiPathProject } from "@uipath/project-packager";
2
- import { type IFileSystem, type IProjectPackOptions, type IProjectValidateOptions, type ISolutionPackOptions } from "@uipath/solutionpackager-tool-core";
2
+ import { type IFileSystem, 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";
@@ -19,6 +19,10 @@ export interface IOptionsBuilder {
19
19
  * Build project validate options from solution parameters, for a specific project
20
20
  */
21
21
  buildProjectValidateOptions(options: SolutionPackOptions, project: UiPathProject): IProjectValidateOptions;
22
+ /**
23
+ * Build project restore options from solution parameters, for a specific project
24
+ */
25
+ buildProjectRestoreOptions(options: SolutionPackOptions, project: UiPathProject): Promise<IProjectRestoreOptions>;
22
26
  }
23
27
  export declare class OptionsBuilder implements IOptionsBuilder {
24
28
  private readonly packageIdReader;
@@ -33,6 +37,7 @@ export declare class OptionsBuilder implements IOptionsBuilder {
33
37
  */
34
38
  buildProjectPackOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): Promise<IProjectPackOptions>;
35
39
  buildProjectValidateOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): IProjectValidateOptions;
40
+ buildProjectRestoreOptions(solutionOptions: SolutionPackOptions, project: UiPathProject): Promise<IProjectRestoreOptions>;
36
41
  private resolveProjectPath;
37
42
  /**
38
43
  * Build the output path for a project
@@ -11,7 +11,7 @@ export interface ISolutionLoader {
11
11
  }
12
12
  export declare class SolutionLoader implements ISolutionLoader {
13
13
  private readonly fileSystem;
14
- static readonly SolutionStorageFileName = ".storage";
14
+ static readonly SolutionStorageFileName = "SolutionStorage.json";
15
15
  constructor(fileSystem: IFileSystem);
16
16
  loadSolution(solutionPath: string): Promise<LoadedUiPathSolution>;
17
17
  private getSolutionFilePathAsync;