convex-linear 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +438 -0
- package/dist/client/_generated/_ignore.d.ts +1 -0
- package/dist/client/_generated/_ignore.d.ts.map +1 -0
- package/dist/client/_generated/_ignore.js +3 -0
- package/dist/client/_generated/_ignore.js.map +1 -0
- package/dist/client/index.d.ts +163 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +316 -0
- package/dist/client/index.js.map +1 -0
- package/dist/component/_generated/api.d.ts +34 -0
- package/dist/component/_generated/api.d.ts.map +1 -0
- package/dist/component/_generated/api.js +31 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/component.d.ts +170 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +46 -0
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +133 -0
- package/dist/component/_generated/server.d.ts.map +1 -0
- package/dist/component/_generated/server.js +80 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/convex.config.d.ts +3 -0
- package/dist/component/convex.config.d.ts.map +1 -0
- package/dist/component/convex.config.js +4 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/lib.d.ts +146 -0
- package/dist/component/lib.d.ts.map +1 -0
- package/dist/component/lib.js +258 -0
- package/dist/component/lib.js.map +1 -0
- package/dist/component/schema.d.ts +75 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/component/schema.js +51 -0
- package/dist/component/schema.js.map +1 -0
- package/package.json +105 -0
- package/src/client/_generated/_ignore.ts +1 -0
- package/src/client/index.ts +460 -0
- package/src/client/setup.test.ts +26 -0
- package/src/component/_generated/api.ts +50 -0
- package/src/component/_generated/component.ts +224 -0
- package/src/component/_generated/dataModel.ts +60 -0
- package/src/component/_generated/server.ts +169 -0
- package/src/component/convex.config.ts +5 -0
- package/src/component/lib.test.ts +191 -0
- package/src/component/lib.ts +280 -0
- package/src/component/schema.ts +53 -0
- package/src/component/setup.test.ts +11 -0
- package/src/test.ts +18 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { httpActionGeneric } from "convex/server";
|
|
2
|
+
import type { GenericActionCtx, GenericDataModel } from "convex/server";
|
|
3
|
+
import type { ComponentApi } from "../component/_generated/component.js";
|
|
4
|
+
export type LinearOptions = {
|
|
5
|
+
/** A personal API key or OAuth access token for the Linear GraphQL API. */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
webhookSecret: string;
|
|
8
|
+
};
|
|
9
|
+
export type CreateIssueArgs = {
|
|
10
|
+
teamId: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
priority?: number;
|
|
14
|
+
assigneeId?: string;
|
|
15
|
+
labelIds?: string[];
|
|
16
|
+
};
|
|
17
|
+
export type UpdateIssueArgs = {
|
|
18
|
+
issueId: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
stateId?: string;
|
|
22
|
+
priority?: number;
|
|
23
|
+
assigneeId?: string;
|
|
24
|
+
labelIds?: string[];
|
|
25
|
+
};
|
|
26
|
+
export declare class Linear {
|
|
27
|
+
private component;
|
|
28
|
+
private options;
|
|
29
|
+
webhookHandler: ReturnType<typeof httpActionGeneric>;
|
|
30
|
+
constructor(component: ComponentApi, options: LinearOptions);
|
|
31
|
+
private headers;
|
|
32
|
+
private graphql;
|
|
33
|
+
createIssue(ctx: GenericActionCtx<GenericDataModel>, args: CreateIssueArgs): Promise<{
|
|
34
|
+
identifier: string;
|
|
35
|
+
url: string;
|
|
36
|
+
}>;
|
|
37
|
+
updateIssue(ctx: GenericActionCtx<GenericDataModel>, args: UpdateIssueArgs): Promise<void>;
|
|
38
|
+
createComment(ctx: GenericActionCtx<GenericDataModel>, args: {
|
|
39
|
+
issueId: string;
|
|
40
|
+
body: string;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
id: string;
|
|
43
|
+
}>;
|
|
44
|
+
archiveIssue(ctx: GenericActionCtx<GenericDataModel>, args: {
|
|
45
|
+
issueId: string;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
unarchiveIssue(ctx: GenericActionCtx<GenericDataModel>, args: {
|
|
48
|
+
issueId: string;
|
|
49
|
+
}): Promise<void>;
|
|
50
|
+
getIssue(ctx: RunQueryCtx, args: {
|
|
51
|
+
issueId: string;
|
|
52
|
+
}): Promise<{
|
|
53
|
+
_creationTime: number;
|
|
54
|
+
_id: string;
|
|
55
|
+
archivedAt?: number;
|
|
56
|
+
assigneeId?: string;
|
|
57
|
+
assigneeName?: string;
|
|
58
|
+
createdAt: number;
|
|
59
|
+
description?: string;
|
|
60
|
+
identifier: string;
|
|
61
|
+
issueId: string;
|
|
62
|
+
labels?: Array<string>;
|
|
63
|
+
priority?: number;
|
|
64
|
+
state: string;
|
|
65
|
+
teamId: string;
|
|
66
|
+
title: string;
|
|
67
|
+
trashed?: boolean;
|
|
68
|
+
updatedAt: number;
|
|
69
|
+
url: string;
|
|
70
|
+
} | null>;
|
|
71
|
+
listIssuesByTeam(ctx: RunQueryCtx, args: {
|
|
72
|
+
teamId: string;
|
|
73
|
+
limit?: number;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
_creationTime: number;
|
|
76
|
+
_id: string;
|
|
77
|
+
archivedAt?: number;
|
|
78
|
+
assigneeId?: string;
|
|
79
|
+
assigneeName?: string;
|
|
80
|
+
createdAt: number;
|
|
81
|
+
description?: string;
|
|
82
|
+
identifier: string;
|
|
83
|
+
issueId: string;
|
|
84
|
+
labels?: Array<string>;
|
|
85
|
+
priority?: number;
|
|
86
|
+
state: string;
|
|
87
|
+
teamId: string;
|
|
88
|
+
title: string;
|
|
89
|
+
trashed?: boolean;
|
|
90
|
+
updatedAt: number;
|
|
91
|
+
url: string;
|
|
92
|
+
}[]>;
|
|
93
|
+
listCommentsByIssue(ctx: RunQueryCtx, args: {
|
|
94
|
+
issueId: string;
|
|
95
|
+
limit?: number;
|
|
96
|
+
}): Promise<{
|
|
97
|
+
_creationTime: number;
|
|
98
|
+
_id: string;
|
|
99
|
+
body: string;
|
|
100
|
+
commentId: string;
|
|
101
|
+
createdAt: number;
|
|
102
|
+
issueId: string;
|
|
103
|
+
updatedAt: number;
|
|
104
|
+
userId?: string;
|
|
105
|
+
userName?: string;
|
|
106
|
+
}[]>;
|
|
107
|
+
getStats(ctx: RunQueryCtx): Promise<{
|
|
108
|
+
archivedCount: number;
|
|
109
|
+
commentCount: number;
|
|
110
|
+
issueCount: number;
|
|
111
|
+
webhookEventCount: number;
|
|
112
|
+
}>;
|
|
113
|
+
listRecentIssues(ctx: RunQueryCtx, args?: {
|
|
114
|
+
limit?: number;
|
|
115
|
+
}): Promise<{
|
|
116
|
+
_creationTime: number;
|
|
117
|
+
_id: string;
|
|
118
|
+
archivedAt?: number;
|
|
119
|
+
assigneeId?: string;
|
|
120
|
+
assigneeName?: string;
|
|
121
|
+
createdAt: number;
|
|
122
|
+
description?: string;
|
|
123
|
+
identifier: string;
|
|
124
|
+
issueId: string;
|
|
125
|
+
labels?: Array<string>;
|
|
126
|
+
priority?: number;
|
|
127
|
+
state: string;
|
|
128
|
+
teamId: string;
|
|
129
|
+
title: string;
|
|
130
|
+
trashed?: boolean;
|
|
131
|
+
updatedAt: number;
|
|
132
|
+
url: string;
|
|
133
|
+
}[]>;
|
|
134
|
+
listRecentComments(ctx: RunQueryCtx, args?: {
|
|
135
|
+
limit?: number;
|
|
136
|
+
}): Promise<{
|
|
137
|
+
_creationTime: number;
|
|
138
|
+
_id: string;
|
|
139
|
+
body: string;
|
|
140
|
+
commentId: string;
|
|
141
|
+
createdAt: number;
|
|
142
|
+
issueId: string;
|
|
143
|
+
updatedAt: number;
|
|
144
|
+
userId?: string;
|
|
145
|
+
userName?: string;
|
|
146
|
+
}[]>;
|
|
147
|
+
listRecentWebhookEvents(ctx: RunQueryCtx, args?: {
|
|
148
|
+
limit?: number;
|
|
149
|
+
}): Promise<{
|
|
150
|
+
_creationTime: number;
|
|
151
|
+
_id: string;
|
|
152
|
+
action?: string;
|
|
153
|
+
eventId: string;
|
|
154
|
+
eventType: string;
|
|
155
|
+
payload: string;
|
|
156
|
+
receivedAt: number;
|
|
157
|
+
}[]>;
|
|
158
|
+
}
|
|
159
|
+
type RunQueryCtx = {
|
|
160
|
+
runQuery: GenericActionCtx<GenericDataModel>["runQuery"];
|
|
161
|
+
};
|
|
162
|
+
export {};
|
|
163
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { httpActionGeneric } from "convex/server";
|
|
2
|
+
const LINEAR_API_URL = "https://api.linear.app/graphql";
|
|
3
|
+
const WEBHOOK_MAX_CLOCK_SKEW_MS = 60_000;
|
|
4
|
+
function timingSafeEqual(a, b) {
|
|
5
|
+
if (a.length !== b.length)
|
|
6
|
+
return false;
|
|
7
|
+
let mismatch = 0;
|
|
8
|
+
for (let i = 0; i < a.length; i++) {
|
|
9
|
+
mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
10
|
+
}
|
|
11
|
+
return mismatch === 0;
|
|
12
|
+
}
|
|
13
|
+
async function hmacSha256Hex(secret, payload) {
|
|
14
|
+
const enc = new TextEncoder();
|
|
15
|
+
const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
16
|
+
const signature = await crypto.subtle.sign("HMAC", key, enc.encode(payload));
|
|
17
|
+
return Array.from(new Uint8Array(signature))
|
|
18
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
19
|
+
.join("");
|
|
20
|
+
}
|
|
21
|
+
function issueRecordFromFragment(issue) {
|
|
22
|
+
return {
|
|
23
|
+
issueId: issue.id,
|
|
24
|
+
identifier: issue.identifier,
|
|
25
|
+
teamId: issue.team?.id ?? "",
|
|
26
|
+
title: issue.title,
|
|
27
|
+
description: issue.description ?? undefined,
|
|
28
|
+
state: issue.state?.name ?? "Unknown",
|
|
29
|
+
priority: issue.priority ?? undefined,
|
|
30
|
+
assigneeId: issue.assignee?.id,
|
|
31
|
+
assigneeName: issue.assignee?.name,
|
|
32
|
+
labels: issue.labels?.nodes.map((l) => l.name),
|
|
33
|
+
url: issue.url,
|
|
34
|
+
archivedAt: issue.archivedAt ? new Date(issue.archivedAt).getTime() : undefined,
|
|
35
|
+
trashed: issue.trashed ?? undefined,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const ISSUE_FRAGMENT = `
|
|
39
|
+
id
|
|
40
|
+
identifier
|
|
41
|
+
title
|
|
42
|
+
description
|
|
43
|
+
priority
|
|
44
|
+
url
|
|
45
|
+
archivedAt
|
|
46
|
+
trashed
|
|
47
|
+
state { name }
|
|
48
|
+
team { id }
|
|
49
|
+
assignee { id name }
|
|
50
|
+
labels { nodes { name } }
|
|
51
|
+
`;
|
|
52
|
+
// Linear's webhook `action` field for Issue events turns out NOT to reliably
|
|
53
|
+
// distinguish archived / trashed / permanently-deleted:
|
|
54
|
+
// - issueArchive (soft, restorable) -> webhook action "remove"
|
|
55
|
+
// - issueUnarchive (restore from archive) -> webhook action "restore"
|
|
56
|
+
// - moving an issue to the 30-day trash -> webhook action "update"
|
|
57
|
+
// (confirmed by live testing against Linear's real API — not documented
|
|
58
|
+
// this precisely anywhere). None of these deliveries include archivedAt or
|
|
59
|
+
// trashed on their own `data` payload either. So instead of branching on
|
|
60
|
+
// `action`, every Issue webhook re-fetches the issue's current state
|
|
61
|
+
// straight from Linear's API and mirrors that — the payload's `action` is
|
|
62
|
+
// still recorded on the webhookEvents row for auditing, but the *only*
|
|
63
|
+
// thing that decides a hard local delete is the issue genuinely no longer
|
|
64
|
+
// existing when re-fetched (a real "Entity not found" from the API, e.g.
|
|
65
|
+
// after the 30-day trash window elapses).
|
|
66
|
+
async function fetchIssueOrNull(apiKey, issueId) {
|
|
67
|
+
const res = await fetch(LINEAR_API_URL, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
Authorization: apiKey,
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({
|
|
74
|
+
query: `query($id: String!) { issue(id: $id) { ${ISSUE_FRAGMENT} } }`,
|
|
75
|
+
variables: { id: issueId },
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
const json = (await res.json());
|
|
79
|
+
if (json.errors) {
|
|
80
|
+
const notFound = json.errors.some((e) => /not found/i.test(e.message));
|
|
81
|
+
if (notFound)
|
|
82
|
+
return null;
|
|
83
|
+
throw new Error(`Linear API error: ${json.errors.map((e) => e.message).join("; ")}`);
|
|
84
|
+
}
|
|
85
|
+
return json.data?.issue ?? null;
|
|
86
|
+
}
|
|
87
|
+
export class Linear {
|
|
88
|
+
component;
|
|
89
|
+
options;
|
|
90
|
+
webhookHandler;
|
|
91
|
+
constructor(component, options) {
|
|
92
|
+
this.component = component;
|
|
93
|
+
this.options = options;
|
|
94
|
+
const component_ = component;
|
|
95
|
+
const webhookSecret = options.webhookSecret;
|
|
96
|
+
const apiKey = options.apiKey;
|
|
97
|
+
this.webhookHandler = httpActionGeneric(async (ctx, request) => {
|
|
98
|
+
const rawBody = await request.text();
|
|
99
|
+
const signatureHeader = request.headers.get("linear-signature");
|
|
100
|
+
const deliveryId = request.headers.get("linear-delivery");
|
|
101
|
+
const eventType = request.headers.get("linear-event");
|
|
102
|
+
const timestampHeader = request.headers.get("linear-timestamp");
|
|
103
|
+
if (!signatureHeader || !deliveryId || !eventType) {
|
|
104
|
+
return new Response(JSON.stringify({ error: "Missing Linear webhook headers" }), {
|
|
105
|
+
status: 400,
|
|
106
|
+
headers: { "Content-Type": "application/json" },
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const expected = await hmacSha256Hex(webhookSecret, rawBody);
|
|
110
|
+
if (!timingSafeEqual(expected, signatureHeader)) {
|
|
111
|
+
console.error("convex-linear: webhook signature mismatch");
|
|
112
|
+
return new Response(JSON.stringify({ error: "Invalid signature" }), {
|
|
113
|
+
status: 401,
|
|
114
|
+
headers: { "Content-Type": "application/json" },
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const timestamp = timestampHeader ? Number(timestampHeader) : NaN;
|
|
118
|
+
if (!Number.isFinite(timestamp) || Math.abs(Date.now() - timestamp) > WEBHOOK_MAX_CLOCK_SKEW_MS) {
|
|
119
|
+
console.error("convex-linear: webhook timestamp outside allowed clock skew");
|
|
120
|
+
return new Response(JSON.stringify({ error: "Stale webhook timestamp" }), {
|
|
121
|
+
status: 400,
|
|
122
|
+
headers: { "Content-Type": "application/json" },
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const payload = JSON.parse(rawBody);
|
|
126
|
+
const action = payload.action ?? undefined;
|
|
127
|
+
const { alreadyProcessed } = await ctx.runMutation(component_.lib.checkAndRecordEvent, {
|
|
128
|
+
eventId: deliveryId,
|
|
129
|
+
eventType,
|
|
130
|
+
action,
|
|
131
|
+
payload: rawBody,
|
|
132
|
+
});
|
|
133
|
+
if (alreadyProcessed) {
|
|
134
|
+
return new Response(JSON.stringify({ success: true, duplicate: true }), {
|
|
135
|
+
status: 200,
|
|
136
|
+
headers: { "Content-Type": "application/json" },
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const data = payload.data;
|
|
140
|
+
if (eventType === "Issue" && data) {
|
|
141
|
+
// See the comment on fetchIssueOrNull above: `action` alone can't
|
|
142
|
+
// tell us whether this issue is still active, archived, trashed, or
|
|
143
|
+
// truly gone, so every delivery re-fetches ground truth instead.
|
|
144
|
+
const fresh = await fetchIssueOrNull(apiKey, String(data.id));
|
|
145
|
+
if (fresh === null) {
|
|
146
|
+
await ctx.runMutation(component_.lib.removeIssue, { issueId: String(data.id) });
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
await ctx.runMutation(component_.lib.recordIssue, issueRecordFromFragment(fresh));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (eventType === "Comment" && data) {
|
|
153
|
+
if (action !== "remove") {
|
|
154
|
+
const issue = data.issue;
|
|
155
|
+
const user = data.user;
|
|
156
|
+
await ctx.runMutation(component_.lib.recordComment, {
|
|
157
|
+
commentId: String(data.id),
|
|
158
|
+
issueId: issue?.id ?? String(data.issueId ?? ""),
|
|
159
|
+
body: data.body ?? "",
|
|
160
|
+
userId: user?.id ?? undefined,
|
|
161
|
+
userName: user?.name ?? undefined,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return new Response(JSON.stringify({ success: true }), {
|
|
166
|
+
status: 200,
|
|
167
|
+
headers: { "Content-Type": "application/json" },
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
headers() {
|
|
172
|
+
// Linear personal API keys are sent as-is in the Authorization header —
|
|
173
|
+
// unlike OAuth access tokens, they do NOT take a "Bearer " prefix.
|
|
174
|
+
return {
|
|
175
|
+
"Content-Type": "application/json",
|
|
176
|
+
Authorization: this.options.apiKey,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
async graphql(query, variables) {
|
|
180
|
+
const res = await fetch(LINEAR_API_URL, {
|
|
181
|
+
method: "POST",
|
|
182
|
+
headers: this.headers(),
|
|
183
|
+
body: JSON.stringify({ query, variables }),
|
|
184
|
+
});
|
|
185
|
+
const json = (await res.json());
|
|
186
|
+
if (!res.ok || json.errors) {
|
|
187
|
+
const message = json.errors?.map((e) => e.message).join("; ") ?? res.statusText;
|
|
188
|
+
throw new Error(`Linear API error: ${message}`);
|
|
189
|
+
}
|
|
190
|
+
return json.data;
|
|
191
|
+
}
|
|
192
|
+
async createIssue(ctx, args) {
|
|
193
|
+
const data = await this.graphql(`mutation IssueCreate($input: IssueCreateInput!) {
|
|
194
|
+
issueCreate(input: $input) {
|
|
195
|
+
success
|
|
196
|
+
issue { ${ISSUE_FRAGMENT} }
|
|
197
|
+
}
|
|
198
|
+
}`, {
|
|
199
|
+
input: {
|
|
200
|
+
teamId: args.teamId,
|
|
201
|
+
title: args.title,
|
|
202
|
+
description: args.description,
|
|
203
|
+
priority: args.priority,
|
|
204
|
+
assigneeId: args.assigneeId,
|
|
205
|
+
labelIds: args.labelIds,
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
if (!data.issueCreate.success) {
|
|
209
|
+
throw new Error("Linear API error: issueCreate did not succeed");
|
|
210
|
+
}
|
|
211
|
+
const issue = data.issueCreate.issue;
|
|
212
|
+
await ctx.runMutation(this.component.lib.recordIssue, issueRecordFromFragment(issue));
|
|
213
|
+
return { identifier: issue.identifier, url: issue.url };
|
|
214
|
+
}
|
|
215
|
+
async updateIssue(ctx, args) {
|
|
216
|
+
const { issueId, ...rest } = args;
|
|
217
|
+
const data = await this.graphql(`mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) {
|
|
218
|
+
issueUpdate(id: $id, input: $input) {
|
|
219
|
+
success
|
|
220
|
+
issue { ${ISSUE_FRAGMENT} }
|
|
221
|
+
}
|
|
222
|
+
}`, {
|
|
223
|
+
id: issueId,
|
|
224
|
+
input: {
|
|
225
|
+
title: rest.title,
|
|
226
|
+
description: rest.description,
|
|
227
|
+
stateId: rest.stateId,
|
|
228
|
+
priority: rest.priority,
|
|
229
|
+
assigneeId: rest.assigneeId,
|
|
230
|
+
labelIds: rest.labelIds,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
if (!data.issueUpdate.success) {
|
|
234
|
+
throw new Error("Linear API error: issueUpdate did not succeed");
|
|
235
|
+
}
|
|
236
|
+
await ctx.runMutation(this.component.lib.recordIssue, issueRecordFromFragment(data.issueUpdate.issue));
|
|
237
|
+
}
|
|
238
|
+
async createComment(ctx, args) {
|
|
239
|
+
const data = await this.graphql(`mutation CommentCreate($input: CommentCreateInput!) {
|
|
240
|
+
commentCreate(input: $input) {
|
|
241
|
+
success
|
|
242
|
+
comment {
|
|
243
|
+
id
|
|
244
|
+
body
|
|
245
|
+
issue { id }
|
|
246
|
+
user { id name }
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}`, { input: { issueId: args.issueId, body: args.body } });
|
|
250
|
+
if (!data.commentCreate.success) {
|
|
251
|
+
throw new Error("Linear API error: commentCreate did not succeed");
|
|
252
|
+
}
|
|
253
|
+
const comment = data.commentCreate.comment;
|
|
254
|
+
await ctx.runMutation(this.component.lib.recordComment, {
|
|
255
|
+
commentId: comment.id,
|
|
256
|
+
issueId: comment.issue.id,
|
|
257
|
+
body: comment.body,
|
|
258
|
+
userId: comment.user?.id,
|
|
259
|
+
userName: comment.user?.name,
|
|
260
|
+
});
|
|
261
|
+
return { id: comment.id };
|
|
262
|
+
}
|
|
263
|
+
async archiveIssue(ctx, args) {
|
|
264
|
+
const data = await this.graphql(`mutation IssueArchive($id: String!) {
|
|
265
|
+
issueArchive(id: $id) {
|
|
266
|
+
success
|
|
267
|
+
}
|
|
268
|
+
}`, { id: args.issueId });
|
|
269
|
+
if (!data.issueArchive.success) {
|
|
270
|
+
throw new Error("Linear API error: issueArchive did not succeed");
|
|
271
|
+
}
|
|
272
|
+
// Linear archives (soft-hides, restorable), it doesn't delete — mirror
|
|
273
|
+
// that locally instead of dropping the row, so a re-fetch or webhook
|
|
274
|
+
// replay never has to guess whether the issue still exists.
|
|
275
|
+
await ctx.runMutation(this.component.lib.setIssueArchived, {
|
|
276
|
+
issueId: args.issueId,
|
|
277
|
+
archivedAt: Date.now(),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async unarchiveIssue(ctx, args) {
|
|
281
|
+
const data = await this.graphql(`mutation IssueUnarchive($id: String!) {
|
|
282
|
+
issueUnarchive(id: $id) {
|
|
283
|
+
success
|
|
284
|
+
}
|
|
285
|
+
}`, { id: args.issueId });
|
|
286
|
+
if (!data.issueUnarchive.success) {
|
|
287
|
+
throw new Error("Linear API error: issueUnarchive did not succeed");
|
|
288
|
+
}
|
|
289
|
+
await ctx.runMutation(this.component.lib.setIssueArchived, {
|
|
290
|
+
issueId: args.issueId,
|
|
291
|
+
archivedAt: null,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
async getIssue(ctx, args) {
|
|
295
|
+
return await ctx.runQuery(this.component.lib.getIssue, args);
|
|
296
|
+
}
|
|
297
|
+
async listIssuesByTeam(ctx, args) {
|
|
298
|
+
return await ctx.runQuery(this.component.lib.listIssuesByTeam, args);
|
|
299
|
+
}
|
|
300
|
+
async listCommentsByIssue(ctx, args) {
|
|
301
|
+
return await ctx.runQuery(this.component.lib.listCommentsByIssue, args);
|
|
302
|
+
}
|
|
303
|
+
async getStats(ctx) {
|
|
304
|
+
return await ctx.runQuery(this.component.lib.getStats, {});
|
|
305
|
+
}
|
|
306
|
+
async listRecentIssues(ctx, args = {}) {
|
|
307
|
+
return await ctx.runQuery(this.component.lib.listRecentIssues, args);
|
|
308
|
+
}
|
|
309
|
+
async listRecentComments(ctx, args = {}) {
|
|
310
|
+
return await ctx.runQuery(this.component.lib.listRecentComments, args);
|
|
311
|
+
}
|
|
312
|
+
async listRecentWebhookEvents(ctx, args = {}) {
|
|
313
|
+
return await ctx.runQuery(this.component.lib.listRecentWebhookEvents, args);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated `api` utility.
|
|
3
|
+
*
|
|
4
|
+
* THIS CODE IS AUTOMATICALLY GENERATED.
|
|
5
|
+
*
|
|
6
|
+
* To regenerate, run `npx convex dev`.
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type * as lib from "../lib.js";
|
|
10
|
+
import type { ApiFromModules, FilterApi, FunctionReference } from "convex/server";
|
|
11
|
+
declare const fullApi: ApiFromModules<{
|
|
12
|
+
lib: typeof lib;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* A utility for referencing Convex functions in your app's public API.
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* ```js
|
|
19
|
+
* const myFunctionReference = api.myModule.myFunction;
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const api: FilterApi<typeof fullApi, FunctionReference<any, "public">>;
|
|
23
|
+
/**
|
|
24
|
+
* A utility for referencing Convex functions in your app's internal API.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
* ```js
|
|
28
|
+
* const myFunctionReference = internal.myModule.myFunction;
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
|
|
32
|
+
export declare const components: {};
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,GAAG,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,GAAG,EAAE,OAAO,GAAG,CAAC;CACjB,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Generated `api` utility.
|
|
4
|
+
*
|
|
5
|
+
* THIS CODE IS AUTOMATICALLY GENERATED.
|
|
6
|
+
*
|
|
7
|
+
* To regenerate, run `npx convex dev`.
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
11
|
+
const fullApi = anyApi;
|
|
12
|
+
/**
|
|
13
|
+
* A utility for referencing Convex functions in your app's public API.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```js
|
|
17
|
+
* const myFunctionReference = api.myModule.myFunction;
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const api = anyApi;
|
|
21
|
+
/**
|
|
22
|
+
* A utility for referencing Convex functions in your app's internal API.
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* ```js
|
|
26
|
+
* const myFunctionReference = internal.myModule.myFunction;
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export const internal = anyApi;
|
|
30
|
+
export const components = componentsGeneric();
|
|
31
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AASH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAER,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
|