license-downloader 1.3.3 → 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/CHANGELOG.md +19 -0
- package/README.md +1 -1
- package/index.js +7 -21
- package/lib/util.js +6 -25
- package/lib/web-service.js +16 -47
- package/package.json +13 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.0.0](https://github.com/BePo65/license-downloader/compare/v1.3.3...v2.0.0) (2026-05-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* requires node version >= 22
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* set minimal node version to 22 ([779d017](https://github.com/BePo65/license-downloader/commit/779d017efe09b5f95bc48f6967aa69a7a7d038d5))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* update packages to fix dependabot security warnings ([1222a97](https://github.com/BePo65/license-downloader/commit/1222a977bd4e294a51d39fc837fee9b9934c78af))
|
|
20
|
+
* update packages to fix dependabot security warnings ([d746f3b](https://github.com/BePo65/license-downloader/commit/d746f3b1eb87c6091d857eb973ec5f6ea98d1211))
|
|
21
|
+
* update packages to fix dependabot security warnings ([2c86a69](https://github.com/BePo65/license-downloader/commit/2c86a696a641f03a256afcacba7cc4ca57818620))
|
|
22
|
+
* update packages to fix github dependabot security warnings ([2c97082](https://github.com/BePo65/license-downloader/commit/2c97082d5ac99d0b9f9fab840f3d2f614a8536f7))
|
|
23
|
+
|
|
5
24
|
## [1.3.3](https://github.com/BePo65/license-downloader/compare/v1.3.2...v1.3.3) (2025-10-24)
|
|
6
25
|
|
|
7
26
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# license-downloader - an add-on to license-report tool
|
|
2
2
|
|
|
3
|
-
[](https://github.com/BePo65/license-downloader/blob/main/CHANGELOG.md)
|
|
4
4
|
[](https://github.com/BePo65/license-downloader/blob/main/LICENSE)
|
|
5
5
|
|
|
6
6
|
> Download the license files of the dependencies of a project based on the json report from the package 'license-report'.
|
package/index.js
CHANGED
|
@@ -1,42 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import path from 'path';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
|
|
5
5
|
import config from './lib/config.js';
|
|
6
6
|
import FsService from './lib/filesystem-service.js';
|
|
7
|
+
import { helpText, licenseFilesTargetFolder, sourceToTargetFilename } from './lib/util.js';
|
|
7
8
|
import WebService from './lib/web-service.js';
|
|
8
|
-
import {
|
|
9
|
-
helpText,
|
|
10
|
-
licenseFilesTargetFolder,
|
|
11
|
-
sourceToTargetFilename,
|
|
12
|
-
} from './lib/util.js';
|
|
13
9
|
|
|
14
10
|
(async () => {
|
|
15
11
|
if (config.help) {
|
|
16
|
-
console.log(helpText);
|
|
12
|
+
console.log(helpText);
|
|
17
13
|
return;
|
|
18
14
|
}
|
|
19
15
|
|
|
20
16
|
try {
|
|
21
17
|
const sourceFilename = config.source;
|
|
22
18
|
const json = await FsService.readJson(sourceFilename);
|
|
23
|
-
await WebService.addLicenseFilePath(
|
|
24
|
-
|
|
25
|
-
config.httpRetryOptions,
|
|
26
|
-
config.githubToken,
|
|
27
|
-
);
|
|
28
|
-
const targetFilename = sourceToTargetFilename(
|
|
29
|
-
sourceFilename,
|
|
30
|
-
config.licDir,
|
|
31
|
-
);
|
|
19
|
+
await WebService.addLicenseFilePath(json, config.httpRetryOptions, config.githubToken);
|
|
20
|
+
const targetFilename = sourceToTargetFilename(sourceFilename, config.licDir);
|
|
32
21
|
FsService.createDirFromFilename(targetFilename);
|
|
33
22
|
await FsService.writeJson(json, targetFilename);
|
|
34
23
|
if (config.download) {
|
|
35
24
|
const sourceDirectory = path.dirname(sourceFilename);
|
|
36
|
-
const targetDirectory = licenseFilesTargetFolder(
|
|
37
|
-
config.licDir,
|
|
38
|
-
sourceDirectory,
|
|
39
|
-
);
|
|
25
|
+
const targetDirectory = licenseFilesTargetFolder(config.licDir, sourceDirectory);
|
|
40
26
|
await WebService.downloadLicenseFiles(
|
|
41
27
|
json,
|
|
42
28
|
targetDirectory,
|
|
@@ -46,6 +32,6 @@ import {
|
|
|
46
32
|
}
|
|
47
33
|
} catch (e) {
|
|
48
34
|
console.error(e.message);
|
|
49
|
-
process.exit(1);
|
|
35
|
+
process.exit(1);
|
|
50
36
|
}
|
|
51
37
|
})();
|
package/lib/util.js
CHANGED
|
@@ -13,26 +13,15 @@ const defaultTargetSubdirectory = 'licenses';
|
|
|
13
13
|
export const sourceToTargetFilename = (sourceFilename, targetDirectory) => {
|
|
14
14
|
if (typeof sourceFilename === 'string' && sourceFilename.trim().length > 0) {
|
|
15
15
|
const extension = path.extname(sourceFilename);
|
|
16
|
-
const fileBasename = path
|
|
17
|
-
.basename(sourceFilename)
|
|
18
|
-
.slice(0, -1 * extension.length);
|
|
16
|
+
const fileBasename = path.basename(sourceFilename).slice(0, -1 * extension.length);
|
|
19
17
|
let targetDir = targetDirectory;
|
|
20
|
-
if (
|
|
21
|
-
targetDir === undefined ||
|
|
22
|
-
targetDir === null ||
|
|
23
|
-
targetDir.trim().length === 0
|
|
24
|
-
) {
|
|
18
|
+
if (targetDir === undefined || targetDir === null || targetDir.trim().length === 0) {
|
|
25
19
|
targetDir = path.dirname(sourceFilename);
|
|
26
20
|
}
|
|
27
|
-
const targetFilename = path.join(
|
|
28
|
-
targetDir,
|
|
29
|
-
`${fileBasename}.ext${extension}`,
|
|
30
|
-
);
|
|
21
|
+
const targetFilename = path.join(targetDir, `${fileBasename}.ext${extension}`);
|
|
31
22
|
return targetFilename;
|
|
32
23
|
} else {
|
|
33
|
-
throw new Error(
|
|
34
|
-
'Source filename must not be empty to generate target filename',
|
|
35
|
-
);
|
|
24
|
+
throw new Error('Source filename must not be empty to generate target filename');
|
|
36
25
|
}
|
|
37
26
|
};
|
|
38
27
|
|
|
@@ -44,18 +33,10 @@ export const sourceToTargetFilename = (sourceFilename, targetDirectory) => {
|
|
|
44
33
|
*/
|
|
45
34
|
export const licenseFilesTargetFolder = (licenseDirectory, sourceDirectory) => {
|
|
46
35
|
let targetFolder = '';
|
|
47
|
-
if (
|
|
48
|
-
licenseDirectory !== undefined &&
|
|
49
|
-
licenseDirectory !== null &&
|
|
50
|
-
licenseDirectory.length > 0
|
|
51
|
-
) {
|
|
36
|
+
if (licenseDirectory !== undefined && licenseDirectory !== null && licenseDirectory.length > 0) {
|
|
52
37
|
targetFolder = licenseDirectory;
|
|
53
38
|
} else {
|
|
54
|
-
if (
|
|
55
|
-
sourceDirectory !== undefined &&
|
|
56
|
-
sourceDirectory !== null &&
|
|
57
|
-
sourceDirectory.length > 0
|
|
58
|
-
) {
|
|
39
|
+
if (sourceDirectory !== undefined && sourceDirectory !== null && sourceDirectory.length > 0) {
|
|
59
40
|
targetFolder = path.join(sourceDirectory, defaultTargetSubdirectory);
|
|
60
41
|
} else {
|
|
61
42
|
targetFolder = defaultTargetSubdirectory;
|
package/lib/web-service.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import stream from 'stream';
|
|
4
|
-
import { promisify } from 'util';
|
|
5
|
-
import got from 'got';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import stream from 'node:stream';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
6
5
|
import debug from 'debug';
|
|
6
|
+
import got from 'got';
|
|
7
7
|
|
|
8
8
|
import FsService from './filesystem-service.js';
|
|
9
9
|
|
|
@@ -42,7 +42,6 @@ const tokenFromConfigObject = (githubTokenConfig) => {
|
|
|
42
42
|
typeof tokenFileEnvVar === 'string' &&
|
|
43
43
|
tokenFileEnvVar.length > 0
|
|
44
44
|
) {
|
|
45
|
-
// eslint-disable-next-line security/detect-object-injection
|
|
46
45
|
const tokenFile = process.env[tokenFileEnvVar];
|
|
47
46
|
if (tokenFile !== undefined && tokenFile.length > 0) {
|
|
48
47
|
if (fs.existsSync(tokenFile)) {
|
|
@@ -58,12 +57,7 @@ const tokenFromConfigObject = (githubTokenConfig) => {
|
|
|
58
57
|
}
|
|
59
58
|
} else {
|
|
60
59
|
const tokenEnvVar = githubTokenConfig.tokenEnvVar;
|
|
61
|
-
if (
|
|
62
|
-
tokenEnvVar !== undefined &&
|
|
63
|
-
typeof tokenEnvVar === 'string' &&
|
|
64
|
-
tokenEnvVar.length > 0
|
|
65
|
-
) {
|
|
66
|
-
// eslint-disable-next-line security/detect-object-injection
|
|
60
|
+
if (tokenEnvVar !== undefined && typeof tokenEnvVar === 'string' && tokenEnvVar.length > 0) {
|
|
67
61
|
const tempToken = process.env[tokenEnvVar];
|
|
68
62
|
if (tempToken !== undefined && tempToken.trim().length > 0) {
|
|
69
63
|
token = tempToken;
|
|
@@ -87,8 +81,7 @@ const gotGithubJsonOptions = (maxAttempts, name, githubTokenConfig = {}) => {
|
|
|
87
81
|
retry: { limit: maxAttempts },
|
|
88
82
|
hooks: {
|
|
89
83
|
beforeRetry: [
|
|
90
|
-
|
|
91
|
-
(error, retryCount) => {
|
|
84
|
+
(_error, _retryCount) => {
|
|
92
85
|
debugForApp(
|
|
93
86
|
`http request to github api for package "${name}" license info failed, retrying again soon...`,
|
|
94
87
|
);
|
|
@@ -99,7 +92,6 @@ const gotGithubJsonOptions = (maxAttempts, name, githubTokenConfig = {}) => {
|
|
|
99
92
|
|
|
100
93
|
const token = tokenFromConfigObject(githubTokenConfig);
|
|
101
94
|
// no idea how to prevent timing attacks for the download operations
|
|
102
|
-
// eslint-disable-next-line security/detect-possible-timing-attacks
|
|
103
95
|
if (token !== undefined) {
|
|
104
96
|
gotOptions.headers = {
|
|
105
97
|
Authorization: `Bearer ${token}`,
|
|
@@ -116,17 +108,12 @@ const gotGithubJsonOptions = (maxAttempts, name, githubTokenConfig = {}) => {
|
|
|
116
108
|
* @param {object} githubTokenConfig - object with authorization data {tokenEnvVar, tokenFileEnvVar}
|
|
117
109
|
* @returns {object} object with the options for 'got' request
|
|
118
110
|
*/
|
|
119
|
-
const gotGithubLicenseFileOptions = (
|
|
120
|
-
maxAttempts,
|
|
121
|
-
url,
|
|
122
|
-
githubTokenConfig = {},
|
|
123
|
-
) => {
|
|
111
|
+
const gotGithubLicenseFileOptions = (maxAttempts, url, githubTokenConfig = {}) => {
|
|
124
112
|
const gotOptions = {
|
|
125
113
|
retry: { limit: maxAttempts },
|
|
126
114
|
hooks: {
|
|
127
115
|
beforeRetry: [
|
|
128
|
-
|
|
129
|
-
(error, retryCount) => {
|
|
116
|
+
(_error, _retryCount) => {
|
|
130
117
|
debugForApp(
|
|
131
118
|
`http request to github for license file at "${url}" failed, retrying again soon...`,
|
|
132
119
|
);
|
|
@@ -143,7 +130,6 @@ const gotGithubLicenseFileOptions = (
|
|
|
143
130
|
|
|
144
131
|
const token = tokenFromConfigObject(githubTokenConfig);
|
|
145
132
|
// no idea how to prevent timing attacks for the download operations
|
|
146
|
-
// eslint-disable-next-line security/detect-possible-timing-attacks
|
|
147
133
|
if (token !== undefined) {
|
|
148
134
|
gotOptions.headers = {
|
|
149
135
|
Authorization: `Bearer ${token}`,
|
|
@@ -161,9 +147,7 @@ const gotGithubLicenseFileOptions = (
|
|
|
161
147
|
*/
|
|
162
148
|
const getPackageNameFromLinkGit = (link) => {
|
|
163
149
|
let packageName = '';
|
|
164
|
-
const results = link.match(
|
|
165
|
-
/.+github\.com\/([^/]+\/[^/#]+?)(?:\.git)?(?=\/|#|$)/i,
|
|
166
|
-
);
|
|
150
|
+
const results = link.match(/.+github\.com\/([^/]+\/[^/#]+?)(?:\.git)?(?=\/|#|$)/i);
|
|
167
151
|
if (results !== null && results.length === 2) {
|
|
168
152
|
packageName = results[1];
|
|
169
153
|
}
|
|
@@ -220,11 +204,7 @@ export const addLicenseFilePath = async (
|
|
|
220
204
|
httpRetryOptions = {},
|
|
221
205
|
authorizationOptions = {},
|
|
222
206
|
) => {
|
|
223
|
-
if (
|
|
224
|
-
packagesInfos !== undefined &&
|
|
225
|
-
Array.isArray(packagesInfos) &&
|
|
226
|
-
packagesInfos.length > 0
|
|
227
|
-
) {
|
|
207
|
+
if (packagesInfos !== undefined && Array.isArray(packagesInfos) && packagesInfos.length > 0) {
|
|
228
208
|
await Promise.all(
|
|
229
209
|
packagesInfos.map(async (element) => {
|
|
230
210
|
element.licenseFileLink = '';
|
|
@@ -241,10 +221,7 @@ export const addLicenseFilePath = async (
|
|
|
241
221
|
);
|
|
242
222
|
const result = await got(licenseInfoAdr, options);
|
|
243
223
|
const licenseInfo = result.body;
|
|
244
|
-
if (
|
|
245
|
-
licenseInfo.download_url !== undefined &&
|
|
246
|
-
licenseInfo.download_url.length > 0
|
|
247
|
-
) {
|
|
224
|
+
if (licenseInfo.download_url !== undefined && licenseInfo.download_url.length > 0) {
|
|
248
225
|
element.licenseFileLink = licenseInfo.download_url;
|
|
249
226
|
}
|
|
250
227
|
} catch (error) {
|
|
@@ -253,8 +230,8 @@ export const addLicenseFilePath = async (
|
|
|
253
230
|
const { headers } = response;
|
|
254
231
|
if (headers['x-ratelimit-remaining'] === '0') {
|
|
255
232
|
const timeForRateLimitReset =
|
|
256
|
-
parseInt(error.response.headers['x-ratelimit-reset']) -
|
|
257
|
-
Math.floor(
|
|
233
|
+
parseInt(error.response.headers['x-ratelimit-reset'], 10) -
|
|
234
|
+
Math.floor(Date.now() / 1000);
|
|
258
235
|
const resetMsg = timeForRateLimitReset
|
|
259
236
|
? ` please wait ${timeForRateLimitReset} seconds before trying again.`
|
|
260
237
|
: '';
|
|
@@ -265,18 +242,14 @@ export const addLicenseFilePath = async (
|
|
|
265
242
|
console.error(
|
|
266
243
|
'You can increase the rate limit by providing a github token. See the README for more information.',
|
|
267
244
|
);
|
|
268
|
-
debugForApp(
|
|
269
|
-
`Failed query '${licenseInfoAdr}' ('${error.message}')`,
|
|
270
|
-
);
|
|
245
|
+
debugForApp(`Failed query '${licenseInfoAdr}' ('${error.message}')`);
|
|
271
246
|
return;
|
|
272
247
|
}
|
|
273
248
|
}
|
|
274
249
|
console.error(
|
|
275
250
|
`the project '${githubPackageName}' does not contain a license file on github; request returned ${response.statusCode} ( ${response.statusMessage})`,
|
|
276
251
|
);
|
|
277
|
-
debugForApp(
|
|
278
|
-
`no license file on '${licenseInfoAdr}' ('${error.message}')`,
|
|
279
|
-
);
|
|
252
|
+
debugForApp(`no license file on '${licenseInfoAdr}' ('${error.message}')`);
|
|
280
253
|
}
|
|
281
254
|
}
|
|
282
255
|
}
|
|
@@ -324,11 +297,7 @@ export const downloadLicenseFiles = async (
|
|
|
324
297
|
await pipeline(
|
|
325
298
|
got.stream(
|
|
326
299
|
url,
|
|
327
|
-
gotGithubLicenseFileOptions(
|
|
328
|
-
httpRetryOptions.maxAttempts,
|
|
329
|
-
url,
|
|
330
|
-
authorizationOptions,
|
|
331
|
-
),
|
|
300
|
+
gotGithubLicenseFileOptions(httpRetryOptions.maxAttempts, url, authorizationOptions),
|
|
332
301
|
),
|
|
333
302
|
fileWriterStream,
|
|
334
303
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "license-downloader",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Download the license files of the dependencies of a project",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
11
|
+
"node": ">=22"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
"bugs": "https://github.com/BePo65/license-downloader/issues",
|
|
23
23
|
"scripts": {
|
|
24
|
-
"lint": "npx
|
|
24
|
+
"lint": "npx @biomejs/biome check .",
|
|
25
|
+
"lint:fix": "npx @biomejs/biome check --write .",
|
|
25
26
|
"test": "node --test --test-reporter=spec",
|
|
26
27
|
"lint-commits": "commitlint --from d6a731d70b4f2 --to HEAD --verbose",
|
|
27
28
|
"init-changelog": "commit-and-tag-version -i CHANGELOG.md --same-file --prerelease pre --first-release",
|
|
@@ -37,28 +38,22 @@
|
|
|
37
38
|
"license": "MIT",
|
|
38
39
|
"dependencies": {
|
|
39
40
|
"debug": "^4.4.3",
|
|
40
|
-
"got": "^
|
|
41
|
-
"jsonfile": "^6.2.
|
|
41
|
+
"got": "^15.0.3",
|
|
42
|
+
"jsonfile": "^6.2.1",
|
|
42
43
|
"rc": "^1.2.8"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@
|
|
46
|
-
"@commitlint/
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"eslint-plugin-json": "^4.0.1",
|
|
51
|
-
"eslint-plugin-n": "^17.23.1",
|
|
52
|
-
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
53
|
-
"eslint-plugin-security": "^3.0.1",
|
|
54
|
-
"eslint-plugin-security-node": "^1.1.4",
|
|
46
|
+
"@biomejs/biome": "^2.4.5",
|
|
47
|
+
"@commitlint/cli": "^20.4.3",
|
|
48
|
+
"@commitlint/config-angular": "^20.4.3",
|
|
49
|
+
"commit-and-tag-version": "^12.7.1",
|
|
50
|
+
"conventional-commits-filter": "^5.0.0",
|
|
55
51
|
"husky": "^9.1.7",
|
|
56
|
-
"lint-staged": "^16.
|
|
57
|
-
"prettier": "^3.6.2",
|
|
52
|
+
"lint-staged": "^16.4.0",
|
|
58
53
|
"temp": "^0.9.4"
|
|
59
54
|
},
|
|
60
55
|
"lint-staged": {
|
|
61
|
-
"**/*": "
|
|
56
|
+
"**/*": "npx @biomejs/biome check --write ."
|
|
62
57
|
},
|
|
63
58
|
"commit-and-tag-version": {
|
|
64
59
|
"packageFiles": [
|