From a18ca9952aed7849284a25654a81999277f5b3fe Mon Sep 17 00:00:00 2001
From: Manuel Kaufmann <humitos@gmail.com>
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 <humitos@gmail.com>
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 <humitos@gmail.com>
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 <humitos@gmail.com>
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 <humitos@gmail.com>
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 <humitos@gmail.com>
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,
   );