@mr.dj2u/doctor 0.1.7 → 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.
- package/dist/checks/api-safety.d.ts +17 -0
- package/dist/checks/api-safety.d.ts.map +1 -0
- package/dist/checks/api-safety.js +282 -0
- package/dist/checks/api-safety.js.map +1 -0
- package/dist/checks/app-architecture.d.ts +3 -3
- package/dist/checks/app-architecture.d.ts.map +1 -1
- package/dist/checks/app-architecture.js +14 -11
- package/dist/checks/app-architecture.js.map +1 -1
- package/dist/checks/env-hygiene.d.ts +17 -0
- package/dist/checks/env-hygiene.d.ts.map +1 -1
- package/dist/checks/env-hygiene.js +376 -32
- package/dist/checks/env-hygiene.js.map +1 -1
- package/dist/checks/expo-config.d.ts.map +1 -1
- package/dist/checks/expo-config.js +4 -7
- package/dist/checks/expo-config.js.map +1 -1
- package/dist/checks/expo-doctor.d.ts.map +1 -1
- package/dist/checks/expo-doctor.js +6 -2
- package/dist/checks/expo-doctor.js.map +1 -1
- package/dist/checks/index.d.ts +4 -0
- package/dist/checks/index.d.ts.map +1 -1
- package/dist/checks/index.js +4 -0
- package/dist/checks/index.js.map +1 -1
- package/dist/checks/react-doctor.d.ts +28 -0
- package/dist/checks/react-doctor.d.ts.map +1 -0
- package/dist/checks/react-doctor.js +360 -0
- package/dist/checks/react-doctor.js.map +1 -0
- package/dist/checks/router-safety.d.ts +13 -0
- package/dist/checks/router-safety.d.ts.map +1 -0
- package/dist/checks/router-safety.js +360 -0
- package/dist/checks/router-safety.js.map +1 -0
- package/dist/checks/runtime-security.d.ts +17 -0
- package/dist/checks/runtime-security.d.ts.map +1 -0
- package/dist/checks/runtime-security.js +583 -0
- package/dist/checks/runtime-security.js.map +1 -0
- package/dist/checks/script-checks.d.ts +2 -0
- package/dist/checks/script-checks.d.ts.map +1 -1
- package/dist/checks/script-checks.js +33 -9
- package/dist/checks/script-checks.js.map +1 -1
- package/dist/cli-main.d.ts +1 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli-main.js +28 -1
- package/dist/cli-main.js.map +1 -1
- package/dist/expo-router.d.ts +15 -0
- package/dist/expo-router.d.ts.map +1 -0
- package/dist/expo-router.js +76 -0
- package/dist/expo-router.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -15
- package/dist/index.js.map +1 -1
- package/dist/modes.d.ts +8 -0
- package/dist/modes.d.ts.map +1 -0
- package/dist/modes.js +71 -0
- package/dist/modes.js.map +1 -0
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +73 -3
- package/dist/reporter.js.map +1 -1
- package/dist/scan-file.d.ts.map +1 -1
- package/dist/scan-file.js +9 -5
- package/dist/scan-file.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +11 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +124 -2
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,29 @@
|
|
|
1
|
+
import { createSkippedCheck } from '../modes.js';
|
|
1
2
|
import { buildRunScriptCommand, commandResultToCheck, detectPackageManager, runShellCommand, } from '../utils.js';
|
|
2
3
|
import { runEslintCheck, findScript } from './eslint.js';
|
|
3
4
|
import { runExpoDoctorCheck } from './expo-doctor.js';
|
|
5
|
+
import { runReactDoctorCheck } from './react-doctor.js';
|
|
4
6
|
import { runTypeScriptCheck } from './typescript.js';
|
|
5
7
|
export async function runScriptChecks(args) {
|
|
8
|
+
if (!args.runScripts) {
|
|
9
|
+
return [
|
|
10
|
+
createScriptDisabledSkip('lint'),
|
|
11
|
+
createScriptDisabledSkip('typecheck'),
|
|
12
|
+
createScriptDisabledSkip('tests'),
|
|
13
|
+
createScriptDisabledSkip('expo doctor'),
|
|
14
|
+
createScriptDisabledSkip('react doctor'),
|
|
15
|
+
createScriptDisabledSkip('production build'),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
6
18
|
const checks = [];
|
|
7
19
|
for (const check of [
|
|
8
20
|
await runEslintCheck(args),
|
|
9
21
|
await runTypeScriptCheck(args),
|
|
10
22
|
await runTestsCheck(args),
|
|
11
23
|
await runExpoDoctorCheck(args),
|
|
24
|
+
await runReactDoctorCheck({ ...args, runner: args.reactDoctorRunner }),
|
|
12
25
|
await runProductionBuildCheck(args),
|
|
26
|
+
runFullBuildProfileSkip(args),
|
|
13
27
|
]) {
|
|
14
28
|
if (check) {
|
|
15
29
|
checks.push(check);
|
|
@@ -17,18 +31,22 @@ export async function runScriptChecks(args) {
|
|
|
17
31
|
}
|
|
18
32
|
return checks;
|
|
19
33
|
}
|
|
34
|
+
function createScriptDisabledSkip(name) {
|
|
35
|
+
return createSkippedCheck(name, 'Skipped because package script execution is disabled.', { reason: 'runScripts=false' });
|
|
36
|
+
}
|
|
20
37
|
async function runTestsCheck(args) {
|
|
21
38
|
const candidates = ['test', 'test:ci'];
|
|
39
|
+
if (args.mode === 'fast') {
|
|
40
|
+
return createSkippedCheck('tests', 'Skipped in fast mode; run --ci or --full to include tests.', { reason: 'fast mode', candidates });
|
|
41
|
+
}
|
|
22
42
|
const scriptName = findScript(args.packageJson, candidates);
|
|
23
43
|
if (!scriptName) {
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
details: { candidates },
|
|
31
|
-
};
|
|
44
|
+
return {
|
|
45
|
+
name: 'tests',
|
|
46
|
+
status: 'warn',
|
|
47
|
+
message: 'No package script found for tests.',
|
|
48
|
+
details: { candidates },
|
|
49
|
+
};
|
|
32
50
|
}
|
|
33
51
|
const packageManager = await detectPackageManager(args.projectPath, args.packageJson);
|
|
34
52
|
const command = buildRunScriptCommand(packageManager, scriptName);
|
|
@@ -41,7 +59,7 @@ async function runProductionBuildCheck(args) {
|
|
|
41
59
|
? ['build:web:deploy', 'build:web', 'build:prod', 'build']
|
|
42
60
|
: [];
|
|
43
61
|
if (candidates.length === 0) {
|
|
44
|
-
return
|
|
62
|
+
return createSkippedCheck('production build', 'Skipped in fast mode; run --ci to include release build checks or --full for the broadest build profile.', { reason: 'fast mode', fullModeGuidance: 'Run --full to include preview/development build candidates.' });
|
|
45
63
|
}
|
|
46
64
|
const scriptName = findScript(args.packageJson, candidates);
|
|
47
65
|
if (!scriptName) {
|
|
@@ -56,4 +74,10 @@ async function runProductionBuildCheck(args) {
|
|
|
56
74
|
const command = buildRunScriptCommand(packageManager, scriptName);
|
|
57
75
|
return commandResultToCheck('production build', command, await runShellCommand(command, args.projectPath, args.timeoutMs));
|
|
58
76
|
}
|
|
77
|
+
function runFullBuildProfileSkip(args) {
|
|
78
|
+
if (args.mode === 'full') {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return createSkippedCheck('full build profile', 'Skipped because this mode does not include preview/development build candidates; run --full when release approval needs the broadest build profile.', { reason: `${args.mode} mode`, requiredMode: 'full' });
|
|
82
|
+
}
|
|
59
83
|
//# sourceMappingURL=script-checks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-checks.js","sourceRoot":"","sources":["../../src/checks/script-checks.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"script-checks.js","sourceRoot":"","sources":["../../src/checks/script-checks.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-main.d.ts
CHANGED
package/dist/cli-main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAuFhE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoB9E"}
|
package/dist/cli-main.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { formatHumanReport, runDoctor } from './index.js';
|
|
1
|
+
import { formatHumanReport, formatModeHelp, runDoctor } from './index.js';
|
|
2
2
|
export function parseDoctorCliArgs(argv) {
|
|
3
3
|
let projectPath = '.';
|
|
4
4
|
let mode = null;
|
|
5
5
|
let json = false;
|
|
6
|
+
let help = false;
|
|
6
7
|
let runScripts = true;
|
|
7
8
|
let timeoutMs = 120000;
|
|
9
|
+
let modeFlagCount = 0;
|
|
8
10
|
const positionals = [];
|
|
9
11
|
for (let index = 0; index < argv.length; index += 1) {
|
|
10
12
|
const arg = argv[index] ?? '';
|
|
@@ -16,17 +18,24 @@ export function parseDoctorCliArgs(argv) {
|
|
|
16
18
|
continue;
|
|
17
19
|
}
|
|
18
20
|
if (arg === '--ci') {
|
|
21
|
+
modeFlagCount += 1;
|
|
19
22
|
mode = 'ci';
|
|
20
23
|
continue;
|
|
21
24
|
}
|
|
22
25
|
if (arg === '--fast') {
|
|
26
|
+
modeFlagCount += 1;
|
|
23
27
|
mode = 'fast';
|
|
24
28
|
continue;
|
|
25
29
|
}
|
|
26
30
|
if (arg === '--full') {
|
|
31
|
+
modeFlagCount += 1;
|
|
27
32
|
mode = 'full';
|
|
28
33
|
continue;
|
|
29
34
|
}
|
|
35
|
+
if (arg === '--help' || arg === '-h') {
|
|
36
|
+
help = true;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
30
39
|
if (arg === '--json') {
|
|
31
40
|
json = true;
|
|
32
41
|
continue;
|
|
@@ -57,6 +66,9 @@ export function parseDoctorCliArgs(argv) {
|
|
|
57
66
|
if (positionals.length > 1) {
|
|
58
67
|
throw new Error(`Unexpected extra arguments: ${positionals.slice(1).join(' ')}`);
|
|
59
68
|
}
|
|
69
|
+
if (modeFlagCount > 1) {
|
|
70
|
+
throw new Error('Choose only one Doctor mode flag: --fast, --ci, or --full.');
|
|
71
|
+
}
|
|
60
72
|
if (positionals.length === 1) {
|
|
61
73
|
projectPath = positionals[0] ?? '.';
|
|
62
74
|
}
|
|
@@ -64,20 +76,35 @@ export function parseDoctorCliArgs(argv) {
|
|
|
64
76
|
projectPath,
|
|
65
77
|
mode: mode ?? 'ci',
|
|
66
78
|
json,
|
|
79
|
+
help,
|
|
67
80
|
runScripts,
|
|
68
81
|
timeoutMs,
|
|
69
82
|
};
|
|
70
83
|
}
|
|
71
84
|
export async function runDoctorCli(argv) {
|
|
72
85
|
const args = parseDoctorCliArgs(argv);
|
|
86
|
+
if (args.help) {
|
|
87
|
+
return {
|
|
88
|
+
output: formatDoctorCliHelp(),
|
|
89
|
+
exitCode: 0,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
73
92
|
const report = await runDoctor(args.projectPath, {
|
|
74
93
|
mode: args.mode,
|
|
75
94
|
runScripts: args.runScripts,
|
|
76
95
|
timeoutMs: args.timeoutMs,
|
|
96
|
+
selectionDefaultMode: 'ci',
|
|
77
97
|
});
|
|
78
98
|
return {
|
|
79
99
|
output: args.json ? JSON.stringify(report, null, 2) : formatHumanReport(report),
|
|
80
100
|
exitCode: report.summary.errors > 0 ? 1 : 0,
|
|
81
101
|
};
|
|
82
102
|
}
|
|
103
|
+
function formatDoctorCliHelp() {
|
|
104
|
+
return [
|
|
105
|
+
'Usage: mds-doctor [projectPath] [--fast|--ci|--full] [--json] [--no-scripts] [--timeout-ms value]',
|
|
106
|
+
'',
|
|
107
|
+
formatModeHelp('ci'),
|
|
108
|
+
].join('\n');
|
|
109
|
+
}
|
|
83
110
|
//# sourceMappingURL=cli-main.js.map
|
package/dist/cli-main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-main.js","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-main.js","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PackageJson } from './types.js';
|
|
2
|
+
export declare function hasExpoRouterSignal(packageJson: PackageJson): boolean;
|
|
3
|
+
export declare function findExpoRouterAppDirs(projectPath: string): Promise<string[]>;
|
|
4
|
+
export declare function isExpoRouterApiRouteFile(projectPath: string, filePath: string, packageJson: PackageJson): boolean;
|
|
5
|
+
export declare function isExpoRouterApiRouteSourceFile(filePath: string): boolean;
|
|
6
|
+
export declare function findExpoRouterApiRouteFiles(projectPath: string, packageJson: PackageJson): Promise<string[]>;
|
|
7
|
+
export declare function isRouteGroupDirName(name: string): boolean;
|
|
8
|
+
export declare function isExpoRouterLayoutFile(filePath: string): boolean;
|
|
9
|
+
export declare function isExpoRouterSpecialFile(filePath: string): boolean;
|
|
10
|
+
export declare function isTestLikeFile(filePath: string): boolean;
|
|
11
|
+
export declare function toPosixPath(filePath: string): string;
|
|
12
|
+
export declare function appRelativePath(appDir: string, filePath: string): string;
|
|
13
|
+
export declare function routeGroupSegments(appRelative: string): string[];
|
|
14
|
+
export declare function isRootLayoutPath(projectRelative: string): boolean;
|
|
15
|
+
//# sourceMappingURL=expo-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-router.d.ts","sourceRoot":"","sources":["../src/expo-router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAMrE;AAED,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASlF;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,GACvB,OAAO,CAYT;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOxE;AAED,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC,CAenB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AAED,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAEjE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findFiles, pathExists, relative } from './utils.js';
|
|
3
|
+
const API_ROUTE_EXTENSIONS = new Set(['.ts', '.js']);
|
|
4
|
+
export function hasExpoRouterSignal(packageJson) {
|
|
5
|
+
const deps = {
|
|
6
|
+
...packageJson.dependencies,
|
|
7
|
+
...packageJson.devDependencies,
|
|
8
|
+
};
|
|
9
|
+
return packageJson.main === 'expo-router/entry' || 'expo-router' in deps;
|
|
10
|
+
}
|
|
11
|
+
export async function findExpoRouterAppDirs(projectPath) {
|
|
12
|
+
const candidates = [path.join(projectPath, 'app'), path.join(projectPath, 'src', 'app')];
|
|
13
|
+
const existing = [];
|
|
14
|
+
for (const candidate of candidates) {
|
|
15
|
+
if (await pathExists(candidate)) {
|
|
16
|
+
existing.push(candidate);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return existing;
|
|
20
|
+
}
|
|
21
|
+
export function isExpoRouterApiRouteFile(projectPath, filePath, packageJson) {
|
|
22
|
+
if (!hasExpoRouterSignal(packageJson)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const normalized = relative(projectPath, filePath);
|
|
26
|
+
const inAppRoot = normalized.startsWith('app/') || normalized.startsWith('src/app/');
|
|
27
|
+
if (!inAppRoot) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return isExpoRouterApiRouteSourceFile(filePath);
|
|
31
|
+
}
|
|
32
|
+
export function isExpoRouterApiRouteSourceFile(filePath) {
|
|
33
|
+
const extension = path.extname(filePath);
|
|
34
|
+
if (!API_ROUTE_EXTENSIONS.has(extension)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return path.basename(filePath, extension).endsWith('+api');
|
|
38
|
+
}
|
|
39
|
+
export async function findExpoRouterApiRouteFiles(projectPath, packageJson) {
|
|
40
|
+
if (!hasExpoRouterSignal(packageJson)) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const appDirs = await findExpoRouterAppDirs(projectPath);
|
|
44
|
+
const files = [];
|
|
45
|
+
for (const appDir of appDirs) {
|
|
46
|
+
files.push(...(await findFiles(appDir, (filePath) => isExpoRouterApiRouteFile(projectPath, filePath, packageJson))));
|
|
47
|
+
}
|
|
48
|
+
return files;
|
|
49
|
+
}
|
|
50
|
+
export function isRouteGroupDirName(name) {
|
|
51
|
+
return name.startsWith('(') && name.endsWith(')') && name.length > 2;
|
|
52
|
+
}
|
|
53
|
+
export function isExpoRouterLayoutFile(filePath) {
|
|
54
|
+
return /^_layout(?:\.[^.]+)?\.(tsx|ts|jsx|js)$/.test(path.basename(filePath));
|
|
55
|
+
}
|
|
56
|
+
export function isExpoRouterSpecialFile(filePath) {
|
|
57
|
+
const basename = path.basename(filePath);
|
|
58
|
+
return basename.startsWith('+') || isExpoRouterLayoutFile(filePath);
|
|
59
|
+
}
|
|
60
|
+
export function isTestLikeFile(filePath) {
|
|
61
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
62
|
+
return /\/__tests__\/|\.test\.|\.spec\./.test(normalized);
|
|
63
|
+
}
|
|
64
|
+
export function toPosixPath(filePath) {
|
|
65
|
+
return filePath.replace(/\\/g, '/');
|
|
66
|
+
}
|
|
67
|
+
export function appRelativePath(appDir, filePath) {
|
|
68
|
+
return relative(appDir, filePath);
|
|
69
|
+
}
|
|
70
|
+
export function routeGroupSegments(appRelative) {
|
|
71
|
+
return appRelative.split('/').filter((segment) => isRouteGroupDirName(segment));
|
|
72
|
+
}
|
|
73
|
+
export function isRootLayoutPath(projectRelative) {
|
|
74
|
+
return /^(src\/)?app\/_layout(?:\.[^./]+)?\.(tsx|ts|jsx|js)$/.test(projectRelative);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=expo-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-router.js","sourceRoot":"","sources":["../src/expo-router.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAErD,MAAM,UAAU,mBAAmB,CAAC,WAAwB;IAC1D,MAAM,IAAI,GAAG;QACX,GAAG,WAAW,CAAC,YAAY;QAC3B,GAAG,WAAW,CAAC,eAAe;KAC/B,CAAC;IACF,OAAO,WAAW,CAAC,IAAI,KAAK,mBAAmB,IAAI,aAAa,IAAI,IAAI,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB;IAC7D,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACzF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,WAAmB,EACnB,QAAgB,EAChB,WAAwB;IAExB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACrF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,8BAA8B,CAAC,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,QAAgB;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,WAAmB,EACnB,WAAwB;IAExB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAC7D,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,OAAO,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,QAAQ,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,iCAAiC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,QAAgB;IAC9D,OAAO,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,eAAuB;IACtD,OAAO,sDAAsD,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AACtF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DoctorOptions, DoctorReport } from './types.js';
|
|
2
|
-
export type { DoctorCheckResult, DoctorCheckStatus, DoctorMode, DoctorOptions, DoctorReport, PackageJson, ScanFileOptions, } from './types.js';
|
|
2
|
+
export type { DoctorCheckResult, DoctorCheckStatus, DoctorMode, DoctorModeSelection, DoctorOptions, DoctorReport, PackageJson, ScanFileOptions, } from './types.js';
|
|
3
|
+
export { DEFAULT_DOCTOR_MODE, FULL_MODE_GUIDANCE, createModeSelection, formatModeHelp, normalizeDoctorMode, } from './modes.js';
|
|
3
4
|
export { createReport, formatHumanReport, formatJsonReport } from './reporter.js';
|
|
4
5
|
export { scanFile } from './scan-file.js';
|
|
5
6
|
export declare function runDoctor(projectPath: string, options?: DoctorOptions): Promise<DoctorReport>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG9D,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAwDvB;AAED,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,IAAI,CAAC,aAAa,EAAE,KAAK,CAAM,GACvC,OAAO,CAAC,YAAY,CAAC,CAEvB"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { checkAppArchitecture, checkAnimationPerformance, checkEnvHygiene, checkExpoConfiguration, checkGitignoreEnv, checkPackageScripts, checkProjectDocs, checkSeoMetadata, checkStylingDependencies, checkTodoForContextMarkers, runScriptChecks, } from './checks/index.js';
|
|
2
|
+
import { checkAppArchitecture, checkAnimationPerformance, checkApiSafety, checkEnvHygiene, checkExpoConfiguration, checkGitignoreEnv, checkRuntimeSecurity, checkPackageScripts, checkProjectDocs, checkRouterSafety, checkSeoMetadata, checkStylingDependencies, checkTodoForContextMarkers, runScriptChecks, } from './checks/index.js';
|
|
3
|
+
import { DEFAULT_DOCTOR_MODE, normalizeDoctorMode } from './modes.js';
|
|
3
4
|
import { createReport } from './reporter.js';
|
|
4
5
|
import { pathExists, readPackageJson } from './utils.js';
|
|
6
|
+
export { DEFAULT_DOCTOR_MODE, FULL_MODE_GUIDANCE, createModeSelection, formatModeHelp, normalizeDoctorMode, } from './modes.js';
|
|
5
7
|
export { createReport, formatHumanReport, formatJsonReport } from './reporter.js';
|
|
6
8
|
export { scanFile } from './scan-file.js';
|
|
7
9
|
export async function runDoctor(projectPath, options = {}) {
|
|
8
10
|
const resolvedProjectPath = path.resolve(projectPath);
|
|
9
|
-
const mode = options.mode
|
|
11
|
+
const mode = normalizeDoctorMode(options.mode);
|
|
12
|
+
const runScripts = options.runScripts !== false;
|
|
13
|
+
const selectionDefaultMode = options.selectionDefaultMode ?? DEFAULT_DOCTOR_MODE;
|
|
10
14
|
const checks = [];
|
|
11
15
|
if (!(await pathExists(resolvedProjectPath))) {
|
|
12
16
|
checks.push({
|
|
@@ -14,7 +18,7 @@ export async function runDoctor(projectPath, options = {}) {
|
|
|
14
18
|
status: 'error',
|
|
15
19
|
message: `Project path does not exist: ${resolvedProjectPath}`,
|
|
16
20
|
});
|
|
17
|
-
return createReport(resolvedProjectPath, mode, checks);
|
|
21
|
+
return createReport(resolvedProjectPath, mode, checks, runScripts, selectionDefaultMode);
|
|
18
22
|
}
|
|
19
23
|
const packageJsonPath = path.join(resolvedProjectPath, 'package.json');
|
|
20
24
|
const packageJson = await readPackageJson(packageJsonPath);
|
|
@@ -27,25 +31,28 @@ export async function runDoctor(projectPath, options = {}) {
|
|
|
27
31
|
status: 'warn',
|
|
28
32
|
message: 'No package.json found; package scripts and dependency checks were skipped.',
|
|
29
33
|
});
|
|
30
|
-
return createReport(resolvedProjectPath, mode, checks);
|
|
34
|
+
return createReport(resolvedProjectPath, mode, checks, runScripts, selectionDefaultMode);
|
|
31
35
|
}
|
|
32
36
|
checks.push(checkPackageScripts(packageJson, resolvedProjectPath));
|
|
33
37
|
checks.push(checkStylingDependencies(packageJson));
|
|
34
38
|
checks.push(await checkExpoConfiguration(packageJson, resolvedProjectPath));
|
|
35
39
|
checks.push(await checkEnvHygiene(resolvedProjectPath));
|
|
36
|
-
checks.push(await
|
|
40
|
+
checks.push(await checkRuntimeSecurity(resolvedProjectPath));
|
|
41
|
+
checks.push(await checkAppArchitecture(packageJson, resolvedProjectPath));
|
|
42
|
+
checks.push(await checkRouterSafety(resolvedProjectPath));
|
|
43
|
+
checks.push(await checkApiSafety(packageJson, resolvedProjectPath));
|
|
37
44
|
checks.push(await checkAnimationPerformance(resolvedProjectPath));
|
|
38
45
|
checks.push(await checkSeoMetadata(resolvedProjectPath));
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
return createReport(resolvedProjectPath, mode, checks);
|
|
46
|
+
checks.push(...(await runScriptChecks({
|
|
47
|
+
packageJson,
|
|
48
|
+
projectPath: resolvedProjectPath,
|
|
49
|
+
mode,
|
|
50
|
+
fix: options.fix ?? false,
|
|
51
|
+
runScripts,
|
|
52
|
+
timeoutMs: options.timeoutMs ?? 120000,
|
|
53
|
+
reactDoctorRunner: options.reactDoctorRunner,
|
|
54
|
+
})));
|
|
55
|
+
return createReport(resolvedProjectPath, mode, checks, runScripts, selectionDefaultMode);
|
|
49
56
|
}
|
|
50
57
|
export async function fixDoctor(projectPath, options = {}) {
|
|
51
58
|
return runDoctor(projectPath, { ...options, fix: true });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/modes.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DoctorCheckResult, DoctorMode, DoctorModeSelection } from './types.js';
|
|
2
|
+
export declare const DEFAULT_DOCTOR_MODE: DoctorMode;
|
|
3
|
+
export declare const FULL_MODE_GUIDANCE = "Use --full when release approval needs the broadest available build profile, including preview or development build scripts.";
|
|
4
|
+
export declare function normalizeDoctorMode(value: DoctorMode | undefined): DoctorMode;
|
|
5
|
+
export declare function createModeSelection(mode: DoctorMode, runScripts: boolean, defaultMode?: DoctorMode): DoctorModeSelection;
|
|
6
|
+
export declare function createSkippedCheck(name: string, message: string, details?: Record<string, unknown>): DoctorCheckResult;
|
|
7
|
+
export declare function formatModeHelp(defaultMode?: DoctorMode): string;
|
|
8
|
+
//# sourceMappingURL=modes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErF,eAAO,MAAM,mBAAmB,EAAE,UAAmB,CAAC;AAEtD,eAAO,MAAM,kBAAkB,iIACiG,CAAC;AAqCjI,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAE7E;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,OAAO,EACnB,WAAW,GAAE,UAAgC,GAC5C,mBAAmB,CAYrB;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,iBAAiB,CAOnB;AAED,wBAAgB,cAAc,CAAC,WAAW,GAAE,UAAgC,GAAG,MAAM,CAWpF"}
|
package/dist/modes.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const DEFAULT_DOCTOR_MODE = 'fast';
|
|
2
|
+
export const FULL_MODE_GUIDANCE = 'Use --full when release approval needs the broadest available build profile, including preview or development build scripts.';
|
|
3
|
+
const MODE_INCLUDES = {
|
|
4
|
+
fast: [
|
|
5
|
+
'static project checks',
|
|
6
|
+
'lint script when scripts are enabled',
|
|
7
|
+
'typecheck script when scripts are enabled',
|
|
8
|
+
],
|
|
9
|
+
ci: [
|
|
10
|
+
'static project checks',
|
|
11
|
+
'lint and typecheck scripts when scripts are enabled',
|
|
12
|
+
'tests, Expo Doctor, and release build scripts when available',
|
|
13
|
+
],
|
|
14
|
+
full: [
|
|
15
|
+
'static project checks',
|
|
16
|
+
'all CI script checks when scripts are enabled',
|
|
17
|
+
'the broadest available build script, including preview or development builds',
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
const MODE_SKIPS = {
|
|
21
|
+
fast: [
|
|
22
|
+
'tests',
|
|
23
|
+
'Expo Doctor',
|
|
24
|
+
'production build',
|
|
25
|
+
'full build profile',
|
|
26
|
+
],
|
|
27
|
+
ci: ['full build profile'],
|
|
28
|
+
full: [],
|
|
29
|
+
};
|
|
30
|
+
const MODE_DESCRIPTIONS = {
|
|
31
|
+
fast: 'Fast profile for local iteration and pre-commit checks.',
|
|
32
|
+
ci: 'CI-equivalent profile for pull requests and release gates.',
|
|
33
|
+
full: 'Full profile for broad pre-release verification.',
|
|
34
|
+
};
|
|
35
|
+
export function normalizeDoctorMode(value) {
|
|
36
|
+
return value === 'ci' || value === 'full' || value === 'fast' ? value : DEFAULT_DOCTOR_MODE;
|
|
37
|
+
}
|
|
38
|
+
export function createModeSelection(mode, runScripts, defaultMode = DEFAULT_DOCTOR_MODE) {
|
|
39
|
+
return {
|
|
40
|
+
defaultMode,
|
|
41
|
+
mode,
|
|
42
|
+
runScripts,
|
|
43
|
+
description: MODE_DESCRIPTIONS[mode],
|
|
44
|
+
includes: MODE_INCLUDES[mode],
|
|
45
|
+
skips: runScripts
|
|
46
|
+
? MODE_SKIPS[mode]
|
|
47
|
+
: ['all package script checks because script execution is disabled'],
|
|
48
|
+
fullModeGuidance: FULL_MODE_GUIDANCE,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function createSkippedCheck(name, message, details) {
|
|
52
|
+
return {
|
|
53
|
+
name,
|
|
54
|
+
status: 'skip',
|
|
55
|
+
message,
|
|
56
|
+
...(details ? { details } : {}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function formatModeHelp(defaultMode = DEFAULT_DOCTOR_MODE) {
|
|
60
|
+
return [
|
|
61
|
+
`Default mode: ${defaultMode}`,
|
|
62
|
+
'',
|
|
63
|
+
'Modes:',
|
|
64
|
+
' --fast Static checks plus lint/typecheck scripts. Skips tests, Expo Doctor, and builds.',
|
|
65
|
+
' --ci CI-equivalent checks: lint, typecheck, tests, Expo Doctor, and release build.',
|
|
66
|
+
' --full CI checks plus the broadest available build script candidates.',
|
|
67
|
+
'',
|
|
68
|
+
FULL_MODE_GUIDANCE,
|
|
69
|
+
].join('\n');
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=modes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.js","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAe,MAAM,CAAC;AAEtD,MAAM,CAAC,MAAM,kBAAkB,GAC7B,8HAA8H,CAAC;AAEjI,MAAM,aAAa,GAAiC;IAClD,IAAI,EAAE;QACJ,uBAAuB;QACvB,sCAAsC;QACtC,2CAA2C;KAC5C;IACD,EAAE,EAAE;QACF,uBAAuB;QACvB,qDAAqD;QACrD,8DAA8D;KAC/D;IACD,IAAI,EAAE;QACJ,uBAAuB;QACvB,+CAA+C;QAC/C,8EAA8E;KAC/E;CACF,CAAC;AAEF,MAAM,UAAU,GAAiC;IAC/C,IAAI,EAAE;QACJ,OAAO;QACP,aAAa;QACb,kBAAkB;QAClB,oBAAoB;KACrB;IACD,EAAE,EAAE,CAAC,oBAAoB,CAAC;IAC1B,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,MAAM,iBAAiB,GAA+B;IACpD,IAAI,EAAE,yDAAyD;IAC/D,EAAE,EAAE,4DAA4D;IAChE,IAAI,EAAE,kDAAkD;CACzD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,KAA6B;IAC/D,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,IAAgB,EAChB,UAAmB,EACnB,cAA0B,mBAAmB;IAE7C,OAAO;QACL,WAAW;QACX,IAAI;QACJ,UAAU;QACV,WAAW,EAAE,iBAAiB,CAAC,IAAI,CAAC;QACpC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC;QAC7B,KAAK,EAAE,UAAU;YACf,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YAClB,CAAC,CAAC,CAAC,gEAAgE,CAAC;QACtE,gBAAgB,EAAE,kBAAkB;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,OAAe,EACf,OAAiC;IAEjC,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,MAAM;QACd,OAAO;QACP,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,cAA0B,mBAAmB;IAC1E,OAAO;QACL,iBAAiB,WAAW,EAAE;QAC9B,EAAE;QACF,QAAQ;QACR,4FAA4F;QAC5F,yFAAyF;QACzF,0EAA0E;QAC1E,EAAE;QACF,kBAAkB;KACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
package/dist/reporter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DoctorCheckResult, DoctorMode, DoctorReport } from './types.js';
|
|
2
|
-
export declare function createReport(projectPath: string, mode: DoctorMode, checks: DoctorCheckResult[]): DoctorReport;
|
|
2
|
+
export declare function createReport(projectPath: string, mode: DoctorMode, checks: DoctorCheckResult[], runScripts?: boolean, selectionDefaultMode?: DoctorMode): DoctorReport;
|
|
3
3
|
export declare function formatJsonReport(report: DoctorReport): string;
|
|
4
4
|
export declare function formatHumanReport(report: DoctorReport): string;
|
|
5
5
|
//# sourceMappingURL=reporter.d.ts.map
|
package/dist/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EAEb,MAAM,YAAY,CAAC;AAkFpB,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,UAAU,UAAO,EACjB,oBAAoB,GAAE,UAAmB,GACxC,YAAY,CAqBd;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE7D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA2B9D"}
|
package/dist/reporter.js
CHANGED
|
@@ -1,20 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
import { createModeSelection } from './modes.js';
|
|
2
|
+
const EXTERNAL_SCORE_CHECKS = new Set(['react doctor', 'expo doctor']);
|
|
3
|
+
function computeNativeScore(summary) {
|
|
2
4
|
return Math.max(0, 100 - summary.errors * 25 - summary.warnings * 5);
|
|
3
5
|
}
|
|
4
|
-
|
|
6
|
+
function computeScoreBreakdown(checks) {
|
|
7
|
+
const nativeChecks = checks.filter((check) => !EXTERNAL_SCORE_CHECKS.has(check.name));
|
|
8
|
+
const nativeSummary = {
|
|
9
|
+
errors: nativeChecks.filter((check) => check.status === 'error').length,
|
|
10
|
+
warnings: nativeChecks.filter((check) => check.status === 'warn').length,
|
|
11
|
+
};
|
|
12
|
+
const candidates = [
|
|
13
|
+
{
|
|
14
|
+
name: 'mds',
|
|
15
|
+
label: 'MDS native checks',
|
|
16
|
+
score: computeNativeScore(nativeSummary),
|
|
17
|
+
desiredWeight: 50,
|
|
18
|
+
},
|
|
19
|
+
reactDoctorScoreComponent(checks),
|
|
20
|
+
expoDoctorScoreComponent(checks),
|
|
21
|
+
].filter((component) => {
|
|
22
|
+
return component !== null;
|
|
23
|
+
});
|
|
24
|
+
const totalDesiredWeight = candidates.reduce((sum, component) => sum + component.desiredWeight, 0);
|
|
25
|
+
const components = candidates.map((component) => ({
|
|
26
|
+
...component,
|
|
27
|
+
weight: totalDesiredWeight > 0 ? component.desiredWeight / totalDesiredWeight : 0,
|
|
28
|
+
}));
|
|
29
|
+
return { components };
|
|
30
|
+
}
|
|
31
|
+
function computeCompositeScore(breakdown) {
|
|
32
|
+
return Math.round(breakdown.components.reduce((sum, component) => sum + component.score * component.weight, 0));
|
|
33
|
+
}
|
|
34
|
+
function reactDoctorScoreComponent(checks) {
|
|
35
|
+
const check = checks.find((entry) => entry.name === 'react doctor');
|
|
36
|
+
if (!check || check.status === 'skip') {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const score = readNumber(check.details?.score);
|
|
40
|
+
if (score === undefined) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
name: 'react-doctor',
|
|
45
|
+
label: 'React Doctor',
|
|
46
|
+
score,
|
|
47
|
+
desiredWeight: 35,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function expoDoctorScoreComponent(checks) {
|
|
51
|
+
const check = checks.find((entry) => entry.name === 'expo doctor');
|
|
52
|
+
if (!check || check.status === 'skip') {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
name: 'expo-doctor',
|
|
57
|
+
label: 'Expo Doctor',
|
|
58
|
+
score: check.status === 'pass' ? 100 : check.status === 'warn' ? 75 : 0,
|
|
59
|
+
desiredWeight: 15,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function readNumber(value) {
|
|
63
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
64
|
+
}
|
|
65
|
+
export function createReport(projectPath, mode, checks, runScripts = true, selectionDefaultMode = 'fast') {
|
|
5
66
|
const summary = {
|
|
6
67
|
errors: checks.filter((check) => check.status === 'error').length,
|
|
7
68
|
warnings: checks.filter((check) => check.status === 'warn').length,
|
|
8
69
|
passed: checks.filter((check) => check.status === 'pass').length,
|
|
9
70
|
skipped: checks.filter((check) => check.status === 'skip').length,
|
|
10
71
|
};
|
|
72
|
+
const scoreBreakdown = computeScoreBreakdown(checks);
|
|
11
73
|
return {
|
|
12
74
|
projectPath,
|
|
13
75
|
timestamp: new Date().toISOString(),
|
|
14
76
|
mode,
|
|
77
|
+
selection: createModeSelection(mode, runScripts, selectionDefaultMode),
|
|
15
78
|
checks,
|
|
16
79
|
summary: {
|
|
17
|
-
score:
|
|
80
|
+
score: computeCompositeScore(scoreBreakdown),
|
|
81
|
+
scoreBreakdown,
|
|
18
82
|
...summary,
|
|
19
83
|
},
|
|
20
84
|
};
|
|
@@ -23,7 +87,13 @@ export function formatJsonReport(report) {
|
|
|
23
87
|
return JSON.stringify(report, null, 2);
|
|
24
88
|
}
|
|
25
89
|
export function formatHumanReport(report) {
|
|
90
|
+
const selection = report.selection ?? createModeSelection(report.mode, true);
|
|
26
91
|
const lines = [`mds doctor (${report.mode})`, report.projectPath, ''];
|
|
92
|
+
lines.push(`mode: ${selection.description}`);
|
|
93
|
+
lines.push(`default: ${selection.defaultMode}`);
|
|
94
|
+
lines.push(`scripts: ${selection.runScripts ? 'enabled' : 'disabled'}`);
|
|
95
|
+
lines.push(`full mode: ${selection.fullModeGuidance}`);
|
|
96
|
+
lines.push('');
|
|
27
97
|
for (const check of report.checks) {
|
|
28
98
|
lines.push(`${label(check)} ${check.name}: ${check.message}`);
|
|
29
99
|
if (check.status !== 'pass' && check.details) {
|