@uipath/solution-sdk 1.204.0-preview.261 → 1.204.0-preview.264
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/resources/index.js
CHANGED
|
@@ -3334,6 +3334,19 @@ class NullSecretsProvider {
|
|
|
3334
3334
|
}
|
|
3335
3335
|
}
|
|
3336
3336
|
|
|
3337
|
+
// ../../node_modules/@uipath/resource-builder-sdk/dist/providers/feature-flag-provider.js
|
|
3338
|
+
class NullFeatureFlagProvider {
|
|
3339
|
+
getBool(_featureFlagName, defaultValue) {
|
|
3340
|
+
return defaultValue ?? false;
|
|
3341
|
+
}
|
|
3342
|
+
getInt(_featureFlagName, defaultValue) {
|
|
3343
|
+
return defaultValue ?? 0;
|
|
3344
|
+
}
|
|
3345
|
+
getString(_featureFlagName, defaultValue) {
|
|
3346
|
+
return defaultValue ?? "";
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
|
|
3337
3350
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/exceptions/timeout-exception.js
|
|
3338
3351
|
class TimeoutException extends Error {
|
|
3339
3352
|
constructor(message, timeoutMs) {
|
|
@@ -3488,10 +3501,12 @@ function withFileOperationTimeout2(provider, timeoutMs) {
|
|
|
3488
3501
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/solution/solution-context-options.js
|
|
3489
3502
|
var DEFAULT_SOLUTION_CONTEXT_OPTIONS = {
|
|
3490
3503
|
lockTimeoutMs: 30000,
|
|
3491
|
-
fileOperationTimeoutMs: 30000
|
|
3504
|
+
fileOperationTimeoutMs: 30000,
|
|
3505
|
+
maxDegreeOfParallelism: 1
|
|
3492
3506
|
};
|
|
3493
3507
|
var SOLUTION_CONTEXT_TIMEOUT_STORAGE_KEY = "SOL_RB_SOLUTION_CONTEXT_TIMEOUT_MS";
|
|
3494
3508
|
var FILE_OPERATION_TIMEOUT_STORAGE_KEY = "SOL_RB_FILE_OPERATION_TIMEOUT_MS";
|
|
3509
|
+
var MAX_DEGREE_OF_PARALLELISM_STORAGE_KEY = "SOL_RB_MAX_DEGREE_OF_PARALLELISM";
|
|
3495
3510
|
function resolveTimeoutMs(storageKey, configured, fallback) {
|
|
3496
3511
|
const override = readTimeoutOverrideMs(storageKey);
|
|
3497
3512
|
if (override !== undefined)
|
|
@@ -3504,10 +3519,33 @@ function resolveLockTimeoutMs(options) {
|
|
|
3504
3519
|
function resolveFileOperationTimeoutMs(options) {
|
|
3505
3520
|
return resolveTimeoutMs(FILE_OPERATION_TIMEOUT_STORAGE_KEY, options?.fileOperationTimeoutMs, DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs);
|
|
3506
3521
|
}
|
|
3522
|
+
function isValidDegreeOfParallelism(value) {
|
|
3523
|
+
return typeof value == "number" && Number.isInteger(value) && value > 0;
|
|
3524
|
+
}
|
|
3525
|
+
function resolveMaxDegreeOfParallelism(options) {
|
|
3526
|
+
const override = readDegreeOfParallelismOverride(MAX_DEGREE_OF_PARALLELISM_STORAGE_KEY);
|
|
3527
|
+
if (override !== undefined)
|
|
3528
|
+
return override;
|
|
3529
|
+
return isValidDegreeOfParallelism(options?.maxDegreeOfParallelism) ? options.maxDegreeOfParallelism : DEFAULT_SOLUTION_CONTEXT_OPTIONS.maxDegreeOfParallelism;
|
|
3530
|
+
}
|
|
3531
|
+
function readDegreeOfParallelismOverride(storageKey) {
|
|
3532
|
+
try {
|
|
3533
|
+
if ("u" < typeof localStorage)
|
|
3534
|
+
return;
|
|
3535
|
+
const raw = localStorage.getItem(storageKey);
|
|
3536
|
+
if (raw === null || raw.trim() === "")
|
|
3537
|
+
return;
|
|
3538
|
+
const parsed = Number(raw);
|
|
3539
|
+
return isValidDegreeOfParallelism(parsed) ? parsed : undefined;
|
|
3540
|
+
} catch {
|
|
3541
|
+
return;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3507
3544
|
function mergeSolutionContextOptions(options) {
|
|
3508
3545
|
return {
|
|
3509
3546
|
lockTimeoutMs: isValidTimeoutMs(options?.lockTimeoutMs) ? options.lockTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.lockTimeoutMs,
|
|
3510
|
-
fileOperationTimeoutMs: isValidTimeoutMs(options?.fileOperationTimeoutMs) ? options.fileOperationTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs
|
|
3547
|
+
fileOperationTimeoutMs: isValidTimeoutMs(options?.fileOperationTimeoutMs) ? options.fileOperationTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs,
|
|
3548
|
+
maxDegreeOfParallelism: isValidDegreeOfParallelism(options?.maxDegreeOfParallelism) ? options.maxDegreeOfParallelism : DEFAULT_SOLUTION_CONTEXT_OPTIONS.maxDegreeOfParallelism
|
|
3511
3549
|
};
|
|
3512
3550
|
}
|
|
3513
3551
|
|
|
@@ -4298,6 +4336,16 @@ function getRootFolder(solution) {
|
|
|
4298
4336
|
}
|
|
4299
4337
|
|
|
4300
4338
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/solution/multi-file-solution-definition-provider.js
|
|
4339
|
+
function nowMs() {
|
|
4340
|
+
return globalThis.performance?.now?.() ?? Date.now();
|
|
4341
|
+
}
|
|
4342
|
+
function round1(ms) {
|
|
4343
|
+
return Math.round(10 * ms) / 10;
|
|
4344
|
+
}
|
|
4345
|
+
function cancellationError(signal) {
|
|
4346
|
+
return signal?.reason instanceof OperationCancelledException ? signal.reason : new OperationCancelledException;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4301
4349
|
class MultiFileSolutionDefinitionProvider {
|
|
4302
4350
|
get caseInsensitiveSerializer() {
|
|
4303
4351
|
if (!this._caseInsensitiveSerializer)
|
|
@@ -4315,137 +4363,344 @@ class MultiFileSolutionDefinitionProvider {
|
|
|
4315
4363
|
}
|
|
4316
4364
|
async readAsync(context, cancellationToken) {
|
|
4317
4365
|
this.logger.info("Reading multi-file solution definition for solution %s", context.path);
|
|
4318
|
-
const
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
let
|
|
4323
|
-
let
|
|
4324
|
-
|
|
4325
|
-
let
|
|
4326
|
-
|
|
4366
|
+
const loadStarted = nowMs();
|
|
4367
|
+
let fileCount = 0;
|
|
4368
|
+
let listMs = 0;
|
|
4369
|
+
let readStarted = loadStarted;
|
|
4370
|
+
let readWallMs = 0;
|
|
4371
|
+
let readCompleted = false;
|
|
4372
|
+
let ioMs = 0;
|
|
4373
|
+
let maxFileIoMs = 0;
|
|
4374
|
+
let parseMs = 0;
|
|
4375
|
+
let hashMs = 0;
|
|
4376
|
+
let chars = 0;
|
|
4377
|
+
let loadedCount = 0;
|
|
4327
4378
|
const parseErrors = [];
|
|
4328
4379
|
const missingFiles = [];
|
|
4329
4380
|
const invalidFiles = [];
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4381
|
+
let metricsLogged = false;
|
|
4382
|
+
const logReadMetrics = (outcome) => {
|
|
4383
|
+
metricsLogged = true;
|
|
4384
|
+
const totalMs = nowMs() - loadStarted;
|
|
4385
|
+
const mergeMs = readCompleted ? nowMs() - readStarted - readWallMs : 0;
|
|
4386
|
+
const metrics = {
|
|
4387
|
+
outcome,
|
|
4388
|
+
path: context.path,
|
|
4389
|
+
fileCount,
|
|
4390
|
+
totalMs: round1(totalMs),
|
|
4391
|
+
listMs: round1(listMs),
|
|
4392
|
+
readWallMs: round1(readWallMs),
|
|
4393
|
+
ioMs: round1(ioMs),
|
|
4394
|
+
maxFileIoMs: round1(maxFileIoMs),
|
|
4395
|
+
parseMs: round1(parseMs),
|
|
4396
|
+
hashMs: round1(hashMs),
|
|
4397
|
+
mergeMs: round1(mergeMs),
|
|
4398
|
+
chars,
|
|
4399
|
+
degreeOfParallelism: resolveMaxDegreeOfParallelism(this.options),
|
|
4400
|
+
isReadOnly: context.isReadOnly,
|
|
4401
|
+
loaded: loadedCount,
|
|
4402
|
+
missing: missingFiles.length,
|
|
4403
|
+
invalid: invalidFiles.length,
|
|
4404
|
+
parseErrors: parseErrors.length
|
|
4405
|
+
};
|
|
4406
|
+
const message = `Solution read ${outcome} for solution ${context.path}: ${metrics.fileCount} files in ${metrics.totalMs} ms (list ${metrics.listMs} ms, read ${metrics.readWallMs} ms wall, io ${metrics.ioMs} ms summed, max file io ${metrics.maxFileIoMs} ms, parse ${metrics.parseMs} ms, hash ${metrics.hashMs} ms, merge ${metrics.mergeMs} ms); ${metrics.chars} chars; parallelism ${metrics.degreeOfParallelism}; readOnly ${metrics.isReadOnly}; loaded ${metrics.loaded}, missing ${metrics.missing}, invalid ${metrics.invalid}, parseErrors ${metrics.parseErrors}`;
|
|
4407
|
+
if (outcome === "Success")
|
|
4408
|
+
this.logger.info(message, metrics);
|
|
4409
|
+
else
|
|
4410
|
+
this.logger.warn(message, metrics);
|
|
4411
|
+
};
|
|
4412
|
+
const readCore = async () => {
|
|
4413
|
+
const solutionKey = this.getSolutionKey(context);
|
|
4414
|
+
const fileStorageProvider = await this.getFileStorageProviderAsync(context, cancellationToken);
|
|
4415
|
+
const resources = [];
|
|
4416
|
+
const solutionFiles = [];
|
|
4417
|
+
let hashes;
|
|
4418
|
+
let paths;
|
|
4419
|
+
const pathsByKind = this.getPathsByKind(context);
|
|
4420
|
+
let tree;
|
|
4421
|
+
pathsByKind.clear();
|
|
4422
|
+
context.items[SolutionContextKeys.PARSE_ERRORS_ITEM_KEY] = parseErrors;
|
|
4423
|
+
if (!context.isReadOnly) {
|
|
4424
|
+
hashes = this.getHashes(context);
|
|
4425
|
+
paths = this.getPaths(context);
|
|
4426
|
+
tree = this.getTree(context);
|
|
4427
|
+
hashes.clear();
|
|
4428
|
+
paths.clear();
|
|
4429
|
+
tree.length = 0;
|
|
4430
|
+
}
|
|
4431
|
+
const listStarted = nowMs();
|
|
4432
|
+
const resourceFiles = await fileStorageProvider.getFilesAsync(SolutionConstants.RESOURCE_FILES_FOLDER_NAME, "*.json", cancellationToken);
|
|
4433
|
+
listMs = nowMs() - listStarted;
|
|
4434
|
+
fileCount = resourceFiles.length;
|
|
4435
|
+
readStarted = nowMs();
|
|
4436
|
+
const readResults = await this.readResourceFilesAsync(context, fileStorageProvider, resourceFiles, cancellationToken);
|
|
4437
|
+
readWallMs = nowMs() - readStarted;
|
|
4438
|
+
readCompleted = true;
|
|
4439
|
+
let fatal;
|
|
4440
|
+
let hasFatal = false;
|
|
4441
|
+
for (const result of readResults)
|
|
4442
|
+
if (result !== undefined) {
|
|
4443
|
+
if (result.timings) {
|
|
4444
|
+
ioMs += result.timings.ioMs;
|
|
4445
|
+
maxFileIoMs = Math.max(maxFileIoMs, result.timings.ioMs);
|
|
4446
|
+
parseMs += result.timings.parseMs;
|
|
4447
|
+
hashMs += result.timings.hashMs;
|
|
4448
|
+
chars += result.timings.chars;
|
|
4449
|
+
}
|
|
4450
|
+
if (result.fatal !== undefined) {
|
|
4451
|
+
if (!hasFatal) {
|
|
4452
|
+
fatal = result.fatal;
|
|
4453
|
+
hasFatal = true;
|
|
4367
4454
|
}
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4455
|
+
continue;
|
|
4456
|
+
}
|
|
4457
|
+
if (!hasFatal)
|
|
4458
|
+
switch (result.outcome) {
|
|
4459
|
+
case "loaded": {
|
|
4460
|
+
loadedCount++;
|
|
4461
|
+
const rd = result.resource;
|
|
4462
|
+
for (const file of result.files)
|
|
4463
|
+
if (!solutionFiles.some((sf) => sf.name === file.name && sf.kind === file.kind))
|
|
4464
|
+
solutionFiles.push(file);
|
|
4465
|
+
resources.push(rd);
|
|
4466
|
+
const resourceKey = rd.key;
|
|
4467
|
+
const normalizedFullPath = result.normalizedPath;
|
|
4468
|
+
if (!pathsByKind.has(rd.kind))
|
|
4469
|
+
pathsByKind.set(rd.kind, []);
|
|
4470
|
+
const kindPaths = pathsByKind.get(rd.kind);
|
|
4471
|
+
if (kindPaths)
|
|
4472
|
+
kindPaths.push({
|
|
4473
|
+
name: rd.name,
|
|
4474
|
+
key: rd.key,
|
|
4475
|
+
path: normalizedFullPath
|
|
4476
|
+
});
|
|
4477
|
+
if (!context.isReadOnly && hashes && paths) {
|
|
4478
|
+
paths.set(resourceKey, normalizedFullPath);
|
|
4479
|
+
hashes.set(resourceKey, result.hash);
|
|
4480
|
+
}
|
|
4481
|
+
break;
|
|
4372
4482
|
}
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4483
|
+
case "missing":
|
|
4484
|
+
missingFiles.push(result.file);
|
|
4485
|
+
break;
|
|
4486
|
+
case "invalid":
|
|
4487
|
+
invalidFiles.push(result.file);
|
|
4488
|
+
break;
|
|
4489
|
+
case "parseError":
|
|
4490
|
+
parseErrors.push(result.file);
|
|
4491
|
+
break;
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
4494
|
+
if (hasFatal) {
|
|
4495
|
+
logReadMetrics("Fatal");
|
|
4496
|
+
throw fatal;
|
|
4497
|
+
}
|
|
4498
|
+
if (missingFiles.length > 0) {
|
|
4499
|
+
logReadMetrics("MissingFiles");
|
|
4500
|
+
throw new BadRequestException(ErrorCodes.Resources.MissingFileDependencies, `Solution has missing files: ${missingFiles.join(", ")}`);
|
|
4501
|
+
}
|
|
4502
|
+
if (invalidFiles.length > 0) {
|
|
4503
|
+
logReadMetrics("InvalidFiles");
|
|
4504
|
+
throw new BadRequestException(ErrorCodes.Resources.InvalidResourceFile, `Solution has resource files with invalid content: ${invalidFiles.join(", ")}`);
|
|
4505
|
+
}
|
|
4506
|
+
if (parseErrors.length > 0) {
|
|
4507
|
+
logReadMetrics("ParseErrors");
|
|
4508
|
+
throw new Error(`Failed to read resource files for solution ${context.path}: ${parseErrors.join(", ")}`);
|
|
4509
|
+
}
|
|
4510
|
+
const folderMap = new Map;
|
|
4511
|
+
const rootFolder = this.buildRootFolder(solutionKey, SolutionConstants.ROOT_FOLDER_NAME);
|
|
4512
|
+
folderMap.set(rootFolder.fullyQualifiedName.toLowerCase(), rootFolder);
|
|
4513
|
+
for (const res of resources)
|
|
4514
|
+
for (const fdep of res.folders ?? []) {
|
|
4515
|
+
const fqnLower = fdep.fullyQualifiedName.toLowerCase();
|
|
4516
|
+
if (!folderMap.has(fqnLower)) {
|
|
4517
|
+
const folderKey = this.generateGuidFromString(fdep.fullyQualifiedName);
|
|
4518
|
+
const pathSegments = fdep.fullyQualifiedName.split("/").filter((s) => s.length > 0).map((p) => {
|
|
4519
|
+
if (p.toLowerCase() !== SolutionConstants.ROOT_FOLDER_NAME.toLowerCase())
|
|
4520
|
+
return this.generateGuidFromString(SolutionConstants.ROOT_FOLDER_NAME);
|
|
4521
|
+
return rootFolder.key;
|
|
4522
|
+
});
|
|
4523
|
+
const folderPath = pathSegments.join(".");
|
|
4524
|
+
folderMap.set(fqnLower, {
|
|
4525
|
+
key: folderKey,
|
|
4526
|
+
fullyQualifiedName: fdep.fullyQualifiedName,
|
|
4527
|
+
path: folderPath
|
|
4385
4528
|
});
|
|
4386
|
-
if (!context.isReadOnly && hashes && paths) {
|
|
4387
|
-
paths.set(resourceKey, normalizedFullPath);
|
|
4388
|
-
hashes.set(resourceKey, await this.computeHash(content));
|
|
4389
4529
|
}
|
|
4390
|
-
} else {
|
|
4391
|
-
this.logger.error("Failed to read resource file %s for solution %s: invalid content", undefined, resourceFile, context.path);
|
|
4392
|
-
invalidFiles.push(resourceFile);
|
|
4393
|
-
}
|
|
4394
|
-
} catch (ex) {
|
|
4395
|
-
if (ex instanceof OperationCancelledException || cancellationToken?.aborted) {
|
|
4396
|
-
this.logger.warn("Operation cancelled while reading file %s for solution %s", resourceFile, context.path);
|
|
4397
|
-
throw ex instanceof OperationCancelledException ? ex : new OperationCancelledException;
|
|
4398
|
-
}
|
|
4399
|
-
if (ex instanceof TimeoutException)
|
|
4400
|
-
throw new TimeoutException(`Reading resource file ${resourceFile} for solution ${context.path} timed out: ${ex.message}`, ex.timeoutMs);
|
|
4401
|
-
if (isFileNotFoundError(ex)) {
|
|
4402
|
-
this.logger.warn("Resource file listed but missing in storage for solution %s: %s", resourceFile, context.path);
|
|
4403
|
-
missingFiles.push(resourceFile);
|
|
4404
|
-
} else {
|
|
4405
|
-
this.logger.error("Failed to read resource file %s for solution %s", ex, resourceFile, context.path);
|
|
4406
|
-
parseErrors.push(resourceFile);
|
|
4407
4530
|
}
|
|
4531
|
+
const solution = {
|
|
4532
|
+
key: solutionKey,
|
|
4533
|
+
docVersion: SolutionConstants.CURRENT_DOC_VERSION,
|
|
4534
|
+
folders: Array.from(folderMap.values()),
|
|
4535
|
+
resources,
|
|
4536
|
+
files: solutionFiles
|
|
4537
|
+
};
|
|
4538
|
+
await this.replaceDuplicateKeysAsync(solution, cancellationToken);
|
|
4539
|
+
if (!context.isReadOnly && tree) {
|
|
4540
|
+
const orderedResourceKeys = getTopologicalIdsOrdering(buildDependencyGraph(solution.resources));
|
|
4541
|
+
tree.push(...orderedResourceKeys);
|
|
4408
4542
|
}
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4543
|
+
logReadMetrics("Success");
|
|
4544
|
+
return solution;
|
|
4545
|
+
};
|
|
4546
|
+
try {
|
|
4547
|
+
return await readCore();
|
|
4548
|
+
} catch (ex) {
|
|
4549
|
+
if (!metricsLogged)
|
|
4550
|
+
logReadMetrics("Fatal");
|
|
4551
|
+
throw ex;
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4554
|
+
async readResourceFilesAsync(context, fileStorageProvider, resourceFiles, cancellationToken) {
|
|
4555
|
+
const results = Array.from({
|
|
4556
|
+
length: resourceFiles.length
|
|
4557
|
+
}, () => {
|
|
4558
|
+
return;
|
|
4559
|
+
});
|
|
4560
|
+
if (resourceFiles.length === 0)
|
|
4561
|
+
return results;
|
|
4562
|
+
const computeHash = !context.isReadOnly;
|
|
4563
|
+
const degreeOfParallelism = Math.min(resolveMaxDegreeOfParallelism(this.options), resourceFiles.length);
|
|
4564
|
+
let nextIndex = 0;
|
|
4565
|
+
let stopRequested = false;
|
|
4566
|
+
const runWorkerAsync = async () => {
|
|
4567
|
+
while (!stopRequested && nextIndex < resourceFiles.length) {
|
|
4568
|
+
const index = nextIndex++;
|
|
4569
|
+
const resourceFile = resourceFiles[index];
|
|
4570
|
+
const result = await this.readResourceFileAsync(context, fileStorageProvider, resourceFile, computeHash, cancellationToken);
|
|
4571
|
+
results[index] = result;
|
|
4572
|
+
if (result.fatal !== undefined)
|
|
4573
|
+
stopRequested = true;
|
|
4435
4574
|
}
|
|
4436
|
-
const solution = {
|
|
4437
|
-
key: solutionKey,
|
|
4438
|
-
docVersion: SolutionConstants.CURRENT_DOC_VERSION,
|
|
4439
|
-
folders: Array.from(folderMap.values()),
|
|
4440
|
-
resources,
|
|
4441
|
-
files: solutionFiles
|
|
4442
4575
|
};
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4576
|
+
const workers = [];
|
|
4577
|
+
for (let i = 0;i < degreeOfParallelism; i++)
|
|
4578
|
+
workers.push(runWorkerAsync());
|
|
4579
|
+
await Promise.all(workers);
|
|
4580
|
+
if (cancellationToken?.aborted && !results.some((result) => result?.fatal !== undefined))
|
|
4581
|
+
throw cancellationError(cancellationToken);
|
|
4582
|
+
return results;
|
|
4583
|
+
}
|
|
4584
|
+
async readResourceFileAsync(context, fileStorageProvider, resourceFile, computeHash, cancellationToken) {
|
|
4585
|
+
const started = nowMs();
|
|
4586
|
+
let ioMs;
|
|
4587
|
+
let content;
|
|
4588
|
+
const failureTimings = () => {
|
|
4589
|
+
const elapsed = nowMs() - started;
|
|
4590
|
+
return ioMs === undefined ? {
|
|
4591
|
+
ioMs: elapsed,
|
|
4592
|
+
parseMs: 0,
|
|
4593
|
+
hashMs: 0,
|
|
4594
|
+
chars: 0
|
|
4595
|
+
} : {
|
|
4596
|
+
ioMs,
|
|
4597
|
+
parseMs: elapsed - ioMs,
|
|
4598
|
+
hashMs: 0,
|
|
4599
|
+
chars: content?.length ?? 0
|
|
4600
|
+
};
|
|
4601
|
+
};
|
|
4602
|
+
try {
|
|
4603
|
+
if (cancellationToken?.aborted)
|
|
4604
|
+
throw cancellationError(cancellationToken);
|
|
4605
|
+
const stream = await fileStorageProvider.openFileAsync(resourceFile, cancellationToken);
|
|
4606
|
+
content = await this.streamToString(stream);
|
|
4607
|
+
ioMs = nowMs() - started;
|
|
4608
|
+
const parseStarted = nowMs();
|
|
4609
|
+
const wrapper = this.caseInsensitiveSerializer.deserialize(content);
|
|
4610
|
+
if (!wrapper?.resource) {
|
|
4611
|
+
this.logger.error("Failed to read resource file %s for solution %s: invalid content", undefined, resourceFile, context.path);
|
|
4612
|
+
return {
|
|
4613
|
+
file: resourceFile,
|
|
4614
|
+
outcome: "invalid",
|
|
4615
|
+
timings: failureTimings()
|
|
4616
|
+
};
|
|
4617
|
+
}
|
|
4618
|
+
const files = [];
|
|
4619
|
+
const rd = this.fromSerializable(wrapper.resource, files);
|
|
4620
|
+
this.applyFolders(rd, resourceFile);
|
|
4621
|
+
const parseMs = nowMs() - parseStarted;
|
|
4622
|
+
let hash;
|
|
4623
|
+
let hashMs = 0;
|
|
4624
|
+
if (computeHash) {
|
|
4625
|
+
const hashStarted = nowMs();
|
|
4626
|
+
hash = await this.computeHash(content);
|
|
4627
|
+
hashMs = nowMs() - hashStarted;
|
|
4628
|
+
}
|
|
4629
|
+
return {
|
|
4630
|
+
file: resourceFile,
|
|
4631
|
+
outcome: "loaded",
|
|
4632
|
+
resource: rd,
|
|
4633
|
+
files,
|
|
4634
|
+
normalizedPath: this.getNormalizedPath(resourceFile),
|
|
4635
|
+
hash,
|
|
4636
|
+
timings: {
|
|
4637
|
+
ioMs,
|
|
4638
|
+
parseMs,
|
|
4639
|
+
hashMs,
|
|
4640
|
+
chars: content.length
|
|
4641
|
+
}
|
|
4642
|
+
};
|
|
4643
|
+
} catch (ex) {
|
|
4644
|
+
if (ex instanceof OperationCancelledException || cancellationToken?.aborted) {
|
|
4645
|
+
this.logger.warn("Operation cancelled while reading file %s for solution %s", resourceFile, context.path);
|
|
4646
|
+
return {
|
|
4647
|
+
file: resourceFile,
|
|
4648
|
+
outcome: "fatal",
|
|
4649
|
+
fatal: ex instanceof OperationCancelledException ? ex : cancellationError(cancellationToken),
|
|
4650
|
+
timings: failureTimings()
|
|
4651
|
+
};
|
|
4652
|
+
}
|
|
4653
|
+
if (ex instanceof TimeoutException)
|
|
4654
|
+
return {
|
|
4655
|
+
file: resourceFile,
|
|
4656
|
+
outcome: "fatal",
|
|
4657
|
+
fatal: new TimeoutException(`Reading resource file ${resourceFile} for solution ${context.path} timed out: ${ex.message}`, ex.timeoutMs),
|
|
4658
|
+
timings: failureTimings()
|
|
4659
|
+
};
|
|
4660
|
+
if (isFileNotFoundError(ex)) {
|
|
4661
|
+
this.logger.warn("Resource file listed but missing in storage for solution %s: %s", resourceFile, context.path);
|
|
4662
|
+
return {
|
|
4663
|
+
file: resourceFile,
|
|
4664
|
+
outcome: "missing",
|
|
4665
|
+
timings: failureTimings()
|
|
4666
|
+
};
|
|
4667
|
+
}
|
|
4668
|
+
this.logger.error("Failed to read resource file %s for solution %s", ex, resourceFile, context.path);
|
|
4669
|
+
return {
|
|
4670
|
+
file: resourceFile,
|
|
4671
|
+
outcome: "parseError",
|
|
4672
|
+
timings: failureTimings()
|
|
4673
|
+
};
|
|
4447
4674
|
}
|
|
4448
|
-
|
|
4675
|
+
}
|
|
4676
|
+
applyFolders(resource, resourceFile) {
|
|
4677
|
+
const relPath = resourceFile.replace(/\\/g, "/");
|
|
4678
|
+
const segments = relPath.split("/").filter((s) => s.length > 0);
|
|
4679
|
+
const firstSegment = segments[0];
|
|
4680
|
+
if (segments.length >= 3 && firstSegment && firstSegment.toLowerCase() === SolutionConstants.RESOURCE_FILES_FOLDER_NAME.toLowerCase()) {
|
|
4681
|
+
const hasType = !!resource.type;
|
|
4682
|
+
const folderSegmentCount = hasType ? segments.length - 3 : segments.length - 2;
|
|
4683
|
+
if (folderSegmentCount < 1)
|
|
4684
|
+
resource.folders = [
|
|
4685
|
+
{
|
|
4686
|
+
fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
|
|
4687
|
+
}
|
|
4688
|
+
];
|
|
4689
|
+
else {
|
|
4690
|
+
const segmentsToUse = segments.slice(1, folderSegmentCount);
|
|
4691
|
+
const folderFqn = segmentsToUse.join("/");
|
|
4692
|
+
resource.folders = [
|
|
4693
|
+
{
|
|
4694
|
+
fullyQualifiedName: folderFqn
|
|
4695
|
+
}
|
|
4696
|
+
];
|
|
4697
|
+
}
|
|
4698
|
+
} else
|
|
4699
|
+
resource.folders = [
|
|
4700
|
+
{
|
|
4701
|
+
fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
|
|
4702
|
+
}
|
|
4703
|
+
];
|
|
4449
4704
|
}
|
|
4450
4705
|
async writeAsync(context, solution, cancellationToken) {
|
|
4451
4706
|
if (context.isReadOnly)
|
|
@@ -4750,7 +5005,7 @@ class MultiFileSolutionDefinitionFactory {
|
|
|
4750
5005
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/embedded-files-default.js
|
|
4751
5006
|
async function createDefaultEmbeddedFileReaderAsync() {
|
|
4752
5007
|
const [{ EmbeddedFileReader }, { JsonSerializerFactory: JsonSerializerFactory2 }] = await Promise.all([
|
|
4753
|
-
import("../embedded-file-reader-
|
|
5008
|
+
import("../embedded-file-reader-z4becc02.js"),
|
|
4754
5009
|
import("../index-dqa169gp.js")
|
|
4755
5010
|
]);
|
|
4756
5011
|
return new EmbeddedFileReader(new JsonSerializerFactory2);
|
|
@@ -4768,6 +5023,7 @@ var ServiceTokens = {
|
|
|
4768
5023
|
SecretsProvider: "ISecretsProvider",
|
|
4769
5024
|
FileStorageProviderFactory: "IFileStorageProviderFactory",
|
|
4770
5025
|
IpRangeBypassSecretProvider: "IIpRangeBypassSecretProvider",
|
|
5026
|
+
FeatureFlagProvider: "IFeatureFlagProvider",
|
|
4771
5027
|
SolutionDefinitionProvider: "ISolutionDefinitionProvider",
|
|
4772
5028
|
SolutionDefinitionFactory: "ISolutionDefinitionFactory",
|
|
4773
5029
|
ArtifactResourceSpecEnhancer: "IArtifactResourceSpecEnhancer",
|
|
@@ -5118,6 +5374,9 @@ function getBindingType(resourceKind, resourceType) {
|
|
|
5118
5374
|
}
|
|
5119
5375
|
|
|
5120
5376
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/bindings-metadata-serializer.js
|
|
5377
|
+
var SUPPORTED_SCHEMA_MAJOR_VERSION = 2;
|
|
5378
|
+
var INT32_MAX_VALUE = 2147483647;
|
|
5379
|
+
|
|
5121
5380
|
class BindingsMetadataSerializer {
|
|
5122
5381
|
tryDeserialize(input) {
|
|
5123
5382
|
if (!input)
|
|
@@ -5128,30 +5387,52 @@ class BindingsMetadataSerializer {
|
|
|
5128
5387
|
let cleanInput = input.charCodeAt(0) === 65279 ? input.slice(1) : input;
|
|
5129
5388
|
if (cleanInput.charCodeAt(cleanInput.length - 1) === 26)
|
|
5130
5389
|
cleanInput = cleanInput.slice(0, -1);
|
|
5131
|
-
const
|
|
5390
|
+
const root = JSON.parse(cleanInput);
|
|
5391
|
+
if (root === null || typeof root != "object" || Array.isArray(root)) {
|
|
5392
|
+
this.logger.warn("Invalid bindings: content is not a JSON object");
|
|
5393
|
+
return {
|
|
5394
|
+
success: false
|
|
5395
|
+
};
|
|
5396
|
+
}
|
|
5397
|
+
const jsonObject = root;
|
|
5132
5398
|
const versionValue = jsonObject[BindingsKnownKeys.Version];
|
|
5133
|
-
if (
|
|
5399
|
+
if (typeof versionValue != "string") {
|
|
5400
|
+
this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Version}' is missing or not a string`);
|
|
5134
5401
|
return {
|
|
5135
5402
|
success: false
|
|
5136
5403
|
};
|
|
5137
|
-
|
|
5138
|
-
const majorVersion =
|
|
5139
|
-
if (majorVersion
|
|
5140
|
-
|
|
5404
|
+
}
|
|
5405
|
+
const majorVersion = BindingsMetadataSerializer.tryParseMajorVersion(versionValue);
|
|
5406
|
+
if (majorVersion === undefined) {
|
|
5407
|
+
this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Version}' is not a valid version`);
|
|
5408
|
+
return {
|
|
5409
|
+
success: false
|
|
5410
|
+
};
|
|
5411
|
+
}
|
|
5412
|
+
if (majorVersion !== SUPPORTED_SCHEMA_MAJOR_VERSION) {
|
|
5413
|
+
this.logger.warn(`Invalid bindings: unsupported schema major version ${majorVersion}`);
|
|
5414
|
+
return {
|
|
5415
|
+
success: false
|
|
5416
|
+
};
|
|
5417
|
+
}
|
|
5418
|
+
const resources = jsonObject[BindingsKnownKeys.Resources];
|
|
5419
|
+
if (!Array.isArray(resources)) {
|
|
5420
|
+
this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Resources}' is missing or not an array`);
|
|
5421
|
+
return {
|
|
5422
|
+
success: false
|
|
5423
|
+
};
|
|
5424
|
+
}
|
|
5141
5425
|
const metadata = {
|
|
5142
5426
|
version: versionValue,
|
|
5143
5427
|
resources: []
|
|
5144
5428
|
};
|
|
5145
|
-
const resources
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
this.logger.warn("Skipping null bindings resource element");
|
|
5150
|
-
continue;
|
|
5151
|
-
}
|
|
5152
|
-
const resource = this.getBindingsResourceV2(resourceElement);
|
|
5153
|
-
metadata.resources.push(resource);
|
|
5429
|
+
for (const resourceElement of resources) {
|
|
5430
|
+
if (resourceElement == null) {
|
|
5431
|
+
this.logger.warn("Skipping null bindings resource element");
|
|
5432
|
+
continue;
|
|
5154
5433
|
}
|
|
5434
|
+
metadata.resources.push(this.getBindingsResourceV2(resourceElement));
|
|
5435
|
+
}
|
|
5155
5436
|
this.linkDependencies(metadata.resources);
|
|
5156
5437
|
return {
|
|
5157
5438
|
success: true,
|
|
@@ -5164,6 +5445,22 @@ class BindingsMetadataSerializer {
|
|
|
5164
5445
|
};
|
|
5165
5446
|
}
|
|
5166
5447
|
}
|
|
5448
|
+
static tryParseMajorVersion(value) {
|
|
5449
|
+
const parts = value.split(".");
|
|
5450
|
+
if (parts.length < 2 || parts.length > 4)
|
|
5451
|
+
return;
|
|
5452
|
+
let major;
|
|
5453
|
+
for (const [index, part] of parts.entries()) {
|
|
5454
|
+
if (!/^\s*[+-]?\d+\s*$/.test(part))
|
|
5455
|
+
return;
|
|
5456
|
+
const component = Number(part);
|
|
5457
|
+
if (component < 0 || component > INT32_MAX_VALUE)
|
|
5458
|
+
return;
|
|
5459
|
+
if (index === 0)
|
|
5460
|
+
major = component === 0 ? 0 : component;
|
|
5461
|
+
}
|
|
5462
|
+
return major;
|
|
5463
|
+
}
|
|
5167
5464
|
linkDependencies(resources) {
|
|
5168
5465
|
for (const resource of resources) {
|
|
5169
5466
|
const propertyMeta = resource.metadata;
|
|
@@ -5323,6 +5620,62 @@ class BindingOverwritesMappingRequest {
|
|
|
5323
5620
|
}
|
|
5324
5621
|
}
|
|
5325
5622
|
|
|
5623
|
+
// ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/jit-debug-project-types.js
|
|
5624
|
+
var JIT_DEBUG_PROJECT_TYPES_FEATURE_FLAG = "FE.JitDebugProjectTypes";
|
|
5625
|
+
var PROCESS_KIND = "process";
|
|
5626
|
+
var BUSINESS_RULE_KIND = "businessrule";
|
|
5627
|
+
var APP_KIND = "app";
|
|
5628
|
+
var LOW_CODE_APP_PROJECT_TYPE = "webapp";
|
|
5629
|
+
var LOW_CODE_APP_TYPES = new Set([
|
|
5630
|
+
"workflow action"
|
|
5631
|
+
]);
|
|
5632
|
+
var CODED_APP_PROJECT_TYPE = "appv2";
|
|
5633
|
+
var CODED_APP_TYPES = new Set([
|
|
5634
|
+
"coded",
|
|
5635
|
+
"codedaction"
|
|
5636
|
+
]);
|
|
5637
|
+
var DEFAULT_PROCESS_PROJECT_TYPE = "process";
|
|
5638
|
+
var KNOWN_PROCESS_PROJECT_TYPES = new Set([
|
|
5639
|
+
DEFAULT_PROCESS_PROJECT_TYPE,
|
|
5640
|
+
"processorchestration",
|
|
5641
|
+
"agent",
|
|
5642
|
+
"api",
|
|
5643
|
+
"flow",
|
|
5644
|
+
"function",
|
|
5645
|
+
"casemanagement",
|
|
5646
|
+
"webapp",
|
|
5647
|
+
"businessrules"
|
|
5648
|
+
]);
|
|
5649
|
+
var BUSINESS_RULE_PROJECT_TYPE = "businessrules";
|
|
5650
|
+
function parseJitDebugProjectTypes(flagValue) {
|
|
5651
|
+
if (!flagValue || !flagValue.trim())
|
|
5652
|
+
return [];
|
|
5653
|
+
return flagValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
5654
|
+
}
|
|
5655
|
+
function solutionSupportsJitDebug(solution, flagValue) {
|
|
5656
|
+
const enabledProjectTypes = parseJitDebugProjectTypes(flagValue).map((t) => t.toLowerCase());
|
|
5657
|
+
if (enabledProjectTypes.length === 0)
|
|
5658
|
+
return false;
|
|
5659
|
+
return (solution.resources ?? []).filter((r) => (r.projectKey != null || r.isArtefactResource === true) && isDecisionKind(r.kind)).every((r) => enabledProjectTypes.some((projectType) => matches(projectType, r)));
|
|
5660
|
+
}
|
|
5661
|
+
function isDecisionKind(kind) {
|
|
5662
|
+
const normalized = (kind ?? "").toLowerCase();
|
|
5663
|
+
return normalized === PROCESS_KIND || normalized === BUSINESS_RULE_KIND || normalized === APP_KIND;
|
|
5664
|
+
}
|
|
5665
|
+
function matches(projectType, resource) {
|
|
5666
|
+
if ((resource.kind ?? "").toLowerCase() === BUSINESS_RULE_KIND)
|
|
5667
|
+
return projectType === BUSINESS_RULE_PROJECT_TYPE;
|
|
5668
|
+
if ((resource.kind ?? "").toLowerCase() === APP_KIND) {
|
|
5669
|
+
const appType = (resource.type ?? "").toLowerCase();
|
|
5670
|
+
if (appType === "" || LOW_CODE_APP_TYPES.has(appType))
|
|
5671
|
+
return projectType === LOW_CODE_APP_PROJECT_TYPE;
|
|
5672
|
+
return CODED_APP_TYPES.has(appType) && projectType === CODED_APP_PROJECT_TYPE;
|
|
5673
|
+
}
|
|
5674
|
+
const resourceType = (resource.type ?? "").toLowerCase();
|
|
5675
|
+
const processType = resourceType === "" ? DEFAULT_PROCESS_PROJECT_TYPE : resourceType;
|
|
5676
|
+
return !KNOWN_PROCESS_PROJECT_TYPES.has(processType) || projectType === processType;
|
|
5677
|
+
}
|
|
5678
|
+
|
|
5326
5679
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/binding-overwrites-handler.js
|
|
5327
5680
|
class BindingOverwritesHandler {
|
|
5328
5681
|
async handleAsync(request, cancellationToken) {
|
|
@@ -5338,6 +5691,10 @@ class BindingOverwritesHandler {
|
|
|
5338
5691
|
if (bindingResources.length === 0)
|
|
5339
5692
|
return {};
|
|
5340
5693
|
const result = {};
|
|
5694
|
+
const solution = await request.context.loadAsync(cancellationToken);
|
|
5695
|
+
const jitDebugProjectTypes = this.featureFlagProvider.getString(JIT_DEBUG_PROJECT_TYPES_FEATURE_FLAG, "");
|
|
5696
|
+
const emptyFolderPathForArtefacts = solutionSupportsJitDebug(solution, jitDebugProjectTypes);
|
|
5697
|
+
this.logger.info(`Binding overwrites for solution ${request.context.path}: JIT debug ${emptyFolderPathForArtefacts ? "on" : "off"} (FE.JitDebugProjectTypes = '${jitDebugProjectTypes}')`);
|
|
5341
5698
|
const resourceOverwrites = await this.resourceOverwritesService.getResourceOverwritesAsync(request.context, cancellationToken);
|
|
5342
5699
|
for (const bindingResource of bindingResources) {
|
|
5343
5700
|
const resourceOverwrite = resourceOverwrites.get(bindingResource.resourceKey.toLowerCase());
|
|
@@ -5350,8 +5707,7 @@ class BindingOverwritesHandler {
|
|
|
5350
5707
|
[BindingsKnownKeys.FolderKeyPropertyName]: resourceOverwrite.folderKey ?? ""
|
|
5351
5708
|
};
|
|
5352
5709
|
else {
|
|
5353
|
-
const
|
|
5354
|
-
const folderPath = bindingResource.isArtefactResource && !isBusinessRule ? "" : resourceOverwrite.folderFullyQualifiedName ?? "";
|
|
5710
|
+
const folderPath = emptyFolderPathForArtefacts && bindingResource.isArtefactResource ? "" : resourceOverwrite.folderFullyQualifiedName ?? "";
|
|
5355
5711
|
overwrite = {
|
|
5356
5712
|
[BindingsKnownKeys.FolderPathPropertyName]: folderPath,
|
|
5357
5713
|
[BindingsKnownKeys.NamePropertyName]: resourceOverwrite.resourceName
|
|
@@ -5373,9 +5729,10 @@ class BindingOverwritesHandler {
|
|
|
5373
5729
|
throw new BadRequestException("Bindings.ValidationFailed", `Binding validation failed: ${failureMessages}`);
|
|
5374
5730
|
}
|
|
5375
5731
|
}
|
|
5376
|
-
constructor(mediator, resourceOverwritesService, loggerFactory) {
|
|
5732
|
+
constructor(mediator, resourceOverwritesService, loggerFactory, featureFlagProvider) {
|
|
5377
5733
|
this.mediator = mediator;
|
|
5378
5734
|
this.resourceOverwritesService = resourceOverwritesService;
|
|
5735
|
+
this.featureFlagProvider = featureFlagProvider;
|
|
5379
5736
|
this.logger = loggerFactory.create("BindingOverwritesHandler");
|
|
5380
5737
|
}
|
|
5381
5738
|
}
|
|
@@ -5384,6 +5741,11 @@ function removeTimeTriggerBindings(bindings) {
|
|
|
5384
5741
|
}
|
|
5385
5742
|
|
|
5386
5743
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/binding-overwrites-mapping-handler.js
|
|
5744
|
+
function isCodedAppType(type) {
|
|
5745
|
+
const normalized = type?.toLowerCase();
|
|
5746
|
+
return normalized === "coded" || normalized === "codedaction";
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5387
5749
|
class BindingOverwritesMappingRequestHandler {
|
|
5388
5750
|
async handleAsync(request, cancellationToken) {
|
|
5389
5751
|
const solutionBindings = request.bindings.resources.filter((x) => isSolutionResource(x.metadata));
|
|
@@ -5409,7 +5771,8 @@ class BindingOverwritesMappingRequestHandler {
|
|
|
5409
5771
|
result.push({
|
|
5410
5772
|
binding: bindingsResource,
|
|
5411
5773
|
resourceKey: resource.key,
|
|
5412
|
-
isArtefactResource: resource.projectKey != null
|
|
5774
|
+
isArtefactResource: resource.projectKey != null,
|
|
5775
|
+
isCodedApp: bindingsResource.resourceType === models_BindingsResourceType.App && isCodedAppType(resource.type)
|
|
5413
5776
|
});
|
|
5414
5777
|
} else {
|
|
5415
5778
|
this.logger.error(`Solution does not contain binding resource of type ${models_BindingsResourceType[bindingsResource.resourceType]}.`);
|
|
@@ -6414,6 +6777,9 @@ class SolutionPublishLocationRequest {
|
|
|
6414
6777
|
}
|
|
6415
6778
|
|
|
6416
6779
|
class SolutionPublishLocationRequestV2 {
|
|
6780
|
+
constructor(permissionType) {
|
|
6781
|
+
this.permissionType = permissionType;
|
|
6782
|
+
}
|
|
6417
6783
|
}
|
|
6418
6784
|
|
|
6419
6785
|
class SettingsRequest {
|
|
@@ -6578,12 +6944,13 @@ function _ts_param3(paramIndex, decorator) {
|
|
|
6578
6944
|
}
|
|
6579
6945
|
|
|
6580
6946
|
class SolutionPublishLocationRequestV2Handler {
|
|
6581
|
-
async handleAsync(
|
|
6947
|
+
async handleAsync(request, cancellationToken) {
|
|
6582
6948
|
try {
|
|
6583
6949
|
const orchestratorClient = await this.orchestratorClientFactory.getClientAsync(cancellationToken);
|
|
6584
6950
|
if (!orchestratorClient)
|
|
6585
6951
|
throw new InvalidOperationException("Failed to create Orchestrator client");
|
|
6586
|
-
|
|
6952
|
+
const { permissionType } = request;
|
|
6953
|
+
return permissionType == null ? await orchestratorClient.getPublishLocationsAsync(cancellationToken) : await orchestratorClient.getAccessiblePublishLocationsAsync(permissionType, cancellationToken);
|
|
6587
6954
|
} catch (error) {
|
|
6588
6955
|
this.logger.error("An unexpected error occurred while retrieving publish locations from Automation Solutions service.", error);
|
|
6589
6956
|
throw error;
|
|
@@ -8023,8 +8390,8 @@ class SolutionDefinitionHelper {
|
|
|
8023
8390
|
if (references.length === 0)
|
|
8024
8391
|
continue;
|
|
8025
8392
|
const referenceKind = refProp["referenceKind"];
|
|
8026
|
-
const
|
|
8027
|
-
const filtered = references.filter((r) => !
|
|
8393
|
+
const matches2 = (ref) => ref.name != null && invariantEquals(resource.name, ref.name) && referenceKind != null && invariantEquals(referenceKind, resource.kind);
|
|
8394
|
+
const filtered = references.filter((r) => !matches2(r));
|
|
8028
8395
|
if (filtered.length !== references.length)
|
|
8029
8396
|
spec[refProp.property] = isSingleReferenceProperty(refProp) ? filtered[0] ?? null : filtered;
|
|
8030
8397
|
}
|
|
@@ -8613,7 +8980,7 @@ class GetResourceKeyForProjectRequestHandler {
|
|
|
8613
8980
|
projectKey: request.projectKey,
|
|
8614
8981
|
solution: request.context.path
|
|
8615
8982
|
});
|
|
8616
|
-
const cacheKey = `prk:${request.projectKey}`;
|
|
8983
|
+
const cacheKey = `prk:${request.context.path}:${request.projectKey}`;
|
|
8617
8984
|
const cached = await this.cacheProvider.getAsync(cacheKey, cancellationToken);
|
|
8618
8985
|
if (cached && typeof cached == "object" && "resourceKey" in cached) {
|
|
8619
8986
|
this.logger.info("Cache hit for project {projectKey} resource key.", {
|
|
@@ -9441,7 +9808,11 @@ class UpdateResourceConfigurationCommandHandler {
|
|
|
9441
9808
|
for (const prop of command.properties) {
|
|
9442
9809
|
const propKey = prop.property.toLowerCase();
|
|
9443
9810
|
const metadata = propertiesMetadata.get(propKey);
|
|
9444
|
-
if (
|
|
9811
|
+
if (metadata && metadata.readOnly !== true) {
|
|
9812
|
+
if (isAnyReferenceProperty(metadata)) {
|
|
9813
|
+
updated = this.setSolutionReference(solution, resource, currentConfiguration, propertiesMetadata, metadata, prop.configuredValue) || updated;
|
|
9814
|
+
continue;
|
|
9815
|
+
}
|
|
9445
9816
|
if (isSecretProperty(metadata)) {
|
|
9446
9817
|
const secretValue = prop.configuredValue?.toString() || "";
|
|
9447
9818
|
const existingKey = currentConfiguration[metadata.property]?.toString();
|
|
@@ -9485,6 +9856,38 @@ class UpdateResourceConfigurationCommandHandler {
|
|
|
9485
9856
|
await command.context.saveChangesAsync(cancellationToken);
|
|
9486
9857
|
return resourceConfiguration;
|
|
9487
9858
|
}
|
|
9859
|
+
setSolutionReference(solution, resource, currentConfiguration, propertiesMetadata, metadata, configuredValue) {
|
|
9860
|
+
const referenceKind = metadata["referenceKind"];
|
|
9861
|
+
if (!isSingleReferenceProperty(metadata) || isFileReferenceProperty(metadata) || typeof referenceKind != "string" || !referenceKind)
|
|
9862
|
+
return false;
|
|
9863
|
+
const requested = asReference(configuredValue);
|
|
9864
|
+
const target = requested?.key ? solution.resources.find((r) => invariantEquals(r.key, requested.key) && invariantEquals(r.kind, referenceKind)) : undefined;
|
|
9865
|
+
if (!requested || !target || invariantEquals(target.key, resource.key))
|
|
9866
|
+
return false;
|
|
9867
|
+
const dependencies = resource.dependencies ??= [];
|
|
9868
|
+
const previous = asReference(currentConfiguration[metadata.property]);
|
|
9869
|
+
const previousKey = previous?.key;
|
|
9870
|
+
const isReferencedElsewhere = (key) => [
|
|
9871
|
+
...propertiesMetadata.values()
|
|
9872
|
+
].some((p) => isAnyReferenceProperty(p) && !isFileReferenceProperty(p) && typeof p["referenceKind"] == "string" && invariantEquals(p["referenceKind"], target.kind) && !invariantEquals(p.property, metadata.property) && asReferences(currentConfiguration[p.property]).some((r) => r.key !== undefined && invariantEquals(r.key, key)));
|
|
9873
|
+
if (previousKey && !invariantEquals(previousKey, target.key) && !isReferencedElsewhere(previousKey)) {
|
|
9874
|
+
const previousName = solution.resources.find((r) => invariantEquals(r.key, previousKey) && invariantEquals(r.kind, target.kind))?.name ?? previous?.name ?? "";
|
|
9875
|
+
resource.dependencies = dependencies.filter((d) => !(invariantEquals(d.kind, target.kind) && invariantEquals(d.name, previousName)));
|
|
9876
|
+
}
|
|
9877
|
+
if (!resource.dependencies.some((d) => invariantEquals(d.kind, target.kind) && invariantEquals(d.name, target.name)))
|
|
9878
|
+
resource.dependencies.push({
|
|
9879
|
+
kind: target.kind,
|
|
9880
|
+
name: target.name
|
|
9881
|
+
});
|
|
9882
|
+
currentConfiguration[metadata.property] = {
|
|
9883
|
+
name: target.name,
|
|
9884
|
+
key: target.key,
|
|
9885
|
+
folderKey: requested.folderKey ?? null,
|
|
9886
|
+
lookupStrategy: null,
|
|
9887
|
+
info: null
|
|
9888
|
+
};
|
|
9889
|
+
return true;
|
|
9890
|
+
}
|
|
9488
9891
|
async updateReferencesName(solutionDefinition, resource, oldName, cancellationToken) {
|
|
9489
9892
|
const resourcesToBeChanged = solutionDefinition.resources.filter((r) => r.key !== resource.key && (r.dependencies ?? []).some((d) => invariantEquals(d.kind, resource.kind) && invariantEquals(d.name, oldName)));
|
|
9490
9893
|
if (resourcesToBeChanged.length === 0)
|
|
@@ -9771,6 +10174,28 @@ class UpsertResourceSecretCommandHandler {
|
|
|
9771
10174
|
this.secretsProvider = secretsProvider;
|
|
9772
10175
|
}
|
|
9773
10176
|
}
|
|
10177
|
+
function asReference(value) {
|
|
10178
|
+
if (!value || typeof value != "object" || Array.isArray(value))
|
|
10179
|
+
return;
|
|
10180
|
+
const record = value;
|
|
10181
|
+
const pick = (name) => {
|
|
10182
|
+
const entry = Object.entries(record).find(([k]) => k.toLowerCase() === name.toLowerCase());
|
|
10183
|
+
return typeof entry?.[1] == "string" ? entry[1] : undefined;
|
|
10184
|
+
};
|
|
10185
|
+
return {
|
|
10186
|
+
key: pick("key"),
|
|
10187
|
+
name: pick("name"),
|
|
10188
|
+
folderKey: pick("folderKey")
|
|
10189
|
+
};
|
|
10190
|
+
}
|
|
10191
|
+
function asReferences(value) {
|
|
10192
|
+
if (Array.isArray(value))
|
|
10193
|
+
return value.map(asReference).filter((r) => r !== undefined);
|
|
10194
|
+
const single = asReference(value);
|
|
10195
|
+
return single ? [
|
|
10196
|
+
single
|
|
10197
|
+
] : [];
|
|
10198
|
+
}
|
|
9774
10199
|
|
|
9775
10200
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/handlers/solution-handlers.js
|
|
9776
10201
|
var DUPLICATE_NAMES_SUPPORTED_KINDS = new Set([
|
|
@@ -13019,7 +13444,16 @@ class AutomationSolutionsClientProxy2 {
|
|
|
13019
13444
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/clients/orchestrator/orchestrator-client.js
|
|
13020
13445
|
class OrchestratorClient {
|
|
13021
13446
|
async getPublishLocationsAsync(cancellationToken) {
|
|
13022
|
-
|
|
13447
|
+
return this.getPublishLocationsFromAsync(this.publishLocationsUrl(), cancellationToken);
|
|
13448
|
+
}
|
|
13449
|
+
async getAccessiblePublishLocationsAsync(permissionType, cancellationToken) {
|
|
13450
|
+
const url = `${this.publishLocationsUrl()}?permissionType=${encodeURIComponent(permissionType)}`;
|
|
13451
|
+
return this.getPublishLocationsFromAsync(url, cancellationToken);
|
|
13452
|
+
}
|
|
13453
|
+
publishLocationsUrl() {
|
|
13454
|
+
return `${this.options.baseUrl}api/v2/AutomationSolutions/publish_locations`;
|
|
13455
|
+
}
|
|
13456
|
+
async getPublishLocationsFromAsync(url, cancellationToken) {
|
|
13023
13457
|
const headers = OrchestratorClientFactory.buildHeaders(this.options.securityData);
|
|
13024
13458
|
const response = await fetch(url, {
|
|
13025
13459
|
method: "GET",
|
|
@@ -13709,7 +14143,7 @@ class ReconcileProjectsCommandHandler {
|
|
|
13709
14143
|
} : {
|
|
13710
14144
|
resourceKey: undefined
|
|
13711
14145
|
};
|
|
13712
|
-
await this.cacheProvider.setAsync(`prk:${projectKey}`, result, cancellationToken);
|
|
14146
|
+
await this.cacheProvider.setAsync(`prk:${context.path}:${projectKey}`, result, cancellationToken);
|
|
13713
14147
|
}
|
|
13714
14148
|
groupByProjectKey(artefactResources) {
|
|
13715
14149
|
const map = new Map;
|
|
@@ -14583,6 +15017,11 @@ class ResourceBuilder {
|
|
|
14583
15017
|
const request = new SolutionPublishLocationRequestV2;
|
|
14584
15018
|
return this._mediator.sendAsync(request, cancellationToken);
|
|
14585
15019
|
}
|
|
15020
|
+
async getAccessiblePublishLocationsAsync(permissionType, cancellationToken) {
|
|
15021
|
+
this.throwIfCancelled(cancellationToken);
|
|
15022
|
+
const request = new SolutionPublishLocationRequestV2(permissionType);
|
|
15023
|
+
return this._mediator.sendAsync(request, cancellationToken);
|
|
15024
|
+
}
|
|
14586
15025
|
async getSettingsAsync(cancellationToken) {
|
|
14587
15026
|
this.throwIfCancelled(cancellationToken);
|
|
14588
15027
|
const request = new SettingsRequest;
|
|
@@ -15142,9 +15581,9 @@ class UnconfiguredEmbeddedFileReader {
|
|
|
15142
15581
|
}
|
|
15143
15582
|
|
|
15144
15583
|
// ../../node_modules/@uipath/resource-builder-sdk/dist/container.js
|
|
15145
|
-
function createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, embeddedFileReader, solutionContextOptions) {
|
|
15584
|
+
function createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, embeddedFileReader, solutionContextOptions, featureFlagProvider) {
|
|
15146
15585
|
const childContainer = import_tsyringe6.container.createChildContainer();
|
|
15147
|
-
registerProviders(childContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions);
|
|
15586
|
+
registerProviders(childContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions, featureFlagProvider);
|
|
15148
15587
|
registerServices(childContainer, embeddedFileReader);
|
|
15149
15588
|
registerHandlers(childContainer);
|
|
15150
15589
|
childContainer.register(ServiceTokens.Mediator, {
|
|
@@ -15168,11 +15607,15 @@ function registerProvider(diContainer, token, provider) {
|
|
|
15168
15607
|
break;
|
|
15169
15608
|
}
|
|
15170
15609
|
}
|
|
15171
|
-
function registerProviders(diContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions) {
|
|
15610
|
+
function registerProviders(diContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions, featureFlagProvider) {
|
|
15172
15611
|
registerProvider(diContainer, ServiceTokens.AccessProvider, accessProvider);
|
|
15173
15612
|
registerProvider(diContainer, ServiceTokens.CacheProvider, cacheProvider);
|
|
15174
15613
|
registerProvider(diContainer, ServiceTokens.SecretsProvider, secretsProvider);
|
|
15175
15614
|
registerProvider(diContainer, ServiceTokens.IpRangeBypassSecretProvider, ipRangeBypassSecretProvider);
|
|
15615
|
+
registerProvider(diContainer, ServiceTokens.FeatureFlagProvider, featureFlagProvider ?? {
|
|
15616
|
+
instance: new NullFeatureFlagProvider,
|
|
15617
|
+
lifetime: service_tokens_ServiceLifetime.Singleton
|
|
15618
|
+
});
|
|
15176
15619
|
registerProvider(diContainer, ServiceTokens.FileStorageProviderFactory, fileStorageProviderFactory);
|
|
15177
15620
|
registerProvider(diContainer, ServiceTokens.SolutionDefinitionProvider, solutionDefinitionProvider);
|
|
15178
15621
|
registerProvider(diContainer, ServiceTokens.SolutionDefinitionFactory, solutionDefinitionFactory);
|
|
@@ -15609,7 +16052,8 @@ function registerHandlers(diContainer) {
|
|
|
15609
16052
|
const mediator = c.resolve(ServiceTokens.Mediator);
|
|
15610
16053
|
const resourceOverwritesService = c.resolve(Tokens.IResourceOverwritesService);
|
|
15611
16054
|
const loggerFactory = c.resolve(ServiceTokens.LoggerFactory);
|
|
15612
|
-
|
|
16055
|
+
const featureFlagProvider = c.resolve(ServiceTokens.FeatureFlagProvider);
|
|
16056
|
+
return new BindingOverwritesHandler(mediator, resourceOverwritesService, loggerFactory, featureFlagProvider);
|
|
15613
16057
|
}
|
|
15614
16058
|
});
|
|
15615
16059
|
diContainer.register(createCommandHandlerToken(BindingOverwritesValidationCommand.name), {
|
|
@@ -15617,7 +16061,8 @@ function registerHandlers(diContainer) {
|
|
|
15617
16061
|
const mediator = c.resolve(ServiceTokens.Mediator);
|
|
15618
16062
|
const resourceOverwritesService = c.resolve(Tokens.IResourceOverwritesService);
|
|
15619
16063
|
const loggerFactory = c.resolve(ServiceTokens.LoggerFactory);
|
|
15620
|
-
|
|
16064
|
+
const featureFlagProvider = c.resolve(ServiceTokens.FeatureFlagProvider);
|
|
16065
|
+
return new BindingOverwritesHandler(mediator, resourceOverwritesService, loggerFactory, featureFlagProvider);
|
|
15621
16066
|
}
|
|
15622
16067
|
});
|
|
15623
16068
|
diContainer.register(createRequestHandlerToken(BindingOverwritesMappingRequest.name), {
|
|
@@ -15899,6 +16344,11 @@ class ResourceBuilderConfiguration {
|
|
|
15899
16344
|
this._ipRangeBypassSecretProviderLifetime = lifetime;
|
|
15900
16345
|
return this;
|
|
15901
16346
|
}
|
|
16347
|
+
addFeatureFlagProvider(provider, lifetime = service_tokens_ServiceLifetime.Scoped) {
|
|
16348
|
+
this._featureFlagProviderProvider = provider;
|
|
16349
|
+
this._featureFlagProviderLifetime = lifetime;
|
|
16350
|
+
return this;
|
|
16351
|
+
}
|
|
15902
16352
|
addSolutionDefinitionProvider(provider, lifetime = service_tokens_ServiceLifetime.Scoped) {
|
|
15903
16353
|
this._solutionDefinitionProviderProvider = provider;
|
|
15904
16354
|
this._solutionDefinitionProviderLifetime = lifetime;
|
|
@@ -15952,6 +16402,11 @@ class ResourceBuilderConfiguration {
|
|
|
15952
16402
|
instance: ipRangeBypassSecretProviderInstance,
|
|
15953
16403
|
lifetime: this._ipRangeBypassSecretProviderLifetime
|
|
15954
16404
|
};
|
|
16405
|
+
const featureFlagProviderInstance = this._featureFlagProviderProvider ? await resolveProvider(this._featureFlagProviderProvider) : new NullFeatureFlagProvider;
|
|
16406
|
+
const featureFlagProvider = {
|
|
16407
|
+
instance: featureFlagProviderInstance,
|
|
16408
|
+
lifetime: this._featureFlagProviderLifetime
|
|
16409
|
+
};
|
|
15955
16410
|
const secretsProviderInstance = this._secretsProviderProvider ? await resolveProvider(this._secretsProviderProvider) : new NullSecretsProvider;
|
|
15956
16411
|
const secretsProvider = {
|
|
15957
16412
|
instance: secretsProviderInstance,
|
|
@@ -15995,7 +16450,7 @@ class ResourceBuilderConfiguration {
|
|
|
15995
16450
|
lifetime: this._artifactResourceSpecEnhancerLifetime
|
|
15996
16451
|
};
|
|
15997
16452
|
const embeddedFileReader = await createDefaultEmbeddedFileReaderAsync();
|
|
15998
|
-
const container3 = createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, this._httpReaderOptions, loggerFactory, embeddedFileReader, this._solutionContextOptions);
|
|
16453
|
+
const container3 = createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, this._httpReaderOptions, loggerFactory, embeddedFileReader, this._solutionContextOptions, featureFlagProvider);
|
|
15999
16454
|
return new ResourceBuilderServices(container3);
|
|
16000
16455
|
}
|
|
16001
16456
|
async buildServices() {
|
|
@@ -16007,6 +16462,7 @@ class ResourceBuilderConfiguration {
|
|
|
16007
16462
|
this._secretsProviderLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
16008
16463
|
this._fileStorageProviderFactoryLifetime = service_tokens_ServiceLifetime.Singleton;
|
|
16009
16464
|
this._ipRangeBypassSecretProviderLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
16465
|
+
this._featureFlagProviderLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
16010
16466
|
this._solutionDefinitionProviderLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
16011
16467
|
this._solutionDefinitionFactoryLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
16012
16468
|
this._artifactResourceSpecEnhancerLifetime = service_tokens_ServiceLifetime.Scoped;
|
|
@@ -19173,12 +19629,12 @@ async function findResourceByKeyInRcs(builder, kind, expectedKey, folderPath, pr
|
|
|
19173
19629
|
return;
|
|
19174
19630
|
}
|
|
19175
19631
|
async function searchRcsResources(builder, kind, name) {
|
|
19176
|
-
const [searchError,
|
|
19632
|
+
const [searchError, matches2] = await catchError(searchRcsResourcesStrict(builder, kind, name));
|
|
19177
19633
|
if (searchError) {
|
|
19178
19634
|
logger.warn(`Failed to search ${kind} resources in RCS: ${searchError.message}`);
|
|
19179
19635
|
return [];
|
|
19180
19636
|
}
|
|
19181
|
-
return
|
|
19637
|
+
return matches2;
|
|
19182
19638
|
}
|
|
19183
19639
|
async function searchRcsResourcesStrict(builder, kind, name) {
|
|
19184
19640
|
let pageCursor;
|
|
@@ -19186,8 +19642,8 @@ async function searchRcsResourcesStrict(builder, kind, name) {
|
|
|
19186
19642
|
do {
|
|
19187
19643
|
const result = await builder.searchResourcesAsync(kind, undefined, name, pageCursor, 50, undefined, false);
|
|
19188
19644
|
for (const folderResources of result.availableResources) {
|
|
19189
|
-
const
|
|
19190
|
-
for (const match of
|
|
19645
|
+
const matches2 = folderResources.resources.filter((r) => r.name.toLowerCase() === name.toLowerCase());
|
|
19646
|
+
for (const match of matches2) {
|
|
19191
19647
|
allMatches.push({
|
|
19192
19648
|
key: match.key,
|
|
19193
19649
|
name: match.name,
|
|
@@ -19722,4 +20178,4 @@ export {
|
|
|
19722
20178
|
writeSolutionFile
|
|
19723
20179
|
};
|
|
19724
20180
|
|
|
19725
|
-
//# debugId=
|
|
20181
|
+
//# debugId=E5F793889B09FC5464756E2164756E21
|