|
| 1 | +import fs from 'fs'; |
| 2 | +import assert from 'assert'; |
| 3 | + |
| 4 | +import { |
| 5 | + remarkParse, |
| 6 | + unified, |
| 7 | +} from '../../tools/doc/deps.mjs'; |
| 8 | + |
| 9 | +const ignore = ['deprecations.md', 'documentation.md']; |
| 10 | + |
| 11 | +const docURL = new URL('../../doc/api/', import.meta.url); |
| 12 | +const docList = fs.readdirSync(docURL).filter(filename => !ignore.includes(filename)); |
| 13 | + |
| 14 | +for (const file of docList) { |
| 15 | + const fileURL = new URL(file, docURL); |
| 16 | + const tree = unified() |
| 17 | + .use(remarkParse) |
| 18 | + .parse(fs.readFileSync(fileURL)); |
| 19 | + |
| 20 | + for (let i = 0; i < tree.children.length; i++) { |
| 21 | + const { [i]: node, [i-1]: previousNode } = tree.children; |
| 22 | + if (node.type !== 'blockquote' || !node.children.length) continue; |
| 23 | + |
| 24 | + const paragraph = node.children[0]; |
| 25 | + if (paragraph.type !== 'paragraph' || !paragraph.children.length) continue; |
| 26 | + |
| 27 | + const text = paragraph.children[0]; |
| 28 | + if (text.type !== 'text' || !text.value.match(/^Stability: \d/)) continue; |
| 29 | + |
| 30 | + // Check that previous node type is one of: |
| 31 | + // * 'heading' |
| 32 | + // * 'html' (YAML block) |
| 33 | + // * 'paragraph' with a leading 'strong' node (pseudo-heading, eg. assert.equal) |
| 34 | + try { |
| 35 | + assert(previousNode.type === 'heading' || previousNode.type === 'html' || |
| 36 | + (previousNode.type === 'paragraph' && previousNode.children[0]?.type === 'strong'), |
| 37 | + 'Stability block must be the first content element under heading'); |
| 38 | + } catch (error) { |
| 39 | + const { line, column } = node.position.start; |
| 40 | + error.stack = error.stack.split('\n') |
| 41 | + .toSpliced(1, 0, ` at ${fileURL}:${line}:${column}`) |
| 42 | + .join('\n'); |
| 43 | + throw error; |
| 44 | + } |
| 45 | + } |
| 46 | +} |
0 commit comments