diff --git a/docs/package.json b/docs/package.json
index 4919faf..81898ab 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -1,16 +1,17 @@
{
"name": "akiradocs",
- "version": "1.0.46",
+ "version": "1.0.47",
"private": true,
"scripts": {
"translate": "npm run compile && node scripts/translate.js",
- "compile": "node scripts/compile.js",
+ "compile": "node scripts/compile.js && npm run generate-manifest",
"generate-sitemap": "node scripts/generate-sitemap.mjs",
"dev": "npm run compile && set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=true && next dev",
"build": "npm run compile && npm run generate-sitemap && set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=false && next build",
"start": "set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=false && next start",
"lint": "next lint",
- "migrate-gitbook": "node scripts/migrations/gitbook.js"
+ "migrate-gitbook": "node scripts/migrations/gitbook.js",
+ "generate-manifest": "node scripts/generate-manifest.js"
},
"dependencies": {
"@ai-sdk/anthropic": "^1.0.1",
diff --git a/docs/scripts/generate-manifest.js b/docs/scripts/generate-manifest.js
new file mode 100644
index 0000000..f88bc92
--- /dev/null
+++ b/docs/scripts/generate-manifest.js
@@ -0,0 +1,28 @@
+const fs = require('fs');
+const path = require('path');
+
+function getAllFiles(dirPath, arrayOfFiles = []) {
+ const files = fs.readdirSync(dirPath);
+
+ files.forEach(file => {
+ const fullPath = path.join(dirPath, file);
+ if (fs.statSync(fullPath).isDirectory()) {
+ getAllFiles(fullPath, arrayOfFiles);
+ } else {
+ arrayOfFiles.push(
+ fullPath.replace(path.join(process.cwd(), 'compiled/'), '')
+ );
+ }
+ });
+
+ return arrayOfFiles;
+}
+
+const manifest = {
+ files: getAllFiles(path.join(process.cwd(), 'compiled'))
+};
+
+fs.writeFileSync(
+ path.join(process.cwd(), 'compiled/manifest.json'),
+ JSON.stringify(manifest, null, 2)
+);
\ No newline at end of file
diff --git a/docs/src/app/[locale]/[type]/[...slug]/page.tsx b/docs/src/app/[locale]/[type]/[...slug]/page.tsx
index db4fce9..4111dac 100644
--- a/docs/src/app/[locale]/[type]/[...slug]/page.tsx
+++ b/docs/src/app/[locale]/[type]/[...slug]/page.tsx
@@ -13,14 +13,13 @@ import { PageNavigation } from '@/components/layout/PageNavigation'
import { MainTitle, SubTitle } from '@/components/blocks/HeadingBlock'
import { SEO } from '@/components/layout/SEO'
import { NotFound } from '@/components/layout/NotFound'
-import { TextToSpeech } from '@/components/tts/TextToSpeech'
import { getAkiradocsConfig } from "@/lib/getAkiradocsConfig";
import { getTranslation } from '@/lib/staticTranslation';
import { ClientSideControls } from '@/components/layout/ClientSideControl';
import { Metadata } from 'next'
-// export const runtime = 'edge'
-export const dynamic = 'force-static';
+export const runtime = 'edge'
+// export const dynamic = 'force-static';
const PostContainer = ({ children }: { children: React.ReactNode }) => (
@@ -36,33 +35,33 @@ type Props = {
}>;
}
-export async function generateStaticParams() {
- const locales = ['en', 'es', 'fr'];
- const types = ['docs', 'api', 'articles'];
- const allSlugs: { locale: string, type: string, slug: string[] }[] = [];
+// export async function generateStaticParams() {
+// const locales = ['en', 'es', 'fr'];
+// const types = ['docs', 'api', 'articles'];
+// const allSlugs: { locale: string, type: string, slug: string[] }[] = [];
- locales.forEach(locale => {
- types.forEach(type => {
- const navigationItems = getContentNavigation({}, locale, type);
- if (Array.isArray(navigationItems)) {
- navigationItems.forEach(item => {
- if (item.slug) {
- allSlugs.push({ locale, type, slug: item.slug.split('/') });
- }
- });
- }
- });
- });
+// locales.forEach(locale => {
+// types.forEach(type => {
+// const navigationItems = getContentNavigation({}, locale, type);
+// if (Array.isArray(navigationItems)) {
+// navigationItems.forEach(item => {
+// if (item.slug) {
+// allSlugs.push({ locale, type, slug: item.slug.split('/') });
+// }
+// });
+// }
+// });
+// });
- return allSlugs;
-}
+// return allSlugs;
+// }
export async function generateMetadata({ params }: Props): Promise
{
const resolvedParams = await Promise.resolve(params);
const { locale, type, slug: slugArray } = resolvedParams;
const slug = slugArray.length ? slugArray.join('/') : '';
- const post = getContentBySlug(locale, type, slug);
+ const post = await getContentBySlug(locale, type, slug);
const t = getTranslation(locale as 'en' | 'es' | 'fr');
const akiradocsConfig = getAkiradocsConfig();
@@ -94,15 +93,14 @@ export default async function ContentPage({ params }: Props) {
const t = getTranslation(locale as 'en' | 'es' | 'de');
const slug = slugArray.length ? slugArray.join('/') : '';
- const post = getContentBySlug(locale, type, slug);
-
+ const post = await getContentBySlug(locale, type, slug);
if (!post) {
return ;
}
const akiradocsConfig = getAkiradocsConfig();
const headerConfig = getHeaderConfig();
const footerConfig = getFooterConfig();
- const navigationItems = getContentNavigation({}, locale, type);
+ const navigationItems = await getContentNavigation({}, locale, type);
const { prev, next } = getNextPrevPages(navigationItems, `/${type}/${slug}`);
const pageTitle = t(post.title) || t('common.documentation');
const pageDescription = t(post.description) || t('common.documentationContent');
diff --git a/docs/src/app/[locale]/[type]/page.tsx b/docs/src/app/[locale]/[type]/page.tsx
index 1b964cc..0b15df0 100644
--- a/docs/src/app/[locale]/[type]/page.tsx
+++ b/docs/src/app/[locale]/[type]/page.tsx
@@ -49,18 +49,33 @@ export async function generateMetadata({ params }: Props): Promise {
}
}
+function formatRedirectUrl(locale: string, type: string, slug: string): string {
+ // Remove leading/trailing slashes
+ const cleanSlug = slug.replace(/^\/+|\/+$/g, '');
+
+ // Check if slug already contains locale and/or type
+ const parts = cleanSlug.split('/');
+ const slugWithoutLocaleAndType = parts
+ .filter(part => part !== locale && part !== type)
+ .join('/');
+
+ return `/${locale}/${type}/${slugWithoutLocaleAndType}`;
+}
+
export default async function Page({ params }: Props) {
const resolvedParams = await Promise.resolve(params);
const { locale, type } = resolvedParams;
// Get the first/default content for this type
- const recentContent = getRecentContent(`${locale}/${type}`);
+ const recentContent = await getRecentContent(`${locale}/${type}`);
if (recentContent) {
- const redirectUrl = `/${locale}/${type}/${recentContent.slug.replace(`${type}/`, '')}`;
+ const redirectUrl = formatRedirectUrl(locale, type, recentContent.slug);
redirect(redirectUrl);
}
// Fallback redirect if no content found
+ console.log("redirecting to", `/${locale}`);
redirect(`/${locale}`);
}
+
diff --git a/docs/src/app/page.tsx b/docs/src/app/page.tsx
index f91a87e..ce277e7 100644
--- a/docs/src/app/page.tsx
+++ b/docs/src/app/page.tsx
@@ -19,7 +19,7 @@ export async function generateMetadata() {
export default async function DocPage() {
const config = getAkiradocsConfig()
const defaultLocale = config.localization.defaultLocale
- const recentContent = getRecentContent(`${defaultLocale}/docs`)
+ const recentContent = await getRecentContent(`${defaultLocale}/docs`)
if (recentContent) {
const redirectUrl = `/${defaultLocale}/docs/${recentContent.slug.replace('docs/', '')}`
diff --git a/docs/src/components/layout/Navigation.tsx b/docs/src/components/layout/Navigation.tsx
index adecb05..5214cd3 100644
--- a/docs/src/components/layout/Navigation.tsx
+++ b/docs/src/components/layout/Navigation.tsx
@@ -133,8 +133,8 @@ const NavItem = React.memo(({ locale, item, pathname, depth = 0 }: NavItemProps)
NavItem.displayName = 'NavItem'
-export function ApiSidebar() {
- const navigation = getApiNavigation();
+export async function ApiSidebar() {
+ const navigation = await getApiNavigation();
return (
diff --git a/docs/src/lib/content.ts b/docs/src/lib/content.ts
index d44e357..65c14f2 100644
--- a/docs/src/lib/content.ts
+++ b/docs/src/lib/content.ts
@@ -1,26 +1,23 @@
import { Post } from '@/types/Block'
-declare var require: {
- context(
- directory: string,
- useSubdirectories: boolean,
- regExp: RegExp
- ): any;
-};
-const contentContext = require.context(`../../compiled/`, true, /\.json$/)
-export function getContentBySlug(locale: string, type: string, slug: string): Post | null {
+// Create a function to get the JSON path
+async function getJsonContent(path: string) {
try {
- // Construct the exact path we're looking for
- const filePath = `./${locale}/${type}/${slug}.json`;
-
- // Check if the file exists in our context
- if (!contentContext.keys().includes(filePath)) {
- console.warn(`File not found: ${filePath}`);
- return null;
- }
+ // Dynamic import for JSON files
+ console.log(path)
+ const content = await import(`../../compiled/${path}`);
+ return content.default;
+ } catch (error) {
+ console.error(`Error loading content for ${path}:`, error);
+ return null;
+ }
+}
- // Load the content
- const content = contentContext(filePath);
+export async function getContentBySlug(locale: string, type: string, slug: string): Promise {
+ try {
+ const content = await getJsonContent(`${locale}/${type}/${slug}.json`);
+ if (!content) return null;
+
return {
...content,
slug
@@ -31,55 +28,40 @@ export function getContentBySlug(locale: string, type: string, slug: string): Po
}
}
-export function getAllPosts(locale: string, type: string): Post[] {
- const posts = contentContext.keys()
- .filter((fileName: string) => {
- // Only include files that match the exact locale and type path
- const pattern = new RegExp(`^\./${locale}/${type}/[^/]+\.json$`);
- return pattern.test(fileName) && !fileName.endsWith('/_meta.json');
- })
- .map((fileName: string) => {
- try {
- // Load the content directly using the full path
- const content = contentContext(fileName);
+export async function getAllPosts(locale: string, type: string): Promise {
+ // You'll need to maintain a manifest file that lists all available content
+ // For example, create a manifest.json in your compiled directory
+ const manifest = await import('../../compiled/manifest.json');
+
+ const posts = await Promise.all(
+ manifest.files
+ .filter((fileName: string) => {
+ const pattern = new RegExp(`^${locale}/${type}/[^/]+\.json$`);
+ return pattern.test(fileName) && !fileName.endsWith('/_meta.json');
+ })
+ .map(async (fileName: string) => {
+ const content = await getJsonContent(fileName);
+ if (!content) return null;
+
const slug = fileName
- .replace(`\./${locale}/${type}/`, '')
+ .replace(`${locale}/${type}/`, '')
.replace(/\.json$/, '');
+
return {
...content,
slug
};
- } catch (error) {
- console.error(`Error loading content for ${fileName}:`, error);
- return null;
- }
- })
- .filter((post: unknown): post is Post => post !== null);
+ })
+ );
- return posts;
+ return posts.filter((post): post is Post => post !== null);
}
-export function getContentNavigation(defaultValue: T, locale: string, type: string): T {
+export async function getContentNavigation(defaultValue: T, locale: string, type: string): Promise {
try {
- const navigationFile = `./${locale}/${type}/_meta.json`
- const navigation = contentContext(navigationFile) as T
-
- if (type === 'articles') {
- // Get all articles and their content
- const articles = contentContext.keys()
- .filter((key: string) => key.startsWith(`./${locale}/${type}/`) && !key.endsWith('/_meta.json'))
- .map((key: string) => ({
- path: key.replace(`./${locale}/${type}/`, '').replace('.json', ''),
- content: contentContext(key)
- }))
- .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
-
- // Assuming navigation is an object with a routes property
- return {
- ...navigation
- } as T
- }
-
+ const navigationFile = `${locale}/${type}/_meta.json`
+ const navigation = await getJsonContent(navigationFile)
+ console.log(navigation)
return navigation
} catch (error) {
console.warn(`Failed to read ${type} _meta.json file. Using default value.`)
@@ -87,54 +69,52 @@ export function getContentNavigation(defaultValue: T, locale: string, type: s
}
}
-export function getRecentContent(folderPath: string) {
+export async function getRecentContent(folderPath: string) {
try {
// For non-article paths, get default route from _meta.json
- if (!folderPath.includes('/articles/')) {
- const metaContent = contentContext(`./${folderPath}/_meta.json`)
+ // if (!folderPath.includes('/articles/')) {
+ const metaContent = await getJsonContent(`${folderPath}/_meta.json`)
if (metaContent?.defaultRoute) {
return {
slug: metaContent.defaultRoute
}
}
- }
-
- // Existing logic for articles
- const files = contentContext.keys()
- .filter((key: string) => key.startsWith(`./${folderPath}/`) && key.endsWith('.json') && !key.endsWith('/_meta.json'))
-
- if (files.length === 0) {
- return null
- }
-
- // Sort files by their content's date field
- const sortedFiles = files
- .map((file: string) => ({
- name: file,
- content: contentContext(file)
- }))
- .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
-
- return {
- slug: sortedFiles[0].name.replace(`./${folderPath}/`, '').replace('.json', '')
- }
+ // }
+
+ // // Existing logic for articles
+ // const metaContent = await getJsonContent(`${folderPath}/_meta.json`)
+ // const files = metaContent?.filter((key: string) =>
+ // key.startsWith(`./${folderPath}/`) &&
+ // key.endsWith('.json') &&
+ // !key.endsWith('/_meta.json')
+ // )
+
+ // if (!files || files.length === 0) {
+ // return null
+ // }
+
+ // // Sort files by their content's date field
+ // const sortedFiles = await Promise.all(
+ // files
+ // .map(async (file: string) => ({
+ // name: file,
+ // content: await getJsonContent(file)
+ // }))
+ // .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
+ // )
+ // console.log("sortedFiles", sortedFiles)
+ // return {
+ // slug: sortedFiles[0].name.replace(`./${folderPath}/`, '').replace('.json', '')
+ // }
} catch (error) {
console.error('Error finding recent article:', error)
return null
}
}
-export function folderExists(folderPath: string): boolean {
- try {
- return contentContext.keys().some((key: string) => key.startsWith(`./${folderPath}/`))
- } catch (error) {
- console.error('Error checking folder existence:', error)
- return false
- }
-}
-export function get_api_spec(): any {
+export async function get_api_spec(): Promise {
try {
- return contentContext('./en/api/apiSpec.json')
+ return await getJsonContent('en/api/apiSpec.json')
} catch (error) {
console.error('Error reading API spec file:', error)
return null
@@ -148,9 +128,10 @@ interface ApiNavItem {
children?: ApiNavItem[];
}
-export function getApiNavigation(): ApiNavItem[] {
+export async function getApiNavigation(): Promise {
try {
- const apiSpec = get_api_spec();
+ const apiSpec = await get_api_spec();
+ console.log("apiSpec", apiSpec)
if (!apiSpec || !apiSpec.paths) {
return [];
}
diff --git a/packages/akiradocs/package.json b/packages/akiradocs/package.json
index 0c6f5fc..a391fc2 100644
--- a/packages/akiradocs/package.json
+++ b/packages/akiradocs/package.json
@@ -4,13 +4,14 @@
"private": true,
"scripts": {
"translate": "npm run compile && node scripts/translate.js",
- "compile": "node scripts/compile.js",
+ "compile": "node scripts/compile.js && npm run generate-manifest",
"generate-sitemap": "node scripts/generate-sitemap.mjs",
"dev": "npm run compile && set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=true && next dev",
"build": "npm run compile && npm run generate-sitemap && set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=false && next build",
"start": "set NEXT_PUBLIC_AKIRADOCS_EDIT_MODE=false && next start",
"lint": "next lint",
- "migrate-gitbook": "node scripts/migrations/gitbook.js"
+ "migrate-gitbook": "node scripts/migrations/gitbook.js",
+ "generate-manifest": "node scripts/generate-manifest.js"
},
"dependencies": {
"@ai-sdk/anthropic": "^1.0.1",
diff --git a/packages/akiradocs/scripts/generate-manifest.js b/packages/akiradocs/scripts/generate-manifest.js
new file mode 100644
index 0000000..f88bc92
--- /dev/null
+++ b/packages/akiradocs/scripts/generate-manifest.js
@@ -0,0 +1,28 @@
+const fs = require('fs');
+const path = require('path');
+
+function getAllFiles(dirPath, arrayOfFiles = []) {
+ const files = fs.readdirSync(dirPath);
+
+ files.forEach(file => {
+ const fullPath = path.join(dirPath, file);
+ if (fs.statSync(fullPath).isDirectory()) {
+ getAllFiles(fullPath, arrayOfFiles);
+ } else {
+ arrayOfFiles.push(
+ fullPath.replace(path.join(process.cwd(), 'compiled/'), '')
+ );
+ }
+ });
+
+ return arrayOfFiles;
+}
+
+const manifest = {
+ files: getAllFiles(path.join(process.cwd(), 'compiled'))
+};
+
+fs.writeFileSync(
+ path.join(process.cwd(), 'compiled/manifest.json'),
+ JSON.stringify(manifest, null, 2)
+);
\ No newline at end of file
diff --git a/packages/akiradocs/src/app/[locale]/[type]/[...slug]/page.tsx b/packages/akiradocs/src/app/[locale]/[type]/[...slug]/page.tsx
index db4fce9..4111dac 100644
--- a/packages/akiradocs/src/app/[locale]/[type]/[...slug]/page.tsx
+++ b/packages/akiradocs/src/app/[locale]/[type]/[...slug]/page.tsx
@@ -13,14 +13,13 @@ import { PageNavigation } from '@/components/layout/PageNavigation'
import { MainTitle, SubTitle } from '@/components/blocks/HeadingBlock'
import { SEO } from '@/components/layout/SEO'
import { NotFound } from '@/components/layout/NotFound'
-import { TextToSpeech } from '@/components/tts/TextToSpeech'
import { getAkiradocsConfig } from "@/lib/getAkiradocsConfig";
import { getTranslation } from '@/lib/staticTranslation';
import { ClientSideControls } from '@/components/layout/ClientSideControl';
import { Metadata } from 'next'
-// export const runtime = 'edge'
-export const dynamic = 'force-static';
+export const runtime = 'edge'
+// export const dynamic = 'force-static';
const PostContainer = ({ children }: { children: React.ReactNode }) => (
@@ -36,33 +35,33 @@ type Props = {
}>;
}
-export async function generateStaticParams() {
- const locales = ['en', 'es', 'fr'];
- const types = ['docs', 'api', 'articles'];
- const allSlugs: { locale: string, type: string, slug: string[] }[] = [];
+// export async function generateStaticParams() {
+// const locales = ['en', 'es', 'fr'];
+// const types = ['docs', 'api', 'articles'];
+// const allSlugs: { locale: string, type: string, slug: string[] }[] = [];
- locales.forEach(locale => {
- types.forEach(type => {
- const navigationItems = getContentNavigation({}, locale, type);
- if (Array.isArray(navigationItems)) {
- navigationItems.forEach(item => {
- if (item.slug) {
- allSlugs.push({ locale, type, slug: item.slug.split('/') });
- }
- });
- }
- });
- });
+// locales.forEach(locale => {
+// types.forEach(type => {
+// const navigationItems = getContentNavigation({}, locale, type);
+// if (Array.isArray(navigationItems)) {
+// navigationItems.forEach(item => {
+// if (item.slug) {
+// allSlugs.push({ locale, type, slug: item.slug.split('/') });
+// }
+// });
+// }
+// });
+// });
- return allSlugs;
-}
+// return allSlugs;
+// }
export async function generateMetadata({ params }: Props): Promise
{
const resolvedParams = await Promise.resolve(params);
const { locale, type, slug: slugArray } = resolvedParams;
const slug = slugArray.length ? slugArray.join('/') : '';
- const post = getContentBySlug(locale, type, slug);
+ const post = await getContentBySlug(locale, type, slug);
const t = getTranslation(locale as 'en' | 'es' | 'fr');
const akiradocsConfig = getAkiradocsConfig();
@@ -94,15 +93,14 @@ export default async function ContentPage({ params }: Props) {
const t = getTranslation(locale as 'en' | 'es' | 'de');
const slug = slugArray.length ? slugArray.join('/') : '';
- const post = getContentBySlug(locale, type, slug);
-
+ const post = await getContentBySlug(locale, type, slug);
if (!post) {
return ;
}
const akiradocsConfig = getAkiradocsConfig();
const headerConfig = getHeaderConfig();
const footerConfig = getFooterConfig();
- const navigationItems = getContentNavigation({}, locale, type);
+ const navigationItems = await getContentNavigation({}, locale, type);
const { prev, next } = getNextPrevPages(navigationItems, `/${type}/${slug}`);
const pageTitle = t(post.title) || t('common.documentation');
const pageDescription = t(post.description) || t('common.documentationContent');
diff --git a/packages/akiradocs/src/app/[locale]/[type]/page.tsx b/packages/akiradocs/src/app/[locale]/[type]/page.tsx
index 1b964cc..0b15df0 100644
--- a/packages/akiradocs/src/app/[locale]/[type]/page.tsx
+++ b/packages/akiradocs/src/app/[locale]/[type]/page.tsx
@@ -49,18 +49,33 @@ export async function generateMetadata({ params }: Props): Promise {
}
}
+function formatRedirectUrl(locale: string, type: string, slug: string): string {
+ // Remove leading/trailing slashes
+ const cleanSlug = slug.replace(/^\/+|\/+$/g, '');
+
+ // Check if slug already contains locale and/or type
+ const parts = cleanSlug.split('/');
+ const slugWithoutLocaleAndType = parts
+ .filter(part => part !== locale && part !== type)
+ .join('/');
+
+ return `/${locale}/${type}/${slugWithoutLocaleAndType}`;
+}
+
export default async function Page({ params }: Props) {
const resolvedParams = await Promise.resolve(params);
const { locale, type } = resolvedParams;
// Get the first/default content for this type
- const recentContent = getRecentContent(`${locale}/${type}`);
+ const recentContent = await getRecentContent(`${locale}/${type}`);
if (recentContent) {
- const redirectUrl = `/${locale}/${type}/${recentContent.slug.replace(`${type}/`, '')}`;
+ const redirectUrl = formatRedirectUrl(locale, type, recentContent.slug);
redirect(redirectUrl);
}
// Fallback redirect if no content found
+ console.log("redirecting to", `/${locale}`);
redirect(`/${locale}`);
}
+
diff --git a/packages/akiradocs/src/app/page.tsx b/packages/akiradocs/src/app/page.tsx
index f91a87e..ce277e7 100644
--- a/packages/akiradocs/src/app/page.tsx
+++ b/packages/akiradocs/src/app/page.tsx
@@ -19,7 +19,7 @@ export async function generateMetadata() {
export default async function DocPage() {
const config = getAkiradocsConfig()
const defaultLocale = config.localization.defaultLocale
- const recentContent = getRecentContent(`${defaultLocale}/docs`)
+ const recentContent = await getRecentContent(`${defaultLocale}/docs`)
if (recentContent) {
const redirectUrl = `/${defaultLocale}/docs/${recentContent.slug.replace('docs/', '')}`
diff --git a/packages/akiradocs/src/components/layout/Navigation.tsx b/packages/akiradocs/src/components/layout/Navigation.tsx
index adecb05..5214cd3 100644
--- a/packages/akiradocs/src/components/layout/Navigation.tsx
+++ b/packages/akiradocs/src/components/layout/Navigation.tsx
@@ -133,8 +133,8 @@ const NavItem = React.memo(({ locale, item, pathname, depth = 0 }: NavItemProps)
NavItem.displayName = 'NavItem'
-export function ApiSidebar() {
- const navigation = getApiNavigation();
+export async function ApiSidebar() {
+ const navigation = await getApiNavigation();
return (
diff --git a/packages/akiradocs/src/lib/content.ts b/packages/akiradocs/src/lib/content.ts
index d44e357..65c14f2 100644
--- a/packages/akiradocs/src/lib/content.ts
+++ b/packages/akiradocs/src/lib/content.ts
@@ -1,26 +1,23 @@
import { Post } from '@/types/Block'
-declare var require: {
- context(
- directory: string,
- useSubdirectories: boolean,
- regExp: RegExp
- ): any;
-};
-const contentContext = require.context(`../../compiled/`, true, /\.json$/)
-export function getContentBySlug(locale: string, type: string, slug: string): Post | null {
+// Create a function to get the JSON path
+async function getJsonContent(path: string) {
try {
- // Construct the exact path we're looking for
- const filePath = `./${locale}/${type}/${slug}.json`;
-
- // Check if the file exists in our context
- if (!contentContext.keys().includes(filePath)) {
- console.warn(`File not found: ${filePath}`);
- return null;
- }
+ // Dynamic import for JSON files
+ console.log(path)
+ const content = await import(`../../compiled/${path}`);
+ return content.default;
+ } catch (error) {
+ console.error(`Error loading content for ${path}:`, error);
+ return null;
+ }
+}
- // Load the content
- const content = contentContext(filePath);
+export async function getContentBySlug(locale: string, type: string, slug: string): Promise {
+ try {
+ const content = await getJsonContent(`${locale}/${type}/${slug}.json`);
+ if (!content) return null;
+
return {
...content,
slug
@@ -31,55 +28,40 @@ export function getContentBySlug(locale: string, type: string, slug: string): Po
}
}
-export function getAllPosts(locale: string, type: string): Post[] {
- const posts = contentContext.keys()
- .filter((fileName: string) => {
- // Only include files that match the exact locale and type path
- const pattern = new RegExp(`^\./${locale}/${type}/[^/]+\.json$`);
- return pattern.test(fileName) && !fileName.endsWith('/_meta.json');
- })
- .map((fileName: string) => {
- try {
- // Load the content directly using the full path
- const content = contentContext(fileName);
+export async function getAllPosts(locale: string, type: string): Promise {
+ // You'll need to maintain a manifest file that lists all available content
+ // For example, create a manifest.json in your compiled directory
+ const manifest = await import('../../compiled/manifest.json');
+
+ const posts = await Promise.all(
+ manifest.files
+ .filter((fileName: string) => {
+ const pattern = new RegExp(`^${locale}/${type}/[^/]+\.json$`);
+ return pattern.test(fileName) && !fileName.endsWith('/_meta.json');
+ })
+ .map(async (fileName: string) => {
+ const content = await getJsonContent(fileName);
+ if (!content) return null;
+
const slug = fileName
- .replace(`\./${locale}/${type}/`, '')
+ .replace(`${locale}/${type}/`, '')
.replace(/\.json$/, '');
+
return {
...content,
slug
};
- } catch (error) {
- console.error(`Error loading content for ${fileName}:`, error);
- return null;
- }
- })
- .filter((post: unknown): post is Post => post !== null);
+ })
+ );
- return posts;
+ return posts.filter((post): post is Post => post !== null);
}
-export function getContentNavigation(defaultValue: T, locale: string, type: string): T {
+export async function getContentNavigation(defaultValue: T, locale: string, type: string): Promise {
try {
- const navigationFile = `./${locale}/${type}/_meta.json`
- const navigation = contentContext(navigationFile) as T
-
- if (type === 'articles') {
- // Get all articles and their content
- const articles = contentContext.keys()
- .filter((key: string) => key.startsWith(`./${locale}/${type}/`) && !key.endsWith('/_meta.json'))
- .map((key: string) => ({
- path: key.replace(`./${locale}/${type}/`, '').replace('.json', ''),
- content: contentContext(key)
- }))
- .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
-
- // Assuming navigation is an object with a routes property
- return {
- ...navigation
- } as T
- }
-
+ const navigationFile = `${locale}/${type}/_meta.json`
+ const navigation = await getJsonContent(navigationFile)
+ console.log(navigation)
return navigation
} catch (error) {
console.warn(`Failed to read ${type} _meta.json file. Using default value.`)
@@ -87,54 +69,52 @@ export function getContentNavigation(defaultValue: T, locale: string, type: s
}
}
-export function getRecentContent(folderPath: string) {
+export async function getRecentContent(folderPath: string) {
try {
// For non-article paths, get default route from _meta.json
- if (!folderPath.includes('/articles/')) {
- const metaContent = contentContext(`./${folderPath}/_meta.json`)
+ // if (!folderPath.includes('/articles/')) {
+ const metaContent = await getJsonContent(`${folderPath}/_meta.json`)
if (metaContent?.defaultRoute) {
return {
slug: metaContent.defaultRoute
}
}
- }
-
- // Existing logic for articles
- const files = contentContext.keys()
- .filter((key: string) => key.startsWith(`./${folderPath}/`) && key.endsWith('.json') && !key.endsWith('/_meta.json'))
-
- if (files.length === 0) {
- return null
- }
-
- // Sort files by their content's date field
- const sortedFiles = files
- .map((file: string) => ({
- name: file,
- content: contentContext(file)
- }))
- .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
-
- return {
- slug: sortedFiles[0].name.replace(`./${folderPath}/`, '').replace('.json', '')
- }
+ // }
+
+ // // Existing logic for articles
+ // const metaContent = await getJsonContent(`${folderPath}/_meta.json`)
+ // const files = metaContent?.filter((key: string) =>
+ // key.startsWith(`./${folderPath}/`) &&
+ // key.endsWith('.json') &&
+ // !key.endsWith('/_meta.json')
+ // )
+
+ // if (!files || files.length === 0) {
+ // return null
+ // }
+
+ // // Sort files by their content's date field
+ // const sortedFiles = await Promise.all(
+ // files
+ // .map(async (file: string) => ({
+ // name: file,
+ // content: await getJsonContent(file)
+ // }))
+ // .sort((a: any, b: any) => new Date(b.content.date).getTime() - new Date(a.content.date).getTime())
+ // )
+ // console.log("sortedFiles", sortedFiles)
+ // return {
+ // slug: sortedFiles[0].name.replace(`./${folderPath}/`, '').replace('.json', '')
+ // }
} catch (error) {
console.error('Error finding recent article:', error)
return null
}
}
-export function folderExists(folderPath: string): boolean {
- try {
- return contentContext.keys().some((key: string) => key.startsWith(`./${folderPath}/`))
- } catch (error) {
- console.error('Error checking folder existence:', error)
- return false
- }
-}
-export function get_api_spec(): any {
+export async function get_api_spec(): Promise {
try {
- return contentContext('./en/api/apiSpec.json')
+ return await getJsonContent('en/api/apiSpec.json')
} catch (error) {
console.error('Error reading API spec file:', error)
return null
@@ -148,9 +128,10 @@ interface ApiNavItem {
children?: ApiNavItem[];
}
-export function getApiNavigation(): ApiNavItem[] {
+export async function getApiNavigation(): Promise {
try {
- const apiSpec = get_api_spec();
+ const apiSpec = await get_api_spec();
+ console.log("apiSpec", apiSpec)
if (!apiSpec || !apiSpec.paths) {
return [];
}
diff --git a/packages/akiradocs/src/lib/getContents.ts b/packages/akiradocs/src/lib/getContents.ts
deleted file mode 100644
index f4534c5..0000000
--- a/packages/akiradocs/src/lib/getContents.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { getAkiradocsConfig } from "./getAkiradocsConfig";
-const config = getAkiradocsConfig();
-declare var require: {
- context(
- directory: string,
- useSubdirectories: boolean,
- regExp: RegExp
- ): any;
-};
-const contentContext = require.context(
- `../../compiled/`,
- true, // Include subdirectories
- /^\.\/.*\.json$/ // Update this regex to be more specific
-);
-
-export function fetchAllContent() {
- const content: { [key: string]: any } = {};
-
- contentContext.keys().forEach((key: string) => {
- const fileName = key.replace(/^\.\//, '');
- const fileContent = contentContext(key);
- content[fileName] = fileContent;
- });
-
- return content;
-}
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index caf1ad8..0d2f666 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-akiradocs",
- "version": "1.0.46",
+ "version": "1.0.47",
"description": "Create Akira Docs documentation sites with one command",
"main": "./dist/index.js",
"type": "module",