|
| 1 | +const fetch = require('node-fetch') |
1 | 2 | const fs = require('fs')
|
2 | 3 | const YAML = require('yaml')
|
3 | 4 |
|
| 5 | +async function fetchScopeTable(uuid, title, path) { |
| 6 | + const response = await fetch( |
| 7 | + `https://compliance.sovereignit.cloud/markdown/scope/${uuid}` |
| 8 | + ) |
| 9 | + var text = await response.text() |
| 10 | + text = `# ${title}\n\n${text}` |
| 11 | + fs.writeFileSync(path, text, 'utf8') |
| 12 | +} |
| 13 | + |
4 | 14 | // how many outdated versions of any scope to include
|
5 | 15 | const MAX_OLD = 1
|
6 | 16 |
|
7 | 17 | const filenames = fs
|
8 |
| - .readdirSync('standards/') |
9 |
| - .filter((fn) => fn.startsWith('scs-') && fn.endsWith('.yaml')) |
| 18 | + .readdirSync('standards/') |
| 19 | + .filter((fn) => fn.startsWith('scs-') && fn.endsWith('.yaml')) |
10 | 20 |
|
11 | 21 | const scopes = filenames.map((filename) => {
|
12 |
| - return { |
13 |
| - ...YAML.parseDocument(fs.readFileSync(`standards/${filename}`, 'utf8')).toJSON(), |
14 |
| - filename, |
15 |
| - id: filename.substring(0, filename.length - 5), |
16 |
| - } |
| 22 | + return { |
| 23 | + ...YAML.parseDocument( |
| 24 | + fs.readFileSync(`standards/${filename}`, 'utf8') |
| 25 | + ).toJSON(), |
| 26 | + filename, |
| 27 | + id: filename.substring(0, filename.length - 5) |
| 28 | + } |
17 | 29 | })
|
18 | 30 |
|
19 | 31 | const today = new Date().toISOString().slice(0, 10)
|
20 | 32 |
|
21 | 33 | const sidebarItems = scopes.map((scope) => {
|
22 |
| - const matrix = {} |
23 |
| - const versionsShown = {} |
24 |
| - var numOld = 0 |
25 |
| - var modules = {} |
26 |
| - scope.modules.forEach((module) => { |
27 |
| - modules[module.id] = module |
28 |
| - module.prettyName = module.id.startsWith('scs-') ? `${module.id}: ${module.name}` : module.name |
29 |
| - }) |
30 |
| - scope.timeline.sort((a, b) => b.date.localeCompare(a.date)) |
31 |
| - const current = scope.timeline.filter((entry) => entry.date <= today) |
32 |
| - const lookup = current.length ? current[0].versions : {} |
33 |
| - // sort in descending order, so we get the MAX_OLD most recent obsolete versions |
34 |
| - scope.versions.sort((a, b) => b.version.localeCompare(a.version)); |
35 |
| - scope.versions.forEach((version) => { |
36 |
| - version.state = lookup[version.version] || 'deprecated' |
37 |
| - version.isStable = version.stabilized_at !== undefined && version.stabilized_at <= today |
38 |
| - version.isEffective = version.state == 'effective' |
39 |
| - if (['warn', 'effective', 'draft'].indexOf(version.state) == -1) { |
40 |
| - numOld += 1 |
41 |
| - if (numOld > MAX_OLD) return |
42 |
| - } |
43 |
| - if (version.include === undefined) return |
44 |
| - versionsShown[version.version] = version |
45 |
| - version.include.forEach((include) => { |
46 |
| - if (include.ref === undefined) { |
47 |
| - include = {ref: include, parameters: {}} |
48 |
| - } |
49 |
| - const module = modules[include.ref] |
50 |
| - if (matrix[module.id] === undefined) { |
51 |
| - matrix[module.id] = { |
52 |
| - name: module.prettyName, |
53 |
| - columns: {}, |
54 |
| - url: module.url, |
55 |
| - } |
56 |
| - } |
57 |
| - matrix[module.id].columns[version.version] = { |
58 |
| - parameters: include.parameters, |
59 |
| - } |
60 |
| - }) |
61 |
| - }) |
62 |
| - |
63 |
| - const rows = Object.values(matrix) |
64 |
| - const columns = Object.keys(versionsShown) |
65 |
| - rows.sort((a, b) => a.name.localeCompare(b.name)); |
66 |
| - columns.sort((a, b) => a.localeCompare(b)); |
67 |
| - |
68 |
| - lines = [`# ${scope.name} |
69 |
| -
|
70 |
| -Note that the state _Stable_ is shown here if _stabilized at_ is in the future, whereas _Effective_ is shown here if _stabilized at_ is in the past and _deprecated at_ is unset or in the future. |
71 |
| -`] |
72 |
| - lines.push('| Scope versions -> | ' + columns.join(' | ') + ' |') |
73 |
| - lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |') |
74 |
| - lines.push('| State | ' + columns.map((c) => versionsShown[c].state).join(' | ') + ' |') |
75 |
| - lines.push('| Stabilized at | ' + columns.map((c) => versionsShown[c].stabilized_at || '').join(' | ') + ' |') |
76 |
| - // lines.push('| Deprecated at | ' + columns.map((c) => versionsShown[c].deprecated_at || '').join(' | ') + ' |') |
77 |
| - // md doesn't allow intermediate header rows |
78 |
| - // lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |') |
79 |
| - lines.push('| **Modules** | ' + columns.map((c) => ' '.repeat(c.length)).join(' | ') + ' |') |
80 |
| - // md doesn't allow intermediate header rows |
81 |
| - // lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |') |
82 |
| - rows.forEach((row) => { |
83 |
| - lines.push(`| [${row.name}](${row.url}) | ` + columns.map((c) => row.columns[c]).map((col) => { |
84 |
| - if (col === undefined) { |
85 |
| - // this version of the cert does not include this standard |
86 |
| - return '' |
87 |
| - } |
88 |
| - let params = Object.entries(col.parameters || {}).map((entry) => |
89 |
| - entry[1].startsWith('https://') ? `[${entry[0]}](${entry[1]})` : `${entry[0]}=${entry[1]}` |
90 |
| - ).join(', ') |
91 |
| - if (params.length) { |
92 |
| - params = ` (${params})` |
93 |
| - } |
94 |
| - return `X${params}` |
95 |
| - }).join(' | ') + ' |') |
96 |
| - }) |
97 |
| - lines.push('') // file should end with a single newline character |
98 |
| - fs.writeFileSync(`standards/${scope.id}.md`, lines.join('\n'), 'utf8') |
99 |
| - |
100 |
| - const state = columns.filter((c) => versionsShown[c].isEffective).length ? '📜' : '✏️' |
101 |
| - return { |
102 |
| - type: 'doc', |
103 |
| - label: scope.name, |
104 |
| - id: scope.id, |
| 34 | + fetchScopeTable(scope.uuid, scope.name, `standards/${scope.id}.md`).catch( |
| 35 | + (e) => { |
| 36 | + console.log(e) |
105 | 37 | }
|
| 38 | + ) |
| 39 | + return { |
| 40 | + type: 'doc', |
| 41 | + label: scope.name, |
| 42 | + id: scope.id |
| 43 | + } |
106 | 44 | })
|
107 | 45 |
|
108 | 46 | var newSidebars = `module.exports = ${JSON.stringify(sidebarItems, null, ' ')}`
|
|
0 commit comments