@cipherly/plane-cli 1.0.0
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/LICENSE +201 -0
- package/README.md +65 -0
- package/dist/cycles/create.cycles.js +44 -0
- package/dist/cycles/delete.cycles.js +30 -0
- package/dist/cycles/index.js +21 -0
- package/dist/cycles/list.cycles.js +42 -0
- package/dist/cycles/update.cycles.js +46 -0
- package/dist/cycles/work-items/index.js +17 -0
- package/dist/cycles/work-items/list.cycles.work-items.js +43 -0
- package/dist/labels/create.labels.js +34 -0
- package/dist/labels/delete.labels.js +30 -0
- package/dist/labels/index.js +20 -0
- package/dist/labels/list.labels.js +36 -0
- package/dist/labels/update.labels.js +36 -0
- package/dist/plane.js +60 -0
- package/dist/projects/create.projects.js +38 -0
- package/dist/projects/delete.projects.js +28 -0
- package/dist/projects/index.js +20 -0
- package/dist/projects/list.projects.js +35 -0
- package/dist/projects/update.projects.js +39 -0
- package/dist/states/create.states.js +37 -0
- package/dist/states/delete.states.js +30 -0
- package/dist/states/index.js +20 -0
- package/dist/states/list.states.js +36 -0
- package/dist/states/update.states.js +36 -0
- package/dist/users/index.js +17 -0
- package/dist/users/me.users.js +36 -0
- package/dist/utils.js +63 -0
- package/dist/work-items/create.work-items.js +51 -0
- package/dist/work-items/delete.work-items.js +30 -0
- package/dist/work-items/index.js +21 -0
- package/dist/work-items/list.work-items.js +44 -0
- package/dist/work-items/types/index.js +17 -0
- package/dist/work-items/types/list.types.work-items.js +40 -0
- package/dist/work-items/update.work-items.js +41 -0
- package/package.json +29 -0
- package/src/cycles/create.cycles.ts +39 -0
- package/src/cycles/delete.cycles.ts +25 -0
- package/src/cycles/index.ts +5 -0
- package/src/cycles/list.cycles.ts +37 -0
- package/src/cycles/update.cycles.ts +41 -0
- package/src/cycles/work-items/index.ts +1 -0
- package/src/cycles/work-items/list.cycles.work-items.ts +40 -0
- package/src/labels/create.labels.ts +29 -0
- package/src/labels/delete.labels.ts +25 -0
- package/src/labels/index.ts +5 -0
- package/src/labels/list.labels.ts +31 -0
- package/src/labels/update.labels.ts +31 -0
- package/src/plane.ts +97 -0
- package/src/projects/create.projects.ts +33 -0
- package/src/projects/delete.projects.ts +23 -0
- package/src/projects/index.ts +5 -0
- package/src/projects/list.projects.ts +30 -0
- package/src/projects/update.projects.ts +32 -0
- package/src/states/create.states.ts +32 -0
- package/src/states/delete.states.ts +25 -0
- package/src/states/index.ts +5 -0
- package/src/states/list.states.ts +31 -0
- package/src/states/update.states.ts +31 -0
- package/src/users/index.ts +1 -0
- package/src/users/me.users.ts +30 -0
- package/src/utils.ts +81 -0
- package/src/work-items/create.work-items.ts +85 -0
- package/src/work-items/delete.work-items.ts +25 -0
- package/src/work-items/index.ts +5 -0
- package/src/work-items/list.work-items.ts +43 -0
- package/src/work-items/types/index.ts +1 -0
- package/src/work-items/types/list.types.work-items.ts +36 -0
- package/src/work-items/update.work-items.ts +79 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderWorkItem = exports.listWorkItems = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
exports.listWorkItems = new commander_1.Command("list")
|
|
7
|
+
.description("List work items")
|
|
8
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
9
|
+
.action(async (__, cmd) => {
|
|
10
|
+
if (cmd.parent == null)
|
|
11
|
+
return;
|
|
12
|
+
const { apiKey, apiBase, workspaceSlug, json } = (0, utils_1.checkRequiredOptionsAndReturn)(cmd);
|
|
13
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
14
|
+
const { result, status } = await (0, utils_1.requestPlaneAPI)({
|
|
15
|
+
apiBase,
|
|
16
|
+
apiKey,
|
|
17
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/work-items/`,
|
|
18
|
+
method: "GET",
|
|
19
|
+
params: {
|
|
20
|
+
expand: "state,labels,assignees",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (json)
|
|
24
|
+
console.log(JSON.stringify(result));
|
|
25
|
+
else {
|
|
26
|
+
if (status !== 200)
|
|
27
|
+
console.table(result);
|
|
28
|
+
else
|
|
29
|
+
console.table(result.results.map(exports.renderWorkItem));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const renderWorkItem = (workItem) => {
|
|
33
|
+
return {
|
|
34
|
+
id: workItem.id,
|
|
35
|
+
name: workItem.name,
|
|
36
|
+
state: (workItem.state && workItem.state.name) || null,
|
|
37
|
+
labels: (workItem.labels && workItem.labels.map((label) => label.name)) ||
|
|
38
|
+
[],
|
|
39
|
+
assignees: (workItem.assignees &&
|
|
40
|
+
workItem.assignees.map((user) => `${user.first_name} ${user.last_name}`.trim())) ||
|
|
41
|
+
[],
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
exports.renderWorkItem = renderWorkItem;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./list.types.work-items"), exports);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderWorkItemType = exports.listWorkItemTypes = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
exports.listWorkItemTypes = new commander_1.Command("list")
|
|
7
|
+
.description("List work item types")
|
|
8
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
9
|
+
.action(async (__, cmd) => {
|
|
10
|
+
if (cmd.parent == null)
|
|
11
|
+
return;
|
|
12
|
+
const { apiKey, apiBase, workspaceSlug, json } = (0, utils_1.checkRequiredOptionsAndReturn)(cmd);
|
|
13
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
14
|
+
const { result, status } = await (0, utils_1.requestPlaneAPI)({
|
|
15
|
+
apiBase,
|
|
16
|
+
apiKey,
|
|
17
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/work-item-types/`,
|
|
18
|
+
method: "GET",
|
|
19
|
+
});
|
|
20
|
+
if (json)
|
|
21
|
+
console.log(JSON.stringify(result));
|
|
22
|
+
else {
|
|
23
|
+
if (status !== 200)
|
|
24
|
+
console.table(result);
|
|
25
|
+
else
|
|
26
|
+
console.table(result.results.map(exports.renderWorkItemType));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const renderWorkItemType = (workItemType) => {
|
|
30
|
+
return {
|
|
31
|
+
id: workItemType.id,
|
|
32
|
+
name: workItemType.name,
|
|
33
|
+
description: workItemType.description,
|
|
34
|
+
is_epic: workItemType.is_epic,
|
|
35
|
+
is_default: workItemType.is_default,
|
|
36
|
+
is_active: workItemType.is_active,
|
|
37
|
+
level: workItemType.level,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
exports.renderWorkItemType = renderWorkItemType;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateWorkItem = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const list_work_items_1 = require("./list.work-items");
|
|
7
|
+
exports.updateWorkItem = new commander_1.Command("update")
|
|
8
|
+
.description("Update a work-item")
|
|
9
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
10
|
+
.requiredOption("-w, --work-item-id <workItemId>", "Work item's ID")
|
|
11
|
+
.option("-n, --name [name]", "Work item's name")
|
|
12
|
+
.option("-d, --description [description]", "Work item's description in HTML")
|
|
13
|
+
.action(async (__, cmd) => {
|
|
14
|
+
if (cmd.parent == null)
|
|
15
|
+
return;
|
|
16
|
+
const { apiKey, apiBase, workspaceSlug, json } = (0, utils_1.checkRequiredOptionsAndReturn)(cmd);
|
|
17
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
18
|
+
const workItemId = cmd.getOptionValue("workItemId");
|
|
19
|
+
const name = cmd.getOptionValue("name");
|
|
20
|
+
const description = cmd.getOptionValue("description");
|
|
21
|
+
const body = {};
|
|
22
|
+
if (name !== undefined)
|
|
23
|
+
body.name = name;
|
|
24
|
+
if (description !== undefined)
|
|
25
|
+
body.description = description;
|
|
26
|
+
const { result, status } = await (0, utils_1.requestPlaneAPI)({
|
|
27
|
+
apiBase,
|
|
28
|
+
apiKey,
|
|
29
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/work-items/${workItemId}/`,
|
|
30
|
+
method: "PATCH",
|
|
31
|
+
body,
|
|
32
|
+
});
|
|
33
|
+
if (json)
|
|
34
|
+
console.log(JSON.stringify(result));
|
|
35
|
+
else {
|
|
36
|
+
if (status !== 200)
|
|
37
|
+
console.table(result);
|
|
38
|
+
else
|
|
39
|
+
console.table((0, list_work_items_1.renderWorkItem)(result));
|
|
40
|
+
}
|
|
41
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cipherly/plane-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for api.plane.so",
|
|
5
|
+
"packageManager": "pnpm@8.8.0",
|
|
6
|
+
"bin": {
|
|
7
|
+
"plane": "dist/plane.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc -p tsconfig.json",
|
|
11
|
+
"dev": "ts-node src/plane.ts"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"commander": "^11.1.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^20.8.1",
|
|
21
|
+
"ts-node": "^10.9.1",
|
|
22
|
+
"typescript": "^5.2.2"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"plane",
|
|
26
|
+
"cli"
|
|
27
|
+
],
|
|
28
|
+
"license": "Apache-2.0"
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
import { renderCycle } from "./list.cycles";
|
|
4
|
+
|
|
5
|
+
export const createCycle = new Command("create")
|
|
6
|
+
.description("Create a new cycle")
|
|
7
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
8
|
+
.requiredOption("-n, --name <name>", "Cycle's name")
|
|
9
|
+
.option("-d, --description [description]", "Cycle's description")
|
|
10
|
+
.option("-sd, --start-date [startDate]", "Cycle's start date")
|
|
11
|
+
.option("-ed, --end-date [endDate]", "Cycle's end date")
|
|
12
|
+
.action(async (__, cmd: Command) => {
|
|
13
|
+
if (cmd.parent == null) return;
|
|
14
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
15
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
16
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
17
|
+
const name = cmd.getOptionValue("name");
|
|
18
|
+
const description = cmd.getOptionValue("description");
|
|
19
|
+
const startDate = cmd.getOptionValue("startDate");
|
|
20
|
+
const endDate = cmd.getOptionValue("endDate");
|
|
21
|
+
const { result, status } = await requestPlaneAPI({
|
|
22
|
+
apiBase,
|
|
23
|
+
apiKey,
|
|
24
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/cycles/`,
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: {
|
|
27
|
+
name,
|
|
28
|
+
description,
|
|
29
|
+
project_id: projectId,
|
|
30
|
+
start_date: startDate,
|
|
31
|
+
end_date: endDate,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
if (json) console.log(JSON.stringify(result));
|
|
35
|
+
else {
|
|
36
|
+
if (status !== 201) console.table(result);
|
|
37
|
+
else console.table(renderCycle(result));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const deleteCycle = new Command("delete")
|
|
5
|
+
.description("Delete a cycle")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.requiredOption("-c, --cycle-id <cycleId>", "Cycle's ID")
|
|
8
|
+
.action(async (__, cmd: Command) => {
|
|
9
|
+
if (cmd.parent == null) return;
|
|
10
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
11
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
12
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
13
|
+
const cycleId = cmd.getOptionValue("cycleId");
|
|
14
|
+
const { result, status } = await requestPlaneAPI({
|
|
15
|
+
apiBase,
|
|
16
|
+
apiKey,
|
|
17
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`,
|
|
18
|
+
method: "DELETE",
|
|
19
|
+
});
|
|
20
|
+
if (json) console.log(JSON.stringify(result));
|
|
21
|
+
else {
|
|
22
|
+
if (status !== 204) console.table(result);
|
|
23
|
+
else console.table(result);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const listCycles = new Command("list")
|
|
5
|
+
.description("List cycles")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.action(async (__, cmd: Command) => {
|
|
8
|
+
if (cmd.parent == null) return;
|
|
9
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
10
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
11
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
12
|
+
const { result, status } = await requestPlaneAPI({
|
|
13
|
+
apiBase,
|
|
14
|
+
apiKey,
|
|
15
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/cycles/`,
|
|
16
|
+
method: "GET",
|
|
17
|
+
});
|
|
18
|
+
if (json) console.log(JSON.stringify(result));
|
|
19
|
+
else {
|
|
20
|
+
if (status !== 200) console.table(result);
|
|
21
|
+
else console.table(result.results.map(renderCycle));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const renderCycle = (cycle: any) => {
|
|
26
|
+
return {
|
|
27
|
+
id: cycle.id,
|
|
28
|
+
name: cycle.name,
|
|
29
|
+
description: cycle.description,
|
|
30
|
+
total_issues: cycle.total_issues,
|
|
31
|
+
cancelled_issues: cycle.cancelled_issues,
|
|
32
|
+
completed_issues: cycle.completed_issues,
|
|
33
|
+
started_issues: cycle.started_issues,
|
|
34
|
+
unstarted_issues: cycle.unstarted_issues,
|
|
35
|
+
backlog_issues: cycle.backlog_issues,
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
import { renderCycle } from "./list.cycles";
|
|
4
|
+
|
|
5
|
+
export const updateCycle = new Command("update")
|
|
6
|
+
.description("Update a cycle")
|
|
7
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
8
|
+
.requiredOption("-c, --cycle-id <cycleId>", "Cycle's ID")
|
|
9
|
+
.option("-n, --name [name]", "Cycle's name")
|
|
10
|
+
.option("-d, --description [description]", "Cycle's description")
|
|
11
|
+
.option("-sd, --start-date [startDate]", "Cycle's start date")
|
|
12
|
+
.option("-ed, --end-date [endDate]", "Cycle's end date")
|
|
13
|
+
.action(async (__, cmd: Command) => {
|
|
14
|
+
if (cmd.parent == null) return;
|
|
15
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
16
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
17
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
18
|
+
const cycleId = cmd.getOptionValue("cycleId");
|
|
19
|
+
const name = cmd.getOptionValue("name");
|
|
20
|
+
const description = cmd.getOptionValue("description");
|
|
21
|
+
const startDate = cmd.getOptionValue("startDate");
|
|
22
|
+
const endDate = cmd.getOptionValue("endDate");
|
|
23
|
+
const { result, status } = await requestPlaneAPI({
|
|
24
|
+
apiBase,
|
|
25
|
+
apiKey,
|
|
26
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`,
|
|
27
|
+
method: "PATCH",
|
|
28
|
+
body: {
|
|
29
|
+
name,
|
|
30
|
+
description,
|
|
31
|
+
project_id: projectId,
|
|
32
|
+
start_date: startDate,
|
|
33
|
+
end_date: endDate,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
if (json) console.log(JSON.stringify(result));
|
|
37
|
+
else {
|
|
38
|
+
if (status !== 200) console.table(result);
|
|
39
|
+
else console.table(renderCycle(result));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./list.cycles.work-items";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../../utils";
|
|
3
|
+
|
|
4
|
+
export const listCyclesWorkItems = new Command("list-work-items")
|
|
5
|
+
.description("List cycle work items")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.requiredOption("-c, --cycle-id <cycleId>", "Cycle's ID")
|
|
8
|
+
.action(async (__, cmd: Command) => {
|
|
9
|
+
if (cmd.parent == null) return;
|
|
10
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
11
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
12
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
13
|
+
const cycleId = cmd.getOptionValue("cycleId");
|
|
14
|
+
const { result, status } = await requestPlaneAPI({
|
|
15
|
+
apiBase,
|
|
16
|
+
apiKey,
|
|
17
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`,
|
|
18
|
+
method: "GET",
|
|
19
|
+
params: {
|
|
20
|
+
expand: "state,labels,assignees",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (json) console.log(JSON.stringify(result));
|
|
24
|
+
else {
|
|
25
|
+
if (status !== 200) console.table(result);
|
|
26
|
+
else console.table(result.results.map(renderCycleWorkItem));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const renderCycleWorkItem = (workItem: any) => {
|
|
31
|
+
return {
|
|
32
|
+
id: workItem.id,
|
|
33
|
+
name: workItem.name,
|
|
34
|
+
state: workItem.state.name,
|
|
35
|
+
labels: workItem.labels.map((label: any) => label.name),
|
|
36
|
+
assignees: workItem.assignees.map((user: any) =>
|
|
37
|
+
`${user.first_name} ${user.last_name}`.trim(),
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
import { renderLabel } from "./list.labels";
|
|
4
|
+
|
|
5
|
+
export const createLabel = new Command("create")
|
|
6
|
+
.description("Create a new label")
|
|
7
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
8
|
+
.requiredOption("-n, --name <name>", "Label's name")
|
|
9
|
+
.action(async (__, cmd: Command) => {
|
|
10
|
+
if (cmd.parent == null) return;
|
|
11
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
12
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
13
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
14
|
+
const name = cmd.getOptionValue("name");
|
|
15
|
+
const { result, status } = await requestPlaneAPI({
|
|
16
|
+
apiBase,
|
|
17
|
+
apiKey,
|
|
18
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/labels/`,
|
|
19
|
+
method: "POST",
|
|
20
|
+
body: {
|
|
21
|
+
name,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (json) console.log(JSON.stringify(result));
|
|
25
|
+
else {
|
|
26
|
+
if (status !== 201) console.table(result);
|
|
27
|
+
else console.table(renderLabel(result));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const deleteLabel = new Command("delete")
|
|
5
|
+
.description("Delete a label")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.requiredOption("-l, --label-id <labelId>", "Label's ID")
|
|
8
|
+
.action(async (__, cmd: Command) => {
|
|
9
|
+
if (cmd.parent == null) return;
|
|
10
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
11
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
12
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
13
|
+
const labelId = cmd.getOptionValue("labelId");
|
|
14
|
+
const { result, status } = await requestPlaneAPI({
|
|
15
|
+
apiBase,
|
|
16
|
+
apiKey,
|
|
17
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/labels/${labelId}/`,
|
|
18
|
+
method: "DELETE",
|
|
19
|
+
});
|
|
20
|
+
if (json) console.log(JSON.stringify(result));
|
|
21
|
+
else {
|
|
22
|
+
if (status !== 204) console.table(result);
|
|
23
|
+
else console.table(result);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const listLabels = new Command("list")
|
|
5
|
+
.description("List labels")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.action(async (__, cmd: Command) => {
|
|
8
|
+
if (cmd.parent == null) return;
|
|
9
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
10
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
11
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
12
|
+
const { result, status } = await requestPlaneAPI({
|
|
13
|
+
apiBase,
|
|
14
|
+
apiKey,
|
|
15
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/labels/`,
|
|
16
|
+
method: "GET",
|
|
17
|
+
});
|
|
18
|
+
if (json) console.log(JSON.stringify(result));
|
|
19
|
+
else {
|
|
20
|
+
if (status !== 200) console.table(result);
|
|
21
|
+
else console.table(result.results.map(renderLabel));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const renderLabel = (label: any) => {
|
|
26
|
+
return {
|
|
27
|
+
id: label.id,
|
|
28
|
+
name: label.name,
|
|
29
|
+
description: label.description,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
import { renderLabel } from "./list.labels";
|
|
4
|
+
|
|
5
|
+
export const updateLabel = new Command("update")
|
|
6
|
+
.description("Update a label")
|
|
7
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
8
|
+
.requiredOption("-l, --label-id <labelId>", "Label's ID")
|
|
9
|
+
.requiredOption("-n, --name <name>", "Label's name")
|
|
10
|
+
.action(async (__, cmd: Command) => {
|
|
11
|
+
if (cmd.parent == null) return;
|
|
12
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
13
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
14
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
15
|
+
const labelId = cmd.getOptionValue("labelId");
|
|
16
|
+
const name = cmd.getOptionValue("name");
|
|
17
|
+
const { result, status } = await requestPlaneAPI({
|
|
18
|
+
apiBase,
|
|
19
|
+
apiKey,
|
|
20
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/labels/${labelId}/`,
|
|
21
|
+
method: "PATCH",
|
|
22
|
+
body: {
|
|
23
|
+
name,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
if (json) console.log(JSON.stringify(result));
|
|
27
|
+
else {
|
|
28
|
+
if (status !== 200) console.table(result);
|
|
29
|
+
else console.table(renderLabel(result));
|
|
30
|
+
}
|
|
31
|
+
});
|
package/src/plane.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import {
|
|
4
|
+
createProject,
|
|
5
|
+
deleteProject,
|
|
6
|
+
listProjects,
|
|
7
|
+
updateProject,
|
|
8
|
+
} from "./projects";
|
|
9
|
+
import {
|
|
10
|
+
createWorkItem,
|
|
11
|
+
deleteWorkItem,
|
|
12
|
+
listWorkItems,
|
|
13
|
+
listWorkItemTypes,
|
|
14
|
+
updateWorkItem,
|
|
15
|
+
} from "./work-items";
|
|
16
|
+
import { createState, deleteState, listStates, updateState } from "./states";
|
|
17
|
+
import { createLabel, deleteLabel, listLabels, updateLabel } from "./labels";
|
|
18
|
+
import {
|
|
19
|
+
createCycle,
|
|
20
|
+
deleteCycle,
|
|
21
|
+
listCycles,
|
|
22
|
+
listCyclesWorkItems,
|
|
23
|
+
updateCycle,
|
|
24
|
+
} from "./cycles";
|
|
25
|
+
import { getCurrentUser } from "./users";
|
|
26
|
+
|
|
27
|
+
const program = new Command();
|
|
28
|
+
program.name("plane").description("CLI for api.plane.so").version("1.0.0");
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command("projects")
|
|
32
|
+
.description("Manage projects")
|
|
33
|
+
.addCommand(listProjects)
|
|
34
|
+
.addCommand(createProject)
|
|
35
|
+
.addCommand(updateProject)
|
|
36
|
+
.addCommand(deleteProject);
|
|
37
|
+
|
|
38
|
+
program
|
|
39
|
+
.command("work-items")
|
|
40
|
+
.description("Manage work items")
|
|
41
|
+
.addCommand(listWorkItems)
|
|
42
|
+
.addCommand(createWorkItem)
|
|
43
|
+
.addCommand(updateWorkItem)
|
|
44
|
+
.addCommand(deleteWorkItem);
|
|
45
|
+
|
|
46
|
+
program
|
|
47
|
+
.command("work-item-types")
|
|
48
|
+
.description("Manage work item types")
|
|
49
|
+
.addCommand(listWorkItemTypes);
|
|
50
|
+
|
|
51
|
+
program
|
|
52
|
+
.command("states")
|
|
53
|
+
.description("Manage states")
|
|
54
|
+
.addCommand(listStates)
|
|
55
|
+
.addCommand(createState)
|
|
56
|
+
.addCommand(updateState)
|
|
57
|
+
.addCommand(deleteState);
|
|
58
|
+
|
|
59
|
+
program
|
|
60
|
+
.command("labels")
|
|
61
|
+
.description("Manage labels")
|
|
62
|
+
.addCommand(listLabels)
|
|
63
|
+
.addCommand(createLabel)
|
|
64
|
+
.addCommand(updateLabel)
|
|
65
|
+
.addCommand(deleteLabel);
|
|
66
|
+
|
|
67
|
+
program
|
|
68
|
+
.command("cycles")
|
|
69
|
+
.description("Manage cycles")
|
|
70
|
+
.addCommand(listCycles)
|
|
71
|
+
.addCommand(listCyclesWorkItems)
|
|
72
|
+
.addCommand(createCycle)
|
|
73
|
+
.addCommand(updateCycle)
|
|
74
|
+
.addCommand(deleteCycle);
|
|
75
|
+
|
|
76
|
+
program.command("users").description("Manage users").addCommand(getCurrentUser);
|
|
77
|
+
|
|
78
|
+
program.commands.forEach((cmd) => {
|
|
79
|
+
cmd.requiredOption(
|
|
80
|
+
"--api-key <key>",
|
|
81
|
+
"Plane API key",
|
|
82
|
+
process.env.PLANE_API_KEY,
|
|
83
|
+
);
|
|
84
|
+
cmd.requiredOption(
|
|
85
|
+
"--api-base <url>",
|
|
86
|
+
"Plane API base",
|
|
87
|
+
process.env.PLANE_API_BASE || "api.plane.so",
|
|
88
|
+
);
|
|
89
|
+
cmd.requiredOption(
|
|
90
|
+
"--workspace-slug <slug>",
|
|
91
|
+
"Workspace slug",
|
|
92
|
+
process.env.PLANE_WORKSPACE_SLUG,
|
|
93
|
+
);
|
|
94
|
+
cmd.option("-j, --json", "Print in JSON format");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
program.parse();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
import { renderProject } from "./list.projects";
|
|
4
|
+
|
|
5
|
+
export const createProject = new Command("create")
|
|
6
|
+
.description("Create a new project")
|
|
7
|
+
.requiredOption("-n, --name <name>", "Project's name")
|
|
8
|
+
.requiredOption("-i, --identifier <identifier>", "Project' identifier")
|
|
9
|
+
.option("-d, --description [description]", "Project's description")
|
|
10
|
+
.action(async (__, cmd: Command) => {
|
|
11
|
+
if (cmd.parent == null) return;
|
|
12
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
13
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
14
|
+
const name = cmd.getOptionValue("name");
|
|
15
|
+
const identifier = cmd.getOptionValue("identifier");
|
|
16
|
+
const description = cmd.getOptionValue("description");
|
|
17
|
+
const { result, status } = await requestPlaneAPI({
|
|
18
|
+
apiBase,
|
|
19
|
+
apiKey,
|
|
20
|
+
endpoint: `workspaces/${workspaceSlug}/projects/`,
|
|
21
|
+
method: "POST",
|
|
22
|
+
body: {
|
|
23
|
+
name,
|
|
24
|
+
identifier,
|
|
25
|
+
description,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
if (json) console.log(JSON.stringify(result));
|
|
29
|
+
else {
|
|
30
|
+
if (status !== 201) console.table(result);
|
|
31
|
+
else console.table(renderProject(result));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { checkRequiredOptionsAndReturn, requestPlaneAPI } from "../utils";
|
|
3
|
+
|
|
4
|
+
export const deleteProject = new Command("delete")
|
|
5
|
+
.description("Delete a project")
|
|
6
|
+
.requiredOption("-p, --project-id <projectId>", "Project's ID")
|
|
7
|
+
.action(async (__, cmd: Command) => {
|
|
8
|
+
if (cmd.parent == null) return;
|
|
9
|
+
const { apiKey, apiBase, workspaceSlug, json } =
|
|
10
|
+
checkRequiredOptionsAndReturn(cmd);
|
|
11
|
+
const projectId = cmd.getOptionValue("projectId");
|
|
12
|
+
const { result, status } = await requestPlaneAPI({
|
|
13
|
+
apiBase,
|
|
14
|
+
apiKey,
|
|
15
|
+
endpoint: `workspaces/${workspaceSlug}/projects/${projectId}/`,
|
|
16
|
+
method: "DELETE",
|
|
17
|
+
});
|
|
18
|
+
if (json) console.log(JSON.stringify(result));
|
|
19
|
+
else {
|
|
20
|
+
if (status !== 204) console.table(result);
|
|
21
|
+
else console.table(result);
|
|
22
|
+
}
|
|
23
|
+
});
|