| | |
| | |
| | |
| | |
| | |
| | import fs from 'fs' |
| | import path from 'path' |
| | import _ from 'lodash' |
| |
|
| | import frontmatter from '@/frame/lib/read-frontmatter' |
| | import getApplicableVersions from '@/versions/lib/get-applicable-versions' |
| | import { allVersions, getDocsVersion } from '@/versions/lib/all-versions' |
| | import { REST_DATA_DIR, REST_SCHEMA_FILENAME } from '../lib/index' |
| | import { nonAutomatedRestPaths } from '../lib/config' |
| | import { deprecated } from '@/versions/lib/enterprise-server-releases' |
| | import walkFiles from '@/workflows/walk-files' |
| |
|
| | type CheckObject = Record<string, Record<string, string[]>> |
| |
|
| | type DifferenceResult = Record<string, string[]> |
| |
|
| | type ErrorMessages = Record<string, Record<string, { contentDir: string[]; openAPI: string[] }>> |
| |
|
| | export async function getDiffOpenAPIContentRest(): Promise<ErrorMessages> { |
| | const contentFiles = getAutomatedMarkdownFiles('content/rest') |
| | |
| | const checkContentDir = await createCheckContentDirectory(contentFiles) |
| |
|
| | |
| | const openAPISchemaCheck = await createOpenAPISchemasCheck() |
| |
|
| | |
| | const differences = getDifferences(openAPISchemaCheck, checkContentDir) |
| | const errorMessages: ErrorMessages = {} |
| |
|
| | if (Object.keys(differences).length > 0) { |
| | for (const schemaName in differences) { |
| | errorMessages[schemaName] = {} |
| |
|
| | for (const category of differences[schemaName]) { |
| | errorMessages[schemaName][category] = { |
| | contentDir: checkContentDir[schemaName][category], |
| | openAPI: openAPISchemaCheck[schemaName][category], |
| | } |
| | } |
| | } |
| | } |
| |
|
| | return errorMessages |
| | } |
| |
|
| | async function createOpenAPISchemasCheck(): Promise<CheckObject> { |
| | const openAPICheck = createCheckObj() |
| | const restDirectory = fs |
| | .readdirSync(REST_DATA_DIR) |
| | .filter((dir) => !dir.endsWith('.json')) |
| | |
| | .filter((dir) => !dir.includes(deprecated[0])) |
| |
|
| | for (const dir of restDirectory) { |
| | const filename = path.join(REST_DATA_DIR, dir, REST_SCHEMA_FILENAME) |
| | const fileSchema = JSON.parse(fs.readFileSync(filename, 'utf8')) |
| | const categories = Object.keys(fileSchema).sort() |
| | const version = getDocsVersion(dir) |
| |
|
| | for (const category of categories) { |
| | const subcategories = Object.keys(fileSchema[category]) as string[] |
| | if (isApiVersioned(version)) { |
| | for (const apiVersion of getOnlyApiVersions(version)) { |
| | openAPICheck[apiVersion][category] = subcategories.sort() |
| | } |
| | } else { |
| | openAPICheck[version][category] = subcategories.sort() |
| | } |
| | } |
| | } |
| |
|
| | return openAPICheck |
| | } |
| |
|
| | async function createCheckContentDirectory(contentFiles: string[]): Promise<CheckObject> { |
| | const checkContent = createCheckObj() |
| |
|
| | for (const filename of contentFiles) { |
| | const { data } = frontmatter(await fs.promises.readFile(filename, 'utf8')) |
| | const applicableVersions = getApplicableVersions(data?.versions, filename) |
| | const splitPath = filename.split('/') |
| | const subCategory = splitPath[splitPath.length - 1].replace('.md', '') |
| | const category = |
| | splitPath[splitPath.length - 2] === 'rest' ? subCategory : splitPath[splitPath.length - 2] |
| | |
| | const allCompleteVersions = applicableVersions.flatMap((version) => { |
| | return isApiVersioned(version) |
| | ? allVersions[version].apiVersions.map( |
| | (apiVersion) => `${allVersions[version].version}.${apiVersion}`, |
| | ) |
| | : version |
| | }) |
| |
|
| | for (const version of allCompleteVersions) { |
| | if (!checkContent[version][category]) { |
| | checkContent[version][category] = [subCategory] |
| | } else { |
| | checkContent[version][category].push(subCategory) |
| | } |
| | checkContent[version][category].sort() |
| | } |
| | } |
| |
|
| | return checkContent |
| | } |
| |
|
| | function isApiVersioned(version: string): boolean { |
| | return allVersions[version] && allVersions[version].apiVersions.length > 0 |
| | } |
| |
|
| | function getOnlyApiVersions(version: string): string[] { |
| | return allVersions[version].apiVersions.map( |
| | (apiVersion) => `${allVersions[version].version}.${apiVersion}`, |
| | ) |
| | } |
| |
|
| | function createCheckObj(): CheckObject { |
| | const versions: CheckObject = {} |
| | for (const version of Object.keys(allVersions)) { |
| | if (isApiVersioned(version)) { |
| | for (const apiVersion of getOnlyApiVersions(version)) { |
| | versions[apiVersion] = {} |
| | } |
| | } else { |
| | versions[`${allVersions[version].version}`] = {} |
| | } |
| | } |
| |
|
| | return versions |
| | } |
| |
|
| | function getDifferences( |
| | openAPISchemaCheck: CheckObject, |
| | contentCheck: CheckObject, |
| | ): DifferenceResult { |
| | const differences: DifferenceResult = {} |
| | for (const version in openAPISchemaCheck) { |
| | const diffOpenApiContent = difference(openAPISchemaCheck[version], contentCheck[version]) |
| | if (Object.keys(diffOpenApiContent).length > 0) differences[version] = diffOpenApiContent |
| | } |
| |
|
| | return differences |
| | } |
| |
|
| | function difference(obj1: Record<string, string[]>, obj2: Record<string, string[]>): string[] { |
| | const diff = Object.keys(obj1).reduce((result, key) => { |
| | if (!Object.prototype.hasOwnProperty.call(obj2, key)) { |
| | result.push(key) |
| | } else if (_.isEqual(obj1[key], obj2[key])) { |
| | const resultKeyIndex = result.indexOf(key) |
| | result.splice(resultKeyIndex, 1) |
| | } |
| | return result |
| | }, Object.keys(obj2)) |
| |
|
| | return diff |
| | } |
| |
|
| | export function getAutomatedMarkdownFiles(rootDir: string): string[] { |
| | return walkFiles(rootDir, '.md') |
| | .filter((file) => !file.includes('index.md')) |
| | .filter((file) => !nonAutomatedRestPaths.some((excludePath) => file.includes(excludePath))) |
| | } |
| |
|