@grafana/react-detect 0.6.1 → 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/CHANGELOG.md +12 -0
- package/dist/patterns/matcher.js +6 -1
- package/package.json +2 -2
- package/src/patterns/matcher.test.ts +31 -0
- package/src/patterns/matcher.ts +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# v0.6.2 (Wed Apr 01 2026)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- fix: reduce false positives in findStringRefs [#2551](https://github.com/grafana/plugin-tools/pull/2551) ([@jackw](https://github.com/jackw))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Jack Westbrook ([@jackw](https://github.com/jackw))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
1
13
|
# v0.6.1 (Tue Feb 17 2026)
|
|
2
14
|
|
|
3
15
|
#### 🐛 Bug Fix
|
package/dist/patterns/matcher.js
CHANGED
|
@@ -74,8 +74,13 @@ function findJsxRuntimeImports(ast, code) {
|
|
|
74
74
|
}
|
|
75
75
|
function findStringRefs(ast, code) {
|
|
76
76
|
const matches = [];
|
|
77
|
+
const imports = trackImportsFromPackage(ast, "react");
|
|
78
|
+
const hasReactImport = imports.defaultImports.size > 0 || imports.namedImports.size > 0;
|
|
79
|
+
if (!hasReactImport) {
|
|
80
|
+
return matches;
|
|
81
|
+
}
|
|
77
82
|
walk(ast, (node) => {
|
|
78
|
-
if (node && node.type === "MemberExpression" && node.object.type === "ThisExpression" && node.property
|
|
83
|
+
if (node && node.type === "MemberExpression" && node.object?.type === "MemberExpression" && node.object.object?.type === "ThisExpression" && node.object.property?.type === "Identifier" && node.object.property.name === "refs") {
|
|
79
84
|
matches.push(createPatternMatch(node, "stringRefs", code));
|
|
80
85
|
}
|
|
81
86
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/react-detect",
|
|
3
3
|
"description": "Run various checks to detect if a Grafana plugin is compatible with React.",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.2",
|
|
5
5
|
"repository": {
|
|
6
6
|
"directory": "packages/react-detect",
|
|
7
7
|
"url": "https://github.com/grafana/plugin-tools"
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=20"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "def49813c11febf54299c9541b0eeb243fb4e495"
|
|
45
45
|
}
|
|
@@ -92,6 +92,7 @@ describe('matcher', () => {
|
|
|
92
92
|
describe('findStringRefs', () => {
|
|
93
93
|
it('should find stringRefs assignments in source code', () => {
|
|
94
94
|
const code = `
|
|
95
|
+
import React from 'react';
|
|
95
96
|
class MyComponent extends React.Component {
|
|
96
97
|
componentDidMount() {
|
|
97
98
|
this.refs.input.focus();
|
|
@@ -111,6 +112,7 @@ describe('matcher', () => {
|
|
|
111
112
|
|
|
112
113
|
it('should find bracket notation refs access', () => {
|
|
113
114
|
const code = `
|
|
115
|
+
import React from 'react';
|
|
114
116
|
class MyComponent extends React.Component {
|
|
115
117
|
componentDidMount() {
|
|
116
118
|
this.refs['input'].focus();
|
|
@@ -127,6 +129,35 @@ describe('matcher', () => {
|
|
|
127
129
|
expect(matches[0].pattern).toBe('stringRefs');
|
|
128
130
|
expect(matches[0].matched).toContain('this.refs');
|
|
129
131
|
});
|
|
132
|
+
|
|
133
|
+
it('should not match this.refs in files without a React import', () => {
|
|
134
|
+
const code = `
|
|
135
|
+
class ComponentRegistry {
|
|
136
|
+
getRef() {
|
|
137
|
+
return this.refs.primary;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
const ast = parseFile(code, 'test.js');
|
|
142
|
+
const matches = findStringRefs(ast, code);
|
|
143
|
+
|
|
144
|
+
expect(matches).toHaveLength(0);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should not match bare this.refs access without property access', () => {
|
|
148
|
+
const code = `
|
|
149
|
+
import React from 'react';
|
|
150
|
+
class MyComponent extends React.Component {
|
|
151
|
+
getAllRefs() {
|
|
152
|
+
return this.refs;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
`;
|
|
156
|
+
const ast = parseFile(code, 'test.js');
|
|
157
|
+
const matches = findStringRefs(ast, code);
|
|
158
|
+
|
|
159
|
+
expect(matches).toHaveLength(0);
|
|
160
|
+
});
|
|
130
161
|
});
|
|
131
162
|
|
|
132
163
|
describe('findFindDOMNode', () => {
|
package/src/patterns/matcher.ts
CHANGED
|
@@ -102,14 +102,21 @@ export function findJsxRuntimeImports(ast: TSESTree.Program, code: string): Patt
|
|
|
102
102
|
|
|
103
103
|
export function findStringRefs(ast: TSESTree.Program, code: string): PatternMatch[] {
|
|
104
104
|
const matches: PatternMatch[] = [];
|
|
105
|
+
const imports = trackImportsFromPackage(ast, 'react');
|
|
106
|
+
|
|
107
|
+
const hasReactImport = imports.defaultImports.size > 0 || imports.namedImports.size > 0;
|
|
108
|
+
if (!hasReactImport) {
|
|
109
|
+
return matches;
|
|
110
|
+
}
|
|
105
111
|
|
|
106
112
|
walk(ast, (node) => {
|
|
107
113
|
if (
|
|
108
114
|
node &&
|
|
109
115
|
node.type === 'MemberExpression' &&
|
|
110
|
-
node.object
|
|
111
|
-
node.
|
|
112
|
-
node.property
|
|
116
|
+
node.object?.type === 'MemberExpression' &&
|
|
117
|
+
node.object.object?.type === 'ThisExpression' &&
|
|
118
|
+
node.object.property?.type === 'Identifier' &&
|
|
119
|
+
node.object.property.name === 'refs'
|
|
113
120
|
) {
|
|
114
121
|
matches.push(createPatternMatch(node, 'stringRefs', code));
|
|
115
122
|
}
|