@aaronshaf/plane 0.1.3 → 0.1.5
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/package.json +1 -1
- package/scripts/check-coverage.ts +2 -2
- package/src/api.ts +67 -59
- package/src/app.ts +78 -0
- package/src/bin.ts +6 -71
- package/src/commands/cycles.ts +104 -85
- package/src/commands/init.ts +57 -55
- package/src/commands/intake.ts +82 -65
- package/src/commands/issue.ts +418 -314
- package/src/commands/issues.ts +51 -43
- package/src/commands/labels.ts +52 -43
- package/src/commands/members.ts +25 -19
- package/src/commands/modules.ts +136 -99
- package/src/commands/pages.ts +58 -49
- package/src/commands/projects.ts +28 -22
- package/src/commands/states.ts +31 -25
- package/src/config.ts +152 -154
- package/src/format.ts +15 -8
- package/src/output.ts +28 -28
- package/src/resolve.ts +66 -53
- package/tests/api.test.ts +178 -155
- package/tests/cycles-extended.test.ts +205 -162
- package/tests/format.test.ts +72 -54
- package/tests/helpers/mock-api.ts +16 -14
- package/tests/intake.test.ts +173 -139
- package/tests/issue-activity.test.ts +191 -158
- package/tests/issue-commands.test.ts +587 -304
- package/tests/issue-comments-worklogs.test.ts +337 -265
- package/tests/issue-links.test.ts +229 -193
- package/tests/modules.test.ts +283 -239
- package/tests/new-schemas.test.ts +203 -183
- package/tests/new-schemas2.test.ts +195 -183
- package/tests/output.test.ts +66 -64
- package/tests/pages.test.ts +122 -108
- package/tests/resolve.test.ts +186 -156
- package/tests/schemas.test.ts +215 -177
package/src/commands/pages.ts
CHANGED
|
@@ -1,66 +1,75 @@
|
|
|
1
|
-
import { Command, Args } from "@effect/cli"
|
|
2
|
-
import { Console, Effect } from "effect"
|
|
3
|
-
import { api, decodeOrFail } from "../api.js"
|
|
4
|
-
import { PagesResponseSchema, PageSchema } from "../config.js"
|
|
5
|
-
import { resolveProject } from "../resolve.js"
|
|
6
|
-
import { jsonMode, xmlMode, toXml } from "../output.js"
|
|
1
|
+
import { Command, Args } from "@effect/cli";
|
|
2
|
+
import { Console, Effect } from "effect";
|
|
3
|
+
import { api, decodeOrFail } from "../api.js";
|
|
4
|
+
import { PagesResponseSchema, PageSchema } from "../config.js";
|
|
5
|
+
import { resolveProject } from "../resolve.js";
|
|
6
|
+
import { jsonMode, xmlMode, toXml } from "../output.js";
|
|
7
7
|
|
|
8
8
|
const projectArg = Args.text({ name: "project" }).pipe(
|
|
9
|
-
|
|
10
|
-
)
|
|
9
|
+
Args.withDescription("Project identifier (e.g. PROJ, WEB, OPS)"),
|
|
10
|
+
);
|
|
11
11
|
|
|
12
12
|
// --- pages list ---
|
|
13
13
|
|
|
14
|
-
export const pagesList = Command.make(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
export const pagesList = Command.make(
|
|
15
|
+
"list",
|
|
16
|
+
{ project: projectArg },
|
|
17
|
+
({ project }) =>
|
|
18
|
+
Effect.gen(function* () {
|
|
19
|
+
const { id } = yield* resolveProject(project);
|
|
20
|
+
const raw = yield* api.get(`projects/${id}/pages/`);
|
|
21
|
+
const { results } = yield* decodeOrFail(PagesResponseSchema, raw);
|
|
22
|
+
if (jsonMode) {
|
|
23
|
+
yield* Console.log(JSON.stringify(results, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (xmlMode) {
|
|
27
|
+
yield* Console.log(toXml(results));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (results.length === 0) {
|
|
31
|
+
yield* Console.log("No pages");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const lines = results.map((p) => {
|
|
35
|
+
const updated = (p.updated_at ?? p.created_at).slice(0, 10);
|
|
36
|
+
return `${p.id} ${updated} ${p.name}`;
|
|
37
|
+
});
|
|
38
|
+
yield* Console.log(lines.join("\n"));
|
|
39
|
+
}),
|
|
31
40
|
).pipe(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
41
|
+
Command.withDescription(
|
|
42
|
+
"List pages for a project. Shows page UUID, last updated date, and title.\n\nExample:\n plane pages list PROJ",
|
|
43
|
+
),
|
|
44
|
+
);
|
|
36
45
|
|
|
37
46
|
// --- pages get ---
|
|
38
47
|
|
|
39
48
|
const pageIdArg = Args.text({ name: "page-id" }).pipe(
|
|
40
|
-
|
|
41
|
-
)
|
|
49
|
+
Args.withDescription("Page UUID (from 'plane pages list')"),
|
|
50
|
+
);
|
|
42
51
|
|
|
43
52
|
export const pagesGet = Command.make(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
"get",
|
|
54
|
+
{ project: projectArg, pageId: pageIdArg },
|
|
55
|
+
({ project, pageId }) =>
|
|
56
|
+
Effect.gen(function* () {
|
|
57
|
+
const { id } = yield* resolveProject(project);
|
|
58
|
+
const raw = yield* api.get(`projects/${id}/pages/${pageId}/`);
|
|
59
|
+
const page = yield* decodeOrFail(PageSchema, raw);
|
|
60
|
+
yield* Console.log(JSON.stringify(page, null, 2));
|
|
61
|
+
}),
|
|
53
62
|
).pipe(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
63
|
+
Command.withDescription(
|
|
64
|
+
"Print full JSON for a page including description_html.\n\nExample:\n plane pages get PROJ <page-id>",
|
|
65
|
+
),
|
|
66
|
+
);
|
|
58
67
|
|
|
59
68
|
// --- pages (parent) ---
|
|
60
69
|
|
|
61
70
|
export const pages = Command.make("pages").pipe(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
71
|
+
Command.withDescription(
|
|
72
|
+
"Manage project pages (documentation). Subcommands: list, get\n\nExamples:\n plane pages list PROJ\n plane pages get PROJ <page-id>",
|
|
73
|
+
),
|
|
74
|
+
Command.withSubcommands([pagesList, pagesGet]),
|
|
75
|
+
);
|
package/src/commands/projects.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
|
-
import { Command } from "@effect/cli"
|
|
2
|
-
import { Console, Effect } from "effect"
|
|
3
|
-
import { api, decodeOrFail } from "../api.js"
|
|
4
|
-
import { ProjectsResponseSchema } from "../config.js"
|
|
5
|
-
import { jsonMode, xmlMode, toXml } from "../output.js"
|
|
1
|
+
import { Command } from "@effect/cli";
|
|
2
|
+
import { Console, Effect } from "effect";
|
|
3
|
+
import { api, decodeOrFail } from "../api.js";
|
|
4
|
+
import { ProjectsResponseSchema } from "../config.js";
|
|
5
|
+
import { jsonMode, xmlMode, toXml } from "../output.js";
|
|
6
6
|
|
|
7
7
|
export const projectsList = Command.make("list", {}, () =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
Effect.gen(function* () {
|
|
9
|
+
const raw = yield* api.get("projects/");
|
|
10
|
+
const { results } = yield* decodeOrFail(ProjectsResponseSchema, raw);
|
|
11
|
+
if (jsonMode) {
|
|
12
|
+
yield* Console.log(JSON.stringify(results, null, 2));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (xmlMode) {
|
|
16
|
+
yield* Console.log(toXml(results));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const lines = results.map(
|
|
20
|
+
(p) => `${p.identifier.padEnd(6)} ${p.id} ${p.name}`,
|
|
21
|
+
);
|
|
22
|
+
yield* Console.log(lines.join("\n"));
|
|
23
|
+
}),
|
|
18
24
|
).pipe(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
)
|
|
25
|
+
Command.withDescription(
|
|
26
|
+
"List all projects in the workspace. The IDENTIFIER column is what you pass to other commands (e.g. 'plane issues list PROJ').",
|
|
27
|
+
),
|
|
28
|
+
);
|
|
23
29
|
|
|
24
30
|
export const projects = Command.make("projects").pipe(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
31
|
+
Command.withDescription("Manage projects."),
|
|
32
|
+
Command.withSubcommands([projectsList]),
|
|
33
|
+
);
|
package/src/commands/states.ts
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
|
-
import { Command, Options, Args } from "@effect/cli"
|
|
2
|
-
import { Console, Effect } from "effect"
|
|
3
|
-
import { api, decodeOrFail } from "../api.js"
|
|
4
|
-
import { StatesResponseSchema } from "../config.js"
|
|
5
|
-
import { resolveProject } from "../resolve.js"
|
|
6
|
-
import { jsonMode, xmlMode, toXml } from "../output.js"
|
|
1
|
+
import { Command, Options, Args } from "@effect/cli";
|
|
2
|
+
import { Console, Effect } from "effect";
|
|
3
|
+
import { api, decodeOrFail } from "../api.js";
|
|
4
|
+
import { StatesResponseSchema } from "../config.js";
|
|
5
|
+
import { resolveProject } from "../resolve.js";
|
|
6
|
+
import { jsonMode, xmlMode, toXml } from "../output.js";
|
|
7
7
|
|
|
8
8
|
const projectArg = Args.text({ name: "project" }).pipe(
|
|
9
|
-
|
|
10
|
-
)
|
|
9
|
+
Args.withDescription("Project identifier (e.g. PROJ, WEB, OPS)"),
|
|
10
|
+
);
|
|
11
11
|
|
|
12
12
|
export const statesList = Command.make(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
"list",
|
|
14
|
+
{ project: projectArg },
|
|
15
|
+
({ project }) =>
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const { id } = yield* resolveProject(project);
|
|
18
|
+
const raw = yield* api.get(`projects/${id}/states/`);
|
|
19
|
+
const { results } = yield* decodeOrFail(StatesResponseSchema, raw);
|
|
20
|
+
if (jsonMode) {
|
|
21
|
+
yield* Console.log(JSON.stringify(results, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (xmlMode) {
|
|
25
|
+
yield* Console.log(toXml(results));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const lines = results.map(
|
|
29
|
+
(s) => `${s.id} ${s.group.padEnd(12)} ${s.name}`,
|
|
30
|
+
);
|
|
31
|
+
yield* Console.log(lines.join("\n"));
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
28
34
|
|
|
29
35
|
export const states = Command.make("states").pipe(
|
|
30
|
-
|
|
31
|
-
)
|
|
36
|
+
Command.withSubcommands([statesList]),
|
|
37
|
+
);
|
package/src/config.ts
CHANGED
|
@@ -1,217 +1,215 @@
|
|
|
1
|
-
import { Schema } from "effect"
|
|
1
|
+
import { Schema } from "effect";
|
|
2
2
|
|
|
3
3
|
// --- Schemas ---
|
|
4
4
|
|
|
5
5
|
export const StateSchema = Schema.Struct({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
})
|
|
11
|
-
export type State = typeof StateSchema.Type
|
|
6
|
+
id: Schema.String,
|
|
7
|
+
name: Schema.String,
|
|
8
|
+
group: Schema.String,
|
|
9
|
+
color: Schema.optional(Schema.String),
|
|
10
|
+
});
|
|
11
|
+
export type State = typeof StateSchema.Type;
|
|
12
12
|
|
|
13
13
|
export const IssueSchema = Schema.Struct({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
21
|
-
export type Issue = typeof IssueSchema.Type
|
|
14
|
+
id: Schema.String,
|
|
15
|
+
sequence_id: Schema.Number,
|
|
16
|
+
name: Schema.String,
|
|
17
|
+
priority: Schema.String,
|
|
18
|
+
state: Schema.Union(Schema.String, StateSchema),
|
|
19
|
+
description_html: Schema.optional(Schema.NullOr(Schema.String)),
|
|
20
|
+
});
|
|
21
|
+
export type Issue = typeof IssueSchema.Type;
|
|
22
22
|
|
|
23
23
|
export const StatesResponseSchema = Schema.Struct({
|
|
24
|
-
|
|
25
|
-
})
|
|
24
|
+
results: Schema.Array(StateSchema),
|
|
25
|
+
});
|
|
26
26
|
|
|
27
27
|
export const IssuesResponseSchema = Schema.Struct({
|
|
28
|
-
|
|
29
|
-
})
|
|
28
|
+
results: Schema.Array(IssueSchema),
|
|
29
|
+
});
|
|
30
30
|
|
|
31
31
|
export const LabelSchema = Schema.Struct({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
})
|
|
37
|
-
export type Label = typeof LabelSchema.Type
|
|
32
|
+
id: Schema.String,
|
|
33
|
+
name: Schema.String,
|
|
34
|
+
color: Schema.optional(Schema.NullOr(Schema.String)),
|
|
35
|
+
parent: Schema.optional(Schema.NullOr(Schema.String)),
|
|
36
|
+
});
|
|
37
|
+
export type Label = typeof LabelSchema.Type;
|
|
38
38
|
|
|
39
39
|
export const LabelsResponseSchema = Schema.Struct({
|
|
40
|
-
|
|
41
|
-
})
|
|
40
|
+
results: Schema.Array(LabelSchema),
|
|
41
|
+
});
|
|
42
42
|
|
|
43
43
|
// Members endpoint returns a flat array (no results wrapper)
|
|
44
44
|
export const MemberSchema = Schema.Struct({
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
})
|
|
49
|
-
export type Member = typeof MemberSchema.Type
|
|
45
|
+
id: Schema.String,
|
|
46
|
+
display_name: Schema.String,
|
|
47
|
+
email: Schema.optional(Schema.NullOr(Schema.String)),
|
|
48
|
+
});
|
|
49
|
+
export type Member = typeof MemberSchema.Type;
|
|
50
50
|
|
|
51
|
-
export const MembersResponseSchema = Schema.Array(MemberSchema)
|
|
51
|
+
export const MembersResponseSchema = Schema.Array(MemberSchema);
|
|
52
52
|
|
|
53
53
|
export const CycleSchema = Schema.Struct({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
})
|
|
60
|
-
export type Cycle = typeof CycleSchema.Type
|
|
54
|
+
id: Schema.String,
|
|
55
|
+
name: Schema.String,
|
|
56
|
+
status: Schema.optional(Schema.String),
|
|
57
|
+
start_date: Schema.optional(Schema.NullOr(Schema.String)),
|
|
58
|
+
end_date: Schema.optional(Schema.NullOr(Schema.String)),
|
|
59
|
+
});
|
|
60
|
+
export type Cycle = typeof CycleSchema.Type;
|
|
61
61
|
|
|
62
62
|
export const CyclesResponseSchema = Schema.Struct({
|
|
63
|
-
|
|
64
|
-
})
|
|
63
|
+
results: Schema.Array(CycleSchema),
|
|
64
|
+
});
|
|
65
65
|
|
|
66
66
|
export const ProjectSchema = Schema.Struct({
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})
|
|
72
|
-
export type Project = typeof ProjectSchema.Type
|
|
67
|
+
id: Schema.String,
|
|
68
|
+
identifier: Schema.String,
|
|
69
|
+
name: Schema.String,
|
|
70
|
+
description: Schema.optional(Schema.NullOr(Schema.String)),
|
|
71
|
+
});
|
|
72
|
+
export type Project = typeof ProjectSchema.Type;
|
|
73
73
|
|
|
74
74
|
export const ProjectsResponseSchema = Schema.Struct({
|
|
75
|
-
|
|
76
|
-
})
|
|
75
|
+
results: Schema.Array(ProjectSchema),
|
|
76
|
+
});
|
|
77
77
|
|
|
78
|
-
export const ProjectsFlatResponseSchema = Schema.Array(ProjectSchema)
|
|
78
|
+
export const ProjectsFlatResponseSchema = Schema.Array(ProjectSchema);
|
|
79
79
|
|
|
80
80
|
export const ActivitySchema = Schema.Struct({
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
})
|
|
93
|
-
export type Activity = typeof ActivitySchema.Type
|
|
81
|
+
id: Schema.String,
|
|
82
|
+
actor_detail: Schema.optional(
|
|
83
|
+
Schema.Struct({
|
|
84
|
+
display_name: Schema.String,
|
|
85
|
+
}),
|
|
86
|
+
),
|
|
87
|
+
field: Schema.optional(Schema.NullOr(Schema.String)),
|
|
88
|
+
old_value: Schema.optional(Schema.NullOr(Schema.String)),
|
|
89
|
+
new_value: Schema.optional(Schema.NullOr(Schema.String)),
|
|
90
|
+
verb: Schema.optional(Schema.String),
|
|
91
|
+
created_at: Schema.String,
|
|
92
|
+
});
|
|
93
|
+
export type Activity = typeof ActivitySchema.Type;
|
|
94
94
|
|
|
95
95
|
export const ActivitiesResponseSchema = Schema.Struct({
|
|
96
|
-
|
|
97
|
-
})
|
|
96
|
+
results: Schema.Array(ActivitySchema),
|
|
97
|
+
});
|
|
98
98
|
|
|
99
99
|
export const IssueLinkSchema = Schema.Struct({
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
})
|
|
105
|
-
export type IssueLink = typeof IssueLinkSchema.Type
|
|
100
|
+
id: Schema.String,
|
|
101
|
+
title: Schema.optional(Schema.NullOr(Schema.String)),
|
|
102
|
+
url: Schema.String,
|
|
103
|
+
created_at: Schema.String,
|
|
104
|
+
});
|
|
105
|
+
export type IssueLink = typeof IssueLinkSchema.Type;
|
|
106
106
|
|
|
107
107
|
export const IssueLinksResponseSchema = Schema.Struct({
|
|
108
|
-
|
|
109
|
-
})
|
|
108
|
+
results: Schema.Array(IssueLinkSchema),
|
|
109
|
+
});
|
|
110
110
|
|
|
111
111
|
export const ModuleSchema = Schema.Struct({
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
})
|
|
117
|
-
export type Module = typeof ModuleSchema.Type
|
|
112
|
+
id: Schema.String,
|
|
113
|
+
name: Schema.String,
|
|
114
|
+
status: Schema.optional(Schema.String),
|
|
115
|
+
description: Schema.optional(Schema.NullOr(Schema.String)),
|
|
116
|
+
});
|
|
117
|
+
export type Module = typeof ModuleSchema.Type;
|
|
118
118
|
|
|
119
119
|
export const ModulesResponseSchema = Schema.Struct({
|
|
120
|
-
|
|
121
|
-
})
|
|
120
|
+
results: Schema.Array(ModuleSchema),
|
|
121
|
+
});
|
|
122
122
|
|
|
123
123
|
export const ModuleIssueSchema = Schema.Struct({
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
})
|
|
134
|
-
export type ModuleIssue = typeof ModuleIssueSchema.Type
|
|
124
|
+
id: Schema.String,
|
|
125
|
+
issue: Schema.String,
|
|
126
|
+
issue_detail: Schema.optional(
|
|
127
|
+
Schema.Struct({
|
|
128
|
+
id: Schema.String,
|
|
129
|
+
sequence_id: Schema.Number,
|
|
130
|
+
name: Schema.String,
|
|
131
|
+
}),
|
|
132
|
+
),
|
|
133
|
+
});
|
|
134
|
+
export type ModuleIssue = typeof ModuleIssueSchema.Type;
|
|
135
135
|
|
|
136
136
|
export const ModuleIssuesResponseSchema = Schema.Struct({
|
|
137
|
-
|
|
138
|
-
})
|
|
137
|
+
results: Schema.Array(ModuleIssueSchema),
|
|
138
|
+
});
|
|
139
139
|
|
|
140
140
|
export const WorklogSchema = Schema.Struct({
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})
|
|
149
|
-
export type Worklog = typeof WorklogSchema.Type
|
|
141
|
+
id: Schema.String,
|
|
142
|
+
description: Schema.optional(Schema.NullOr(Schema.String)),
|
|
143
|
+
duration: Schema.Number,
|
|
144
|
+
logged_by_detail: Schema.optional(
|
|
145
|
+
Schema.Struct({ display_name: Schema.String }),
|
|
146
|
+
),
|
|
147
|
+
created_at: Schema.String,
|
|
148
|
+
});
|
|
149
|
+
export type Worklog = typeof WorklogSchema.Type;
|
|
150
150
|
|
|
151
151
|
export const WorklogsResponseSchema = Schema.Struct({
|
|
152
|
-
|
|
153
|
-
})
|
|
152
|
+
results: Schema.Array(WorklogSchema),
|
|
153
|
+
});
|
|
154
154
|
|
|
155
155
|
export const IntakeIssueSchema = Schema.Struct({
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
})
|
|
169
|
-
export type IntakeIssue = typeof IntakeIssueSchema.Type
|
|
156
|
+
id: Schema.String,
|
|
157
|
+
issue: Schema.optional(Schema.String),
|
|
158
|
+
issue_detail: Schema.optional(
|
|
159
|
+
Schema.Struct({
|
|
160
|
+
id: Schema.String,
|
|
161
|
+
sequence_id: Schema.Number,
|
|
162
|
+
name: Schema.String,
|
|
163
|
+
priority: Schema.String,
|
|
164
|
+
}),
|
|
165
|
+
),
|
|
166
|
+
status: Schema.optional(Schema.Number),
|
|
167
|
+
created_at: Schema.String,
|
|
168
|
+
});
|
|
169
|
+
export type IntakeIssue = typeof IntakeIssueSchema.Type;
|
|
170
170
|
|
|
171
171
|
export const IntakeIssuesResponseSchema = Schema.Struct({
|
|
172
|
-
|
|
173
|
-
})
|
|
172
|
+
results: Schema.Array(IntakeIssueSchema),
|
|
173
|
+
});
|
|
174
174
|
|
|
175
175
|
export const PageSchema = Schema.Struct({
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
})
|
|
182
|
-
export type Page = typeof PageSchema.Type
|
|
176
|
+
id: Schema.String,
|
|
177
|
+
name: Schema.String,
|
|
178
|
+
description_html: Schema.optional(Schema.NullOr(Schema.String)),
|
|
179
|
+
created_at: Schema.String,
|
|
180
|
+
updated_at: Schema.optional(Schema.String),
|
|
181
|
+
});
|
|
182
|
+
export type Page = typeof PageSchema.Type;
|
|
183
183
|
|
|
184
184
|
export const PagesResponseSchema = Schema.Struct({
|
|
185
|
-
|
|
186
|
-
})
|
|
185
|
+
results: Schema.Array(PageSchema),
|
|
186
|
+
});
|
|
187
187
|
|
|
188
188
|
export const CommentSchema = Schema.Struct({
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
})
|
|
196
|
-
export type Comment = typeof CommentSchema.Type
|
|
189
|
+
id: Schema.String,
|
|
190
|
+
comment_html: Schema.optional(Schema.String),
|
|
191
|
+
actor_detail: Schema.optional(Schema.Struct({ display_name: Schema.String })),
|
|
192
|
+
created_at: Schema.String,
|
|
193
|
+
});
|
|
194
|
+
export type Comment = typeof CommentSchema.Type;
|
|
197
195
|
|
|
198
196
|
export const CommentsResponseSchema = Schema.Struct({
|
|
199
|
-
|
|
200
|
-
})
|
|
197
|
+
results: Schema.Array(CommentSchema),
|
|
198
|
+
});
|
|
201
199
|
|
|
202
200
|
export const CycleIssueSchema = Schema.Struct({
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
})
|
|
213
|
-
export type CycleIssue = typeof CycleIssueSchema.Type
|
|
201
|
+
id: Schema.String,
|
|
202
|
+
issue: Schema.String,
|
|
203
|
+
issue_detail: Schema.optional(
|
|
204
|
+
Schema.Struct({
|
|
205
|
+
id: Schema.String,
|
|
206
|
+
sequence_id: Schema.Number,
|
|
207
|
+
name: Schema.String,
|
|
208
|
+
}),
|
|
209
|
+
),
|
|
210
|
+
});
|
|
211
|
+
export type CycleIssue = typeof CycleIssueSchema.Type;
|
|
214
212
|
|
|
215
213
|
export const CycleIssuesResponseSchema = Schema.Struct({
|
|
216
|
-
|
|
217
|
-
})
|
|
214
|
+
results: Schema.Array(CycleIssueSchema),
|
|
215
|
+
});
|
package/src/format.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import type { Issue, State } from "./config.js"
|
|
1
|
+
import type { Issue, State } from "./config.js";
|
|
2
|
+
|
|
3
|
+
export function escapeHtmlText(text: string): string {
|
|
4
|
+
return text
|
|
5
|
+
.replace(/&/g, "&")
|
|
6
|
+
.replace(/</g, "<")
|
|
7
|
+
.replace(/>/g, ">");
|
|
8
|
+
}
|
|
2
9
|
|
|
3
10
|
export function formatIssue(issue: Issue, projKey: string): string {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
const state = issue.state as State | string;
|
|
12
|
+
const stateName = typeof state === "object" ? state.name : "?";
|
|
13
|
+
const stateGroup = typeof state === "object" ? state.group : "?";
|
|
14
|
+
const seqPad = String(issue.sequence_id).padStart(3, " ");
|
|
15
|
+
const groupPad = stateGroup.padEnd(10, " ");
|
|
16
|
+
const namePad = stateName.padEnd(12, " ");
|
|
17
|
+
return `${projKey}-${seqPad} [${groupPad}] ${namePad} ${issue.name}`;
|
|
11
18
|
}
|