/* eslint-disable @typescript-eslint/no-explicit-any */ import fs from 'node:fs/promises' import url from 'node:url' import path from 'node:path' import { downloadFromGitHub } from '../utils/index.js' import { buildPreface } from '../utils/helpers.js' import reporters3rdParty from './3rd-party/reporters.json' with { type: 'json' } import services3rdParty from './3rd-party/services.json' with { type: 'json' } import api3rdParty from './3rd-party/api.json' with { type: 'json' } interface Plugin { packageName: string title: string githubUrl: string npmUrl: string branch?: string location?: string locations: string[] suppressBuildInfo?: boolean } const docsFixes: Record string)> = { '@sap_oss/wdio-qmate-service' : (docs: string) => docs .replace('Benjamin Warth ', '[Benjamin Warth](mailto:benjamin.warth@sap.com)') .replace('Georgios Treska ', '[Georgios Treska](mailto:georgios.treska@sap.com)') .replace('Marvin Grüßinger ', '[Marvin Grüßinger](mailto:marvin.gruessinger@sap.com)'), 'wdio-ui5-service': (docs: string) => docs .replace('', '[https://ui5-community.github.io/wdi5/](https://ui5-community.github.io/wdi5/)') .replace('Roadmap: ', '[Roadmap](https://github.com/orgs/ui5-community/projects/2/views/1)'), 'wdio-intercept-service': (docs: string) => docs .replace('browser.excludeUrls(urlRegexes: (string | RegExp)[])', '`browser.excludeUrls(urlRegexes: (string | RegExp)[])`') .replace('browser.assertRequests({ orderBy?: \'START\' | \'END\' }?: = {})', '`browser.assertRequests({ orderBy?: \'START\' | \'END\' }?: = {})`') .replace('browser.assertExpectedRequestsOnly({ inOrder?: boolean, orderBy?: \'START\' | \'END\' }?: = {})', "`browser.assertExpectedRequestsOnly({ inOrder?: boolean, orderBy?: 'START' | 'END' }?: = {})`") .replace('browser.getRequest(index: number, { includePending?: boolean, orderBy?: \'START\' | \'END\' }?: = {})', "`browser.getRequest(index: number, { includePending?: boolean, orderBy?: 'START' | 'END' }?: = {})`") .replace('browser.getRequests({ includePending?: boolean, orderBy?: \'START\' | \'END\' }?: = {})', "`browser.getRequests({ includePending?: boolean, orderBy?: 'START' | 'END' }?: = {})`"), 'wdio-reportportal-reporter': (docs: string) => docs .replace('', '[http://reportportal.io/](http://reportportal.io/)') } const __dirname = path.dirname(url.fileURLToPath(import.meta.url)) const plugins = [{ category: 'docs', namePlural: 'Reporter', nameSingular: 'Reporter', packages3rdParty: reporters3rdParty }, { category: 'docs', namePlural: 'Services', nameSingular: 'Service', packages3rdParty: services3rdParty }, { category: 'api', namePlural: 'Testrunner', nameSingular: '', packages3rdParty: api3rdParty }] const githubReadme = 'README.md' const readmeHeaderLines = 9 const readmeHeaders = ['===', '# '] const readmeBadges = ['https://badge', 'https://travis-ci.org/'] const PROJECT_ROOT_DIR = path.join(__dirname, '..', '..') const DOCS_ROOT_DIR = path.join(PROJECT_ROOT_DIR, 'website', 'docs') /** * Generate docs for 3rd party reporters and services * @param {object} sidebars website/sidebars */ export async function generate3rdPartyDocs (sidebars: any) { for (const { category, namePlural, nameSingular, packages3rdParty } of plugins) { const categoryDir = path.join(DOCS_ROOT_DIR, category === 'api' ? 'api' : '') await fs.mkdir(categoryDir, { recursive: true }) const sidebar = sidebars[category] const items: string[] = [] for (const { packageName, title, githubUrl, npmUrl, suppressBuildInfo, locations, location = githubReadme, branch = 'main' } of packages3rdParty as Plugin[]) { const readme = locations ? await Promise.all(locations.map((l) => downloadFromGitHub(githubUrl, branch, l))) .then((readmes) => readmes.join('\n')) : await downloadFromGitHub(githubUrl, branch, location) const id = `${packageName}`.replace(/@/g, '').replace(/\//g, '-') const doc = normalizeDoc( readme, githubUrl, branch, buildPreface(id, title, nameSingular, `${githubUrl}/edit/${branch}/${location}`), suppressBuildInfo ? [] : buildInfo(packageName, githubUrl, npmUrl), packageName ) await fs.writeFile(path.join(categoryDir, `_${id}.md`), doc, { encoding: 'utf-8' }) if (namePlural === 'Testrunner') { return } console.log(`Generated docs for ${packageName}`) items.push(category === 'api' ? `${category}/${id}` : id) } const section = sidebar.find((s: any) => s.label === namePlural) section.items.push(...items) } } /** * Removes header from README.md * @param {string} readme readme content * @param {string} githubUrl repo url * @param {string} branch repo branch * @param {string} preface docusaurus header * @param {string} repoInfo repoInfo * @return {string} readme content without header */ function normalizeDoc(readme: string, githubUrl: string, branch: string, preface: string[], repoInfo: string[], packageName: string) { /** * remove badges */ let readmeArr = readme.split('\n').filter(row => !readmeBadges.some(b => row.includes(b))) /** * get index of header to remove further */ let sliceIdx = 0 for (let i = 0; i < readmeHeaderLines && sliceIdx === 0; i++) { if (typeof readmeArr[i] === 'string' && readmeHeaders.some(x => readmeArr[i].startsWith(x))) { sliceIdx = i + 1 } } readmeArr = readmeArr.slice(sliceIdx) /** * prepend additional # to header rows * and add path to links */ readmeArr.forEach((row, idx) => { /** * prepend # to header rows */ if (row.match(/^(# )\1* /)) { readmeArr[idx] = `#${row}` } /** * transform partial to full links * match links like [foo](bar). `stringInParentheses` would be `bar` * do not match [foo](http://bar), [foo](#bar) */ const mdLinks = row.match(/\[([^\]]+)\]\(([^)"]+)(?: "([^"]+)")?\)/g) || [] for (const mdLink of mdLinks) { const urlMatcher = mdLink.match(/\[([^[]+)\]\((.*)\)/) if (!urlMatcher) { continue } const stringInParentheses = urlMatcher[2] const url = ( stringInParentheses.startsWith('http') || stringInParentheses.startsWith('#') ) ? stringInParentheses : `${githubUrl}/blob/${branch}/${stringInParentheses}` readmeArr[idx] = readmeArr[idx].replace(`](${stringInParentheses})`, `](${url})`) } }) /** * apply custom fixes */ if (docsFixes[packageName]) { console.log(`Applying custom fixes for ${packageName}`) readmeArr = [docsFixes[packageName](readmeArr.join('\n'))] } return [...preface, ...repoInfo, ...readmeArr] .join('\n') .replace(/
/g, '
') } /** * 3rd party package info * @param {string} packageName package name * @param {string} githubUrl GitHub url * @param {string} npmUrl npm url */ function buildInfo(packageName: string, githubUrl: string, npmUrl: string) { return [ `> ${packageName} is a 3rd party package, for more information please see [GitHub](${githubUrl}) | [npm](${npmUrl})` ] }