ework-web 0.2.0 → 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/src/giteaApi.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  // bg audit) plus a few cheap stubs (/version, /user, /repos/:o/:r) that
13
13
  // Gitea clients commonly hit during connection bootstrap.
14
14
 
15
- import { rawDB } from "./db";
15
+ import { getDB } from "./db";
16
16
  import {
17
17
  StoreError,
18
18
  getProject,
@@ -122,18 +122,17 @@ export async function handleGiteaApi(
122
122
  const limitRaw = Number(url.searchParams.get("limit") ?? 50);
123
123
  const limit = Number.isFinite(limitRaw) && limitRaw > 0 ? Math.min(limitRaw, 200) : 50;
124
124
  try {
125
- const rows = listAllIssues({ q, state, limit });
126
- return {
127
- status: 200,
128
- body: rows.map((row) => {
129
- const project = getProject(row.project_owner, row.project_name);
130
- if (!project) return null;
131
- return {
132
- ...buildIssuePayload(row, project, row.comment_count ?? 0, origin),
133
- repository: buildRepository(project, origin),
134
- };
135
- }).filter((x) => x !== null),
136
- };
125
+ const rows = await listAllIssues({ q, state, limit });
126
+ const body = [];
127
+ for (const row of rows) {
128
+ const project = await getProject(row.project_owner, row.project_name);
129
+ if (!project) continue;
130
+ body.push({
131
+ ...buildIssuePayload(row, project, row.comment_count ?? 0, origin),
132
+ repository: buildRepository(project, origin),
133
+ });
134
+ }
135
+ return { status: 200, body };
137
136
  } catch (e) {
138
137
  return giteaError(e instanceof StoreError ? e.status : 500, e instanceof Error ? e.message : "error");
139
138
  }
@@ -143,7 +142,7 @@ export async function handleGiteaApi(
143
142
  if (m && req.method === "GET") {
144
143
  const [, owner, repo] = m;
145
144
  if (!(owner && repo)) return giteaError(404, "not found");
146
- const project = getProject(owner, repo);
145
+ const project = await getProject(owner, repo);
147
146
  if (!project) return giteaError(404, "repository not found");
148
147
  return { status: 200, body: buildRepository(project, origin) };
149
148
  }
@@ -153,22 +152,22 @@ export async function handleGiteaApi(
153
152
  const [, owner, repo] = m;
154
153
  if (!(owner && repo)) return giteaError(404, "not found");
155
154
  try {
156
- const project = getProject(owner, repo);
155
+ const project = await getProject(owner, repo);
157
156
  if (!project) return giteaError(404, "repository not found");
158
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
157
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
159
158
  const body = await readJson(req);
160
159
  const title = asString(body.title);
161
160
  if (!title) return giteaError(400, "title required");
162
161
  const text = asString(body.body) ?? "";
163
- const created = createIssue(project.id, title, text, user.login, {
162
+ const created = await createIssue(project.id, title, text, user.login, {
164
163
  createdAt: asString(body.created_at),
165
164
  updatedAt: asString(body.updated_at),
166
165
  state: asIssueState(body.state) ?? "open",
167
166
  closedAt: asString(body.closed_at) || undefined,
168
167
  });
169
- emitIssueEvent(project.id, created.id, "opened", origin);
168
+ void emitIssueEvent(project.id, created.id, "opened", origin);
170
169
  if (created.state === "closed") {
171
- emitIssueEvent(project.id, created.id, "closed", origin);
170
+ void emitIssueEvent(project.id, created.id, "closed", origin);
172
171
  }
173
172
  return { status: 201, body: buildIssuePayload(created, project, 0, origin) };
174
173
  } catch (e) {
@@ -182,33 +181,33 @@ export async function handleGiteaApi(
182
181
  if (!(owner && repo && numStr)) return giteaError(404, "not found");
183
182
  const number = Number(numStr);
184
183
  try {
185
- const project = getProject(owner, repo);
184
+ const project = await getProject(owner, repo);
186
185
  if (!project) return giteaError(404, "repository not found");
187
- const issue = getIssue(project.id, number);
186
+ const issue = await getIssue(project.id, number);
188
187
  if (!issue) return giteaError(404, "issue not found");
189
188
 
190
189
  if (req.method === "GET") {
191
- return { status: 200, body: buildIssuePayload(issue, project, countComments(issue.id), origin) };
190
+ return { status: 200, body: buildIssuePayload(issue, project, await countComments(issue.id), origin) };
192
191
  }
193
192
  if (req.method === "PATCH") {
194
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
193
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
195
194
  const body = await readJson(req);
196
195
  const before = issue.state;
197
- editIssue(issue.id, {
196
+ await editIssue(issue.id, {
198
197
  title: asString(body.title),
199
198
  body: asString(body.body),
200
199
  state: asIssueState(body.state),
201
200
  closedAt: asString(body.closed_at) || undefined,
202
201
  updatedAt: asString(body.updated_at),
203
202
  });
204
- const after = getIssueById(issue.id);
203
+ const after = await getIssueById(issue.id);
205
204
  if (!after) return giteaError(404, "issue vanished mid-edit");
206
205
  if (before === "open" && after.state === "closed") {
207
- emitIssueEvent(project.id, after.id, "closed", origin);
206
+ void emitIssueEvent(project.id, after.id, "closed", origin);
208
207
  } else if (before === "closed" && after.state === "open") {
209
- emitIssueEvent(project.id, after.id, "reopened", origin);
208
+ void emitIssueEvent(project.id, after.id, "reopened", origin);
210
209
  }
211
- return { status: 200, body: buildIssuePayload(after, project, countComments(after.id), origin) };
210
+ return { status: 200, body: buildIssuePayload(after, project, await countComments(after.id), origin) };
212
211
  }
213
212
  return giteaError(405, `method ${req.method} not allowed`);
214
213
  } catch (e) {
@@ -222,28 +221,28 @@ export async function handleGiteaApi(
222
221
  if (!(owner && repo && numStr)) return giteaError(404, "not found");
223
222
  const number = Number(numStr);
224
223
  try {
225
- const project = getProject(owner, repo);
224
+ const project = await getProject(owner, repo);
226
225
  if (!project) return giteaError(404, "repository not found");
227
- const issue = getIssue(project.id, number);
226
+ const issue = await getIssue(project.id, number);
228
227
  if (!issue) return giteaError(404, "issue not found");
229
228
 
230
229
  if (req.method === "GET") {
231
- const comments = listCommentsForIssue(issue.id);
230
+ const comments = await listCommentsForIssue(issue.id);
232
231
  return {
233
232
  status: 200,
234
233
  body: comments.map((c) => buildCommentPayload(issue, c, project, origin)),
235
234
  };
236
235
  }
237
236
  if (req.method === "POST") {
238
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
237
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
239
238
  const body = await readJson(req);
240
239
  const text = asString(body.body);
241
240
  if (text === undefined) return giteaError(400, "body required");
242
- const created = postComment(issue.id, text, user.login, {
241
+ const created = await postComment(issue.id, text, user.login, {
243
242
  createdAt: asString(body.created_at),
244
243
  updatedAt: asString(body.updated_at),
245
244
  });
246
- emitCommentEvent(project.id, issue.id, created.id, origin);
245
+ void emitCommentEvent(project.id, issue.id, created.id, origin);
247
246
  return { status: 201, body: buildCommentPayload(issue, created, project, origin) };
248
247
  }
249
248
  return giteaError(405, `method ${req.method} not allowed`);
@@ -268,29 +267,29 @@ export async function handleGiteaApi(
268
267
  if (!(owner && repo && cidStr)) return giteaError(404, "not found");
269
268
  const cid = Number(cidStr);
270
269
  try {
271
- const project = getProject(owner, repo);
270
+ const project = await getProject(owner, repo);
272
271
  if (!project) return giteaError(404, "repository not found");
273
272
 
274
273
  if (req.method === "GET") {
275
- const comment = getComment(cid);
274
+ const comment = await getComment(cid);
276
275
  if (!comment) return giteaError(404, "comment not found");
277
- const issue = getIssueById(comment.issue_id);
276
+ const issue = await getIssueById(comment.issue_id);
278
277
  if (!issue) return giteaError(404, "issue not found");
279
278
  return { status: 200, body: buildCommentPayload(issue, comment, project, origin) };
280
279
  }
281
280
  if (req.method === "PATCH") {
282
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
281
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
283
282
  const body = await readJson(req);
284
283
  const text = asString(body.body);
285
284
  if (text === undefined) return giteaError(400, "body required");
286
- const updated = editComment(cid, text);
287
- const issue = getIssueById(updated.issue_id);
285
+ const updated = await editComment(cid, text);
286
+ const issue = await getIssueById(updated.issue_id);
288
287
  if (!issue) return giteaError(404, "issue not found");
289
288
  return { status: 200, body: buildCommentPayload(issue, updated, project, origin) };
290
289
  }
291
290
  if (req.method === "DELETE") {
292
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
293
- deleteComment(cid);
291
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
292
+ await deleteComment(cid);
294
293
  return { status: 204, body: null };
295
294
  }
296
295
  return giteaError(405, `method ${req.method} not allowed`);
@@ -305,20 +304,20 @@ export async function handleGiteaApi(
305
304
  if (!(owner && repo && cidStr)) return giteaError(404, "not found");
306
305
  const cid = Number(cidStr);
307
306
  try {
308
- const project = getProject(owner, repo);
307
+ const project = await getProject(owner, repo);
309
308
  if (!project) return giteaError(404, "repository not found");
310
309
 
311
310
  if (req.method === "GET") {
312
- return { status: 200, body: reactionsList(cid, origin) };
311
+ return { status: 200, body: await reactionsList(cid, origin) };
313
312
  }
314
313
  if (req.method === "POST" || req.method === "DELETE") {
315
- if (!canWriteProject(project.id, user)) return giteaError(403, "requires writer role");
314
+ if (!(await canWriteProject(project.id, user))) return giteaError(403, "requires writer role");
316
315
  const body = await readJson(req);
317
316
  const content = asContent(body.content);
318
317
  if (content === undefined) return giteaError(400, "content required");
319
- if (req.method === "POST") addReaction(cid, user.login, content);
320
- else removeReaction(cid, user.login, content);
321
- return { status: 200, body: reactionsList(cid, origin) };
318
+ if (req.method === "POST") await addReaction(cid, user.login, content);
319
+ else await removeReaction(cid, user.login, content);
320
+ return { status: 200, body: await reactionsList(cid, origin) };
322
321
  }
323
322
  return giteaError(405, `method ${req.method} not allowed`);
324
323
  } catch (e) {
@@ -332,12 +331,13 @@ export async function handleGiteaApi(
332
331
  // Gitea returns a per-user list, not the aggregated counts ework's store
333
332
  // keeps. The "reaction" key is Gitea's wire name; we also emit "content"
334
333
  // for self-consistency with ework's schema.
335
- function reactionsList(commentId: number, origin: string): { user: ReturnType<typeof buildUser>; reaction: string; content: string }[] {
336
- const aggs = listReactionsFor([commentId]);
334
+ async function reactionsList(commentId: number, origin: string): Promise<{ user: ReturnType<typeof buildUser>; reaction: string; content: string }[]> {
335
+ const aggs = await listReactionsFor([commentId]);
337
336
  if (aggs.length === 0) return [];
338
- const rows = rawDB()
339
- .query("SELECT user_login, content FROM reactions WHERE comment_id = ? ORDER BY rowid")
340
- .all(commentId) as { user_login: string; content: string }[];
337
+ const rows = await getDB().all<{ user_login: string; content: string }>(
338
+ "SELECT user_login, content FROM {{reactions}} WHERE comment_id = ? ORDER BY rowid",
339
+ [commentId]
340
+ );
341
341
  return rows.map((r) => ({
342
342
  user: buildUser(r.user_login, origin),
343
343
  reaction: r.content,