forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-open-api-schema.js
executable file
·168 lines (139 loc) · 5.42 KB
/
test-open-api-schema.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env node
// [start-readme]
//
// Run this script to check if OpenAPI operations match versions in content/rest operations
//
// [end-readme]
import fs from 'fs'
import path from 'path'
import _ from 'lodash'
import frontmatter from '../../lib/read-frontmatter.js'
import getApplicableVersions from '../../lib/get-applicable-versions.js'
import { allVersions, getDocsVersion } from '../../lib/all-versions.js'
const contentFiles = []
export async function getDiffOpenAPIContentRest() {
const contentPath = path.join(process.cwd(), 'content/rest')
// Recursively go through the content/rest directory and add all categories/subcategories to contentFiles
throughDirectory(contentPath)
// Creating the categories/subcategories based on the current content directory
const checkContentDir = await createCheckContentDirectory(contentFiles)
// Create categories/subcategories from OpenAPI Schemas
const openAPISchemaCheck = await createOpenAPISchemasCheck()
// Get Differences between categories/subcategories from dereferenced schemas and the content/rest directory frontmatter versions
const differences = getDifferences(openAPISchemaCheck, checkContentDir)
const errorMessages = {}
if (Object.keys(differences).length > 0) {
for (const schemaName in differences) {
errorMessages[schemaName] = {}
differences[schemaName].forEach((category) => {
if (!errorMessages[schemaName]) errorMessages[schemaName] = category
errorMessages[schemaName][category] = {
contentDir: checkContentDir[schemaName][category],
openAPI: openAPISchemaCheck[schemaName][category],
}
})
}
}
return errorMessages
}
async function createOpenAPISchemasCheck() {
const schemasPath = path.join(process.cwd(), 'lib/rest/static/decorated')
const openAPICheck = createCheckObj()
const schemas = fs.readdirSync(schemasPath)
schemas.forEach((file) => {
const fileData = fs.readFileSync(path.join(schemasPath, file))
const fileSchema = JSON.parse(fileData.toString())
const categories = Object.keys(fileSchema).sort()
const version = getDocsVersion(file.split(/.json/)[0])
categories.forEach((category) => {
const subcategories = Object.keys(fileSchema[category])
if (isApiVersioned(version)) {
getOnlyApiVersions(version).forEach(
(apiVersion) => (openAPICheck[apiVersion][category] = subcategories.sort())
)
} else {
openAPICheck[version][category] = subcategories.sort()
}
})
})
return openAPICheck
}
async function createCheckContentDirectory(contentFiles) {
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]
// All versions with appended calendar date versions if it exists
const allCompleteVersions = applicableVersions.flatMap((version) => {
return isApiVersioned(version)
? allVersions[version].apiVersions.map(
(apiVersion) => `${allVersions[version].version}.${apiVersion}`
)
: version
})
allCompleteVersions.forEach((version) => {
!checkContent[version][category]
? (checkContent[version][category] = [subCategory])
: checkContent[version][category].push(subCategory)
checkContent[version][category].sort()
})
}
return checkContent
}
function isApiVersioned(version) {
return allVersions[version] && allVersions[version].apiVersions.length > 0
}
function getOnlyApiVersions(version) {
return allVersions[version].apiVersions.map(
(apiVersion) => `${allVersions[version].version}.${apiVersion}`
)
}
function createCheckObj() {
const versions = {}
Object.keys(allVersions).forEach((version) => {
isApiVersioned(version)
? getOnlyApiVersions(version).forEach((apiVersion) => (versions[apiVersion] = {}))
: (versions[`${allVersions[version].version}`] = {})
})
return versions
}
function getDifferences(openAPISchemaCheck, contentCheck) {
const differences = {}
for (const version in openAPISchemaCheck) {
const diffOpenApiContent = difference(openAPISchemaCheck[version], contentCheck[version])
if (Object.keys(diffOpenApiContent).length > 0) differences[version] = diffOpenApiContent
}
return differences
}
function throughDirectory(directory) {
fs.readdirSync(directory).forEach((file) => {
const absolute = path.join(directory, file)
if (fs.statSync(absolute).isDirectory()) {
return throughDirectory(absolute)
} else if (
!directory.includes('rest/guides') &&
!directory.includes('rest/overview') &&
!file.includes('index.md') &&
!file.includes('quickstart.md') &&
!file.includes('README.md')
) {
return contentFiles.push(absolute)
}
})
}
function difference(obj1, obj2) {
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
}