@empline/preflight 1.1.52 → 1.1.55

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.
Files changed (24) hide show
  1. package/dist/checks/data-integrity/internal-link-validation.d.ts +10 -0
  2. package/dist/checks/data-integrity/internal-link-validation.d.ts.map +1 -0
  3. package/dist/checks/data-integrity/internal-link-validation.js +279 -0
  4. package/dist/checks/data-integrity/internal-link-validation.js.map +1 -0
  5. package/dist/checks/data-integrity/scan-billing-enforcement.d.ts +10 -0
  6. package/dist/checks/data-integrity/scan-billing-enforcement.d.ts.map +1 -0
  7. package/dist/checks/data-integrity/scan-billing-enforcement.js +596 -0
  8. package/dist/checks/data-integrity/scan-billing-enforcement.js.map +1 -0
  9. package/dist/checks/performance/barrel-import-detection.d.ts +10 -0
  10. package/dist/checks/performance/barrel-import-detection.d.ts.map +1 -0
  11. package/dist/checks/performance/barrel-import-detection.js +251 -0
  12. package/dist/checks/performance/barrel-import-detection.js.map +1 -0
  13. package/dist/checks/react/vercel-react-best-practices.d.ts.map +1 -1
  14. package/dist/checks/react/vercel-react-best-practices.js +56 -1
  15. package/dist/checks/react/vercel-react-best-practices.js.map +1 -1
  16. package/dist/checks/store/team-member-access-consistency.d.ts +10 -0
  17. package/dist/checks/store/team-member-access-consistency.d.ts.map +1 -0
  18. package/dist/checks/store/team-member-access-consistency.js +199 -0
  19. package/dist/checks/store/team-member-access-consistency.js.map +1 -0
  20. package/dist/checks/ui/missing-page-layout.d.ts +10 -0
  21. package/dist/checks/ui/missing-page-layout.d.ts.map +1 -0
  22. package/dist/checks/ui/missing-page-layout.js +350 -0
  23. package/dist/checks/ui/missing-page-layout.js.map +1 -0
  24. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { PreflightCheckResult } from "../../core/types";
