UNPKG

@backstage/plugin-techdocs-node

Version:

Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli

158 lines (152 loc) 5.55 kB
'use strict'; var fs = require('fs-extra'); var yaml = require('js-yaml'); var helpers = require('./helpers.cjs.js'); var errors = require('@backstage/errors'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var fs__default = /*#__PURE__*/_interopDefaultCompat(fs); var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml); const MATERIAL_THEME = "material"; function isThemeObject(theme) { return typeof theme === "object" && theme !== null && !Array.isArray(theme); } const patchMkdocsFile = async (mkdocsYmlPath, logger, updateAction) => { let didEdit = false; let mkdocsYmlFileString; try { mkdocsYmlFileString = await fs__default.default.readFile(mkdocsYmlPath, "utf8"); } catch (error) { logger.warn( `Could not read MkDocs YAML config file ${mkdocsYmlPath} before running the generator: ${errors.toError(error).message}` ); return; } let mkdocsYml; try { mkdocsYml = yaml__default.default.load(mkdocsYmlFileString, { schema: helpers.MKDOCS_SCHEMA }); if (typeof mkdocsYml === "string" || typeof mkdocsYml === "undefined") { throw new Error("Bad YAML format."); } } catch (error) { logger.warn( `Error in parsing YAML at ${mkdocsYmlPath} before running the generator. ${errors.toError(error).message}` ); return; } didEdit = updateAction(mkdocsYml); try { if (didEdit) { await fs__default.default.writeFile( mkdocsYmlPath, yaml__default.default.dump(mkdocsYml, { schema: helpers.MKDOCS_SCHEMA }), "utf8" ); } } catch (error) { logger.warn( `Could not write to ${mkdocsYmlPath} after updating it before running the generator. ${errors.toError(error).message}` ); return; } }; const patchMkdocsYmlPreBuild = async (mkdocsYmlPath, logger, parsedLocationAnnotation, scmIntegrations) => { await patchMkdocsFile(mkdocsYmlPath, logger, (mkdocsYml) => { if (!("repo_url" in mkdocsYml) || !("edit_uri" in mkdocsYml)) { const result = helpers.getRepoUrlFromLocationAnnotation( parsedLocationAnnotation, scmIntegrations, mkdocsYml.docs_dir ); if (result.repo_url || result.edit_uri) { mkdocsYml.repo_url = mkdocsYml.repo_url || result.repo_url; mkdocsYml.edit_uri = mkdocsYml.edit_uri || result.edit_uri; logger.info( `Set ${JSON.stringify( result )}. You can disable this feature by manually setting 'repo_url' or 'edit_uri' according to the MkDocs documentation at https://www.mkdocs.org/user-guide/configuration/#repo_url` ); return true; } } return false; }); }; const patchMkdocsYmlWithPlugins = async (mkdocsYmlPath, logger, defaultPlugins = ["techdocs-core"]) => { await patchMkdocsFile(mkdocsYmlPath, logger, (mkdocsYml) => { if (!("plugins" in mkdocsYml)) { mkdocsYml.plugins = defaultPlugins; return true; } let changesMade = false; defaultPlugins.forEach((dp) => { if (!(mkdocsYml.plugins.includes(dp) || mkdocsYml.plugins.some((p) => p.hasOwnProperty(dp)))) { mkdocsYml.plugins = [.../* @__PURE__ */ new Set([...mkdocsYml.plugins, dp])]; changesMade = true; } }); return changesMade; }); }; const patchMkdocsYmlWithFontDisabled = async (mkdocsYmlPath, logger) => { await patchMkdocsFile(mkdocsYmlPath, logger, (mkdocsYml) => { if (!("theme" in mkdocsYml)) { mkdocsYml.theme = { name: MATERIAL_THEME, font: false }; return true; } const theme = mkdocsYml.theme; if (isThemeObject(theme)) { if (theme.name === MATERIAL_THEME && !("font" in theme)) { theme.font = false; return true; } if (theme.name !== MATERIAL_THEME) { logger.debug( 'mkdocs.yml theme is not "material"; skipping font disabling patch' ); } } return false; }); }; const sanitizeMkdocsYml = async (mkdocsYmlPath, logger, additionalAllowedKeys) => { await patchMkdocsFile(mkdocsYmlPath, logger, (mkdocsYml) => { const allowedKeys = new Set(helpers.ALLOWED_MKDOCS_KEYS); if (additionalAllowedKeys && additionalAllowedKeys.length > 0) { logger.warn( `DANGEROUS: Allowing additional MkDocs configuration keys beyond the default safe allowlist: ${additionalAllowedKeys.join( ", " )}. This may introduce security vulnerabilities. Only use in trusted environments.` ); additionalAllowedKeys.forEach((key) => allowedKeys.add(key)); } const removedKeys = Object.keys(mkdocsYml).filter( (key) => !allowedKeys.has(key) ); if (removedKeys.length > 0) { logger.warn( `Removed the following unsupported configuration keys from mkdocs.yml: ${removedKeys.join( ", " )}. TechDocs only supports a subset of MkDocs configuration options.` ); } const sanitized = {}; for (const key of allowedKeys) { if (key in mkdocsYml) { sanitized[key] = mkdocsYml[key]; } } for (const key of Object.keys(mkdocsYml)) { delete mkdocsYml[key]; } Object.assign(mkdocsYml, sanitized); return true; }); }; exports.patchMkdocsYmlPreBuild = patchMkdocsYmlPreBuild; exports.patchMkdocsYmlWithFontDisabled = patchMkdocsYmlWithFontDisabled; exports.patchMkdocsYmlWithPlugins = patchMkdocsYmlWithPlugins; exports.sanitizeMkdocsYml = sanitizeMkdocsYml; //# sourceMappingURL=mkdocsPatchers.cjs.js.map