@objectdocs/site 0.2.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.
- package/CHANGELOG.md +25 -0
- package/README.md +42 -0
- package/app/[lang]/docs/[[...slug]]/page.tsx +84 -0
- package/app/[lang]/docs/layout.tsx +61 -0
- package/app/[lang]/layout.tsx +35 -0
- package/app/[lang]/page.tsx +20 -0
- package/app/api/search/route.ts +20 -0
- package/app/layout.config.tsx +49 -0
- package/app/layout.tsx +34 -0
- package/app/page.tsx +19 -0
- package/docs.site.json +69 -0
- package/lib/deep-merge.ts +31 -0
- package/lib/i18n.ts +16 -0
- package/lib/site-config.ts +154 -0
- package/lib/source.ts +24 -0
- package/lib/translations.ts +110 -0
- package/mdx-components.tsx +20 -0
- package/next.config.mjs +20 -0
- package/objectdocs.json +69 -0
- package/package.json +34 -0
- package/proxy.ts +44 -0
- package/public/.gitkeep +0 -0
- package/public/logo.svg +11 -0
- package/source.config.ts +43 -0
- package/tsconfig.json +43 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @objectdocs/site
|
|
2
|
+
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Bug fixes and improvements for ObjectDocs
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Initial release of ObjectDocs - A modern documentation engine built on Next.js 14 and Fumadocs
|
|
14
|
+
|
|
15
|
+
## 0.1.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- Initial release of ObjectDocs
|
|
20
|
+
|
|
21
|
+
- Modern documentation engine built on Next.js 14 and Fumadocs
|
|
22
|
+
- Metadata-driven architecture with configuration as code
|
|
23
|
+
- Support for low-code component embedding
|
|
24
|
+
- Enterprise-grade UI with dark mode support
|
|
25
|
+
- Multi-product documentation support
|
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @objectdocs/site
|
|
2
|
+
|
|
3
|
+
The Next.js application foundation for the ObjectStack documentation.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the actual Next.js application structure, configuration, and UI components used to render the documentation. It is designed to be encapsulated and run via the `@objectdocs/cli`.
|
|
8
|
+
|
|
9
|
+
## Tech Stack
|
|
10
|
+
|
|
11
|
+
- **Concepts**: Next.js 16 (App Router)
|
|
12
|
+
- **Documentation**: Fumadocs
|
|
13
|
+
- **Styling**: Tailwind CSS
|
|
14
|
+
- **Deployment**: Static Export (`output: 'export'`)
|
|
15
|
+
|
|
16
|
+
## Development
|
|
17
|
+
|
|
18
|
+
Typically you won't run this package directly. Instead, you should use the CLI from the root workspace:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm dev
|
|
22
|
+
# or
|
|
23
|
+
pnpm objectdocs dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
However, for internal development of the site theme or logic, you can run:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd packages/site
|
|
30
|
+
pnpm dev
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Structure
|
|
34
|
+
|
|
35
|
+
- `app/`: Next.js App Router pages and layouts.
|
|
36
|
+
- `lib/`: Utility functions (i18n, etc).
|
|
37
|
+
- `source.config.ts`: Fumadocs configuration.
|
|
38
|
+
- `next.config.mjs`: Next.js configuration (configured for static export).
|
|
39
|
+
|
|
40
|
+
## Build output
|
|
41
|
+
|
|
42
|
+
When built, the static assets are generated in the `out/` directory.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { source } from '@/lib/source';
|
|
10
|
+
import type { Metadata } from 'next';
|
|
11
|
+
import { DocsPage, DocsBody } from 'fumadocs-ui/page';
|
|
12
|
+
import { notFound } from 'next/navigation';
|
|
13
|
+
import { siteConfig } from '@/lib/site-config';
|
|
14
|
+
import defaultComponents from 'fumadocs-ui/mdx';
|
|
15
|
+
import { Callout } from 'fumadocs-ui/components/callout';
|
|
16
|
+
import { Card, Cards } from 'fumadocs-ui/components/card';
|
|
17
|
+
import { Steps, Step } from 'fumadocs-ui/components/steps';
|
|
18
|
+
|
|
19
|
+
const components = {
|
|
20
|
+
...defaultComponents,
|
|
21
|
+
Callout,
|
|
22
|
+
Card,
|
|
23
|
+
Cards,
|
|
24
|
+
Steps,
|
|
25
|
+
Step,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface PageProps {
|
|
29
|
+
params: Promise<{
|
|
30
|
+
lang: string;
|
|
31
|
+
slug?: string[];
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default async function Page({ params }: PageProps) {
|
|
36
|
+
const { lang, slug = [] } = await params;
|
|
37
|
+
|
|
38
|
+
const page = source.getPage(slug, lang);
|
|
39
|
+
|
|
40
|
+
if (!page) {
|
|
41
|
+
notFound();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const MDX = page.data.body as any;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<DocsPage
|
|
48
|
+
toc={page.data.toc as any}
|
|
49
|
+
full={page.data.full as any}
|
|
50
|
+
lastUpdate={siteConfig.page.showLastUpdate ? (page.data as any).lastModified : undefined}
|
|
51
|
+
tableOfContent={{
|
|
52
|
+
enabled: siteConfig.layout.toc.enabled,
|
|
53
|
+
style: siteConfig.layout.toc.depth > 2 ? 'clerk' : 'normal',
|
|
54
|
+
}}
|
|
55
|
+
editOnGithub={siteConfig.page.showEditLink ? {
|
|
56
|
+
owner: siteConfig.page.repoBaseUrl.split('/')[3],
|
|
57
|
+
repo: siteConfig.page.repoBaseUrl.split('/')[4],
|
|
58
|
+
sha: 'main', // Defaulting to main, could be extracted
|
|
59
|
+
path: siteConfig.page.repoBaseUrl.split('/').slice(7).join('/') // simplistic parsing
|
|
60
|
+
} : undefined}
|
|
61
|
+
>
|
|
62
|
+
<DocsBody>
|
|
63
|
+
<MDX components={components} />
|
|
64
|
+
</DocsBody>
|
|
65
|
+
</DocsPage>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
export async function generateStaticParams() {
|
|
71
|
+
return source.generateParams();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
|
75
|
+
const { lang, slug = [] } = await params;
|
|
76
|
+
const page = source.getPage(slug, lang);
|
|
77
|
+
|
|
78
|
+
if (!page) notFound();
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
title: page.data.title,
|
|
82
|
+
description: page.data.description,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { source } from '@/lib/source';
|
|
10
|
+
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
11
|
+
import type { ReactNode } from 'react';
|
|
12
|
+
import { baseOptions } from '@/app/layout.config';
|
|
13
|
+
import { siteConfig } from '@/lib/site-config';
|
|
14
|
+
|
|
15
|
+
export default async function Layout({
|
|
16
|
+
params,
|
|
17
|
+
children,
|
|
18
|
+
}: {
|
|
19
|
+
params: Promise<{ lang: string }>;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}) {
|
|
22
|
+
const { lang } = await params;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<DocsLayout
|
|
26
|
+
tree={source.getPageTree(lang)}
|
|
27
|
+
{...baseOptions}
|
|
28
|
+
sidebar={{
|
|
29
|
+
enabled: siteConfig.layout.sidebar.enabled,
|
|
30
|
+
prefetch: siteConfig.layout.sidebar.prefetch,
|
|
31
|
+
collapsible: siteConfig.layout.sidebar.collapsible,
|
|
32
|
+
defaultOpenLevel: siteConfig.layout.sidebar.defaultOpenLevel,
|
|
33
|
+
footer: siteConfig.layout.sidebar.footer ? (
|
|
34
|
+
<div className="p-4 text-xs text-muted-foreground border-t">
|
|
35
|
+
{siteConfig.layout.sidebar.footer.html ? (
|
|
36
|
+
<div dangerouslySetInnerHTML={{ __html: siteConfig.layout.sidebar.footer.html }} />
|
|
37
|
+
) : (
|
|
38
|
+
siteConfig.layout.sidebar.footer.text
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
) : undefined,
|
|
42
|
+
tabs: siteConfig.layout.sidebar.tabs && siteConfig.layout.sidebar.tabs.length > 0 ?
|
|
43
|
+
siteConfig.layout.sidebar.tabs.map(tab => ({
|
|
44
|
+
title: tab.title,
|
|
45
|
+
url: tab.url,
|
|
46
|
+
description: tab.description,
|
|
47
|
+
})) : undefined,
|
|
48
|
+
banner: siteConfig.layout.sidebar.banner ? (
|
|
49
|
+
<div className="-mx-2 -mt-2 rounded-lg border bg-card p-4 transition-colors hover:bg-accent/50 text-card-foreground text-sm">
|
|
50
|
+
<a href={siteConfig.layout.sidebar.banner.url} className="block font-medium">
|
|
51
|
+
{siteConfig.layout.sidebar.banner.text}
|
|
52
|
+
</a>
|
|
53
|
+
</div>
|
|
54
|
+
) : undefined
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
</DocsLayout>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import 'fumadocs-ui/style.css';
|
|
10
|
+
import { RootProvider } from 'fumadocs-ui/provider/next';
|
|
11
|
+
import { defineI18nUI } from 'fumadocs-ui/i18n';
|
|
12
|
+
import { i18n } from '@/lib/i18n';
|
|
13
|
+
import { getTranslations } from '@/lib/translations';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const { provider } = defineI18nUI(i18n, {
|
|
17
|
+
translations: getTranslations(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default async function Layout({ params, children }: LayoutProps<'/[lang]'>) {
|
|
21
|
+
const { lang } = await params;
|
|
22
|
+
return (
|
|
23
|
+
<html lang={lang} suppressHydrationWarning>
|
|
24
|
+
<body
|
|
25
|
+
style={{
|
|
26
|
+
display: 'flex',
|
|
27
|
+
flexDirection: 'column',
|
|
28
|
+
minHeight: '100vh',
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<RootProvider i18n={provider(lang)}>{children}</RootProvider>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { redirect, notFound } from 'next/navigation';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export default async function LangPage({
|
|
13
|
+
params,
|
|
14
|
+
}: {
|
|
15
|
+
params: Promise<{ lang: string }>;
|
|
16
|
+
}) {
|
|
17
|
+
const { lang } = await params;
|
|
18
|
+
|
|
19
|
+
redirect(`/${lang}/docs`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { source } from '@/lib/source';
|
|
10
|
+
import { createSearchAPI } from 'fumadocs-core/search/server';
|
|
11
|
+
|
|
12
|
+
export const { GET } = createSearchAPI('advanced', {
|
|
13
|
+
indexes: source.getPages().map((page) => ({
|
|
14
|
+
title: page.data.title,
|
|
15
|
+
description: page.data.description,
|
|
16
|
+
url: page.url,
|
|
17
|
+
id: page.url,
|
|
18
|
+
structuredData: page.data.structuredData,
|
|
19
|
+
})),
|
|
20
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { type BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
|
|
10
|
+
import { siteConfig } from '@/lib/site-config';
|
|
11
|
+
import Image from 'next/image';
|
|
12
|
+
|
|
13
|
+
export const baseOptions: BaseLayoutProps = {
|
|
14
|
+
nav: {
|
|
15
|
+
title: (
|
|
16
|
+
<div className="flex items-center gap-2">
|
|
17
|
+
{siteConfig.branding.logo.light && (
|
|
18
|
+
<Image
|
|
19
|
+
src={siteConfig.branding.logo.light}
|
|
20
|
+
alt={siteConfig.branding.logo.text || 'Logo'}
|
|
21
|
+
width={30}
|
|
22
|
+
height={30}
|
|
23
|
+
className={siteConfig.branding.logo.dark ? 'dark:hidden' : ''}
|
|
24
|
+
/>
|
|
25
|
+
)}
|
|
26
|
+
{siteConfig.branding.logo.dark && (
|
|
27
|
+
<Image
|
|
28
|
+
src={siteConfig.branding.logo.dark}
|
|
29
|
+
alt={siteConfig.branding.logo.text || 'Logo'}
|
|
30
|
+
width={30}
|
|
31
|
+
height={30}
|
|
32
|
+
className="hidden dark:block"
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
<span className="font-bold">{siteConfig.branding.logo.text || 'ObjectStack'}</span>
|
|
36
|
+
</div>
|
|
37
|
+
),
|
|
38
|
+
transparentMode: siteConfig.layout.navbar.transparentMode,
|
|
39
|
+
},
|
|
40
|
+
links: siteConfig.layout.navbar.links.map(link => ({
|
|
41
|
+
text: link.text,
|
|
42
|
+
url: link.url,
|
|
43
|
+
active: link.active || 'nested-url',
|
|
44
|
+
external: link.external,
|
|
45
|
+
})),
|
|
46
|
+
githubUrl: siteConfig.layout.navbar.socials.find(s => s.platform === 'github')?.url,
|
|
47
|
+
i18n: siteConfig.i18n.enabled,
|
|
48
|
+
};
|
|
49
|
+
|
package/app/layout.tsx
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import 'fumadocs-ui/style.css';
|
|
10
|
+
import { RootProvider } from 'fumadocs-ui/provider/next';
|
|
11
|
+
import { defineI18nUI } from 'fumadocs-ui/i18n';
|
|
12
|
+
import { i18n } from '@/lib/i18n';
|
|
13
|
+
import { getTranslations } from '@/lib/translations';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const { provider } = defineI18nUI(i18n, {
|
|
17
|
+
translations: getTranslations(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
21
|
+
return (
|
|
22
|
+
<html lang="en" suppressHydrationWarning>
|
|
23
|
+
<body
|
|
24
|
+
style={{
|
|
25
|
+
display: 'flex',
|
|
26
|
+
flexDirection: 'column',
|
|
27
|
+
minHeight: '100vh',
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
33
|
+
);
|
|
34
|
+
}
|
package/app/page.tsx
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { redirect } from 'next/navigation';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Root page - redirects are handled by proxy.ts middleware
|
|
13
|
+
* This page should never actually render as the middleware intercepts and redirects
|
|
14
|
+
* But Next.js requires a page component for the route to be recognized
|
|
15
|
+
*/
|
|
16
|
+
export default function RootPage() {
|
|
17
|
+
// Fallback redirect if middleware didn't handle it
|
|
18
|
+
redirect('/en/docs');
|
|
19
|
+
}
|
package/docs.site.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "ObjectDocs",
|
|
4
|
+
"description": "The Metadata-Driven Documentation Engine for the Low-Code Era.",
|
|
5
|
+
"url": "https://docs.objectstack.ai",
|
|
6
|
+
"favicon": "/favicon.ico"
|
|
7
|
+
},
|
|
8
|
+
"i18n": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"defaultLanguage": "en",
|
|
11
|
+
"languages": ["en", "cn"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"branding": {
|
|
15
|
+
"logo": {
|
|
16
|
+
"text": "ObjectDocs",
|
|
17
|
+
"light": "/logo.svg",
|
|
18
|
+
"dark": "/logo.svg"
|
|
19
|
+
},
|
|
20
|
+
"theme": {
|
|
21
|
+
"accentColor": "blue",
|
|
22
|
+
"radius": "0.5rem"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"layout": {
|
|
26
|
+
"navbar": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"transparentMode": "top",
|
|
29
|
+
"links": [
|
|
30
|
+
{
|
|
31
|
+
"text": "Home",
|
|
32
|
+
"url": "https://www.objectstack.ai",
|
|
33
|
+
"external": true
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"socials": [
|
|
37
|
+
{ "platform": "github", "url": "https://github.com/objectstack-ai" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"sidebar": {
|
|
41
|
+
"enabled": true,
|
|
42
|
+
"prefetch": true,
|
|
43
|
+
"defaultOpenLevel": 1,
|
|
44
|
+
"collapsible": true,
|
|
45
|
+
"tabs": []
|
|
46
|
+
},
|
|
47
|
+
"toc": {
|
|
48
|
+
"enabled": true,
|
|
49
|
+
"depth": 3
|
|
50
|
+
},
|
|
51
|
+
"footer": {
|
|
52
|
+
"enabled": false,
|
|
53
|
+
"copyright": "© 2026 ObjectStack Inc."
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"page": {
|
|
57
|
+
"showLastUpdate": true,
|
|
58
|
+
"showEditLink": true,
|
|
59
|
+
"repoBaseUrl": "https://github.com/objectstack-ai/objectdocs"
|
|
60
|
+
},
|
|
61
|
+
"content": {
|
|
62
|
+
"math": false,
|
|
63
|
+
"imageZoom": true,
|
|
64
|
+
"codeBlock": {
|
|
65
|
+
"theme": "vesper",
|
|
66
|
+
"showLineNumbers": true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export function isObject(item: any): item is Record<string, any> {
|
|
10
|
+
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function deepMerge<T extends Record<string, any>>(target: T, source: Record<string, any>): T {
|
|
14
|
+
const output = { ...target };
|
|
15
|
+
|
|
16
|
+
if (isObject(target) && isObject(source)) {
|
|
17
|
+
Object.keys(source).forEach(key => {
|
|
18
|
+
if (isObject(source[key])) {
|
|
19
|
+
if (!(key in target)) {
|
|
20
|
+
Object.assign(output, { [key]: source[key] });
|
|
21
|
+
} else {
|
|
22
|
+
(output as any)[key] = deepMerge(target[key], source[key]);
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
Object.assign(output, { [key]: source[key] });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return output;
|
|
31
|
+
}
|
package/lib/i18n.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { siteConfig } from './site-config';
|
|
10
|
+
import { defineI18n } from 'fumadocs-core/i18n';
|
|
11
|
+
|
|
12
|
+
export const i18n = defineI18n({
|
|
13
|
+
defaultLanguage: siteConfig.i18n.defaultLanguage,
|
|
14
|
+
languages: siteConfig.i18n.languages,
|
|
15
|
+
parser: 'dot',
|
|
16
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { deepMerge } from './deep-merge';
|
|
10
|
+
import objectDocsConfig from '@/docs.site.json';
|
|
11
|
+
|
|
12
|
+
export interface SiteConfig {
|
|
13
|
+
meta: {
|
|
14
|
+
title: string;
|
|
15
|
+
description: string;
|
|
16
|
+
url: string;
|
|
17
|
+
favicon: string;
|
|
18
|
+
};
|
|
19
|
+
i18n: {
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
defaultLanguage: string;
|
|
22
|
+
languages: Array<string>;
|
|
23
|
+
};
|
|
24
|
+
build?: {
|
|
25
|
+
output?: 'export' | 'standalone' | undefined;
|
|
26
|
+
};
|
|
27
|
+
branding: {
|
|
28
|
+
logo: {
|
|
29
|
+
light?: string;
|
|
30
|
+
dark?: string;
|
|
31
|
+
text?: string;
|
|
32
|
+
};
|
|
33
|
+
theme: {
|
|
34
|
+
accentColor: string;
|
|
35
|
+
radius: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
layout: {
|
|
39
|
+
navbar: {
|
|
40
|
+
enabled: boolean;
|
|
41
|
+
transparentMode?: 'none' | 'top' | 'always';
|
|
42
|
+
links: Array<{
|
|
43
|
+
text: string;
|
|
44
|
+
url: string;
|
|
45
|
+
active?: 'url' | 'nested-url';
|
|
46
|
+
external?: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
socials: Array<{ platform: string; url: string }>;
|
|
49
|
+
};
|
|
50
|
+
sidebar: {
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
defaultOpenLevel: number;
|
|
53
|
+
collapsible: boolean;
|
|
54
|
+
prefetch?: boolean;
|
|
55
|
+
banner?: {
|
|
56
|
+
text: string;
|
|
57
|
+
url: string;
|
|
58
|
+
};
|
|
59
|
+
footer?: {
|
|
60
|
+
text?: string;
|
|
61
|
+
html?: string;
|
|
62
|
+
};
|
|
63
|
+
tabs?: Array<{
|
|
64
|
+
title: string;
|
|
65
|
+
url: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
toc: {
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
depth: number;
|
|
72
|
+
};
|
|
73
|
+
footer: {
|
|
74
|
+
copyright: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
page: {
|
|
78
|
+
showLastUpdate: boolean;
|
|
79
|
+
showEditLink: boolean;
|
|
80
|
+
repoBaseUrl: string;
|
|
81
|
+
};
|
|
82
|
+
content: {
|
|
83
|
+
math: boolean;
|
|
84
|
+
imageZoom: boolean;
|
|
85
|
+
codeBlock: {
|
|
86
|
+
theme: string;
|
|
87
|
+
showLineNumbers: boolean;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const defaultConfig: SiteConfig = {
|
|
93
|
+
meta: {
|
|
94
|
+
title: 'ObjectStack ',
|
|
95
|
+
description: 'Documentation',
|
|
96
|
+
url: 'https://objectstack.com',
|
|
97
|
+
favicon: '/favicon.ico',
|
|
98
|
+
},
|
|
99
|
+
i18n: {
|
|
100
|
+
enabled: true,
|
|
101
|
+
defaultLanguage: 'en',
|
|
102
|
+
languages: ["en", "cn"
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
branding: {
|
|
106
|
+
logo: {
|
|
107
|
+
text: 'ObjectStack',
|
|
108
|
+
},
|
|
109
|
+
theme: {
|
|
110
|
+
accentColor: 'blue',
|
|
111
|
+
radius: '0.5rem',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
layout: {
|
|
115
|
+
navbar: {
|
|
116
|
+
enabled: true,
|
|
117
|
+
transparentMode: 'top',
|
|
118
|
+
links: [],
|
|
119
|
+
socials: [],
|
|
120
|
+
},
|
|
121
|
+
sidebar: {
|
|
122
|
+
enabled: true,
|
|
123
|
+
defaultOpenLevel: 1,
|
|
124
|
+
collapsible: true,
|
|
125
|
+
prefetch: true,
|
|
126
|
+
},
|
|
127
|
+
toc: {
|
|
128
|
+
enabled: true,
|
|
129
|
+
depth: 3,
|
|
130
|
+
},
|
|
131
|
+
footer: {
|
|
132
|
+
copyright: '© 2026',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
page: {
|
|
136
|
+
showLastUpdate: true,
|
|
137
|
+
showEditLink: true,
|
|
138
|
+
repoBaseUrl: '',
|
|
139
|
+
},
|
|
140
|
+
content: {
|
|
141
|
+
math: false,
|
|
142
|
+
imageZoom: true,
|
|
143
|
+
codeBlock: {
|
|
144
|
+
theme: 'vesper',
|
|
145
|
+
showLineNumbers: true,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export function getSiteConfig(): SiteConfig {
|
|
151
|
+
return deepMerge(defaultConfig, objectDocsConfig);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const siteConfig = getSiteConfig();
|
package/lib/source.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { loader } from 'fumadocs-core/source';
|
|
10
|
+
import { docs, meta } from '@/.source/server';
|
|
11
|
+
import { toFumadocsSource } from 'fumadocs-mdx/runtime/server';
|
|
12
|
+
import { i18n } from './i18n';
|
|
13
|
+
|
|
14
|
+
const mainSource = toFumadocsSource(docs, meta);
|
|
15
|
+
|
|
16
|
+
export const source = loader({
|
|
17
|
+
baseUrl: '/docs',
|
|
18
|
+
source: {
|
|
19
|
+
files: [
|
|
20
|
+
...mainSource.files,
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
i18n,
|
|
24
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { siteConfig } from './site-config';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Translation strings for different languages
|
|
13
|
+
* These are the UI strings used by fumadocs-ui
|
|
14
|
+
*/
|
|
15
|
+
interface LanguageTranslations {
|
|
16
|
+
displayName: string;
|
|
17
|
+
toc?: string;
|
|
18
|
+
search?: string;
|
|
19
|
+
lastUpdate?: string;
|
|
20
|
+
searchNoResult?: string;
|
|
21
|
+
previousPage?: string;
|
|
22
|
+
nextPage?: string;
|
|
23
|
+
chooseLanguage?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Default translations for supported languages
|
|
28
|
+
* Add new language translations here as needed
|
|
29
|
+
*/
|
|
30
|
+
const defaultTranslations: Record<string, LanguageTranslations> = {
|
|
31
|
+
en: {
|
|
32
|
+
displayName: 'English',
|
|
33
|
+
},
|
|
34
|
+
cn: {
|
|
35
|
+
displayName: '简体中文',
|
|
36
|
+
toc: '目录',
|
|
37
|
+
search: '搜索文档',
|
|
38
|
+
lastUpdate: '最后更新于',
|
|
39
|
+
searchNoResult: '没有结果',
|
|
40
|
+
previousPage: '上一页',
|
|
41
|
+
nextPage: '下一页',
|
|
42
|
+
chooseLanguage: '选择语言',
|
|
43
|
+
},
|
|
44
|
+
ja: {
|
|
45
|
+
displayName: '日本語',
|
|
46
|
+
toc: '目次',
|
|
47
|
+
search: 'ドキュメントを検索',
|
|
48
|
+
lastUpdate: '最終更新',
|
|
49
|
+
searchNoResult: '結果がありません',
|
|
50
|
+
previousPage: '前のページ',
|
|
51
|
+
nextPage: '次のページ',
|
|
52
|
+
chooseLanguage: '言語を選択',
|
|
53
|
+
},
|
|
54
|
+
fr: {
|
|
55
|
+
displayName: 'Français',
|
|
56
|
+
toc: 'Table des matières',
|
|
57
|
+
search: 'Rechercher dans la documentation',
|
|
58
|
+
lastUpdate: 'Dernière mise à jour',
|
|
59
|
+
searchNoResult: 'Aucun résultat',
|
|
60
|
+
previousPage: 'Page précédente',
|
|
61
|
+
nextPage: 'Page suivante',
|
|
62
|
+
chooseLanguage: 'Choisir la langue',
|
|
63
|
+
},
|
|
64
|
+
de: {
|
|
65
|
+
displayName: 'Deutsch',
|
|
66
|
+
toc: 'Inhaltsverzeichnis',
|
|
67
|
+
search: 'Dokumentation durchsuchen',
|
|
68
|
+
lastUpdate: 'Zuletzt aktualisiert',
|
|
69
|
+
searchNoResult: 'Keine Ergebnisse',
|
|
70
|
+
previousPage: 'Vorherige Seite',
|
|
71
|
+
nextPage: 'Nächste Seite',
|
|
72
|
+
chooseLanguage: 'Sprache wählen',
|
|
73
|
+
},
|
|
74
|
+
es: {
|
|
75
|
+
displayName: 'Español',
|
|
76
|
+
toc: 'Tabla de contenidos',
|
|
77
|
+
search: 'Buscar documentación',
|
|
78
|
+
lastUpdate: 'Última actualización',
|
|
79
|
+
searchNoResult: 'Sin resultados',
|
|
80
|
+
previousPage: 'Página anterior',
|
|
81
|
+
nextPage: 'Página siguiente',
|
|
82
|
+
chooseLanguage: 'Elegir idioma',
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get translations for configured languages
|
|
88
|
+
* Returns only the translations for languages specified in docs.site.json
|
|
89
|
+
*/
|
|
90
|
+
export function getTranslations(): Record<string, LanguageTranslations> {
|
|
91
|
+
const configuredLanguages = siteConfig.i18n.languages;
|
|
92
|
+
const translations: Record<string, LanguageTranslations> = {};
|
|
93
|
+
|
|
94
|
+
for (const lang of configuredLanguages) {
|
|
95
|
+
if (defaultTranslations[lang]) {
|
|
96
|
+
translations[lang] = defaultTranslations[lang];
|
|
97
|
+
} else {
|
|
98
|
+
// If no translation exists for a configured language, provide a minimal fallback
|
|
99
|
+
// Only log warning in development
|
|
100
|
+
if (process.env.NODE_ENV === 'development') {
|
|
101
|
+
console.warn(`Warning: No translations found for language "${lang}". Using minimal fallback.`);
|
|
102
|
+
}
|
|
103
|
+
translations[lang] = {
|
|
104
|
+
displayName: lang.toUpperCase(),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return translations;
|
|
110
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import defaultComponents from 'fumadocs-ui/mdx';
|
|
10
|
+
import type { MDXComponents } from 'mdx/types';
|
|
11
|
+
import { Steps, Step } from 'fumadocs-ui/components/steps';
|
|
12
|
+
|
|
13
|
+
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
|
14
|
+
return {
|
|
15
|
+
...defaultComponents,
|
|
16
|
+
Steps,
|
|
17
|
+
Step,
|
|
18
|
+
...components,
|
|
19
|
+
};
|
|
20
|
+
}
|
package/next.config.mjs
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createMDX } from 'fumadocs-mdx/next';
|
|
10
|
+
|
|
11
|
+
const withMDX = createMDX();
|
|
12
|
+
|
|
13
|
+
/** @type {import('next').NextConfig} */
|
|
14
|
+
const nextConfig = {
|
|
15
|
+
reactStrictMode: true,
|
|
16
|
+
distDir: '.next',
|
|
17
|
+
images: { unoptimized: true },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default withMDX(nextConfig);
|
package/objectdocs.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "ObjectStack Docs",
|
|
4
|
+
"description": "Enterprise-grade low-code platform documentation",
|
|
5
|
+
"url": "https://docs.objectstack.ai",
|
|
6
|
+
"favicon": "/favicon.ico"
|
|
7
|
+
},
|
|
8
|
+
"i18n": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"defaultLanguage": "en",
|
|
11
|
+
"languages": ["en", "cn"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"branding": {
|
|
15
|
+
"logo": {
|
|
16
|
+
"text": "ObjectStack",
|
|
17
|
+
"light": "/logo.svg",
|
|
18
|
+
"dark": "/logo.svg"
|
|
19
|
+
},
|
|
20
|
+
"theme": {
|
|
21
|
+
"accentColor": "blue",
|
|
22
|
+
"radius": "0.5rem"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"layout": {
|
|
26
|
+
"navbar": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"transparentMode": "top",
|
|
29
|
+
"links": [
|
|
30
|
+
{
|
|
31
|
+
"text": "Home",
|
|
32
|
+
"url": "https://www.objectstack.ai",
|
|
33
|
+
"external": true
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"socials": [
|
|
37
|
+
{ "platform": "github", "url": "https://github.com/objectstack-ai/" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"sidebar": {
|
|
41
|
+
"enabled": true,
|
|
42
|
+
"prefetch": true,
|
|
43
|
+
"defaultOpenLevel": 1,
|
|
44
|
+
"collapsible": true,
|
|
45
|
+
"tabs": []
|
|
46
|
+
},
|
|
47
|
+
"toc": {
|
|
48
|
+
"enabled": true,
|
|
49
|
+
"depth": 3
|
|
50
|
+
},
|
|
51
|
+
"footer": {
|
|
52
|
+
"enabled": false,
|
|
53
|
+
"copyright": "© 2026 ObjectStack Inc."
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"page": {
|
|
57
|
+
"showLastUpdate": true,
|
|
58
|
+
"showEditLink": true,
|
|
59
|
+
"repoBaseUrl": "https://github.com/objectstack-ai/docs"
|
|
60
|
+
},
|
|
61
|
+
"content": {
|
|
62
|
+
"math": false,
|
|
63
|
+
"imageZoom": true,
|
|
64
|
+
"codeBlock": {
|
|
65
|
+
"theme": "vesper",
|
|
66
|
+
"showLineNumbers": true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@objectdocs/site",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"@fumadocs/ui": "^16.4.7",
|
|
6
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
7
|
+
"@types/mdx": "^2.0.13",
|
|
8
|
+
"@types/node": "^25.0.8",
|
|
9
|
+
"@types/react": "^19.2.8",
|
|
10
|
+
"autoprefixer": "^10.4.23",
|
|
11
|
+
"client-only": "^0.0.1",
|
|
12
|
+
"dotenv": "^16.4.5",
|
|
13
|
+
"lucide-react": "^0.562.0",
|
|
14
|
+
"fumadocs-core": "^16.4.7",
|
|
15
|
+
"fumadocs-mdx": "^14.2.5",
|
|
16
|
+
"fumadocs-ui": "^16.4.7",
|
|
17
|
+
"next": "^16.1.2",
|
|
18
|
+
"openai": "^4.0.0",
|
|
19
|
+
"postcss": "^8.5.6",
|
|
20
|
+
"react": "^19.2.3",
|
|
21
|
+
"react-dom": "^19.2.3",
|
|
22
|
+
"remark-directive": "^4.0.0",
|
|
23
|
+
"server-only": "^0.0.1",
|
|
24
|
+
"tailwindcss": "^4.1.18",
|
|
25
|
+
"typescript": "^5.9.3"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"dev": "next dev",
|
|
29
|
+
"build": "next build",
|
|
30
|
+
"start": "next start",
|
|
31
|
+
"lint": "next lint",
|
|
32
|
+
"test": "echo \"No test specified\" && exit 0"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/proxy.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createI18nMiddleware } from 'fumadocs-core/i18n/middleware';
|
|
10
|
+
import { i18n } from '@/lib/i18n';
|
|
11
|
+
import { NextResponse, NextRequest, NextFetchEvent } from 'next/server';
|
|
12
|
+
|
|
13
|
+
// Create fumadocs middleware
|
|
14
|
+
const fumadocsMiddleware = createI18nMiddleware(i18n);
|
|
15
|
+
|
|
16
|
+
export default function proxy(request: NextRequest, event: NextFetchEvent) {
|
|
17
|
+
const path = request.nextUrl.pathname;
|
|
18
|
+
|
|
19
|
+
// Handle root path separately with custom language detection
|
|
20
|
+
if (path === '/') {
|
|
21
|
+
const acceptLanguage = request.headers.get('accept-language') || '';
|
|
22
|
+
|
|
23
|
+
// Simple language detection: check if zh is in Accept-Language
|
|
24
|
+
if (acceptLanguage.toLowerCase().includes('zh')) {
|
|
25
|
+
// Redirect to Chinese docs
|
|
26
|
+
const url = request.nextUrl.clone();
|
|
27
|
+
url.pathname = '/cn/docs';
|
|
28
|
+
return NextResponse.redirect(url);
|
|
29
|
+
} else {
|
|
30
|
+
// Redirect to default language (English)
|
|
31
|
+
const url = request.nextUrl.clone();
|
|
32
|
+
url.pathname = '/en/docs';
|
|
33
|
+
return NextResponse.redirect(url);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// For all other paths, pass through to fumadocs middleware
|
|
38
|
+
return fumadocsMiddleware(request, event);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const config = {
|
|
42
|
+
// Matcher ignoring `/_next/` and `/api/`
|
|
43
|
+
matcher: ['/((?!api|_next/static|_next/image|favicon.ico|logo.svg).*)'],
|
|
44
|
+
};
|
package/public/.gitkeep
ADDED
|
File without changes
|
package/public/logo.svg
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" width="512" height="512">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="logo-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#818cf8" />
|
|
5
|
+
<stop offset="100%" stop-color="#c084fc" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<path d="M12 22.5L2 17.5L12 12.5L22 17.5L12 22.5Z" fill="url(#logo-gradient)" fill-opacity="0.6" />
|
|
9
|
+
<path d="M12 17.5L2 12.5L12 7.5L22 12.5L12 17.5Z" fill="url(#logo-gradient)" fill-opacity="0.8" />
|
|
10
|
+
<path d="M12 12.5L2 7.5L12 2.5L22 7.5L12 12.5Z" fill="url(#logo-gradient)" fill-opacity="1" />
|
|
11
|
+
</svg>
|
package/source.config.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectDocs
|
|
3
|
+
* Copyright (c) 2026-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
|
|
10
|
+
import { siteConfig } from './lib/site-config';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import remarkDirective from 'remark-directive';
|
|
14
|
+
import { remarkDirectiveAdmonition } from 'fumadocs-core/mdx-plugins';
|
|
15
|
+
|
|
16
|
+
function resolveContentDir(dir: string) {
|
|
17
|
+
if (process.env.DOCS_DIR && dir === 'content/docs') return process.env.DOCS_DIR;
|
|
18
|
+
|
|
19
|
+
// Try local first (Root deployment)
|
|
20
|
+
if (fs.existsSync(path.resolve(dir))) return dir;
|
|
21
|
+
|
|
22
|
+
// Try parent (Monorepo/Vercel deployment where CWD is packages/site)
|
|
23
|
+
const parentDir = path.join('../..', dir);
|
|
24
|
+
if (fs.existsSync(path.resolve(parentDir))) return parentDir;
|
|
25
|
+
|
|
26
|
+
return dir;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const docsDir = resolveContentDir('content/docs');
|
|
30
|
+
|
|
31
|
+
export const { docs, meta } = defineDocs({
|
|
32
|
+
dir: docsDir,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default defineConfig({
|
|
36
|
+
mdxOptions: {
|
|
37
|
+
remarkPlugins: [remarkDirective, remarkDirectiveAdmonition],
|
|
38
|
+
rehypeCodeOptions: {
|
|
39
|
+
theme: siteConfig.content.codeBlock.theme,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": [
|
|
4
|
+
"dom",
|
|
5
|
+
"dom.iterable",
|
|
6
|
+
"esnext"
|
|
7
|
+
],
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"module": "esnext",
|
|
14
|
+
"moduleResolution": "bundler",
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"isolatedModules": true,
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
"incremental": true,
|
|
19
|
+
"plugins": [
|
|
20
|
+
{
|
|
21
|
+
"name": "next"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"paths": {
|
|
25
|
+
"@/*": [
|
|
26
|
+
"./*"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"target": "ES2017"
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"next-env.d.ts",
|
|
33
|
+
"**/*.ts",
|
|
34
|
+
"**/*.tsx",
|
|
35
|
+
".next/types/**/*.ts",
|
|
36
|
+
".next/dev/types/**/*.ts",
|
|
37
|
+
"/Users/steedos/Documents/GitHub/docs/packages/site/.next/types/**/*.ts",
|
|
38
|
+
"/Users/steedos/Documents/GitHub/docs/packages/site/.next/dev/types/**/*.ts"
|
|
39
|
+
],
|
|
40
|
+
"exclude": [
|
|
41
|
+
"node_modules"
|
|
42
|
+
]
|
|
43
|
+
}
|