From dcbef85813d5e698a11d927fe5317a6953c77094 Mon Sep 17 00:00:00 2001
From: Sergio Zharinov <zharinov@users.noreply.github.com>
Date: Mon, 1 Jun 2020 16:01:09 +0400
Subject: [PATCH] refactor(gitea): Switch to new http wrapper (#6394)

---
 lib/platform/gitea/gitea-got-wrapper.ts       |  68 ------------
 lib/platform/gitea/gitea-helper.spec.ts       |   4 +-
 lib/platform/gitea/gitea-helper.ts            | 102 +++++++++---------
 lib/platform/gitea/index.spec.ts              |   3 +
 lib/platform/gitea/index.ts                   |   4 +-
 .../http/__snapshots__/gitea.spec.ts.snap}    |   6 +-
 .../http/gitea.spec.ts}                       |  21 ++--
 lib/util/http/gitea.ts                        |  62 +++++++++++
 8 files changed, 138 insertions(+), 132 deletions(-)
 delete mode 100644 lib/platform/gitea/gitea-got-wrapper.ts
 rename lib/{platform/gitea/__snapshots__/gitea-got-wrapper.spec.ts.snap => util/http/__snapshots__/gitea.spec.ts.snap} (89%)
 rename lib/{platform/gitea/gitea-got-wrapper.spec.ts => util/http/gitea.spec.ts} (76%)
 create mode 100644 lib/util/http/gitea.ts

diff --git a/lib/platform/gitea/gitea-got-wrapper.ts b/lib/platform/gitea/gitea-got-wrapper.ts
deleted file mode 100644
index 26f4d7cff7..0000000000
--- a/lib/platform/gitea/gitea-got-wrapper.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { URL } from 'url';
-import { PLATFORM_TYPE_GITEA } from '../../constants/platforms';
-import got from '../../util/got';
-import { GotApi, GotApiOptions, GotResponse } from '../common';
-
-const hostType = PLATFORM_TYPE_GITEA;
-let baseUrl: string;
-
-function getPaginationContainer(body: any): any[] {
-  if (Array.isArray(body) && body.length) {
-    return body;
-  }
-  if (Array.isArray(body?.data) && body.data.length) {
-    return body.data;
-  }
-
-  return null;
-}
-
-async function get(path: string, options?: any): Promise<GotResponse> {
-  const opts = {
-    hostType,
-    baseUrl,
-    json: true,
-    ...options,
-  };
-
-  const res = await got(path, opts);
-  const pc = getPaginationContainer(res.body);
-  if (opts.paginate && pc) {
-    const url = new URL(res.url);
-    const total = parseInt(res.headers['x-total-count'] as string, 10);
-    let nextPage = parseInt(url.searchParams.get('page') || '1', 10);
-
-    while (total && pc.length < total) {
-      nextPage += 1;
-      url.searchParams.set('page', nextPage.toString());
-
-      const nextRes = await got(url.toString(), opts);
-      pc.push(...getPaginationContainer(nextRes.body));
-    }
-  }
-
-  return res;
-}
-
-const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
-
-export type GiteaGotOptions = {
-  paginate?: boolean;
-  token?: string;
-} & GotApiOptions;
-
-export interface GiteaGotApi extends GotApi<GiteaGotOptions> {
-  setBaseUrl(url: string): void;
-}
-
-export const api: GiteaGotApi = {} as any;
-
-for (const x of helpers) {
-  (api as any)[x] = (path: string, options: any): Promise<GotResponse> =>
-    get(path, { ...options, method: x.toUpperCase() });
-}
-
-// eslint-disable-next-line @typescript-eslint/unbound-method
-api.setBaseUrl = (e: string): void => {
-  baseUrl = e;
-};
diff --git a/lib/platform/gitea/gitea-helper.spec.ts b/lib/platform/gitea/gitea-helper.spec.ts
index d1cce2fd5e..5115c9ebb8 100644
--- a/lib/platform/gitea/gitea-helper.spec.ts
+++ b/lib/platform/gitea/gitea-helper.spec.ts
@@ -1,6 +1,6 @@
 import * as httpMock from '../../../test/httpMock';
 import { PR_STATE_CLOSED } from '../../constants/pull-requests';
