-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmerge.js
More file actions
120 lines (110 loc) · 3.94 KB
/
merge.js
File metadata and controls
120 lines (110 loc) · 3.94 KB
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
/// Uses a main.json file to merge all json files in the same directory into a single openapi.json file
const fs = require("fs").promises;
const path = require("path");
// https://swagger.io/specification/
const ROOT_KEYS = [
'info',
'servers',
'paths',
'webhooks',
'components',
'security',
'tags',
'externalDocs'
];
(async () => {
// read main.json
const main = await readJson('main.json');
const output = { ...main };
for (const key of ROOT_KEYS) {
await processDir(output[key], key, '');
}
for (const key of ROOT_KEYS) {
await cleanUpRefs(output, key, true);
}
// write openapi.json
await fs.writeFile('openapi.json', JSON.stringify(output, null, 2), {
encoding: 'utf8',
flag: process.argv.includes('--force') ? 'w' : 'wx'
});
})();
async function processDir(output, path_, parent) {
console.debug(`Processing ${ path_ } ${ parent }`);
let dir;
try {
dir = await fs.readdir(path_);
} catch (e) {
console.log(e);
return;
}
if (!output) {
output = {};
}
for (const file of dir) {
const base = path.basename(file);
const joined = path.join(path_, file);
const stat = await fs.stat(joined);
if (stat.isDirectory()) {
let out;
if (parent === '') {
out = output;
} else {
if (!output[base]) {
output[base] = {};
}
out = output[base];
}
await processDir(out, joined, base);
} else {
const content = await readJson(joined);
// merge with main
if (!output[parent]) {
output[parent] = {};
}
console.debug(`Merging ${ file } into ${ parent }`);
await cleanUpRefs(content, path_);
output[parent][file.replace('.json', '')] = content;
}
}
}
async function cleanUpRefs(obj, contextPath0, strict = false, path = '',) {
let contextPath = contextPath0;
//console.debug(`Cleaning up refs ${ strict }`);
// console.log(path)
for (const key in obj) {
if (key === '$ref') {
console.log('context', contextPath)
const val = obj[key];
console.log(val);
if (strict) {
if (val.startsWith(`./${ contextPath }/`)) {
obj[key] = val.replace(`./${ contextPath }/`, `#/${ contextPath }/`).replace('.json', '');
console.debug('replace strict')
} else if (val.startsWith(`../${ contextPath }/`)) {
contextPath = contextPath.split('/').slice(0, -1).join('/');
obj[key] = val.replace(`../${ contextPath }/`, `#/${ contextPath }/`).replace('.json', '');
console.debug('replace strict up')
}
} else {
if (val.startsWith(`../`)) {
contextPath = contextPath.split('/').slice(0, -1).join('/');
obj[key] = val.replace(`../`, `#/${ contextPath }/`).replace('.json', '');
console.debug('replace up')
} else if (val.startsWith(`./`)) {
obj[key] = val.replace(`./`, `#/${ contextPath }/`).replace('.json', '');
console.debug('replace')
}
}
} else if (key === 'source' && path.includes('x-codeSamples') && typeof obj[key] === 'object' && '$ref' in obj[key]) {
console.log('codeSamples', key, obj, obj[key]);
const content = await fs.readFile(obj[key]['$ref'], 'utf8');
obj[key] = content;
} else if (typeof obj[key] === 'object') {
await cleanUpRefs(obj[key], contextPath0, strict, path + '.' + key);
}
}
}
async function readJson(file) {
console.debug(`Reading ${ file }`);
return JSON.parse(await fs.readFile(file, 'utf8'));
}