eslint-plugin-baseline-js 0.1.0 → 0.2.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/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  Enforce the JavaScript Baseline (`widely` / `newly` / `year`) with a single ESLint rule powered by web‑features.
8
8
  This plugin delegates detection to eslint-plugin-es-x and ESLint core (plus a few small gap‑filling rules) and reports with one consistent Baseline message.
9
9
 
10
+ [![npm](https://img.shields.io/npm/v/eslint-plugin-baseline-js?logoColor=green&color=green)](https://www.npmjs.com/package/eslint-plugin-baseline-js)
10
11
  [![CI](https://github.com/3ru/eslint-plugin-baseline-js/actions/workflows/ci.yml/badge.svg)](https://github.com/3ru/eslint-plugin-baseline-js/actions/workflows/ci.yml)
11
12
  [![Release](https://github.com/3ru/eslint-plugin-baseline-js/actions/workflows/release.yml/badge.svg)](https://github.com/3ru/eslint-plugin-baseline-js/actions/workflows/release.yml)
12
13
  <img alt="License" src="https://img.shields.io/badge/license-MIT-blue" />
@@ -56,11 +57,11 @@ export default [
56
57
 
57
58
  // Recommended: enables Web APIs & JS builtins detection with `preset: 'auto'`.
58
59
  // Level defaults to 'error'; pass level to change severity
59
- ...baselineJs.configs.recommended({ available: "widely", level: "warn" }),
60
+ baselineJs.configs.recommended({ available: "widely", level: "warn" }),
60
61
 
61
62
  // TypeScript-aware: requires type info for instance-member checks (`preset: 'type-aware'`).
62
63
  // Works best with @typescript-eslint/parser and a proper tsconfig.
63
- // ...baselineJs.configs["recommended-ts"]({ available: "widely", level: "error" }),
64
+ // baselineJs.configs["recommended-ts"]({ available: "widely", level: "error" }),
64
65
  ];
65
66
  ```
66
67
 
package/dist/index.cjs CHANGED
@@ -28,11 +28,6 @@ let eslint_plugin_es_x = require("eslint-plugin-es-x");
28
28
  eslint_plugin_es_x = __toESM(eslint_plugin_es_x);
29
29
 
30
30
  //#region src/configs/baseline.ts
31
- function baselineConfigs(opts = {}) {
32
- const available = opts.available ?? opts.baseline ?? "widely";
33
- const level = opts.level ?? "error";
34
- return [{ rules: { "baseline-js/use-baseline": [level, { available }] } }];
35
- }
36
31
  /**
37
32
  * Recommended config: enable Baseline with Web APIs and JS builtins detection on auto preset.
38
33
  * - baseline: defaults to 'widely'
@@ -41,11 +36,14 @@ function baselineConfigs(opts = {}) {
41
36
  function recommendedConfig(opts = {}) {
42
37
  const available = opts.available ?? opts.baseline ?? "widely";
43
38
  const level = opts.level ?? "error";
44
- return [{ rules: { "baseline-js/use-baseline": [level, {
45
- available,
46
- includeWebApis: { preset: "auto" },
47
- includeJsBuiltins: { preset: "auto" }
48
- }] } }];
39
+ return {
40
+ files: ["**/*.{js,cjs,mjs,jsx}"],
41
+ rules: { "baseline-js/use-baseline": [level, {
42
+ available,
43
+ includeWebApis: { preset: "auto" },
44
+ includeJsBuiltins: { preset: "auto" }
45
+ }] }
46
+ };
49
47
  }
50
48
  /**
51
49
  * Recommended config for TypeScript-aware projects:
@@ -55,11 +53,14 @@ function recommendedConfig(opts = {}) {
55
53
  function recommendedTsConfig(opts = {}) {
56
54
  const available = opts.available ?? opts.baseline ?? "widely";
57
55
  const level = opts.level ?? "error";
58
- return [{ rules: { "baseline-js/use-baseline": [level, {
59
- available,
60
- includeWebApis: { preset: "type-aware" },
61
- includeJsBuiltins: { preset: "type-aware" }
62
- }] } }];
56
+ return {
57
+ files: ["**/*.{ts,tsx}"],
58
+ rules: { "baseline-js/use-baseline": [level, {
59
+ available,
60
+ includeWebApis: { preset: "type-aware" },
61
+ includeJsBuiltins: { preset: "type-aware" }
62
+ }] }
63
+ };
63
64
  }
64
65
 
65
66
  //#endregion
@@ -55813,6 +55814,7 @@ function isBeyondBaseline(featureId, baseline) {
55813
55814
  if (baseline === "widely") return bucket !== "widely";
55814
55815
  if (baseline === "newly") return bucket === "limited";
55815
55816
  if (typeof baseline === "number") {
55817
+ if (bucket === "limited") return true;
55816
55818
  const y = yearFrom(rec.status?.baseline_low_date) ?? yearFrom(rec.status?.baseline_high_date);
55817
55819
  if (y == null) return false;
55818
55820
  return y > baseline;
@@ -56201,6 +56203,8 @@ const rule$2 = {
56201
56203
  },
56202
56204
  MemberExpression(node) {
56203
56205
  const m = node;
56206
+ const parent = m.parent;
56207
+ if (parent?.type === "CallExpression" && parent.callee === node) return;
56204
56208
  if (m.computed === false && m.object?.type === "Identifier" && m.object?.name === "Math" && m.property?.type === "Identifier" && m.property?.name === "sumPrecise") report(m.property);
56205
56209
  }
56206
56210
  };
@@ -56259,11 +56263,14 @@ function mergeListeners(target, add) {
56259
56263
  }
56260
56264
  }
56261
56265
  function baselineMessage(featureId, baseline) {
56262
- if (baseline === "widely") return `Feature '${featureId}' is not a widely available Baseline feature.`;
56263
- if (baseline === "newly") return `Feature '${featureId}' is not a newly available Baseline feature.`;
56264
56266
  const rec = getFeatureRecord(featureId);
56267
+ const label = rec?.name || featureId;
56268
+ const idSuffix = rec?.name ? ` (${featureId})` : "";
56269
+ if (baseline === "widely") return `Feature '${label}'${idSuffix} is not a widely available Baseline feature.`;
56270
+ if (baseline === "newly") return `Feature '${label}'${idSuffix} is not a newly available Baseline feature.`;
56271
+ if (rec?.status?.baseline === false) return `Feature '${label}'${idSuffix} has Limited availability and exceeds ${baseline}.`;
56265
56272
  const year = rec?.status?.baseline_low_date?.slice(0, 4) || rec?.status?.baseline_high_date?.slice(0, 4) || "unknown";
56266
- return `Feature '${featureId}' became Baseline in ${year} and exceeds ${baseline}.`;
56273
+ return `Feature '${label}'${idSuffix} became Baseline in ${year} and exceeds ${baseline}.`;
56267
56274
  }
56268
56275
  const rule = {
56269
56276
  meta: {
@@ -56353,6 +56360,14 @@ const rule = {
56353
56360
  }]
56354
56361
  },
56355
56362
  create(ctx) {
56363
+ const getFilename = ctx.getFilename;
56364
+ let filename = null;
56365
+ if (typeof getFilename === "function") try {
56366
+ filename = getFilename();
56367
+ } catch {}
56368
+ if (filename) {
56369
+ if (!/\.(?:[mc]?[jt]s|[jt]sx)$/i.test(filename)) return {};
56370
+ }
56356
56371
  const opt = ctx.options[0] ?? {};
56357
56372
  const baseline = getBaselineValue(opt);
56358
56373
  const ignoreFeaturePatterns = opt.ignoreFeatures ?? [];
@@ -56548,7 +56563,6 @@ const rules = {
56548
56563
  var src_default = {
56549
56564
  rules,
56550
56565
  configs: {
56551
- baseline: baselineConfigs,
56552
56566
  recommended: recommendedConfig,
56553
56567
  "recommended-ts": recommendedTsConfig
56554
56568
  }
package/dist/index.d.cts CHANGED
@@ -16,14 +16,6 @@ type BaselineName = (typeof BASELINE)[keyof typeof BASELINE];
16
16
  type BaselineOption = BaselineName | number;
17
17
  //#endregion
18
18
  //#region src/configs/baseline.d.ts
19
- declare function baselineConfigs(opts?: {
20
- available?: BaselineOption;
21
- baseline?: BaselineOption;
22
- env?: "browser" | "worker" | "node";
23
- level?: "error" | "warn";
24
- }): {
25
- rules: Record<string, unknown>;
26
- }[];
27
19
  /**
28
20
  * Recommended config: enable Baseline with Web APIs and JS builtins detection on auto preset.
29
21
  * - baseline: defaults to 'widely'
@@ -35,8 +27,9 @@ declare function recommendedConfig(opts?: {
35
27
  env?: "browser" | "worker" | "node";
36
28
  level?: "error" | "warn";
37
29
  }): {
38
- rules: Record<string, unknown>;
39
- }[];
30
+ readonly files: readonly ["**/*.{js,cjs,mjs,jsx}"];
31
+ readonly rules: Record<string, unknown>;
32
+ };
40
33
  /**
41
34
  * Recommended config for TypeScript-aware projects:
42
35
  * - Uses 'type-aware' preset to require type information for instance-member checks.
@@ -48,14 +41,14 @@ declare function recommendedTsConfig(opts?: {
48
41
  env?: "browser" | "worker" | "node";
49
42
  level?: "error" | "warn";
50
43
  }): {
51
- rules: Record<string, unknown>;
52
- }[];
44
+ readonly files: readonly ["**/*.{ts,tsx}"];
45
+ readonly rules: Record<string, unknown>;
46
+ };
53
47
  //#endregion
54
48
  //#region src/index.d.ts
55
49
  declare const _default: {
56
50
  readonly rules: Record<string, Rule.RuleModule>;
57
51
  readonly configs: {
58
- readonly baseline: typeof baselineConfigs;
59
52
  readonly recommended: typeof recommendedConfig;
60
53
  readonly "recommended-ts": typeof recommendedTsConfig;
61
54
  };
package/dist/index.d.mts CHANGED
@@ -16,14 +16,6 @@ type BaselineName = (typeof BASELINE)[keyof typeof BASELINE];
16
16
  type BaselineOption = BaselineName | number;
17
17
  //#endregion
18
18
  //#region src/configs/baseline.d.ts
19
- declare function baselineConfigs(opts?: {
20
- available?: BaselineOption;
21
- baseline?: BaselineOption;
22
- env?: "browser" | "worker" | "node";
23
- level?: "error" | "warn";
24
- }): {
25
- rules: Record<string, unknown>;
26
- }[];
27
19
  /**
28
20
  * Recommended config: enable Baseline with Web APIs and JS builtins detection on auto preset.
29
21
  * - baseline: defaults to 'widely'
@@ -35,8 +27,9 @@ declare function recommendedConfig(opts?: {
35
27
  env?: "browser" | "worker" | "node";
36
28
  level?: "error" | "warn";
37
29
  }): {
38
- rules: Record<string, unknown>;
39
- }[];
30
+ readonly files: readonly ["**/*.{js,cjs,mjs,jsx}"];
31
+ readonly rules: Record<string, unknown>;
32
+ };
40
33
  /**
41
34
  * Recommended config for TypeScript-aware projects:
42
35
  * - Uses 'type-aware' preset to require type information for instance-member checks.
@@ -48,14 +41,14 @@ declare function recommendedTsConfig(opts?: {
48
41
  env?: "browser" | "worker" | "node";
49
42
  level?: "error" | "warn";
50
43
  }): {
51
- rules: Record<string, unknown>;
52
- }[];
44
+ readonly files: readonly ["**/*.{ts,tsx}"];
45
+ readonly rules: Record<string, unknown>;
46
+ };
53
47
  //#endregion
54
48
  //#region src/index.d.ts
55
49
  declare const _default: {
56
50
  readonly rules: Record<string, Rule.RuleModule>;
57
51
  readonly configs: {
58
- readonly baseline: typeof baselineConfigs;
59
52
  readonly recommended: typeof recommendedConfig;
60
53
  readonly "recommended-ts": typeof recommendedTsConfig;
61
54
  };
package/dist/index.mjs CHANGED
@@ -2,11 +2,6 @@ import { builtinRules } from "eslint/use-at-your-own-risk";
2
2
  import esx from "eslint-plugin-es-x";
3
3
 
4
4
  //#region src/configs/baseline.ts
5
- function baselineConfigs(opts = {}) {
6
- const available = opts.available ?? opts.baseline ?? "widely";
7
- const level = opts.level ?? "error";
8
- return [{ rules: { "baseline-js/use-baseline": [level, { available }] } }];
9
- }
10
5
  /**
11
6
  * Recommended config: enable Baseline with Web APIs and JS builtins detection on auto preset.
12
7
  * - baseline: defaults to 'widely'
@@ -15,11 +10,14 @@ function baselineConfigs(opts = {}) {
15
10
  function recommendedConfig(opts = {}) {
16
11
  const available = opts.available ?? opts.baseline ?? "widely";
17
12
  const level = opts.level ?? "error";
18
- return [{ rules: { "baseline-js/use-baseline": [level, {
19
- available,
20
- includeWebApis: { preset: "auto" },
21
- includeJsBuiltins: { preset: "auto" }
22
- }] } }];
13
+ return {
14
+ files: ["**/*.{js,cjs,mjs,jsx}"],
15
+ rules: { "baseline-js/use-baseline": [level, {
16
+ available,
17
+ includeWebApis: { preset: "auto" },
18
+ includeJsBuiltins: { preset: "auto" }
19
+ }] }
20
+ };
23
21
  }
24
22
  /**
25
23
  * Recommended config for TypeScript-aware projects:
@@ -29,11 +27,14 @@ function recommendedConfig(opts = {}) {
29
27
  function recommendedTsConfig(opts = {}) {
30
28
  const available = opts.available ?? opts.baseline ?? "widely";
31
29
  const level = opts.level ?? "error";
32
- return [{ rules: { "baseline-js/use-baseline": [level, {
33
- available,
34
- includeWebApis: { preset: "type-aware" },
35
- includeJsBuiltins: { preset: "type-aware" }
36
- }] } }];
30
+ return {
31
+ files: ["**/*.{ts,tsx}"],
32
+ rules: { "baseline-js/use-baseline": [level, {
33
+ available,
34
+ includeWebApis: { preset: "type-aware" },
35
+ includeJsBuiltins: { preset: "type-aware" }
36
+ }] }
37
+ };
37
38
  }
38
39
 
39
40
  //#endregion
@@ -55787,6 +55788,7 @@ function isBeyondBaseline(featureId, baseline) {
55787
55788
  if (baseline === "widely") return bucket !== "widely";
55788
55789
  if (baseline === "newly") return bucket === "limited";
55789
55790
  if (typeof baseline === "number") {
55791
+ if (bucket === "limited") return true;
55790
55792
  const y = yearFrom(rec.status?.baseline_low_date) ?? yearFrom(rec.status?.baseline_high_date);
55791
55793
  if (y == null) return false;
55792
55794
  return y > baseline;
@@ -56175,6 +56177,8 @@ const rule$2 = {
56175
56177
  },
56176
56178
  MemberExpression(node) {
56177
56179
  const m = node;
56180
+ const parent = m.parent;
56181
+ if (parent?.type === "CallExpression" && parent.callee === node) return;
56178
56182
  if (m.computed === false && m.object?.type === "Identifier" && m.object?.name === "Math" && m.property?.type === "Identifier" && m.property?.name === "sumPrecise") report(m.property);
56179
56183
  }
56180
56184
  };
@@ -56233,11 +56237,14 @@ function mergeListeners(target, add) {
56233
56237
  }
56234
56238
  }
56235
56239
  function baselineMessage(featureId, baseline) {
56236
- if (baseline === "widely") return `Feature '${featureId}' is not a widely available Baseline feature.`;
56237
- if (baseline === "newly") return `Feature '${featureId}' is not a newly available Baseline feature.`;
56238
56240
  const rec = getFeatureRecord(featureId);
56241
+ const label = rec?.name || featureId;
56242
+ const idSuffix = rec?.name ? ` (${featureId})` : "";
56243
+ if (baseline === "widely") return `Feature '${label}'${idSuffix} is not a widely available Baseline feature.`;
56244
+ if (baseline === "newly") return `Feature '${label}'${idSuffix} is not a newly available Baseline feature.`;
56245
+ if (rec?.status?.baseline === false) return `Feature '${label}'${idSuffix} has Limited availability and exceeds ${baseline}.`;
56239
56246
  const year = rec?.status?.baseline_low_date?.slice(0, 4) || rec?.status?.baseline_high_date?.slice(0, 4) || "unknown";
56240
- return `Feature '${featureId}' became Baseline in ${year} and exceeds ${baseline}.`;
56247
+ return `Feature '${label}'${idSuffix} became Baseline in ${year} and exceeds ${baseline}.`;
56241
56248
  }
56242
56249
  const rule = {
56243
56250
  meta: {
@@ -56327,6 +56334,14 @@ const rule = {
56327
56334
  }]
56328
56335
  },
56329
56336
  create(ctx) {
56337
+ const getFilename = ctx.getFilename;
56338
+ let filename = null;
56339
+ if (typeof getFilename === "function") try {
56340
+ filename = getFilename();
56341
+ } catch {}
56342
+ if (filename) {
56343
+ if (!/\.(?:[mc]?[jt]s|[jt]sx)$/i.test(filename)) return {};
56344
+ }
56330
56345
  const opt = ctx.options[0] ?? {};
56331
56346
  const baseline = getBaselineValue(opt);
56332
56347
  const ignoreFeaturePatterns = opt.ignoreFeatures ?? [];
@@ -56522,7 +56537,6 @@ const rules = {
56522
56537
  var src_default = {
56523
56538
  rules,
56524
56539
  configs: {
56525
- baseline: baselineConfigs,
56526
56540
  recommended: recommendedConfig,
56527
56541
  "recommended-ts": recommendedTsConfig
56528
56542
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-baseline-js",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Enforce JavaScript Baseline (widely/newly/year) browser compatibility with a single ESLint rule. Prevent runtime errors by catching unsupported JavaScript features during development.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -42,14 +42,14 @@
42
42
  "eslint-plugin-es-x": "^9.1.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@biomejs/biome": "^2.2.3",
45
+ "@biomejs/biome": "^2.2.4",
46
46
  "@semantic-release/changelog": "^6.0.3",
47
47
  "@semantic-release/git": "^10.0.1",
48
48
  "@types/eslint": "^9.6.1",
49
- "@types/node": "^24.3.1",
49
+ "@types/node": "^24.4.0",
50
50
  "@typescript-eslint/parser": "^8.43.0",
51
51
  "semantic-release": "^24.2.7",
52
- "tsdown": "v0.14.2",
52
+ "tsdown": "v0.15.1",
53
53
  "typescript": "^5.4.0",
54
54
  "vitest": "^3.2.4",
55
55
  "web-features": "^2.47.0"
@@ -75,7 +75,7 @@
75
75
  "typescript",
76
76
  "linting"
77
77
  ],
78
- "homepage": "https://github.com/3ru/eslint-plugin-baseline-js#readme",
78
+ "homepage": "https://baselinejs.vercel.app/",
79
79
  "bugs": {
80
80
  "url": "https://github.com/3ru/eslint-plugin-baseline-js/issues"
81
81
  },