Skip to content
Merged
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
42 changes: 36 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,35 @@ This repository contains two main projects:
#### Backend

```bash
cd Server
cd Source/SuperOffice.DocsNext
dotnet restore
```

Frontend
```bash
cd ClientApp
cd Source/SuperOffice.DocsNext/ClientApp
npm install
```

### 3. Run Development Servers
### 3. Clone external repos

You can either
1. Manually clone or copy files of `SuperOfficeDocs/superoffice-docs` and `SuperOfficeDocs/contribution` repos into `ClientApp/src/external-content`

2. Use following script to clone or update the required external GitHub repositories into the `ClientApp/src/external-content/` directory.
If a repository folder already exists, script will fetch and reset it to the latest commit on the `main` branch.

```bash
cd Source/SuperOffice.DocsNext/ClientApp/build
node setup-external-repos.js
```


### 4. Run Development Servers

#### Backend (with API and proxy to frontend)

From docs-next/Server:
From docs-next/Source/SuperOffice.DocsNext:
```bash
dotnet run
```
Expand All @@ -49,7 +63,7 @@ By default API runs at: http://localhost:5215/api. Any non-API request is proxie

#### Frontend (Astro dev server)

From docs-next/ClientApp:
From docs-next/Source/SuperOffice.DocsNext/ClientApp:

