239 lines · 10.2 KB
import { z } from "zod";
import { all, chunks, placeholders } from "../db";
import { accountDb, repoDb } from "../scoped-db";
import { forbidden, notFoundError } from "../errors";
import { limitWrite } from "../limits";
import { deleteLabel, listRepoLabels, loadLabel, saveLabel } from "../label-write";
import { loadProtectionRule, setCodeOwnerRequirement } from "../protection-write";
import { hasPermission } from "../repos";
import { assertAreasWithinGrant, scopedRepoPermission, TOKEN_AREAS } from "../token-scope";
import type { TokenPermissions } from "../token-scope";
import { createDeployToken, createFineGrainedToken, revokeDeployToken } from "../token-write";
import { labelColor } from "~/lib/validation";
import { noContent, readJson, requireScopedAdminWrite, requireScopedRepo, requireTokenWrite } from "./http";
import type { ApiContext } from "./http";

const labelInput = z.object({
  name: z.string().trim().min(1).max(50),
  color: labelColor,
  description: z.string().max(100).nullable().default(null),
});

export async function listLabels(ctx: ApiContext, owner: string, name: string): Promise<Response> {
  const { repo } = await requireScopedRepo(ctx, owner, name, "issues", "read");
  return Response.json(await listRepoLabels(repo.id));
}

async function labelRepo(ctx: ApiContext, owner: string, name: string) {
  await limitWrite(ctx.viewer);
  const { repo } = await requireScopedRepo(ctx, owner, name, "issues", "write");
  await requireTokenWrite(ctx, repo, ["issues"]);
  return repo;
}

export async function createLabel(ctx: ApiContext, owner: string, name: string): Promise<Response> {
  const data = await readJson(ctx.request, labelInput);
  const repo = await labelRepo(ctx, owner, name);
  const id = await saveLabel(repo.id, null, data);
  return Response.json(await loadLabel(repo.id, id), { status: 201 });
}