@coffic/cosy-ui 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/index-astro.ts +2 -19
  2. package/dist/index-collection.ts +1 -105
  3. package/dist/src-astro/collection/entities/BaseDoc.ts +28 -0
  4. package/dist/src-astro/collection/entities/BlogDoc.ts +221 -0
  5. package/dist/src-astro/collection/entities/CourseDoc.ts +254 -0
  6. package/dist/src-astro/collection/entities/ExperimentDoc.ts +169 -0
  7. package/dist/src-astro/collection/entities/LessonDoc.ts +203 -0
  8. package/dist/src-astro/collection/entities/MetaDoc.ts +115 -0
  9. package/dist/src-astro/{entities → collection/entities}/SidebarItem.ts +17 -17
  10. package/dist/src-astro/collection/entities/Tag.ts +42 -0
  11. package/dist/src-astro/collection/index.ts +11 -0
  12. package/dist/src-astro/collection/repos/BaseRepo.ts +276 -0
  13. package/dist/src-astro/collection/repos/BlogRepo.ts +226 -0
  14. package/dist/src-astro/collection/repos/CourseRepo.ts +137 -0
  15. package/dist/src-astro/collection/repos/ExperimentRepo.ts +121 -0
  16. package/dist/src-astro/collection/repos/LessonRepo.ts +128 -0
  17. package/dist/src-astro/collection/repos/MetaRepo.ts +89 -0
  18. package/package.json +1 -1
  19. package/dist/src-astro/database/BaseDB.ts +0 -264
  20. package/dist/src-astro/database/BlogDB.ts +0 -198
  21. package/dist/src-astro/database/CourseDB.ts +0 -90
  22. package/dist/src-astro/database/ExperimentDB.ts +0 -106
  23. package/dist/src-astro/database/LessonDB.ts +0 -106
  24. package/dist/src-astro/database/MetaDB.ts +0 -74
  25. package/dist/src-astro/database/index.ts +0 -3
  26. package/dist/src-astro/entities/BaseDoc.ts +0 -207
  27. package/dist/src-astro/entities/BlogDoc.ts +0 -107
  28. package/dist/src-astro/entities/CourseDoc.ts +0 -102
  29. package/dist/src-astro/entities/ExperimentDoc.ts +0 -119
  30. package/dist/src-astro/entities/LessonDoc.ts +0 -153
  31. package/dist/src-astro/entities/MetaDoc.ts +0 -93
  32. package/dist/src-astro/entities/Tag.ts +0 -42
  33. /package/dist/src-astro/{entities → collection/entities}/Feature.ts +0 -0
