@uipath/packager-tool-workflowcompiler 1.201.0-preview.121 → 1.201.0-preview.123

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
@@ -695,7 +695,12 @@ var en2 = {
695
695
  feeds: {
696
696
  errors: {
697
697
  orchestratorUrlRequired: "Orchestrator URL is required.",
698
- getAccessibleFeedsFailed: "GetAccessibleFeeds failed: {status} {statusText}{body}"
698
+ requestFailed: "{operation} failed: {status} {statusText}{body}",
699
+ feedFolderNeedsConnection: "Cannot resolve the library feed of folder '{folder}' without a signed-in Orchestrator session. Run 'uip login', or omit the folder to use every accessible tenant feed.",
700
+ feedFolderNotFound: "Orchestrator folder '{folder}' was not found. Available folders: {available}",
701
+ feedFolderAmbiguous: "Orchestrator folder name '{folder}' is ambiguous — {count} folders share it ({paths}). Pass the fully qualified path instead.",
702
+ feedFolderNotWritten: "Could not write the feed configuration for folder '{folder}'. Retry, or omit the folder to use every accessible tenant feed.",
703
+ feedFolderHasNoFeed: "Orchestrator folder '{folder}' has no library feed. Publish a library to that folder, or omit the folder to use every accessible tenant feed."
699
704
  },
700
705
  warnings: {
701
706
  tenantFeedsUnavailable: "Could not retrieve Orchestrator tenant feeds. Packaging will continue, but it may fail if a project references a library published to a tenant feed."
@@ -833,6 +838,10 @@ var package_default = {
833
838
  }
834
839
  };
835
840
  var FEEDS_PATH = "/api/PackageFeeds/GetFeeds?onlyPublishable=false";
841
+ var FOLDER_FEED_PATH = "/api/PackageFeeds/GetFolderFeedByKey";
842
+ var FOLDERS_PAGE_SIZE = 1000;
843
+ var FOLDERS_PATH = `/odata/Folders?$select=Key,DisplayName,FullyQualifiedName&$top=${FOLDERS_PAGE_SIZE}`;
844
+ var FOLDERS_MAX_PAGES = 50;
836
845
  var HEADER_TENANT_ID = "X-UIPATH-TenantId";
837
846
  var FEEDS_TIMEOUT_MS = 30000;
838
847
  var SDK_USER_AGENT = `${package_default.name.replace(/^@uipath\//, "")}/${package_default.version}`;
@@ -861,21 +870,96 @@ class OrchestratorFeedsService {
861
870
  signal: AbortSignal.timeout(FEEDS_TIMEOUT_MS)
862
871
  });
863
872
  if (!response.ok) {
864
- throw new Error(translate.t("packagerOrchestratorClient.feeds.errors.getAccessibleFeedsFailed", await describeFailure(response)));
873
+ throw new Error(translate.t("packagerOrchestratorClient.feeds.errors.requestFailed", {
874
+ operation: "GetAccessibleFeeds",
875
+ ...await describeFailure(response)
876
+ }));
865
877
  }
866
878
  const text = await response.text();
867
879
  const feeds = text === "" || text === "null" ? null : JSON.parse(text);
868
880
  return Array.isArray(feeds) ? feeds : [];
869
881
  }
882
+ async getFoldersAsync(connection) {
883
+ const folders = [];
884
+ const seen = new Set;
885
+ for (let page = 0;page < FOLDERS_MAX_PAGES; page++) {
886
+ const path = page === 0 ? FOLDERS_PATH : `${FOLDERS_PATH}&$skip=${page * FOLDERS_PAGE_SIZE}`;
887
+ const text = await this.getAsync(connection, path, "GetFolders");
888
+ if (text === "" || text === "null") {
889
+ break;
890
+ }
891
+ const payload = JSON.parse(text);
892
+ if (!Array.isArray(payload.value) || payload.value.length === 0) {
893
+ break;
894
+ }
895
+ const fresh = payload.value.map((f) => mapFolder(f)).filter((folder) => {
896
+ const identity = folder.key ?? folder.fullyQualifiedName ?? folder.displayName;
897
+ if (identity === undefined || seen.has(identity)) {
898
+ return false;
899
+ }
900
+ seen.add(identity);
901
+ return true;
902
+ });
903
+ folders.push(...fresh);
904
+ if (fresh.length === 0) {
905
+ this.logger.warn(`Orchestrator returned no new folders for $skip=${page * FOLDERS_PAGE_SIZE}; using the ${folders.length} already retrieved.`);
906
+ break;
907
+ }
908
+ if (payload.value.length < FOLDERS_PAGE_SIZE) {
909
+ break;
910
+ }
911
+ }
912
+ return folders;
913
+ }
914
+ async getFolderFeedIdAsync(connection, folderKey) {
915
+ const path = `${FOLDER_FEED_PATH}?folderKey=${encodeURIComponent(folderKey)}`;
916
+ const text = await this.getAsync(connection, path, "GetFolderFeedByKey");
917
+ const feedId = text.trim().replace(/^"|"$/g, "");
918
+ return feedId === "" || feedId === "null" ? undefined : feedId;
919
+ }
920
+ async getAsync(connection, relativePath, operation) {
921
+ const { orchestratorUrl, accessToken, tenantId } = connection;
922
+ if (!orchestratorUrl) {
923
+ throw new Error(translate.t("packagerOrchestratorClient.feeds.errors.orchestratorUrlRequired"));
924
+ }
925
+ const headers = {};
926
+ if (accessToken) {
927
+ headers.Authorization = `Bearer ${accessToken}`;
928
+ }
929
+ if (tenantId) {
930
+ headers[HEADER_TENANT_ID] = tenantId;
931
+ }
932
+ const response = await fetch(`${orchestratorBase(orchestratorUrl)}${relativePath}`, {
933
+ method: "GET",
934
+ headers: addSdkUserAgentHeader(headers, SDK_USER_AGENT),
935
+ signal: AbortSignal.timeout(FEEDS_TIMEOUT_MS)
936
+ });
937
+ if (!response.ok) {
938
+ throw new Error(translate.t("packagerOrchestratorClient.feeds.errors.requestFailed", { operation, ...await describeFailure(response) }));
939
+ }
940
+ return response.text();
941
+ }
870
942
  }
