@uipath/solution-tool 1.204.0-preview.255 → 1.205.0-preview.256
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 +3 -3
- package/dist/THIRD-PARTY-NOTICES.md +2 -2
- package/dist/archive-extract-x35t9ktj.js +120 -0
- package/dist/cleanup-command-service-n4e7vxnw.js +149 -0
- package/dist/deploy-delete-service-cag0q8yx.js +25 -0
- package/dist/deploy-run-service-f0h8wb9w.js +25 -0
- package/dist/{deploy-status-service-6svq7c6w.js → deploy-status-service-yh6xn6e0.js} +41 -33
- package/dist/deploy.js +23 -17
- package/dist/{deployment-search-v2qtz23x.js → deployment-search-mnywd9nc.js} +16 -10
- package/dist/{embedded-file-reader-rf2g1kfj.js → embedded-file-reader-z4becc02.js} +2 -2
- package/dist/{feed-resolver-xz3akamf.js → feed-resolver-fve33dxq.js} +10 -9
- package/dist/feed-scope-failure-jmg4t1r1.js +19 -0
- package/dist/{feed-session-sxga31vn.js → feed-session-7xqphdrg.js} +3 -3
- package/dist/governance-options-4vxz7ekn.js +32 -0
- package/dist/index-g8c8nf1c.js +667 -0
- package/dist/index-prm27bvm.js +138 -0
- package/dist/index.js +27 -29
- package/dist/init.js +11 -10
- package/dist/{list-tjetkspc.js → list-50mepbed.js} +10 -8
- package/dist/models/pack-command-types.d.ts +15 -0
- package/dist/node-7jm7ksqa.js +86 -0
- package/dist/pack-command-service-dewf5vsq.js +35 -0
- package/dist/pack-project-xwd1rbaa.js +97 -0
- package/dist/pack.js +24 -14
- package/dist/package-id-1wr3cy9c.js +13 -0
- package/dist/packager-tool-09swr9cp.js +171 -0
- package/dist/{packager-tool-a9jx8gf4.js → packager-tool-2vmsh5pt.js} +196 -1519
- package/dist/{packager-tool-px1j9kre.js → packager-tool-3bwnkjdq.js} +2 -2
- package/dist/{packager-tool-gb35b4qs.js → packager-tool-43ahv5mn.js} +192 -96
- package/dist/{packager-tool-9ha2z8h5.js → packager-tool-47by487p.js} +6 -4
- package/dist/packager-tool-47wzvqw0.js +86 -0
- package/dist/{packager-tool-zns6n8zp.js → packager-tool-5ddtwzva.js} +1 -1
- package/dist/packager-tool-5edvzz80.js +543 -0
- package/dist/{packager-tool-jq9zw82w.js → packager-tool-5n6jsn41.js} +104 -14
- package/dist/packager-tool-60af1hw2.js +26 -0
- package/dist/{packager-tool-f5gq77m5.js → packager-tool-61pwb567.js} +2 -2
- package/dist/{packager-tool-yrz4mwfn.js → packager-tool-6kz1pv9f.js} +1373 -486
- package/dist/packager-tool-6ybywxxn.js +1809 -0
- package/dist/packager-tool-8ptbmmmp.js +2132 -0
- package/dist/{packager-tool-7gr2nphb.js → packager-tool-97rcgwvv.js} +224 -6
- package/dist/{packager-tool-83m6ns0r.js → packager-tool-9t26kde1.js} +3556 -1646
- package/dist/packager-tool-act5r386.js +239 -0
- package/dist/packager-tool-amhyxzz6.js +125 -0
- package/dist/packager-tool-b03rva43.js +188 -0
- package/dist/{packager-tool-e2rtr49j.js → packager-tool-b2nhscfk.js} +15 -31
- package/dist/{packager-tool-tv9c1e80.js → packager-tool-d6rrfd46.js} +149 -53
- package/dist/packager-tool-frr2xmkr.js +445 -0
- package/dist/{packager-tool-v8bkkqdb.js → packager-tool-gmwva4yv.js} +5 -5
- package/dist/packager-tool-gs3f3tf7.js +103 -0
- package/dist/packager-tool-jg692f13.js +517 -0
- package/dist/packager-tool-jmpb786m.js +109 -0
- package/dist/{packager-tool-5sex4a1h.js → packager-tool-kds8ytzw.js} +74 -23
- package/dist/packager-tool-kkfb5kgn.js +182 -0
- package/dist/packager-tool-kvcxg0zv.js +1510 -0
- package/dist/packager-tool-n3jfjn5r.js +42 -0
- package/dist/{packager-tool-fjsn5h8s.js → packager-tool-n5d5dx5j.js} +2196 -3455
- package/dist/{packager-tool-yfpcvdpm.js → packager-tool-nsya65z1.js} +357 -1370
- package/dist/{packager-tool-fv7xyzg2.js → packager-tool-pbmqk39a.js} +126 -128
- package/dist/{packager-tool-bqre28m1.js → packager-tool-qw47eyw7.js} +1 -1
- package/dist/{packager-tool-9qgmwy21.js → packager-tool-rc3hwn4b.js} +25 -4
- package/dist/packager-tool-resolver-994z3jkj.js +23 -0
- package/dist/{packager-tool-tgw5x6vx.js → packager-tool-rvt68c1t.js} +17 -8
- package/dist/{packager-tool-gab9y5ct.js → packager-tool-t8gh825q.js} +37 -13
- package/dist/{packager-tool-kswwd3hp.js → packager-tool-tx834spe.js} +2376 -4077
- package/dist/{packager-tool-zf3929se.js → packager-tool-v1f5e8t9.js} +11 -1
- package/dist/{packager-tool-ssq2kzqm.js → packager-tool-w77d72a7.js} +13 -11
- package/dist/{packager-tool-1rzssy0x.js → packager-tool-wy4fx250.js} +19 -18
- package/dist/packager-tool-wz34ma3s.js +1333 -0
- package/dist/packager-tool-zq16e1xv.js +68 -0
- package/dist/packager-tool.js +2 -2
- package/dist/prepare-solution-resources-m1djfj62.js +29 -0
- package/dist/project-command-utils-t6pmpvq3.js +90 -0
- package/dist/project-contributions-79ndycrx.js +32 -0
- package/dist/publish.js +13 -12
- package/dist/resource-mutations-c3krjqze.js +36 -0
- package/dist/resource-version-lookup-0e3e2j58.js +99 -0
- package/dist/resource.js +10 -9
- package/dist/restore-command-service-5v0b9363.js +155 -0
- package/dist/run-service-tg6b67wp.js +428 -0
- package/dist/services/deploy-activate-service.d.ts +10 -5
- package/dist/services/deploy-delete-service.d.ts +8 -4
- package/dist/services/deploy-run-service.d.ts +34 -1
- package/dist/services/deploy-uninstall-service.d.ts +21 -3
- package/dist/services/deploy-upgrade-service.d.ts +35 -1
- package/dist/services/deployment-feed-locator.d.ts +15 -4
- package/dist/services/deployment-search-client.d.ts +5 -53
- package/dist/services/deployment-search.d.ts +58 -3
- package/dist/services/deployment-state.d.ts +84 -24
- package/dist/services/deployment-validation.d.ts +5 -0
- package/dist/services/emit-runtime-dependencies.d.ts +2 -1
- package/dist/services/feed-resolver.d.ts +6 -4
- package/dist/services/feed-selection.d.ts +47 -0
- package/dist/services/http-status.d.ts +2 -7
- package/dist/services/pack-command-service.d.ts +9 -0
- package/dist/services/pack-project-selection.d.ts +51 -0
- package/dist/services/pack-project.d.ts +26 -0
- package/dist/services/pack-service.d.ts +7 -3
- package/dist/services/package-search-client.d.ts +7 -0
- package/dist/services/packager-tool-resolver.d.ts +7 -1
- package/dist/services/packages-list-service.d.ts +1 -1
- package/dist/services/permanent-deletion-consent.d.ts +110 -0
- package/dist/services/pipeline-deploy-poll.d.ts +7 -0
- package/dist/services/prepare-solution-resources.d.ts +12 -2
- package/dist/services/project-contributions.d.ts +5 -4
- package/dist/services/search-failure.d.ts +9 -13
- package/dist/services/solution-packager-helpers.d.ts +5 -2
- package/dist/services/solution-path.d.ts +1 -1
- package/dist/services/uninstall-consent.d.ts +82 -0
- package/dist/ship-telemetry-myes7ak5.js +21 -0
- package/dist/solution-auth-aead70sw.js +11 -0
- package/dist/templates/AGENTS.md +125 -12
- package/dist/tool.js +27 -29
- package/dist/utils/deployment-errors.d.ts +9 -1
- package/package.json +2 -2
- package/dist/deploy-delete-service-w3e8x1kq.js +0 -22
- package/dist/feed-scope-failure-0j5byccb.js +0 -18
- package/dist/packager-tool-f2e9rzxk.js +0 -104
- package/dist/packager-tool-resolver-6zwhec62.js +0 -20
- package/dist/packager-tool-zdfn32bc.js +0 -4465
- package/dist/prepare-solution-resources-jpb5as2s.js +0 -25
- package/dist/project-contributions-6wpff2hm.js +0 -30
- package/dist/services/legacy-deployment-search-v3.d.ts +0 -23
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isCurrentRecordAsync
|
|
3
|
+
} from "./packager-tool-5n6jsn41.js";
|
|
4
|
+
import {
|
|
5
|
+
VALIDATION_CONFIRMATION_REQUIRED_CODE,
|
|
6
|
+
coerceWorkflowErrorMessages
|
|
7
|
+
} from "./packager-tool-act5r386.js";
|
|
8
|
+
import {
|
|
9
|
+
deploymentToTerminalPipelineResult,
|
|
10
|
+
findDeploymentBestEffort,
|
|
11
|
+
isPipelineDeploymentNotFoundError,
|
|
12
|
+
mapOperationStatusToPipelineStatus
|
|
13
|
+
} from "./packager-tool-d6rrfd46.js";
|
|
14
|
+
import {
|
|
15
|
+
resolvePersonalWorkspace
|
|
16
|
+
} from "./packager-tool-rvt68c1t.js";
|
|
17
|
+
import {
|
|
18
|
+
Configuration,
|
|
19
|
+
PipelinesApi
|
|
20
|
+
} from "./packager-tool-97rcgwvv.js";
|
|
21
|
+
import {
|
|
22
|
+
Configuration as Configuration2,
|
|
23
|
+
DeploymentsApi
|
|
24
|
+
} from "./packager-tool-9t26kde1.js";
|
|
25
|
+
import {
|
|
26
|
+
resolveFolder
|
|
27
|
+
} from "./packager-tool-8ptbmmmp.js";
|
|
28
|
+
import {
|
|
29
|
+
PollOutcome,
|
|
30
|
+
logger,
|
|
31
|
+
pollUntil,
|
|
32
|
+
processContext
|
|
33
|
+
} from "./packager-tool-tx834spe.js";
|
|
34
|
+
import {
|
|
35
|
+
catchError,
|
|
36
|
+
extractErrorDetails
|
|
37
|
+
} from "./packager-tool-6ybywxxn.js";
|
|
38
|
+
|
|
39
|
+
// src/services/activation.ts
|
|
40
|
+
var TERMINAL_STATUSES = new Set([
|
|
41
|
+
"SuccessfulActivate",
|
|
42
|
+
"FailedActivate"
|
|
43
|
+
]);
|
|
44
|
+
async function activateDeployment(auth, deploymentName, options) {
|
|
45
|
+
const api = new PipelinesApi(new Configuration({
|
|
46
|
+
basePath: auth.basePath,
|
|
47
|
+
accessToken: auth.accessToken
|
|
48
|
+
}));
|
|
49
|
+
const [stepsError, steps] = await catchError(api.pipelinesGetPreActivateSteps({ deploymentName }, options.scope));
|
|
50
|
+
if (stepsError) {
|
|
51
|
+
const { message, details, errorCode, retry, context } = await extractErrorDetails(stepsError);
|
|
52
|
+
const deployment = await findDeploymentBestEffort(auth, deploymentName, options.scope);
|
|
53
|
+
return {
|
|
54
|
+
kind: "RequestFailed",
|
|
55
|
+
phase: "preActivateSteps",
|
|
56
|
+
message,
|
|
57
|
+
details,
|
|
58
|
+
errorCode,
|
|
59
|
+
retry,
|
|
60
|
+
httpStatus: context?.httpStatus,
|
|
61
|
+
deployment
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (steps.steps.length > 0) {
|
|
65
|
+
logger.info(`Pre-activate steps for ${deploymentName}:`);
|
|
66
|
+
for (const step of steps.steps) {
|
|
67
|
+
logger.info(` [${step.serviceName}] ${step.step}: ${step.description}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const [activateError, activateResult] = await catchError(api.pipelinesActivate({ deploymentName }, options.scope));
|
|
71
|
+
if (activateError) {
|
|
72
|
+
const { message, details, errorCode, retry, context } = await extractErrorDetails(activateError);
|
|
73
|
+
const deployment = await findDeploymentBestEffort(auth, deploymentName, options.scope);
|
|
74
|
+
return {
|
|
75
|
+
kind: "RequestFailed",
|
|
76
|
+
phase: "activate",
|
|
77
|
+
message,
|
|
78
|
+
details,
|
|
79
|
+
errorCode,
|
|
80
|
+
retry,
|
|
81
|
+
httpStatus: context?.httpStatus,
|
|
82
|
+
deployment
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const instanceId = activateResult.instanceId;
|
|
86
|
+
if (!instanceId) {
|
|
87
|
+
return { kind: "NoInstance" };
|
|
88
|
+
}
|
|
89
|
+
const pollResult = await pollUntil({
|
|
90
|
+
fn: () => api.pipelinesGetDeploymentInstanceStatus({ instanceId }, options.scope),
|
|
91
|
+
until: (result) => TERMINAL_STATUSES.has(result.status),
|
|
92
|
+
getStatus: (result) => result.status,
|
|
93
|
+
label: `activate ${deploymentName}`,
|
|
94
|
+
logPrefix: "activate",
|
|
95
|
+
timeoutMs: options.timeoutSeconds * 1000,
|
|
96
|
+
intervalMs: options.pollIntervalMs,
|
|
97
|
+
signal: options.signal ?? processContext.pollSignal
|
|
98
|
+
});
|
|
99
|
+
if (pollResult.outcome !== PollOutcome.Completed || !pollResult.data) {
|
|
100
|
+
return { kind: "PollFailed", poll: pollResult };
|
|
101
|
+
}
|
|
102
|
+
const finalStatus = pollResult.data;
|
|
103
|
+
if (finalStatus.status !== "SuccessfulActivate") {
|
|
104
|
+
const errorMessage = coerceWorkflowErrorMessages(finalStatus.errorMessage).map((e) => e.errorMessage).join(", ") || "Unknown error";
|
|
105
|
+
return {
|
|
106
|
+
kind: "ActivationFailed",
|
|
107
|
+
status: finalStatus.status,
|
|
108
|
+
instanceId,
|
|
109
|
+
errorMessage
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
kind: "Success",
|
|
114
|
+
status: finalStatus.status,
|
|
115
|
+
instanceId
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/services/folder-helper.ts
|
|
120
|
+
async function resolveParentFolder(options) {
|
|
121
|
+
if (!options.folderPath && !options.folderKey && !options.personalWorkspace) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (options.personalWorkspace) {
|
|
125
|
+
const [pwError, pw] = await catchError(resolvePersonalWorkspace({
|
|
126
|
+
tenant: options.tenant,
|
|
127
|
+
loginValidity: options.loginValidity,
|
|
128
|
+
envFilePath: options.envFilePath
|
|
129
|
+
}));
|
|
130
|
+
if (pwError) {
|
|
131
|
+
throw new Error(`Failed to resolve Personal Workspace: ${pwError.message}`);
|
|
132
|
+
}
|
|
133
|
+
return pw.name;
|
|
134
|
+
}
|
|
135
|
+
if (options.folderPath) {
|
|
136
|
+
return options.folderPath;
|
|
137
|
+
}
|
|
138
|
+
const [resolveError, resolved] = await catchError(resolveFolder({ folderKey: options.folderKey }, {
|
|
139
|
+
tenant: options.tenant,
|
|
140
|
+
loginValidity: options.loginValidity,
|
|
141
|
+
envFilePath: options.envFilePath
|
|
142
|
+
}));
|
|
143
|
+
if (resolveError) {
|
|
144
|
+
throw new Error(`Failed to resolve folder key '${options.folderKey}': ${resolveError.message}`);
|
|
145
|
+
}
|
|
146
|
+
if (!resolved) {
|
|
147
|
+
throw new Error(`Folder not found for key '${options.folderKey}'.`);
|
|
148
|
+
}
|
|
149
|
+
return resolved.path;
|
|
150
|
+
}
|
|
151
|
+
async function resolveFolderInfo(options) {
|
|
152
|
+
if (!options.folderPath && !options.folderKey) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const [resolveError, resolved] = await catchError(resolveFolder({ folderPath: options.folderPath, folderKey: options.folderKey }, {
|
|
156
|
+
tenant: options.tenant,
|
|
157
|
+
loginValidity: options.loginValidity,
|
|
158
|
+
envFilePath: options.envFilePath
|
|
159
|
+
}));
|
|
160
|
+
if (resolveError) {
|
|
161
|
+
throw new Error(`Failed to resolve folder '${options.folderPath ?? options.folderKey}': ${resolveError.message}`);
|
|
162
|
+
}
|
|
163
|
+
if (!resolved) {
|
|
164
|
+
throw new Error(`Folder not found: '${options.folderPath ?? options.folderKey}'.`);
|
|
165
|
+
}
|
|
166
|
+
return { key: resolved.key, path: resolved.path };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/services/deployment-validation.ts
|
|
170
|
+
var NO_SERVER_REASON = "the server reported no reason.";
|
|
171
|
+
var LOOKUP_TIMEOUT_MS = 15000;
|
|
172
|
+
function boundedScope(scope, signal) {
|
|
173
|
+
const deadline = AbortSignal.timeout(LOOKUP_TIMEOUT_MS);
|
|
174
|
+
const abort = signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
175
|
+
return async (requestContext) => ({
|
|
176
|
+
...await scope?.(requestContext),
|
|
177
|
+
signal: abort
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
async function describeValidationFailureAsync(deploymentsApi, deploymentKey, deploymentAction, scope, signal) {
|
|
181
|
+
const [error, validation] = await catchError(deploymentsApi.deploymentsGetValidationResult({ deploymentKey, deploymentAction }, boundedScope(scope, signal)));
|
|
182
|
+
if (error || !validation) {
|
|
183
|
+
return NO_SERVER_REASON;
|
|
184
|
+
}
|
|
185
|
+
const messages = [
|
|
186
|
+
...validation.validationErrors.map((item) => item.text || item.resource),
|
|
187
|
+
...validation.resourceValidationErrors.flatMap((resource) => resource.errors.map((item) => item.text || item.resource))
|
|
188
|
+
].filter(Boolean);
|
|
189
|
+
return messages.length > 0 ? messages.join("; ") : NO_SERVER_REASON;
|
|
190
|
+
}
|
|
191
|
+
async function describeDeploymentFailureAsync(auth, deployment, deploymentAction, scope, signal) {
|
|
192
|
+
const deploymentsApi = new DeploymentsApi(new Configuration2({
|
|
193
|
+
basePath: auth.basePath,
|
|
194
|
+
accessToken: auth.accessToken
|
|
195
|
+
}));
|
|
196
|
+
const keys = [deployment.key, deployment.installDeploymentKey].filter((key, index, all) => Boolean(key) && all.indexOf(key) === index);
|
|
197
|
+
for (const key of keys) {
|
|
198
|
+
const reason = await describeValidationFailureAsync(deploymentsApi, key, deploymentAction, scope, signal);
|
|
199
|
+
if (reason !== NO_SERVER_REASON) {
|
|
200
|
+
return reason;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return NO_SERVER_REASON;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/services/permanent-deletion-consent.ts
|
|
207
|
+
function isPermanentDeletionRefusal(status) {
|
|
208
|
+
return status?.status === "DeploymentScheduleError" && (status.deploymentScheduleErrors ?? []).some((error) => error.errorCode === VALIDATION_CONFIRMATION_REQUIRED_CODE);
|
|
209
|
+
}
|
|
210
|
+
function selectPermanentDeletionResources(validationErrors) {
|
|
211
|
+
const byKey = new Map;
|
|
212
|
+
for (const error of validationErrors) {
|
|
213
|
+
if (error.errorKind !== "RequiresConfirmation" || error.level !== "Warning" || !error.key || byKey.has(error.key)) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
byKey.set(error.key, {
|
|
217
|
+
key: error.key,
|
|
218
|
+
name: error.name || error.key,
|
|
219
|
+
...error.kind ? { kind: error.kind } : {}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return [...byKey.values()];
|
|
223
|
+
}
|
|
224
|
+
async function listPermanentDeletionResourcesAsync(api, deploymentName, deploymentKey, scope, signal) {
|
|
225
|
+
if (!deploymentKey) {
|
|
226
|
+
logger.debug(`No deployment key to tie the validation result of '${deploymentName}' to`);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const [error, validation] = await catchError(() => api.pipelinesGetDeploymentValidationResult({ deploymentName }, boundedScope(scope, signal)));
|
|
230
|
+
if (error || !validation) {
|
|
231
|
+
if (error) {
|
|
232
|
+
logger.debug(`Could not read the validation result of '${deploymentName}': ${error.message}`);
|
|
233
|
+
}
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (!await isCurrentRecordAsync(api, deploymentKey, boundedScope(undefined, signal))) {
|
|
237
|
+
logger.debug(`The validation result of '${deploymentName}' is not provably record ${deploymentKey}'s: it was superseded, or the by-key lookup failed`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
return selectPermanentDeletionResources(validation.validationErrors ?? []);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
class AcknowledgePermanentDeletionError extends Error {
|
|
244
|
+
resource;
|
|
245
|
+
detail;
|
|
246
|
+
constructor(resource, detail) {
|
|
247
|
+
const reason = detail.details ? `${detail.message}: ${detail.details}` : detail.message;
|
|
248
|
+
super(`Acknowledging the permanent deletion of ${formatPermanentDeletionResource(resource)} (${resource.key}) failed: ${reason}`);
|
|
249
|
+
this.resource = resource;
|
|
250
|
+
this.detail = detail;
|
|
251
|
+
this.name = "AcknowledgePermanentDeletionError";
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async function acknowledgePermanentDeletionAsync(api, deploymentName, resources, scope, signal) {
|
|
255
|
+
for (const resource of resources) {
|
|
256
|
+
const [error] = await catchError(() => api.pipelinesAcknowledgeResourcePermanentDeletion({
|
|
257
|
+
deploymentName,
|
|
258
|
+
resourceKey: resource.key,
|
|
259
|
+
acknowledged: true
|
|
260
|
+
}, boundedScope(scope, signal)));
|
|
261
|
+
if (error) {
|
|
262
|
+
throw new AcknowledgePermanentDeletionError(resource, await extractErrorDetails(error));
|
|
263
|
+
}
|
|
264
|
+
logger.info(`Acknowledged permanent deletion of ${formatPermanentDeletionResource(resource)}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function formatPermanentDeletionResource(resource) {
|
|
268
|
+
return resource.kind ? `${resource.kind} '${resource.name}'` : `'${resource.name}'`;
|
|
269
|
+
}
|
|
270
|
+
function formatPermanentDeletionResources(resources) {
|
|
271
|
+
return resources.map(formatPermanentDeletionResource).join(", ");
|
|
272
|
+
}
|
|
273
|
+
var ACKNOWLEDGE_PERMANENT_DELETION_FLAG = "--acknowledge-permanent-deletion";
|
|
274
|
+
async function settlePermanentDeletionRefusalAsync(request) {
|
|
275
|
+
const deploymentKey = request.status.deploymentKey || undefined;
|
|
276
|
+
const resources = await listPermanentDeletionResourcesAsync(request.api, request.deploymentName, deploymentKey, request.scope, request.signal);
|
|
277
|
+
const draft = request.status.deploymentKey ? ` (${request.status.deploymentKey})` : "";
|
|
278
|
+
const nothingInstalled = `Nothing was installed; the attempt is kept as a pending draft${draft}.`;
|
|
279
|
+
if (!resources || resources.length === 0) {
|
|
280
|
+
const serverText = (request.status.deploymentScheduleErrors ?? []).filter((error) => error.errorCode === VALIDATION_CONFIRMATION_REQUIRED_CODE).map((error) => error.errorText).join(" ");
|
|
281
|
+
const why = resources ? "the deployment's validation result names no resource to confirm" : "the deployment's validation result could not be read, or the deployment changed under this run";
|
|
282
|
+
return {
|
|
283
|
+
ok: false,
|
|
284
|
+
reason: "permanent_deletion_confirmation_required",
|
|
285
|
+
message: `The server requires confirmation before ${request.verb.toLowerCase()} '${request.deploymentName}': ${serverText || "installed resources replaced by links would be permanently deleted with their data."}`,
|
|
286
|
+
instructions: request.acknowledge ? `The resources to confirm could not be listed (${why}), so none were acknowledged: the CLI only confirms deletions it can name. ${nothingInstalled} Retry the same command, or review the deployment in Orchestrator.` : `The resources could not be listed (${why}). ${nothingInstalled} To confirm, ${request.confirmHint}. To keep the installed copies instead, ${request.keepCopiesHint}.`,
|
|
287
|
+
classification: request.acknowledge ? {} : { errorCode: "invalid_argument", retry: "RetryWillNotFix" }
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
if (!request.acknowledge) {
|
|
291
|
+
return {
|
|
292
|
+
ok: false,
|
|
293
|
+
reason: "permanent_deletion_confirmation_required",
|
|
294
|
+
message: `${request.verb} '${request.deploymentName}' will permanently delete ${resources.length} installed resource(s) replaced by links: ${formatPermanentDeletionResources(resources)}, along with their data.`,
|
|
295
|
+
instructions: `${nothingInstalled} To confirm the deletion, ${request.confirmHint}. To keep the installed copies instead, ${request.keepCopiesHint}.`,
|
|
296
|
+
resources,
|
|
297
|
+
classification: {
|
|
298
|
+
errorCode: "invalid_argument",
|
|
299
|
+
retry: "RetryWillNotFix"
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const [ackError] = await catchError(acknowledgePermanentDeletionAsync(request.api, request.deploymentName, resources, request.scope, request.signal));
|
|
304
|
+
if (ackError) {
|
|
305
|
+
return {
|
|
306
|
+
ok: false,
|
|
307
|
+
reason: "acknowledge_failed",
|
|
308
|
+
message: ackError.message,
|
|
309
|
+
instructions: `${nothingInstalled} The install was not re-run. Resources acknowledged before the failure stay acknowledged on the draft. Retry the same command once the server accepts the acknowledgement; a 404 means this server does not offer the Pipelines acknowledge route yet, so confirm the deletion in Orchestrator instead.`,
|
|
310
|
+
resources,
|
|
311
|
+
classification: ackError instanceof AcknowledgePermanentDeletionError ? {
|
|
312
|
+
errorCode: ackError.detail.errorCode,
|
|
313
|
+
retry: ackError.detail.retry
|
|
314
|
+
} : {}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const stillCurrent = deploymentKey !== undefined && await isCurrentRecordAsync(request.api, deploymentKey, boundedScope(undefined, request.signal));
|
|
318
|
+
if (!stillCurrent) {
|
|
319
|
+
return {
|
|
320
|
+
ok: false,
|
|
321
|
+
reason: "acknowledge_failed",
|
|
322
|
+
message: `Deployment '${request.deploymentName}' changed under this run: record ${deploymentKey} is no longer its current record, so the install was not re-run.`,
|
|
323
|
+
instructions: `Nothing was installed by this run. The acknowledgement was sent to the deployment by name, so another install or upgrade of '${request.deploymentName}' that landed meanwhile may now carry it: review the deployment in Orchestrator before running anything else.`,
|
|
324
|
+
resources,
|
|
325
|
+
classification: {
|
|
326
|
+
errorCode: "invalid_argument",
|
|
327
|
+
retry: "RetryWillNotFix"
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
return { ok: true, resources };
|
|
332
|
+
}
|
|
333
|
+
function acknowledgedButNotRunHint(resources, keepCopiesHint) {
|
|
334
|
+
return `The permanent deletion of ${formatPermanentDeletionResources(resources)} is already acknowledged on the kept draft, though nothing was deleted because the install did not run: re-running the same command deletes them without asking again. To keep the installed copies instead, ${keepCopiesHint}.`;
|
|
335
|
+
}
|
|
336
|
+
function stillRequiresConfirmation(deploymentName, resources, deploymentKey) {
|
|
337
|
+
const acknowledged = resources.map((resource) => resource.key).join(", ");
|
|
338
|
+
const draft = deploymentKey ? ` (${deploymentKey})` : "";
|
|
339
|
+
return {
|
|
340
|
+
reason: "permanent_deletion_confirmation_required",
|
|
341
|
+
message: `The server still requires confirmation for '${deploymentName}' after acknowledging ${acknowledged}.`,
|
|
342
|
+
instructions: `The install was re-run once and refused again, so the CLI stopped rather than loop. Nothing was installed; the attempt is kept as a pending draft${draft}. Review the deployment's resources in Orchestrator: another resource may need confirmation, or the acknowledgement did not reach the draft.`,
|
|
343
|
+
resources: [...resources],
|
|
344
|
+
classification: {}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/services/pipeline-deploy-poll.ts
|
|
349
|
+
var PIPELINE_TERMINAL_STATUSES = new Set([
|
|
350
|
+
"DeploymentSucceeded",
|
|
351
|
+
"DeploymentFailed",
|
|
352
|
+
"ValidationFailed",
|
|
353
|
+
"ConflictFixingError",
|
|
354
|
+
"DeploymentScheduleError"
|
|
355
|
+
]);
|
|
356
|
+
function remainingTimeoutMs(timeoutMs, deadline) {
|
|
357
|
+
if (timeoutMs === 0) {
|
|
358
|
+
return 0;
|
|
359
|
+
}
|
|
360
|
+
return Math.max(1, deadline - Date.now());
|
|
361
|
+
}
|
|
362
|
+
var NO_ERRORS = {
|
|
363
|
+
validationResult: { validationErrors: [], conflictErrors: [] },
|
|
364
|
+
conflictFixingErrors: [],
|
|
365
|
+
deploymentScheduleErrors: []
|
|
366
|
+
};
|
|
367
|
+
function stillInFlight(deploymentKey) {
|
|
368
|
+
return {
|
|
369
|
+
status: "DeploymentInProgress",
|
|
370
|
+
deploymentKey: deploymentKey ?? "",
|
|
371
|
+
configurationKey: "",
|
|
372
|
+
...NO_ERRORS
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
async function readOutcomeByKeyAsync(api, deploymentKey) {
|
|
376
|
+
const [error, info] = await catchError(() => api.pipelinesGetDeploymentByKey({ key: deploymentKey }));
|
|
377
|
+
if (error || !info) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (info.deploymentKey !== deploymentKey) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (info.operation === "Uninstall" || info.operationStatus === "Draft") {
|
|
384
|
+
return stillInFlight(deploymentKey);
|
|
385
|
+
}
|
|
386
|
+
const status = mapOperationStatusToPipelineStatus(info.operationStatus);
|
|
387
|
+
if (!status) {
|
|
388
|
+
return stillInFlight(deploymentKey);
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
status,
|
|
392
|
+
deploymentKey: info.deploymentKey,
|
|
393
|
+
configurationKey: "",
|
|
394
|
+
...NO_ERRORS,
|
|
395
|
+
synthesizedOperation: info.operation
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
async function pollPipelineDeploymentAsync(api, auth, options) {
|
|
399
|
+
let observedDeploymentKey;
|
|
400
|
+
return pollUntil({
|
|
401
|
+
fn: async () => {
|
|
402
|
+
try {
|
|
403
|
+
const status = await api.pipelinesGetPipelineDeploymentStatus({ pipelineDeploymentId: options.pipelineDeploymentId }, options.scope);
|
|
404
|
+
if (status.deploymentKey) {
|
|
405
|
+
observedDeploymentKey = status.deploymentKey;
|
|
406
|
+
}
|
|
407
|
+
return status;
|
|
408
|
+
} catch (err) {
|
|
409
|
+
if (!await isPipelineDeploymentNotFoundError(err)) {
|
|
410
|
+
throw err;
|
|
411
|
+
}
|
|
412
|
+
if (!observedDeploymentKey) {
|
|
413
|
+
return stillInFlight(undefined);
|
|
414
|
+
}
|
|
415
|
+
const byKey = await readOutcomeByKeyAsync(api, observedDeploymentKey);
|
|
416
|
+
if (byKey) {
|
|
417
|
+
return byKey;
|
|
418
|
+
}
|
|
419
|
+
const deployment = await findDeploymentBestEffort(auth, options.deploymentName, options.scope, { deploymentKey: observedDeploymentKey });
|
|
420
|
+
if (!deployment || deployment.operationStatus === "Draft") {
|
|
421
|
+
return stillInFlight(observedDeploymentKey);
|
|
422
|
+
}
|
|
423
|
+
const synthesized = deploymentToTerminalPipelineResult(deployment);
|
|
424
|
+
if (!synthesized) {
|
|
425
|
+
return stillInFlight(observedDeploymentKey);
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
...synthesized,
|
|
429
|
+
synthesizedOperation: deployment.operation
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
until: (result) => PIPELINE_TERMINAL_STATUSES.has(result.status),
|
|
434
|
+
getStatus: (result) => result.status,
|
|
435
|
+
label: `deployment ${options.pipelineDeploymentId}`,
|
|
436
|
+
logPrefix: options.logPrefix,
|
|
437
|
+
timeoutMs: options.timeoutMs,
|
|
438
|
+
intervalMs: options.intervalMs,
|
|
439
|
+
signal: options.signal
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export { activateDeployment, resolveParentFolder, resolveFolderInfo, NO_SERVER_REASON, describeValidationFailureAsync, describeDeploymentFailureAsync, isPermanentDeletionRefusal, listPermanentDeletionResourcesAsync, formatPermanentDeletionResources, ACKNOWLEDGE_PERMANENT_DELETION_FLAG, settlePermanentDeletionRefusalAsync, acknowledgedButNotRunHint, stillRequiresConfirmation, remainingTimeoutMs, pollPipelineDeploymentAsync };
|
|
444
|
+
|
|
445
|
+
//# debugId=0A59B0D65B5A781064756E2164756E21
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
catchError
|
|
3
|
-
} from "./packager-tool-kswwd3hp.js";
|
|
4
1
|
import {
|
|
5
2
|
getAuthContext
|
|
6
|
-
} from "./packager-tool-
|
|
3
|
+
} from "./packager-tool-43ahv5mn.js";
|
|
4
|
+
import {
|
|
5
|
+
catchError
|
|
6
|
+
} from "./packager-tool-6ybywxxn.js";
|
|
7
7
|
|
|
8
8
|
// src/services/studio-web-auth-middleware.ts
|
|
9
9
|
var studioWebAuthByCommand = new WeakMap;
|
|
@@ -66,4 +66,4 @@ async function resolveStudioWebAuthContext(options) {
|
|
|
66
66
|
|
|
67
67
|
export { useStudioWebAuth, getStudioWebAuth, getStudioWebAuthWithOrganizationId };
|
|
68
68
|
|
|
69
|
-
//# debugId=
|
|
69
|
+
//# debugId=FCF746C59C6BE72F64756E2164756E21
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {
|
|
2
|
+
catchError
|
|
3
|
+
} from "./packager-tool-6ybywxxn.js";
|
|
4
|
+
|
|
5
|
+
// src/services/pack-project-selection.ts
|
|
6
|
+
function validatePackProjectOptions(options) {
|
|
7
|
+
if (options.project !== undefined && options.project.trim() === "") {
|
|
8
|
+
return "--project was given an empty value.";
|
|
9
|
+
}
|
|
10
|
+
if (options.project !== undefined && options.name !== undefined) {
|
|
11
|
+
return "--name cannot be used together with --project: it names the solution package, and --project packs a project package. Use --package-id to name that.";
|
|
12
|
+
}
|
|
13
|
+
if (options.packageId === undefined) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (options.project === undefined) {
|
|
17
|
+
return "--package-id can only be used together with --project.";
|
|
18
|
+
}
|
|
19
|
+
if (options.packageId.trim() === "") {
|
|
20
|
+
return "--package-id was given an empty value.";
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class PackProjectError extends Error {
|
|
26
|
+
instructions;
|
|
27
|
+
errorCode = "invalid_argument";
|
|
28
|
+
constructor(message, instructions) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.instructions = instructions;
|
|
31
|
+
this.name = "PackProjectError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function resolvePackProjectAsync(fs, solutionDir, selector) {
|
|
35
|
+
const { projects, solutionName } = await readPackProjectEntriesAsync(fs, solutionDir);
|
|
36
|
+
const wanted = normalizeRelativePath(selector);
|
|
37
|
+
const byId = projects.filter((p) => p.id.toLowerCase() === selector.trim().toLowerCase());
|
|
38
|
+
const matches = byId.length > 0 ? byId : projects.filter((p) => {
|
|
39
|
+
const file = normalizeRelativePath(p.relativePath);
|
|
40
|
+
return wanted !== "" && (file === wanted || projectFolder(file) === wanted);
|
|
41
|
+
});
|
|
42
|
+
if (matches.length === 1) {
|
|
43
|
+
assertInsideSolution(fs, solutionDir, selector, matches[0]);
|
|
44
|
+
return { project: matches[0], solutionName };
|
|
45
|
+
}
|
|
46
|
+
throw new PackProjectError(matches.length === 0 ? `Project '${selector}' is not part of the solution.` : `Project '${selector}' matches more than one project of the solution.`, choicesInstructions(matches.length === 0 ? projects : matches));
|
|
47
|
+
}
|
|
48
|
+
function assertInsideSolution(fs, solutionDir, selector, project) {
|
|
49
|
+
const instructions = "Fix the project's ProjectRelativePath in the .uipx so it names a project file inside the solution folder, then rerun.";
|
|
50
|
+
if (project.relativePath.trim() === "") {
|
|
51
|
+
throw new PackProjectError(`Project '${selector}' has no ProjectRelativePath in the .uipx.`, instructions);
|
|
52
|
+
}
|
|
53
|
+
const relative = fs.path.relative(solutionDir, fs.path.resolve(solutionDir, projectFolder(project.relativePath)));
|
|
54
|
+
if (relative === ".." || relative.startsWith("../") || relative.startsWith("..\\") || fs.path.isAbsolute(relative)) {
|
|
55
|
+
throw new PackProjectError(`Project '${selector}' points outside the solution folder: '${project.relativePath}'.`, instructions);
|
|
56
|
+
}
|
|
57
|
+
if (relative === "") {
|
|
58
|
+
throw new PackProjectError(`Project '${selector}' sits at the solution root ('${project.relativePath}'), so packing it on its own would pack the whole solution with it.`, "Move the project into its own folder inside the solution, update its ProjectRelativePath in the .uipx to match, then rerun.");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function choicesInstructions(projects) {
|
|
62
|
+
if (projects.length === 0) {
|
|
63
|
+
return "The solution lists no projects. Add one with 'uip solution project add', then rerun.";
|
|
64
|
+
}
|
|
65
|
+
const choices = projects.map((p) => `'${projectFolder(p.relativePath) || p.relativePath}' (Id: ${p.id})`).join(", ");
|
|
66
|
+
return `Pass --project with one of the solution's project Ids or paths: ${choices}.`;
|
|
67
|
+
}
|
|
68
|
+
async function readPackProjectEntriesAsync(fs, solutionDir) {
|
|
69
|
+
const entries = await fs.readdir(solutionDir);
|
|
70
|
+
const uipxFile = entries.find((entry) => entry.endsWith(".uipx"));
|
|
71
|
+
if (!uipxFile) {
|
|
72
|
+
throw new PackProjectError(`No .uipx solution file found in ${solutionDir}.`, "Pass the solution folder, the one that contains the .uipx file.");
|
|
73
|
+
}
|
|
74
|
+
const content = await fs.readFile(fs.path.join(solutionDir, uipxFile), "utf-8");
|
|
75
|
+
const [parseError, manifest] = catchError(() => JSON.parse(content ?? ""));
|
|
76
|
+
if (parseError) {
|
|
77
|
+
throw new PackProjectError(`Failed to parse ${uipxFile}: ${parseError.message}`, `Fix the JSON in ${uipxFile}, then rerun.`);
|
|
78
|
+
}
|
|
79
|
+
const projects = [];
|
|
80
|
+
for (const raw of Array.isArray(manifest?.Projects) ? manifest.Projects : []) {
|
|
81
|
+
const entry = raw;
|
|
82
|
+
if (typeof entry?.Id !== "string" || !entry.Id)
|
|
83
|
+
continue;
|
|
84
|
+
projects.push({
|
|
85
|
+
id: entry.Id,
|
|
86
|
+
type: typeof entry.Type === "string" ? entry.Type : "",
|
|
87
|
+
relativePath: typeof entry.ProjectRelativePath === "string" ? entry.ProjectRelativePath : ""
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return { projects, solutionName: uipxFile.slice(0, -".uipx".length) };
|
|
91
|
+
}
|
|
92
|
+
function normalizeRelativePath(path) {
|
|
93
|
+
return path.trim().replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^(\.\/)+/, "").replace(/\/$/, "").toLowerCase();
|
|
94
|
+
}
|
|
95
|
+
function projectFolder(relativePath) {
|
|
96
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
97
|
+
const slash = normalized.lastIndexOf("/");
|
|
98
|
+
return slash === -1 ? "" : normalized.slice(0, slash);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { validatePackProjectOptions, PackProjectError, resolvePackProjectAsync, projectFolder };
|
|
102
|
+
|
|
103
|
+
//# debugId=A02E54BA1CA9A95764756E2164756E21
|