@tool-bridge/server 0.1.1 → 0.3.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/dist/airtable-V6446SVY.js +792 -0
- package/dist/alt_text_generator_ai-HV7JZPDT.js +72 -0
- package/dist/amap-TTTVB6WS.js +755 -0
- package/dist/anthropic-JH3RA363.js +224 -0
- package/dist/apify-ETNN7ITU.js +262 -0
- package/dist/brave_search-3DDR2MMB.js +322 -0
- package/dist/chunk-CSJEZHQO.js +252 -0
- package/dist/chunk-JLTYA2B3.js +20121 -0
- package/dist/chunk-K7FVSFUX.js +333 -0
- package/dist/{chunk-MQEYFCJB.js → chunk-KGYJEEBI.js} +2770 -21574
- package/dist/circleci-MX3TX3HC.js +409 -0
- package/dist/clerk-MRPORVF4.js +1036 -0
- package/dist/cloudflare_dns-OWP7DD7L.js +605 -0
- package/dist/cohere-GPECP66S.js +197 -0
- package/dist/confluence-BN7LZ6BC.js +436 -0
- package/dist/convertapi-SBEOFOFQ.js +161 -0
- package/dist/currencyapi-P2YY7Y7P.js +306 -0
- package/dist/deepseek-MWB3NYIN.js +205 -0
- package/dist/docker_hub-3JSCIGQ3.js +946 -0
- package/dist/dropbox-RFIBDAXO.js +1308 -0
- package/dist/dub-YVP57ELQ.js +706 -0
- package/dist/e2b-NFSUHTZR.js +305 -0
- package/dist/exa-KTDY6IV3.js +360 -0
- package/dist/fal_ai-OCUENLNQ.js +405 -0
- package/dist/feishu-5CWBQ7E5.js +225 -0
- package/dist/feishu_custom_bot-ZJR22OK6.js +240 -0
- package/dist/figma-YULGANSA.js +798 -0
- package/dist/firehydrant-2V6YSYAP.js +573 -0
- package/dist/fixer-LTCDB3CJ.js +171 -0
- package/dist/fly-IXPKMAML.js +478 -0
- package/dist/front-KRFB4M5X.js +379 -0
- package/dist/geocodio-VVURKYHQ.js +236 -0
- package/dist/ghost-6J2RIOUB.js +341 -0
- package/dist/github-5Z6KQRYH.js +5410 -0
- package/dist/gmail-KU4NZ7VA.js +1894 -0
- package/dist/googlecalendar-X44DFFXG.js +2539 -0
- package/dist/googledocs-WSGLPKSF.js +1322 -0
- package/dist/grafana-4PKSSDXY.js +817 -0
- package/dist/graphhopper-DF65ZNGK.js +336 -0
- package/dist/index.d.ts +181 -2
- package/dist/index.js +2 -1
- package/dist/ip2proxy-UCAQ5P2J.js +118 -0
- package/dist/ipgeolocation_io-UX6FCA2S.js +333 -0
- package/dist/ipqualityscore-MKTRXIZJ.js +287 -0
- package/dist/jina_ai-MRHPCSV5.js +119 -0
- package/dist/jira-EG7ZPOIW.js +627 -0
- package/dist/langsmith-FNO3RCOZ.js +597 -0
- package/dist/lemlist-SN6BJHSG.js +298 -0
- package/dist/linear-H3VU4PSD.js +2163 -0
- package/dist/logsnag-OY2JJT2H.js +167 -0
- package/dist/main.js +246 -2
- package/dist/mattermost-C5SQ7PGD.js +320 -0
- package/dist/mem0-LMLE5BFC.js +567 -0
- package/dist/memos-UWFAMBZC.js +781 -0
- package/dist/metabase-SRYDSDJ6.js +365 -0
- package/dist/mistral_ai-YNIJ7VDM.js +1195 -0
- package/dist/mother_duck-CPGOFEXE.js +322 -0
- package/dist/ngrok-CDJFBSOM.js +375 -0
- package/dist/notes-DIVFH3P3.js +109 -0
- package/dist/notion-HGDKS4HK.js +945 -0
- package/dist/open_exchange_rates-COHHYJDD.js +216 -0
- package/dist/openai-4TRT66GW.js +795 -0
- package/dist/opengraph_io-YKVW4PXI.js +377 -0
- package/dist/openrouter-6CV7B7V5.js +444 -0
- package/dist/outline-YWDUK5F7.js +604 -0
- package/dist/paddle-MEU7HWDZ.js +464 -0
- package/dist/perplexity-MRQUDBIC.js +238 -0
- package/dist/pinecone-JI7X2TAF.js +599 -0
- package/dist/pipedrive-6JQPAW23.js +453 -0
- package/dist/polar-7BF56CMC.js +400 -0
- package/dist/posthog-YPU5ADEN.js +3462 -0
- package/dist/postmark-BEU5OFKU.js +441 -0
- package/dist/prerender-UT5GOOZH.js +180 -0
- package/dist/pubmed-3SGOE24Q.js +1052 -0
- package/dist/railway-CEK4GLRQ.js +452 -0
- package/dist/readwise-DXQUQU67.js +482 -0
- package/dist/render-7TGAU5AW.js +473 -0
- package/dist/replicate-VICFSQ5A.js +347 -0
- package/dist/resend-3E76WK3O.js +100 -0
- package/dist/rootly-36GY46BY.js +345 -0
- package/dist/scrapfly-VDVUYAHX.js +289 -0
- package/dist/scrapingbee-3KTPMAVY.js +247 -0
- package/dist/screenshot_fyi-LKG62C3J.js +116 -0
- package/dist/semantic_scholar-4WREECYO.js +626 -0
- package/dist/sentry-HUQTGXOV.js +1139 -0
- package/dist/shodan-SGRKU4KS.js +303 -0
- package/dist/shopify-YCZ4L5HT.js +620 -0
- package/dist/stripe-OEBKMELB.js +583 -0
- package/dist/supabase-I3DBY7L4.js +937 -0
- package/dist/tavily-B2YHCNRD.js +349 -0
- package/dist/telegram-2VYJELZX.js +1773 -0
- package/dist/telnyx-HHXD3CXL.js +237 -0
- package/dist/todoist-PHFDEEIS.js +672 -0
- package/dist/trello-WUSAK6YN.js +1091 -0
- package/dist/turso-FW56U2B3.js +432 -0
- package/dist/twilio-M5JI7XHA.js +321 -0
- package/dist/umami-HAYODRC4.js +411 -0
- package/dist/unsplash-EDPTNEHJ.js +364 -0
- package/dist/upstash_redis-GC2CLIWD.js +299 -0
- package/dist/uptimerobot-XMSNYLIT.js +481 -0
- package/dist/v2ex-KU4ECD65.js +672 -0
- package/dist/vercel-THPCEFHW.js +1096 -0
- package/dist/wolfram_alpha_api-WHHTH4GU.js +212 -0
- package/dist/wordpress-O6TQEQNF.js +822 -0
- package/dist/workos-A3VHHWI3.js +681 -0
- package/dist/zhihu-BJAI64YJ.js +273 -0
- package/package.json +5 -4
|
@@ -0,0 +1,2163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createProviderPlugin,
|
|
3
|
+
guardedFetch,
|
|
4
|
+
requireApiKey,
|
|
5
|
+
upstreamError
|
|
6
|
+
} from "./chunk-CSJEZHQO.js";
|
|
7
|
+
import "./chunk-K7FVSFUX.js";
|
|
8
|
+
import {
|
|
9
|
+
TBError,
|
|
10
|
+
external_exports
|
|
11
|
+
} from "./chunk-JLTYA2B3.js";
|
|
12
|
+
import "./chunk-MLKGABMK.js";
|
|
13
|
+
|
|
14
|
+
// ../plugins/src/linear/api.ts
|
|
15
|
+
var SERVICE = "linear";
|
|
16
|
+
var GRAPHQL_URL = "https://api.linear.app/graphql";
|
|
17
|
+
var MAX_PAGES = 100;
|
|
18
|
+
var pageInfoFields = `
|
|
19
|
+
startCursor
|
|
20
|
+
endCursor
|
|
21
|
+
hasPreviousPage
|
|
22
|
+
hasNextPage
|
|
23
|
+
`;
|
|
24
|
+
var userFields = `
|
|
25
|
+
id
|
|
26
|
+
name
|
|
27
|
+
displayName
|
|
28
|
+
email
|
|
29
|
+
avatarUrl
|
|
30
|
+
active
|
|
31
|
+
admin
|
|
32
|
+
createdAt
|
|
33
|
+
`;
|
|
34
|
+
var teamFields = `
|
|
35
|
+
id
|
|
36
|
+
name
|
|
37
|
+
key
|
|
38
|
+
`;
|
|
39
|
+
var workflowStateFields = `
|
|
40
|
+
id
|
|
41
|
+
name
|
|
42
|
+
type
|
|
43
|
+
color
|
|
44
|
+
description
|
|
45
|
+
`;
|
|
46
|
+
var labelFields = `
|
|
47
|
+
id
|
|
48
|
+
name
|
|
49
|
+
color
|
|
50
|
+
description
|
|
51
|
+
isGroup
|
|
52
|
+
parent {
|
|
53
|
+
id
|
|
54
|
+
name
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
var cycleFields = `
|
|
58
|
+
id
|
|
59
|
+
name
|
|
60
|
+
number
|
|
61
|
+
description
|
|
62
|
+
startsAt
|
|
63
|
+
endsAt
|
|
64
|
+
completedAt
|
|
65
|
+
isActive
|
|
66
|
+
isFuture
|
|
67
|
+
isPast
|
|
68
|
+
isNext
|
|
69
|
+
isPrevious
|
|
70
|
+
team {
|
|
71
|
+
${teamFields}
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
var projectStatusFields = `
|
|
75
|
+
id
|
|
76
|
+
name
|
|
77
|
+
type
|
|
78
|
+
color
|
|
79
|
+
description
|
|
80
|
+
`;
|
|
81
|
+
var projectFields = `
|
|
82
|
+
id
|
|
83
|
+
name
|
|
84
|
+
description
|
|
85
|
+
url
|
|
86
|
+
slugId
|
|
87
|
+
icon
|
|
88
|
+
color
|
|
89
|
+
state
|
|
90
|
+
health
|
|
91
|
+
progress
|
|
92
|
+
priority
|
|
93
|
+
priorityLabel
|
|
94
|
+
scope
|
|
95
|
+
startDate
|
|
96
|
+
targetDate
|
|
97
|
+
createdAt
|
|
98
|
+
updatedAt
|
|
99
|
+
lead {
|
|
100
|
+
${userFields}
|
|
101
|
+
}
|
|
102
|
+
creator {
|
|
103
|
+
${userFields}
|
|
104
|
+
}
|
|
105
|
+
status {
|
|
106
|
+
${projectStatusFields}
|
|
107
|
+
}
|
|
108
|
+
`;
|
|
109
|
+
var initiativeFields = `
|
|
110
|
+
id
|
|
111
|
+
name
|
|
112
|
+
description
|
|
113
|
+
url
|
|
114
|
+
`;
|
|
115
|
+
var attachmentFields = `
|
|
116
|
+
id
|
|
117
|
+
title
|
|
118
|
+
subtitle
|
|
119
|
+
url
|
|
120
|
+
sourceType
|
|
121
|
+
metadata
|
|
122
|
+
source
|
|
123
|
+
createdAt
|
|
124
|
+
updatedAt
|
|
125
|
+
issue {
|
|
126
|
+
id
|
|
127
|
+
identifier
|
|
128
|
+
title
|
|
129
|
+
}
|
|
130
|
+
`;
|
|
131
|
+
var reactionFields = `
|
|
132
|
+
id
|
|
133
|
+
emoji
|
|
134
|
+
createdAt
|
|
135
|
+
updatedAt
|
|
136
|
+
user {
|
|
137
|
+
${userFields}
|
|
138
|
+
}
|
|
139
|
+
comment {
|
|
140
|
+
id
|
|
141
|
+
}
|
|
142
|
+
issue {
|
|
143
|
+
id
|
|
144
|
+
identifier
|
|
145
|
+
}
|
|
146
|
+
projectUpdate {
|
|
147
|
+
id
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
var commentFields = `
|
|
151
|
+
id
|
|
152
|
+
body
|
|
153
|
+
url
|
|
154
|
+
quotedText
|
|
155
|
+
createdAt
|
|
156
|
+
updatedAt
|
|
157
|
+
editedAt
|
|
158
|
+
resolvedAt
|
|
159
|
+
issueId
|
|
160
|
+
parentId
|
|
161
|
+
projectUpdateId
|
|
162
|
+
user {
|
|
163
|
+
${userFields}
|
|
164
|
+
}
|
|
165
|
+
reactions {
|
|
166
|
+
${reactionFields}
|
|
167
|
+
}
|
|
168
|
+
`;
|
|
169
|
+
var issueFields = `
|
|
170
|
+
id
|
|
171
|
+
identifier
|
|
172
|
+
title
|
|
173
|
+
description
|
|
174
|
+
url
|
|
175
|
+
createdAt
|
|
176
|
+
updatedAt
|
|
177
|
+
archivedAt
|
|
178
|
+
completedAt
|
|
179
|
+
dueDate
|
|
180
|
+
priority
|
|
181
|
+
estimate
|
|
182
|
+
team {
|
|
183
|
+
${teamFields}
|
|
184
|
+
}
|
|
185
|
+
state {
|
|
186
|
+
${workflowStateFields}
|
|
187
|
+
}
|
|
188
|
+
project {
|
|
189
|
+
${projectFields}
|
|
190
|
+
}
|
|
191
|
+
assignee {
|
|
192
|
+
${userFields}
|
|
193
|
+
}
|
|
194
|
+
creator {
|
|
195
|
+
${userFields}
|
|
196
|
+
}
|
|
197
|
+
cycle {
|
|
198
|
+
${cycleFields}
|
|
199
|
+
}
|
|
200
|
+
parent {
|
|
201
|
+
id
|
|
202
|
+
identifier
|
|
203
|
+
title
|
|
204
|
+
}
|
|
205
|
+
labels(first: 50) {
|
|
206
|
+
nodes {
|
|
207
|
+
${labelFields}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
`;
|
|
211
|
+
var detailedIssueFields = `
|
|
212
|
+
${issueFields}
|
|
213
|
+
attachments(first: 50) {
|
|
214
|
+
nodes {
|
|
215
|
+
${attachmentFields}
|
|
216
|
+
}
|
|
217
|
+
pageInfo {
|
|
218
|
+
${pageInfoFields}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
comments(first: 50) {
|
|
222
|
+
nodes {
|
|
223
|
+
${commentFields}
|
|
224
|
+
}
|
|
225
|
+
pageInfo {
|
|
226
|
+
${pageInfoFields}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
subscribers(first: 50) {
|
|
230
|
+
nodes {
|
|
231
|
+
${userFields}
|
|
232
|
+
}
|
|
233
|
+
pageInfo {
|
|
234
|
+
${pageInfoFields}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
reactions {
|
|
238
|
+
${reactionFields}
|
|
239
|
+
}
|
|
240
|
+
`;
|
|
241
|
+
function asRecord(value) {
|
|
242
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
243
|
+
}
|
|
244
|
+
function str(value) {
|
|
245
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
246
|
+
}
|
|
247
|
+
function num(value) {
|
|
248
|
+
return typeof value === "number" ? value : void 0;
|
|
249
|
+
}
|
|
250
|
+
function bool(value) {
|
|
251
|
+
return typeof value === "boolean" ? value : void 0;
|
|
252
|
+
}
|
|
253
|
+
function compact(input) {
|
|
254
|
+
const output = {};
|
|
255
|
+
for (const [key, value] of Object.entries(input)) {
|
|
256
|
+
if (value !== void 0) output[key] = value;
|
|
257
|
+
}
|
|
258
|
+
return output;
|
|
259
|
+
}
|
|
260
|
+
function nodesOf(connection) {
|
|
261
|
+
const nodes = asRecord(connection)?.nodes;
|
|
262
|
+
return Array.isArray(nodes) ? nodes : [];
|
|
263
|
+
}
|
|
264
|
+
function basenameFromUrl(url) {
|
|
265
|
+
const withoutQuery = url.includes("?") ? url.slice(0, url.indexOf("?")) : url;
|
|
266
|
+
const lastSlash = withoutQuery.lastIndexOf("/");
|
|
267
|
+
return lastSlash >= 0 ? withoutQuery.slice(lastSlash + 1) : withoutQuery;
|
|
268
|
+
}
|
|
269
|
+
async function mapWithConcurrency(items, concurrency, mapper) {
|
|
270
|
+
const results = [];
|
|
271
|
+
for (let index = 0; index < items.length; index += concurrency) {
|
|
272
|
+
results.push(...await Promise.all(items.slice(index, index + concurrency).map(mapper)));
|
|
273
|
+
}
|
|
274
|
+
return results;
|
|
275
|
+
}
|
|
276
|
+
async function readJson(response) {
|
|
277
|
+
const text = await response.text().catch(() => "");
|
|
278
|
+
if (text === "") return {};
|
|
279
|
+
try {
|
|
280
|
+
return asRecord(JSON.parse(text)) ?? { message: text };
|
|
281
|
+
} catch {
|
|
282
|
+
return { message: text };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function extractErrorMessage(body) {
|
|
286
|
+
const direct = str(body.message);
|
|
287
|
+
if (direct !== void 0) return direct;
|
|
288
|
+
if (Array.isArray(body.errors) && body.errors.length > 0) {
|
|
289
|
+
const joined = body.errors.map((error) => str(asRecord(error)?.message)).filter((message) => message !== void 0).join("; ");
|
|
290
|
+
if (joined !== "") return joined;
|
|
291
|
+
}
|
|
292
|
+
return "linear \u8BF7\u6C42\u5931\u8D25";
|
|
293
|
+
}
|
|
294
|
+
function graphqlErrorsToTBError(errors) {
|
|
295
|
+
const message = errors.map((error) => typeof error.message === "string" ? error.message : "").join("; ");
|
|
296
|
+
const lower = message.toLowerCase();
|
|
297
|
+
if (lower.includes("cannot query field") || lower.includes("syntax error") || lower.includes("entity not found") || lower.includes("invalid") || lower.includes("expected type") || lower.includes("required type") || lower.includes("must be")) {
|
|
298
|
+
return upstreamError(400, message);
|
|
299
|
+
}
|
|
300
|
+
if (lower.includes("unauthorized") || lower.includes("authentication")) {
|
|
301
|
+
return upstreamError(401, message);
|
|
302
|
+
}
|
|
303
|
+
if (lower.includes("rate limit")) {
|
|
304
|
+
return upstreamError(429, message);
|
|
305
|
+
}
|
|
306
|
+
return upstreamError(502, message);
|
|
307
|
+
}
|
|
308
|
+
async function graphqlRequest(ctx, query, variables) {
|
|
309
|
+
const authorization = requireApiKey(ctx, SERVICE);
|
|
310
|
+
let response;
|
|
311
|
+
let body;
|
|
312
|
+
try {
|
|
313
|
+
response = await guardedFetch(GRAPHQL_URL, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
headers: {
|
|
316
|
+
"accept": "application/json",
|
|
317
|
+
"authorization": authorization,
|
|
318
|
+
"content-type": "application/json"
|
|
319
|
+
},
|
|
320
|
+
body: JSON.stringify(compact({ query, variables }))
|
|
321
|
+
});
|
|
322
|
+
body = await readJson(response);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
if (error instanceof TBError) throw error;
|
|
325
|
+
throw upstreamError(502, error instanceof Error ? `linear \u8BF7\u6C42\u5931\u8D25: ${error.message}` : "linear \u8BF7\u6C42\u5931\u8D25");
|
|
326
|
+
}
|
|
327
|
+
if (!response.ok) throw upstreamError(response.status, extractErrorMessage(body));
|
|
328
|
+
const errors = Array.isArray(body.errors) ? body.errors.map((error) => asRecord(error) ?? { message: String(error) }) : void 0;
|
|
329
|
+
return {
|
|
330
|
+
// `data: null` 与"没有 data 字段"要分开:前者是 GraphQL 明确说"这次没有数据"。
|
|
331
|
+
data: body.data === null ? null : asRecord(body.data),
|
|
332
|
+
errors,
|
|
333
|
+
extensions: asRecord(body.extensions)
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
async function operation(ctx, query, variables) {
|
|
337
|
+
const response = await graphqlRequest(ctx, query, variables);
|
|
338
|
+
if (response.errors !== void 0 && response.errors.length > 0) {
|
|
339
|
+
throw graphqlErrorsToTBError(response.errors);
|
|
340
|
+
}
|
|
341
|
+
if (response.data === null || response.data === void 0) {
|
|
342
|
+
throw upstreamError(502, "linear graphql \u54CD\u5E94\u91CC\u6CA1\u6709 data");
|
|
343
|
+
}
|
|
344
|
+
return response.data;
|
|
345
|
+
}
|
|
346
|
+
async function rawDocument(ctx, document, variables) {
|
|
347
|
+
const response = await graphqlRequest(ctx, document, variables);
|
|
348
|
+
const hasErrors = response.errors !== void 0 && response.errors.length > 0;
|
|
349
|
+
return compact({
|
|
350
|
+
data: response.data === null ? null : response.data,
|
|
351
|
+
errors: response.errors,
|
|
352
|
+
extensions: response.extensions,
|
|
353
|
+
message: hasErrors ? response.errors.map((error) => typeof error.message === "string" ? error.message : "").join("; ") : void 0
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
async function fetchAllNodes(ctx, query, extract) {
|
|
357
|
+
const nodes = [];
|
|
358
|
+
let after;
|
|
359
|
+
for (let page = 0; ; page += 1) {
|
|
360
|
+
if (page >= MAX_PAGES) {
|
|
361
|
+
throw upstreamError(502, `linear \u7FFB\u9875\u8D85\u8FC7 ${MAX_PAGES} \u9875,\u4E0A\u6E38\u6E38\u6807\u53EF\u80FD\u6CA1\u6709\u63A8\u8FDB`);
|
|
362
|
+
}
|
|
363
|
+
const data = await operation(ctx, query, { after });
|
|
364
|
+
const connection = asRecord(extract(data));
|
|
365
|
+
if (connection === void 0) return nodes;
|
|
366
|
+
nodes.push(...nodesOf(connection));
|
|
367
|
+
const pageInfo = asRecord(connection.pageInfo);
|
|
368
|
+
const endCursor = str(pageInfo?.endCursor);
|
|
369
|
+
if (pageInfo?.hasNextPage !== true || endCursor === void 0) return nodes;
|
|
370
|
+
after = endCursor;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function requireEntity(value, message) {
|
|
374
|
+
const record = asRecord(value);
|
|
375
|
+
if (record === void 0) throw new TBError("invalid_argument", message);
|
|
376
|
+
return record;
|
|
377
|
+
}
|
|
378
|
+
async function fetchIssueById(ctx, issueId) {
|
|
379
|
+
const payload = await operation(ctx, `
|
|
380
|
+
query GetIssue($id: String!) {
|
|
381
|
+
issue(id: $id) {
|
|
382
|
+
${detailedIssueFields}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
`, { id: issueId });
|
|
386
|
+
return requireEntity(payload.issue, "linear issue \u4E0D\u5B58\u5728");
|
|
387
|
+
}
|
|
388
|
+
async function fetchProjectById(ctx, projectId, includeTeams, includeMembers, includeInitiatives) {
|
|
389
|
+
const payload = await operation(ctx, `
|
|
390
|
+
query GetProject(
|
|
391
|
+
$id: String!
|
|
392
|
+
$includeTeams: Boolean!
|
|
393
|
+
$includeMembers: Boolean!
|
|
394
|
+
$includeInitiatives: Boolean!
|
|
395
|
+
) {
|
|
396
|
+
project(id: $id) {
|
|
397
|
+
${projectFields}
|
|
398
|
+
teams(first: 50, includeArchived: false) @include(if: $includeTeams) {
|
|
399
|
+
nodes {
|
|
400
|
+
${teamFields}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
members(first: 100, includeArchived: false, includeDisabled: true) @include(if: $includeMembers) {
|
|
404
|
+
nodes {
|
|
405
|
+
${userFields}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
initiatives(first: 50, includeArchived: false) @include(if: $includeInitiatives) {
|
|
409
|
+
nodes {
|
|
410
|
+
${initiativeFields}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
`, { id: projectId, includeTeams, includeMembers, includeInitiatives });
|
|
416
|
+
return requireEntity(payload.project, "linear project \u4E0D\u5B58\u5728");
|
|
417
|
+
}
|
|
418
|
+
async function fetchAttachmentById(ctx, attachmentId) {
|
|
419
|
+
const payload = await operation(ctx, `
|
|
420
|
+
query GetAttachment($id: String!) {
|
|
421
|
+
attachment(id: $id) {
|
|
422
|
+
${attachmentFields}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
`, { id: attachmentId });
|
|
426
|
+
return requireEntity(payload.attachment, "linear attachment \u4E0D\u5B58\u5728");
|
|
427
|
+
}
|
|
428
|
+
async function fetchIssueLabelById(ctx, labelId) {
|
|
429
|
+
const payload = await operation(ctx, `
|
|
430
|
+
query GetIssueLabel($id: String!) {
|
|
431
|
+
issueLabel(id: $id) {
|
|
432
|
+
${labelFields}
|
|
433
|
+
team {
|
|
434
|
+
${teamFields}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
`, { id: labelId });
|
|
439
|
+
return requireEntity(payload.issueLabel, "linear label \u4E0D\u5B58\u5728");
|
|
440
|
+
}
|
|
441
|
+
async function fetchCommentById(ctx, commentId) {
|
|
442
|
+
const payload = await operation(ctx, `
|
|
443
|
+
query GetComment($id: String!) {
|
|
444
|
+
comment(id: $id) {
|
|
445
|
+
${commentFields}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
`, { id: commentId });
|
|
449
|
+
return requireEntity(payload.comment, "linear comment \u4E0D\u5B58\u5728");
|
|
450
|
+
}
|
|
451
|
+
async function fetchIssueRelationById(ctx, relationId) {
|
|
452
|
+
const payload = await operation(ctx, `
|
|
453
|
+
query GetIssueRelation($id: String!) {
|
|
454
|
+
issueRelation(id: $id) {
|
|
455
|
+
id
|
|
456
|
+
type
|
|
457
|
+
issue {
|
|
458
|
+
id
|
|
459
|
+
}
|
|
460
|
+
relatedIssue {
|
|
461
|
+
id
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
`, { id: relationId });
|
|
466
|
+
return requireEntity(payload.issueRelation, "linear issue relation \u4E0D\u5B58\u5728");
|
|
467
|
+
}
|
|
468
|
+
async function fetchProjectMilestoneById(ctx, milestoneId) {
|
|
469
|
+
const payload = await operation(ctx, `
|
|
470
|
+
query GetProjectMilestone($id: String!) {
|
|
471
|
+
projectMilestone(id: $id) {
|
|
472
|
+
id
|
|
473
|
+
name
|
|
474
|
+
description
|
|
475
|
+
targetDate
|
|
476
|
+
sortOrder
|
|
477
|
+
progress
|
|
478
|
+
status
|
|
479
|
+
project {
|
|
480
|
+
id
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
`, { id: milestoneId });
|
|
485
|
+
return requireEntity(payload.projectMilestone, "linear project milestone \u4E0D\u5B58\u5728");
|
|
486
|
+
}
|
|
487
|
+
async function fetchProjectUpdateById(ctx, projectUpdateId) {
|
|
488
|
+
const payload = await operation(ctx, `
|
|
489
|
+
query GetProjectUpdate($id: String!) {
|
|
490
|
+
projectUpdate(id: $id) {
|
|
491
|
+
id
|
|
492
|
+
body
|
|
493
|
+
health
|
|
494
|
+
isDiffHidden
|
|
495
|
+
isStale
|
|
496
|
+
url
|
|
497
|
+
createdAt
|
|
498
|
+
updatedAt
|
|
499
|
+
editedAt
|
|
500
|
+
slugId
|
|
501
|
+
project {
|
|
502
|
+
id
|
|
503
|
+
}
|
|
504
|
+
user {
|
|
505
|
+
${userFields}
|
|
506
|
+
}
|
|
507
|
+
reactions {
|
|
508
|
+
${reactionFields}
|
|
509
|
+
}
|
|
510
|
+
commentCount
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
`, { id: projectUpdateId });
|
|
514
|
+
return requireEntity(payload.projectUpdate, "linear project update \u4E0D\u5B58\u5728");
|
|
515
|
+
}
|
|
516
|
+
async function fetchViewer(ctx) {
|
|
517
|
+
const payload = await operation(ctx, `
|
|
518
|
+
query Viewer {
|
|
519
|
+
viewer {
|
|
520
|
+
${userFields}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
`, {});
|
|
524
|
+
const viewer = asRecord(payload.viewer);
|
|
525
|
+
if (viewer === void 0) throw upstreamError(502, "linear viewer \u67E5\u8BE2\u56DE\u4E86\u7A7A\u54CD\u5E94");
|
|
526
|
+
return viewer;
|
|
527
|
+
}
|
|
528
|
+
async function fetchIssueAttachments(ctx, issueId) {
|
|
529
|
+
const payload = await operation(ctx, `
|
|
530
|
+
query GetIssueAttachments($id: String!) {
|
|
531
|
+
issue(id: $id) {
|
|
532
|
+
attachments(first: 100, includeArchived: false) {
|
|
533
|
+
nodes {
|
|
534
|
+
${attachmentFields}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
`, { id: issueId });
|
|
540
|
+
return nodesOf(requireEntity(payload.issue, "linear issue \u4E0D\u5B58\u5728").attachments);
|
|
541
|
+
}
|
|
542
|
+
async function fetchTeamCycles(ctx, teamId) {
|
|
543
|
+
const payload = await operation(ctx, `
|
|
544
|
+
query GetTeamCycles($id: String!) {
|
|
545
|
+
team(id: $id) {
|
|
546
|
+
cycles(first: 100, includeArchived: false) {
|
|
547
|
+
nodes {
|
|
548
|
+
${cycleFields}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
`, { id: teamId });
|
|
554
|
+
return nodesOf(requireEntity(payload.team, "linear team \u4E0D\u5B58\u5728").cycles);
|
|
555
|
+
}
|
|
556
|
+
async function fetchTeamLabels(ctx, teamId) {
|
|
557
|
+
const payload = await operation(ctx, `
|
|
558
|
+
query GetTeamLabels($id: String!) {
|
|
559
|
+
team(id: $id) {
|
|
560
|
+
labels(first: 100, includeArchived: false) {
|
|
561
|
+
nodes {
|
|
562
|
+
${labelFields}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
`, { id: teamId });
|
|
568
|
+
return nodesOf(requireEntity(payload.team, "linear team \u4E0D\u5B58\u5728").labels);
|
|
569
|
+
}
|
|
570
|
+
async function fetchTeamStates(ctx, teamId) {
|
|
571
|
+
const payload = await operation(ctx, `
|
|
572
|
+
query GetTeamStates($id: String!) {
|
|
573
|
+
team(id: $id) {
|
|
574
|
+
states(first: 100, includeArchived: false) {
|
|
575
|
+
nodes {
|
|
576
|
+
${workflowStateFields}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
`, { id: teamId });
|
|
582
|
+
return nodesOf(requireEntity(payload.team, "linear team \u4E0D\u5B58\u5728").states);
|
|
583
|
+
}
|
|
584
|
+
async function fetchTeamDetails(ctx, teamId) {
|
|
585
|
+
const payload = await operation(ctx, `
|
|
586
|
+
query GetTeamDetails($id: String!) {
|
|
587
|
+
team(id: $id) {
|
|
588
|
+
${teamFields}
|
|
589
|
+
members(first: 100, includeDisabled: true) {
|
|
590
|
+
nodes {
|
|
591
|
+
${userFields}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
projects(first: 100, includeArchived: false) {
|
|
595
|
+
nodes {
|
|
596
|
+
${projectFields}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
`, { id: teamId });
|
|
602
|
+
return requireEntity(payload.team, "linear team \u4E0D\u5B58\u5728");
|
|
603
|
+
}
|
|
604
|
+
async function resolveAssigneeFilterId(ctx, assigneeId) {
|
|
605
|
+
if (assigneeId === void 0) return void 0;
|
|
606
|
+
if (assigneeId !== "me") return assigneeId;
|
|
607
|
+
return String((await fetchViewer(ctx)).id);
|
|
608
|
+
}
|
|
609
|
+
function buildIssuesFilter(projectId, assigneeId) {
|
|
610
|
+
const filter = compact({
|
|
611
|
+
project: projectId === void 0 ? void 0 : { id: { eq: projectId } },
|
|
612
|
+
assignee: assigneeId === void 0 ? void 0 : { id: { eq: assigneeId } }
|
|
613
|
+
});
|
|
614
|
+
return Object.keys(filter).length > 0 ? filter : void 0;
|
|
615
|
+
}
|
|
616
|
+
async function resolveProjectStatusId(ctx, statusType) {
|
|
617
|
+
const payload = await operation(ctx, `
|
|
618
|
+
query GetProjectStatuses {
|
|
619
|
+
organization {
|
|
620
|
+
projectStatuses {
|
|
621
|
+
id
|
|
622
|
+
type
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
`, {});
|
|
627
|
+
const statuses = asRecord(payload.organization)?.projectStatuses;
|
|
628
|
+
const list = Array.isArray(statuses) ? statuses : [];
|
|
629
|
+
const matched = list.map((item) => asRecord(item)).find((item) => item?.type === statusType);
|
|
630
|
+
const id = str(matched?.id);
|
|
631
|
+
if (id === void 0) throw new TBError("invalid_argument", `linear \u6CA1\u6709 state \u4E3A ${statusType} \u7684 project status`);
|
|
632
|
+
return id;
|
|
633
|
+
}
|
|
634
|
+
function mutationEntityId(payload, entityKey, message) {
|
|
635
|
+
const record = asRecord(payload);
|
|
636
|
+
const id = str(asRecord(record?.[entityKey])?.id);
|
|
637
|
+
if (record?.success !== true || id === void 0) throw upstreamError(502, message);
|
|
638
|
+
return id;
|
|
639
|
+
}
|
|
640
|
+
function archiveEntityId(payload, message) {
|
|
641
|
+
const record = asRecord(payload);
|
|
642
|
+
const id = str(asRecord(record?.entity)?.id);
|
|
643
|
+
if (record?.success !== true || id === void 0) throw upstreamError(502, message);
|
|
644
|
+
return id;
|
|
645
|
+
}
|
|
646
|
+
function requireSuccess(payload, message) {
|
|
647
|
+
if (asRecord(payload)?.success !== true) throw upstreamError(502, message);
|
|
648
|
+
}
|
|
649
|
+
function mapPageInfo(pageInfo) {
|
|
650
|
+
const info = asRecord(pageInfo);
|
|
651
|
+
return {
|
|
652
|
+
startCursor: info?.startCursor ?? null,
|
|
653
|
+
endCursor: info?.endCursor ?? null,
|
|
654
|
+
hasPreviousPage: Boolean(info?.hasPreviousPage),
|
|
655
|
+
hasNextPage: Boolean(info?.hasNextPage)
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function mapSnakePageInfo(pageInfo) {
|
|
659
|
+
const info = asRecord(pageInfo);
|
|
660
|
+
return {
|
|
661
|
+
end_cursor: info?.endCursor ?? null,
|
|
662
|
+
has_next_page: Boolean(info?.hasNextPage)
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
function mapUser(user) {
|
|
666
|
+
const record = asRecord(user);
|
|
667
|
+
if (record === void 0) return null;
|
|
668
|
+
return compact({
|
|
669
|
+
id: str(record.id),
|
|
670
|
+
name: str(record.name),
|
|
671
|
+
displayName: str(record.displayName),
|
|
672
|
+
email: str(record.email),
|
|
673
|
+
avatarUrl: str(record.avatarUrl),
|
|
674
|
+
active: bool(record.active),
|
|
675
|
+
admin: bool(record.admin),
|
|
676
|
+
createdAt: str(record.createdAt)
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
function mapTeam(team) {
|
|
680
|
+
const record = asRecord(team);
|
|
681
|
+
if (record === void 0) return null;
|
|
682
|
+
return compact({ id: str(record.id), name: str(record.name), key: str(record.key) });
|
|
683
|
+
}
|
|
684
|
+
function mapWorkflowState(state) {
|
|
685
|
+
const record = asRecord(state);
|
|
686
|
+
if (record === void 0) return null;
|
|
687
|
+
return compact({
|
|
688
|
+
id: str(record.id),
|
|
689
|
+
name: str(record.name),
|
|
690
|
+
type: str(record.type),
|
|
691
|
+
color: str(record.color),
|
|
692
|
+
description: str(record.description)
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
function mapLabel(label) {
|
|
696
|
+
const record = asRecord(label);
|
|
697
|
+
if (record === void 0) return null;
|
|
698
|
+
const parent = asRecord(record.parent);
|
|
699
|
+
return compact({
|
|
700
|
+
id: str(record.id),
|
|
701
|
+
name: str(record.name),
|
|
702
|
+
color: str(record.color),
|
|
703
|
+
description: str(record.description),
|
|
704
|
+
is_group: bool(record.isGroup),
|
|
705
|
+
parent: parent === void 0 ? null : compact({ id: str(parent.id), name: str(parent.name) })
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
function mapCycle(cycle) {
|
|
709
|
+
const record = asRecord(cycle);
|
|
710
|
+
if (record === void 0) return null;
|
|
711
|
+
return compact({
|
|
712
|
+
id: str(record.id),
|
|
713
|
+
name: str(record.name),
|
|
714
|
+
number: num(record.number),
|
|
715
|
+
description: str(record.description),
|
|
716
|
+
startsAt: str(record.startsAt),
|
|
717
|
+
endsAt: str(record.endsAt),
|
|
718
|
+
completedAt: str(record.completedAt),
|
|
719
|
+
isActive: bool(record.isActive),
|
|
720
|
+
isFuture: bool(record.isFuture),
|
|
721
|
+
isPast: bool(record.isPast),
|
|
722
|
+
team: mapTeam(record.team)
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
function mapProjectStatus(status) {
|
|
726
|
+
const record = asRecord(status);
|
|
727
|
+
if (record === void 0) return null;
|
|
728
|
+
return compact({
|
|
729
|
+
id: str(record.id),
|
|
730
|
+
name: str(record.name),
|
|
731
|
+
type: str(record.type),
|
|
732
|
+
color: str(record.color),
|
|
733
|
+
description: str(record.description)
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
function mapProject(project, options = {}) {
|
|
737
|
+
const record = asRecord(project);
|
|
738
|
+
if (record === void 0) return null;
|
|
739
|
+
return compact({
|
|
740
|
+
id: str(record.id),
|
|
741
|
+
name: str(record.name),
|
|
742
|
+
description: str(record.description),
|
|
743
|
+
url: str(record.url),
|
|
744
|
+
slugId: str(record.slugId),
|
|
745
|
+
icon: str(record.icon),
|
|
746
|
+
color: str(record.color),
|
|
747
|
+
state: str(record.state),
|
|
748
|
+
health: str(record.health),
|
|
749
|
+
progress: num(record.progress),
|
|
750
|
+
priority: num(record.priority),
|
|
751
|
+
priorityLabel: str(record.priorityLabel),
|
|
752
|
+
scope: num(record.scope),
|
|
753
|
+
startDate: str(record.startDate),
|
|
754
|
+
targetDate: str(record.targetDate),
|
|
755
|
+
createdAt: str(record.createdAt),
|
|
756
|
+
updatedAt: str(record.updatedAt),
|
|
757
|
+
lead: mapUser(record.lead),
|
|
758
|
+
creator: mapUser(record.creator),
|
|
759
|
+
status: mapProjectStatus(record.status),
|
|
760
|
+
// 这三块只在调用方明确要了、且上游确实回了的时候才出现 —— 没要就整个键都不该在。
|
|
761
|
+
teams: options.includeTeams === true && record.teams !== void 0 ? { nodes: nodesOf(record.teams).map(mapTeam) } : void 0,
|
|
762
|
+
members: options.includeMembers === true && record.members !== void 0 ? { nodes: nodesOf(record.members).map(mapUser) } : void 0,
|
|
763
|
+
initiatives: options.includeInitiatives === true && record.initiatives !== void 0 ? {
|
|
764
|
+
nodes: nodesOf(record.initiatives).map((initiative) => {
|
|
765
|
+
const item = asRecord(initiative) ?? {};
|
|
766
|
+
return compact({
|
|
767
|
+
id: str(item.id),
|
|
768
|
+
name: str(item.name),
|
|
769
|
+
description: str(item.description),
|
|
770
|
+
url: str(item.url)
|
|
771
|
+
});
|
|
772
|
+
})
|
|
773
|
+
} : void 0
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
function mapAttachment(attachment) {
|
|
777
|
+
const record = asRecord(attachment);
|
|
778
|
+
if (record === void 0) return null;
|
|
779
|
+
const issue = asRecord(record.issue);
|
|
780
|
+
return compact({
|
|
781
|
+
id: str(record.id),
|
|
782
|
+
title: str(record.title),
|
|
783
|
+
subtitle: str(record.subtitle),
|
|
784
|
+
url: str(record.url),
|
|
785
|
+
sourceType: str(record.sourceType),
|
|
786
|
+
metadata: asRecord(record.metadata),
|
|
787
|
+
source: asRecord(record.source),
|
|
788
|
+
issue: issue === void 0 ? null : compact({ id: str(issue.id), identifier: str(issue.identifier), title: str(issue.title) }),
|
|
789
|
+
createdAt: str(record.createdAt),
|
|
790
|
+
updatedAt: str(record.updatedAt)
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function mapReaction(reaction) {
|
|
794
|
+
const record = asRecord(reaction);
|
|
795
|
+
if (record === void 0) return null;
|
|
796
|
+
const comment = asRecord(record.comment);
|
|
797
|
+
const issue = asRecord(record.issue);
|
|
798
|
+
const projectUpdate = asRecord(record.projectUpdate);
|
|
799
|
+
return compact({
|
|
800
|
+
id: str(record.id),
|
|
801
|
+
emoji: str(record.emoji),
|
|
802
|
+
createdAt: str(record.createdAt),
|
|
803
|
+
updatedAt: str(record.updatedAt),
|
|
804
|
+
user: mapUser(record.user),
|
|
805
|
+
comment: comment === void 0 ? null : { id: str(comment.id) },
|
|
806
|
+
issue: issue === void 0 ? null : compact({ id: str(issue.id), identifier: str(issue.identifier) }),
|
|
807
|
+
projectUpdate: projectUpdate === void 0 ? null : { id: str(projectUpdate.id) }
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
function mapComment(comment) {
|
|
811
|
+
const record = asRecord(comment);
|
|
812
|
+
if (record === void 0) return null;
|
|
813
|
+
return compact({
|
|
814
|
+
id: str(record.id),
|
|
815
|
+
body: str(record.body),
|
|
816
|
+
url: str(record.url),
|
|
817
|
+
quotedText: str(record.quotedText),
|
|
818
|
+
createdAt: str(record.createdAt),
|
|
819
|
+
updatedAt: str(record.updatedAt),
|
|
820
|
+
editedAt: str(record.editedAt),
|
|
821
|
+
resolvedAt: str(record.resolvedAt),
|
|
822
|
+
issueId: str(record.issueId),
|
|
823
|
+
parentId: str(record.parentId),
|
|
824
|
+
projectUpdateId: str(record.projectUpdateId),
|
|
825
|
+
user: mapUser(record.user),
|
|
826
|
+
// reactions 在 Linear 这里是裸数组而不是 connection,不能走 nodesOf。
|
|
827
|
+
reactions: Array.isArray(record.reactions) ? record.reactions.map(mapReaction) : []
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
function mapIssueSummary(issue) {
|
|
831
|
+
const record = asRecord(issue);
|
|
832
|
+
if (record === void 0) return null;
|
|
833
|
+
return compact({
|
|
834
|
+
id: str(record.id),
|
|
835
|
+
identifier: str(record.identifier),
|
|
836
|
+
title: str(record.title),
|
|
837
|
+
description: str(record.description),
|
|
838
|
+
url: str(record.url),
|
|
839
|
+
createdAt: str(record.createdAt),
|
|
840
|
+
updatedAt: str(record.updatedAt),
|
|
841
|
+
archivedAt: str(record.archivedAt),
|
|
842
|
+
dueDate: str(record.dueDate),
|
|
843
|
+
priority: num(record.priority),
|
|
844
|
+
estimate: num(record.estimate),
|
|
845
|
+
team: mapTeam(record.team),
|
|
846
|
+
state: mapWorkflowState(record.state),
|
|
847
|
+
project: mapProject(record.project),
|
|
848
|
+
assignee: mapUser(record.assignee),
|
|
849
|
+
labels: { nodes: nodesOf(record.labels).map(mapLabel) }
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
function mapDetailedIssue(issue) {
|
|
853
|
+
const base = mapIssueSummary(issue);
|
|
854
|
+
if (base === null) return null;
|
|
855
|
+
const record = asRecord(issue) ?? {};
|
|
856
|
+
const parent = asRecord(record.parent);
|
|
857
|
+
return compact({
|
|
858
|
+
...base,
|
|
859
|
+
creator: mapUser(record.creator),
|
|
860
|
+
cycle: mapCycle(record.cycle),
|
|
861
|
+
parent: parent === void 0 ? null : compact({ id: str(parent.id), identifier: str(parent.identifier), title: str(parent.title) }),
|
|
862
|
+
attachments: {
|
|
863
|
+
nodes: nodesOf(record.attachments).map(mapAttachment),
|
|
864
|
+
pageInfo: mapPageInfo(asRecord(record.attachments)?.pageInfo)
|
|
865
|
+
},
|
|
866
|
+
comments: {
|
|
867
|
+
nodes: nodesOf(record.comments).map(mapComment),
|
|
868
|
+
pageInfo: mapPageInfo(asRecord(record.comments)?.pageInfo)
|
|
869
|
+
},
|
|
870
|
+
subscribers: {
|
|
871
|
+
nodes: nodesOf(record.subscribers).map(mapUser),
|
|
872
|
+
pageInfo: mapPageInfo(asRecord(record.subscribers)?.pageInfo)
|
|
873
|
+
},
|
|
874
|
+
reactions: Array.isArray(record.reactions) ? record.reactions.map(mapReaction) : []
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
function mapDraft(draft) {
|
|
878
|
+
const record = asRecord(draft);
|
|
879
|
+
if (record === void 0) return null;
|
|
880
|
+
const issue = asRecord(record.issue);
|
|
881
|
+
const project = asRecord(record.project);
|
|
882
|
+
const projectUpdate = asRecord(record.projectUpdate);
|
|
883
|
+
return compact({
|
|
884
|
+
id: str(record.id),
|
|
885
|
+
data: asRecord(record.data),
|
|
886
|
+
bodyData: str(record.bodyData),
|
|
887
|
+
createdAt: str(record.createdAt),
|
|
888
|
+
updatedAt: str(record.updatedAt),
|
|
889
|
+
isAutogenerated: bool(record.isAutogenerated),
|
|
890
|
+
team: mapTeam(record.team),
|
|
891
|
+
issue: issue === void 0 ? null : { id: str(issue.id) },
|
|
892
|
+
project: project === void 0 ? null : { id: str(project.id) },
|
|
893
|
+
projectUpdate: projectUpdate === void 0 ? null : { id: str(projectUpdate.id) },
|
|
894
|
+
user: mapUser(record.user)
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
async function createAttachment(input, ctx) {
|
|
898
|
+
const payload = await operation(ctx, `
|
|
899
|
+
mutation CreateAttachment($input: AttachmentCreateInput!) {
|
|
900
|
+
attachmentCreate(input: $input) {
|
|
901
|
+
success
|
|
902
|
+
attachment {
|
|
903
|
+
id
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
`, {
|
|
908
|
+
input: compact({
|
|
909
|
+
issueId: input.issue_id,
|
|
910
|
+
title: input.title,
|
|
911
|
+
url: input.url,
|
|
912
|
+
subtitle: str(input.subtitle)
|
|
913
|
+
})
|
|
914
|
+
});
|
|
915
|
+
const attachmentId = mutationEntityId(payload.attachmentCreate, "attachment", "linear create_attachment \u5931\u8D25");
|
|
916
|
+
const attachment = await fetchAttachmentById(ctx, attachmentId);
|
|
917
|
+
return {
|
|
918
|
+
id: attachment.id,
|
|
919
|
+
issue_id: asRecord(attachment.issue)?.id ?? input.issue_id,
|
|
920
|
+
title: attachment.title,
|
|
921
|
+
url: attachment.url,
|
|
922
|
+
subtitle: attachment.subtitle ?? null
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
async function createCommentReaction(input, ctx) {
|
|
926
|
+
const payload = await operation(ctx, `
|
|
927
|
+
mutation CreateCommentReaction($input: ReactionCreateInput!) {
|
|
928
|
+
reactionCreate(input: $input) {
|
|
929
|
+
success
|
|
930
|
+
reaction {
|
|
931
|
+
id
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
`, { input: { commentId: input.comment_id, emoji: input.emoji } });
|
|
936
|
+
return {
|
|
937
|
+
reaction_id: mutationEntityId(payload.reactionCreate, "reaction", "linear create_comment_reaction \u5931\u8D25"),
|
|
938
|
+
comment_id: input.comment_id,
|
|
939
|
+
emoji: input.emoji
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
async function createLinearComment(input, ctx) {
|
|
943
|
+
const payload = await operation(ctx, `
|
|
944
|
+
mutation CreateComment($input: CommentCreateInput!) {
|
|
945
|
+
commentCreate(input: $input) {
|
|
946
|
+
success
|
|
947
|
+
comment {
|
|
948
|
+
id
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
`, { input: { issueId: input.issueId, body: input.body } });
|
|
953
|
+
const commentId = mutationEntityId(payload.commentCreate, "comment", "linear create_linear_comment \u5931\u8D25");
|
|
954
|
+
const comment = await fetchCommentById(ctx, commentId);
|
|
955
|
+
return {
|
|
956
|
+
comment_id: comment.id,
|
|
957
|
+
issue_id: comment.issueId ?? input.issueId,
|
|
958
|
+
body: comment.body ?? input.body
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
async function createLinearIssue(input, ctx) {
|
|
962
|
+
const payload = await operation(ctx, `
|
|
963
|
+
mutation CreateIssue($input: IssueCreateInput!) {
|
|
964
|
+
issueCreate(input: $input) {
|
|
965
|
+
success
|
|
966
|
+
issue {
|
|
967
|
+
id
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
`, {
|
|
972
|
+
input: compact({
|
|
973
|
+
title: input.title,
|
|
974
|
+
teamId: input.team_id,
|
|
975
|
+
cycleId: str(input.cycle_id),
|
|
976
|
+
dueDate: str(input.due_date),
|
|
977
|
+
estimate: input.estimate,
|
|
978
|
+
priority: input.priority,
|
|
979
|
+
stateId: str(input.state_id),
|
|
980
|
+
labelIds: input.label_ids,
|
|
981
|
+
parentId: str(input.parent_id),
|
|
982
|
+
projectId: str(input.project_id),
|
|
983
|
+
assigneeId: str(input.assignee_id),
|
|
984
|
+
description: str(input.description)
|
|
985
|
+
})
|
|
986
|
+
});
|
|
987
|
+
const issueId = mutationEntityId(payload.issueCreate, "issue", "linear create_linear_issue \u5931\u8D25");
|
|
988
|
+
const issue = await fetchIssueById(ctx, issueId);
|
|
989
|
+
return {
|
|
990
|
+
id: issue.id,
|
|
991
|
+
identifier: issue.identifier,
|
|
992
|
+
issue_title: issue.title,
|
|
993
|
+
issue_description: issue.description ?? null,
|
|
994
|
+
ticket_url: issue.url
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
async function createLinearIssueRelation(input, ctx) {
|
|
998
|
+
const payload = await operation(ctx, `
|
|
999
|
+
mutation CreateIssueRelation($input: IssueRelationCreateInput!) {
|
|
1000
|
+
issueRelationCreate(input: $input) {
|
|
1001
|
+
success
|
|
1002
|
+
issueRelation {
|
|
1003
|
+
id
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
`, {
|
|
1008
|
+
input: {
|
|
1009
|
+
issueId: input.issue_id,
|
|
1010
|
+
relatedIssueId: input.related_issue_id,
|
|
1011
|
+
type: input.relation_type
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
const relationId = mutationEntityId(
|
|
1015
|
+
payload.issueRelationCreate,
|
|
1016
|
+
"issueRelation",
|
|
1017
|
+
"linear create_linear_issue_relation \u5931\u8D25"
|
|
1018
|
+
);
|
|
1019
|
+
const relation = await fetchIssueRelationById(ctx, relationId);
|
|
1020
|
+
return {
|
|
1021
|
+
id: relation.id,
|
|
1022
|
+
issue_id: asRecord(relation.issue)?.id ?? input.issue_id,
|
|
1023
|
+
related_issue_id: asRecord(relation.relatedIssue)?.id ?? input.related_issue_id,
|
|
1024
|
+
relation_type: relation.type ?? input.relation_type
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
async function createLinearLabel(input, ctx) {
|
|
1028
|
+
const payload = await operation(ctx, `
|
|
1029
|
+
mutation CreateIssueLabel($input: IssueLabelCreateInput!) {
|
|
1030
|
+
issueLabelCreate(input: $input) {
|
|
1031
|
+
success
|
|
1032
|
+
issueLabel {
|
|
1033
|
+
id
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
`, {
|
|
1038
|
+
input: compact({
|
|
1039
|
+
teamId: input.team_id,
|
|
1040
|
+
name: input.name,
|
|
1041
|
+
color: input.color,
|
|
1042
|
+
description: str(input.description)
|
|
1043
|
+
})
|
|
1044
|
+
});
|
|
1045
|
+
const labelId = mutationEntityId(payload.issueLabelCreate, "issueLabel", "linear create_linear_label \u5931\u8D25");
|
|
1046
|
+
const label = await fetchIssueLabelById(ctx, labelId);
|
|
1047
|
+
return {
|
|
1048
|
+
id: label.id,
|
|
1049
|
+
team_id: asRecord(label.team)?.id ?? input.team_id,
|
|
1050
|
+
name: label.name,
|
|
1051
|
+
color: label.color ?? input.color,
|
|
1052
|
+
description: label.description ?? null
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
async function createLinearProject(input, ctx) {
|
|
1056
|
+
const payload = await operation(ctx, `
|
|
1057
|
+
mutation CreateProject($input: ProjectCreateInput!) {
|
|
1058
|
+
projectCreate(input: $input) {
|
|
1059
|
+
success
|
|
1060
|
+
project {
|
|
1061
|
+
id
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
`, {
|
|
1066
|
+
// 入参声明里还有 `status_id` 与 `state`,上游**不往 create 里发**(只有 update 认它们)。
|
|
1067
|
+
// 保留这个取舍:替上游发一个没验证过的字段,失败方式会比"这个字段没生效"更难查。
|
|
1068
|
+
input: compact({
|
|
1069
|
+
icon: str(input.icon),
|
|
1070
|
+
name: input.name,
|
|
1071
|
+
color: str(input.color),
|
|
1072
|
+
leadId: str(input.lead_id),
|
|
1073
|
+
priority: input.priority,
|
|
1074
|
+
teamIds: input.team_ids,
|
|
1075
|
+
startDate: str(input.start_date),
|
|
1076
|
+
description: str(input.description),
|
|
1077
|
+
targetDate: str(input.target_date)
|
|
1078
|
+
})
|
|
1079
|
+
});
|
|
1080
|
+
const projectId = mutationEntityId(payload.projectCreate, "project", "linear create_linear_project \u5931\u8D25");
|
|
1081
|
+
const project = await fetchProjectById(ctx, projectId, false, false, false);
|
|
1082
|
+
return { id: project.id, name: project.name, url: project.url, state: project.state };
|
|
1083
|
+
}
|
|
1084
|
+
async function createProjectMilestone(input, ctx) {
|
|
1085
|
+
const payload = await operation(ctx, `
|
|
1086
|
+
mutation CreateProjectMilestone($input: ProjectMilestoneCreateInput!) {
|
|
1087
|
+
projectMilestoneCreate(input: $input) {
|
|
1088
|
+
success
|
|
1089
|
+
projectMilestone {
|
|
1090
|
+
id
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
`, {
|
|
1095
|
+
input: compact({
|
|
1096
|
+
name: input.name,
|
|
1097
|
+
projectId: input.project_id,
|
|
1098
|
+
sortOrder: input.sort_order,
|
|
1099
|
+
description: str(input.description),
|
|
1100
|
+
targetDate: str(input.target_date)
|
|
1101
|
+
})
|
|
1102
|
+
});
|
|
1103
|
+
const milestoneId = mutationEntityId(
|
|
1104
|
+
payload.projectMilestoneCreate,
|
|
1105
|
+
"projectMilestone",
|
|
1106
|
+
"linear create_project_milestone \u5931\u8D25"
|
|
1107
|
+
);
|
|
1108
|
+
const milestone = await fetchProjectMilestoneById(ctx, milestoneId);
|
|
1109
|
+
return {
|
|
1110
|
+
id: milestone.id,
|
|
1111
|
+
project_id: asRecord(milestone.project)?.id ?? input.project_id,
|
|
1112
|
+
name: milestone.name,
|
|
1113
|
+
target_date: milestone.targetDate ?? null
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
async function createProjectUpdate(input, ctx) {
|
|
1117
|
+
const payload = await operation(ctx, `
|
|
1118
|
+
mutation CreateProjectUpdate($input: ProjectUpdateCreateInput!) {
|
|
1119
|
+
projectUpdateCreate(input: $input) {
|
|
1120
|
+
success
|
|
1121
|
+
projectUpdate {
|
|
1122
|
+
id
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
`, {
|
|
1127
|
+
input: compact({
|
|
1128
|
+
body: input.body,
|
|
1129
|
+
health: str(input.health),
|
|
1130
|
+
projectId: input.project_id,
|
|
1131
|
+
isDiffHidden: input.is_diff_hidden
|
|
1132
|
+
})
|
|
1133
|
+
});
|
|
1134
|
+
const projectUpdateId = mutationEntityId(
|
|
1135
|
+
payload.projectUpdateCreate,
|
|
1136
|
+
"projectUpdate",
|
|
1137
|
+
"linear create_project_update \u5931\u8D25"
|
|
1138
|
+
);
|
|
1139
|
+
const projectUpdate = await fetchProjectUpdateById(ctx, projectUpdateId);
|
|
1140
|
+
return {
|
|
1141
|
+
id: projectUpdate.id,
|
|
1142
|
+
project_id: asRecord(projectUpdate.project)?.id ?? input.project_id,
|
|
1143
|
+
body: projectUpdate.body ?? null,
|
|
1144
|
+
health: projectUpdate.health ?? null,
|
|
1145
|
+
is_diff_hidden: Boolean(projectUpdate.isDiffHidden)
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
async function deleteLinearIssue(input, ctx) {
|
|
1149
|
+
const payload = await operation(ctx, `
|
|
1150
|
+
mutation DeleteIssue($id: String!) {
|
|
1151
|
+
issueDelete(id: $id) {
|
|
1152
|
+
success
|
|
1153
|
+
entity {
|
|
1154
|
+
id
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
`, { id: input.issue_id });
|
|
1159
|
+
return { id: archiveEntityId(payload.issueDelete, "linear delete_linear_issue \u5931\u8D25"), deleted: true };
|
|
1160
|
+
}
|
|
1161
|
+
var LIST_TEAMS_QUERY = `
|
|
1162
|
+
query ListTeams($after: String) {
|
|
1163
|
+
teams(after: $after, first: 100, includeArchived: false) {
|
|
1164
|
+
nodes {
|
|
1165
|
+
${teamFields}
|
|
1166
|
+
}
|
|
1167
|
+
pageInfo {
|
|
1168
|
+
${pageInfoFields}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
`;
|
|
1173
|
+
async function getAllLinearTeams(_input, ctx) {
|
|
1174
|
+
const teams = await fetchAllNodes(ctx, LIST_TEAMS_QUERY, (data) => data.teams);
|
|
1175
|
+
return { teams: teams.map(mapTeam) };
|
|
1176
|
+
}
|
|
1177
|
+
async function getAttachment(input, ctx) {
|
|
1178
|
+
const attachmentId = str(input.attachment_id);
|
|
1179
|
+
const fileName = str(input.file_name);
|
|
1180
|
+
if (attachmentId === void 0 && fileName === void 0) {
|
|
1181
|
+
throw new TBError("invalid_argument", "linear attachment \u9700\u8981 attachment_id \u6216 file_name");
|
|
1182
|
+
}
|
|
1183
|
+
const attachments = await fetchIssueAttachments(ctx, input.issue_id);
|
|
1184
|
+
const matched = attachments.find((item) => {
|
|
1185
|
+
const attachment = asRecord(item);
|
|
1186
|
+
if (attachmentId !== void 0 && attachment?.id === attachmentId) return true;
|
|
1187
|
+
if (fileName !== void 0 && attachment?.title === fileName) return true;
|
|
1188
|
+
return fileName !== void 0 && basenameFromUrl(String(attachment?.url ?? "")) === fileName;
|
|
1189
|
+
});
|
|
1190
|
+
if (matched === void 0) {
|
|
1191
|
+
throw new TBError("invalid_argument", "linear \u5728\u8BE5 issue \u4E0B\u627E\u4E0D\u5230\u5339\u914D\u7684 attachment");
|
|
1192
|
+
}
|
|
1193
|
+
return { attachment: mapAttachment(matched) };
|
|
1194
|
+
}
|
|
1195
|
+
async function getCurrentUser(_input, ctx) {
|
|
1196
|
+
return { viewer: mapUser(await fetchViewer(ctx)) };
|
|
1197
|
+
}
|
|
1198
|
+
async function getCyclesByTeamId(input, ctx) {
|
|
1199
|
+
const cycles = await fetchTeamCycles(ctx, input.team_id);
|
|
1200
|
+
return { cycles: cycles.map(mapCycle) };
|
|
1201
|
+
}
|
|
1202
|
+
async function getIssueDefaults(input, ctx) {
|
|
1203
|
+
const data = await operation(ctx, `
|
|
1204
|
+
query GetIssueDefaults($id: String!) {
|
|
1205
|
+
team(id: $id) {
|
|
1206
|
+
defaultIssueEstimate
|
|
1207
|
+
defaultIssueState {
|
|
1208
|
+
id
|
|
1209
|
+
name
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
`, { id: input.team_id });
|
|
1214
|
+
const team = requireEntity(data.team, "linear team \u4E0D\u5B58\u5728");
|
|
1215
|
+
const defaultState = asRecord(team.defaultIssueState);
|
|
1216
|
+
return {
|
|
1217
|
+
team: {
|
|
1218
|
+
defaultIssueState: defaultState === void 0 ? null : { id: String(defaultState.id), name: String(defaultState.name) },
|
|
1219
|
+
defaultIssueEstimate: num(team.defaultIssueEstimate) ?? null
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
async function getLinearIssue(input, ctx) {
|
|
1224
|
+
return { issue: mapDetailedIssue(await fetchIssueById(ctx, input.issue_id)) };
|
|
1225
|
+
}
|
|
1226
|
+
async function getLinearProject(input, ctx) {
|
|
1227
|
+
const includeTeams = input.include_teams === true;
|
|
1228
|
+
const includeMembers = input.include_members === true;
|
|
1229
|
+
const includeInitiatives = input.include_initiatives === true;
|
|
1230
|
+
const project = await fetchProjectById(ctx, input.project_id, includeTeams, includeMembers, includeInitiatives);
|
|
1231
|
+
return { project: mapProject(project, { includeTeams, includeMembers, includeInitiatives }) };
|
|
1232
|
+
}
|
|
1233
|
+
async function listIssuesByTeamId(input, ctx) {
|
|
1234
|
+
const payload = await operation(ctx, `
|
|
1235
|
+
query ListIssuesByTeamId($id: String!, $after: String, $first: Int, $includeArchived: Boolean) {
|
|
1236
|
+
team(id: $id) {
|
|
1237
|
+
${teamFields}
|
|
1238
|
+
issues(after: $after, first: $first, includeArchived: $includeArchived) {
|
|
1239
|
+
nodes {
|
|
1240
|
+
${issueFields}
|
|
1241
|
+
}
|
|
1242
|
+
pageInfo {
|
|
1243
|
+
${pageInfoFields}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
`, {
|
|
1249
|
+
id: input.team_id,
|
|
1250
|
+
after: str(input.after),
|
|
1251
|
+
first: input.first,
|
|
1252
|
+
includeArchived: input.include_archived
|
|
1253
|
+
});
|
|
1254
|
+
const team = requireEntity(payload.team, "linear team \u4E0D\u5B58\u5728");
|
|
1255
|
+
const issues = asRecord(team.issues);
|
|
1256
|
+
return {
|
|
1257
|
+
team: mapTeam(team),
|
|
1258
|
+
issues: nodesOf(issues).map(mapIssueSummary),
|
|
1259
|
+
// 只有这一个 action 的 page_info 是蛇形键,上游如此。
|
|
1260
|
+
page_info: mapSnakePageInfo(issues?.pageInfo)
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
async function listIssueDrafts(input, ctx) {
|
|
1264
|
+
const payload = await operation(ctx, `
|
|
1265
|
+
query ListIssueDrafts($after: String, $first: Int) {
|
|
1266
|
+
viewer {
|
|
1267
|
+
drafts(after: $after, first: $first, includeArchived: false) {
|
|
1268
|
+
nodes {
|
|
1269
|
+
id
|
|
1270
|
+
data
|
|
1271
|
+
bodyData
|
|
1272
|
+
createdAt
|
|
1273
|
+
updatedAt
|
|
1274
|
+
isAutogenerated
|
|
1275
|
+
team {
|
|
1276
|
+
${teamFields}
|
|
1277
|
+
}
|
|
1278
|
+
issue {
|
|
1279
|
+
id
|
|
1280
|
+
}
|
|
1281
|
+
project {
|
|
1282
|
+
id
|
|
1283
|
+
}
|
|
1284
|
+
projectUpdate {
|
|
1285
|
+
id
|
|
1286
|
+
}
|
|
1287
|
+
user {
|
|
1288
|
+
${userFields}
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
pageInfo {
|
|
1292
|
+
${pageInfoFields}
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
`, { after: str(input.after), first: input.first });
|
|
1298
|
+
const drafts = asRecord(asRecord(payload.viewer)?.drafts);
|
|
1299
|
+
return { drafts: nodesOf(drafts).map(mapDraft), page_info: mapPageInfo(drafts?.pageInfo) };
|
|
1300
|
+
}
|
|
1301
|
+
async function listLinearCycles(_input, ctx) {
|
|
1302
|
+
const cycles = await fetchAllNodes(ctx, `
|
|
1303
|
+
query ListCycles($after: String) {
|
|
1304
|
+
cycles(after: $after, first: 100, includeArchived: false) {
|
|
1305
|
+
nodes {
|
|
1306
|
+
${cycleFields}
|
|
1307
|
+
}
|
|
1308
|
+
pageInfo {
|
|
1309
|
+
${pageInfoFields}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
`, (data) => data.cycles);
|
|
1314
|
+
return { cycles: cycles.map(mapCycle) };
|
|
1315
|
+
}
|
|
1316
|
+
async function listLinearIssues(input, ctx) {
|
|
1317
|
+
const assigneeId = await resolveAssigneeFilterId(ctx, str(input.assignee_id));
|
|
1318
|
+
const payload = await operation(ctx, `
|
|
1319
|
+
query ListLinearIssues($after: String, $first: Int, $filter: IssueFilter) {
|
|
1320
|
+
issues(after: $after, first: $first, includeArchived: false, filter: $filter) {
|
|
1321
|
+
nodes {
|
|
1322
|
+
${issueFields}
|
|
1323
|
+
}
|
|
1324
|
+
pageInfo {
|
|
1325
|
+
${pageInfoFields}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
`, {
|
|
1330
|
+
after: str(input.after),
|
|
1331
|
+
first: input.first,
|
|
1332
|
+
filter: buildIssuesFilter(str(input.project_id), assigneeId)
|
|
1333
|
+
});
|
|
1334
|
+
const issues = asRecord(payload.issues);
|
|
1335
|
+
return { issues: nodesOf(issues).map(mapIssueSummary), page_info: mapPageInfo(issues?.pageInfo) };
|
|
1336
|
+
}
|
|
1337
|
+
async function listLinearLabels(input, ctx) {
|
|
1338
|
+
const teamId = str(input.team_id);
|
|
1339
|
+
const labels = teamId === void 0 ? await fetchAllNodes(ctx, `
|
|
1340
|
+
query ListWorkspaceLabels($after: String) {
|
|
1341
|
+
issueLabels(after: $after, first: 100, includeArchived: false) {
|
|
1342
|
+
nodes {
|
|
1343
|
+
${labelFields}
|
|
1344
|
+
team {
|
|
1345
|
+
${teamFields}
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
pageInfo {
|
|
1349
|
+
${pageInfoFields}
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
`, (data) => data.issueLabels) : await fetchTeamLabels(ctx, teamId);
|
|
1354
|
+
return { labels: labels.map(mapLabel) };
|
|
1355
|
+
}
|
|
1356
|
+
async function listLinearProjects(_input, ctx) {
|
|
1357
|
+
const projects = await fetchAllNodes(ctx, `
|
|
1358
|
+
query ListProjects($after: String) {
|
|
1359
|
+
projects(after: $after, first: 100, includeArchived: false) {
|
|
1360
|
+
nodes {
|
|
1361
|
+
${projectFields}
|
|
1362
|
+
}
|
|
1363
|
+
pageInfo {
|
|
1364
|
+
${pageInfoFields}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
`, (data) => data.projects);
|
|
1369
|
+
return { projects: projects.map((project) => mapProject(project)) };
|
|
1370
|
+
}
|
|
1371
|
+
async function listLinearStates(input, ctx) {
|
|
1372
|
+
const states = await fetchTeamStates(ctx, input.team_id);
|
|
1373
|
+
return { states: states.map(mapWorkflowState) };
|
|
1374
|
+
}
|
|
1375
|
+
async function listLinearTeams(input, ctx) {
|
|
1376
|
+
const teams = await fetchAllNodes(ctx, LIST_TEAMS_QUERY, (data) => data.teams);
|
|
1377
|
+
const projectId = str(input.project_id);
|
|
1378
|
+
const detailedTeams = await mapWithConcurrency(teams, 5, async (team) => {
|
|
1379
|
+
const teamId = str(asRecord(team)?.id);
|
|
1380
|
+
const detailed = teamId === void 0 ? asRecord(team) ?? {} : await fetchTeamDetails(ctx, teamId);
|
|
1381
|
+
return {
|
|
1382
|
+
...mapTeam(detailed),
|
|
1383
|
+
members: nodesOf(detailed.members).map(mapUser),
|
|
1384
|
+
projects: nodesOf(detailed.projects).filter((project) => projectId === void 0 || String(asRecord(project)?.id) === projectId).map((project) => mapProject(project))
|
|
1385
|
+
};
|
|
1386
|
+
});
|
|
1387
|
+
return { teams: detailedTeams };
|
|
1388
|
+
}
|
|
1389
|
+
async function listLinearUsers(input, ctx) {
|
|
1390
|
+
const payload = await operation(ctx, `
|
|
1391
|
+
query ListUsers($after: String, $first: Int) {
|
|
1392
|
+
users(
|
|
1393
|
+
after: $after
|
|
1394
|
+
first: $first
|
|
1395
|
+
includeArchived: false
|
|
1396
|
+
includeDisabled: true
|
|
1397
|
+
) {
|
|
1398
|
+
nodes {
|
|
1399
|
+
${userFields}
|
|
1400
|
+
}
|
|
1401
|
+
pageInfo {
|
|
1402
|
+
${pageInfoFields}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
`, { after: str(input.after), first: input.first });
|
|
1407
|
+
const users = asRecord(payload.users);
|
|
1408
|
+
return { users: nodesOf(users).map(mapUser), page_info: mapPageInfo(users?.pageInfo) };
|
|
1409
|
+
}
|
|
1410
|
+
async function removeIssueLabel(input, ctx) {
|
|
1411
|
+
const payload = await operation(ctx, `
|
|
1412
|
+
mutation RemoveIssueLabel($id: String!, $labelId: String!) {
|
|
1413
|
+
issueRemoveLabel(id: $id, labelId: $labelId) {
|
|
1414
|
+
success
|
|
1415
|
+
issue {
|
|
1416
|
+
id
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
`, { id: input.issue_id, labelId: input.label_id });
|
|
1421
|
+
requireSuccess(payload.issueRemoveLabel, "linear remove_issue_label \u5931\u8D25");
|
|
1422
|
+
return { issue_id: input.issue_id, label_id: input.label_id, removed: true };
|
|
1423
|
+
}
|
|
1424
|
+
async function removeReaction(input, ctx) {
|
|
1425
|
+
const payload = await operation(ctx, `
|
|
1426
|
+
mutation RemoveReaction($id: String!) {
|
|
1427
|
+
reactionDelete(id: $id) {
|
|
1428
|
+
success
|
|
1429
|
+
entityId
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
`, { id: input.reaction_id });
|
|
1433
|
+
requireSuccess(payload.reactionDelete, "linear remove_reaction \u5931\u8D25");
|
|
1434
|
+
return { reaction_id: input.reaction_id, removed: true };
|
|
1435
|
+
}
|
|
1436
|
+
async function runQuery(input, ctx) {
|
|
1437
|
+
return rawDocument(ctx, input.query, input.variables);
|
|
1438
|
+
}
|
|
1439
|
+
async function runMutation(input, ctx) {
|
|
1440
|
+
return rawDocument(ctx, input.mutation, input.variables);
|
|
1441
|
+
}
|
|
1442
|
+
async function searchIssues(input, ctx) {
|
|
1443
|
+
const payload = await operation(ctx, `
|
|
1444
|
+
query SearchIssues($after: String, $first: Int, $includeArchived: Boolean, $term: String!) {
|
|
1445
|
+
searchIssues(
|
|
1446
|
+
after: $after
|
|
1447
|
+
first: $first
|
|
1448
|
+
includeArchived: $includeArchived
|
|
1449
|
+
term: $term
|
|
1450
|
+
) {
|
|
1451
|
+
nodes {
|
|
1452
|
+
${issueFields}
|
|
1453
|
+
}
|
|
1454
|
+
pageInfo {
|
|
1455
|
+
${pageInfoFields}
|
|
1456
|
+
}
|
|
1457
|
+
totalCount
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
`, {
|
|
1461
|
+
after: str(input.after),
|
|
1462
|
+
first: input.first,
|
|
1463
|
+
includeArchived: input.include_archived,
|
|
1464
|
+
// 入参叫 query,GraphQL 变量叫 term —— 别顺手改名。
|
|
1465
|
+
term: input.query
|
|
1466
|
+
});
|
|
1467
|
+
const results = asRecord(payload.searchIssues);
|
|
1468
|
+
return {
|
|
1469
|
+
issues: nodesOf(results).map(mapIssueSummary),
|
|
1470
|
+
page_info: mapPageInfo(results?.pageInfo),
|
|
1471
|
+
total_count: num(results?.totalCount) ?? 0
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
async function updateIssue(input, ctx) {
|
|
1475
|
+
const payload = await operation(ctx, `
|
|
1476
|
+
mutation UpdateIssue($id: String!, $input: IssueUpdateInput!) {
|
|
1477
|
+
issueUpdate(id: $id, input: $input) {
|
|
1478
|
+
success
|
|
1479
|
+
issue {
|
|
1480
|
+
id
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
`, {
|
|
1485
|
+
id: input.issueId,
|
|
1486
|
+
input: compact({
|
|
1487
|
+
title: str(input.title),
|
|
1488
|
+
teamId: str(input.teamId),
|
|
1489
|
+
cycleId: str(input.cycleId),
|
|
1490
|
+
dueDate: str(input.dueDate),
|
|
1491
|
+
stateId: str(input.stateId),
|
|
1492
|
+
estimate: input.estimate,
|
|
1493
|
+
labelIds: input.labelIds,
|
|
1494
|
+
parentId: str(input.parentId),
|
|
1495
|
+
priority: input.priority,
|
|
1496
|
+
projectId: str(input.projectId),
|
|
1497
|
+
assigneeId: str(input.assigneeId),
|
|
1498
|
+
description: str(input.description)
|
|
1499
|
+
})
|
|
1500
|
+
});
|
|
1501
|
+
const issueId = mutationEntityId(payload.issueUpdate, "issue", "linear update_issue \u5931\u8D25");
|
|
1502
|
+
return { issue: mapDetailedIssue(await fetchIssueById(ctx, issueId)) };
|
|
1503
|
+
}
|
|
1504
|
+
async function updateLinearComment(input, ctx) {
|
|
1505
|
+
const payload = await operation(ctx, `
|
|
1506
|
+
mutation UpdateComment($id: String!, $input: CommentUpdateInput!) {
|
|
1507
|
+
commentUpdate(id: $id, input: $input) {
|
|
1508
|
+
success
|
|
1509
|
+
comment {
|
|
1510
|
+
id
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
`, { id: input.comment_id, input: { body: input.body } });
|
|
1515
|
+
const commentId = mutationEntityId(payload.commentUpdate, "comment", "linear update_linear_comment \u5931\u8D25");
|
|
1516
|
+
return { comment: mapComment(await fetchCommentById(ctx, commentId)) };
|
|
1517
|
+
}
|
|
1518
|
+
async function updateLinearProject(input, ctx) {
|
|
1519
|
+
const requestedState = str(input.state);
|
|
1520
|
+
const resolvedStatusId = str(input.status_id) ?? (requestedState === void 0 ? void 0 : await resolveProjectStatusId(ctx, requestedState));
|
|
1521
|
+
const payload = await operation(ctx, `
|
|
1522
|
+
mutation UpdateProject($id: String!, $input: ProjectUpdateInput!) {
|
|
1523
|
+
projectUpdate(id: $id, input: $input) {
|
|
1524
|
+
success
|
|
1525
|
+
project {
|
|
1526
|
+
id
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
`, {
|
|
1531
|
+
id: input.project_id,
|
|
1532
|
+
input: compact({
|
|
1533
|
+
icon: str(input.icon),
|
|
1534
|
+
name: str(input.name),
|
|
1535
|
+
color: str(input.color),
|
|
1536
|
+
leadId: str(input.lead_id),
|
|
1537
|
+
priority: input.priority,
|
|
1538
|
+
statusId: resolvedStatusId,
|
|
1539
|
+
startDate: str(input.start_date),
|
|
1540
|
+
description: str(input.description),
|
|
1541
|
+
targetDate: str(input.target_date)
|
|
1542
|
+
})
|
|
1543
|
+
});
|
|
1544
|
+
const projectId = mutationEntityId(payload.projectUpdate, "project", "linear update_linear_project \u5931\u8D25");
|
|
1545
|
+
return { project: mapProject(await fetchProjectById(ctx, projectId, false, false, false)) };
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// ../plugins/src/linear/schema.ts
|
|
1549
|
+
var createAttachmentInput = external_exports.strictObject({
|
|
1550
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1551
|
+
title: external_exports.string().min(1).describe("Attachment title."),
|
|
1552
|
+
url: external_exports.string().min(1).describe("Attachment URL."),
|
|
1553
|
+
subtitle: external_exports.string().describe("Attachment subtitle.").optional()
|
|
1554
|
+
}).describe("The input payload for this action.");
|
|
1555
|
+
var createAttachmentOutput = external_exports.looseObject({
|
|
1556
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1557
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1558
|
+
title: external_exports.string().describe("Attachment title.").optional(),
|
|
1559
|
+
url: external_exports.string().describe("Attachment URL.").optional(),
|
|
1560
|
+
subtitle: external_exports.string().describe("Attachment subtitle.").nullable().optional()
|
|
1561
|
+
}).describe("Linear action output.");
|
|
1562
|
+
var createCommentReactionInput = external_exports.strictObject({
|
|
1563
|
+
comment_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1564
|
+
emoji: external_exports.string().min(1).describe("Emoji to add.")
|
|
1565
|
+
}).describe("The input payload for this action.");
|
|
1566
|
+
var createCommentReactionOutput = external_exports.looseObject({
|
|
1567
|
+
reaction_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1568
|
+
comment_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1569
|
+
emoji: external_exports.string().optional()
|
|
1570
|
+
}).describe("Linear action output.");
|
|
1571
|
+
var createLinearCommentInput = external_exports.strictObject({
|
|
1572
|
+
issueId: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1573
|
+
body: external_exports.string().min(1).describe("Comment text in Markdown.")
|
|
1574
|
+
}).describe("The input payload for this action.");
|
|
1575
|
+
var createLinearCommentOutput = external_exports.looseObject({
|
|
1576
|
+
comment_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1577
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1578
|
+
body: external_exports.string().optional()
|
|
1579
|
+
}).describe("Linear action output.");
|
|
1580
|
+
var createLinearIssueInput = external_exports.strictObject({
|
|
1581
|
+
title: external_exports.string().min(1).describe("Issue title."),
|
|
1582
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1583
|
+
cycle_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1584
|
+
due_date: external_exports.string().describe("Issue due date.").optional(),
|
|
1585
|
+
estimate: external_exports.number().describe("Issue estimate.").optional(),
|
|
1586
|
+
priority: external_exports.number().describe("Issue priority.").optional(),
|
|
1587
|
+
state_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1588
|
+
label_ids: external_exports.array(external_exports.string().min(1).describe("Linear resource ID.")).describe("Label IDs.").optional(),
|
|
1589
|
+
parent_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1590
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1591
|
+
assignee_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1592
|
+
description: external_exports.string().describe("Issue description in Markdown.").optional()
|
|
1593
|
+
}).describe("The input payload for this action.");
|
|
1594
|
+
var createLinearIssueOutput = external_exports.looseObject({
|
|
1595
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1596
|
+
identifier: external_exports.string().describe("Issue identifier.").optional(),
|
|
1597
|
+
issue_title: external_exports.string().describe("Issue title.").optional(),
|
|
1598
|
+
issue_description: external_exports.string().describe("Issue description.").nullable().optional(),
|
|
1599
|
+
ticket_url: external_exports.string().describe("Issue URL.").optional()
|
|
1600
|
+
}).describe("Linear action output.");
|
|
1601
|
+
var createLinearIssueRelationInput = external_exports.strictObject({
|
|
1602
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1603
|
+
related_issue_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1604
|
+
relation_type: external_exports.enum(["blocks", "duplicate", "related", "similar"]).describe("Relationship type.")
|
|
1605
|
+
}).describe("The input payload for this action.");
|
|
1606
|
+
var createLinearIssueRelationOutput = external_exports.looseObject({
|
|
1607
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1608
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1609
|
+
related_issue_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1610
|
+
relation_type: external_exports.string().optional()
|
|
1611
|
+
}).describe("Linear action output.");
|
|
1612
|
+
var createLinearLabelInput = external_exports.strictObject({
|
|
1613
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1614
|
+
name: external_exports.string().min(1).describe("Label name."),
|
|
1615
|
+
color: external_exports.string().min(1).describe("Label color."),
|
|
1616
|
+
description: external_exports.string().describe("Label description.").optional()
|
|
1617
|
+
}).describe("The input payload for this action.");
|
|
1618
|
+
var createLinearLabelOutput = external_exports.looseObject({
|
|
1619
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1620
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1621
|
+
name: external_exports.string().optional(),
|
|
1622
|
+
color: external_exports.string().optional(),
|
|
1623
|
+
description: external_exports.string().nullable().optional()
|
|
1624
|
+
}).describe("Linear action output.");
|
|
1625
|
+
var createLinearProjectInput = external_exports.strictObject({
|
|
1626
|
+
icon: external_exports.string().describe("Project icon.").optional(),
|
|
1627
|
+
name: external_exports.string().min(1).describe("Project name."),
|
|
1628
|
+
color: external_exports.string().describe("Project color.").optional(),
|
|
1629
|
+
lead_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1630
|
+
priority: external_exports.number().describe("Project priority.").optional(),
|
|
1631
|
+
status_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1632
|
+
state: external_exports.string().describe("Project state type.").optional(),
|
|
1633
|
+
start_date: external_exports.string().describe("Project start date.").optional(),
|
|
1634
|
+
description: external_exports.string().describe("Project description.").optional(),
|
|
1635
|
+
target_date: external_exports.string().describe("Project target date.").optional(),
|
|
1636
|
+
team_ids: external_exports.array(external_exports.string().min(1).describe("Linear resource ID.")).min(1).describe("Team IDs associated with the project.")
|
|
1637
|
+
}).describe("The input payload for this action.");
|
|
1638
|
+
var createLinearProjectOutput = external_exports.looseObject({
|
|
1639
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1640
|
+
name: external_exports.string().optional(),
|
|
1641
|
+
url: external_exports.string().optional(),
|
|
1642
|
+
state: external_exports.string().optional()
|
|
1643
|
+
}).describe("Linear action output.");
|
|
1644
|
+
var createProjectMilestoneInput = external_exports.strictObject({
|
|
1645
|
+
name: external_exports.string().min(1).describe("Milestone name."),
|
|
1646
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1647
|
+
sort_order: external_exports.number().describe("Milestone sort order.").optional(),
|
|
1648
|
+
description: external_exports.string().describe("Milestone description.").optional(),
|
|
1649
|
+
target_date: external_exports.string().describe("Target date.").optional()
|
|
1650
|
+
}).describe("The input payload for this action.");
|
|
1651
|
+
var createProjectMilestoneOutput = external_exports.looseObject({
|
|
1652
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1653
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1654
|
+
name: external_exports.string().optional(),
|
|
1655
|
+
target_date: external_exports.string().nullable().optional()
|
|
1656
|
+
}).describe("Linear action output.");
|
|
1657
|
+
var createProjectUpdateInput = external_exports.strictObject({
|
|
1658
|
+
body: external_exports.string().min(1).describe("Project update body."),
|
|
1659
|
+
health: external_exports.enum(["onTrack", "atRisk", "offTrack"]).describe("Project health.").optional(),
|
|
1660
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1661
|
+
is_diff_hidden: external_exports.boolean().describe("Whether to hide diff.").optional()
|
|
1662
|
+
}).describe("The input payload for this action.");
|
|
1663
|
+
var createProjectUpdateOutput = external_exports.looseObject({
|
|
1664
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1665
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1666
|
+
body: external_exports.string().nullable().optional(),
|
|
1667
|
+
health: external_exports.string().nullable().optional(),
|
|
1668
|
+
is_diff_hidden: external_exports.boolean().optional()
|
|
1669
|
+
}).describe("Linear action output.");
|
|
1670
|
+
var deleteLinearIssueInput = external_exports.strictObject({
|
|
1671
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1672
|
+
}).describe("The input payload for this action.");
|
|
1673
|
+
var deleteLinearIssueOutput = external_exports.looseObject({
|
|
1674
|
+
id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1675
|
+
deleted: external_exports.boolean().optional()
|
|
1676
|
+
}).describe("Linear action output.");
|
|
1677
|
+
var getAllLinearTeamsInput = external_exports.strictObject({}).describe("The input payload for this action.");
|
|
1678
|
+
var getAllLinearTeamsOutput = external_exports.looseObject({
|
|
1679
|
+
teams: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("teams returned by Linear.").optional()
|
|
1680
|
+
}).describe("Linear action output.");
|
|
1681
|
+
var getAttachmentInput = external_exports.strictObject({
|
|
1682
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1683
|
+
attachment_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1684
|
+
file_name: external_exports.string().min(1).describe("Attachment file name or title.").optional()
|
|
1685
|
+
}).describe("The input payload for this action.");
|
|
1686
|
+
var getAttachmentOutput = external_exports.looseObject({
|
|
1687
|
+
attachment: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1688
|
+
}).describe("Linear action output.");
|
|
1689
|
+
var getCurrentUserInput = external_exports.strictObject({}).describe("The input payload for this action.");
|
|
1690
|
+
var getCurrentUserOutput = external_exports.looseObject({
|
|
1691
|
+
viewer: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1692
|
+
}).describe("Linear action output.");
|
|
1693
|
+
var getCyclesByTeamIdInput = external_exports.strictObject({
|
|
1694
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1695
|
+
}).describe("The input payload for this action.");
|
|
1696
|
+
var getCyclesByTeamIdOutput = external_exports.looseObject({
|
|
1697
|
+
cycles: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("cycles returned by Linear.").optional()
|
|
1698
|
+
}).describe("Linear action output.");
|
|
1699
|
+
var getIssueDefaultsInput = external_exports.strictObject({
|
|
1700
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1701
|
+
}).describe("The input payload for this action.");
|
|
1702
|
+
var getIssueDefaultsOutput = external_exports.looseObject({
|
|
1703
|
+
team: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1704
|
+
}).describe("Linear action output.");
|
|
1705
|
+
var getLinearIssueInput = external_exports.strictObject({
|
|
1706
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1707
|
+
}).describe("The input payload for this action.");
|
|
1708
|
+
var getLinearIssueOutput = external_exports.looseObject({
|
|
1709
|
+
issue: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1710
|
+
}).describe("Linear action output.");
|
|
1711
|
+
var getLinearProjectInput = external_exports.strictObject({
|
|
1712
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1713
|
+
include_teams: external_exports.boolean().describe("Include project teams.").optional(),
|
|
1714
|
+
include_members: external_exports.boolean().describe("Include project members.").optional(),
|
|
1715
|
+
include_initiatives: external_exports.boolean().describe("Include project initiatives.").optional()
|
|
1716
|
+
}).describe("The input payload for this action.");
|
|
1717
|
+
var getLinearProjectOutput = external_exports.looseObject({
|
|
1718
|
+
project: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1719
|
+
}).describe("Linear action output.");
|
|
1720
|
+
var listIssuesByTeamIdInput = external_exports.strictObject({
|
|
1721
|
+
after: external_exports.string().describe("Pagination cursor.").optional(),
|
|
1722
|
+
first: external_exports.int().min(1).describe("Number of records to return.").optional(),
|
|
1723
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1724
|
+
include_archived: external_exports.boolean().describe("Include archived issues.").optional()
|
|
1725
|
+
}).describe("The input payload for this action.");
|
|
1726
|
+
var listIssuesByTeamIdOutput = external_exports.looseObject({
|
|
1727
|
+
team: external_exports.looseObject({}).describe("Linear API object.").optional(),
|
|
1728
|
+
issues: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).optional(),
|
|
1729
|
+
page_info: external_exports.looseObject({
|
|
1730
|
+
startCursor: external_exports.string().describe("Previous-page start cursor.").nullable().optional(),
|
|
1731
|
+
endCursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1732
|
+
hasPreviousPage: external_exports.boolean().describe("Whether a previous page exists.").optional(),
|
|
1733
|
+
hasNextPage: external_exports.boolean().describe("Whether a next page exists.").optional(),
|
|
1734
|
+
end_cursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1735
|
+
has_next_page: external_exports.boolean().describe("Whether a next page exists.").optional()
|
|
1736
|
+
}).describe("Pagination information.").optional()
|
|
1737
|
+
}).describe("Linear action output.");
|
|
1738
|
+
var listIssueDraftsInput = external_exports.strictObject({
|
|
1739
|
+
after: external_exports.string().describe("Pagination cursor.").optional(),
|
|
1740
|
+
first: external_exports.int().min(1).describe("Number of records to return.").optional()
|
|
1741
|
+
}).describe("The input payload for this action.");
|
|
1742
|
+
var listIssueDraftsOutput = external_exports.looseObject({
|
|
1743
|
+
drafts: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).optional(),
|
|
1744
|
+
page_info: external_exports.looseObject({
|
|
1745
|
+
startCursor: external_exports.string().describe("Previous-page start cursor.").nullable().optional(),
|
|
1746
|
+
endCursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1747
|
+
hasPreviousPage: external_exports.boolean().describe("Whether a previous page exists.").optional(),
|
|
1748
|
+
hasNextPage: external_exports.boolean().describe("Whether a next page exists.").optional(),
|
|
1749
|
+
end_cursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1750
|
+
has_next_page: external_exports.boolean().describe("Whether a next page exists.").optional()
|
|
1751
|
+
}).describe("Pagination information.").optional()
|
|
1752
|
+
}).describe("Linear action output.");
|
|
1753
|
+
var listLinearCyclesInput = external_exports.strictObject({}).describe("The input payload for this action.");
|
|
1754
|
+
var listLinearCyclesOutput = external_exports.looseObject({
|
|
1755
|
+
cycles: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("cycles returned by Linear.").optional()
|
|
1756
|
+
}).describe("Linear action output.");
|
|
1757
|
+
var listLinearIssuesInput = external_exports.strictObject({
|
|
1758
|
+
after: external_exports.string().describe("Pagination cursor.").optional(),
|
|
1759
|
+
first: external_exports.int().min(1).describe("Number of records to return.").optional(),
|
|
1760
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1761
|
+
assignee_id: external_exports.string().min(1).describe("Linear resource ID.").optional()
|
|
1762
|
+
}).describe("The input payload for this action.");
|
|
1763
|
+
var listLinearIssuesOutput = external_exports.looseObject({
|
|
1764
|
+
issues: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).optional(),
|
|
1765
|
+
page_info: external_exports.looseObject({
|
|
1766
|
+
startCursor: external_exports.string().describe("Previous-page start cursor.").nullable().optional(),
|
|
1767
|
+
endCursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1768
|
+
hasPreviousPage: external_exports.boolean().describe("Whether a previous page exists.").optional(),
|
|
1769
|
+
hasNextPage: external_exports.boolean().describe("Whether a next page exists.").optional(),
|
|
1770
|
+
end_cursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1771
|
+
has_next_page: external_exports.boolean().describe("Whether a next page exists.").optional()
|
|
1772
|
+
}).describe("Pagination information.").optional()
|
|
1773
|
+
}).describe("Linear action output.");
|
|
1774
|
+
var listLinearLabelsInput = external_exports.strictObject({
|
|
1775
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID.").optional()
|
|
1776
|
+
}).describe("The input payload for this action.");
|
|
1777
|
+
var listLinearLabelsOutput = external_exports.looseObject({
|
|
1778
|
+
labels: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("labels returned by Linear.").optional()
|
|
1779
|
+
}).describe("Linear action output.");
|
|
1780
|
+
var listLinearProjectsInput = external_exports.strictObject({}).describe("The input payload for this action.");
|
|
1781
|
+
var listLinearProjectsOutput = external_exports.looseObject({
|
|
1782
|
+
projects: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("projects returned by Linear.").optional()
|
|
1783
|
+
}).describe("Linear action output.");
|
|
1784
|
+
var listLinearStatesInput = external_exports.strictObject({
|
|
1785
|
+
team_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1786
|
+
}).describe("The input payload for this action.");
|
|
1787
|
+
var listLinearStatesOutput = external_exports.looseObject({
|
|
1788
|
+
states: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("states returned by Linear.").optional()
|
|
1789
|
+
}).describe("Linear action output.");
|
|
1790
|
+
var listLinearTeamsInput = external_exports.strictObject({
|
|
1791
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID.").optional()
|
|
1792
|
+
}).describe("The input payload for this action.");
|
|
1793
|
+
var listLinearTeamsOutput = external_exports.looseObject({
|
|
1794
|
+
teams: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("teams returned by Linear.").optional()
|
|
1795
|
+
}).describe("Linear action output.");
|
|
1796
|
+
var listLinearUsersInput = external_exports.strictObject({
|
|
1797
|
+
after: external_exports.string().describe("Pagination cursor.").optional(),
|
|
1798
|
+
first: external_exports.int().min(1).describe("Number of records to return.").optional()
|
|
1799
|
+
}).describe("The input payload for this action.");
|
|
1800
|
+
var listLinearUsersOutput = external_exports.looseObject({
|
|
1801
|
+
users: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).optional(),
|
|
1802
|
+
page_info: external_exports.looseObject({
|
|
1803
|
+
startCursor: external_exports.string().describe("Previous-page start cursor.").nullable().optional(),
|
|
1804
|
+
endCursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1805
|
+
hasPreviousPage: external_exports.boolean().describe("Whether a previous page exists.").optional(),
|
|
1806
|
+
hasNextPage: external_exports.boolean().describe("Whether a next page exists.").optional(),
|
|
1807
|
+
end_cursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1808
|
+
has_next_page: external_exports.boolean().describe("Whether a next page exists.").optional()
|
|
1809
|
+
}).describe("Pagination information.").optional()
|
|
1810
|
+
}).describe("Linear action output.");
|
|
1811
|
+
var removeIssueLabelInput = external_exports.strictObject({
|
|
1812
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1813
|
+
label_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1814
|
+
}).describe("The input payload for this action.");
|
|
1815
|
+
var removeIssueLabelOutput = external_exports.looseObject({
|
|
1816
|
+
issue_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1817
|
+
label_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1818
|
+
removed: external_exports.boolean().optional()
|
|
1819
|
+
}).describe("Linear action output.");
|
|
1820
|
+
var removeReactionInput = external_exports.strictObject({
|
|
1821
|
+
reaction_id: external_exports.string().min(1).describe("Linear resource ID.")
|
|
1822
|
+
}).describe("The input payload for this action.");
|
|
1823
|
+
var removeReactionOutput = external_exports.looseObject({
|
|
1824
|
+
reaction_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1825
|
+
removed: external_exports.boolean().optional()
|
|
1826
|
+
}).describe("Linear action output.");
|
|
1827
|
+
var runQueryInput = external_exports.strictObject({
|
|
1828
|
+
query: external_exports.string().min(1),
|
|
1829
|
+
variables: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1830
|
+
}).describe("The input payload for this action.");
|
|
1831
|
+
var runQueryOutput = external_exports.looseObject({
|
|
1832
|
+
data: external_exports.looseObject({}).describe("Linear API object.").nullable().optional(),
|
|
1833
|
+
errors: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("GraphQL errors.").optional(),
|
|
1834
|
+
extensions: external_exports.looseObject({}).describe("Linear API object.").optional(),
|
|
1835
|
+
message: external_exports.string().describe("Summarized execution status.").optional()
|
|
1836
|
+
}).describe("Raw GraphQL response.");
|
|
1837
|
+
var runMutationInput = external_exports.strictObject({
|
|
1838
|
+
mutation: external_exports.string().min(1),
|
|
1839
|
+
variables: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1840
|
+
}).describe("The input payload for this action.");
|
|
1841
|
+
var runMutationOutput = external_exports.looseObject({
|
|
1842
|
+
data: external_exports.looseObject({}).describe("Linear API object.").nullable().optional(),
|
|
1843
|
+
errors: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).describe("GraphQL errors.").optional(),
|
|
1844
|
+
extensions: external_exports.looseObject({}).describe("Linear API object.").optional(),
|
|
1845
|
+
message: external_exports.string().describe("Summarized execution status.").optional()
|
|
1846
|
+
}).describe("Raw GraphQL response.");
|
|
1847
|
+
var searchIssuesInput = external_exports.strictObject({
|
|
1848
|
+
query: external_exports.string().min(1).describe("Search query."),
|
|
1849
|
+
after: external_exports.string().describe("Pagination cursor.").optional(),
|
|
1850
|
+
first: external_exports.int().min(1).describe("Number of records to return.").optional(),
|
|
1851
|
+
include_archived: external_exports.boolean().describe("Include archived issues.").optional()
|
|
1852
|
+
}).describe("The input payload for this action.");
|
|
1853
|
+
var searchIssuesOutput = external_exports.looseObject({
|
|
1854
|
+
issues: external_exports.array(external_exports.looseObject({}).describe("Linear API object.")).optional(),
|
|
1855
|
+
page_info: external_exports.looseObject({
|
|
1856
|
+
startCursor: external_exports.string().describe("Previous-page start cursor.").nullable().optional(),
|
|
1857
|
+
endCursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1858
|
+
hasPreviousPage: external_exports.boolean().describe("Whether a previous page exists.").optional(),
|
|
1859
|
+
hasNextPage: external_exports.boolean().describe("Whether a next page exists.").optional(),
|
|
1860
|
+
end_cursor: external_exports.string().describe("Next-page end cursor.").nullable().optional(),
|
|
1861
|
+
has_next_page: external_exports.boolean().describe("Whether a next page exists.").optional()
|
|
1862
|
+
}).describe("Pagination information.").optional(),
|
|
1863
|
+
total_count: external_exports.int().optional()
|
|
1864
|
+
}).describe("Linear action output.");
|
|
1865
|
+
var updateIssueInput = external_exports.strictObject({
|
|
1866
|
+
issueId: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1867
|
+
title: external_exports.string().describe("Issue title.").optional(),
|
|
1868
|
+
teamId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1869
|
+
cycleId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1870
|
+
dueDate: external_exports.string().describe("Issue due date.").optional(),
|
|
1871
|
+
stateId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1872
|
+
estimate: external_exports.number().describe("Issue estimate.").optional(),
|
|
1873
|
+
labelIds: external_exports.array(external_exports.string().min(1).describe("Linear resource ID.")).describe("Label IDs.").optional(),
|
|
1874
|
+
parentId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1875
|
+
priority: external_exports.number().describe("Issue priority.").optional(),
|
|
1876
|
+
projectId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1877
|
+
assigneeId: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1878
|
+
description: external_exports.string().describe("Issue description in Markdown.").optional()
|
|
1879
|
+
}).describe("The input payload for this action.");
|
|
1880
|
+
var updateIssueOutput = external_exports.looseObject({
|
|
1881
|
+
issue: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1882
|
+
}).describe("Linear action output.");
|
|
1883
|
+
var updateLinearCommentInput = external_exports.strictObject({
|
|
1884
|
+
comment_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1885
|
+
body: external_exports.string().min(1)
|
|
1886
|
+
}).describe("The input payload for this action.");
|
|
1887
|
+
var updateLinearCommentOutput = external_exports.looseObject({
|
|
1888
|
+
comment: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1889
|
+
}).describe("Linear action output.");
|
|
1890
|
+
var updateLinearProjectInput = external_exports.strictObject({
|
|
1891
|
+
project_id: external_exports.string().min(1).describe("Linear resource ID."),
|
|
1892
|
+
icon: external_exports.string().describe("Project icon.").optional(),
|
|
1893
|
+
name: external_exports.string().min(1).describe("Project name.").optional(),
|
|
1894
|
+
color: external_exports.string().describe("Project color.").optional(),
|
|
1895
|
+
lead_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1896
|
+
priority: external_exports.number().describe("Project priority.").optional(),
|
|
1897
|
+
status_id: external_exports.string().min(1).describe("Linear resource ID.").optional(),
|
|
1898
|
+
state: external_exports.string().describe("Project state type.").optional(),
|
|
1899
|
+
start_date: external_exports.string().describe("Project start date.").optional(),
|
|
1900
|
+
description: external_exports.string().describe("Project description.").optional(),
|
|
1901
|
+
target_date: external_exports.string().describe("Project target date.").optional()
|
|
1902
|
+
}).describe("The input payload for this action.");
|
|
1903
|
+
var updateLinearProjectOutput = external_exports.looseObject({
|
|
1904
|
+
project: external_exports.looseObject({}).describe("Linear API object.").optional()
|
|
1905
|
+
}).describe("Linear action output.");
|
|
1906
|
+
var linearActions = {
|
|
1907
|
+
create_attachment: {
|
|
1908
|
+
description: "Create or update an attachment for the specified Linear issue.",
|
|
1909
|
+
effect: "write",
|
|
1910
|
+
inputSchema: createAttachmentInput,
|
|
1911
|
+
outputSchema: external_exports.toJSONSchema(createAttachmentOutput, { io: "output", unrepresentable: "any" })
|
|
1912
|
+
},
|
|
1913
|
+
create_comment_reaction: {
|
|
1914
|
+
description: "Creates an emoji reaction for the specified Linear comment.",
|
|
1915
|
+
effect: "write",
|
|
1916
|
+
inputSchema: createCommentReactionInput,
|
|
1917
|
+
outputSchema: external_exports.toJSONSchema(createCommentReactionOutput, { io: "output", unrepresentable: "any" })
|
|
1918
|
+
},
|
|
1919
|
+
create_linear_comment: {
|
|
1920
|
+
description: "Creates a comment for the specified Linear issue.",
|
|
1921
|
+
effect: "write",
|
|
1922
|
+
inputSchema: createLinearCommentInput,
|
|
1923
|
+
outputSchema: external_exports.toJSONSchema(createLinearCommentOutput, { io: "output", unrepresentable: "any" })
|
|
1924
|
+
},
|
|
1925
|
+
create_linear_issue: {
|
|
1926
|
+
description: "Create a new Linear issue in the specified team and support fields such as project, person in charge, status, label, etc.",
|
|
1927
|
+
effect: "write",
|
|
1928
|
+
inputSchema: createLinearIssueInput,
|
|
1929
|
+
outputSchema: external_exports.toJSONSchema(createLinearIssueOutput, { io: "output", unrepresentable: "any" })
|
|
1930
|
+
},
|
|
1931
|
+
create_linear_issue_relation: {
|
|
1932
|
+
description: "Create a relationship between two Linear issues, such as blocks, related, or duplicate.",
|
|
1933
|
+
effect: "write",
|
|
1934
|
+
inputSchema: createLinearIssueRelationInput,
|
|
1935
|
+
outputSchema: external_exports.toJSONSchema(createLinearIssueRelationOutput, { io: "output", unrepresentable: "any" })
|
|
1936
|
+
},
|
|
1937
|
+
create_linear_label: {
|
|
1938
|
+
description: "Creates a new Linear issue label in the specified team.",
|
|
1939
|
+
effect: "write",
|
|
1940
|
+
inputSchema: createLinearLabelInput,
|
|
1941
|
+
outputSchema: external_exports.toJSONSchema(createLinearLabelOutput, { io: "output", unrepresentable: "any" })
|
|
1942
|
+
},
|
|
1943
|
+
create_linear_project: {
|
|
1944
|
+
description: "Create a new Linear project and associate one or more teams.",
|
|
1945
|
+
effect: "write",
|
|
1946
|
+
inputSchema: createLinearProjectInput,
|
|
1947
|
+
outputSchema: external_exports.toJSONSchema(createLinearProjectOutput, { io: "output", unrepresentable: "any" })
|
|
1948
|
+
},
|
|
1949
|
+
create_project_milestone: {
|
|
1950
|
+
description: "Creates a project milestone for the specified Linear project.",
|
|
1951
|
+
effect: "write",
|
|
1952
|
+
inputSchema: createProjectMilestoneInput,
|
|
1953
|
+
outputSchema: external_exports.toJSONSchema(createProjectMilestoneOutput, { io: "output", unrepresentable: "any" })
|
|
1954
|
+
},
|
|
1955
|
+
create_project_update: {
|
|
1956
|
+
description: "Creates a project progress update for the specified Linear project.",
|
|
1957
|
+
effect: "write",
|
|
1958
|
+
inputSchema: createProjectUpdateInput,
|
|
1959
|
+
outputSchema: external_exports.toJSONSchema(createProjectUpdateOutput, { io: "output", unrepresentable: "any" })
|
|
1960
|
+
},
|
|
1961
|
+
delete_linear_issue: {
|
|
1962
|
+
description: "Delete the specified Linear issue.",
|
|
1963
|
+
effect: "destructive",
|
|
1964
|
+
inputSchema: deleteLinearIssueInput,
|
|
1965
|
+
outputSchema: external_exports.toJSONSchema(deleteLinearIssueOutput, { io: "output", unrepresentable: "any" })
|
|
1966
|
+
},
|
|
1967
|
+
get_all_linear_teams: {
|
|
1968
|
+
description: "Lists all Linear team basic information accessible with the current credentials.",
|
|
1969
|
+
effect: "read",
|
|
1970
|
+
inputSchema: getAllLinearTeamsInput,
|
|
1971
|
+
outputSchema: external_exports.toJSONSchema(getAllLinearTeamsOutput, { io: "output", unrepresentable: "any" })
|
|
1972
|
+
},
|
|
1973
|
+
get_attachment: {
|
|
1974
|
+
description: "Retrieve a Linear attachment based on the issue and attachment ID or file name.",
|
|
1975
|
+
effect: "read",
|
|
1976
|
+
inputSchema: getAttachmentInput,
|
|
1977
|
+
outputSchema: external_exports.toJSONSchema(getAttachmentOutput, { io: "output", unrepresentable: "any" })
|
|
1978
|
+
},
|
|
1979
|
+
get_current_user: {
|
|
1980
|
+
description: "Get the currently authenticated Linear user profile.",
|
|
1981
|
+
effect: "read",
|
|
1982
|
+
inputSchema: getCurrentUserInput,
|
|
1983
|
+
outputSchema: external_exports.toJSONSchema(getCurrentUserOutput, { io: "output", unrepresentable: "any" })
|
|
1984
|
+
},
|
|
1985
|
+
get_cycles_by_team_id: {
|
|
1986
|
+
description: "Get all cycle information under the specified team.",
|
|
1987
|
+
effect: "read",
|
|
1988
|
+
inputSchema: getCyclesByTeamIdInput,
|
|
1989
|
+
outputSchema: external_exports.toJSONSchema(getCyclesByTeamIdOutput, { io: "output", unrepresentable: "any" })
|
|
1990
|
+
},
|
|
1991
|
+
get_issue_defaults: {
|
|
1992
|
+
description: "Gets the default status and default estimate used when the specified team creates an issue.",
|
|
1993
|
+
effect: "read",
|
|
1994
|
+
inputSchema: getIssueDefaultsInput,
|
|
1995
|
+
outputSchema: external_exports.toJSONSchema(getIssueDefaultsOutput, { io: "output", unrepresentable: "any" })
|
|
1996
|
+
},
|
|
1997
|
+
get_linear_issue: {
|
|
1998
|
+
description: "Get details of a Linear issue, including comments, attachments, subscribers, and underlying relationship fields.",
|
|
1999
|
+
effect: "read",
|
|
2000
|
+
inputSchema: getLinearIssueInput,
|
|
2001
|
+
outputSchema: external_exports.toJSONSchema(getLinearIssueOutput, { io: "output", unrepresentable: "any" })
|
|
2002
|
+
},
|
|
2003
|
+
get_linear_project: {
|
|
2004
|
+
description: "Get the details of a Linear project, complete with team, members, and initiatives on demand.",
|
|
2005
|
+
effect: "read",
|
|
2006
|
+
inputSchema: getLinearProjectInput,
|
|
2007
|
+
outputSchema: external_exports.toJSONSchema(getLinearProjectOutput, { io: "output", unrepresentable: "any" })
|
|
2008
|
+
},
|
|
2009
|
+
list_issues_by_team_id: {
|
|
2010
|
+
description: "List Linear issues by team, and support cursor paging and whether to include archived issues.",
|
|
2011
|
+
effect: "read",
|
|
2012
|
+
inputSchema: listIssuesByTeamIdInput,
|
|
2013
|
+
outputSchema: external_exports.toJSONSchema(listIssuesByTeamIdOutput, { io: "output", unrepresentable: "any" })
|
|
2014
|
+
},
|
|
2015
|
+
list_issue_drafts: {
|
|
2016
|
+
description: "Lists issue drafts visible to the current user in Linear.",
|
|
2017
|
+
effect: "read",
|
|
2018
|
+
inputSchema: listIssueDraftsInput,
|
|
2019
|
+
outputSchema: external_exports.toJSONSchema(listIssueDraftsOutput, { io: "output", unrepresentable: "any" })
|
|
2020
|
+
},
|
|
2021
|
+
list_linear_cycles: {
|
|
2022
|
+
description: "Lists the Linear periods accessible by the current credential.",
|
|
2023
|
+
effect: "read",
|
|
2024
|
+
inputSchema: listLinearCyclesInput,
|
|
2025
|
+
outputSchema: external_exports.toJSONSchema(listLinearCyclesOutput, { io: "output", unrepresentable: "any" })
|
|
2026
|
+
},
|
|
2027
|
+
list_linear_issues: {
|
|
2028
|
+
description: "Lists Linear issues accessible with current credentials, and supports filtering by project and person in charge.",
|
|
2029
|
+
effect: "read",
|
|
2030
|
+
inputSchema: listLinearIssuesInput,
|
|
2031
|
+
outputSchema: external_exports.toJSONSchema(listLinearIssuesOutput, { io: "output", unrepresentable: "any" })
|
|
2032
|
+
},
|
|
2033
|
+
list_linear_labels: {
|
|
2034
|
+
description: "Lists Linear labels for a specified team or entire workspace.",
|
|
2035
|
+
effect: "read",
|
|
2036
|
+
inputSchema: listLinearLabelsInput,
|
|
2037
|
+
outputSchema: external_exports.toJSONSchema(listLinearLabelsOutput, { io: "output", unrepresentable: "any" })
|
|
2038
|
+
},
|
|
2039
|
+
list_linear_projects: {
|
|
2040
|
+
description: "Lists Linear projects accessible with the current credentials.",
|
|
2041
|
+
effect: "read",
|
|
2042
|
+
inputSchema: listLinearProjectsInput,
|
|
2043
|
+
outputSchema: external_exports.toJSONSchema(listLinearProjectsOutput, { io: "output", unrepresentable: "any" })
|
|
2044
|
+
},
|
|
2045
|
+
list_linear_states: {
|
|
2046
|
+
description: "Lists all workflow statuses for the specified team.",
|
|
2047
|
+
effect: "read",
|
|
2048
|
+
inputSchema: listLinearStatesInput,
|
|
2049
|
+
outputSchema: external_exports.toJSONSchema(listLinearStatesOutput, { io: "output", unrepresentable: "any" })
|
|
2050
|
+
},
|
|
2051
|
+
list_linear_teams: {
|
|
2052
|
+
description: "Lists Linear teams accessible with current credentials, along with a list of members and projects.",
|
|
2053
|
+
effect: "read",
|
|
2054
|
+
inputSchema: listLinearTeamsInput,
|
|
2055
|
+
outputSchema: external_exports.toJSONSchema(listLinearTeamsOutput, { io: "output", unrepresentable: "any" })
|
|
2056
|
+
},
|
|
2057
|
+
list_linear_users: {
|
|
2058
|
+
description: "List Linear users in the current workspace and support cursor paging.",
|
|
2059
|
+
effect: "read",
|
|
2060
|
+
inputSchema: listLinearUsersInput,
|
|
2061
|
+
outputSchema: external_exports.toJSONSchema(listLinearUsersOutput, { io: "output", unrepresentable: "any" })
|
|
2062
|
+
},
|
|
2063
|
+
remove_issue_label: {
|
|
2064
|
+
description: "Removes a label from the specified Linear issue.",
|
|
2065
|
+
effect: "destructive",
|
|
2066
|
+
inputSchema: removeIssueLabelInput,
|
|
2067
|
+
outputSchema: external_exports.toJSONSchema(removeIssueLabelOutput, { io: "output", unrepresentable: "any" })
|
|
2068
|
+
},
|
|
2069
|
+
remove_reaction: {
|
|
2070
|
+
description: "Delete an existing Linear reaction.",
|
|
2071
|
+
effect: "destructive",
|
|
2072
|
+
inputSchema: removeReactionInput,
|
|
2073
|
+
outputSchema: external_exports.toJSONSchema(removeReactionOutput, { io: "output", unrepresentable: "any" })
|
|
2074
|
+
},
|
|
2075
|
+
run_query: {
|
|
2076
|
+
description: "Execute a read-only query directly against the Linear GraphQL API.",
|
|
2077
|
+
effect: "write",
|
|
2078
|
+
inputSchema: runQueryInput,
|
|
2079
|
+
outputSchema: external_exports.toJSONSchema(runQueryOutput, { io: "output", unrepresentable: "any" })
|
|
2080
|
+
},
|
|
2081
|
+
run_mutation: {
|
|
2082
|
+
description: "Perform a mutation directly on the Linear GraphQL API.",
|
|
2083
|
+
effect: "write",
|
|
2084
|
+
inputSchema: runMutationInput,
|
|
2085
|
+
outputSchema: external_exports.toJSONSchema(runMutationOutput, { io: "output", unrepresentable: "any" })
|
|
2086
|
+
},
|
|
2087
|
+
search_issues: {
|
|
2088
|
+
description: "Retrieve issues through Linear's full-text search capabilities.",
|
|
2089
|
+
effect: "read",
|
|
2090
|
+
inputSchema: searchIssuesInput,
|
|
2091
|
+
outputSchema: external_exports.toJSONSchema(searchIssuesOutput, { io: "output", unrepresentable: "any" })
|
|
2092
|
+
},
|
|
2093
|
+
update_issue: {
|
|
2094
|
+
description: "Update an existing Linear issue and support fields such as title, description, status, project, label, etc.",
|
|
2095
|
+
effect: "write",
|
|
2096
|
+
inputSchema: updateIssueInput,
|
|
2097
|
+
outputSchema: external_exports.toJSONSchema(updateIssueOutput, { io: "output", unrepresentable: "any" })
|
|
2098
|
+
},
|
|
2099
|
+
update_linear_comment: {
|
|
2100
|
+
description: "Update the text of an existing Linear comment.",
|
|
2101
|
+
effect: "write",
|
|
2102
|
+
inputSchema: updateLinearCommentInput,
|
|
2103
|
+
outputSchema: external_exports.toJSONSchema(updateLinearCommentOutput, { io: "output", unrepresentable: "any" })
|
|
2104
|
+
},
|
|
2105
|
+
update_linear_project: {
|
|
2106
|
+
description: "Update an existing Linear project.",
|
|
2107
|
+
effect: "write",
|
|
2108
|
+
inputSchema: updateLinearProjectInput,
|
|
2109
|
+
outputSchema: external_exports.toJSONSchema(updateLinearProjectOutput, { io: "output", unrepresentable: "any" })
|
|
2110
|
+
}
|
|
2111
|
+
};
|
|
2112
|
+
|
|
2113
|
+
// ../plugins/src/linear/index.ts
|
|
2114
|
+
function createLinearPlugin() {
|
|
2115
|
+
return createProviderPlugin({
|
|
2116
|
+
description: "Linear",
|
|
2117
|
+
actions: linearActions,
|
|
2118
|
+
// 上游两个 credentialValidators(apiKey 与 oauth2)都打 `viewer` 查询 —— 只读、
|
|
2119
|
+
// 入参 schema 是空对象,正好当挂载时的凭证探针。
|
|
2120
|
+
credentialProbe: "get_current_user",
|
|
2121
|
+
handlers: {
|
|
2122
|
+
create_attachment: createAttachment,
|
|
2123
|
+
create_comment_reaction: createCommentReaction,
|
|
2124
|
+
create_linear_comment: createLinearComment,
|
|
2125
|
+
create_linear_issue: createLinearIssue,
|
|
2126
|
+
create_linear_issue_relation: createLinearIssueRelation,
|
|
2127
|
+
create_linear_label: createLinearLabel,
|
|
2128
|
+
create_linear_project: createLinearProject,
|
|
2129
|
+
create_project_milestone: createProjectMilestone,
|
|
2130
|
+
create_project_update: createProjectUpdate,
|
|
2131
|
+
delete_linear_issue: deleteLinearIssue,
|
|
2132
|
+
get_all_linear_teams: getAllLinearTeams,
|
|
2133
|
+
get_attachment: getAttachment,
|
|
2134
|
+
get_current_user: getCurrentUser,
|
|
2135
|
+
get_cycles_by_team_id: getCyclesByTeamId,
|
|
2136
|
+
get_issue_defaults: getIssueDefaults,
|
|
2137
|
+
get_linear_issue: getLinearIssue,
|
|
2138
|
+
get_linear_project: getLinearProject,
|
|
2139
|
+
list_issue_drafts: listIssueDrafts,
|
|
2140
|
+
list_issues_by_team_id: listIssuesByTeamId,
|
|
2141
|
+
list_linear_cycles: listLinearCycles,
|
|
2142
|
+
list_linear_issues: listLinearIssues,
|
|
2143
|
+
list_linear_labels: listLinearLabels,
|
|
2144
|
+
list_linear_projects: listLinearProjects,
|
|
2145
|
+
list_linear_states: listLinearStates,
|
|
2146
|
+
list_linear_teams: listLinearTeams,
|
|
2147
|
+
list_linear_users: listLinearUsers,
|
|
2148
|
+
remove_issue_label: removeIssueLabel,
|
|
2149
|
+
remove_reaction: removeReaction,
|
|
2150
|
+
run_mutation: runMutation,
|
|
2151
|
+
run_query: runQuery,
|
|
2152
|
+
search_issues: searchIssues,
|
|
2153
|
+
update_issue: updateIssue,
|
|
2154
|
+
update_linear_comment: updateLinearComment,
|
|
2155
|
+
update_linear_project: updateLinearProject
|
|
2156
|
+
}
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
var linear_default = createLinearPlugin();
|
|
2160
|
+
export {
|
|
2161
|
+
createLinearPlugin,
|
|
2162
|
+
linear_default as default
|
|
2163
|
+
};
|