fumapress 0.2.0 → 0.2.2

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.
Files changed (38) hide show
  1. package/LICENSE +1 -1
  2. package/css/default.css +4 -4
  3. package/css/preset.css +1 -1
  4. package/package.json +14 -13
  5. package/css/generated.css +0 -98
  6. package/dist/_virtual/_rolldown/runtime.js +0 -4
  7. package/dist/adapters/mdx.d.ts +0 -6
  8. package/dist/adapters/mdx.js +0 -39
  9. package/dist/components/flexsearch-static.js +0 -24
  10. package/dist/components/orama-search-static.js +0 -34
  11. package/dist/config.d.ts +0 -52
  12. package/dist/config.js +0 -13
  13. package/dist/index.d.ts +0 -4
  14. package/dist/index.js +0 -2
  15. package/dist/layouts/docs.d.ts +0 -29
  16. package/dist/layouts/docs.js +0 -67
  17. package/dist/layouts/home.d.ts +0 -26
  18. package/dist/layouts/home.js +0 -34
  19. package/dist/layouts/root.d.ts +0 -7
  20. package/dist/layouts/root.js +0 -33
  21. package/dist/lib/fs.js +0 -18
  22. package/dist/lib/shared.d.ts +0 -38
  23. package/dist/lib/shared.js +0 -49
  24. package/dist/lib/types.d.ts +0 -33
  25. package/dist/node_modules/.pnpm/vitefu@1.1.3_vite@8.0.11_@types_node@25.6.2_esbuild@0.28.0_jiti@2.7.0_terser@5.47.1_tsx@4.21.0_yaml@2.8.4_/node_modules/vitefu/src/index.js +0 -199
  26. package/dist/node_modules/.pnpm/vitefu@1.1.3_vite@8.0.11_@types_node@25.6.2_esbuild@0.28.0_jiti@2.7.0_terser@5.47.1_tsx@4.21.0_yaml@2.8.4_/node_modules/vitefu/src/sync.js +0 -48
  27. package/dist/plugins/flexsearch.d.ts +0 -14
  28. package/dist/plugins/flexsearch.js +0 -36
  29. package/dist/plugins/llms.txt.d.ts +0 -11
  30. package/dist/plugins/llms.txt.js +0 -71
  31. package/dist/plugins/orama-search.d.ts +0 -14
  32. package/dist/plugins/orama-search.js +0 -35
  33. package/dist/plugins/takumi.d.ts +0 -16
  34. package/dist/plugins/takumi.js +0 -62
  35. package/dist/router.d.ts +0 -26
  36. package/dist/router.js +0 -129
  37. package/dist/vite.d.ts +0 -6
  38. package/dist/vite.js +0 -45
