Skip to content

Commit ae5439e

Browse files
authored
feat(no-unknown-wire-adapters): support module and identifier as a glob pattern (#40)
In some cases like [apex adapters](https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex), we don’t know the adapters before hand. This PR adds support for globs in the `module` and `identifier` property, allowing (mark as known) all wire adapters matching the `module` and `identifier` glob patterns.
1 parent b9d4da9 commit ae5439e

File tree

4 files changed

+201
-3
lines changed

4 files changed

+201
-3
lines changed

docs/rules/no-unknown-wire-adapters.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ This rule can be configured as follows:
1414

1515
// for modules exporting wire adapters using default exports
1616
{ module: '<module name>', identifier: 'default' },
17+
18+
// to match multiple adapters, use glob patterns
19+
{ module: '<module name glob pattern>', identifier: '<adapter identifier glob pattern>' },
1720
];
1821
}
1922
```
2023

2124
Any usage of the `@wire` decorator will be flagged as an error unless a list of known adapters has been provided.
2225

2326
```js
24-
/*eslint lwc/no-unexpected-wire-adapters: ["error", {"adapters": [{"module": "myAdapters", "identifier": "fooAdapter"}]}]*/
27+
/*eslint lwc/no-unexpected-wire-adapters: ["error", {"adapters": [{"module": "myAdapters", "identifier": "fooAdapter"}, {"module": "@salesforce/apex/*", "identifier": "*"}]}]*/
2528

2629
import { LightningElement, wire } from 'lwc';
30+
import { apexMethod } from '@salesforce/apex/Namespace.Classname.apexMethodReference';
31+
import { otherApexMethod } from '@salesforce/apex/Namespace/Classname.apexMethodReference';
2732
import defaultAdapter, { fooAdapter, barAdapter } from 'myAdapters';
2833

