@@ -223,6 +223,40 @@ def from_osv_v1(data, scheme):
223223 """
224224
225225
226+ def get_allof_constraints (cls , clause ):
227+ """
228+ Return a list of VersionConstraint given an AllOf ``clause``.
229+ """
230+ if not isinstance (clause , AllOf ):
231+ raise ValueError (f"Unknown clause type: { clause !r} " )
232+ allof_constraints = []
233+ for constraint in clause .clauses :
234+ comparator = cls .vers_by_native_comparators [constraint .operator ]
235+ version = cls .version_class (str (constraint .target ))
236+ constraint = VersionConstraint (comparator = comparator , version = version )
237+ allof_constraints .append (constraint )
238+ return allof_constraints
239+
240+
241+ def get_npm_version_constraints_from_semver_npm_spec (string , cls ):
242+ """
243+ Return a VersionConstraint for the provided ``string``.
244+ """
245+ spec = semantic_version .NpmSpec (string )
246+ clause = spec .clause .simplify ()
247+ if isinstance (clause , (AnyOf , AllOf )):
248+ anyof_constraints = []
249+ if isinstance (clause , AnyOf ):
250+ for allof_clause in clause .clauses :
251+ anyof_constraints .extend (get_allof_constraints (cls , allof_clause ))
252+ elif isinstance (clause , AllOf ):
253+ alloc = get_allof_constraints (cls , clause )
254+ anyof_constraints .extend (alloc )
255+ else :
256+ raise ValueError (f"Unknown clause type: { spec !r} " )
257+ return anyof_constraints
258+
259+
226260class NpmVersionRange (VersionRange ):
227261 scheme = "npm"
228262 version_class = versions .SemverVersion
@@ -245,35 +279,71 @@ def from_native(cls, string):
245279
246280 # an NpmSpec handles parsing of both the semver versions and node-semver
247281 # ranges at once
248- spec = semantic_version .NpmSpec (string )
249-
250- clause = spec .clause .simplify ()
251- assert isinstance (clause , (AnyOf , AllOf ))
252- anyof_constraints = []
253- if isinstance (clause , AnyOf ):
254- for allof_clause in clause .clauses :
255- anyof_constraints .extend (get_allof_constraints (cls , allof_clause ))
256- elif isinstance (clause , AllOf ):
257- alloc = get_allof_constraints (cls , clause )
258- anyof_constraints .extend (alloc )
259- else :
260- raise ValueError (f"Unknown clause type: { spec !r} " )
261-
262- return cls (constraints = anyof_constraints )
263282
283+ if string == "*" :
284+ return cls (
285+ constraints = [
286+ VersionConstraint .from_string (string = "*" , version_class = cls .version_class )
287+ ]
288+ )
264289
265- def get_allof_constraints (cls , clause ):
266- """
267- Return a list of VersionConstraint given an AllOf ``clause``.
268- """
269- assert isinstance (clause , AllOf )
270- allof_constraints = []
271- for constraint in clause .clauses :
272- comparator = cls .vers_by_native_comparators [constraint .operator ]
273- version = cls .version_class (str (constraint .target ))
274- constraint = VersionConstraint (comparator = comparator , version = version )
275- allof_constraints .append (constraint )
276- return allof_constraints
290+ constraints = []
291+ vrc = cls .version_class
292+ # A constraint item can be a comparator or a version or a version with comparator
293+ # If it's empty continue
294+ # If it's in `vers_by_native_comparators`, append it with the comparator and continue
295+ # If it's a version, make version constraint from the version and use the comparator from the previous item and make comparator empty
296+ # If it's a version with comparator, use split_req to get version and comparator to form constraint and make comparator empty
297+
298+ for range in string .split ("||" ):
299+ if " - " in range :
300+ constraints .extend (
301+ get_npm_version_constraints_from_semver_npm_spec (string = range , cls = cls )
302+ )
303+ continue
304+ comparator = ""
305+ for constraint in range .split ():
306+ cmp = "" .join ([comparator , constraint ])
307+ if cmp in cls .vers_by_native_comparators :
308+ comparator = cls .vers_by_native_comparators [cmp ]
309+ continue
310+ if comparator :
311+ if constraint .endswith (".x" ):
312+ constraints .extend (
313+ get_npm_version_constraints_from_semver_npm_spec (
314+ string = constraint , cls = cls
315+ )
316+ )
317+ else :
318+ constraint = constraint .lstrip ("vV" )
319+ constraints .append (
320+ VersionConstraint (comparator = comparator , version = vrc (constraint ))
321+ )
322+ else :
323+ if (
324+ constraint .endswith (".x" )
325+ or constraint .startswith ("~" )
326+ or constraint .startswith ("^" )
327+ ):
328+ constraints .extend (
329+ get_npm_version_constraints_from_semver_npm_spec (
330+ string = constraint , cls = cls
331+ )
332+ )
333+ else :
334+ comparator , version_constraint = split_req (
335+ string = constraint ,
336+ comparators = cls .vers_by_native_comparators ,
337+ default = "=" ,
338+ )
339+ version_constraint = version_constraint .lstrip ("vV" )
340+ constraints .append (
341+ VersionConstraint (
342+ comparator = comparator , version = vrc (version_constraint )
343+ )
344+ )
345+ comparator = ""
346+ return cls (constraints = constraints )
277347
278348
279349class GemVersionRange (VersionRange ):
0 commit comments