@uipath/solution-tool 1.203.0-preview.212 → 1.204.0-preview.211
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/README.md +2 -2
- package/dist/THIRD-PARTY-NOTICES.md +4 -4
- package/dist/deploy-delete-service-gg00vadc.js +22 -0
- package/dist/deploy-status-service-cqfrvxpz.js +256 -0
- package/dist/deploy.d.ts +11 -4
- package/dist/deploy.js +19 -7
- package/dist/deployment-search-j34w33b2.js +49 -0
- package/dist/{embedded-file-reader-xxqe8vs8.js → embedded-file-reader-rf2g1kfj.js} +2 -2
- package/dist/feed-resolver-31gcvnnk.js +27 -0
- package/dist/feed-scope-failure-fwtdvvrh.js +18 -0
- package/dist/feed-session-sxga31vn.js +17 -0
- package/dist/index.js +27 -18
- package/dist/init.js +10 -7
- package/dist/{list-xjdnbyka.js → list-q4dzkv45.js} +9 -6
- package/dist/pack.js +14 -11
- package/dist/{packager-tool-7qmx64kz.js → packager-tool-00vh1ktg.js} +1022 -1342
- package/dist/packager-tool-1phh2rfx.js +37 -0
- package/dist/{packager-tool-vas0xg5h.js → packager-tool-2cntqvdv.js} +5 -3
- package/dist/{packager-tool-1haahq17.js → packager-tool-3enm2h28.js} +5 -5
- package/dist/{packager-tool-2syrt51a.js → packager-tool-3fv6zc86.js} +1062 -825
- package/dist/{packager-tool-grtmkd54.js → packager-tool-3m36mxn7.js} +16 -74
- package/dist/packager-tool-40vcj4wv.js +172 -0
- package/dist/packager-tool-482eg22x.js +322 -0
- package/dist/{packager-tool-k4mskzww.js → packager-tool-5dzjsw5q.js} +3 -3
- package/dist/{packager-tool-0f0wt9vh.js → packager-tool-5fjp60dk.js} +3071 -2794
- package/dist/{packager-tool-bkwnetqn.js → packager-tool-83rzavkx.js} +383 -88
- package/dist/{packager-tool-f423v35w.js → packager-tool-9hj0cfd0.js} +756 -359
- package/dist/{packager-tool-7znqtw3f.js → packager-tool-9vvdgbay.js} +8 -6
- package/dist/packager-tool-bqre28m1.js +43 -0
- package/dist/packager-tool-f5gq77m5.js +28 -0
- package/dist/{packager-tool-nzghfa48.js → packager-tool-fv7xyzg2.js} +550 -2
- package/dist/{packager-tool-3jrq7smt.js → packager-tool-gb35b4qs.js} +206 -289
- package/dist/{packager-tool-4kdt8mys.js → packager-tool-j30xck4w.js} +1008 -647
- package/dist/packager-tool-ks8spnq8.js +166 -0
- package/dist/packager-tool-q3tgpemc.js +113 -0
- package/dist/packager-tool-qdtjywsk.js +173 -0
- package/dist/{packager-tool-2p5yh1q9.js → packager-tool-qgaqqq41.js} +320 -151
- package/dist/packager-tool-qm24rbae.js +5889 -0
- package/dist/{packager-tool-resolver-fmjr60x8.js → packager-tool-resolver-2cbxyq6k.js} +6 -5
- package/dist/{packager-tool-znakt6yw.js → packager-tool-vh4ng74p.js} +8 -6
- package/dist/packager-tool-vmsxq1pc.js +104 -0
- package/dist/packager-tool-zf3929se.js +237 -0
- package/dist/packager-tool-zns6n8zp.js +837 -0
- package/dist/packager-tool.js +2 -2
- package/dist/prepare-solution-resources-p3gzdecy.js +25 -0
- package/dist/{project-contributions-cvttys34.js → project-contributions-txe8v6sm.js} +12 -9
- package/dist/publish.js +12 -7
- package/dist/resource.js +9 -6
- package/dist/services/activation.d.ts +17 -2
- package/dist/services/deploy-activate-service.d.ts +10 -0
- package/dist/services/deploy-delete-service.d.ts +82 -0
- package/dist/services/deploy-list-service.d.ts +15 -45
- package/dist/services/deploy-run-service.d.ts +36 -23
- package/dist/services/deploy-upgrade-service.d.ts +198 -39
- package/dist/services/deployment-feed-locator.d.ts +50 -12
- package/dist/services/deployment-search-client.d.ts +55 -0
- package/dist/services/deployment-search.d.ts +87 -34
- package/dist/services/deployment-state.d.ts +119 -0
- package/dist/services/feed-resolver.d.ts +31 -0
- package/dist/services/feed-session.d.ts +70 -0
- package/dist/services/folder-helper.d.ts +4 -27
- package/dist/services/http-status.d.ts +9 -0
- package/dist/services/incomplete-feed-sweep.d.ts +77 -0
- package/dist/services/legacy-deployment-search-v3.d.ts +23 -0
- package/dist/services/packages-list-service.d.ts +5 -0
- package/dist/services/pipeline-deploy-poll.d.ts +69 -0
- package/dist/services/publish-service.d.ts +14 -16
- package/dist/services/search-failure.d.ts +27 -0
- package/dist/templates/AGENTS.md +60 -20
- package/dist/tool.js +27 -18
- package/dist/utils/deployment-errors.d.ts +57 -0
- package/package.json +2 -2
- package/dist/packager-tool-jz2wbfjz.js +0 -2275
- package/dist/packager-tool-wtpe9285.js +0 -51960
- package/dist/prepare-solution-resources-wds3r8bq.js +0 -22
- package/dist/services/personal-workspace-deploy.d.ts +0 -49
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getStudioWebAuthWithOrganizationId,
|
|
3
3
|
useStudioWebAuth
|
|
4
|
-
} from "./packager-tool-
|
|
4
|
+
} from "./packager-tool-3enm2h28.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveFeedScopeOrFailureAsync
|
|
7
|
+
} from "./packager-tool-1phh2rfx.js";
|
|
5
8
|
import {
|
|
6
9
|
activateDeploymentAsync,
|
|
7
10
|
deployRunAsync,
|
|
@@ -11,11 +14,11 @@ import {
|
|
|
11
14
|
listPackagesAsync,
|
|
12
15
|
uninstallDeploymentAsync,
|
|
13
16
|
upgradeDeploymentAsync
|
|
14
|
-
} from "./packager-tool-
|
|
17
|
+
} from "./packager-tool-j30xck4w.js";
|
|
15
18
|
import {
|
|
16
19
|
SolutionInitError,
|
|
17
20
|
solutionInitAsync
|
|
18
|
-
} from "./packager-tool-
|
|
21
|
+
} from "./packager-tool-2cntqvdv.js";
|
|
19
22
|
import {
|
|
20
23
|
GOVERNANCE_OPTION_INSTRUCTIONS,
|
|
21
24
|
PackCommandService,
|
|
@@ -28,32 +31,29 @@ import {
|
|
|
28
31
|
readSolutionFileAsUint8Array,
|
|
29
32
|
resolveSdkLogLevel,
|
|
30
33
|
validateGovernanceOptions
|
|
31
|
-
} from "./packager-tool-
|
|
34
|
+
} from "./packager-tool-qm24rbae.js";
|
|
32
35
|
import {
|
|
33
36
|
prepareSolutionResources
|
|
34
|
-
} from "./packager-tool-
|
|
37
|
+
} from "./packager-tool-9vvdgbay.js";
|
|
35
38
|
import {
|
|
36
39
|
ensurePackagerTools,
|
|
37
40
|
isUnpackableProjectTypeError,
|
|
38
41
|
toolVerbForProjectType
|
|
39
|
-
} from "./packager-tool-
|
|
42
|
+
} from "./packager-tool-5dzjsw5q.js";
|
|
40
43
|
import {
|
|
41
44
|
publishSolutionAsync
|
|
42
|
-
} from "./packager-tool-
|
|
45
|
+
} from "./packager-tool-3m36mxn7.js";
|
|
43
46
|
import {
|
|
44
47
|
Configuration,
|
|
45
|
-
PipelinesApi
|
|
46
|
-
|
|
48
|
+
PipelinesApi
|
|
49
|
+
} from "./packager-tool-qgaqqq41.js";
|
|
50
|
+
import {
|
|
47
51
|
feedScopeInitOverride,
|
|
48
|
-
listSelectablePublishLocations
|
|
49
|
-
|
|
50
|
-
} from "./packager-tool-2p5yh1q9.js";
|
|
52
|
+
listSelectablePublishLocations
|
|
53
|
+
} from "./packager-tool-qdtjywsk.js";
|
|
51
54
|
import {
|
|
52
|
-
Configuration as Configuration2,
|
|
53
55
|
DeploymentActivationStatus,
|
|
54
56
|
DeploymentOperationStatus,
|
|
55
|
-
PackagesApi,
|
|
56
|
-
SearchApi,
|
|
57
57
|
StudioWebIncompatibleProjectError,
|
|
58
58
|
buildSolutionUploadFailureOutput,
|
|
59
59
|
bundleSolution,
|
|
@@ -63,20 +63,22 @@ import {
|
|
|
63
63
|
isDebugProvisioningTerminal,
|
|
64
64
|
isSolutionUploadHttpError,
|
|
65
65
|
overwriteSolution,
|
|
66
|
-
searchPackageVersions,
|
|
67
66
|
solutionExistsOnStudioWeb
|
|
68
|
-
} from "./packager-tool-
|
|
67
|
+
} from "./packager-tool-00vh1ktg.js";
|
|
69
68
|
import {
|
|
70
|
-
Tokens,
|
|
71
69
|
applyEntryPointEnhancementAsync,
|
|
72
70
|
assertSolutionManifest,
|
|
73
71
|
createLocalResource,
|
|
74
72
|
createProjectInSolutionBuilder,
|
|
75
73
|
createResourceBuilderServices,
|
|
76
74
|
createResourceKindMetadataResolver,
|
|
75
|
+
exportResourceDefinitionAsync,
|
|
76
|
+
findCatalogEntityAsync,
|
|
77
77
|
findMatchingLocalResource,
|
|
78
78
|
findProjectFile,
|
|
79
79
|
findResourceByKeyInRcs,
|
|
80
|
+
formatResourceSubtypes,
|
|
81
|
+
getRemoteResourceClients,
|
|
80
82
|
hasAnyTemplateRow,
|
|
81
83
|
hasBareTemplateRow,
|
|
82
84
|
isMissingProjectTypeError,
|
|
@@ -85,41 +87,47 @@ import {
|
|
|
85
87
|
normalizeResourceFileCasing,
|
|
86
88
|
readProjectFile,
|
|
87
89
|
readSolutionFile,
|
|
90
|
+
readSpecProperty,
|
|
91
|
+
resolveResourceKindMetadata,
|
|
88
92
|
resolveSolutionFilePath,
|
|
89
93
|
resourceRefreshAsync,
|
|
90
94
|
resourceRemoteSyncAsync,
|
|
91
95
|
restoreSolutionFile,
|
|
96
|
+
sameResourceSubtype,
|
|
92
97
|
saveCasingNormalized,
|
|
93
98
|
searchRcsResources,
|
|
94
99
|
syncResourcesFromBindings,
|
|
100
|
+
toResourceReference,
|
|
101
|
+
validateResourceName,
|
|
95
102
|
writeSolutionFile
|
|
96
|
-
} from "./packager-tool-
|
|
103
|
+
} from "./packager-tool-83rzavkx.js";
|
|
97
104
|
import {
|
|
98
105
|
ToolResult
|
|
99
|
-
} from "./packager-tool-
|
|
106
|
+
} from "./packager-tool-fv7xyzg2.js";
|
|
100
107
|
import {
|
|
101
108
|
getSolutionAuthContext
|
|
102
|
-
} from "./packager-tool-
|
|
109
|
+
} from "./packager-tool-f5gq77m5.js";
|
|
103
110
|
import {
|
|
104
|
-
getLoginStatusAsync,
|
|
105
111
|
resolveSolutionDir,
|
|
106
112
|
toPortableRelativePath,
|
|
107
113
|
updateUipxSolutionId
|
|
108
|
-
} from "./packager-tool-
|
|
114
|
+
} from "./packager-tool-vmsxq1pc.js";
|
|
109
115
|
import {
|
|
116
|
+
CommandDimensions,
|
|
110
117
|
DEFAULT_PAGE_SIZE,
|
|
111
118
|
Option,
|
|
112
119
|
OutputFormatter,
|
|
113
120
|
Pagination,
|
|
114
121
|
PollOutcome,
|
|
115
122
|
RESULTS,
|
|
123
|
+
ShipDimensions,
|
|
116
124
|
carriedErrorCode,
|
|
117
125
|
carriedInstructions,
|
|
126
|
+
carriedRetry,
|
|
118
127
|
catchError,
|
|
119
128
|
createHiddenDeprecatedTenantOption,
|
|
120
129
|
extractErrorDetails,
|
|
121
130
|
extractErrorMessage,
|
|
122
|
-
getFileSystem,
|
|
123
131
|
isGuid,
|
|
124
132
|
isPreviewBuild,
|
|
125
133
|
logger,
|
|
@@ -137,7 +145,13 @@ import {
|
|
|
137
145
|
unsupportedSolutionProjectType,
|
|
138
146
|
warnDeprecatedOptionAlias,
|
|
139
147
|
withCompleter
|
|
140
|
-
} from "./packager-tool-
|
|
148
|
+
} from "./packager-tool-5fjp60dk.js";
|
|
149
|
+
import {
|
|
150
|
+
getLoginStatusAsync
|
|
151
|
+
} from "./packager-tool-gb35b4qs.js";
|
|
152
|
+
import {
|
|
153
|
+
getFileSystem
|
|
154
|
+
} from "./packager-tool-zf3929se.js";
|
|
141
155
|
import {
|
|
142
156
|
strFromU8,
|
|
143
157
|
unzip,
|
|
@@ -151,7 +165,7 @@ var package_default = {
|
|
|
151
165
|
name: "@uipath/solution-tool",
|
|
152
166
|
author: "UiPath",
|
|
153
167
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
154
|
-
version: "1.
|
|
168
|
+
version: "1.204.0-preview.211",
|
|
155
169
|
description: "Create, pack, publish, and deploy UiPath Automation Solutions.",
|
|
156
170
|
repository: {
|
|
157
171
|
type: "git",
|
|
@@ -214,8 +228,8 @@ var package_default = {
|
|
|
214
228
|
"@uipath/packager-tool-connector": "workspace:*",
|
|
215
229
|
"@uipath/pipelines-sdk": "workspace:*",
|
|
216
230
|
"@uipath/project-executor": "workspace:*",
|
|
217
|
-
"@uipath/resource-builder-sdk": "2025.11.0-
|
|
218
|
-
"@uipath/resource-builder-tool": "2025.11.0-
|
|
231
|
+
"@uipath/resource-builder-sdk": "2025.11.0-alpha6004-4107",
|
|
232
|
+
"@uipath/resource-builder-tool": "2025.11.0-alpha6004-4107",
|
|
219
233
|
"@uipath/solution-packager": "workspace:*",
|
|
220
234
|
"@uipath/solution-sdk": "workspace:*",
|
|
221
235
|
"@uipath/solutionpackager-tool-core": "workspace:*",
|
|
@@ -489,7 +503,9 @@ var registerDeployActivateCommand = (program) => {
|
|
|
489
503
|
OutputFormatter.error({
|
|
490
504
|
Result: RESULTS.Failure,
|
|
491
505
|
Message: result.message,
|
|
492
|
-
Instructions: result.instructions
|
|
506
|
+
Instructions: result.instructions,
|
|
507
|
+
ErrorCode: result.errorCode,
|
|
508
|
+
Retry: result.retry
|
|
493
509
|
});
|
|
494
510
|
processContext.exit(result.exitCode);
|
|
495
511
|
return;
|
|
@@ -1016,6 +1032,54 @@ var registerDeployConfigCommand = (program) => {
|
|
|
1016
1032
|
registerDeployConfigUnlinkCommand(config);
|
|
1017
1033
|
};
|
|
1018
1034
|
|
|
1035
|
+
// src/commands/deploy-delete.ts
|
|
1036
|
+
var SOLUTION_DEPLOY_DELETE_EXAMPLES = [
|
|
1037
|
+
{
|
|
1038
|
+
Description: "Delete an inactive deployment record left behind by 'deploy uninstall'",
|
|
1039
|
+
Command: "uip solution deploy delete my-deployment --yes",
|
|
1040
|
+
Output: {
|
|
1041
|
+
Code: "SolutionDeployDelete",
|
|
1042
|
+
Data: {
|
|
1043
|
+
Status: "Deleted",
|
|
1044
|
+
DeploymentName: "my-deployment",
|
|
1045
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001"
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
];
|
|
1050
|
+
var registerDeployDeleteCommand = (program) => {
|
|
1051
|
+
program.command("delete").description("Delete a deployment from the tenant. Use this for a deployment that 'deploy uninstall' cannot remove: one left inactive after an uninstall, one superseded by a newer version, or one left behind by a failed install — Orchestrator refuses to uninstall those with error 4007. The command reads the deployment first, and refuses when its own action list offers actions but not Delete, naming the state and the actions that are available. A record that lists no actions at all says nothing, so there the request goes to the server and the server decides.").argument("<deployment-name>", "Name of the deployment to delete. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").examples(SOLUTION_DEPLOY_DELETE_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
|
|
1052
|
+
if (!requireConfirmation(options, `delete deployment '${deploymentName}'`)) {
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
const { deleteDeploymentAsync } = await import("./deploy-delete-service-gg00vadc.js");
|
|
1056
|
+
const result = await deleteDeploymentAsync(deploymentName, {
|
|
1057
|
+
tenant: options.tenant,
|
|
1058
|
+
loginValidity: options.loginValidity
|
|
1059
|
+
});
|
|
1060
|
+
if (!result.ok) {
|
|
1061
|
+
OutputFormatter.error({
|
|
1062
|
+
Result: RESULTS.Failure,
|
|
1063
|
+
Message: result.message,
|
|
1064
|
+
Instructions: result.instructions,
|
|
1065
|
+
ErrorCode: result.errorCode,
|
|
1066
|
+
Retry: result.retry
|
|
1067
|
+
});
|
|
1068
|
+
processContext.exit(result.exitCode);
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
OutputFormatter.success({
|
|
1072
|
+
Result: RESULTS.Success,
|
|
1073
|
+
Code: "SolutionDeployDelete",
|
|
1074
|
+
Data: {
|
|
1075
|
+
Status: "Deleted",
|
|
1076
|
+
DeploymentName: result.deploymentName,
|
|
1077
|
+
DeploymentKey: result.deploymentKey
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
});
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1019
1083
|
// src/commands/deploy-list.ts
|
|
1020
1084
|
var OPERATION_STATUS_VALUES = Object.values(DeploymentOperationStatus);
|
|
1021
1085
|
var ACTIVATION_STATUS_VALUES = Object.values(DeploymentActivationStatus);
|
|
@@ -1096,7 +1160,7 @@ var SOLUTION_DEPLOY_LIST_EXAMPLES = [
|
|
|
1096
1160
|
}
|
|
1097
1161
|
];
|
|
1098
1162
|
var registerDeployListCommand = (program) => {
|
|
1099
|
-
const command = program.command("list").description("List solution deployments. Shows deployment name, status, package version (current/target), pending operation, and folder path. --operation-status
|
|
1163
|
+
const command = program.command("list").description("List solution deployments. Shows deployment name, status, package version (current/target), pending operation, and folder path. --operation-status, --activation-status and --folder-path/--folder-key all filter server-side.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--folder-path <path>", "Filter by the full path of the folder the deployment was installed into (e.g., 'Shared' or 'Shared/Finance'). Exact match, not case-sensitive; subfolders are not included.").option("--folder-key <key>", "Filter by the key (GUID) of the folder the deployment was installed into. Alternative to --folder-path.").option("-l, --limit <number>", "Max deployments to return", parseLimit, DEFAULT_PAGE_SIZE).option("--offset <number>", "Number of deployments to skip", parseOffset, 0).option("--sort-by <column>", "Column to sort by (default: startTime)", "startTime").option("--sort-order <direction>", "Sort direction: Ascending or Descending (default: Descending)", "Descending").option("--operation-status <statuses>", `Filter by deployment operation status, server-side (comma-separated). One or more of: ${OPERATION_STATUS_VALUES.join(", ")}.`).option("--activation-status <statuses>", `Filter by deployment activation status, server-side (comma-separated). One or more of: ${ACTIVATION_STATUS_VALUES.join(", ")}.`).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10);
|
|
1100
1164
|
command.addOption(new Option("--feed <name-or-key>", "Only list deployments from this feed (name or folder key, from 'solution feeds list'). Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace")).option("--personal-workspace", "Only list deployments from the current user's Personal Workspace feed.");
|
|
1101
1165
|
command.examples(SOLUTION_DEPLOY_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
|
|
1102
1166
|
const operationStatus = parseStatusFilter(options.operationStatus, OPERATION_STATUS_VALUES, "--operation-status");
|
|
@@ -1137,7 +1201,10 @@ var registerDeployListCommand = (program) => {
|
|
|
1137
1201
|
OutputFormatter.error({
|
|
1138
1202
|
Result: RESULTS.Failure,
|
|
1139
1203
|
Message: result.message,
|
|
1140
|
-
Instructions: result.instructions
|
|
1204
|
+
Instructions: result.instructions,
|
|
1205
|
+
ErrorCode: result.errorCode,
|
|
1206
|
+
Retry: result.retry,
|
|
1207
|
+
...result.context ? { Context: result.context } : {}
|
|
1141
1208
|
});
|
|
1142
1209
|
processContext.exit(result.exitCode);
|
|
1143
1210
|
return;
|
|
@@ -1237,35 +1304,49 @@ var SOLUTION_DEPLOY_RUN_EXAMPLES = [
|
|
|
1237
1304
|
}
|
|
1238
1305
|
},
|
|
1239
1306
|
{
|
|
1240
|
-
Description: "
|
|
1241
|
-
Command:
|
|
1307
|
+
Description: "A deploy that succeeded but is not live: a resource needs 'Setup activation' in Orchestrator before the deployment can be activated (Result: Success; do not deploy again)",
|
|
1308
|
+
Command: 'uip solution deploy run --name my-deployment --package-name my-package --package-version 1.0.0 --folder-name MySolution --parent-folder-path "Shared"',
|
|
1242
1309
|
Output: {
|
|
1243
1310
|
Code: "SolutionDeployRun",
|
|
1244
1311
|
Data: {
|
|
1245
|
-
Status: "
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1312
|
+
Status: "DeploymentSucceeded",
|
|
1313
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000003",
|
|
1314
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000003",
|
|
1315
|
+
InstanceId: null,
|
|
1249
1316
|
FolderName: "MySolution",
|
|
1250
|
-
FolderPath: "
|
|
1251
|
-
ActivationStatus: "
|
|
1252
|
-
|
|
1317
|
+
FolderPath: "Shared/MySolution",
|
|
1318
|
+
ActivationStatus: "NeedsSetupToActivate",
|
|
1319
|
+
PendingResources: [
|
|
1320
|
+
{
|
|
1321
|
+
Kind: "connection",
|
|
1322
|
+
Name: "Outlook",
|
|
1323
|
+
Type: "uipath-microsoft-outlook365",
|
|
1324
|
+
Reason: "[CNS1072] You will need to authenticate this connection before proceeding further"
|
|
1325
|
+
}
|
|
1326
|
+
],
|
|
1327
|
+
NextSteps: [
|
|
1328
|
+
"Deployment 'my-deployment' is installed at version 1.0.0 but not live: it needs 'Setup activation' before it can be activated.",
|
|
1329
|
+
"Resources that need configuration: connection 'Outlook' (uipath-microsoft-outlook365): [CNS1072] You will need to authenticate this connection before proceeding further."
|
|
1330
|
+
]
|
|
1253
1331
|
}
|
|
1254
1332
|
}
|
|
1255
1333
|
},
|
|
1256
1334
|
{
|
|
1257
|
-
Description: "Deploy
|
|
1258
|
-
Command: "uip solution deploy run --name my-deployment --package-name my-package --package-version 1.0.0 --folder-name MySolution --personal-workspace
|
|
1335
|
+
Description: "Deploy a solution package into the current user's Personal Workspace",
|
|
1336
|
+
Command: "uip solution deploy run --name my-deployment --package-name my-package --package-version 1.0.0 --folder-name MySolution --personal-workspace",
|
|
1259
1337
|
Output: {
|
|
1260
1338
|
Code: "SolutionDeployRun",
|
|
1261
1339
|
Data: {
|
|
1262
1340
|
Status: "DeploymentSucceeded",
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1341
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
1342
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000001",
|
|
1343
|
+
InstanceId: "c3d4e5f6-0000-0000-0000-000000000001",
|
|
1266
1344
|
FolderName: "MySolution",
|
|
1267
1345
|
FolderPath: "alice@uipath.com/MySolution",
|
|
1268
|
-
ActivationStatus: "
|
|
1346
|
+
ActivationStatus: "SuccessfulActivate",
|
|
1347
|
+
DeploymentName: "my-deployment",
|
|
1348
|
+
PackageName: "my-package",
|
|
1349
|
+
PackageVersion: "1.0.0"
|
|
1269
1350
|
}
|
|
1270
1351
|
}
|
|
1271
1352
|
},
|
|
@@ -1292,20 +1373,22 @@ var SOLUTION_DEPLOY_RUN_FEED_EXAMPLE = {
|
|
|
1292
1373
|
Output: {
|
|
1293
1374
|
Code: "SolutionDeployRun",
|
|
1294
1375
|
Data: {
|
|
1295
|
-
Status: "
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1376
|
+
Status: "DeploymentSucceeded",
|
|
1377
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
1378
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000001",
|
|
1379
|
+
InstanceId: "c3d4e5f6-0000-0000-0000-000000000001",
|
|
1299
1380
|
FolderName: "MySolution",
|
|
1300
1381
|
FolderPath: "Finance/MySolution",
|
|
1301
|
-
ActivationStatus: "
|
|
1302
|
-
|
|
1382
|
+
ActivationStatus: "SuccessfulActivate",
|
|
1383
|
+
DeploymentName: "my-deployment",
|
|
1384
|
+
PackageName: "my-package",
|
|
1385
|
+
PackageVersion: "1.0.0"
|
|
1303
1386
|
}
|
|
1304
1387
|
}
|
|
1305
1388
|
};
|
|
1306
1389
|
var registerDeployRunCommand = (program) => {
|
|
1307
|
-
const command = program.command("run").description("Deploy a solution package to Orchestrator. Creates a folder, provisions resources, and (by default) activates the solution.
|
|
1308
|
-
command.addOption(new Option("--feed <name-or-key>", "Deploy a package from a specific feed (name or folder key, from 'solution feeds list') instead of the tenant feed. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace"));
|
|
1390
|
+
const command = program.command("run").description("Deploy a solution package to Orchestrator. Creates a folder, provisions resources, and (by default) activates the solution. The deployment is keyed on --name: a name that does not exist yet gets a NEW deployment in a NEW folder (the normal case), while re-using an existing deployment's name updates that deployment in place — use 'deploy upgrade' when that is what you want. If the package is already deployed the command stops and points you at the upgrade path; pass --yes with a different --name to deploy a second, separate copy anyway. Pass --skip-activate to leave the deployment in 'Inactive (Ready to activate)' state and activate later with 'deploy activate'. A deployment whose resources need 'Setup activation' in Orchestrator is installed but not activated: the command reports Result: Success with ActivationStatus: NeedsSetupToActivate, the resources and the steps left — do not deploy it again. To customize resource settings before deploying, use 'config get' to fetch the default config, 'config set' / 'config link' to edit it, then pass it here with --config-file.").requiredOption("-n, --name <deployment-name>", "Name for the deployment").addOption(withCompleter(new Option("--package-name <name>", "Solution package name to deploy. Use 'solution packages list' to find available names.").makeOptionMandatory(), packageNameCompleter)).addOption(withCompleter(new Option("--package-version <version>", "Solution package version to deploy. Use 'solution packages list' to find available versions.").makeOptionMandatory(), packageVersionCompleter)).requiredOption("--folder-name <name>", "Name for the new Orchestrator folder created for this deployment (created under --parent-folder-path if specified)").addOption(new Option("--parent-folder-path <path>", "Parent folder path (e.g., 'Shared'). Solution folder is created under this.").conflicts("parentFolderKey")).option("--parent-folder-key <key>", "Parent folder key (GUID). Alternative to --parent-folder-path.").addOption(new Option("--personal-workspace", "Deploy into the current user's Personal Workspace. Resolves the workspace name from Orchestrator automatically; needs a user session (an external app has no workspace, and the server ignores the feed header on client-credentials requests). Mutually exclusive with --parent-folder-path and --parent-folder-key.").conflicts(["parentFolderPath", "parentFolderKey"])).option("--config-file <path>", "JSON or YAML configuration file. Generate with: uip solution deploy config get <name> -d config.json, then customize with 'config set' or 'config link'.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds applied per polling phase — deploy and (when not skipped) activate (default: 360 each)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between status polls during the deploy and activate phases (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).addOption(new Option("--wait", "Deprecated and ignored: every deploy now waits for the install to finish (bounded by --timeout).").hideHelp()).option("--skip-activate", "Skip auto-activation; leave the deployment in 'Inactive (Ready to activate)' state. Activate later with 'uip solution deploy activate <name>'.").option("-y, --yes", "Deploy even when this package already has a deployment. Without it, deploy run looks the package up and stops if it is already deployed. That check is best-effort, not a guarantee: a lookup failure only warns, and under an application (client-credentials) login it never stops the deploy — an existing deployment is reported as a warning, or the check is skipped on servers without the Pipelines deployment search. --yes only skips that check: the install is keyed on --name, so re-using an existing deployment's name updates that deployment in place rather than creating a second copy — pass a different --name for a separate deployment.");
|
|
1391
|
+
command.addOption(new Option("--feed <name-or-key>", "Deploy a package from a specific feed (name or folder key, from 'solution feeds list') instead of the tenant feed. Needs a user session: the server ignores the feed header on client-credentials requests, so an external app is refused rather than deploying to the tenant feed by accident. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace"));
|
|
1309
1392
|
command.examples([
|
|
1310
1393
|
...SOLUTION_DEPLOY_RUN_EXAMPLES,
|
|
1311
1394
|
SOLUTION_DEPLOY_RUN_FEED_EXAMPLE
|
|
@@ -1321,7 +1404,6 @@ var registerDeployRunCommand = (program) => {
|
|
|
1321
1404
|
personalWorkspace: options.personalWorkspace,
|
|
1322
1405
|
feed: options.feed,
|
|
1323
1406
|
configFile: options.configFile,
|
|
1324
|
-
wait: options.wait,
|
|
1325
1407
|
timeout: options.timeout,
|
|
1326
1408
|
pollInterval: options.pollInterval,
|
|
1327
1409
|
loginValidity: options.loginValidity,
|
|
@@ -1353,21 +1435,29 @@ var registerDeployRunCommand = (program) => {
|
|
|
1353
1435
|
RequestedFolderName: result.requestedFolderName,
|
|
1354
1436
|
FolderNote: result.requestedFolderName === undefined ? undefined : `Requested folder '${result.requestedFolderName}' already existed, so Orchestrator created '${result.folderName}' instead. Deploying cannot target a pre-existing folder; provision resources into '${result.folderPath}', or re-run with a free --folder-name.`,
|
|
1355
1437
|
ActivationStatus: result.activationStatus,
|
|
1438
|
+
...result.pendingResources ? {
|
|
1439
|
+
PendingResources: result.pendingResources.map((resource) => ({
|
|
1440
|
+
Kind: resource.kind,
|
|
1441
|
+
Name: resource.name,
|
|
1442
|
+
Type: resource.type ?? null,
|
|
1443
|
+
Reason: resource.reason ?? null
|
|
1444
|
+
}))
|
|
1445
|
+
} : {},
|
|
1446
|
+
...result.nextSteps ? { NextSteps: result.nextSteps } : {},
|
|
1356
1447
|
DeploymentName: result.deploymentName,
|
|
1357
1448
|
PackageName: result.packageName,
|
|
1358
|
-
PackageVersion: result.packageVersion
|
|
1359
|
-
NextSteps: result.nextSteps
|
|
1449
|
+
PackageVersion: result.packageVersion
|
|
1360
1450
|
}
|
|
1361
1451
|
});
|
|
1362
1452
|
trackShipSucceeded({
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1453
|
+
[ShipDimensions.ShipKind]: "deploy",
|
|
1454
|
+
[ShipDimensions.Target]: result.feedKind === "personal" ? "personal_workspace_orchestrator" : result.feedKind === "folder" ? "folder_orchestrator" : "orchestrator",
|
|
1455
|
+
[ShipDimensions.ProjectType]: "solution",
|
|
1456
|
+
[CommandDimensions.CommandName]: "uip solution deploy run",
|
|
1457
|
+
[ShipDimensions.ArtifactCorrelationKey]: result.deploymentKey ?? result.pipelineDeploymentId ?? result.deploymentName,
|
|
1458
|
+
[ShipDimensions.DeploymentKey]: result.deploymentKey,
|
|
1459
|
+
[ShipDimensions.PackageName]: options.packageName,
|
|
1460
|
+
[ShipDimensions.PackageVersion]: options.packageVersion
|
|
1371
1461
|
});
|
|
1372
1462
|
});
|
|
1373
1463
|
};
|
|
@@ -1375,7 +1465,66 @@ var registerDeployRunCommand = (program) => {
|
|
|
1375
1465
|
// src/commands/deploy-status.ts
|
|
1376
1466
|
var SOLUTION_DEPLOY_STATUS_EXAMPLES = [
|
|
1377
1467
|
{
|
|
1378
|
-
Description: "Check
|
|
1468
|
+
Description: "Check a deployment by name: here one that is upgraded but not live",
|
|
1469
|
+
Command: 'uip solution deploy status "my-deployment"',
|
|
1470
|
+
Output: {
|
|
1471
|
+
Code: "SolutionDeployment",
|
|
1472
|
+
Data: {
|
|
1473
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000002",
|
|
1474
|
+
Superseded: false,
|
|
1475
|
+
CurrentDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000002",
|
|
1476
|
+
InstallDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
1477
|
+
Name: "my-deployment",
|
|
1478
|
+
PackageName: "my-package",
|
|
1479
|
+
PackageVersion: "2.0.0",
|
|
1480
|
+
NewPackageVersionAvailable: null,
|
|
1481
|
+
Operation: "VersionChange",
|
|
1482
|
+
OperationStatus: "Successful",
|
|
1483
|
+
DeploymentStatus: "SuccessfulInstall",
|
|
1484
|
+
ActivationStatus: "NeedsSetupToActivate",
|
|
1485
|
+
Actions: ["SetupActivation", "Uninstall", "Upgrade"],
|
|
1486
|
+
PendingResources: [
|
|
1487
|
+
{
|
|
1488
|
+
Kind: "connection",
|
|
1489
|
+
Name: "Outlook",
|
|
1490
|
+
Type: "uipath-microsoft-outlook365",
|
|
1491
|
+
Reason: "[CNS1072] You will need to authenticate this connection before proceeding further"
|
|
1492
|
+
}
|
|
1493
|
+
],
|
|
1494
|
+
NextSteps: [
|
|
1495
|
+
"Deployment 'my-deployment' is installed at version 2.0.0 but not live: it needs 'Setup activation' before it can be activated.",
|
|
1496
|
+
"Resources that need configuration: connection 'Outlook' (uipath-microsoft-outlook365): [CNS1072] You will need to authenticate this connection before proceeding further."
|
|
1497
|
+
]
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
Description: "Check a deployment key from deploy run or deploy list: here one an upgrade has superseded",
|
|
1503
|
+
Command: "uip solution deploy status a1b2c3d4-0000-0000-0000-000000000001",
|
|
1504
|
+
Output: {
|
|
1505
|
+
Code: "SolutionDeployment",
|
|
1506
|
+
Data: {
|
|
1507
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
1508
|
+
Superseded: true,
|
|
1509
|
+
CurrentDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000002",
|
|
1510
|
+
InstallDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
1511
|
+
Name: "my-deployment",
|
|
1512
|
+
PackageName: "my-package",
|
|
1513
|
+
PackageVersion: "2.0.0",
|
|
1514
|
+
NewPackageVersionAvailable: null,
|
|
1515
|
+
Operation: "ActivationSetup",
|
|
1516
|
+
OperationStatus: "Successful",
|
|
1517
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1518
|
+
ActivationStatus: "Active",
|
|
1519
|
+
Actions: ["Uninstall", "Upgrade"],
|
|
1520
|
+
NextSteps: [
|
|
1521
|
+
"Key 'a1b2c3d4-0000-0000-0000-000000000001' is superseded: 'my-deployment' is now record 'a1b2c3d4-0000-0000-0000-000000000002' (ActivationSetup/Successful, version 2.0.0). Every operation creates a new record; use the current key from now on."
|
|
1522
|
+
]
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
Description: "Check the pipeline deployment run that deploy run started",
|
|
1379
1528
|
Command: "uip solution deploy status b2c3d4e5-0000-0000-0000-000000000001",
|
|
1380
1529
|
Output: {
|
|
1381
1530
|
Code: "SolutionDeployStatus",
|
|
@@ -1392,10 +1541,32 @@ var SOLUTION_DEPLOY_STATUS_EXAMPLES = [
|
|
|
1392
1541
|
}
|
|
1393
1542
|
}
|
|
1394
1543
|
}
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
Description: "Check a deployment key that lives in your Personal Workspace feed",
|
|
1547
|
+
Command: "uip solution deploy status a1b2c3d4-0000-0000-0000-000000000003 --personal-workspace",
|
|
1548
|
+
Output: {
|
|
1549
|
+
Code: "SolutionDeployment",
|
|
1550
|
+
Data: {
|
|
1551
|
+
DeploymentKey: "a1b2c3d4-0000-0000-0000-000000000003",
|
|
1552
|
+
Superseded: false,
|
|
1553
|
+
CurrentDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000003",
|
|
1554
|
+
InstallDeploymentKey: "a1b2c3d4-0000-0000-0000-000000000003",
|
|
1555
|
+
Name: "my-deployment",
|
|
1556
|
+
PackageName: "my-package",
|
|
1557
|
+
PackageVersion: "1.0.0",
|
|
1558
|
+
NewPackageVersionAvailable: null,
|
|
1559
|
+
Operation: "Install",
|
|
1560
|
+
OperationStatus: "Successful",
|
|
1561
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1562
|
+
ActivationStatus: "Active",
|
|
1563
|
+
Actions: ["Uninstall", "Upgrade"]
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1395
1566
|
}
|
|
1396
1567
|
];
|
|
1397
1568
|
var registerDeployStatusCommand = (program) => {
|
|
1398
|
-
program.command("status").description("Check the
|
|
1569
|
+
program.command("status").description("Check the state of a deployment by name, or by a deployment key from 'solution deploy list' / 'solution deploy upgrade': operation, activation status, and what is left to do before it runs. Also takes the pipeline deployment ID from 'solution deploy run' for that run's progress and errors.").argument("<deployment>", "Deployment name (preferred). A deployment key from 'solution deploy list' / 'solution deploy upgrade', or the pipeline deployment ID from 'solution deploy run', works as well. A key is resolved through the Pipelines deployment lookup, which spans every feed and answers a superseded key with the deployment's current record.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).addOption(new Option("--feed <name-or-key>", "For a deployment name: the feed to look it up in (name or folder key, from 'solution feeds list'). For a key: read only on a server without the Pipelines by-key lookup, whose read is feed-scoped; the lookup itself spans every feed and answers the key wherever it lives. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace")).option("--personal-workspace", "For a deployment name: look it up in your Personal Workspace feed instead of the tenant. For a key: read only on a server without the Pipelines by-key lookup; the lookup itself spans every feed.").examples(SOLUTION_DEPLOY_STATUS_EXAMPLES).trackedAction(processContext, async (deployment, options) => {
|
|
1399
1570
|
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
1400
1571
|
tenant: options.tenant,
|
|
1401
1572
|
loginValidity: options.loginValidity
|
|
@@ -1409,20 +1580,106 @@ var registerDeployStatusCommand = (program) => {
|
|
|
1409
1580
|
processContext.exit(1);
|
|
1410
1581
|
return;
|
|
1411
1582
|
}
|
|
1583
|
+
const { feedScopeInitOverride: feedScopeInitOverride2 } = await import("./feed-resolver-31gcvnnk.js");
|
|
1584
|
+
const { FeedReadRefusedError, feedReadRefusalForApplication } = await import("./feed-session-sxga31vn.js");
|
|
1585
|
+
const refuseFeed = (action) => {
|
|
1586
|
+
const refusal = feedReadRefusalForApplication(auth, action);
|
|
1587
|
+
if (!refusal) {
|
|
1588
|
+
return false;
|
|
1589
|
+
}
|
|
1590
|
+
OutputFormatter.error({
|
|
1591
|
+
Result: RESULTS.Failure,
|
|
1592
|
+
Message: refusal.message,
|
|
1593
|
+
Instructions: refusal.instructions,
|
|
1594
|
+
ErrorCode: "permission_denied",
|
|
1595
|
+
Retry: "RetryWillNotFix"
|
|
1596
|
+
});
|
|
1597
|
+
processContext.exit(1);
|
|
1598
|
+
return true;
|
|
1599
|
+
};
|
|
1600
|
+
if (options.personalWorkspace === true && refuseFeed("Reading a Personal Workspace deployment")) {
|
|
1601
|
+
return;
|
|
1602
|
+
}
|
|
1603
|
+
const { resolveFeedScopeOrFailureAsync: resolveFeedScopeOrFailureAsync2 } = await import("./feed-scope-failure-fwtdvvrh.js");
|
|
1604
|
+
const [scopeFailure, feedScope] = await resolveFeedScopeOrFailureAsync2(options, auth);
|
|
1605
|
+
if (scopeFailure) {
|
|
1606
|
+
OutputFormatter.error(scopeFailure);
|
|
1607
|
+
processContext.exit(1);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
const { describeDeploymentAsync, looksLikeDeploymentKey } = await import("./deploy-status-service-cqfrvxpz.js");
|
|
1611
|
+
if (feedScope.kind !== "tenant" && !looksLikeDeploymentKey(deployment) && refuseFeed(`Reading a deployment in the feed '${feedScope.name ?? feedScope.folderKey}'`)) {
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
const feedSelected = options.personalWorkspace === true || options.feed !== undefined;
|
|
1615
|
+
const describe = () => describeDeploymentAsync(auth, deployment, {
|
|
1616
|
+
selectedFeed: feedSelected ? feedScope : undefined,
|
|
1617
|
+
locate: {
|
|
1618
|
+
tenant: options.tenant,
|
|
1619
|
+
loginValidity: options.loginValidity
|
|
1620
|
+
}
|
|
1621
|
+
});
|
|
1622
|
+
if (!looksLikeDeploymentKey(deployment)) {
|
|
1623
|
+
const [stateError, state] = await catchError(describe());
|
|
1624
|
+
if (stateError) {
|
|
1625
|
+
await reportStateError(deployment, stateError);
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
if (!state) {
|
|
1629
|
+
OutputFormatter.error({
|
|
1630
|
+
Result: RESULTS.Failure,
|
|
1631
|
+
Message: `Deployment '${deployment}' was not found.`,
|
|
1632
|
+
Instructions: "No deployment of that name is visible in the feeds this session can reach. Run 'uip solution deploy list' to see the names; add --personal-workspace or --feed <name-or-key> for a feed outside the tenant."
|
|
1633
|
+
});
|
|
1634
|
+
processContext.exit(1);
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
OutputFormatter.success({
|
|
1638
|
+
Result: RESULTS.Success,
|
|
1639
|
+
Code: "SolutionDeployment",
|
|
1640
|
+
Data: deploymentStateData(state)
|
|
1641
|
+
});
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1412
1644
|
const configuration = new Configuration({
|
|
1413
1645
|
basePath: auth.basePath,
|
|
1414
1646
|
accessToken: auth.accessToken
|
|
1415
1647
|
});
|
|
1416
1648
|
const api = new PipelinesApi(configuration);
|
|
1417
|
-
const [statusError, result] = await catchError(api.pipelinesGetPipelineDeploymentStatus({
|
|
1418
|
-
pipelineDeploymentId
|
|
1419
|
-
}));
|
|
1649
|
+
const [statusError, result] = await catchError(api.pipelinesGetPipelineDeploymentStatus({ pipelineDeploymentId: deployment }, feedSelected ? feedScopeInitOverride2(feedScope) : undefined));
|
|
1420
1650
|
if (statusError) {
|
|
1651
|
+
const { isPipelineDeploymentNotFoundError } = await import("./deployment-search-j34w33b2.js");
|
|
1652
|
+
if (await isPipelineDeploymentNotFoundError(statusError)) {
|
|
1653
|
+
const [stateError, state] = await catchError(describe());
|
|
1654
|
+
if (stateError instanceof FeedReadRefusedError) {
|
|
1655
|
+
OutputFormatter.error({
|
|
1656
|
+
Result: RESULTS.Failure,
|
|
1657
|
+
Message: stateError.refusal.message,
|
|
1658
|
+
Instructions: stateError.refusal.instructions,
|
|
1659
|
+
ErrorCode: "permission_denied",
|
|
1660
|
+
Retry: "RetryWillNotFix"
|
|
1661
|
+
});
|
|
1662
|
+
processContext.exit(1);
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
if (stateError) {
|
|
1666
|
+
await reportStateError(deployment, stateError);
|
|
1667
|
+
return;
|
|
1668
|
+
}
|
|
1669
|
+
if (state) {
|
|
1670
|
+
OutputFormatter.success({
|
|
1671
|
+
Result: RESULTS.Success,
|
|
1672
|
+
Code: "SolutionDeployment",
|
|
1673
|
+
Data: deploymentStateData(state)
|
|
1674
|
+
});
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1421
1678
|
const { message, details } = await extractErrorDetails(statusError);
|
|
1422
1679
|
OutputFormatter.error({
|
|
1423
1680
|
Result: RESULTS.Failure,
|
|
1424
1681
|
Message: message,
|
|
1425
|
-
Instructions: `Check the pipeline deployment ID
|
|
1682
|
+
Instructions: `Check the pipeline deployment ID (from 'deploy run' output) or the deployment key (from 'deploy list' / 'deploy upgrade'); a deployment name works too. A deployment outside the tenant feed needs --personal-workspace or --feed. Details: ${details}`
|
|
1426
1683
|
});
|
|
1427
1684
|
processContext.exit(1);
|
|
1428
1685
|
return;
|
|
@@ -1433,7 +1690,7 @@ var registerDeployStatusCommand = (program) => {
|
|
|
1433
1690
|
Result: RESULTS.Success,
|
|
1434
1691
|
Code: "SolutionDeployStatus",
|
|
1435
1692
|
Data: {
|
|
1436
|
-
PipelineDeploymentId:
|
|
1693
|
+
PipelineDeploymentId: deployment,
|
|
1437
1694
|
Status: result.status,
|
|
1438
1695
|
DeploymentKey: result.deploymentKey,
|
|
1439
1696
|
ConfigurationKey: result.configurationKey,
|
|
@@ -1451,6 +1708,44 @@ var registerDeployStatusCommand = (program) => {
|
|
|
1451
1708
|
});
|
|
1452
1709
|
});
|
|
1453
1710
|
};
|
|
1711
|
+
async function reportStateError(deployment, stateError) {
|
|
1712
|
+
const { message, details } = await extractErrorDetails(stateError);
|
|
1713
|
+
OutputFormatter.error({
|
|
1714
|
+
Result: RESULTS.Failure,
|
|
1715
|
+
Message: message,
|
|
1716
|
+
Instructions: carriedInstructions(stateError) ?? `The deployments service could not read deployment '${deployment}'. Details: ${details}`,
|
|
1717
|
+
ErrorCode: carriedErrorCode(stateError),
|
|
1718
|
+
Retry: carriedRetry(stateError)
|
|
1719
|
+
});
|
|
1720
|
+
processContext.exit(1);
|
|
1721
|
+
}
|
|
1722
|
+
function deploymentStateData(state) {
|
|
1723
|
+
const { current } = state;
|
|
1724
|
+
return {
|
|
1725
|
+
DeploymentKey: state.requestedKey,
|
|
1726
|
+
Superseded: state.superseded,
|
|
1727
|
+
CurrentDeploymentKey: current.key,
|
|
1728
|
+
InstallDeploymentKey: current.installDeploymentKey,
|
|
1729
|
+
Name: current.name,
|
|
1730
|
+
PackageName: current.packageName,
|
|
1731
|
+
PackageVersion: current.currentPackageVersion ?? current.packageVersion,
|
|
1732
|
+
NewPackageVersionAvailable: current.newPackageVersionAvailable ?? null,
|
|
1733
|
+
Operation: current.operation,
|
|
1734
|
+
OperationStatus: current.operationStatus,
|
|
1735
|
+
DeploymentStatus: current.deploymentStatus ?? null,
|
|
1736
|
+
ActivationStatus: current.activationStatus ?? null,
|
|
1737
|
+
Actions: current.actions ?? null,
|
|
1738
|
+
...state.pendingResources ? {
|
|
1739
|
+
PendingResources: state.pendingResources.map((resource) => ({
|
|
1740
|
+
Kind: resource.kind,
|
|
1741
|
+
Name: resource.name,
|
|
1742
|
+
Type: resource.type ?? null,
|
|
1743
|
+
Reason: resource.reason ?? null
|
|
1744
|
+
}))
|
|
1745
|
+
} : {},
|
|
1746
|
+
...state.nextSteps ? { NextSteps: state.nextSteps } : {}
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1454
1749
|
|
|
1455
1750
|
// src/commands/deploy-uninstall.ts
|
|
1456
1751
|
var SOLUTION_DEPLOY_UNINSTALL_EXAMPLES = [
|
|
@@ -1528,50 +1823,147 @@ var registerDeployUninstallCommand = (program) => {
|
|
|
1528
1823
|
// src/commands/deploy-upgrade.ts
|
|
1529
1824
|
var SOLUTION_DEPLOY_UPGRADE_EXAMPLES = [
|
|
1530
1825
|
{
|
|
1531
|
-
Description: "Upgrade a deployment to the newest published version",
|
|
1532
|
-
Command: "uip solution deploy upgrade
|
|
1826
|
+
Description: "Upgrade a deployment by its key to the newest published version (name, package and feed are read from the deployment)",
|
|
1827
|
+
Command: "uip solution deploy upgrade c3d4e5f6-0000-0000-0000-000000000003",
|
|
1533
1828
|
Output: {
|
|
1534
1829
|
Code: "SolutionDeployUpgrade",
|
|
1535
1830
|
Data: {
|
|
1536
|
-
Status: "
|
|
1537
|
-
|
|
1538
|
-
|
|
1831
|
+
Status: "DeploymentSucceeded",
|
|
1832
|
+
Operation: "VersionChange",
|
|
1833
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1834
|
+
Actions: ["Uninstall", "Upgrade"],
|
|
1835
|
+
DeploymentName: "my-deployment",
|
|
1836
|
+
FromVersion: "1.5.0",
|
|
1837
|
+
ToVersion: "2.0.0",
|
|
1838
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000002",
|
|
1839
|
+
DeploymentKey: "d4e5f6a7-0000-0000-0000-000000000004",
|
|
1840
|
+
InstallDeploymentKey: "c3d4e5f6-0000-0000-0000-000000000003"
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
Description: "An upgrade that succeeded but is not live: a resource needs setup before activation",
|
|
1846
|
+
Command: "uip solution deploy upgrade c3d4e5f6-0000-0000-0000-000000000003",
|
|
1847
|
+
Output: {
|
|
1848
|
+
Code: "SolutionDeployUpgrade",
|
|
1849
|
+
Data: {
|
|
1850
|
+
Status: "DeploymentSucceeded",
|
|
1851
|
+
Operation: "VersionChange",
|
|
1852
|
+
DeploymentStatus: "SuccessfulInstall",
|
|
1853
|
+
Actions: ["SetupActivation", "Uninstall", "Upgrade"],
|
|
1854
|
+
ActivationStatus: "NeedsSetupToActivate",
|
|
1855
|
+
PendingResources: [
|
|
1856
|
+
{
|
|
1857
|
+
Kind: "connection",
|
|
1858
|
+
Name: "Outlook",
|
|
1859
|
+
Type: "uipath-microsoft-outlook365",
|
|
1860
|
+
Reason: "[CNS1072] You will need to authenticate this connection before proceeding further"
|
|
1861
|
+
}
|
|
1862
|
+
],
|
|
1863
|
+
NextSteps: [
|
|
1864
|
+
"Deployment 'my-deployment' is installed at version 2.0.0 but not live: it needs 'Setup activation' before it can be activated.",
|
|
1865
|
+
"Resources that need configuration: connection 'Outlook' (uipath-microsoft-outlook365): [CNS1072] You will need to authenticate this connection before proceeding further."
|
|
1866
|
+
],
|
|
1867
|
+
DeploymentName: "my-deployment",
|
|
1868
|
+
FromVersion: "1.5.0",
|
|
1869
|
+
ToVersion: "2.0.0",
|
|
1870
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000002",
|
|
1871
|
+
DeploymentKey: "d4e5f6a7-0000-0000-0000-000000000004",
|
|
1872
|
+
InstallDeploymentKey: "c3d4e5f6-0000-0000-0000-000000000003"
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
Description: "Upgrade a deployment by name to the newest published version",
|
|
1878
|
+
Command: "uip solution deploy upgrade --name my-deployment --package-name my-package",
|
|
1879
|
+
Output: {
|
|
1880
|
+
Code: "SolutionDeployUpgrade",
|
|
1881
|
+
Data: {
|
|
1882
|
+
Status: "DeploymentSucceeded",
|
|
1883
|
+
Operation: "VersionChange",
|
|
1884
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1885
|
+
Actions: ["Uninstall", "Upgrade"],
|
|
1886
|
+
DeploymentName: "my-deployment",
|
|
1539
1887
|
ToVersion: "2.0.0",
|
|
1540
|
-
|
|
1888
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000002",
|
|
1889
|
+
DeploymentKey: "c3d4e5f6-0000-0000-0000-000000000003"
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1893
|
+
{
|
|
1894
|
+
Description: "Upgrade to a specific published version (the CI/CD form: no version lookup, one existence check and the install)",
|
|
1895
|
+
Command: "uip solution deploy upgrade --name my-deployment --package-name my-package --version 1.5.0",
|
|
1896
|
+
Output: {
|
|
1897
|
+
Code: "SolutionDeployUpgrade",
|
|
1898
|
+
Data: {
|
|
1899
|
+
Status: "DeploymentSucceeded",
|
|
1900
|
+
Operation: "VersionChange",
|
|
1901
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1902
|
+
Actions: ["Uninstall", "Upgrade"],
|
|
1903
|
+
DeploymentName: "my-deployment",
|
|
1904
|
+
ToVersion: "1.5.0",
|
|
1905
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000002",
|
|
1906
|
+
DeploymentKey: "c3d4e5f6-0000-0000-0000-000000000003"
|
|
1541
1907
|
}
|
|
1542
1908
|
}
|
|
1543
1909
|
},
|
|
1544
1910
|
{
|
|
1545
1911
|
Description: "Start the upgrade without waiting for it to finish",
|
|
1546
|
-
Command: "uip solution deploy upgrade
|
|
1912
|
+
Command: "uip solution deploy upgrade --name my-deployment --package-name my-package --no-wait",
|
|
1547
1913
|
Output: {
|
|
1548
1914
|
Code: "SolutionDeployUpgrade",
|
|
1549
1915
|
Data: {
|
|
1550
|
-
Status: "
|
|
1551
|
-
DeploymentName: "
|
|
1552
|
-
FromVersion: "1.0.0",
|
|
1916
|
+
Status: "Accepted",
|
|
1917
|
+
DeploymentName: "my-deployment",
|
|
1553
1918
|
ToVersion: "2.0.0",
|
|
1554
|
-
|
|
1919
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000002"
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
Description: "Discard the pending draft an earlier, rejected attempt left behind, then upgrade the live version",
|
|
1925
|
+
Command: "uip solution deploy upgrade c3d4e5f6-0000-0000-0000-000000000003 --version 2.0.0 --discard-draft",
|
|
1926
|
+
Output: {
|
|
1927
|
+
Code: "SolutionDeployUpgrade",
|
|
1928
|
+
Data: {
|
|
1929
|
+
Status: "DeploymentSucceeded",
|
|
1930
|
+
Operation: "VersionChange",
|
|
1931
|
+
DeploymentStatus: "SuccessfulActivate",
|
|
1932
|
+
Actions: ["Uninstall", "Upgrade"],
|
|
1933
|
+
DeploymentName: "my-deployment",
|
|
1934
|
+
FromVersion: "1.5.0",
|
|
1935
|
+
ToVersion: "2.0.0",
|
|
1936
|
+
PipelineDeploymentId: "b2c3d4e5-0000-0000-0000-000000000005",
|
|
1937
|
+
DeploymentKey: "d4e5f6a7-0000-0000-0000-000000000006",
|
|
1938
|
+
InstallDeploymentKey: "c3d4e5f6-0000-0000-0000-000000000003",
|
|
1939
|
+
DiscardedDraftKey: "e5f6a7b8-0000-0000-0000-000000000007"
|
|
1555
1940
|
}
|
|
1556
1941
|
}
|
|
1557
1942
|
}
|
|
1558
1943
|
];
|
|
1559
1944
|
var registerDeployUpgradeCommand = (program) => {
|
|
1560
|
-
program.command("upgrade").description("Upgrade an existing deployment to
|
|
1561
|
-
const result = await upgradeDeploymentAsync(
|
|
1945
|
+
program.command("upgrade").description("Upgrade an existing deployment to another published version of its package in place — the CLI equivalent of the Orchestrator UI 'Upgrade' button. Use this when 'deploy run' is blocked because a deployment already exists. The deployment's existing configuration is preserved, so values already set on it (for example a credential asset's secret) are not reset to the package defaults. The package is validated against the target before anything is installed; a validation failure reports the errors and leaves the deployment on its current version. Address the deployment either by key (positional) or by --name with --package-name. Every call this command makes is an external-app (client-credentials) capable Pipelines endpoint, so both forms work from a CI/CD pipeline (on a server that predates the Pipelines deployment lookup, the key form falls back to the Solutions API for a user session); a deployment in a Personal Workspace or folder feed needs a user session, because the server ignores the feed header on client-credentials requests. Waits for the upgrade to finish unless --no-wait is passed; track a running upgrade with 'deploy status <pipeline-deployment-id>'.").argument("[deployment-key]", "Key of the deployment to upgrade, as 'solution deploy list' reports it (Key), or a stored InstallDeploymentKey. Resolved through the Pipelines deployment lookup: the deployment's name, package, current version and feed come from the server, so --package-name and --personal-workspace are not needed. On a server without that lookup, a user session reads the key through the Solutions API instead, where a Personal Workspace deployment needs --personal-workspace. Use either this or --name with --package-name.").option("-n, --name <deployment-name>", "Name of the deployment to upgrade, as reported by 'solution deploy list'. Goes with --package-name. The name is checked to exist first, because the install route would create a new deployment for a name it cannot find; this form never does.").option("--package-name <name>", "The deployment's package, for the --name form. Required there: it identifies the package version to install, and nothing name-keyed in Pipelines reports it.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--version <version>", "Target package version (default: the newest published). Any published version of the same package is accepted, including an older one.").option("--personal-workspace", "With --name: upgrade a deployment in your Personal Workspace feed instead of the tenant. With a key the feed is read from the deployment itself and this flag is not needed, except on a server without the Pipelines deployment lookup, where a key is read on the tenant feed unless you pass it.").option("--discard-draft", "When the deployment has a pending draft (an earlier attempt that never completed, usually one rejected by validation), discard it first and upgrade the live version. Without it such a deployment is refused, because the server would re-run the draft, with the configuration it was rejected for, in place of this upgrade. With --name the draft is found through a user session only; under an external app, pass the deployment key.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("--no-wait", "Return as soon as the upgrade is accepted instead of waiting for it to finish.").option("--timeout <seconds>", "Seconds to wait for the upgrade to finish (default: 300)", (v) => parseInt(v, 10), 300).option("--poll-interval <ms>", "Milliseconds between status polls (default: 5000)", (v) => parseInt(v, 10), 5000).examples(SOLUTION_DEPLOY_UPGRADE_EXAMPLES).trackedAction(processContext, async (deploymentKey, options) => {
|
|
1946
|
+
const result = await upgradeDeploymentAsync({
|
|
1947
|
+
deploymentKey,
|
|
1948
|
+
deploymentName: options.name,
|
|
1949
|
+
packageName: options.packageName,
|
|
1562
1950
|
tenant: options.tenant,
|
|
1563
1951
|
version: options.version,
|
|
1564
1952
|
personalWorkspace: options.personalWorkspace,
|
|
1953
|
+
discardDraft: options.discardDraft,
|
|
1565
1954
|
loginValidity: options.loginValidity,
|
|
1566
1955
|
noWait: options.wait === false,
|
|
1567
1956
|
timeout: options.timeout,
|
|
1568
|
-
pollInterval: options.pollInterval
|
|
1957
|
+
pollInterval: options.pollInterval,
|
|
1958
|
+
signal: processContext.pollSignal
|
|
1569
1959
|
});
|
|
1570
1960
|
if (!result.ok) {
|
|
1571
1961
|
OutputFormatter.error({
|
|
1572
1962
|
Result: RESULTS.Failure,
|
|
1573
1963
|
Message: result.message,
|
|
1574
|
-
Instructions: result.instructions
|
|
1964
|
+
Instructions: result.instructions,
|
|
1965
|
+
ErrorCode: result.errorCode,
|
|
1966
|
+
Retry: result.retry
|
|
1575
1967
|
});
|
|
1576
1968
|
processContext.exit(result.exitCode);
|
|
1577
1969
|
return;
|
|
@@ -1581,10 +1973,26 @@ var registerDeployUpgradeCommand = (program) => {
|
|
|
1581
1973
|
Code: "SolutionDeployUpgrade",
|
|
1582
1974
|
Data: {
|
|
1583
1975
|
Status: result.status,
|
|
1976
|
+
Operation: result.operation,
|
|
1977
|
+
DeploymentStatus: result.deploymentStatus,
|
|
1978
|
+
Actions: result.actions,
|
|
1979
|
+
ActivationStatus: result.activationStatus,
|
|
1980
|
+
...result.pendingResources ? {
|
|
1981
|
+
PendingResources: result.pendingResources.map((resource) => ({
|
|
1982
|
+
Kind: resource.kind,
|
|
1983
|
+
Name: resource.name,
|
|
1984
|
+
Type: resource.type ?? null,
|
|
1985
|
+
Reason: resource.reason ?? null
|
|
1986
|
+
}))
|
|
1987
|
+
} : {},
|
|
1988
|
+
...result.nextSteps ? { NextSteps: result.nextSteps } : {},
|
|
1584
1989
|
DeploymentName: result.deploymentName,
|
|
1585
1990
|
FromVersion: result.fromVersion,
|
|
1586
1991
|
ToVersion: result.toVersion,
|
|
1587
|
-
|
|
1992
|
+
PipelineDeploymentId: result.pipelineDeploymentId,
|
|
1993
|
+
DeploymentKey: result.deploymentKey,
|
|
1994
|
+
InstallDeploymentKey: result.installDeploymentKey,
|
|
1995
|
+
DiscardedDraftKey: result.discardedDraftKey
|
|
1588
1996
|
}
|
|
1589
1997
|
});
|
|
1590
1998
|
});
|
|
@@ -1592,12 +2000,13 @@ var registerDeployUpgradeCommand = (program) => {
|
|
|
1592
2000
|
|
|
1593
2001
|
// src/commands/deploy.ts
|
|
1594
2002
|
var registerDeployCommand = (program) => {
|
|
1595
|
-
const deploy = program.command("deploy").description("Deploy, activate, uninstall, and monitor solution deployments. Typical workflow: run -> check status -> (optionally) activate -> uninstall.");
|
|
2003
|
+
const deploy = program.command("deploy").description("Deploy, activate, uninstall, and monitor solution deployments. Typical workflow: run -> check status -> (optionally) activate -> uninstall -> delete.");
|
|
1596
2004
|
registerDeployRunCommand(deploy);
|
|
1597
2005
|
registerDeployStatusCommand(deploy);
|
|
1598
2006
|
registerDeployConfigCommand(deploy);
|
|
1599
2007
|
registerDeployActivateCommand(deploy);
|
|
1600
2008
|
registerDeployUninstallCommand(deploy);
|
|
2009
|
+
registerDeployDeleteCommand(deploy);
|
|
1601
2010
|
registerDeployListCommand(deploy);
|
|
1602
2011
|
registerDeployUpgradeCommand(deploy);
|
|
1603
2012
|
};
|
|
@@ -2043,7 +2452,7 @@ var SOLUTION_PACK_EXAMPLES = [
|
|
|
2043
2452
|
}
|
|
2044
2453
|
];
|
|
2045
2454
|
var registerPackCommand = (program) => {
|
|
2046
|
-
const command = program.command("pack").description("Pack a UiPath solution into a deployable .zip package. Accepts a solution directory (containing .uipx) or a .uis file. Output is used with 'solution publish' to upload to UiPath. Pass --dry-run to check that the solution packs without producing a package.").argument("<solutionPath>", "Path to a solution directory (containing .uipx) or a .uis file").argument("[output-path]", "Output directory where the packed solution will be saved. Required unless --dry-run is set.").option("-n, --name <name>", "Package name (default: solution folder name or .uis file name)").option("-v, --version <version>", "Package version (default: 1.0.0)", "1.0.0").addOption(new Option("--solution-type <type>", "What kind of solution this is. Omitted by default, which means a standard solution.").choices(["standard", "vertical"]).hideHelp()).option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--signing-certificate-path <path>", "Path to .pfx certificate file used to sign each packed project .nupkg").option("--signing-certificate-password <password>", "Certificate password. Use env.ENV_NAME to read from an environment variable.").option("--signing-timestamp-server <url>", "Timestamp server URL").option("--skip-analyze", "Skip the workflow analyzer for every RPA project in the solution. Compilation and validation still run.").option("--governance-file-path <path>", "Analyze every RPA project against this local governance policy file, instead of the analyzer rules shipped with the WorkflowCompiler. When you are signed in the tenant is asked first — about StudioWeb unless --governance-product names another product — and
|
|
2455
|
+
const command = program.command("pack").description("Pack a UiPath solution into a deployable .zip package. Accepts a solution directory (containing .uipx) or a .uis file. Output is used with 'solution publish' to upload to UiPath. Pass --dry-run to check that the solution packs without producing a package.").argument("<solutionPath>", "Path to a solution directory (containing .uipx) or a .uis file").argument("[output-path]", "Output directory where the packed solution will be saved. Required unless --dry-run is set.").option("-n, --name <name>", "Package name (default: solution folder name or .uis file name)").option("-v, --version <version>", "Package version (default: 1.0.0)", "1.0.0").addOption(new Option("--solution-type <type>", "What kind of solution this is. Omitted by default, which means a standard solution.").choices(["standard", "vertical"]).hideHelp()).option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--signing-certificate-path <path>", "Path to .pfx certificate file used to sign each packed project .nupkg").option("--signing-certificate-password <password>", "Certificate password. Use env.ENV_NAME to read from an environment variable.").option("--signing-timestamp-server <url>", "Timestamp server URL").option("--skip-analyze", "Skip the workflow analyzer for every RPA project in the solution. Compilation and validation still run.").option("--governance-file-path <path>", "Analyze every RPA project against this local governance policy file, instead of the analyzer rules shipped with the WorkflowCompiler. When you are signed in the tenant is asked first — about StudioWeb unless --governance-product names another product — and when the tenant publishes a policy of its own, that policy is used instead and this file is ignored with a warning.").option("--governance-product <product>", "Analyze every RPA project against the governance policy published in AutomationOps for the signed-in tenant. The value is the product whose policy is downloaded, e.g. StudioWeb, Development, Business.").addOption(new Option("--automation-ops-profile <profile>").hideHelp());
|
|
2047
2456
|
registerPackageMetadataOptions(command).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("--dry-run", "Run the full pack pipeline against a temporary directory and discard the output. Catches pack-time failures; does not inspect the produced package contents.").examples(SOLUTION_PACK_EXAMPLES).trackedAction(processContext, async (solutionPath, outputPath, options) => {
|
|
2048
2457
|
if (!options.dryRun && outputPath === undefined) {
|
|
2049
2458
|
OutputFormatter.error({
|
|
@@ -2122,16 +2531,6 @@ var SOLUTION_PACKAGES_DELETE_EXAMPLES = [
|
|
|
2122
2531
|
}
|
|
2123
2532
|
}
|
|
2124
2533
|
];
|
|
2125
|
-
var SEARCH_PAGE_SIZE = 50;
|
|
2126
|
-
function scopeName(scope) {
|
|
2127
|
-
if (scope.kind === "tenant") {
|
|
2128
|
-
return "the tenant feed";
|
|
2129
|
-
}
|
|
2130
|
-
if (scope.name) {
|
|
2131
|
-
return `'${scope.name}'`;
|
|
2132
|
-
}
|
|
2133
|
-
return scope.kind === "personal" ? "the Personal Workspace feed" : "the selected feed";
|
|
2134
|
-
}
|
|
2135
2534
|
function packageDeleteFailureInstructions(scope, packageName) {
|
|
2136
2535
|
const base = "Check that the package name and version are correct and that you have permission to delete it.";
|
|
2137
2536
|
if (scope.kind === "personal") {
|
|
@@ -2142,70 +2541,12 @@ function packageDeleteFailureInstructions(scope, packageName) {
|
|
|
2142
2541
|
}
|
|
2143
2542
|
return `${base} If the package was published to a Personal Workspace or folder feed, add --personal-workspace or --feed.`;
|
|
2144
2543
|
}
|
|
2145
|
-
async function
|
|
2146
|
-
const config = new Configuration2({
|
|
2147
|
-
basePath: auth.basePath,
|
|
2148
|
-
accessToken: auth.accessToken
|
|
2149
|
-
});
|
|
2150
|
-
const searchApi = new SearchApi(config);
|
|
2151
|
-
const pkg = await findPackage(searchApi, scope, packageName);
|
|
2152
|
-
if (pkg.latestVersion === packageVersion) {
|
|
2153
|
-
return pkg.packageVersionKey;
|
|
2154
|
-
}
|
|
2155
|
-
for (let skip = 0;; ) {
|
|
2156
|
-
const page = await searchPackageVersions({ basePath: auth.basePath, accessToken: auth.accessToken }, pkg.key, {
|
|
2157
|
-
searchTerm: packageVersion,
|
|
2158
|
-
take: SEARCH_PAGE_SIZE,
|
|
2159
|
-
skip,
|
|
2160
|
-
excludeInvalidPackages: true
|
|
2161
|
-
}, scope.folderKey);
|
|
2162
|
-
const match = page.values.find((version) => version.version === packageVersion);
|
|
2163
|
-
if (match) {
|
|
2164
|
-
return match.key;
|
|
2165
|
-
}
|
|
2166
|
-
if (page.values.length < SEARCH_PAGE_SIZE) {
|
|
2167
|
-
throw new Error(`Package version '${packageName}@${packageVersion}' was not found in ${scopeName(scope)}.`);
|
|
2168
|
-
}
|
|
2169
|
-
skip += page.values.length;
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
async function findPackage(searchApi, scope, packageName) {
|
|
2173
|
-
for (let skip = 0;; ) {
|
|
2174
|
-
const packages = await searchApi.searchSearchPackages({
|
|
2175
|
-
searchFilter: {
|
|
2176
|
-
searchTerm: packageName,
|
|
2177
|
-
take: SEARCH_PAGE_SIZE,
|
|
2178
|
-
skip
|
|
2179
|
-
}
|
|
2180
|
-
}, feedScopeInitOverride(scope));
|
|
2181
|
-
const values = packages.values ?? [];
|
|
2182
|
-
const match = values.find((pkg) => pkg.name === packageName);
|
|
2183
|
-
if (match) {
|
|
2184
|
-
return match;
|
|
2185
|
-
}
|
|
2186
|
-
if (values.length < SEARCH_PAGE_SIZE) {
|
|
2187
|
-
throw new Error(`Package '${packageName}' was not found in ${scopeName(scope)}.`);
|
|
2188
|
-
}
|
|
2189
|
-
skip += values.length;
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
async function deleteTenantPackageVersion(auth, packageName, packageVersion) {
|
|
2544
|
+
async function deletePackageVersion(auth, scope, packageName, packageVersion) {
|
|
2193
2545
|
const api = new PipelinesApi(new Configuration({
|
|
2194
2546
|
basePath: auth.basePath,
|
|
2195
2547
|
accessToken: auth.accessToken
|
|
2196
2548
|
}));
|
|
2197
|
-
await api.pipelinesPackageDelete({
|
|
2198
|
-
packageName,
|
|
2199
|
-
packageVersion
|
|
2200
|
-
});
|
|
2201
|
-
}
|
|
2202
|
-
async function deleteScopedPackageVersion(auth, scope, packageName, packageVersion) {
|
|
2203
|
-
const packageVersionKey = await resolvePackageVersionKey(auth, scope, packageName, packageVersion);
|
|
2204
|
-
const packagesApi = new PackagesApi(new Configuration2({
|
|
2205
|
-
basePath: auth.basePath,
|
|
2206
|
-
accessToken: auth.accessToken
|
|
2207
|
-
}));
|
|
2208
|
-
await packagesApi.packagesDeleteVersion({ packageVersionKey }, feedScopeInitOverride(scope));
|
|
2549
|
+
await api.pipelinesPackageDelete({ packageName, packageVersion }, feedScopeInitOverride(scope));
|
|
2209
2550
|
}
|
|
2210
2551
|
var registerPackagesDeleteCommand = (program) => {
|
|
2211
2552
|
const command = program.command("delete").description("Delete a specific version of a solution package. " + "Use 'solution packages list' to find available package names and versions.").argument("<package-name>", "The name of the package").argument("<package-version>", "The version to delete (e.g. 1.0.0)").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").option("--personal-workspace", "Delete the package version from the current user's Personal Workspace feed.");
|
|
@@ -2227,22 +2568,13 @@ var registerPackagesDeleteCommand = (program) => {
|
|
|
2227
2568
|
processContext.exit(1);
|
|
2228
2569
|
return;
|
|
2229
2570
|
}
|
|
2230
|
-
const [
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
tenant: options.tenant,
|
|
2234
|
-
loginValidity: options.loginValidity
|
|
2235
|
-
}));
|
|
2236
|
-
if (scopeError) {
|
|
2237
|
-
OutputFormatter.error({
|
|
2238
|
-
Result: RESULTS.Failure,
|
|
2239
|
-
Message: scopeError.message,
|
|
2240
|
-
Instructions: feedResolutionFailureInstructions(options)
|
|
2241
|
-
});
|
|
2571
|
+
const [scopeFailure, scope] = await resolveFeedScopeOrFailureAsync(options, auth);
|
|
2572
|
+
if (scopeFailure) {
|
|
2573
|
+
OutputFormatter.error(scopeFailure);
|
|
2242
2574
|
processContext.exit(1);
|
|
2243
2575
|
return;
|
|
2244
2576
|
}
|
|
2245
|
-
const [deleteError] = await catchError(
|
|
2577
|
+
const [deleteError] = await catchError(deletePackageVersion(auth, scope, packageName, packageVersion));
|
|
2246
2578
|
if (deleteError) {
|
|
2247
2579
|
const { message } = await extractErrorDetails(deleteError);
|
|
2248
2580
|
OutputFormatter.error({
|
|
@@ -2461,9 +2793,9 @@ var SOLUTION_PACKAGES_LIST_EXAMPLES = [
|
|
|
2461
2793
|
Code: "SolutionPackagesList",
|
|
2462
2794
|
Data: [
|
|
2463
2795
|
{
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2796
|
+
Name: "MyPackage",
|
|
2797
|
+
LatestVersion: "1.0.0",
|
|
2798
|
+
PublishDate: "2025-04-15T10:30:00Z"
|
|
2467
2799
|
}
|
|
2468
2800
|
]
|
|
2469
2801
|
}
|
|
@@ -2488,7 +2820,10 @@ var registerPackagesListCommand = (program) => {
|
|
|
2488
2820
|
OutputFormatter.error({
|
|
2489
2821
|
Result: RESULTS.Failure,
|
|
2490
2822
|
Message: result.message,
|
|
2491
|
-
Instructions: result.instructions
|
|
2823
|
+
Instructions: result.instructions,
|
|
2824
|
+
ErrorCode: result.errorCode,
|
|
2825
|
+
Retry: result.retry,
|
|
2826
|
+
...result.context ? { Context: result.context } : {}
|
|
2492
2827
|
});
|
|
2493
2828
|
processContext.exit(result.exitCode);
|
|
2494
2829
|
return;
|
|
@@ -3129,12 +3464,12 @@ var registerProjectPublishCommand = (project) => {
|
|
|
3129
3464
|
return;
|
|
3130
3465
|
}
|
|
3131
3466
|
trackShipSucceeded({
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3467
|
+
[ShipDimensions.ShipKind]: "publish",
|
|
3468
|
+
[ShipDimensions.Target]: "solution_package_feed",
|
|
3469
|
+
[ShipDimensions.ProjectType]: "solution_project",
|
|
3470
|
+
[CommandDimensions.CommandName]: "uip solution projects publish",
|
|
3471
|
+
[ShipDimensions.PackageName]: options.packageName,
|
|
3472
|
+
[ShipDimensions.PackageVersion]: options.packageVersion
|
|
3138
3473
|
});
|
|
3139
3474
|
OutputFormatter.success({
|
|
3140
3475
|
Result: RESULTS.Success,
|
|
@@ -3529,21 +3864,21 @@ async function inspectSolutionPackageProjectTypes(packagePath) {
|
|
|
3529
3864
|
const fs = getFileSystem();
|
|
3530
3865
|
const [statError, stats] = await catchError(fs.stat(packagePath));
|
|
3531
3866
|
if (statError || !stats) {
|
|
3532
|
-
logger.debug(`[
|
|
3867
|
+
logger.debug(`[Cli.ShipSucceeded] Could not stat solution package for project type telemetry: ${statError?.message ?? "no stats"}`);
|
|
3533
3868
|
return { projectType: "unknown" };
|
|
3534
3869
|
}
|
|
3535
3870
|
if (stats.size > MAX_INSPECTABLE_PACKAGE_BYTES) {
|
|
3536
|
-
logger.debug(`[
|
|
3871
|
+
logger.debug(`[Cli.ShipSucceeded] Solution package is ${stats.size} bytes, over the ${MAX_INSPECTABLE_PACKAGE_BYTES}-byte inspection cap; skipping project type telemetry.`);
|
|
3537
3872
|
return { projectType: "unknown" };
|
|
3538
3873
|
}
|
|
3539
3874
|
const [readError, archive] = await catchError(fs.readFile(packagePath));
|
|
3540
3875
|
if (readError || !archive) {
|
|
3541
|
-
logger.debug(`[
|
|
3876
|
+
logger.debug(`[Cli.ShipSucceeded] Could not read solution package for project type telemetry: ${readError?.message ?? "empty archive"}`);
|
|
3542
3877
|
return { projectType: "unknown" };
|
|
3543
3878
|
}
|
|
3544
3879
|
const [unzipError, entries] = await catchError(unzipProjectManifests(new Uint8Array(archive)));
|
|
3545
3880
|
if (unzipError || !entries) {
|
|
3546
|
-
logger.debug(`[
|
|
3881
|
+
logger.debug(`[Cli.ShipSucceeded] Could not inspect solution package zip: ${unzipError?.message ?? "no entries"}`);
|
|
3547
3882
|
return { projectType: "unknown" };
|
|
3548
3883
|
}
|
|
3549
3884
|
const decoder = new TextDecoder;
|
|
@@ -3554,7 +3889,7 @@ async function inspectSolutionPackageProjectTypes(packagePath) {
|
|
|
3554
3889
|
}
|
|
3555
3890
|
const [parseError, parsedTypes] = await catchError(Promise.resolve().then(() => readProjectTypesFromUipx(decoder.decode(entryBytes))));
|
|
3556
3891
|
if (parseError) {
|
|
3557
|
-
logger.debug(`[
|
|
3892
|
+
logger.debug(`[Cli.ShipSucceeded] Could not parse ${entryName} for project type telemetry: ${parseError.message}`);
|
|
3558
3893
|
continue;
|
|
3559
3894
|
}
|
|
3560
3895
|
projectTypes.push(...parsedTypes);
|
|
@@ -3565,8 +3900,8 @@ function trackSolutionShipSucceeded(payload) {
|
|
|
3565
3900
|
const { projectTypeSummary, ...rest } = payload;
|
|
3566
3901
|
return trackShipSucceeded({
|
|
3567
3902
|
...rest,
|
|
3568
|
-
|
|
3569
|
-
|
|
3903
|
+
[ShipDimensions.ProjectType]: projectTypeSummary.projectType,
|
|
3904
|
+
[ShipDimensions.ProjectTypes]: projectTypeSummary.projectTypes
|
|
3570
3905
|
});
|
|
3571
3906
|
}
|
|
3572
3907
|
|
|
@@ -3716,13 +4051,13 @@ var registerPublishCommand = (program) => {
|
|
|
3716
4051
|
});
|
|
3717
4052
|
const projectTypeSummary = await inspectSolutionPackageProjectTypes(packagePath);
|
|
3718
4053
|
trackSolutionShipSucceeded({
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
4054
|
+
[ShipDimensions.ShipKind]: "publish",
|
|
4055
|
+
[ShipDimensions.Target]: result.feedKind === "personal" ? "personal_workspace_solution_feed" : result.feedKind === "folder" ? "folder_solution_feed" : "tenant_solution_feed",
|
|
4056
|
+
[CommandDimensions.CommandName]: "uip solution publish",
|
|
4057
|
+
[ShipDimensions.ArtifactCorrelationKey]: result.packageVersionKey,
|
|
4058
|
+
[ShipDimensions.PackageVersionKey]: result.packageVersionKey,
|
|
4059
|
+
[ShipDimensions.PackageName]: result.packageName,
|
|
4060
|
+
[ShipDimensions.PackageVersion]: result.packageVersion,
|
|
3726
4061
|
projectTypeSummary
|
|
3727
4062
|
});
|
|
3728
4063
|
});
|
|
@@ -3765,7 +4100,7 @@ var RESOURCE_ADD_EXAMPLES = [
|
|
|
3765
4100
|
}
|
|
3766
4101
|
];
|
|
3767
4102
|
var registerResourceAddCommand = (resource) => {
|
|
3768
|
-
resource.command("add").description("Add a resource to the solution. Use --source local to create a virtual stub, " + "or --source remote to import an existing Orchestrator resource. Idempotent: " + "if a resource with the same (kind, name, folder) already exists, it is returned unchanged.").option("--source <source>", "Resource source: local (virtual stub) or remote (import from Orchestrator)").option("--kind <kind>", "Resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Case-insensitive, matched against SDK metadata.").option("--name <name>", "Resource name").option("--type <type>", "Resource subtype (e.g. Text/Bool/
|
|
4103
|
+
resource.command("add").description("Add a resource to the solution. Use --source local to create a virtual stub, " + "or --source remote to import an existing Orchestrator resource. Idempotent: " + "if a resource with the same (kind, name, folder) already exists, it is returned unchanged.").option("--source <source>", "Resource source: local (virtual stub) or remote (import from Orchestrator)").option("--kind <kind>", "Resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Case-insensitive, matched against SDK metadata.").option("--name <name>", "Resource name").option("--type <type>", "Resource subtype, case-insensitive (e.g. Text/Integer/Bool/Credential/Secret or stringAsset/credentialAsset for Asset, connector type for Connection). Rejected when the kind does not declare it or has no subtypes (Queue); with --source remote it must match the resource's type and narrows same-name matches.").option("--folder-path <path>", "Orchestrator folder path for remote lookup. Required to disambiguate when more than one remote match exists. Not valid with --source local.").option("--cloud-key <guid>", "Skip remote search and import this exact resource key. Only valid with --source remote.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(RESOURCE_ADD_EXAMPLES).trackedAction(processContext, async (options) => {
|
|
3769
4104
|
const validation = validateOptions(options);
|
|
3770
4105
|
if (!validation.ok) {
|
|
3771
4106
|
OutputFormatter.error({
|
|
@@ -3856,6 +4191,10 @@ var registerResourceAddCommand = (resource) => {
|
|
|
3856
4191
|
OutputFormatter.error({
|
|
3857
4192
|
Result: RESULTS.Failure,
|
|
3858
4193
|
Message: outcome.message,
|
|
4194
|
+
...outcome.invalidArgument ? {
|
|
4195
|
+
ErrorCode: "invalid_argument",
|
|
4196
|
+
Retry: "RetryWillNotFix"
|
|
4197
|
+
} : {},
|
|
3859
4198
|
Instructions: outcome.instructions
|
|
3860
4199
|
});
|
|
3861
4200
|
processContext.exit(1);
|
|
@@ -3889,15 +4228,6 @@ function canonicalizeKind(kind) {
|
|
|
3889
4228
|
return trimmed;
|
|
3890
4229
|
return trimmed.charAt(0).toLowerCase() + trimmed.slice(1);
|
|
3891
4230
|
}
|
|
3892
|
-
var MAX_NAME_LENGTH = 256;
|
|
3893
|
-
var UNSAFE_NAME_CHARS = /[\\/:*?"<>|]/;
|
|
3894
|
-
function hasControlChar(s) {
|
|
3895
|
-
for (let i = 0;i < s.length; i++) {
|
|
3896
|
-
if (s.charCodeAt(i) < 32)
|
|
3897
|
-
return true;
|
|
3898
|
-
}
|
|
3899
|
-
return false;
|
|
3900
|
-
}
|
|
3901
4231
|
var GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3902
4232
|
function validateOptions(options) {
|
|
3903
4233
|
if (!options.source) {
|
|
@@ -3929,18 +4259,12 @@ function validateOptions(options) {
|
|
|
3929
4259
|
instructions: "Pass --name <resource-name>"
|
|
3930
4260
|
};
|
|
3931
4261
|
}
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
ok: false,
|
|
3935
|
-
message: `--name exceeds the ${MAX_NAME_LENGTH}-character limit (got ${options.name.length})`,
|
|
3936
|
-
instructions: "Shorten the resource name. Orchestrator name limits are kind-specific (queues cap at 50, assets at 256)."
|
|
3937
|
-
};
|
|
3938
|
-
}
|
|
3939
|
-
if (UNSAFE_NAME_CHARS.test(options.name) || hasControlChar(options.name)) {
|
|
4262
|
+
const nameCheck = validateResourceName(options.name);
|
|
4263
|
+
if (!nameCheck.ok) {
|
|
3940
4264
|
return {
|
|
3941
4265
|
ok: false,
|
|
3942
|
-
message:
|
|
3943
|
-
instructions:
|
|
4266
|
+
message: nameCheck.message,
|
|
4267
|
+
instructions: nameCheck.instructions
|
|
3944
4268
|
};
|
|
3945
4269
|
}
|
|
3946
4270
|
if (options.cloudKey && source !== "remote") {
|
|
@@ -3976,10 +4300,53 @@ function validateOptions(options) {
|
|
|
3976
4300
|
}
|
|
3977
4301
|
};
|
|
3978
4302
|
}
|
|
3979
|
-
async function
|
|
4303
|
+
async function resolveTypeInput(services, kind, type) {
|
|
4304
|
+
if (type === undefined)
|
|
4305
|
+
return { ok: true, type };
|
|
4306
|
+
const metadata = await resolveResourceKindMetadata(services, kind, type);
|
|
4307
|
+
if (metadata?.typeMatched) {
|
|
4308
|
+
return { ok: true, type: metadata.type ?? type };
|
|
4309
|
+
}
|
|
4310
|
+
const subtypes = metadata?.subtypes ?? [];
|
|
4311
|
+
const useOneOf = `Use one of: ${formatResourceSubtypes(subtypes)}. Either name works, case-insensitive.`;
|
|
4312
|
+
if (type.trim() === "") {
|
|
4313
|
+
return refuseType("--type is empty", subtypes.length > 0 ? `${useOneOf} Or drop --type.` : "Drop --type.");
|
|
4314
|
+
}
|
|
4315
|
+
if (!metadata)
|
|
4316
|
+
return { ok: true, type };
|
|
4317
|
+
return subtypes.length > 0 ? refuseType(`Unknown --type "${type}" for kind ${kind}`, useOneOf) : refuseType(`--type does not apply to kind ${kind}`, `A ${kind} has no subtypes. Drop --type.`);
|
|
4318
|
+
}
|
|
4319
|
+
function refuseType(message, instructions) {
|
|
4320
|
+
return {
|
|
4321
|
+
ok: false,
|
|
4322
|
+
outcome: {
|
|
4323
|
+
kind: "error",
|
|
4324
|
+
message,
|
|
4325
|
+
instructions,
|
|
4326
|
+
invalidArgument: true
|
|
4327
|
+
}
|
|
4328
|
+
};
|
|
4329
|
+
}
|
|
4330
|
+
function formatCandidates(matches) {
|
|
4331
|
+
return matches.map((m) => ` - Folder=${m.folder?.fullyQualifiedName ?? "<none>"} Type=${m.type ?? "<none>"} Key=${m.key}`).join(`
|
|
4332
|
+
`);
|
|
4333
|
+
}
|
|
4334
|
+
async function runAdd(builder, services, rawInput) {
|
|
4335
|
+
const typeResolution = await resolveTypeInput(services, rawInput.kind, rawInput.type);
|
|
4336
|
+
if (!typeResolution.ok)
|
|
4337
|
+
return typeResolution.outcome;
|
|
4338
|
+
const input = { ...rawInput, type: typeResolution.type };
|
|
3980
4339
|
const solution = await builder.context.loadAsync();
|
|
3981
4340
|
if (input.source === "local") {
|
|
3982
4341
|
const existing = findMatchingLocalResource(solution.resources, input.kind, input.name, input.folderPath);
|
|
4342
|
+
if (existing && input.type !== undefined && !sameResourceSubtype(existing.type, input.type)) {
|
|
4343
|
+
return {
|
|
4344
|
+
kind: "error",
|
|
4345
|
+
message: `A local ${input.kind} named ${existing.name} already exists with type ${existing.type ?? "<none>"}, not ${input.type}`,
|
|
4346
|
+
instructions: existing.type ? `Drop --type to reuse it, pass --type ${existing.type}, or pick another --name.` : "Drop --type to reuse it, or pick another --name.",
|
|
4347
|
+
invalidArgument: true
|
|
4348
|
+
};
|
|
4349
|
+
}
|
|
3983
4350
|
if (existing) {
|
|
3984
4351
|
return {
|
|
3985
4352
|
kind: "success",
|
|
@@ -4026,27 +4393,36 @@ async function runAdd(builder, services, input) {
|
|
|
4026
4393
|
instructions: searchError.message
|
|
4027
4394
|
};
|
|
4028
4395
|
}
|
|
4029
|
-
const
|
|
4030
|
-
if (
|
|
4396
|
+
const inFolder = filterMatchesByFolder(matches, input.folderPath);
|
|
4397
|
+
if (inFolder.length === 0) {
|
|
4031
4398
|
return {
|
|
4032
4399
|
kind: "error",
|
|
4033
4400
|
message: `No remote resource found matching kind=${input.kind} name=${input.name}`,
|
|
4034
4401
|
instructions: `Use 'uip solution resources list --source remote --kind ${input.kind} --search ${input.name}' to discover candidates, or pass --source local to create a local stub.`
|
|
4035
4402
|
};
|
|
4036
4403
|
}
|
|
4404
|
+
const wantedType = input.type;
|
|
4405
|
+
const filtered = wantedType === undefined ? inFolder : inFolder.filter((m) => sameResourceSubtype(m.type, wantedType));
|
|
4406
|
+
if (filtered.length === 0) {
|
|
4407
|
+
return {
|
|
4408
|
+
kind: "error",
|
|
4409
|
+
message: `No remote ${input.kind} named ${input.name} has type ${wantedType}`,
|
|
4410
|
+
instructions: `Drop --type, or pass the type of the one you want:
|
|
4411
|
+
${formatCandidates(inFolder)}`,
|
|
4412
|
+
invalidArgument: true
|
|
4413
|
+
};
|
|
4414
|
+
}
|
|
4037
4415
|
if (filtered.length > 1) {
|
|
4038
|
-
const candidates = filtered.map((m) => ` - Folder=${m.folder?.fullyQualifiedName ?? "<none>"} Type=${m.type ?? "<none>"} Key=${m.key}`).join(`
|
|
4039
|
-
`);
|
|
4040
4416
|
return {
|
|
4041
4417
|
kind: "error",
|
|
4042
4418
|
message: `Ambiguous match: ${filtered.length} remote resources matching kind=${input.kind} name=${input.name}`,
|
|
4043
|
-
instructions: `Candidates (disambiguate with --cloud-key <key>; --folder-path only
|
|
4044
|
-
${
|
|
4419
|
+
instructions: `Candidates (disambiguate with --cloud-key <key>; --folder-path and --type only help when they differ in folder or type):
|
|
4420
|
+
${formatCandidates(filtered)}`
|
|
4045
4421
|
};
|
|
4046
4422
|
}
|
|
4047
4423
|
cloudKey = filtered[0].key;
|
|
4048
4424
|
matchFolder = filtered[0].folder;
|
|
4049
|
-
resolvedType =
|
|
4425
|
+
resolvedType = filtered[0].type ?? resolvedType;
|
|
4050
4426
|
} else {
|
|
4051
4427
|
const [lookupError, match] = await catchError(findResourceByKeyInRcs(builder, input.kind, cloudKey, input.folderPath, true));
|
|
4052
4428
|
if (lookupError) {
|
|
@@ -4057,8 +4433,16 @@ ${candidates}`
|
|
|
4057
4433
|
};
|
|
4058
4434
|
}
|
|
4059
4435
|
if (match) {
|
|
4436
|
+
if (input.type !== undefined && !sameResourceSubtype(match.type, input.type)) {
|
|
4437
|
+
return {
|
|
4438
|
+
kind: "error",
|
|
4439
|
+
message: `Remote ${input.kind} ${cloudKey} has type ${match.type ?? "<none>"}, not ${input.type}`,
|
|
4440
|
+
instructions: match.type ? `Drop --type, or pass --type ${match.type}.` : "Drop --type.",
|
|
4441
|
+
invalidArgument: true
|
|
4442
|
+
};
|
|
4443
|
+
}
|
|
4060
4444
|
matchFolder = match.folder;
|
|
4061
|
-
resolvedType =
|
|
4445
|
+
resolvedType = match.type ?? resolvedType;
|
|
4062
4446
|
}
|
|
4063
4447
|
}
|
|
4064
4448
|
const existingByKey = solution.resources.find((r) => r.key.toLowerCase() === cloudKey);
|
|
@@ -4622,7 +5006,7 @@ async function getRemoteConfiguration(services, resourceKey, includeDependencies
|
|
|
4622
5006
|
if (!reference) {
|
|
4623
5007
|
throw new Error(`Resource '${resourceKey}' was not found in the solution or in the resource catalog`);
|
|
4624
5008
|
}
|
|
4625
|
-
const importer = services
|
|
5009
|
+
const { importer } = getRemoteResourceClients(services);
|
|
4626
5010
|
const payload = await importer.exportResourceAsync(reference);
|
|
4627
5011
|
const definitions = payload.resourceDefinitions ?? [];
|
|
4628
5012
|
const primary = definitions.find((d) => d.key === resourceKey) ?? definitions[0];
|
|
@@ -4660,7 +5044,7 @@ async function attachLiveSpecOnMismatchAsync(services, resource, config) {
|
|
|
4660
5044
|
if (overwriteData?.matchingOverwriteConfiguration !== false || !overwrite || !resource) {
|
|
4661
5045
|
return;
|
|
4662
5046
|
}
|
|
4663
|
-
const importer = services
|
|
5047
|
+
const { importer } = getRemoteResourceClients(services);
|
|
4664
5048
|
const [exportError, exported] = await catchError(importer.exportResourceOverwriteAsync(resource, overwrite));
|
|
4665
5049
|
if (exportError || !exported?.spec) {
|
|
4666
5050
|
return;
|
|
@@ -4690,30 +5074,8 @@ async function refreshArtefactSpecAsync(builder, data, includeDeps) {
|
|
|
4690
5074
|
return requestedResource;
|
|
4691
5075
|
}
|
|
4692
5076
|
async function findRemoteReferenceByKey(services, resourceKey) {
|
|
4693
|
-
const
|
|
4694
|
-
|
|
4695
|
-
do {
|
|
4696
|
-
const result = await rcs.searchFolderEntities({
|
|
4697
|
-
pageSize: 100,
|
|
4698
|
-
pageCursor
|
|
4699
|
-
});
|
|
4700
|
-
for (const item of result.items ?? []) {
|
|
4701
|
-
if (item.entityKey === resourceKey) {
|
|
4702
|
-
return {
|
|
4703
|
-
kind: item.entityType ?? "",
|
|
4704
|
-
type: item.entitySubType ?? undefined,
|
|
4705
|
-
key: item.entityKey ?? resourceKey,
|
|
4706
|
-
name: item.entityName ?? undefined,
|
|
4707
|
-
folder: item.fullyQualifiedName ? {
|
|
4708
|
-
fullyQualifiedName: item.fullyQualifiedName,
|
|
4709
|
-
folderKey: item.folderKey ?? undefined
|
|
4710
|
-
} : undefined
|
|
4711
|
-
};
|
|
4712
|
-
}
|
|
4713
|
-
}
|
|
4714
|
-
pageCursor = result.nextPage ?? undefined;
|
|
4715
|
-
} while (pageCursor);
|
|
4716
|
-
return null;
|
|
5077
|
+
const entity = await findCatalogEntityAsync(getRemoteResourceClients(services).catalog, {}, (item) => item.entityKey === resourceKey);
|
|
5078
|
+
return entity ? toResourceReference(entity) : null;
|
|
4717
5079
|
}
|
|
4718
5080
|
|
|
4719
5081
|
// src/services/resource-version-lookup.ts
|
|
@@ -4735,7 +5097,7 @@ async function resolveResourceVersionsAsync(services, builder, targets) {
|
|
|
4735
5097
|
if (versioned.length === 0) {
|
|
4736
5098
|
return versions;
|
|
4737
5099
|
}
|
|
4738
|
-
const importer = services
|
|
5100
|
+
const { importer } = getRemoteResourceClients(services);
|
|
4739
5101
|
for (let i = 0;i < versioned.length; i += LOOKUP_CONCURRENCY) {
|
|
4740
5102
|
const batch = versioned.slice(i, i + LOOKUP_CONCURRENCY);
|
|
4741
5103
|
const resolved = await Promise.all(batch.map((target) => target.source === "Local" ? readLocalVersionAsync(builder, target) : readRemoteVersionAsync(importer, target)));
|
|
@@ -4766,13 +5128,11 @@ async function readRemoteVersionAsync(importer, target) {
|
|
|
4766
5128
|
folderKey: target.folderKey
|
|
4767
5129
|
} : undefined
|
|
4768
5130
|
};
|
|
4769
|
-
const [error,
|
|
4770
|
-
if (error
|
|
5131
|
+
const [error, primary] = await catchError(exportResourceDefinitionAsync(importer, reference));
|
|
5132
|
+
if (error) {
|
|
4771
5133
|
warnLookupFailed(target, error);
|
|
4772
5134
|
return [target.id, undefined];
|
|
4773
5135
|
}
|
|
4774
|
-
const definitions = payload.resourceDefinitions ?? [];
|
|
4775
|
-
const primary = definitions.find((d) => d.key === target.key);
|
|
4776
5136
|
if (!primary) {
|
|
4777
5137
|
logger.warn(`Export for ${target.kind} '${target.name ?? target.key}' returned no definition for that key; version omitted.`);
|
|
4778
5138
|
return [target.id, undefined];
|
|
@@ -4780,18 +5140,7 @@ async function readRemoteVersionAsync(importer, target) {
|
|
|
4780
5140
|
return [target.id, readVersion(primary.spec)];
|
|
4781
5141
|
}
|
|
4782
5142
|
function readVersion(spec) {
|
|
4783
|
-
|
|
4784
|
-
return;
|
|
4785
|
-
}
|
|
4786
|
-
let value = spec[VERSION_PROPERTY];
|
|
4787
|
-
if (value === undefined) {
|
|
4788
|
-
for (const [key, candidate] of Object.entries(spec)) {
|
|
4789
|
-
if (key.toLowerCase() === VERSION_PROPERTY) {
|
|
4790
|
-
value = candidate;
|
|
4791
|
-
break;
|
|
4792
|
-
}
|
|
4793
|
-
}
|
|
4794
|
-
}
|
|
5143
|
+
const value = readSpecProperty(spec, VERSION_PROPERTY);
|
|
4795
5144
|
if (value === undefined || value === null || value === "") {
|
|
4796
5145
|
return;
|
|
4797
5146
|
}
|
|
@@ -4839,7 +5188,7 @@ var RESOURCE_LIST_EXAMPLES = [
|
|
|
4839
5188
|
}
|
|
4840
5189
|
];
|
|
4841
5190
|
var registerResourceListCommand = (resource) => {
|
|
4842
|
-
resource.command("list").description("List resources in the solution and/or available in Orchestrator. " + "Shows local solution resources, remote Orchestrator resources, or both.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--kind <kind>", "Filter by resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Any kind RCS indexes is accepted.").option("--search <term>", "Filter resources by name").option("--source <source>", "Resource source: all, local, or remote (default: all)", "all").option("--include-version", "Also report each resource's version, for the kinds that carry one (app, appVersion, package, process). " + "Remote rows report the version live in the folder, local rows the version the solution pins. " + "Costs one extra call per resource, so it is off by default.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(RESOURCE_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
|
|
5191
|
+
resource.command("list").description("List resources in the solution and/or available in Orchestrator. " + "Shows local solution resources, remote Orchestrator resources, or both.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--kind <kind>", "Filter by resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Any kind RCS indexes is accepted.").option("--search <term>", "Filter resources by name").option("--source <source>", "Resource source: all, local, or remote (default: all)", "all").option("--include-version", "Also report each resource's version, for the kinds that carry one (app, appVersion, package, process). " + "Remote rows report the version live in the folder, local rows the version the solution pins. " + "Costs one extra call per resource, so it is off by default.").option("-l, --limit <number>", "Number of resources to return", parseLimit, DEFAULT_PAGE_SIZE).option("--offset <number>", "Only 0 is accepted: the resource catalog pages by cursor. Use --next-page instead", parseOffset).option("--next-page <cursor>", "Cursor from a previous response's Pagination.NextPage").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(RESOURCE_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
|
|
4843
5192
|
const solutionPath = options.solutionFolder ?? ".";
|
|
4844
5193
|
const fs = getFileSystem();
|
|
4845
5194
|
const resolvedPath = fs.path.resolve(fs.env.cwd(), solutionPath);
|
|
@@ -4863,6 +5212,10 @@ var registerResourceListCommand = (resource) => {
|
|
|
4863
5212
|
processContext.exit(1);
|
|
4864
5213
|
return;
|
|
4865
5214
|
}
|
|
5215
|
+
const start = resolveListStart(options);
|
|
5216
|
+
if (start === undefined) {
|
|
5217
|
+
return;
|
|
5218
|
+
}
|
|
4866
5219
|
const normalizedKind = options.kind;
|
|
4867
5220
|
const [authError] = await catchError(getSolutionAuthContext({
|
|
4868
5221
|
loginValidity: options.loginValidity
|
|
@@ -4896,7 +5249,7 @@ var registerResourceListCommand = (resource) => {
|
|
|
4896
5249
|
processContext.exit(1);
|
|
4897
5250
|
return;
|
|
4898
5251
|
}
|
|
4899
|
-
const [listError, data] = await catchError(listResources(builder, services, source, normalizedKind, options.search, options.includeVersion === true));
|
|
5252
|
+
const [listError, data] = await catchError(listResources(builder, services, source, options.limit, start, normalizedKind, options.search, options.includeVersion === true));
|
|
4900
5253
|
await builder.disposeAsync();
|
|
4901
5254
|
if (listError) {
|
|
4902
5255
|
OutputFormatter.error({
|
|
@@ -4907,37 +5260,106 @@ var registerResourceListCommand = (resource) => {
|
|
|
4907
5260
|
processContext.exit(1);
|
|
4908
5261
|
return;
|
|
4909
5262
|
}
|
|
5263
|
+
const { rows, next } = data;
|
|
4910
5264
|
OutputFormatter.success({
|
|
4911
5265
|
Result: RESULTS.Success,
|
|
4912
5266
|
Code: "ResourceList",
|
|
4913
|
-
Data:
|
|
5267
|
+
Data: rows,
|
|
5268
|
+
Pagination: new Pagination({
|
|
5269
|
+
returned: rows.length,
|
|
5270
|
+
limit: options.limit,
|
|
5271
|
+
hasMore: next !== undefined,
|
|
5272
|
+
nextPage: next && encodeListPosition(next)
|
|
5273
|
+
})
|
|
4914
5274
|
});
|
|
4915
5275
|
});
|
|
4916
5276
|
};
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
5277
|
+
function resolveListStart(options) {
|
|
5278
|
+
if (options.offset !== undefined && options.offset !== 0) {
|
|
5279
|
+
failListArgument("--offset is not supported when listing resources", "The resource catalog pages by cursor, not by offset. Drop --offset, " + "then pass the Pagination.NextPage value from the previous " + "response to --next-page.");
|
|
5280
|
+
return;
|
|
5281
|
+
}
|
|
5282
|
+
if (options.nextPage === undefined) {
|
|
5283
|
+
return { at: "local", index: 0 };
|
|
4921
5284
|
}
|
|
4922
|
-
|
|
5285
|
+
const position = decodeListPosition(options.nextPage);
|
|
5286
|
+
if (position === undefined) {
|
|
5287
|
+
failListArgument("Invalid --next-page value", "Pass the Pagination.NextPage value from the previous " + "`resources list` response unchanged, or drop --next-page to " + "start from the first page.");
|
|
5288
|
+
}
|
|
5289
|
+
return position;
|
|
4923
5290
|
}
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
5291
|
+
function failListArgument(message, instructions) {
|
|
5292
|
+
OutputFormatter.error({
|
|
5293
|
+
Result: RESULTS.Failure,
|
|
5294
|
+
ErrorCode: "invalid_argument",
|
|
5295
|
+
Retry: "RetryWillNotFix",
|
|
5296
|
+
Message: message,
|
|
5297
|
+
Instructions: instructions
|
|
5298
|
+
});
|
|
5299
|
+
processContext.exit(1);
|
|
5300
|
+
}
|
|
5301
|
+
function encodeListPosition(position) {
|
|
5302
|
+
return Buffer.from(JSON.stringify(position), "utf8").toString("base64url");
|
|
5303
|
+
}
|
|
5304
|
+
function decodeListPosition(cursor) {
|
|
5305
|
+
const [parseError, value] = catchError(() => JSON.parse(Buffer.from(cursor, "base64url").toString("utf8")));
|
|
5306
|
+
if (parseError || typeof value !== "object" || value === null) {
|
|
5307
|
+
return;
|
|
4929
5308
|
}
|
|
4930
|
-
const
|
|
4931
|
-
if (
|
|
4932
|
-
|
|
5309
|
+
const { at, index, page, skip } = value;
|
|
5310
|
+
if (at === "local" && isRowCount(index)) {
|
|
5311
|
+
return { at, index };
|
|
4933
5312
|
}
|
|
4934
|
-
if (
|
|
4935
|
-
|
|
4936
|
-
const localKeys = new Set(all.map((e) => `${e.Kind}:${e.Name}`.toLowerCase()));
|
|
4937
|
-
const uniqueRemote = remote.filter((r) => !localKeys.has(`${r.Kind}:${r.Name}`.toLowerCase()));
|
|
4938
|
-
all.push(...uniqueRemote);
|
|
5313
|
+
if (at === "remote" && isRowCount(skip) && (page === undefined || typeof page === "string")) {
|
|
5314
|
+
return { at, page, skip };
|
|
4939
5315
|
}
|
|
4940
|
-
return
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5318
|
+
function isRowCount(value) {
|
|
5319
|
+
return Number.isInteger(value) && value >= 0;
|
|
5320
|
+
}
|
|
5321
|
+
async function listResources(builder, services, source, limit, start, kind, search, includeVersion = false) {
|
|
5322
|
+
const listed = await collectWindow(builder, services, source, limit, start, kind, search);
|
|
5323
|
+
if (includeVersion) {
|
|
5324
|
+
await annotateVersions(services, builder, listed.rows);
|
|
5325
|
+
}
|
|
5326
|
+
return listed;
|
|
5327
|
+
}
|
|
5328
|
+
function resourceIdentity(entry) {
|
|
5329
|
+
return `${entry.Kind}:${entry.Name}`.toLowerCase();
|
|
5330
|
+
}
|
|
5331
|
+
async function collectWindow(builder, services, source, limit, start, kind, search) {
|
|
5332
|
+
const local = source === "remote" ? [] : await listLocalResources(builder, kind, search);
|
|
5333
|
+
const want = limit + 1;
|
|
5334
|
+
const found = [];
|
|
5335
|
+
if (start.at === "local") {
|
|
5336
|
+
for (let i = start.index;i < local.length && found.length < want; i++) {
|
|
5337
|
+
found.push({ entry: local[i], at: { at: "local", index: i } });
|
|
5338
|
+
}
|
|
5339
|
+
}
|
|
5340
|
+
if (source !== "local" && found.length < want) {
|
|
5341
|
+
const localKeys = new Set(local.map(resourceIdentity));
|
|
5342
|
+
let page = start.at === "remote" ? start.page : undefined;
|
|
5343
|
+
let skip = start.at === "remote" ? start.skip : 0;
|
|
5344
|
+
for (;; ) {
|
|
5345
|
+
const result = kind ? await remoteKindPage(builder, kind, search, page) : await allRemotePage(services, search, page);
|
|
5346
|
+
for (let i = skip;i < result.entries.length && found.length < want; i++) {
|
|
5347
|
+
const entry = result.entries[i];
|
|
5348
|
+
if (!localKeys.has(resourceIdentity(entry))) {
|
|
5349
|
+
found.push({ entry, at: { at: "remote", page, skip: i } });
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
if (found.length >= want || result.nextPage === undefined) {
|
|
5353
|
+
break;
|
|
5354
|
+
}
|
|
5355
|
+
page = result.nextPage;
|
|
5356
|
+
skip = 0;
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
return {
|
|
5360
|
+
rows: found.slice(0, limit).map((row) => row.entry),
|
|
5361
|
+
next: found[limit]?.at
|
|
5362
|
+
};
|
|
4941
5363
|
}
|
|
4942
5364
|
function versionLookupId(entry) {
|
|
4943
5365
|
return `${entry.Source}|${entry.Key}|${entry.Folder ?? ""}`;
|
|
@@ -4973,34 +5395,25 @@ async function annotateVersions(services, builder, entries) {
|
|
|
4973
5395
|
}
|
|
4974
5396
|
}
|
|
4975
5397
|
}
|
|
4976
|
-
async function
|
|
4977
|
-
const rcs = services.
|
|
4978
|
-
const
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
Kind: item.entityType ?? "",
|
|
4996
|
-
Type: item.entitySubType ?? undefined,
|
|
4997
|
-
Folder: item.fullyQualifiedName,
|
|
4998
|
-
FolderKey: item.folderKey
|
|
4999
|
-
});
|
|
5000
|
-
}
|
|
5001
|
-
pageCursor = result.nextPage ?? undefined;
|
|
5002
|
-
} while (pageCursor);
|
|
5003
|
-
return entries;
|
|
5398
|
+
async function allRemotePage(services, search, pageCursor) {
|
|
5399
|
+
const rcs = getRemoteResourceClients(services).catalog;
|
|
5400
|
+
const result = await rcs.searchFolderEntities({
|
|
5401
|
+
name: search,
|
|
5402
|
+
pageSize: 100,
|
|
5403
|
+
pageCursor
|
|
5404
|
+
});
|
|
5405
|
+
return {
|
|
5406
|
+
entries: (result.items ?? []).map((item) => ({
|
|
5407
|
+
Source: "Remote",
|
|
5408
|
+
Key: item.entityKey ?? "",
|
|
5409
|
+
Name: item.entityName ?? "",
|
|
5410
|
+
Kind: item.entityType ?? "",
|
|
5411
|
+
Type: item.entitySubType ?? undefined,
|
|
5412
|
+
Folder: item.fullyQualifiedName,
|
|
5413
|
+
FolderKey: item.folderKey
|
|
5414
|
+
})),
|
|
5415
|
+
nextPage: result.nextPage || undefined
|
|
5416
|
+
};
|
|
5004
5417
|
}
|
|
5005
5418
|
async function listLocalResources(builder, kind, search) {
|
|
5006
5419
|
const solution = await builder.context.loadAsync();
|
|
@@ -5021,36 +5434,20 @@ async function listLocalResources(builder, kind, search) {
|
|
|
5021
5434
|
Folder: r.folders?.[0]?.fullyQualifiedName
|
|
5022
5435
|
}));
|
|
5023
5436
|
}
|
|
5024
|
-
async function
|
|
5025
|
-
const
|
|
5026
|
-
|
|
5027
|
-
entries.
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
Name: r.name,
|
|
5039
|
-
Kind: r.kind,
|
|
5040
|
-
Type: r.type,
|
|
5041
|
-
Folder: folder.fullyQualifiedName,
|
|
5042
|
-
FolderKey: folder.key
|
|
5043
|
-
});
|
|
5044
|
-
}
|
|
5045
|
-
}
|
|
5046
|
-
pageCursor = result.nextPage;
|
|
5047
|
-
} while (pageCursor);
|
|
5048
|
-
}
|
|
5049
|
-
if (includeLocal && includeRemote) {
|
|
5050
|
-
const localKeys = new Set(entries.filter((e) => e.Source === "Local").map((e) => `${e.Kind}:${e.Name}`.toLowerCase()));
|
|
5051
|
-
return entries.filter((e) => e.Source === "Local" || !localKeys.has(`${e.Kind}:${e.Name}`.toLowerCase()));
|
|
5052
|
-
}
|
|
5053
|
-
return entries;
|
|
5437
|
+
async function remoteKindPage(builder, kind, search, pageCursor) {
|
|
5438
|
+
const result = await builder.searchResourcesAsync(kind, undefined, search, pageCursor, 100, undefined, false);
|
|
5439
|
+
return {
|
|
5440
|
+
entries: (result.availableResources ?? []).flatMap((folder) => (folder.resources ?? []).map((r) => ({
|
|
5441
|
+
Source: "Remote",
|
|
5442
|
+
Key: r.key,
|
|
5443
|
+
Name: r.name,
|
|
5444
|
+
Kind: r.kind,
|
|
5445
|
+
Type: r.type,
|
|
5446
|
+
Folder: folder.fullyQualifiedName,
|
|
5447
|
+
FolderKey: folder.key
|
|
5448
|
+
}))),
|
|
5449
|
+
nextPage: result.nextPage || undefined
|
|
5450
|
+
};
|
|
5054
5451
|
}
|
|
5055
5452
|
|
|
5056
5453
|
// src/commands/resource-refresh.ts
|
|
@@ -5093,9 +5490,9 @@ var registerResourceRefreshSubcommand = (resource) => {
|
|
|
5093
5490
|
contributionErrorMessages
|
|
5094
5491
|
}
|
|
5095
5492
|
] = await Promise.all([
|
|
5096
|
-
import("./packager-tool-resolver-
|
|
5097
|
-
import("./prepare-solution-resources-
|
|
5098
|
-
import("./project-contributions-
|
|
5493
|
+
import("./packager-tool-resolver-2cbxyq6k.js"),
|
|
5494
|
+
import("./prepare-solution-resources-p3gzdecy.js"),
|
|
5495
|
+
import("./project-contributions-txe8v6sm.js")
|
|
5099
5496
|
]);
|
|
5100
5497
|
const resolveProjectSubTypesAsync = async () => {
|
|
5101
5498
|
await ensurePackagerTools2(solutionFolder, fs);
|
|
@@ -6293,11 +6690,11 @@ var registerUploadCommand = (program) => {
|
|
|
6293
6690
|
});
|
|
6294
6691
|
const projectTypeSummary = bundledProjectTypes.length > 0 ? summarizeShipProjectTypes(bundledProjectTypes) : await inspectSolutionPackageProjectTypes(uisPath);
|
|
6295
6692
|
trackSolutionShipSucceeded({
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6693
|
+
[ShipDimensions.ShipKind]: "upload",
|
|
6694
|
+
[ShipDimensions.Target]: "studio_web",
|
|
6695
|
+
[CommandDimensions.CommandName]: "uip solution upload",
|
|
6696
|
+
[ShipDimensions.ArtifactCorrelationKey]: returnedSolutionId,
|
|
6697
|
+
[ShipDimensions.SolutionId]: returnedSolutionId,
|
|
6301
6698
|
projectTypeSummary
|
|
6302
6699
|
});
|
|
6303
6700
|
} finally {
|
|
@@ -6387,7 +6784,7 @@ var registerCommands = async (program) => {
|
|
|
6387
6784
|
registerResourceCommand(program);
|
|
6388
6785
|
registerDeleteCommand(program);
|
|
6389
6786
|
if (isPreviewBuild()) {
|
|
6390
|
-
const { registerListCommand } = await import("./list-
|
|
6787
|
+
const { registerListCommand } = await import("./list-q4dzkv45.js");
|
|
6391
6788
|
registerListCommand(program);
|
|
6392
6789
|
}
|
|
6393
6790
|
registerFeedsCommand(program);
|
|
@@ -6395,4 +6792,4 @@ var registerCommands = async (program) => {
|
|
|
6395
6792
|
|
|
6396
6793
|
export { metadata, registerCommands };
|
|
6397
6794
|
|
|
6398
|
-
//# debugId=
|
|
6795
|
+
//# debugId=BBC3E9770AD02E7064756E2164756E21
|