@@ -1,49 +0,0 @@
1
- import { getGitRootDir } from "./fs.js";
2
- import { fumadocsMdx } from "../adapters/mdx.js";
3
- import path from "node:path";
4
- import { Fragment, createElement } from "react";
5
- //#region src/lib/shared.ts
6
- function parseConfig(config) {
7
- const context = {
8
- getLoader() {
9
- if (typeof config.loader === "function") return config.loader();
10
- return config.loader;
11
- },
12
- plugins: Array.isArray(config.plugins) ? config.plugins : [],
13
- adapters: config.adapters ?? [fumadocsMdx()],
14
- $context: void 0,
15
- data: {},
16
- i18nConfig: config.i18n,
17
- mode: config.mode ?? "default",
18
- siteConfig: {
19
- name: config.site?.name ?? "Fumapress",
20
- git: config.site?.git ? {
21
- ...config.site.git,
22
- rootDir: config.site.git.rootDir ?? getGitRootDir() ?? process.cwd()
23
- } : void 0
24
- }
25
- };
26
- if (typeof config.plugins === "function") context.plugins = config.plugins(context);
27
- return context;
28
- }
29
- function renderPageMeta(page, context) {
30
- const meta = context.data["core:page-meta"];
31
- if (!meta) return;
32
- return meta.map((fn, i) => createElement(Fragment, { key: i }, fn(page)));
33
- }
34
- function getGitHubFileUrl(ctx, absolutePath) {
35
- const { git } = ctx.siteConfig;
36
- if (!git) return;
37
- const p = path.relative(git.rootDir, absolutePath).replaceAll(path.sep, "/");
38
- if (p.startsWith("../")) return;
39
- return `https://github.com/${git.user}/${git.repo}/blob/${git.branch}/${p}`;
40
- }
41
- function baseOptions(ctx) {
42
- const { name, git } = ctx.siteConfig;
43
- return {
44
- nav: { title: name },
45
- githubUrl: git ? `https://github.com/${git.user}/${git.repo}` : void 0
46
- };
47
- }
48
- //#endregion
49
- export { baseOptions, getGitHubFileUrl, parseConfig, renderPageMeta };
@@ -1,33 +0,0 @@
1
- import { AppContext } from "./shared.js";
2
- import { createPages } from "waku";
3
- import { ReactNode } from "react";
4
- import { Page } from "fumadocs-core/source";
5
- import { StructuredData } from "fumadocs-core/mdx-plugins";
6
- import { TOCItemType } from "fumadocs-core/toc";
7
-
8
- //#region src/lib/types.d.ts
9
- type Awaitable<T> = T | Promise<T>;
10
- /** allow content sources to implement interfaces for pages, instead of requiring consumers to specify manually */
11
- interface Adapter {
12
- 'core:get-text'?: (this: AppContext, page: Page) => Awaitable<string | undefined>;
13
- 'core:get-structured-data'?: (this: AppContext, page: Page) => Awaitable<StructuredData | undefined>;
14
- 'core:render-body'?: (this: AppContext, page: Page) => Awaitable<ReactNode>;
15
- 'core:render-toc'?: (this: AppContext, page: Page) => Awaitable<TOCItemType[] | undefined>;
16
- }
17
- interface ServerPlugin {
18
- /** receive & modify context */
19
- init?: (this: AppContext) => void;
20
- createPages?: (this: AppContext, fns: RouteFns) => Awaitable<void>;
21
- }
22
- type RouteFns = Parameters<Parameters<typeof createPages>[0]>[0] & {
23
- createApiIsomorphic: (config: {
24
- render: 'static' | 'dynamic';
25
- path: string;
26
- staticPaths?: string[][];
27
- handler: (req: Request, ctx: {
28
- params: Record<string, string | string[]>;
29
- }) => Promise<Response>;
30
- }) => void;
31
- };
32
- //#endregion
33
- export { Adapter, Awaitable, ServerPlugin };
@@ -1,199 +0,0 @@
1
- import { require_sync } from "./sync.js";
2
- import fsSync from "node:fs";
3
- import path from "node:path";
4
- import fs from "node:fs/promises";
5
- import { createRequire } from "node:module";
6
- //#region ../../node_modules/.pnpm/vitefu@1.1.3_vite@8.0.11_@types+node@25.6.2_esbuild@0.28.0_jiti@2.7.0_terser@5.47.1_tsx@4.21.0_yaml@2.8.4_/node_modules/vitefu/src/index.js
7
- var import_sync = require_sync();
8
- /** @type {import('pnpapi')} */
9
- let pnp;
10
- /** @type {Array<{ name: string; reference: string; }>} */
11
- let pnpWorkspaceLocators;
12
- if (process.versions.pnp) try {
13
- pnp = createRequire(import.meta.url)("pnpapi");
14
- pnpWorkspaceLocators = pnp.getDependencyTreeRoots();
15
- } catch {}
16
- /** @type {import('./index.d.ts').crawlFrameworkPkgs} */
17
- async function crawlFrameworkPkgs(options) {
18
- const pkgJsonPath = await findClosestPkgJsonPath(options.root);
19
- if (!pkgJsonPath) return {
20
- optimizeDeps: {
21
- include: [],
22
- exclude: []
23
- },
24
- ssr: {
25
- noExternal: [],
26
- external: []
27
- }
28
- };
29
- const pkgJson = await readJson(pkgJsonPath).catch((e) => {
30
- throw new Error(`Unable to read ${pkgJsonPath}`, { cause: e });
31
- });
32
- /** @type {string[]} */
33
- let optimizeDepsInclude = [];
34
- /** @type {string[]} */
35
- let optimizeDepsExclude = [];
36
- /** @type {string[]} */
37
- let ssrNoExternal = [];
38
- /** @type {string[]} */
39
- let ssrExternal = [];
40
- await crawl(pkgJsonPath, pkgJson);
41
- if (options.viteUserConfig) {
42
- const _optimizeDepsExclude = options.viteUserConfig?.optimizeDeps?.exclude;
43
- if (_optimizeDepsExclude) optimizeDepsInclude = optimizeDepsInclude.filter((dep) => !(0, import_sync.isDepExcluded)(dep, _optimizeDepsExclude));
44
- const _optimizeDepsInclude = options.viteUserConfig?.optimizeDeps?.include;
45
- if (_optimizeDepsInclude) optimizeDepsExclude = optimizeDepsExclude.filter((dep) => !(0, import_sync.isDepIncluded)(dep, _optimizeDepsInclude));
46
- const _ssrExternal = options.viteUserConfig?.ssr?.external;
47
- if (_ssrExternal) ssrNoExternal = ssrNoExternal.filter((dep) => !(0, import_sync.isDepExternaled)(dep, _ssrExternal));
48
- const _ssrNoExternal = options.viteUserConfig?.ssr?.noExternal;
49
- if (_ssrNoExternal) ssrExternal = ssrExternal.filter((dep) => !(0, import_sync.isDepNoExternaled)(dep, _ssrNoExternal));
50
- }
51
- optimizeDepsInclude.sort();
52
- optimizeDepsExclude.sort();
53
- ssrExternal.sort();
54
- ssrNoExternal.sort();
55
- return {
56
- optimizeDeps: {
57
- include: optimizeDepsInclude,
58
- exclude: optimizeDepsExclude
59
- },
60
- ssr: {
61
- noExternal: ssrNoExternal,
62
- external: ssrExternal
63
- }
64
- };
65
- /**
66
- * crawl the package.json dependencies for framework packages. rules:
67
- * 1. a framework package should be `optimizeDeps.exclude` and `ssr.noExternal`.
68
- * 2. the deps of the framework package should be `optimizeDeps.include` and `ssr.external`
69
- * unless the dep is also a framework package, in which case do no1 & no2 recursively.
70
- * 3. any non-framework packages that aren't imported by a framework package can be skipped entirely.
71
- * 4. a semi-framework package is like a framework package, except it isn't `optimizeDeps.exclude`,
72
- * but only applies `ssr.noExternal`.
73
- * @param {string} pkgJsonPath
74
- * @param {Record<string, any>} pkgJson
75
- * @param {string[]} [parentDepNames]
76
- */
77
- async function crawl(pkgJsonPath, pkgJson, parentDepNames = []) {
78
- const isRoot = parentDepNames.length === 0;
79
- const crawlDevDependencies = isRoot || isPrivateWorkspacePackage(pkgJsonPath, pkgJson, options.workspaceRoot);
80
- /** @type {string[]} */
81
- let deps = [...Object.keys(pkgJson.dependencies || {}), ...crawlDevDependencies ? Object.keys(pkgJson.devDependencies || {}) : []];
82
- deps = deps.filter((dep) => {
83
- if (parentDepNames.includes(dep)) return false;
84
- const isFrameworkPkg = options.isFrameworkPkgByName?.(dep);
85
- const isSemiFrameworkPkg = options.isSemiFrameworkPkgByName?.(dep);
86
- if (isFrameworkPkg) {
87
- optimizeDepsExclude.push(dep);
88
- ssrNoExternal.push(dep);
89
- } else if (isSemiFrameworkPkg) ssrNoExternal.push(dep);
90
- if (isFrameworkPkg === false || isSemiFrameworkPkg === false) return false;
91
- else return true;
92
- });
93
- const promises = deps.map(async (dep) => {
94
- const depPkgJsonPath = await _findDepPkgJsonPath(dep, pkgJsonPath, !!options.workspaceRoot);
95
- if (!depPkgJsonPath) return;
96
- const depPkgJson = await readJson(depPkgJsonPath).catch(() => {});
97
- if (!depPkgJson) return;
98
- if (ssrNoExternal.includes(dep)) return crawl(depPkgJsonPath, depPkgJson, parentDepNames.concat(dep));
99
- const isFrameworkPkg = options.isFrameworkPkgByJson?.(depPkgJson);
100
- const isSemiFrameworkPkg = options.isSemiFrameworkPkgByJson?.(depPkgJson);
101
- if (isFrameworkPkg || isSemiFrameworkPkg) {
102
- if (isFrameworkPkg) {
103
- optimizeDepsExclude.push(dep);
104
- ssrNoExternal.push(dep);
105
- } else if (isSemiFrameworkPkg) ssrNoExternal.push(dep);
106
- return crawl(depPkgJsonPath, depPkgJson, parentDepNames.concat(dep));
107
- }
108
- if (!isRoot) {
109
- if (await pkgNeedsOptimization(depPkgJson, depPkgJsonPath)) optimizeDepsInclude.push(parentDepNames.concat(dep).join(" > "));
110
- if (!options.isBuild && !ssrExternal.includes(dep)) ssrExternal.push(dep);
111
- }
112
- });
113
- await Promise.all(promises);
114
- }
115
- }
116
- /**
117
- * internal implementation to avoid exposing the usePnpWorkspaceLocators flag
118
- *
119
- * @param {string} dep
120
- * @param {string} parent
121
- * @param {boolean} usePnpWorkspaceLocators
122
- * @returns {Promise<undefined|string>}
123
- * @private
124
- */
125
- async function _findDepPkgJsonPath(dep, parent, usePnpWorkspaceLocators) {
126
- if (pnp) {
127
- if (usePnpWorkspaceLocators) try {
128
- const locator = pnpWorkspaceLocators.find((root) => root.name === dep);
129
- if (locator) {
130
- const pkgPath = pnp.getPackageInformation(locator).packageLocation;
131
- return path.resolve(pkgPath, "package.json");
132
- }
133
- } catch {}
134
- try {
135
- const depRoot = pnp.resolveToUnqualified(dep, parent);
136
- if (!depRoot) return void 0;
137
- return path.join(depRoot, "package.json");
138
- } catch {
139
- return;
140
- }
141
- }
142
- let root = parent;
143
- while (root) {
144
- const pkg = path.join(root, "node_modules", dep, "package.json");
145
- try {
146
- await fs.access(pkg);
147
- return fsSync.realpathSync(pkg);
148
- } catch {}
149
- const nextRoot = path.dirname(root);
150
- if (nextRoot === root) break;
151
- root = nextRoot;
152
- }
153
- }
154
- /** @type {import('./index.d.ts').findClosestPkgJsonPath} */
155
- async function findClosestPkgJsonPath(dir, predicate = void 0) {
156
- if (dir.endsWith("package.json")) dir = path.dirname(dir);
157
- while (dir) {
158
- const pkg = path.join(dir, "package.json");
159
- try {
160
- if ((await fs.stat(pkg)).isFile() && (!predicate || await predicate(pkg))) return pkg;
161
- } catch {}
162
- const nextDir = path.dirname(dir);
163
- if (nextDir === dir) break;
164
- dir = nextDir;
165
- }
166
- }
167
- /** @type {import('./index.d.ts').pkgNeedsOptimization} */
168
- async function pkgNeedsOptimization(pkgJson, pkgJsonPath) {
169
- if (pkgJson.module || pkgJson.exports) return false;
170
- if (pkgJson.main) {
171
- const entryExt = path.extname(pkgJson.main);
172
- return !entryExt || entryExt === ".js" || entryExt === ".cjs";
173
- }
174
- try {
175
- await fs.access(path.join(path.dirname(pkgJsonPath), "index.js"));
176
- return true;
177
- } catch {
178
- return false;
179
- }
180
- }
181
- /**
182
- * @param {string} findDepPkgJsonPath
183
- * @returns {Promise<Record<string, any>>}
184
- */
185
- async function readJson(findDepPkgJsonPath) {
186
- return JSON.parse(await fs.readFile(findDepPkgJsonPath, "utf8"));
187
- }
188
- /**
189
- *
190
- * @param {string} pkgJsonPath
191
- * @param {Record<string,any>} pkgJson
192
- * @param {string} [workspaceRoot]
193
- * @returns {boolean}
194
- */
195
- function isPrivateWorkspacePackage(pkgJsonPath, pkgJson, workspaceRoot = void 0) {
196
- return !!(workspaceRoot && pkgJson.private && !pkgJsonPath.match(/[/\\]node_modules[/\\]/) && !path.relative(workspaceRoot, pkgJsonPath).startsWith(".."));
197
- }
198
- //#endregion
199
- export { crawlFrameworkPkgs };
@@ -1,48 +0,0 @@
1
- import { __commonJSMin } from "../../../../../../_virtual/_rolldown/runtime.js";
2
- //#region ../../node_modules/.pnpm/vitefu@1.1.3_vite@8.0.11_@types+node@25.6.2_esbuild@0.28.0_jiti@2.7.0_terser@5.47.1_tsx@4.21.0_yaml@2.8.4_/node_modules/vitefu/src/sync.cjs
3
- var require_sync = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
- /** @type {import('./index.d.ts').isDepIncluded} */
5
- function isDepIncluded(dep, optimizeDepsInclude) {
6
- return optimizeDepsInclude.some((id) => parseIncludeStr(id) === dep);
7
- }
8
- /** @type {import('./index.d.ts').isDepExcluded} */
9
- function isDepExcluded(dep, optimizeDepsExclude) {
10
- dep = parseIncludeStr(dep);
11
- return optimizeDepsExclude.some((id) => id === dep || dep.startsWith(`${id}/`));
12
- }
13
- /** @type {import('./index.d.ts').isDepNoExternaled} */
14
- function isDepNoExternaled(dep, ssrNoExternal) {
15
- if (ssrNoExternal === true) return true;
16
- else return isMatch(dep, ssrNoExternal);
17
- }
18
- /** @type {import('./index.d.ts').isDepExternaled} */
19
- function isDepExternaled(dep, ssrExternal) {
20
- if (ssrExternal === true) return false;
21
- else return ssrExternal.includes(dep);
22
- }
23
- /**
24
- * @param {string} raw could be "foo" or "foo > bar" etc
25
- */
26
- function parseIncludeStr(raw) {
27
- const lastArrow = raw.lastIndexOf(">");
28
- return lastArrow === -1 ? raw : raw.slice(lastArrow + 1).trim();
29
- }
30
- /**
31
- * @param {string} target
32
- * @param {string | RegExp | (string | RegExp)[]} pattern
33
- */
34
- function isMatch(target, pattern) {
35
- if (Array.isArray(pattern)) return pattern.some((p) => isMatch(target, p));
36
- else if (typeof pattern === "string") return target === pattern;
37
- else if (pattern instanceof RegExp) return pattern.test(target);
38
- }
39
- module.exports = {
40
- isDepIncluded,
41
- isDepExcluded,
42
- isDepNoExternaled,
43
- isDepExternaled
44
- };
45
- }));
46
- //#endregion
47
- export default require_sync();
48
- export { require_sync };
@@ -1,14 +0,0 @@
1
- import { ConfigContext } from "../config.js";
2
- import { AppContext } from "../lib/shared.js";
3
- import { Awaitable, ServerPlugin } from "../lib/types.js";
4
- import { Index } from "fumadocs-core/search/flexsearch";
5
-
6
- //#region src/plugins/flexsearch.d.ts
7
- interface FlexsearchOptions<C extends ConfigContext = ConfigContext> {
8
- buildIndex?: (this: AppContext<C>, page: C['loaderConfig']['page']) => Awaitable<Index>;
9
- }
10
- declare function flexsearchPlugin<C extends ConfigContext = ConfigContext>({
11
- buildIndex
12
- }?: FlexsearchOptions<C>): ServerPlugin;
13
- //#endregion
14
- export { FlexsearchOptions, flexsearchPlugin };
@@ -1,36 +0,0 @@
1
- import DefaultSearchDialog from "../components/flexsearch-static.js";
2
- //#region src/plugins/flexsearch.ts
3
- function flexsearchPlugin({ buildIndex = async function buildIndexDefault(page) {
4
- for (const adapter of this.adapters) {
5
- const structuredData = await adapter["core:get-structured-data"]?.call(this, page);
6
- if (structuredData !== void 0) return {
7
- id: page.url,
8
- title: page.data.title ?? page.path,
9
- description: page.data.description,
10
- url: page.url,
11
- structuredData
12
- };
13
- }
14
- throw new Error("[Fumapress] Please specify the `buildIndex` option to flexsearchPlugin()");
15
- } } = {}) {
16
- return {
17
- init() {
18
- if (this.mode === "static") (this.data["core:provider"] ??= []).push((props) => {
19
- props.search ??= {};
20
- props.search.SearchDialog ??= DefaultSearchDialog;
21
- return props;
22
- });
23
- },
24
- async createPages({ createApiIsomorphic }) {
25
- const { flexsearchFromSource } = await import("fumadocs-core/search/flexsearch");
26
- const server = flexsearchFromSource(this.getLoader, { buildIndex: buildIndex.bind(this) });
27
- createApiIsomorphic({
28
- render: this.mode === "static" ? "static" : "dynamic",
29
- path: "/api/search",
30
- handler: this.mode === "static" ? server.staticGET : server.GET
31
- });
32
- }
33
- };
34
- }
35
- //#endregion
36
- export { flexsearchPlugin };
@@ -1,11 +0,0 @@
1
- import { ConfigContext } from "../config.js";
2
- import { AppContext } from "../lib/shared.js";
3
- import { Awaitable, ServerPlugin } from "../lib/types.js";
4
-
5
- //#region src/plugins/llms.txt.d.ts
6
- interface LLMsOptions<C extends ConfigContext = ConfigContext> {
7
- getLLMText?: (this: AppContext<C>, page: C['loaderConfig']['page']) => Awaitable<string>;
8
- }
9
- declare function llmsPlugin<C extends ConfigContext = ConfigContext>(options?: LLMsOptions<C>): ServerPlugin;
10
- //#endregion
11
- export { LLMsOptions, llmsPlugin };
@@ -1,71 +0,0 @@
1
- import { unstable_notFound } from "waku/router/server";
2
- import { llms } from "fumadocs-core/source/llms";
3
- //#region src/plugins/llms.txt.ts
4
- function llmsPlugin(options = {}) {
5
- const { getLLMText = async function getLLMTextDefault(page) {
6
- for (const adapter of this.adapters) {
7
- const txt = await adapter["core:get-text"]?.call(this, page);
8
- if (txt !== void 0) return `# ${page.data.title} (${page.url})\n\n${txt}`;
9
- }
10
- throw new Error("[Fumapress] Please specify the `getLLMText()` option in llmsPlugin()");
11
- } } = options;
12
- return {
13
- init() {
14
- this.data["core:docs-layout"] ??= {};
15
- this.data["core:docs-layout"].renderers ??= [];
16
- this.data["core:docs-layout"].renderers.push(function(res) {
17
- res.markdownUrl ??= slugsToMarkdownPath(this.page.slugs, this.page.locale).url;
18
- return res;
19
- });
20
- },
21
- async createPages({ createApiIsomorphic }) {
22
- const defaultRenderMode = this.mode === "dynamic" ? "dynamic" : "static";
23
- createApiIsomorphic({
24
- render: defaultRenderMode,
25
- path: "/llms.txt",
26
- handler: async () => {
27
- const source = await this.getLoader();
28
- return new Response(llms(source).index());
29
- }
30
- });
31
- createApiIsomorphic({
32
- render: defaultRenderMode,
33
- path: "/llms-full.txt",
34
- handler: async () => {
35
- const scan = (await this.getLoader()).getPages().map(getLLMText);
36
- const scanned = await Promise.all(scan);
37
- return new Response(scanned.join("\n\n"));
38
- }
39
- });
40
- createApiIsomorphic({
41
- render: defaultRenderMode,
42
- path: this.i18nConfig ? "/[lang]/[...slugs]" : "/[...slugs]",
43
- staticPaths: defaultRenderMode === "static" ? (await this.getLoader()).getPages().map((page) => slugsToMarkdownPath(page.slugs, page.locale).segments) : void 0,
44
- handler: async (_req, { params }) => {
45
- const page = (await this.getLoader()).getPage(markdownPathToSlugs(params.slugs), params.lang);
46
- if (!page) unstable_notFound();
47
- return new Response(await getLLMText.call(this, page), { headers: { "Content-Type": "text/markdown" } });
48
- }
49
- });
50
- }
51
- };
52
- }
53
- function markdownPathToSlugs(segs) {
54
- const slugs = [...segs];
55
- if (slugs.length === 0) return slugs;
56
- slugs[slugs.length - 1] = slugs[slugs.length - 1].replace(/\.md$/, "");
57
- if (slugs.length === 1 && slugs[0] === "index") slugs.pop();
58
- return slugs;
59
- }
60
- function slugsToMarkdownPath(slugs, lang) {
61
- const segments = [...slugs];
62
- if (segments.length === 0) segments.push("index.md");
63
- else segments[segments.length - 1] += ".md";
64
- if (lang) segments.unshift(lang);
65
- return {
66
- segments,
67
- url: `/${segments.join("/")}`
68
- };
69
- }
70
- //#endregion
71
- export { llmsPlugin };
@@ -1,14 +0,0 @@
1
- import { ConfigContext } from "../config.js";
2
- import { AppContext } from "../lib/shared.js";
3
- import { Awaitable, ServerPlugin } from "../lib/types.js";
4
- import { AdvancedIndex } from "fumadocs-core/search/server";
5
-
6
- //#region src/plugins/orama-search.d.ts
7
- interface OramaSearchOptions<C extends ConfigContext = ConfigContext> {
8
- buildIndex?: (this: AppContext<C>, page: C['loaderConfig']['page']) => Awaitable<AdvancedIndex>;
9
- }
10
- declare function oramaSearchPlugin<C extends ConfigContext = ConfigContext>({
11
- buildIndex
12
- }?: OramaSearchOptions<C>): ServerPlugin;
13
- //#endregion
14
- export { OramaSearchOptions, oramaSearchPlugin };
@@ -1,35 +0,0 @@
1
- //#region src/plugins/orama-search.ts
2
- function oramaSearchPlugin({ buildIndex = async function buildIndexDefault(page) {
3
- for (const adapter of this.adapters) {
4
- const structuredData = await adapter["core:get-structured-data"]?.call(this, page);
5
- if (structuredData !== void 0) return {
6
- id: page.url,
7
- title: page.data.title ?? page.path,
8
- description: page.data.description,
9
- url: page.url,
10
- structuredData
11
- };
12
- }
13
- throw new Error("[Fumapress] Please specify the `buildIndex` option to oramaSearchPlugin()");
14
- } } = {}) {
15
- return {
16
- init() {
17
- if (this.mode === "static") (this.data["core:provider"] ??= []).push(async (props) => {
18
- props.search ??= {};
19
- props.search.SearchDialog ??= (await import("../components/orama-search-static.js")).default;
20
- return props;
21
- });
22
- },
23
- async createPages({ createApiIsomorphic }) {
24
- const { createFromSource } = await import("fumadocs-core/search/server");
25
- const server = createFromSource(this.getLoader, { buildIndex: buildIndex.bind(this) });
26
- createApiIsomorphic({
27
- render: this.mode === "static" ? "static" : "dynamic",
28
- path: "/api/search",
29
- handler: this.mode === "static" ? server.staticGET : server.GET
30
- });
31
- }
32
- };
33
- }
34
- //#endregion
35
- export { oramaSearchPlugin };
@@ -1,16 +0,0 @@
1
- import { ConfigContext } from "../config.js";
2
- import { AppContext } from "../lib/shared.js";
3
- import { Awaitable, ServerPlugin } from "../lib/types.js";
4
- import { ReactNode } from "react";
5
- import { ImageResponseOptions } from "@takumi-rs/image-response";
6
-
7
- //#region src/plugins/takumi.d.ts
8
- interface TakumiOptions<C extends ConfigContext = ConfigContext> {
9
- generate?: (this: AppContext<C>, page: C['loaderConfig']['page']) => Awaitable<{
10
- node: ReactNode;
11
- options?: Partial<ImageResponseOptions>;
12
- }>;
13
- }
14
- declare function takumiPlugin<C extends ConfigContext = ConfigContext>(options?: TakumiOptions<C>): ServerPlugin;
15
- //#endregion
16
- export { TakumiOptions, takumiPlugin };
@@ -1,62 +0,0 @@
1
- import { createElement } from "react";
2
- import { unstable_notFound } from "waku/router/server";
3
- import { ImageResponse } from "@takumi-rs/image-response";
4
- //#region src/plugins/takumi.ts
5
- function takumiPlugin(options = {}) {
6
- const { generate = async function generateDefault(page) {
7
- const { generate } = await import("fumadocs-ui/og/takumi");
8
- return { node: generate({
9
- title: page.data.title,
10
- description: page.data.description,
11
- site: this.siteConfig.name
12
- }) };
13
- } } = options;
14
- return {
15
- init() {
16
- (this.data["core:page-meta"] ??= []).push((page) => {
17
- return createElement("meta", {
18
- property: "og:image",
19
- content: slugsToImagePath(page.slugs, page.locale).url
20
- });
21
- });
22
- },
23
- async createPages({ createApiIsomorphic }) {
24
- const renderMode = this.mode === "dynamic" ? "dynamic" : "static";
25
- createApiIsomorphic({
26
- render: renderMode,
27
- path: this.i18nConfig ? "/[lang]/[...slugs]" : "/[...slugs]",
28
- staticPaths: renderMode === "static" ? (await this.getLoader()).getPages().map((page) => slugsToImagePath(page.slugs, page.locale).segments) : void 0,
29
- handler: async (_, { params }) => {
30
- const page = (await this.getLoader()).getPage(imagePathToSlugs(params.slugs), params.lang);
31
- if (!page) unstable_notFound();
32
- const { node, options } = await generate.call(this, page);
33
- return new ImageResponse(node, {
34
- width: 1200,
35
- height: 630,
36
- ...options,
37
- format: "webp"
38
- });
39
- }
40
- });
41
- }
42
- };
43
- }
44
- function slugsToImagePath(slugs, lang) {
45
- const segments = [...slugs];
46
- if (segments.length === 0) segments.push("index.webp");
47
- else segments[segments.length - 1] += ".webp";
48
- if (lang) segments.unshift(lang);
49
- return {
50
- segments,
51
- url: `/${segments.join("/")}`
52
- };
53
- }
54
- function imagePathToSlugs(segs) {
55
- const slugs = [...segs];
56
- if (slugs.length === 0) return slugs;
57
- slugs[slugs.length - 1] = slugs[slugs.length - 1].replace(/\.webp$/, "");
58
- if (slugs.length === 1 && slugs[0] === "index") slugs.pop();
59
- return slugs;
60
- }
61
- //#endregion
62
- export { takumiPlugin };
package/dist/router.d.ts DELETED
@@ -1,26 +0,0 @@
1
- import { Config, ConfigContext } from "./config.js";
2
- import { AppContext } from "./lib/shared.js";
3
- import * as waku from "waku";
4
- import { ComponentType, ReactNode } from "react";
5
-
6
- //#region src/router.d.ts
7
- type RouterOptions<C extends ConfigContext = ConfigContext> = Partial<Layouts<C>>;
8
- interface Layouts<C extends ConfigContext = ConfigContext> {
9
- root: ComponentType<AppContext<C> & {
10
- lang?: string;
11
- children: ReactNode;
12
- }>;
13
- page: ComponentType<AppContext<C> & {
14
- lang?: string;
15
- slugs: string[];
16
- }>;
17
- notFound: ComponentType<AppContext<C> & {
18
- lang?: string;
19
- }>;
20
- }
21
- declare function createRouter<C extends ConfigContext>(rawConfig: Config<C>, options?: RouterOptions<NoInfer<C>>): {
22
- extend: typeof waku.createPages;
23
- createPages: () => ReturnType<typeof waku.createPages>;
24
- };
25
- //#endregion
26
- export { Layouts, RouterOptions, createRouter };