wikilint 2.36.0 → 2.37.0

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.
package/LICENSE CHANGED
@@ -1,3 +1,21 @@
1
+ WikiLint
2
+ Copyright (C) 2022 Bhsd
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+
18
+
1
19
  GNU GENERAL PUBLIC LICENSE
2
20
  Version 3, 29 June 2007
3
21
 
package/dist/bin/cli.js CHANGED
@@ -78,16 +78,8 @@ const throwOnLintConfig = (config) => {
78
78
  * load lintConfig
79
79
  * @param file lintConfig file path
80
80
  */
81
- const loadLintConfig = async (file) => {
82
- const symbol = Symbol('lintConfig');
83
- let lintConfig = symbol;
84
- try {
85
- lintConfig = require(file);
86
- }
87
- catch { }
88
- if (lintConfig === symbol) {
89
- lintConfig = await import(file);
90
- }
81
+ const loadLintConfig = (file) => {
82
+ let lintConfig = require(file);
91
83
  if (lintConfig && typeof lintConfig === 'object' && 'default' in lintConfig) {
92
84
  lintConfig = lintConfig.default;
93
85
  }
@@ -292,42 +284,28 @@ config = (config.includes('/')
292
284
  ? path_1.default.resolve(index_1.default.config)
293
285
  : path_1.default.join(configPath, index_1.default.config)) + (config.endsWith('.json') ? '' : '.json');
294
286
  const { mtimeMs } = fs_1.default.statSync(config), obj = cache?.[include ? 'include' : 'noinclude'];
295
- let minimatch;
296
- try {
297
- ({ minimatch } = require('minimatch'));
298
- }
299
- catch {
300
- /* eslint-disable n/no-unsupported-features/node-builtins */
301
- if (typeof path_1.default.matchesGlob !== 'function') {
302
- exit('Cannot load Node.js package "minimatch"');
303
- }
304
- minimatch = path_1.default.matchesGlob.bind(path_1.default);
305
- /* eslint-enable n/no-unsupported-features/node-builtins */
306
- }
307
287
  (async () => {
308
288
  if (lintConfigFile) {
309
289
  try {
310
- index_1.default.lintConfig = await loadLintConfig(lintConfigFile);
290
+ index_1.default.lintConfig = loadLintConfig(lintConfigFile);
311
291
  }
312
292
  catch {
313
293
  exit(`Cannot load lint config file: ${lintConfigFile}`);
314
294
  }
315
295
  }
316
296
  else {
317
- await (async () => {
318
- let cur = process.cwd(), last;
319
- while (last !== cur) {
320
- for (const file of lintConfigDefaults) {
321
- try {
322
- index_1.default.lintConfig = await loadLintConfig(path_1.default.join(cur, file));
323
- return;
324
- }
325
- catch { }
297
+ let cur = process.cwd(), last;
298
+ while (last !== cur) {
299
+ for (const file of lintConfigDefaults) {
300
+ try {
301
+ index_1.default.lintConfig = loadLintConfig(path_1.default.join(cur, file));
302
+ return;
326
303
  }
327
- last = cur;
328
- cur = path_1.default.dirname(cur);
304
+ catch { }
329
305
  }
330
- })();
306
+ last = cur;
307
+ cur = path_1.default.dirname(cur);
308
+ }
331
309
  }
332
310
  index_1.default.lintConfig.computeEditInfo = false;
333
311
  index_1.default.lintConfig.fix = true;
@@ -338,7 +316,7 @@ catch {
338
316
  exiting = true;
339
317
  continue;
340
318
  }
341
- else if (ignorePatterns.some(ignore => minimatch(file, ignore))) {
319
+ else if (ignorePatterns.some(ignore => path_1.default.matchesGlob(file, ignore))) {
342
320
  continue;
343
321
  }
344
322
  const fileCache = obj?.[file];
@@ -39,46 +39,7 @@ const filterGadget = (id) => {
39
39
  const n = Number(id);
40
40
  return n < 2300 || n > 2303; // Gadget, Gadget talk, Gadget definition, Gadget definition talk
41
41
  };
42
- /**
43
- * Execute the data script.
44
- * @param obj MediaWiki module implementation
45
- */
46
- const execute = (obj) => {
47
- Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
48
- };
49
- const mw = {
50
- loader: {
51
- done: false,
52
- /** @ignore */
53
- impl(callback) {
54
- execute(callback()[1]);
55
- },
56
- /** @ignore */
57
- implement(name, callback) {
58
- if (typeof callback === 'object') {
59
- execute(callback);
60
- }
61
- else if (!this.done) {
62
- callback();
63
- }
64
- if (name.startsWith('ext.CodeMirror.data')) {
65
- this.done = true;
66
- }
67
- },
68
- /** @ignore */
69
- state() {
70
- //
71
- },
72
- },
73
- config: {
74
- /** @ignore */
75
- set({ extCodeMirrorConfig }) {
76
- mwConfig = extCodeMirrorConfig;
77
- },
78
- },
79
- };
80
- const pkg = "wikilint", version = "2.36.0";
81
- let mwConfig;
42
+ const pkg = "wikilint", version = "2.37.0";
82
43
  /**
83
44
  * Get the parser configuration for a Wikimedia Foundation project.
84
45
  * @param site site nickname
@@ -122,15 +83,28 @@ exports.default = async (site, url, user, force, internal) => {
122
83
  siprop: 'general|magicwords|functionhooks|namespaces|namespacealiases',
123
84
  format: 'json',
124
85
  formatversion: '2',
125
- }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query;
126
- try {
127
- eval(m); // eslint-disable-line no-eval
86
+ }, { general: { articlepath, variants, langconversion }, magicwords, namespaces, namespacealiases, functionhooks, } = (await (await fetch(`${url}/api.php?${new URLSearchParams(params).toString()}`, headers)).json()).query, tempFile = path_1.default.join(__dirname, 'mw.js');
87
+ fs_1.default.writeFileSync(tempFile, m);
88
+ const { stdout, stderr } = (0, child_process_1.spawnSync)(process.execPath, [
89
+ '-r',
90
+ './env.js',
91
+ process.allowedNodeEnvironmentFlags.has('--permission')
92
+ ? '--permission'
93
+ : '--experimental-permission',
94
+ `--allow-fs-read=${__dirname}`,
95
+ '--disable-warning=ExperimentalWarning',
96
+ tempFile,
97
+ ], { cwd: __dirname, encoding: 'utf8' });
98
+ fs_1.default.unlinkSync(tempFile);
99
+ if (stderr) {
100
+ console.error(stderr);
101
+ throw new Error('Failed to execute the fetched MediaWiki module!', { cause: m });
128
102
  }
129
- catch (e) {
130
- console.log(m);
131
- throw e;
103
+ let mwConfig;
104
+ try {
105
+ mwConfig = JSON.parse(stdout);
132
106
  }
133
- if (!mwConfig) {
107
+ catch {
134
108
  throw new RangeError('Extension:CodeMirror is not installed!');
135
109
  }
136
110
  const ns = Object.entries(namespaces).filter(([id]) => filterGadget(id))
@@ -138,7 +112,7 @@ exports.default = async (site, url, user, force, internal) => {
138
112
  [id, name],
139
113
  ...name === canonical ? [] : [[id, canonical]],
140
114
  ]), config = {
141
- ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum')), mwConfig),
115
+ ...(0, cm_util_1.getParserConfig)(require(path_1.default.join(dir, 'minimum.json')), mwConfig),
142
116
  ...(0, cm_util_1.getKeywords)(magicwords),
143
117
  variants: langconversion ? (0, cm_util_1.getVariants)(variants) : [],
144
118
  namespaces: Object.fromEntries(ns),
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Execute the data script.
5
+ * @param obj MediaWiki module implementation
6
+ */
7
+ const execute = (obj) => {
8
+ Object.entries(obj.files).find(([k]) => k.endsWith('.data.js'))[1]();
9
+ };
10
+ Object.assign(globalThis, {
11
+ mw: {
12
+ loader: {
13
+ done: false,
14
+ /** @ignore */
15
+ impl(callback) {
16
+ execute(callback()[1]);
17
+ },
18
+ /** @ignore */
19
+ implement(name, callback) {
20
+ if (typeof callback === 'object') {
21
+ execute(callback);
22
+ }
23
+ else if (!this.done) {
24
+ callback();
25
+ }
26
+ if (name.startsWith('ext.CodeMirror.data')) {
27
+ this.done = true;
28
+ }
29
+ },
30
+ /** @ignore */
31
+ state() {
32
+ //
33
+ },
34
+ },
35
+ config: {
36
+ /** @ignore */
37
+ set({ extCodeMirrorConfig }) {
38
+ console.log(JSON.stringify(extCodeMirrorConfig));
39
+ },
40
+ },
41
+ },
42
+ });
package/dist/index.js CHANGED
@@ -17,20 +17,25 @@ const diff_1 = require("./util/diff");
17
17
  /* NOT FOR BROWSER ONLY */
18
18
  const re = new RegExp(String.raw `^https?:\/\/([^./]+)\.(${common_1.wmf})\.org`, 'iu');
19
19
  /**
20
- * 从根路径require
20
+ * require一个JSON文件
21
21
  * @param file 文件名
22
- * @param dir 子路径
23
22
  * @throws {RangeError} 仅支持JSON文件
24
23
  */
25
- const rootRequire = (file, dir) => {
26
- const fullPath = require.resolve(path_1.default.isAbsolute(file)
27
- ? /* c8 ignore next */ file
28
- : path_1.default.join('..', file.includes('/') ? '' : dir, file));
29
- if (!fullPath.endsWith('.json')) {
30
- throw new RangeError('Only JSON files are supported!');
24
+ const jsonRequire = (file) => {
25
+ const fullPath = require.resolve(file);
26
+ if (fullPath.endsWith('.json')) {
27
+ return require(fullPath);
31
28
  }
32
- return require(fullPath);
29
+ throw new RangeError('Only JSON files are supported!');
33
30
  };
31
+ /**
32
+ * 从根路径require
33
+ * @param file 文件名
34
+ * @param dir 子路径
35
+ */
36
+ const rootRequire = (file, dir) => jsonRequire(path_1.default.isAbsolute(file)
37
+ ? /* c8 ignore next */ file
38
+ : path_1.default.join('..', file.includes('/') ? '' : dir, file));
34
39
  /* NOT FOR BROWSER ONLY END */
35
40
  let viewOnly = true;
36
41
  let lintConfig = (() => {
@@ -92,7 +97,7 @@ const Parser = {
92
97
  if (!path_1.default.isAbsolute(this.config)) {
93
98
  for (const p of this.configPaths) {
94
99
  try {
95
- this.config = require(path_1.default.resolve(process.cwd(), p, this.config));
100
+ this.config = jsonRequire(path_1.default.resolve(process.cwd(), p, this.config));
96
101
  break;
97
102
  }
98
103
  catch { }
@@ -29,11 +29,10 @@ declare interface Texvcjs {
29
29
  };
30
30
  }
31
31
  export declare const loadTexvcjs: () => Texvcjs | null;
32
- export declare const jsonTags: string[];
33
32
  export declare const loadJsonLSP: () => JSONLanguageService | null;
34
33
  export declare const loadCssLSP: () => CSSLanguageService | null;
35
34
  export declare const loadHtmlData: () => IHTMLDataProvider | null;
36
- export declare const loadStylelint: () => Promise<PublicApi | null>;
35
+ export declare const loadStylelint: () => PublicApi | null;
37
36
  /** embedded document */
38
37
  declare class EmbeddedDocument implements TextDocument {
39
38
  #private;
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.jsonTags = exports.loadTexvcjs = void 0;
6
+ exports.EmbeddedCSSDocument = exports.EmbeddedJSONDocument = exports.loadStylelint = exports.loadHtmlData = exports.loadCssLSP = exports.loadJsonLSP = exports.loadTexvcjs = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const common_1 = require("@bhsd/common");
9
+ const constants_1 = require("../util/constants");
9
10
  let texcvjs;
10
11
  const loadTexvcjs = () => {
11
12
  NPM: {
@@ -22,7 +23,6 @@ const loadTexvcjs = () => {
22
23
  }
23
24
  };
24
25
  exports.loadTexvcjs = loadTexvcjs;
25
- exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
26
26
  let jsonLSP;
27
27
  const loadJsonLSP = () => {
28
28
  if (jsonLSP === undefined) {
@@ -38,10 +38,10 @@ const loadJsonLSP = () => {
38
38
  });
39
39
  const dir = path_1.default.join('..', '..', 'data', 'ext');
40
40
  jsonLSP.configure({
41
- schemas: exports.jsonTags.map((tag) => {
42
- const uri = path_1.default.join(dir, tag);
41
+ schemas: constants_1.jsonTags.map((tag) => {
42
+ const uri = path_1.default.join(dir, `${tag}.json`);
43
43
  try {
44
- const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe') : uri);
44
+ const schema = require(tag === 'maplink' ? path_1.default.join(dir, 'mapframe.json') : uri);
45
45
  return {
46
46
  uri,
47
47
  fileMatch: [tag],
@@ -96,15 +96,15 @@ exports.loadHtmlData = loadHtmlData;
96
96
  let stylelint;
97
97
  const loadStylelint = () => {
98
98
  NPM: {
99
- stylelint ??= (async () => {
99
+ if (stylelint === undefined) {
100
100
  try {
101
- return (await import('stylelint')).default;
101
+ stylelint = require('stylelint');
102
102
  }
103
103
  catch /* c8 ignore start */ {
104
- return null;
104
+ stylelint = null;
105
105
  }
106
106
  /* c8 ignore stop */
107
- })();
107
+ }
108
108
  return stylelint;
109
109
  }
110
110
  };
package/dist/lib/lsp.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import Parser from '../index';
2
+ import { Token } from '../src/index';
2
3
  import type { Range, Position, ColorInformation, ColorPresentation, FoldingRange, DocumentLink, Location, WorkspaceEdit, Diagnostic as DiagnosticBase, TextEdit, Hover, SignatureHelp, InlayHint, CodeAction, DocumentSymbol } from 'vscode-languageserver-types';
3
4
  import type { Config, LanguageService as LanguageServiceBase, CompletionItem, SignatureData } from '../base';
4
5
  import type { AttributeToken } from '../internal';
package/dist/lib/lsp.js CHANGED
@@ -22,6 +22,7 @@ const child_process_1 = require("child_process");
22
22
  const crypto_1 = require("crypto");
23
23
  const stylelint_util_1 = require("@bhsd/stylelint-util");
24
24
  const search_1 = __importDefault(require("../util/search"));
25
+ const constants_2 = require("../util/constants");
25
26
  const document_1 = require("./document");
26
27
  exports.tasks = new WeakMap();
27
28
  const refTags = new Set(['ref']), referencesTags = new Set(['ref', 'references']), nameAttrs = new Set(['name', 'follow']), groupAttrs = new Set(['group']), renameTypes = new Set([
@@ -279,7 +280,7 @@ const partialParse = async (wikitext, watch, include, config = index_1.default.g
279
280
  };
280
281
  /* NOT FOR BROWSER ONLY */
281
282
  /** @see https://www.npmjs.com/package/stylelint-config-recommended */
282
- const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = document_1.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
283
+ const cssRules = { 'block-no-empty': null }, sources = { 'invalid-css': 'css', 'invalid-math': 'texvc' }, jsonSelector = constants_2.jsonTags.map(s => `ext#${s}`).join(), scores = new Map();
283
284
  let colors;
284
285
  /**
285
286
  * Correct the position of an error.
@@ -372,15 +373,15 @@ class LanguageService {
372
373
  exports.tasks.set(uri, this);
373
374
  /* NOT FOR BROWSER ONLY */
374
375
  const dataDir = path_1.default.join('..', '..', 'data'), extDir = path_1.default.join(dataDir, 'ext');
375
- this.#lilypondData = require(path_1.default.join(extDir, 'score'));
376
- this.#mathData = require(path_1.default.join(extDir, 'math'));
376
+ this.#lilypondData = require(path_1.default.join(extDir, 'score.json'));
377
+ this.#mathData = require(path_1.default.join(extDir, 'math.json'));
377
378
  /* NOT FOR BROWSER ONLY END */
378
379
  Object.defineProperties(this, {
379
380
  config: { enumerable: false },
380
381
  data: {
381
382
  enumerable: false,
382
383
  /* NOT FOR BROWSER ONLY */
383
- value: require(path_1.default.join(dataDir, 'signatures')),
384
+ value: require(path_1.default.join(dataDir, 'signatures.json')),
384
385
  },
385
386
  });
386
387
  }
@@ -491,15 +492,15 @@ class LanguageService {
491
492
  async provideDocumentColors(rgba, text, hsl = true) {
492
493
  const root = await this.#queue(text);
493
494
  /* NOT FOR BROWSER ONLY */
494
- colors ??= (async () => {
495
+ if (colors === undefined) {
495
496
  try {
496
- return new RegExp(String.raw `\b${Object.keys((await import('color-name')).default).join('|')}\b`, 'giu');
497
+ const { default: colorName } = require('color-name');
498
+ colors = new RegExp(String.raw `\b${Object.keys(colorName).join('|')}\b`, 'giu');
497
499
  }
498
500
  catch {
499
- return false;
501
+ colors = false;
500
502
  }
501
- })();
502
- const re = await colors;
503
+ }
503
504
  /* NOT FOR BROWSER ONLY END */
504
505
  return root.querySelectorAll('attr-value,parameter-value,arg-default').reverse().flatMap(token => {
505
506
  const { type, childNodes,
@@ -515,13 +516,13 @@ class LanguageService {
515
516
  /* NOT FOR BROWSER ONLY END */
516
517
  }
517
518
  /* NOT FOR BROWSER ONLY */
518
- const isStyle = re && type === 'attr-value' && parentNode.name === 'style';
519
+ const isStyle = colors && type === 'attr-value' && parentNode.name === 'style';
519
520
  /* NOT FOR BROWSER ONLY END */
520
521
  return childNodes.filter((child) => child.type === 'text').reverse().flatMap(child => {
521
522
  const { data } = child, parts = (0, common_1.splitColors)(data, hsl).filter(([, , , isColor]) => isColor);
522
523
  /* NOT FOR BROWSER ONLY */
523
524
  if (isStyle) {
524
- parts.push(...[...data.matchAll(re)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
525
+ parts.push(...[...data.matchAll(colors)].map(({ index, 0: s }) => [s, index, index + s.length, true]));
525
526
  }
526
527
  /* NOT FOR BROWSER ONLY END */
527
528
  if (parts.length === 0) {
@@ -762,7 +763,7 @@ class LanguageService {
762
763
  },
763
764
  }));
764
765
  }
765
- else if (type === 'ext-inner' && document_1.jsonTags.includes(cur.name)) {
766
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(cur.name)) {
766
767
  const jsonLSP = (0, document_1.loadJsonLSP)();
767
768
  if (!jsonLSP) {
768
769
  return undefined;
@@ -822,7 +823,7 @@ class LanguageService {
822
823
  const root = await this.#queue(text), { lintConfig } = index_1.default, needFix = lintConfig.fix;
823
824
  lintConfig.fix = false;
824
825
  /* NOT FOR BROWSER ONLY */
825
- const stylelint = await (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
826
+ const stylelint = (0, document_1.loadStylelint)(), jsonLSP = (0, document_1.loadJsonLSP)();
826
827
  let s;
827
828
  NPM: if (jsonLSP) {
828
829
  s = lintConfig.rules['invalid-json'];
@@ -1314,7 +1315,7 @@ class LanguageService {
1314
1315
  const textDoc = new document_1.EmbeddedCSSDocument(root, offsetNode);
1315
1316
  return (0, document_1.loadCssLSP)().doHover(textDoc, position, textDoc.styleSheet) ?? undefined;
1316
1317
  }
1317
- else if (type === 'ext-inner' && document_1.jsonTags.includes(name)) {
1318
+ else if (type === 'ext-inner' && constants_2.jsonTags.includes(name)) {
1318
1319
  const jsonLSP = (0, document_1.loadJsonLSP)();
1319
1320
  if (!jsonLSP) {
1320
1321
  return undefined;
@@ -1434,8 +1435,12 @@ class LanguageService {
1434
1435
  return hints;
1435
1436
  }
1436
1437
  /** @private */
1438
+ querySelectorAll(selector) {
1439
+ return this.#done.querySelectorAll(selector);
1440
+ }
1441
+ /** @private */
1437
1442
  findStyleTokens() {
1438
- return this.#done.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1443
+ return this.querySelectorAll(cssSelector).filter(({ lastChild }) => isAttr(lastChild));
1439
1444
  }
1440
1445
  /**
1441
1446
  * Provide refactoring actions
@@ -1577,7 +1582,7 @@ class LanguageService {
1577
1582
  async setTargetWikipedia(wiki, user) {
1578
1583
  const [site, host] = index_1.default.getWMFSite(wiki);
1579
1584
  try {
1580
- const config = require(path_1.default.join('..', '..', 'config', site));
1585
+ const config = require(path_1.default.join('..', '..', 'config', `${site}.json`));
1581
1586
  this.config = index_1.default.getConfig(config);
1582
1587
  }
1583
1588
  catch {
package/dist/lib/node.js CHANGED
@@ -196,10 +196,13 @@ let AstNode = (() => {
196
196
  : 0;
197
197
  }
198
198
  return (0, lint_1.cache)(this.#rIndex[j], () => {
199
- const { childNodes } = this, n = j + (j < 0 ? childNodes.length : 0);
199
+ const { childNodes } = this, parentAIndex = this.#aIndex?.[0] === debug_1.Shadow.rev && this.#aIndex[1], n = j + (j < 0 ? childNodes.length : 0);
200
200
  let acc = this.getAttribute('padding');
201
201
  for (let i = 0; i < n; i++) {
202
202
  this.#rIndex[i] = [debug_1.Shadow.rev, acc];
203
+ if (parentAIndex !== false) {
204
+ childNodes[i].#aIndex = [debug_1.Shadow.rev, parentAIndex + acc];
205
+ }
203
206
  acc += childNodes[i].toString().length + this.getGaps(i);
204
207
  }
205
208
  return acc;
@@ -108,14 +108,18 @@ let ConverterFlagsToken = (() => {
108
108
  }
109
109
  /** @private */
110
110
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
111
- isInvalidFlag(flag, variant, unknown, valid) {
112
- return Boolean(flag) && !variant.has(flag) && !unknown.has(flag) && (variant.size > 0 || !valid.has(flag));
111
+ isInvalidFlag(flag, variant, unknown) {
112
+ return Boolean(flag)
113
+ && !variant.has(flag)
114
+ && !unknown.has(flag)
115
+ && (variant.size > 0 || !definedFlags.has(flag));
113
116
  }
114
117
  /** @private */
115
118
  lint(start = this.getAbsoluteIndex(), re) {
116
119
  LINT: {
117
- const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), validFlags = new Set(this.#flags.filter(flag => definedFlags.has(flag))), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
118
- if (variantFlags.size === knownFlagCount || validFlags.size === knownFlagCount) {
120
+ const variantFlags = this.getVariantFlags(), unknownFlags = this.getUnknownFlags(), emptyFlagCount = this.#flags.filter(flag => !flag).length, knownFlagCount = this.#flags.length - unknownFlags.size - emptyFlagCount, { lintConfig } = index_1.default, { computeEditInfo, fix } = lintConfig, errors = super.lint(start, re);
121
+ if (variantFlags.size === knownFlagCount
122
+ || this.#flags.filter(flag => definedFlags.has(flag)).length === knownFlagCount) {
119
123
  return errors;
120
124
  }
121
125
  const rule = 'no-ignored', s = lintConfig.getSeverity(rule, 'conversionFlag');
@@ -123,7 +127,7 @@ let ConverterFlagsToken = (() => {
123
127
  const rect = new rect_1.BoundingRect(this, start);
124
128
  for (let i = 0; i < this.length; i++) {
125
129
  const child = this.childNodes[i], flag = child.text().trim();
126
- if (this.isInvalidFlag(flag, variantFlags, unknownFlags, validFlags)) {
130
+ if (this.isInvalidFlag(flag, variantFlags, unknownFlags)) {
127
131
  const e = (0, lint_1.generateForChild)(child, rect, rule, 'invalid-conversion-flag', s);
128
132
  if (computeEditInfo || fix) {
129
133
  if (variantFlags.size === 0 && definedFlags.has(flag.toUpperCase())) {
@@ -5,12 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NowikiToken = void 0;
7
7
  const common_1 = require("@bhsd/common");
8
+ const constants_1 = require("../../util/constants");
8
9
  const lint_1 = require("../../util/lint");
9
10
  const rect_1 = require("../../lib/rect");
10
11
  const index_1 = __importDefault(require("../../index"));
11
12
  const base_1 = require("./base");
12
13
  /* NOT FOR BROWSER ONLY */
13
- const constants_1 = require("../../util/constants");
14
+ const constants_2 = require("../../util/constants");
14
15
  const document_1 = require("../../lib/document");
15
16
  /** @ignore */
16
17
  const updateLocation = ({ startIndex, startLine, startCol, endIndex, endLine, endCol }, { offset, line, column }, n) => {
@@ -56,22 +57,10 @@ class NowikiToken extends base_1.NowikiBaseToken {
56
57
  }
57
58
  NPM: {
58
59
  rule = 'invalid-json';
59
- const sSyntax = lintConfig.getSeverity(rule);
60
- /* NOT FOR BROWSER ONLY */
61
- const sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
62
- /* NOT FOR BROWSER ONLY END */
63
- if (name === 'templatedata' && (sSyntax
64
- || sDuplicate)) {
65
- // browser版本使用`lintJSONNative()`
66
- return (0, common_1.lintJSON)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column,
67
- /* NOT FOR BROWSER ONLY */
68
- severity, }) => {
69
- s =
70
- /* eslint-disable @stylistic/operator-linebreak */
71
- severity === 'warning' ?
72
- sDuplicate :
73
- /* eslint-enable @stylistic/operator-linebreak */
74
- sSyntax;
60
+ const sSyntax = lintConfig.getSeverity(rule), sDuplicate = lintConfig.getSeverity(rule, 'duplicate');
61
+ if (constants_1.jsonTags.includes(name) && (sSyntax || sDuplicate)) {
62
+ return (name === 'templatedata' ? common_1.lintJSON : common_1.lintJSONC)(innerText).map(({ message, from, to = from, line, endLine = line, column, endColumn = column, severity, }) => {
63
+ s = severity === 'warning' ? sDuplicate : sSyntax;
75
64
  if (!s) {
76
65
  return false;
77
66
  }
@@ -92,7 +81,7 @@ class NowikiToken extends base_1.NowikiBaseToken {
92
81
  /* NOT FOR BROWSER ONLY */
93
82
  rule = 'invalid-math';
94
83
  s = lintConfig.getSeverity(rule);
95
- if (s && constants_1.mathTags.has(name)) {
84
+ if (s && constants_2.mathTags.has(name)) {
96
85
  const texvcjs = (0, document_1.loadTexvcjs)();
97
86
  if (texvcjs) {
98
87
  const isChem = name !== 'math', display = previousSibling?.getAttr('display') ?? 'block';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mathTags = exports.extensions = exports.galleryParams = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
3
+ exports.mathTags = exports.jsonTags = exports.extensions = exports.galleryParams = exports.enMsg = exports.BuildMethod = exports.MAX_STAGE = void 0;
4
4
  exports.MAX_STAGE = 11;
5
5
  var BuildMethod;
6
6
  (function (BuildMethod) {
@@ -13,5 +13,6 @@ exports.enMsg = (() => {
13
13
  })();
14
14
  exports.galleryParams = new Set(['alt', 'link', 'lang', 'page', 'caption']);
15
15
  exports.extensions = new Set(['tiff', 'tif', 'png', 'gif', 'jpg', 'jpeg', 'webp', 'xcf', 'pdf', 'svg', 'djvu']);
16
+ exports.jsonTags = ['templatedata', 'mapframe', 'maplink'];
16
17
  /* NOT FOR BROWSER ONLY */
17
18
  exports.mathTags = new Set(['math', 'chem', 'ce']);
package/dist/util/diff.js CHANGED
@@ -18,40 +18,42 @@ process.on('unhandledRejection', e => {
18
18
  * @param args shell输入参数
19
19
  */
20
20
  const cmd = (command, args) => new Promise(resolve => {
21
- let timer, shell;
22
- /**
23
- * 清除进程并返回
24
- * @param val 返回值
25
- */
26
- const r = (val) => {
27
- clearTimeout(timer);
28
- shell?.kill('SIGINT');
29
- resolve(val);
30
- };
31
- try {
32
- shell = (0, child_process_1.spawn)(command, args);
33
- timer = setTimeout(() => {
34
- /* c8 ignore next */
35
- shell.kill('SIGINT');
36
- }, 60 * 1e3);
37
- let buf = '';
38
- shell.stdout.on('data', data => {
39
- buf += String(data);
40
- });
41
- shell.stdout.on('end', () => {
42
- r(buf);
43
- });
44
- shell.on('exit', () => {
45
- r(shell.killed ? undefined : '');
46
- });
47
- shell.on('error', () => {
21
+ NPM: {
22
+ let timer, shell;
23
+ /**
24
+ * 清除进程并返回
25
+ * @param val 返回值
26
+ */
27
+ const r = (val) => {
28
+ clearTimeout(timer);
29
+ shell?.kill('SIGINT');
30
+ resolve(val);
31
+ };
32
+ try {
33
+ shell = (0, child_process_1.spawn)(command, args);
34
+ timer = setTimeout(() => {
35
+ /* c8 ignore next */
36
+ shell.kill('SIGINT');
37
+ }, 60 * 1e3);
38
+ let buf = '';
39
+ shell.stdout.on('data', data => {
40
+ buf += String(data);
41
+ });
42
+ shell.stdout.on('end', () => {
43
+ r(buf);
44
+ });
45
+ shell.on('exit', () => {
46
+ r(shell.killed ? undefined : '');
47
+ });
48
+ shell.on('error', () => {
49
+ r(undefined);
50
+ });
51
+ }
52
+ catch /* c8 ignore start */ {
48
53
  r(undefined);
49
- });
54
+ }
55
+ /* c8 ignore stop */
50
56
  }
51
- catch /* c8 ignore start */ {
52
- r(undefined);
53
- }
54
- /* c8 ignore stop */
55
57
  });
56
58
  exports.cmd = cmd;
57
59
  /* c8 ignore start */
@@ -62,37 +64,37 @@ exports.cmd = cmd;
62
64
  * @param uid 唯一标识
63
65
  */
64
66
  const diff = async (oldStr, newStr, uid) => {
65
- if (oldStr === newStr) {
66
- return;
67
+ NPM: {
68
+ if (oldStr === newStr) {
69
+ return;
70
+ }
71
+ const oldFile = `diffOld${uid}`, newFile = `diffNew${uid}`;
72
+ await Promise.all([promises_1.default.writeFile(oldFile, oldStr), promises_1.default.writeFile(newFile, newStr)]);
73
+ const stdout = await (0, exports.cmd)('git', [
74
+ 'diff',
75
+ '--color-words=[\xC0-\xFF][\x80-\xBF]+|<?/?\\w+/?>?|[^[:space:]]',
76
+ '-U0',
77
+ '--no-index',
78
+ oldFile,
79
+ newFile,
80
+ ]);
81
+ console.log(stdout?.split('\n').slice(4).join('\n'));
82
+ await Promise.allSettled([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
67
83
  }
68
- const oldFile = `diffOld${uid}`, newFile = `diffNew${uid}`;
69
- await Promise.all([promises_1.default.writeFile(oldFile, oldStr), promises_1.default.writeFile(newFile, newStr)]);
70
- const stdout = await (0, exports.cmd)('git', [
71
- 'diff',
72
- '--color-words=[\xC0-\xFF][\x80-\xBF]+|<?/?\\w+/?>?|[^[:space:]]',
73
- '-U0',
74
- '--no-index',
75
- oldFile,
76
- newFile,
77
- ]);
78
- console.log(stdout?.split('\n').slice(4).join('\n'));
79
- await Promise.allSettled([promises_1.default.unlink(oldFile), promises_1.default.unlink(newFile)]);
80
84
  };
81
85
  exports.diff = diff;
82
86
  /* c8 ignore stop */
83
87
  /* c8 ignore start */
84
88
  /** @implements */
85
89
  const error = (msg, ...args) => {
86
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
87
- console.error(util_1.default.styleText?.('red', msg) ?? msg, ...args);
90
+ console.error(util_1.default.styleText('red', msg), ...args);
88
91
  };
89
92
  exports.error = error;
90
93
  /* c8 ignore stop */
91
94
  /* c8 ignore start */
92
95
  /** @implements */
93
96
  const info = (msg, ...args) => {
94
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
95
- console.info(util_1.default.styleText?.('green', msg) ?? msg, ...args);
97
+ NPM: console.info(util_1.default.styleText('green', msg), ...args);
96
98
  };
97
99
  exports.info = info;
98
100
  /* c8 ignore stop */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikilint",
3
- "version": "2.36.0",
3
+ "version": "2.37.0",
4
4
  "description": "A Node.js linter for MediaWiki markup",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -12,7 +12,7 @@
12
12
  "bugs": {
13
13
  "url": "https://github.com/bhsd-harry/wikiparser-node/issues"
14
14
  },
15
- "license": "GPL-3.0",
15
+ "license": "GPL-3.0-or-later",
16
16
  "author": "Bhsd",
17
17
  "files": [
18
18
  "/errors/README",
@@ -73,44 +73,43 @@
73
73
  ]
74
74
  },
75
75
  "dependencies": {
76
- "@bhsd/cm-util": "^0.1.0",
77
- "@bhsd/common": "^1.3.1",
76
+ "@bhsd/cm-util": "^1.0.0",
77
+ "@bhsd/common": "^2.0.0",
78
78
  "@bhsd/stylelint-util": "^1.0.1",
79
79
  "binary-search": "^1.3.6",
80
80
  "vscode-languageserver-types": "^3.17.5"
81
81
  },
82
82
  "optionalDependencies": {
83
83
  "color-name": "^2.0.0",
84
- "entities": "^7.0.1",
84
+ "entities": "^8.0.0",
85
85
  "mathoid-texvcjs": "^0.6.0",
86
- "minimatch": "^10.2.4",
87
- "stylelint": "^17.4.0",
86
+ "stylelint": "^17.5.0",
88
87
  "vscode-css-languageservice": "^6.3.10",
89
88
  "vscode-html-languageservice": "^5.6.2",
90
89
  "vscode-json-languageservice": "^5.7.2"
91
90
  },
92
91
  "devDependencies": {
93
- "@bhsd/code-standard": "^2.1.0",
94
- "@bhsd/nodejs": "^0.1.1",
95
- "@bhsd/test-util": "^0.3.0",
96
- "@stylistic/eslint-plugin": "^5.9.0",
92
+ "@bhsd/code-standard": "^2.1.1",
93
+ "@bhsd/nodejs": "^1.0.0",
94
+ "@bhsd/test-util": "^0.4.0",
95
+ "@stylistic/eslint-plugin": "^5.10.0",
97
96
  "@types/color-name": "^2.0.0",
98
97
  "@types/color-rgba": "^2.1.3",
99
98
  "@types/mocha": "^10.0.10",
100
99
  "@types/node": "^24.11.0",
101
- "@typescript-eslint/eslint-plugin": "^8.54.0",
102
- "@typescript-eslint/parser": "^8.54.0",
100
+ "@typescript-eslint/eslint-plugin": "^8.57.0",
101
+ "@typescript-eslint/parser": "^8.57.0",
103
102
  "c8": "^11.0.0",
104
103
  "color-rgba": "^3.0.0",
105
104
  "diff2html-cli": "^5.2.15",
106
- "esbuild": "^0.27.3",
107
- "eslint": "^9.39.3",
105
+ "esbuild": "^0.27.4",
106
+ "eslint": "^9.39.4",
108
107
  "eslint-plugin-eslint-comments": "^3.2.0",
109
108
  "eslint-plugin-jsdoc": "^62.7.1",
110
109
  "eslint-plugin-jsonc": "^3.1.1",
111
110
  "eslint-plugin-n": "^17.24.0",
112
111
  "eslint-plugin-promise": "^7.2.1",
113
- "eslint-plugin-regexp": "^3.0.0",
112
+ "eslint-plugin-regexp": "^3.1.0",
114
113
  "eslint-plugin-unicorn": "^63.0.0",
115
114
  "markdownlint-cli2": "^0.21.0",
116
115
  "mocha": "^11.7.5",
@@ -119,6 +118,6 @@
119
118
  "vscode-languageserver-textdocument": "^1.0.12"
120
119
  },
121
120
  "engines": {
122
- "node": ">=20.19.0"
121
+ "node": "^20.19.0 || ^22.13.0 || >=24.11.0"
123
122
  }
124
123
  }