@guanghechen/version 1.0.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 +168 -0
- package/lib/cjs/index.cjs +322 -0
- package/lib/esm/index.mjs +313 -0
- package/lib/types/index.d.ts +41 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<h1 align="center">
|
|
3
|
+
<a href="https://github.com/guanghechen/sora/tree/@guanghechen/version@1.0.0/packages/version#readme">@guanghechen/version</a>
|
|
4
|
+
</h1>
|
|
5
|
+
<div align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@guanghechen/version">
|
|
7
|
+
<img
|
|
8
|
+
alt="Npm Version"
|
|
9
|
+
src="https://img.shields.io/npm/v/@guanghechen/version.svg"
|
|
10
|
+
/>
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/@guanghechen/version">
|
|
13
|
+
<img
|
|
14
|
+
alt="Npm Download"
|
|
15
|
+
src="https://img.shields.io/npm/dm/@guanghechen/version.svg"
|
|
16
|
+
/>
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@guanghechen/version">
|
|
19
|
+
<img
|
|
20
|
+
alt="Npm License"
|
|
21
|
+
src="https://img.shields.io/npm/l/@guanghechen/version.svg"
|
|
22
|
+
/>
|
|
23
|
+
</a>
|
|
24
|
+
<a href="#install">
|
|
25
|
+
<img
|
|
26
|
+
alt="Module Formats: cjs, esm"
|
|
27
|
+
src="https://img.shields.io/badge/module_formats-cjs%2C%20esm-green.svg"
|
|
28
|
+
/>
|
|
29
|
+
</a>
|
|
30
|
+
<a href="https://github.com/nodejs/node">
|
|
31
|
+
<img
|
|
32
|
+
alt="Node.js Version"
|
|
33
|
+
src="https://img.shields.io/node/v/@guanghechen/version"
|
|
34
|
+
/>
|
|
35
|
+
</a>
|
|
36
|
+
<a href="https://github.com/facebook/jest">
|
|
37
|
+
<img
|
|
38
|
+
alt="Tested with Jest"
|
|
39
|
+
src="https://img.shields.io/badge/tested_with-jest-9c465e.svg"
|
|
40
|
+
/>
|
|
41
|
+
</a>
|
|
42
|
+
<a href="https://github.com/prettier/prettier">
|
|
43
|
+
<img
|
|
44
|
+
alt="Code Style: prettier"
|
|
45
|
+
src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square"
|
|
46
|
+
/>
|
|
47
|
+
</a>
|
|
48
|
+
</div>
|
|
49
|
+
</header>
|
|
50
|
+
<br/>
|
|
51
|
+
|
|
52
|
+
Lightweight semver version comparison utilities.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
- npm
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install --save @guanghechen/version
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- yarn
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
yarn add @guanghechen/version
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
### Parse and Compare Versions
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { parseVersion, compareVersions, compareSemVer } from '@guanghechen/version'
|
|
74
|
+
|
|
75
|
+
// Parse a version string
|
|
76
|
+
const v = parseVersion('1.2.3-alpha.1')
|
|
77
|
+
// => { major: 1, minor: 2, patch: 3, prerelease: ['alpha', 1] }
|
|
78
|
+
|
|
79
|
+
// Compare version strings
|
|
80
|
+
compareVersions('1.2.3', '1.2.4') // => -1
|
|
81
|
+
compareVersions('2.0.0', '1.9.9') // => 1
|
|
82
|
+
compareVersions('1.0.0', '1.0.0') // => 0
|
|
83
|
+
|
|
84
|
+
// Compare parsed versions
|
|
85
|
+
compareSemVer(
|
|
86
|
+
{ major: 1, minor: 0, patch: 0, prerelease: [] },
|
|
87
|
+
{ major: 2, minor: 0, patch: 0, prerelease: [] }
|
|
88
|
+
) // => -1
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Check Version Ranges
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { satisfies } from '@guanghechen/version'
|
|
95
|
+
|
|
96
|
+
// Exact version
|
|
97
|
+
satisfies('1.2.3', '1.2.3') // => true
|
|
98
|
+
|
|
99
|
+
// Caret ranges (^)
|
|
100
|
+
satisfies('1.2.3', '^1.0.0') // => true
|
|
101
|
+
satisfies('2.0.0', '^1.0.0') // => false
|
|
102
|
+
|
|
103
|
+
// Tilde ranges (~)
|
|
104
|
+
satisfies('1.2.5', '~1.2.0') // => true
|
|
105
|
+
satisfies('1.3.0', '~1.2.0') // => false
|
|
106
|
+
|
|
107
|
+
// Comparison operators
|
|
108
|
+
satisfies('1.5.0', '>=1.0.0') // => true
|
|
109
|
+
satisfies('1.5.0', '<2.0.0') // => true
|
|
110
|
+
satisfies('1.5.0', '>1.0.0 <2.0.0') // => true
|
|
111
|
+
|
|
112
|
+
// X-ranges
|
|
113
|
+
satisfies('1.2.3', '1.x') // => true
|
|
114
|
+
satisfies('1.2.3', '1.2.x') // => true
|
|
115
|
+
|
|
116
|
+
// Hyphen ranges
|
|
117
|
+
satisfies('1.5.0', '1.0.0 - 2.0.0') // => true
|
|
118
|
+
|
|
119
|
+
// OR ranges
|
|
120
|
+
satisfies('3.0.0', '^1.0.0 || ^2.0.0 || ^3.0.0') // => true
|
|
121
|
+
|
|
122
|
+
// Prerelease versions (includePrerelease defaults to true)
|
|
123
|
+
satisfies('1.0.0-alpha', '^1.0.0') // => true
|
|
124
|
+
|
|
125
|
+
// Strict mode (node-semver compatible)
|
|
126
|
+
satisfies('1.0.0-alpha', '^1.0.0', { includePrerelease: false }) // => false
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## API
|
|
130
|
+
|
|
131
|
+
### Types
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface ISemVer {
|
|
135
|
+
major: number
|
|
136
|
+
minor: number
|
|
137
|
+
patch: number
|
|
138
|
+
prerelease: ReadonlyArray<string | number>
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
interface IPartialSemVer {
|
|
142
|
+
major: number
|
|
143
|
+
minor: number | undefined
|
|
144
|
+
patch: number | undefined
|
|
145
|
+
prerelease: ReadonlyArray<string | number>
|
|
146
|
+
isWildcard?: boolean
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface ISatisfiesOptions {
|
|
150
|
+
includePrerelease?: boolean // default: true
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Functions
|
|
155
|
+
|
|
156
|
+
| Function | Description |
|
|
157
|
+
| ----------------------------------------------------- | ---------------------------------------------- |
|
|
158
|
+
| `parseVersion(version: string)` | Parse a full semver string to `ISemVer` |
|
|
159
|
+
| `parsePartialVersion(version: string)` | Parse a partial version to `IPartialSemVer` |
|
|
160
|
+
| `compareVersions(v1: string, v2: string)` | Compare two version strings (-1, 0, 1) |
|
|
161
|
+
| `compareSemVer(v1: ISemVer, v2: ISemVer)` | Compare two parsed versions (-1, 0, 1) |
|
|
162
|
+
| `satisfies(version: string, range: string, options?)` | Check if version satisfies the range |
|
|
163
|
+
| `formatVersion(v: ISemVer)` | Format a parsed version back to string |
|
|
164
|
+
| `isFullVersion(v: IPartialSemVer)` | Check if partial version is a full version |
|
|
165
|
+
| `toFullVersion(v: IPartialSemVer)` | Convert partial version to full (fill with 0s) |
|
|
166
|
+
|
|
167
|
+
[homepage]:
|
|
168
|
+
https://github.com/guanghechen/sora/tree/@guanghechen/version@1.0.0/packages/version#readme
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const SEMVER_REGEX = /^[v=]?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
4
|
+
const PARTIAL_SEMVER_REGEX = /^[v=]?(\d+)(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
5
|
+
function isWildcardChar(s) {
|
|
6
|
+
return s === '*' || s === 'x' || s === 'X';
|
|
7
|
+
}
|
|
8
|
+
function parsePrerelease(prereleaseStr) {
|
|
9
|
+
if (!prereleaseStr)
|
|
10
|
+
return [];
|
|
11
|
+
return prereleaseStr.split('.').map(part => {
|
|
12
|
+
const num = parseInt(part, 10);
|
|
13
|
+
return String(num) === part ? num : part;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function parseVersion(version) {
|
|
17
|
+
const match = SEMVER_REGEX.exec(version);
|
|
18
|
+
if (!match)
|
|
19
|
+
return undefined;
|
|
20
|
+
return {
|
|
21
|
+
major: parseInt(match[1], 10),
|
|
22
|
+
minor: parseInt(match[2], 10),
|
|
23
|
+
patch: parseInt(match[3], 10),
|
|
24
|
+
prerelease: parsePrerelease(match[4]),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function parsePartialVersion(version) {
|
|
28
|
+
const trimmed = version.trim();
|
|
29
|
+
if (trimmed === '' || isWildcardChar(trimmed)) {
|
|
30
|
+
return { major: 0, minor: undefined, patch: undefined, prerelease: [], isWildcard: true };
|
|
31
|
+
}
|
|
32
|
+
const match = PARTIAL_SEMVER_REGEX.exec(trimmed);
|
|
33
|
+
if (!match)
|
|
34
|
+
return undefined;
|
|
35
|
+
const minorStr = match[2];
|
|
36
|
+
const patchStr = match[3];
|
|
37
|
+
return {
|
|
38
|
+
major: parseInt(match[1], 10),
|
|
39
|
+
minor: minorStr === undefined || isWildcardChar(minorStr) ? undefined : parseInt(minorStr, 10),
|
|
40
|
+
patch: patchStr === undefined || isWildcardChar(patchStr) ? undefined : parseInt(patchStr, 10),
|
|
41
|
+
prerelease: parsePrerelease(match[4]),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function isFullVersion(v) {
|
|
45
|
+
return v.minor !== undefined && v.patch !== undefined;
|
|
46
|
+
}
|
|
47
|
+
function toFullVersion(v) {
|
|
48
|
+
return {
|
|
49
|
+
major: v.major,
|
|
50
|
+
minor: v.minor ?? 0,
|
|
51
|
+
patch: v.patch ?? 0,
|
|
52
|
+
prerelease: v.prerelease,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function formatVersion(v) {
|
|
56
|
+
const base = `${v.major}.${v.minor}.${v.patch}`;
|
|
57
|
+
return v.prerelease.length === 0 ? base : `${base}-${v.prerelease.join('.')}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function comparePrerelease(a, b) {
|
|
61
|
+
if (a.length === 0 && b.length === 0)
|
|
62
|
+
return 0;
|
|
63
|
+
if (a.length === 0)
|
|
64
|
+
return 1;
|
|
65
|
+
if (b.length === 0)
|
|
66
|
+
return -1;
|
|
67
|
+
const len = Math.max(a.length, b.length);
|
|
68
|
+
for (let i = 0; i < len; i++) {
|
|
69
|
+
if (i >= a.length)
|
|
70
|
+
return -1;
|
|
71
|
+
if (i >= b.length)
|
|
72
|
+
return 1;
|
|
73
|
+
const aVal = a[i];
|
|
74
|
+
const bVal = b[i];
|
|
75
|
+
if (aVal === bVal)
|
|
76
|
+
continue;
|
|
77
|
+
const aIsNum = typeof aVal === 'number';
|
|
78
|
+
const bIsNum = typeof bVal === 'number';
|
|
79
|
+
if (aIsNum !== bIsNum)
|
|
80
|
+
return aIsNum ? -1 : 1;
|
|
81
|
+
return aVal < bVal ? -1 : 1;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
function compareSemVer(v1, v2) {
|
|
86
|
+
if (v1.major !== v2.major)
|
|
87
|
+
return v1.major < v2.major ? -1 : 1;
|
|
88
|
+
if (v1.minor !== v2.minor)
|
|
89
|
+
return v1.minor < v2.minor ? -1 : 1;
|
|
90
|
+
if (v1.patch !== v2.patch)
|
|
91
|
+
return v1.patch < v2.patch ? -1 : 1;
|
|
92
|
+
return comparePrerelease(v1.prerelease, v2.prerelease);
|
|
93
|
+
}
|
|
94
|
+
function compareVersions(v1, v2) {
|
|
95
|
+
const parsed1 = parseVersion(v1);
|
|
96
|
+
const parsed2 = parseVersion(v2);
|
|
97
|
+
if (!parsed1 || !parsed2) {
|
|
98
|
+
throw new Error(`Invalid version: ${!parsed1 ? v1 : v2}`);
|
|
99
|
+
}
|
|
100
|
+
return compareSemVer(parsed1, parsed2);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const HYPHEN_RANGE_REGEX = /^\s*(\S+)\s+-\s+(\S+)\s*$/;
|
|
104
|
+
const COMPARATOR_REGEX = /^(>=|>|<=|<|=|\^|~)?(.*)$/;
|
|
105
|
+
function createComparator(target, op) {
|
|
106
|
+
return (v) => {
|
|
107
|
+
const cmp = compareSemVer(v, target);
|
|
108
|
+
if (op === 'gt')
|
|
109
|
+
return cmp > 0;
|
|
110
|
+
if (op === 'gte')
|
|
111
|
+
return cmp >= 0;
|
|
112
|
+
if (op === 'lt')
|
|
113
|
+
return cmp < 0;
|
|
114
|
+
if (op === 'lte')
|
|
115
|
+
return cmp <= 0;
|
|
116
|
+
return cmp === 0;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function createAndComparator(comparators) {
|
|
120
|
+
return (v) => comparators.every(c => c(v));
|
|
121
|
+
}
|
|
122
|
+
function createSemVer(major, minor, patch, prerelease = []) {
|
|
123
|
+
return { major, minor, patch, prerelease: [...prerelease] };
|
|
124
|
+
}
|
|
125
|
+
function withResult(comparator, prereleaseVersions) {
|
|
126
|
+
return { comparator, prereleaseVersions };
|
|
127
|
+
}
|
|
128
|
+
function hasSameBaseVersion(v1, v2) {
|
|
129
|
+
return v1.major === v2.major && v1.minor === v2.minor && v1.patch === v2.patch;
|
|
130
|
+
}
|
|
131
|
+
function parseHyphenRange(range) {
|
|
132
|
+
const match = HYPHEN_RANGE_REGEX.exec(range);
|
|
133
|
+
if (!match)
|
|
134
|
+
return undefined;
|
|
135
|
+
const start = parsePartialVersion(match[1]);
|
|
136
|
+
const end = parsePartialVersion(match[2]);
|
|
137
|
+
if (!start || !end)
|
|
138
|
+
return undefined;
|
|
139
|
+
const startFull = toFullVersion(start);
|
|
140
|
+
const comparators = [createComparator(startFull, 'gte')];
|
|
141
|
+
const prereleaseVersions = [];
|
|
142
|
+
if (start.prerelease.length > 0)
|
|
143
|
+
prereleaseVersions.push(startFull);
|
|
144
|
+
if (isFullVersion(end)) {
|
|
145
|
+
comparators.push(createComparator(end, 'lte'));
|
|
146
|
+
if (end.prerelease.length > 0)
|
|
147
|
+
prereleaseVersions.push(end);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const endMax = end.minor === undefined
|
|
151
|
+
? createSemVer(end.major + 1, 0, 0, [0])
|
|
152
|
+
: createSemVer(end.major, end.minor + 1, 0, [0]);
|
|
153
|
+
comparators.push(createComparator(endMax, 'lt'));
|
|
154
|
+
}
|
|
155
|
+
return [withResult(createAndComparator(comparators), prereleaseVersions)];
|
|
156
|
+
}
|
|
157
|
+
function parseXRange(partial) {
|
|
158
|
+
if (partial.minor === undefined) {
|
|
159
|
+
if (partial.isWildcard)
|
|
160
|
+
return withResult(() => true, []);
|
|
161
|
+
const min = createSemVer(partial.major, 0, 0, partial.prerelease);
|
|
162
|
+
const max = createSemVer(partial.major + 1, 0, 0, [0]);
|
|
163
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), partial.prerelease.length > 0 ? [min] : []);
|
|
164
|
+
}
|
|
165
|
+
const min = createSemVer(partial.major, partial.minor, 0, partial.prerelease);
|
|
166
|
+
const max = createSemVer(partial.major, partial.minor + 1, 0, [0]);
|
|
167
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), partial.prerelease.length > 0 ? [min] : []);
|
|
168
|
+
}
|
|
169
|
+
function parseCaretRange(partial) {
|
|
170
|
+
const min = toFullVersion(partial);
|
|
171
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
172
|
+
let max;
|
|
173
|
+
if (partial.minor === undefined) {
|
|
174
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
175
|
+
}
|
|
176
|
+
else if (partial.patch === undefined) {
|
|
177
|
+
if (min.major === 0 && min.minor === 0) {
|
|
178
|
+
max = createSemVer(0, 1, 0, [0]);
|
|
179
|
+
}
|
|
180
|
+
else if (min.major === 0) {
|
|
181
|
+
max = createSemVer(0, min.minor + 1, 0, [0]);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (min.major > 0) {
|
|
188
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
189
|
+
}
|
|
190
|
+
else if (min.minor > 0) {
|
|
191
|
+
max = createSemVer(0, min.minor + 1, 0, [0]);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
max = createSemVer(0, 0, min.patch + 1, [0]);
|
|
195
|
+
}
|
|
196
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), hasPrerelease ? [min] : []);
|
|
197
|
+
}
|
|
198
|
+
function parseTildeRange(partial) {
|
|
199
|
+
const min = toFullVersion(partial);
|
|
200
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
201
|
+
const max = partial.minor === undefined
|
|
202
|
+
? createSemVer(min.major + 1, 0, 0, [0])
|
|
203
|
+
: createSemVer(min.major, min.minor + 1, 0, [0]);
|
|
204
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), hasPrerelease ? [min] : []);
|
|
205
|
+
}
|
|
206
|
+
function parseComparatorWithOperator(operator, partial) {
|
|
207
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
208
|
+
switch (operator) {
|
|
209
|
+
case '':
|
|
210
|
+
case '=': {
|
|
211
|
+
if (!isFullVersion(partial))
|
|
212
|
+
return parseXRange(partial);
|
|
213
|
+
return withResult(createComparator(partial, 'eq'), hasPrerelease ? [partial] : []);
|
|
214
|
+
}
|
|
215
|
+
case '>': {
|
|
216
|
+
if (!isFullVersion(partial)) {
|
|
217
|
+
const target = partial.minor === undefined
|
|
218
|
+
? createSemVer(partial.major + 1, 0, 0)
|
|
219
|
+
: createSemVer(partial.major, partial.minor + 1, 0);
|
|
220
|
+
return withResult(createComparator(target, 'gte'), hasPrerelease ? [toFullVersion(partial)] : []);
|
|
221
|
+
}
|
|
222
|
+
return withResult(createComparator(partial, 'gt'), hasPrerelease ? [partial] : []);
|
|
223
|
+
}
|
|
224
|
+
case '>=': {
|
|
225
|
+
const full = toFullVersion(partial);
|
|
226
|
+
return withResult(createComparator(full, 'gte'), hasPrerelease ? [full] : []);
|
|
227
|
+
}
|
|
228
|
+
case '<': {
|
|
229
|
+
if (!isFullVersion(partial)) {
|
|
230
|
+
const target = toFullVersion(partial);
|
|
231
|
+
const targetWithPrerelease = createSemVer(target.major, target.minor, target.patch, [0]);
|
|
232
|
+
return withResult(createComparator(targetWithPrerelease, 'lt'), hasPrerelease ? [target] : []);
|
|
233
|
+
}
|
|
234
|
+
return withResult(createComparator(partial, 'lt'), hasPrerelease ? [partial] : []);
|
|
235
|
+
}
|
|
236
|
+
case '<=': {
|
|
237
|
+
if (!isFullVersion(partial)) {
|
|
238
|
+
const target = partial.minor === undefined
|
|
239
|
+
? createSemVer(partial.major + 1, 0, 0, [0])
|
|
240
|
+
: createSemVer(partial.major, partial.minor + 1, 0, [0]);
|
|
241
|
+
return withResult(createComparator(target, 'lt'), hasPrerelease ? [toFullVersion(partial)] : []);
|
|
242
|
+
}
|
|
243
|
+
return withResult(createComparator(partial, 'lte'), hasPrerelease ? [partial] : []);
|
|
244
|
+
}
|
|
245
|
+
case '^':
|
|
246
|
+
return parseCaretRange(partial);
|
|
247
|
+
case '~':
|
|
248
|
+
return parseTildeRange(partial);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const OPERATORS = ['>=', '>', '<=', '<', '=', '^', '~', ''];
|
|
252
|
+
function isOperator(s) {
|
|
253
|
+
return OPERATORS.includes(s);
|
|
254
|
+
}
|
|
255
|
+
function parseSingleComparator(comp) {
|
|
256
|
+
const trimmed = comp.trim();
|
|
257
|
+
if (trimmed === '' || trimmed === '*' || trimmed === 'x' || trimmed === 'X') {
|
|
258
|
+
return withResult(() => true, []);
|
|
259
|
+
}
|
|
260
|
+
const match = COMPARATOR_REGEX.exec(trimmed);
|
|
261
|
+
if (!match)
|
|
262
|
+
return undefined;
|
|
263
|
+
const operator = match[1] || '';
|
|
264
|
+
const versionStr = match[2];
|
|
265
|
+
if (!versionStr) {
|
|
266
|
+
return operator === '' ? withResult(() => true, []) : undefined;
|
|
267
|
+
}
|
|
268
|
+
const partial = parsePartialVersion(versionStr);
|
|
269
|
+
if (!partial || !isOperator(operator))
|
|
270
|
+
return undefined;
|
|
271
|
+
return parseComparatorWithOperator(operator, partial);
|
|
272
|
+
}
|
|
273
|
+
function parseComparatorSet(set) {
|
|
274
|
+
const hyphenResult = parseHyphenRange(set);
|
|
275
|
+
if (hyphenResult)
|
|
276
|
+
return hyphenResult;
|
|
277
|
+
const parts = set.trim().split(/\s+/);
|
|
278
|
+
const results = [];
|
|
279
|
+
for (const part of parts) {
|
|
280
|
+
if (part === '')
|
|
281
|
+
continue;
|
|
282
|
+
const parsed = parseSingleComparator(part);
|
|
283
|
+
if (!parsed)
|
|
284
|
+
return undefined;
|
|
285
|
+
results.push(parsed);
|
|
286
|
+
}
|
|
287
|
+
return results.length === 0 ? [withResult(() => true, [])] : results;
|
|
288
|
+
}
|
|
289
|
+
function checkPrereleaseAllowed(version, prereleaseVersions) {
|
|
290
|
+
if (version.prerelease.length === 0)
|
|
291
|
+
return true;
|
|
292
|
+
return prereleaseVersions.some(pv => hasSameBaseVersion(version, pv));
|
|
293
|
+
}
|
|
294
|
+
function satisfies(version, range, options) {
|
|
295
|
+
const parsed = parseVersion(version);
|
|
296
|
+
if (!parsed)
|
|
297
|
+
return false;
|
|
298
|
+
const includePrerelease = options?.includePrerelease ?? true;
|
|
299
|
+
for (const orPart of range.split('||')) {
|
|
300
|
+
const comparatorSet = parseComparatorSet(orPart);
|
|
301
|
+
if (!comparatorSet)
|
|
302
|
+
continue;
|
|
303
|
+
const allMatch = comparatorSet.every(c => c.comparator(parsed));
|
|
304
|
+
if (!allMatch)
|
|
305
|
+
continue;
|
|
306
|
+
if (includePrerelease)
|
|
307
|
+
return true;
|
|
308
|
+
const prereleaseVersions = comparatorSet.flatMap(c => c.prereleaseVersions);
|
|
309
|
+
if (checkPrereleaseAllowed(parsed, prereleaseVersions))
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
exports.compareSemVer = compareSemVer;
|
|
316
|
+
exports.compareVersions = compareVersions;
|
|
317
|
+
exports.formatVersion = formatVersion;
|
|
318
|
+
exports.isFullVersion = isFullVersion;
|
|
319
|
+
exports.parsePartialVersion = parsePartialVersion;
|
|
320
|
+
exports.parseVersion = parseVersion;
|
|
321
|
+
exports.satisfies = satisfies;
|
|
322
|
+
exports.toFullVersion = toFullVersion;
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
const SEMVER_REGEX = /^[v=]?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
2
|
+
const PARTIAL_SEMVER_REGEX = /^[v=]?(\d+)(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
3
|
+
function isWildcardChar(s) {
|
|
4
|
+
return s === '*' || s === 'x' || s === 'X';
|
|
5
|
+
}
|
|
6
|
+
function parsePrerelease(prereleaseStr) {
|
|
7
|
+
if (!prereleaseStr)
|
|
8
|
+
return [];
|
|
9
|
+
return prereleaseStr.split('.').map(part => {
|
|
10
|
+
const num = parseInt(part, 10);
|
|
11
|
+
return String(num) === part ? num : part;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function parseVersion(version) {
|
|
15
|
+
const match = SEMVER_REGEX.exec(version);
|
|
16
|
+
if (!match)
|
|
17
|
+
return undefined;
|
|
18
|
+
return {
|
|
19
|
+
major: parseInt(match[1], 10),
|
|
20
|
+
minor: parseInt(match[2], 10),
|
|
21
|
+
patch: parseInt(match[3], 10),
|
|
22
|
+
prerelease: parsePrerelease(match[4]),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function parsePartialVersion(version) {
|
|
26
|
+
const trimmed = version.trim();
|
|
27
|
+
if (trimmed === '' || isWildcardChar(trimmed)) {
|
|
28
|
+
return { major: 0, minor: undefined, patch: undefined, prerelease: [], isWildcard: true };
|
|
29
|
+
}
|
|
30
|
+
const match = PARTIAL_SEMVER_REGEX.exec(trimmed);
|
|
31
|
+
if (!match)
|
|
32
|
+
return undefined;
|
|
33
|
+
const minorStr = match[2];
|
|
34
|
+
const patchStr = match[3];
|
|
35
|
+
return {
|
|
36
|
+
major: parseInt(match[1], 10),
|
|
37
|
+
minor: minorStr === undefined || isWildcardChar(minorStr) ? undefined : parseInt(minorStr, 10),
|
|
38
|
+
patch: patchStr === undefined || isWildcardChar(patchStr) ? undefined : parseInt(patchStr, 10),
|
|
39
|
+
prerelease: parsePrerelease(match[4]),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function isFullVersion(v) {
|
|
43
|
+
return v.minor !== undefined && v.patch !== undefined;
|
|
44
|
+
}
|
|
45
|
+
function toFullVersion(v) {
|
|
46
|
+
return {
|
|
47
|
+
major: v.major,
|
|
48
|
+
minor: v.minor ?? 0,
|
|
49
|
+
patch: v.patch ?? 0,
|
|
50
|
+
prerelease: v.prerelease,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function formatVersion(v) {
|
|
54
|
+
const base = `${v.major}.${v.minor}.${v.patch}`;
|
|
55
|
+
return v.prerelease.length === 0 ? base : `${base}-${v.prerelease.join('.')}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function comparePrerelease(a, b) {
|
|
59
|
+
if (a.length === 0 && b.length === 0)
|
|
60
|
+
return 0;
|
|
61
|
+
if (a.length === 0)
|
|
62
|
+
return 1;
|
|
63
|
+
if (b.length === 0)
|
|
64
|
+
return -1;
|
|
65
|
+
const len = Math.max(a.length, b.length);
|
|
66
|
+
for (let i = 0; i < len; i++) {
|
|
67
|
+
if (i >= a.length)
|
|
68
|
+
return -1;
|
|
69
|
+
if (i >= b.length)
|
|
70
|
+
return 1;
|
|
71
|
+
const aVal = a[i];
|
|
72
|
+
const bVal = b[i];
|
|
73
|
+
if (aVal === bVal)
|
|
74
|
+
continue;
|
|
75
|
+
const aIsNum = typeof aVal === 'number';
|
|
76
|
+
const bIsNum = typeof bVal === 'number';
|
|
77
|
+
if (aIsNum !== bIsNum)
|
|
78
|
+
return aIsNum ? -1 : 1;
|
|
79
|
+
return aVal < bVal ? -1 : 1;
|
|
80
|
+
}
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
function compareSemVer(v1, v2) {
|
|
84
|
+
if (v1.major !== v2.major)
|
|
85
|
+
return v1.major < v2.major ? -1 : 1;
|
|
86
|
+
if (v1.minor !== v2.minor)
|
|
87
|
+
return v1.minor < v2.minor ? -1 : 1;
|
|
88
|
+
if (v1.patch !== v2.patch)
|
|
89
|
+
return v1.patch < v2.patch ? -1 : 1;
|
|
90
|
+
return comparePrerelease(v1.prerelease, v2.prerelease);
|
|
91
|
+
}
|
|
92
|
+
function compareVersions(v1, v2) {
|
|
93
|
+
const parsed1 = parseVersion(v1);
|
|
94
|
+
const parsed2 = parseVersion(v2);
|
|
95
|
+
if (!parsed1 || !parsed2) {
|
|
96
|
+
throw new Error(`Invalid version: ${!parsed1 ? v1 : v2}`);
|
|
97
|
+
}
|
|
98
|
+
return compareSemVer(parsed1, parsed2);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const HYPHEN_RANGE_REGEX = /^\s*(\S+)\s+-\s+(\S+)\s*$/;
|
|
102
|
+
const COMPARATOR_REGEX = /^(>=|>|<=|<|=|\^|~)?(.*)$/;
|
|
103
|
+
function createComparator(target, op) {
|
|
104
|
+
return (v) => {
|
|
105
|
+
const cmp = compareSemVer(v, target);
|
|
106
|
+
if (op === 'gt')
|
|
107
|
+
return cmp > 0;
|
|
108
|
+
if (op === 'gte')
|
|
109
|
+
return cmp >= 0;
|
|
110
|
+
if (op === 'lt')
|
|
111
|
+
return cmp < 0;
|
|
112
|
+
if (op === 'lte')
|
|
113
|
+
return cmp <= 0;
|
|
114
|
+
return cmp === 0;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function createAndComparator(comparators) {
|
|
118
|
+
return (v) => comparators.every(c => c(v));
|
|
119
|
+
}
|
|
120
|
+
function createSemVer(major, minor, patch, prerelease = []) {
|
|
121
|
+
return { major, minor, patch, prerelease: [...prerelease] };
|
|
122
|
+
}
|
|
123
|
+
function withResult(comparator, prereleaseVersions) {
|
|
124
|
+
return { comparator, prereleaseVersions };
|
|
125
|
+
}
|
|
126
|
+
function hasSameBaseVersion(v1, v2) {
|
|
127
|
+
return v1.major === v2.major && v1.minor === v2.minor && v1.patch === v2.patch;
|
|
128
|
+
}
|
|
129
|
+
function parseHyphenRange(range) {
|
|
130
|
+
const match = HYPHEN_RANGE_REGEX.exec(range);
|
|
131
|
+
if (!match)
|
|
132
|
+
return undefined;
|
|
133
|
+
const start = parsePartialVersion(match[1]);
|
|
134
|
+
const end = parsePartialVersion(match[2]);
|
|
135
|
+
if (!start || !end)
|
|
136
|
+
return undefined;
|
|
137
|
+
const startFull = toFullVersion(start);
|
|
138
|
+
const comparators = [createComparator(startFull, 'gte')];
|
|
139
|
+
const prereleaseVersions = [];
|
|
140
|
+
if (start.prerelease.length > 0)
|
|
141
|
+
prereleaseVersions.push(startFull);
|
|
142
|
+
if (isFullVersion(end)) {
|
|
143
|
+
comparators.push(createComparator(end, 'lte'));
|
|
144
|
+
if (end.prerelease.length > 0)
|
|
145
|
+
prereleaseVersions.push(end);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const endMax = end.minor === undefined
|
|
149
|
+
? createSemVer(end.major + 1, 0, 0, [0])
|
|
150
|
+
: createSemVer(end.major, end.minor + 1, 0, [0]);
|
|
151
|
+
comparators.push(createComparator(endMax, 'lt'));
|
|
152
|
+
}
|
|
153
|
+
return [withResult(createAndComparator(comparators), prereleaseVersions)];
|
|
154
|
+
}
|
|
155
|
+
function parseXRange(partial) {
|
|
156
|
+
if (partial.minor === undefined) {
|
|
157
|
+
if (partial.isWildcard)
|
|
158
|
+
return withResult(() => true, []);
|
|
159
|
+
const min = createSemVer(partial.major, 0, 0, partial.prerelease);
|
|
160
|
+
const max = createSemVer(partial.major + 1, 0, 0, [0]);
|
|
161
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), partial.prerelease.length > 0 ? [min] : []);
|
|
162
|
+
}
|
|
163
|
+
const min = createSemVer(partial.major, partial.minor, 0, partial.prerelease);
|
|
164
|
+
const max = createSemVer(partial.major, partial.minor + 1, 0, [0]);
|
|
165
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), partial.prerelease.length > 0 ? [min] : []);
|
|
166
|
+
}
|
|
167
|
+
function parseCaretRange(partial) {
|
|
168
|
+
const min = toFullVersion(partial);
|
|
169
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
170
|
+
let max;
|
|
171
|
+
if (partial.minor === undefined) {
|
|
172
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
173
|
+
}
|
|
174
|
+
else if (partial.patch === undefined) {
|
|
175
|
+
if (min.major === 0 && min.minor === 0) {
|
|
176
|
+
max = createSemVer(0, 1, 0, [0]);
|
|
177
|
+
}
|
|
178
|
+
else if (min.major === 0) {
|
|
179
|
+
max = createSemVer(0, min.minor + 1, 0, [0]);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (min.major > 0) {
|
|
186
|
+
max = createSemVer(min.major + 1, 0, 0, [0]);
|
|
187
|
+
}
|
|
188
|
+
else if (min.minor > 0) {
|
|
189
|
+
max = createSemVer(0, min.minor + 1, 0, [0]);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
max = createSemVer(0, 0, min.patch + 1, [0]);
|
|
193
|
+
}
|
|
194
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), hasPrerelease ? [min] : []);
|
|
195
|
+
}
|
|
196
|
+
function parseTildeRange(partial) {
|
|
197
|
+
const min = toFullVersion(partial);
|
|
198
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
199
|
+
const max = partial.minor === undefined
|
|
200
|
+
? createSemVer(min.major + 1, 0, 0, [0])
|
|
201
|
+
: createSemVer(min.major, min.minor + 1, 0, [0]);
|
|
202
|
+
return withResult(createAndComparator([createComparator(min, 'gte'), createComparator(max, 'lt')]), hasPrerelease ? [min] : []);
|
|
203
|
+
}
|
|
204
|
+
function parseComparatorWithOperator(operator, partial) {
|
|
205
|
+
const hasPrerelease = partial.prerelease.length > 0;
|
|
206
|
+
switch (operator) {
|
|
207
|
+
case '':
|
|
208
|
+
case '=': {
|
|
209
|
+
if (!isFullVersion(partial))
|
|
210
|
+
return parseXRange(partial);
|
|
211
|
+
return withResult(createComparator(partial, 'eq'), hasPrerelease ? [partial] : []);
|
|
212
|
+
}
|
|
213
|
+
case '>': {
|
|
214
|
+
if (!isFullVersion(partial)) {
|
|
215
|
+
const target = partial.minor === undefined
|
|
216
|
+
? createSemVer(partial.major + 1, 0, 0)
|
|
217
|
+
: createSemVer(partial.major, partial.minor + 1, 0);
|
|
218
|
+
return withResult(createComparator(target, 'gte'), hasPrerelease ? [toFullVersion(partial)] : []);
|
|
219
|
+
}
|
|
220
|
+
return withResult(createComparator(partial, 'gt'), hasPrerelease ? [partial] : []);
|
|
221
|
+
}
|
|
222
|
+
case '>=': {
|
|
223
|
+
const full = toFullVersion(partial);
|
|
224
|
+
return withResult(createComparator(full, 'gte'), hasPrerelease ? [full] : []);
|
|
225
|
+
}
|
|
226
|
+
case '<': {
|
|
227
|
+
if (!isFullVersion(partial)) {
|
|
228
|
+
const target = toFullVersion(partial);
|
|
229
|
+
const targetWithPrerelease = createSemVer(target.major, target.minor, target.patch, [0]);
|
|
230
|
+
return withResult(createComparator(targetWithPrerelease, 'lt'), hasPrerelease ? [target] : []);
|
|
231
|
+
}
|
|
232
|
+
return withResult(createComparator(partial, 'lt'), hasPrerelease ? [partial] : []);
|
|
233
|
+
}
|
|
234
|
+
case '<=': {
|
|
235
|
+
if (!isFullVersion(partial)) {
|
|
236
|
+
const target = partial.minor === undefined
|
|
237
|
+
? createSemVer(partial.major + 1, 0, 0, [0])
|
|
238
|
+
: createSemVer(partial.major, partial.minor + 1, 0, [0]);
|
|
239
|
+
return withResult(createComparator(target, 'lt'), hasPrerelease ? [toFullVersion(partial)] : []);
|
|
240
|
+
}
|
|
241
|
+
return withResult(createComparator(partial, 'lte'), hasPrerelease ? [partial] : []);
|
|
242
|
+
}
|
|
243
|
+
case '^':
|
|
244
|
+
return parseCaretRange(partial);
|
|
245
|
+
case '~':
|
|
246
|
+
return parseTildeRange(partial);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const OPERATORS = ['>=', '>', '<=', '<', '=', '^', '~', ''];
|
|
250
|
+
function isOperator(s) {
|
|
251
|
+
return OPERATORS.includes(s);
|
|
252
|
+
}
|
|
253
|
+
function parseSingleComparator(comp) {
|
|
254
|
+
const trimmed = comp.trim();
|
|
255
|
+
if (trimmed === '' || trimmed === '*' || trimmed === 'x' || trimmed === 'X') {
|
|
256
|
+
return withResult(() => true, []);
|
|
257
|
+
}
|
|
258
|
+
const match = COMPARATOR_REGEX.exec(trimmed);
|
|
259
|
+
if (!match)
|
|
260
|
+
return undefined;
|
|
261
|
+
const operator = match[1] || '';
|
|
262
|
+
const versionStr = match[2];
|
|
263
|
+
if (!versionStr) {
|
|
264
|
+
return operator === '' ? withResult(() => true, []) : undefined;
|
|
265
|
+
}
|
|
266
|
+
const partial = parsePartialVersion(versionStr);
|
|
267
|
+
if (!partial || !isOperator(operator))
|
|
268
|
+
return undefined;
|
|
269
|
+
return parseComparatorWithOperator(operator, partial);
|
|
270
|
+
}
|
|
271
|
+
function parseComparatorSet(set) {
|
|
272
|
+
const hyphenResult = parseHyphenRange(set);
|
|
273
|
+
if (hyphenResult)
|
|
274
|
+
return hyphenResult;
|
|
275
|
+
const parts = set.trim().split(/\s+/);
|
|
276
|
+
const results = [];
|
|
277
|
+
for (const part of parts) {
|
|
278
|
+
if (part === '')
|
|
279
|
+
continue;
|
|
280
|
+
const parsed = parseSingleComparator(part);
|
|
281
|
+
if (!parsed)
|
|
282
|
+
return undefined;
|
|
283
|
+
results.push(parsed);
|
|
284
|
+
}
|
|
285
|
+
return results.length === 0 ? [withResult(() => true, [])] : results;
|
|
286
|
+
}
|
|
287
|
+
function checkPrereleaseAllowed(version, prereleaseVersions) {
|
|
288
|
+
if (version.prerelease.length === 0)
|
|
289
|
+
return true;
|
|
290
|
+
return prereleaseVersions.some(pv => hasSameBaseVersion(version, pv));
|
|
291
|
+
}
|
|
292
|
+
function satisfies(version, range, options) {
|
|
293
|
+
const parsed = parseVersion(version);
|
|
294
|
+
if (!parsed)
|
|
295
|
+
return false;
|
|
296
|
+
const includePrerelease = options?.includePrerelease ?? true;
|
|
297
|
+
for (const orPart of range.split('||')) {
|
|
298
|
+
const comparatorSet = parseComparatorSet(orPart);
|
|
299
|
+
if (!comparatorSet)
|
|
300
|
+
continue;
|
|
301
|
+
const allMatch = comparatorSet.every(c => c.comparator(parsed));
|
|
302
|
+
if (!allMatch)
|
|
303
|
+
continue;
|
|
304
|
+
if (includePrerelease)
|
|
305
|
+
return true;
|
|
306
|
+
const prereleaseVersions = comparatorSet.flatMap(c => c.prereleaseVersions);
|
|
307
|
+
if (checkPrereleaseAllowed(parsed, prereleaseVersions))
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export { compareSemVer, compareVersions, formatVersion, isFullVersion, parsePartialVersion, parseVersion, satisfies, toFullVersion };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
interface ISemVer {
|
|
2
|
+
major: number;
|
|
3
|
+
minor: number;
|
|
4
|
+
patch: number;
|
|
5
|
+
prerelease: ReadonlyArray<string | number>;
|
|
6
|
+
}
|
|
7
|
+
interface IPartialSemVer {
|
|
8
|
+
major: number;
|
|
9
|
+
minor: number | undefined;
|
|
10
|
+
patch: number | undefined;
|
|
11
|
+
prerelease: ReadonlyArray<string | number>;
|
|
12
|
+
isWildcard?: boolean;
|
|
13
|
+
}
|
|
14
|
+
type IComparator = (version: ISemVer) => boolean;
|
|
15
|
+
interface IComparatorWithPrerelease {
|
|
16
|
+
comparator: IComparator;
|
|
17
|
+
prereleaseVersions: ISemVer[];
|
|
18
|
+
}
|
|
19
|
+
interface ISatisfiesOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Include prerelease versions in the comparison.
|
|
22
|
+
* When true, prerelease versions will match ranges even if the range
|
|
23
|
+
* doesn't include a prerelease tag.
|
|
24
|
+
* @default true (for compatibility with compare-versions)
|
|
25
|
+
*/
|
|
26
|
+
includePrerelease?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare function compareSemVer(v1: ISemVer, v2: ISemVer): -1 | 0 | 1;
|
|
30
|
+
declare function compareVersions(v1: string, v2: string): -1 | 0 | 1;
|
|
31
|
+
|
|
32
|
+
declare function parseVersion(version: string): ISemVer | undefined;
|
|
33
|
+
declare function parsePartialVersion(version: string): IPartialSemVer | undefined;
|
|
34
|
+
declare function isFullVersion(v: IPartialSemVer): v is ISemVer;
|
|
35
|
+
declare function toFullVersion(v: IPartialSemVer): ISemVer;
|
|
36
|
+
declare function formatVersion(v: ISemVer): string;
|
|
37
|
+
|
|
38
|
+
declare function satisfies(version: string, range: string, options?: ISatisfiesOptions): boolean;
|
|
39
|
+
|
|
40
|
+
export { compareSemVer, compareVersions, formatVersion, isFullVersion, parsePartialVersion, parseVersion, satisfies, toFullVersion };
|
|
41
|
+
export type { IComparator, IComparatorWithPrerelease, IPartialSemVer, ISatisfiesOptions, ISemVer };
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guanghechen/version",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight semver version comparison utilities.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "guanghechen",
|
|
7
|
+
"url": "https://github.com/guanghechen/"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/version@0.0.1",
|
|
12
|
+
"directory": "packages/version"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/version@0.0.1/packages/version#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"semver",
|
|
17
|
+
"version",
|
|
18
|
+
"compare"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"source": "./src/index.ts",
|
|
24
|
+
"import": "./lib/esm/index.mjs",
|
|
25
|
+
"require": "./lib/cjs/index.cjs",
|
|
26
|
+
"types": "./lib/types/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"source": "./src/index.ts",
|
|
30
|
+
"main": "./lib/cjs/index.cjs",
|
|
31
|
+
"module": "./lib/esm/index.mjs",
|
|
32
|
+
"types": "./lib/types/index.d.ts",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "rollup -c ../../rollup.config.mjs",
|
|
36
|
+
"clean": "rimraf lib",
|
|
37
|
+
"test": "vitest run --config ../../vitest.config.ts",
|
|
38
|
+
"test:coverage": "vitest run --config ../../vitest.config.ts --coverage",
|
|
39
|
+
"test:update": "vitest run --config ../../vitest.config.ts -u"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"lib/",
|
|
43
|
+
"!lib/**/*.map",
|
|
44
|
+
"package.json",
|
|
45
|
+
"CHANGELOG.md",
|
|
46
|
+
"LICENSE",
|
|
47
|
+
"README.md"
|
|
48
|
+
],
|
|
49
|
+
"gitHead": "12990a720b31d50d217e2e17a6191256dc94eda6"
|
|
50
|
+
}
|