Class: Dependabot::NpmAndYarn::PackageName

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/npm_and_yarn/package_name.rb

Defined Under Namespace

Classes: InvalidPackageName

Constant Summary collapse

PACKAGE_NAME_REGEX =

NPM package naming rules are defined by the following projects:

%r{
  \A                                          # beginning of string
  (?=.{1,214}\z)                              # enforce length (1 - 214)
  (@(?<scope>                                 # capture 'scope' if present
    [a-z0-9\-\_\.\!\~\*\'\(\)]+               # URL-safe characters in scope
  )\/)?                                       # scope must be followed by slash
  (?<name>                                    # capture package name
    (?(<scope>)                               # if scope is present
      [a-z0-9\-\_\.\!\~\*\'\(\)]+             # scoped names can start with any URL-safe character
    |                                         # if no scope
      [a-z0-9\-\!\~\*\'\(\)]                  # non-scoped names cannot start with . or _
      [a-z0-9\-\_\.\!\~\*\'\(\)]*             # subsequent characters can be any URL-safe character
    )
  )
  \z                                          # end of string
}xi
TYPES_PACKAGE_NAME_REGEX =

multi-line/case-insensitive

%r{
    \A                                          # beginning of string
    @types\/                                    # starts with @types/
    ((?<scope>.+)__)?                           # capture scope
    (?<name>.+)                                 # capture name
    \z                                          # end of string
}xi

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ PackageName

Returns a new instance of PackageName.

Raises:



42
43
44
45
46
47
48
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 42

def initialize(string)
  match = PACKAGE_NAME_REGEX.match(string.to_s)
  raise InvalidPackageName unless match

  @scope = T.let(match[:scope], T.nilable(String))
  @name = T.let(match[:name], T.nilable(String))
end

Instance Method Details

#<=>(other) ⇒ Object



70
71
72
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 70

def <=>(other)
  to_s.casecmp(other.to_s)
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 60

def eql?(other)
  self.class == other.class && to_s == other.to_s
end

#hashObject



65
66
67
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 65

def hash
  to_s.downcase.hash
end

#library_nameObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 75

def library_name
  return unless types_package?
  return @library_name if defined?(@library_name)

  lib_name =
    begin
      match = T.must(TYPES_PACKAGE_NAME_REGEX.match(to_s))
      if match[:scope]
        self.class.new("@#{match[:scope]}/#{match[:name]}")
      else
        self.class.new(match[:name].to_s)
      end
    end

  @library_name ||= T.let(lib_name, T.nilable(PackageName))
end

#to_sObject



51
52
53
54
55
56
57
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 51

def to_s
  if scoped?
    "@#{@scope}/#{@name}"
  else
    @name.to_s
  end
end

#types_package_nameObject



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/dependabot/npm_and_yarn/package_name.rb', line 93

def types_package_name
  return if types_package?

  @types_package_name ||= T.let(
    if scoped?
      self.class.new("@types/#{@scope}__#{@name}")
    else
      self.class.new("@types/#{@name}")
    end, T.nilable(PackageName)
  )
end