blob: 416f1d44a74becb69df773a66c5422f7e5d817d2 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Generates the `/services` documentation section from `data/services.json`
// (produced by `just generate docs`). Every service gets a page with language
// tabs, and every supported (service, binding) pair gets a deep-linkable page
// such as `/services/s3/python`. These routes are registered programmatically
// so they stay out of the autogenerated docs sidebar while remaining real,
// statically rendered URLs.
const path = require("path");
const fs = require("fs");
// Join path segments under the site's baseUrl, collapsing duplicate slashes.
// Avoids depending on @docusaurus/utils, which pnpm does not hoist to a place
// resolvable from this plugin file.
function joinUrl(parts) {
const joined = parts.join("/").replace(/\/{2,}/g, "/");
return joined.startsWith("/") ? joined : `/${joined}`;
}
module.exports = function servicesDocsPlugin(context) {
const { baseUrl } = context;
return {
name: "opendal-services-docs",
async loadContent() {
const dataPath = path.resolve(__dirname, "../data/services.json");
const raw = fs.readFileSync(dataPath, "utf8");
return JSON.parse(raw);
},
async contentLoaded({ content, actions }) {
const { createData, addRoute } = actions;
const { bindings, services } = content;
const indexComponent =
"@site/src/components/services/ServicesIndex.jsx";
const pageComponent = "@site/src/components/services/ServicePage.jsx";
// The index only needs a slim summary per service, not full snippets.
const summary = services.map((s) => ({
name: s.name,
scheme: s.scheme,
bindings: s.examples.map((e) => e.binding),
configCount: s.configs.length,
}));
const indexData = await createData(
"services-index.json",
JSON.stringify({ bindings, services: summary })
);
addRoute({
path: joinUrl([baseUrl, "services"]),
component: indexComponent,
modules: { data: indexData },
exact: true,
});
for (const service of services) {
const data = await createData(
`service-${service.scheme}.json`,
JSON.stringify({ bindings, service })
);
addRoute({
path: joinUrl([baseUrl, "services", service.scheme]),
component: pageComponent,
modules: { data },
exact: true,
});
for (const example of service.examples) {
addRoute({
path: joinUrl([
baseUrl,
"services",
service.scheme,
example.binding,
]),
component: pageComponent,
modules: { data },
exact: true,
});
}
}
},
};
};