wikilint 2.4.2 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,17 +21,13 @@ class AstElement extends node_1.AstNode {
21
21
  normalize() {
22
22
  const childNodes = [...this.childNodes];
23
23
  for (let i = childNodes.length - 1; i >= 0; i--) {
24
- const { type, data } = childNodes[i], prev = childNodes[i - 1];
24
+ const { type, data } = childNodes[i];
25
25
  if (type !== 'text' || this.getGaps(i - 1)) {
26
26
  //
27
27
  }
28
28
  else if (data === '') {
29
29
  childNodes.splice(i, 1);
30
30
  }
31
- else if (prev?.type === 'text') {
32
- prev.setAttribute('data', prev.data + data);
33
- childNodes.splice(i, 1);
34
- }
35
31
  }
36
32
  this.setAttribute('childNodes', childNodes);
37
33
  }
@@ -56,11 +52,8 @@ class AstElement extends node_1.AstNode {
56
52
  * @param selector 选择器
57
53
  */
58
54
  #getCondition(selector) {
59
- let condition;
60
55
  const types = new Set(selector.split(',').map(str => str.trim()));
61
- // eslint-disable-next-line prefer-const
62
- condition = (token => types.has(token.type));
63
- return condition;
56
+ return (({ type }) => types.has(type));
64
57
  }
65
58
  /**
66
59
  * 最近的祖先节点
package/dist/lib/node.js CHANGED
@@ -111,5 +111,12 @@ class AstNode {
111
111
  const { parentNode } = this;
112
112
  return parentNode ? parentNode.getAbsoluteIndex() + this.getRelativeIndex() : 0;
113
113
  }
114
+ /** @private */
115
+ seal(key, permanent) {
116
+ Object.defineProperty(this, key, {
117
+ enumerable: !permanent && Boolean(this[key]),
118
+ configurable: true,
119
+ });
120
+ }
114
121
  }
115
122
  exports.AstNode = AstNode;
