From 44c05a8e7844a9d5a59a4588474db3c303fb526b Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 3 Jun 2021 02:06:24 +0000 Subject: [PATCH 1/4] Update dependency prettier to v2.3.0 --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e415974de..6fcb62c0f 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "husky": "4.3.8", "jest": "26.6.3", "lint-staged": "11.0.0", - "prettier": "2.2.1", + "prettier": "2.3.0", "supertest": "6.1.3", "ts-jest": "26.5.6", "ts-node-dev": "1.1.6", diff --git a/yarn.lock b/yarn.lock index 29a630fd9..f029aba5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1743,7 +1743,7 @@ __metadata: lint-staged: 11.0.0 pino: 6.11.3 pino-pretty: 4.8.0 - prettier: 2.2.1 + prettier: 2.3.0 sqlite3: 5.0.2 supertest: 6.1.3 ts-jest: 26.5.6 @@ -7571,12 +7571,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:2.2.1": - version: 2.2.1 - resolution: "prettier@npm:2.2.1" +"prettier@npm:2.3.0": + version: 2.3.0 + resolution: "prettier@npm:2.3.0" bin: prettier: bin-prettier.js - checksum: 800de2df3d37067ab24478c7f32c60ca0c57b01742133287829feeb4a70d239a7bf6bccb56196784777af591ad80fb9ba70c1a49b0fcecf9f5622a764d513edb + checksum: e8851a45f60f2994775f96e07964646c299b8a8f9c64da4fbd8efafc20db3458bdcedac79aed34e1d5477540b3aa04f6499adc4979cb7937f8ebd058a767d8ff languageName: node linkType: hard From f8f1a34c28eff5fdfeef0199588ed31b23e30f1e Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 3 Jun 2021 18:57:56 +0200 Subject: [PATCH 2/4] format files --- src/routes/handlers/common.ts | 2 +- src/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/handlers/common.ts b/src/routes/handlers/common.ts index 008405fde..b1b881b7b 100644 --- a/src/routes/handlers/common.ts +++ b/src/routes/handlers/common.ts @@ -9,7 +9,7 @@ export enum Source { Kitsu = 'kitsu', } -export const sourceArray = (enumToArray(Source) as unknown) as string[] +export const sourceArray = enumToArray(Source) as unknown as string[] export const idSchema = Joi.number() .min(0) diff --git a/src/utils.ts b/src/utils.ts index b9ecc7ae4..0004f44fd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,7 +3,7 @@ export const enumToArray = (e: E): E[] => Object.values(e) export const isEmpty = < - T extends Record | Record[] + T extends Record | Record[], >( obj: T, ) => { From 1b83b2da525a7563e3a7f0e21af6db87590f55d3 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 3 Jun 2021 19:00:41 +0200 Subject: [PATCH 3/4] change formatting --- .eslintrc.js | 10 ++-- .github/renovate.json5 | 26 ++++----- .prettierrc | 2 +- bin/update.ts | 2 +- jest.config.js | 16 +++--- knexfile.ts | 10 ++-- migrations/20190611171759_create_tables.ts | 16 +++--- src/app.ts | 26 ++++----- src/config.ts | 22 +++----- src/db.ts | 4 +- src/index.ts | 10 ++-- src/lib/logger.ts | 6 +- src/lib/sentry.ts | 31 +++++----- src/manual-rules.ts | 26 ++++----- src/routes/handlers/common.ts | 18 +++--- src/routes/handlers/json-body.ts | 19 +++---- src/routes/handlers/query-params.ts | 8 +-- src/routes/ids.test.ts | 66 +++++++++++----------- src/routes/ids.ts | 43 +++++++------- src/routes/index.ts | 6 +- src/shims.d.ts | 4 +- src/update.ts | 40 ++++++------- src/utils.ts | 4 +- 23 files changed, 193 insertions(+), 222 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e2b53e2e0..ac447169d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,12 +5,12 @@ module.exports = { node: true, }, extends: [ - 'plugin:@beequeue/base', - 'plugin:@beequeue/node', - 'plugin:@beequeue/typescript', - 'plugin:@beequeue/prettier', + "plugin:@beequeue/base", + "plugin:@beequeue/node", + "plugin:@beequeue/typescript", + "plugin:@beequeue/prettier", ], rules: { - 'import/no-named-as-default': 'off', + "import/no-named-as-default": "off", }, } diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5ecfbafbe..e4df92bca 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,30 +1,30 @@ { - extends: ['config:js-app', 'helpers:disableTypesNodeMajor'], + extends: ["config:js-app", "helpers:disableTypesNodeMajor"], prConcurrentLimit: 5, branchConcurrentLimit: 5, - schedule: ['before 11am'], - labels: ['dependencies'], - baseBranches: ['master'], + schedule: ["before 11am"], + labels: ["dependencies"], + baseBranches: ["master"], automerge: false, packageRules: [ { - packageNames: ['node'], - allowedVersions: '<13', - rangeStrategy: 'replace', + packageNames: ["node"], + allowedVersions: "<13", + rangeStrategy: "replace", }, { - groupName: 'linters', - matchPackageNames: ['eslint'], + groupName: "linters", + matchPackageNames: ["eslint"], automerge: true, }, { - groupName: 'testing packages', - matchPackageNames: ['jest', 'test'], + groupName: "testing packages", + matchPackageNames: ["jest", "test"], automerge: true, }, { - groupName: '`@types` package patches', - matchPackagePrefixes: ['@types/'], + groupName: "`@types` package patches", + matchPackagePrefixes: ["@types/"], patch: true, automerge: true, }, diff --git a/.prettierrc b/.prettierrc index e3b414c7e..3ee6ca58f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { + "printWidth": 90, "semi": false, - "singleQuote": true, "trailingComma": "all" } diff --git a/bin/update.ts b/bin/update.ts index 829632a3f..3334ec32b 100644 --- a/bin/update.ts +++ b/bin/update.ts @@ -1,3 +1,3 @@ -import { updateRelations } from '../src/update' +import { updateRelations } from "../src/update" void updateRelations() diff --git a/jest.config.js b/jest.config.js index e9d4c4678..6df073f00 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,16 +1,16 @@ -const { pathsToModuleNameMapper } = require('ts-jest/utils') -const { compilerOptions } = require('./tsconfig') +const { pathsToModuleNameMapper } = require("ts-jest/utils") +const { compilerOptions } = require("./tsconfig") module.exports = { - roots: ['/src'], - preset: 'ts-jest', - moduleFileExtensions: ['js', 'ts'], + roots: ["/src"], + preset: "ts-jest", + moduleFileExtensions: ["js", "ts"], moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { - prefix: '/', + prefix: "/", }), - coveragePathIgnorePatterns: ['sentry.ts', 'utils.ts'], + coveragePathIgnorePatterns: ["sentry.ts", "utils.ts"], collectCoverage: true, - coverageReporters: ['text', 'text-summary'], + coverageReporters: ["text", "text-summary"], coverageThreshold: { global: { statements: 90, diff --git a/knexfile.ts b/knexfile.ts index 0b0f36c8d..fc4f65b8a 100644 --- a/knexfile.ts +++ b/knexfile.ts @@ -1,12 +1,12 @@ -export const config: import('knex').Knex.Config = { - client: 'sqlite3', +export const config: import("knex").Knex.Config = { + client: "sqlite3", migrations: { - tableName: 'migrations', - directory: 'migrations', + tableName: "migrations", + directory: "migrations", }, useNullAsDefault: true, connection: { - filename: `./sqlite/${process.env.NODE_ENV ?? 'development'}.sqlite3`, + filename: `./sqlite/${process.env.NODE_ENV ?? "development"}.sqlite3`, }, } diff --git a/migrations/20190611171759_create_tables.ts b/migrations/20190611171759_create_tables.ts index 538e7d22a..d0bb94473 100644 --- a/migrations/20190611171759_create_tables.ts +++ b/migrations/20190611171759_create_tables.ts @@ -1,16 +1,16 @@ -import { Knex } from 'knex' +import { Knex } from "knex" export async function up(knex: Knex): Promise { - if (await knex.schema.hasTable('relations')) return + if (await knex.schema.hasTable("relations")) return const promises: Promise[] = [] promises.push( - knex.schema.createTable('relations', (table) => { - table.integer('anilist').unique() - table.integer('anidb').unique() - table.integer('myanimelist').unique() - table.integer('kitsu').unique() + knex.schema.createTable("relations", (table) => { + table.integer("anilist").unique() + table.integer("anidb").unique() + table.integer("myanimelist").unique() + table.integer("kitsu").unique() }), ) @@ -18,5 +18,5 @@ export async function up(knex: Knex): Promise { } export async function down(knex: Knex): Promise { - await knex.schema.dropTableIfExists('relations') + await knex.schema.dropTableIfExists("relations") } diff --git a/src/app.ts b/src/app.ts index 03c148403..db17f95bb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,31 +1,27 @@ -import Koa, { Context } from 'koa' -import BodyParser from 'koa-bodyparser' -import RequestLogger from 'koa-pino-logger' -import Router from 'koa-router' +import Koa, { Context } from "koa" +import BodyParser from "koa-bodyparser" +import RequestLogger from "koa-pino-logger" +import Router from "koa-router" -import { config } from '@/config' -import { Logger } from '@/lib/logger' -import { - requestHandler, - sendErrorToSentry, - tracingMiddleWare, -} from '@/lib/sentry' +import { config } from "@/config" +import { Logger } from "@/lib/logger" +import { requestHandler, sendErrorToSentry, tracingMiddleWare } from "@/lib/sentry" -import { routes } from './routes' +import { routes } from "./routes" export const App = new Koa() const router = new Router() App.use( RequestLogger({ - prettyPrint: config.NODE_ENV === 'development', + prettyPrint: config.NODE_ENV === "development", }), ) App.use(requestHandler) App.use(tracingMiddleWare) -App.on('error', (err, ctx) => { +App.on("error", (err, ctx) => { Logger.error(err) sendErrorToSentry(err, ctx) @@ -33,7 +29,7 @@ App.on('error', (err, ctx) => { App.use(BodyParser()) -router.get('/', (ctx: Context) => { +router.get("/", (ctx: Context) => { ctx.body = `
 Get IDs:
