From 925a27bf6464650877185958014d43886b8fa380 Mon Sep 17 00:00:00 2001 From: Jason Jean Date: Wed, 1 Jun 2022 13:13:24 -0400 Subject: [PATCH] fix(devkit): add options allow trailing commas for parsing json (#10538) --- .../update-14-2-0/update-tsconfig-target.ts | 33 ++++++++++++------- .../update-14-0-0/update-jest-config-ext.ts | 20 +++++++---- packages/nx/src/utils/json.spec.ts | 17 ++++++++++ packages/nx/src/utils/json.ts | 24 ++++++-------- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/packages/angular/src/migrations/update-14-2-0/update-tsconfig-target.ts b/packages/angular/src/migrations/update-14-2-0/update-tsconfig-target.ts index 6ef8eb6386128..c3cd4ce2d8411 100644 --- a/packages/angular/src/migrations/update-14-2-0/update-tsconfig-target.ts +++ b/packages/angular/src/migrations/update-14-2-0/update-tsconfig-target.ts @@ -32,17 +32,25 @@ export default async function (tree: Tree) { const tsConfigPaths = await collectTsConfigPaths(tree); for (const tsConfigPath of tsConfigPaths) { - updateJson(tree, tsConfigPath, (json) => { - if ( - !json.compilerOptions?.target || - (json.compilerOptions?.target && - !skipTargets.includes(json.compilerOptions.target.toLowerCase())) - ) { - json.compilerOptions ??= {}; - json.compilerOptions.target = 'es2020'; + updateJson( + tree, + tsConfigPath, + (json) => { + if ( + !json.compilerOptions?.target || + (json.compilerOptions?.target && + !skipTargets.includes(json.compilerOptions.target.toLowerCase())) + ) { + json.compilerOptions ??= {}; + json.compilerOptions.target = 'es2020'; + } + return json; + }, + { + allowTrailingComma: true, + disallowComments: false, } - return json; - }); + ); } await formatFiles(tree); @@ -73,7 +81,10 @@ async function collectTsConfigPaths(tree: Tree): Promise { false ); targetTsConfigPaths.forEach((tsConfigPath) => { - const tsConfig = readJson(tree, tsConfigPath); + const tsConfig = readJson(tree, tsConfigPath, { + allowTrailingComma: true, + disallowComments: false, + }); if (tsConfig.compilerOptions?.target) { uniqueTsConfigs.add(tsConfigPath); } diff --git a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts index 03bab41987400..25044ce893453 100644 --- a/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts +++ b/packages/jest/src/migrations/update-14-0-0/update-jest-config-ext.ts @@ -18,12 +18,20 @@ const allowedExt = ['.ts', '.js']; function updateTsConfig(tree: Tree, tsConfigPath: string) { try { - updateJson(tree, tsConfigPath, (json) => { - json.exclude = Array.from( - new Set([...(json.exclude || []), 'jest.config.ts']) - ); - return json; - }); + updateJson( + tree, + tsConfigPath, + (json) => { + json.exclude = Array.from( + new Set([...(json.exclude || []), 'jest.config.ts']) + ); + return json; + }, + { + allowTrailingComma: true, + disallowComments: false, + } + ); } catch (e) { logger.warn( stripIndents`Nx Unable to update ${tsConfigPath}. Please manually ignore the jest.config.ts file.` diff --git a/packages/nx/src/utils/json.spec.ts b/packages/nx/src/utils/json.spec.ts index 1581d85dbf75a..8d053badd466a 100644 --- a/packages/nx/src/utils/json.spec.ts +++ b/packages/nx/src/utils/json.spec.ts @@ -79,4 +79,21 @@ describe('parseJson', () => { ) ).toThrowError(); }); + + it('should handle trailing commas', () => { + expect( + parseJson( + `{ + "nested": { + "test": 123, + }, + "array": [1, 2, 3,] + }`, + { allowTrailingComma: true } + ) + ).toEqual({ + nested: { test: 123 }, + array: [1, 2, 3], + }); + }); }); diff --git a/packages/nx/src/utils/json.ts b/packages/nx/src/utils/json.ts index a56b6d0fd63b4..b619f67fd031f 100644 --- a/packages/nx/src/utils/json.ts +++ b/packages/nx/src/utils/json.ts @@ -1,9 +1,9 @@ import { parse, printParseErrorCode, stripComments } from 'jsonc-parser'; -import type { ParseError } from 'jsonc-parser'; +import type { ParseError, ParseOptions } from 'jsonc-parser'; export { stripComments as stripJsonComments }; -export interface JsonParseOptions { +export interface JsonParseOptions extends ParseOptions { /** * Expect JSON with javascript-style * @default false @@ -14,6 +14,11 @@ export interface JsonParseOptions { * @default false */ disallowComments?: boolean; + + /** + * Allow trailing commas in the JSON content + */ + allowTrailingComma?: boolean; } export interface JsonSerializeOptions { @@ -37,20 +42,11 @@ export function parseJson( options?: JsonParseOptions ): T { try { - if ( - options?.disallowComments === true || - options?.expectComments !== true - ) { - return JSON.parse(input); - } - } catch (error) { - if (options?.disallowComments === true) { - throw error; - } - } + return JSON.parse(input); + } catch {} const errors: ParseError[] = []; - const result: T = parse(input, errors); + const result: T = parse(input, errors, options); if (errors.length > 0) { const { error, offset } = errors[0];