UNPKG

@talend/module-to-cdn

Version:

Get cdn config from npm module name

167 lines (141 loc) 4.58 kB
/* eslint-disable import/no-dynamic-require */ /* eslint-disable global-require */ /* eslint-disable no-underscore-dangle */ /* eslint-disable no-console */ const fs = require('fs'); const path = require('path'); const https = require('https'); const child = require('child_process'); 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`; function httpGet(url, {retry} = {retry: 0}) { return new Promise((resolve, reject) => { https .get(url, response => { const result = { status: response.statusCode, data: '' }; response.on('data', d => { result.data += d; }); response.on('end', () => { resolve(result); }); }) .on('error', error => { if (retry < 3) { const options = {retry: retry + 1}; httpGet(url, options).then(resolve).catch(reject); } else { reject(error); } }); }); } 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 response 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 httpGet(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 stdout = child.execSync(`npm info --json ${moduleName}`, {encoding: 'utf8'}); const info = JSON.parse(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 get(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 };