diff --git a/src/config.ts b/src/config.ts
index fb670f1ca..9e7716abd 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,30 +1,26 @@
 /* eslint-disable @typescript-eslint/naming-convention */
-import { envsafe, port, str } from 'envsafe'
+import { envsafe, port, str } from "envsafe"
 
 export enum Environment {
-  Development = 'development',
-  Test = 'test',
-  Production = 'production',
+  Development = "development",
+  Test = "test",
+  Production = "production",
 }
 
 export const config = envsafe({
   NODE_ENV: str({
-    choices: [
-      Environment.Development,
-      Environment.Test,
-      Environment.Production,
-    ],
+    choices: [Environment.Development, Environment.Test, Environment.Production],
     default: Environment.Development,
   }),
   PORT: port({
     devDefault: 3000,
   }),
   LOG_LEVEL: str({
-    default: 'info',
-    devDefault: 'debug',
-    choices: ['fatal', 'error', 'warn', 'info', 'debug', 'trace'],
+    default: "info",
+    devDefault: "debug",
+    choices: ["fatal", "error", "warn", "info", "debug", "trace"],
   }),
   USER_AGENT: str({
-    default: 'arm-server',
+    default: "arm-server",
   }),
 })
diff --git a/src/db.ts b/src/db.ts
index 2e3d20aaf..bc102efbf 100644
--- a/src/db.ts
+++ b/src/db.ts
@@ -1,6 +1,6 @@
-import Knex from 'knex'
+import Knex from "knex"
 
