forked from denoland/std
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse.ts
80 lines (70 loc) · 2.02 KB
/
parse.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import { SemVer } from "./types.ts";
import { isValidNumber } from "./_shared.ts";
import { isSemVer } from "./is_semver.ts";
import { FULL, MAX_LENGTH, NUMERICIDENTIFIER, re, src } from "./_shared.ts";
/**
* Attempt to parse a string as a semantic version, returning either a `SemVer`
* object or throws a TypeError.
* @param version The version string to parse
* @returns A valid SemVer
*/
export function parse(version: string | SemVer): SemVer {
if (typeof version === "object") {
if (isSemVer(version)) {
return version;
} else {
throw new TypeError(`not a valid SemVer object`);
}
}
if (typeof version !== "string") {
throw new TypeError(
`version must be a string`,
);
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`,
);
}
version = version.trim();
const r = re[FULL];
const m = version.match(r);
if (!m) {
throw new TypeError(`Invalid Version: ${version}`);
}
// these are actually numbers
const major = parseInt(m[1]);
const minor = parseInt(m[2]);
const patch = parseInt(m[3]);
if (major > Number.MAX_SAFE_INTEGER || major < 0) {
throw new TypeError("Invalid major version");
}
if (minor > Number.MAX_SAFE_INTEGER || minor < 0) {
throw new TypeError("Invalid minor version");
}
if (patch > Number.MAX_SAFE_INTEGER || patch < 0) {
throw new TypeError("Invalid patch version");
}
// number-ify any prerelease numeric ids
const numericIdentifier = new RegExp(`^(${src[NUMERICIDENTIFIER]})$`);
const prerelease = (m[4] ?? "")
.split(".")
.filter((id) => id)
.map((id: string) => {
const num = parseInt(id);
if (id.match(numericIdentifier) && isValidNumber(num)) {
return num;
} else {
return id;
}
});
const build = m[5]?.split(".")?.filter((m) => m) ?? [];
return {
major,
minor,
patch,
prerelease,
build,
};
}