Commit 540184c1 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Migrate APIRoutesService to TS

parent 15d64695
import type {
IndexResponse,
LinksResponse,
RouteMap,
RouteMetadata,
} from '../../types/api';
import type { SidebarSettings } from '../../types/config';
import { fetchJSON } from '../util/fetch';
import { retryPromiseOperation } from '../util/retry';
/**
* Fetch an API metadata file, retrying the operation if it fails.
*
* @param {string} url
*/
function getJSON(url) {
return retryPromiseOperation(() =>
// nb. The `/api/` and `/api/links` routes are fetched without specifying
// any additional headers/config so that we can use `<link rel="preload">` in
// the `/app.html` response to fetch them early, while the client JS app
// is loading.
fetchJSON(url)
function getJSON<T>(url: string): Promise<T> {
return retryPromiseOperation(
() =>
// nb. The `/api/` and `/api/links` routes are fetched without specifying
// any additional headers/config so that we can use `<link rel="preload">` in
// the `/app.html` response to fetch them early, while the client JS app
// is loading.
fetchJSON(url) as Promise<T>
);
}
/**
* @typedef {import('../../types/api').IndexResponse} IndexResponse
* @typedef {import('../../types/api').LinksResponse} LinksResponse
* @typedef {import('../../types/api').RouteMap} RouteMap
* @typedef {import('../../types/api').RouteMetadata} RouteMetadata
* @typedef {import('../../types/config').SidebarSettings} SidebarSettings
*/
/**
* A service which fetches and caches API route metadata.
*/
// @inject
export class APIRoutesService {
/**
* @param {SidebarSettings} settings
*/
constructor(settings) {
this._apiURL = settings.apiUrl;
private _apiURL: SidebarSettings['apiUrl'];
private _routeCache: Promise<RouteMap> | null;
private _linkCache: Promise<LinksResponse> | null;
/** @type {Promise<RouteMap>|null} */
constructor(settings: SidebarSettings) {
this._apiURL = settings.apiUrl;
this._routeCache = null;
/** @type {Promise<LinksResponse>|null} */
this._linkCache = null;
}
......@@ -48,29 +43,25 @@ export class APIRoutesService {
* Routes are fetched without any authentication and therefore assumed to be
* the same regardless of whether the user is authenticated or not.
*
* @return {Promise<RouteMap>} - Map of routes to route metadata.
* @return Map of routes to route metadata.
*/
routes() {
routes(): Promise<RouteMap> {
if (!this._routeCache) {
this._routeCache = getJSON(this._apiURL).then(result => {
const index = /** @type {IndexResponse} */ (result);
return index.links;
});
this._routeCache = getJSON<IndexResponse>(this._apiURL).then(
result => result.links
);
}
return this._routeCache;
}
/**
* Fetch and cache service page links from the API.
*
* @return {Promise<LinksResponse>}
*/
links() {
links(): Promise<LinksResponse> {
if (!this._linkCache) {
this._linkCache = this.routes().then(async routes => {
const linksRoute = /** @type {RouteMetadata} */ (routes.links);
const links = await getJSON(linksRoute.url);
return /** @type {LinksResponse} */ (links);
const linksRoute = routes.links as RouteMetadata;
return getJSON<LinksResponse>(linksRoute.url);
});
}
return this._linkCache;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment