@sarj/eslint-plugin 2.3.0 → 2.3.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/dist/index.cjs +194 -155
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -8
- package/dist/index.d.ts +0 -8
- package/dist/index.js +174 -135
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -72,9 +72,6 @@ declare const rules: {
|
|
|
72
72
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
73
73
|
name: string;
|
|
74
74
|
};
|
|
75
|
-
"no-template-literal-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noTemplateLiteralInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
|
-
name: string;
|
|
77
|
-
};
|
|
78
75
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
79
76
|
name: string;
|
|
80
77
|
};
|
|
@@ -159,9 +156,6 @@ declare const plugin: {
|
|
|
159
156
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
160
157
|
name: string;
|
|
161
158
|
};
|
|
162
|
-
"no-template-literal-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noTemplateLiteralInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
163
|
-
name: string;
|
|
164
|
-
};
|
|
165
159
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
166
160
|
name: string;
|
|
167
161
|
};
|
|
@@ -192,7 +186,6 @@ declare const plugin: {
|
|
|
192
186
|
"@sarj/prefer-semantic-colors": string;
|
|
193
187
|
"@sarj/no-fat-try-blocks": string;
|
|
194
188
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
195
|
-
"@sarj/no-template-literal-in-log": string;
|
|
196
189
|
"@sarj/no-secret-in-log": string;
|
|
197
190
|
"@sarj/single-public-export": string;
|
|
198
191
|
"@sarj/prefer-string-literal-union": string;
|
|
@@ -223,7 +216,6 @@ declare const plugin: {
|
|
|
223
216
|
"@sarj/prefer-semantic-colors": string;
|
|
224
217
|
"@sarj/no-fat-try-blocks": string;
|
|
225
218
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
226
|
-
"@sarj/no-template-literal-in-log": string;
|
|
227
219
|
"@sarj/no-secret-in-log": string;
|
|
228
220
|
"@sarj/single-public-export": string;
|
|
229
221
|
"@sarj/prefer-string-literal-union": string;
|
package/dist/index.d.ts
CHANGED
|
@@ -72,9 +72,6 @@ declare const rules: {
|
|
|
72
72
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
73
73
|
name: string;
|
|
74
74
|
};
|
|
75
|
-
"no-template-literal-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noTemplateLiteralInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
76
|
-
name: string;
|
|
77
|
-
};
|
|
78
75
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
79
76
|
name: string;
|
|
80
77
|
};
|
|
@@ -159,9 +156,6 @@ declare const plugin: {
|
|
|
159
156
|
"no-secret-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noSecretInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
160
157
|
name: string;
|
|
161
158
|
};
|
|
162
|
-
"no-template-literal-in-log": _typescript_eslint_utils_ts_eslint.RuleModule<"noTemplateLiteralInLog", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
163
|
-
name: string;
|
|
164
|
-
};
|
|
165
159
|
"prefer-string-literal-union": _typescript_eslint_utils_ts_eslint.RuleModule<"bareChoiceField" | "comparisonCluster", readonly [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
|
|
166
160
|
name: string;
|
|
167
161
|
};
|
|
@@ -192,7 +186,6 @@ declare const plugin: {
|
|
|
192
186
|
"@sarj/prefer-semantic-colors": string;
|
|
193
187
|
"@sarj/no-fat-try-blocks": string;
|
|
194
188
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
195
|
-
"@sarj/no-template-literal-in-log": string;
|
|
196
189
|
"@sarj/no-secret-in-log": string;
|
|
197
190
|
"@sarj/single-public-export": string;
|
|
198
191
|
"@sarj/prefer-string-literal-union": string;
|
|
@@ -223,7 +216,6 @@ declare const plugin: {
|
|
|
223
216
|
"@sarj/prefer-semantic-colors": string;
|
|
224
217
|
"@sarj/no-fat-try-blocks": string;
|
|
225
218
|
"@sarj/no-cors-wildcard-with-credentials": string;
|
|
226
|
-
"@sarj/no-template-literal-in-log": string;
|
|
227
219
|
"@sarj/no-secret-in-log": string;
|
|
228
220
|
"@sarj/single-public-export": string;
|
|
229
221
|
"@sarj/prefer-string-literal-union": string;
|
package/dist/index.js
CHANGED
|
@@ -2223,7 +2223,15 @@ var PURE_CONSTRUCTORS = /* @__PURE__ */ new Set([
|
|
|
2223
2223
|
"Object",
|
|
2224
2224
|
"Headers",
|
|
2225
2225
|
"URLSearchParams",
|
|
2226
|
-
"FormData"
|
|
2226
|
+
"FormData",
|
|
2227
|
+
"TextEncoder",
|
|
2228
|
+
"TextDecoder",
|
|
2229
|
+
"Blob",
|
|
2230
|
+
"ReadableStream",
|
|
2231
|
+
"WritableStream",
|
|
2232
|
+
"TransformStream",
|
|
2233
|
+
"Response",
|
|
2234
|
+
"AbortController"
|
|
2227
2235
|
]);
|
|
2228
2236
|
function isNode3(value) {
|
|
2229
2237
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
@@ -2413,7 +2421,49 @@ var INNOCUOUS_WORDS = /* @__PURE__ */ new Set([
|
|
|
2413
2421
|
"invalid",
|
|
2414
2422
|
"exists",
|
|
2415
2423
|
"type",
|
|
2416
|
-
"types"
|
|
2424
|
+
"types",
|
|
2425
|
+
"name",
|
|
2426
|
+
"names",
|
|
2427
|
+
"label",
|
|
2428
|
+
"labels",
|
|
2429
|
+
"title",
|
|
2430
|
+
"expiry",
|
|
2431
|
+
"expiration",
|
|
2432
|
+
"expires",
|
|
2433
|
+
"ttl",
|
|
2434
|
+
"version",
|
|
2435
|
+
"versions",
|
|
2436
|
+
"policy",
|
|
2437
|
+
"rotation",
|
|
2438
|
+
"arn",
|
|
2439
|
+
"path",
|
|
2440
|
+
"paths",
|
|
2441
|
+
"issuer",
|
|
2442
|
+
"audience",
|
|
2443
|
+
"strength",
|
|
2444
|
+
"manager",
|
|
2445
|
+
"service",
|
|
2446
|
+
"services",
|
|
2447
|
+
"repository",
|
|
2448
|
+
"provider",
|
|
2449
|
+
"providers",
|
|
2450
|
+
"store",
|
|
2451
|
+
"factory",
|
|
2452
|
+
"handler",
|
|
2453
|
+
"controller",
|
|
2454
|
+
"bucket",
|
|
2455
|
+
"url",
|
|
2456
|
+
"uri",
|
|
2457
|
+
"endpoint",
|
|
2458
|
+
"endpoints",
|
|
2459
|
+
"scope",
|
|
2460
|
+
"scopes",
|
|
2461
|
+
"event",
|
|
2462
|
+
"events",
|
|
2463
|
+
"format",
|
|
2464
|
+
"at",
|
|
2465
|
+
"len",
|
|
2466
|
+
"length"
|
|
2417
2467
|
]);
|
|
2418
2468
|
var REDACTION_RE = /prefix|suffix|redact|mask|hash|hint|_len|length/i;
|
|
2419
2469
|
var WHOLE_TOKEN_REDACTION_MARKERS = /* @__PURE__ */ new Set(["tag"]);
|
|
@@ -2488,6 +2538,12 @@ function isLoggerExpr(expr) {
|
|
|
2488
2538
|
return false;
|
|
2489
2539
|
}
|
|
2490
2540
|
}
|
|
2541
|
+
function isRawSecretValue(prop) {
|
|
2542
|
+
if (prop.shorthand) {
|
|
2543
|
+
return true;
|
|
2544
|
+
}
|
|
2545
|
+
return prop.value.type === "Identifier" || prop.value.type === "MemberExpression";
|
|
2546
|
+
}
|
|
2491
2547
|
function propertyKeyName2(prop) {
|
|
2492
2548
|
if (prop.computed) {
|
|
2493
2549
|
return null;
|
|
@@ -2542,7 +2598,7 @@ var no_secret_in_log_default = ESLintUtils23.RuleCreator(
|
|
|
2542
2598
|
continue;
|
|
2543
2599
|
}
|
|
2544
2600
|
const keyName2 = propertyKeyName2(prop);
|
|
2545
|
-
if (keyName2 !== null && isSecretKeyword(keyName2)) {
|
|
2601
|
+
if (keyName2 !== null && isSecretKeyword(keyName2) && isRawSecretValue(prop)) {
|
|
2546
2602
|
context.report({
|
|
2547
2603
|
node: prop,
|
|
2548
2604
|
messageId: "noSecretInLog",
|
|
@@ -2557,120 +2613,9 @@ var no_secret_in_log_default = ESLintUtils23.RuleCreator(
|
|
|
2557
2613
|
}
|
|
2558
2614
|
});
|
|
2559
2615
|
|
|
2560
|
-
// src/rules/no-template-literal-in-log.ts
|
|
2561
|
-
import { ESLintUtils as ESLintUtils24 } from "@typescript-eslint/utils";
|
|
2562
|
-
var LOG_METHODS2 = /* @__PURE__ */ new Set([
|
|
2563
|
-
"debug",
|
|
2564
|
-
"info",
|
|
2565
|
-
"warn",
|
|
2566
|
-
"warning",
|
|
2567
|
-
"error",
|
|
2568
|
-
"exception",
|
|
2569
|
-
"critical",
|
|
2570
|
-
"trace",
|
|
2571
|
-
"log",
|
|
2572
|
-
"fatal",
|
|
2573
|
-
"success"
|
|
2574
|
-
]);
|
|
2575
|
-
var LOGGER_NAMES2 = /* @__PURE__ */ new Set([
|
|
2576
|
-
"console",
|
|
2577
|
-
"logger",
|
|
2578
|
-
"log",
|
|
2579
|
-
"_log",
|
|
2580
|
-
"_logger"
|
|
2581
|
-
]);
|
|
2582
|
-
var LOGGER_FACTORIES2 = /* @__PURE__ */ new Set([
|
|
2583
|
-
"getlogger",
|
|
2584
|
-
"createlogger"
|
|
2585
|
-
]);
|
|
2586
|
-
function looksLikeLogger(node) {
|
|
2587
|
-
switch (node.type) {
|
|
2588
|
-
case "Identifier": {
|
|
2589
|
-
const name = node.name.toLowerCase();
|
|
2590
|
-
return LOGGER_NAMES2.has(name) || LOGGER_FACTORIES2.has(name);
|
|
2591
|
-
}
|
|
2592
|
-
case "MemberExpression": {
|
|
2593
|
-
if (!node.computed && node.property.type === "Identifier") {
|
|
2594
|
-
const prop = node.property.name.toLowerCase();
|
|
2595
|
-
if (LOGGER_NAMES2.has(prop) || LOGGER_FACTORIES2.has(prop)) {
|
|
2596
|
-
return true;
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
return looksLikeLogger(node.object);
|
|
2600
|
-
}
|
|
2601
|
-
case "CallExpression":
|
|
2602
|
-
return looksLikeLogger(node.callee);
|
|
2603
|
-
default:
|
|
2604
|
-
return false;
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2607
|
-
function findInterpolatingTemplate(node) {
|
|
2608
|
-
if (node.type === "TemplateLiteral") {
|
|
2609
|
-
return node.expressions.length > 0 ? node : null;
|
|
2610
|
-
}
|
|
2611
|
-
if (node.type === "BinaryExpression" && node.operator === "+") {
|
|
2612
|
-
return findInterpolatingTemplate(node.left) ?? findInterpolatingTemplate(node.right);
|
|
2613
|
-
}
|
|
2614
|
-
return null;
|
|
2615
|
-
}
|
|
2616
|
-
function messageArg(node, method, receiver) {
|
|
2617
|
-
const levelFirst = method === "log" && !isConsoleReceiver(receiver);
|
|
2618
|
-
const arg = node.arguments[levelFirst ? 1 : 0];
|
|
2619
|
-
if (arg === void 0 || arg.type === "SpreadElement") {
|
|
2620
|
-
return null;
|
|
2621
|
-
}
|
|
2622
|
-
return arg;
|
|
2623
|
-
}
|
|
2624
|
-
function isConsoleReceiver(node) {
|
|
2625
|
-
return node.type === "Identifier" && node.name === "console";
|
|
2626
|
-
}
|
|
2627
|
-
var no_template_literal_in_log_default = ESLintUtils24.RuleCreator(
|
|
2628
|
-
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2629
|
-
)({
|
|
2630
|
-
name: "no-template-literal-in-log",
|
|
2631
|
-
meta: {
|
|
2632
|
-
type: "problem",
|
|
2633
|
-
docs: {
|
|
2634
|
-
description: "Disallow an interpolating template literal as a logging message \u2014 pass variables as structured fields so logs stay filterable and templates stay constant."
|
|
2635
|
-
},
|
|
2636
|
-
schema: [],
|
|
2637
|
-
messages: {
|
|
2638
|
-
noTemplateLiteralInLog: "Interpolating template literal as a logging message \u2014 pass variables as structured fields (logger.info('msg', { key })) instead."
|
|
2639
|
-
}
|
|
2640
|
-
},
|
|
2641
|
-
defaultOptions: [],
|
|
2642
|
-
create(context) {
|
|
2643
|
-
return {
|
|
2644
|
-
CallExpression(node) {
|
|
2645
|
-
const callee = node.callee;
|
|
2646
|
-
if (callee.type !== "MemberExpression" || callee.computed) {
|
|
2647
|
-
return;
|
|
2648
|
-
}
|
|
2649
|
-
if (callee.property.type !== "Identifier") {
|
|
2650
|
-
return;
|
|
2651
|
-
}
|
|
2652
|
-
const method = callee.property.name;
|
|
2653
|
-
if (!LOG_METHODS2.has(method)) {
|
|
2654
|
-
return;
|
|
2655
|
-
}
|
|
2656
|
-
if (!looksLikeLogger(callee.object)) {
|
|
2657
|
-
return;
|
|
2658
|
-
}
|
|
2659
|
-
const arg = messageArg(node, method, callee.object);
|
|
2660
|
-
if (arg === null) {
|
|
2661
|
-
return;
|
|
2662
|
-
}
|
|
2663
|
-
if (findInterpolatingTemplate(arg) !== null) {
|
|
2664
|
-
context.report({ node, messageId: "noTemplateLiteralInLog" });
|
|
2665
|
-
}
|
|
2666
|
-
}
|
|
2667
|
-
};
|
|
2668
|
-
}
|
|
2669
|
-
});
|
|
2670
|
-
|
|
2671
2616
|
// src/rules/prefer-string-literal-union.ts
|
|
2672
2617
|
import {
|
|
2673
|
-
ESLintUtils as
|
|
2618
|
+
ESLintUtils as ESLintUtils24,
|
|
2674
2619
|
AST_NODE_TYPES as AST_NODE_TYPES12
|
|
2675
2620
|
} from "@typescript-eslint/utils";
|
|
2676
2621
|
var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
@@ -2689,6 +2634,10 @@ var CHOICE_TOKENS = /* @__PURE__ */ new Set([
|
|
|
2689
2634
|
]);
|
|
2690
2635
|
var LOWER_TOKEN_RE = /^[a-z][a-z0-9_-]{0,30}$/;
|
|
2691
2636
|
var MIN_CLUSTER_SIZE = 2;
|
|
2637
|
+
var BOOLEANISH = /* @__PURE__ */ new Set(["true", "false"]);
|
|
2638
|
+
function isEnumToken(lit) {
|
|
2639
|
+
return LOWER_TOKEN_RE.test(lit) && lit.length >= 2 && !BOOLEANISH.has(lit);
|
|
2640
|
+
}
|
|
2692
2641
|
var IGNORE_PATTERNS = [
|
|
2693
2642
|
/[\\/]generated[\\/]/,
|
|
2694
2643
|
/\.gen\.tsx?$/,
|
|
@@ -2718,14 +2667,89 @@ function keyName(key) {
|
|
|
2718
2667
|
}
|
|
2719
2668
|
return null;
|
|
2720
2669
|
}
|
|
2670
|
+
function isStringLiteralMember(t) {
|
|
2671
|
+
return t.type === AST_NODE_TYPES12.TSLiteralType && t.literal.type === AST_NODE_TYPES12.Literal && typeof t.literal.value === "string";
|
|
2672
|
+
}
|
|
2721
2673
|
function isStringLiteralUnion(node) {
|
|
2722
2674
|
if (node?.type !== AST_NODE_TYPES12.TSUnionType) {
|
|
2723
2675
|
return false;
|
|
2724
2676
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
return
|
|
2677
|
+
return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
|
|
2678
|
+
}
|
|
2679
|
+
function isLikelyClosedUnion(node) {
|
|
2680
|
+
return node?.type === AST_NODE_TYPES12.TSUnionType && node.types.some(isStringLiteralMember);
|
|
2681
|
+
}
|
|
2682
|
+
function unionMemberNames(typeNode, out) {
|
|
2683
|
+
if (typeNode === void 0) {
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
if (typeNode.type === AST_NODE_TYPES12.TSIntersectionType || typeNode.type === AST_NODE_TYPES12.TSUnionType) {
|
|
2687
|
+
for (const t of typeNode.types) {
|
|
2688
|
+
unionMemberNames(t, out);
|
|
2689
|
+
}
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
if (typeNode.type !== AST_NODE_TYPES12.TSTypeLiteral) {
|
|
2693
|
+
return;
|
|
2694
|
+
}
|
|
2695
|
+
for (const member of typeNode.members) {
|
|
2696
|
+
if (member.type === AST_NODE_TYPES12.TSPropertySignature && isLikelyClosedUnion(member.typeAnnotation?.typeAnnotation)) {
|
|
2697
|
+
const propName2 = keyName(member.key);
|
|
2698
|
+
if (propName2 !== null) {
|
|
2699
|
+
out.add(propName2);
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
function bindingName(node) {
|
|
2705
|
+
const id = node.type === AST_NODE_TYPES12.AssignmentPattern ? node.left : node;
|
|
2706
|
+
return id.type === AST_NODE_TYPES12.Identifier ? id.name : null;
|
|
2707
|
+
}
|
|
2708
|
+
function addUnionRefsFromBinding(param, out) {
|
|
2709
|
+
const binding = param.type === AST_NODE_TYPES12.AssignmentPattern ? param.left : param;
|
|
2710
|
+
if (binding.type === AST_NODE_TYPES12.ObjectPattern) {
|
|
2711
|
+
const members = /* @__PURE__ */ new Set();
|
|
2712
|
+
unionMemberNames(binding.typeAnnotation?.typeAnnotation, members);
|
|
2713
|
+
if (members.size === 0) {
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
for (const prop of binding.properties) {
|
|
2717
|
+
if (prop.type !== AST_NODE_TYPES12.Property) {
|
|
2718
|
+
continue;
|
|
2719
|
+
}
|
|
2720
|
+
const propKey = keyName(prop.key);
|
|
2721
|
+
const local = bindingName(prop.value);
|
|
2722
|
+
if (propKey !== null && local !== null && members.has(propKey)) {
|
|
2723
|
+
out.add(local);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
return;
|
|
2727
|
+
}
|
|
2728
|
+
if (binding.type !== AST_NODE_TYPES12.Identifier) {
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
const typeNode = binding.typeAnnotation?.typeAnnotation;
|
|
2732
|
+
if (isLikelyClosedUnion(typeNode)) {
|
|
2733
|
+
out.add(binding.name);
|
|
2734
|
+
return;
|
|
2735
|
+
}
|
|
2736
|
+
if (typeNode?.type === AST_NODE_TYPES12.TSTypeLiteral) {
|
|
2737
|
+
for (const member of typeNode.members) {
|
|
2738
|
+
if (member.type === AST_NODE_TYPES12.TSPropertySignature && isLikelyClosedUnion(member.typeAnnotation?.typeAnnotation)) {
|
|
2739
|
+
const propName2 = keyName(member.key);
|
|
2740
|
+
if (propName2 !== null) {
|
|
2741
|
+
out.add(`${binding.name}.${propName2}`);
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
function unionRefsFromParams(fn) {
|
|
2748
|
+
const out = /* @__PURE__ */ new Set();
|
|
2749
|
+
for (const param of fn.params) {
|
|
2750
|
+
addUnionRefsFromBinding(param, out);
|
|
2751
|
+
}
|
|
2752
|
+
return out;
|
|
2729
2753
|
}
|
|
2730
2754
|
function refKey(node) {
|
|
2731
2755
|
if (node.type === AST_NODE_TYPES12.Identifier) {
|
|
@@ -2746,7 +2770,7 @@ function strLiteral(node) {
|
|
|
2746
2770
|
}
|
|
2747
2771
|
return null;
|
|
2748
2772
|
}
|
|
2749
|
-
var prefer_string_literal_union_default =
|
|
2773
|
+
var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
|
|
2750
2774
|
(name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
2751
2775
|
)({
|
|
2752
2776
|
name: "prefer-string-literal-union",
|
|
@@ -2772,16 +2796,25 @@ var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
|
2772
2796
|
const validClusters = [];
|
|
2773
2797
|
const bareChoiceProps = [];
|
|
2774
2798
|
const containersWithUnion = /* @__PURE__ */ new Set();
|
|
2775
|
-
function pushScope() {
|
|
2776
|
-
scopeStack.push(
|
|
2799
|
+
function pushScope(fn) {
|
|
2800
|
+
scopeStack.push({
|
|
2801
|
+
clusters: /* @__PURE__ */ new Map(),
|
|
2802
|
+
unionRefs: unionRefsFromParams(fn)
|
|
2803
|
+
});
|
|
2804
|
+
}
|
|
2805
|
+
function isUnionTypedRef(key, current) {
|
|
2806
|
+
if (current.has(key)) {
|
|
2807
|
+
return true;
|
|
2808
|
+
}
|
|
2809
|
+
return scopeStack.some((s) => s.unionRefs.has(key));
|
|
2777
2810
|
}
|
|
2778
2811
|
function popScope() {
|
|
2779
|
-
const
|
|
2780
|
-
if (
|
|
2812
|
+
const scope = scopeStack.pop();
|
|
2813
|
+
if (scope === void 0) {
|
|
2781
2814
|
return;
|
|
2782
2815
|
}
|
|
2783
|
-
for (const entry of clusters
|
|
2784
|
-
if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE) {
|
|
2816
|
+
for (const [key, entry] of scope.clusters) {
|
|
2817
|
+
if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE && !isUnionTypedRef(key, scope.unionRefs)) {
|
|
2785
2818
|
validClusters.push(entry.node);
|
|
2786
2819
|
}
|
|
2787
2820
|
}
|
|
@@ -2791,10 +2824,10 @@ var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
|
2791
2824
|
if (scope === void 0) {
|
|
2792
2825
|
return;
|
|
2793
2826
|
}
|
|
2794
|
-
const allTokens = literals.every((lit) =>
|
|
2795
|
-
const existing = scope.get(key);
|
|
2827
|
+
const allTokens = literals.every((lit) => isEnumToken(lit));
|
|
2828
|
+
const existing = scope.clusters.get(key);
|
|
2796
2829
|
if (existing === void 0) {
|
|
2797
|
-
scope.set(key, {
|
|
2830
|
+
scope.clusters.set(key, {
|
|
2798
2831
|
node,
|
|
2799
2832
|
literals: new Set(literals),
|
|
2800
2833
|
allTokens
|
|
@@ -2827,6 +2860,15 @@ var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
|
2827
2860
|
"FunctionExpression:exit": popScope,
|
|
2828
2861
|
ArrowFunctionExpression: pushScope,
|
|
2829
2862
|
"ArrowFunctionExpression:exit": popScope,
|
|
2863
|
+
VariableDeclarator(node) {
|
|
2864
|
+
const scope = scopeStack[scopeStack.length - 1];
|
|
2865
|
+
if (scope === void 0 || node.id.type !== AST_NODE_TYPES12.Identifier) {
|
|
2866
|
+
return;
|
|
2867
|
+
}
|
|
2868
|
+
if (isLikelyClosedUnion(node.id.typeAnnotation?.typeAnnotation)) {
|
|
2869
|
+
scope.unionRefs.add(node.id.name);
|
|
2870
|
+
}
|
|
2871
|
+
},
|
|
2830
2872
|
BinaryExpression(node) {
|
|
2831
2873
|
if (node.operator !== "===" && node.operator !== "!==" && node.operator !== "==" && node.operator !== "!=") {
|
|
2832
2874
|
return;
|
|
@@ -2907,7 +2949,7 @@ var prefer_string_literal_union_default = ESLintUtils25.RuleCreator(
|
|
|
2907
2949
|
});
|
|
2908
2950
|
|
|
2909
2951
|
// src/rules/single-public-export.ts
|
|
2910
|
-
import { ESLintUtils as
|
|
2952
|
+
import { ESLintUtils as ESLintUtils25, AST_NODE_TYPES as AST_NODE_TYPES13 } from "@typescript-eslint/utils";
|
|
2911
2953
|
var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
|
|
2912
2954
|
"util",
|
|
2913
2955
|
"utils",
|
|
@@ -3012,7 +3054,7 @@ var summarizeExports = (body) => {
|
|
|
3012
3054
|
}
|
|
3013
3055
|
return { names, hasReExport, candidate };
|
|
3014
3056
|
};
|
|
3015
|
-
var single_public_export_default =
|
|
3057
|
+
var single_public_export_default = ESLintUtils25.RuleCreator(
|
|
3016
3058
|
(name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
|
|
3017
3059
|
)({
|
|
3018
3060
|
name: "single-public-export",
|
|
@@ -3076,14 +3118,13 @@ var rules = {
|
|
|
3076
3118
|
"no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
|
|
3077
3119
|
"no-fat-try-blocks": no_fat_try_blocks_default,
|
|
3078
3120
|
"no-secret-in-log": no_secret_in_log_default,
|
|
3079
|
-
"no-template-literal-in-log": no_template_literal_in_log_default,
|
|
3080
3121
|
"prefer-string-literal-union": prefer_string_literal_union_default,
|
|
3081
3122
|
"single-public-export": single_public_export_default
|
|
3082
3123
|
};
|
|
3083
3124
|
var plugin = {
|
|
3084
3125
|
meta: {
|
|
3085
3126
|
name: "@sarj/eslint-plugin",
|
|
3086
|
-
version: "2.3.
|
|
3127
|
+
version: "2.3.2"
|
|
3087
3128
|
},
|
|
3088
3129
|
rules,
|
|
3089
3130
|
configs: {
|
|
@@ -3112,7 +3153,6 @@ var plugin = {
|
|
|
3112
3153
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
3113
3154
|
"@sarj/no-fat-try-blocks": "warn",
|
|
3114
3155
|
"@sarj/no-cors-wildcard-with-credentials": "warn",
|
|
3115
|
-
"@sarj/no-template-literal-in-log": "warn",
|
|
3116
3156
|
"@sarj/no-secret-in-log": "warn",
|
|
3117
3157
|
"@sarj/single-public-export": "warn",
|
|
3118
3158
|
"@sarj/prefer-string-literal-union": "warn"
|
|
@@ -3147,7 +3187,6 @@ var plugin = {
|
|
|
3147
3187
|
// Ported from sarj-python-lint (SARJ), corpus-validated FP~0.
|
|
3148
3188
|
"@sarj/no-fat-try-blocks": "error",
|
|
3149
3189
|
"@sarj/no-cors-wildcard-with-credentials": "error",
|
|
3150
|
-
"@sarj/no-template-literal-in-log": "error",
|
|
3151
3190
|
"@sarj/no-secret-in-log": "error",
|
|
3152
3191
|
"@sarj/single-public-export": "error",
|
|
3153
3192
|
// High-volume/stylistic — warn until rollout proves FP rate.
|