@xyd-js/content 0.1.0-xyd.10
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.
- package/CHANGELOG.md +49 -0
- package/README.md +3 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +22004 -0
- package/dist/index.js.map +1 -0
- package/dist/md.d.ts +14 -0
- package/dist/md.js +20410 -0
- package/dist/md.js.map +1 -0
- package/dist/mdToc-CYxzibVZ.d.ts +11 -0
- package/dist/vite.d.ts +987 -0
- package/dist/vite.js +20420 -0
- package/dist/vite.js.map +1 -0
- package/package.json +45 -0
- package/packages/md/index.ts +13 -0
- package/packages/md/plugins/index.ts +26 -0
- package/packages/md/plugins/mdCode.ts +19 -0
- package/packages/md/plugins/mdCodeGroup.ts +40 -0
- package/packages/md/plugins/mdComponentDirective.ts +141 -0
- package/packages/md/plugins/mdPage.ts +32 -0
- package/packages/md/plugins/mdThemeSettings.ts +30 -0
- package/packages/md/plugins/mdToc.ts +133 -0
- package/packages/vite/index.ts +14 -0
- package/src/fs.ts +43 -0
- package/src/index.ts +8 -0
- package/src/navigation.ts +172 -0
- package/tsconfig.json +26 -0
- package/tsup.config.ts +29 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {promises as fs} from 'fs';
|
|
2
|
+
import fs2, {open} from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import React from "react";
|
|
6
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
7
|
+
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
|
|
8
|
+
import matter from 'gray-matter';
|
|
9
|
+
import {VFile} from "vfile";
|
|
10
|
+
import {compile as mdxCompile} from "@mdx-js/mdx";
|
|
11
|
+
|
|
12
|
+
import {FrontMatter, Sidebar, PageFrontMatter, Header} from "@xyd-js/core";
|
|
13
|
+
|
|
14
|
+
// TODO: better algorithm + data structures - since it's on build time it's not a big deal nevertheless it should be changed in the future
|
|
15
|
+
|
|
16
|
+
// pageFrontMatters gets frontmatters for given navigation
|
|
17
|
+
export async function pageFrontMatters(navigation: Sidebar[]): Promise<PageFrontMatter> {
|
|
18
|
+
const frontmatters: PageFrontMatter = {}
|
|
19
|
+
|
|
20
|
+
const promises: Promise<any>[] = []
|
|
21
|
+
|
|
22
|
+
function mapPages(page: string | Sidebar) {
|
|
23
|
+
if (typeof page !== "string") {
|
|
24
|
+
page.pages?.forEach(mapPages)
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
promises.push(job(page, frontmatters))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
navigation.map(async (nav: Sidebar) => {
|
|
32
|
+
nav.pages?.forEach(mapPages)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
await Promise.all(promises)
|
|
36
|
+
|
|
37
|
+
return frontmatters
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// filterNavigation filter navigation items by top levels of 'header' configuration and current 'slug'
|
|
41
|
+
export function filterNavigationByLevels(
|
|
42
|
+
headers: Header[],
|
|
43
|
+
slug: string
|
|
44
|
+
) {
|
|
45
|
+
const topLevelTabMatcher = headers?.reduce((acc: any, header) => {
|
|
46
|
+
const tabLevel = header?.url?.split("/")?.length
|
|
47
|
+
|
|
48
|
+
if (!tabLevel) {
|
|
49
|
+
return {
|
|
50
|
+
...acc
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!acc[tabLevel]) {
|
|
55
|
+
return {
|
|
56
|
+
...acc,
|
|
57
|
+
[tabLevel]: new Set().add(header?.url)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
...acc,
|
|
63
|
+
[tabLevel]: acc[tabLevel].add(header?.url)
|
|
64
|
+
}
|
|
65
|
+
}, {}) as { [level: number]: Set<string> }
|
|
66
|
+
|
|
67
|
+
return (nav: Sidebar) => {
|
|
68
|
+
let match = false
|
|
69
|
+
|
|
70
|
+
Object.keys(topLevelTabMatcher).forEach((levelStr) => {
|
|
71
|
+
if (match) {
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
const level = parseInt(levelStr)
|
|
75
|
+
const findThisSlug = slug.split("/").filter(s => !!s).slice(0, level).join("/")
|
|
76
|
+
|
|
77
|
+
function findMatchedPage(page: string | Sidebar) {
|
|
78
|
+
if (typeof page !== "string") {
|
|
79
|
+
page.pages?.forEach(findMatchedPage)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
const findThisPage = page.split("/").filter(p => !!p).slice(0, level).join("/")
|
|
83
|
+
|
|
84
|
+
const set = topLevelTabMatcher[level]
|
|
85
|
+
|
|
86
|
+
if (set.has(findThisPage) && findThisPage === findThisSlug) {
|
|
87
|
+
match = true
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
nav?.pages?.forEach(findMatchedPage)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return match
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function mdxExport(code: string) {
|
|
100
|
+
const scope = {
|
|
101
|
+
Fragment: React.Fragment,
|
|
102
|
+
jsxs: React.createElement,
|
|
103
|
+
jsx: React.createElement,
|
|
104
|
+
jsxDEV: React.createElement,
|
|
105
|
+
}
|
|
106
|
+
const fn = new Function(...Object.keys(scope), code)
|
|
107
|
+
return fn(scope)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function getFrontmatter(filePath: string): Promise<FrontMatter> {
|
|
111
|
+
const body = await fs.readFile(filePath, "utf-8");
|
|
112
|
+
|
|
113
|
+
const vfile = new VFile({
|
|
114
|
+
path: filePath,
|
|
115
|
+
value: body,
|
|
116
|
+
contents: body
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const compiled = await mdxCompile(vfile, {
|
|
120
|
+
remarkPlugins: [
|
|
121
|
+
remarkFrontmatter,
|
|
122
|
+
remarkMdxFrontmatter
|
|
123
|
+
],
|
|
124
|
+
rehypePlugins: [],
|
|
125
|
+
recmaPlugins: [],
|
|
126
|
+
outputFormat: 'function-body',
|
|
127
|
+
development: false,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const code = String(compiled)
|
|
131
|
+
|
|
132
|
+
const {
|
|
133
|
+
reactFrontmatter, // in the future same key?
|
|
134
|
+
frontmatter
|
|
135
|
+
} = mdxExport(code)
|
|
136
|
+
|
|
137
|
+
const matter: FrontMatter = frontmatter
|
|
138
|
+
|
|
139
|
+
let title = ""
|
|
140
|
+
if (typeof matter.title === "string" ) {
|
|
141
|
+
title = matter.title
|
|
142
|
+
}
|
|
143
|
+
if (reactFrontmatter) {
|
|
144
|
+
if (typeof reactFrontmatter?.title === "function") {
|
|
145
|
+
matter.title = {
|
|
146
|
+
title,
|
|
147
|
+
code: reactFrontmatter.title.toString()
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return matter
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function job(page: string, frontmatters: PageFrontMatter) {
|
|
156
|
+
// TODO: it can be cwd because on build time it has entire path?
|
|
157
|
+
let filePath = path.join(process.cwd(), `${page}.mdx`) // TODO: support md toos
|
|
158
|
+
try {
|
|
159
|
+
await fs.access(filePath)
|
|
160
|
+
} catch (e) {
|
|
161
|
+
try {
|
|
162
|
+
const mdPath = filePath.replace(".mdx", ".md")
|
|
163
|
+
await fs.access(mdPath)
|
|
164
|
+
filePath = mdPath
|
|
165
|
+
} catch (e) {
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const matter = await getFrontmatter(filePath)
|
|
170
|
+
|
|
171
|
+
frontmatters[page] = matter
|
|
172
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"baseUrl": ".",
|
|
4
|
+
"paths": {
|
|
5
|
+
"@/mdx/*": ["src/mdx/*"],
|
|
6
|
+
"@/navigation/*": ["src/navigation/*"],
|
|
7
|
+
"@/utils/*": ["src/utils/*"],
|
|
8
|
+
"@/vite-plugins/*": ["src/vite-plugins/*"]
|
|
9
|
+
},
|
|
10
|
+
"target": "ES2020",
|
|
11
|
+
"module": "ESNext",
|
|
12
|
+
"moduleResolution": "node",
|
|
13
|
+
"strict": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"skipLibCheck": true,
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"outDir": "./dist",
|
|
18
|
+
"types": ["node", "estree", "vite"],
|
|
19
|
+
"declaration": true,
|
|
20
|
+
"declarationMap": true,
|
|
21
|
+
"incremental": true,
|
|
22
|
+
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
|
|
23
|
+
},
|
|
24
|
+
"include": ["src/**/*.ts"],
|
|
25
|
+
"exclude": ["node_modules", "dist"]
|
|
26
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {defineConfig, Options} from 'tsup';
|
|
2
|
+
|
|
3
|
+
const config: Options = {
|
|
4
|
+
entry: {
|
|
5
|
+
index: 'src/index.ts',
|
|
6
|
+
vite: 'packages/vite/index.ts',
|
|
7
|
+
md: 'packages/md/index.ts',
|
|
8
|
+
},
|
|
9
|
+
dts: {
|
|
10
|
+
entry: {
|
|
11
|
+
index: 'src/index.ts',
|
|
12
|
+
vite: 'packages/vite/index.ts',
|
|
13
|
+
md: 'packages/md/index.ts'
|
|
14
|
+
},
|
|
15
|
+
resolve: true, // Resolve external types
|
|
16
|
+
},
|
|
17
|
+
format: ['esm'], // Output both ESM and CJS formats
|
|
18
|
+
target: 'node16', // Ensure compatibility with Node.js 16
|
|
19
|
+
splitting: false, // Disable code splitting
|
|
20
|
+
sourcemap: true, // Generate source maps
|
|
21
|
+
clean: true, // Clean the output directory before each build
|
|
22
|
+
// esbuildOptions: (options) => {
|
|
23
|
+
// options.platform = 'node'; // Ensure the platform is set to Node.js
|
|
24
|
+
// options.external = ['node:fs/promises']; // Mark 'node:fs/promises' as external
|
|
25
|
+
// options.loader = { '.js': 'jsx' }; // Ensure proper handling of .js files
|
|
26
|
+
// },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default defineConfig(config);
|