@uipath/packager-tool-workflowcompiler-browser 1.202.0-preview.140 → 1.202.0-preview.142
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/package.json +4 -8
- package/src/cleanup-result.ts +0 -7
- package/src/i18n/index.ts +0 -45
- package/src/i18n/locales/de.json +0 -36
- package/src/i18n/locales/en.ts +0 -69
- package/src/i18n/locales/es-MX.json +0 -36
- package/src/i18n/locales/es.json +0 -36
- package/src/i18n/locales/fr.json +0 -36
- package/src/i18n/locales/ja.json +0 -36
- package/src/i18n/locales/ko.json +0 -36
- package/src/i18n/locales/pt-BR.json +0 -36
- package/src/i18n/locales/pt.json +0 -36
- package/src/i18n/locales/ro.json +0 -36
- package/src/i18n/locales/ru.json +0 -36
- package/src/i18n/locales/tr.json +0 -36
- package/src/i18n/locales/zh-CN.json +0 -36
- package/src/i18n/locales/zh-TW.json +0 -36
- package/src/i18n/locales/zu.json +0 -36
- package/src/index.ts +0 -11
- package/src/pack-result-processor.ts +0 -307
- package/src/packager-hub-connection.ts +0 -241
- package/src/project-bundle-executor.ts +0 -783
- package/src/workflow-compiler-tool-factory.ts +0 -47
- package/src/workflow-compiler-tool.ts +0 -93
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"toolWorkflowCompilerBrowser": {
|
|
3
|
-
"info": {
|
|
4
|
-
"connectingToHub": "Connecting to SignalR hub: {url}",
|
|
5
|
-
"remoteAgentStartedExecution": "Remote agent started execution",
|
|
6
|
-
"downloadingArchive": "Downloading pack result archive from bucket {bucketId}",
|
|
7
|
-
"extractingArchive": "Extracting archive ({size} bytes) to {path}",
|
|
8
|
-
"distributingPackages": "Distributing packages for {count} project(s)",
|
|
9
|
-
"cleaningUpTempDir": "Cleaning up temporary directory {path}",
|
|
10
|
-
"deletingBucket": "Deleting temporary storage bucket {bucketId}",
|
|
11
|
-
"copyingFiles": "Copying {count} file(s) for project {designId} to {path}",
|
|
12
|
-
"offloadingInputArguments": "輸入引數過大({length} 個字元),無法內嵌傳送;將以檔案附件形式上傳"
|
|
13
|
-
},
|
|
14
|
-
"errors": {
|
|
15
|
-
"missingConnectionInfo": "Missing connection info (cloudUrl, accessToken, or folderId)",
|
|
16
|
-
"signalRConnectionFailed": "Failed to connect to SignalR hub",
|
|
17
|
-
"hubConnectionFailed": "Failed to connect to SignalR hub at {url}: {message}",
|
|
18
|
-
"packSucceededNoBucket": "Pack succeeded but no BucketId was returned",
|
|
19
|
-
"noResultForProject": "No result for project",
|
|
20
|
-
"beginSessionFailed": "BeginSession failed ({status}): {errorText}",
|
|
21
|
-
"hubConnectionClosed": "Hub connection closed unexpectedly",
|
|
22
|
-
"packAgentDisconnected": "Pack agent disconnected unexpectedly",
|
|
23
|
-
"deleteBucketFailed": "Unable to delete temporary storage bucket on Orchestrator: {statusText}",
|
|
24
|
-
"cleanupBucketFailed": "Unable to cleanup remote bucket {bucketId}: {message}",
|
|
25
|
-
"getBucketUriFailed": "Failed to get bucket read URI ({status}): {errorText}",
|
|
26
|
-
"downloadArchiveFailed": "Failed to download archive from bucket ({status}): {statusText}",
|
|
27
|
-
"noMatchingProject": "No matching project found for path: {projectPath}",
|
|
28
|
-
"noOutputForProject": "No output found for project {designId}",
|
|
29
|
-
"distributePackagesFailed": "Failed to distribute packages for {designId}: {message}",
|
|
30
|
-
"sessionTimeout": "Session timed out waiting for projects: received {received} of {expected} expected projects",
|
|
31
|
-
"createAttachmentFailed": "無法建立輸入引數附件 ({status}):{errorText}",
|
|
32
|
-
"attachmentResponseMalformed": "附件建立回應未包含 id 和 blob URI",
|
|
33
|
-
"uploadInputArgumentsFailed": "無法上傳輸入引數檔案 ({status}):{statusText}"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
package/src/i18n/locales/zu.json
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"toolWorkflowCompilerBrowser": {
|
|
3
|
-
"info": {
|
|
4
|
-
"connectingToHub": "Connecting to SignalR hub: {url}",
|
|
5
|
-
"remoteAgentStartedExecution": "Remote agent started execution",
|
|
6
|
-
"downloadingArchive": "Downloading pack result archive from bucket {bucketId}",
|
|
7
|
-
"extractingArchive": "Extracting archive ({size} bytes) to {path}",
|
|
8
|
-
"distributingPackages": "Distributing packages for {count} project(s)",
|
|
9
|
-
"cleaningUpTempDir": "Cleaning up temporary directory {path}",
|
|
10
|
-
"deletingBucket": "Deleting temporary storage bucket {bucketId}",
|
|
11
|
-
"copyingFiles": "Copying {count} file(s) for project {designId} to {path}",
|
|
12
|
-
"offloadingInputArguments": "Izimpikiswano zokufaka zinkulu kakhulu ({length} izinhlamvu) ukuze zithunyelwe ngaphakathi; zizolayishwa njengesinamathiselo sefayela"
|
|
13
|
-
},
|
|
14
|
-
"errors": {
|
|
15
|
-
"missingConnectionInfo": "Missing connection info (cloudUrl, accessToken, or folderId)",
|
|
16
|
-
"signalRConnectionFailed": "Failed to connect to SignalR hub",
|
|
17
|
-
"hubConnectionFailed": "Failed to connect to SignalR hub at {url}: {message}",
|
|
18
|
-
"packSucceededNoBucket": "Pack succeeded but no BucketId was returned",
|
|
19
|
-
"noResultForProject": "No result for project",
|
|
20
|
-
"beginSessionFailed": "BeginSession failed ({status}): {errorText}",
|
|
21
|
-
"hubConnectionClosed": "Hub connection closed unexpectedly",
|
|
22
|
-
"packAgentDisconnected": "Pack agent disconnected unexpectedly",
|
|
23
|
-
"deleteBucketFailed": "Unable to delete temporary storage bucket on Orchestrator: {statusText}",
|
|
24
|
-
"cleanupBucketFailed": "Unable to cleanup remote bucket {bucketId}: {message}",
|
|
25
|
-
"getBucketUriFailed": "Failed to get bucket read URI ({status}): {errorText}",
|
|
26
|
-
"downloadArchiveFailed": "Failed to download archive from bucket ({status}): {statusText}",
|
|
27
|
-
"noMatchingProject": "No matching project found for path: {projectPath}",
|
|
28
|
-
"noOutputForProject": "No output found for project {designId}",
|
|
29
|
-
"distributePackagesFailed": "Failed to distribute packages for {designId}: {message}",
|
|
30
|
-
"sessionTimeout": "Session timed out waiting for projects: received {received} of {expected} expected projects",
|
|
31
|
-
"createAttachmentFailed": "Yehlulekile ukudala isinamathiselo sezimpikiswano zokufaka ({status}): {errorText}",
|
|
32
|
-
"attachmentResponseMalformed": "Impendulo yokudala isinamathiselo ayifakanga i-id ne-blob URI",
|
|
33
|
-
"uploadInputArgumentsFailed": "Yehlulekile ukulayisha ifayela lezimpikiswano zokufaka ({status}): {statusText}"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import "./i18n/index.js";
|
|
2
|
-
|
|
3
|
-
// Tool-specific cleanup detail. Surfaced via `ProjectCleanupInfo.toolDetails`;
|
|
4
|
-
// only consumers that want WorkflowCompiler specifics import these types.
|
|
5
|
-
export type {
|
|
6
|
-
CleanedWorkflowDetail,
|
|
7
|
-
WorkflowCleanupDetails,
|
|
8
|
-
} from "./cleanup-result.js";
|
|
9
|
-
// Workflow Compiler (browser) tool factory. Consumers register it explicitly via
|
|
10
|
-
// `toolsFactoryRepository.registerProjectToolFactory(new WorkflowCompilerToolFactory())`.
|
|
11
|
-
export { WorkflowCompilerToolFactory } from "./workflow-compiler-tool-factory.js";
|
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ConnectionInfo,
|
|
3
|
-
type IFileSystem,
|
|
4
|
-
type IProjectPackOptions,
|
|
5
|
-
type IToolLogger,
|
|
6
|
-
type IZipService,
|
|
7
|
-
type ProjectOperationContext,
|
|
8
|
-
ToolErrorCodes,
|
|
9
|
-
ToolResult,
|
|
10
|
-
toRelativeUrl,
|
|
11
|
-
translate,
|
|
12
|
-
ZipService,
|
|
13
|
-
} from "@uipath/solutionpackager-tool-core";
|
|
14
|
-
|
|
15
|
-
interface BlobFileAccessDto {
|
|
16
|
-
Uri: string;
|
|
17
|
-
Verb: string;
|
|
18
|
-
Headers: Record<string, string>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface ProjectResultEntry {
|
|
22
|
-
options: IProjectPackOptions;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class PackResultProcessor {
|
|
26
|
-
constructor(
|
|
27
|
-
private readonly fileSystem: IFileSystem,
|
|
28
|
-
private readonly logger?: IToolLogger,
|
|
29
|
-
private readonly zipService: IZipService = new ZipService(fileSystem),
|
|
30
|
-
) {}
|
|
31
|
-
|
|
32
|
-
async processAsync(
|
|
33
|
-
bucketId: number,
|
|
34
|
-
projects: Map<string, ProjectResultEntry>,
|
|
35
|
-
context: ProjectOperationContext,
|
|
36
|
-
): Promise<Map<string, ToolResult>> {
|
|
37
|
-
const connection = context.connection!;
|
|
38
|
-
const results = new Map<string, ToolResult>();
|
|
39
|
-
const tempDir = await this.fileSystem.getTempDir();
|
|
40
|
-
const extractPath = `${tempDir}/pack-result-${context.id}`;
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
this.logger?.info(
|
|
44
|
-
translate.t(
|
|
45
|
-
"toolWorkflowCompilerBrowser.info.downloadingArchive",
|
|
46
|
-
{ bucketId },
|
|
47
|
-
),
|
|
48
|
-
);
|
|
49
|
-
const zipData = await this.downloadArchiveAsync(
|
|
50
|
-
bucketId,
|
|
51
|
-
connection,
|
|
52
|
-
);
|
|
53
|
-
this.logger?.info(
|
|
54
|
-
translate.t(
|
|
55
|
-
"toolWorkflowCompilerBrowser.info.extractingArchive",
|
|
56
|
-
{ size: zipData.length, path: extractPath },
|
|
57
|
-
),
|
|
58
|
-
);
|
|
59
|
-
await this.zipService.extractAsync(zipData, extractPath);
|
|
60
|
-
this.logger?.info(
|
|
61
|
-
translate.t(
|
|
62
|
-
"toolWorkflowCompilerBrowser.info.distributingPackages",
|
|
63
|
-
{ count: projects.size },
|
|
64
|
-
),
|
|
65
|
-
);
|
|
66
|
-
await this.distributePackages(
|
|
67
|
-
extractPath,
|
|
68
|
-
projects,
|
|
69
|
-
context,
|
|
70
|
-
results,
|
|
71
|
-
);
|
|
72
|
-
} catch (error) {
|
|
73
|
-
const message =
|
|
74
|
-
error instanceof Error ? error.message : String(error);
|
|
75
|
-
for (const [projectPath] of projects) {
|
|
76
|
-
if (!results.has(projectPath)) {
|
|
77
|
-
results.set(
|
|
78
|
-
projectPath,
|
|
79
|
-
ToolResult.error("PackResultError", message),
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} finally {
|
|
84
|
-
this.logger?.info(
|
|
85
|
-
translate.t(
|
|
86
|
-
"toolWorkflowCompilerBrowser.info.cleaningUpTempDir",
|
|
87
|
-
{ path: extractPath },
|
|
88
|
-
),
|
|
89
|
-
);
|
|
90
|
-
await this.fileSystem.rm(extractPath).catch(() => {});
|
|
91
|
-
await this.deleteBucketAsync(bucketId, connection);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return results;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private async downloadArchiveAsync(
|
|
98
|
-
bucketId: number,
|
|
99
|
-
connection: ConnectionInfo,
|
|
100
|
-
): Promise<Uint8Array> {
|
|
101
|
-
const blobAccess = await this.getReadUriAsync(bucketId, connection);
|
|
102
|
-
return await this.downloadBlobAsync(blobAccess);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private async deleteBucketAsync(
|
|
106
|
-
bucketId: number,
|
|
107
|
-
connection: ConnectionInfo,
|
|
108
|
-
): Promise<void> {
|
|
109
|
-
try {
|
|
110
|
-
if (!bucketId) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const baseUrl = toRelativeUrl(connection.cloudUrl!);
|
|
115
|
-
const url = `${baseUrl}/orchestrator_/odata/Buckets(${bucketId})`;
|
|
116
|
-
|
|
117
|
-
this.logger?.info(
|
|
118
|
-
translate.t("toolWorkflowCompilerBrowser.info.deletingBucket", {
|
|
119
|
-
bucketId,
|
|
120
|
-
}),
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const response = await fetch(url, {
|
|
124
|
-
method: "DELETE",
|
|
125
|
-
headers: {
|
|
126
|
-
Authorization: `Bearer ${connection.accessToken}`,
|
|
127
|
-
"X-UIPATH-OrganizationUnitId": connection.folderId ?? "",
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
if (!response.ok) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
translate.t(
|
|
134
|
-
"toolWorkflowCompilerBrowser.errors.deleteBucketFailed",
|
|
135
|
-
{ statusText: response.statusText },
|
|
136
|
-
),
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
} catch (error) {
|
|
140
|
-
const message =
|
|
141
|
-
error instanceof Error ? error.message : String(error);
|
|
142
|
-
this.logger?.warn(
|
|
143
|
-
translate.t(
|
|
144
|
-
"toolWorkflowCompilerBrowser.errors.cleanupBucketFailed",
|
|
145
|
-
{ bucketId, message },
|
|
146
|
-
),
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private async getReadUriAsync(
|
|
152
|
-
bucketId: number,
|
|
153
|
-
connection: ConnectionInfo,
|
|
154
|
-
): Promise<BlobFileAccessDto> {
|
|
155
|
-
const baseUrl = toRelativeUrl(connection.cloudUrl!);
|
|
156
|
-
const url =
|
|
157
|
-
`${baseUrl}/orchestrator_/odata/Buckets(${bucketId})` +
|
|
158
|
-
`/UiPath.Server.Configuration.OData.GetReadUri` +
|
|
159
|
-
`?path=rpa-packages.zip&expiryInMinutes=0`;
|
|
160
|
-
|
|
161
|
-
const response = await fetch(url, {
|
|
162
|
-
method: "GET",
|
|
163
|
-
headers: {
|
|
164
|
-
Authorization: `Bearer ${connection.accessToken}`,
|
|
165
|
-
"X-UIPATH-OrganizationUnitId": connection.folderId ?? "",
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
if (!response.ok) {
|
|
170
|
-
const errorText = await response.text();
|
|
171
|
-
throw new Error(
|
|
172
|
-
translate.t(
|
|
173
|
-
"toolWorkflowCompilerBrowser.errors.getBucketUriFailed",
|
|
174
|
-
{ status: response.status, errorText },
|
|
175
|
-
),
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return (await response.json()) as BlobFileAccessDto;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
private async downloadBlobAsync(
|
|
183
|
-
blobAccess: BlobFileAccessDto,
|
|
184
|
-
): Promise<Uint8Array> {
|
|
185
|
-
const headers: Record<string, string> = {};
|
|
186
|
-
if (blobAccess.Headers) {
|
|
187
|
-
for (const [key, value] of Object.entries(blobAccess.Headers)) {
|
|
188
|
-
headers[key] = value;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const response = await fetch(blobAccess.Uri, {
|
|
193
|
-
method: blobAccess.Verb || "GET",
|
|
194
|
-
headers,
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
if (!response.ok) {
|
|
198
|
-
throw new Error(
|
|
199
|
-
translate.t(
|
|
200
|
-
"toolWorkflowCompilerBrowser.errors.downloadArchiveFailed",
|
|
201
|
-
{
|
|
202
|
-
status: response.status,
|
|
203
|
-
statusText: response.statusText,
|
|
204
|
-
},
|
|
205
|
-
),
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const buffer = await response.arrayBuffer();
|
|
210
|
-
return new Uint8Array(buffer);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
private async distributePackages(
|
|
214
|
-
extractPath: string,
|
|
215
|
-
projects: Map<string, ProjectResultEntry>,
|
|
216
|
-
context: ProjectOperationContext,
|
|
217
|
-
results: Map<string, ToolResult>,
|
|
218
|
-
): Promise<void> {
|
|
219
|
-
for (const [projectPath, entry] of projects) {
|
|
220
|
-
const project = context.projects.find(
|
|
221
|
-
(p) => p.ProjectPath === projectPath,
|
|
222
|
-
);
|
|
223
|
-
|
|
224
|
-
if (!project) {
|
|
225
|
-
results.set(
|
|
226
|
-
projectPath,
|
|
227
|
-
ToolResult.error(
|
|
228
|
-
"PackResultError",
|
|
229
|
-
translate.t(
|
|
230
|
-
"toolWorkflowCompilerBrowser.errors.noMatchingProject",
|
|
231
|
-
{ projectPath },
|
|
232
|
-
),
|
|
233
|
-
),
|
|
234
|
-
);
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const designId = project.Id;
|
|
239
|
-
const projectFilesDir = `${extractPath}/${designId}`;
|
|
240
|
-
const outputPath = entry.options.outputPath;
|
|
241
|
-
|
|
242
|
-
try {
|
|
243
|
-
const exists = await this.fileSystem.exists(projectFilesDir);
|
|
244
|
-
if (!exists) {
|
|
245
|
-
results.set(
|
|
246
|
-
projectPath,
|
|
247
|
-
ToolResult.error(
|
|
248
|
-
"PackResultError",
|
|
249
|
-
translate.t(
|
|
250
|
-
"toolWorkflowCompilerBrowser.errors.noOutputForProject",
|
|
251
|
-
{ designId },
|
|
252
|
-
),
|
|
253
|
-
),
|
|
254
|
-
);
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const files = await this.fileSystem.readdir(projectFilesDir);
|
|
259
|
-
const outputFiles: string[] = [];
|
|
260
|
-
|
|
261
|
-
await this.fileSystem.mkdir(outputPath);
|
|
262
|
-
this.logger?.info(
|
|
263
|
-
translate.t(
|
|
264
|
-
"toolWorkflowCompilerBrowser.info.copyingFiles",
|
|
265
|
-
{
|
|
266
|
-
count: files.length,
|
|
267
|
-
designId,
|
|
268
|
-
path: outputPath,
|
|
269
|
-
},
|
|
270
|
-
),
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
for (const fileName of files) {
|
|
274
|
-
const srcFile = `${projectFilesDir}/${fileName}`;
|
|
275
|
-
const destFile = `${outputPath}/${fileName}`;
|
|
276
|
-
const data = await this.fileSystem.readFile(srcFile);
|
|
277
|
-
if (data) {
|
|
278
|
-
await this.fileSystem.writeFile(destFile, data);
|
|
279
|
-
outputFiles.push(destFile);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
results.set(
|
|
284
|
-
projectPath,
|
|
285
|
-
new ToolResult(
|
|
286
|
-
ToolErrorCodes.Success,
|
|
287
|
-
undefined,
|
|
288
|
-
outputFiles,
|
|
289
|
-
),
|
|
290
|
-
);
|
|
291
|
-
} catch (error) {
|
|
292
|
-
const message =
|
|
293
|
-
error instanceof Error ? error.message : String(error);
|
|
294
|
-
results.set(
|
|
295
|
-
projectPath,
|
|
296
|
-
ToolResult.error(
|
|
297
|
-
"PackResultError",
|
|
298
|
-
translate.t(
|
|
299
|
-
"toolWorkflowCompilerBrowser.errors.distributePackagesFailed",
|
|
300
|
-
{ designId, message },
|
|
301
|
-
),
|
|
302
|
-
),
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HttpTransportType,
|
|
3
|
-
type HubConnection,
|
|
4
|
-
HubConnectionBuilder,
|
|
5
|
-
HubConnectionState,
|
|
6
|
-
} from "@microsoft/signalr";
|
|
7
|
-
import {
|
|
8
|
-
type IToolLogger,
|
|
9
|
-
LogMessage,
|
|
10
|
-
translate,
|
|
11
|
-
} from "@uipath/solutionpackager-tool-core";
|
|
12
|
-
import type { RemoteProjectCleanup } from "./cleanup-result.js";
|
|
13
|
-
|
|
14
|
-
/** @public */
|
|
15
|
-
export enum CompletedStatus {
|
|
16
|
-
Succeeded = 0,
|
|
17
|
-
Stopped = 1,
|
|
18
|
-
Failed = 2,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface PackAgentResult {
|
|
22
|
-
errorCode: number;
|
|
23
|
-
status: CompletedStatus;
|
|
24
|
-
message?: string;
|
|
25
|
-
bucketId?: number;
|
|
26
|
-
/** Cleanup only: files changed per project design id, relative to each project. */
|
|
27
|
-
changedFilesByProject?: Record<string, string[]>;
|
|
28
|
-
/** Cleanup only: raw per-project cleanup payload, keyed by project design id. */
|
|
29
|
-
unusedDependenciesByProject?: Record<string, RemoteProjectCleanup>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface ExecutorCommand<T> {
|
|
33
|
-
Id: number;
|
|
34
|
-
Argument1: T;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface PackJobResult {
|
|
38
|
-
ErrorCode: number;
|
|
39
|
-
Status: number;
|
|
40
|
-
Message?: string;
|
|
41
|
-
BucketId?: number;
|
|
42
|
-
ChangedFilesByProject?: Record<string, string[]>;
|
|
43
|
-
UnusedDependenciesByProject?: Record<string, RemoteProjectCleanup>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
enum PackagerCommandType {
|
|
47
|
-
PeerDisconnected = "PeerDisconnected",
|
|
48
|
-
SetLogMessage = "SetLogMessage",
|
|
49
|
-
SetExecutionStarted = "SetExecutionStarted",
|
|
50
|
-
SetExecutionCompleted = "SetExecutionCompleted",
|
|
51
|
-
Stop = "Stop",
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export class PackagerHubConnection {
|
|
55
|
-
private hubConnection: HubConnection | null = null;
|
|
56
|
-
private completionResolve: ((result: PackAgentResult) => void) | null =
|
|
57
|
-
null;
|
|
58
|
-
private completionReject: ((error: Error) => void) | null = null;
|
|
59
|
-
|
|
60
|
-
constructor(private readonly logger?: IToolLogger) {}
|
|
61
|
-
|
|
62
|
-
async connectAsync(hubUrl: string, accessToken: string): Promise<void> {
|
|
63
|
-
try {
|
|
64
|
-
this.hubConnection = this.buildConnection(hubUrl, accessToken);
|
|
65
|
-
this.registerHandlers();
|
|
66
|
-
this.registerOnClose();
|
|
67
|
-
await this.hubConnection.start();
|
|
68
|
-
} catch (error) {
|
|
69
|
-
// Retry with SSE/LongPolling if WebSocket fails (matches StudioWeb pattern)
|
|
70
|
-
if (
|
|
71
|
-
error instanceof Error &&
|
|
72
|
-
error.message.toLowerCase().includes("websocket")
|
|
73
|
-
) {
|
|
74
|
-
this.hubConnection = this.buildConnection(
|
|
75
|
-
hubUrl,
|
|
76
|
-
accessToken,
|
|
77
|
-
true,
|
|
78
|
-
);
|
|
79
|
-
this.registerHandlers();
|
|
80
|
-
this.registerOnClose();
|
|
81
|
-
await this.hubConnection.start();
|
|
82
|
-
} else {
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private buildConnection(
|
|
89
|
-
hubUrl: string,
|
|
90
|
-
accessToken: string,
|
|
91
|
-
disableWs = false,
|
|
92
|
-
): HubConnection {
|
|
93
|
-
return new HubConnectionBuilder()
|
|
94
|
-
.withUrl(hubUrl, {
|
|
95
|
-
accessTokenFactory: () => accessToken,
|
|
96
|
-
transport: disableWs
|
|
97
|
-
? HttpTransportType.ServerSentEvents |
|
|
98
|
-
HttpTransportType.LongPolling
|
|
99
|
-
: undefined,
|
|
100
|
-
})
|
|
101
|
-
.withAutomaticReconnect()
|
|
102
|
-
.build();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private registerOnClose(): void {
|
|
106
|
-
this.hubConnection?.onclose((error) => {
|
|
107
|
-
this.logger?.info(
|
|
108
|
-
`[PackagerHub] onclose fired. error=${error?.message ?? "none"}, hasReject=${!!this.completionReject}, hasResolve=${!!this.completionResolve}`,
|
|
109
|
-
);
|
|
110
|
-
if (this.completionReject) {
|
|
111
|
-
this.completionReject(
|
|
112
|
-
error ??
|
|
113
|
-
new Error(
|
|
114
|
-
translate.t(
|
|
115
|
-
"toolWorkflowCompilerBrowser.errors.hubConnectionClosed",
|
|
116
|
-
),
|
|
117
|
-
),
|
|
118
|
-
);
|
|
119
|
-
this.completionResolve = null;
|
|
120
|
-
this.completionReject = null;
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
waitForCompletionAsync(): Promise<PackAgentResult> {
|
|
126
|
-
return new Promise<PackAgentResult>((resolve, reject) => {
|
|
127
|
-
this.completionResolve = resolve;
|
|
128
|
-
this.completionReject = reject;
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async disconnectAsync(): Promise<void> {
|
|
133
|
-
if (
|
|
134
|
-
this.hubConnection &&
|
|
135
|
-
this.hubConnection.state !== HubConnectionState.Disconnected
|
|
136
|
-
) {
|
|
137
|
-
await this.hubConnection.stop();
|
|
138
|
-
}
|
|
139
|
-
this.hubConnection = null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private registerHandlers(): void {
|
|
143
|
-
if (!this.hubConnection) return;
|
|
144
|
-
|
|
145
|
-
this.hubConnection.on(
|
|
146
|
-
PackagerCommandType.SetExecutionCompleted,
|
|
147
|
-
(jsonCommand: string) => {
|
|
148
|
-
this.onExecutionCompleted(jsonCommand);
|
|
149
|
-
},
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
this.hubConnection.on(
|
|
153
|
-
PackagerCommandType.SetLogMessage,
|
|
154
|
-
(jsonCommand: string) => {
|
|
155
|
-
this.onLogMessage(jsonCommand);
|
|
156
|
-
},
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
this.hubConnection.on(
|
|
160
|
-
PackagerCommandType.SetExecutionStarted,
|
|
161
|
-
(_jsonCommand: string) => {
|
|
162
|
-
this.logger?.info(
|
|
163
|
-
translate.t(
|
|
164
|
-
"toolWorkflowCompilerBrowser.info.remoteAgentStartedExecution",
|
|
165
|
-
),
|
|
166
|
-
);
|
|
167
|
-
},
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
this.hubConnection.on(PackagerCommandType.PeerDisconnected, () => {
|
|
171
|
-
this.logger?.info(
|
|
172
|
-
`[PackagerHub] PeerDisconnected received. hasReject=${!!this.completionReject}`,
|
|
173
|
-
);
|
|
174
|
-
if (this.completionReject) {
|
|
175
|
-
this.completionReject(
|
|
176
|
-
new Error(
|
|
177
|
-
translate.t(
|
|
178
|
-
"toolWorkflowCompilerBrowser.errors.packAgentDisconnected",
|
|
179
|
-
),
|
|
180
|
-
),
|
|
181
|
-
);
|
|
182
|
-
this.completionResolve = null;
|
|
183
|
-
this.completionReject = null;
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
private onLogMessage(jsonCommand: string): void {
|
|
189
|
-
if (!this.logger) return;
|
|
190
|
-
|
|
191
|
-
const command: ExecutorCommand<LogMessage> = JSON.parse(jsonCommand);
|
|
192
|
-
const agentLog = command.Argument1;
|
|
193
|
-
|
|
194
|
-
const logMessage = new LogMessage(
|
|
195
|
-
agentLog.message,
|
|
196
|
-
agentLog.logLevel,
|
|
197
|
-
{
|
|
198
|
-
source: agentLog.source,
|
|
199
|
-
sourceTarget: agentLog.sourceTarget,
|
|
200
|
-
progress: agentLog.progress,
|
|
201
|
-
code: agentLog.code,
|
|
202
|
-
filePath: agentLog.filePath,
|
|
203
|
-
line: agentLog.line,
|
|
204
|
-
id: agentLog.id,
|
|
205
|
-
},
|
|
206
|
-
agentLog.timestamp,
|
|
207
|
-
);
|
|
208
|
-
this.logger.logMessage(logMessage);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private onExecutionCompleted(jsonCommand: string): void {
|
|
212
|
-
this.logger?.info(
|
|
213
|
-
`[PackagerHub] onExecutionCompleted called. hasResolve=${!!this.completionResolve}, raw=${jsonCommand}`,
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
if (!this.completionResolve) {
|
|
217
|
-
this.logger?.warn(
|
|
218
|
-
`[PackagerHub] onExecutionCompleted: completionResolve is null, ignoring result`,
|
|
219
|
-
);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const command: ExecutorCommand<PackJobResult> = JSON.parse(jsonCommand);
|
|
224
|
-
const jobResult = command.Argument1;
|
|
225
|
-
|
|
226
|
-
this.logger?.info(
|
|
227
|
-
`[PackagerHub] onExecutionCompleted parsed: errorCode=${jobResult.ErrorCode}, status=${jobResult.Status}, message=${jobResult.Message}, bucketId=${jobResult.BucketId}`,
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
this.completionResolve({
|
|
231
|
-
errorCode: jobResult.ErrorCode,
|
|
232
|
-
status: jobResult.Status,
|
|
233
|
-
message: jobResult.Message,
|
|
234
|
-
bucketId: jobResult.BucketId,
|
|
235
|
-
changedFilesByProject: jobResult.ChangedFilesByProject,
|
|
236
|
-
unusedDependenciesByProject: jobResult.UnusedDependenciesByProject,
|
|
237
|
-
});
|
|
238
|
-
this.completionResolve = null;
|
|
239
|
-
this.completionReject = null;
|
|
240
|
-
}
|
|
241
|
-
}
|