content/frontend/services/fetch_versions.js (54 lines of code) (raw):
/* eslint-disable no-console */
import { satisfies, compareVersions } from 'compare-versions';
const DOCS_VERSIONS_ENDPOINT = 'https://docs.gitlab.com/versions.json';
const ARCHIVE_VERSIONS_ENDPOINT = 'https://archives.docs.gitlab.com/archive_versions.json';
// Archived versions moved registries starting with 15.5.
const DOCS_IMAGES_ENDPOINT_V1 =
'https://gitlab.com/api/v4/projects/1794617/registry/repositories/631635/tags?per_page=100';
const DOCS_IMAGES_ENDPOINT_V2 =
'https://gitlab.com/api/v4/projects/1794617/registry/repositories/3631228/tags?per_page=100';
export const SITE_VERSION = document
.querySelector('meta[name="gitlab-docs-version"]')
?.getAttribute('content');
/**
* Fetch a list of versions available on docs.gitlab.com.
*
* @returns Array
*/
let cachedVersions = null;
export async function getVersions() {
if (!cachedVersions) {
try {
const data = await (await fetch(DOCS_VERSIONS_ENDPOINT)).json();
cachedVersions = Object.assign(...data);
} catch (error) {
console.error(error);
}
}
return cachedVersions || [];
}
/**
* Fetch a list of archived versions available as container images.
*
* The Archive image endpoint changed in 15.5, so we need to query
* two separate endpoints and combine the result to build our list.
*
* @returns Array
*/
const fetchArchiveImages = async (endpoint, versionRange) => {
try {
const response = await fetch(endpoint);
const data = await response.json();
return data.filter(
(object) => !Number.isNaN(Number(object.name)) && satisfies(object.name, versionRange),
);
} catch (error) {
console.error(error);
return [];
}
};
export async function getArchiveImages() {
const images = await fetchArchiveImages(DOCS_IMAGES_ENDPOINT_V1, '<15.6');
const newerImages = await fetchArchiveImages(DOCS_IMAGES_ENDPOINT_V2, '>=15.6');
return (
[...images, ...newerImages].sort((a, b) => compareVersions(a.name, b.name)).reverse() || []
);
}
/**
* Fetch a list of site versions available on the Archives site.
*
* @returns Array
*/
export async function getArchivesVersions() {
const versions = await fetch(ARCHIVE_VERSIONS_ENDPOINT)
.then((response) => response.json())
.catch((error) => console.error(error));
return versions || [];
}
/**
* Check if a version of the site is archived.
*
* All versions except the pre-release and most
* recent stable version are considered archived
* versions.
*
* Note that this will return false in an offline
* or air-gapped environment.
*
* @returns Boolean
*/
export async function isOnlineArchivedVersion(version) {
const onlineVersions = await getVersions();
if (Object.keys(onlineVersions).length > 0) {
return ![onlineVersions.next, onlineVersions.current].includes(version);
}
return false;
}