Repository: JoshuaKGoldberg/TypeStat (ts)

Issue:
🛠 Tooling: replace strip-ansi package with node's stripVTControlCharacters
### Bug Report Checklist

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

### Overview

We could replace `strip-ansi` package with node's `stripVTControlCharacters`. strip-ansi is used only in one place (`createProcessOutput.ts`), so it should be easy task.

### Additional Info

_No response_

Pull request description:
fix: replace `strip-ansi` with `stripVTControlCharacters`
## PR Checklist

- [x] Addresses an existing open issue: fixes #2177
- [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/TypeStat/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/TypeStat/blob/main/.github/CONTRIBUTING.md) were taken

## Overview

`stripVTControlCharacters` was added in nodejs v16.11.0 and appears to be a direct replacement for the functionality from `strip-ansi`.

`TypeStat` already declares a dependency on nodejs >= 18 in its `package.json`, so depending on this new API should be safe.

Fixes #2177

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad06134..4184e7c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
 # Changelog
 
+## [0.8.14](https://github.com/JoshuaKGoldberg/TypeStat/compare/0.8.13...0.8.14) (2025-02-06)
+
+### Bug Fixes
+
+- createJavaScriptConfig should print projectPath instead of project ([#2184](https://github.com/JoshuaKGoldberg/TypeStat/issues/2184)) ([8a5792b](https://github.com/JoshuaKGoldberg/TypeStat/commit/8a5792b897c091168d6977af66ca679ba44bcf0f)), closes [#2178](https://github.com/JoshuaKGoldberg/TypeStat/issues/2178)
+
+## [0.8.13](https://github.com/JoshuaKGoldberg/TypeStat/compare/0.8.12...0.8.13) (2025-02-06)
+
+### Bug Fixes
+
+- replace builtin-modules package with node's isBuiltin check ([#2176](https://github.com/JoshuaKGoldberg/TypeStat/issues/2176)) ([8d40464](https://github.com/JoshuaKGoldberg/TypeStat/commit/8d404647cb29e43416b169e6149fef604fcb3f40)), closes [#2175](https://github.com/JoshuaKGoldberg/TypeStat/issues/2175)
+
 ## [0.8.12](https://github.com/JoshuaKGoldberg/TypeStat/compare/0.8.11...0.8.12) (2025-02-04)
 
 ### Bug Fixes
diff --git a/package.json b/package.json
index 4a28653..f5b2ef6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "typestat",
-	"version": "0.8.12",
+	"version": "0.8.14",
 	"description": "Converts JavaScript to TypeScript and TypeScript to better TypeScript. 🧫",
 	"repository": {
 		"type": "git",
@@ -46,7 +46,6 @@
 		"commander": "13.1.0",
 		"enquirer": "2.4.1",
 		"glob": "11.0.1",
-		"strip-ansi": "7.1.0",
 		"ts-api-utils": "2.0.1"
 	},
 	"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c1f3b9c..df18de7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -26,9 +26,6 @@ importers:
       glob:
         specifier: 11.0.1
         version: 11.0.1
-      strip-ansi:
-        specifier: 7.1.0
-        version: 7.1.0
       ts-api-utils:
         specifier: 2.0.1
         version: 2.0.1(typescript@5.7.3)
diff --git a/src/initialization/initializeJavaScript/createJavaScriptConfig.ts b/src/initialization/initializeJavaScript/createJavaScriptConfig.ts
index e64f2c7..9fd68dd 100644
--- a/src/initialization/initializeJavaScript/createJavaScriptConfig.ts
+++ b/src/initialization/initializeJavaScript/createJavaScriptConfig.ts
@@ -1,3 +1,4 @@
+import { RawTypeStatOptions, RenameExtensions } from "../../options/types.js";
 import { ProjectDescription } from "../initializeProject/shared.js";
 import { InitializationCleanups } from "./cleanups.js";
 import { InitializationImports } from "./imports.js";
@@ -17,60 +18,61 @@ export const createJavaScriptConfig = ({
 	project,
 	renames,
 	sourceFiles,
-}: JavaScriptConfigSettings) => {
-	const fileConversion = {
+}: JavaScriptConfigSettings): RawTypeStatOptions | RawTypeStatOptions[] => {
+	const fileConversion: RawTypeStatOptions = {
 		files: {
 			renameExtensions: printRenames(renames),
 		},
 	};
-	const coreConversion = {
+
+	const coreCleanups: RawTypeStatOptions =
+		cleanups === InitializationCleanups.Yes
+			? { cleanups: { suppressTypeErrors: true } }
+			: {};
+
+	const coreConversion: RawTypeStatOptions = {
 		fixes: {
 			incompleteTypes: true,
 			missingProperties: true,
 			noImplicitAny: true,
 		},
-		...(cleanups === InitializationCleanups.Yes
-			? { cleanups: { suppressTypeErrors: true } }
-			: {}),
+		...coreCleanups,
 	};
-	const shared = (include: string[] | undefined) => ({
-		...(include && { include }),
-		project: project.filePath,
-	});
 
-	const allConversions =
-		imports === InitializationImports.Yes
-			? [
-					{
-						...fileConversion,
-						fixes: {
-							importExtensions: true,
-						},
-						...shared(sourceFiles ? [sourceFiles] : undefined),
-					},
-					{
-						...coreConversion,
-						...shared(
-							sourceFiles
-								? renames === InitializationRenames.Auto
-									? renameSourceFilesExtensionsAuto(sourceFiles)
-									: renames === InitializationRenames.TS
-										? renameSourceFilesExtensions(sourceFiles, "ts")
-										: renameSourceFilesExtensions(sourceFiles, "tsx")
-								: undefined,
-						),
-					},
-				]
-			: {
-					...fileConversion,
-					...coreConversion,
-					...shared(sourceFiles ? [sourceFiles] : undefined),
-				};
+	const included = (include: string[] | undefined): RawTypeStatOptions =>
+		include?.length ? { include } : {};
+
+	const sourceFilesInclude: RawTypeStatOptions = included(
+		sourceFiles ? [sourceFiles] : undefined,
+	);
 
-	return allConversions;
+	if (imports === InitializationImports.Yes) {
+		return [
+			{
+				...fileConversion,
+				fixes: {
+					importExtensions: true,
+				},
+				...sourceFilesInclude,
+				projectPath: project.filePath,
+			},
+			{
+				...coreConversion,
+				...included(getRenamedSourceFiles(sourceFiles, renames)),
+				projectPath: project.filePath,
+			},
+		];
+	}
+
+	return {
+		...fileConversion,
+		...coreConversion,
+		...sourceFilesInclude,
+		projectPath: project.filePath,
+	};
 };
 
-const printRenames = (renames: InitializationRenames) => {
+const printRenames = (renames: InitializationRenames): RenameExtensions => {
 	switch (renames) {
 		case InitializationRenames.Auto:
 			return true;
@@ -83,7 +85,23 @@ const printRenames = (renames: InitializationRenames) => {
 	}
 };
 
-function renameSourceFilesExtensions(sourceFiles: string, extension: string) {
+function getRenamedSourceFiles(
+	sourceFiles: string | undefined,
+	renames: InitializationRenames,
+): string[] | undefined {
+	return sourceFiles
+		? renames === InitializationRenames.Auto
+			? renameSourceFilesExtensionsAuto(sourceFiles)
+			: renames === InitializationRenames.TS
+				? renameSourceFilesExtensions(sourceFiles, "ts")
+				: renameSourceFilesExtensions(sourceFiles, "tsx")
+		: undefined;
+}
+
+function renameSourceFilesExtensions(
+	sourceFiles: string,
+	extension: string,
+): string[] {
 	return [
 		sourceFiles
 			.replace(/(\.|\{)js/, `$1${extension}`)
@@ -91,7 +109,7 @@ function renameSourceFilesExtensions(sourceFiles: string, extension: string) {
 	];
 }
 
-function renameSourceFilesExtensionsAuto(sourceFiles: string) {
+function renameSourceFilesExtensionsAuto(sourceFiles: string): string[] {
 	for (const [original, replacement] of [
 		[/\{js,jsx\}/, "{ts,tsx}"],
 		[/\.js$/, ".{ts,tsx}"],
diff --git a/src/output/createProcessOutput.ts b/src/output/createProcessOutput.ts
index 344fc0b..3d70374 100644
--- a/src/output/createProcessOutput.ts
+++ b/src/output/createProcessOutput.ts
@@ -1,6 +1,6 @@
 import * as fs from "node:fs";
 import { EOL } from "os";
-import stripAnsi from "strip-ansi";
+import { stripVTControlCharacters } from "util";
 
 import { ProcessOutput } from "./types.js";
 
@@ -11,7 +11,7 @@ export const createProcessOutput = (logFile?: string): ProcessOutput => {
 		return (line: string) => {
 			stream.write(line + EOL);
 			log?.(
-				stripAnsi(
+				stripVTControlCharacters(
 					`[${prefix}] ${line.replace(/^\r\n|\r|\n/g, "").replace(/\r\n|\r|\n$/g, "")}`,
 				),
 			);


Test patch:
diff --git a/src/initialization/initializeJavaScript/createJavaScriptConfig.test.ts b/src/initialization/initializeJavaScript/createJavaScriptConfig.test.ts
index 21effe1..68d78a8 100644
--- a/src/initialization/initializeJavaScript/createJavaScriptConfig.test.ts
+++ b/src/initialization/initializeJavaScript/createJavaScriptConfig.test.ts
@@ -1,12 +1,22 @@
 import { describe, expect, it } from "vitest";
 
+import { RawTypeStatOptions } from "../../options/types.js";
 import { InitializationCleanups } from "./cleanups.js";
-import { createJavaScriptConfig } from "./createJavaScriptConfig.js";
+import {
+	createJavaScriptConfig,
+	JavaScriptConfigSettings,
+} from "./createJavaScriptConfig.js";
 import { InitializationImports } from "./imports.js";
 import { InitializationRenames } from "./renames.js";
 
+interface TestArguments {
+	expected: RawTypeStatOptions | RawTypeStatOptions[];
+	name: string;
+	settings: JavaScriptConfigSettings;
+}
+
 describe("createJavaScriptConfig", () => {
-	it.each([
+	it.each<TestArguments>([
 		{
 			expected: {
 				files: { renameExtensions: "ts" },
@@ -15,7 +25,7 @@ describe("createJavaScriptConfig", () => {
 					missingProperties: true,
 					noImplicitAny: true,
 				},
-				project: "tsconfig.json",
+				projectPath: "tsconfig.json",
 			},
 			name: "Basic",
 			settings: {
@@ -36,7 +46,7 @@ describe("createJavaScriptConfig", () => {
 					missingProperties: true,
 					noImplicitAny: true,
 				},
-				project: "tsconfig.json",
+				projectPath: "tsconfig.json",
 			},
 			name: "Basic with Suppressions",
 			settings: {
@@ -54,7 +64,7 @@ describe("createJavaScriptConfig", () => {
 					files: { renameExtensions: "ts" },
 					fixes: { importExtensions: true },
 					include: ["src/**/*.{js,jsx}"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -63,7 +73,7 @@ describe("createJavaScriptConfig", () => {
 						noImplicitAny: true,
 					},
 					include: ["src/**/*.ts"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "TS Renames (multiple sourceFiles extensions)",
@@ -83,7 +93,7 @@ describe("createJavaScriptConfig", () => {
 					files: { renameExtensions: "tsx" },
 					fixes: { importExtensions: true },
 					include: ["src/**/*.{js,jsx}"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -92,7 +102,7 @@ describe("createJavaScriptConfig", () => {
 						noImplicitAny: true,
 					},
 					include: ["src/**/*.tsx"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "TSX Renames (multiple sourceFiles extensions)",
@@ -111,7 +121,7 @@ describe("createJavaScriptConfig", () => {
 				{
 					files: { renameExtensions: true },
 					fixes: { importExtensions: true },
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -119,7 +129,7 @@ describe("createJavaScriptConfig", () => {
 						missingProperties: true,
 						noImplicitAny: true,
 					},
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "Auto Renames (no sourceFiles)",
@@ -138,7 +148,7 @@ describe("createJavaScriptConfig", () => {
 					files: { renameExtensions: true },
 					fixes: { importExtensions: true },
 					include: ["src/**/*.js"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -147,7 +157,7 @@ describe("createJavaScriptConfig", () => {
 						noImplicitAny: true,
 					},
 					include: ["src/**/*.{ts,tsx}"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "Auto Renames (single sourceFiles extension)",
@@ -167,7 +177,7 @@ describe("createJavaScriptConfig", () => {
 					files: { renameExtensions: true },
 					fixes: { importExtensions: true },
 					include: ["src/**/*.{js,jsx}"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -176,7 +186,7 @@ describe("createJavaScriptConfig", () => {
 						noImplicitAny: true,
 					},
 					include: ["src/**/*.{ts,tsx}"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "Auto Renames (multiple sourceFiles extensions)",
@@ -196,7 +206,7 @@ describe("createJavaScriptConfig", () => {
 					files: { renameExtensions: true },
 					fixes: { importExtensions: true },
 					include: ["src/**/*.js(x)"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 				{
 					fixes: {
@@ -205,7 +215,7 @@ describe("createJavaScriptConfig", () => {
 						noImplicitAny: true,
 					},
 					include: ["src/**/*.ts(x)"],
-					project: "tsconfig.json",
+					projectPath: "tsconfig.json",
 				},
 			],
 			name: "Auto Renames (parenthesized sourceFiles extensions)",