runtime-eol
Version:
check runtime versions
168 lines (141 loc) • 4.46 kB
JavaScript
const fs = require('fs');
const config = require('../config');
const specialTools = [
{
input: ['lambda', 'aws-lambda', 'sls'],
remote: 'aws-lambda',
local: 'sls',
},
];
const getLocalEol = () => {
try {
const fileContent = fs.readFileSync(config.fileName, 'utf-8');
return JSON.parse(fileContent);
}
catch(err){
console.log('getLocalEol - catch - err = %s', err.message);
return null;
}
};
const saveLocalEol = (reference) => {
try {
return fs.writeFileSync(config.fileName, JSON.stringify(reference, null, 2));
}
catch {
console.log('failed to save file...')
}
};
const getRemoteEol = async (tools=[]) => {
const reqs = tools.map(t => {
const special = specialTools.find(s => s.input.includes(t));
const remoteLabel = special ? special.remote : t;
const url = config.remoteUrl.replace('{product}', remoteLabel);
return fetch(url);
});
const results = await Promise.allSettled(reqs);
const date = new Date();
const today = date.toISOString().slice(0,10);
const list = [];
for(let i=0; i<tools.length; i++){
const label = tools[i];
const res = results[i];
const special = specialTools.find(s => s.input.includes(label));
if( res.status === 'rejected' ){
console.error(`${label} - request error - err = ${res.reason}`)
continue;
}
if(!res.value.ok){
console.error(`${label} - bad response - status = ${res.value.status}`)
continue;
}
const body = await res.value.json();
const alive = body.filter(x => x.eol >= today || !x.eol);
alive.sort((a, b) => b.releaseDate.localeCompare(a.releaseDate) );
const supported = alive.filter(x => x.support >= today);
const mapped = {
label: label,
source: config.remoteUrl,
sync: today,
};
if( special ){
supported.sort((a, b) => {
const first = a.cycle.localeCompare(b.cycle);
if( first !== 0 ){
return first;
}
return b.releaseDate.localeCompare(a.releaseDate);
});
mapped.supported = supported.map(s => {
return {
cycle: s.cycle,
support: s.support,
}
});
}
else {
const min = alive[alive.length-1];
const recommended = supported[supported.length-1] || alive[0];
mapped.min = {
cycle: min.cycle,
eol: min.eol,
latest: min.latest,
};
mapped.recommended = {
cycle: recommended.cycle,
eol: recommended.eol,
latest: recommended.latest,
};
}
list.push(mapped);
}
return list;
};
const getReference = async (skipRemote=false, tools=[]) => {
let reference = getLocalEol();
const localList = reference ? reference.tools : [];
const pastDate = new Date();
pastDate.setMonth(pastDate.getMonth() - 1);
const foundLocally = localList.filter(x => {
const syncDate = new Date(x.sync);
return tools.includes(x.label) && syncDate > pastDate;
});
console.log('getRef - skip remote = %s | found locally = %j | needed = %j',
skipRemote, foundLocally.map(x => x.label), tools
);
if( foundLocally.length === tools.length ){
console.log('getRef - found everything locally...')
return reference;
}
if( !skipRemote ){
try{
console.log('getRef - fetching remote - t = %j', tools);
const got = await getRemoteEol(tools);
console.log('getRef - got from remote - len = %s', got.length);
got.forEach(remote => {
const localIndex = localList.findIndex(x => x.label === remote.label);
if( localIndex > -1 ){
localList.splice(localIndex, 1);
}
localList.unshift(remote);
});
reference = {
tag: 'sync',
updated: localList[0]?.sync || '',
tools: localList,
};
saveLocalEol(reference);
}
catch(err){
console.log('getRef.remote - catch.unknown - err = %s', err.message, err.stack);
}
}
if( localList.length < tools.length ){
console.log('get - using failover - local = %s | need = %s', foundLocally.length, tools.length);
reference = Object.assign({}, config);
}
return reference;
};
module.exports = {
getReference: getReference,
getRemoteEol: getRemoteEol,
};