From 23a7cc231c6c4cb43d017a499372bcbf2404ff07 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Tue, 15 Oct 2024 20:48:52 -0700 Subject: [PATCH] refactor(npm): add validation of parsed pnpm-lock data --- npm/private/pnpm.bzl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/npm/private/pnpm.bzl b/npm/private/pnpm.bzl index 86f352619..92b563bd8 100644 --- a/npm/private/pnpm.bzl +++ b/npm/private/pnpm.bzl @@ -566,8 +566,38 @@ def _parse_lockfile(parsed, err): importers = utils.sorted_map(importers) packages = utils.sorted_map(packages) + _validate_lockfile_data(importers, packages) + return importers, packages, patched_dependencies, lockfile_version, None +def _validate_lockfile_data(importers, packages): + for name, deps in importers.items(): + _validate_lockfile_deps(packages, "importer", name, deps["dependencies"]) + _validate_lockfile_deps(packages, "importer", name, deps["dev_dependencies"]) + _validate_lockfile_deps(packages, "importer", name, deps["optional_dependencies"]) + + for name, info in packages.items(): + _validate_lockfile_deps(packages, "package", name, info["dependencies"]) + _validate_lockfile_deps(packages, "package", name, info["optional_dependencies"]) + +def _validate_lockfile_deps(packages, importer_type, importer, deps): + for dep, version in deps.items(): + if version.startswith("npm:"): + version = version[4:] + + if version not in packages and not (version.startswith("file:") or version.startswith("link:")) and not ("{}@{}".format(dep, version) in packages): + msg = "ERROR: {} '{}' depends on package '{}' at version '{}' which is not in the packages: {}".format( + importer_type, + importer, + dep, + version, + packages.keys(), + ) + + # TODO: fail instead of print + # buildifier: disable=print + print(msg) + def _assert_lockfile_version(version, testonly = False): if type(version) != type(1.0): fail("version should be passed as a float")