~repos /website

#astro#js#html#css

git clone https://pyrossh.dev/repos/website.git

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


6d177b0b pyrossh

1 month ago
update packages
Files changed (3) hide show
  1. src/consts.ts +17 -3
  2. src/content.config.ts +1 -80
  3. src/utils/files.ts +76 -3
src/consts.ts CHANGED
@@ -18,7 +18,7 @@ export const REPOS = [
18
18
  badges: [
19
19
  {
20
20
  href: "https://crates.io/crates/rust-embed",
21
- img: "https://img.shields.io/crates/v/rust-embed.svg",
21
+ img: "https://img.shields.io/crates/v/rust-embed",
22
22
  alt: "crates.io",
23
23
  }
24
24
  ]
@@ -46,12 +46,26 @@ export const REPOS = [
46
46
  {
47
47
  title: "atoms-element",
48
48
  description: "A simple web component library for defining your custom elements. It works on both client and server.",
49
- tags: ['js']
49
+ tags: ['js'],
50
+ badges: [
51
+ {
52
+ href: "https://www.npmjs.com/package/atoms-element",
53
+ img: "https://img.shields.io/npm/v/atoms-element?color=ba271a",
54
+ alt: "npmjs.com",
55
+ }
56
+ ]
50
57
  },
51
58
  {
52
59
  title: "atoms-state",
53
60
  description: "Simple State management for react",
54
- tags: ['js', 'react', 'flux']
61
+ tags: ['js', 'react', 'flux'],
62
+ badges: [
63
+ {
64
+ href: "https://www.npmjs.com/package/atoms-state",
65
+ img: "https://img.shields.io/npm/v/atoms-state?color=ba271a",
66
+ alt: "npmjs.com",
67
+ }
68
+ ]
55
69
  },
56
70
  {
57
71
  title: "remote-monitor",
src/content.config.ts CHANGED
@@ -3,6 +3,7 @@ import { simpleGit } from "simple-git";
3
3
  import { glob } from 'astro/loaders';
4
4
  import { defineCollection, z } from 'astro:content';
5
5
  import { REPOS } from './consts';
6
+ import { buildFileTree, sortChildren, fileNodeSchema } from "./utils/files";
6
7
 
7
8
  async function checkFileExists(filePath: string) {
8
9
  try {
@@ -13,72 +14,6 @@ async function checkFileExists(filePath: string) {
13
14
  }
14
15
  }
15
16
 
16
- interface FileNode {
17
- name: string;
18
- path: string;
19
- isDirectory: boolean;
20
- children?: FileNode[];
21
- size?: number;
22
- ext?: string;
23
- absolutePath?: string;
24
- }
25
-
26
- function buildFileTree(files: any[]): FileNode[] {
27
- const root: FileNode[] = [];
28
-
29
- for (const file of files) {
30
- const parts = file.name.split('/');
31
- let currentLevel = root;
32
-
33
- for (let i = 0; i < parts.length; i++) {
34
- const part = parts[i];
35
- const isLastPart = i === parts.length - 1;
36
- const currentPath = parts.slice(0, i + 1).join('/');
37
-
38
- let existingNode = currentLevel.find(node => node.name === part);
39
-
40
- if (!existingNode) {
41
- const newNode: FileNode = {
42
- name: part,
43
- path: currentPath,
44
- isDirectory: !isLastPart,
45
- };
46
-
47
- if (isLastPart) {
48
- // It's a file, add file metadata
49
- newNode.size = file.size;
50
- newNode.ext = file.ext;
51
- newNode.absolutePath = file.absolutePath;
52
- } else {
53
- // It's a directory
54
- newNode.children = [];
55
- }
56
-
57
- currentLevel.push(newNode);
58
- existingNode = newNode;
59
- }
60
-
61
- if (!isLastPart) {
62
- currentLevel = existingNode.children!;
63
- }
64
- }
65
- }
66
-
67
- return root;
68
- }
69
-
70
- const fileNodeSchema: z.ZodType<FileNode> = z.lazy(() =>
71
- z.object({
72
- name: z.string(),
73
- path: z.string(),
74
- isDirectory: z.boolean(),
75
- children: z.array(fileNodeSchema),
76
- size: z.number(),
77
- ext: z.string(),
78
- absolutePath: z.string(),
79
- })
80
- );
81
-
82
17
  export const collections = {
83
18
  repos: defineCollection({
84
19
  loader: {
@@ -99,20 +34,6 @@ export const collections = {
99
34
  .then((stat) => ({ name: p, absolutePath: `${repoPath}/${p}`, ...stat }))
100
35
  .catch(() => null)
101
36
  ));
102
- const sortAll = (a: FileNode, b: FileNode): number => {
103
- if (a.isDirectory && !b.isDirectory) return -1;
104
- if (!a.isDirectory && b.isDirectory) return 1;
105
- return a.name.localeCompare(b.name);
106
- }
107
- const sortChildren = (nodes: FileNode[]) => {
108
- for (const node of nodes) {
109
- if (node.isDirectory && node.children) {
110
- node.children.sort(sortAll);
111
- sortChildren(node.children);
112
- }
113
- }
114
- return nodes.sort(sortAll);
115
- };
116
37
  const fileTree = sortChildren(buildFileTree(files.filter((f) => f !== null)));
117
38
  const readmeContent = await checkFileExists(readmePath) ? await renderMarkdown(await fs.readFile(readmePath, 'utf-8')) : {
118
39
  html: '',
src/utils/files.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import { z } from 'astro:content';
2
+
1
- interface FileNode {
3
+ export interface FileNode {
2
4
  name: string;
3
5
  path: string;
4
6
  isDirectory: boolean;
@@ -8,9 +10,21 @@ interface FileNode {
8
10
  absolutePath?: string;
9
11
  }
10
12
 
13
+ export const fileNodeSchema: z.ZodType<FileNode> = z.lazy(() =>
14
+ z.object({
15
+ name: z.string(),
16
+ path: z.string(),
17
+ isDirectory: z.boolean(),
18
+ children: z.array(fileNodeSchema),
19
+ size: z.number(),
20
+ ext: z.string(),
21
+ absolutePath: z.string(),
22
+ })
23
+ );
24
+
11
25
  export const collectFiles = (nodes: FileNode[]): FileNode[] => {
12
26
  const files: FileNode[] = [];
13
-
27
+
14
28
  for (const node of nodes) {
15
29
  if (node.isDirectory && node.children) {
16
30
  files.push(...collectFiles(node.children));
@@ -18,6 +32,65 @@ export const collectFiles = (nodes: FileNode[]): FileNode[] => {
18
32
  files.push(node);
19
33
  }
20
34
  }
21
-
35
+
22
36
  return files;
23
37
  };
38
+
39
+ export const sortAll = (a: FileNode, b: FileNode): number => {
40
+ if (a.isDirectory && !b.isDirectory) return -1;
41
+ if (!a.isDirectory && b.isDirectory) return 1;
42
+ return a.name.localeCompare(b.name);
43
+ }
44
+ export const sortChildren = (nodes: FileNode[]) => {
45
+ for (const node of nodes) {
46
+ if (node.isDirectory && node.children) {
47
+ node.children.sort(sortAll);
48
+ sortChildren(node.children);
49
+ }
50
+ }
51
+ return nodes.sort(sortAll);
52
+ };
53
+
54
+ export const buildFileTree = (files: any[]): FileNode[] => {
55
+ const root: FileNode[] = [];
56
+
57
+ for (const file of files) {
58
+ const parts = file.name.split('/');
59
+ let currentLevel = root;
60
+
61
+ for (let i = 0; i < parts.length; i++) {
62
+ const part = parts[i];
63
+ const isLastPart = i === parts.length - 1;
64
+ const currentPath = parts.slice(0, i + 1).join('/');
65
+
66
+ let existingNode = currentLevel.find(node => node.name === part);
67
+
68
+ if (!existingNode) {
69
+ const newNode: FileNode = {
70
+ name: part,
71
+ path: currentPath,
72
+ isDirectory: !isLastPart,
73
+ };
74
+
75
+ if (isLastPart) {
76
+ // It's a file, add file metadata
77
+ newNode.size = file.size;
78
+ newNode.ext = file.ext;
79
+ newNode.absolutePath = file.absolutePath;
80
+ } else {
81
+ // It's a directory
82
+ newNode.children = [];
83
+ }
84
+
85
+ currentLevel.push(newNode);
86
+ existingNode = newNode;
87
+ }
88
+
89
+ if (!isLastPart) {
90
+ currentLevel = existingNode.children!;
91
+ }
92
+ }
93
+ }
94
+
95
+ return root;
96
+ }