diff --git a/lib/platform/github/__snapshots__/index.spec.ts.snap b/lib/platform/github/__snapshots__/index.spec.ts.snap
index 339ec34173c28d9cef056aa656183e78b5b50819..d6715d11e3db39e6d5e52fad9a5ed79ea7cb7dde 100644
--- a/lib/platform/github/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/github/__snapshots__/index.spec.ts.snap
@@ -7156,6 +7156,14 @@ Array [
 ]
 `;
 
+exports[`platform/github/index initPlatform() should support custom endpoint without version 1`] = `
+Object {
+  "endpoint": "https://ghe.renovatebot.com/",
+  "gitAuthor": "undefined <user@domain.com>",
+  "renovateUsername": "renovate-bot",
+}
+`;
+
 exports[`platform/github/index initPlatform() should support default endpoint no email access 1`] = `
 Object {
   "endpoint": "https://api.github.com/",
diff --git a/lib/platform/github/index.spec.ts b/lib/platform/github/index.spec.ts
index 97fd3541e27143d73522d377b1c8d148c0289811..ebb9ef0581ee148bdc778911e9e86348be86d2be 100644
--- a/lib/platform/github/index.spec.ts
+++ b/lib/platform/github/index.spec.ts
@@ -132,6 +132,30 @@ describe('platform/github/index', () => {
       ).toMatchSnapshot();
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
+
+    it('should support custom endpoint without version', async () => {
+      httpMock
+        .scope('https://ghe.renovatebot.com')
+        .head('/')
+        .reply(200)
+
+        .get('/user')
+        .reply(200, {
+          login: 'renovate-bot',
+        })
+        .get('/user/emails')
+        .reply(200, [
+          {
+            email: 'user@domain.com',
+          },
+        ]);
+      expect(
+        await github.initPlatform({
+          endpoint: 'https://ghe.renovatebot.com',
+          token: '123test',
+        })
+      ).toMatchSnapshot();
+    });
   });
 
   describe('getRepos', () => {
diff --git a/lib/util/cache/package/decorator.spec.ts b/lib/util/cache/package/decorator.spec.ts
index 8aa008b09cd3e193573c18135b2ad03e6552b35c..69b024c5f47affbaef0f08c731a0273445e4c031 100644
--- a/lib/util/cache/package/decorator.spec.ts
+++ b/lib/util/cache/package/decorator.spec.ts
@@ -33,6 +33,25 @@ describe('util/cache/package/decorator', () => {
     expect(spy).toHaveBeenCalledTimes(1);
   });
 
+  it('Do not cache', async () => {
+    class MyClass {
+      @cache({ namespace: 'namespace', key: 'key', cacheable: () => false })
+      public async getString(
+        cacheKey: string,
+        test: string | null
+      ): Promise<string | null> {
+        await spy();
+        return test;
+      }
+    }
+    const myClass = new MyClass();
+    expect(await myClass.getString('null', null)).toBeNull();
+    expect(await myClass.getString('null', null)).toBeNull();
+    expect(await myClass.getString('test', 'test')).toBe('test');
+    expect(await myClass.getString('test', 'test')).toBe('test');
+    expect(spy).toHaveBeenCalledTimes(4);
+  });
+
   it('Do cache null', async () => {
     class MyClass {
       @cache({ namespace: 'namespace', key: (cacheKey, test) => cacheKey })
@@ -88,4 +107,17 @@ describe('util/cache/package/decorator', () => {
     expect(await myClass.getNumber(getReleasesConfig)).toBeDefined();
     expect(spy).toHaveBeenCalledTimes(1);
   });
+
+  it('works', async () => {
+    class MyClass {
+      public async getNumber(): Promise<number> {
+        await spy();
+        return Math.random();
+      }
+    }
+    const decorator = cache({ namespace: 'namespace', key: 'key' });
+    const getNumber = decorator(MyClass.prototype, 'getNumber', undefined);
+
+    expect(await getNumber.value()).toBeNumber();
+  });
 });
diff --git a/lib/util/cache/package/decorator.ts b/lib/util/cache/package/decorator.ts
index a0d8e0d0ef6f7d68622f7f690d3dc5869a316ffc..7094e725a5d62e95885b9a92015fae7079a58d0c 100644
--- a/lib/util/cache/package/decorator.ts
+++ b/lib/util/cache/package/decorator.ts
@@ -34,6 +34,7 @@ function decorate<T>(fn: Handler<T>): Decorator<T> {
   const result: Decorator<T> = (
     target,
     key,
+    /* TODO: Can descriptor be undefined ? */
     descriptor = Object.getOwnPropertyDescriptor(target, key) ?? {
       enumerable: true,
       configurable: true,
diff --git a/package.json b/package.json
index 0866d7f354d220fd9f44a34c631243fce1152d85..90074825c2395d0c080485a0463b801663eb907d 100644
--- a/package.json
+++ b/package.json
@@ -118,12 +118,12 @@
   },
   "homepage": "https://renovatebot.com",
   "engines": {
-    "node": "^12.22.0 || >=14.15.0",
+    "node": "^14.15.0 || >=16.13.0",
     "yarn": "^1.17.0"
   },
   "engines-next": {
     "description": "Versions other than the below are deprecated and a warning will be logged",
-    "node": ">=14.15.0"
+    "node": "^14.15.0 || >=16.13.0"
   },
   "dependencies": {
     "@aws-sdk/client-ec2": "3.35.0",
diff --git a/tsconfig.json b/tsconfig.json
index 042da7b89c1dccb173f701053f9d0155aeb8a2b4..81382ed8bd1f05fb7f1f5fbeb036ba32de382394 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,7 +4,8 @@
     "noImplicitAny": false /* required for js files */,
     "strictNullChecks": false /* required for js files */,
     "outDir": "./dist",
-    "target": "es2018",
+    /* https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping */
+    "target": "es2020",
     "module": "commonjs",
     "sourceMap": true,
     "allowSyntheticDefaultImports": true,
@@ -14,7 +15,7 @@
     "noImplicitOverride": true,
     "experimentalDecorators": true,
     "useUnknownInCatchVariables": false /* we aren't prepared for enabling this by default since ts 4.4*/,
-    "lib": ["es2018"],
+    "lib": ["es2020"],
     "types": ["node", "jest", "jest-extended", "expect-more-jest"],
     "allowJs": true,
     "checkJs": true
diff --git a/tsconfig.strict.json b/tsconfig.strict.json
index d2bb5af542a5e3c6463e61c4944299d116b8a7a4..004501067f1fc566a3f0054fd30016b99d2b393b 100644
--- a/tsconfig.strict.json
+++ b/tsconfig.strict.json
@@ -3,7 +3,7 @@
   "compilerOptions": {
     "strictNullChecks": true,
     "noImplicitAny": true,
-    "lib": ["es2019"]
+    "lib": ["es2020"]
   },
   "include": [
     "lib/config/app-strings.ts",