eslint-plugin-baseline-js 0.7.3 → 0.7.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.
- package/README.md +1 -1
- package/dist/index.mjs +98 -103
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ This plugin delegates detection to eslint-plugin-es-x and ESLint core (plus a fe
|
|
|
26
26
|
- yarn: `yarn add -D eslint-plugin-baseline-js`
|
|
27
27
|
|
|
28
28
|
Recommended
|
|
29
|
-
- ESLint >=
|
|
29
|
+
- ESLint >= 9.29.0 and < 11 (Flat Config)
|
|
30
30
|
|
|
31
31
|
## Quick Start (Flat Config)
|
|
32
32
|
|
package/dist/index.mjs
CHANGED
|
@@ -64403,71 +64403,45 @@ function addTypedInstanceMemberDetector(context, d, report) {
|
|
|
64403
64403
|
//#region src/rules/feature-usage/builder.ts
|
|
64404
64404
|
function buildListeners(context, opt) {
|
|
64405
64405
|
const listeners = {};
|
|
64406
|
-
function report(node, featureId) {
|
|
64407
|
-
const msg = opt.messages[featureId] ?? `Feature '${featureId}' exceeds configured Baseline.`;
|
|
64408
|
-
context.report({
|
|
64409
|
-
node,
|
|
64410
|
-
message: msg
|
|
64411
|
-
});
|
|
64412
|
-
}
|
|
64413
64406
|
const ctxLike = context;
|
|
64414
64407
|
const services = ctxLike.parserServices || ctxLike.sourceCode?.parserServices || {};
|
|
64415
64408
|
const checker = services.program?.getTypeChecker?.();
|
|
64416
64409
|
const useTyped = !!opt.typed && !!checker && !!services.esTreeNodeToTSNodeMap;
|
|
64417
|
-
for (const d of opt.descriptors)
|
|
64418
|
-
|
|
64419
|
-
|
|
64420
|
-
|
|
64421
|
-
|
|
64422
|
-
|
|
64423
|
-
|
|
64424
|
-
|
|
64425
|
-
|
|
64426
|
-
|
|
64427
|
-
|
|
64428
|
-
|
|
64429
|
-
|
|
64430
|
-
|
|
64431
|
-
|
|
64432
|
-
|
|
64433
|
-
|
|
64434
|
-
|
|
64435
|
-
|
|
64436
|
-
|
|
64437
|
-
|
|
64438
|
-
|
|
64439
|
-
|
|
64440
|
-
|
|
64441
|
-
|
|
64442
|
-
|
|
64410
|
+
for (const d of opt.descriptors) {
|
|
64411
|
+
function report(node) {
|
|
64412
|
+
opt.report(node, d);
|
|
64413
|
+
}
|
|
64414
|
+
switch (d.kind) {
|
|
64415
|
+
case "newIdent":
|
|
64416
|
+
mergeRuleListeners(listeners, addNewIdentDetector(context, d, report));
|
|
64417
|
+
break;
|
|
64418
|
+
case "newMember":
|
|
64419
|
+
mergeRuleListeners(listeners, addNewMemberDetector(context, d, report));
|
|
64420
|
+
break;
|
|
64421
|
+
case "callStatic":
|
|
64422
|
+
mergeRuleListeners(listeners, addCallStaticDetector(context, d, report));
|
|
64423
|
+
break;
|
|
64424
|
+
case "callGlobal":
|
|
64425
|
+
mergeRuleListeners(listeners, addCallGlobalDetector(context, d, report));
|
|
64426
|
+
break;
|
|
64427
|
+
case "member":
|
|
64428
|
+
mergeRuleListeners(listeners, addMemberDetector(context, d, report));
|
|
64429
|
+
break;
|
|
64430
|
+
case "staticMember":
|
|
64431
|
+
mergeRuleListeners(listeners, addStaticMemberDetector(context, d, report));
|
|
64432
|
+
break;
|
|
64433
|
+
case "instanceMember":
|
|
64434
|
+
if (useTyped) mergeRuleListeners(listeners, addTypedInstanceMemberDetector(context, d, report));
|
|
64435
|
+
break;
|
|
64436
|
+
case "callMemberWithArgs":
|
|
64437
|
+
mergeRuleListeners(listeners, addCallMemberWithArgsDetector(context, d, report));
|
|
64438
|
+
break;
|
|
64439
|
+
case "newWithOptions": mergeRuleListeners(listeners, addNewWithOptionsDetector(context, d, report));
|
|
64440
|
+
}
|
|
64443
64441
|
}
|
|
64444
64442
|
return listeners;
|
|
64445
64443
|
}
|
|
64446
64444
|
//#endregion
|
|
64447
|
-
//#region src/rules/feature-usage/index.ts
|
|
64448
|
-
const rule$6 = {
|
|
64449
|
-
meta: {
|
|
64450
|
-
type: "problem",
|
|
64451
|
-
docs: { description: "Detect usage of Web APIs and JS builtins beyond configured Baseline (data-driven)." },
|
|
64452
|
-
schema: [{
|
|
64453
|
-
type: "object",
|
|
64454
|
-
properties: {
|
|
64455
|
-
descriptors: { type: "array" },
|
|
64456
|
-
messages: { type: "object" }
|
|
64457
|
-
},
|
|
64458
|
-
additionalProperties: false
|
|
64459
|
-
}]
|
|
64460
|
-
},
|
|
64461
|
-
create(context) {
|
|
64462
|
-
const opt = context.options?.[0] ?? {};
|
|
64463
|
-
return buildListeners(context, {
|
|
64464
|
-
descriptors: opt.descriptors ?? [],
|
|
64465
|
-
messages: opt.messages ?? {},
|
|
64466
|
-
typed: !!opt.typed
|
|
64467
|
-
});
|
|
64468
|
-
}
|
|
64469
|
-
};
|
|
64470
|
-
//#endregion
|
|
64471
64445
|
//#region src/rules/no-atomics-pause/index.ts
|
|
64472
64446
|
const rule$5 = {
|
|
64473
64447
|
meta: {
|
|
@@ -64713,6 +64687,52 @@ function listResolverPlugins() {
|
|
|
64713
64687
|
return Object.keys(registry).sort();
|
|
64714
64688
|
}
|
|
64715
64689
|
//#endregion
|
|
64690
|
+
//#region src/orchestrator/messages.ts
|
|
64691
|
+
function baselineMessage(featureId, baseline, subject) {
|
|
64692
|
+
const feature = getFeatureRecord(featureId);
|
|
64693
|
+
const label = subject ?? `'${feature?.name ?? featureId}'`;
|
|
64694
|
+
if (baseline === "widely") return `${label} is not Baseline Widely available (${featureId}).`;
|
|
64695
|
+
if (baseline === "newly") return `${label} is not Baseline Newly available (${featureId}).`;
|
|
64696
|
+
if (feature?.status?.baseline === false) return `${label} has Limited availability and exceeds ${baseline} (${featureId}).`;
|
|
64697
|
+
return `${label} became Baseline in ${baselineYearLabel(feature?.status) ?? "unknown"} and exceeds ${baseline} (${featureId}).`;
|
|
64698
|
+
}
|
|
64699
|
+
function delegateSubject(name) {
|
|
64700
|
+
const separator = name.lastIndexOf(".");
|
|
64701
|
+
if (separator === -1) return `'${name}'`;
|
|
64702
|
+
const owner = name.slice(0, separator).replace(/\.prototype$/, "");
|
|
64703
|
+
return memberSubject(name.slice(separator + 1), owner);
|
|
64704
|
+
}
|
|
64705
|
+
function descriptorSubject(descriptor) {
|
|
64706
|
+
switch (descriptor.kind) {
|
|
64707
|
+
case "newIdent":
|
|
64708
|
+
case "callGlobal": return `'${descriptor.name}'`;
|
|
64709
|
+
case "newMember":
|
|
64710
|
+
case "callStatic":
|
|
64711
|
+
case "member":
|
|
64712
|
+
case "staticMember": return memberSubject(descriptor.prop, descriptor.base);
|
|
64713
|
+
case "instanceMember": return memberSubject(descriptor.prop, descriptor.iface);
|
|
64714
|
+
case "callMemberWithArgs":
|
|
64715
|
+
case "newWithOptions": return callSubject(descriptor);
|
|
64716
|
+
}
|
|
64717
|
+
}
|
|
64718
|
+
function memberSubject(name, owner) {
|
|
64719
|
+
return `'${name}' on ${owner}`;
|
|
64720
|
+
}
|
|
64721
|
+
function callSubject(descriptor) {
|
|
64722
|
+
const args = [];
|
|
64723
|
+
const objectArg = descriptor.objectArg;
|
|
64724
|
+
if (descriptor.kind === "callMemberWithArgs" && descriptor.stringArg) args[descriptor.stringArg.index] = descriptor.stringArg.values.map((value) => JSON.stringify(value)).join(" | ");
|
|
64725
|
+
if (objectArg) {
|
|
64726
|
+
const properties = /* @__PURE__ */ new Map();
|
|
64727
|
+
for (const key of objectArg.hasKeys ?? []) properties.set(key, "...");
|
|
64728
|
+
for (const { key, values } of objectArg.keyValues ?? []) properties.set(key, values?.map((value) => JSON.stringify(value)).join(" | ") || "...");
|
|
64729
|
+
args[objectArg.index] = `{ ${Array.from(properties, ([key, value]) => `${key}: ${value}`).join(", ")} }`;
|
|
64730
|
+
}
|
|
64731
|
+
const argumentsText = Array.from(args, (argument) => argument ?? "...").join(", ");
|
|
64732
|
+
if (descriptor.kind === "newWithOptions") return `new ${descriptor.name}(${argumentsText})`;
|
|
64733
|
+
return `${descriptor.viaCall ? `${descriptor.viaCall.prop}().` : ""}${descriptor.prop}(${argumentsText})`;
|
|
64734
|
+
}
|
|
64735
|
+
//#endregion
|
|
64716
64736
|
//#region src/orchestrator/use-baseline.ts
|
|
64717
64737
|
function buildDelegateContext(ctx, overrides) {
|
|
64718
64738
|
const src = ctx;
|
|
@@ -64732,15 +64752,6 @@ registerSelfRules({
|
|
|
64732
64752
|
"no-math-sum-precise": rule$2,
|
|
64733
64753
|
"no-temporal": rule$1
|
|
64734
64754
|
});
|
|
64735
|
-
function baselineMessage(featureId, baseline) {
|
|
64736
|
-
const rec = getFeatureRecord(featureId);
|
|
64737
|
-
const label = rec?.name || featureId;
|
|
64738
|
-
const idSuffix = rec?.name ? ` (${featureId})` : "";
|
|
64739
|
-
if (baseline === "widely") return `Feature '${label}'${idSuffix} is not a widely available Baseline feature.`;
|
|
64740
|
-
if (baseline === "newly") return `Feature '${label}'${idSuffix} is not a newly available Baseline feature.`;
|
|
64741
|
-
if (rec?.status?.baseline === false) return `Feature '${label}'${idSuffix} has Limited availability and exceeds ${baseline}.`;
|
|
64742
|
-
return `Feature '${label}'${idSuffix} became Baseline in ${baselineYearLabel(rec?.status) ?? "unknown"} and exceeds ${baseline}.`;
|
|
64743
|
-
}
|
|
64744
64755
|
const rule = {
|
|
64745
64756
|
meta: {
|
|
64746
64757
|
type: "problem",
|
|
@@ -64896,14 +64907,16 @@ const rule = {
|
|
|
64896
64907
|
},
|
|
64897
64908
|
options: delegateOptions,
|
|
64898
64909
|
report(arg) {
|
|
64899
|
-
|
|
64900
|
-
|
|
64901
|
-
|
|
64902
|
-
|
|
64903
|
-
|
|
64904
|
-
|
|
64905
|
-
|
|
64906
|
-
|
|
64910
|
+
if ("node" in arg && matchIgnoreNodeType?.(arg.node.type)) return;
|
|
64911
|
+
const subject = arg.data?.name ? delegateSubject(String(arg.data.name)) : void 0;
|
|
64912
|
+
const message = baselineMessage(featureId, baseline, subject);
|
|
64913
|
+
if ("node" in arg) ctx.report({
|
|
64914
|
+
node: arg.node,
|
|
64915
|
+
message
|
|
64916
|
+
});
|
|
64917
|
+
else ctx.report({
|
|
64918
|
+
loc: arg.loc,
|
|
64919
|
+
message
|
|
64907
64920
|
});
|
|
64908
64921
|
}
|
|
64909
64922
|
});
|
|
@@ -64934,35 +64947,17 @@ const rule = {
|
|
|
64934
64947
|
const useTypesJs = resolveUseTypes(includeJsBuiltins);
|
|
64935
64948
|
const typedEnabled = (useTypesWeb === "require" || useTypesJs === "require" || useTypesWeb === "auto" || useTypesJs === "auto") && typedAvailable;
|
|
64936
64949
|
if (!typedEnabled) descriptors = descriptors.filter((d) => d.kind !== "instanceMember" && !d.typedOnly);
|
|
64937
|
-
if (descriptors.length > 0) {
|
|
64938
|
-
|
|
64939
|
-
|
|
64940
|
-
|
|
64941
|
-
|
|
64942
|
-
|
|
64943
|
-
|
|
64944
|
-
|
|
64945
|
-
}
|
|
64946
|
-
|
|
64947
|
-
|
|
64948
|
-
}],
|
|
64949
|
-
report(arg) {
|
|
64950
|
-
const isObj = typeof arg === "object" && arg !== null;
|
|
64951
|
-
const node = isObj && "node" in arg ? arg.node : arg;
|
|
64952
|
-
if (matchIgnoreNodeType) {
|
|
64953
|
-
const t = node?.type;
|
|
64954
|
-
if (t && matchIgnoreNodeType(t)) return;
|
|
64955
|
-
}
|
|
64956
|
-
let msg;
|
|
64957
|
-
if (isObj && typeof arg.message === "string") msg = arg.message;
|
|
64958
|
-
ctx.report({
|
|
64959
|
-
node,
|
|
64960
|
-
message: msg
|
|
64961
|
-
});
|
|
64962
|
-
}
|
|
64963
|
-
});
|
|
64964
|
-
mergeRuleListeners(listeners, rule$6.create(delegateCtx));
|
|
64965
|
-
}
|
|
64950
|
+
if (descriptors.length > 0) mergeRuleListeners(listeners, buildListeners(ctx, {
|
|
64951
|
+
descriptors,
|
|
64952
|
+
typed: typedEnabled,
|
|
64953
|
+
report(node, descriptor) {
|
|
64954
|
+
if (matchIgnoreNodeType?.(node.type)) return;
|
|
64955
|
+
ctx.report({
|
|
64956
|
+
node,
|
|
64957
|
+
message: baselineMessage(descriptor.featureId, baseline, descriptorSubject(descriptor))
|
|
64958
|
+
});
|
|
64959
|
+
}
|
|
64960
|
+
}));
|
|
64966
64961
|
return listeners;
|
|
64967
64962
|
}
|
|
64968
64963
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-baseline-js",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
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",
|