Skip to content

Commit

Permalink
fix(@angular/cli): prevent BOM errors in package.json during `ng up…
Browse files Browse the repository at this point in the history
…date`

To prevent `JSON.parse` errors triggered by Byte Order Marks (BOMs) in package.json files, the `readJson` tree method is now utilized for more reliable BOM handling.

Closes #27052

(cherry picked from commit 782c718)
  • Loading branch information
alan-agius4 committed Feb 9, 2024
1 parent da1c38c commit b07246a
Showing 1 changed file with 14 additions and 27 deletions.
41 changes: 14 additions & 27 deletions packages/angular/cli/src/commands/update/schematic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,7 @@ function _performUpdate(
throw new SchematicsException('Could not find a package.json. Are you in a Node project?');
}

let packageJson: JsonSchemaForNpmPackageJsonFiles;
try {
packageJson = JSON.parse(packageJsonContent.toString()) as JsonSchemaForNpmPackageJsonFiles;
} catch (e) {
assertIsError(e);
throw new SchematicsException('package.json could not be parsed: ' + e.message);
}
const packageJson = tree.readJson('/package.json') as JsonSchemaForNpmPackageJsonFiles;

const updateDependency = (deps: Record<string, string>, name: string, newVersion: string) => {
const oldVersion = deps[name];
Expand Down Expand Up @@ -556,11 +550,13 @@ function _buildPackageInfo(

// Find out the currently installed version. Either from the package.json or the node_modules/
// TODO: figure out a way to read package-lock.json and/or yarn.lock.
const pkgJsonPath = `/node_modules/${name}/package.json`;
const pkgJsonExists = tree.exists(pkgJsonPath);

let installedVersion: string | undefined | null;
const packageContent = tree.read(`/node_modules/${name}/package.json`);
if (packageContent) {
const content = JSON.parse(packageContent.toString()) as JsonSchemaForNpmPackageJsonFiles;
installedVersion = content.version;
if (pkgJsonExists) {
const { version } = tree.readJson(pkgJsonPath) as JsonSchemaForNpmPackageJsonFiles;
installedVersion = version;
}

const packageVersionsNonDeprecated: string[] = [];
Expand Down Expand Up @@ -590,7 +586,7 @@ function _buildPackageInfo(
);
}

const installedPackageJson = npmPackageJson.versions[installedVersion] || packageContent;
const installedPackageJson = npmPackageJson.versions[installedVersion] || pkgJsonExists;
if (!installedPackageJson) {
throw new SchematicsException(
`An unexpected error happened; package ${name} has no version ${installedVersion}.`,
Expand Down Expand Up @@ -783,23 +779,14 @@ function _addPeerDependencies(
}

function _getAllDependencies(tree: Tree): Array<readonly [string, VersionRange]> {
const packageJsonContent = tree.read('/package.json');
if (!packageJsonContent) {
throw new SchematicsException('Could not find a package.json. Are you in a Node project?');
}

let packageJson: JsonSchemaForNpmPackageJsonFiles;
try {
packageJson = JSON.parse(packageJsonContent.toString()) as JsonSchemaForNpmPackageJsonFiles;
} catch (e) {
assertIsError(e);
throw new SchematicsException('package.json could not be parsed: ' + e.message);
}
const { dependencies, devDependencies, peerDependencies } = tree.readJson(
'/package.json',
) as JsonSchemaForNpmPackageJsonFiles;

return [
...(Object.entries(packageJson.peerDependencies || {}) as Array<[string, VersionRange]>),
...(Object.entries(packageJson.devDependencies || {}) as Array<[string, VersionRange]>),
...(Object.entries(packageJson.dependencies || {}) as Array<[string, VersionRange]>),
...(Object.entries(peerDependencies || {}) as Array<[string, VersionRange]>),
...(Object.entries(devDependencies || {}) as Array<[string, VersionRange]>),
...(Object.entries(dependencies || {}) as Array<[string, VersionRange]>),
];
}

Expand Down

0 comments on commit b07246a

Please sign in to comment.