102 lines · 3.9 KB
import { env } from "cloudflare:workers";
import { parse as parseYaml } from "yaml";
import { branchSha, listRefs } from "./git/refs";
import { withStore } from "./git/store";
import { issueFormSchema, markdownTemplateSchema, templateConfigSchema } from "~/lib/issue-templates";
import type { IssueTemplate, TemplateConfig } from "~/lib/issue-templates";
import type { RepoRow } from "~/lib/types";

const TEMPLATE_DIR = ".gitfor/ISSUE_TEMPLATE";
const MAX_TEMPLATES = 20;
const MAX_TEMPLATE_BYTES = 64 * 1024;
const CACHE_TTL_SECONDS = 7 * 24 * 60 * 60;
const FRONT_MATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
const decoder = new TextDecoder();

export type RepoTemplates = { templates: IssueTemplate[]; config: TemplateConfig };

const EMPTY: RepoTemplates = { templates: [], config: templateConfigSchema.parse({}) };

function parseTemplate(file: string, text: string): IssueTemplate | null {
  try {
    if (/\.ya?ml$/i.test(file)) {
      const form = issueFormSchema.safeParse(parseYaml(text));
      if (!form.success) return null;
      return {
        kind: "form",
        file,
        name: form.data.name,
        about: form.data.description,
        title: form.data.title,
        labels: form.data.labels,
        fields: form.data.body,
      };
    }
    const match = FRONT_MATTER.exec(text);
    if (!match) return null;
    const meta = markdownTemplateSchema.safeParse(parseYaml(match[1]));
    if (!meta.success) return null;
    return {
      kind: "markdown",