@mr.dj2u/doctor 0.1.6 → 0.1.8

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 (71) hide show
  1. package/dist/checks/animation-performance.d.ts.map +1 -1
  2. package/dist/checks/animation-performance.js +3 -0
  3. package/dist/checks/animation-performance.js.map +1 -1
  4. package/dist/checks/api-safety.d.ts +17 -0
  5. package/dist/checks/api-safety.d.ts.map +1 -0
  6. package/dist/checks/api-safety.js +282 -0
  7. package/dist/checks/api-safety.js.map +1 -0
  8. package/dist/checks/app-architecture.d.ts +3 -3
  9. package/dist/checks/app-architecture.d.ts.map +1 -1
  10. package/dist/checks/app-architecture.js +14 -11
  11. package/dist/checks/app-architecture.js.map +1 -1
  12. package/dist/checks/env-hygiene.d.ts +17 -0
  13. package/dist/checks/env-hygiene.d.ts.map +1 -1
  14. package/dist/checks/env-hygiene.js +376 -32
  15. package/dist/checks/env-hygiene.js.map +1 -1
  16. package/dist/checks/expo-config.d.ts.map +1 -1
  17. package/dist/checks/expo-config.js +4 -7
  18. package/dist/checks/expo-config.js.map +1 -1
  19. package/dist/checks/expo-doctor.d.ts.map +1 -1
  20. package/dist/checks/expo-doctor.js +6 -2
  21. package/dist/checks/expo-doctor.js.map +1 -1
  22. package/dist/checks/index.d.ts +4 -0
  23. package/dist/checks/index.d.ts.map +1 -1
  24. package/dist/checks/index.js +4 -0
  25. package/dist/checks/index.js.map +1 -1
  26. package/dist/checks/react-doctor.d.ts +28 -0
  27. package/dist/checks/react-doctor.d.ts.map +1 -0
  28. package/dist/checks/react-doctor.js +360 -0
  29. package/dist/checks/react-doctor.js.map +1 -0
  30. package/dist/checks/router-safety.d.ts +13 -0
  31. package/dist/checks/router-safety.d.ts.map +1 -0
  32. package/dist/checks/router-safety.js +360 -0
  33. package/dist/checks/router-safety.js.map +1 -0
  34. package/dist/checks/runtime-security.d.ts +17 -0
  35. package/dist/checks/runtime-security.d.ts.map +1 -0
  36. package/dist/checks/runtime-security.js +583 -0
  37. package/dist/checks/runtime-security.js.map +1 -0
  38. package/dist/checks/script-checks.d.ts +2 -0
  39. package/dist/checks/script-checks.d.ts.map +1 -1
  40. package/dist/checks/script-checks.js +33 -9
  41. package/dist/checks/script-checks.js.map +1 -1
  42. package/dist/cli-main.d.ts +1 -0
  43. package/dist/cli-main.d.ts.map +1 -1
  44. package/dist/cli-main.js +28 -1
  45. package/dist/cli-main.js.map +1 -1
  46. package/dist/expo-router.d.ts +15 -0
  47. package/dist/expo-router.d.ts.map +1 -0
  48. package/dist/expo-router.js +76 -0
  49. package/dist/expo-router.js.map +1 -0
  50. package/dist/index.d.ts +2 -1
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +22 -15
  53. package/dist/index.js.map +1 -1
  54. package/dist/modes.d.ts +8 -0
  55. package/dist/modes.d.ts.map +1 -0
  56. package/dist/modes.js +71 -0
  57. package/dist/modes.js.map +1 -0
  58. package/dist/reporter.d.ts +1 -1
  59. package/dist/reporter.d.ts.map +1 -1
  60. package/dist/reporter.js +73 -3
  61. package/dist/reporter.js.map +1 -1
  62. package/dist/scan-file.d.ts.map +1 -1
  63. package/dist/scan-file.js +9 -5
  64. package/dist/scan-file.js.map +1 -1
  65. package/dist/types.d.ts +33 -0
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/utils.d.ts +11 -0
  68. package/dist/utils.d.ts.map +1 -1
  69. package/dist/utils.js +124 -2
  70. package/dist/utils.js.map +1 -1
  71. package/package.json +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"animation-performance.d.ts","sourceRoot":"","sources":["../../src/checks/animation-performance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2C/F;AAED,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAuB5B"}
