signal-codec 1.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/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/checker.d.ts +30 -0
- package/dist/checker.js +69 -0
- package/dist/checker.test.d.ts +1 -0
- package/dist/checker.test.js +85 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +26 -0
- package/dist/codec-verifier.d.ts +30 -0
- package/dist/codec-verifier.js +69 -0
- package/dist/codec-verifier.test.d.ts +1 -0
- package/dist/codec-verifier.test.js +85 -0
- package/dist/fragment-scanner.d.ts +39 -0
- package/dist/fragment-scanner.js +150 -0
- package/dist/fragment-scanner.test.d.ts +1 -0
- package/dist/fragment-scanner.test.js +55 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +110 -0
- package/dist/matrix.d.ts +35 -0
- package/dist/matrix.js +80 -0
- package/dist/matrix.test.d.ts +1 -0
- package/dist/matrix.test.js +68 -0
- package/dist/protocol-reporter.d.ts +34 -0
- package/dist/protocol-reporter.js +107 -0
- package/dist/protocol-reporter.test.d.ts +1 -0
- package/dist/protocol-reporter.test.js +82 -0
- package/dist/reporter.d.ts +34 -0
- package/dist/reporter.js +104 -0
- package/dist/reporter.test.d.ts +1 -0
- package/dist/reporter.test.js +82 -0
- package/dist/scanner.d.ts +39 -0
- package/dist/scanner.js +150 -0
- package/dist/scanner.test.d.ts +1 -0
- package/dist/scanner.test.js +55 -0
- package/package.json +62 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CheckResult, CompatibilityIssue } from './codec-verifier';
|
|
2
|
+
/**
|
|
3
|
+
* Reporter for formatted output
|
|
4
|
+
*/
|
|
5
|
+
export declare class Reporter {
|
|
6
|
+
/**
|
|
7
|
+
* Print a colored header
|
|
8
|
+
*/
|
|
9
|
+
private printHeader;
|
|
10
|
+
/**
|
|
11
|
+
* Print colored error message
|
|
12
|
+
*/
|
|
13
|
+
private printError;
|
|
14
|
+
/**
|
|
15
|
+
* Print colored warning message
|
|
16
|
+
*/
|
|
17
|
+
private printWarning;
|
|
18
|
+
/**
|
|
19
|
+
* Format codec analysis summary
|
|
20
|
+
*/
|
|
21
|
+
formatSummary(result: CheckResult): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format issues as a table
|
|
24
|
+
*/
|
|
25
|
+
formatTable(issues: CompatibilityIssue[]): string;
|
|
26
|
+
/**
|
|
27
|
+
* Format detailed report with mythology terminology
|
|
28
|
+
*/
|
|
29
|
+
formatDetailed(result: CheckResult): string;
|
|
30
|
+
/**
|
|
31
|
+
* Format JSON output
|
|
32
|
+
*/
|
|
33
|
+
formatJson(result: CheckResult): string;
|
|
34
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Reporter = void 0;
|
|
7
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
8
|
+
/**
|
|
9
|
+
* Reporter for formatted output
|
|
10
|
+
*/
|
|
11
|
+
class Reporter {
|
|
12
|
+
/**
|
|
13
|
+
* Print a colored header
|
|
14
|
+
*/
|
|
15
|
+
printHeader(text) {
|
|
16
|
+
return `\x1b[1m\x1b[36m${text}\x1b[0m`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Print colored error message
|
|
20
|
+
*/
|
|
21
|
+
printError(text) {
|
|
22
|
+
return `\x1b[31m✗\x1b[0m ${text}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Print colored warning message
|
|
26
|
+
*/
|
|
27
|
+
printWarning(text) {
|
|
28
|
+
return `\x1b[33m⚠\x1b[0m ${text}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format codec analysis summary
|
|
32
|
+
*/
|
|
33
|
+
formatSummary(result) {
|
|
34
|
+
let output = '';
|
|
35
|
+
output += `\n◆ \x1b[1m\x1b[38;5;208mSIGNAL-CODEC\x1b[0m — Transmission Protocol Analysis\n`;
|
|
36
|
+
output += `────────────────────────────────────────────\n\n`;
|
|
37
|
+
output += `Archive Codec: ${result.projectLicense}\n`;
|
|
38
|
+
output += `Fragments Analyzed: ${result.totalDependencies}\n`;
|
|
39
|
+
output += `Codec Conflicts: ${result.issues.length}\n\n`;
|
|
40
|
+
if (result.issues.length === 0) {
|
|
41
|
+
output += `\x1b[32m✓\x1b[0m All fragments use interoperable codecs\n`;
|
|
42
|
+
return output;
|
|
43
|
+
}
|
|
44
|
+
output += `${this.printWarning(`${result.issues.length} transmission protocol conflict${result.issues.length > 1 ? 's' : ''} detected`)}\n`;
|
|
45
|
+
return output;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Format issues as a table
|
|
49
|
+
*/
|
|
50
|
+
formatTable(issues) {
|
|
51
|
+
if (issues.length === 0) {
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
const table = new cli_table3_1.default({
|
|
55
|
+
head: ['Fragment', 'Codec', 'Conflict'].map((h) => `\x1b[1m${h}\x1b[0m`),
|
|
56
|
+
style: {
|
|
57
|
+
head: [],
|
|
58
|
+
border: ['cyan'],
|
|
59
|
+
},
|
|
60
|
+
colWidths: [25, 20, 50],
|
|
61
|
+
wordWrap: true,
|
|
62
|
+
});
|
|
63
|
+
for (const issue of issues) {
|
|
64
|
+
const severity = issue.severity === 'error'
|
|
65
|
+
? `\x1b[31m${issue.severity}\x1b[0m`
|
|
66
|
+
: issue.severity === 'warning'
|
|
67
|
+
? `\x1b[33m${issue.severity}\x1b[0m`
|
|
68
|
+
: `\x1b[36m${issue.severity}\x1b[0m`;
|
|
69
|
+
table.push([issue.package, issue.license, `[${severity}] ${issue.message}`]);
|
|
70
|
+
}
|
|
71
|
+
return table.toString();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Format detailed report with mythology terminology
|
|
75
|
+
*/
|
|
76
|
+
formatDetailed(result) {
|
|
77
|
+
let output = this.formatSummary(result);
|
|
78
|
+
if (result.issues.length > 0) {
|
|
79
|
+
output += '\n' + this.printHeader('Codec Conflicts') + '\n\n';
|
|
80
|
+
output += this.formatTable(result.issues);
|
|
81
|
+
output += '\n';
|
|
82
|
+
}
|
|
83
|
+
const errorCount = result.summary.errors;
|
|
84
|
+
const warningCount = result.summary.warnings + result.summary.info;
|
|
85
|
+
if (errorCount > 0) {
|
|
86
|
+
output += `\n${this.printError(`${errorCount} incompatible codec${errorCount > 1 ? 's' : ''}`)}\n`;
|
|
87
|
+
}
|
|
88
|
+
if (warningCount > 0) {
|
|
89
|
+
output += `${this.printWarning(`${warningCount} unverified codec${warningCount > 1 ? 's' : ''}`)}\n`;
|
|
90
|
+
}
|
|
91
|
+
if (result.summary.errors === 0 && result.issues.length > 0) {
|
|
92
|
+
output += `\n${this.printWarning('Signal integrity compromised • Review required')}\n`;
|
|
93
|
+
}
|
|
94
|
+
else if (result.summary.errors === 0 && result.issues.length === 0) {
|
|
95
|
+
output += `Signal integrity maintained • Amulet Digital Archive Protocol\n`;
|
|
96
|
+
}
|
|
97
|
+
output += '\n';
|
|
98
|
+
return output;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Format JSON output
|
|
102
|
+
*/
|
|
103
|
+
formatJson(result) {
|
|
104
|
+
return JSON.stringify(result, null, 2);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.Reporter = Reporter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const protocol_reporter_1 = require("./protocol-reporter");
|
|
4
|
+
describe('Reporter', () => {
|
|
5
|
+
let reporter;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
reporter = new protocol_reporter_1.Reporter();
|
|
8
|
+
});
|
|
9
|
+
describe('formatSummary', () => {
|
|
10
|
+
it('should include project license and count', () => {
|
|
11
|
+
const result = {
|
|
12
|
+
projectLicense: 'MIT',
|
|
13
|
+
totalDependencies: 10,
|
|
14
|
+
issues: [],
|
|
15
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
16
|
+
};
|
|
17
|
+
const output = reporter.formatSummary(result);
|
|
18
|
+
expect(output).toContain('MIT');
|
|
19
|
+
expect(output).toContain('10');
|
|
20
|
+
});
|
|
21
|
+
it('should show success for no issues', () => {
|
|
22
|
+
const result = {
|
|
23
|
+
projectLicense: 'MIT',
|
|
24
|
+
totalDependencies: 5,
|
|
25
|
+
issues: [],
|
|
26
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
27
|
+
};
|
|
28
|
+
const output = reporter.formatSummary(result);
|
|
29
|
+
expect(output).toContain('interoperable');
|
|
30
|
+
});
|
|
31
|
+
it('should warn when issues found', () => {
|
|
32
|
+
const result = {
|
|
33
|
+
projectLicense: 'MIT',
|
|
34
|
+
totalDependencies: 5,
|
|
35
|
+
issues: [
|
|
36
|
+
{
|
|
37
|
+
package: 'test',
|
|
38
|
+
license: 'GPL-3.0',
|
|
39
|
+
severity: 'error',
|
|
40
|
+
message: 'test',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
summary: { errors: 1, warnings: 0, info: 0 },
|
|
44
|
+
};
|
|
45
|
+
const output = reporter.formatSummary(result);
|
|
46
|
+
expect(output).toContain('transmission protocol conflict');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('formatTable', () => {
|
|
50
|
+
it('should return empty string for no issues', () => {
|
|
51
|
+
const output = reporter.formatTable([]);
|
|
52
|
+
expect(output).toBe('');
|
|
53
|
+
});
|
|
54
|
+
it('should create table with issues', () => {
|
|
55
|
+
const issues = [
|
|
56
|
+
{
|
|
57
|
+
package: 'test-lib',
|
|
58
|
+
license: 'GPL-3.0',
|
|
59
|
+
severity: 'error',
|
|
60
|
+
message: 'GPL not compatible with MIT',
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
const output = reporter.formatTable(issues);
|
|
64
|
+
expect(output).toContain('test-lib');
|
|
65
|
+
expect(output).toContain('GPL-3.0');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('formatJson', () => {
|
|
69
|
+
it('should output valid JSON', () => {
|
|
70
|
+
const result = {
|
|
71
|
+
projectLicense: 'MIT',
|
|
72
|
+
totalDependencies: 5,
|
|
73
|
+
issues: [],
|
|
74
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
75
|
+
};
|
|
76
|
+
const output = reporter.formatJson(result);
|
|
77
|
+
const parsed = JSON.parse(output);
|
|
78
|
+
expect(parsed.projectLicense).toBe('MIT');
|
|
79
|
+
expect(parsed.totalDependencies).toBe(5);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CheckResult, CompatibilityIssue } from './checker';
|
|
2
|
+
/**
|
|
3
|
+
* Reporter for formatted output
|
|
4
|
+
*/
|
|
5
|
+
export declare class Reporter {
|
|
6
|
+
/**
|
|
7
|
+
* Print a colored header
|
|
8
|
+
*/
|
|
9
|
+
private printHeader;
|
|
10
|
+
/**
|
|
11
|
+
* Print colored error message
|
|
12
|
+
*/
|
|
13
|
+
private printError;
|
|
14
|
+
/**
|
|
15
|
+
* Print colored warning message
|
|
16
|
+
*/
|
|
17
|
+
private printWarning;
|
|
18
|
+
/**
|
|
19
|
+
* Format license summary
|
|
20
|
+
*/
|
|
21
|
+
formatSummary(result: CheckResult): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format issues as a table
|
|
24
|
+
*/
|
|
25
|
+
formatTable(issues: CompatibilityIssue[]): string;
|
|
26
|
+
/**
|
|
27
|
+
* Format detailed report
|
|
28
|
+
*/
|
|
29
|
+
formatDetailed(result: CheckResult): string;
|
|
30
|
+
/**
|
|
31
|
+
* Format JSON output
|
|
32
|
+
*/
|
|
33
|
+
formatJson(result: CheckResult): string;
|
|
34
|
+
}
|
package/dist/reporter.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Reporter = void 0;
|
|
7
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
8
|
+
/**
|
|
9
|
+
* Reporter for formatted output
|
|
10
|
+
*/
|
|
11
|
+
class Reporter {
|
|
12
|
+
/**
|
|
13
|
+
* Print a colored header
|
|
14
|
+
*/
|
|
15
|
+
printHeader(text) {
|
|
16
|
+
return `\x1b[1m\x1b[36m${text}\x1b[0m`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Print colored error message
|
|
20
|
+
*/
|
|
21
|
+
printError(text) {
|
|
22
|
+
return `\x1b[31m✗\x1b[0m ${text}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Print colored warning message
|
|
26
|
+
*/
|
|
27
|
+
printWarning(text) {
|
|
28
|
+
return `\x1b[33m⚠\x1b[0m ${text}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format license summary
|
|
32
|
+
*/
|
|
33
|
+
formatSummary(result) {
|
|
34
|
+
let output = '';
|
|
35
|
+
output += `\n${this.printHeader('License Guard Report')}\n\n`;
|
|
36
|
+
output += `Project License: ${result.projectLicense}\n`;
|
|
37
|
+
output += `Dependencies Checked: ${result.totalDependencies}\n`;
|
|
38
|
+
output += `Issues Found: ${result.issues.length}\n\n`;
|
|
39
|
+
if (result.issues.length === 0) {
|
|
40
|
+
output += `\x1b[32m✓\x1b[0m All licenses are compatible!\n`;
|
|
41
|
+
return output;
|
|
42
|
+
}
|
|
43
|
+
output += `${this.printWarning(`${result.issues.length} potential compatibility issues found`)}\n`;
|
|
44
|
+
return output;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Format issues as a table
|
|
48
|
+
*/
|
|
49
|
+
formatTable(issues) {
|
|
50
|
+
if (issues.length === 0) {
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
const table = new cli_table3_1.default({
|
|
54
|
+
head: ['Package', 'License', 'Issue'].map((h) => `\x1b[1m${h}\x1b[0m`),
|
|
55
|
+
style: {
|
|
56
|
+
head: [],
|
|
57
|
+
border: ['cyan'],
|
|
58
|
+
},
|
|
59
|
+
colWidths: [25, 20, 50],
|
|
60
|
+
wordWrap: true,
|
|
61
|
+
});
|
|
62
|
+
for (const issue of issues) {
|
|
63
|
+
const severity = issue.severity === 'error'
|
|
64
|
+
? `\x1b[31m${issue.severity}\x1b[0m`
|
|
65
|
+
: issue.severity === 'warning'
|
|
66
|
+
? `\x1b[33m${issue.severity}\x1b[0m`
|
|
67
|
+
: `\x1b[36m${issue.severity}\x1b[0m`;
|
|
68
|
+
table.push([issue.package, issue.license, `[${severity}] ${issue.message}`]);
|
|
69
|
+
}
|
|
70
|
+
return table.toString();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format detailed report
|
|
74
|
+
*/
|
|
75
|
+
formatDetailed(result) {
|
|
76
|
+
let output = this.formatSummary(result);
|
|
77
|
+
if (result.issues.length > 0) {
|
|
78
|
+
output += '\n' + this.printHeader('Compatibility Issues') + '\n\n';
|
|
79
|
+
output += this.formatTable(result.issues);
|
|
80
|
+
output += '\n';
|
|
81
|
+
}
|
|
82
|
+
if (result.summary.errors > 0) {
|
|
83
|
+
output += `\n${this.printError(`Found ${result.summary.errors} error(s)`)}\n`;
|
|
84
|
+
}
|
|
85
|
+
if (result.summary.warnings > 0) {
|
|
86
|
+
output += `${this.printWarning(`Found ${result.summary.warnings} warning(s)`)}\n`;
|
|
87
|
+
}
|
|
88
|
+
if (result.summary.info > 0) {
|
|
89
|
+
output += `${this.printWarning(`Found ${result.summary.info} info message(s)`)}\n`;
|
|
90
|
+
}
|
|
91
|
+
if (result.summary.errors === 0 && result.issues.length > 0) {
|
|
92
|
+
output += `\n${this.printWarning('Review warnings above for compliance')}\n`;
|
|
93
|
+
}
|
|
94
|
+
output += '\n';
|
|
95
|
+
return output;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Format JSON output
|
|
99
|
+
*/
|
|
100
|
+
formatJson(result) {
|
|
101
|
+
return JSON.stringify(result, null, 2);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.Reporter = Reporter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const reporter_1 = require("./reporter");
|
|
4
|
+
describe('Reporter', () => {
|
|
5
|
+
let reporter;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
reporter = new reporter_1.Reporter();
|
|
8
|
+
});
|
|
9
|
+
describe('formatSummary', () => {
|
|
10
|
+
it('should include project license and count', () => {
|
|
11
|
+
const result = {
|
|
12
|
+
projectLicense: 'MIT',
|
|
13
|
+
totalDependencies: 10,
|
|
14
|
+
issues: [],
|
|
15
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
16
|
+
};
|
|
17
|
+
const output = reporter.formatSummary(result);
|
|
18
|
+
expect(output).toContain('MIT');
|
|
19
|
+
expect(output).toContain('10');
|
|
20
|
+
});
|
|
21
|
+
it('should show success for no issues', () => {
|
|
22
|
+
const result = {
|
|
23
|
+
projectLicense: 'MIT',
|
|
24
|
+
totalDependencies: 5,
|
|
25
|
+
issues: [],
|
|
26
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
27
|
+
};
|
|
28
|
+
const output = reporter.formatSummary(result);
|
|
29
|
+
expect(output).toContain('compatible');
|
|
30
|
+
});
|
|
31
|
+
it('should warn when issues found', () => {
|
|
32
|
+
const result = {
|
|
33
|
+
projectLicense: 'MIT',
|
|
34
|
+
totalDependencies: 5,
|
|
35
|
+
issues: [
|
|
36
|
+
{
|
|
37
|
+
package: 'test',
|
|
38
|
+
license: 'GPL-3.0',
|
|
39
|
+
severity: 'error',
|
|
40
|
+
message: 'test',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
summary: { errors: 1, warnings: 0, info: 0 },
|
|
44
|
+
};
|
|
45
|
+
const output = reporter.formatSummary(result);
|
|
46
|
+
expect(output).toContain('compatibility issues');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('formatTable', () => {
|
|
50
|
+
it('should return empty string for no issues', () => {
|
|
51
|
+
const output = reporter.formatTable([]);
|
|
52
|
+
expect(output).toBe('');
|
|
53
|
+
});
|
|
54
|
+
it('should create table with issues', () => {
|
|
55
|
+
const issues = [
|
|
56
|
+
{
|
|
57
|
+
package: 'test-lib',
|
|
58
|
+
license: 'GPL-3.0',
|
|
59
|
+
severity: 'error',
|
|
60
|
+
message: 'GPL not compatible with MIT',
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
const output = reporter.formatTable(issues);
|
|
64
|
+
expect(output).toContain('test-lib');
|
|
65
|
+
expect(output).toContain('GPL-3.0');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('formatJson', () => {
|
|
69
|
+
it('should output valid JSON', () => {
|
|
70
|
+
const result = {
|
|
71
|
+
projectLicense: 'MIT',
|
|
72
|
+
totalDependencies: 5,
|
|
73
|
+
issues: [],
|
|
74
|
+
summary: { errors: 0, warnings: 0, info: 0 },
|
|
75
|
+
};
|
|
76
|
+
const output = reporter.formatJson(result);
|
|
77
|
+
const parsed = JSON.parse(output);
|
|
78
|
+
expect(parsed.projectLicense).toBe('MIT');
|
|
79
|
+
expect(parsed.totalDependencies).toBe(5);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface DependencyInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
license: string;
|
|
5
|
+
location: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PackageJson {
|
|
8
|
+
name?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
license?: string;
|
|
11
|
+
dependencies?: Record<string, string>;
|
|
12
|
+
devDependencies?: Record<string, string>;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Scanner for collecting dependency licenses
|
|
17
|
+
*/
|
|
18
|
+
export declare class Scanner {
|
|
19
|
+
/**
|
|
20
|
+
* Load package.json from a directory
|
|
21
|
+
*/
|
|
22
|
+
loadPackageJson(projectRoot: string): PackageJson;
|
|
23
|
+
/**
|
|
24
|
+
* Extract all dependencies from package.json
|
|
25
|
+
*/
|
|
26
|
+
extractDependencies(pkg: PackageJson): Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* Get license for a specific dependency
|
|
29
|
+
*/
|
|
30
|
+
private getLicenseFromPackageJson;
|
|
31
|
+
/**
|
|
32
|
+
* Scan node_modules for all installed dependencies and their licenses
|
|
33
|
+
*/
|
|
34
|
+
scanDependencies(projectRoot: string): DependencyInfo[];
|
|
35
|
+
/**
|
|
36
|
+
* Recursively scan for transitive dependencies
|
|
37
|
+
*/
|
|
38
|
+
private scanTransitiveDeps;
|
|
39
|
+
}
|
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Scanner = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
/**
|
|
40
|
+
* Scanner for collecting dependency licenses
|
|
41
|
+
*/
|
|
42
|
+
class Scanner {
|
|
43
|
+
/**
|
|
44
|
+
* Load package.json from a directory
|
|
45
|
+
*/
|
|
46
|
+
loadPackageJson(projectRoot) {
|
|
47
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
48
|
+
if (!fs.existsSync(pkgPath)) {
|
|
49
|
+
throw new Error('package.json not found');
|
|
50
|
+
}
|
|
51
|
+
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
52
|
+
return JSON.parse(content);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract all dependencies from package.json
|
|
56
|
+
*/
|
|
57
|
+
extractDependencies(pkg) {
|
|
58
|
+
const deps = {};
|
|
59
|
+
if (pkg.dependencies) {
|
|
60
|
+
Object.assign(deps, pkg.dependencies);
|
|
61
|
+
}
|
|
62
|
+
if (pkg.devDependencies) {
|
|
63
|
+
Object.assign(deps, pkg.devDependencies);
|
|
64
|
+
}
|
|
65
|
+
return deps;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get license for a specific dependency
|
|
69
|
+
*/
|
|
70
|
+
getLicenseFromPackageJson(depPath) {
|
|
71
|
+
try {
|
|
72
|
+
const pkgPath = path.join(depPath, 'package.json');
|
|
73
|
+
if (!fs.existsSync(pkgPath)) {
|
|
74
|
+
return 'UNKNOWN';
|
|
75
|
+
}
|
|
76
|
+
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
77
|
+
const pkg = JSON.parse(content);
|
|
78
|
+
return pkg.license || 'UNKNOWN';
|
|
79
|
+
}
|
|
80
|
+
catch (_a) {
|
|
81
|
+
return 'UNKNOWN';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Scan node_modules for all installed dependencies and their licenses
|
|
86
|
+
*/
|
|
87
|
+
scanDependencies(projectRoot) {
|
|
88
|
+
const nodeModulesPath = path.join(projectRoot, 'node_modules');
|
|
89
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
90
|
+
throw new Error('node_modules not found. Run npm install first.');
|
|
91
|
+
}
|
|
92
|
+
const dependencies = [];
|
|
93
|
+
const pkg = this.loadPackageJson(projectRoot);
|
|
94
|
+
const allDeps = this.extractDependencies(pkg);
|
|
95
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
96
|
+
const depPath = path.join(nodeModulesPath, name);
|
|
97
|
+
const license = this.getLicenseFromPackageJson(depPath);
|
|
98
|
+
dependencies.push({
|
|
99
|
+
name,
|
|
100
|
+
version,
|
|
101
|
+
license,
|
|
102
|
+
location: depPath,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Also scan transitive dependencies (nested in node_modules)
|
|
106
|
+
this.scanTransitiveDeps(nodeModulesPath, dependencies);
|
|
107
|
+
return dependencies;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Recursively scan for transitive dependencies
|
|
111
|
+
*/
|
|
112
|
+
scanTransitiveDeps(nodeModulesPath, dependencies, visited = new Set()) {
|
|
113
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const entries = fs.readdirSync(nodeModulesPath);
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
if (entry.startsWith('.'))
|
|
119
|
+
continue;
|
|
120
|
+
const entryPath = path.join(nodeModulesPath, entry);
|
|
121
|
+
const stat = fs.statSync(entryPath);
|
|
122
|
+
if (!stat.isDirectory())
|
|
123
|
+
continue;
|
|
124
|
+
const pkgPath = path.join(entryPath, 'package.json');
|
|
125
|
+
if (!fs.existsSync(pkgPath))
|
|
126
|
+
continue;
|
|
127
|
+
const normalized = path.normalize(entryPath);
|
|
128
|
+
if (visited.has(normalized))
|
|
129
|
+
continue;
|
|
130
|
+
visited.add(normalized);
|
|
131
|
+
try {
|
|
132
|
+
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
133
|
+
const pkg = JSON.parse(content);
|
|
134
|
+
// Only add if not already scanned
|
|
135
|
+
if (!dependencies.some((d) => d.name === entry)) {
|
|
136
|
+
dependencies.push({
|
|
137
|
+
name: entry,
|
|
138
|
+
version: pkg.version || 'unknown',
|
|
139
|
+
license: pkg.license || 'UNKNOWN',
|
|
140
|
+
location: entryPath,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (_a) {
|
|
145
|
+
// Skip packages that can't be parsed
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.Scanner = Scanner;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|