Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions .github/workflows/continuous-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,11 @@ jobs:
# Configure DocumentDB version (can be overridden by repository variables)
echo "DOCUMENTDB_VERSION=${{ vars.DOCUMENTDB_VERSION || 'latest' }}" >> $GITHUB_ENV
echo "MULTI_VERSION=${{ vars.MULTI_VERSION || 'true' }}" >> $GITHUB_ENV
- name: Detect package manager
id: detect-package-manager
run: |
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
echo "manager=yarn" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=yarn" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/package.json" ]; then
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=ci" >> $GITHUB_OUTPUT
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
exit 0
else
echo "Unable to determine package manager"
exit 1
fi
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24
cache: ${{ steps.detect-package-manager.outputs.manager }}
cache: npm
- name: Restore cache
uses: actions/cache@v4
with:
Expand All @@ -83,11 +66,11 @@ jobs:
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
- name: Install dependencies
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
run: npm ci
- name: Build with Next.js
env:
NEXT_BASE_PATH: ${{ github.event.repository.name }}
run: ${{ steps.detect-package-manager.outputs.runner }} next build
run: npm run build
- name: Download DocumentDB packages from latest release
run: .github/scripts/download_packages.sh
- name: Upload artifact
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ yarn-error.log*

# typescript
*.tsbuildinfo
next-env.d.ts
next-env.d.ts

# Built resources
/public/open-graph/**/*
8 changes: 5 additions & 3 deletions app/docs/[section]/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Link from "next/link";
import { notFound } from 'next/navigation';
import { getAllArticlePaths, getArticleByPath } from "../../../services/articleService";
import { getMetadata } from "../../../services/metadataService";
import ComingSoon from "../../../components/ComingSoon";
import Markdown from "../../../components/Markdown";

Expand Down Expand Up @@ -34,10 +35,11 @@ export async function generateMetadata({ params }: PageProps) {
const selectedNavItem = navigation.find((item) => item.link.includes(file));
const pageTitle = frontmatter.title || selectedNavItem?.title || section;

return {
return getMetadata({
title: `${pageTitle} - DocumentDB Documentation`,
description: frontmatter.description || undefined,
};
description: frontmatter.description || `${pageTitle} - DocumentDB Documentation`,
pagePath: `docs/${section}${slug.length ? '/' + slug.join('/') : ''}`
});
}

export default async function ArticlePage({ params }: PageProps) {
Expand Down
3 changes: 2 additions & 1 deletion app/docs/reference/[type]/[category]/[name]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
return getMetadata({
title: `${data?.name || 'Reference'} - DocumentDB MQL Reference`,
description: data?.description || data?.summary || '',
extraKeywords: ['reference', type, category, name]
extraKeywords: ['reference', type, category, name],
pagePath: `docs/reference/${type}/${category}/${name}`
});
}

Expand Down
3 changes: 2 additions & 1 deletion app/docs/reference/[type]/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
return getMetadata({
title: `${title} - DocumentDB MQL Reference`,
description: description || '',
extraKeywords: ['reference', type, category]
extraKeywords: ['reference', type, category],
pagePath: `docs/reference/${type}/${category}`
});
}

Expand Down
9 changes: 5 additions & 4 deletions app/docs/reference/[type]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { getMetadata } from "../../../services/metadataService";
import pluralize from 'pluralize';
import { capitalCase } from 'change-case';

const allowed_types = ['operator', 'command'];
const allowed_types = ['operators', 'commands'];

export const generateStaticParams = async (): Promise<{ type: string }[]> => [
{ type: 'operator' },
{ type: 'command' }
{ type: 'operators' },
{ type: 'commands' }
];

export async function generateMetadata({ params }: { params: Promise<{ type: string }> }) {
Expand All @@ -21,7 +21,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
return getMetadata({
title: `${title} - DocumentDB MQL Reference`,
description: description || '',
extraKeywords: ['reference', type]
extraKeywords: ['reference', type],
pagePath: `docs/reference/${type}`
});
}