3
+ export declare const id = "data-integrity/internal-link-validation";
4
+ export declare const name = "Internal Link Validation";
5
+ export declare const description = "Detects UI references to internal pages that don't exist";
6
+ export declare const category = "data-integrity";
7
+ export declare const blocking = true;
8
+ export declare const tags: string[];
9
+ export declare function run(): Promise<PreflightCheckResult>;
10
+ //# sourceMappingURL=internal-link-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-link-validation.d.ts","sourceRoot":"","sources":["../../../src/checks/data-integrity/internal-link-validation.ts"],"names":[],"mappings":";AAUA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,4CAA4C,CAAC;AAC5D,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,6DAA6D,CAAC;AACtF,eAAO,MAAM,QAAQ,mBAAmB,CAAC;AACzC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAA8E,CAAC;AAiFhG,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAgIzD"}
@@ -0,0 +1,279 @@
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
+ * Internal Link Validation Preflight (BLOCKING)
41
+ *
42
+ * Detects when UI code references internal pages/routes that don't exist.
43
+ * Catches broken router.push(), Link href, and redirect() calls.
44
+ */
45
+ const fs = __importStar(require("node:fs"));
46
+ const path = __importStar(require("node:path"));
47
+ const glob_1 = require("glob");
48
+ const console_chars_1 = require("../../utils/console-chars");
49
+ exports.id = "data-integrity/internal-link-validation";
50
+ exports.name = "Internal Link Validation";
51
+ exports.description = "Detects UI references to internal pages that don't exist";
52
+ exports.category = "data-integrity";
53
+ exports.blocking = true;
54
+ exports.tags = ["links", "routes", "integrity", "dead-code", "broken-links", "navigation"];
55
+ // Patterns to detect internal link references
56
+ const LINK_PATTERNS = [
57
+ // router.push("/path")
58
+ /router\.push\s*\(\s*["'`]([/][^"'`\s$][^"'`]*)/g,
59
+ // router.replace("/path")
60
+ /router\.replace\s*\(\s*["'`]([/][^"'`\s$][^"'`]*)/g,
61
+ // redirect("/path")
62
+ /redirect\s*\(\s*["'`]([/][^"'`\s$][^"'`]*)/g,
63
+ // permanentRedirect("/path")
64
+ /permanentRedirect\s*\(\s*["'`]([/][^"'`\s$][^"'`]*)/g,
65
+ // Link href="/path"
66
+ /<Link[^>]*href\s*=\s*["'`]([/][^"'`\s$][^"'`]*)/g,
67
+ // href="/path" (general)
68
+ /href\s*=\s*["'`]([/][^"'`\s$][^"'`]*)/g,
69
+ ];
70
+ // Paths to ignore (external, special, or dynamic)
71
+ const IGNORED_PATH_PREFIXES = [
72
+ "/api/", // API routes are checked by api-route-reference-validation
73
+ "/#", // Hash links
74
+ "/auth/", // Auth callback paths handled by NextAuth
75
+ ];
76
+ // Special paths that don't have corresponding page files
77
+ const SPECIAL_PATHS = [
78
+ "/login", // May redirect or be handled specially
79
+ "/logout",
80
+ "/signin",
81
+ "/signout",
82
+ "/register",
83
+ "/signup",
84
+ ];
85
+ function normalizePath(linkPath) {
86
+ // Remove query params and hash
87
+ let normalized = linkPath.split("?")[0].split("#")[0];
88
+ // Remove trailing slash (except for root)
89
+ if (normalized.length > 1 && normalized.endsWith("/")) {
90
+ normalized = normalized.slice(0, -1);
91
+ }
92
+ // Replace template literals with param placeholder
93
+ normalized = normalized.replace(/\$\{[^}]+\}/g, "[param]");
94
+ return normalized;
95
+ }
96
+ function routeFromPageFile(pageFile) {
97
+ const normalized = pageFile.replace(/\\/g, "/");
98
+ // Remove app/ prefix and /page.{tsx,ts,js} suffix
99
+ let route = normalized
100
+ .replace(/^app\//, "/")
101
+ .replace(/\/page\.(tsx|ts|js)$/, "");
102
+ // Handle route groups - remove (groupName) segments
103
+ route = route.replace(/\/\([^)]+\)/g, "");
104
+ // Handle root page
105
+ if (route === "" || route === "/") {
106
+ return "/";
107
+ }
108
+ return route;
109
+ }
110
+ function routeToRegex(routePath) {
111
+ const catchallToken = "__CATCHALL__";
112
+ const paramToken = "__PARAM__";
113
+ let pattern = routePath
114
+ .replace(/\[\.\.\.[^\]]+\]/g, catchallToken)
115
+ .replace(/\[[^\]]+\]/g, paramToken);
116
+ pattern = pattern.replace(/[.*+?^${}()|\\]/g, "\\$&");
117
+ pattern = pattern.replace(new RegExp(catchallToken, "g"), ".+");
118
+ pattern = pattern.replace(new RegExp(paramToken, "g"), "[^/]+");
119
+ return new RegExp(`^${pattern}$`);
120
+ }
121
+ async function run() {
122
+ const startTime = Date.now();
123
+ const findings = [];
124
+ const linkReferences = [];
125
+ // Scan for all page files to build existing routes
126
+ const pageFiles = await (0, glob_1.glob)("app/**/page.{tsx,ts,js}", { cwd: process.cwd() });
127
+ const existingRoutes = [];
128
+ for (const pageFile of pageFiles) {
129
+ const route = routeFromPageFile(pageFile);
130
+ existingRoutes.push(route);
131
+ }
132
+ // Scan UI code for internal links
133
+ const uiFiles = await (0, glob_1.glob)([
134
+ "app/**/*.tsx",
135
+ "app/**/*.ts",
136
+ "components/**/*.tsx",
137
+ "components/**/*.ts",
138
+ "lib/**/*.ts",
139
+ "hooks/**/*.ts",
140
+ ], {
141
+ cwd: process.cwd(),
142
+ ignore: ["**/*.d.ts", "**/node_modules/**"],
143
+ });
144
+ for (const uiFile of uiFiles) {
145
+ const filePath = path.join(process.cwd(), uiFile);
146
+ if (!fs.existsSync(filePath))
147
+ continue;
148
+ const content = fs.readFileSync(filePath, "utf-8");
149
+ const lines = content.split("\n");
150
+ for (const pattern of LINK_PATTERNS) {
151
+ pattern.lastIndex = 0;
152
+ let match;
153
+ while ((match = pattern.exec(content)) !== null) {
154
+ const link = match[1];
155
+ const lineNum = content.substring(0, match.index).split("\n").length;
156
+ const lineContent = lines[lineNum - 1]?.trim() || "";
157
+ // Skip ignored prefixes
158
+ if (IGNORED_PATH_PREFIXES.some((prefix) => link.startsWith(prefix))) {
159
+ continue;
160
+ }
161
+ // Skip external links
162
+ if (link.startsWith("http://") || link.startsWith("https://") || link.startsWith("//")) {
163
+ continue;
164
+ }
165
+ linkReferences.push({
166
+ file: uiFile,
167
+ line: lineNum,
168
+ link,
169
+ context: lineContent.slice(0, 100),
170
+ });
171
+ }
172
+ }
173
+ }
174
+ for (const ref of linkReferences) {
175
+ const normalizedLink = normalizePath(ref.link);
176
+ // Skip special paths
177
+ if (SPECIAL_PATHS.some((special) => normalizedLink === special || normalizedLink.startsWith(special + "/"))) {
178
+ continue;
179
+ }
180
+ // Skip dynamic segments that look like IDs (uuid, numeric, etc.)
181
+ const hasDynamicSegment = /\/[a-f0-9-]{8,}|\/\d+(?:\/|$)/.test(normalizedLink);
182
+ // Build a regex for the normalized link (treating any [param] as dynamic)
183
+ const linkRegex = routeToRegex(normalizedLink);
184
+ // Check if any existing route matches
185
+ const hasMatch = existingRoutes.some((existingRoute) => {
186
+ // Direct match
187
+ if (existingRoute === normalizedLink)
188
+ return true;
189
+ // Route has dynamic segments that could match our link
190
+ const routeRegex = routeToRegex(existingRoute);
191
+ if (routeRegex.test(normalizedLink))
192
+ return true;
193
+ // Link has param placeholders that could match the route
194
+ if (linkRegex.test(existingRoute))
195
+ return true;
196
+ return false;
197
+ });
198
+ // For links with dynamic segments, try matching parent routes
199
+ if (!hasMatch && hasDynamicSegment) {
200
+ // Remove the last segment if it looks like an ID and try again
201
+ const parentPath = normalizedLink.replace(/\/[a-f0-9-]{8,}$|\/\d+$/, "/[id]");
202
+ const parentRegex = routeToRegex(parentPath);
203
+ const hasParentMatch = existingRoutes.some((existingRoute) => {
204
+ return parentRegex.test(existingRoute) || routeToRegex(existingRoute).test(parentPath);
205
+ });
206
+ if (hasParentMatch) {
207
+ continue; // Skip this - it's probably a valid dynamic route
208
+ }
209
+ }
210
+ if (!hasMatch) {
211
+ findings.push({
212
+ level: "error",
213
+ message: `References internal page that doesn't exist: ${ref.link}`,
214
+ file: ref.file,
215
+ startLine: ref.line,
216
+ ruleId: "broken-internal-link",
217
+ suggestion: "Create the missing page or update the link to use the correct path",
218
+ });
219
+ }
220
+ }
221
+ return {
222
+ passed: findings.length === 0,
223
+ findings,
224
+ duration: Date.now() - startTime,
225
+ metadata: {
226
+ pageRoutesFound: existingRoutes.length,
227
+ internalLinksFound: linkReferences.length,
228
+ brokenLinks: findings.length,
229
+ },
230
+ };
231
+ }
232
+ async function main() {
233
+ console.log(`\n${console_chars_1.emoji.search} INTERNAL LINK VALIDATION`);
234
+ console.log((0, console_chars_1.createDivider)(65, "heavy"));
235
+ console.log(`\n${console_chars_1.emoji.file} Scanning page routes...`);
236
+ const result = await run();
237
+ const { pageRoutesFound, internalLinksFound, brokenLinks } = result.metadata || {};
238
+ console.log(`\n${console_chars_1.emoji.chart} Summary:`);
239
+ console.log(` Page routes found: ${pageRoutesFound}`);
240
+ console.log(` Internal links found: ${internalLinksFound}`);
241
+ console.log(` Broken links: ${brokenLinks}`);
242
+ if (result.passed) {
243
+ console.log(`\n${console_chars_1.emoji.success} INTERNAL LINK VALIDATION PASSED`);
244
+ console.log(`\nAll internal links point to existing pages.`);
245
+ process.exit(0);
246
+ }
247
+ // Group issues by link path
248
+ const issuesByLink = new Map();
249
+ for (const finding of result.findings) {
250
+ const link = finding.message.split(": ")[1] || finding.message;
251
+ const existing = issuesByLink.get(link) || [];
252
+ existing.push(finding);
253
+ issuesByLink.set(link, existing);
254
+ }
255
+ console.log(`\n${console_chars_1.emoji.error} Broken internal links:`);
256
+ for (const [link, linkIssues] of issuesByLink) {
257
+ console.log(`\n ${link}`);
258
+ console.log(` Referenced in ${linkIssues.length} place(s):`);
259
+ for (const issue of linkIssues.slice(0, 3)) {
260
+ console.log(` - ${issue.file}:${issue.startLine}`);
261
+ }
262
+ if (linkIssues.length > 3) {
263
+ console.log(` ... and ${linkIssues.length - 3} more`);
264
+ }
265
+ }
266
+ console.log(`\n${console_chars_1.emoji.info} To fix broken internal links:`);
267
+ console.log(` 1. Create the missing page at the expected path (app/[path]/page.tsx)`);
268
+ console.log(` 2. Or update the link to use the correct path`);
269
+ console.log(` 3. Or remove the dead code if the feature was removed`);
270
+ console.log(`\n${console_chars_1.emoji.error} INTERNAL LINK VALIDATION FAILED`);
271
+ process.exit(1);
272
+ }
273
+ if (require.main === module) {
274
+ main().catch((err) => {
275
+ console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
276
+ process.exit(1);
277
+ });
278
+ }
279
+ //# sourceMappingURL=internal-link-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-link-validation.js","sourceRoot":"","sources":["../../../src/checks/data-integrity/internal-link-validation.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 = "data-integrity/scan-billing-enforcement";
4
+ export declare const name = "Scan Billing Enforcement Validation";
5
+ export declare const description = "Ensures card recognition properly checks and tracks billing for AI scans";
6
+ export declare const category = "data-integrity";
7
+ export declare const blocking = true;
8
+ export declare const tags: string[];
9
+ export declare function run(): Promise<PreflightCheckResult>;
10
+ //# sourceMappingURL=scan-billing-enforcement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-billing-enforcement.d.ts","sourceRoot":"","sources":["../../../src/checks/data-integrity/scan-billing-enforcement.ts"],"names":[],"mappings":";AAkBA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,4CAA4C,CAAC;AAC5D,eAAO,MAAM,IAAI,wCAAwC,CAAC;AAC1D,eAAO,MAAM,WAAW,6EAA6E,CAAC;AACtG,eAAO,MAAM,QAAQ,mBAAmB,CAAC;AACzC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAuE,CAAC;AAohBzF,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkCzD"}