mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
112 lines
2.8 KiB
JavaScript
112 lines
2.8 KiB
JavaScript
import {
|
|
fetchNewPackagesList,
|
|
fetchNewPackagesListVersion,
|
|
} from "../api/aikido.js";
|
|
import {
|
|
readNewPackagesListFromLocalCache,
|
|
writeNewPackagesListToLocalCache,
|
|
} from "../config/configFile.js";
|
|
import { ui } from "../environment/userInteraction.js";
|
|
import {
|
|
getMinimumPackageAgeHours,
|
|
getEcoSystem,
|
|
ECOSYSTEM_JS,
|
|
} from "../config/settings.js";
|
|
|
|
/**
|
|
* @typedef {Object} NewPackagesDatabase
|
|
* @property {function(string, string): boolean} isNewlyReleasedPackage
|
|
*/
|
|
|
|
/** @type {NewPackagesDatabase | null} */
|
|
let cachedNewPackagesDatabase = null;
|
|
|
|
/**
|
|
* Returns the source identifier used in the feed for the current ecosystem.
|
|
* @returns {string}
|
|
*/
|
|
function getCurrentFeedSource() {
|
|
return getEcoSystem();
|
|
}
|
|
|
|
/**
|
|
* @returns {Promise<NewPackagesDatabase>}
|
|
*/
|
|
export async function openNewPackagesDatabase() {
|
|
if (cachedNewPackagesDatabase) {
|
|
return cachedNewPackagesDatabase;
|
|
}
|
|
|
|
if (getEcoSystem() !== ECOSYSTEM_JS) {
|
|
cachedNewPackagesDatabase = { isNewlyReleasedPackage: () => false };
|
|
return cachedNewPackagesDatabase;
|
|
}
|
|
|
|
const newPackagesList = await getNewPackagesList();
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {string} version
|
|
* @returns {boolean}
|
|
*/
|
|
function isNewlyReleasedPackage(name, version) {
|
|
const cutOff = new Date(
|
|
new Date().getTime() - getMinimumPackageAgeHours() * 3600 * 1000
|
|
);
|
|
const expectedSource = getCurrentFeedSource();
|
|
|
|
const entry = newPackagesList.find(
|
|
(pkg) =>
|
|
pkg.source?.toLowerCase() === expectedSource &&
|
|
pkg.name === name &&
|
|
pkg.version === version
|
|
);
|
|
|
|
if (!entry) {
|
|
return false;
|
|
}
|
|
|
|
const releasedOn = new Date(entry.released_on * 1000);
|
|
return releasedOn > cutOff;
|
|
}
|
|
|
|
cachedNewPackagesDatabase = { isNewlyReleasedPackage };
|
|
return cachedNewPackagesDatabase;
|
|
}
|
|
|
|
/**
|
|
* @returns {Promise<import("../api/aikido.js").NewPackageEntry[]>}
|
|
*/
|
|
async function getNewPackagesList() {
|
|
const { newPackagesList: cachedList, version: cachedVersion } =
|
|
readNewPackagesListFromLocalCache();
|
|
|
|
try {
|
|
if (cachedList) {
|
|
const currentVersion = await fetchNewPackagesListVersion();
|
|
if (cachedVersion === currentVersion) {
|
|
return cachedList;
|
|
}
|
|
}
|
|
|
|
const { newPackagesList, version } = await fetchNewPackagesList();
|
|
|
|
if (version) {
|
|
writeNewPackagesListToLocalCache(newPackagesList, version);
|
|
return newPackagesList;
|
|
} else {
|
|
ui.writeWarning(
|
|
"The new packages list was downloaded, but could not be cached due to a missing version."
|
|
);
|
|
return newPackagesList;
|
|
}
|
|
} catch (/** @type {any} */ error) {
|
|
if (cachedList) {
|
|
ui.writeWarning(
|
|
"Failed to fetch the latest new packages list. Using cached version."
|
|
);
|
|
return cachedList;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|