Expand Down
10 changes: 5 additions & 5 deletions app/docs/reference/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function ReferenceLayout({
const groupedReferences = getReferencesGroupedByTypeAndCategory();

return (
<div className="min-h-screen bg-neutral-900 relative overflow-hidden">
<div className="min-h-screen bg-neutral-900 relative overflow-hidden max-h-screen">
{/* Background elements */}
<div className="absolute inset-0 bg-gradient-to-br from-neutral-900 via-neutral-800 to-black"></div>
<div className="absolute inset-0 opacity-5">
Expand All @@ -28,9 +28,9 @@ export default function ReferenceLayout({
style={{ animationDelay: "1.5s" }}
></div>
</div>
<div className="relative flex min-h-screen">
<div className="w-80 bg-neutral-800/50 backdrop-blur-sm border-r border-neutral-700/50 flex flex-col">
<div className="p-6 border-b border-neutral-700/50">
<div className="relative flex h-screen">
<div className="w-80 bg-neutral-800/50 backdrop-blur-sm border-r border-neutral-700/50 flex flex-col h-full">
<div className="p-6 border-b border-neutral-700/50 flex-shrink-0">
<Link href="/docs" className="text-blue-400 hover:text-blue-300 text-sm mb-4 flex items-center transition-colors">
<svg
className="w-4 h-4 mr-2"
Expand All @@ -51,7 +51,7 @@ export default function ReferenceLayout({
</div>
<Index groupedReferences={groupedReferences} />
</div>
<article className="flex-1 p-8">
<article className="flex-1 p-8 overflow-y-auto h-full">
<div className="max-w-4xl">
{children}
</div>
Expand Down
183 changes: 183 additions & 0 deletions app/services/contentService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { getAllArticlePaths, getArticleByPath } from './articleService';
import { getAllPosts } from './blogService';
import { getReferencesGroupedByTypeAndCategory, getAllReferenceParams, getReferenceByPath } from './referenceService';
import path from 'path';
import { Entity } from '../types/Entity';

export function getAllContent(): Entity[] {
const pages: Entity[] = [];

// 1. Home page
pages.push({
url: '/',
slug: 'home.png',
title: 'DocumentDB',
description: 'A powerful, scalable open-source document database solution',
type: 'home',
});

// 2. Docs landing
pages.push({
url: '/docs',
slug: 'docs.png',
title: 'Documentation',
description: 'Complete DocumentDB documentation and guides',
section: 'docs',
type: 'landing',
});

// 3. All article/documentation pages
const articlePaths = getAllArticlePaths();
for (const articlePath of articlePaths) {
const article = getArticleByPath(articlePath.section, articlePath.slug);
if (article) {
const selectedNavItem = article.navigation.find((item: any) =>
item.link.includes(articlePath.slug[articlePath.slug.length - 1] || 'index')
);
const title = article.frontmatter.title || selectedNavItem?.title || articlePath.section;

let url = `/docs/${articlePath.section}`;
if (articlePath.slug.length > 0) {
url += `/${articlePath.slug.join('/')}`;
}

const mdFilePath = path.join(
process.cwd(),
'articles',
articlePath.section,
...articlePath.slug,
'index.md'
);

// Convert URL to slug filename
const slug = url === '/'
? 'home.png'
: url.slice(1).replace(/\//g, '-') + '.png';

pages.push({
url,
slug,
title,
description: article.frontmatter.description || `${title} - DocumentDB Documentation`,
section: articlePath.section,
type: 'docs',
filePath: mdFilePath,
});
}
}

// 4. Blogs landing
pages.push({
url: '/blogs',
slug: 'blogs.png',
title: 'Blog',
description: 'Latest insights and updates from DocumentDB',
section: 'blog',
type: 'landing',
});

// 5. Individual blog posts (external URIs)
const posts = getAllPosts();
for (const post of posts) {
// Generate slug from title (for external blog posts without slugs)
const slug = post.title
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');

const url = `/blogs/${slug}`;
const filename = url.slice(1).replace(/\//g, '-') + '.png';

pages.push({
url,
slug: filename,
title: post.title,
description: post.description,
section: 'blog',
type: 'blog',
isExternal: true, // Mark as external since these redirect to external URIs
});
}

// 6. Reference landing page
pages.push({
url: '/docs/reference',
slug: 'docs-reference.png',
title: 'API Reference',
description: 'Complete DocumentDB API reference documentation',
section: 'reference',
type: 'landing',
});

// 7. Reference type pages (e.g., /docs/reference/commands)
const referenceContent = getReferencesGroupedByTypeAndCategory();
for (const [type] of Object.entries(referenceContent)) {
const url = `/docs/reference/${type}`;
const slug = url.slice(1).replace(/\//g, '-') + '.png';

pages.push({
url,
slug,
title: `${type.charAt(0).toUpperCase() + type.slice(1)} Reference`,
description: `DocumentDB ${type} reference documentation`,
section: 'reference',
type: 'landing',
});
}

// 8. Reference category pages (e.g., /docs/reference/operators/aggregation)
for (const [type, categories] of Object.entries(referenceContent)) {
for (const [category] of Object.entries(categories)) {
const url = `/docs/reference/${type}/${category}`;
const slug = url.slice(1).replace(/\//g, '-') + '.png';

pages.push({
url,
slug,
title: `${category} - ${type.charAt(0).toUpperCase() + type.slice(1)}`,
description: `${category} ${type} reference documentation`,
section: 'reference',
type: 'landing',
});
}
}

// 9. Individual reference items
const referenceParams = getAllReferenceParams();
for (const param of referenceParams) {
const reference = getReferenceByPath(param.type, param.category, param.name);
if (reference) {
const url = `/docs/reference/${param.type}/${param.category}/${param.name}`;
const slug = url.slice(1).replace(/\//g, '-') + '.png';

const mdFilePath = path.join(
process.cwd(),
'reference',
param.type,
param.category,
`${param.name}.yml`
);

pages.push({
url,
slug,
title: reference.name || param.name,
description: reference.description || `${param.name} - DocumentDB Reference`,
section: 'reference',
type: 'reference',
filePath: mdFilePath,
});
}
}

// 10. Packages page
pages.push({
url: '/packages',
slug: 'packages.png',
title: 'Packages',
description: 'Download and install DocumentDB packages',
type: 'packages',
});

return pages;
}
Loading