aboutsummaryrefslogtreecommitdiffstats
path: root/src/content.config.ts
blob: f0c8009f4ff5e77e3c052d402c7ba20ee0486cec (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { glob } from 'astro/loaders'
import { defineCollection, z } from 'astro:content'

const events = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/events' }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      date: z.coerce.date(),
      order: z.number().optional(),
      image: image().optional(),
      type: z.string(),
      draft: z.boolean().optional(),
    }),
})

const blog = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      date: z.coerce.date(),
      order: z.number().optional(),
      image: image().optional(),
      tags: z.array(z.string()).optional(),
      authors: z.array(z.string()).optional(),
      draft: z.boolean().optional(),
    }),
})

const members = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/members' }),
  schema: z.object({
    name: z.string(),
    pronouns: z.string().optional(),
    avatar: z.string().url().or(z.string().startsWith('/')),
    bio: z.string().optional(),
    mail: z.string().email().optional(),
    website: z.string().url().optional(),
    twitter: z.string().url().optional(),
    github: z.string().url().optional(),
    codeberg: z.string().url().optional(),
    linkedin: z.string().url().optional(),
    discord: z.string().url().optional(),
    instagram: z.string().url().optional(),
  }),
})

const forms = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/forms' }),
  schema: () =>
    z.object({
      title: z.string(),
      description: z.string(),
      date: z.coerce.date(),
      // sqlite-safe
      id: z.string().regex(/^[a-zA-Z0-9_]+$/, {
        message:
          "Form 'id' can only contain letters, numbers, and underscores.",
      }),
      submit_text: z.string().default('Submit'),
      form: z.object({
        submit_text: z.string().default('Submit'),
        fields: z
          .array(
            z.object({
              id: z.string().regex(/^[a-zA-Z0-9_]+$/, {
                message:
                  "Field 'name' can only contain letters, numbers, and underscores.",
              }),
              label: z.string(),
              type: z
                .enum([
                  'text',
                  'email',
                  'number',
                  'textarea',
                  'tel',
                  'url',
                  'select',
                  'checkbox',
                  'radio',
                ])
                .default('text'),
              options: z.array(z.string()).optional(),
              required: z.boolean().default(false),
            }),
          )
          .min(1, {
            message: 'A form must have at least one field defined.',
          }),
      }),
    }),
})

const projects = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/projects' }),
  schema: ({ image }) =>
    z.object({
      name: z.string(),
      description: z.string(),
      tags: z.array(z.string()),
      image: image(),
      link: z.string().url(),
      startDate: z.coerce.date().optional(),
      endDate: z.coerce.date().optional(),
    }),
})

export const collections = { events, blog, members, projects, forms }