Repository: typescript-eslint/tslint-to-eslint-config (ts)

Issue:
Consider TSLint rules enabled by eslint-plugin-tslint
### 🚀 Feature Request

ESLint configurations might already enable TSLint rules under [eslint-plugin-tslint](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin-tslint). 

#### Existing Behavior

Only `tslint.json` is considered as a source of truth.

#### Change Proposal

When creating the list of enabled TSLint rules, apply any rules listed under `eslint-plugin-tslint` on top of `tslint.json` rules.

Related: #5, #34.


Pull request:
Included ESLint configuration in TSLint rules list
# PR Checklist

-   [x] Addresses an existing issue: fixes #57
-   [x] That issue was marked as [`status: accepting prs`](https://github.com/typescript-eslint/tslint-to-eslint-config/labels/status%3A%20accepting%20prs)

## Overview

As long as the parsed ESLint configuration wasn't an `Error`, any existing typescript-eslint-wrapped TSLint rules will be read by it as well.

Patch:
diff --git a/src/cli/main.ts b/src/cli/main.ts
index cbfd1f1..c6a3535 100644
--- a/src/cli/main.ts
+++ b/src/cli/main.ts
@@ -27,6 +27,7 @@ import { findPackagesConfiguration } from "../input/findPackagesConfiguration";
 import { findESLintConfiguration } from "../input/findESLintConfiguration";
 import { findTSLintConfiguration } from "../input/findTSLintConfiguration";
 import { findTypeScriptConfiguration } from "../input/findTypeScriptConfiguration";
+import { mergeLintConfigurations } from "../input/mergeLintConfigurations";
 import {
     reportConversionResults,
     ReportConversionResultsDependencies,
@@ -50,6 +51,7 @@ const findOriginalConfigurationsDependencies: FindOriginalConfigurationsDependen
     findPackagesConfiguration: bind(findPackagesConfiguration, findConfigurationDependencies),
     findTypeScriptConfiguration: bind(findTypeScriptConfiguration, findConfigurationDependencies),
     findTSLintConfiguration: bind(findTSLintConfiguration, findConfigurationDependencies),
+    mergeLintConfigurations,
 };
 
 const reportConversionResultsDependencies: ReportConversionResultsDependencies = {
diff --git a/src/input/findOriginalConfigurations.ts b/src/input/findOriginalConfigurations.ts
index a3b387b..a2139f0 100644
--- a/src/input/findOriginalConfigurations.ts
+++ b/src/input/findOriginalConfigurations.ts
@@ -7,12 +7,14 @@ import {
     TypeScriptConfiguration,
 } from "./findTypeScriptConfiguration";
 import { findTSLintConfiguration, TSLintConfiguration } from "./findTSLintConfiguration";
+import { mergeLintConfigurations } from "./mergeLintConfigurations";
 
 export type FindOriginalConfigurationsDependencies = {
     findESLintConfiguration: SansDependencies<typeof findESLintConfiguration>;
     findPackagesConfiguration: SansDependencies<typeof findPackagesConfiguration>;
     findTypeScriptConfiguration: SansDependencies<typeof findTypeScriptConfiguration>;
     findTSLintConfiguration: SansDependencies<typeof findTSLintConfiguration>;
+    mergeLintConfigurations: typeof mergeLintConfigurations;
 };
 
 export type OriginalConfigurations = {
@@ -44,7 +46,7 @@ export const findOriginalConfigurations = async (
         data: {
             ...(!(eslint instanceof Error) && { eslint }),
             ...(!(packages instanceof Error) && { packages }),
-            tslint,
+            tslint: dependencies.mergeLintConfigurations(eslint, tslint),
             ...(!(typescript instanceof Error) && { typescript }),
         },
         status: ResultStatus.Succeeded,
diff --git a/src/input/mergeLintConfigurations.ts b/src/input/mergeLintConfigurations.ts
new file mode 100644
index 0000000..662be35
--- /dev/null
+++ b/src/input/mergeLintConfigurations.ts
@@ -0,0 +1,24 @@
+import { TSLintConfiguration } from "./findTSLintConfiguration";
+import { ESLintConfiguration } from "./findESLintConfiguration";
+
+export const mergeLintConfigurations = (
+    eslint: ESLintConfiguration | Error,
+    tslint: TSLintConfiguration,
+) => {
+    if (eslint instanceof Error) {
+        return tslint;
+    }
+
+    const mappedConfig = eslint.rules["@typescript-eslint/tslint/config"];
+    if (!(mappedConfig instanceof Array) || mappedConfig[0] === "off") {
+        return tslint;
+    }
+
+    return {
+        ...tslint,
+        rules: {
+            ...tslint.rules,
+            ...mappedConfig[1].rules,
+        },
+    };
+};


Test patch:
diff --git a/src/conversion/convertConfig.test.ts b/src/conversion/convertConfig.test.ts
index 92a9eb1..aadc257 100644
--- a/src/conversion/convertConfig.test.ts
+++ b/src/conversion/convertConfig.test.ts
@@ -1,6 +1,5 @@
-import { ResultStatus, FailedResult, SucceededDataResult } from "../types";
+import { ResultStatus, FailedResult } from "../types";
 import { convertConfig, ConvertConfigDependencies } from "./convertConfig";
-import { OriginalConfigurations } from "../input/findOriginalConfigurations";
 
 const stubSettings = {
     config: "./eslintrc.js",
diff --git a/src/input/findOriginalConfigurations.test.ts b/src/input/findOriginalConfigurations.test.ts
index cd476f2..267ca06 100644
--- a/src/input/findOriginalConfigurations.test.ts
+++ b/src/input/findOriginalConfigurations.test.ts
@@ -3,6 +3,8 @@ import {
     FindOriginalConfigurationsDependencies,
 } from "./findOriginalConfigurations";
 import { ResultStatus } from "../types";
+import { TSLintConfiguration } from "./findTSLintConfiguration";
+import { ESLintConfiguration } from "./findESLintConfiguration";
 
 const createRawSettings = () => ({
     config: "./eslintrc.js",
@@ -30,6 +32,8 @@ const createDependencies = (overrides: Partial<FindOriginalConfigurationsDepende
             target: "es3",
         },
     }),
+    mergeLintConfigurations: (_: ESLintConfiguration | Error, tslint: TSLintConfiguration) =>
+        tslint,
     ...overrides,
 });
 
diff --git a/src/input/mergeLintConfigurations.test.ts b/src/input/mergeLintConfigurations.test.ts
new file mode 100644
index 0000000..56297d8
--- /dev/null
+++ b/src/input/mergeLintConfigurations.test.ts
@@ -0,0 +1,91 @@
+import { mergeLintConfigurations } from "./mergeLintConfigurations";
+import { ESLintConfiguration } from "./findESLintConfiguration";
+
+const stubTSLintConfiguration = {
+    rulesDirectory: [],
+    rules: {
+        disabled: true,
+        enabled: true,
+    },
+};
+
+describe("mergeLintConfigurations", () => {
+    it("returns the tslint configuration when the eslint configuration is an error", () => {
+        // Arrange
+        const eslint = new Error();
+
+        // Act
+        const result = mergeLintConfigurations(eslint, stubTSLintConfiguration);
+
+        // Assert
+        expect(result).toBe(stubTSLintConfiguration);
+    });
+
+    it("returns the tslint configuration when the eslint configuration doesn't have tslint rules", () => {
+        // Arrange
+        const eslint: ESLintConfiguration = {
+            env: {},
+            extends: [],
+            rules: {},
+        };
+
+        // Act
+        const result = mergeLintConfigurations(eslint, stubTSLintConfiguration);
+
+        // Assert
+        expect(result).toBe(stubTSLintConfiguration);
+    });
+
+    it("returns the tslint configuration when the eslint configuration's tslint rules are disabled", () => {
+        // Arrange
+        const eslint: ESLintConfiguration = {
+            env: {},
+            extends: [],
+            rules: {
+                "@typescript-eslint/tslint/config": [
+                    "off",
+                    {
+                        extra: true,
+                    },
+                ],
+            },
+        };
+
+        // Act
+        const result = mergeLintConfigurations(eslint, stubTSLintConfiguration);
+
+        // Assert
+        expect(result).toBe(stubTSLintConfiguration);
+    });
+
+    it("returns the merged configurations when the eslint configuration has tslint rules", () => {
+        // Arrange
+        const extraRules = {
+            extra: true,
+        };
+        const eslint: ESLintConfiguration = {
+            env: {},
+            extends: [],
+            rules: {
+                "@typescript-eslint/tslint/config": [
+                    "error",
+                    {
+                        rules: extraRules,
+                    },
+                ],
+            },
+        };
+
+        // Act
+        const result = mergeLintConfigurations(eslint, stubTSLintConfiguration);
+
+        // Assert
+        expect(result).toEqual({
+            ...stubTSLintConfiguration,
+            rules: {
+                ...stubTSLintConfiguration.rules,
+                ...extraRules,
+            },
+        });
+    });
+});