@timmo001/oxlint-rules 0.6.0 → 0.6.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/README.md +3 -2
- package/dist/cli.js +14 -7
- package/dist/configs/recommended-effect.js +14 -7
- package/dist/effect/index.js +14 -7
- package/package.json +1 -1
- package/src/effect/rules/no-raw-gh.ts +28 -7
package/README.md
CHANGED
|
@@ -137,8 +137,9 @@ they only run when the consumer enables `typeAware`.
|
|
|
137
137
|
|
|
138
138
|
- `no-raw-gh`: reports the raw `execute`, `json` and `stream` methods called on
|
|
139
139
|
a `yield* Gh` binding from `@timmo001/effect-gh`, `Api.raw` from that package,
|
|
140
|
-
and
|
|
141
|
-
|
|
140
|
+
and calls that launch gh: `"gh"` followed by its arguments, such as
|
|
141
|
+
`executor.run("gh", ...)`, or an argument array starting with `"gh"` passed
|
|
142
|
+
to a spawn, exec, run or command function, such as `Bun.spawn(["gh", ...])`. Use the
|
|
142
143
|
package's typed operations, and add one to effect-gh when a command has none.
|
|
143
144
|
effect-gh's own relative imports are not reported.
|
|
144
145
|
- `no-try-catch-in-effect-generators`: diagnoses synchronous `try/catch` owned
|
package/dist/cli.js
CHANGED
|
@@ -3004,13 +3004,20 @@ function isYieldGh(sourceCode, node) {
|
|
|
3004
3004
|
function isGhBinding(sourceCode, identifier) {
|
|
3005
3005
|
return resolveVariable(sourceCode, identifier)?.defs.some((definition) => definition.type === "Variable" && definition.node.type === "VariableDeclarator" && isYieldGh(sourceCode, definition.node.init)) ?? false;
|
|
3006
3006
|
}
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3007
|
+
var launcherName = /spawn|exec|run|command/i;
|
|
3008
|
+
function calleeName(callee) {
|
|
3009
|
+
if (callee.type === "Identifier")
|
|
3010
|
+
return callee.name;
|
|
3011
|
+
return staticMemberName(callee);
|
|
3012
|
+
}
|
|
3013
|
+
function launchesGh(node) {
|
|
3014
|
+
const [command, argv] = node.arguments;
|
|
3015
|
+
if (command?.type === "Literal")
|
|
3016
|
+
return command.value === "gh" && argv !== undefined;
|
|
3017
|
+
if (command?.type !== "ArrayExpression")
|
|
3011
3018
|
return false;
|
|
3012
|
-
const first =
|
|
3013
|
-
return first?.type === "Literal" && first.value === "gh";
|
|
3019
|
+
const first = command.elements[0];
|
|
3020
|
+
return first?.type === "Literal" && first.value === "gh" && launcherName.test(calleeName(node.callee) ?? "");
|
|
3014
3021
|
}
|
|
3015
3022
|
var noRawGhRule = defineRule24({
|
|
3016
3023
|
meta: {
|
|
@@ -3040,7 +3047,7 @@ var noRawGhRule = defineRule24({
|
|
|
3040
3047
|
return;
|
|
3041
3048
|
}
|
|
3042
3049
|
}
|
|
3043
|
-
if (
|
|
3050
|
+
if (launchesGh(node))
|
|
3044
3051
|
context.report({ node, messageId: "spawnGh" });
|
|
3045
3052
|
}
|
|
3046
3053
|
};
|
|
@@ -55,13 +55,20 @@ function isYieldGh(sourceCode, node) {
|
|
|
55
55
|
function isGhBinding(sourceCode, identifier) {
|
|
56
56
|
return resolveVariable(sourceCode, identifier)?.defs.some((definition) => definition.type === "Variable" && definition.node.type === "VariableDeclarator" && isYieldGh(sourceCode, definition.node.init)) ?? false;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
var launcherName = /spawn|exec|run|command/i;
|
|
59
|
+
function calleeName(callee) {
|
|
60
|
+
if (callee.type === "Identifier")
|
|
61
|
+
return callee.name;
|
|
62
|
+
return staticMemberName(callee);
|
|
63
|
+
}
|
|
64
|
+
function launchesGh(node) {
|
|
65
|
+
const [command, argv] = node.arguments;
|
|
66
|
+
if (command?.type === "Literal")
|
|
67
|
+
return command.value === "gh" && argv !== undefined;
|
|
68
|
+
if (command?.type !== "ArrayExpression")
|
|
62
69
|
return false;
|
|
63
|
-
const first =
|
|
64
|
-
return first?.type === "Literal" && first.value === "gh";
|
|
70
|
+
const first = command.elements[0];
|
|
71
|
+
return first?.type === "Literal" && first.value === "gh" && launcherName.test(calleeName(node.callee) ?? "");
|
|
65
72
|
}
|
|
66
73
|
var noRawGhRule = defineRule({
|
|
67
74
|
meta: {
|
|
@@ -91,7 +98,7 @@ var noRawGhRule = defineRule({
|
|
|
91
98
|
return;
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
|
-
if (
|
|
101
|
+
if (launchesGh(node))
|
|
95
102
|
context.report({ node, messageId: "spawnGh" });
|
|
96
103
|
}
|
|
97
104
|
};
|
package/dist/effect/index.js
CHANGED
|
@@ -50,13 +50,20 @@ function isYieldGh(sourceCode, node) {
|
|
|
50
50
|
function isGhBinding(sourceCode, identifier) {
|
|
51
51
|
return resolveVariable(sourceCode, identifier)?.defs.some((definition) => definition.type === "Variable" && definition.node.type === "VariableDeclarator" && isYieldGh(sourceCode, definition.node.init)) ?? false;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
var launcherName = /spawn|exec|run|command/i;
|
|
54
|
+
function calleeName(callee) {
|
|
55
|
+
if (callee.type === "Identifier")
|
|
56
|
+
return callee.name;
|
|
57
|
+
return staticMemberName(callee);
|
|
58
|
+
}
|
|
59
|
+
function launchesGh(node) {
|
|
60
|
+
const [command, argv] = node.arguments;
|
|
61
|
+
if (command?.type === "Literal")
|
|
62
|
+
return command.value === "gh" && argv !== undefined;
|
|
63
|
+
if (command?.type !== "ArrayExpression")
|
|
57
64
|
return false;
|
|
58
|
-
const first =
|
|
59
|
-
return first?.type === "Literal" && first.value === "gh";
|
|
65
|
+
const first = command.elements[0];
|
|
66
|
+
return first?.type === "Literal" && first.value === "gh" && launcherName.test(calleeName(node.callee) ?? "");
|
|
60
67
|
}
|
|
61
68
|
var noRawGhRule = defineRule({
|
|
62
69
|
meta: {
|
|
@@ -86,7 +93,7 @@ var noRawGhRule = defineRule({
|
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
|
-
if (
|
|
96
|
+
if (launchesGh(node))
|
|
90
97
|
context.report({ node, messageId: "spawnGh" });
|
|
91
98
|
}
|
|
92
99
|
};
|
package/package.json
CHANGED
|
@@ -61,13 +61,35 @@ function isGhBinding(
|
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
/** Callee names that take an argv array to launch, such as `Bun.spawn` or `execFileSync`. */
|
|
65
|
+
const launcherName = /spawn|exec|run|command/i;
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
function calleeName(callee: ESTree.Expression): string | null {
|
|
68
|
+
if (callee.type === "Identifier") return callee.name;
|
|
69
69
|
|
|
70
|
-
return
|
|
70
|
+
return staticMemberName(callee);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whether a call launches gh: `"gh"` followed by its argv, as in
|
|
75
|
+
* `run("gh", args)`, or an argv array starting with `"gh"` passed to a
|
|
76
|
+
* spawn, exec, run or command function. Recording argv, as in
|
|
77
|
+
* `calls.push(["gh", ...args])`, is not launching it.
|
|
78
|
+
*/
|
|
79
|
+
function launchesGh(node: ESTree.CallExpression): boolean {
|
|
80
|
+
const [command, argv] = node.arguments;
|
|
81
|
+
|
|
82
|
+
if (command?.type === "Literal")
|
|
83
|
+
return command.value === "gh" && argv !== undefined;
|
|
84
|
+
|
|
85
|
+
if (command?.type !== "ArrayExpression") return false;
|
|
86
|
+
const first = command.elements[0];
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
first?.type === "Literal" &&
|
|
90
|
+
first.value === "gh" &&
|
|
91
|
+
launcherName.test(calleeName(node.callee) ?? "")
|
|
92
|
+
);
|
|
71
93
|
}
|
|
72
94
|
|
|
73
95
|
/** Route gh through effect-gh's typed operations instead of raw argv or direct spawns. */
|
|
@@ -118,8 +140,7 @@ export const noRawGhRule = defineRule({
|
|
|
118
140
|
}
|
|
119
141
|
}
|
|
120
142
|
|
|
121
|
-
if (
|
|
122
|
-
context.report({ node, messageId: "spawnGh" });
|
|
143
|
+
if (launchesGh(node)) context.report({ node, messageId: "spawnGh" });
|
|
123
144
|
},
|
|
124
145
|
};
|
|
125
146
|
},
|