docs(ai-agents): Move Sonar API docs from embedded-api to ai-agents instance (#70235)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: ian.alton@airbyte.io <ian.alton@airbyte.io> Co-authored-by: letiescanciano <leticia.escanciano@gmail.com>
This commit is contained in:
committed by
GitHub
parent
1088cedd76
commit
cdd58ead27
4
docs/ai-agents/embedded/api-reference/.gitignore
vendored
Normal file
4
docs/ai-agents/embedded/api-reference/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore all generated OpenAPI documentation files
|
||||
# These are generated by docusaurus-plugin-openapi-docs during build
|
||||
*
|
||||
!.gitignore
|
||||
@@ -2,8 +2,11 @@ import "dotenv/config.js";
|
||||
import type { Config } from "@docusaurus/types";
|
||||
import { themes as prismThemes } from "prism-react-renderer";
|
||||
import type { Options as ClassicPresetOptions } from "@docusaurus/preset-classic";
|
||||
import fs from "fs";
|
||||
import { PluginOptions as LLmPluginOptions } from "@signalwire/docusaurus-plugin-llms-txt";
|
||||
import {
|
||||
loadSonarApiSidebar,
|
||||
replaceApiReferenceCategory,
|
||||
} from "./src/scripts/embedded-api/sidebar-generator";
|
||||
|
||||
// Import remark plugins - lazy load to prevent webpack from bundling Node.js code
|
||||
const getRemarkPlugins = () => ({
|
||||
@@ -19,7 +22,7 @@ const getRemarkPlugins = () => ({
|
||||
|
||||
const plugins = getRemarkPlugins();
|
||||
|
||||
// Import constants
|
||||
// Import constants for embedded API sidebar generation
|
||||
const {
|
||||
SPEC_CACHE_PATH,
|
||||
API_SIDEBAR_PATH,
|
||||
@@ -164,8 +167,17 @@ const config: Config = {
|
||||
id: "ai-agents",
|
||||
path: "../docs/ai-agents",
|
||||
routeBasePath: "/ai-agents",
|
||||
sidebarPath: "./sidebar-ai-agents.js",
|
||||
editUrl: "https://github.com/airbytehq/airbyte/blob/master/docs",
|
||||
docItemComponent: "@theme/ApiItem", // Required for OpenAPI docs rendering
|
||||
async sidebarItemsGenerator({ defaultSidebarItemsGenerator, ...args }) {
|
||||
const sidebarItems = await defaultSidebarItemsGenerator(args);
|
||||
|
||||
// Load and filter the Sonar API sidebar based on allowed tags
|
||||
const sonarApiItems = loadSonarApiSidebar();
|
||||
|
||||
// Replace the "api-reference" category with the filtered API items
|
||||
return replaceApiReferenceCategory(sidebarItems, sonarApiItems);
|
||||
},
|
||||
remarkPlugins: [
|
||||
plugins.docsHeaderDecoration,
|
||||
plugins.enterpriseDocsHeaderInformation,
|
||||
@@ -249,90 +261,15 @@ const config: Config = {
|
||||
],
|
||||
},
|
||||
],
|
||||
[
|
||||
"@docusaurus/plugin-content-docs",
|
||||
{
|
||||
id: "embedded-api",
|
||||
path: "api-docs/embedded-api",
|
||||
routeBasePath: "/embedded-api/",
|
||||
docItemComponent: "@theme/ApiItem",
|
||||
async sidebarItemsGenerator() {
|
||||
// We only want to include visible endpoints on the sidebar. We need to filter out endpoints with tags
|
||||
// that are not included in the spec. Even if we didn't need to filter out elements the OpenAPI plugin generates a sidebar.ts
|
||||
// file that exports a nested object, but Docusaurus expects just the array of sidebar items, so we need to extracts the actual sidebar
|
||||
// items from the generated file structure.
|
||||
|
||||
try {
|
||||
const specPath = SPEC_CACHE_PATH;
|
||||
|
||||
if (!fs.existsSync(specPath)) {
|
||||
console.warn(
|
||||
"Embedded API spec file not found, using empty sidebar",
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(specPath, "utf8"));
|
||||
console.log("Loaded embedded API spec from cache");
|
||||
|
||||
// Load the freshly generated sidebar (not the cached one from module load)
|
||||
const sidebarPath = API_SIDEBAR_PATH;
|
||||
let freshSidebar: any[] = [];
|
||||
|
||||
if (fs.existsSync(sidebarPath)) {
|
||||
try {
|
||||
const sidebarModule = require("./api-docs/embedded-api/sidebar.ts");
|
||||
freshSidebar = sidebarModule.default || sidebarModule;
|
||||
console.log("Loaded fresh sidebar from generated files");
|
||||
} catch (sidebarError: any) {
|
||||
console.warn(
|
||||
"Could not load fresh sidebar, using empty array:",
|
||||
sidebarError.message,
|
||||
);
|
||||
freshSidebar = [];
|
||||
}
|
||||
} else {
|
||||
console.warn(
|
||||
"Generated sidebar file not found, using empty array",
|
||||
);
|
||||
freshSidebar = [];
|
||||
}
|
||||
|
||||
const allowedTags = data.tags?.map((tag: any) => tag["name"]) || [];
|
||||
|
||||
// Use freshly loaded sidebar items from the generated file
|
||||
const sidebarItems = Array.isArray(freshSidebar)
|
||||
? freshSidebar
|
||||
: [];
|
||||
|
||||
const filteredItems = sidebarItems.filter((item: any) => {
|
||||
if (item.type !== "category") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return allowedTags.includes(item.label);
|
||||
});
|
||||
|
||||
return filteredItems;
|
||||
} catch (error: any) {
|
||||
console.warn(
|
||||
"Error loading embedded API spec from cache:",
|
||||
error.message,
|
||||
);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
"docusaurus-plugin-openapi-docs",
|
||||
{
|
||||
id: "embedded-api",
|
||||
docsPluginId: "embedded-api",
|
||||
docsPluginId: "ai-agents",
|
||||
config: {
|
||||
embedded: {
|
||||
specPath: "src/data/embedded_api_spec.json",
|
||||
outputDir: "api-docs/embedded-api",
|
||||
outputDir: "../docs/ai-agents/embedded/api-reference",
|
||||
sidebarOptions: {
|
||||
groupPathsBy: "tag",
|
||||
categoryLinkSource: "tag",
|
||||
@@ -476,10 +413,10 @@ const config: Config = {
|
||||
label: "Release notes",
|
||||
},
|
||||
{
|
||||
type: "docSidebar",
|
||||
type: "doc",
|
||||
position: "left",
|
||||
docsPluginId: "ai-agents",
|
||||
sidebarId: "ai-agents",
|
||||
docId: "README",
|
||||
label: "AI agents",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"cleanup-cache": "node src/scripts/cleanup-cache.js",
|
||||
"prebuild": "pnpm run prepare-registry-cache && pnpm run prepare-embedded-api",
|
||||
"postbuild": "pnpm run cleanup-cache",
|
||||
"prestart": "pnpm run prepare-registry-cache",
|
||||
"prestart": "pnpm run prepare-registry-cache && pnpm run prepare-embedded-api",
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "node src/scripts/fetchSchema.js && docusaurus start --port 3005",
|
||||
"build": "node src/scripts/fetchSchema.js && docusaurus build",
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
export default {
|
||||
"ai-agents": [
|
||||
{
|
||||
type: "category",
|
||||
collapsible: false,
|
||||
label: "AI Agents",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "README",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: "category",
|
||||
label: "Embedded",
|
||||
items: [
|
||||
{
|
||||
type: "category",
|
||||
label: "Widget",
|
||||
items: [
|
||||
"embedded/widget/quickstart",
|
||||
{
|
||||
type: "category",
|
||||
label: "Tutorials",
|
||||
items: [
|
||||
"embedded/widget/tutorials/prerequisites-setup",
|
||||
"embedded/widget/tutorials/develop-your-app",
|
||||
"embedded/widget/tutorials/use-embedded",
|
||||
],
|
||||
},
|
||||
"embedded/widget/managing-embedded",
|
||||
"embedded/widget/template-tags",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "API",
|
||||
items: [
|
||||
"embedded/api/README",
|
||||
{
|
||||
type: "link",
|
||||
label: "Sonar API reference",
|
||||
href: "/embedded-api/sonar",
|
||||
},
|
||||
"embedded/api/connection-templates",
|
||||
"embedded/api/source-templates",
|
||||
"embedded/api/configuring-sources",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "MCP Servers",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "pyairbyte-mcp",
|
||||
label: "PyAirbyte MCP",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "connector-builder-mcp",
|
||||
label: "Connector Builder MCP",
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ const SPEC_CACHE_PATH = path.join(PROJECT_ROOT, "src", "data", "embedded_api_spe
|
||||
const EMBEDDED_API_SPEC_URL = "https://airbyte-sonar-prod.s3.us-east-2.amazonaws.com/openapi/latest/app.json";
|
||||
|
||||
// API documentation output directory (relative to project root)
|
||||
const API_DOCS_OUTPUT_DIR = "api-docs/embedded-api";
|
||||
const API_DOCS_OUTPUT_DIR = "../docs/ai-agents/embedded/api-reference";
|
||||
|
||||
// Sidebar file path for generated API docs
|
||||
const API_SIDEBAR_PATH = path.join(PROJECT_ROOT, API_DOCS_OUTPUT_DIR, "sidebar.ts");
|
||||
|
||||
72
docusaurus/src/scripts/embedded-api/sidebar-generator.ts
Normal file
72
docusaurus/src/scripts/embedded-api/sidebar-generator.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { API_SIDEBAR_PATH, SPEC_CACHE_PATH } from "./constants";
|
||||
import * as fs from "fs";
|
||||
|
||||
const loadAllowedTags = (): string[] => {
|
||||
if (fs.existsSync(SPEC_CACHE_PATH)) {
|
||||
try {
|
||||
const spec = JSON.parse(fs.readFileSync(SPEC_CACHE_PATH, "utf8"));
|
||||
return spec.tags?.map((tag: any) => tag.name) || [];
|
||||
} catch (e) {
|
||||
console.warn("Could not load OpenAPI spec for tag filtering:", e);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
export const loadSonarApiSidebar = (): any[] => {
|
||||
const allowedTags = loadAllowedTags();
|
||||
|
||||
if (fs.existsSync(API_SIDEBAR_PATH)) {
|
||||
try {
|
||||
const sidebarModule = require(API_SIDEBAR_PATH);
|
||||
// The sidebar.ts exports the array directly via: export default sidebar.apisidebar;
|
||||
let apiSidebarItems = sidebarModule.default || sidebarModule || [];
|
||||
|
||||
// Filter to only show tags that are defined in the spec
|
||||
apiSidebarItems = apiSidebarItems.filter((item: any) => {
|
||||
if (item.type !== "category") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return allowedTags.includes(item.label);
|
||||
});
|
||||
|
||||
console.log(`Filtered API sidebar to ${apiSidebarItems.length} items`);
|
||||
return apiSidebarItems;
|
||||
} catch (e) {
|
||||
console.warn("Could not load pre-generated API sidebar:", e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
// Helper function to find and replace the "api-reference" category
|
||||
export const replaceApiReferenceCategory = (
|
||||
items: any[],
|
||||
sonarApiItems: any[],
|
||||
): any[] => {
|
||||
return items.map((item) => {
|
||||
if (
|
||||
item.type === "category" &&
|
||||
item.label === "api-reference" &&
|
||||
item.items !== undefined
|
||||
) {
|
||||
// Replace the api-reference category items with the filtered autogenerated API sidebar
|
||||
return {
|
||||
...item,
|
||||
label: "Sonar API Reference",
|
||||
items: sonarApiItems,
|
||||
};
|
||||
}
|
||||
|
||||
if (item.items) {
|
||||
return {
|
||||
...item,
|
||||
items: replaceApiReferenceCategory(item.items, sonarApiItems),
|
||||
};
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
};
|
||||
@@ -595,6 +595,16 @@
|
||||
"source": "/platform/developer-guides/licenses/:path*",
|
||||
"destination": "/community/licenses/:path*",
|
||||
"statusCode": 301
|
||||
},
|
||||
{
|
||||
"source": "/embedded-api/sonar",
|
||||
"destination": "/ai-agents/embedded/api-reference/sonar",
|
||||
"statusCode": 301
|
||||
},
|
||||
{
|
||||
"source": "/embedded-api/:path*",
|
||||
"destination": "/ai-agents/embedded/api-reference/:path*",
|
||||
"statusCode": 301
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user