@uipath/integrationservice-tool 1.203.0-preview.212 → 1.204.0-preview.211
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -8
- package/dist/index.js +1 -1
- package/dist/{tool-rpm313p8.js → tool-2h04aqp4.js} +1333 -169
- package/dist/tool.js +1 -1
- package/package.json +2 -2
|
@@ -2101,7 +2101,7 @@ var package_default = {
|
|
|
2101
2101
|
name: "@uipath/integrationservice-tool",
|
|
2102
2102
|
author: "UiPath",
|
|
2103
2103
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
2104
|
-
version: "1.
|
|
2104
|
+
version: "1.204.0-preview.211",
|
|
2105
2105
|
description: "Manage Integration Service connectors, connections, and triggers.",
|
|
2106
2106
|
private: false,
|
|
2107
2107
|
repository: {
|
|
@@ -2913,9 +2913,60 @@ function settlePromiseLike(thenable) {
|
|
|
2913
2913
|
return Promise.resolve(thenable).then((data) => [undefined, data]).catch((error) => [toError(error), undefined]);
|
|
2914
2914
|
}
|
|
2915
2915
|
|
|
2916
|
+
// ../common/src/error-graph.ts
|
|
2917
|
+
function* walkErrorGraph(error) {
|
|
2918
|
+
const queue = [error];
|
|
2919
|
+
const seen = new Set;
|
|
2920
|
+
for (let steps = 0;queue.length > 0 && steps < 32; steps++) {
|
|
2921
|
+
const current = queue.shift();
|
|
2922
|
+
if (current === null || typeof current !== "object")
|
|
2923
|
+
continue;
|
|
2924
|
+
if (seen.has(current))
|
|
2925
|
+
continue;
|
|
2926
|
+
seen.add(current);
|
|
2927
|
+
const cur = current;
|
|
2928
|
+
yield cur;
|
|
2929
|
+
if (cur.cause !== undefined)
|
|
2930
|
+
queue.push(cur.cause);
|
|
2931
|
+
if (Array.isArray(cur.errors))
|
|
2932
|
+
queue.push(...cur.errors);
|
|
2933
|
+
}
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
function parseHttpStatusFromMessage(message) {
|
|
2937
|
+
const match = /^HTTP\s+(\d{3})(?::|\s|-|$)/i.exec(message.trim());
|
|
2938
|
+
if (!match)
|
|
2939
|
+
return;
|
|
2940
|
+
const status = Number(match[1]);
|
|
2941
|
+
return Number.isInteger(status) && status >= 100 && status <= 599 ? status : undefined;
|
|
2942
|
+
}
|
|
2943
|
+
function findHttpStatusInGraph(error) {
|
|
2944
|
+
for (const node of walkErrorGraph(error)) {
|
|
2945
|
+
const response = node.response;
|
|
2946
|
+
const explicit = typeof node.status === "number" ? node.status : response?.status;
|
|
2947
|
+
if (typeof explicit === "number" && explicit >= 400 && explicit <= 599) {
|
|
2948
|
+
return explicit;
|
|
2949
|
+
}
|
|
2950
|
+
if (typeof node.message === "string") {
|
|
2951
|
+
const parsed = parseHttpStatusFromMessage(node.message);
|
|
2952
|
+
if (parsed !== undefined && parsed >= 400) {
|
|
2953
|
+
return parsed;
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
return;
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
// ../common/src/local-permission-codes.ts
|
|
2961
|
+
var LOCAL_PERMISSION_ERROR_CODES = new Set([
|
|
2962
|
+
"EACCES",
|
|
2963
|
+
"EPERM",
|
|
2964
|
+
"EROFS"
|
|
2965
|
+
]);
|
|
2966
|
+
|
|
2916
2967
|
// ../common/src/error-handler.ts
|
|
2917
|
-
var DEFAULT_401 = "Unauthorized (401). Run `uip login` to
|
|
2918
|
-
var DEFAULT_403 = "Forbidden (403).
|
|
2968
|
+
var DEFAULT_401 = "Unauthorized (401). The session is missing or expired, or its token carries no scope for this API. Run `uip login status --detailed` to see the session and its scopes.";
|
|
2969
|
+
var DEFAULT_403 = "Forbidden (403). The account lacks permission for this operation, or the token carries no scope for this API. Run `uip login status --detailed` to see the token's scopes.";
|
|
2919
2970
|
var DEFAULT_405 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
|
|
2920
2971
|
var DEFAULT_413 = "Payload too large (413). The upload exceeded the server or CDN size limit. Reduce the package size — for example, exclude unused dependencies or remove large files from the project — and try again.";
|
|
2921
2972
|
var HTML_RESPONSE_MESSAGE = "Received HTML instead of the expected JSON response.";
|
|
@@ -2942,14 +2993,14 @@ var TLS_ERROR_CODES = new Set([
|
|
|
2942
2993
|
]);
|
|
2943
2994
|
var TLS_INSTRUCTIONS = "The server's TLS certificate could not be verified. Most often a " + "corporate proxy/firewall re-signs HTTPS with a root CA that Node does " + "not trust — set NODE_EXTRA_CA_CERTS to that CA's PEM file (and HTTPS_PROXY " + "if you connect through a proxy). If the certificate is instead expired or " + "its hostname does not match, fix the endpoint URL or the system clock. " + "Then retry.";
|
|
2944
2995
|
var NETWORK_INSTRUCTIONS = "Could not reach the UiPath service. Check your network connection and " + "VPN, confirm any HTTP_PROXY/HTTPS_PROXY/NO_PROXY settings are correct, " + "then retry.";
|
|
2945
|
-
var
|
|
2946
|
-
var LOCAL_PERMISSION_MESSAGE_PATTERN = /\b(EACCES|EPERM|EROFS)\b/;
|
|
2996
|
+
var LOCAL_PERMISSION_MESSAGE_PATTERN = new RegExp(`\\b(${[...LOCAL_PERMISSION_ERROR_CODES].join("|")})\\b`);
|
|
2947
2997
|
function localPermissionInstructions(code, path2) {
|
|
2948
2998
|
const target = path2 !== undefined ? `'${path2}'` : "a local file or resource";
|
|
2949
2999
|
if (code === "EROFS") {
|
|
2950
3000
|
return `The filesystem containing ${target} is read-only (EROFS), so the ` + "CLI could not write to it. This is a local environment problem, " + "not a UiPath service error — retrying will not help. Use a " + "writable location, or give this environment write access to the " + "path.";
|
|
2951
3001
|
}
|
|
2952
|
-
const
|
|
3002
|
+
const onWindows = typeof process !== "undefined" && process.platform === "win32";
|
|
3003
|
+
const remedy = onWindows ? "Re-run from an elevated terminal, close any program holding " + "the file open, or grant your user access to the path." : "Grant this user (or the sandbox the command runs in) access " + "to the path, or run the command outside the sandbox.";
|
|
2953
3004
|
return `The operating system denied access to ${target} (${code}). This is ` + "a local permission problem, not a UiPath service error — retrying " + `without a permission change will not help. ${remedy}`;
|
|
2954
3005
|
}
|
|
2955
3006
|
function describeConnectivityError(error) {
|
|
@@ -3003,48 +3054,6 @@ function localPermissionPath(path2, message) {
|
|
|
3003
3054
|
return path2;
|
|
3004
3055
|
return message ? /'([^']+)'/.exec(message)?.[1] : undefined;
|
|
3005
3056
|
}
|
|
3006
|
-
function* walkErrorGraph(error) {
|
|
3007
|
-
const queue = [error];
|
|
3008
|
-
const seen = new Set;
|
|
3009
|
-
for (let steps = 0;queue.length > 0 && steps < 32; steps++) {
|
|
3010
|
-
const current = queue.shift();
|
|
3011
|
-
if (current === null || typeof current !== "object")
|
|
3012
|
-
continue;
|
|
3013
|
-
if (seen.has(current))
|
|
3014
|
-
continue;
|
|
3015
|
-
seen.add(current);
|
|
3016
|
-
const cur = current;
|
|
3017
|
-
yield cur;
|
|
3018
|
-
if (cur.cause !== undefined)
|
|
3019
|
-
queue.push(cur.cause);
|
|
3020
|
-
if (Array.isArray(cur.errors))
|
|
3021
|
-
queue.push(...cur.errors);
|
|
3022
|
-
}
|
|
3023
|
-
return;
|
|
3024
|
-
}
|
|
3025
|
-
function parseHttpStatusFromMessage(message) {
|
|
3026
|
-
const match = /^HTTP\s+(\d{3})(?::|\s|-|$)/i.exec(message.trim());
|
|
3027
|
-
if (!match)
|
|
3028
|
-
return;
|
|
3029
|
-
const status = Number(match[1]);
|
|
3030
|
-
return Number.isInteger(status) && status >= 100 && status <= 599 ? status : undefined;
|
|
3031
|
-
}
|
|
3032
|
-
function findHttpStatusInGraph(error) {
|
|
3033
|
-
for (const node of walkErrorGraph(error)) {
|
|
3034
|
-
const response = node.response;
|
|
3035
|
-
const explicit = typeof node.status === "number" ? node.status : response?.status;
|
|
3036
|
-
if (typeof explicit === "number" && explicit >= 400 && explicit <= 599) {
|
|
3037
|
-
return explicit;
|
|
3038
|
-
}
|
|
3039
|
-
if (typeof node.message === "string") {
|
|
3040
|
-
const parsed = parseHttpStatusFromMessage(node.message);
|
|
3041
|
-
if (parsed !== undefined && parsed >= 400) {
|
|
3042
|
-
return parsed;
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
}
|
|
3046
|
-
return;
|
|
3047
|
-
}
|
|
3048
3057
|
function isHtmlDocument(body) {
|
|
3049
3058
|
return /^\s*(<!doctype html|<html\b)/i.test(body);
|
|
3050
3059
|
}
|
|
@@ -3566,12 +3575,162 @@ function getOutputFilter() {
|
|
|
3566
3575
|
return filterSlot.get();
|
|
3567
3576
|
}
|
|
3568
3577
|
|
|
3578
|
+
// ../common/src/telemetry/telemetry-dimensions.ts
|
|
3579
|
+
var BaseDimensions = {
|
|
3580
|
+
ApplicationName: "ApplicationName",
|
|
3581
|
+
ProductVersion: "ProductVersion",
|
|
3582
|
+
InstallationId: "InstallationId",
|
|
3583
|
+
CloudUserId: "CloudUserId",
|
|
3584
|
+
CloudTenantId: "CloudTenantId",
|
|
3585
|
+
CloudOrganizationId: "CloudOrganizationId",
|
|
3586
|
+
IsInternalUser: "IsInternalUser",
|
|
3587
|
+
Environment: "Environment",
|
|
3588
|
+
BaseUrl: "BaseUrl",
|
|
3589
|
+
Region: "Region",
|
|
3590
|
+
Agent: "Agent",
|
|
3591
|
+
AgentVersion: "AgentVersion",
|
|
3592
|
+
AgentModel: "AgentModel",
|
|
3593
|
+
ToolName: "ToolName",
|
|
3594
|
+
ToolVersion: "ToolVersion",
|
|
3595
|
+
ExecutionContext: "ExecutionContext",
|
|
3596
|
+
CiProvider: "CiProvider",
|
|
3597
|
+
SessionIdSource: "SessionIdSource",
|
|
3598
|
+
SessionId: "SessionId"
|
|
3599
|
+
};
|
|
3600
|
+
var CommandDimensions = {
|
|
3601
|
+
IsCommand: "IsCommand",
|
|
3602
|
+
IsReexec: "IsReexec",
|
|
3603
|
+
CommandName: "CommandName",
|
|
3604
|
+
ExitCode: "ExitCode",
|
|
3605
|
+
TerminalOutcome: "TerminalOutcome",
|
|
3606
|
+
ErrorClass: "ErrorClass",
|
|
3607
|
+
TerminalSignal: "TerminalSignal",
|
|
3608
|
+
ErrorMessage: "ErrorMessage",
|
|
3609
|
+
SkillName: "SkillName",
|
|
3610
|
+
ProductArea: "ProductArea",
|
|
3611
|
+
Mode: "Mode"
|
|
3612
|
+
};
|
|
3613
|
+
var ShipDimensions = {
|
|
3614
|
+
ShipKind: "ShipKind",
|
|
3615
|
+
Target: "Target",
|
|
3616
|
+
ProjectType: "ProjectType",
|
|
3617
|
+
ProjectTypes: "ProjectTypes",
|
|
3618
|
+
ArtifactCorrelationKey: "ArtifactCorrelationKey",
|
|
3619
|
+
PackageName: "PackageName",
|
|
3620
|
+
PackageVersion: "PackageVersion",
|
|
3621
|
+
PackageVersionKey: "PackageVersionKey",
|
|
3622
|
+
DeploymentKey: "DeploymentKey",
|
|
3623
|
+
SolutionId: "SolutionId",
|
|
3624
|
+
FolderKey: "FolderKey",
|
|
3625
|
+
FeedId: "FeedId"
|
|
3626
|
+
};
|
|
3627
|
+
var ErrorDimensions = {
|
|
3628
|
+
Result: "Result",
|
|
3629
|
+
ErrorCode: "ErrorCode",
|
|
3630
|
+
Retry: "Retry",
|
|
3631
|
+
ErrorMessage: "ErrorMessage"
|
|
3632
|
+
};
|
|
3633
|
+
var AuthDimensions = {
|
|
3634
|
+
AuthenticationMethod: "AuthenticationMethod",
|
|
3635
|
+
Success: "Success",
|
|
3636
|
+
Reason: "Reason"
|
|
3637
|
+
};
|
|
3638
|
+
var SkillsDimensions = {
|
|
3639
|
+
SchemaVersion: "SchemaVersion",
|
|
3640
|
+
AgentType: "AgentType",
|
|
3641
|
+
SkillsVersion: "SkillsVersion",
|
|
3642
|
+
UipSubcommand: "UipSubcommand",
|
|
3643
|
+
FileExtension: "FileExtension",
|
|
3644
|
+
SubagentModel: "SubagentModel",
|
|
3645
|
+
SubagentType: "SubagentType",
|
|
3646
|
+
PermissionMode: "PermissionMode",
|
|
3647
|
+
EffortLevel: "EffortLevel",
|
|
3648
|
+
SessionSource: "SessionSource",
|
|
3649
|
+
Outcome: "Outcome",
|
|
3650
|
+
DurationMs: "DurationMs",
|
|
3651
|
+
Source: "Source"
|
|
3652
|
+
};
|
|
3653
|
+
var PackagerDimensions = {
|
|
3654
|
+
ProjectId: "ProjectId",
|
|
3655
|
+
ProjectType: "ProjectType",
|
|
3656
|
+
SolutionId: "SolutionId"
|
|
3657
|
+
};
|
|
3658
|
+
var ScopeDimensions = {
|
|
3659
|
+
FolderId: "FolderId"
|
|
3660
|
+
};
|
|
3661
|
+
var ID_DIMENSIONS = new Set([
|
|
3662
|
+
BaseDimensions.CloudUserId,
|
|
3663
|
+
BaseDimensions.CloudTenantId,
|
|
3664
|
+
BaseDimensions.CloudOrganizationId,
|
|
3665
|
+
BaseDimensions.InstallationId,
|
|
3666
|
+
ShipDimensions.ArtifactCorrelationKey,
|
|
3667
|
+
ShipDimensions.PackageVersionKey,
|
|
3668
|
+
ShipDimensions.DeploymentKey,
|
|
3669
|
+
ShipDimensions.SolutionId,
|
|
3670
|
+
ShipDimensions.FolderKey,
|
|
3671
|
+
ShipDimensions.FeedId,
|
|
3672
|
+
PackagerDimensions.ProjectId
|
|
3673
|
+
]);
|
|
3674
|
+
var NON_IDENTIFIER_PLACEHOLDER_PATTERN = /^(?:\[[A-Z_]+\]|<[^>]+>)$/;
|
|
3675
|
+
var RESERVED_DIMENSION_NAMES = new Set([
|
|
3676
|
+
...Object.values(BaseDimensions),
|
|
3677
|
+
...Object.values(CommandDimensions),
|
|
3678
|
+
...Object.values(ShipDimensions),
|
|
3679
|
+
...Object.values(ErrorDimensions),
|
|
3680
|
+
...Object.values(AuthDimensions),
|
|
3681
|
+
...Object.values(SkillsDimensions),
|
|
3682
|
+
...Object.values(PackagerDimensions),
|
|
3683
|
+
...Object.values(ScopeDimensions)
|
|
3684
|
+
]);
|
|
3685
|
+
var CURATED_DIMENSIONS = new Set([
|
|
3686
|
+
BaseDimensions.ApplicationName,
|
|
3687
|
+
BaseDimensions.ProductVersion,
|
|
3688
|
+
BaseDimensions.InstallationId,
|
|
3689
|
+
BaseDimensions.CloudUserId,
|
|
3690
|
+
BaseDimensions.CloudTenantId,
|
|
3691
|
+
BaseDimensions.CloudOrganizationId,
|
|
3692
|
+
BaseDimensions.IsInternalUser,
|
|
3693
|
+
BaseDimensions.Environment,
|
|
3694
|
+
BaseDimensions.BaseUrl,
|
|
3695
|
+
BaseDimensions.Region,
|
|
3696
|
+
BaseDimensions.Agent,
|
|
3697
|
+
BaseDimensions.AgentVersion,
|
|
3698
|
+
BaseDimensions.ToolVersion,
|
|
3699
|
+
BaseDimensions.ExecutionContext,
|
|
3700
|
+
BaseDimensions.CiProvider,
|
|
3701
|
+
BaseDimensions.SessionIdSource,
|
|
3702
|
+
BaseDimensions.SessionId,
|
|
3703
|
+
...Object.values(CommandDimensions),
|
|
3704
|
+
...Object.values(ShipDimensions)
|
|
3705
|
+
]);
|
|
3706
|
+
function lowercaseIdDimensionValues(properties) {
|
|
3707
|
+
let changed = false;
|
|
3708
|
+
const result = {
|
|
3709
|
+
...properties
|
|
3710
|
+
};
|
|
3711
|
+
for (const key of Object.keys(result)) {
|
|
3712
|
+
const value = result[key];
|
|
3713
|
+
if (!ID_DIMENSIONS.has(key) || typeof value !== "string" || NON_IDENTIFIER_PLACEHOLDER_PATTERN.test(value)) {
|
|
3714
|
+
continue;
|
|
3715
|
+
}
|
|
3716
|
+
const lowered = value.toLowerCase();
|
|
3717
|
+
if (lowered !== value) {
|
|
3718
|
+
result[key] = lowered;
|
|
3719
|
+
changed = true;
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
return changed ? result : properties;
|
|
3723
|
+
}
|
|
3724
|
+
|
|
3569
3725
|
// ../common/src/telemetry/command-terminal.ts
|
|
3570
3726
|
var recordedFailureSlot = singleton("CommandTelemetryFailure");
|
|
3571
3727
|
var AUTH_ERROR_CODES = new Set([
|
|
3572
3728
|
"authentication_required",
|
|
3573
3729
|
"permission_denied"
|
|
3574
3730
|
]);
|
|
3731
|
+
var LOCAL_PERMISSION_CLI_ERROR_CODES = new Set([
|
|
3732
|
+
"local_permission_denied"
|
|
3733
|
+
]);
|
|
3575
3734
|
var VALIDATION_ERROR_CODES = new Set(["invalid_argument"]);
|
|
3576
3735
|
var NETWORK_HTTP_ERROR_CODES = new Set([
|
|
3577
3736
|
"network_error",
|
|
@@ -3712,6 +3871,9 @@ function classifyFromErrorCode(errorCode) {
|
|
|
3712
3871
|
if (AUTH_ERROR_CODES.has(errorCode)) {
|
|
3713
3872
|
return "auth";
|
|
3714
3873
|
}
|
|
3874
|
+
if (LOCAL_PERMISSION_CLI_ERROR_CODES.has(errorCode)) {
|
|
3875
|
+
return "local_permission";
|
|
3876
|
+
}
|
|
3715
3877
|
if (VALIDATION_ERROR_CODES.has(errorCode)) {
|
|
3716
3878
|
return "validation";
|
|
3717
3879
|
}
|
|
@@ -3723,6 +3885,15 @@ function classifyFromErrorCode(errorCode) {
|
|
|
3723
3885
|
}
|
|
3724
3886
|
return;
|
|
3725
3887
|
}
|
|
3888
|
+
function hasLocalPermissionCode(error) {
|
|
3889
|
+
for (const node of walkErrorGraph(error)) {
|
|
3890
|
+
const code = node.code;
|
|
3891
|
+
if (typeof code === "string" && LOCAL_PERMISSION_ERROR_CODES.has(code)) {
|
|
3892
|
+
return true;
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
return false;
|
|
3896
|
+
}
|
|
3726
3897
|
function classifyFromError(error) {
|
|
3727
3898
|
const code = findCodeInCauseChain(error);
|
|
3728
3899
|
if (code) {
|
|
@@ -3739,6 +3910,9 @@ function classifyFromError(error) {
|
|
|
3739
3910
|
return "missing_dependency";
|
|
3740
3911
|
}
|
|
3741
3912
|
}
|
|
3913
|
+
if (hasLocalPermissionCode(error)) {
|
|
3914
|
+
return "local_permission";
|
|
3915
|
+
}
|
|
3742
3916
|
const message = stringField(error, "message");
|
|
3743
3917
|
if (message?.includes("fetch failed") === true) {
|
|
3744
3918
|
return "network_http";
|
|
@@ -3754,7 +3928,7 @@ function classifyError2(input) {
|
|
|
3754
3928
|
if (recorded?.errorClass) {
|
|
3755
3929
|
return recorded.errorClass;
|
|
3756
3930
|
}
|
|
3757
|
-
const status = recorded?.context?.httpStatus;
|
|
3931
|
+
const status = recorded?.context?.httpStatus ?? findHttpStatusInGraph(input.error);
|
|
3758
3932
|
if (status !== undefined) {
|
|
3759
3933
|
return classifyHttpStatus(status);
|
|
3760
3934
|
}
|
|
@@ -3777,17 +3951,18 @@ function buildCommandTerminalTelemetryProperties(input) {
|
|
|
3777
3951
|
const errorClass = outcome === "success" || outcome === "no_op" ? undefined : outcome === "cancelled" ? "user_cancelled" : classifyError2(input);
|
|
3778
3952
|
const terminalSignal = terminalSignalFor(input, outcome);
|
|
3779
3953
|
return {
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
...errorClass ? {
|
|
3783
|
-
...terminalSignal ? {
|
|
3954
|
+
[CommandDimensions.ExitCode]: input.exitCode,
|
|
3955
|
+
[CommandDimensions.TerminalOutcome]: outcome,
|
|
3956
|
+
...errorClass ? { [CommandDimensions.ErrorClass]: errorClass } : {},
|
|
3957
|
+
...terminalSignal ? { [CommandDimensions.TerminalSignal]: terminalSignal } : {}
|
|
3784
3958
|
};
|
|
3785
3959
|
}
|
|
3786
3960
|
|
|
3787
3961
|
// ../common/src/telemetry/telemetry-events.ts
|
|
3788
3962
|
var CommonTelemetryEvents = {
|
|
3789
|
-
|
|
3790
|
-
|
|
3963
|
+
Start: "Application.Start",
|
|
3964
|
+
Error: "Application.Error",
|
|
3965
|
+
ShipSucceeded: "Cli.ShipSucceeded"
|
|
3791
3966
|
};
|
|
3792
3967
|
|
|
3793
3968
|
// ../common/src/registry.ts
|
|
@@ -3995,8 +4170,8 @@ function detectExecutionContext(options = {}) {
|
|
|
3995
4170
|
function getExecutionContextTelemetryProperties() {
|
|
3996
4171
|
const detected = detectExecutionContext();
|
|
3997
4172
|
return {
|
|
3998
|
-
|
|
3999
|
-
...detected.ciProvider ? {
|
|
4173
|
+
[BaseDimensions.ExecutionContext]: detected.executionContext,
|
|
4174
|
+
...detected.ciProvider ? { [BaseDimensions.CiProvider]: detected.ciProvider } : {}
|
|
4000
4175
|
};
|
|
4001
4176
|
}
|
|
4002
4177
|
// ../common/src/telemetry/node-context-storage.ts
|
|
@@ -4039,7 +4214,7 @@ function getInboundTraceContext() {
|
|
|
4039
4214
|
var TELEMETRY_SESSION_ID_ENV = "UIPATH_SESSION_ID";
|
|
4040
4215
|
var SESSION_ID_MAX_LENGTH = 64;
|
|
4041
4216
|
var RANDOM_SESSION_ID_LENGTH = 32;
|
|
4042
|
-
var TELEMETRY_SESSION_SOURCE_PROPERTY = "
|
|
4217
|
+
var TELEMETRY_SESSION_SOURCE_PROPERTY = "SessionIdSource";
|
|
4043
4218
|
var CONTROL_CHARACTERS = /\p{Cc}/gu;
|
|
4044
4219
|
var INHERITED_SESSION_SOURCES = [
|
|
4045
4220
|
{ envVar: "CLAUDE_CODE_SESSION_ID", source: "claude-code" },
|
|
@@ -4091,6 +4266,9 @@ function resolveTelemetrySession() {
|
|
|
4091
4266
|
telemetrySessionSlot.set(resolved);
|
|
4092
4267
|
return resolved;
|
|
4093
4268
|
}
|
|
4269
|
+
function getTelemetrySessionId() {
|
|
4270
|
+
return resolveTelemetrySession().id;
|
|
4271
|
+
}
|
|
4094
4272
|
function getTelemetrySessionSource() {
|
|
4095
4273
|
return resolveTelemetrySession().source;
|
|
4096
4274
|
}
|
|
@@ -4171,7 +4349,10 @@ class TelemetryService {
|
|
|
4171
4349
|
} catch (error) {
|
|
4172
4350
|
const durationMs = clock.elapsedMs();
|
|
4173
4351
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
4174
|
-
await this.telemetryProvider.trackRequest(this.spanFor(name, durationMs, false, {
|
|
4352
|
+
await this.telemetryProvider.trackRequest(this.spanFor(name, durationMs, false, {
|
|
4353
|
+
...properties,
|
|
4354
|
+
[CommandDimensions.ErrorMessage]: err.message
|
|
4355
|
+
}, context));
|
|
4175
4356
|
throw error;
|
|
4176
4357
|
}
|
|
4177
4358
|
}
|
|
@@ -4242,7 +4423,10 @@ class TelemetryService {
|
|
|
4242
4423
|
const durationMs = clock.elapsedMs();
|
|
4243
4424
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
4244
4425
|
await this.telemetryProvider.trackDependency({
|
|
4245
|
-
...this.spanFor(name, durationMs, false, {
|
|
4426
|
+
...this.spanFor(name, durationMs, false, {
|
|
4427
|
+
...properties,
|
|
4428
|
+
[CommandDimensions.ErrorMessage]: err.message
|
|
4429
|
+
}, childContext),
|
|
4246
4430
|
type
|
|
4247
4431
|
});
|
|
4248
4432
|
throw error;
|
|
@@ -4277,9 +4461,10 @@ class TelemetryService {
|
|
|
4277
4461
|
...globalProperties,
|
|
4278
4462
|
...this.defaultProperties,
|
|
4279
4463
|
...redactProperties(properties ?? {}),
|
|
4280
|
-
[TELEMETRY_SESSION_SOURCE_PROPERTY]: getTelemetrySessionSource()
|
|
4464
|
+
[TELEMETRY_SESSION_SOURCE_PROPERTY]: getTelemetrySessionSource(),
|
|
4465
|
+
[BaseDimensions.SessionId]: this.telemetryProvider.getSessionId?.() ?? getTelemetrySessionId()
|
|
4281
4466
|
};
|
|
4282
|
-
return enriched;
|
|
4467
|
+
return lowercaseIdDimensionValues(enriched);
|
|
4283
4468
|
}
|
|
4284
4469
|
generateId() {
|
|
4285
4470
|
const bytes = new Uint8Array(8);
|
|
@@ -5040,7 +5225,165 @@ class FilterImplicitLimitError extends Error {
|
|
|
5040
5225
|
this.instructions = "Pass --limit <n> to choose how many records the filter applies to. " + "To filter over all records, pass the command's maximum accepted --limit (see the option's description in --help).";
|
|
5041
5226
|
}
|
|
5042
5227
|
}
|
|
5043
|
-
function
|
|
5228
|
+
function countRecords(data) {
|
|
5229
|
+
if (Array.isArray(data))
|
|
5230
|
+
return data.length;
|
|
5231
|
+
return data == null ? 0 : 1;
|
|
5232
|
+
}
|
|
5233
|
+
function availableFields(data) {
|
|
5234
|
+
const records = Array.isArray(data) ? data : [data];
|
|
5235
|
+
const keys = new Set;
|
|
5236
|
+
for (const record of records) {
|
|
5237
|
+
if (record && typeof record === "object" && !Array.isArray(record)) {
|
|
5238
|
+
for (const key of Object.keys(record))
|
|
5239
|
+
keys.add(key);
|
|
5240
|
+
}
|
|
5241
|
+
}
|
|
5242
|
+
return [...keys];
|
|
5243
|
+
}
|
|
5244
|
+
function decodeQuotedIdentifier(whole, inner) {
|
|
5245
|
+
const [error, decoded] = catchError(() => JSON.parse(whole));
|
|
5246
|
+
if (!error && typeof decoded === "string")
|
|
5247
|
+
return decoded;
|
|
5248
|
+
return inner.replace(/\\(.)/g, "$1");
|
|
5249
|
+
}
|
|
5250
|
+
function referencedFields(filter) {
|
|
5251
|
+
const top = new Set;
|
|
5252
|
+
const nested = new Set;
|
|
5253
|
+
const withoutValueLiterals = filter.replace(/'(?:\\.|[^'\\])*'/g, " ").replace(/`(?:\\.|[^`\\])*`/g, " ");
|
|
5254
|
+
const isPathTail = (text, index) => text[index - 1] === "." && /[A-Za-z0-9_"]/.test(text[index - 2] ?? "");
|
|
5255
|
+
const quoted = [];
|
|
5256
|
+
const withoutLiterals = withoutValueLiterals.replace(/"((?:\\.|[^"\\])*)"/g, (whole, name, index) => {
|
|
5257
|
+
const isAlias = /^\s*:/.test(withoutValueLiterals.slice(index + whole.length));
|
|
5258
|
+
if (!isAlias) {
|
|
5259
|
+
quoted.push({
|
|
5260
|
+
name: decodeQuotedIdentifier(whole, name),
|
|
5261
|
+
index,
|
|
5262
|
+
tail: isPathTail(withoutValueLiterals, index)
|
|
5263
|
+
});
|
|
5264
|
+
}
|
|
5265
|
+
return `"${" ".repeat(whole.length - 2)}"`;
|
|
5266
|
+
});
|
|
5267
|
+
const descent = /[A-Za-z0-9_"]\s*[.[]/.exec(withoutLiterals);
|
|
5268
|
+
const rootEnd = descent ? descent.index + 1 : Number.POSITIVE_INFINITY;
|
|
5269
|
+
const place = (name, index, tail) => {
|
|
5270
|
+
if (tail || index >= rootEnd)
|
|
5271
|
+
nested.add(name);
|
|
5272
|
+
else
|
|
5273
|
+
top.add(name);
|
|
5274
|
+
};
|
|
5275
|
+
for (const entry of quoted)
|
|
5276
|
+
place(entry.name, entry.index, entry.tail);
|
|
5277
|
+
const identifiers = withoutLiterals.matchAll(/([A-Za-z_][A-Za-z0-9_]*)(\s*[:(])?/g);
|
|
5278
|
+
const reserved = new Set(["true", "false", "null", "and", "or", "not"]);
|
|
5279
|
+
for (const match of identifiers) {
|
|
5280
|
+
const [, name, trailing] = match;
|
|
5281
|
+
if (trailing || reserved.has(name))
|
|
5282
|
+
continue;
|
|
5283
|
+
place(name, match.index, isPathTail(withoutLiterals, match.index));
|
|
5284
|
+
}
|
|
5285
|
+
return {
|
|
5286
|
+
top: [...top],
|
|
5287
|
+
nested: [...nested].filter((name) => !top.has(name)),
|
|
5288
|
+
hasPredicate: /\[\s*\?/.test(withoutValueLiterals)
|
|
5289
|
+
};
|
|
5290
|
+
}
|
|
5291
|
+
function appearsBelowTopLevel(data, name) {
|
|
5292
|
+
let budget = 2000;
|
|
5293
|
+
const visit = (value, depth) => {
|
|
5294
|
+
if (budget-- <= 0 || depth > 4)
|
|
5295
|
+
return false;
|
|
5296
|
+
if (value === null || typeof value !== "object")
|
|
5297
|
+
return false;
|
|
5298
|
+
if (Array.isArray(value))
|
|
5299
|
+
return value.some((entry) => visit(entry, depth));
|
|
5300
|
+
const record = value;
|
|
5301
|
+
if (depth > 0 && Object.hasOwn(record, name))
|
|
5302
|
+
return true;
|
|
5303
|
+
return Object.values(record).some((entry) => visit(entry, depth + 1));
|
|
5304
|
+
};
|
|
5305
|
+
return visit(data, 0);
|
|
5306
|
+
}
|
|
5307
|
+
function alwaysNullKeys(records) {
|
|
5308
|
+
const objects = records.filter((r) => r != null && typeof r === "object" && !Array.isArray(r));
|
|
5309
|
+
if (objects.length === 0 || objects.length !== records.length)
|
|
5310
|
+
return [];
|
|
5311
|
+
const keys = [...new Set(objects.flatMap((o) => Object.keys(o)))];
|
|
5312
|
+
if (keys.length === 0)
|
|
5313
|
+
return [];
|
|
5314
|
+
const nullKeys = keys.filter((key) => objects.every((record) => record[key] === null));
|
|
5315
|
+
return nullKeys.length === keys.length ? nullKeys : [];
|
|
5316
|
+
}
|
|
5317
|
+
function carriesOnlyNulls(value) {
|
|
5318
|
+
if (value === null)
|
|
5319
|
+
return true;
|
|
5320
|
+
if (Array.isArray(value)) {
|
|
5321
|
+
return value.length > 0 && value.every(carriesOnlyNulls);
|
|
5322
|
+
}
|
|
5323
|
+
if (typeof value === "object" && value !== undefined) {
|
|
5324
|
+
const values = Object.values(value);
|
|
5325
|
+
return values.length > 0 && values.every(carriesOnlyNulls);
|
|
5326
|
+
}
|
|
5327
|
+
return false;
|
|
5328
|
+
}
|
|
5329
|
+
function nameList(names, cap2 = 12) {
|
|
5330
|
+
const shown = names.slice(0, cap2).map((n) => `\`${n}\``);
|
|
5331
|
+
const rest = names.length - shown.length;
|
|
5332
|
+
return shown.join(", ") + (rest > 0 ? `, and ${rest} more` : "");
|
|
5333
|
+
}
|
|
5334
|
+
function buildFilterWarning(filter, data, outcome) {
|
|
5335
|
+
const present = availableFields(data);
|
|
5336
|
+
const refs = referencedFields(filter);
|
|
5337
|
+
const unknown = refs.top.filter((name) => !present.includes(name) && !appearsBelowTopLevel(data, name));
|
|
5338
|
+
const unchecked = refs.nested.filter((name) => !present.includes(name));
|
|
5339
|
+
const count = countRecords(data);
|
|
5340
|
+
const scope = `${count} record(s)`;
|
|
5341
|
+
const isNotAField = (names) => `${nameList(names)} ${names.length === 1 ? "is not a field" : "are not fields"} on the ${scope} it read`;
|
|
5342
|
+
const soundness = unchecked.length > 0 ? `${nameList(unchecked)} ${unchecked.length === 1 ? "reads" : "read"} below the top level, so ${unchecked.length === 1 ? "it was" : "they were"} not checked against the record keys` : refs.top.length > 0 ? "every field it names exists" : "";
|
|
5343
|
+
const withSoundness = (base) => soundness ? `${base}, and ${soundness}` : base;
|
|
5344
|
+
let detail;
|
|
5345
|
+
let lede;
|
|
5346
|
+
if (outcome.kind === "null-elements") {
|
|
5347
|
+
lede = "returned only null values";
|
|
5348
|
+
const projected = `all ${outcome.count} of the elements it projected are null`;
|
|
5349
|
+
if (unknown.length > 0) {
|
|
5350
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
5351
|
+
} else if (unchecked.length > 0) {
|
|
5352
|
+
detail = withSoundness(projected);
|
|
5353
|
+
} else {
|
|
5354
|
+
detail = `${projected}, and every field it names exists — a multi-select list ` + `(\`[A, B]\`) reads each entry against \`Data\` itself, so on a list ` + `result use \`[].[A, B]\` or \`[].{a: A, b: B}\` to read the records`;
|
|
5355
|
+
}
|
|
5356
|
+
} else if (outcome.kind === "null-rows") {
|
|
5357
|
+
lede = "returned only null values";
|
|
5358
|
+
const projected = `every value it projected is null on all ${outcome.count} row(s)`;
|
|
5359
|
+
detail = unknown.length > 0 ? `${projected}, because ${isNotAField(unknown)}` : withSoundness(projected);
|
|
5360
|
+
} else if (outcome.kind === "null-values") {
|
|
5361
|
+
lede = "returned only null values";
|
|
5362
|
+
const projected = `every key it projected (${nameList(outcome.keys)}) is null`;
|
|
5363
|
+
const sameSet = unknown.length === outcome.keys.length && outcome.keys.every((k) => unknown.includes(k));
|
|
5364
|
+
if (sameSet) {
|
|
5365
|
+
detail = `${isNotAField(outcome.keys)}, so every key it projected is null`;
|
|
5366
|
+
} else if (unknown.length > 0) {
|
|
5367
|
+
detail = `${projected}, because ${isNotAField(unknown)}`;
|
|
5368
|
+
} else {
|
|
5369
|
+
detail = withSoundness(`${projected} on all ${scope}`);
|
|
5370
|
+
}
|
|
5371
|
+
} else {
|
|
5372
|
+
lede = "returned nothing";
|
|
5373
|
+
if (unknown.length > 0) {
|
|
5374
|
+
detail = isNotAField(unknown);
|
|
5375
|
+
} else {
|
|
5376
|
+
const selection = refs.hasPredicate ? "no record matched" : "the expression resolved to no value";
|
|
5377
|
+
detail = withSoundness(`${selection} — it read ${scope}`);
|
|
5378
|
+
}
|
|
5379
|
+
}
|
|
5380
|
+
const fields = present.length > 0 ? ` Available fields: ${nameList(present)}.` : "";
|
|
5381
|
+
return `--output-filter ${JSON.stringify(filter)} ${lede}: ${detail}.${fields}`;
|
|
5382
|
+
}
|
|
5383
|
+
function appendWarning(existing, note) {
|
|
5384
|
+
return existing ? `${existing} ${note}` : note;
|
|
5385
|
+
}
|
|
5386
|
+
function applyFilter(data, filter, onWarning) {
|
|
5044
5387
|
const codec = requireJmespath();
|
|
5045
5388
|
let result;
|
|
5046
5389
|
try {
|
|
@@ -5048,9 +5391,34 @@ function applyFilter(data, filter) {
|
|
|
5048
5391
|
} catch (err) {
|
|
5049
5392
|
throw new FilterEvaluationError(filter, err);
|
|
5050
5393
|
}
|
|
5051
|
-
|
|
5394
|
+
const inputCount = countRecords(data);
|
|
5395
|
+
const warn = (outcome) => {
|
|
5396
|
+
if (inputCount === 0)
|
|
5397
|
+
return;
|
|
5398
|
+
const note = buildFilterWarning(filter, data, outcome);
|
|
5399
|
+
getOutputSink().writeErr(`[WARN] ${note}
|
|
5400
|
+
`);
|
|
5401
|
+
onWarning?.(note);
|
|
5402
|
+
};
|
|
5403
|
+
const warnIfAllNull = (records) => {
|
|
5404
|
+
const keys = alwaysNullKeys(records);
|
|
5405
|
+
if (keys.length > 0)
|
|
5406
|
+
warn({ kind: "null-values", keys });
|
|
5407
|
+
};
|
|
5408
|
+
if (result == null) {
|
|
5409
|
+
warn({ kind: "empty" });
|
|
5052
5410
|
return [];
|
|
5411
|
+
}
|
|
5053
5412
|
if (Array.isArray(result)) {
|
|
5413
|
+
if (result.length === 0) {
|
|
5414
|
+
warn({ kind: "empty" });
|
|
5415
|
+
} else if (result.every((entry) => entry === null)) {
|
|
5416
|
+
warn({ kind: "null-elements", count: result.length });
|
|
5417
|
+
} else if (result.every((entry) => Array.isArray(entry)) && carriesOnlyNulls(result)) {
|
|
5418
|
+
warn({ kind: "null-rows", count: result.length });
|
|
5419
|
+
} else {
|
|
5420
|
+
warnIfAllNull(result);
|
|
5421
|
+
}
|
|
5054
5422
|
if (result.length > 0 && typeof result[0] !== "object") {
|
|
5055
5423
|
const fieldMatch = filter.match(/\.(\w+)$/);
|
|
5056
5424
|
const key = fieldMatch ? fieldMatch[1] : "Value";
|
|
@@ -5058,10 +5426,30 @@ function applyFilter(data, filter) {
|
|
|
5058
5426
|
}
|
|
5059
5427
|
return result;
|
|
5060
5428
|
}
|
|
5061
|
-
if (typeof result === "object")
|
|
5429
|
+
if (typeof result === "object") {
|
|
5430
|
+
warnIfAllNull([result]);
|
|
5062
5431
|
return result;
|
|
5432
|
+
}
|
|
5063
5433
|
return { Value: result };
|
|
5064
5434
|
}
|
|
5435
|
+
function filterFailureData(envelope) {
|
|
5436
|
+
const filter = getOutputFilter();
|
|
5437
|
+
const data = envelope.Data;
|
|
5438
|
+
if (!filter || data == null)
|
|
5439
|
+
return;
|
|
5440
|
+
let note;
|
|
5441
|
+
const [filterError, filtered] = catchError(() => applyFilter(data, filter, (n) => {
|
|
5442
|
+
note = n;
|
|
5443
|
+
}));
|
|
5444
|
+
if (filterError) {
|
|
5445
|
+
envelope.Warning = appendWarning(envelope.Warning, `--output-filter was not applied, so Data is shown in full: ${filterError.message}`);
|
|
5446
|
+
return;
|
|
5447
|
+
}
|
|
5448
|
+
envelope.Data = filtered;
|
|
5449
|
+
if (note) {
|
|
5450
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
5451
|
+
}
|
|
5452
|
+
}
|
|
5065
5453
|
function defaultErrorCodeForResult(result) {
|
|
5066
5454
|
switch (result) {
|
|
5067
5455
|
case RESULTS.AuthenticationError:
|
|
@@ -5105,7 +5493,7 @@ function defaultErrorCodeForHttpStatus(status) {
|
|
|
5105
5493
|
return "server_error";
|
|
5106
5494
|
return;
|
|
5107
5495
|
}
|
|
5108
|
-
var LOCAL_PERMISSION_TEXT_PATTERN =
|
|
5496
|
+
var LOCAL_PERMISSION_TEXT_PATTERN = new RegExp(`(?:\\b|\\()(?:${[...LOCAL_PERMISSION_ERROR_CODES].join("|")})(?::\\s|\\))`);
|
|
5109
5497
|
function defaultErrorCodeForFailure(data) {
|
|
5110
5498
|
if (data.Result === RESULTS.Failure) {
|
|
5111
5499
|
const status = data.Context?.httpStatus ?? parseHttpStatusFromMessage2(data.Message);
|
|
@@ -5144,8 +5532,14 @@ var OutputFormatter;
|
|
|
5144
5532
|
}
|
|
5145
5533
|
const filter = getOutputFilter();
|
|
5146
5534
|
if (filter) {
|
|
5147
|
-
|
|
5535
|
+
let note;
|
|
5536
|
+
const filtered = applyFilter(data.Data, filter, (n) => {
|
|
5537
|
+
note = n;
|
|
5538
|
+
});
|
|
5148
5539
|
data.Data = normalize ? normalizeDataKeys(filtered, verbatim, subtrees && { refs: subtrees.refs, mode: "skip" }) : filtered;
|
|
5540
|
+
if (note) {
|
|
5541
|
+
data.Warning = appendWarning(data.Warning, note);
|
|
5542
|
+
}
|
|
5149
5543
|
}
|
|
5150
5544
|
logOutput(normalizeOutputKeys(data), getOutputFormat(), options?.tableRowStyle);
|
|
5151
5545
|
}
|
|
@@ -5173,12 +5567,13 @@ var OutputFormatter;
|
|
|
5173
5567
|
delete envelope.TelemetryErrorClass;
|
|
5174
5568
|
delete envelope.TelemetryTerminalOutcome;
|
|
5175
5569
|
delete envelope.TelemetryTerminalSignal;
|
|
5570
|
+
filterFailureData(envelope);
|
|
5176
5571
|
if (!suppressTelemetry) {
|
|
5177
5572
|
telemetry.trackEvent(CommonTelemetryEvents.Error, {
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5573
|
+
[ErrorDimensions.Result]: data.Result,
|
|
5574
|
+
[ErrorDimensions.ErrorCode]: data.ErrorCode,
|
|
5575
|
+
[ErrorDimensions.Retry]: data.Retry,
|
|
5576
|
+
[ErrorDimensions.ErrorMessage]: data.Message
|
|
5182
5577
|
});
|
|
5183
5578
|
}
|
|
5184
5579
|
logOutput(normalizeOutputKeys(envelope), getOutputFormat());
|
|
@@ -5221,13 +5616,20 @@ var OutputFormatter;
|
|
|
5221
5616
|
OutputFormatter.log = log;
|
|
5222
5617
|
function formatToString(data) {
|
|
5223
5618
|
const filter = getOutputFilter();
|
|
5619
|
+
const envelope = data;
|
|
5224
5620
|
if ("Data" in data && data.Data != null) {
|
|
5225
5621
|
data.Data = normalizeDataKeys(data.Data);
|
|
5226
5622
|
if (filter) {
|
|
5227
|
-
|
|
5623
|
+
let note;
|
|
5624
|
+
data.Data = normalizeDataKeys(applyFilter(data.Data, filter, (n) => {
|
|
5625
|
+
note = n;
|
|
5626
|
+
}));
|
|
5627
|
+
if (note) {
|
|
5628
|
+
envelope.Warning = appendWarning(envelope.Warning, note);
|
|
5629
|
+
}
|
|
5228
5630
|
}
|
|
5229
5631
|
}
|
|
5230
|
-
const output = normalizeOutputKeys(
|
|
5632
|
+
const output = normalizeOutputKeys(envelope);
|
|
5231
5633
|
const lines = [];
|
|
5232
5634
|
const sink = getOutputSink();
|
|
5233
5635
|
printOutput(output, getOutputFormat(), (msg) => {
|
|
@@ -5277,7 +5679,7 @@ var LEGACY_SKILL_NAMESPACE = "uipath:";
|
|
|
5277
5679
|
var MAX_SKILL_NAME_LENGTH = 80;
|
|
5278
5680
|
var SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
5279
5681
|
function productMode(productArea, mode) {
|
|
5280
|
-
return {
|
|
5682
|
+
return { ProductArea: productArea, Mode: mode };
|
|
5281
5683
|
}
|
|
5282
5684
|
function attributionRecord(groups) {
|
|
5283
5685
|
const record = {};
|
|
@@ -5335,6 +5737,7 @@ var COMMAND_ATTRIBUTION = commandAttribution([
|
|
|
5335
5737
|
["rpa", "build", ["uip.rpa-legacy"]],
|
|
5336
5738
|
["conversational", "operate", ["uip.conversational"]],
|
|
5337
5739
|
["agents", "build", ["uip.codedagent", "uip.agent"]],
|
|
5740
|
+
["coding-agents", "build", ["uip.coder"]],
|
|
5338
5741
|
["agenthub", "build", ["uip.agenthub"]],
|
|
5339
5742
|
["coded-apps", "build", ["uip.codedapp"]],
|
|
5340
5743
|
["functions", "build", ["uip.function", "uip.functions"]],
|
|
@@ -5420,32 +5823,64 @@ function normalizeSkillName(value) {
|
|
|
5420
5823
|
function buildCommandTelemetryAttribution(commandPath, skillSource) {
|
|
5421
5824
|
const skillName = normalizeSkillName(skillSource);
|
|
5422
5825
|
return {
|
|
5423
|
-
...skillName ? {
|
|
5826
|
+
...skillName ? { SkillName: skillName } : {},
|
|
5424
5827
|
...getCommandProductModeAttribution(commandPath)
|
|
5425
5828
|
};
|
|
5426
5829
|
}
|
|
5830
|
+
var AGENT_SESSION_ENV = {
|
|
5831
|
+
[BaseDimensions.AgentModel]: "UIPATH_AGENT_MODEL",
|
|
5832
|
+
[SkillsDimensions.PermissionMode]: "UIPATH_PERMISSION_MODE",
|
|
5833
|
+
[SkillsDimensions.EffortLevel]: "UIPATH_EFFORT_LEVEL",
|
|
5834
|
+
[SkillsDimensions.SkillsVersion]: "UIPATH_SKILLS_VERSION"
|
|
5835
|
+
};
|
|
5836
|
+
var MAX_TELEMETRY_TOKEN_LENGTH = 120;
|
|
5837
|
+
function sanitizeTelemetryToken(value) {
|
|
5838
|
+
return value.replace(/[^A-Za-z0-9:._/ -]/g, "_").slice(0, MAX_TELEMETRY_TOKEN_LENGTH);
|
|
5839
|
+
}
|
|
5840
|
+
function buildAgentSessionTelemetry(env) {
|
|
5841
|
+
const dimensions = {};
|
|
5842
|
+
for (const [key, variable] of Object.entries(AGENT_SESSION_ENV)) {
|
|
5843
|
+
const value = env[variable]?.trim();
|
|
5844
|
+
if (value) {
|
|
5845
|
+
dimensions[key] = sanitizeTelemetryToken(value);
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
return dimensions;
|
|
5849
|
+
}
|
|
5427
5850
|
|
|
5428
5851
|
// ../common/src/telemetry/command-name.ts
|
|
5429
|
-
var
|
|
5852
|
+
var TELEMETRY_NAME_ROOT = "Cli";
|
|
5853
|
+
var CLI_COMMAND_ROOT = "uip";
|
|
5854
|
+
var TELEMETRY_NAME_BARE_ACTION = "Invoke";
|
|
5430
5855
|
function commandTelemetryName(parts) {
|
|
5856
|
+
const action = vetCommandTokens(parts).map(pascalizeToken).join("");
|
|
5857
|
+
return `${TELEMETRY_NAME_ROOT}.${action || TELEMETRY_NAME_BARE_ACTION}`;
|
|
5858
|
+
}
|
|
5859
|
+
function commandInvocationPath(parts) {
|
|
5860
|
+
return [CLI_COMMAND_ROOT, ...vetCommandTokens(parts)].join(" ");
|
|
5861
|
+
}
|
|
5862
|
+
function vetCommandTokens(parts) {
|
|
5431
5863
|
const tokens = [];
|
|
5432
5864
|
for (const part of parts) {
|
|
5433
|
-
const pieces = String(part ?? "").split(/\s+/).filter((token) => token && !token.startsWith("-") && token !==
|
|
5865
|
+
const pieces = String(part ?? "").split(/\s+/).filter((token) => token && !token.startsWith("-") && token !== CLI_COMMAND_ROOT);
|
|
5434
5866
|
if (pieces.every(isCommandToken)) {
|
|
5435
5867
|
tokens.push(...pieces);
|
|
5436
5868
|
continue;
|
|
5437
5869
|
}
|
|
5438
5870
|
tokens.push(UNKNOWN_TOKEN);
|
|
5439
5871
|
}
|
|
5440
|
-
return
|
|
5872
|
+
return tokens;
|
|
5873
|
+
}
|
|
5874
|
+
function pascalizeToken(token) {
|
|
5875
|
+
return token.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
5441
5876
|
}
|
|
5442
|
-
var COMMAND_TOKEN_PATTERN = /^[a-
|
|
5877
|
+
var COMMAND_TOKEN_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
5443
5878
|
var MAX_COMMAND_TOKEN_LENGTH = 32;
|
|
5444
5879
|
var GUID_TOKEN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
5445
5880
|
function isCommandToken(token) {
|
|
5446
|
-
return token.length <= MAX_COMMAND_TOKEN_LENGTH && COMMAND_TOKEN_PATTERN.test(token) && !GUID_TOKEN.test(token)
|
|
5881
|
+
return token.length <= MAX_COMMAND_TOKEN_LENGTH && COMMAND_TOKEN_PATTERN.test(token) && !GUID_TOKEN.test(token);
|
|
5447
5882
|
}
|
|
5448
|
-
var UNKNOWN_TOKEN = "
|
|
5883
|
+
var UNKNOWN_TOKEN = "unknown";
|
|
5449
5884
|
|
|
5450
5885
|
// ../common/src/telemetry/invocation-request.ts
|
|
5451
5886
|
var requestContextSlot = singleton("TelemetryInvocationRequestContext");
|
|
@@ -5550,7 +5985,7 @@ function withheldArgumentValues(cmd) {
|
|
|
5550
5985
|
});
|
|
5551
5986
|
return values;
|
|
5552
5987
|
}
|
|
5553
|
-
function
|
|
5988
|
+
function deriveCommandParts(cmd) {
|
|
5554
5989
|
const parts = [];
|
|
5555
5990
|
let current = cmd;
|
|
5556
5991
|
while (current) {
|
|
@@ -5563,14 +5998,13 @@ function deriveCommandPath(cmd) {
|
|
|
5563
5998
|
if (parts.length > 1) {
|
|
5564
5999
|
parts.shift();
|
|
5565
6000
|
}
|
|
5566
|
-
return
|
|
6001
|
+
return parts;
|
|
5567
6002
|
}
|
|
5568
6003
|
function isErrorContext(value) {
|
|
5569
6004
|
return value !== null && typeof value === "object";
|
|
5570
6005
|
}
|
|
5571
6006
|
function commandHelpHint(commandPath) {
|
|
5572
|
-
|
|
5573
|
-
return `An unexpected error occurred. Run '${command} --help' to verify command syntax, or run with --log-level debug for details.`;
|
|
6007
|
+
return `An unexpected error occurred. Run '${commandPath} --help' to verify command syntax, or run with --log-level debug for details.`;
|
|
5574
6008
|
}
|
|
5575
6009
|
function isPromptCancellation(error) {
|
|
5576
6010
|
return error instanceof Error && error.name === "ExitPromptError";
|
|
@@ -5595,7 +6029,9 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
5595
6029
|
yaml: getOutputFormat() === "yaml",
|
|
5596
6030
|
filter: getOutputFilter() !== undefined
|
|
5597
6031
|
});
|
|
5598
|
-
const
|
|
6032
|
+
const commandParts = deriveCommandParts(command);
|
|
6033
|
+
const telemetryName = commandTelemetryName(commandParts);
|
|
6034
|
+
const commandPath = commandInvocationPath(commandParts);
|
|
5599
6035
|
const props = typeof properties === "function" ? properties(...args) : properties;
|
|
5600
6036
|
markCommandStart();
|
|
5601
6037
|
const supplied = recordSuppliedArgumentValues(withheldArgumentValues(command));
|
|
@@ -5630,7 +6066,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
5630
6066
|
Result: finalResult,
|
|
5631
6067
|
...customErrorCode ? { ErrorCode: customErrorCode } : {},
|
|
5632
6068
|
Message: errorMessage,
|
|
5633
|
-
Instructions: customInstructions ?? commandHelpHint(
|
|
6069
|
+
Instructions: customInstructions ?? commandHelpHint(commandPath),
|
|
5634
6070
|
...customRetry ? { Retry: customRetry } : {},
|
|
5635
6071
|
...customContext ? { Context: customContext } : {}
|
|
5636
6072
|
});
|
|
@@ -5647,8 +6083,8 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
5647
6083
|
recordedFailure,
|
|
5648
6084
|
pollSignal: context.pollSignal
|
|
5649
6085
|
});
|
|
5650
|
-
if (terminalTelemetry.
|
|
5651
|
-
telemetry.trackException(error instanceof Error ? error : new Error(String(error)), {
|
|
6086
|
+
if (terminalTelemetry[CommandDimensions.ErrorClass] === "internal" && error) {
|
|
6087
|
+
telemetry.trackException(error instanceof Error ? error : new Error(String(error)), { [CommandDimensions.CommandName]: commandPath }, getInvocationRequestContext());
|
|
5652
6088
|
}
|
|
5653
6089
|
const commandParams = extractCommandParams(command);
|
|
5654
6090
|
if (props) {
|
|
@@ -5659,10 +6095,12 @@ Command.prototype.trackedAction = function(context, fn, properties) {
|
|
|
5659
6095
|
const baseProperties = redactProperties({
|
|
5660
6096
|
...commandParams,
|
|
5661
6097
|
...props,
|
|
5662
|
-
...buildCommandTelemetryAttribution(
|
|
5663
|
-
|
|
6098
|
+
...buildCommandTelemetryAttribution(commandPath, process.env.UIPATH_SKILL),
|
|
6099
|
+
...buildAgentSessionTelemetry(process.env),
|
|
6100
|
+
[CommandDimensions.CommandName]: commandPath,
|
|
6101
|
+
[CommandDimensions.IsCommand]: "true",
|
|
5664
6102
|
...terminalTelemetry,
|
|
5665
|
-
...errorMessage ? { errorMessage } : {}
|
|
6103
|
+
...errorMessage ? { [CommandDimensions.ErrorMessage]: errorMessage } : {}
|
|
5666
6104
|
});
|
|
5667
6105
|
emitInvocationRequest(telemetryName, success, baseProperties);
|
|
5668
6106
|
} finally {
|
|
@@ -5907,6 +6345,43 @@ var BOOLEAN_FLAGS = new Set(HOST_GLOBAL_FLAGS);
|
|
|
5907
6345
|
// ../common/src/interactivity-context.ts
|
|
5908
6346
|
var modeSlot = singleton("InteractivityMode");
|
|
5909
6347
|
var interactiveFlagSlot = singleton("InteractiveFlag");
|
|
6348
|
+
function getInteractivityMode() {
|
|
6349
|
+
return modeSlot.get("auto") ?? "auto";
|
|
6350
|
+
}
|
|
6351
|
+
// ../common/src/mime-types.ts
|
|
6352
|
+
var MIME_TYPES_BY_EXTENSION = Object.freeze({
|
|
6353
|
+
pdf: "application/pdf",
|
|
6354
|
+
png: "image/png",
|
|
6355
|
+
jpg: "image/jpeg",
|
|
6356
|
+
jpeg: "image/jpeg",
|
|
6357
|
+
gif: "image/gif",
|
|
6358
|
+
webp: "image/webp",
|
|
6359
|
+
bmp: "image/bmp",
|
|
6360
|
+
tif: "image/tiff",
|
|
6361
|
+
tiff: "image/tiff",
|
|
6362
|
+
svg: "image/svg+xml",
|
|
6363
|
+
txt: "text/plain",
|
|
6364
|
+
log: "text/plain",
|
|
6365
|
+
md: "text/markdown",
|
|
6366
|
+
csv: "text/csv",
|
|
6367
|
+
tsv: "text/tab-separated-values",
|
|
6368
|
+
json: "application/json",
|
|
6369
|
+
xml: "application/xml",
|
|
6370
|
+
html: "text/html",
|
|
6371
|
+
htm: "text/html",
|
|
6372
|
+
yaml: "application/yaml",
|
|
6373
|
+
yml: "application/yaml",
|
|
6374
|
+
doc: "application/msword",
|
|
6375
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
6376
|
+
xls: "application/vnd.ms-excel",
|
|
6377
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
6378
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
6379
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
6380
|
+
zip: "application/zip",
|
|
6381
|
+
mp3: "audio/mpeg",
|
|
6382
|
+
wav: "audio/wav",
|
|
6383
|
+
mp4: "video/mp4"
|
|
6384
|
+
});
|
|
5910
6385
|
// ../common/src/option-aliases.ts
|
|
5911
6386
|
function resolveDeprecatedOptionAlias({
|
|
5912
6387
|
preferredValue,
|
|
@@ -6415,6 +6890,7 @@ var ScreenLogger;
|
|
|
6415
6890
|
})(ScreenLogger ||= {});
|
|
6416
6891
|
// ../common/src/sdk-user-agent.ts
|
|
6417
6892
|
var USER_AGENT_HEADER = "User-Agent";
|
|
6893
|
+
var AGENT_PROPERTY = BaseDimensions.Agent;
|
|
6418
6894
|
var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
|
|
6419
6895
|
function userAgentPatchKey(userAgent) {
|
|
6420
6896
|
return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
|
|
@@ -7022,7 +7498,7 @@ var package_default2 = {
|
|
|
7022
7498
|
name: "@uipath/integrationservice-sdk",
|
|
7023
7499
|
author: "UiPath",
|
|
7024
7500
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
7025
|
-
version: "1.
|
|
7501
|
+
version: "1.204.0-preview.211",
|
|
7026
7502
|
repository: {
|
|
7027
7503
|
type: "git",
|
|
7028
7504
|
url: "https://github.com/UiPath/cli.git",
|
|
@@ -13073,6 +13549,11 @@ var pickName = (claims) => {
|
|
|
13073
13549
|
const username = asString(claims?.preferred_username);
|
|
13074
13550
|
return asString(claims?.name) ?? (looksLikeEmail(username) ? undefined : username);
|
|
13075
13551
|
};
|
|
13552
|
+
var pickScopes = (claims) => {
|
|
13553
|
+
const raw = claims?.scope;
|
|
13554
|
+
const scopes = Array.isArray(raw) ? raw.filter((entry) => asString(entry) !== undefined) : typeof raw === "string" ? raw.split(/\s+/).filter(Boolean) : [];
|
|
13555
|
+
return scopes.length > 0 ? scopes : undefined;
|
|
13556
|
+
};
|
|
13076
13557
|
var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
13077
13558
|
const claims = accessToken ? decodeClaims(accessToken) : undefined;
|
|
13078
13559
|
const email = pickEmail(claims);
|
|
@@ -13098,6 +13579,7 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
13098
13579
|
identity.clientId = clientId;
|
|
13099
13580
|
return identity;
|
|
13100
13581
|
};
|
|
13582
|
+
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
13101
13583
|
|
|
13102
13584
|
// ../auth/src/envAuth.ts
|
|
13103
13585
|
var ENV_AUTH_ENABLE_VAR = "UIPATH_CLI_ENABLE_ENV_AUTH";
|
|
@@ -13170,6 +13652,7 @@ var readAuthFromEnv = () => {
|
|
|
13170
13652
|
const expiration = getTokenExpiration(accessToken);
|
|
13171
13653
|
const loginStatus = expiration && expiration <= new Date ? "Expired" : "Logged in";
|
|
13172
13654
|
const identity = resolveSessionIdentity(accessToken);
|
|
13655
|
+
const scopes = readTokenScopes(accessToken);
|
|
13173
13656
|
return {
|
|
13174
13657
|
loginStatus,
|
|
13175
13658
|
accessToken,
|
|
@@ -13180,7 +13663,8 @@ var readAuthFromEnv = () => {
|
|
|
13180
13663
|
tenantId,
|
|
13181
13664
|
expiration,
|
|
13182
13665
|
source: "env-vars" /* EnvironmentVariables */,
|
|
13183
|
-
...identity ? { identity } : {}
|
|
13666
|
+
...identity ? { identity } : {},
|
|
13667
|
+
...scopes ? { scopes } : {}
|
|
13184
13668
|
};
|
|
13185
13669
|
};
|
|
13186
13670
|
|
|
@@ -13818,10 +14302,15 @@ async function buildFileStatus(tokens, credentials, globalHint) {
|
|
|
13818
14302
|
}
|
|
13819
14303
|
function identityFields(accessToken, credentials) {
|
|
13820
14304
|
const identity = resolveSessionIdentity(accessToken, parseAuthFlow(credentials[AUTH_FLOW_ENV_VAR]));
|
|
13821
|
-
|
|
14305
|
+
const scopes = readTokenScopes(accessToken);
|
|
14306
|
+
return {
|
|
14307
|
+
...identity ? { identity } : {},
|
|
14308
|
+
...scopes ? { scopes } : {}
|
|
14309
|
+
};
|
|
13822
14310
|
}
|
|
13823
14311
|
function buildRobotStatus(robotCreds) {
|
|
13824
14312
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
14313
|
+
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
13825
14314
|
return {
|
|
13826
14315
|
loginStatus: "Logged in",
|
|
13827
14316
|
accessToken: robotCreds.accessToken,
|
|
@@ -13833,7 +14322,8 @@ function buildRobotStatus(robotCreds) {
|
|
|
13833
14322
|
issuer: robotCreds.issuer,
|
|
13834
14323
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
13835
14324
|
source: "robot" /* Robot */,
|
|
13836
|
-
...identity ? { identity } : {}
|
|
14325
|
+
...identity ? { identity } : {},
|
|
14326
|
+
...scopes ? { scopes } : {}
|
|
13837
14327
|
};
|
|
13838
14328
|
}
|
|
13839
14329
|
var isFileNotFoundError = (error) => {
|
|
@@ -14100,7 +14590,8 @@ var getAuthContext = async (options = {}) => {
|
|
|
14100
14590
|
organizationId: status.organizationId,
|
|
14101
14591
|
organizationName: status.organizationName,
|
|
14102
14592
|
tenantId: status.tenantId,
|
|
14103
|
-
tenantName
|
|
14593
|
+
tenantName,
|
|
14594
|
+
identity: status.identity
|
|
14104
14595
|
};
|
|
14105
14596
|
};
|
|
14106
14597
|
// ../auth/src/tenantSelection.ts
|
|
@@ -14998,6 +15489,577 @@ function filterByTriggerMode(activities, isTrigger) {
|
|
|
14998
15489
|
return activities.filter((a) => a.isTrigger === isTrigger);
|
|
14999
15490
|
}
|
|
15000
15491
|
|
|
15492
|
+
// src/services/activity-metadata/text.ts
|
|
15493
|
+
function asText(v, fallback = "") {
|
|
15494
|
+
if (typeof v === "string") {
|
|
15495
|
+
return v;
|
|
15496
|
+
}
|
|
15497
|
+
if (v === undefined || v === null) {
|
|
15498
|
+
return fallback;
|
|
15499
|
+
}
|
|
15500
|
+
if (typeof v === "number" || typeof v === "boolean") {
|
|
15501
|
+
return String(v);
|
|
15502
|
+
}
|
|
15503
|
+
return JSON.stringify(v) ?? fallback;
|
|
15504
|
+
}
|
|
15505
|
+
|
|
15506
|
+
// src/services/activity-metadata/annotate.ts
|
|
15507
|
+
var asBag = (v) => v && typeof v === "object" ? v : {};
|
|
15508
|
+
var TS_TYPE = {
|
|
15509
|
+
string: "string",
|
|
15510
|
+
integer: "number",
|
|
15511
|
+
number: "number",
|
|
15512
|
+
double: "number",
|
|
15513
|
+
float: "number",
|
|
15514
|
+
boolean: "boolean",
|
|
15515
|
+
object: "Record<string, unknown>",
|
|
15516
|
+
array: "unknown[]",
|
|
15517
|
+
date: "string",
|
|
15518
|
+
datetime: "string"
|
|
15519
|
+
};
|
|
15520
|
+
function firstLine(description) {
|
|
15521
|
+
const text = asText(description);
|
|
15522
|
+
return text ? text.split(`
|
|
15523
|
+
`)[0] : undefined;
|
|
15524
|
+
}
|
|
15525
|
+
function tsType(raw) {
|
|
15526
|
+
return TS_TYPE[asText(raw).toLowerCase()] ?? "unknown";
|
|
15527
|
+
}
|
|
15528
|
+
var emptyNode = () => ({ children: new Map, isArray: false });
|
|
15529
|
+
function insert(root, leaf) {
|
|
15530
|
+
const parts = leaf.path.split(".");
|
|
15531
|
+
let node2 = root;
|
|
15532
|
+
parts.forEach((rawPart, i) => {
|
|
15533
|
+
const isArray = rawPart.endsWith("[*]");
|
|
15534
|
+
const key = isArray ? rawPart.slice(0, -3) : rawPart;
|
|
15535
|
+
if (!node2.children.has(key)) {
|
|
15536
|
+
node2.children.set(key, emptyNode());
|
|
15537
|
+
}
|
|
15538
|
+
const child = node2.children.get(key);
|
|
15539
|
+
if (isArray) {
|
|
15540
|
+
child.isArray = true;
|
|
15541
|
+
}
|
|
15542
|
+
if (i === parts.length - 1) {
|
|
15543
|
+
child.leaf = leaf;
|
|
15544
|
+
}
|
|
15545
|
+
node2 = child;
|
|
15546
|
+
});
|
|
15547
|
+
}
|
|
15548
|
+
function render(node2, indent = " ") {
|
|
15549
|
+
const lines = [];
|
|
15550
|
+
for (const [key, child] of node2.children) {
|
|
15551
|
+
const opt = child.leaf?.optional ?? true ? "?" : "";
|
|
15552
|
+
const comment = child.leaf?.comment ? ` // ${child.leaf.comment}` : "";
|
|
15553
|
+
let type;
|
|
15554
|
+
if (child.children.size > 0) {
|
|
15555
|
+
const inner = render(child, `${indent} `);
|
|
15556
|
+
type = `{
|
|
15557
|
+
${inner}${indent}}`;
|
|
15558
|
+
} else {
|
|
15559
|
+
type = child.leaf ? child.leaf.type : "unknown";
|
|
15560
|
+
}
|
|
15561
|
+
if (child.isArray) {
|
|
15562
|
+
type = `Array<${type}>`;
|
|
15563
|
+
}
|
|
15564
|
+
lines.push(`${indent}${key}${opt}: ${type};${comment}`);
|
|
15565
|
+
}
|
|
15566
|
+
return lines.length ? `${lines.join(`
|
|
15567
|
+
`)}
|
|
15568
|
+
` : "";
|
|
15569
|
+
}
|
|
15570
|
+
function block(name, leaves) {
|
|
15571
|
+
if (leaves.length === 0) {
|
|
15572
|
+
return;
|
|
15573
|
+
}
|
|
15574
|
+
const root = emptyNode();
|
|
15575
|
+
for (const l of leaves) {
|
|
15576
|
+
insert(root, l);
|
|
15577
|
+
}
|
|
15578
|
+
return `type ${name} = {
|
|
15579
|
+
${render(root)}};`;
|
|
15580
|
+
}
|
|
15581
|
+
function firstMethod(sr) {
|
|
15582
|
+
const methods = asBag(asBag(sr.metadata).method);
|
|
15583
|
+
const verb = Object.keys(methods)[0] ?? "GET";
|
|
15584
|
+
return { verb, def: asBag(methods[verb]) };
|
|
15585
|
+
}
|
|
15586
|
+
function paramLeaves(def, kind) {
|
|
15587
|
+
return (def.parameters ?? []).map(asBag).filter((p) => asText(p.type).toLowerCase() === kind).map((p) => ({
|
|
15588
|
+
path: asText(p.name),
|
|
15589
|
+
type: tsType(p.dataType ?? p.type),
|
|
15590
|
+
optional: p.required !== true,
|
|
15591
|
+
comment: firstLine(p.description)
|
|
15592
|
+
}));
|
|
15593
|
+
}
|
|
15594
|
+
function fieldLeaves(sr, verb, side) {
|
|
15595
|
+
const out = [];
|
|
15596
|
+
const walk = (obj, prefix) => {
|
|
15597
|
+
for (const [key, value] of Object.entries(asBag(obj))) {
|
|
15598
|
+
const v = asBag(value);
|
|
15599
|
+
if (v.method && v.type) {
|
|
15600
|
+
const m = asBag(v.method)[verb];
|
|
15601
|
+
if (m && asBag(m)[side] === true) {
|
|
15602
|
+
out.push({
|
|
15603
|
+
path: prefix + key,
|
|
15604
|
+
type: tsType(v.type),
|
|
15605
|
+
optional: !(asBag(m).required === true || v.required === true),
|
|
15606
|
+
comment: firstLine(v.description)
|
|
15607
|
+
});
|
|
15608
|
+
}
|
|
15609
|
+
} else if (value && typeof value === "object") {
|
|
15610
|
+
walk(value, `${prefix + key}.`);
|
|
15611
|
+
}
|
|
15612
|
+
}
|
|
15613
|
+
};
|
|
15614
|
+
walk(sr.fields, "");
|
|
15615
|
+
return out;
|
|
15616
|
+
}
|
|
15617
|
+
function pascal(raw) {
|
|
15618
|
+
const cleaned = raw.replace(/[^A-Za-z0-9]+(.)?/g, (_, c) => c ? c.toUpperCase() : "");
|
|
15619
|
+
return cleaned.charAt(0).toUpperCase() + cleaned.slice(1) || "Action";
|
|
15620
|
+
}
|
|
15621
|
+
function buildTypeHeader(sr) {
|
|
15622
|
+
const name = pascal(asText(sr.name, "Action"));
|
|
15623
|
+
const { verb, def } = firstMethod(sr);
|
|
15624
|
+
const isList = asText(def.operation).toLowerCase() === "list";
|
|
15625
|
+
const body = block(`${name}RequestBody`, fieldLeaves(sr, verb, "request"));
|
|
15626
|
+
const query = block(`${name}RequestQuery`, paramLeaves(def, "query"));
|
|
15627
|
+
const path2 = block(`${name}RequestPath`, paramLeaves(def, "path"));
|
|
15628
|
+
let response = block(`${name}Response`, fieldLeaves(sr, verb, "response"));
|
|
15629
|
+
if (isList && response) {
|
|
15630
|
+
response = response.replace(`type ${name}Response = {`, `type ${name}ResponseRecord = {`).concat(`
|
|
15631
|
+
|
|
15632
|
+
type ${name}Response = Array<${name}ResponseRecord>;`);
|
|
15633
|
+
}
|
|
15634
|
+
const bodyType = body ? `${name}RequestBody` : "unknown";
|
|
15635
|
+
const queryType = query ? `${name}RequestQuery` : "Record<string, string>";
|
|
15636
|
+
const responseType = response ? `${name}Response` : "unknown";
|
|
15637
|
+
const context = [
|
|
15638
|
+
"type Context = {",
|
|
15639
|
+
" request: {",
|
|
15640
|
+
` body?: ${bodyType};`,
|
|
15641
|
+
` query?: ${queryType};`,
|
|
15642
|
+
" headers?: Record<string, string>;",
|
|
15643
|
+
" };",
|
|
15644
|
+
" connectionConfiguration?: Record<string, string>;",
|
|
15645
|
+
" connectorKey: string;",
|
|
15646
|
+
" connectionId: string;",
|
|
15647
|
+
"};"
|
|
15648
|
+
].join(`
|
|
15649
|
+
`);
|
|
15650
|
+
const signature = [
|
|
15651
|
+
"// execute(context: Context): Promise<{",
|
|
15652
|
+
`// status: number; headers?: { name: string; value: string }[]; body: ${responseType};`,
|
|
15653
|
+
"// }>",
|
|
15654
|
+
"// Docs only — generated from the activity metadata; re-run on change."
|
|
15655
|
+
].join(`
|
|
15656
|
+
`);
|
|
15657
|
+
const parts = [body, query, path2, response, context, signature].filter((b) => b !== undefined);
|
|
15658
|
+
return `/*
|
|
15659
|
+
${parts.join(`
|
|
15660
|
+
|
|
15661
|
+
`)}
|
|
15662
|
+
*/
|
|
15663
|
+
`;
|
|
15664
|
+
}
|
|
15665
|
+
function injectTypeHeader(source, header) {
|
|
15666
|
+
const leading = /^\s*\/\*[\s\S]*?\*\/\s*\n/;
|
|
15667
|
+
return leading.test(source) ? source.replace(leading, header) : `${header}
|
|
15668
|
+
${source}`;
|
|
15669
|
+
}
|
|
15670
|
+
|
|
15671
|
+
// src/services/activity-metadata/generate.ts
|
|
15672
|
+
var VERB_SLOTS = ["GET", "GETBYID", "POST", "PUT", "PATCH", "DELETE"];
|
|
15673
|
+
var VERB_OP = {
|
|
15674
|
+
GET: "List",
|
|
15675
|
+
GETBYID: "Retrieve",
|
|
15676
|
+
POST: "Create",
|
|
15677
|
+
PUT: "Replace",
|
|
15678
|
+
PATCH: "Update",
|
|
15679
|
+
DELETE: "Delete"
|
|
15680
|
+
};
|
|
15681
|
+
var OPERATIONS = [
|
|
15682
|
+
"Unknown",
|
|
15683
|
+
"List",
|
|
15684
|
+
"Retrieve",
|
|
15685
|
+
"Replace",
|
|
15686
|
+
"Update",
|
|
15687
|
+
"Create",
|
|
15688
|
+
"Delete",
|
|
15689
|
+
"Upload",
|
|
15690
|
+
"Download"
|
|
15691
|
+
];
|
|
15692
|
+
function humanize(s) {
|
|
15693
|
+
const last = s.replace(/\[\*\]$/, "").split(".").pop() ?? s;
|
|
15694
|
+
return last.replaceAll("_", " ").replaceAll(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
|
|
15695
|
+
}
|
|
15696
|
+
function fieldName(e) {
|
|
15697
|
+
return e.isArray ? `${e.name}[*]` : e.name;
|
|
15698
|
+
}
|
|
15699
|
+
function referenceFor(l) {
|
|
15700
|
+
return {
|
|
15701
|
+
scriptRef: l.scriptRef,
|
|
15702
|
+
lookupValue: l.value,
|
|
15703
|
+
lookupNames: l.display
|
|
15704
|
+
};
|
|
15705
|
+
}
|
|
15706
|
+
function fieldEntry(verb, e, dir) {
|
|
15707
|
+
const m = { name: verb };
|
|
15708
|
+
if (dir === "request") {
|
|
15709
|
+
m.request = true;
|
|
15710
|
+
if (e.required) {
|
|
15711
|
+
m.required = true;
|
|
15712
|
+
}
|
|
15713
|
+
if (e.returned) {
|
|
15714
|
+
m.response = true;
|
|
15715
|
+
}
|
|
15716
|
+
} else {
|
|
15717
|
+
m.response = true;
|
|
15718
|
+
}
|
|
15719
|
+
const f = {
|
|
15720
|
+
name: fieldName(e),
|
|
15721
|
+
type: e.type,
|
|
15722
|
+
displayName: e.displayName ?? humanize(e.name)
|
|
15723
|
+
};
|
|
15724
|
+
if (e.description) {
|
|
15725
|
+
f.description = e.description;
|
|
15726
|
+
}
|
|
15727
|
+
f.method = { [verb]: m };
|
|
15728
|
+
if (e.primaryKey) {
|
|
15729
|
+
f.primaryKey = true;
|
|
15730
|
+
}
|
|
15731
|
+
if (e.enum) {
|
|
15732
|
+
f.enum = e.enum;
|
|
15733
|
+
}
|
|
15734
|
+
if (e.defaultValue !== undefined) {
|
|
15735
|
+
f.defaultValue = e.defaultValue;
|
|
15736
|
+
}
|
|
15737
|
+
if (e.lookup) {
|
|
15738
|
+
f.reference = referenceFor(e.lookup);
|
|
15739
|
+
}
|
|
15740
|
+
if (dir === "request" && e.design) {
|
|
15741
|
+
f.design = e.design;
|
|
15742
|
+
}
|
|
15743
|
+
return f;
|
|
15744
|
+
}
|
|
15745
|
+
function generateActivityMetadata(min) {
|
|
15746
|
+
const a = min.activity;
|
|
15747
|
+
const verb = String(a.httpMethod).toUpperCase();
|
|
15748
|
+
const inputs = min.inputs ?? [];
|
|
15749
|
+
const outputs = min.outputs ?? [];
|
|
15750
|
+
const urlIns = inputs.filter((i) => i.in === "path" || i.in === "query");
|
|
15751
|
+
const bodyIns = inputs.filter((i) => i.in === "body");
|
|
15752
|
+
const parameters = urlIns.map((i) => {
|
|
15753
|
+
const p = {
|
|
15754
|
+
name: i.name,
|
|
15755
|
+
description: i.description,
|
|
15756
|
+
type: i.in,
|
|
15757
|
+
dataType: i.type,
|
|
15758
|
+
displayName: i.displayName ?? humanize(i.name)
|
|
15759
|
+
};
|
|
15760
|
+
if (i.required) {
|
|
15761
|
+
p.required = true;
|
|
15762
|
+
}
|
|
15763
|
+
if (i.defaultValue !== undefined) {
|
|
15764
|
+
p.defaultValue = i.defaultValue;
|
|
15765
|
+
}
|
|
15766
|
+
if (i.enum) {
|
|
15767
|
+
p.enhancedEnum = i.enum;
|
|
15768
|
+
}
|
|
15769
|
+
if (i.lookup) {
|
|
15770
|
+
p.reference = referenceFor(i.lookup);
|
|
15771
|
+
}
|
|
15772
|
+
if (i.design) {
|
|
15773
|
+
p.design = i.design;
|
|
15774
|
+
}
|
|
15775
|
+
return p;
|
|
15776
|
+
});
|
|
15777
|
+
const fields = {};
|
|
15778
|
+
for (const i of bodyIns) {
|
|
15779
|
+
fields[fieldName(i)] = fieldEntry(verb, i, "request");
|
|
15780
|
+
}
|
|
15781
|
+
for (const i of urlIns.filter((x) => x.returned)) {
|
|
15782
|
+
fields[fieldName(i)] = fieldEntry(verb, {
|
|
15783
|
+
...i,
|
|
15784
|
+
required: false,
|
|
15785
|
+
lookup: undefined,
|
|
15786
|
+
design: undefined,
|
|
15787
|
+
returned: false
|
|
15788
|
+
}, "response");
|
|
15789
|
+
}
|
|
15790
|
+
for (const o of outputs) {
|
|
15791
|
+
const key = fieldName(o);
|
|
15792
|
+
const existing = fields[key];
|
|
15793
|
+
if (existing) {
|
|
15794
|
+
const method = existing.method;
|
|
15795
|
+
method[verb].response = true;
|
|
15796
|
+
if (o.primaryKey) {
|
|
15797
|
+
existing.primaryKey = true;
|
|
15798
|
+
}
|
|
15799
|
+
} else {
|
|
15800
|
+
fields[key] = fieldEntry(verb, o, "response");
|
|
15801
|
+
}
|
|
15802
|
+
}
|
|
15803
|
+
const primaryKey = Object.values(fields).filter((f) => f.primaryKey).map((f) => f.name);
|
|
15804
|
+
const operation = a.operation ?? VERB_OP[verb];
|
|
15805
|
+
const methodObj = {
|
|
15806
|
+
operation,
|
|
15807
|
+
method: verb === "GETBYID" ? "GET" : verb,
|
|
15808
|
+
path: a.vendorPath,
|
|
15809
|
+
scriptRef: a.scriptRef
|
|
15810
|
+
};
|
|
15811
|
+
if (a.description) {
|
|
15812
|
+
methodObj.description = a.description;
|
|
15813
|
+
}
|
|
15814
|
+
if (parameters.length) {
|
|
15815
|
+
methodObj.parameters = parameters;
|
|
15816
|
+
}
|
|
15817
|
+
return {
|
|
15818
|
+
name: a.name,
|
|
15819
|
+
displayName: a.displayName ?? humanize(a.name),
|
|
15820
|
+
description: a.description,
|
|
15821
|
+
type: "standard",
|
|
15822
|
+
elementKey: a.elementKey,
|
|
15823
|
+
path: a.vendorPath,
|
|
15824
|
+
metadata: {
|
|
15825
|
+
...primaryKey.length ? { primaryKey } : {},
|
|
15826
|
+
method: { [verb]: methodObj }
|
|
15827
|
+
},
|
|
15828
|
+
fields
|
|
15829
|
+
};
|
|
15830
|
+
}
|
|
15831
|
+
|
|
15832
|
+
// src/services/activity-metadata/validate.ts
|
|
15833
|
+
var BANNED_REFERENCE_KEYS = [
|
|
15834
|
+
"path",
|
|
15835
|
+
"objectName",
|
|
15836
|
+
"childPath",
|
|
15837
|
+
"hydration",
|
|
15838
|
+
"dependsOn"
|
|
15839
|
+
];
|
|
15840
|
+
var asBag2 = (v) => v && typeof v === "object" ? v : {};
|
|
15841
|
+
var isBareName = (v) => !/[\\/.]/.test(asText(v));
|
|
15842
|
+
function checkReference(where, r, errs) {
|
|
15843
|
+
const scriptRef = r.scriptRef;
|
|
15844
|
+
if (!scriptRef) {
|
|
15845
|
+
errs.push(`${where}: reference.scriptRef is required (this structure is scriptRef-only)`);
|
|
15846
|
+
} else if (!isBareName(scriptRef)) {
|
|
15847
|
+
errs.push(`${where}: scriptRef "${asText(scriptRef)}" must be a bare base name (no path, no extension)`);
|
|
15848
|
+
}
|
|
15849
|
+
if (!r.lookupValue) {
|
|
15850
|
+
errs.push(`${where}: reference.lookupValue is required`);
|
|
15851
|
+
}
|
|
15852
|
+
if (!Array.isArray(r.lookupNames) || r.lookupNames.length === 0) {
|
|
15853
|
+
errs.push(`${where}: reference.lookupNames must be a non-empty array`);
|
|
15854
|
+
}
|
|
15855
|
+
for (const banned of BANNED_REFERENCE_KEYS) {
|
|
15856
|
+
if (r[banned] !== undefined) {
|
|
15857
|
+
errs.push(`${where}: reference must not carry "${banned}" (obsolete / not used in this structure)`);
|
|
15858
|
+
}
|
|
15859
|
+
}
|
|
15860
|
+
}
|
|
15861
|
+
function checkDesign(where, d, required, errs) {
|
|
15862
|
+
if (!d) {
|
|
15863
|
+
errs.push(`${where}: every input must carry a design block (authored in the min-file)`);
|
|
15864
|
+
return;
|
|
15865
|
+
}
|
|
15866
|
+
const design = asBag2(d);
|
|
15867
|
+
const position = asText(design.position);
|
|
15868
|
+
if (!["primary", "secondary"].includes(position)) {
|
|
15869
|
+
errs.push(`${where}: design.position must be primary|secondary (got "${position}")`);
|
|
15870
|
+
} else if (required && position !== "primary") {
|
|
15871
|
+
errs.push(`${where}: required input must have design.position "primary"`);
|
|
15872
|
+
} else if (!required && position !== "secondary") {
|
|
15873
|
+
errs.push(`${where}: optional input must have design.position "secondary"`);
|
|
15874
|
+
}
|
|
15875
|
+
if (design.component === "FolderPicker" && design.enableUserOverride) {
|
|
15876
|
+
errs.push(`${where}: FolderPicker lookups must not set enableUserOverride`);
|
|
15877
|
+
}
|
|
15878
|
+
}
|
|
15879
|
+
function checkSource(min, errs) {
|
|
15880
|
+
for (const i of [...min.inputs ?? [], ...min.outputs ?? []]) {
|
|
15881
|
+
const delimiter = asBag2(i.design).delimiter;
|
|
15882
|
+
if (i.isArray && delimiter != null) {
|
|
15883
|
+
errs.push(`input ${i.name}: isArray and design.delimiter are mutually exclusive (a true array is never joined)`);
|
|
15884
|
+
}
|
|
15885
|
+
}
|
|
15886
|
+
for (const i of min.inputs ?? []) {
|
|
15887
|
+
if (i.primaryKey && !i.returned) {
|
|
15888
|
+
errs.push(`input ${i.name}: primaryKey requires returned:true (primaryKey is a response-side fact)`);
|
|
15889
|
+
}
|
|
15890
|
+
}
|
|
15891
|
+
}
|
|
15892
|
+
function verbSlot(sr, errs) {
|
|
15893
|
+
const methods = asBag2(asBag2(sr.metadata).method);
|
|
15894
|
+
const verbSlots = Object.keys(methods);
|
|
15895
|
+
if (verbSlots.length !== 1) {
|
|
15896
|
+
errs.push(`metadata.method must have exactly ONE verb slot (got ${verbSlots.length}) — an activity is always single-verb`);
|
|
15897
|
+
}
|
|
15898
|
+
const verb = verbSlots[0];
|
|
15899
|
+
return { verb, m: asBag2(methods[verb]) };
|
|
15900
|
+
}
|
|
15901
|
+
function checkRequiredKeys(sr, verb, m, errs) {
|
|
15902
|
+
for (const k of ["name", "displayName", "description", "metadata"]) {
|
|
15903
|
+
if (!sr[k]) {
|
|
15904
|
+
errs.push(`missing top-level "${k}"`);
|
|
15905
|
+
}
|
|
15906
|
+
}
|
|
15907
|
+
for (const k of ["operation", "method", "path", "scriptRef"]) {
|
|
15908
|
+
if (!m[k]) {
|
|
15909
|
+
errs.push(`method ${verb}: missing "${k}"`);
|
|
15910
|
+
}
|
|
15911
|
+
}
|
|
15912
|
+
if (m.scriptRef && !isBareName(m.scriptRef)) {
|
|
15913
|
+
errs.push(`method ${verb}: scriptRef "${asText(m.scriptRef)}" must be a bare base name (no path, no extension)`);
|
|
15914
|
+
}
|
|
15915
|
+
}
|
|
15916
|
+
function checkParameter(raw, errs) {
|
|
15917
|
+
const p = asBag2(raw);
|
|
15918
|
+
const label = `parameter ${asText(p.name, "?")}`;
|
|
15919
|
+
for (const k of [
|
|
15920
|
+
"name",
|
|
15921
|
+
"description",
|
|
15922
|
+
"type",
|
|
15923
|
+
"dataType",
|
|
15924
|
+
"displayName"
|
|
15925
|
+
]) {
|
|
15926
|
+
if (!p[k]) {
|
|
15927
|
+
errs.push(`${label}: missing "${k}"`);
|
|
15928
|
+
}
|
|
15929
|
+
}
|
|
15930
|
+
const type = asText(p.type);
|
|
15931
|
+
if (type && !["path", "query"].includes(type)) {
|
|
15932
|
+
errs.push(`${label}: type must be path|query (got "${type}") — body inputs are fields`);
|
|
15933
|
+
}
|
|
15934
|
+
if (p.enum) {
|
|
15935
|
+
errs.push(`${label}: parameters use enhancedEnum, never the deprecated enum`);
|
|
15936
|
+
}
|
|
15937
|
+
if (p.reference) {
|
|
15938
|
+
checkReference(label, asBag2(p.reference), errs);
|
|
15939
|
+
}
|
|
15940
|
+
checkDesign(label, p.design, Boolean(p.required), errs);
|
|
15941
|
+
}
|
|
15942
|
+
function checkField(verb, k, rawField, errs) {
|
|
15943
|
+
const f = asBag2(rawField);
|
|
15944
|
+
for (const key of ["name", "type", "displayName", "method"]) {
|
|
15945
|
+
if (!f[key]) {
|
|
15946
|
+
errs.push(`field ${k}: missing "${key}"`);
|
|
15947
|
+
}
|
|
15948
|
+
}
|
|
15949
|
+
const fm = asBag2(asBag2(f.method)[verb]);
|
|
15950
|
+
if (Object.keys(fm).length === 0) {
|
|
15951
|
+
errs.push(`field ${k}: no method entry for verb ${verb}`);
|
|
15952
|
+
return;
|
|
15953
|
+
}
|
|
15954
|
+
if (f.primaryKey && !fm.response) {
|
|
15955
|
+
errs.push(`field ${k}: primaryKey on a field that is not returned`);
|
|
15956
|
+
}
|
|
15957
|
+
if (k.endsWith("[*]") && asBag2(f.design).delimiter != null) {
|
|
15958
|
+
errs.push(`field ${k}: a true-array field must not carry a delimiter`);
|
|
15959
|
+
}
|
|
15960
|
+
if (f.reference) {
|
|
15961
|
+
checkReference(`field ${k}`, asBag2(f.reference), errs);
|
|
15962
|
+
}
|
|
15963
|
+
if (fm.request) {
|
|
15964
|
+
checkDesign(`field ${k}`, f.design, Boolean(fm.required), errs);
|
|
15965
|
+
} else if (f.design) {
|
|
15966
|
+
errs.push(`field ${k}: response-only fields must not carry design`);
|
|
15967
|
+
}
|
|
15968
|
+
}
|
|
15969
|
+
function checkListOutputs(sr, verb, m, errs) {
|
|
15970
|
+
if (m.operation !== "List") {
|
|
15971
|
+
return;
|
|
15972
|
+
}
|
|
15973
|
+
const outs = Object.entries(asBag2(sr.fields)).filter(([, f]) => asBag2(asBag2(asBag2(f).method)[verb]).response);
|
|
15974
|
+
if (outs.length === 0) {
|
|
15975
|
+
errs.push("List operation must declare the returned element's fields as outputs");
|
|
15976
|
+
} else if (outs.length === 1 && /^[^.]+\[\*\]$/.test(outs[0][0])) {
|
|
15977
|
+
errs.push(`List operation output "${outs[0][0]}" is a records-array wrapper — declare the element's fields (id, name, …) flat instead; the action returns the bare array`);
|
|
15978
|
+
}
|
|
15979
|
+
}
|
|
15980
|
+
function checkClosedSets(verb, m, errs) {
|
|
15981
|
+
if (verb && !VERB_SLOTS.includes(verb)) {
|
|
15982
|
+
errs.push(`httpMethod "${verb}" not in ${VERB_SLOTS.join("|")} (the single-record slot is GETBYID, no underscores)`);
|
|
15983
|
+
}
|
|
15984
|
+
const operation = asText(m.operation);
|
|
15985
|
+
if (operation && !OPERATIONS.includes(operation)) {
|
|
15986
|
+
errs.push(`operation "${operation}" not in ${OPERATIONS.join("|")}`);
|
|
15987
|
+
}
|
|
15988
|
+
}
|
|
15989
|
+
function collectActivityMetadataErrors(min, sr) {
|
|
15990
|
+
const errs = [];
|
|
15991
|
+
checkSource(min, errs);
|
|
15992
|
+
const { verb, m } = verbSlot(sr, errs);
|
|
15993
|
+
checkRequiredKeys(sr, verb, m, errs);
|
|
15994
|
+
for (const raw of m.parameters ?? []) {
|
|
15995
|
+
checkParameter(raw, errs);
|
|
15996
|
+
}
|
|
15997
|
+
for (const [k, rawField] of Object.entries(asBag2(sr.fields))) {
|
|
15998
|
+
checkField(verb, k, rawField, errs);
|
|
15999
|
+
}
|
|
16000
|
+
checkListOutputs(sr, verb, m, errs);
|
|
16001
|
+
checkClosedSets(verb, m, errs);
|
|
16002
|
+
return errs;
|
|
16003
|
+
}
|
|
16004
|
+
function validateActivityMetadata(min, sr) {
|
|
16005
|
+
const errs = collectActivityMetadataErrors(min, sr);
|
|
16006
|
+
if (errs.length) {
|
|
16007
|
+
throw new Error(`activity metadata invalid:
|
|
16008
|
+
- ${errs.join(`
|
|
16009
|
+
- `)}`);
|
|
16010
|
+
}
|
|
16011
|
+
}
|
|
16012
|
+
|
|
16013
|
+
// src/services/activity-metadata/index.ts
|
|
16014
|
+
async function readJson(path2, what) {
|
|
16015
|
+
const fs2 = getFileSystem();
|
|
16016
|
+
const raw = await fs2.readFile(path2, "utf-8");
|
|
16017
|
+
if (raw === null || raw === undefined) {
|
|
16018
|
+
throw new Error(`${what} not found: ${path2}`);
|
|
16019
|
+
}
|
|
16020
|
+
try {
|
|
16021
|
+
return JSON.parse(raw);
|
|
16022
|
+
} catch (err) {
|
|
16023
|
+
throw new Error(`${what} is not valid JSON (${path2}): ${err instanceof Error ? err.message : String(err)}`);
|
|
16024
|
+
}
|
|
16025
|
+
}
|
|
16026
|
+
async function generateActivityMetadataFile(minFile, outFile) {
|
|
16027
|
+
const out = outFile ?? (minFile.endsWith(".min.json") ? minFile.replace(/\.min\.json$/, ".json") : null);
|
|
16028
|
+
if (!out) {
|
|
16029
|
+
throw new Error(`cannot derive an output path: ${minFile} does not end in .min.json — pass --out`);
|
|
16030
|
+
}
|
|
16031
|
+
const min = await readJson(minFile, "minimal-metadata file");
|
|
16032
|
+
if (!min.activity) {
|
|
16033
|
+
throw new Error(`${minFile} has no "activity" block`);
|
|
16034
|
+
}
|
|
16035
|
+
const sr = generateActivityMetadata(min);
|
|
16036
|
+
validateActivityMetadata(min, sr);
|
|
16037
|
+
const fs2 = getFileSystem();
|
|
16038
|
+
await fs2.writeFile(out, `${JSON.stringify(sr, null, 2)}
|
|
16039
|
+
`);
|
|
16040
|
+
const primaryKey = sr.metadata?.primaryKey;
|
|
16041
|
+
return {
|
|
16042
|
+
Out: out,
|
|
16043
|
+
Name: asText(sr.name),
|
|
16044
|
+
Fields: Object.keys(sr.fields ?? {}).length,
|
|
16045
|
+
...Array.isArray(primaryKey) ? { PrimaryKey: primaryKey } : {}
|
|
16046
|
+
};
|
|
16047
|
+
}
|
|
16048
|
+
async function stampTypeHeader(metadataFile, scriptFile) {
|
|
16049
|
+
const sr = await readJson(metadataFile, "activity metadata");
|
|
16050
|
+
const fs2 = getFileSystem();
|
|
16051
|
+
const source = await fs2.readFile(scriptFile, "utf-8");
|
|
16052
|
+
if (source === null || source === undefined) {
|
|
16053
|
+
throw new Error(`action script not found: ${scriptFile}`);
|
|
16054
|
+
}
|
|
16055
|
+
const header = buildTypeHeader(sr);
|
|
16056
|
+
await fs2.writeFile(scriptFile, injectTypeHeader(source, header));
|
|
16057
|
+
return {
|
|
16058
|
+
Script: scriptFile,
|
|
16059
|
+
Types: (header.match(/^type /gm) ?? []).length
|
|
16060
|
+
};
|
|
16061
|
+
}
|
|
16062
|
+
|
|
15001
16063
|
// src/store/cache.ts
|
|
15002
16064
|
var fs2 = getFileSystem();
|
|
15003
16065
|
var HOUR = 60 * 60 * 1000;
|
|
@@ -15050,7 +16112,7 @@ async function buildPath(parts, tenantName) {
|
|
|
15050
16112
|
function sanitizeObjectNameForFile(objectName) {
|
|
15051
16113
|
return objectName.replace(/[<>:"/\\|?*]/g, "_");
|
|
15052
16114
|
}
|
|
15053
|
-
async function
|
|
16115
|
+
async function readJson2(filePath, ttlMs, schema) {
|
|
15054
16116
|
if (filePath === null)
|
|
15055
16117
|
return null;
|
|
15056
16118
|
const [err, raw] = await catchError(fs2.readFile(filePath, "utf-8"));
|
|
@@ -15088,7 +16150,7 @@ function resolveCacheKey(id) {
|
|
|
15088
16150
|
return id || "_static";
|
|
15089
16151
|
}
|
|
15090
16152
|
async function readConnectors(tenantName) {
|
|
15091
|
-
return
|
|
16153
|
+
return readJson2(await buildPath(["connectors.json"], tenantName), TTL.connectors, CONNECTORS_CACHE_SCHEMA);
|
|
15092
16154
|
}
|
|
15093
16155
|
async function writeConnectors(connectors, tenantName) {
|
|
15094
16156
|
const compact = connectors.map((c) => ({
|
|
@@ -15111,7 +16173,7 @@ function connectionsFile(folderKey, allFolders) {
|
|
|
15111
16173
|
return folderKey ? `connections.folder.${folderKey}.json` : "connections.json";
|
|
15112
16174
|
}
|
|
15113
16175
|
async function readConnections(connectorKey, folderKey, tenantName, allFolders) {
|
|
15114
|
-
return
|
|
16176
|
+
return readJson2(await buildPath([connectorKey, connectionsFile(folderKey, allFolders)], tenantName), TTL.connections);
|
|
15115
16177
|
}
|
|
15116
16178
|
async function writeConnections(connectorKey, connections, folderKey, tenantName, allFolders, detailsComplete = false) {
|
|
15117
16179
|
const compact = connections.map((c) => ({
|
|
@@ -15133,7 +16195,7 @@ async function writeConnections(connectorKey, connections, folderKey, tenantName
|
|
|
15133
16195
|
await writeJson(await buildPath([connectorKey, connectionsFile(folderKey, allFolders)], tenantName), compact);
|
|
15134
16196
|
}
|
|
15135
16197
|
async function readActivities(connectorKey, tenantName) {
|
|
15136
|
-
return
|
|
16198
|
+
return readJson2(await buildPath([connectorKey, "activities.json"], tenantName), TTL.activities);
|
|
15137
16199
|
}
|
|
15138
16200
|
async function writeActivities(connectorKey, activities, tenantName) {
|
|
15139
16201
|
const compact = activities.map((a) => ({
|
|
@@ -15149,7 +16211,7 @@ async function writeActivities(connectorKey, activities, tenantName) {
|
|
|
15149
16211
|
await writeJson(await buildPath([connectorKey, "activities.json"], tenantName), compact);
|
|
15150
16212
|
}
|
|
15151
16213
|
async function readResourcesList(connectorKey, connectionId, tenantName) {
|
|
15152
|
-
return
|
|
16214
|
+
return readJson2(await buildPath([connectorKey, connectionId, "resources.json"], tenantName), TTL.resources);
|
|
15153
16215
|
}
|
|
15154
16216
|
async function writeResourcesList(connectorKey, connectionId, resources, tenantName) {
|
|
15155
16217
|
const compact = resources.map((r) => ({
|
|
@@ -15169,7 +16231,7 @@ function schemaFileName(objectName, activityVersion) {
|
|
|
15169
16231
|
return `${sanitizeObjectNameForFile(objectName)}${versionSegment}.schema.json`;
|
|
15170
16232
|
}
|
|
15171
16233
|
async function readSchema(connectorKey, connectionId, objectName, tenantName, activityVersion) {
|
|
15172
|
-
return
|
|
16234
|
+
return readJson2(await buildPath([
|
|
15173
16235
|
connectorKey,
|
|
15174
16236
|
resolveCacheKey(connectionId),
|
|
15175
16237
|
schemaFileName(objectName, activityVersion)
|
|
@@ -15183,13 +16245,13 @@ async function writeSchema(connectorKey, connectionId, objectName, schema, tenan
|
|
|
15183
16245
|
], tenantName), schema);
|
|
15184
16246
|
}
|
|
15185
16247
|
async function readTriggerObjects(connectorKey, connectionId, operation, tenantName) {
|
|
15186
|
-
return
|
|
16248
|
+
return readJson2(await buildPath([connectorKey, connectionId, "triggers", operation, "objects.json"], tenantName), TTL.triggerObjects);
|
|
15187
16249
|
}
|
|
15188
16250
|
async function writeTriggerObjects(connectorKey, connectionId, operation, objects, tenantName) {
|
|
15189
16251
|
await writeJson(await buildPath([connectorKey, connectionId, "triggers", operation, "objects.json"], tenantName), objects);
|
|
15190
16252
|
}
|
|
15191
16253
|
async function readTypecachePackages(projectType, tenantName) {
|
|
15192
|
-
return
|
|
16254
|
+
return readJson2(await buildPath(["typecache", projectType, "connectors.json"], tenantName), TTL.typecache);
|
|
15193
16255
|
}
|
|
15194
16256
|
async function writeTypecachePackages(projectType, connectors, tenantName) {
|
|
15195
16257
|
const compact = connectors.map((c) => ({
|
|
@@ -15200,7 +16262,7 @@ async function writeTypecachePackages(projectType, connectors, tenantName) {
|
|
|
15200
16262
|
await writeJson(await buildPath(["typecache", projectType, "connectors.json"], tenantName), compact);
|
|
15201
16263
|
}
|
|
15202
16264
|
async function readTypecacheActivities(projectType, connectorKey, tenantName) {
|
|
15203
|
-
return
|
|
16265
|
+
return readJson2(await buildPath(["typecache", projectType, connectorKey, "activities.json"], tenantName), TTL.typecache);
|
|
15204
16266
|
}
|
|
15205
16267
|
async function writeTypecacheActivities(projectType, connectorKey, activities, tenantName) {
|
|
15206
16268
|
const compact = activities.map((a) => ({
|
|
@@ -15214,7 +16276,7 @@ async function writeTypecacheActivities(projectType, connectorKey, activities, t
|
|
|
15214
16276
|
await writeJson(await buildPath(["typecache", projectType, connectorKey, "activities.json"], tenantName), compact);
|
|
15215
16277
|
}
|
|
15216
16278
|
async function readTriggerMetadata(connectorKey, connectionId, operation, objectName, tenantName) {
|
|
15217
|
-
return
|
|
16279
|
+
return readJson2(await buildPath([
|
|
15218
16280
|
connectorKey,
|
|
15219
16281
|
connectionId,
|
|
15220
16282
|
"triggers",
|
|
@@ -15271,6 +16333,31 @@ var ACTIVITIES_LIST_EXAMPLES = [
|
|
|
15271
16333
|
}
|
|
15272
16334
|
}
|
|
15273
16335
|
];
|
|
16336
|
+
var METADATA_GENERATE_EXAMPLES = [
|
|
16337
|
+
{
|
|
16338
|
+
Description: "Generate activity metadata from a minimal-metadata file",
|
|
16339
|
+
Command: "uip is activities metadata generate ./AddUsersToUsergroup.min.json",
|
|
16340
|
+
Output: {
|
|
16341
|
+
Code: "ActivityMetadataGenerated",
|
|
16342
|
+
Data: {
|
|
16343
|
+
Out: "./AddUsersToUsergroup.json",
|
|
16344
|
+
Name: "AddUsersToUsergroup",
|
|
16345
|
+
Fields: 12,
|
|
16346
|
+
PrimaryKey: ["usergroup.id"]
|
|
16347
|
+
}
|
|
16348
|
+
}
|
|
16349
|
+
}
|
|
16350
|
+
];
|
|
16351
|
+
var SCRIPT_UPDATE_EXAMPLES = [
|
|
16352
|
+
{
|
|
16353
|
+
Description: "Update an action script's type header in place from its activity metadata",
|
|
16354
|
+
Command: "uip is activities script update ./AddUsersToUsergroup.js --metadata ./AddUsersToUsergroup.json",
|
|
16355
|
+
Output: {
|
|
16356
|
+
Code: "ScriptUpdated",
|
|
16357
|
+
Data: { Script: "./AddUsersToUsergroup.js", Types: 4 }
|
|
16358
|
+
}
|
|
16359
|
+
}
|
|
16360
|
+
];
|
|
15274
16361
|
var registerActivitiesCommand = (program2) => {
|
|
15275
16362
|
const activities = program2.command("activities").description("Manage UiPath Integration Service activities");
|
|
15276
16363
|
activities.command("list").description("List activities for a connector").argument("<connector-key>", "Connector key (e.g., uipath-zoho-desk)").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--refresh", "Force re-fetch from API, ignoring cache").option("--triggers", "List trigger activities only").examples(ACTIVITIES_LIST_EXAMPLES).trackedAction(processContext, async (connectorKey, options) => {
|
|
@@ -15316,6 +16403,44 @@ var registerActivitiesCommand = (program2) => {
|
|
|
15316
16403
|
emptyInstructions: !data || data.length === 0 ? `No activities found for connector '${connectorKey}'. Check that the connector key is correct.` : isTriggerMode ? `No trigger activities found for connector '${connectorKey}'. This connector has no trigger activities.` : `No non-trigger activities found for connector '${connectorKey}'. All activities are triggers — use --triggers to list them.`
|
|
15317
16404
|
});
|
|
15318
16405
|
});
|
|
16406
|
+
const metadata = activities.command("metadata").description("Generate activity metadata from a minimal-metadata file");
|
|
16407
|
+
metadata.command("generate").description("Generate activity metadata from a minimal-metadata file").argument("<min-file>", "Path to the <name>.min.json file").option("--out <file>", "Output path (default: the input with .min.json → .json)").examples(METADATA_GENERATE_EXAMPLES).trackedAction(processContext, async (minFile, options) => {
|
|
16408
|
+
const [error, result] = await catchError(generateActivityMetadataFile(minFile, options.out));
|
|
16409
|
+
if (error) {
|
|
16410
|
+
OutputFormatter.error({
|
|
16411
|
+
Result: RESULTS.Failure,
|
|
16412
|
+
ErrorCode: "invalid_metadata",
|
|
16413
|
+
Message: `Could not generate activity metadata: ${error.message}`,
|
|
16414
|
+
Instructions: "Fix the minimal-metadata file and regenerate — never hand-edit the generated metadata."
|
|
16415
|
+
});
|
|
16416
|
+
processContext.exit(1);
|
|
16417
|
+
return;
|
|
16418
|
+
}
|
|
16419
|
+
OutputFormatter.success({
|
|
16420
|
+
Result: RESULTS.Success,
|
|
16421
|
+
Code: "ActivityMetadataGenerated",
|
|
16422
|
+
Data: result
|
|
16423
|
+
});
|
|
16424
|
+
});
|
|
16425
|
+
const script = activities.command("script").description("Manage activity action scripts");
|
|
16426
|
+
script.command("update").description("Update an action script's type header in place from its activity metadata").argument("<script-file>", "Path to the action script (.js) to update").requiredOption("--metadata <file>", "Path to the activity metadata JSON the type header is derived from").examples(SCRIPT_UPDATE_EXAMPLES).trackedAction(processContext, async (scriptFile, options) => {
|
|
16427
|
+
const [error, result] = await catchError(stampTypeHeader(options.metadata, scriptFile));
|
|
16428
|
+
if (error) {
|
|
16429
|
+
OutputFormatter.error({
|
|
16430
|
+
Result: RESULTS.Failure,
|
|
16431
|
+
ErrorCode: "invalid_metadata",
|
|
16432
|
+
Message: `Could not update the script's type header: ${error.message}`,
|
|
16433
|
+
Instructions: "Check both paths exist and the metadata file is valid JSON."
|
|
16434
|
+
});
|
|
16435
|
+
processContext.exit(1);
|
|
16436
|
+
return;
|
|
16437
|
+
}
|
|
16438
|
+
OutputFormatter.success({
|
|
16439
|
+
Result: RESULTS.Success,
|
|
16440
|
+
Code: "ScriptUpdated",
|
|
16441
|
+
Data: result
|
|
16442
|
+
});
|
|
16443
|
+
});
|
|
15319
16444
|
};
|
|
15320
16445
|
|
|
15321
16446
|
// src/helpers/connections.ts
|
|
@@ -15409,7 +16534,8 @@ var POLL_EXIT_CODES = {
|
|
|
15409
16534
|
[PollOutcome.Interrupted]: 1,
|
|
15410
16535
|
[PollOutcome.Aborted]: 1
|
|
15411
16536
|
};
|
|
15412
|
-
function handleAuthPollFailure(outcome, error, noun, retryCommand) {
|
|
16537
|
+
function handleAuthPollFailure(outcome, error, noun, retryCommand, authUrl) {
|
|
16538
|
+
const target = authUrl ? authUrl : "the authentication URL";
|
|
15413
16539
|
const messages = {
|
|
15414
16540
|
[PollOutcome.Timeout]: `${noun} timed out after 5 minutes`,
|
|
15415
16541
|
[PollOutcome.Failed]: `${noun} polling failed: ${error?.message ?? "too many consecutive errors"}`,
|
|
@@ -15419,19 +16545,20 @@ function handleAuthPollFailure(outcome, error, noun, retryCommand) {
|
|
|
15419
16545
|
OutputFormatter.error({
|
|
15420
16546
|
Result: RESULTS.Failure,
|
|
15421
16547
|
Message: messages[outcome] ?? `${noun} polling failed`,
|
|
15422
|
-
Instructions: `Open
|
|
16548
|
+
Instructions: `Open ${target} while it is valid, then retry. For scripts, run '${retryCommand} --no-wait' to return the pending authorization details without polling.`
|
|
15423
16549
|
});
|
|
15424
16550
|
processContext.exit(POLL_EXIT_CODES[outcome] ?? 1);
|
|
15425
16551
|
}
|
|
15426
16552
|
function normalizeSessionStatus(session) {
|
|
15427
16553
|
return (session.status ?? "pending").toLowerCase();
|
|
15428
16554
|
}
|
|
16555
|
+
var PENDING_AUTHORIZATION_INSTRUCTIONS = "Open AuthUrl to authorize the connection, then run 'uip is connections list' or 'uip is connections ping <connection-id>' to verify the connection.";
|
|
15429
16556
|
function writePendingAuthorization(connectorKey, connectionId, response) {
|
|
15430
16557
|
const data = {
|
|
15431
16558
|
Status: "AuthorizationPending",
|
|
15432
16559
|
SessionId: response.sessionId,
|
|
15433
16560
|
AuthUrl: response.authUrl,
|
|
15434
|
-
Instructions:
|
|
16561
|
+
Instructions: PENDING_AUTHORIZATION_INSTRUCTIONS
|
|
15435
16562
|
};
|
|
15436
16563
|
if (connectorKey)
|
|
15437
16564
|
data.Connector = connectorKey;
|
|
@@ -15579,7 +16706,7 @@ var CONNECTIONS_LIST_EXAMPLES = [
|
|
|
15579
16706
|
];
|
|
15580
16707
|
var CONNECTIONS_CREATE_EXAMPLES = [
|
|
15581
16708
|
{
|
|
15582
|
-
Description: "Create a new OAuth connection",
|
|
16709
|
+
Description: "Create a new OAuth connection from an interactive terminal: the browser opens and the command waits for the consent",
|
|
15583
16710
|
Command: "uip is connections create uipath-zoho-desk",
|
|
15584
16711
|
Output: {
|
|
15585
16712
|
Code: "ConnectionCreated",
|
|
@@ -15593,6 +16720,21 @@ var CONNECTIONS_CREATE_EXAMPLES = [
|
|
|
15593
16720
|
FolderKey: "f0f0f0f0-0000-0000-0000-000000000001"
|
|
15594
16721
|
}
|
|
15595
16722
|
}
|
|
16723
|
+
},
|
|
16724
|
+
{
|
|
16725
|
+
Description: "The same command with nobody at the terminal (an agent, a CI job, a piped run) or with --no-wait: no browser is opened and the authorization is handed back to finish elsewhere",
|
|
16726
|
+
Command: "uip is connections create uipath-zoho-desk",
|
|
16727
|
+
Output: {
|
|
16728
|
+
Code: "ConnectionAuthorizationPending",
|
|
16729
|
+
Data: {
|
|
16730
|
+
Status: "AuthorizationPending",
|
|
16731
|
+
SessionId: "b2c3d4e5-0000-0000-0000-000000000020",
|
|
16732
|
+
AuthUrl: "https://cloud.uipath.com/connections_/authorize/b2c3d4e5-0000-0000-0000-000000000020",
|
|
16733
|
+
Instructions: PENDING_AUTHORIZATION_INSTRUCTIONS,
|
|
16734
|
+
Connector: "uipath-zoho-desk",
|
|
16735
|
+
ExpiresAt: 1774000000
|
|
16736
|
+
}
|
|
16737
|
+
}
|
|
15596
16738
|
}
|
|
15597
16739
|
];
|
|
15598
16740
|
var CONNECTIONS_PING_EXAMPLES = [
|
|
@@ -15638,7 +16780,7 @@ var CONNECTIONS_DELETE_EXAMPLES = [
|
|
|
15638
16780
|
];
|
|
15639
16781
|
var CONNECTIONS_EDIT_EXAMPLES = [
|
|
15640
16782
|
{
|
|
15641
|
-
Description: "Re-authenticate an existing connection",
|
|
16783
|
+
Description: "Re-authenticate an existing connection from an interactive terminal: the browser opens and the command waits for the consent",
|
|
15642
16784
|
Command: "uip is connections edit a1b2c3d4-0000-0000-0000-000000000001",
|
|
15643
16785
|
Output: {
|
|
15644
16786
|
Code: "ConnectionEdited",
|
|
@@ -15647,6 +16789,21 @@ var CONNECTIONS_EDIT_EXAMPLES = [
|
|
|
15647
16789
|
State: "Enabled"
|
|
15648
16790
|
}
|
|
15649
16791
|
}
|
|
16792
|
+
},
|
|
16793
|
+
{
|
|
16794
|
+
Description: "The same command with nobody at the terminal (an agent, a CI job, a piped run) or with --no-wait: no browser is opened and the re-authorization is handed back to finish elsewhere",
|
|
16795
|
+
Command: "uip is connections edit a1b2c3d4-0000-0000-0000-000000000001",
|
|
16796
|
+
Output: {
|
|
16797
|
+
Code: "ConnectionAuthorizationPending",
|
|
16798
|
+
Data: {
|
|
16799
|
+
Status: "AuthorizationPending",
|
|
16800
|
+
SessionId: "b2c3d4e5-0000-0000-0000-000000000021",
|
|
16801
|
+
AuthUrl: "https://cloud.uipath.com/connections_/authorize/b2c3d4e5-0000-0000-0000-000000000021",
|
|
16802
|
+
Instructions: PENDING_AUTHORIZATION_INSTRUCTIONS,
|
|
16803
|
+
ConnectionId: "a1b2c3d4-0000-0000-0000-000000000001",
|
|
16804
|
+
ExpiresAt: 1774000000
|
|
16805
|
+
}
|
|
16806
|
+
}
|
|
15650
16807
|
}
|
|
15651
16808
|
];
|
|
15652
16809
|
var CONNECTIONS_EXPORT_EXAMPLES = [
|
|
@@ -15898,7 +17055,7 @@ var registerConnectionsCommand = (program2) => {
|
|
|
15898
17055
|
Data: result
|
|
15899
17056
|
});
|
|
15900
17057
|
});
|
|
15901
|
-
connections.command("create").description("Create a new connection (OAuth flow)").argument("<connector-key>", "Connector key").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--no-browser", "Don't auto-open browser").option("--no-wait", "Return pending authorization details without polling").examples(CONNECTIONS_CREATE_EXAMPLES).trackedAction(processContext, async (connectorKey, options) => {
|
|
17058
|
+
connections.command("create").description("Create a new connection (OAuth flow)").argument("<connector-key>", "Connector key").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--no-browser", "Don't auto-open browser").option("--no-wait", "Return pending authorization details without opening a browser or polling").examples(CONNECTIONS_CREATE_EXAMPLES).trackedAction(processContext, async (connectorKey, options) => {
|
|
15902
17059
|
logger.info(`Creating connection for: ${connectorKey}`);
|
|
15903
17060
|
const [configError, config] = await catchError(createConnectionsConfig({ tenant: options.tenant }));
|
|
15904
17061
|
if (configError) {
|
|
@@ -15930,18 +17087,16 @@ var registerConnectionsCommand = (program2) => {
|
|
|
15930
17087
|
}
|
|
15931
17088
|
logger.info(`Session: ${createResponse.sessionId}`);
|
|
15932
17089
|
logger.info(`Auth URL: ${createResponse.authUrl}`);
|
|
15933
|
-
if (options.
|
|
15934
|
-
const [openError] = await catchError(openBrowser(createResponse.authUrl));
|
|
15935
|
-
if (openError) {
|
|
15936
|
-
logger.info(`Open manually: ${createResponse.authUrl}`);
|
|
15937
|
-
}
|
|
15938
|
-
} else {
|
|
15939
|
-
logger.info(`Open in browser: ${createResponse.authUrl}`);
|
|
15940
|
-
}
|
|
15941
|
-
if (options.wait === false) {
|
|
17090
|
+
if (options.wait === false || !canFinishBrowserFlow()) {
|
|
15942
17091
|
writePendingAuthorization(connectorKey, undefined, createResponse);
|
|
15943
17092
|
return;
|
|
15944
17093
|
}
|
|
17094
|
+
const opened = options.browser !== false && await tryOpenAuthUrl(createResponse.authUrl);
|
|
17095
|
+
if (!opened && createResponse.authUrl) {
|
|
17096
|
+
OutputFormatter.log({
|
|
17097
|
+
Message: `Open this URL to authorize: ${createResponse.authUrl}`
|
|
17098
|
+
});
|
|
17099
|
+
}
|
|
15945
17100
|
const pollResult = await pollUntil({
|
|
15946
17101
|
fn: () => sessionsApi.apiV1SessionsSessionIdGet({
|
|
15947
17102
|
sessionId: createResponse.sessionId
|
|
@@ -15996,7 +17151,7 @@ var registerConnectionsCommand = (program2) => {
|
|
|
15996
17151
|
processContext.exit(1);
|
|
15997
17152
|
return;
|
|
15998
17153
|
}
|
|
15999
|
-
handleAuthPollFailure(pollResult.outcome, pollResult.error, "Authentication", `uip is connections create ${connectorKey}
|
|
17154
|
+
handleAuthPollFailure(pollResult.outcome, pollResult.error, "Authentication", `uip is connections create ${connectorKey}`, createResponse.authUrl);
|
|
16000
17155
|
});
|
|
16001
17156
|
connections.command("ping").description("Check if a connection is active").argument("<connection-id>", "Connection ID").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--force-refresh", "Force a live connection status refresh").examples(CONNECTIONS_PING_EXAMPLES).trackedAction(processContext, async (connectionId, options) => {
|
|
16002
17157
|
logger.info(`Pinging: ${connectionId}`);
|
|
@@ -16235,7 +17390,7 @@ var registerConnectionsCommand = (program2) => {
|
|
|
16235
17390
|
}
|
|
16236
17391
|
});
|
|
16237
17392
|
});
|
|
16238
|
-
connections.command("edit").description("Re-authenticate a connection (OAuth flow)").argument("<connection-id>", "Connection ID").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--no-browser", "Don't auto-open browser").option("--no-wait", "Return pending authorization details without polling").examples(CONNECTIONS_EDIT_EXAMPLES).trackedAction(processContext, async (connectionId, options) => {
|
|
17393
|
+
connections.command("edit").description("Re-authenticate a connection (OAuth flow)").argument("<connection-id>", "Connection ID").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--no-browser", "Don't auto-open browser").option("--no-wait", "Return pending authorization details without opening a browser or polling").examples(CONNECTIONS_EDIT_EXAMPLES).trackedAction(processContext, async (connectionId, options) => {
|
|
16239
17394
|
logger.info(`Re-authenticating: ${connectionId}`);
|
|
16240
17395
|
const [configError, config] = await catchError(createConnectionsConfig({ tenant: options.tenant }));
|
|
16241
17396
|
if (configError) {
|
|
@@ -16263,18 +17418,16 @@ var registerConnectionsCommand = (program2) => {
|
|
|
16263
17418
|
return;
|
|
16264
17419
|
}
|
|
16265
17420
|
logger.info(`Auth URL: ${editResponse.authUrl}`);
|
|
16266
|
-
if (options.
|
|
16267
|
-
const [openError] = await catchError(openBrowser(editResponse.authUrl));
|
|
16268
|
-
if (openError) {
|
|
16269
|
-
logger.info(`Open manually: ${editResponse.authUrl}`);
|
|
16270
|
-
}
|
|
16271
|
-
} else {
|
|
16272
|
-
logger.info(`Open in browser: ${editResponse.authUrl}`);
|
|
16273
|
-
}
|
|
16274
|
-
if (options.wait === false) {
|
|
17421
|
+
if (options.wait === false || !canFinishBrowserFlow()) {
|
|
16275
17422
|
writePendingAuthorization(undefined, connectionId, editResponse);
|
|
16276
17423
|
return;
|
|
16277
17424
|
}
|
|
17425
|
+
const opened = options.browser !== false && await tryOpenAuthUrl(editResponse.authUrl);
|
|
17426
|
+
if (!opened && editResponse.authUrl) {
|
|
17427
|
+
OutputFormatter.log({
|
|
17428
|
+
Message: `Open this URL to authorize: ${editResponse.authUrl}`
|
|
17429
|
+
});
|
|
17430
|
+
}
|
|
16278
17431
|
const pollResult = await pollUntil({
|
|
16279
17432
|
fn: () => sessionsApi.apiV1SessionsSessionIdGet({
|
|
16280
17433
|
sessionId: editResponse.sessionId
|
|
@@ -16309,7 +17462,7 @@ var registerConnectionsCommand = (program2) => {
|
|
|
16309
17462
|
processContext.exit(1);
|
|
16310
17463
|
return;
|
|
16311
17464
|
}
|
|
16312
|
-
handleAuthPollFailure(pollResult.outcome, pollResult.error, "Re-authentication", `uip is connections edit ${connectionId}
|
|
17465
|
+
handleAuthPollFailure(pollResult.outcome, pollResult.error, "Re-authentication", `uip is connections edit ${connectionId}`, editResponse.authUrl);
|
|
16313
17466
|
});
|
|
16314
17467
|
connections.command("base-url").description("Get the API base URL for a connection").argument("<connection-id>", "Connection ID").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).examples(CONNECTIONS_BASE_URL_EXAMPLES).trackedAction(processContext, async (connectionId, options) => {
|
|
16315
17468
|
logger.info(`Fetching base URL for: ${connectionId}`);
|
|
@@ -16334,8 +17487,19 @@ var registerConnectionsCommand = (program2) => {
|
|
|
16334
17487
|
});
|
|
16335
17488
|
});
|
|
16336
17489
|
};
|
|
16337
|
-
|
|
16338
|
-
|
|
17490
|
+
function canFinishBrowserFlow() {
|
|
17491
|
+
const mode = getInteractivityMode();
|
|
17492
|
+
if (mode !== "auto") {
|
|
17493
|
+
return mode === "always";
|
|
17494
|
+
}
|
|
17495
|
+
return getOutputSink().capabilities.isInteractive;
|
|
17496
|
+
}
|
|
17497
|
+
async function tryOpenAuthUrl(url) {
|
|
17498
|
+
if (!url) {
|
|
17499
|
+
return false;
|
|
17500
|
+
}
|
|
17501
|
+
const [openError] = await catchError(getFileSystem().utils.open(url));
|
|
17502
|
+
return !openError;
|
|
16339
17503
|
}
|
|
16340
17504
|
|
|
16341
17505
|
// src/helpers/connectors.ts
|
|
@@ -18335,7 +19499,7 @@ function isRec(value) {
|
|
|
18335
19499
|
function pascalCase2(s) {
|
|
18336
19500
|
return s.split(/[_\-/\s]+/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
18337
19501
|
}
|
|
18338
|
-
function
|
|
19502
|
+
function humanize2(s) {
|
|
18339
19503
|
return s.split(/[_\-/\s]+/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
18340
19504
|
}
|
|
18341
19505
|
function singularizeWord(word) {
|
|
@@ -18366,7 +19530,7 @@ function applyDefaultCuration(sr, resourceName, options = {}) {
|
|
|
18366
19530
|
if (verbs.length === 0)
|
|
18367
19531
|
return;
|
|
18368
19532
|
const multiVerb = verbs.length > 1;
|
|
18369
|
-
const baseDisplay = options.displayName ?? (typeof sr.displayName === "string" && sr.displayName ? sr.displayName :
|
|
19533
|
+
const baseDisplay = options.displayName ?? (typeof sr.displayName === "string" && sr.displayName ? sr.displayName : humanize2(resourceName));
|
|
18370
19534
|
for (const verb of verbs) {
|
|
18371
19535
|
const cfg = methodMap[verb];
|
|
18372
19536
|
if (!isRec(cfg) || isRec(cfg.curated))
|
|
@@ -18482,11 +19646,11 @@ function buildSrParamFromElement(elemParam) {
|
|
|
18482
19646
|
}
|
|
18483
19647
|
}
|
|
18484
19648
|
if ("name" in srParam && !("displayName" in srParam)) {
|
|
18485
|
-
srParam.displayName =
|
|
19649
|
+
srParam.displayName = humanize3(String(srParam.name));
|
|
18486
19650
|
}
|
|
18487
19651
|
return srParam;
|
|
18488
19652
|
}
|
|
18489
|
-
function
|
|
19653
|
+
function humanize3(name) {
|
|
18490
19654
|
if (!name) {
|
|
18491
19655
|
return name;
|
|
18492
19656
|
}
|
|
@@ -18553,7 +19717,7 @@ function syncMethodParams(srMethodParams, elemResourceParams, options = {}) {
|
|
|
18553
19717
|
}
|
|
18554
19718
|
}
|
|
18555
19719
|
if (!("displayName" in merged) && "name" in merged) {
|
|
18556
|
-
merged.displayName =
|
|
19720
|
+
merged.displayName = humanize3(String(merged.name));
|
|
18557
19721
|
}
|
|
18558
19722
|
out.push(merged);
|
|
18559
19723
|
usedIds.add(identity);
|
|
@@ -18782,19 +19946,19 @@ async function resolveSrNameByInternalPath(connectorRoot, internalPath) {
|
|
|
18782
19946
|
return null;
|
|
18783
19947
|
return matches.find((n) => normalizeInternalPath(`/${n}`) === target) ?? matches[0];
|
|
18784
19948
|
}
|
|
18785
|
-
function getSrField(sr,
|
|
18786
|
-
return sr.fields?.[
|
|
19949
|
+
function getSrField(sr, fieldName2) {
|
|
19950
|
+
return sr.fields?.[fieldName2] ?? null;
|
|
18787
19951
|
}
|
|
18788
|
-
function upsertSrField(sr,
|
|
19952
|
+
function upsertSrField(sr, fieldName2, field, overwrite = false) {
|
|
18789
19953
|
if (!sr.fields) {
|
|
18790
19954
|
sr.fields = {};
|
|
18791
19955
|
}
|
|
18792
|
-
const existing = sr.fields[
|
|
19956
|
+
const existing = sr.fields[fieldName2];
|
|
18793
19957
|
if (existing === undefined || overwrite) {
|
|
18794
|
-
sr.fields[
|
|
19958
|
+
sr.fields[fieldName2] = field;
|
|
18795
19959
|
return sr;
|
|
18796
19960
|
}
|
|
18797
|
-
sr.fields[
|
|
19961
|
+
sr.fields[fieldName2] = mergeField(existing, field);
|
|
18798
19962
|
return sr;
|
|
18799
19963
|
}
|
|
18800
19964
|
function mergeField(existing, incoming) {
|
|
@@ -18814,12 +19978,12 @@ function mergeField(existing, incoming) {
|
|
|
18814
19978
|
function isRecord2(value) {
|
|
18815
19979
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18816
19980
|
}
|
|
18817
|
-
function removeSrField(sr,
|
|
19981
|
+
function removeSrField(sr, fieldName2) {
|
|
18818
19982
|
const fields = sr.fields ?? {};
|
|
18819
|
-
if (!(
|
|
18820
|
-
throw new Error(`Field '${
|
|
19983
|
+
if (!(fieldName2 in fields)) {
|
|
19984
|
+
throw new Error(`Field '${fieldName2}' not found in standard resource.`);
|
|
18821
19985
|
}
|
|
18822
|
-
delete fields[
|
|
19986
|
+
delete fields[fieldName2];
|
|
18823
19987
|
return sr;
|
|
18824
19988
|
}
|
|
18825
19989
|
function getSrMetadataKey(sr, key) {
|
|
@@ -19843,13 +21007,13 @@ async function listFields(connectorRoot, resource) {
|
|
|
19843
21007
|
const fields = Object.values(sr.sr.fields ?? {});
|
|
19844
21008
|
return { ok: true, data: { resource, fields } };
|
|
19845
21009
|
}
|
|
19846
|
-
async function getField(connectorRoot, resource,
|
|
21010
|
+
async function getField(connectorRoot, resource, fieldName2) {
|
|
19847
21011
|
const sr = await loadSr(connectorRoot, resource);
|
|
19848
21012
|
if (!sr.ok)
|
|
19849
21013
|
return sr;
|
|
19850
|
-
const field = getSrField(sr.sr,
|
|
21014
|
+
const field = getSrField(sr.sr, fieldName2);
|
|
19851
21015
|
if (field === null) {
|
|
19852
|
-
return fieldNotFound(resource,
|
|
21016
|
+
return fieldNotFound(resource, fieldName2);
|
|
19853
21017
|
}
|
|
19854
21018
|
return { ok: true, data: { resource, field } };
|
|
19855
21019
|
}
|
|
@@ -19892,17 +21056,17 @@ async function upsertField(connectorRoot, resource, field, overwrite = false) {
|
|
|
19892
21056
|
}
|
|
19893
21057
|
};
|
|
19894
21058
|
}
|
|
19895
|
-
async function removeField(connectorRoot, resource,
|
|
21059
|
+
async function removeField(connectorRoot, resource, fieldName2) {
|
|
19896
21060
|
const loaded = await loadSr(connectorRoot, resource);
|
|
19897
21061
|
if (!loaded.ok)
|
|
19898
21062
|
return loaded;
|
|
19899
21063
|
const sr = loaded.sr;
|
|
19900
|
-
if (getSrField(sr,
|
|
19901
|
-
return fieldNotFound(resource,
|
|
21064
|
+
if (getSrField(sr, fieldName2) === null) {
|
|
21065
|
+
return fieldNotFound(resource, fieldName2);
|
|
19902
21066
|
}
|
|
19903
|
-
removeSrField(sr,
|
|
21067
|
+
removeSrField(sr, fieldName2);
|
|
19904
21068
|
await writeStandardResource(loaded.root, resource, sr);
|
|
19905
|
-
return { ok: true, data: { resource, fieldName } };
|
|
21069
|
+
return { ok: true, data: { resource, fieldName: fieldName2 } };
|
|
19906
21070
|
}
|
|
19907
21071
|
async function loadSr(connectorRoot, resource) {
|
|
19908
21072
|
const found = await findElementDir(connectorRoot);
|
|
@@ -19923,12 +21087,12 @@ async function loadSr(connectorRoot, resource) {
|
|
|
19923
21087
|
};
|
|
19924
21088
|
}
|
|
19925
21089
|
}
|
|
19926
|
-
function fieldNotFound(resource,
|
|
21090
|
+
function fieldNotFound(resource, fieldName2) {
|
|
19927
21091
|
return {
|
|
19928
21092
|
ok: false,
|
|
19929
21093
|
error: {
|
|
19930
21094
|
code: "fieldNotFound",
|
|
19931
|
-
message: `Field '${
|
|
21095
|
+
message: `Field '${fieldName2}' was not found in resource '${resource}'.`,
|
|
19932
21096
|
fixHint: "Use listFields to see the available field names."
|
|
19933
21097
|
}
|
|
19934
21098
|
};
|
|
@@ -27517,21 +28681,21 @@ async function patchStandardResources(cp, root, value, op) {
|
|
|
27517
28681
|
}
|
|
27518
28682
|
const srData = await readStandardResource(root, srName);
|
|
27519
28683
|
if (cp.section === Section.FIELDS && cp.fieldName !== null) {
|
|
27520
|
-
const
|
|
28684
|
+
const fieldName2 = cp.fieldName;
|
|
27521
28685
|
if (op === "remove") {
|
|
27522
|
-
removeSrField(srData,
|
|
28686
|
+
removeSrField(srData, fieldName2);
|
|
27523
28687
|
await writeStandardResource(root, srName, srData);
|
|
27524
|
-
return ok(`Removed field '${
|
|
28688
|
+
return ok(`Removed field '${fieldName2}' from ${srName}.`);
|
|
27525
28689
|
}
|
|
27526
|
-
const validationErr = validateFieldValue(value,
|
|
28690
|
+
const validationErr = validateFieldValue(value, fieldName2, warnings);
|
|
27527
28691
|
if (validationErr !== null) {
|
|
27528
28692
|
return validationErr;
|
|
27529
28693
|
}
|
|
27530
28694
|
const obj = value;
|
|
27531
|
-
obj.name =
|
|
27532
|
-
upsertSrField(srData,
|
|
28695
|
+
obj.name = fieldName2;
|
|
28696
|
+
upsertSrField(srData, fieldName2, obj, true);
|
|
27533
28697
|
await writeStandardResource(root, srName, srData);
|
|
27534
|
-
return ok(`Upserted field '${
|
|
28698
|
+
return ok(`Upserted field '${fieldName2}' in ${srName}.`, warnings);
|
|
27535
28699
|
}
|
|
27536
28700
|
if (cp.section === Section.METADATA) {
|
|
27537
28701
|
return patchSrMetadata(cp, root, srName, srData, value, op, warnings);
|
|
@@ -31125,4 +32289,4 @@ var registerCommands = async (program2) => {
|
|
|
31125
32289
|
|
|
31126
32290
|
export { Command, metadata, registerCommands };
|
|
31127
32291
|
|
|
31128
|
-
//# debugId=
|
|
32292
|
+
//# debugId=0E02A525AF08DC4F64756E2164756E21
|