2934
export default class Example extends LightningElement {
@@ -35,5 +40,11 @@ export default class Example extends LightningElement {
3540

3641
@wire(defaultAdapter) // invalid, missing adapter in config: {"module": "myAdapters", "identifier": "default"}
3742
default;
43+
44+
@wire(apexMethod) // valid
45+
apexMethodResult;
46+
47+
@wire(otherApexMethod) // invalid, does not match "@salesforce/apex/*" glob pattern
48+
otherApexMethodResult;
3849
}
3950
```

lib/rules/no-unknown-wire-adapters.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
'use strict';
88

99
const { docUrl } = require('../util/doc-url');
10+
const { Minimatch } = require("minimatch");
1011

1112
module.exports = {
1213
meta: {
@@ -43,7 +44,12 @@ module.exports = {
4344
},
4445

4546
create(context) {
46-
const knownAdapters = context.options[0].adapters;
47+
const knownAdapters = context.options[0].adapters.map((adapter) => {
48+
return {
49+
module: new Minimatch(adapter.module),
50+
identifier: new Minimatch(adapter.identifier),
51+
}
52+
});
4753

4854
return {
4955
Decorator(node) {
@@ -101,7 +107,7 @@ module.exports = {
101107
// Finally check if the imported identifier originates from a known module.
102108
const isKnownAdapter = knownAdapters.some((adapter) => {
103109
return (
104-
adapter.module === adapterModule && adapter.identifier === adapterIdentifier
110+
adapter.module.match(adapterModule) && adapter.identifier.match(adapterIdentifier)
105111
);
106112
});
107113
if (!isKnownAdapter) {

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
"nyc": "^15.0.1",
2525
"prettier": "^2.0.5"
2626
},
27+
"dependencies": {
28+
"minimatch": "^3.0.4"
29+
},
2730
"peerDependencies": {
2831
"babel-eslint": ">=10.0.0",
2932
"eslint": ">=6.0.0"

test/lib/rules/no-unknown-wire-adapters.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,58 @@ ruleTester.run('no-unknown-wire-adapters', rule, {
122122
},
123123
],
124124
},
125+
{
126+
code: `import { wire } from 'lwc';
127+
import { apexMethod } from '@salesforce/apex/Namespace.Classname.apexMethodReference';
128+
129+
class Test {
130+
@wire(apexMethod)
131+
wiredProp;
132+
}`,
133+
options: [
134+
{
135+
adapters: [
136+
{ module: '@salesforce/apex/*', identifier: '*' },
137+
],
138+
},
139+
],
140+
},
141+
{
142+
code: `import { wire } from 'lwc';
143+
import { getFoo } from 'adapterFoo';
144+
import { apexMethod } from '@salesforce/apex/Namespace.Classname.apexMethodReference';
145+
146+
class Test {
147+
@wire(apexMethod)
148+
wiredProp;
149+
150+
@wire(getFoo)
151+
wiredFoo;
152+
}`,
153+
options: [
154+
{
155+
adapters: [
156+
{ module: 'adapterFoo', identifier: 'getFoo' },
157+
{ module: '@salesforce/apex/*', identifier: '*' },
158+
],
159+
},
160+
],
161+
},
162+
{
163+
code: `import { wire } from 'lwc';
164+
import startRequest from '@salesforce/apexContinuation/SampleContinuationClass.startRequest';
165+
166+
class Test {
167+
@wire(startRequest) wiredProp;
168+
}`,
169+
options: [
170+
{
171+
adapters: [
172+
{ module: '@salesforce/**', identifier: '*' },
173+
],
174+
},
175+
]
176+
},
125177
],
126178
invalid: [
127179
{
@@ -198,5 +250,131 @@ ruleTester.run('no-unknown-wire-adapters', rule, {
198250
},
199251
],
200252
},
253+
// verify matches is not using includes.
254+
{
255+
code: `import { wire } from 'lwc';
256+
import { getPost } from 'adapter';
257+
258+
class Test {
259+
@wire(getPost) wiredProp;
260+
}`,
261+
options: [
262+
{
263+
adapters: [{ module: 'adapter', identifier: 'getPosts' }],
264+
},
265+
],
266+
errors: [
267+
{
268+
message: '"getPost" from "adapter" is not a known adapter.',
269+
},
270+
],
271+
},
272+
// code sensitive.
273+
{
274+
code: `import { wire } from 'lwc';
275+
import { getFoo } from 'adapter';
276+
277+
class Test {
278+
@wire(getFoo) wiredProp;
279+
}`,
280+
options: [
281+
{
282+
adapters: [{ module: 'adapter', identifier: 'getfoo' }],
283+
},
284+
],
285+
errors: [
286+
{
287+
message: '"getFoo" from "adapter" is not a known adapter.',
288+
},
289+
],
290+
},
291+
// matches multiple module, but not identifier
292+
{
293+
code: `import { wire } from 'lwc';
294+
import { apexMethod } from '@salesforce/apex/Namespace.Classname.apexMethodReference';
295+
296+
class Test {
297+
@wire(apexMethod)
298+
wiredProp;
299+
}`,
300+
options: [
301+
{
302+
adapters: [
303+
{ module: '@salesforce/apex/*', identifier: 'default' },
304+
],
305+
},
306+
],
307+
errors: [
308+
{
309+
message: '"apexMethod" from "@salesforce/apex/Namespace.Classname.apexMethodReference" is not a known adapter.',
310+
},
311+
],
312+
},
313+
// matches multiple identifiers, but only one module.
314+
{
315+
code: `import { wire } from 'lwc';
316+
import { apexMethod } from '@salesforce/apex/Namespace.Classname.apexMethodReference';
317+
import { fooMethod } from '@salesforce/apex/Foo.Namespace';
318+
319+
class Test {
320+
@wire(apexMethod)
321+
wiredProp;
322+
323+
@wire(fooMethod)
324+
wiredValue;
325+
}`,
326+
options: [
327+
{
328+
adapters: [
329+
{ module: '@salesforce/apex/Foo.Namespace', identifier: '*' },
330+
],
331+
},
332+
],
333+
errors: [
334+
{
335+
message: '"apexMethod" from "@salesforce/apex/Namespace.Classname.apexMethodReference" is not a known adapter.',
336+
},
337+
],
338+
},
339+
{
340+
code: `import { wire } from 'lwc';
341+
import startRequest from '@salesforce/apex/Continuation/SampleContinuationClass.startRequest';
342+
343+
class Test {
344+
@wire(startRequest) wiredProp;
345+
}`,
346+
options: [
347+
{
348+
adapters: [
349+
{ module: '@salesforce/apex/*', identifier: '*' },
350+
],
351+
},
352+
],
353+
errors: [
354+
{
355+
message: '"default" from "@salesforce/apex/Continuation/SampleContinuationClass.startRequest" is not a known adapter.',
356+
},
357+
],
358+
},
359+
{
360+
code: `import { wire } from 'lwc';
361+
import startRequest from '@salesforce/apexContinuation/SampleContinuationClass.startRequest';
362+
363+
class Test {
364+
@wire(startRequest) wiredProp;
365+
}`,
366+
options: [
367+
{
368+
adapters: [
369+
{ module: '@salesforce/apex*', identifier: '*' },
370+
],
371+
},
372+
],
373+
errors: [
374+
{
375+
message: '"default" from "@salesforce/apexContinuation/SampleContinuationClass.startRequest" is not a known adapter.',
376+
},
377+
],
378+
},
201379
],
202380
});

0 commit comments

Comments
 (0)