(node: Node, config: Config)
| 131 | } |
| 132 | |
| 133 | export default function validator(node: Node, config: Config) { |
| 134 | const schema = node.findSchema(config); |
| 135 | const errors: ValidationError[] = [...(node.errors || [])]; |
| 136 | |
| 137 | if (!schema) { |
| 138 | errors.push({ |
| 139 | id: node.tag ? 'tag-undefined' : 'node-undefined', |
| 140 | level: 'critical', |
| 141 | message: node.tag |
| 142 | ? `Undefined tag: '${node.tag}'` |
| 143 | : `Undefined node: '${node.type}'`, |
| 144 | }); |
| 145 | |
| 146 | return errors; |
| 147 | } |
| 148 | |
| 149 | if (schema.inline != undefined && node.inline !== schema.inline) |
| 150 | errors.push({ |
| 151 | id: 'tag-placement-invalid', |
| 152 | level: 'critical', |
| 153 | message: `'${node.tag}' tag should be ${ |
| 154 | schema.inline ? 'inline' : 'block' |
| 155 | }`, |
| 156 | }); |
| 157 | |
| 158 | if (schema.selfClosing && node.children.length > 0) |
| 159 | errors.push({ |
| 160 | id: 'tag-selfclosing-has-children', |
| 161 | level: 'critical', |
| 162 | message: `'${node.tag}' tag should be self-closing`, |
| 163 | }); |
| 164 | |
| 165 | const attributes = { |
| 166 | ...globalAttributes, |
| 167 | ...schema.attributes, |
| 168 | }; |
| 169 | |
| 170 | for (const key of Object.keys(node.slots)) { |
| 171 | const slot = schema.slots?.[key]; |
| 172 | if (!slot) |
| 173 | errors.push({ |
| 174 | id: 'slot-undefined', |
| 175 | level: 'error', |
| 176 | message: `Invalid slot: '${key}'`, |
| 177 | }); |
| 178 | } |
| 179 | |
| 180 | for (let [key, value] of Object.entries(node.attributes)) { |
| 181 | const attrib = attributes[key]; |
| 182 | |
| 183 | if (!attrib) { |
| 184 | errors.push({ |
| 185 | id: 'attribute-undefined', |
| 186 | level: 'error', |
| 187 | message: `Invalid attribute: '${key}'`, |
| 188 | }); |
| 189 | |
| 190 | continue; |
no test coverage detected
searching dependent graphs…