From 3e3023fd5effca903472c2846810111bd7427a2e Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Mon, 3 Oct 2022 11:53:20 +0300
Subject: [PATCH] refactor(http): Simplify base types (#18088)

---
 .../platform/bitbucket-server/utils.ts        | 27 +++------
 lib/modules/platform/bitbucket/utils.ts       | 18 +++---
 lib/util/http/gitea.ts                        |  2 +-
 lib/util/http/github.ts                       |  5 +-
 lib/util/http/gitlab.ts                       |  2 +-
 lib/util/http/index.ts                        | 56 ++++++++-----------
 lib/util/http/types.ts                        |  6 +-
 7 files changed, 42 insertions(+), 74 deletions(-)

diff --git a/lib/modules/platform/bitbucket-server/utils.ts b/lib/modules/platform/bitbucket-server/utils.ts
index 5320b7ce14..a39d29be1f 100644
--- a/lib/modules/platform/bitbucket-server/utils.ts
+++ b/lib/modules/platform/bitbucket-server/utils.ts
@@ -7,11 +7,7 @@ import { HostRule, PrState } from '../../../types';
 import type { GitProtocol } from '../../../types/git';
 import * as git from '../../../util/git';
 import { BitbucketServerHttp } from '../../../util/http/bitbucket-server';
-import type {
-  HttpOptions,
-  HttpPostOptions,
-  HttpResponse,
-} from '../../../util/http/types';
+import type { HttpOptions, HttpResponse } from '../../../util/http/types';
 import { parseUrl } from '../../../util/url';
 import { getPrBodyStruct } from '../pr-body';
 import type { GitUrlOption } from '../types';
@@ -54,29 +50,20 @@ const addMaxLength = (inputUrl: string, limit = 100): string => {
 function callApi<T>(
   apiUrl: string,
   method: string,
-  options?: HttpOptions | HttpPostOptions
+  options?: HttpOptions
 ): Promise<HttpResponse<T>> {
   /* istanbul ignore next */
   switch (method.toLowerCase()) {
     case 'post':
-      return bitbucketServerHttp.postJson<T>(
-        apiUrl,
-        options as HttpPostOptions
-      );
+      return bitbucketServerHttp.postJson<T>(apiUrl, options);
     case 'put':
-      return bitbucketServerHttp.putJson<T>(apiUrl, options as HttpPostOptions);
+      return bitbucketServerHttp.putJson<T>(apiUrl, options);
     case 'patch':
-      return bitbucketServerHttp.patchJson<T>(
-        apiUrl,
-        options as HttpPostOptions
-      );
+      return bitbucketServerHttp.patchJson<T>(apiUrl, options);
     case 'head':
       return bitbucketServerHttp.headJson<T>(apiUrl, options);
     case 'delete':
-      return bitbucketServerHttp.deleteJson<T>(
-        apiUrl,
-        options as HttpPostOptions
-      );
+      return bitbucketServerHttp.deleteJson<T>(apiUrl, options);
     case 'get':
     default:
       return bitbucketServerHttp.getJson<T>(apiUrl, options);
@@ -86,7 +73,7 @@ function callApi<T>(
 export async function accumulateValues<T = any>(
   reqUrl: string,
   method = 'get',
-  options?: HttpOptions | HttpPostOptions,
+  options?: HttpOptions,
   limit?: number
 ): Promise<T[]> {
   let accumulator: T[] = [];
diff --git a/lib/modules/platform/bitbucket/utils.ts b/lib/modules/platform/bitbucket/utils.ts
index 6eb16508ee..2685b14e46 100644
--- a/lib/modules/platform/bitbucket/utils.ts
+++ b/lib/modules/platform/bitbucket/utils.ts
@@ -2,11 +2,7 @@ import url from 'url';
 import type { MergeStrategy } from '../../../config/types';
 import { BranchStatus, PrState } from '../../../types';
 import { BitbucketHttp } from '../../../util/http/bitbucket';
-import type {
-  HttpOptions,
-  HttpPostOptions,
-  HttpResponse,
-} from '../../../util/http/types';
+import type { HttpOptions, HttpResponse } from '../../../util/http/types';
 import { getPrBodyStruct } from '../pr-body';
 import type { Pr } from '../types';
 import type { BitbucketMergeStrategy, MergeRequestBody } from './types';
@@ -114,20 +110,20 @@ const addMaxLength = (inputUrl: string, pagelen = 100): string => {
 function callApi<T>(
   apiUrl: string,
   method: string,
-  options?: HttpOptions | HttpPostOptions
+  options?: HttpOptions
 ): Promise<HttpResponse<T>> {
   /* istanbul ignore next */
   switch (method.toLowerCase()) {
     case 'post':
-      return bitbucketHttp.postJson<T>(apiUrl, options as HttpPostOptions);
+      return bitbucketHttp.postJson<T>(apiUrl, options);
     case 'put':
-      return bitbucketHttp.putJson<T>(apiUrl, options as HttpPostOptions);
+      return bitbucketHttp.putJson<T>(apiUrl, options);
     case 'patch':
-      return bitbucketHttp.patchJson<T>(apiUrl, options as HttpPostOptions);
+      return bitbucketHttp.patchJson<T>(apiUrl, options);
     case 'head':
       return bitbucketHttp.headJson<T>(apiUrl, options);
     case 'delete':
-      return bitbucketHttp.deleteJson<T>(apiUrl, options as HttpPostOptions);
+      return bitbucketHttp.deleteJson<T>(apiUrl, options);
     case 'get':
     default:
       return bitbucketHttp.getJson<T>(apiUrl, options);
@@ -137,7 +133,7 @@ function callApi<T>(
 export async function accumulateValues<T = any>(
   reqUrl: string,
   method = 'get',
-  options?: HttpOptions | HttpPostOptions,
+  options?: HttpOptions,
   pagelen?: number
 ): Promise<T[]> {
   let accumulator: T[] = [];
diff --git a/lib/util/http/gitea.ts b/lib/util/http/gitea.ts
index a3305b6cc7..9dd49c2112 100644
--- a/lib/util/http/gitea.ts
+++ b/lib/util/http/gitea.ts
@@ -30,7 +30,7 @@ function resolveUrl(path: string, base: string): URL {
   return new URL(resolvedUrlString);
 }
 
-export class GiteaHttp extends Http<GiteaHttpOptions, GiteaHttpOptions> {
+export class GiteaHttp extends Http<GiteaHttpOptions> {
   constructor(options?: HttpOptions) {
     super(PlatformId.Gitea, options);
   }
diff --git a/lib/util/http/github.ts b/lib/util/http/github.ts
index 2f5eca7ebe..2f7d1a01b3 100644
--- a/lib/util/http/github.ts
+++ b/lib/util/http/github.ts
@@ -20,7 +20,6 @@ import type { GotLegacyError } from './legacy';
 import type {
   GraphqlOptions,
   HttpOptions,
-  HttpPostOptions,
   HttpResponse,
   InternalHttpOptions,
 } from './types';
@@ -265,7 +264,7 @@ function setGraphqlPageSize(fieldName: string, newPageSize: number): void {
   }
 }
 
-export class GithubHttp extends Http<GithubHttpOptions, GithubHttpOptions> {
+export class GithubHttp extends Http<GithubHttpOptions> {
   constructor(
     hostType: string = PlatformId.Github,
     options?: GithubHttpOptions
@@ -380,7 +379,7 @@ export class GithubHttp extends Http<GithubHttpOptions, GithubHttpOptions> {
     }
     const body = variables ? { query, variables } : { query };
 
-    const opts: HttpPostOptions = {
+    const opts: GithubHttpOptions = {
       baseUrl: baseUrl.replace('/v3/', '/'), // GHE uses unversioned graphql path
       body,
       headers: { accept: options?.acceptHeader },
diff --git a/lib/util/http/gitlab.ts b/lib/util/http/gitlab.ts
index cd43052b37..b345797bf8 100644
--- a/lib/util/http/gitlab.ts
+++ b/lib/util/http/gitlab.ts
@@ -15,7 +15,7 @@ export interface GitlabHttpOptions extends HttpOptions {
   paginate?: boolean;
 }
 
-export class GitlabHttp extends Http<GitlabHttpOptions, GitlabHttpOptions> {
+export class GitlabHttp extends Http<GitlabHttpOptions> {
   constructor(type: string = PlatformId.Gitlab, options?: GitlabHttpOptions) {
     super(type, options);
   }
diff --git a/lib/util/http/index.ts b/lib/util/http/index.ts
index 21bb432567..7aef53c600 100644
--- a/lib/util/http/index.ts
+++ b/lib/util/http/index.ts
@@ -16,7 +16,6 @@ import type {
   GotJSONOptions,
   GotOptions,
   HttpOptions,
-  HttpPostOptions,
   HttpResponse,
   InternalHttpOptions,
   RequestStats,
@@ -92,7 +91,7 @@ async function gotRoutine<T>(
   }
 }
 
-export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
+export class Http<Opts extends HttpOptions = HttpOptions> {
   private options?: GotOptions;
 
   constructor(protected hostType: string, options: HttpOptions = {}) {
@@ -210,59 +209,50 @@ export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
 
   private async requestJson<T = unknown>(
     url: string,
-    options: InternalHttpOptions
+    requestOptions?: Opts,
+    internalOptions?: InternalHttpOptions
   ): Promise<HttpResponse<T>> {
-    const { body, ...jsonOptions } = options;
+    const { body, ...httpOptions } = { ...requestOptions };
+    const opts: InternalHttpOptions = {
+      ...httpOptions,
+      ...internalOptions,
+      responseType: 'json',
+    };
     if (body) {
-      jsonOptions.json = body;
+      opts.json = body;
     }
-    const res = await this.request<T>(url, {
-      ...jsonOptions,
-      responseType: 'json',
-    });
+    const res = await this.request<T>(url, opts);
     return { ...res, body: res.body };
   }
 
-  getJson<T = unknown>(
-    url: string,
-    options?: GetOptions
-  ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options });
+  getJson<T = unknown>(url: string, options?: Opts): Promise<HttpResponse<T>> {
+    return this.requestJson<T>(url, options);
   }
 
-  headJson<T = unknown>(
-    url: string,
-    options?: GetOptions
-  ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options, method: 'head' });
+  headJson<T = unknown>(url: string, options?: Opts): Promise<HttpResponse<T>> {
+    return this.requestJson<T>(url, options, { method: 'head' });
   }
 
-  postJson<T = unknown>(
-    url: string,
-    options?: PostOptions
-  ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options, method: 'post' });
+  postJson<T = unknown>(url: string, options?: Opts): Promise<HttpResponse<T>> {
+    return this.requestJson<T>(url, options, { method: 'post' });
   }
 
-  putJson<T = unknown>(
-    url: string,
-    options?: PostOptions
-  ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options, method: 'put' });
+  putJson<T = unknown>(url: string, options?: Opts): Promise<HttpResponse<T>> {
+    return this.requestJson<T>(url, options, { method: 'put' });
   }
 
   patchJson<T = unknown>(
     url: string,
-    options?: PostOptions
+    options?: Opts
   ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options, method: 'patch' });
+    return this.requestJson<T>(url, options, { method: 'patch' });
   }
 
   deleteJson<T = unknown>(
     url: string,
-    options?: PostOptions
+    options?: Opts
   ): Promise<HttpResponse<T>> {
-    return this.requestJson<T>(url, { ...options, method: 'delete' });
+    return this.requestJson<T>(url, options, { method: 'delete' });
   }
 
   stream(url: string, options?: HttpOptions): NodeJS.ReadableStream {
diff --git a/lib/util/http/types.ts b/lib/util/http/types.ts
index 5fe79a1c2f..32f873f6bc 100644
--- a/lib/util/http/types.ts
+++ b/lib/util/http/types.ts
@@ -65,12 +65,8 @@ export interface HttpOptions {
   useCache?: boolean;
 }
 
-export interface HttpPostOptions extends HttpOptions {
-  body: unknown;
-}
-
 export interface InternalHttpOptions extends HttpOptions {
-  json?: Record<string, unknown>;
+  json?: HttpOptions['body'];
   responseType?: 'json' | 'buffer';
   method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head';
 }
-- 
GitLab