Module: Dependabot::NpmAndYarn
- Defined in:
- lib/dependabot/npm_and_yarn.rb,
lib/dependabot/npm_and_yarn/helpers.rb,
lib/dependabot/npm_and_yarn/version.rb,
lib/dependabot/npm_and_yarn/file_parser.rb,
lib/dependabot/npm_and_yarn/requirement.rb,
lib/dependabot/npm_and_yarn/file_fetcher.rb,
lib/dependabot/npm_and_yarn/file_updater.rb,
lib/dependabot/npm_and_yarn/package_name.rb,
lib/dependabot/npm_and_yarn/native_helpers.rb,
lib/dependabot/npm_and_yarn/update_checker.rb,
lib/dependabot/npm_and_yarn/metadata_finder.rb,
lib/dependabot/npm_and_yarn/package_manager.rb,
lib/dependabot/npm_and_yarn/registry_parser.rb,
lib/dependabot/npm_and_yarn/version_selector.rb,
lib/dependabot/npm_and_yarn/file_parser/json_lock.rb,
lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb,
lib/dependabot/npm_and_yarn/file_parser/yarn_lock.rb,
lib/dependabot/npm_and_yarn/dependency_files_filterer.rb,
lib/dependabot/npm_and_yarn/file_updater/npmrc_builder.rb,
lib/dependabot/npm_and_yarn/file_parser/lockfile_parser.rb,
lib/dependabot/npm_and_yarn/sub_dependency_files_filterer.rb,
lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb,
lib/dependabot/npm_and_yarn/update_checker/library_detector.rb,
lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb,
lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb,
lib/dependabot/npm_and_yarn/file_updater/package_json_updater.rb,
lib/dependabot/npm_and_yarn/file_updater/package_json_preparer.rb,
lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb,
lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb,
lib/dependabot/npm_and_yarn/update_checker/requirements_updater.rb,
lib/dependabot/npm_and_yarn/file_fetcher/path_dependency_builder.rb,
lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb,
lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb,
lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb,
lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb,
lib/dependabot/npm_and_yarn/update_checker/conflicting_dependency_resolver.rb
Overview
rubocop:disable Metrics/ModuleLength
Defined Under Namespace
Modules: Helpers, NativeHelpers Classes: DependencyFilesFilterer, FileFetcher, FileParser, FileUpdater, MetadataFinder, PackageManager, PackageName, RegistryParser, Requirement, SubDependencyFilesFilterer, UpdateChecker, Utils, Version, VersionSelector, YarnErrorHandler
Constant Summary collapse
- NODE_VERSION_NOT_SATISFY_REGEX =
rubocop:disable Layout/LineLength
/The current Node version (?<current_version>v?\d+\.\d+\.\d+) does not satisfy the required version (?<required_version>v?\d+\.\d+\.\d+)\./
- NPM_REGISTRY =
Used to check if package manager registry is public npm registry
"registry.npmjs.org"
- HTTP_CHECK_REGEX =
Used to check if url is http or https
%r{https?://}
- URL_CAPTURE =
Used to check capture url match in regex capture group
"url"
- INVALID_NAME_IN_PACKAGE_JSON =
When package name contains package.json name cannot contain characters like empty string or @.
"Name contains illegal characters"
- PACKAGE_MISSING_REGEX =
Used to identify error messages indicating a package is missing, unreachable, or there are network issues (e.g., ENOBUFS, ETIMEDOUT, registry down).
/(ENOBUFS|ETIMEDOUT|The registry may be down)/
- TIMEOUT_FETCHING_PACKAGE_REGEX =
Used to check if error message contains timeout fetching package
%r{(?<url>.+)/(?<package>[^/]+): ETIMEDOUT}
- ESOCKETTIMEDOUT =
/(?<package>.*?): ESOCKETTIMEDOUT/
- SOCKET_HANG_UP =
/(?<url>.*?): socket hang up/
- EEXIST =
Misc errors
/EEXIST: file already exists, mkdir '(?<regis>.*)'/
- REQUEST_ERROR_E403 =
registry access errors
/Request "(?<url>.*)" returned a 403/
- AUTH_REQUIRED_ERROR =
Authentication is required for the URL.
/(?<url>.*): authentication required/
- PERMISSION_DENIED =
Lack of permission to access the URL.
/(?<url>.*): Permission denied/
- BAD_REQUEST =
Inconsistent request while accessing resource.
/(?<url>.*): bad_request/
- INTERNAL_SERVER_ERROR =
Server error response by remote registry.
/Request failed "500 Internal Server Error"/
- UNREACHABLE_GIT_CHECK_REGEX =
Used to identify git unreachable error
/ls-remote --tags --heads (?<url>.*)/
- ONLY_PRIVATE_WORKSPACE_TEXT =
Used to check if yarn workspace is enabled in non-private workspace
"Workspaces can only be enabled in priva"
- SUB_DEP_LOCAL_PATH_TEXT =
Used to identify local path error in yarn when installing sub-dependency
"refers to a non-existing file"
- INVALID_PACKAGE_REGEX =
Used to identify invalid package error when package is not found in registry
/Can't add "[\w\-.]+": invalid/
- PACKAGE_NOT_FOUND =
Used to identify error if package not found in registry
"Couldn't find package"
- PACKAGE_NOT_FOUND_PACKAGE_NAME_REGEX =
/package "(?<package_req>.*?)"/
- PACKAGE_NOT_FOUND_PACKAGE_NAME_CAPTURE =
"package_req"
- PACKAGE_NOT_FOUND_PACKAGE_NAME_CAPTURE_SPLIT_REGEX =
/(?<=\w)\@/
- YARN_PACKAGE_NOT_FOUND_CODE =
/npm package "(?<dep>.*)" does not exist under owner "(?<regis>.*)"/
- YARN_PACKAGE_NOT_FOUND_CODE_1 =
/Couldn't find package "[^@].*(?<dep>.*)" on the "(?<regis>.*)" registry./
- YARN_PACKAGE_NOT_FOUND_CODE_2 =
rubocop:disable Layout/LineLength
/Couldn't find package "[^@].*(?<dep>.*)" required by "(?<pkg>.*)" on the "(?<regis>.*)" registry./
- YN0035 =
T.let({ PACKAGE_NOT_FOUND: %r{(?<package_req>@[\w-]+\/[\w-]+@\S+): Package not found}, FAILED_TO_RETRIEVE: %r{(?<package_req>@[\w-]+\/[\w-]+@\S+): The remote server failed to provide the requested resource} # rubocop:disable Layout/LineLength }.freeze, T::Hash[String, Regexp])
- YN0082_PACKAGE_NOT_FOUND_REGEX =
/YN0082:.*?(\S+@\S+): No candidates found/
- PACKAGE_NOT_FOUND2 =
%r{/[^/]+: Not found}
- PACKAGE_NOT_FOUND2_PACKAGE_NAME_REGEX =
%r{/(?<package_name>[^/]+): Not found}
- PACKAGE_NOT_FOUND2_PACKAGE_NAME_CAPTURE =
"package_name"
- DEPENDENCY_VERSION_NOT_FOUND =
Used to identify error if package not found in registry
"Couldn't find any versions"
- DEPENDENCY_NOT_FOUND =
": Not found"
- DEPENDENCY_MATCH_NOT_FOUND =
"Couldn't find match for"
- DEPENDENCY_NO_VERSION_FOUND =
"Couldn't find any versions"
- MANIFEST_NOT_FOUND =
Manifest not found
/Cannot read properties of undefined \(reading '(?<file>.*)'\)/
- NODE_MODULES_STATE_FILE_NOT_FOUND =
Used to identify error if node_modules state file not resolved
"Couldn't find the node_modules state file"
- YARN_USAGE_ERROR_TEXT =
Used to find error message in yarn error output
"Usage Error:"
- TARBALL_IS_NOT_IN_NETWORK =
Used to identify error if tarball is not in network
"Tarball is not in network and can not be located in cache"
- AUTHENTICATION_TOKEN_NOT_PROVIDED =
Used to identify if authentication failure error
"authentication token not provided"
- AUTHENTICATION_IS_NOT_CONFIGURED =
"No authentication configured for request"
- AUTHENTICATION_HEADER_NOT_PROVIDED =
"Unauthenticated: request did not include an Authorization header."
- DEPENDENCY_FILE_NOT_RESOLVABLE =
Used to identify if error message is related to yarn workspaces
"conflicts with direct dependency"
- ENV_VAR_NOT_RESOLVABLE =
/Failed to replace env in config: \$\{(?<var>.*)\}/
- OUT_OF_DISKSPACE =
/ Out of diskspace/
- YARNRC_PARSE_ERROR =
yarnrc.yml errors
/Parse error when loading (?<filename>.*?); /
- YARNRC_ENV_NOT_FOUND =
/Usage Error: Environment variable not found /
- YARNRC_ENV_NOT_FOUND_REGEX =
/Usage Error: Environment variable not found \((?<token>.*)\) in (?<filename>.*?) /
- YARNRC_EAI_AGAIN =
/getaddrinfo EAI_AGAIN/
- YARNRC_ENOENT =
/Internal Error: ENOENT/
- YARNRC_ENOENT_REGEX =
/Internal Error: ENOENT: no such file or directory, stat '(?<filename>.*?)'/
- YARN_PACKAGE_NOT_FOUND =
if not package found with specified version
/MessageError: Couldn't find any versions for "(?<pkg>.*?)" that matches "(?<ver>.*?)"/
- YN0001_FILE_NOT_RESOLVED_CODES =
T.let({ FIND_PACKAGE_LOCATION: /YN0001:(.*?)UsageError: Couldn't find the (?<pkg>.*) state file/, NO_CANDIDATE_FOUND: /YN0001:(.*?)Error: (?<pkg>.*): No candidates found/, NO_SUPPORTED_RESOLVER: /YN0001:(.*?)Error: (?<pkg>.*) isn't supported by any available resolver/, WORKSPACE_NOT_FOUND: /YN0001:(.*?)Error: (?<pkg>.*): Workspace not found/, ENOENT: /YN0001:(.*?)Thrown Error: (?<pkg>.*) ENOENT/, MANIFEST_NOT_FOUND: /YN0001:(.*?)Error: (?<pkg>.*): Manifest not found/, LIBZIP_ERROR: /YN0001:(.*?)Libzip Error: Failed to open the cache entry for (?<pkg>.*): Not a zip archive/ }.freeze, T::Hash[String, Regexp])
- YN0001_AUTH_ERROR_CODES =
T.let({ AUTH_ERROR: /YN0001:*.*Fatal Error: could not read Username for '(?<url>.*)': terminal prompts disabled/ }.freeze, T::Hash[String, Regexp])
- YN0001_REQ_NOT_FOUND_CODES =
T.let({ REQUIREMENT_NOT_SATISFIED: /provides (?<dep>.*)(.*?)with version (?<ver>.*), which doesn't satisfy what (?<pkg>.*) requests/, # rubocop:disable Layout/LineLength REQUIREMENT_NOT_PROVIDED: /(?<dep>.*)(.*?)doesn't provide (?<pkg>.*)(.*?), requested by (?<parent>.*)/ }.freeze, T::Hash[String, Regexp])
- REGISTRY_NOT_REACHABLE =
registry returns malformed response
/Received malformed response from registry for "(?<ver>.*)". The registry may be down./
- YARN_CODE_REGEX =
/(YN\d{4})/
- YARN_ERROR_CODES =
T.let({ "YN0001" => { message: "Exception error", handler: lambda { |, _error, _params| YN0001_FILE_NOT_RESOLVED_CODES.each do |(_yn0001_key, yn0001_regex)| if (msg = .match(yn0001_regex)) return Dependabot::DependencyFileNotResolvable.new(msg) end end YN0001_AUTH_ERROR_CODES.each do |(_yn0001_key, yn0001_regex)| if (msg = .match(yn0001_regex)) url = msg.named_captures.fetch(URL_CAPTURE) return Dependabot::PrivateSourceAuthenticationFailure.new(url) end end YN0001_REQ_NOT_FOUND_CODES.each do |(_yn0001_key, yn0001_regex)| if (msg = .match(yn0001_regex)) return Dependabot::DependencyFileNotResolvable.new(msg) end end Dependabot::DependabotError.new() } }, "YN0002" => { message: "Missing peer dependency", handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new() } }, "YN0009" => { message: "Build Failed", handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new() } }, "YN0016" => { message: "Remote not found", handler: lambda { |, _error, _params| Dependabot::GitDependenciesNotReachable.new() } }, "YN0020" => { message: "Missing lockfile entry", handler: lambda { |, _error, _params| Dependabot::DependencyFileNotFound.new() } }, "YN0035" => { message: "Package not found", handler: lambda { |, _error, _params| YN0035.each do |(_yn0035_key, yn0035_regex)| if (match_data = .match(yn0035_regex)) && (package_req = match_data[:package_req]) return Dependabot::DependencyNotFound.new( "#{package_req} Detail: #{}" ) end end Dependabot::DependencyNotFound.new() } }, "YN0041" => { message: "Invalid authentication", handler: lambda { |, _error, _params| url = T.must(URI.decode_www_form_component().split("https://").last).split("/").first Dependabot::PrivateSourceAuthenticationFailure.new(url) } }, "YN0046" => { message: "Automerge failed to parse", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0047" => { message: "Automerge immutable", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0062" => { message: "Incompatible OS", handler: lambda { |, _error, _params| Dependabot::DependabotError.new() } }, "YN0063" => { message: "Incompatible CPU", handler: lambda { |, _error, _params| Dependabot::IncompatibleCPU.new() } }, "YN0068" => { message: "No matching package", handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new() } }, "YN0071" => { message: "NM can't install external soft link", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0072" => { message: "NM preserve symlinks required", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0075" => { message: "Prolog instantiation error", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0077" => { message: "Ghost architecture", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0080" => { message: "Network disabled", handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) } }, "YN0081" => { message: "Network unsafe HTTP", handler: lambda { |, _error, _params| Dependabot::NetworkUnsafeHTTP.new() } }, "YN0082" => { message: "No candidates found", handler: lambda { |, _error, _params| match_data = .match(YN0082_PACKAGE_NOT_FOUND_REGEX) if match_data package_req = match_data[1] Dependabot::DependencyNotFound.new("#{package_req} Detail: #{}") else Dependabot::DependencyNotFound.new() end } } }.freeze, T::Hash[String, { message: T.any(String, NilClass), handler: ErrorHandler }])
- VALIDATION_GROUP_PATTERNS =
Group of patterns to validate error message and raise specific error
T.let([ { patterns: [INVALID_NAME_IN_PACKAGE_JSON], handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new() }, in_usage: false, matchfn: nil }, { # Check if sub dependency is using local path and raise a resolvability error patterns: [INVALID_PACKAGE_REGEX, SUB_DEP_LOCAL_PATH_TEXT], handler: lambda { |, _error, params| Dependabot::DependencyFileNotResolvable.new( Utils.( , params[:dependencies], params[:yarn_lock] ) ) }, in_usage: false, matchfn: nil }, { patterns: [NODE_MODULES_STATE_FILE_NOT_FOUND], handler: lambda { |, _error, _params| Dependabot::MisconfiguredTooling.new("Yarn", ) }, in_usage: true, matchfn: nil }, { patterns: [TARBALL_IS_NOT_IN_NETWORK], handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new() }, in_usage: false, matchfn: nil }, { patterns: [NODE_VERSION_NOT_SATISFY_REGEX], handler: lambda { |, _error, _params| versions = Utils.extract_node_versions() current_version = versions[:current_version] required_version = versions[:required_version] return Dependabot::DependabotError.new() unless current_version && required_version Dependabot::ToolVersionNotSupported.new("Yarn", current_version, required_version) }, in_usage: false, matchfn: nil }, { patterns: [AUTHENTICATION_TOKEN_NOT_PROVIDED, AUTHENTICATION_IS_NOT_CONFIGURED, AUTHENTICATION_HEADER_NOT_PROVIDED], handler: lambda { |, _error, _params| Dependabot::PrivateSourceAuthenticationFailure.new() }, in_usage: false, matchfn: nil }, { patterns: [DEPENDENCY_FILE_NOT_RESOLVABLE], handler: lambda { |, _error, _params| DependencyFileNotResolvable.new() }, in_usage: false, matchfn: nil }, { patterns: [ENV_VAR_NOT_RESOLVABLE], handler: lambda { |, _error, _params| var = Utils.extract_var() Dependabot::MissingEnvironmentVariable.new(var, ) }, in_usage: false, matchfn: nil }, { patterns: [ONLY_PRIVATE_WORKSPACE_TEXT], handler: lambda { |, _error, _params| Dependabot::DependencyFileNotEvaluatable.new() }, in_usage: false, matchfn: nil }, { patterns: [UNREACHABLE_GIT_CHECK_REGEX], handler: lambda { |, _error, _params| dependency_url = .match(UNREACHABLE_GIT_CHECK_REGEX).named_captures.fetch(URL_CAPTURE) Dependabot::GitDependenciesNotReachable.new(dependency_url) }, in_usage: false, matchfn: nil }, { patterns: [SOCKET_HANG_UP], handler: lambda { |, _error, _params| url = .match(SOCKET_HANG_UP).named_captures.fetch(URL_CAPTURE) Dependabot::PrivateSourceTimedOut.new(url.gsub(HTTP_CHECK_REGEX, "")) }, in_usage: false, matchfn: nil }, { patterns: [ESOCKETTIMEDOUT], handler: lambda { |, _error, _params| package_req = .match(ESOCKETTIMEDOUT).named_captures.fetch("package") Dependabot::PrivateSourceTimedOut.new(package_req.gsub(HTTP_CHECK_REGEX, "")) }, in_usage: false, matchfn: nil }, { patterns: [OUT_OF_DISKSPACE], handler: lambda { |, _error, _params| Dependabot::OutOfDisk.new() }, in_usage: false, matchfn: nil }, { patterns: [YARNRC_PARSE_ERROR], handler: lambda { |, _error, _params| filename = .match(YARNRC_PARSE_ERROR).named_captures["filename"] msg = "Error while loading \"#{filename.split('/').last}\"." Dependabot::DependencyFileNotResolvable.new(msg) }, in_usage: false, matchfn: nil }, { patterns: [YARNRC_ENV_NOT_FOUND], handler: lambda { |, _error, _params| = .gsub(/[[:space:]]+/, " ").strip filename = .match(YARNRC_ENV_NOT_FOUND_REGEX) .named_captures["filename"] env_var = .match(YARNRC_ENV_NOT_FOUND_REGEX) .named_captures["token"] msg = "Environment variable \"#{env_var}\" not found in \"#{filename.split('/').last}\"." Dependabot::MissingEnvironmentVariable.new(env_var, msg) }, in_usage: false, matchfn: nil }, { patterns: [YARNRC_EAI_AGAIN], handler: lambda { |, _error, _params| Dependabot::DependencyFileNotResolvable.new("Network error while resolving dependency.") }, in_usage: false, matchfn: nil }, { patterns: [YARNRC_ENOENT], handler: lambda { |, _error, _params| = .gsub(/[[:space:]]+/, " ").strip filename = .match(YARNRC_ENOENT_REGEX).named_captures["filename"] Dependabot::DependencyFileNotResolvable.new("Internal error while resolving dependency." \ "File not found \"#{filename.split('/').last}\"") }, in_usage: false, matchfn: nil }, { patterns: [YARN_PACKAGE_NOT_FOUND], handler: lambda { |, _error, _params| package_name = .match(YARN_PACKAGE_NOT_FOUND).named_captures["pkg"] version = .match(YARN_PACKAGE_NOT_FOUND).named_captures["ver"] Dependabot::InconsistentRegistryResponse.new("Couldn't find any versions for \"#{package_name}\" that " \ "matches \"#{version}\"") }, in_usage: false, matchfn: nil }, { patterns: [YARN_PACKAGE_NOT_FOUND_CODE, YARN_PACKAGE_NOT_FOUND_CODE_1, YARN_PACKAGE_NOT_FOUND_CODE_2], handler: lambda { |, _error, _params| msg = .match(YARN_PACKAGE_NOT_FOUND_CODE) || .match(YARN_PACKAGE_NOT_FOUND_CODE_1) || .match(YARN_PACKAGE_NOT_FOUND_CODE_2) Dependabot::DependencyFileNotResolvable.new(msg) }, in_usage: false, matchfn: nil }, { patterns: [REQUEST_ERROR_E403, AUTH_REQUIRED_ERROR, PERMISSION_DENIED, BAD_REQUEST], handler: lambda { |, _error, _params| dependency_url = T.must(URI.decode_www_form_component().split("https://").last).split("/").first Dependabot::PrivateSourceAuthenticationFailure.new(dependency_url) }, in_usage: false, matchfn: nil }, { patterns: [MANIFEST_NOT_FOUND], handler: lambda { |, _error, _params| msg = .match(MANIFEST_NOT_FOUND) Dependabot::DependencyFileNotResolvable.new(msg) }, in_usage: false, matchfn: nil }, { patterns: [INTERNAL_SERVER_ERROR], handler: lambda { |, _error, _params| msg = .match(INTERNAL_SERVER_ERROR) Dependabot::DependencyFileNotResolvable.new(msg) }, in_usage: false, matchfn: nil }, { patterns: [REGISTRY_NOT_REACHABLE], handler: lambda { |, _error, _params| msg = .match(REGISTRY_NOT_REACHABLE) Dependabot::DependencyFileNotResolvable.new(msg) }, in_usage: false, matchfn: nil } ].freeze, T::Array[{ patterns: T::Array[T.any(String, Regexp)], handler: ErrorHandler, in_usage: T.nilable(T::Boolean), matchfn: T.nilable(T.proc.params(usage: String, message: String).returns(T::Boolean)) }])