kaneo (minimalist kanban) fork to experiment adding a tangled integration
github.com/usekaneo/kaneo
1import * as v from "valibot";
2
3export const branchPatterns = [
4 "{slug}-{number}",
5 "{slug}-{number}-{title}",
6 "{number}",
7 "{number}-{title}",
8 "feature/{slug}-{number}",
9 "feature/{number}-{title}",
10 "fix/{slug}-{number}",
11 "fix/{number}-{title}",
12] as const;
13
14export type BranchPattern = (typeof branchPatterns)[number] | "custom";
15
16export const githubConfigSchema = v.object({
17 repositoryOwner: v.string(),
18 repositoryName: v.string(),
19 installationId: v.nullable(v.number()),
20 branchPattern: v.optional(v.string()),
21 customBranchRegex: v.optional(v.string()),
22 commentTaskLinkOnGitHubIssue: v.optional(v.boolean()),
23 statusTransitions: v.optional(
24 v.object({
25 onBranchPush: v.optional(v.string()),
26 onPROpen: v.optional(v.string()),
27 onPRMerge: v.optional(v.string()),
28 }),
29 ),
30});
31
32export type GitHubConfig = v.InferOutput<typeof githubConfigSchema>;
33
34export async function validateGitHubConfig(
35 config: unknown,
36): Promise<{ valid: boolean; errors?: string[] }> {
37 try {
38 v.parse(githubConfigSchema, config);
39 return { valid: true };
40 } catch (error) {
41 if (error instanceof v.ValiError) {
42 return {
43 valid: false,
44 errors: error.issues.map((issue) => issue.message),
45 };
46 }
47 return {
48 valid: false,
49 errors: [error instanceof Error ? error.message : "Invalid config"],
50 };
51 }
52}
53
54export const defaultGitHubConfig: Partial<GitHubConfig> = {
55 branchPattern: "{slug}-{number}",
56 commentTaskLinkOnGitHubIssue: true,
57 statusTransitions: {
58 onBranchPush: "in-progress",
59 onPROpen: "in-review",
60 onPRMerge: "done",
61 },
62};
63
64export function getDefaultConfig(
65 repositoryOwner: string,
66 repositoryName: string,
67 installationId: number | null = null,
68): GitHubConfig {
69 return {
70 repositoryOwner,
71 repositoryName,
72 installationId,
73 ...defaultGitHubConfig,
74 };
75}