@csaf-rs/vers-like-specifier 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -14
- package/package.json +2 -2
- package/vers_like_specifier.d.ts +55 -32
- package/vers_like_specifier.js +56 -29
- package/vers_like_specifier_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
[](https://crates.io/crates/vers-like-specifier)
|
|
4
4
|
[](https://www.npmjs.com/package/@csaf-rs/vers-like-specifier)
|
|
5
5
|
|
|
6
|
-
A Rust library for parsing and validating **
|
|
6
|
+
A Rust library for parsing and validating **VERS-like Specifiers** (vls) as defined in [CSAF 2.0](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#31232-branches-type---name-under-product-version-range) and [CSAF 2.1](https://docs.oasis-open.org/csaf/csaf/v2.1/csaf-v2.1.html#branches-type---name-under-product-version-range).
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
VERS-like specifier is the `<constraints>` portion of a [VERS](https://github.com/package-url/vers-spec) URL **without** the `vers:<type>/` prefix.
|
|
9
9
|
|
|
10
10
|
It represents a `|`-separated list of constraints each consisting of an implicit or explicit comparator and a version string.
|
|
11
11
|
|
|
12
|
-
**Due to the undefined / unknown
|
|
12
|
+
**Due to the undefined / unknown VERS type, it is nearly impossible for tools to reliably determine whether a given version is in the range or not. vls is a fallback option and SHOULD NOT be used unless really necessary.**
|
|
13
13
|
|
|
14
14
|
## Minimum Supported Rust Version (MSRV)
|
|
15
15
|
|
|
@@ -21,13 +21,13 @@ Add `vers-like-specifier` to your `Cargo.toml`. The package is published on http
|
|
|
21
21
|
|
|
22
22
|
```toml
|
|
23
23
|
[dependencies]
|
|
24
|
-
vers-like-specifier = "0.
|
|
24
|
+
vers-like-specifier = "0.2"
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Usage
|
|
28
28
|
|
|
29
29
|
```rust
|
|
30
|
-
use vers_like_specifier::{Vls, Comparator};
|
|
30
|
+
use vers_like_specifier::{Vls, Comparator, Containment};
|
|
31
31
|
|
|
32
32
|
let vls: Vls = ">=1.0.0|<2.0.0".parse().unwrap();
|
|
33
33
|
assert_eq!(vls.constraints().len(), 2);
|
|
@@ -35,32 +35,45 @@ assert_eq!(vls.to_string(), ">=1.0.0|<2.0.0");
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
let constraints = vls.constraints();
|
|
38
|
-
assert_eq!(constraints[0].comparator(),
|
|
38
|
+
assert_eq!(constraints[0].comparator(), Comparator::GreaterThanOrEqual);
|
|
39
39
|
assert_eq!(constraints[0].version().to_string(), "1.0.0");
|
|
40
|
-
assert_eq!(constraints[1].comparator(),
|
|
40
|
+
assert_eq!(constraints[1].comparator(), Comparator::LessThan);
|
|
41
41
|
assert_eq!(constraints[1].version().to_string(), "2.0.0");
|
|
42
|
+
|
|
43
|
+
// Because the VERS type is unknown, `contains` can only resolve a definite
|
|
44
|
+
// answer when a version exactly matches a constraint; otherwise it is `Undetermined`.
|
|
45
|
+
assert_eq!(vls.contains("1.0.0"), Containment::Contained);
|
|
46
|
+
assert_eq!(vls.contains("2.0.0"), Containment::NotContained);
|
|
47
|
+
assert_eq!(vls.contains("1.5.0"), Containment::Undetermined);
|
|
48
|
+
|
|
49
|
+
// The one exception: a vls containing only exact-match comparators (equal, not equal) is always decidable, since
|
|
50
|
+
// containment then reduces to a plain string comparison if there is a constraint with that version. If there isn't a
|
|
51
|
+
// constraint with the version, it is not contained by default.
|
|
52
|
+
let exact_only: Vls = "1.0.0|!=2.0.0".parse().unwrap();
|
|
53
|
+
assert_eq!(exact_only.contains("1.0.0"), Containment::Contained);
|
|
54
|
+
assert_eq!(exact_only.contains("2.0.0"), Containment::NotContained);
|
|
55
|
+
assert_eq!(exact_only.contains("3.0.0"), Containment::NotContained);
|
|
42
56
|
```
|
|
43
57
|
|
|
44
58
|
### JavaScript / WASM Usage
|
|
45
59
|
|
|
46
60
|
```js
|
|
47
|
-
import init, { Vls, Constraint, Comparator } from "@csaf-rs/vers-like-specifier";
|
|
61
|
+
import init, { Vls, Constraint, Comparator, Containment } from "@csaf-rs/vers-like-specifier";
|
|
48
62
|
|
|
49
63
|
await init();
|
|
50
64
|
|
|
51
65
|
const vls = Vls.parse(">=1.0.0|<2.0.0");
|
|
52
|
-
console.log(vls.isSingleVersion()); // false
|
|
53
|
-
|
|
54
|
-
const single = Vls.parse("=1.0.0");
|
|
55
|
-
console.log(single.isSingleVersion()); // true
|
|
56
|
-
|
|
57
66
|
const constraint = new Constraint(Comparator.GreaterThanOrEqual, "1.0.0");
|
|
58
67
|
console.log(constraint.version); // "1.0.0"
|
|
59
68
|
|
|
69
|
+
console.log(vls.contains("1.0.0") === Containment.Contained); // true (matches the >= constraint exactly)
|
|
70
|
+
console.log(vls.contains("2.0.0") === Containment.NotContained); // true (2.0.0 < 2.0.0 is always false)
|
|
71
|
+
console.log(vls.contains("1.5.0") === Containment.Undetermined); // true (can't be resolved; VERS type is unknown)
|
|
72
|
+
|
|
60
73
|
try {
|
|
61
74
|
Vls.parse("*");
|
|
62
75
|
} catch (e) {
|
|
63
|
-
console.error(e); // Error: '*' (
|
|
76
|
+
console.error(e); // Error: '*' (VERS syntax for matching all versions) is not allowed as a vls string
|
|
64
77
|
}
|
|
65
78
|
```
|
|
66
79
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@csaf-rs/vers-like-specifier",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"description": "vls (
|
|
5
|
-
"version": "0.
|
|
4
|
+
"description": "vls (VERS-like specifier) parser",
|
|
5
|
+
"version": "0.2.0",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/vers_like_specifier.d.ts
CHANGED
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
export type VersionString = string;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Errors specific to a single constraint within a
|
|
12
|
+
* Errors specific to a single constraint within a vls string.
|
|
13
13
|
*/
|
|
14
14
|
export type ConstraintError = "EmptyConstraint" | "EmptyConstraintVersion" | { InvalidConstraintVersionCharacters: string[] };
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Errors that can occur when parsing a vls string.
|
|
18
18
|
*/
|
|
19
|
-
export type VlsError = "EmptyInput" | "ForbiddenAnyUsed" | {
|
|
19
|
+
export type VlsError = "EmptyInput" | "ForbiddenAnyUsed" | { SingleVersionNotAllowed: string } | { InvalidCharacters: string[] } | { InvalidConstraints: ConstraintError[] } | { DuplicateConstraintVersions: string[] } | { Serialization: string };
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -61,7 +61,7 @@ export class Constraint {
|
|
|
61
61
|
[Symbol.dispose](): void;
|
|
62
62
|
/**
|
|
63
63
|
* Construct a new [`Constraint`] from a [`Comparator`] and a version string, validating
|
|
64
|
-
* the version string against the
|
|
64
|
+
* the version string against the vls grammar. Exposed as `new Constraint(comparator, version)`
|
|
65
65
|
* in JS.
|
|
66
66
|
*
|
|
67
67
|
* # Errors
|
|
@@ -79,9 +79,48 @@ export class Constraint {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
82
|
+
* The result of a containment check performed by [`Vls::contains`].
|
|
83
|
+
*
|
|
84
|
+
* Because the VERS type of a [`Vls`] is unspecified, containment can usually only be
|
|
85
|
+
* resolved when the queried version exactly matches a constraint's version:
|
|
86
|
+
*
|
|
87
|
+
* * [`Comparator::Equal`], [`Comparator::GreaterThanOrEqual`], [`Comparator::LessThanOrEqual`]:
|
|
88
|
+
* an exact match means the version is contained (`x = x`, `x >= x`, `x <= x` all hold) →
|
|
89
|
+
* [`Containment::Contained`].
|
|
90
|
+
* * [`Comparator::NotEqual`], [`Comparator::LessThan`], [`Comparator::GreaterThan`]:
|
|
91
|
+
* an exact match means the version is explicitly not contained (`x != x`, `x < x`, `x > x`
|
|
92
|
+
* are always false) → [`Containment::NotContained`].
|
|
93
|
+
* * No constraint's version matches exactly: containment cannot be resolved, as the VERS
|
|
94
|
+
* type is unknown / unspecified → [`Containment::Undetermined`].
|
|
95
|
+
*
|
|
96
|
+
* The one exception is a [`Vls`] that uses only exact-match comparators (i.e.
|
|
97
|
+
* [`Comparator::Equal`] and/or [`Comparator::NotEqual`]).
|
|
98
|
+
* Here, containment is reduced to a plain string comparison and is always decidable,
|
|
99
|
+
* regardless of VERS type. In that case, *any* queried version resolves to either [`Containment::Contained`] or
|
|
100
|
+
* [`Containment::NotContained`] depending on the exact-match comparator if there is a constraint with
|
|
101
|
+
* the queried version, and always to [`Containment::NotContained`] if there is no constraint with that version.
|
|
102
|
+
*/
|
|
103
|
+
export enum Containment {
|
|
104
|
+
/**
|
|
105
|
+
* The version is contained in the specifier.
|
|
106
|
+
*/
|
|
107
|
+
Contained = 0,
|
|
108
|
+
/**
|
|
109
|
+
* The version is explicitly not contained in the specifier.
|
|
110
|
+
*/
|
|
111
|
+
NotContained = 1,
|
|
112
|
+
/**
|
|
113
|
+
* Containment could not be determined: the version does not exactly match any
|
|
114
|
+
* constraint, and the (unspecified) VERS type does not allow any further
|
|
115
|
+
* comparison.
|
|
116
|
+
*/
|
|
117
|
+
Undetermined = 2,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A **VERS-like specifier** (vls).
|
|
83
122
|
*
|
|
84
|
-
*
|
|
123
|
+
* vls is the `<constraints>` part of a [VERS](https://github.com/package-url/vers-spec)
|
|
85
124
|
* URL *without* the `vers:<type>/` prefix.
|
|
86
125
|
*
|
|
87
126
|
* It is an ordered, `|`-separated list of [`Constraint`] values.
|
|
@@ -93,30 +132,14 @@ export class Constraint {
|
|
|
93
132
|
*
|
|
94
133
|
* # Syntax
|
|
95
134
|
*
|
|
96
|
-
* Derived from the [
|
|
135
|
+
* Derived from the [VERS specification](https://www.packageurl.org/docs/vers/how-to-parse),
|
|
97
136
|
* its comments in
|
|
98
137
|
* [CSAF 2.0](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#31232-branches-type---name-under-product-version-range)
|
|
99
138
|
* and
|
|
100
139
|
* [CSAF 2.1](https://docs.oasis-open.org/csaf/csaf/v2.1/csaf-v2.1.html#branches-type---name-under-product-version-range).
|
|
101
140
|
*
|
|
102
|
-
* There currently is no "official" grammar for
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* **Note:** This grammar may need to be updated once vers has been ratified through ECMA / following changes
|
|
106
|
-
* to / clarifications of CSAF 2.0 or CSAF 2.1.
|
|
107
|
-
*
|
|
108
|
-
* ```text
|
|
109
|
-
* vls = constraint *( "|" constraint )
|
|
110
|
-
* constraint = comparator version-string / version-string
|
|
111
|
-
* comparator = "!=" / "<=" / ">=" / "<" / ">"
|
|
112
|
-
* version-string = 1*( ALPHA / DIGIT / "-" / "." / "_" / "+" / "~" )
|
|
113
|
-
* ```
|
|
114
|
-
*
|
|
115
|
-
* For validation, this leads to two sets of characters allowed in the context of the grammar.
|
|
116
|
-
*
|
|
117
|
-
* For `constraints`: `ALPHA / DIGIT / "-" / "." / "_" / "+" / "~" / "=" / "!" / "<" / ">" / "|"`
|
|
118
|
-
*
|
|
119
|
-
* For `version-string`: `ALPHA / DIGIT / "-" / "." / "_" / "+" / "~"`
|
|
141
|
+
* There currently is no "official" grammar for VERS-like specifier / the `<constraints>` part of
|
|
142
|
+
* VERS. This is a best-effort attempt used for this library.
|
|
120
143
|
*
|
|
121
144
|
* # Examples
|
|
122
145
|
*
|
|
@@ -136,15 +159,15 @@ export class Vls {
|
|
|
136
159
|
free(): void;
|
|
137
160
|
[Symbol.dispose](): void;
|
|
138
161
|
/**
|
|
139
|
-
* Return `
|
|
140
|
-
* instance method `vls.
|
|
162
|
+
* Return the [`Containment`] of the given `version` in this specifier, exposed as the
|
|
163
|
+
* instance method `vls.contains(version)` in JS.
|
|
141
164
|
*/
|
|
142
|
-
|
|
165
|
+
contains(version: string): Containment;
|
|
143
166
|
/**
|
|
144
167
|
* Parse a `vls` as a [`Vls`] string, exposed as the static `Vls.parse(vls)` in JS.
|
|
145
168
|
*
|
|
146
169
|
* # Errors
|
|
147
|
-
* Throws a JS `Error` if `vls` is not a valid
|
|
170
|
+
* Throws a JS `Error` if `vls` is not a valid VERS-like specifier.
|
|
148
171
|
*/
|
|
149
172
|
static parse(vls: string): Vls;
|
|
150
173
|
}
|
|
@@ -158,14 +181,14 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|
|
158
181
|
|
|
159
182
|
export interface InitOutput {
|
|
160
183
|
readonly memory: WebAssembly.Memory;
|
|
161
|
-
readonly
|
|
184
|
+
readonly init: () => void;
|
|
162
185
|
readonly __wbg_vls_free: (a: number, b: number) => void;
|
|
186
|
+
readonly vls_contains: (a: number, b: number, c: number) => number;
|
|
187
|
+
readonly vls_parse: (a: number, b: number) => [number, number, number];
|
|
188
|
+
readonly __wbg_constraint_free: (a: number, b: number) => void;
|
|
163
189
|
readonly constraint_comparator: (a: number) => number;
|
|
164
190
|
readonly constraint_version: (a: number) => [number, number];
|
|
165
191
|
readonly constraint_wasm_new: (a: number, b: number, c: number) => [number, number, number];
|
|
166
|
-
readonly vls_isSingleVersion: (a: number) => number;
|
|
167
|
-
readonly vls_parse: (a: number, b: number) => [number, number, number];
|
|
168
|
-
readonly init: () => void;
|
|
169
192
|
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
170
193
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
171
194
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
package/vers_like_specifier.js
CHANGED
|
@@ -75,7 +75,7 @@ export class Constraint {
|
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Construct a new [`Constraint`] from a [`Comparator`] and a version string, validating
|
|
78
|
-
* the version string against the
|
|
78
|
+
* the version string against the vls grammar. Exposed as `new Constraint(comparator, version)`
|
|
79
79
|
* in JS.
|
|
80
80
|
*
|
|
81
81
|
* # Errors
|
|
@@ -98,9 +98,49 @@ export class Constraint {
|
|
|
98
98
|
if (Symbol.dispose) Constraint.prototype[Symbol.dispose] = Constraint.prototype.free;
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
101
|
+
* The result of a containment check performed by [`Vls::contains`].
|
|
102
102
|
*
|
|
103
|
-
*
|
|
103
|
+
* Because the VERS type of a [`Vls`] is unspecified, containment can usually only be
|
|
104
|
+
* resolved when the queried version exactly matches a constraint's version:
|
|
105
|
+
*
|
|
106
|
+
* * [`Comparator::Equal`], [`Comparator::GreaterThanOrEqual`], [`Comparator::LessThanOrEqual`]:
|
|
107
|
+
* an exact match means the version is contained (`x = x`, `x >= x`, `x <= x` all hold) →
|
|
108
|
+
* [`Containment::Contained`].
|
|
109
|
+
* * [`Comparator::NotEqual`], [`Comparator::LessThan`], [`Comparator::GreaterThan`]:
|
|
110
|
+
* an exact match means the version is explicitly not contained (`x != x`, `x < x`, `x > x`
|
|
111
|
+
* are always false) → [`Containment::NotContained`].
|
|
112
|
+
* * No constraint's version matches exactly: containment cannot be resolved, as the VERS
|
|
113
|
+
* type is unknown / unspecified → [`Containment::Undetermined`].
|
|
114
|
+
*
|
|
115
|
+
* The one exception is a [`Vls`] that uses only exact-match comparators (i.e.
|
|
116
|
+
* [`Comparator::Equal`] and/or [`Comparator::NotEqual`]).
|
|
117
|
+
* Here, containment is reduced to a plain string comparison and is always decidable,
|
|
118
|
+
* regardless of VERS type. In that case, *any* queried version resolves to either [`Containment::Contained`] or
|
|
119
|
+
* [`Containment::NotContained`] depending on the exact-match comparator if there is a constraint with
|
|
120
|
+
* the queried version, and always to [`Containment::NotContained`] if there is no constraint with that version.
|
|
121
|
+
* @enum {0 | 1 | 2}
|
|
122
|
+
*/
|
|
123
|
+
export const Containment = Object.freeze({
|
|
124
|
+
/**
|
|
125
|
+
* The version is contained in the specifier.
|
|
126
|
+
*/
|
|
127
|
+
Contained: 0, "0": "Contained",
|
|
128
|
+
/**
|
|
129
|
+
* The version is explicitly not contained in the specifier.
|
|
130
|
+
*/
|
|
131
|
+
NotContained: 1, "1": "NotContained",
|
|
132
|
+
/**
|
|
133
|
+
* Containment could not be determined: the version does not exactly match any
|
|
134
|
+
* constraint, and the (unspecified) VERS type does not allow any further
|
|
135
|
+
* comparison.
|
|
136
|
+
*/
|
|
137
|
+
Undetermined: 2, "2": "Undetermined",
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A **VERS-like specifier** (vls).
|
|
142
|
+
*
|
|
143
|
+
* vls is the `<constraints>` part of a [VERS](https://github.com/package-url/vers-spec)
|
|
104
144
|
* URL *without* the `vers:<type>/` prefix.
|
|
105
145
|
*
|
|
106
146
|
* It is an ordered, `|`-separated list of [`Constraint`] values.
|
|
@@ -112,30 +152,14 @@ if (Symbol.dispose) Constraint.prototype[Symbol.dispose] = Constraint.prototype.
|
|
|
112
152
|
*
|
|
113
153
|
* # Syntax
|
|
114
154
|
*
|
|
115
|
-
* Derived from the [
|
|
155
|
+
* Derived from the [VERS specification](https://www.packageurl.org/docs/vers/how-to-parse),
|
|
116
156
|
* its comments in
|
|
117
157
|
* [CSAF 2.0](https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#31232-branches-type---name-under-product-version-range)
|
|
118
158
|
* and
|
|
119
159
|
* [CSAF 2.1](https://docs.oasis-open.org/csaf/csaf/v2.1/csaf-v2.1.html#branches-type---name-under-product-version-range).
|
|
120
160
|
*
|
|
121
|
-
* There currently is no "official" grammar for
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* **Note:** This grammar may need to be updated once vers has been ratified through ECMA / following changes
|
|
125
|
-
* to / clarifications of CSAF 2.0 or CSAF 2.1.
|
|
126
|
-
*
|
|
127
|
-
* ```text
|
|
128
|
-
* vls = constraint *( "|" constraint )
|
|
129
|
-
* constraint = comparator version-string / version-string
|
|
130
|
-
* comparator = "!=" / "<=" / ">=" / "<" / ">"
|
|
131
|
-
* version-string = 1*( ALPHA / DIGIT / "-" / "." / "_" / "+" / "~" )
|
|
132
|
-
* ```
|
|
133
|
-
*
|
|
134
|
-
* For validation, this leads to two sets of characters allowed in the context of the grammar.
|
|
135
|
-
*
|
|
136
|
-
* For `constraints`: `ALPHA / DIGIT / "-" / "." / "_" / "+" / "~" / "=" / "!" / "<" / ">" / "|"`
|
|
137
|
-
*
|
|
138
|
-
* For `version-string`: `ALPHA / DIGIT / "-" / "." / "_" / "+" / "~"`
|
|
161
|
+
* There currently is no "official" grammar for VERS-like specifier / the `<constraints>` part of
|
|
162
|
+
* VERS. This is a best-effort attempt used for this library.
|
|
139
163
|
*
|
|
140
164
|
* # Examples
|
|
141
165
|
*
|
|
@@ -169,19 +193,22 @@ export class Vls {
|
|
|
169
193
|
wasm.__wbg_vls_free(ptr, 0);
|
|
170
194
|
}
|
|
171
195
|
/**
|
|
172
|
-
* Return `
|
|
173
|
-
* instance method `vls.
|
|
174
|
-
* @
|
|
196
|
+
* Return the [`Containment`] of the given `version` in this specifier, exposed as the
|
|
197
|
+
* instance method `vls.contains(version)` in JS.
|
|
198
|
+
* @param {string} version
|
|
199
|
+
* @returns {Containment}
|
|
175
200
|
*/
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
201
|
+
contains(version) {
|
|
202
|
+
const ptr0 = passStringToWasm0(version, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
203
|
+
const len0 = WASM_VECTOR_LEN;
|
|
204
|
+
const ret = wasm.vls_contains(this.__wbg_ptr, ptr0, len0);
|
|
205
|
+
return ret;
|
|
179
206
|
}
|
|
180
207
|
/**
|
|
181
208
|
* Parse a `vls` as a [`Vls`] string, exposed as the static `Vls.parse(vls)` in JS.
|
|
182
209
|
*
|
|
183
210
|
* # Errors
|
|
184
|
-
* Throws a JS `Error` if `vls` is not a valid
|
|
211
|
+
* Throws a JS `Error` if `vls` is not a valid VERS-like specifier.
|
|
185
212
|
* @param {string} vls
|
|
186
213
|
* @returns {Vls}
|
|
187
214
|
*/
|
|
Binary file
|