toolip 1.0.6 → 2.0.0
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/README.md +189 -448
- package/dist/src/analyzers/ast/ast-security-analyzer.d.ts +6 -0
- package/dist/src/analyzers/ast/ast-security-analyzer.js +64 -0
- package/dist/src/analyzers/ast/ast-security-analyzer.js.map +1 -0
- package/dist/src/analyzers/ast/rules.d.ts +48 -0
- package/dist/src/analyzers/ast/rules.js +39 -0
- package/dist/src/analyzers/ast/rules.js.map +1 -0
- package/dist/src/analyzers/ast/source-analysis.d.ts +2 -0
- package/dist/src/analyzers/ast/source-analysis.js +225 -0
- package/dist/src/analyzers/ast/source-analysis.js.map +1 -0
- package/dist/src/analyzers/dependency-confusion/analyzer.d.ts +9 -0
- package/dist/src/analyzers/dependency-confusion/analyzer.js +98 -0
- package/dist/src/analyzers/dependency-confusion/analyzer.js.map +1 -0
- package/dist/src/analyzers/docker/analyzer.d.ts +6 -0
- package/dist/src/analyzers/docker/analyzer.js +103 -0
- package/dist/src/analyzers/docker/analyzer.js.map +1 -0
- package/dist/src/analyzers/git-history/analyzer.d.ts +8 -0
- package/dist/src/analyzers/git-history/analyzer.js +157 -0
- package/dist/src/analyzers/git-history/analyzer.js.map +1 -0
- package/dist/src/analyzers/git-history/secret-patterns.d.ts +7 -0
- package/dist/src/analyzers/git-history/secret-patterns.js +33 -0
- package/dist/src/analyzers/git-history/secret-patterns.js.map +1 -0
- package/dist/src/analyzers/install-scripts/install-script-analyzer.d.ts +6 -0
- package/dist/src/analyzers/install-scripts/install-script-analyzer.js +135 -0
- package/dist/src/analyzers/install-scripts/install-script-analyzer.js.map +1 -0
- package/dist/src/analyzers/reachability/import-graph.d.ts +9 -0
- package/dist/src/analyzers/reachability/import-graph.js +110 -0
- package/dist/src/analyzers/reachability/import-graph.js.map +1 -0
- package/dist/src/analyzers/reachability/reachability-analyzer.d.ts +16 -0
- package/dist/src/analyzers/reachability/reachability-analyzer.js +95 -0
- package/dist/src/analyzers/reachability/reachability-analyzer.js.map +1 -0
- package/dist/src/analyzers/vulnerability/osv-analyzer.d.ts +9 -0
- package/dist/src/analyzers/vulnerability/osv-analyzer.js +94 -0
- package/dist/src/analyzers/vulnerability/osv-analyzer.js.map +1 -0
- package/dist/src/analyzers/vulnerability/severity.d.ts +3 -0
- package/dist/src/analyzers/vulnerability/severity.js +13 -0
- package/dist/src/analyzers/vulnerability/severity.js.map +1 -0
- package/dist/src/application/analyzer-runner.d.ts +12 -0
- package/dist/src/application/analyzer-runner.js +45 -0
- package/dist/src/application/analyzer-runner.js.map +1 -0
- package/dist/src/commands/alternatives.d.ts +2 -0
- package/dist/src/commands/alternatives.js +17 -0
- package/dist/src/commands/alternatives.js.map +1 -0
- package/dist/src/commands/announce.d.ts +2 -0
- package/dist/src/commands/announce.js +27 -0
- package/dist/src/commands/announce.js.map +1 -0
- package/dist/src/commands/ast-scan.d.ts +2 -0
- package/dist/src/commands/ast-scan.js +86 -0
- package/dist/src/commands/ast-scan.js.map +1 -0
- package/dist/src/commands/audit-repo.d.ts +2 -0
- package/dist/src/commands/audit-repo.js +20 -0
- package/dist/src/commands/audit-repo.js.map +1 -0
- package/dist/src/commands/compare.d.ts +2 -0
- package/dist/src/commands/compare.js +19 -0
- package/dist/src/commands/compare.js.map +1 -0
- package/dist/src/commands/config.d.ts +2 -0
- package/dist/src/commands/config.js +69 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/dependency-confusion.d.ts +2 -0
- package/dist/src/commands/dependency-confusion.js +37 -0
- package/dist/src/commands/dependency-confusion.js.map +1 -0
- package/dist/src/commands/diff.d.ts +2 -0
- package/dist/src/commands/diff.js +24 -0
- package/dist/src/commands/diff.js.map +1 -0
- package/dist/src/commands/docker-scan.d.ts +2 -0
- package/dist/src/commands/docker-scan.js +34 -0
- package/dist/src/commands/docker-scan.js.map +1 -0
- package/dist/src/commands/doctor.d.ts +2 -0
- package/dist/src/commands/doctor.js +42 -0
- package/dist/src/commands/doctor.js.map +1 -0
- package/dist/src/commands/git-audit.d.ts +2 -0
- package/dist/src/commands/git-audit.js +37 -0
- package/dist/src/commands/git-audit.js.map +1 -0
- package/dist/src/commands/git-history.d.ts +2 -0
- package/dist/src/commands/git-history.js +40 -0
- package/dist/src/commands/git-history.js.map +1 -0
- package/dist/src/commands/history.d.ts +2 -0
- package/dist/src/commands/history.js +69 -0
- package/dist/src/commands/history.js.map +1 -0
- package/dist/src/commands/hook.d.ts +2 -0
- package/dist/src/commands/hook.js +16 -0
- package/dist/src/commands/hook.js.map +1 -0
- package/dist/src/commands/inspect.d.ts +2 -0
- package/dist/src/commands/inspect.js +24 -0
- package/dist/src/commands/inspect.js.map +1 -0
- package/dist/src/commands/install-scripts.d.ts +2 -0
- package/dist/src/commands/install-scripts.js +52 -0
- package/dist/src/commands/install-scripts.js.map +1 -0
- package/dist/src/commands/learn.d.ts +2 -0
- package/dist/src/commands/learn.js +42 -0
- package/dist/src/commands/learn.js.map +1 -0
- package/dist/src/commands/licenses.d.ts +2 -0
- package/dist/src/commands/licenses.js +40 -0
- package/dist/src/commands/licenses.js.map +1 -0
- package/dist/src/commands/mcp.d.ts +2 -0
- package/dist/src/commands/mcp.js +10 -0
- package/dist/src/commands/mcp.js.map +1 -0
- package/dist/src/commands/monorepo.d.ts +2 -0
- package/dist/src/commands/monorepo.js +21 -0
- package/dist/src/commands/monorepo.js.map +1 -0
- package/dist/src/commands/package-health.d.ts +2 -0
- package/dist/src/commands/package-health.js +50 -0
- package/dist/src/commands/package-health.js.map +1 -0
- package/dist/src/commands/pre-commit.d.ts +2 -0
- package/dist/src/commands/pre-commit.js +37 -0
- package/dist/src/commands/pre-commit.js.map +1 -0
- package/dist/src/commands/profile.d.ts +2 -0
- package/dist/src/commands/profile.js +18 -0
- package/dist/src/commands/profile.js.map +1 -0
- package/dist/src/commands/publish.d.ts +2 -0
- package/dist/src/commands/publish.js +25 -0
- package/dist/src/commands/publish.js.map +1 -0
- package/dist/src/commands/reachability.d.ts +2 -0
- package/dist/src/commands/reachability.js +47 -0
- package/dist/src/commands/reachability.js.map +1 -0
- package/dist/src/commands/sbom.d.ts +2 -0
- package/dist/src/commands/sbom.js +33 -0
- package/dist/src/commands/sbom.js.map +1 -0
- package/dist/src/commands/scan.d.ts +2 -0
- package/dist/src/commands/scan.js +48 -0
- package/dist/src/commands/scan.js.map +1 -0
- package/dist/src/commands/score.d.ts +2 -0
- package/dist/src/commands/score.js +24 -0
- package/dist/src/commands/score.js.map +1 -0
- package/dist/src/commands/self-test.d.ts +2 -0
- package/dist/src/commands/self-test.js +63 -0
- package/dist/src/commands/self-test.js.map +1 -0
- package/dist/src/commands/tree.d.ts +2 -0
- package/dist/src/commands/tree.js +21 -0
- package/dist/src/commands/tree.js.map +1 -0
- package/dist/src/commands/upgrade-pr.d.ts +2 -0
- package/dist/src/commands/upgrade-pr.js +15 -0
- package/dist/src/commands/upgrade-pr.js.map +1 -0
- package/dist/src/commands/vault.d.ts +2 -0
- package/dist/src/commands/vault.js +86 -0
- package/dist/src/commands/vault.js.map +1 -0
- package/dist/src/commands/vulnerabilities.d.ts +2 -0
- package/dist/src/commands/vulnerabilities.js +42 -0
- package/dist/src/commands/vulnerabilities.js.map +1 -0
- package/dist/src/commands/watch.d.ts +2 -0
- package/dist/src/commands/watch.js +34 -0
- package/dist/src/commands/watch.js.map +1 -0
- package/dist/src/config/version.d.ts +6 -0
- package/dist/src/config/version.js +29 -0
- package/dist/src/config/version.js.map +1 -0
- package/dist/src/contracts/analyzer.d.ts +23 -0
- package/dist/src/contracts/analyzer.js +2 -0
- package/dist/src/contracts/analyzer.js.map +1 -0
- package/dist/src/contracts/finding.d.ts +35 -0
- package/dist/src/contracts/finding.js +13 -0
- package/dist/src/contracts/finding.js.map +1 -0
- package/dist/src/contracts/report.d.ts +30 -0
- package/dist/src/contracts/report.js +2 -0
- package/dist/src/contracts/report.js.map +1 -0
- package/dist/src/contracts/rule.d.ts +12 -0
- package/dist/src/contracts/rule.js +7 -0
- package/dist/src/contracts/rule.js.map +1 -0
- package/dist/src/core/alternatives.d.ts +8 -0
- package/dist/src/core/alternatives.js +35 -0
- package/dist/src/core/alternatives.js.map +1 -0
- package/dist/src/core/analyze-package.d.ts +2 -0
- package/dist/src/core/analyze-package.js +49 -0
- package/dist/src/core/analyze-package.js.map +1 -0
- package/dist/src/core/announce/generate.d.ts +9 -0
- package/dist/src/core/announce/generate.js +19 -0
- package/dist/src/core/announce/generate.js.map +1 -0
- package/dist/src/core/compare-packages.d.ts +7 -0
- package/dist/src/core/compare-packages.js +19 -0
- package/dist/src/core/compare-packages.js.map +1 -0
- package/dist/src/core/config/load.d.ts +3 -0
- package/dist/src/core/config/load.js +21 -0
- package/dist/src/core/config/load.js.map +1 -0
- package/dist/src/core/config/policy.d.ts +3 -0
- package/dist/src/core/config/policy.js +48 -0
- package/dist/src/core/config/policy.js.map +1 -0
- package/dist/src/core/config/schema.d.ts +172 -0
- package/dist/src/core/config/schema.js +84 -0
- package/dist/src/core/config/schema.js.map +1 -0
- package/dist/src/core/dependencies/inventory.d.ts +9 -0
- package/dist/src/core/dependencies/inventory.js +43 -0
- package/dist/src/core/dependencies/inventory.js.map +1 -0
- package/dist/src/core/dependency-scan.d.ts +17 -0
- package/dist/src/core/dependency-scan.js +70 -0
- package/dist/src/core/dependency-scan.js.map +1 -0
- package/dist/src/core/dependency-tree.d.ts +16 -0
- package/dist/src/core/dependency-tree.js +19 -0
- package/dist/src/core/dependency-tree.js.map +1 -0
- package/dist/src/core/dependency-types.d.ts +17 -0
- package/dist/src/core/dependency-types.js +2 -0
- package/dist/src/core/dependency-types.js.map +1 -0
- package/dist/src/core/diff/security-diff.d.ts +10 -0
- package/dist/src/core/diff/security-diff.js +20 -0
- package/dist/src/core/diff/security-diff.js.map +1 -0
- package/dist/src/core/file-walker.d.ts +6 -0
- package/dist/src/core/file-walker.js +27 -0
- package/dist/src/core/file-walker.js.map +1 -0
- package/dist/src/core/git-audit.d.ts +12 -0
- package/dist/src/core/git-audit.js +111 -0
- package/dist/src/core/git-audit.js.map +1 -0
- package/dist/src/core/github/remote-audit.d.ts +5 -0
- package/dist/src/core/github/remote-audit.js +28 -0
- package/dist/src/core/github/remote-audit.js.map +1 -0
- package/dist/src/core/github/upgrade-pr.d.ts +4 -0
- package/dist/src/core/github/upgrade-pr.js +41 -0
- package/dist/src/core/github/upgrade-pr.js.map +1 -0
- package/dist/src/core/history/git-metadata.d.ts +5 -0
- package/dist/src/core/history/git-metadata.js +37 -0
- package/dist/src/core/history/git-metadata.js.map +1 -0
- package/dist/src/core/history/store.d.ts +5 -0
- package/dist/src/core/history/store.js +65 -0
- package/dist/src/core/history/store.js.map +1 -0
- package/dist/src/core/history/types.d.ts +27 -0
- package/dist/src/core/history/types.js +2 -0
- package/dist/src/core/history/types.js.map +1 -0
- package/dist/src/core/hooks.d.ts +1 -0
- package/dist/src/core/hooks.js +14 -0
- package/dist/src/core/hooks.js.map +1 -0
- package/dist/src/core/learn.d.ts +11 -0
- package/dist/src/core/learn.js +163 -0
- package/dist/src/core/learn.js.map +1 -0
- package/dist/src/core/license-analysis.d.ts +18 -0
- package/dist/src/core/license-analysis.js +98 -0
- package/dist/src/core/license-analysis.js.map +1 -0
- package/dist/src/core/load-toolip-ignore.d.ts +5 -0
- package/dist/src/core/load-toolip-ignore.js +35 -0
- package/dist/src/core/load-toolip-ignore.js.map +1 -0
- package/dist/src/core/monorepo/discover.d.ts +7 -0
- package/dist/src/core/monorepo/discover.js +49 -0
- package/dist/src/core/monorepo/discover.js.map +1 -0
- package/dist/src/core/npm-registry.d.ts +3 -0
- package/dist/src/core/npm-registry.js +5 -0
- package/dist/src/core/npm-registry.js.map +1 -0
- package/dist/src/core/pre-commit.d.ts +11 -0
- package/dist/src/core/pre-commit.js +22 -0
- package/dist/src/core/pre-commit.js.map +1 -0
- package/dist/src/core/profile-project.d.ts +23 -0
- package/dist/src/core/profile-project.js +119 -0
- package/dist/src/core/profile-project.js.map +1 -0
- package/dist/src/core/publish/html.d.ts +6 -0
- package/dist/src/core/publish/html.js +44 -0
- package/dist/src/core/publish/html.js.map +1 -0
- package/dist/src/core/read-dependencies.d.ts +2 -0
- package/dist/src/core/read-dependencies.js +24 -0
- package/dist/src/core/read-dependencies.js.map +1 -0
- package/dist/src/core/report-writer.d.ts +5 -0
- package/dist/src/core/report-writer.js +61 -0
- package/dist/src/core/report-writer.js.map +1 -0
- package/dist/src/core/report.d.ts +34 -0
- package/dist/src/core/report.js +26 -0
- package/dist/src/core/report.js.map +1 -0
- package/dist/src/core/risk-score.d.ts +5 -0
- package/dist/src/core/risk-score.js +14 -0
- package/dist/src/core/risk-score.js.map +1 -0
- package/dist/src/core/sbom/generate.d.ts +2 -0
- package/dist/src/core/sbom/generate.js +120 -0
- package/dist/src/core/sbom/generate.js.map +1 -0
- package/dist/src/core/scanner-context.d.ts +12 -0
- package/dist/src/core/scanner-context.js +27 -0
- package/dist/src/core/scanner-context.js.map +1 -0
- package/dist/src/core/score.d.ts +13 -0
- package/dist/src/core/score.js +44 -0
- package/dist/src/core/score.js.map +1 -0
- package/dist/src/core/security-doctor.d.ts +12 -0
- package/dist/src/core/security-doctor.js +158 -0
- package/dist/src/core/security-doctor.js.map +1 -0
- package/dist/src/core/security-patterns.d.ts +14 -0
- package/dist/src/core/security-patterns.js +139 -0
- package/dist/src/core/security-patterns.js.map +1 -0
- package/dist/src/core/typosquat.d.ts +6 -0
- package/dist/src/core/typosquat.js +50 -0
- package/dist/src/core/typosquat.js.map +1 -0
- package/dist/src/core/vault.d.ts +48 -0
- package/dist/src/core/vault.js +127 -0
- package/dist/src/core/vault.js.map +1 -0
- package/dist/src/core/watch/watch.d.ts +5 -0
- package/dist/src/core/watch/watch.js +49 -0
- package/dist/src/core/watch/watch.js.map +1 -0
- package/dist/src/errors/toolip-error.d.ts +8 -0
- package/dist/src/errors/toolip-error.js +11 -0
- package/dist/src/errors/toolip-error.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +89 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +1 -0
- package/dist/src/mcp/server.js +64 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/providers/depsdev/client.d.ts +71 -0
- package/dist/src/providers/depsdev/client.js +44 -0
- package/dist/src/providers/depsdev/client.js.map +1 -0
- package/dist/src/providers/osv/client.d.ts +15 -0
- package/dist/src/providers/osv/client.js +51 -0
- package/dist/src/providers/osv/client.js.map +1 -0
- package/dist/src/providers/osv/types.d.ts +38 -0
- package/dist/src/providers/osv/types.js +2 -0
- package/dist/src/providers/osv/types.js.map +1 -0
- package/dist/src/storage/memory-cache.d.ts +7 -0
- package/dist/src/storage/memory-cache.js +25 -0
- package/dist/src/storage/memory-cache.js.map +1 -0
- package/dist/src/utils/error-handler.d.ts +1 -0
- package/dist/src/utils/error-handler.js +24 -0
- package/dist/src/utils/error-handler.js.map +1 -0
- package/dist/src/utils/output.d.ts +6 -0
- package/dist/src/utils/output.js +72 -0
- package/dist/src/utils/output.js.map +1 -0
- package/dist/src/utils/package-output.d.ts +4 -0
- package/dist/src/utils/package-output.js +40 -0
- package/dist/src/utils/package-output.js.map +1 -0
- package/package.json +13 -8
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ProjectProfile = {
|
|
2
|
+
root: string;
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
description: string;
|
|
6
|
+
packageManager: 'npm' | 'pnpm' | 'yarn' | 'unknown';
|
|
7
|
+
hasTypeScript: boolean;
|
|
8
|
+
hasJavaScript: boolean;
|
|
9
|
+
hasReact: boolean;
|
|
10
|
+
hasExpress: boolean;
|
|
11
|
+
hasFastify: boolean;
|
|
12
|
+
hasPrisma: boolean;
|
|
13
|
+
hasDocker: boolean;
|
|
14
|
+
hasVitest: boolean;
|
|
15
|
+
hasJest: boolean;
|
|
16
|
+
hasESLint: boolean;
|
|
17
|
+
hasPrettier: boolean;
|
|
18
|
+
hasGitHubActions: boolean;
|
|
19
|
+
detected: string[];
|
|
20
|
+
languages: Record<string, number>;
|
|
21
|
+
packageScripts: string[];
|
|
22
|
+
};
|
|
23
|
+
export declare function profileProject(root: string): Promise<ProjectProfile>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { access, readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { walkProjectFiles } from './file-walker.js';
|
|
4
|
+
async function fileExists(filePath) {
|
|
5
|
+
try {
|
|
6
|
+
await access(filePath);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function readPackageJson(root) {
|
|
14
|
+
const packagePath = path.join(root, 'package.json');
|
|
15
|
+
if (!(await fileExists(packagePath))) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
const raw = await readFile(packagePath, 'utf8');
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
function dependencyNames(packageJson) {
|
|
22
|
+
const dependencies = packageJson.dependencies;
|
|
23
|
+
const devDependencies = packageJson.devDependencies;
|
|
24
|
+
return [
|
|
25
|
+
...Object.keys(dependencies ?? {}),
|
|
26
|
+
...Object.keys(devDependencies ?? {})
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
function packageScripts(packageJson) {
|
|
30
|
+
const scripts = packageJson.scripts;
|
|
31
|
+
return Object.keys(scripts ?? {});
|
|
32
|
+
}
|
|
33
|
+
async function detectPackageManager(root) {
|
|
34
|
+
if (await fileExists(path.join(root, 'pnpm-lock.yaml')))
|
|
35
|
+
return 'pnpm';
|
|
36
|
+
if (await fileExists(path.join(root, 'yarn.lock')))
|
|
37
|
+
return 'yarn';
|
|
38
|
+
if (await fileExists(path.join(root, 'package-lock.json')))
|
|
39
|
+
return 'npm';
|
|
40
|
+
return 'unknown';
|
|
41
|
+
}
|
|
42
|
+
function summarizeLanguages(files) {
|
|
43
|
+
const languageMap = {
|
|
44
|
+
ts: 'TypeScript',
|
|
45
|
+
tsx: 'TypeScript React',
|
|
46
|
+
js: 'JavaScript',
|
|
47
|
+
jsx: 'JavaScript React',
|
|
48
|
+
json: 'JSON',
|
|
49
|
+
yml: 'YAML',
|
|
50
|
+
yaml: 'YAML',
|
|
51
|
+
md: 'Markdown',
|
|
52
|
+
css: 'CSS',
|
|
53
|
+
html: 'HTML',
|
|
54
|
+
env: 'Environment',
|
|
55
|
+
dockerfile: 'Docker'
|
|
56
|
+
};
|
|
57
|
+
return files.reduce((summary, file) => {
|
|
58
|
+
const extension = file.extension || file.relativePath.toLowerCase();
|
|
59
|
+
const language = languageMap[extension] ?? extension.toUpperCase();
|
|
60
|
+
summary[language] = (summary[language] ?? 0) + 1;
|
|
61
|
+
return summary;
|
|
62
|
+
}, {});
|
|
63
|
+
}
|
|
64
|
+
export async function profileProject(root) {
|
|
65
|
+
const absoluteRoot = path.resolve(root);
|
|
66
|
+
const packageJson = await readPackageJson(absoluteRoot);
|
|
67
|
+
const deps = dependencyNames(packageJson);
|
|
68
|
+
const scripts = packageScripts(packageJson);
|
|
69
|
+
const files = await walkProjectFiles(absoluteRoot);
|
|
70
|
+
const packageManager = await detectPackageManager(absoluteRoot);
|
|
71
|
+
const profile = {
|
|
72
|
+
root: absoluteRoot,
|
|
73
|
+
name: typeof packageJson.name === 'string' ? packageJson.name : 'unknown',
|
|
74
|
+
version: typeof packageJson.version === 'string' ? packageJson.version : 'unknown',
|
|
75
|
+
description: typeof packageJson.description === 'string' ? packageJson.description : '',
|
|
76
|
+
packageManager,
|
|
77
|
+
hasTypeScript: deps.includes('typescript') || await fileExists(path.join(absoluteRoot, 'tsconfig.json')),
|
|
78
|
+
hasJavaScript: files.some((file) => ['js', 'jsx'].includes(file.extension)),
|
|
79
|
+
hasReact: deps.includes('react'),
|
|
80
|
+
hasExpress: deps.includes('express'),
|
|
81
|
+
hasFastify: deps.includes('fastify'),
|
|
82
|
+
hasPrisma: deps.includes('prisma') || deps.includes('@prisma/client'),
|
|
83
|
+
hasDocker: await fileExists(path.join(absoluteRoot, 'Dockerfile')) || await fileExists(path.join(absoluteRoot, 'docker-compose.yml')),
|
|
84
|
+
hasVitest: deps.includes('vitest'),
|
|
85
|
+
hasJest: deps.includes('jest'),
|
|
86
|
+
hasESLint: deps.includes('eslint'),
|
|
87
|
+
hasPrettier: deps.includes('prettier'),
|
|
88
|
+
hasGitHubActions: await fileExists(path.join(absoluteRoot, '.github', 'workflows')),
|
|
89
|
+
detected: [],
|
|
90
|
+
languages: summarizeLanguages(files),
|
|
91
|
+
packageScripts: scripts
|
|
92
|
+
};
|
|
93
|
+
if (profile.hasTypeScript)
|
|
94
|
+
profile.detected.push('TypeScript');
|
|
95
|
+
if (profile.hasJavaScript)
|
|
96
|
+
profile.detected.push('JavaScript');
|
|
97
|
+
if (profile.hasReact)
|
|
98
|
+
profile.detected.push('React');
|
|
99
|
+
if (profile.hasExpress)
|
|
100
|
+
profile.detected.push('Express');
|
|
101
|
+
if (profile.hasFastify)
|
|
102
|
+
profile.detected.push('Fastify');
|
|
103
|
+
if (profile.hasPrisma)
|
|
104
|
+
profile.detected.push('Prisma');
|
|
105
|
+
if (profile.hasDocker)
|
|
106
|
+
profile.detected.push('Docker');
|
|
107
|
+
if (profile.hasVitest)
|
|
108
|
+
profile.detected.push('Vitest');
|
|
109
|
+
if (profile.hasJest)
|
|
110
|
+
profile.detected.push('Jest');
|
|
111
|
+
if (profile.hasESLint)
|
|
112
|
+
profile.detected.push('ESLint');
|
|
113
|
+
if (profile.hasPrettier)
|
|
114
|
+
profile.detected.push('Prettier');
|
|
115
|
+
if (profile.hasGitHubActions)
|
|
116
|
+
profile.detected.push('GitHub Actions');
|
|
117
|
+
return profile;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=profile-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-project.js","sourceRoot":"","sources":["../../../src/core/profile-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAyBpD,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAEpD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;AACpD,CAAC;AAED,SAAS,eAAe,CAAC,WAAoC;IAC3D,MAAM,YAAY,GAAG,WAAW,CAAC,YAAkD,CAAC;IACpF,MAAM,eAAe,GAAG,WAAW,CAAC,eAAqD,CAAC;IAE1F,OAAO;QACL,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QAClC,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,WAAoC;IAC1D,MAAM,OAAO,GAAG,WAAW,CAAC,OAA6C,CAAC;IAC1E,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,IAAY;IAC9C,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACvE,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAClE,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAmD;IAC7E,MAAM,WAAW,GAA2B;QAC1C,EAAE,EAAE,YAAY;QAChB,GAAG,EAAE,kBAAkB;QACvB,EAAE,EAAE,YAAY;QAChB,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,MAAM;QACX,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,UAAU;QACd,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,aAAa;QAClB,UAAU,EAAE,QAAQ;KACrB,CAAC;IAEF,OAAO,KAAK,CAAC,MAAM,CAAyB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QACpE,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;QAEnE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAEnD,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAEhE,MAAM,OAAO,GAAmB;QAC9B,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACzE,OAAO,EAAE,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;QAClF,WAAW,EAAE,OAAO,WAAW,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;QACvF,cAAc;QACd,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACxG,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3E,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAChC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACpC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACpC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QACrE,SAAS,EAAE,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;QACrI,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAClC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC9B,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAClC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtC,gBAAgB,EAAE,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACnF,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC;QACpC,cAAc,EAAE,OAAO;KACxB,CAAC;IAEF,IAAI,OAAO,CAAC,aAAa;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,aAAa;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,OAAO,CAAC,UAAU;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,UAAU;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,gBAAgB;QAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAEtE,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function escapeHtml(value) {
|
|
2
|
+
return value
|
|
3
|
+
.replaceAll('&', '&')
|
|
4
|
+
.replaceAll('<', '<')
|
|
5
|
+
.replaceAll('>', '>')
|
|
6
|
+
.replaceAll('"', '"')
|
|
7
|
+
.replaceAll("'", ''');
|
|
8
|
+
}
|
|
9
|
+
export function renderHtmlReport(input) {
|
|
10
|
+
const rows = input.findings.map((finding) => `
|
|
11
|
+
<tr>
|
|
12
|
+
<td>${escapeHtml(finding.severity)}</td>
|
|
13
|
+
<td>${escapeHtml(finding.title)}</td>
|
|
14
|
+
<td>${escapeHtml(finding.file ?? '')}</td>
|
|
15
|
+
<td>${escapeHtml(finding.recommendation)}</td>
|
|
16
|
+
</tr>
|
|
17
|
+
`).join('');
|
|
18
|
+
return `<!doctype html>
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="utf-8">
|
|
22
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
23
|
+
<title>Toolip Security Report</title>
|
|
24
|
+
<style>
|
|
25
|
+
body{font-family:system-ui,sans-serif;max-width:1100px;margin:40px auto;padding:0 20px;color:#111}
|
|
26
|
+
table{width:100%;border-collapse:collapse}
|
|
27
|
+
th,td{border:1px solid #ddd;padding:10px;text-align:left;vertical-align:top}
|
|
28
|
+
th{background:#f5f5f5}
|
|
29
|
+
code{font-family:ui-monospace,monospace}
|
|
30
|
+
</style>
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<h1>Toolip Security Report</h1>
|
|
34
|
+
<p><strong>Project:</strong> ${escapeHtml(input.project)}</p>
|
|
35
|
+
<p><strong>Generated:</strong> ${escapeHtml(input.generatedAt)}</p>
|
|
36
|
+
<p><strong>Findings:</strong> ${input.findings.length}</p>
|
|
37
|
+
<table>
|
|
38
|
+
<thead><tr><th>Severity</th><th>Finding</th><th>File</th><th>Recommendation</th></tr></thead>
|
|
39
|
+
<tbody>${rows}</tbody>
|
|
40
|
+
</table>
|
|
41
|
+
</body>
|
|
42
|
+
</html>`;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../../../src/core/publish/html.ts"],"names":[],"mappings":"AAEA,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAIhC;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;;YAEnC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC5B,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;YACzB,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;YAC9B,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC;;GAE3C,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO;;;;;;;;;;;;;;;;+BAgBsB,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;iCACvB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;gCAC9B,KAAK,CAAC,QAAQ,CAAC,MAAM;;;SAG5C,IAAI;;;QAGL,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function readDependencies(root) {
|
|
4
|
+
const packageJsonPath = path.join(root, 'package.json');
|
|
5
|
+
const raw = await readFile(packageJsonPath, 'utf8');
|
|
6
|
+
const pkg = JSON.parse(raw);
|
|
7
|
+
const results = [];
|
|
8
|
+
for (const [name, version] of Object.entries(pkg.dependencies ?? {})) {
|
|
9
|
+
results.push({
|
|
10
|
+
name,
|
|
11
|
+
version,
|
|
12
|
+
type: 'dependency'
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
for (const [name, version] of Object.entries(pkg.devDependencies ?? {})) {
|
|
16
|
+
results.push({
|
|
17
|
+
name,
|
|
18
|
+
version,
|
|
19
|
+
type: 'devDependency'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return results.sort((a, b) => a.name.localeCompare(b.name));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=read-dependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-dependencies.js","sourceRoot":"","sources":["../../../src/core/read-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAEpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAGzB,CAAC;IAEF,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ToolipReport } from './report.js';
|
|
2
|
+
export type ReportFormat = 'json' | 'md';
|
|
3
|
+
export declare function detectReportFormat(outputPath: string): ReportFormat;
|
|
4
|
+
export declare function writeReport(outputPath: string, report: ToolipReport): Promise<void>;
|
|
5
|
+
export declare function renderMarkdownReport(report: ToolipReport): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function detectReportFormat(outputPath) {
|
|
4
|
+
const extension = path.extname(outputPath).toLowerCase();
|
|
5
|
+
if (extension === '.md' || extension === '.markdown') {
|
|
6
|
+
return 'md';
|
|
7
|
+
}
|
|
8
|
+
return 'json';
|
|
9
|
+
}
|
|
10
|
+
export async function writeReport(outputPath, report) {
|
|
11
|
+
const format = detectReportFormat(outputPath);
|
|
12
|
+
if (format === 'md') {
|
|
13
|
+
await writeFile(outputPath, renderMarkdownReport(report), 'utf8');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
await writeFile(outputPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8');
|
|
17
|
+
}
|
|
18
|
+
export function renderMarkdownReport(report) {
|
|
19
|
+
const findings = report.findings.length
|
|
20
|
+
? report.findings
|
|
21
|
+
.map((finding) => {
|
|
22
|
+
const fileLine = finding.file ? `\n- File: \`${finding.file}\`` : '';
|
|
23
|
+
const evidenceLine = finding.evidence ? `\n- Evidence: \`${finding.evidence}\`` : '';
|
|
24
|
+
return `### ${finding.title}
|
|
25
|
+
|
|
26
|
+
- ID: \`${finding.id}\`
|
|
27
|
+
- Severity: **${finding.severity.toUpperCase()}**
|
|
28
|
+
- Category: ${finding.category}${fileLine}${evidenceLine}
|
|
29
|
+
|
|
30
|
+
${finding.message}
|
|
31
|
+
|
|
32
|
+
**Recommendation:** ${finding.recommendation}
|
|
33
|
+
`;
|
|
34
|
+
})
|
|
35
|
+
.join('\n')
|
|
36
|
+
: 'No findings were detected.';
|
|
37
|
+
return `# Toolip Report
|
|
38
|
+
|
|
39
|
+
Generated: ${report.generatedAt}
|
|
40
|
+
|
|
41
|
+
Root: \`${report.root}\`
|
|
42
|
+
|
|
43
|
+
Command: \`${report.command}\`
|
|
44
|
+
|
|
45
|
+
## Summary
|
|
46
|
+
|
|
47
|
+
| Severity | Count |
|
|
48
|
+
|---|---:|
|
|
49
|
+
| Critical | ${report.summary.critical} |
|
|
50
|
+
| High | ${report.summary.high} |
|
|
51
|
+
| Medium | ${report.summary.medium} |
|
|
52
|
+
| Low | ${report.summary.low} |
|
|
53
|
+
| Info | ${report.summary.info} |
|
|
54
|
+
| Total | ${report.summary.totalFindings} |
|
|
55
|
+
|
|
56
|
+
## Findings
|
|
57
|
+
|
|
58
|
+
${findings}
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=report-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-writer.js","sourceRoot":"","sources":["../../../src/core/report-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAEzD,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB,EAAE,MAAoB;IACxE,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,SAAS,CAAC,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IAED,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM;QACrC,CAAC,CAAC,MAAM,CAAC,QAAQ;aACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACf,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAErF,OAAO,OAAO,OAAO,CAAC,KAAK;;UAE3B,OAAO,CAAC,EAAE;gBACJ,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE;cAChC,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,YAAY;;EAEtD,OAAO,CAAC,OAAO;;sBAEK,OAAO,CAAC,cAAc;CAC3C,CAAC;QACM,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,4BAA4B,CAAC;IAEjC,OAAO;;aAEI,MAAM,CAAC,WAAW;;UAErB,MAAM,CAAC,IAAI;;aAER,MAAM,CAAC,OAAO;;;;;;eAMZ,MAAM,CAAC,OAAO,CAAC,QAAQ;WAC3B,MAAM,CAAC,OAAO,CAAC,IAAI;aACjB,MAAM,CAAC,OAAO,CAAC,MAAM;UACxB,MAAM,CAAC,OAAO,CAAC,GAAG;WACjB,MAAM,CAAC,OAAO,CAAC,IAAI;YAClB,MAAM,CAAC,OAAO,CAAC,aAAa;;;;EAItC,QAAQ;CACT,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type FindingSeverity = 'info' | 'low' | 'medium' | 'high' | 'critical';
|
|
2
|
+
export type ToolipFinding = {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
severity: FindingSeverity;
|
|
6
|
+
category: string;
|
|
7
|
+
message: string;
|
|
8
|
+
recommendation: string;
|
|
9
|
+
file?: string;
|
|
10
|
+
evidence?: string;
|
|
11
|
+
};
|
|
12
|
+
export type ToolipReport = {
|
|
13
|
+
tool: 'toolip';
|
|
14
|
+
version: string;
|
|
15
|
+
command: string;
|
|
16
|
+
generatedAt: string;
|
|
17
|
+
root: string;
|
|
18
|
+
summary: {
|
|
19
|
+
totalFindings: number;
|
|
20
|
+
critical: number;
|
|
21
|
+
high: number;
|
|
22
|
+
medium: number;
|
|
23
|
+
low: number;
|
|
24
|
+
info: number;
|
|
25
|
+
};
|
|
26
|
+
findings: ToolipFinding[];
|
|
27
|
+
};
|
|
28
|
+
export declare function createReport(input: {
|
|
29
|
+
version: string;
|
|
30
|
+
command: string;
|
|
31
|
+
root: string;
|
|
32
|
+
findings: ToolipFinding[];
|
|
33
|
+
}): ToolipReport;
|
|
34
|
+
export declare function summarizeFindings(findings: ToolipFinding[]): ToolipReport['summary'];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function createReport(input) {
|
|
2
|
+
return {
|
|
3
|
+
tool: 'toolip',
|
|
4
|
+
version: input.version,
|
|
5
|
+
command: input.command,
|
|
6
|
+
generatedAt: new Date().toISOString(),
|
|
7
|
+
root: input.root,
|
|
8
|
+
summary: summarizeFindings(input.findings),
|
|
9
|
+
findings: input.findings
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function summarizeFindings(findings) {
|
|
13
|
+
return findings.reduce((summary, finding) => {
|
|
14
|
+
summary.totalFindings += 1;
|
|
15
|
+
summary[finding.severity] += 1;
|
|
16
|
+
return summary;
|
|
17
|
+
}, {
|
|
18
|
+
totalFindings: 0,
|
|
19
|
+
critical: 0,
|
|
20
|
+
high: 0,
|
|
21
|
+
medium: 0,
|
|
22
|
+
low: 0,
|
|
23
|
+
info: 0
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/core/report.ts"],"names":[],"mappings":"AA8BA,MAAM,UAAU,YAAY,CAAC,KAK5B;IACC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAyB;IACzD,OAAO,QAAQ,CAAC,MAAM,CACpB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QACnB,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC,EACD;QACE,aAAa,EAAE,CAAC;QAChB,QAAQ,EAAE,CAAC;QACX,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;KACR,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function calculateRiskScore(input) {
|
|
2
|
+
let score = 0;
|
|
3
|
+
if (input.deprecated)
|
|
4
|
+
score += 40;
|
|
5
|
+
if (input.maintainers === 0)
|
|
6
|
+
score += 30;
|
|
7
|
+
else if (input.maintainers === 1)
|
|
8
|
+
score += 15;
|
|
9
|
+
if (input.ageInDays !== null && input.ageInDays > 730) {
|
|
10
|
+
score += 20;
|
|
11
|
+
}
|
|
12
|
+
return Math.min(score, 100);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=risk-score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk-score.js","sourceRoot":"","sources":["../../../src/core/risk-score.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,KAIlC;IACC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,IAAI,EAAE,CAAC;IAElC,IAAI,KAAK,CAAC,WAAW,KAAK,CAAC;QAAE,KAAK,IAAI,EAAE,CAAC;SACpC,IAAI,KAAK,CAAC,WAAW,KAAK,CAAC;QAAE,KAAK,IAAI,EAAE,CAAC;IAE9C,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;QACtD,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { readNpmDependencyInventory } from '../dependencies/inventory.js';
|
|
5
|
+
function purl(dependency) {
|
|
6
|
+
return (`pkg:npm/${encodeURIComponent(dependency.name)}@${encodeURIComponent(dependency.version)}`);
|
|
7
|
+
}
|
|
8
|
+
function bomRef(dependency) {
|
|
9
|
+
return purl(dependency);
|
|
10
|
+
}
|
|
11
|
+
function spdxId(value) {
|
|
12
|
+
return ('SPDXRef-' +
|
|
13
|
+
value.replaceAll(/[^A-Za-z0-9.-]/g, '-'));
|
|
14
|
+
}
|
|
15
|
+
function namespace(name, version) {
|
|
16
|
+
const digest = createHash('sha256')
|
|
17
|
+
.update(`${name}@${version}:${Date.now()}`)
|
|
18
|
+
.digest('hex')
|
|
19
|
+
.slice(0, 24);
|
|
20
|
+
return `https://toolip.dev/spdx/${encodeURIComponent(name)}/${version}/${digest}`;
|
|
21
|
+
}
|
|
22
|
+
export async function generateSbom(root, format) {
|
|
23
|
+
const manifest = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
|
|
24
|
+
const dependencies = await readNpmDependencyInventory(root);
|
|
25
|
+
const rootName = manifest.name ?? 'unknown-project';
|
|
26
|
+
const rootVersion = manifest.version ?? '0.0.0';
|
|
27
|
+
if (format === 'cyclonedx') {
|
|
28
|
+
return {
|
|
29
|
+
bomFormat: 'CycloneDX',
|
|
30
|
+
specVersion: '1.5',
|
|
31
|
+
serialNumber: `urn:uuid:${crypto.randomUUID()}`,
|
|
32
|
+
version: 1,
|
|
33
|
+
metadata: {
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
tools: [
|
|
36
|
+
{
|
|
37
|
+
vendor: 'Toolip',
|
|
38
|
+
name: 'toolip'
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
component: {
|
|
42
|
+
type: 'application',
|
|
43
|
+
name: rootName,
|
|
44
|
+
version: rootVersion,
|
|
45
|
+
description: manifest.description
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
components: dependencies.map((dependency) => ({
|
|
49
|
+
type: 'library',
|
|
50
|
+
'bom-ref': bomRef(dependency),
|
|
51
|
+
name: dependency.name,
|
|
52
|
+
version: dependency.version,
|
|
53
|
+
scope: dependency.development
|
|
54
|
+
? 'optional'
|
|
55
|
+
: 'required',
|
|
56
|
+
purl: purl(dependency),
|
|
57
|
+
properties: [
|
|
58
|
+
{
|
|
59
|
+
name: 'toolip:direct',
|
|
60
|
+
value: String(dependency.direct)
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'toolip:development',
|
|
64
|
+
value: String(dependency.development)
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
})),
|
|
68
|
+
dependencies: dependencies.map((dependency) => ({
|
|
69
|
+
ref: bomRef(dependency),
|
|
70
|
+
dependsOn: []
|
|
71
|
+
}))
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const documentId = 'SPDXRef-DOCUMENT';
|
|
75
|
+
const rootId = spdxId(`${rootName}-${rootVersion}`);
|
|
76
|
+
return {
|
|
77
|
+
spdxVersion: 'SPDX-2.3',
|
|
78
|
+
dataLicense: 'CC0-1.0',
|
|
79
|
+
SPDXID: documentId,
|
|
80
|
+
name: `${rootName}-${rootVersion}`,
|
|
81
|
+
documentNamespace: namespace(rootName, rootVersion),
|
|
82
|
+
creationInfo: {
|
|
83
|
+
created: new Date().toISOString(),
|
|
84
|
+
creators: ['Tool: Toolip']
|
|
85
|
+
},
|
|
86
|
+
packages: [
|
|
87
|
+
{
|
|
88
|
+
name: rootName,
|
|
89
|
+
SPDXID: rootId,
|
|
90
|
+
versionInfo: rootVersion,
|
|
91
|
+
downloadLocation: 'NOASSERTION',
|
|
92
|
+
filesAnalyzed: false,
|
|
93
|
+
licenseConcluded: manifest.license ?? 'NOASSERTION',
|
|
94
|
+
licenseDeclared: manifest.license ?? 'NOASSERTION'
|
|
95
|
+
},
|
|
96
|
+
...dependencies.map((dependency) => ({
|
|
97
|
+
name: dependency.name,
|
|
98
|
+
SPDXID: spdxId(`${dependency.name}-${dependency.version}`),
|
|
99
|
+
versionInfo: dependency.version,
|
|
100
|
+
downloadLocation: 'NOASSERTION',
|
|
101
|
+
filesAnalyzed: false,
|
|
102
|
+
licenseConcluded: 'NOASSERTION',
|
|
103
|
+
licenseDeclared: 'NOASSERTION',
|
|
104
|
+
externalRefs: [
|
|
105
|
+
{
|
|
106
|
+
referenceCategory: 'PACKAGE-MANAGER',
|
|
107
|
+
referenceType: 'purl',
|
|
108
|
+
referenceLocator: purl(dependency)
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}))
|
|
112
|
+
],
|
|
113
|
+
relationships: dependencies.map((dependency) => ({
|
|
114
|
+
spdxElementId: rootId,
|
|
115
|
+
relationshipType: 'DEPENDS_ON',
|
|
116
|
+
relatedSpdxElement: spdxId(`${dependency.name}-${dependency.version}`)
|
|
117
|
+
}))
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../src/core/sbom/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ProjectFile } from './file-walker.js';
|
|
2
|
+
import { type ProjectProfile } from './profile-project.js';
|
|
3
|
+
export type ScannerContext = {
|
|
4
|
+
root: string;
|
|
5
|
+
profile: ProjectProfile;
|
|
6
|
+
files: ProjectFile[];
|
|
7
|
+
summary: {
|
|
8
|
+
totalFiles: number;
|
|
9
|
+
extensions: Record<string, number>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export declare function createScannerContext(root: string): Promise<ScannerContext>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { walkProjectFiles } from './file-walker.js';
|
|
3
|
+
import { profileProject } from './profile-project.js';
|
|
4
|
+
function summarizeExtensions(files) {
|
|
5
|
+
return files.reduce((summary, file) => {
|
|
6
|
+
const key = file.extension || 'none';
|
|
7
|
+
summary[key] = (summary[key] ?? 0) + 1;
|
|
8
|
+
return summary;
|
|
9
|
+
}, {});
|
|
10
|
+
}
|
|
11
|
+
export async function createScannerContext(root) {
|
|
12
|
+
const absoluteRoot = path.resolve(root);
|
|
13
|
+
const [profile, files] = await Promise.all([
|
|
14
|
+
profileProject(absoluteRoot),
|
|
15
|
+
walkProjectFiles(absoluteRoot)
|
|
16
|
+
]);
|
|
17
|
+
return {
|
|
18
|
+
root: absoluteRoot,
|
|
19
|
+
profile,
|
|
20
|
+
files,
|
|
21
|
+
summary: {
|
|
22
|
+
totalFiles: files.length,
|
|
23
|
+
extensions: summarizeExtensions(files)
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=scanner-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner-context.js","sourceRoot":"","sources":["../../../src/core/scanner-context.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAoB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAY3E,SAAS,mBAAmB,CAAC,KAAoB;IAC/C,OAAO,KAAK,CAAC,MAAM,CAAyB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,cAAc,CAAC,YAAY,CAAC;QAC5B,gBAAgB,CAAC,YAAY,CAAC;KAC/B,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,OAAO;QACP,KAAK;QACL,OAAO,EAAE;YACP,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC;SACvC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolipFinding } from './report.js';
|
|
2
|
+
export type ScoreGrade = 'A' | 'B' | 'C' | 'D' | 'F';
|
|
3
|
+
export type ToolipScore = {
|
|
4
|
+
dependencyHealth: number;
|
|
5
|
+
secretHygiene: number;
|
|
6
|
+
configurationSecurity: number;
|
|
7
|
+
gitSafety: number;
|
|
8
|
+
overall: number;
|
|
9
|
+
grade: ScoreGrade;
|
|
10
|
+
};
|
|
11
|
+
export declare function calculateScore(input?: Partial<Omit<ToolipScore, 'overall' | 'grade'>>): ToolipScore;
|
|
12
|
+
export declare function calculateDependencyHealth(findings: ToolipFinding[]): number;
|
|
13
|
+
export declare function gradeScore(score: number): ScoreGrade;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function calculateScore(input) {
|
|
2
|
+
const dependencyHealth = clamp(input?.dependencyHealth ?? 100);
|
|
3
|
+
const secretHygiene = clamp(input?.secretHygiene ?? 100);
|
|
4
|
+
const configurationSecurity = clamp(input?.configurationSecurity ?? 100);
|
|
5
|
+
const gitSafety = clamp(input?.gitSafety ?? 100);
|
|
6
|
+
const overall = Math.round((dependencyHealth + secretHygiene + configurationSecurity + gitSafety) / 4);
|
|
7
|
+
return {
|
|
8
|
+
dependencyHealth,
|
|
9
|
+
secretHygiene,
|
|
10
|
+
configurationSecurity,
|
|
11
|
+
gitSafety,
|
|
12
|
+
overall,
|
|
13
|
+
grade: gradeScore(overall)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function calculateDependencyHealth(findings) {
|
|
17
|
+
const penalty = findings.reduce((total, finding) => {
|
|
18
|
+
if (finding.severity === 'critical')
|
|
19
|
+
return total + 35;
|
|
20
|
+
if (finding.severity === 'high')
|
|
21
|
+
return total + 25;
|
|
22
|
+
if (finding.severity === 'medium')
|
|
23
|
+
return total + 12;
|
|
24
|
+
if (finding.severity === 'low')
|
|
25
|
+
return total + 5;
|
|
26
|
+
return total + 0;
|
|
27
|
+
}, 0);
|
|
28
|
+
return clamp(100 - penalty);
|
|
29
|
+
}
|
|
30
|
+
function clamp(value) {
|
|
31
|
+
return Math.max(0, Math.min(100, Math.round(value)));
|
|
32
|
+
}
|
|
33
|
+
export function gradeScore(score) {
|
|
34
|
+
if (score >= 90)
|
|
35
|
+
return 'A';
|
|
36
|
+
if (score >= 80)
|
|
37
|
+
return 'B';
|
|
38
|
+
if (score >= 70)
|
|
39
|
+
return 'C';
|
|
40
|
+
if (score >= 60)
|
|
41
|
+
return 'D';
|
|
42
|
+
return 'F';
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=score.js.map
|