@uipath/tasks-tool 1.202.0-preview.140 → 1.202.0-preview.142
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/{tool-4er8cbf1.js → tool-315h4wtj.js} +5 -2
- package/dist/tool.js +1 -1
- package/package.json +5 -2
- package/browser.json +0 -4
- package/src/commands/_shared/catalog-options.spec.ts +0 -114
- package/src/commands/_shared/catalog-options.ts +0 -122
- package/src/commands/_shared/connect.spec.ts +0 -52
- package/src/commands/_shared/connect.ts +0 -31
- package/src/commands/_shared/constants.ts +0 -1
- package/src/commands/_shared/folder-picker-interactive.spec.ts +0 -92
- package/src/commands/_shared/folder-picker-interactive.ts +0 -76
- package/src/commands/_shared/folder-picker.spec.ts +0 -159
- package/src/commands/_shared/folder-picker.ts +0 -113
- package/src/commands/_shared/folder-resolver.spec.ts +0 -152
- package/src/commands/_shared/folder-resolver.ts +0 -113
- package/src/commands/_shared/parse.spec.ts +0 -69
- package/src/commands/_shared/parse.ts +0 -43
- package/src/commands/catalogs.ts +0 -281
- package/src/commands/comments.ts +0 -160
- package/src/commands/data.ts +0 -137
- package/src/commands/labels.ts +0 -93
- package/src/commands/metadata.ts +0 -139
- package/src/commands/tasks.spec.ts +0 -2449
- package/src/commands/tasks.ts +0 -631
- package/src/index.ts +0 -12
- package/src/tool.ts +0 -24
- package/src/utils/sdk-client.ts +0 -30
- package/tests/assign.e2e.test.ts +0 -166
- package/tests/assignable-users.e2e.test.ts +0 -167
- package/tests/catalogs.e2e.test.ts +0 -418
- package/tests/comments.e2e.test.ts +0 -223
- package/tests/complete.e2e.test.ts +0 -207
- package/tests/data.e2e.test.ts +0 -187
- package/tests/get.e2e.test.ts +0 -103
- package/tests/labels.e2e.test.ts +0 -184
- package/tests/list.e2e.test.ts +0 -234
- package/tests/metadata.e2e.test.ts +0 -186
- package/tests/performance.e2e.test.ts +0 -32
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -4502,7 +4502,7 @@ var require_src6 = __commonJS(function(exports) {
|
|
|
4502
4502
|
var package_default = {
|
|
4503
4503
|
name: "@uipath/tasks-tool",
|
|
4504
4504
|
license: "MIT",
|
|
4505
|
-
version: "1.202.0-preview.
|
|
4505
|
+
version: "1.202.0-preview.142",
|
|
4506
4506
|
description: "Manage Action Center tasks.",
|
|
4507
4507
|
publishConfig: {
|
|
4508
4508
|
registry: "https://npm.pkg.github.com/"
|
|
@@ -4515,6 +4515,9 @@ var package_default = {
|
|
|
4515
4515
|
bin: {
|
|
4516
4516
|
"tasks-tool": "./dist/index.js"
|
|
4517
4517
|
},
|
|
4518
|
+
files: [
|
|
4519
|
+
"dist"
|
|
4520
|
+
],
|
|
4518
4521
|
scripts: {
|
|
4519
4522
|
build: "bun ../../tools/build-tool.ts",
|
|
4520
4523
|
test: "vitest run",
|
|
@@ -18243,4 +18246,4 @@ var registerCommands = async (program) => {
|
|
|
18243
18246
|
|
|
18244
18247
|
export { metadata, registerCommands };
|
|
18245
18248
|
|
|
18246
|
-
//# debugId=
|
|
18249
|
+
//# debugId=4B608B7C6EC19A3264756E2164756E21
|
package/dist/tool.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/tasks-tool",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "1.202.0-preview.
|
|
4
|
+
"version": "1.202.0-preview.142",
|
|
5
5
|
"description": "Manage Action Center tasks.",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -14,5 +14,8 @@
|
|
|
14
14
|
"bin": {
|
|
15
15
|
"tasks-tool": "./dist/index.js"
|
|
16
16
|
},
|
|
17
|
-
"
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"gitHead": "2f7204440851d62ecc9f2d2e202c863293821d90"
|
|
18
21
|
}
|
package/browser.json
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
vi.mock("@uipath/common", async (importOriginal) => {
|
|
4
|
-
const actual = await importOriginal<typeof import("@uipath/common")>();
|
|
5
|
-
return {
|
|
6
|
-
...actual,
|
|
7
|
-
OutputFormatter: { success: vi.fn(), error: vi.fn() },
|
|
8
|
-
};
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
import { OutputFormatter } from "@uipath/common";
|
|
12
|
-
import {
|
|
13
|
-
buildCatalogCreateOptions,
|
|
14
|
-
buildCatalogUpdateOptions,
|
|
15
|
-
} from "./catalog-options";
|
|
16
|
-
|
|
17
|
-
describe("buildCatalogCreateOptions", () => {
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
vi.resetAllMocks();
|
|
20
|
-
process.exitCode = undefined;
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("builds folderId only", () => {
|
|
24
|
-
expect(
|
|
25
|
-
buildCatalogCreateOptions({ folderId: "42", name: "x" }, 42),
|
|
26
|
-
).toEqual({ folderId: 42 });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("includes description, encryption, and retention", () => {
|
|
30
|
-
const result = buildCatalogCreateOptions(
|
|
31
|
-
{
|
|
32
|
-
folderId: "42",
|
|
33
|
-
name: "x",
|
|
34
|
-
description: "desc",
|
|
35
|
-
encrypted: true,
|
|
36
|
-
retentionAction: "Archive",
|
|
37
|
-
retentionPeriod: "30",
|
|
38
|
-
retentionBucketId: "7",
|
|
39
|
-
},
|
|
40
|
-
42,
|
|
41
|
-
);
|
|
42
|
-
expect(result).toEqual({
|
|
43
|
-
folderId: 42,
|
|
44
|
-
description: "desc",
|
|
45
|
-
encrypted: true,
|
|
46
|
-
retentionAction: "Archive",
|
|
47
|
-
retentionPeriod: 30,
|
|
48
|
-
retentionBucketId: 7,
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("rejects an invalid retention action", () => {
|
|
53
|
-
const result = buildCatalogCreateOptions(
|
|
54
|
-
{ folderId: "42", name: "x", retentionAction: "Purge" },
|
|
55
|
-
42,
|
|
56
|
-
);
|
|
57
|
-
expect(result).toBeNull();
|
|
58
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
59
|
-
expect.objectContaining({
|
|
60
|
-
Message: "Invalid --retention-action 'Purge'",
|
|
61
|
-
}),
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it.each([
|
|
66
|
-
["retentionPeriod", "--retention-period"],
|
|
67
|
-
["retentionBucketId", "--retention-bucket-id"],
|
|
68
|
-
])("rejects an invalid %s", (field, flag) => {
|
|
69
|
-
const result = buildCatalogCreateOptions(
|
|
70
|
-
{ folderId: "42", name: "x", [field]: "abc" },
|
|
71
|
-
42,
|
|
72
|
-
);
|
|
73
|
-
expect(result).toBeNull();
|
|
74
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
75
|
-
expect.objectContaining({ Message: `Invalid ${flag}: abc` }),
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("buildCatalogUpdateOptions", () => {
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
vi.resetAllMocks();
|
|
83
|
-
process.exitCode = undefined;
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("includes name when provided", () => {
|
|
87
|
-
expect(
|
|
88
|
-
buildCatalogUpdateOptions({ folderId: "42", name: "renamed" }, 42),
|
|
89
|
-
).toEqual({ folderId: 42, name: "renamed" });
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("omits name when not provided and never sets encrypted", () => {
|
|
93
|
-
const result = buildCatalogUpdateOptions(
|
|
94
|
-
{ folderId: "42", description: "d" },
|
|
95
|
-
42,
|
|
96
|
-
);
|
|
97
|
-
expect(result).toEqual({ folderId: 42, description: "d" });
|
|
98
|
-
expect(result).not.toHaveProperty("name");
|
|
99
|
-
expect(result).not.toHaveProperty("encrypted");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("rejects an invalid retention action", () => {
|
|
103
|
-
const result = buildCatalogUpdateOptions(
|
|
104
|
-
{ folderId: "42", retentionAction: "Nope" },
|
|
105
|
-
42,
|
|
106
|
-
);
|
|
107
|
-
expect(result).toBeNull();
|
|
108
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
109
|
-
expect.objectContaining({
|
|
110
|
-
Message: "Invalid --retention-action 'Nope'",
|
|
111
|
-
}),
|
|
112
|
-
);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { OutputFormatter, processContext, RESULTS } from "@uipath/common";
|
|
2
|
-
import type {
|
|
3
|
-
TaskCatalogCreateOptions,
|
|
4
|
-
TaskCatalogUpdateOptions,
|
|
5
|
-
} from "@uipath/uipath-typescript";
|
|
6
|
-
import { TaskCatalogRetentionAction } from "@uipath/uipath-typescript";
|
|
7
|
-
|
|
8
|
-
import type { FolderScopeOptions } from "./folder-picker";
|
|
9
|
-
import { parsePositiveInt, reportInvalidInt } from "./parse";
|
|
10
|
-
|
|
11
|
-
// None is a read-only state, not a settable action, so the CLI only offers Delete and Archive.
|
|
12
|
-
const RETENTION_ACTIONS: TaskCatalogRetentionAction[] = [
|
|
13
|
-
TaskCatalogRetentionAction.Delete,
|
|
14
|
-
TaskCatalogRetentionAction.Archive,
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
export interface CatalogListOptions extends FolderScopeOptions {
|
|
18
|
-
limit?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type CatalogGetOptions = FolderScopeOptions;
|
|
22
|
-
|
|
23
|
-
export interface CatalogCreateOptions extends FolderScopeOptions {
|
|
24
|
-
name: string;
|
|
25
|
-
description?: string;
|
|
26
|
-
encrypted?: boolean;
|
|
27
|
-
retentionAction?: string;
|
|
28
|
-
retentionPeriod?: string;
|
|
29
|
-
retentionBucketId?: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface CatalogUpdateOptions extends FolderScopeOptions {
|
|
33
|
-
name?: string;
|
|
34
|
-
description?: string;
|
|
35
|
-
retentionAction?: string;
|
|
36
|
-
retentionPeriod?: string;
|
|
37
|
-
retentionBucketId?: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Common retention/description fields shared by create and update. Returns
|
|
41
|
-
// false after emitting an error + exit when a value is invalid.
|
|
42
|
-
function applyCommonFields(
|
|
43
|
-
target: {
|
|
44
|
-
description?: string;
|
|
45
|
-
retentionAction?: TaskCatalogRetentionAction;
|
|
46
|
-
retentionPeriod?: number;
|
|
47
|
-
retentionBucketId?: number;
|
|
48
|
-
},
|
|
49
|
-
options: {
|
|
50
|
-
description?: string;
|
|
51
|
-
retentionAction?: string;
|
|
52
|
-
retentionPeriod?: string;
|
|
53
|
-
retentionBucketId?: string;
|
|
54
|
-
},
|
|
55
|
-
): boolean {
|
|
56
|
-
if (options.description !== undefined) {
|
|
57
|
-
target.description = options.description;
|
|
58
|
-
}
|
|
59
|
-
if (options.retentionAction !== undefined) {
|
|
60
|
-
if (
|
|
61
|
-
!RETENTION_ACTIONS.includes(
|
|
62
|
-
options.retentionAction as TaskCatalogRetentionAction,
|
|
63
|
-
)
|
|
64
|
-
) {
|
|
65
|
-
OutputFormatter.error({
|
|
66
|
-
Result: RESULTS.Failure,
|
|
67
|
-
Message: `Invalid --retention-action '${options.retentionAction}'`,
|
|
68
|
-
Instructions: `Valid values: ${RETENTION_ACTIONS.join(", ")}`,
|
|
69
|
-
});
|
|
70
|
-
processContext.exit(1);
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
target.retentionAction =
|
|
74
|
-
options.retentionAction as TaskCatalogRetentionAction;
|
|
75
|
-
}
|
|
76
|
-
if (options.retentionPeriod !== undefined) {
|
|
77
|
-
const parsed = parsePositiveInt(
|
|
78
|
-
options.retentionPeriod,
|
|
79
|
-
"--retention-period",
|
|
80
|
-
);
|
|
81
|
-
if (!parsed.valid) {
|
|
82
|
-
reportInvalidInt(parsed);
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
target.retentionPeriod = parsed.value;
|
|
86
|
-
}
|
|
87
|
-
if (options.retentionBucketId !== undefined) {
|
|
88
|
-
const parsed = parsePositiveInt(
|
|
89
|
-
options.retentionBucketId,
|
|
90
|
-
"--retention-bucket-id",
|
|
91
|
-
);
|
|
92
|
-
if (!parsed.valid) {
|
|
93
|
-
reportInvalidInt(parsed);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
target.retentionBucketId = parsed.value;
|
|
97
|
-
}
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function buildCatalogCreateOptions(
|
|
102
|
-
options: CatalogCreateOptions,
|
|
103
|
-
folderId: number,
|
|
104
|
-
): TaskCatalogCreateOptions | null {
|
|
105
|
-
const result: TaskCatalogCreateOptions = { folderId };
|
|
106
|
-
if (options.encrypted) {
|
|
107
|
-
result.encrypted = true;
|
|
108
|
-
}
|
|
109
|
-
return applyCommonFields(result, options) ? result : null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function buildCatalogUpdateOptions(
|
|
113
|
-
options: CatalogUpdateOptions,
|
|
114
|
-
folderId: number,
|
|
115
|
-
): TaskCatalogUpdateOptions | null {
|
|
116
|
-
// `encrypted` is immutable on update, so it is intentionally not set here.
|
|
117
|
-
const result: TaskCatalogUpdateOptions = { folderId };
|
|
118
|
-
if (options.name !== undefined) {
|
|
119
|
-
result.name = options.name;
|
|
120
|
-
}
|
|
121
|
-
return applyCommonFields(result, options) ? result : null;
|
|
122
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
vi.mock("../../utils/sdk-client", () => ({
|
|
4
|
-
createTasksClient: vi.fn(),
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
vi.mock("@uipath/common", async (importOriginal) => {
|
|
8
|
-
const actual = await importOriginal<typeof import("@uipath/common")>();
|
|
9
|
-
return {
|
|
10
|
-
...actual,
|
|
11
|
-
OutputFormatter: { success: vi.fn(), error: vi.fn() },
|
|
12
|
-
};
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
import { OutputFormatter } from "@uipath/common";
|
|
16
|
-
import { createTasksClient } from "../../utils/sdk-client";
|
|
17
|
-
import { connectTasksClient } from "./connect";
|
|
18
|
-
|
|
19
|
-
describe("connectTasksClient", () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
vi.resetAllMocks();
|
|
22
|
-
process.exitCode = undefined;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("returns the client on success", async () => {
|
|
26
|
-
const sdk = { tasks: {} };
|
|
27
|
-
vi.mocked(createTasksClient).mockResolvedValue(sdk as never);
|
|
28
|
-
|
|
29
|
-
const result = await connectTasksClient("MyTenant");
|
|
30
|
-
|
|
31
|
-
expect(result).toBe(sdk);
|
|
32
|
-
expect(createTasksClient).toHaveBeenCalledWith("MyTenant");
|
|
33
|
-
expect(OutputFormatter.error).not.toHaveBeenCalled();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("reports, exits, and returns null on failure", async () => {
|
|
37
|
-
vi.mocked(createTasksClient).mockRejectedValue(
|
|
38
|
-
new Error("Not logged in"),
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
const result = await connectTasksClient();
|
|
42
|
-
|
|
43
|
-
expect(result).toBeNull();
|
|
44
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
45
|
-
expect.objectContaining({
|
|
46
|
-
Result: "Failure",
|
|
47
|
-
Message: "Error connecting to Action Center",
|
|
48
|
-
}),
|
|
49
|
-
);
|
|
50
|
-
expect(process.exitCode).toBe(1);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
catchError,
|
|
3
|
-
extractErrorMessage,
|
|
4
|
-
OutputFormatter,
|
|
5
|
-
processContext,
|
|
6
|
-
RESULTS,
|
|
7
|
-
} from "@uipath/common";
|
|
8
|
-
import type { UiPath } from "@uipath/uipath-typescript";
|
|
9
|
-
|
|
10
|
-
import { createTasksClient } from "../../utils/sdk-client";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Connects to Action Center for the given tenant. On failure, emits the
|
|
14
|
-
* standard error, exits with code 1, and returns null so the caller can
|
|
15
|
-
* `return` early. Keeps the connect boilerplate in one place.
|
|
16
|
-
*/
|
|
17
|
-
export async function connectTasksClient(
|
|
18
|
-
tenant?: string,
|
|
19
|
-
): Promise<UiPath | null> {
|
|
20
|
-
const [clientError, sdk] = await catchError(createTasksClient(tenant));
|
|
21
|
-
if (clientError) {
|
|
22
|
-
OutputFormatter.error({
|
|
23
|
-
Result: RESULTS.Failure,
|
|
24
|
-
Message: "Error connecting to Action Center",
|
|
25
|
-
Instructions: await extractErrorMessage(clientError),
|
|
26
|
-
});
|
|
27
|
-
processContext.exit(1);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
return sdk;
|
|
31
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_PAGE_SIZE = 100;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
vi.mock("@inquirer/prompts", () => ({ select: vi.fn() }));
|
|
4
|
-
|
|
5
|
-
vi.mock("@uipath/orchestrator-sdk", () => ({
|
|
6
|
-
createApiClient: vi.fn(),
|
|
7
|
-
FoldersApi: class {},
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
vi.mock("@uipath/common", async (importOriginal) => {
|
|
11
|
-
const actual = await importOriginal<typeof import("@uipath/common")>();
|
|
12
|
-
return {
|
|
13
|
-
...actual,
|
|
14
|
-
OutputFormatter: { success: vi.fn(), error: vi.fn() },
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
import { select } from "@inquirer/prompts";
|
|
19
|
-
import { OutputFormatter } from "@uipath/common";
|
|
20
|
-
import { createApiClient } from "@uipath/orchestrator-sdk";
|
|
21
|
-
import { pickFolderInteractively } from "./folder-picker-interactive";
|
|
22
|
-
|
|
23
|
-
function mockFolders(pageItems: unknown[]) {
|
|
24
|
-
vi.mocked(createApiClient).mockResolvedValue({
|
|
25
|
-
foldersGetAllForCurrentUser: vi.fn().mockResolvedValue({ pageItems }),
|
|
26
|
-
} as never);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe("pickFolderInteractively", () => {
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
vi.resetAllMocks();
|
|
32
|
-
process.exitCode = undefined;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("lists folders and returns the selected id", async () => {
|
|
36
|
-
mockFolders([
|
|
37
|
-
{ id: 7, displayName: "Finance" },
|
|
38
|
-
{ id: 9, displayName: "HR" },
|
|
39
|
-
]);
|
|
40
|
-
vi.mocked(select).mockResolvedValue(7 as never);
|
|
41
|
-
|
|
42
|
-
expect(await pickFolderInteractively()).toBe(7);
|
|
43
|
-
expect(select).toHaveBeenCalled();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("passes the tenant through to the folder client", async () => {
|
|
47
|
-
mockFolders([{ id: 7, displayName: "Finance" }]);
|
|
48
|
-
vi.mocked(select).mockResolvedValue(7 as never);
|
|
49
|
-
|
|
50
|
-
expect(await pickFolderInteractively("my-tenant")).toBe(7);
|
|
51
|
-
expect(createApiClient).toHaveBeenCalledWith(expect.anything(), {
|
|
52
|
-
tenant: "my-tenant",
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("reports a connection error", async () => {
|
|
57
|
-
vi.mocked(createApiClient).mockRejectedValue(new Error("boom"));
|
|
58
|
-
|
|
59
|
-
expect(await pickFolderInteractively()).toBeNull();
|
|
60
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
61
|
-
expect.objectContaining({
|
|
62
|
-
Message: "Error connecting to Action Center",
|
|
63
|
-
}),
|
|
64
|
-
);
|
|
65
|
-
expect(process.exitCode).toBe(1);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("reports a listing error", async () => {
|
|
69
|
-
vi.mocked(createApiClient).mockResolvedValue({
|
|
70
|
-
foldersGetAllForCurrentUser: vi
|
|
71
|
-
.fn()
|
|
72
|
-
.mockRejectedValue(new Error("nope")),
|
|
73
|
-
} as never);
|
|
74
|
-
|
|
75
|
-
expect(await pickFolderInteractively()).toBeNull();
|
|
76
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
77
|
-
expect.objectContaining({ Message: "Error listing folders" }),
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("fails when no selectable folders are returned", async () => {
|
|
82
|
-
mockFolders([{ displayName: "no id here" }]);
|
|
83
|
-
|
|
84
|
-
expect(await pickFolderInteractively()).toBeNull();
|
|
85
|
-
expect(OutputFormatter.error).toHaveBeenCalledWith(
|
|
86
|
-
expect.objectContaining({
|
|
87
|
-
Message: "No folders available to select",
|
|
88
|
-
}),
|
|
89
|
-
);
|
|
90
|
-
expect(select).not.toHaveBeenCalled();
|
|
91
|
-
});
|
|
92
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { select } from "@inquirer/prompts";
|
|
2
|
-
import {
|
|
3
|
-
catchError,
|
|
4
|
-
extractErrorMessage,
|
|
5
|
-
OutputFormatter,
|
|
6
|
-
processContext,
|
|
7
|
-
RESULTS,
|
|
8
|
-
} from "@uipath/common";
|
|
9
|
-
import {
|
|
10
|
-
type CurrentUserFolderDto,
|
|
11
|
-
createApiClient,
|
|
12
|
-
FoldersApi,
|
|
13
|
-
} from "@uipath/orchestrator-sdk";
|
|
14
|
-
|
|
15
|
-
const FOLDER_PAGE_SIZE = 200;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Interactive folder picker. Pulls @inquirer/prompts, which is Node-only
|
|
19
|
-
* (TTY prompts), so it is excluded from the browser bundle
|
|
20
|
-
* (browser.json -> excludedImports) and only imported on a TTY.
|
|
21
|
-
* (@uipath/orchestrator-sdk itself is browser-safe — it ships a browser
|
|
22
|
-
* export and reaches the browser bundle through folder-resolver.)
|
|
23
|
-
*
|
|
24
|
-
* Returns null when listing/selection fails (after emitting an error + exit).
|
|
25
|
-
*/
|
|
26
|
-
export async function pickFolderInteractively(
|
|
27
|
-
tenant?: string,
|
|
28
|
-
): Promise<number | null> {
|
|
29
|
-
const [clientError, api] = await catchError(
|
|
30
|
-
createApiClient(FoldersApi, { tenant }),
|
|
31
|
-
);
|
|
32
|
-
if (clientError) {
|
|
33
|
-
OutputFormatter.error({
|
|
34
|
-
Result: RESULTS.Failure,
|
|
35
|
-
Message: "Error connecting to Action Center",
|
|
36
|
-
Instructions: await extractErrorMessage(clientError),
|
|
37
|
-
});
|
|
38
|
-
processContext.exit(1);
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const [listError, result] = await catchError(
|
|
43
|
-
api.foldersGetAllForCurrentUser({ take: FOLDER_PAGE_SIZE }),
|
|
44
|
-
);
|
|
45
|
-
if (listError) {
|
|
46
|
-
OutputFormatter.error({
|
|
47
|
-
Result: RESULTS.Failure,
|
|
48
|
-
Message: "Error listing folders",
|
|
49
|
-
Instructions: await extractErrorMessage(listError),
|
|
50
|
-
});
|
|
51
|
-
processContext.exit(1);
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const folders = (result.pageItems ?? []).filter(
|
|
56
|
-
(f: CurrentUserFolderDto): f is CurrentUserFolderDto & { id: number } =>
|
|
57
|
-
typeof f.id === "number",
|
|
58
|
-
);
|
|
59
|
-
if (folders.length === 0) {
|
|
60
|
-
OutputFormatter.error({
|
|
61
|
-
Result: RESULTS.Failure,
|
|
62
|
-
Message: "No folders available to select",
|
|
63
|
-
Instructions: "Pass --folder-id <id> instead.",
|
|
64
|
-
});
|
|
65
|
-
processContext.exit(1);
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return select<number>({
|
|
70
|
-
message: "Select a folder",
|
|
71
|
-
choices: folders.map((f) => ({
|
|
72
|
-
name: f.fullyQualifiedName || f.displayName || String(f.id),
|
|
73
|
-
value: f.id,
|
|
74
|
-
})),
|
|
75
|
-
});
|
|
76
|
-
}
|