871
- function feedsEndpoint(orchestratorUrl) {
943
+ function folderFeedUrl(orchestratorUrl, feedId) {
944
+ return `${orchestratorBase(orchestratorUrl)}/nuget/v3/${feedId}/index.json`;
945
+ }
946
+ function mapFolder(json) {
947
+ return {
948
+ key: json.Key,
949
+ displayName: json.DisplayName,
950
+ fullyQualifiedName: json.FullyQualifiedName
951
+ };
952
+ }
953
+ function orchestratorBase(orchestratorUrl) {
872
954
  let end = orchestratorUrl.length;
873
955
  while (end > 0 && orchestratorUrl.charAt(end - 1) === "/") {
874
956
  end--;
875
957
  }
876
958
  const trimmed = orchestratorUrl.slice(0, end);
877
- const base = /\/orchestrator_$/i.test(trimmed) ? trimmed : `${trimmed}/orchestrator_`;
878
- return `${base}${FEEDS_PATH}`;
959
+ return /\/orchestrator_$/i.test(trimmed) ? trimmed : `${trimmed}/orchestrator_`;
960
+ }
961
+ function feedsEndpoint(orchestratorUrl) {
962
+ return `${orchestratorBase(orchestratorUrl)}${FEEDS_PATH}`;
879
963
  }
880
964
  async function describeFailure(response) {
881
965
  const text = await response.text().catch(() => "");
@@ -921,14 +1005,18 @@ class OrchestratorFeedComposer {
921
1005
  this.feedsService = feedsService ?? new OrchestratorFeedsService(logger);
922
1006
  }
923
1007
  async composeAsync({
924
- connection
1008
+ connection,
1009
+ feedFolder
925
1010
  }) {
926
- const feeds = await this.resolveTenantFeeds(connection);
1011
+ const feeds = feedFolder ? await this.resolveFolderFeed(connection, feedFolder) : await this.resolveTenantFeeds(connection);
927
1012
  if (feeds.length === 0) {
928
1013
  return NO_FEEDS;
929
1014
  }
930
1015
  const [error, composed] = await catchError(this.writeFeedsFile(feeds));
931
1016
  if (error || !composed) {
1017
+ if (feedFolder) {
1018
+ throw error ?? new Error(translate2.t("packagerOrchestratorClient.feeds.errors.feedFolderNotWritten", { folder: feedFolder }));
1019
+ }
932
1020
  this.warnFeedsUnavailable();
933
1021
  return NO_FEEDS;
934
1022
  }
@@ -951,6 +1039,46 @@ class OrchestratorFeedComposer {
951
1039
  }
952
1040
  return feeds.map((feed) => toTenantFeedSource(feed, accessToken)).filter((feed) => feed !== undefined);
953
1041
  }
1042
+ async resolveFolderFeed(connection, feedFolder) {
1043
+ if (!connection?.accessToken || !connection.cloudUrl) {
1044
+ throw new Error(translate2.t("packagerOrchestratorClient.feeds.errors.feedFolderNeedsConnection", { folder: feedFolder }));
1045
+ }
1046
+ const { accessToken, cloudUrl, tenantId } = connection;
1047
+ const orchestratorConnection = {
1048
+ orchestratorUrl: cloudUrl,
1049
+ accessToken,
1050
+ tenantId
1051
+ };
1052
+ const folders = await this.feedsService.getFoldersAsync(orchestratorConnection);
1053
+ const wanted = feedFolder.trim().toLowerCase();
1054
+ const byPath = folders.filter((f) => f.fullyQualifiedName?.toLowerCase() === wanted);
1055
+ const byName = folders.filter((f) => f.displayName?.toLowerCase() === wanted);
1056
+ if (byPath.length === 0 && byName.length > 1) {
1057
+ throw new Error(translate2.t("packagerOrchestratorClient.feeds.errors.feedFolderAmbiguous", {
1058
+ folder: feedFolder,
1059
+ count: byName.length,
1060
+ paths: byName.map((f) => f.fullyQualifiedName ?? f.displayName).filter(Boolean).join(", ")
1061
+ }));
1062
+ }
1063
+ const folder = byPath[0] ?? byName[0];
1064
+ if (!folder?.key) {
1065
+ throw new Error(translate2.t("packagerOrchestratorClient.feeds.errors.feedFolderNotFound", {
1066
+ folder: feedFolder,
1067
+ available: folders.map((f) => f.fullyQualifiedName ?? f.displayName).filter(Boolean).join(", ")
1068
+ }));
1069
+ }
1070
+ const feedId = await this.feedsService.getFolderFeedIdAsync(orchestratorConnection, folder.key);
1071
+ if (!feedId) {
1072
+ throw new Error(translate2.t("packagerOrchestratorClient.feeds.errors.feedFolderHasNoFeed", { folder: feedFolder }));
1073
+ }
1074
+ this.logger.info(`Resolving library dependencies from the feed of folder '${feedFolder}' instead of all tenant feeds.`);
1075
+ return [
1076
+ {
1077
+ Url: folderFeedUrl(cloudUrl, feedId),
1078
+ AccessToken: accessToken
1079
+ }
1080
+ ];
1081
+ }
954
1082
  async writeFeedsFile(feeds) {
955
1083
  const storage = new TemporaryStorageService(this.fileSystem);
956
1084
  const directory = await storage.getTempFolderPath();
@@ -1454,10 +1582,10 @@ class WorkflowCompilerTool extends ProjectTool {
1454
1582
  async withFeedPaths(options, run) {
1455
1583
  const userNugetConfigPath = options.nuGetSourcesConfigPath;
1456
1584
  const connection = this.context?.connection;
1457
- if (!connection) {
1585
+ if (!connection && !options.feedFolder) {
1458
1586
  return run({ userNugetConfigPath });
1459
1587
  }
1460
- const composed = await new OrchestratorFeedComposer(this.fileSystem, this.logger).composeAsync({ connection });
1588
+ const composed = await new OrchestratorFeedComposer(this.fileSystem, this.logger).composeAsync({ connection, feedFolder: options.feedFolder });
1461
1589
  try {
1462
1590
  return await run({
1463
1591
  orchestratorFeedsJsonPath: composed.configPath,
@@ -1780,4 +1908,4 @@ export {
1780
1908
  WorkflowCompilerToolFactory
1781
1909
  };
1782
1910
 
1783
- //# debugId=8617FFB8E317023F64756E2164756E21
1911
+ //# debugId=2AB2C16F453AA28E64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/packager-tool-workflowcompiler",
3
- "version": "1.201.0-preview.121",
3
+ "version": "1.201.0-preview.123",
4
4
  "description": "UiPath Workflow Compiler tool implementation",
5
5
  "type": "module",
6
6
  "exports": {
@@ -28,5 +28,5 @@
28
28
  "@uipath/solutionpackager-tool-core": "1.201.0"
29
29
  },
30
30
  "dependencies": {},
31
- "gitHead": "c70ccfc0b12e637441d67df1d212b71d7784b5f8"
31
+ "gitHead": "0b5e086775b5974d9df45fc98f96f868bb3dda61"
32
32
  }
@@ -77,7 +77,11 @@ export class WorkflowCompilerTool extends ProjectTool {
77
77
  // channel; it is never mixed into the internal feeds file.
78
78
  const userNugetConfigPath = options.nuGetSourcesConfigPath;
79
79
  const connection = this.context?.connection;
80
- if (!connection) {
80
+ // A named folder must fail closed. Skipping composition here would let
81
+ // the build fall back to whatever other sources are configured, which is
82
+ // precisely what --feed-folder exists to prevent — so hand it to the
83
+ // composer even without a session and let it raise.
84
+ if (!connection && !options.feedFolder) {
81
85
  return run({ userNugetConfigPath });
82
86
  }
83
87
  // Orchestrator tenant feeds are composed into a JSON file that only ever
@@ -85,7 +89,7 @@ export class WorkflowCompilerTool extends ProjectTool {
85
89
  const composed = await new OrchestratorFeedComposer(
86
90
  this.fileSystem,
87
91
  this.logger,
88
- ).composeAsync({ connection });
92
+ ).composeAsync({ connection, feedFolder: options.feedFolder });
89
93
  try {
90
94
  return await run({
91
95
  orchestratorFeedsJsonPath: composed.configPath,