@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.
- package/dist/checks/data-integrity/internal-link-validation.d.ts +10 -0
- package/dist/checks/data-integrity/internal-link-validation.d.ts.map +1 -0
- package/dist/checks/data-integrity/internal-link-validation.js +279 -0
- package/dist/checks/data-integrity/internal-link-validation.js.map +1 -0
- package/dist/checks/data-integrity/scan-billing-enforcement.d.ts +10 -0
- package/dist/checks/data-integrity/scan-billing-enforcement.d.ts.map +1 -0
- package/dist/checks/data-integrity/scan-billing-enforcement.js +596 -0
- package/dist/checks/data-integrity/scan-billing-enforcement.js.map +1 -0
- package/dist/checks/performance/barrel-import-detection.d.ts +10 -0
- package/dist/checks/performance/barrel-import-detection.d.ts.map +1 -0
- package/dist/checks/performance/barrel-import-detection.js +251 -0
- package/dist/checks/performance/barrel-import-detection.js.map +1 -0
- package/dist/checks/react/vercel-react-best-practices.d.ts.map +1 -1
- package/dist/checks/react/vercel-react-best-practices.js +56 -1
- package/dist/checks/react/vercel-react-best-practices.js.map +1 -1
- package/dist/checks/store/team-member-access-consistency.d.ts +10 -0
- package/dist/checks/store/team-member-access-consistency.d.ts.map +1 -0
- package/dist/checks/store/team-member-access-consistency.js +199 -0
- package/dist/checks/store/team-member-access-consistency.js.map +1 -0
- package/dist/checks/ui/missing-page-layout.d.ts +10 -0
- package/dist/checks/ui/missing-page-layout.d.ts.map +1 -0
- package/dist/checks/ui/missing-page-layout.js +350 -0
- package/dist/checks/ui/missing-page-layout.js.map +1 -0
- 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmGA,kBAgIC;AAlOD;;;;;GAKG;AACH,4CAA8B;AAC9B,gDAAkC;AAClC,+BAA4B;AAE5B,6DAAiE;AAEpD,QAAA,EAAE,GAAG,yCAAyC,CAAC;AAC/C,QAAA,IAAI,GAAG,0BAA0B,CAAC;AAClC,QAAA,WAAW,GAAG,0DAA0D,CAAC;AACzE,QAAA,QAAQ,GAAG,gBAAgB,CAAC;AAC5B,QAAA,QAAQ,GAAG,IAAI,CAAC;AAChB,QAAA,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;AAEhG,8CAA8C;AAC9C,MAAM,aAAa,GAAG;IACpB,uBAAuB;IACvB,iDAAiD;IACjD,0BAA0B;IAC1B,oDAAoD;IACpD,oBAAoB;IACpB,6CAA6C;IAC7C,6BAA6B;IAC7B,sDAAsD;IACtD,oBAAoB;IACpB,kDAAkD;IAClD,yBAAyB;IACzB,wCAAwC;CACzC,CAAC;AAEF,kDAAkD;AAClD,MAAM,qBAAqB,GAAG;IAC5B,OAAO,EAAE,2DAA2D;IACpE,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,0CAA0C;CACrD,CAAC;AAEF,yDAAyD;AACzD,MAAM,aAAa,GAAG;IACpB,QAAQ,EAAE,uCAAuC;IACjD,SAAS;IACT,SAAS;IACT,UAAU;IACV,WAAW;IACX,SAAS;CACV,CAAC;AAEF,SAAS,aAAa,CAAC,QAAgB;IACrC,+BAA+B;IAC/B,IAAI,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,0CAA0C;IAC1C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtD,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,mDAAmD;IACnD,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC3D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEhD,kDAAkD;IAClD,IAAI,KAAK,GAAG,UAAU;SACnB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAEvC,oDAAoD;IACpD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAE1C,mBAAmB;IACnB,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,SAAiB;IACrC,MAAM,aAAa,GAAG,cAAc,CAAC;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC;IAE/B,IAAI,OAAO,GAAG,SAAS;SACpB,OAAO,CAAC,mBAAmB,EAAE,aAAa,CAAC;SAC3C,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAEtC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;IACtD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAChE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAEhE,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;AACpC,CAAC;AAEM,KAAK,UAAU,GAAG;IACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,cAAc,GAAyE,EAAE,CAAC;IAEhG,mDAAmD;IACnD,MAAM,SAAS,GAAG,MAAM,IAAA,WAAI,EAAC,yBAAyB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC1C,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,kCAAkC;IAClC,MAAM,OAAO,GAAG,MAAM,IAAA,WAAI,EAAC;QACzB,cAAc;QACd,aAAa;QACb,qBAAqB;QACrB,oBAAoB;QACpB,aAAa;QACb,eAAe;KAChB,EAAE;QACD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,EAAE,CAAC,WAAW,EAAE,oBAAoB,CAAC;KAC5C,CAAC,CAAC;IAEH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;YACtB,IAAI,KAA6B,CAAC;YAElC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;gBACrE,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAErD,wBAAwB;gBACxB,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;oBACpE,SAAS;gBACX,CAAC;gBAED,sBAAsB;gBACtB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvF,SAAS;gBACX,CAAC;gBAED,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,OAAO;oBACb,IAAI;oBACJ,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE/C,qBAAqB;QACrB,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,KAAK,OAAO,IAAI,cAAc,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5G,SAAS;QACX,CAAC;QAED,iEAAiE;QACjE,MAAM,iBAAiB,GAAG,+BAA+B,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE/E,0EAA0E;QAC1E,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;QAE/C,sCAAsC;QACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE;YACrD,eAAe;YACf,IAAI,aAAa,KAAK,cAAc;gBAAE,OAAO,IAAI,CAAC;YAElD,uDAAuD;YACvD,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;YAC/C,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEjD,yDAAyD;YACzD,IAAI,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAC;YAE/C,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,IAAI,CAAC,QAAQ,IAAI,iBAAiB,EAAE,CAAC;YACnC,+DAA+D;YAC/D,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;YAE7C,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE;gBAC3D,OAAO,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzF,CAAC,CAAC,CAAC;YAEH,IAAI,cAAc,EAAE,CAAC;gBACnB,SAAS,CAAC,kDAAkD;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,gDAAgD,GAAG,CAAC,IAAI,EAAE;gBACnE,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,SAAS,EAAE,GAAG,CAAC,IAAI;gBACnB,MAAM,EAAE,sBAAsB;gBAC9B,UAAU,EAAE,oEAAoE;aACjF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC7B,QAAQ;QACR,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAChC,QAAQ,EAAE;YACR,eAAe,EAAE,cAAc,CAAC,MAAM;YACtC,kBAAkB,EAAE,cAAc,CAAC,MAAM;YACzC,WAAW,EAAE,QAAQ,CAAC,MAAM;SAC7B;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,MAAM,2BAA2B,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,IAAA,6BAAa,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,IAAI,0BAA0B,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAC3B,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEnF,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,WAAW,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,yBAAyB,eAAe,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,4BAA4B,kBAAkB,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;IAE/C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,4BAA4B;IAC5B,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAC;IAC3D,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC;QAC/D,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,yBAAyB,CAAC,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,YAAY,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,CAAC,MAAM,YAAY,CAAC,CAAC;QAC/D,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,IAAI,gCAAgC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,KAAK,qBAAK,CAAC,KAAK,kCAAkC,CAAC,CAAC;IAEhE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,qBAAK,CAAC,KAAK,oBAAoB,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -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"}
|