-import { config } from '../knexfile'
+import { config } from "../knexfile"
 
 export const knex = Knex(config)
 
diff --git a/src/index.ts b/src/index.ts
index 4b1c60ab6..ba3853e5f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,9 +1,9 @@
-import { captureException } from '@sentry/node'
+import { captureException } from "@sentry/node"
 
-import { Logger } from '@/lib/logger'
+import { Logger } from "@/lib/logger"
 
-import { App } from './app'
-import { updateRelations } from './update'
+import { App } from "./app"
+import { updateRelations } from "./update"
 
 const { NODE_ENV, PORT } = process.env
 const port = PORT ?? 3000
@@ -11,7 +11,7 @@ const port = PORT ?? 3000
 const runUpdateScript = () => updateRelations().catch(captureException)
 
 const listen = () => {
-  if (NODE_ENV === 'production') {
+  if (NODE_ENV === "production") {
     void runUpdateScript()
 
     // eslint-disable-next-line @typescript-eslint/no-misused-promises
diff --git a/src/lib/logger.ts b/src/lib/logger.ts
index a80158d84..735d0750e 100644
--- a/src/lib/logger.ts
+++ b/src/lib/logger.ts
@@ -1,8 +1,8 @@
-import Pino from 'pino'
+import Pino from "pino"
 
-import { config } from '../config'
+import { config } from "../config"
 
 export const Logger = Pino({
   level: config.LOG_LEVEL,
-  prettyPrint: config.NODE_ENV !== 'production',
+  prettyPrint: config.NODE_ENV !== "production",
 })
diff --git a/src/lib/sentry.ts b/src/lib/sentry.ts
index 139136c7f..f46932e5c 100644
--- a/src/lib/sentry.ts
+++ b/src/lib/sentry.ts
@@ -1,19 +1,16 @@
 // eslint-disable-next-line node/no-deprecated-api
-import domain from 'domain'
+import domain from "domain"
 
-import { Context, Next } from 'koa'
+import { Context, Next } from "koa"
 
-import * as Sentry from '@sentry/node'
-import {
-  extractTraceparentData,
-  stripUrlQueryAndFragment,
-} from '@sentry/tracing'
+import * as Sentry from "@sentry/node"
+import { extractTraceparentData, stripUrlQueryAndFragment } from "@sentry/tracing"
 
 const { NODE_ENV, TRACES_SAMPLERATE, SENTRY_DSN } = process.env
 
 Sentry.init({
   dsn: SENTRY_DSN,
-  enabled: NODE_ENV === 'production',
+  enabled: NODE_ENV === "production",
   tracesSampleRate: Number(TRACES_SAMPLERATE ?? 1),
 })
 
@@ -23,10 +20,10 @@ export const requestHandler = (ctx: Context, next: Next) =>
 
     local.add(ctx as any) // TODO
 
-    local.on('error', (err) => {
+    local.on("error", (err) => {
       ctx.status = err.status || 500
       ctx.body = err.message
-      ctx.app.emit('error', err, ctx)
+      ctx.app.emit("error", err, ctx)
     })
 
     void local.run(async () => {
@@ -45,19 +42,19 @@ export const requestHandler = (ctx: Context, next: Next) =>
   })
 
 export const tracingMiddleWare = async (ctx: Context, next: Next) => {
-  const reqMethod = (ctx.method || '').toUpperCase()
+  const reqMethod = (ctx.method || "").toUpperCase()
   const reqUrl = ctx.url && stripUrlQueryAndFragment(ctx.url)
 
   // connect to trace of upstream app
   let traceparentData = null
 
-  if (ctx.request.get('sentry-trace')) {
-    traceparentData = extractTraceparentData(ctx.request.get('sentry-trace'))
+  if (ctx.request.get("sentry-trace")) {
+    traceparentData = extractTraceparentData(ctx.request.get("sentry-trace"))
   }
 
   const transaction = Sentry.startTransaction({
     name: `${reqMethod} ${reqUrl}`,
-    op: 'http.server',
+    op: "http.server",
     ...traceparentData,
   })
 
@@ -67,10 +64,8 @@ export const tracingMiddleWare = async (ctx: Context, next: Next) => {
 
   // if using koa router, a nicer way to capture transaction using the matched route
   if (ctx._matchedRoute) {
-    const mountPath = (ctx.mountPath as string) || ''
-    transaction.setName(
-      `${reqMethod} ${mountPath}${ctx._matchedRoute as string}`,
-    )
+    const mountPath = (ctx.mountPath as string) || ""
+    transaction.setName(`${reqMethod} ${mountPath}${ctx._matchedRoute as string}`)
   }
 
   transaction.setHttpStatus(ctx.status)
diff --git a/src/manual-rules.ts b/src/manual-rules.ts
index 77a13ad77..e6d3c82d7 100644
--- a/src/manual-rules.ts
+++ b/src/manual-rules.ts
@@ -1,29 +1,27 @@
-import { knex, Relation } from './db'
-import { Logger } from './lib/logger'
+import { knex, Relation } from "./db"
+import { Logger } from "./lib/logger"
 
 const rules = {
   // Kaguya-sama
-  'anidb:14111': 'anilist:101921',
+  "anidb:14111": "anilist:101921",
   // Shield Hero
-  'anidb:13246': 'anilist:99263',
+  "anidb:13246": "anilist:99263",
   // Vivy #385
-  'anidb:15988': 'myanimelist:46095',
+  "anidb:15988": "myanimelist:46095",
   // Osananajimi #386
-  'anidb:15756': 'myanimelist:43007',
+  "anidb:15756": "myanimelist:43007",
   // Iruma-kun S2 #387
-  'anidb:15428': 'myanimelist:41402',
+  "anidb:15428": "myanimelist:41402",
 }
 
 export const updateBasedOnManualRules = async () => {
   const promises = Object.entries(rules).map(async ([from, to]) => {
-    const [fromSource, fromId] = from.split(':')
+    const [fromSource, fromId] = from.split(":")
     const fromWhere = { [fromSource]: Number(fromId) }
-    const [toSource, toId] = to.split(':')
+    const [toSource, toId] = to.split(":")
     const toWhere = { [toSource]: Number(toId) }
 
-    const badRelation: Relation | null = await knex('relations')
-      .where(fromWhere)
-      .first()
+    const badRelation: Relation | null = await knex("relations").where(fromWhere).first()
 
     if (!badRelation) {
       throw new Error(`Could not find rule source for ${from}->${to}!!!!!`)
@@ -31,12 +29,12 @@ export const updateBasedOnManualRules = async () => {
 
     await knex
       .transaction((trx) =>
-        knex('relations')
+        knex("relations")
           .delete()
           .where(fromWhere)
           .transacting(trx)
           .then(() =>
-            knex('relations').update(fromWhere).where(toWhere).transacting(trx),
+            knex("relations").update(fromWhere).where(toWhere).transacting(trx),
           ),
       )
       .catch(Logger.error)
diff --git a/src/routes/handlers/common.ts b/src/routes/handlers/common.ts
index b1b881b7b..173cdff6a 100644
--- a/src/routes/handlers/common.ts
+++ b/src/routes/handlers/common.ts
@@ -1,18 +1,14 @@
-import Joi from 'joi'
+import Joi from "joi"
 
-import { enumToArray } from '@/utils'
+import { enumToArray } from "@/utils"
 
 export enum Source {
-  AniList = 'anilist',
-  AniDB = 'anidb',
-  MAL = 'myanimelist',
-  Kitsu = 'kitsu',
+  AniList = "anilist",
+  AniDB = "anidb",
+  MAL = "myanimelist",
+  Kitsu = "kitsu",
 }
 
 export const sourceArray = enumToArray(Source) as unknown as string[]
 
-export const idSchema = Joi.number()
-  .min(0)
-  .max(2_147_483_647)
-  .precision(0)
-  .required()
+export const idSchema = Joi.number().min(0).max(2_147_483_647).precision(0).required()
diff --git a/src/routes/handlers/json-body.ts b/src/routes/handlers/json-body.ts
index f5f694432..851d104b6 100644
--- a/src/routes/handlers/json-body.ts
+++ b/src/routes/handlers/json-body.ts
@@ -1,7 +1,7 @@
-import Joi from 'joi'
+import Joi from "joi"
 
-import { knex, Relation } from '@/db'
-import { idSchema, Source, sourceArray } from '@/routes/handlers/common'
+import { knex, Relation } from "@/db"
+import { idSchema, Source, sourceArray } from "@/routes/handlers/common"
 
 type BodyItem = {
   [key in Source]?: number
@@ -27,11 +27,9 @@ export const bodySchema = Joi.alternatives(arraySchema, bodyItemSchema)
 
 export const bodyHandler = async (
   input: BodyQuery,
-): Promise<
-  BodyQuery extends Array ? Array : Relation
-> => {
+): Promise ? Array : Relation> => {
   if (!Array.isArray(input)) {
-    const relation = await knex.where(input).from('relations').first()
+    const relation = await knex.where(input).from("relations").first()
 
     return relation ?? null
   }
@@ -44,16 +42,13 @@ export const bodyHandler = async (
       // eslint-disable-next-line @typescript-eslint/no-floating-promises
       for (const item of input) this.orWhere(item)
     })
-    .from('relations')
+    .from("relations")
 
   // Map them against the input, so we get results like [{item}, null, {item}]
   relations = input.map((item) => {
     const realItem = Object.entries(item)[0] as [Source, number]
 
-    return (
-      relations.find((relation) => relation![realItem[0]] === realItem[1]) ??
-      null
-    )
+    return relations.find((relation) => relation![realItem[0]] === realItem[1]) ?? null
   })
 
   return relations as any
diff --git a/src/routes/handlers/query-params.ts b/src/routes/handlers/query-params.ts
index 971a9b280..999ddabdd 100644
--- a/src/routes/handlers/query-params.ts
+++ b/src/routes/handlers/query-params.ts
@@ -1,7 +1,7 @@
-import Joi from 'joi'
+import Joi from "joi"
 
-import { knex } from '@/db'
-import { idSchema, Source, sourceArray } from '@/routes/handlers/common'
+import { knex } from "@/db"
+import { idSchema, Source, sourceArray } from "@/routes/handlers/common"
 
 export type QueryParamQuery = {
   source: Source
@@ -18,6 +18,6 @@ export const querySchema = Joi.object({
 export const handleQueryParams = async (input: QueryParamQuery) => {
   return knex
     .where({ [input.source]: input.id })
-    .from('relations')
+    .from("relations")
     .first()
 }
diff --git a/src/routes/ids.test.ts b/src/routes/ids.test.ts
index 950a518a0..a63318284 100644
--- a/src/routes/ids.test.ts
+++ b/src/routes/ids.test.ts
@@ -1,8 +1,8 @@
-import request from 'supertest'
+import request from "supertest"
 
-import { App } from '@/app'
-import { knex, Relation } from '@/db'
-import { Source } from '@/routes/handlers/common'
+import { App } from "@/app"
+import { knex, Relation } from "@/db"
+import { Source } from "@/routes/handlers/common"
 
 let id = 0
 const createRelations = async (
@@ -21,7 +21,7 @@ const createRelations = async (
     return r
   })
 
-  await knex.insert(relations).into('relations')
+  await knex.insert(relations).into("relations")
 
   if (amount === 1) {
     return relations[0] as any
@@ -36,25 +36,25 @@ afterAll(() => {
   server.close()
 })
 
-afterEach(() => knex.delete().from('relations'))
+afterEach(() => knex.delete().from("relations"))
 
-describe('query params', () => {
-  test('fetches relation correctly', async () => {
+describe("query params", () => {
+  test("fetches relation correctly", async () => {
     const relation = await createRelations(1)
 
     return request(server)
-      .get('/api/ids')
+      .get("/api/ids")
       .query({
         source: Source.AniList,
         id: relation.anilist,
       })
       .expect(200, relation)
-      .expect('Content-Type', /json/)
+      .expect("Content-Type", /json/)
   })
 
   test("returns null when id doesn't exist", async () =>
     request(server)
-      .get('/api/ids')
+      .get("/api/ids")
       .query({
         source: Source.Kitsu,
         id: 404,
@@ -62,9 +62,9 @@ describe('query params', () => {
       .expect(200, null))
 })
 
-describe('json body', () => {
-  describe('object input', () => {
-    test('fetches a single relation', async () => {
+describe("json body", () => {
+  describe("object input", () => {
+    test("fetches a single relation", async () => {
       const relations = await createRelations(4)
 
       const body = {
@@ -72,41 +72,41 @@ describe('json body', () => {
       }
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send(body)
         .expect(relations[0])
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
 
-    test('errors correctly on an empty object', async () => {
+    test("errors correctly on an empty object", async () => {
       await createRelations(4)
 
       const response = {
         code: 400,
-        error: 'Bad Request',
+        error: "Bad Request",
         validation: '"value" must have at least 1 key',
       }
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send({})
         .expect(400, response)
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
 
-    test('returns null if not found', async () => {
+    test("returns null if not found", async () => {
       await createRelations(4)
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send({ anidb: 100_000 })
         .expect(200, null)
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
   })
 
-  describe('array input', () => {
-    test('fetches relations correctly', async () => {
+  describe("array input", () => {
+    test("fetches relations correctly", async () => {
       const relations = await createRelations(4)
 
       const body = [
@@ -118,32 +118,32 @@ describe('json body', () => {
       const result = [relations[0], null, relations[2]]
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send(body)
         .expect(result)
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
 
-    test('responds correctly on no finds', async () => {
+    test("responds correctly on no finds", async () => {
       const body = [{ [Source.AniList]: 1000 }, { [Source.Kitsu]: 1000 }]
 
       const result = [null, null]
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send(body)
         .expect(result)
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
 
-    test('requires at least one source', async () => {
+    test("requires at least one source", async () => {
       const body = [{}]
 
       return request(server)
-        .post('/api/ids')
+        .post("/api/ids")
         .send(body)
         .expect(400)
-        .expect('Content-Type', /json/)
+        .expect("Content-Type", /json/)
     })
   })
 })
diff --git a/src/routes/ids.ts b/src/routes/ids.ts
index 02a552110..6baa75e33 100644
--- a/src/routes/ids.ts
+++ b/src/routes/ids.ts
@@ -1,13 +1,13 @@
-import { Context } from 'koa'
-import Router from 'koa-router'
+import { Context } from "koa"
+import Router from "koa-router"
 
-import { bodyHandler, BodyQuery, bodySchema } from '@/routes/handlers/json-body'
+import { bodyHandler, BodyQuery, bodySchema } from "@/routes/handlers/json-body"
 import {
   handleQueryParams,
   QueryParamQuery,
   querySchema,
-} from '@/routes/handlers/query-params'
-import { isEmpty } from '@/utils'
+} from "@/routes/handlers/query-params"
+import { isEmpty } from "@/utils"
 
 const router = new Router()
 
@@ -15,13 +15,10 @@ const getIds = async (ctx: Context) => {
   const isBodyQuery = isEmpty(ctx.query)
   const unvalidatedInput = isBodyQuery ? ctx.request.body : ctx.query
 
-  const result = (isBodyQuery ? bodySchema : querySchema).validate(
-    unvalidatedInput,
-    {
-      stripUnknown: true,
-      abortEarly: false,
-    },
-  )
+  const result = (isBodyQuery ? bodySchema : querySchema).validate(unvalidatedInput, {
+    stripUnknown: true,
+    abortEarly: false,
+  })
 
   if (result.error) {
     if (!result.error.isJoi) {
@@ -31,7 +28,7 @@ const getIds = async (ctx: Context) => {
     ctx.status = 400
     ctx.body = {
       code: 400,
-      error: 'Bad Request',
+      error: "Bad Request",
       validation: result.error.message,
     }
 
@@ -41,13 +38,13 @@ const getIds = async (ctx: Context) => {
   const input = result.value as QueryParamQuery | BodyQuery
 
   if (isBodyQuery) {
-    if (ctx.request.method === 'GET' && Math.random() >= 0.33) {
+    if (ctx.request.method === "GET" && Math.random() >= 0.33) {
       ctx.status = 400
       ctx.body = {
         code: 400,
-        error: 'Deprecated request',
+        error: "Deprecated request",
         message:
-          'JSON bodies in GET requests has been deprecated. Please use POST instead.',
+          "JSON bodies in GET requests has been deprecated. Please use POST instead.",
       }
 
       return
@@ -55,13 +52,13 @@ const getIds = async (ctx: Context) => {
 
     ctx.body = await bodyHandler(input as BodyQuery)
   } else {
-    if (ctx.request.method === 'POST' && Math.random() >= 0.33) {
+    if (ctx.request.method === "POST" && Math.random() >= 0.33) {
       ctx.status = 400
       ctx.body = {
         code: 400,
-        error: 'Deprecated request',
+        error: "Deprecated request",
         message:
-          'Query parameters in POST requests has been deprecated. Please use GET instead.',
+          "Query parameters in POST requests has been deprecated. Please use GET instead.",
       }
 
       return
@@ -72,12 +69,12 @@ const getIds = async (ctx: Context) => {
 
   if (ctx.body == null) {
     ctx.response.status = 200
-    ctx.response.type = 'json'
-    ctx.body = 'null'
+    ctx.response.type = "json"
+    ctx.body = "null"
   }
 }
 
-router.get('/ids', getIds)
-router.post('/ids', getIds)
+router.get("/ids", getIds)
+router.post("/ids", getIds)
 
 export const singleRoutes = router.routes()
diff --git a/src/routes/index.ts b/src/routes/index.ts
index 04a43652d..b948bad7b 100644
--- a/src/routes/index.ts
+++ b/src/routes/index.ts
@@ -1,10 +1,10 @@
-import Router from 'koa-router'
+import Router from "koa-router"
 
-import { singleRoutes } from './ids'
+import { singleRoutes } from "./ids"
 
 const router = new Router()
 
-router.prefix('/api')
+router.prefix("/api")
 
 router.use(singleRoutes)
 
diff --git a/src/shims.d.ts b/src/shims.d.ts
index b4a6fa011..1a361e69d 100644
--- a/src/shims.d.ts
+++ b/src/shims.d.ts
@@ -1,5 +1,5 @@
-declare module '*/knexfile' {
-  import { Config } from 'knex'
+declare module "*/knexfile" {
+  import { Config } from "knex"
 
   const config: {
     development: Config
diff --git a/src/update.ts b/src/update.ts
index 662cb2a0c..6783040ec 100644
--- a/src/update.ts
+++ b/src/update.ts
@@ -1,10 +1,10 @@
-import Http from 'got'
+import Http from "got"
 
-import { captureException } from '@sentry/node'
+import { captureException } from "@sentry/node"
 
-import { knex, Relation } from './db'
-import { Logger } from './lib/logger'
-import { updateBasedOnManualRules } from './manual-rules'
+import { knex, Relation } from "./db"
+import { Logger } from "./lib/logger"
+import { updateBasedOnManualRules } from "./manual-rules"
 
 type OfflineDatabaseSchema = {
   sources: string[]
@@ -19,15 +19,15 @@ type OfflineDatabaseSchema = {
 
 const fetchDatabase = async (): Promise => {
   const response = await Http.get<{ data: OfflineDatabaseSchema[] }>(
-    'https://raw.githubusercontent.com/manami-project/anime-offline-database/master/anime-offline-database.json',
+    "https://raw.githubusercontent.com/manami-project/anime-offline-database/master/anime-offline-database.json",
     {
-      responseType: 'json',
+      responseType: "json",
     },
   )
 
   if (response.statusCode !== 200) {
-    Logger.error('Could not fetch updated database!!')
-    captureException(new Error('Could not fetch updated database!!'))
+    Logger.error("Could not fetch updated database!!")
+    captureException(new Error("Could not fetch updated database!!"))
 
     return null
   }
@@ -89,37 +89,37 @@ const formatEntry = (entry: OfflineDatabaseSchema): Relation => {
 export const updateRelations = async () => {
   Logger.info(`Using ${process.env.NODE_ENV!} database configuration...`)
 
-  Logger.info('Fetching updated Database...')
+  Logger.info("Fetching updated Database...")
   const data = await fetchDatabase()
-  Logger.info('Fetched updated Database.')
+  Logger.info("Fetched updated Database.")
 
   if (data == null) {
-    Logger.info('got no data')
+    Logger.info("got no data")
     return
   }
 
-  Logger.info('Formatting data...')
+  Logger.info("Formatting data...")
   const formattedEntries = data.map(formatEntry)
-  Logger.info('Formatted data.')
+  Logger.info("Formatted data.")
 
-  Logger.info('Updating database...')
+  Logger.info("Updating database...")
   try {
     await knex.transaction((trx) =>
       knex
         .delete()
-        .from('relations')
+        .from("relations")
         .transacting(trx)
         .then(() =>
-          knex.batchInsert('relations', formattedEntries, 100).transacting(trx),
+          knex.batchInsert("relations", formattedEntries, 100).transacting(trx),
         ),
     )
   } catch (error) {
     throw new Error(error)
   }
-  Logger.info('Updated database.')
+  Logger.info("Updated database.")
 
-  Logger.info('Executing manual rules...')
+  Logger.info("Executing manual rules...")
   await updateBasedOnManualRules()
 
-  Logger.info('Done.')
+  Logger.info("Done.")
 }
diff --git a/src/utils.ts b/src/utils.ts
index 0004f44fd..5b5202885 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -2,9 +2,7 @@
 
 export const enumToArray = (e: E): E[] => Object.values(e)
 
-export const isEmpty = <
-  T extends Record | Record[],
->(
+export const isEmpty =  | Record[]>(
   obj: T,
 ) => {
   if (Array.isArray(obj)) {

From 144354a05b838865193ba211a8ce109a086f65dd Mon Sep 17 00:00:00 2001
From: Adam 
Date: Thu, 3 Jun 2021 19:01:12 +0200
Subject: [PATCH 4/4] update renovate node config

---
 .github/renovate.json5 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/renovate.json5 b/.github/renovate.json5
index e4df92bca..4fd6ab7fc 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -9,7 +9,7 @@
   packageRules: [
     {
       packageNames: ["node"],
-      allowedVersions: "<13",
+      allowedVersions: "<=14",
       rangeStrategy: "replace",
     },
     {