Repository: JoshuaKGoldberg/create-typescript-app (ts)

Issue:
🚀 Feature: Infer tsconfig.json entries from disk
### Feature Request Checklist

- [x] I have pulled the latest `main` branch of the repository.
- [x] I have [searched for related issues](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aissue) and found none that matched my issue.

### Overview

Running `npx create-typescript-app` on a repo with existing `tsconfig.json` customizations should read those in as Addons to `blockTypeScript`. That way `create-typescript-app.config.*` files won't need to explicitly describe them under `refinements`.

### Additional Info

https://github.com/JoshuaKGoldberg/package-json-validator/pull/178/files#diff-5b778358ef07c9914c10021cf98855c355bb26724b4a16956a714515b556f750R68-R74 is an example of `compilerOptions` being specified.

🎁

Pull request description:
feat: add intake to blockTypeScript
## PR Checklist

- [x] Addresses an existing open issue: fixes #2115
- [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken

## Overview

🎁 

Patch:
diff --git a/src/blocks/blockTypeScript.ts b/src/blocks/blockTypeScript.ts
index a1f457f..2a646ad 100644
--- a/src/blocks/blockTypeScript.ts
+++ b/src/blocks/blockTypeScript.ts
@@ -1,3 +1,4 @@
+import JSON5 from "json5";
 import sortKeys from "sort-keys";
 import { CompilerOptionsSchema } from "zod-tsconfig";
 
@@ -14,6 +15,7 @@ import { blockPackageJson } from "./blockPackageJson.js";
 import { blockRemoveWorkflows } from "./blockRemoveWorkflows.js";
 import { blockVitest } from "./blockVitest.js";
 import { blockVSCode } from "./blockVSCode.js";
+import { intakeFile } from "./intake/intakeFile.js";
 
 export const blockTypeScript = base.createBlock({
 	about: {
@@ -22,6 +24,22 @@ export const blockTypeScript = base.createBlock({
 	addons: {
 		compilerOptions: CompilerOptionsSchema.optional(),
 	},
+	intake({ files }) {
+		const tsconfig = intakeFile(files, ["tsconfig.json"]);
+		if (!tsconfig) {
+			return undefined;
+		}
+
+		const raw = JSON5.parse<Record<string, undefined> | undefined>(tsconfig[0]);
+		const { data } = CompilerOptionsSchema.safeParse(raw?.compilerOptions);
+		if (!data) {
+			return undefined;
+		}
+
+		return {
+			compilerOptions: data,
+		};
+	},
 	produce({ addons, options }) {
 		const { compilerOptions } = addons;
 		const primaryBin = getPrimaryBin(options.bin, options.repository);


Test patch:
diff --git a/src/blocks/blockTypeScript.test.ts b/src/blocks/blockTypeScript.test.ts
index e01341a..405f180 100644
--- a/src/blocks/blockTypeScript.test.ts
+++ b/src/blocks/blockTypeScript.test.ts
@@ -1,5 +1,5 @@
-import { testBlock } from "bingo-stratum-testers";
-import { describe, expect, test } from "vitest";
+import { testBlock, testIntake } from "bingo-stratum-testers";
+import { describe, expect, it, test } from "vitest";
 
 import { blockTypeScript } from "./blockTypeScript.js";
 import { optionsBase } from "./options.fakes.js";
@@ -652,4 +652,46 @@ describe("blockTypeScript", () => {
 			}
 		`);
 	});
+
+	describe("intake", () => {
+		it("returns undefined when tsconfig.json does not exist", () => {
+			const actual = testIntake(blockTypeScript, {
+				files: {},
+			});
+
+			expect(actual).toBeUndefined();
+		});
+
+		it("returns undefined when tsconfig.json does not contain truthy data", () => {
+			const actual = testIntake(blockTypeScript, {
+				files: {
+					"tsconfig.json": [JSON.stringify(null)],
+				},
+			});
+
+			expect(actual).toBeUndefined();
+		});
+
+		it("returns undefined when tsconfig.json does not contain compilerOptions", () => {
+			const actual = testIntake(blockTypeScript, {
+				files: {
+					"tsconfig.json": [JSON.stringify({ other: true })],
+				},
+			});
+
+			expect(actual).toBeUndefined();
+		});
+
+		it("returns compilerOptions when tsconfig.json contains compilerOptions", () => {
+			const compilerOptions = { module: "ESNext" };
+
+			const actual = testIntake(blockTypeScript, {
+				files: {
+					"tsconfig.json": [JSON.stringify({ compilerOptions })],
+				},
+			});
+
+			expect(actual).toEqual({ compilerOptions });
+		});
+	});
 });