oxlint-plugin-effect 0.5.0 → 0.5.1
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/rules/no-globals.js +14 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ If the project uses JSON configuration, copy the exported rule map into `rules`;
|
|
|
37
37
|
| `effect/noDynamicImports` | Allows import() only behind a named lazy-loading boundary; bans require() |
|
|
38
38
|
| `effect/noEffectDo` | Bans Effect.Do |
|
|
39
39
|
| `effect/noEffectBind` | Bans Effect.bind |
|
|
40
|
-
| `effect/noGlobals` | Bans ambient capabilities with direct Effect replacements
|
|
40
|
+
| `effect/noGlobals` | Bans ambient capabilities with direct Effect replacements; allows `process.std*.isTTY` |
|
|
41
41
|
| `effect/noNodeBuiltinImport` | Bans fully replaced Node modules and replaced operations from partial modules |
|
|
42
42
|
|
|
43
43
|
The preset intentionally allows `Effect.as`, `Option.as`, `Effect.never`, `Effect.async`, ordinary `if` and `switch` statements, and runtime runners at explicit application boundaries.
|
package/dist/rules/no-globals.js
CHANGED
|
@@ -148,6 +148,16 @@ const isUnshadowedGlobal = (ctx, node, name) => Option.match(findVariableUp(ctx.
|
|
|
148
148
|
onSome: (variable) => variable.defs.length === 0
|
|
149
149
|
});
|
|
150
150
|
const staticMember = (node) => Option.getOrUndefined(memberNames(node));
|
|
151
|
+
const processStreams = new Set([
|
|
152
|
+
"stderr",
|
|
153
|
+
"stdin",
|
|
154
|
+
"stdout"
|
|
155
|
+
]);
|
|
156
|
+
const isTtyRead = (node) => {
|
|
157
|
+
const parent = node.parent;
|
|
158
|
+
if (parent?.type !== "MemberExpression" || parent.computed) return false;
|
|
159
|
+
return parent.object === node && parent.property.type === "Identifier" && parent.property.name === "isTTY";
|
|
160
|
+
};
|
|
151
161
|
const isCryptoDigest = (node) => {
|
|
152
162
|
if (node.computed || node.property.type !== "Identifier" || node.property.name !== "digest") return false;
|
|
153
163
|
const object = node.object;
|
|
@@ -175,7 +185,10 @@ const noGlobals = define({
|
|
|
175
185
|
if (names === void 0) return Effect.void;
|
|
176
186
|
const [object, property] = names;
|
|
177
187
|
if (!isUnshadowedGlobal(ctx, memberExpression, object)) return Effect.void;
|
|
178
|
-
for (const [bannedObject, properties, alternative] of memberBans) if (object === bannedObject && properties.has(property))
|
|
188
|
+
for (const [bannedObject, properties, alternative] of memberBans) if (object === bannedObject && properties.has(property)) {
|
|
189
|
+
if (object === "process" && processStreams.has(property) && isTtyRead(memberExpression)) return Effect.void;
|
|
190
|
+
return report(memberExpression, `${object}.${property}`, alternative);
|
|
191
|
+
}
|
|
179
192
|
return Effect.void;
|
|
180
193
|
},
|
|
181
194
|
CallExpression: (node) => {
|