runline 0.11.3 → 0.11.4
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/plugins/googleDocs/src/documents.js +91 -0
- package/dist/plugins/googleDocs/src/formatting.js +126 -0
- package/dist/plugins/googleDocs/src/images.js +66 -0
- package/dist/plugins/googleDocs/src/index.js +45 -1008
- package/dist/plugins/googleDocs/src/shared.js +110 -0
- package/dist/plugins/googleDocs/src/structure.js +392 -0
- package/dist/plugins/googleDocs/src/tables.js +390 -0
- package/dist/plugins/googleDocs/src/tabs.js +77 -0
- package/dist/plugins/googleDocs/src/text.js +313 -0
- package/dist/plugins/linear/src/attachments.js +36 -12
- package/dist/plugins/linear/src/comments.js +20 -8
- package/dist/plugins/linear/src/cycles.js +22 -8
- package/dist/plugins/linear/src/initiatives.js +59 -19
- package/dist/plugins/linear/src/issues.js +118 -40
- package/dist/plugins/linear/src/labels.js +31 -11
- package/dist/plugins/linear/src/organization.js +1 -1
- package/dist/plugins/linear/src/projects.js +171 -57
- package/dist/plugins/linear/src/shared.js +16 -5
- package/dist/plugins/linear/src/states.js +14 -6
- package/dist/plugins/linear/src/teams.js +35 -12
- package/dist/plugins/linear/src/users.js +7 -3
- package/dist/plugins/linear/src/views.js +29 -10
- package/dist/plugins/linear/src/webhooks.js +39 -13
- package/dist/plugins/salesforce/src/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { bindGetAction, bindListAction, gql, key, MILESTONE_FIELDS, PROJECT_FIELDS, PROJECT_UPDATE_FIELDS, requireUnscoped, } from "./shared.js";
|
|
3
3
|
export function registerProjectActions(rl) {
|
|
4
4
|
const listAction = bindListAction(rl);
|
|
5
5
|
const getAction = bindGetAction(rl);
|
|
@@ -9,26 +9,54 @@ export function registerProjectActions(rl) {
|
|
|
9
9
|
description: "Create a project. teamIds is required.",
|
|
10
10
|
inputSchema: t.Object({
|
|
11
11
|
name: t.String({ description: "The name of the project" }),
|
|
12
|
-
teamIds: t.Array(t.Unknown(), {
|
|
12
|
+
teamIds: t.Array(t.Unknown(), {
|
|
13
|
+
description: "The identifiers of the teams this project is associated with",
|
|
14
|
+
}),
|
|
13
15
|
description: t.Optional(t.String({ description: "The description for the project" })),
|
|
14
16
|
content: t.Optional(t.String({ description: "The project content as markdown" })),
|
|
15
17
|
icon: t.Optional(t.String({ description: "The icon of the project" })),
|
|
16
18
|
color: t.Optional(t.String({ description: "The color of the project (hex)" })),
|
|
17
|
-
priority: t.Optional(t.Number({
|
|
19
|
+
priority: t.Optional(t.Number({
|
|
20
|
+
description: "The priority of the project. 0=No priority, 1=Urgent, 2=High, 3=Medium, 4=Low",
|
|
21
|
+
})),
|
|
18
22
|
leadId: t.Optional(t.String({ description: "The identifier of the project lead" })),
|
|
19
|
-
memberIds: t.Optional(t.Array(t.Unknown(), {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
memberIds: t.Optional(t.Array(t.Unknown(), {
|
|
24
|
+
description: "The identifiers of the members of this project",
|
|
25
|
+
})),
|
|
26
|
+
startDate: t.Optional(t.String({
|
|
27
|
+
description: "The planned start date of the project (TimelessDate, YYYY-MM-DD)",
|
|
28
|
+
})),
|
|
29
|
+
startDateResolution: t.Optional(t.String({
|
|
30
|
+
description: "The resolution of the project's start date (DateResolutionType)",
|
|
31
|
+
})),
|
|
32
|
+
targetDate: t.Optional(t.String({
|
|
33
|
+
description: "The planned target date of the project (TimelessDate, YYYY-MM-DD)",
|
|
34
|
+
})),
|
|
35
|
+
targetDateResolution: t.Optional(t.String({
|
|
36
|
+
description: "The resolution of the project's estimated completion date (DateResolutionType)",
|
|
37
|
+
})),
|
|
24
38
|
statusId: t.Optional(t.String({ description: "The ID of the project status" })),
|
|
25
|
-
labelIds: t.Optional(t.Array(t.Unknown(), {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
labelIds: t.Optional(t.Array(t.Unknown(), {
|
|
40
|
+
description: "The identifiers of the project labels associated with this project",
|
|
41
|
+
})),
|
|
42
|
+
sortOrder: t.Optional(t.Number({
|
|
43
|
+
description: "The sort order for the project in shared views (Float)",
|
|
44
|
+
})),
|
|
45
|
+
templateId: t.Optional(t.String({
|
|
46
|
+
description: "The ID of a project template to apply when creating the project",
|
|
47
|
+
})),
|
|
48
|
+
useDefaultTemplate: t.Optional(t.Boolean({
|
|
49
|
+
description: "Apply the default project template of the first team provided. Ignored if templateId is set",
|
|
50
|
+
})),
|
|
51
|
+
convertedFromIssueId: t.Optional(t.String({
|
|
52
|
+
description: "The ID of the issue that was converted into this project",
|
|
53
|
+
})),
|
|
54
|
+
id: t.Optional(t.String({
|
|
55
|
+
description: "The identifier in UUID v4 format. If none is provided, the backend will generate one",
|
|
56
|
+
})),
|
|
57
|
+
slackChannelName: t.Optional(t.String({
|
|
58
|
+
description: "The full name for the Slack channel to create (including prefix). Creates and connects a Slack channel if provided",
|
|
59
|
+
})),
|
|
32
60
|
}),
|
|
33
61
|
async execute(input, ctx) {
|
|
34
62
|
requireUnscoped(ctx, "projects.*");
|
|
@@ -40,26 +68,52 @@ export function registerProjectActions(rl) {
|
|
|
40
68
|
rl.registerAction("project.update", {
|
|
41
69
|
description: "Update a project.",
|
|
42
70
|
inputSchema: t.Object({
|
|
43
|
-
id: t.String({
|
|
71
|
+
id: t.String({
|
|
72
|
+
description: "The identifier of the project to update (UUID or slug)",
|
|
73
|
+
}),
|
|
44
74
|
name: t.Optional(t.String({ description: "The name of the project" })),
|
|
45
75
|
description: t.Optional(t.String({ description: "The description for the project" })),
|
|
46
76
|
content: t.Optional(t.String({ description: "The project content as markdown" })),
|
|
47
77
|
icon: t.Optional(t.String({ description: "The icon of the project" })),
|
|
48
78
|
color: t.Optional(t.String({ description: "The color of the project (hex)" })),
|
|
49
|
-
priority: t.Optional(t.Number({
|
|
79
|
+
priority: t.Optional(t.Number({
|
|
80
|
+
description: "The priority of the project. 0=No, 1=Urgent, 2=High, 3=Medium, 4=Low",
|
|
81
|
+
})),
|
|
50
82
|
leadId: t.Optional(t.String({ description: "The identifier of the project lead" })),
|
|
51
|
-
memberIds: t.Optional(t.Array(t.Unknown(), {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
83
|
+
memberIds: t.Optional(t.Array(t.Unknown(), {
|
|
84
|
+
description: "The identifiers of the members of this project",
|
|
85
|
+
})),
|
|
86
|
+
startDate: t.Optional(t.String({
|
|
87
|
+
description: "The planned start date (TimelessDate, YYYY-MM-DD)",
|
|
88
|
+
})),
|
|
89
|
+
startDateResolution: t.Optional(t.String({
|
|
90
|
+
description: "The resolution of the project's start date (DateResolutionType)",
|
|
91
|
+
})),
|
|
92
|
+
targetDate: t.Optional(t.String({
|
|
93
|
+
description: "The planned target date (TimelessDate, YYYY-MM-DD)",
|
|
94
|
+
})),
|
|
95
|
+
targetDateResolution: t.Optional(t.String({
|
|
96
|
+
description: "The resolution of the project's estimated completion date (DateResolutionType)",
|
|
97
|
+
})),
|
|
56
98
|
statusId: t.Optional(t.String({ description: "The ID of the project status" })),
|
|
57
|
-
labelIds: t.Optional(t.Array(t.Unknown(), {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
99
|
+
labelIds: t.Optional(t.Array(t.Unknown(), {
|
|
100
|
+
description: "The identifiers of the project labels associated with this project",
|
|
101
|
+
})),
|
|
102
|
+
teamIds: t.Optional(t.Array(t.Unknown(), {
|
|
103
|
+
description: "The identifiers of the teams this project is associated with",
|
|
104
|
+
})),
|
|
105
|
+
sortOrder: t.Optional(t.Number({
|
|
106
|
+
description: "The sort order for the project in shared views (Float)",
|
|
107
|
+
})),
|
|
108
|
+
completedAt: t.Optional(t.String({
|
|
109
|
+
description: "The time at which the project was completed (DateTime)",
|
|
110
|
+
})),
|
|
111
|
+
canceledAt: t.Optional(t.String({
|
|
112
|
+
description: "The time at which the project was canceled (DateTime)",
|
|
113
|
+
})),
|
|
114
|
+
trashed: t.Optional(t.Boolean({
|
|
115
|
+
description: "Whether the project has been trashed. Set to true to trash, or null to restore",
|
|
116
|
+
})),
|
|
63
117
|
}),
|
|
64
118
|
async execute(input, ctx) {
|
|
65
119
|
requireUnscoped(ctx, "projects.*");
|
|
@@ -70,7 +124,9 @@ export function registerProjectActions(rl) {
|
|
|
70
124
|
});
|
|
71
125
|
rl.registerAction("project.delete", {
|
|
72
126
|
description: "Trash (soft-delete) a project. Restorable via project.unarchive.",
|
|
73
|
-
inputSchema: t.Object({
|
|
127
|
+
inputSchema: t.Object({
|
|
128
|
+
id: t.String({ description: "The identifier of the project to delete" }),
|
|
129
|
+
}),
|
|
74
130
|
async execute(input, ctx) {
|
|
75
131
|
requireUnscoped(ctx, "projects.*");
|
|
76
132
|
const data = await gql(key(ctx), `mutation($id: String!) { projectDelete(id: $id) { success } }`, { id: input.id });
|
|
@@ -79,7 +135,11 @@ export function registerProjectActions(rl) {
|
|
|
79
135
|
});
|
|
80
136
|
rl.registerAction("project.unarchive", {
|
|
81
137
|
description: "Restore a previously trashed or archived project.",
|
|
82
|
-
inputSchema: t.Object({
|
|
138
|
+
inputSchema: t.Object({
|
|
139
|
+
id: t.String({
|
|
140
|
+
description: "The identifier of the project to restore (UUID or slug)",
|
|
141
|
+
}),
|
|
142
|
+
}),
|
|
83
143
|
async execute(input, ctx) {
|
|
84
144
|
requireUnscoped(ctx, "projects.*");
|
|
85
145
|
const data = await gql(key(ctx), `mutation($id: String!) { projectUnarchive(id: $id) { success } }`, { id: input.id });
|
|
@@ -90,8 +150,12 @@ export function registerProjectActions(rl) {
|
|
|
90
150
|
description: "Search projects by text. Rate-limited to 30 req/min.",
|
|
91
151
|
inputSchema: t.Object({
|
|
92
152
|
term: t.String({ description: "Search string to look for" }),
|
|
93
|
-
limit: t.Optional(t.Number({
|
|
94
|
-
|
|
153
|
+
limit: t.Optional(t.Number({
|
|
154
|
+
description: "Max results (forward pagination, default 50)",
|
|
155
|
+
})),
|
|
156
|
+
includeComments: t.Optional(t.Boolean({
|
|
157
|
+
description: "Should associated comments be searched (default false)",
|
|
158
|
+
})),
|
|
95
159
|
teamId: t.Optional(t.String({ description: "UUID of a team to boost in search results" })),
|
|
96
160
|
}),
|
|
97
161
|
async execute(input, ctx) {
|
|
@@ -117,39 +181,65 @@ export function registerProjectActions(rl) {
|
|
|
117
181
|
rl.registerAction("milestone.create", {
|
|
118
182
|
description: "Create a project milestone.",
|
|
119
183
|
inputSchema: t.Object({
|
|
120
|
-
projectId: t.String({
|
|
184
|
+
projectId: t.String({
|
|
185
|
+
description: "Related project for the project milestone",
|
|
186
|
+
}),
|
|
121
187
|
name: t.String({ description: "The name of the project milestone" }),
|
|
122
|
-
description: t.Optional(t.String({
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
188
|
+
description: t.Optional(t.String({
|
|
189
|
+
description: "The description of the project milestone in markdown format",
|
|
190
|
+
})),
|
|
191
|
+
targetDate: t.Optional(t.String({
|
|
192
|
+
description: "The planned target date of the project milestone (TimelessDate, YYYY-MM-DD)",
|
|
193
|
+
})),
|
|
194
|
+
sortOrder: t.Optional(t.Number({
|
|
195
|
+
description: "The sort order for the project milestone within a project (Float)",
|
|
196
|
+
})),
|
|
197
|
+
id: t.Optional(t.String({
|
|
198
|
+
description: "The identifier in UUID v4 format. If none is provided, the backend will generate one",
|
|
199
|
+
})),
|
|
126
200
|
}),
|
|
127
201
|
async execute(input, ctx) {
|
|
128
202
|
requireUnscoped(ctx, "projects.*");
|
|
129
203
|
const data = await gql(key(ctx), `mutation($input: ProjectMilestoneCreateInput!) { projectMilestoneCreate(input: $input) { success projectMilestone { ${MILESTONE_FIELDS} } } }`, { input: input });
|
|
130
|
-
return data.projectMilestoneCreate
|
|
204
|
+
return data.projectMilestoneCreate
|
|
205
|
+
?.projectMilestone;
|
|
131
206
|
},
|
|
132
207
|
});
|
|
133
208
|
rl.registerAction("milestone.update", {
|
|
134
209
|
description: "Update a project milestone.",
|
|
135
210
|
inputSchema: t.Object({
|
|
136
|
-
id: t.String({
|
|
211
|
+
id: t.String({
|
|
212
|
+
description: "The identifier of the project milestone to update",
|
|
213
|
+
}),
|
|
137
214
|
name: t.Optional(t.String({ description: "The name of the project milestone" })),
|
|
138
|
-
description: t.Optional(t.String({
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
215
|
+
description: t.Optional(t.String({
|
|
216
|
+
description: "The description of the project milestone in markdown format",
|
|
217
|
+
})),
|
|
218
|
+
targetDate: t.Optional(t.String({
|
|
219
|
+
description: "The planned target date (TimelessDate, YYYY-MM-DD)",
|
|
220
|
+
})),
|
|
221
|
+
projectId: t.Optional(t.String({
|
|
222
|
+
description: "Related project for the project milestone (move to another project)",
|
|
223
|
+
})),
|
|
224
|
+
sortOrder: t.Optional(t.Number({
|
|
225
|
+
description: "The sort order for the project milestone within a project (Float)",
|
|
226
|
+
})),
|
|
142
227
|
}),
|
|
143
228
|
async execute(input, ctx) {
|
|
144
229
|
requireUnscoped(ctx, "projects.*");
|
|
145
230
|
const { id, ...fields } = input;
|
|
146
231
|
const data = await gql(key(ctx), `mutation($id: String!, $input: ProjectMilestoneUpdateInput!) { projectMilestoneUpdate(id: $id, input: $input) { success projectMilestone { ${MILESTONE_FIELDS} } } }`, { id, input: fields });
|
|
147
|
-
return data.projectMilestoneUpdate
|
|
232
|
+
return data.projectMilestoneUpdate
|
|
233
|
+
?.projectMilestone;
|
|
148
234
|
},
|
|
149
235
|
});
|
|
150
236
|
rl.registerAction("milestone.delete", {
|
|
151
237
|
description: "Delete a project milestone.",
|
|
152
|
-
inputSchema: t.Object({
|
|
238
|
+
inputSchema: t.Object({
|
|
239
|
+
id: t.String({
|
|
240
|
+
description: "The identifier of the project milestone to delete",
|
|
241
|
+
}),
|
|
242
|
+
}),
|
|
153
243
|
async execute(input, ctx) {
|
|
154
244
|
requireUnscoped(ctx, "projects.*");
|
|
155
245
|
const data = await gql(key(ctx), `mutation($id: String!) { projectMilestoneDelete(id: $id) { success } }`, { id: input.id });
|
|
@@ -161,36 +251,60 @@ export function registerProjectActions(rl) {
|
|
|
161
251
|
rl.registerAction("projectUpdate.create", {
|
|
162
252
|
description: "Post a status update on a project.",
|
|
163
253
|
inputSchema: t.Object({
|
|
164
|
-
projectId: t.String({
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
254
|
+
projectId: t.String({
|
|
255
|
+
description: "The project to associate the project update with",
|
|
256
|
+
}),
|
|
257
|
+
body: t.Optional(t.String({
|
|
258
|
+
description: "The content of the project update in markdown format",
|
|
259
|
+
})),
|
|
260
|
+
health: t.Optional(t.String({
|
|
261
|
+
description: "The health of the project at the time of the update (ProjectUpdateHealthType: onTrack | atRisk | offTrack)",
|
|
262
|
+
})),
|
|
263
|
+
isDiffHidden: t.Optional(t.Boolean({
|
|
264
|
+
description: "Whether the diff between the current update and the previous one should be hidden",
|
|
265
|
+
})),
|
|
266
|
+
id: t.Optional(t.String({
|
|
267
|
+
description: "The identifier in UUID v4 format. If none is provided, the backend will generate one",
|
|
268
|
+
})),
|
|
169
269
|
}),
|
|
170
270
|
async execute(input, ctx) {
|
|
171
271
|
requireUnscoped(ctx, "projects.*");
|
|
172
272
|
const data = await gql(key(ctx), `mutation($input: ProjectUpdateCreateInput!) { projectUpdateCreate(input: $input) { success projectUpdate { ${PROJECT_UPDATE_FIELDS} } } }`, { input: input });
|
|
173
|
-
return data.projectUpdateCreate
|
|
273
|
+
return data.projectUpdateCreate
|
|
274
|
+
?.projectUpdate;
|
|
174
275
|
},
|
|
175
276
|
});
|
|
176
277
|
rl.registerAction("projectUpdate.update", {
|
|
177
278
|
description: "Update a project status update.",
|
|
178
279
|
inputSchema: t.Object({
|
|
179
|
-
id: t.String({
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
280
|
+
id: t.String({
|
|
281
|
+
description: "The identifier of the project update to update",
|
|
282
|
+
}),
|
|
283
|
+
body: t.Optional(t.String({
|
|
284
|
+
description: "The content of the project update in markdown format",
|
|
285
|
+
})),
|
|
286
|
+
health: t.Optional(t.String({
|
|
287
|
+
description: "The health of the project at the time of the update (ProjectUpdateHealthType: onTrack | atRisk | offTrack)",
|
|
288
|
+
})),
|
|
289
|
+
isDiffHidden: t.Optional(t.Boolean({
|
|
290
|
+
description: "Whether the diff between the current update and the previous one should be hidden",
|
|
291
|
+
})),
|
|
183
292
|
}),
|
|
184
293
|
async execute(input, ctx) {
|
|
185
294
|
requireUnscoped(ctx, "projects.*");
|
|
186
295
|
const { id, ...fields } = input;
|
|
187
296
|
const data = await gql(key(ctx), `mutation($id: String!, $input: ProjectUpdateUpdateInput!) { projectUpdateUpdate(id: $id, input: $input) { success projectUpdate { ${PROJECT_UPDATE_FIELDS} } } }`, { id, input: fields });
|
|
188
|
-
return data.projectUpdateUpdate
|
|
297
|
+
return data.projectUpdateUpdate
|
|
298
|
+
?.projectUpdate;
|
|
189
299
|
},
|
|
190
300
|
});
|
|
191
301
|
rl.registerAction("projectUpdate.archive", {
|
|
192
302
|
description: "Archive a project status update.",
|
|
193
|
-
inputSchema: t.Object({
|
|
303
|
+
inputSchema: t.Object({
|
|
304
|
+
id: t.String({
|
|
305
|
+
description: "The identifier of the project update to archive",
|
|
306
|
+
}),
|
|
307
|
+
}),
|
|
194
308
|
async execute(input, ctx) {
|
|
195
309
|
requireUnscoped(ctx, "projects.*");
|
|
196
310
|
const data = await gql(key(ctx), `mutation($id: String!) { projectUpdateArchive(id: $id) { success } }`, { id: input.id });
|
|
@@ -22,10 +22,16 @@ export function key(ctx) {
|
|
|
22
22
|
export function scopeLabelIds(ctx) {
|
|
23
23
|
const raw = ctx.connection.config.scopeLabelIds;
|
|
24
24
|
if (Array.isArray(raw))
|
|
25
|
-
return raw
|
|
25
|
+
return raw
|
|
26
|
+
.map(String)
|
|
27
|
+
.map((s) => s.trim())
|
|
28
|
+
.filter(Boolean);
|
|
26
29
|
if (typeof raw !== "string")
|
|
27
30
|
return [];
|
|
28
|
-
return raw
|
|
31
|
+
return raw
|
|
32
|
+
.split(",")
|
|
33
|
+
.map((s) => s.trim())
|
|
34
|
+
.filter(Boolean);
|
|
29
35
|
}
|
|
30
36
|
export function isScoped(ctx) {
|
|
31
37
|
return scopeLabelIds(ctx).length > 0;
|
|
@@ -44,7 +50,8 @@ export function issueHasScope(ctx, issue) {
|
|
|
44
50
|
if (ids.size === 0)
|
|
45
51
|
return true;
|
|
46
52
|
const labels = issue?.labels?.nodes;
|
|
47
|
-
return Array.isArray(labels) &&
|
|
53
|
+
return (Array.isArray(labels) &&
|
|
54
|
+
labels.some((label) => ids.has(String(label.id))));
|
|
48
55
|
}
|
|
49
56
|
export async function getIssueForScope(ctx, issueId) {
|
|
50
57
|
const data = await gql(key(ctx), `query($id: String!) { issue(id: $id) { id identifier labels { nodes { id name } } } }`, { id: issueId });
|
|
@@ -78,7 +85,9 @@ export function forbidScopeLabelRemoval(ctx, labelIds) {
|
|
|
78
85
|
const scoped = new Set(scopeLabelIds(ctx));
|
|
79
86
|
if (scoped.size === 0)
|
|
80
87
|
return;
|
|
81
|
-
const ids = Array.isArray(labelIds)
|
|
88
|
+
const ids = Array.isArray(labelIds)
|
|
89
|
+
? labelIds.map(String)
|
|
90
|
+
: [String(labelIds)];
|
|
82
91
|
if (ids.some((id) => scoped.has(id))) {
|
|
83
92
|
throw new Error("Cannot remove a required Linear scope label");
|
|
84
93
|
}
|
|
@@ -224,7 +233,9 @@ export function registerListAction(rl, name, description, rootField, filterTypeN
|
|
|
224
233
|
export function registerGetAction(rl, name, description, rootField, selection) {
|
|
225
234
|
rl.registerAction(name, {
|
|
226
235
|
description,
|
|
227
|
-
inputSchema: t.Object({
|
|
236
|
+
inputSchema: t.Object({
|
|
237
|
+
id: t.String({ description: "Identifier or slug" }),
|
|
238
|
+
}),
|
|
228
239
|
async execute(input, ctx) {
|
|
229
240
|
requireRootFieldAvailable(ctx, name, rootField);
|
|
230
241
|
const data = await gql(key(ctx), `query($id: String!) { ${rootField}(id: $id) { ${selection} } }`, { id: input.id });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { bindGetAction, bindListAction, gql, key, requireUnscoped, STATE_FIELDS, } from "./shared.js";
|
|
3
3
|
export function registerStateActions(rl) {
|
|
4
4
|
const listAction = bindListAction(rl);
|
|
5
5
|
const getAction = bindGetAction(rl);
|
|
@@ -10,16 +10,23 @@ export function registerStateActions(rl) {
|
|
|
10
10
|
inputSchema: t.Object({
|
|
11
11
|
teamId: t.String({ description: "The team associated with the state" }),
|
|
12
12
|
name: t.String({ description: "The name of the state" }),
|
|
13
|
-
type: t.String({
|
|
14
|
-
|
|
13
|
+
type: t.String({
|
|
14
|
+
description: "The workflow state type which categorizes the state. Valid values: backlog, unstarted, started, completed, canceled",
|
|
15
|
+
}),
|
|
16
|
+
color: t.String({
|
|
17
|
+
description: "The color of the state (hex, e.g. #6B7280)",
|
|
18
|
+
}),
|
|
15
19
|
description: t.Optional(t.String({ description: "The description of the state" })),
|
|
16
20
|
position: t.Optional(t.Number({ description: "The position of the state (Float)" })),
|
|
17
|
-
id: t.Optional(t.String({
|
|
21
|
+
id: t.Optional(t.String({
|
|
22
|
+
description: "The identifier in UUID v4 format. If none is provided, the backend will generate one",
|
|
23
|
+
})),
|
|
18
24
|
}),
|
|
19
25
|
async execute(input, ctx) {
|
|
20
26
|
requireUnscoped(ctx, "state.create");
|
|
21
27
|
const data = await gql(key(ctx), `mutation($input: WorkflowStateCreateInput!) { workflowStateCreate(input: $input) { success workflowState { ${STATE_FIELDS} } } }`, { input: input });
|
|
22
|
-
return data.workflowStateCreate
|
|
28
|
+
return data.workflowStateCreate
|
|
29
|
+
?.workflowState;
|
|
23
30
|
},
|
|
24
31
|
});
|
|
25
32
|
rl.registerAction("state.update", {
|
|
@@ -35,7 +42,8 @@ export function registerStateActions(rl) {
|
|
|
35
42
|
requireUnscoped(ctx, "state.update");
|
|
36
43
|
const { id, ...fields } = input;
|
|
37
44
|
const data = await gql(key(ctx), `mutation($id: String!, $input: WorkflowStateUpdateInput!) { workflowStateUpdate(id: $id, input: $input) { success workflowState { ${STATE_FIELDS} } } }`, { id, input: fields });
|
|
38
|
-
return data.workflowStateUpdate
|
|
45
|
+
return data.workflowStateUpdate
|
|
46
|
+
?.workflowState;
|
|
39
47
|
},
|
|
40
48
|
});
|
|
41
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { bindGetAction, bindListAction, gql, key, requireUnscoped, TEAM_FIELDS, USER_FIELDS, } from "./shared.js";
|
|
3
3
|
export function registerTeamActions(rl) {
|
|
4
4
|
const listAction = bindListAction(rl);
|
|
5
5
|
const getAction = bindGetAction(rl);
|
|
@@ -9,7 +9,9 @@ export function registerTeamActions(rl) {
|
|
|
9
9
|
description: "Create a team. Most settings have sensible defaults.",
|
|
10
10
|
inputSchema: t.Object({
|
|
11
11
|
name: t.String({ description: "The name of the team" }),
|
|
12
|
-
key: t.Optional(t.String({
|
|
12
|
+
key: t.Optional(t.String({
|
|
13
|
+
description: "The key of the team. If not given, the key will be generated based on the name",
|
|
14
|
+
})),
|
|
13
15
|
description: t.Optional(t.String({ description: "The description of the team" })),
|
|
14
16
|
icon: t.Optional(t.String({ description: "The icon of the team" })),
|
|
15
17
|
color: t.Optional(t.String({ description: "The color of the team (hex)" })),
|
|
@@ -17,19 +19,32 @@ export function registerTeamActions(rl) {
|
|
|
17
19
|
timezone: t.Optional(t.String({ description: "The timezone of the team" })),
|
|
18
20
|
cyclesEnabled: t.Optional(t.Boolean({ description: "Whether the team uses cycles" })),
|
|
19
21
|
cycleDuration: t.Optional(t.Number({ description: "The duration of each cycle in weeks (Int)" })),
|
|
20
|
-
cycleCooldownTime: t.Optional(t.Number({
|
|
21
|
-
|
|
22
|
+
cycleCooldownTime: t.Optional(t.Number({
|
|
23
|
+
description: "The cooldown time after each cycle in weeks (Int)",
|
|
24
|
+
})),
|
|
25
|
+
cycleStartDay: t.Optional(t.Number({
|
|
26
|
+
description: "The day of the week that a new cycle starts. 0=Sun..6=Sat (Float)",
|
|
27
|
+
})),
|
|
22
28
|
upcomingCycleCount: t.Optional(t.Number({ description: "How many upcoming cycles to create (Float)" })),
|
|
23
|
-
issueEstimationType: t.Optional(t.String({
|
|
24
|
-
|
|
29
|
+
issueEstimationType: t.Optional(t.String({
|
|
30
|
+
description: "The issue estimation type: notUsed | exponential | fibonacci | linear | tShirt",
|
|
31
|
+
})),
|
|
32
|
+
triageEnabled: t.Optional(t.Boolean({
|
|
33
|
+
description: "Whether triage mode is enabled for the team",
|
|
34
|
+
})),
|
|
25
35
|
parentId: t.Optional(t.String({ description: "The parent team ID (for sub-teams)" })),
|
|
26
|
-
id: t.Optional(t.String({
|
|
36
|
+
id: t.Optional(t.String({
|
|
37
|
+
description: "The identifier in UUID v4 format. If none is provided, the backend will generate one",
|
|
38
|
+
})),
|
|
27
39
|
copySettingsFromTeamId: t.Optional(t.String({ description: "The team id to copy settings from, if any" })),
|
|
28
40
|
}),
|
|
29
41
|
async execute(input, ctx) {
|
|
30
42
|
requireUnscoped(ctx, "team.create");
|
|
31
43
|
const { copySettingsFromTeamId, ...fields } = input;
|
|
32
|
-
const data = await gql(key(ctx), `mutation($input: TeamCreateInput!, $copySettingsFromTeamId: String) { teamCreate(input: $input, copySettingsFromTeamId: $copySettingsFromTeamId) { success team { ${TEAM_FIELDS} } } }`, {
|
|
44
|
+
const data = await gql(key(ctx), `mutation($input: TeamCreateInput!, $copySettingsFromTeamId: String) { teamCreate(input: $input, copySettingsFromTeamId: $copySettingsFromTeamId) { success team { ${TEAM_FIELDS} } } }`, {
|
|
45
|
+
input: fields,
|
|
46
|
+
copySettingsFromTeamId: copySettingsFromTeamId ?? null,
|
|
47
|
+
});
|
|
33
48
|
return data.teamCreate?.team;
|
|
34
49
|
},
|
|
35
50
|
});
|
|
@@ -46,11 +61,19 @@ export function registerTeamActions(rl) {
|
|
|
46
61
|
timezone: t.Optional(t.String({ description: "The timezone of the team" })),
|
|
47
62
|
cyclesEnabled: t.Optional(t.Boolean({ description: "Whether the team uses cycles" })),
|
|
48
63
|
cycleDuration: t.Optional(t.Number({ description: "The duration of each cycle in weeks (Int)" })),
|
|
49
|
-
cycleCooldownTime: t.Optional(t.Number({
|
|
50
|
-
|
|
64
|
+
cycleCooldownTime: t.Optional(t.Number({
|
|
65
|
+
description: "The cooldown time after each cycle in weeks (Int)",
|
|
66
|
+
})),
|
|
67
|
+
cycleStartDay: t.Optional(t.Number({
|
|
68
|
+
description: "The day of the week that a new cycle starts. 0=Sun..6=Sat (Float)",
|
|
69
|
+
})),
|
|
51
70
|
upcomingCycleCount: t.Optional(t.Number({ description: "How many upcoming cycles to create (Float)" })),
|
|
52
|
-
issueEstimationType: t.Optional(t.String({
|
|
53
|
-
|
|
71
|
+
issueEstimationType: t.Optional(t.String({
|
|
72
|
+
description: "The issue estimation type: notUsed | exponential | fibonacci | linear | tShirt",
|
|
73
|
+
})),
|
|
74
|
+
triageEnabled: t.Optional(t.Boolean({
|
|
75
|
+
description: "Whether triage mode is enabled for the team",
|
|
76
|
+
})),
|
|
54
77
|
}),
|
|
55
78
|
async execute(input, ctx) {
|
|
56
79
|
requireUnscoped(ctx, "team.update");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from "typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { bindGetAction, bindListAction, gql, key, requireUnscoped, USER_FIELDS, } from "./shared.js";
|
|
3
3
|
export function registerUserActions(rl) {
|
|
4
4
|
const listAction = bindListAction(rl);
|
|
5
5
|
const getAction = bindGetAction(rl);
|
|
@@ -16,7 +16,9 @@ export function registerUserActions(rl) {
|
|
|
16
16
|
rl.registerAction("user.update", {
|
|
17
17
|
description: "Update a user. Use id='me' to update the authenticated user.",
|
|
18
18
|
inputSchema: t.Object({
|
|
19
|
-
id: t.String({
|
|
19
|
+
id: t.String({
|
|
20
|
+
description: "The identifier of the user to update. Use 'me' to reference the currently authenticated user",
|
|
21
|
+
}),
|
|
20
22
|
name: t.Optional(t.String({ description: "The name of the user" })),
|
|
21
23
|
displayName: t.Optional(t.String({ description: "The display name of the user" })),
|
|
22
24
|
description: t.Optional(t.String({ description: "The user description or short bio" })),
|
|
@@ -25,7 +27,9 @@ export function registerUserActions(rl) {
|
|
|
25
27
|
title: t.Optional(t.String({ description: "The user's job title" })),
|
|
26
28
|
statusEmoji: t.Optional(t.String({ description: "The emoji part of the user status" })),
|
|
27
29
|
statusLabel: t.Optional(t.String({ description: "The label part of the user status" })),
|
|
28
|
-
statusUntilAt: t.Optional(t.String({
|
|
30
|
+
statusUntilAt: t.Optional(t.String({
|
|
31
|
+
description: "When the user status should be cleared (DateTime)",
|
|
32
|
+
})),
|
|
29
33
|
}),
|
|
30
34
|
async execute(input, ctx) {
|
|
31
35
|
requireUnscoped(ctx, "user.update");
|