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
3 changes: 3 additions & 0 deletions crowdsec-docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { themes } from "prism-react-renderer";
import tailwindPlugin from "./plugins/tailwind-config";
import { ctiApiSidebar, guidesSideBar, remediationSideBar, trackerApiSidebar } from "./sidebarsUnversioned";

const extractPreprocessor = require("./plugins/extract-preprocessor");

const generateCurrentAndNextRedirects = (s) => [
{
from: `/docs/${s}`,
Expand Down Expand Up @@ -225,6 +227,7 @@ const config: Config = {
admonitions: true,
headingIds: true,
},
preprocessor: extractPreprocessor,
},
stylesheets: [
{
Expand Down
104 changes: 104 additions & 0 deletions crowdsec-docs/plugins/extract-preprocessor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const fs = require('fs');
const path = require('path');

// --- CONFIGURATION ---
// The directories to scan for snippets
const DOCS_DIRS = ['./docs', './unversioned'];
// ---------------------

const snippetRegistry = new Map();
let isIndexed = false;

// Helper: Recursively find all .md/.mdx files
const getAllFiles = (dirPath, arrayOfFiles = []) => {
if (!fs.existsSync(dirPath)) return arrayOfFiles;

const files = fs.readdirSync(dirPath);
files.forEach((file) => {
const fullPath = path.join(dirPath, file);
if (fs.statSync(fullPath).isDirectory()) {
getAllFiles(fullPath, arrayOfFiles);
} else if (file.endsWith('.md') || file.endsWith('.mdx')) {
arrayOfFiles.push(fullPath);
}
});
return arrayOfFiles;
};

// Helper: Extract Doc ID from Frontmatter
const getDocId = (content, filename) => {
const idMatch = content.match(/^---\s+[\s\S]*?\nid:\s*(.*?)\s*[\n\r]/m);
if (idMatch && idMatch[1]) {
return idMatch[1].replace(/['"]/g, '').trim();
}
return filename;
};

// --- CORE LOGIC ---
const buildIndex = () => {
if (isIndexed) return;
console.log('[ExtractPreprocessor] ⚡ Indexing snippets via Regex...');

const allFiles = [];
DOCS_DIRS.forEach(dir => getAllFiles(path.resolve(process.cwd(), dir), allFiles));

let count = 0;

// Regex to find: <div data-extract="ID"> CONTENT </div>
// We use [\s\S]*? to match content across multiple lines (lazy match)
const extractRegex = /<div\s+data-extract=["']([^"']+)["'][^>]*>([\s\S]*?)<\/div>/g;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try using a custom tag, if it's removed docusauus shjould not be bothered


allFiles.forEach(filePath => {
try {
const content = fs.readFileSync(filePath, 'utf8');
const filename = path.basename(filePath, path.extname(filePath));
const docId = getDocId(content, filename);

let match;
// Loop through all matches in the file
while ((match = extractRegex.exec(content)) !== null) {
let [fullTag, extractId, snippetContent] = match;

// Clean up the content (optional: trim leading/trailing newlines)
snippetContent = snippetContent.replace(/^\n+|\n+$/g, '');

// Generate Key: "docId:snippetId"
// If the ID already has a colon, assume user provided full ID
const key = extractId.includes(':') ? extractId : `${docId}:${extractId}`;

snippetRegistry.set(key, snippetContent);
console.log(`[ExtractPreprocessor] ⚡ Indexed snippet: ${key}`);
count++;
}
} catch (e) {
console.warn(`[ExtractPreprocessor] Failed to read ${filePath}`);
}
});

isIndexed = true;
console.log(`[ExtractPreprocessor] ⚡ Indexed ${count} snippets.`);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now remove all divs that have been indexed

};

// This function is called by Docusaurus for EVERY markdown file
const preprocessor = ({ filePath, fileContent }) => {
// 1. Ensure Index exists (runs once)
buildIndex();

// 2. Regex to find: <div data-extract-copy="ID" />
// Matches <div data-extract-copy="xyz"></div> OR <div data-extract-copy="xyz" />
const copyRegex = /<div\s+data-extract-copy=["']([^"']+)["']\s*\/?>\s*(?:<\/div>)?/g;

// 3. Replace with content
return fileContent.replace(copyRegex, (match, requestedId) => {
if (snippetRegistry.has(requestedId)) {
// Return the stored snippet content
return snippetRegistry.get(requestedId);
} else {
console.error(`[ExtractPreprocessor] ❌ Snippet not found: "${requestedId}" in ${path.basename(filePath)}`);
// Return an error message in the UI so you see it
return `> **Error: Snippet "${requestedId}" not found.**`;
}
});
};

module.exports = preprocessor;
2 changes: 2 additions & 0 deletions crowdsec-docs/unversioned/troubleshooting/console_issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This page lists all possible health check issues, their trigger conditions, and
- 🌟 **Bonus**: Optimization advice and upper-tier recommendations with strong return on value *(coming in future Stack Health iterations)*

## Health Check Issues Overview
<div data-extract="stackhealth_issues_list">
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the div once the extracts have been indexed


| Issue | Criticality | Summary | Resolution |
|-------|---------------|---------|------------|
Expand All @@ -30,6 +31,7 @@ This page lists all possible health check issues, their trigger conditions, and
| **Security Engine Offline** | 🔥 Critical | Security Engine has not reported to Console for 24+ hours | [Troubleshooting](/u/troubleshooting/issue_se_offline) |
| **Security Engine Too Many Alerts** | ⚠️ High | More than 250,000 alerts in 6 hours | [Troubleshooting](/u/troubleshooting/issue_se_too_many_alerts) |

</div>
## Issue Dependencies

Some issues are related and share common root causes:
Expand Down
4 changes: 3 additions & 1 deletion crowdsec-docs/unversioned/troubleshooting/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ Please try to resolve your issue by reading the documentation. If you're unable

If you are on an Enterprise plan, you can use dedicated support via the Console:

- [Enterprise plan support](/u/console/enterprise_plan/enterprise_support)
### Stack Health issues list

<div data-extract-copy="console_issues:stackhealth_issues_list"></div>
Loading