@empline/preflight 1.1.50 → 1.1.52
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/dist/checks/react/session-provider-usage.d.ts +11 -0
- package/dist/checks/react/session-provider-usage.d.ts.map +1 -0
- package/dist/checks/react/session-provider-usage.js +263 -0
- package/dist/checks/react/session-provider-usage.js.map +1 -0
- package/dist/checks/react/state-update-during-render.d.ts.map +1 -1
- package/dist/checks/react/state-update-during-render.js +1 -0
- package/dist/checks/react/state-update-during-render.js.map +1 -1
- package/dist/checks/react/turbopack-safe-expressions.d.ts +49 -0
- package/dist/checks/react/turbopack-safe-expressions.d.ts.map +1 -0
- package/dist/checks/react/turbopack-safe-expressions.js +450 -0
- package/dist/checks/react/turbopack-safe-expressions.js.map +1 -0
- package/dist/checks/ui/floating-element-zindex.d.ts +10 -0
- package/dist/checks/ui/floating-element-zindex.d.ts.map +1 -0
- package/dist/checks/ui/floating-element-zindex.js +292 -0
- package/dist/checks/ui/floating-element-zindex.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { PreflightCheckResult } from "../../core/types";
|
|
3
|
+
export declare const id = "react/session-provider-usage";
|
|
4
|
+
export declare const name = "Session Provider Usage";
|
|
5
|
+
export declare const description = "Detects useSession usage without proper SessionProvider context";
|
|
6
|
+
export declare const category = "react";
|
|
7
|
+
export declare const blocking = true;
|
|
8
|
+
export declare const tags: string[];
|
|
9
|
+
export declare const requires: string[];
|
|
10
|
+
export declare function run(): Promise<PreflightCheckResult>;
|
|
11
|
+
//# sourceMappingURL=session-provider-usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-provider-usage.d.ts","sourceRoot":"","sources":["../../../src/checks/react/session-provider-usage.ts"],"names":[],"mappings":";AAwBA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAI1E,eAAO,MAAM,EAAE,iCAAiC,CAAC;AACjD,eAAO,MAAM,IAAI,2BAA2B,CAAC;AAC7C,eAAO,MAAM,WAAW,oEAAoE,CAAC;AAC7F,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAoD,CAAC;AACtE,eAAO,MAAM,QAAQ,UAAgB,CAAC;AAmEtC,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkFzD"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.requires = exports.tags = exports.blocking = exports.category = exports.description = exports.name = exports.id = void 0;
|
|
38
|
+
exports.run = run;
|
|
39
|
+
/**
|
|
40
|
+
* Session Provider Usage Preflight
|
|
41
|
+
*
|
|
42
|
+
* Detects common issues with next-auth useSession hook usage that cause:
|
|
43
|
+
* "useSession must be wrapped in a <SessionProvider />"
|
|
44
|
+
*
|
|
45
|
+
* Common problematic patterns:
|
|
46
|
+
*
|
|
47
|
+
* 1. Components using useSession without "use client" directive
|
|
48
|
+
* Server components cannot use React hooks
|
|
49
|
+
*
|
|
50
|
+
* 2. Components using useSession imported directly in server components
|
|
51
|
+
* Should use dynamic import with { ssr: false } or wrap in Suspense
|
|
52
|
+
*
|
|
53
|
+
* 3. useSession used in components rendered outside SessionProvider context
|
|
54
|
+
* Usually happens when components are rendered in a sub-layout that
|
|
55
|
+
* doesn't inherit from the root layout's Providers
|
|
56
|
+
*
|
|
57
|
+
* BLOCKING: Yes - This causes runtime errors
|
|
58
|
+
*/
|
|
59
|
+
const fs = __importStar(require("node:fs"));
|
|
60
|
+
const path = __importStar(require("node:path"));
|
|
61
|
+
const glob_1 = require("glob");
|
|
62
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
63
|
+
// METADATA
|
|
64
|
+
exports.id = "react/session-provider-usage";
|
|
65
|
+
exports.name = "Session Provider Usage";
|
|
66
|
+
exports.description = "Detects useSession usage without proper SessionProvider context";
|
|
67
|
+
exports.category = "react";
|
|
68
|
+
exports.blocking = true;
|
|
69
|
+
exports.tags = ["react", "next-auth", "session", "hooks", "ssr"];
|
|
70
|
+
exports.requires = ["next-auth"];
|
|
71
|
+
const FILE_PATTERNS = ["components/**/*.tsx", "app/**/*.tsx", "src/**/*.tsx", "pages/**/*.tsx"];
|
|
72
|
+
const EXCLUDE_PATTERNS = [
|
|
73
|
+
"**/node_modules/**",
|
|
74
|
+
"**/*.test.tsx",
|
|
75
|
+
"**/*.spec.tsx",
|
|
76
|
+
"**/*.stories.tsx",
|
|
77
|
+
"**/.storybook/**",
|
|
78
|
+
"**/providers.tsx",
|
|
79
|
+
];
|
|
80
|
+
function hasUseClientDirective(content) {
|
|
81
|
+
const firstNonCommentLine = content
|
|
82
|
+
.split("\n")
|
|
83
|
+
.find(line => {
|
|
84
|
+
const trimmed = line.trim();
|
|
85
|
+
return trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("/*") && !trimmed.startsWith("*");
|
|
86
|
+
});
|
|
87
|
+
return firstNonCommentLine?.includes('"use client"') ||
|
|
88
|
+
firstNonCommentLine?.includes("'use client'") ||
|
|
89
|
+
content.trimStart().startsWith('"use client"') ||
|
|
90
|
+
content.trimStart().startsWith("'use client'");
|
|
91
|
+
}
|
|
92
|
+
function usesSessionHook(content) {
|
|
93
|
+
const lines = content.split("\n");
|
|
94
|
+
for (let i = 0; i < lines.length; i++) {
|
|
95
|
+
if (lines[i].includes("useSession") && !lines[i].includes("import")) {
|
|
96
|
+
return { uses: true, line: i + 1 };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { uses: false, line: 0 };
|
|
100
|
+
}
|
|
101
|
+
function importsSessionComponent(content, sessionComponents) {
|
|
102
|
+
const lines = content.split("\n");
|
|
103
|
+
for (let i = 0; i < lines.length; i++) {
|
|
104
|
+
const line = lines[i];
|
|
105
|
+
if (line.includes("import") && line.includes("from")) {
|
|
106
|
+
for (const component of sessionComponents) {
|
|
107
|
+
if (line.includes(component) && !line.includes("dynamic(")) {
|
|
108
|
+
return { imports: true, component, line: i + 1 };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { imports: false, component: "", line: 0 };
|
|
114
|
+
}
|
|
115
|
+
function isDynamicImportWithSsrFalse(content, componentName) {
|
|
116
|
+
const dynamicPattern = new RegExp(`dynamic\\s*\\([^)]*${componentName}[^)]*\\{[^}]*ssr\\s*:\\s*false`, "s");
|
|
117
|
+
return dynamicPattern.test(content);
|
|
118
|
+
}
|
|
119
|
+
async function run() {
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
const findings = [];
|
|
122
|
+
// Find all component files
|
|
123
|
+
const allFiles = [];
|
|
124
|
+
for (const pattern of FILE_PATTERNS) {
|
|
125
|
+
const matches = await (0, glob_1.glob)(pattern, { cwd: process.cwd(), ignore: EXCLUDE_PATTERNS });
|
|
126
|
+
allFiles.push(...matches);
|
|
127
|
+
}
|
|
128
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
129
|
+
// First pass: Find all components that use useSession
|
|
130
|
+
const sessionComponents = new Map();
|
|
131
|
+
for (const relativePath of uniqueFiles) {
|
|
132
|
+
const filePath = path.join(process.cwd(), relativePath);
|
|
133
|
+
if (!fs.existsSync(filePath))
|
|
134
|
+
continue;
|
|
135
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
136
|
+
const { uses, line } = usesSessionHook(content);
|
|
137
|
+
if (uses) {
|
|
138
|
+
const fileName = path.basename(relativePath, ".tsx");
|
|
139
|
+
sessionComponents.set(fileName, relativePath);
|
|
140
|
+
// Check if it has "use client" directive
|
|
141
|
+
if (!hasUseClientDirective(content)) {
|
|
142
|
+
findings.push({
|
|
143
|
+
level: "error",
|
|
144
|
+
message: `Component uses useSession but missing "use client" directive`,
|
|
145
|
+
file: relativePath,
|
|
146
|
+
startLine: line,
|
|
147
|
+
ruleId: "missing-use-client",
|
|
148
|
+
suggestion: `Add "use client" at the top of the file`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Second pass: Check for server components importing session-using components
|
|
154
|
+
for (const relativePath of uniqueFiles) {
|
|
155
|
+
const filePath = path.join(process.cwd(), relativePath);
|
|
156
|
+
if (!fs.existsSync(filePath))
|
|
157
|
+
continue;
|
|
158
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
159
|
+
// Skip client components - they're safe
|
|
160
|
+
if (hasUseClientDirective(content))
|
|
161
|
+
continue;
|
|
162
|
+
// Skip files that are the session components themselves
|
|
163
|
+
const fileName = path.basename(relativePath, ".tsx");
|
|
164
|
+
if (sessionComponents.has(fileName))
|
|
165
|
+
continue;
|
|
166
|
+
// Check if this server component imports any session-using component
|
|
167
|
+
const componentNames = new Set(sessionComponents.keys());
|
|
168
|
+
const { imports, component, line } = importsSessionComponent(content, componentNames);
|
|
169
|
+
if (imports) {
|
|
170
|
+
// Check if it's a safe dynamic import
|
|
171
|
+
if (!isDynamicImportWithSsrFalse(content, component)) {
|
|
172
|
+
findings.push({
|
|
173
|
+
level: "error",
|
|
174
|
+
message: `Server component imports ${component} (uses useSession) without dynamic({ ssr: false })`,
|
|
175
|
+
file: relativePath,
|
|
176
|
+
startLine: line,
|
|
177
|
+
ruleId: "server-component-import",
|
|
178
|
+
suggestion: `Use dynamic import: const ${component} = dynamic(() => import("..."), { ssr: false })`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
passed: findings.filter(f => f.level === "error").length === 0,
|
|
185
|
+
findings,
|
|
186
|
+
duration: Date.now() - startTime,
|
|
187
|
+
metadata: {
|
|
188
|
+
sessionComponents: Array.from(sessionComponents.entries()).map(([name, file]) => ({ name, file })),
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async function main() {
|
|
193
|
+
console.log(`\n${console_chars_1.emoji.ruler} SESSION PROVIDER USAGE CHECK`);
|
|
194
|
+
console.log((0, console_chars_1.createDivider)(65, "heavy"));
|
|
195
|
+
const result = await run();
|
|
196
|
+
const sessionComponents = (result.metadata?.sessionComponents || []);
|
|
197
|
+
console.log(`\n${console_chars_1.emoji.info} Found ${sessionComponents.length} components using useSession:`);
|
|
198
|
+
for (const comp of sessionComponents) {
|
|
199
|
+
console.log(` - ${comp.name} (${comp.file})`);
|
|
200
|
+
}
|
|
201
|
+
if (result.passed) {
|
|
202
|
+
console.log(`\n${console_chars_1.emoji.success} SESSION PROVIDER USAGE CHECK PASSED`);
|
|
203
|
+
console.log(`\nAll useSession usages are properly configured.`);
|
|
204
|
+
// Advisory: Check if SessionProvider is in root layout
|
|
205
|
+
const layoutPath = path.join(process.cwd(), "app/layout.tsx");
|
|
206
|
+
const providersPath = path.join(process.cwd(), "app/providers.tsx");
|
|
207
|
+
if (fs.existsSync(layoutPath) && fs.existsSync(providersPath)) {
|
|
208
|
+
const layoutContent = fs.readFileSync(layoutPath, "utf-8");
|
|
209
|
+
const providersContent = fs.readFileSync(providersPath, "utf-8");
|
|
210
|
+
const hasProvidersInLayout = layoutContent.includes("<Providers") || layoutContent.includes("Providers>");
|
|
211
|
+
const hasSessionProvider = providersContent.includes("SessionProvider");
|
|
212
|
+
if (!hasProvidersInLayout || !hasSessionProvider) {
|
|
213
|
+
console.log(`\n${console_chars_1.emoji.warning} Advisory: SessionProvider setup may be incomplete`);
|
|
214
|
+
if (!hasSessionProvider) {
|
|
215
|
+
console.log(` - app/providers.tsx should include SessionProvider`);
|
|
216
|
+
}
|
|
217
|
+
if (!hasProvidersInLayout) {
|
|
218
|
+
console.log(` - app/layout.tsx should wrap children with <Providers>`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
console.log(`\n${console_chars_1.emoji.info} If you still see "useSession must be wrapped in SessionProvider":`);
|
|
223
|
+
console.log(` 1. Ensure components using useSession are rendered INSIDE Providers`);
|
|
224
|
+
console.log(` 2. Check for sub-layouts that might bypass root layout's Providers`);
|
|
225
|
+
console.log(` 3. For Turbopack/dev mode: Try hard refresh (Ctrl+Shift+R)`);
|
|
226
|
+
console.log(` 4. Check if the component is rendered before hydration completes`);
|
|
227
|
+
process.exit(0);
|
|
228
|
+
}
|
|
229
|
+
// Group issues by type
|
|
230
|
+
const missingDirective = result.findings?.filter(f => f.ruleId === "missing-use-client") || [];
|
|
231
|
+
const serverImports = result.findings?.filter(f => f.ruleId === "server-component-import") || [];
|
|
232
|
+
if (missingDirective.length > 0) {
|
|
233
|
+
console.log(`\n${console_chars_1.emoji.error} Missing "use client" directive (${missingDirective.length}):`);
|
|
234
|
+
console.log((0, console_chars_1.createDivider)(65, "light"));
|
|
235
|
+
for (const issue of missingDirective) {
|
|
236
|
+
console.log(` ${issue.file}:${issue.startLine}`);
|
|
237
|
+
console.log(` ${issue.message}`);
|
|
238
|
+
}
|
|
239
|
+
console.log(`\n Fix: Add "use client" at the top of the file`);
|
|
240
|
+
}
|
|
241
|
+
if (serverImports.length > 0) {
|
|
242
|
+
console.log(`\n${console_chars_1.emoji.error} Server components importing session hooks (${serverImports.length}):`);
|
|
243
|
+
console.log((0, console_chars_1.createDivider)(65, "light"));
|
|
244
|
+
for (const issue of serverImports) {
|
|
245
|
+
console.log(` ${issue.file}:${issue.startLine}`);
|
|
246
|
+
console.log(` ${issue.message}`);
|
|
247
|
+
}
|
|
248
|
+
console.log(`\n Fix: Use dynamic import with ssr: false:`);
|
|
249
|
+
console.log(` const UserMenu = dynamic(() => import("@/components/UserMenu"), { ssr: false })`);
|
|
250
|
+
}
|
|
251
|
+
console.log(`\n${console_chars_1.emoji.info} Why this matters:`);
|
|
252
|
+
console.log(` useSession requires SessionProvider context which is only available client-side.`);
|
|
253
|
+
console.log(` Server components that directly import session-using components will error.`);
|
|
254
|
+
console.log(`\n${console_chars_1.emoji.error} SESSION PROVIDER USAGE CHECK FAILED`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
if (require.main === module) {
|
|
258
|
+
main().catch((err) => {
|
|
259
|
+
console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
|
|
260
|
+
process.exit(1);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=session-provider-usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-provider-usage.js","sourceRoot":"","sources":["../../../src/checks/react/session-provider-usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-update-during-render.d.ts","sourceRoot":"","sources":["../../../src/checks/react/state-update-during-render.ts"],"names":[],"mappings":";AAeA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAI1E,eAAO,MAAM,EAAE,qCAAqC,CAAC;AACrD,eAAO,MAAM,IAAI,yCAAyC,CAAC;AAC3D,eAAO,MAAM,WAAW,4DAA4D,CAAC;AACrF,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAuD,CAAC;AACzE,eAAO,MAAM,QAAQ,UAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"state-update-during-render.d.ts","sourceRoot":"","sources":["../../../src/checks/react/state-update-during-render.ts"],"names":[],"mappings":";AAeA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAI1E,eAAO,MAAM,EAAE,qCAAqC,CAAC;AACrD,eAAO,MAAM,IAAI,yCAAyC,CAAC;AAC3D,eAAO,MAAM,WAAW,4DAA4D,CAAC;AACrF,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAuD,CAAC;AACzE,eAAO,MAAM,QAAQ,UAAY,CAAC;AA4ClC,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA+CzD"}
|
|
@@ -72,6 +72,7 @@ const SAFE_CONTEXTS = [
|
|
|
72
72
|
/\.catch\s*\(/,
|
|
73
73
|
/async\s+function/,
|
|
74
74
|
/const\s+\w+\s*=\s*async/,
|
|
75
|
+
/=>\s*\{[\s\S]*?await\b/, // Async arrow functions with await
|
|
75
76
|
];
|
|
76
77
|
const SET_STATE_PATTERN = /\b(set[A-Z]\w+)\s*\(/g;
|
|
77
78
|
function isInSafeContext(content, position) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-update-during-render.js","sourceRoot":"","sources":["../../../src/checks/react/state-update-during-render.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"state-update-during-render.js","sourceRoot":"","sources":["../../../src/checks/react/state-update-during-render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Preflight: Turbopack Safe Expressions
|
|
4
|
+
*
|
|
5
|
+
* Detects JavaScript expression patterns in JSX that can cause runtime errors
|
|
6
|
+
* when compiled by Turbopack (Next.js 13+). These patterns often result in
|
|
7
|
+
* cryptic "_ref is not defined" or similar errors.
|
|
8
|
+
*
|
|
9
|
+
* Known problematic patterns:
|
|
10
|
+
* 1. Nested optional chaining in template literals: ${a?.b?.c}
|
|
11
|
+
* 2. Optional chaining + nullish coalescing in JSX: ${a?.b ?? c}
|
|
12
|
+
* 3. Complex computed property access: obj[a?.b]
|
|
13
|
+
* 4. Optional chaining in function calls within JSX: ${fn(a?.b)}
|
|
14
|
+
*
|
|
15
|
+
* These patterns compile to temporary _ref variables that can become
|
|
16
|
+
* undefined in edge cases, causing runtime ReferenceErrors.
|
|
17
|
+
*
|
|
18
|
+
* BLOCKING: These cause runtime crashes that are hard to debug
|
|
19
|
+
*/
|
|
20
|
+
export declare const id = "react/turbopack-safe-expressions";
|
|
21
|
+
export declare const name = "Turbopack Safe Expressions";
|
|
22
|
+
export declare const category = "react";
|
|
23
|
+
export declare const blocking = true;
|
|
24
|
+
export declare const description = "Detects JSX expression patterns that cause Turbopack runtime errors";
|
|
25
|
+
export declare const tags: string[];
|
|
26
|
+
export declare function run(): Promise<{
|
|
27
|
+
passed: boolean;
|
|
28
|
+
findings: any[];
|
|
29
|
+
duration: number;
|
|
30
|
+
metadata?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
passed: boolean;
|
|
33
|
+
findings: {
|
|
34
|
+
message: string;
|
|
35
|
+
level: "error" | "warning";
|
|
36
|
+
file: string;
|
|
37
|
+
line: number;
|
|
38
|
+
code: string;
|
|
39
|
+
suggestion: string;
|
|
40
|
+
}[];
|
|
41
|
+
duration: number;
|
|
42
|
+
metadata: {
|
|
43
|
+
filesScanned: number;
|
|
44
|
+
errors: number;
|
|
45
|
+
warnings: number;
|
|
46
|
+
byRule: Record<string, number>;
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
49
|
+
//# sourceMappingURL=turbopack-safe-expressions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turbopack-safe-expressions.d.ts","sourceRoot":"","sources":["../../../src/checks/react/turbopack-safe-expressions.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG;AAQH,eAAO,MAAM,EAAE,qCAAqC,CAAC;AACrD,eAAO,MAAM,IAAI,+BAA+B,CAAC;AACjD,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,WAAW,wEAAwE,CAAC;AACjG,eAAO,MAAM,IAAI,UAAqE,CAAC;AAkUvF,wBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;GA+IxB"}
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Preflight: Turbopack Safe Expressions
|
|
5
|
+
*
|
|
6
|
+
* Detects JavaScript expression patterns in JSX that can cause runtime errors
|
|
7
|
+
* when compiled by Turbopack (Next.js 13+). These patterns often result in
|
|
8
|
+
* cryptic "_ref is not defined" or similar errors.
|
|
9
|
+
*
|
|
10
|
+
* Known problematic patterns:
|
|
11
|
+
* 1. Nested optional chaining in template literals: ${a?.b?.c}
|
|
12
|
+
* 2. Optional chaining + nullish coalescing in JSX: ${a?.b ?? c}
|
|
13
|
+
* 3. Complex computed property access: obj[a?.b]
|
|
14
|
+
* 4. Optional chaining in function calls within JSX: ${fn(a?.b)}
|
|
15
|
+
*
|
|
16
|
+
* These patterns compile to temporary _ref variables that can become
|
|
17
|
+
* undefined in edge cases, causing runtime ReferenceErrors.
|
|
18
|
+
*
|
|
19
|
+
* BLOCKING: These cause runtime crashes that are hard to debug
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.tags = exports.description = exports.blocking = exports.category = exports.name = exports.id = void 0;
|
|
56
|
+
exports.run = run;
|
|
57
|
+
const fs = __importStar(require("fs"));
|
|
58
|
+
const path = __importStar(require("path"));
|
|
59
|
+
const glob_1 = require("glob");
|
|
60
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
61
|
+
// Check metadata
|
|
62
|
+
exports.id = "react/turbopack-safe-expressions";
|
|
63
|
+
exports.name = "Turbopack Safe Expressions";
|
|
64
|
+
exports.category = "react";
|
|
65
|
+
exports.blocking = true;
|
|
66
|
+
exports.description = "Detects JSX expression patterns that cause Turbopack runtime errors";
|
|
67
|
+
exports.tags = ["turbopack", "nextjs", "runtime", "optional-chaining", "bundler"];
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// CONFIGURATION
|
|
70
|
+
// =============================================================================
|
|
71
|
+
const FILE_PATTERNS = [
|
|
72
|
+
"app/**/*.{tsx,jsx}",
|
|
73
|
+
"src/**/*.{tsx,jsx}",
|
|
74
|
+
"pages/**/*.{tsx,jsx}",
|
|
75
|
+
"components/**/*.{tsx,jsx}",
|
|
76
|
+
];
|
|
77
|
+
const EXCLUDE_PATTERNS = [
|
|
78
|
+
"node_modules/**",
|
|
79
|
+
"**/*.test.{ts,tsx}",
|
|
80
|
+
"**/*.spec.{ts,tsx}",
|
|
81
|
+
"**/*.stories.{tsx}",
|
|
82
|
+
"**/*.d.ts",
|
|
83
|
+
".next/**",
|
|
84
|
+
"dist/**",
|
|
85
|
+
];
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// DETECTION PATTERNS
|
|
88
|
+
// =============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Detect nested optional chaining in template literals within JSX
|
|
91
|
+
* Pattern: ${a?.b?.c} or ${a?.b?.c?.d}
|
|
92
|
+
*/
|
|
93
|
+
function detectNestedOptionalChaining(content, filePath) {
|
|
94
|
+
const findings = [];
|
|
95
|
+
const lines = content.split("\n");
|
|
96
|
+
// Track if we're in JSX context
|
|
97
|
+
let inJSX = false;
|
|
98
|
+
let jsxDepth = 0;
|
|
99
|
+
for (let i = 0; i < lines.length; i++) {
|
|
100
|
+
const line = lines[i];
|
|
101
|
+
// Simple JSX detection (not perfect but catches most cases)
|
|
102
|
+
const jsxOpens = (line.match(/<[A-Z][a-zA-Z]*|<[a-z]+\s/g) || []).length;
|
|
103
|
+
const jsxCloses = (line.match(/\/>/g) || []).length + (line.match(/<\/[a-zA-Z]+>/g) || []).length;
|
|
104
|
+
jsxDepth += jsxOpens - jsxCloses;
|
|
105
|
+
inJSX = jsxDepth > 0 || jsxOpens > 0;
|
|
106
|
+
// Look for template literals with nested optional chaining
|
|
107
|
+
// Pattern: `...${something?.nested?.property}...`
|
|
108
|
+
const templateMatches = line.matchAll(/\$\{([^}]+)\}/g);
|
|
109
|
+
for (const match of templateMatches) {
|
|
110
|
+
const expression = match[1];
|
|
111
|
+
const columnIndex = match.index || 0;
|
|
112
|
+
// Count optional chaining operators
|
|
113
|
+
const optionalChainCount = (expression.match(/\?\./g) || []).length;
|
|
114
|
+
if (optionalChainCount >= 2) {
|
|
115
|
+
// Nested optional chaining detected
|
|
116
|
+
findings.push({
|
|
117
|
+
file: filePath,
|
|
118
|
+
line: i + 1,
|
|
119
|
+
column: columnIndex,
|
|
120
|
+
rule: "turbopack-nested-optional",
|
|
121
|
+
severity: "error",
|
|
122
|
+
message: `Nested optional chaining in template literal can cause "_ref is not defined" runtime error`,
|
|
123
|
+
code: expression.trim(),
|
|
124
|
+
suggestion: `Extract to variable: const value = ${expression.trim()}; then use \${value}`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Check for optional chaining + nullish coalescing
|
|
128
|
+
if (expression.includes("?.") && expression.includes("??")) {
|
|
129
|
+
findings.push({
|
|
130
|
+
file: filePath,
|
|
131
|
+
line: i + 1,
|
|
132
|
+
column: columnIndex,
|
|
133
|
+
rule: "turbopack-optional-nullish",
|
|
134
|
+
severity: "error",
|
|
135
|
+
message: `Optional chaining with nullish coalescing in template literal can cause Turbopack runtime errors`,
|
|
136
|
+
code: expression.trim(),
|
|
137
|
+
suggestion: `Extract to variable: const value = ${expression.trim()}; then use \${value}`,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return findings;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Detect optional chaining in JSX attribute values (non-template)
|
|
146
|
+
* Pattern: prop={a?.b?.c ?? d}
|
|
147
|
+
*/
|
|
148
|
+
function detectOptionalChainingInJSXProps(content, filePath) {
|
|
149
|
+
const findings = [];
|
|
150
|
+
const lines = content.split("\n");
|
|
151
|
+
for (let i = 0; i < lines.length; i++) {
|
|
152
|
+
const line = lines[i];
|
|
153
|
+
// Match JSX prop assignments with complex expressions
|
|
154
|
+
// Pattern: propName={expression}
|
|
155
|
+
const propMatches = line.matchAll(/(\w+)=\{([^}]+)\}/g);
|
|
156
|
+
for (const match of propMatches) {
|
|
157
|
+
const propName = match[1];
|
|
158
|
+
const expression = match[2];
|
|
159
|
+
const columnIndex = match.index || 0;
|
|
160
|
+
// Skip simple expressions
|
|
161
|
+
if (!expression.includes("?."))
|
|
162
|
+
continue;
|
|
163
|
+
// Check for nested optional chaining with nullish coalescing
|
|
164
|
+
const hasNestedOptional = (expression.match(/\?\./g) || []).length >= 2;
|
|
165
|
+
const hasNullishCoalescing = expression.includes("??");
|
|
166
|
+
if (hasNestedOptional && hasNullishCoalescing) {
|
|
167
|
+
findings.push({
|
|
168
|
+
file: filePath,
|
|
169
|
+
line: i + 1,
|
|
170
|
+
column: columnIndex,
|
|
171
|
+
rule: "turbopack-complex-prop",
|
|
172
|
+
severity: "error",
|
|
173
|
+
message: `Complex expression in JSX prop "${propName}" can cause Turbopack runtime errors`,
|
|
174
|
+
code: expression.trim(),
|
|
175
|
+
suggestion: `Extract to variable above JSX: const ${propName}Value = ${expression.trim()};`,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// Check for optional chaining in computed property access
|
|
179
|
+
if (/\[[^\]]*\?\.[^\]]*\]/.test(expression)) {
|
|
180
|
+
findings.push({
|
|
181
|
+
file: filePath,
|
|
182
|
+
line: i + 1,
|
|
183
|
+
column: columnIndex,
|
|
184
|
+
rule: "turbopack-computed-optional",
|
|
185
|
+
severity: "error",
|
|
186
|
+
message: `Optional chaining in computed property access can cause runtime errors`,
|
|
187
|
+
code: expression.trim(),
|
|
188
|
+
suggestion: `Extract the optional chain: const key = a?.b; then use obj[key]`,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return findings;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Detect optional chaining in callback arguments within JSX
|
|
197
|
+
* Pattern: onClick={() => fn(a?.b?.c)}
|
|
198
|
+
*/
|
|
199
|
+
function detectOptionalChainingInCallbacks(content, filePath) {
|
|
200
|
+
const findings = [];
|
|
201
|
+
const lines = content.split("\n");
|
|
202
|
+
for (let i = 0; i < lines.length; i++) {
|
|
203
|
+
const line = lines[i];
|
|
204
|
+
// Match arrow functions in JSX with function calls containing optional chaining
|
|
205
|
+
// Pattern: () => fn(a?.b?.c) or (e) => fn(e, a?.b?.c)
|
|
206
|
+
const callbackMatches = line.matchAll(/=>\s*\w+\(([^)]+)\)/g);
|
|
207
|
+
for (const match of callbackMatches) {
|
|
208
|
+
const args = match[1];
|
|
209
|
+
const columnIndex = match.index || 0;
|
|
210
|
+
// Check for nested optional chaining in function arguments
|
|
211
|
+
const optionalChainCount = (args.match(/\?\./g) || []).length;
|
|
212
|
+
if (optionalChainCount >= 2) {
|
|
213
|
+
findings.push({
|
|
214
|
+
file: filePath,
|
|
215
|
+
line: i + 1,
|
|
216
|
+
column: columnIndex,
|
|
217
|
+
rule: "turbopack-callback-optional",
|
|
218
|
+
severity: "warning",
|
|
219
|
+
message: `Nested optional chaining in callback argument may cause issues`,
|
|
220
|
+
code: args.trim(),
|
|
221
|
+
suggestion: `Extract to variable inside callback: const value = ${args.split(",")[0].trim()}; fn(value)`,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return findings;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Detect spread with optional chaining in JSX
|
|
230
|
+
* Pattern: {...obj?.nested?.props}
|
|
231
|
+
*/
|
|
232
|
+
function detectOptionalSpread(content, filePath) {
|
|
233
|
+
const findings = [];
|
|
234
|
+
const lines = content.split("\n");
|
|
235
|
+
for (let i = 0; i < lines.length; i++) {
|
|
236
|
+
const line = lines[i];
|
|
237
|
+
// Match spread with optional chaining
|
|
238
|
+
const spreadMatches = line.matchAll(/\{\s*\.\.\.([^}]+\?\.[^}]+)\}/g);
|
|
239
|
+
for (const match of spreadMatches) {
|
|
240
|
+
const expression = match[1];
|
|
241
|
+
const columnIndex = match.index || 0;
|
|
242
|
+
if ((expression.match(/\?\./g) || []).length >= 1) {
|
|
243
|
+
findings.push({
|
|
244
|
+
file: filePath,
|
|
245
|
+
line: i + 1,
|
|
246
|
+
column: columnIndex,
|
|
247
|
+
rule: "turbopack-optional-spread",
|
|
248
|
+
severity: "error",
|
|
249
|
+
message: `Spread with optional chaining can cause runtime errors when undefined`,
|
|
250
|
+
code: `{...${expression.trim()}}`,
|
|
251
|
+
suggestion: `Use conditional: {...(obj?.nested?.props ?? {})} or extract: const props = obj?.nested?.props ?? {}; {...props}`,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return findings;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Detect chained method calls with optional chaining
|
|
260
|
+
* Pattern: ${arr?.filter(...)?.map(...)}
|
|
261
|
+
*/
|
|
262
|
+
function detectChainedMethodsWithOptional(content, filePath) {
|
|
263
|
+
const findings = [];
|
|
264
|
+
const lines = content.split("\n");
|
|
265
|
+
for (let i = 0; i < lines.length; i++) {
|
|
266
|
+
const line = lines[i];
|
|
267
|
+
// Match template literals containing chained optional method calls
|
|
268
|
+
const templateMatches = line.matchAll(/\$\{([^}]*\?\.\w+\([^)]*\)\?\.[^}]+)\}/g);
|
|
269
|
+
for (const match of templateMatches) {
|
|
270
|
+
const expression = match[1];
|
|
271
|
+
const columnIndex = match.index || 0;
|
|
272
|
+
findings.push({
|
|
273
|
+
file: filePath,
|
|
274
|
+
line: i + 1,
|
|
275
|
+
column: columnIndex,
|
|
276
|
+
rule: "turbopack-chained-methods",
|
|
277
|
+
severity: "error",
|
|
278
|
+
message: `Chained optional method calls in template literal can cause Turbopack runtime errors`,
|
|
279
|
+
code: expression.trim(),
|
|
280
|
+
suggestion: `Extract chain: const result = ${expression.trim()}; then use \${result}`,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return findings;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Detect ternary with optional chaining in JSX
|
|
288
|
+
* Pattern: {a?.b ? x : y} where a?.b?.c is used
|
|
289
|
+
*/
|
|
290
|
+
function detectTernaryWithNestedOptional(content, filePath) {
|
|
291
|
+
const findings = [];
|
|
292
|
+
const lines = content.split("\n");
|
|
293
|
+
for (let i = 0; i < lines.length; i++) {
|
|
294
|
+
const line = lines[i];
|
|
295
|
+
// Match ternary expressions with nested optional chaining
|
|
296
|
+
const ternaryMatches = line.matchAll(/\{([^}]*\?\.[^}]*\?\.[^}]*\?[^:}]+:[^}]+)\}/g);
|
|
297
|
+
for (const match of ternaryMatches) {
|
|
298
|
+
const expression = match[1];
|
|
299
|
+
const columnIndex = match.index || 0;
|
|
300
|
+
// Only flag if there's nested optional chaining before the ternary
|
|
301
|
+
const beforeTernary = expression.split("?")[0] + "?." + (expression.split("?.")[1]?.split("?")[0] || "");
|
|
302
|
+
if ((beforeTernary.match(/\?\./g) || []).length >= 2) {
|
|
303
|
+
findings.push({
|
|
304
|
+
file: filePath,
|
|
305
|
+
line: i + 1,
|
|
306
|
+
column: columnIndex,
|
|
307
|
+
rule: "turbopack-ternary-optional",
|
|
308
|
+
severity: "warning",
|
|
309
|
+
message: `Ternary with nested optional chaining may cause Turbopack issues`,
|
|
310
|
+
code: expression.trim().substring(0, 60) + (expression.length > 60 ? "..." : ""),
|
|
311
|
+
suggestion: `Extract condition: const hasValue = Boolean(a?.b?.c); then {hasValue ? x : y}`,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return findings;
|
|
317
|
+
}
|
|
318
|
+
// =============================================================================
|
|
319
|
+
// MAIN
|
|
320
|
+
// =============================================================================
|
|
321
|
+
function createDivider(length) {
|
|
322
|
+
return "═".repeat(length);
|
|
323
|
+
}
|
|
324
|
+
async function run() {
|
|
325
|
+
const startTime = Date.now();
|
|
326
|
+
const allFindings = [];
|
|
327
|
+
console.log(`\n${console_chars_1.emoji.lightning} TURBOPACK SAFE EXPRESSIONS CHECK`);
|
|
328
|
+
console.log(createDivider(65));
|
|
329
|
+
console.log(`\n${console_chars_1.emoji.info} Detects patterns that cause "_ref is not defined" runtime errors`);
|
|
330
|
+
// Find all files
|
|
331
|
+
const allFiles = [];
|
|
332
|
+
for (const pattern of FILE_PATTERNS) {
|
|
333
|
+
const matches = await (0, glob_1.glob)(pattern, {
|
|
334
|
+
cwd: process.cwd(),
|
|
335
|
+
ignore: EXCLUDE_PATTERNS,
|
|
336
|
+
});
|
|
337
|
+
allFiles.push(...matches);
|
|
338
|
+
}
|
|
339
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
340
|
+
if (uniqueFiles.length === 0) {
|
|
341
|
+
console.log(`${console_chars_1.emoji.skip} No React/JSX files found`);
|
|
342
|
+
return {
|
|
343
|
+
passed: true,
|
|
344
|
+
findings: [],
|
|
345
|
+
duration: Date.now() - startTime,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
console.log(`\n${console_chars_1.emoji.search} Scanning ${uniqueFiles.length} files for unsafe patterns...`);
|
|
349
|
+
// Analyze each file
|
|
350
|
+
for (const relativePath of uniqueFiles) {
|
|
351
|
+
const filePath = path.join(process.cwd(), relativePath);
|
|
352
|
+
if (!fs.existsSync(filePath))
|
|
353
|
+
continue;
|
|
354
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
355
|
+
// Skip files with ignore comment
|
|
356
|
+
if (content.includes("turbopack-safe-ignore") || content.includes("preflight-ignore-turbopack")) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
allFindings.push(...detectNestedOptionalChaining(content, relativePath));
|
|
360
|
+
allFindings.push(...detectOptionalChainingInJSXProps(content, relativePath));
|
|
361
|
+
allFindings.push(...detectOptionalChainingInCallbacks(content, relativePath));
|
|
362
|
+
allFindings.push(...detectOptionalSpread(content, relativePath));
|
|
363
|
+
allFindings.push(...detectChainedMethodsWithOptional(content, relativePath));
|
|
364
|
+
allFindings.push(...detectTernaryWithNestedOptional(content, relativePath));
|
|
365
|
+
}
|
|
366
|
+
// Group by severity
|
|
367
|
+
const errors = allFindings.filter((f) => f.severity === "error");
|
|
368
|
+
const warnings = allFindings.filter((f) => f.severity === "warning");
|
|
369
|
+
// Group by rule
|
|
370
|
+
const byRule = allFindings.reduce((acc, f) => {
|
|
371
|
+
acc[f.rule] = (acc[f.rule] || 0) + 1;
|
|
372
|
+
return acc;
|
|
373
|
+
}, {});
|
|
374
|
+
// Summary
|
|
375
|
+
console.log(`\n${console_chars_1.emoji.chart} Summary:`);
|
|
376
|
+
console.log(` Files scanned: ${uniqueFiles.length}`);
|
|
377
|
+
console.log(` Errors: ${errors.length} (blocking)`);
|
|
378
|
+
console.log(` Warnings: ${warnings.length}`);
|
|
379
|
+
if (Object.keys(byRule).length > 0) {
|
|
380
|
+
console.log(`\n By rule:`);
|
|
381
|
+
for (const [rule, count] of Object.entries(byRule)) {
|
|
382
|
+
console.log(` ${rule}: ${count}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (allFindings.length === 0) {
|
|
386
|
+
console.log(`\n${console_chars_1.emoji.success} TURBOPACK SAFE EXPRESSIONS CHECK PASSED`);
|
|
387
|
+
console.log(`\nNo unsafe expression patterns detected.`);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
// Show errors first
|
|
391
|
+
if (errors.length > 0) {
|
|
392
|
+
console.log(`\n${console_chars_1.emoji.error} BLOCKING: Unsafe Patterns Detected`);
|
|
393
|
+
console.log(`\nThese patterns WILL cause runtime errors with Turbopack:\n`);
|
|
394
|
+
for (const f of errors.slice(0, 15)) {
|
|
395
|
+
console.log(` ${console_chars_1.emoji.error} ${f.file}:${f.line}:${f.column}`);
|
|
396
|
+
console.log(` Rule: ${f.rule}`);
|
|
397
|
+
console.log(` Code: ${f.code}`);
|
|
398
|
+
console.log(` Fix: ${f.suggestion}`);
|
|
399
|
+
console.log();
|
|
400
|
+
}
|
|
401
|
+
if (errors.length > 15) {
|
|
402
|
+
console.log(` ... and ${errors.length - 15} more errors\n`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// Show warnings
|
|
406
|
+
if (warnings.length > 0) {
|
|
407
|
+
console.log(`${console_chars_1.emoji.warning} Warnings (${warnings.length}):`);
|
|
408
|
+
for (const f of warnings.slice(0, 5)) {
|
|
409
|
+
console.log(` ${f.file}:${f.line} [${f.rule}]`);
|
|
410
|
+
console.log(` ${f.message}`);
|
|
411
|
+
}
|
|
412
|
+
if (warnings.length > 5) {
|
|
413
|
+
console.log(` ... and ${warnings.length - 5} more warnings`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
console.log(`\n${console_chars_1.emoji.hint} How to fix:`);
|
|
417
|
+
console.log(` 1. Extract complex expressions to variables BEFORE the JSX return`);
|
|
418
|
+
console.log(` 2. Use simple variable references in template literals: \${value}`);
|
|
419
|
+
console.log(` 3. Avoid nested optional chaining (?.) in JSX expressions`);
|
|
420
|
+
console.log(`\n Example fix:`);
|
|
421
|
+
console.log(` ${console_chars_1.emoji.error} BEFORE: alt={\`Image: \${obj?.nested?.name ?? 'default'}\`}`);
|
|
422
|
+
console.log(` ${console_chars_1.emoji.success} AFTER: const altText = obj?.nested?.name ?? 'default';`);
|
|
423
|
+
console.log(` alt={\`Image: \${altText}\`}`);
|
|
424
|
+
const status = errors.length > 0 ? "FAILED" : "PASSED WITH WARNINGS";
|
|
425
|
+
console.log(`\n${errors.length > 0 ? console_chars_1.emoji.error : console_chars_1.emoji.warning} TURBOPACK SAFE EXPRESSIONS ${status}`);
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
passed: errors.length === 0,
|
|
429
|
+
findings: allFindings.map((f) => ({
|
|
430
|
+
message: `[${f.rule}] ${f.message}`,
|
|
431
|
+
level: f.severity,
|
|
432
|
+
file: f.file,
|
|
433
|
+
line: f.line,
|
|
434
|
+
code: f.rule,
|
|
435
|
+
suggestion: f.suggestion,
|
|
436
|
+
})),
|
|
437
|
+
duration: Date.now() - startTime,
|
|
438
|
+
metadata: {
|
|
439
|
+
filesScanned: uniqueFiles.length,
|
|
440
|
+
errors: errors.length,
|
|
441
|
+
warnings: warnings.length,
|
|
442
|
+
byRule,
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
// Standalone execution
|
|
447
|
+
if (require.main === module) {
|
|
448
|
+
run().then((result) => process.exit(result.passed ? 0 : 1));
|
|
449
|
+
}
|
|
450
|
+
//# sourceMappingURL=turbopack-safe-expressions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turbopack-safe-expressions.js","sourceRoot":"","sources":["../../../src/checks/react/turbopack-safe-expressions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { PreflightCheckResult } from "../../core/types";
|
|
3
|
+
export declare const id = "ui/floating-element-zindex";
|
|
4
|
+
export declare const name = "Floating Element Z-Index";
|
|
5
|
+
export declare const description = "Detects floating badges inside ring-offset elements and missing z-index";
|
|
6
|
+
export declare const category = "ui";
|
|
7
|
+
export declare const blocking = true;
|
|
8
|
+
export declare const tags: string[];
|
|
9
|
+
export declare function run(): Promise<PreflightCheckResult>;
|
|
10
|
+
//# sourceMappingURL=floating-element-zindex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-element-zindex.d.ts","sourceRoot":"","sources":["../../../src/checks/ui/floating-element-zindex.ts"],"names":[],"mappings":";AAiCA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAI1E,eAAO,MAAM,EAAE,+BAA+B,CAAC;AAC/C,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,4EAA4E,CAAC;AACrG,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAiF,CAAC;AA+FnG,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA0EzD"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.tags = exports.blocking = exports.category = exports.description = exports.name = exports.id = void 0;
|
|
38
|
+
exports.run = run;
|
|
39
|
+
/**
|
|
40
|
+
* Floating Element Z-Index Preflight
|
|
41
|
+
*
|
|
42
|
+
* Detects two problematic patterns:
|
|
43
|
+
*
|
|
44
|
+
* 1. CRITICAL: Floating badges INSIDE elements with ring-offset
|
|
45
|
+
* The ring-offset box-shadow will overlap badges regardless of z-index.
|
|
46
|
+
* Solution: Move badge outside the ring-offset element as a sibling.
|
|
47
|
+
*
|
|
48
|
+
* Problem pattern:
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <Card className="ring-2 ring-offset-2">
|
|
51
|
+
* <Badge className="absolute -top-2" /> // WRONG - ring overlaps badge
|
|
52
|
+
* </Card>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Correct pattern:
|
|
56
|
+
* ```tsx
|
|
57
|
+
* <Box className="relative">
|
|
58
|
+
* <Badge className="absolute -top-2" style={{ zIndex: "var(--z-floating-badge)" }} />
|
|
59
|
+
* <Card className="ring-2 ring-offset-2">...</Card>
|
|
60
|
+
* </Box>
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* 2. Floating elements missing z-index (advisory)
|
|
64
|
+
* Elements with negative positioning should have proper z-index.
|
|
65
|
+
*
|
|
66
|
+
* BLOCKING: Yes - Critical issues (ring-offset + badge) block the build
|
|
67
|
+
*/
|
|
68
|
+
const fs = __importStar(require("node:fs"));
|
|
69
|
+
const path = __importStar(require("node:path"));
|
|
70
|
+
const glob_1 = require("glob");
|
|
71
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
72
|
+
// METADATA
|
|
73
|
+
exports.id = "ui/floating-element-zindex";
|
|
74
|
+
exports.name = "Floating Element Z-Index";
|
|
75
|
+
exports.description = "Detects floating badges inside ring-offset elements and missing z-index";
|
|
76
|
+
exports.category = "ui";
|
|
77
|
+
exports.blocking = true;
|
|
78
|
+
exports.tags = ["ui", "z-index", "layout", "badge", "positioning", "ring-offset", "tailwind"];
|
|
79
|
+
const FILE_PATTERNS = ["components/**/*.tsx", "app/**/*.tsx", "src/**/*.tsx", "pages/**/*.tsx"];
|
|
80
|
+
const EXCLUDE_PATTERNS = [
|
|
81
|
+
"**/node_modules/**",
|
|
82
|
+
"**/*.test.tsx",
|
|
83
|
+
"**/*.spec.tsx",
|
|
84
|
+
"**/*.stories.tsx",
|
|
85
|
+
"**/.storybook/**",
|
|
86
|
+
];
|
|
87
|
+
const NEGATIVE_POSITION_PATTERNS = [
|
|
88
|
+
/-top-\d/,
|
|
89
|
+
/-bottom-\d/,
|
|
90
|
+
/-left-\d/,
|
|
91
|
+
/-right-\d/,
|
|
92
|
+
/top-\[-/,
|
|
93
|
+
/bottom-\[-/,
|
|
94
|
+
/left-\[-/,
|
|
95
|
+
/right-\[-/,
|
|
96
|
+
];
|
|
97
|
+
const VALID_ZINDEX_PATTERNS = [
|
|
98
|
+
/z-index:\s*["']?var\(--z-floating-badge\)/,
|
|
99
|
+
/z-index:\s*["']?var\(--z-content-controls\)/,
|
|
100
|
+
/z-index:\s*["']?var\(--z-/,
|
|
101
|
+
/zIndex:\s*["']?var\(--z-floating-badge\)/,
|
|
102
|
+
/zIndex:\s*["']?var\(--z-content-controls\)/,
|
|
103
|
+
/zIndex:\s*["']?var\(--z-/,
|
|
104
|
+
/z-\d{2,}/,
|
|
105
|
+
/z-\[/,
|
|
106
|
+
];
|
|
107
|
+
const SKIP_PATTERNS = [
|
|
108
|
+
/blur-/,
|
|
109
|
+
/opacity-\d/,
|
|
110
|
+
/bg-white\/\d/,
|
|
111
|
+
/animate-/,
|
|
112
|
+
/rounded-full.*bg-white\//,
|
|
113
|
+
/h-\d+.*w-\d+.*rounded/,
|
|
114
|
+
];
|
|
115
|
+
function detectRingOffsetBadgePattern(content, relativePath) {
|
|
116
|
+
const findings = [];
|
|
117
|
+
const ringOffsetPattern = /(<(?:Card|Box|div)[^>]*className="[^"]*ring-offset[^"]*"[^>]*>)([\s\S]*?)(<\/(?:Card|Box|div)>)/g;
|
|
118
|
+
let match;
|
|
119
|
+
while ((match = ringOffsetPattern.exec(content)) !== null) {
|
|
120
|
+
const openTag = match[1];
|
|
121
|
+
const innerContent = match[2];
|
|
122
|
+
const hasFloatingChild = NEGATIVE_POSITION_PATTERNS.some(pattern => pattern.test(innerContent));
|
|
123
|
+
if (hasFloatingChild) {
|
|
124
|
+
const hasBadgePattern = /(?:Badge|Chip|StatusChip|Box|span)[^>]*(?:-top-|-bottom-|-left-|-right-)/.test(innerContent);
|
|
125
|
+
if (hasBadgePattern) {
|
|
126
|
+
const beforeMatch = content.slice(0, match.index);
|
|
127
|
+
const lineNumber = (beforeMatch.match(/\n/g) || []).length + 1;
|
|
128
|
+
findings.push({
|
|
129
|
+
level: "error",
|
|
130
|
+
message: `Floating badge inside ring-offset element - badge will appear BEHIND ring regardless of z-index`,
|
|
131
|
+
file: relativePath,
|
|
132
|
+
startLine: lineNumber,
|
|
133
|
+
ruleId: "ring-offset-badge",
|
|
134
|
+
suggestion: `Move badge outside the ring-offset element as a sibling: <Box className="relative"><Badge .../><Card className="ring-offset-2">...</Card></Box>`,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return findings;
|
|
140
|
+
}
|
|
141
|
+
function extractLineContext(content, match) {
|
|
142
|
+
const beforeMatch = content.slice(0, match.index);
|
|
143
|
+
const lineNumber = (beforeMatch.match(/\n/g) || []).length + 1;
|
|
144
|
+
const lines = content.split("\n");
|
|
145
|
+
const lineContent = lines[lineNumber - 1] || "";
|
|
146
|
+
return { line: lineNumber, code: lineContent.trim() };
|
|
147
|
+
}
|
|
148
|
+
function hasProperZIndex(lineContent, surroundingContent) {
|
|
149
|
+
const contextToCheck = lineContent + " " + surroundingContent;
|
|
150
|
+
return VALID_ZINDEX_PATTERNS.some((pattern) => pattern.test(contextToCheck));
|
|
151
|
+
}
|
|
152
|
+
function isDecorativeElement(lineContent) {
|
|
153
|
+
return SKIP_PATTERNS.some((pattern) => pattern.test(lineContent));
|
|
154
|
+
}
|
|
155
|
+
async function run() {
|
|
156
|
+
const startTime = Date.now();
|
|
157
|
+
const findings = [];
|
|
158
|
+
let floatingElementsFound = 0;
|
|
159
|
+
// Find all component files
|
|
160
|
+
const allFiles = [];
|
|
161
|
+
for (const pattern of FILE_PATTERNS) {
|
|
162
|
+
const matches = await (0, glob_1.glob)(pattern, { cwd: process.cwd(), ignore: EXCLUDE_PATTERNS });
|
|
163
|
+
allFiles.push(...matches);
|
|
164
|
+
}
|
|
165
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
166
|
+
for (const relativePath of uniqueFiles) {
|
|
167
|
+
const filePath = path.join(process.cwd(), relativePath);
|
|
168
|
+
if (!fs.existsSync(filePath))
|
|
169
|
+
continue;
|
|
170
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
171
|
+
// CRITICAL CHECK: Detect ring-offset + floating badge pattern
|
|
172
|
+
const ringOffsetIssues = detectRingOffsetBadgePattern(content, relativePath);
|
|
173
|
+
findings.push(...ringOffsetIssues);
|
|
174
|
+
// Check for each negative position pattern (advisory)
|
|
175
|
+
for (const pattern of NEGATIVE_POSITION_PATTERNS) {
|
|
176
|
+
const matches = content.matchAll(new RegExp(pattern, "g"));
|
|
177
|
+
for (const match of matches) {
|
|
178
|
+
floatingElementsFound++;
|
|
179
|
+
const { line, code } = extractLineContext(content, match);
|
|
180
|
+
// Skip if it's a decorative element
|
|
181
|
+
if (isDecorativeElement(code))
|
|
182
|
+
continue;
|
|
183
|
+
// Skip if has preflight-ignore comment
|
|
184
|
+
const lineStart = content.lastIndexOf('\n', match.index || 0) + 1;
|
|
185
|
+
const lineBefore = content.substring(Math.max(0, lineStart - 100), lineStart);
|
|
186
|
+
if (/preflight-ignore/.test(lineBefore))
|
|
187
|
+
continue;
|
|
188
|
+
// Get surrounding context (3 lines before and after)
|
|
189
|
+
const lines = content.split("\n");
|
|
190
|
+
const startLine = Math.max(0, line - 4);
|
|
191
|
+
const endLine = Math.min(lines.length, line + 3);
|
|
192
|
+
const surroundingContent = lines.slice(startLine, endLine).join("\n");
|
|
193
|
+
// Check if proper z-index exists
|
|
194
|
+
if (!hasProperZIndex(code, surroundingContent)) {
|
|
195
|
+
findings.push({
|
|
196
|
+
level: "warning",
|
|
197
|
+
message: `Floating element with ${match[0]} may need z-index for proper stacking`,
|
|
198
|
+
file: relativePath,
|
|
199
|
+
startLine: line,
|
|
200
|
+
ruleId: "missing-zindex",
|
|
201
|
+
suggestion: `Add z-index: style={{ zIndex: "var(--z-floating-badge)" }}`,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Only block on critical errors (ring-offset + badge), not warnings
|
|
208
|
+
const criticalCount = findings.filter(f => f.ruleId === "ring-offset-badge").length;
|
|
209
|
+
return {
|
|
210
|
+
passed: criticalCount === 0,
|
|
211
|
+
findings,
|
|
212
|
+
duration: Date.now() - startTime,
|
|
213
|
+
metadata: {
|
|
214
|
+
floatingElementsFound,
|
|
215
|
+
criticalIssues: criticalCount,
|
|
216
|
+
advisoryIssues: findings.filter(f => f.level === "warning").length,
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
async function main() {
|
|
221
|
+
console.log(`\n${console_chars_1.emoji.ruler} FLOATING ELEMENT Z-INDEX CHECK`);
|
|
222
|
+
console.log((0, console_chars_1.createDivider)(65, "heavy"));
|
|
223
|
+
const result = await run();
|
|
224
|
+
const { floatingElementsFound, criticalIssues, advisoryIssues } = result.metadata || {};
|
|
225
|
+
console.log(`\n${console_chars_1.emoji.chart} Summary:`);
|
|
226
|
+
console.log(` Floating elements found: ${floatingElementsFound}`);
|
|
227
|
+
console.log(` Critical issues (ring-offset + badge): ${criticalIssues}`);
|
|
228
|
+
console.log(` Advisory issues (missing z-index): ${advisoryIssues}`);
|
|
229
|
+
if (result.passed && advisoryIssues === 0) {
|
|
230
|
+
console.log(`\n${console_chars_1.emoji.success} FLOATING ELEMENT Z-INDEX CHECK PASSED`);
|
|
231
|
+
console.log(`\nAll floating elements are properly structured.`);
|
|
232
|
+
process.exit(0);
|
|
233
|
+
}
|
|
234
|
+
// Display CRITICAL issues first
|
|
235
|
+
const critical = result.findings?.filter(f => f.ruleId === "ring-offset-badge") || [];
|
|
236
|
+
if (critical.length > 0) {
|
|
237
|
+
console.log(`\n${console_chars_1.emoji.error} CRITICAL: Floating badges inside ring-offset elements (${critical.length}):`);
|
|
238
|
+
console.log((0, console_chars_1.createDivider)(65, "heavy"));
|
|
239
|
+
console.log(`\n These will ALWAYS appear behind the ring, regardless of z-index!`);
|
|
240
|
+
console.log(` Fix: Move the badge OUTSIDE the ring-offset element as a sibling.\n`);
|
|
241
|
+
for (const issue of critical) {
|
|
242
|
+
console.log(`${console_chars_1.emoji.file} ${issue.file}:${issue.startLine}`);
|
|
243
|
+
console.log(` ${console_chars_1.emoji.warning} ${issue.message}\n`);
|
|
244
|
+
}
|
|
245
|
+
console.log(`${console_chars_1.emoji.info} Correct pattern:`);
|
|
246
|
+
console.log(` <Box className="relative">`);
|
|
247
|
+
console.log(` <Badge className="absolute -top-2" style={{ zIndex: "var(--z-floating-badge)" }} />`);
|
|
248
|
+
console.log(` <Card className="ring-offset-2">...</Card>`);
|
|
249
|
+
console.log(` </Box>`);
|
|
250
|
+
}
|
|
251
|
+
// Display advisory issues
|
|
252
|
+
const advisory = result.findings?.filter(f => f.level === "warning") || [];
|
|
253
|
+
if (advisory.length > 0) {
|
|
254
|
+
console.log(`\n${console_chars_1.emoji.warning} Advisory: Missing z-index on floating elements (${advisory.length}):`);
|
|
255
|
+
console.log((0, console_chars_1.createDivider)(65, "light"));
|
|
256
|
+
// Group by file
|
|
257
|
+
const byFile = new Map();
|
|
258
|
+
for (const issue of advisory) {
|
|
259
|
+
const existing = byFile.get(issue.file) || [];
|
|
260
|
+
existing.push(issue);
|
|
261
|
+
byFile.set(issue.file, existing);
|
|
262
|
+
}
|
|
263
|
+
for (const [file, fileIssues] of byFile) {
|
|
264
|
+
console.log(`\n${console_chars_1.emoji.file} ${file}`);
|
|
265
|
+
for (const issue of fileIssues) {
|
|
266
|
+
console.log(` Line ${issue.startLine}: ${issue.message}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
console.log(`\n${console_chars_1.emoji.info} Recommended fix:`);
|
|
270
|
+
console.log(` Add z-index for floating badges/elements that appear outside parent bounds:`);
|
|
271
|
+
console.log(` style={{ zIndex: "var(--z-floating-badge)" }}`);
|
|
272
|
+
}
|
|
273
|
+
console.log(`\n Z-index tokens available:`);
|
|
274
|
+
console.log(` - --z-content-overlay: 10 (within component)`);
|
|
275
|
+
console.log(` - --z-content-controls: 20 (controls above content)`);
|
|
276
|
+
console.log(` - --z-floating-badge: 30 (badges outside parent bounds)`);
|
|
277
|
+
if (!result.passed) {
|
|
278
|
+
console.log(`\n${console_chars_1.emoji.error} FLOATING ELEMENT Z-INDEX CHECK FAILED`);
|
|
279
|
+
console.log(` ${criticalIssues} critical issue(s) must be fixed.`);
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
console.log(`\n${console_chars_1.emoji.warning} FLOATING ELEMENT Z-INDEX CHECK COMPLETED WITH WARNINGS`);
|
|
283
|
+
console.log(` Review the advisory issues - some may be intentional.`);
|
|
284
|
+
process.exit(0);
|
|
285
|
+
}
|
|
286
|
+
if (require.main === module) {
|
|
287
|
+
main().catch((err) => {
|
|
288
|
+
console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
|
|
289
|
+
process.exit(1);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=floating-element-zindex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-element-zindex.js","sourceRoot":"","sources":["../../../src/checks/ui/floating-element-zindex.ts"],"names":[],"mappings":"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"}
|