@callstack/licenses 0.2.2 → 0.3.1
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 +1 -1
- package/build/constants/index.d.ts +1 -0
- package/build/constants/index.js +17 -0
- package/build/constants/licenses.d.ts +7 -0
- package/build/constants/licenses.js +53 -0
- package/build/index.d.ts +2 -1
- package/build/index.js +5 -4
- package/build/licenses/LicenseCategory.d.ts +6 -0
- package/build/licenses/LicenseCategory.js +10 -0
- package/build/licenses/descriptions.d.ts +16 -0
- package/build/licenses/descriptions.js +53 -0
- package/build/licenses/index.d.ts +3 -0
- package/build/licenses/index.js +19 -0
- package/build/licenses/licenseAnalysis.d.ts +15 -0
- package/build/licenses/licenseAnalysis.js +65 -0
- package/build/{common.d.ts → node/common.d.ts} +6 -6
- package/build/{common.js → node/common.js} +108 -60
- package/build/node/index.d.ts +3 -0
- package/build/node/index.js +19 -0
- package/build/node/utils/index.d.ts +2 -0
- package/build/node/utils/index.js +38 -0
- package/build/{utils → node/utils}/packageUtils.d.ts +2 -2
- package/build/{utils → node/utils}/packageUtils.js +1 -1
- package/build/types/AggregatedLicensesMapping.d.ts +6 -0
- package/build/types/{LicenseObj.d.ts → License.d.ts} +8 -2
- package/build/types/LicenseAnalysisResult.d.ts +5 -0
- package/build/types/LicenseAnalysisResult.js +2 -0
- package/build/types/LicenseStats.d.ts +28 -0
- package/build/types/LicenseStats.js +2 -0
- package/build/types/ParentPackageInfo.d.ts +14 -0
- package/build/types/ParentPackageInfo.js +2 -0
- package/build/types/index.d.ts +5 -2
- package/build/types/index.js +5 -2
- package/build/utils/index.d.ts +0 -2
- package/build/utils/index.js +1 -3
- package/package.json +20 -7
- package/src/constants/index.ts +1 -0
- package/src/constants/licenses.ts +58 -0
- package/src/index.ts +2 -1
- package/src/licenses/LicenseCategory.ts +6 -0
- package/src/licenses/descriptions.ts +56 -0
- package/src/licenses/index.ts +3 -0
- package/src/licenses/licenseAnalysis.ts +78 -0
- package/src/{common.ts → node/common.ts} +104 -45
- package/src/node/index.ts +3 -0
- package/src/node/utils/index.ts +2 -0
- package/src/{utils → node/utils}/packageUtils.ts +3 -3
- package/src/types/AggregatedLicensesMapping.ts +7 -0
- package/src/types/{LicenseObj.ts → License.ts} +9 -2
- package/src/types/LicenseAnalysisResult.ts +7 -0
- package/src/types/LicenseStats.ts +33 -0
- package/src/types/ParentPackageInfo.ts +16 -0
- package/src/types/index.ts +5 -2
- package/src/utils/index.ts +0 -2
- package/build/types/AggregatedLicensesObj.d.ts +0 -6
- package/src/types/AggregatedLicensesObj.ts +0 -7
- /package/build/{utils → node/utils}/miscUtils.d.ts +0 -0
- /package/build/{utils → node/utils}/miscUtils.js +0 -0
- /package/build/types/{AggregatedLicensesObj.js → AggregatedLicensesMapping.js} +0 -0
- /package/build/types/{LicenseObj.js → License.js} +0 -0
- /package/src/{utils → node/utils}/miscUtils.ts +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common"), exports);
|
|
18
|
+
__exportStar(require("./utils"), exports);
|
|
19
|
+
__exportStar(require("../"), exports);
|
|
@@ -0,0 +1,38 @@
|
|
|
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.MiscUtils = exports.PackageUtils = void 0;
|
|
37
|
+
exports.PackageUtils = __importStar(require("./packageUtils"));
|
|
38
|
+
exports.MiscUtils = __importStar(require("./miscUtils"));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { License, ScanPackageOptionsFactory } from '../../types';
|
|
2
2
|
export declare function getPackageJsonPath(dependency: string, root?: string): string | null;
|
|
3
3
|
export declare function resolvePackageJsonFromEntry(dependency: string): string | null;
|
|
4
4
|
export declare function findPackageRoot(entryPath: string): string | undefined;
|
|
5
5
|
export declare function normalizePackageName(packageName: string): string;
|
|
6
|
-
export declare function prepareAboutLibrariesLicenseField(license:
|
|
6
|
+
export declare function prepareAboutLibrariesLicenseField(license: License): string;
|
|
7
7
|
export declare function parseAuthorField(json: {
|
|
8
8
|
author: string | {
|
|
9
9
|
name: string;
|
|
@@ -14,8 +14,8 @@ exports.parseLicenseField = parseLicenseField;
|
|
|
14
14
|
exports.parseRepositoryFieldToUrl = parseRepositoryFieldToUrl;
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const repositoryUtils_1 = require("../../utils/repositoryUtils");
|
|
17
18
|
const miscUtils_1 = require("./miscUtils");
|
|
18
|
-
const repositoryUtils_1 = require("./repositoryUtils");
|
|
19
19
|
function getPackageJsonPath(dependency, root) {
|
|
20
20
|
const rootsToSearch = [
|
|
21
21
|
...(root ? [root] : []), // provided for purpose of nested node_modules resolution inside a package dir, in a subdirectory inside the root node_modules dir
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DependencyType } from './DependencyType';
|
|
2
|
+
import type { ParentPackageInfo } from './ParentPackageInfo';
|
|
2
3
|
import type { ScanPackageCallContext } from './ScanPackageCallContext';
|
|
3
|
-
export type
|
|
4
|
+
export type License = {
|
|
4
5
|
/** Package name */
|
|
5
6
|
name: string;
|
|
6
7
|
/** Package author */
|
|
@@ -21,4 +22,9 @@ export type LicenseObj = {
|
|
|
21
22
|
dependencyType: DependencyType;
|
|
22
23
|
/** The required version specified in package.json */
|
|
23
24
|
requiredVersion: string;
|
|
24
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The name(s) of the package(s) that introduced the package as a dependency (of any type);
|
|
27
|
+
* empty array if the package is a dependency of the root package
|
|
28
|
+
*/
|
|
29
|
+
parentPackages: ParentPackageInfo[];
|
|
30
|
+
} & Pick<ScanPackageCallContext, 'parentPackageRequiredVersion' | 'parentPackageResolvedVersion'>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LicenseCategory } from '../licenses/LicenseCategory';
|
|
2
|
+
export interface LicenseStats {
|
|
3
|
+
/**
|
|
4
|
+
* Total number of packages
|
|
5
|
+
*/
|
|
6
|
+
total: number;
|
|
7
|
+
/**
|
|
8
|
+
* Mapping of license category to count of packages in that category
|
|
9
|
+
*/
|
|
10
|
+
byCategory: Record<LicenseCategory, number>;
|
|
11
|
+
/**
|
|
12
|
+
* Mapping of license name to count of packages with that license
|
|
13
|
+
*/
|
|
14
|
+
byLicense: Record<string, number>;
|
|
15
|
+
/**
|
|
16
|
+
* Information about the presence of different license categories
|
|
17
|
+
*/
|
|
18
|
+
categoriesPresence: {
|
|
19
|
+
hasAnyUnknown: boolean;
|
|
20
|
+
hasAnyWeakCopyleft: boolean;
|
|
21
|
+
hasAnyStrongCopyleft: boolean;
|
|
22
|
+
hasAllPermissive: boolean;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Description of the graph state based on the license categories
|
|
26
|
+
*/
|
|
27
|
+
description: string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ParentPackageInfo = {
|
|
2
|
+
/**
|
|
3
|
+
* The name of the package
|
|
4
|
+
*/
|
|
5
|
+
name: string;
|
|
6
|
+
/**
|
|
7
|
+
* The required version, as specified in package.json
|
|
8
|
+
*/
|
|
9
|
+
requiredVersion: string;
|
|
10
|
+
/**
|
|
11
|
+
* The resolved version, as specified in package.json
|
|
12
|
+
*/
|
|
13
|
+
resolvedVersion: string;
|
|
14
|
+
};
|
package/build/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './License';
|
|
2
|
+
export * from './AggregatedLicensesMapping';
|
|
3
3
|
export * from './AboutLibrariesLibraryJsonPayload';
|
|
4
4
|
export * from './AboutLibrariesLicenseJsonPayload';
|
|
5
5
|
export * from './LicensePlistPayload';
|
|
@@ -7,3 +7,6 @@ export * from './AboutLibrariesLikePackageInfo';
|
|
|
7
7
|
export * from './ScanPackageOptions';
|
|
8
8
|
export * from './ScanPackageCallContext';
|
|
9
9
|
export * from './DependencyType';
|
|
10
|
+
export * from './ParentPackageInfo';
|
|
11
|
+
export * from './LicenseAnalysisResult';
|
|
12
|
+
export * from './LicenseStats';
|
package/build/types/index.js
CHANGED
|
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./License"), exports);
|
|
18
|
+
__exportStar(require("./AggregatedLicensesMapping"), exports);
|
|
19
19
|
__exportStar(require("./AboutLibrariesLibraryJsonPayload"), exports);
|
|
20
20
|
__exportStar(require("./AboutLibrariesLicenseJsonPayload"), exports);
|
|
21
21
|
__exportStar(require("./LicensePlistPayload"), exports);
|
|
@@ -23,3 +23,6 @@ __exportStar(require("./AboutLibrariesLikePackageInfo"), exports);
|
|
|
23
23
|
__exportStar(require("./ScanPackageOptions"), exports);
|
|
24
24
|
__exportStar(require("./ScanPackageCallContext"), exports);
|
|
25
25
|
__exportStar(require("./DependencyType"), exports);
|
|
26
|
+
__exportStar(require("./ParentPackageInfo"), exports);
|
|
27
|
+
__exportStar(require("./LicenseAnalysisResult"), exports);
|
|
28
|
+
__exportStar(require("./LicenseStats"), exports);
|
package/build/utils/index.d.ts
CHANGED
package/build/utils/index.js
CHANGED
|
@@ -33,8 +33,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.YamlUtils = exports.RepositoryUtils =
|
|
37
|
-
exports.PackageUtils = __importStar(require("./packageUtils"));
|
|
38
|
-
exports.MiscUtils = __importStar(require("./miscUtils"));
|
|
36
|
+
exports.YamlUtils = exports.RepositoryUtils = void 0;
|
|
39
37
|
exports.RepositoryUtils = __importStar(require("./repositoryUtils"));
|
|
40
38
|
exports.YamlUtils = __importStar(require("./yamlUtils"));
|
package/package.json
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@callstack/licenses",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "API package that exposes functionalities for programmatic scanning of licenses in Node.js projects.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"types": "build/index.d.ts",
|
|
5
|
+
"browser": "./build/index.js",
|
|
6
|
+
"main": "./build/node/index.js",
|
|
8
7
|
"exports": {
|
|
9
8
|
".": {
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
"import": {
|
|
10
|
+
"source": "./src/index.ts",
|
|
11
|
+
"types": "./build/index.d.ts",
|
|
12
|
+
"default": "./build/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"source": "./src/node/index.ts",
|
|
16
|
+
"types": "./build/node/index.d.ts",
|
|
17
|
+
"default": "./build/node/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./node": {
|
|
21
|
+
"import": {
|
|
22
|
+
"source": "./src/node/index.ts",
|
|
23
|
+
"types": "./build/node/index.d.ts",
|
|
24
|
+
"default": "./build/node/index.js"
|
|
25
|
+
}
|
|
13
26
|
},
|
|
14
27
|
"./package.json": "./package.json"
|
|
15
28
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './licenses';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* https://spdx.org/licenses
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const STRONG_COPYLEFT_LICENSES = new Set([
|
|
6
|
+
'GPL',
|
|
7
|
+
'GPL-1.0',
|
|
8
|
+
'GPL-1.0+',
|
|
9
|
+
'GPL-2.0',
|
|
10
|
+
'GPL-2.0+',
|
|
11
|
+
'GPL-2.0-only',
|
|
12
|
+
'GPL-2.0-or-later',
|
|
13
|
+
'GPL-3.0',
|
|
14
|
+
'GPL-3.0+',
|
|
15
|
+
'GPL-3.0-only',
|
|
16
|
+
'GPL-3.0-or-later',
|
|
17
|
+
'AGPL-3.0',
|
|
18
|
+
'AGPL-3.0-only',
|
|
19
|
+
'AGPL-3.0-or-later',
|
|
20
|
+
'EUPL-1.0',
|
|
21
|
+
'EUPL-1.1',
|
|
22
|
+
'EUPL-1.2',
|
|
23
|
+
'OSL-1.0',
|
|
24
|
+
'OSL-1.1',
|
|
25
|
+
'OSL-2.0',
|
|
26
|
+
'OSL-2.1',
|
|
27
|
+
'OSL-3.0',
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
export const WEAK_COPYLEFT_LICENSES = new Set([
|
|
31
|
+
'CDDL-1.0',
|
|
32
|
+
'CDDL-1.1',
|
|
33
|
+
'EPL-1.0',
|
|
34
|
+
'EPL-2.0',
|
|
35
|
+
'LGPL',
|
|
36
|
+
'LGPL-2.0',
|
|
37
|
+
'LGPL-2.0+',
|
|
38
|
+
'LGPL-2.0-only',
|
|
39
|
+
'LGPL-2.0-or-later',
|
|
40
|
+
'LGPL-2.1',
|
|
41
|
+
'LGPL-2.1+',
|
|
42
|
+
'LGPL-2.1-only',
|
|
43
|
+
'LGPL-2.1-or-later',
|
|
44
|
+
'LGPL-3.0',
|
|
45
|
+
'LGPL-3.0+',
|
|
46
|
+
'LGPL-3.0-only',
|
|
47
|
+
'LGPL-3.0-or-later',
|
|
48
|
+
'MPL-1.1',
|
|
49
|
+
'MPL-2.0',
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
export const STRONG_COPYLEFT_LICENSES_LOWERCASE = new Set(
|
|
53
|
+
Array.from(STRONG_COPYLEFT_LICENSES).map((license) => license.toLowerCase()),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export const WEAK_COPYLEFT_LICENSES_LOWERCASE = new Set(
|
|
57
|
+
Array.from(WEAK_COPYLEFT_LICENSES).map((license) => license.toLowerCase()),
|
|
58
|
+
);
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { LicenseCategory } from './LicenseCategory';
|
|
2
|
+
|
|
3
|
+
export function getGraphStateInfo(stats: Record<LicenseCategory, number>) {
|
|
4
|
+
const hasAnyUnknown = stats[LicenseCategory.UNKNOWN] > 0;
|
|
5
|
+
const hasAnyWeakCopyleft = stats[LicenseCategory.WEAK_COPYLEFT] > 0;
|
|
6
|
+
const hasAnyStrongCopyleft = stats[LicenseCategory.STRONG_COPYLEFT] > 0;
|
|
7
|
+
const hasAllPermissive = !hasAnyUnknown && !hasAnyStrongCopyleft && !hasAnyWeakCopyleft;
|
|
8
|
+
|
|
9
|
+
let description = '';
|
|
10
|
+
if (hasAnyWeakCopyleft || hasAnyStrongCopyleft) {
|
|
11
|
+
description = `Some detected licenses are ${[
|
|
12
|
+
hasAnyWeakCopyleft ? 'weak' : null,
|
|
13
|
+
hasAnyStrongCopyleft ? 'strong' : null,
|
|
14
|
+
]
|
|
15
|
+
.filter((x) => !!x)
|
|
16
|
+
.map((x) => `${x}-`)
|
|
17
|
+
.join(' and ')}copyleft`;
|
|
18
|
+
} else {
|
|
19
|
+
description = `${hasAllPermissive ? 'All' : stats[LicenseCategory.PERMISSIVE]} detected licenses are permissive`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (hasAnyUnknown) {
|
|
23
|
+
description += `, ${hasAllPermissive ? 'but ' : ''}${stats[LicenseCategory.UNKNOWN]} are unknown.`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
description,
|
|
28
|
+
categoriesPresence: {
|
|
29
|
+
hasAnyUnknown,
|
|
30
|
+
hasAnyWeakCopyleft,
|
|
31
|
+
hasAnyStrongCopyleft,
|
|
32
|
+
hasAllPermissive,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Gets a human-readable description of the license category
|
|
39
|
+
* @param category the license category
|
|
40
|
+
* @returns the human-readable description of the license category
|
|
41
|
+
*/
|
|
42
|
+
export function getLicenseCategoryDescription(category: LicenseCategory): string {
|
|
43
|
+
switch (category) {
|
|
44
|
+
case LicenseCategory.STRONG_COPYLEFT:
|
|
45
|
+
return 'Strong Copyleft';
|
|
46
|
+
|
|
47
|
+
case LicenseCategory.WEAK_COPYLEFT:
|
|
48
|
+
return 'Weak Copyleft';
|
|
49
|
+
|
|
50
|
+
case LicenseCategory.PERMISSIVE:
|
|
51
|
+
return 'Permissive';
|
|
52
|
+
|
|
53
|
+
case LicenseCategory.UNKNOWN:
|
|
54
|
+
return 'Unknown';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { STRONG_COPYLEFT_LICENSES_LOWERCASE, WEAK_COPYLEFT_LICENSES_LOWERCASE } from '../constants/licenses';
|
|
2
|
+
import type { AggregatedLicensesMapping } from '../types';
|
|
3
|
+
import type { LicenseAnalysisResult } from '../types/LicenseAnalysisResult';
|
|
4
|
+
|
|
5
|
+
import { LicenseCategory } from './LicenseCategory';
|
|
6
|
+
import { getGraphStateInfo } from './descriptions';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Categorizes a license based on its copyleft characteristics.
|
|
10
|
+
* @param licenseType the license type
|
|
11
|
+
* @returns the license category
|
|
12
|
+
*/
|
|
13
|
+
export function categorizeLicense(licenseType?: string): LicenseCategory {
|
|
14
|
+
if (!licenseType || licenseType === 'unknown') {
|
|
15
|
+
return LicenseCategory.UNKNOWN;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// check for strong copyleft licenses
|
|
19
|
+
if (STRONG_COPYLEFT_LICENSES_LOWERCASE.has(licenseType.toLowerCase())) {
|
|
20
|
+
return LicenseCategory.STRONG_COPYLEFT;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// check for weak copyleft licenses
|
|
24
|
+
if (WEAK_COPYLEFT_LICENSES_LOWERCASE.has(licenseType.toLowerCase())) {
|
|
25
|
+
return LicenseCategory.WEAK_COPYLEFT;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// everything else is considered permissive
|
|
29
|
+
return LicenseCategory.PERMISSIVE;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Analyzes license data and returns comprehensive statistics.
|
|
34
|
+
* @param report the licenses report data
|
|
35
|
+
* @returns the license analysis result
|
|
36
|
+
*/
|
|
37
|
+
export function analyzeLicenses(report: AggregatedLicensesMapping): LicenseAnalysisResult {
|
|
38
|
+
const byCategory: Record<LicenseCategory, number> = {
|
|
39
|
+
[LicenseCategory.STRONG_COPYLEFT]: 0,
|
|
40
|
+
[LicenseCategory.WEAK_COPYLEFT]: 0,
|
|
41
|
+
[LicenseCategory.PERMISSIVE]: 0,
|
|
42
|
+
[LicenseCategory.UNKNOWN]: 0,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const byLicense: Record<string, number> = {};
|
|
46
|
+
const categorizedLicenses: Record<string, LicenseCategory> = {};
|
|
47
|
+
|
|
48
|
+
Object.entries(report).forEach(([packageKey, license]) => {
|
|
49
|
+
const licenseType = license.type;
|
|
50
|
+
const category = categorizeLicense(licenseType);
|
|
51
|
+
|
|
52
|
+
// stats by category
|
|
53
|
+
byCategory[category]++;
|
|
54
|
+
|
|
55
|
+
// stats by specific license
|
|
56
|
+
{
|
|
57
|
+
const key = licenseType ?? 'unknown';
|
|
58
|
+
|
|
59
|
+
byLicense[key] = (byLicense[key] ?? 0) + 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// memoization for lookup
|
|
63
|
+
categorizedLicenses[packageKey] = category;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const total = Object.keys(report).length;
|
|
67
|
+
|
|
68
|
+
const { categoriesPresence, description } = getGraphStateInfo(byCategory);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
total,
|
|
72
|
+
byCategory,
|
|
73
|
+
byLicense,
|
|
74
|
+
description,
|
|
75
|
+
categoriesPresence,
|
|
76
|
+
categorizedLicenses,
|
|
77
|
+
};
|
|
78
|
+
}
|