2021-10-19 16:54:01 +00:00
|
|
|
import { LoadContext, Plugin, PluginContentLoadedActions } from '@docusaurus/types';
|
|
|
|
import path from 'path';
|
2022-09-25 17:04:47 +00:00
|
|
|
import fs from 'fs';
|
|
|
|
import axios, { AxiosError } from 'axios';
|
|
|
|
import { Content, WoodpeckerPlugin, WoodpeckerPluginHeader, WoodpeckerPluginIndexEntry } from './types';
|
2021-10-19 16:54:01 +00:00
|
|
|
import * as markdown from './markdown';
|
|
|
|
|
|
|
|
async function loadContent(): Promise<Content> {
|
2022-09-25 17:04:47 +00:00
|
|
|
const file = path.join(__dirname, '..', 'plugins.json');
|
2021-10-19 16:54:01 +00:00
|
|
|
|
2022-09-25 17:04:47 +00:00
|
|
|
const pluginsIndex = JSON.parse(fs.readFileSync(file).toString()) as { plugins: WoodpeckerPluginIndexEntry[] };
|
2021-10-19 16:54:01 +00:00
|
|
|
|
|
|
|
const plugins = (
|
|
|
|
await Promise.all(
|
2024-06-06 13:28:08 +00:00
|
|
|
pluginsIndex.plugins.map(async (i): Promise<WoodpeckerPlugin | undefined> => {
|
2022-09-25 17:04:47 +00:00
|
|
|
let docsContent: string;
|
|
|
|
try {
|
|
|
|
const response = await axios(i.docs);
|
|
|
|
docsContent = response.data;
|
|
|
|
} catch (e) {
|
|
|
|
console.error("Can't fetch docs file", i.docs, (e as AxiosError).message);
|
2021-10-19 16:54:01 +00:00
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
2022-09-25 17:04:47 +00:00
|
|
|
const docsHeader = markdown.getHeader<WoodpeckerPluginHeader>(docsContent);
|
|
|
|
const docsBody = markdown.getContent(docsContent);
|
2021-10-19 16:54:01 +00:00
|
|
|
|
2022-09-25 17:04:47 +00:00
|
|
|
if (!docsHeader.name) {
|
|
|
|
return undefined;
|
|
|
|
}
|
2021-10-19 16:54:01 +00:00
|
|
|
|
2024-06-06 13:28:08 +00:00
|
|
|
let pluginIconDataUrl: string | undefined;
|
|
|
|
if (docsHeader.icon) {
|
|
|
|
try {
|
|
|
|
const response = await axios(docsHeader.icon, {
|
|
|
|
responseType: 'arraybuffer',
|
|
|
|
});
|
|
|
|
pluginIconDataUrl = `data:${response.headers['content-type'].toString()};base64,${Buffer.from(
|
|
|
|
response.data,
|
|
|
|
'binary',
|
|
|
|
).toString('base64')}`;
|
|
|
|
} catch (e) {
|
|
|
|
console.error("Can't fetch plugin icon", docsHeader.icon, (e as AxiosError).message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
2024-03-22 17:07:07 +00:00
|
|
|
name: docsHeader.name,
|
2022-09-25 17:04:47 +00:00
|
|
|
url: docsHeader.url,
|
|
|
|
icon: docsHeader.icon,
|
|
|
|
description: docsHeader.description,
|
|
|
|
docs: docsBody,
|
|
|
|
tags: docsHeader.tags || [],
|
|
|
|
author: docsHeader.author,
|
|
|
|
containerImage: docsHeader.containerImage,
|
|
|
|
containerImageUrl: docsHeader.containerImageUrl,
|
|
|
|
verified: i.verified || false,
|
2024-06-06 13:28:08 +00:00
|
|
|
iconDataUrl: pluginIconDataUrl,
|
|
|
|
} satisfies WoodpeckerPlugin;
|
2021-10-19 16:54:01 +00:00
|
|
|
}),
|
|
|
|
)
|
2022-09-25 17:04:47 +00:00
|
|
|
).filter<WoodpeckerPlugin>((plugin): plugin is WoodpeckerPlugin => plugin !== undefined);
|
2021-10-19 16:54:01 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
plugins,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function contentLoaded({
|
|
|
|
content: { plugins },
|
|
|
|
actions,
|
|
|
|
}: {
|
|
|
|
content: Content;
|
|
|
|
actions: PluginContentLoadedActions;
|
|
|
|
}): Promise<void> {
|
|
|
|
const { createData, addRoute } = actions;
|
|
|
|
|
|
|
|
const pluginsJsonPath = await createData('plugins.json', JSON.stringify(plugins));
|
|
|
|
|
|
|
|
await Promise.all(
|
2022-09-25 17:04:47 +00:00
|
|
|
plugins.map(async (plugin, i) => {
|
|
|
|
const pluginJsonPath = await createData(`plugin-${i}.json`, JSON.stringify(plugin));
|
2021-10-19 16:54:01 +00:00
|
|
|
|
|
|
|
addRoute({
|
2022-09-25 17:04:47 +00:00
|
|
|
path: `/plugins/${plugin.name}`,
|
2021-10-19 16:54:01 +00:00
|
|
|
component: '@theme/WoodpeckerPlugin',
|
|
|
|
modules: {
|
|
|
|
plugin: pluginJsonPath,
|
|
|
|
},
|
|
|
|
exact: true,
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
addRoute({
|
|
|
|
path: '/plugins',
|
|
|
|
component: '@theme/WoodpeckerPluginList',
|
|
|
|
modules: {
|
|
|
|
plugins: pluginsJsonPath,
|
|
|
|
},
|
|
|
|
exact: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function pluginWoodpeckerPluginsIndex(context: LoadContext, options: any): Plugin<Content> {
|
|
|
|
return {
|
|
|
|
name: 'woodpecker-plugins',
|
|
|
|
loadContent,
|
|
|
|
contentLoaded,
|
|
|
|
getThemePath() {
|
|
|
|
return path.join(__dirname, '..', 'dist', 'theme');
|
|
|
|
},
|
|
|
|
getTypeScriptThemePath() {
|
|
|
|
return path.join(__dirname, '..', 'src', 'theme');
|
|
|
|
},
|
|
|
|
getPathsToWatch() {
|
2022-09-25 17:04:47 +00:00
|
|
|
return [path.join(__dirname, '..', 'dist', '**', '*.{js,jsx,css}')];
|
2021-10-19 16:54:01 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const getSwizzleComponentList = (): string[] => {
|
|
|
|
return ['WoodpeckerPluginList', 'WoodpeckerPlugin'];
|
|
|
|
};
|
|
|
|
|
|
|
|
export { getSwizzleComponentList };
|