```bash
npm run dev
Expand All @@ -61,7 +75,15 @@ By default Frontend dev server runs at: http://localhost:4321. The backend proxi

Any other path → served by Astro dev server.

### 4. Run Production Build
##### Reduce content during development (dev:partial)

To manage the content during development, npm command to run dev server with reduced content was introduced. This is useful when you only need to run the development server without the content from superoffice-docs. It uses a pre-defined enviornment variable (PARTIAL_BUILD) to disable content collections from rendering.

```bash
npm run dev:partial
```

### 5. Run Production Build

1. Build Backend (includes frontend)

Expand All @@ -81,6 +103,14 @@ dotnet docs-next.dll
API: https://localhost:5001/api/...
Frontend: served from wwwroot

#### Partial frontend build (build:partial)

To reduce build time when testing a build, npm command to do partial builds was introduced. This is useful when you only need to build the frontend without the content from superoffice-docs. It uses a pre-defined enviornment variable (PARTIAL_BUILD) to disable content collections from building.

```bash
npm run build:partial
```

### Notes
In development, run both servers:

Expand Down
14 changes: 4 additions & 10 deletions Source/SuperOffice.DocsNext/ClientApp/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,22 @@ import icon from "astro-icon";
import remarkDirective from "remark-directive";
import codeImport from "remark-code-import";
import mdx from "@astrojs/mdx";
// import preact from "@astrojs/preact";
import robots from "astro-robots";
import sitemap from "@astrojs/sitemap";
import pagefind from "astro-pagefind";
import { rehypeHeadingIds } from "@astrojs/markdown-remark";
//import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from "rehype-autolink-headings";
// import rehypeSanitize from "rehype-sanitize";
import remarkIncludeDirective from "./src/plugins/AddIncludesToMarkdown.js";
import remarkRestyleDirective from "./src/plugins/RestyleDirectives.js";
import react from "@astrojs/react";
import yaml from '@rollup/plugin-yaml';
import redirectFrom from "astro-redirect-from";
import { getRedirectFromSlug } from './src/utils/slugUtils.ts';

const apiOnly = process.env.API_ONLY === 'true';

export default defineConfig({
// Conditionally exclude static landing page
pages: [
'src/pages/**/*',
...(apiOnly ? ['!src/pages/contribute/index.astro'] : []),
'src/pages/**/*'
],

markdown: {
Expand All @@ -39,7 +33,6 @@ export default defineConfig({
},
],
],
// rehypeSanitize, rehypeSlug
shikiConfig: {
theme: "houston",
wrap: true,
Expand Down Expand Up @@ -96,13 +89,14 @@ export default defineConfig({
},
}),
mdx(),
// pagefind(),
pagefind(),
react(),
// redirectFrom({
// contentDir: './external-content',
// getSlug: getRedirectFromSlug, // Function to get the slug for redirect_from
// }),
robots(), sitemap(),
robots(),
sitemap(),
],

image: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
// detect-duplicate-frontmatter.js
// Usage: node detect-duplicate-frontmatter.js
/**
* Duplicate Frontmatter Detection Tool
*
* This script analyzes Markdown files for duplicate frontmatter properties
* and generates a report of any duplicates found.
*
* Usage:
* go to ClientApp/build directory
* node detect-duplicate-frontmatter.js
*
* Prerequisites:
* - Node.js installed
* - Run from the script's directory
*
*/

import fs from "fs";
import path from "path";
Expand All @@ -9,7 +22,7 @@ import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const contentDir = path.resolve("external-content/superoffice-docs/docs");
const contentDir = path.resolve("../external-content/superoffice-docs");
const outputFile = path.resolve(__dirname, "duplicate-frontmatter.txt");
const extensions = new Set([".md"]); // add ".mdx" if needed

Expand Down Expand Up @@ -60,7 +73,6 @@ function findTopLevelDuplicateKeys(yamlText) {
const files = fs.existsSync(contentDir) ? walk(contentDir) : [];
/** @type {{file:string, duplicates:string[]}[]} */
const problemFiles = [];

for (const file of files) {
const raw = fs.readFileSync(file, "utf8");
const fm = extractFrontmatter(raw);
Expand Down
32 changes: 32 additions & 0 deletions Source/SuperOffice.DocsNext/ClientApp/build/local-build-script.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
/**
* Local build script for split builds
*
* This script performs a two-phase build process and merges the results:
* 1. Builds with API_ONLY=true
* 2. Builds with API_ONLY=false
* 3. Merges both builds
* 4. Indexes the result with Pagefind
*
* @description
* To use this script for split builds:
* 1. Set up your content collections to handle API_ONLY environment variable
* 2. Configure other files to respond to API_ONLY flag appropriately
* 3. Run this script instead of regular astro build
*
* @example
* // In your content collections:
* const items = API_ONLY === 'true'
* ? apiOnlyContent
* : fullContent;
*
* @note
* - Cleans up temporary build directories (.distA and .distB)
* - Final output will be in dist/ directory
* - Automatically runs Pagefind indexing on final build
*
* @warning
* Currently not actively used in the codebase.
* Ensure proper setup before running split builds.
*/


import { execSync } from "child_process";
import { cpSync, rmSync, existsSync } from "fs";
import path from "path";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Setup External Repositories
*
* This script clones or updates the required external GitHub repositories
* into the `src/external-content/` directory. If a repository folder
* already exists, it will fetch and reset it to the latest commit on the
* `main` branch.
*
* Usage:
* # From ClientApp/build directory
* node setup-external-repos.js
*
* Notes:
* - Requires Git to be installed and available in PATH.
* - Local changes inside the external repos will be overwritten when updating.
*/




import { exec } from "node:child_process";
import path from "node:path";
import fs from "node:fs";

const baseDir = path.resolve(process.cwd(), "..", "external-content");

const repos = [
{
url: "https://github.com/SuperOfficeDocs/contribution.git",
dest: path.join(baseDir, "contribution"),
},
{
url: "https://github.com/SuperOfficeDocs/superoffice-docs.git",
dest: path.join(baseDir, "superoffice-docs"),
},
];

function runCommand(command, cwd) {
return new Promise((resolve, reject) => {
exec(command, { cwd }, (error, stdout, stderr) => {
if (error) {
console.error(`Command failed: ${command}\n${stderr}`);
return reject(error);
}
resolve(stdout.trim());
});
});
}

async function cloneOrUpdate({ url, dest }) {
if (fs.existsSync(dest)) {
console.log(`Repo already exists at ${dest}. Pulling latest changes...`);
await runCommand("git fetch --all", dest);
await runCommand("git reset --hard origin/main", dest);
console.log(`Updated ${url}`);
} else {
console.log(`Cloning ${url} into ${dest}...`);
await runCommand(`git clone ${url} "${dest}"`, process.cwd());
console.log(`Successfully cloned ${url}`);
}
}

async function main() {
for (const repo of repos) {
try {
await cloneOrUpdate(repo);
} catch {
process.exitCode = 1;
break;
}
}
}

main();
6 changes: 3 additions & 3 deletions Source/SuperOffice.DocsNext/ClientApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"dev:partial": "powershell -Command \"$env:PARTIAL_BUILD='true'; astro dev\"",
"start": "astro dev",
"build": "cross-env NODE_OPTIONS=\"--max-old-space-size=12288\" astro check && astro build",
"build:default": "astro check && astro build",
"build:local": "node build/local-build-script.mjs",
"build": "astro check && astro build",
"build:partial": "powershell -Command \"$env:PARTIAL_BUILD='true'; astro check; astro build\"",
"preview": "astro preview",
"astro": "astro",
"test:e2e": "npm run test --workspace=e2e-tests"
Expand Down
Loading
Loading