package/dist/lib/text.js CHANGED
@@ -52,6 +52,8 @@ class AstText extends node_1.AstNode {
52
52
  constructor(text) {
53
53
  super();
54
54
  Object.defineProperties(this, {
55
+ childNodes: { enumerable: false, configurable: false },
56
+ type: { enumerable: false, writable: false },
55
57
  data: {
56
58
  value: text,
57
59
  },
package/dist/lib/title.js CHANGED
@@ -17,7 +17,6 @@ class Title {
17
17
  * @param selfLink 是否允许selfLink
18
18
  */
19
19
  constructor(title, defaultNs = 0, config = index_1.default.getConfig(), decode = false, selfLink = false) {
20
- const { nsid, } = config;
21
20
  title = (0, string_1.decodeHtml)(title);
22
21
  if (decode && title.includes('%')) {
23
22
  try {
@@ -35,7 +34,7 @@ class Title {
35
34
  }
36
35
  const m = title.split(':');
37
36
  if (m.length > 1) {
38
- const id = nsid[m[0].trim().toLowerCase()];
37
+ const id = config.nsid[m[0].trim().toLowerCase()];
39
38
  if (id) {
40
39
  ns = id;
41
40
  title = m.slice(1).join(':').trim();
@@ -60,8 +59,8 @@ class Title {
60
59
  this.fragment = fragment;
61
60
  title = title.slice(0, i).trim();
62
61
  }
63
- this.valid = Boolean(title
64
- || selfLink && this.fragment !== undefined) && !/^:|\0\d+[eh!+-]\x7F|[<>[\]{}|]|%[\da-f]{2}/iu.test(title);
62
+ this.valid = Boolean(title || this.interwiki || selfLink && this.fragment !== undefined)
63
+ && !/^:|\0\d+[eh!+-]\x7F|[<>[\]{}|]|%[\da-f]{2}/iu.test(title);
65
64
  }
66
65
  }
67
66
  exports.Title = Title;
@@ -41,13 +41,13 @@ const parseLinks = (wikitext, config = index_1.default.getConfig(), accum = [])
41
41
  s += `[[${x}`;
42
42
  continue;
43
43
  }
44
- const title = index_1.default.normalizeTitle(link, 0, false, config, true, true, true), { ns, valid, } = title;
44
+ const title = index_1.default.normalizeTitle(link, 0, false, config, true, true, true), { ns, valid, interwiki } = title;
45
45
  if (!valid) {
46
46
  s += `[[${x}`;
47
47
  continue;
48
48
  }
49
49
  else if (mightBeImg) {
50
- if (ns !== 6) {
50
+ if (interwiki || ns !== 6) {
51
51
  s += `[[${x}`;
52
52
  continue;
53
53
  }
@@ -78,10 +78,10 @@ const parseLinks = (wikitext, config = index_1.default.getConfig(), accum = [])
78
78
  s += `\0${accum.length}l\x7F${after}`;
79
79
  let SomeLinkToken = index_2.LinkToken;
80
80
  if (!force) {
81
- if (ns === 6) {
81
+ if (!interwiki && ns === 6) {
82
82
  SomeLinkToken = file_1.FileToken;
83
83
  }
84
- else if (ns === 14) {
84
+ else if (!interwiki && ns === 14) {
85
85
  SomeLinkToken = category_1.CategoryToken;
86
86
  }
87
87
  }
@@ -12,7 +12,6 @@ export declare abstract class AttributeToken extends Token {
12
12
  #private;
13
13
  type: AttributeTypes;
14
14
  readonly name: string;
15
- readonly tag: string;
16
15
  readonly childNodes: readonly [AtomToken, Token];
17
16
  abstract get firstChild(): AtomToken;
18
17
  abstract get lastChild(): Token;
@@ -174,9 +174,13 @@ const commonHtmlAttrs = new Set([
174
174
  * @classdesc `{childNodes: [AtomToken, Token|AtomToken]}`
175
175
  */
176
176
  class AttributeToken extends index_2.Token {
177
- tag;
177
+ #tag;
178
178
  #equal;
179
179
  #quotes;
180
+ /** @private */
181
+ get tag() {
182
+ return this.#tag;
183
+ }
180
184
  /** 引号是否匹配 */
181
185
  get balanced() {
182
186
  return !this.#equal || this.#quotes[0] === this.#quotes[1];
@@ -223,7 +227,7 @@ class AttributeToken extends index_2.Token {
223
227
  this.append(keyToken, valueToken);
224
228
  this.#equal = equal;
225
229
  this.#quotes = [...quotes];
226
- this.tag = tag;
230
+ this.#tag = tag;
227
231
  this.setAttribute('name', (0, string_1.removeComment)(key).trim().toLowerCase());
228
232
  }
229
233
  /** @private */
@@ -232,7 +236,7 @@ class AttributeToken extends index_2.Token {
232
236
  this.#equal = this.buildFromStr(this.#equal, constants_1.BuildMethod.String);
233
237
  }
234
238
  if (this.parentNode) {
235
- this.setAttribute('tag', this.parentNode.name);
239
+ this.#tag = this.parentNode.name;
236
240
  }
237
241
  this.setAttribute('name', this.firstChild.text().trim().toLowerCase());
238
242
  }
@@ -263,7 +267,8 @@ class AttributeToken extends index_2.Token {
263
267
  startCol: e.startCol - 1,
264
268
  });
265
269
  }
266
- if (extAttrs[tag] && !extAttrs[tag].has(name)
270
+ const attrs = extAttrs[tag];
271
+ if (attrs && !attrs.has(name)
267
272
  || (type === 'ext-attr' ? tag in htmlAttrs : !/\{\{[^{]+\}\}/u.test(name))
268
273
  && !htmlAttrs[tag]?.has(name)
269
274
  && !/^(?:xmlns:[\w:.-]+|data-[^:]*)$/u.test(name)
@@ -2,9 +2,14 @@ import Parser from '../index';
2
2
  import { Token } from './index';
3
3
  import { ConverterFlagsToken } from './converterFlags';
4
4
  import { ConverterRuleToken } from './converterRule';
5
+ /**
6
+ * 转换
7
+ * @classdesc `{childNodes: [ConverterFlagsToken, ...ConverterRuleToken]}`
8
+ */
5
9
  export declare abstract class ConverterToken extends Token {
6
10
  readonly type = "converter";
7
11
  readonly childNodes: readonly [ConverterFlagsToken, ...ConverterRuleToken[]];
12
+ abstract get firstChild(): ConverterFlagsToken;
8
13
  abstract get lastChild(): ConverterFlagsToken | ConverterRuleToken;
9
14
  /**
10
15
  * @param flags 转换类型标记
@@ -14,4 +19,3 @@ export declare abstract class ConverterToken extends Token {
14
19
  /** @override */
15
20
  text(): string;
16
21
  }
17
- export {};
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConverterToken = void 0;
4
4
  const string_1 = require("../util/string");
5
- const flagsParent_1 = require("../mixin/flagsParent");
6
5
  const index_1 = require("../index");
7
6
  const index_2 = require("./index");
8
7
  const converterFlags_1 = require("./converterFlags");
@@ -11,7 +10,7 @@ const converterRule_1 = require("./converterRule");
11
10
  * 转换
12
11
  * @classdesc `{childNodes: [ConverterFlagsToken, ...ConverterRuleToken]}`
13
12
  */
14
- class ConverterToken extends (0, flagsParent_1.flagsParent)(index_2.Token) {
13
+ class ConverterToken extends index_2.Token {
15
14
  type = 'converter';
16
15
  /**
17
16
  * @param flags 转换类型标记
@@ -2,10 +2,15 @@ import Parser from '../index';
2
2
  import { Token } from './index';
3
3
  import { MagicLinkToken } from './magicLink';
4
4
  import type { LintError } from '../base';
5
+ /**
6
+ * 外链
7
+ * @classdesc `{childNodes: [MagicLinkToken, ?Token]}`
8
+ */
5
9
  export declare abstract class ExtLinkToken extends Token {
6
10
  #private;
7
11
  readonly type = "ext-link";
8
12
  readonly childNodes: readonly [MagicLinkToken] | readonly [MagicLinkToken, Token];
13
+ abstract get firstChild(): MagicLinkToken;
9
14
  abstract get lastChild(): Token;
10
15
  /**
11
16
  * @param url 网址
@@ -18,4 +23,3 @@ export declare abstract class ExtLinkToken extends Token {
18
23
  /** @override */
19
24
  lint(start?: number): LintError[];
20
25
  }
21
- export {};
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExtLinkToken = void 0;
4
4
  const constants_1 = require("../util/constants");
5
5
  const lint_1 = require("../util/lint");
6
- const magicLinkParent_1 = require("../mixin/magicLinkParent");
7
6
  const index_1 = require("../index");
8
7
  const index_2 = require("./index");
9
8
  const magicLink_1 = require("./magicLink");
@@ -11,7 +10,7 @@ const magicLink_1 = require("./magicLink");
11
10
  * 外链
12
11
  * @classdesc `{childNodes: [MagicLinkToken, ?Token]}`
13
12
  */
14
- class ExtLinkToken extends (0, magicLinkParent_1.magicLinkParent)(index_2.Token) {
13
+ class ExtLinkToken extends index_2.Token {
15
14
  type = 'ext-link';
16
15
  #space;
17
16
  /**
@@ -45,9 +45,7 @@ class HeadingToken extends index_2.Token {
45
45
  }
46
46
  /** @private */
47
47
  getAttribute(key) {
48
- return key === 'padding'
49
- ? super.getAttribute('padding') + this.level
50
- : super.getAttribute(key);
48
+ return key === 'padding' ? this.level : super.getAttribute(key);
51
49
  }
52
50
  /** @private */
53
51
  getGaps() {
package/dist/src/html.js CHANGED
@@ -65,11 +65,8 @@ class HtmlToken extends index_2.Token {
65
65
  }
66
66
  /** @override */
67
67
  text() {
68
- const { closing, name } = this, tag = `${this.#tag}${closing ? '' : super.text()}`, { html } = this.getAttribute('config');
69
- if (html[2].includes(name)) {
70
- return closing && name !== 'br' ? '' : `<${tag}>`;
71
- }
72
- return `<${closing ? '/' : ''}${tag}${this.#selfClosing && html[1].includes(name) ? '/' : ''}>`;
68
+ const { closing, } = this, tag = `${this.#tag}${closing ? '' : super.text()}`;
69
+ return `<${closing ? '/' : ''}${tag}${this.#selfClosing ? '/' : ''}>`;
73
70
  }
74
71
  /** @private */
75
72
  getAttribute(key) {
@@ -33,8 +33,7 @@ class ImagemapToken extends index_2.Token {
33
33
  }
34
34
  else if (first) {
35
35
  const [file, ...options] = line.split('|'), title = this.normalizeTitle(file, 0, true);
36
- if (title.valid
37
- && title.ns === 6) {
36
+ if (title.valid && !title.interwiki && title.ns === 6) {
38
37
  // @ts-expect-error abstract class
39
38
  const token = new galleryImage_1.GalleryImageToken('imagemap', file, options.length > 0 ? options.join('|') : undefined, config, accum);
40
39
  super.insertAt(token);
package/dist/src/index.js CHANGED
@@ -272,8 +272,6 @@ class Token extends element_1.AstElement {
272
272
  return (this.constructor === Token);
273
273
  case 'config':
274
274
  return structuredClone(this.#config);
275
- case 'accum':
276
- return this.#accum;
277
275
  case 'include': {
278
276
  if (this.#include !== undefined) {
279
277
  return this.#include;
@@ -281,6 +279,8 @@ class Token extends element_1.AstElement {
281
279
  const root = this.getRootNode();
282
280
  return (root !== this && root.getAttribute('include'));
283
281
  }
282
+ case 'accum':
283
+ return this.#accum;
284
284
  default:
285
285
  return super.getAttribute(key);
286
286
  }
@@ -38,8 +38,8 @@ class GalleryImageToken extends file_1.FileToken {
38
38
  }
39
39
  /** @override */
40
40
  lint(start = this.getAbsoluteIndex()) {
41
- const errors = super.lint(start), { ns, } = this.getAttribute('title');
42
- if (ns !== 6) {
41
+ const errors = super.lint(start), { ns, interwiki } = this.getAttribute('title');
42
+ if (interwiki || ns !== 6) {
43
43
  errors.push((0, lint_1.generateForSelf)(this, { start }, 'invalid gallery image'));
44
44
  }
45
45
  return errors;
@@ -34,9 +34,11 @@ class TableToken extends trBase_1.TrBaseToken {
34
34
  }
35
35
  /** @private */
36
36
  close(syntax = '\n|}', halfParsed = false) {
37
- const config = this.getAttribute('config'), accum = this.getAttribute('accum'), inner = [syntax];
38
- // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
37
+ const config = this.getAttribute('config'), accum = this.getAttribute('accum'), inner = halfParsed ? [syntax] : index_1.default.parse(syntax, this.getAttribute('include'), 2, config).childNodes;
39
38
  const token = debug_1.Shadow.run(() => super.insertAt(new syntax_1.SyntaxToken(undefined, closingPattern, 'table-syntax', config, accum, {})));
39
+ if (!halfParsed) {
40
+ token.afterBuild();
41
+ }
40
42
  this.lastChild.replaceChildren(...inner);
41
43
  }
42
44
  }
@@ -46,7 +46,9 @@ class TdToken extends base_1.TableBaseToken {
46
46
  else if (char === '+') {
47
47
  subtype = 'caption';
48
48
  }
49
- return { subtype };
49
+ return {
50
+ subtype,
51
+ };
50
52
  }
51
53
  /** @private */
52
54
  afterBuild() {
@@ -116,6 +116,7 @@ class ExtToken extends index_3.TagPairToken {
116
116
  innerToken.setAttribute('name', lcName);
117
117
  innerToken.type = 'ext-inner';
118
118
  super(name, attrToken, innerToken, closed, config, accum);
119
+ this.seal('closed', true);
119
120
  }
120
121
  /** @override */
121
122
  lint(start = this.getAbsoluteIndex()) {
@@ -8,7 +8,6 @@ class TagPairToken extends index_2.Token {
8
8
  #tags;
9
9
  closed;
10
10
  selfClosing;
11
- /* NOT FOR BROWSER END */
12
11
  /** 内部wikitext */
13
12
  get innerText() {
14
13
  return this.selfClosing ? undefined : this.lastChild.text();
@@ -92,6 +92,7 @@ class TranscludeToken extends index_2.Token {
92
92
  // @ts-expect-error abstract class
93
93
  this.insertAt(new parameter_1.ParameterToken(...part, config, accum));
94
94
  }
95
+ this.seal('modifier');
95
96
  }
96
97
  /**
97
98
  * 设置引用修饰符
@@ -105,7 +106,7 @@ class TranscludeToken extends index_2.Token {
105
106
  const magicWord = lcModifier.slice(0, -1).toLowerCase(), isRaw = raw.includes(magicWord), isSubst = subst.includes(magicWord);
106
107
  if (this.#raw && isRaw
107
108
  || !this.#raw && (isSubst || modifier === '')
108
- || this.length > 1 && (isRaw || isSubst || modifier === '')) {
109
+ || (debug_1.Shadow.running || this.length > 1) && (isRaw || isSubst || modifier === '')) {
109
110
  this.setAttribute('modifier', modifier);
110
111
  this.#raw = isRaw;
111
112
  return Boolean(modifier);
@@ -242,10 +243,7 @@ class TranscludeToken extends index_2.Token {
242
243
  * 获取重名参数
243
244
  */
244
245
  getDuplicatedArgs() {
245
- if (this.isTemplate()) {
246
- return [...this.#args].filter(([, { size }]) => size > 1).map(([key, args]) => [key, [...args]]);
247
- }
248
- return [];
246
+ return [...this.#args].filter(([, { size }]) => size > 1).map(([key, args]) => [key, [...args]]);
249
247
  }
250
248
  /**
251
249
  * 对特定魔术字获取可能的取值
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setChildNodes = exports.isToken = exports.Shadow = void 0;
4
4
  exports.Shadow = {
5
+ running: false,
5
6
  /** @private */
6
7
  run(callback) {
7
8
  const result = callback();
package/i18n/zh-hans.json CHANGED
@@ -21,6 +21,7 @@
21
21
  "HTML tag in table attributes": "表格属性中的HTML标签",
22
22
  "illegal attribute name": "非法的属性名",
23
23
  "illegal module name": "非法的模块名称",
24
+ "inconsistent table layout": "不一致的表格布局",
24
25
  "insecure style": "不安全的样式",
25
26
  "internal link in an external link": "外链中的内链",
26
27
  "invalid content in <$1>": "<$1>内的无效内容",
package/i18n/zh-hant.json CHANGED
@@ -21,6 +21,7 @@
21
21
  "HTML tag in table attributes": "表格屬性中的HTML標籤",
22
22
  "illegal attribute name": "非法的屬性名",
23
23
  "illegal module name": "非法的模組名稱",
24
+ "inconsistent table layout": "不一致的表格佈局",
24
25
  "insecure style": "不安全的樣式",
25
26
  "internal link in an external link": "外部連結中的內部連結",
26
27
  "invalid content in <$1>": "<$1>內的無效內容",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -35,14 +35,13 @@
35
35
  "declaration": "grep -rl --include='*.d.ts' '@private' dist/ | xargs bash sed.sh -i -E '/^\\s+\\/\\*\\* @private/,+1d'; node ./dist/bin/declaration.js",
36
36
  "prepublishOnly": "npm run build && rm dist/internal.js dist/base.js dist/[bmpu]*/*.d.ts",
37
37
  "build": "bash build.sh",
38
- "diff": "git diff --ignore-all-space --color-moved",
38
+ "diff": "bash diff.sh",
39
+ "diff:stat": "f() { git diff --stat --ignore-all-space --color=always $1 $2 -- . ':!extensions/' ':!bin/' | grep '\\.ts'; }; f",
39
40
  "lint:ts": "tsc --noEmit && eslint --cache .",
40
41
  "lint:json": "ajv -s config/.schema.json -d 'config/*.json' --strict=true --strict-required=false",
41
42
  "lint": "npm run lint:ts && npm run lint:json",
42
- "test": "npx wikilint test/single-page.wiki",
43
43
  "test:end": "pkill -x http-server",
44
- "test:real": "node dist/test/real.js",
45
- "test:single": "node dist/test/single.js && node --prof dist/test/single.js && node --prof-process isolate-0x*-v8.log > test/processed.txt && rm isolate-0x*-v8.log"
44
+ "test:real": "node dist/test/real.js"
46
45
  },
47
46
  "devDependencies": {
48
47
  "@cypress/request": "^3.0.1",
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flagsParent = void 0;
4
- /**
5
- * ConverterToken
6
- * @param constructor 基类
7
- */
8
- const flagsParent = (constructor) => {
9
- /** 子节点含有ConverterFlagsToken的类 */
10
- class FlagsParent extends constructor {
11
- }
12
- return FlagsParent;
13
- };
14
- exports.flagsParent = flagsParent;
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.magicLinkParent = void 0;
4
- /**
5
- * ExtLinkToken
6
- * @param constructor 基类
7
- */
8
- const magicLinkParent = (constructor) => {
9
- /** 子节点含有MagicLinkParent的类 */
10
- class MagicLinkParent extends constructor {
11
- }
12
- return MagicLinkParent;
13
- };
14
- exports.magicLinkParent = magicLinkParent;