@magic/semver 0.0.18 → 0.0.20

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 CHANGED
@@ -37,13 +37,173 @@ const version = '0.0.1-alpha.0'
37
37
 
38
38
  const parsed = semver.parse(version)
39
39
 
40
- // parsed === { major: 0, minor: 0, patch: 1, demo: { string: 'alpha', version: 0 } }
40
+ // parsed === { major: 0, minor: 0, patch: 1, demo: { string: 'alpha', version: 0 }, v: '0.0.1-alpha.0' }
41
41
 
42
42
  const serialized = semver.serialize(parsed)
43
43
 
44
44
  // version === serialized
45
45
  ```
46
46
 
47
+ ## API
48
+
49
+ ### parse(version)
50
+
51
+ Parses a semver string into a `VersionResult` object.
52
+
53
+ **Parameters:**
54
+
55
+ - `version` (string): A semantic version string (e.g., `"1.2.3"`, `"1.2.3-alpha.0"`, `"v1.2.3"`)
56
+
57
+ **Returns:** `VersionResult` — An object with `major`, `minor`, `patch`, `demo`, and `v` properties.
58
+
59
+ ```javascript
60
+ semver.parse('1.2.3')
61
+ // { major: 1, minor: 2, patch: 3, v: '1.2.3' }
62
+
63
+ semver.parse('1.2.3-alpha.0')
64
+ // { major: 1, minor: 2, patch: 3, demo: { string: 'alpha', version: 0 }, v: '1.2.3-alpha.0' }
65
+
66
+ semver.parse('v1.2.3')
67
+ // { major: 1, minor: 2, patch: 3, v: 'v1.2.3' }
68
+ ```
69
+
70
+ ### serialize(version)
71
+
72
+ **Aliases:** `stringify`
73
+
74
+ Converts a `Version` object back into a semver string.
75
+
76
+ **Parameters:**
77
+
78
+ - `version` (Version): An object with `major`, `minor`, and `patch` properties. Optional `demo` property for pre-release versions.
79
+
80
+ **Returns:** (string): The serialized semver string.
81
+
82
+ ```javascript
83
+ semver.serialize({ major: 1, minor: 2, patch: 3 })
84
+ // '1.2.3'
85
+
86
+ semver.serialize({ major: 1, minor: 2, patch: 3, demo: { string: 'alpha', version: 0 } })
87
+ // '1.2.3-alpha.0'
88
+ ```
89
+
90
+ ### isSemver(value)
91
+
92
+ Type guard that checks if a value is a valid semver (either a string or object).
93
+
94
+ **Parameters:**
95
+
96
+ - `value` (unknown): The value to check.
97
+
98
+ **Returns:** (boolean): `true` if the value is a valid semver string or object.
99
+
100
+ ```javascript
101
+ semver.isSemver('1.2.3') // true
102
+ semver.isSemver('1.2.3-alpha.0') // true
103
+ semver.isSemver({ major: 1, minor: 2, patch: 3 }) // true
104
+ semver.isSemver('not-a-version') // false
105
+ semver.isSemver(123) // false
106
+ ```
107
+
108
+ ### bump(version, options)
109
+
110
+ Increments a semver version. Returns a string if input was a string, or a `Version` object if input was an object.
111
+
112
+ **Parameters:**
113
+
114
+ - `version` (string | Version): The version to bump.
115
+ - `options` (object):
116
+ - `options.major` (boolean): Bump major version, resets minor and patch.
117
+ - `options.minor` (boolean): Bump minor version, resets patch.
118
+ - `options.patch` (boolean): Bump patch version.
119
+ - `options.alpha` (boolean): Set or increment alpha pre-release.
120
+ - `options.beta` (boolean): Set or increment beta pre-release.
121
+
122
+ **Returns:** (string | Version): The bumped version in the same format as input.
123
+
124
+ ```javascript
125
+ semver.bump('1.2.3', { major: true }) // '2.0.0'
126
+ semver.bump('1.2.3', { minor: true }) // '1.3.0'
127
+ semver.bump('1.2.3', { patch: true }) // '1.2.4'
128
+ semver.bump('1.2.3', { alpha: true }) // '1.2.4-alpha.0'
129
+ semver.bump('1.2.3-alpha.0', { alpha: true }) // '1.2.3-alpha.1'
130
+ semver.bump('1.2.3-alpha.0', { beta: true }) // '1.2.3-beta.0'
131
+ semver.bump('1.2.3', { beta: true }) // '1.2.4-beta.0'
132
+
133
+ // No options: increments alpha version if present, otherwise patch
134
+ semver.bump('1.2.3-alpha.0') // '1.2.3-alpha.1'
135
+ semver.bump('1.2.3') // '1.2.4'
136
+ ```
137
+
138
+ ### isBigger(a, b)
139
+
140
+ Compares two versions. Returns `true` if `a` is greater than `b`.
141
+
142
+ **Parameters:**
143
+
144
+ - `a` (string): First version string.
145
+ - `b` (string): Second version string.
146
+
147
+ **Returns:** (boolean): `true` if `a > b`.
148
+
149
+ ```javascript
150
+ semver.isBigger('2.0.0', '1.0.0') // true
151
+ semver.isBigger('1.0.0', '1.0.0') // false
152
+ semver.isBigger('1.0.0-alpha', '1.0.0') // false (release > pre-release)
153
+ semver.isBigger('1.0.0-beta', '1.0.0-alpha') // true (beta > alpha)
154
+ ```
155
+
156
+ ### isSmaller(a, b)
157
+
158
+ Compares two versions. Returns `true` if `a` is less than `b`.
159
+
160
+ **Parameters:**
161
+
162
+ - `a` (string): First version string.
163
+ - `b` (string): Second version string.
164
+
165
+ **Returns:** (boolean): `true` if `a < b`.
166
+
167
+ ```javascript
168
+ semver.isSmaller('1.0.0', '2.0.0') // true
169
+ semver.isSmaller('1.0.0', '1.0.0') // false
170
+ semver.isSmaller('1.0.0-alpha', '1.0.0') // true (pre-release < release)
171
+ ```
172
+
173
+ ### sort(versions)
174
+
175
+ Sorts an array of versions in ascending order according to semver spec (pre-releases come before releases, alpha < beta).
176
+
177
+ **Parameters:**
178
+
179
+ - `versions` (Array<string | Version>): An array of version strings or objects.
180
+
181
+ **Returns:** (Array<string | Version>): The sorted array, preserving input types.
182
+
183
+ ```javascript
184
+ semver.sort(['1.0.0', '2.0.0-alpha', '1.0.0-alpha.0', '2.0.0'])
185
+ // ['1.0.0-alpha.0', '1.0.0', '2.0.0-alpha', '2.0.0']
186
+
187
+ semver.sort(['1.2.3', '1.2.0', '1.3.0'])
188
+ // ['1.2.0', '1.2.3', '1.3.0']
189
+ ```
190
+
191
+ ## Types
192
+
193
+ ```typescript
194
+ type Version = {
195
+ major: number
196
+ minor: number
197
+ patch: number
198
+ demo?: {
199
+ string: string // 'alpha' or 'beta'
200
+ version: number
201
+ }
202
+ }
203
+
204
+ type VersionResult = Version & { v: string }
205
+ ```
206
+
47
207
  ##### changelog
48
208
 
49
209
  ##### 0.0.1
@@ -122,6 +282,16 @@ update dependencies
122
282
 
123
283
  - fix handling a v in front of the version, eg v0.0.1
124
284
 
125
- ##### 0.0.19 - unreleased
285
+ ##### 0.0.19
286
+
287
+ - better type exports
288
+
289
+ ##### 0.0.20
290
+
291
+ - add sort function, sorts arrays of versions
292
+ - add documentation to README.md
293
+ - update dependencies
294
+
295
+ ##### 0.0.21 - unreleased
126
296
 
127
297
  ...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic/semver",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "author": "Wizards & Witches",
5
5
  "description": "semantic version parsing and serialization.",
6
6
  "license": "AGPL-3.0",
@@ -37,8 +37,8 @@
37
37
  "url": "https://github.com/magic/semver/issues"
38
38
  },
39
39
  "dependencies": {
40
- "@magic/error": "0.0.21",
41
- "@magic/types": "0.1.31"
40
+ "@magic/error": "0.0.23",
41
+ "@magic/types": "0.1.37"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@magic-modules/git-badges": "0.0.12",
@@ -46,10 +46,10 @@
46
46
  "@magic-modules/no-spy": "0.0.9",
47
47
  "@magic-modules/pre": "0.0.12",
48
48
  "@magic-themes/docs": "0.0.15",
49
- "@magic/core": "0.0.156",
50
- "@magic/format": "0.0.69",
51
- "@magic/test": "0.2.28",
52
- "typescript": "5.9.3"
49
+ "@magic/core": "0.0.158",
50
+ "@magic/format": "0.0.73",
51
+ "@magic/test": "0.3.12",
52
+ "typescript": "6.0.3"
53
53
  },
54
54
  "files": [
55
55
  "src",
package/src/bump.js CHANGED
@@ -7,10 +7,6 @@ import { isSemver } from './isSemver.js'
7
7
 
8
8
  const libName = '@magic/semver.bump'
9
9
 
10
- /**
11
- * @typedef {import('./types.js').Version} Version
12
- */
13
-
14
10
  /**
15
11
  * @param {string} v
16
12
  * @param {object} options
@@ -19,14 +15,14 @@ const libName = '@magic/semver.bump'
19
15
  * @param {boolean} [options.patch]
20
16
  * @param {boolean} [options.beta]
21
17
  * @param {boolean} [options.alpha]
22
- * @returns {Version | string}
18
+ * @returns {import('./types.js').Version | string}
23
19
  */
24
20
  export const bump = (v, options = {}) => {
25
21
  if (is.empty(v)) {
26
22
  throw error(`${libName} expects arguments to be non-empty`, 'E_VERSION_EMPTY')
27
23
  }
28
24
 
29
- /** @type {Partial<Version> } */
25
+ /** @type {Partial<import('./types.js').Version> } */
30
26
  let version
31
27
 
32
28
  const isString = is.string(v)
package/src/index.js CHANGED
@@ -12,6 +12,9 @@ export const parse = p
12
12
  export const stringify = s
13
13
  export const serialize = s
14
14
 
15
+ /** @typedef {import('./types.js').Version} Version */
16
+ /** @typedef {import('./types.js').VersionResult} VersionResult */
17
+
15
18
  export default {
16
19
  bump,
17
20
  isBigger,
package/src/isSemver.js CHANGED
@@ -3,12 +3,8 @@ import { parse } from './parse.js'
3
3
  import { serialize } from './serialize.js'
4
4
 
5
5
  /**
6
- * @typedef {import('./types.js').Version} Version
7
- */
8
-
9
- /**
10
- * @param {Version | string | unknown} v
11
- * @returns {v is Version}
6
+ * @param {import('./types.js').Version | string | unknown} v
7
+ * @returns {v is import('./types.js').Version}
12
8
  *
13
9
  */
14
10
  export const isSemver = v => {
package/src/parse.js CHANGED
@@ -3,14 +3,9 @@ import error from '@magic/error'
3
3
 
4
4
  const libName = `@magic/semver.parse:`
5
5
 
6
- /**
7
- * @typedef {import('./types.js').Version} Version
8
- * @typedef {import('./types.js').VersionResult} VersionResult
9
- */
10
-
11
6
  /**
12
7
  * @param {string} v
13
- * @returns {VersionResult}
8
+ * @returns {import('./types.js').VersionResult}
14
9
  */
15
10
  export const parse = v => {
16
11
  if (is.empty(v)) {
@@ -27,7 +22,7 @@ export const parse = v => {
27
22
 
28
23
  const [major, minor, patch, demo] = v.split('.')
29
24
 
30
- /** @type {VersionResult} */
25
+ /** @type {import('./types.js').VersionResult} */
31
26
  const result = {
32
27
  major: parseInt(major.replace('v', '')),
33
28
  minor: parseInt(minor),
package/src/serialize.js CHANGED
@@ -4,11 +4,7 @@ import error from '@magic/error'
4
4
  const libName = `@magic/semver.serialize:`
5
5
 
6
6
  /**
7
- * @typedef {import('./types.js').Version} Version
8
- */
9
-
10
- /**
11
- * @param {Version | unknown} v
7
+ * @param {import('./types.js').Version | unknown} v
12
8
  * @returns {string}
13
9
  */
14
10
  export const serialize = v => {
package/src/sort.js ADDED
@@ -0,0 +1,77 @@
1
+ import is from '@magic/types'
2
+ import { parse } from './parse.js'
3
+
4
+ /**
5
+ * Compares pre-release identifiers according to semver rules
6
+ * @private
7
+ * @param {import('./types.js').Version['demo']} a
8
+ * @param {import('./types.js').Version['demo']} b
9
+ * @returns {number}
10
+ */
11
+ const comparePreRelease = (a, b) => {
12
+ if (!a && !b) {
13
+ return 0
14
+ }
15
+ if (!a) {
16
+ return -1
17
+ }
18
+ if (!b) {
19
+ return 1
20
+ }
21
+
22
+ // First compare the string identifiers (alpha, beta, etc)
23
+ if (a.string < b.string) {
24
+ return -1
25
+ }
26
+ if (a.string > b.string) {
27
+ return 1
28
+ }
29
+
30
+ // If strings are same, compare version numbers
31
+ return a.version - b.version
32
+ }
33
+
34
+ /**
35
+ * Sorts versions according to semver spec
36
+ * @param {(import('./types.js').Version | string)[]} versions
37
+ * @returns {import('./types.js').Version[]}
38
+ */
39
+ export const sort = versions => {
40
+ return /** @type {import('./types.js').Version[]} */ (
41
+ versions
42
+ .map(
43
+ v =>
44
+ /** @type {[string | import('./types.js').Version, import('./types.js').Version]} */ ([
45
+ v,
46
+ is.str(v) ? parse(v) : v,
47
+ ]),
48
+ )
49
+ .sort(([, a], [, b]) => {
50
+ if (a.major !== b.major) {
51
+ return a.major - b.major
52
+ }
53
+ if (a.minor !== b.minor) {
54
+ return a.minor - b.minor
55
+ }
56
+ if (a.patch !== b.patch) {
57
+ return a.patch - b.patch
58
+ }
59
+
60
+ const hasPreA = !!a.demo
61
+ const hasPreB = !!b.demo
62
+
63
+ if (hasPreA && !hasPreB) {
64
+ return -1
65
+ }
66
+ if (!hasPreA && hasPreB) {
67
+ return 1
68
+ }
69
+ if (hasPreA && hasPreB) {
70
+ return comparePreRelease(a.demo, b.demo)
71
+ }
72
+
73
+ return 0
74
+ })
75
+ .map(([original]) => original)
76
+ )
77
+ }
package/types/bump.d.ts CHANGED
@@ -7,5 +7,4 @@ export function bump(
7
7
  beta?: boolean | undefined
8
8
  alpha?: boolean | undefined
9
9
  },
10
- ): Version | string
11
- export type Version = import('./types.js').Version
10
+ ): import('./types.js').Version | string
package/types/index.d.ts CHANGED
@@ -7,13 +7,15 @@ export const bump: (
7
7
  beta?: boolean | undefined
8
8
  alpha?: boolean | undefined
9
9
  },
10
- ) => Version | string
10
+ ) => import('./types.js').Version | string
11
11
  export const isBigger: (a: string, b: string) => boolean
12
- export const isSemver: (v: Version | string | unknown) => v is Version
12
+ export const isSemver: (
13
+ v: import('./types.js').Version | string | unknown,
14
+ ) => v is import('./types.js').Version
13
15
  export const isSmaller: (a: string, b: string) => boolean
14
- export const parse: (v: string) => VersionResult
15
- export const stringify: (v: Version | unknown) => string
16
- export const serialize: (v: Version | unknown) => string
16
+ export const parse: (v: string) => import('./types.js').VersionResult
17
+ export const stringify: (v: import('./types.js').Version | unknown) => string
18
+ export const serialize: (v: import('./types.js').Version | unknown) => string
17
19
  declare namespace _default {
18
20
  export { bump }
19
21
  export { isBigger }
@@ -24,3 +26,5 @@ declare namespace _default {
24
26
  export { stringify }
25
27
  }
26
28
  export default _default
29
+ export type Version = import('./types.js').Version
30
+ export type VersionResult = import('./types.js').VersionResult
@@ -1,2 +1,3 @@
1
- export function isSemver(v: Version | string | unknown): v is Version
2
- export type Version = import('./types.js').Version
1
+ export function isSemver(
2
+ v: import('./types.js').Version | string | unknown,
3
+ ): v is import('./types.js').Version
package/types/parse.d.ts CHANGED
@@ -1,3 +1 @@
1
- export function parse(v: string): VersionResult
2
- export type Version = import('./types.js').Version
3
- export type VersionResult = import('./types.js').VersionResult
1
+ export function parse(v: string): import('./types.js').VersionResult
@@ -1,2 +1 @@
1
- export function serialize(v: Version | unknown): string
2
- export type Version = import('./types.js').Version
1
+ export function serialize(v: import('./types.js').Version | unknown): string
@@ -0,0 +1,3 @@
1
+ export function sort(
2
+ versions: (import('./types.js').Version | string)[],
3
+ ): import('./types.js').Version[]