@@ -1,198 +0,0 @@
1
- import BlogDoc from '../entities/BlogDoc';
2
- import type Tag from '../entities/Tag';
3
- import { cosyLogger } from '../cosy';
4
- import { type CollectionEntry } from 'astro:content';
5
- import { BaseDB } from './BaseDB';
6
-
7
- export const COLLECTION_BLOG = 'blogs' as const;
8
- export type BlogEntry = CollectionEntry<typeof COLLECTION_BLOG>;
9
-
10
- /**
11
- * 博客数据库类,用于管理博客内容集合。
12
- *
13
- * 目录结构:
14
- * ```
15
- * blogs/
16
- * ├── zh-cn/
17
- * │ ├── typescript-intro.md # 文章内容
18
- * │ ├── images/ # 文章相关图片
19
- * │ └── web-performance.md
20
- * └── en/
21
- * └── typescript-intro.md
22
- * └── images/
23
- * └── web-performance.md
24
- * ```
25
- */
26
- class BlogDB extends BaseDB<typeof COLLECTION_BLOG, BlogEntry, BlogDoc> {
27
- protected collectionName = COLLECTION_BLOG;
28
-
29
- protected createDoc(entry: BlogEntry): BlogDoc {
30
- return BlogDoc.fromEntry(entry);
31
- }
32
-
33
- /**
34
- * 获取所有博客
35
- *
36
- * @returns {Promise<BlogDoc[]>} 返回所有博客
37
- */
38
- async allBlogs(): Promise<BlogDoc[]> {
39
- const debug = false;
40
- const entries = await this.getDocsByDepth(2);
41
-
42
- if (debug) {
43
- cosyLogger.array('所有博客文档', entries);
44
- }
45
-
46
- return entries;
47
- }
48
-
49
- /**
50
- * 获取指定语言的所有博客
51
- *
52
- * @param lang - 语言代码
53
- * @returns {Promise<BlogDoc[]>} 返回指定语言的所有博客
54
- */
55
- async allBlogsByLang(lang: string): Promise<BlogDoc[]> {
56
- const docs = await this.allBlogs();
57
- const filteredEntries = docs.filter((doc) => doc.getId().startsWith(lang));
58
-
59
- return filteredEntries;
60
- }
61
-
62
- /**
63
- * 获取用于 Astro 静态路由生成的路径参数,专门配合 [lang]/blogs/[slug].astro 使用
64
- *
65
- * @param debug - 是否开启调试模式
66
- * @returns 返回路径参数数组
67
- */
68
- async getStaticPaths(debug: boolean = false) {
69
- const docs = await this.allBlogs();
70
-
71
- const paths = docs.map((doc) => {
72
- return {
73
- params: {
74
- lang: doc.getLang(),
75
- slug: doc.getSlug(),
76
- },
77
- };
78
- });
79
-
80
- if (debug) {
81
- cosyLogger.array('所有博客文档的路径', paths);
82
- }
83
-
84
- return paths;
85
- }
86
-
87
- /**
88
- * 获取所有博客标签
89
- * 标签会根据语言和名称去重,使用复合键 "lang:name" 确保唯一性
90
- *
91
- * @returns 返回所有标签数组
92
- * 返回格式:
93
- * [
94
- * { name: 'typescript', lang: 'zh-cn', count: 5 },
95
- * { name: 'javascript', lang: 'en', count: 3 }
96
- * ]
97
- */
98
- async getTags(): Promise<Tag[]> {
99
- const tagsMap = new Map<string, Tag>();
100
- const posts = await this.allBlogs();
101
-
102
- posts.forEach((post) => {
103
- post.getTags().forEach((tag) => {
104
- const key = `${tag.lang}:${tag.name}`;
105
- if (!tagsMap.has(key)) {
106
- tagsMap.set(key, tag);
107
- }
108
- });
109
- });
110
-
111
- return Array.from(tagsMap.values());
112
- }
113
-
114
- /**
115
- * 获取指定语言的博客标签
116
- *
117
- * @param lang - 语言代码(如 'zh-cn', 'en')
118
- * @returns 返回指定语言的标签数组
119
- */
120
- async getTagsByLang(lang: string): Promise<Tag[]> {
121
- const debug = false;
122
- const tagsMap = new Map<string, Tag>();
123
- const posts = await this.allBlogsByLang(lang);
124
-
125
- if (debug) {
126
- cosyLogger.array('posts', posts);
127
- }
128
-
129
- if (posts.length === 0) {
130
- return [];
131
- }
132
-
133
- posts.forEach((post) => {
134
- post.getTags().forEach((tag) => {
135
- const key = `${tag.lang}:${tag.name}`;
136
- if (!tagsMap.has(key)) {
137
- tagsMap.set(key, tag);
138
- }
139
- });
140
- });
141
-
142
- if (debug) {
143
- cosyLogger.array('tags', Array.from(tagsMap.values()));
144
- }
145
-
146
- return Array.from(tagsMap.values());
147
- }
148
-
149
- /**
150
- * 获取指定标签和语言的博客文章
151
- *
152
- * @param tag - 标签名称
153
- * @param lang - 语言代码
154
- * @returns 返回匹配的博客文档数组
155
- * @example
156
- * ```typescript
157
- * const posts = await blogDB.getBlogsByTag('typescript', 'zh-cn');
158
- * // 返回所有包含 'typescript' 标签的中文博客
159
- * ```
160
- */
161
- async getBlogsByTag(tag: string, lang: string): Promise<BlogDoc[]> {
162
- const posts = await this.allBlogsByLang(lang);
163
- return posts.filter((post) => post.getTags().some((t) => t.name === tag));
164
- }
165
-
166
- /**
167
- * 获取标签的静态路径参数,用于生成标签页面的路由,专门配合 [lang]/blogs/tag/[name].astro 使用
168
- *
169
- * @returns 返回所有标签的路径参数数组
170
- * 返回格式:
171
- * [
172
- * { params: { lang: 'zh-cn', name: 'typescript' } },
173
- * { params: { lang: 'en', name: 'javascript' } }
174
- * ]
175
- */
176
- async getTagsStaticPaths() {
177
- const debug = false;
178
- const tags = await this.getTags();
179
-
180
- const paths = tags.map((tag) => {
181
- return {
182
- params: {
183
- lang: tag.lang,
184
- name: tag.name,
185
- },
186
- };
187
- });
188
-
189
- if (debug) {
190
- cosyLogger.array('所有的标签路径', paths);
191
- }
192
-
193
- return paths;
194
- }
195
- }
196
-
197
- // 创建并导出单例实例
198
- export const blogDB = new BlogDB();
@@ -1,90 +0,0 @@
1
- import CourseDoc from '../entities/CourseDoc';
2
- import { getCollection, type CollectionEntry } from 'astro:content';
3
- import { BaseDB } from './BaseDB';
4
-
5
- export const COLLECTION_COURSE = 'courses' as const;
6
- export type CourseEntry = CollectionEntry<typeof COLLECTION_COURSE>;
7
-
8
- /**
9
- * 课程数据库类,用于管理课程内容集合。
10
- *
11
- * 目录结构:
12
- * ```
13
- * courses/
14
- * ├── zh-cn/ # 中文版本
15
- * │ ├── web-development/ # 课程1
16
- * │ │ ├── index.md # 课程文档
17
- * │ │ ├── chapter1
18
- * │ │ │ ├── index.md
19
- * │ │ │ ├── content.md
20
- * │ │ │ └── ...
21
- * │ │ └── chapter2
22
- * │ │ ├── index.md
23
- * │ │ ├── content.md
24
- * │ │ └── ...
25
- * │ └── mobile-dev/ # 课程2
26
- * │ ├── index.md
27
- * │ └── ...
28
- * └── en/ # 英文版本
29
- * └── ...
30
- * ```
31
- */
32
- class CourseDB extends BaseDB<
33
- typeof COLLECTION_COURSE,
34
- CourseEntry,
35
- CourseDoc
36
- > {
37
- protected collectionName = COLLECTION_COURSE;
38
-
39
- protected createDoc(entry: CourseEntry): CourseDoc {
40
- return new CourseDoc(entry);
41
- }
42
-
43
- /**
44
- * 获取指定语言的所有顶级课程
45
- *
46
- * @param lang - 语言代码
47
- * @returns 返回指定语言的顶级课程数组
48
- */
49
- async allCoursesByLang(lang: string): Promise<CourseDoc[]> {
50
- const entries = await getCollection(COLLECTION_COURSE, ({ id }) => {
51
- return id.startsWith(lang) && id.split('/').length === 2;
52
- });
53
- return entries.map((entry) => new CourseDoc(entry));
54
- }
55
-
56
- /**
57
- * 获取用于 Astro 静态路由生成的路径参数,专门配合 [lang]/courses/[...slug].astro 使用
58
- *
59
- * @returns 返回路径参数数组
60
- */
61
- async getStaticPaths(): Promise<
62
- { params: { lang: string; slug: string } }[]
63
- > {
64
- const entries = await getCollection(COLLECTION_COURSE);
65
- return entries.map((entry) => {
66
- const doc = new CourseDoc(entry);
67
- return {
68
- params: {
69
- lang: doc.getLang(),
70
- slug: doc.getSlug(),
71
- },
72
- };
73
- });
74
- }
75
-
76
- /**
77
- * 获取精选课程
78
- * 返回指定语言的前4个顶级课程文档
79
- *
80
- * @param lang - 语言代码(如 'zh-cn', 'en')
81
- * @returns 返回精选课程文档数组(最多4个)
82
- */
83
- async getFamousCourses(lang: string): Promise<CourseDoc[]> {
84
- const courses = await this.allCoursesByLang(lang);
85
- return courses.slice(0, 4);
86
- }
87
- }
88
-
89
- // 创建并导出单例实例
90
- export const courseDB = new CourseDB();
@@ -1,106 +0,0 @@
1
- import { type CollectionEntry } from 'astro:content';
2
- import { BaseDB } from './BaseDB';
3
- import ExperimentDoc from '../entities/ExperimentDoc';
4
- import { cosyLogger } from '../cosy';
5
-
6
- export const COLLECTION_EXPERIMENT = 'experiments' as const;
7
- export type ExperimentEntry = CollectionEntry<typeof COLLECTION_EXPERIMENT>;
8
-
9
- /**
10
- * 实验数据库类,用于管理实验内容集合
11
- *
12
- * 目录结构:
13
- * ```
14
- * experiments/
15
- * ├── safari_itp/ # 实验目录
16
- * │ ├── images/ # 实验图片资源
17
- * │ ├── components/ # 课程组件
18
- * │ ├── en/ # 英文版本
19
- * │ │ ├── index.mdx # 课程首页
20
- * │ │ ├── 1.mdx # 第一章
21
- * │ │ └── 2.mdx # 第二章
22
- * │ └── zh-cn/ # 中文版本
23
- * │ ├── index.mdx # 课程首页
24
- * │ ├── 1.mdx # 第一章
25
- * │ └── 2.mdx # 第二章
26
- * └── learn_astro/ # 另一个课程
27
- * ├── en/
28
- * │ ├── index.mdx
29
- * │ ├── 1.mdx
30
- * │ └── 2.mdx
31
- * └── zh-cn/
32
- * ├── index.mdx
33
- * ├── 1.mdx
34
- * └── 2.mdx
35
- * ```
36
- *
37
- * 说明:
38
- * - 每个课程(如 build_your_own_web_toolbox)是一个独立的目录
39
- * - 课程目录可以包含多语言版本(en, zh-cn 等)
40
- * - 每个语言版本包含完整的课程内容
41
- * - 课程目录可以作为 git 子模块独立管理
42
- */
43
- class ExperimentDB extends BaseDB<
44
- typeof COLLECTION_EXPERIMENT,
45
- ExperimentEntry,
46
- ExperimentDoc
47
- > {
48
- protected collectionName = COLLECTION_EXPERIMENT;
49
-
50
- protected createDoc(entry: ExperimentEntry): ExperimentDoc {
51
- return new ExperimentDoc(entry);
52
- }
53
-
54
- /**
55
- * 获取指定语言的所有课程
56
- *
57
- * @param {string} lang - 语言代码
58
- * @returns {Promise<ExperimentDoc[]>} 返回指定语言的所有课程
59
- */
60
- async allExperiments(lang: string): Promise<ExperimentDoc[]> {
61
- const docs = await this.getDocsByDepth(2);
62
- return docs.filter((doc) => doc.getId().endsWith(lang));
63
- }
64
-
65
- /**
66
- * 获取用于 Astro 静态路由生成的路径参数
67
- *
68
- * @param debug - 是否开启调试模式
69
- * @returns 返回路径参数数组
70
- */
71
- async getStaticPaths(debug: boolean = false) {
72
- const docs = await this.getEntries();
73
-
74
- if (debug) {
75
- cosyLogger.array('所有文档', docs);
76
- }
77
-
78
- const paths = docs.map((doc) => {
79
- const id = doc.id;
80
- const lang = id.split('/')[1];
81
-
82
- let slug = '';
83
- if (id.endsWith(lang)) {
84
- slug = id.replace(`${lang}`, '');
85
- } else {
86
- slug = id.replace(`${lang}/`, '');
87
- }
88
-
89
- return {
90
- params: {
91
- lang: lang,
92
- slug: slug,
93
- },
94
- };
95
- });
96
-
97
- if (debug) {
98
- cosyLogger.array('所有文档的路径', paths);
99
- }
100
-
101
- return paths;
102
- }
103
- }
104
-
105
- // 创建并导出单例实例
106
- export const experimentDB = new ExperimentDB();
@@ -1,106 +0,0 @@
1
- import { type CollectionEntry } from 'astro:content';
2
- import { BaseDB } from './BaseDB';
3
- import LessonDoc from '../entities/LessonDoc';
4
- import { cosyLogger } from '../cosy';
5
-
6
- export const COLLECTION_LESSON = 'lessons' as const;
7
- export type LessonEntry = CollectionEntry<typeof COLLECTION_LESSON>;
8
-
9
- /**
10
- * 课程数据库类,用于管理课程内容集合
11
- *
12
- * 目录结构:
13
- * ```
14
- * lessons/
15
- * ├── build_your_own_web_toolbox/ # 课程目录
16
- * │ ├── images/ # 课程图片资源
17
- * │ ├── components/ # 课程组件
18
- * │ ├── en/ # 英文版本
19
- * │ │ ├── index.mdx # 课程首页
20
- * │ │ ├── 1.mdx # 第一章
21
- * │ │ └── 2.mdx # 第二章
22
- * │ └── zh-cn/ # 中文版本
23
- * │ ├── index.mdx # 课程首页
24
- * │ ├── 1.mdx # 第一章
25
- * │ └── 2.mdx # 第二章
26
- * └── learn_astro/ # 另一个课程
27
- * ├── en/
28
- * │ ├── index.mdx
29
- * │ ├── 1.mdx
30
- * │ └── 2.mdx
31
- * └── zh-cn/
32
- * ├── index.mdx
33
- * ├── 1.mdx
34
- * └── 2.mdx
35
- * ```
36
- *
37
- * 说明:
38
- * - 每个课程(如 build_your_own_web_toolbox)是一个独立的目录
39
- * - 课程目录可以包含多语言版本(en, zh-cn 等)
40
- * - 每个语言版本包含完整的课程内容
41
- * - 课程目录可以作为 git 子模块独立管理
42
- */
43
- class LessonDB extends BaseDB<
44
- typeof COLLECTION_LESSON,
45
- LessonEntry,
46
- LessonDoc
47
- > {
48
- protected collectionName = COLLECTION_LESSON;
49
-
50
- protected createDoc(entry: LessonEntry): LessonDoc {
51
- return new LessonDoc(entry);
52
- }
53
-
54
- /**
55
- * 获取指定语言的所有课程
56
- *
57
- * @param {string} lang - 语言代码
58
- * @returns {Promise<LessonDoc[]>} 返回指定语言的所有课程
59
- */
60
- async allLessons(lang: string): Promise<LessonDoc[]> {
61
- const docs = await this.getDocsByDepth(2);
62
- return docs.filter((doc) => doc.getId().endsWith(lang));
63
- }
64
-
65
- /**
66
- * 获取用于 Astro 静态路由生成的路径参数
67
- *
68
- * @param debug - 是否开启调试模式
69
- * @returns 返回路径参数数组
70
- */
71
- async getStaticPaths(debug: boolean = false) {
72
- const docs = await this.getEntries();
73
-
74
- if (debug) {
75
- cosyLogger.array('所有文档', docs);
76
- }
77
-
78
- const paths = docs.map((doc) => {
79
- const id = doc.id;
80
- const lang = id.split('/')[1];
81
-
82
- let slug = '';
83
- if (id.endsWith(lang)) {
84
- slug = id.replace(`${lang}`, '');
85
- } else {
86
- slug = id.replace(`${lang}/`, '');
87
- }
88
-
89
- return {
90
- params: {
91
- lang: lang,
92
- slug: slug,
93
- },
94
- };
95
- });
96
-
97
- if (debug) {
98
- cosyLogger.array('所有文档的路径', paths);
99
- }
100
-
101
- return paths;
102
- }
103
- }
104
-
105
- // 创建并导出单例实例
106
- export const lessonDB = new LessonDB();
@@ -1,74 +0,0 @@
1
- import MetaDoc from '../entities/MetaDoc';
2
- import { cosyLogger } from '../cosy';
3
- import { type CollectionEntry } from 'astro:content';
4
- import { BaseDB } from './BaseDB';
5
-
6
- export const COLLECTION_META = 'meta' as const;
7
- export type MetaEntry = CollectionEntry<typeof COLLECTION_META>;
8
-
9
- /**
10
- * 元数据数据库类,用于管理网站的元数据内容集合(如"关于我们"等页面)
11
- *
12
- * 目录结构:
13
- * ```
14
- * meta/
15
- * ├── zh-cn/ # 中文内容
16
- * │ ├── about.md # 关于我们
17
- * │ ├── advice.md # 建议
18
- * └── en/ # 英文内容
19
- * ├── about.md
20
- * ├── privacy.md
21
- * └── terms.md
22
- * ```
23
- */
24
- class MetaDB extends BaseDB<typeof COLLECTION_META, MetaEntry, MetaDoc> {
25
- protected collectionName = COLLECTION_META;
26
-
27
- protected createDoc(entry: MetaEntry): MetaDoc {
28
- return new MetaDoc(entry);
29
- }
30
-
31
- /**
32
- * 获取指定文档的兄弟文档
33
- * 例如:对于 'zh-cn/about',会返回 'zh-cn' 下的文档
34
- *
35
- * @param targetId - 目标文档ID
36
- * @returns 返回兄弟文档数组(包括目标文档本身)
37
- */
38
- async getSiblings(targetId: string): Promise<MetaDoc[]> {
39
- const target = await this.find(targetId);
40
- if (!target) {
41
- return [];
42
- }
43
- const docs = await this.getDocsByDepth(2);
44
- return docs.filter((doc) => doc.getLang() === target.getLang());
45
- }
46
-
47
- /**
48
- * 获取用于 Astro 静态路由生成的路径参数,专门配合 [lang]/meta/[slug].astro 使用
49
- *
50
- * @param debug - 是否开启调试模式
51
- * @returns 返回路径参数数组
52
- */
53
- async getStaticPaths(debug: boolean = false) {
54
- const docs = await this.getDescendantDocs('');
55
-
56
- const paths = docs.map((doc) => {
57
- return {
58
- params: {
59
- lang: doc.getLang(),
60
- slug: doc.getSlug(),
61
- },
62
- };
63
- });
64
-
65
- if (debug) {
66
- cosyLogger.array('所有元数据文档的路径', paths);
67
- }
68
-
69
- return paths;
70
- }
71
- }
72
-
73
- // 创建并导出单例实例
74
- export const metaDB = new MetaDB();
@@ -1,3 +0,0 @@
1
- export * from './LessonDB';
2
- export * from './CourseDB';
3
- export * from './MetaDB';