[READ-ONLY] Mirror of https://github.com/danielroe/roe.dev. This is the code and content for my personal website, built in Nuxt.
roe.dev
1import { readFile } from 'node:fs/promises'
2
3import { addTemplate, addTypeTemplate, defineNuxtModule, useNuxt } from 'nuxt/kit'
4import { resolve } from 'pathe'
5import yaml from 'js-yaml'
6
7export interface ProjectItem {
8 name: string
9 description?: string
10 url?: string
11 repo?: string
12 image?: string
13 icon?: string
14 archived?: boolean
15 order?: number
16}
17
18export interface ProjectCategory {
19 category: string
20 order?: number
21 items: ProjectItem[]
22}
23
24export default defineNuxtModule({
25 meta: {
26 name: 'projects',
27 },
28 async setup () {
29 const nuxt = useNuxt()
30 const filePath = resolve(nuxt.options.rootDir, 'content/projects.yml')
31
32 let categories: ProjectCategory[] = []
33 try {
34 const raw = await readFile(filePath, 'utf-8')
35 const parsed = yaml.load(raw) as ProjectCategory[] | null
36 categories = Array.isArray(parsed) ? parsed : []
37 }
38 catch (err: unknown) {
39 if ((err as NodeJS.ErrnoException)?.code !== 'ENOENT') throw err
40 }
41
42 categories = categories
43 .map(c => ({
44 ...c,
45 items: [...(c.items || [])].sort(
46 (a, b) => (a.order ?? 100) - (b.order ?? 100),
47 ),
48 }))
49 .sort((a, b) => (a.order ?? 100) - (b.order ?? 100))
50
51 addTemplate({
52 filename: 'projects.mjs',
53 getContents: () => `export const projects = ${JSON.stringify(categories)}`,
54 write: true,
55 })
56
57 nuxt.options.nitro.virtual ||= {}
58 nuxt.options.nitro.virtual['#projects.json'] = () =>
59 `export const projects = ${JSON.stringify(categories)}`
60
61 nuxt.options.nitro.externals ||= {}
62 nuxt.options.nitro.externals.inline ||= []
63 nuxt.options.nitro.externals.inline.push('#projects.json')
64
65 addTypeTemplate({
66 filename: 'types/projects.d.ts',
67 getContents: () => `
68interface ProjectItem {
69 name: string
70 description?: string
71 url?: string
72 repo?: string
73 image?: string
74 icon?: string
75 archived?: boolean
76 order?: number
77}
78interface ProjectCategory {
79 category: string
80 order?: number
81 items: ProjectItem[]
82}
83
84declare module '#build/projects.mjs' {
85 export const projects: ProjectCategory[]
86}
87
88declare module '#projects.json' {
89 export const projects: ProjectCategory[]
90}
91`,
92 }, { nuxt: true, nitro: true })
93 },
94})