@talend/module-to-cdn
Version:
Get cdn config from npm module name
140 lines (113 loc) • 3.69 kB
JavaScript
const axios = require('axios');
const axiosRetry = require('axios-retry');
const fs = require('fs');
const path = require('path');
const execa = require('execa');
const semver = require('semver');
const mkdirp = require('mkdirp');
const CACHE_BASE_PATH = `${process.cwd()}/.test-cache`;
const CACHE_NPM_PATH = `${CACHE_BASE_PATH}/.npm-cache-info.json`;
const CACHE_NPM = {
__last: Date.now()
};
if (fs.existsSync(CACHE_NPM_PATH)) {
const cache = require(CACHE_NPM_PATH);
if (Date.now() - cache.__last < 1000 * 60 * 60) {
console.log('use cache on NPM');
Object.assign(CACHE_NPM, cache);
} else {
console.log('reset NPM cache');
}
}
const AXIOS_CACHE_PATH = `${CACHE_BASE_PATH}/axios`;
axiosRetry(axios, {retries: 3, retryDelay: () => 3000});
function ensureCacheFolderExists() {
if (!fs.existsSync(CACHE_BASE_PATH)) {
console.log('Setup cache for testing');
fs.mkdirSync(CACHE_BASE_PATH);
}
if (!fs.existsSync(AXIOS_CACHE_PATH)) {
console.log(`Setup cache folder for axios request in ${AXIOS_CACHE_PATH}`);
fs.mkdirSync(AXIOS_CACHE_PATH);
}
}
function getInfo(url) {
ensureCacheFolderExists();
const info = {};
const splitted = url.replace('https://unpkg.com/', '').split('/');
const [packageAndVersion, inCase, ...restPath] = splitted;
if (packageAndVersion.startsWith('@')) {
const [n, version] = inCase.split('@');
info.name = `${packageAndVersion}/${n}`;
info.version = version;
info.path = restPath.join('/');
} else {
const [n, version] = packageAndVersion.split('@');
info.name = n;
info.version = version;
info.path = [inCase, ...restPath].join('/');
}
return info;
}
function getPathFromURL(url) {
const info = getInfo(url);
return `${AXIOS_CACHE_PATH}/${info.name}/${info.version}/${info.path}`;
}
async function cachedGet(url) {
ensureCacheFolderExists();
const pathFromURL = getPathFromURL(url);
if (fs.existsSync(pathFromURL)) {
return Promise.resolve({data: fs.readFileSync(pathFromURL).toString()});
}
try {
const response = await axios.get(url);
if (process.env.DEBUG) {
console.debug('downloaded', url);
}
mkdirp.sync(path.dirname(pathFromURL));
fs.writeFileSync(pathFromURL, response.data);
return response;
} catch (error) {
console.error('DownloadError', url, error.message);
return Promise.reject(error);
}
}
function isInCache(url) {
return fs.existsSync(getPathFromURL(url));
}
function getModuleInfo(moduleName) {
ensureCacheFolderExists();
if (!CACHE_NPM[moduleName]) {
const info = JSON.parse(execa.sync('npm', ['info', '--json', `${moduleName}`]).stdout);
CACHE_NPM[moduleName] = {
'dist-tags': info['dist-tags'],
versions: info.versions
};
fs.writeFileSync(CACHE_NPM_PATH, JSON.stringify(CACHE_NPM));
}
return CACHE_NPM[moduleName];
}
function getAllVersions(moduleName) {
return getModuleInfo(moduleName).versions;
}
function getRangeEdgeVersions(allVersions) {
return function (range) {
const result = [];
const values = allVersions.filter(version => semver.satisfies(version, range));
if (values.length > 0) {
result.push(values[0]);
}
if (values.length > 1) {
result.push(values[values.length - 1]);
}
return result;
};
}
module.exports = {
cachedGet,
isInCache,
getModuleInfo,
getAllVersions,
getRangeEdgeVersions,
getPathFromURL
};