-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.ts
112 lines (99 loc) · 3.48 KB
/
schema.ts
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 { s, defineSchema } from 'velite';
import { ThumbnailType, TocEntry } from '@/types/components';
import { generateHeadingTree } from '@/utils/meta/generateHeadingTree';
import { generateThumbnailURL } from './src/utils/meta/generateThumbnail';
import remarkImagePath from '@/plugins/remark-image-path';
import { basename } from 'node:path';
export const headingTree = defineSchema(() =>
s.custom().transform<TocEntry[]>((data, { meta }) => {
if (!meta.mdast) return [];
return generateHeadingTree(meta.mdast);
}));
export const postSlug = defineSchema(() =>
s.path().transform<string>((data) => basename(data)),
);
export const metadataObject = s.object({
slug: postSlug(),
title: s.string().max(99),
date: s.string().datetime(),
description: s.string().max(200),
thumbnail: s.object({
local: s.string(),
cloud: s.string().optional(),
blurURL: s.string().optional(),
}).optional(),
});
export const articleMetadataObject = metadataObject.extend({
tags: s.array(s.string()),
});
export const articleMetadataSchema = defineSchema(() =>
articleMetadataObject
// transform을 거친 타입은 동기 함수일 경우 타입에 포함됨
.transform((data) => ({ ...data, url: `/posts/${data.slug}` })),
);
export const articleSchema = defineSchema(() =>
articleMetadataObject
.extend({
html: s.markdown({
gfm: true,
}),
headingTree: headingTree(),
})
.transform((data) => ({ ...data, url: `/posts/${data.slug}` }))
.transform(async (data, { meta }) => {
if (!meta.mdast) return data;
const localThumbnailURL = await generateThumbnailURL(meta, data.title);
const thumbnail: ThumbnailType = {
local: localThumbnailURL,
};
return ({ ...data, thumbnail });
}),
);
export const enArticleMetadataSchema = defineSchema(() =>
articleMetadataObject
// transform을 거친 타입은 동기 함수일 경우 타입에 포함됨
.transform((data) => ({ ...data, url: `/en/posts/${data.slug}` })),
);
export const enArticleSchema = defineSchema(() =>
articleMetadataObject
.extend({
html: s.markdown({
gfm: true,
remarkPlugins: [remarkImagePath],
}),
headingTree: headingTree(),
})
// TODO: slug를 en-posts로 시작하는 것을 posts로 바꾸는 로직을 좀더 확장성 있게 추가하자
.transform((data) => ({ ...data, url: `/en/posts/${data.slug}` }))
.transform(async (data, { meta }) => {
if (!meta.mdast) return data;
const localThumbnailURL = await generateThumbnailURL(meta, data.title, 'en');
const thumbnail: ThumbnailType = {
local: localThumbnailURL,
};
return ({ ...data, thumbnail });
}),
);
export const translationMetadataSchema = defineSchema(() =>
metadataObject
.transform((data) => ({ ...data, url: `/translations/${data.slug}` })),
);
export const translationSchema = defineSchema(() =>
metadataObject
.extend({
html: s.markdown({
gfm: true,
}),
headingTree: headingTree(),
})
.transform((data) => ({ ...data, url: `/translations/${data.slug}` }))
.transform(async (data, { meta }) => {
if (!meta.mdast) return data;
// TODO: 번역 글에 대해 썸네일에도 [번역] 같은 표시를 붙이도록 하자
const localThumbnailURL = await generateThumbnailURL(meta, data.title);
const thumbnail: ThumbnailType = {
local: localThumbnailURL,
};
return ({ ...data, thumbnail });
}),
);