@canonical/jujulib
Version:
Juju API client
91 lines (83 loc) • 2.5 kB
text/typescript
export const parseVersion = (version: string): number[] =>
version.split(".").map((v) => parseInt(v));
const versionGreaterThan = (v1: string, v2: string): boolean => {
const v1Parts = parseVersion(v1);
const v2Parts = parseVersion(v2);
for (let i = 0; i < v1Parts.length; i++) {
const v1Part = v1Parts[i];
const v2Part = v2Parts[i];
if (v1Part > v2Part) {
return true;
} else if (v1Part < v2Part) {
return false;
}
}
return false;
};
const sortVersions = (versions: string[]): string[] =>
versions?.sort((v1, v2) => {
if (versionGreaterThan(v1, v2)) {
return -1;
} else if (versionGreaterThan(v2, v1)) {
return 1;
}
return 0;
});
type APIPayload = {
dashboard: string;
juju: string[];
};
/**
* Avoid making multiple requests to the API by caching the response.
*/
export let cachedAPIResponse: { data: APIPayload; fetchedAt: Date } | null =
null;
const TTL = 1000 * 60 * 60; // 1 hours
/**
* Fetch the latest Juju versions from the API.
*/
const fetchVersions = async () => {
if (
cachedAPIResponse &&
cachedAPIResponse.fetchedAt.getTime() + TTL > new Date().getTime()
)
return cachedAPIResponse.data;
cachedAPIResponse = null;
const response = await fetch("https://juju.is/latest.json");
const data: APIPayload | undefined = await response?.json();
if (!data) {
return null;
}
cachedAPIResponse = {
data: { ...data, juju: sortVersions(data.juju) },
fetchedAt: new Date(),
};
return cachedAPIResponse.data;
};
/**
* Check the Juju controller version against the latest available
* version (ignores the patch version).
* @param jujuVersion The version of the Juju controller to check
* @returns
*/
export const jujuUpdateAvailable = async (jujuVersion: string) => {
const jujuVersions = (await fetchVersions())?.juju;
if (!jujuVersions) {
return null;
}
const latestAvailableVersion = jujuVersions.slice(-1)[0];
return versionGreaterThan(latestAvailableVersion, jujuVersion);
};
/**
* Check the Juju dashboard version against the latest available
* version (ignore the patch version).
* @param dashboardVersion The version of the Juju dashboard to check
* @returns
*/
export const dashboardUpdateAvailable = async (dashboardVersion: string) => {
const latestDashboardVersion = (await fetchVersions())?.dashboard;
if (!latestDashboardVersion) {
return null;
}
return versionGreaterThan(latestDashboardVersion, dashboardVersion);
};