UNPKG

wikiparser-node

Version:

A Node.js parser for MediaWiki markup with AST

326 lines (325 loc) 7.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LintConfiguration = void 0; const base_1 = require("../base"); /* NOT FOR BRWOSER */ const constants_1 = require("../util/constants"); /* NOT FOR BROWSER END */ const dict = new Map([ [0, false], [1, 'warning'], [2, 'error'], [false, false], ['off', false], ['warning', 'warning'], ['error', 'error'], ]); const defaultLintRuleConfig = { 'bold-header': [ 1, { // b: 1, // strong: 1, }, ], 'format-leakage': [ 1, { // apostrophe: 1, }, ], 'fostered-content': [ 1, { // transclusion: 1, }, ], h1: [ 1, { // html: 1, }, ], 'illegal-attr': [ 2, { // tabindex: 2, // unknown: 2, // value: 2, }, ], 'insecure-style': 2, 'invalid-gallery': [ 2, { // extension: 2, // image: 2, parameter: 1, }, ], 'invalid-imagemap': [ 2, { // image: 2, // link: 2, }, ], 'invalid-invoke': [ 2, { // function: 2, // name: 2, }, ], 'invalid-isbn': 2, 'lonely-apos': [ 1, { // word: 1, }, ], 'lonely-bracket': [ 1, { // converter: 1, // double: 1, extLink: 2, // single: 1, }, ], 'lonely-http': [ 1, { // ISBN: 1, // PMID: 1, // RFC: 1, }, ], 'nested-link': [ 2, { // file: 2, }, ], 'no-arg': 1, 'no-duplicate': [ 2, { // attribute: 2, category: 1, id: 1, // imageParameter: 2, // parameter: 2, unknownImageParameter: 1, }, ], 'no-ignored': [ 2, { // arg: 2, // closingTag: 2, // conversionFlag: 2, fragment: 1, galleryComment: 1, // galleryImage: 2, galleryNoImage: 1, include: 1, // invalidAttributes: 2, nonWordAttributes: 1, redirect: 1, // choose: 2, // combobox: 2, // dynamicpagelist: 2, // inputbox: 2, // references: 2, }, ], 'obsolete-attr': 1, 'obsolete-tag': 1, 'parsing-order': [ 2, { // ext: 2, // heading: 2, // html: 2, templateInTable: 1, }, ], 'pipe-like': [ 1, { double: 2, // link: 1, // td: 1, }, ], 'table-layout': 1, 'tag-like': [ 2, { disallowed: 1, invalid: 1, }, ], 'unbalanced-header': 2, 'unclosed-comment': [ 1, { // include: 1, }, ], 'unclosed-quote': 1, 'unclosed-table': 2, unescaped: 2, 'unknown-page': 1, 'unmatched-tag': [ 1, { // both: 1, // closing: 1, // conditional: 1, // opening: 1, // selfClosing: 1, }, ], 'unterminated-url': [ 1, { // pipe: 1, // punctuation: 1, }, ], 'url-encoding': [ 1, { // file: 1, }, ], 'var-anchor': [ 1, { // extLink: 1, // ref: 1, }, ], 'void-ext': [ 2, { // img: 2, // languages: 2, // section: 2, // templatestyles: 2, }, ], /* NOT FOR BROWSER ONLY */ 'invalid-css': [ 2, { warn: 1, }, ], }; Object.freeze(defaultLintRuleConfig); const defaultLintConfig = { configurationComment: 'lint', ignoreDisables: false, fix: true, computeEditInfo: true, }; Object.freeze(defaultLintConfig); /** * 验证错误级别是否符合规范 * @param severity 错误级别 */ const validateSeverity = (severity) => dict.has(severity); /** * 验证设置值是否符合规范 * @param value 设置值 */ const validateConfigValue = (value) => validateSeverity(value) || Array.isArray(value) && validateSeverity(value[0]) && (value.length === 1 || typeof value[1] === 'object'); /** * 设置语法检查规则 * @param obj 语法检查设置对象 * @param key 语法检查规则 * @param value 语法检查规则值 * @throws `RangeError` 未知的规则或无效的值 */ const set = (obj, key, value) => { /* istanbul ignore if */ if (!base_1.rules.includes(key)) { throw new RangeError(`Unknown lint rule: ${key}`); } else /* istanbul ignore if */ if (value === undefined) { return false; } else if (validateConfigValue(value)) { obj[key] = value; return true; } /* istanbul ignore next */ throw new RangeError(`Invalid lint config for ${key}: ${JSON.stringify(value)}`); }; /** 语法规则设置 */ class LintRuleConfiguration { /** @param config 语法规则设置 */ constructor(config) { Object.assign(this, structuredClone(defaultLintRuleConfig)); if (!config) { return; } for (const [key, value] of Object.entries(config)) { set(this, key, value); } } /** @implements */ getSeverity(rule, key) { const value = this[rule]; if (typeof value !== 'object') { return dict.get(value); } return key ? dict.get(value[1]?.[key]) ?? dict.get(value[0]) : dict.get(value[0]); } } /** 语法检查设置 */ class LintConfiguration { #rules; /** @implements */ get rules() { return this.#rules; } set rules(config) { this.#rules = new Proxy(new LintRuleConfiguration(config), { set, /** @ignore */ deleteProperty() { /* istanbul ignore next */ return false; }, }); } /** @param config 语法检查设置 */ constructor(config) { Object.assign(this, defaultLintConfig); if (config && !('rules' in config) && Object.keys(config).some(key => base_1.rules.includes(key))) { this.rules = config; } else { const { rules: ruleConfig, ...other } = (config ?? {}); this.rules = ruleConfig; for (const [key, value] of Object.entries(other)) { if (value !== undefined && Object.prototype.hasOwnProperty.call(defaultLintConfig, key)) { this[key] = value; } } } } /** @implements */ getSeverity(rule, key) { return this.#rules.getSeverity(rule, key); } } exports.LintConfiguration = LintConfiguration; constants_1.classes['LintConfiguration'] = __filename;