-import { api } from './gitea-got-wrapper';
+import { setBaseUrl } from '../../util/http/gitea';
 import * as ght from './gitea-helper';
 
 describe('platform/gitea/gitea-helper', () => {
@@ -141,7 +141,7 @@ describe('platform/gitea/gitea-helper', () => {
     jest.resetAllMocks();
     httpMock.reset();
     httpMock.setup();
-    api.setBaseUrl(baseUrl);
+    setBaseUrl(baseUrl);
   });
 
   describe('getCurrentUser', () => {
diff --git a/lib/platform/gitea/gitea-helper.ts b/lib/platform/gitea/gitea-helper.ts
index fd7e48a0b2..60ba5f35d3 100644
--- a/lib/platform/gitea/gitea-helper.ts
+++ b/lib/platform/gitea/gitea-helper.ts
@@ -1,8 +1,9 @@
 import { URLSearchParams } from 'url';
 import { PR_STATE_CLOSED } from '../../constants/pull-requests';
 import { BranchStatus } from '../../types';
-import { GotResponse } from '../common';
-import { GiteaGotOptions, api } from './gitea-got-wrapper';
+import { GiteaHttp, GiteaHttpOptions } from '../../util/http/gitea';
+
+const giteaHttp = new GiteaHttp();
 
 export type PRState = 'open' | 'closed' | 'all';
 export type IssueState = 'open' | 'closed' | 'all';
@@ -200,20 +201,21 @@ function queryParams(params: Record<string, any>): URLSearchParams {
   return usp;
 }
 
-export async function getCurrentUser(options?: GiteaGotOptions): Promise<User> {
+export async function getCurrentUser(
+  options?: GiteaHttpOptions
+): Promise<User> {
   const url = 'user';
-  const res: GotResponse<User> = await api.get(url, options);
-
+  const res = await giteaHttp.getJson<User>(url, options);
   return res.body;
 }
 
 export async function searchRepos(
   params: RepoSearchParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Repo[]> {
   const query = queryParams(params).toString();
   const url = `repos/search?${query}`;
-  const res: GotResponse<RepoSearchResults> = await api.get(url, {
+  const res = await giteaHttp.getJson<RepoSearchResults>(url, {
     ...options,
     paginate: true,
   });
@@ -229,11 +231,10 @@ export async function searchRepos(
 
 export async function getRepo(
   repoPath: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Repo> {
   const url = `repos/${repoPath}`;
-  const res: GotResponse<Repo> = await api.get(url, options);
-
+  const res = await giteaHttp.getJson<Repo>(url, options);
   return res.body;
 }
 
@@ -241,11 +242,11 @@ export async function getRepoContents(
   repoPath: string,
   filePath: string,
   ref?: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<RepoContents> {
   const query = queryParams(ref ? { ref } : {}).toString();
   const url = `repos/${repoPath}/contents/${urlEscape(filePath)}?${query}`;
-  const res: GotResponse<RepoContents> = await api.get(url, options);
+  const res = await giteaHttp.getJson<RepoContents>(url, options);
 
   if (res.body.content) {
     res.body.contentString = Buffer.from(res.body.content, 'base64').toString();
@@ -257,10 +258,10 @@ export async function getRepoContents(
 export async function createPR(
   repoPath: string,
   params: PRCreateParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<PR> {
   const url = `repos/${repoPath}/pulls`;
-  const res: GotResponse<PR> = await api.post(url, {
+  const res = await giteaHttp.postJson<PR>(url, {
     ...options,
     body: params,
   });
@@ -272,10 +273,10 @@ export async function updatePR(
   repoPath: string,
   idx: number,
   params: PRUpdateParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<PR> {
   const url = `repos/${repoPath}/pulls/${idx}`;
-  const res: GotResponse<PR> = await api.patch(url, {
+  const res = await giteaHttp.patchJson<PR>(url, {
     ...options,
     body: params,
   });
@@ -286,7 +287,7 @@ export async function updatePR(
 export async function closePR(
   repoPath: string,
   idx: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<void> {
   await updatePR(repoPath, idx, {
     ...options,
@@ -298,11 +299,11 @@ export async function mergePR(
   repoPath: string,
   idx: number,
   method: PRMergeMethod,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<void> {
   const params: PRMergeParams = { Do: method };
   const url = `repos/${repoPath}/pulls/${idx}/merge`;
-  await api.post(url, {
+  await giteaHttp.postJson(url, {
     ...options,
     body: params,
   });
@@ -311,22 +312,21 @@ export async function mergePR(
 export async function getPR(
   repoPath: string,
   idx: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<PR> {
   const url = `repos/${repoPath}/pulls/${idx}`;
-  const res: GotResponse<PR> = await api.get(url, options);
-
+  const res = await giteaHttp.getJson<PR>(url, options);
   return res.body;
 }
 
 export async function searchPRs(
   repoPath: string,
   params: PRSearchParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<PR[]> {
   const query = queryParams(params).toString();
   const url = `repos/${repoPath}/pulls?${query}`;
-  const res: GotResponse<PR[]> = await api.get(url, {
+  const res = await giteaHttp.getJson<PR[]>(url, {
     ...options,
     paginate: true,
   });
@@ -337,10 +337,10 @@ export async function searchPRs(
 export async function createIssue(
   repoPath: string,
   params: IssueCreateParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Issue> {
   const url = `repos/${repoPath}/issues`;
-  const res: GotResponse<Issue> = await api.post(url, {
+  const res = await giteaHttp.postJson<Issue>(url, {
     ...options,
     body: params,
   });
@@ -352,10 +352,10 @@ export async function updateIssue(
   repoPath: string,
   idx: number,
   params: IssueUpdateParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Issue> {
   const url = `repos/${repoPath}/issues/${idx}`;
-  const res: GotResponse<Issue> = await api.patch(url, {
+  const res = await giteaHttp.patchJson<Issue>(url, {
     ...options,
     body: params,
   });
@@ -366,7 +366,7 @@ export async function updateIssue(
 export async function closeIssue(
   repoPath: string,
   idx: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<void> {
   await updateIssue(repoPath, idx, {
     ...options,
@@ -377,11 +377,11 @@ export async function closeIssue(
 export async function searchIssues(
   repoPath: string,
   params: IssueSearchParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Issue[]> {
   const query = queryParams(params).toString();
   const url = `repos/${repoPath}/issues?${query}`;
-  const res: GotResponse<Issue[]> = await api.get(url, {
+  const res = await giteaHttp.getJson<Issue[]>(url, {
     ...options,
     paginate: true,
   });
@@ -391,20 +391,20 @@ export async function searchIssues(
 
 export async function getRepoLabels(
   repoPath: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Label[]> {
   const url = `repos/${repoPath}/labels`;
-  const res: GotResponse<Label[]> = await api.get(url, options);
+  const res = await giteaHttp.getJson<Label[]>(url, options);
 
   return res.body;
 }
 
 export async function getOrgLabels(
   orgName: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Label[]> {
   const url = `orgs/${orgName}/labels`;
-  const res: GotResponse<Label[]> = await api.get(url, options);
+  const res = await giteaHttp.getJson<Label[]>(url, options);
 
   return res.body;
 }
@@ -413,21 +413,21 @@ export async function unassignLabel(
   repoPath: string,
   issue: number,
   label: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<void> {
   const url = `repos/${repoPath}/issues/${issue}/labels/${label}`;
-  await api.delete(url, options);
+  await giteaHttp.deleteJson(url, options);
 }
 
 export async function createComment(
   repoPath: string,
   issue: number,
   body: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Comment> {
   const params: CommentCreateParams = { body };
   const url = `repos/${repoPath}/issues/${issue}/comments`;
-  const res: GotResponse<Comment> = await api.post(url, {
+  const res = await giteaHttp.postJson<Comment>(url, {
     ...options,
     body: params,
   });
@@ -439,11 +439,11 @@ export async function updateComment(
   repoPath: string,
   idx: number,
   body: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Comment> {
   const params: CommentUpdateParams = { body };
   const url = `repos/${repoPath}/issues/comments/${idx}`;
-  const res: GotResponse<Comment> = await api.patch(url, {
+  const res = await giteaHttp.patchJson<Comment>(url, {
     ...options,
     body: params,
   });
@@ -454,19 +454,19 @@ export async function updateComment(
 export async function deleteComment(
   repoPath,
   idx: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<void> {
   const url = `repos/${repoPath}/issues/comments/${idx}`;
-  await api.delete(url, options);
+  await giteaHttp.deleteJson(url, options);
 }
 
 export async function getComments(
   repoPath,
   issue: number,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Comment[]> {
   const url = `repos/${repoPath}/issues/${issue}/comments`;
-  const res: GotResponse<Comment[]> = await api.get(url, options);
+  const res = await giteaHttp.getJson<Comment[]>(url, options);
 
   return res.body;
 }
@@ -475,10 +475,10 @@ export async function createCommitStatus(
   repoPath: string,
   branchCommit: string,
   params: CommitStatusCreateParams,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<CommitStatus> {
   const url = `repos/${repoPath}/statuses/${branchCommit}`;
-  const res: GotResponse<CommitStatus> = await api.post(url, {
+  const res = await giteaHttp.postJson<CommitStatus>(url, {
     ...options,
     body: params,
   });
@@ -523,10 +523,10 @@ function filterStatus(data: CommitStatus[]): CommitStatus[] {
 export async function getCombinedCommitStatus(
   repoPath: string,
   branchName: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<CombinedCommitStatus> {
   const url = `repos/${repoPath}/commits/${urlEscape(branchName)}/statuses`;
-  const res: GotResponse<CommitStatus[]> = await api.get(url, {
+  const res = await giteaHttp.getJson<CommitStatus[]>(url, {
     ...options,
     paginate: true,
   });
@@ -545,10 +545,10 @@ export async function getCombinedCommitStatus(
 export async function getBranch(
   repoPath: string,
   branchName: string,
-  options?: GiteaGotOptions
+  options?: GiteaHttpOptions
 ): Promise<Branch> {
   const url = `repos/${repoPath}/branches/${urlEscape(branchName)}`;
-  const res: GotResponse<Branch> = await api.get(url, options);
+  const res = await giteaHttp.getJson<Branch>(url, options);
 
   return res.body;
 }
diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts
index 98333eeaf4..0a0ea9f36c 100644
--- a/lib/platform/gitea/index.spec.ts
+++ b/lib/platform/gitea/index.spec.ts
@@ -18,6 +18,7 @@ import {
 } from '../../constants/error-messages';
 import { logger as _logger } from '../../logger';
 import { BranchStatus } from '../../types';
+import { setBaseUrl } from '../../util/http/gitea';
 import * as ght from './gitea-helper';
 
 describe('platform/gitea', () => {
@@ -201,6 +202,8 @@ describe('platform/gitea', () => {
     }));
 
     global.gitAuthor = { name: 'Renovate', email: 'renovate@example.com' };
+
+    setBaseUrl('https://gitea.renovatebot.com/api/v1');
   });
 
   function initFakeRepo(
diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts
index ae71c3fc56..62947e6bd2 100644
--- a/lib/platform/gitea/index.ts
+++ b/lib/platform/gitea/index.ts
@@ -15,6 +15,7 @@ import { PR_STATE_ALL, PR_STATE_OPEN } from '../../constants/pull-requests';
 import { logger } from '../../logger';
 import { BranchStatus } from '../../types';
 import * as hostRules from '../../util/host-rules';
+import { setBaseUrl } from '../../util/http/gitea';
 import { sanitize } from '../../util/sanitize';
 import { ensureTrailingSlash } from '../../util/url';
 import {
@@ -35,7 +36,6 @@ import {
 } from '../common';
 import GitStorage, { StatusResult } from '../git/storage';
 import { smartTruncate } from '../utils/pr-body';
-import { api } from './gitea-got-wrapper';
 import * as helper from './gitea-helper';
 
 type GiteaRenovateConfig = {
@@ -224,7 +224,7 @@ const platform: Platform = {
     } else {
       logger.debug('Using default Gitea endpoint: ' + defaults.endpoint);
     }
-    api.setBaseUrl(defaults.endpoint);
+    setBaseUrl(defaults.endpoint);
 
     let gitAuthor: string;
     try {
diff --git a/lib/platform/gitea/__snapshots__/gitea-got-wrapper.spec.ts.snap b/lib/util/http/__snapshots__/gitea.spec.ts.snap
similarity index 89%
rename from lib/platform/gitea/__snapshots__/gitea-got-wrapper.spec.ts.snap
rename to lib/util/http/__snapshots__/gitea.spec.ts.snap
index c72a7fa4e0..42efc4a783 100644
--- a/lib/platform/gitea/__snapshots__/gitea-got-wrapper.spec.ts.snap
+++ b/lib/util/http/__snapshots__/gitea.spec.ts.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`platform/gitea/gitea-got-wrapper supports pagination on data property 1`] = `
+exports[`util/http/gitea supports pagination on data property 1`] = `
 Array [
   Object {
     "headers": Object {
@@ -35,7 +35,7 @@ Array [
 ]
 `;
 
-exports[`platform/gitea/gitea-got-wrapper supports responses without pagination when enabled 1`] = `
+exports[`util/http/gitea supports responses without pagination when enabled 1`] = `
 Array [
   Object {
     "headers": Object {
@@ -50,7 +50,7 @@ Array [
 ]
 `;
 
-exports[`platform/gitea/gitea-got-wrapper supports root-level pagination 1`] = `
+exports[`util/http/gitea supports root-level pagination 1`] = `
 Array [
   Object {
     "headers": Object {
diff --git a/lib/platform/gitea/gitea-got-wrapper.spec.ts b/lib/util/http/gitea.spec.ts
similarity index 76%
rename from lib/platform/gitea/gitea-got-wrapper.spec.ts
rename to lib/util/http/gitea.spec.ts
index 69ef28291a..bb5ecd2d3c 100644
--- a/lib/platform/gitea/gitea-got-wrapper.spec.ts
+++ b/lib/util/http/gitea.spec.ts
@@ -1,16 +1,21 @@
 import * as httpMock from '../../../test/httpMock';
-import { api } from './gitea-got-wrapper';
+import { getName } from '../../../test/util';
+import { GiteaHttp, setBaseUrl } from './gitea';
 
-describe('platform/gitea/gitea-got-wrapper', () => {
+describe(getName(__filename), () => {
   const baseUrl = 'https://gitea.renovatebot.com/api/v1';
 
+  let giteaHttp: GiteaHttp;
+
   beforeEach(() => {
+    giteaHttp = new GiteaHttp();
+
     jest.resetAllMocks();
 
     httpMock.reset();
     httpMock.setup();
 
-    api.setBaseUrl(baseUrl);
+    setBaseUrl(baseUrl);
   });
 
   it('supports responses without pagination when enabled', async () => {
@@ -19,7 +24,9 @@ describe('platform/gitea/gitea-got-wrapper', () => {
       .get('/pagination-example-1')
       .reply(200, { hello: 'world' });
 
-    const res = await api.get('pagination-example-1', { paginate: true });
+    const res = await giteaHttp.getJson('pagination-example-1', {
+      paginate: true,
+    });
     expect(res.body).toEqual({ hello: 'world' });
     expect(httpMock.getTrace()).toMatchSnapshot();
   });
@@ -34,7 +41,7 @@ describe('platform/gitea/gitea-got-wrapper', () => {
       .get('/pagination-example-1?page=3')
       .reply(200, ['mno', 'pqr']);
 
-    const res = await api.get(`${baseUrl}/pagination-example-1`, {
+    const res = await giteaHttp.getJson(`${baseUrl}/pagination-example-1`, {
       paginate: true,
     });
     httpMock.getTrace();
@@ -54,7 +61,9 @@ describe('platform/gitea/gitea-got-wrapper', () => {
       .get('/pagination-example-2?page=3')
       .reply(200, { data: ['mno', 'pqr'] });
 
-    const res = await api.get('pagination-example-2', { paginate: true });
+    const res = await giteaHttp.getJson<{ data: any }>('pagination-example-2', {
+      paginate: true,
+    });
     expect(res.body.data).toHaveLength(6);
     expect(res.body.data).toEqual(['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr']);
     expect(httpMock.getTrace()).toMatchSnapshot();
diff --git a/lib/util/http/gitea.ts b/lib/util/http/gitea.ts
new file mode 100644
index 0000000000..d9d4867242
--- /dev/null
+++ b/lib/util/http/gitea.ts
@@ -0,0 +1,62 @@
+import url from 'url';
+import { PLATFORM_TYPE_GITEA } from '../../constants/platforms';
+import { Http, HttpOptions, HttpResponse, InternalHttpOptions } from '.';
+
+let baseUrl;
+export const setBaseUrl = (newBaseUrl: string): void => {
+  baseUrl = newBaseUrl.replace(/\/*$/, '/');
+};
+
+export interface GiteaHttpOptions extends InternalHttpOptions {
+  paginate?: boolean;
+  token?: string;
+}
+
+function getPaginationContainer(body: any): any[] {
+  if (Array.isArray(body) && body.length) {
+    return body;
+  }
+  if (Array.isArray(body?.data) && body.data.length) {
+    return body.data;
+  }
+
+  return null;
+}
+
+function resolveUrl(path: string): URL {
+  const resolvedUrlString = url.resolve(baseUrl, path);
+  return new url.URL(resolvedUrlString);
+}
+
+export class GiteaHttp extends Http<GiteaHttpOptions, GiteaHttpOptions> {
+  constructor(options?: HttpOptions) {
+    super(PLATFORM_TYPE_GITEA, options);
+  }
+
+  protected async request<T>(
+    path: string,
+    options?: InternalHttpOptions & GiteaHttpOptions
+  ): Promise<HttpResponse<T> | null> {
+    const resolvedUrl = resolveUrl(path);
+    const opts = {
+      baseUrl,
+      ...options,
+    };
+    const res = await super.request<T>(resolvedUrl, opts);
+    const pc = getPaginationContainer(res.body);
+    if (opts.paginate && pc) {
+      const total = parseInt(res.headers['x-total-count'] as string, 10);
+      let nextPage = parseInt(resolvedUrl.searchParams.get('page') || '1', 10);
+
+      while (total && pc.length < total) {
+        nextPage += 1;
+        resolvedUrl.searchParams.set('page', nextPage.toString());
+
+        const nextRes = await super.request<T>(resolvedUrl.toString(), opts);
+        pc.push(...getPaginationContainer(nextRes.body));
+      }
+    }
+
+    return res;
+  }
+}
-- 
GitLab