From fbece3ecf08f62d2fc03fb04778dfee5d377321c Mon Sep 17 00:00:00 2001 From: DuroCodes Date: Tue, 30 Jul 2024 17:21:21 -0400 Subject: [PATCH] fix: make tsconfig work with comments/trailing commas --- src/commands/build.ts | 5 ++-- src/utilities/edits.ts | 5 +++- src/utilities/parseTsconfig.ts | 50 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/utilities/parseTsconfig.ts diff --git a/src/commands/build.ts b/src/commands/build.ts index c7a2244..1795caf 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -10,6 +10,7 @@ import { pathExists, pathExistsSync } from 'find-up'; import { mkdir, writeFile, readFile } from 'fs/promises'; import * as Preprocessor from '../utilities/preprocessor'; import { bold, magentaBright } from 'colorette'; +import { parseTsConfig } from '../utilities/parseTsconfig'; const VALID_EXTENSIONS = ['.ts', '.js' ]; @@ -103,8 +104,8 @@ export async function build(options: Record) { } assert(buildConfig.mode === 'development' || buildConfig.mode === 'production', 'Mode is not `production` or `development`'); try { - let config = JSON.parse(await readFile(buildConfig.tsconfig!, 'utf8')); - config.extends && console.warn("Extend the generated tsconfig") + let config = await parseTsConfig(buildConfig.tsconfig!); + config?.extends && console.warn("Extend the generated tsconfig") } catch(e) { console.error("no tsconfig / jsconfig found"); console.error(`Please create a ${sernConfig.language === 'javascript' ? 'jsconfig.json' : 'tsconfig.json' }`); diff --git a/src/utilities/edits.ts b/src/utilities/edits.ts index 77d4c7a..68e9c60 100644 --- a/src/utilities/edits.ts +++ b/src/utilities/edits.ts @@ -1,6 +1,7 @@ import { findUp } from 'find-up'; import { readFile, rename, writeFile } from 'node:fs/promises'; import { fromCwd } from './fromCwd.js'; +import { parseTsConfig } from './parseTsconfig.js'; /** * It takes a string, finds the package.json file in the directory of the string, and changes the name @@ -61,10 +62,12 @@ export async function editDirs( }); if (tsconfig) { - const output = JSON.parse(await readFile(tsconfig, 'utf8')); + const output = await parseTsConfig(tsconfig); if (!output) throw new Error("Can't read your tsconfig.json."); + if (!output.compilerOptions) throw new Error("Can't find compilerOptions in your tsconfig.json."); output.compilerOptions.rootDir = srcName; + // This will strip comments/trailing commas from the tsconfig.json file await writeFile(tsconfig, JSON.stringify(output, null, 2)); } diff --git a/src/utilities/parseTsconfig.ts b/src/utilities/parseTsconfig.ts new file mode 100644 index 0000000..0aff283 --- /dev/null +++ b/src/utilities/parseTsconfig.ts @@ -0,0 +1,50 @@ +import { resolve } from 'node:path'; +import { readFile } from 'node:fs/promises'; + +interface CompilerOptions { + target: string; + module: string; + lib: string[]; + allowJs: boolean; + checkJs: boolean; + jsx: string; + declaration: boolean; + sourceMap: boolean; + outDir: string; + rootDir: string; + strict: boolean; + esModuleInterop: boolean; + forceConsistentCasingInFileNames: boolean; + noEmit: boolean; + importHelpers: boolean; + isolatedModules: boolean; + moduleResolution: string; + resolveJsonModule: boolean; + noEmitHelpers: boolean; +} + +interface TsConfig { + compilerOptions: CompilerOptions; + files: string[]; + include: string[]; + exclude: string[]; + extends: string; +} + +const cleanJson = (json: string) => + json + .replace(/\/\/.*$/gm, '') + .replace(/\/\*[\s\S]*?\*\//gm, '') + .replace(/,\s*([}\]])/g, '$1'); + +export const parseTsConfig = async (path: string) => { + const absPath = resolve(path); + const fileContent = await readFile(absPath, 'utf-8'); + const cleanContent = cleanJson(fileContent); + + try { + return JSON.parse(cleanContent) as Partial; + } catch (e) { + return null; + } +};