Monorepo for Tangled
tangled.org
1import { z } from "zod";
2
3const hexColor = /^#[0-9A-Fa-f]{6}$/;
4
5const languageSchema = z.object({
6 color: z.string().regex(hexColor),
7 percentage: z.number().min(0).max(100),
8});
9
10export const repositoryCardSchema = z.object({
11 type: z.literal("repository"),
12 repoName: z.string().min(1).max(100),
13 ownerHandle: z.string().min(1).max(100),
14 stars: z.number().int().min(0).max(1000000),
15 pulls: z.number().int().min(0).max(100000),
16 issues: z.number().int().min(0).max(100000),
17 createdAt: z.string().max(100),
18 avatarUrl: z.string().url(),
19 languages: z.array(languageSchema).max(5),
20});
21
22export const issueCardSchema = z.object({
23 type: z.literal("issue"),
24 repoName: z.string().min(1).max(100),
25 ownerHandle: z.string().min(1).max(100),
26 authorHandle: z.string().min(1).max(100),
27 avatarUrl: z.string().url(),
28 authorAvatarUrl: z.string().url(),
29 title: z.string().min(1).max(500),
30 issueNumber: z.number().int().positive(),
31 status: z.enum(["open", "closed"]),
32 labels: z
33 .array(
34 z.object({
35 name: z.string().max(50),
36 color: z.string().regex(hexColor),
37 }),
38 )
39 .max(10),
40 commentCount: z.number().int().min(0),
41 reactionCount: z.number().int().min(0),
42 createdAt: z.string(),
43});
44
45export const pullRequestCardSchema = z.object({
46 type: z.literal("pullRequest"),
47 repoName: z.string().min(1).max(100),
48 ownerHandle: z.string().min(1).max(100),
49 authorHandle: z.string().min(1).max(100),
50 avatarUrl: z.string().url(),
51 authorAvatarUrl: z.string().url(),
52 title: z.string().min(1).max(500),
53 pullRequestNumber: z.number().int().positive(),
54 status: z.enum(["open", "closed", "merged"]),
55 filesChanged: z.number().int().min(0),
56 additions: z.number().int().min(0),
57 deletions: z.number().int().min(0),
58 rounds: z.number().int().min(1),
59 // reviews: z.number().int().min(0), // TODO: implement review tracking
60 commentCount: z.number().int().min(0),
61 reactionCount: z.number().int().min(0),
62 createdAt: z.string(),
63});
64
65export const cardPayloadSchema = z.discriminatedUnion("type", [
66 repositoryCardSchema,
67 issueCardSchema,
68 pullRequestCardSchema,
69]);
70
71export type Language = z.infer<typeof languageSchema>;
72export type RepositoryCardData = z.infer<typeof repositoryCardSchema>;
73export type IssueCardData = z.infer<typeof issueCardSchema>;
74export type PullRequestCardData = z.infer<typeof pullRequestCardSchema>;