@xyd-js/cli 0.1.0-xyd.3 → 0.1.0-xyd.31
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/.cli/bin.js +3 -0
- package/.cli/index.js +45726 -0
- package/.cli/package.json +38 -0
- package/.cli/plugins/xyd-plugin-zero/src/pages/api-reference-source.tsx +272 -0
- package/.cli/plugins/xyd-plugin-zero/src/pages/api-reference.tsx +90 -211
- package/.cli/plugins/xyd-plugin-zero/src/pages/docs.tsx +53 -25
- package/.cli/pnpm-lock.yaml +4425 -0
- package/.cli/{host/vite.config.ts → vite.config.ts} +1 -1
- package/LICENSE +21 -0
- package/package.json +17 -20
- package/postinstall.js +15 -0
- package/.cli/dist/index.js +0 -12417
- package/.cli/host/.react-router/types/app/+types/root.ts +0 -40
- package/.cli/host/node_modules/.vite/deps/@mdx-js_mdx.js +0 -81
- package/.cli/host/node_modules/.vite/deps/@mdx-js_mdx.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/@mdx-js_rollup.js +0 -4003
- package/.cli/host/node_modules/.vite/deps/@mdx-js_rollup.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/@radix-ui_react-icons.js +0 -7531
- package/.cli/host/node_modules/.vite/deps/@radix-ui_react-icons.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/@radix-ui_react-tabs.js +0 -917
- package/.cli/host/node_modules/.vite/deps/@radix-ui_react-tabs.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/_metadata.json +0 -157
- package/.cli/host/node_modules/.vite/deps/chunk-2TUXWMP5.js +0 -46
- package/.cli/host/node_modules/.vite/deps/chunk-2TUXWMP5.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-DNIFH2K7.js +0 -3461
- package/.cli/host/node_modules/.vite/deps/chunk-DNIFH2K7.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-ERHH4CDL.js +0 -23875
- package/.cli/host/node_modules/.vite/deps/chunk-ERHH4CDL.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-ETJV5QNK.js +0 -27
- package/.cli/host/node_modules/.vite/deps/chunk-ETJV5QNK.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-GPEJJ3KZ.js +0 -1906
- package/.cli/host/node_modules/.vite/deps/chunk-GPEJJ3KZ.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-IVP26VTC.js +0 -21
- package/.cli/host/node_modules/.vite/deps/chunk-IVP26VTC.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-MJUUSK53.js +0 -894
- package/.cli/host/node_modules/.vite/deps/chunk-MJUUSK53.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-NHN7DW4J.js +0 -928
- package/.cli/host/node_modules/.vite/deps/chunk-NHN7DW4J.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-OO6QDGMA.js +0 -10609
- package/.cli/host/node_modules/.vite/deps/chunk-OO6QDGMA.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-OUN4SSIE.js +0 -205
- package/.cli/host/node_modules/.vite/deps/chunk-OUN4SSIE.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-TKNG6GUJ.js +0 -894
- package/.cli/host/node_modules/.vite/deps/chunk-TKNG6GUJ.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-TM4FKLNO.js +0 -21628
- package/.cli/host/node_modules/.vite/deps/chunk-TM4FKLNO.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/chunk-V2IF7L2E.js +0 -12
- package/.cli/host/node_modules/.vite/deps/chunk-V2IF7L2E.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/gray-matter.js +0 -3492
- package/.cli/host/node_modules/.vite/deps/gray-matter.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/lucide-react.js +0 -34742
- package/.cli/host/node_modules/.vite/deps/lucide-react.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/package.json +0 -3
- package/.cli/host/node_modules/.vite/deps/react-dom.js +0 -7
- package/.cli/host/node_modules/.vite/deps/react-dom.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react-dom_client.js +0 -39
- package/.cli/host/node_modules/.vite/deps/react-dom_client.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react-router.js +0 -243
- package/.cli/host/node_modules/.vite/deps/react-router.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react-router_dom.js +0 -212
- package/.cli/host/node_modules/.vite/deps/react-router_dom.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react.js +0 -6
- package/.cli/host/node_modules/.vite/deps/react.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react_jsx-dev-runtime.js +0 -913
- package/.cli/host/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/react_jsx-runtime.js +0 -7
- package/.cli/host/node_modules/.vite/deps/react_jsx-runtime.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/remark-frontmatter.js +0 -428
- package/.cli/host/node_modules/.vite/deps/remark-frontmatter.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/remark-gfm.js +0 -3122
- package/.cli/host/node_modules/.vite/deps/remark-gfm.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/remark-mdx-frontmatter.js +0 -10482
- package/.cli/host/node_modules/.vite/deps/remark-mdx-frontmatter.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/unist-util-visit.js +0 -14
- package/.cli/host/node_modules/.vite/deps/unist-util-visit.js.map +0 -7
- package/.cli/host/node_modules/.vite/deps/vfile.js +0 -8
- package/.cli/host/node_modules/.vite/deps/vfile.js.map +0 -7
- package/.cli/host/package.json +0 -43
- package/bin.js +0 -3
- /package/.cli/{host/app → app}/root.tsx +0 -0
- /package/.cli/{host/app → app}/routes.ts +0 -0
- /package/.cli/{dist/index.d.ts → index.d.ts} +0 -0
- /package/.cli/{host/postcss.config.cjs → postcss.config.cjs} +0 -0
- /package/.cli/{host/react-router.config.ts → react-router.config.ts} +0 -0
- /package/.cli/{host/tsconfig.json → tsconfig.json} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"private": true,
|
|
3
|
+
"name": "@xyd-js/documan-host",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"xyd": "bin.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@xyd-js/theme-poetry": "0.1.0-xyd.23",
|
|
13
|
+
"@xyd-js/react-router-dev": "7.1.1-xyd.4",
|
|
14
|
+
"@readme/oas-to-snippet": "^26.0.1",
|
|
15
|
+
"@react-router/node": "7.1.1",
|
|
16
|
+
"@react-router/serve": "7.1.1",
|
|
17
|
+
"@react-router/dev": "7.1.1",
|
|
18
|
+
"react-router": "7.1.1",
|
|
19
|
+
"isbot": "^5",
|
|
20
|
+
"remark-frontmatter": "^5.0.0",
|
|
21
|
+
"remark-mdx-frontmatter": "^5.0.0",
|
|
22
|
+
"json-to-graphql-query": "^2.3.0",
|
|
23
|
+
"remark": "^15.0.1",
|
|
24
|
+
"unist-builder": "^4.0.0",
|
|
25
|
+
"oas": "^25.0.3",
|
|
26
|
+
"openapi-sampler": "^1.5.1",
|
|
27
|
+
"json-schema-ref-parser": "^9.0.9",
|
|
28
|
+
"typedoc": "^0.28.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@mdx-js/rollup": "^3.1.0",
|
|
32
|
+
"vite": "^5.4.9",
|
|
33
|
+
"semver": "^7.6.3",
|
|
34
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
35
|
+
"autoprefixer": "^10.4.20",
|
|
36
|
+
"postcss": "^8.4.47"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import {promises as fs} from "fs";
|
|
3
|
+
|
|
4
|
+
import React, {} from "react";
|
|
5
|
+
import {redirect} from "react-router";
|
|
6
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
7
|
+
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
|
|
8
|
+
import remarkGfm from "remark-gfm";
|
|
9
|
+
import {parse} from "codehike";
|
|
10
|
+
import {visit} from "unist-util-visit";
|
|
11
|
+
import {recmaCodeHike, remarkCodeHike} from "codehike/mdx";
|
|
12
|
+
import {compile as mdxCompile} from "@mdx-js/mdx";
|
|
13
|
+
|
|
14
|
+
import {PageFrontMatter} from "@xyd-js/core";
|
|
15
|
+
import getContentComponents from "@xyd-js/components/content";
|
|
16
|
+
import {mapSettingsToProps} from "@xyd-js/framework/hydration";
|
|
17
|
+
import {Framework, type FwSidebarGroupProps} from "@xyd-js/framework/react";
|
|
18
|
+
import {AtlasIndex} from "@xyd-js/atlas/atlas-index";
|
|
19
|
+
import type {IBreadcrumb, INavLinks} from "@xyd-js/ui";
|
|
20
|
+
|
|
21
|
+
import Theme from "virtual:xyd-theme" // TODO: for some reasons this cannot be hydrated by react-router
|
|
22
|
+
import settings from 'virtual:xyd-settings';
|
|
23
|
+
|
|
24
|
+
import "virtual:xyd-theme/index.css"
|
|
25
|
+
import "virtual:xyd-theme-override/index.css"
|
|
26
|
+
|
|
27
|
+
interface loaderData {
|
|
28
|
+
sidebarGroups: FwSidebarGroupProps[]
|
|
29
|
+
breadcrumbs: IBreadcrumb[],
|
|
30
|
+
navlinks?: INavLinks,
|
|
31
|
+
toc: PageFrontMatter
|
|
32
|
+
slug: string
|
|
33
|
+
code: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const contentComponents = getContentComponents()
|
|
37
|
+
|
|
38
|
+
// since unist does not support heading level > 6, we need to normalize them
|
|
39
|
+
function normalizeCustomHeadings() {
|
|
40
|
+
return (tree: any) => {
|
|
41
|
+
visit(tree, 'paragraph', (node, index, parent) => {
|
|
42
|
+
if (!node.children[0].value) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
const match = node.children[0] && node.children[0].value.match(/^(#+)\s+(.*)/);
|
|
46
|
+
if (match) {
|
|
47
|
+
const level = match[1].length;
|
|
48
|
+
const text = match[2];
|
|
49
|
+
if (level > 6) {
|
|
50
|
+
// Create a new heading node with depth 6
|
|
51
|
+
const headingNode = {
|
|
52
|
+
type: 'heading',
|
|
53
|
+
depth: level,
|
|
54
|
+
children: [{type: 'text', value: text}]
|
|
55
|
+
};
|
|
56
|
+
// Replace the paragraph node with the new heading node
|
|
57
|
+
//@ts-ignore
|
|
58
|
+
parent.children[index] = headingNode;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const codeHikeOptions = {
|
|
66
|
+
lineNumbers: true,
|
|
67
|
+
showCopyButton: true,
|
|
68
|
+
autoImport: true,
|
|
69
|
+
components: {},
|
|
70
|
+
// syntaxHighlighting: { // TODO: !!! FROM SETTINGS !!! wait for rr7 rsc ??
|
|
71
|
+
// theme: "github-dark",
|
|
72
|
+
// },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const compiledBySlug = {}
|
|
76
|
+
|
|
77
|
+
// TODO: map every file and merge them or load via client-side ?
|
|
78
|
+
async function compileBySlug(slug: string) {
|
|
79
|
+
if (compiledBySlug[slug]) {
|
|
80
|
+
return compiledBySlug[slug]
|
|
81
|
+
}
|
|
82
|
+
console.time("api-reference compileBySlug")
|
|
83
|
+
// TODO: cwd ?
|
|
84
|
+
let filePath = path.join(process.cwd(), `${slug}.md`)
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await fs.access(filePath)
|
|
88
|
+
} catch (_) {
|
|
89
|
+
filePath = path.join(process.cwd(), `${slug}.mdx`)
|
|
90
|
+
|
|
91
|
+
await fs.access(filePath)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.time("api-reference readFile")
|
|
95
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
96
|
+
console.timeEnd("api-reference readFile")
|
|
97
|
+
|
|
98
|
+
console.time("api-reference compile")
|
|
99
|
+
const resp = await compile(content)
|
|
100
|
+
console.timeEnd("api-reference compile")
|
|
101
|
+
|
|
102
|
+
console.timeEnd("api-reference compileBySlug")
|
|
103
|
+
compiledBySlug[slug] = resp
|
|
104
|
+
return resp
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function compile(content: string): Promise<string> {
|
|
108
|
+
const compiled = await mdxCompile(content, {
|
|
109
|
+
remarkPlugins: [
|
|
110
|
+
normalizeCustomHeadings,
|
|
111
|
+
[
|
|
112
|
+
remarkCodeHike,
|
|
113
|
+
codeHikeOptions
|
|
114
|
+
],
|
|
115
|
+
remarkFrontmatter,
|
|
116
|
+
remarkMdxFrontmatter,
|
|
117
|
+
remarkGfm
|
|
118
|
+
],
|
|
119
|
+
rehypePlugins: [],
|
|
120
|
+
recmaPlugins: [
|
|
121
|
+
[
|
|
122
|
+
recmaCodeHike,
|
|
123
|
+
codeHikeOptions
|
|
124
|
+
]
|
|
125
|
+
],
|
|
126
|
+
outputFormat: 'function-body',
|
|
127
|
+
development: false,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return String(compiled)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface loaderData {
|
|
134
|
+
sidebarGroups: FwSidebarGroupProps[]
|
|
135
|
+
toc: PageFrontMatter
|
|
136
|
+
slug: string
|
|
137
|
+
code: string
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function getPathname(url: string) {
|
|
141
|
+
const parsedUrl = new URL(url);
|
|
142
|
+
return parsedUrl.pathname.replace(/^\//, '');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// TODO: fix any
|
|
146
|
+
function findFirstUrl(items: any): string {
|
|
147
|
+
const queue = [...items];
|
|
148
|
+
|
|
149
|
+
while (queue.length > 0) {
|
|
150
|
+
const item = queue.shift();
|
|
151
|
+
|
|
152
|
+
if (item.href) {
|
|
153
|
+
return item.href;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (item.items) {
|
|
157
|
+
queue.push(...item.items);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return "";
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface data {
|
|
165
|
+
groups: FwSidebarGroupProps[],
|
|
166
|
+
breadcrumbs: IBreadcrumb[]
|
|
167
|
+
navlinks?: INavLinks
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const mapSettingsToPropsMap: { [key: string]: data } = {}
|
|
171
|
+
|
|
172
|
+
// TODO: fix any
|
|
173
|
+
export async function loader({request}: { request: any }) {
|
|
174
|
+
console.time("api-reference loader")
|
|
175
|
+
const slug = getPathname(request.url);
|
|
176
|
+
|
|
177
|
+
let code = "";
|
|
178
|
+
let error: any;
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
code = await compileBySlug(slug);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
error = e;
|
|
184
|
+
}
|
|
185
|
+
let data: data
|
|
186
|
+
|
|
187
|
+
if (!mapSettingsToPropsMap[slug]) {
|
|
188
|
+
data = await mapSettingsToProps(
|
|
189
|
+
settings,
|
|
190
|
+
slug
|
|
191
|
+
);
|
|
192
|
+
mapSettingsToPropsMap[slug] = data
|
|
193
|
+
} else {
|
|
194
|
+
data = mapSettingsToPropsMap[slug]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const {groups: sidebarGroups, breadcrumbs, navlinks} = data;
|
|
198
|
+
|
|
199
|
+
if (error) {
|
|
200
|
+
if (sidebarGroups && error.code === "ENOENT") {
|
|
201
|
+
const firstItem = findFirstUrl(sidebarGroups?.[0]?.items);
|
|
202
|
+
|
|
203
|
+
if (firstItem) {
|
|
204
|
+
return redirect(firstItem);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.error(error);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
console.timeEnd("api-reference loader")
|
|
212
|
+
return {
|
|
213
|
+
sidebarGroups,
|
|
214
|
+
breadcrumbs,
|
|
215
|
+
navlinks,
|
|
216
|
+
slug,
|
|
217
|
+
code,
|
|
218
|
+
} as loaderData;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function mdxExport(code: string) {
|
|
222
|
+
const scope = {
|
|
223
|
+
Fragment: React.Fragment,
|
|
224
|
+
jsxs: React.createElement,
|
|
225
|
+
jsx: React.createElement,
|
|
226
|
+
jsxDEV: React.createElement,
|
|
227
|
+
}
|
|
228
|
+
const fn = new Function(...Object.keys(scope), code)
|
|
229
|
+
return fn(scope)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function MemoMDXComponent(codeComponent: any) {
|
|
233
|
+
return React.useMemo(
|
|
234
|
+
() => codeComponent ? codeComponent : null,
|
|
235
|
+
[codeComponent]
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// // TODO: move to content?
|
|
240
|
+
function mdxContent(code: string) {
|
|
241
|
+
const content = mdxExport(code) // TODO: fix any
|
|
242
|
+
if (!mdxExport) {
|
|
243
|
+
return {}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
component: content?.default,
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// TODO: in the future more smoother loader - first fast server render then move to ideal position of client and then replace and 3 items at start
|
|
252
|
+
export default function APIReference({loaderData}: { loaderData: loaderData }) {
|
|
253
|
+
const content = mdxContent(loaderData.code)
|
|
254
|
+
const serverComponent = content ? parse(content.component, {
|
|
255
|
+
components: contentComponents
|
|
256
|
+
}) : null
|
|
257
|
+
|
|
258
|
+
const memoizedServerComponent = MemoMDXComponent(serverComponent)
|
|
259
|
+
|
|
260
|
+
return <Framework
|
|
261
|
+
settings={settings}
|
|
262
|
+
sidebarGroups={loaderData.sidebarGroups || []}
|
|
263
|
+
breadcrumbs={loaderData.breadcrumbs || []}
|
|
264
|
+
navlinks={loaderData.navlinks}
|
|
265
|
+
>
|
|
266
|
+
<Theme>
|
|
267
|
+
<AtlasIndex
|
|
268
|
+
data={memoizedServerComponent?.references[0]}
|
|
269
|
+
/>
|
|
270
|
+
</Theme>
|
|
271
|
+
</Framework>
|
|
272
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import {promises as fs} from "fs";
|
|
3
3
|
|
|
4
|
-
import React, {
|
|
5
|
-
import {redirect
|
|
4
|
+
import React, {} from "react";
|
|
5
|
+
import {redirect} from "react-router";
|
|
6
6
|
import remarkFrontmatter from "remark-frontmatter";
|
|
7
7
|
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
|
|
8
8
|
import remarkGfm from "remark-gfm";
|
|
@@ -12,14 +12,12 @@ import {recmaCodeHike, remarkCodeHike} from "codehike/mdx";
|
|
|
12
12
|
import {compile as mdxCompile} from "@mdx-js/mdx";
|
|
13
13
|
|
|
14
14
|
import {PageFrontMatter} from "@xyd-js/core";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
AtlasLazy
|
|
18
|
-
} from "@xyd-js/atlas";
|
|
15
|
+
import {BaseThemeSettings} from "@xyd-js/themes";
|
|
19
16
|
import getContentComponents from "@xyd-js/components/content";
|
|
20
17
|
import {mapSettingsToProps} from "@xyd-js/framework/hydration";
|
|
21
|
-
import {Framework} from "@xyd-js/framework/react";
|
|
22
|
-
import
|
|
18
|
+
import {Framework, type FwSidebarGroupProps} from "@xyd-js/framework/react";
|
|
19
|
+
import {AtlasLazy} from "@xyd-js/atlas";
|
|
20
|
+
import type {IBreadcrumb, INavLinks} from "@xyd-js/ui";
|
|
23
21
|
|
|
24
22
|
import Theme from "virtual:xyd-theme" // TODO: for some reasons this cannot be hydrated by react-router
|
|
25
23
|
import settings from 'virtual:xyd-settings';
|
|
@@ -27,6 +25,15 @@ import settings from 'virtual:xyd-settings';
|
|
|
27
25
|
import "virtual:xyd-theme/index.css"
|
|
28
26
|
import "virtual:xyd-theme-override/index.css"
|
|
29
27
|
|
|
28
|
+
interface loaderData {
|
|
29
|
+
sidebarGroups: FwSidebarGroupProps[]
|
|
30
|
+
breadcrumbs: IBreadcrumb[],
|
|
31
|
+
navlinks?: INavLinks,
|
|
32
|
+
toc: PageFrontMatter
|
|
33
|
+
slug: string
|
|
34
|
+
code: string
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
const contentComponents = getContentComponents()
|
|
31
38
|
const ComponentContent = contentComponents.Content
|
|
32
39
|
|
|
@@ -67,8 +74,14 @@ const codeHikeOptions = {
|
|
|
67
74
|
// },
|
|
68
75
|
};
|
|
69
76
|
|
|
77
|
+
const compiledBySlug = {}
|
|
78
|
+
|
|
70
79
|
// TODO: map every file and merge them or load via client-side ?
|
|
71
80
|
async function compileBySlug(slug: string) {
|
|
81
|
+
if (compiledBySlug[slug]) {
|
|
82
|
+
return compiledBySlug[slug]
|
|
83
|
+
}
|
|
84
|
+
console.time("api-reference compileBySlug")
|
|
72
85
|
// TODO: cwd ?
|
|
73
86
|
let filePath = path.join(process.cwd(), `${slug}.md`)
|
|
74
87
|
|
|
@@ -80,23 +93,37 @@ async function compileBySlug(slug: string) {
|
|
|
80
93
|
await fs.access(filePath)
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
console.time("api-reference readFile")
|
|
83
97
|
const content = await fs.readFile(filePath, "utf-8");
|
|
98
|
+
console.timeEnd("api-reference readFile")
|
|
84
99
|
|
|
85
|
-
|
|
100
|
+
console.time("api-reference compile")
|
|
101
|
+
const resp = await compile(content)
|
|
102
|
+
console.timeEnd("api-reference compile")
|
|
103
|
+
|
|
104
|
+
console.timeEnd("api-reference compileBySlug")
|
|
105
|
+
compiledBySlug[slug] = resp
|
|
106
|
+
return resp
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
async function compile(content: string): Promise<string> {
|
|
89
110
|
const compiled = await mdxCompile(content, {
|
|
90
111
|
remarkPlugins: [
|
|
91
112
|
normalizeCustomHeadings,
|
|
92
|
-
[
|
|
113
|
+
[
|
|
114
|
+
remarkCodeHike,
|
|
115
|
+
codeHikeOptions
|
|
116
|
+
],
|
|
93
117
|
remarkFrontmatter,
|
|
94
118
|
remarkMdxFrontmatter,
|
|
95
119
|
remarkGfm
|
|
96
120
|
],
|
|
97
121
|
rehypePlugins: [],
|
|
98
122
|
recmaPlugins: [
|
|
99
|
-
[
|
|
123
|
+
[
|
|
124
|
+
recmaCodeHike,
|
|
125
|
+
codeHikeOptions
|
|
126
|
+
]
|
|
100
127
|
],
|
|
101
128
|
outputFormat: 'function-body',
|
|
102
129
|
development: false,
|
|
@@ -136,42 +163,61 @@ function findFirstUrl(items: any): string {
|
|
|
136
163
|
return "";
|
|
137
164
|
}
|
|
138
165
|
|
|
166
|
+
interface data {
|
|
167
|
+
groups: FwSidebarGroupProps[],
|
|
168
|
+
breadcrumbs: IBreadcrumb[]
|
|
169
|
+
navlinks?: INavLinks
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const mapSettingsToPropsMap: { [key: string]: data } = {}
|
|
173
|
+
|
|
139
174
|
// TODO: fix any
|
|
140
175
|
export async function loader({request}: { request: any }) {
|
|
141
|
-
|
|
176
|
+
console.time("api-reference loader")
|
|
177
|
+
const slug = getPathname(request.url);
|
|
142
178
|
|
|
143
|
-
let code = ""
|
|
144
|
-
let error: any
|
|
179
|
+
let code = "";
|
|
180
|
+
let error: any;
|
|
145
181
|
|
|
146
182
|
try {
|
|
147
|
-
code = await compileBySlug(slug)
|
|
183
|
+
code = await compileBySlug(slug);
|
|
148
184
|
} catch (e) {
|
|
149
|
-
error = e
|
|
185
|
+
error = e;
|
|
186
|
+
}
|
|
187
|
+
let data: data
|
|
188
|
+
|
|
189
|
+
if (!mapSettingsToPropsMap[slug]) {
|
|
190
|
+
data = await mapSettingsToProps(
|
|
191
|
+
settings,
|
|
192
|
+
slug
|
|
193
|
+
);
|
|
194
|
+
mapSettingsToPropsMap[slug] = data
|
|
195
|
+
} else {
|
|
196
|
+
data = mapSettingsToPropsMap[slug]
|
|
150
197
|
}
|
|
151
198
|
|
|
152
|
-
const {groups: sidebarGroups} =
|
|
153
|
-
settings,
|
|
154
|
-
slug
|
|
155
|
-
)
|
|
199
|
+
const {groups: sidebarGroups, breadcrumbs, navlinks} = data;
|
|
156
200
|
|
|
157
|
-
// TODO: dry with docs.tsx - resolver?
|
|
158
201
|
if (error) {
|
|
159
202
|
if (sidebarGroups && error.code === "ENOENT") {
|
|
160
|
-
const firstItem = findFirstUrl(sidebarGroups?.[0]?.items)
|
|
203
|
+
const firstItem = findFirstUrl(sidebarGroups?.[0]?.items);
|
|
161
204
|
|
|
162
205
|
if (firstItem) {
|
|
163
|
-
return redirect(firstItem)
|
|
206
|
+
return redirect(firstItem);
|
|
164
207
|
}
|
|
165
208
|
}
|
|
166
209
|
|
|
167
|
-
console.error(error)
|
|
210
|
+
console.error(error);
|
|
168
211
|
}
|
|
169
212
|
|
|
213
|
+
console.timeEnd("api-reference loader")
|
|
170
214
|
return {
|
|
171
215
|
sidebarGroups,
|
|
216
|
+
breadcrumbs,
|
|
217
|
+
navlinks,
|
|
172
218
|
slug,
|
|
173
|
-
code
|
|
174
|
-
} as loaderData
|
|
219
|
+
code,
|
|
220
|
+
} as loaderData;
|
|
175
221
|
}
|
|
176
222
|
|
|
177
223
|
function mdxExport(code: string) {
|
|
@@ -185,157 +231,6 @@ function mdxExport(code: string) {
|
|
|
185
231
|
return fn(scope)
|
|
186
232
|
}
|
|
187
233
|
|
|
188
|
-
function renderollAsyncClient(routeId: string, slug: string) {
|
|
189
|
-
return async () => {
|
|
190
|
-
let mod;
|
|
191
|
-
let urlPrefix;
|
|
192
|
-
let data;
|
|
193
|
-
|
|
194
|
-
// TODO: fix any
|
|
195
|
-
function moduleData(mods: any, id: string) {
|
|
196
|
-
mod = mods.default[id]
|
|
197
|
-
if (!mod) {
|
|
198
|
-
throw new Error(`Unknown openapi id: ${id}`)
|
|
199
|
-
}
|
|
200
|
-
urlPrefix = mod.urlPrefix
|
|
201
|
-
data = mod.data
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
switch (routeId) {
|
|
205
|
-
case "xyd-plugin-zero/graphql": {
|
|
206
|
-
// @ts-ignore
|
|
207
|
-
mod = await import("virtual:xyd-plugin-zero/graphql");
|
|
208
|
-
urlPrefix = "/docs/api/graphql" // TODO: dynamic urlPreifx
|
|
209
|
-
data = mod.default.data
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case "xyd-plugin-zero/openapi": {
|
|
213
|
-
// @ts-ignore
|
|
214
|
-
mod = await import("virtual:xyd-plugin-zero/openapi");
|
|
215
|
-
urlPrefix = "/docs/api/openapi" // TODO: dynamic urlPrefix
|
|
216
|
-
data = mod.default.data
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
default: {
|
|
220
|
-
if (routeId.includes("xyd-plugin-zero/openapi")) {
|
|
221
|
-
const [_, id] = routeId.split("xyd-plugin-zero/openapi-")
|
|
222
|
-
// @ts-ignore
|
|
223
|
-
const mods = await import("virtual:xyd-plugin-zero/openapi")
|
|
224
|
-
moduleData(mods, id)
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
if (routeId.includes("xyd-plugin-zero/graphql")) {
|
|
228
|
-
const [_, id] = routeId.split("xyd-plugin-zero/graphql-")
|
|
229
|
-
// @ts-ignore
|
|
230
|
-
const mods = await import("virtual:xyd-plugin-zero/graphql")
|
|
231
|
-
moduleData(mods, id)
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
throw new Error(`Unknown routeId: ${routeId}`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (!Array.isArray(data)) {
|
|
240
|
-
console.warn(`mod.default is not an array, current type is: ${typeof mod.default}`)
|
|
241
|
-
|
|
242
|
-
return
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// TODO: in the future custom position
|
|
246
|
-
const prevRefs = []
|
|
247
|
-
const nextRefs = []
|
|
248
|
-
const mdxComponentsPrev: any[] = []
|
|
249
|
-
const mdxComponentsNext: any[] = []
|
|
250
|
-
|
|
251
|
-
let pos = 0;
|
|
252
|
-
|
|
253
|
-
for (const chunk of data) {
|
|
254
|
-
if (!chunk) {
|
|
255
|
-
continue
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (chunk.slug === slug) {
|
|
259
|
-
pos = 1
|
|
260
|
-
continue
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const references = pos === 0 ? prevRefs : nextRefs
|
|
264
|
-
|
|
265
|
-
const code = await compile(chunk.content) // TODO: do we need real path?
|
|
266
|
-
const mdx = mdxExport(code)
|
|
267
|
-
const Content = mdx.default
|
|
268
|
-
const content = Content ? parse(Content, {
|
|
269
|
-
components: contentComponents
|
|
270
|
-
}) : null
|
|
271
|
-
|
|
272
|
-
// TODO: support non-fererence pages
|
|
273
|
-
if (content.references) {
|
|
274
|
-
references.push(...(content?.references || []) as [])
|
|
275
|
-
} else {
|
|
276
|
-
const mdxComponents = pos === 0 ? mdxComponentsPrev : mdxComponentsNext
|
|
277
|
-
|
|
278
|
-
mdxComponents.push(<div data-slug={`/${chunk.slug}`}>
|
|
279
|
-
<ComponentContent>
|
|
280
|
-
{content}
|
|
281
|
-
</ComponentContent>
|
|
282
|
-
</div>)
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return [
|
|
287
|
-
({onLoaded}) => <>
|
|
288
|
-
<ComponentContent>
|
|
289
|
-
{mdxComponentsPrev}
|
|
290
|
-
</ComponentContent>
|
|
291
|
-
|
|
292
|
-
{
|
|
293
|
-
prevRefs.length ? <div>
|
|
294
|
-
<AtlasLazy
|
|
295
|
-
references={prevRefs}
|
|
296
|
-
urlPrefix={urlPrefix}
|
|
297
|
-
slug={slug}
|
|
298
|
-
onLoaded={onLoaded}
|
|
299
|
-
/>
|
|
300
|
-
</div> : null
|
|
301
|
-
}
|
|
302
|
-
</>,
|
|
303
|
-
|
|
304
|
-
({onLoaded}) => <>
|
|
305
|
-
<ComponentContent>
|
|
306
|
-
{mdxComponentsNext}
|
|
307
|
-
</ComponentContent>
|
|
308
|
-
|
|
309
|
-
{
|
|
310
|
-
nextRefs.length ? <div>
|
|
311
|
-
<AtlasLazy
|
|
312
|
-
references={nextRefs}
|
|
313
|
-
urlPrefix={urlPrefix}
|
|
314
|
-
slug={slug}
|
|
315
|
-
onLoaded={onLoaded}
|
|
316
|
-
/>
|
|
317
|
-
</div> : null
|
|
318
|
-
}
|
|
319
|
-
</>
|
|
320
|
-
]
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
function getRouteId() {
|
|
325
|
-
const routerState = useContext(UNSAFE_DataRouterStateContext)
|
|
326
|
-
let routeId: string = ""
|
|
327
|
-
|
|
328
|
-
routerState?.matches?.forEach(match => {
|
|
329
|
-
const loader = routerState?.loaderData[match?.route?.id]
|
|
330
|
-
|
|
331
|
-
if (loader) {
|
|
332
|
-
routeId = match?.route?.id
|
|
333
|
-
}
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
return routeId
|
|
337
|
-
}
|
|
338
|
-
|
|
339
234
|
function MemoMDXComponent(codeComponent: any) {
|
|
340
235
|
return React.useMemo(
|
|
341
236
|
() => codeComponent ? codeComponent : null,
|
|
@@ -355,6 +250,15 @@ function mdxContent(code: string) {
|
|
|
355
250
|
}
|
|
356
251
|
}
|
|
357
252
|
|
|
253
|
+
// TODO: get settings from md files??
|
|
254
|
+
function themeSettings(
|
|
255
|
+
this: BaseThemeSettings,
|
|
256
|
+
) {
|
|
257
|
+
return this
|
|
258
|
+
.layout.size("large")
|
|
259
|
+
.toc.hide()
|
|
260
|
+
}
|
|
261
|
+
|
|
358
262
|
// TODO: in the future more smoother loader - first fast server render then move to ideal position of client and then replace and 3 items at start
|
|
359
263
|
export default function APIReference({loaderData}: { loaderData: loaderData }) {
|
|
360
264
|
const content = mdxContent(loaderData.code)
|
|
@@ -364,43 +268,18 @@ export default function APIReference({loaderData}: { loaderData: loaderData }) {
|
|
|
364
268
|
|
|
365
269
|
const memoizedServerComponent = MemoMDXComponent(serverComponent)
|
|
366
270
|
|
|
367
|
-
const serverAtlasOrMDX = memoizedServerComponent?.references ?
|
|
368
|
-
<AtlasLazy
|
|
369
|
-
references={memoizedServerComponent?.references || []}
|
|
370
|
-
slug={loaderData.slug.startsWith("/") ? loaderData.slug : `/${loaderData.slug}`}
|
|
371
|
-
urlPrefix="/"
|
|
372
|
-
/> :
|
|
373
|
-
<ComponentContent>
|
|
374
|
-
{memoizedServerComponent}
|
|
375
|
-
</ComponentContent>
|
|
376
|
-
|
|
377
|
-
const routeId = getRouteId()
|
|
378
|
-
|
|
379
|
-
const RenderollContent = renderoll(
|
|
380
|
-
renderollAsyncClient(routeId, loaderData.slug),
|
|
381
|
-
{
|
|
382
|
-
decorator: ({children}) => <ComponentContent>
|
|
383
|
-
{children}
|
|
384
|
-
</ComponentContent>
|
|
385
|
-
}
|
|
386
|
-
)
|
|
387
|
-
|
|
388
271
|
return <Framework
|
|
389
272
|
settings={settings}
|
|
390
|
-
sidebarGroups={loaderData.sidebarGroups}
|
|
273
|
+
sidebarGroups={loaderData.sidebarGroups || []}
|
|
274
|
+
breadcrumbs={loaderData.breadcrumbs || []}
|
|
275
|
+
navlinks={loaderData.navlinks}
|
|
391
276
|
>
|
|
392
|
-
<Theme
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
}}
|
|
400
|
-
>
|
|
401
|
-
<RenderollContent>
|
|
402
|
-
{serverAtlasOrMDX}
|
|
403
|
-
</RenderollContent>
|
|
277
|
+
<Theme settings={themeSettings}>
|
|
278
|
+
<AtlasLazy
|
|
279
|
+
references={memoizedServerComponent?.references || []}
|
|
280
|
+
slug={loaderData.slug.startsWith("/") ? loaderData.slug : `/${loaderData.slug}`}
|
|
281
|
+
urlPrefix="/"
|
|
282
|
+
/>
|
|
404
283
|
</Theme>
|
|
405
284
|
</Framework>
|
|
406
285
|
}
|