fumapress 0.2.2 → 0.2.4
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/css/generated.css +103 -0
- package/dist/adapters/mdx.d.ts +12 -0
- package/dist/adapters/mdx.js +37 -0
- package/dist/components/flexsearch-static.js +24 -0
- package/dist/components/orama-search-static.js +34 -0
- package/dist/config.d.ts +84 -0
- package/dist/config.js +36 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/layouts/docs.d.ts +35 -0
- package/dist/layouts/docs.js +85 -0
- package/dist/layouts/home.d.ts +28 -0
- package/dist/layouts/home.js +34 -0
- package/dist/layouts/root.d.ts +10 -0
- package/dist/layouts/root.js +38 -0
- package/dist/lib/fs.js +18 -0
- package/dist/lib/shared.d.ts +41 -0
- package/dist/lib/shared.js +63 -0
- package/dist/lib/types.d.ts +33 -0
- package/dist/lib/vitefu.js +179 -0
- package/dist/plugins/flexsearch.d.ts +14 -0
- package/dist/plugins/flexsearch.js +35 -0
- package/dist/plugins/llms.txt.d.ts +11 -0
- package/dist/plugins/llms.txt.js +72 -0
- package/dist/plugins/orama-search.d.ts +14 -0
- package/dist/plugins/orama-search.js +35 -0
- package/dist/plugins/takumi.d.ts +16 -0
- package/dist/plugins/takumi.js +79 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.js +133 -0
- package/dist/vite.d.ts +6 -0
- package/dist/vite.js +45 -0
- package/package.json +10 -16
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
@source inline("@orama/orama");
|
|
2
|
+
@source inline("absolutePath");
|
|
3
|
+
@source inline("adapter");
|
|
4
|
+
@source inline("as");
|
|
5
|
+
@source inline("async");
|
|
6
|
+
@source inline("await");
|
|
7
|
+
@source inline("body");
|
|
8
|
+
@source inline("border-b");
|
|
9
|
+
@source inline("className");
|
|
10
|
+
@source inline("client");
|
|
11
|
+
@source inline("const");
|
|
12
|
+
@source inline("core:docs-layout");
|
|
13
|
+
@source inline("core:home-layout");
|
|
14
|
+
@source inline("core:provider");
|
|
15
|
+
@source inline("core:render-body");
|
|
16
|
+
@source inline("core:render-toc");
|
|
17
|
+
@source inline("create");
|
|
18
|
+
@source inline("createDocsLayout");
|
|
19
|
+
@source inline("createHomeLayout");
|
|
20
|
+
@source inline("createRootLayout");
|
|
21
|
+
@source inline("data");
|
|
22
|
+
@source inline("data-version");
|
|
23
|
+
@source inline("default");
|
|
24
|
+
@source inline("else");
|
|
25
|
+
@source inline("empty");
|
|
26
|
+
@source inline("en");
|
|
27
|
+
@source inline("english");
|
|
28
|
+
@source inline("export");
|
|
29
|
+
@source inline("extends");
|
|
30
|
+
@source inline("flex");
|
|
31
|
+
@source inline("flex-col");
|
|
32
|
+
@source inline("flex-row");
|
|
33
|
+
@source inline("flexsearchStaticClient");
|
|
34
|
+
@source inline("for");
|
|
35
|
+
@source inline("from");
|
|
36
|
+
@source inline("fumadocs-core/source");
|
|
37
|
+
@source inline("fumadocs-core/toc");
|
|
38
|
+
@source inline("function");
|
|
39
|
+
@source inline("gap-2");
|
|
40
|
+
@source inline("githubUrl");
|
|
41
|
+
@source inline("hook");
|
|
42
|
+
@source inline("hooks");
|
|
43
|
+
@source inline("i18n");
|
|
44
|
+
@source inline("i18nConfig");
|
|
45
|
+
@source inline("if");
|
|
46
|
+
@source inline("import");
|
|
47
|
+
@source inline("in");
|
|
48
|
+
@source inline("interface");
|
|
49
|
+
@source inline("isLoading");
|
|
50
|
+
@source inline("items");
|
|
51
|
+
@source inline("items-center");
|
|
52
|
+
@source inline("lang");
|
|
53
|
+
@source inline("language");
|
|
54
|
+
@source inline("languages");
|
|
55
|
+
@source inline("layoutData");
|
|
56
|
+
@source inline("layoutProps");
|
|
57
|
+
@source inline("let");
|
|
58
|
+
@source inline("loaderConfig");
|
|
59
|
+
@source inline("locale");
|
|
60
|
+
@source inline("locales");
|
|
61
|
+
@source inline("markdownUrl");
|
|
62
|
+
@source inline("mb-0");
|
|
63
|
+
@source inline("min-h-screen");
|
|
64
|
+
@source inline("name");
|
|
65
|
+
@source inline("new");
|
|
66
|
+
@source inline("of");
|
|
67
|
+
@source inline("onSearchChange");
|
|
68
|
+
@source inline("option");
|
|
69
|
+
@source inline("page");
|
|
70
|
+
@source inline("pageProps");
|
|
71
|
+
@source inline("pb-6");
|
|
72
|
+
@source inline("providerProps");
|
|
73
|
+
@source inline("pt-2");
|
|
74
|
+
@source inline("query");
|
|
75
|
+
@source inline("r");
|
|
76
|
+
@source inline("react");
|
|
77
|
+
@source inline("render");
|
|
78
|
+
@source inline("renderCtx");
|
|
79
|
+
@source inline("renderPageMeta");
|
|
80
|
+
@source inline("renderRootMeta");
|
|
81
|
+
@source inline("result");
|
|
82
|
+
@source inline("return");
|
|
83
|
+
@source inline("root");
|
|
84
|
+
@source inline("satisfies");
|
|
85
|
+
@source inline("schema");
|
|
86
|
+
@source inline("search");
|
|
87
|
+
@source inline("source");
|
|
88
|
+
@source inline("specify");
|
|
89
|
+
@source inline("static");
|
|
90
|
+
@source inline("string");
|
|
91
|
+
@source inline("styles");
|
|
92
|
+
@source inline("the");
|
|
93
|
+
@source inline("this");
|
|
94
|
+
@source inline("throw");
|
|
95
|
+
@source inline("toc");
|
|
96
|
+
@source inline("translations");
|
|
97
|
+
@source inline("tree");
|
|
98
|
+
@source inline("type");
|
|
99
|
+
@source inline("undefined");
|
|
100
|
+
@source inline("unstable_notFound");
|
|
101
|
+
@source inline("use");
|
|
102
|
+
@source inline("useDocsSearch");
|
|
103
|
+
@source inline("useI18n");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AppContext } from "../lib/shared.js";
|
|
2
|
+
import { ConfigContext } from "../config.js";
|
|
3
|
+
import { Adapter, Awaitable } from "../lib/types.js";
|
|
4
|
+
import { MDXComponents } from "mdx/types";
|
|
5
|
+
|
|
6
|
+
//#region src/adapters/mdx.d.ts
|
|
7
|
+
interface MdxAdapterOptions<C extends ConfigContext = ConfigContext> {
|
|
8
|
+
getMdxComponents?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<MDXComponents>;
|
|
9
|
+
}
|
|
10
|
+
declare function fumadocsMdx<C extends ConfigContext = ConfigContext>(options?: MdxAdapterOptions<C>): Adapter<C>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { MdxAdapterOptions, fumadocsMdx };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
import defaultMdxComponents, { createRelativeLink } from "fumadocs-ui/mdx";
|
|
3
|
+
//#region src/adapters/mdx.ts
|
|
4
|
+
function fumadocsMdx(options) {
|
|
5
|
+
const getMdxComponents = options?.getMdxComponents;
|
|
6
|
+
return {
|
|
7
|
+
async "core:get-text"(page) {
|
|
8
|
+
if (isAsyncEntry(page.data) || isSyncEntry(page.data)) return page.data.getText("processed");
|
|
9
|
+
},
|
|
10
|
+
async "core:get-structured-data"(page) {
|
|
11
|
+
if (isSyncEntry(page.data)) return page.data.structuredData;
|
|
12
|
+
if (isAsyncEntry(page.data)) return (await page.data.load()).structuredData;
|
|
13
|
+
},
|
|
14
|
+
async "core:render-body"(page) {
|
|
15
|
+
let body;
|
|
16
|
+
if (isSyncEntry(page.data)) body = page.data.body;
|
|
17
|
+
else if (isAsyncEntry(page.data)) body = (await page.data.load()).body;
|
|
18
|
+
else return;
|
|
19
|
+
return createElement(body, getMdxComponents ? await getMdxComponents.call(this, page) : { components: {
|
|
20
|
+
...defaultMdxComponents,
|
|
21
|
+
a: createRelativeLink(await this.getLoader(), page)
|
|
22
|
+
} });
|
|
23
|
+
},
|
|
24
|
+
async "core:render-toc"(page) {
|
|
25
|
+
if (isSyncEntry(page.data)) return page.data.toc;
|
|
26
|
+
if (isAsyncEntry(page.data)) return (await page.data.load()).toc;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function isSyncEntry(v) {
|
|
31
|
+
return "info" in v && typeof v.info === "object" && "_exports" in v && typeof v._exports === "object";
|
|
32
|
+
}
|
|
33
|
+
function isAsyncEntry(v) {
|
|
34
|
+
return "info" in v && typeof v.info === "object" && "load" in v && typeof v.load === "function";
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { fumadocsMdx };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { SearchDialog, SearchDialogClose, SearchDialogContent, SearchDialogHeader, SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay } from "fumadocs-ui/components/dialog/search";
|
|
4
|
+
import { useDocsSearch } from "fumadocs-core/search/client";
|
|
5
|
+
import { flexsearchStaticClient } from "fumadocs-core/search/client/flexsearch-static";
|
|
6
|
+
import { useI18n } from "fumadocs-ui/contexts/i18n";
|
|
7
|
+
//#region src/components/flexsearch-static.tsx
|
|
8
|
+
function DefaultSearchDialog(props) {
|
|
9
|
+
const { locale } = useI18n();
|
|
10
|
+
const { search, setSearch, query } = useDocsSearch({ client: flexsearchStaticClient({ locale }) });
|
|
11
|
+
return /* @__PURE__ */ jsxs(SearchDialog, {
|
|
12
|
+
search,
|
|
13
|
+
onSearchChange: setSearch,
|
|
14
|
+
isLoading: query.isLoading,
|
|
15
|
+
...props,
|
|
16
|
+
children: [/* @__PURE__ */ jsx(SearchDialogOverlay, {}), /* @__PURE__ */ jsxs(SearchDialogContent, { children: [/* @__PURE__ */ jsxs(SearchDialogHeader, { children: [
|
|
17
|
+
/* @__PURE__ */ jsx(SearchDialogIcon, {}),
|
|
18
|
+
/* @__PURE__ */ jsx(SearchDialogInput, {}),
|
|
19
|
+
/* @__PURE__ */ jsx(SearchDialogClose, {})
|
|
20
|
+
] }), /* @__PURE__ */ jsx(SearchDialogList, { items: query.data !== "empty" ? query.data : null })] })]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { DefaultSearchDialog as default };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { SearchDialog, SearchDialogClose, SearchDialogContent, SearchDialogHeader, SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay } from "fumadocs-ui/components/dialog/search";
|
|
4
|
+
import { useDocsSearch } from "fumadocs-core/search/client";
|
|
5
|
+
import { useI18n } from "fumadocs-ui/contexts/i18n";
|
|
6
|
+
import { create } from "@orama/orama";
|
|
7
|
+
//#region src/components/orama-search-static.tsx
|
|
8
|
+
function initOrama() {
|
|
9
|
+
return create({
|
|
10
|
+
schema: { _: "string" },
|
|
11
|
+
language: "english"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function DefaultSearchDialog(props) {
|
|
15
|
+
const { locale } = useI18n();
|
|
16
|
+
const { search, setSearch, query } = useDocsSearch({
|
|
17
|
+
type: "static",
|
|
18
|
+
initOrama,
|
|
19
|
+
locale
|
|
20
|
+
});
|
|
21
|
+
return /* @__PURE__ */ jsxs(SearchDialog, {
|
|
22
|
+
search,
|
|
23
|
+
onSearchChange: setSearch,
|
|
24
|
+
isLoading: query.isLoading,
|
|
25
|
+
...props,
|
|
26
|
+
children: [/* @__PURE__ */ jsx(SearchDialogOverlay, {}), /* @__PURE__ */ jsxs(SearchDialogContent, { children: [/* @__PURE__ */ jsxs(SearchDialogHeader, { children: [
|
|
27
|
+
/* @__PURE__ */ jsx(SearchDialogIcon, {}),
|
|
28
|
+
/* @__PURE__ */ jsx(SearchDialogInput, {}),
|
|
29
|
+
/* @__PURE__ */ jsx(SearchDialogClose, {})
|
|
30
|
+
] }), /* @__PURE__ */ jsx(SearchDialogList, { items: query.data !== "empty" ? query.data : null })] })]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { DefaultSearchDialog as default };
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { AppContext } from "./lib/shared.js";
|
|
2
|
+
import { Adapter, Awaitable, ServerPlugin } from "./lib/types.js";
|
|
3
|
+
import { ComponentType, ReactNode } from "react";
|
|
4
|
+
import { TranslationsOption } from "fumadocs-ui/contexts/i18n";
|
|
5
|
+
import { LoaderConfig, LoaderOutput } from "fumadocs-core/source";
|
|
6
|
+
import { I18nConfig } from "fumadocs-core/i18n";
|
|
7
|
+
|
|
8
|
+
//#region src/config.d.ts
|
|
9
|
+
interface ConfigContext {
|
|
10
|
+
loaderConfig: LoaderConfig;
|
|
11
|
+
lang: string;
|
|
12
|
+
}
|
|
13
|
+
type BuildMode = "static" | "dynamic" | "default";
|
|
14
|
+
interface Config<C extends ConfigContext = ConfigContext> {
|
|
15
|
+
/**
|
|
16
|
+
* - `static`: always prefer static, including search etc.
|
|
17
|
+
* - `dynamic`: always prefer dynamic.
|
|
18
|
+
* - `default`: only certain parts like search routes are dynamic.
|
|
19
|
+
*/
|
|
20
|
+
mode?: BuildMode;
|
|
21
|
+
/** the default content loader */
|
|
22
|
+
loader: LoaderOutput<C["loaderConfig"]> | (() => Awaitable<LoaderOutput<C["loaderConfig"]>>);
|
|
23
|
+
site?: SiteConfig;
|
|
24
|
+
layouts?: Partial<Layouts>;
|
|
25
|
+
plugins?: ServerPlugin[];
|
|
26
|
+
/** adapter for content sources, use `fumadocs-mdx` if not specified */
|
|
27
|
+
adapters?: Adapter[];
|
|
28
|
+
i18n?: I18nConfig$1<C["lang"]>;
|
|
29
|
+
meta?: {
|
|
30
|
+
/** render meta tags for any pages */root?: (this: AppContext<C>) => ReactNode; /** render meta tags for page */
|
|
31
|
+
page?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => ReactNode;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
interface Layouts<C extends ConfigContext = ConfigContext> {
|
|
35
|
+
root: ComponentType<AppContext<C> & {
|
|
36
|
+
lang?: string;
|
|
37
|
+
children: ReactNode;
|
|
38
|
+
}>;
|
|
39
|
+
page: ComponentType<AppContext<C> & {
|
|
40
|
+
lang?: string;
|
|
41
|
+
slugs: string[];
|
|
42
|
+
}>;
|
|
43
|
+
notFound: ComponentType<AppContext<C> & {
|
|
44
|
+
lang?: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
interface I18nConfig$1<Lang extends string = string> extends Pick<I18nConfig<NoInfer<Lang>>, "fallbackLanguage" | "parser"> {
|
|
48
|
+
/** locale code -> language info */
|
|
49
|
+
languages: { [K in Lang]: {
|
|
50
|
+
displayName: string;
|
|
51
|
+
translations?: TranslationsOption;
|
|
52
|
+
} };
|
|
53
|
+
defaultLanguage: NoInfer<Lang>;
|
|
54
|
+
}
|
|
55
|
+
interface SiteConfig {
|
|
56
|
+
/** full URL of app, used for metadata generation*/
|
|
57
|
+
baseUrl?: string;
|
|
58
|
+
name?: string;
|
|
59
|
+
git?: {
|
|
60
|
+
user: string;
|
|
61
|
+
repo: string;
|
|
62
|
+
branch: string; /** the root directory of git repo */
|
|
63
|
+
rootDir?: string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
interface I18nConfigBuilder<Lang extends string> extends I18nConfig$1<Lang> {
|
|
67
|
+
/** convert Fumapress i18n config to core i18n config */
|
|
68
|
+
toCore: () => I18nConfig<Lang>;
|
|
69
|
+
}
|
|
70
|
+
interface ConfigBuilder<C extends ConfigContext> extends Config<C> {
|
|
71
|
+
usePlugins: (...plugins: ServerPlugin<C>[]) => ConfigBuilder<C>;
|
|
72
|
+
useLayouts: (layouts: Partial<Layouts<C>>) => ConfigBuilder<C>;
|
|
73
|
+
useAdapters: (...adapters: Adapter[]) => ConfigBuilder<C>;
|
|
74
|
+
}
|
|
75
|
+
declare function defineConfig<C extends LoaderConfig, L extends string = string>(config: Config<{
|
|
76
|
+
loaderConfig: C;
|
|
77
|
+
lang: L;
|
|
78
|
+
}>): ConfigBuilder<{
|
|
79
|
+
loaderConfig: C;
|
|
80
|
+
lang: L;
|
|
81
|
+
}>;
|
|
82
|
+
declare function defineI18nConfig<Lang extends string>(config: I18nConfig$1<Lang>): I18nConfigBuilder<Lang>;
|
|
83
|
+
//#endregion
|
|
84
|
+
export { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig$1 as I18nConfig, I18nConfigBuilder, Layouts, SiteConfig, defineConfig, defineI18nConfig };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/config.ts
|
|
2
|
+
function defineConfig(config) {
|
|
3
|
+
return {
|
|
4
|
+
...config,
|
|
5
|
+
useAdapters(...adapters) {
|
|
6
|
+
this.adapters ??= [];
|
|
7
|
+
this.adapters.push(...adapters);
|
|
8
|
+
return this;
|
|
9
|
+
},
|
|
10
|
+
useLayouts(layouts) {
|
|
11
|
+
this.layouts ??= {};
|
|
12
|
+
Object.assign(this.layouts, layouts);
|
|
13
|
+
return this;
|
|
14
|
+
},
|
|
15
|
+
usePlugins(...plugins) {
|
|
16
|
+
this.plugins ??= [];
|
|
17
|
+
this.plugins.push(...plugins);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function defineI18nConfig(config) {
|
|
23
|
+
return {
|
|
24
|
+
...config,
|
|
25
|
+
toCore() {
|
|
26
|
+
return {
|
|
27
|
+
defaultLanguage: this.defaultLanguage,
|
|
28
|
+
fallbackLanguage: this.fallbackLanguage,
|
|
29
|
+
parser: this.parser,
|
|
30
|
+
languages: Object.keys(this.languages)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { defineConfig, defineI18nConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AppContext, AppContextData } from "./lib/shared.js";
|
|
2
|
+
import { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, SiteConfig, defineConfig, defineI18nConfig } from "./config.js";
|
|
3
|
+
import { Adapter, ServerPlugin } from "./lib/types.js";
|
|
4
|
+
export { type Adapter, type AppContext, type AppContextData, BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, type ServerPlugin, SiteConfig, defineConfig, defineI18nConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { AppContext } from "../lib/shared.js";
|
|
2
|
+
import { ConfigContext, Layouts } from "../config.js";
|
|
3
|
+
import { Awaitable } from "../lib/types.js";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
import { DocsLayoutProps } from "fumadocs-ui/layouts/docs";
|
|
6
|
+
import { DocsPageProps } from "fumadocs-ui/layouts/docs/page";
|
|
7
|
+
import { Page } from "fumadocs-core/source";
|
|
8
|
+
|
|
9
|
+
//#region src/layouts/docs.d.ts
|
|
10
|
+
interface DocsLayoutOptions<C extends ConfigContext = ConfigContext> {
|
|
11
|
+
render?: (this: AppContext<C> & {
|
|
12
|
+
lang?: string;
|
|
13
|
+
}, page: C["loaderConfig"]["page"]) => Awaitable<{
|
|
14
|
+
markdownUrl?: string;
|
|
15
|
+
body?: ReactNode;
|
|
16
|
+
layoutProps?: Partial<DocsLayoutProps>;
|
|
17
|
+
pageProps?: DocsPageProps;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
interface DocsLayoutRenderData {
|
|
21
|
+
markdownUrl?: string;
|
|
22
|
+
body: ReactNode;
|
|
23
|
+
layoutProps: DocsLayoutProps;
|
|
24
|
+
pageProps: DocsPageProps;
|
|
25
|
+
}
|
|
26
|
+
interface DocsLayoutContextData {
|
|
27
|
+
renderers?: ((this: {
|
|
28
|
+
page: Page;
|
|
29
|
+
}, data: DocsLayoutRenderData) => Awaitable<DocsLayoutRenderData>)[];
|
|
30
|
+
}
|
|
31
|
+
declare function createDocsLayout<C extends ConfigContext = ConfigContext>({
|
|
32
|
+
render
|
|
33
|
+
}?: DocsLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
|
|
34
|
+
//#endregion
|
|
35
|
+
export { DocsLayoutContextData, DocsLayoutOptions, DocsLayoutRenderData, createDocsLayout };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { baseOptions, getGitHubFileUrl, renderPageMeta } from "../lib/shared.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { unstable_notFound } from "waku/router/server";
|
|
4
|
+
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
|
5
|
+
import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, ViewOptionsPopover } from "fumadocs-ui/layouts/docs/page";
|
|
6
|
+
//#region src/layouts/docs.tsx
|
|
7
|
+
function createDocsLayout({ render } = {}) {
|
|
8
|
+
async function defaultRender(page) {
|
|
9
|
+
let body;
|
|
10
|
+
let toc;
|
|
11
|
+
for (const adapter of this.adapters) {
|
|
12
|
+
body = await adapter["core:render-body"]?.call(this, page);
|
|
13
|
+
if (body !== void 0) break;
|
|
14
|
+
}
|
|
15
|
+
for (const adapter of this.adapters) {
|
|
16
|
+
toc = await adapter["core:render-toc"]?.call(this, page);
|
|
17
|
+
if (toc !== void 0) break;
|
|
18
|
+
}
|
|
19
|
+
if (body === void 0) throw new Error("[Fumapress] Please specify the `render` option in createDocsLayout()");
|
|
20
|
+
return {
|
|
21
|
+
body,
|
|
22
|
+
pageProps: { toc }
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return async function Layout(props) {
|
|
26
|
+
const { slugs, lang, getLoader, data: { "core:docs-layout": layoutData } } = props;
|
|
27
|
+
const source = await getLoader();
|
|
28
|
+
const page = source.getPage(slugs, lang);
|
|
29
|
+
if (!page) unstable_notFound();
|
|
30
|
+
const _raw = await (render ?? defaultRender).call(props, page);
|
|
31
|
+
let result;
|
|
32
|
+
if (_raw.body === void 0 || _raw.pageProps === void 0) {
|
|
33
|
+
const _default = await defaultRender.call(props, page);
|
|
34
|
+
result = {
|
|
35
|
+
markdownUrl: _raw.markdownUrl,
|
|
36
|
+
pageProps: _raw.pageProps ?? _default.pageProps,
|
|
37
|
+
body: _raw.body ?? _default.body,
|
|
38
|
+
layoutProps: {
|
|
39
|
+
tree: source.getPageTree(lang),
|
|
40
|
+
..._raw.layoutProps ?? baseOptions(props)
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
} else result = {
|
|
44
|
+
body: _raw.body,
|
|
45
|
+
pageProps: _raw.pageProps,
|
|
46
|
+
markdownUrl: _raw.markdownUrl,
|
|
47
|
+
layoutProps: {
|
|
48
|
+
tree: source.getPageTree(lang),
|
|
49
|
+
..._raw.layoutProps ?? baseOptions(props)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
if (layoutData?.renderers) {
|
|
53
|
+
const renderCtx = { page };
|
|
54
|
+
for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
|
|
55
|
+
}
|
|
56
|
+
return /* @__PURE__ */ jsxs(DocsLayout, {
|
|
57
|
+
...result.layoutProps,
|
|
58
|
+
children: [
|
|
59
|
+
renderPageMeta(page, props),
|
|
60
|
+
result.layoutProps.children,
|
|
61
|
+
/* @__PURE__ */ jsxs(DocsPage, {
|
|
62
|
+
...result.pageProps,
|
|
63
|
+
children: [
|
|
64
|
+
result.pageProps.children,
|
|
65
|
+
/* @__PURE__ */ jsx(DocsTitle, { children: page.data.title }),
|
|
66
|
+
/* @__PURE__ */ jsx(DocsDescription, {
|
|
67
|
+
className: "mb-0",
|
|
68
|
+
children: page.data.description
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ jsxs("div", {
|
|
71
|
+
className: "flex flex-row gap-2 items-center border-b pt-2 pb-6",
|
|
72
|
+
children: [result.markdownUrl && /* @__PURE__ */ jsx(MarkdownCopyButton, { markdownUrl: result.markdownUrl }), /* @__PURE__ */ jsx(ViewOptionsPopover, {
|
|
73
|
+
markdownUrl: result.markdownUrl,
|
|
74
|
+
githubUrl: page.absolutePath ? getGitHubFileUrl(props, page.absolutePath) : void 0
|
|
75
|
+
})]
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ jsx(DocsBody, { children: result.body })
|
|
78
|
+
]
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { createDocsLayout };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AppContext } from "../lib/shared.js";
|
|
2
|
+
import { ConfigContext, Layouts } from "../config.js";
|
|
3
|
+
import { Awaitable } from "../lib/types.js";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
import { HomeLayoutProps } from "fumadocs-ui/layouts/home";
|
|
6
|
+
import { Page } from "fumadocs-core/source";
|
|
7
|
+
|
|
8
|
+
//#region src/layouts/home.d.ts
|
|
9
|
+
interface HomeLayoutOptions<C extends ConfigContext = ConfigContext> {
|
|
10
|
+
render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<{
|
|
11
|
+
body?: ReactNode;
|
|
12
|
+
layoutProps?: Partial<HomeLayoutProps>;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
interface HomeLayoutRenderData {
|
|
16
|
+
body: ReactNode;
|
|
17
|
+
layoutProps: HomeLayoutProps;
|
|
18
|
+
}
|
|
19
|
+
interface HomeLayoutContextData {
|
|
20
|
+
renderers?: ((this: {
|
|
21
|
+
page: Page;
|
|
22
|
+
}, data: HomeLayoutRenderData) => Awaitable<HomeLayoutRenderData>)[];
|
|
23
|
+
}
|
|
24
|
+
declare function createHomeLayout<C extends ConfigContext = ConfigContext>({
|
|
25
|
+
render
|
|
26
|
+
}: HomeLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
|
|
27
|
+
//#endregion
|
|
28
|
+
export { HomeLayoutContextData, HomeLayoutOptions, HomeLayoutRenderData, createHomeLayout };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { baseOptions, renderPageMeta } from "../lib/shared.js";
|
|
2
|
+
import { jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { unstable_notFound } from "waku/router/server";
|
|
4
|
+
import { HomeLayout } from "fumadocs-ui/layouts/home";
|
|
5
|
+
//#region src/layouts/home.tsx
|
|
6
|
+
function createHomeLayout({ render }) {
|
|
7
|
+
async function renderDefault(page) {
|
|
8
|
+
for (const adapter of this.adapters) {
|
|
9
|
+
const body = await adapter["core:render-body"]?.call(this, page);
|
|
10
|
+
if (body !== void 0) return { body };
|
|
11
|
+
}
|
|
12
|
+
throw new Error("[Fumapress] Please specify the `render` option in createHomeLayout()");
|
|
13
|
+
}
|
|
14
|
+
return async function Layout(props) {
|
|
15
|
+
const { slugs, lang, getLoader, data: { "core:home-layout": layoutData } } = props;
|
|
16
|
+
const page = (await getLoader()).getPage(slugs, lang);
|
|
17
|
+
if (!page) unstable_notFound();
|
|
18
|
+
const _raw = await (render ?? renderDefault).call(props, page);
|
|
19
|
+
let result = {
|
|
20
|
+
body: _raw.body === void 0 ? (await renderDefault.call(props, page)).body : _raw.body,
|
|
21
|
+
layoutProps: _raw.layoutProps ?? baseOptions(props)
|
|
22
|
+
};
|
|
23
|
+
if (layoutData?.renderers) {
|
|
24
|
+
const renderCtx = { page };
|
|
25
|
+
for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
|
|
26
|
+
}
|
|
27
|
+
return /* @__PURE__ */ jsxs(HomeLayout, {
|
|
28
|
+
...result.layoutProps,
|
|
29
|
+
children: [renderPageMeta(page, props), result.body]
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { createHomeLayout };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ConfigContext, Layouts } from "../config.js";
|
|
2
|
+
import { RootProviderProps } from "fumadocs-ui/provider/waku";
|
|
3
|
+
|
|
4
|
+
//#region src/layouts/root.d.ts
|
|
5
|
+
interface RootLayoutOptions {
|
|
6
|
+
providerProps?: RootProviderProps;
|
|
7
|
+
}
|
|
8
|
+
declare function createRootLayout<C extends ConfigContext = ConfigContext>(options?: RootLayoutOptions): Layouts<C>["root"];
|
|
9
|
+
//#endregion
|
|
10
|
+
export { RootLayoutOptions, createRootLayout };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { renderRootMeta } from "../lib/shared.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import styles from "virtual:root.css?inline";
|
|
4
|
+
import { RootProvider } from "fumadocs-ui/provider/waku";
|
|
5
|
+
//#region src/layouts/root.tsx
|
|
6
|
+
function createRootLayout(options) {
|
|
7
|
+
return async function(props) {
|
|
8
|
+
const { children, lang, i18nConfig, data } = props;
|
|
9
|
+
const hooks = data["core:provider"];
|
|
10
|
+
let providerProps = { ...options?.providerProps };
|
|
11
|
+
if (i18nConfig) {
|
|
12
|
+
const { languages } = i18nConfig;
|
|
13
|
+
providerProps.i18n ??= {
|
|
14
|
+
locale: lang,
|
|
15
|
+
locales: Object.entries(languages).map(([k, v]) => ({
|
|
16
|
+
name: v.displayName,
|
|
17
|
+
locale: k
|
|
18
|
+
})),
|
|
19
|
+
translations: lang ? languages[lang]?.translations : void 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (hooks) for (const hook of hooks) providerProps = await hook(providerProps);
|
|
23
|
+
return /* @__PURE__ */ jsxs("html", {
|
|
24
|
+
lang: lang ?? "en",
|
|
25
|
+
suppressHydrationWarning: true,
|
|
26
|
+
children: [/* @__PURE__ */ jsxs("head", { children: [/* @__PURE__ */ jsx("style", { children: styles }), renderRootMeta(props)] }), /* @__PURE__ */ jsx("body", {
|
|
27
|
+
"data-version": "1.0",
|
|
28
|
+
className: "flex flex-col min-h-screen",
|
|
29
|
+
children: /* @__PURE__ */ jsx(RootProvider, {
|
|
30
|
+
...providerProps,
|
|
31
|
+
children
|
|
32
|
+
})
|
|
33
|
+
})]
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { createRootLayout };
|
package/dist/lib/fs.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
//#region src/lib/fs.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns the absolute path to the root directory of the current git repository.
|
|
6
|
+
*/
|
|
7
|
+
function getGitRootDir(startDir = process.cwd()) {
|
|
8
|
+
let dir = startDir;
|
|
9
|
+
while (true) {
|
|
10
|
+
if (existsSync(join(dir, ".git"))) return dir;
|
|
11
|
+
const parent = dirname(dir);
|
|
12
|
+
if (parent === dir) break;
|
|
13
|
+
dir = parent;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getGitRootDir };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DocsLayoutContextData } from "../layouts/docs.js";
|
|
2
|
+
import { HomeLayoutContextData } from "../layouts/home.js";
|
|
3
|
+
import { BuildMode, Config, ConfigContext, I18nConfig } from "../config.js";
|
|
4
|
+
import { Adapter, Awaitable, ServerPlugin } from "./types.js";
|
|
5
|
+
import { ReactNode } from "react";
|
|
6
|
+
import { RootProviderProps } from "fumadocs-ui/provider/waku";
|
|
7
|
+
import { LoaderOutput, Page } from "fumadocs-core/source";
|
|
8
|
+
|
|
9
|
+
//#region src/lib/shared.d.ts
|
|
10
|
+
interface AppContext<C extends ConfigContext = ConfigContext> {
|
|
11
|
+
mode: BuildMode;
|
|
12
|
+
getLoader: () => Awaitable<LoaderOutput<C["loaderConfig"]>>;
|
|
13
|
+
plugins: ServerPlugin<C>[];
|
|
14
|
+
adapters: Adapter<C>[];
|
|
15
|
+
/** always `undefined`, easier way to infer types */
|
|
16
|
+
$context: C;
|
|
17
|
+
/**
|
|
18
|
+
* custom data in app context, can be referenced from plugins/pages etc
|
|
19
|
+
*/
|
|
20
|
+
data: AppContextData & Record<string, unknown>;
|
|
21
|
+
i18nConfig?: I18nConfig<C["lang"]>;
|
|
22
|
+
metaConfig?: Config<C>["meta"];
|
|
23
|
+
siteConfig: {
|
|
24
|
+
name: string;
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
git?: {
|
|
27
|
+
user: string;
|
|
28
|
+
repo: string;
|
|
29
|
+
branch: string;
|
|
30
|
+
rootDir: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
interface AppContextData {
|
|
35
|
+
"core:page-meta"?: ((page: Page) => ReactNode)[];
|
|
36
|
+
"core:docs-layout"?: DocsLayoutContextData;
|
|
37
|
+
"core:home-layout"?: HomeLayoutContextData;
|
|
38
|
+
"core:provider"?: ((props: RootProviderProps) => Awaitable<RootProviderProps>)[];
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { AppContext, AppContextData };
|