webpack-license-plugin
Version:
Extracts OSS license information of the npm packages in your webpack output
109 lines (97 loc) • 3.74 kB
text/typescript
import type IAlertAggregator from './types/IAlertAggregator'
import type IFileSystem from './types/IFileSystem'
import type ILicenseIdentifier from './types/ILicenseIdentifier'
import type ILicenseMetaAggregator from './types/ILicenseMetaAggregator'
import type ILicenseTextReader from './types/ILicenseTextReader'
import type INoticeTextReader from './types/INoticeTextReader'
import type IPackageJson from './types/IPackageJson'
import type IPackageJsonReader from './types/IPackageJsonReader'
import type IPackageLicenseMeta from './types/IPackageLicenseMeta'
import type IPluginOptions from './types/IPluginOptions'
import LicenseIdentifier from './LicenseIdentifier'
import LicenseTextReader from './LicenseTextReader'
import NoticeTextReader from './NoticeTextReader'
export default class LicenseMetaAggregator implements ILicenseMetaAggregator {
constructor(
fileSystem: IFileSystem,
alertAggregator: IAlertAggregator,
private options: IPluginOptions,
private packageJsonReader: IPackageJsonReader,
private licenseIdentifier: ILicenseIdentifier = new LicenseIdentifier(
alertAggregator,
),
private licenseTextReader: ILicenseTextReader = new LicenseTextReader(
alertAggregator,
fileSystem,
options,
),
private noticeTextReader: INoticeTextReader = new NoticeTextReader(
fileSystem,
),
) { }
private getNpmTarballUrl(
pkgName: string,
pkgVersion: string,
) {
const scopelessName = pkgName[0] !== '@' ? pkgName : pkgName.split('/')[1]
const plusPos = pkgVersion.indexOf('+')
const version = plusPos === -1 ? pkgVersion : pkgVersion.substring(0, plusPos)
return `https://registry.npmjs.org/${pkgName}/-/${scopelessName}-${version}.tgz`
}
public async aggregateMeta(
moduleDirs: string[],
): Promise<IPackageLicenseMeta[]> {
const packageSet = new Set()
const result: IPackageLicenseMeta[] = []
const sortedModuleDirs = moduleDirs.sort((a, b) =>
this.packageJsonReader
.readPackageJson(a)
.name
.localeCompare(this.packageJsonReader.readPackageJson(b).name),
)
for (const moduleDir of sortedModuleDirs) {
const meta = this.packageJsonReader.readPackageJson(moduleDir)
const packageIdentifier = `${meta.name}@${meta.version}`
if (packageSet.has(packageIdentifier)) {
continue
}
if (this.options.excludedPackageTest(meta.name, meta.version)) {
continue
}
packageSet.add(packageIdentifier)
const license = this.licenseIdentifier.identifyLicense(meta, this.options)
const licenseText = await this.licenseTextReader.readLicenseText(
meta,
license,
moduleDir,
)
const noticeText = this.options.includeNoticeText ? await this.noticeTextReader.readNoticeText(moduleDir) : undefined
result.push({
name: meta.name,
version: meta.version,
author: this.getAuthor(meta),
repository: this.getRepository(meta),
source: this.getNpmTarballUrl(meta.name, meta.version),
license,
licenseText,
...(noticeText ? { noticeText } : {}),
})
}
return result
}
public getAuthor(meta: Pick<IPackageJson, 'author'>): string {
return typeof meta.author === 'object'
? `${meta.author.name}${meta.author.email ? ` <${meta.author.email}>` : ''
}${meta.author.url ? ` (${meta.author.url})` : ''}`
: meta.author
}
public getRepository(meta: Pick<IPackageJson, 'repository'>): string {
if (meta.repository && meta.repository.url) {
return meta.repository.url
}
else if (typeof meta.repository === 'string') {
return meta.repository
}
return null
}
}