From a18ca9952aed7849284a25654a81999277f5b3fe Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Mon, 9 Dec 2024 16:45:05 +0100 Subject: [PATCH 1/6] API: use APIv3 endpoint for resources Initial implementation as a POC to give it a try. It works fine at first sight and I think it could be a good idea to move forward with it. I didn't find any blocker yet. Closes #356 --- src/index.js | 8 ++++-- src/readthedocs-config.js | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index ad761db6..f277cbee 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,7 @@ -import { getReadTheDocsConfig } from "./readthedocs-config"; +import { + getReadTheDocsConfig, + getReadTheDocsConfigUsingAPIv3, +} from "./readthedocs-config"; import * as notification from "./notification"; import * as analytics from "./analytics"; import * as search from "./search"; @@ -45,7 +48,8 @@ export function setup() { } } - return getReadTheDocsConfig(sendUrlParam); + // return getReadTheDocsConfig(sendUrlParam); + return getReadTheDocsConfigUsingAPIv3(sendUrlParam); }) .then((config) => { const loadWhenEmbedded = objectPath.get( diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index d597009d..56bc5a1a 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -129,6 +129,57 @@ export function getReadTheDocsConfig(sendUrlParam) { }); } +export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { + // TODO: get the project/version slug from the META tags + const projectResponse = fetch("/_/api/v3/projects/test-builds/"); + const translationsResponse = fetch( + "/_/api/v3/projects/test-builds/translations/", + ); + const versionResponse = fetch( + "/_/api/v3/projects/test-builds/versions/full-feature/", + ); + const activeVersionsResponse = fetch( + "/_/api/v3/projects/test-builds/versions/?active=true", + ); + const buildResponse = fetch("/_/api/v3/projects/test-builds/builds/3111/"); + + const responses = await Promise.all([ + projectResponse, + translationsResponse, + versionResponse, + activeVersionsResponse, + buildResponse, + ]); + + const [project, translations, version, activeVersions, build] = + await Promise.all(responses.map((response) => response.json())); + + // TODO: we are missing the data from the `/_/addons/` endpoint that are not resources. + // We need to perform another request for that. + const dataEvent = { + builds: { + current: build, + }, + projects: { + current: project, + translations: translations.results, + }, + versions: { + active: activeVersions.results, + current: version, + }, + }; + + // Trigger the addons data ready CustomEvent to with the data the user is expecting. + dispatchEvent( + EVENT_READTHEDOCS_ADDONS_DATA_READY, + document, + new ReadTheDocsEventData(dataEvent), + ); + + return dataEvent; +} + function dispatchEvent(eventName, element, data) { const event = new CustomEvent(eventName, { detail: data }); element.dispatchEvent(event); From ddeb084723fb9ecb63dd99641a711358c6725e43 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 12 Dec 2024 18:19:10 +0100 Subject: [PATCH 2/6] Mix addons API endpoint with APIv3 endpoints --- src/readthedocs-config.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index 56bc5a1a..ba39c767 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -130,6 +130,9 @@ export function getReadTheDocsConfig(sendUrlParam) { } export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { + const defaultApiUrl = _getApiUrl(sendUrlParam, ADDONS_API_VERSION); + const addonsResponse = fetch(defaultApiUrl); + // TODO: get the project/version slug from the META tags const projectResponse = fetch("/_/api/v3/projects/test-builds/"); const translationsResponse = fetch( @@ -144,6 +147,7 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { const buildResponse = fetch("/_/api/v3/projects/test-builds/builds/3111/"); const responses = await Promise.all([ + addonsResponse, projectResponse, translationsResponse, versionResponse, @@ -151,12 +155,12 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { buildResponse, ]); - const [project, translations, version, activeVersions, build] = + const [addons, project, translations, version, activeVersions, build] = await Promise.all(responses.map((response) => response.json())); // TODO: we are missing the data from the `/_/addons/` endpoint that are not resources. // We need to perform another request for that. - const dataEvent = { + Object.assign(addons, { builds: { current: build, }, @@ -168,16 +172,16 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { active: activeVersions.results, current: version, }, - }; + }); // Trigger the addons data ready CustomEvent to with the data the user is expecting. dispatchEvent( EVENT_READTHEDOCS_ADDONS_DATA_READY, document, - new ReadTheDocsEventData(dataEvent), + new ReadTheDocsEventData(addons), ); - return dataEvent; + return addons; } function dispatchEvent(eventName, element, data) { From d19d740120340a19419a47db93d123c563b5cf0d Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 12 Dec 2024 18:48:03 +0100 Subject: [PATCH 3/6] Hit the endpoint for filetreediff --- src/readthedocs-config.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index ba39c767..e55ccf03 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -145,6 +145,10 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { "/_/api/v3/projects/test-builds/versions/?active=true", ); const buildResponse = fetch("/_/api/v3/projects/test-builds/builds/3111/"); + // TODO: use `?base-version=` coming from `addons.options.base_version` + const filetreediffResponse = fetch( + "/_/api/v3/projects/test-builds/versions/2109/filetreediff/?base-version=latest", + ); const responses = await Promise.all([ addonsResponse, @@ -153,10 +157,18 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { versionResponse, activeVersionsResponse, buildResponse, + filetreediffResponse, ]); - const [addons, project, translations, version, activeVersions, build] = - await Promise.all(responses.map((response) => response.json())); + const [ + addons, + project, + translations, + version, + activeVersions, + build, + filetreediff, + ] = await Promise.all(responses.map((response) => response.json())); // TODO: we are missing the data from the `/_/addons/` endpoint that are not resources. // We need to perform another request for that. @@ -174,6 +186,8 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { }, }); + Object.assign(addons["addons"]["filetreediff"], filetreediff); + // Trigger the addons data ready CustomEvent to with the data the user is expecting. dispatchEvent( EVENT_READTHEDOCS_ADDONS_DATA_READY, From b5392567525deeac35be2fbaec899f372e37fb91 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Mon, 16 Dec 2024 15:45:25 +0100 Subject: [PATCH 4/6] Use APIv3 URLs coming from the `/_/addons/` endpoint --- src/readthedocs-config.js | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index e55ccf03..a5383ba4 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -131,27 +131,27 @@ export function getReadTheDocsConfig(sendUrlParam) { export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { const defaultApiUrl = _getApiUrl(sendUrlParam, ADDONS_API_VERSION); - const addonsResponse = fetch(defaultApiUrl); + const addons = await (await fetch(defaultApiUrl)).json(); - // TODO: get the project/version slug from the META tags - const projectResponse = fetch("/_/api/v3/projects/test-builds/"); + const projectResponse = fetch( + addons.readthedocs.urls.api.v3.projects.current, + ); const translationsResponse = fetch( - "/_/api/v3/projects/test-builds/translations/", + addons.readthedocs.urls.api.v3.projects.translations, ); + const versionResponse = fetch( - "/_/api/v3/projects/test-builds/versions/full-feature/", + addons.readthedocs.urls.api.v3.versions.current, ); const activeVersionsResponse = fetch( - "/_/api/v3/projects/test-builds/versions/?active=true", + addons.readthedocs.urls.api.v3.versions.active, ); - const buildResponse = fetch("/_/api/v3/projects/test-builds/builds/3111/"); - // TODO: use `?base-version=` coming from `addons.options.base_version` + const buildResponse = fetch(addons.readthedocs.urls.api.v3.builds.current); const filetreediffResponse = fetch( - "/_/api/v3/projects/test-builds/versions/2109/filetreediff/?base-version=latest", + addons.readthedocs.urls.api.v3.filetreediff, ); const responses = await Promise.all([ - addonsResponse, projectResponse, translationsResponse, versionResponse, @@ -160,18 +160,9 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { filetreediffResponse, ]); - const [ - addons, - project, - translations, - version, - activeVersions, - build, - filetreediff, - ] = await Promise.all(responses.map((response) => response.json())); - - // TODO: we are missing the data from the `/_/addons/` endpoint that are not resources. - // We need to perform another request for that. + const [project, translations, version, activeVersions, build, filetreediff] = + await Promise.all(responses.map((response) => response.json())); + Object.assign(addons, { builds: { current: build, From 737d6f78e4ba779d6ce19e7175a1ed2fc8809f1e Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 9 Jan 2025 16:22:07 +0100 Subject: [PATCH 5/6] Explain why we are getting only 10 results --- src/readthedocs-config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index a5383ba4..d410f16a 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -143,6 +143,11 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { const versionResponse = fetch( addons.readthedocs.urls.api.v3.versions.current, ); + // TODO: the results come paginated, so we are only seeing the first 10 results. + // We need to perform more requests to get all the resulsts. + // What's the correct way to do that? + // + // The response comes with a `next` attribute that has the URL for the next 10 results. const activeVersionsResponse = fetch( addons.readthedocs.urls.api.v3.versions.active, ); From cd037dea29f4ff20104f0f8fd2dafb9cca95796e Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 9 Jan 2025 16:34:26 +0100 Subject: [PATCH 6/6] We are using the `?limit=` paramenter in the endpoint now --- src/readthedocs-config.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/readthedocs-config.js b/src/readthedocs-config.js index d410f16a..a5383ba4 100644 --- a/src/readthedocs-config.js +++ b/src/readthedocs-config.js @@ -143,11 +143,6 @@ export async function getReadTheDocsConfigUsingAPIv3(sendUrlParam) { const versionResponse = fetch( addons.readthedocs.urls.api.v3.versions.current, ); - // TODO: the results come paginated, so we are only seeing the first 10 results. - // We need to perform more requests to get all the resulsts. - // What's the correct way to do that? - // - // The response comes with a `next` attribute that has the URL for the next 10 results. const activeVersionsResponse = fetch( addons.readthedocs.urls.api.v3.versions.active, );