metalint 0.21.1 → 0.21.2

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,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020-2025 Sébastien Règne
3
+ Copyright (c) 2020-2026 Sébastien Règne
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -273,10 +273,10 @@ jobs:
273
273
  lint:
274
274
  runs-on: ubuntu-latest
275
275
  steps:
276
- - uses: actions/checkout@v5
276
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
277
277
  with:
278
278
  persist-credentials: false
279
- - uses: actions/setup-node@v5
279
+ - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
280
280
  - name: Install dependencies
281
281
  run: npm ci
282
282
  - name: Lint files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metalint",
3
- "version": "0.21.1",
3
+ "version": "0.21.2",
4
4
  "description": "One linter to rule them all.",
5
5
  "keywords": [
6
6
  "checker",
@@ -53,67 +53,72 @@
53
53
  },
54
54
  "type": "module",
55
55
  "scripts": {
56
+ "prepare": "tsc --project .tsconfig_types.json",
56
57
  "lint": "node src/bin/index.js",
57
58
  "lint:fix": "node src/bin/index.js --fix",
58
59
  "lint:types": "tsc --project .tsconfig_lint.json",
59
60
  "test": "npm run test:unit",
60
- "test:unit": "node --test 'test/unit/**/*.js'",
61
+ "test:unit": "npm run test:unit:node",
62
+ "test:unit:node": "node --test --import ./test/polyfills/node.js 'test/unit/**/*.test.js'",
63
+ "test:unit:bun": "bun test --preload ./test/polyfills/bun.js test/unit/",
64
+ "test:fuzz": "node --test 'test/fuzz/**/*.test.js'",
61
65
  "test:coverage": "stryker run",
62
- "test:fuzz": "node --test 'test/fuzz/**/*.js'",
63
66
  "jsdocs": "typedoc --tsconfig .tsconfig_jsdocs.json",
64
- "prepare": "tsc --project .tsconfig_types.json",
65
67
  "clean": "node .script/clean.js"
66
68
  },
67
69
  "devDependencies": {
68
70
  "@biomejs/js-api": "4.0.0",
69
- "@biomejs/wasm-nodejs": "2.3.1",
71
+ "@biomejs/wasm-nodejs": "2.3.10",
70
72
  "@coffeelint/cli": "5.2.11",
71
73
  "@mapbox/jsonlint-lines-primitives": "2.0.2",
72
74
  "@prantlf/jsonlint": "16.0.0",
73
75
  "@prettier/plugin-xml": "3.4.2",
74
76
  "@secretlint/secretlint-rule-github": "11.2.5",
75
77
  "@secretlint/secretlint-rule-npm": "11.2.5",
76
- "@stryker-mutator/core": "9.2.0",
77
- "@stryker-mutator/tap-runner": "9.2.0",
78
+ "@stryker-mutator/core": "9.4.0",
79
+ "@stryker-mutator/tap-runner": "9.4.0",
80
+ "@types/bun": "1.3.5",
78
81
  "@types/htmlhint": "1.1.5",
79
82
  "@types/js-yaml": "4.0.9",
80
83
  "@types/jshint": "2.12.4",
84
+ "@types/node": "25.0.3",
81
85
  "@types/semver-utils": "1.1.3",
82
- "addons-linter": "8.4.0",
86
+ "addons-linter": "9.3.0",
83
87
  "ajv": "8.17.1",
84
88
  "depcheck": "1.4.7",
85
- "doiuse": "6.0.5",
86
- "eslint": "9.38.0",
89
+ "doiuse": "6.0.6",
90
+ "eslint": "9.39.2",
87
91
  "eslint-plugin-array-func": "5.1.0",
88
92
  "eslint-plugin-eslint-comments": "3.2.0",
89
93
  "eslint-plugin-import": "2.32.0",
90
- "eslint-plugin-jsdoc": "61.1.9",
94
+ "eslint-plugin-jsdoc": "61.5.0",
91
95
  "eslint-plugin-mocha": "11.2.0",
92
96
  "eslint-plugin-n": "17.23.1",
93
97
  "eslint-plugin-no-unsanitized": "4.1.4",
94
98
  "eslint-plugin-promise": "7.2.1",
95
99
  "eslint-plugin-regexp": "2.10.0",
96
100
  "eslint-plugin-unicorn": "62.0.0",
97
- "fast-check": "4.3.0",
98
- "globals": "16.4.0",
99
- "htmlhint": "1.7.1",
101
+ "fast-check": "4.5.3",
102
+ "globals": "16.5.0",
103
+ "htmlhint": "1.8.0",
100
104
  "htmllint": "0.8.0",
101
105
  "jshint": "2.13.6",
102
106
  "jsonlint-mod": "1.7.6",
107
+ "jsr": "0.13.5",
103
108
  "jszip": "3.10.1",
104
- "markdownlint": "0.39.0",
105
- "markuplint": "4.13.1",
106
- "npm-check-updates": "19.1.1",
109
+ "markdownlint": "0.40.0",
110
+ "markuplint": "4.14.0",
111
+ "npm-check-updates": "19.2.0",
107
112
  "npm-package-json-lint": "9.0.0",
108
- "prettier": "3.6.2",
109
- "publint": "0.3.15",
113
+ "prettier": "3.7.4",
114
+ "publint": "0.3.16",
110
115
  "purgecss": "7.0.2",
111
116
  "secretlint": "11.2.5",
112
- "sort-package-json": "3.4.0",
117
+ "sort-package-json": "3.6.0",
113
118
  "standard": "17.1.2",
114
- "stylelint": "16.25.0",
119
+ "stylelint": "16.26.1",
115
120
  "svglint": "4.1.2",
116
- "typedoc": "0.28.14",
121
+ "typedoc": "0.28.15",
117
122
  "typescript": "5.9.3",
118
123
  "yaml-lint": "1.7.0"
119
124
  },
@@ -29,7 +29,10 @@ export const FORMATTERS = scripts
29
29
  // "formatter.js" qui n'est pas un vrai formateur.
30
30
  .filter((f) => f.endsWith(".js") && "formatter.js" !== f)
31
31
  // Enlever l'extension des fichiers.
32
- .map((f) => f.slice(0, -3));
32
+ .map((f) => f.slice(0, -3))
33
+ // Trier la liste, car Bun retourne une liste non-triée.
34
+ // https://github.com/oven-sh/bun/issues/25734
35
+ .toSorted((a, b) => a.localeCompare(b));
33
36
 
34
37
  /**
35
38
  * Le formateur parent.
@@ -252,6 +252,9 @@ export default class Glob {
252
252
  // Si c'est un répertoire : parcourir ses fichiers.
253
253
  if (base.endsWith("/")) {
254
254
  const dirents = await fs.readdir(base, { withFileTypes: true });
255
+ // Trier la liste, car Bun retourne une liste non-triée.
256
+ // https://github.com/oven-sh/bun/issues/25734
257
+ dirents.sort((a, b) => a.name.localeCompare(b.name));
255
258
  for (const dirent of dirents) {
256
259
  files.push(
257
260
  ...(await this.walk(
@@ -16,7 +16,7 @@ import Wrapper from "./wrapper.js";
16
16
 
17
17
  /**
18
18
  * @import { Level } from "../levels.js"
19
- * @import { Notice, PartialNotice } from "../results.js"
19
+ * @import { PartialNotice } from "../results.js"
20
20
  */
21
21
 
22
22
  const SEVERITY_MAPPINGS = {
@@ -61,14 +61,17 @@ const getUtf8ByteLength = (codeUnit) => {
61
61
  * Convertit l'intervalle en décalages d'octets UTF-8 en un intervalle en
62
62
  * décalages d'unités de code.
63
63
  *
64
- * @param {number[]} span L'intervalle en octets UTF-8.
65
- * @param {string} str La chaine de caractères.
66
- * @returns {number[]} L'intervalle en unités de code.
64
+ * @param {[number, number]} span L'intervalle en octets UTF-8.
65
+ * @param {string} str La chaine de caractères.
66
+ * @returns {[number, number]} L'intervalle en unités de code.
67
67
  * @see https://github.com/biomejs/website/blob/main/src/playground/utils.ts#L381
68
68
  * @see https://stackoverflow.com/a/73096001/4668057
69
69
  */
70
70
  const spanInBytesToSpanInCodeUnits = ([startInBytes, endInBytes], str) => {
71
- const spanInCodeUnits = [startInBytes, endInBytes];
71
+ const spanInCodeUnits = /** @type {[number, number]} */ ([
72
+ startInBytes,
73
+ endInBytes,
74
+ ]);
72
75
 
73
76
  let currCodeUnitIndex = 0;
74
77
 
@@ -111,8 +114,10 @@ const spanInBytesToSpanInCodeUnits = ([startInBytes, endInBytes], str) => {
111
114
  *
112
115
  * @param {number[]} lengths Le tableau des longueurs de chaque ligne.
113
116
  * @param {number} position La position à convertir.
114
- * @returns {object|undefined} La ligne et la colonne ; ou `undefined` si la
115
- * position est hors limites.
117
+ * @returns {{line: number, column: number}|undefined} La ligne et la colonne ;
118
+ * ou `undefined` si la
119
+ * position est hors
120
+ * limites.
116
121
  */
117
122
  const positionToLineColumn = (lengths, position) => {
118
123
  let index = 0;
@@ -202,70 +207,99 @@ export default class BiomeJsJsApiWrapper extends Wrapper {
202
207
  let source = await fs.readFile(file, "utf8");
203
208
  const notices = [];
204
209
 
205
- // Formater le fichier seulement si le formateur est activé.
206
- // https://github.com/biomejs/biome/issues/7814
207
- if (this.#options.formatter?.enabled ?? true) {
208
- const formatted = this.#biome.formatContent(
209
- this.#projectKey,
210
- source,
211
- {
212
- filePath: file,
213
- },
214
- );
215
- if (source !== formatted.content) {
216
- if (this.fix) {
217
- source = formatted.content;
218
- await fs.writeFile(file, source);
219
- } else {
220
- notices.push({
221
- file,
222
- linter: "biomejs__js-api",
223
- severity: Severities.ERROR,
224
- message: "Code style issues found.",
225
- });
210
+ try {
211
+ // Formater le fichier seulement si le formateur est activé.
212
+ // https://github.com/biomejs/biome/issues/7814
213
+ if (this.#options.formatter?.enabled ?? true) {
214
+ const formatted = this.#biome.formatContent(
215
+ this.#projectKey,
216
+ source,
217
+ {
218
+ filePath: file,
219
+ },
220
+ );
221
+ if (source !== formatted.content) {
222
+ if (this.fix) {
223
+ source = formatted.content;
224
+ await fs.writeFile(file, source);
225
+ } else {
226
+ notices.push({
227
+ file,
228
+ linter: "biomejs__js-api",
229
+ severity: Severities.ERROR,
230
+ message: "Code style issues found.",
231
+ });
232
+ }
226
233
  }
227
234
  }
228
- }
229
235
 
230
- // Analyser le fichier seulement si le linter est activé.
231
- // https://github.com/biomejs/biome/issues/7814
232
- if (this.#options.linter?.enabled ?? true) {
233
- const results = this.#biome.lintContent(this.#projectKey, source, {
234
- filePath: file,
235
- });
236
- // Calculer le nombre d'octets de chaque ligne (et ajouter un pour le
237
- // retour à ligne). https://github.com/biomejs/biome/issues/4035
238
- const lengths = source.split("\n").map((l) => l.length + 1);
239
- return results.diagnostics
240
- .map((diagnostic) => {
241
- const span = spanInBytesToSpanInCodeUnits(
242
- diagnostic.location.span,
243
- source,
244
- );
245
- const start = positionToLineColumn(lengths, span[0]);
246
- const end = positionToLineColumn(lengths, span[1]);
236
+ // Analyser le fichier seulement si le linter est activé.
237
+ // https://github.com/biomejs/biome/issues/7814
238
+ if (
239
+ (this.#options.linter?.enabled ?? true) ||
240
+ (this.#options.assist?.enabled ?? true)
241
+ ) {
242
+ const results = this.#biome.lintContent(
243
+ this.#projectKey,
244
+ source,
245
+ {
246
+ filePath: file,
247
+ },
248
+ );
249
+ // Calculer le nombre d'octets de chaque ligne (et ajouter un pour le
250
+ // retour à ligne). https://github.com/biomejs/biome/issues/4035
251
+ const lengths = source.split("\n").map((l) => l.length + 1);
252
+ notices.push(
253
+ ...results.diagnostics
254
+ .filter(
255
+ (d) =>
256
+ undefined === d.category ||
257
+ (d.category.startsWith("lint/") &&
258
+ (this.#options.linter?.enabled ?? true)) ||
259
+ (d.category.startsWith("assist/") &&
260
+ (this.#options.assist?.enabled ?? true)),
261
+ )
262
+ .map((diagnostic) => {
263
+ const span = spanInBytesToSpanInCodeUnits(
264
+ diagnostic.location.span,
265
+ source,
266
+ );
267
+ const start = positionToLineColumn(
268
+ lengths,
269
+ span[0],
270
+ );
271
+ const end = positionToLineColumn(lengths, span[1]);
247
272
 
248
- return {
249
- file,
250
- linter: "biomejs__js-api",
251
- // Enlever le préfixe "lint/".
252
- rule: diagnostic.category?.slice(5),
253
- severity: SEVERITY_MAPPINGS[diagnostic.severity],
254
- message: diagnostic.description,
255
- locations: [
256
- {
257
- line: start.line,
258
- column: start.column,
259
- endLine: end.line,
260
- endColumn: end.column,
261
- },
262
- ],
263
- };
264
- })
265
- .concat(notices)
266
- .filter((n) => this.level >= n.severity);
267
- }
273
+ return {
274
+ file,
275
+ linter: "biomejs__js-api",
276
+ rule: diagnostic.category,
277
+ severity:
278
+ SEVERITY_MAPPINGS[diagnostic.severity],
279
+ message: diagnostic.description,
280
+ locations: [
281
+ {
282
+ line: start.line,
283
+ column: start.column,
284
+ endLine: end.line,
285
+ endColumn: end.column,
286
+ },
287
+ ],
288
+ };
289
+ }),
290
+ );
291
+ }
268
292
 
269
- return [];
293
+ return notices.filter((n) => this.level >= n.severity);
294
+ } catch (err) {
295
+ return [
296
+ {
297
+ file,
298
+ severity: Severities.FATAL,
299
+ linter: "biomejs__js-api",
300
+ message: err.stackTrace.message,
301
+ },
302
+ ];
303
+ }
270
304
  }
271
305
  }
@@ -40,7 +40,10 @@ export const WRAPPERS = scripts
40
40
  // "wrapper.js" qui n'est pas un vrai enrobage.
41
41
  .filter((f) => f.endsWith(".js") && "wrapper.js" !== f)
42
42
  // Enlever l'extension des fichiers.
43
- .map((f) => f.slice(0, -3));
43
+ .map((f) => f.slice(0, -3))
44
+ // Trier la liste, car Bun retourne une liste non-triée.
45
+ // https://github.com/oven-sh/bun/issues/25734
46
+ .toSorted((a, b) => a.localeCompare(b));
44
47
 
45
48
  /**
46
49
  * La classe mère des enrobages de linters.