UNPKG

@telefonica/markdown-confluence-sync

Version:

Creates/updates/deletes Confluence pages based on markdown files in a directory. Supports Mermaid diagrams and per-page configuration using frontmatter metadata. Works great with Docusaurus

159 lines (158 loc) 6.39 kB
// SPDX-FileCopyrightText: 2024 Telefónica Innovación Digital // SPDX-License-Identifier: Apache-2.0 import { ConfluenceSyncPages, SyncModes } from "@telefonica/confluence-sync"; import { isStringWithLength } from "../support/typesValidations.js"; import { ConfluencePageTransformer } from "./transformer/ConfluencePageTransformer.js"; import { PageIdRequiredException } from "./transformer/errors/PageIdRequiredException.js"; const urlOption = { name: "url", type: "string", }; const apiPrefixOption = { name: "apiPrefix", type: "string", default: "/rest/", }; const personalAccessTokenOption = { name: "personalAccessToken", type: "string", }; const spaceKeyOption = { name: "spaceKey", type: "string", }; const rootPageIdOption = { name: "rootPageId", type: "string", }; const rootPageNameOption = { name: "rootPageName", type: "string", }; const noticeMessageOption = { name: "noticeMessage", type: "string", }; const noticeTemplateOption = { name: "noticeTemplate", type: "string", }; const dryRunOption = { name: "dryRun", type: "boolean", default: false, }; const authenticationOption = { name: "authentication", type: "object", }; const rehypeCodeBlocksOption = { name: "codeBlocks", type: "boolean", default: false, }; const rehypeGithubAlertsOption = { name: "githubAlerts", type: "boolean", default: false, }; export const ConfluenceSync = class ConfluenceSync { _confluencePageTransformer; _confluenceSyncPages; _urlOption; _apiPrefixOption; _personalAccessTokenOption; _spaceKeyOption; _rootPageIdOption; _rootPageNameOption; _noticeMessageOption; _noticeTemplateOption; _authenticationOption; _dryRunOption; _initialized = false; _logger; _modeOption; _rehypeCodeBlocksOption; _rehypeGithubAlertsOption; constructor({ config, rehypeConfig, logger, mode }) { this._urlOption = config.addOption(urlOption); this._apiPrefixOption = config.addOption(apiPrefixOption); this._personalAccessTokenOption = config.addOption(personalAccessTokenOption); this._spaceKeyOption = config.addOption(spaceKeyOption); this._rootPageIdOption = config.addOption(rootPageIdOption); this._rootPageNameOption = config.addOption(rootPageNameOption); this._noticeMessageOption = config.addOption(noticeMessageOption); this._noticeTemplateOption = config.addOption(noticeTemplateOption); this._authenticationOption = config.addOption(authenticationOption); this._dryRunOption = config.addOption(dryRunOption); this._rehypeCodeBlocksOption = rehypeConfig.addOption(rehypeCodeBlocksOption); this._rehypeGithubAlertsOption = rehypeConfig.addOption(rehypeGithubAlertsOption); this._modeOption = mode; this._logger = logger; } async sync(confluencePages) { await this._init(); this._logger.debug(`confluence.url option is ${this._urlOption.value}`); this._logger.debug(`confluence.apiPrefix option is ${this._apiPrefixOption.value}`); this._logger.debug(`confluence.spaceKey option is ${this._spaceKeyOption.value}`); this._logger.debug(`confluence.dryRun option is ${this._dryRunOption.value}`); this._logger.info(`Confluence pages to sync: ${confluencePages.map((page) => page.title).join(", ")}`); this._logger.silly(`Extended version: ${JSON.stringify(confluencePages, null, 2)}`); const pages = await this._confluencePageTransformer.transform(confluencePages); this._checkConfluencePagesIds(pages); this._logger.info(`Confluence pages to sync after transformation: ${pages .map((page) => page.title) .join(", ")}`); this._logger.silly(`Extended version: ${JSON.stringify(pages, null, 2)}`); await this._confluenceSyncPages.sync(pages); } _init() { if (!this._initialized) { if (!this._urlOption.value) { throw new Error("Confluence URL is required. Please set confluence.url option."); } if (!this._spaceKeyOption.value) { throw new Error("Confluence space id is required. Please set confluence.spaceId option."); } if (!this._rootPageIdOption.value && this._modeOption.value === SyncModes.TREE) { throw new Error("Confluence root page id is required for TREE sync mode. Please set confluence.rootPageId option."); } if (this._personalAccessTokenOption.value) { this._logger.warn("The 'personalAccessToken' option is deprecated and will be removed in future versions. Please use the 'authentication' option instead."); } this._confluencePageTransformer = new ConfluencePageTransformer({ noticeMessage: this._noticeMessageOption.value, noticeTemplate: this._noticeTemplateOption.value, rootPageName: this._rootPageNameOption.value, spaceKey: this._spaceKeyOption.value, logger: this._logger.namespace("transformer"), rehype: { codeBlocks: this._rehypeCodeBlocksOption.value, githubAlerts: this._rehypeGithubAlertsOption.value, }, }); this._confluenceSyncPages = new ConfluenceSyncPages({ url: this._urlOption.value, apiPrefix: this._apiPrefixOption.value, personalAccessToken: this._personalAccessTokenOption.value, authentication: this._authenticationOption.value, spaceId: this._spaceKeyOption.value, rootPageId: this._rootPageIdOption.value, logLevel: this._logger.level, dryRun: this._dryRunOption.value, syncMode: this._modeOption.value, }); this._initialized = true; } } _checkConfluencePagesIds(pages) { if (!this._rootPageIdOption.value && this._modeOption.value === SyncModes.FLAT) { const allPagesHaveId = pages.every(({ id }) => isStringWithLength(id)); if (!allPagesHaveId) { throw new PageIdRequiredException(); } } } };