@callstack/licenses 0.2.1 → 0.3.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.
Files changed (61) hide show
  1. package/README.md +13 -1
  2. package/build/constants/index.d.ts +1 -0
  3. package/build/constants/index.js +17 -0
  4. package/build/constants/licenses.d.ts +7 -0
  5. package/build/constants/licenses.js +53 -0
  6. package/build/index.d.ts +2 -1
  7. package/build/index.js +5 -4
  8. package/build/licenses/LicenseCategory.d.ts +6 -0
  9. package/build/licenses/LicenseCategory.js +10 -0
  10. package/build/licenses/descriptions.d.ts +16 -0
  11. package/build/licenses/descriptions.js +53 -0
  12. package/build/licenses/index.d.ts +3 -0
  13. package/build/licenses/index.js +19 -0
  14. package/build/licenses/licenseAnalysis.d.ts +15 -0
  15. package/build/licenses/licenseAnalysis.js +65 -0
  16. package/build/{common.d.ts → node/common.d.ts} +6 -6
  17. package/build/{common.js → node/common.js} +75 -60
  18. package/build/node/index.d.ts +3 -0
  19. package/build/node/index.js +19 -0
  20. package/build/node/utils/index.d.ts +2 -0
  21. package/build/node/utils/index.js +38 -0
  22. package/build/{utils → node/utils}/packageUtils.d.ts +3 -3
  23. package/build/{utils → node/utils}/packageUtils.js +2 -2
  24. package/build/types/AggregatedLicensesMapping.d.ts +6 -0
  25. package/build/types/{LicenseObj.d.ts → License.d.ts} +8 -2
  26. package/build/types/LicenseAnalysisResult.d.ts +5 -0
  27. package/build/types/LicenseAnalysisResult.js +2 -0
  28. package/build/types/LicenseStats.d.ts +28 -0
  29. package/build/types/LicenseStats.js +2 -0
  30. package/build/types/ParentPackageInfo.d.ts +14 -0
  31. package/build/types/ParentPackageInfo.js +2 -0
  32. package/build/types/index.d.ts +5 -2
  33. package/build/types/index.js +5 -2
  34. package/build/utils/index.d.ts +0 -2
  35. package/build/utils/index.js +1 -3
  36. package/package.json +22 -9
  37. package/src/constants/index.ts +1 -0
  38. package/src/constants/licenses.ts +58 -0
  39. package/src/index.ts +2 -1
  40. package/src/licenses/LicenseCategory.ts +6 -0
  41. package/src/licenses/descriptions.ts +56 -0
  42. package/src/licenses/index.ts +3 -0
  43. package/src/licenses/licenseAnalysis.ts +78 -0
  44. package/src/{common.ts → node/common.ts} +62 -45
  45. package/src/node/index.ts +3 -0
  46. package/src/node/utils/index.ts +2 -0
  47. package/src/{utils → node/utils}/packageUtils.ts +4 -4
  48. package/src/types/AggregatedLicensesMapping.ts +7 -0
  49. package/src/types/{LicenseObj.ts → License.ts} +9 -2
  50. package/src/types/LicenseAnalysisResult.ts +7 -0
  51. package/src/types/LicenseStats.ts +33 -0
  52. package/src/types/ParentPackageInfo.ts +16 -0
  53. package/src/types/index.ts +5 -2
  54. package/src/utils/index.ts +0 -2
  55. package/build/types/AggregatedLicensesObj.d.ts +0 -6
  56. package/src/types/AggregatedLicensesObj.ts +0 -7
  57. /package/build/{utils → node/utils}/miscUtils.d.ts +0 -0
  58. /package/build/{utils → node/utils}/miscUtils.js +0 -0
  59. /package/build/types/{AggregatedLicensesObj.js → AggregatedLicensesMapping.js} +0 -0
  60. /package/build/types/{LicenseObj.js → License.js} +0 -0
  61. /package/src/{utils → node/utils}/miscUtils.ts +0 -0
@@ -1,5 +1,5 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
3
 
4
4
  import glob from 'glob';
