@hashicorp/js-releases
Advanced tools
Comparing version 1.5.0 to 1.5.1
{ | ||
"extension": ["ts"], | ||
"spec": "src/**/*.test.ts", | ||
"require": "ts-node/register" | ||
} | ||
"extension": ["ts"], | ||
"spec": "src/**/*.test.ts", | ||
"require": "ts-node/register" | ||
} |
@@ -0,1 +1,11 @@ | ||
# 1.5.1 (2022-03-17) | ||
BUG FIXES: | ||
- Fix `download` and `verify` ([#27](https://github.com/hashicorp/js-releases/pull/27)) | ||
INTERNAL: | ||
- Add prettier and format code ([#28](https://github.com/hashicorp/js-releases/pull/28)) | ||
# 1.5.0 (2022-02-07) | ||
@@ -2,0 +12,0 @@ |
@@ -17,4 +17,7 @@ "use strict"; | ||
const semver = require("semver"); | ||
const stream = require("stream"); | ||
const yauzl = require("yauzl"); | ||
const util_1 = require("util"); | ||
const utils_1 = require("./utils"); | ||
const finished = (0, util_1.promisify)(stream.finished); | ||
const hashiPublicKeyId = '72D7468F'; | ||
@@ -144,3 +147,3 @@ const hashiPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
-----END PGP PUBLIC KEY BLOCK-----`; | ||
const releasesUrl = "https://releases.hashicorp.com"; | ||
const releasesUrl = 'https://releases.hashicorp.com'; | ||
class Release { | ||
@@ -153,3 +156,3 @@ constructor(release) { | ||
if (release.shasums_signatures) { | ||
this.shasums_signature = release.shasums_signatures.find(sig => sig.endsWith(`_SHA256SUMS.${hashiPublicKeyId}.sig`)); | ||
this.shasums_signature = release.shasums_signatures.find((sig) => sig.endsWith(`_SHA256SUMS.${hashiPublicKeyId}.sig`)); | ||
} | ||
@@ -161,16 +164,12 @@ else { | ||
getBuild(platform, arch) { | ||
return this.builds.find(b => b.os === platform && b.arch === arch); | ||
return this.builds.find((b) => b.os === platform && b.arch === arch); | ||
} | ||
download(downloadUrl, installPath, identifier) { | ||
const headers = { 'User-Agent': identifier }; | ||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const result = yield (0, utils_1.request)(downloadUrl, { headers: Object.assign({}, headers), responseType: 'stream' }); | ||
result.pipe(fs.createWriteStream(installPath)); | ||
resolve(); | ||
} | ||
catch (e) { | ||
return reject(e.message); | ||
} | ||
})); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const headers = { 'User-Agent': identifier }; | ||
const writer = fs.createWriteStream(installPath); | ||
const result = yield (0, utils_1.request)(downloadUrl, { headers: Object.assign({}, headers), responseType: 'stream' }); | ||
result.pipe(writer); | ||
yield finished(writer); | ||
}); | ||
} | ||
@@ -181,3 +180,3 @@ verify(pkg, buildName) { | ||
this.calculateFileSha256Sum(pkg), | ||
this.downloadSha256Sum(buildName) | ||
this.downloadSha256Sum(buildName), | ||
]); | ||
@@ -195,3 +194,3 @@ if (remoteSum !== localSum) { | ||
.on('error', reject) | ||
.on('data', data => hash.update(data)) | ||
.on('data', (data) => hash.update(data)) | ||
.on('end', () => resolve(hash.digest('hex'))); | ||
@@ -203,4 +202,8 @@ }); | ||
const [shasumsResponse, shasumsSignature] = yield Promise.all([ | ||
(0, utils_1.request)(`${releasesUrl}/${this.name}/${this.version}/${this.shasums}`), | ||
(0, utils_1.request)(`${releasesUrl}/${this.name}/${this.version}/${this.shasums_signature}`), | ||
(0, utils_1.request)(`${releasesUrl}/${this.name}/${this.version}/${this.shasums}`, { | ||
responseType: 'text', | ||
}), | ||
(0, utils_1.request)(`${releasesUrl}/${this.name}/${this.version}/${this.shasums_signature}`, { | ||
responseType: 'arraybuffer', | ||
}), | ||
]); | ||
@@ -213,3 +216,3 @@ const publicKey = yield openpgp.readKey({ armoredKey: hashiPublicKey }); | ||
verificationKeys: publicKey, | ||
signature: signature | ||
signature: signature, | ||
}); | ||
@@ -219,7 +222,7 @@ if (!verified) { | ||
} | ||
const shasumLine = shasumsResponse.split(`\n`).find(line => line.includes(buildName)); | ||
const shasumLine = shasumsResponse.split(`\n`).find((line) => line.includes(buildName)); | ||
if (!shasumLine) { | ||
throw new Error(`Install error: no matching SHA sum for ${buildName}`); | ||
} | ||
return shasumLine.split(" ")[0]; | ||
return shasumLine.split(' ')[0]; | ||
}); | ||
@@ -266,4 +269,5 @@ } | ||
let release; | ||
if (!validVersion) { // pick the latest release (prereleases will be skipped for safety, set an explicit version instead) | ||
const releaseVersions = Object.keys(response.versions).filter(v => !semver.prerelease(v)); | ||
if (!validVersion) { | ||
// pick the latest release (prereleases will be skipped for safety, set an explicit version instead) | ||
const releaseVersions = Object.keys(response.versions).filter((v) => !semver.prerelease(v)); | ||
version = releaseVersions.sort((a, b) => semver.rcompare(a, b))[0]; | ||
@@ -288,5 +292,5 @@ release = new Release(response.versions[version]); | ||
else { | ||
throw new Error("No matching version found"); | ||
throw new Error('No matching version found'); | ||
} | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -14,12 +14,48 @@ "use strict"; | ||
const path = require("path"); | ||
const fs = require("fs"); | ||
const tempy = require("tempy"); | ||
const index_1 = require("./index"); | ||
describe('LS installer', () => { | ||
let release; | ||
before(() => { | ||
release = new index_1.Release({ | ||
name: 'terraform-ls', | ||
version: '0.25.2', | ||
shasums: 'terraform-ls_0.25.2_SHA256SUMS', | ||
shasums_signature: 'terraform-ls_0.25.2_SHA256SUMS.sig', | ||
shasums_signatures: ['terraform-ls_0.25.2_SHA256SUMS.72D7468F.sig', 'terraform-ls_0.25.2_SHA256SUMS.sig'], | ||
builds: [ | ||
{ | ||
name: 'terraform-ls', | ||
version: '0.25.2', | ||
os: 'darwin', | ||
arch: 'amd64', | ||
filename: 'terraform-ls_0.25.2_darwin_amd64.zip', | ||
url: 'https://releases.hashicorp.com/terraform-ls/0.25.2/terraform-ls_0.25.2_darwin_amd64.zip', | ||
}, | ||
], | ||
}); | ||
}); | ||
it('should calculate correct file sha256 sum', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const release = new index_1.Release({ name: "terraform-ls", version: "1.0.0" }); | ||
const expectedSum = "0314c6a66b059bde92c5ed0f11601c144cbd916eff6d1241b5b44e076e5888dc"; | ||
const testPath = path.resolve(__dirname, "..", "testFixture", "shasumtest.txt"); | ||
const expectedSum = '0314c6a66b059bde92c5ed0f11601c144cbd916eff6d1241b5b44e076e5888dc'; | ||
const testPath = path.resolve(__dirname, '..', 'testFixture', 'shasumtest.txt'); | ||
const sum = yield release.calculateFileSha256Sum(testPath); | ||
assert.strictEqual(sum, expectedSum); | ||
})); | ||
it('should download the correct sha256 sum', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const expectedSum = '8629ccc47ee8d4dfe6d23efb93b293948a088a936180d07d3f2ed118f6dd64a5'; | ||
const remoteSum = yield release.downloadSha256Sum(release.builds[0].filename); | ||
assert.strictEqual(remoteSum, expectedSum); | ||
})); | ||
it('should download the release', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const build = release.getBuild('darwin', 'amd64'); | ||
const tmpDir = tempy.directory(); | ||
const zipFile = path.resolve(tmpDir, `terraform-ls_v${release.version}.zip`); | ||
yield release.download(build.url, zipFile, 'js-releases/mocha-test'); | ||
yield release.verify(zipFile, build.filename); | ||
fs.rmSync(tmpDir, { | ||
recursive: true, | ||
}); | ||
})).timeout(20 * 1000); // increase timeout for file download | ||
}); | ||
//# sourceMappingURL=index.test.js.map |
@@ -1,2 +0,2 @@ | ||
import { AxiosRequestConfig } from "axios"; | ||
import { AxiosRequestConfig } from 'axios'; | ||
export declare function request<T = any>(url: string, options?: AxiosRequestConfig): Promise<T>; |
@@ -14,5 +14,5 @@ "use strict"; | ||
const axios_1 = require("axios"); | ||
const ProxyAgent = require("proxy-agent"); | ||
const httpProxy = process.env["HTTP_PROXY"] || process.env["http_proxy"]; | ||
const httpsProxy = process.env["HTTPS_PROXY"] || process.env["https_proxy"]; | ||
const ProxyAgent = require('proxy-agent'); | ||
const httpProxy = process.env['HTTP_PROXY'] || process.env['http_proxy']; | ||
const httpsProxy = process.env['HTTPS_PROXY'] || process.env['https_proxy']; | ||
let proxyConf = {}; | ||
@@ -19,0 +19,0 @@ if (httpProxy || httpsProxy) { |
{ | ||
"name": "@hashicorp/js-releases", | ||
"version": "1.5.0", | ||
"version": "1.5.1", | ||
"description": "Download packages from releases.hashicorp.com", | ||
@@ -11,3 +11,6 @@ "main": "./out/index.js", | ||
"test": "mocha", | ||
"prepare": "npm run-script test && npm run-script compile" | ||
"prepare": "npm run-script test && npm run-script compile", | ||
"prettier": "prettier \"**/*.+(js|json|ts)\"", | ||
"format": "npm run prettier -- --write", | ||
"check-format": "npm run prettier -- --check" | ||
}, | ||
@@ -37,2 +40,4 @@ "repository": { | ||
"mocha": "^9.2.0", | ||
"prettier": "^2.5.1", | ||
"tempy": "^1.0.1", | ||
"ts-node": "^9.1.1", | ||
@@ -39,0 +44,0 @@ "typescript": "^4.2.4" |
import * as assert from 'assert'; | ||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
import * as tempy from 'tempy'; | ||
import { Release, getRelease } from './index'; | ||
import { Release } from './index'; | ||
describe('LS installer', () => { | ||
it('should calculate correct file sha256 sum', async () => { | ||
const release = new Release({ name: "terraform-ls", version: "1.0.0" }); | ||
const expectedSum = "0314c6a66b059bde92c5ed0f11601c144cbd916eff6d1241b5b44e076e5888dc"; | ||
const testPath = path.resolve(__dirname, "..", "testFixture", "shasumtest.txt"); | ||
let release: Release; | ||
const sum = await release.calculateFileSha256Sum(testPath); | ||
assert.strictEqual(sum, expectedSum); | ||
}); | ||
before(() => { | ||
release = new Release({ | ||
name: 'terraform-ls', | ||
version: '0.25.2', | ||
shasums: 'terraform-ls_0.25.2_SHA256SUMS', | ||
shasums_signature: 'terraform-ls_0.25.2_SHA256SUMS.sig', | ||
shasums_signatures: ['terraform-ls_0.25.2_SHA256SUMS.72D7468F.sig', 'terraform-ls_0.25.2_SHA256SUMS.sig'], | ||
builds: [ | ||
{ | ||
name: 'terraform-ls', | ||
version: '0.25.2', | ||
os: 'darwin', | ||
arch: 'amd64', | ||
filename: 'terraform-ls_0.25.2_darwin_amd64.zip', | ||
url: 'https://releases.hashicorp.com/terraform-ls/0.25.2/terraform-ls_0.25.2_darwin_amd64.zip', | ||
}, | ||
], | ||
}); | ||
}); | ||
it('should calculate correct file sha256 sum', async () => { | ||
const expectedSum = '0314c6a66b059bde92c5ed0f11601c144cbd916eff6d1241b5b44e076e5888dc'; | ||
const testPath = path.resolve(__dirname, '..', 'testFixture', 'shasumtest.txt'); | ||
const sum = await release.calculateFileSha256Sum(testPath); | ||
assert.strictEqual(sum, expectedSum); | ||
}); | ||
it('should download the correct sha256 sum', async () => { | ||
const expectedSum = '8629ccc47ee8d4dfe6d23efb93b293948a088a936180d07d3f2ed118f6dd64a5'; | ||
const remoteSum = await release.downloadSha256Sum(release.builds[0].filename); | ||
assert.strictEqual(remoteSum, expectedSum); | ||
}); | ||
it('should download the release', async () => { | ||
const build = release.getBuild('darwin', 'amd64'); | ||
const tmpDir = tempy.directory(); | ||
const zipFile = path.resolve(tmpDir, `terraform-ls_v${release.version}.zip`); | ||
await release.download(build.url, zipFile, 'js-releases/mocha-test'); | ||
await release.verify(zipFile, build.filename); | ||
fs.rmSync(tmpDir, { | ||
recursive: true, | ||
}); | ||
}).timeout(20 * 1000); // increase timeout for file download | ||
}); |
270
src/index.ts
@@ -5,5 +5,8 @@ import * as crypto from 'crypto'; | ||
import * as semver from 'semver'; | ||
import * as stream from 'stream'; | ||
import * as yauzl from 'yauzl'; | ||
import { promisify } from 'util'; | ||
import { request } from './utils'; | ||
const finished = promisify(stream.finished); | ||
const hashiPublicKeyId = '72D7468F'; | ||
@@ -134,123 +137,124 @@ const hashiPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
const releasesUrl = "https://releases.hashicorp.com"; | ||
const releasesUrl = 'https://releases.hashicorp.com'; | ||
interface Build { | ||
url: string, | ||
filename: string | ||
url: string; | ||
filename: string; | ||
} | ||
export class Release { | ||
public name: string; | ||
public version: string; | ||
public builds?: any[]; | ||
public shasums?: string; | ||
public shasums_signature?: string; | ||
public shasums_signatures?: any[]; | ||
public name: string; | ||
public version: string; | ||
public builds?: any[]; | ||
public shasums?: string; | ||
public shasums_signature?: string; | ||
public shasums_signatures?: any[]; | ||
constructor( | ||
release: any | ||
) { | ||
this.name = release.name; | ||
this.version = release.version; | ||
this.builds = release.builds; | ||
this.shasums = release.shasums; | ||
if (release.shasums_signatures) { | ||
this.shasums_signature = release.shasums_signatures.find(sig => sig.endsWith(`_SHA256SUMS.${hashiPublicKeyId}.sig`)); | ||
} else { | ||
this.shasums_signature = release.shasums_signature; | ||
} | ||
} | ||
public getBuild(platform: string, arch: string): Build { | ||
return this.builds.find(b => b.os === platform && b.arch === arch); | ||
} | ||
constructor(release: any) { | ||
this.name = release.name; | ||
this.version = release.version; | ||
this.builds = release.builds; | ||
this.shasums = release.shasums; | ||
if (release.shasums_signatures) { | ||
this.shasums_signature = release.shasums_signatures.find((sig) => | ||
sig.endsWith(`_SHA256SUMS.${hashiPublicKeyId}.sig`), | ||
); | ||
} else { | ||
this.shasums_signature = release.shasums_signature; | ||
} | ||
} | ||
public download(downloadUrl: string, installPath: string, identifier: string): Promise<void> { | ||
const headers = { 'User-Agent': identifier }; | ||
public getBuild(platform: string, arch: string): Build { | ||
return this.builds.find((b) => b.os === platform && b.arch === arch); | ||
} | ||
return new Promise<void>(async (resolve, reject) => { | ||
try { | ||
const result = await request(downloadUrl, {headers: {...headers}, responseType: 'stream'}); | ||
result.pipe(fs.createWriteStream(installPath)) | ||
resolve(); | ||
} catch (e) { | ||
return reject(e.message); | ||
} | ||
}); | ||
} | ||
public async download(downloadUrl: string, installPath: string, identifier: string): Promise<void> { | ||
const headers = { 'User-Agent': identifier }; | ||
const writer = fs.createWriteStream(installPath); | ||
public async verify(pkg: string, buildName: string): Promise<void> { | ||
const [localSum, remoteSum] = await Promise.all([ | ||
this.calculateFileSha256Sum(pkg), | ||
this.downloadSha256Sum(buildName) | ||
]); | ||
if (remoteSum !== localSum) { | ||
throw new Error(`Install error: SHA sum for ${buildName} does not match.\n` + | ||
`(expected: ${remoteSum} calculated: ${localSum})`); | ||
} | ||
} | ||
const result = await request(downloadUrl, { headers: { ...headers }, responseType: 'stream' }); | ||
result.pipe(writer); | ||
await finished(writer); | ||
} | ||
calculateFileSha256Sum(path: string): Promise<string> { | ||
return new Promise<string>((resolve, reject) => { | ||
const hash = crypto.createHash('sha256'); | ||
fs.createReadStream(path) | ||
.on('error', reject) | ||
.on('data', data => hash.update(data)) | ||
.on('end', () => resolve(hash.digest('hex'))); | ||
}); | ||
} | ||
public async verify(pkg: string, buildName: string): Promise<void> { | ||
const [localSum, remoteSum] = await Promise.all([ | ||
this.calculateFileSha256Sum(pkg), | ||
this.downloadSha256Sum(buildName), | ||
]); | ||
if (remoteSum !== localSum) { | ||
throw new Error( | ||
`Install error: SHA sum for ${buildName} does not match.\n` + | ||
`(expected: ${remoteSum} calculated: ${localSum})`, | ||
); | ||
} | ||
} | ||
async downloadSha256Sum(buildName: string): Promise<string> { | ||
const [shasumsResponse, shasumsSignature] = await Promise.all([ | ||
request(`${releasesUrl}/${this.name}/${this.version}/${this.shasums}`), | ||
request(`${releasesUrl}/${this.name}/${this.version}/${this.shasums_signature}`), | ||
]); | ||
const publicKey = await openpgp.readKey({ armoredKey: hashiPublicKey }); | ||
const signature = await openpgp.readSignature({ binarySignature: Buffer.from(shasumsSignature, 'hex') }); | ||
const message = await openpgp.createMessage({ text: shasumsResponse }); | ||
const verified = await openpgp.verify({ | ||
message: message, | ||
verificationKeys: publicKey, | ||
signature: signature | ||
}); | ||
if (!verified) { | ||
throw new Error('signature could not be verified'); | ||
} | ||
const shasumLine = shasumsResponse.split(`\n`).find(line => line.includes(buildName)); | ||
if (!shasumLine) { | ||
throw new Error(`Install error: no matching SHA sum for ${buildName}`); | ||
} | ||
calculateFileSha256Sum(path: string): Promise<string> { | ||
return new Promise<string>((resolve, reject) => { | ||
const hash = crypto.createHash('sha256'); | ||
fs.createReadStream(path) | ||
.on('error', reject) | ||
.on('data', (data) => hash.update(data)) | ||
.on('end', () => resolve(hash.digest('hex'))); | ||
}); | ||
} | ||
return shasumLine.split(" ")[0]; | ||
} | ||
async downloadSha256Sum(buildName: string): Promise<string> { | ||
const [shasumsResponse, shasumsSignature] = await Promise.all([ | ||
request(`${releasesUrl}/${this.name}/${this.version}/${this.shasums}`, { | ||
responseType: 'text', | ||
}), | ||
request(`${releasesUrl}/${this.name}/${this.version}/${this.shasums_signature}`, { | ||
responseType: 'arraybuffer', | ||
}), | ||
]); | ||
const publicKey = await openpgp.readKey({ armoredKey: hashiPublicKey }); | ||
const signature = await openpgp.readSignature({ binarySignature: Buffer.from(shasumsSignature, 'hex') }); | ||
const message = await openpgp.createMessage({ text: shasumsResponse }); | ||
const verified = await openpgp.verify({ | ||
message: message, | ||
verificationKeys: publicKey, | ||
signature: signature, | ||
}); | ||
if (!verified) { | ||
throw new Error('signature could not be verified'); | ||
} | ||
const shasumLine = shasumsResponse.split(`\n`).find((line) => line.includes(buildName)); | ||
if (!shasumLine) { | ||
throw new Error(`Install error: no matching SHA sum for ${buildName}`); | ||
} | ||
public unpack(directory: string, pkgName: string): Promise<void> { | ||
return new Promise<void>((resolve, reject) => { | ||
let executable: string; | ||
yauzl.open(pkgName, { lazyEntries: true }, (err, zipfile) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
zipfile.readEntry(); | ||
zipfile.on('entry', (entry) => { | ||
zipfile.openReadStream(entry, (err, readStream) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
readStream.on('end', () => { | ||
zipfile.readEntry(); // Close it | ||
}); | ||
return shasumLine.split(' ')[0]; | ||
} | ||
executable = `${directory}/${entry.fileName}`; | ||
const destination = fs.createWriteStream(executable); | ||
readStream.pipe(destination); | ||
}); | ||
}); | ||
zipfile.on('close', () => { | ||
fs.chmodSync(executable, '755'); | ||
return resolve(); | ||
}); | ||
}); | ||
}); | ||
} | ||
public unpack(directory: string, pkgName: string): Promise<void> { | ||
return new Promise<void>((resolve, reject) => { | ||
let executable: string; | ||
yauzl.open(pkgName, { lazyEntries: true }, (err, zipfile) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
zipfile.readEntry(); | ||
zipfile.on('entry', (entry) => { | ||
zipfile.openReadStream(entry, (err, readStream) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
readStream.on('end', () => { | ||
zipfile.readEntry(); // Close it | ||
}); | ||
executable = `${directory}/${entry.fileName}`; | ||
const destination = fs.createWriteStream(executable); | ||
readStream.pipe(destination); | ||
}); | ||
}); | ||
zipfile.on('close', () => { | ||
fs.chmodSync(executable, '755'); | ||
return resolve(); | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
@@ -260,28 +264,34 @@ | ||
// from ranges unless they are explicitly opted into. | ||
export async function getRelease(product: string, version?: string, userAgent?: string, includePrerelease?: boolean): Promise<Release> { | ||
const validVersion = semver.validRange(version, { includePrerelease, loose: true }); // "latest" will return invalid but that's ok because we'll select it by default | ||
const indexUrl = `${releasesUrl}/${product}/index.json`; | ||
const headers = userAgent ? { 'User-Agent': userAgent } : null; | ||
const response = await request(indexUrl, { headers }); | ||
let release: Release; | ||
if (!validVersion) { // pick the latest release (prereleases will be skipped for safety, set an explicit version instead) | ||
const releaseVersions = Object.keys(response.versions).filter(v => !semver.prerelease(v)); | ||
version = releaseVersions.sort((a, b) => semver.rcompare(a, b))[0]; | ||
release = new Release(response.versions[version]); | ||
} else { | ||
release = matchVersion(response.versions, validVersion, includePrerelease); | ||
} | ||
return release; | ||
export async function getRelease( | ||
product: string, | ||
version?: string, | ||
userAgent?: string, | ||
includePrerelease?: boolean, | ||
): Promise<Release> { | ||
const validVersion = semver.validRange(version, { includePrerelease, loose: true }); // "latest" will return invalid but that's ok because we'll select it by default | ||
const indexUrl = `${releasesUrl}/${product}/index.json`; | ||
const headers = userAgent ? { 'User-Agent': userAgent } : null; | ||
const response = await request(indexUrl, { headers }); | ||
let release: Release; | ||
if (!validVersion) { | ||
// pick the latest release (prereleases will be skipped for safety, set an explicit version instead) | ||
const releaseVersions = Object.keys(response.versions).filter((v) => !semver.prerelease(v)); | ||
version = releaseVersions.sort((a, b) => semver.rcompare(a, b))[0]; | ||
release = new Release(response.versions[version]); | ||
} else { | ||
release = matchVersion(response.versions, validVersion, includePrerelease); | ||
} | ||
return release; | ||
} | ||
function matchVersion(versions: Release[], range: string, includePrerelease?: boolean): Release { | ||
// If a prerelease version range is given, it will only match in that series (0.14-rc0, 0.14-rc1) | ||
// unless includePrerelease is set to true | ||
// https://www.npmjs.com/package/semver#prerelease-tags | ||
const version = semver.maxSatisfying(Object.keys(versions), range, { includePrerelease }); | ||
if (version) { | ||
return new Release(versions[version]); | ||
} else { | ||
throw new Error("No matching version found"); | ||
} | ||
// If a prerelease version range is given, it will only match in that series (0.14-rc0, 0.14-rc1) | ||
// unless includePrerelease is set to true | ||
// https://www.npmjs.com/package/semver#prerelease-tags | ||
const version = semver.maxSatisfying(Object.keys(versions), range, { includePrerelease }); | ||
if (version) { | ||
return new Release(versions[version]); | ||
} else { | ||
throw new Error('No matching version found'); | ||
} | ||
} |
@@ -1,6 +0,6 @@ | ||
import axiosBase, { AxiosRequestConfig } from "axios"; | ||
const ProxyAgent = require("proxy-agent"); | ||
import axiosBase, { AxiosRequestConfig } from 'axios'; | ||
const ProxyAgent = require('proxy-agent'); | ||
const httpProxy = process.env["HTTP_PROXY"] || process.env["http_proxy"]; | ||
const httpsProxy = process.env["HTTPS_PROXY"] || process.env["https_proxy"]; | ||
const httpProxy = process.env['HTTP_PROXY'] || process.env['http_proxy']; | ||
const httpsProxy = process.env['HTTPS_PROXY'] || process.env['https_proxy']; | ||
@@ -19,8 +19,5 @@ let proxyConf = {}; | ||
export async function request<T = any>( | ||
url: string, | ||
options: AxiosRequestConfig = {} | ||
): Promise<T> { | ||
export async function request<T = any>(url: string, options: AxiosRequestConfig = {}): Promise<T> { | ||
const result = await axios.get(url, { ...options }); | ||
return result.data; | ||
} |
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"target": "es6", | ||
"outDir": "out", | ||
"rootDir": "src", | ||
"sourceMap": true, | ||
"declaration": true | ||
}, | ||
"include": [ | ||
"src" | ||
], | ||
"exclude": [ | ||
"node_modules", | ||
"out" | ||
] | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"target": "es6", | ||
"outDir": "out", | ||
"rootDir": "src", | ||
"sourceMap": true, | ||
"declaration": true | ||
}, | ||
"include": ["src"], | ||
"exclude": ["node_modules", "out"] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
53245
25
755
0
8
6