1 | import matter from 'gray-matter'
|
2 |
|
3 | import { promises as fs } from 'fs'
|
4 | import config from 'lib/config'
|
5 |
|
6 | function fullPath(node) {
|
7 | const fullpath = [node.name]
|
8 |
|
9 | while (node.parent?.name) {
|
10 | node = node.parent
|
11 | fullpath.unshift(node.name)
|
12 | }
|
13 |
|
14 | return '/' + fullpath.join('/')
|
15 | }
|
16 |
|
17 | class Node {
|
18 | children = {}
|
19 |
|
20 | constructor(opts) {
|
21 | Object.assign(this, opts)
|
22 |
|
23 | if (this.isRoot) this.isDirectory = true
|
24 | else this.path = fullPath(this)
|
25 | }
|
26 |
|
27 | add = async path => {
|
28 | const segments = typeof path == 'string' ? path.split('/') : path,
|
29 | nextSegment = segments[0]
|
30 |
|
31 | let node = this.children[nextSegment]
|
32 |
|
33 | if (!node) {
|
34 | node = new Node({ name: nextSegment, parent: this })
|
35 | this.children[nextSegment] = node
|
36 | }
|
37 |
|
38 | if (segments.length > 1) {
|
39 | node.isDirectory = true
|
40 | await node.add(segments.slice(1))
|
41 | } else {
|
42 | await node.change()
|
43 | }
|
44 | }
|
45 |
|
46 | get = path => {
|
47 | const segments = typeof path == 'string' ? path.split('/') : path
|
48 |
|
49 | return segments.reduce((node, segment) => {
|
50 | return node.children[segment]
|
51 | }, this)
|
52 | }
|
53 |
|
54 | remove = async () => {}
|
55 |
|
56 | change = async () => {
|
57 | const fileContents = (await fs.readFile(this.path)).toString(),
|
58 | { content, data } = matter(fileContents)
|
59 |
|
60 | this.source = content
|
61 | this.data = data
|
62 | }
|
63 |
|
64 | get isFile() {
|
65 | return !this.isDirectory
|
66 | }
|
67 |
|
68 | get relativePath() {
|
69 | return this.path.replace(config.srcDir, '')
|
70 | }
|
71 |
|
72 | get prepackPath() {
|
73 | return this.path
|
74 | .replace(/\.md$/, '.html')
|
75 | .replace(config.srcDir, config.prePackDir)
|
76 | }
|
77 |
|
78 | get destPath() {
|
79 | return this.path
|
80 | .replace(/\.md$/, '.html')
|
81 | .replace(config.srcDir, config.destDir)
|
82 | }
|
83 |
|
84 | get pageContext() {
|
85 | return {
|
86 | path: this.path,
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | export default new Node({ isRoot: true })
|