5
5
 
@@ -7,13 +7,16 @@ import type {
7
7
  AboutLibrariesLibraryJsonPayload,
8
8
  AboutLibrariesLicenseJsonPayload,
9
9
  AboutLibrariesLikePackageInfo,
10
- AggregatedLicensesObj,
10
+ AggregatedLicensesMapping,
11
11
  DependencyType,
12
12
  LicensePlistPayload,
13
+ ParentPackageInfo,
13
14
  ScanPackageCallContext,
14
15
  ScanPackageOptionsFactory,
15
- } from './types';
16
- import { PackageUtils, YamlUtils } from './utils';
16
+ } from '../types';
17
+ import { YamlUtils } from '../utils';
18
+
19
+ import { PackageUtils } from './utils';
17
20
 
18
21
  type InternalScanGroupSpecifier = { packages: [depName: string, depVersion: string][]; dependencyType: DependencyType };
19
22
 
@@ -32,7 +35,7 @@ function scanPackage(
32
35
  packageName: string,
33
36
  requiredVersion: string,
34
37
  processedPackages: Set<string>,
35
- result: AggregatedLicensesObj,
38
+ result: AggregatedLicensesMapping,
36
39
  scanOptionsFactory: ScanPackageOptionsFactory = PackageUtils.legacyDefaultScanPackageOptionsFactory,
37
40
  {
38
41
  parentPackageRoot,
@@ -83,21 +86,37 @@ function scanPackage(
83
86
 
84
87
  const resolvedVersionPackageKey = `${packageName}@${localPackageJson.version}`;
85
88
 
86
- result[resolvedVersionPackageKey] = {
87
- name: packageName,
88
- author: PackageUtils.parseAuthorField(localPackageJson),
89
- content: licenseFiles?.[0] ? fs.readFileSync(licenseFiles[0], { encoding: 'utf-8' }) : undefined,
90
- file: licenseFiles?.[0] ? licenseFiles[0] : undefined,
91
- description: localPackageJson.description,
92
- type: PackageUtils.parseLicenseField(localPackageJson),
93
- url: PackageUtils.parseRepositoryFieldToUrl(localPackageJson),
94
- version: localPackageJson.version,
95
- requiredVersion,
96
- parentPackageName,
97
- parentPackageRequiredVersion,
98
- parentPackageResolvedVersion,
99
- dependencyType,
100
- };
89
+ let parentPackageInfo: ParentPackageInfo | undefined;
90
+ if (parentPackageName && parentPackageRequiredVersion && parentPackageResolvedVersion) {
91
+ parentPackageInfo = {
92
+ name: parentPackageName,
93
+ requiredVersion: parentPackageRequiredVersion,
94
+ resolvedVersion: parentPackageResolvedVersion,
95
+ };
96
+ }
97
+
98
+ if (parentPackageInfo && resolvedVersionPackageKey in result) {
99
+ result[resolvedVersionPackageKey].parentPackages = [
100
+ ...(result[resolvedVersionPackageKey].parentPackages ?? []),
101
+ parentPackageInfo,
102
+ ];
103
+ } else {
104
+ result[resolvedVersionPackageKey] = {
105
+ name: packageName,
106
+ author: PackageUtils.parseAuthorField(localPackageJson),
107
+ content: licenseFiles?.[0] ? fs.readFileSync(licenseFiles[0], { encoding: 'utf-8' }) : undefined,
108
+ file: licenseFiles?.[0] ? licenseFiles[0] : undefined,
109
+ description: localPackageJson.description,
110
+ type: PackageUtils.parseLicenseField(localPackageJson),
111
+ url: PackageUtils.parseRepositoryFieldToUrl(localPackageJson),
112
+ version: localPackageJson.version,
113
+ requiredVersion,
114
+ parentPackages: parentPackageInfo ? [parentPackageInfo] : [],
115
+ parentPackageRequiredVersion,
116
+ parentPackageResolvedVersion,
117
+ dependencyType,
118
+ };
119
+ }
101
120
  }
102
121
 
103
122
  const dependencies: MaybeDependencyMapping = localPackageJson.dependencies;
@@ -161,12 +180,12 @@ type MaybeDependencyMapping = DependencyMapping | undefined;
161
180
  export function scanDependencies(
162
181
  appPackageJsonPath: string,
163
182
  scanOptionsFactory: ScanPackageOptionsFactory = PackageUtils.legacyDefaultScanPackageOptionsFactory,
164
- ): AggregatedLicensesObj {
183
+ ): AggregatedLicensesMapping {
165
184
  const appPackageJson = require(path.resolve(appPackageJsonPath));
166
185
  const dependencies: MaybeDependencyMapping = appPackageJson.dependencies;
167
186
  const devDependencies: MaybeDependencyMapping = appPackageJson.devDependencies;
168
187
  const optionalDependencies: MaybeDependencyMapping = appPackageJson.optionalDependencies;
169
- const result: AggregatedLicensesObj = {};
188
+ const result: AggregatedLicensesMapping = {};
170
189
  const processedPackages = new Set<string>();
171
190
 
172
191
  const rootScanOptions = scanOptionsFactory({ isRoot: true, isWorkspacePackage: false });
@@ -205,24 +224,22 @@ export function scanDependencies(
205
224
  * @param iosProjectPath Path to the iOS project directory
206
225
  * @see {@link writeLicensePlistNPMOutput}
207
226
  */
208
- export function generateLicensePlistNPMOutput(licenses: AggregatedLicensesObj, iosProjectPath: string): string {
227
+ export function generateLicensePlistNPMOutput(licenses: AggregatedLicensesMapping, iosProjectPath: string): string {
209
228
  const renames: Record<string, string> = {};
210
- const licenseEntries = Object.entries(licenses).map(([packageKey, licenseObj]) => {
229
+ const licenseEntries = Object.entries(licenses).map(([packageKey, license]) => {
211
230
  const normalizedPackageNameWithVersion = PackageUtils.normalizePackageName(packageKey);
212
231
 
213
- if (licenseObj.name !== normalizedPackageNameWithVersion) {
214
- renames[normalizedPackageNameWithVersion] = licenseObj.name;
232
+ if (license.name !== normalizedPackageNameWithVersion) {
233
+ renames[normalizedPackageNameWithVersion] = license.name;
215
234
  }
216
235
 
217
- const relativeLicenseFile = licenseObj.file ? path.relative(iosProjectPath, licenseObj.file) : undefined;
236
+ const relativeLicenseFile = license.file ? path.relative(iosProjectPath, license.file) : undefined;
218
237
 
219
238
  return {
220
239
  name: normalizedPackageNameWithVersion,
221
- version: licenseObj.version,
222
- ...(licenseObj.url && { source: licenseObj.url }),
223
- ...(licenseObj.file
224
- ? { file: relativeLicenseFile }
225
- : { body: licenseObj.content ?? licenseObj.type ?? 'UNKNOWN' }),
240
+ version: license.version,
241
+ ...(license.url && { source: license.url }),
242
+ ...(license.file ? { file: relativeLicenseFile } : { body: license.content ?? license.type ?? 'UNKNOWN' }),
226
243
  } as LicensePlistPayload;
227
244
  });
228
245
 
@@ -261,7 +278,7 @@ export function generateLicensePlistNPMOutput(licenses: AggregatedLicensesObj, i
261
278
  * @see {@link generateLicensePlistNPMOutput}
262
279
  */
263
280
  export function writeLicensePlistNPMOutput(
264
- licenses: AggregatedLicensesObj,
281
+ licenses: AggregatedLicensesMapping,
265
282
  iosProjectPath: string,
266
283
  plistLikeOutput?: string,
267
284
  ) {
@@ -281,20 +298,20 @@ export function writeLicensePlistNPMOutput(
281
298
  * @returns Array of AboutLibrariesLikePackage objects, each representing a NPM dependency
282
299
  * @see {@link writeAboutLibrariesNPMOutput}
283
300
  */
284
- export function generateAboutLibrariesNPMOutput(licenses: AggregatedLicensesObj): AboutLibrariesLikePackageInfo[] {
301
+ export function generateAboutLibrariesNPMOutput(licenses: AggregatedLicensesMapping): AboutLibrariesLikePackageInfo[] {
285
302
  return Object.entries(licenses)
286
- .map(([packageKey, licenseObj]) => {
303
+ .map(([packageKey, license]) => {
287
304
  return {
288
- artifactVersion: licenseObj.version,
289
- content: licenseObj.content ?? '',
290
- description: licenseObj.description ?? '',
291
- developers: [{ name: licenseObj.author ?? '', organisationUrl: '' }],
292
- licenses: [PackageUtils.prepareAboutLibrariesLicenseField(licenseObj)],
293
- name: licenseObj.name,
305
+ artifactVersion: license.version,
306
+ content: license.content ?? '',
307
+ description: license.description ?? '',
308
+ developers: [{ name: license.author ?? '', organisationUrl: '' }],
309
+ licenses: [PackageUtils.prepareAboutLibrariesLicenseField(license)],
310
+ name: license.name,
294
311
  tag: '',
295
- type: licenseObj.type,
312
+ type: license.type,
296
313
  uniqueId: PackageUtils.normalizePackageName(packageKey),
297
- website: licenseObj.url,
314
+ website: license.url,
298
315
  };
299
316
  })
300
317
  .map((jsonPayload) => {
@@ -344,7 +361,7 @@ export function generateAboutLibrariesNPMOutput(licenses: AggregatedLicensesObj)
344
361
  * @see {@link generateAboutLibrariesNPMOutput}
345
362
  */
346
363
  export function writeAboutLibrariesNPMOutput(
347
- licenses: AggregatedLicensesObj,
364
+ licenses: AggregatedLicensesMapping,
348
365
  androidProjectPath: string,
349
366
  aboutLibrariesLikeOutput?: AboutLibrariesLikePackageInfo[],
350
367
  ) {
@@ -0,0 +1,3 @@
1
+ export * from './common';
2
+ export * from './utils';
3
+ export * from '../';
@@ -0,0 +1,2 @@
1
+ export * as PackageUtils from './packageUtils';
2
+ export * as MiscUtils from './miscUtils';
@@ -1,10 +1,10 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
 
4
- import type { LicenseObj, ScanPackageOptionsFactory } from '../types';
4
+ import type { License, ScanPackageOptionsFactory } from '../../types';
5
+ import { normalizeRepositoryUrl } from '../../utils/repositoryUtils';
5
6
 
6
7
  import { sha512 } from './miscUtils';
7
- import { normalizeRepositoryUrl } from './repositoryUtils';
8
8
 
9
9
  export function getPackageJsonPath(dependency: string, root?: string) {
10
10
  const rootsToSearch = [
@@ -54,7 +54,7 @@ export function normalizePackageName(packageName: string): string {
54
54
  return packageName.replace('/', '_');
55
55
  }
56
56
 
57
- export function prepareAboutLibrariesLicenseField(license: LicenseObj) {
57
+ export function prepareAboutLibrariesLicenseField(license: License) {
58
58
  if (!license.type) {
59
59
  return '';
60
60
  }
@@ -94,7 +94,7 @@ export function parseRepositoryFieldToUrl(json: { repository: string | { url?: s
94
94
 
95
95
  /**
96
96
  * Default value consistent with legacy behaviour assumptions for the scan package options factory
97
- * used so as not to introduce breaking API changes to the shared package
97
+ * used so as not to introduce breaking API changes
98
98
  */
99
99
  export const legacyDefaultScanPackageOptionsFactory: ScanPackageOptionsFactory = () => ({
100
100
  includeTransitiveDependencies: true,
@@ -0,0 +1,7 @@
1
+ import type { License } from './License';
2
+
3
+ /**
4
+ * Mapping from package keys in format `<package-name>@<package-version>` to license objects.
5
+ * @see {@link License}
6
+ */
7
+ export type AggregatedLicensesMapping = Record<string, License>;
@@ -1,7 +1,8 @@
1
1
  import type { DependencyType } from './DependencyType';
2
+ import type { ParentPackageInfo } from './ParentPackageInfo';
2
3
  import type { ScanPackageCallContext } from './ScanPackageCallContext';
3
4
 
4
- export type LicenseObj = {
5
+ export type License = {
5
6
  /** Package name */
6
7
  name: string;
7
8
 
@@ -31,4 +32,10 @@ export type LicenseObj = {
31
32
 
32
33
  /** The required version specified in package.json */
33
34
  requiredVersion: string;
34
- } & Pick<ScanPackageCallContext, 'parentPackageName' | 'parentPackageRequiredVersion' | 'parentPackageResolvedVersion'>;
35
+
36
+ /**
37
+ * The name(s) of the package(s) that introduced the package as a dependency (of any type);
38
+ * empty array if the package is a dependency of the root package
39
+ */
40
+ parentPackages: ParentPackageInfo[];
41
+ } & Pick<ScanPackageCallContext, 'parentPackageRequiredVersion' | 'parentPackageResolvedVersion'>;
@@ -0,0 +1,7 @@
1
+ import type { LicenseCategory } from '../licenses/LicenseCategory';
2
+
3
+ import type { LicenseStats } from './LicenseStats';
4
+
5
+ export interface LicenseAnalysisResult extends LicenseStats {
6
+ categorizedLicenses: Record<string, LicenseCategory>;
7
+ }
@@ -0,0 +1,33 @@
1
+ import type { LicenseCategory } from '../licenses/LicenseCategory';
2
+
3
+ export interface LicenseStats {
4
+ /**
5
+ * Total number of packages
6
+ */
7
+ total: number;
8
+
9
+ /**
10
+ * Mapping of license category to count of packages in that category
11
+ */
12
+ byCategory: Record<LicenseCategory, number>;
13
+
14
+ /**
15
+ * Mapping of license name to count of packages with that license
16
+ */
17
+ byLicense: Record<string, number>;
18
+
19
+ /**
20
+ * Information about the presence of different license categories
21
+ */
22
+ categoriesPresence: {
23
+ hasAnyUnknown: boolean;
24
+ hasAnyWeakCopyleft: boolean;
25
+ hasAnyStrongCopyleft: boolean;
26
+ hasAllPermissive: boolean;
27
+ };
28
+
29
+ /**
30
+ * Description of the graph state based on the license categories
31
+ */
32
+ description: string;
33
+ }
@@ -0,0 +1,16 @@
1
+ export type ParentPackageInfo = {
2
+ /**
3
+ * The name of the package
4
+ */
5
+ name: string;
6
+
7
+ /**
8
+ * The required version, as specified in package.json
9
+ */
10
+ requiredVersion: string;
11
+
12
+ /**
13
+ * The resolved version, as specified in package.json
14
+ */
15
+ resolvedVersion: string;
16
+ };
@@ -1,5 +1,5 @@
1
- export * from './LicenseObj';
2
- export * from './AggregatedLicensesObj';
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';
@@ -1,4 +1,2 @@
1
- export * as PackageUtils from './packageUtils';
2
- export * as MiscUtils from './miscUtils';
3
1
  export * as RepositoryUtils from './repositoryUtils';
4
2
  export * as YamlUtils from './yamlUtils';
@@ -1,6 +0,0 @@
1
- import type { LicenseObj } from './LicenseObj';
2
- /**
3
- * Mapping from package keys in format `<package-name>/<package-version>` to license objects.
4
- * @see {@link LicenseObj}
5
- */
6
- export type AggregatedLicensesObj = Record<string, LicenseObj>;
@@ -1,7 +0,0 @@
1
- import type { LicenseObj } from './LicenseObj';
2
-
3
- /**
4
- * Mapping from package keys in format `<package-name>/<package-version>` to license objects.
5
- * @see {@link LicenseObj}
6
- */
7
- export type AggregatedLicensesObj = Record<string, LicenseObj>;
File without changes
File without changes
File without changes
File without changes