Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/loud-mammals-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'eslint-plugin-qwik': patch
---

FIX: cover more qwik eslint's edge case
12 changes: 10 additions & 2 deletions packages/eslint-plugin-qwik/src/scope-use-task.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Rule } from 'eslint';
import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils';
import * as eslint from 'eslint'; // For Scope types
import type { Identifier } from 'estree';
const ISSERVER = 'isServer';
// Helper function: checks if a node is a descendant of another node
function isNodeDescendantOf(descendantNode, ancestorNode): boolean {
Expand Down Expand Up @@ -93,7 +94,6 @@ export const scopeUseTask: Rule.RuleModule = {
*/
function isApiUsageGuarded(apiOrCallNode, functionContextNode): boolean {
let currentParentNode: TSESTree.Node | undefined = apiOrCallNode.parent;

while (
currentParentNode &&
currentParentNode !== functionContextNode.body &&
Expand Down Expand Up @@ -322,7 +322,15 @@ export const scopeUseTask: Rule.RuleModule = {
}

if (forbiddenApis.has(node.name)) {
if (isIdentifierShadowedByDeclaration(node)) {
const isDirectIdentifier =
node.parent.type === 'VariableDeclarator' &&
(node?.parent?.init as Identifier)?.name === node.name;
// node'api usually be invoked as a member expression (e.g., process.env)
// or as a direct identifier (e.g., process).
if (
isIdentifierShadowedByDeclaration(node) ||
(node.parent.type !== 'MemberExpression' && node.parent.type !== 'VariableDeclarator')
) {
return;
}
if (!isApiUsageGuarded(node, currentUseTaskFunction)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Expect error: { "messageId": "unsafeApiUsage" }

// Expect error: { "messageId": "unsafeApiUsage" }
import { component$, useSignal, useTask$ } from '@qwik.dev/core';

export default component$(() => {
const s = useSignal(0);
useTask$(({ track }) => {
track(() => {
process.env;
const m = process;
return s.value;
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export default component$(() => {
function foo() {
if (isServer) {
process.env;
const m = process;
}
}
foo();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { component$, useTask$, isBrowser, useSignal } from '@qwik.dev/core';

export default component$(() => {
const state = useSignal(true);
useTask$(({ track }) => {
if (isBrowser) {
track(() => {
if (state.value) {
const values = [
{
relativePath: '',
name: 'index',
type: '',
path: '',
isSymbolicLink: false,
children: undefined,
},
];
}
});
}
});
return <></>;
});