|
| 1 | +// Author: Chandan BN (c) 2021 |
| 2 | +// (1) convert CVE JSON schema to a mindmap |
| 3 | +// (2) creates a bundled schema |
| 4 | + |
| 5 | +var ml = require('markmap-lib') |
| 6 | +var Transformer = ml.Transformer; |
| 7 | +var fillTemplate = ml.fillTemplate; |
| 8 | +var sw = require('@cloudflare/json-schema-walker'); |
| 9 | +var rp = require('json-schema-ref-parser'); |
| 10 | +var fold = ['metrics', 'cvssV3_1', 'cvssV3_0', 'cvssV2_0', 'supportingMedia', |
| 11 | + 'tags', 'impacts', 'configurations', 'workarounds', 'solutions', 'exploits', |
| 12 | + 'timeline', 'credits', 'tags', 'taxonomyMappings', 'adp']; |
| 13 | +var symbol = { object: '', array: '[]', string: '', boolean: '☯', number: '', integer: '', undefined: '' }; |
| 14 | +const fs = require('fs'); |
| 15 | +var markmap = require('markmap-view'); |
| 16 | +const { Markmap, loadCSS, loadJS } = markmap; |
| 17 | + |
| 18 | +let forDeletion = ['properties', 'items', 'anyOf', 'allOf', 'oneOf']; |
| 19 | + |
| 20 | +var markdown = ''; |
| 21 | + |
| 22 | +function postfunc(obj, path, parent, parentPath) { |
| 23 | + if (path[1] && isNaN(path[1])) { |
| 24 | + var depth = parentPath.filter(i => !forDeletion.includes(i)).length; |
| 25 | + var reqStart = ""; |
| 26 | + var reqEnd = ""; |
| 27 | + |
| 28 | + if (parent?.required?.includes(path[1])) { |
| 29 | + reqStart = "<b>"; |
| 30 | + reqEnd = "</b>"; |
| 31 | + } |
| 32 | + markdown += (" ".repeat(depth) |
| 33 | + + "* " + reqStart + path[1] + reqEnd |
| 34 | + + ' ' + (fold.includes(path[1]) ? '<!-- fold -->' : '') |
| 35 | + + symbol[obj.type] |
| 36 | + + (obj.examples ? 'e.g., `' + obj.examples[0] + '`' : '') |
| 37 | + + (obj.enum ? '`' + obj.enum.join('` `') + '`' : '')) |
| 38 | + + '\n'; |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +async function schemaMindMap() { |
| 43 | + var cveSchema = await rp.dereference(process.argv[2]); |
| 44 | + markdown += "## Published <style>b {font-weight:800}</style>\n"; |
| 45 | + sw.schemaWalk(cveSchema.oneOf[0], postfunc, null); |
| 46 | + |
| 47 | + markdown += "## Reserved <style>b {font-weight:800}</style>\n"; |
| 48 | + sw.schemaWalk(cveSchema.oneOf[1], postfunc, null); |
| 49 | + |
| 50 | + markdown += "## Rejected <style>b {font-weight:800}</style>\n"; |
| 51 | + sw.schemaWalk(cveSchema.oneOf[2], postfunc, null); |
| 52 | + |
| 53 | + const transformer = new Transformer(); |
| 54 | + |
| 55 | + // transform markdown |
| 56 | + const { root, features } = transformer.transform(markdown); |
| 57 | + |
| 58 | + // get assets required by used features |
| 59 | + var assets = transformer.getUsedAssets(features); |
| 60 | + |
| 61 | + // create mindmap html |
| 62 | + var html = fillTemplate(root, assets); |
| 63 | + html = html.replace('<title>Markmap</title>', '<title>CVE JSON v5 Mindmap</title>') |
| 64 | + |
| 65 | + try { |
| 66 | + var cveSchemaBundle = await rp.bundle(process.argv[2]); |
| 67 | + fs.writeFileSync('docs/CVE_JSON_5.0_bundled.schema', JSON.stringify(cveSchemaBundle, null, 2)); |
| 68 | + fs.writeFileSync('docs/mindmap.html', html); |
| 69 | + } catch (err) { |
| 70 | + console.error(err) |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | +var markdown = "# CVE JSON Record\n"; |
| 75 | +schemaMindMap(); |
0 commit comments