Skip to content

Commit c57c51f

Browse files
@W-17070457 Allow multi conditional !import.meta.env.SSR statements (#171)
Co-authored-by: Nolan Lawson <[email protected]>
1 parent c9ac717 commit c57c51f

File tree

2 files changed

+208
-3
lines changed

2 files changed

+208
-3
lines changed

lib/util/ssr.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,38 @@
77
'use strict';
88

99
module.exports.isSSREscape = function isSSREscape(node) {
10-
return (
10+
if (
1111
(node.type === 'IfStatement' || node.type === 'ConditionalExpression') &&
12-
(isMetaEnvCheck(node.test) || isWindowOrDocumentCheck(node.test))
13-
);
12+
checkConditionalStatements(node.test)
13+
) {
14+
return true;
15+
}
16+
17+
return false;
1418
};
1519

20+
function checkConditionalStatements(test) {
21+
let node = test;
22+
23+
// Base Case: If the node is a `!` UnaryExpression, call isMetaEnvCheck().
24+
if (node.type === 'UnaryExpression' && node.operator === '!') {
25+
return isMetaEnvCheck(node);
26+
}
27+
28+
// Base Case: If the node is a `!==` BinaryExpresion, call isWindowOrDocumentCheck().
29+
if (node.type === 'BinaryExpression' && node.operator === '!==') {
30+
return isWindowOrDocumentCheck(node);
31+
}
32+
33+
// Recursive Case: If the node is a `&&` logical expression, check its left and right parts.
34+
if (node.type === 'LogicalExpression' && node.operator === '&&') {
35+
const rightNodeConditional = checkConditionalStatements(node.right);
36+
return rightNodeConditional || checkConditionalStatements(node.left);
37+
}
38+
39+
return false;
40+
}
41+
1642
function isMetaEnvCheck(test) {
1743
let node = test;
1844
if (!(node.type === 'UnaryExpression' && node.operator === '!')) return false;

test/lib/rules/no-unsupported-ssr-properties.js

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,95 @@ testRule('no-unsupported-ssr-properties', {
107107
}
108108
`,
109109
},
110+
{
111+
code: `
112+
import { LightningElement } from 'lwc';
113+
114+
export default class Foo extends LightningElement {
115+
connectedCallback() {
116+
if (!import.meta.env.SSR && !randomOtherCheck) {
117+
this.querySelector('span').getAttribute('role');
118+
}
119+
}
120+
}
121+
`,
122+
},
123+
{
124+
code: `
125+
import { LightningElement } from 'lwc';
126+
127+
export default class Foo extends LightningElement {
128+
connectedCallback() {
129+
if (!import.meta.env.SSR && randomOtherCheck) {
130+
this.querySelector('span').getAttribute('role');
131+
}
132+
}
133+
}
134+
`,
135+
},
136+
{
137+
code: `
138+
import { LightningElement } from 'lwc';
139+
140+
export default class Foo extends LightningElement {
141+
connectedCallback() {
142+
if (randomOtherCheck && !import.meta.env.SSR) {
143+
this.querySelector('span').getAttribute('role');
144+
}
145+
}
146+
}
147+
`,
148+
},
149+
{
150+
code: `
151+
import { LightningElement } from 'lwc';
152+
153+
export default class Foo extends LightningElement {
154+
connectedCallback() {
155+
if (!a && b && !c && d && !import.meta.env.SSR) {
156+
this.querySelector('span').getAttribute('role');
157+
}
158+
}
159+
}
160+
`,
161+
},
162+
{
163+
code: `
164+
import { LightningElement } from 'lwc';
165+
166+
export default class Foo extends LightningElement {
167+
connectedCallback() {
168+
if (a && (b && !import.meta.env.SSR)) {
169+
this.querySelector('span').getAttribute('role');
170+
}
171+
}
172+
}
173+
`,
174+
},
175+
{
176+
code: `
177+
import { LightningElement } from 'lwc';
178+
179+
export default class Foo extends LightningElement {
180+
connectedCallback() {
181+
return !import.meta.env.SSR ? this.querySelector('button') : null;
182+
}
183+
}
184+
`,
185+
},
186+
{
187+
code: `
188+
import { LightningElement } from 'lwc';
189+
190+
export default class Foo extends LightningElement {
191+
connectedCallback() {
192+
if (randomOtherCheck && typeof window !== 'undefined') {
193+
this.querySelector('span').getAttribute('role');
194+
}
195+
}
196+
}
197+
`,
198+
},
110199
],
111200
invalid: [
112201
{
@@ -364,5 +453,95 @@ testRule('no-unsupported-ssr-properties', {
364453
},
365454
],
366455
},
456+
{
457+
code: `
458+
import { LightningElement } from 'lwc';
459+
460+
export default class Foo extends LightningElement {
461+
connectedCallback() {
462+
if (!a && b && !c && d) {
463+
this.querySelector('span').getAttribute('role');
464+
}
465+
}
466+
}
467+
`,
468+
errors: [
469+
{
470+
messageId: 'propertyAccessFound',
471+
},
472+
],
473+
},
474+
{
475+
code: `
476+
import { LightningElement } from 'lwc';
477+
478+
export default class Foo extends LightningElement {
479+
connectedCallback() {
480+
if (a && (b || !import.meta.env.SSR)) {
481+
this.querySelector('span').getAttribute('role');
482+
}
483+
}
484+
}
485+
`,
486+
errors: [
487+
{
488+
messageId: 'propertyAccessFound',
489+
},
490+
],
491+
},
492+
{
493+
code: `
494+
import { LightningElement } from 'lwc';
495+
496+
export default class Foo extends LightningElement {
497+
connectedCallback() {
498+
if (a || (b || !import.meta.env.SSR)) {
499+
this.querySelector('span').getAttribute('role');
500+
}
501+
}
502+
}
503+
`,
504+
errors: [
505+
{
506+
messageId: 'propertyAccessFound',
507+
},
508+
],
509+
},
510+
{
511+
code: `
512+
import { LightningElement } from 'lwc';
513+
514+
export default class Foo extends LightningElement {
515+
connectedCallback() {
516+
if (a || (b && !import.meta.env.SSR)) {
517+
this.querySelector('span').getAttribute('role');
518+
}
519+
}
520+
}
521+
`,
522+
errors: [
523+
{
524+
messageId: 'propertyAccessFound',
525+
},
526+
],
527+
},
528+
{
529+
code: `
530+
import { LightningElement } from 'lwc';
531+
532+
export default class Foo extends LightningElement {
533+
connectedCallback() {
534+
if (randomOtherCheck && typeof window == 'undefined') {
535+
this.querySelector('span').getAttribute('role');
536+
}
537+
}
538+
}
539+
`,
540+
errors: [
541+
{
542+
messageId: 'propertyAccessFound',
543+
},
544+
],
545+
},
367546
],
368547
});

0 commit comments

Comments
 (0)