@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
142 lines (141 loc) • 5.3 kB
JavaScript
// SPDX-FileCopyrightText: 2024 Telefónica Innovación Digital
// SPDX-License-Identifier: Apache-2.0
import { resolve } from "path";
import { Config } from "@mocks-server/config";
import { Logger } from "@mocks-server/logger";
import { SyncModes } from "@telefonica/confluence-sync";
import { ConfluenceSync } from "./confluence/ConfluenceSync.js";
import { MarkdownDocuments } from "./docusaurus/DocusaurusPages.js";
const MODULE_NAME = "markdown-confluence-sync";
const MARKDOWN_NAMESPACE = "markdown";
const CONFLUENCE_NAMESPACE = "confluence";
const REHYPE_CONFIG_NAMESPACE = "rehype";
const DEFAULT_CONFIG = {
readArguments: false,
readEnvironment: false,
readFile: false,
};
const logLevelOption = {
name: "logLevel",
type: "string",
default: "info",
};
const modeOption = {
name: "mode",
type: "string",
default: SyncModes.TREE,
};
const filesPatternOption = {
name: "filesPattern",
type: "string",
};
const filesIgnoreOption = {
name: "ignore",
type: "array",
};
const filesMetadataOption = {
name: "filesMetadata",
type: "array",
};
const contentPreprocessorOption = {
name: "preprocessor",
type: "unknown",
};
const dryRunOption = {
name: "dryRun",
type: "boolean",
default: false,
description: "Process markdown files without sending them to confluence-sync",
};
export const MarkdownConfluenceSync = class MarkdownConfluenceSync {
_markdownDocuments;
_confluenceSync;
_configuration;
_initialized = false;
_config;
_logger;
_logLevelOption;
_modeOption;
_filesPatternOption;
_filesMetadataOption;
_filesIgnoreOption;
_contentPreprocessorOption;
_dryRunOption;
_cwd;
constructor(config) {
const cwd = config?.cwd || process.env.MARKDOWN_CONFLUENCE_SYNC_CWD;
this._cwd = cwd ? resolve(process.cwd(), cwd) : process.cwd();
this._config = config;
if (!this._config) {
throw new Error("Please provide configuration");
}
this._configuration = new Config({
moduleName: MODULE_NAME,
});
this._logger = new Logger(MODULE_NAME);
this._logLevelOption = this._configuration.addOption(logLevelOption);
this._modeOption = this._configuration.addOption(modeOption);
this._filesPatternOption = this._configuration.addOption(filesPatternOption);
this._filesMetadataOption = this._configuration.addOption(filesMetadataOption);
this._filesIgnoreOption = this._configuration.addOption(filesIgnoreOption);
this._contentPreprocessorOption = this._configuration.addOption(contentPreprocessorOption);
this._dryRunOption = this._configuration.addOption(dryRunOption);
const markdownLogger = this._logger.namespace(MARKDOWN_NAMESPACE);
const confluenceConfig = this._configuration.addNamespace(CONFLUENCE_NAMESPACE);
const rehypeConfig = this._configuration.addNamespace(REHYPE_CONFIG_NAMESPACE);
const confluenceLogger = this._logger.namespace(CONFLUENCE_NAMESPACE);
this._markdownDocuments = new MarkdownDocuments({
config: this._configuration,
logger: markdownLogger,
mode: this._modeOption,
filesPattern: this._filesPatternOption,
filesIgnore: this._filesIgnoreOption,
filesMetadata: this._filesMetadataOption,
contentPreprocessor: this._contentPreprocessorOption,
cwd: this._cwd,
});
this._confluenceSync = new ConfluenceSync({
config: confluenceConfig,
rehypeConfig: rehypeConfig,
logger: confluenceLogger,
mode: this._modeOption,
});
}
async sync() {
await this._init();
const pages = await this._markdownDocuments.read();
const convertedPages = this._markdownPagesToConfluencePages(pages);
const dryRun = this._dryRunOption.value;
if (dryRun) {
this._logger.info("Dry run mode is enabled. No changes will be made to Confluence.");
return;
}
await this._confluenceSync.sync(convertedPages);
}
async _init() {
if (!this._initialized) {
// NOTE: We delete the cwd property from the configuration because it can be configured only programmatically. It is not a configuration option.
const configToLoad = {
...this._config,
cwd: undefined,
config: {
...DEFAULT_CONFIG,
...{
fileSearchFrom: this._cwd,
fileSearchStop: this._cwd,
},
...this._config.config,
},
};
delete configToLoad.cwd;
this._logger.debug(`Initializing with config: ${JSON.stringify(configToLoad)}`);
await this._configuration.load(configToLoad);
this._logger.setLevel(this._logLevelOption.value);
this._initialized = true;
}
}
_markdownPagesToConfluencePages(markdownDocuments) {
this._logger.info(`Converting ${markdownDocuments.length} markdown documents to Confluence pages...`);
return markdownDocuments;
}
};