diff --git a/website/package.json b/website/package.json index dc69571af6..5c2d31251b 100644 --- a/website/package.json +++ b/website/package.json @@ -38,6 +38,7 @@ "react-dom": "^17.0.1", "sha1": "^1.1.1", "sharp": "^0.29.3", + "picocolors": "^1.0.0", "superstruct": "^0.15.3", "text-to-svg": "^3.1.5", "url-loader": "^4.1.1" diff --git a/website/plugins/docusaurus-plugin-open-graph-image/config.js b/website/plugins/docusaurus-plugin-open-graph-image/config.js index 97684353e6..3eea8c914c 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/config.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/config.js @@ -1,14 +1,21 @@ -const fs = require("fs"); +const { resolve } = require("path"); +const { readFile } = require("fs/promises"); const { object, string, number, array, is } = require("superstruct"); -const { objectFromBuffer } = require("./utils"); +const { objectFromBuffer, Logger } = require("./utils"); -function getConfig(path, encode = "utf-8") { - const config = objectFromBuffer(fs.readFileSync(`${path}\\config.json`, encode)); - if (!validateConfig(config)) { - console.error("Config validation error"); - return; +async function getConfig(configPath, encode = "utf-8") { + try { + const config = objectFromBuffer(await readFile(resolve(configPath, "config.json"), encode)); + + if (!validateConfig(config)) { + Logger.err("Config validation error"); + return; + } + + return config; + } catch (error) { + Logger.err(error); } - return config; } const Rule = object({ diff --git a/website/plugins/docusaurus-plugin-open-graph-image/font.js b/website/plugins/docusaurus-plugin-open-graph-image/font.js index 20130cdca7..b2689a2b8a 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/font.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/font.js @@ -1,3 +1,4 @@ +const { resolve } = require("path"); const textToSVG = require("text-to-svg"); function createFontsMapFromTemplates(templates) { @@ -6,7 +7,7 @@ function createFontsMapFromTemplates(templates) { if (!fonts.has(template.params.font)) { fonts.set( template.params.font, - textToSVG.loadSync(`${template.path}\\${template.name}\\${template.params.font}`), + textToSVG.loadSync(resolve(template.path, template.name, template.params.font)), ); } }); diff --git a/website/plugins/docusaurus-plugin-open-graph-image/image.js b/website/plugins/docusaurus-plugin-open-graph-image/image.js index 4a020cdffe..9ffc5726e3 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/image.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/image.js @@ -1,3 +1,4 @@ +const { resolve } = require("path"); const sharp = require("sharp"); function getTemplateImageId(template) { @@ -11,7 +12,7 @@ function createImagePipeline(file) { } function createImageFromTemplate({ path, name, params }) { - return createImagePipeline(`${path}\\${name}\\${params.image}`); + return createImagePipeline(resolve(path, name, params.image)); } function createImagesMapFromTemplates(templates) { diff --git a/website/plugins/docusaurus-plugin-open-graph-image/index.js b/website/plugins/docusaurus-plugin-open-graph-image/index.js index 392bf75364..8cdd278d5f 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/index.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/index.js @@ -1,4 +1,5 @@ -const fs = require("fs"); +const { mkdir } = require("fs/promises"); +const { resolve } = require("path"); const sha1 = require("sha1"); const { getTemplates } = require("./template"); const { createLayoutLayers } = require("./layout"); @@ -6,35 +7,44 @@ const { createFontsMapFromTemplates } = require("./font"); const { createImagesMapFromTemplates, getTemplateImageId } = require("./image"); const { getConfig } = require("./config"); const { getTemplateNameByRules } = require("./rules"); +const { Logger } = require("./utils"); -module.exports = function ({ templatesDir }) { - const initData = bootstrap(templatesDir); - if (!initData) { - console.error("OpenGraph plugin exit with error."); - return; - } - - const { config } = initData; - +module.exports = function (_, { templatesDir }) { return { name: "docusaurus-plugin-open-graph-image", async postBuild({ plugins, outDir, i18n }) { + Logger.info(`OG: work in progress.`); + + const initData = await bootstrap(templatesDir); + if (!initData) { + Logger.err("OpenGraph plugin exit with error."); + return; + } + + Logger.ok(`OG: initialization complete.`); + + const { config } = initData; + const docsPlugin = plugins.find( (plugin) => plugin.name === "docusaurus-plugin-content-docs", ); if (!docsPlugin) throw new Error("Docusaurus Doc plugin not found."); - const previewOutputDir = `${outDir}\\${config.outputDir}`; - fs.mkdir(previewOutputDir, { recursive: true }, (error) => { - if (error) throw error; - }); + const previewOutputDir = resolve(outDir, config.outputDir); + + try { + await mkdir(previewOutputDir, { recursive: true }); + } catch (error) { + Logger.err(error); + return; + } + Logger.ok(`OG: assets output folder created.`); const docsContent = docsPlugin.content; const docsVersions = docsContent.loadedVersions; docsVersions.forEach((version) => { const { docs } = version; - docs.forEach((document) => { generateImageFromDoc(initData, document, i18n.currentLocale, previewOutputDir); }); @@ -43,19 +53,19 @@ module.exports = function ({ templatesDir }) { }; }; -function bootstrap(templatesDir) { +async function bootstrap(templatesDir) { const isProd = process.env.NODE_ENV === "production"; if (!isProd) return; if (!templatesDir) { - console.error("Wrong templatesDir option."); + Logger.err("Wrong templatesDir option."); return; } - const templates = getTemplates(templatesDir); + const templates = await getTemplates(templatesDir); if (!templates) return; - const config = getConfig(templatesDir); + const config = await getConfig(templatesDir); if (!config) return; // TODO: File not found exception? @@ -93,8 +103,13 @@ async function generateImageFromDoc(initData, doc, locale, outputDir) { quality: config.quality, chromaSubsampling: "4:4:4", }) - .toFile(`${outputDir}\\${hashFileName}.jpg`); + .toFile(resolve(outputDir, `${hashFileName}.jpg`)); + Logger.ok(`Generated: ${hashFileName}.jpg`); } catch (error) { - console.error(error, id, title, hashFileName); + Logger.err(`${error} + DocumentID: ${id} + Title: ${title} + Hash: ${hashFileName} + Path: ${resolve(outputDir, `${hashFileName}.jpg`)}`); } } diff --git a/website/plugins/docusaurus-plugin-open-graph-image/layout.js b/website/plugins/docusaurus-plugin-open-graph-image/layout.js index 6bcb384672..0d4ca790e7 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/layout.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/layout.js @@ -1,9 +1,10 @@ const { createSVGText } = require("./font"); +const { Logger } = require("./utils"); function createLayoutLayers(doc, layout, previewFont, textWidthLimit) { /* Check for all layers names exist in doc fields */ if (layout.some((layer) => !doc[layer.name])) { - console.error(`Wrong template config.`); + Logger.err(`Wrong template config.`); return; } diff --git a/website/plugins/docusaurus-plugin-open-graph-image/template.js b/website/plugins/docusaurus-plugin-open-graph-image/template.js index 2d6ec095f9..29532a3c14 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/template.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/template.js @@ -1,29 +1,39 @@ -const fs = require("fs"); +const { resolve } = require("path"); +const { readdir, readFile } = require("fs/promises"); const { object, string, number, array, is } = require("superstruct"); -const { objectFromBuffer } = require("./utils"); +const { objectFromBuffer, Logger } = require("./utils"); const dirIgnore = ["config.json"]; -function getTemplates(templatesDir, encode = "utf8") { - const templatesDirNames = fs - .readdirSync(templatesDir) - .filter((fileName) => !dirIgnore.includes(fileName)); - - // TODO: check file exist - const templates = templatesDirNames.map((templateName) => ({ - name: templateName, - path: templatesDir, - params: objectFromBuffer( - fs.readFileSync(`${templatesDir}\\${templateName}\\template.json`, encode), - ), - })); - - if (!templates.some(validateTemplate)) { - console.error("Templates validation error."); - return; - } +async function getTemplates(templatesDir, encode = "utf8") { + try { + const allDirFiles = await readdir(templatesDir); + const templatesDirNames = allDirFiles.filter((fileName) => !dirIgnore.includes(fileName)); + + const templates = await Promise.all( + templatesDirNames.map(async (templateName) => { + const templateBuffer = await readFile( + resolve(templatesDir, templateName, "template.json"), + encode, + ); + + return { + name: templateName, + path: templatesDir, + params: objectFromBuffer(templateBuffer), + }; + }), + ); - return templates; + if (!templates.some(validateTemplate)) { + Logger.err("Templates validation error."); + return; + } + + return templates; + } catch (error) { + Logger.err(error); + } } // TODO: May be with postEffects, images and etc? (optional fontSize, fill and etc) diff --git a/website/plugins/docusaurus-plugin-open-graph-image/utils.js b/website/plugins/docusaurus-plugin-open-graph-image/utils.js index b824a4e88c..d0d2d085f8 100644 --- a/website/plugins/docusaurus-plugin-open-graph-image/utils.js +++ b/website/plugins/docusaurus-plugin-open-graph-image/utils.js @@ -1,5 +1,21 @@ +const pc = require("picocolors"); + function objectFromBuffer(buffer) { return JSON.parse(buffer.toString()); } -module.exports = { objectFromBuffer }; +const Logger = { + info(text) { + // eslint-disable-next-line no-console + console.log(pc.bgYellow(pc.black(`! ${text}`))); + }, + ok(text) { + // eslint-disable-next-line no-console + console.log(pc.bgGreen(pc.black(`\u2714 ${text}`))); + }, + err(text) { + console.error(pc.bgRed(pc.black(`\u274C ${text}`))); + }, +}; + +module.exports = { objectFromBuffer, Logger };