@farming-labs/next 0.0.2-beta.1

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.
@@ -0,0 +1,23 @@
1
+ import * as next from "next";
2
+
3
+ //#region src/config.d.ts
4
+ /**
5
+ * Next.js config wrapper for @farming-labs/docs.
6
+ * Handles MDX compilation, frontmatter, syntax highlighting, TOC extraction,
7
+ * and auto-generates mdx-components.tsx + docs layout when missing.
8
+ *
9
+ * @example
10
+ * // next.config.ts — this is all you need:
11
+ * import { withDocs } from "@farming-labs/next/config";
12
+ * export default withDocs();
13
+ *
14
+ * @example
15
+ * // With existing Next.js config
16
+ * import { withDocs } from "@farming-labs/next/config";
17
+ * export default withDocs({
18
+ * images: { remotePatterns: [{ hostname: "example.com" }] },
19
+ * });
20
+ */
21
+ declare function withDocs(nextConfig?: Record<string, unknown>): Promise<next.NextConfig>;
22
+ //#endregion
23
+ export { withDocs };
@@ -0,0 +1,122 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import createMDX from "@next/mdx";
4
+ import remarkGfm from "remark-gfm";
5
+ import remarkFrontmatter from "remark-frontmatter";
6
+ import remarkMdxFrontmatter from "remark-mdx-frontmatter";
7
+
8
+ //#region src/config.ts
9
+ /**
10
+ * Next.js config wrapper for @farming-labs/docs.
11
+ * Handles MDX compilation, frontmatter, syntax highlighting, TOC extraction,
12
+ * and auto-generates mdx-components.tsx + docs layout when missing.
13
+ *
14
+ * @example
15
+ * // next.config.ts — this is all you need:
16
+ * import { withDocs } from "@farming-labs/next/config";
17
+ * export default withDocs();
18
+ *
19
+ * @example
20
+ * // With existing Next.js config
21
+ * import { withDocs } from "@farming-labs/next/config";
22
+ * export default withDocs({
23
+ * images: { remotePatterns: [{ hostname: "example.com" }] },
24
+ * });
25
+ */
26
+ const GENERATED_BANNER = "// Auto-generated by @farming-labs/next — do not edit manually.\n";
27
+ const MDX_COMPONENTS_TEMPLATE = `\
28
+ ${GENERATED_BANNER}
29
+ import { getMDXComponents } from "@farming-labs/fumadocs/mdx";
30
+ import type { MDXComponents } from "mdx/types";
31
+ import docsConfig from "@/docs.config";
32
+
33
+ export function useMDXComponents(components?: MDXComponents): MDXComponents {
34
+ return getMDXComponents({
35
+ ...(docsConfig.components as MDXComponents),
36
+ ...components,
37
+ });
38
+ }
39
+ `;
40
+ const DOCS_LAYOUT_TEMPLATE = `\
41
+ ${GENERATED_BANNER}
42
+ import docsConfig from "@/docs.config";
43
+ import { createDocsLayout, createDocsMetadata } from "@farming-labs/fumadocs";
44
+
45
+ export const metadata = createDocsMetadata(docsConfig);
46
+ export default createDocsLayout(docsConfig);
47
+ `;
48
+ const SEARCH_ROUTE_TEMPLATE = `\
49
+ ${GENERATED_BANNER}
50
+ import { createDocsSearchAPI } from "@farming-labs/fumadocs/search";
51
+
52
+ export const { GET } = createDocsSearchAPI();
53
+
54
+ export const revalidate = false;
55
+ `;
56
+ const FILE_EXTS = [
57
+ "tsx",
58
+ "ts",
59
+ "jsx",
60
+ "js"
61
+ ];
62
+ function hasFile(root, baseName) {
63
+ return FILE_EXTS.some((ext) => existsSync(join(root, `${baseName}.${ext}`)));
64
+ }
65
+ /** Read the docs entry path from docs.config.ts[x] (defaults to "docs"). */
66
+ function readDocsEntry(root) {
67
+ for (const ext of FILE_EXTS) {
68
+ const configPath = join(root, `docs.config.${ext}`);
69
+ if (existsSync(configPath)) try {
70
+ const match = readFileSync(configPath, "utf-8").match(/entry\s*:\s*["']([^"']+)["']/);
71
+ if (match) return match[1];
72
+ } catch {}
73
+ }
74
+ return "docs";
75
+ }
76
+ async function withDocs(nextConfig = {}) {
77
+ const root = process.cwd();
78
+ const { remarkHeading, rehypeToc, rehypeCode } = await new Function("specifier", "return import(specifier)")("fumadocs-core/mdx-plugins");
79
+ if (!hasFile(root, "mdx-components")) writeFileSync(join(root, "mdx-components.tsx"), MDX_COMPONENTS_TEMPLATE);
80
+ const layoutDir = join(root, "app", readDocsEntry(root));
81
+ if (existsSync(layoutDir) && !hasFile(layoutDir, "layout")) writeFileSync(join(layoutDir, "layout.tsx"), DOCS_LAYOUT_TEMPLATE);
82
+ else if (!existsSync(layoutDir)) {
83
+ mkdirSync(layoutDir, { recursive: true });
84
+ writeFileSync(join(layoutDir, "layout.tsx"), DOCS_LAYOUT_TEMPLATE);
85
+ }
86
+ const searchRouteDir = join(root, "app", "api", "search");
87
+ if (!hasFile(searchRouteDir, "route")) {
88
+ mkdirSync(searchRouteDir, { recursive: true });
89
+ writeFileSync(join(searchRouteDir, "route.ts"), SEARCH_ROUTE_TEMPLATE);
90
+ }
91
+ const withMDX = createMDX({
92
+ extension: /\.mdx?$/,
93
+ options: {
94
+ remarkPlugins: [
95
+ remarkGfm,
96
+ remarkFrontmatter,
97
+ [remarkMdxFrontmatter, { name: "metadata" }],
98
+ remarkHeading
99
+ ],
100
+ rehypePlugins: [rehypeToc, [rehypeCode, { themes: {
101
+ dark: "github-dark",
102
+ light: "github-light"
103
+ } }]]
104
+ }
105
+ });
106
+ const defaultExts = [
107
+ "js",
108
+ "jsx",
109
+ "md",
110
+ "mdx",
111
+ "ts",
112
+ "tsx"
113
+ ];
114
+ const userExts = nextConfig.pageExtensions;
115
+ if (userExts) {
116
+ for (const ext of ["md", "mdx"]) if (!userExts.includes(ext)) userExts.push(ext);
117
+ } else nextConfig.pageExtensions = defaultExts;
118
+ return withMDX(nextConfig);
119
+ }
120
+
121
+ //#endregion
122
+ export { withDocs };
@@ -0,0 +1,2 @@
1
+ import { withDocs } from "./config.mjs";
2
+ export { withDocs };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { withDocs } from "./config.mjs";
2
+
3
+ export { withDocs };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@farming-labs/next",
3
+ "version": "0.0.2-beta.1",
4
+ "description": "Next.js adapter for @farming-labs/docs — MDX config wrapper",
5
+ "type": "module",
6
+ "main": "./dist/index.mjs",
7
+ "types": "./dist/index.d.mts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.mts",
11
+ "import": "./dist/index.mjs",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "./config": {
15
+ "types": "./dist/config.d.mts",
16
+ "import": "./dist/config.mjs",
17
+ "default": "./dist/config.mjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "keywords": [
24
+ "docs",
25
+ "next",
26
+ "mdx",
27
+ "documentation"
28
+ ],
29
+ "author": "Farming Labs",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@mdx-js/loader": "^3.1.0",
33
+ "@mdx-js/react": "^3.1.0",
34
+ "@next/mdx": "^16.1.6",
35
+ "fumadocs-core": "^16.6.1",
36
+ "remark-frontmatter": "^5.0.0",
37
+ "remark-gfm": "^4.0.1",
38
+ "remark-mdx-frontmatter": "^5.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^22.10.0",
42
+ "tsdown": "^0.20.3",
43
+ "typescript": "^5.9.3"
44
+ },
45
+ "peerDependencies": {
46
+ "next": ">=14.0.0",
47
+ "react": ">=18.0.0",
48
+ "react-dom": ">=18.0.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsdown",
52
+ "dev": "tsdown --watch",
53
+ "typecheck": "tsc --noEmit"
54
+ }
55
+ }