@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.
@@ -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
- Args.withDescription("Project identifier (e.g. PROJ, WEB, OPS)"),
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("list", { project: projectArg }, ({ project }) =>
15
- Effect.gen(function* () {
16
- const { id } = yield* resolveProject(project)
17
- const raw = yield* api.get(`projects/${id}/pages/`)
18
- const { results } = yield* decodeOrFail(PagesResponseSchema, raw)
19
- if (jsonMode) { yield* Console.log(JSON.stringify(results, null, 2)); return }
20
- if (xmlMode) { yield* Console.log(toXml(results)); return }
21
- if (results.length === 0) {
22
- yield* Console.log("No pages")
23
- return
24
- }
25
- const lines = results.map((p) => {
26
- const updated = (p.updated_at ?? p.created_at).slice(0, 10)
27
- return `${p.id} ${updated} ${p.name}`
28
- })
29
- yield* Console.log(lines.join("\n"))
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
- Command.withDescription(
33
- "List pages for a project. Shows page UUID, last updated date, and title.\n\nExample:\n plane pages list PROJ",
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
- Args.withDescription("Page UUID (from 'plane pages list')"),
41
- )
49
+ Args.withDescription("Page UUID (from 'plane pages list')"),
50
+ );
42
51
 
43
52
  export const pagesGet = Command.make(
44
- "get",
45
- { project: projectArg, pageId: pageIdArg },
46
- ({ project, pageId }) =>
47
- Effect.gen(function* () {
48
- const { id } = yield* resolveProject(project)
49
- const raw = yield* api.get(`projects/${id}/pages/${pageId}/`)
50
- const page = yield* decodeOrFail(PageSchema, raw)
51
- yield* Console.log(JSON.stringify(page, null, 2))
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
- Command.withDescription(
55
- "Print full JSON for a page including description_html.\n\nExample:\n plane pages get PROJ <page-id>",
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
- Command.withDescription(
63
- "Manage project pages (documentation). Subcommands: list, get\n\nExamples:\n plane pages list PROJ\n plane pages get PROJ <page-id>",
64
- ),
65
- Command.withSubcommands([pagesList, pagesGet]),
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
+ );
@@ -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
- Effect.gen(function* () {
9
- const raw = yield* api.get("projects/")
10
- const { results } = yield* decodeOrFail(ProjectsResponseSchema, raw)
11
- if (jsonMode) { yield* Console.log(JSON.stringify(results, null, 2)); return }
12
- if (xmlMode) { yield* Console.log(toXml(results)); return }
13
- const lines = results.map(
14
- (p) => `${p.identifier.padEnd(6)} ${p.id} ${p.name}`,
15
- )
16
- yield* Console.log(lines.join("\n"))
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
- Command.withDescription(
20
- "List all projects in the workspace. The IDENTIFIER column is what you pass to other commands (e.g. 'plane issues list PROJ').",
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
- Command.withDescription("Manage projects."),
26
- Command.withSubcommands([projectsList]),
27
- )
31
+ Command.withDescription("Manage projects."),
32
+ Command.withSubcommands([projectsList]),
33
+ );
@@ -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
- Args.withDescription("Project identifier (e.g. PROJ, WEB, OPS)"),
10
- )
9
+ Args.withDescription("Project identifier (e.g. PROJ, WEB, OPS)"),
10
+ );
11
11
 
12
12
  export const statesList = Command.make(
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) { yield* Console.log(JSON.stringify(results, null, 2)); return }
21
- if (xmlMode) { yield* Console.log(toXml(results)); return }
22
- const lines = results.map(
23
- (s) => `${s.id} ${s.group.padEnd(12)} ${s.name}`,
24
- )
25
- yield* Console.log(lines.join("\n"))
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
- Command.withSubcommands([statesList]),
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
- 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
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
- 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
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
- results: Schema.Array(StateSchema),
25
- })
24
+ results: Schema.Array(StateSchema),
25
+ });
26
26
 
27
27
  export const IssuesResponseSchema = Schema.Struct({
28
- results: Schema.Array(IssueSchema),
29
- })
28
+ results: Schema.Array(IssueSchema),
29
+ });
30
30
 
31
31
  export const LabelSchema = Schema.Struct({
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
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
- results: Schema.Array(LabelSchema),
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
- id: Schema.String,
46
- display_name: Schema.String,
47
- email: Schema.optional(Schema.NullOr(Schema.String)),
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
- 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
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
- results: Schema.Array(CycleSchema),
64
- })
63
+ results: Schema.Array(CycleSchema),
64
+ });
65
65
 
66
66
  export const ProjectSchema = Schema.Struct({
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
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
- results: Schema.Array(ProjectSchema),
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
- 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
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
- results: Schema.Array(ActivitySchema),
97
- })
96
+ results: Schema.Array(ActivitySchema),
97
+ });
98
98
 
99
99
  export const IssueLinkSchema = Schema.Struct({
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
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
- results: Schema.Array(IssueLinkSchema),
109
- })
108
+ results: Schema.Array(IssueLinkSchema),
109
+ });
110
110
 
111
111
  export const ModuleSchema = Schema.Struct({
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
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
- results: Schema.Array(ModuleSchema),
121
- })
120
+ results: Schema.Array(ModuleSchema),
121
+ });
122
122
 
123
123
  export const ModuleIssueSchema = Schema.Struct({
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
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
- results: Schema.Array(ModuleIssueSchema),
138
- })
137
+ results: Schema.Array(ModuleIssueSchema),
138
+ });
139
139
 
140
140
  export const WorklogSchema = Schema.Struct({
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
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
- results: Schema.Array(WorklogSchema),
153
- })
152
+ results: Schema.Array(WorklogSchema),
153
+ });
154
154
 
155
155
  export const IntakeIssueSchema = Schema.Struct({
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
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
- results: Schema.Array(IntakeIssueSchema),
173
- })
172
+ results: Schema.Array(IntakeIssueSchema),
173
+ });
174
174
 
175
175
  export const PageSchema = Schema.Struct({
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
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
- results: Schema.Array(PageSchema),
186
- })
185
+ results: Schema.Array(PageSchema),
186
+ });
187
187
 
188
188
  export const CommentSchema = Schema.Struct({
189
- id: Schema.String,
190
- comment_html: Schema.optional(Schema.String),
191
- actor_detail: Schema.optional(
192
- Schema.Struct({ display_name: Schema.String }),
193
- ),
194
- created_at: Schema.String,
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
- results: Schema.Array(CommentSchema),
200
- })
197
+ results: Schema.Array(CommentSchema),
198
+ });
201
199
 
202
200
  export const CycleIssueSchema = Schema.Struct({
203
- id: Schema.String,
204
- issue: Schema.String,
205
- issue_detail: Schema.optional(
206
- Schema.Struct({
207
- id: Schema.String,
208
- sequence_id: Schema.Number,
209
- name: Schema.String,
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
- results: Schema.Array(CycleIssueSchema),
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, "&amp;")
6
+ .replace(/</g, "&lt;")
7
+ .replace(/>/g, "&gt;");
8
+ }
2
9
 
3
10
  export function formatIssue(issue: Issue, projKey: string): string {
4
- const state = issue.state as State | string
5
- const stateName = typeof state === "object" ? state.name : "?"
6
- const stateGroup = typeof state === "object" ? state.group : "?"
7
- const seqPad = String(issue.sequence_id).padStart(3, " ")
8
- const groupPad = stateGroup.padEnd(10, " ")
9
- const namePad = stateName.padEnd(12, " ")
10
- return `${projKey}-${seqPad} [${groupPad}] ${namePad} ${issue.name}`
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
  }