@uipath/solution-sdk 1.204.0 → 1.205.0-preview.258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD-PARTY-NOTICES.md +2 -2
- package/dist/deployment-search.js +182 -0
- package/dist/{embedded-file-reader-rf2g1kfj.js → embedded-file-reader-z4becc02.js} +2 -2
- package/dist/index-78paj2kz.js +1908 -0
- package/dist/index-cs3g624n.js +28 -0
- package/dist/index-eav127tv.js +3004 -0
- package/dist/{index-fb21bjwj.js → index-enc2hqq5.js} +255 -1409
- package/dist/{index-6gp5j7j5.js → index-hkexw5er.js} +193 -118
- package/dist/{index-g0hcxnae.js → index-y4vgqz1w.js} +11 -1
- package/dist/index-zmneg45c.js +1184 -0
- package/dist/index.js +1551 -4214
- package/dist/package-search.js +105 -0
- package/dist/resources/index.js +1183 -1177
- package/dist/solution-auth.js +4 -3
- package/dist/src/deployment-search.d.ts +104 -0
- package/dist/src/legacy-deployment-search-v3.d.ts +24 -0
- package/dist/src/legacy-package-search.d.ts +25 -0
- package/dist/src/package-search.d.ts +41 -0
- package/dist/src/pipelines-route.d.ts +43 -0
- package/dist/src/resources/index.d.ts +3 -0
- package/dist/src/resources/providers/artefact-pair-binding-provider.d.ts +4 -0
- package/dist/src/resources/services/catalog-lookup-failure.d.ts +50 -0
- package/dist/src/resources/services/remote-resources.d.ts +2 -0
- package/dist/src/resources/services/resource-configurations.d.ts +44 -0
- package/dist/src/resources/services/resource-lookup.d.ts +29 -0
- package/dist/src/resources/services/resource-refresh-service.d.ts +13 -0
- package/dist/src/resources/services/sync-resources-from-bindings.d.ts +43 -6
- package/dist/src/zip-utils.d.ts +5 -0
- package/package.json +10 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getFileSystem
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-y4vgqz1w.js";
|
|
4
4
|
import {
|
|
5
5
|
__require
|
|
6
6
|
} from "./index-1de529jm.js";
|
|
@@ -39,11 +39,79 @@ var AUTH_FILENAME = ".auth";
|
|
|
39
39
|
var DEFAULT_BASE_URL = "https://cloud.uipath.com";
|
|
40
40
|
var DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000;
|
|
41
41
|
|
|
42
|
+
// ../auth/src/authProfile.ts
|
|
43
|
+
var DEFAULT_AUTH_PROFILE = "default";
|
|
44
|
+
var PROFILE_DIR = "profiles";
|
|
45
|
+
var PROFILE_NAME_RE = /^[A-Za-z0-9._-]+$/;
|
|
46
|
+
var ACTIVE_AUTH_PROFILE_KEY = Symbol.for("@uipath/auth/ActiveAuthProfile");
|
|
47
|
+
var AUTH_PROFILE_STORAGE_KEY = Symbol.for("@uipath/auth/ProfileStorage");
|
|
48
|
+
var globalSlot = globalThis;
|
|
49
|
+
function isAuthProfileStorage(value) {
|
|
50
|
+
return value !== null && typeof value === "object" && "getStore" in value && "run" in value;
|
|
51
|
+
}
|
|
52
|
+
function createProfileStorage() {
|
|
53
|
+
const [error, mod] = catchError(() => __require("node:async_hooks"));
|
|
54
|
+
if (error || typeof mod?.AsyncLocalStorage !== "function") {
|
|
55
|
+
return {
|
|
56
|
+
getStore: () => {
|
|
57
|
+
return;
|
|
58
|
+
},
|
|
59
|
+
run: (_store, fn) => fn()
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return new mod.AsyncLocalStorage;
|
|
63
|
+
}
|
|
64
|
+
function getProfileStorage() {
|
|
65
|
+
const existing = globalSlot[AUTH_PROFILE_STORAGE_KEY];
|
|
66
|
+
if (isAuthProfileStorage(existing)) {
|
|
67
|
+
return existing;
|
|
68
|
+
}
|
|
69
|
+
const storage = createProfileStorage();
|
|
70
|
+
globalSlot[AUTH_PROFILE_STORAGE_KEY] = storage;
|
|
71
|
+
return storage;
|
|
72
|
+
}
|
|
73
|
+
var profileStorage = getProfileStorage();
|
|
74
|
+
|
|
75
|
+
class AuthProfileValidationError extends Error {
|
|
76
|
+
constructor(message) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.name = "AuthProfileValidationError";
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function normalizeAuthProfileName(profile) {
|
|
82
|
+
if (profile === undefined || profile === DEFAULT_AUTH_PROFILE) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (profile.length === 0 || profile === "." || profile === ".." || !PROFILE_NAME_RE.test(profile)) {
|
|
86
|
+
throw new AuthProfileValidationError(`Invalid profile name "${profile}". Profile names may contain only letters, numbers, '.', '_', and '-'.`);
|
|
87
|
+
}
|
|
88
|
+
return profile;
|
|
89
|
+
}
|
|
90
|
+
function getActiveAuthProfile() {
|
|
91
|
+
const scopedState = profileStorage.getStore();
|
|
92
|
+
if (scopedState !== undefined) {
|
|
93
|
+
return scopedState.profile;
|
|
94
|
+
}
|
|
95
|
+
return globalSlot[ACTIVE_AUTH_PROFILE_KEY]?.profile;
|
|
96
|
+
}
|
|
97
|
+
function resolveAuthProfileFilePath(profile) {
|
|
98
|
+
const normalized = normalizeAuthProfileName(profile);
|
|
99
|
+
if (normalized === undefined) {
|
|
100
|
+
throw new AuthProfileValidationError(`"${DEFAULT_AUTH_PROFILE}" is the built-in profile and does not have a profile file path.`);
|
|
101
|
+
}
|
|
102
|
+
const fs = getFileSystem();
|
|
103
|
+
return fs.path.join(fs.env.homedir(), UIPATH_HOME_DIR, PROFILE_DIR, normalized, AUTH_FILENAME);
|
|
104
|
+
}
|
|
105
|
+
function getActiveAuthProfileFilePath() {
|
|
106
|
+
const profile = getActiveAuthProfile();
|
|
107
|
+
return profile ? resolveAuthProfileFilePath(profile) : undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
42
110
|
// ../auth/src/config.ts
|
|
43
111
|
var DEFAULT_CLIENT_ID = "36dea5b8-e8bb-423d-8e7b-c808df8f1c00";
|
|
44
112
|
var AUTH_FILE_CONFIG_KEY = Symbol.for("@uipath/auth/AuthFileConfig");
|
|
45
|
-
var
|
|
46
|
-
var getAuthFileConfig = () =>
|
|
113
|
+
var globalSlot2 = globalThis;
|
|
114
|
+
var getAuthFileConfig = () => globalSlot2[AUTH_FILE_CONFIG_KEY] ?? {};
|
|
47
115
|
|
|
48
116
|
class InvalidBaseUrlError extends Error {
|
|
49
117
|
url;
|
|
@@ -114,22 +182,12 @@ var resolveConfigAsync = async ({
|
|
|
114
182
|
baseUrl = DEFAULT_BASE_URL;
|
|
115
183
|
}
|
|
116
184
|
baseUrl = normalizeAndValidateBaseUrl(baseUrl);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
clientId = fileAuth.clientId;
|
|
120
|
-
}
|
|
121
|
-
if (!clientId) {
|
|
122
|
-
clientId = DEFAULT_CLIENT_ID;
|
|
123
|
-
}
|
|
124
|
-
let clientSecret = customClientSecret;
|
|
125
|
-
if (!clientSecret && fileAuth.clientSecret) {
|
|
126
|
-
clientSecret = fileAuth.clientSecret;
|
|
127
|
-
}
|
|
128
|
-
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
|
|
185
|
+
const clientId = customClientId || DEFAULT_CLIENT_ID;
|
|
186
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
|
|
129
187
|
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
130
188
|
return {
|
|
131
189
|
clientId,
|
|
132
|
-
clientSecret,
|
|
190
|
+
clientSecret: customClientSecret,
|
|
133
191
|
scopes,
|
|
134
192
|
baseUrl,
|
|
135
193
|
authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
|
|
@@ -142,74 +200,6 @@ function isBrowser() {
|
|
|
142
200
|
return typeof globalThis !== "undefined" && "window" in globalThis && "document" in globalThis;
|
|
143
201
|
}
|
|
144
202
|
|
|
145
|
-
// ../auth/src/authProfile.ts
|
|
146
|
-
var DEFAULT_AUTH_PROFILE = "default";
|
|
147
|
-
var PROFILE_DIR = "profiles";
|
|
148
|
-
var PROFILE_NAME_RE = /^[A-Za-z0-9._-]+$/;
|
|
149
|
-
var ACTIVE_AUTH_PROFILE_KEY = Symbol.for("@uipath/auth/ActiveAuthProfile");
|
|
150
|
-
var AUTH_PROFILE_STORAGE_KEY = Symbol.for("@uipath/auth/ProfileStorage");
|
|
151
|
-
var globalSlot2 = globalThis;
|
|
152
|
-
function isAuthProfileStorage(value) {
|
|
153
|
-
return value !== null && typeof value === "object" && "getStore" in value && "run" in value;
|
|
154
|
-
}
|
|
155
|
-
function createProfileStorage() {
|
|
156
|
-
const [error, mod] = catchError(() => __require("node:async_hooks"));
|
|
157
|
-
if (error || typeof mod?.AsyncLocalStorage !== "function") {
|
|
158
|
-
return {
|
|
159
|
-
getStore: () => {
|
|
160
|
-
return;
|
|
161
|
-
},
|
|
162
|
-
run: (_store, fn) => fn()
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
return new mod.AsyncLocalStorage;
|
|
166
|
-
}
|
|
167
|
-
function getProfileStorage() {
|
|
168
|
-
const existing = globalSlot2[AUTH_PROFILE_STORAGE_KEY];
|
|
169
|
-
if (isAuthProfileStorage(existing)) {
|
|
170
|
-
return existing;
|
|
171
|
-
}
|
|
172
|
-
const storage = createProfileStorage();
|
|
173
|
-
globalSlot2[AUTH_PROFILE_STORAGE_KEY] = storage;
|
|
174
|
-
return storage;
|
|
175
|
-
}
|
|
176
|
-
var profileStorage = getProfileStorage();
|
|
177
|
-
|
|
178
|
-
class AuthProfileValidationError extends Error {
|
|
179
|
-
constructor(message) {
|
|
180
|
-
super(message);
|
|
181
|
-
this.name = "AuthProfileValidationError";
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
function normalizeAuthProfileName(profile) {
|
|
185
|
-
if (profile === undefined || profile === DEFAULT_AUTH_PROFILE) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (profile.length === 0 || profile === "." || profile === ".." || !PROFILE_NAME_RE.test(profile)) {
|
|
189
|
-
throw new AuthProfileValidationError(`Invalid profile name "${profile}". Profile names may contain only letters, numbers, '.', '_', and '-'.`);
|
|
190
|
-
}
|
|
191
|
-
return profile;
|
|
192
|
-
}
|
|
193
|
-
function getActiveAuthProfile() {
|
|
194
|
-
const scopedState = profileStorage.getStore();
|
|
195
|
-
if (scopedState !== undefined) {
|
|
196
|
-
return scopedState.profile;
|
|
197
|
-
}
|
|
198
|
-
return globalSlot2[ACTIVE_AUTH_PROFILE_KEY]?.profile;
|
|
199
|
-
}
|
|
200
|
-
function resolveAuthProfileFilePath(profile) {
|
|
201
|
-
const normalized = normalizeAuthProfileName(profile);
|
|
202
|
-
if (normalized === undefined) {
|
|
203
|
-
throw new AuthProfileValidationError(`"${DEFAULT_AUTH_PROFILE}" is the built-in profile and does not have a profile file path.`);
|
|
204
|
-
}
|
|
205
|
-
const fs = getFileSystem();
|
|
206
|
-
return fs.path.join(fs.env.homedir(), UIPATH_HOME_DIR, PROFILE_DIR, normalized, AUTH_FILENAME);
|
|
207
|
-
}
|
|
208
|
-
function getActiveAuthProfileFilePath() {
|
|
209
|
-
const profile = getActiveAuthProfile();
|
|
210
|
-
return profile ? resolveAuthProfileFilePath(profile) : undefined;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
203
|
// ../auth/src/utils/jwt.ts
|
|
214
204
|
class InvalidIssuerError extends Error {
|
|
215
205
|
expected;
|
|
@@ -303,6 +293,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
|
|
|
303
293
|
}
|
|
304
294
|
return;
|
|
305
295
|
};
|
|
296
|
+
var resolveApplicationSubtype = (claims, authFlow) => {
|
|
297
|
+
switch (asString(claims?.sub_type)) {
|
|
298
|
+
case "service.external":
|
|
299
|
+
return "External";
|
|
300
|
+
case "service.internal":
|
|
301
|
+
return "Internal";
|
|
302
|
+
default:
|
|
303
|
+
return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
306
|
var looksLikeEmail = (value) => value?.includes("@") ?? false;
|
|
307
307
|
var pickEmail = (claims) => {
|
|
308
308
|
for (const candidate of [claims?.email, claims?.preferred_username]) {
|
|
@@ -344,6 +344,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
344
344
|
const clientId = asString(claims?.client_id);
|
|
345
345
|
if (clientId)
|
|
346
346
|
identity.clientId = clientId;
|
|
347
|
+
const subType = asString(claims?.sub_type);
|
|
348
|
+
if (subType)
|
|
349
|
+
identity.subType = subType;
|
|
350
|
+
const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
|
|
351
|
+
if (applicationSubtype)
|
|
352
|
+
identity.applicationSubtype = applicationSubtype;
|
|
347
353
|
return identity;
|
|
348
354
|
};
|
|
349
355
|
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
@@ -636,6 +642,40 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
636
642
|
}
|
|
637
643
|
};
|
|
638
644
|
|
|
645
|
+
// ../auth/src/tenantSelection.ts
|
|
646
|
+
var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
|
|
647
|
+
var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
|
|
648
|
+
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
649
|
+
var describeNonJsonResponse = (organizationId, response, parseError) => {
|
|
650
|
+
if (response.redirected) {
|
|
651
|
+
return `Could not find organization '${organizationId}': the request was ` + `redirected to a sign-in page instead of the organization's tenant ` + `list. ${LOGIN_STATUS_HINT}`;
|
|
652
|
+
}
|
|
653
|
+
const contentType = response.headers.get("content-type") ?? "unknown";
|
|
654
|
+
return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
|
|
655
|
+
};
|
|
656
|
+
var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
|
|
657
|
+
const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
|
|
658
|
+
const response = await fetch(url, {
|
|
659
|
+
headers: {
|
|
660
|
+
Authorization: `Bearer ${accessToken}`
|
|
661
|
+
},
|
|
662
|
+
...signal ? { signal } : {}
|
|
663
|
+
});
|
|
664
|
+
if (!response.ok) {
|
|
665
|
+
if (response.status === 401) {
|
|
666
|
+
throw new Error(`Unauthorized: the access token was rejected, it was not ` + `issued for organization '${organizationId}', or ` + `'${organizationId}' was not accepted as an organization ` + `URL segment in this environment. ` + LOGIN_STATUS_HINT);
|
|
667
|
+
}
|
|
668
|
+
const errorText = await response.text();
|
|
669
|
+
const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
|
|
670
|
+
throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
|
|
671
|
+
}
|
|
672
|
+
const [parseError, data] = await catchError(response.json());
|
|
673
|
+
if (parseError) {
|
|
674
|
+
throw new Error(describeNonJsonResponse(organizationId, response, parseError));
|
|
675
|
+
}
|
|
676
|
+
return data;
|
|
677
|
+
};
|
|
678
|
+
|
|
639
679
|
// ../auth/src/tokenRefresh.ts
|
|
640
680
|
var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
|
|
641
681
|
|
|
@@ -848,6 +888,8 @@ var saveEnvFileAsync = async ({
|
|
|
848
888
|
};
|
|
849
889
|
|
|
850
890
|
// ../auth/src/loginStatus.ts
|
|
891
|
+
var defaultRobotTenantIdCache = new Map;
|
|
892
|
+
var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
|
|
851
893
|
var getLoginStatusAsync = async (options = {}) => {
|
|
852
894
|
return getLoginStatusWithDeps(options);
|
|
853
895
|
};
|
|
@@ -860,12 +902,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
860
902
|
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
861
903
|
resolveConfig = resolveConfigAsync,
|
|
862
904
|
robotFallback = tryRobotClientFallback,
|
|
905
|
+
fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
|
|
906
|
+
robotTenantIdCache = defaultRobotTenantIdCache,
|
|
907
|
+
robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
|
|
863
908
|
loadBreaker = loadRefreshBreaker,
|
|
864
909
|
saveBreaker = saveRefreshBreaker,
|
|
865
910
|
clearBreaker = clearRefreshBreaker
|
|
866
911
|
} = deps;
|
|
912
|
+
const robotDeps = {
|
|
913
|
+
fetchTenantsAndOrgs,
|
|
914
|
+
cache: robotTenantIdCache,
|
|
915
|
+
lookupTimeoutMs: robotTenantLookupTimeoutMs
|
|
916
|
+
};
|
|
867
917
|
if (isRobotAuthEnforced()) {
|
|
868
|
-
return resolveRobotEnforcedStatus(robotFallback);
|
|
918
|
+
return resolveRobotEnforcedStatus(robotFallback, robotDeps);
|
|
869
919
|
}
|
|
870
920
|
if (isEnvAuthEnabled()) {
|
|
871
921
|
return readAuthFromEnv();
|
|
@@ -883,7 +933,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
883
933
|
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
884
934
|
};
|
|
885
935
|
}
|
|
886
|
-
return resolveBorrowedRobotStatus(robotFallback);
|
|
936
|
+
return resolveBorrowedRobotStatus(robotFallback, robotDeps);
|
|
887
937
|
}
|
|
888
938
|
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
889
939
|
if ("status" in loaded) {
|
|
@@ -925,7 +975,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
925
975
|
}
|
|
926
976
|
return buildFileStatus(tokens, credentials, globalHint);
|
|
927
977
|
};
|
|
928
|
-
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
978
|
+
async function resolveRobotEnforcedStatus(robotFallback, deps) {
|
|
929
979
|
if (isEnvAuthEnabled()) {
|
|
930
980
|
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
931
981
|
}
|
|
@@ -936,11 +986,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
|
|
|
936
986
|
hint: `${ENFORCE_ROBOT_AUTH_VAR}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR} to fall back to file or ` + `env-var authentication.`
|
|
937
987
|
};
|
|
938
988
|
}
|
|
939
|
-
return buildRobotStatus(robotCreds);
|
|
989
|
+
return buildRobotStatus(robotCreds, deps);
|
|
940
990
|
}
|
|
941
|
-
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
991
|
+
async function resolveBorrowedRobotStatus(robotFallback, deps) {
|
|
942
992
|
const robotCreds = await robotFallback();
|
|
943
|
-
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
993
|
+
return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
|
|
944
994
|
}
|
|
945
995
|
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
946
996
|
let credentials;
|
|
@@ -1075,9 +1125,10 @@ function identityFields(accessToken, credentials) {
|
|
|
1075
1125
|
...scopes ? { scopes } : {}
|
|
1076
1126
|
};
|
|
1077
1127
|
}
|
|
1078
|
-
function buildRobotStatus(robotCreds) {
|
|
1128
|
+
async function buildRobotStatus(robotCreds, deps) {
|
|
1079
1129
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
1080
1130
|
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
1131
|
+
const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
|
|
1081
1132
|
return {
|
|
1082
1133
|
loginStatus: "Logged in",
|
|
1083
1134
|
accessToken: robotCreds.accessToken,
|
|
@@ -1085,14 +1136,62 @@ function buildRobotStatus(robotCreds) {
|
|
|
1085
1136
|
organizationName: robotCreds.organizationName,
|
|
1086
1137
|
organizationId: robotCreds.organizationId,
|
|
1087
1138
|
tenantName: robotCreds.tenantName,
|
|
1088
|
-
tenantId:
|
|
1139
|
+
tenantId: tenant.tenantId,
|
|
1089
1140
|
issuer: robotCreds.issuer,
|
|
1090
1141
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
1091
1142
|
source: "robot" /* Robot */,
|
|
1143
|
+
...tenant.hint ? { hint: tenant.hint } : {},
|
|
1092
1144
|
...identity ? { identity } : {},
|
|
1093
1145
|
...scopes ? { scopes } : {}
|
|
1094
1146
|
};
|
|
1095
1147
|
}
|
|
1148
|
+
async function resolveRobotTenantId(robotCreds, deps) {
|
|
1149
|
+
const { baseUrl, accessToken, tenantName } = robotCreds;
|
|
1150
|
+
const organization = robotCreds.organizationName ?? robotCreds.organizationId;
|
|
1151
|
+
if (!tenantName || !organization) {
|
|
1152
|
+
return {};
|
|
1153
|
+
}
|
|
1154
|
+
const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
|
|
1155
|
+
let pending = deps.cache.get(key);
|
|
1156
|
+
if (!pending) {
|
|
1157
|
+
pending = catchError(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
|
|
1158
|
+
const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
|
|
1159
|
+
if (!settled.tenantId) {
|
|
1160
|
+
deps.cache.delete(key);
|
|
1161
|
+
}
|
|
1162
|
+
return settled;
|
|
1163
|
+
});
|
|
1164
|
+
deps.cache.set(key, pending);
|
|
1165
|
+
}
|
|
1166
|
+
return pending;
|
|
1167
|
+
}
|
|
1168
|
+
async function lookupRobotTenantId(target, deps) {
|
|
1169
|
+
const { baseUrl, accessToken, organization, tenantName } = target;
|
|
1170
|
+
const [error, data] = await catchError(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
|
|
1171
|
+
if (error) {
|
|
1172
|
+
const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
|
|
1173
|
+
return { hint: tenantLookupFailureHint(tenantName, reason) };
|
|
1174
|
+
}
|
|
1175
|
+
const rows = data?.tenants;
|
|
1176
|
+
const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
|
|
1177
|
+
const wantedName = decodePathSegment(tenantName);
|
|
1178
|
+
const wanted = wantedName.toLowerCase();
|
|
1179
|
+
const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
|
|
1180
|
+
if (!match) {
|
|
1181
|
+
const names = tenants.map((tenant) => tenant.name).join(", ");
|
|
1182
|
+
return {
|
|
1183
|
+
hint: `The Robot session targets tenant '${tenantName}', but ` + `organization '${organization}' lists no tenant of that name` + `${names ? ` (available: ${names})` : ""}. Commands that need ` + `the tenant id will fail until it can be resolved.`
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
return { tenantId: match.id };
|
|
1187
|
+
}
|
|
1188
|
+
function tenantLookupFailureHint(tenantName, reason) {
|
|
1189
|
+
return `Could not resolve the id of tenant '${tenantName}' from the ` + `Robot session: ${reason} Commands that need the tenant id will ` + `fail until it can be resolved.`;
|
|
1190
|
+
}
|
|
1191
|
+
function decodePathSegment(segment) {
|
|
1192
|
+
const [error, decoded] = catchError(() => decodeURIComponent(segment));
|
|
1193
|
+
return error ? segment : decoded;
|
|
1194
|
+
}
|
|
1096
1195
|
var isFileNotFoundError = (error) => {
|
|
1097
1196
|
if (!(error instanceof Object))
|
|
1098
1197
|
return false;
|
|
@@ -1361,9 +1460,6 @@ var getAuthContext = async (options = {}) => {
|
|
|
1361
1460
|
identity: status.identity
|
|
1362
1461
|
};
|
|
1363
1462
|
};
|
|
1364
|
-
// ../auth/src/tenantSelection.ts
|
|
1365
|
-
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
1366
|
-
|
|
1367
1463
|
// ../auth/src/selectTenant.ts
|
|
1368
1464
|
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
1369
1465
|
var INVALID_TENANT_CODE = "INVALID_TENANT";
|
|
@@ -1371,27 +1467,6 @@ var TENANT_SELECTION_CODES = new Set([
|
|
|
1371
1467
|
TENANT_SELECTION_REQUIRED_CODE,
|
|
1372
1468
|
INVALID_TENANT_CODE
|
|
1373
1469
|
]);
|
|
1374
|
-
|
|
1375
|
-
async function getSolutionAuthContext(options) {
|
|
1376
|
-
const ctx = await getAuthContext({
|
|
1377
|
-
tenant: options.tenant,
|
|
1378
|
-
ensureTokenValidityMinutes: options.loginValidity ?? 10,
|
|
1379
|
-
envFilePath: options.envFilePath,
|
|
1380
|
-
requireOrganizationId: true,
|
|
1381
|
-
requireTenantName: true
|
|
1382
|
-
});
|
|
1383
|
-
const organizationId = ctx.organizationId;
|
|
1384
|
-
const tenantName = ctx.tenantName;
|
|
1385
|
-
const basePath = `${ctx.baseUrl}/${organizationId}/${tenantName}/automationsolutions_`;
|
|
1386
|
-
return {
|
|
1387
|
-
accessToken: ctx.accessToken,
|
|
1388
|
-
basePath,
|
|
1389
|
-
organizationId,
|
|
1390
|
-
tenantName,
|
|
1391
|
-
identity: ctx.identity
|
|
1392
|
-
};
|
|
1393
|
-
}
|
|
1394
|
-
|
|
1395
|
-
export { getLoginStatusAsync, getAuthContext, getSolutionAuthContext };
|
|
1470
|
+
export { resolveSessionIdentity, getLoginStatusAsync, getAuthContext };
|
|
1396
1471
|
|
|
1397
|
-
//# debugId=
|
|
1472
|
+
//# debugId=0C9CFE4BD0AC04DE64756E2164756E21
|
|
@@ -182,6 +182,16 @@ class NodeFileSystem {
|
|
|
182
182
|
async rename(oldPath, newPath) {
|
|
183
183
|
await fs.rename(oldPath, newPath);
|
|
184
184
|
}
|
|
185
|
+
async isSymbolicLink(filePath) {
|
|
186
|
+
try {
|
|
187
|
+
return (await fs.lstat(filePath)).isSymbolicLink();
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
185
195
|
async realpath(filePath) {
|
|
186
196
|
try {
|
|
187
197
|
return await fs.realpath(filePath);
|
|
@@ -234,4 +244,4 @@ var getFileSystem = () => fsInstance;
|
|
|
234
244
|
|
|
235
245
|
export { getFileSystem };
|
|
236
246
|
|
|
237
|
-
//# debugId=
|
|
247
|
+
//# debugId=82E3494FD83B7EB464756E2164756E21
|