@uipath/cli 1.202.1 → 1.203.0-preview.180
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 +101 -5
- package/dist/THIRD-PARTY-NOTICES.md +64 -7
- package/dist/{cli-p61a1vc8.js → cli-w7vb50ez.js} +4 -4
- package/dist/{index-tqczrxct.js → index-7pvwjzsq.js} +297 -25
- package/dist/{index-bhjtwzfa.js → index-hgvsratt.js} +14 -2
- package/dist/{index-vmj27s6h.js → index-mtdmza3c.js} +55 -32
- package/dist/{index-9d17sa6t.js → index-szrenqr6.js} +331 -39
- package/dist/{index-v5cj0bhj.js → index-vmn69waj.js} +127 -12
- package/dist/index.js +5 -5
- package/dist/{server-0243hbq7.js → server-z7wh3gfs.js} +6 -5
- package/dist/{telemetry-drain-wqmnr7t7.js → telemetry-drain-zkrm8xja.js} +1 -1
- package/dist/{updateService-mashkk31.js → updateService-n7hftkkv.js} +2 -2
- package/package.json +8 -12
- package/README.browser.md +0 -128
- package/dist/index.browser.js +0 -16410
- package/dist/services.feedback.browser.js +0 -90
- package/dist/services.markdown.browser.js +0 -4
|
@@ -568,6 +568,63 @@ function getActiveAuthProfileFilePath() {
|
|
|
568
568
|
const profile = getActiveAuthProfile();
|
|
569
569
|
return profile ? resolveAuthProfileFilePath(profile) : undefined;
|
|
570
570
|
}
|
|
571
|
+
function getAuthProfilesRootPath() {
|
|
572
|
+
const fs = getFileSystem();
|
|
573
|
+
return fs.path.join(fs.env.homedir(), UIPATH_HOME_DIR, PROFILE_DIR);
|
|
574
|
+
}
|
|
575
|
+
function resolveAuthProfileDirPath(profile) {
|
|
576
|
+
const normalized = normalizeAuthProfileName(profile);
|
|
577
|
+
if (normalized === undefined) {
|
|
578
|
+
throw new AuthProfileValidationError(`"${DEFAULT_AUTH_PROFILE}" is the built-in profile and does not have a profile directory.`);
|
|
579
|
+
}
|
|
580
|
+
const fs = getFileSystem();
|
|
581
|
+
return fs.path.join(getAuthProfilesRootPath(), normalized);
|
|
582
|
+
}
|
|
583
|
+
async function listAuthProfileNamesAsync() {
|
|
584
|
+
const fs = getFileSystem();
|
|
585
|
+
const root = getAuthProfilesRootPath();
|
|
586
|
+
if (!await fs.exists(root)) {
|
|
587
|
+
return [];
|
|
588
|
+
}
|
|
589
|
+
const [readError, entries] = await catchError(fs.readdir(root));
|
|
590
|
+
if (readError || !entries) {
|
|
591
|
+
return [];
|
|
592
|
+
}
|
|
593
|
+
const names = [];
|
|
594
|
+
for (const entry of entries) {
|
|
595
|
+
if (!PROFILE_NAME_RE.test(entry) || entry === DEFAULT_AUTH_PROFILE) {
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
const stats = await fs.stat(fs.path.join(root, entry));
|
|
599
|
+
if (stats?.isDirectory()) {
|
|
600
|
+
names.push(entry);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return names.sort((a, b) => a.localeCompare(b));
|
|
604
|
+
}
|
|
605
|
+
async function authProfileExistsAsync(profile) {
|
|
606
|
+
const fs = getFileSystem();
|
|
607
|
+
const [pathError, dir] = catchError(() => resolveAuthProfileDirPath(profile));
|
|
608
|
+
if (pathError || dir === undefined) {
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
const stats = await fs.stat(dir);
|
|
612
|
+
return stats?.isDirectory() === true;
|
|
613
|
+
}
|
|
614
|
+
async function deleteAuthProfileAsync(profile) {
|
|
615
|
+
const dir = resolveAuthProfileDirPath(profile);
|
|
616
|
+
const fs = getFileSystem();
|
|
617
|
+
const relativeToRoot = fs.path.relative(getAuthProfilesRootPath(), dir);
|
|
618
|
+
if (relativeToRoot === "" || relativeToRoot.startsWith("..") || fs.path.isAbsolute(relativeToRoot)) {
|
|
619
|
+
throw new AuthProfileValidationError(`Refusing to delete "${profile}": resolved path escapes the profiles directory.`);
|
|
620
|
+
}
|
|
621
|
+
const stats = await fs.stat(dir);
|
|
622
|
+
if (stats?.isDirectory() !== true) {
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
await fs.rm(dir);
|
|
626
|
+
return dir;
|
|
627
|
+
}
|
|
571
628
|
|
|
572
629
|
// ../auth/src/utils/jwt.ts
|
|
573
630
|
class InvalidIssuerError extends Error {
|
|
@@ -1136,16 +1193,7 @@ var resolveEnvFilePathAsync = async (envFilePath = DEFAULT_ENV_FILENAME, opts) =
|
|
|
1136
1193
|
errorMessage: location.source === "absolute" ? `Environment file not found: ${envFilePath}` : `Unable to locate environment file: ${envFilePath}. Run 'uip login' to authenticate.`
|
|
1137
1194
|
};
|
|
1138
1195
|
};
|
|
1139
|
-
var
|
|
1140
|
-
const fs = getFileSystem();
|
|
1141
|
-
const absolutePath = fs.path.isAbsolute(envPath) ? envPath : fs.path.join(fs.env.cwd(), envPath);
|
|
1142
|
-
if (!await fs.exists(absolutePath)) {
|
|
1143
|
-
throw new Error(`Environment file not found: ${envPath}`);
|
|
1144
|
-
}
|
|
1145
|
-
const content = await fs.readFile(absolutePath, "utf-8");
|
|
1146
|
-
if (content === null) {
|
|
1147
|
-
throw new Error(`Environment file not found: ${envPath}`);
|
|
1148
|
-
}
|
|
1196
|
+
var parseEnvContent = (content) => {
|
|
1149
1197
|
const env = {};
|
|
1150
1198
|
for (const line of content.split(`
|
|
1151
1199
|
`)) {
|
|
@@ -1166,6 +1214,18 @@ var loadEnvFileAsync = async ({ envPath }) => {
|
|
|
1166
1214
|
}
|
|
1167
1215
|
return env;
|
|
1168
1216
|
};
|
|
1217
|
+
var loadEnvFileAsync = async ({ envPath }) => {
|
|
1218
|
+
const fs = getFileSystem();
|
|
1219
|
+
const absolutePath = fs.path.isAbsolute(envPath) ? envPath : fs.path.join(fs.env.cwd(), envPath);
|
|
1220
|
+
if (!await fs.exists(absolutePath)) {
|
|
1221
|
+
throw new Error(`Environment file not found: ${envPath}`);
|
|
1222
|
+
}
|
|
1223
|
+
const content = await fs.readFile(absolutePath, "utf-8");
|
|
1224
|
+
if (content === null) {
|
|
1225
|
+
throw new Error(`Environment file not found: ${envPath}`);
|
|
1226
|
+
}
|
|
1227
|
+
return parseEnvContent(content);
|
|
1228
|
+
};
|
|
1169
1229
|
var saveEnvFileAsync = async ({
|
|
1170
1230
|
envPath,
|
|
1171
1231
|
data,
|
|
@@ -1740,6 +1800,61 @@ var getAuthEnv = async (options = {}) => {
|
|
|
1740
1800
|
}
|
|
1741
1801
|
return { authEnv, loginStatus: status };
|
|
1742
1802
|
};
|
|
1803
|
+
// ../auth/src/authProfileDetails.ts
|
|
1804
|
+
var ORGANIZATION_NAME_KEY = "UIPATH_ORGANIZATION_NAME";
|
|
1805
|
+
var TENANT_NAME_KEY = "UIPATH_TENANT_NAME";
|
|
1806
|
+
var URL_KEY = "UIPATH_URL";
|
|
1807
|
+
var ACCESS_TOKEN_KEY = "UIPATH_ACCESS_TOKEN";
|
|
1808
|
+
function statusFromToken(accessToken) {
|
|
1809
|
+
if (!accessToken) {
|
|
1810
|
+
return { status: "Not logged in" };
|
|
1811
|
+
}
|
|
1812
|
+
const expiration = getTokenExpiration(accessToken);
|
|
1813
|
+
if (expiration === undefined) {
|
|
1814
|
+
return { status: "Logged in" };
|
|
1815
|
+
}
|
|
1816
|
+
return {
|
|
1817
|
+
status: expiration.getTime() <= Date.now() ? "Expired" : "Logged in",
|
|
1818
|
+
expiresAt: expiration.toISOString()
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
async function describeAuthProfileAsync(name, filePath, active) {
|
|
1822
|
+
const base = {
|
|
1823
|
+
name,
|
|
1824
|
+
active,
|
|
1825
|
+
...filePath ? { path: filePath } : {}
|
|
1826
|
+
};
|
|
1827
|
+
if (!filePath) {
|
|
1828
|
+
return { ...base, status: "Not logged in" };
|
|
1829
|
+
}
|
|
1830
|
+
const fs = getFileSystem();
|
|
1831
|
+
const [readError, content] = await catchError(fs.readFile(filePath, "utf-8"));
|
|
1832
|
+
if (readError) {
|
|
1833
|
+
return { ...base, status: "Unreadable" };
|
|
1834
|
+
}
|
|
1835
|
+
if (content === null || content === undefined) {
|
|
1836
|
+
return { ...base, status: "Not logged in" };
|
|
1837
|
+
}
|
|
1838
|
+
const values = parseEnvContent(content);
|
|
1839
|
+
return {
|
|
1840
|
+
...base,
|
|
1841
|
+
...values[ORGANIZATION_NAME_KEY] ? { organizationName: values[ORGANIZATION_NAME_KEY] } : {},
|
|
1842
|
+
...values[TENANT_NAME_KEY] ? { tenantName: values[TENANT_NAME_KEY] } : {},
|
|
1843
|
+
...values[URL_KEY] ? { url: values[URL_KEY] } : {},
|
|
1844
|
+
...statusFromToken(values[ACCESS_TOKEN_KEY])
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
async function describeAuthProfilesAsync() {
|
|
1848
|
+
const activeProfile = getActiveAuthProfile();
|
|
1849
|
+
const [defaultPathError, defaultLocation] = await catchError(resolveEnvFilePathAsync());
|
|
1850
|
+
const rows = [
|
|
1851
|
+
await describeAuthProfileAsync(DEFAULT_AUTH_PROFILE, defaultPathError ? undefined : defaultLocation?.absolutePath, activeProfile === undefined)
|
|
1852
|
+
];
|
|
1853
|
+
for (const name of await listAuthProfileNamesAsync()) {
|
|
1854
|
+
rows.push(await describeAuthProfileAsync(name, resolveAuthProfileFilePath(name), activeProfile === name));
|
|
1855
|
+
}
|
|
1856
|
+
return rows;
|
|
1857
|
+
}
|
|
1743
1858
|
// ../auth/src/tokenGrant.ts
|
|
1744
1859
|
var requestClientCredentialsToken = async ({
|
|
1745
1860
|
tokenEndpoint,
|
|
@@ -2322,6 +2437,6 @@ var authenticate = async ({
|
|
|
2322
2437
|
});
|
|
2323
2438
|
};
|
|
2324
2439
|
|
|
2325
|
-
export { setAuthFileConfig, InvalidBaseUrlError, DEFAULT_AUTH_PROFILE, AuthProfileValidationError, normalizeAuthProfileName, setActiveAuthProfile, clearActiveAuthProfile, getActiveAuthProfile, runWithAuthProfile, resolveAuthProfileFilePath, getActiveAuthProfileFilePath, parseJWT, parseAuthFlow, resolveSessionIdentity, ENV_AUTH_ENABLE_VAR, ENFORCE_ROBOT_AUTH_VAR, ENV_AUTH_VARS, EnvAuthConfigError, isEnvAuthEnabled, isRobotAuthEnforced, readAuthFromEnv, refreshTokenFingerprint, loadRefreshBreaker, saveRefreshBreaker, clearRefreshBreaker, registerRobotClientLoader, TokenRefreshOAuthError, isTokenRefreshOAuthFailure, refreshAccessToken, AUTH_FLOW_ENV_VAR, DEFAULT_AUTH_FILENAME, DEFAULT_ENV_FILENAME, resolveEnvFileLocationAsync, resolveEnvFilePathAsync, loadEnvFileAsync, saveEnvFileAsync, CredentialSource, getLoginStatusAsync, getLoginStatusWithDeps, getAuthContext, getAuthEnv, ClientCredentialsAuthenticationError, clientCredentialsLogin, JWT_BEARER_ASSERTION_TYPE, FederatedCredentialsAuthenticationError, federatedCredentialsLogin, fetchTenantsAndOrganizations, TENANT_SELECTION_REQUIRED_CODE, INVALID_TENANT_CODE, TenantSelectionError, TenantSelectionRequiredError, InvalidTenantError, isTenantSelectionError, selectTenantWithDeps, interactiveLoginWithDeps, interactiveLogin, logoutWithDeps, logout, authenticate };
|
|
2440
|
+
export { setAuthFileConfig, InvalidBaseUrlError, DEFAULT_AUTH_PROFILE, AuthProfileValidationError, normalizeAuthProfileName, setActiveAuthProfile, clearActiveAuthProfile, getActiveAuthProfile, runWithAuthProfile, resolveAuthProfileFilePath, getActiveAuthProfileFilePath, getAuthProfilesRootPath, resolveAuthProfileDirPath, listAuthProfileNamesAsync, authProfileExistsAsync, deleteAuthProfileAsync, parseJWT, parseAuthFlow, resolveSessionIdentity, ENV_AUTH_ENABLE_VAR, ENFORCE_ROBOT_AUTH_VAR, ENV_AUTH_VARS, EnvAuthConfigError, isEnvAuthEnabled, isRobotAuthEnforced, readAuthFromEnv, refreshTokenFingerprint, loadRefreshBreaker, saveRefreshBreaker, clearRefreshBreaker, registerRobotClientLoader, TokenRefreshOAuthError, isTokenRefreshOAuthFailure, refreshAccessToken, AUTH_FLOW_ENV_VAR, DEFAULT_AUTH_FILENAME, DEFAULT_ENV_FILENAME, resolveEnvFileLocationAsync, resolveEnvFilePathAsync, loadEnvFileAsync, saveEnvFileAsync, CredentialSource, getLoginStatusAsync, getLoginStatusWithDeps, getAuthContext, getAuthEnv, describeAuthProfilesAsync, ClientCredentialsAuthenticationError, clientCredentialsLogin, JWT_BEARER_ASSERTION_TYPE, FederatedCredentialsAuthenticationError, federatedCredentialsLogin, fetchTenantsAndOrganizations, TENANT_SELECTION_REQUIRED_CODE, INVALID_TENANT_CODE, TenantSelectionError, TenantSelectionRequiredError, InvalidTenantError, isTenantSelectionError, selectTenantWithDeps, interactiveLoginWithDeps, interactiveLogin, logoutWithDeps, logout, authenticate };
|
|
2326
2441
|
|
|
2327
|
-
//# debugId=
|
|
2442
|
+
//# debugId=05DE97FE1B9FF5A064756E2164756E21
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runNode
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-szrenqr6.js";
|
|
5
5
|
import {
|
|
6
6
|
registerRobotClientLoader
|
|
7
|
-
} from "./index-
|
|
8
|
-
import"./index-
|
|
7
|
+
} from "./index-vmn69waj.js";
|
|
8
|
+
import"./index-mtdmza3c.js";
|
|
9
9
|
import {
|
|
10
10
|
TELEMETRY_DRAIN_ARGV,
|
|
11
11
|
configureLogger,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
setProcessContextPollSignal,
|
|
19
19
|
setProxyAuthHttpsAgent,
|
|
20
20
|
setTelemetrySidecarEntry
|
|
21
|
-
} from "./index-
|
|
21
|
+
} from "./index-7pvwjzsq.js";
|
|
22
22
|
import"./index-g8ck9tv6.js";
|
|
23
23
|
import"./index-hrt7fpkk.js";
|
|
24
24
|
import"./index-d3w0wn6k.js";
|
|
@@ -192,7 +192,7 @@ var isMain = __require.main == __require.module ?? process.argv[1] === currentFi
|
|
|
192
192
|
if (isMain) {
|
|
193
193
|
setTelemetrySidecarEntry(currentFile);
|
|
194
194
|
if (process.argv[2] === TELEMETRY_DRAIN_ARGV) {
|
|
195
|
-
const { drainPendingTelemetry } = await import("./telemetry-drain-
|
|
195
|
+
const { drainPendingTelemetry } = await import("./telemetry-drain-zkrm8xja.js");
|
|
196
196
|
await drainPendingTelemetry();
|
|
197
197
|
process.exit(0);
|
|
198
198
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runWithAuthProfile
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-vmn69waj.js";
|
|
4
4
|
import {
|
|
5
|
+
OUTPUT_FORMATS,
|
|
5
6
|
catchError,
|
|
6
7
|
collectCommands,
|
|
7
8
|
getOutputSink,
|
|
8
9
|
logger,
|
|
9
10
|
runWithSink,
|
|
10
11
|
setGlobalSink
|
|
11
|
-
} from "./index-
|
|
12
|
+
} from "./index-7pvwjzsq.js";
|
|
12
13
|
import"./index-g8ck9tv6.js";
|
|
13
14
|
import {
|
|
14
15
|
exports_external
|
|
@@ -83,7 +84,7 @@ async function executeCommand(command) {
|
|
|
83
84
|
const previousSink = getOutputSink();
|
|
84
85
|
setGlobalSink(sink);
|
|
85
86
|
const [error] = await catchError(async () => {
|
|
86
|
-
const { run } = await import("./cli-
|
|
87
|
+
const { run } = await import("./cli-w7vb50ez.js");
|
|
87
88
|
await runWithAuthProfile(undefined, () => runWithSink(sink, () => run(context)));
|
|
88
89
|
});
|
|
89
90
|
if (error) {
|
|
@@ -131,7 +132,7 @@ function introspectCommands(program) {
|
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
lines.push(`
|
|
134
|
-
Global Options (can be used with any command):`,
|
|
135
|
+
Global Options (can be used with any command):`, ` --output <${OUTPUT_FORMATS.join("|")}>: Output format (default: json)`, " --output-filter <expression>: JMESPath expression applied to the Data field of the response envelope", " --log-level <debug|info|warn|error>: Log level threshold (default: info)", " --log-file <path>: Write logs to file instead of stderr", " --profile <name>: Use a named login profile (~/.uipath/profiles/<name>/.auth)", `
|
|
135
136
|
Pass the command without the 'uip' prefix. Example: "login status --output json"`, `Filter example: "tools list --output-filter 'Data[].name'"`);
|
|
136
137
|
return lines.join(`
|
|
137
138
|
`);
|
|
@@ -191,4 +192,4 @@ export {
|
|
|
191
192
|
startMcpServer
|
|
192
193
|
};
|
|
193
194
|
|
|
194
|
-
//# debugId=
|
|
195
|
+
//# debugId=95A6EF0EC5E5518C64756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/cli",
|
|
3
|
+
"author": "UiPath",
|
|
3
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "1.
|
|
5
|
+
"version": "1.203.0-preview.180",
|
|
5
6
|
"description": "Cross platform CLI for UiPath",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
@@ -12,20 +13,15 @@
|
|
|
12
13
|
"registry": "https://registry.npmjs.org/"
|
|
13
14
|
},
|
|
14
15
|
"type": "module",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22"
|
|
18
|
+
},
|
|
15
19
|
"main": "./dist/index.js",
|
|
16
20
|
"exports": {
|
|
17
|
-
".":
|
|
18
|
-
"browser": "./dist/index.browser.js",
|
|
19
|
-
"default": "./dist/index.js"
|
|
20
|
-
},
|
|
21
|
-
"./browser": "./dist/index.browser.js",
|
|
22
|
-
"./services/markdown-to-jira-wiki": "./dist/services.markdown.browser.js",
|
|
23
|
-
"./services/feedback/browser": "./dist/services.feedback.browser.js"
|
|
21
|
+
".": "./dist/index.js"
|
|
24
22
|
},
|
|
25
23
|
"files": [
|
|
26
|
-
"dist"
|
|
27
|
-
"!dist/uip-browser.js",
|
|
28
|
-
"!dist/metafile.json"
|
|
24
|
+
"dist"
|
|
29
25
|
],
|
|
30
26
|
"bin": {
|
|
31
27
|
"uip": "./dist/index.js"
|
|
@@ -40,5 +36,5 @@
|
|
|
40
36
|
"kerberos": "7.0.0",
|
|
41
37
|
"node-expose-sspi": "0.1.60"
|
|
42
38
|
},
|
|
43
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "4e0a51e3ab2c9d89afd3d35a7b087a7fa58133a0"
|
|
44
40
|
}
|
package/README.browser.md
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# UiPath CLI — Browser Bundle
|
|
2
|
-
|
|
3
|
-
A browser-runnable bundle of the UiPath CLI. Exposes a `UiPathCLI` global that host applications can load to run CLI commands without a Node.js backend.
|
|
4
|
-
|
|
5
|
-
## What's in the bundle
|
|
6
|
-
|
|
7
|
-
- **3 tools** (browser-compatible): `orchestrator-tool` (`or`), `integrationservice-tool` (`is`), `test-manager-tool` (`tm`)
|
|
8
|
-
- **Core framework**: Commander program, `--output-filter`, output formatting, telemetry, error handling
|
|
9
|
-
|
|
10
|
-
Each tool opts in by shipping a `browser.json` next to its `package.json` with `{ "compatible": true }`. At build time, `discover-browser-tools` scans `packages/*-tool/` and emits a virtual module importing each opted-in tool.
|
|
11
|
-
|
|
12
|
-
Authentication is **not** included in this bundle — commands will return "Not logged in" until the browser-auth PR lands (#701).
|
|
13
|
-
|
|
14
|
-
## Bundle
|
|
15
|
-
|
|
16
|
-
- **Build command**: `bun run browser:build` (from `packages/cli/`)
|
|
17
|
-
- **Output**: `packages/cli/dist/uip-browser.js`, plus `dist/metafile.json` for build-time assertions
|
|
18
|
-
- **Size**: ~3.3 MB unminified; ~1.4 MB / ~250 KB gzipped when `minify: true` is re-enabled in `build-browser.ts`
|
|
19
|
-
- **Format**: IIFE, exposes `UiPathCLI` global
|
|
20
|
-
|
|
21
|
-
## Loading the bundle
|
|
22
|
-
|
|
23
|
-
```html
|
|
24
|
-
<script src="/path/to/uip-browser.js"></script>
|
|
25
|
-
<script>
|
|
26
|
-
(async () => {
|
|
27
|
-
// Wait for filesystem (LightningFS over IndexedDB) to initialize
|
|
28
|
-
await UiPathCLI.ready;
|
|
29
|
-
|
|
30
|
-
// Run a CLI command
|
|
31
|
-
await UiPathCLI.run(['node', 'uip', '--help']);
|
|
32
|
-
})();
|
|
33
|
-
</script>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## API
|
|
37
|
-
|
|
38
|
-
### `UiPathCLI.run(args, options?)`
|
|
39
|
-
|
|
40
|
-
Parses and executes a CLI invocation.
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
UiPathCLI.run(
|
|
44
|
-
args: string[], // e.g. ['node', 'uip', 'or', 'folders', 'list']
|
|
45
|
-
options?: {
|
|
46
|
-
enabledTools?: string[]; // allowlist by command prefix: ['or', 'is']
|
|
47
|
-
}
|
|
48
|
-
): Promise<void>
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
**`enabledTools`** — allowlist of tool command prefixes that register with Commander. Omit to register all discovered browser-compatible tools.
|
|
52
|
-
|
|
53
|
-
### `UiPathCLI.ready`
|
|
54
|
-
|
|
55
|
-
A `Promise<void>` that resolves when the virtual filesystem (LightningFS over IndexedDB) has initialized. Await before the first `run()` call.
|
|
56
|
-
|
|
57
|
-
## Browser-compatible tools
|
|
58
|
-
|
|
59
|
-
| Command | Tool | What it does |
|
|
60
|
-
|---------|------|--------------|
|
|
61
|
-
| `uip or <subcommand>` | orchestrator-tool | Jobs, processes, packages, folders, machines, licenses, users, permissions |
|
|
62
|
-
| `uip is <subcommand>` | integrationservice-tool | Connectors, connections, triggers |
|
|
63
|
-
| `uip tm <subcommand>` | test-manager-tool | Test cases, sets, executions, results |
|
|
64
|
-
|
|
65
|
-
Use `uip or --help` (etc.) for the full subcommand tree.
|
|
66
|
-
|
|
67
|
-
## Reusing services without the CLI program
|
|
68
|
-
|
|
69
|
-
`@uipath/cli/browser` exports the CLI **runner** — the whole Commander program.
|
|
70
|
-
A host that only needs one of the CLI's services can import it directly:
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
// Dependency-free, ~3KB, no side effects.
|
|
74
|
-
const { markdownToJiraWiki } = await import(
|
|
75
|
-
"@uipath/cli/services/markdown-to-jira-wiki"
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// ~178KB. Browser-only — @uipath/filesystem creates an IndexedDB store on
|
|
79
|
-
// import, so this crashes under Node. Hence the `/browser` suffix, matching
|
|
80
|
-
// `@uipath/cli/browser`.
|
|
81
|
-
const { createFeedbackIssue, uploadAttachment } = await import(
|
|
82
|
-
"@uipath/cli/services/feedback/browser"
|
|
83
|
-
);
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
These exist so embedding hosts stop duplicating service logic. Autopilot's Studio
|
|
87
|
-
Web MFE serves `uip feedback send` through a host interceptor — the command is
|
|
88
|
-
Node-only, registered in `cli.node.ts` — and had ported the markdown converter
|
|
89
|
-
and the issue-creation calls verbatim. Two copies of the tracker's
|
|
90
|
-
project/component/field ids is a drift hazard.
|
|
91
|
-
|
|
92
|
-
The two entries are split deliberately: the markdown converter is
|
|
93
|
-
dependency-free, so a host that only formats descriptions should not pay for a
|
|
94
|
-
filesystem it never touches.
|
|
95
|
-
|
|
96
|
-
**These bundles are browser-safe because of the build, not the dependency graph.**
|
|
97
|
-
`@uipath/common` resolves to its Node source and reaches `node:async_hooks`;
|
|
98
|
-
`build-browser.ts`'s alias map rewrites that to a throwing shim and routes
|
|
99
|
-
`@uipath/filesystem` to its browser entry. Importing the TypeScript sources
|
|
100
|
-
directly is not browser-safe.
|
|
101
|
-
|
|
102
|
-
Node-only services are deliberately absent: `send-feedback.ts`
|
|
103
|
-
(`@inquirer/prompts`, stdin) and `environmentInfo.ts` (`node:os`).
|
|
104
|
-
`services.browser.spec.ts` guards the surface and the exclusions.
|
|
105
|
-
|
|
106
|
-
No type declarations ship with this package, so declare the surface structurally
|
|
107
|
-
at the call site — the same way Autopilot already declares `run`/`ready`.
|
|
108
|
-
|
|
109
|
-
## Limitations
|
|
110
|
-
|
|
111
|
-
- **No authentication.** Wiring for credential injection ships in a follow-up (#701). Until then, any command that calls the UiPath Cloud API returns `Not logged in`.
|
|
112
|
-
- **No interactive prompts.** Commands that use `@inquirer/prompts` (e.g. `send-feedback`, `tools install --interactive`) are Node-only and not registered in the browser bundle.
|
|
113
|
-
- **No file-based auth.** `uip login` / `uip logout` are Node-only and excluded from the browser entry.
|
|
114
|
-
- **No subprocess spawning.** `child_process` is not available.
|
|
115
|
-
- **Filesystem is virtual.** All file I/O routes through `@uipath/filesystem`'s `BrowserFileSystem`, backed by LightningFS + IndexedDB. Host-app code that reads/writes files should use `getFileSystem()` / `getFileSystemAsync()` from `@uipath/filesystem`.
|
|
116
|
-
- **Direct `node:fs` / `node:path` imports fail at build time** for any non-commander caller — Rule 10 is enforced by the bundler.
|
|
117
|
-
|
|
118
|
-
## CORS
|
|
119
|
-
|
|
120
|
-
Once auth lands in #701, the bundle will make `fetch()` requests directly to the UiPath Cloud API. The host page's origin must be allow-listed by the target environment, or the host can proxy API calls through its own server to avoid cross-origin preflight.
|
|
121
|
-
|
|
122
|
-
## Troubleshooting
|
|
123
|
-
|
|
124
|
-
**`"Result": "Failure", "Instructions": "Not logged in..."`** — expected for now; auth wiring ships in #701.
|
|
125
|
-
|
|
126
|
-
**`UiPathCLI is not defined`** — bundle hasn't loaded or loaded at a different scope. Confirm the `<script>` tag fires before your init code, or listen for its `load` event.
|
|
127
|
-
|
|
128
|
-
**IndexedDB errors** — the bundle uses LightningFS for its virtual filesystem. Not available in headless environments without IndexedDB polyfills (e.g. `happy-dom` without `fake-indexeddb`).
|