@uipath/solution-packager 1.202.0-preview.159 → 1.203.0-preview.160

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
@@ -391,6 +391,7 @@ import { ToolLogger as ToolLogger2 } from "@uipath/project-packager";
391
391
  import { BaseBrowserPackagerFactory } from "@uipath/project-packager/browser";
392
392
 
393
393
  // src/services/solution-packager.ts
394
+ import { carriedInstructions } from "@uipath/common";
394
395
  import {
395
396
  GovernancePolicyService,
396
397
  PackService,
@@ -399,7 +400,7 @@ import {
399
400
  ToolsFactory
400
401
  } from "@uipath/project-packager";
401
402
  import {
402
- Path as Path4,
403
+ Path as Path6,
403
404
  TargetFramework,
404
405
  TemporaryStorageService,
405
406
  ToolErrorCodes as ToolErrorCodes5,
@@ -906,6 +907,7 @@ class SolutionPackOptionsValidator extends PackagerParametersValidator {
906
907
 
907
908
  // src/services/solution-pack-service.ts
908
909
  import {
910
+ isPackageIdTooLongError,
909
911
  resolveProducedNupkgsAsync,
910
912
  signNupkgsAsync
911
913
  } from "@uipath/project-packager";
@@ -914,13 +916,84 @@ import {
914
916
  ToolResult as ToolResult2
915
917
  } from "@uipath/solutionpackager-tool-core";
916
918
 
919
+ // src/services/member-package-ids.ts
920
+ import { Path as Path4 } from "@uipath/solutionpackager-tool-core";
921
+ var INVALID_PACKAGE_ID = "INVALID_PACKAGE_ID";
922
+ function memberFolder(project) {
923
+ return Path4.dirname(project.ProjectRelativePath);
924
+ }
925
+ function findPackageIdConflicts(members) {
926
+ const byId = new Map;
927
+ for (const member of members) {
928
+ if (!member.id) {
929
+ continue;
930
+ }
931
+ const key = member.id.toLowerCase();
932
+ const existing = byId.get(key);
933
+ if (existing) {
934
+ existing.folders.push(member.folder);
935
+ continue;
936
+ }
937
+ byId.set(key, { id: member.id, folders: [member.folder] });
938
+ }
939
+ return [...byId.values()].filter((conflict) => conflict.folders.length > 1);
940
+ }
941
+ function packageIdConflictMessage(conflicts) {
942
+ const described = conflicts.map((conflict) => `'${conflict.id}' from ${conflict.folders.map((folder) => `'${folder}'`).join(" and ")}`).join("; ");
943
+ return `Solution members share a package id: ${described}. A NuGet feed stores one package per id and version, so one member's package would replace the other's.`;
944
+ }
945
+
917
946
  // src/services/tool-result-helpers.ts
947
+ import { Path as Path5 } from "@uipath/solutionpackager-tool-core";
918
948
  function hasFailedResults(results) {
919
949
  return results.some((result) => !result.isSuccess);
920
950
  }
921
951
  function getFailedResultsMessage(results) {
922
952
  return results.filter((result) => !result.isSuccess).map((r) => r.message || "Unknown error").join(", ");
923
953
  }
954
+ function toProjectDiagnostics(projects, results) {
955
+ return projects.map((project, index) => {
956
+ const result = results[index];
957
+ const findings = result?.details?.findings;
958
+ return {
959
+ Path: Path5.dirname(project.ProjectRelativePath),
960
+ Type: project.Type,
961
+ Result: result?.isSuccess ? "Success" : "Failure",
962
+ Message: result?.message,
963
+ Findings: Array.isArray(findings) ? findings.map(toFindingContract) : []
964
+ };
965
+ });
966
+ }
967
+ var FINDING_FIELDS = [
968
+ "Level",
969
+ "Source",
970
+ "ErrorCode",
971
+ "RuleName",
972
+ "Description",
973
+ "FilePath",
974
+ "ActivityIdRef",
975
+ "DocumentationLink"
976
+ ];
977
+ var CAMEL_TO_CONTRACT = new Map(FINDING_FIELDS.map((field) => [
978
+ field[0].toLowerCase() + field.slice(1),
979
+ field
980
+ ]));
981
+ function toFindingContract(finding) {
982
+ if (typeof finding !== "object" || finding === null) {
983
+ return {};
984
+ }
985
+ const source = finding;
986
+ const normalized = {};
987
+ for (const [key, value] of Object.entries(source)) {
988
+ const contractName = CAMEL_TO_CONTRACT.get(key);
989
+ if (contractName === undefined) {
990
+ normalized[key] = value;
991
+ } else if (source[contractName] === undefined) {
992
+ normalized[contractName] = value;
993
+ }
994
+ }
995
+ return normalized;
996
+ }
924
997
 
925
998
  // src/services/solution-pack-service.ts
926
999
  class SolutionPackService {
@@ -942,19 +1015,27 @@ class SolutionPackService {
942
1015
  }
943
1016
  async packAsync(parameters, solution, context, cancellationToken) {
944
1017
  const solutionOptions = await this.optionsBuilder.buildSolutionPackOptions(parameters, solution);
1018
+ const prepared = await this.prepareProjectPackOptionsAsync(parameters, solution.Projects, solution.Name);
1019
+ if (!prepared.ok) {
1020
+ return ToolResult2.error(prepared.errorCode, `Solution pack failed: ${prepared.message}`);
1021
+ }
945
1022
  const solutionTool = await this.toolsFactory.createSolutionToolAsync(solution.SolutionId);
946
1023
  try {
947
1024
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Pack" /* SolutionPack */, "pack", async () => {
948
1025
  const [restoreResult, ...projectResults] = await Promise.all([
949
1026
  solutionTool.restoreAsync(solutionOptions, cancellationToken),
950
- ...this.packAllProjectsAsync(parameters, solution.Projects, solution.Name, context, cancellationToken)
1027
+ ...this.packAllProjectsAsync(prepared.options, context, cancellationToken)
951
1028
  ]);
952
1029
  const restoreAndPackResults = [
953
1030
  restoreResult,
954
1031
  ...projectResults
955
1032
  ];
956
1033
  if (hasFailedResults(restoreAndPackResults)) {
957
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
1034
+ const failure = ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
1035
+ failure.details = {
1036
+ projects: toProjectDiagnostics(solution.Projects, projectResults)
1037
+ };
1038
+ return failure;
958
1039
  }
959
1040
  const buildResult = await solutionTool.buildAsync(solutionOptions, cancellationToken);
960
1041
  if (!buildResult.isSuccess) {
@@ -979,13 +1060,49 @@ class SolutionPackService {
979
1060
  }
980
1061
  }
981
1062
  }
982
- packAllProjectsAsync(parameters, projects, solutionName, context, cancellationToken) {
983
- return projects.map((project) => this.packSingleProjectAsync(parameters, project, solutionName, context, cancellationToken));
1063
+ async prepareProjectPackOptionsAsync(parameters, projects, solutionName) {
1064
+ const settled = await Promise.allSettled(projects.map((project) => this.optionsBuilder.buildProjectPackOptions(parameters, project, solutionName)));
1065
+ const prepared = [];
1066
+ const failures = [];
1067
+ settled.forEach((result, index) => {
1068
+ const project = projects[index];
1069
+ if (result.status === "fulfilled") {
1070
+ prepared.push({ project, options: result.value });
1071
+ return;
1072
+ }
1073
+ const error = result.reason;
1074
+ const message = error instanceof Error ? error.message : String(error);
1075
+ failures.push(isPackageIdTooLongError(error) ? {
1076
+ message: `${message} (member '${memberFolder(project)}')`,
1077
+ isIdFailure: true
1078
+ } : { message, isIdFailure: false });
1079
+ });
1080
+ if (failures.length > 0) {
1081
+ return {
1082
+ ok: false,
1083
+ errorCode: failures.every((failure) => failure.isIdFailure) ? INVALID_PACKAGE_ID : ToolErrorCodes2.InternalError,
1084
+ message: failures.map((failure) => failure.message).join("; ")
1085
+ };
1086
+ }
1087
+ const conflicts = findPackageIdConflicts(prepared.map((entry) => ({
1088
+ folder: memberFolder(entry.project),
1089
+ id: entry.options.package?.id ?? ""
1090
+ })));
1091
+ if (conflicts.length > 0) {
1092
+ return {
1093
+ ok: false,
1094
+ errorCode: INVALID_PACKAGE_ID,
1095
+ message: packageIdConflictMessage(conflicts)
1096
+ };
1097
+ }
1098
+ return { ok: true, options: prepared };
1099
+ }
1100
+ packAllProjectsAsync(prepared, context, cancellationToken) {
1101
+ return prepared.map((entry) => this.packSingleProjectAsync(entry, context, cancellationToken));
984
1102
  }
985
- async packSingleProjectAsync(parameters, project, solutionName, context, cancellationToken) {
1103
+ async packSingleProjectAsync(prepared, context, cancellationToken) {
986
1104
  try {
987
- const projectOptions = await this.optionsBuilder.buildProjectPackOptions(parameters, project, solutionName);
988
- return await this.projectExecutor.packAsync(projectOptions, project, context, cancellationToken);
1105
+ return await this.projectExecutor.packAsync(prepared.options, prepared.project, context, cancellationToken);
989
1106
  } catch (error) {
990
1107
  const errorMessage = error instanceof Error ? error.message : String(error);
991
1108
  return ToolResult2.error(ToolErrorCodes2.InternalError, errorMessage);
@@ -1177,7 +1294,7 @@ class SolutionPackager {
1177
1294
  await this.zipService.extractAsync(input, inputPath);
1178
1295
  const entries = await this.fileSystem.readdir(inputPath);
1179
1296
  if (entries.length === 1) {
1180
- const innerPath = Path4.join(inputPath, entries[0]);
1297
+ const innerPath = Path6.join(inputPath, entries[0]);
1181
1298
  const stat = await this.fileSystem.stat(innerPath);
1182
1299
  if (stat?.isDirectory()) {
1183
1300
  return innerPath;
@@ -1222,7 +1339,7 @@ class SolutionPackager {
1222
1339
  } catch (error) {
1223
1340
  const errorMessage = error instanceof Error ? error.message : String(error);
1224
1341
  this.logger.error(`Processing error: ${errorMessage}`);
1225
- return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`);
1342
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`, carriedInstructions(error));
1226
1343
  } finally {
1227
1344
  await this.temporaryStorage.cleanup();
1228
1345
  }
@@ -1231,7 +1348,7 @@ class SolutionPackager {
1231
1348
  async validateSolutionAsync(options, cancellationToken) {
1232
1349
  return await this.telemetryService.trackDependencyOperation("SolutionPackager.ValidateSolution" /* SolutionPackagerValidateSolution */, "validate", async () => {
1233
1350
  try {
1234
- await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
1351
+ await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken, "analyze");
1235
1352
  const validationResult = await this.validateOptionsValidator.validateAsync(options, cancellationToken);
1236
1353
  if (!validationResult.isSuccess) {
1237
1354
  return validationResult;
@@ -1249,7 +1366,7 @@ class SolutionPackager {
1249
1366
  } catch (error) {
1250
1367
  const errorMessage = error instanceof Error ? error.message : String(error);
1251
1368
  this.logger.error(`Processing error: ${errorMessage}`);
1252
- return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`);
1369
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`, carriedInstructions(error));
1253
1370
  } finally {
1254
1371
  await this.temporaryStorage.cleanup();
1255
1372
  }
@@ -1402,6 +1519,7 @@ class SolutionPackOptions extends PackagerParameters {
1402
1519
  }
1403
1520
  export {
1404
1521
  BuildConfiguration2 as BuildConfiguration,
1522
+ INVALID_PACKAGE_ID,
1405
1523
  LogLevel,
1406
1524
  RulesConfigFileType2 as RulesConfigFileType,
1407
1525
  SolutionPackOptions,
@@ -1409,4 +1527,4 @@ export {
1409
1527
  createBrowserSolutionPackager
1410
1528
  };
1411
1529
 
1412
- //# debugId=E42C0DAAD1D016BD64756E2164756E21
1530
+ //# debugId=CF29C179DF2F6E6F64756E2164756E21
package/dist/node.js CHANGED
@@ -421,6 +421,7 @@ import {
421
421
  } from "@uipath/project-packager/node";
422
422
 
423
423
  // src/services/solution-packager.ts
424
+ import { carriedInstructions } from "@uipath/common";
424
425
  import {
425
426
  GovernancePolicyService,
426
427
  PackService,
@@ -429,7 +430,7 @@ import {
429
430
  ToolsFactory
430
431
  } from "@uipath/project-packager";
431
432
  import {
432
- Path as Path4,
433
+ Path as Path6,
433
434
  TargetFramework,
434
435
  TemporaryStorageService,
435
436
  ToolErrorCodes as ToolErrorCodes5,
@@ -936,6 +937,7 @@ class SolutionPackOptionsValidator extends PackagerParametersValidator {
936
937
 
937
938
  // src/services/solution-pack-service.ts
938
939
  import {
940
+ isPackageIdTooLongError,
939
941
  resolveProducedNupkgsAsync,
940
942
  signNupkgsAsync
941
943
  } from "@uipath/project-packager";
@@ -944,13 +946,84 @@ import {
944
946
  ToolResult as ToolResult2
945
947
  } from "@uipath/solutionpackager-tool-core";
946
948
 
949
+ // src/services/member-package-ids.ts
950
+ import { Path as Path4 } from "@uipath/solutionpackager-tool-core";
951
+ var INVALID_PACKAGE_ID = "INVALID_PACKAGE_ID";
952
+ function memberFolder(project) {
953
+ return Path4.dirname(project.ProjectRelativePath);
954
+ }
955
+ function findPackageIdConflicts(members) {
956
+ const byId = new Map;
957
+ for (const member of members) {
958
+ if (!member.id) {
959
+ continue;
960
+ }
961
+ const key = member.id.toLowerCase();
962
+ const existing = byId.get(key);
963
+ if (existing) {
964
+ existing.folders.push(member.folder);
965
+ continue;
966
+ }
967
+ byId.set(key, { id: member.id, folders: [member.folder] });
968
+ }
969
+ return [...byId.values()].filter((conflict) => conflict.folders.length > 1);
970
+ }
971
+ function packageIdConflictMessage(conflicts) {
972
+ const described = conflicts.map((conflict) => `'${conflict.id}' from ${conflict.folders.map((folder) => `'${folder}'`).join(" and ")}`).join("; ");
973
+ return `Solution members share a package id: ${described}. A NuGet feed stores one package per id and version, so one member's package would replace the other's.`;
974
+ }
975
+
947
976
  // src/services/tool-result-helpers.ts
977
+ import { Path as Path5 } from "@uipath/solutionpackager-tool-core";
948
978
  function hasFailedResults(results) {
949
979
  return results.some((result) => !result.isSuccess);
950
980
  }
951
981
  function getFailedResultsMessage(results) {
952
982
  return results.filter((result) => !result.isSuccess).map((r) => r.message || "Unknown error").join(", ");
953
983
  }
984
+ function toProjectDiagnostics(projects, results) {
985
+ return projects.map((project, index) => {
986
+ const result = results[index];
987
+ const findings = result?.details?.findings;
988
+ return {
989
+ Path: Path5.dirname(project.ProjectRelativePath),
990
+ Type: project.Type,
991
+ Result: result?.isSuccess ? "Success" : "Failure",
992
+ Message: result?.message,
993
+ Findings: Array.isArray(findings) ? findings.map(toFindingContract) : []
994
+ };
995
+ });
996
+ }
997
+ var FINDING_FIELDS = [
998
+ "Level",
999
+ "Source",
1000
+ "ErrorCode",
1001
+ "RuleName",
1002
+ "Description",
1003
+ "FilePath",
1004
+ "ActivityIdRef",
1005
+ "DocumentationLink"
1006
+ ];
1007
+ var CAMEL_TO_CONTRACT = new Map(FINDING_FIELDS.map((field) => [
1008
+ field[0].toLowerCase() + field.slice(1),
1009
+ field
1010
+ ]));
1011
+ function toFindingContract(finding) {
1012
+ if (typeof finding !== "object" || finding === null) {
1013
+ return {};
1014
+ }
1015
+ const source = finding;
1016
+ const normalized = {};
1017
+ for (const [key, value] of Object.entries(source)) {
1018
+ const contractName = CAMEL_TO_CONTRACT.get(key);
1019
+ if (contractName === undefined) {
1020
+ normalized[key] = value;
1021
+ } else if (source[contractName] === undefined) {
1022
+ normalized[contractName] = value;
1023
+ }
1024
+ }
1025
+ return normalized;
1026
+ }
954
1027
 
955
1028
  // src/services/solution-pack-service.ts
956
1029
  class SolutionPackService {
@@ -972,19 +1045,27 @@ class SolutionPackService {
972
1045
  }
973
1046
  async packAsync(parameters, solution, context, cancellationToken) {
974
1047
  const solutionOptions = await this.optionsBuilder.buildSolutionPackOptions(parameters, solution);
1048
+ const prepared = await this.prepareProjectPackOptionsAsync(parameters, solution.Projects, solution.Name);
1049
+ if (!prepared.ok) {
1050
+ return ToolResult2.error(prepared.errorCode, `Solution pack failed: ${prepared.message}`);
1051
+ }
975
1052
  const solutionTool = await this.toolsFactory.createSolutionToolAsync(solution.SolutionId);
976
1053
  try {
977
1054
  return await this.telemetry.trackDependencyOperation("SolutionPackager.Solution.Pack" /* SolutionPack */, "pack", async () => {
978
1055
  const [restoreResult, ...projectResults] = await Promise.all([
979
1056
  solutionTool.restoreAsync(solutionOptions, cancellationToken),
980
- ...this.packAllProjectsAsync(parameters, solution.Projects, solution.Name, context, cancellationToken)
1057
+ ...this.packAllProjectsAsync(prepared.options, context, cancellationToken)
981
1058
  ]);
982
1059
  const restoreAndPackResults = [
983
1060
  restoreResult,
984
1061
  ...projectResults
985
1062
  ];
986
1063
  if (hasFailedResults(restoreAndPackResults)) {
987
- return ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
1064
+ const failure = ToolResult2.error(ToolErrorCodes2.InternalError, `Solution pack failed: ${getFailedResultsMessage(restoreAndPackResults)}`);
1065
+ failure.details = {
1066
+ projects: toProjectDiagnostics(solution.Projects, projectResults)
1067
+ };
1068
+ return failure;
988
1069
  }
989
1070
  const buildResult = await solutionTool.buildAsync(solutionOptions, cancellationToken);
990
1071
  if (!buildResult.isSuccess) {
@@ -1009,13 +1090,49 @@ class SolutionPackService {
1009
1090
  }
1010
1091
  }
1011
1092
  }
1012
- packAllProjectsAsync(parameters, projects, solutionName, context, cancellationToken) {
1013
- return projects.map((project) => this.packSingleProjectAsync(parameters, project, solutionName, context, cancellationToken));
1093
+ async prepareProjectPackOptionsAsync(parameters, projects, solutionName) {
1094
+ const settled = await Promise.allSettled(projects.map((project) => this.optionsBuilder.buildProjectPackOptions(parameters, project, solutionName)));
1095
+ const prepared = [];
1096
+ const failures = [];
1097
+ settled.forEach((result, index) => {
1098
+ const project = projects[index];
1099
+ if (result.status === "fulfilled") {
1100
+ prepared.push({ project, options: result.value });
1101
+ return;
1102
+ }
1103
+ const error = result.reason;
1104
+ const message = error instanceof Error ? error.message : String(error);
1105
+ failures.push(isPackageIdTooLongError(error) ? {
1106
+ message: `${message} (member '${memberFolder(project)}')`,
1107
+ isIdFailure: true
1108
+ } : { message, isIdFailure: false });
1109
+ });
1110
+ if (failures.length > 0) {
1111
+ return {
1112
+ ok: false,
1113
+ errorCode: failures.every((failure) => failure.isIdFailure) ? INVALID_PACKAGE_ID : ToolErrorCodes2.InternalError,
1114
+ message: failures.map((failure) => failure.message).join("; ")
1115
+ };
1116
+ }
1117
+ const conflicts = findPackageIdConflicts(prepared.map((entry) => ({
1118
+ folder: memberFolder(entry.project),
1119
+ id: entry.options.package?.id ?? ""
1120
+ })));
1121
+ if (conflicts.length > 0) {
1122
+ return {
1123
+ ok: false,
1124
+ errorCode: INVALID_PACKAGE_ID,
1125
+ message: packageIdConflictMessage(conflicts)
1126
+ };
1127
+ }
1128
+ return { ok: true, options: prepared };
1129
+ }
1130
+ packAllProjectsAsync(prepared, context, cancellationToken) {
1131
+ return prepared.map((entry) => this.packSingleProjectAsync(entry, context, cancellationToken));
1014
1132
  }
1015
- async packSingleProjectAsync(parameters, project, solutionName, context, cancellationToken) {
1133
+ async packSingleProjectAsync(prepared, context, cancellationToken) {
1016
1134
  try {
1017
- const projectOptions = await this.optionsBuilder.buildProjectPackOptions(parameters, project, solutionName);
1018
- return await this.projectExecutor.packAsync(projectOptions, project, context, cancellationToken);
1135
+ return await this.projectExecutor.packAsync(prepared.options, prepared.project, context, cancellationToken);
1019
1136
  } catch (error) {
1020
1137
  const errorMessage = error instanceof Error ? error.message : String(error);
1021
1138
  return ToolResult2.error(ToolErrorCodes2.InternalError, errorMessage);
@@ -1207,7 +1324,7 @@ class SolutionPackager {
1207
1324
  await this.zipService.extractAsync(input, inputPath);
1208
1325
  const entries = await this.fileSystem.readdir(inputPath);
1209
1326
  if (entries.length === 1) {
1210
- const innerPath = Path4.join(inputPath, entries[0]);
1327
+ const innerPath = Path6.join(inputPath, entries[0]);
1211
1328
  const stat = await this.fileSystem.stat(innerPath);
1212
1329
  if (stat?.isDirectory()) {
1213
1330
  return innerPath;
@@ -1252,7 +1369,7 @@ class SolutionPackager {
1252
1369
  } catch (error) {
1253
1370
  const errorMessage = error instanceof Error ? error.message : String(error);
1254
1371
  this.logger.error(`Processing error: ${errorMessage}`);
1255
- return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`);
1372
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution pack failed: ${errorMessage}`, carriedInstructions(error));
1256
1373
  } finally {
1257
1374
  await this.temporaryStorage.cleanup();
1258
1375
  }
@@ -1261,7 +1378,7 @@ class SolutionPackager {
1261
1378
  async validateSolutionAsync(options, cancellationToken) {
1262
1379
  return await this.telemetryService.trackDependencyOperation("SolutionPackager.ValidateSolution" /* SolutionPackagerValidateSolution */, "validate", async () => {
1263
1380
  try {
1264
- await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken);
1381
+ await this.governancePolicyService.resolveGovernancePolicyAsync(options.validateOptions, options.connection, cancellationToken, "analyze");
1265
1382
  const validationResult = await this.validateOptionsValidator.validateAsync(options, cancellationToken);
1266
1383
  if (!validationResult.isSuccess) {
1267
1384
  return validationResult;
@@ -1279,7 +1396,7 @@ class SolutionPackager {
1279
1396
  } catch (error) {
1280
1397
  const errorMessage = error instanceof Error ? error.message : String(error);
1281
1398
  this.logger.error(`Processing error: ${errorMessage}`);
1282
- return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`);
1399
+ return ToolResult5.error(ToolErrorCodes5.InternalError, `Solution validate failed: ${errorMessage}`, carriedInstructions(error));
1283
1400
  } finally {
1284
1401
  await this.temporaryStorage.cleanup();
1285
1402
  }
@@ -1404,10 +1521,11 @@ async function createNodeSolutionPackager(options) {
1404
1521
  return factory.createAsync(options);
1405
1522
  }
1406
1523
  export {
1524
+ INVALID_PACKAGE_ID,
1407
1525
  RulesConfigFileType2 as RulesConfigFileType,
1408
1526
  SolutionPackOptions,
1409
1527
  SolutionPackager,
1410
1528
  createNodeSolutionPackager
1411
1529
  };
1412
1530
 
1413
- //# debugId=0773CC8956B6196964756E2164756E21
1531
+ //# debugId=170B238929E3651264756E2164756E21
@@ -4,5 +4,6 @@ export { RulesConfigFileType } from "@uipath/project-packager";
4
4
  export { BuildConfiguration, LogLevel, } from "@uipath/solutionpackager-tool-core";
5
5
  export { createBrowserSolutionPackager } from "./browser-solution-packager-factory.js";
6
6
  export { SolutionPackOptions } from "./models/solution-pack-options.js";
7
+ export { INVALID_PACKAGE_ID } from "./services/member-package-ids.js";
7
8
  export type { ISolutionPackager } from "./services/solution-packager.js";
8
9
  export { SolutionPackager } from "./services/solution-packager.js";
@@ -2,5 +2,6 @@ import "./i18n/index.js";
2
2
  export { RulesConfigFileType } from "@uipath/project-packager";
3
3
  export { SolutionPackOptions } from "./models/solution-pack-options.js";
4
4
  export { createNodeSolutionPackager } from "./node-solution-packager-factory.js";
5
+ export { INVALID_PACKAGE_ID } from "./services/member-package-ids.js";
5
6
  export type { ISolutionPackager } from "./services/solution-packager.js";
6
7
  export { SolutionPackager } from "./services/solution-packager.js";
@@ -0,0 +1,39 @@
1
+ import type { UiPathProject } from "@uipath/project-packager";
2
+ /**
3
+ * Error code every refusal in this module reports, so a caller can tell "the
4
+ * member ids are wrong" from "the pack broke".
5
+ *
6
+ * `ToolErrorCode` is `ToolErrorCodes | string` on purpose — a tool may add its
7
+ * own codes — so this rides that door rather than widening the core enum.
8
+ */
9
+ export declare const INVALID_PACKAGE_ID = "INVALID_PACKAGE_ID";
10
+ /** A member and the NuGet id it would be published under. */
11
+ export interface MemberPackageId {
12
+ /** The member's folder, i.e. the directory of its `.uipx` relative path. */
13
+ folder: string;
14
+ id: string;
15
+ }
16
+ /** Two or more members that compose the same id. */
17
+ export interface PackageIdConflict {
18
+ id: string;
19
+ folders: string[];
20
+ }
21
+ /** The folder a member lives in — the first segment of its relative path. */
22
+ export declare function memberFolder(project: UiPathProject): string;
23
+ /**
24
+ * Group members by the id they would publish under and return every group
25
+ * holding more than one.
26
+ *
27
+ * Compared case-insensitively because NuGet ids are: `Foo` and `foo` are one
28
+ * package in a feed, so letting both through would be the same defect with a
29
+ * quieter symptom.
30
+ */
31
+ export declare function findPackageIdConflicts(members: MemberPackageId[]): PackageIdConflict[];
32
+ /**
33
+ * What to tell the user when members collide.
34
+ *
35
+ * Names the id and every folder that produced it: the ids are composed from
36
+ * the solution name, the project type and the folder, so the folder list is
37
+ * the only part the author can act on.
38
+ */
39
+ export declare function packageIdConflictMessage(conflicts: PackageIdConflict[]): string;
@@ -22,20 +22,31 @@ export declare class SolutionPackService implements ISolutionPackService {
22
22
  private readonly packageSignService?;
23
23
  constructor(optionsBuilder: IOptionsBuilder, toolsFactory: IToolsFactory, projectExecutor: IProjectToolExecutor, zipService: IZipService, fileSystem: IFileSystem, telemetry: ITelemetryService, packageSignService?: IPackageSignService | undefined);
24
24
  packAsync(parameters: SolutionPackOptions, solution: LoadedUiPathSolution, context: ProjectOperationContext, cancellationToken?: AbortSignal): Promise<ToolResult>;
25
+ /**
26
+ * Build the pack options for every member, then refuse the ids that cannot
27
+ * be published: one longer than NuGet allows, or two members composing the
28
+ * same id.
29
+ *
30
+ * The composed id is `<solution>.<short type>.<member folder>`, so both
31
+ * failures are the author's to fix by renaming, and both are cheaper to
32
+ * report here than after a compile.
33
+ *
34
+ * Every member's options are built concurrently, as they were when each
35
+ * project built its own, and every failure is collected: a solution with
36
+ * two unpublishable ids names both rather than making the author rerun to
37
+ * find the second.
38
+ */
39
+ private prepareProjectPackOptionsAsync;
25
40
  /**
26
41
  * Pack all projects in parallel
27
- * @param parameters Solution pack parameters
28
- * @param projects Array of projects to pack
29
- * @param solutionName The solution's `.uipx` basename, anchoring member package ids
42
+ * @param prepared Members with their already-built pack options
30
43
  * @param cancellationToken Optional cancellation token
31
44
  * @returns Array of promises for packing each project
32
45
  */
33
46
  private packAllProjectsAsync;
34
47
  /**
35
48
  * Pack a single project
36
- * @param parameters Solution pack parameters
37
- * @param project Project to pack
38
- * @param solutionName The solution's `.uipx` basename, anchoring the member package id
49
+ * @param prepared The member and its pack options
39
50
  * @param cancellationToken Optional cancellation token
40
51
  * @param context Optional operation context
41
52
  * @returns Result of the pack operation
@@ -1,4 +1,5 @@
1
- import type { ToolResult } from "@uipath/solutionpackager-tool-core";
1
+ import type { UiPathProject } from "@uipath/project-packager";
2
+ import { type ToolResult } from "@uipath/solutionpackager-tool-core";
2
3
  /**
3
4
  * Result-aggregation helpers shared by the solution pack and restore services,
4
5
  * which both fan a batch of tool operations out in parallel and need to report
@@ -8,3 +9,24 @@ import type { ToolResult } from "@uipath/solutionpackager-tool-core";
8
9
  export declare function hasFailedResults(results: ToolResult[]): boolean;
9
10
  /** Combined, comma-separated message of every failed result in the batch. */
10
11
  export declare function getFailedResultsMessage(results: ToolResult[]): string;
12
+ /**
13
+ * One project's outcome inside a solution operation, in the shape the CLI puts on the wire under
14
+ * `Data.Projects`. Field names mirror the flattened findings the workflow compiler already emits, so
15
+ * a consumer reads one vocabulary for `uip rpa analyze` and for a solution pack alike.
16
+ */
17
+ export interface ProjectDiagnostics {
18
+ /** The project directory, relative to the solution directory, with forward slashes. */
19
+ Path: string;
20
+ Type: string;
21
+ Result: "Success" | "Failure";
22
+ Message?: string;
23
+ Findings: unknown[];
24
+ }
25
+ /**
26
+ * Pair each project with its result. Positional: the caller builds the results by mapping over the
27
+ * same array and awaits them with `Promise.all`, which resolves in input order.
28
+ *
29
+ * Without this the per-project detail dies in {@link getFailedResultsMessage} — the joined string is
30
+ * all a caller gets, and it names neither the file nor the activity that failed. See STUD-81458.
31
+ */
32
+ export declare function toProjectDiagnostics(projects: UiPathProject[], results: ToolResult[]): ProjectDiagnostics[];
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@uipath/solution-packager",
3
+ "author": "UiPath",
3
4
  "license": "SEE LICENSE IN LICENSE.txt",
4
- "version": "1.202.0-preview.159",
5
+ "version": "1.203.0-preview.160",
5
6
  "description": "UiPath Solution Packager - core library for packing UiPath solutions",
6
7
  "type": "module",
7
8
  "main": "./dist/index.js",
@@ -28,11 +29,11 @@
28
29
  "dist"
29
30
  ],
30
31
  "dependencies": {
31
- "@uipath/project-packager": "1.202.0",
32
- "@uipath/solutionpackager-tool-core": "1.202.0"
32
+ "@uipath/project-packager": "1.203.0",
33
+ "@uipath/solutionpackager-tool-core": "1.203.0"
33
34
  },
34
35
  "peerDependencies": {
35
36
  "fflate": "^0.8.2"
36
37
  },
37
- "gitHead": "a3f23209784c6cec7155e735fa051b48ca49e8d7"
38
+ "gitHead": "3a42062ba731afca4595ba9aa8a80afc9667528d"
38
39
  }