1
+ {"version":3,"file":"animation-performance.d.ts","sourceRoot":"","sources":["../../src/checks/animation-performance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8C/F;AAED,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAuB5B"}
@@ -14,6 +14,9 @@ export async function checkAnimationPerformance(projectPath) {
14
14
  const findings = [];
15
15
  let scannedAnimatedFiles = 0;
16
16
  for (const filePath of sourceFiles) {
17
+ if (findings.length >= 50) {
18
+ break;
19
+ }
17
20
  const contents = await readOptionalText(filePath);
18
21
  if (!contents || !ANIMATION_SIGNAL_RE.test(contents)) {
19
22
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"animation-performance.js","sourceRoot":"","sources":["../../src/checks/animation-performance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"animation-performance.js","sourceRoot":"","sources":["../../src/checks/animation-performance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DoctorCheckResult, PackageJson } from '../types.js';
2
+ export interface ApiSafetyFinding {
3
+ file: string;
4
+ kind: string;
5
+ message: string;
6
+ severity: 'warn' | 'error';
7
+ }
8
+ export declare function checkApiSafety(packageJson: PackageJson, projectPath: string): Promise<DoctorCheckResult>;
9
+ export declare function scanFileApiSafety(projectPath: string, filePath: string, packageJson?: PackageJson): Promise<DoctorCheckResult>;
10
+ export declare function checkAuthChecks(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
11
+ export declare function checkMethodValidation(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
12
+ export declare function checkInputValidation(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
13
+ export declare function checkServiceRole(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
14
+ export declare function checkRateLimiting(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
15
+ export declare function checkErrorExposure(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
16
+ export declare function checkCors(projectPath: string, filePath: string, contents: string): ApiSafetyFinding[];
17
+ //# sourceMappingURL=api-safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-safety.d.ts","sourceRoot":"","sources":["../../src/checks/api-safety.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4ClE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B;AAED,wBAAsB,cAAc,CAClC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CA4B5B;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAmB5B;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAkBpB;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CA6BpB;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAsBpB;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAkBpB;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAmBpB;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAkCpB;AAED,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CA6BpB"}
@@ -0,0 +1,282 @@
1
+ import path from 'node:path';
2
+ import { findExpoRouterApiRouteFiles, hasExpoRouterSignal, isExpoRouterApiRouteFile, isTestLikeFile, } from '../expo-router.js';
3
+ import { readOptionalText, relative, stripJsComments } from '../utils.js';
4
+ const MAX_FINDINGS = 50;
5
+ const NAMED_METHOD_RE = /\bexport\s+(async\s+)?function\s+(GET|POST|PUT|PATCH|DELETE|OPTIONS)\b|\bexport\s+const\s+(GET|POST|PUT|PATCH|DELETE|OPTIONS)\s*=/;
6
+ const DEFAULT_EXPORT_RE = /\bexport\s+default\b/;
7
+ const REQUEST_METHOD_RE = /\brequest\.method\b/;
8
+ const BODY_READ_RE = /\brequest\.(json|formData)\s*\(/;
9
+ const GET_EXPORT_RE = /\bexport\s+(async\s+)?function\s+GET\b|\bexport\s+const\s+GET\s*=/;
10
+ const WRITE_METHOD_EXPORT_RE = /\bexport\s+(async\s+)?function\s+(POST|PUT|PATCH|DELETE)\b|\bexport\s+const\s+(POST|PUT|PATCH|DELETE)\s*=/;
11
+ const VALIDATION_RE = /\b(z\.object|z\.string|z\.enum|\.safeParse\s*\(|\.parse\s*\(|parseBillingJson|handleDbWrite\s*\(|zod)\b/;
12
+ const AUTH_SIGNAL_RE = /\b(requireAuth|requireAuthUserId|requireBillingAuth|requireBillingAuthUserId|handleDbWrite|getSession|getUser|getClaims|request\.auth|createServerClient|Authorization|Bearer|requireHostedAccess)\b/;
13
+ const WEBHOOK_SIGNATURE_RE = /\b(stripe-signature|svix-signature|webhook-signature|x-hub-signature|x-signature)\b/i;
14
+ const SERVICE_ROLE_USE_RE = /\bprocess\.env\.[A-Z0-9_]*SERVICE_ROLE[A-Z0-9_]*\b|\bcreate(?:Client|SupabaseClient)\s*\([\s\S]{0,300}\b(SERVICE_ROLE|serviceRole|service_role)\b/;
15
+ const RATE_LIMIT_RE = /\b(rateLimit|rate-limit|ratelimit|quota|upstash)\b|\bstatus:\s*429\b/;
16
+ const STACK_JSON_RE = /\bstack\s*:\s*(error|err|e)\.stack\b/;
17
+ const STACK_VALUE_RE = /\b(error|err|e)\.stack\b/;
18
+ const STRINGIFY_ERROR_RE = /\bJSON\.stringify\s*\(\s*(error|err|e)\s*\)/;
19
+ const CORS_STAR_RE = /Access-Control-Allow-Origin['"`]\s*,\s*['"`]\s*\*/i;
20
+ const CORS_HEADER_RE = /Access-Control-Allow-Origin/i;
21
+ const ORIGIN_REFLECT_RE = /\b(origin|requestOrigin|allowedOrigin)\b/;
22
+ const CORS_ALLOWLIST_RE = /\b(ALLOWED_ORIGINS|allowedOrigins|allowedOrigin|normalizeOrigin)\b/;
23
+ const ARRAY_BUFFER_RE = /\brequest\.arrayBuffer\s*\(/;
24
+ const CATCH_ALL_RE = /\[\.\.\./;
25
+ const SENSITIVE_PATH_RE = /(auth|sign-in|sign-up|login|billing|payment|checkout|subscription|webhook|admin|account|credential|mercury-credentials|\/db\/)/i;
26
+ const RATE_LIMIT_PATH_RE = /(auth|sign-in|sign-up|login|billing|payment|checkout|subscription|webhook|credential|mercury-credentials)/i;
27
+ const PUBLIC_PATH_RE = /(public|health|content)/i;
28
+ export async function checkApiSafety(packageJson, projectPath) {
29
+ if (!hasExpoRouterSignal(packageJson)) {
30
+ return {
31
+ name: 'api safety',
32
+ status: 'skip',
33
+ message: 'No Expo Router API route files found.',
34
+ };
35
+ }
36
+ const apiFiles = await findExpoRouterApiRouteFiles(projectPath, packageJson);
37
+ if (apiFiles.length === 0) {
38
+ return {
39
+ name: 'api safety',
40
+ status: 'skip',
41
+ message: 'No Expo Router API route files found.',
42
+ };
43
+ }
44
+ const findings = [];
45
+ for (const filePath of apiFiles) {
46
+ if (isTestLikeFile(filePath)) {
47
+ continue;
48
+ }
49
+ const contents = (await readOptionalText(filePath)) ?? '';
50
+ findings.push(...scanApiFile(projectPath, filePath, contents));
51
+ }
52
+ return toApiResult(findings);
53
+ }
54
+ export async function scanFileApiSafety(projectPath, filePath, packageJson) {
55
+ if (!packageJson || !isExpoRouterApiRouteFile(projectPath, filePath, packageJson)) {
56
+ return {
57
+ name: 'api safety',
58
+ status: 'skip',
59
+ message: 'File is not an Expo Router API route.',
60
+ };
61
+ }
62
+ if (isTestLikeFile(filePath)) {
63
+ return {
64
+ name: 'api safety',
65
+ status: 'skip',
66
+ message: 'Test files are excluded from API safety checks.',
67
+ };
68
+ }
69
+ const contents = (await readOptionalText(filePath)) ?? '';
70
+ return toApiResult(scanApiFile(projectPath, filePath, contents), true);
71
+ }
72
+ export function checkAuthChecks(projectPath, filePath, contents) {
73
+ const classification = classifyApiFile(projectPath, filePath, contents);
74
+ if (!classification.sensitive || classification.webhook || classification.publicOrProxy) {
75
+ return [];
76
+ }
77
+ if (hasAuthSignal(contents)) {
78
+ return [];
79
+ }
80
+ const shortPath = relative(projectPath, filePath);
81
+ return [
82
+ {
83
+ file: shortPath,
84
+ kind: 'missing-auth',
85
+ severity: 'warn',
86
+ message: `${shortPath}: sensitive API route does not verify auth (request.auth, session helper, or handleDbWrite).`,
87
+ },
88
+ ];
89
+ }
90
+ export function checkMethodValidation(projectPath, filePath, contents) {
91
+ const scanned = stripJsComments(contents);
92
+ const shortPath = relative(projectPath, filePath);
93
+ const findings = [];
94
+ const hasNamedMethod = NAMED_METHOD_RE.test(scanned);
95
+ if (!hasNamedMethod && DEFAULT_EXPORT_RE.test(scanned) && !REQUEST_METHOD_RE.test(scanned)) {
96
+ findings.push({
97
+ file: shortPath,
98
+ kind: 'missing-method-guard',
99
+ severity: 'warn',
100
+ message: `${shortPath}: default API handler does not inspect request.method or export named HTTP methods.`,
101
+ });
102
+ }
103
+ if (GET_EXPORT_RE.test(scanned) &&
104
+ !WRITE_METHOD_EXPORT_RE.test(scanned) &&
105
+ BODY_READ_RE.test(scanned)) {
106
+ findings.push({
107
+ file: shortPath,
108
+ kind: 'get-reads-body',
109
+ severity: 'warn',
110
+ message: `${shortPath}: GET handler reads a request body; add a named POST/PUT/PATCH export or stop parsing JSON on GET.`,
111
+ });
112
+ }
113
+ return findings;
114
+ }
115
+ export function checkInputValidation(projectPath, filePath, contents) {
116
+ const classification = classifyApiFile(projectPath, filePath, contents);
117
+ const scanned = stripJsComments(contents);
118
+ if (!BODY_READ_RE.test(scanned)) {
119
+ return [];
120
+ }
121
+ if (classification.webhook || ARRAY_BUFFER_RE.test(scanned)) {
122
+ return [];
123
+ }
124
+ if (VALIDATION_RE.test(scanned)) {
125
+ return [];
126
+ }
127
+ const shortPath = relative(projectPath, filePath);
128
+ return [
129
+ {
130
+ file: shortPath,
131
+ kind: 'missing-validation',
132
+ severity: 'warn',
133
+ message: `${shortPath}: request body is read without a Zod/schema parse; validate input before business logic.`,
134
+ },
135
+ ];
136
+ }
137
+ export function checkServiceRole(projectPath, filePath, contents) {
138
+ const scanned = stripJsComments(contents);
139
+ if (!SERVICE_ROLE_USE_RE.test(scanned)) {
140
+ return [];
141
+ }
142
+ if (hasAuthSignal(contents)) {
143
+ return [];
144
+ }
145
+ const shortPath = relative(projectPath, filePath);
146
+ return [
147
+ {
148
+ file: shortPath,
149
+ kind: 'service-role-without-auth',
150
+ severity: 'warn',
151
+ message: `${shortPath}: uses a service-role token without an auth check; prefer the user/anon client or gate the privileged client.`,
152
+ },
153
+ ];
154
+ }
155
+ export function checkRateLimiting(projectPath, filePath, contents) {
156
+ const classification = classifyApiFile(projectPath, filePath, contents);
157
+ if (!classification.rateLimitSensitive) {
158
+ return [];
159
+ }
160
+ const scanned = stripJsComments(contents);
161
+ if (RATE_LIMIT_RE.test(scanned)) {
162
+ return [];
163
+ }
164
+ const shortPath = relative(projectPath, filePath);
165
+ return [
166
+ {
167
+ file: shortPath,
168
+ kind: 'missing-rate-limit',
169
+ severity: 'warn',
170
+ message: `${shortPath}: sensitive endpoint has no rate-limit or quota signal (rateLimit, 429, quota).`,
171
+ },
172
+ ];
173
+ }
174
+ export function checkErrorExposure(projectPath, filePath, contents) {
175
+ const scanned = stripJsComments(contents);
176
+ const shortPath = relative(projectPath, filePath);
177
+ const findings = [];
178
+ if (STACK_JSON_RE.test(scanned)) {
179
+ findings.push({
180
+ file: shortPath,
181
+ kind: 'stack-in-json',
182
+ severity: 'error',
183
+ message: `${shortPath}: returns error.stack in a JSON body; clients must not receive stack traces.`,
184
+ });
185
+ return findings;
186
+ }
187
+ if (STACK_VALUE_RE.test(scanned)) {
188
+ findings.push({
189
+ file: shortPath,
190
+ kind: 'stack-exposure',
191
+ severity: 'warn',
192
+ message: `${shortPath}: interpolates error.stack into a response path; return a generic error instead.`,
193
+ });
194
+ }
195
+ if (STRINGIFY_ERROR_RE.test(scanned)) {
196
+ findings.push({
197
+ file: shortPath,
198
+ kind: 'stringify-error',
199
+ severity: 'warn',
200
+ message: `${shortPath}: JSON.stringify(error) may leak internals; return a safe error envelope.`,
201
+ });
202
+ }
203
+ return findings;
204
+ }
205
+ export function checkCors(projectPath, filePath, contents) {
206
+ const scanned = stripJsComments(contents);
207
+ const shortPath = relative(projectPath, filePath);
208
+ const findings = [];
209
+ if (CORS_STAR_RE.test(scanned) || /Access-Control-Allow-Origin['":\s]*\*/.test(scanned)) {
210
+ findings.push({
211
+ file: shortPath,
212
+ kind: 'cors-wildcard',
213
+ severity: 'warn',
214
+ message: `${shortPath}: Access-Control-Allow-Origin is '*'; restrict CORS to an explicit origin allowlist.`,
215
+ });
216
+ return findings;
217
+ }
218
+ if (CORS_HEADER_RE.test(scanned) &&
219
+ ORIGIN_REFLECT_RE.test(scanned) &&
220
+ !CORS_ALLOWLIST_RE.test(scanned)) {
221
+ findings.push({
222
+ file: shortPath,
223
+ kind: 'cors-reflect',
224
+ severity: 'warn',
225
+ message: `${shortPath}: reflects request Origin without an allowlist; validate origin before echoing it.`,
226
+ });
227
+ }
228
+ return findings;
229
+ }
230
+ function scanApiFile(projectPath, filePath, contents) {
231
+ return [
232
+ ...checkAuthChecks(projectPath, filePath, contents),
233
+ ...checkMethodValidation(projectPath, filePath, contents),
234
+ ...checkInputValidation(projectPath, filePath, contents),
235
+ ...checkServiceRole(projectPath, filePath, contents),
236
+ ...checkRateLimiting(projectPath, filePath, contents),
237
+ ...checkErrorExposure(projectPath, filePath, contents),
238
+ ...checkCors(projectPath, filePath, contents),
239
+ ];
240
+ }
241
+ function classifyApiFile(projectPath, filePath, contents) {
242
+ const shortPath = relative(projectPath, filePath);
243
+ const scanned = stripJsComments(contents);
244
+ const webhook = /webhook/i.test(shortPath) || WEBHOOK_SIGNATURE_RE.test(scanned);
245
+ const publicOrProxy = PUBLIC_PATH_RE.test(shortPath) ||
246
+ (CATCH_ALL_RE.test(path.basename(filePath)) && CORS_ALLOWLIST_RE.test(scanned));
247
+ const sensitive = SENSITIVE_PATH_RE.test(shortPath);
248
+ const rateLimitSensitive = RATE_LIMIT_PATH_RE.test(shortPath);
249
+ return { sensitive, rateLimitSensitive, webhook, publicOrProxy };
250
+ }
251
+ function hasAuthSignal(contents) {
252
+ const scanned = stripJsComments(contents);
253
+ return AUTH_SIGNAL_RE.test(scanned) || WEBHOOK_SIGNATURE_RE.test(scanned);
254
+ }
255
+ function toApiResult(findings, fileScan = false) {
256
+ if (findings.length === 0) {
257
+ return {
258
+ name: 'api safety',
259
+ status: 'pass',
260
+ message: fileScan
261
+ ? 'File passed the API safety scan.'
262
+ : 'API routes passed auth, validation, method, and exposure checks.',
263
+ };
264
+ }
265
+ const hasError = findings.some((finding) => finding.severity === 'error');
266
+ return {
267
+ name: 'api safety',
268
+ status: hasError ? 'error' : 'warn',
269
+ message: hasError
270
+ ? fileScan
271
+ ? 'File leaks internals in an API error response.'
272
+ : 'API routes leak internals in error responses.'
273
+ : fileScan
274
+ ? 'File has API safety warnings.'
275
+ : 'API routes have auth, validation, method, or exposure warnings.',
276
+ details: {
277
+ findings: findings.slice(0, MAX_FINDINGS),
278
+ truncated: findings.length > MAX_FINDINGS,
279
+ },
280
+ };
281
+ }
282
+ //# sourceMappingURL=api-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-safety.js","sourceRoot":"","sources":["../../src/checks/api-safety.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,eAAe,GACnB,mIAAmI,CAAC;AACtI,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACjD,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAChD,MAAM,YAAY,GAAG,iCAAiC,CAAC;AACvD,MAAM,aAAa,GAAG,mEAAmE,CAAC;AAC1F,MAAM,sBAAsB,GAC1B,2GAA2G,CAAC;AAC9G,MAAM,aAAa,GACjB,yGAAyG,CAAC;AAC5G,MAAM,cAAc,GAClB,sMAAsM,CAAC;AACzM,MAAM,oBAAoB,GACxB,sFAAsF,CAAC;AACzF,MAAM,mBAAmB,GACvB,mJAAmJ,CAAC;AACtJ,MAAM,aAAa,GAAG,sEAAsE,CAAC;AAC7F,MAAM,aAAa,GAAG,sCAAsC,CAAC;AAC7D,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAClD,MAAM,kBAAkB,GAAG,6CAA6C,CAAC;AACzE,MAAM,YAAY,GAAG,oDAAoD,CAAC;AAC1E,MAAM,cAAc,GAAG,8BAA8B,CAAC;AACtD,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AACrE,MAAM,iBAAiB,GAAG,oEAAoE,CAAC;AAC/F,MAAM,eAAe,GAAG,6BAA6B,CAAC;AACtD,MAAM,YAAY,GAAG,UAAU,CAAC;AAEhC,MAAM,iBAAiB,GACrB,iIAAiI,CAAC;AACpI,MAAM,kBAAkB,GACtB,4GAA4G,CAAC;AAC/G,MAAM,cAAc,GAAG,0BAA0B,CAAC;AASlD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAwB,EACxB,WAAmB;IAEnB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,uCAAuC;SACjD,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,uCAAuC;SACjD,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,QAAQ,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,QAAgB,EAChB,WAAyB;IAEzB,IAAI,CAAC,WAAW,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;QAClF,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,uCAAuC;SACjD,CAAC;IACJ,CAAC;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,iDAAiD;SAC3D,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,OAAO,WAAW,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,cAAc,GAAG,eAAe,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxE,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;QACxF,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,OAAO;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,8FAA8F;SACpH;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,cAAc,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3F,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,qFAAqF;SAC3G,CAAC,CAAC;IACL,CAAC;IAED,IACE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAC3B,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC;QACrC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAC1B,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,oGAAoG;SAC1H,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,cAAc,GAAG,eAAe,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,cAAc,CAAC,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,OAAO;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,0FAA0F;SAChH;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,OAAO;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,2BAA2B;YACjC,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,+GAA+G;SACrI;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,cAAc,GAAG,eAAe,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxE,IAAI,CAAC,cAAc,CAAC,kBAAkB,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,OAAO;QACL;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,iFAAiF;SACvG;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,GAAG,SAAS,8EAA8E;SACpG,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,kFAAkF;SACxG,CAAC,CAAC;IACL,CAAC;IAED,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,2EAA2E;SACjG,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,uCAAuC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxF,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,sFAAsF;SAC5G,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IACE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QAC5B,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;QAC/B,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAChC,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,oFAAoF;SAC1G,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,WAAmB,EAAE,QAAgB,EAAE,QAAgB;IAC1E,OAAO;QACL,GAAG,eAAe,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACnD,GAAG,qBAAqB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACzD,GAAG,oBAAoB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACxD,GAAG,gBAAgB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACpD,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACrD,GAAG,kBAAkB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACtD,GAAG,SAAS,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,WAAmB,EACnB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjF,MAAM,aAAa,GACjB,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;QAC9B,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAClF,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9D,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,WAAW,CAAC,QAA4B,EAAE,QAAQ,GAAG,KAAK;IACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,QAAQ;gBACf,CAAC,CAAC,kCAAkC;gBACpC,CAAC,CAAC,kEAAkE;SACvE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC1E,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;QACnC,OAAO,EAAE,QAAQ;YACf,CAAC,CAAC,QAAQ;gBACR,CAAC,CAAC,gDAAgD;gBAClD,CAAC,CAAC,+CAA+C;YACnD,CAAC,CAAC,QAAQ;gBACR,CAAC,CAAC,+BAA+B;gBACjC,CAAC,CAAC,iEAAiE;QACvE,OAAO,EAAE;YACP,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;YACzC,SAAS,EAAE,QAAQ,CAAC,MAAM,GAAG,YAAY;SAC1C;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { DoctorCheckResult } from '../types.js';
2
- export declare function checkAppArchitecture(projectPath: string): Promise<DoctorCheckResult>;
3
- export declare function scanFileAppArchitecture(projectPath: string, filePath: string): Promise<DoctorCheckResult>;
1
+ import type { DoctorCheckResult, PackageJson } from '../types.js';
2
+ export declare function checkAppArchitecture(packageJson: PackageJson, projectPath: string): Promise<DoctorCheckResult>;
3
+ export declare function scanFileAppArchitecture(projectPath: string, filePath: string, packageJson?: PackageJson): Promise<DoctorCheckResult>;
4
4
  //# sourceMappingURL=app-architecture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-architecture.d.ts","sourceRoot":"","sources":["../../src/checks/app-architecture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4C1F;AAED,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAc5B"}
1
+ {"version":3,"file":"app-architecture.d.ts","sourceRoot":"","sources":["../../src/checks/app-architecture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQlE,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAwC5B;AAED,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAsB5B"}
@@ -1,14 +1,9 @@
1
1
  import path from 'node:path';
2
+ import { findExpoRouterAppDirs, isExpoRouterApiRouteFile, } from '../expo-router.js';
2
3
  import { findSsrFindings } from './ssr-safety.js';
3
- import { findFiles, pathExists, readOptionalText, relative, SOURCE_EXTENSIONS } from '../utils.js';
4
- export async function checkAppArchitecture(projectPath) {
5
- const appDirs = [path.join(projectPath, 'app'), path.join(projectPath, 'src', 'app')];
6
- const existingAppDirs = [];
7
- for (const appDir of appDirs) {
8
- if (await pathExists(appDir)) {
9
- existingAppDirs.push(appDir);
10
- }
11
- }
4
+ import { findFiles, readOptionalText, relative, SOURCE_EXTENSIONS } from '../utils.js';
5
+ export async function checkAppArchitecture(packageJson, projectPath) {
6
+ const existingAppDirs = await findExpoRouterAppDirs(projectPath);
12
7
  if (existingAppDirs.length === 0) {
13
8
  return {
14
9
  name: 'app architecture',
@@ -20,7 +15,8 @@ export async function checkAppArchitecture(projectPath) {
20
15
  for (const appDir of existingAppDirs) {
21
16
  const routeFiles = await findFiles(appDir, (filePath) => {
22
17
  const extension = path.extname(filePath);
23
- return SOURCE_EXTENSIONS.has(extension) && !filePath.endsWith('+api.ts');
18
+ return (SOURCE_EXTENSIONS.has(extension) &&
19
+ !isExpoRouterApiRouteFile(projectPath, filePath, packageJson));
24
20
  });
25
21
  for (const filePath of routeFiles) {
26
22
  findings.push(...(await scanRouteFileArchitecture(projectPath, filePath)));
@@ -40,7 +36,14 @@ export async function checkAppArchitecture(projectPath) {
40
36
  message: 'Route files passed the first-pass architecture scan.',
41
37
  };
42
38
  }
43
- export async function scanFileAppArchitecture(projectPath, filePath) {
39
+ export async function scanFileAppArchitecture(projectPath, filePath, packageJson) {
40
+ if (packageJson && isExpoRouterApiRouteFile(projectPath, filePath, packageJson)) {
41
+ return {
42
+ name: 'app architecture',
43
+ status: 'skip',
44
+ message: 'Expo Router API route files are excluded from route-component architecture checks.',
45
+ };
46
+ }
44
47
  const findings = await scanRouteFileArchitecture(projectPath, filePath);
45
48
  return findings.length > 0
46
49
  ? {
@@ -1 +1 @@
1
- {"version":3,"file":"app-architecture.js","sourceRoot":"","sources":["../../src/checks/app-architecture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-architecture.js","sourceRoot":"","sources":["../../src/checks/app-architecture.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEvF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,WAAwB,EACxB,WAAmB;IAEnB,MAAM,eAAe,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAEjE,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,qCAAqC;SAC/C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACzC,OAAO,CACL,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;gBAChC,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAC9D,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,yBAAyB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,qDAAqD;YAC9D,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE;SAC9E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,sDAAsD;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,WAAmB,EACnB,QAAgB,EAChB,WAAyB;IAEzB,IAAI,WAAW,IAAI,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;QAChF,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,oFAAoF;SAC9F,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACxE,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC;QACxB,CAAC,CAAC;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,iCAAiC;YAC1C,OAAO,EAAE,EAAE,QAAQ,EAAE;SACtB;QACH,CAAC,CAAC;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,oCAAoC;SAC9C,CAAC;AACR,CAAC;AAED,KAAK,UAAU,yBAAyB,CAAC,WAAmB,EAAE,QAAgB;IAC5E,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACjD,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAElD,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,KAAK,SAAS,uDAAuD,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,4DAA4D,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChF,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,4DAA4D,CAAC,CAAC;IAC1F,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEnE,IAAI,oDAAoD,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;QAC3F,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,wDAAwD,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,4 +1,21 @@
1
1
  import type { DoctorCheckResult } from '../types.js';
2
+ export type EnvHygieneFindingKind = 'public-secret-name' | 'hardcoded-credential-value' | 'undocumented-public-env';
3
+ export interface EnvHygieneFinding {
4
+ file: string;
5
+ line: number;
6
+ kind: EnvHygieneFindingKind;
7
+ severity: 'error' | 'warn';
8
+ identifier?: string;
9
+ detector: string;
10
+ remediation: string;
11
+ }
2
12
  export declare function checkEnvHygiene(projectPath: string): Promise<DoctorCheckResult>;
3
13
  export declare function scanFileEnvHygiene(projectPath: string, filePath: string): Promise<DoctorCheckResult>;
14
+ export declare function detectKnownCredentialShape(value: string): string | null;
15
+ export declare function credentialSeverityForDetector(detector: string): 'error' | 'warn';
16
+ export declare function looksLikeCredentialValue(value: string): boolean;
17
+ export declare function isDynamicOrInterpolatedValue(value: string): boolean;
18
+ export declare function isPlaceholderValue(value: string): boolean;
19
+ export declare function isCommentOnlyLine(line: string): boolean;
20
+ export declare function stripBearerPrefix(value: string): string;
4
21
  //# sourceMappingURL=env-hygiene.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env-hygiene.d.ts","sourceRoot":"","sources":["../../src/checks/env-hygiene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMrD,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwBrF;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAc5B"}
1
+ {"version":3,"file":"env-hygiene.d.ts","sourceRoot":"","sources":["../../src/checks/env-hygiene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD,MAAM,MAAM,qBAAqB,GAC7B,oBAAoB,GACpB,4BAA4B,GAC5B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,qBAAqB,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CASrF;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAM5B;AAgRD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBvE;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAEhF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAmB/D;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAoBzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}